pax_global_header00006660000000000000000000000064117072422730014517gustar00rootroot0000000000000052 comment=3cebd4f10dcf0c7c502d7f3f030a8ea644d501ec qtscriptgenerator-src-0.2.0/000077500000000000000000000000001170724227300160635ustar00rootroot00000000000000qtscriptgenerator-src-0.2.0/LGPL_EXCEPTION.txt000066400000000000000000000022431170724227300210010ustar00rootroot00000000000000Nokia Qt LGPL Exception version 1.1 As an additional permission to the GNU Lesser General Public License version 2.1, the object code form of a "work that uses the Library" may incorporate material from a header file that is part of the Library. You may distribute such object code under terms of your choice, provided that: (i) the header files of the Library have not been modified; and (ii) the incorporated material is limited to numerical parameters, data structure layouts, accessors, macros, inline functions and templates; and (iii) you comply with the terms of Section 6 of the GNU Lesser General Public License version 2.1. Moreover, you may apply this exception to a modified version of the Library, provided that such modification does not involve copying material from the Library into the modified Library's header files unless such material is limited to (i) numerical parameters; (ii) data structure layouts; (iii) accessors; and (iv) small macros, templates and inline functions of five lines or less in length. Furthermore, you are not required to apply this additional permission to a modified version of the Library. qtscriptgenerator-src-0.2.0/LICENSE.LGPL000066400000000000000000000643231170724227300176350ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE The Qt GUI Toolkit is Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). Contact: Nokia Corporation (qt-info@nokia.com) You may use, distribute and copy the Qt GUI Toolkit under the terms of GNU Lesser General Public License version 2.1, which is displayed below. ------------------------------------------------------------------------- GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] 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 Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, 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 and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these 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 other code 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. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. 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, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser 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 combine 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) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) 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. d) 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. e) 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 materials to be 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 with 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 Lesser 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 Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 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 Ty Coon, President of Vice That's all there is to it! qtscriptgenerator-src-0.2.0/LICENSE.PREVIEW.COMMERCIAL000066400000000000000000000755251170724227300216400ustar00rootroot00000000000000TECHNOLOGY PREVIEW LICENSE AGREEMENT For individuals and/or legal entities resident in the Americas (North America, Central America and South America), the applicable licensing terms are specified under the heading "Technology Preview License Agreement: The Americas". For individuals and/or legal entities not resident in The Americas, the applicable licensing terms are specified under the heading "Technology Preview License Agreement: Rest of the World". TECHNOLOGY PREVIEW LICENSE AGREEMENT: The Americas Agreement version 2.4 This Technology Preview License Agreement ("Agreement") is a legal agreement between Nokia Inc. ("Nokia"), with its registered office at 102 Corporate Park Drive, White Plains, N.Y., U.S.A. 10604 and you (either an individual or a legal entity) ("Licensee") for the Licensed Software (as defined below). 1. DEFINITIONS "Affiliate" of a Party shall mean an entity (i) which is directly or indirectly controlling such Party; (ii) which is under the same direct or indirect ownership or control as such Party; or (iii) which is directly or indirectly owned or controlled by such Party. For these purposes, an entity shall be treated as being controlled by another if that other entity has fifty percent (50 %) or more of the votes in such entity, is able to direct its affairs and/or to control the composition of its board of directors or equivalent body. "Applications" shall mean Licensee's software products created using the Licensed Software which may include portions of the Licensed Software. "Term" shall mean the period of time six (6) months from the later of (a) the Effective Date; or (b) the date the Licensed Software was initially delivered to Licensee by Nokia. If no specific Effective Date is set forth in the Agreement, the Effective Date shall be deemed to be the date the Licensed Software was initially delivered to Licensee. "Licensed Software" shall mean the computer software, "online" or electronic documentation, associated media and printed materials, including the source code, example programs and the documentation delivered by Nokia to Licensee in conjunction with this Agreement. "Party" or "Parties" shall mean Licensee and/or Nokia. 2. OWNERSHIP The Licensed Software is protected by copyright laws and international copyright treaties, as well as other intellectual property laws and treaties. The Licensed Software is licensed, not sold. If Licensee provides any findings, proposals, suggestions or other feedback ("Feedback") to Nokia regarding the Licensed Software, Nokia shall own all right, title and interest including the intellectual property rights in and to such Feedback, excluding however any existing patent rights of Licensee. To the extent Licensee owns or controls any patents for such Feedback Licensee hereby grants to Nokia and its Affiliates, a worldwide, perpetual, non-transferable, sublicensable, royalty-free license to (i) use, copy and modify Feedback and to create derivative works thereof, (ii) to make (and have made), use, import, sell, offer for sale, lease, dispose, offer for disposal or otherwise exploit any products or services of Nokia containing Feedback,, and (iii) sublicense all the foregoing rights to third party licensees and customers of Nokia and/or its Affiliates. 3. VALIDITY OF THE AGREEMENT By installing, copying, or otherwise using the Licensed Software, Licensee agrees to be bound by the terms of this Agreement. If Licensee does not agree to the terms of this Agreement, Licensee may not install, copy, or otherwise use the Licensed Software. Upon Licensee's acceptance of the terms and conditions of this Agreement, Nokia grants Licensee the right to use the Licensed Software in the manner provided below. 4. LICENSES 4.1. Using and Copying Nokia grants to Licensee a non-exclusive, non-transferable, time-limited license to use and copy the Licensed Software for sole purpose of designing, developing and testing Applications, and evaluating and the Licensed Software during the Term. Licensee may install copies of the Licensed Software on an unlimited number of computers provided that (a) if an individual, only such individual; or (b) if a legal entity only its employees; use the Licensed Software for the authorized purposes. 4.2 No Distribution or Modifications Licensee may not disclose, modify, sell, market, commercialise, distribute, loan, rent, lease, or license the Licensed Software or any copy of it or use the Licensed Software for any purpose that is not expressly granted in this Section 4. Licensee may not alter or remove any details of ownership, copyright, trademark or other property right connected with the Licensed Software. Licensee may not distribute any software statically or dynamically linked with the Licensed Software. 4.3 No Technical Support Nokia has no obligation to furnish Licensee with any technical support whatsoever. Any such support is subject to separate agreement between the Parties. 5. PRE-RELEASE CODE The Licensed Software contains pre-release code that is not at the level of performance and compatibility of a final, generally available, product offering. The Licensed Software may not operate correctly and may be substantially modified prior to the first commercial product release, if any. Nokia is not obligated to make this or any later version of the Licensed Software commercially available. The License Software is "Not for Commercial Use" and may only be used for the purposes described in Section 4. The Licensed Software may not be used in a live operating environment where it may be relied upon to perform in the same manner as a commercially released product or with data that has not been sufficiently backed up. 6. THIRD PARTY SOFTWARE The Licensed Software may provide links to third party libraries or code (collectively "Third Party Software") to implement various functions. Third Party Software does not comprise part of the Licensed Software. In some cases, access to Third Party Software may be included along with the Licensed Software delivery as a convenience for development and testing only. Such source code and libraries may be listed in the ".../src/3rdparty" source tree delivered with the Licensed Software or documented in the Licensed Software where the Third Party Software is used, as may be amended from time to time, do not comprise the Licensed Software. Licensee acknowledges (1) that some part of Third Party Software may require additional licensing of copyright and patents from the owners of such, and (2) that distribution of any of the Licensed Software referencing any portion of a Third Party Software may require appropriate licensing from such third parties. 7. LIMITED WARRANTY AND WARRANTY DISCLAIMER The Licensed Software is licensed to Licensee "as is". To the maximum extent permitted by applicable law, Nokia on behalf of itself and its suppliers, disclaims all warranties and conditions, either express or implied, including, but not limited to, implied warranties of merchantability, fitness for a particular purpose, title and non-infringement with regard to the Licensed Software. 8. LIMITATION OF LIABILITY If, Nokia's warranty disclaimer notwithstanding, Nokia is held liable to Licensee, whether in contract, tort or any other legal theory, based on the Licensed Software, Nokia's entire liability to Licensee and Licensee's exclusive remedy shall be, at Nokia's option, either (A) return of the price Licensee paid for the Licensed Software, or (B) repair or replacement of the Licensed Software, provided Licensee returns to Nokia all copies of the Licensed Software as originally delivered to Licensee. Nokia shall not under any circumstances be liable to Licensee based on failure of the Licensed Software if the failure resulted from accident, abuse or misapplication, nor shall Nokia under any circumstances be liable for special damages, punitive or exemplary damages, damages for loss of profits or interruption of business or for loss or corruption of data. Any award of damages from Nokia to Licensee shall not exceed the total amount Licensee has paid to Nokia in connection with this Agreement. 9. CONFIDENTIALITY Each party acknowledges that during the Term of this Agreement it shall have access to information about the other party's business, business methods, business plans, customers, business relations, technology, and other information, including the terms of this Agreement, that is confidential and of great value to the other party, and the value of which would be significantly reduced if disclosed to third parties (the "Confidential Information"). Accordingly, when a party (the "Receiving Party") receives Confidential Information from another party (the "Disclosing Party"), the Receiving Party shall, and shall obligate its employees and agents and employees and agents of its Affiliates to: (i) maintain the Confidential Information in strict confidence; (ii) not disclose the Confidential Information to a third party without the Disclosing Party's prior written approval; and (iii) not, directly or indirectly, use the Confidential Information for any purpose other than for exercising its rights and fulfilling its responsibilities pursuant to this Agreement. Each party shall take reasonable measures to protect the Confidential Information of the other party, which measures shall not be less than the measures taken by such party to protect its own confidential and proprietary information. "Confidential Information" shall not include information that (a) is or becomes generally known to the public through no act or omission of the Receiving Party; (b) was in the Receiving Party's lawful possession prior to the disclosure hereunder and was not subject to limitations on disclosure or use; (c) is developed by the Receiving Party without access to the Confidential Information of the Disclosing Party or by persons who have not had access to the Confidential Information of the Disclosing Party as proven by the written records of the Receiving Party; (d) is lawfully disclosed to the Receiving Party without restrictions, by a third party not under an obligation of confidentiality; or (e) the Receiving Party is legally compelled to disclose the information, in which case the Receiving Party shall assert the privileged and confidential nature of the information and cooperate fully with the Disclosing Party to protect against and prevent disclosure of any Confidential Information and to limit the scope of disclosure and the dissemination of disclosed Confidential Information by all legally available means. The obligations of the Receiving Party under this Section shall continue during the Initial Term and for a period of five (5) years after expiration or termination of this Agreement. To the extent that the terms of the Non-Disclosure Agreement between Nokia and Licensee conflict with the terms of this Section 9, this Section 9 shall be controlling over the terms of the Non-Disclosure Agreement. 10. GENERAL PROVISIONS 10.1 No Assignment Licensee shall not be entitled to assign or transfer all or any of its rights, benefits and obligations under this Agreement without the prior written consent of Nokia, which shall not be unreasonably withheld. 10.2 Termination Nokia may terminate the Agreement at any time immediately upon written notice by Nokia to Licensee if Licensee breaches this Agreement. Upon termination of this Agreement, Licensee shall return to Nokia all copies of Licensed Software that were supplied by Nokia. All other copies of Licensed Software in the possession or control of Licensee must be erased or destroyed. An officer of Licensee must promptly deliver to Nokia a written confirmation that this has occurred. 10.3 Surviving Sections Any terms and conditions that by their nature or otherwise reasonably should survive a cancellation or termination of this Agreement shall also be deemed to survive. Such terms and conditions include, but are not limited to the following Sections: 2, 5, 6, 7, 8, 9, 10.2, 10.3, 10.4, 10.5, 10.6, 10.7, and 10.8 of this Agreement. 10.4 Entire Agreement This Agreement constitutes the complete agreement between the parties and supersedes all prior or contemporaneous discussions, representations, and proposals, written or oral, with respect to the subject matters discussed herein, with the exception of the non-disclosure agreement executed by the parties in connection with this Agreement ("Non-Disclosure Agreement"), if any, shall be subject to Section 9. No modification of this Agreement shall be effective unless contained in a writing executed by an authorized representative of each party. No term or condition contained in Licensee's purchase order shall apply unless expressly accepted by Nokia in writing. If any provision of the Agreement is found void or unenforceable, the remainder shall remain valid and enforceable according to its terms. If any remedy provided is determined to have failed for its essential purpose, all limitations of liability and exclusions of damages set forth in this Agreement shall remain in effect. 10.5 Export Control Licensee acknowledges that the Licensed Software may be subject to export control restrictions of various countries. Licensee shall fully comply with all applicable export license restrictions and requirements as well as with all laws and regulations relating to the importation of the Licensed Software and shall procure all necessary governmental authorizations, including without limitation, all necessary licenses, approvals, permissions or consents, where necessary for the re-exportation of the Licensed Software., 10.6 Governing Law and Legal Venue This Agreement shall be governed by and construed in accordance with the federal laws of the United States of America and the internal laws of the State of New York without given effect to any choice of law rule that would result in the application of the laws of any other jurisdiction. The United Nations Convention on Contracts for the International Sale of Goods (CISG) shall not apply. Each Party (a) hereby irrevocably submits itself to and consents to the jurisdiction of the United States District Court for the Southern District of New York (or if such court lacks jurisdiction, the state courts of the State of New York) for the purposes of any action, claim, suit or proceeding between the Parties in connection with any controversy, claim, or dispute arising out of or relating to this Agreement; and (b) hereby waives, and agrees not to assert by way of motion, as a defense or otherwise, in any such action, claim, suit or proceeding, any claim that is not personally subject to the jurisdiction of such court(s), that the action, claim, suit or proceeding is brought in an inconvenient forum or that the venue of the action, claim, suit or proceeding is improper. Notwithstanding the foregoing, nothing in this Section 9.6 is intended to, or shall be deemed to, constitute a submission or consent to, or selection of, jurisdiction, forum or venue for any action for patent infringement, whether or not such action relates to this Agreement. 10.7 No Implied License There are no implied licenses or other implied rights granted under this Agreement, and all rights, save for those expressly granted hereunder, shall remain with Nokia and its licensors. In addition, no licenses or immunities are granted to the combination of the Licensed Software with any other software or hardware not delivered by Nokia under this Agreement. 10.8 Government End Users A "U.S. Government End User" shall mean any agency or entity of the government of the United States. The following shall apply if Licensee is a U.S. Government End User. The Licensed Software is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software" and "commercial computer software documentation," as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire the Licensed Software with only those rights set forth herein. The Licensed Software (including related documentation) is provided to U.S. Government End Users: (a) only as a commercial end item; and (b) only pursuant to this Agreement. TECHNOLOGY PREVIEW LICENSE AGREEMENT: Rest of the World Agreement version 2.4 This Technology Preview License Agreement ("Agreement") is a legal agreement between Nokia Corporation ("Nokia"), with its registered office at Keilalahdentie 4, 02150 Espoo, Finland and you (either an individual or a legal entity) ("Licensee") for the Licensed Software (as defined below). 1. DEFINITIONS "Affiliate" of a Party shall mean an entity (i) which is directly or indirectly controlling such Party; (ii) which is under the same direct or indirect ownership or control as such Party; or (iii) which is directly or indirectly owned or controlled by such Party. For these purposes, an entity shall be treated as being controlled by another if that other entity has fifty percent (50 %) or more of the votes in such entity, is able to direct its affairs and/or to control the composition of its board of directors or equivalent body. "Applications" shall mean Licensee's software products created using the Licensed Software which may include portions of the Licensed Software. "Term" shall mean the period of time six (6) months from the later of (a) the Effective Date; or (b) the date the Licensed Software was initially delivered to Licensee by Nokia. If no specific Effective Date is set forth in the Agreement, the Effective Date shall be deemed to be the date the Licensed Software was initially delivered to Licensee. "Licensed Software" shall mean the computer software, "online" or electronic documentation, associated media and printed materials, including the source code, example programs and the documentation delivered by Nokia to Licensee in conjunction with this Agreement. "Party" or "Parties" shall mean Licensee and/or Nokia. 2. OWNERSHIP The Licensed Software is protected by copyright laws and international copyright treaties, as well as other intellectual property laws and treaties. The Licensed Software is licensed, not sold. If Licensee provides any findings, proposals, suggestions or other feedback ("Feedback") to Nokia regarding the Licensed Software, Nokia shall own all right, title and interest including the intellectual property rights in and to such Feedback, excluding however any existing patent rights of Licensee. To the extent Licensee owns or controls any patents for such Feedback Licensee hereby grants to Nokia and its Affiliates, a worldwide, perpetual, non-transferable, sublicensable, royalty-free license to (i) use, copy and modify Feedback and to create derivative works thereof, (ii) to make (and have made), use, import, sell, offer for sale, lease, dispose, offer for disposal or otherwise exploit any products or services of Nokia containing Feedback,, and (iii) sublicense all the foregoing rights to third party licensees and customers of Nokia and/or its Affiliates. 3. VALIDITY OF THE AGREEMENT By installing, copying, or otherwise using the Licensed Software, Licensee agrees to be bound by the terms of this Agreement. If Licensee does not agree to the terms of this Agreement, Licensee may not install, copy, or otherwise use the Licensed Software. Upon Licensee's acceptance of the terms and conditions of this Agreement, Nokia grants Licensee the right to use the Licensed Software in the manner provided below. 4. LICENSES 4.1. Using and Copying Nokia grants to Licensee a non-exclusive, non-transferable, time-limited license to use and copy the Licensed Software for sole purpose of designing, developing and testing Applications, and evaluating and the Licensed Software during the Term. Licensee may install copies of the Licensed Software on an unlimited number of computers provided that (a) if an individual, only such individual; or (b) if a legal entity only its employees; use the Licensed Software for the authorized purposes. 4.2 No Distribution or Modifications Licensee may not disclose, modify, sell, market, commercialise, distribute, loan, rent, lease, or license the Licensed Software or any copy of it or use the Licensed Software for any purpose that is not expressly granted in this Section 4. Licensee may not alter or remove any details of ownership, copyright, trademark or other property right connected with the Licensed Software. Licensee may not distribute any software statically or dynamically linked with the Licensed Software. 4.3 No Technical Support Nokia has no obligation to furnish Licensee with any technical support whatsoever. Any such support is subject to separate agreement between the Parties. 5. PRE-RELEASE CODE The Licensed Software contains pre-release code that is not at the level of performance and compatibility of a final, generally available, product offering. The Licensed Software may not operate correctly and may be substantially modified prior to the first commercial product release, if any. Nokia is not obligated to make this or any later version of the Licensed Software commercially available. The License Software is "Not for Commercial Use" and may only be used for the purposes described in Section 4. The Licensed Software may not be used in a live operating environment where it may be relied upon to perform in the same manner as a commercially released product or with data that has not been sufficiently backed up. 6. THIRD PARTY SOFTWARE The Licensed Software may provide links to third party libraries or code (collectively "Third Party Software") to implement various functions. Third Party Software does not comprise part of the Licensed Software. In some cases, access to Third Party Software may be included along with the Licensed Software delivery as a convenience for development and testing only. Such source code and libraries may be listed in the ".../src/3rdparty" source tree delivered with the Licensed Software or documented in the Licensed Software where the Third Party Software is used, as may be amended from time to time, do not comprise the Licensed Software. Licensee acknowledges (1) that some part of Third Party Software may require additional licensing of copyright and patents from the owners of such, and (2) that distribution of any of the Licensed Software referencing any portion of a Third Party Software may require appropriate licensing from such third parties. 7. LIMITED WARRANTY AND WARRANTY DISCLAIMER The Licensed Software is licensed to Licensee "as is". To the maximum extent permitted by applicable law, Nokia on behalf of itself and its suppliers, disclaims all warranties and conditions, either express or implied, including, but not limited to, implied warranties of merchantability, fitness for a particular purpose, title and non-infringement with regard to the Licensed Software. 8. LIMITATION OF LIABILITY If, Nokia's warranty disclaimer notwithstanding, Nokia is held liable to Licensee, whether in contract, tort or any other legal theory, based on the Licensed Software, Nokia's entire liability to Licensee and Licensee's exclusive remedy shall be, at Nokia's option, either (A) return of the price Licensee paid for the Licensed Software, or (B) repair or replacement of the Licensed Software, provided Licensee returns to Nokia all copies of the Licensed Software as originally delivered to Licensee. Nokia shall not under any circumstances be liable to Licensee based on failure of the Licensed Software if the failure resulted from accident, abuse or misapplication, nor shall Nokia under any circumstances be liable for special damages, punitive or exemplary damages, damages for loss of profits or interruption of business or for loss or corruption of data. Any award of damages from Nokia to Licensee shall not exceed the total amount Licensee has paid to Nokia in connection with this Agreement. 9. CONFIDENTIALITY Each party acknowledges that during the Term of this Agreement it shall have access to information about the other party's business, business methods, business plans, customers, business relations, technology, and other information, including the terms of this Agreement, that is confidential and of great value to the other party, and the value of which would be significantly reduced if disclosed to third parties (the "Confidential Information"). Accordingly, when a party (the "Receiving Party") receives Confidential Information from another party (the "Disclosing Party"), the Receiving Party shall, and shall obligate its employees and agents and employees and agents of its Affiliates to: (i) maintain the Confidential Information in strict confidence; (ii) not disclose the Confidential Information to a third party without the Disclosing Party's prior written approval; and (iii) not, directly or indirectly, use the Confidential Information for any purpose other than for exercising its rights and fulfilling its responsibilities pursuant to this Agreement. Each party shall take reasonable measures to protect the Confidential Information of the other party, which measures shall not be less than the measures taken by such party to protect its own confidential and proprietary information. "Confidential Information" shall not include information that (a) is or becomes generally known to the public through no act or omission of the Receiving Party; (b) was in the Receiving Party's lawful possession prior to the disclosure hereunder and was not subject to limitations on disclosure or use; (c) is developed by the Receiving Party without access to the Confidential Information of the Disclosing Party or by persons who have not had access to the Confidential Information of the Disclosing Party as proven by the written records of the Receiving Party; (d) is lawfully disclosed to the Receiving Party without restrictions, by a third party not under an obligation of confidentiality; or (e) the Receiving Party is legally compelled to disclose the information, in which case the Receiving Party shall assert the privileged and confidential nature of the information and cooperate fully with the Disclosing Party to protect against and prevent disclosure of any Confidential Information and to limit the scope of disclosure and the dissemination of disclosed Confidential Information by all legally available means. The obligations of the Receiving Party under this Section shall continue during the Initial Term and for a period of five (5) years after expiration or termination of this Agreement. To the extent that the terms of the Non-Disclosure Agreement between Nokia and Licensee conflict with the terms of this Section 9, this Section 9 shall be controlling over the terms of the Non-Disclosure Agreement. 10. GENERAL PROVISIONS 10.1 No Assignment Licensee shall not be entitled to assign or transfer all or any of its rights, benefits and obligations under this Agreement without the prior written consent of Nokia, which shall not be unreasonably withheld. 10.2 Termination Nokia may terminate the Agreement at any time immediately upon written notice by Nokia to Licensee if Licensee breaches this Agreement. Upon termination of this Agreement, Licensee shall return to Nokia all copies of Licensed Software that were supplied by Nokia. All other copies of Licensed Software in the possession or control of Licensee must be erased or destroyed. An officer of Licensee must promptly deliver to Nokia a written confirmation that this has occurred. 10.3 Surviving Sections Any terms and conditions that by their nature or otherwise reasonably should survive a cancellation or termination of this Agreement shall also be deemed to survive. Such terms and conditions include, but are not limited to the following Sections: 2, 5, 6, 7, 8, 9, 10.2, 10.3, 10.4, 10.5, 10.6, 10.7, and 10.8 of this Agreement. 10.4 Entire Agreement This Agreement constitutes the complete agreement between the parties and supersedes all prior or contemporaneous discussions, representations, and proposals, written or oral, with respect to the subject matters discussed herein, with the exception of the non-disclosure agreement executed by the parties in connection with this Agreement ("Non-Disclosure Agreement"), if any, shall be subject to Section 9. No modification of this Agreement shall be effective unless contained in a writing executed by an authorized representative of each party. No term or condition contained in Licensee's purchase order shall apply unless expressly accepted by Nokia in writing. If any provision of the Agreement is found void or unenforceable, the remainder shall remain valid and enforceable according to its terms. If any remedy provided is determined to have failed for its essential purpose, all limitations of liability and exclusions of damages set forth in this Agreement shall remain in effect. 10.5 Export Control Licensee acknowledges that the Licensed Software may be subject to export control restrictions of various countries. Licensee shall fully comply with all applicable export license restrictions and requirements as well as with all laws and regulations relating to the importation of the Licensed Software and shall procure all necessary governmental authorizations, including without limitation, all necessary licenses, approvals, permissions or consents, where necessary for the re-exportation of the Licensed Software., 10.6 Governing Law and Legal Venue This Agreement shall be construed and interpreted in accordance with the laws of Finland, excluding its choice of law provisions. Any disputes arising out of or relating to this Agreement shall be resolved in arbitration under the Rules of Arbitration of the Chamber of Commerce of Helsinki, Finland. The arbitration tribunal shall consist of one (1), or if either Party so requires, of three (3), arbitrators. The award shall be final and binding and enforceable in any court of competent jurisdiction. The arbitration shall be held in Helsinki, Finland and the process shall be conducted in the English language. 10.7 No Implied License There are no implied licenses or other implied rights granted under this Agreement, and all rights, save for those expressly granted hereunder, shall remain with Nokia and its licensors. In addition, no licenses or immunities are granted to the combination of the Licensed Software with any other software or hardware not delivered by Nokia under this Agreement. 10.8 Government End Users A "U.S. Government End User" shall mean any agency or entity of the government of the United States. The following shall apply if Licensee is a U.S. Government End User. The Licensed Software is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software" and "commercial computer software documentation," as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire the Licensed Software with only those rights set forth herein. The Licensed Software (including related documentation) is provided to U.S. Government End Users: (a) only as a commercial end item; and (b) only pursuant to this Agreement. qtscriptgenerator-src-0.2.0/README000066400000000000000000000021361170724227300167450ustar00rootroot00000000000000Qt Script Generator labs package, version 0.2 The Qt Script Generator is a tool that generates Qt bindings for Qt Script. --- Instructions: 1) Build the generator: cd path/to/this/project/generator, qmake && make 2) Run the generator (without arguments) This will generate C++ files in path/to/this/project/generated_cpp and documentation in path/to/this/project/doc 3) Build the bindings plugins: cd path/to/this/project/qtbindings, qmake && make The plugins will be put under path/to/this/project/plugins 4) To use the plugins in your application, add the plugins path to the library paths (QCoreApplication::setLibraryPaths()), then call QScriptEngine::importExtension() (plugin keys are "qt.core", "qt.gui", etc). There is a simple script interpreter / launcher in path/to/this/project/qtbindings/qs_eval that imports all the bindings. You can use it to run the examples found in path/to/this/project/examples. E.g., with the examples directory being the working directory: ../qtbindings/qs_eval/qs_eval CollidingMice.js See the generated doc/index.html for more information. Have fun! qtscriptgenerator-src-0.2.0/doc/000077500000000000000000000000001170724227300166305ustar00rootroot00000000000000qtscriptgenerator-src-0.2.0/doc/classic.css000066400000000000000000000024751170724227300207730ustar00rootroot00000000000000h3.fn,span.fn { margin-left: 1cm; text-indent: -1cm; } a:link { color: #004faf; text-decoration: none } a:visited { color: #672967; text-decoration: none } a.obsolete { color: #661100; text-decoration: none } a.compat { color: #661100; text-decoration: none } a.obsolete:visited { color: #995500; text-decoration: none } a.compat:visited { color: #995500; text-decoration: none } td.postheader { font-family: sans-serif } tr.address { font-family: sans-serif } body { background: #ffffff; color: black } table tr.odd { background: #f0f0f0; color: black; } table tr.even { background: #e4e4e4; color: black; } table.annotated th { padding: 3px; text-align: left } table.annotated td { padding: 3px; } table tr pre { padding-top: none; padding-bottom: none; padding-left: none; padding-right: none; border: none; background: none } tr.qt-style { background: #a2c511; color: black } body pre { padding: 0.2em; border: #e7e7e7 1px solid; background: #f1f1f1; color: black } span.preprocessor, span.preprocessor a { color: darkblue; } span.comment { color: darkred; font-style: italic } span.string,span.char { color: darkgreen; } .title { text-align: center } .subtitle { font-size: 0.8em } .small-subtitle { font-size: 0.65em } qtscriptgenerator-src-0.2.0/examples/000077500000000000000000000000001170724227300177015ustar00rootroot00000000000000qtscriptgenerator-src-0.2.0/examples/AnalogClock.js000066400000000000000000000067771170724227300224350ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ function AnalogClock(parent) { QWidget.call(this, parent); var timer = new QTimer(this); timer.timeout.connect(this, "update()"); timer.start(1000); this.setWindowTitle("Analog Clock"); this.resize(200, 200); } AnalogClock.prototype = new QWidget(); AnalogClock.prototype.paintEvent = function() { var side = Math.min(this.width, this.height); var time = new Date(); var painter = new QPainter(); painter.begin(this); painter.setRenderHint(QPainter.Antialiasing); painter.translate(this.width / 2, this.height / 2); painter.scale(side / 200.0, side / 200.0); painter.setPen(new QPen(Qt.NoPen)); painter.setBrush(new QBrush(AnalogClock.hourColor)); painter.save(); painter.rotate(30.0 * ((time.getHours() + time.getMinutes() / 60.0))); painter.drawConvexPolygon(AnalogClock.hourHand); painter.drawLine(0, 0, 100, 100); painter.restore(); painter.setPen(AnalogClock.hourColor); for (var i = 0; i < 12; ++i) { painter.drawLine(88, 0, 96, 0); painter.rotate(30.0); } painter.setPen(new QPen(Qt.NoPen)); painter.setBrush(new QBrush(AnalogClock.minuteColor)); painter.save(); painter.rotate(6.0 * (time.getMinutes() + time.getSeconds() / 60.0)); painter.drawConvexPolygon(AnalogClock.minuteHand); painter.restore(); painter.setPen(AnalogClock.minuteColor); for (var j = 0; j < 60; ++j) { if ((j % 5) != 0) painter.drawLine(92, 0, 96, 0); painter.rotate(6.0); } painter.end(); }; AnalogClock.hourColor = new QColor(127, 0, 127); AnalogClock.minuteColor = new QColor(0, 127, 127, 191); AnalogClock.hourHand = new QPolygon([new QPoint(7, 8), new QPoint(-7, 8), new QPoint(0, -40)]); AnalogClock.minuteHand = new QPolygon([new QPoint(7, 8), new QPoint(-7, 8), new QPoint(0, -70)]); var clock = new AnalogClock(); clock.show(); QCoreApplication.exec(); qtscriptgenerator-src-0.2.0/examples/AnimatedBox.qs000066400000000000000000000030031170724227300224350ustar00rootroot00000000000000function createBox(parent) { var result = new QWidget(); result.styleSheet = "background: #00f060"; return result; } var scene = new QGraphicsScene(); scene.setSceneRect(0, 0, 400, 400); scene.itemIndexMethod = QGraphicsScene.NoIndex; box = scene.addWidget(createBox()); var machine = new QStateMachine(); var s1 = new QState(machine); s1.assignProperty(box, "geometry", new QRect(-50, 50, 100, 100)); s1.assignProperty(box, "opacity", 1.0); var s2 = new QState(machine); s2.assignProperty(box, "geometry", new QRect(250, 200, 200, 150)); s2.assignProperty(box, "opacity", 0.2); var timer = new QTimer(); timer.interval = 2000; timer.singleShot = false; timer.start(); var t1 = s1.addTransition(timer, "timeout()", s2); var geometryAnim = new QPropertyAnimation(box, "geometry"); geometryAnim.easingCurve = new QEasingCurve(QEasingCurve.InOutElastic); geometryAnim.duration = 1500; t1.addAnimation(geometryAnim); var opacityAnim = new QPropertyAnimation(box, "opacity"); opacityAnim.easingCurve = new QEasingCurve(QEasingCurve.InOutQuad); opacityAnim.duration = 1500; t1.addAnimation(opacityAnim); var t2 = s2.addTransition(timer, "timeout()", s1); t2.addAnimation(geometryAnim); t2.addAnimation(opacityAnim); machine.initialState = s1; machine.start(); var view = new QGraphicsView(scene); view.setRenderHint(QPainter.Antialiasing); view.backgroundBrush = new QBrush(new QColor(0, 48, 32)); view.viewportUpdateMode = QGraphicsView.FullViewportUpdate; view.resize(600, 410); view.show(); QCoreApplication.exec(); qtscriptgenerator-src-0.2.0/examples/BasicDrawing.js000066400000000000000000000352251170724227300226030ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ function tr(s) { return s; } function RenderArea(parent) { QWidget.call(this, parent); this.shape = RenderArea.Polygon; this.antialiased = false; this.transformed = false; this.pen = new QPen(); this.brush = new QBrush(); this.pixmap = new QPixmap("images/qt-logo.png"); this.setBackgroundRole(QPalette.Base); this.autoFillBackground = true; } RenderArea.prototype = new QWidget(); RenderArea.Line = 0; RenderArea.Points = 1; RenderArea.Polyline = 2; RenderArea.Polygon = 3; RenderArea.Rect = 4; RenderArea.RoundedRect = 5; RenderArea.Ellipse = 6; RenderArea.Arc = 7; RenderArea.Chord = 8; RenderArea.Pie = 9; RenderArea.Path = 10; RenderArea.Text = 11; RenderArea.Pixmap = 12; RenderArea.prototype.getMinimumSizeHint = function() { return new QSize(100, 100); } RenderArea.prototype.getSizeHint = function() { return new QSize(400, 200); } RenderArea.prototype.setShape = function(shape) { this.shape = shape; this.update(); } RenderArea.prototype.setPen = function(pen) { this.pen = pen; this.update(); } RenderArea.prototype.setBrush = function(brush) { this.brush = brush; this.update(); } RenderArea.prototype.setAntialiased = function(antialiased) { this.antialiased = antialiased; this.update(); } RenderArea.prototype.setTransformed = function(transformed) { this.transformed = transformed; this.update(); } RenderArea.prototype.paintEvent = function(/* event */) { if (RenderArea.points == undefined) { RenderArea.points = new QPolygon(); RenderArea.points.append(new QPoint(10, 80)); RenderArea.points.append(new QPoint(20, 10)); RenderArea.points.append(new QPoint(80, 30)); RenderArea.points.append(new QPoint(90, 70)); } var rect = new QRect(10, 20, 80, 60); var path = new QPainterPath(); path.moveTo(20, 80); path.lineTo(20, 30); path.cubicTo(80, 0, 50, 50, 80, 80); var startAngle = 20 * 16; var arcLength = 120 * 16; var painter = new QPainter(); painter.begin(this); painter.setPen(this.pen); painter.setBrush(this.brush); if (this.antialiased) { painter.setRenderHint(QPainter.Antialiasing, true); painter.translate(+0.5, +0.5); } for (var x = 0; x < this.width; x += 100) { for (var y = 0; y < this.height; y += 100) { painter.save(); painter.translate(x, y); if (this.transformed) { painter.translate(50, 50); painter.rotate(60.0); painter.scale(0.6, 0.9); painter.translate(-50, -50); } switch (this.shape) { case RenderArea.Line: painter.drawLine(rect.bottomLeft(), rect.topRight()); break; case RenderArea.Points: painter.drawPoints(RenderArea.points); break; case RenderArea.Polyline: painter.drawPolyline(RenderArea.points); break; case RenderArea.Polygon: painter.drawPolygon(RenderArea.points); break; case RenderArea.Rect: painter.drawRect(rect); break; case RenderArea.RoundedRect: painter.drawRoundedRect(rect, 25, 25, Qt.RelativeSize); break; case RenderArea.Ellipse: painter.drawEllipse(rect); break; case RenderArea.Arc: painter.drawArc(rect, startAngle, arcLength); break; case RenderArea.Chord: painter.drawChord(rect, startAngle, arcLength); break; case RenderArea.Pie: painter.drawPie(rect, startAngle, arcLength); break; case RenderArea.Path: painter.drawPath(path); break; case RenderArea.Text: // ### overload issue //painter.drawText(rect, Qt.AlignCenter, tr("Qt by\nTrolltech")); painter.drawText(rect.x, rect.y, rect.width, rect.height, Qt.AlignCenter, tr("Qt by\nTrolltech"), undefined); break; case RenderArea.Pixmap: painter.drawPixmap(10, 10, this.pixmap); } painter.restore(); } } painter.setPen(this.palette.dark().color()); painter.setBrush(Qt.NoBrush); painter.drawRect(0, 0, this.width - 1, this.height - 1); painter.end(); } function Window(parent) { QWidget.call(this, parent); this.renderArea = new RenderArea(); this.shapeComboBox = new QComboBox(); var icon = new QIcon(); // ### working around addItem() overload issue this.shapeComboBox.addItem(icon, tr("Polygon"), RenderArea.Polygon); this.shapeComboBox.addItem(icon, tr("Rectangle"), RenderArea.Rect); this.shapeComboBox.addItem(icon, tr("Rounded Rectangle"), RenderArea.RoundedRect); this.shapeComboBox.addItem(icon, tr("Ellipse"), RenderArea.Ellipse); this.shapeComboBox.addItem(icon, tr("Pie"), RenderArea.Pie); this.shapeComboBox.addItem(icon, tr("Chord"), RenderArea.Chord); this.shapeComboBox.addItem(icon, tr("Path"), RenderArea.Path); this.shapeComboBox.addItem(icon, tr("Line"), RenderArea.Line); this.shapeComboBox.addItem(icon, tr("Polyline"), RenderArea.Polyline); this.shapeComboBox.addItem(icon, tr("Arc"), RenderArea.Arc); this.shapeComboBox.addItem(icon, tr("Points"), RenderArea.Points); this.shapeComboBox.addItem(icon, tr("Text"), RenderArea.Text); this.shapeComboBox.addItem(icon, tr("Pixmap"), RenderArea.Pixmap); this.shapeLabel = new QLabel(tr("&Shape:")); this.shapeLabel.setBuddy(this.shapeComboBox); this.penWidthSpinBox = new QSpinBox(); this.penWidthSpinBox.setRange(0, 20); this.penWidthSpinBox.specialValueText = tr("0 (cosmetic pen)"); this.penWidthLabel = new QLabel(tr("Pen &Width:")); this.penWidthLabel.setBuddy(this.penWidthSpinBox); this.penStyleComboBox = new QComboBox(); this.penStyleComboBox.addItem(tr("Solid"), Qt.SolidLine); this.penStyleComboBox.addItem(tr("Dash"), Qt.DashLine); this.penStyleComboBox.addItem(tr("Dot"), Qt.DotLine); this.penStyleComboBox.addItem(tr("Dash Dot"), Qt.DashDotLine); this.penStyleComboBox.addItem(tr("Dash Dot Dot"), Qt.DashDotDotLine); this.penStyleComboBox.addItem(tr("None"), Qt.NoPen); this.penStyleLabel = new QLabel(tr("&Pen Style:")); this.penStyleLabel.setBuddy(this.penStyleComboBox); this.penCapComboBox = new QComboBox(); this.penCapComboBox.addItem(tr("Flat"), Qt.FlatCap); this.penCapComboBox.addItem(tr("Square"), Qt.SquareCap); this.penCapComboBox.addItem(tr("Round"), Qt.RoundCap); this.penCapLabel = new QLabel(tr("Pen &Cap:")); this.penCapLabel.setBuddy(this.penCapComboBox); this.penJoinComboBox = new QComboBox(); this.penJoinComboBox.addItem(tr("Miter"), Qt.MiterJoin); this.penJoinComboBox.addItem(tr("Bevel"), Qt.BevelJoin); this.penJoinComboBox.addItem(tr("Round"), Qt.RoundJoin); this.penJoinLabel = new QLabel(tr("Pen &Join:")); this.penJoinLabel.setBuddy(this.penJoinComboBox); this.brushStyleComboBox = new QComboBox(); this.brushStyleComboBox.addItem(tr("Linear Gradient"), Qt.LinearGradientPattern); this.brushStyleComboBox.addItem(tr("Radial Gradient"), Qt.RadialGradientPattern); this.brushStyleComboBox.addItem(tr("Conical Gradient"), Qt.ConicalGradientPattern); this.brushStyleComboBox.addItem(tr("Texture"), Qt.TexturePattern); this.brushStyleComboBox.addItem(tr("Solid"), Qt.SolidPattern); this.brushStyleComboBox.addItem(tr("Horizontal"), Qt.HorPattern); this.brushStyleComboBox.addItem(tr("Vertical"), Qt.VerPattern); this.brushStyleComboBox.addItem(tr("Cross"), Qt.CrossPattern); this.brushStyleComboBox.addItem(tr("Backward Diagonal"), Qt.BDiagPattern); this.brushStyleComboBox.addItem(tr("Forward Diagonal"), Qt.FDiagPattern); this.brushStyleComboBox.addItem(tr("Diagonal Cross"), Qt.DiagCrossPattern); this.brushStyleComboBox.addItem(tr("Dense 1"), Qt.Dense1Pattern); this.brushStyleComboBox.addItem(tr("Dense 2"), Qt.Dense2Pattern); this.brushStyleComboBox.addItem(tr("Dense 3"), Qt.Dense3Pattern); this.brushStyleComboBox.addItem(tr("Dense 4"), Qt.Dense4Pattern); this.brushStyleComboBox.addItem(tr("Dense 5"), Qt.Dense5Pattern); this.brushStyleComboBox.addItem(tr("Dense 6"), Qt.Dense6Pattern); this.brushStyleComboBox.addItem(tr("Dense 7"), Qt.Dense7Pattern); this.brushStyleComboBox.addItem(tr("None"), Qt.NoBrush); this.brushStyleLabel = new QLabel(tr("&Brush Style:")); this.brushStyleLabel.setBuddy(this.brushStyleComboBox); this.otherOptionsLabel = new QLabel(tr("Other Options:")); this.antialiasingCheckBox = new QCheckBox(tr("&Antialiasing")); this.transformationsCheckBox = new QCheckBox(tr("&Transformations")); this.shapeComboBox["activated(int)"].connect( this, this.shapeChanged); this.penWidthSpinBox["valueChanged(int)"].connect( this, this.penChanged); this.penStyleComboBox["activated(int)"].connect( this, this.penChanged); this.penCapComboBox["activated(int)"].connect( this, this.penChanged); this.penJoinComboBox["activated(int)"].connect( this, this.penChanged); this.brushStyleComboBox["activated(int)"].connect( this, this.brushChanged); this.antialiasingCheckBox["toggled(bool)"].connect( this.renderArea, this.renderArea.setAntialiased); this.transformationsCheckBox["toggled(bool)"].connect( this.renderArea, this.renderArea.setTransformed); var mainLayout = new QGridLayout(); mainLayout.setColumnStretch(0, 1); mainLayout.setColumnStretch(3, 1); mainLayout.addWidget(this.renderArea, 0, 0, 1, 4); mainLayout.setRowMinimumHeight(1, 6); mainLayout.addWidget(this.shapeLabel, 2, 1, Qt.AlignRight); mainLayout.addWidget(this.shapeComboBox, 2, 2); mainLayout.addWidget(this.penWidthLabel, 3, 1, Qt.AlignRight); mainLayout.addWidget(this.penWidthSpinBox, 3, 2); mainLayout.addWidget(this.penStyleLabel, 4, 1, Qt.AlignRight); mainLayout.addWidget(this.penStyleComboBox, 4, 2); mainLayout.addWidget(this.penCapLabel, 5, 1, Qt.AlignRight); mainLayout.addWidget(this.penCapComboBox, 5, 2); mainLayout.addWidget(this.penJoinLabel, 6, 1, Qt.AlignRight); mainLayout.addWidget(this.penJoinComboBox, 6, 2); mainLayout.addWidget(this.brushStyleLabel, 7, 1, Qt.AlignRight); mainLayout.addWidget(this.brushStyleComboBox, 7, 2); mainLayout.setRowMinimumHeight(8, 6); mainLayout.addWidget(this.otherOptionsLabel, 9, 1, Qt.AlignRight); mainLayout.addWidget(this.antialiasingCheckBox, 9, 2); mainLayout.addWidget(this.transformationsCheckBox, 10, 2); this.setLayout(mainLayout); this.shapeChanged(); this.penChanged(); this.brushChanged(); this.antialiasingCheckBox.checked = true; this.windowTitle = tr("Basic Drawing"); } Window.prototype = new QWidget(); Window.prototype.shapeChanged = function() { var shape = this.shapeComboBox.itemData(this.shapeComboBox.currentIndex); this.renderArea.setShape(shape); } Window.prototype.penChanged = function() { var width = this.penWidthSpinBox.value; var style = this.penStyleComboBox.itemData( this.penStyleComboBox.currentIndex); var cap = this.penCapComboBox.itemData( this.penCapComboBox.currentIndex); var join = this.penJoinComboBox.itemData( this.penJoinComboBox.currentIndex); this.renderArea.setPen(new QPen(new QColor(Qt.blue), width, style, cap, join)); } Window.prototype.brushChanged = function() { var style = Qt.BrushStyle(this.brushStyleComboBox.itemData( this.brushStyleComboBox.currentIndex)); if (style == Qt.LinearGradientPattern) { var linearGradient = new QLinearGradient(0, 0, 100, 100); // ### working around issue with Qt.GlobalColor linearGradient.setColorAt(0.0, new QColor(Qt.white)); linearGradient.setColorAt(0.2, new QColor(Qt.green)); linearGradient.setColorAt(1.0, new QColor(Qt.black)); this.renderArea.setBrush(new QBrush(linearGradient)); } else if (style == Qt.RadialGradientPattern) { var radialGradient = new QRadialGradient(50, 50, 50, 70, 70); radialGradient.setColorAt(0.0, new QColor(Qt.white)); radialGradient.setColorAt(0.2, new QColor(Qt.green)); radialGradient.setColorAt(1.0, new QColor(Qt.black)); this.renderArea.setBrush(new QBrush(radialGradient)); } else if (style == Qt.ConicalGradientPattern) { var conicalGradient = new QConicalGradient(50, 50, 150); conicalGradient.setColorAt(0.0, new QColor(Qt.white)); conicalGradient.setColorAt(0.2, new QColor(Qt.green)); conicalGradient.setColorAt(1.0, new QColor(Qt.black)); this.renderArea.setBrush(new QBrush(conicalGradient)); } else if (style == Qt.TexturePattern) { this.renderArea.setBrush(new QBrush(new QPixmap("images/brick.png"))); } else { this.renderArea.setBrush(new QBrush(new QColor(Qt.green), style)); } } var win = new Window(); win.show(); QCoreApplication.exec(); qtscriptgenerator-src-0.2.0/examples/CalendarWidget.js000066400000000000000000000406751170724227300231300ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ function tr(s) { return s; } function CalendarWidget(parent) { QWidget.call(this, parent); this.createPreviewGroupBox(); this.createGeneralOptionsGroupBox(); this.createDatesGroupBox(); this.createTextFormatsGroupBox(); var layout = new QGridLayout(); layout.addWidget(this.previewGroupBox, 0, 0); layout.addWidget(this.generalOptionsGroupBox, 0, 1); layout.addWidget(this.datesGroupBox, 1, 0); layout.addWidget(this.textFormatsGroupBox, 1, 1); layout.sizeConstraint = QLayout.SetFixedSize; this.setLayout(layout); this.previewLayout.setRowMinimumHeight(0, this.calendar.sizeHint.height()); this.previewLayout.setColumnMinimumWidth(0, this.calendar.sizeHint.width()); this.setWindowTitle(tr("Calendar Widget")); } CalendarWidget.prototype = new QWidget(); CalendarWidget.prototype.localeChanged = function(index) { this.calendar.setLocale(this.localeCombo.itemData(index)); } CalendarWidget.prototype.firstDayChanged = function(index) { this.calendar.firstDayOfWeek = this.firstDayCombo.itemData(index); } CalendarWidget.prototype.selectionModeChanged = function(index) { this.calendar.selectionMode = this.selectionModeCombo.itemData(index); } CalendarWidget.prototype.horizontalHeaderChanged = function(index) { this.calendar.horizontalHeaderFormat = this.horizontalHeaderCombo.itemData(index); } CalendarWidget.prototype.verticalHeaderChanged = function(index) { this.calendar.verticalHeaderFormat = this.verticalHeaderCombo.itemData(index); } CalendarWidget.prototype.selectedDateChanged = function() { this.currentDateEdit.setDate(this.calendar.selectedDate); } CalendarWidget.prototype.minimumDateChanged = function(date) { this.calendar.minimumDate = date; this.maximumDateEdit.setDate(this.calendar.maximumDate); } CalendarWidget.prototype.maximumDateChanged = function(date) { this.calendar.setMaximumDate(date); this.minimumDateEdit.setDate(this.calendar.minimumDate); } CalendarWidget.prototype.weekdayFormatChanged = function() { var format = new QTextCharFormat(); format.setForeground(new QBrush(this.weekdayColorCombo.itemData(this.weekdayColorCombo.currentIndex))); this.calendar.setWeekdayTextFormat(Qt.DayOfWeek.Monday, format); this.calendar.setWeekdayTextFormat(Qt.DayOfWeek.Tuesday, format); this.calendar.setWeekdayTextFormat(Qt.DayOfWeek.Wednesday, format); this.calendar.setWeekdayTextFormat(Qt.DayOfWeek.Thursday, format); this.calendar.setWeekdayTextFormat(Qt.DayOfWeek.Friday, format); } CalendarWidget.prototype.weekendFormatChanged = function() { var format = new QTextCharFormat(); format.setForeground(new QBrush(this.weekendColorCombo.itemData(this.weekendColorCombo.currentIndex))); this.calendar.setWeekdayTextFormat(Qt.DayOfWeek.Saturday, format); this.calendar.setWeekdayTextFormat(Qt.DayOfWeek.Sunday, format); } CalendarWidget.prototype.reformatHeaders = function() { var text = this.headerTextFormatCombo.currentText; var format = new QTextCharFormat(); if (text == tr("Bold")) { format.setFontWeight(QFont.Bold); } else if (text == tr("Italic")) { format.setFontItalic(true); } else if (text == tr("Green")) { format.setForeground(new QBrush(new QColor(Qt.green))); } this.calendar.setHeaderTextFormat(format); } CalendarWidget.prototype.reformatCalendarPage = function() { var mayFirstFormat = new QTextCharFormat(); if (this.mayFirstCheckBox.isChecked) mayFirstFormat.setForeground(new QBrush(new QColor(Qt.red))); var firstFridayFormat = new QTextCharFormat(); if (this.firstFridayCheckBox.isChecked) firstFridayFormat.setForeground(new QBrush(new QColor(Qt.blue))); var date = new Date(this.calendar.yearShown(), this.calendar.monthShown(), 1); //fixme this.calendar.setDateTextFormat(new Date(date.year, 5, 1), mayFirstFormat); date.setDate(date.year, date.month, 1); //fixme // while (date.dayOfWeek != Qt.Friday) // date = date.addDays(1); this.calendar.setDateTextFormat(date, firstFridayFormat); } CalendarWidget.prototype.createPreviewGroupBox = function() { this.previewGroupBox = new QGroupBox(tr("Preview")); this.calendar = new QCalendarWidget(); this.calendar.minimumDate = new Date(1900, 1, 1); this.calendar.maximumDate = new Date(3000, 1, 1); this.calendar.setGridVisible(true); this.calendar.currentPageChanged.connect(this, this.reformatCalendarPage); this.previewLayout = new QGridLayout(); this.previewLayout.addWidget(this.calendar, 0, 0, Qt.AlignmentFlag.AlignCenter); this.previewGroupBox.setLayout(this.previewLayout); } CalendarWidget.prototype.createGeneralOptionsGroupBox = function() { this.generalOptionsGroupBox = new QGroupBox(tr("General Options")); this.localeCombo = new QComboBox(); var curLocaleIndex = -1; var index = 0; for (var lang in QLocale.Language) { var countries = QLocale.countriesForLanguage(lang); for (var country in countries) { var label = QLocale.languageToString(lang); label += "/"; label += QLocale.countryToString(country); var locale = new QLocale(lang, country); if (this.locale().language() == lang && this.locale().country() == country) curLocaleIndex = index; localeCombo.addItem(label, locale); ++index; } } if (curLocaleIndex != -1) localeCombo.setCurrentIndex(curLocaleIndex); this.localeLabel = new QLabel(tr("&Locale")); this.localeLabel.setBuddy(this.localeCombo); this.firstDayCombo = new QComboBox(); this.firstDayCombo.addItem(null, tr("Sunday"), Qt.DayOfWeek.Sunday); this.firstDayCombo.addItem(null, tr("Monday"), Qt.DayOfWeek.Monday); this.firstDayCombo.addItem(null, tr("Tuesday"), Qt.DayOfWeek.Tuesday); this.firstDayCombo.addItem(null, tr("Wednesday"), Qt.DayOfWeek.Wednesday); this.firstDayCombo.addItem(null, tr("Thursday"), Qt.DayOfWeek.Thursday); this.firstDayCombo.addItem(null, tr("Friday"), Qt.DayOfWeek.Friday); this.firstDayCombo.addItem(null, tr("Saturday"), Qt.DayOfWeek.Saturday); this.firstDayLabel = new QLabel(tr("Wee&k starts on:")); this.firstDayLabel.setBuddy(this.firstDayCombo); this.selectionModeCombo = new QComboBox(); this.selectionModeCombo.addItem(null, tr("Single selection"), QCalendarWidget.SelectionMode.SingleSelection); this.selectionModeCombo.addItem(null, tr("None"), QCalendarWidget.SelectionMode.NoSelection); this.selectionModeLabel = new QLabel(tr("&Selection mode:")); this.selectionModeLabel.setBuddy(this.selectionModeCombo); this.gridCheckBox = new QCheckBox(tr("&Grid")); this.gridCheckBox.setChecked(this.calendar.gridVisible); this.navigationCheckBox = new QCheckBox(tr("&Navigation bar")); this.navigationCheckBox.setChecked(true); this.horizontalHeaderCombo = new QComboBox(); this.horizontalHeaderCombo.addItem(null, tr("Single letter day names"), QCalendarWidget.HorizontalHeaderFormat.SingleLetterDayNames); this.horizontalHeaderCombo.addItem(null, tr("Short day names"), QCalendarWidget.HorizontalHeaderFormat.ShortDayNames); this.horizontalHeaderCombo.addItem(null, tr("None"), QCalendarWidget.HorizontalHeaderFormat.NoHorizontalHeader); this.horizontalHeaderCombo.setCurrentIndex(1); this.horizontalHeaderLabel = new QLabel(tr("&Horizontal header:")); this.horizontalHeaderLabel.setBuddy(this.horizontalHeaderCombo); this.verticalHeaderCombo = new QComboBox(); this.verticalHeaderCombo.addItem(null, tr("ISO week numbers"), QCalendarWidget.VerticalHeaderFormat.ISOWeekNumbers); this.verticalHeaderCombo.addItem(null, tr("None"), QCalendarWidget.VerticalHeaderFormat.NoVerticalHeader); this.verticalHeaderLabel = new QLabel(tr("&Vertical header:")); this.verticalHeaderLabel.setBuddy(this.verticalHeaderCombo); this.localeCombo['currentIndexChanged(int)'].connect(this, this.localeChanged); this.firstDayCombo['currentIndexChanged(int)'].connect(this, this.firstDayChanged); this.selectionModeCombo['currentIndexChanged(int)'].connect(this, this.selectionModeChanged); this.gridCheckBox.toggled.connect(this, this.calendar.setGridVisible); this.navigationCheckBox.toggled.connect(this, this.calendar.setNavigationBarVisible); this.horizontalHeaderCombo['currentIndexChanged(int)'].connect(this, this.horizontalHeaderChanged); this.verticalHeaderCombo['currentIndexChanged(int)'].connect(this, "verticalHeaderChanged"); var checkBoxLayout = new QHBoxLayout(); checkBoxLayout.addWidget(this.gridCheckBox, 0, Qt.AlignmentFlag(1)); //FIXME checkBoxLayout.addStretch(); checkBoxLayout.addWidget(this.navigationCheckBox, 0, Qt.AlignmentFlag(1)); //FIXME var outerLayout = new QGridLayout(); outerLayout.addWidget(this.localeLabel, 0, 0); outerLayout.addWidget(this.localeCombo, 0, 1); outerLayout.addWidget(this.firstDayLabel, 1, 0); outerLayout.addWidget(this.firstDayCombo, 1, 1); outerLayout.addWidget(this.selectionModeLabel, 2, 0); outerLayout.addWidget(this.selectionModeCombo, 2, 1); outerLayout.addLayout(checkBoxLayout, 3, 0, 1, 2); outerLayout.addWidget(this.horizontalHeaderLabel, 4, 0); outerLayout.addWidget(this.horizontalHeaderCombo, 4, 1); outerLayout.addWidget(this.verticalHeaderLabel, 5, 0); outerLayout.addWidget(this.verticalHeaderCombo, 5, 1); this.generalOptionsGroupBox.setLayout(outerLayout); this.firstDayChanged(this.firstDayCombo.currentIndex); this.selectionModeChanged(this.selectionModeCombo.currentIndex); this.horizontalHeaderChanged(this.horizontalHeaderCombo.currentIndex); this.verticalHeaderChanged(this.verticalHeaderCombo.currentIndex); } CalendarWidget.prototype.createDatesGroupBox = function() { this.datesGroupBox = new QGroupBox(tr("Dates")); this.minimumDateEdit = new QDateEdit(); this.minimumDateEdit.displayFormat = "MMM d, yyyy"; this.minimumDateEdit.setDateRange(this.calendar.minimumDate, this.calendar.maximumDate); this.minimumDateEdit.setDate(this.calendar.minimumDate); this.minimumDateLabel = new QLabel(tr("&Minimum Date:")); this.minimumDateLabel.setBuddy(this.minimumDateEdit); this.currentDateEdit = new QDateEdit(); this.currentDateEdit.displayFormat = "MMM d, yyyy"; this.currentDateEdit.setDate(this.calendar.selectedDate); this.currentDateEdit.setDateRange(this.calendar.minimumDate, this.calendar.maximumDate); this.currentDateLabel = new QLabel(tr("&Current Date:")); this.currentDateLabel.setBuddy(this.currentDateEdit); this.maximumDateEdit = new QDateEdit(); this.maximumDateEdit.displayFormat = "MMM d, yyyy"; this.maximumDateEdit.setDateRange(this.calendar.minimumDate, this.calendar.maximumDate); this.maximumDateEdit.setDate(this.calendar.maximumDate); this.maximumDateLabel = new QLabel(tr("Ma&ximum Date:")); this.maximumDateLabel.setBuddy(this.maximumDateEdit); this.currentDateEdit.dateChanged.connect(this, this.calendar.setSelectedDate); this.calendar.selectionChanged.connect(this, this.selectedDateChanged); this.minimumDateEdit.dateChanged.connect(this, this.minimumDateChanged); this.maximumDateEdit.dateChanged.connect(this, this.maximumDateChanged); var dateBoxLayout = new QGridLayout(); dateBoxLayout.addWidget(this.currentDateLabel, 1, 0); dateBoxLayout.addWidget(this.currentDateEdit, 1, 1); dateBoxLayout.addWidget(this.minimumDateLabel, 0, 0); dateBoxLayout.addWidget(this.minimumDateEdit, 0, 1); dateBoxLayout.addWidget(this.maximumDateLabel, 2, 0); dateBoxLayout.addWidget(this.maximumDateEdit, 2, 1); dateBoxLayout.setRowStretch(3, 1); this.datesGroupBox.setLayout(dateBoxLayout); } CalendarWidget.prototype.createTextFormatsGroupBox = function() { this.textFormatsGroupBox = new QGroupBox(tr("Text Formats")); this.weekdayColorCombo = this.createColorComboBox(); this.weekdayColorCombo.setCurrentIndex(this.weekdayColorCombo.findText(tr("Black"))); this.weekdayColorLabel = new QLabel(tr("&Weekday color:")); this.weekdayColorLabel.setBuddy(this.weekdayColorCombo); this.weekendColorCombo = this.createColorComboBox(); this.weekendColorCombo.setCurrentIndex(this.weekendColorCombo.findText(tr("Red"))); this.weekendColorLabel = new QLabel(tr("Week&end color:")); this.weekendColorLabel.setBuddy(this.weekendColorCombo); this.headerTextFormatCombo = new QComboBox(); this.headerTextFormatCombo.addItem(tr("Bold")); this.headerTextFormatCombo.addItem(tr("Italic")); this.headerTextFormatCombo.addItem(tr("Plain")); this.headerTextFormatLabel = new QLabel(tr("&Header text:")); this.headerTextFormatLabel.setBuddy(this.headerTextFormatCombo); this.firstFridayCheckBox = new QCheckBox(tr("&First Friday in blue")); this.mayFirstCheckBox = new QCheckBox(tr("May &1 in red")); this.weekdayColorCombo['currentIndexChanged(int)'].connect(this, this.weekdayFormatChanged); this.weekendColorCombo['currentIndexChanged(int)'].connect(this, this.weekendFormatChanged); this.headerTextFormatCombo['currentIndexChanged(int)'].connect(this, this.reformatHeaders); this.firstFridayCheckBox.toggled.connect(this, this.reformatCalendarPage); this.mayFirstCheckBox.toggled.connect(this, this.reformatCalendarPage); var checkBoxLayout = new QHBoxLayout(); checkBoxLayout.addWidget(this.firstFridayCheckBox, 0, Qt.AlignmentFlag(1)); checkBoxLayout.addStretch(); checkBoxLayout.addWidget(this.mayFirstCheckBox, 0, Qt.AlignmentFlag(1)); var outerLayout = new QGridLayout(); outerLayout.addWidget(this.weekdayColorLabel, 0, 0); outerLayout.addWidget(this.weekdayColorCombo, 0, 1); outerLayout.addWidget(this.weekendColorLabel, 1, 0); outerLayout.addWidget(this.weekendColorCombo, 1, 1); outerLayout.addWidget(this.headerTextFormatLabel, 2, 0); outerLayout.addWidget(this.headerTextFormatCombo, 2, 1); outerLayout.addLayout(checkBoxLayout, 3, 0, 1, 2); this.textFormatsGroupBox.setLayout(outerLayout); this.weekdayFormatChanged(); this.weekendFormatChanged(); this.reformatHeaders(); this.reformatCalendarPage(); } CalendarWidget.prototype.createColorComboBox = function() { var comboBox = new QComboBox(); comboBox.addItem(null, tr("Red"), new QColor(Qt.red)); comboBox.addItem(null, tr("Blue"), new QColor(Qt.blue)); comboBox.addItem(null, tr("Black"), new QColor(Qt.black)); comboBox.addItem(null, tr("Magenta"), new QColor(Qt.magenta)); return comboBox; } var calendarWidget = new CalendarWidget(null); calendarWidget.show(); QCoreApplication.exec(); qtscriptgenerator-src-0.2.0/examples/CollidingMice.js000066400000000000000000000173401170724227300227460ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ function Mouse(parent) { QGraphicsItem.call(this, parent); this.angle = 0; this.speed = 0; this.mouseEyeDirection = 0; var adjust = 0.5; this._boundingRect = new QRectF(-20 - adjust, -22 - adjust, 40 + adjust, 83 + adjust); this.boundingRect = function() { return this._boundingRect; }; this._shape = new QPainterPath(); this._shape.addRect(-10, -20, 20, 40); this.shape = function() { return this._shape; } this._brush = new QBrush(Qt.SolidPattern); this._tail = new QPainterPath(new QPointF(0, 20)); this._tail.cubicTo(-5, 22, -5, 22, 0, 25); this._tail.cubicTo(5, 27, 5, 32, 0, 30); this._tail.cubicTo(-5, 32, -5, 42, 0, 35); this._pupilRect1 = new QRectF(-8 + this.mouseEyeDirection, -17, 4, 4); this._pupilRect2 = new QRectF(4 + this.mouseEyeDirection, -17, 4, 4); this.color = new QColor(Math.random()*256, Math.random()*256, Math.random()*256); this.rotate(Math.random()*360); var timer = new QTimer(this); timer.singleShot = false; timer.timeout.connect(this, function() { this.move(); }); timer.start(1000 / 33); } Mouse.prototype = new QGraphicsItem(); Mouse.prototype.paint = function(painter, styleOptionGraphicsItem, widget) { // Body painter.setBrush(new QBrush(this.color)); painter.drawEllipse(-10, -20, 20, 40); // Eyes this._brush.setColor(Qt.white); painter.setBrush(this._brush); painter.drawEllipse(-10, -17, 8, 8); painter.drawEllipse(2, -17, 8, 8); // Nose this._brush.setColor(Qt.black); painter.setBrush(this._brush); painter.drawEllipse(-2, -22, 4, 4); // Pupils painter.drawEllipse(this._pupilRect1); painter.drawEllipse(this._pupilRect2); // Ears // if (this.scene().collidingItems(this).length == 0) FIXME: const QGraphicsItem* if (this.scene().items(this.pos()).length == 1) this._brush.setColor(Qt.darkYellow); else this._brush.setColor(Qt.red); painter.setBrush(this._brush); painter.drawEllipse(-17, -12, 16, 16); painter.drawEllipse(1, -12, 16, 16); // Tail painter.setBrush(Qt.NoBrush); painter.drawPath(this._tail); } Mouse.prototype.move = function() { // Don't move too far away var lineToCenter = new QLineF(Mouse.origo, this.mapFromScene(0, 0)); if (lineToCenter.length() > 150) { var angleToCenter = Math.acos(lineToCenter.dx() / lineToCenter.length()); if (lineToCenter.dy() < 0) angleToCenter = Mouse.TWO_PI - angleToCenter; angleToCenter = Mouse.normalizeAngle((Math.PI - angleToCenter) + Math.PI / 2); if (angleToCenter < Math.PI && angleToCenter > Math.PI / 4) { // Rotate left this.angle += (this.angle < -Math.PI / 2) ? 0.25 : -0.25; } else if (angleToCenter >= Math.PI && angleToCenter < (Math.PI + Math.PI / 2 + Math.PI / 4)) { // Rotate right this.angle += (this.angle < Math.PI / 2) ? 0.25 : -0.25; } } else if (Math.sin(this.angle) < 0) { this.angle += 0.25; } else if (Math.sin(this.angle) > 0) { this.angle -= 0.25; } // Try not to crash with any other mice var polygon = new QPolygonF( [ this.mapToScene(0, 0), this.mapToScene(-30, -50), this.mapToScene(30, -50) ] ); var dangerMice = this.scene().items(polygon); for (var i = 0; i < dangerMice.length; ++i) { var item = dangerMice[i]; if (item == this) continue; var lineToMouse = new QLineF(Mouse.origo, this.mapFromItem(item, 0, 0)); var angleToMouse = Math.acos(lineToMouse.dx() / lineToMouse.length()); if (lineToMouse.dy() < 0) angleToMouse = Mouse.TWO_PI - angleToMouse; angleToMouse = Mouse.normalizeAngle((Math.PI - angleToMouse) + Math.PI / 2); if (angleToMouse >= 0 && angleToMouse < (Math.PI / 2)) { // Rotate right this.angle += 0.5; } else if (angleToMouse <= Mouse.TWO_PI && angleToMouse > (Mouse.TWO_PI - Math.PI / 2)) { // Rotate left this.angle -= 0.5; } } // Add some random movement if (dangerMice.length < 1 && Math.random() < 0.1) { if (Math.random() > 0.5) this.angle += Math.random() / 5; else this.angle -= Math.random() / 5; } this.speed += (-50 + Math.random() * 100) / 100.0; var dx = Math.sin(this.angle) * 10; this.mouseEyeDirection = (Math.abs(dx / 5) < 1) ? 0 : dx / 5; this.rotate(dx); this.setPos(this.mapToParent(0, -(3 + Math.sin(this.speed) * 3))); } Mouse.normalizeAngle = function(angle) { while (angle < 0) angle += Mouse.TWO_PI; while (angle > Mouse.TWO_PI) angle -= Mouse.TWO_PI; return angle; } Mouse.TWO_PI = Math.PI * 2; Mouse.origo = new QPointF(0, 0); function CollidingMice(parent) { QWidget.call(this, parent); var scene = new QGraphicsScene(this); scene.setSceneRect(-300, -300, 600, 600); scene.itemIndexMethod = QGraphicsScene.NoIndex; for (var i = 0; i < CollidingMice.MOUSE_COUNT; ++i) { var mouse = new Mouse(this); mouse.setPos(Math.sin((i * 6.28) / CollidingMice.MOUSE_COUNT) * 200, Math.cos((i * 6.28) / CollidingMice.MOUSE_COUNT) * 200); scene.addItem(mouse); } var view = new QGraphicsView(scene, this); view.setRenderHint(QPainter.Antialiasing); view.backgroundBrush = new QBrush(new QPixmap("images/cheese.png")); view.cacheMode = new QGraphicsView.CacheMode(QGraphicsView.CacheBackground); view.dragMode = QGraphicsView.ScrollHandDrag; view.viewportUpdateMode = QGraphicsView.FullViewportUpdate; var layout = new QGridLayout(); layout.addWidget(view, 0, 0); this.setLayout(layout); this.setWindowTitle("Colliding Mice"); this.resize(400, 300); } CollidingMice.prototype = new QWidget(); CollidingMice.MOUSE_COUNT = 7; var collidingMice = new CollidingMice(null); collidingMice.show(); QCoreApplication.exec(); qtscriptgenerator-src-0.2.0/examples/ConcentricCircles.js000066400000000000000000000107301170724227300236340ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ function tr(s) { return s; } function CircleWidget(parent) { QWidget.call(this, parent); this.floatBased = false; this.antialiased = false; this.frameNo = 0; this.setBackgroundRole(QPalette.Base); this.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding); } CircleWidget.prototype = new QWidget(); CircleWidget.prototype.setFloatBased = function(floatBased) { this.floatBased = floatBased; this.update(); } CircleWidget.prototype.setAntialiased = function(antialiased) { this.antialiased = antialiased; this.update(); } CircleWidget.prototype.getMinimumSizeHint = function() { return new QSize(50, 50); } CircleWidget.prototype.getSizeHint = function() { return new QSize(180, 180); } CircleWidget.prototype.nextAnimationFrame = function() { ++this.frameNo; this.update(); } CircleWidget.prototype.paintEvent = function(/* event */) { var painter = new QPainter(); painter.begin(this); painter.setRenderHint(QPainter.Antialiasing, this.antialiased); painter.translate(this.width / 2, this.height / 2); for (var diameter = 0; diameter < 256; diameter += 9) { var delta = Math.abs((this.frameNo % 128) - diameter / 2); var alpha = 255 - (delta * delta) / 4 - diameter; if (alpha > 0) { painter.setPen(new QPen(new QColor(0, diameter / 2, 127, alpha), 3)); if (this.floatBased) { painter.drawEllipse(new QRectF(-diameter / 2.0, -diameter / 2.0, diameter, diameter)); } else { painter.drawEllipse(new QRect(-diameter / 2, -diameter / 2, diameter, diameter)); } } } painter.end(); } function Window(parent) { QWidget.call(this, parent); var aliasedLabel = this.createLabel(tr("Aliased")); var antialiasedLabel = this.createLabel(tr("Antialiased")); var intLabel = this.createLabel(tr("Int")); var floatLabel = this.createLabel(tr("Float")); var layout = new QGridLayout(); layout.addWidget(aliasedLabel, 0, 1); layout.addWidget(antialiasedLabel, 0, 2); layout.addWidget(intLabel, 1, 0); layout.addWidget(floatLabel, 2, 0); var timer = new QTimer(this); for (var i = 0; i < 2; ++i) { for (var j = 0; j < 2; ++j) { var cw = new CircleWidget(); cw.setAntialiased(j != 0); cw.setFloatBased(i != 0); timer.timeout.connect( cw, cw.nextAnimationFrame); layout.addWidget(cw, i + 1, j + 1); } } timer.start(100); this.setLayout(layout); this.windowTitle = tr("Concentric Circles"); } Window.prototype = new QWidget(); Window.prototype.createLabel = function(text) { var label = new QLabel(text); label.alignment = Qt.AlignCenter; label.margin = 2; label.setFrameStyle(QFrame.Box | QFrame.Sunken); return label; } var win = new Window(); win.show(); QCoreApplication.exec(); qtscriptgenerator-src-0.2.0/examples/DigitalClock.js000066400000000000000000000042611170724227300225730ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ function tr(s) { return s; } function DigitalClock(parent) { QLCDNumber.call(this, parent); this.segmentStyle = QLCDNumber.Filled; var timer = new QTimer(this); timer.timeout.connect(this, this.showTime); timer.start(1000); this.showTime(); this.windowTitle = tr("Digital Clock"); this.resize(150, 60); } DigitalClock.prototype = new QLCDNumber(); DigitalClock.prototype.showTime = function() { var time = QTime.currentTime(); var format = "hh"; format += ((time.second() % 2) == 0) ? " " : ":"; format += "mm"; var text = time.toString(format); this.display(text); } var clock = new DigitalClock(5); // ### fixme clock.show(); QCoreApplication.exec(); qtscriptgenerator-src-0.2.0/examples/ImageComposition.js000066400000000000000000000145131170724227300235110ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ function tr(s) { return s; } function ImageComposer(parent) { QWidget.call(this, parent); this.sourceButton = new QToolButton(); this.sourceButton.setIconSize(ImageComposer.resultSize); this.operatorComboBox = new QComboBox(); this.addOp(QPainter.CompositionMode_SourceOver, tr("SourceOver")); this.addOp(QPainter.CompositionMode_DestinationOver, tr("DestinationOver")); this.addOp(QPainter.CompositionMode_Clear, tr("Clear")); this.addOp(QPainter.CompositionMode_Source, tr("Source")); this.addOp(QPainter.CompositionMode_Destination, tr("Destination")); this.addOp(QPainter.CompositionMode_SourceIn, tr("SourceIn")); this.addOp(QPainter.CompositionMode_DestinationIn, tr("DestinationIn")); this.addOp(QPainter.CompositionMode_SourceOut, tr("SourceOut")); this.addOp(QPainter.CompositionMode_DestinationOut, tr("DestinationOut")); this.addOp(QPainter.CompositionMode_SourceAtop, tr("SourceAtop")); this.addOp(QPainter.CompositionMode_DestinationAtop, tr("DestinationAtop")); this.addOp(QPainter.CompositionMode_Xor, tr("Xor")); this.destinationButton = new QToolButton(); this.destinationButton.setIconSize(ImageComposer.resultSize); this.equalLabel = new QLabel(tr("=")); this.resultLabel = new QLabel(); this.resultLabel.minimumWidth = ImageComposer.resultSize.width(); this.sourceButton["clicked()"].connect(this, this.chooseSource); this.operatorComboBox["activated(int)"].connect( this, this.recalculateResult); this.destinationButton["clicked()"].connect( this, this.chooseDestination); var mainLayout = new QGridLayout(); mainLayout.addWidget(this.sourceButton, 0, 0, 3, 1); mainLayout.addWidget(this.operatorComboBox, 1, 1); mainLayout.addWidget(this.destinationButton, 0, 2, 3, 1); mainLayout.addWidget(this.equalLabel, 1, 3); mainLayout.addWidget(this.resultLabel, 0, 4, 3, 1); mainLayout.sizeConstraint = QLayout.SetFixedSize; this.setLayout(mainLayout); this.sourceImage = new QImage(); this.destinationImage = new QImage(); this.resultImage = new QImage(ImageComposer.resultSize, QImage.Format_ARGB32_Premultiplied); this.loadImage("images/butterfly.png", "sourceImage", this.sourceButton); this.loadImage("images/checker.png", "destinationImage", this.destinationButton); this.windowTitle = tr("Image Composition"); } ImageComposer.resultSize = new QSize(200, 200); ImageComposer.prototype = new QWidget(); ImageComposer.prototype.chooseSource = function() { this.chooseImage(tr("Choose Source Image"), "sourceImage", this.sourceButton); } ImageComposer.prototype.chooseDestination = function() { this.chooseImage(tr("Choose Destination Image"), "destinationImage", this.destinationButton); } ImageComposer.prototype.recalculateResult = function() { var mode = this.currentMode(); var painter = new QPainter(this.resultImage); painter.setCompositionMode(QPainter.CompositionMode_Source); painter.fillRect(this.resultImage.rect(), new QBrush(new QColor(Qt.transparent))); painter.setCompositionMode(QPainter.CompositionMode_SourceOver); painter.drawImage(0, 0, this.destinationImage); painter.setCompositionMode(mode); painter.drawImage(0, 0, this.sourceImage); painter.setCompositionMode(QPainter.CompositionMode_DestinationOver); painter.fillRect(this.resultImage.rect(), new QBrush(new QColor(Qt.white))); painter.end(); this.resultLabel.setPixmap(QPixmap.fromImage(this.resultImage)); } ImageComposer.prototype.addOp = function(mode, name) { this.operatorComboBox.addItem(name, mode); } ImageComposer.prototype.chooseImage = function(title, property, button) { var fileName = QFileDialog.getOpenFileName(this, title); if (!fileName.isEmpty()) loadImage(fileName, property, button); } ImageComposer.prototype.loadImage = function(fileName, property, button) { var image = new QImage(fileName); var fixedImage = new QImage(ImageComposer.resultSize, QImage.Format_ARGB32_Premultiplied); var painter = new QPainter(fixedImage); painter.setCompositionMode(QPainter.CompositionMode_Source); painter.fillRect(fixedImage.rect(), new QBrush(new QColor(Qt.transparent))); painter.setCompositionMode(QPainter.CompositionMode_SourceOver); painter.drawImage(this.imagePos(image), image); painter.end(); button.icon = new QIcon(QPixmap.fromImage(fixedImage)); this[property] = fixedImage; this.recalculateResult(); } ImageComposer.prototype.currentMode = function() { return this.operatorComboBox.itemData(this.operatorComboBox.currentIndex); } ImageComposer.prototype.imagePos = function(image) { return new QPoint((ImageComposer.resultSize.width() - image.width()) / 2, (ImageComposer.resultSize.height() - image.height()) / 2); } var composer = new ImageComposer(); composer.show(); QCoreApplication.exec(); qtscriptgenerator-src-0.2.0/examples/LineEdits.js000066400000000000000000000164051170724227300221250ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ function tr(s) { return s; } function Window(parent) { QWidget.call(this, parent); var echoGroup = new QGroupBox(tr("Echo")); var echoLabel = new QLabel(tr("Mode:")); var echoComboBox = new QComboBox(); echoComboBox.addItem(tr("Normal")); echoComboBox.addItem(tr("Password")); echoComboBox.addItem(tr("PasswordEchoOnEdit")); echoComboBox.addItem(tr("No Echo")); this.echoLineEdit = new QLineEdit(); this.echoLineEdit.setFocus(); var validatorGroup = new QGroupBox(tr("Validator")); var validatorLabel = new QLabel(tr("Type:")); var validatorComboBox = new QComboBox(); validatorComboBox.addItem(tr("No validator")); validatorComboBox.addItem(tr("Integer validator")); validatorComboBox.addItem(tr("Double validator")); this.validatorLineEdit = new QLineEdit(); var alignmentGroup = new QGroupBox(tr("Alignment")); var alignmentLabel = new QLabel(tr("Type:")); var alignmentComboBox = new QComboBox(); alignmentComboBox.addItem(tr("Left")); alignmentComboBox.addItem(tr("Centered")); alignmentComboBox.addItem(tr("Right")); this.alignmentLineEdit = new QLineEdit(); var inputMaskGroup = new QGroupBox(tr("Input mask")); var inputMaskLabel = new QLabel(tr("Type:")); var inputMaskComboBox = new QComboBox; inputMaskComboBox.addItem(tr("No mask")); inputMaskComboBox.addItem(tr("Phone number")); inputMaskComboBox.addItem(tr("ISO date")); inputMaskComboBox.addItem(tr("License key")); this.inputMaskLineEdit = new QLineEdit(); var accessGroup = new QGroupBox(tr("Access")); var accessLabel = new QLabel(tr("Read-only:")); var accessComboBox = new QComboBox; accessComboBox.addItem(tr("False")); accessComboBox.addItem(tr("True")); this.accessLineEdit = new QLineEdit(); echoComboBox["activated(int)"].connect( this, "echoChanged"); validatorComboBox["activated(int)"].connect( this, "validatorChanged"); alignmentComboBox["activated(int)"].connect( this, "alignmentChanged"); inputMaskComboBox["activated(int)"].connect( this, "inputMaskChanged"); accessComboBox["activated(int)"].connect( this, "accessChanged"); var echoLayout = new QGridLayout; echoLayout.addWidget(echoLabel, 0, 0); echoLayout.addWidget(echoComboBox, 0, 1); echoLayout.addWidget(this.echoLineEdit, 1, 0, 1, 2); echoGroup.setLayout(echoLayout); var validatorLayout = new QGridLayout; validatorLayout.addWidget(validatorLabel, 0, 0); validatorLayout.addWidget(validatorComboBox, 0, 1); validatorLayout.addWidget(this.validatorLineEdit, 1, 0, 1, 2); validatorGroup.setLayout(validatorLayout); var alignmentLayout = new QGridLayout; alignmentLayout.addWidget(alignmentLabel, 0, 0); alignmentLayout.addWidget(alignmentComboBox, 0, 1); alignmentLayout.addWidget(this.alignmentLineEdit, 1, 0, 1, 2); alignmentGroup.setLayout(alignmentLayout); var inputMaskLayout = new QGridLayout; inputMaskLayout.addWidget(inputMaskLabel, 0, 0); inputMaskLayout.addWidget(inputMaskComboBox, 0, 1); inputMaskLayout.addWidget(this.inputMaskLineEdit, 1, 0, 1, 2); inputMaskGroup.setLayout(inputMaskLayout); var accessLayout = new QGridLayout; accessLayout.addWidget(accessLabel, 0, 0); accessLayout.addWidget(accessComboBox, 0, 1); accessLayout.addWidget(this.accessLineEdit, 1, 0, 1, 2); accessGroup.setLayout(accessLayout); var layout = new QGridLayout; layout.addWidget(echoGroup, 0, 0); layout.addWidget(validatorGroup, 1, 0); layout.addWidget(alignmentGroup, 2, 0); layout.addWidget(inputMaskGroup, 0, 1); layout.addWidget(accessGroup, 1, 1); this.setLayout(layout); this.setWindowTitle(tr("Line Edits")); } Window.prototype = new QWidget(); Window.prototype.echoChanged = function(index) { switch (index) { case 0: this.echoLineEdit.echoMode = QLineEdit.Normal; break; case 1: this.echoLineEdit.echoMode = QLineEdit.Password; break; case 2: this.echoLineEdit.echoMode = QLineEdit.PasswordEchoOnEdit; break; case 3: this.echoLineEdit.echoMode = QLineEdit.NoEcho; break; } }; Window.prototype.validatorChanged = function(index) { switch (index) { case 0: this.validatorLineEdit.setValidator(null); break; case 1: this.validatorLineEdit.setValidator( new QIntValidator(this.validatorLineEdit)); break; case 2: this.validatorLineEdit.setValidator( new QDoubleValidator(-999.0, 999.0, 2, this.validatorLineEdit)); break; } this.validatorLineEdit.clear(); }; Window.prototype.alignmentChanged = function(index) { switch (index) { case 0: this.alignmentLineEdit.alignment = Qt.Alignment(Qt.AlignLeft); break; case 1: this.alignmentLineEdit.alignment = Qt.Alignment(Qt.AlignCenter); break; case 2: this.alignmentLineEdit.alignment = Qt.Alignment(Qt.AlignRight); } }; Window.prototype.inputMaskChanged = function(index) { switch (index) { case 0: this.inputMaskLineEdit.inputMask = ""; break; case 1: this.inputMaskLineEdit.inputMask = "+99 99 99 99 99;_"; break; case 2: this.inputMaskLineEdit.inputMask = "0000-00-00"; this.inputMaskLineEdit.text = "00000000"; this.inputMaskLineEdit.cursorPosition = 0; break; case 3: this.inputMaskLineEdit.inputMask = ">AAAAA-AAAAA-AAAAA-AAAAA-AAAAA;#"; } }; Window.prototype.accessChanged = function(index) { switch (index) { case 0: this.accessLineEdit.readOnly = false; break; case 1: this.accessLineEdit.readOnly = true; } }; var win = new Window(null); win.show(); QCoreApplication.exec(); qtscriptgenerator-src-0.2.0/examples/PainterPaths.js000066400000000000000000000247511170724227300226520ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ function tr(s) { return s; } function RenderArea(path, parent) { QWidget.call(this, parent); this.path = path; this.penWidth = 1; this.rotationAngle = 0; this.setBackgroundRole(QPalette.Base); } RenderArea.prototype = new QWidget(); RenderArea.prototype.getMinimumSizeHint = function() { return new QSize(50, 50); } RenderArea.prototype.getSizeHint = function() { return new QSize(100, 100); } RenderArea.prototype.setFillRule = function(rule) { this.path.setFillRule(rule); this.update(); } RenderArea.prototype.setFillGradient = function(color1, color2) { this.fillColor1 = color1; this.fillColor2 = color2; this.update(); } RenderArea.prototype.setPenWidth = function(width) { this.penWidth = width; this.update(); } RenderArea.prototype.setPenColor = function(color) { this.penColor = color; this.update(); } RenderArea.prototype.setRotationAngle = function(degrees) { this.rotationAngle = degrees; this.update(); } RenderArea.prototype.paintEvent = function() { var painter = new QPainter(); painter.begin(this); painter.setRenderHint(QPainter.Antialiasing); painter.scale(this.width / 100.0, this.height / 100.0); painter.translate(50.0, 50.0); painter.rotate(-this.rotationAngle); painter.translate(-50.0, -50.0); painter.setPen(new QPen(this.penColor, this.penWidth, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)); var gradient = new QLinearGradient(0, 0, 0, 100); gradient.setColorAt(0.0, this.fillColor1); gradient.setColorAt(1.0, this.fillColor2); painter.setBrush(new QBrush(gradient)); painter.drawPath(this.path); painter.end(); } function Window(parent) { QWidget.call(this, parent); var rectPath = new QPainterPath(); rectPath.moveTo(20.0, 30.0); rectPath.lineTo(80.0, 30.0); rectPath.lineTo(80.0, 70.0); rectPath.lineTo(20.0, 70.0); rectPath.closeSubpath(); var roundRectPath = new QPainterPath(); roundRectPath.moveTo(80.0, 35.0); roundRectPath.arcTo(70.0, 30.0, 10.0, 10.0, 0.0, 90.0); roundRectPath.lineTo(25.0, 30.0); roundRectPath.arcTo(20.0, 30.0, 10.0, 10.0, 90.0, 90.0); roundRectPath.lineTo(20.0, 65.0); roundRectPath.arcTo(20.0, 60.0, 10.0, 10.0, 180.0, 90.0); roundRectPath.lineTo(75.0, 70.0); roundRectPath.arcTo(70.0, 60.0, 10.0, 10.0, 270.0, 90.0); roundRectPath.closeSubpath(); var ellipsePath = new QPainterPath(); ellipsePath.moveTo(80.0, 50.0); ellipsePath.arcTo(20.0, 30.0, 60.0, 40.0, 0.0, 360.0); var piePath = new QPainterPath(); piePath.moveTo(50.0, 50.0); piePath.arcTo(20.0, 30.0, 60.0, 40.0, 60.0, 240.0); piePath.closeSubpath(); var polygonPath = new QPainterPath(); polygonPath.moveTo(10.0, 80.0); polygonPath.lineTo(20.0, 10.0); polygonPath.lineTo(80.0, 30.0); polygonPath.lineTo(90.0, 70.0); polygonPath.closeSubpath(); var groupPath = new QPainterPath(); groupPath.moveTo(60.0, 40.0); groupPath.arcTo(20.0, 20.0, 40.0, 40.0, 0.0, 360.0); groupPath.moveTo(40.0, 40.0); groupPath.lineTo(40.0, 80.0); groupPath.lineTo(80.0, 80.0); groupPath.lineTo(80.0, 40.0); groupPath.closeSubpath(); var textPath = new QPainterPath(); var timesFont = new QFont("Times", 50); timesFont.setStyleStrategy(QFont.ForceOutline); textPath.addText(10, 70, timesFont, tr("Qt")); var bezierPath = new QPainterPath(); bezierPath.moveTo(20, 30); bezierPath.cubicTo(80, 0, 50, 50, 80, 80); var starPath = new QPainterPath(); starPath.moveTo(90, 50); for (var i = 1; i < 5; ++i) { starPath.lineTo(50 + 40 * Math.cos(0.8 * i * Math.PI), 50 + 40 * Math.sin(0.8 * i * Math.PI)); } starPath.closeSubpath(); this.renderAreas = new Array(Window.NumRenderAreas); this.renderAreas[0] = new RenderArea(rectPath); this.renderAreas[1] = new RenderArea(roundRectPath); this.renderAreas[2] = new RenderArea(ellipsePath); this.renderAreas[3] = new RenderArea(piePath); this.renderAreas[4] = new RenderArea(polygonPath); this.renderAreas[5] = new RenderArea(groupPath); this.renderAreas[6] = new RenderArea(textPath); this.renderAreas[7] = new RenderArea(bezierPath); this.renderAreas[8] = new RenderArea(starPath); this.fillRuleComboBox = new QComboBox(); this.fillRuleComboBox.addItem(tr("Odd Even"), Qt.OddEvenFill); this.fillRuleComboBox.addItem(tr("Winding"), Qt.WindingFill); this.fillRuleLabel = new QLabel(tr("Fill &Rule:")); this.fillRuleLabel.setBuddy(this.fillRuleComboBox); this.fillColor1ComboBox = new QComboBox(); this.populateWithColors(this.fillColor1ComboBox); this.fillColor1ComboBox.setCurrentIndex( this.fillColor1ComboBox.findText("mediumslateblue")); this.fillColor2ComboBox = new QComboBox(); this.populateWithColors(this.fillColor2ComboBox); this.fillColor2ComboBox.setCurrentIndex( this.fillColor2ComboBox.findText("cornsilk")); this.fillGradientLabel = new QLabel(tr("&Fill Gradient:")); this.fillGradientLabel.setBuddy(this.fillColor1ComboBox); this.fillToLabel = new QLabel(tr("to")); this.fillToLabel.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed); this.penWidthSpinBox = new QSpinBox(); this.penWidthSpinBox.setRange(0, 20); this.penWidthLabel = new QLabel(tr("&Pen Width:")); this.penWidthLabel.setBuddy(this.penWidthSpinBox); this.penColorComboBox = new QComboBox(); this.populateWithColors(this.penColorComboBox); this.penColorComboBox.setCurrentIndex( this.penColorComboBox.findText("darkslateblue")); this.penColorLabel = new QLabel(tr("Pen &Color:")); this.penColorLabel.setBuddy(this.penColorComboBox); this.rotationAngleSpinBox = new QSpinBox(); this.rotationAngleSpinBox.setRange(0, 359); this.rotationAngleSpinBox.wrapping = true; this.rotationAngleSpinBox.suffix = "\xB0"; this.rotationAngleLabel = new QLabel(tr("&Rotation Angle:")); this.rotationAngleLabel.setBuddy(this.rotationAngleSpinBox); this.fillRuleComboBox["activated(int)"].connect( this, this.fillRuleChanged); this.fillColor1ComboBox["activated(int)"].connect( this, this.fillGradientChanged); this.fillColor2ComboBox["activated(int)"].connect( this, this.fillGradientChanged); this.penColorComboBox["activated(int)"].connect( this, this.penColorChanged); for (var i = 0; i < Window.NumRenderAreas; ++i) { this.penWidthSpinBox["valueChanged(int)"].connect( this.renderAreas[i], this.renderAreas[i].setPenWidth); this.rotationAngleSpinBox["valueChanged(int)"].connect( this.renderAreas[i], this.renderAreas[i].setRotationAngle); } var topLayout = new QGridLayout(); for (var i = 0; i < Window.NumRenderAreas; ++i) topLayout.addWidget(this.renderAreas[i], i / 3, i % 3); var mainLayout = new QGridLayout(); mainLayout.addLayout(topLayout, 0, 0, 1, 4); mainLayout.addWidget(this.fillRuleLabel, 1, 0); mainLayout.addWidget(this.fillRuleComboBox, 1, 1, 1, 3); mainLayout.addWidget(this.fillGradientLabel, 2, 0); mainLayout.addWidget(this.fillColor1ComboBox, 2, 1); mainLayout.addWidget(this.fillToLabel, 2, 2); mainLayout.addWidget(this.fillColor2ComboBox, 2, 3); mainLayout.addWidget(this.penWidthLabel, 3, 0); mainLayout.addWidget(this.penWidthSpinBox, 3, 1, 1, 3); mainLayout.addWidget(this.penColorLabel, 4, 0); mainLayout.addWidget(this.penColorComboBox, 4, 1, 1, 3); mainLayout.addWidget(this.rotationAngleLabel, 5, 0); mainLayout.addWidget(this.rotationAngleSpinBox, 5, 1, 1, 3); this.setLayout(mainLayout); this.fillRuleChanged(); this.fillGradientChanged(); this.penColorChanged(); this.penWidthSpinBox.value = 2; this.windowTitle = tr("Painter Paths"); } Window.NumRenderAreas = 9; Window.prototype = new QWidget(); Window.prototype.fillRuleChanged = function() { var rule = Qt.FillRule(this.currentItemData(this.fillRuleComboBox)); for (var i = 0; i < Window.NumRenderAreas; ++i) this.renderAreas[i].setFillRule(rule); } Window.prototype.fillGradientChanged = function() { var color1 = this.currentItemData(this.fillColor1ComboBox); var color2 = this.currentItemData(this.fillColor2ComboBox); for (var i = 0; i < Window.NumRenderAreas; ++i) this.renderAreas[i].setFillGradient(color1, color2); } Window.prototype.penColorChanged = function() { var color = this.currentItemData(this.penColorComboBox); for (var i = 0; i < Window.NumRenderAreas; ++i) this.renderAreas[i].setPenColor(color); } Window.prototype.populateWithColors = function(comboBox) { var colorNames = QColor.colorNames(); for (var i = 0; i < colorNames.length; ++i) { var name = colorNames[i]; comboBox.addItem(name, new QColor(name)); } } Window.prototype.currentItemData = function(comboBox) { return comboBox.itemData(comboBox.currentIndex); } var win = new Window(); win.show(); QCoreApplication.exec(); qtscriptgenerator-src-0.2.0/examples/RSSListing.js000066400000000000000000000130561170724227300222450ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ function tr(s) { return s; } function RSSListing(parent) { QWidget.call(this, parent); this.xml = new QXmlStreamReader(); this.currentTag = ""; this.linkString = ""; this.titleString = ""; this.connectionId = -1; this.lineEdit = new QLineEdit(this); this.lineEdit.text = "http://labs.trolltech.com/blogs/feed"; this.fetchButton = new QPushButton(tr("Fetch"), this); this.abortButton = new QPushButton(tr("Abort"), this); this.abortButton.enabled = false; this.treeWidget = new QTreeWidget(this); this.treeWidget["itemActivated(QTreeWidgetItem*, int)"].connect( this, this.itemActivated); var headerLabels = new Array(); headerLabels.push(tr("Title")); headerLabels.push(tr("Link")); this.treeWidget.setHeaderLabels(headerLabels); this.treeWidget.header().setResizeMode(QHeaderView.ResizeToContents); this.http = new QHttp(this); this.http.readyRead.connect(this, this.readData); this.http.requestFinished.connect(this, this.finished); this.lineEdit.returnPressed.connect(this, this.fetch); this.fetchButton.clicked.connect(this, this.fetch); this.abortButton.clicked.connect(this.http, this.http.abort); var layout = new QVBoxLayout(this); var hboxLayout = new QHBoxLayout(); // ### working around problem with addWidget() binding hboxLayout.addWidget(this.lineEdit, 0, Qt.AlignLeft); hboxLayout.addWidget(this.fetchButton, 0, Qt.AlignLeft); hboxLayout.addWidget(this.abortButton, 0, Qt.AlignLeft); layout.addLayout(hboxLayout); layout.addWidget(this.treeWidget, 0, Qt.AlignLeft); this.windowTitle = tr("RSS listing example"); this.resize(640,480); } RSSListing.prototype = new QWidget(); RSSListing.prototype.fetch = function() { this.lineEdit.readOnly = true; this.fetchButton.enabled = false; this.abortButton.enabled = true; this.treeWidget.clear(); this.xml.clear(); var url = new QUrl(this.lineEdit.text); this.http.setHost(url.host()); this.connectionId = this.http.get(url.path()); } RSSListing.prototype.readData = function(resp) { if (resp.statusCode() != 200) this.http.abort(); else { this.xml.addData(this.http.readAll()); this.parseXml(); } } RSSListing.prototype.finished = function(id, error) { if (error) { print("Received error during HTTP fetch."); // ### qWarning() this.lineEdit.readOnly = false; this.abortButton.enabled = false; this.fetchButton.enabled = true; } else if (id == this.connectionId) { this.lineEdit.readOnly = false; this.abortButton.enabled = false; this.fetchButton.enabled = true; } } RSSListing.prototype.parseXml = function() { while (!this.xml.atEnd()) { this.xml.readNext(); if (this.xml.isStartElement()) { if (this.xml.name() == "item") this.linkString = this.xml.attributes().value("rss:about").toString(); this.currentTag = this.xml.name().toString(); } else if (this.xml.isEndElement()) { if (this.xml.name() == "item") { var item = new QTreeWidgetItem(); item.setText(0, this.titleString); item.setText(1, this.linkString); this.treeWidget.addTopLevelItem(item); this.titleString = ""; this.linkString = ""; } } else if (this.xml.isCharacters() && !this.xml.isWhitespace()) { if (this.currentTag == "title") this.titleString += this.xml.text().toString(); else if (this.currentTag == "link") this.linkString += this.xml.text().toString(); } } if (this.xml.hasError() && (this.xml.error() != QXmlStreamReader.PrematureEndOfDocumentError)) { print("XML ERROR:", this.xml.lineNumber() + ":", this.xml.errorString()); this.http.abort(); } } RSSListing.prototype.itemActivated = function(item) { QDesktopServices.openUrl(new QUrl(item.text(1))); } var rsslisting = new RSSListing(); rsslisting.show(); QCoreApplication.exec(); qtscriptgenerator-src-0.2.0/examples/Screenshot.js000066400000000000000000000144501170724227300223600ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ function tr(s) { return s; } function Screenshot(parent) { QWidget.call(this, parent); this.screenshotLabel = new QLabel(); this.screenshotLabel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding); this.screenshotLabel.alignment = Qt.Alignment(Qt.AlignCenter); this.screenshotLabel.setMinimumSize(240, 160); this.createOptionsGroupBox(); this.createButtonsLayout(); this.mainLayout = new QVBoxLayout(); this.mainLayout.addWidget(this.screenshotLabel,0 ,0); this.mainLayout.addWidget(this.optionsGroupBox,0 ,0); this.mainLayout.addLayout(this.buttonsLayout); this.setLayout(this.mainLayout); this.shootScreen(); this.delaySpinBox.setValue(5); this.windowIcon = new QIcon("classpath:com/trolltech/images/qt-logo.png"); this.windowTitle = tr("Screenshot"); this.resize(300, 200); } Screenshot.prototype = new QWidget(); Screenshot.prototype.resizeEvent = function(event) { var scaledSize = this.originalPixmap.size(); scaledSize.scale(this.screenshotLabel.size, Qt.AspectRatioMode.KeepAspectRatio); if (this.screenshotLabel.pixmap != null || scaledSize != this.screenshotLabel.pixmap.size()) this.updateScreenshotLabel(); } Screenshot.prototype.newScreenshot = function() { if ( this.hideThisWindowCheckBox.checked) this.hide(); this.newScreenshotButton.setDisabled(true); //FIXME // QTimer.singleShot(this.delaySpinBox.value * 1000, // this, this.shootScreen); var singleShot = new QTimer(); singleShot.singleShot = true; singleShot.timeout.connect(this, this.shootScreen); singleShot.start(this.delaySpinBox.value * 1000); } Screenshot.prototype.saveScreenshot = function() { var format = "png"; var initialPath = QDir.currentPath() + tr("/untitled.") + format; var filter = tr(format.toUpperCase() + " Files (*." + format + ");;All Files (*)"); var fileName = QFileDialog.getSaveFileName(this, tr("Save As"), initialPath, filter, null, null); // new QFileDialog.Option.Filter(filter)); //FIXME if (fileName != "") this.originalPixmap.save(fileName); //, format); //FIXME } Screenshot.prototype.shootScreen = function() { if ( this.delaySpinBox.value != 0) QApplication.beep(); this.originalPixmap = null; this.originalPixmap = QPixmap.grabWindow( QApplication.desktop().winId()); this.updateScreenshotLabel(); this.newScreenshotButton.enabled = true; if (this.hideThisWindowCheckBox.checked) this.show(); } Screenshot.prototype.updateCheckBox = function() { if (this.delaySpinBox.value) this.hideThisWindowCheckBox.setDisabled(true); else this.hideThisWindowCheckBox.setDisabled(false); } Screenshot.prototype.createOptionsGroupBox = function() { this.optionsGroupBox = new QGroupBox(tr("Options")); this.delaySpinBox = new QSpinBox(); this.delaySpinBox.suffix = tr(" s"); this.delaySpinBox.maximum = 60; this.delaySpinBox['valueChanged(int)'].connect(this, this.updateCheckBox); this.delaySpinBoxLabel = new QLabel(tr("Screenshot Delay:")); this.hideThisWindowCheckBox = new QCheckBox(tr("Hide This Window")); this.optionsGroupBoxLayout = new QGridLayout(); this.optionsGroupBoxLayout.addWidget(this.delaySpinBoxLabel, 0, 0); this.optionsGroupBoxLayout.addWidget(this.delaySpinBox, 0, 1); this.optionsGroupBoxLayout.addWidget(this.hideThisWindowCheckBox, 1, 0, 1, 2); this.optionsGroupBox.setLayout(this.optionsGroupBoxLayout); } Screenshot.prototype.createButtonsLayout = function() { this.newScreenshotButton = this.createButton(tr("New Screenshot"), this, this.newScreenshot); this.saveScreenshotButton = this.createButton(tr("Save Screenshot"), this, this.saveScreenshot); this.quitScreenshotButton = this.createButton(tr("Quit"), this, this.close); this.buttonsLayout = new QHBoxLayout(); this.buttonsLayout.addStretch(); this.buttonsLayout.addWidget(this.newScreenshotButton, 0, 0); this.buttonsLayout.addWidget(this.saveScreenshotButton, 0, 0); this.buttonsLayout.addWidget(this.quitScreenshotButton, 0, 0); } Screenshot.prototype.createButton = function(text, receiver, member) { var button = new QPushButton(text); button.clicked.connect(receiver, member); return button; } Screenshot.prototype.updateScreenshotLabel = function() { this.screenshotLabel.setPixmap(this.originalPixmap.scaled(this.screenshotLabel.size, Qt.KeepAspectRatio, Qt.SmoothTransformation)); } var screenshot = new Screenshot(null); screenshot.show(); QCoreApplication.exec(); qtscriptgenerator-src-0.2.0/examples/StandardDialogs.js000066400000000000000000000335671170724227300233200ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ function tr(s) { return s; } function Dialog(parent) { QDialog.call(this, parent); this.errorMessageDialog = new QErrorMessage(this); var frameStyle = QFrame.Sunken | QFrame.Panel; this.integerLabel = new QLabel; this.integerLabel.setFrameStyle(frameStyle); var integerButton = new QPushButton(tr("QInputDialog::get&Integer()")); this.doubleLabel = new QLabel; this.doubleLabel.setFrameStyle(frameStyle); var doubleButton = new QPushButton(tr("QInputDialog::get&Double()")); this.itemLabel = new QLabel; this.itemLabel.setFrameStyle(frameStyle); var itemButton = new QPushButton(tr("QInputDialog::getIte&m()")); this.textLabel = new QLabel; this.textLabel.setFrameStyle(frameStyle); var textButton = new QPushButton(tr("QInputDialog::get&Text()")); this.colorLabel = new QLabel; this.colorLabel.setFrameStyle(frameStyle); var colorButton = new QPushButton(tr("QColorDialog::get&Color()")); this.fontLabel = new QLabel; this.fontLabel.setFrameStyle(frameStyle); var fontButton = new QPushButton(tr("QFontDialog::get&Font()")); this.directoryLabel = new QLabel; this.directoryLabel.setFrameStyle(frameStyle); var directoryButton = new QPushButton(tr("QFileDialog::getE&xistingDirectory()")); this.openFilePaths = "."; this.openFileNameLabel = new QLabel; this.openFileNameLabel.setFrameStyle(frameStyle); var openFileNameButton = new QPushButton(tr("QFileDialog::get&OpenFileName()")); this.openFileNamesLabel = new QLabel; this.openFileNamesLabel.setFrameStyle(frameStyle); var openFileNamesButton = new QPushButton(tr("QFileDialog::&getOpenFileNames()")); this.saveFileNameLabel = new QLabel; this.saveFileNameLabel.setFrameStyle(frameStyle); var saveFileNameButton = new QPushButton(tr("QFileDialog::get&SaveFileName()")); this.criticalLabel = new QLabel; this.criticalLabel.setFrameStyle(frameStyle); var criticalButton = new QPushButton(tr("QMessageBox::critica&l()")); this.informationLabel = new QLabel; this.informationLabel.setFrameStyle(frameStyle); var informationButton = new QPushButton(tr("QMessageBox::i&nformation()")); this.questionLabel = new QLabel; this.questionLabel.setFrameStyle(frameStyle); var questionButton = new QPushButton(tr("QMessageBox::&question()")); this.warningLabel = new QLabel; this.warningLabel.setFrameStyle(frameStyle); var warningButton = new QPushButton(tr("QMessageBox::&warning()")); this.errorLabel = new QLabel; this.errorLabel.setFrameStyle(frameStyle); var errorButton = new QPushButton(tr("QErrorMessage::show&M&essage()")); integerButton["clicked()"].connect(this, this.setInteger); doubleButton["clicked()"].connect(this, this.setDouble); itemButton["clicked()"].connect(this, this.setItem); textButton["clicked()"].connect(this, this.setText); colorButton["clicked()"].connect(this, this.setColor); fontButton["clicked()"].connect(this, this.setFont); directoryButton["clicked()"].connect( this, this.setExistingDirectory); openFileNameButton["clicked()"].connect( this, this.setOpenFileName); openFileNamesButton["clicked()"].connect( this, this.setOpenFileNames); saveFileNameButton["clicked()"].connect( this, this.setSaveFileName); criticalButton["clicked()"].connect(this, this.criticalMessage); informationButton["clicked()"].connect( this, this.informationMessage); questionButton["clicked()"].connect(this, this.questionMessage); warningButton["clicked()"].connect(this, this.warningMessage); errorButton["clicked()"].connect(this, this.errorMessage); this.useNative = new QCheckBox(this); this.useNative.text = tr("Use native file dialog"); this.useNative.checked = true; var layout = new QGridLayout; layout.setColumnStretch(1, 1); layout.setColumnMinimumWidth(1, 250); layout.addWidget(integerButton, 0, 0); layout.addWidget(this.integerLabel, 0, 1); layout.addWidget(doubleButton, 1, 0); layout.addWidget(this.doubleLabel, 1, 1); layout.addWidget(itemButton, 2, 0); layout.addWidget(this.itemLabel, 2, 1); layout.addWidget(textButton, 3, 0); layout.addWidget(this.textLabel, 3, 1); layout.addWidget(colorButton, 4, 0); layout.addWidget(this.colorLabel, 4, 1); layout.addWidget(fontButton, 5, 0); layout.addWidget(this.fontLabel, 5, 1); layout.addWidget(directoryButton, 6, 0); layout.addWidget(this.directoryLabel, 6, 1); layout.addWidget(openFileNameButton, 7, 0); layout.addWidget(this.openFileNameLabel, 7, 1); layout.addWidget(openFileNamesButton, 8, 0); layout.addWidget(this.openFileNamesLabel, 8, 1); layout.addWidget(saveFileNameButton, 9, 0); layout.addWidget(this.saveFileNameLabel, 9, 1); layout.addWidget(criticalButton, 10, 0); layout.addWidget(this.criticalLabel, 10, 1); layout.addWidget(informationButton, 11, 0); layout.addWidget(this.informationLabel, 11, 1); layout.addWidget(questionButton, 12, 0); layout.addWidget(this.questionLabel, 12, 1); layout.addWidget(warningButton, 13, 0); layout.addWidget(this.warningLabel, 13, 1); layout.addWidget(errorButton, 14, 0); layout.addWidget(this.errorLabel, 14, 1); layout.addWidget(this.useNative, 15, 0); this.setLayout(layout); this.windowTitle = tr("Standard Dialogs"); } Dialog.MESSAGE = tr("

Message boxes have a caption, a text, " + "and any number of buttons, each with standard or custom texts." + "

Click a button to close the message box. Pressing the Esc button " + "will activate the detected escape button (if any)."); Dialog.prototype = new QDialog(); Dialog.prototype.setInteger = function() { var i = QInputDialog.getInteger(this, tr("QInputDialog::getInteger()"), tr("Percentage:"), 25, 0, 100, 1, Qt.WindowFlags(0)); if (i != null) this.integerLabel.text = i; } Dialog.prototype.setDouble = function() { var d = QInputDialog.getDouble(this, tr("QInputDialog::getDouble()"), tr("Amount:"), 37.56, -10000, 10000, 2, Qt.WindowFlags(0)); if (d != null) this.doubleLabel.text = d; } Dialog.prototype.setItem = function() { var items = new Array(tr("Spring"), tr("Summer"), tr("Fall"), tr("Winter")); var item = QInputDialog.getItem(this, tr("QInputDialog::getItem()"), tr("Season:"), items, 0, false, Qt.WindowFlags(0)); if (item != null & item.length != 0) this.itemLabel.text = item; } Dialog.prototype.setText = function() { var text = QInputDialog.getText(this, tr("QInputDialog::getText()"), tr("User name:"), QLineEdit.Normal, QDir.home().dirName(), Qt.WindowFlags(0)); if (text != null && text.length != 0) this.textLabel.text = text; } Dialog.prototype.setColor = function() { var color = QColorDialog.getColor(new QColor(Qt.green), this); if (color.isValid()) { this.colorLabel.text = color.name(); this.colorLabel.palette = new QPalette(color); this.colorLabel.autoFillBackground = true; } } Dialog.prototype.setFont = function() { var font = QFontDialog.getFont(new QFont(this.fontLabel.text), this); if (font != null) { this.fontLabel.text = font.key(); this.fontLabel.font = font; } } Dialog.prototype.setExistingDirectory = function() { var options = QFileDialog.DontResolveSymlinks | QFileDialog.ShowDirsOnly; if (!this.useNative.checked) options |= QFileDialog.DontUseNativeDialog; var directory = QFileDialog.getExistingDirectory(this, tr("QFileDialog::getExistingDirectory()"), this.directoryLabel.text, QFileDialog.Options(options)); if (directory.length != 0) this.directoryLabel.text = directory; } Dialog.prototype.setOpenFileName = function() { var options = 0; if (!this.useNative.checked) options |= QFileDialog.DontUseNativeDialog; var selectedFilter; var fileName = QFileDialog.getOpenFileName(this, tr("QFileDialog::getOpenFileName()"), this.openFileNameLabel.text, tr("All Files (*);;Text Files (*.txt)"), selectedFilter, QFileDialog.Options(options)); if (fileName.length != 0) this.openFileNameLabel.text = fileName; } Dialog.prototype.setOpenFileNames = function() { var options = 0; if (!this.useNative.checked) options |= QFileDialog.DontUseNativeDialog; var selectedFilter; var files = QFileDialog.getOpenFileNames( this, tr("QFileDialog::getOpenFileNames()"), this.openFilesPath, tr("All Files (*);;Text Files (*.txt)"), selectedFilter, options); if (files.length != 0) { this.openFilesPath = files[0]; this.openFileNamesLabel.text = "[" + files.join(", ") + "]"; } } Dialog.prototype.setSaveFileName = function() { var options = 0; if (!this.useNative.checked) options |= QFileDialog.DontUseNativeDialog; var selectedFilter; var fileName = QFileDialog.getSaveFileName(this, tr("QFileDialog::getSaveFileName()"), this.saveFileNameLabel.text, tr("All Files (*);;Text Files (*.txt)"), selectedFilter, options); if (fileName.length != 0) this.saveFileNameLabel.text = fileName; } Dialog.prototype.criticalMessage = function() { var reply = QMessageBox.critical(this, tr("QMessageBox::critical()"), Dialog.MESSAGE, QMessageBox.StandardButtons(QMessageBox.Abort, QMessageBox.Retry, QMessageBox.Ignore)); if (reply == QMessageBox.Abort) this.criticalLabel.text = tr("Abort"); else if (reply == QMessageBox.Retry) this.criticalLabel.text = tr("Retry"); else this.criticalLabel.text = tr("Ignore"); } Dialog.prototype.informationMessage = function() { var reply = QMessageBox.information(this, tr("QMessageBox::information()"), Dialog.MESSAGE); if (reply == QMessageBox.Ok) this.informationLabel.text = tr("OK"); else this.informationLabel.text = tr("Escape"); } Dialog.prototype.questionMessage = function() { var reply = QMessageBox.question(this, tr("QMessageBox::question()"), Dialog.MESSAGE, QMessageBox.StandardButtons(QMessageBox.Yes, QMessageBox.No, QMessageBox.Cancel)); if (reply == QMessageBox.Yes) this.questionLabel.text = tr("Yes"); else if (reply == QMessageBox.No) this.questionLabel.text = tr("No"); else this.questionLabel.text = tr("Cancel"); } Dialog.prototype.warningMessage = function() { var msgBox = new QMessageBox(QMessageBox.Warning, tr("QMessageBox::warning()"), Dialog.MESSAGE, 0, this); msgBox.addButton(tr("Save &Again"), QMessageBox.AcceptRole); msgBox.addButton(tr("&Continue"), QMessageBox.RejectRole); if (msgBox.exec() == QMessageBox.AcceptRole) this.warningLabel.text = tr("Save Again"); else this.warningLabel.text = tr("Continue"); } Dialog.prototype.errorMessage = function() { this.errorMessageDialog.showMessage( tr("This dialog shows and remembers error messages. " + "If the checkbox is checked (as it is by default), " + "the shown message will be shown again, " + "but if the user unchecks the box the message " + "will not appear again if QErrorMessage::showMessage() " + "is called with the same message.")); this.errorLabel.text = tr("If the box is unchecked, the message " + "won't appear again."); }; (function() { var translatorFileName = "qt_"; translatorFileName += QLocale.system().name(); var translator = new QTranslator(qApp); if (translator.load(translatorFileName, QLibraryInfo.location(QLibraryInfo.TranslationsPath))) qApp.installTranslator(translator); var dialog = new Dialog(); return dialog.exec(); })(); qtscriptgenerator-src-0.2.0/examples/StreamBookmarks.js000066400000000000000000000260761170724227300233560ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ function tr(s) { return s; } function XbelWriter(treeWidget) { QXmlStreamWriter.call(this); this.treeWidget = treeWidget; this.setAutoFormatting(true); } XbelWriter.prototype = new QXmlStreamWriter(); XbelWriter.prototype.writeFile = function(device) { this.setDevice(device); this.writeStartDocument(); this.writeDTD(""); this.writeStartElement("xbel"); this.writeAttribute("version", "1.0"); for (var i = 0; i < this.treeWidget.topLevelItemCount; ++i) this.writeItem(this.treeWidget.topLevelItem(i)); this.writeEndDocument(); return true; } XbelWriter.prototype.writeItem = function(item) { var tagName = item.data(0, Qt.UserRole); if (tagName == "folder") { var folded = !item.isExpanded(); this.writeStartElement(tagName); this.writeAttribute("folded", folded ? "yes" : "no"); this.writeTextElement("title", item.text(0)); for (var i = 0; i < item.childCount(); ++i) this.writeItem(item.child(i)); this.writeEndElement(); } else if (tagName == "bookmark") { this.writeStartElement(tagName); if (item.text(1) != "") this.writeAttribute("href", item.text(1)); this.writeTextElement("title", item.text(0)); this.writeEndElement(); } else if (tagName == "separator") { this.writeEmptyElement(tagName); } } function XbelReader(treeWidget) { QXmlStreamReader.call(this); this.treeWidget = treeWidget; var style = treeWidget.style(); this.folderIcon = new QIcon(); this.folderIcon.addPixmap(style.standardPixmap(QStyle.SP_DirClosedIcon), QIcon.Normal, QIcon.Off); this.folderIcon.addPixmap(style.standardPixmap(QStyle.SP_DirOpenIcon), QIcon.Normal, QIcon.On); this.bookmarkIcon = new QIcon(); this.bookmarkIcon.addPixmap(style.standardPixmap(QStyle.SP_FileIcon)); } XbelReader.prototype = new QXmlStreamReader(); XbelReader.prototype.read = function(device) { this.setDevice(device); while (!this.atEnd()) { this.readNext(); if (this.isStartElement()) { if (this.name() == "xbel" && this.attributes().value("version") == "1.0") this.readXBEL(); else this.raiseError(tr("The file is not an XBEL version 1.0 file.")); } } return this.error() == QXmlStreamReader.NoError; } XbelReader.prototype.readUnknownElement = function() { while (!this.atEnd()) { this.readNext(); if (this.isEndElement()) break; if (this.isStartElement()) this.readUnknownElement(); } } XbelReader.prototype.readXBEL = function() { // Q_ASSERT(isStartElement() && name() == "xbel"); while (!this.atEnd()) { this.readNext(); if (this.isEndElement()) break; if (this.isStartElement()) { if (this.name() == "folder") this.readFolder(null); else if (name() == "bookmark") this.readBookmark(null); else if (name() == "separator") this.readSeparator(null); else this.readUnknownElement(); } } } XbelReader.prototype.readTitle = function(item) { // Q_ASSERT(isStartElement() && name() == "title"); var title = this.readElementText(); item.setText(0, title); } XbelReader.prototype.readSeparator = function(item) { var separator = this.createChildItem(item); separator.setFlags(Qt.ItemFlags(item.flags() & ~Qt.ItemIsSelectable)); separator.setText(0, "---" /*QString(30, 0xB7)*/); this.readElementText(); } XbelReader.prototype.readFolder = function(item) { // Q_ASSERT(isStartElement() && name() == "folder"); var folder = this.createChildItem(item); var folded = (this.attributes().value("folded") != "no"); folder.setExpanded(!folded); while (!this.atEnd()) { this.readNext(); if (this.isEndElement()) break; if (this.isStartElement()) { if (this.name() == "title") this.readTitle(folder); else if (this.name() == "folder") this.readFolder(folder); else if (this.name() == "bookmark") this.readBookmark(folder); else if (this.name() == "separator") this.readSeparator(folder); else this.readUnknownElement(); } } } XbelReader.prototype.readBookmark = function(item) { // Q_ASSERT(isStartElement() && name() == "bookmark"); var bookmark = this.createChildItem(item); bookmark.setFlags(Qt.ItemFlags(bookmark.flags() | Qt.ItemIsEditable)); bookmark.setIcon(0, this.bookmarkIcon); bookmark.setText(0, tr("Unknown title")); bookmark.setText(1, this.attributes().value("href")); while (!this.atEnd()) { this.readNext(); if (this.isEndElement()) break; if (this.isStartElement()) { if (this.name() == "title") this.readTitle(bookmark); else this.readUnknownElement(); } } } XbelReader.prototype.createChildItem = function(item) { var childItem; if (item) { childItem = new QTreeWidgetItem(item); } else { // ### childItem = new QTreeWidgetItem(this.treeWidget); childItem = new QTreeWidgetItem(); this.treeWidget.addTopLevelItem(childItem); } childItem.setData(0, Qt.UserRole, this.name()); return childItem; } function MainWindow() { QMainWindow.call(this); var labels = new Array(); labels.push(tr("Title")); labels.push(tr("Location")); this.treeWidget = new QTreeWidget(); this.treeWidget.header().setResizeMode(QHeaderView.Stretch); this.treeWidget.setHeaderLabels(labels); this.setCentralWidget(this.treeWidget); this.createActions(); this.createMenus(); this.statusBar().showMessage(tr("Ready")); this.windowTitle = tr("QXmlStream Bookmarks"); this.resize(480, 320); } MainWindow.prototype = new QMainWindow(); MainWindow.prototype.open = function() { var fileName = QFileDialog.getOpenFileName(this, tr("Open Bookmark File"), QDir.currentPath(), tr("XBEL Files (*.xbel *.xml)")); if (fileName == "") return; this.treeWidget.clear(); var file = new QFile(fileName); if (!file.open(QIODevice.OpenMode(QIODevice.ReadOnly, QIODevice.Text))) { QMessageBox.warning(this, tr("QXmlStream Bookmarks"), tr("Cannot read file %1:\n%2.") .arg(fileName) .arg(file.errorString())); return; } var reader = new XbelReader(this.treeWidget); if (!reader.read(file)) { QMessageBox.warning(this, tr("QXmlStream Bookmarks"), tr("Parse error in file " + fileName + " at line " + reader.lineNumber() + ", column " + reader.columnNumber() + ":\n" + reader.errorString())); } else { this.statusBar().showMessage(tr("File loaded"), 2000); } } MainWindow.prototype.saveAs = function() { var fileName = QFileDialog.getSaveFileName(this, tr("Save Bookmark File"), QDir.currentPath(), tr("XBEL Files (*.xbel *.xml)")); if (fileName == "") return; var file = new QFile(fileName); if (!file.open(QIODevice.OpenMode(QIODevice.WriteOnly, QIODevice.Text))) { QMessageBox.warning(this, tr("QXmlStream Bookmarks"), tr("Cannot write file %1:\n%2.") .arg(fileName) .arg(file.errorString())); return; } var writer = new XbelWriter(this.treeWidget); if (writer.writeFile(file)) this.statusBar().showMessage(tr("File saved"), 2000); } MainWindow.prototype.about = function() { QMessageBox.about(this, tr("About QXmlStream Bookmarks"), tr("The QXmlStream Bookmarks example demonstrates how to use Qt's QXmlStream classes to read and write XML documents.")); } MainWindow.prototype.createActions = function() { this.openAct = new QAction(tr("&Open..."), this); this.openAct.shortcut = tr("Ctrl+O"); this.openAct.triggered.connect(this, this.open); this.saveAsAct = new QAction(tr("&Save As..."), this); this.saveAsAct.shortcut = tr("Ctrl+S"); this.saveAsAct.triggered.connect(this, this.saveAs); this.exitAct = new QAction(tr("E&xit"), this); this.exitAct.shortcut = tr("Ctrl+Q"); this.exitAct.triggered.connect(this, this.close); this.aboutAct = new QAction(tr("&About"), this); this.aboutAct.triggered.connect(this, this.about); this.aboutQtAct = new QAction(tr("About &Qt"), this); // ### this.aboutQtAct.triggered.connect(QApplication.aboutQt); this.aboutQtAct.triggered.connect(qApp.aboutQt); } MainWindow.prototype.createMenus = function() { this.fileMenu = this.menuBar().addMenu(tr("&File")); // ### working around bug in QMenu.prototype.addAction QMenu.prototype.addAction = QWidget.prototype.addAction; this.fileMenu.addAction(this.openAct); this.fileMenu.addAction(this.saveAsAct); this.fileMenu.addAction(this.exitAct); this.menuBar().addSeparator(); this.helpMenu = this.menuBar().addMenu(tr("&Help")); this.helpMenu.addAction(this.aboutAct); this.helpMenu.addAction(this.aboutQtAct); } var mainWin = new MainWindow(); mainWin.show(); mainWin.open(); QCoreApplication.exec(); qtscriptgenerator-src-0.2.0/examples/Transformations.js000066400000000000000000000201451170724227300234320ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ function tr(s) { return s; } Operation = { NoTransformation: 0, Rotate: 1, Scale: 2, Translate: 3 }; function RenderArea(parent) { QWidget.call(this, parent); var newFont = new QFont(this.font); newFont.setPixelSize(12); this.font = newFont; var fontMetrics = new QFontMetrics(newFont); this.xBoundingRect = fontMetrics.boundingRect(tr("x")); this.yBoundingRect = fontMetrics.boundingRect(tr("y")); this.shape = new QPainterPath(); this.operations = new Array(); } RenderArea.prototype = new QWidget(); RenderArea.prototype.setOperations = function(operations) { this.operations = operations; this.update(); } RenderArea.prototype.setShape = function(shape) { this.shape = shape; this.update(); } RenderArea.prototype.getMinimumSizeHint = function() { return new QSize(182, 182); } RenderArea.prototype.getSizeHint = function() { return new QSize(232, 232); } RenderArea.prototype.paintEvent = function(event) { var painter = new QPainter(); painter.begin(this); painter.setRenderHint(QPainter.Antialiasing); painter.fillRect(event.rect(), new QBrush(new QColor(Qt.white))); painter.translate(66, 66); painter.save(); this.transformPainter(painter); this.drawShape(painter); painter.restore(); this.drawOutline(painter); this.transformPainter(painter); this.drawCoordinates(painter); painter.end(); } RenderArea.prototype.drawCoordinates = function(painter) { painter.setPen(new QColor(Qt.red)); painter.drawLine(0, 0, 50, 0); painter.drawLine(48, -2, 50, 0); painter.drawLine(48, 2, 50, 0); painter.drawText(60 - this.xBoundingRect.width() / 2, 0 + this.xBoundingRect.height() / 2, tr("x")); painter.drawLine(0, 0, 0, 50); painter.drawLine(-2, 48, 0, 50); painter.drawLine(2, 48, 0, 50); painter.drawText(0 - this.yBoundingRect.width() / 2, 60 + this.yBoundingRect.height() / 2, tr("y")); } RenderArea.prototype.drawOutline = function(painter) { painter.setPen(new QPen(new QColor(Qt.darkGreen))); painter.setPen(new QPen(Qt.DashLine)); painter.setBrush(new QBrush(Qt.NoBrush)); painter.drawRect(0, 0, 100, 100); } RenderArea.prototype.drawShape = function(painter) { painter.fillPath(this.shape, new QColor(Qt.blue)); } RenderArea.prototype.transformPainter = function(painter) { for (var i = 0; i < this.operations.length; ++i) { switch (this.operations[i]) { case Operation.Translate: painter.translate(50, 50); break; case Operation.Scale: painter.scale(0.75, 0.75); break; case Operation.Rotate: painter.rotate(60); break; case Operation.NoTransformation: default: ; } } } function Window(parent) { QWidget.call(this, parent); this.originalRenderArea = new RenderArea(); this.shapeComboBox = new QComboBox(); this.shapeComboBox.addItem(tr("Clock")); this.shapeComboBox.addItem(tr("House")); this.shapeComboBox.addItem(tr("Text")); this.shapeComboBox.addItem(tr("Truck")); var layout = new QGridLayout(); layout.addWidget(this.originalRenderArea, 0, 0); layout.addWidget(this.shapeComboBox, 1, 0); this.transformedRenderAreas = new Array(Window.NumTransformedAreas); this.operationComboBoxes = new Array(Window.NumTransformedAreas); for (var i = 0; i < Window.NumTransformedAreas; ++i) { this.transformedRenderAreas[i] = new RenderArea(); this.operationComboBoxes[i] = new QComboBox; this.operationComboBoxes[i].addItem(tr("No transformation")); this.operationComboBoxes[i].addItem(tr("Rotate by 60\xB0")); this.operationComboBoxes[i].addItem(tr("Scale to 75%")); this.operationComboBoxes[i].addItem(tr("Translate by (50, 50)")); this.operationComboBoxes[i]["activated(int)"].connect( this, this.operationChanged); layout.addWidget(this.transformedRenderAreas[i], 0, i + 1); layout.addWidget(this.operationComboBoxes[i], 1, i + 1); } this.setLayout(layout); this.setupShapes(); this.shapeSelected(0); this.windowTitle = tr("Transformations"); } Window.prototype = new QWidget(); Window.NumTransformedAreas = 3; Window.prototype.setupShapes = function() { var truck = new QPainterPath(); truck.setFillRule(Qt.WindingFill); truck.moveTo(0.0, 87.0); truck.lineTo(0.0, 60.0); truck.lineTo(10.0, 60.0); truck.lineTo(35.0, 35.0); truck.lineTo(100.0, 35.0); truck.lineTo(100.0, 87.0); truck.lineTo(0.0, 87.0); truck.moveTo(17.0, 60.0); truck.lineTo(55.0, 60.0); truck.lineTo(55.0, 40.0); truck.lineTo(37.0, 40.0); truck.lineTo(17.0, 60.0); truck.addEllipse(17.0, 75.0, 25.0, 25.0); truck.addEllipse(63.0, 75.0, 25.0, 25.0); var clock = new QPainterPath(); clock.addEllipse(-50.0, -50.0, 100.0, 100.0); clock.addEllipse(-48.0, -48.0, 96.0, 96.0); clock.moveTo(0.0, 0.0); clock.lineTo(-2.0, -2.0); clock.lineTo(0.0, -42.0); clock.lineTo(2.0, -2.0); clock.lineTo(0.0, 0.0); clock.moveTo(0.0, 0.0); clock.lineTo(2.732, -0.732); clock.lineTo(24.495, 14.142); clock.lineTo(0.732, 2.732); clock.lineTo(0.0, 0.0); var house = new QPainterPath(); house.moveTo(-45.0, -20.0); house.lineTo(0.0, -45.0); house.lineTo(45.0, -20.0); house.lineTo(45.0, 45.0); house.lineTo(-45.0, 45.0); house.lineTo(-45.0, -20.0); house.addRect(15.0, 5.0, 20.0, 35.0); house.addRect(-35.0, -15.0, 25.0, 25.0); var text = new QPainterPath(); font = new QFont(); font.setPixelSize(50); var fontBoundingRect = new QFontMetrics(font).boundingRect(tr("Qt")); text.addText(-new QPointF(fontBoundingRect.center()), font, tr("Qt")); this.shapes = new Array(); this.shapes.push(clock); this.shapes.push(house); this.shapes.push(text); this.shapes.push(truck); this.shapeComboBox["activated(int)"].connect( this, this.shapeSelected); } Window.prototype.operationChanged = function() { var operations = new Array(); for (var i = 0; i < Window.NumTransformedAreas; ++i) { var index = this.operationComboBoxes[i].currentIndex; operations.push(index); this.transformedRenderAreas[i].setOperations(operations.slice()); } } Window.prototype.shapeSelected = function(index) { var shape = this.shapes[index]; this.originalRenderArea.setShape(shape); for (var i = 0; i < Window.NumTransformedAreas; ++i) this.transformedRenderAreas[i].setShape(shape); } var win = new Window(); win.show(); QCoreApplication.exec(); qtscriptgenerator-src-0.2.0/examples/TwoWayButton.qs000066400000000000000000000006771170724227300227060ustar00rootroot00000000000000var button = new QPushButton(); var off = new QState(); off.assignProperty(button, "text", "Off"); var on = new QState(); on.assignProperty(button, "text", "On"); off.addTransition(button, "clicked()", on); on.addTransition(button, "clicked()", off); var machine = new QStateMachine(); machine.addState(off); machine.addState(on); machine.initialState = off; machine.start(); button.resize(100, 100); button.show(); QCoreApplication.exec(); qtscriptgenerator-src-0.2.0/examples/WebKitPlugins.html000066400000000000000000000004621170724227300233200ustar00rootroot00000000000000

My Nifty Plugin

qtscriptgenerator-src-0.2.0/examples/WebKitPlugins.js000066400000000000000000000077271170724227300230030ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ function getArgumentValue(name, names, values, from) { var i = (from == undefined) ? 0 : from; for ( ; i < names.length; ++i) { if (names[i] == name) return values[i]; } return undefined; } // // Plugin class // function MyWebPlugin(formUrl, scriptUrl, parent) { QWidget.call(this, parent); this.initialized = false; this.formReply = this.downloadFile(formUrl, this.formDownloaded); if (scriptUrl == undefined) this.script = ""; else this.scriptReply = this.downloadFile(scriptUrl, this.scriptDownloaded); } MyWebPlugin.prototype = new QWidget(); MyWebPlugin.prototype.downloadFile = function(url, callback) { if (this.accessManager == undefined) this.accessManager = new QNetworkAccessManager(); var reply = this.accessManager.get(new QNetworkRequest(url)); reply.finished.connect(this, callback); return reply; } MyWebPlugin.prototype.formDownloaded = function() { var loader = new QUiLoader(); this.form = loader.load(this.formReply); var layout = new QVBoxLayout(this); layout.addWidget(this.form, 0, Qt.AlignCenter); this.initialize(); } MyWebPlugin.prototype.scriptDownloaded = function() { var stream = new QTextStream(this.scriptReply); this.script = stream.readAll(); this.initialize(); } MyWebPlugin.prototype.initialize = function() { if (this.initialized) return; if ((this.form == undefined) || (this.script == undefined)) return; var ctor = eval(this.script); if (typeof ctor != "function") return; this.instance = new ctor(this.form); this.initialized = true; } // // QWebPluginFactory subclass // function MyWebPluginFactory(parent) { QWebPluginFactory.call(this, parent); } MyWebPluginFactory.prototype = new QWebPluginFactory(); MyWebPluginFactory.prototype.create = function(mimeType, url, argumentNames, argumentValues) { if (mimeType != "application/x-qtform") return null; var formUrl = getArgumentValue("form", argumentNames, argumentValues); var scriptUrl = getArgumentValue("script", argumentNames, argumentValues); if (formUrl == undefined) return null; return new MyWebPlugin(new QUrl(formUrl), new QUrl(scriptUrl)); } // // Main // var view = new QWebView(); view.settings().setAttribute(QWebSettings.PluginsEnabled, true); var factory = new MyWebPluginFactory(); view.page().setPluginFactory(factory); view.load(new QUrl("WebKitPlugins.html")); view.show(); QCoreApplication.exec(); qtscriptgenerator-src-0.2.0/examples/Wiggly.js000066400000000000000000000071651170724227300215120ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ function tr(s) { return s; } function WigglyWidget(parent) { QWidget.call(this, parent); this.setBackgroundRole(QPalette.Midlight); this.autoFillBackground = true; var newFont = new QFont(this.font); newFont.setPointSize(newFont.pointSize() + 20); this.font = newFont; this.step = 0; this.timer = new QBasicTimer(); this.timer.start(60, this); } WigglyWidget.sineTable = new Array(0, 38, 71, 92, 100, 92, 71, 38, 0, -38, -71, -92, -100, -92, -71, -38); WigglyWidget.prototype = new QWidget(); WigglyWidget.prototype.paintEvent = function(/* event */) { var metrics = new QFontMetrics(this.font); var x = (this.width - metrics.width(this.text)) / 2; var y = (this.height + metrics.ascent() - metrics.descent()) / 2; var color = new QColor(); var painter = new QPainter(); painter.begin(this); for (var i = 0; i < this.text.length; ++i) { var index = (this.step + i) % 16; color.setHsv((15 - index) * 16, 255, 191); painter.setPen(new QPen(color)); painter.drawText(x, y - ((WigglyWidget.sineTable[index] * metrics.height()) / 400), this.text[i]); x += metrics.width(this.text[i]); } painter.end(); } WigglyWidget.prototype.timerEvent = function(event) { if (event.timerId() == this.timer.timerId()) { ++this.step; this.update(); } else { // QWidget::timerEvent(event); // ### this.super_timerEvent(event); } } WigglyWidget.prototype.setText = function(newText) { this.text = newText; } function Dialog(parent) { QWidget.call(this, parent); var wigglyWidget = new WigglyWidget(); var lineEdit = new QLineEdit(); var layout = new QVBoxLayout(); // ### workaround layout.addWidget(wigglyWidget, 0, Qt.AlignLeft); layout.addWidget(lineEdit, 0, Qt.AlignLeft); this.setLayout(layout); lineEdit.textChanged.connect( wigglyWidget, wigglyWidget.setText); lineEdit.text = tr("Hello world!"); this.windowTitle = tr("Wiggly"); this.resize(360, 145); } Dialog.prototype = new QDialog(); var dialog = new Dialog(); dialog.show(); QCoreApplication.exec(); qtscriptgenerator-src-0.2.0/examples/frank.xbel000066400000000000000000000247711170724227300216710ustar00rootroot00000000000000 Literate Programming Synopsis of Literate Programming Literate Programming: Propaganda and Tools Literate Programming by Henrik Turbell Literate Programming Library Literate Programming Basics Literate Programming Overview POD is not Literate Programming Computers That We Can Count On Literate Programming - Issues and Problems Literate Programming - Wiki Pages What is well-commented code? Bibliography on literate programming - A searchable bibliography Program comprehension and code reading bibliography Elucidative Programming AVL Trees (TexiWeb) Literate Programming on Wikiverse Physically Based Rendering: From Theory to Implementation Useful C++ Links STL STL Reference Documentation STL Tutorial STL Reference Qt Qt 2.3 Reference Qt 3.3 Reference Qt 4.0 Reference Trolltech Home Page IOStreams IO Stream Library Binary I/O I/O Stream FAQ gdb GDB Tutorial Debugging with GDB GDB Quick Reference Page (PDF) (Handy) Classes and Constructors Constructor FAQ Organizing Classes Software Documentation or System Documentation The Almighty Thud Microsoft Coding Techniques and Programming Practices Software and Documentation The Source Code is the Design What is Software Design? How To Write Unmaintainable Code Self Documenting Program Code Remains a Distant Goal Place Tab A in Slot B UML Reference Card TeX Resources The TeX User's Group MikTeX website MetaPost website HEVEA is a quite complete and fast LATEX to HTML translator Portable Document Format (PDF) Adobe - The postscript and PDF standards Reference Manual Portable Document Format Adobe Acrobat Software Development Kit Literature Sites Guide to Special Collections (Columbia University) Literary Criticism on the Web from the Internet Public Library Victorian Web. Voice of the Shuttle. Modernist Journals Project Museum of American Poetics Modern American Poetry FindArticles.com Literary History Literary Encyclopedia The University of California Press Wright American Fiction, 1851-1875 Documenting the American South: Beginnings to 1920 Electronic Text Center at the University of Virginia The Schomburg Center for Research in Black Culture Alex Catalogue of Electronic Texts. qtscriptgenerator-src-0.2.0/examples/images/000077500000000000000000000000001170724227300211465ustar00rootroot00000000000000qtscriptgenerator-src-0.2.0/examples/images/brick.png000066400000000000000000000013771170724227300227560ustar00rootroot00000000000000‰PNG  IHDR øbêÆIDATx^-”[n1E¯Ý“‡&;al‚, …õÀ‘ø` ,–J“~Ú.Ó[²<·íªºå[Uã~ÿøäƒŽ%/ï$§Z¥ªj2“ŠŠ©ñyì3çä<'ÍPºWO ƒB”‹ºwå´]~§ÞË`’ 8”$ËÊ;{-D·¤’‰î£$as, ¸uœt¸ÖÕYá¤ÕIßk{ùù¡§ "Û´MJ³ÒÚ’…¬¬0ùMIJ ‡2Y…Ò{ro•îôõÛ£>ÊÐ~y<ðé,I¥Ië“Ö¿Zžµ½vöIyÃØ² ˜”“¼׊,§;Òn9!4pgAñJh5¹¹îÅÈ‹ Bi?À& Ëì‚ %0â¾GÈ_Ä“y„ÂFJÄ}Öò‡¬«Ày&_< )œG=!Ò„Kt”$œŽÇ­pS¼XNVa»h}9¢¨a=?ÁDm3BC07/p-3‚ªâ•VB!F­n™#Bë¹ûUìyÊ¡€„±È2ÜHµé††¾5q/ša¼l” æýBîû+Zñ¦¡,IOÙT{Ü8ŠòTQêÁQU¬ÖŠF.Vð§µ L›.­#I¶Kì6b#uî(ÌpËg—ÎÃù1Y¦C¼'%ÈZåkå$/••Ôäà¨N¶s›’ä5ÞÈ ªjÕn”=¡HÃ$ZeúE –{=wT Ê…9ا>Pˆ–¹•£*µ€ÓÌ^yA¹EFËè0?C0ž¹+;YË"K}Ú(ÁPµÿ=Äk…˜–¸q“bÀ>¢{Ö—ÏLöéܧT(@Öû,Ò¿@iÖ•­m Ø/ ›ÂÔ«È`Š }xÿÐ/Œ0Kbú3º“Õ Sº2’AF”‘p.a/b0%”{ûFòxI]8€Z;aA8t4;Ò¯ípt4À5ŽÐ[î¶„$âY’pIEND®B`‚qtscriptgenerator-src-0.2.0/examples/images/butterfly.png000066400000000000000000001100041170724227300236700ustar00rootroot00000000000000‰PNG  IHDR G?±¾ËIDATx^ì½”^U¹ðÿÛ{ŸsÞ2ïô$“I2齑MzEiŠf"6PQ±#¨(E±ÊEšôÞC-é½N’éóösÎÞÏ?eÌšü¼ßý®—{ÿ÷·Ö³Îykee~yž³Ÿ½ÏÞôAÔœ H¥?zA:É‚JŸc×.>¸î“•ƒ}ÿÿæQž®H1ªið9€àÁÿ Æ÷vËG_äÜé òöÀ<~ð‚£®YpÆiYð¥ÏcÁ)§¿àð£]0thÓÙJ©#ü@5ñ?’ÿÅxŒ4>GŒÓôÉÃ?jÁ)§~dÁ¾ðÕ.œ½à}6-xü™.è)±àÞ»¿´ ¿„ ÿß•¨4Ta£øfú!qXÉöò•oîO,‹ñUÌìépÄ‘pÁŸûýïýððÏ_üÑóÏüôá fÏp–¨ü·æQЦ¹sgœ}Þù§,øòÅ?oᕟ;ü¼ ÎsÄ‘ïcÎÌYè(KTz‹…WÍâ€ÖòÌk5øJ!z\)Fý;Ì?Æ®û^AÊ$9ìðŸ¾h Ûw<…ƒŠ=_ÓÓS “®fò¨Cøà÷…K?tÁ~‡Œ?SûÂ+þ—D‚÷rð¾g}ýÒ Î?ù¤÷=b Õ©±HXOX#`\™®ÎøÜWª8âè·ðU+Ø “bŠ>aÝ?/½â\n¦zÿø…ü7!t*€A<óØ$þx“cä˜}Qž‡H€2Õ¡TüVüD;cÇÕ°dév}hñêÅ/¬Y‡<Ã{ŽÿEÞwÀ!ãG~ÔÔqûΜÀò7zЮ±• > Ä:‡hK’$o¼v7ŸýB=‡¹ Om;”ØŽå§,çû·,„þ€æŸÀóŒZÅBž{v-JÏB©6÷eÅSä¨0¯/üÊÅ3~QTåb­|e#¥“¨d‘0.y”îg•Ø ¢leÎ&•X|%ŸïI±Ô#·ÜÜ¥OûÈØÉïûé뫳]å'gQ±¥PhˆÓéív§ˆ¶« wë¿;#þ/Z1lÎÜ‘‡õòÉ7¯ Y±bŸº(ÂO—HÄI CÁ´!Ä”‹U”J1••JY)ÏW€hp*Š"K—ŠÝ:½yC¨G»ïú¸çîA?=û³Ju—jÕÒ0yâàsjjD¥vF&Æ@. Àw( ­úÙk@IÆ]i(QÎ7ÐÖfª{sVõËôª•JÕ5ŒP5ƒÒøžâ ýÆPDé4a,lܸ™ö틹®eƬÀÓˆ«Ê8b)+ä/Rràû†Ë¶önÑO׬*sO{ìÐ-qœÛÛ·ÛDâmÝ?–ðÑиÿÃŽ¸äÒÉG ¯àч7óÙæÕiEäm#¡ VÕÁó/OàòK² ù>5fÌXÇ¡2Fkç¬zá…ç´sN‡y¥»;v詳{õ®«|“Wb}‘SŠÁŒnzâs¼ƒ\vÙìi92™ (ï–oÆ·Þ Yµ*d۶݆Ä@äñ(Ûj*L©” º]eÕuöÙ“äÚïö¨!u£;½–d0”+.ÿþ|€“OøÀõ±@6¿šƒN‚׉rµÄÖ¢u«RÚ–!4©„S\”'ŸZÇŽm‘þë]ã&Ýy{yäµ?\òÌç×?ïyµqq"±=>üpìO °7ÿÏã _Þ|âáùhCâÆŸ-%e:¹øË1 £n<£‰©A;GÎd˜6}œÊ–žV¯¿þšÚ°a _Çq¤“©@ï»ï,£zýÚåʆÝú㟨’‰M¸%¦„Q¸ñì x'Âp¯á Äš=ˆV•G¬å?»FáâQ@¾‡CrnúLŸl®k³DåháòoŸsýw¯>µeî!£˜³ÿ$†ɦ5)nþe’[~™fùëMX[ƒ "Ji£„²>üе}è˾°ÃLTÜýØAÇ<ôhôÑçžu#3?u‰I“ƒ÷¿o§ˆЀâÁ÷hœsPÕ«ÚuĤ¿ÞRà‚?FB„Åyíˆ*àLžÈö¢´Ïë¯ V×~¿BwuÖèl~ú·›??ÈŒlJ›úº*/™ô<¥¬±§TlŒ¶Æ´"V§}bŒRÉ%J$Mí  TœÉUßY<`ùRŸlµ¶¬â‚¨B!è/årHîº"ýôx›x½1þyÖF7Ó_^ï1ïscQʸ PΕ=íl^\¹NŒmT ãséä‰#»;E×ÔW±½ÕcÍš5qR‘ýÍÉA‡ÕñÄ#)Ž>úÑùk·ÌºÞª ¢k(¹N^|¹s~1Î]¿üµ æÜ FTÜq×~ÇÌûô²Q¾‰Ÿ>è T«1~T]]¯;âÓ‡`Û7Pqüÿ„T’?uáìÿúõéÉ-[zùÔG–që+Òépa9 P¦­ùÅ¢<_ú ï¸÷}ßúì—µ·UExú¶¿¾¥}Õ`**RÚ¹PO+Ï(- ´R8)ç4¢³ø&B¬ .ƒ¡‰›o\Í@ùFެ;oÎÜš-!!Î!a²'Øu¥p€â"âôðÕ‹Ÿ_X,¶ðCjÝ´)¾³å@Þx}µ´·)¾ñ™Lštà0žà\ë…ˆí;4_žÿ*KWt5³.úT³æƺN~ü“ךéãÍ×Ãùo¾¾„Uol¹þ£çŒ×¾õȉ·ýuKÓ/®õÙ“?Ö°8Ÿ÷ãaau´up§ómñœ9Ø—_†ÿ?Œ–÷?°ê”ïʳ×âæŸmå—×=Ï[ëó èÇ_»ƒ´7 åÅç6ª¹‡Õ)€ÓNzú ú±Ï¤Ì5™ê‘zåÊåÚóP»ÄJ©=«³­›—_ˆøÄ'†ãÑË[¯UñÒâ ßýÞýóöŽQAHé+Á@_Üù<¢Â~Ù¯/Ô^æï,8áSžÿéQÞé§ÜÀŸ{ØO~þ³U¦qÌ,=²i,锯ó¥”6šr9bÓ†m¬^½˜+Lcò”¸8Æøq ˆñÈÒÑ–’}ö}µ™ÀÅ_ýׯ,Û·WËüϼòæ¾³½J¥(ÊfýȹRÔSѧºˆÿ'gC£iøâ'žóµËF¦2Õ½|iÞ~yÃúþâ)úqÜaƒ¯üÝ­ST&“UÊ•ÄJK¤µ£¨Ã82KÞ˜ª¿½`n·¯j=R‰’BÒJÙ ðzCË–­ëÙ¸î9šçOaÙ’MÄ…J.ûΫó?qrË÷-o„~œwÞÔéC‡æ:4$“€ÞÞPV®d×èwWHggh³YB ²æŸàï÷,[˜©.°½}ä÷¶nõ~íº!Z¶mÊJ6[åc… ‚g •Ui‰*V®Ì¹Jð6ƒjEt7õƒCõ…/N^Ä^˜³oCËœiµ-¯½Øª~õ˼îèY¦[n2³\®žÿüó¥á¥R)YP~²*W€ÁÁŽøsæüϤhECË/ö?çªï›ÔÖõ=üä*xéÅVF¯¸PåkjH\9ç @¥*—*ÌÛœq.k"Ú½rÜá…ΙWÞØh”®T¡•‰µ£W 혠 ‘zººØ¾uÃFÃÌ9ÝœõÉ uæ§|ÈNùæ‚`xA°çÞ¹Pö >B²Ù( ¥ßè×:ÏóŽb/ìLÅ"¦(žßáLb»\ù½©Ò•_FggûîŒçœBœJ)R©4UUƒ¸í/+±ñ´®Å9‘Áठ§ŠLŸ™`o¼üÊö惬ãÛ×îßvlYë«ömV}婊ùÍœ³vu𡕯ö¢ ‘Lú‰#ê‚Æ9ø§ŸŽ·3þÛK¨5 ³g þèïnûÙ³ÎU©ÕK³yM‚¯^nøÅ-Ó8ú„Ñ k¬ZH?‡§¿e¡Þw¿‘Úº” Cm¢ØxQ”ölì›8N›B~°¹ëέ:©SÆó”R‚¦T.¡sêYþj=W.|Šn®§¾2èŠI†2sZfáKroKhHšiÓšt2%ÆFuæ·7õ—¿¶ú‹ô㤸~[«B'ß`ÓvðaÿýÆZM"P.UÊ̘ÕH*ð±qŒ¸ˆ8L³7 ª¼|Ƭš-²G¾b1ŽÖÖ]vB9 åw2 û‡¢”:_D~Í~ö“¼\¹àå¯|ù󓯽õÏ/KP1œžžW©««F)K}} 3gÎ…‚P•i`hÃzÖoœÖ‚Ëa|ƒ³ò¹z~óv"ñ8áð‰‹þþÄÊyýËfe¥V£Ç”QdÒ‚è^¬@ØãsÂ1oÌÿÖw÷o9ýìn®»aø¬K¿¸C‡'©ª2º2tXU­GŽLFa¸]¾û8¹õÅ/žµÿ¾÷ûîã_ÀØqc_½jíÉüì3»î¤;î7§²n7ý¢Š/Ì¿}Á)ÇÕ]i]§B´Ê㙈²ÄL\«i­†5%®Úº©|9ÀÆÍ½ßxóÍ?ºñ†ncâXŸqF£úèÇ“?wN(KAŶ‰«¿ÝHc§6QY™ ¡=^ë9¬D*.;¬"ßUæ÷¿ZÁ¥_-Ï£Ë/™º×ò›Nz[Î|ttì’/Ü}Íål™½¾ÿ¢ßEÀ½fÁ‹¿^–Þ\ãwÚvLûþgç“}æ ‘šº Ù9—ÈŒ3Ùo¿¹Lœ8Ð*2P׳nÝœ+£U'ÕE¦zŸü”ã¼ó1iZšþòí7}b‹¢ˆ§Ò`«á %„XBº²ŽûŸ[× pÅ77_÷¼j¨Õ÷2föó/DÇAd2&Q[›H æ'êêêûöŽðO_ºûÝð•G~æ¾ã?¸Ïþ1ª_ü‡X¿qí(æüå›Vÿ»îÚoÿÆ:…_ ùÑ÷^àov.èìq ÛÐ:‰¸:”ó•’¬ ŒÓ»åëÇÌY)sþ§œ9ÿ3J'ÒÛ´2ÛjƒRt`#ظ®ªª ‰D\€³žÚgæ,5g¿ipðtšF¦ª"Áþs†³vý!‹6n»hÓæ‹Îù¬ÏÞ8⨦ÅA²+ |ûý¯³s×uWì)¿{Ë~š½àœ[çyÞù à™§4hOŒ×#•5Û܇?Q!=½íd³=R,–ñü”B%J C*A&hÄ×uhBO%¡Dcü6´ÓŸ—ÞZÙìi…Q0E”ß „Jˆ÷—•E¿ØÚü³çÕ°a½êG?9ëGâc2¤R&*A¢ª*›PÉ]ŠØõE‘–h˜vqÂx¾ ÐFûV %et ”¤Ak à¾{Öj¨­jĸ*t\¡ •H\‰’j²=1ùBÅp#<}A¢ M€u!o¼že ƒê+/O¥´d2ô€¬Eúf<Èf÷\ýþa8Ž70€~ºUÄÁ”DK·zp MÃ+Ĺ6âXÈ—s„DXq {ÑbɤœŽ(Š#VY´éBÙ žªÂx¸”8â,hÝEl#@ccQQ4D ì}ýäÇšŸ~¼‚Ɔê§×ÚçÎ;óGE‘ tI%œÓI’UU¥D2Yt÷ö<½rÍô?ÐëæÿVÀ‰GþØÃÏM¡•½£ö™QsÒßîiš[Yß©/ùêr}í¢—3±%Œ×Md Z)_‰ršáœ2ôcÆ”äÏ|_k-2Ú*t§Ä~è2 eL*RšXUF™ Ð{)»º¡¯~R½?xê`Ô¨ÿûÞâªÕëPŠýx¦Í¬9é¯wM™[_×¥W¾iôÃ÷nÑì…—Ÿ)”jµV)†±Ž£È”JÛ¼}÷­õ¤\5iJµR:Ü…ÝryA'¨"¢Ê,_±Ž(B‰Ò8>6öQÚ%bÛE.\Ã7®œŒI,C¤$Å›¯Uqß]›ç1€Šj½è?óA¹¼ûÚÿÞí¥ý"ÿÌ—KëÙ ‹ŸMcLß8ßÓnölߥýJ‰J¡¸”ó, _œÑ¾7ˆ¿ýµ0jÄÆCqq%ÎÖàâá(í1y»—Ñ`#¢Š D°¡¦Í}wm`o{Lë×)6¯O1xP+?¸fĬGΞmw^w·õ{{ã /A¯ ƒ¡ Cõ˜1£ŽZ°``‰EíNWVÖ™”‰üå ™¬÷Çÿ¿P1ñ ç4*öÎŒ™ÿv_Ýþƒ­U«–×ë•˾táš½ðÇß/×¹®qÊJ ßàœÑf»™9«ÚÐå|µÏìDj7TÞg,cQn¢º÷î-ÊÓ#*°Ä˜@0FaL ÖA”à'N'´:‰H%ÆkäÕãwÉðƒ÷Ìý¾]~û¥T~<ދℇyùÙ_–I“> §}ø¹KàMš¥®[±d3›·dñS‚ŸˆIhPÚ»í­ÛY»"ÇäEëö‘ÔÞgAL‹àÀU£$‡ÃáÕÜø‹<öX{3{!–Ç=˜Cë€ÆQY®¹nƬy.aØ0ý¤Ÿ¯‹;~´b…{ ¥…__x!+n¸KÖ¢Àêd&mœ˜’´·7Zhµü;˜0iø…O?ýr#ð ˜6¥ú„ûî™3·nеlé`µf©¨NÙ¡þþöÂo»üÇW«ï^ñmÏ(ñŒµÊظ`„=vlÅÏ×®ÍÀÅ·þiI/æë—¯žÏÆÊ´x~\a9ÉtJ…$¼$ZØ$…náåçWsÉ—;šéã/·ÕòÛ›W1 HSÓÐ R©X‚€%˜Ýeä]²ŸÐ‡Ç?Bx| 0[»Ã+*ê:®êèmú®Š1½¹¡Þ³Od¼k¿»AF˜¡†O¡u©h¹JV/3t¶-cí¦Ãiº@÷¢Ð(ØÈjäï÷Â5W½ÁšÖ®æêTŠÑ£S(rhO£Ab%)Þ ­<¬ìàÐ#"žx¸–R>Ͱ±[¹îú÷ͺð¼gÞ<™@yɤ¦ixйycI¢XOª¨pkvJHßÊkŒAŒÑ✨ôΈâ ×FšVô¿gAìªå[¾Ü8|ðWZ·´ÑŸÉ3kÞÏ}ûÏ­­îR«^®V¬Œô±'õªØv*‘ á]ˆ2bÁyÆFÎ FS©ªÒ `BSêúK.›À ' çñÙ/6]om¬¢È–|JåÎ?o9µµƒ;a©d‘dàPâ‘L(Z·¬fíÚùâ7'°ï¾CZÄÆDNóÆ+õ¬ßšmèÁœ9Ãg‚"A¦o }ò…”Ë}Sojï£ßÏÇâUÐ4,7ülJ&‹Si ‚2ëÀ 2r|,ííë¤TŒ0Ô l=¸ Auà=|øcAzѺˆÁ ”Aàû ­»8ñ]ÜõØL>û©‘-¼c_&LÚŠ¨Í(U (¥Ù jÆL‘%±Už_äÐ#cÖm(±i£¡vÐJ>tz݄ի³õ¹œè(rÞqÇU·WטïG‘^5ºÎ¯¨À«­EÏ™ƒÐZ‰WÒ.8׫œuŠñ(þy&j'¶µ¶ý‰~hà /6­ªî-µv]U«Kêèc ÊÙP)1HœäÝÐbŒŒuÎ8jëŒ3.R¸ý(>rjãõ{pǽ3žÚ„R Y%’éÀó ˆ+pú‡'€-£Ù(‹  TŒØ¶m##F)f죬E£€:~ù«—È!µ—%«" ú~=é[ýB˜ë7úÝûàCþYŸtÀíw¬½üÅs¢µˆ§ó’Nää+—Í”ÞÜ&z:±-bEð©BBãwatˆ&‡&FKŒ’2X# ¤“Lª“/_2”;þÚ†V %1ˆ(A”eoÔfÒŒ#(“Gâ„•S‡³riškj9ýŒTÅG>>öCk6–ê• ¾·pÁ ò9¹èê¯w_5ºO±cQ¾ôôtºB!¿+$›iÅê¶7¨&ø~â1±ê+âØJZ1è'×zÎ…™M«GðæIu䉅jSJˆËxZÞ=Ã+ãœGI =JœU.ªáo·-ç›—M!éw¡Å›T*N+íct c4J,ž±! _¡<¬bÑÛ]¤\ÊòåKg$¶ÊñêË!÷Þ½¶™¤ÓþÖêÝí—¾0{²^ßâSòÑn¥\Ø|þ÷g@ÊŽOͽù âD‰g*œˆK$Û$›³b­/Ît«8WÄ–jHcY¹¢$…R ¢Q€RyDr ;0|¿“ÊÊ¡CÒ¬^!R‚4öJý ÃÐá Pı¤q® {ùæEo°yc’³Î«¯8å”1Z¶,®O$œÎd|ï”S*¶Víÿ›ß&í’pÄÌðá(ÏÃerº¨€ˆü{Ó¢¨Ü("/õ—ïÚk§Ÿó©Ï3—æÓg-Q§&”Óy¥5 {ÐFDœÏ»¡”g„@#¡r®¬,+W@ãPM¦j9ÚtÇå$‹{û5G¡Ü`ÄV`T=kW•¨È¤ñH`pžQ„t÷Fh“!‘ ¶’7_Ùsçö5Ÿƒþ‹r͆„9Dõý”ïß% HìiïXð“ï¾ ¶VD)QÊŠÒZ”«”Øä ‰v‹à9NvHº¾‚·–E¬Zë»4bÓDQeI`uëjvG,i¬Îqð‘%6m-³jUŠXeÑÞ•bóº{Å/£t7ÎfPÆ`ãÖ*”‡zqY¾ù’/,aëÃ>PU‡fª¢ƒÀéŸYÛ6czòG¯¾Zz1™LUUu~SSƒ<eü—7Úe³à\—ô?'¡·ÿÀç:mrjÎéö2ë–cê>w.hÍ(G¡ DÐ*¥Œã2arBfÏH~—½°zm¬³ÝMJ$R‘ X²´†MÛ²¼ïÈNCDBYL×Ù*⸠d0ÖòÓ,[SÅòÕ!•U5¾Æ+£X—(⤠‹Á©<±ÍM7¬a Ǻ ¢Âº¾eWX‹ì¯cwÿ²årÿÑïÀÜ‚ØÅ´×Š“ŠŠ@ÊQäTÜèþøë®"¨ÓŠ¢ª6¯éܾRe<]I®·¯|î-^}37ï€{tZËÔi fÏ®âáº;v*dzOkî¼·µ™½pÆ'æ ôF Œbœ¤°®€%KsÍ_ûÜ+-?nÙŸŸ^àì¯]ò<çœ<“ò_ýZíóç—¯þþ;Ž?¯þ¡ÚÚrX; WxÚ²½¢2`†Ä  ”ù´H´¸’>f̪>þοM=°~P5×üp6Rʳ8Û®„£­ã& G?Z½úærrç]?wêéc[N:aÚõðƫǟJ¬XšTÏ= ß»z`¹DècŸ©%R£Y¯Æxk|:<ÃèÑ#1ü¸‘?ß²‰ Îo$Šs8ç±ak®™xà®ì'¼“Cr!tæ ·'úV¾àÞE@þݱÂ'ØéÃOz<öH('ž´å°…yMOG,o¼¶žU«6ËôISÔ܃GaUŠD:#›×oV­%î¾ð"­6K„ñ… ÈðôcEŽ<ê•·E»p|씆– ›ºÙgfEËëoäJˆïw`t\ˆµB,±u¼ör™>xå­lóW/z±åÇ7Mãˆ3_}µcéa‡%º Áᇧï¾÷ïÙ/ií?^Q¡dRmm\¬ë’(Bººž ¡ Põ~±ö—€~GHêÏúä¸é#„+.]ǵ?_± u£\öæ+½ß›8ÁG›’ˆìº&ÄJ«:ðàJ5~dåÕ«7f¿ÂÎ9ûñæŸ<²åOwol¸ôR¸é—3]ðYÅ…óG´ø‰?Ðx&XœˆâéÌÿìk :ú!µà‘¡½½“gžXB.›¤Ø«Xòr/Ã.[Ö pûmS[À¨QTUù6“éûî7èûî#’íx{DÂð]³ÿ·¢µÚ`o³iGéŠd…wU¾8ëÛ.Î™ŽŽïâ/v¹¶ö&=jÂHÕØÀÆ>~ZÅ%É4Î0]()`¬hŒ*(Ry;:fû¶±-^1lÞìsÁÇß॥a3”Èiªi9ä°…¸mb” AÃÒ·²ôÏV/¼žkþÛí-Ÿ»xtÅ7.vÇh¿Í9Ñ'ŸœÙ~Ûm½ºòÊÍ[¾øÅúïø~̨Qµq{{—(…ëWz àö’Ç£?[«éÇI}Ú¼ùS3 ¿±˜?ýq퀾«ùðÇS(%bŒ/¨ ÕGÖëIÓw˜ÕÙ+»ä{õ•£ZjêVá¬VÖ "yÄ Êh4ZÊhŠ h­ŠÉD ¾—Á ŽihÈLNgÝú•ÔÍêäk_oâ§‹†¶8 <û\'Ùo¿‘‹ƒ Ü÷í@¹R.C.×oáé»d¿ÿHÄ:»žèzAoE鬤*²òÁ4ʵ?Xç²Ù„Üà+%ƒq”к‚ ]"6=X1âHƒIà”@am"´WFéJ #F§¹èk³8çœéÏŒ™•-U•š¯|c&š%ˆ W¸˜Ø–§@ ¹û¶­i8ÿÂ1 7üüÅQü zz”þîwM¾êªÎïìœGÈ!«“ÉMMÕz¤ õ®YPsAÚ €OÓ‡ö™øµã‡}çÊçùáV/`*)`Ê¢•F©­K UÊ×ýõ…£õ½÷u±7~}ó-Æo&ŒzTL'Õ(UU@ˆqâá$s(  1º Ÿ@×¢l¨˜,Öèî,íYËÇÏÏP‘^‡ÄIÂØcɲúÓÐ0èrß7îíÏÏ!aß²û0Ü¢®üŽxñÿ)jþi$òtò8ú±øÅ.Q*F¹zñÔ7g_ã¢r^ ]„=£D—'á cq¥5H<_#TÅž¢) \ E Ò R—Blâ,Ê…8[âø¸á¦÷µLŸ–n¡AuŽk[&1zÜ&”‹±6IE1">NêpÖc KW囯º|UsEª†dºnÿCèêU,ºoÜX>¤Pðý HyC†ˆ®­…Z2@@(¥§`ÉÀgyÊGžJ&¹ÿîöFw. ÖiÑF‹ReÄyÚ…Ê„a3*gž|òÈŸ3€~3§å„lD¤¬° ( Zwyq‚s"„"µž˜ ˆ_ QQ@›>qÐÝÙK!_bÖÔ&l”[v*¿ºaÝÀ$·£e/»¼ýr9¤\Fö*ß\@°.Ü@?~üÃgÁ åuŠg:]Í vwì‰._Ü,¹ž^±Òs!Ž^ü|¿Š•oE¤š(Œ§µ‘<`QDŠˆœ ñØÀ‘Ƕ2rL€ýgdZ?x(cGöèD4†qTÆK¥èØ>œMëó¼?úö‹|üœ™ ·ýµ0ª»[TOêôÓë§xÆ—gŸíE±i3bDµª¯GêêÞ‘°ŸˆJ„UgŒŒÇ„/_ò¡a_ÿ:¯¿Ùµ€½°isÌŽŽÑ 4 ”¸´Æy:Šºµ’^5jÌvuñE“[èãÇo9îȾ+)eZ”N¢T€"ƒ¸:ÄÕãì®{p6‡³àË(–¿•¤2Q‹Ñ0yœêE€ÞÞnB·‰#ŽBôੈ(îäÍ×r»ž]3ý˜>}Ââ·¿ñú/¹ê (#”ß–o €ü‡ÜZ?‘þ}lÛ/¸ñ§Z”Jˆ—°’ *œÖVâ¨G¬*`*ÚUD™hGÊ)?ùáKàš@X[…ØáuˆÔìþíì°=÷.…ašZjª ¯ÜŸé“tËIÁE_©EÑ…ÂCKq!„D6B©ýìUžyq{ó»¸×­kSÏ>ÖÅœƒçñÆ›…šžžòî}ì*«ôâU« Îå/ŽcO)gªG×*¥ÏMãDØLÚPÿ«ßwò]w<ÃÚ¥Ûx7ž~jËׯþÁ[ˆT*ç|m­Ò±uZb­£H”¸¼šÿu/sT À·4“ÊÌVåùÕøž ƒ¢bÔÛ "…ŸØ&±.PO)ßÄÏ®}„7­’(SFéfϬZô‘3&²yË.x¡ùŽ{Ooùû©)•µÑs½½¨tZ·ëý÷õ|åØãkàœv©DÙ „Óik£´B)¸1ôc”º}§NTùÁ/ݹàÓŸwå°±ߺráW°ý{+¿ß·^úᤖ°Wc}­H(±V‰Ê¡âj®ýΆf€Y3þÞÌ»ðµ¯M_ä ¾¯0´*$–/]ÆÚÍB¯ÝÄ 1cIÛZ i¬(“Çyıàtš‚nä7-¥? õµ/g|çv>`w@‚0,™Õoæã]³ß\@@ÖÓkÒÁ}}x9G½oÔº¶UHo®ÃmÝ**ô*­Û¨Èxì;{&«×¶sÔ‰5üèçûµ¸Èb"Œñ@­cÜîð¼eJiÀçQÝN‰á‰Çº9êè*DmCùH 6AWG-Ü·žwcðÇûO©"ícÑõ¹ú[sæ9Çì{ÍîÜ’É$6F9˜8:Ù²r]î7÷ÝÛúã㎯ýBJÛbF»ÎÎ.  ŒRß²â.@¢|Æ_zÅ_ñ¥‡øæ÷ÇÐÝ«{î¨ýöËot]Æ6m¯ßùçö«:r‚N%×i-¡Š¢"Z{Äq?ÒÅsÏÞ2nRˆumÊb´6ˆbWÂFš8Ì`ãk ¶ŽTÒ`¼?Hñ÷{}"—bì¤ývÊøqY£T+!Ùb™lG/½(|ã›;ÞUð±›¶‰˜ `Oû% ÊäØS’£(…N©þòaø, ¡1æxkíÛ{K ÑáW…a‡ÞÑ:Áœqê³®qø4=|ô©©* bT2 JÈdŒœpRBy²‘P4F<”¶(§PÊ`´E+‡Ñ h¥Ñ*‚]¡¸€ÑM l\fÓŠFŒño ¢2 üòº6{¼£™½°ÿ>þ¢#ŽjdÄðõh©fÑϦ,úéµ+Tëæ6Ùù÷_»~ÇÆ2¨DI¨©ò¿Ù>W.‹yõåÎò ÅÔ¡FÇX%Ddî70qÇŸ4ñˆ¥¯m£w;åžseÝMª¶Þçø“kÙ)à^—¡=ôhëW𭪟|óÛÕJ³M‰ RaäX¿Î‘Hx4z“84*<: ª &ÂSŽXFº° b $|ð|p<ÝÎ>°?O?ÕMÚ¤™1m_|mP:O±\fã¦^¶ºçøÑOäW7-m‰GÃ×›ª«Æ·ôô®n1bاR©dLÐI¦¯ý’N+;¡\~;D©w_ùüzüg>ݵJ|³Yjë6Èq§TºBùM ãÕÅÝ/¢œ (¶a%ÄÓ tŒ1Ú÷qbAĈÂ9…C)#’“EÔ9²Èú-[Y»>‰PKL̆M)~ñëu{“O pÒ‡|S@«­v¤ÏòunÞƒw¿®>ð¡1C{ÚÂ&²@U]W¹Ñ›Ÿy*{qFï;þ„Qg~ðCM#!:ø„ƒïš¾Ð>öÛÔˆß.z•µm½ N<µ¬Œ”¢UvFZí»OÅwßí}ô7¿[ñÅõ†¨Ð%UD‘Õ«êÙ¸¶’ƒ ‰ãZ%q=.Î`mäMCÏmØ}5»CÐZ¡Ã˜2Ö¶"6B;ƒg´ŠQ*¦P*ÓÓ³†cN¨ ²öMbÖc]}°K>€Y³¦/† ïýÊ}‹B $Žqaˆ-±@^2G=åÈgŸ\¥íôõ×͹ª¾6§p½J;ÔèÑêë—OP¼ ß]¸Duö aíšj6o´vl ‡V"ÎËáLGWचXEX¿„¾Ï€ï±çÞ ¬xx&Ñ)¬s(À:‹ ez³Û9õÃ#P6‹&Cd‡rê©SZdxÓÐO¥´Ž)‡ô}±FI_ã¹/BÙ)â^W¾üg•àYÅÏm#‡IÂëV¾éa«ë\)眓PÇÖ*_Cì ¹\’ï‹8öØ€"´Y<“@b,J…àÄÑÝí3uÜÒfþ1|ü#M-½yx°³™waú>>s,`Ä".‰H€¸,'žRËsO5òãkž™÷í±èûWliª¬Ìlêí- ·4%Å=w­à#ŸÇÆÕ!m#|ÓH¤rŸÉýd3† sæŽù»–¤µ#üÆég¦¾EE”ó•(ÑY;b„Ô ï<ðhû7÷>¾ýs_ÿ¬¹>™L±ÏŒZ>3ïåù{Dýèêi‹YÎøø*ªÊ8]¥@¡˜2iÒKå>ñB€þ»^‘ïBúæ~Räëã?M@‰•æÓâøÕ¦m] Þz}Ò•ûÏ©£uµ)9éÔJ·léVQªÖ)í+ÑPЬ²’fÕÒˆÊ*#ûèSóù\÷“©-mc[´gQx(|@è=bD+W á ýŸü‡¢ž~ÆXŒn—ÀJk-±óö™]Ï­wneëzaÆìû—²Ý›²ÙxDÃÊ‘eÇfGëªqüúúçQÔQŽËˆ.ŒÆÊ õðæ¾øÙå&0I D«-^¹h•¯ªDL¥qÆßÁg?7™}šwãÉç·Îø‘\ß8b)çÎohñãatÏÓ>{dð¸í¯½;%]1À·½èÎÛ“LOÇymb4"†8Š8éäjjÛ±x:àåW{X·>7`ÈAWø¾oÁ‘H@@*¥ú5Ÿ#%q¬úÊï^zÿ™Vœz€ŸuÌÝ¿,J[å#AÒŠ§†;ÕVÊ"ªW_}…B¶‹Ömí{Jë7ÍhÁiDÂ=‚iBPZ0ÚaŒÅC£‰Ð: ”À„P†pÛ6ðøØG·ìwpgCD4N X .®D)ËÄi€–Ÿ>1¼Ñw<1"mbÁ „.âSó§ò«Oày PÄy”³Œ›lzëµ:U‘S÷=pèO{{·'OãTÑ©Xœñ<”‰Ý¥9á˜A?øûÃí_ã]øëŸžçK_­T …’$ÊÆhU@9A,ø~€s­œþ±xW\d%ˆf ”qšåKÊôözr9º?Ëœýg‘V ŒññC"ˆñ}°aš0V,]Rè·Æ²îeß÷\"‘ë[ùž+eB Ž•äóHá´ÞKßï_ kLŠOÛ"¿ºúG¯ó©‹¦ $’Ž.OîøëvWQÕèÚv¼å$جƒD¥ÌÞ–êÜÚAg÷³Ì˜î—‹8¯çúõv•ì íÀg¨A¡°(ÀFiŒ®$–vVn ¸æ'šÿa‰þä,"·(ãâ˜8JôeÀ^¾G¼úÚFFN=×׿ж5Üê`ØÁõ\~Åbö;œÁCjضµ+|'“æ¥!ƒ‡žÓÚ¾Á“dÉÓ& {Udۉㄕ¶H.®H{âë,©ä 9çÜÉúïÿƒ,øð6>ñ‰É VÝ \¼g'1çºà{„,Z$ŠJG€“§ ¢±êjGÓÐ4ŽW^ ‡‚¸»‹p.^f-¡Là7,îÛï¥æŠ ãÇlN$úÚ/;@®oFDïÞrM¹RiïÙï_ ±-íÉ‚[[Ë *ƒ×8ù¨‘Wõto—a#'¹™“rNÍrV[¥1ÉuêŒO6bÙJ"PÅ¢œ2ý˜ ‚b€J²mKW-¡Ÿëù鉛¢RFG¥$"¡•|[é\TÂH #+4ÿ€åëãù¾eKË%—BÔËà*ñÁÆ8X %6>˜­JY”*ƒŠAB”ŠXNùØhž}(6Íì}æ"~ÚiÞze—Ñ4ê¾y°œ>hlòre"a!„`xÕÕJ‰2¦¨Dk%±Q.ŠÊv¯ðŸDóEdE:9üú(–¾ò÷wŽ•¹û’”õIJÝyžv(E,©T¢ñTˆC‘@“@I²/R°+Ü®{’ƒ8pÎúXÛ†ñ…{ÿÖŸzï±GU¶üäºÉ¬^ÚËï~‘`ÓšFlqì¸FÙZ»ä¨ôþòÛ{›?7ëC_º´Šg^XŽÅRŽÊ 5¤t£› |ìLF¥µùL"‘¬NxI`ãæòRÖAXòÅ^9²^)Ny…¸`V¯®Ò?ÿa½Y¹,§{æøëøüâ–eÍ÷ÞÛ†€. º¤âp±C\ˆuEAðA9Pyèë!! puX ˆ ©¨ÌऄBãbETrø¦ÈŸÌö¶‹¶l›¾ˆ>F o¸pæÌÉB€~Ÿ\o߇„a™b—Ïc=Øâíþu…Ò–'F4úWjÓC:½…ëo,‰Ê—]뎗%’íbt,Ê+H`êåοl×€(0¦$¨Â^BJ  Då==,шòèêªã¾»;øG{l##†8öÄ6κ Ä²eÜ}—F$…¥¦¥»ÐÀ¸‘ÉEkV›ƒ@8ôˆ‹_ØÆ³Oì@ù!âY"É*ùÉ÷^áÐÃj8蚃ð¬éØ^ü À¸•´´'9ÇÚ¸8cD<=yÌö/¬x+i>ó…¬~ÿ7êQ£6¨Ë¿9öçüþ~oÙÞé}¥5B$Fœg°Öá$Æ9¸$®E-Je@y bTÜÈÝw¶ã¥:Ѻ€+Ö²mÓkùð'*ñLˆ²C˜:>½`æŒ1/…a„ô]I¥"Ùó¬UR((q.tq¬l¹Œíé ß¿Z@ ¤5S;vDüêº4Ä#$]±•kÑ$U•‘“¸ÂW:g5"qŠ•Ë‘N<”ò<ú‘=W' œø(e ÄáñGº£m Ø ßýîø–s/E ZQÞfŽ8.Ïœ}ëøõ/ [6U"âpâ3qª0ûÀzöhÕ‹²‚+â0‰‹Rˆ.É<íSRAB }LŸQ£ÆUæµµ•zýêÁêO7¡Ÿyz\ËÑïoÓÎuj"­ˆjž7B]þõ¦ëy֬鿹§Ö %t>±õq.…³Aßn´"QEDÉà\%Ö}ýÕ,Ë—ðT#Æ«­0^ãét—{™Êœkâ/,’ëVÌž9òÉÊtH™·ÑzO߯ÿê—Riwösq\²ÅâÞ–]ýëÄ9V;Í–]ó< v°d* r̉Æe;Ú]àùÎF)§t uCɽw÷F£<œ(”R"(v‡Úse÷Õ"&*RE”‰iïJsßý[èCÀ·¿7¢å3ÁFðº±XWušú¡mœyA‘·–Ùºq8HJ%ÐFÑBˆï§Á%P’©eq"˜DÌ3O·ñÊ šƒ¯mjÝšÿ,}8Ê*ŒÊʺ:ÖoôX³±]}â“FªOë¸T­£0­séAÔ›|á+,X0n¯®Z6ÿíž•teSxÚÃ’'²D•òX)cÃI§·#ÞzÄlS¹ADáDú{/M#f#dÀÖ‡%zropìIT¦×ãT‘Ø$ùÕ-¯Ò41y߬9C×”P´Ž% ßùè¼XT’Í*×Ý­\©¤â("ö¼>ÿ‹3 @\ŽøÍŽíá–OŸµã'EéÌÚ'/Û6¯tb»œï9[$†Ë›otËŸþÚAì’8bœJˆ•»ƒ]‘ÆR‹Pƒ“F,ÉíH~uÃfn½uû<öÂGOkh¹ð3ÓÁ9lì;Ghk]-¡V‡h“รXþV̽w&1jÎ&èÏTô/VÀ¨T tıÆÅ Ã%èR¡l<‰¨bÅš*õÕ¯¬=[¥B§µ5ESV½ºL^ÅT(QC/|þP>ú¡Æ½J¸a}77ü²ÈŽF¤OÇÙz"[K7Ú&"7ŠØ5S ª kë;ŠÛþìX·¶ˆ%‚ˆ&ð+èèZËø ‘[šÆW¾ØÊè‘Á}ÇÛ°.vEHi-ýßû¬E¬ÝÓz)•”-t†Ä{ŸzûW‚cn¹óß6ž3ç—5ÃÏûìñ½A¸¸×¥¬z•‹j’P³ªR'œœaîì×OhjªÜây&zýõŽÙ¹|TÀ¿Þ±½ù¯wÜÏ?ËgΛÝrÉE/s÷ßßY¾•ʨý7ÙÞ£t ƒØ4¢"D9"-8Û-b6¯ÔO¯ÝL2᫚áefÍ\q¡€ï{ßëy‘}Ê_ïl¥?£š·{ ÜݧQS„HÀ~ðӵͼ ×þxR‹S«8ãccèÈ%(r@ÆK‡…B„Ÿ°jùÛm=,~nã¶sϱ©T è­µ@øöïD $ µ-—ÃØÚb\, Ì~ÿÕ"e-·\vÙ²#¦Ì=åàÑMe¼ê²˜”qN´3QÚU&Ö¨æOWãùõk¯ù»«±â¡Tf™è%iŒÏ”PÊG+ƒ3“æ¿WóÉ¿°×ìwÆiu-×ÿfFmG9… Sı#Š#"[ÆÚ'P(ñ0F¡t'KÞjÚ% }0rD’qc;ikõq&¶U8¥;A;”/¨xÂúóê[Û>úéæCo<­U|“U~rðŸŒïÛÀKDÆ‹bã¬o*G-~"ï·)¥ Î ãÕg‡µüå®­o‹µaS[óä 3Z–¯z³yòLZŽ; (›äÓó'¶`"´‰ñ…ï%whSDë.”Šqn9Í͸îšÕ$ã±Äø`™4‘Ѽôú n½íµW¾ôåÚÅ"^¼m[€ÖIÑZ¿3òÍ”©IG ˆ\E6ÞIêHºˆR)âÿ¨€šÿ¢\wôÐû¾í_¸pÍ–dª±ü÷¿?üÄSO¼õ¬ñÄ}Òç¼u‚BXŒ²øž RB“ènep(#ºcRRèýw®}ïaê¬&Du"´ã؆ÓmXòXʈ8ÄEc´‚„CkC, ‘cBÐ=hrhRH¤p’á—-›³ ÀJ —”‹…8B)Ñʉ¯w(¥P”ETˆ6P9")3]òÜß:¢Â0ð:@gŠ8)‚-€Ë‚”Ð’›AÙZ<•ÁÊVŽ8®ñ»q^'¡ì *Wóovl¿åÆ×îùÒÅ5ÏUT¤âR)±»¼†!od &­%“ÊÊÈUT+bbçÊQ¡`"©&Ú¼y€|ï… Ø‰YuÿÝKWÁÒIžçÝ¿CöÙ°ýÍ­ùáp§††)<•×Ú„Ä®¬”ΠHƒXp>Nù(C©"®<„_þxüå/mÍìykÉFb;'‚²1q\&²b+ØØCðƒŒñpRÅí·¯ ?¯½VÜúô“ãGø‰N4‚g¡ÍŽ@WslègJúáûŒJPZ”§ôΧ”uF#XG¢H¡duX­y7¶®ÎqÓ¢u\ôåA{äñÐ’ÄYƒS1N‡ÄbL‚H@¡p4»¡´îèbËöìØ¶a{cCûâsÎN¯Ã4¹8§ú6’LÁîH™X!‰D씊\YÅ;E"7a"Ѷ·÷_tú^p +â8ZùÜó?ñÒËú—ÛXsüñ&M›f†q”aÒT§­h½{¦Bi݉ör(]¥±6ÉÖ-Ež~|-‡ÎÒòÔk{_½û׿tÍ›¶O´HÅ®¸â•fþÏÀч^D?Œï¶¼ôró¾XÇ!‡ å‰G{Ñ~%`ã6Ž8ªÁmmúSWQsëuW/céªÞÓù'ùöwf¶8²üíomÍ€ÌÚ×_ôÚ+Ñ;çç­(5û¬oùÄ™ã4,‡¨D4ÎA¬"Ħˆ#m4†4+–)^x>˪;¶¯ZùʆáÃÍŽóÎK¯€tß×lårb÷ŒÑbLL¤Œˆ$ #§”‰ãR1Š¢rØãra*E´zu¿ÁÇÅ¿=gÆ÷ñššjƒ¡CÁ“OôN C7ÌYO+ë)Ïèqo­ê\È?É3‹nùëŸ6ñÓkW¾-Ü‘GT.ºê;1|ÄJbq¸ØÃ‰F¡ÐÊ¢=‹ñÊ$¼ vlË7¿²Œ{ÜÜ_XF^¼ù‡Î Ã'Ÿð ±í Àm;ƒë~ò\ö¾{7T2€ýfÕÝú•oNdð .I%³$Œó½ 6~iãbcB§¼ÐUIëæ&¾yéb²ûmÙŽ;qdËÁ‡Å8‹VB, ¾ùf3ïÂÅ_Ø¿eçÉ—m¢âõ© ¨¨Ô áí8û¬Êõéô?–#›M°«üvtTÒÑ‘Ùý;Ž“e‚ è*+;\2™ãÀFÙí]áöíA¸ysg»²€ðÄã_‹¼ü2v§„@P''œX³$Nø+ËUÞã·Í¼öÇ3ê¦ÎØò3+½J«” ü¥DiŽA| "–{ðT‘þ<öxvÞßïn]tþgê@:P„h°}+n mp*KwïÚòP]mVüêg¯N¹áwã*=¶ÇÝŽVšÃ­Á3kYúb~°xéµÎÓ»º‹·"ªˆV(UF“K^ø(åïþv¥¿|ûÌJ¶Lžâñéy†@ÊXgÁÄ\8oh‹ØqX‰Š{QXŸH –ˆƒ?bð×/}òõƒI¬92`èPÞ&àBÞÁyJ|?Ü% Æ„bL„ˆ'¥RAœ³.ŽKÎóˆËžD^ÞFÝ&z^GýO ‚ÿvöIH&ƒ¤Óbí`'â¹Ç[?废xÔ´}¶X­·ªF[*¥+”Ñ(PFY”Ä*”Å©2ZÇ dÉ›ÛF¢±ˆ "”±£3à2å˜4q0ç­ZnþÝêþòÆ’âÙ£†§³F6¶ F'ç°.Çú¶öýØ 'Ôpëè1)Dõ€øà J•D)%Zy(Î)4ðÚ«/Ó|° \7)ßÃI%N%±J#ºŒÓ‚!‰…/ÊmfÊtøÞ:æ; Ÿ•¡Cƒ•„ày„ý ÄsJD„IH¬!bñ}O‰²ø¾ãÊÚÙÐE¶T0qeQ"¥¢Èæ;âõëß–Ïüwp î‰'`È¢çžkóÃrpè¯oÙÿÀÙ³—ÇqTPÚŽÐJEΘ¬Få”ÂW ”Fƒ}G ˆR¾—@‰b wÞÛ6ï‹—Y4ª)Fœ"Båj¹÷®>ݼjÀÅOXĦMóÿí _›|êöÍŠÖõ q "†¦‘5tPÍ–çžëΉnÿkcG'å˜c”ˆQ8qN1x¾Çú !½Ý!ýyýõRó±G™ð L±Y”ŠÁfÀ…@…hZ´ÙÀ¾³s|ç{‡ûKŸ|â’‹k†xå Ÿ|Î)Av]Q.E»ïCm]ì—\E WÀ8òb …8¶¶h»½(N¥ÚbÀöÏ|ÿÝp·Ý¦“UU gNžÛwn¯õ(9ãkeã’6”ÄZi«”r»ó(Y§ç«ØÆJ)CìBå°ìÍ›j>Â!X”TñÐýšç/ðä“û/Ú¸yö"íu²r\s (úÈW^޵[ ¬Y׎¶V¶–Q~šCýª~Y]õ]9þÉ“ó¢l޶Z™=÷3~výØ:2#Æ+"ZX½¥ƒÇŸÉ73cÀº2¥á©J)DBœl œC#&@‘F»Z4E&Ï IUW̺óNox}}ùß•„„Ú q¬\”S´…ЖËÊ…eqùvqP¶¥’uR¶\ιmª×¦Âf³­öž{ÌtüOPk3£¡ªá´Öî­ µ©»R“Vh‹Ñ¡RÚs†²Â9-¤hå ¢”ö¤ï%UlA”QìÇÌrÖ'–Í£GžºhÕª9‹Dw Ì*œWÏ”)CøÔ§‹‹nüÕæ·7̘6høeyî…sF­…›òlÜÜÎ…Ÿ]y뿵I? 9åäa·NšcYG:¨‘¦QYüòˆßyA*Úº1í~“Ÿ”ؤeóö½†‚gƈq ¬ó°Võe`A°(mѦ„ÖYŒ*¡48 ¿Ä’%= ¾üeœüô)Ÿùlr•ç”” P*)±6´¥’‰Êe?Žã‚¢†Æ¶µ·}»ç²Ù¼kkÛà–.ÅÁ^ÄûŸ  §õŒØÙ7vÊ@ggQÖ¬¨’ÉÓ†+K/Šz甦 ;Q"('"Z‡qY])V¥•²®‡Ÿ=ž]³s|W~{Ö"c²”ÃJwS,´ãëW¢•B›2ÎåpÚÒ?£yZ¡t7¢*A à€íã2Dn ñ±ª‡„Ñ(UFë"ÊDâ›XFŒnã“$E«$:¥yâÉ4O<œnÙ¸±ÐLsfù-gj2è×±åÕX·•؆DÖàœÂ h-(4¢«P:ƒÒ EŠu«,O=ÒÓLwßSø›ç¹SÎ;¿b¥ç)q>µËfÝùÌã|>Ø)bg\.ã l6‹<ñý¢ÿ)©Túˆb±ðýX±ª¸ðºïo]xó_–,x—Cš„\óýi??üèJÆL* ªÌÞHUH¥ÛÉ¡µ#Ž=’‰€°¡Tç XéÀÙ ¢0ú—`… ˆŒEˆXÄNx>A[A *)ŠVF\”üÏäEÑ d1ÔxýåˆÃºW°i]šÇ,qÉ77ÏûgÛg~rr ø·;KkoçSg^|¡®Â/Å&¡}ðÝo¾¾´ãŻϸë®Í=åc“o8Dj”CTê@kƒÑF%1x( Jòú¶ùН.k9òèA|õk¯6·wŒhùøùE±%¶ 9”Qh­ð…ñCŒWÂSUàFòÃï.go<õtéÆîvµà¢/«Ûjj´Íç‰"g::ªM¡ÐãÞxÝï]ÖüPAP—I“®iV ªJMÀìƒf³ôw%ÛÛ³ð¸NâªïÍžg%.©pVY»Í8gµsbŒ 5’ÔâøÕu›ùêeC:(DÄ¡v¢D"¥ŒEiÆ °7Î=ÿ<ÝF[û¬–R©+Eƒ‹K( 0ŒRøÚG+À´c­åk߃g’-ßýÁÚæ1ûŒi™vÄáòæë/à²Þ|yÕ¿ºÎw>+¼#Šzz ›-«înÔàÁ¨¶6úãø¡ùOÆóÓʹâ EÐtØû8àÎ?ÐxΙh/ôIµ Ͼ ‰ ^£TÞ¦p¡Â•Ë:.kc£¤‰ËiÏF)ãâ #qŽK•ï©U·Ü¸ÑcBÆNìb¯èG'¢c09”W vE¬MQކsõµxô™íÍo ôë#9듃H㥠ËJ{Ķˆ£„‹ 3h±¼¾¸Kqúpu÷Güñ€ý‡üàùr§ÿáW9 D••ˆQ¨$è HÊ Ù• d¿9~ËØ)­ ÓͯÙC®· bƒX0*@Ä¡±(,‡‹ŽF¾ŸÃx8ñ D3ø”“™óë_3ìCXüVïU—^ڵ䮻z' 6èí ¥Ò‰r¹*À4 ÿ'è{Jë)ù}Då˜`¿¬®¯ã‰Ûï@ªjH§3ÌœQ‹’åyN‰ó”µ¶¡26Þ% 3q[#…Cõtyêч;8缑Œ£A {Câ œŽNõbéÅQD©ŽÑüùw9îøËÆ·åûÁ&·Œhjç¿[š}òáõÙb1GD‘(îÄóKØ2\óÝWÐ’Ù)ÉOüõ–žü°á99ÖÑ·ßµí£Ü€©Äé$h•CT‡ÂÛŽ˜vD—ˆöcü¸Îýt-?ÖN>[’$qlÑÊC)…B‚8P’BEµxR’€ë7àgBžyêשּׂÌÀ¤ñ40þzúؼ9>ñÑÇÃÃÊå8†.ˆƒ8AeeøýލՀúo) ‚ Isj«ÌÁßúölæ/œ½ gûÚ…ÉBŒPGzÆLz×/Y¸øÕM ÿü—¢’°J©rƒ*…¡)Dµ¦d3¦\´^Æ&Ž ºTŽtgT[GR=ö˜ãC§Õ#ª£óŒžàKŸ»ˆ¨Ø‡8 =´­@Ç "ª¸íŽn¾uÕ’f€ÉuË÷¿³ïÎh7ÿ:›Í¶ýM|zð|0Õ÷g)(iMER½O=¿ê?ÿ¡»päÁM̹PW}wÉÇþvWkÇ ¥l†zI€ä1„ 䨃1yt ÝJ"±ƒÓ?æóØ#tõdÀK# $ÖØr€³‚ÅÇ)”ÈP’تÆí«ò6DÜëðÕ˦_ÿ¹ÏWs6lЧçŠnBàA*4fÔÖ&œ“¬þ[ ¨5SÒI>q S†ß}ïÑ\üùz¾rÉHN8yøB€%·ÞJåÑs ?l!ÀËÏöª’-é²+‡Æ†í^v{±*˜(NëRÚª]âÅꑇ˜úÑ«6àù=(eQ;ÑX¢Ä6&–"Ž<–"mÛ§qõBÍßXÖüÎ.Õyb=;ZëXü\çÊ# Ç"h­Qâ¡T¿ùD­5C†$²O<²cf˜š{è`¡«®Xúñ_ü‚[nLóÌ ãZ>xzÊÑ\ÛrÌ õÜwo{nÒ4»,$@œâ¥—×ñÜ3›1¾´íÄøÎ9%a­}ì‘Í…“?4š>?|Ô­³òþ“œL˜T¹s&$!=C]¤TîÞË^ A…SÑCùæW6rç=ëšÿò—•üæ¦Ùî:”ŒÒÃPá Œ„‹Ç±ð[¯0ræÐ–¦|‚P4ÙåËH÷äÑA¤¦M«&Àâ«A$\€g6ñƒëê9ô¸z¥ åýãt:Ô¤‚êÁ^PS%&O&9iÁˆøý$TïI}/y„ |ð$UBùEü J¬_ SB‰‹TÙS:ªª1“gšUÝ_ß°Áy÷ý½Õ¸(£]بz;šÔ¯]T÷?Râ _ÎÇÏšz=À“ÏôÌè>£”¦œtâyE¼ Ǥiiúó±Óxð0º:k™2õ¹æO^XfÄÈE¶mÍÑGÛ€QÂÓ¶­8`NÐCßbM8«‰Ê…!‘+âƒBvÊ9ëœÃ¥Rº÷á‡Öl:Ìçð#jÿ à$`ÓÆXº³97ld;÷SMî¹g‹ÒÕQ%£F5ÑŸ}g×O˜ÜÀ"Ü—ç•W³Íf ç^˜áá¿»±@>¡üpÿÛyðþ|3@å”Il®kÀzFÊG0xº¬œõ.H"‚bßýFSêí½*Z½úLÚ˜tµ ꆉººTbð`’ sæàOÚ¯$¿×Œl'ŽK.ypáygnDG!Š ñR€@(¢lIi#VGÉ”ILÙ×H¤0Ï=ž5#G-ûü˜1o\´ï̧?wÎ9>üa‹6Û8oÞ;‚)ã]+Z'"”ÎÒŸ8r´wyþù.vtŒmñM§éîÎóäÓíÍïxSËýwwåFŠ—õßzLá@€Eˆ@ P"a£H9k‘|6\ụ̂݅ž<€µ[W}âÉg¶žÓ¾}˜Ó&t$»Ÿº+¬%™&ÇÝp=}¼òj8ßèH p€rX‰èƒO~j2Ζ9ícÎÿ¬ðÐ}1·Ü˜â–›êxö¡SgOkÐã&Ò]›Ä* H“Ç' Êõ ª ¼nååÆóõK:ùÎ7ŸlPF«L§k«=3ªÁ÷šš‚`Ô¨TbÊHCS$†{øãÇ÷“ð½$`ð‰­,øÓ_×/<÷Ü­ho,`IXQRÒ»uݱWc”Ä^‘¼W{Þ) ®ÖêO7§Õ¦“¯_¶aÚõk6ìw}J;pbÙë×¶(Å9´Tàl D#béOWGȳϬ㤔ðt½3l°ôõ}pÔq -MÃêxê‘­+¦L zÂðÍ  x ((%EØblãÐÅÎZ%ÆèÞçënl1ŒÃügúxëµ²Kø•Ö÷ŒÚÝG>&òìs«åG¶Ï§±„ˆÕˆXP¢ðµ¡´Káû!‹6íœ~ÆÎüÔÎüLŸ ‡AÅšž À|Œµ(§(Hžb˜Q߸d÷ÜúÎÎb&H’©Õ0ÄéAcÅŒ#ÞèÑ_9&™HK'‚&‚toêÔ~åø=“Ãh½ XHøý¦…/½4œ”(¬2„®FÔNòݪÞ¯‹qѤ•o ’2õ™¤š4!§´—%ðåoA£ñt#i”«PôñúK!¢5NöèÄCý!• øàÉø^ìÀSÕxj$o¾úŽ€³÷ǽwoÌ%«ìr€r9 ”\ â@PÈ»M*ˆCgÃP9[F¬…îîÒÚ‡ÜPœ<­@–¼µÝÅN9£ë¬§[mÄ}èÔaVlß¶®¯YÅË/—è­c¬-ø…£ŸJBÌîÞa¥ èV'%0ÂÐ÷ˆ©©Ä…Í`J¶šX2¼õf%·ýeM3ýHÔè-i§êëax½¯|3x°ó† NøµÕ.t:QUEÐÕ…÷ža½„`á󯵓‹¦óø} ê¢ùËðóµº`ËÆ¸H»¸¬=SÖc÷ôóŠ(VÊàyy4Ýh[‹’¢ êÕÅ ú`ñKÉÛ…•˜ØfC’ž‡s%œ±‚s†í]–UÛ‹ôÁ>ûÖòÀƒ[WLtC@звô­¸ÁŠB€”§Á@¨„ÈâJ¥È•ˈµñΰ`Tö¾ûWoœ6u:ûî_õ@Öl.HWoS^ì‚ ë’~Ù~(GSû3úᜇSZBk)[¡á…×:é1ytÐUE(€Êd)Ç1þÎ0‰zT¤8¤Ôá$ (Å|å¯òÔ3øÅ¡¼ùz©ŸÔ¸5„Ô¤Q55¢j† 2õ®ô—Ö Ï×Î¼ŠŠþ¢ÞŠ€J²Pj!@9„çžèæc§¬f^óÓ<ÿÆ Æ)ßxÊŠh-(yc6ŽÔÇ?;‘Èå°âxñ¶‘WNU©0E,ïøÌ³Ùæk®ò(Eñ¥‰(j)•3ô'Š-b»atç4O>ÖÃSmo8æØQ-¿ÿõ²mãÇÈóÐB¢¤Ïľß ­’ µˆs.Ž‘¸ïœŽ8¬¥»§÷õ¿üé…ÎêÊ*ž¢sþý÷fE\¥h­gÄyÚs %ôC[³-à&ðëÖñês=ÍïœR/8;g‡ò‰£v4H ÌNûøL6-~‚PÒˆKâ"TÙÃsi^«—Ë¬æ ŸoçùçïFâíD™e-ªèœ¡$¦XÄ Ã÷` öüÄèÀO ìÁE,|éAÅ’g“¬Ú$ ¶o’ËÕ¶öù¯Úû‹JÚXy¡UñëϪ„Tðë_-§ êÀ¤ˆ¬ÃEi娧;WÍo~ÛEÓx˜ù¾†–wö~«ùò¯oæ·ØÆ¯oôذÑÑ<‡Óš8ö±6EG—σ÷m£fì3••Ë·¾D?Ày€ pP(Á˜$Ú8põÕkŸ0)X¼G@ˆcKÞzký’É“¦Ò÷ݹ]::ª2Æ)å9cÄé8pcFN~; þÛŸ üöçƒøÍ/jåÊ‹·ñà­­ôÁsk[† ¿ûµ¦˜O#ÎÇø …vu(iä÷¿ Y²Ñ zž½ŸµO-ž'’dùÒâ¼Þ(àÅÕ;vÞ·2dPÃ"úѳ®}8{è{.Duw‹*t¡::н½èînÔ{mâÙØ"%…ç`dcÍÂq Sª“ÊÌꇾ’=HÅȆ«ã§ŸRÉbßjülSÈк#Ã÷~åx:ÄMª·{,S_k~ð>á‚Ïæ˜½ßVZ~ÕÈ¥ jùüæ¶ÌœQÑòéÏŒàìs{8A<ö`ý±ÎàlQ §…GÏs÷=ó9ö¤)-;?bß>v„·!€~§C„aˆÃúZp$ÀºˆX"ö;`  5 ”ÛÏÁdRoyë­uG5ò¦=Ÿ´_òÈC9QF;mŒÓ:rÚCÖm\~}Œ•æœye>uÑFÎiNS5Øã‹Ÿß¯åëߨ§å'‹&pÀmœÿiǃÏrËÍ1½Ù*BWM)œÍÕßÚÊã/d›¼’ÃQuÂËOðüò-ó¶/Û2ÏSHšºL’ác†¾-aÛË«î)u+/®ÈuBGǞغµLOÏž{À{"*¥¼´_qN#2iËåWÀm÷Mâµµµ¼ÕZÏ«kàG×MdäxïªÑCk¾—ŸüóëÄ_²’0,¹4¡);áW?z}þé'>©nþ…â¡»s,ÙvLËé§{x0 5=œñ±"'uóÀ#3™8®¥=ÝÕ¥éµAD’æµW‹ôÁì}ưréÊż½wEE(»ä+—aÃæž–'/¿½W!€èå[ö?x"Q,PÜ#_@? •+W¿¾Ï>ãèƒçŸíAܱbE(8$tôqÞ93~ÒKW—%Œ#FOn•ûŸÇȉY>vV’úún¨Å®ÖT†óÏkâžûB~õÛ<'ð!~ö‹w>-õ%!Š`ÅZ²/®föìšEÓgW-ÚwN°èÖ?Î^ôÐ#ÃùÛÓ#¸ý™1\wÓT.^xÜ¢ÁÃ/ÊTU-zó±-ô¶‰jm…=²y3jÇTOO™b²Y„=ȵ€ž‡D!Êßxä‰ãøó}ïçK_I3mz©D­¶¡¼ùØ)›xþÉc˜13Žó$²ÄË7àt=©½*Éêå›ç¼ôJ®¹³£ÌÏò»ãÅØX(\GO<rÊcÄ-GÓE¾}"=Ò»3Kâ„“†,¢™³2X× T°|¹Ï/Z6Ï8øºE;¶wäÓiÓóöÉ?}”ËïôãX‰rƒAdO ‡“ˆm­eZ7åž.k%„ìÁ2´ïõ´µå ûì7èg¿û݆¯/_^!ÊÄÎÓ¸s2Ž>n¾åÍÏúQx䈎ÖQ$¤ Ëf>~ºáñ»ÈvV’öÇaã$¢·±žSO­eû–"o,.7Ó0¥”–­ :,#ÎgÊÌ€[ï8šÃŽÐ$¬% ‡c#“¦öpÎg~|ñð¾1´mìºá¡»»\·¦äí’oC+tôÇßÓó^›ŠSIøÀý÷._øÑSàÇßW\Mq8™XN×®êk^ág7Îaòœ$eÕ­ªUš>ÁŒý°*MìÜÛ¯å3_ дáiEì²h]ÍcÃÃVrò©‚—(¡M%>dxìÁ|øô2•5=Œ¡öÙgâÊ •üé–úàð£f°}ko®¾Þëqé“l2fËsO¯ß‚Š@Å œŸßÞüܺÞîî?ÄQ ±¬5’ tÏö;r‡=Vè㆟­jÅóÊîÀý-ýòrÊi)žx´´û ¾@eD$Ïi§&yôïYž|´ŒVƒH/6ÚÂé'b Á>ûa}AQK\VLš%\ýƒZ*Ò/cÍV [B«AÜò»ˆå9ëœ÷È}¯ÏÈõäç<÷D~nkÇž2œË!ˆ `@ü ˜@xݰ »=\xÅ,üê¥Ï/üÔù«ˆì";F)[O\ŠU²b›9±R«ºnòJ{ÃHúA†Î>ˆ‘MM×Ïž<´åÄS3(Ó…HÄYÇ䆗šGŒIrÒimàç(‡ƒx≠#ÇÔrÊGAÈ£%!¦´h ¬X‘ç…§{ú=ß@ë–έaH?úËW,*ijªØüú›K/@ àR¸Èãù'—Þ2u u‰"$Žû—$ú¤´žÛ¼¹gë°iÀ¯nÞzùš•b¼²³’sôCKþ>ü±,£FWñøChÆôð‘3}‡—xöi…Ö$ À”‰mÜôëÙ-S¦ø-SÏ=§%uø±híéÄ Ë˜ÑƒÈƒ‹"BW@¢¡|í¢n®þÊó~~åcóèG!oçµµG¿*ö8 @¢2 ª •L¢34ôÔí Äm_È~ÿÇõ óë"Y:§BRZ…)]jå"«rµ1H¬ F( ÚˆMiª2!&F$°€G\ÄsÕrÏÓ³[ÆÛV½¨¸†ÑÃߘ7|HŠ‘£·bu:jÄ—Ÿüäˆ~­…1Uüöö<¡D}G6 Zd’íäò=[úïþn ö½xwô?_(„nìèÌsžÖÏz´*¡D°¶´Þóø]w7yÊűrÖ²3v_Œ€ç¬R¶½½¸©"Q'³÷þ}@\ײE*ññ䣺Žþ‰Qˆ#fâÄ;ņÝÔ[‡µY&L†6Vòô#uh=Qez9ö˜&2C“ÄèJ(ÀàüŠÎ')þnùP–°TB©Z~ý§"÷ܾrÿ€t-ÔÕA}c°ëª TUUB'“xÕÕx€ù¯° Læðƒï>­Åª6è2•úÁû»Í}w¯ÓAb˜ª9îý ‚@‘LUcTŽ ""‘èFS…’ ¦¾yØ0ËØÑ†rXɰaƒ`Ìøv4„¶oÃHÕƒò¶Ñ‘ÑÜugÌËOY¾<7àÐ#Fóðß7ì˜:-Ý7ú}'û•Ëë€b·’ö,DâûÚŠÈ3"‚Ö €[†lèJáº"eSq¹¬lßyi{ÂZœvØšªôêî\Úzüû‡ }Üü«Í þ|K†Xk¡DJ‹ÒNÄ nWHȘq![6E¤ŒµŽqã-C†wóÔ£Z'Q.Â÷óø¥ b(-Œ<úLæÖ»–óØÓ ¬ ÆWQ±ž›n\Ã?bÖœôISÇ%£Q£aôè€úú„\…®’^ÊâÁ@ ÿõp ”b‚1êÈD2q¤—TŸ¦M›¢Ë{c z uú̳v˜…—nÔ¹ü( ãTo2‰ò A`1’ÀOTqÖ¹Óñ´‡àñÜÓ>÷?>¹eâ¤'9”«¡Oï.§ë7ŽX$b‰­è Ömê±Ëл½Ï4/›÷Æë]óŽ<ºfÑèq•ìhÝöbe‚Ìžýû ì+¿»"Î+‰ã”³V[ß×O9çÐZ£”Â@ÐŽ ;M\(„qÙ©ÈÚ8.[ìžlhsv—˜±sQôÔS«žž6}¤ì·Oõ·èã‚æç¯¸å+ôQCgA '%œó±lÝ:ãú—^è \‚—Ècü-Lš Ã5?’@üŒÚÀ9gLPÊëƒòÉ^ÂD@ÑÖ³à»oðè#¶l¸í/›Ù±6Û (@ Ò#‡ž_ÛT}þäÙÕ'^tñÐé§œ–ÜÐ8šÝòÕפӪðPÆ&öÅD ü½-áÿ/)Á"¬¶V/—ÊÇeù }”ëÕ“VêåËŠºÖé¶ö•_ˆ½Jâ²B·¢l´Òüù÷KÄÙ¡,~Î9û­æqã 茧)öözó©g¤@)P`¼ 6àòù^›Ëé°XŠÂrYE¶ŒÝ±µ6*Yæóa䬲ÇÜÍœÂÜÕ éã…ßðÅ×¶‹RIIŠ“ëÀ:2=|øŒ€i3ÞlÎõT¡h]`„áM•<óœ‡Ñc¸û/ëÐDiD+¬­Ö¾¹­9[Ä÷¿ý‹¯Ãêaô§êˆ¹w>zꋳOþâáGUo¬ C† •àígÒSU,••+`\oàªé÷Æ7!BQ{œÄTGW¬®øòß…¡jk׆/X<('…he Úw8— ßSÉÅ­¤Xα~óþ-PB”%Ž…;nw¬Út`‹ Jhm0&¨2PFk¡³³Š-}æìgÑK¾<~Ñ÷~<Ñc{XòjG~î\ÝÉô•_@ÇH6»§üfwE_ù5‘ra¨].gœÖî·qo‘_‹È@×ÕE\.Ã(•ã= 0ê“/.•â¨XŠË½½åÐÚxÇË/ç³ã'Z¹åϰßìÊ…m;–\A[68ÉöTIl=‰'Ö–‰ãΖ°l— klù·?홦süD– S6ÓÕ^dþÙëÈuňW‰qb!lzðõf€”áâ ~ôý7éÎô7nìg¼!ƒB‚€ÌÎ2 !— w·a¶o¥³3”öÞžrYd¯õ_/ è ÆÌ\õÙ/—¸æçÓEÛõBÝË_ùœ~àV(8Á%(Dy ±aËVžÎ’zx-EA$ÅŒ¦e͇™Æª(J;”ŽØƒÃº4ãÇ/›wê‡FÐ|á\Ž;ªaÑo~?wÑ¥—UÒÔ´ŽU«6Q,l_¼§éÌÛäBèìëø J¢HIkçyÊ¥R[U•°ÌZ-"W±çóDaH9Ž)c ÈZÂ]¿Ã\X. Ke¶ÿúÆ×ÞÚ²Y1vâ2žz~7ÜrÈÂÙû§¯œ8Š«~ÑrðwÏøèH÷Ò ¡8—g3X«Pø­âupÀÁƒyê‡ñ|Àb]H2åñçV7?þBW3€x¼8$)E²<ÀãG´¤U/Yæ¢Ëf2ç>PžîëÄC‚uHß²4:ZÙ-_k+²SDÉåpå2vgìmïy|˜®R**Í:È|ëÆß¦½äkrÔÑrí÷gÚ/_¶üšMÛʨç6:u¢S%k˜õþÓÔKw_Deª«‹àY €s>ÙÞ!|û§©–ÑãshE„Re>($EW—âÆ__4nÂ&NHrÊ©,R¾BT½XI£â:ŒÞ¸G¾`O¹¥¾åTbŒr¾Z—â°Gl]Ýfwÿýý a”û¢8Àöý°+Öô¬ïìòöÙç8ï|â£Óð¤AJa—8×-/¿h]1_«S9qJ©ØÅ(¥AR Y&NMq÷ßòd»ª©®Kb8☩œ||[ËÝt5˜=®eüñG²Þ3˜ŠK_`ÚìÊ–d˜Åéó.ߟé!Žº¸ãþ£vž§ò:í+Vÿ²xø³C„¹:”\Ùݙٶ]ÙÏåóØÞ^,`ˆú®pï‰lÑ•UŠ»ç(Ùï %âç<[iû Ø‡O?wÉÌ«z_{ÉV˜ØQ°²öÙ—©×ÄÊ5oÍ/K„H9r=•áØ?(ª^;üéç\pÿßDs¸ñ£èu@q„H8„Wžª#êMr×=Žˆ2HXKäª([8ͦõ€¦¦$˜Z´¥ FŠx’Æ£4 }úÓoÂ„êjdÐ åêëË63"okj|—É ð3 í'`Èõ]‹@¹ÿÿœ]ò• ˆ|‡²H€W'bíwÉÄ)=°q}ˆT¢¼…§Ðf0ay wÞ]ù žzÙ»¡ ë)%þ˜‰ÈÇN&÷Èä^ž ÷¾Þ»÷x™±ïJñ‚¼Ò~JÙ¨W š—‰S*yxÝ&µúégtð…’u–ªiGw°ôÉ®ù?ºvÝõ¦Žá‡×>Gd’Dõõüð§íŒI9û¼áœp’!“Ô” ¸ç‰2m.òd3” ¸À'"„‚°½5¢«#»@ßÌÇe $“PQ¡Äó´ },¡sÛ7»'†üãÙýÊp À뻆ý3 ÀÒ¥¹ ­;*‡6 ‰‰u _IØ.b]!‘ ’²2n˶÷]ó»7zç_åÜX~wGÌ7.~a>}6¹¢åÉåùæ?ÿ•¯½Éã·g›ÜAû‘õ`ð1Ç^u9ã'UQ‘†°”B+CJ$Yúf>þÍôáz"씆;I–ã0€Ðѧ5¶ªŠ¸·—ž„¼>Ë4ãmT¾ÁÙzâh0­Ñ‚Ÿ^³‰kAª«ÄZPV”5’$!£'OñCÊÉ9òFõ‘ë‡N™pým÷oaÁž"–ºVµ7çž_Ѭid]6Ãw¾”oßÒN»ÅS8öÈ‘î&6ظ„Q!9ò„ÊUÁ¶VC2UܲG¾€LÝž¼Gz'šÆ!Hí0í2ÚU[ãFŽÄq+Bÿlì‹õ{QgÕÊžõm#ˆlÆÓàJhW%ª\–”›”t*t‡Ù(=¤Á›!?þÙ¶Ýò Ÿ0âzúØ%ÀgßÛ|Å5«›Æ}rKêÀ#°6AJkÚVo hJ­±Å¥Ò„Q7ßÒIÂŽ¶oe·îhª  2õ¨¯‡Aƒ ¡Fjj~â9@Þ+Ç4xhÎÁñ+úê™§[xàœDâ°~Yßs—¯>öáÕ—×4Nûaå1S=÷ýKMY{&°IÕ°=‡þí/ØqÛ=lÚÒ:ŸŒ5¼¥˜mz¹ôSG¶o¡2ã}Ÿ0PÄ6˱‡Ö3qT/ÚïÀj‡Ïðú«¦`eÕ¿ÍÝ7èÀlœ % Àó”(¥˜¨\ŽË¹\\\Wê)7Bxå•ÿTyQ{™8JÄÍo>àœ£Žœ9þ¤^D­@ÊÒ%ÃÔýnׯ·ÆFx)§<É{^jH¥þܼÇ>G?†î;¦EÙ­¯/o¾ß˜–Ñø œ}&[kj08†d{ÙòéÏPµa;¦ª‡¯|µ£íź*ÊqßÇÇOz¦™T×W^qäûSÿ6jxl+°VIooèvìÐÑ–-a¹»»Xêê¢ÔÚÚ/¾G¶góúËןW_éäÀzQU²xñù ãÕ³r½\H(?夥½É¾àª÷iR‰CÏh‰tޤK“æEü×ß`Ó#÷“Ž Ô<~vÍý¬ÝZj(Ç7€Oq¢‹>9ׯåú_­"´QþÛß©Ú-}ï{žÇÛ8€DúÚ©¼và–.Eøç~Â)€½ekiÿÃ-/çïù›Í|£ó`f0‡¯_ÃÃw>ΪÖâeÿ§¤pàŧ^ïæž¨âgH²Ô¢(?ü"Þ¤ItVgHZE¯‰Arذ̛+·6¼õ-‡:¡ñË–v°7åý×þö—hoDÞVM^x(?Š÷ÞAiÔñX•$ÙÛö_Ïæ'–6ÓÇßnÝÆ´‰ûñ¾£R”h/ ?UWTW˜M#ݶ)ã½pH]är`ºQZ‹.«„ ÃÈÄ Àö½’AX–ìjpÏÅ96²Ã’©j:ÛŒúÕ/;Õ7ÉW¾9µå£çÎé¤c†fÂcž™édB]'AæÏè[!Ô]Då;Ð=¡x¶¿ÿä=xX¡DV¶ÿÑÆä:»Ó\tÞ[¼ò¼¨!C&|'òœ—.'=£»Íƶ-_\¿fÝ熪òõîÅç)ù‚:ýx›ãŸLmwÂßogÍ/ÿH2ŽÀ‡7U™0W$¡cÌkýËß"Jc}±³çÐ4kvT¼E¡ØJ¡w µ¢òƒ†eº7nëkø® Éï¼ÿÅñžèîV®·7ïZ[{]cãÎ&ÝQ·ÓÇè}÷¿Ò ®bôäF¶-yLÞ|ÿB)¯Ï~¼Ê߯ӟZ®nIŸx4ñè¼ïnª¶®æ¾O^Ö\=nZKÊã]¹ú;K›_[¶L9>¨ÝoÚbÂnCú†ìY½Õ³#T]]Jç;Ê&ç0¼ÏŠK9€Áƒ®lkÛ¾‚©&^&cJ®[m^ÒÙ\;ª©Å©ˆ„Ibü˜X!LlÃS¤³ ÒâHiÖnZ:½0yzíÉ3ö¯\— Þ)¿Õ)¤¯ˆ±{ åröôøe‘¨¸ukOo½÷Ÿ!aE:sB¾»÷Ý‚ã‡MûAETö|/òJU9óÖŠŽÏñ‡üŸ$©?éˆ}Ò…òÈ`††ŒÜ55H† !«W#«V…²m[h³Y¢R‰p@#Ú¾Ç2 ("Ð'?ºnÆU眧u©ØãáÒ¦}G½¹ã¯=æéç·êÇnÿ€¬gé›á|úèÚ°©`ظI-ùPÑÔsíwOäÕ_lbÌkS[ð舳¼â·óìˆÊE›•%V%6o|k@ÈI‹z‹]´¶}Ù/H@2©Hô•c+¬;WTR,[,:ìš~þpb×”oŸô˜+'©J571NO(õªµ'Ý•N–ÏZ&mGv_Í/žžÏ»0rTªeã†b3}þÁ‘-‡RÇN«%UÙKÄf¸÷Þ›o\ÍÚWÞ9m4ÊG„Ź:ƒ=•ÁÚ¾BYèÈ…ä¢ÝBºRéÝÛ/ï)µb”Àg>;fá4Qi½E ÅÊ.,w©¡µÝê‚ <õÓ§ñཹŸŸù‰‘jñ‹ëyãUwýw¾÷ú|úQr­èd#)ϲå¹2•/M !L‘(§ˆUÇ„SxŸžÀÖdÌãågù3oP2®½º~кm}*IÀ’:…¢µqa¬­Íå]å¬ïãá?‰b±¸lРAóÛÛÛ[.:cá‡ä<†v[•)[œ®²ÉI"*IÏSVRÇ&dæ¬!׿ñÚŽ½JxÚG¦2c¿¨eß¹n½½‡}h•y¬Û€¯ žçãpÚ‡Rœúáý¹ìŠM-ÝŸ%¿a]3=½„~HŽ ©‘BÂ0¤Ð½ûÞÅùЖËÄ@4`þWÞ‹úFéC,މMÕ ¯¿n4εK9….ŠgÎéñ ZêÔíiU|¶(ŠõêÀƒSì?w#GϽþ3Ÿyñm T‚ÛÁñ‡Îåµ_oçÀh&¹(I1ˆHH•E–ZYÆŽÉñýùÇ-ºô›Î ³mP;š€0%Þy߉Bt¬Äº²PŠ,øÖ9ÜæÍ ÿ‰pÓÏ>±pûͲ6Íв'KFJ‰ S’(Nç¯÷?͈}†ñ;ޏùù¢ƒuLão•æcžÄooiåSÖàyM„q‘„_€¸ßV`U…ßœÂ+Ï=H$Ú°eFfž†pÏ\p„9®.ˆrHbµ&‚¾0ÿû^Û#Ú ­ûÀ.¸U(¶c‚œˆ—”Îü·è–¤[tS;û¬mîž?m“5KFcÃJÑNüVŽ;©ÈŸšÔBZ)†Ô„L2¤¡¡[14줦`±q=¸–€Mz5SÎt4Ò@E²âÅL™\°;‚Ýä œƒ(§$—Û5ðP®£¤\.×cwÊçá?y|X“¿p¿Ãr¼ï3–õéÈ¥¶“Ö"žŠ$›Œ¤—„h;Nüh˜œ|ÒtrÁ§f.:ñ¨I¶c"-°r©æšo½1¯ù¼mÜr³âÆ_ûtuÁ1G'Æ®'É›œóÑá;;‘¶…`Ïœxßࣼ§üæúžOŸ€{Ë€î=—•2‡‹X>ñ‰q ÏùL7Ú9”WÍ“UȯÙÎ=÷-¿‚|ëo^÷ÇÛ÷Q±]M„ ZÙÿÀ7݆i){[9ô€ñ4+ñŠî¢7ÝC²\“]ö ôÞdÛ aÖY :¾u+|Æ rÕàôðu™Äh)'9 A$¹!B´ÕV…ÊvæÌoþ'R(–UÖ³#Jå‡ìsf]~×ÞôœÔmK©C˜!ãJc\ìW»µ•;\6µY͘V+Λrý ‹–ͧýfV ífpCMåûW¾Àc­œ·3øéåpôñ}Þ(>(ĆÎúXÀ›¯]tçíÛæunï™;ñÀʧ Ð:|{\”B”Âí ÀöoÁ¼çöˆ6^rŠgê¸à³ãðd<2ŽÓNÎrî™oì”oÓú1x¸÷ÃA#‚·¶—xð2_ v³ïÌVm]×<´*Éé§6Ò81`ÿot°æýã–ÄíüeÈÝ´}áIÎ\qÙÝENúØ*œâ?ë)dLúÁQ!Œ 3ý" 1› ±PB µvJ]Îäþ%òõ§c»ºí{ßÚœObøÄEëYôz%__;†Ž¯më†Ý.?¯þ¬9ñQ9äb¡©i§œ’aæ”êëécŸéø^O Æ0ˆîÙÎË/uÌc/<òÀªyçžñü¼ùtóÆkuøœuî(vìˆ~±eKqÌÈ‘0jT@]]ðö' É$¤Ó{D„~ñÐC•ñ“y>ræä……¬áÌS6Ó|þJ^{+âîûŸc m[â¯Nžt0Šáê'?|‘ë~PD›ñx^ L€±Ó+Z9²‘éc»Èx8ìÔ-œþ¾öÂv¾ô`Çž¡*:°jŽ4¿ÿ…åo–Ò5” Cà cÂjÙ»%$Ãp¥ex"!5©”«SÊ£m­®ý—ʇÒöo\qËM7v䕪„!½NΜ·Q~´Ø“ï-M¸|?'sNÙâŒ×)S'9ü°ôAÒ«Èy[k¿×Ë¿úòÛòqè1‹¾ñõ¯-ºtgœþñ³ÑÇC¯÷ñÓŸ÷åæmÄå&Nùø´EmfßÊJgë ±† 4  BÕÖ¦T&ƒ‚~ñ^;ªËSS˜á¹ï8:{J\xáƒpì1æó_º„Y³f-d/<ýÈã_:þýÿlõÊœºëá„éU|áK3Q&+kßÊ7Oÿrýõø“Ç9§|Ó…Ñ1Qì¡mŒÈÚÛöaþ…/®»âÅ3«wÕƒ£¤T’" €j±¤+ü¤mCñ“e••ëééú—g@çhûÜü%·ü↚#î¹÷°©Cê·H••u[DáIʈ³^Ik Q¯š;u°Dª€@¦ò£k–Èu¿[ÓpÈoû·o|éâO^ÿãk~;Ÿ<øô)×-,~²‡Í{˜6k/½ÜÁcoZ³}Kï–Ñã3oær  >h¬¬¤®œ¡>WITDI!€r"¤X“ȳ®½¢+ÞQÌGÛ:lyKï¶ÒŽ„«W÷ëoý˜1«nÌɧ4MÛÿ€áæõŽÉSïà÷¥ôò7+ô‚¯¿¤žXÜ9Ÿ|ðÄý[®»îf¾qÙ¥më6~k¿lë54à×דH$Rɪª ðýDŨQïûÈM7ݱð­·^º~úôý ÈÉÚçúÕ«–æ¤\Y|C[úèÇ*ßðo 1C¨ `h}@c&A=Ò6)‰l@Йؙ vÝ:o‹ÆE6¶fÃr×]áŽÑOàÇ{}øáèW^æêŠTeÊOÌM¦ó™™³Çë?üeÙçÀGO9¼å'?]Ä‚+/m+gŸ½³l\˜Í†•uP_™ ärðÒKnèâÅ;?zôõDÜyÿaTViFº«¹apâòãÞ?øÎTÊÚ|^Iwwèr¹(ÚÖ†ù¶b)Š(oßÞ¯ó_$ I¨àÜÚL<âÏcÆÌaœsÚVÞx­õ{ŸíÍöDÎòL?Ñ͈øÆ¨¬¬HTW;¯žŸLfÌúõᔟþì×ÇLõ©Ó–žý‰ÔòíÛE ²Ù¾}or»îÄqBa=À„1]CÇ{Üœ<°5•b}¿ÖÅq•ºª¤£#A.¼½¡d\PR,†’ C×#‘-Æq%ã¨ìÛ0ÖR.Ù|IB)U”¢’¿½"ì[Znû­zy¯!}7ÛÚÚuVýƑýCÆŽË\Ct »ýÖ»Ü>ûæŸË…¡+ÚP }KÌr9è|{«Ý…BB¬­v±Zׯ'žô¡ÛG6<õÕ7;Ê‹_ÊÇƇº9nž7Ööv—¿³|U~x…R.ƒÖQéÀR™òÕ`‚©ƒñÿå›iåMôuâ㵆ó?; çJWðìÓ=q{gù6÷/!€™9¿®?=Øî¼:Ïóšdðl±µ&j6lÙ 7ÜØzâI' ýÀñÇþ RK"€ñã'vćo‚d˜H±ÖÕÖ¹Z— ƒ·ßgòy%ù<ÒÓ³«¢ã¶6wtxao”;ò®TWÊ‹”º¢¨Ôí¢r>ÙöVmŽß»ò ”°±ÛÛ»9ºø«ñKµu‰O¬]“»˜>|/ßpÓ÷Œ¦;ÛÚ¢¸³3²»žE>ìz6{äƒ|~—|I'’±¾_yžWÖZ—NúÀIO ª~{Úi/~Y{*Vº7þÌgÆÄÛ·fZ»¶8Âå ¨­ LÝð¤×Ðöë&áÏ™3àȆÿäl”6ï+S ¤Ý$y\ó£ï=µæ¥ç¶z{K³Ëe³¡*‘ : ¾ïL…IøaA¹N“—Dž Èâ Ä;â‡ü âCTdeþ¼—̪w :FÖU$ÒC—ñ=Š.”+•Œ¢š¨\®ˆ|_Ež7$Þ‰]÷Òâ`‡‹ç†å¸xâ‰'¾P[[«Ëå²2dˆŸN§½½½‰l6ì,IÞöíÛu{¶(—sÆD¶²RGét9ª­õÂÁÚ‹Õ Nk ¶PÀMºç#£~âýwEj§ˆê‰'ª*—£Ô¸q…§N%ÁlÛVé÷öZ?ŸOÙ¬õ­ A *•ÔÔÔ¸í|¦¡ïûåRe©œ]›ŠÅ¢}bÈáÖ[a§áÉÛo;³ää7ô£²ÂûøÁï«¡¾^tÆ¥RÚærQÜÑ–ÛÚráöí„›7pÿ_{WÓÚÆ†ß™™Õ®ÖqTIýu1±Aà€/%Лôrõ½§üŽöOøZJýiMèQWåÔÒPC±Uä(ÑÇj>ûŒ½tÁÁDIÝš¦~áÑè4Bïóì¼³ÏìÌþã+!fN_%‚>#K¿]±EQ4$‹ª»«äæ¦O8'fˆùÅB;ï¥~ùr¦'“±évs;›97£84ð€X¾g±í÷ûa{{›Ê²ä1 TN”²ê↓1Ü-<·ËS°‘-V(=¨³dgr÷ïÇÑîÒúå¡*ˈitØÎ±gψP2n¾Â¶Š•‚Yë™”DŠ¥œgœ :‡QϹ,3‰Ö&ŸçðBOÝÑÑQ}†œ—Dß1âOùŸ© HÎ8g5‘“êNÊ…az¹\i­§ÚÚ3½ùñž8ÿ9;;óZ·ìt ŸsmDd”÷&ö µCÐâ«P÷ûžGMx}jì ¡cçŒ_x£1W//Îó3 ü}þˆ«oЖKx§®¡WÖ ‚±‘Óù<°’‡8×”‘s"JÞÆ_N®Û8­úJ‘TJH§®r 2B¬tY6Œ”sŒ|ë‹d4±,˯’§Óé) Ìýd2q˜#|ýÌ’ÿy@o„œ…ROJ9á½MÓTg>3hÝááá:Õ!DL§DPHÓUPJžû‰ó¹aÑâ991¬,-,°‹½#7ã«ÖâK;@'ïÐ'[½ìÞÇùÇýGEçà µùè1å˜ç*:¨®”·^žê  ±¿¿ßìõzív\ÿ ¼ú]0º ˆŠ‹fÌQ^QÑÜÝÝ?ýwÉo  G#—à4r»µ•Ýë€ëÈyÅ}Z„7#À  MMú°(¨‹[½môûÔ€o$ßݸ¬KüÞÞžª[yéߢæCi…Ú8þ}Fa½d‘S8DŽ›à:r^qã,€»@ ØpåQºîÖë ±Æ­øþ­<Õƒ@Åi³â¸Uq^j]þ £†Æ7ÕdgôIEND®B`‚qtscriptgenerator-src-0.2.0/examples/images/checker.png000066400000000000000000000242201170724227300232600ustar00rootroot00000000000000‰PNG  IHDRÈÈš†^¬}PLTEJB”BB”{k”{s”9{Bk{9sJk„RB”ZB”cB”sZ”skŒ9k)Jk9cs1Zk1ck9ck9k9ksBBŒB„BJŒ9kBk„JBŒB„9kRBŒZBŒ!BkZkŒcJ”cRŒkJ”kR”)BŒsc”9sssŒ)Rk1BŒ!9kckŒRkŒ!BŒ9BŒBŒkZ”kcŒkkŒZJ”JJŒ1RkBŒBc{9B”ksŒ!Jk9„9sRJŒ!9sBc„9JŒ1J„B„ss”JkŒ9„!B„1R{ZJŒ9{ZRŒ1JŒ1Rs)B{)B„9{)Js!Bs9Zs9Z„1B„sk”9s9c{1B”9k{9{9„1ZsBRŒ!9{)9„ZcŒ1R„9R„)RscR”cZŒ9Z{!9„JRŒkk”1J{)J„ccŒ9RŒ1Z{RZŒBcŒJcŒ!B{9c„BZŒ)J{JZŒ)BsRRŒ1cskc”ZZŒcZ”-„iÎtRNS@æØf&ÁIDATx^Å}ec$·Öæ Š©™™ÁÌæ03_Æ—a~ûPUw'ûY‘cϸݞèÑaЩÿbcÕpUª°J )åDk=‘Årjµr5_ïì½Ü.^Mk°Î…ÒZ+iVüÿ¬]£e 廒©Z«D6òqêÕÒGý8*^^†b·Nc¹Vð1ç7LµÏ@F–Œ‡«­‡ž7„”])E>^?Çq¥×q [RÊÆä¸D¥øºù‡?—‘솱үE%}Tí[’"_¹Zi8S½ÖCØl‹p´€Û^‰`t&¼ár2Œ¦JëqÉx†G ÄC¤‰N”ÆÄ%Jmn-é§Ä6HŒh h’è!¶l¥H™t:ÿù2šÄ:Á÷\|Ü©np“ýRGãK±C…ˆôÕC¥ÕqµBG´iÛÒêýîEu¥˜ÂN†¢õmvÑÜ ¢‰Ò1²“ ¾/Ž ‰^ÿ³ë[‚§ÕP'H‘È×@’6‘«ZNS+@¼Õùù9ÞP°•lp.ÏVÄÞB€¬ t"ºH›Æ ¶<?™"™PB €§HΗ]9GDu™¬|HÊ #´ÚV€àfnd#VZMe˜(tæÕx­>€í‡”‘D&¸Í'§ð$ ¼5hÁo0´Jð«Ï:÷S€äZÍ ¶ì²Ö!&ÿ²–¯¦hˆDd‹´XëOuÜ—wzÍÍŠ„>Ö$C.«ÜþW€Î%5±±$#²Å"ó~I©Ÿñ„¼€sÏ5ØpcåÑGÄL³a“|GCH|6^‚lö°ÃÓk ÙhÄx¦ OY—ªíZÈ)Y9!å¿¡uY† « ¿d-x1¥~„@zD¬xùúÄýãXÒ\y½RÂŽqOÙ"1Qž)â~ä+4Ø'Õ¬ÖU;šä)‰o'ŠÐ÷A¢´_8H¨ê= k–Ý-I¼HòTQ$@ê:œã›}ÆÆ=üp!¤ ‹X 6DDD˜}k–½ÿޱjs Ë|Çí\iM\%E¢IÉâ[Ý%-xâyÕ¬Rw†lHÈeËЄÙÔ †rõX'³aƉJ ÏkX ¬šƒJÍ jû§}’üçz•üÜ~ÿˆ\.8@HŒ×šëuÉöàb‡]¨üð‡ %ùL/CIª˜é‘¼!¤âÚ¨Š×3Ò µ wSµÄwÝ1ž#Ù <÷}ÿ¹Bf9 VGÖŠáeßÕ’‚8k2ú»8Ð ­ñ·déAx•k±Ð@Vg=¯>…÷\« ``xÆæ‡âì/À(éÊù€ÙX¿•k¼]¶rYGÂØ‚<K² [tËèÝÞ«.ËñWˆC øq?«–û5ïLÈVˆ|¶~Ð*ŒÃ‘(F^àïeÔwö€ g ÄWÛU#¾Í† -º³ÒŠtÉ ôPšØÁ#g §á†p çNmÕDQéj‹PEÈW’wCÊŠ–‚é`(nú ‘Œváïîç%6µ`ôU²d­‡еР—@}õ(·¨µ›[n¬¤ž5„hᛸû‰”óšÏ{“Ýî;Z¯„ï¢! ±µE»ö²ñ)•ÉøùQmu&¥ÒÉNVX!ér•ßÊp(jGš¬Mú’0bAr¶VWYÅEh!.@Éo(µ¾Å4.e;9Ó~Ž“€@â[ EÏižÅäsuüÞï{‚(…Ö/VJÜlÉQã÷7Æ3}%'ŠÂ@?í·o7éoþ7pVÜÈ+ (ë=9ܖ2|%£ßJ !åS.Ôi¥.€2IÐØÖíh-50œÕ X-7;!wd±|:Þ)@È9KžÅ×C9и:ü­gÀu¡ †×\QMb­íPd=‘Ì[Xèõ Pl€JÎP•® ‚À Øp Òèâ¦g7RPÈz21ZQa¸½¯–|"M¢-ÉÈ:jIÜH´F‚©w~¯r»Ý6ŽÉŽI8¨Æ)5^GORIúl±XœaVÞT ò…aDNKQ*ž†â…óÉ?jŠ.PeŠÉ5Àó¶CNTÝÃw(#‚-H$ƒ}¢,ø¯Hdœ».‡•Tlè‘m©“טXÒ¥bÎ×àÙº = *ÞÃøuÔ½Ù¸O~§CÓÏЕbëåñâ x½Z3ëû?ë‚"MúÕñèÌ ”óP¯ÝT+÷רH§”ºTܱPÎC¦´cx‹>›&‚wQÉ–Èååõi©;½ ”yôQqÒEàŒ™SJzºL¨Â™ìÛ¹#Dé_“a‘çúnýý(è>š@në¸qV¿né6ûlgi«°@hg ìÕgì–oF)2euÿS=ø¿;oõ©Â÷+”yvy)Ô­ b°ÿyw.c,}/;@à˜8¤…°£l:K´þNý<:ÈX]…ò¦hÏ,5躛;æ±6 râv8c,ŠÚ‡T,ï,õ42³|@~Ð 5V¨®6\Fäýå~È¡"C"a9¦,49"¡h;ä`á—¦ˆÕR ôš=ú&jPÉ-â0¸qÏÛOÑr>…ð+â2tWý•z!£’3bZyM%^[¬E&B`G¢ZŠÆ\—öý>¸éú«ÓkþNkmº1ç@šÓ¢\µ«ò`{3×ÂA¨×mk@ZÃôœ˜³(é@…Þ<5úäŠ "‰eK ¦H…(‚i­Sqg3aöûÖ€°}8˜. Ãö+Ü4ÀUŸQm}zUdS»D¶ŒY¡²³K@I¡ Jj‘µEC´LéSÑßÓVåÚÁJß`ç2e¿ælãI/ì”BéJ1ÍT4ÕIud åXUöÛ”G™Y~äd‚æ„h2aËxdÞĸ]ã¤$f—°ÅÔžÖ"½%äÔ°¶zë äqX_ûüx‚ÿ&׾ݧÌuÎZ£>…“$GÔÔø¿@Ðl1-@rŠ•Jî€p™Ç¬¯u‚o^ [JE11¯0ãEwœdWüñ­-Š ÈÝÆ¢áZžq Í:‚dh†ê·ù×ÒZ/‡—9Ñ­zMNY!NÞ·72 ¨ÕäÜ$¾,uÐÉ`k_Õ%Õ5uþ?E¨òQÚkÍŽÔ®¢¥®˜&Æn‘\æ&J2_¢]±§µZ‘æÖQW\ÀïsfÝÅb¹ƒk#lI4µ0ž}ȹܬ ±8¾Bb%æžRÙÞœ)*|²=ĺƼ¥µtåÏs¥‚Rñ0šM‰„”Ú[¸Ø"ôG·#n¤·GV€Të i-Aûd7jndi–ãP¦ûzh2§ˆd6#?íôy)íä#w’¤å‰Y"Ŷo±É 3=¡ /kN·êugO±~ó“Ò ÃT-s-íŽ ‹»¶qN€„ƒ×¹l̇RüÞŠ ÎÆ|¢k.$AõñuÇåD¨{"d,¡¶‰ ±gô&¯ö.„ׯ^﹘ç7R Rïlm¬é7HšQɉߓRN©!ëx ëµÆhë‚PªWw=!¥É‹·K úXWk; |Ït4- û¹ˆHçræ[N¼ÞÄt¿‘!±x¢(Rù« w7œâÚ:ýÊÂ;ú‡w†Éd= Ñs,ub7ŒõHHX©íSbM¡²\ΠЖøÄ9 ! Wm@S±ŠóÔßöï”J¬Y¤l%è"²tC!Gå¢CYÍÑÌG “ÆnoõЯdÝ6M¿ñ]ß3ˆé¤5`Ä]جS@6ªËaû€k:$*“xddZ™Ü€g:ËŽ|Õô‹Ñ¯ ØÊ¢ Ñ_Ä-;E ÷œÓq¢×ë”Ø5™%ý-ãí‚*°6¡”™—¦^úU„Fç…¥6ëk::éaÈZ²·"l‘¹Æ]få”Ö­i˜ër³I•-‘×èµBZö,9òš#‘b{C’-•Ùè.¯fKT¡Íú’jQkßîµ¢WFÔô˜¬ç²eÌe#¸Œvµx–œÆ'u­ÌÕ[ϴθq!+\ŽÖz©îO…[¢B±R`þ´E“OX)ct,Ù<ÈÒý"Bü^=çÒ'3«'£ˆ`ø÷EìVŸOà¡NôeHÍ^t÷Q©ÏþÃ’Óhn~ÄYó7÷õ7:ùªk4ìIæj94š¬; ÌO¼²> U ×ËùeŒ•§vf‹@*5çRM"Ѽô©šµ½u¦Iµ±.–ÿŠ»'2ðª¿Ñøk€ bÆ®ÏØÞÔfp.0'4¢õ˜ý“ö^ åÿ²jãr. †±;…ÖRš½.+´”Bªh+@íäµ'&”l HurGÑøÇdi®Šr¢øm2êýÊ>$"D´{Õt7>QQdiRM¥rÂYBÜçLCÐ\VÚøzÊÉÕ.7@˜X`zd)«°º¦p¥!IH…*´Ø‰}”ë=çÚCsDÑÉîØnKZG‚¯àšÐêd¯…ªŒ€c¬Ê/viŠ…š —j‰ñ˜5 E.nó;ôá`¦“x'k×ôí¯žëÄØizÏ”{0C "ÄÍÈ¢”afËóµ*mÐ±Š´Ž¾ Ì´ƒ1@©xoÉ9º1-’Ž…~Ýá ¯Ï:k x×dÕSÜ`:eumyâYF—ÒµÒÌØÜÄ<×$6ÀLçw¬ …äæ´“z1 Ìk%¹"X>'"AÞŠ= åH­‹V`@r|ðS”ú9Ý~32«…:\~çCDÑìÑu‘anCÛ÷|iÀB] «]™bd¼æk¶Þ^Åu.eÑ.r‡q\Ô.vû„ø^ÿ¾H²ÛŸ‡ñÀ¡—ù(,ƒ«W¤Ì±ñ"˜Ž3Ü8χË6cÎû eÜìχ“R|\=X©¡HuÇǸ:<|3ß®jÿæÃi·¨½V­Ï‡g¸S$[F; fˆ]ø_Ð|(rÕ(ûáB³ûÿAOvU-ÕßÐL&{tµ>. D¯½É‰@„dšHyâ¾ã<€¿„lTk¶¸Yp>¸ÂžéÀ³lχ“-”è‘ò4—‘S.Œ ôˆ””'Ÿ‘s1kÈ/óPÇ‘k.Ìhœ÷ÚPö±W1.µVquXaް‰ˆy­¼›R†hnY¹Ã†É#ð*¹ trmiÍéØx³Þ*VÛZ1_œ_¹\\o~̦•ïmÛÙåêr({í]£ÅÍöI©P¹ŒÁæ|8b¡]ÖŒ…e…£¬h÷âR­Ñ½ÙnÈ›XáÁÏ>"À£4ͨŒ3ºñ0J¾2ºbÕYœÇ5żX%”r0nh>ÜD6šxi2!Ò¢4ž–L3Ûš†“þÜ]ÙÞl,á- 'c–rX|HÇ[9_¾ìÝ<ÕI<sÝ! Gë#¶.kEm3AÑ´¿1FùâŃÒI´‡vµóÅ÷›,ÛÐ4ØDéØ#/­£07¬u©(¶,T¢(Á u¶H·£Û²A”Ú+æo›ØNïe÷~ÇýÆqœó÷Éîùy¢yˆå²ÏGéQ°xÀüìY;ODÍYÚýWçx¥ã 7Âõöç Ü¢³Ä3M!S‹ÒS¡ÞX{÷Ã/ëXë$¼žP‰¼ž4£ëpîNK,µË¾óÁ¥Ô²Åùp¹Êú´×š³ûg€tbjNZ®ºÏÃ%ø¶Mï±óøŒ¯9™~8¼ž¢ÇÓåÆÄê|8ÊèQK[åÞ´N$.šægïã|¸%ìÿx|Å3É"ÊÔPyÏ õ™ÁùpU»yok{+³ Ä´šÀº>6cJ¾IkΞGxž™žÚ"kysI¨Õ{¤q)?ÒÚÒ¶d³7ŒÀU*Ö¨‡l)ŒÊû ¥ƒ®‰ª§ó Å-<á)IÌ 8ûH*¶ô÷ñ/g˜˜t¥i>ˆMg*Mó*rš U ÷»•çœKÀ¤¤ôö€”-ytðÿÞÜɘ«- ÐßEz(ÕÝ:ƒ ht‹âZû®O•Yꇖf¾Iž•¶$Eã{( .yl-`(Ô ù·ÿŒìhª|ÉVè²3ƒ93©·K×Ðä’¾Mn:òˆoûÌo8 Ù~ÛŠG £{ÿ6 RÓhxáæFâË(™Pæ™o ͯàS›võýN÷sõñ~­*¸BÈUû¾«ÇC̲´ïùböwÁÆ©Œ§(ýi·ÅêÌÙ笶½áôûÄä;k¼p'> 4ÕË'QÛأFfÄ—þ{r¨ãád¹6Ljï홑¾5 v+vóáp¿Ëü~P¿ÒÑjNŽ]ða¸{$Y“'’‘ì‰ cÀ¯ðåRžK.¯ŠÛΖ€ô9hØŸ”qëÒÃÄc¶,þzü2×ÇÀVL×䣗)šôŠm¦ZGB|é—ÊŸ=YõÎ&_uÜ:#YR®˜»ûóá(^ZNÞîÓ$(Ÿ¦v µiGäë[U3Ã,û@p5,[§¶1eñLà½ùòÕËNÇ·;®RÞu©—Ì9׌ĸ”¦‡/Ž)“ÿ¶œ§Âjw"Z"D­£ Få¨N<ß”B ûóáª3έ—\dý7»V³† )ùDZìˆG§½ÿ¾ÖǤ©LçdÃÕ¥øÕæÃe%’Þ8R\GVÑL'lÃh.€ÓzeãÜ ¦Nߦ)íbÂÉ Óc~µùpt‘*CJ‘äóát݇è&æ,çôDó0k²Ùù'È ëõ¯:îŠA©xªˆRþ ZDÜÏä N{äý½…½_·+œ+¤âTˆ_o>ÜXàFP¾â•³á‰ç›$6¢¡«ð¬Ò_áV÷`ëüjóá\Ô§!¹¾”$¹¾ÛM…ò¹;_FJy¿œgV™þxëY³ì‡ŽQ­†=Á¬t‹eDx>#!¾"瑯à?+·!t _8µ_Ȇ®¡r¥`MI8”5M`•ŒüÙà+¸¿œÇžoÙ¼ï×,I‹AÔ7Sâ¶óáj/õšßZ@|ëý|yÉmšÐýƒRz @ìχcÞÁ2MH®Cç`>\m…®!åå°èý–Iõî¯ »“5œš:é·?®Ï#œiDj¢ ‡VÂÙŸKéèz"z¿œGç’ÑÈêX?üÜ*´oþÄ̯ÖÓ@6¶ÝûÄ[Â9˜W{Fü¶Ž‡342ñï1Žez5(Ù¹íÛÇ„éàac6±GóŽu²G#C¤â.å‹{·˜œr¹Ê€î¿eÊŽnÕê|8Zι¢¸‚íCJ··ô»çú€y L v™ü’s¾ãzVË×îõ \æçV€°¤EœSP¤QR‡[!±õp//—KÇäáStŒ˜b¦uÐR?ä8¼®V¦t¢C;@xƒŽ³XГ±(Dâ ;ã ¼JNÍ”‚2f¼1ŒÍ(jvŸ<™e² ±¸%=ǃŃ`°Á±4C‘µj=¦4$áAÀ âò#±^óájŽD¼q¢âhº¤g¡'3Ì»>¥Tãùp ys+@¸ õs…`@C|ø#®xžh¶'~Ý̇k"^€27Æå©… bn&›P®Ž^1ÚZ(›âšÄš-¹šröý£>­¦1Ù?ý_Wž‡óáZ|§[ÎÇä’Å<ÛÈ8Åøä™$ œ6¶$ź:œ!],ÅùiÊÔjytJ@7IRÀÚ͇ëå7R§x½›Ûºü7ò|ÄèÁL5¿j HÊs™%é ¸!z½òû²˜b¾™1ØùpRôX„¨ð>Ov—k×ñÖñú_ÿ  °!¦Ú&Eú4Öb»À›Aúâ½À’ÏgI=(Éš¶o¦xu¹­°LJMscˆÑ¢¦÷ûD`ôsâ×2^ƒ;kbm +6 k>_%Z‚ؤ!oør A‘à>" kö- ކôŒÙ¬ë ¦VÝÇGv,{½lú6ŸóPÑ”[ÉÔl.“p¸$}\ÌY"»!‚[é.ó¹èDÁ¡ØuÜùêN ù¤fmÐ]O|k—è©xç7îI$#çù@6ðv4ü[ïÑ ñÛv?¥ÉX'ö =ä#öØ',½¿<¦¨{T=¡Jëd¥Ç®¼fKÐ+ù´1ÉÁ±àòÖŒ L§ÊK­ ¨bˆJâùd;eß–bé’ ¿‡ †-ìrB}è¸ÍÑ…!]*ÍmŽCóšÀˆ¢<ÔSk×"A¶xñ#v‘¡Í8ùqå¢ìª°+.U¢g‹'B¾kÖâ–à€œÄBâsêx«Ÿ¸–Eýn®“«’ÍV@A\|Ñ9Q×R`ái›»Î*AwiàÔRö´Âôb#"qe hæ'ZŸ¸ #ï¢±ïØ¬X5ÏnØÌÅèn˜½iúÃ<«sâôo9]µ lJZ¿pÅ:7&O·)aœ¬ÿþðïZèÄ_ ›Y,á=æ!c]ª‰ MÏb­’û¼es‘s–hºþÇv?býŠ÷ ‘‰œ÷ÙÍÖÛðØ ¬šlfhÖ¦|™Ñ}÷5í›ÄÛêÌXD)ƒ$‰Dƒè#æëðæÜ̇ó£À°0ÜŒcfõÙéM’“œã\ ÇsßFHz hÞªÿIAà3J”*žœ÷êMé³h= Ûw ू)¥S«©U |{½wóˆŸdI3†xV ñKÙ“'"Šçá „h$ulz›ÜÏ¥È ™UL¹fkÛ‚í±üä[ Ÿ“´½„vðàŒ»M˜ÿ•^Ï%µxóá2ïiH¡£z÷,E•e7ezއ ¤ …«Æ¸†‚—˜. $O´kxàÄïb[§w8pÞŠr­fÄ2EøÞKÀŠW»÷)6 @ «’¹â‘7ˆÂ$²Ôo?¢=;΋­Çy»ýùpéßò9w$[©e žìʈ('uÎ:¦¦¨Óå{$’o‡ëñS ÉjžgÊn23k\L¼‡ÌŸm B â}¿¨Ôl¸ÄÎŒìÄK9<”\75ì½Q°¢S€jc[ÿÑ6EZs®ŸüµBúáHò[Ëõ1ÃðiQßá“@ÌSl¹XƒºL­Ã…xÒ¼Š’hž/Žñ'V¼Z";4V{Ï÷åÏ”š g˸‹¬uýœè8±9{Œ©êÃyÔ²¤´9¡vÑ·h£ƒ6¾:Ï\[NÂá…®ÿ@¥²7nw£ViÎÁoØb- ¹¿ç²8ïˆç©U¸y€±hur€{jú$H¤MÑ#[º’˜ vÉ"–œ…û4ç»?Î5ÜxªŒ÷ø(MÓ¬²»D’`m“î"¬ôßß³$­¾œcÓX÷§êáʸ}3¸‘òå~kè(QwÊ ŠæÃõ·!͇ …˜juîÙj—ý«”3äzX›åùpT´"ÃØ½Ã^çS–ÝP>2óáôT|  Ld'ÓXêÈχ;Í)Qt#¦dÀâ³×Þ«ìwÖÝ©›2^òåÅ@4ð3–B¾ßéXBO%¤ùpâŒ#%QçÅÖ=‰ºm”Œ@•[¦L¾ ‚-Z”f zO>µ—ÂPçÃ=,æ ;{ˆ Y¾„êgÏY<Êú‡8ŒÔ<¦l¤ø¡„Êy“eV€ˆ¡˜¢Mªò3 šæÃÅ”Š8)$¤è7)0˜ß-®^o›¤¬ùZRDf,gn'ŽXë‹p(dþLKåùÙ|¸Mn1º:% ™ÅÛÓ ¬ÍŽDuØP3‚áëg&ðí6á9œW+g† ¹ð¨Õ %ª£®O¿Ùk)éƒï2:Ï*¡r-÷‘·ãN1àvfFKJÇ]>ù?æŒÂÒp.qÑØ­;ž Ùôr?<œ—²¢xKæó%ÒÔ&шør\UcšT‡Çô| @iüTv¿]POÀÝöz|8cv~Pà [>²„’¥œPøerRÏÕh“Џ„Ð1 ä.¹üŒÅR׋ùp¼2ÄÑ2iWËxÍ-¶2   çÙ“×Ç®ûŽÓ{ ¤¡‡X¢}r´˜xÌwK{óáp½¤¤'%2p'íÁÞï±"ˆEð¸éˆ¾Ãs§ñ(9Jî†hˆÁŒ•öÃN}o>œ;ÖÔ$œÛýÌb…§hp‰“êjJaê”ÿž? °nZ ˆkj”×ü%étJä™<ïŒ5¬+¢”A͎а¥©ÅÛ ãÙSkÏñJ±T áäÁ[Ä×»sL3â5Â~ýðý³o‡Ú\qÐËw2 W*v¯¸òê™,œHx;Ë&QѵHk¡GxšßBŒ1sȉ‰0~½îso‘vý @²-Ý%ÄÉ* Á´,C!Äõ ¼ÃÂɪm2«¦‹I(Mâ!gzió>G†>’c/Ûbu>Üw ÀD!Ž !ĺû°‘c ™22ÿû)ˆóÞʃµj~y¬Ù ÓåšœË0 ‡ÊÝw¢Ëijw>ÜX%Š«n(ìºàâÓJÔµsqÖóöü¬û+uAÉùi43@n_‘h}‘·–—¹[Íî|¸Žf5¤ôPœS"”yE]ÎçSTSÑ)Ã0«Âmš‰Bï8x‡ý&eóÎ~äç%ÜOÇî|¸ºNâ)÷+]?A®$Û”9±£‡ôPßÀA/=6j†Äy§¸÷Ô9c-—Œ–çé°!ÅÏwÏxiù¡VÄkS}¢#$à³p“ ÆOŒQm9•ƒœåùp—Âôf)õu! O×Z£ô'ÜñË ê'ÁÙúðáxÜ쾈Ó‚Ô,χûÕ¤0Æ vûÝÆ(Ë7\<øå„¿.&δÖ×y/TxoÈÿß%—“rsêtIEND®B`‚qtscriptgenerator-src-0.2.0/examples/images/cheese.png000066400000000000000000000222651170724227300231170ustar00rootroot00000000000000‰PNG  IHDR^^%°49$|IDATx^…¼ë®kIr&ß‘k‘ûrN:U]Õ=]Ëš1àwðKòËŒÇþ£‘_€XOã~€Áca¦¥¾TUWÕ¹Õ9{o’keF¸:“L,,’Û± "™Ì•—ȸ^¸‘üG"ÒÞ£Býõc‘ Ѧp‰ðã`V(á€"<".'@°Dn3{éÝŒà8!+ˆˆ»GE]JÐ?n²”âî$Ô†E”¶½€ôݪDˆºh°MBˆ„Ôm@¼~¥©Ë8É€èø÷ÿSÇKkœpäm•Þ߀¨]ŽÄˆ(î"pr:sCŸà¸×öHÇ3‰år‹UB°†!´á«!¥ã4£d O0„:$ä¸bDx}±.V÷€ EÂ2"hKzY⨣wöþÁF5Ú> *â}˜{@$à—ð+:].A²é+†Dëi+®w‹>¾ï“¢”zòFÐFh ÅÛœ„jDD‘z±.A‘0 €6—÷ õeVx9hðN;Å‹*ƒû®U¢õ÷ô¾¼ƒè Û$â'p‰ö©³^GèñR<:pHð8@@ƒÔC‡ÂÝÃK#ÀÊXŒ¨uFq-Qp #g.¢¨P·åõþX÷¦•†ðÕÌ­ \^·N¢‹~ŠD£ÂÑU-&6ä´™I–RrÎÑ "—™$@)^¢ÎM Àp¯§¶åJ–ŽšÕÁbqùõ©MÎô‹?’ ²|6ÀÚ„8'ÉÆå™býðMŽtA#סMÛì´Û‘4RŠï÷»Çù0¹»&†a»mPXR A ° faŲî¾ä|TèbmÅÃ@Ž^A$wå¶ž«Ñ£»KYœ“‰œ‹³3DÝ=g÷6‰÷©ª]B‘ô𵔩p³öûýÃÇÇ?<|útxÚA<¥ÔKƒnïn>{õùý‹ÏégM&AG°mb ÑùöªºÃWZ#çL4©§~ÊQݰ‹g@V°¦VH;-¥”yÎ¥Фš}Ÿ¥”#šâ„Í%jOŸÞ½{÷þÝ›ý~‰‚®ªj,9úp˜þùå‹×ÛÍíäˆð…ü€‰YCÛACÿRvÖÉÃ$:)¡vèBº·óSÑ@‚µ-‚¶y¾’;doWš, Ñ’áb»§=ìŸ>Æ> w÷2ŽÃmë~f†GÀxÝ3‰©ìß|ûÍÃÃC™g8æ97&0S£•B™X²|x÷>¢übüEÈb*ɹwqÆÖ¢b«i¸…IÖ ¢,/¢YéÚ• _õœ+Ú>r!S)²À³øaÊSΞKþø‡Ýúþ3C>ÿâþOÿü«¯¿¾ª@¸O"ô¦¥ažŸ>¼ßïŸæyvw OjB4*#•\.çeλÝζ#@ ?îÊ‹±=eëMwœ]óo¯ˆ•Žß> MrLsþðáÃÛÞÿî·xxœw»ùî>íwöði/¿Lžóìš,D‚hT-áóþñÓ‡·îN6‰€R›Ö[è¾J:͇§Ç‡›{¥¶í‰Xº½qfÚP¤‹º«$sn.®-ðœÜí"@ðã‡Ãï~ýæ»ï~xüô0Žã‹›q»M•Ëd»¹›Jžöû&Ú$è8n€—œ÷»8ìÄÃØl6¤±YLª À]=2 „ÀK>ìóá)m†å®l¹Q]õ¬«gÍŸ¾Ò§Øq#HÝ\–<šðó¼‡/o†_¼þúööæýû÷S.žó<‡‹A‚$É8—èì©*Ó~:ìžÒü¬dVBHªDIê‘”¢†Jø~÷0÷Pí&›-hAclºݿPàr ÎÑ.NÐ;£ó¯›ÞÙn¶Ó.Ó_þÕë¿üo^öùÍ?}zœëaó\nSw/EB(*ëËÝçy&ÔT•¦'šª6‰¬JT‰\­Š"JÞ‡Ošn›MFÒ:×D…kÎAÃ€î ž“Ûnеgï¾ðΚ$¬o%æ9?=¾!½äÝ>|Îïß=|ûÍ&“ùîå/^½z•l8ä¹”€(á‘©FPÄˤ”èT¢²²‚ª9YÙÊ¥!…ÂΠрº^Ä Z)¯\ÞÍ’b§aÅË<==„»aâöv³ÙnmܤaC2‡ÖH¯HÐ]"NÐ Xž¼÷÷Æó!ŽK*ÓÞ³ÛoM¿QE’ˆl|+2‹¤|*ù});â hñ„‡‰øÅ‚„æG!B¶ ã ýÓÓû·?þôîÇÇŸ>äý^)»}Fâ¸ÝÞ½zùÙç_Þ~ö4‰l²‡¨(M·G•K1Ð8QI;örÀ em—óHPíSö˜v1aä°Ñ4ª¦ƾf—].^ájHA"x T6ÓÜ.^KYº»¡V$"XJIÌß}øÃ·ß|xóv:ìɱ÷É̲ßï§wå0ͯs~õÅkr.E BaxˆÂEtuók—õ:\Æ–JCÕ}^Æ(sÕ{™>W^3ßDLnATªÝOš{´e,".‘q»½zÏJ¯¦uÅÇÿðÝïÿöíûÈ!!‡r´ 1ÈF©€pyzxT¼”/>¿á"@t!S´ëÄ+qŒ5Ê΀{Ÿ$¾]ݬR‘2€'ŸGÃ¥d1’¢"𬠖/{†]¢g#á…”˜w?|ó»§5Éò,¡´aàNÉÅMåVªÄœ÷w/w¦•ðºõSö­yÎË€,;¯ù_耽· ÷Y޹[Àµ”Ûc ˜1¤¡‚{N¹öÓVaMçwÅp•(ÓáÓ»wû½0 pÒ͸ÕdóTDÅÌ!ÕjŠÙ]|ú7ŸÞÿ,xTGW±ŠÈš¥Öçï[º]] ¾žlUMU¸”{`PZQ‡‹‹@¡R@©¡[}êî‡Äñi÷îí÷û\‚jj$I 77j€&Ér.N•a¤ÇüøðÓÝÝ]Jƒ:€6™Ëõè2p®¡ž:—‰+qö¦i¥„ÓAQÕ443¢#á`ˆ8å w‚.kÎîJ©(EKŽDب⇷O:?¥@‰°êá@‹3B%Õ‡¨&£•Ùóá‰øððpÿbû‰‘‹=JXŒ‚šiÓ£5„¢<“*'€†Ã]ÄrG‡,B¨áÑi=Â;É´ÊJŸÚò ½ئ°¡Åh3ZÝG·µ*W†C ®­ðB ‚¦Î²ˆ¨ASKiÖ) KÖB zöB\5Arxw‚ÆÌlG¢GHÙÄD)Êê’»ˆCT" zÎJzJëÙÀ~oÄ’¤C3A—šÁVê`azj“•¢˜rcQhR´U0\Šq #i¨…+‹Z¸(•Œ¿7í&n5ÿ‚¢$ûÙ*ºô£FëC ¬ðÒÛX´ŸO‡µ1äe{XkFëxZg΀ª£š ©ÄÀF)¨û  62QEŠÍ0$7+nR²…„ ª€dH÷S9P¨Ù,ä#ûPÕ;óF_õj›¯zUâ\4…ΰٯüòx .:*jV  ÏHTCÀU‚”ª¥hfP PÕ!ÑLÉbr2F°d–Há–K¶´U,"NÞ9—ª°ÞgëñR»u\•Bða¥I⫝̸GsñÙ¢ Àů¥dˆ7UÒp'¶‘) KL# Í¥ã&1™§DEŽ€«eWóik›{µ‹G¯ ÛBÍî$ë*QNûf8z.  \Ò­-—­ÂÅtXŸáyëÁ:Ž×££(¤¸·òÐ67÷ãÍç“ HQód: –F fƹN'hP*÷ãx/6x M-#JÊ* IPñUñ¥½÷<áMx´€FÏ@ë¢ü©aA‚–”<7N⪺ˆ#w¿b7ÅEeU'ò›ÿýbŠa@Dõ=BÙßxÑßÿ:ç¬áÉ„ZtšÃH}%C)Øåx"©™!Ežnÿ‡ÁßËôbñàD²¥’O5´~Ò [MI âyj%F@p÷gHf}ŠàyôçÚS½´¢]`irBŽÉy€7M•ãý‹üð“—Ù6‘¬ˆLFÒà>0ß«¾P2f Ÿ©¾¾»Óy·÷<) Áâ…$¯ž >cŽ ÒÉæy9Ú9îZõz™G½¦žJDÕP%1'2£8]\YÀ¸½ÿ+ðwóôp6½ôFÉ{ÞµØë$ò$rÐa‹á—Â?ÿ!Ïï¥L‰ÚüU_i㎠êE?ƒ<å£\ î~MXõ¬ÐºúÊ¥–v¶ÀßýÃ¥:‡ÆÝ\– 4³OÒ¿¦($$¿Ÿçï%>™byØ ªÖÁ ›¯„_çiôÇÿèyO„¼¦ªQä@aËä,ª!7D:ñóHä@D^Y(F®Ep.b0¹b%†”%qýœ½üëöÅê]Ð MY·Û,wŸýS!_`ó¥Ú½ÃÜLDZ`‹4Êø’ã—´¯…÷’wóÓ·‘ß+)Jªª0.„uÅè§^lûÄM$®Ç´Ö°t,û…—d3ŠH Ê±:Ÿ(oÿ‹öÒ/‡GÅÉ )Hûy”¾†¯%Ý Eþ{‰Iô ò8Í?æý÷2¿‘ò)é˦I3*P¢Ì(šQ×–ÅIÜ’ÖvåTµHoôm?_[¸2÷¯hú „¨I‡]õ'ZÅ 4L*‚^f“˜ËîÓô_°ÿ—Û›Wƒ½ô’$ý_¥Ìᇈ'Ï»˜'Šv?FÀt°a†xÁ)øqQ¹¤c@ËQ^ŒxN*_w©.¤ù“‰—(SÎûˆP­ùîëm’ZñáMi‘˜¼eÜê˜#Ï®ŠNãƒ02Ù†¼ÈÎ)³è Ì„˜æCŒê¥Peé%D(–cQ^uàJËöª"}¥”eçó¾Õuµ?ì1ƒA@"óP+av2C£óÔ‚uËÏà‘×Ù"¤>^‚½Ÿ’§ ·÷µÔpV¿åµÍöqµ«s}¿2â×X^÷9—T=ijŽF›\‚^F|®ZÄ€°Å-ùÒú$‰ ÇFÔru /À§b„¸,àG½ÿ*§\—>‹è¾ŠööUÔ\ŠaÑI ï¯í(¬Ží½E¨¶¨X¯¡ꫜSGD\#~½W%ˆ<7`qå8ygkóÇ®<¨ÐŸFìi±ooï§;)Šî ËòªÙ‹ —áh¥Ì ˃A´OP_Í:»”¥éµ,gŽÒ4]6²MÄ›>NÔƒ’+Ò]ѶjZ1ÀãiOç÷R†i7aúõâT¹sdû(¾¤jth¨<.];@¤Í¼$±ãB$!zº?ñ6Áå’ê•Ò7qft;"¬ ]Ç£û^H(NVÜO§ŸÊ×QÈv+— Ýý|ÃçRy…©3[†}¹EvxÍ’ö¬»”EÚ¾£Âߎ^mÏð~?’Ðpm=!È«AÁó3@íæYŽ%Veÿÿ­ŽÉ"`\‹lèß×2Çk1g½ŒÞ¬ ¥b ,m瞎zVxY̹8­(ÀRî¶…b©"ôr¹sÚ/Ö¹_üÕ]_î4ÀEj°kÚŒ…tŒ~…î*1›Y ™Wó(ùðôð¸|šóž”›»—Û»W"WÎ9Ì,©xL@Pd8Å4±ÄÂ2Cñ^ø¾dL¨tˆrÍ·ìÅšXЕ¨ê*²í¤Ø"®ç¼ÏÕv©)IiêaFB¿ýæ·ïü°ÛíÆÁ4)íí篿úâË_7[ íLú&QÜ'N­…<<¾÷ïb!^—šK¸J*E¬Ë'âºÜYFW>Úê"¾!x!w!)áN£‹$À§Ç¿ûýÛ¿ÏsVCÚ¨ª{‰"¶·÷„Ö Œz4ê1·{m$ÙÞ_°Ÿa—eçQ-_‹2æú1Ú‡ ׿tS‹ç† Nvî¡]õháH ‚AˆòððÓÇ·ß#Ê‹»¦[ #døþéãn·»ÙÞõâ— .ˆ•ŠY Ýs‡uLpi˜9EV’q…„@[—ˆqyŸª•­ä ¤2Ôµ¸üSðv4U„Cɪi÷dûÛ»d[`«š`‘˾”œT÷ûýϨ!)Î…U.®ˆ ‹ž…Í\f¦ŠÄQ9a¡ƒE€s÷’Œ¶pi!ºÞ¿ÚÆÊ/±‹¿ k‰Ý6x}ÏíÜCa¿¸Ùl#mL7#L‡Ì9è$ ÞsµWày¹éhZ0Ýšõú’åˆb0dDœ0¤Ò²c„x§ o{³¥ÓuiC'«ÿØç¥¸QëãÉ…”HiôÍֱ݌wÎä6`¶á^rL–ªÀ'D%êR }é+=gÂwy×Ç:ÓÅÊ]èÆ¢+3Aéøj¹>OÉöœ1Öw³X•ªæâ¨Æi}?7iØØ¸‰*Qf‡87£ªæ,ÝÜ8Ýâ( yÒ@m¾Òw)DSlqÊpI ²Éû/ªde@õÿöØ]¢µ´m YúŒçCs7ºÝIP„ô9<;†›—¶ÏŸ±éi4’%@ †›¯KÙ»RNñpE˜°4“ðôC²"(Ç2Ñ® «¤mì . ’s6KlKñ© ‚`‹a{x´Ê&&’-ÀÔôF9ér =ÕîÐÈÙW%púwÿî¯{l强Xý¨ÛAÂ]ÜÅLÎQhÊÁTÔBMÓh›ÛªS戬! G‡@_×ëœ<hçšèEÚȹ ¢ëÒeš!s‚˜B‘ÝgÉ“DVŠG&%JÎs&DÍDdÎÅÈ¥}ÔøÍi[¹ÐM-YFö®{AÀ¨Ñï´Ùr{óoŠïŠï KÔ-¹‘òü­{Ž2»PéG#€`ÿµXç‚£€ Ö–ž%Š„ÑHͳÏÓn0Ýn 1==ýôþáa¿{œçYZ^ü(FB\œ¦–9¤DR‹rØoøîñÓO?~œ¦IDxr»4™™ÝÝÝ¿|õúÅË×ø…Z%˜£Þ<Þ¸î¢eg«ÐÔÙûÚôêf¸€¬O÷rØ¿#©|/D=s¸`C”\š¥d/é¸VvúŠæÚì§Ùg,AÊo~øþ¿?<>åœ+êÑøª‰)Â=—ÇOŸæÃa¿ßù‹_mî^ÌynûЦv4¦%d­õïþ皢[@ÄÒ^ˆµe ïd¥!¯µp¸”/”lc&ÉÊÏdëqJU5K]Öœ¼ðþߪN/¢P”á%)§ýÃß}óÝïóðñCdñìeŠ<•<•’¢¤Í1T¥Gž÷‡9Ï)éf»uA@(Z7ãúB(ŽÐ±qüíeë:÷r†š"ÒkY›Ê‹v ä¬ÊD$øš›ÙFE{{øX¹p_lK =@'Á@»'-%+QþðÝo¿ûýo÷ŸÆ”ö“ç⥺çPªMC$`U’Ç Ô¤%ç@ÜÜlDG@+vØrúMàŒ¡*\q½ÖÙ?îQPÅ]NåÊ÷BP*µfê Š¸…xó)Oå &`›­ý~Hÿ8ç©UüPUÃ矶·oþž7ãpØDÔŒ€’Ê&= ÍŒáSΞ’{”i:Ló~>ë«<ú÷ÿËÿx´!Ä—¬‚¾r  Œ"@ñFÕ…”S,À6'…uæã#< •ˆÒæWíY ˆö¸’dˆ?E6ñxúôö›ßí>F”9Pm  : ƒm6šªÖšæd„’ˆÆÉTE¢H™7›a µÚV2©¦¹¢Ñ\Ð܈ê^žk¨U{•èë4µ,àqŘöEÔŽš»Ñg[‘1Gr ©£aíÚ==vû¾"©4*Mª¨ ¨Í2+ôþÓãȥ̇ýáÑlCMîâ0z1ja×2-ç…«ÊÊÞÙ@äR]…óô`Kï7öì³ :yEй À`ä”wŸò´‡Ä–R¢QŽvI ²3lˆƒB¤jÎÝÓÇÍx»¶q4&ÑW_]Ë »{ÛVOc®œ©yåâx«¢¨ˆ^€EÀW^ËU·ÆÉSFSf/ù0µ‚ˆ$K¦BBa‰$â„·±”9¢€‘Ôœ§]ɸCÜF1É+ ð¼Ìâù´Uq‚åaž±›£Ôé%„­¸ï|@´6+@¼L‡Rò˜Uµa43%i43SURTUµíf2’±õÕ!^•|å25© ˆsâ0T8WÞ$c!wV¸è⣓pÙq÷ :ÂŒ+Éœý¢yRêRÛLFÁ`SQUBšÆ&QEH©øH´K$SÎ"$!’Ôõ€qœê d…#yùçk~1:!¼Yµx¬wN€„ÁÐy»ûM˰@x‰@'â¨ö¤ŠªÂlÇP QÕ&³ª.Q¨BU5BU)pgÖ…}O%‰#x(W’Øž/O^UVFªË‹ãyš—¨r­ø££¸NÜ£”Þ¹ÀKœ"ûˆ†A›ÁÃk#†)ÍY†a,®4K)¹„{£Y6£Y¯]äÃë ²DÏg¸/‹ásy¡U@d—a§ÃI‡Ý¶ÚÐf4܋ϚÆ(e1س‚ŽˆP­H‰ðæªËc™M§»ƒ¦…Á xµ³†{Ú“¤[Ï9Êcl3ÜBäÍfÜäÈCRwI£ä1 Šm~bžÇÙgºsL»áöeÖa°À43CÓ°‹ÃÈêRÿlòýõEQ< Äþ0SM(Ò~ÚSˆª6j@˜œWÖ!Z»ÇâôÒ$Díäji4`çýÐI^»Ý;qÐ7":«Ã†Q…aZ‰ecƒbÜè˜N‚¢š¨I¤â›éàqw÷—œ x"& ÂD ân„@ÿ·ÿõoÖwƒÄ©”¹µDÓÃ4W oÍN"žBâ4‰nԬź—ÊóäJÚ}®"ë\¬­hŸštSòÞ‹KlÕœ6)FÄŒ’™r™ŒãÆ`.â. ŒŠ(åf²›»»ÿöèžéCÈSKŽ @~FÍß8/ûóÓ{”ßüó¯û›yûæ)6›mÄÑ¢ fç YñÂ^ü€«!!¸°¥bÛÞ"zpKÂQ˜>“lsÞ»†”ÀPÓªÃ5Ù`†d € Ð`‰Öj›M "ü7ÿj³¹óØyÉ€‹Oqô’×Jcí(ôFIªüî·¿ý—ú'wOIcÿ°ù·w7·›ñZ6«òŵ§ß¥{‰« Ñ©Sà­±HR¢$‚•ÁgÅ^Ó«ÍMžó­wsk2g”æyªHªjî$\´&px0¹onïÿUÁ1G¤hRr­‹gÐBoÉÌKÑðOïßÝo7ö'_ýÅŸ|}3r¿ß£‚»Kz{ ÀÚƒo¯dDØûN {žÄE„bÅ?2ùöö«´}=‡ÏÁ­éЦeÀ"Pè(ºAÚ(b‚m(g Å^ ·_Ù0‡’+§ÎW%rW}¨!” ‡ôÙ«Û _¾¸¹¹½Ì¾Ùœø($jƒk’‘“ÙR-@Ï? @Ak÷¢&xû Tö ? ‡„n°Eð„ñ~só+„ùü@øE2Ù^Rd¦$¹ÙHÙ…Šbkö¯™~Uò›’w ôÎÔLtÒÚ%.Ó*¶²/:d/ òÅ/^ü /^Ül7*ܺ½ôÈ?ØLÈȹÉ¿VÅD²ûb¨í¦Ú¼—\öÝ:Ÿ4¶“ì¡>n^¼Ÿö¿!Þ7#×T¨khH±”½jUŠAEÓKÁ—‚ÓáÿìÐG‰>Íõ :c‰ÀßýCTXeðYÂz§LãH³”ÇÏU;u„÷þÎbwÎû—&é_€K¦Šâ{å_ vŸvoî‹ÿQ£E0‹Œa¤I&ìEïÂRÖ1¥ÿN ö»ÿ[lK·à?j³ú¸â)‹¬Î‰Þp‘ÈóAäpp÷„µr;\ûÉqkà¬öué¯] ÷Ùñnñ8•'îï†ñõý‹?—ßÐLd@! Üïï_™¼D Ä«Ä_Ê”çÃ?óà'Ò±­q®@L‚Yÿ+v&‹RªoX¼ “F\-mw÷óèú³ õËþzd]Å;ì}¶ÈX’iž?ìæ½~JŸýôO¤0Ïs¼1Ýšþب~“ä/¤¸ø·1ÿó~÷&¦·séh=Rs@¯V‡¿ýÇöù¬¶ôËl*ˆªD—Æáu€÷c^Öýíã¥ôsÉ™0q´8Î\¦’jù´¹ùìvóÊ/jÌeÙˆDBæßÊüχÃã|DÍàðˆc°AQlGŽó+n+ê]!ˆäÊêô<šwíΟÇày\ñúàîßvölŽh¾q•û½Íš~M{¡”M)Aaž4œ2„Hò2@÷+ÓT®€-¦±¨%èáD’ªIØÿ§'Vw{†ßx¤¶%º¬!y^gßö€ å€â$Å#{À9Û$ïJ™^Ä'P(Tâ§ò8âWsì?V&ˆnÒQ¬°S°ÎwøÿÖ}ãÑ_3¨IEND®B`‚qtscriptgenerator-src-0.2.0/examples/images/qt-logo.png000066400000000000000000000007411170724227300232400ustar00rootroot00000000000000‰PNG  IHDRPP|?ïžPLTE£ÂŠ¡ ?Gp‚p.UIDATx^í–Mrƒ0 …áÆíb›PO@ûŸ©­AóF‘¨–]4ZÅšçO¶I÷çö²qßG_E[ÍßVáwÝÐdMºüªË°¼x:_IU ËUžk~²ÉÖݲ²ÙV-,.P#5°<ö}« ©ZsŒ„¶Kd Qt Resources Trolltech Partners Training Partners Consultants and System Integrators Technology Partners Value Added Resellers (VARs) Community Resources QtForum.org The Independent Qt Tutorial French PROG.Qt German Qt Forum Korean Qt Community Site Russian Qt Forum Digitalfanatics: The QT 4 Resource Center QtQuestions Qt Quarterly Trolltech's home page Qt 4.0 documentation Frequently Asked Questions Online Dictionaries Dictionary.com Merriam-Webster Online Cambridge Dictionaries Online OneLook Dictionary Search The New English-German Dictionary TU Chemnitz German-English Dictionary Trésor de la Langue Française informatisé Dictionnaire de l'Académie Française Dictionnaire des synonymes qtscriptgenerator-src-0.2.0/generator/000077500000000000000000000000001170724227300200515ustar00rootroot00000000000000qtscriptgenerator-src-0.2.0/generator/abstractmetabuilder.cpp000066400000000000000000002724571170724227300246170ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "abstractmetabuilder.h" #include "reporthandler.h" #include "ast.h" #include "binder.h" #include "control.h" #include "default_visitor.h" #include "dumptree.h" #include "lexer.h" #include "parser.h" #include "tokens.h" #include #include #include #include #include #include static QString strip_template_args(const QString &name) { int pos = name.indexOf('<'); return pos < 0 ? name : name.left(pos); } static QHash *operator_names; QString rename_operator(const QString &oper) { QString op = oper.trimmed(); if (!operator_names) { operator_names = new QHash; operator_names->insert("+", "add"); operator_names->insert("-", "subtract"); operator_names->insert("*", "multiply"); operator_names->insert("/", "divide"); operator_names->insert("%", "modulo"); operator_names->insert("&", "and"); operator_names->insert("|", "or"); operator_names->insert("^", "xor"); operator_names->insert("~", "negate"); operator_names->insert("<<", "shift_left"); operator_names->insert(">>", "shift_right"); // assigments operator_names->insert("=", "assign"); operator_names->insert("+=", "add_assign"); operator_names->insert("-=", "subtract_assign"); operator_names->insert("*=", "multiply_assign"); operator_names->insert("/=", "divide_assign"); operator_names->insert("%=", "modulo_assign"); operator_names->insert("&=", "and_assign"); operator_names->insert("|=", "or_assign"); operator_names->insert("^=", "xor_assign"); operator_names->insert("<<=", "shift_left_assign"); operator_names->insert(">>=", "shift_right_assign"); // Logical operator_names->insert("&&", "logical_and"); operator_names->insert("||", "logical_or"); operator_names->insert("!", "not"); // incr/decr operator_names->insert("++", "increment"); operator_names->insert("--", "decrement"); // compare operator_names->insert("<", "less"); operator_names->insert(">", "greater"); operator_names->insert("<=", "less_or_equal"); operator_names->insert(">=", "greater_or_equal"); operator_names->insert("!=", "not_equal"); operator_names->insert("==", "equal"); // other operator_names->insert("[]", "subscript"); operator_names->insert("->", "pointer"); } if (!operator_names->contains(op)) { TypeDatabase *tb = TypeDatabase::instance(); TypeParser::Info typeInfo = TypeParser::parse(op); QString cast_to_name = typeInfo.qualified_name.join("::"); TypeEntry *te = tb->findType(cast_to_name); if ((te && te->codeGeneration() == TypeEntry::GenerateNothing) || tb->isClassRejected(cast_to_name)) { return QString(); } else if (te) { return "operator_cast_" + typeInfo.qualified_name.join("_"); } else { ReportHandler::warning(QString("unknown operator '%1'").arg(op)); return "operator " + op; } } return "operator_" + operator_names->value(op); } AbstractMetaBuilder::AbstractMetaBuilder() : m_current_class(0) { } void AbstractMetaBuilder::checkFunctionModifications() { TypeDatabase *types = TypeDatabase::instance(); SingleTypeEntryHash entryHash = types->entries(); QList entries = entryHash.values(); foreach (TypeEntry *entry, entries) { if (entry == 0) continue; if (!entry->isComplex() || entry->codeGeneration() == TypeEntry::GenerateNothing) continue; ComplexTypeEntry *centry = static_cast(entry); FunctionModificationList modifications = centry->functionModifications(); foreach (FunctionModification modification, modifications) { QString signature = modification.signature; QString name = signature.trimmed(); name = name.mid(0, signature.indexOf("(")); AbstractMetaClass *clazz = m_meta_classes.findClass(centry->qualifiedCppName()); if (clazz == 0) continue; AbstractMetaFunctionList functions = clazz->functions(); bool found = false; QStringList possibleSignatures; foreach (AbstractMetaFunction *function, functions) { if (function->minimalSignature() == signature && function->implementingClass() == clazz) { found = true; break; } if (function->originalName() == name) possibleSignatures.append(function->minimalSignature() + " in " + function->implementingClass()->name()); } if (!found) { QString warning = QString("signature '%1' for function modification in '%2' not found. Possible candidates: %3") .arg(signature) .arg(clazz->qualifiedCppName()) .arg(possibleSignatures.join(", ")); ReportHandler::warning(warning); } } } } AbstractMetaClass *AbstractMetaBuilder::argumentToClass(ArgumentModelItem argument) { AbstractMetaClass *returned = 0; bool ok = false; AbstractMetaType *type = translateType(argument->type(), &ok); if (ok && type != 0 && type->typeEntry() != 0 && type->typeEntry()->isComplex()) { const TypeEntry *entry = type->typeEntry(); returned = m_meta_classes.findClass(entry->name()); } delete type; return returned; } /** * Checks the argument of a hash function and flags the type if it is a complex type */ void AbstractMetaBuilder::registerHashFunction(FunctionModelItem function_item) { ArgumentList arguments = function_item->arguments(); if (arguments.size() == 1) { if (AbstractMetaClass *cls = argumentToClass(arguments.at(0))) cls->setHasHashFunction(true); } } /** * Check if a class has a debug stream operator that can be used as toString */ void AbstractMetaBuilder::registerToStringCapability(FunctionModelItem function_item) { ArgumentList arguments = function_item->arguments(); if (arguments.size() == 2) { if (arguments.at(0)->type().toString() == "QDebug"){ ArgumentModelItem arg = arguments.at(1); if (AbstractMetaClass *cls = argumentToClass(arg)) { if (arg->type().indirections() < 2) { cls->setToStringCapability(function_item); } } } } } void AbstractMetaBuilder::traverseCompareOperator(FunctionModelItem item) { ArgumentList arguments = item->arguments(); if (arguments.size() == 2 && item->accessPolicy() == CodeModel::Public) { AbstractMetaClass *comparer_class = argumentToClass(arguments.at(0)); AbstractMetaClass *compared_class = argumentToClass(arguments.at(1)); if (comparer_class != 0 && compared_class != 0) { AbstractMetaClass *old_current_class = m_current_class; m_current_class = comparer_class; AbstractMetaFunction *meta_function = traverseFunction(item); if (meta_function != 0 && !meta_function->isInvalid()) { // Strip away first argument, since that is the containing object AbstractMetaArgumentList arguments = meta_function->arguments(); arguments.pop_front(); meta_function->setArguments(arguments); meta_function->setFunctionType(AbstractMetaFunction::GlobalScopeFunction); meta_function->setOriginalAttributes(meta_function->attributes()); setupFunctionDefaults(meta_function, comparer_class); comparer_class->addFunction(meta_function); } else if (meta_function != 0) { delete meta_function; } m_current_class = old_current_class; } } } void AbstractMetaBuilder::traverseStreamOperator(FunctionModelItem item) { ArgumentList arguments = item->arguments(); if (arguments.size() == 2 && item->accessPolicy() == CodeModel::Public) { AbstractMetaClass *streamClass = argumentToClass(arguments.at(0)); AbstractMetaClass *streamedClass = argumentToClass(arguments.at(1)); if (streamClass != 0 && streamedClass != 0 && (streamClass->name() == "QDataStream" || streamClass->name() == "QTextStream")) { AbstractMetaClass *old_current_class = m_current_class; m_current_class = streamedClass; AbstractMetaFunction *streamFunction = traverseFunction(item); if (streamFunction != 0 && !streamFunction->isInvalid()) { QString name = item->name(); streamFunction->setFunctionType(AbstractMetaFunction::GlobalScopeFunction); if (name.endsWith("<<")) streamFunction->setName("writeTo"); else streamFunction->setName("readFrom"); // Strip away last argument, since that is the containing object AbstractMetaArgumentList arguments = streamFunction->arguments(); arguments.pop_back(); streamFunction->setArguments(arguments); *streamFunction += AbstractMetaAttributes::Final; *streamFunction += AbstractMetaAttributes::Public; streamFunction->setOriginalAttributes(streamFunction->attributes()); streamFunction->setType(0); setupFunctionDefaults(streamFunction, streamedClass); streamedClass->addFunction(streamFunction); streamedClass->typeEntry()->addExtraInclude(streamClass->typeEntry()->include()); m_current_class = old_current_class; } } } } void AbstractMetaBuilder::fixQObjectForScope(TypeDatabase *types, NamespaceModelItem scope) { foreach (ClassModelItem item, scope->classes()) { QString qualified_name = item->qualifiedName().join("::"); TypeEntry *entry = types->findType(qualified_name); if (entry) { if (isQObject(qualified_name) && entry->isComplex()) { ((ComplexTypeEntry *) entry)->setQObject(true); } } } foreach (NamespaceModelItem item, scope->namespaceMap().values()) { if (scope != item) fixQObjectForScope(types, item); } } static bool class_less_than(AbstractMetaClass *a, AbstractMetaClass *b) { return a->name() < b->name(); } void AbstractMetaBuilder::sortLists() { qSort(m_meta_classes.begin(), m_meta_classes.end(), class_less_than); foreach (AbstractMetaClass *cls, m_meta_classes) { cls->sortFunctions(); } } bool AbstractMetaBuilder::build() { Q_ASSERT(!m_file_name.isEmpty()); QFile file(m_file_name); if (!file.open(QFile::ReadOnly)) return false; QTextStream stream(&file); stream.setCodec(QTextCodec::codecForName("UTF-8")); QByteArray contents = stream.readAll().toUtf8(); file.close(); Control control; Parser p(&control); pool __pool; TranslationUnitAST *ast = p.parse(contents, contents.size(), &__pool); CodeModel model; Binder binder(&model, p.location()); m_dom = binder.run(ast); pushScope(model_dynamic_cast(m_dom)); QHash typeMap = m_dom->classMap(); // fix up QObject's in the type system.. TypeDatabase *types = TypeDatabase::instance(); fixQObjectForScope(types, model_dynamic_cast(m_dom)); // Start the generation... foreach (ClassModelItem item, typeMap.values()) { AbstractMetaClass *cls = traverseClass(item); addAbstractMetaClass(cls); } QHash namespaceMap = m_dom->namespaceMap(); foreach (NamespaceModelItem item, namespaceMap.values()) { AbstractMetaClass *meta_class = traverseNamespace(item); if (meta_class) m_meta_classes << meta_class; } // Some trickery to support global-namespace enums... QHash enumMap = m_dom->enumMap(); m_current_class = 0; foreach (EnumModelItem item, enumMap) { AbstractMetaEnum *meta_enum = traverseEnum(item, 0, QSet()); if (meta_enum) { QString package = meta_enum->typeEntry()->javaPackage(); QString globalName = TypeDatabase::globalNamespaceClassName(meta_enum->typeEntry()); AbstractMetaClass *global = m_meta_classes.findClass(package + "." + globalName); if (!global) { ComplexTypeEntry *gte = new ObjectTypeEntry(globalName); gte->setTargetLangPackage(meta_enum->typeEntry()->javaPackage()); gte->setCodeGeneration(meta_enum->typeEntry()->codeGeneration()); global = createMetaClass(); global->setTypeEntry(gte); *global += AbstractMetaAttributes::Final; *global += AbstractMetaAttributes::Public; *global += AbstractMetaAttributes::Fake; m_meta_classes << global; } global->addEnum(meta_enum); meta_enum->setEnclosingClass(global); meta_enum->typeEntry()->setQualifier(globalName); // Global enums should be public despite not having public // identifiers so we'll fix the original attributes here. meta_enum->setOriginalAttributes(meta_enum->attributes()); } } // Go through all typedefs to see if we have defined any // specific typedefs to be used as classes. TypeAliasList typeAliases = m_dom->typeAliases(); foreach (TypeAliasModelItem typeAlias, typeAliases) { AbstractMetaClass *cls = traverseTypeAlias(typeAlias); addAbstractMetaClass(cls); } foreach (AbstractMetaClass *cls, m_meta_classes) { if (!cls->isInterface() && !cls->isNamespace()) { setupInheritance(cls); } } foreach (AbstractMetaClass *cls, m_meta_classes) { cls->fixFunctions(); if (cls->typeEntry() == 0) { ReportHandler::warning(QString("class '%1' does not have an entry in the type system") .arg(cls->name())); } else { if (!cls->hasConstructors() && !cls->isFinalInCpp() && !cls->isInterface() && !cls->isNamespace()) cls->addDefaultConstructor(); } if (cls->isAbstract() && !cls->isInterface()) { cls->typeEntry()->setLookupName(cls->typeEntry()->targetLangName() + "$ConcreteWrapper"); } } QList entries = TypeDatabase::instance()->entries().values(); foreach (const TypeEntry *entry, entries) { if (entry->isPrimitive()) continue; if ((entry->isValue() || entry->isObject()) && !entry->isString() && !entry->isChar() && !entry->isContainer() && !entry->isCustom() && !entry->isVariant() && !m_meta_classes.findClass(entry->qualifiedCppName())) { ReportHandler::warning(QString("type '%1' is specified in typesystem, but not defined. This could potentially lead to compilation errors.") .arg(entry->qualifiedCppName())); } if (entry->isEnum()) { QString pkg = entry->javaPackage(); QString name = (pkg.isEmpty() ? QString() : pkg + ".") + ((EnumTypeEntry *) entry)->javaQualifier(); AbstractMetaClass *cls = m_meta_classes.findClass(name); if (!cls) { ReportHandler::warning(QString("namespace '%1' for enum '%2' is not declared") .arg(name).arg(entry->targetLangName())); } else { AbstractMetaEnum *e = cls->findEnum(entry->targetLangName()); if (!e) ReportHandler::warning(QString("enum '%1' is specified in typesystem, " "but not declared") .arg(entry->qualifiedCppName())); } } } { FunctionList hash_functions = m_dom->findFunctions("qHash"); foreach (FunctionModelItem item, hash_functions) { registerHashFunction(item); } } { FunctionList hash_functions = m_dom->findFunctions("operator<<"); foreach (FunctionModelItem item, hash_functions) { registerToStringCapability(item); } } { FunctionList compare_operators = m_dom->findFunctions("operator==") + m_dom->findFunctions("operator<=") + m_dom->findFunctions("operator>=") + m_dom->findFunctions("operator<") + m_dom->findFunctions("operator>"); foreach (FunctionModelItem item, compare_operators) { traverseCompareOperator(item); } } { FunctionList stream_operators = m_dom->findFunctions("operator<<") + m_dom->findFunctions("operator>>"); foreach (FunctionModelItem item, stream_operators) { traverseStreamOperator(item); } } figureOutEnumValues(); figureOutDefaultEnumArguments(); checkFunctionModifications(); foreach (AbstractMetaClass *cls, m_meta_classes) { setupEquals(cls); setupComparable(cls); setupClonable(cls); } dumpLog(); sortLists(); return true; } void AbstractMetaBuilder::addAbstractMetaClass(AbstractMetaClass *cls) { if (!cls) return; cls->setOriginalAttributes(cls->attributes()); if (cls->typeEntry()->isContainer()) { m_templates << cls; } else { m_meta_classes << cls; if (cls->typeEntry()->designatedInterface()) { AbstractMetaClass *interface = cls->extractInterface(); m_meta_classes << interface; ReportHandler::debugSparse(QString(" -> interface '%1'").arg(interface->name())); } } } AbstractMetaClass *AbstractMetaBuilder::traverseNamespace(NamespaceModelItem namespace_item) { QString namespace_name = (!m_namespace_prefix.isEmpty() ? m_namespace_prefix + "::" : QString()) + namespace_item->name(); NamespaceTypeEntry *type = TypeDatabase::instance()->findNamespaceType(namespace_name); if (TypeDatabase::instance()->isClassRejected(namespace_name)) { m_rejected_classes.insert(namespace_name, GenerationDisabled); return 0; } if (!type) { ReportHandler::warning(QString("namespace '%1' does not have a type entry") .arg(namespace_name)); return 0; } AbstractMetaClass *meta_class = createMetaClass(); meta_class->setTypeEntry(type); *meta_class += AbstractMetaAttributes::Public; m_current_class = meta_class; ReportHandler::debugSparse(QString("namespace '%1.%2'") .arg(meta_class->package()) .arg(namespace_item->name())); traverseEnums(model_dynamic_cast(namespace_item), meta_class, namespace_item->enumsDeclarations()); traverseFunctions(model_dynamic_cast(namespace_item), meta_class); // traverseClasses(model_dynamic_cast(namespace_item)); pushScope(model_dynamic_cast(namespace_item)); m_namespace_prefix = currentScope()->qualifiedName().join("::"); ClassList classes = namespace_item->classes(); foreach (ClassModelItem cls, classes) { AbstractMetaClass *mjc = traverseClass(cls); addAbstractMetaClass(mjc); } // Go through all typedefs to see if we have defined any // specific typedefs to be used as classes. TypeAliasList typeAliases = namespace_item->typeAliases(); foreach (TypeAliasModelItem typeAlias, typeAliases) { AbstractMetaClass *cls = traverseTypeAlias(typeAlias); addAbstractMetaClass(cls); } // Traverse namespaces recursively QList inner_namespaces = namespace_item->namespaceMap().values(); foreach (const NamespaceModelItem &ni, inner_namespaces) { AbstractMetaClass *mjc = traverseNamespace(ni); addAbstractMetaClass(mjc); } m_current_class = 0; popScope(); m_namespace_prefix = currentScope()->qualifiedName().join("::"); if (!type->include().isValid()) { QFileInfo info(namespace_item->fileName()); type->setInclude(Include(Include::IncludePath, info.fileName())); } return meta_class; } struct Operator { enum Type { Plus, ShiftLeft, None }; Operator() : type(None) { } int calculate(int x) { switch (type) { case Plus: return x + value; case ShiftLeft: return x << value; case None: return x; } return x; } Type type; int value; }; Operator findOperator(QString *s) { const char *names[] = { "+", "<<" }; for (int i=0; i 0) { bool ok; QString right = str.mid(splitPoint + name.length()); Operator op; op.value = right.toInt(&ok); if (ok) { op.type = Operator::Type(i); *s = str.left(splitPoint).trimmed(); return op; } } } return Operator(); } int AbstractMetaBuilder::figureOutEnumValue(const QString &stringValue, int oldValuevalue, AbstractMetaEnum *meta_enum, AbstractMetaFunction *meta_function) { if (stringValue.isEmpty()) return oldValuevalue; QStringList stringValues = stringValue.split("|"); int returnValue = 0; bool matched = false; for (int i=0; i 0 && s.at(0) == QLatin1Char('0')) v = s.toUInt(&ok, 0); else v = s.toInt(&ok); if (ok) { matched = true; } else if (m_enum_values.contains(s)) { v = m_enum_values[s]->value(); matched = true; } else { AbstractMetaEnumValue *ev = 0; if (meta_enum && (ev = meta_enum->values().find(s))) { v = ev->value(); matched = true; } else if (meta_enum && (ev = meta_enum->enclosingClass()->findEnumValue(s, meta_enum))) { v = ev->value(); matched = true; } else { if (meta_enum) ReportHandler::warning("unhandled enum value: " + s + " in " + meta_enum->enclosingClass()->name() + "::" + meta_enum->name()); else ReportHandler::warning("unhandled enum value: Unknown enum"); } } if (matched) returnValue |= op.calculate(v); } if (!matched) { QString warn = QString("unmatched enum %1").arg(stringValue); if (meta_function != 0) { warn += QString(" when parsing default value of '%1' in class '%2'") .arg(meta_function->name()) .arg(meta_function->implementingClass()->name()); } ReportHandler::warning(warn); returnValue = oldValuevalue; } return returnValue; } void AbstractMetaBuilder::figureOutEnumValuesForClass(AbstractMetaClass *meta_class, QSet *classes) { AbstractMetaClass *base = meta_class->baseClass(); if (base != 0 && !classes->contains(base)) figureOutEnumValuesForClass(base, classes); if (classes->contains(meta_class)) return; AbstractMetaEnumList enums = meta_class->enums(); foreach (AbstractMetaEnum *e, enums) { if (!e) { ReportHandler::warning("bad enum in class " + meta_class->name()); continue; } AbstractMetaEnumValueList lst = e->values(); int value = 0; for (int i=0; istringValue(), value, e); lst.at(i)->setValue(value); value++; } // Check for duplicate values... EnumTypeEntry *ete = e->typeEntry(); if (!ete->forceInteger()) { QHash entries; foreach (AbstractMetaEnumValue *v, lst) { bool vRejected = ete->isEnumValueRejected(v->name()); AbstractMetaEnumValue *current = entries.value(v->value()); if (current) { bool currentRejected = ete->isEnumValueRejected(current->name()); if (!currentRejected && !vRejected) { ReportHandler::warning( QString("duplicate enum values: %1::%2, %3 and %4 are %5, already rejected: (%6)") .arg(meta_class->name()) .arg(e->name()) .arg(v->name()) .arg(entries[v->value()]->name()) .arg(v->value()) .arg(ete->enumValueRejections().join(", "))); continue; } } if (!vRejected) entries[v->value()] = v; } // Entries now contain all the original entries, no // rejected ones... Use this to generate the enumValueRedirection table. foreach (AbstractMetaEnumValue *reject, lst) { if (!ete->isEnumValueRejected(reject->name())) continue; AbstractMetaEnumValue *used = entries.value(reject->value()); if (!used) { ReportHandler::warning( QString::fromLatin1("Rejected enum has no alternative...: %1::%2") .arg(meta_class->name()) .arg(reject->name())); continue; } ete->addEnumValueRedirection(reject->name(), used->name()); } } } *classes += meta_class; } void AbstractMetaBuilder::figureOutEnumValues() { // Keep a set of classes that we already traversed. We use this to // enforce that we traverse base classes prior to subclasses. QSet classes; foreach (AbstractMetaClass *c, m_meta_classes) { figureOutEnumValuesForClass(c, &classes); } } void AbstractMetaBuilder::figureOutDefaultEnumArguments() { foreach (AbstractMetaClass *meta_class, m_meta_classes) { foreach (AbstractMetaFunction *meta_function, meta_class->functions()) { foreach (AbstractMetaArgument *arg, meta_function->arguments()) { QString expr = arg->defaultValueExpression(); if (expr.isEmpty()) continue; if (!meta_function->replacedDefaultExpression(meta_function->implementingClass(), arg->argumentIndex()+1).isEmpty()) { continue; } QString new_expr = expr; if (arg->type()->isEnum()) { QStringList lst = expr.split(QLatin1String("::")); if (lst.size() == 1) { QVector classes(1, meta_class); AbstractMetaEnum *e = 0; while (!classes.isEmpty() && e == 0) { if (classes.front() != 0) { classes << classes.front()->baseClass(); AbstractMetaClassList interfaces = classes.front()->interfaces(); foreach (AbstractMetaClass *interface, interfaces) classes << interface->primaryInterfaceImplementor(); e = classes.front()->findEnumForValue(expr); } classes.pop_front(); } if (e != 0) { new_expr = QString("%1.%2") .arg(e->typeEntry()->qualifiedTargetLangName()) .arg(expr); } else { ReportHandler::warning("Cannot find enum constant for value '" + expr + "' in '" + meta_class->name() + "' or any of its super classes"); } } else if (lst.size() == 2) { AbstractMetaClass *cl = m_meta_classes.findClass(lst.at(0)); if (!cl) { ReportHandler::warning("missing required class for enums: " + lst.at(0)); continue; } new_expr = QString("%1.%2.%3") .arg(cl->typeEntry()->qualifiedTargetLangName()) .arg(arg->type()->name()) .arg(lst.at(1)); } else { ReportHandler::warning("bad default value passed to enum " + expr); } } else if(arg->type()->isFlags()) { const FlagsTypeEntry *flagsEntry = static_cast(arg->type()->typeEntry()); EnumTypeEntry *enumEntry = flagsEntry->originator(); AbstractMetaEnum *meta_enum = m_meta_classes.findEnum(enumEntry); if (!meta_enum) { ReportHandler::warning("unknown required enum " + enumEntry->qualifiedCppName()); continue; } int value = figureOutEnumValue(expr, 0, meta_enum, meta_function); new_expr = QString::number(value); } else if (arg->type()->isPrimitive()) { AbstractMetaEnumValue *value = 0; if (expr.contains("::")) value = m_meta_classes.findEnumValue(expr); if (!value) value = meta_class->findEnumValue(expr, 0); if (value) { new_expr = QString::number(value->value()); } else if (expr.contains(QLatin1Char('+'))) { new_expr = QString::number(figureOutEnumValue(expr, 0, 0)); } } arg->setDefaultValueExpression(new_expr); } } } } AbstractMetaEnum *AbstractMetaBuilder::traverseEnum(EnumModelItem enum_item, AbstractMetaClass *enclosing, const QSet &enumsDeclarations) { // Skipping private enums. if (enum_item->accessPolicy() == CodeModel::Private) { return 0; } QString qualified_name = enum_item->qualifiedName().join("::"); TypeEntry *type_entry = TypeDatabase::instance()->findType(qualified_name); QString enum_name = enum_item->name(); QString class_name; if (m_current_class) class_name = m_current_class->typeEntry()->qualifiedCppName(); if (TypeDatabase::instance()->isEnumRejected(class_name, enum_name)) { m_rejected_enums.insert(qualified_name, GenerationDisabled); return 0; } if (!type_entry || !type_entry->isEnum()) { QString context = m_current_class ? m_current_class->name() : QLatin1String(""); ReportHandler::warning(QString("enum '%1' does not have a type entry or is not an enum") .arg(qualified_name)); m_rejected_enums.insert(qualified_name, NotInTypeSystem); return 0; } AbstractMetaEnum *meta_enum = createMetaEnum(); if ( enumsDeclarations.contains(qualified_name) || enumsDeclarations.contains(enum_name)) { meta_enum->setHasQEnumsDeclaration(true); } meta_enum->setTypeEntry((EnumTypeEntry *) type_entry); switch (enum_item->accessPolicy()) { case CodeModel::Public: *meta_enum += AbstractMetaAttributes::Public; break; case CodeModel::Protected: *meta_enum += AbstractMetaAttributes::Protected; break; // case CodeModel::Private: *meta_enum += AbstractMetaAttributes::Private; break; default: break; } ReportHandler::debugMedium(QString(" - traversing enum %1").arg(meta_enum->fullName())); foreach (EnumeratorModelItem value, enum_item->enumerators()) { AbstractMetaEnumValue *meta_enum_value = createMetaEnumValue(); meta_enum_value->setName(value->name()); // Deciding the enum value... meta_enum_value->setStringValue(value->value()); meta_enum->addEnumValue(meta_enum_value); ReportHandler::debugFull(" - " + meta_enum_value->name() + " = " + meta_enum_value->value()); // Add into global register... if (enclosing) m_enum_values[enclosing->name() + "::" + meta_enum_value->name()] = meta_enum_value; else m_enum_values[meta_enum_value->name()] = meta_enum_value; } QFileInfo info(enum_item->fileName()); meta_enum->typeEntry()->setInclude(Include(Include::IncludePath, info.fileName())); m_enums << meta_enum; return meta_enum; } AbstractMetaClass *AbstractMetaBuilder::traverseTypeAlias(TypeAliasModelItem typeAlias) { QString class_name = strip_template_args(typeAlias->name()); QString full_class_name = class_name; // we have an inner class if (m_current_class) { full_class_name = strip_template_args(m_current_class->typeEntry()->qualifiedCppName()) + "::" + full_class_name; } // If we haven't specified anything for the typedef, then we don't care ComplexTypeEntry *type = TypeDatabase::instance()->findComplexType(full_class_name); if (type == 0) return 0; if (type->isObject()) static_cast(type)->setQObject(isQObject(strip_template_args(typeAlias->type().qualifiedName().join("::")))); AbstractMetaClass *meta_class = createMetaClass(); meta_class->setTypeAlias(true); meta_class->setTypeEntry(type); meta_class->setBaseClassNames(QStringList() << typeAlias->type().qualifiedName().join("::")); *meta_class += AbstractMetaAttributes::Public; // Set the default include file name if (!type->include().isValid()) { QFileInfo info(typeAlias->fileName()); type->setInclude(Include(Include::IncludePath, info.fileName())); } return meta_class; } AbstractMetaClass *AbstractMetaBuilder::traverseClass(ClassModelItem class_item) { QString class_name = strip_template_args(class_item->name()); QString full_class_name = class_name; // we have inner an class if (m_current_class) { full_class_name = strip_template_args(m_current_class->typeEntry()->qualifiedCppName()) + "::" + full_class_name; } ComplexTypeEntry *type = TypeDatabase::instance()->findComplexType(full_class_name); RejectReason reason = NoReason; if (full_class_name == "QMetaTypeId") { // QtScript: record which types have been declared int lpos = class_item->name().indexOf('<'); int rpos = class_item->name().lastIndexOf('>'); if ((lpos != -1) && (rpos != -1)) { QString declared_typename = class_item->name().mid(lpos+1, rpos - lpos-1); m_qmetatype_declared_typenames.insert(declared_typename); } } if (TypeDatabase::instance()->isClassRejected(full_class_name)) { reason = GenerationDisabled; } else if (!type) { TypeEntry *te = TypeDatabase::instance()->findType(full_class_name); if (te && !te->isComplex()) reason = RedefinedToNotClass; else reason = NotInTypeSystem; } else if (type->codeGeneration() == TypeEntry::GenerateNothing) { reason = GenerationDisabled; } if (reason != NoReason) { m_rejected_classes.insert(full_class_name, reason); return 0; } if (type->isObject()) { ((ObjectTypeEntry *)type)->setQObject(isQObject(full_class_name)); } AbstractMetaClass *meta_class = createMetaClass(); meta_class->setTypeEntry(type); meta_class->setBaseClassNames(class_item->baseClasses()); *meta_class += AbstractMetaAttributes::Public; AbstractMetaClass *old_current_class = m_current_class; m_current_class = meta_class; if (type->isContainer()) { ReportHandler::debugSparse(QString("container: '%1'").arg(full_class_name)); } else { ReportHandler::debugSparse(QString("class: '%1'").arg(meta_class->fullName())); } TemplateParameterList template_parameters = class_item->templateParameters(); QList template_args; template_args.clear(); for (int i=0; iname()); param_type->setOrdinal(i); template_args.append(param_type); } meta_class->setTemplateArguments(template_args); parseQ_Property(meta_class, class_item->propertyDeclarations()); traverseFunctions(model_dynamic_cast(class_item), meta_class); traverseEnums(model_dynamic_cast(class_item), meta_class, class_item->enumsDeclarations()); traverseFields(model_dynamic_cast(class_item), meta_class); // Inner classes { QList inner_classes = class_item->classMap().values(); foreach (const ClassModelItem &ci, inner_classes) { AbstractMetaClass *cl = traverseClass(ci); if (cl) { cl->setEnclosingClass(meta_class); m_meta_classes << cl; } } } // Go through all typedefs to see if we have defined any // specific typedefs to be used as classes. TypeAliasList typeAliases = class_item->typeAliases(); foreach (TypeAliasModelItem typeAlias, typeAliases) { AbstractMetaClass *cls = traverseTypeAlias(typeAlias); if (cls != 0) { cls->setEnclosingClass(meta_class); addAbstractMetaClass(cls); } } m_current_class = old_current_class; // Set the default include file name if (!type->include().isValid()) { QFileInfo info(class_item->fileName()); type->setInclude(Include(Include::IncludePath, info.fileName())); } return meta_class; } AbstractMetaField *AbstractMetaBuilder::traverseField(VariableModelItem field, const AbstractMetaClass *cls) { QString field_name = field->name(); QString class_name = m_current_class->typeEntry()->qualifiedCppName(); // Ignore friend decl. if (field->isFriend()) return 0; if (field->accessPolicy() == CodeModel::Private) return 0; if (TypeDatabase::instance()->isFieldRejected(class_name, field_name)) { m_rejected_fields.insert(class_name + "::" + field_name, GenerationDisabled); return 0; } AbstractMetaField *meta_field = createMetaField(); meta_field->setName(field_name); meta_field->setEnclosingClass(cls); bool ok; TypeInfo field_type = field->type(); AbstractMetaType *meta_type = translateType(field_type, &ok); if (!meta_type || !ok) { ReportHandler::warning(QString("skipping field '%1::%2' with unmatched type '%3'") .arg(m_current_class->name()) .arg(field_name) .arg(TypeInfo::resolveType(field_type, currentScope()->toItem()).qualifiedName().join("::"))); delete meta_field; return 0; } meta_field->setType(meta_type); uint attr = 0; if (field->isStatic()) attr |= AbstractMetaAttributes::Static; CodeModel::AccessPolicy policy = field->accessPolicy(); if (policy == CodeModel::Public) attr |= AbstractMetaAttributes::Public; else if (policy == CodeModel::Protected) attr |= AbstractMetaAttributes::Protected; else attr |= AbstractMetaAttributes::Private; meta_field->setAttributes(attr); return meta_field; } void AbstractMetaBuilder::traverseFields(ScopeModelItem scope_item, AbstractMetaClass *meta_class) { foreach (VariableModelItem field, scope_item->variables()) { AbstractMetaField *meta_field = traverseField(field, meta_class); if (meta_field) { meta_field->setOriginalAttributes(meta_field->attributes()); meta_class->addField(meta_field); } } } void AbstractMetaBuilder::setupFunctionDefaults(AbstractMetaFunction *meta_function, AbstractMetaClass *meta_class) { // Set the default value of the declaring class. This may be changed // in fixFunctions later on meta_function->setDeclaringClass(meta_class); // Some of the queries below depend on the implementing class being set // to function properly. Such as function modifications meta_function->setImplementingClass(meta_class); if (meta_function->name() == "operator_equal") meta_class->setHasEqualsOperator(true); if (!meta_function->isFinalInTargetLang() && meta_function->isRemovedFrom(meta_class, TypeSystem::TargetLangCode)) { *meta_function += AbstractMetaAttributes::FinalInCpp; } } void AbstractMetaBuilder::traverseFunctions(ScopeModelItem scope_item, AbstractMetaClass *meta_class) { foreach (FunctionModelItem function, scope_item->functions()) { AbstractMetaFunction *meta_function = traverseFunction(function); if (meta_function) { meta_function->setOriginalAttributes(meta_function->attributes()); if (meta_class->isNamespace()) *meta_function += AbstractMetaAttributes::Static; if (QPropertySpec *read = meta_class->propertySpecForRead(meta_function->name())) { if (read->type() == meta_function->type()->typeEntry()) { *meta_function += AbstractMetaAttributes::PropertyReader; meta_function->setPropertySpec(read); // printf("%s is reader for %s\n", // qPrintable(meta_function->name()), // qPrintable(read->name())); } } else if (QPropertySpec *write = meta_class->propertySpecForWrite(meta_function->name())) { if (write->type() == meta_function->arguments().at(0)->type()->typeEntry()) { *meta_function += AbstractMetaAttributes::PropertyWriter; meta_function->setPropertySpec(write); // printf("%s is writer for %s\n", // qPrintable(meta_function->name()), // qPrintable(write->name())); } } else if (QPropertySpec *reset = meta_class->propertySpecForReset(meta_function->name())) { *meta_function += AbstractMetaAttributes::PropertyResetter; meta_function->setPropertySpec(reset); // printf("%s is resetter for %s\n", // qPrintable(meta_function->name()), // qPrintable(reset->name())); } bool isInvalidDestructor = meta_function->isDestructor() && meta_function->isPrivate(); bool isInvalidConstructor = meta_function->isConstructor() && (meta_function->isPrivate() || meta_function->isInvalid()); if ((isInvalidDestructor || isInvalidConstructor) && !meta_class->hasNonPrivateConstructor()) { *meta_class += AbstractMetaAttributes::Final; } else if (meta_function->isConstructor() && !meta_function->isPrivate()) { *meta_class -= AbstractMetaAttributes::Final; meta_class->setHasNonPrivateConstructor(true); } // Classes with virtual destructors should always have a shell class // (since we aren't registering the destructors, we need this extra check) if (meta_function->isDestructor() && !meta_function->isFinal()) meta_class->setForceShellClass(true); if (!meta_function->isDestructor() && !meta_function->isInvalid() && (!meta_function->isConstructor() || !meta_function->isPrivate())) { if (meta_class->typeEntry()->designatedInterface() && !meta_function->isPublic() && !meta_function->isPrivate()) { QString warn = QString("non-public function '%1' in interface '%2'") .arg(meta_function->name()).arg(meta_class->name()); ReportHandler::warning(warn); meta_function->setVisibility(AbstractMetaClass::Public); } setupFunctionDefaults(meta_function, meta_class); if (meta_function->isSignal() && meta_class->hasSignal(meta_function)) { QString warn = QString("signal '%1' in class '%2' is overloaded.") .arg(meta_function->name()).arg(meta_class->name()); ReportHandler::warning(warn); } if (meta_function->isSignal() && !meta_class->isQObject()) { QString warn = QString("signal '%1' in non-QObject class '%2'") .arg(meta_function->name()).arg(meta_class->name()); ReportHandler::warning(warn); } meta_class->addFunction(meta_function); } else if (meta_function->isDestructor()) { meta_class->setDestructorException(meta_function->exception()); if (!meta_function->isPublic()) meta_class->setHasPublicDestructor(false); } } } } bool AbstractMetaBuilder::setupInheritance(AbstractMetaClass *meta_class) { Q_ASSERT(!meta_class->isInterface()); if (m_setup_inheritance_done.contains(meta_class)) return true; m_setup_inheritance_done.insert(meta_class); QStringList base_classes = meta_class->baseClassNames(); TypeDatabase *types = TypeDatabase::instance(); // we only support our own containers and ONLY if there is only one baseclass if (base_classes.size() == 1 && base_classes.first().count('<') == 1) { QStringList scope = meta_class->typeEntry()->qualifiedCppName().split("::"); scope.removeLast(); for (int i=scope.size(); i>=0; --i) { QString prefix = i > 0 ? QStringList(scope.mid(0, i)).join("::") + "::" : QString(); QString complete_name = prefix + base_classes.first(); TypeParser::Info info = TypeParser::parse(complete_name); QString base_name = info.qualified_name.join("::"); AbstractMetaClass *templ = 0; foreach (AbstractMetaClass *c, m_templates) { if (c->typeEntry()->name() == base_name) { templ = c; break; } } if (templ == 0) templ = m_meta_classes.findClass(base_name); if (templ) { setupInheritance(templ); inheritTemplate(meta_class, templ, info); return true; } } ReportHandler::warning(QString("template baseclass '%1' of '%2' is not known") .arg(base_classes.first()) .arg(meta_class->name())); return false; } int primary = -1; int primaries = 0; for (int i=0; iisClassRejected(base_classes.at(i))) continue; TypeEntry *base_class_entry = types->findType(base_classes.at(i)); if (!base_class_entry) { ReportHandler::warning(QString("class '%1' inherits from unknown base class '%2'") .arg(meta_class->name()).arg(base_classes.at(i))); } // true for primary base class else if (!base_class_entry->designatedInterface()) { if (primaries > 0) { ReportHandler::warning(QString("class '%1' has multiple primary base classes" " '%2' and '%3'") .arg(meta_class->name()) .arg(base_classes.at(primary)) .arg(base_class_entry->name())); return false; } primaries++; primary = i; } } if (primary >= 0) { AbstractMetaClass *base_class = m_meta_classes.findClass(base_classes.at(primary)); if (!base_class) { ReportHandler::warning(QString("unknown baseclass for '%1': '%2'") .arg(meta_class->name()) .arg(base_classes.at(primary))); return false; } meta_class->setBaseClass(base_class); if (meta_class->typeEntry()->designatedInterface() != 0 && meta_class->isQObject()) { ReportHandler::warning(QString("QObject extended by interface type '%1'. This is not supported and the generated Java code will not compile.") .arg(meta_class->name())); } else if (meta_class->typeEntry()->designatedInterface() != 0 && base_class != 0 && !base_class->isInterface()) { ReportHandler::warning(QString("object type '%1' extended by interface type '%2'. The resulting API will be less expressive than the original.") .arg(base_class->name()) .arg(meta_class->name())); } } for (int i=0; iisClassRejected(base_classes.at(i))) continue; if (i != primary) { AbstractMetaClass *base_class = m_meta_classes.findClass(base_classes.at(i)); if (base_class == 0) { ReportHandler::warning(QString("class not found for setup inheritance '%1'").arg(base_classes.at(i))); return false; } setupInheritance(base_class); QString interface_name = InterfaceTypeEntry::interfaceName(base_class->name()); AbstractMetaClass *iface = m_meta_classes.findClass(interface_name); if (!iface) { ReportHandler::warning(QString("unknown interface for '%1': '%2'") .arg(meta_class->name()) .arg(interface_name)); return false; } meta_class->addInterface(iface); AbstractMetaClassList interfaces = iface->interfaces(); foreach (AbstractMetaClass *iface, interfaces) meta_class->addInterface(iface); } } return true; } void AbstractMetaBuilder::traverseEnums(ScopeModelItem scope_item, AbstractMetaClass *meta_class, const QStringList &enumsDeclarations) { EnumList enums = scope_item->enums(); foreach (EnumModelItem enum_item, enums) { AbstractMetaEnum *meta_enum = traverseEnum(enum_item, meta_class, QSet::fromList(enumsDeclarations)); if (meta_enum) { meta_enum->setOriginalAttributes(meta_enum->attributes()); meta_class->addEnum(meta_enum); meta_enum->setEnclosingClass(meta_class); } } } AbstractMetaFunction *AbstractMetaBuilder::traverseFunction(FunctionModelItem function_item) { QString function_name = function_item->name(); QString class_name = m_current_class->typeEntry()->qualifiedCppName(); if (TypeDatabase::instance()->isFunctionRejected(class_name, function_name)) { m_rejected_functions.insert(class_name + "::" + function_name, GenerationDisabled); return 0; } Q_ASSERT(function_item->functionType() == CodeModel::Normal || function_item->functionType() == CodeModel::Signal || function_item->functionType() == CodeModel::Slot); if (function_item->isFriend()) return 0; QString cast_type; if (function_name.startsWith("operator")) { function_name = rename_operator(function_name.mid(8)); if (function_name.isEmpty()) { m_rejected_functions.insert(class_name + "::" + function_name, GenerationDisabled); return 0; } if (function_name.contains("_cast_")) cast_type = function_name.mid(14).trimmed(); } AbstractMetaFunction *meta_function = createMetaFunction(); meta_function->setConstant(function_item->isConstant()); meta_function->setException(function_item->exception()); ReportHandler::debugMedium(QString(" - %2()").arg(function_name)); meta_function->setName(function_name); meta_function->setOriginalName(function_item->name()); if (function_item->isAbstract()) *meta_function += AbstractMetaAttributes::Abstract; if (!meta_function->isAbstract()) *meta_function += AbstractMetaAttributes::Native; if (!function_item->isVirtual()) *meta_function += AbstractMetaAttributes::Final; if (function_item->isInvokable()) *meta_function += AbstractMetaAttributes::Invokable; if (function_item->isStatic()) { *meta_function += AbstractMetaAttributes::Static; *meta_function += AbstractMetaAttributes::Final; } // Access rights if (function_item->accessPolicy() == CodeModel::Public) *meta_function += AbstractMetaAttributes::Public; else if (function_item->accessPolicy() == CodeModel::Private) *meta_function += AbstractMetaAttributes::Private; else *meta_function += AbstractMetaAttributes::Protected; QString stripped_class_name = class_name; int cc_pos = stripped_class_name.lastIndexOf("::"); if (cc_pos > 0) stripped_class_name = stripped_class_name.mid(cc_pos + 2); TypeInfo function_type = function_item->type(); if (function_name.startsWith('~')) { meta_function->setFunctionType(AbstractMetaFunction::DestructorFunction); meta_function->setInvalid(true); } else if (strip_template_args(function_name) == stripped_class_name) { meta_function->setFunctionType(AbstractMetaFunction::ConstructorFunction); meta_function->setName(m_current_class->name()); } else { bool ok; AbstractMetaType *type = 0; if (!cast_type.isEmpty()) { TypeInfo info; info.setQualifiedName(QStringList(cast_type)); type = translateType(info, &ok); } else { type = translateType(function_type, &ok); } if (!ok) { ReportHandler::warning(QString("skipping function '%1::%2', unmatched return type '%3'") .arg(class_name) .arg(function_item->name()) .arg(function_item->type().toString())); m_rejected_functions[class_name + "::" + function_name] = UnmatchedReturnType; meta_function->setInvalid(true); return meta_function; } meta_function->setType(type); if (function_item->functionType() == CodeModel::Signal) meta_function->setFunctionType(AbstractMetaFunction::SignalFunction); else if (function_item->functionType() == CodeModel::Slot) meta_function->setFunctionType(AbstractMetaFunction::SlotFunction); } ArgumentList arguments = function_item->arguments(); AbstractMetaArgumentList meta_arguments; int first_default_argument = 0; for (int i=0; itype(), &ok); if (!meta_type || !ok) { ReportHandler::warning(QString("skipping function '%1::%2', " "unmatched parameter type '%3'") .arg(class_name) .arg(function_item->name()) .arg(arg->type().toString())); m_rejected_functions[class_name + "::" + function_name] = UnmatchedArgumentType; meta_function->setInvalid(true); return meta_function; } AbstractMetaArgument *meta_argument = createMetaArgument(); meta_argument->setType(meta_type); meta_argument->setName(arg->name()); meta_argument->setArgumentIndex(i); meta_arguments << meta_argument; } meta_function->setArguments(meta_arguments); // Find the correct default values for (int i=0; idefaultValue()) { QString expr = arg->defaultValueExpression(); if (!expr.isEmpty()) meta_arg->setOriginalDefaultValueExpression(expr); expr = translateDefaultValue(arg, meta_arg->type(), meta_function, m_current_class, i); if (expr.isEmpty()) { first_default_argument = i; } else { meta_arg->setDefaultValueExpression(expr); } if (meta_arg->type()->isEnum() || meta_arg->type()->isFlags()) { m_enum_default_arguments << QPair(meta_arg, meta_function); } } } // If we where not able to translate the default argument make it // reset all default arguments before this one too. for (int i=0; isetDefaultValueExpression(QString()); if (ReportHandler::debugLevel() == ReportHandler::FullDebug) foreach(AbstractMetaArgument *arg, meta_arguments) ReportHandler::debugFull(" - " + arg->toString()); return meta_function; } AbstractMetaType *AbstractMetaBuilder::translateType(const TypeInfo &_typei, bool *ok, bool resolveType, bool resolveScope) { Q_ASSERT(ok); *ok = true; // 1. Test the type info without resolving typedefs in case this is present in the // type system TypeInfo typei; if (resolveType) { bool isok; AbstractMetaType *t = translateType(_typei, &isok, false, resolveScope); if (t != 0 && isok) return t; } if (!resolveType) typei = _typei; else { // Go through all parts of the current scope (including global namespace) // to resolve typedefs. The parser does not properly resolve typedefs in // the global scope when they are referenced from inside a namespace. // This is a work around to fix this bug since fixing it in resolveType // seemed non-trivial int i = m_scopes.size() - 1; while (i >= 0) { typei = TypeInfo::resolveType(_typei, m_scopes.at(i--)->toItem()); if (typei.qualifiedName().join("::") != _typei.qualifiedName().join("::")) break; } } if (typei.isFunctionPointer()) { *ok = false; return 0; } TypeParser::Info typeInfo = TypeParser::parse(typei.toString()); if (typeInfo.is_busted) { *ok = false; return 0; } // 2. Handle pointers specified as arrays with unspecified size bool array_of_unspecified_size = false; if (typeInfo.arrays.size() > 0) { array_of_unspecified_size = true; for (int i=0; i=0; --i) { QString s = typeInfo.arrays.at(i); bool isok; int elems = s.toInt(&isok); if (!isok) return 0; AbstractMetaType *arrayType = createMetaType(); arrayType->setArrayElementCount(elems); arrayType->setArrayElementType(elementType); arrayType->setTypeEntry(new ArrayTypeEntry(elementType->typeEntry())); decideUsagePattern(arrayType); elementType = arrayType; } return elementType; } else { typeInfo.indirections += typeInfo.arrays.size(); } } QStringList qualifier_list = typeInfo.qualified_name; if (qualifier_list.isEmpty()) { ReportHandler::warning(QString("horribly broken type '%1'").arg(_typei.toString())); *ok = false; return 0; } QString qualified_name = qualifier_list.join("::"); QString name = qualifier_list.takeLast(); // 3. Special case 'void' type if (name == "void" && typeInfo.indirections == 0) { return 0; } // 4. Special case QFlags (include instantiation in name) if (qualified_name == "QFlags") qualified_name = typeInfo.toString(); // 5. Try to find the type const TypeEntry *type = TypeDatabase::instance()->findType(qualified_name); // 6. No? Try looking it up as a flags type if (!type) type = TypeDatabase::instance()->findFlagsType(qualified_name); // 7. No? Try looking it up as a container type if (!type) type = TypeDatabase::instance()->findContainerType(name); // 8. No? Check if the current class is a template and this type is one // of the parameters. if (type == 0 && m_current_class != 0) { QList template_args = m_current_class->templateArguments(); foreach (TypeEntry *te, template_args) { if (te->name() == qualified_name) type = te; } } // 9. Try finding the type by prefixing it with the current // context and all baseclasses of the current context if (!type && !TypeDatabase::instance()->isClassRejected(qualified_name) && m_current_class != 0 && resolveScope) { QStringList contexts; contexts.append(m_current_class->qualifiedCppName()); contexts.append(currentScope()->qualifiedName().join("::")); TypeInfo info = typei; bool subclasses_done = false; while (!contexts.isEmpty() && type == 0) { //type = TypeDatabase::instance()->findType(contexts.at(0) + "::" + qualified_name); bool isok; info.setQualifiedName(QStringList() << contexts.at(0) << qualified_name); AbstractMetaType *t = translateType(info, &isok, true, false); if (t != 0 && isok) return t; ClassModelItem item = m_dom->findClass(contexts.at(0)); if (item != 0) contexts += item->baseClasses(); contexts.pop_front(); // 10. Last resort: Special cased prefix of Qt namespace since the meta object implicitly inherits this, so // enum types from there may be addressed without any scope resolution in properties. if (contexts.size() == 0 && !subclasses_done) { contexts << "Qt"; subclasses_done = true; } } } if (!type) { *ok = false; return 0; } // Used to for diagnostics later... m_used_types << type; // These are only implicit and should not appear in code... Q_ASSERT(!type->isInterface()); AbstractMetaType *meta_type = createMetaType(); meta_type->setTypeEntry(type); meta_type->setIndirections(typeInfo.indirections); meta_type->setReference(typeInfo.is_reference); meta_type->setConstant(typeInfo.is_constant); meta_type->setOriginalTypeDescription(_typei.toString()); decideUsagePattern(meta_type); if (meta_type->typeEntry()->isContainer()) { ContainerTypeEntry::Type container_type = static_cast(type)->type(); if (container_type == ContainerTypeEntry::StringListContainer) { TypeInfo info; info.setQualifiedName(QStringList() << "QString"); AbstractMetaType *targ_type = translateType(info, ok); Q_ASSERT(*ok); Q_ASSERT(targ_type); meta_type->addInstantiation(targ_type); meta_type->setInstantiationInCpp(false); } else { foreach (const TypeParser::Info &ta, typeInfo.template_instantiations) { TypeInfo info; info.setConstant(ta.is_constant); info.setReference(ta.is_reference); info.setIndirections(ta.indirections); info.setFunctionPointer(false); info.setQualifiedName(ta.instantiationName().split("::")); AbstractMetaType *targ_type = translateType(info, ok); if (!(*ok)) { delete meta_type; return 0; } meta_type->addInstantiation(targ_type); } } if (container_type == ContainerTypeEntry::ListContainer || container_type == ContainerTypeEntry::VectorContainer || container_type == ContainerTypeEntry::StringListContainer) { Q_ASSERT(meta_type->instantiations().size() == 1); } } return meta_type; } void AbstractMetaBuilder::decideUsagePattern(AbstractMetaType *meta_type) { const TypeEntry *type = meta_type->typeEntry(); if (type->isPrimitive() && (meta_type->actualIndirections() == 0 || (meta_type->isConstant() && meta_type->isReference() && meta_type->indirections() == 0))) { meta_type->setTypeUsagePattern(AbstractMetaType::PrimitivePattern); } else if (type->isVoid()) { meta_type->setTypeUsagePattern(AbstractMetaType::NativePointerPattern); } else if (type->isString() && meta_type->indirections() == 0 && (meta_type->isConstant() == meta_type->isReference() || meta_type->isConstant())) { meta_type->setTypeUsagePattern(AbstractMetaType::StringPattern); } else if (type->isChar() && meta_type->indirections() == 0 && meta_type->isConstant() == meta_type->isReference()) { meta_type->setTypeUsagePattern(AbstractMetaType::CharPattern); } else if (type->isJObjectWrapper() && meta_type->indirections() == 0 && meta_type->isConstant() == meta_type->isReference()) { meta_type->setTypeUsagePattern(AbstractMetaType::JObjectWrapperPattern); } else if (type->isVariant() && meta_type->indirections() == 0 && meta_type->isConstant() == meta_type->isReference()) { meta_type->setTypeUsagePattern(AbstractMetaType::VariantPattern); } else if (type->isEnum() && meta_type->actualIndirections() == 0) { meta_type->setTypeUsagePattern(AbstractMetaType::EnumPattern); } else if (type->isObject() && meta_type->indirections() == 0 && meta_type->isReference()) { if (((ComplexTypeEntry *) type)->isQObject()) meta_type->setTypeUsagePattern(AbstractMetaType::QObjectPattern); else meta_type->setTypeUsagePattern(AbstractMetaType::ObjectPattern); } else if (type->isObject() && meta_type->indirections() == 1) { if (((ComplexTypeEntry *) type)->isQObject()) meta_type->setTypeUsagePattern(AbstractMetaType::QObjectPattern); else meta_type->setTypeUsagePattern(AbstractMetaType::ObjectPattern); // const-references to pointers can be passed as pointers if (meta_type->isReference() && meta_type->isConstant()) { meta_type->setReference(false); meta_type->setConstant(false); } } else if (type->isContainer() && meta_type->indirections() == 0) { meta_type->setTypeUsagePattern(AbstractMetaType::ContainerPattern); } else if (type->isTemplateArgument()) { } else if (type->isFlags() && meta_type->indirections() == 0 && (meta_type->isConstant() == meta_type->isReference())) { meta_type->setTypeUsagePattern(AbstractMetaType::FlagsPattern); } else if (type->isArray()) { meta_type->setTypeUsagePattern(AbstractMetaType::ArrayPattern); } else if (type->isThread()) { Q_ASSERT(meta_type->indirections() == 1); meta_type->setTypeUsagePattern(AbstractMetaType::ThreadPattern); } else if (type->isValue() && meta_type->indirections() == 0 && (meta_type->isConstant() == meta_type->isReference() || !meta_type->isReference())) { meta_type->setTypeUsagePattern(AbstractMetaType::ValuePattern); } else { meta_type->setTypeUsagePattern(AbstractMetaType::NativePointerPattern); ReportHandler::debugFull(QString("native pointer pattern for '%1'") .arg(meta_type->cppSignature())); } } QString AbstractMetaBuilder::translateDefaultValue(ArgumentModelItem item, AbstractMetaType *type, AbstractMetaFunction *fnc, AbstractMetaClass *implementing_class, int argument_index) { QString function_name = fnc->name(); QString class_name = implementing_class->name(); QString replaced_expression = fnc->replacedDefaultExpression(implementing_class, argument_index + 1); if (fnc->removedDefaultExpression(implementing_class, argument_index +1)) return ""; if (!replaced_expression.isEmpty()) return replaced_expression; QString expr = item->defaultValueExpression(); if (type != 0 && type->isPrimitive()) { if (type->name() == "boolean") { if (expr == "false" || expr=="true") { return expr; } else { bool ok = false; int number = expr.toInt(&ok); if (ok && number) return "true"; else return "false"; } } else if (expr == "ULONG_MAX") { return "Long.MAX_VALUE"; } else if (expr == "QVariant::Invalid") { return QString::number(QVariant::Invalid); } else { // This can be an enum or flag so I need to delay the // translation untill all namespaces are completly // processed. This is done in figureOutEnumValues() return expr; } } else if (type != 0 && (type->isFlags() || type->isEnum())) { // Same as with enum explanation above... return expr; } else { // constructor or functioncall can be a bit tricky... if (expr == "QVariant()" || expr == "QModelIndex()") { return "null"; } else if (expr == "QString()") { return "null"; } else if (expr.endsWith(")") && expr.contains("::")) { TypeEntry *typeEntry = TypeDatabase::instance()->findType(expr.left(expr.indexOf("::"))); if (typeEntry) return typeEntry->qualifiedTargetLangName() + "." + expr.right(expr.length() - expr.indexOf("::") - 2); } else if (expr.endsWith(")") && type != 0 && type->isValue()) { int pos = expr.indexOf("("); TypeEntry *typeEntry = TypeDatabase::instance()->findType(expr.left(pos)); if (typeEntry) return "new " + typeEntry->qualifiedTargetLangName() + expr.right(expr.length() - pos); else return expr; } else if (expr == "0") { return "null"; } else if (type != 0 && (type->isObject() || type->isValue() || expr.contains("::"))) { // like Qt::black passed to a QColor TypeEntry *typeEntry = TypeDatabase::instance()->findType(expr.left(expr.indexOf("::"))); expr = expr.right(expr.length() - expr.indexOf("::") - 2); if (typeEntry) { return "new " + type->typeEntry()->qualifiedTargetLangName() + "(" + typeEntry->qualifiedTargetLangName() + "." + expr + ")"; } } } QString warn = QString("unsupported default value '%3' of argument in function '%1', class '%2'") .arg(function_name).arg(class_name).arg(item->defaultValueExpression()); ReportHandler::warning(warn); return QString(); } bool AbstractMetaBuilder::isQObject(const QString &qualified_name) { if (qualified_name == "QObject") return true; ClassModelItem class_item = m_dom->findClass(qualified_name); if (!class_item) { QStringList names = qualified_name.split(QLatin1String("::")); NamespaceModelItem ns = model_dynamic_cast(m_dom); for (int i=0; inamespaceMap().value(names.at(i)); if (ns && names.size() >= 2) class_item = ns->findClass(names.at(names.size() - 1)); } bool isqobject = class_item && class_item->extendsClass("QObject"); if (class_item && !isqobject) { QStringList baseClasses = class_item->baseClasses(); for (int i=0; imodel()->findItem(qualified_name, m_dom->toItem()); return item && item->kind() == _EnumModelItem::__node_kind; } AbstractMetaType *AbstractMetaBuilder::inheritTemplateType(const QList &template_types, AbstractMetaType *meta_type, bool *ok) { if (ok != 0) *ok = true; if (!meta_type || (!meta_type->typeEntry()->isTemplateArgument() && !meta_type->hasInstantiations())) return meta_type ? meta_type->copy() : 0; AbstractMetaType *returned = meta_type->copy(); returned->setOriginalTemplateType(meta_type->copy()); if (returned->typeEntry()->isTemplateArgument()) { const TemplateArgumentEntry *tae = static_cast(returned->typeEntry()); // If the template is intantiated with void we special case this as rejecting the functions that use this // parameter from the instantiation. if (template_types.size() <= tae->ordinal() || template_types.at(tae->ordinal())->typeEntry()->name() == "void") { if (ok != 0) *ok = false; return 0; } AbstractMetaType *t = returned->copy(); t->setTypeEntry(template_types.at(tae->ordinal())->typeEntry()); t->setIndirections(template_types.at(tae->ordinal())->indirections() + t->indirections() ? 1 : 0); decideUsagePattern(t); delete returned; returned = inheritTemplateType(template_types, t, ok); if (ok != 0 && !(*ok)) return 0; } if (returned->hasInstantiations()) { QList instantiations = returned->instantiations(); for (int i=0; isetInstantiations(instantiations); } return returned; } bool AbstractMetaBuilder::inheritTemplate(AbstractMetaClass *subclass, const AbstractMetaClass *template_class, const TypeParser::Info &info) { QList targs = info.template_instantiations; QList template_types; foreach (const TypeParser::Info &i, targs) { TypeEntry *t = TypeDatabase::instance()->findType(i.qualified_name.join("::")); if (t != 0) { AbstractMetaType *temporary_type = createMetaType(); temporary_type->setTypeEntry(t); temporary_type->setConstant(i.is_constant); temporary_type->setReference(i.is_reference); temporary_type->setIndirections(i.indirections); template_types << temporary_type; } } AbstractMetaFunctionList funcs = subclass->functions(); foreach (const AbstractMetaFunction *function, template_class->functions()) { if (function->isModifiedRemoved(TypeSystem::All)) continue; AbstractMetaFunction *f = function->copy(); f->setArguments(AbstractMetaArgumentList()); bool ok = true; AbstractMetaType *ftype = function->type(); f->setType(inheritTemplateType(template_types, ftype, &ok)); if (!ok) { delete f; continue; } foreach (AbstractMetaArgument *argument, function->arguments()) { AbstractMetaType *atype = argument->type(); AbstractMetaArgument *arg = argument->copy(); arg->setType(inheritTemplateType(template_types, atype, &ok)); if (!ok) break; f->addArgument(arg); } if (!ok) { delete f; continue ; } // There is no base class in java to inherit from here, so the // template instantiation is the class that implements the function.. f->setImplementingClass(subclass); // We also set it as the declaring class, since the superclass is // supposed to disappear. This allows us to make certain function modifications // on the inherited functions. f->setDeclaringClass(subclass); if (f->isConstructor() && subclass->isTypeAlias()) { f->setName(subclass->name()); } else if (f->isConstructor()) { delete f; continue; } // if the instantiation has a function named the same as an existing // function we have shadowing so we need to skip it. bool found = false; for (int i=0; iname() == f->name()) { found = true; continue; } } if (found) { delete f; continue; } ComplexTypeEntry *te = subclass->typeEntry(); FunctionModificationList mods = function->modifications(template_class); for (int i=0; iminimalSignature(); // If we ever need it... Below is the code to do // substitution of the template instantation type inside // injected code.. #if 0 if (mod.modifiers & Modification::CodeInjection) { for (int j=0; jtypeEntry()->qualifiedCppName()); snip.codeList.clear(); snip.addCode(code); } } #endif te->addFunctionModification(mod); } subclass->addFunction(f); } // Clean up foreach (AbstractMetaType *type, template_types) { delete type; } { subclass->setTemplateBaseClass(template_class); subclass->setInterfaces(template_class->interfaces()); subclass->setBaseClass(template_class->baseClass()); } return true; } void AbstractMetaBuilder::parseQ_Property(AbstractMetaClass *meta_class, const QStringList &declarations) { for (int i=0; iqualifiedName(); bool ok = false; AbstractMetaType *type = 0; QString scope; for (int j=qualifiedScopeName.size(); j>=0; --j) { scope = j > 0 ? QStringList(qualifiedScopeName.mid(0, j)).join("::") + "::" : QString(); TypeInfo info; info.setQualifiedName((scope + l.at(0)).split("::")); type = translateType(info, &ok); if (type != 0 && ok) { break; } } if (type == 0 || !ok) { ReportHandler::warning(QString("Unable to decide type of property: '%1' in class '%2'") .arg(l.at(0)).arg(meta_class->name())); continue; } QString typeName = scope + l.at(0); QPropertySpec *spec = new QPropertySpec(type->typeEntry()); spec->setName(l.at(1)); spec->setIndex(i); for (int pos=2; pos+1setRead(l.at(pos+1)); else if (l.at(pos) == QLatin1String("WRITE")) spec->setWrite(l.at(pos+1)); else if (l.at(pos) == QLatin1String("DESIGNABLE")) spec->setDesignable(l.at(pos+1)); else if (l.at(pos) == QLatin1String("RESET")) spec->setReset(l.at(pos+1)); } meta_class->addPropertySpec(spec); delete type; } } static void hide_functions(const AbstractMetaFunctionList &l) { foreach (AbstractMetaFunction *f, l) { FunctionModification mod; mod.signature = f->minimalSignature(); mod.modifiers = FunctionModification::Private; ((ComplexTypeEntry *) f->implementingClass()->typeEntry())->addFunctionModification(mod); } } static void remove_function(AbstractMetaFunction *f) { FunctionModification mod; mod.removal = TypeSystem::All; mod.signature = f->minimalSignature(); ((ComplexTypeEntry *) f->implementingClass()->typeEntry())->addFunctionModification(mod); } static AbstractMetaFunctionList filter_functions(const AbstractMetaFunctionList &lst, QSet *signatures) { AbstractMetaFunctionList functions; foreach (AbstractMetaFunction *f, lst) { QString signature = f->minimalSignature(); int start = signature.indexOf(QLatin1Char('(')) + 1; int end = signature.lastIndexOf(QLatin1Char(')')); signature = signature.mid(start, end - start); if (signatures->contains(signature)) { remove_function(f); continue; } (*signatures) << signature; functions << f; } return functions; } void AbstractMetaBuilder::setupEquals(AbstractMetaClass *cls) { AbstractMetaFunctionList equals; AbstractMetaFunctionList nequals; QString op_equals = QLatin1String("operator_equal"); QString op_nequals = QLatin1String("operator_not_equal"); AbstractMetaFunctionList functions = cls->queryFunctions(AbstractMetaClass::ClassImplements | AbstractMetaClass::NotRemovedFromTargetLang); foreach (AbstractMetaFunction *f, functions) { if (f->name() == op_equals) equals << f; else if (f->name() == op_nequals) nequals << f; } if (equals.size() || nequals.size()) { if (!cls->hasHashFunction()) { ReportHandler::warning(QString::fromLatin1("Class '%1' has equals operators but no qHash() function") .arg(cls->name())); } hide_functions(equals); hide_functions(nequals); // We only need == if we have both == and !=, and one == for // each signature type, like QDateTime::==(QDate) and (QTime) // if such a thing exists... QSet func_signatures; cls->setEqualsFunctions(filter_functions(equals, &func_signatures)); cls->setNotEqualsFunctions(filter_functions(nequals, &func_signatures)); } } void AbstractMetaBuilder::setupComparable(AbstractMetaClass *cls) { AbstractMetaFunctionList greater; AbstractMetaFunctionList greaterEquals; AbstractMetaFunctionList less; AbstractMetaFunctionList lessEquals; QString op_greater = QLatin1String("operator_greater"); QString op_greater_eq = QLatin1String("operator_greater_or_equal"); QString op_less = QLatin1String("operator_less"); QString op_less_eq = QLatin1String("operator_less_or_equal"); AbstractMetaFunctionList functions = cls->queryFunctions(AbstractMetaClass::ClassImplements | AbstractMetaClass::NotRemovedFromTargetLang); foreach (AbstractMetaFunction *f, functions) { if (f->name() == op_greater) greater << f; else if (f->name() == op_greater_eq) greaterEquals << f; else if (f->name() == op_less) less << f; else if (f->name() == op_less_eq) lessEquals << f; } bool hasEquals = cls->equalsFunctions().size() || cls->notEqualsFunctions().size(); // Conditions for comparable is: // >, ==, < - The basic case // >, == - Less than becomes else case // <, == - Greater than becomes else case // >=, <= - if (<= && >=) -> equal bool mightBeComparable = greater.size() || greaterEquals.size() || less.size() || lessEquals.size() || greaterEquals.size() == 1 || lessEquals.size() == 1; if (mightBeComparable) { QSet signatures; // We only hide the original functions if we are able to make a compareTo() method bool wasComparable = false; // The three upper cases, prefer the <, == approach if (hasEquals && (greater.size() || less.size())) { cls->setLessThanFunctions(filter_functions(less, &signatures)); cls->setGreaterThanFunctions(filter_functions(greater, &signatures)); filter_functions(greaterEquals, &signatures); filter_functions(lessEquals, &signatures); wasComparable = true; } else if (hasEquals && (greaterEquals.size() || lessEquals.size())) { cls->setLessThanEqFunctions(filter_functions(lessEquals, &signatures)); cls->setGreaterThanEqFunctions(filter_functions(greaterEquals, &signatures)); wasComparable = true; } else if (greaterEquals.size() == 1 || lessEquals.size() == 1) { cls->setGreaterThanEqFunctions(greaterEquals); cls->setLessThanEqFunctions(lessEquals); filter_functions(less, &signatures); filter_functions(greater, &signatures); wasComparable = true; } if (wasComparable) { hide_functions(greater); hide_functions(greaterEquals); hide_functions(less); hide_functions(lessEquals); } } } void AbstractMetaBuilder::setupClonable(AbstractMetaClass *cls) { QString op_assign = QLatin1String("operator_assign"); AbstractMetaFunctionList functions = cls->queryFunctions(AbstractMetaClass::ClassImplements); foreach (AbstractMetaFunction *f, functions) { if ((f->name() == op_assign || f->isConstructor()) && f->isPublic()) { AbstractMetaArgumentList arguments = f->arguments(); if (arguments.size() == 1) { if (cls->typeEntry()->qualifiedCppName() == arguments.at(0)->type()->typeEntry()->qualifiedCppName()) { if (cls->typeEntry()->isValue()) { cls->setHasCloneOperator(true); return; } } } } } } static void write_reject_log_file(const QString &name, const QMap &rejects) { QFile f(name); if (!f.open(QIODevice::WriteOnly | QIODevice::Text)) { ReportHandler::warning(QString("failed to write log file: '%1'") .arg(f.fileName())); return; } QTextStream s(&f); for (int reason=0; reason::const_iterator it = rejects.constBegin(); it != rejects.constEnd(); ++it) { if (it.value() != reason) continue; s << " - " << it.key() << endl; } s << QString(72, '*') << endl << endl; } } void AbstractMetaBuilder::dumpLog() { write_reject_log_file("mjb_rejected_classes.log", m_rejected_classes); write_reject_log_file("mjb_rejected_enums.log", m_rejected_enums); write_reject_log_file("mjb_rejected_functions.log", m_rejected_functions); write_reject_log_file("mjb_rejected_fields.log", m_rejected_fields); } AbstractMetaClassList AbstractMetaBuilder::classesTopologicalSorted() const { AbstractMetaClassList res; AbstractMetaClassList classes = m_meta_classes; qSort(classes); QSet noDependency; QHash* > hash; foreach (AbstractMetaClass *cls, classes) { QSet *depends = new QSet(); if (cls->baseClass()) depends->insert(cls->baseClass()); foreach (AbstractMetaClass *interface, cls->interfaces()) { AbstractMetaClass *impl = interface->primaryInterfaceImplementor(); if (impl == cls) continue; depends->insert(impl); } if (depends->empty()) { noDependency.insert(cls); } else { hash.insert(cls, depends); } } while (!noDependency.empty()) { foreach (AbstractMetaClass *cls, noDependency.values()) { if(!cls->isInterface()) res.append(cls); noDependency.remove(cls); QHashIterator* > i(hash); while (i.hasNext()) { i.next(); i.value()->remove(cls); if (i.value()->empty()) { AbstractMetaClass *key = i.key(); noDependency.insert(key); hash.remove(key); delete(i.value()); } } } } if (!noDependency.empty() || !hash.empty()) { qWarning("dependency graph was cyclic."); } return res; } qtscriptgenerator-src-0.2.0/generator/abstractmetabuilder.h000066400000000000000000000152071170724227300242500ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef ABSTRACTMETABUILDER_H #define ABSTRACTMETABUILDER_H #include "codemodel.h" #include "abstractmetalang.h" #include "typesystem.h" #include "typeparser.h" #include class AbstractMetaBuilder { public: enum RejectReason { NotInTypeSystem, GenerationDisabled, RedefinedToNotClass, UnmatchedArgumentType, UnmatchedReturnType, NoReason }; AbstractMetaBuilder(); virtual ~AbstractMetaBuilder() {}; AbstractMetaClassList classes() const { return m_meta_classes; } AbstractMetaClassList classesTopologicalSorted() const; FileModelItem model() const { return m_dom; } void setModel(FileModelItem item) { m_dom = item; } ScopeModelItem popScope() { return m_scopes.takeLast(); } void pushScope(ScopeModelItem item) { m_scopes << item; } ScopeModelItem currentScope() const { return m_scopes.last(); } QString fileName() const { return m_file_name; } void setFileName(const QString &fileName) { m_file_name = fileName; } void dumpLog(); bool build(); void figureOutEnumValuesForClass(AbstractMetaClass *meta_class, QSet *classes); int figureOutEnumValue(const QString &name, int value, AbstractMetaEnum *meta_enum, AbstractMetaFunction *meta_function = 0); void figureOutEnumValues(); void figureOutDefaultEnumArguments(); void addAbstractMetaClass(AbstractMetaClass *cls); AbstractMetaClass *traverseTypeAlias(TypeAliasModelItem item); AbstractMetaClass *traverseClass(ClassModelItem item); bool setupInheritance(AbstractMetaClass *meta_class); AbstractMetaClass *traverseNamespace(NamespaceModelItem item); AbstractMetaEnum *traverseEnum(EnumModelItem item, AbstractMetaClass *enclosing, const QSet &enumsDeclarations); void traverseEnums(ScopeModelItem item, AbstractMetaClass *parent, const QStringList &enumsDeclarations); void traverseFunctions(ScopeModelItem item, AbstractMetaClass *parent); void traverseFields(ScopeModelItem item, AbstractMetaClass *parent); void traverseStreamOperator(FunctionModelItem function_item); void traverseCompareOperator(FunctionModelItem item); AbstractMetaFunction *traverseFunction(FunctionModelItem function); AbstractMetaField *traverseField(VariableModelItem field, const AbstractMetaClass *cls); void checkFunctionModifications(); void registerHashFunction(FunctionModelItem function_item); void registerToStringCapability(FunctionModelItem function_item); void parseQ_Property(AbstractMetaClass *meta_class, const QStringList &declarations); void setupEquals(AbstractMetaClass *meta_class); void setupComparable(AbstractMetaClass *meta_class); void setupClonable(AbstractMetaClass *cls); void setupFunctionDefaults(AbstractMetaFunction *meta_function, AbstractMetaClass *meta_class); QString translateDefaultValue(ArgumentModelItem item, AbstractMetaType *type, AbstractMetaFunction *fnc, AbstractMetaClass *, int argument_index); AbstractMetaType *translateType(const TypeInfo &type, bool *ok, bool resolveType = true, bool resolveScope = true); void decideUsagePattern(AbstractMetaType *type); bool inheritTemplate(AbstractMetaClass *subclass, const AbstractMetaClass *template_class, const TypeParser::Info &info); AbstractMetaType *inheritTemplateType(const QList &template_types, AbstractMetaType *meta_type, bool *ok = 0); bool isQObject(const QString &qualified_name); bool isEnum(const QStringList &qualified_name); void fixQObjectForScope (TypeDatabase *types, NamespaceModelItem item); // QtScript QSet qtMetaTypeDeclaredTypeNames() const { return m_qmetatype_declared_typenames; } protected: AbstractMetaClass *argumentToClass(ArgumentModelItem); virtual AbstractMetaClass *createMetaClass() = 0; virtual AbstractMetaEnum *createMetaEnum() = 0; virtual AbstractMetaEnumValue *createMetaEnumValue() = 0; virtual AbstractMetaField *createMetaField() = 0; virtual AbstractMetaFunction *createMetaFunction() = 0; virtual AbstractMetaArgument *createMetaArgument() = 0; virtual AbstractMetaType *createMetaType() = 0; private: void sortLists(); QString m_file_name; AbstractMetaClassList m_meta_classes; AbstractMetaClassList m_templates; FileModelItem m_dom; QSet m_used_types; QMap m_rejected_classes; QMap m_rejected_enums; QMap m_rejected_functions; QMap m_rejected_fields; QList m_enums; QList > m_enum_default_arguments; QHash m_enum_values; AbstractMetaClass *m_current_class; QList m_scopes; QString m_namespace_prefix; QSet m_setup_inheritance_done; // QtScript QSet m_qmetatype_declared_typenames; }; #endif // ABSTRACTMETBUILDER_H qtscriptgenerator-src-0.2.0/generator/abstractmetalang.cpp000066400000000000000000002004731170724227300240770ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "abstractmetalang.h" #include "reporthandler.h" /******************************************************************************* * AbstractMetaType */ AbstractMetaType *AbstractMetaType::copy() const { AbstractMetaType *cpy = new AbstractMetaType; cpy->setTypeUsagePattern(typeUsagePattern()); cpy->setConstant(isConstant()); cpy->setReference(isReference()); cpy->setIndirections(indirections()); cpy->setInstantiations(instantiations()); cpy->setArrayElementCount(arrayElementCount()); cpy->setOriginalTypeDescription(originalTypeDescription()); cpy->setOriginalTemplateType(originalTemplateType() ? originalTemplateType()->copy() : 0); cpy->setArrayElementType(arrayElementType() ? arrayElementType()->copy() : 0); cpy->setTypeEntry(typeEntry()); return cpy; } QString AbstractMetaType::cppSignature() const { QString s; if (isConstant()) s += "const "; s += typeEntry()->qualifiedCppName(); if (hasInstantiationInCpp()) { QList types = instantiations(); s += "<"; for (int i=0; i 0) s += ", "; s += types.at(i)->cppSignature(); } s += " >"; } if (actualIndirections()) { s += ' '; if (indirections()) s += QString(indirections(), '*'); if (isReference()) s += '&'; } return s; } /******************************************************************************* * AbstractMetaArgument */ AbstractMetaArgument *AbstractMetaArgument::copy() const { AbstractMetaArgument *cpy = new AbstractMetaArgument; cpy->setName(AbstractMetaVariable::name()); cpy->setDefaultValueExpression(defaultValueExpression()); cpy->setType(type()->copy()); cpy->setArgumentIndex(argumentIndex()); return cpy; } QString AbstractMetaArgument::argumentName() const { QString n = AbstractMetaVariable::name(); if (n.isEmpty()) { return QString("arg__%2").arg(m_argument_index + 1); } return n; } QString AbstractMetaArgument::indexedName() const { QString n = AbstractMetaVariable::name(); if (n.isEmpty()) return argumentName(); return QString("%1%2").arg(n).arg(m_argument_index); } QString AbstractMetaArgument::name() const { Q_ASSERT_X(0, "AbstractMetaArgument::name()", "use argumentName() or indexedName() instead"); return QString(); } /******************************************************************************* * AbstractMetaFunction */ AbstractMetaFunction::~AbstractMetaFunction() { qDeleteAll(m_arguments); delete m_type; } /******************************************************************************* * Indicates that this function has a modification that removes it */ bool AbstractMetaFunction::isModifiedRemoved(int types) const { FunctionModificationList mods = modifications(implementingClass()); foreach (FunctionModification mod, mods) { if (!mod.isRemoveModifier()) continue; if ((mod.removal & types) == types) return true; } return false; } bool AbstractMetaFunction::needsCallThrough() const { if (ownerClass()->isInterface()) return false; if (referenceCounts(implementingClass()).size() > 0) return true; if (argumentsHaveNativeId() || !isStatic()) return true; foreach (const AbstractMetaArgument *arg, arguments()) { if (arg->type()->isArray() || arg->type()->isTargetLangEnum() || arg->type()->isTargetLangFlags()) return true; } if (type() && (type()->isArray() || type()->isTargetLangEnum() || type()->isTargetLangFlags())) return true; for (int i=-1; i<=arguments().size(); ++i) { TypeSystem::Ownership owner = this->ownership(implementingClass(), TypeSystem::TargetLangCode, i); if (owner != TypeSystem::InvalidOwnership) return true; } return false; } bool AbstractMetaFunction::needsSuppressUncheckedWarning() const { for (int i=-1; i<=arguments().size(); ++i) { QList referenceCounts = this->referenceCounts(implementingClass(), i); foreach (ReferenceCount referenceCount, referenceCounts) { if (referenceCount.action != ReferenceCount::Set) return true; } } return false; } QString AbstractMetaFunction::marshalledName() const { QString returned = "__qt_" + name(); AbstractMetaArgumentList arguments = this->arguments(); foreach (const AbstractMetaArgument *arg, arguments) { returned += "_"; if (arg->type()->isNativePointer()) { returned += "nativepointer"; } else if (arg->type()->isIntegerEnum() || arg->type()->isIntegerFlags()) { returned += "int"; } else { returned += arg->type()->name().replace("[]", "_3").replace(".", "_"); } } return returned; } bool AbstractMetaFunction::operator<(const AbstractMetaFunction &other) const { uint result = compareTo(&other); return result & NameLessThan; } /*! Returns a mask of CompareResult describing how this function is compares to another function */ uint AbstractMetaFunction::compareTo(const AbstractMetaFunction *other) const { uint result = 0; // Enclosing class... if (ownerClass() == other->ownerClass()) { result |= EqualImplementor; } // Attributes if (attributes() == other->attributes()) { result |= EqualAttributes; } // Compare types AbstractMetaType *t = type(); AbstractMetaType *ot = other->type(); if ((!t && !ot) || ((t && ot && t->name() == ot->name()))) { result |= EqualReturnType; } // Compare names int cmp = originalName().compare(other->originalName()); if (cmp < 0) { result |= NameLessThan; } else if (cmp == 0) { result |= EqualName; } // compare name after modification... cmp = modifiedName().compare(other->modifiedName()); if (cmp == 0) result |= EqualModifiedName; // Compare arguments... AbstractMetaArgumentList min_arguments; AbstractMetaArgumentList max_arguments; if (arguments().size() < other->arguments().size()) { min_arguments = arguments(); max_arguments = other->arguments(); } else { min_arguments = other->arguments(); max_arguments = arguments(); } int min_count = min_arguments.size(); int max_count = max_arguments.size(); bool same = true; for (int i=0; itype()->name() != max_arg->type()->name() && (min_arg->defaultValueExpression().isEmpty() || max_arg->defaultValueExpression().isEmpty())) { same = false; break; } } else { if (max_arguments.at(i)->defaultValueExpression().isEmpty()) { same = false; break; } } } if (same) result |= min_count == max_count ? EqualArguments : EqualDefaultValueOverload; return result; } AbstractMetaFunction *AbstractMetaFunction::copy() const { AbstractMetaFunction *cpy = new AbstractMetaFunction; cpy->setName(name()); cpy->setOriginalName(originalName()); cpy->setOwnerClass(ownerClass()); cpy->setImplementingClass(implementingClass()); cpy->setInterfaceClass(interfaceClass()); cpy->setFunctionType(functionType()); cpy->setAttributes(attributes()); cpy->setDeclaringClass(declaringClass()); if (type()) cpy->setType(type()->copy()); cpy->setConstant(isConstant()); cpy->setException(exception()); cpy->setOriginalAttributes(originalAttributes()); foreach (AbstractMetaArgument *arg, arguments()) cpy->addArgument(arg->copy()); Q_ASSERT((!type() && !cpy->type()) || (type()->instantiations() == cpy->type()->instantiations())); return cpy; } QStringList AbstractMetaFunction::introspectionCompatibleSignatures(const QStringList &resolvedArguments) const { AbstractMetaArgumentList arguments = this->arguments(); if (arguments.size() == resolvedArguments.size()) { return (QStringList() << QMetaObject::normalizedSignature((name() + "(" + resolvedArguments.join(",") + ")").toUtf8().constData())); } else { QStringList returned; AbstractMetaArgument *argument = arguments.at(resolvedArguments.size()); QStringList minimalTypeSignature = argument->type()->minimalSignature().split("::"); for (int i=0; i 0) s += ", "; AbstractMetaArgument *a = m_arguments.at(i); s += a->type()->cppSignature(); // We need to have the argument names in the qdoc files s += " "; s += a->argumentName(); } s += ")"; if (isConstant()) s += " const"; return s; } int AbstractMetaFunction::actualMinimumArgumentCount() const { AbstractMetaArgumentList arguments = this->arguments(); int count = 0; for (int i=0; idefaultValueExpression().isEmpty()) break; } return count; } // Returns reference counts for argument at idx, or all arguments if idx == -2 QList AbstractMetaFunction::referenceCounts(const AbstractMetaClass *cls, int idx) const { QList returned; FunctionModificationList mods = this->modifications(cls); foreach (FunctionModification mod, mods) { QList argument_mods = mod.argument_mods; foreach (ArgumentModification argument_mod, argument_mods) { if (argument_mod.index != idx && idx != -2) continue; returned += argument_mod.referenceCounts; } } return returned; } QString AbstractMetaFunction::replacedDefaultExpression(const AbstractMetaClass *cls, int key) const { FunctionModificationList modifications = this->modifications(cls); foreach (FunctionModification modification, modifications) { QList argument_modifications = modification.argument_mods; foreach (ArgumentModification argument_modification, argument_modifications) { if (argument_modification.index == key && !argument_modification.replaced_default_expression.isEmpty()) { return argument_modification.replaced_default_expression; } } } return QString(); } bool AbstractMetaFunction::removedDefaultExpression(const AbstractMetaClass *cls, int key) const { FunctionModificationList modifications = this->modifications(cls); foreach (FunctionModification modification, modifications) { QList argument_modifications = modification.argument_mods; foreach (ArgumentModification argument_modification, argument_modifications) { if (argument_modification.index == key && argument_modification.removed_default_expression) { return true; } } } return false; } bool AbstractMetaFunction::resetObjectAfterUse(int argument_idx) const { const AbstractMetaClass *cls = declaringClass(); FunctionModificationList modifications = this->modifications(cls); foreach (FunctionModification modification, modifications) { QList argumentModifications = modification.argument_mods; foreach (ArgumentModification argumentModification, argumentModifications) { if (argumentModification.index == argument_idx && argumentModification.reset_after_use) return true; } } return false; } QString AbstractMetaFunction::nullPointerDefaultValue(const AbstractMetaClass *mainClass, int argument_idx) const { Q_ASSERT(nullPointersDisabled(mainClass, argument_idx)); const AbstractMetaClass *cls = mainClass; if (cls == 0) cls = implementingClass(); do { FunctionModificationList modifications = this->modifications(cls); foreach (FunctionModification modification, modifications) { QList argument_modifications = modification.argument_mods; foreach (ArgumentModification argument_modification, argument_modifications) { if (argument_modification.index == argument_idx && argument_modification.no_null_pointers) { return argument_modification.null_pointer_default_value; } } } cls = cls->baseClass(); } while (cls != 0 && mainClass == 0); // Once when mainClass != 0, or once for all base classes of implementing class return QString(); } bool AbstractMetaFunction::nullPointersDisabled(const AbstractMetaClass *mainClass, int argument_idx) const { const AbstractMetaClass *cls = mainClass; if (cls == 0) cls = implementingClass(); do { FunctionModificationList modifications = this->modifications(cls); foreach (FunctionModification modification, modifications) { QList argument_modifications = modification.argument_mods; foreach (ArgumentModification argument_modification, argument_modifications) { if (argument_modification.index == argument_idx && argument_modification.no_null_pointers) { return true; } } } cls = cls->baseClass(); } while (cls != 0 && mainClass == 0); // Once when mainClass != 0, or once for all base classes of implementing class return false; } QString AbstractMetaFunction::conversionRule(TypeSystem::Language language, int key) const { FunctionModificationList modifications = this->modifications(declaringClass()); foreach (FunctionModification modification, modifications) { QList argument_modifications = modification.argument_mods; foreach (ArgumentModification argument_modification, argument_modifications) { if (argument_modification.index != key) continue; foreach (CodeSnip snip, argument_modification.conversion_rules) { if (snip.language == language && !snip.code().isEmpty()) return snip.code(); } } } return QString(); } QString AbstractMetaFunction::argumentReplaced(int key) const { FunctionModificationList modifications = this->modifications(declaringClass()); foreach (FunctionModification modification, modifications) { QList argument_modifications = modification.argument_mods; foreach (ArgumentModification argument_modification, argument_modifications) { if (argument_modification.index == key && !argument_modification.replace_value.isEmpty()) { return argument_modification.replace_value; } } } return ""; } bool AbstractMetaFunction::argumentRemoved(int key) const { FunctionModificationList modifications = this->modifications(declaringClass()); foreach (FunctionModification modification, modifications) { QList argument_modifications = modification.argument_mods; foreach (ArgumentModification argument_modification, argument_modifications) { if (argument_modification.index == key) { if (argument_modification.removed) { return true; } } } } return false; } bool AbstractMetaFunction::isVirtualSlot() const { FunctionModificationList modifications = this->modifications(declaringClass()); foreach (FunctionModification modification, modifications) { if (modification.isVirtualSlot()) return true; } return false; } bool AbstractMetaFunction::disabledGarbageCollection(const AbstractMetaClass *cls, int key) const { FunctionModificationList modifications = this->modifications(cls); foreach (FunctionModification modification, modifications) { QList argument_modifications = modification.argument_mods; foreach (ArgumentModification argument_modification, argument_modifications) { if (argument_modification.index != key) continue; foreach (TypeSystem::Ownership ownership, argument_modification.ownerships.values()) { if (ownership == TypeSystem::CppOwnership) return true; } } } return false; } bool AbstractMetaFunction::isDeprecated() const { FunctionModificationList modifications = this->modifications(declaringClass()); foreach (FunctionModification modification, modifications) { if (modification.isDeprecated()) return true; } return false; } TypeSystem::Ownership AbstractMetaFunction::ownership(const AbstractMetaClass *cls, TypeSystem::Language language, int key) const { FunctionModificationList modifications = this->modifications(cls); foreach (FunctionModification modification, modifications) { QList argument_modifications = modification.argument_mods; foreach (ArgumentModification argument_modification, argument_modifications) { if (argument_modification.index == key) return argument_modification.ownerships.value(language, TypeSystem::InvalidOwnership); } } return TypeSystem::InvalidOwnership; } bool AbstractMetaFunction::isRemovedFromAllLanguages(const AbstractMetaClass *cls) const { return isRemovedFrom(cls, TypeSystem::All); } bool AbstractMetaFunction::isRemovedFrom(const AbstractMetaClass *cls, TypeSystem::Language language) const { FunctionModificationList modifications = this->modifications(cls); foreach (FunctionModification modification, modifications) { if ((modification.removal & language) == language) return true; } return false; } QString AbstractMetaFunction::typeReplaced(int key) const { FunctionModificationList modifications = this->modifications(declaringClass()); foreach (FunctionModification modification, modifications) { QList argument_modifications = modification.argument_mods; foreach (ArgumentModification argument_modification, argument_modifications) { if (argument_modification.index == key && !argument_modification.modified_type.isEmpty()) { return argument_modification.modified_type; } } } return QString(); } QString AbstractMetaFunction::minimalSignature() const { if (!m_cached_minimal_signature.isEmpty()) return m_cached_minimal_signature; QString minimalSignature = originalName() + "("; AbstractMetaArgumentList arguments = this->arguments(); for (int i=0; itype(); if (i > 0) minimalSignature += ","; minimalSignature += t->minimalSignature(); } minimalSignature += ")"; if (isConstant()) minimalSignature += "const"; minimalSignature = QMetaObject::normalizedSignature(minimalSignature.toLocal8Bit().constData()); m_cached_minimal_signature = minimalSignature; return minimalSignature; } FunctionModificationList AbstractMetaFunction::modifications(const AbstractMetaClass *implementor) const { Q_ASSERT(implementor); return implementor->typeEntry()->functionModifications(minimalSignature()); } bool AbstractMetaFunction::hasModifications(const AbstractMetaClass *implementor) const { FunctionModificationList mods = modifications(implementor); return mods.count() > 0; } QString AbstractMetaFunction::modifiedName() const { if (m_cached_modified_name.isEmpty()) { FunctionModificationList mods = modifications(implementingClass()); foreach (FunctionModification mod, mods) { if (mod.isRenameModifier()) { m_cached_modified_name = mod.renamedToName; break; } } if (m_cached_modified_name.isEmpty()) m_cached_modified_name = name(); } return m_cached_modified_name; } QString AbstractMetaFunction::targetLangSignature(bool minimal) const { QString s; // Attributes... if (!minimal) { #if 0 // jambi if (isPublic()) s += "public "; else if (isProtected()) s += "protected "; else if (isPrivate()) s += "private "; // if (isNative()) s += "native "; // else if (isFinalInTargetLang()) s += "final "; else if (isAbstract()) s += "abstract "; if (isStatic()) s += "static "; #endif // Return type if (type()) s += type()->name() + " "; else s += "void "; } s += modifiedName(); s += "("; int j = 0; for (int i=0; itype()->name(); if (!minimal) { s += " "; s += m_arguments.at(i)->argumentName(); } ++j; } s += ")"; return s; } bool function_sorter(AbstractMetaFunction *a, AbstractMetaFunction *b) { return a->signature() < b->signature(); } /******************************************************************************* * AbstractMetaClass */ AbstractMetaClass::~AbstractMetaClass() { qDeleteAll(m_functions); qDeleteAll(m_fields); } /*AbstractMetaClass *AbstractMetaClass::copy() const { AbstractMetaClass *cls = new AbstractMetaClass; cls->setAttributes(attributes()); cls->setBaseClass(baseClass()); cls->setTypeEntry(typeEntry()); foreach (AbstractMetaFunction *function, functions()) { AbstractMetaFunction *copy = function->copy(); function->setImplementingClass(cls); cls->addFunction(copy); } cls->setEnums(enums()); foreach (const AbstractMetaField *field, fields()) { AbstractMetaField *copy = field->copy(); copy->setEnclosingClass(cls); cls->addField(copy); } cls->setInterfaces(interfaces()); return cls; }*/ /******************************************************************************* * Returns true if this class is a subclass of the given class */ bool AbstractMetaClass::inheritsFrom(const AbstractMetaClass *cls) const { Q_ASSERT(cls != 0); const AbstractMetaClass *clazz = this; while (clazz != 0) { if (clazz == cls) return true; clazz = clazz->baseClass(); } return false; } /******************************************************************************* * Constructs an interface based on the functions and enums in this * class and returns it... */ AbstractMetaClass *AbstractMetaClass::extractInterface() { Q_ASSERT(typeEntry()->designatedInterface()); if (m_extracted_interface == 0) { AbstractMetaClass *iface = new AbstractMetaClass; iface->setAttributes(attributes()); iface->setBaseClass(0); iface->setPrimaryInterfaceImplementor(this); iface->setTypeEntry(typeEntry()->designatedInterface()); foreach (AbstractMetaFunction *function, functions()) { if (!function->isConstructor()) iface->addFunction(function->copy()); } // iface->setEnums(enums()); // setEnums(AbstractMetaEnumList()); foreach (const AbstractMetaField *field, fields()) { if (field->isPublic()) { AbstractMetaField *new_field = field->copy(); new_field->setEnclosingClass(iface); iface->addField(new_field); } } m_extracted_interface = iface; addInterface(iface); } return m_extracted_interface; } /******************************************************************************* * Returns a list of all the functions with a given name */ AbstractMetaFunctionList AbstractMetaClass::queryFunctionsByName(const QString &name) const { AbstractMetaFunctionList returned; AbstractMetaFunctionList functions = this->functions(); foreach (AbstractMetaFunction *function, functions) { if (function->name() == name) returned.append(function); } return returned; } /******************************************************************************* * Returns all reference count modifications for any function in the class */ QList AbstractMetaClass::referenceCounts() const { QList returned; AbstractMetaFunctionList functions = this->functions(); foreach (AbstractMetaFunction *function, functions) { returned += function->referenceCounts(this); } return returned; } /******************************************************************************* * Returns a list of all the functions retrieved during parsing which should * be added to the Java API. */ AbstractMetaFunctionList AbstractMetaClass::functionsInTargetLang() const { int default_flags = NormalFunctions | Visible | NotRemovedFromTargetLang; // Interfaces don't implement functions default_flags |= isInterface() ? 0 : ClassImplements; // Only public functions in final classes // default_flags |= isFinal() ? WasPublic : 0; int public_flags = isFinal() ? WasPublic : 0; // Constructors AbstractMetaFunctionList returned = queryFunctions(Constructors | default_flags | public_flags); // Final functions returned += queryFunctions(FinalInTargetLangFunctions | NonStaticFunctions | default_flags | public_flags); // Virtual functions returned += queryFunctions(VirtualInTargetLangFunctions | NonStaticFunctions | default_flags | public_flags); // Static functions returned += queryFunctions(StaticFunctions | default_flags | public_flags); // Empty, private functions, since they aren't caught by the other ones returned += queryFunctions(Empty | Invisible); return returned; } AbstractMetaFunctionList AbstractMetaClass::virtualFunctions() const { AbstractMetaFunctionList list = functionsInShellClass(); AbstractMetaFunctionList returned; foreach (AbstractMetaFunction *f, list) { if (!f->isFinalInCpp() || f->isVirtualSlot()) returned += f; } return returned; } AbstractMetaFunctionList AbstractMetaClass::nonVirtualShellFunctions() const { AbstractMetaFunctionList list = functionsInShellClass(); AbstractMetaFunctionList returned; foreach (AbstractMetaFunction *f, list) { if (f->isFinalInCpp() && !f->isVirtualSlot()) returned += f; } return returned; } /******************************************************************************* * Returns a list of all functions that should be declared and implemented in * the shell class which is generated as a wrapper on top of the actual C++ class */ AbstractMetaFunctionList AbstractMetaClass::functionsInShellClass() const { // Only functions and only protected and public functions int default_flags = NormalFunctions | Visible | WasVisible | NotRemovedFromShell; // All virtual functions AbstractMetaFunctionList returned = queryFunctions(VirtualFunctions | default_flags); // All functions explicitly set to be implemented by the shell class // (mainly superclass functions that are hidden by other declarations) returned += queryFunctions(ForcedShellFunctions | default_flags); // All functions explicitly set to be virtual slots returned += queryFunctions(VirtualSlots | default_flags); return returned; } /******************************************************************************* * Returns a list of all functions that require a public override function to * be generated in the shell class. This includes all functions that were originally * protected in the superclass. */ AbstractMetaFunctionList AbstractMetaClass::publicOverrideFunctions() const { return queryFunctions(NormalFunctions | WasProtected | FinalInCppFunctions | NotRemovedFromTargetLang) + queryFunctions(Signals | WasProtected | FinalInCppFunctions | NotRemovedFromTargetLang); } AbstractMetaFunctionList AbstractMetaClass::virtualOverrideFunctions() const { return queryFunctions(NormalFunctions | NonEmptyFunctions | Visible | VirtualInCppFunctions | NotRemovedFromShell) + queryFunctions(Signals | NonEmptyFunctions | Visible | VirtualInCppFunctions | NotRemovedFromShell); } void AbstractMetaClass::sortFunctions() { qSort(m_functions.begin(), m_functions.end(), function_sorter); } void AbstractMetaClass::setFunctions(const AbstractMetaFunctionList &functions) { m_functions = functions; // Functions must be sorted by name before next loop sortFunctions(); QString currentName; bool hasVirtuals = false; AbstractMetaFunctionList final_functions; foreach (AbstractMetaFunction *f, m_functions) { f->setOwnerClass(this); m_has_virtual_slots |= f->isVirtualSlot(); m_has_virtuals |= !f->isFinal() || f->isVirtualSlot(); m_has_nonpublic |= !f->isPublic(); // If we have non-virtual overloads of a virtual function, we have to implement // all the overloads in the shell class to override the hiding rule if (currentName == f->name()) { hasVirtuals = hasVirtuals || !f->isFinal(); if (f->isFinal()) final_functions += f; } else { if (hasVirtuals && final_functions.size() > 0) { foreach (AbstractMetaFunction *final_function, final_functions) { *final_function += AbstractMetaAttributes::ForceShellImplementation; QString warn = QString("hiding of function '%1' in class '%2'") .arg(final_function->name()).arg(name()); ReportHandler::warning(warn); } } hasVirtuals = !f->isFinal(); final_functions.clear(); if (f->isFinal()) final_functions += f; currentName = f->name(); } } #ifndef QT_NO_DEBUG bool duplicate_function = false; for (int j=0; jmodifications(m_functions.at(j)->implementingClass()); bool removed = false; foreach (const FunctionModification &mod, mods) { if (mod.isRemoveModifier()) { removed = true; break ; } } if (removed) continue ; for (int i=0; imodifications(m_functions.at(i)->implementingClass()); bool removed = false; foreach (const FunctionModification &mod, mods) { if (mod.isRemoveModifier()) { removed = true; break ; } } if (removed) continue ; uint cmp = m_functions.at(i)->compareTo(m_functions.at(j)); if ((cmp & AbstractMetaFunction::EqualName) && (cmp & AbstractMetaFunction::EqualArguments)) { printf("%s.%s mostly equal to %s.%s\n", qPrintable(m_functions.at(i)->implementingClass()->typeEntry()->qualifiedCppName()), qPrintable(m_functions.at(i)->signature()), qPrintable(m_functions.at(j)->implementingClass()->typeEntry()->qualifiedCppName()), qPrintable(m_functions.at(j)->signature())); duplicate_function = true; } } } //Q_ASSERT(!duplicate_function); #endif } bool AbstractMetaClass::hasFieldAccessors() const { foreach (const AbstractMetaField *field, fields()) { if (field->getter() || field->setter()) return true; } return false; } bool AbstractMetaClass::hasDefaultToStringFunction() const { foreach (AbstractMetaFunction *f, queryFunctionsByName("toString")) { if (f->actualMinimumArgumentCount() == 0) { return true; } } return false; } void AbstractMetaClass::addFunction(AbstractMetaFunction *function) { function->setOwnerClass(this); if (!function->isDestructor()) { m_functions << function; qSort(m_functions.begin(), m_functions.end(), function_sorter); } m_has_virtual_slots |= function->isVirtualSlot(); m_has_virtuals |= !function->isFinal() || function->isVirtualSlot(); m_has_nonpublic |= !function->isPublic(); } bool AbstractMetaClass::hasSignal(const AbstractMetaFunction *other) const { if (!other->isSignal()) return false; foreach (const AbstractMetaFunction *f, functions()) { if (f->isSignal() && f->compareTo(other) & AbstractMetaFunction::EqualName) return other->modifiedName() == f->modifiedName(); } return false; } QString AbstractMetaClass::name() const { return QString(m_type_entry->targetLangName()).replace("::", "_"); } bool AbstractMetaClass::hasFunction(const QString &str) const { foreach (const AbstractMetaFunction *f, functions()) if (f->name() == str) return true; return false; } /* Returns true if this class has one or more functions that are protected. If a class has protected members we need to generate a shell class with public accessors to the protected functions, so they can be called from the native functions. */ bool AbstractMetaClass::hasProtectedFunctions() const { foreach (AbstractMetaFunction *func, m_functions) { if (func->isProtected()) return true; } return false; } bool AbstractMetaClass::generateShellClass() const { return m_force_shell_class || (!isFinal() && (hasVirtualFunctions() || hasProtectedFunctions() || hasFieldAccessors())); } QPropertySpec *AbstractMetaClass::propertySpecForRead(const QString &name) const { for (int i=0; iread()) return m_property_specs.at(i); return 0; } QPropertySpec *AbstractMetaClass::propertySpecForWrite(const QString &name) const { for (int i=0; iwrite()) return m_property_specs.at(i); return 0; } QPropertySpec *AbstractMetaClass::propertySpecForReset(const QString &name) const { for (int i=0; ireset()) return m_property_specs.at(i); } return 0; } static bool functions_contains(const AbstractMetaFunctionList &l, const AbstractMetaFunction *func) { foreach (const AbstractMetaFunction *f, l) { if ((f->compareTo(func) & AbstractMetaFunction::PrettySimilar) == AbstractMetaFunction::PrettySimilar) return true; } return false; } AbstractMetaField::AbstractMetaField() : m_getter(0), m_setter(0), m_class(0) { } AbstractMetaField::~AbstractMetaField() { delete m_setter; delete m_getter; } ushort painters; // refcount AbstractMetaField *AbstractMetaField::copy() const { AbstractMetaField *returned = new AbstractMetaField; returned->setEnclosingClass(0); returned->setAttributes(attributes()); returned->setName(name()); returned->setType(type()->copy()); returned->setOriginalAttributes(originalAttributes()); return returned; } static QString upCaseFirst(const QString &str) { Q_ASSERT(!str.isEmpty()); QString s = str; s[0] = s.at(0).toUpper(); return s; } static AbstractMetaFunction *createXetter(const AbstractMetaField *g, const QString &name, uint type) { AbstractMetaFunction *f = new AbstractMetaFunction; f->setName(name); f->setOriginalName(name); f->setOwnerClass(g->enclosingClass()); f->setImplementingClass(g->enclosingClass()); f->setDeclaringClass(g->enclosingClass()); uint attr = AbstractMetaAttributes::Native | AbstractMetaAttributes::Final | type; if (g->isStatic()) attr |= AbstractMetaAttributes::Static; if (g->isPublic()) attr |= AbstractMetaAttributes::Public; else if (g->isProtected()) attr |= AbstractMetaAttributes::Protected; else attr |= AbstractMetaAttributes::Private; f->setAttributes(attr); f->setOriginalAttributes(attr); FieldModificationList mods = g->modifications(); foreach (FieldModification mod, mods) { if (mod.isRenameModifier()) f->setName(mod.renamedTo()); if (mod.isAccessModifier()) { if (mod.isPrivate()) f->setVisibility(AbstractMetaAttributes::Private); else if (mod.isProtected()) f->setVisibility(AbstractMetaAttributes::Protected); else if (mod.isPublic()) f->setVisibility(AbstractMetaAttributes::Public); else if (mod.isFriendly()) f->setVisibility(AbstractMetaAttributes::Friendly); } } return f; } FieldModificationList AbstractMetaField::modifications() const { FieldModificationList mods = enclosingClass()->typeEntry()->fieldModifications(); FieldModificationList returned; foreach (FieldModification mod, mods) { if (mod.name == name()) returned += mod; } return returned; } const AbstractMetaFunction *AbstractMetaField::setter() const { if (m_setter == 0) { m_setter = createXetter(this, "set" + upCaseFirst(name()), AbstractMetaAttributes::SetterFunction); AbstractMetaArgumentList arguments; AbstractMetaArgument *argument = new AbstractMetaArgument; argument->setType(type()->copy()); argument->setName(name()); arguments.append(argument); m_setter->setArguments(arguments); } return m_setter; } const AbstractMetaFunction *AbstractMetaField::getter() const { if (m_getter == 0) { m_getter = createXetter(this, name(), AbstractMetaAttributes::GetterFunction); m_getter->setType(type()); } return m_getter; } bool AbstractMetaClass::hasConstructors() const { return queryFunctions(Constructors).size() != 0; } void AbstractMetaClass::addDefaultConstructor() { AbstractMetaFunction *f = new AbstractMetaFunction; f->setName(name()); f->setOwnerClass(this); f->setFunctionType(AbstractMetaFunction::ConstructorFunction); f->setArguments(AbstractMetaArgumentList()); f->setDeclaringClass(this); uint attr = AbstractMetaAttributes::Native; attr |= AbstractMetaAttributes::Public; f->setAttributes(attr); f->setImplementingClass(this); f->setOriginalAttributes(f->attributes()); addFunction(f); } bool AbstractMetaClass::hasFunction(const AbstractMetaFunction *f) const { return functions_contains(m_functions, f); } /* Goes through the list of functions and returns a list of all functions matching all of the criteria in \a query. */ AbstractMetaFunctionList AbstractMetaClass::queryFunctions(uint query) const { AbstractMetaFunctionList functions; foreach (AbstractMetaFunction *f, m_functions) { if ((query & VirtualSlots) && !f->isVirtualSlot()) continue; if ((query & NotRemovedFromTargetLang) && f->isRemovedFrom(f->implementingClass(), TypeSystem::TargetLangCode)) { continue; } if ((query & NotRemovedFromTargetLang) && !f->isFinal() && f->isRemovedFrom(f->declaringClass(), TypeSystem::TargetLangCode)) { continue; } if ((query & NotRemovedFromShell) && f->isRemovedFrom(f->implementingClass(), TypeSystem::ShellCode)) { continue; } if ((query & NotRemovedFromShell) && !f->isFinal() && f->isRemovedFrom(f->declaringClass(), TypeSystem::ShellCode)) { continue; } if ((query & Visible) && f->isPrivate()) { continue; } if ((query & VirtualInTargetLangFunctions) && f->isFinalInTargetLang()) { continue; } if ((query & Invisible) && !f->isPrivate()) { continue; } if ((query & Empty) && !f->isEmptyFunction()) { continue; } if ((query & WasPublic) && !f->wasPublic()) { continue; } if ((query & WasVisible) && f->wasPrivate()) { continue; } if ((query & WasProtected) && !f->wasProtected()) { continue; } if ((query & ClassImplements) && f->ownerClass() != f->implementingClass()) { continue; } if ((query & Inconsistent) && (f->isFinalInTargetLang() || !f->isFinalInCpp() || f->isStatic())) { continue; } if ((query & FinalInTargetLangFunctions) && !f->isFinalInTargetLang()) { continue; } if ((query & FinalInCppFunctions) && !f->isFinalInCpp()) { continue; } if ((query & VirtualInCppFunctions) && f->isFinalInCpp()) { continue; } if ((query & Signals) && (!f->isSignal())) { continue; } if ((query & ForcedShellFunctions) && (!f->isForcedShellImplementation() || !f->isFinal())) { continue; } if (((query & Constructors) && (!f->isConstructor() || f->ownerClass() != f->implementingClass())) || (f->isConstructor() && (query & Constructors) == 0)) { continue; } // Destructors are never included in the functions of a class currently /* if ((query & Destructors) && (!f->isDestructor() || f->ownerClass() != f->implementingClass()) || f->isDestructor() && (query & Destructors) == 0) { continue; }*/ if ((query & VirtualFunctions) && (f->isFinal() || f->isSignal() || f->isStatic())) { continue; } if ((query & StaticFunctions) && (!f->isStatic() || f->isSignal())) { continue; } if ((query & NonStaticFunctions) && (f->isStatic())) { continue; } if ((query & NonEmptyFunctions) && (f->isEmptyFunction())) { continue; } if ((query & NormalFunctions) && (f->isSignal())) { continue; } if ((query & AbstractFunctions) && !f->isAbstract()) { continue; } functions << f; } // qDebug() << "queried" << m_type_entry->qualifiedCppName() << "got" << functions.size() << "out of" << m_functions.size(); return functions; } bool AbstractMetaClass::hasInconsistentFunctions() const { return cppInconsistentFunctions().size() > 0; } bool AbstractMetaClass::hasSignals() const { return cppSignalFunctions().size() > 0; } /** * Adds the specified interface to this class by adding all the * functions in the interface to this class. */ void AbstractMetaClass::addInterface(AbstractMetaClass *interface) { Q_ASSERT(!m_interfaces.contains(interface)); m_interfaces << interface; if (m_extracted_interface != 0 && m_extracted_interface != interface) m_extracted_interface->addInterface(interface); foreach (AbstractMetaFunction *function, interface->functions()) if (!hasFunction(function) && !function->isConstructor()) { AbstractMetaFunction *cpy = function->copy(); cpy->setImplementingClass(this); // Setup that this function is an interface class. cpy->setInterfaceClass(interface); *cpy += AbstractMetaAttributes::InterfaceFunction; // Copy the modifications in interface into the implementing classes. FunctionModificationList mods = function->modifications(interface); foreach (const FunctionModification &mod, mods) { m_type_entry->addFunctionModification(mod); } // It should be mostly safe to assume that when we implement an interface // we don't "pass on" pure virtual functions to our sublcasses... // *cpy -= AbstractMetaAttributes::Abstract; addFunction(cpy); } } void AbstractMetaClass::setInterfaces(const AbstractMetaClassList &interfaces) { m_interfaces = interfaces; } AbstractMetaEnum *AbstractMetaClass::findEnum(const QString &enumName) { foreach (AbstractMetaEnum *e, m_enums) { if (e->name() == enumName) return e; } if (typeEntry()->designatedInterface()) return extractInterface()->findEnum(enumName); return 0; } /*! Recursivly searches for the enum value named \a enumValueName in this class and its superclasses and interfaces. Values belonging to \a meta_enum are excluded from the search. */ AbstractMetaEnumValue *AbstractMetaClass::findEnumValue(const QString &enumValueName, AbstractMetaEnum *meta_enum) { foreach (AbstractMetaEnum *e, m_enums) { if (e == meta_enum) continue; foreach (AbstractMetaEnumValue *v, e->values()) { if (v->name() == enumValueName) return v; } } if (typeEntry()->designatedInterface()) return extractInterface()->findEnumValue(enumValueName, meta_enum); if (baseClass() != 0) return baseClass()->findEnumValue(enumValueName, meta_enum); return 0; } /*! * Searches through all of this class' enums for a value matching the * name \a enumValueName. The name is excluding the class/namespace * prefix. The function recursivly searches interfaces and baseclasses * of this class. */ AbstractMetaEnum *AbstractMetaClass::findEnumForValue(const QString &enumValueName) { foreach (AbstractMetaEnum *e, m_enums) { foreach (AbstractMetaEnumValue *v, e->values()) { if (v->name() == enumValueName) return e; } } if (typeEntry()->designatedInterface()) return extractInterface()->findEnumForValue(enumValueName); if (baseClass() != 0) return baseClass()->findEnumForValue(enumValueName); return 0; } static void add_extra_include_for_type(AbstractMetaClass *meta_class, const AbstractMetaType *type) { if (type == 0) return; Q_ASSERT(meta_class != 0); const TypeEntry *entry = (type ? type->typeEntry() : 0); if (entry != 0 && entry->isComplex()) { const ComplexTypeEntry *centry = static_cast(entry); ComplexTypeEntry *class_entry = meta_class->typeEntry(); if (class_entry != 0 && centry->include().isValid()) class_entry->addExtraInclude(centry->include()); } if (type->hasInstantiations()) { QList instantiations = type->instantiations(); foreach (AbstractMetaType *instantiation, instantiations) add_extra_include_for_type(meta_class, instantiation); } } static void add_extra_includes_for_function(AbstractMetaClass *meta_class, const AbstractMetaFunction *meta_function) { Q_ASSERT(meta_class != 0); Q_ASSERT(meta_function != 0); add_extra_include_for_type(meta_class, meta_function->type()); AbstractMetaArgumentList arguments = meta_function->arguments(); foreach (AbstractMetaArgument *argument, arguments) add_extra_include_for_type(meta_class, argument->type()); } void AbstractMetaClass::fixFunctions() { if (m_functions_fixed) return; else m_functions_fixed = true; AbstractMetaClass *super_class = baseClass(); AbstractMetaFunctionList funcs = functions(); // printf("fix functions for %s\n", qPrintable(name())); if (super_class != 0) super_class->fixFunctions(); int iface_idx = 0; while (super_class || iface_idx < interfaces().size()) { // printf(" - base: %s\n", qPrintable(super_class->name())); // Since we always traverse the complete hierarchy we are only // interrested in what each super class implements, not what // we may have propagated from their base classes again. AbstractMetaFunctionList super_funcs; if (super_class) { // Super classes can never be final if (super_class->isFinalInTargetLang()) { ReportHandler::warning("Final class '" + super_class->name() + "' set to non-final, as it is extended by other classes"); *super_class -= AbstractMetaAttributes::FinalInTargetLang; } super_funcs = super_class->queryFunctions(AbstractMetaClass::ClassImplements); } else { super_funcs = interfaces().at(iface_idx)->queryFunctions(AbstractMetaClass::NormalFunctions); } QSet funcs_to_add; for (int sfi=0; sfiisRemovedFromAllLanguages(sf->implementingClass())) continue; // we generally don't care about private functions, but we have to get the ones that are // virtual in case they override abstract functions. bool add = (sf->isNormal() || sf->isSignal() || sf->isEmptyFunction()); for (int fi=0; fiisRemovedFromAllLanguages(f->implementingClass())) continue; uint cmp = f->compareTo(sf); if (cmp & AbstractMetaFunction::EqualModifiedName) { // printf(" - %s::%s similar to %s::%s %x vs %x\n", // qPrintable(sf->implementingClass()->typeEntry()->qualifiedCppName()), // qPrintable(sf->name()), // qPrintable(f->implementingClass()->typeEntry()->qualifiedCppName()), // qPrintable(f->name()), // sf->attributes(), // f->attributes()); add = false; if (cmp & AbstractMetaFunction::EqualArguments) { // if (!(cmp & AbstractMetaFunction::EqualReturnType)) { // ReportHandler::warning(QString("%1::%2 and %3::%4 differ in retur type") // .arg(sf->implementingClass()->name()) // .arg(sf->name()) // .arg(f->implementingClass()->name()) // .arg(f->name())); // } // Same function, propegate virtual... if (!(cmp & AbstractMetaFunction::EqualAttributes)) { if (!f->isEmptyFunction()) { if (!sf->isFinalInCpp() && f->isFinalInCpp()) { *f -= AbstractMetaAttributes::FinalInCpp; // printf(" --- inherit virtual\n"); } if (!sf->isFinalInTargetLang() && f->isFinalInTargetLang()) { *f -= AbstractMetaAttributes::FinalInTargetLang; // printf(" --- inherit virtual\n"); } if (!f->isFinalInTargetLang() && f->isPrivate()) { f->setFunctionType(AbstractMetaFunction::EmptyFunction); f->setVisibility(AbstractMetaAttributes::Protected); *f += AbstractMetaAttributes::FinalInTargetLang; ReportHandler::warning(QString("private virtual function '%1' in '%2'") .arg(f->signature()) .arg(f->implementingClass()->name())); } } } if (f->visibility() != sf->visibility()) { QString warn = QString("visibility of function '%1' modified in class '%2'") .arg(f->name()).arg(name()); ReportHandler::warning(warn); // If new visibility is private, we can't // do anything. If it isn't, then we // prefer the parent class's visibility // setting for the function. if (!f->isPrivate() && !sf->isPrivate()) f->setVisibility(sf->visibility()); // Private overrides of abstract functions have to go into the class or // the subclasses will not compile as non-abstract classes. // But they don't need to be implemented, since they can never be called. if (f->isPrivate() && sf->isAbstract()) { f->setFunctionType(AbstractMetaFunction::EmptyFunction); f->setVisibility(sf->visibility()); *f += AbstractMetaAttributes::FinalInTargetLang; *f += AbstractMetaAttributes::FinalInCpp; } } // Set the class which first declares this function, afawk f->setDeclaringClass(sf->declaringClass()); if (sf->isFinalInTargetLang() && !sf->isPrivate() && !f->isPrivate() && !sf->isStatic() && !f->isStatic()) { // Shadowed funcion, need to make base class // function non-virtual if (f->implementingClass() != sf->implementingClass() && f->implementingClass()->inheritsFrom(sf->implementingClass())) { // Check whether the superclass method has been redefined to non-final bool hasNonFinalModifier = false; bool isBaseImplPrivate = false; FunctionModificationList mods = sf->modifications(sf->implementingClass()); foreach (FunctionModification mod, mods) { if (mod.isNonFinal()) { hasNonFinalModifier = true; break; } else if (mod.isPrivate()) { isBaseImplPrivate = true; break; } } if (!hasNonFinalModifier && !isBaseImplPrivate) { ReportHandler::warning(QString::fromLatin1("Shadowing: %1::%2 and %3::%4; Java code will not compile") .arg(sf->implementingClass()->name()) .arg(sf->signature()) .arg(f->implementingClass()->name()) .arg(f->signature())); } } } } if (cmp & AbstractMetaFunction::EqualDefaultValueOverload) { AbstractMetaArgumentList arguments; if (f->arguments().size() < sf->arguments().size()) arguments = sf->arguments(); else arguments = f->arguments(); for (int i=0; isetDefaultValueExpression(QString()); } // Otherwise we have function shadowing and we can // skip the thing... } else if (cmp & AbstractMetaFunction::EqualName && !sf->isSignal()) { // In the case of function shadowing where the function name has been altered to // avoid conflict, we don't copy in the original. add = false; } } if (add) funcs_to_add << sf; } foreach (AbstractMetaFunction *f, funcs_to_add) funcs << f->copy(); if (super_class) super_class = super_class->baseClass(); else iface_idx++; } bool hasPrivateConstructors = false; bool hasPublicConstructors = false; foreach (AbstractMetaFunction *func, funcs) { FunctionModificationList mods = func->modifications(this); foreach (const FunctionModification &mod, mods) { if (mod.isRenameModifier()) { // qDebug() << name() << func->originalName() << func << " from " // << func->implementingClass()->name() << "renamed to" << mod.renamedTo(); func->setName(mod.renamedTo()); } } // Make sure class is abstract if one of the functions is if (func->isAbstract()) { (*this) += AbstractMetaAttributes::Abstract; (*this) -= AbstractMetaAttributes::Final; } if (func->isConstructor()) { if (func->isPrivate()) hasPrivateConstructors = true; else hasPublicConstructors = true; } // Make sure that we include files for all classes that are in use if (!func->isRemovedFrom(this, TypeSystem::ShellCode)) add_extra_includes_for_function(this, func); } if (hasPrivateConstructors && !hasPublicConstructors) { (*this) += AbstractMetaAttributes::Abstract; (*this) -= AbstractMetaAttributes::Final; } foreach (AbstractMetaFunction *f1, funcs) { foreach (AbstractMetaFunction *f2, funcs) { if (f1 != f2) { uint cmp = f1->compareTo(f2); if ((cmp & AbstractMetaFunction::EqualName) && !f1->isFinalInCpp() && f2->isFinalInCpp()) { *f2 += AbstractMetaAttributes::FinalOverload; // qDebug() << f2 << f2->implementingClass()->name() << "::" << f2->name() << f2->arguments().size() << " vs " << f1 << f1->implementingClass()->name() << "::" << f1->name() << f1->arguments().size(); // qDebug() << " " << f2; // AbstractMetaArgumentList f2Args = f2->arguments(); // foreach (AbstractMetaArgument *a, f2Args) // qDebug() << " " << a->type()->name() << a->name(); // qDebug() << " " << f1; // AbstractMetaArgumentList f1Args = f1->arguments(); // foreach (AbstractMetaArgument *a, f1Args) // qDebug() << " " << a->type()->name() << a->name(); } } } } setFunctions(funcs); } QString AbstractMetaType::minimalSignature() const { QString minimalSignature; if (isConstant()) minimalSignature += "const "; minimalSignature += typeEntry()->qualifiedCppName(); if (hasInstantiations()) { QList instantiations = this->instantiations(); minimalSignature += "<"; for (int i=0;i 0) minimalSignature += ","; minimalSignature += instantiations.at(i)->minimalSignature(); } minimalSignature += ">"; } if (isReference()) minimalSignature += "&"; for (int j=0; jisNativeIdBased(); } /******************************************************************************* * Other stuff... */ AbstractMetaEnum *AbstractMetaClassList::findEnum(const EnumTypeEntry *entry) const { Q_ASSERT(entry->isEnum()); QString qualified_name = entry->qualifiedCppName(); int pos = qualified_name.lastIndexOf("::"); QString enum_name; QString class_name; if (pos > 0) { enum_name = qualified_name.mid(pos + 2); class_name = qualified_name.mid(0, pos); } else { enum_name = qualified_name; class_name = TypeDatabase::globalNamespaceClassName(entry); } AbstractMetaClass *meta_class = findClass(class_name); if (!meta_class) { ReportHandler::warning(QString("AbstractMeta::findEnum(), unknown class '%1' in '%2'") .arg(class_name).arg(entry->qualifiedCppName())); return 0; } return meta_class->findEnum(enum_name); } AbstractMetaEnumValue *AbstractMetaEnumValueList::find(const QString &name) const { for (int i=0; iname()) return at(i); } return 0; } AbstractMetaEnumValue *AbstractMetaClassList::findEnumValue(const QString &name) const { QStringList lst = name.split(QLatin1String("::")); Q_ASSERT_X(lst.size() == 2, "AbstractMetaClassList::findEnumValue()", "Expected qualified enum"); QString prefixName = lst.at(0); QString enumName = lst.at(1); AbstractMetaClass *cl = findClass(prefixName); if (cl) return cl->findEnumValue(enumName, 0); ReportHandler::warning(QString("no matching enum '%1'").arg(name)); return 0; } /*! * Searches the list after a class that mathces \a name; either as * C++, Java base name or complete Java package.class name. */ AbstractMetaClass *AbstractMetaClassList::findClass(const QString &name) const { if (name.isEmpty()) return 0; foreach (AbstractMetaClass *c, *this) { if (c->qualifiedCppName() == name) return c; } foreach (AbstractMetaClass *c, *this) { if (c->fullName() == name) return c; } foreach (AbstractMetaClass *c, *this) { if (c->name() == name) return c; } return 0; } qtscriptgenerator-src-0.2.0/generator/abstractmetalang.h000066400000000000000000001105671170724227300235500ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef ABSTRACTMETALANG_H #define ABSTRACTMETALANG_H #include "codemodel.h" #include "typesystem.h" #include #include #include class AbstractMeta; class AbstractMetaClass; class AbstractMetaField; class AbstractMetaFunction; class AbstractMetaType; class AbstractMetaVariable; class AbstractMetaArgument; class AbstractMetaEnumValue; class AbstractMetaEnum; class QPropertySpec; typedef QList AbstractMetaFieldList; typedef QList AbstractMetaArgumentList; typedef QList AbstractMetaFunctionList; class AbstractMetaClassList : public QList { public: AbstractMetaClass *findClass(const QString &name) const; AbstractMetaEnumValue *findEnumValue(const QString &string) const; AbstractMetaEnum *findEnum(const EnumTypeEntry *entry) const; }; class AbstractMetaAttributes { public: AbstractMetaAttributes() : m_attributes(0) { }; enum Attribute { None = 0x00000000, Private = 0x00000001, Protected = 0x00000002, Public = 0x00000004, Friendly = 0x00000008, Visibility = 0x0000000f, Native = 0x00000010, Abstract = 0x00000020, Static = 0x00000040, FinalInTargetLang = 0x00000080, FinalInCpp = 0x00000100, ForceShellImplementation = 0x00000200, GetterFunction = 0x00000400, SetterFunction = 0x00000800, FinalOverload = 0x00001000, InterfaceFunction = 0x00002000, PropertyReader = 0x00004000, PropertyWriter = 0x00008000, PropertyResetter = 0x00010000, Fake = 0x00020000, Invokable = 0x00040000, Final = FinalInTargetLang | FinalInCpp }; uint attributes() const { return m_attributes; } void setAttributes(uint attributes) { m_attributes = attributes; } uint originalAttributes() const { return m_originalAttributes; } void setOriginalAttributes(uint attributes) { m_originalAttributes = attributes; } uint visibility() const { return m_attributes & Visibility; } void setVisibility(uint visi) { m_attributes = (m_attributes & ~Visibility) | visi; } void operator+=(Attribute attribute) { m_attributes |= attribute; } void operator-=(Attribute attribute) { m_attributes &= ~attribute; } bool isNative() const { return m_attributes & Native; } bool isFinal() const { return (m_attributes & Final) == Final; } bool isFinalInTargetLang() const { return m_attributes & FinalInTargetLang; } bool isFinalInCpp() const { return m_attributes & FinalInCpp; } bool isAbstract() const { return m_attributes & Abstract; } bool isStatic() const { return m_attributes & Static; } bool isForcedShellImplementation() const { return m_attributes & ForceShellImplementation; } bool isInterfaceFunction() const { return m_attributes & InterfaceFunction; } bool isFinalOverload() const { return m_attributes & FinalOverload; } bool isInvokable() const { return m_attributes & Invokable; } bool isPropertyReader() const { return m_attributes & PropertyReader; } bool isPropertyWriter() const { return m_attributes & PropertyWriter; } bool isPropertyResetter() const { return m_attributes & PropertyResetter; } bool isPrivate() const { return m_attributes & Private; } bool isProtected() const { return m_attributes & Protected; } bool isPublic() const { return m_attributes & Public; } bool isFriendly() const { return m_attributes & Friendly; } bool wasPrivate() const { return m_originalAttributes & Private; } bool wasProtected() const { return m_originalAttributes & Protected; } bool wasPublic() const { return m_originalAttributes & Public; } bool wasFriendly() const { return m_originalAttributes & Friendly; } private: uint m_attributes; uint m_originalAttributes; }; class AbstractMetaType { public: enum TypeUsagePattern { InvalidPattern, PrimitivePattern, FlagsPattern, EnumPattern, ValuePattern, StringPattern, CharPattern, ObjectPattern, QObjectPattern, NativePointerPattern, ContainerPattern, VariantPattern, JObjectWrapperPattern, ArrayPattern, ThreadPattern }; AbstractMetaType() : m_type_entry(0), m_array_element_count(0), m_array_element_type(0), m_original_template_type(0), m_pattern(InvalidPattern), m_constant(false), m_reference(false), m_cpp_instantiation(true), m_indirections(0), m_reserved(0) { } QString package() const { return m_type_entry->javaPackage(); } QString name() const { return m_type_entry->targetLangName(); } QString fullName() const { return m_type_entry->qualifiedTargetLangName(); } void setTypeUsagePattern(TypeUsagePattern pattern) { m_pattern = pattern; } TypeUsagePattern typeUsagePattern() const { return m_pattern; } // true when use pattern is container bool hasInstantiations() const { return !m_instantiations.isEmpty(); } void addInstantiation(AbstractMetaType *inst) { m_instantiations << inst; } void setInstantiations(const QList &insts) { m_instantiations = insts; } QList instantiations() const { return m_instantiations; } void setInstantiationInCpp(bool incpp) { m_cpp_instantiation = incpp; } bool hasInstantiationInCpp() const { return hasInstantiations() && m_cpp_instantiation; } QString minimalSignature() const; // true when the type is a QtJambiObject subclass bool hasNativeId() const; // returns true if the typs is used as a non complex primitive, no & or *'s bool isPrimitive() const { return m_pattern == PrimitivePattern; } // returns true if the type is used as an enum bool isEnum() const { return m_pattern == EnumPattern; } // returns true if the type is used as a QObject * bool isQObject() const { return m_pattern == QObjectPattern; } // returns true if the type is used as an object, e.g. Xxx * bool isObject() const { return m_pattern == ObjectPattern; } // returns true if the type is used as an array, e.g. Xxx[42] bool isArray() const { return m_pattern == ArrayPattern; } // returns true if the type is used as a value type (X or const X &) bool isValue() const { return m_pattern == ValuePattern; } // returns true for more complex types... bool isNativePointer() const { return m_pattern == NativePointerPattern; } // returns true if the type was originally a QString or const QString & or equivalent for QLatin1String bool isTargetLangString() const { return m_pattern == StringPattern; } // returns true if the type was originally a QChar or const QChar & bool isTargetLangChar() const { return m_pattern == CharPattern; } // return true if the type was originally a QVariant or const QVariant & bool isVariant() const { return m_pattern == VariantPattern; } // return true if the type was originally a JObjectWrapper or const JObjectWrapper & bool isJObjectWrapper() const { return m_pattern == JObjectWrapperPattern; } // returns true if the type was used as a container bool isContainer() const { return m_pattern == ContainerPattern; } // returns true if the type was used as a flag bool isFlags() const { return m_pattern == FlagsPattern; } // returns true if the type was used as a thread bool isThread() const { return m_pattern == ThreadPattern; } bool isConstant() const { return m_constant; } void setConstant(bool constant) { m_constant = constant; } bool isReference() const { return m_reference; } void setReference(bool ref) { m_reference = ref; } // Returns true if the type is to be implemented using Java enums, e.g. not plain ints. bool isTargetLangEnum() const { return isEnum() && !((EnumTypeEntry *) typeEntry())->forceInteger(); } bool isIntegerEnum() const { return isEnum() && !isTargetLangEnum(); } // Returns true if the type is to be implemented using Java QFlags, e.g. not plain ints. bool isTargetLangFlags() const { return isFlags() && !((FlagsTypeEntry *) typeEntry())->forceInteger(); } bool isIntegerFlags() const { return isFlags() && !isTargetLangFlags(); } int actualIndirections() const { return m_indirections + (isReference() ? 1 : 0); } int indirections() const { return m_indirections; } void setIndirections(int indirections) { m_indirections = indirections; } void setArrayElementCount(int n) { m_array_element_count = n; } int arrayElementCount() const { return m_array_element_count; } AbstractMetaType *arrayElementType() const { return m_array_element_type; } void setArrayElementType(AbstractMetaType *t) { m_array_element_type = t; } QString cppSignature() const; AbstractMetaType *copy() const; const TypeEntry *typeEntry() const { return m_type_entry; } void setTypeEntry(const TypeEntry *type) { m_type_entry = type; } void setOriginalTypeDescription(const QString &otd) { m_original_type_description = otd; } QString originalTypeDescription() const { return m_original_type_description; } void setOriginalTemplateType(const AbstractMetaType *type) { m_original_template_type = type; } const AbstractMetaType *originalTemplateType() const { return m_original_template_type; } private: const TypeEntry *m_type_entry; QList m_instantiations; QString m_package; QString m_original_type_description; int m_array_element_count; AbstractMetaType *m_array_element_type; const AbstractMetaType *m_original_template_type; TypeUsagePattern m_pattern; uint m_constant : 1; uint m_reference : 1; uint m_cpp_instantiation : 1; int m_indirections : 4; uint m_reserved : 25; // unused }; class AbstractMetaVariable { public: AbstractMetaVariable() : m_type(0) { } AbstractMetaType *type() const { return m_type; } void setType(AbstractMetaType *type) { m_type = type; } QString name() const { return m_name; } void setName(const QString &name) { m_name = name; } private: QString m_name; AbstractMetaType *m_type; }; class AbstractMetaArgument : public AbstractMetaVariable { public: AbstractMetaArgument() : m_argument_index(0) { }; QString defaultValueExpression() const { return m_expression; } void setDefaultValueExpression(const QString &expr) { m_expression = expr; } QString originalDefaultValueExpression() const { return m_original_expression; } void setOriginalDefaultValueExpression(const QString &expr) { m_original_expression = expr; } QString toString() const { return type()->name() + " " + AbstractMetaVariable::name() + (m_expression.isEmpty() ? "" : " = " + m_expression); } int argumentIndex() const { return m_argument_index; } void setArgumentIndex(int argIndex) { m_argument_index = argIndex; } QString argumentName() const; QString indexedName() const; AbstractMetaArgument *copy() const; private: // Just to force people to call argumentName() And indexedName(); QString name() const; QString m_expression; QString m_original_expression; int m_argument_index; }; class AbstractMetaField : public AbstractMetaVariable, public AbstractMetaAttributes { public: AbstractMetaField(); ~AbstractMetaField(); const AbstractMetaClass *enclosingClass() const { return m_class; } void setEnclosingClass(const AbstractMetaClass *cls) { m_class = cls; } const AbstractMetaFunction *getter() const; const AbstractMetaFunction *setter() const; FieldModificationList modifications() const; AbstractMetaField *copy() const; private: mutable AbstractMetaFunction *m_getter; mutable AbstractMetaFunction *m_setter; const AbstractMetaClass *m_class; }; class AbstractMetaFunction : public AbstractMetaAttributes { public: enum FunctionType { ConstructorFunction, DestructorFunction, NormalFunction, SignalFunction, EmptyFunction, SlotFunction, GlobalScopeFunction }; enum CompareResult { EqualName = 0x00000001, EqualArguments = 0x00000002, EqualAttributes = 0x00000004, EqualImplementor = 0x00000008, EqualReturnType = 0x00000010, EqualDefaultValueOverload = 0x00000020, EqualModifiedName = 0x00000040, NameLessThan = 0x00001000, PrettySimilar = EqualName | EqualArguments, Equal = 0x0000001f, NotEqual = 0x00001000 }; AbstractMetaFunction() : m_function_type(NormalFunction), m_type(0), m_class(0), m_implementing_class(0), m_declaring_class(0), m_interface_class(0), m_property_spec(0), m_constant(false), m_invalid(false) { } ~AbstractMetaFunction(); QString name() const { return m_name; } void setName(const QString &name) { m_name = name; } QString originalName() const { return m_original_name.isEmpty() ? name() : m_original_name; } void setOriginalName(const QString &name) { m_original_name = name; } QString modifiedName() const; QString minimalSignature() const; QStringList possibleIntrospectionCompatibleSignatures() const; QString marshalledName() const; // true if one or more of the arguments are of QtJambiObject subclasses bool argumentsHaveNativeId() const { foreach (const AbstractMetaArgument *arg, m_arguments) { if (arg->type()->hasNativeId()) return true; } return false; } bool isModifiedRemoved(int types = TypeSystem::All) const; AbstractMetaType *type() const { return m_type; } void setType(AbstractMetaType *type) { m_type = type; } // The class that has this function as a member. const AbstractMetaClass *ownerClass() const { return m_class; } void setOwnerClass(const AbstractMetaClass *cls) { m_class = cls; } // The first class in a hierarchy that declares the function const AbstractMetaClass *declaringClass() const { return m_declaring_class; } void setDeclaringClass(const AbstractMetaClass *cls) { m_declaring_class = cls; } // The class that actually implements this function const AbstractMetaClass *implementingClass() const { return m_implementing_class; } void setImplementingClass(const AbstractMetaClass *cls) { m_implementing_class = cls; } bool needsCallThrough() const; AbstractMetaArgumentList arguments() const { return m_arguments; } void setArguments(const AbstractMetaArgumentList &arguments) { m_arguments = arguments; } void addArgument(AbstractMetaArgument *argument) { m_arguments << argument; } int actualMinimumArgumentCount() const; void setInvalid(bool on) { m_invalid = on; } bool isInvalid() const { return m_invalid; } bool isDeprecated() const; bool isDestructor() const { return functionType() == DestructorFunction; } bool isConstructor() const { return functionType() == ConstructorFunction; } bool isNormal() const { return functionType() == NormalFunction || isSlot() || isInGlobalScope(); } bool isInGlobalScope() const { return functionType() == GlobalScopeFunction; } bool isSignal() const { return functionType() == SignalFunction; } bool isSlot() const { return functionType() == SlotFunction; } bool isEmptyFunction() const { return functionType() == EmptyFunction; } FunctionType functionType() const { return m_function_type; } void setFunctionType(FunctionType type) { m_function_type = type; } QStringList introspectionCompatibleSignatures(const QStringList &resolvedArguments = QStringList()) const; QString signature() const; QString targetLangSignature(bool minimal = false) const; bool shouldReturnThisObject() const { return QLatin1String("this") == argumentReplaced(0); } bool shouldIgnoreReturnValue() const { return QLatin1String("void") == argumentReplaced(0); } bool isConstant() const { return m_constant; } void setConstant(bool constant) { m_constant = constant; } QString exception() const { return m_exception; } void setException(const QString &exception) { m_exception = exception; } QString toString() const { return m_name; } uint compareTo(const AbstractMetaFunction *other) const; bool operator <(const AbstractMetaFunction &a) const; AbstractMetaFunction *copy() const; QString replacedDefaultExpression(const AbstractMetaClass *cls, int idx) const; bool removedDefaultExpression(const AbstractMetaClass *cls, int idx) const; QString conversionRule(TypeSystem::Language language, int idx) const; QList referenceCounts(const AbstractMetaClass *cls, int idx = -2) const; bool nullPointersDisabled(const AbstractMetaClass *cls = 0, int argument_idx = 0) const; QString nullPointerDefaultValue(const AbstractMetaClass *cls = 0, int argument_idx = 0) const; bool resetObjectAfterUse(int argument_idx) const; // Returns whether garbage collection is disabled for the argument in any context bool disabledGarbageCollection(const AbstractMetaClass *cls, int key) const; // Returns the ownership rules for the given argument in the given context TypeSystem::Ownership ownership(const AbstractMetaClass *cls, TypeSystem::Language language, int idx) const; bool isVirtualSlot() const; QString typeReplaced(int argument_index) const; bool isRemovedFromAllLanguages(const AbstractMetaClass *) const; bool isRemovedFrom(const AbstractMetaClass *, TypeSystem::Language language) const; bool argumentRemoved(int) const; QString argumentReplaced(int key) const; bool needsSuppressUncheckedWarning() const; bool hasModifications(const AbstractMetaClass *implementor) const; FunctionModificationList modifications(const AbstractMetaClass *implementor) const; // If this function stems from an interface, this returns the // interface that declares it. const AbstractMetaClass *interfaceClass() const { return m_interface_class; } void setInterfaceClass(const AbstractMetaClass *cl) { m_interface_class = cl; } void setPropertySpec(QPropertySpec *spec) { m_property_spec = spec; } QPropertySpec *propertySpec() const { return m_property_spec; } private: QString m_name; QString m_original_name; mutable QString m_cached_minimal_signature; mutable QString m_cached_modified_name; FunctionType m_function_type; AbstractMetaType *m_type; const AbstractMetaClass *m_class; const AbstractMetaClass *m_implementing_class; const AbstractMetaClass *m_declaring_class; const AbstractMetaClass *m_interface_class; QPropertySpec *m_property_spec; AbstractMetaArgumentList m_arguments; QString m_exception; uint m_constant : 1; uint m_invalid : 1; }; class AbstractMetaEnumValue { public: AbstractMetaEnumValue() : m_value_set(false), m_value(0) { } int value() const { return m_value; } void setValue(int value) { m_value_set = true; m_value = value; } QString stringValue() const { return m_string_value; } void setStringValue(const QString &v) { m_string_value = v; } QString name() const { return m_name; } void setName(const QString &name) { m_name = name; } bool isValueSet() const { return m_value_set; } private: QString m_name; QString m_string_value; bool m_value_set; int m_value; }; class AbstractMetaEnumValueList : public QList { public: AbstractMetaEnumValue *find(const QString &name) const; }; class AbstractMetaEnum : public AbstractMetaAttributes { public: AbstractMetaEnum() : m_type_entry(0), m_class(0), m_has_qenums_declaration(false) {} AbstractMetaEnumValueList values() const { return m_enum_values; } void addEnumValue(AbstractMetaEnumValue *enumValue) { m_enum_values << enumValue; } QString name() const { return m_type_entry->targetLangName(); } QString qualifier() const { return m_type_entry->javaQualifier(); } QString package() const { return m_type_entry->javaPackage(); } QString fullName() const { return package() + "." + qualifier() + "." + name(); } // Has the enum been declared inside a Q_ENUMS() macro in its enclosing class? void setHasQEnumsDeclaration(bool on) { m_has_qenums_declaration = on; } bool hasQEnumsDeclaration() const { return m_has_qenums_declaration; } EnumTypeEntry *typeEntry() const { return m_type_entry; } void setTypeEntry(EnumTypeEntry *entry) { m_type_entry = entry; } AbstractMetaClass *enclosingClass() const { return m_class; } void setEnclosingClass(AbstractMetaClass *c) { m_class = c; } private: AbstractMetaEnumValueList m_enum_values; EnumTypeEntry *m_type_entry; AbstractMetaClass *m_class; uint m_has_qenums_declaration : 1; uint m_reserved : 31; }; typedef QList AbstractMetaEnumList; class AbstractMetaClass : public AbstractMetaAttributes { public: enum FunctionQueryOption { Constructors = 0x000001, // Only constructors //Destructors = 0x000002, // Only destructors. Not included in class. VirtualFunctions = 0x000004, // Only virtual functions (virtual in both TargetLang and C++) FinalInTargetLangFunctions = 0x000008, // Only functions that are non-virtual in TargetLang FinalInCppFunctions = 0x000010, // Only functions that are non-virtual in C++ ClassImplements = 0x000020, // Only functions implemented by the current class Inconsistent = 0x000040, // Only inconsistent functions (inconsistent virtualness in TargetLang/C++) StaticFunctions = 0x000080, // Only static functions Signals = 0x000100, // Only signals NormalFunctions = 0x000200, // Only functions that aren't signals Visible = 0x000400, // Only public and protected functions ForcedShellFunctions = 0x000800, // Only functions that are overridden to be implemented in the shell class WasPublic = 0x001000, // Only functions that were originally public WasProtected = 0x002000, // Only functions that were originally protected NonStaticFunctions = 0x004000, // No static functions Empty = 0x008000, // Empty overrides of abstract functions Invisible = 0x010000, // Only private functions VirtualInCppFunctions = 0x020000, // Only functions that are virtual in C++ NonEmptyFunctions = 0x040000, // Only functions with JNI implementations VirtualInTargetLangFunctions = 0x080000, // Only functions which are virtual in TargetLang AbstractFunctions = 0x100000, // Only abstract functions WasVisible = 0x200000, // Only functions that were public or protected in the original code NotRemovedFromTargetLang = 0x400000, // Only functions that have not been removed from TargetLang NotRemovedFromShell = 0x800000, // Only functions that have not been removed from the shell class VirtualSlots = 0x1000000 // Only functions that are set as virtual slots in the type system }; AbstractMetaClass() : m_namespace(false), m_qobject(false), m_has_virtuals(false), m_has_nonpublic(false), m_has_virtual_slots(false), m_has_nonprivateconstructor(false), m_functions_fixed(false), m_has_public_destructor(true), m_force_shell_class(false), m_has_hash_function(false), m_has_equals_operator(false), m_has_clone_operator(false), m_is_type_alias(false), m_enclosing_class(0), m_base_class(0), m_template_base_class(0), m_extracted_interface(0), m_primary_interface_implementor(0), m_type_entry(0), m_qDebug_stream_function(0) { } virtual ~AbstractMetaClass(); AbstractMetaClass *extractInterface(); void fixFunctions(); AbstractMetaFunctionList functions() const { return m_functions; } void setFunctions(const AbstractMetaFunctionList &functions); void addFunction(AbstractMetaFunction *function); bool hasFunction(const AbstractMetaFunction *f) const; bool hasFunction(const QString &str) const; bool hasSignal(const AbstractMetaFunction *f) const; bool hasConstructors() const; void addDefaultConstructor(); bool hasNonPrivateConstructor() const { return m_has_nonprivateconstructor; } void setHasNonPrivateConstructor(bool on) { m_has_nonprivateconstructor = on; } bool hasPublicDestructor() const { return m_has_public_destructor; } void setHasPublicDestructor(bool on) { m_has_public_destructor = on; } QString destructorException() const { return m_destructor_exception; } void setDestructorException(const QString &exception) { m_destructor_exception = exception; } AbstractMetaFunctionList queryFunctionsByName(const QString &name) const; AbstractMetaFunctionList queryFunctions(uint query) const; inline AbstractMetaFunctionList allVirtualFunctions() const; inline AbstractMetaFunctionList allFinalFunctions() const; AbstractMetaFunctionList functionsInTargetLang() const; AbstractMetaFunctionList functionsInShellClass() const; inline AbstractMetaFunctionList cppInconsistentFunctions() const; inline AbstractMetaFunctionList cppSignalFunctions() const; AbstractMetaFunctionList publicOverrideFunctions() const; AbstractMetaFunctionList virtualOverrideFunctions() const; AbstractMetaFunctionList virtualFunctions() const; AbstractMetaFunctionList nonVirtualShellFunctions() const; AbstractMetaFieldList fields() const { return m_fields; } void setFields(const AbstractMetaFieldList &fields) { m_fields = fields; } void addField(AbstractMetaField *field) { m_fields << field; } AbstractMetaEnumList enums() const { return m_enums; } void setEnums(const AbstractMetaEnumList &enums) { m_enums = enums; } void addEnum(AbstractMetaEnum *e) { m_enums << e; } AbstractMetaEnum *findEnum(const QString &enumName); AbstractMetaEnum *findEnumForValue(const QString &enumName); AbstractMetaEnumValue *findEnumValue(const QString &enumName, AbstractMetaEnum *meta_enum); AbstractMetaClassList interfaces() const { return m_interfaces; } void addInterface(AbstractMetaClass *interface); void setInterfaces(const AbstractMetaClassList &interface); QString fullName() const { return package() + "." + name(); } QString name() const; QString baseClassName() const { return m_base_class ? m_base_class->name() : QString(); } AbstractMetaClass *baseClass() const { return m_base_class; } void setBaseClass(AbstractMetaClass *base_class) { m_base_class = base_class; } const AbstractMetaClass *enclosingClass() const { return m_enclosing_class; } void setEnclosingClass(AbstractMetaClass *cl) { m_enclosing_class = cl; } QString package() const { return m_type_entry->javaPackage(); } bool isInterface() const { return m_type_entry->isInterface(); } bool isNamespace() const { return m_type_entry->isNamespace(); } bool isQObject() const { return m_type_entry->isQObject(); } bool isQtNamespace() const { return isNamespace() && name() == "Qt"; } QString qualifiedCppName() const { return m_type_entry->qualifiedCppName(); } bool hasInconsistentFunctions() const; bool hasSignals() const; bool inheritsFrom(const AbstractMetaClass *other) const; void setForceShellClass(bool on) { m_force_shell_class = on; } bool generateShellClass() const; bool hasVirtualSlots() const { return m_has_virtual_slots; } bool hasVirtualFunctions() const { return !isFinal() && m_has_virtuals; } bool hasProtectedFunctions() const; QList templateArguments() const { return m_template_args; } void setTemplateArguments(const QList &args) { m_template_args = args; } bool hasFieldAccessors() const; // only valid during metajavabuilder's run QStringList baseClassNames() const { return m_base_class_names; } void setBaseClassNames(const QStringList &names) { m_base_class_names = names; } AbstractMetaClass *primaryInterfaceImplementor() const { return m_primary_interface_implementor; } void setPrimaryInterfaceImplementor(AbstractMetaClass *cl) { m_primary_interface_implementor = cl; } const ComplexTypeEntry *typeEntry() const { return m_type_entry; } ComplexTypeEntry *typeEntry() { return m_type_entry; } void setTypeEntry(ComplexTypeEntry *type) { m_type_entry = type; } void setHasHashFunction(bool on) { m_has_hash_function = on; } bool hasHashFunction() const { return m_has_hash_function; } void setToStringCapability(FunctionModelItem fun) { m_qDebug_stream_function= fun; } FunctionModelItem hasToStringCapability() const { return m_qDebug_stream_function; } virtual bool hasDefaultToStringFunction() const; void setHasEqualsOperator(bool on) { m_has_equals_operator = on; } bool hasEqualsOperator() const { return m_has_equals_operator; } void setHasCloneOperator(bool on) { m_has_clone_operator = on; } bool hasCloneOperator() const { return m_has_clone_operator; } void addPropertySpec(QPropertySpec *spec) { m_property_specs << spec; } QList propertySpecs() const { return m_property_specs; } QPropertySpec *propertySpecForRead(const QString &name) const; QPropertySpec *propertySpecForWrite(const QString &name) const; QPropertySpec *propertySpecForReset(const QString &name) const; QList referenceCounts() const; void setEqualsFunctions(const AbstractMetaFunctionList &lst) { m_equals_functions = lst; } AbstractMetaFunctionList equalsFunctions() const { return m_equals_functions; } void setNotEqualsFunctions(const AbstractMetaFunctionList &lst) { m_nequals_functions = lst; } AbstractMetaFunctionList notEqualsFunctions() const { return m_nequals_functions; } void setLessThanFunctions(const AbstractMetaFunctionList &lst) { m_less_than_functions = lst; } AbstractMetaFunctionList lessThanFunctions() const { return m_less_than_functions; } void setGreaterThanFunctions(const AbstractMetaFunctionList &lst) { m_greater_than_functions = lst; } AbstractMetaFunctionList greaterThanFunctions() const { return m_greater_than_functions; } void setLessThanEqFunctions(const AbstractMetaFunctionList &lst) { m_less_than_eq_functions = lst; } AbstractMetaFunctionList lessThanEqFunctions() const { return m_less_than_eq_functions; } void setGreaterThanEqFunctions(const AbstractMetaFunctionList &lst) { m_greater_than_eq_functions = lst; } AbstractMetaFunctionList greaterThanEqFunctions() const { return m_greater_than_eq_functions; } void sortFunctions(); const AbstractMetaClass *templateBaseClass() const { return m_template_base_class; } void setTemplateBaseClass(const AbstractMetaClass *cls) { m_template_base_class = cls; } void setTypeAlias(bool typeAlias) { m_is_type_alias = typeAlias; } bool isTypeAlias() const { return m_is_type_alias; } private: uint m_namespace : 1; uint m_qobject : 1; uint m_has_virtuals : 1; uint m_has_nonpublic : 1; uint m_has_virtual_slots : 1; uint m_has_nonprivateconstructor : 1; uint m_functions_fixed : 1; uint m_has_public_destructor : 1; uint m_force_shell_class : 1; uint m_has_hash_function : 1; uint m_has_equals_operator : 1; uint m_has_clone_operator :1; uint m_is_type_alias : 1; uint m_reserved : 19; QString m_destructor_exception; const AbstractMetaClass *m_enclosing_class; AbstractMetaClass *m_base_class; const AbstractMetaClass *m_template_base_class; AbstractMetaFunctionList m_functions; AbstractMetaFieldList m_fields; AbstractMetaEnumList m_enums; AbstractMetaClassList m_interfaces; AbstractMetaClass *m_extracted_interface; AbstractMetaClass *m_primary_interface_implementor; QList m_property_specs; AbstractMetaFunctionList m_equals_functions; AbstractMetaFunctionList m_nequals_functions; AbstractMetaFunctionList m_less_than_functions; AbstractMetaFunctionList m_greater_than_functions; AbstractMetaFunctionList m_less_than_eq_functions; AbstractMetaFunctionList m_greater_than_eq_functions; QStringList m_base_class_names; QList m_template_args; ComplexTypeEntry *m_type_entry; FunctionModelItem m_qDebug_stream_function; }; class QPropertySpec { public: QPropertySpec(const TypeEntry *type) : m_type(type), m_index(-1) { } const TypeEntry *type() const { return m_type; } QString name() const { return m_name; } void setName(const QString &name) { m_name = name; } QString read() const { return m_read; } void setRead(const QString &read) { m_read = read; } QString write() const { return m_write; } void setWrite(const QString &write) { m_write = write; } QString designable() const { return m_designable; } void setDesignable(const QString &designable) { m_designable = designable; } QString reset() const { return m_reset; } void setReset(const QString &reset) { m_reset = reset; } int index() const { return m_index; } void setIndex(int index) { m_index = index; } private: QString m_name; QString m_read; QString m_write; QString m_designable; QString m_reset; const TypeEntry *m_type; int m_index; }; inline AbstractMetaFunctionList AbstractMetaClass::allVirtualFunctions() const { return queryFunctions(VirtualFunctions | NotRemovedFromTargetLang); } inline AbstractMetaFunctionList AbstractMetaClass::allFinalFunctions() const { return queryFunctions(FinalInTargetLangFunctions | FinalInCppFunctions | NotRemovedFromTargetLang); } inline AbstractMetaFunctionList AbstractMetaClass::cppInconsistentFunctions() const { return queryFunctions(Inconsistent | NormalFunctions | Visible | NotRemovedFromTargetLang); } inline AbstractMetaFunctionList AbstractMetaClass::cppSignalFunctions() const { return queryFunctions(Signals | Visible | NotRemovedFromTargetLang); } #endif // ABSTRACTMETALANG_H qtscriptgenerator-src-0.2.0/generator/asttoxml.cpp000066400000000000000000000125101170724227300224270ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "asttoxml.h" #include "control.h" #include "parser.h" #include "binder.h" #include #include #include #include void astToXML(QString name) { QFile file(name); if (!file.open(QFile::ReadOnly)) return; QTextStream stream(&file); stream.setCodec(QTextCodec::codecForName("UTF-8")); QByteArray contents = stream.readAll().toUtf8(); file.close(); Control control; Parser p(&control); pool __pool; TranslationUnitAST *ast = p.parse(contents, contents.size(), &__pool); CodeModel model; Binder binder(&model, p.location()); FileModelItem dom = binder.run(ast); QFile outputFile; if (!outputFile.open(stdout, QIODevice::WriteOnly)) { return; } QXmlStreamWriter s( &outputFile); s.setAutoFormatting( true ); s.writeStartElement("code"); QHash namespaceMap = dom->namespaceMap(); foreach (NamespaceModelItem item, namespaceMap.values()) { writeOutNamespace(s, item); } QHash typeMap = dom->classMap(); foreach (ClassModelItem item, typeMap.values()) { writeOutClass(s, item); } s.writeEndElement(); } void writeOutNamespace(QXmlStreamWriter &s, NamespaceModelItem &item) { s.writeStartElement("namespace"); s.writeAttribute("name", item->name()); QHash namespaceMap = item->namespaceMap(); foreach (NamespaceModelItem namespaceItem, namespaceMap.values()) { writeOutNamespace(s, namespaceItem); } QHash typeMap = item->classMap(); foreach (ClassModelItem classItem, typeMap.values()) { writeOutClass(s, classItem); } QHash enumMap = item->enumMap(); foreach (EnumModelItem enumItem, enumMap.values()) { writeOutEnum(s, enumItem); } s.writeEndElement(); } void writeOutEnum(QXmlStreamWriter &s, EnumModelItem &item) { QString qualified_name = item->qualifiedName().join("::"); s.writeStartElement("enum"); s.writeAttribute("name", qualified_name); EnumeratorList enumList = item->enumerators(); for(int i=0; i < enumList.size() ; i++) { s.writeStartElement("enumerator"); if( !enumList[i]->value().isEmpty() ) s.writeAttribute("value", enumList[i]->value()); s.writeCharacters(enumList[i]->name()); s.writeEndElement(); } s.writeEndElement(); } void writeOutFunction(QXmlStreamWriter &s, FunctionModelItem &item) { QString qualified_name = item->qualifiedName().join("::"); s.writeStartElement("function"); s.writeAttribute("name", qualified_name); if (!item->exception().isEmpty()) { s.writeStartElement("exception"); s.writeAttribute("throw", item->exception()); s.writeEndElement(); } ArgumentList arguments = item->arguments(); for(int i=0; i < arguments.size() ; i++) { s.writeStartElement("argument"); s.writeAttribute("type", arguments[i]->type().qualifiedName().join("::")); s.writeEndElement(); } s.writeEndElement(); } void writeOutClass(QXmlStreamWriter &s, ClassModelItem &item) { QString qualified_name = item->qualifiedName().join("::"); s.writeStartElement("class"); s.writeAttribute("name", qualified_name); QHash enumMap = item->enumMap(); foreach (EnumModelItem enumItem, enumMap.values()) { writeOutEnum(s, enumItem); } QHash functionMap = item->functionMap(); foreach (FunctionModelItem funcItem, functionMap.values()) { writeOutFunction(s, funcItem); } QHash typeMap = item->classMap(); foreach (ClassModelItem classItem, typeMap.values()) { writeOutClass(s, classItem); } s.writeEndElement(); } qtscriptgenerator-src-0.2.0/generator/asttoxml.h000066400000000000000000000036161170724227300221030ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef ASTTOXML #define ASTTOXML #include "codemodel.h" #include #include void astToXML(const QString name); void writeOutNamespace(QXmlStreamWriter &s, NamespaceModelItem &item); void writeOutEnum(QXmlStreamWriter &s, EnumModelItem &item); void writeOutFunction(QXmlStreamWriter &s, FunctionModelItem &item); void writeOutClass(QXmlStreamWriter &s, ClassModelItem &item); #endif // ASTTOXML qtscriptgenerator-src-0.2.0/generator/build_all.txt000066400000000000000000000013521170724227300225420ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/build_core.txt000066400000000000000000000002311170724227300227150ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/build_gui.txt000066400000000000000000000002311170724227300225510ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/build_network.txt000066400000000000000000000002371170724227300234640ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/build_opengl.txt000066400000000000000000000003321170724227300232530ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/build_phonon.txt000066400000000000000000000003351170724227300232730ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/build_sql.txt000066400000000000000000000003431170724227300225700ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/build_svg.txt000066400000000000000000000004251170724227300225710ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/build_typesystem.txt000066400000000000000000000172661170724227300242330ustar00rootroot00000000000000 QList<MetaJavaClass *> &operator=(const QList<MetaJavaClass *> &other) { return ((QList<MetaJavaClass *> *)this)->operator=(other); } QList<MetaJavaEnumValue *> &operator=(const QList<MetaJavaEnumValue *> &other) { return ((QList<MetaJavaEnumValue *> *)this)->operator=(other); } qtscriptgenerator-src-0.2.0/generator/build_uitools.txt000066400000000000000000000003331170724227300234660ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/build_webkit.txt000066400000000000000000000004401170724227300232540ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/build_xml.txt000066400000000000000000000002331170724227300225670ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/build_xmlpatterns.txt000066400000000000000000000002431170724227300243510ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/classgenerator.cpp000066400000000000000000002322341170724227300235770ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "classgenerator.h" #include "fileout.h" #include #include #include #define GENERATOR_NO_PROTECTED_FUNCTIONS ClassGenerator::ClassGenerator(PriGenerator *pri, SetupGenerator *setup) : priGenerator(pri), setupGenerator(setup) {} QString ClassGenerator::fileNameForClass(const AbstractMetaClass *meta_class) const { return QString("qtscript_%1.cpp").arg(meta_class->name()); } bool ClassGenerator::shouldGenerate(const AbstractMetaClass *meta_class) const { uint cg = meta_class->typeEntry()->codeGeneration(); return (cg & TypeEntry::GenerateCode) != 0; } static QString normalizedType(const AbstractMetaType *type) { QString str = QString::fromLatin1(QMetaObject::normalizedType(type->cppSignature().toLatin1())); if (str.endsWith(QLatin1Char('&'))) str.chop(1); else if (str.startsWith("const ")) { if (str.endsWith('*') || type->hasInstantiations() || type->typeEntry()->isValue()) str.remove(0, 6); } if (str == QLatin1String("QBool")) // ### hack str = QLatin1String("bool"); return str; } /*! Returns true if the class \a meta_class inherits from QObject, otherwise returns false. */ static bool isQObjectBased(const AbstractMetaClass *meta_class) { while (meta_class) { if (meta_class->name() == QLatin1String("QObject")) return true; meta_class = meta_class->baseClass(); } return false; } /*! Returns true if any of the given \a enums has been declared with Q_ENUMS. */ static bool hasQEnums(const AbstractMetaEnumList &enums) { for (int i = 0; i < enums.size(); ++i) { if (enums.at(i)->hasQEnumsDeclaration()) return true; } return false; } /*! Returns true if any of the given \a enums has a QFlags class associated with it. */ static bool hasFlags(const AbstractMetaEnumList &enums) { for (int i = 0; i < enums.size(); ++i) { FlagsTypeEntry *flags = enums.at(i)->typeEntry()->flags(); if (flags) return true; } return false; } static bool isSequenceType(const AbstractMetaType *tp) { return tp->isContainer() && (tp->instantiations().size() == 1); } static AbstractMetaFunction *findDefaultConstructor(const AbstractMetaFunctionList &ctors) { for (int i = 0; i < ctors.size(); ++i) { if (ctors.at(i)->actualMinimumArgumentCount() == 0) return ctors.at(i); } return 0; } static AbstractMetaFunctionList findConstructors(const AbstractMetaClass *meta_class) { return meta_class->queryFunctions(AbstractMetaClass::Constructors | AbstractMetaClass::WasPublic | AbstractMetaClass::NotRemovedFromTargetLang); } /*! Returns true if \a meta_class has a default constructor, false otherwise. */ bool hasDefaultConstructor(const AbstractMetaClass *meta_class) { return findDefaultConstructor(findConstructors(meta_class)) != 0; } /*! Given the list of \a functions, creates a mapping from # of arguments to list of functions. */ static QMap createArgcToFunctionsMap( const AbstractMetaFunctionList &functions) { QMap result; for (int i = 0; i < functions.size(); ++i) { AbstractMetaFunction *func = functions.at(i); int argc = func->arguments().size(); for (int k = argc; k > 0; --k) { if (func->argumentRemoved(k)) --argc; } for (int j = func->actualMinimumArgumentCount(); j <= argc; ++j) result[j].append(func); } return result; } /*! Returns the name of the QScriptValue function to use to test if a value is of the given \a typeName, or an empty string if there is no such function. */ static QString builtinTypeTesterFunction(const QString &typeName) { if (typeName == QLatin1String("QString")) return QLatin1String("isString"); else if (typeName == QLatin1String("double")) return QLatin1String("isNumber"); else if (typeName == QLatin1String("float")) return QLatin1String("isNumber"); else if (typeName == QLatin1String("int")) return QLatin1String("isNumber"); else if (typeName == QLatin1String("uint")) return QLatin1String("isNumber"); else if (typeName == QLatin1String("short")) return QLatin1String("isNumber"); else if (typeName == QLatin1String("unsigned short")) return QLatin1String("isNumber"); else if (typeName == QLatin1String("bool")) return QLatin1String("isBoolean"); else if (typeName == QLatin1String("QVariant")) return QLatin1String("isVariant"); // else if (typeName == QLatin1String("QDateTime")) // return QLatin1String("isDate"); else if (typeName == QLatin1String("QRegExp")) return QLatin1String("isRegExp"); else if (typeName == QLatin1String("QObject*")) return QLatin1String("isQObject"); return QString(); } /*! Writes the code injections for the class \a meta_class that should be injected at position \a pos. */ static void writeInjectedCode(QTextStream &s, const AbstractMetaClass *meta_class, CodeSnip::Position pos) { CodeSnipList code_snips = meta_class->typeEntry()->codeSnips(); foreach (const CodeSnip &cs, code_snips) { if ((cs.language == TypeSystem::NativeCode) && (cs.position == pos)) { s << cs.code() << endl; } } } /*! Writes the code injections for the function \a fun of the class \a meta_class that should be injected at position \a pos. */ static void writeInjectedCode(QTextStream &s, const AbstractMetaClass *meta_class, const AbstractMetaFunction *fun, CodeSnip::Position pos) { FunctionModificationList mods = fun->modifications(meta_class); foreach (const FunctionModification &mod, mods) { if (!mod.isCodeInjection()) continue; foreach (const CodeSnip &cs, mod.snips) { if ((cs.language == TypeSystem::NativeCode) && (cs.position == pos)) { s << cs.code() << endl; } } } } /*! Writes a boolean expression that checks if the actual arguments are compatible with what the function expects. This is used to resolve ambiguous calls. */ static void writeArgumentTypeTests(QTextStream &stream, const AbstractMetaFunction *fun, const AbstractMetaArgumentList &arguments, int argc, int indent) { QString indentStr(indent, QLatin1Char(' ')); int j = 0; for (int i = 0; i < argc; ++j) { if (fun->argumentRemoved(j+1)) continue; if (i > 0) stream << endl << indentStr << "&& "; const AbstractMetaType *argType = 0; QString typeName = fun->typeReplaced(j+1); if (typeName.isEmpty()) { AbstractMetaArgument *arg = arguments.at(j); argType = arg->type(); typeName = normalizedType(argType); } QString scriptArg = QString::fromLatin1("context->argument(%0)").arg(i); if (argType && isSequenceType(argType)) { stream << scriptArg << ".isArray()"; } else if (typeName == "QVariant") { stream << "true"; } else { QString tester = builtinTypeTesterFunction(typeName); if (!tester.isEmpty()) { stream << scriptArg << "." << tester << "()"; } else if (typeName.endsWith('*')) { stream << "qscriptvalue_cast<" << typeName << ">(" << scriptArg << ")"; } else { // typeid-based test stream << "(qMetaTypeId<" << typeName; if (typeName.endsWith(QLatin1Char('>'))) stream << " "; stream << ">() == " << scriptArg << ".toVariant().userType())"; } } ++i; } } /*! Returns the name of the QScriptValue function to use to convert a value is of the given \a typeName, or an empty string if there is no such function. */ static QString builtinConversionFunction(const QString &typeName) { if (typeName == QLatin1String("QString")) return QLatin1String("toString"); else if (typeName == QLatin1String("double")) return QLatin1String("toNumber"); else if (typeName == QLatin1String("int")) return QLatin1String("toInt32"); else if (typeName == QLatin1String("uint")) return QLatin1String("toUInt32"); else if (typeName == QLatin1String("bool")) return QLatin1String("toBoolean"); else if (typeName == QLatin1String("QVariant")) return QLatin1String("toVariant"); else if (typeName == QLatin1String("QDateTime")) return QLatin1String("toDateTime"); else if (typeName == QLatin1String("QRegExp")) return QLatin1String("toRegExp"); else if (typeName == QLatin1String("QObject*")) return QLatin1String("toQObject"); return QString(); } /*! Generates script arguments --> C++ types conversion, in preparation for calling the native function we are binding. */ static int writePrepareArguments(QTextStream &stream, const AbstractMetaFunction *fun, const AbstractMetaArgumentList &arguments, int scriptArgc, int indent) { if (arguments.size() == 0) { Q_ASSERT(scriptArgc == 0); return 0; // nothing to do } QString indentStr(indent, QLatin1Char(' ')); int j = 0; for (int scriptArgIndex = 0; j < arguments.size(); ++j) { const AbstractMetaArgument *arg = arguments.at(j); bool isOptional = !arg->defaultValueExpression().isEmpty(); if (isOptional && (scriptArgIndex == scriptArgc)) break; QString conv = fun->conversionRule(TypeSystem::NativeCode, j+1); QString actualIn = QString::fromLatin1("context->argument(%0)").arg(scriptArgIndex); QString actualOut = QString::fromLatin1("_q_arg%0").arg(j); if (!conv.isEmpty()) { // custom conversion conv.replace(QString::fromLatin1("%in%"), actualIn); conv.replace(QString::fromLatin1("%out%"), actualOut); conv.replace(QString::fromLatin1("%this%"), QString::fromLatin1("_q_self")); stream << conv; } else { const AbstractMetaType *argType = 0; QString typeName = fun->typeReplaced(j+1); if (typeName.isEmpty()) { argType = arg->type(); typeName = normalizedType(argType); } stream << indentStr << typeName << " " << actualOut; QString converter; // ### generalize the QSet check (we should check if the type has push_back()) bool useToSequence = argType && isSequenceType(argType) && !argType->name().startsWith("Set"); if (useToSequence) { stream << ";" << endl; stream << indentStr << "qScriptValueToSequence("; } else { stream << " = "; converter = builtinConversionFunction(typeName); if (converter.isEmpty()) { // generic conversion stream << "qscriptvalue_cast<" << typeName; if (typeName.endsWith(QLatin1Char('>'))) stream << " "; stream << ">("; } } stream << actualIn; if (useToSequence) { stream << ", " << actualOut << ")"; } else { if (converter.isEmpty()) { stream << ")"; // close qscriptvalue_cast } else { stream << "." << converter << "()"; } } stream << ";" << endl; } if (!fun->argumentRemoved(j+1)) ++scriptArgIndex; } return j; } /*! Writes the arguments that are passed to the native function we are binding. Those arguments must have been prepared already in variables _q_arg0, _q_arg1, .. in the generated code. */ static void writeArguments(QTextStream &stream, int count) { for (int i = 0; i < count; ++i) { if (i > 0) stream << ", "; stream << "_q_arg" << i; } } /*! Writes a constructor call. */ static void writeConstructorCallAndReturn(QTextStream &stream, const AbstractMetaFunction *fun, int scriptArgc, const AbstractMetaClass *meta_class, int indent) { QString indentStr(indent, QLatin1Char(' ')); writeInjectedCode(stream, meta_class, fun, CodeSnip::Beginning); AbstractMetaArgumentList arguments = fun->arguments(); Q_ASSERT(arguments.size() >= scriptArgc); int nativeArgc = writePrepareArguments(stream, fun, arguments, scriptArgc, indent); stream << indentStr; if (meta_class->generateShellClass()) { stream << "QtScriptShell_" << meta_class->name(); } else { stream << meta_class->qualifiedCppName(); } bool useNew = meta_class->typeEntry()->isObject() || !hasDefaultConstructor(meta_class); if (useNew) stream << "*"; stream << " _q_cpp_result"; if (useNew) { stream << " = new "; if (meta_class->generateShellClass()) stream << "QtScriptShell_" << meta_class->name(); else stream << meta_class->qualifiedCppName(); } if (useNew || (nativeArgc != 0)) { stream << "("; writeArguments(stream, nativeArgc); stream << ")"; } stream << ";" << endl; stream << indentStr << "QScriptValue _q_result = context->engine()->new"; if (isQObjectBased(meta_class)) stream << "QObject"; else stream << "Variant"; stream << "(context->thisObject(), "; if (!isQObjectBased(meta_class)) stream << "qVariantFromValue("; if (meta_class->generateShellClass()) { stream << "(" << meta_class->qualifiedCppName(); if (useNew) stream << "*"; stream << ")"; } stream << "_q_cpp_result"; if (isQObjectBased(meta_class)) stream << ", QScriptEngine::AutoOwnership"; else stream << ")"; stream << ");" << endl; if (meta_class->generateShellClass()) { stream << indentStr << "_q_cpp_result"; if (useNew) stream << "->"; else stream << "."; stream << "__qtscript_self = _q_result;" << endl; } writeInjectedCode(stream, meta_class, fun, CodeSnip::End); stream << indentStr << "return _q_result;" << endl; } /*! Returns true if the given \a typeName has a QScriptValue constructor we can use, false otherwise. */ static bool hasScriptValueConstructor(const QString &typeName) { return (typeName == QLatin1String("bool")) || (typeName == QLatin1String("int")) || (typeName == QLatin1String("uint")) || (typeName == QLatin1String("double")) || (typeName == QLatin1String("QString")); } /*! Writes a function call. */ static void writeFunctionCallAndReturn(QTextStream &stream, const AbstractMetaFunction *fun, int scriptArgc, const AbstractMetaClass *meta_class, int indent) { QString indentStr(indent, QLatin1Char(' ')); AbstractMetaArgumentList arguments = fun->arguments(); Q_ASSERT(arguments.size() >= scriptArgc); writeInjectedCode(stream, meta_class, fun, CodeSnip::Beginning); int nativeArgc = writePrepareArguments(stream, fun, arguments, scriptArgc, indent); bool returnThisObject = fun->shouldReturnThisObject(); bool ignoreReturnValue = returnThisObject || fun->shouldIgnoreReturnValue(); stream << indentStr; AbstractMetaType *retType = fun->type(); bool constCastResult = false; if (retType && !ignoreReturnValue) { QString rsig = retType->cppSignature(); QString typeName = normalizedType(retType); stream << typeName << " _q_result = "; constCastResult = rsig.endsWith('*') && rsig.startsWith("const "); if (constCastResult) stream << "const_cast<" << typeName << ">("; } if (!fun->isStatic()) { // ### the friendly check should be enough... if (fun->isFriendly() || ((fun->name() == QLatin1String("operator_equal")) && ((meta_class->name() == QLatin1String("QPoint")) || (meta_class->name() == QLatin1String("QPointF")) || (meta_class->name() == QLatin1String("QRect")) || (meta_class->name() == QLatin1String("QRectF")) || (meta_class->name() == QLatin1String("QSize")) || (meta_class->name() == QLatin1String("QSizeF")) || (meta_class->name() == QLatin1String("QQuaternion")) || (meta_class->name() == QLatin1String("QMargins")) || (meta_class->name() == QLatin1String("QVector2D")) || (meta_class->name() == QLatin1String("QVector3D")) || (meta_class->name() == QLatin1String("QVector4D"))))) { stream << fun->originalName() << "("; stream << "*_q_self, "; } else { stream << "_q_self->"; stream << fun->originalName() << "("; } } else { stream << meta_class->qualifiedCppName() << "::"; stream << fun->originalName() << "("; } writeArguments(stream, nativeArgc); if (constCastResult) stream << ")"; stream << ");" << endl; writeInjectedCode(stream, meta_class, fun, CodeSnip::End); // write return statement stream << indentStr; if (returnThisObject) { stream << "return context->thisObject();"; } else { QString conv = fun->conversionRule(TypeSystem::NativeCode, 0); if (!conv.isEmpty()) { // custom conversion conv.replace(QString::fromLatin1("%in%"), "_q_result"); conv.replace(QString::fromLatin1("%out%"), "_q_convertedResult"); stream << conv; stream << "return qScriptValueFromValue(context->engine(), _q_convertedResult);"; } else { stream << "return "; if (retType) { if (isSequenceType(retType)) stream << "qScriptValueFromSequence"; else if (hasScriptValueConstructor(normalizedType(retType))) stream << "QScriptValue"; else stream << "qScriptValueFromValue"; stream << "(context->engine(), _q_result);"; } else { stream << "context->engine()->undefinedValue();"; } } } stream << endl; } /*! Returns true if the given function \a fun is operator>>() or operator<<() that streams from/to a Q{Data,Text}Stream, false otherwise. */ static bool isSpecialStreamingOperator(const AbstractMetaFunction *fun) { return ((fun->functionType() == AbstractMetaFunction::GlobalScopeFunction) && (fun->arguments().size() == 1) && (((fun->originalName() == "operator>>") && (fun->modifiedName() == "readFrom")) || ((fun->originalName() == "operator<<") && (fun->modifiedName() == "writeTo")))); } /*! Generates code that uses Q{Data,Text}Stream operator>>() or operator<<() to read/write an instance of meta_class. */ static void writeStreamingOperatorCall(QTextStream &stream, const AbstractMetaFunction *fun, const AbstractMetaClass * /*meta_class*/, int indent) { QString indentStr(indent, QLatin1Char(' ')); QString streamClassName = fun->arguments().at(0)->type()->name(); stream << indentStr << streamClassName << "* _q_arg0 = qscriptvalue_cast<" << streamClassName << "*>(context->argument(0));" << endl; stream << indentStr << "operator"; if (fun->modifiedName() == "readFrom") stream << ">>"; else stream << "<<"; stream << "(*_q_arg0, *_q_self);" << endl; stream << indentStr << "return context->engine()->undefinedValue();" << endl; } /*! Writes the constructor forwarding for \a meta_class. */ static void writeConstructorForwarding(QTextStream &stream, const AbstractMetaFunctionList &functions, const AbstractMetaClass *meta_class) { #if 0 stream << "/** signatures:" << endl; foreach (const AbstractMetaFunction *fun, functions) { stream << " * " << fun->signature() << endl; } stream << " */" << endl; #endif if (/*meta_class->isAbstract() ||*/ (functions.size() == 0)) { stream << " return context->throwError(QScriptContext::TypeError," << endl << " QString::fromLatin1(\"" << meta_class->name() << " cannot be constructed\"));" << endl; } else { stream << " if (context->thisObject().strictlyEquals(context->engine()->globalObject())) {" << endl << " return context->throwError(QString::fromLatin1(\"" << meta_class->name() << "(): Did you forget to construct with 'new'?\"));" << endl << " }" << endl; writeInjectedCode(stream, meta_class, CodeSnip::Constructor); QMap argcToFunctions; argcToFunctions = createArgcToFunctionsMap(functions); int argcMin = argcToFunctions.keys().first(); int argcMax = argcToFunctions.keys().last(); bool needElse = false; for (int i = argcMin; i <= argcMax; ++i) { AbstractMetaFunctionList funcs = argcToFunctions.value(i); if (funcs.isEmpty()) continue; if (needElse) stream << " else "; else stream << " "; needElse = true; stream << "if (context->argumentCount() == " << i << ") {" << endl; if ((funcs.size() == 1) || (i == 0)) { AbstractMetaFunction *fun = funcs.at(0); const int indent = 8; writeConstructorCallAndReturn(stream, fun, i, meta_class, indent); } else { // handle overloads for (int j = 0; j < funcs.size(); ++j) { AbstractMetaFunction *fun = funcs.at(j); stream << " "; if (j > 0) stream << "} else "; stream << "if ("; AbstractMetaArgumentList arguments = fun->arguments(); const int indent = 12; writeArgumentTypeTests(stream, fun, arguments, i, indent); stream << ") {" << endl; writeConstructorCallAndReturn(stream, fun, i, meta_class, indent); } stream << " }" << endl; } stream << " }"; } stream << endl; // writeThrowAmbiguityError(stream, meta_class, 0, signatures.toList()); } } /*! Returns a list of enum \a values that are actually unique. */ QList uniqueEnumValueIndexes(const AbstractMetaEnumValueList &values) { QMap map; for (int i = 0; i < values.count(); ++i) { AbstractMetaEnumValue *val = values.at(i); if (!map.contains(val->value())) map.insert(val->value(), i); } return map.values(); } /*! */ static bool isContiguousEnum(const QList &indexes, const AbstractMetaEnumValueList &values) { if (indexes.isEmpty()) return false; int prev = values.at(indexes.at(0))->value(); for (int i = 1; i < indexes.size(); ++i) { int curr = values.at(indexes.at(i))->value(); if (curr != prev + 1) return false; prev = curr; } return true; } static void writeCreateEnumClassHelper(QTextStream &stream) { stream << "static QScriptValue qtscript_create_enum_class_helper(" << endl << " QScriptEngine *engine," << endl << " QScriptEngine::FunctionSignature construct," << endl << " QScriptEngine::FunctionSignature valueOf," << endl << " QScriptEngine::FunctionSignature toString)" << endl << "{" << endl << " QScriptValue proto = engine->newObject();" << endl << " proto.setProperty(QString::fromLatin1(\"valueOf\")," << endl << " engine->newFunction(valueOf), QScriptValue::SkipInEnumeration);" << endl << " proto.setProperty(QString::fromLatin1(\"toString\")," << endl << " engine->newFunction(toString), QScriptValue::SkipInEnumeration);" << endl << " return engine->newFunction(construct, proto, 1);" << endl << "}" << endl << endl; } static void writeCreateFlagsClassHelper(QTextStream &stream) { stream << "static QScriptValue qtscript_create_flags_class_helper(" << endl << " QScriptEngine *engine," << endl << " QScriptEngine::FunctionSignature construct," << endl << " QScriptEngine::FunctionSignature valueOf," << endl << " QScriptEngine::FunctionSignature toString," << endl << " QScriptEngine::FunctionSignature equals)" << endl << "{" << endl << " QScriptValue proto = engine->newObject();" << endl << " proto.setProperty(QString::fromLatin1(\"valueOf\")," << endl << " engine->newFunction(valueOf), QScriptValue::SkipInEnumeration);" << endl << " proto.setProperty(QString::fromLatin1(\"toString\")," << endl << " engine->newFunction(toString), QScriptValue::SkipInEnumeration);" << endl << " proto.setProperty(QString::fromLatin1(\"equals\")," << endl << " engine->newFunction(equals), QScriptValue::SkipInEnumeration);" << endl << " return engine->newFunction(construct, proto);" << endl << "}" << endl << endl; } /*! Writes the enum \a enom belonging to the class \a meta_class to the given \a stream. */ static void writeEnumClass(QTextStream &stream, const AbstractMetaClass *meta_class, const AbstractMetaEnum *enom) { QString qualifiedCppNameColons; if (meta_class->name() != "Global") qualifiedCppNameColons = meta_class->qualifiedCppName() + "::"; QString qualifiedEnumName = qualifiedCppNameColons + enom->name(); QString qtScriptEnumName = meta_class->name() + "_" + enom->name(); stream << "//" << endl; stream << "// " << qualifiedEnumName << endl; stream << "//" << endl << endl; // determine unique values (aliases will cause switch statement to not compile) AbstractMetaEnumValueList values = enom->values(); QList uniqueIndexes = uniqueEnumValueIndexes(values); bool contiguous = isContiguousEnum(uniqueIndexes, values); // write arrays of values and keys stream << "static const " << qualifiedEnumName << " qtscript_" << qtScriptEnumName << "_values[] = {" << endl; for (int i = 0; i < uniqueIndexes.size(); ++i) { stream << " "; if (i > 0) stream << ", "; stream << qualifiedCppNameColons << values.at(uniqueIndexes.at(i))->name() << endl; } stream << "};" << endl << endl; stream << "static const char * const qtscript_" << qtScriptEnumName << "_keys[] = {" << endl; for (int i = 0; i < uniqueIndexes.size(); ++i) { stream << " "; if (i > 0) stream << ", "; stream << "\"" << values.at(uniqueIndexes.at(i))->name() << "\"" << endl; } stream << "};" << endl << endl; // write toString helper stream << "static QString qtscript_" << qtScriptEnumName << "_toStringHelper" << "(" << qualifiedEnumName << " value)" << endl; stream << "{" << endl; if (enom->hasQEnumsDeclaration() && (meta_class->qualifiedCppName() != "QTransform")) { stream << " const QMetaObject *meta = qtscript_" << meta_class->name() << "_metaObject();" << endl; stream << " int idx = meta->indexOfEnumerator(\"" << enom->name() << "\");" << endl; stream << " Q_ASSERT(idx != -1);" << endl; stream << " QMetaEnum menum = meta->enumerator(idx);" << endl; stream << " return QString::fromLatin1(menum.valueToKey(value));" << endl; } else { if (contiguous) { stream << " if ((value >= " << qualifiedCppNameColons << values.at(uniqueIndexes.first())->name() << ")" << " && (value <= " << qualifiedCppNameColons << values.at(uniqueIndexes.last())->name() << "))" << endl << " return qtscript_" << qtScriptEnumName << "_keys[static_cast(value)-static_cast(" << qualifiedCppNameColons << values.at(uniqueIndexes.first())->name() << ")];" << endl; } else { stream << " for (int i = 0; i < " << uniqueIndexes.size() << "; ++i) {" << endl << " if (qtscript_" << qtScriptEnumName << "_values[i] == value)" << endl << " return QString::fromLatin1(qtscript_" << qtScriptEnumName << "_keys[i]);" << endl << " }" << endl; } stream << " return QString();" << endl; } stream << "}" << endl << endl; // write QScriptValue <--> C++ conversion functions stream << "static QScriptValue qtscript_" << qtScriptEnumName << "_toScriptValue(" << "QScriptEngine *engine, const " << qualifiedEnumName << " &value)" << endl << "{" << endl << " QScriptValue clazz = engine->globalObject().property(QString::fromLatin1(\"" << meta_class->name() << "\"));" << endl // << " QScriptValue enumClazz = clazz.property(QString::fromLatin1(\"" // << enom->name() << "\"));" << endl << " return clazz.property(qtscript_" << qtScriptEnumName << "_toStringHelper(value));" << endl << "}" << endl << endl; stream << "static void qtscript_" << qtScriptEnumName << "_fromScriptValue(" << "const QScriptValue &value, " << qualifiedEnumName << " &out)" << endl << "{" << endl << " out = qvariant_cast<" << qualifiedEnumName << ">(value.toVariant());" << endl << "}" << endl << endl; // write constructor stream << "static QScriptValue qtscript_construct_" << qtScriptEnumName << "(QScriptContext *context, QScriptEngine *engine)" << endl; stream << "{" << endl; stream << " int arg = context->argument(0).toInt32();" << endl; if (enom->hasQEnumsDeclaration() && (meta_class->qualifiedCppName() != "QTransform")) { stream << " const QMetaObject *meta = qtscript_" << meta_class->name() << "_metaObject();" << endl; stream << " int idx = meta->indexOfEnumerator(\"" << enom->name() << "\");" << endl; stream << " Q_ASSERT(idx != -1);" << endl; stream << " QMetaEnum menum = meta->enumerator(idx);" << endl; stream << " if (menum.valueToKey(arg) != 0)" << endl; stream << " return qScriptValueFromValue(engine, static_cast<" << qualifiedEnumName << ">(arg));" << endl; } else { if (contiguous) { stream << " if ((arg >= " << qualifiedCppNameColons << values.at(uniqueIndexes.first())->name() << ")" << " && (arg <= " << qualifiedCppNameColons << values.at(uniqueIndexes.last())->name() << "))" << endl; stream << " return qScriptValueFromValue(engine, static_cast<" << qualifiedEnumName << ">(arg));" << endl; } else { stream << " for (int i = 0; i < " << uniqueIndexes.size() << "; ++i) {" << endl << " if (qtscript_" << qtScriptEnumName << "_values[i] == arg)" << endl; stream << " return qScriptValueFromValue(engine, static_cast<" << qualifiedEnumName << ">(arg));" << endl; stream << " }" << endl; } } stream << " return context->throwError(QString::fromLatin1(\"" << enom->name() << "(): invalid enum value (%0)\").arg(arg));" << endl; stream << "}" << endl; stream << endl; // write prototype.valueOf() stream << "static QScriptValue qtscript_" << qtScriptEnumName << "_valueOf(QScriptContext *context, QScriptEngine *engine)" << endl; stream << "{" << endl; stream << " " << qualifiedEnumName << " value = " << "qscriptvalue_cast<" << qualifiedEnumName << ">(context->thisObject());" << endl; stream << " return QScriptValue(engine, static_cast(value));" << endl; stream << "}" << endl; stream << endl; // write prototype.toString() stream << "static QScriptValue qtscript_" << qtScriptEnumName << "_toString(QScriptContext *context, QScriptEngine *engine)" << endl; stream << "{" << endl; stream << " " << qualifiedEnumName << " value = " << "qscriptvalue_cast<" << qualifiedEnumName << ">(context->thisObject());" << endl; stream << " return QScriptValue(engine, qtscript_" << qtScriptEnumName << "_toStringHelper(value));" << endl; stream << "}" << endl; stream << endl; // write class creation function stream << "static QScriptValue qtscript_create_" << qtScriptEnumName << "_class(QScriptEngine *engine, QScriptValue &clazz)" << endl; stream << "{" << endl; stream << " QScriptValue ctor = qtscript_create_enum_class_helper(" << endl << " engine, qtscript_construct_" << qtScriptEnumName << "," << endl << " qtscript_" << qtScriptEnumName << "_valueOf, qtscript_" << qtScriptEnumName << "_toString);" << endl; stream << " qScriptRegisterMetaType<" << qualifiedEnumName << ">(engine, " << "qtscript_" << qtScriptEnumName << "_toScriptValue," << endl << " qtscript_" << qtScriptEnumName << "_fromScriptValue," << " ctor.property(QString::fromLatin1(\"prototype\")));" << endl; // enum values are properties of the constructor stream << " for (int i = 0; i < " << uniqueIndexes.size() << "; ++i) {" << endl << " clazz.setProperty(QString::fromLatin1(qtscript_" << qtScriptEnumName << "_keys[i])," << endl << " engine->newVariant(qVariantFromValue(qtscript_" << qtScriptEnumName << "_values[i]))," << endl << " QScriptValue::ReadOnly | QScriptValue::Undeletable);" << endl << " }" << endl; stream << " return ctor;" << endl; stream << "}" << endl; stream << endl; // write flags class too, if any FlagsTypeEntry *flags = enom->typeEntry()->flags(); if (!flags) return; QString qualifiedFlagsName = qualifiedCppNameColons + flags->targetLangName(); QString qtScriptFlagsName = meta_class->name() + "_" + flags->targetLangName(); stream << "//" << endl; stream << "// " << qualifiedFlagsName << endl; stream << "//" << endl << endl; // write QScriptValue <--> C++ conversion functions stream << "static QScriptValue qtscript_" << qtScriptFlagsName << "_toScriptValue(" << "QScriptEngine *engine, const " << qualifiedFlagsName << " &value)" << endl << "{" << endl << " return engine->newVariant(qVariantFromValue(value));" << endl << "}" << endl << endl; stream << "static void qtscript_" << qtScriptFlagsName << "_fromScriptValue(" << "const QScriptValue &value, " << qualifiedFlagsName << " &out)" << endl << "{" << endl << " QVariant var = value.toVariant();" << endl << " if (var.userType() == qMetaTypeId<" << qualifiedFlagsName << ">())" << endl << " out = qvariant_cast<" << qualifiedFlagsName << ">(var);" << endl << " else if (var.userType() == qMetaTypeId<" << qualifiedEnumName << ">())" << endl << " out = qvariant_cast<" << qualifiedEnumName << ">(var);" << endl << " else" << endl << " out = 0;" << endl << "}" << endl << endl; // write constructor stream << "static QScriptValue qtscript_construct_" << qtScriptFlagsName << "(QScriptContext *context, QScriptEngine *engine)" << endl; stream << "{" << endl; stream << " " << qualifiedFlagsName << " result = 0;" << endl; stream << " if ((context->argumentCount() == 1) && context->argument(0).isNumber()) {" << endl; stream << " result = static_cast<" << qualifiedFlagsName << ">(context->argument(0).toInt32());" << endl; stream << " } else {" << endl; stream << " for (int i = 0; i < context->argumentCount(); ++i) {" << endl; stream << " QVariant v = context->argument(i).toVariant();" << endl; stream << " if (v.userType() != qMetaTypeId<" << qualifiedEnumName << ">()) {" << endl; stream << " return context->throwError(QScriptContext::TypeError," << endl << " QString::fromLatin1(\"" << flags->targetLangName() << "(): argument %0 is not of type " << enom->name() << "\").arg(i));" << endl; stream << " }" << endl; stream << " result |= qvariant_cast<" << qualifiedEnumName << ">(v);" << endl; stream << " }" << endl; stream << " }" << endl; stream << " return engine->newVariant(qVariantFromValue(result));" << endl; stream << "}" << endl; stream << endl; // write prototype.valueOf() stream << "static QScriptValue qtscript_" << qtScriptFlagsName << "_valueOf(QScriptContext *context, QScriptEngine *engine)" << endl; stream << "{" << endl; stream << " " << qualifiedFlagsName << " value = " << "qscriptvalue_cast<" << qualifiedFlagsName << ">(context->thisObject());" << endl; stream << " return QScriptValue(engine, static_cast(value));" << endl; stream << "}" << endl; stream << endl; // write prototype.toString() stream << "static QScriptValue qtscript_" << qtScriptFlagsName << "_toString(QScriptContext *context, QScriptEngine *engine)" << endl; stream << "{" << endl; stream << " " << qualifiedFlagsName << " value = " << "qscriptvalue_cast<" << qualifiedFlagsName << ">(context->thisObject());" << endl; stream << " QString result;" << endl; stream << " for (int i = 0; i < " << uniqueIndexes.size() << "; ++i) {" << endl << " if ((value & qtscript_" << qtScriptEnumName << "_values[i])" << " == qtscript_" << qtScriptEnumName << "_values[i]) {" << endl << " if (!result.isEmpty())" << endl << " result.append(QString::fromLatin1(\",\"));" << endl << " result.append(QString::fromLatin1(qtscript_" << qtScriptEnumName << "_keys[i]));" << endl << " }" << endl << " }" << endl << " return QScriptValue(engine, result);" << endl << "}" << endl << endl; // write prototype.equals() stream << "static QScriptValue qtscript_" << qtScriptFlagsName << "_equals(QScriptContext *context, QScriptEngine *engine)" << endl << "{" << endl << " QVariant thisObj = context->thisObject().toVariant();" << endl << " QVariant otherObj = context->argument(0).toVariant();" << endl << " return QScriptValue(engine, ((thisObj.userType() == otherObj.userType()) &&" << endl << " (thisObj.value<" << qualifiedFlagsName << ">() == otherObj.value<" << qualifiedFlagsName << ">())));" << endl << "}" << endl << endl; // write class creation function stream << "static QScriptValue qtscript_create_" << qtScriptFlagsName << "_class(QScriptEngine *engine)" << endl; stream << "{" << endl; stream << " QScriptValue ctor = qtscript_create_flags_class_helper(" << endl << " engine, qtscript_construct_" << qtScriptFlagsName << ", qtscript_" << qtScriptFlagsName << "_valueOf," << endl << " qtscript_" << qtScriptFlagsName << "_toString, qtscript_" << qtScriptFlagsName << "_equals);" << endl; stream << " qScriptRegisterMetaType<" << qualifiedFlagsName << ">(engine, " << "qtscript_" << qtScriptFlagsName << "_toScriptValue," << endl << " qtscript_" << qtScriptFlagsName << "_fromScriptValue," << " ctor.property(QString::fromLatin1(\"prototype\")));" << endl; stream << " return ctor;" << endl; stream << "}" << endl; stream << endl; } /*! Declares the given \a typeName if it hasn't been declared already, and adds it to the set of registered type names. */ void maybeDeclareMetaType(QTextStream &stream, const QString &typeName, QSet ®isteredTypeNames) { QString name = typeName; if (name.endsWith(QLatin1Char('&'))) name.chop(1); if (registeredTypeNames.contains(name) || (QMetaType::type(typeName.toLatin1()) != 0)) return; if (name.contains(QLatin1Char(','))) { // need to expand the Q_DECLARE_METATYPE macro manually, // otherwise the compiler will choke stream << "template <> \\" << endl << "struct QMetaTypeId< " << name << " > \\" << endl << "{ \\" << endl << " enum { Defined = 1 }; \\" << endl << " static int qt_metatype_id() \\" << endl << " { \\" << endl << " static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \\" << endl << " if (!metatype_id) \\" << endl << " metatype_id = qRegisterMetaType< " << name << " >(\"" << name << "\"); \\" << endl << " return metatype_id; \\" << endl << " } \\" << endl << "};" << endl; } else { stream << "Q_DECLARE_METATYPE(" << name << ")" << endl; } registeredTypeNames << name; } /*! Declares the given \a type recursively (i.e. subtypes of a composite type are also declared). */ static void declareTypeRecursive(QTextStream &stream, const AbstractMetaType *type, QSet ®isteredTypeNames) { if (!type) return; QList subTypes = type->instantiations(); for (int i = 0; i < subTypes.size(); ++i) declareTypeRecursive(stream, subTypes.at(i), registeredTypeNames); QString typeName = normalizedType(type); if (typeName == QLatin1String("QStringList")) return; // ### wtf... maybeDeclareMetaType(stream, typeName, registeredTypeNames); } /*! Declares the types associated with the given \a functions. */ void declareFunctionMetaTypes(QTextStream &stream, const AbstractMetaFunctionList &functions, QSet ®isteredTypeNames) { for (int i = 0; i < functions.size(); ++i) { AbstractMetaFunction *fun = functions.at(i); if (isSpecialStreamingOperator(fun)) { maybeDeclareMetaType(stream, fun->arguments().at(0)->type()->name() + "*", registeredTypeNames); continue; } AbstractMetaArgumentList arguments = fun->arguments(); for (int j = 0; j < arguments.size(); ++j) { if (fun->argumentRemoved(j+1)) continue; QString repl = fun->typeReplaced(j+1); if (!repl.isEmpty()) { maybeDeclareMetaType(stream, repl, registeredTypeNames); } else { const AbstractMetaArgument *arg = arguments.at(j); declareTypeRecursive(stream, arg->type(), registeredTypeNames); } } QString retRepl = fun->typeReplaced(0); if (!retRepl.isEmpty()) maybeDeclareMetaType(stream, retRepl, registeredTypeNames); else declareTypeRecursive(stream, fun->type(), registeredTypeNames); } } /*! Returns true if we don't care about the given enum \a enom, false otherwise. */ static bool shouldIgnoreEnum(const AbstractMetaEnum *enom) { return !enom->wasPublic() || (enom->name() == "enum_1"); } /*! Declares the types associated with the enums of the given \a meta_class. */ void declareEnumMetaTypes(QTextStream &stream, const AbstractMetaClass *meta_class, QSet ®isteredTypeNames) { AbstractMetaEnumList enums = meta_class->enums(); for (int i = 0; i < enums.size(); ++i) { const AbstractMetaEnum *enom = enums.at(i); if (shouldIgnoreEnum(enom)) continue; if (meta_class->name() == "Global") maybeDeclareMetaType(stream, enom->name(), registeredTypeNames); else maybeDeclareMetaType(stream, QString::fromLatin1("%0::%1") .arg(meta_class->qualifiedCppName()).arg(enom->name()), registeredTypeNames); FlagsTypeEntry *flags = enom->typeEntry()->flags(); if (flags) { maybeDeclareMetaType(stream, QString::fromLatin1("QFlags<%0::%1>") .arg(meta_class->qualifiedCppName()).arg(enom->name()), registeredTypeNames); } } } /*! Returns the maximum function length among \a functions. */ static int maxFunctionLength(const AbstractMetaFunctionList &functions) { int result = 0; for (int i = 0; i < functions.size(); ++i) result = qMax(result, functions.at(i)->arguments().size()); return result; } /*! Writes a prototype/static function. */ static void writeFunctionForwarding(QTextStream &stream, const AbstractMetaClass *meta_class, const AbstractMetaFunctionList &functions) { #if 0 stream << "/** signatures:" << endl; foreach (const AbstractMetaFunction *fun, functions) { stream << " * " << fun->signature() << endl; } stream << " */" << endl; #endif QMap argcToFunctions; argcToFunctions = createArgcToFunctionsMap(functions); QSet signatures; int argcMin = argcToFunctions.keys().first(); int argcMax = argcToFunctions.keys().last(); for (int i = argcMin; i <= argcMax; ++i) { AbstractMetaFunctionList funcs = argcToFunctions.value(i); if (funcs.isEmpty()) continue; stream << " if (context->argumentCount() == " << i << ") {" << endl; if (funcs.size() == 1 || i == 0) { AbstractMetaFunction *fun = funcs.at(0); const int indent = 8; // special case for Q{Data,Text}Stream streaming operators if (isSpecialStreamingOperator(fun)) writeStreamingOperatorCall(stream, fun, meta_class, indent); else writeFunctionCallAndReturn(stream, fun, i, meta_class, indent); signatures.insert(fun->targetLangSignature()); } else { // handle overloads QStringList sigs; for (int j = 0; j < funcs.size(); ++j) { AbstractMetaFunction *fun = funcs.at(j); sigs.append(fun->signature()); stream << " "; if (j > 0) stream << "} else "; stream << "if ("; AbstractMetaArgumentList arguments = fun->arguments(); const int indent = 12; writeArgumentTypeTests(stream, fun, arguments, i, indent); stream << ") {" << endl; writeFunctionCallAndReturn(stream, fun, i, meta_class, indent); signatures.insert(fun->targetLangSignature()); } stream << " }" << endl; } stream << " }" << endl; } } static void writePrototypeCall(QTextStream &s, const AbstractMetaClass *meta_class, const QMap &nameToFunctions, int prototypeFunctionsOffset) { s << "static QScriptValue qtscript_" << meta_class->name() << "_prototype_call(QScriptContext *context, QScriptEngine *)" << endl << "{" << endl; s << "#if QT_VERSION > 0x040400" << endl; s << " Q_ASSERT(context->callee().isFunction());" << endl << " uint _id = context->callee().data().toUInt32();" << endl; s << "#else" << endl << " uint _id;" << endl << " if (context->callee().isFunction())" << endl << " _id = context->callee().data().toUInt32();" << endl << " else" << endl << " _id = 0xBABE0000 + " << nameToFunctions.size() << ";" << endl; s << "#endif" << endl; s << " Q_ASSERT((_id & 0xFFFF0000) == 0xBABE0000);" << endl << " _id &= 0x0000FFFF;" << endl; // cast the thisObject to C++ type s << " "; #ifndef GENERATOR_NO_PROTECTED_FUNCTIONS if (meta_class->hasProtectedFunctions()) s << "qtscript_"; #endif s << meta_class->qualifiedCppName() << "* _q_self = "; #ifndef GENERATOR_NO_PROTECTED_FUNCTIONS if (meta_class->hasProtectedFunctions()) s << "reinterpret_castname() << "*>("; #endif s << "qscriptvalue_cast<" << meta_class->qualifiedCppName() << "*>(context->thisObject())"; #ifndef GENERATOR_NO_PROTECTED_FUNCTIONS if (meta_class->hasProtectedFunctions()) s << ")"; #endif s << ";" << endl << " if (!_q_self) {" << endl << " return context->throwError(QScriptContext::TypeError," << endl << " QString::fromLatin1(\"" << meta_class->name() << ".%0(): this object is not a " << meta_class->name() << "\")" << endl << " .arg(qtscript_" << meta_class->name() << "_function_names[_id+" << prototypeFunctionsOffset <<"]));" << endl << " }" << endl << endl; s << " switch (_id) {" << endl; QMap::const_iterator it; int index = 0; for (it = nameToFunctions.constBegin(); it != nameToFunctions.constEnd(); ++it) { s << " case " << index << ":" << endl; writeFunctionForwarding(s, meta_class, it.value()); s << " break;" << endl << endl; ++index; } if (!meta_class->hasDefaultToStringFunction()) { s << " case " << index << ": {" << endl; s << " QString result"; FunctionModelItem fun = meta_class->hasToStringCapability(); if (fun) { int indirections = fun->arguments().at(1)->type().indirections(); QString deref = QLatin1String(indirections == 0 ? "*" : ""); s << ";" << endl << " QDebug d(&result);" << endl << " d << " << deref << "_q_self;" << endl; } else { // ### FIXME: can cause compile error // s << "=QString(\"" << meta_class->name() << "(0x%1)\").arg((int)_q_self, 0, 16);" << endl; s << " = QString::fromLatin1(\"" << meta_class->name() << "\");" << endl; } s << " return QScriptValue(context->engine(), result);" << endl << " }" << endl << endl; } s << " default:" << endl << " Q_ASSERT(false);" << endl << " }" << endl; s << " return qtscript_" << meta_class->name() << "_throw_ambiguity_error_helper(context," << endl << " qtscript_" << meta_class->name() << "_function_names[_id+" << prototypeFunctionsOffset << "]," << endl << " qtscript_" << meta_class->name() << "_function_signatures[_id+" << prototypeFunctionsOffset << "]);" << endl; s << "}" << endl << endl; } static void writeStaticCall(QTextStream &s, const AbstractMetaClass *meta_class, const AbstractMetaFunctionList &constructors, const QMap &nameToFunctions) { s << "static QScriptValue qtscript_" << meta_class->name() << "_static_call(QScriptContext *context, QScriptEngine *)" << endl << "{" << endl; s << " uint _id = context->callee().data().toUInt32();" << endl << " Q_ASSERT((_id & 0xFFFF0000) == 0xBABE0000);" << endl << " _id &= 0x0000FFFF;" << endl; s << " switch (_id) {" << endl; s << " case 0:" << endl; writeConstructorForwarding(s, constructors, meta_class); s << " break;" << endl << endl; QMap::const_iterator it; int index = 1; for (it = nameToFunctions.constBegin(); it != nameToFunctions.constEnd(); ++it) { s << " case " << index << ":" << endl; writeFunctionForwarding(s, meta_class, it.value()); s << " break;" << endl << endl; ++index; } s << " default:" << endl << " Q_ASSERT(false);" << endl << " }" << endl; s << " return qtscript_" << meta_class->name() << "_throw_ambiguity_error_helper(context," << endl << " qtscript_" << meta_class->name() << "_function_names[_id]," << endl << " qtscript_" << meta_class->name() << "_function_signatures[_id]);" << endl; s << "}" << endl << endl; } /*! Writes the include defined by \a inc to \a stream. */ void writeInclude(QTextStream &stream, const Include &inc) { if (inc.name.isEmpty()) return; if (inc.type == Include::TargetLangImport) return; stream << "#include "; if (inc.type == Include::IncludePath) stream << "<"; else stream << "\""; stream << inc.name; if (inc.type == Include::IncludePath) stream << ">"; else stream << "\""; stream << endl; } static void writeHelperFunctions(QTextStream &stream, const AbstractMetaClass *meta_class) { stream << "static QScriptValue qtscript_" << meta_class->name() << "_throw_ambiguity_error_helper(" << endl << " QScriptContext *context, const char *functionName, const char *signatures)" << endl << "{" << endl << " QStringList lines = QString::fromLatin1(signatures).split(QLatin1Char('\\n'));" << endl << " QStringList fullSignatures;" << endl << " for (int i = 0; i < lines.size(); ++i)" << endl << " fullSignatures.append(QString::fromLatin1(\"%0(%1)\").arg(functionName).arg(lines.at(i)));" << endl << " return context->throwError(QString::fromLatin1(\"" << meta_class->name() << "::%0(): could not find a function match; candidates are:\\n%1\")" << endl << " .arg(functionName).arg(fullSignatures.join(QLatin1String(\"\\n\"))));" << endl << "}" << endl << endl; } void writeQtScriptQtBindingsLicense(QTextStream &stream) { stream << "/****************************************************************************" << endl << "**" << endl << "** Copyright (C) 2008 Trolltech ASA. All rights reserved." << endl << "**" << endl << "** This file is part of the Qt Script Qt Bindings project on Trolltech Labs." << endl << "**" << endl << "** This file may be used under the terms of the GNU General Public" << endl << "** License version 2.0 as published by the Free Software Foundation" << endl << "** and appearing in the file LICENSE.GPL included in the packaging of" << endl << "** this file. Please review the following information to ensure GNU" << endl << "** General Public Licensing requirements will be met:" << endl << "** http://www.trolltech.com/products/qt/opensource.html" << endl << "**" << endl << "** If you are unsure which license is appropriate for your use, please" << endl << "** review the following information:" << endl << "** http://www.trolltech.com/products/qt/licensing.html or contact the" << endl << "** sales department at sales@trolltech.com." << endl << "**" << endl << "** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE" << endl << "** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE." << endl << "**" << endl << "****************************************************************************/" << endl << endl; } /*! Finds the functions in \a meta_class that we actually want to generate bindings for. */ void findPrototypeAndStaticFunctions( const AbstractMetaClass *meta_class, QMap &nameToPrototypeFunctions, QMap &nameToStaticFunctions) { AbstractMetaFunctionList functions = meta_class->functionsInTargetLang(); for (int i = 0; i < functions.size(); ++i) { AbstractMetaFunction* func = functions.at(i); if (!func->isNormal()) continue; #ifdef GENERATOR_NO_PROTECTED_FUNCTIONS if (func->wasProtected()) continue; #endif if (func->declaringClass() != meta_class) continue; // function inherited through prototype if (func->isPropertyReader() || func->isPropertyWriter()) continue; // no point in including property accessors if (func->isSlot() || func->isSignal() || func->isInvokable()) continue; // no point in including signals and slots QMap &map = func->isStatic() ? nameToStaticFunctions : nameToPrototypeFunctions; map[func->modifiedName()].append(func); } } static void writeFunctionSignaturesString(QTextStream &s, const AbstractMetaFunctionList &functions) { s << "\""; for (int i = 0; i < functions.size(); ++i) { if (i > 0) s << "\\n"; QString sig = functions.at(i)->targetLangSignature(); sig = sig.mid(sig.indexOf('(') + 1); sig.chop(1); s << sig; } s << "\""; } /*! Writes the whole native binding for the class \a meta_class. */ void ClassGenerator::write(QTextStream &stream, const AbstractMetaClass *meta_class) { if (FileOut::license) writeQtScriptQtBindingsLicense(stream); // write common includes stream << "#include " << endl; stream << "#include " << endl; stream << "#include " << endl; stream << "#include " << endl; stream << "#include " << endl; stream << "#include " << endl; stream << endl; // write class-specific includes { Include inc = meta_class->typeEntry()->include(); writeInclude(stream, inc); } { IncludeList includes = meta_class->typeEntry()->extraIncludes(); qSort(includes.begin(), includes.end()); foreach (const Include &i, includes) { writeInclude(stream, i); } } stream << endl; if (meta_class->generateShellClass()) { stream << "#include \"qtscriptshell_" << meta_class->name() << ".h\"" << endl; stream << endl; } AbstractMetaEnumList enums = meta_class->enums(); { // kill the enums we don't care about AbstractMetaEnumList::iterator it; for (it = enums.begin(); it != enums.end(); ) { if (shouldIgnoreEnum(*it)) it = enums.erase(it); else ++it; } } if (meta_class->isNamespace() || meta_class->name() == "Global") { QMap includes; foreach (AbstractMetaEnum *enom, enums) { Include include = enom->typeEntry()->include(); includes.insert(include.toString(), include); } foreach (const Include &i, includes) { writeInclude(stream, i); } stream << endl; } if (meta_class->name() == "Global") { stream << "class Global {};" << endl; stream << endl; } // find constructors AbstractMetaFunctionList ctors = findConstructors(meta_class); bool hasDefaultCtor = findDefaultConstructor(ctors) != 0; // find interesting functions QMap nameToPrototypeFunctions; QMap nameToStaticFunctions; findPrototypeAndStaticFunctions(meta_class, nameToPrototypeFunctions, nameToStaticFunctions); int staticFunctionsOffset = 1; int prototypeFunctionsOffset = staticFunctionsOffset + nameToStaticFunctions.size(); // write table of function names stream << "static const char * const qtscript_" << meta_class->name() << "_function_names[] = {" << endl; stream << " \"" << meta_class->name() << "\"" << endl; { QMap::const_iterator it; stream << " // static" << endl; for (it = nameToStaticFunctions.constBegin(); it != nameToStaticFunctions.constEnd(); ++it) { stream << " , "; stream << "\"" << it.key() << "\"" << endl; } stream << " // prototype" << endl; for (it = nameToPrototypeFunctions.constBegin(); it != nameToPrototypeFunctions.constEnd(); ++it) { QString functionName = it.key(); QString scriptName = functionName; if (functionName == QLatin1String("operator_equal")) scriptName = QLatin1String("equals"); stream << " , "; stream << "\"" << scriptName << "\"" << endl; } if (!meta_class->hasDefaultToStringFunction()) stream << " , \"toString\"" << endl; } stream << "};" << endl << endl; // write table of function signatures stream << "static const char * const qtscript_" << meta_class->name() << "_function_signatures[] = {" << endl; stream << " "; writeFunctionSignaturesString(stream, ctors); stream << endl; { QMap::const_iterator it; stream << " // static" << endl; for (it = nameToStaticFunctions.constBegin(); it != nameToStaticFunctions.constEnd(); ++it) { stream << " , "; writeFunctionSignaturesString(stream, it.value()); stream << endl; } stream << " // prototype" << endl; for (it = nameToPrototypeFunctions.constBegin(); it != nameToPrototypeFunctions.constEnd(); ++it) { stream << " , "; writeFunctionSignaturesString(stream, it.value()); stream << endl; } if (!meta_class->hasDefaultToStringFunction()) stream << "\"\"" << endl; } stream << "};" << endl << endl; // write table of function lengths stream << "static const int qtscript_" << meta_class->name() << "_function_lengths[] = {" << endl; stream << " " << maxFunctionLength(ctors) << endl; { QMap::const_iterator it; stream << " // static" << endl; for (it = nameToStaticFunctions.constBegin(); it != nameToStaticFunctions.constEnd(); ++it) { stream << " , " << maxFunctionLength(it.value()) << endl; } stream << " // prototype" << endl; for (it = nameToPrototypeFunctions.constBegin(); it != nameToPrototypeFunctions.constEnd(); ++it) { stream << " , " << maxFunctionLength(it.value()) << endl; } if (!meta_class->hasDefaultToStringFunction()) stream << " , 0" << endl; } stream << "};" << endl << endl; #ifndef GENERATOR_NO_PROTECTED_FUNCTIONS if (meta_class->hasProtectedFunctions()) { // write a friendly class stream << "class qtscript_" << meta_class->name() << " : public " << meta_class->qualifiedCppName() << endl; stream << "{" << endl; for (int x = 0; x < 2; ++x) { QMap &map = x ? nameToStaticFunctions : nameToPrototypeFunctions; QMap::const_iterator it; for (it = map.constBegin(); it != map.constEnd(); ++it) { AbstractMetaFunctionList functions = it.value(); for (int i = 0; i < functions.size(); ++i) { if (functions.at(i)->isProtected()) { stream << " friend QScriptValue qtscript_" << meta_class->name() << "_" << it.key(); if (functions.at(i)->isStatic()) stream << "_static"; stream << "(QScriptContext *, QScriptEngine *);" << endl; break; } } } } stream << "};" << endl; stream << endl; } #endif writeHelperFunctions(stream, meta_class); // write metaobject getter if we need it if (hasQEnums(enums) && (meta_class->qualifiedCppName() != "QTransform")) { if (meta_class->qualifiedCppName() == "Qt") { stream << "struct qtscript_Qt_metaObject_helper : private QObject" << endl << "{" << endl << " static const QMetaObject *get()" << endl << " { return &static_cast(0)->staticQtMetaObject; }" << endl << "};" << endl << endl; } stream << "static const QMetaObject *qtscript_" << meta_class->name() << "_metaObject()" << endl << "{" << endl << " return "; if (meta_class->qualifiedCppName() == "Qt") stream << "qtscript_Qt_metaObject_helper::get()"; else stream << "&" << meta_class->qualifiedCppName() << "::staticMetaObject"; stream << ";" << endl << "}" << endl << endl; } // write metatype declarations { QSet registeredTypeNames = m_qmetatype_declared_typenames; if (!meta_class->isNamespace()) { if (meta_class->typeEntry()->isValue() && hasDefaultCtor) maybeDeclareMetaType(stream, meta_class->qualifiedCppName(), registeredTypeNames); else registeredTypeNames << meta_class->qualifiedCppName(); maybeDeclareMetaType(stream, meta_class->qualifiedCppName() + "*", registeredTypeNames); } if (meta_class->generateShellClass()) { if (meta_class->typeEntry()->isValue()) { maybeDeclareMetaType(stream, "QtScriptShell_" + meta_class->name(), registeredTypeNames); } maybeDeclareMetaType(stream, "QtScriptShell_" + meta_class->name() + "*", registeredTypeNames); } declareEnumMetaTypes(stream, meta_class, registeredTypeNames); for (int x = 0; x < 2; ++x) { QMap &map = x ? nameToStaticFunctions : nameToPrototypeFunctions; QMap::const_iterator it; for (it = map.constBegin(); it != map.constEnd(); ++it) { declareFunctionMetaTypes(stream, it.value(), registeredTypeNames); } } declareFunctionMetaTypes(stream, ctors, registeredTypeNames); if (meta_class->baseClass() != 0) { maybeDeclareMetaType(stream, meta_class->baseClass()->qualifiedCppName() + QLatin1String("*"), registeredTypeNames); } foreach (AbstractMetaClass *iface, meta_class->interfaces()) { AbstractMetaClass *impl = iface->primaryInterfaceImplementor(); maybeDeclareMetaType(stream, impl->qualifiedCppName() + QLatin1String("*"), registeredTypeNames); } // ### hackety hack if (meta_class->name().endsWith("Gradient")) maybeDeclareMetaType(stream, "QGradient", registeredTypeNames); stream << endl; } writeInjectedCode(stream, meta_class, CodeSnip::Beginning); // write enum classes if (!enums.isEmpty()) { writeCreateEnumClassHelper(stream); if (hasFlags(enums)) writeCreateFlagsClassHelper(stream); for (int i = 0; i < enums.size(); ++i) { const AbstractMetaEnum *enom = enums.at(i); writeEnumClass(stream, meta_class, enom); } } stream << "//" << endl; stream << "// " << meta_class->name() << endl; stream << "//" << endl << endl; if (!meta_class->isNamespace()) { if (!nameToPrototypeFunctions.isEmpty() || !meta_class->hasDefaultToStringFunction()) writePrototypeCall(stream, meta_class, nameToPrototypeFunctions, prototypeFunctionsOffset); } writeStaticCall(stream, meta_class, ctors, nameToStaticFunctions); if (isQObjectBased(meta_class)) { // write C++ <--> script conversion functions stream << "static QScriptValue qtscript_" << meta_class->name() << "_toScriptValue(QScriptEngine *engine, " << meta_class->qualifiedCppName() << "* const &in)" << endl << "{" << endl << " return engine->newQObject(in, QScriptEngine::QtOwnership, QScriptEngine::PreferExistingWrapperObject);" << endl << "}" << endl << endl; stream << "static void qtscript_" << meta_class->name() << "_fromScriptValue(const QScriptValue &value, " << meta_class->qualifiedCppName() << "* &out)" << endl << "{" << endl << " out = qobject_cast<" << meta_class->qualifiedCppName() << "*>(value.toQObject());" << endl << "}" << endl << endl; } // // write exported function that creates the QtScript class // stream << "QScriptValue qtscript_create_" << meta_class->name() << "_class(QScriptEngine *engine)" << endl; stream << "{" << endl; // setup prototype if (!meta_class->isNamespace()) { stream << " engine->setDefaultPrototype(qMetaTypeId<" << meta_class->qualifiedCppName() << "*>(), QScriptValue());" << endl; stream << " QScriptValue proto = engine->newVariant(qVariantFromValue((" << meta_class->qualifiedCppName() << "*)0));" << endl; bool havePrototypePrototype = false; if (meta_class->baseClass() != 0) { stream << " proto.setPrototype(engine->defaultPrototype(qMetaTypeId<" << meta_class->baseClass()->qualifiedCppName() << "*>()));" << endl; havePrototypePrototype = true; } foreach (AbstractMetaClass *iface, meta_class->interfaces()) { AbstractMetaClass *impl = iface->primaryInterfaceImplementor(); if (impl == meta_class) continue; if (!havePrototypePrototype) { stream << " proto.setPrototype(engine->defaultPrototype(qMetaTypeId<" << impl->qualifiedCppName() << "*>()));" << endl; havePrototypePrototype = true; } else { // alternative would be to copy the properties from the secondary // prototype to the primary prototype. stream << " proto.setProperty(QString::fromLatin1(\"__" << impl->name() << "__\")," << endl << " engine->defaultPrototype(qMetaTypeId<" << impl->qualifiedCppName() << "*>())," << endl << " QScriptValue::SkipInEnumeration);" << endl; } } if (!nameToPrototypeFunctions.isEmpty()) { QMap::const_iterator it; int count = nameToPrototypeFunctions.size(); if (!meta_class->hasDefaultToStringFunction()) ++count; stream << " for (int i = 0; i < " << count << "; ++i) {" << endl << " QScriptValue fun = engine->newFunction(qtscript_" << meta_class->name() << "_prototype_call, qtscript_" << meta_class->name() << "_function_lengths[i+" << prototypeFunctionsOffset << "]);" << endl << " fun.setData(QScriptValue(engine, uint(0xBABE0000 + i)));" << endl << " proto.setProperty(QString::fromLatin1(qtscript_" << meta_class->name() << "_function_names[i+" << prototypeFunctionsOffset << "])," << endl << " fun, QScriptValue::SkipInEnumeration);" << endl << " }" << endl; } writeInjectedCode(stream, meta_class, CodeSnip::PrototypeInitialization); stream << endl; // register the prototype // stream << " qDebug() << \"registering " << meta_class->name() << " prototype\";" << endl; if (meta_class->typeEntry()->isValue() && hasDefaultCtor) { stream << " engine->setDefaultPrototype(qMetaTypeId<" << meta_class->qualifiedCppName() << ">(), proto);" << endl; } if (isQObjectBased(meta_class)) { stream << " qScriptRegisterMetaType<" << meta_class->qualifiedCppName() << "*>(engine, qtscript_" << meta_class->name() << "_toScriptValue, " << endl << " qtscript_" << meta_class->name() << "_fromScriptValue, proto);" << endl; } else { stream << " engine->setDefaultPrototype(qMetaTypeId<" << meta_class->qualifiedCppName() << "*>(), proto);" << endl; } stream << endl; } else { stream << " QScriptValue proto = QScriptValue();" << endl; } // setup constructor stream << " QScriptValue ctor = engine->newFunction(qtscript_" << meta_class->name() << "_static_call, proto, qtscript_" << meta_class->name() << "_function_lengths[0]);" << endl; stream << " ctor.setData(QScriptValue(engine, uint(0xBABE0000 + 0)));" << endl; if (!nameToStaticFunctions.isEmpty()) { // static functions QMap::const_iterator it; stream << " for (int i = 0; i < " << nameToStaticFunctions.size() << "; ++i) {" << endl << " QScriptValue fun = engine->newFunction(qtscript_" << meta_class->name() << "_static_call," << endl << " qtscript_" << meta_class->name() << "_function_lengths[i+" << staticFunctionsOffset << "]);" << endl << " fun.setData(QScriptValue(engine, uint(0xBABE0000 + i+1)));" << endl << " ctor.setProperty(QString::fromLatin1(qtscript_" << meta_class->name() << "_function_names[i+" << staticFunctionsOffset << "])," << endl << " fun, QScriptValue::SkipInEnumeration);" << endl << " }" << endl; } stream << endl; // enums and flags classes { for (int i = 0; i < enums.size(); ++i) { const AbstractMetaEnum *enom = enums.at(i); stream << " ctor.setProperty(QString::fromLatin1(\"" << enom->name() << "\")," << endl << " qtscript_create_" << meta_class->name() << "_" << enom->name() << "_class(engine, ctor));" << endl; FlagsTypeEntry *flags = enom->typeEntry()->flags(); if (flags) { stream << " ctor.setProperty(QString::fromLatin1(\"" << flags->targetLangName() << "\")," << endl << " qtscript_create_" << meta_class->name() << "_" << flags->targetLangName() << "_class(engine));" << endl; } } } writeInjectedCode(stream, meta_class, CodeSnip::ConstructorInitialization); stream << " return ctor;" << endl; stream << "}" << endl; writeInjectedCode(stream, meta_class, CodeSnip::End); QString packName = meta_class->package().replace(".", "_"); priGenerator->addSource(packName, fileNameForClass(meta_class)); setupGenerator->addClass(meta_class); } qtscriptgenerator-src-0.2.0/generator/classgenerator.h000066400000000000000000000044171170724227300232440ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef CLASS_GENERATOR #define CLASS_GENERATOR #include "generator.h" #include "metaqtscript.h" #include "prigenerator.h" #include "setupgenerator.h" class ClassGenerator : public Generator { Q_OBJECT public: ClassGenerator(PriGenerator *pri, SetupGenerator *setup); virtual QString fileNameForClass(const AbstractMetaClass *meta_class) const; virtual QString subDirectoryForClass(const AbstractMetaClass *cls) const { return "generated_cpp/" + cls->package().replace(".", "_") + "/"; } virtual bool shouldGenerate(const AbstractMetaClass *meta_class) const; void write(QTextStream &s, const AbstractMetaClass *meta_class); private: PriGenerator *priGenerator; SetupGenerator *setupGenerator; QStringList describeFunctons; }; #endif // CLASS_GENERATOR qtscriptgenerator-src-0.2.0/generator/customtypes.cpp000066400000000000000000000050041170724227300231530ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "customtypes.h" #include "metajava.h" #include #include void QModelIndexTypeEntry::generateCppJavaToQt(QTextStream &s, const AbstractMetaType *, const QString &env_name, const QString &qt_name, const QString &java_name) const { s << "QModelIndex " << qt_name << " = qtjambi_to_QModelIndex(" << env_name << ", " << java_name << ")"; } void QModelIndexTypeEntry::generateCppQtToJava(QTextStream &s, const AbstractMetaType *, const QString &env_name, const QString &qt_name, const QString &java_name) const { s << "jobject " << java_name << " = qtjambi_from_QModelIndex(" << env_name << ", " << qt_name << ")"; } qtscriptgenerator-src-0.2.0/generator/customtypes.h000066400000000000000000000047451170724227300226330ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef CUSTOMTYPES_H #define CUSTOMTYPES_H #include "typesystem.h" class QModelIndexTypeEntry : public CustomTypeEntry { public: QModelIndexTypeEntry() : CustomTypeEntry("QModelIndex") { setCodeGeneration(GenerateNothing); } virtual QString javaPackage() const { return "com.trolltech.qt.core"; } virtual bool isValue() const { return true; } virtual void generateCppJavaToQt(QTextStream &s, const AbstractMetaType *java_type, const QString &env_name, const QString &qt_name, const QString &java_name) const; virtual void generateCppQtToJava(QTextStream &s, const AbstractMetaType *java_type, const QString &env_name, const QString &qt_name, const QString &java_name) const; }; #endif qtscriptgenerator-src-0.2.0/generator/docgenerator.cpp000066400000000000000000000340121170724227300232310ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "docgenerator.h" #include "fileout.h" DocGenerator::DocGenerator() { } QString DocGenerator::fileNameForClass(const AbstractMetaClass *meta_class) const { return QString::fromLatin1("%0.html").arg(meta_class->name().toLower()); } QString DocGenerator::subDirectoryForClass(const AbstractMetaClass *) const { return QString::fromLatin1("doc"); } static void writeDocumentHeader(QTextStream &s, const QString &title) { s << "" << endl << "" << endl << "" << endl << "" << endl << " " << title << "" << endl << " " << endl << "" << endl << "" << endl; } static void writeDocumentFooter(QTextStream &s) { s << "" << endl << "" << endl; } static bool classLessThan(const AbstractMetaClass *c1, const AbstractMetaClass *c2) { return c1->name() < c2->name(); } bool DocGenerator::shouldGenerate(const AbstractMetaClass *meta_class) const { uint cg = meta_class->typeEntry()->codeGeneration(); return (cg & TypeEntry::GenerateCode) != 0; } void DocGenerator::generate() { Generator::generate(); QHash > packHash; for (int i = 0; i < m_classes.size(); ++i) { const AbstractMetaClass *cls = m_classes.at(i); packHash[cls->package()].append(cls); } // package pages QHash >::const_iterator it; for (it = packHash.constBegin(); it != packHash.constEnd(); ++it) { QString package = it.key(); QList classesInPackage = it.value(); qSort(classesInPackage.begin(), classesInPackage.end(), classLessThan); FileOut file(m_out_dir + "/doc/" + package.split(".").join("_") + ".html"); writeDocumentHeader(file.stream, package + " Package"); file.stream << "

" << package << " Package

" << endl; file.stream << "

Classes

" << endl << "

" << endl; for (int i = 0; i < classesInPackage.size(); ++i) { const AbstractMetaClass *cls = classesInPackage.at(i); if (cls->name() == "Global") continue; /// ### fixme file.stream << "" << endl; } file.stream << "
" << cls->name() << "

" << endl; writeDocumentFooter(file.stream); } // all classes page { FileOut file(m_out_dir + "/doc/classes.html"); writeDocumentHeader(file.stream, "Classes"); file.stream << "

Classes

" << endl << "

" << endl; AbstractMetaClassList sortedClasses = m_classes; qSort(sortedClasses.begin(), sortedClasses.end(), classLessThan); for (int i = 0; i < sortedClasses.size(); ++i) { const AbstractMetaClass *cls = sortedClasses.at(i); if (cls->name() == "Global") continue; /// ### fixme file.stream << "" << endl; } file.stream << "
" << cls->name() << "

" << endl; writeDocumentFooter(file.stream); } // index.html { FileOut file(m_out_dir + "/doc/index.html"); writeDocumentHeader(file.stream, "Qt Bindings Reference Documentation"); file.stream << "

Qt Script Qt Bindings Reference Documentation

" << endl; file.stream << "

Packages

" << endl; file.stream << "
    " << endl; QStringList sortedPackages = packHash.keys(); qSort(sortedPackages.begin(), sortedPackages.end()); for (int i = 0; i < sortedPackages.size(); ++i) { QString pkg = sortedPackages.at(i); file.stream << "
  • " << pkg << "
  • " << endl; } file.stream << "
" << endl; file.stream << "

All Classes

" << endl; file.stream << "

Examples

" << endl; file.stream << "

Getting Started

" << endl << "

Using the Qt API in Qt Script is very similar to C++." << endl << "

var f = new QFile(\"foo.txt\");
" << endl << "C++ enum values are mapped to properties of the script constructor function; e.g. " << endl << "QIODevice::ReadOnly becomes QIODevice.ReadOnly.

" << endl << "
f.open(new QIODevice.OpenMode(QIODevice.ReadOnly));
" << endl << "

Each C++ flag type is mapped to a property of the script constructor function; e.g. " << endl << "QIODevice::OpenMode becomes QIODevice.OpenMode. Such a property is a constructor function " << endl << "that takes one or more enum values and constructs a flags instance by OR'ing the arguments " << endl << "together.

" << endl << "
var ts = new QTextStream(f);" << endl
                    << "ts.writeString(\"Boo\");
" << endl << "

C++ streaming operators are normally mapped to readT() and writeT() functions.

" << endl << "
f.close();
" << endl << "

In Qt Script, all objects are allocated on the heap; objects that are no longer " << endl << "referenced are garbage collected sometime in the future; therefore, make sure to " << endl << "explicitly free up resources if you can. (Without the call to close(), the underlying " << endl << "file would remain open until the file object is garbage collected.)

" << endl ; file.stream << "

Qt Reference Documentation

" << endl; writeDocumentFooter(file.stream); } } static bool shouldIgnoreEnum(const AbstractMetaEnum *enom) { return !enom->wasPublic() || (enom->name() == "enum_1"); } // in classgenerator.cpp void findPrototypeAndStaticFunctions( const AbstractMetaClass *meta_class, QMap &nameToPrototypeFunctions, QMap &nameToStaticFunctions); QList uniqueEnumValueIndexes(const AbstractMetaEnumValueList &values); static void writeFunction(QTextStream &s, const AbstractMetaFunction *fun) { s << "
  • " << fun->targetLangSignature() << "
  • " << endl; } void DocGenerator::write(QTextStream &s, const AbstractMetaClass *meta_class) { QString title = meta_class->name(); title.append(" "); if (meta_class->isNamespace()) title.append("Namespace"); else title.append("Class"); title.append(" Reference"); writeDocumentHeader(s, title); s << "

    " << title << "

    " << endl; s << "

    [package().split(".").join("_") << ".html"; s << "\">"; s << meta_class->package(); s << " package]

    " << endl; if (meta_class->baseClass()) { s << "

    Inherits baseClass()) << "\">" << meta_class->baseClass()->name() << ".

    " << endl; } else if (!meta_class->interfaces().isEmpty()) { AbstractMetaClass *iface = meta_class->interfaces().first(); AbstractMetaClass *impl = iface->primaryInterfaceImplementor(); if (impl != meta_class) { s << "

    Inherits " << impl->name() << ".

    " << endl; } } AbstractMetaFunctionList ctors; ctors = meta_class->queryFunctions(AbstractMetaClass::Constructors | AbstractMetaClass::WasPublic | AbstractMetaClass::NotRemovedFromTargetLang); QMap nameToPrototypeFunctions; QMap nameToStaticFunctions; findPrototypeAndStaticFunctions(meta_class, nameToPrototypeFunctions, nameToStaticFunctions); s << "

    Constructor

    " << endl; if (!ctors.isEmpty()) { s << "
      " << endl; for (int i = 0; i < ctors.size(); ++i) { writeFunction(s, ctors.at(i)); } s << "
    " << endl; } else { s << "

    This class has no public constructors. Calling the constructor function will cause a TypeError.

    "; } s << "

    Constructor Properties

    " << endl; s << "
      " << endl; s << "
    • prototype: The " << meta_class->name() << " prototype object
    • " << endl; if (!nameToStaticFunctions.isEmpty()) { QMap::const_iterator it; for (it = nameToStaticFunctions.constBegin(); it != nameToStaticFunctions.constEnd(); ++it) { writeFunction(s, it.value().first()); } } { AbstractMetaEnumList enums = meta_class->enums(); for (int i = 0; i < enums.size(); ++i) { const AbstractMetaEnum *enom = enums.at(i); if (shouldIgnoreEnum(enom)) continue; AbstractMetaEnumValueList values = enom->values(); QList indexes = uniqueEnumValueIndexes(values); for (int j = 0; j < indexes.size(); ++j) { AbstractMetaEnumValue *val = values.at(indexes.at(j)); s << "
    • " << val->name(); if (!val->stringValue().isEmpty()) s << " = " << val->stringValue(); s << "
    • " << endl; } s << "
    • " << enom->name() << "( value )
    • " << endl; FlagsTypeEntry *flags = enom->typeEntry()->flags(); if (flags) s << "
    • " << flags->flagsName() << "( value1, value2, ... )
    • " << endl; } } s << "
    " << endl; if (!nameToPrototypeFunctions.isEmpty()) { s << "

    Prototype Object Properties

    " << endl; if (meta_class->baseClass()) { s << "

    The " << meta_class->name() << " prototype object inherits properties from the " << "baseClass()) << "\">" << meta_class->baseClass()->name() << " prototype object and " << "also has the following properties.

    " << endl; } s << "
      " << endl; QMap::const_iterator it; for (it = nameToPrototypeFunctions.constBegin(); it != nameToPrototypeFunctions.constEnd(); ++it) { writeFunction(s, it.value().first()); } s << "
    " << endl; } if (!meta_class->isNamespace()) { s << "

    Instance Properties

    " << endl; { QList props = meta_class->propertySpecs(); if (!props.isEmpty()) { s << "

    " << meta_class->name() << " objects inherit properties from the " << meta_class->name() << " prototype object and also have the following properties.

    " << endl; s << "
      " << endl; for (int i = 0; i < props.size(); ++i) { s << "
    • " << props.at(i)->name() << "
    • " << endl; } s << "
    " << endl; } else { s << "

    " << meta_class->name() << " objects have no special properties beyond those " << "inherited from the " << meta_class->name() << " prototype object.

    " << endl; } } } writeDocumentFooter(s); } qtscriptgenerator-src-0.2.0/generator/docgenerator.h000066400000000000000000000037161170724227300227050ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef DOCGENERATOR_H #define DOCGENERATOR_H #include "generator.h" class DocGenerator : public Generator { public: DocGenerator(); virtual bool shouldGenerate(const AbstractMetaClass *meta_class) const; virtual void generate(); virtual QString fileNameForClass(const AbstractMetaClass *meta_class) const; virtual QString subDirectoryForClass(const AbstractMetaClass *cls) const; virtual void write(QTextStream &s, const AbstractMetaClass *meta_class); }; #endif qtscriptgenerator-src-0.2.0/generator/fileout.cpp000066400000000000000000000160371170724227300222330ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "fileout.h" #include "reporthandler.h" #include #include bool FileOut::dummy = false; bool FileOut::diff = false; bool FileOut::license = false; #ifdef Q_OS_LINUX const char* colorDelete = "\033[31m"; const char* colorAdd = "\033[32m"; const char* colorInfo = "\033[36m"; const char* colorReset = "\033[0m"; #else const char* colorDelete = ""; const char* colorAdd = ""; const char* colorInfo = ""; const char* colorReset = ""; #endif FileOut::FileOut(QString n): name(n), stream(&tmp), isDone(false) {} static int* lcsLength(QList a, QList b) { const int height = a.size() + 1; const int width = b.size() + 1; int *res = new int[width * height]; for (int row=0; row a, QList b){ { if (type == Unchanged) { if ((end - start) > 9) { for (int i = start; i <= start+2; i++) printf(" %s\n", a[i].data()); printf("%s=\n= %d more lines\n=%s\n", colorInfo, end - start - 6, colorReset); for (int i = end-2; i <= end; i++) printf(" %s\n", a[i].data()); } else for (int i = start; i <= end; i++) printf(" %s\n", a[i].data()); } else if(type == Add) { printf("%s", colorAdd); for (int i = start; i <= end; i++){ printf("+ %s\n", b[i].data()); } printf("%s", colorReset); } else if (type == Delete) { printf("%s", colorDelete); for (int i = start; i <= end; i++) { printf("- %s\n", a[i].data()); } printf("%s", colorReset); } } } }; static QList *unitAppend(QList *res, Type type, int pos) { if (res == 0) { res = new QList; res->append(new Unit(type, pos)); return res; } Unit *last = res->last(); if (last->type == type) { last->end = pos; } else { res->append(new Unit(type, pos)); } return res; } static QList *diffHelper(int *lcs, QList a, QList b, int row, int col) { if (row>0 && col>0 && (a[row-1] == b[col-1])) { return unitAppend(diffHelper(lcs, a, b, row-1, col-1), Unchanged, row-1); } else { int width = b.size()+1; if ((col > 0) && ((row==0) || lcs[width * row + col-1] >= lcs[width * (row-1) + col])) { return unitAppend(diffHelper(lcs, a, b, row, col-1), Add, col-1); } else if((row > 0) && ((col==0) || lcs[width * row + col-1] < lcs[width * (row-1) + col])){ return unitAppend(diffHelper(lcs, a, b, row-1, col), Delete, row-1);; } } delete lcs; return 0; } static void diff(QList a, QList b) { QList *res = diffHelper(lcsLength(a, b), a, b, a.size(), b.size()); for (int i=0; i < res->size(); i++) { Unit *unit = res->at(i); unit->print(a, b); delete(unit); } delete(res); } bool FileOut::done() { Q_ASSERT( !isDone ); isDone = true; bool fileEqual = false; QFile fileRead(name); QFileInfo info(fileRead); stream.flush(); QByteArray original; if (info.exists() && (diff || (info.size() == tmp.size()))) { if ( !fileRead.open(QIODevice::ReadOnly) ) { ReportHandler::warning(QString("failed to open file '%1' for reading") .arg(fileRead.fileName())); return false; } original = fileRead.readAll(); fileRead.close(); fileEqual = (original == tmp); } if( !fileEqual ) { if( !FileOut::dummy ) { QDir dir(info.absolutePath()); if (!dir.mkpath(dir.absolutePath())) { ReportHandler::warning(QString("unable to create directory '%1'") .arg(dir.absolutePath())); return false; } QFile fileWrite(name); if (!fileWrite.open(QIODevice::WriteOnly)) { ReportHandler::warning(QString("failed to open file '%1' for writing") .arg(fileWrite.fileName())); return false; } stream.setDevice(&fileWrite); stream << tmp; } if (diff) { printf("%sFile: %s%s\n", colorInfo, qPrintable(name), colorReset); ::diff(original.split('\n'), tmp.split('\n')); printf("\n"); } return true; } return false; } qtscriptgenerator-src-0.2.0/generator/fileout.h000066400000000000000000000037051170724227300216760ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef FILEOUT_H #define FILEOUT_H #include #include #include class FileOut : public QObject { Q_OBJECT private: QByteArray tmp; QString name; public: FileOut(QString name); ~FileOut() { if( !isDone ) done(); } bool done(); QTextStream stream; static bool dummy; static bool diff; static bool license; private: bool isDone; }; #endif // FILEOUT_H qtscriptgenerator-src-0.2.0/generator/generate.sh000077500000000000000000000024761170724227300222130ustar00rootroot00000000000000xsltproc --stringparam source $PWD/typesystem_core-qtscript.xml merge.xsl typesystem_core-common.xml > typesystem_core.xml xsltproc --stringparam source $PWD/typesystem_gui-qtscript.xml merge.xsl typesystem_gui-common.xml > typesystem_gui.xml xsltproc --stringparam source $PWD/typesystem_svg-qtscript.xml merge.xsl typesystem_svg-common.xml > typesystem_svg.xml xsltproc --stringparam source $PWD/typesystem_network-qtscript.xml merge.xsl typesystem_network-common.xml > typesystem_network.xml xsltproc --stringparam source $PWD/typesystem_opengl-qtscript.xml merge.xsl typesystem_opengl-common.xml > typesystem_opengl.xml xsltproc --stringparam source $PWD/typesystem_xml-qtscript.xml merge.xsl typesystem_xml-common.xml > typesystem_xml.xml xsltproc --stringparam source $PWD/typesystem_sql-qtscript.xml merge.xsl typesystem_sql-common.xml > typesystem_sql.xml xsltproc --stringparam source $PWD/typesystem_phonon-qtscript.xml merge.xsl typesystem_phonon-common.xml > typesystem_phonon.xml xsltproc --stringparam source $PWD/typesystem_webkit-qtscript.xml merge.xsl typesystem_webkit-common.xml > typesystem_webkit.xml xsltproc --stringparam source $PWD/typesystem_xmlpatterns-qtscript.xml merge.xsl typesystem_xmlpatterns-common.xml > typesystem_xmlpatterns.xml # ./generator qtscript_masterinclude.h typesystem_core.xml --diff qtscriptgenerator-src-0.2.0/generator/generator.cpp000066400000000000000000000077311170724227300225530ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "generator.h" #include "reporthandler.h" #include "fileout.h" #include #include #include Generator::Generator() { m_num_generated = 0; m_num_generated_written = 0; m_out_dir = "."; } void Generator::generate() { if (m_classes.size() == 0) { ReportHandler::warning(QString("%1: no java classes, skipping") .arg(metaObject()->className())); return; } foreach (AbstractMetaClass *cls, m_classes) { if (!shouldGenerate(cls)) continue; QString fileName = fileNameForClass(cls); ReportHandler::debugSparse(QString("generating: %1").arg(fileName)); FileOut fileOut(outputDirectory() + "/" + subDirectoryForClass(cls) + "/" + fileName); write(fileOut.stream, cls); if( fileOut.done() ) ++m_num_generated_written; ++m_num_generated; } } void Generator::printClasses() { QTextStream s(stdout); AbstractMetaClassList classes = m_classes; qSort(classes); foreach (AbstractMetaClass *cls, classes) { if (!shouldGenerate(cls)) continue; write(s, cls); s << endl << endl; } } void Generator::verifyDirectoryFor(const QFile &file) { QDir dir = QFileInfo(file).dir(); if (!dir.exists()) { if (!dir.mkpath(dir.absolutePath())) ReportHandler::warning(QString("unable to create directory '%1'") .arg(dir.absolutePath())); } } QString Generator::subDirectoryForClass(const AbstractMetaClass *) const { Q_ASSERT(false); return QString(); } QString Generator::fileNameForClass(const AbstractMetaClass *) const { Q_ASSERT(false); return QString(); } void Generator::write(QTextStream &, const AbstractMetaClass *) { Q_ASSERT(false); } bool Generator::hasDefaultConstructor(const AbstractMetaType *type) { QString full_name = type->typeEntry()->qualifiedTargetLangName(); QString class_name = type->typeEntry()->targetLangName(); foreach (const AbstractMetaClass *java_class, m_classes) { if (java_class->typeEntry()->qualifiedTargetLangName() == full_name) { AbstractMetaFunctionList functions = java_class->functions(); foreach (const AbstractMetaFunction *function, functions) { if (function->arguments().size() == 0 && function->name() == class_name) return true; } return false; } } return false; } qtscriptgenerator-src-0.2.0/generator/generator.h000066400000000000000000000114441170724227300222140ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef GENERATOR_H #define GENERATOR_H #include "metajava.h" #include "typesystem.h" #include "codemodel.h" #include #include class Generator : public QObject { Q_OBJECT Q_PROPERTY(QString outputDirectory READ outputDirectory WRITE setOutputDirectory); public: enum Option { NoOption = 0x00000000, BoxedPrimitive = 0x00000001, ExcludeConst = 0x00000002, ExcludeReference = 0x00000004, UseNativeIds = 0x00000008, EnumAsInts = 0x00000010, SkipName = 0x00000020, NoCasts = 0x00000040, SkipReturnType = 0x00000080, OriginalName = 0x00000100, ShowStatic = 0x00000200, UnderscoreSpaces = 0x00000400, ForceEnumCast = 0x00000800, ArrayAsPointer = 0x00001000, VirtualCall = 0x00002000, SkipTemplateParameters = 0x00004000, SkipAttributes = 0x00008000, OriginalTypeDescription = 0x00010000, SkipRemovedArguments = 0x00020000, IncludeDefaultExpression = 0x00040000, NoReturnStatement = 0x00080000, NoBlockedSlot = 0x00100000, SuperCall = 0x00200000, GlobalRefJObject = 0x00100000, ForceValueType = ExcludeReference | ExcludeConst }; Generator(); void setClasses(const AbstractMetaClassList &classes) { m_classes = classes; } AbstractMetaClassList classes() const { return m_classes; } QString outputDirectory() const { return m_out_dir; } void setOutputDirectory(const QString &outDir) { m_out_dir = outDir; } virtual void generate(); void printClasses(); int numGenerated() { return m_num_generated; } int numGeneratedAndWritten() { return m_num_generated_written; } virtual bool shouldGenerate(const AbstractMetaClass *) const { return true; } virtual QString subDirectoryForClass(const AbstractMetaClass *java_class) const; virtual QString fileNameForClass(const AbstractMetaClass *java_class) const; virtual void write(QTextStream &s, const AbstractMetaClass *java_class); bool hasDefaultConstructor(const AbstractMetaType *type); // QtScript void setQtMetaTypeDeclaredTypeNames(const QSet &names) { m_qmetatype_declared_typenames = names; } QSet qtMetaTypeDeclaredTypeNames() const { return m_qmetatype_declared_typenames; } protected: void verifyDirectoryFor(const QFile &file); AbstractMetaClassList m_classes; int m_num_generated; int m_num_generated_written; QString m_out_dir; // QtScript QSet m_qmetatype_declared_typenames; }; class Indentor { public: Indentor(): indent(0) {} int indent; }; class Indentation { public: Indentation(Indentor &indentor): indentor(indentor) { indentor.indent++; } ~Indentation() { indentor.indent--; } private: Indentor &indentor; }; inline QTextStream &operator <<(QTextStream &s, const Indentor &indentor) { for (int i=0; i qtscript_masterinclude.h build_all.txt typesystem_core.xml typesystem_gui.xml typesystem_sql.xml typesystem_opengl.xml typesystem_svg.xml typesystem_network.xml typesystem_xml.xml typesystem_phonon.xml typesystem_webkit.xml typesystem_xmlpatterns.xml parser/rpp/pp-qt-configuration qtscriptgenerator-src-0.2.0/generator/generatorset.cpp000066400000000000000000000035721170724227300232660ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "generatorset.h" GeneratorSet::GeneratorSet() : outDir(".."), printStdout(false) {} bool GeneratorSet::readParameters(const QMap args) { if (args.contains("output-directory")) { outDir = args.value("output-directory"); } printStdout = args.contains("print-stdout"); return !(args.contains("help") || args.contains("h") || args.contains("?")); } qtscriptgenerator-src-0.2.0/generator/generatorset.h000066400000000000000000000040201170724227300227200ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef GENERATOR_SET_H #define GENERATOR_SET_H #include #include #include #include class GeneratorSet : public QObject { Q_OBJECT public: GeneratorSet(); virtual QString usage() = 0; virtual bool readParameters(const QMap args) = 0; virtual void buildModel(const QString pp_file) = 0; virtual void dumpObjectTree() = 0; virtual QString generate() = 0; static GeneratorSet *getInstance(); QString outDir; bool printStdout; }; #endif // GENERATOR_SET_H qtscriptgenerator-src-0.2.0/generator/generatorsetqtscript.cpp000066400000000000000000000110121170724227300250440ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "generatorsetqtscript.h" #include "reporthandler.h" #include "classgenerator.h" #include "shellheadergenerator.h" #include "shellimplgenerator.h" #include "docgenerator.h" GeneratorSet *GeneratorSet::getInstance() { return new GeneratorSetQtScript(); } GeneratorSetQtScript::GeneratorSetQtScript() {} QString GeneratorSetQtScript::usage() { QString usage = "QtScript:\n" " --nothing-to-report-yet \n"; return usage; } bool GeneratorSetQtScript::readParameters(const QMap args) { return GeneratorSet::readParameters(args); } void GeneratorSetQtScript::buildModel(const QString pp_file) { // Building the code inforamation... ReportHandler::setContext("MetaJavaBuilder"); builder.setFileName(pp_file); builder.build(); } void GeneratorSetQtScript::dumpObjectTree() { } QString GeneratorSetQtScript::generate() { AbstractMetaClassList classes = builder.classesTopologicalSorted(); QSet declaredTypeNames = builder.qtMetaTypeDeclaredTypeNames(); PriGenerator priGenerator; priGenerator.setOutputDirectory(outDir); SetupGenerator setupGenerator; setupGenerator.setOutputDirectory(outDir); setupGenerator.setQtMetaTypeDeclaredTypeNames(declaredTypeNames); ClassGenerator classGenerator(&priGenerator, &setupGenerator); classGenerator.setOutputDirectory(outDir); classGenerator.setClasses(classes); classGenerator.setQtMetaTypeDeclaredTypeNames(declaredTypeNames); classGenerator.generate(); ShellImplGenerator shellImplGenerator(&priGenerator); shellImplGenerator.setOutputDirectory(outDir); shellImplGenerator.setClasses(classes); shellImplGenerator.setQtMetaTypeDeclaredTypeNames(declaredTypeNames); shellImplGenerator.generate(); ShellHeaderGenerator shellHeaderGenerator(&priGenerator); shellHeaderGenerator.setOutputDirectory(outDir); shellHeaderGenerator.setClasses(classes); shellHeaderGenerator.generate(); DocGenerator docGenerator; docGenerator.setOutputDirectory(outDir); docGenerator.setClasses(classes); docGenerator.generate(); priGenerator.generate(); setupGenerator.generate(); return QString("Classes in typesystem: %1\n" "Generated:\n" " - classes...: %2 (%3)\n" " - header....: %4 (%5)\n" " - impl......: %6 (%7)\n" " - modules...: %8 (%9)\n" " - pri.......: %10 (%11)\n" ) .arg(builder.classes().size()) .arg(classGenerator.numGenerated()) .arg(classGenerator.numGeneratedAndWritten()) .arg(shellHeaderGenerator.numGenerated()) .arg(shellHeaderGenerator.numGeneratedAndWritten()) .arg(shellImplGenerator.numGenerated()) .arg(shellImplGenerator.numGeneratedAndWritten()) .arg(setupGenerator.numGenerated()) .arg(setupGenerator.numGeneratedAndWritten()) .arg(priGenerator.numGenerated()) .arg(priGenerator.numGeneratedAndWritten()); } qtscriptgenerator-src-0.2.0/generator/generatorsetqtscript.h000066400000000000000000000037701170724227300245250ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef GENERATOR_SET_QT_SCRIPT_H #define GENERATOR_SET_QT_SCRIPT_H #include "generatorset.h" #include "metaqtscriptbuilder.h" class GeneratorSetQtScript : public GeneratorSet { Q_OBJECT public: GeneratorSetQtScript(); QString usage(); bool readParameters(const QMap args); void buildModel(const QString pp_file); void dumpObjectTree(); QString generate( ); private: MetaQtScriptBuilder builder; }; #endif // GENERATOR_SET_QT_SCRIPT_H qtscriptgenerator-src-0.2.0/generator/main.cpp000066400000000000000000000131401170724227300215000ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "main.h" #include "asttoxml.h" #include "reporthandler.h" #include "typesystem.h" #include "generatorset.h" #include "fileout.h" #include void displayHelp(GeneratorSet *generatorSet); #include int main(int argc, char *argv[]) { GeneratorSet *gs = GeneratorSet::getInstance(); QString default_file = ":/trolltech/generator/qtscript_masterinclude.h"; QString default_system = ":/trolltech/generator/build_all.txt"; QString fileName; QString typesystemFileName; QString pp_file = ".preprocessed.tmp"; QStringList rebuild_classes; QMap args; int argNum = 0; for (int i=1; i 0 ) args[arg.mid(2).left(split-2)] = arg.mid(split + 1).trimmed(); else args[arg.mid(2)] = QString(); } else if( arg.startsWith("-")) { args[arg.mid(1)] = QString(); } else { argNum++; args[QString("arg-%1").arg(argNum)] = arg; } } if (args.contains("no-suppress-warnings")) { TypeDatabase *db = TypeDatabase::instance(); db->setSuppressWarnings(false); } if (args.contains("debug-level")) { QString level = args.value("debug-level"); if (level == "sparse") ReportHandler::setDebugLevel(ReportHandler::SparseDebug); else if (level == "medium") ReportHandler::setDebugLevel(ReportHandler::MediumDebug); else if (level == "full") ReportHandler::setDebugLevel(ReportHandler::FullDebug); } if (args.contains("dummy")) { FileOut::dummy = true; } if (args.contains("diff")) { FileOut::diff = true; } if (args.contains("license")) FileOut::license = true; if (args.contains("rebuild-only")) { QStringList classes = args.value("rebuild-only").split(",", QString::SkipEmptyParts); TypeDatabase::instance()->setRebuildClasses(classes); } fileName = args.value("arg-1"); typesystemFileName = args.value("arg-2"); if (args.contains("arg-3")) displayHelp(gs); if (fileName.isEmpty()) fileName = default_file; if (typesystemFileName.isEmpty()) typesystemFileName = default_system; if (fileName.isEmpty() || typesystemFileName.isEmpty() ) displayHelp(gs); if (!gs->readParameters(args)) displayHelp(gs); printf("Please wait while source files are being generated...\n"); if (!TypeDatabase::instance()->parseFile(typesystemFileName)) qFatal("Cannot parse file: '%s'", qPrintable(typesystemFileName)); if (!Preprocess::preprocess(fileName, pp_file, args.value("include-paths"))) { fprintf(stderr, "Preprocessor failed on file: '%s'\n", qPrintable(fileName)); return 1; } if (args.contains("ast-to-xml")) { astToXML(pp_file); return 0; } gs->buildModel(pp_file); if (args.contains("dump-object-tree")) { gs->dumpObjectTree(); return 0; } printf("%s\n", qPrintable(gs->generate())); printf("Done, %d warnings (%d known issues)\n", ReportHandler::warningCount(), ReportHandler::suppressedCount()); } void displayHelp(GeneratorSet* generatorSet) { #if defined(Q_OS_WIN32) char path_splitter = ';'; #else char path_splitter = ':'; #endif printf("Usage:\n generator [options] header-file typesystem-file\n\n"); printf("Available options:\n\n"); printf("General:\n"); printf(" --debug-level=[sparse|medium|full] \n" " --dump-object-tree \n" " --help, -h or -? \n" " --no-suppress-warnings \n" " --output-directory=[dir] \n" " --include-paths=[%c%c...] \n" " --print-stdout \n", path_splitter, path_splitter); printf("%s", qPrintable( generatorSet->usage())); exit(0); } qtscriptgenerator-src-0.2.0/generator/main.h000066400000000000000000000115241170724227300211510ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef MAIN_H #define MAIN_H #include "pp.h" #include #include struct Preprocess { static bool preprocess(const QString &sourceFile, const QString &targetFile, const QString &commandLineIncludes = QString()) { rpp::pp_environment env; rpp::pp preprocess(env); rpp::pp_null_output_iterator null_out; const char *ppconfig = ":/trolltech/generator/parser/rpp/pp-qt-configuration"; QFile file(ppconfig); if (!file.open(QFile::ReadOnly)) { fprintf(stderr, "Preprocessor configuration file not found '%s'\n", ppconfig); return false; } QByteArray ba = file.readAll(); file.close(); preprocess.operator() (ba.constData(), ba.constData() + ba.size(), null_out); QStringList includes; includes << QString("."); #if defined(Q_OS_WIN32) char *path_splitter = ";"; #else const char *path_splitter = ":"; #endif // Environment INCLUDE QString includePath = getenv("INCLUDE"); if (!includePath.isEmpty()) includes += includePath.split(path_splitter); // Includes from the command line if (!commandLineIncludes.isEmpty()) includes += commandLineIncludes.split(path_splitter); // Include Qt QString qtdir = getenv ("QTDIR"); if (qtdir.isEmpty()) { #if defined(Q_OS_MAC) qWarning("QTDIR environment variable not set. Assuming standard binary install using frameworks."); QString frameworkDir = "/Library/Frameworks"; includes << (frameworkDir + "/QtXml.framework/Headers"); includes << (frameworkDir + "/QtNetwork.framework/Headers"); includes << (frameworkDir + "/QtCore.framework/Headers"); includes << (frameworkDir + "/QtGui.framework/Headers"); includes << (frameworkDir + "/QtOpenGL.framework/Headers"); includes << frameworkDir; #else qWarning("QTDIR environment variable not set. This may cause problems with finding the necessary include files."); #endif } else { qtdir += "/include"; includes << (qtdir + "/QtXml"); includes << (qtdir + "/QtNetwork"); includes << (qtdir + "/QtCore"); includes << (qtdir + "/QtGui"); includes << (qtdir + "/QtOpenGL"); includes << qtdir; } foreach (QString include, includes) preprocess.push_include_path(QDir::convertSeparators(include).toStdString()); QString currentDir = QDir::current().absolutePath(); QFileInfo sourceInfo(sourceFile); QDir::setCurrent(sourceInfo.absolutePath()); std::string result; result.reserve (20 * 1024); // 20K result += "# 1 \"builtins\"\n"; result += "# 1 \""; result += sourceFile.toStdString(); result += "\"\n"; preprocess.file (sourceInfo.fileName().toStdString(), rpp::pp_output_iterator (result)); QDir::setCurrent(currentDir); QFile f(targetFile); if (!f.open(QIODevice::WriteOnly | QIODevice::Text)) { fprintf(stderr, "Failed to write preprocessed file: %s\n", qPrintable(targetFile)); } f.write(result.c_str(), result.length()); return true; } }; #endif // MAIN_H qtscriptgenerator-src-0.2.0/generator/merge.xsl000066400000000000000000000047711170724227300217110ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/metajava.cpp000066400000000000000000000027701170724227300223530ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "metajava.h" qtscriptgenerator-src-0.2.0/generator/metajava.h000066400000000000000000000041571170724227300220210ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef METAJAVA_H #define METAJAVA_H #include "abstractmetalang.h" class MetaJavaClass; class MetaJavaField; class MetaJavaFunction; class MetaJavaType; class MetaJavaVariable; class MetaJavaArgument; class MetaJavaEnumValue; class MetaJavaEnum; class MetaJavaType : public AbstractMetaType {}; class MetaJavaArgument : public AbstractMetaArgument {}; class MetaJavaField : public AbstractMetaField {}; class MetaJavaFunction : public AbstractMetaFunction {}; class MetaJavaEnumValue : public AbstractMetaEnumValue {}; class MetaJavaEnum : public AbstractMetaEnum {}; class MetaJavaClass : public AbstractMetaClass {}; #endif // METAJAVA_H qtscriptgenerator-src-0.2.0/generator/metaqtscript.cpp000066400000000000000000000031651170724227300233020ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "metaqtscript.h" bool MetaQtScriptClass::hasDefaultToStringFunction() const { return 0 < queryFunctionsByName("toString").size(); } qtscriptgenerator-src-0.2.0/generator/metaqtscript.h000066400000000000000000000043551170724227300227510ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef METAQTSCRIPT_H #define METAQTSCRIPT_H #include "abstractmetalang.h" class MetaQtScriptClass; class MetaQtScriptField; class MetaQtScriptFunction; class MetaQtScriptType; class MetaQtScriptVariable; class MetaQtScriptArgument; class MetaQtScriptEnumValue; class MetaQtScriptEnum; class MetaQtScriptType : public AbstractMetaType {}; class MetaQtScriptArgument : public AbstractMetaArgument {}; class MetaQtScriptField : public AbstractMetaField {}; class MetaQtScriptFunction : public AbstractMetaFunction {}; class MetaQtScriptEnumValue : public AbstractMetaEnumValue {}; class MetaQtScriptEnum : public AbstractMetaEnum {}; class MetaQtScriptClass : public AbstractMetaClass { virtual bool hasDefaultToStringFunction() const; }; #endif // METAQTSCRIPT_H qtscriptgenerator-src-0.2.0/generator/metaqtscriptbuilder.cpp000066400000000000000000000030041170724227300246410ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "metaqtscriptbuilder.h" qtscriptgenerator-src-0.2.0/generator/metaqtscriptbuilder.h000066400000000000000000000050411170724227300243110ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef METAQTSCRIPTBUILDER_H #define METAQTSCRIPTBUILDER_H #include "abstractmetabuilder.h" #include "metaqtscript.h" class MetaQtScriptBuilder : public AbstractMetaBuilder { protected: virtual MetaQtScriptClass *createMetaClass() { return new MetaQtScriptClass(); }; virtual MetaQtScriptEnum *createMetaEnum() { return new MetaQtScriptEnum(); }; virtual MetaQtScriptEnumValue *createMetaEnumValue() { return new MetaQtScriptEnumValue(); }; virtual MetaQtScriptField *createMetaField() { return new MetaQtScriptField(); }; virtual MetaQtScriptFunction *createMetaFunction() { return new MetaQtScriptFunction(); }; virtual MetaQtScriptArgument *createMetaArgument() { return new MetaQtScriptArgument(); }; virtual MetaQtScriptType *createMetaType() { return new MetaQtScriptType(); }; }; #endif // METAQTSCRIPTBUILDER_H qtscriptgenerator-src-0.2.0/generator/parser/000077500000000000000000000000001170724227300213455ustar00rootroot00000000000000qtscriptgenerator-src-0.2.0/generator/parser/ast.cpp000066400000000000000000000035011170724227300226370ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "ast.h" #include "lexer.h" // kate: space-indent on; indent-width 2; replace-tabs on; QString AST::toString(TokenStream *stream) const { const Token &tk = stream->token((int) start_token); const Token &end_tk = stream->token ((int) end_token); return QString::fromLatin1(tk.text + tk.position, end_tk.position - tk.position); } qtscriptgenerator-src-0.2.0/generator/parser/ast.h000066400000000000000000000452351170724227300223160ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef AST_H #define AST_H #include "smallobject.h" #include "list.h" class QString; #define DECLARE_AST_NODE(k) \ enum { __node_kind = Kind_##k }; class TokenStream; struct AccessSpecifierAST; struct AsmDefinitionAST; struct BaseClauseAST; struct BaseSpecifierAST; struct BinaryExpressionAST; struct CastExpressionAST; struct ClassMemberAccessAST; struct ClassSpecifierAST; struct CompoundStatementAST; struct ConditionAST; struct ConditionalExpressionAST; struct CppCastExpressionAST; struct CtorInitializerAST; struct DeclarationAST; struct DeclarationStatementAST; struct DeclaratorAST; struct DeleteExpressionAST; struct DoStatementAST; struct ElaboratedTypeSpecifierAST; struct EnumSpecifierAST; struct EnumeratorAST; struct ExceptionSpecificationAST; struct ExpressionAST; struct ExpressionOrDeclarationStatementAST; struct ExpressionStatementAST; struct ForStatementAST; struct FunctionCallAST; struct FunctionDefinitionAST; struct IfStatementAST; struct IncrDecrExpressionAST; struct InitDeclaratorAST; struct InitializerAST; struct InitializerClauseAST; struct LabeledStatementAST; struct LinkageBodyAST; struct LinkageSpecificationAST; struct MemInitializerAST; struct NameAST; struct NamespaceAST; struct NamespaceAliasDefinitionAST; struct NewDeclaratorAST; struct NewExpressionAST; struct NewInitializerAST; struct NewTypeIdAST; struct OperatorAST; struct OperatorFunctionIdAST; struct ParameterDeclarationAST; struct ParameterDeclarationClauseAST; struct PostfixExpressionAST; struct PrimaryExpressionAST; struct PtrOperatorAST; struct PtrToMemberAST; struct ReturnStatementAST; struct SimpleDeclarationAST; struct SimpleTypeSpecifierAST; struct SizeofExpressionAST; struct StatementAST; struct StringLiteralAST; struct SubscriptExpressionAST; struct SwitchStatementAST; struct TemplateArgumentAST; struct TemplateDeclarationAST; struct TemplateParameterAST; struct ThrowExpressionAST; struct TranslationUnitAST; struct TryBlockStatementAST; struct TypeIdAST; struct TypeIdentificationAST; struct TypeParameterAST; struct TypeSpecifierAST; struct TypedefAST; struct UnaryExpressionAST; struct UnqualifiedNameAST; struct UsingAST; struct UsingDirectiveAST; struct WhileStatementAST; struct WinDeclSpecAST; struct QPropertyAST; struct QEnumsAST; struct AST { enum NODE_KIND { Kind_UNKNOWN = 0, Kind_AccessSpecifier, Kind_AsmDefinition, Kind_BaseClause, Kind_BaseSpecifier, Kind_BinaryExpression, Kind_CastExpression, Kind_ClassMemberAccess, Kind_ClassSpecifier, Kind_CompoundStatement, Kind_Condition, Kind_ConditionalExpression, Kind_CppCastExpression, Kind_CtorInitializer, Kind_DeclarationStatement, Kind_Declarator, Kind_DeleteExpression, Kind_DoStatement, Kind_ElaboratedTypeSpecifier, Kind_EnumSpecifier, Kind_Enumerator, Kind_ExceptionSpecification, Kind_ExpressionOrDeclarationStatement, Kind_ExpressionStatement, Kind_ForStatement, Kind_FunctionCall, Kind_FunctionDefinition, Kind_IfStatement, Kind_IncrDecrExpression, Kind_InitDeclarator, Kind_Initializer, Kind_InitializerClause, Kind_LabeledStatement, Kind_LinkageBody, Kind_LinkageSpecification, Kind_MemInitializer, Kind_Name, Kind_Namespace, Kind_NamespaceAliasDefinition, Kind_NewDeclarator, Kind_NewExpression, Kind_NewInitializer, Kind_NewTypeId, Kind_Operator, Kind_OperatorFunctionId, Kind_ParameterDeclaration, Kind_ParameterDeclarationClause, Kind_PostfixExpression, Kind_PrimaryExpression, Kind_PtrOperator, Kind_PtrToMember, Kind_ReturnStatement, Kind_SimpleDeclaration, Kind_SimpleTypeSpecifier, Kind_SizeofExpression, Kind_StringLiteral, Kind_SubscriptExpression, Kind_SwitchStatement, Kind_TemplateArgument, Kind_TemplateDeclaration, Kind_TemplateParameter, Kind_ThrowExpression, Kind_TranslationUnit, Kind_TryBlockStatement, Kind_TypeId, Kind_TypeIdentification, Kind_TypeParameter, Kind_Typedef, Kind_UnaryExpression, Kind_UnqualifiedName, Kind_Using, Kind_UsingDirective, Kind_WhileStatement, Kind_WinDeclSpec, Kind_QPropertyAST, Kind_ForwardDeclarationSpecifier, Kind_QEnumsAST, NODE_KIND_COUNT }; QString toString(TokenStream *stream) const; int kind; std::size_t start_token; std::size_t end_token; }; struct TypeSpecifierAST: public AST { const ListNode *cv; }; struct StatementAST: public AST { }; struct ExpressionAST: public AST { }; struct DeclarationAST: public AST { }; struct AccessSpecifierAST: public DeclarationAST { DECLARE_AST_NODE(AccessSpecifier) const ListNode *specs; }; struct AsmDefinitionAST: public DeclarationAST { DECLARE_AST_NODE(AsmDefinition) const ListNode *cv; }; struct BaseClauseAST: public AST // ### kill me { DECLARE_AST_NODE(BaseClause) const ListNode *base_specifiers; }; struct BaseSpecifierAST: public AST { DECLARE_AST_NODE(BaseSpecifier) std::size_t virt; std::size_t access_specifier; NameAST *name; }; struct BinaryExpressionAST: public ExpressionAST { DECLARE_AST_NODE(BinaryExpression) std::size_t op; ExpressionAST *left_expression; ExpressionAST *right_expression; }; struct CastExpressionAST: public ExpressionAST { DECLARE_AST_NODE(CastExpression) TypeIdAST *type_id; ExpressionAST *expression; }; struct ClassMemberAccessAST: public ExpressionAST { DECLARE_AST_NODE(ClassMemberAccess) std::size_t op; NameAST *name; }; struct ClassSpecifierAST: public TypeSpecifierAST { DECLARE_AST_NODE(ClassSpecifier) WinDeclSpecAST *win_decl_specifiers; std::size_t class_key; NameAST *name; BaseClauseAST *base_clause; const ListNode *member_specs; }; struct ForwardDeclarationSpecifierAST: public TypeSpecifierAST { DECLARE_AST_NODE(ForwardDeclarationSpecifier) std::size_t class_key; NameAST *name; BaseClauseAST *base_clause; }; struct CompoundStatementAST: public StatementAST { DECLARE_AST_NODE(CompoundStatement) const ListNode *statements; }; struct ConditionAST: public AST { DECLARE_AST_NODE(Condition) TypeSpecifierAST *type_specifier; DeclaratorAST *declarator; ExpressionAST *expression; }; struct ConditionalExpressionAST: public ExpressionAST { DECLARE_AST_NODE(ConditionalExpression) ExpressionAST *condition; ExpressionAST *left_expression; ExpressionAST *right_expression; }; struct CppCastExpressionAST: public ExpressionAST { DECLARE_AST_NODE(CppCastExpression) std::size_t op; TypeIdAST *type_id; ExpressionAST *expression; const ListNode *sub_expressions; }; struct CtorInitializerAST: public AST { DECLARE_AST_NODE(CtorInitializer) std::size_t colon; const ListNode *member_initializers; }; struct DeclarationStatementAST: public StatementAST { DECLARE_AST_NODE(DeclarationStatement) DeclarationAST *declaration; }; struct DeclaratorAST: public AST { DECLARE_AST_NODE(Declarator) const ListNode *ptr_ops; DeclaratorAST *sub_declarator; NameAST *id; ExpressionAST *bit_expression; const ListNode *array_dimensions; ParameterDeclarationClauseAST *parameter_declaration_clause; const ListNode *fun_cv; ExceptionSpecificationAST *exception_spec; }; struct DeleteExpressionAST: public ExpressionAST { DECLARE_AST_NODE(DeleteExpression) std::size_t scope_token; std::size_t delete_token; std::size_t lbracket_token; std::size_t rbracket_token; ExpressionAST *expression; }; struct DoStatementAST: public StatementAST { DECLARE_AST_NODE(DoStatement) StatementAST *statement; ExpressionAST *expression; }; struct ElaboratedTypeSpecifierAST: public TypeSpecifierAST { DECLARE_AST_NODE(ElaboratedTypeSpecifier) std::size_t type; NameAST *name; }; struct EnumSpecifierAST: public TypeSpecifierAST { DECLARE_AST_NODE(EnumSpecifier) NameAST *name; const ListNode *enumerators; }; struct EnumeratorAST: public AST { DECLARE_AST_NODE(Enumerator) std::size_t id; ExpressionAST *expression; }; struct ExceptionSpecificationAST: public AST { DECLARE_AST_NODE(ExceptionSpecification) std::size_t ellipsis; const ListNode *type_ids; }; struct ExpressionOrDeclarationStatementAST: public StatementAST { DECLARE_AST_NODE(ExpressionOrDeclarationStatement) StatementAST *expression; StatementAST *declaration; }; struct ExpressionStatementAST: public StatementAST { DECLARE_AST_NODE(ExpressionStatement) ExpressionAST *expression; }; struct FunctionCallAST: public ExpressionAST { DECLARE_AST_NODE(FunctionCall) ExpressionAST *arguments; }; struct FunctionDefinitionAST: public DeclarationAST { DECLARE_AST_NODE(FunctionDefinition) const ListNode *storage_specifiers; const ListNode *function_specifiers; TypeSpecifierAST *type_specifier; InitDeclaratorAST *init_declarator; StatementAST *function_body; WinDeclSpecAST *win_decl_specifiers; }; struct ForStatementAST: public StatementAST { DECLARE_AST_NODE(ForStatement) StatementAST *init_statement; ConditionAST *condition; ExpressionAST *expression; StatementAST *statement; }; struct IfStatementAST: public StatementAST { DECLARE_AST_NODE(IfStatement) ConditionAST *condition; StatementAST *statement; StatementAST *else_statement; }; struct IncrDecrExpressionAST: public ExpressionAST { DECLARE_AST_NODE(IncrDecrExpression) std::size_t op; }; struct InitDeclaratorAST: public AST { DECLARE_AST_NODE(InitDeclarator) DeclaratorAST *declarator; InitializerAST *initializer; }; struct InitializerAST: public AST { DECLARE_AST_NODE(Initializer) InitializerClauseAST *initializer_clause; ExpressionAST *expression; }; struct InitializerClauseAST: public AST { DECLARE_AST_NODE(InitializerClause) ExpressionAST *expression; }; struct LabeledStatementAST: public StatementAST { DECLARE_AST_NODE(LabeledStatement) }; struct LinkageBodyAST: public AST { DECLARE_AST_NODE(LinkageBody) const ListNode *declarations; }; struct LinkageSpecificationAST: public DeclarationAST { DECLARE_AST_NODE(LinkageSpecification) std::size_t extern_type; LinkageBodyAST *linkage_body; DeclarationAST *declaration; }; struct MemInitializerAST: public AST { DECLARE_AST_NODE(MemInitializer) NameAST *initializer_id; ExpressionAST *expression; }; struct NameAST: public AST { DECLARE_AST_NODE(Name) bool global; const ListNode *qualified_names; UnqualifiedNameAST *unqualified_name; }; struct NamespaceAST: public DeclarationAST { DECLARE_AST_NODE(Namespace) std::size_t namespace_name; LinkageBodyAST *linkage_body; }; struct NamespaceAliasDefinitionAST: public DeclarationAST { DECLARE_AST_NODE(NamespaceAliasDefinition) std::size_t namespace_name; NameAST *alias_name; }; struct NewDeclaratorAST: public AST { DECLARE_AST_NODE(NewDeclarator) PtrOperatorAST *ptr_op; NewDeclaratorAST *sub_declarator; const ListNode *expressions; }; struct NewExpressionAST: public ExpressionAST { DECLARE_AST_NODE(NewExpression) std::size_t scope_token; std::size_t new_token; ExpressionAST *expression; TypeIdAST *type_id; NewTypeIdAST *new_type_id; NewInitializerAST *new_initializer; }; struct NewInitializerAST: public AST { DECLARE_AST_NODE(NewInitializer) ExpressionAST *expression; }; struct NewTypeIdAST: public AST { DECLARE_AST_NODE(NewTypeId) TypeSpecifierAST *type_specifier; NewInitializerAST *new_initializer; NewDeclaratorAST *new_declarator; }; struct OperatorAST: public AST { DECLARE_AST_NODE(Operator) std::size_t op; std::size_t open; std::size_t close; }; struct OperatorFunctionIdAST: public AST { DECLARE_AST_NODE(OperatorFunctionId) OperatorAST *op; TypeSpecifierAST *type_specifier; const ListNode *ptr_ops; }; struct ParameterDeclarationAST: public AST { DECLARE_AST_NODE(ParameterDeclaration) TypeSpecifierAST *type_specifier; DeclaratorAST *declarator; ExpressionAST *expression; }; struct ParameterDeclarationClauseAST: public AST { DECLARE_AST_NODE(ParameterDeclarationClause) const ListNode *parameter_declarations; std::size_t ellipsis; }; struct PostfixExpressionAST: public ExpressionAST { DECLARE_AST_NODE(PostfixExpression) TypeSpecifierAST *type_specifier; ExpressionAST *expression; const ListNode *sub_expressions; }; struct PrimaryExpressionAST: public ExpressionAST { DECLARE_AST_NODE(PrimaryExpression) StringLiteralAST *literal; std::size_t token; StatementAST *expression_statement; ExpressionAST *sub_expression; NameAST *name; }; struct PtrOperatorAST: public AST { DECLARE_AST_NODE(PtrOperator) const ListNode *cv; std::size_t op; PtrToMemberAST *mem_ptr; }; struct PtrToMemberAST: public AST { DECLARE_AST_NODE(PtrToMember) }; struct ReturnStatementAST: public StatementAST { DECLARE_AST_NODE(ReturnStatement) ExpressionAST *expression; }; struct SimpleDeclarationAST: public DeclarationAST { DECLARE_AST_NODE(SimpleDeclaration) const ListNode *storage_specifiers; const ListNode *function_specifiers; TypeSpecifierAST *type_specifier; const ListNode *init_declarators; WinDeclSpecAST *win_decl_specifiers; }; struct SimpleTypeSpecifierAST: public TypeSpecifierAST { DECLARE_AST_NODE(SimpleTypeSpecifier) const ListNode *integrals; std::size_t type_of; TypeIdAST *type_id; ExpressionAST *expression; NameAST *name; }; struct SizeofExpressionAST: public ExpressionAST { DECLARE_AST_NODE(SizeofExpression) std::size_t sizeof_token; TypeIdAST *type_id; ExpressionAST *expression; }; struct StringLiteralAST: public AST { DECLARE_AST_NODE(StringLiteral) const ListNode *literals; }; struct SubscriptExpressionAST: public ExpressionAST { DECLARE_AST_NODE(SubscriptExpression) ExpressionAST *subscript; }; struct SwitchStatementAST: public StatementAST { DECLARE_AST_NODE(SwitchStatement) ConditionAST *condition; StatementAST *statement; }; struct TemplateArgumentAST: public AST { DECLARE_AST_NODE(TemplateArgument) TypeIdAST *type_id; ExpressionAST *expression; }; struct TemplateDeclarationAST: public DeclarationAST { DECLARE_AST_NODE(TemplateDeclaration) std::size_t exported; const ListNode *template_parameters; DeclarationAST* declaration; }; struct TemplateParameterAST: public AST { DECLARE_AST_NODE(TemplateParameter) TypeParameterAST *type_parameter; ParameterDeclarationAST *parameter_declaration; }; struct ThrowExpressionAST: public ExpressionAST { DECLARE_AST_NODE(ThrowExpression) std::size_t throw_token; ExpressionAST *expression; }; struct TranslationUnitAST: public AST { DECLARE_AST_NODE(TranslationUnit) const ListNode *declarations; }; struct TryBlockStatementAST: public StatementAST { DECLARE_AST_NODE(TryBlockStatement) }; struct TypeIdAST: public AST { DECLARE_AST_NODE(TypeId) TypeSpecifierAST *type_specifier; DeclaratorAST *declarator; }; struct TypeIdentificationAST: public ExpressionAST { DECLARE_AST_NODE(TypeIdentification) std::size_t typename_token; NameAST *name; ExpressionAST *expression; }; struct TypeParameterAST: public AST { DECLARE_AST_NODE(TypeParameter) std::size_t type; NameAST *name; TypeIdAST *type_id; const ListNode *template_parameters; NameAST *template_name; }; struct TypedefAST: public DeclarationAST { DECLARE_AST_NODE(Typedef) TypeSpecifierAST *type_specifier; const ListNode *init_declarators; }; struct UnaryExpressionAST: public ExpressionAST { DECLARE_AST_NODE(UnaryExpression) std::size_t op; ExpressionAST *expression; }; struct UnqualifiedNameAST: public AST { DECLARE_AST_NODE(UnqualifiedName) std::size_t tilde; std::size_t id; OperatorFunctionIdAST *operator_id; const ListNode *template_arguments; }; struct UsingAST: public DeclarationAST { DECLARE_AST_NODE(Using) std::size_t type_name; NameAST *name; }; struct UsingDirectiveAST: public DeclarationAST { DECLARE_AST_NODE(UsingDirective) NameAST *name; }; struct WhileStatementAST: public StatementAST { DECLARE_AST_NODE(WhileStatement) ConditionAST *condition; StatementAST *statement; }; struct WinDeclSpecAST: public AST { DECLARE_AST_NODE(WinDeclSpec) std::size_t specifier; std::size_t modifier; }; struct QPropertyAST : public DeclarationAST { DECLARE_AST_NODE(QPropertyAST) }; struct QEnumsAST : public DeclarationAST { DECLARE_AST_NODE(QEnumsAST) }; template _Tp *CreateNode(pool *memory_pool) { _Tp *node = reinterpret_cast<_Tp*>(memory_pool->allocate(sizeof(_Tp))); node->kind = _Tp::__node_kind; return node; } template _Tp ast_cast(AST *item) { if (item && static_cast<_Tp>(0)->__node_kind == item->kind) return static_cast<_Tp>(item); return 0; } #endif // AST_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/binder.cpp000066400000000000000000000717121170724227300233240ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "binder.h" #include "lexer.h" #include "control.h" #include "symbol.h" #include "codemodel_finder.h" #include "class_compiler.h" #include "compiler_utils.h" #include "tokens.h" #include "dumptree.h" #include #include Binder::Binder(CodeModel *__model, LocationManager &__location, Control *__control) : _M_model(__model), _M_location(__location), _M_token_stream(&_M_location.token_stream), _M_control(__control), _M_current_function_type(CodeModel::Normal), type_cc(this), name_cc(this), decl_cc(this) { _M_qualified_types["char"] = QString(); _M_qualified_types["double"] = QString(); _M_qualified_types["float"] = QString(); _M_qualified_types["int"] = QString(); _M_qualified_types["long"] = QString(); _M_qualified_types["short"] = QString(); _M_qualified_types["void"] = QString(); } Binder::~Binder() { } FileModelItem Binder::run(AST *node) { FileModelItem old = _M_current_file; _M_current_access = CodeModel::Public; _M_current_file = model()->create(); updateItemPosition (_M_current_file->toItem(), node); visit(node); FileModelItem result = _M_current_file; _M_current_file = old; // restore return result; } ScopeModelItem Binder::currentScope() { if (_M_current_class) return model_static_cast(_M_current_class); else if (_M_current_namespace) return model_static_cast(_M_current_namespace); return model_static_cast(_M_current_file); } TemplateParameterList Binder::changeTemplateParameters(TemplateParameterList templateParameters) { TemplateParameterList old = _M_current_template_parameters; _M_current_template_parameters = templateParameters; return old; } CodeModel::FunctionType Binder::changeCurrentFunctionType(CodeModel::FunctionType functionType) { CodeModel::FunctionType old = _M_current_function_type; _M_current_function_type = functionType; return old; } CodeModel::AccessPolicy Binder::changeCurrentAccess(CodeModel::AccessPolicy accessPolicy) { CodeModel::AccessPolicy old = _M_current_access; _M_current_access = accessPolicy; return old; } NamespaceModelItem Binder::changeCurrentNamespace(NamespaceModelItem item) { NamespaceModelItem old = _M_current_namespace; _M_current_namespace = item; return old; } ClassModelItem Binder::changeCurrentClass(ClassModelItem item) { ClassModelItem old = _M_current_class; _M_current_class = item; return old; } FunctionDefinitionModelItem Binder::changeCurrentFunction(FunctionDefinitionModelItem item) { FunctionDefinitionModelItem old = _M_current_function; _M_current_function = item; return old; } int Binder::decode_token(std::size_t index) const { return _M_token_stream->kind(index); } CodeModel::AccessPolicy Binder::decode_access_policy(std::size_t index) const { switch (decode_token(index)) { case Token_class: return CodeModel::Private; case Token_struct: case Token_union: return CodeModel::Public; default: return CodeModel::Public; } } CodeModel::ClassType Binder::decode_class_type(std::size_t index) const { switch (decode_token(index)) { case Token_class: return CodeModel::Class; case Token_struct: return CodeModel::Struct; case Token_union: return CodeModel::Union; default: std::cerr << "** WARNING unrecognized class type" << std::endl; } return CodeModel::Class; } const NameSymbol *Binder::decode_symbol(std::size_t index) const { return _M_token_stream->symbol(index); } void Binder::visitAccessSpecifier(AccessSpecifierAST *node) { const ListNode *it = node->specs; if (it == 0) return; it = it->toFront(); const ListNode *end = it; do { switch (decode_token(it->element)) { default: break; case Token_public: changeCurrentAccess(CodeModel::Public); changeCurrentFunctionType(CodeModel::Normal); break; case Token_protected: changeCurrentAccess(CodeModel::Protected); changeCurrentFunctionType(CodeModel::Normal); break; case Token_private: changeCurrentAccess(CodeModel::Private); changeCurrentFunctionType(CodeModel::Normal); break; case Token_signals: changeCurrentAccess(CodeModel::Protected); changeCurrentFunctionType(CodeModel::Signal); break; case Token_slots: changeCurrentFunctionType(CodeModel::Slot); break; } it = it->next; } while (it != end); } void Binder::visitSimpleDeclaration(SimpleDeclarationAST *node) { visit(node->type_specifier); if (const ListNode *it = node->init_declarators) { it = it->toFront(); const ListNode *end = it; do { InitDeclaratorAST *init_declarator = it->element; declare_symbol(node, init_declarator); it = it->next; } while (it != end); } } void Binder::declare_symbol(SimpleDeclarationAST *node, InitDeclaratorAST *init_declarator) { DeclaratorAST *declarator = init_declarator->declarator; while (declarator && declarator->sub_declarator) declarator = declarator->sub_declarator; NameAST *id = declarator->id; if (! declarator->id) { std::cerr << "** WARNING expected a declarator id" << std::endl; return; } CodeModelFinder finder(model(), this); ScopeModelItem symbolScope = finder.resolveScope(id, currentScope()); if (! symbolScope) { name_cc.run(id); std::cerr << "** WARNING scope not found for symbol:" << qPrintable(name_cc.name()) << std::endl; return; } decl_cc.run(declarator); if (decl_cc.isFunction()) { name_cc.run(id->unqualified_name); FunctionModelItem fun = model()->create(); updateItemPosition (fun->toItem(), node); fun->setAccessPolicy(_M_current_access); fun->setFunctionType(_M_current_function_type); fun->setName(name_cc.name()); fun->setAbstract(init_declarator->initializer != 0); fun->setConstant(declarator->fun_cv != 0); fun->setException(exceptionSpecToString(declarator->exception_spec)); fun->setTemplateParameters(_M_current_template_parameters); applyStorageSpecifiers(node->storage_specifiers, model_static_cast(fun)); applyFunctionSpecifiers(node->function_specifiers, fun); // build the type TypeInfo typeInfo = CompilerUtils::typeDescription(node->type_specifier, declarator, this); fun->setType(qualifyType(typeInfo, symbolScope->qualifiedName())); fun->setVariadics (decl_cc.isVariadics ()); // ... and the signature foreach (DeclaratorCompiler::Parameter p, decl_cc.parameters()) { ArgumentModelItem arg = model()->create(); arg->setType(qualifyType(p.type, _M_context)); arg->setName(p.name); arg->setDefaultValue(p.defaultValue); if (p.defaultValue) arg->setDefaultValueExpression(p.defaultValueExpression); fun->addArgument(arg); } fun->setScope(symbolScope->qualifiedName()); symbolScope->addFunction(fun); } else { VariableModelItem var = model()->create(); updateItemPosition (var->toItem(), node); var->setTemplateParameters(_M_current_template_parameters); var->setAccessPolicy(_M_current_access); name_cc.run(id->unqualified_name); var->setName(name_cc.name()); TypeInfo typeInfo = CompilerUtils::typeDescription(node->type_specifier, declarator, this); if (declarator != init_declarator->declarator && init_declarator->declarator->parameter_declaration_clause != 0) { typeInfo.setFunctionPointer (true); decl_cc.run (init_declarator->declarator); foreach (DeclaratorCompiler::Parameter p, decl_cc.parameters()) typeInfo.addArgument(p.type); } var->setType(qualifyType(typeInfo, _M_context)); applyStorageSpecifiers(node->storage_specifiers, model_static_cast(var)); var->setScope(symbolScope->qualifiedName()); symbolScope->addVariable(var); } } void Binder::visitFunctionDefinition(FunctionDefinitionAST *node) { Q_ASSERT(node->init_declarator != 0); ScopeModelItem scope = currentScope(); InitDeclaratorAST *init_declarator = node->init_declarator; DeclaratorAST *declarator = init_declarator->declarator; // in the case of "void (func)()" or "void ((func))()" we need to // skip to the inner most. This is in line with how the declarator // node is generated in 'parser.cpp' while (declarator && declarator->sub_declarator) declarator = declarator->sub_declarator; Q_ASSERT(declarator->id); CodeModelFinder finder(model(), this); ScopeModelItem functionScope = finder.resolveScope(declarator->id, scope); if (! functionScope) { name_cc.run(declarator->id); std::cerr << "** WARNING scope not found for function definition:" << qPrintable(name_cc.name()) << std::endl << "\tdefinition *ignored*" << std::endl; return; } decl_cc.run(declarator); Q_ASSERT(! decl_cc.id().isEmpty()); FunctionDefinitionModelItem old = changeCurrentFunction(_M_model->create()); _M_current_function->setScope(functionScope->qualifiedName()); updateItemPosition (_M_current_function->toItem(), node); Q_ASSERT(declarator->id->unqualified_name != 0); name_cc.run(declarator->id->unqualified_name); QString unqualified_name = name_cc.name(); _M_current_function->setName(unqualified_name); TypeInfo tmp_type = CompilerUtils::typeDescription(node->type_specifier, declarator, this); _M_current_function->setType(qualifyType(tmp_type, _M_context)); _M_current_function->setAccessPolicy(_M_current_access); _M_current_function->setFunctionType(_M_current_function_type); _M_current_function->setConstant(declarator->fun_cv != 0); _M_current_function->setTemplateParameters(_M_current_template_parameters); _M_current_function->setException(exceptionSpecToString(declarator->exception_spec)); applyStorageSpecifiers(node->storage_specifiers, model_static_cast(_M_current_function)); applyFunctionSpecifiers(node->function_specifiers, model_static_cast(_M_current_function)); _M_current_function->setVariadics (decl_cc.isVariadics ()); foreach (DeclaratorCompiler::Parameter p, decl_cc.parameters()) { ArgumentModelItem arg = model()->create(); arg->setType(qualifyType(p.type, functionScope->qualifiedName())); arg->setName(p.name); arg->setDefaultValue(p.defaultValue); if (p.defaultValue) arg->setDefaultValueExpression(p.defaultValueExpression); _M_current_function->addArgument(arg); } functionScope->addFunctionDefinition(_M_current_function); FunctionModelItem prototype = model_static_cast(_M_current_function); FunctionModelItem declared = functionScope->declaredFunction(prototype); // try to find a function declaration for this definition.. if (! declared) { functionScope->addFunction(prototype); } else { applyFunctionSpecifiers(node->function_specifiers, declared); // fix the function type and the access policy _M_current_function->setAccessPolicy(declared->accessPolicy()); _M_current_function->setFunctionType(declared->functionType()); } changeCurrentFunction(old); } void Binder::visitTemplateDeclaration(TemplateDeclarationAST *node) { const ListNode *it = node->template_parameters; if (it == 0) { // QtScript: we want to visit the declaration still, so that // e.g. QMetaTypeId is added to the code model visit(node->declaration); return; } TemplateParameterList savedTemplateParameters = changeTemplateParameters(TemplateParameterList()); it = it->toFront(); const ListNode *end = it; TemplateParameterList templateParameters; do { TemplateParameterAST *parameter = it->element; TypeParameterAST *type_parameter = parameter->type_parameter; NameAST *name; if (!type_parameter) { // A hacky hack to work around missing support for parameter declarations in // templates. We just need the to get the name of the variable, since we // aren't actually compiling these anyway. We are still not supporting much // more, but we are refusing to fail for a few more declarations if (parameter->parameter_declaration == 0 || parameter->parameter_declaration->declarator == 0 || parameter->parameter_declaration->declarator->id == 0) { /*std::cerr << "** WARNING template declaration not supported ``"; Token const &tk = _M_token_stream->token ((int) node->start_token); Token const &end_tk = _M_token_stream->token ((int) node->declaration->start_token); std::cerr << std::string (&tk.text[tk.position], (end_tk.position) - tk.position) << "''" << std::endl << std::endl;*/ changeTemplateParameters(savedTemplateParameters); return; } name = parameter->parameter_declaration->declarator->id; } else { int tk = decode_token(type_parameter->type); if (tk != Token_typename && tk != Token_class) { /*std::cerr << "** WARNING template declaration not supported ``"; Token const &tk = _M_token_stream->token ((int) node->start_token); Token const &end_tk = _M_token_stream->token ((int) node->declaration->start_token); std::cerr << std::string (&tk.text[tk.position], (end_tk.position) - tk.position) << "''" << std::endl << std::endl;*/ changeTemplateParameters(savedTemplateParameters); return; } assert(tk == Token_typename || tk == Token_class); name = type_parameter->name; } TemplateParameterModelItem p = model()->create(); name_cc.run(name); p->setName(name_cc.name()); _M_current_template_parameters.append(p); it = it->next; } while (it != end); visit(node->declaration); changeTemplateParameters(savedTemplateParameters); } void Binder::visitTypedef(TypedefAST *node) { const ListNode *it = node->init_declarators; if (it == 0) return; it = it->toFront(); const ListNode *end = it; do { InitDeclaratorAST *init_declarator = it->element; it = it->next; Q_ASSERT(init_declarator->declarator != 0); // the name decl_cc.run (init_declarator->declarator); QString alias_name = decl_cc.id (); if (alias_name.isEmpty ()) { std::cerr << "** WARNING anonymous typedef not supported! ``"; Token const &tk = _M_token_stream->token ((int) node->start_token); Token const &end_tk = _M_token_stream->token ((int) node->end_token); std::cerr << std::string (&tk.text[tk.position], end_tk.position - tk.position) << "''" << std::endl << std::endl; continue; } // build the type TypeInfo typeInfo = CompilerUtils::typeDescription (node->type_specifier, init_declarator->declarator, this); DeclaratorAST *decl = init_declarator->declarator; while (decl && decl->sub_declarator) decl = decl->sub_declarator; if (decl != init_declarator->declarator && init_declarator->declarator->parameter_declaration_clause != 0) { typeInfo.setFunctionPointer (true); decl_cc.run (init_declarator->declarator); foreach (DeclaratorCompiler::Parameter p, decl_cc.parameters()) typeInfo.addArgument(p.type); } ScopeModelItem scope = currentScope(); DeclaratorAST *declarator = init_declarator->declarator; CodeModelFinder finder(model(), this); ScopeModelItem typedefScope = finder.resolveScope(declarator->id, scope); TypeAliasModelItem typeAlias = model ()->create (); updateItemPosition (typeAlias->toItem (), node); typeAlias->setName (alias_name); typeAlias->setType (qualifyType (typeInfo, currentScope ()->qualifiedName ())); typeAlias->setScope (typedefScope->qualifiedName()); _M_qualified_types[typeAlias->qualifiedName().join(".")] = QString(); currentScope ()->addTypeAlias (typeAlias); } while (it != end); } void Binder::visitNamespace(NamespaceAST *node) { bool anonymous = (node->namespace_name == 0); ScopeModelItem scope = currentScope(); NamespaceModelItem old; if (! anonymous) { QString name = decode_symbol(node->namespace_name)->as_string(); QStringList qualified_name = scope->qualifiedName(); qualified_name += name; NamespaceModelItem ns = model_safe_cast(_M_model->findItem(qualified_name, _M_current_file->toItem())); if (!ns) { ns = _M_model->create(); updateItemPosition (ns->toItem(), node); ns->setName(name); ns->setScope(scope->qualifiedName()); } old = changeCurrentNamespace(ns); _M_context.append(name); } DefaultVisitor::visitNamespace(node); if (! anonymous) { Q_ASSERT(scope->kind() == _CodeModelItem::Kind_Namespace || scope->kind() == _CodeModelItem::Kind_File); _M_context.removeLast(); if (NamespaceModelItem ns = model_static_cast(scope)) { ns->addNamespace(_M_current_namespace); } changeCurrentNamespace(old); } } void Binder::visitForwardDeclarationSpecifier(ForwardDeclarationSpecifierAST *node) { name_cc.run(node->name); if (name_cc.name().isEmpty()) return; ScopeModelItem scope = currentScope(); _M_qualified_types[(scope->qualifiedName() + name_cc.qualifiedName()).join(".") ] = QString(); } void Binder::visitClassSpecifier(ClassSpecifierAST *node) { ClassCompiler class_cc(this); class_cc.run(node); if (class_cc.name().isEmpty()) { // anonymous not supported return; } Q_ASSERT(node->name != 0 && node->name->unqualified_name != 0); ScopeModelItem scope = currentScope(); ClassModelItem old = changeCurrentClass(_M_model->create()); updateItemPosition (_M_current_class->toItem(), node); _M_current_class->setName(class_cc.name()); QStringList baseClasses = class_cc.baseClasses(); TypeInfo info; for (int i=0; iqualifiedName()).qualifiedName().join("::"); } _M_current_class->setBaseClasses(baseClasses); _M_current_class->setClassType(decode_class_type(node->class_key)); _M_current_class->setTemplateParameters(_M_current_template_parameters); if (! _M_current_template_parameters.isEmpty()) { QString name = _M_current_class->name(); name += "<"; for (int i = 0; i<_M_current_template_parameters.size(); ++i) { if (i != 0) name += ","; name += _M_current_template_parameters.at(i)->name(); } name += ">"; _M_current_class->setName(name); } CodeModel::AccessPolicy oldAccessPolicy = changeCurrentAccess(decode_access_policy(node->class_key)); CodeModel::FunctionType oldFunctionType = changeCurrentFunctionType(CodeModel::Normal); _M_current_class->setScope(scope->qualifiedName()); _M_qualified_types[_M_current_class->qualifiedName().join(".")] = QString(); scope->addClass(_M_current_class); name_cc.run(node->name->unqualified_name); _M_context.append(name_cc.name()); visitNodes(this, node->member_specs); _M_context.removeLast(); changeCurrentClass(old); changeCurrentAccess(oldAccessPolicy); changeCurrentFunctionType(oldFunctionType); } void Binder::visitLinkageSpecification(LinkageSpecificationAST *node) { DefaultVisitor::visitLinkageSpecification(node); } void Binder::visitUsing(UsingAST *node) { DefaultVisitor::visitUsing(node); } void Binder::visitEnumSpecifier(EnumSpecifierAST *node) { CodeModelFinder finder(model(), this); ScopeModelItem scope = currentScope(); ScopeModelItem enumScope = finder.resolveScope(node->name, scope); name_cc.run(node->name); QString name = name_cc.name(); if (name.isEmpty()) { // anonymous enum QString key = _M_context.join("::"); int current = ++_M_anonymous_enums[key]; name += QLatin1String("enum_"); name += QString::number(current); } _M_current_enum = model()->create(); _M_current_enum->setAccessPolicy(_M_current_access); updateItemPosition (_M_current_enum->toItem(), node); _M_current_enum->setName(name); _M_current_enum->setScope(enumScope->qualifiedName()); _M_qualified_types[_M_current_enum->qualifiedName().join(".")] = QString(); enumScope->addEnum(_M_current_enum); DefaultVisitor::visitEnumSpecifier(node); _M_current_enum = 0; } static QString strip_preprocessor_lines(const QString &name) { QStringList lst = name.split("\n"); QString s; for (int i=0; icreate(); updateItemPosition (e->toItem(), node); e->setName(decode_symbol(node->id)->as_string()); if (ExpressionAST *expr = node->expression) { const Token &start_token = _M_token_stream->token((int) expr->start_token); const Token &end_token = _M_token_stream->token((int) expr->end_token); e->setValue(strip_preprocessor_lines(QString::fromUtf8(&start_token.text[start_token.position], (int) (end_token.position - start_token.position)).trimmed()).remove(' ')); } _M_current_enum->addEnumerator(e); } void Binder::visitUsingDirective(UsingDirectiveAST *node) { DefaultVisitor::visitUsingDirective(node); } void Binder::visitQEnums(QEnumsAST *node) { const Token &start = _M_token_stream->token((int) node->start_token); const Token &end = _M_token_stream->token((int) node->end_token); QStringList enum_list = QString::fromLatin1(start.text + start.position, end.position - start.position).split(' '); ScopeModelItem scope = currentScope(); for (int i=0; iaddEnumsDeclaration(enum_list.at(i)); } void Binder::visitQProperty(QPropertyAST *node) { const Token &start = _M_token_stream->token((int) node->start_token); const Token &end = _M_token_stream->token((int) node->end_token); QString property = QString::fromLatin1(start.text + start.position, end.position - start.position); _M_current_class->addPropertyDeclaration(property); } void Binder::applyStorageSpecifiers(const ListNode *it, MemberModelItem item) { if (it == 0) return; it = it->toFront(); const ListNode *end = it; do { switch (decode_token(it->element)) { default: break; case Token_friend: item->setFriend(true); break; case Token_auto: item->setAuto(true); break; case Token_register: item->setRegister(true); break; case Token_static: item->setStatic(true); break; case Token_extern: item->setExtern(true); break; case Token_mutable: item->setMutable(true); break; } it = it->next; } while (it != end); } void Binder::applyFunctionSpecifiers(const ListNode *it, FunctionModelItem item) { if (it == 0) return; it = it->toFront(); const ListNode *end = it; do { switch (decode_token(it->element)) { default: break; case Token_inline: item->setInline(true); break; case Token_virtual: item->setVirtual(true); break; case Token_explicit: item->setExplicit(true); break; case Token_Q_INVOKABLE: item->setInvokable(true); break; } it = it->next; } while (it != end); } TypeInfo Binder::qualifyType(const TypeInfo &type, const QStringList &context) const { // ### Potentially improve to use string list in the name table to if (context.size() == 0) { // ### We can assume that this means global namespace for now... return type; } else if (_M_qualified_types.contains(type.qualifiedName().join("."))) { return type; } else { QStringList expanded = context; expanded << type.qualifiedName(); if (_M_qualified_types.contains(expanded.join("."))) { TypeInfo modified_type = type; modified_type.setQualifiedName(expanded); return modified_type; } else { CodeModelItem scope = model ()->findItem (context, _M_current_file->toItem ()); if (ClassModelItem klass = model_dynamic_cast (scope)) { foreach (QString base, klass->baseClasses ()) { QStringList ctx = context; ctx.removeLast(); ctx.append (base); TypeInfo qualified = qualifyType (type, ctx); if (qualified != type) return qualified; } } QStringList copy = context; copy.removeLast(); return qualifyType(type, copy); } } } void Binder::updateItemPosition(CodeModelItem item, AST *node) { QString filename; int line, column; assert (node != 0); _M_location.positionAt (_M_token_stream->position(node->start_token), &line, &column, &filename); item->setFileName (filename); } QString Binder::exceptionSpecToString(ExceptionSpecificationAST* exception_spec) { QString exception; if (exception_spec) { const Token &start_token = _M_token_stream->token((int) exception_spec->start_token); const Token &end_token = _M_token_stream->token((int) exception_spec->end_token); exception = QString::fromUtf8(&start_token.text[start_token.position], (int)(end_token.position - start_token.position)); } return exception; } // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/binder.h000066400000000000000000000115571170724227300227720ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef BINDER_H #define BINDER_H #include "default_visitor.h" #include "codemodel.h" #include "type_compiler.h" #include "name_compiler.h" #include "declarator_compiler.h" class TokenStream; class LocationManager; class Control; struct NameSymbol; class Binder: protected DefaultVisitor { public: Binder(CodeModel *__model, LocationManager &__location, Control *__control = 0); virtual ~Binder(); inline TokenStream *tokenStream() const { return _M_token_stream; } inline CodeModel *model() const { return _M_model; } ScopeModelItem currentScope(); FileModelItem run(AST *node); // utils TypeInfo qualifyType(const TypeInfo &type, const QStringList &context) const; protected: virtual void visitAccessSpecifier(AccessSpecifierAST *); virtual void visitClassSpecifier(ClassSpecifierAST *); virtual void visitEnumSpecifier(EnumSpecifierAST *); virtual void visitEnumerator(EnumeratorAST *); virtual void visitFunctionDefinition(FunctionDefinitionAST *); virtual void visitLinkageSpecification(LinkageSpecificationAST *); virtual void visitNamespace(NamespaceAST *); virtual void visitSimpleDeclaration(SimpleDeclarationAST *); virtual void visitTemplateDeclaration(TemplateDeclarationAST *); virtual void visitTypedef(TypedefAST *); virtual void visitUsing(UsingAST *); virtual void visitUsingDirective(UsingDirectiveAST *); virtual void visitQProperty(QPropertyAST *); virtual void visitForwardDeclarationSpecifier(ForwardDeclarationSpecifierAST *); virtual void visitQEnums(QEnumsAST *); private: int decode_token(std::size_t index) const; const NameSymbol *decode_symbol(std::size_t index) const; CodeModel::AccessPolicy decode_access_policy(std::size_t index) const; CodeModel::ClassType decode_class_type(std::size_t index) const; CodeModel::FunctionType changeCurrentFunctionType(CodeModel::FunctionType functionType); CodeModel::AccessPolicy changeCurrentAccess(CodeModel::AccessPolicy accessPolicy); NamespaceModelItem changeCurrentNamespace(NamespaceModelItem item); ClassModelItem changeCurrentClass(ClassModelItem item); FunctionDefinitionModelItem changeCurrentFunction(FunctionDefinitionModelItem item); TemplateParameterList changeTemplateParameters(TemplateParameterList templateParameters); void declare_symbol(SimpleDeclarationAST *node, InitDeclaratorAST *init_declarator); void applyStorageSpecifiers(const ListNode *storage_specifiers, MemberModelItem item); void applyFunctionSpecifiers(const ListNode *it, FunctionModelItem item); void updateItemPosition(CodeModelItem item, AST *node); QString exceptionSpecToString(ExceptionSpecificationAST *exception_spec); private: CodeModel *_M_model; LocationManager &_M_location; TokenStream *_M_token_stream; Control *_M_control; CodeModel::FunctionType _M_current_function_type; CodeModel::AccessPolicy _M_current_access; FileModelItem _M_current_file; NamespaceModelItem _M_current_namespace; ClassModelItem _M_current_class; FunctionDefinitionModelItem _M_current_function; EnumModelItem _M_current_enum; QStringList _M_context; TemplateParameterList _M_current_template_parameters; // ### check me QHash _M_qualified_types; QHash _M_anonymous_enums; protected: TypeCompiler type_cc; NameCompiler name_cc; DeclaratorCompiler decl_cc; }; #endif // BINDER_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/class_compiler.cpp000066400000000000000000000043461170724227300250570ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "class_compiler.h" #include "lexer.h" #include "binder.h" ClassCompiler::ClassCompiler(Binder *binder) : _M_binder (binder), _M_token_stream(binder->tokenStream ()), name_cc(_M_binder), type_cc(_M_binder) { } ClassCompiler::~ClassCompiler() { } void ClassCompiler::run(ClassSpecifierAST *node) { name_cc.run(node->name); _M_name = name_cc.name(); _M_base_classes.clear(); visit(node); } void ClassCompiler::visitClassSpecifier(ClassSpecifierAST *node) { visit(node->base_clause); } void ClassCompiler::visitBaseSpecifier(BaseSpecifierAST *node) { name_cc.run(node->name); QString name = name_cc.name(); if (! name.isEmpty()) _M_base_classes.append(name); } // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/class_compiler.h000066400000000000000000000045321170724227300245210ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef CLASS_COMPILER_H #define CLASS_COMPILER_H #include #include #include "default_visitor.h" #include "name_compiler.h" #include "type_compiler.h" class TokenStream; class Binder; class ClassCompiler: protected DefaultVisitor { public: ClassCompiler(Binder *binder); virtual ~ClassCompiler(); inline QString name() const { return _M_name; } inline QStringList baseClasses() const { return _M_base_classes; } void run(ClassSpecifierAST *node); protected: virtual void visitClassSpecifier(ClassSpecifierAST *node); virtual void visitBaseSpecifier(BaseSpecifierAST *node); private: Binder *_M_binder; TokenStream *_M_token_stream; QString _M_name; QStringList _M_base_classes; NameCompiler name_cc; TypeCompiler type_cc; }; #endif // CLASS_COMPILER_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/codemodel.cpp000066400000000000000000000527341170724227300240170ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "codemodel.h" // --------------------------------------------------------------------------- CodeModel::CodeModel() : _M_creation_id(0) { _M_globalNamespace = create(); } CodeModel::~CodeModel() { } void CodeModel::wipeout() { _M_globalNamespace = create(); _M_files.clear(); } FileList CodeModel::files() const { return _M_files.values(); } NamespaceModelItem CodeModel::globalNamespace() const { return _M_globalNamespace; } void CodeModel::addFile(FileModelItem item) { _M_creation_id = 0; // reset the creation id _M_files.insert(item->name(), item); } void CodeModel::removeFile(FileModelItem item) { QHash::Iterator it = _M_files.find(item->name()); if (it != _M_files.end() && it.value() == item) _M_files.erase(it); } FileModelItem CodeModel::findFile(const QString &name) const { return _M_files.value(name); } QHash CodeModel::fileMap() const { return _M_files; } CodeModelItem CodeModel::findItem(const QStringList &qualifiedName, CodeModelItem scope) const { for (int i=0; i(scope)) { if (NamespaceModelItem tmp_ns = ns->findNamespace(name)) { scope = tmp_ns; continue; } } if (ScopeModelItem ss = model_dynamic_cast(scope)) { if (ClassModelItem cs = ss->findClass(name)) { scope = cs; } else if (EnumModelItem es = ss->findEnum(name)) { if (i == qualifiedName.size () - 1) return es->toItem(); } else if (TypeAliasModelItem tp = ss->findTypeAlias(name)) { if (i == qualifiedName.size () - 1) return tp->toItem (); } else { // If we don't find the name in the scope chain we // need to return an empty item to indicate failure... return CodeModelItem(); } } } return scope; } // --------------------------------------------------------------------------- TypeInfo TypeInfo::combine (const TypeInfo &__lhs, const TypeInfo &__rhs) { TypeInfo __result = __lhs; __result.setConstant (__result.isConstant () || __rhs.isConstant ()); __result.setVolatile (__result.isVolatile () || __rhs.isVolatile ()); __result.setReference (__result.isReference () || __rhs.isReference ()); __result.setIndirections (__result.indirections () + __rhs.indirections ()); __result.setArrayElements (__result.arrayElements () + __rhs.arrayElements ()); return __result; } TypeInfo TypeInfo::resolveType (TypeInfo const &__type, CodeModelItem __scope) { CodeModel *__model = __scope->model (); Q_ASSERT (__model != 0); CodeModelItem __item = __model->findItem (__type.qualifiedName (), __scope); // Copy the type and replace with the proper qualified name. This // only makes sence to do if we're actually getting a resolved // type with a namespace. We only get this if the returned type // has more than 2 entries in the qualified name... This test // could be improved by returning if the type was found or not. TypeInfo otherType(__type); if (__item && __item->qualifiedName().size() > 1) { otherType.setQualifiedName(__item->qualifiedName()); } if (TypeAliasModelItem __alias = model_dynamic_cast (__item)) return resolveType (TypeInfo::combine (__alias->type (), otherType), __scope); return otherType; } QString TypeInfo::toString() const { QString tmp; tmp += m_qualifiedName.join("::"); if (isConstant()) tmp += QLatin1String(" const"); if (isVolatile()) tmp += QLatin1String(" volatile"); if (indirections()) tmp += QString(indirections(), QLatin1Char('*')); if (isReference()) tmp += QLatin1Char('&'); if (isFunctionPointer()) { tmp += QLatin1String(" (*)("); for (int i=0; i(this)); } int _CodeModelItem::kind() const { return _M_kind; } void _CodeModelItem::setKind(int kind) { _M_kind = kind; } QStringList _CodeModelItem::qualifiedName() const { QStringList q = scope(); if (!name().isEmpty()) q += name(); return q; } QString _CodeModelItem::name() const { return _M_name; } void _CodeModelItem::setName(const QString &name) { _M_name = name; } QStringList _CodeModelItem::scope() const { return _M_scope; } void _CodeModelItem::setScope(const QStringList &scope) { _M_scope = scope; } QString _CodeModelItem::fileName() const { return _M_fileName; } void _CodeModelItem::setFileName(const QString &fileName) { _M_fileName = fileName; } FileModelItem _CodeModelItem::file() const { return model()->findFile(fileName()); } void _CodeModelItem::getStartPosition(int *line, int *column) { *line = _M_startLine; *column = _M_startColumn; } void _CodeModelItem::setStartPosition(int line, int column) { _M_startLine = line; _M_startColumn = column; } void _CodeModelItem::getEndPosition(int *line, int *column) { *line = _M_endLine; *column = _M_endColumn; } void _CodeModelItem::setEndPosition(int line, int column) { _M_endLine = line; _M_endColumn = column; } // --------------------------------------------------------------------------- QStringList _ClassModelItem::baseClasses() const { return _M_baseClasses; } void _ClassModelItem::setBaseClasses(const QStringList &baseClasses) { _M_baseClasses = baseClasses; } TemplateParameterList _ClassModelItem::templateParameters() const { return _M_templateParameters; } void _ClassModelItem::setTemplateParameters(const TemplateParameterList &templateParameters) { _M_templateParameters = templateParameters; } void _ClassModelItem::addBaseClass(const QString &baseClass) { _M_baseClasses.append(baseClass); } void _ClassModelItem::removeBaseClass(const QString &baseClass) { _M_baseClasses.removeAt(_M_baseClasses.indexOf(baseClass)); } bool _ClassModelItem::extendsClass(const QString &name) const { return _M_baseClasses.contains(name); } void _ClassModelItem::setClassType(CodeModel::ClassType type) { _M_classType = type; } CodeModel::ClassType _ClassModelItem::classType() const { return _M_classType; } void _ClassModelItem::addPropertyDeclaration(const QString &propertyDeclaration) { _M_propertyDeclarations << propertyDeclaration; } // --------------------------------------------------------------------------- FunctionModelItem _ScopeModelItem::declaredFunction(FunctionModelItem item) { FunctionList function_list = findFunctions(item->name()); foreach (FunctionModelItem fun, function_list) { if (fun->isSimilar(item)) return fun; } return FunctionModelItem(); } ClassList _ScopeModelItem::classes() const { return _M_classes.values(); } TypeAliasList _ScopeModelItem::typeAliases() const { return _M_typeAliases.values(); } VariableList _ScopeModelItem::variables() const { return _M_variables.values(); } FunctionList _ScopeModelItem::functions() const { return _M_functions.values(); } void _ScopeModelItem::addEnumsDeclaration(const QString &enumsDeclaration) { _M_enumsDeclarations << enumsDeclaration; } FunctionDefinitionList _ScopeModelItem::functionDefinitions() const { return _M_functionDefinitions.values(); } EnumList _ScopeModelItem::enums() const { return _M_enums.values(); } void _ScopeModelItem::addClass(ClassModelItem item) { QString name = item->name(); int idx = name.indexOf("<"); if (idx > 0) _M_classes.insert(name.left(idx), item); _M_classes.insert(name, item); } void _ScopeModelItem::addFunction(FunctionModelItem item) { _M_functions.insert(item->name(), item); } void _ScopeModelItem::addFunctionDefinition(FunctionDefinitionModelItem item) { _M_functionDefinitions.insert(item->name(), item); } void _ScopeModelItem::addVariable(VariableModelItem item) { _M_variables.insert(item->name(), item); } void _ScopeModelItem::addTypeAlias(TypeAliasModelItem item) { _M_typeAliases.insert(item->name(), item); } void _ScopeModelItem::addEnum(EnumModelItem item) { _M_enums.insert(item->name(), item); } void _ScopeModelItem::removeClass(ClassModelItem item) { QHash::Iterator it = _M_classes.find(item->name()); if (it != _M_classes.end() && it.value() == item) _M_classes.erase(it); } void _ScopeModelItem::removeFunction(FunctionModelItem item) { QMultiHash::Iterator it = _M_functions.find(item->name()); while (it != _M_functions.end() && it.key() == item->name() && it.value() != item) { ++it; } if (it != _M_functions.end() && it.value() == item) { _M_functions.erase(it); } } void _ScopeModelItem::removeFunctionDefinition(FunctionDefinitionModelItem item) { QMultiHash::Iterator it = _M_functionDefinitions.find(item->name()); while (it != _M_functionDefinitions.end() && it.key() == item->name() && it.value() != item) { ++it; } if (it != _M_functionDefinitions.end() && it.value() == item) { _M_functionDefinitions.erase(it); } } void _ScopeModelItem::removeVariable(VariableModelItem item) { QHash::Iterator it = _M_variables.find(item->name()); if (it != _M_variables.end() && it.value() == item) _M_variables.erase(it); } void _ScopeModelItem::removeTypeAlias(TypeAliasModelItem item) { QHash::Iterator it = _M_typeAliases.find(item->name()); if (it != _M_typeAliases.end() && it.value() == item) _M_typeAliases.erase(it); } void _ScopeModelItem::removeEnum(EnumModelItem item) { QHash::Iterator it = _M_enums.find(item->name()); if (it != _M_enums.end() && it.value() == item) _M_enums.erase(it); } ClassModelItem _ScopeModelItem::findClass(const QString &name) const { return _M_classes.value(name); } VariableModelItem _ScopeModelItem::findVariable(const QString &name) const { return _M_variables.value(name); } TypeAliasModelItem _ScopeModelItem::findTypeAlias(const QString &name) const { return _M_typeAliases.value(name); } EnumModelItem _ScopeModelItem::findEnum(const QString &name) const { return _M_enums.value(name); } FunctionList _ScopeModelItem::findFunctions(const QString &name) const { return _M_functions.values(name); } FunctionDefinitionList _ScopeModelItem::findFunctionDefinitions(const QString &name) const { return _M_functionDefinitions.values(name); } // --------------------------------------------------------------------------- NamespaceList _NamespaceModelItem::namespaces() const { return _M_namespaces.values(); } void _NamespaceModelItem::addNamespace(NamespaceModelItem item) { _M_namespaces.insert(item->name(), item); } void _NamespaceModelItem::removeNamespace(NamespaceModelItem item) { QHash::Iterator it = _M_namespaces.find(item->name()); if (it != _M_namespaces.end() && it.value() == item) _M_namespaces.erase(it); } NamespaceModelItem _NamespaceModelItem::findNamespace(const QString &name) const { return _M_namespaces.value(name); } // --------------------------------------------------------------------------- TypeInfo _ArgumentModelItem::type() const { return _M_type; } void _ArgumentModelItem::setType(const TypeInfo &type) { _M_type = type; } bool _ArgumentModelItem::defaultValue() const { return _M_defaultValue; } void _ArgumentModelItem::setDefaultValue(bool defaultValue) { _M_defaultValue = defaultValue; } // --------------------------------------------------------------------------- bool _FunctionModelItem::isSimilar(FunctionModelItem other) const { if (name() != other->name()) return false; if (isConstant() != other->isConstant()) return false; if (isVariadics() != other->isVariadics()) return false; if (arguments().count() != other->arguments().count()) return false; // ### check the template parameters for (int i=0; iarguments().at(i); if (arg1->type() != arg2->type()) return false; } return true; } ArgumentList _FunctionModelItem::arguments() const { return _M_arguments; } void _FunctionModelItem::addArgument(ArgumentModelItem item) { _M_arguments.append(item); } void _FunctionModelItem::removeArgument(ArgumentModelItem item) { _M_arguments.removeAt(_M_arguments.indexOf(item)); } CodeModel::FunctionType _FunctionModelItem::functionType() const { return _M_functionType; } void _FunctionModelItem::setFunctionType(CodeModel::FunctionType functionType) { _M_functionType = functionType; } QString _FunctionModelItem::exception() const { return _M_exception; } void _FunctionModelItem::setException(const QString &exception) { _M_exception = exception; } bool _FunctionModelItem::isVariadics() const { return _M_isVariadics; } void _FunctionModelItem::setVariadics(bool isVariadics) { _M_isVariadics = isVariadics; } bool _FunctionModelItem::isVirtual() const { return _M_isVirtual; } void _FunctionModelItem::setVirtual(bool isVirtual) { _M_isVirtual = isVirtual; } bool _FunctionModelItem::isInline() const { return _M_isInline; } void _FunctionModelItem::setInline(bool isInline) { _M_isInline = isInline; } bool _FunctionModelItem::isExplicit() const { return _M_isExplicit; } void _FunctionModelItem::setExplicit(bool isExplicit) { _M_isExplicit = isExplicit; } bool _FunctionModelItem::isAbstract() const { return _M_isAbstract; } void _FunctionModelItem::setAbstract(bool isAbstract) { _M_isAbstract = isAbstract; } // Qt bool _FunctionModelItem::isInvokable() const { return _M_isInvokable; } void _FunctionModelItem::setInvokable(bool isInvokable) { _M_isInvokable = isInvokable; } // --------------------------------------------------------------------------- TypeInfo _TypeAliasModelItem::type() const { return _M_type; } void _TypeAliasModelItem::setType(const TypeInfo &type) { _M_type = type; } // --------------------------------------------------------------------------- CodeModel::AccessPolicy _EnumModelItem::accessPolicy() const { return _M_accessPolicy; } void _EnumModelItem::setAccessPolicy(CodeModel::AccessPolicy accessPolicy) { _M_accessPolicy = accessPolicy; } EnumeratorList _EnumModelItem::enumerators() const { return _M_enumerators; } void _EnumModelItem::addEnumerator(EnumeratorModelItem item) { _M_enumerators.append(item); } void _EnumModelItem::removeEnumerator(EnumeratorModelItem item) { _M_enumerators.removeAt(_M_enumerators.indexOf(item)); } // --------------------------------------------------------------------------- QString _EnumeratorModelItem::value() const { return _M_value; } void _EnumeratorModelItem::setValue(const QString &value) { _M_value = value; } // --------------------------------------------------------------------------- TypeInfo _TemplateParameterModelItem::type() const { return _M_type; } void _TemplateParameterModelItem::setType(const TypeInfo &type) { _M_type = type; } bool _TemplateParameterModelItem::defaultValue() const { return _M_defaultValue; } void _TemplateParameterModelItem::setDefaultValue(bool defaultValue) { _M_defaultValue = defaultValue; } // --------------------------------------------------------------------------- ScopeModelItem _ScopeModelItem::create(CodeModel *model) { ScopeModelItem item(new _ScopeModelItem(model)); return item; } ClassModelItem _ClassModelItem::create(CodeModel *model) { ClassModelItem item(new _ClassModelItem(model)); return item; } NamespaceModelItem _NamespaceModelItem::create(CodeModel *model) { NamespaceModelItem item(new _NamespaceModelItem(model)); return item; } FileModelItem _FileModelItem::create(CodeModel *model) { FileModelItem item(new _FileModelItem(model)); return item; } ArgumentModelItem _ArgumentModelItem::create(CodeModel *model) { ArgumentModelItem item(new _ArgumentModelItem(model)); return item; } FunctionModelItem _FunctionModelItem::create(CodeModel *model) { FunctionModelItem item(new _FunctionModelItem(model)); return item; } FunctionDefinitionModelItem _FunctionDefinitionModelItem::create(CodeModel *model) { FunctionDefinitionModelItem item(new _FunctionDefinitionModelItem(model)); return item; } VariableModelItem _VariableModelItem::create(CodeModel *model) { VariableModelItem item(new _VariableModelItem(model)); return item; } TypeAliasModelItem _TypeAliasModelItem::create(CodeModel *model) { TypeAliasModelItem item(new _TypeAliasModelItem(model)); return item; } EnumModelItem _EnumModelItem::create(CodeModel *model) { EnumModelItem item(new _EnumModelItem(model)); return item; } EnumeratorModelItem _EnumeratorModelItem::create(CodeModel *model) { EnumeratorModelItem item(new _EnumeratorModelItem(model)); return item; } TemplateParameterModelItem _TemplateParameterModelItem::create(CodeModel *model) { TemplateParameterModelItem item(new _TemplateParameterModelItem(model)); return item; } // --------------------------------------------------------------------------- TypeInfo _MemberModelItem::type() const { return _M_type; } void _MemberModelItem::setType(const TypeInfo &type) { _M_type = type; } CodeModel::AccessPolicy _MemberModelItem::accessPolicy() const { return _M_accessPolicy; } void _MemberModelItem::setAccessPolicy(CodeModel::AccessPolicy accessPolicy) { _M_accessPolicy = accessPolicy; } bool _MemberModelItem::isStatic() const { return _M_isStatic; } void _MemberModelItem::setStatic(bool isStatic) { _M_isStatic = isStatic; } bool _MemberModelItem::isConstant() const { return _M_isConstant; } void _MemberModelItem::setConstant(bool isConstant) { _M_isConstant = isConstant; } bool _MemberModelItem::isVolatile() const { return _M_isVolatile; } void _MemberModelItem::setVolatile(bool isVolatile) { _M_isVolatile = isVolatile; } bool _MemberModelItem::isAuto() const { return _M_isAuto; } void _MemberModelItem::setAuto(bool isAuto) { _M_isAuto = isAuto; } bool _MemberModelItem::isFriend() const { return _M_isFriend; } void _MemberModelItem::setFriend(bool isFriend) { _M_isFriend = isFriend; } bool _MemberModelItem::isRegister() const { return _M_isRegister; } void _MemberModelItem::setRegister(bool isRegister) { _M_isRegister = isRegister; } bool _MemberModelItem::isExtern() const { return _M_isExtern; } void _MemberModelItem::setExtern(bool isExtern) { _M_isExtern = isExtern; } bool _MemberModelItem::isMutable() const { return _M_isMutable; } void _MemberModelItem::setMutable(bool isMutable) { _M_isMutable = isMutable; } // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/codemodel.h000066400000000000000000000473111170724227300234570ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef CODEMODEL_H #define CODEMODEL_H #include "codemodel_fwd.h" #include #include #include #include #include #include #define DECLARE_MODEL_NODE(k) \ enum { __node_kind = Kind_##k }; \ typedef CodeModelPointer Pointer; template _Target model_static_cast(_Source item) { typedef typename _Target::Type * _Target_pointer; _Target ptr (static_cast<_Target_pointer>(item.data())); return ptr; } class CodeModel { public: enum AccessPolicy { Public, Protected, Private }; enum FunctionType { Normal, Signal, Slot }; enum ClassType { Class, Struct, Union }; public: CodeModel(); virtual ~CodeModel(); template _Target create() { typedef typename _Target::Type _Target_type; _Target result = _Target_type::create(this); result->setCreationId(_M_creation_id++); return result; } FileList files() const; NamespaceModelItem globalNamespace() const; void addFile(FileModelItem item); void removeFile(FileModelItem item); FileModelItem findFile(const QString &name) const; QHash fileMap() const; CodeModelItem findItem(const QStringList &qualifiedName, CodeModelItem scope) const; void wipeout(); private: QHash _M_files; NamespaceModelItem _M_globalNamespace; std::size_t _M_creation_id; private: CodeModel(const CodeModel &other); void operator = (const CodeModel &other); }; class TypeInfo { public: TypeInfo(const TypeInfo &other) : flags(other.flags), m_qualifiedName(other.m_qualifiedName), m_arrayElements(other.m_arrayElements), m_arguments(other.m_arguments) { } TypeInfo(): flags (0) {} QStringList qualifiedName() const { return m_qualifiedName; } void setQualifiedName(const QStringList &qualified_name) { m_qualifiedName = qualified_name; } bool isConstant() const { return m_constant; } void setConstant(bool is) { m_constant = is; } bool isVolatile() const { return m_volatile; } void setVolatile(bool is) { m_volatile = is; } bool isReference() const { return m_reference; } void setReference(bool is) { m_reference = is; } int indirections() const { return m_indirections; } void setIndirections(int indirections) { m_indirections = indirections; } bool isFunctionPointer() const { return m_functionPointer; } void setFunctionPointer(bool is) { m_functionPointer = is; } QStringList arrayElements() const { return m_arrayElements; } void setArrayElements(const QStringList &arrayElements) { m_arrayElements = arrayElements; } QList arguments() const { return m_arguments; } void setArguments(const QList &arguments); void addArgument(const TypeInfo &arg) { m_arguments.append(arg); } bool operator==(const TypeInfo &other); bool operator!=(const TypeInfo &other) { return !(*this==other); } // ### arrays and templates?? QString toString() const; static TypeInfo combine (const TypeInfo &__lhs, const TypeInfo &__rhs); static TypeInfo resolveType (TypeInfo const &__type, CodeModelItem __scope); private: union { uint flags; struct { uint m_constant: 1; uint m_volatile: 1; uint m_reference: 1; uint m_functionPointer: 1; uint m_indirections: 6; uint m_padding: 22; }; }; QStringList m_qualifiedName; QStringList m_arrayElements; QList m_arguments; }; class _CodeModelItem: public QSharedData { public: enum Kind { /* These are bit-flags resembling inheritance */ Kind_Scope = 0x1, Kind_Namespace = 0x2 | Kind_Scope, Kind_Member = 0x4, Kind_Function = 0x8 | Kind_Member, KindMask = 0xf, /* These are for classes that are not inherited from */ FirstKind = 0x8, Kind_Argument = 1 << FirstKind, Kind_Class = 2 << FirstKind | Kind_Scope, Kind_Enum = 3 << FirstKind, Kind_Enumerator = 4 << FirstKind, Kind_File = 5 << FirstKind | Kind_Namespace, Kind_FunctionDefinition = 6 << FirstKind | Kind_Function, Kind_TemplateParameter = 7 << FirstKind, Kind_TypeAlias = 8 << FirstKind, Kind_Variable = 9 << FirstKind | Kind_Member }; public: virtual ~_CodeModelItem(); int kind() const; QStringList qualifiedName() const; QString name() const; void setName(const QString &name); QStringList scope() const; void setScope(const QStringList &scope); QString fileName() const; void setFileName(const QString &fileName); FileModelItem file() const; void getStartPosition(int *line, int *column); void setStartPosition(int line, int column); void getEndPosition(int *line, int *column); void setEndPosition(int line, int column); inline std::size_t creationId() const { return _M_creation_id; } inline void setCreationId(std::size_t creation_id) { _M_creation_id = creation_id; } inline CodeModel *model() const { return _M_model; } CodeModelItem toItem() const; protected: _CodeModelItem(CodeModel *model, int kind); void setKind(int kind); private: CodeModel *_M_model; int _M_kind; int _M_startLine; int _M_startColumn; int _M_endLine; int _M_endColumn; std::size_t _M_creation_id; QString _M_name; QString _M_fileName; QStringList _M_scope; private: _CodeModelItem(const _CodeModelItem &other); void operator = (const _CodeModelItem &other); }; class _ScopeModelItem: public _CodeModelItem { public: DECLARE_MODEL_NODE(Scope) static ScopeModelItem create(CodeModel *model); public: ClassList classes() const; EnumList enums() const; FunctionDefinitionList functionDefinitions() const; FunctionList functions() const; TypeAliasList typeAliases() const; VariableList variables() const; void addClass(ClassModelItem item); void addEnum(EnumModelItem item); void addFunction(FunctionModelItem item); void addFunctionDefinition(FunctionDefinitionModelItem item); void addTypeAlias(TypeAliasModelItem item); void addVariable(VariableModelItem item); void removeClass(ClassModelItem item); void removeEnum(EnumModelItem item); void removeFunction(FunctionModelItem item); void removeFunctionDefinition(FunctionDefinitionModelItem item); void removeTypeAlias(TypeAliasModelItem item); void removeVariable(VariableModelItem item); ClassModelItem findClass(const QString &name) const; EnumModelItem findEnum(const QString &name) const; FunctionDefinitionList findFunctionDefinitions(const QString &name) const; FunctionList findFunctions(const QString &name) const; TypeAliasModelItem findTypeAlias(const QString &name) const; VariableModelItem findVariable(const QString &name) const; void addEnumsDeclaration(const QString &enumsDeclaration); QStringList enumsDeclarations() const { return _M_enumsDeclarations; } inline QHash classMap() const { return _M_classes; } inline QHash enumMap() const { return _M_enums; } inline QHash typeAliasMap() const { return _M_typeAliases; } inline QHash variableMap() const { return _M_variables; } inline QMultiHash functionDefinitionMap() const { return _M_functionDefinitions; } inline QMultiHash functionMap() const { return _M_functions; } FunctionModelItem declaredFunction(FunctionModelItem item); protected: _ScopeModelItem(CodeModel *model, int kind = __node_kind) : _CodeModelItem(model, kind) {} private: QHash _M_classes; QHash _M_enums; QHash _M_typeAliases; QHash _M_variables; QMultiHash _M_functionDefinitions; QMultiHash _M_functions; private: _ScopeModelItem(const _ScopeModelItem &other); void operator = (const _ScopeModelItem &other); QStringList _M_enumsDeclarations; }; class _ClassModelItem: public _ScopeModelItem { public: DECLARE_MODEL_NODE(Class) static ClassModelItem create(CodeModel *model); public: QStringList baseClasses() const; void setBaseClasses(const QStringList &baseClasses); void addBaseClass(const QString &baseClass); void removeBaseClass(const QString &baseClass); TemplateParameterList templateParameters() const; void setTemplateParameters(const TemplateParameterList &templateParameters); bool extendsClass(const QString &name) const; void setClassType(CodeModel::ClassType type); CodeModel::ClassType classType() const; void addPropertyDeclaration(const QString &propertyDeclaration); QStringList propertyDeclarations() const { return _M_propertyDeclarations; } protected: _ClassModelItem(CodeModel *model, int kind = __node_kind) : _ScopeModelItem(model, kind), _M_classType(CodeModel::Class) {} private: QStringList _M_baseClasses; TemplateParameterList _M_templateParameters; CodeModel::ClassType _M_classType; QStringList _M_propertyDeclarations; private: _ClassModelItem(const _ClassModelItem &other); void operator = (const _ClassModelItem &other); }; class _NamespaceModelItem: public _ScopeModelItem { public: DECLARE_MODEL_NODE(Namespace) static NamespaceModelItem create(CodeModel *model); public: NamespaceList namespaces() const; void addNamespace(NamespaceModelItem item); void removeNamespace(NamespaceModelItem item); NamespaceModelItem findNamespace(const QString &name) const; inline QHash namespaceMap() const { return _M_namespaces; }; protected: _NamespaceModelItem(CodeModel *model, int kind = __node_kind) : _ScopeModelItem(model, kind) {} private: QHash _M_namespaces; private: _NamespaceModelItem(const _NamespaceModelItem &other); void operator = (const _NamespaceModelItem &other); }; class _FileModelItem: public _NamespaceModelItem { public: DECLARE_MODEL_NODE(File) static FileModelItem create(CodeModel *model); protected: _FileModelItem(CodeModel *model, int kind = __node_kind) : _NamespaceModelItem(model, kind) {} private: _FileModelItem(const _FileModelItem &other); void operator = (const _FileModelItem &other); }; class _ArgumentModelItem: public _CodeModelItem { public: DECLARE_MODEL_NODE(Argument) static ArgumentModelItem create(CodeModel *model); public: TypeInfo type() const; void setType(const TypeInfo &type); bool defaultValue() const; void setDefaultValue(bool defaultValue); QString defaultValueExpression() const { return _M_defaultValueExpression; } void setDefaultValueExpression(const QString &expr) { _M_defaultValueExpression = expr; } protected: _ArgumentModelItem(CodeModel *model, int kind = __node_kind) : _CodeModelItem(model, kind), _M_defaultValue(false) {} private: TypeInfo _M_type; QString _M_defaultValueExpression; bool _M_defaultValue; private: _ArgumentModelItem(const _ArgumentModelItem &other); void operator = (const _ArgumentModelItem &other); }; class _MemberModelItem: public _CodeModelItem { public: DECLARE_MODEL_NODE(Member) bool isConstant() const; void setConstant(bool isConstant); bool isVolatile() const; void setVolatile(bool isVolatile); bool isStatic() const; void setStatic(bool isStatic); bool isAuto() const; void setAuto(bool isAuto); bool isFriend() const; void setFriend(bool isFriend); bool isRegister() const; void setRegister(bool isRegister); bool isExtern() const; void setExtern(bool isExtern); bool isMutable() const; void setMutable(bool isMutable); CodeModel::AccessPolicy accessPolicy() const; void setAccessPolicy(CodeModel::AccessPolicy accessPolicy); TemplateParameterList templateParameters() const { return _M_templateParameters; } void setTemplateParameters(const TemplateParameterList &templateParameters) { _M_templateParameters = templateParameters; } TypeInfo type() const; void setType(const TypeInfo &type); protected: _MemberModelItem(CodeModel *model, int kind) : _CodeModelItem(model, kind), _M_accessPolicy(CodeModel::Public), _M_flags(0) {} private: TemplateParameterList _M_templateParameters; TypeInfo _M_type; CodeModel::AccessPolicy _M_accessPolicy; union { struct { uint _M_isConstant: 1; uint _M_isVolatile: 1; uint _M_isStatic: 1; uint _M_isAuto: 1; uint _M_isFriend: 1; uint _M_isRegister: 1; uint _M_isExtern: 1; uint _M_isMutable: 1; }; uint _M_flags; }; }; class _FunctionModelItem: public _MemberModelItem { public: DECLARE_MODEL_NODE(Function) static FunctionModelItem create(CodeModel *model); public: ArgumentList arguments() const; void addArgument(ArgumentModelItem item); void removeArgument(ArgumentModelItem item); CodeModel::FunctionType functionType() const; void setFunctionType(CodeModel::FunctionType functionType); QString exception() const; void setException(const QString &exception); bool isVirtual() const; void setVirtual(bool isVirtual); bool isInline() const; void setInline(bool isInline); bool isExplicit() const; void setExplicit(bool isExplicit); bool isInvokable() const; // Qt void setInvokable(bool isInvokable); // Qt bool isAbstract() const; void setAbstract(bool isAbstract); bool isVariadics() const; void setVariadics(bool isVariadics); bool isSimilar(FunctionModelItem other) const; protected: _FunctionModelItem(CodeModel *model, int kind = __node_kind) : _MemberModelItem(model, kind), _M_functionType(CodeModel::Normal), _M_flags(0) {} private: ArgumentList _M_arguments; CodeModel::FunctionType _M_functionType; QString _M_exception; union { struct { uint _M_isVirtual: 1; uint _M_isInline: 1; uint _M_isAbstract: 1; uint _M_isExplicit: 1; uint _M_isVariadics: 1; uint _M_isInvokable : 1; // Qt }; uint _M_flags; }; private: _FunctionModelItem(const _FunctionModelItem &other); void operator = (const _FunctionModelItem &other); }; class _FunctionDefinitionModelItem: public _FunctionModelItem { public: DECLARE_MODEL_NODE(FunctionDefinition) static FunctionDefinitionModelItem create(CodeModel *model); protected: _FunctionDefinitionModelItem(CodeModel *model, int kind = __node_kind) : _FunctionModelItem(model, kind) {} private: _FunctionDefinitionModelItem(const _FunctionDefinitionModelItem &other); void operator = (const _FunctionDefinitionModelItem &other); }; class _VariableModelItem: public _MemberModelItem { public: DECLARE_MODEL_NODE(Variable) static VariableModelItem create(CodeModel *model); protected: _VariableModelItem(CodeModel *model, int kind = __node_kind) : _MemberModelItem(model, kind) {} private: _VariableModelItem(const _VariableModelItem &other); void operator = (const _VariableModelItem &other); }; class _TypeAliasModelItem: public _CodeModelItem { public: DECLARE_MODEL_NODE(TypeAlias) static TypeAliasModelItem create(CodeModel *model); public: TypeInfo type() const; void setType(const TypeInfo &type); protected: _TypeAliasModelItem(CodeModel *model, int kind = __node_kind) : _CodeModelItem(model, kind) {} private: TypeInfo _M_type; private: _TypeAliasModelItem(const _TypeAliasModelItem &other); void operator = (const _TypeAliasModelItem &other); }; class _EnumModelItem: public _CodeModelItem { public: DECLARE_MODEL_NODE(Enum) static EnumModelItem create(CodeModel *model); public: CodeModel::AccessPolicy accessPolicy() const; void setAccessPolicy(CodeModel::AccessPolicy accessPolicy); EnumeratorList enumerators() const; void addEnumerator(EnumeratorModelItem item); void removeEnumerator(EnumeratorModelItem item); protected: _EnumModelItem(CodeModel *model, int kind = __node_kind) : _CodeModelItem(model, kind), _M_accessPolicy(CodeModel::Public) {} private: CodeModel::AccessPolicy _M_accessPolicy; EnumeratorList _M_enumerators; private: _EnumModelItem(const _EnumModelItem &other); void operator = (const _EnumModelItem &other); }; class _EnumeratorModelItem: public _CodeModelItem { public: DECLARE_MODEL_NODE(Enumerator) static EnumeratorModelItem create(CodeModel *model); public: QString value() const; void setValue(const QString &value); protected: _EnumeratorModelItem(CodeModel *model, int kind = __node_kind) : _CodeModelItem(model, kind) {} private: QString _M_value; private: _EnumeratorModelItem(const _EnumeratorModelItem &other); void operator = (const _EnumeratorModelItem &other); }; class _TemplateParameterModelItem: public _CodeModelItem { public: DECLARE_MODEL_NODE(TemplateParameter) static TemplateParameterModelItem create(CodeModel *model); public: TypeInfo type() const; void setType(const TypeInfo &type); bool defaultValue() const; void setDefaultValue(bool defaultValue); protected: _TemplateParameterModelItem(CodeModel *model, int kind = __node_kind) : _CodeModelItem(model, kind), _M_defaultValue(false) {} private: TypeInfo _M_type; bool _M_defaultValue; private: _TemplateParameterModelItem(const _TemplateParameterModelItem &other); void operator = (const _TemplateParameterModelItem &other); }; template _Target model_safe_cast(_Source item) { typedef typename _Target::Type * _Target_pointer; typedef typename _Source::Type * _Source_pointer; _Source_pointer source = item.data(); if (source && source->kind() == _Target_pointer(0)->__node_kind) { _Target ptr(static_cast<_Target_pointer>(source)); return ptr; } return _Target(); } template _Target model_dynamic_cast(_Source item) { typedef typename _Target::Type * _Target_pointer; typedef typename _Source::Type * _Source_pointer; _Source_pointer source = item.data(); if (source && (source->kind() == _Target_pointer(0)->__node_kind || (int(_Target_pointer(0)->__node_kind) <= int(_CodeModelItem::KindMask) && ((source->kind() & _Target_pointer(0)->__node_kind) == _Target_pointer(0)->__node_kind)))) { _Target ptr(static_cast<_Target_pointer>(source)); return ptr; } return _Target(); } #endif // CODEMODEL_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/codemodel_finder.cpp000066400000000000000000000065361170724227300253450ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "codemodel_finder.h" #include "codemodel.h" #include "binder.h" CodeModelFinder::CodeModelFinder(CodeModel *model, Binder *binder) : _M_model(model), _M_binder (binder), _M_token_stream(binder->tokenStream ()), name_cc(_M_binder), _M_resolve_policy(ResolveItem) { } CodeModelFinder::~CodeModelFinder() { } ScopeModelItem CodeModelFinder::resolveScope(NameAST *name, ScopeModelItem scope) { Q_ASSERT(scope != 0); ResolvePolicy saved_resolve_policy = _M_resolve_policy; _M_resolve_policy = ResolveScope; ScopeModelItem old = changeCurrentScope(scope); visit(name); ScopeModelItem result = _M_current_scope; changeCurrentScope(old); // restore _M_resolve_policy = saved_resolve_policy; return result; } ScopeModelItem CodeModelFinder::changeCurrentScope(ScopeModelItem scope) { ScopeModelItem old = _M_current_scope; _M_current_scope = scope; return old; } void CodeModelFinder::visitName(NameAST *node) { visitNodes(this, node->qualified_names); if (_M_resolve_policy == ResolveItem) visit(node->unqualified_name); } void CodeModelFinder::visitUnqualifiedName(UnqualifiedNameAST *node) { if (!_M_current_scope) { // nothing to do return; } name_cc.run(node); QString id = name_cc.name(); if (ClassModelItem klass = _M_current_scope->findClass(id)) { _M_current_scope = klass; } else if (NamespaceModelItem parentNamespace = model_safe_cast(_M_current_scope)) { NamespaceModelItem ns = parentNamespace->findNamespace(id); _M_current_scope = model_static_cast(ns); } else if (FileModelItem file = model_safe_cast(_M_current_scope)) { NamespaceModelItem ns = file->findNamespace(id); _M_current_scope = model_static_cast(ns); } } // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/codemodel_finder.h000066400000000000000000000046351170724227300250100ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef CODEMODEL_FINDER_H #define CODEMODEL_FINDER_H #include "default_visitor.h" #include "codemodel_fwd.h" #include "name_compiler.h" class TokenStream; class Binder; class CodeModelFinder: protected DefaultVisitor { enum ResolvePolicy { ResolveScope, ResolveItem }; public: CodeModelFinder(CodeModel *model, Binder *binder); virtual ~CodeModelFinder(); ScopeModelItem resolveScope(NameAST *name, ScopeModelItem scope); inline CodeModel *model() const { return _M_model; } protected: virtual void visitName(NameAST *node); virtual void visitUnqualifiedName(UnqualifiedNameAST *node); ScopeModelItem changeCurrentScope(ScopeModelItem scope); private: CodeModel *_M_model; Binder *_M_binder; TokenStream *_M_token_stream; NameCompiler name_cc; ScopeModelItem _M_current_scope; ResolvePolicy _M_resolve_policy; }; #endif // CODEMODEL_FINDER_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/codemodel_fwd.h000066400000000000000000000070571170724227300243220ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef CODEMODEL_FWD_H #define CODEMODEL_FWD_H #include #include // forward declarations class CodeModel; class _ArgumentModelItem; class _ClassModelItem; class _CodeModelItem; class _EnumModelItem; class _EnumeratorModelItem; class _FileModelItem; class _FunctionDefinitionModelItem; class _FunctionModelItem; class _NamespaceModelItem; class _ScopeModelItem; class _TemplateParameterModelItem; class _TypeAliasModelItem; class _VariableModelItem; class _MemberModelItem; class TypeInfo; typedef CodeModelPointer<_ArgumentModelItem> ArgumentModelItem; typedef CodeModelPointer<_ClassModelItem> ClassModelItem; typedef CodeModelPointer<_CodeModelItem> CodeModelItem; typedef CodeModelPointer<_EnumModelItem> EnumModelItem; typedef CodeModelPointer<_EnumeratorModelItem> EnumeratorModelItem; typedef CodeModelPointer<_FileModelItem> FileModelItem; typedef CodeModelPointer<_FunctionDefinitionModelItem> FunctionDefinitionModelItem; typedef CodeModelPointer<_FunctionModelItem> FunctionModelItem; typedef CodeModelPointer<_NamespaceModelItem> NamespaceModelItem; typedef CodeModelPointer<_ScopeModelItem> ScopeModelItem; typedef CodeModelPointer<_TemplateParameterModelItem> TemplateParameterModelItem; typedef CodeModelPointer<_TypeAliasModelItem> TypeAliasModelItem; typedef CodeModelPointer<_VariableModelItem> VariableModelItem; typedef CodeModelPointer<_MemberModelItem> MemberModelItem; typedef QList ArgumentList; typedef QList ClassList; typedef QList ItemList; typedef QList EnumList; typedef QList EnumeratorList; typedef QList FileList; typedef QList FunctionDefinitionList; typedef QList FunctionList; typedef QList NamespaceList; typedef QList ScopeList; typedef QList TemplateParameterList; typedef QList TypeAliasList; typedef QList VariableList; typedef QList MemberList; #endif // CODEMODEL_FWD_H qtscriptgenerator-src-0.2.0/generator/parser/codemodel_pointer.h000066400000000000000000000101551170724227300252130ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef CODEMODEL_POINTER_H #define CODEMODEL_POINTER_H #include // Since the atomic API changed in 4.4 we need to hack a little here // to make it work with both 4.3 and 4.4 until that is not required #if QT_VERSION >= 0x040400 # include template class CodeModelPointer: public QAtomicPointer #else template class CodeModelPointer #endif // QT_VERSION >= 0x040400 { public: typedef T Type; #if QT_VERSION < 0x040400 inline T &operator*() { return *d; } inline const T &operator*() const { return *d; } inline T *operator->() { return d; } inline const T *operator->() const { return d; } inline operator T *() { return d; } inline operator const T *() const { return d; } inline T *data() { return d; } inline const T *data() const { return d; } inline const T *constData() const { return d; } inline bool operator==(const CodeModelPointer &other) const { return d == other.d; } inline bool operator!=(const CodeModelPointer &other) const { return d != other.d; } inline bool operator==(const T *ptr) const { return d == ptr; } inline bool operator!=(const T *ptr) const { return d != ptr; } inline CodeModelPointer() { d = 0; } inline ~CodeModelPointer() { if (d && !d->ref.deref()) delete d; } explicit CodeModelPointer(T *data); inline CodeModelPointer(const CodeModelPointer &o) : d(o.d) { if (d) d->ref.ref(); } inline CodeModelPointer & operator=(const CodeModelPointer &o) { if (o.d != d) { T *x = o.d; if (x) x->ref.ref(); x = qAtomicSetPtr(&d, x); if (x && !x->ref.deref()) delete x; } return *this; } inline CodeModelPointer &operator=(T *o) { if (o != d) { T *x = o; if (x) x->ref.ref(); x = qAtomicSetPtr(&d, x); if (x && !x->ref.deref()) delete x; } return *this; } inline bool operator!() const { return !d; } private: T *d; #else // QT_VERSION < 0x040400 inline CodeModelPointer(T *value = 0) : QAtomicPointer(value) {} inline CodeModelPointer &operator=(T *o) { QAtomicPointer::operator=(o); return *this; } inline T *data() { return (T *) *this; } inline const T *data() const { return (const T *) *this; } inline const T *constData() const { return (const T *) *this; } #endif }; #if QT_VERSION < 0x040400 template Q_INLINE_TEMPLATE CodeModelPointer::CodeModelPointer(T *adata) : d(adata) { if (d) d->ref.ref(); } #endif #endif // CODEMODEL_POINTER_H qtscriptgenerator-src-0.2.0/generator/parser/compiler_utils.cpp000066400000000000000000000044271170724227300251120ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "compiler_utils.h" #include "type_compiler.h" #include "name_compiler.h" #include "declarator_compiler.h" #include "ast.h" #include "binder.h" TypeInfo CompilerUtils::typeDescription(TypeSpecifierAST *type_specifier, DeclaratorAST *declarator, Binder *binder) { TypeCompiler type_cc (binder); DeclaratorCompiler decl_cc (binder); type_cc.run (type_specifier); decl_cc.run (declarator); TypeInfo typeInfo; typeInfo.setQualifiedName (type_cc.qualifiedName ()); typeInfo.setConstant (type_cc.isConstant ()); typeInfo.setVolatile (type_cc.isVolatile ()); typeInfo.setReference (decl_cc.isReference ()); typeInfo.setIndirections (decl_cc.indirection ()); typeInfo.setArrayElements (decl_cc.arrayElements ()); return typeInfo; } // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/compiler_utils.h000066400000000000000000000036551170724227300245610ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef COMPILER_UTILS_H #define COMPILER_UTILS_H #include #include "codemodel.h" class QString; class QStringList; struct TypeSpecifierAST; struct DeclaratorAST; class TokenStream; class Binder; namespace CompilerUtils { TypeInfo typeDescription(TypeSpecifierAST *type_specifier, DeclaratorAST *declarator, Binder *binder); } // namespace CompilerUtils #endif // COMPILER_UTILS_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/control.cpp000066400000000000000000000067211170724227300235370ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "control.h" #include "lexer.h" Control::Control() : current_context(0), _M_skipFunctionBody(false), _M_lexer(0), _M_parser(0) { pushContext(); declareTypedef(findOrInsertName("__builtin_va_list", strlen("__builtin_va_list")), 0); } Control::~Control() { popContext(); Q_ASSERT(current_context == 0); } Lexer *Control::changeLexer(Lexer *lexer) { Lexer *old = _M_lexer; _M_lexer = lexer; return old; } Parser *Control::changeParser(Parser *parser) { Parser *old = _M_parser; _M_parser = parser; return old; } Type *Control::lookupType(const NameSymbol *name) const { Q_ASSERT(current_context != 0); return current_context->resolve(name); } void Control::declare(const NameSymbol *name, Type *type) { //printf("*** Declare:"); //printSymbol(name); //putchar('\n'); Q_ASSERT(current_context != 0); current_context->bind(name, type); } void Control::pushContext() { // printf("+Context\n"); Context *new_context = new Context; new_context->parent = current_context; current_context = new_context; } void Control::popContext() { // printf("-Context\n"); Q_ASSERT(current_context != 0); Context *old_context = current_context; current_context = current_context->parent; delete old_context; } void Control::declareTypedef(const NameSymbol *name, Declarator *d) { // printf("declared typedef:"); // printSymbol(name); // printf("\n"); stl_typedef_table.insert(name, d); } bool Control::isTypedef(const NameSymbol *name) const { // printf("is typedef:"); // printSymbol(name); // printf("= %d\n", (stl_typedef_table.find(name) != stl_typedef_table.end())); return stl_typedef_table.contains(name); } QList Control::errorMessages () const { return _M_error_messages; } void Control::clearErrorMessages () { _M_error_messages.clear (); } void Control::reportError (const ErrorMessage &errmsg) { _M_error_messages.append(errmsg); } // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/control.h000066400000000000000000000077731170724227300232140ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef CONTROL_H #define CONTROL_H #include "symbol.h" #include "smallobject.h" #include struct Declarator; struct Type; class Lexer; class Parser; struct Context { Context *parent; inline void bind(const NameSymbol *name, Type *type) { symbol_table.insert(name, type); } inline Type *resolve(const NameSymbol *name) const { if (Type *type = symbol_table.value(name)) return type; else if (parent) return parent->resolve(name); return 0; } typedef QHash symbol_table_t; symbol_table_t symbol_table; }; class Control { public: class ErrorMessage { public: ErrorMessage (): _M_line (0), _M_column (0) {} inline int line () const { return _M_line; } inline void setLine (int line) { _M_line = line; } inline int column () const { return _M_column; } inline void setColumn (int column) { _M_column = column; } inline QString fileName () const { return _M_fileName; } inline void setFileName (const QString &fileName) { _M_fileName = fileName; } inline QString message () const { return _M_message; } inline void setMessage (const QString &message) { _M_message = message; } private: int _M_line; int _M_column; QString _M_fileName; QString _M_message; }; Control(); ~Control(); inline bool skipFunctionBody() const { return _M_skipFunctionBody; } inline void setSkipFunctionBody(bool skip) { _M_skipFunctionBody = skip; } Lexer *changeLexer(Lexer *lexer); Parser *changeParser(Parser *parser); Lexer *currentLexer() const { return _M_lexer; } Parser *currentParser() const { return _M_parser; } Context *current_context; inline Context *currentContext() const { return current_context; } void pushContext(); void popContext(); Type *lookupType(const NameSymbol *name) const; void declare(const NameSymbol *name, Type *type); inline const NameSymbol *findOrInsertName(const char *data, size_t count) { return name_table.findOrInsert(data, count); } void declareTypedef(const NameSymbol *name, Declarator *d); bool isTypedef(const NameSymbol *name) const; void reportError (const ErrorMessage &errmsg); QList errorMessages () const; void clearErrorMessages (); private: NameTable name_table; QHash stl_typedef_table; bool _M_skipFunctionBody; Lexer *_M_lexer; Parser *_M_parser; QList _M_error_messages; }; #endif // CONTROL_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/declarator_compiler.cpp000066400000000000000000000116301170724227300260640ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "declarator_compiler.h" #include "name_compiler.h" #include "type_compiler.h" #include "compiler_utils.h" #include "lexer.h" #include "binder.h" #include "tokens.h" #include DeclaratorCompiler::DeclaratorCompiler(Binder *binder) : _M_binder (binder), _M_token_stream (binder->tokenStream ()) { } void DeclaratorCompiler::run(DeclaratorAST *node) { _M_id.clear(); _M_parameters.clear(); _M_array.clear(); _M_function = false; _M_reference = false; _M_variadics = false; _M_indirection = 0; if (node) { NameCompiler name_cc(_M_binder); DeclaratorAST *decl = node; while (decl && decl->sub_declarator) decl = decl->sub_declarator; Q_ASSERT (decl != 0); name_cc.run(decl->id); _M_id = name_cc.name(); _M_function = (node->parameter_declaration_clause != 0); if (node->parameter_declaration_clause && node->parameter_declaration_clause->ellipsis) _M_variadics = true; visitNodes(this, node->ptr_ops); visit(node->parameter_declaration_clause); if (const ListNode *it = node->array_dimensions) { it->toFront(); const ListNode *end = it; do { QString elt; if (ExpressionAST *expr = it->element) { const Token &start_token = _M_token_stream->token((int) expr->start_token); const Token &end_token = _M_token_stream->token((int) expr->end_token); elt += QString::fromUtf8(&start_token.text[start_token.position], (int) (end_token.position - start_token.position)).trimmed(); } _M_array.append (elt); it = it->next; } while (it != end); } } } void DeclaratorCompiler::visitPtrOperator(PtrOperatorAST *node) { std::size_t op = _M_token_stream->kind(node->op); switch (op) { case '&': _M_reference = true; break; case '*': ++_M_indirection; break; default: break; } if (node->mem_ptr) { #if defined(__GNUC__) #warning "ptr to mem -- not implemented" #endif } } void DeclaratorCompiler::visitParameterDeclaration(ParameterDeclarationAST *node) { Parameter p; TypeCompiler type_cc(_M_binder); DeclaratorCompiler decl_cc(_M_binder); decl_cc.run(node->declarator); p.name = decl_cc.id(); p.type = CompilerUtils::typeDescription(node->type_specifier, node->declarator, _M_binder); // ignore case a single void parameter if (_M_parameters.isEmpty() && p.name.isEmpty() && p.type.toString() == "void") { return; } if (node->expression != 0) { const Token &start = _M_token_stream->token((int) node->expression->start_token); const Token &end = _M_token_stream->token((int) node->expression->end_token); int length = (int) (end.position - start.position); p.defaultValueExpression = QString(); QString source = QString::fromUtf8(&start.text[start.position], length).trimmed(); QStringList list = source.split("\n"); for (int i=0; i 0; } _M_parameters.append(p); } // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/declarator_compiler.h000066400000000000000000000055111170724227300255320ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef DECLARATOR_COMPILER_H #define DECLARATOR_COMPILER_H #include "default_visitor.h" #include "codemodel.h" #include #include class TokenStream; class Binder; class DeclaratorCompiler: protected DefaultVisitor { public: struct Parameter { TypeInfo type; QString name; QString defaultValueExpression; bool defaultValue; Parameter(): defaultValue(false) {} }; public: DeclaratorCompiler(Binder *binder); void run(DeclaratorAST *node); inline QString id() const { return _M_id; } inline QStringList arrayElements() const { return _M_array; } inline bool isFunction() const { return _M_function; } inline bool isVariadics() const { return _M_variadics; } inline bool isReference() const { return _M_reference; } inline int indirection() const { return _M_indirection; } inline QList parameters() const { return _M_parameters; } protected: virtual void visitPtrOperator(PtrOperatorAST *node); virtual void visitParameterDeclaration(ParameterDeclarationAST *node); private: Binder *_M_binder; TokenStream *_M_token_stream; bool _M_function; bool _M_reference; bool _M_variadics; int _M_indirection; QString _M_id; QStringList _M_array; QList _M_parameters; }; #endif // DECLARATOR_COMPILER_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/default_visitor.cpp000066400000000000000000000253121170724227300252570ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "default_visitor.h" void DefaultVisitor::visitAccessSpecifier(AccessSpecifierAST *) { // nothing to do } void DefaultVisitor::visitAsmDefinition(AsmDefinitionAST *) { // nothing to do } void DefaultVisitor::visitBaseClause(BaseClauseAST *node) { visitNodes(this, node->base_specifiers); } void DefaultVisitor::visitBaseSpecifier(BaseSpecifierAST *node) { visit(node->name); } void DefaultVisitor::visitBinaryExpression(BinaryExpressionAST *node) { visit(node->left_expression); visit(node->right_expression); } void DefaultVisitor::visitCastExpression(CastExpressionAST *node) { visit(node->type_id); visit(node->expression); } void DefaultVisitor::visitClassMemberAccess(ClassMemberAccessAST *node) { visit(node->name); } void DefaultVisitor::visitClassSpecifier(ClassSpecifierAST *node) { visit(node->win_decl_specifiers); visit(node->name); visit(node->base_clause); visitNodes(this, node->member_specs); } void DefaultVisitor::visitCompoundStatement(CompoundStatementAST *node) { visitNodes(this, node->statements); } void DefaultVisitor::visitCondition(ConditionAST *node) { visit(node->type_specifier); visit(node->declarator); visit(node->expression); } void DefaultVisitor::visitConditionalExpression(ConditionalExpressionAST *node) { visit(node->condition); visit(node->left_expression); visit(node->right_expression); } void DefaultVisitor::visitCppCastExpression(CppCastExpressionAST *node) { visit(node->type_id); visit(node->expression); visitNodes(this, node->sub_expressions); } void DefaultVisitor::visitCtorInitializer(CtorInitializerAST *node) { visitNodes(this, node->member_initializers); } void DefaultVisitor::visitDeclarationStatement(DeclarationStatementAST *node) { visit(node->declaration); } void DefaultVisitor::visitDeclarator(DeclaratorAST *node) { visit(node->sub_declarator); visitNodes(this, node->ptr_ops); visit(node->id); visit(node->bit_expression); visitNodes(this, node->array_dimensions); visit(node->parameter_declaration_clause); visit(node->exception_spec); } void DefaultVisitor::visitDeleteExpression(DeleteExpressionAST *node) { visit(node->expression); } void DefaultVisitor::visitDoStatement(DoStatementAST *node) { visit(node->statement); visit(node->expression); } void DefaultVisitor::visitElaboratedTypeSpecifier(ElaboratedTypeSpecifierAST *node) { visit(node->name); } void DefaultVisitor::visitEnumSpecifier(EnumSpecifierAST *node) { visit(node->name); visitNodes(this, node->enumerators); } void DefaultVisitor::visitEnumerator(EnumeratorAST *node) { visit(node->expression); } void DefaultVisitor::visitExceptionSpecification(ExceptionSpecificationAST *node) { visitNodes(this, node->type_ids); } void DefaultVisitor::visitExpressionOrDeclarationStatement(ExpressionOrDeclarationStatementAST *node) { visit(node->expression); visit(node->declaration); } void DefaultVisitor::visitExpressionStatement(ExpressionStatementAST *node) { visit(node->expression); } void DefaultVisitor::visitForStatement(ForStatementAST *node) { visit(node->init_statement); visit(node->condition); visit(node->expression); visit(node->statement); } void DefaultVisitor::visitFunctionCall(FunctionCallAST *node) { visit(node->arguments); } void DefaultVisitor::visitFunctionDefinition(FunctionDefinitionAST *node) { visit(node->type_specifier); visit(node->init_declarator); visit(node->function_body); visit(node->win_decl_specifiers); } void DefaultVisitor::visitIfStatement(IfStatementAST *node) { visit(node->condition); visit(node->statement); visit(node->else_statement); } void DefaultVisitor::visitIncrDecrExpression(IncrDecrExpressionAST *) { // nothing to do } void DefaultVisitor::visitInitDeclarator(InitDeclaratorAST *node) { visit(node->declarator); visit(node->initializer); } void DefaultVisitor::visitInitializer(InitializerAST *node) { visit(node->initializer_clause); visit(node->expression); } void DefaultVisitor::visitInitializerClause(InitializerClauseAST *node) { visit(node->expression); } void DefaultVisitor::visitLabeledStatement(LabeledStatementAST *) { // nothing to do } void DefaultVisitor::visitLinkageBody(LinkageBodyAST *node) { visitNodes(this, node->declarations); } void DefaultVisitor::visitLinkageSpecification(LinkageSpecificationAST *node) { visit(node->linkage_body); visit(node->declaration); } void DefaultVisitor::visitMemInitializer(MemInitializerAST *node) { visit(node->initializer_id); visit(node->expression); } void DefaultVisitor::visitName(NameAST *node) { visitNodes(this, node->qualified_names); visit(node->unqualified_name); } void DefaultVisitor::visitNamespace(NamespaceAST *node) { visit(node->linkage_body); } void DefaultVisitor::visitNamespaceAliasDefinition(NamespaceAliasDefinitionAST *node) { visit(node->alias_name); } void DefaultVisitor::visitNewDeclarator(NewDeclaratorAST *node) { visit(node->ptr_op); visit(node->sub_declarator); visitNodes(this, node->expressions); } void DefaultVisitor::visitNewExpression(NewExpressionAST *node) { visit(node->expression); visit(node->type_id); visit(node->new_type_id); visit(node->new_initializer); } void DefaultVisitor::visitNewInitializer(NewInitializerAST *node) { visit(node->expression); } void DefaultVisitor::visitNewTypeId(NewTypeIdAST *node) { visit(node->type_specifier); visit(node->new_initializer); visit(node->new_declarator); } void DefaultVisitor::visitOperator(OperatorAST *) { // nothing to do } void DefaultVisitor::visitOperatorFunctionId(OperatorFunctionIdAST *node) { visit(node->op); visit(node->type_specifier); visitNodes(this, node->ptr_ops); } void DefaultVisitor::visitParameterDeclaration(ParameterDeclarationAST *node) { visit(node->type_specifier); visit(node->declarator); visit(node->expression); } void DefaultVisitor::visitParameterDeclarationClause(ParameterDeclarationClauseAST *node) { visitNodes(this, node->parameter_declarations); } void DefaultVisitor::visitPostfixExpression(PostfixExpressionAST *node) { visit(node->type_specifier); visit(node->expression); visitNodes(this, node->sub_expressions); } void DefaultVisitor::visitPrimaryExpression(PrimaryExpressionAST *node) { visit(node->literal); visit(node->expression_statement); visit(node->sub_expression); visit(node->name); } void DefaultVisitor::visitPtrOperator(PtrOperatorAST *node) { visit(node->mem_ptr); } void DefaultVisitor::visitPtrToMember(PtrToMemberAST *) { // nothing to do } void DefaultVisitor::visitReturnStatement(ReturnStatementAST *node) { visit(node->expression); } void DefaultVisitor::visitSimpleDeclaration(SimpleDeclarationAST *node) { visit(node->type_specifier); visitNodes(this, node->init_declarators); visit(node->win_decl_specifiers); } void DefaultVisitor::visitSimpleTypeSpecifier(SimpleTypeSpecifierAST *node) { visit(node->name); visit(node->type_id); visit(node->expression); } void DefaultVisitor::visitSizeofExpression(SizeofExpressionAST *node) { visit(node->type_id); visit(node->expression); } void DefaultVisitor::visitStringLiteral(StringLiteralAST *) { // nothing to do } void DefaultVisitor::visitSubscriptExpression(SubscriptExpressionAST *node) { visit(node->subscript); } void DefaultVisitor::visitSwitchStatement(SwitchStatementAST *node) { visit(node->condition); visit(node->statement); } void DefaultVisitor::visitTemplateArgument(TemplateArgumentAST *node) { visit(node->type_id); visit(node->expression); } void DefaultVisitor::visitTemplateDeclaration(TemplateDeclarationAST *node) { visitNodes(this, node->template_parameters); visit(node->declaration); } void DefaultVisitor::visitTemplateParameter(TemplateParameterAST *node) { visit(node->type_parameter); visit(node->parameter_declaration); } void DefaultVisitor::visitThrowExpression(ThrowExpressionAST *node) { visit(node->expression); } void DefaultVisitor::visitTranslationUnit(TranslationUnitAST *node) { visitNodes(this, node->declarations); } void DefaultVisitor::visitTryBlockStatement(TryBlockStatementAST *) { // nothing to do } void DefaultVisitor::visitTypeId(TypeIdAST *node) { visit(node->type_specifier); visit(node->declarator); } void DefaultVisitor::visitTypeIdentification(TypeIdentificationAST *node) { visit(node->name); visit(node->expression); } void DefaultVisitor::visitTypeParameter(TypeParameterAST *node) { visit(node->name); visit(node->type_id); visitNodes(this, node->template_parameters); visit(node->template_name); } void DefaultVisitor::visitTypedef(TypedefAST *node) { visit(node->type_specifier); visitNodes(this, node->init_declarators); } void DefaultVisitor::visitUnaryExpression(UnaryExpressionAST *node) { visit(node->expression); } void DefaultVisitor::visitUnqualifiedName(UnqualifiedNameAST *node) { visit(node->operator_id); visitNodes(this, node->template_arguments); } void DefaultVisitor::visitUsing(UsingAST *node) { visit(node->name); } void DefaultVisitor::visitUsingDirective(UsingDirectiveAST *node) { visit(node->name); } void DefaultVisitor::visitWhileStatement(WhileStatementAST *node) { visit(node->condition); visit(node->statement); } void DefaultVisitor::visitWinDeclSpec(WinDeclSpecAST *) { // nothing to do } // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/default_visitor.h000066400000000000000000000137661170724227300247360ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef DEFAULT_VISITOR_H #define DEFAULT_VISITOR_H #include "visitor.h" class DefaultVisitor: public Visitor { public: DefaultVisitor() {} protected: virtual void visitAccessSpecifier(AccessSpecifierAST *); virtual void visitAsmDefinition(AsmDefinitionAST *); virtual void visitBaseClause(BaseClauseAST *); virtual void visitBaseSpecifier(BaseSpecifierAST *); virtual void visitBinaryExpression(BinaryExpressionAST *); virtual void visitCastExpression(CastExpressionAST *); virtual void visitClassMemberAccess(ClassMemberAccessAST *); virtual void visitClassSpecifier(ClassSpecifierAST *); virtual void visitCompoundStatement(CompoundStatementAST *); virtual void visitCondition(ConditionAST *); virtual void visitConditionalExpression(ConditionalExpressionAST *); virtual void visitCppCastExpression(CppCastExpressionAST *); virtual void visitCtorInitializer(CtorInitializerAST *); virtual void visitDeclarationStatement(DeclarationStatementAST *); virtual void visitDeclarator(DeclaratorAST *); virtual void visitDeleteExpression(DeleteExpressionAST *); virtual void visitDoStatement(DoStatementAST *); virtual void visitElaboratedTypeSpecifier(ElaboratedTypeSpecifierAST *); virtual void visitEnumSpecifier(EnumSpecifierAST *); virtual void visitEnumerator(EnumeratorAST *); virtual void visitExceptionSpecification(ExceptionSpecificationAST *); virtual void visitExpressionOrDeclarationStatement(ExpressionOrDeclarationStatementAST *); virtual void visitExpressionStatement(ExpressionStatementAST *); virtual void visitForStatement(ForStatementAST *); virtual void visitFunctionCall(FunctionCallAST *); virtual void visitFunctionDefinition(FunctionDefinitionAST *); virtual void visitIfStatement(IfStatementAST *); virtual void visitIncrDecrExpression(IncrDecrExpressionAST *); virtual void visitInitDeclarator(InitDeclaratorAST *); virtual void visitInitializer(InitializerAST *); virtual void visitInitializerClause(InitializerClauseAST *); virtual void visitLabeledStatement(LabeledStatementAST *); virtual void visitLinkageBody(LinkageBodyAST *); virtual void visitLinkageSpecification(LinkageSpecificationAST *); virtual void visitMemInitializer(MemInitializerAST *); virtual void visitName(NameAST *); virtual void visitNamespace(NamespaceAST *); virtual void visitNamespaceAliasDefinition(NamespaceAliasDefinitionAST *); virtual void visitNewDeclarator(NewDeclaratorAST *); virtual void visitNewExpression(NewExpressionAST *); virtual void visitNewInitializer(NewInitializerAST *); virtual void visitNewTypeId(NewTypeIdAST *); virtual void visitOperator(OperatorAST *); virtual void visitOperatorFunctionId(OperatorFunctionIdAST *); virtual void visitParameterDeclaration(ParameterDeclarationAST *); virtual void visitParameterDeclarationClause(ParameterDeclarationClauseAST *); virtual void visitPostfixExpression(PostfixExpressionAST *); virtual void visitPrimaryExpression(PrimaryExpressionAST *); virtual void visitPtrOperator(PtrOperatorAST *); virtual void visitPtrToMember(PtrToMemberAST *); virtual void visitReturnStatement(ReturnStatementAST *); virtual void visitSimpleDeclaration(SimpleDeclarationAST *); virtual void visitSimpleTypeSpecifier(SimpleTypeSpecifierAST *); virtual void visitSizeofExpression(SizeofExpressionAST *); virtual void visitStringLiteral(StringLiteralAST *); virtual void visitSubscriptExpression(SubscriptExpressionAST *); virtual void visitSwitchStatement(SwitchStatementAST *); virtual void visitTemplateArgument(TemplateArgumentAST *); virtual void visitTemplateDeclaration(TemplateDeclarationAST *); virtual void visitTemplateParameter(TemplateParameterAST *); virtual void visitThrowExpression(ThrowExpressionAST *); virtual void visitTranslationUnit(TranslationUnitAST *); virtual void visitTryBlockStatement(TryBlockStatementAST *); virtual void visitTypeId(TypeIdAST *); virtual void visitTypeIdentification(TypeIdentificationAST *); virtual void visitTypeParameter(TypeParameterAST *); virtual void visitTypedef(TypedefAST *); virtual void visitUnaryExpression(UnaryExpressionAST *); virtual void visitUnqualifiedName(UnqualifiedNameAST *); virtual void visitUsing(UsingAST *); virtual void visitUsingDirective(UsingDirectiveAST *); virtual void visitWhileStatement(WhileStatementAST *); virtual void visitWinDeclSpec(WinDeclSpecAST *); private: typedef void (Visitor::*visitor_fun_ptr)(AST *); static visitor_fun_ptr _S_table[]; }; #endif // VISITOR_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/dumptree.cpp000066400000000000000000000067131170724227300237050ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "dumptree.h" #include #include static char const * const names[] = { 0, "AccessSpecifier", "AsmDefinition", "BaseClause", "BaseSpecifier", "BinaryExpression", "CastExpression", "ClassMemberAccess", "ClassSpecifier", "CompoundStatement", "Condition", "ConditionalExpression", "CppCastExpression", "CtorInitializer", "DeclarationStatement", "Declarator", "DeleteExpression", "DoStatement", "ElaboratedTypeSpecifier", "EnumSpecifier", "Enumerator", "ExceptionSpecification", "ExpressionOrDeclarationStatement", "ExpressionStatement", "ForStatement", "FunctionCall", "FunctionDefinition", "IfStatement", "IncrDecrExpression", "InitDeclarator", "Initializer", "InitializerClause", "LabeledStatement", "LinkageBody", "LinkageSpecification", "MemInitializer", "Name", "Namespace", "NamespaceAliasDefinition", "NewDeclarator", "NewExpression", "NewInitializer", "NewTypeId", "Operator", "OperatorFunctionId", "ParameterDeclaration", "ParameterDeclarationClause", "PostfixExpression", "PrimaryExpression", "PtrOperator", "PtrToMember", "ReturnStatement", "SimpleDeclaration", "SimpleTypeSpecifier", "SizeofExpression", "StringLiteral", "SubscriptExpression", "SwitchStatement", "TemplateArgument", "TemplateDeclaration", "TemplateParameter", "ThrowExpression", "TranslationUnit", "TryBlockStatement", "TypeId", "TypeIdentification", "TypeParameter", "Typedef", "UnaryExpression", "UnqualifiedName", "Using", "UsingDirective", "WhileStatement", "WinDeclSpec" }; DumpTree::DumpTree() { } void DumpTree::visit(AST *node) { static int indent = 0; if (node) qDebug() << QString(indent * 2, ' ').toLatin1().constData() << names[node->kind] << '[' << node->start_token << ", " << node->end_token << ']'; ++indent; DefaultVisitor::visit(node); --indent; } // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/dumptree.h000066400000000000000000000034241170724227300233460ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef DUMPTREE_H #define DUMPTREE_H #include "default_visitor.h" class DumpTree: protected DefaultVisitor { public: DumpTree(); void dump(AST *node) { visit(node); } protected: virtual void visit(AST *node); }; #endif // DUMPTREE_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/include/000077500000000000000000000000001170724227300227705ustar00rootroot00000000000000qtscriptgenerator-src-0.2.0/generator/parser/include/stdarg.h000066400000000000000000000040511170724227300244250ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef __STDARG #define __STDARG #if !defined(_VA_LIST) && !defined(__VA_LIST_DEFINED) #define _VA_LIST #define _VA_LIST_DEFINED typedef char *__va_list; #endif static float __va_arg_tmp; typedef __va_list va_list; #define va_start(list, start) ((void)0) #define __va_arg(list, mode, n) ((void)0) #define _bigendian_va_arg(list, mode, n) ((void)0) #define _littleendian_va_arg(list, mode, n) ((void)0) #define va_end(list) ((void)0) #define va_arg(list, mode) ((void)0) typedef void *__gnuc_va_list; #endif qtscriptgenerator-src-0.2.0/generator/parser/lexer.cpp000066400000000000000000001125141170724227300231740ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "lexer.h" #include "tokens.h" #include "control.h" #include #include scan_fun_ptr Lexer::s_scan_keyword_table[] = { &Lexer::scanKeyword0, &Lexer::scanKeyword0, &Lexer::scanKeyword2, &Lexer::scanKeyword3, &Lexer::scanKeyword4, &Lexer::scanKeyword5, &Lexer::scanKeyword6, &Lexer::scanKeyword7, &Lexer::scanKeyword8, &Lexer::scanKeyword9, &Lexer::scanKeyword10, &Lexer::scanKeyword11, &Lexer::scanKeyword12, &Lexer::scanKeyword13, &Lexer::scanKeyword14, &Lexer::scanKeyword0, &Lexer::scanKeyword16 }; void LocationManager::extract_line(int offset, int *line, QString *filename) const { *line = 0; if (token_stream.size () < 1) return; const unsigned char *begin_buffer = reinterpret_cast(token_stream[0].text); const unsigned char *cursor = begin_buffer + offset; ++cursor; // skip '#' if (std::isspace(*cursor) && std::isdigit(*(cursor + 1))) { ++cursor; char buffer[1024], *cp = buffer; do { *cp++ = *cursor++; } while (std::isdigit(*cursor)); *cp = '\0'; int l = strtol(buffer, 0, 0); Q_ASSERT(std::isspace(*cursor)); ++cursor; Q_ASSERT(*cursor == '"'); ++cursor; cp = buffer; while (*cursor && *cursor != '"') { *cp++ = *cursor++; } *cp = '\0'; Q_ASSERT(*cursor == '"'); ++cursor; *filename = buffer; *line = l; // printf("filename: %s line: %d\n", buffer, line); } } void LocationManager::positionAt(std::size_t offset, int *line, int *column, QString *filename) const { int ppline, ppcolumn; line_table.positionAt(offset, &ppline, &ppcolumn); int base_line; extract_line((int) line_table[ppline-1], &base_line, filename); int line2, column2; location_table.positionAt((int) line_table[ppline-1], &line2, &column2); location_table.positionAt(offset, line, column); *line = base_line + *line - line2 - 1; } scan_fun_ptr Lexer::s_scan_table[256]; bool Lexer::s_initialized = false; void Lexer::tokenize(const char *contents, std::size_t size) { if (!s_initialized) initialize_scan_table(); token_stream.resize(1024); token_stream[0].kind = Token_EOF; token_stream[0].text = contents; index = 1; cursor = (const unsigned char *) contents; begin_buffer = (const unsigned char *) contents; end_buffer = cursor + size; location_table.resize(1024); location_table[0] = 0; location_table.current_line = 1; line_table.resize(1024); line_table[0] = 0; line_table.current_line = 1; do { if (index == token_stream.size()) token_stream.resize(token_stream.size() * 2); Token *current_token = &token_stream[(int) index]; current_token->text = reinterpret_cast(begin_buffer); current_token->position = cursor - begin_buffer; (this->*s_scan_table[*cursor])(); current_token->size = cursor - begin_buffer - current_token->position; } while (cursor < end_buffer); if (index == token_stream.size()) token_stream.resize(token_stream.size() * 2); Q_ASSERT(index < token_stream.size()); token_stream[(int) index].position = cursor - begin_buffer; token_stream[(int) index].kind = Token_EOF; } void Lexer::reportError(const QString& msg) { int line, column; QString fileName; std::size_t tok = token_stream.cursor(); _M_location.positionAt(token_stream.position(tok), &line, &column, &fileName); Control::ErrorMessage errmsg; errmsg.setLine(line + 1); errmsg.setColumn(column); errmsg.setFileName(fileName); errmsg.setMessage(QLatin1String("** LEXER ERROR ") + msg); control->reportError(errmsg); } void Lexer::initialize_scan_table() { s_initialized = true; for (int i=0; i<256; ++i) { if (isspace(i)) s_scan_table[i] = &Lexer::scan_white_spaces; else if (isalpha(i) || i == '_') s_scan_table[i] = &Lexer::scan_identifier_or_keyword; else if (isdigit(i)) s_scan_table[i] = &Lexer::scan_int_constant; else s_scan_table[i] = &Lexer::scan_invalid_input; } s_scan_table[int('L')] = &Lexer::scan_identifier_or_literal; s_scan_table[int('\n')] = &Lexer::scan_newline; s_scan_table[int('#')] = &Lexer::scan_preprocessor; s_scan_table[int('\'')] = &Lexer::scan_char_constant; s_scan_table[int('"')] = &Lexer::scan_string_constant; s_scan_table[int('.')] = &Lexer::scan_int_constant; s_scan_table[int('!')] = &Lexer::scan_not; s_scan_table[int('%')] = &Lexer::scan_remainder; s_scan_table[int('&')] = &Lexer::scan_and; s_scan_table[int('(')] = &Lexer::scan_left_paren; s_scan_table[int(')')] = &Lexer::scan_right_paren; s_scan_table[int('*')] = &Lexer::scan_star; s_scan_table[int('+')] = &Lexer::scan_plus; s_scan_table[int(',')] = &Lexer::scan_comma; s_scan_table[int('-')] = &Lexer::scan_minus; s_scan_table[int('/')] = &Lexer::scan_divide; s_scan_table[int(':')] = &Lexer::scan_colon; s_scan_table[int(';')] = &Lexer::scan_semicolon; s_scan_table[int('<')] = &Lexer::scan_less; s_scan_table[int('=')] = &Lexer::scan_equal; s_scan_table[int('>')] = &Lexer::scan_greater; s_scan_table[int('?')] = &Lexer::scan_question; s_scan_table[int('[')] = &Lexer::scan_left_bracket; s_scan_table[int(']')] = &Lexer::scan_right_bracket; s_scan_table[int('^')] = &Lexer::scan_xor; s_scan_table[int('{')] = &Lexer::scan_left_brace; s_scan_table[int('|')] = &Lexer::scan_or; s_scan_table[int('}')] = &Lexer::scan_right_brace; s_scan_table[int('~')] = &Lexer::scan_tilde; s_scan_table[0] = &Lexer::scan_EOF; } void Lexer::scan_preprocessor() { if (line_table.current_line == line_table.size()) line_table.resize(line_table.current_line * 2); line_table[(int) line_table.current_line++] = (cursor - begin_buffer); while (*cursor && *cursor != '\n') ++cursor; if (*cursor != '\n') reportError("expected newline"); } void Lexer::scan_char_constant() { const unsigned char *begin = cursor; ++cursor; while (*cursor && *cursor != '\'') { if (*cursor == '\n') reportError("did not expect newline"); if (*cursor == '\\') ++cursor; ++cursor; } if (*cursor != '\'') reportError("expected \'"); ++cursor; token_stream[(int) index].extra.symbol = control->findOrInsertName((const char*) begin, cursor - begin); token_stream[(int) index++].kind = Token_char_literal; } void Lexer::scan_string_constant() { const unsigned char *begin = cursor; ++cursor; while (*cursor && *cursor != '"') { if (*cursor == '\n') reportError("did not expect newline"); if (*cursor == '\\') ++cursor; ++cursor; } if (*cursor != '"') reportError("expected \""); ++cursor; token_stream[(int) index].extra.symbol = control->findOrInsertName((const char*) begin, cursor - begin); token_stream[(int) index++].kind = Token_string_literal; } void Lexer::scan_newline() { if (location_table.current_line == location_table.size()) location_table.resize(location_table.current_line * 2); location_table[(int) location_table.current_line++] = (cursor - begin_buffer); ++cursor; } void Lexer::scan_white_spaces() { while (isspace(*cursor)) { if (*cursor == '\n') scan_newline(); else ++cursor; } } void Lexer::scan_identifier_or_literal() { switch (*(cursor + 1)) { case '\'': ++cursor; scan_char_constant(); break; case '\"': ++cursor; scan_string_constant(); break; default: scan_identifier_or_keyword(); break; } } void Lexer::scan_identifier_or_keyword() { const unsigned char *skip = cursor; while (isalnum(*skip) || *skip== '_') ++skip; int n = skip - cursor; Token *current_token = &token_stream[(int) index]; (this->*s_scan_keyword_table[n < 17 ? n : 0])(); if (current_token->kind == Token_identifier) { current_token->extra.symbol = control->findOrInsertName((const char*) cursor, n); } cursor = skip; } void Lexer::scan_int_constant() { if (*cursor == '.' && !std::isdigit(*(cursor + 1))) { scan_dot(); return; } const unsigned char *begin = cursor; while (isalnum(*cursor) || *cursor == '.') ++cursor; token_stream[(int) index].extra.symbol = control->findOrInsertName((const char*) begin, cursor - begin); token_stream[(int) index++].kind = Token_number_literal; } void Lexer::scan_not() { /* '!' ::= not '!=' ::= not_equal */ ++cursor; if (*cursor == '=') { ++cursor; token_stream[(int) index++].kind = Token_not_eq; } else { token_stream[(int) index++].kind = '!'; } } void Lexer::scan_remainder() { /* '%' ::= remainder '%=' ::= remainder_equal */ ++cursor; if (*cursor == '=') { ++cursor; token_stream[(int) index++].kind = Token_assign; } else { token_stream[(int) index++].kind = '%'; } } void Lexer::scan_and() { /* '&&' ::= and_and '&' ::= and '&=' ::= and_equal */ ++cursor; if (*cursor == '=') { ++cursor; token_stream[(int) index++].kind = Token_assign; } else if (*cursor == '&') { ++cursor; token_stream[(int) index++].kind = Token_and; } else { token_stream[(int) index++].kind = '&'; } } void Lexer::scan_left_paren() { ++cursor; token_stream[(int) index++].kind = '('; } void Lexer::scan_right_paren() { ++cursor; token_stream[(int) index++].kind = ')'; } void Lexer::scan_star() { /* '*' ::= star '*=' ::= star_equal */ ++cursor; if (*cursor == '=') { ++cursor; token_stream[(int) index++].kind = Token_assign; } else { token_stream[(int) index++].kind = '*'; } } void Lexer::scan_plus() { /* '+' ::= plus '++' ::= incr '+=' ::= plus_equal */ ++cursor; if (*cursor == '=') { ++cursor; token_stream[(int) index++].kind = Token_assign; } else if (*cursor == '+') { ++cursor; token_stream[(int) index++].kind = Token_incr; } else { token_stream[(int) index++].kind = '+'; } } void Lexer::scan_comma() { ++cursor; token_stream[(int) index++].kind = ','; } void Lexer::scan_minus() { /* '-' ::= minus '--' ::= decr '-=' ::= minus_equal '->' ::= left_arrow */ ++cursor; if (*cursor == '=') { ++cursor; token_stream[(int) index++].kind = Token_assign; } else if (*cursor == '-') { ++cursor; token_stream[(int) index++].kind = Token_decr; } else if (*cursor == '>') { ++cursor; token_stream[(int) index++].kind = Token_arrow; if (*cursor == '*') { ++cursor; token_stream[(int) index++].kind = Token_ptrmem; } } else { token_stream[(int) index++].kind = '-'; } } void Lexer::scan_dot() { /* '.' ::= dot '...' ::= ellipsis */ ++cursor; if (*cursor == '.' && *(cursor + 1) == '.') { cursor += 2; token_stream[(int) index++].kind = Token_ellipsis; } else if (*cursor == '.' && *(cursor + 1) == '*') { cursor += 2; token_stream[(int) index++].kind = Token_ptrmem; } else token_stream[(int) index++].kind = '.'; } void Lexer::scan_divide() { /* '/' ::= divide '/=' ::= divide_equal */ ++cursor; if (*cursor == '=') { ++cursor; token_stream[(int) index++].kind = Token_assign; } else { token_stream[(int) index++].kind = '/'; } } void Lexer::scan_colon() { ++cursor; if (*cursor == ':') { ++cursor; token_stream[(int) index++].kind = Token_scope; } else { token_stream[(int) index++].kind = ':'; } } void Lexer::scan_semicolon() { ++cursor; token_stream[(int) index++].kind = ';'; } void Lexer::scan_less() { /* '<' ::= less '<<' ::= left_shift '<<=' ::= left_shift_equal '<=' ::= less_equal */ ++cursor; if (*cursor == '=') { ++cursor; token_stream[(int) index++].kind = Token_leq; } else if (*cursor == '<') { ++cursor; if (*cursor == '=') { ++cursor; token_stream[(int) index++].kind = Token_assign; } else { token_stream[(int) index++].kind = Token_shift; } } else { token_stream[(int) index++].kind = '<'; } } void Lexer::scan_equal() { /* '=' ::= equal '==' ::= equal_equal */ ++cursor; if (*cursor == '=') { ++cursor; token_stream[(int) index++].kind = Token_eq; } else { token_stream[(int) index++].kind = '='; } } void Lexer::scan_greater() { /* '>' ::= greater '>=' ::= greater_equal '>>' ::= right_shift '>>=' ::= right_shift_equal */ ++cursor; if (*cursor == '=') { ++cursor; token_stream[(int) index++].kind = Token_geq; } else if (*cursor == '>') { ++cursor; if (*cursor == '=') { ++cursor; token_stream[(int) index++].kind = Token_assign; } else { token_stream[(int) index++].kind = Token_shift; } } else { token_stream[(int) index++].kind = '>'; } } void Lexer::scan_question() { ++cursor; token_stream[(int) index++].kind = '?'; } void Lexer::scan_left_bracket() { ++cursor; token_stream[(int) index++].kind = '['; } void Lexer::scan_right_bracket() { ++cursor; token_stream[(int) index++].kind = ']'; } void Lexer::scan_xor() { /* '^' ::= xor '^=' ::= xor_equal */ ++cursor; if (*cursor == '=') { ++cursor; token_stream[(int) index++].kind = Token_assign; } else { token_stream[(int) index++].kind = '^'; } } void Lexer::scan_left_brace() { ++cursor; token_stream[(int) index++].kind = '{'; } void Lexer::scan_or() { /* '|' ::= or '|=' ::= or_equal '||' ::= or_or */ ++cursor; if (*cursor == '=') { ++cursor; token_stream[(int) index++].kind = Token_assign; } else if (*cursor == '|') { ++cursor; token_stream[(int) index++].kind = Token_or; } else { token_stream[(int) index++].kind = '|'; } } void Lexer::scan_right_brace() { ++cursor; token_stream[(int) index++].kind = '}'; } void Lexer::scan_tilde() { ++cursor; token_stream[(int) index++].kind = '~'; } void Lexer::scan_EOF() { ++cursor; token_stream[(int) index++].kind = Token_EOF; } void Lexer::scan_invalid_input() { QString errmsg("invalid input: %1"); errmsg.arg(int(*cursor)); reportError(errmsg); ++cursor; } void LocationTable::positionAt(std::size_t offset, int max_line, int *line, int *column) const { if (!(line && column && max_line != 0)) return; int first = 0; int len = max_line; int half; int middle; while (len > 0) { half = len >> 1; middle = first; middle += half; if (lines[middle] < offset) { first = middle; ++first; len = len - half - 1; } else len = half; } *line = std::max(first, 1); *column = (int) (offset - lines[*line - 1] - 1); if (*column < 0) { *column = 0; } } void Lexer::scanKeyword0() { token_stream[(int) index++].kind = Token_identifier; } void Lexer::scanKeyword2() { switch (*cursor) { case 'i': if (*(cursor + 1) == 'f') { token_stream[(int) index++].kind = Token_if; return; } break; case 'd': if (*(cursor + 1) == 'o') { token_stream[(int) index++].kind = Token_do; return; } break; case 'o': if (*(cursor + 1) == 'r') { token_stream[(int) index++].kind = Token_or; return; } break; } token_stream[(int) index++].kind = Token_identifier; } void Lexer::scanKeyword3() { switch (*cursor) { case 'a': if (*(cursor + 1) == 'n' && *(cursor + 2) == 'd') { token_stream[(int) index++].kind = Token_and; return; } if (*(cursor + 1) == 's' && *(cursor + 2) == 'm') { token_stream[(int) index++].kind = Token_asm; return; } break; case 'f': if (*(cursor + 1) == 'o' && *(cursor + 2) == 'r') { token_stream[(int) index++].kind = Token_for; return; } break; case 'i': if (*(cursor + 1) == 'n' && *(cursor + 2) == 't') { token_stream[(int) index++].kind = Token_int; return; } break; case 'n': if (*(cursor + 1) == 'e' && *(cursor + 2) == 'w') { token_stream[(int) index++].kind = Token_new; return; } if (*(cursor + 1) == 'o' && *(cursor + 2) == 't') { token_stream[(int) index++].kind = Token_not; return; } break; case 't': if (*(cursor + 1) == 'r' && *(cursor + 2) == 'y') { token_stream[(int) index++].kind = Token_try; return; } break; case 'x': if (*(cursor + 1) == 'o' && *(cursor + 2) == 'r') { token_stream[(int) index++].kind = Token_xor; return; } break; } token_stream[(int) index++].kind = Token_identifier; } void Lexer::scanKeyword4() { switch (*cursor) { case 'a': if (*(cursor + 1) == 'u' && *(cursor + 2) == 't' && *(cursor + 3) == 'o') { token_stream[(int) index++].kind = Token_auto; return; } break; case 'c': if (*(cursor + 1) == 'a' && *(cursor + 2) == 's' && *(cursor + 3) == 'e') { token_stream[(int) index++].kind = Token_case; return; } if (*(cursor + 1) == 'h' && *(cursor + 2) == 'a' && *(cursor + 3) == 'r') { token_stream[(int) index++].kind = Token_char; return; } break; case 'b': if (*(cursor + 1) == 'o' && *(cursor + 2) == 'o' && *(cursor + 3) == 'l') { token_stream[(int) index++].kind = Token_bool; return; } break; case 'e': if (*(cursor + 1) == 'l' && *(cursor + 2) == 's' && *(cursor + 3) == 'e') { token_stream[(int) index++].kind = Token_else; return; } if (*(cursor + 1) == 'm' && *(cursor + 2) == 'i' && *(cursor + 3) == 't') { token_stream[(int) index++].kind = Token_emit; return; } if (*(cursor + 1) == 'n' && *(cursor + 2) == 'u' && *(cursor + 3) == 'm') { token_stream[(int) index++].kind = Token_enum; return; } break; case 'g': if (*(cursor + 1) == 'o' && *(cursor + 2) == 't' && *(cursor + 3) == 'o') { token_stream[(int) index++].kind = Token_goto; return; } break; case 'l': if (*(cursor + 1) == 'o' && *(cursor + 2) == 'n' && *(cursor + 3) == 'g') { token_stream[(int) index++].kind = Token_long; return; } break; case 't': if (*(cursor + 1) == 'h' && *(cursor + 2) == 'i' && *(cursor + 3) == 's') { token_stream[(int) index++].kind = Token_this; return; } break; case 'v': if (*(cursor + 1) == 'o' && *(cursor + 2) == 'i' && *(cursor + 3) == 'd') { token_stream[(int) index++].kind = Token_void; return; } break; } token_stream[(int) index++].kind = Token_identifier; } void Lexer::scanKeyword5() { switch (*cursor) { case 'c': if (*(cursor + 1) == 'a' && *(cursor + 2) == 't' && *(cursor + 3) == 'c' && *(cursor + 4) == 'h') { token_stream[(int) index++].kind = Token_catch; return; } if (*(cursor + 1) == 'l' && *(cursor + 2) == 'a' && *(cursor + 3) == 's' && *(cursor + 4) == 's') { token_stream[(int) index++].kind = Token_class; return; } if (*(cursor + 1) == 'o' && *(cursor + 2) == 'm' && *(cursor + 3) == 'p' && *(cursor + 4) == 'l') { token_stream[(int) index++].kind = Token_compl; return; } if (*(cursor + 1) == 'o' && *(cursor + 2) == 'n' && *(cursor + 3) == 's' && *(cursor + 4) == 't') { token_stream[(int) index++].kind = Token_const; return; } break; case 'b': if (*(cursor + 1) == 'i' && *(cursor + 2) == 't' && *(cursor + 3) == 'o' && *(cursor + 4) == 'r') { token_stream[(int) index++].kind = Token_bitor; return; } if (*(cursor + 1) == 'r' && *(cursor + 2) == 'e' && *(cursor + 3) == 'a' && *(cursor + 4) == 'k') { token_stream[(int) index++].kind = Token_break; return; } break; case 'f': if (*(cursor + 1) == 'l' && *(cursor + 2) == 'o' && *(cursor + 3) == 'a' && *(cursor + 4) == 't') { token_stream[(int) index++].kind = Token_float; return; } break; case 'o': if (*(cursor + 1) == 'r' && *(cursor + 2) == '_' && *(cursor + 3) == 'e' && *(cursor + 4) == 'q') { token_stream[(int) index++].kind = Token_or_eq; return; } break; case 's': if (*(cursor + 1) == 'h' && *(cursor + 2) == 'o' && *(cursor + 3) == 'r' && *(cursor + 4) == 't') { token_stream[(int) index++].kind = Token_short; return; } if (*(cursor + 1) == 'l' && *(cursor + 2) == 'o' && *(cursor + 3) == 't' && *(cursor + 4) == 's') { token_stream[(int) index++].kind = Token_slots; return; } break; case 'u': if (*(cursor + 1) == 'n' && *(cursor + 2) == 'i' && *(cursor + 3) == 'o' && *(cursor + 4) == 'n') { token_stream[(int) index++].kind = Token_union; return; } if (*(cursor + 1) == 's' && *(cursor + 2) == 'i' && *(cursor + 3) == 'n' && *(cursor + 4) == 'g') { token_stream[(int) index++].kind = Token_using; return; } break; case 't': if (*(cursor + 1) == 'h' && *(cursor + 2) == 'r' && *(cursor + 3) == 'o' && *(cursor + 4) == 'w') { token_stream[(int) index++].kind = Token_throw; return; } break; case 'w': if (*(cursor + 1) == 'h' && *(cursor + 2) == 'i' && *(cursor + 3) == 'l' && *(cursor + 4) == 'e') { token_stream[(int) index++].kind = Token_while; return; } break; } token_stream[(int) index++].kind = Token_identifier; } void Lexer::scanKeyword6() { switch (*cursor) { case 'a': if (*(cursor + 1) == 'n' && *(cursor + 2) == 'd' && *(cursor + 3) == '_' && *(cursor + 4) == 'e' && *(cursor + 5) == 'q') { token_stream[(int) index++].kind = Token_and_eq; return; } break; case 'b': if (*(cursor + 1) == 'i' && *(cursor + 2) == 't' && *(cursor + 3) == 'a' && *(cursor + 4) == 'n' && *(cursor + 5) == 'd') { token_stream[(int) index++].kind = Token_bitand; return; } break; case 'e': if (*(cursor + 1) == 'x' && *(cursor + 2) == 'p' && *(cursor + 3) == 'o' && *(cursor + 4) == 'r' && *(cursor + 5) == 't') { token_stream[(int) index++].kind = Token_export; return; } if (*(cursor + 1) == 'x' && *(cursor + 2) == 't' && *(cursor + 3) == 'e' && *(cursor + 4) == 'r' && *(cursor + 5) == 'n') { token_stream[(int) index++].kind = Token_extern; return; } break; case 'd': if (*(cursor + 1) == 'e' && *(cursor + 2) == 'l' && *(cursor + 3) == 'e' && *(cursor + 4) == 't' && *(cursor + 5) == 'e') { token_stream[(int) index++].kind = Token_delete; return; } if (*(cursor + 1) == 'o' && *(cursor + 2) == 'u' && *(cursor + 3) == 'b' && *(cursor + 4) == 'l' && *(cursor + 5) == 'e') { token_stream[(int) index++].kind = Token_double; return; } break; case 'f': if (*(cursor + 1) == 'r' && *(cursor + 2) == 'i' && *(cursor + 3) == 'e' && *(cursor + 4) == 'n' && *(cursor + 5) == 'd') { token_stream[(int) index++].kind = Token_friend; return; } break; case 'i': if (*(cursor + 1) == 'n' && *(cursor + 2) == 'l' && *(cursor + 3) == 'i' && *(cursor + 4) == 'n' && *(cursor + 5) == 'e') { token_stream[(int) index++].kind = Token_inline; return; } break; case 'K': if (*(cursor + 1) == '_' && *(cursor + 2) == 'D' && *(cursor + 3) == 'C' && *(cursor + 4) == 'O' && *(cursor + 5) == 'P') { token_stream[(int) index++].kind = Token_K_DCOP; return; } break; case 'n': if (*(cursor + 1) == 'o' && *(cursor + 2) == 't' && *(cursor + 3) == '_' && *(cursor + 4) == 'e' && *(cursor + 5) == 'q') { token_stream[(int) index++].kind = Token_not_eq; return; } break; case 'p': if (*(cursor + 1) == 'u' && *(cursor + 2) == 'b' && *(cursor + 3) == 'l' && *(cursor + 4) == 'i' && *(cursor + 5) == 'c') { token_stream[(int) index++].kind = Token_public; return; } break; case 's': if (*(cursor + 1) == 'i' && *(cursor + 2) == 'g' && *(cursor + 3) == 'n' && *(cursor + 4) == 'e' && *(cursor + 5) == 'd') { token_stream[(int) index++].kind = Token_signed; return; } if (*(cursor + 1) == 'i' && *(cursor + 2) == 'z' && *(cursor + 3) == 'e' && *(cursor + 4) == 'o' && *(cursor + 5) == 'f') { token_stream[(int) index++].kind = Token_sizeof; return; } if (*(cursor + 1) == 't' && *(cursor + 2) == 'a' && *(cursor + 3) == 't' && *(cursor + 4) == 'i' && *(cursor + 5) == 'c') { token_stream[(int) index++].kind = Token_static; return; } if (*(cursor + 1) == 't' && *(cursor + 2) == 'r' && *(cursor + 3) == 'u' && *(cursor + 4) == 'c' && *(cursor + 5) == 't') { token_stream[(int) index++].kind = Token_struct; return; } if (*(cursor + 1) == 'w' && *(cursor + 2) == 'i' && *(cursor + 3) == 't' && *(cursor + 4) == 'c' && *(cursor + 5) == 'h') { token_stream[(int) index++].kind = Token_switch; return; } break; case 'r': if (*(cursor + 1) == 'e' && *(cursor + 2) == 't' && *(cursor + 3) == 'u' && *(cursor + 4) == 'r' && *(cursor + 5) == 'n') { token_stream[(int) index++].kind = Token_return; return; } break; case 't': if (*(cursor + 1) == 'y' && *(cursor + 2) == 'p' && *(cursor + 3) == 'e' && *(cursor + 4) == 'i' && *(cursor + 5) == 'd') { token_stream[(int) index++].kind = Token_typeid; return; } break; case 'x': if (*(cursor + 1) == 'o' && *(cursor + 2) == 'r' && *(cursor + 3) == '_' && *(cursor + 4) == 'e' && *(cursor + 5) == 'q') { token_stream[(int) index++].kind = Token_xor_eq; return; } break; case 'k': if (*(cursor + 1) == '_' && *(cursor + 2) == 'd' && *(cursor + 3) == 'c' && *(cursor + 4) == 'o' && *(cursor + 5) == 'p') { token_stream[(int) index++].kind = Token_k_dcop; return; } break; } token_stream[(int) index++].kind = Token_identifier; } void Lexer::scanKeyword7() { switch (*cursor) { case 'd': if (*(cursor + 1) == 'e' && *(cursor + 2) == 'f' && *(cursor + 3) == 'a' && *(cursor + 4) == 'u' && *(cursor + 5) == 'l' && *(cursor + 6) == 't') { token_stream[(int) index++].kind = Token_default; return; } break; case 'm': if (*(cursor + 1) == 'u' && *(cursor + 2) == 't' && *(cursor + 3) == 'a' && *(cursor + 4) == 'b' && *(cursor + 5) == 'l' && *(cursor + 6) == 'e') { token_stream[(int) index++].kind = Token_mutable; return; } break; case 'p': if (*(cursor + 1) == 'r' && *(cursor + 2) == 'i' && *(cursor + 3) == 'v' && *(cursor + 4) == 'a' && *(cursor + 5) == 't' && *(cursor + 6) == 'e') { token_stream[(int) index++].kind = Token_private; return; } break; case 's': if (*(cursor + 1) == 'i' && *(cursor + 2) == 'g' && *(cursor + 3) == 'n' && *(cursor + 4) == 'a' && *(cursor + 5) == 'l' && *(cursor + 6) == 's') { token_stream[(int) index++].kind = Token_signals; return; } break; case 't': if (*(cursor + 1) == 'y' && *(cursor + 2) == 'p' && *(cursor + 3) == 'e' && *(cursor + 4) == 'd' && *(cursor + 5) == 'e' && *(cursor + 6) == 'f') { token_stream[(int) index++].kind = Token_typedef; return; } break; case 'v': if (*(cursor + 1) == 'i' && *(cursor + 2) == 'r' && *(cursor + 3) == 't' && *(cursor + 4) == 'u' && *(cursor + 5) == 'a' && *(cursor + 6) == 'l') { token_stream[(int) index++].kind = Token_virtual; return; } break; case 'Q': if (*(cursor + 1) == '_' && *(cursor + 2) == 'E' && *(cursor + 3) == 'N' && *(cursor + 4) == 'U' && *(cursor + 5) == 'M' && *(cursor + 6) == 'S') { token_stream[(int) index++].kind = Token_Q_ENUMS; return; } break; } token_stream[(int) index++].kind = Token_identifier; } void Lexer::scanKeyword8() { switch (*cursor) { case '_': if (*(cursor + 1) == '_' && *(cursor + 2) == 't' && *(cursor + 3) == 'y' && *(cursor + 4) == 'p' && *(cursor + 5) == 'e' && *(cursor + 6) == 'o' && *(cursor + 7) == 'f') { token_stream[(int) index++].kind = Token___typeof; return; } break; case 'c': if (*(cursor + 1) == 'o' && *(cursor + 2) == 'n' && *(cursor + 3) == 't' && *(cursor + 4) == 'i' && *(cursor + 5) == 'n' && *(cursor + 6) == 'u' && *(cursor + 7) == 'e') { token_stream[(int) index++].kind = Token_continue; return; } break; case 'e': if (*(cursor + 1) == 'x' && *(cursor + 2) == 'p' && *(cursor + 3) == 'l' && *(cursor + 4) == 'i' && *(cursor + 5) == 'c' && *(cursor + 6) == 'i' && *(cursor + 7) == 't') { token_stream[(int) index++].kind = Token_explicit; return; } break; case 'o': if (*(cursor + 1) == 'p' && *(cursor + 2) == 'e' && *(cursor + 3) == 'r' && *(cursor + 4) == 'a' && *(cursor + 5) == 't' && *(cursor + 6) == 'o' && *(cursor + 7) == 'r') { token_stream[(int) index++].kind = Token_operator; return; } break; case 'Q': if (*(cursor + 1) == '_' && *(cursor + 2) == 'O' && *(cursor + 3) == 'B' && *(cursor + 4) == 'J' && *(cursor + 5) == 'E' && *(cursor + 6) == 'C' && *(cursor + 7) == 'T') { token_stream[(int) index++].kind = Token_Q_OBJECT; return; } break; case 'r': if (*(cursor + 1) == 'e' && *(cursor + 2) == 'g' && *(cursor + 3) == 'i' && *(cursor + 4) == 's' && *(cursor + 5) == 't' && *(cursor + 6) == 'e' && *(cursor + 7) == 'r') { token_stream[(int) index++].kind = Token_register; return; } break; case 'u': if (*(cursor + 1) == 'n' && *(cursor + 2) == 's' && *(cursor + 3) == 'i' && *(cursor + 4) == 'g' && *(cursor + 5) == 'n' && *(cursor + 6) == 'e' && *(cursor + 7) == 'd') { token_stream[(int) index++].kind = Token_unsigned; return; } break; case 't': if (*(cursor + 1) == 'e' && *(cursor + 2) == 'm' && *(cursor + 3) == 'p' && *(cursor + 4) == 'l' && *(cursor + 5) == 'a' && *(cursor + 6) == 't' && *(cursor + 7) == 'e') { token_stream[(int) index++].kind = Token_template; return; } if (*(cursor + 1) == 'y' && *(cursor + 2) == 'p' && *(cursor + 3) == 'e' && *(cursor + 4) == 'n' && *(cursor + 5) == 'a' && *(cursor + 6) == 'm' && *(cursor + 7) == 'e') { token_stream[(int) index++].kind = Token_typename; return; } break; case 'v': if (*(cursor + 1) == 'o' && *(cursor + 2) == 'l' && *(cursor + 3) == 'a' && *(cursor + 4) == 't' && *(cursor + 5) == 'i' && *(cursor + 6) == 'l' && *(cursor + 7) == 'e') { token_stream[(int) index++].kind = Token_volatile; return; } break; } token_stream[(int) index++].kind = Token_identifier; } void Lexer::scanKeyword9() { switch (*cursor) { case 'p': if (*(cursor + 1) == 'r' && *(cursor + 2) == 'o' && *(cursor + 3) == 't' && *(cursor + 4) == 'e' && *(cursor + 5) == 'c' && *(cursor + 6) == 't' && *(cursor + 7) == 'e' && *(cursor + 8) == 'd') { token_stream[(int) index++].kind = Token_protected; return; } break; case 'n': if (*(cursor + 1) == 'a' && *(cursor + 2) == 'm' && *(cursor + 3) == 'e' && *(cursor + 4) == 's' && *(cursor + 5) == 'p' && *(cursor + 6) == 'a' && *(cursor + 7) == 'c' && *(cursor + 8) == 'e') { token_stream[(int) index++].kind = Token_namespace; return; } break; } token_stream[(int) index++].kind = Token_identifier; } void Lexer::scanKeyword10() { switch (*cursor) { case 'c': if (*(cursor + 1) == 'o' && *(cursor + 2) == 'n' && *(cursor + 3) == 's' && *(cursor + 4) == 't' && *(cursor + 5) == '_' && *(cursor + 6) == 'c' && *(cursor + 7) == 'a' && *(cursor + 8) == 's' && *(cursor + 9) == 't') { token_stream[(int) index++].kind = Token_const_cast; return; } break; case 'Q': if (*(cursor + 1) == '_' && *(cursor + 2) == 'P' && *(cursor + 3) == 'R' && *(cursor + 4) == 'O' && *(cursor + 5) == 'P' && *(cursor + 6) == 'E' && *(cursor + 7) == 'R' && *(cursor + 8) == 'T' && *(cursor + 9) == 'Y') { token_stream[(int) index++].kind = Token_Q_PROPERTY; return; } break; } token_stream[(int) index++].kind = Token_identifier; } void Lexer::scanKeyword11() { switch (*cursor) { case 'Q': if (*(cursor + 1) == '_' && *(cursor + 2) == 'I' && *(cursor + 3) == 'N' && *(cursor + 4) == 'V' && *(cursor + 5) == 'O' && *(cursor + 6) == 'K' && *(cursor + 7) == 'A' && *(cursor + 8) == 'B' && *(cursor + 9) == 'L' && *(cursor + 10) == 'E') { token_stream[(int) index++].kind = Token_Q_INVOKABLE; return; } break; case 's': if (*(cursor + 1) == 't' && *(cursor + 2) == 'a' && *(cursor + 3) == 't' && *(cursor + 4) == 'i' && *(cursor + 5) == 'c' && *(cursor + 6) == '_' && *(cursor + 7) == 'c' && *(cursor + 8) == 'a' && *(cursor + 9) == 's' && *(cursor + 10) == 't') { token_stream[(int) index++].kind = Token_static_cast; return; } break; } token_stream[(int) index++].kind = Token_identifier; } void Lexer::scanKeyword12() { switch (*cursor) { case 'd': if (*(cursor + 1) == 'y' && *(cursor + 2) == 'n' && *(cursor + 3) == 'a' && *(cursor + 4) == 'm' && *(cursor + 5) == 'i' && *(cursor + 6) == 'c' && *(cursor + 7) == '_' && *(cursor + 8) == 'c' && *(cursor + 9) == 'a' && *(cursor + 10) == 's' && *(cursor + 11) == 't') { token_stream[(int) index++].kind = Token_dynamic_cast; return; } break; } token_stream[(int) index++].kind = Token_identifier; } void Lexer::scanKeyword13() { switch (*cursor) { case '_': if (*(cursor + 1) == '_' && *(cursor + 2) == 'a' && *(cursor + 3) == 't' && *(cursor + 4) == 't' && *(cursor + 5) == 'r' && *(cursor + 6) == 'i' && *(cursor + 7) == 'b' && *(cursor + 8) == 'u' && *(cursor + 9) == 't' && *(cursor + 10) == 'e' && *(cursor + 11) == '_' && *(cursor + 12) == '_') { token_stream[(int) index++].kind = Token___attribute__; return; } break; } token_stream[(int) index++].kind = Token_identifier; } void Lexer::scanKeyword14() { switch (*cursor) { case 'k': if (*(cursor + 1) == '_' && *(cursor + 2) == 'd' && *(cursor + 3) == 'c' && *(cursor + 4) == 'o' && *(cursor + 5) == 'p' && *(cursor + 6) == '_' && *(cursor + 7) == 's' && *(cursor + 8) == 'i' && *(cursor + 9) == 'g' && *(cursor + 10) == 'n' && *(cursor + 11) == 'a' && *(cursor + 12) == 'l' && *(cursor + 13) == 's') { token_stream[(int) index++].kind = Token_k_dcop_signals; return; } break; } token_stream[(int) index++].kind = Token_identifier; } void Lexer::scanKeyword16() { switch (*cursor) { case 'r': if (*(cursor + 1) == 'e' && *(cursor + 2) == 'i' && *(cursor + 3) == 'n' && *(cursor + 4) == 't' && *(cursor + 5) == 'e' && *(cursor + 6) == 'r' && *(cursor + 7) == 'p' && *(cursor + 8) == 'r' && *(cursor + 9) == 'e' && *(cursor + 10) == 't' && *(cursor + 11) == '_' && *(cursor + 12) == 'c' && *(cursor + 13) == 'a' && *(cursor + 14) == 's' && *(cursor + 15) == 't') { token_stream[(int) index++].kind = Token_reinterpret_cast; return; } break; } token_stream[(int) index++].kind = Token_identifier; } // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/lexer.h000066400000000000000000000154161170724227300226440ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef LEXER_H #define LEXER_H #include "symbol.h" #include #include #include struct NameSymbol; class Lexer; class Control; typedef void (Lexer::*scan_fun_ptr)(); class Token { public: int kind; std::size_t position; std::size_t size; char const *text; union { const NameSymbol *symbol; std::size_t right_brace; } extra; }; class LocationTable { private: LocationTable(const LocationTable &source); void operator = (const LocationTable &source); public: inline LocationTable(std::size_t size = 1024) : lines(0), line_count(0), current_line(0) { resize(size); } inline ~LocationTable() { free(lines); } inline std::size_t size() const { return line_count; } void resize(std::size_t size) { Q_ASSERT(size > 0); lines = (std::size_t*) ::realloc(lines, sizeof(std::size_t) * size); line_count = size; } void positionAt(std::size_t offset, int *line, int *column) const { positionAt(offset, (int) current_line, line, column); } void positionAt(std::size_t offset, int max_line, int *line, int *column) const; inline std::size_t &operator[](int index) { return lines[index]; } private: std::size_t *lines; std::size_t line_count; std::size_t current_line; friend class Lexer; }; class TokenStream { private: TokenStream(const TokenStream &); void operator = (const TokenStream &); public: inline TokenStream(std::size_t size = 1024) : tokens(0), index(0), token_count(0) { resize(size); } inline ~TokenStream() { ::free(tokens); } inline std::size_t size() const { return token_count; } inline std::size_t cursor() const { return index; } inline void rewind(int i) { index = i; } void resize(std::size_t size) { Q_ASSERT(size > 0); tokens = (Token*) ::realloc(tokens, sizeof(Token) * size); token_count = size; } inline std::size_t nextToken() { return index++; } inline int lookAhead(std::size_t i = 0) const { return tokens[index + i].kind; } inline int kind(std::size_t i) const { return tokens[i].kind; } inline std::size_t position(std::size_t i) const { return tokens[i].position; } inline const NameSymbol *symbol(std::size_t i) const { return tokens[i].extra.symbol; } inline std::size_t matchingBrace(std::size_t i) const { return tokens[i].extra.right_brace; } inline Token &operator[](int index) { return tokens[index]; } inline const Token &token(int index) const { return tokens[index]; } private: Token *tokens; std::size_t index; std::size_t token_count; private: friend class Lexer; }; class LocationManager { LocationManager(LocationManager const &__other); void operator = (LocationManager const &__other); public: LocationManager (TokenStream &__token_stream, LocationTable &__location_table, LocationTable &__line_table): token_stream (__token_stream), location_table (__location_table), line_table (__line_table) {} void positionAt(std::size_t offset, int *line, int *column, QString *filename) const; void extract_line(int offset, int *line, QString *filename) const; TokenStream &token_stream; LocationTable &location_table; LocationTable &line_table; }; class Lexer { public: Lexer(LocationManager &__location, Control *__control): _M_location(__location), token_stream(_M_location.token_stream), location_table(_M_location.location_table), line_table(_M_location.line_table), control(__control) {} void tokenize(const char *contents, std::size_t size); LocationManager &_M_location; TokenStream &token_stream; LocationTable &location_table; LocationTable &line_table; private: void reportError(const QString& msg); void initialize_scan_table(); void scan_newline(); void scan_white_spaces(); void scan_identifier_or_keyword(); void scan_identifier_or_literal(); void scan_int_constant(); void scan_char_constant(); void scan_string_constant(); void scan_invalid_input(); void scan_preprocessor(); // keywords void scanKeyword0(); void scanKeyword2(); void scanKeyword3(); void scanKeyword4(); void scanKeyword5(); void scanKeyword6(); void scanKeyword7(); void scanKeyword8(); void scanKeyword9(); void scanKeyword10(); void scanKeyword11(); void scanKeyword12(); void scanKeyword13(); void scanKeyword14(); void scanKeyword16(); // operators void scan_not(); void scan_remainder(); void scan_and(); void scan_left_paren(); void scan_right_paren(); void scan_star(); void scan_plus(); void scan_comma(); void scan_minus(); void scan_dot(); void scan_divide(); void scan_colon(); void scan_semicolon(); void scan_less(); void scan_equal(); void scan_greater(); void scan_question(); void scan_left_bracket(); void scan_right_bracket(); void scan_xor(); void scan_left_brace(); void scan_or(); void scan_right_brace(); void scan_tilde(); void scan_EOF(); private: Control *control; const unsigned char *cursor; const unsigned char *begin_buffer; const unsigned char *end_buffer; std::size_t index; static scan_fun_ptr s_scan_table[]; static scan_fun_ptr s_scan_keyword_table[]; static bool s_initialized; }; #endif // LEXER_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/list.cpp000066400000000000000000000030611170724227300230240ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "list.h" // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/list.h000066400000000000000000000057051170724227300225000ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef FASTLIST_H #define FASTLIST_H #include "smallobject.h" template struct ListNode { Tp element; int index; mutable const ListNode *next; static ListNode *create(const Tp &element, pool *p) { ListNode *node = new (p->allocate(sizeof(ListNode))) ListNode(); node->element = element; node->index = 0; node->next = node; return node; } static ListNode *create(const ListNode *n1, const Tp &element, pool *p) { ListNode *n2 = ListNode::create(element, p); n2->index = n1->index + 1; n2->next = n1->next; n1->next = n2; return n2; } inline ListNode() { } inline const ListNode *at(int index) const { const ListNode *node = this; while (index != node->index) node = node->next; return node; } inline bool hasNext() const { return index < next->index; } inline int count() const { return 1 + toBack()->index; } inline const ListNode *toFront() const { return toBack()->next; } inline const ListNode *toBack() const { const ListNode *node = this; while (node->hasNext()) node = node->next; return node; } }; template inline const ListNode *snoc(const ListNode *list, const Tp &element, pool *p) { if (!list) return ListNode::create(element, p); return ListNode::create(list->toBack(), element, p); } #endif // FASTLIST_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/name_compiler.cpp000066400000000000000000000112251170724227300246640ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "name_compiler.h" #include "type_compiler.h" #include "declarator_compiler.h" #include "lexer.h" #include "symbol.h" #include "binder.h" #include NameCompiler::NameCompiler(Binder *binder) : _M_binder (binder), _M_token_stream (binder->tokenStream ()) { } QString NameCompiler::decode_operator(std::size_t index) const { const Token &tk = _M_token_stream->token((int) index); return QString::fromUtf8(&tk.text[tk.position], (int) tk.size); } QString NameCompiler::internal_run(AST *node) { _M_name.clear(); visit(node); return name(); } void NameCompiler::visitUnqualifiedName(UnqualifiedNameAST *node) { QString tmp_name; if (node->tilde) tmp_name += QLatin1String("~"); if (node->id) tmp_name += _M_token_stream->symbol(node->id)->as_string(); if (OperatorFunctionIdAST *op_id = node->operator_id) { #if defined(__GNUC__) #warning "NameCompiler::visitUnqualifiedName() -- implement me" #endif if (op_id->op && op_id->op->op) { tmp_name += QLatin1String("operator"); tmp_name += decode_operator(op_id->op->op); if (op_id->op->close) tmp_name += decode_operator(op_id->op->close); } else if (op_id->type_specifier) { #if defined(__GNUC__) #warning "don't use an hardcoded string as cast' name" #endif Token const &tk = _M_token_stream->token ((int) op_id->start_token); Token const &end_tk = _M_token_stream->token ((int) op_id->end_token); tmp_name += QString::fromLatin1 (&tk.text[tk.position], (int) (end_tk.position - tk.position)).trimmed (); } } _M_name += tmp_name; if (node->template_arguments) { // ### cleanup _M_name.last() += QLatin1String("<"); visitNodes(this, node->template_arguments); _M_name.last().truncate(_M_name.last().count() - 1); // remove the last ',' _M_name.last() += QLatin1String(">"); } } void NameCompiler::visitTemplateArgument(TemplateArgumentAST *node) { if (node->type_id && node->type_id->type_specifier) { TypeCompiler type_cc(_M_binder); type_cc.run(node->type_id->type_specifier); DeclaratorCompiler decl_cc(_M_binder); decl_cc.run(node->type_id->declarator); if (type_cc.isConstant()) _M_name.last() += "const "; QStringList q = type_cc.qualifiedName (); if (q.count () == 1) { #if defined (RXX_RESOLVE_TYPEDEF) // ### it'll break :( TypeInfo tp; tp.setQualifiedName (q); tp = TypeInfo::resolveType (tp, _M_binder->currentScope ()->toItem ()); q = tp.qualifiedName (); #endif if (CodeModelItem item = _M_binder->model ()->findItem (q, _M_binder->currentScope ()->toItem ())) { if (item->name () == q.last ()) q = item->qualifiedName (); } } _M_name.last() += q.join("::"); if (decl_cc.isReference()) _M_name.last() += "&"; if (decl_cc.indirection()) _M_name.last() += QString(decl_cc.indirection(), '*'); _M_name.last() += QLatin1String(","); } } // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/name_compiler.h000066400000000000000000000044741170724227300243410ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef NAME_COMPILER_H #define NAME_COMPILER_H #include "default_visitor.h" #include class TokenStream; class Binder; class NameCompiler: protected DefaultVisitor { public: NameCompiler(Binder *binder); void run(NameAST *node) { internal_run(node); } void run(UnqualifiedNameAST *node) { internal_run(node); } QString name() const { return _M_name.join("::"); } QStringList qualifiedName() const { return _M_name; } protected: virtual void visitUnqualifiedName(UnqualifiedNameAST *node); virtual void visitTemplateArgument(TemplateArgumentAST *node); QString internal_run(AST *node); QString decode_operator(std::size_t index) const; private: Binder *_M_binder; TokenStream *_M_token_stream; QStringList _M_name; }; #endif // NAME_COMPILER_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/parser.cpp000066400000000000000000003062311170724227300233520ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ // c++ support #include "parser.h" #include "tokens.h" #include "lexer.h" #include "control.h" #include #include #define ADVANCE(tk, descr) \ { \ if (token_stream.lookAhead() != tk) { \ tokenRequiredError(tk); \ return false; \ } \ token_stream.nextToken(); \ } #define ADVANCE_NR(tk, descr) \ do { \ if (token_stream.lookAhead() != tk) { \ tokenRequiredError(tk); \ } \ else \ token_stream.nextToken(); \ } while (0) #define CHECK(tk) \ do { \ if (token_stream.lookAhead() != tk) { \ return false; \ } \ token_stream.nextToken(); \ } while (0) #define UPDATE_POS(_node, start, end) \ do { \ (_node)->start_token = start; \ (_node)->end_token = end; \ } while (0) Parser::Parser(Control *c) : _M_location(token_stream, location_table, line_table), control(c), lexer(_M_location, control) { _M_block_errors = false; } Parser::~Parser() { } void Parser::advance() { token_stream.nextToken(); } TranslationUnitAST *Parser::parse(const char *contents, std::size_t size, pool *p) { _M_block_errors = false; _M_pool = p; lexer.tokenize(contents, size); token_stream.nextToken(); // skip the first token Lexer *oldLexer = control->changeLexer (&lexer); Parser *oldParser = control->changeParser (this); TranslationUnitAST *ast = 0; parseTranslationUnit(ast); control->changeLexer (oldLexer); control->changeParser (oldParser); return ast; } bool Parser::parseWinDeclSpec(WinDeclSpecAST *&node) { if (token_stream.lookAhead() != Token_identifier) return false; std::size_t start = token_stream.cursor(); const NameSymbol *name_symbol = token_stream.symbol(token_stream.cursor()); QString name = name_symbol->as_string(); if (name != QLatin1String("__declspec")) return false; std::size_t specifier = token_stream.cursor(); token_stream.nextToken(); if (token_stream.lookAhead() != '(') return false; token_stream.nextToken(); if (token_stream.lookAhead() != Token_identifier) return false; std::size_t modifier = token_stream.cursor(); token_stream.nextToken(); if (token_stream.lookAhead() != ')') return false; token_stream.nextToken(); node = CreateNode(_M_pool); node->specifier = specifier; node->modifier = modifier; UPDATE_POS(node, start, token_stream.cursor()); return true; } void Parser::tokenRequiredError(int token) { QString err; err += "expected token "; err += "``"; err += token_name(token); err += "'' found ``"; err += token_name(token_stream.lookAhead()); err += "''"; reportError(err); } void Parser::syntaxError() { QString err; err += "unexpected token "; err += "``"; err += token_name(token_stream.lookAhead()); err += "''"; reportError(err); } void Parser::reportError(const QString& msg) { if (!_M_block_errors) { int line, column; QString fileName; std::size_t tok = token_stream.cursor(); location().positionAt(token_stream.position(tok), &line, &column, &fileName); Control::ErrorMessage errmsg; errmsg.setLine(line + 1); errmsg.setColumn(column); errmsg.setFileName(fileName); errmsg.setMessage(QLatin1String("** PARSER ERROR ") + msg); control->reportError(errmsg); } } bool Parser::skipUntil(int token) { while (token_stream.lookAhead()) { if (token_stream.lookAhead() == token) return true; token_stream.nextToken(); } return false; } bool Parser::skipUntilDeclaration() { while (token_stream.lookAhead()) { switch(token_stream.lookAhead()) { case ';': case '~': case Token_scope: case Token_identifier: case Token_operator: case Token_char: case Token_wchar_t: case Token_bool: case Token_short: case Token_int: case Token_long: case Token_signed: case Token_unsigned: case Token_float: case Token_double: case Token_void: case Token_extern: case Token_namespace: case Token_using: case Token_typedef: case Token_asm: case Token_template: case Token_export: case Token_const: // cv case Token_volatile: // cv case Token_public: case Token_protected: case Token_private: case Token_signals: // Qt case Token_slots: // Qt return true; default: token_stream.nextToken(); } } return false; } bool Parser::skipUntilStatement() { while (token_stream.lookAhead()) { switch(token_stream.lookAhead()) { case ';': case '{': case '}': case Token_const: case Token_volatile: case Token_identifier: case Token_case: case Token_default: case Token_if: case Token_switch: case Token_while: case Token_do: case Token_for: case Token_break: case Token_continue: case Token_return: case Token_goto: case Token_try: case Token_catch: case Token_throw: case Token_char: case Token_wchar_t: case Token_bool: case Token_short: case Token_int: case Token_long: case Token_signed: case Token_unsigned: case Token_float: case Token_double: case Token_void: case Token_class: case Token_struct: case Token_union: case Token_enum: case Token_scope: case Token_template: case Token_using: return true; default: token_stream.nextToken(); } } return false; } bool Parser::skip(int l, int r) { int count = 0; while (token_stream.lookAhead()) { int tk = token_stream.lookAhead(); if (tk == l) ++count; else if (tk == r) --count; else if (l != '{' && (tk == '{' || tk == '}' || tk == ';')) return false; if (count == 0) return true; token_stream.nextToken(); } return false; } bool Parser::parseName(NameAST *&node, bool acceptTemplateId) { std::size_t start = token_stream.cursor(); WinDeclSpecAST *winDeclSpec = 0; parseWinDeclSpec(winDeclSpec); NameAST *ast = CreateNode(_M_pool); if (token_stream.lookAhead() == Token_scope) { ast->global = true; token_stream.nextToken(); } std::size_t idx = token_stream.cursor(); while (true) { UnqualifiedNameAST *n = 0; if (!parseUnqualifiedName(n)) return false; if (token_stream.lookAhead() == Token_scope) { token_stream.nextToken(); ast->qualified_names = snoc(ast->qualified_names, n, _M_pool); if (token_stream.lookAhead() == Token_template) { /// skip optional template #### @todo CHECK token_stream.nextToken(); } } else { Q_ASSERT(n != 0); if (!acceptTemplateId) { token_stream.rewind((int) n->start_token); parseUnqualifiedName(n, false); } ast->unqualified_name = n; break; } } if (idx == token_stream.cursor()) return false; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseTranslationUnit(TranslationUnitAST *&node) { std::size_t start = token_stream.cursor(); TranslationUnitAST *ast = CreateNode(_M_pool); while (token_stream.lookAhead()) { std::size_t startDecl = token_stream.cursor(); DeclarationAST *declaration = 0; if (parseDeclaration(declaration)) { ast->declarations = snoc(ast->declarations, declaration, _M_pool); } else { // error recovery if (startDecl == token_stream.cursor()) { // skip at least one token token_stream.nextToken(); } skipUntilDeclaration(); } } UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseDeclaration(DeclarationAST *&node) { std::size_t start = token_stream.cursor(); switch(token_stream.lookAhead()) { case ';': token_stream.nextToken(); return true; case Token_extern: return parseLinkageSpecification(node); case Token_namespace: return parseNamespace(node); case Token_using: return parseUsing(node); case Token_typedef: return parseTypedef(node); case Token_asm: return parseAsmDefinition(node); case Token_Q_ENUMS: return parseQ_ENUMS(node); case Token_template: case Token_export: return parseTemplateDeclaration(node); default: { const ListNode *cv = 0; parseCvQualify(cv); const ListNode *storageSpec = 0; parseStorageClassSpecifier(storageSpec); parseCvQualify(cv); TypeSpecifierAST *spec = 0; if (parseEnumSpecifier(spec) || parseClassSpecifier(spec) || parseForwardDeclarationSpecifier(spec)) { parseCvQualify(cv); spec->cv = cv; const ListNode *declarators = 0; parseInitDeclaratorList(declarators); ADVANCE(';', ";"); SimpleDeclarationAST *ast = CreateNode(_M_pool); ast->storage_specifiers = storageSpec; ast->type_specifier = spec; ast->init_declarators = declarators; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } } } // end switch token_stream.rewind((int) start); return parseDeclarationInternal(node); } bool Parser::parseLinkageSpecification(DeclarationAST *&node) { std::size_t start = token_stream.cursor(); CHECK(Token_extern); LinkageSpecificationAST *ast = CreateNode(_M_pool); if (token_stream.lookAhead() == Token_string_literal) { ast->extern_type = token_stream.cursor(); token_stream.nextToken(); } if (token_stream.lookAhead() == '{') { parseLinkageBody(ast->linkage_body); } else if (!parseDeclaration(ast->declaration)) { reportError(("Declaration syntax error")); } UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseLinkageBody(LinkageBodyAST *&node) { std::size_t start = token_stream.cursor(); CHECK('{'); LinkageBodyAST *ast = CreateNode(_M_pool); while (token_stream.lookAhead()) { int tk = token_stream.lookAhead(); if (tk == '}') break; std::size_t startDecl = token_stream.cursor(); DeclarationAST *declaration = 0; if (parseDeclaration(declaration)) { ast->declarations = snoc(ast->declarations, declaration, _M_pool); } else { // error recovery if (startDecl == token_stream.cursor()) { // skip at least one token token_stream.nextToken(); } skipUntilDeclaration(); } } if (token_stream.lookAhead() != '}') reportError(("} expected")); else token_stream.nextToken(); UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseNamespace(DeclarationAST *&node) { std::size_t start = token_stream.cursor(); CHECK(Token_namespace); std::size_t namespace_name = 0; if (token_stream.lookAhead() == Token_identifier) { namespace_name = token_stream.cursor(); token_stream.nextToken(); } if (token_stream.lookAhead() == '=') { // namespace alias token_stream.nextToken(); NameAST *name = 0; if (parseName(name)) { ADVANCE(';', ";"); NamespaceAliasDefinitionAST *ast = CreateNode(_M_pool); ast->namespace_name = namespace_name; ast->alias_name = name; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } else { reportError(("namespace expected")); return false; } } else if (token_stream.lookAhead() != '{') { reportError(("{ expected")); return false; } NamespaceAST *ast = CreateNode(_M_pool); ast->namespace_name = namespace_name; parseLinkageBody(ast->linkage_body); UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseUsing(DeclarationAST *&node) { std::size_t start = token_stream.cursor(); CHECK(Token_using); if (token_stream.lookAhead() == Token_namespace) return parseUsingDirective(node); UsingAST *ast = CreateNode(_M_pool); if (token_stream.lookAhead() == Token_typename) { ast->type_name = token_stream.cursor(); token_stream.nextToken(); } if (!parseName(ast->name)) return false; ADVANCE(';', ";"); UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseUsingDirective(DeclarationAST *&node) { std::size_t start = token_stream.cursor(); CHECK(Token_namespace); NameAST *name = 0; if (!parseName(name)) { reportError(("Namespace name expected")); return false; } ADVANCE(';', ";"); UsingDirectiveAST *ast = CreateNode(_M_pool); ast->name = name; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseOperatorFunctionId(OperatorFunctionIdAST *&node) { std::size_t start = token_stream.cursor(); CHECK(Token_operator); OperatorFunctionIdAST *ast = CreateNode(_M_pool); if (!parseOperator(ast->op)) { ast->op = 0; // parse cast operator const ListNode *cv = 0; parseCvQualify(cv); if (!parseSimpleTypeSpecifier(ast->type_specifier)) { syntaxError(); return false; } parseCvQualify(cv); ast->type_specifier->cv = cv; PtrOperatorAST *ptr_op = 0; while (parsePtrOperator(ptr_op)) ast->ptr_ops = snoc(ast->ptr_ops, ptr_op, _M_pool); } UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseTemplateArgumentList(const ListNode *&node, bool reportError) { TemplateArgumentAST *templArg = 0; if (!parseTemplateArgument(templArg)) return false; node = snoc(node, templArg, _M_pool); while (token_stream.lookAhead() == ',') { token_stream.nextToken(); if (!parseTemplateArgument(templArg)) { if (reportError) { syntaxError(); break; } node = 0; return false; } node = snoc(node, templArg, _M_pool); } return true; } bool Parser::parseTypedef(DeclarationAST *&node) { std::size_t start = token_stream.cursor(); CHECK(Token_typedef); TypeSpecifierAST *spec = 0; if (!parseTypeSpecifierOrClassSpec(spec)) { reportError(("Need a type specifier to declare")); return false; } const ListNode *declarators = 0; if (!parseInitDeclaratorList(declarators)) { //reportError(("Need an identifier to declare")); //return false; } ADVANCE(';', ";"); TypedefAST *ast = CreateNode(_M_pool); ast->type_specifier = spec; ast->init_declarators = declarators; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseAsmDefinition(DeclarationAST *&node) { std::size_t start = token_stream.cursor(); ADVANCE(Token_asm, "asm"); const ListNode *cv = 0; parseCvQualify(cv); #if defined(__GNUC__) #warning "implement me" #endif skip('(', ')'); token_stream.nextToken(); ADVANCE(';', ";"); AsmDefinitionAST *ast = CreateNode(_M_pool); ast->cv = cv; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseTemplateDeclaration(DeclarationAST *&node) { std::size_t start = token_stream.cursor(); std::size_t exported = 0; if (token_stream.lookAhead() == Token_export) { exported = token_stream.cursor(); token_stream.nextToken(); } CHECK(Token_template); const ListNode *params = 0; if (token_stream.lookAhead() == '<') { token_stream.nextToken(); parseTemplateParameterList(params); ADVANCE('>', ">"); } DeclarationAST *declaration = 0; if (!parseDeclaration(declaration)) { reportError(("expected a declaration")); } TemplateDeclarationAST *ast = CreateNode(_M_pool); ast->exported = exported; ast->template_parameters = params; ast->declaration = declaration; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseOperator(OperatorAST *&node) { std::size_t start = token_stream.cursor(); OperatorAST *ast = CreateNode(_M_pool); switch(token_stream.lookAhead()) { case Token_new: case Token_delete: { ast->op = token_stream.cursor(); token_stream.nextToken(); if (token_stream.lookAhead() == '[' && token_stream.lookAhead(1) == ']') { ast->open = token_stream.cursor(); token_stream.nextToken(); ast->close = token_stream.cursor(); token_stream.nextToken(); } } break; case '+': case '-': case '*': case '/': case '%': case '^': case '&': case '|': case '~': case '!': case '=': case '<': case '>': case ',': case Token_assign: case Token_shift: case Token_eq: case Token_not_eq: case Token_leq: case Token_geq: case Token_and: case Token_or: case Token_incr: case Token_decr: case Token_ptrmem: case Token_arrow: ast->op = token_stream.cursor(); token_stream.nextToken(); break; default: if (token_stream.lookAhead() == '(' && token_stream.lookAhead(1) == ')') { ast->op = ast->open = token_stream.cursor(); token_stream.nextToken(); ast->close = token_stream.cursor(); token_stream.nextToken(); } else if (token_stream.lookAhead() == '[' && token_stream.lookAhead(1) == ']') { ast->op = ast->open = token_stream.cursor(); token_stream.nextToken(); ast->close = token_stream.cursor(); token_stream.nextToken(); } else { return false; } } UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseCvQualify(const ListNode *&node) { std::size_t start = token_stream.cursor(); int tk; while (0 != (tk = token_stream.lookAhead()) && (tk == Token_const || tk == Token_volatile)) { node = snoc(node, token_stream.cursor(), _M_pool); token_stream.nextToken(); } return start != token_stream.cursor(); } bool Parser::parseSimpleTypeSpecifier(TypeSpecifierAST *&node, bool onlyIntegral) { std::size_t start = token_stream.cursor(); bool isIntegral = false; bool done = false; const ListNode *integrals = 0; while (!done) { switch(token_stream.lookAhead()) { case Token_char: case Token_wchar_t: case Token_bool: case Token_short: case Token_int: case Token_long: case Token_signed: case Token_unsigned: case Token_float: case Token_double: case Token_void: integrals = snoc(integrals, token_stream.cursor(), _M_pool); isIntegral = true; token_stream.nextToken(); break; default: done = true; } } SimpleTypeSpecifierAST *ast = CreateNode(_M_pool); if (isIntegral) { ast->integrals = integrals; } else if (token_stream.lookAhead() == Token___typeof) { ast->type_of = token_stream.cursor(); token_stream.nextToken(); if (token_stream.lookAhead() == '(') { token_stream.nextToken(); std::size_t saved = token_stream.cursor(); parseTypeId(ast->type_id); if (token_stream.lookAhead() != ')') { ast->type_id = 0; token_stream.rewind((int) saved); parseUnaryExpression(ast->expression); } ADVANCE(')', ")"); } else { parseUnaryExpression(ast->expression); } } else if (onlyIntegral) { token_stream.rewind((int) start); return false; } else { if (!parseName(ast->name, true)) { ast->name = 0; token_stream.rewind((int) start); return false; } } UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parsePtrOperator(PtrOperatorAST *&node) { int tk = token_stream.lookAhead(); if (tk != '&' && tk != '*' && tk != Token_scope && tk != Token_identifier) { return false; } std::size_t start = token_stream.cursor(); PtrOperatorAST *ast = CreateNode(_M_pool); switch (token_stream.lookAhead()) { case '&': case '*': ast->op = token_stream.cursor(); token_stream.nextToken(); break; case Token_scope: case Token_identifier: { if (!parsePtrToMember(ast->mem_ptr)) { token_stream.rewind((int) start); return false; } } break; default: Q_ASSERT(0); break; } parseCvQualify(ast->cv); UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseTemplateArgument(TemplateArgumentAST *&node) { std::size_t start = token_stream.cursor(); TypeIdAST *typeId = 0; ExpressionAST *expr = 0; if (!parseTypeId(typeId) || (token_stream.lookAhead() != ',' && token_stream.lookAhead() != '>')) { token_stream.rewind((int) start); if (!parseLogicalOrExpression(expr, true)) return false; } TemplateArgumentAST *ast = CreateNode(_M_pool); ast->type_id = typeId; ast->expression = expr; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseTypeSpecifier(TypeSpecifierAST *&node) { std::size_t start = token_stream.cursor(); const ListNode *cv = 0; parseCvQualify(cv); TypeSpecifierAST *ast = 0; if (!parseElaboratedTypeSpecifier(ast) && !parseSimpleTypeSpecifier(ast)) { token_stream.rewind((int) start); return false; } parseCvQualify(cv); ast->cv = cv; node = ast; return true; } bool Parser::parseDeclarator(DeclaratorAST *&node) { std::size_t start = token_stream.cursor(); DeclaratorAST *ast = CreateNode(_M_pool); DeclaratorAST *decl = 0; NameAST *declId = 0; PtrOperatorAST *ptrOp = 0; while (parsePtrOperator(ptrOp)) { ast->ptr_ops = snoc(ast->ptr_ops, ptrOp, _M_pool); } if (token_stream.lookAhead() == '(') { token_stream.nextToken(); if (!parseDeclarator(decl)) return false; ast->sub_declarator = decl; CHECK(')'); } else { if (token_stream.lookAhead() == ':') { // unnamed bitfield } else if (parseName(declId, true)) { ast->id = declId; } else { token_stream.rewind((int) start); return false; } if (token_stream.lookAhead() == ':') { token_stream.nextToken(); if (!parseConstantExpression(ast->bit_expression)) { reportError(("Constant expression expected")); } goto update_pos; } } { bool isVector = true; while (token_stream.lookAhead() == '[') { token_stream.nextToken(); ExpressionAST *expr = 0; parseCommaExpression(expr); ADVANCE(']', "]"); ast->array_dimensions = snoc(ast->array_dimensions, expr, _M_pool); isVector = true; } bool skipParen = false; if (token_stream.lookAhead() == Token_identifier && token_stream.lookAhead(1) == '(' && token_stream.lookAhead(2) == '(') { token_stream.nextToken(); token_stream.nextToken(); skipParen = true; } int tok = token_stream.lookAhead(); if (ast->sub_declarator && !(isVector || tok == '(' || tok == ',' || tok == ';' || tok == '=')) { token_stream.rewind((int) start); return false; } std::size_t index = token_stream.cursor(); if (token_stream.lookAhead() == '(') { token_stream.nextToken(); ParameterDeclarationClauseAST *params = 0; if (!parseParameterDeclarationClause(params)) { token_stream.rewind((int) index); goto update_pos; } ast->parameter_declaration_clause = params; if (token_stream.lookAhead() != ')') { token_stream.rewind((int) index); goto update_pos; } token_stream.nextToken(); // skip ')' parseCvQualify(ast->fun_cv); parseExceptionSpecification(ast->exception_spec); if (token_stream.lookAhead() == Token___attribute__) { parse_Attribute__(); } } if (skipParen) { if (token_stream.lookAhead() != ')') { reportError(("')' expected")); } else token_stream.nextToken(); } } update_pos: UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseAbstractDeclarator(DeclaratorAST *&node) { std::size_t start = token_stream.cursor(); DeclaratorAST *ast = CreateNode(_M_pool); DeclaratorAST *decl = 0; PtrOperatorAST *ptrOp = 0; while (parsePtrOperator(ptrOp)) { ast->ptr_ops = snoc(ast->ptr_ops, ptrOp, _M_pool); } int index = (int) token_stream.cursor(); if (token_stream.lookAhead() == '(') { token_stream.nextToken(); if (!parseAbstractDeclarator(decl)) { token_stream.rewind((int) index); goto label1; } ast->sub_declarator = decl; if (token_stream.lookAhead() != ')') { token_stream.rewind((int) start); return false; } token_stream.nextToken(); } else if (token_stream.lookAhead() == ':') { token_stream.nextToken(); if (!parseConstantExpression(ast->bit_expression)) { ast->bit_expression = 0; reportError(("Constant expression expected")); } goto update_pos; } label1: { bool isVector = true; while (token_stream.lookAhead() == '[') { token_stream.nextToken(); ExpressionAST *expr = 0; parseCommaExpression(expr); ADVANCE(']', "]"); ast->array_dimensions = snoc(ast->array_dimensions, expr, _M_pool); isVector = true; } int tok = token_stream.lookAhead(); if (ast->sub_declarator && !(isVector || tok == '(' || tok == ',' || tok == ';' || tok == '=')) { token_stream.rewind((int) start); return false; } int index = (int) token_stream.cursor(); if (token_stream.lookAhead() == '(') { token_stream.nextToken(); ParameterDeclarationClauseAST *params = 0; if (!parseParameterDeclarationClause(params)) { token_stream.rewind((int) index); goto update_pos; } ast->parameter_declaration_clause = params; if (token_stream.lookAhead() != ')') { token_stream.rewind((int) index); goto update_pos; } token_stream.nextToken(); // skip ')' parseCvQualify(ast->fun_cv); parseExceptionSpecification(ast->exception_spec); } } update_pos: if (token_stream.cursor() == start) return false; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseEnumSpecifier(TypeSpecifierAST *&node) { std::size_t start = token_stream.cursor(); CHECK(Token_enum); NameAST *name = 0; parseName(name); if (token_stream.lookAhead() != '{') { token_stream.rewind((int) start); return false; } token_stream.nextToken(); EnumSpecifierAST *ast = CreateNode(_M_pool); ast->name = name; EnumeratorAST *enumerator = 0; if (parseEnumerator(enumerator)) { ast->enumerators = snoc(ast->enumerators, enumerator, _M_pool); while (token_stream.lookAhead() == ',') { token_stream.nextToken(); if (!parseEnumerator(enumerator)) { //reportError(("Enumerator expected")); break; } ast->enumerators = snoc(ast->enumerators, enumerator, _M_pool); } } ADVANCE_NR('}', "}"); UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseTemplateParameterList(const ListNode *&node) { TemplateParameterAST *param = 0; if (!parseTemplateParameter(param)) return false; node = snoc(node, param, _M_pool); while (token_stream.lookAhead() == ',') { token_stream.nextToken(); if (!parseTemplateParameter(param)) { syntaxError(); break; } else { node = snoc(node, param, _M_pool); } } return true; } bool Parser::parseTemplateParameter(TemplateParameterAST *&node) { std::size_t start = token_stream.cursor(); TemplateParameterAST *ast = CreateNode(_M_pool); int tk = token_stream.lookAhead(); if ((tk == Token_class || tk == Token_typename || tk == Token_template) && parseTypeParameter(ast->type_parameter)) { // nothing to do } else if (!parseParameterDeclaration(ast->parameter_declaration)) return false; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseTypeParameter(TypeParameterAST *&node) { std::size_t start = token_stream.cursor(); TypeParameterAST *ast = CreateNode(_M_pool); ast->type = start; switch(token_stream.lookAhead()) { case Token_class: case Token_typename: { token_stream.nextToken(); // skip class // parse optional name if(parseName(ast->name, true)) { if (token_stream.lookAhead() == '=') { token_stream.nextToken(); if(!parseTypeId(ast->type_id)) { //syntaxError(); token_stream.rewind((int) start); return false; } } else if (token_stream.lookAhead() != ',' && token_stream.lookAhead() != '>') { token_stream.rewind((int) start); return false; } } } break; case Token_template: { token_stream.nextToken(); // skip template ADVANCE('<', "<"); if (!parseTemplateParameterList(ast->template_parameters)) return false; ADVANCE('>', ">"); if (token_stream.lookAhead() == Token_class) token_stream.nextToken(); // parse optional name if (parseName(ast->name, true)) { if (token_stream.lookAhead() == '=') { token_stream.nextToken(); if (!parseTypeId(ast->type_id)) { syntaxError(); return false; } } } if (token_stream.lookAhead() == '=') { token_stream.nextToken(); parseName(ast->template_name, true); } } break; default: return false; } // end switch UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseStorageClassSpecifier(const ListNode *&node) { std::size_t start = token_stream.cursor(); int tk; while (0 != (tk = token_stream.lookAhead()) && (tk == Token_friend || tk == Token_auto || tk == Token_register || tk == Token_static || tk == Token_extern || tk == Token_mutable)) { node = snoc(node, token_stream.cursor(), _M_pool); token_stream.nextToken(); } return start != token_stream.cursor(); } bool Parser::parseFunctionSpecifier(const ListNode *&node) { std::size_t start = token_stream.cursor(); int tk; while (0 != (tk = token_stream.lookAhead()) && (tk == Token_inline || tk == Token_virtual || tk == Token_explicit || tk == Token_Q_INVOKABLE)) { node = snoc(node, token_stream.cursor(), _M_pool); token_stream.nextToken(); } return start != token_stream.cursor(); } bool Parser::parseTypeId(TypeIdAST *&node) { /// @todo implement the AST for typeId std::size_t start = token_stream.cursor(); TypeSpecifierAST *spec = 0; if (!parseTypeSpecifier(spec)) { token_stream.rewind((int) start); return false; } DeclaratorAST *decl = 0; parseAbstractDeclarator(decl); TypeIdAST *ast = CreateNode(_M_pool); ast->type_specifier = spec; ast->declarator = decl; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseInitDeclaratorList(const ListNode *&node) { InitDeclaratorAST *decl = 0; if (!parseInitDeclarator(decl)) return false; node = snoc(node, decl, _M_pool); while (token_stream.lookAhead() == ',') { token_stream.nextToken(); if (!parseInitDeclarator(decl)) { syntaxError(); break; } node = snoc(node, decl, _M_pool); } return true; } bool Parser::parseParameterDeclarationClause(ParameterDeclarationClauseAST *&node) { std::size_t start = token_stream.cursor(); ParameterDeclarationClauseAST *ast = CreateNode(_M_pool); if (!parseParameterDeclarationList(ast->parameter_declarations)) { if (token_stream.lookAhead() == ')') goto good; if (token_stream.lookAhead() == Token_ellipsis && token_stream.lookAhead(1) == ')') { ast->ellipsis = token_stream.cursor(); goto good; } return false; } good: if (token_stream.lookAhead() == Token_ellipsis) { ast->ellipsis = token_stream.cursor(); token_stream.nextToken(); } /// @todo add ellipsis UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseParameterDeclarationList(const ListNode *&node) { std::size_t start = token_stream.cursor(); ParameterDeclarationAST *param = 0; if (!parseParameterDeclaration(param)) { token_stream.rewind((int) start); return false; } node = snoc(node, param, _M_pool); while (token_stream.lookAhead() == ',') { token_stream.nextToken(); if (token_stream.lookAhead() == Token_ellipsis) break; if (!parseParameterDeclaration(param)) { token_stream.rewind((int) start); return false; } node = snoc(node, param, _M_pool); } return true; } bool Parser::parseParameterDeclaration(ParameterDeclarationAST *&node) { std::size_t start = token_stream.cursor(); const ListNode *storage = 0; parseStorageClassSpecifier(storage); // parse decl spec TypeSpecifierAST *spec = 0; if (!parseTypeSpecifier(spec)) { token_stream.rewind((int) start); return false; } int index = (int) token_stream.cursor(); DeclaratorAST *decl = 0; if (!parseDeclarator(decl)) { token_stream.rewind((int) index); // try with abstract declarator parseAbstractDeclarator(decl); } ExpressionAST *expr = 0; if (token_stream.lookAhead() == '=') { token_stream.nextToken(); if (!parseLogicalOrExpression(expr,true)) { //reportError(("Expression expected")); } } ParameterDeclarationAST *ast = CreateNode(_M_pool); ast->type_specifier = spec; ast->declarator = decl; ast->expression = expr; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parse_Attribute__() { token_stream.nextToken(); ADVANCE('(', "("); ExpressionAST *expr = 0; parseExpression(expr); if (token_stream.lookAhead() != ')') { reportError(("')' expected")); return false; } else { token_stream.nextToken(); } return true; } QString Parser::tokenText(AST *ast) const { if (ast == 0) return QString(); int start_token = ast->start_token; int end_token = ast->end_token; Token const &tk = token_stream.token (start_token); Token const &end_tk = token_stream.token(end_token); return QString::fromLatin1 (&tk.text[tk.position],(int) (end_tk.position - tk.position)).trimmed(); } bool Parser::parseForwardDeclarationSpecifier(TypeSpecifierAST *&node) { std::size_t start = token_stream.cursor(); int kind = token_stream.lookAhead(); if (kind != Token_class && kind != Token_struct && kind != Token_union) return false; std::size_t class_key = token_stream.cursor(); token_stream.nextToken(); NameAST *name = 0; if (!parseName(name, false)) { token_stream.rewind((int) start); return false; } BaseClauseAST *bases = 0; if (token_stream.lookAhead() == ':') { if (!parseBaseClause(bases)) { token_stream.rewind((int) start); return false; } } if (token_stream.lookAhead() != ';') { token_stream.rewind((int) start); return false; } ForwardDeclarationSpecifierAST *ast = CreateNode(_M_pool); ast->class_key = class_key; ast->name = name; ast->base_clause = bases; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseClassSpecifier(TypeSpecifierAST *&node) { std::size_t start = token_stream.cursor(); int kind = token_stream.lookAhead(); if (kind != Token_class && kind != Token_struct && kind != Token_union) return false; std::size_t class_key = token_stream.cursor(); token_stream.nextToken(); WinDeclSpecAST *winDeclSpec = 0; parseWinDeclSpec(winDeclSpec); if (token_stream.lookAhead() == Token___attribute__) { parse_Attribute__(); } while (token_stream.lookAhead() == Token_identifier && token_stream.lookAhead(1) == Token_identifier) { token_stream.nextToken(); } NameAST *name = 0; parseName(name, true); BaseClauseAST *bases = 0; if (token_stream.lookAhead() == ':') { if (!parseBaseClause(bases)) { skipUntil('{'); } } if (token_stream.lookAhead() != '{') { token_stream.rewind((int) start); return false; } ADVANCE('{', "{"); ClassSpecifierAST *ast = CreateNode(_M_pool); ast->win_decl_specifiers = winDeclSpec; ast->class_key = class_key; ast->name = name; ast->base_clause = bases; while (token_stream.lookAhead()) { if (token_stream.lookAhead() == '}') break; std::size_t startDecl = token_stream.cursor(); DeclarationAST *memSpec = 0; if (!parseMemberSpecification(memSpec)) { if (startDecl == token_stream.cursor()) token_stream.nextToken(); // skip at least one token skipUntilDeclaration(); } else ast->member_specs = snoc(ast->member_specs, memSpec, _M_pool); } ADVANCE_NR('}', "}"); UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseAccessSpecifier(DeclarationAST *&node) { std::size_t start = token_stream.cursor(); const ListNode *specs = 0; bool done = false; while (!done) { switch(token_stream.lookAhead()) { case Token_signals: case Token_slots: case Token_k_dcop: case Token_k_dcop_signals: case Token_public: case Token_protected: case Token_private: specs = snoc(specs, token_stream.cursor(), _M_pool); token_stream.nextToken(); break; default: done = true; break; } } if (!specs) return false; ADVANCE(':', ":"); AccessSpecifierAST *ast = CreateNode(_M_pool); ast->specs = specs; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseMemberSpecification(DeclarationAST *&node) { std::size_t start = token_stream.cursor(); if (token_stream.lookAhead() == ';') { token_stream.nextToken(); return true; } else if (token_stream.lookAhead() == Token_Q_OBJECT || token_stream.lookAhead() == Token_K_DCOP) { token_stream.nextToken(); return true; } else if (parseTypedef(node)) { return true; } else if (parseUsing(node)) { return true; } else if (parseTemplateDeclaration(node)) { return true; } else if (parseAccessSpecifier(node)) { return true; } else if (parseQ_PROPERTY(node)) { return true; } else if (parseQ_ENUMS(node)) { return true; } token_stream.rewind((int) start); const ListNode *cv = 0; parseCvQualify(cv); const ListNode *storageSpec = 0; parseStorageClassSpecifier(storageSpec); parseCvQualify(cv); TypeSpecifierAST *spec = 0; if (parseEnumSpecifier(spec) || parseClassSpecifier(spec)) { parseCvQualify(cv); spec->cv = cv; const ListNode *declarators = 0; parseInitDeclaratorList(declarators); ADVANCE(';', ";"); SimpleDeclarationAST *ast = CreateNode(_M_pool); ast->type_specifier = spec; ast->init_declarators = declarators; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } token_stream.rewind((int) start); return parseDeclarationInternal(node); } bool Parser::parseCtorInitializer(CtorInitializerAST *&node) { std::size_t start = token_stream.cursor(); CHECK(':'); CtorInitializerAST *ast = CreateNode(_M_pool); ast->colon = start; if (!parseMemInitializerList(ast->member_initializers)) { reportError(("Member initializers expected")); } UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseElaboratedTypeSpecifier(TypeSpecifierAST *&node) { std::size_t start = token_stream.cursor(); int tk = token_stream.lookAhead(); if (tk == Token_class || tk == Token_struct || tk == Token_union || tk == Token_enum || tk == Token_typename) { std::size_t type = token_stream.cursor(); token_stream.nextToken(); NameAST *name = 0; if (parseName(name, true)) { ElaboratedTypeSpecifierAST *ast = CreateNode(_M_pool); ast->type = type; ast->name = name; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } } token_stream.rewind((int) start); return false; } bool Parser::parseExceptionSpecification(ExceptionSpecificationAST *&node) { std::size_t start = token_stream.cursor(); CHECK(Token_throw); ADVANCE('(', "("); ExceptionSpecificationAST *ast = CreateNode(_M_pool); if (token_stream.lookAhead() == Token_ellipsis) { ast->ellipsis = token_stream.cursor(); token_stream.nextToken(); } else { parseTypeIdList(ast->type_ids); } ADVANCE(')', ")"); UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseEnumerator(EnumeratorAST *&node) { std::size_t start = token_stream.cursor(); CHECK(Token_identifier); std::size_t id = token_stream.cursor() - 1; EnumeratorAST *ast = CreateNode(_M_pool); ast->id = id; if (token_stream.lookAhead() == '=') { token_stream.nextToken(); if (!parseConstantExpression(ast->expression)) { reportError(("Constant expression expected")); } } UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseInitDeclarator(InitDeclaratorAST *&node) { std::size_t start = token_stream.cursor(); DeclaratorAST *decl = 0; if (!parseDeclarator(decl)) { return false; } if (token_stream.lookAhead(0) == Token_asm) { token_stream.nextToken(); skip('(', ')'); token_stream.nextToken(); } InitializerAST *init = 0; parseInitializer(init); InitDeclaratorAST *ast = CreateNode(_M_pool); ast->declarator = decl; ast->initializer = init; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseBaseClause(BaseClauseAST *&node) { std::size_t start = token_stream.cursor(); CHECK(':'); BaseSpecifierAST *baseSpec = 0; if (!parseBaseSpecifier(baseSpec)) return false; BaseClauseAST *ast = CreateNode(_M_pool); ast->base_specifiers = snoc(ast->base_specifiers, baseSpec, _M_pool); while (token_stream.lookAhead() == ',') { token_stream.nextToken(); if (!parseBaseSpecifier(baseSpec)) { reportError(("Base class specifier expected")); break; } ast->base_specifiers = snoc(ast->base_specifiers, baseSpec, _M_pool); } UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseInitializer(InitializerAST *&node) { std::size_t start = token_stream.cursor(); int tk = token_stream.lookAhead(); if (tk != '=' && tk != '(') return false; InitializerAST *ast = CreateNode(_M_pool); if (tk == '=') { token_stream.nextToken(); if (!parseInitializerClause(ast->initializer_clause)) { reportError(("Initializer clause expected")); } } else if (tk == '(') { token_stream.nextToken(); parseCommaExpression(ast->expression); CHECK(')'); } UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseMemInitializerList(const ListNode *&node) { MemInitializerAST *init = 0; if (!parseMemInitializer(init)) return false; node = snoc(node, init, _M_pool); while (token_stream.lookAhead() == ',') { token_stream.nextToken(); if (!parseMemInitializer(init)) break; node = snoc(node, init, _M_pool); } return true; } bool Parser::parseMemInitializer(MemInitializerAST *&node) { std::size_t start = token_stream.cursor(); NameAST *initId = 0; if (!parseName(initId, true)) { reportError(("Identifier expected")); return false; } ADVANCE('(', "("); ExpressionAST *expr = 0; parseCommaExpression(expr); ADVANCE(')', ")"); MemInitializerAST *ast = CreateNode(_M_pool); ast->initializer_id = initId; ast->expression = expr; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseTypeIdList(const ListNode *&node) { TypeIdAST *typeId = 0; if (!parseTypeId(typeId)) return false; node = snoc(node, typeId, _M_pool); while (token_stream.lookAhead() == ',') { token_stream.nextToken(); if (parseTypeId(typeId)) { node = snoc(node, typeId, _M_pool); } else { reportError(("Type id expected")); break; } } return true; } bool Parser::parseBaseSpecifier(BaseSpecifierAST *&node) { std::size_t start = token_stream.cursor(); BaseSpecifierAST *ast = CreateNode(_M_pool); if (token_stream.lookAhead() == Token_virtual) { ast->virt = token_stream.cursor(); token_stream.nextToken(); int tk = token_stream.lookAhead(); if (tk == Token_public || tk == Token_protected || tk == Token_private) { ast->access_specifier = token_stream.cursor(); token_stream.nextToken(); } } else { int tk = token_stream.lookAhead(); if (tk == Token_public || tk == Token_protected || tk == Token_private) { ast->access_specifier = token_stream.cursor(); token_stream.nextToken(); } if (token_stream.lookAhead() == Token_virtual) { ast->virt = token_stream.cursor(); token_stream.nextToken(); } } if (!parseName(ast->name, true)) reportError(("Class name expected")); UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseInitializerClause(InitializerClauseAST *&node) { std::size_t start = token_stream.cursor(); InitializerClauseAST *ast = CreateNode(_M_pool); if (token_stream.lookAhead() == '{') { #if defined(__GNUC__) #warning "implement me" #endif if (skip('{','}')) token_stream.nextToken(); else reportError(("} missing")); } else { if (!parseAssignmentExpression(ast->expression)) { //reportError(("Expression expected")); } } UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parsePtrToMember(PtrToMemberAST *&node) { #if defined(__GNUC__) #warning "implemente me (AST)" #endif std::size_t start = token_stream.cursor(); std::size_t global_scope = 0; if (token_stream.lookAhead() == Token_scope) { global_scope = token_stream.cursor(); token_stream.nextToken(); } UnqualifiedNameAST *name = 0; while (token_stream.lookAhead() == Token_identifier) { if (!parseUnqualifiedName(name)) break; if (token_stream.lookAhead() == Token_scope && token_stream.lookAhead(1) == '*') { token_stream.nextToken(); token_stream.nextToken(); PtrToMemberAST *ast = CreateNode(_M_pool); UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } if (token_stream.lookAhead() == Token_scope) token_stream.nextToken(); } token_stream.rewind((int) start); return false; } bool Parser::parseUnqualifiedName(UnqualifiedNameAST *&node, bool parseTemplateId) { std::size_t start = token_stream.cursor(); std::size_t tilde = 0; std::size_t id = 0; OperatorFunctionIdAST *operator_id = 0; if (token_stream.lookAhead() == Token_identifier) { id = token_stream.cursor(); token_stream.nextToken(); } else if (token_stream.lookAhead() == '~' && token_stream.lookAhead(1) == Token_identifier) { tilde = token_stream.cursor(); token_stream.nextToken(); // skip ~ id = token_stream.cursor(); token_stream.nextToken(); // skip classname } else if (token_stream.lookAhead() == Token_operator) { if (!parseOperatorFunctionId(operator_id)) return false; } else { return false; } UnqualifiedNameAST *ast = CreateNode(_M_pool); ast->tilde = tilde; ast->id = id; ast->operator_id = operator_id; if (parseTemplateId && !tilde) { std::size_t index = token_stream.cursor(); if (token_stream.lookAhead() == '<') { token_stream.nextToken(); // optional template arguments parseTemplateArgumentList(ast->template_arguments); if (token_stream.lookAhead() == '>') { token_stream.nextToken(); } else { ast->template_arguments = 0; token_stream.rewind((int) index); } } } UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseStringLiteral(StringLiteralAST *&node) { std::size_t start = token_stream.cursor(); if (token_stream.lookAhead() != Token_string_literal) return false; StringLiteralAST *ast = CreateNode(_M_pool); while (token_stream.lookAhead() == Token_string_literal) { ast->literals = snoc(ast->literals, token_stream.cursor(), _M_pool); token_stream.nextToken(); } UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseExpressionStatement(StatementAST *&node) { std::size_t start = token_stream.cursor(); ExpressionAST *expr = 0; parseCommaExpression(expr); ADVANCE(';', ";"); ExpressionStatementAST *ast = CreateNode(_M_pool); ast->expression = expr; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseStatement(StatementAST *&node) { std::size_t start = token_stream.cursor(); switch(token_stream.lookAhead()) { case Token_while: return parseWhileStatement(node); case Token_do: return parseDoStatement(node); case Token_for: return parseForStatement(node); case Token_if: return parseIfStatement(node); case Token_switch: return parseSwitchStatement(node); case Token_try: return parseTryBlockStatement(node); case Token_case: case Token_default: return parseLabeledStatement(node); case Token_break: case Token_continue: #if defined(__GNUC__) #warning "implement me" #endif token_stream.nextToken(); ADVANCE(';', ";"); return true; case Token_goto: #if defined(__GNUC__) #warning "implement me" #endif token_stream.nextToken(); ADVANCE(Token_identifier, "identifier"); ADVANCE(';', ";"); return true; case Token_return: { token_stream.nextToken(); ExpressionAST *expr = 0; parseCommaExpression(expr); ADVANCE(';', ";"); ReturnStatementAST *ast = CreateNode(_M_pool); ast->expression = expr; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } return true; case '{': return parseCompoundStatement(node); case Token_identifier: if (parseLabeledStatement(node)) return true; break; } return parseExpressionOrDeclarationStatement(node); } bool Parser::parseExpressionOrDeclarationStatement(StatementAST *&node) { bool blocked = block_errors(true); std::size_t start = token_stream.cursor(); StatementAST *decl_ast = 0; bool maybe_amb = parseDeclarationStatement(decl_ast); maybe_amb &= token_stream.kind(token_stream.cursor() - 1) == ';'; std::size_t end = token_stream.cursor(); token_stream.rewind((int) start); StatementAST *expr_ast = 0; maybe_amb &= parseExpressionStatement(expr_ast); maybe_amb &= token_stream.kind(token_stream.cursor() - 1) == ';'; if (maybe_amb) { Q_ASSERT(decl_ast != 0 && expr_ast != 0); ExpressionOrDeclarationStatementAST *ast = CreateNode(_M_pool); ast->declaration = decl_ast; ast->expression = expr_ast; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } else { token_stream.rewind((int) std::max(end, token_stream.cursor())); node = decl_ast; if (!node) node = expr_ast; } block_errors(blocked); if (!node) syntaxError(); return node != 0; } bool Parser::parseCondition(ConditionAST *&node, bool initRequired) { std::size_t start = token_stream.cursor(); ConditionAST *ast = CreateNode(_M_pool); TypeSpecifierAST *spec = 0; if (parseTypeSpecifier(spec)) { ast->type_specifier = spec; std::size_t declarator_start = token_stream.cursor(); DeclaratorAST *decl = 0; if (!parseDeclarator(decl)) { token_stream.rewind((int) declarator_start); if (!initRequired && !parseAbstractDeclarator(decl)) decl = 0; } if (decl && (!initRequired || token_stream.lookAhead() == '=')) { ast->declarator = decl; if (token_stream.lookAhead() == '=') { token_stream.nextToken(); parseExpression(ast->expression); } UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } } token_stream.rewind((int) start); if (!parseCommaExpression(ast->expression)) return false; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseWhileStatement(StatementAST *&node) { std::size_t start = token_stream.cursor(); ADVANCE(Token_while, "while"); ADVANCE('(' , "("); ConditionAST *cond = 0; if (!parseCondition(cond)) { reportError(("condition expected")); return false; } ADVANCE(')', ")"); StatementAST *body = 0; if (!parseStatement(body)) { reportError(("statement expected")); return false; } WhileStatementAST *ast = CreateNode(_M_pool); ast->condition = cond; ast->statement = body; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseDoStatement(StatementAST *&node) { std::size_t start = token_stream.cursor(); ADVANCE(Token_do, "do"); StatementAST *body = 0; if (!parseStatement(body)) { reportError(("statement expected")); //return false; } ADVANCE_NR(Token_while, "while"); ADVANCE_NR('(' , "("); ExpressionAST *expr = 0; if (!parseCommaExpression(expr)) { reportError(("expression expected")); //return false; } ADVANCE_NR(')', ")"); ADVANCE_NR(';', ";"); DoStatementAST *ast = CreateNode(_M_pool); ast->statement = body; ast->expression = expr; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseForStatement(StatementAST *&node) { std::size_t start = token_stream.cursor(); ADVANCE(Token_for, "for"); ADVANCE('(', "("); StatementAST *init = 0; if (!parseForInitStatement(init)) { reportError(("for initialization expected")); return false; } ConditionAST *cond = 0; parseCondition(cond); ADVANCE(';', ";"); ExpressionAST *expr = 0; parseCommaExpression(expr); ADVANCE(')', ")"); StatementAST *body = 0; if (!parseStatement(body)) return false; ForStatementAST *ast = CreateNode(_M_pool); ast->init_statement = init; ast->condition = cond; ast->expression = expr; ast->statement = body; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseForInitStatement(StatementAST *&node) { if (parseDeclarationStatement(node)) return true; return parseExpressionStatement(node); } bool Parser::parseCompoundStatement(StatementAST *&node) { std::size_t start = token_stream.cursor(); CHECK('{'); CompoundStatementAST *ast = CreateNode(_M_pool); while (token_stream.lookAhead()) { if (token_stream.lookAhead() == '}') break; std::size_t startStmt = token_stream.cursor(); StatementAST *stmt = 0; if (!parseStatement(stmt)) { if (startStmt == token_stream.cursor()) token_stream.nextToken(); skipUntilStatement(); } else { ast->statements = snoc(ast->statements, stmt, _M_pool); } } ADVANCE_NR('}', "}"); UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseIfStatement(StatementAST *&node) { std::size_t start = token_stream.cursor(); ADVANCE(Token_if, "if"); ADVANCE('(' , "("); IfStatementAST *ast = CreateNode(_M_pool); ConditionAST *cond = 0; if (!parseCondition(cond)) { reportError(("condition expected")); return false; } ADVANCE(')', ")"); StatementAST *stmt = 0; if (!parseStatement(stmt)) { reportError(("statement expected")); return false; } ast->condition = cond; ast->statement = stmt; if (token_stream.lookAhead() == Token_else) { token_stream.nextToken(); if (!parseStatement(ast->else_statement)) { reportError(("statement expected")); return false; } } UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseSwitchStatement(StatementAST *&node) { std::size_t start = token_stream.cursor(); ADVANCE(Token_switch, "switch"); ADVANCE('(' , "("); ConditionAST *cond = 0; if (!parseCondition(cond)) { reportError(("condition expected")); return false; } ADVANCE(')', ")"); StatementAST *stmt = 0; if (!parseCompoundStatement(stmt)) { syntaxError(); return false; } SwitchStatementAST *ast = CreateNode(_M_pool); ast->condition = cond; ast->statement = stmt; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseLabeledStatement(StatementAST *&node) { switch(token_stream.lookAhead()) { case Token_identifier: case Token_default: if (token_stream.lookAhead(1) == ':') { token_stream.nextToken(); token_stream.nextToken(); StatementAST *stmt = 0; if (parseStatement(stmt)) { node = stmt; return true; } } break; case Token_case: { token_stream.nextToken(); ExpressionAST *expr = 0; if (!parseConstantExpression(expr)) { reportError(("expression expected")); } else if (token_stream.lookAhead() == Token_ellipsis) { token_stream.nextToken(); ExpressionAST *expr2 = 0; if (!parseConstantExpression(expr2)) { reportError(("expression expected")); } } ADVANCE(':', ":"); StatementAST *stmt = 0; if (parseStatement(stmt)) { node = stmt; return true; } } break; } return false; } bool Parser::parseBlockDeclaration(DeclarationAST *&node) { switch(token_stream.lookAhead()) { case Token_typedef: return parseTypedef(node); case Token_using: return parseUsing(node); case Token_asm: return parseAsmDefinition(node); case Token_namespace: return parseNamespaceAliasDefinition(node); } std::size_t start = token_stream.cursor(); const ListNode *cv = 0; parseCvQualify(cv); const ListNode *storageSpec = 0; parseStorageClassSpecifier(storageSpec); parseCvQualify(cv); TypeSpecifierAST *spec = 0; if (!parseTypeSpecifierOrClassSpec(spec)) { // replace with simpleTypeSpecifier?!?! token_stream.rewind((int) start); return false; } parseCvQualify(cv); spec->cv = cv; const ListNode *declarators = 0; parseInitDeclaratorList(declarators); if (token_stream.lookAhead() != ';') { token_stream.rewind((int) start); return false; } token_stream.nextToken(); SimpleDeclarationAST *ast = CreateNode(_M_pool); ast->type_specifier = spec; ast->init_declarators = declarators; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseNamespaceAliasDefinition(DeclarationAST *&node) { std::size_t start = token_stream.cursor(); CHECK(Token_namespace); NamespaceAliasDefinitionAST *ast = CreateNode(_M_pool); ADVANCE(Token_identifier, "identifier"); ast->namespace_name = token_stream.cursor() - 1; ADVANCE('=', "="); if (!parseName(ast->alias_name)) { reportError(("Namespace name expected")); } ADVANCE(';', ";"); UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseDeclarationStatement(StatementAST *&node) { std::size_t start = token_stream.cursor(); DeclarationAST *decl = 0; if (!parseBlockDeclaration(decl)) return false; DeclarationStatementAST *ast = CreateNode(_M_pool); ast->declaration = decl; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseDeclarationInternal(DeclarationAST *&node) { std::size_t start = token_stream.cursor(); // that is for the case '__declspec(dllexport) int ...' or // '__declspec(dllexport) inline int ...', etc. WinDeclSpecAST *winDeclSpec = 0; parseWinDeclSpec(winDeclSpec); const ListNode *funSpec = 0; bool hasFunSpec = parseFunctionSpecifier(funSpec); const ListNode *cv = 0; parseCvQualify(cv); const ListNode *storageSpec = 0; bool hasStorageSpec = parseStorageClassSpecifier(storageSpec); if (hasStorageSpec && !hasFunSpec) hasFunSpec = parseFunctionSpecifier(funSpec); // that is for the case 'friend __declspec(dllexport) ....' parseWinDeclSpec(winDeclSpec); if (!cv) parseCvQualify(cv); int index = (int) token_stream.cursor(); NameAST *name = 0; if (parseName(name, true) && token_stream.lookAhead() == '(') { // no type specifier, maybe a constructor or a cast operator?? token_stream.rewind((int) index); InitDeclaratorAST *declarator = 0; if (parseInitDeclarator(declarator)) { switch(token_stream.lookAhead()) { case ';': { token_stream.nextToken(); SimpleDeclarationAST *ast = CreateNode(_M_pool); ast->storage_specifiers = storageSpec; ast->function_specifiers = funSpec; ast->init_declarators = snoc(ast->init_declarators, declarator, _M_pool); UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } return true; case ':': { CtorInitializerAST *ctorInit = 0; StatementAST *funBody = 0; if (parseCtorInitializer(ctorInit) && parseFunctionBody(funBody)) { FunctionDefinitionAST *ast = CreateNode(_M_pool); ast->storage_specifiers = storageSpec; ast->function_specifiers = funSpec; ast->init_declarator = declarator; ast->function_body = funBody; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } } break; case '{': { StatementAST *funBody = 0; if (parseFunctionBody(funBody)) { FunctionDefinitionAST *ast = CreateNode(_M_pool); ast->storage_specifiers = storageSpec; ast->function_specifiers = funSpec; ast->init_declarator = declarator; ast->function_body = funBody; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } } break; case '(': case '[': // ops!! it seems a declarator goto start_decl; break; } } } start_decl: token_stream.rewind((int) index); if (token_stream.lookAhead() == Token_const && token_stream.lookAhead(1) == Token_identifier && token_stream.lookAhead(2) == '=') { // constant definition token_stream.nextToken(); // skip const const ListNode *declarators = 0; if (!parseInitDeclaratorList(declarators)) { syntaxError(); return false; } ADVANCE(';', ";"); #if defined(__GNUC__) #warning "mark the ast as constant" #endif SimpleDeclarationAST *ast = CreateNode(_M_pool); ast->init_declarators = declarators; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } TypeSpecifierAST *spec = 0; if (parseTypeSpecifier(spec)) { Q_ASSERT(spec != 0); if (!hasFunSpec) parseFunctionSpecifier(funSpec); // e.g. "void inline" spec->cv = cv; const ListNode *declarators = 0; InitDeclaratorAST *decl = 0; int startDeclarator = (int) token_stream.cursor(); bool maybeFunctionDefinition = false; if (token_stream.lookAhead() != ';') { if (parseInitDeclarator(decl) && token_stream.lookAhead() == '{') { // function definition maybeFunctionDefinition = true; } else { token_stream.rewind((int) startDeclarator); if (!parseInitDeclaratorList(declarators)) { syntaxError(); return false; } } } switch(token_stream.lookAhead()) { case ';': { token_stream.nextToken(); SimpleDeclarationAST *ast = CreateNode(_M_pool); ast->storage_specifiers = storageSpec; ast->function_specifiers = funSpec; ast->type_specifier = spec; ast->win_decl_specifiers = winDeclSpec; ast->init_declarators = declarators; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } return true; case '{': { if (!maybeFunctionDefinition) { syntaxError(); return false; } StatementAST *funBody = 0; if (parseFunctionBody(funBody)) { FunctionDefinitionAST *ast = CreateNode(_M_pool); ast->win_decl_specifiers = winDeclSpec; ast->storage_specifiers = storageSpec; ast->function_specifiers = funSpec; ast->type_specifier = spec; ast->init_declarator = decl; ast->function_body = funBody; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } } break; } // end switch } syntaxError(); return false; } bool Parser::skipFunctionBody(StatementAST *&) { #if defined(__GNUC__) #warning "Parser::skipFunctionBody() -- implement me" #endif Q_ASSERT(0); // ### not implemented return 0; } bool Parser::parseFunctionBody(StatementAST *&node) { if (control->skipFunctionBody()) return skipFunctionBody(node); return parseCompoundStatement(node); } bool Parser::parseTypeSpecifierOrClassSpec(TypeSpecifierAST *&node) { if (parseClassSpecifier(node)) return true; else if (parseEnumSpecifier(node)) return true; else if (parseTypeSpecifier(node)) return true; return false; } bool Parser::parseTryBlockStatement(StatementAST *&node) { #if defined(__GNUC__) #warning "implement me" #endif CHECK(Token_try); StatementAST *stmt = 0; if (!parseCompoundStatement(stmt)) { syntaxError(); return false; } if (token_stream.lookAhead() != Token_catch) { reportError(("catch expected")); return false; } while (token_stream.lookAhead() == Token_catch) { token_stream.nextToken(); ADVANCE('(', "("); ConditionAST *cond = 0; if (token_stream.lookAhead() == Token_ellipsis) { token_stream.nextToken(); } else if (!parseCondition(cond, false)) { reportError(("condition expected")); return false; } ADVANCE(')', ")"); StatementAST *body = 0; if (!parseCompoundStatement(body)) { syntaxError(); return false; } } node = stmt; return true; } bool Parser::parsePrimaryExpression(ExpressionAST *&node) { std::size_t start = token_stream.cursor(); PrimaryExpressionAST *ast = CreateNode(_M_pool); switch(token_stream.lookAhead()) { case Token_string_literal: parseStringLiteral(ast->literal); break; case Token_number_literal: case Token_char_literal: case Token_true: case Token_false: case Token_this: ast->token = token_stream.cursor(); token_stream.nextToken(); break; case '(': token_stream.nextToken(); if (token_stream.lookAhead() == '{') { if (!parseCompoundStatement(ast->expression_statement)) return false; } else { if (!parseExpression(ast->sub_expression)) return false; } CHECK(')'); break; default: if (!parseName(ast->name)) return false; break; } UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } /* postfix-expression-internal: [ expression ] ( expression-list [opt] ) (.|->) template [opt] id-expression (.|->) pseudo-destructor-name ++ -- */ bool Parser::parsePostfixExpressionInternal(ExpressionAST *&node) { std::size_t start = token_stream.cursor(); switch (token_stream.lookAhead()) { case '[': { token_stream.nextToken(); ExpressionAST *expr = 0; parseExpression(expr); CHECK(']'); SubscriptExpressionAST *ast = CreateNode(_M_pool); ast->subscript = expr; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } return true; case '(': { token_stream.nextToken(); ExpressionAST *expr = 0; parseExpression(expr); CHECK(')'); FunctionCallAST *ast = CreateNode(_M_pool); ast->arguments = expr; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } return true; case '.': case Token_arrow: { std::size_t op = token_stream.cursor(); token_stream.nextToken(); std::size_t templ = 0; if (token_stream.lookAhead() == Token_template) { templ = token_stream.cursor(); token_stream.nextToken(); } int saved = int(token_stream.cursor()); NameAST *name = 0; if (parseName(name, true) && name->unqualified_name && name->unqualified_name->template_arguments != 0 && token_stream.lookAhead() == '(') { // a template method call // ### reverse the logic } else { token_stream.rewind(saved); name = 0; if (! parseName (name, templ != 0)) return false; } ClassMemberAccessAST *ast = CreateNode(_M_pool); ast->op = op; ast->name = name; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } return true; case Token_incr: case Token_decr: { std::size_t op = token_stream.cursor(); token_stream.nextToken(); IncrDecrExpressionAST *ast = CreateNode(_M_pool); ast->op = op; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } return true; default: return false; } } /* postfix-expression: simple-type-specifier ( expression-list [opt] ) primary-expression postfix-expression-internal* */ bool Parser::parsePostfixExpression(ExpressionAST *&node) { std::size_t start = token_stream.cursor(); switch (token_stream.lookAhead()) { case Token_dynamic_cast: case Token_static_cast: case Token_reinterpret_cast: case Token_const_cast: { std::size_t castOp = token_stream.cursor(); token_stream.nextToken(); CHECK('<'); TypeIdAST *typeId = 0; parseTypeId(typeId); CHECK('>'); CHECK('('); ExpressionAST *expr = 0; parseCommaExpression(expr); CHECK(')'); CppCastExpressionAST *ast = CreateNode(_M_pool); ast->op = castOp; ast->type_id = typeId; ast->expression = expr; ExpressionAST *e = 0; while (parsePostfixExpressionInternal(e)) { ast->sub_expressions = snoc(ast->sub_expressions, e, _M_pool); } UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } return true; case Token_typename: { std::size_t token = token_stream.cursor(); token_stream.nextToken(); NameAST* name = 0; if (!parseName(name, true)) return false; CHECK('('); ExpressionAST *expr = 0; parseCommaExpression(expr); CHECK(')'); TypeIdentificationAST *ast = CreateNode(_M_pool); ast->typename_token = token; ast->name = name; ast->expression = expr; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } return true; case Token_typeid: { token_stream.nextToken(); CHECK('('); TypeIdAST *typeId = 0; parseTypeId(typeId); CHECK(')'); TypeIdentificationAST *ast = CreateNode(_M_pool); UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } return true; default: break; } std::size_t saved_pos = token_stream.cursor(); TypeSpecifierAST *typeSpec = 0; ExpressionAST *expr = 0; // let's try to parse a type NameAST *name = 0; if (parseName(name, true)) { Q_ASSERT(name->unqualified_name != 0); bool has_template_args = name->unqualified_name->template_arguments != 0; if (has_template_args && token_stream.lookAhead() == '(') { ExpressionAST *cast_expr = 0; if (parseCastExpression(cast_expr) && cast_expr->kind == AST::Kind_CastExpression) { token_stream.rewind((int) saved_pos); parsePrimaryExpression(expr); goto L_no_rewind; } } } token_stream.rewind((int) saved_pos); L_no_rewind: if (!expr && parseSimpleTypeSpecifier(typeSpec) && token_stream.lookAhead() == '(') { token_stream.nextToken(); // skip '(' parseCommaExpression(expr); CHECK(')'); } else if (expr) { typeSpec = 0; } else { typeSpec = 0; token_stream.rewind((int) start); if (!parsePrimaryExpression(expr)) return false; } const ListNode *sub_expressions = 0; ExpressionAST *sub_expression = 0; while (parsePostfixExpressionInternal(sub_expression)) sub_expressions = snoc(sub_expressions, sub_expression, _M_pool); if (sub_expressions || ! expr || (typeSpec && expr)) { PostfixExpressionAST *ast = CreateNode(_M_pool); ast->type_specifier = typeSpec; ast->expression = expr; ast->sub_expressions = sub_expressions; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } else node = expr; return true; } bool Parser::parseUnaryExpression(ExpressionAST *&node) { std::size_t start = token_stream.cursor(); switch(token_stream.lookAhead()) { case Token_incr: case Token_decr: case '*': case '&': case '+': case '-': case '!': case '~': { std::size_t op = token_stream.cursor(); token_stream.nextToken(); ExpressionAST *expr = 0; if (!parseCastExpression(expr)) return false; UnaryExpressionAST *ast = CreateNode(_M_pool); ast->op = op; ast->expression = expr; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } return true; case Token_sizeof: { std::size_t sizeof_token = token_stream.cursor(); token_stream.nextToken(); SizeofExpressionAST *ast = CreateNode(_M_pool); ast->sizeof_token = sizeof_token; std::size_t index = token_stream.cursor(); if (token_stream.lookAhead() == '(') { token_stream.nextToken(); if (parseTypeId(ast->type_id) && token_stream.lookAhead() == ')') { token_stream.nextToken(); // skip ) UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } ast->type_id = 0; token_stream.rewind((int) index); } if (!parseUnaryExpression(ast->expression)) return false; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } default: break; } int token = token_stream.lookAhead(); if (token == Token_new || (token == Token_scope && token_stream.lookAhead(1) == Token_new)) return parseNewExpression(node); if (token == Token_delete || (token == Token_scope && token_stream.lookAhead(1) == Token_delete)) return parseDeleteExpression(node); return parsePostfixExpression(node); } bool Parser::parseNewExpression(ExpressionAST *&node) { std::size_t start = token_stream.cursor(); NewExpressionAST *ast = CreateNode(_M_pool); if (token_stream.lookAhead() == Token_scope && token_stream.lookAhead(1) == Token_new) { ast->scope_token = token_stream.cursor(); token_stream.nextToken(); } CHECK(Token_new); ast->new_token = token_stream.cursor() - 1; if (token_stream.lookAhead() == '(') { token_stream.nextToken(); parseCommaExpression(ast->expression); CHECK(')'); } if (token_stream.lookAhead() == '(') { token_stream.nextToken(); parseTypeId(ast->type_id); CHECK(')'); } else { parseNewTypeId(ast->new_type_id); } parseNewInitializer(ast->new_initializer); UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseNewTypeId(NewTypeIdAST *&node) { std::size_t start = token_stream.cursor(); TypeSpecifierAST *typeSpec = 0; if (!parseTypeSpecifier(typeSpec)) return false; NewTypeIdAST *ast = CreateNode(_M_pool); ast->type_specifier = typeSpec; parseNewDeclarator(ast->new_declarator); UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseNewDeclarator(NewDeclaratorAST *&node) { std::size_t start = token_stream.cursor(); NewDeclaratorAST *ast = CreateNode(_M_pool); PtrOperatorAST *ptrOp = 0; if (parsePtrOperator(ptrOp)) { ast->ptr_op = ptrOp; parseNewDeclarator(ast->sub_declarator); } while (token_stream.lookAhead() == '[') { token_stream.nextToken(); ExpressionAST *expr = 0; parseExpression(expr); ast->expressions = snoc(ast->expressions, expr, _M_pool); ADVANCE(']', "]"); } UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseNewInitializer(NewInitializerAST *&node) { std::size_t start = token_stream.cursor(); CHECK('('); NewInitializerAST *ast = CreateNode(_M_pool); parseCommaExpression(ast->expression); CHECK(')'); UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseDeleteExpression(ExpressionAST *&node) { std::size_t start = token_stream.cursor(); DeleteExpressionAST *ast = CreateNode(_M_pool); if (token_stream.lookAhead() == Token_scope && token_stream.lookAhead(1) == Token_delete) { ast->scope_token = token_stream.cursor(); token_stream.nextToken(); } CHECK(Token_delete); ast->delete_token = token_stream.cursor() - 1; if (token_stream.lookAhead() == '[') { ast->lbracket_token = token_stream.cursor(); token_stream.nextToken(); CHECK(']'); ast->rbracket_token = token_stream.cursor() - 1; } if (!parseCastExpression(ast->expression)) return false; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseCastExpression(ExpressionAST *&node) { std::size_t start = token_stream.cursor(); if (token_stream.lookAhead() == '(') { token_stream.nextToken(); CastExpressionAST *ast = CreateNode(_M_pool); if (parseTypeId(ast->type_id)) { if (token_stream.lookAhead() == ')') { token_stream.nextToken(); if (parseCastExpression(ast->expression)) { UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } } } } token_stream.rewind((int) start); return parseUnaryExpression(node); } bool Parser::parsePmExpression(ExpressionAST *&node) { std::size_t start = token_stream.cursor(); if (!parseCastExpression(node) || !node) // ### fixme return false; while (token_stream.lookAhead() == Token_ptrmem) { std::size_t op = token_stream.cursor(); token_stream.nextToken(); ExpressionAST *rightExpr = 0; if (!parseCastExpression(rightExpr)) return false; BinaryExpressionAST *ast = CreateNode(_M_pool); ast->op = op; ast->left_expression = node; ast->right_expression = rightExpr; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } return true; } bool Parser::parseMultiplicativeExpression(ExpressionAST *&node) { std::size_t start = token_stream.cursor(); if (!parsePmExpression(node)) return false; while (token_stream.lookAhead() == '*' || token_stream.lookAhead() == '/' || token_stream.lookAhead() == '%') { std::size_t op = token_stream.cursor(); token_stream.nextToken(); ExpressionAST *rightExpr = 0; if (!parsePmExpression(rightExpr)) return false; BinaryExpressionAST *ast = CreateNode(_M_pool); ast->op = op; ast->left_expression = node; ast->right_expression = rightExpr; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } return true; } bool Parser::parseAdditiveExpression(ExpressionAST *&node) { std::size_t start = token_stream.cursor(); if (!parseMultiplicativeExpression(node)) return false; while (token_stream.lookAhead() == '+' || token_stream.lookAhead() == '-') { std::size_t op = token_stream.cursor(); token_stream.nextToken(); ExpressionAST *rightExpr = 0; if (!parseMultiplicativeExpression(rightExpr)) return false; BinaryExpressionAST *ast = CreateNode(_M_pool); ast->op = op; ast->left_expression = node; ast->right_expression = rightExpr; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } return true; } bool Parser::parseShiftExpression(ExpressionAST *&node) { std::size_t start = token_stream.cursor(); if (!parseAdditiveExpression(node)) return false; while (token_stream.lookAhead() == Token_shift) { std::size_t op = token_stream.cursor(); token_stream.nextToken(); ExpressionAST *rightExpr = 0; if (!parseAdditiveExpression(rightExpr)) return false; BinaryExpressionAST *ast = CreateNode(_M_pool); ast->op = op; ast->left_expression = node; ast->right_expression = rightExpr; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } return true; } bool Parser::parseRelationalExpression(ExpressionAST *&node, bool templArgs) { std::size_t start = token_stream.cursor(); if (!parseShiftExpression(node)) return false; while (token_stream.lookAhead() == '<' || (token_stream.lookAhead() == '>' && !templArgs) || token_stream.lookAhead() == Token_leq || token_stream.lookAhead() == Token_geq) { std::size_t op = token_stream.cursor(); token_stream.nextToken(); ExpressionAST *rightExpr = 0; if (!parseShiftExpression(rightExpr)) return false; BinaryExpressionAST *ast = CreateNode(_M_pool); ast->op = op; ast->left_expression = node; ast->right_expression = rightExpr; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } return true; } bool Parser::parseEqualityExpression(ExpressionAST *&node, bool templArgs) { std::size_t start = token_stream.cursor(); if (!parseRelationalExpression(node, templArgs)) return false; while (token_stream.lookAhead() == Token_eq || token_stream.lookAhead() == Token_not_eq) { std::size_t op = token_stream.cursor(); token_stream.nextToken(); ExpressionAST *rightExpr = 0; if (!parseRelationalExpression(rightExpr, templArgs)) return false; BinaryExpressionAST *ast = CreateNode(_M_pool); ast->op = op; ast->left_expression = node; ast->right_expression = rightExpr; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } return true; } bool Parser::parseAndExpression(ExpressionAST *&node, bool templArgs) { std::size_t start = token_stream.cursor(); if (!parseEqualityExpression(node, templArgs)) return false; while (token_stream.lookAhead() == '&') { std::size_t op = token_stream.cursor(); token_stream.nextToken(); ExpressionAST *rightExpr = 0; if (!parseEqualityExpression(rightExpr, templArgs)) return false; BinaryExpressionAST *ast = CreateNode(_M_pool); ast->op = op; ast->left_expression = node; ast->right_expression = rightExpr; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } return true; } bool Parser::parseExclusiveOrExpression(ExpressionAST *&node, bool templArgs) { std::size_t start = token_stream.cursor(); if (!parseAndExpression(node, templArgs)) return false; while (token_stream.lookAhead() == '^') { std::size_t op = token_stream.cursor(); token_stream.nextToken(); ExpressionAST *rightExpr = 0; if (!parseAndExpression(rightExpr, templArgs)) return false; BinaryExpressionAST *ast = CreateNode(_M_pool); ast->op = op; ast->left_expression = node; ast->right_expression = rightExpr; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } return true; } bool Parser::parseInclusiveOrExpression(ExpressionAST *&node, bool templArgs) { std::size_t start = token_stream.cursor(); if (!parseExclusiveOrExpression(node, templArgs)) return false; while (token_stream.lookAhead() == '|') { std::size_t op = token_stream.cursor(); token_stream.nextToken(); ExpressionAST *rightExpr = 0; if (!parseExclusiveOrExpression(rightExpr, templArgs)) return false; BinaryExpressionAST *ast = CreateNode(_M_pool); ast->op = op; ast->left_expression = node; ast->right_expression = rightExpr; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } return true; } bool Parser::parseLogicalAndExpression(ExpressionAST *&node, bool templArgs) { std::size_t start = token_stream.cursor(); if (!parseInclusiveOrExpression(node, templArgs)) return false; while (token_stream.lookAhead() == Token_and) { std::size_t op = token_stream.cursor(); token_stream.nextToken(); ExpressionAST *rightExpr = 0; if (!parseInclusiveOrExpression(rightExpr, templArgs)) return false; BinaryExpressionAST *ast = CreateNode(_M_pool); ast->op = op; ast->left_expression = node; ast->right_expression = rightExpr; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } return true; } bool Parser::parseLogicalOrExpression(ExpressionAST *&node, bool templArgs) { std::size_t start = token_stream.cursor(); if (!parseLogicalAndExpression(node, templArgs)) return false; while (token_stream.lookAhead() == Token_or) { std::size_t op = token_stream.cursor(); token_stream.nextToken(); ExpressionAST *rightExpr = 0; if (!parseLogicalAndExpression(rightExpr, templArgs)) return false; BinaryExpressionAST *ast = CreateNode(_M_pool); ast->op = op; ast->left_expression = node; ast->right_expression = rightExpr; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } return true; } bool Parser::parseConditionalExpression(ExpressionAST *&node) { std::size_t start = token_stream.cursor(); if (!parseLogicalOrExpression(node)) return false; if (token_stream.lookAhead() == '?') { token_stream.nextToken(); ExpressionAST *leftExpr = 0; if (!parseExpression(leftExpr)) return false; CHECK(':'); ExpressionAST *rightExpr = 0; if (!parseAssignmentExpression(rightExpr)) return false; ConditionalExpressionAST *ast = CreateNode(_M_pool); ast->condition = node; ast->left_expression = leftExpr; ast->right_expression = rightExpr; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } return true; } bool Parser::parseAssignmentExpression(ExpressionAST *&node) { std::size_t start = token_stream.cursor(); if (token_stream.lookAhead() == Token_throw && !parseThrowExpression(node)) return false; else if (!parseConditionalExpression(node)) return false; while (token_stream.lookAhead() == Token_assign || token_stream.lookAhead() == '=') { std::size_t op = token_stream.cursor(); token_stream.nextToken(); ExpressionAST *rightExpr = 0; if (!parseConditionalExpression(rightExpr)) return false; BinaryExpressionAST *ast = CreateNode(_M_pool); ast->op = op; ast->left_expression = node; ast->right_expression = rightExpr; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } return true; } bool Parser::parseConstantExpression(ExpressionAST *&node) { return parseConditionalExpression(node); } bool Parser::parseExpression(ExpressionAST *&node) { return parseCommaExpression(node); } bool Parser::parseCommaExpression(ExpressionAST *&node) { std::size_t start = token_stream.cursor(); if (!parseAssignmentExpression(node)) return false; while (token_stream.lookAhead() == ',') { std::size_t op = token_stream.cursor(); token_stream.nextToken(); ExpressionAST *rightExpr = 0; if (!parseAssignmentExpression(rightExpr)) return false; BinaryExpressionAST *ast = CreateNode(_M_pool); ast->op = op; ast->left_expression = node; ast->right_expression = rightExpr; UPDATE_POS(ast, start, token_stream.cursor()); node = ast; } return true; } bool Parser::parseThrowExpression(ExpressionAST *&node) { std::size_t start = token_stream.cursor(); CHECK(Token_throw); ThrowExpressionAST *ast = CreateNode(_M_pool); ast->throw_token = token_stream.cursor() - 1; parseAssignmentExpression(ast->expression); UPDATE_POS(ast, start, token_stream.cursor()); node = ast; return true; } bool Parser::parseQ_ENUMS(DeclarationAST *&node) { if (token_stream.lookAhead() != Token_Q_ENUMS) return false; if (token_stream.lookAhead(1) != '(') return false; token_stream.nextToken(); token_stream.nextToken(); int firstToken = token_stream.cursor(); while (token_stream.lookAhead() != ')') { token_stream.nextToken(); } QEnumsAST *ast = CreateNode(_M_pool); UPDATE_POS(ast, firstToken, token_stream.cursor()); node = ast; token_stream.nextToken(); return true; } bool Parser::parseQ_PROPERTY(DeclarationAST *&node) { if (token_stream.lookAhead() != Token_Q_PROPERTY) return false; if (token_stream.lookAhead(1) != '(') return false; token_stream.nextToken(); token_stream.nextToken(); int firstToken = token_stream.cursor(); while (token_stream.lookAhead() != ')') { token_stream.nextToken(); } QPropertyAST *ast = CreateNode(_M_pool); UPDATE_POS(ast, firstToken, token_stream.cursor()); node = ast; // const Token &t1 = token_stream[firstToken]; // const Token &t2 = token_stream[token_stream.cursor()]; // printf("property: %s\n", // qPrintable(QString::fromLatin1(t1.text + t1.position, t2.position - t1.position))); token_stream.nextToken(); return true; } bool Parser::block_errors(bool block) { bool current = _M_block_errors; _M_block_errors = block; return current; } // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/parser.h000066400000000000000000000203461170724227300230170ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef PARSER_H #define PARSER_H #include "ast.h" #include "lexer.h" #include class FileSymbol; class Control; class Parser { public: Parser(Control *control); ~Parser(); LocationManager &location() { return _M_location; } TranslationUnitAST *parse(const char *contents, std::size_t size, pool *p); private: void reportError(const QString& msg); void syntaxError(); void tokenRequiredError(int expected); public: bool skipFunctionBody(StatementAST *&node); public: bool parse_Attribute__(); bool parseAbstractDeclarator(DeclaratorAST *&node); bool parseAccessSpecifier(DeclarationAST *&node); bool parseAdditiveExpression(ExpressionAST *&node); bool parseAndExpression(ExpressionAST *&node, bool templArgs = false); bool parseAsmDefinition(DeclarationAST *&node); bool parseAssignmentExpression(ExpressionAST *&node); bool parseBaseClause(BaseClauseAST *&node); bool parseBaseSpecifier(BaseSpecifierAST *&node); bool parseBlockDeclaration(DeclarationAST *&node); bool parseCastExpression(ExpressionAST *&node); bool parseClassSpecifier(TypeSpecifierAST *&node); bool parseForwardDeclarationSpecifier(TypeSpecifierAST *&node); bool parseCommaExpression(ExpressionAST *&node); bool parseCompoundStatement(StatementAST *&node); bool parseCondition(ConditionAST *&node, bool initRequired = true); bool parseConditionalExpression(ExpressionAST *&node); bool parseConstantExpression(ExpressionAST *&node); bool parseCtorInitializer(CtorInitializerAST *&node); bool parseCvQualify(const ListNode *&node); bool parseDeclaration(DeclarationAST *&node); bool parseDeclarationInternal(DeclarationAST *&node); bool parseDeclarationStatement(StatementAST *&node); bool parseDeclarator(DeclaratorAST *&node); bool parseDeleteExpression(ExpressionAST *&node); bool parseDoStatement(StatementAST *&node); bool parseElaboratedTypeSpecifier(TypeSpecifierAST *&node); bool parseEnumSpecifier(TypeSpecifierAST *&node); bool parseEnumerator(EnumeratorAST *&node); bool parseEqualityExpression(ExpressionAST *&node, bool templArgs = false); bool parseExceptionSpecification(ExceptionSpecificationAST *&node); bool parseExclusiveOrExpression(ExpressionAST *&node, bool templArgs = false); bool parseExpression(ExpressionAST *&node); bool parseExpressionOrDeclarationStatement(StatementAST *&node); bool parseExpressionStatement(StatementAST *&node); bool parseForInitStatement(StatementAST *&node); bool parseForStatement(StatementAST *&node); bool parseFunctionBody(StatementAST *&node); bool parseFunctionSpecifier(const ListNode *&node); bool parseIfStatement(StatementAST *&node); bool parseInclusiveOrExpression(ExpressionAST *&node, bool templArgs = false); bool parseInitDeclarator(InitDeclaratorAST *&node); bool parseInitDeclaratorList(const ListNode *&node); bool parseInitializer(InitializerAST *&node); bool parseInitializerClause(InitializerClauseAST *&node); bool parseLabeledStatement(StatementAST *&node); bool parseLinkageBody(LinkageBodyAST *&node); bool parseLinkageSpecification(DeclarationAST *&node); bool parseLogicalAndExpression(ExpressionAST *&node, bool templArgs = false); bool parseLogicalOrExpression(ExpressionAST *&node, bool templArgs = false); bool parseMemInitializer(MemInitializerAST *&node); bool parseMemInitializerList(const ListNode *&node); bool parseMemberSpecification(DeclarationAST *&node); bool parseMultiplicativeExpression(ExpressionAST *&node); bool parseName(NameAST *&node, bool acceptTemplateId = false); bool parseNamespace(DeclarationAST *&node); bool parseNamespaceAliasDefinition(DeclarationAST *&node); bool parseNewDeclarator(NewDeclaratorAST *&node); bool parseNewExpression(ExpressionAST *&node); bool parseNewInitializer(NewInitializerAST *&node); bool parseNewTypeId(NewTypeIdAST *&node); bool parseOperator(OperatorAST *&node); bool parseOperatorFunctionId(OperatorFunctionIdAST *&node); bool parseParameterDeclaration(ParameterDeclarationAST *&node); bool parseParameterDeclarationClause(ParameterDeclarationClauseAST *&node); bool parseParameterDeclarationList(const ListNode *&node); bool parsePmExpression(ExpressionAST *&node); bool parsePostfixExpression(ExpressionAST *&node); bool parsePostfixExpressionInternal(ExpressionAST *&node); bool parsePrimaryExpression(ExpressionAST *&node); bool parsePtrOperator(PtrOperatorAST *&node); bool parsePtrToMember(PtrToMemberAST *&node); bool parseRelationalExpression(ExpressionAST *&node, bool templArgs = false); bool parseShiftExpression(ExpressionAST *&node); bool parseSimpleTypeSpecifier(TypeSpecifierAST *&node, bool onlyIntegral = false); bool parseStatement(StatementAST *&node); bool parseStorageClassSpecifier(const ListNode *&node); bool parseStringLiteral(StringLiteralAST *&node); bool parseSwitchStatement(StatementAST *&node); bool parseTemplateArgument(TemplateArgumentAST *&node); bool parseTemplateArgumentList(const ListNode *&node, bool reportError = true); bool parseTemplateDeclaration(DeclarationAST *&node); bool parseTemplateParameter(TemplateParameterAST *&node); bool parseTemplateParameterList(const ListNode *&node); bool parseThrowExpression(ExpressionAST *&node); bool parseTranslationUnit(TranslationUnitAST *&node); bool parseTryBlockStatement(StatementAST *&node); bool parseTypeId(TypeIdAST *&node); bool parseTypeIdList(const ListNode *&node); bool parseTypeParameter(TypeParameterAST *&node); bool parseTypeSpecifier(TypeSpecifierAST *&node); bool parseTypeSpecifierOrClassSpec(TypeSpecifierAST *&node); bool parseTypedef(DeclarationAST *&node); bool parseUnaryExpression(ExpressionAST *&node); bool parseUnqualifiedName(UnqualifiedNameAST *&node, bool parseTemplateId = true); bool parseUsing(DeclarationAST *&node); bool parseUsingDirective(DeclarationAST *&node); bool parseWhileStatement(StatementAST *&node); bool parseWinDeclSpec(WinDeclSpecAST *&node); bool parseQ_PROPERTY(DeclarationAST *&node); bool parseQ_ENUMS(DeclarationAST *&node); bool skipUntil(int token); bool skipUntilDeclaration(); bool skipUntilStatement(); bool skip(int l, int r); void advance(); // private: TokenStream token_stream; LocationTable location_table; LocationTable line_table; bool block_errors(bool block); private: QString tokenText(AST *) const; LocationManager _M_location; Control *control; Lexer lexer; pool *_M_pool; bool _M_block_errors; private: Parser(const Parser& source); void operator = (const Parser& source); }; #endif // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/r++.macros000066400000000000000000000011021170724227300231340ustar00rootroot00000000000000 #define __attribute__(a...) #define __typeof__ __typeof #define __extension #define __extension__ #define __restrict #define __restrict__ #define __volatile volatile #define __volatile__ volatile #define __inline inline #define __inline__ inline #define __const const #define __const__ const #define __asm asm #define __asm__ asm #define __GNUC__ 3 //#define __GNUC_MINOR__ 4 #define __ROBC__ 0 #define __ROBC_MINOR__ 1 qtscriptgenerator-src-0.2.0/generator/parser/rpp-allocator.h000066400000000000000000000027751170724227300243100ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "rxx_allocator.h" qtscriptgenerator-src-0.2.0/generator/parser/rpp/000077500000000000000000000000001170724227300221465ustar00rootroot00000000000000qtscriptgenerator-src-0.2.0/generator/parser/rpp/builtin-macros.cpp000066400000000000000000000027421170724227300256070ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ qtscriptgenerator-src-0.2.0/generator/parser/rpp/pp-cctype.h000066400000000000000000000037651170724227300242360ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef PP_CCTYPE_H #define PP_CCTYPE_H #include namespace rpp { inline bool pp_isalpha (int __ch) { return std::isalpha ((unsigned char) __ch) != 0; } inline bool pp_isalnum (int __ch) { return std::isalnum ((unsigned char) __ch) != 0; } inline bool pp_isdigit (int __ch) { return std::isdigit ((unsigned char) __ch) != 0; } inline bool pp_isspace (int __ch) { return std::isspace ((unsigned char) __ch) != 0; } } // namespace rpp #endif // PP_CCTYPE_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/rpp/pp-configuration000066400000000000000000000050061170724227300253560ustar00rootroot00000000000000#define __DBL_MIN_EXP__ (-1021) #define __FLT_MIN__ 1.17549435e-38F #define __CHAR_BIT__ 8 #define __WCHAR_MAX__ 2147483647 #define __DBL_DENORM_MIN__ 4.9406564584124654e-324 #define __FLT_EVAL_METHOD__ 2 #define __DBL_MIN_10_EXP__ (-307) #define __FINITE_MATH_ONLY__ 0 #define __GNUC_PATCHLEVEL__ 2 #define __SHRT_MAX__ 32767 #define __LDBL_MAX__ 1.18973149535723176502e+4932L #define __UINTMAX_TYPE__ long long unsigned int #define __linux 1 #define __unix 1 #define __LDBL_MAX_EXP__ 16384 #define __linux__ 1 #define __SCHAR_MAX__ 127 #define __USER_LABEL_PREFIX__ #define __STDC_HOSTED__ 1 #define __LDBL_HAS_INFINITY__ 1 #define __DBL_DIG__ 15 #define __FLT_EPSILON__ 1.19209290e-7F #define __GXX_WEAK__ 1 #define __LDBL_MIN__ 3.36210314311209350626e-4932L #define __unix__ 1 #define __DECIMAL_DIG__ 21 #define __gnu_linux__ 1 #define __LDBL_HAS_QUIET_NAN__ 1 #define __GNUC__ 4 #define __DBL_MAX__ 1.7976931348623157e+308 #define __DBL_HAS_INFINITY__ 1 #define __cplusplus 1 #define __DEPRECATED 1 #define __DBL_MAX_EXP__ 1024 #define __GNUG__ 4 #define __LONG_LONG_MAX__ 9223372036854775807LL #define __GXX_ABI_VERSION 1002 #define __FLT_MIN_EXP__ (-125) #define __DBL_MIN__ 2.2250738585072014e-308 #define __FLT_MIN_10_EXP__ (-37) #define __DBL_HAS_QUIET_NAN__ 1 #define __REGISTER_PREFIX__ #define __NO_INLINE__ 1 #define __i386 1 #define __FLT_MANT_DIG__ 24 #define __VERSION__ "4.0.2 20050808 (prerelease) (Ubuntu 4.0.1-4ubuntu9)" #define i386 1 #define __i486__ 1 #define unix 1 #define __i386__ 1 #define __SIZE_TYPE__ unsigned int #define __ELF__ 1 #define __FLT_RADIX__ 2 #define __LDBL_EPSILON__ 1.08420217248550443401e-19L #define __FLT_HAS_QUIET_NAN__ 1 #define __FLT_MAX_10_EXP__ 38 #define __LONG_MAX__ 2147483647L #define __FLT_HAS_INFINITY__ 1 #define linux 1 #define __EXCEPTIONS 1 #define __LDBL_MANT_DIG__ 64 #define __WCHAR_TYPE__ int #define __FLT_DIG__ 6 #define __INT_MAX__ 2147483647 #define __i486 1 #define __FLT_MAX_EXP__ 128 #define __DBL_MANT_DIG__ 53 #define __WINT_TYPE__ unsigned int #define __LDBL_MIN_EXP__ (-16381) #define __LDBL_MAX_10_EXP__ 4932 #define __DBL_EPSILON__ 2.2204460492503131e-16 #define __tune_i486__ 1 #define __INTMAX_MAX__ 9223372036854775807LL #define __FLT_DENORM_MIN__ 1.40129846e-45F #define __FLT_MAX__ 3.40282347e+38F #define __INTMAX_TYPE__ long long int #define __GNUC_MINOR__ 0 #define __DBL_MAX_10_EXP__ 308 #define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L #define __PTRDIFF_TYPE__ int #define __LDBL_MIN_10_EXP__ (-4931) #define __LDBL_DIG__ 18 #define _GNU_SOURCE 1 #define __STDC__ qtscriptgenerator-src-0.2.0/generator/parser/rpp/pp-engine-bits.h000066400000000000000000001054111170724227300251420ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef PP_ENGINE_BITS_H #define PP_ENGINE_BITS_H #include namespace rpp { inline std::string pp::fix_file_path(std::string const &filename) const { #if defined (PP_OS_WIN) std::string s = filename; for (std::string::iterator it = s.begin(); it != s.end(); ++it) { if (*it == '/') *it = '\\'; } return s; #else return filename; #endif } inline bool pp::is_absolute(std::string const &filename) const { #if defined(PP_OS_WIN) return filename.length() >= 3 && filename.at(1) == ':' && (filename.at(2) == '\\' || filename.at(2) == '/'); #else return filename.length() >= 1 && filename.at(0) == '/'; #endif } template void pp::file (std::string const &filename, _OutputIterator __result) { FILE *fp = fopen (filename.c_str(), "rb"); if (fp != 0) { std::string was = env.current_file; env.current_file = filename; file (fp, __result); env.current_file = was; } //else //std::cerr << "** WARNING file ``" << filename << " not found!" << std::endl; } template void pp::file (FILE *fp, _OutputIterator __result) { assert (fp != 0); #if defined (HAVE_MMAP) struct stat st; fstat(FILENO (fp), &st); std::size_t size = st.st_size; char *buffer = 0; buffer = (char *) ::mmap(0, size, PROT_READ, MAP_SHARED, FILENO (fp), 0); fclose (fp); if (!buffer || buffer == (char*) -1) return; this->operator () (buffer, buffer + size, __result); ::munmap(buffer, size); #else std::string buffer; while (!feof(fp)) { char tmp[1024]; int read = (int) fread (tmp, sizeof(char), 1023, fp); tmp[read] = '\0'; buffer += tmp; } fclose (fp); this->operator () (buffer.c_str(), buffer.c_str() + buffer.size(), __result); #endif } template bool pp::find_header_protection (_InputIterator __first, _InputIterator __last, std::string *__prot) { int was = env.current_line; while (__first != __last) { if (pp_isspace (*__first)) { if (*__first == '\n') ++env.current_line; ++__first; } else if (_PP_internal::comment_p (__first, __last)) { __first = skip_comment_or_divop (__first, __last); env.current_line += skip_comment_or_divop.lines; } else if (*__first == '#') { __first = skip_blanks (++__first, __last); env.current_line += skip_blanks.lines; if (__first != __last && *__first == 'i') { _InputIterator __begin = __first; __first = skip_identifier (__begin, __last); env.current_line += skip_identifier.lines; std::string __directive (__begin, __first); if (__directive == "ifndef") { __first = skip_blanks (__first, __last); env.current_line += skip_blanks.lines; __begin = __first; __first = skip_identifier (__first, __last); env.current_line += skip_identifier.lines; if (__begin != __first && __first != __last) { __prot->assign (__begin, __first); return true; } } } break; } else break; } env.current_line = was; return false; } inline pp::PP_DIRECTIVE_TYPE pp::find_directive (char const *__directive, std::size_t __size) const { switch (__size) { case 2: if (__directive[0] == 'i' && __directive[1] == 'f') return PP_IF; break; case 4: if (__directive[0] == 'e' && !strcmp (__directive, "elif")) return PP_ELIF; else if (__directive[0] == 'e' && !strcmp (__directive, "else")) return PP_ELSE; break; case 5: if (__directive[0] == 'i' && !strcmp (__directive, "ifdef")) return PP_IFDEF; else if (__directive[0] == 'u' && !strcmp (__directive, "undef")) return PP_UNDEF; else if (__directive[0] == 'e') { if (!strcmp (__directive, "endif")) return PP_ENDIF; else if (!strcmp (__directive, "error")) return PP_ERROR; } break; case 6: if (__directive[0] == 'i' && !strcmp (__directive, "ifndef")) return PP_IFNDEF; else if (__directive[0] == 'd' && !strcmp (__directive, "define")) return PP_DEFINE; else if (__directive[0] == 'p' && !strcmp (__directive, "pragma")) return PP_PRAGMA; break; case 7: if (__directive[0] == 'i' && !strcmp (__directive, "include")) return PP_INCLUDE; else if (__directive[0] == 'w' && !strcmp(__directive, "warning")) return PP_WARNING; break; case 12: if (__directive[0] == 'i' && !strcmp (__directive, "include_next")) return PP_INCLUDE_NEXT; break; default: break; } std::cerr << "** WARNING unknown directive '#" << __directive << "' at " << env.current_file << ":" << env.current_line << std::endl; return PP_UNKNOWN_DIRECTIVE; } inline bool pp::file_isdir (std::string const &__filename) const { struct stat __st; #if defined(PP_OS_WIN) if (stat(__filename.c_str (), &__st) == 0) return (__st.st_mode & _S_IFDIR) == _S_IFDIR; else return false; #else if (lstat (__filename.c_str (), &__st) == 0) return (__st.st_mode & S_IFDIR) == S_IFDIR; else return false; #endif } inline bool pp::file_exists (std::string const &__filename) const { struct stat __st; #if defined(PP_OS_WIN) return stat(__filename.c_str (), &__st) == 0; #else return lstat (__filename.c_str (), &__st) == 0; #endif } inline FILE *pp::find_include_file(std::string const &__input_filename, std::string *__filepath, INCLUDE_POLICY __include_policy, bool __skip_current_path) const { assert (__filepath != 0); assert (! __input_filename.empty()); __filepath->assign (__input_filename); if (is_absolute (*__filepath)) return fopen (__filepath->c_str(), "r"); if (! env.current_file.empty ()) _PP_internal::extract_file_path (env.current_file, __filepath); if (__include_policy == INCLUDE_LOCAL && ! __skip_current_path) { std::string __tmp (*__filepath); __tmp += __input_filename; if (file_exists (__tmp) && !file_isdir(__tmp)) { __filepath->append (__input_filename); return fopen (__filepath->c_str (), "r"); } } std::vector::const_iterator it = include_paths.begin (); if (__skip_current_path) { it = std::find (include_paths.begin (), include_paths.end (), *__filepath); if (it != include_paths.end ()) ++it; else it = include_paths.begin (); } for (; it != include_paths.end (); ++it) { if (__skip_current_path && it == include_paths.begin()) continue; __filepath->assign (*it); __filepath->append (__input_filename); if (file_exists (*__filepath) && !file_isdir(*__filepath)) return fopen (__filepath->c_str(), "r"); #ifdef Q_OS_MAC // try in Framework path on Mac, if there is a path in front // ### what about escaped slashes? size_t slashPos = __input_filename.find('/'); if (slashPos != std::string::npos) { __filepath->assign (*it); __filepath->append (__input_filename.substr(0, slashPos)); __filepath->append (".framework/Headers/"); __filepath->append (__input_filename.substr(slashPos+1, std::string::npos)); std::cerr << *__filepath << "\n"; if (file_exists (*__filepath) && !file_isdir(*__filepath)) return fopen (__filepath->c_str(), "r"); } #endif // Q_OS_MAC } return 0; } template _InputIterator pp::handle_directive(char const *__directive, std::size_t __size, _InputIterator __first, _InputIterator __last, _OutputIterator __result) { __first = skip_blanks (__first, __last); PP_DIRECTIVE_TYPE d = find_directive (__directive, __size); switch (d) { case PP_DEFINE: if (! skipping ()) return handle_define (__first, __last); break; case PP_INCLUDE: case PP_INCLUDE_NEXT: if (! skipping ()) return handle_include (d == PP_INCLUDE_NEXT, __first, __last, __result); break; case PP_UNDEF: if (! skipping ()) return handle_undef(__first, __last); break; case PP_ELIF: return handle_elif (__first, __last); case PP_ELSE: return handle_else (__first, __last); case PP_ENDIF: return handle_endif (__first, __last); case PP_IF: return handle_if (__first, __last); case PP_IFDEF: return handle_ifdef (false, __first, __last); case PP_IFNDEF: return handle_ifdef (true, __first, __last); default: break; } return __first; } template _InputIterator pp::handle_include (bool __skip_current_path, _InputIterator __first, _InputIterator __last, _OutputIterator __result) { if (pp_isalpha (*__first) || *__first == '_') { pp_macro_expander expand_include (env); std::string name; name.reserve (255); expand_include (__first, __last, std::back_inserter (name)); std::string::iterator it = skip_blanks (name.begin (), name.end ()); assert (it != name.end () && (*it == '<' || *it == '"')); handle_include (__skip_current_path, it, name.end (), __result); return __first; } assert (*__first == '<' || *__first == '"'); int quote = (*__first == '"') ? '"' : '>'; ++__first; _InputIterator end_name = __first; for (; end_name != __last; ++end_name) { assert (*end_name != '\n'); if (*end_name == quote) break; } std::string filename (__first, end_name); #ifdef PP_OS_WIN std::replace(filename.begin(), filename.end(), '/', '\\'); #endif std::string filepath; FILE *fp = find_include_file (filename, &filepath, quote == '>' ? INCLUDE_GLOBAL : INCLUDE_LOCAL, __skip_current_path); #if defined (PP_HOOK_ON_FILE_INCLUDED) PP_HOOK_ON_FILE_INCLUDED (env.current_file, fp ? filepath : filename, fp); #endif if (fp != 0) { std::string old_file = env.current_file; env.current_file = filepath; int __saved_lines = env.current_line; env.current_line = 1; //output_line (env.current_file, 1, __result); file (fp, __result); // restore the file name and the line position env.current_file = old_file; env.current_line = __saved_lines; // sync the buffer _PP_internal::output_line (env.current_file, env.current_line, __result); } #ifndef RPP_JAMBI // else // std::cerr << "*** WARNING " << filename << ": No such file or directory" << std::endl; #endif return __first; } template void pp::operator () (_InputIterator __first, _InputIterator __last, _OutputIterator __result) { #ifndef PP_NO_SMART_HEADER_PROTECTION std::string __prot; __prot.reserve (255); pp_fast_string __tmp (__prot.c_str (), __prot.size ()); if (find_header_protection (__first, __last, &__prot) && env.resolve (&__tmp) != 0) { // std::cerr << "** DEBUG found header protection:" << __prot << std::endl; return; } #endif env.current_line = 1; char __buffer[512]; while (true) { __first = skip_blanks (__first, __last); env.current_line += skip_blanks.lines; if (__first == __last) break; else if (*__first == '#') { assert (*__first == '#'); __first = skip_blanks (++__first, __last); env.current_line += skip_blanks.lines; _InputIterator end_id = skip_identifier (__first, __last); env.current_line += skip_identifier.lines; std::size_t __size = end_id - __first; assert (__size < 512); char *__cp = __buffer; std::copy (__first, end_id, __cp); __cp[__size] = '\0'; end_id = skip_blanks (end_id, __last); __first = skip (end_id, __last); int was = env.current_line; (void) handle_directive (__buffer, __size, end_id, __first, __result); if (env.current_line != was) { env.current_line = was; _PP_internal::output_line (env.current_file, env.current_line, __result); } } else if (*__first == '\n') { // ### compress the line *__result++ = *__first++; ++env.current_line; } else if (skipping ()) __first = skip (__first, __last); else { _PP_internal::output_line (env.current_file, env.current_line, __result); __first = expand (__first, __last, __result); env.current_line += expand.lines; if (expand.generated_lines) _PP_internal::output_line (env.current_file, env.current_line, __result); } } } inline pp::pp (pp_environment &__env): env (__env), expand (env) { iflevel = 0; _M_skipping[iflevel] = 0; _M_true_test[iflevel] = 0; } inline std::back_insert_iterator > pp::include_paths_inserter () { return std::back_inserter (include_paths); } inline std::vector::iterator pp::include_paths_begin () { return include_paths.begin (); } inline std::vector::iterator pp::include_paths_end () { return include_paths.end (); } inline std::vector::const_iterator pp::include_paths_begin () const { return include_paths.begin (); } inline std::vector::const_iterator pp::include_paths_end () const { return include_paths.end (); } inline void pp::push_include_path (std::string const &__path) { if (__path.empty () || __path [__path.size () - 1] != PATH_SEPARATOR) { std::string __tmp (__path); __tmp += PATH_SEPARATOR; include_paths.push_back (__tmp); } else include_paths.push_back (__path); } template _InputIterator pp::handle_define (_InputIterator __first, _InputIterator __last) { pp_macro macro; #if defined (PP_WITH_MACRO_POSITION) macro.file = pp_symbol::get (env.current_file); #endif std::string definition; __first = skip_blanks (__first, __last); _InputIterator end_macro_name = skip_identifier (__first, __last); pp_fast_string const *macro_name = pp_symbol::get (__first, end_macro_name); __first = end_macro_name; if (__first != __last && *__first == '(') { macro.function_like = true; macro.formals.reserve (5); __first = skip_blanks (++__first, __last); // skip '(' _InputIterator arg_end = skip_identifier (__first, __last); if (__first != arg_end) macro.formals.push_back (pp_symbol::get (__first, arg_end)); __first = skip_blanks (arg_end, __last); if (*__first == '.') { macro.variadics = true; while (*__first == '.') ++__first; } while (__first != __last && *__first == ',') { __first = skip_blanks (++__first, __last); arg_end = skip_identifier (__first, __last); if (__first != arg_end) macro.formals.push_back (pp_symbol::get (__first, arg_end)); __first = skip_blanks (arg_end, __last); if (*__first == '.') { macro.variadics = true; while (*__first == '.') ++__first; } } assert (*__first == ')'); ++__first; } __first = skip_blanks (__first, __last); while (__first != __last && *__first != '\n') { if (*__first == '/') { __first = skip_comment_or_divop(__first, __last); env.current_line += skip_comment_or_divop.lines; } if (*__first == '\\') { _InputIterator __begin = __first; __begin = skip_blanks (++__begin, __last); if (__begin != __last && *__begin == '\n') { ++macro.lines; __first = skip_blanks (++__begin, __last); definition += ' '; continue; } } definition += *__first++; } macro.definition = pp_symbol::get (definition); env.bind (macro_name, macro); return __first; } template _InputIterator pp::skip (_InputIterator __first, _InputIterator __last) { pp_skip_string_literal skip_string_literal; pp_skip_char_literal skip_char_literal; while (__first != __last && *__first != '\n') { if (*__first == '/') { __first = skip_comment_or_divop (__first, __last); env.current_line += skip_comment_or_divop.lines; } else if (*__first == '"') { __first = skip_string_literal (__first, __last); env.current_line += skip_string_literal.lines; } else if (*__first == '\'') { __first = skip_char_literal (__first, __last); env.current_line += skip_char_literal.lines; } else if (*__first == '\\') { __first = skip_blanks (++__first, __last); env.current_line += skip_blanks.lines; if (__first != __last && *__first == '\n') { ++__first; ++env.current_line; } } else ++__first; } return __first; } inline bool pp::test_if_level() { bool result = !_M_skipping[iflevel++]; _M_skipping[iflevel] = _M_skipping[iflevel - 1]; _M_true_test[iflevel] = false; return result; } inline int pp::skipping() const { return _M_skipping[iflevel]; } template _InputIterator pp::eval_primary(_InputIterator __first, _InputIterator __last, Value *result) { bool expect_paren = false; int token; __first = next_token (__first, __last, &token); switch (token) { case TOKEN_NUMBER: result->set_long (token_value); break; case TOKEN_UNUMBER: result->set_ulong (token_uvalue); break; case TOKEN_DEFINED: __first = next_token (__first, __last, &token); if (token == '(') { expect_paren = true; __first = next_token (__first, __last, &token); } if (token != TOKEN_IDENTIFIER) { std::cerr << "** WARNING expected ``identifier'' found:" << char(token) << std::endl; result->set_long (0); break; } result->set_long (env.resolve (token_text->c_str (), token_text->size ()) != 0); next_token (__first, __last, &token); // skip '(' if (expect_paren) { _InputIterator next = next_token (__first, __last, &token); if (token != ')') std::cerr << "** WARNING expected ``)''" << std::endl; else __first = next; } break; case TOKEN_IDENTIFIER: result->set_long (0); break; case '-': __first = eval_primary (__first, __last, result); result->set_long (- result->l); return __first; case '+': __first = eval_primary (__first, __last, result); return __first; case '!': __first = eval_primary (__first, __last, result); result->set_long (result->is_zero ()); return __first; case '(': __first = eval_constant_expression(__first, __last, result); next_token (__first, __last, &token); if (token != ')') std::cerr << "** WARNING expected ``)'' = " << token << std::endl; else __first = next_token(__first, __last, &token); break; default: result->set_long (0); } return __first; } template _InputIterator pp::eval_multiplicative(_InputIterator __first, _InputIterator __last, Value *result) { __first = eval_primary(__first, __last, result); int token; _InputIterator next = next_token (__first, __last, &token); while (token == '*' || token == '/' || token == '%') { Value value; __first = eval_primary(next, __last, &value); if (token == '*') result->op_mult (value); else if (token == '/') { if (value.is_zero ()) { std::cerr << "** WARNING division by zero" << std::endl; result->set_long (0); } else result->op_div (value); } else { if (value.is_zero ()) { std::cerr << "** WARNING division by zero" << std::endl; result->set_long (0); } else result->op_mod (value); } next = next_token (__first, __last, &token); } return __first; } template _InputIterator pp::eval_additive(_InputIterator __first, _InputIterator __last, Value *result) { __first = eval_multiplicative(__first, __last, result); int token; _InputIterator next = next_token (__first, __last, &token); while (token == '+' || token == '-') { Value value; __first = eval_multiplicative(next, __last, &value); if (token == '+') result->op_add (value); else result->op_sub (value); next = next_token (__first, __last, &token); } return __first; } template _InputIterator pp::eval_shift(_InputIterator __first, _InputIterator __last, Value *result) { __first = eval_additive(__first, __last, result); int token; _InputIterator next = next_token (__first, __last, &token); while (token == TOKEN_LT_LT || token == TOKEN_GT_GT) { Value value; __first = eval_additive (next, __last, &value); if (token == TOKEN_LT_LT) result->op_lhs (value); else result->op_rhs (value); next = next_token (__first, __last, &token); } return __first; } template _InputIterator pp::eval_relational(_InputIterator __first, _InputIterator __last, Value *result) { __first = eval_shift(__first, __last, result); int token; _InputIterator next = next_token (__first, __last, &token); while (token == '<' || token == '>' || token == TOKEN_LT_EQ || token == TOKEN_GT_EQ) { Value value; __first = eval_shift(next, __last, &value); switch (token) { default: assert (0); break; case '<': result->op_lt (value); break; case '>': result->op_gt (value); break; case TOKEN_LT_EQ: result->op_le (value); break; case TOKEN_GT_EQ: result->op_ge (value); break; } next = next_token (__first, __last, &token); } return __first; } template _InputIterator pp::eval_equality(_InputIterator __first, _InputIterator __last, Value *result) { __first = eval_relational(__first, __last, result); int token; _InputIterator next = next_token (__first, __last, &token); while (token == TOKEN_EQ_EQ || token == TOKEN_NOT_EQ) { Value value; __first = eval_relational(next, __last, &value); if (token == TOKEN_EQ_EQ) result->op_eq (value); else result->op_ne (value); next = next_token (__first, __last, &token); } return __first; } template _InputIterator pp::eval_and(_InputIterator __first, _InputIterator __last, Value *result) { __first = eval_equality(__first, __last, result); int token; _InputIterator next = next_token (__first, __last, &token); while (token == '&') { Value value; __first = eval_equality(next, __last, &value); result->op_bit_and (value); next = next_token (__first, __last, &token); } return __first; } template _InputIterator pp::eval_xor(_InputIterator __first, _InputIterator __last, Value *result) { __first = eval_and(__first, __last, result); int token; _InputIterator next = next_token (__first, __last, &token); while (token == '^') { Value value; __first = eval_and(next, __last, &value); result->op_bit_xor (value); next = next_token (__first, __last, &token); } return __first; } template _InputIterator pp::eval_or(_InputIterator __first, _InputIterator __last, Value *result) { __first = eval_xor(__first, __last, result); int token; _InputIterator next = next_token (__first, __last, &token); while (token == '|') { Value value; __first = eval_xor(next, __last, &value); result->op_bit_or (value); next = next_token (__first, __last, &token); } return __first; } template _InputIterator pp::eval_logical_and(_InputIterator __first, _InputIterator __last, Value *result) { __first = eval_or(__first, __last, result); int token; _InputIterator next = next_token (__first, __last, &token); while (token == TOKEN_AND_AND) { Value value; __first = eval_or(next, __last, &value); result->op_and (value); next = next_token (__first, __last, &token); } return __first; } template _InputIterator pp::eval_logical_or(_InputIterator __first, _InputIterator __last, Value *result) { __first = eval_logical_and (__first, __last, result); int token; _InputIterator next = next_token (__first, __last, &token); while (token == TOKEN_OR_OR) { Value value; __first = eval_logical_and(next, __last, &value); result->op_or (value); next = next_token (__first, __last, &token); } return __first; } template _InputIterator pp::eval_constant_expression(_InputIterator __first, _InputIterator __last, Value *result) { __first = eval_logical_or(__first, __last, result); int token; _InputIterator next = next_token (__first, __last, &token); if (token == '?') { Value left_value; __first = eval_constant_expression(next, __last, &left_value); __first = skip_blanks (__first, __last); __first = next_token(__first, __last, &token); if (token == ':') { Value right_value; __first = eval_constant_expression(__first, __last, &right_value); *result = !result->is_zero () ? left_value : right_value; } else { std::cerr << "** WARNING expected ``:'' = " << int (token) << std::endl; *result = left_value; } } return __first; } template _InputIterator pp::eval_expression (_InputIterator __first, _InputIterator __last, Value *result) { return __first = eval_constant_expression (skip_blanks (__first, __last), __last, result); } template _InputIterator pp::handle_if (_InputIterator __first, _InputIterator __last) { if (test_if_level()) { pp_macro_expander expand_condition (env); std::string condition; condition.reserve (255); expand_condition (skip_blanks (__first, __last), __last, std::back_inserter (condition)); Value result; result.set_long (0); eval_expression(condition.c_str (), condition.c_str () + condition.size (), &result); _M_true_test[iflevel] = !result.is_zero (); _M_skipping[iflevel] = result.is_zero (); } return __first; } template _InputIterator pp::handle_else (_InputIterator __first, _InputIterator /*__last*/) { if (iflevel == 0 && !skipping ()) { std::cerr << "** WARNING #else without #if" << std::endl; } else if (iflevel > 0 && _M_skipping[iflevel - 1]) { _M_skipping[iflevel] = true; } else { _M_skipping[iflevel] = _M_true_test[iflevel]; } return __first; } template _InputIterator pp::handle_elif (_InputIterator __first, _InputIterator __last) { assert(iflevel > 0); if (iflevel == 0 && !skipping()) { std::cerr << "** WARNING #else without #if" << std::endl; } else if (!_M_true_test[iflevel] && !_M_skipping[iflevel - 1]) { Value result; __first = eval_expression(__first, __last, &result); _M_true_test[iflevel] = !result.is_zero (); _M_skipping[iflevel] = result.is_zero (); } else { _M_skipping[iflevel] = true; } return __first; } template _InputIterator pp::handle_endif (_InputIterator __first, _InputIterator /*__last*/) { if (iflevel == 0 && !skipping()) { std::cerr << "** WARNING #endif without #if" << std::endl; } else { _M_skipping[iflevel] = 0; _M_true_test[iflevel] = 0; --iflevel; } return __first; } template _InputIterator pp::handle_ifdef (bool check_undefined, _InputIterator __first, _InputIterator __last) { if (test_if_level()) { _InputIterator end_macro_name = skip_identifier (__first, __last); std::size_t __size; #if defined(__SUNPRO_CC) std::distance (__first, end_macro_name, __size); #else __size = std::distance (__first, end_macro_name); #endif assert (__size < 256); char __buffer [256]; std::copy (__first, end_macro_name, __buffer); bool value = env.resolve (__buffer, __size) != 0; __first = end_macro_name; if (check_undefined) value = !value; _M_true_test[iflevel] = value; _M_skipping[iflevel] = !value; } return __first; } template _InputIterator pp::handle_undef(_InputIterator __first, _InputIterator __last) { __first = skip_blanks (__first, __last); _InputIterator end_macro_name = skip_identifier (__first, __last); assert (end_macro_name != __first); std::size_t __size; #if defined(__SUNPRO_CC) std::distance (__first, end_macro_name, __size); #else __size = std::distance (__first, end_macro_name); #endif assert (__size < 256); char __buffer [256]; std::copy (__first, end_macro_name, __buffer); pp_fast_string const __tmp (__buffer, __size); env.unbind (&__tmp); __first = end_macro_name; return __first; } template char pp::peek_char (_InputIterator __first, _InputIterator __last) { if (__first == __last) return 0; return *++__first; } template _InputIterator pp::next_token (_InputIterator __first, _InputIterator __last, int *kind) { __first = skip_blanks (__first, __last); if (__first == __last) { *kind = 0; return __first; } char ch = *__first; char ch2 = peek_char (__first, __last); switch (ch) { case '/': if (ch2 == '/' || ch2 == '*') { __first = skip_comment_or_divop (__first, __last); return next_token (__first, __last, kind); } ++__first; *kind = '/'; break; case '<': ++__first; if (ch2 == '<') { ++__first; *kind = TOKEN_LT_LT; } else if (ch2 == '=') { ++__first; *kind = TOKEN_LT_EQ; } else *kind = '<'; return __first; case '>': ++__first; if (ch2 == '>') { ++__first; *kind = TOKEN_GT_GT; } else if (ch2 == '=') { ++__first; *kind = TOKEN_GT_EQ; } else *kind = '>'; return __first; case '!': ++__first; if (ch2 == '=') { ++__first; *kind = TOKEN_NOT_EQ; } else *kind = '!'; return __first; case '=': ++__first; if (ch2 == '=') { ++__first; *kind = TOKEN_EQ_EQ; } else *kind = '='; return __first; case '|': ++__first; if (ch2 == '|') { ++__first; *kind = TOKEN_OR_OR; } else *kind = '|'; return __first; case '&': ++__first; if (ch2 == '&') { ++__first; *kind = TOKEN_AND_AND; } else *kind = '&'; return __first; default: if (pp_isalpha (ch) || ch == '_') { _InputIterator end = skip_identifier (__first, __last); _M_current_text.assign (__first, end); token_text = &_M_current_text; __first = end; if (*token_text == "defined") *kind = TOKEN_DEFINED; else *kind = TOKEN_IDENTIFIER; } else if (pp_isdigit (ch)) { _InputIterator end = skip_number (__first, __last); std::string __str (__first, __last); char ch = __str [__str.size () - 1]; if (ch == 'u' || ch == 'U') { token_uvalue = strtoul (__str.c_str (), 0, 0); *kind = TOKEN_UNUMBER; } else { token_value = strtol (__str.c_str (), 0, 0); *kind = TOKEN_NUMBER; } __first = end; } else *kind = *__first++; } return __first; } } // namespace rpp #endif // PP_ENGINE_BITS_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/rpp/pp-engine.h000066400000000000000000000212561170724227300242070ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef PP_ENGINE_H #define PP_ENGINE_H namespace rpp { struct Value { enum Kind { Kind_Long, Kind_ULong, }; Kind kind; union { long l; unsigned long ul; }; inline bool is_ulong () const { return kind == Kind_ULong; } inline void set_ulong (unsigned long v) { ul = v; kind = Kind_ULong; } inline void set_long (long v) { l = v; kind = Kind_Long; } inline bool is_zero () const { return l == 0; } #define PP_DEFINE_BIN_OP(name, op) \ inline Value &name (const Value &other) \ { \ if (is_ulong () || other.is_ulong ()) \ set_ulong (ul op other.ul); \ else \ set_long (l op other.l); \ return *this; \ } PP_DEFINE_BIN_OP(op_add, +) PP_DEFINE_BIN_OP(op_sub, -) PP_DEFINE_BIN_OP(op_mult, *) PP_DEFINE_BIN_OP(op_div, /) PP_DEFINE_BIN_OP(op_mod, %) PP_DEFINE_BIN_OP(op_lhs, <<) PP_DEFINE_BIN_OP(op_rhs, >>) PP_DEFINE_BIN_OP(op_lt, <) PP_DEFINE_BIN_OP(op_gt, >) PP_DEFINE_BIN_OP(op_le, <=) PP_DEFINE_BIN_OP(op_ge, >=) PP_DEFINE_BIN_OP(op_eq, ==) PP_DEFINE_BIN_OP(op_ne, !=) PP_DEFINE_BIN_OP(op_bit_and, &) PP_DEFINE_BIN_OP(op_bit_or, |) PP_DEFINE_BIN_OP(op_bit_xor, ^) PP_DEFINE_BIN_OP(op_and, &&) PP_DEFINE_BIN_OP(op_or, ||) #undef PP_DEFINE_BIN_OP }; class pp { pp_environment &env; pp_macro_expander expand; pp_skip_identifier skip_identifier; pp_skip_comment_or_divop skip_comment_or_divop; pp_skip_blanks skip_blanks; pp_skip_number skip_number; std::vector include_paths; std::string _M_current_text; enum { MAX_LEVEL = 512 }; int _M_skipping[MAX_LEVEL]; int _M_true_test[MAX_LEVEL]; int iflevel; union { long token_value; unsigned long token_uvalue; std::string *token_text; }; enum INCLUDE_POLICY { INCLUDE_GLOBAL, INCLUDE_LOCAL }; enum TOKEN_TYPE { TOKEN_NUMBER = 1000, TOKEN_UNUMBER, TOKEN_IDENTIFIER, TOKEN_DEFINED, TOKEN_LT_LT, TOKEN_LT_EQ, TOKEN_GT_GT, TOKEN_GT_EQ, TOKEN_EQ_EQ, TOKEN_NOT_EQ, TOKEN_OR_OR, TOKEN_AND_AND, }; enum PP_DIRECTIVE_TYPE { PP_UNKNOWN_DIRECTIVE, PP_DEFINE, PP_INCLUDE, PP_INCLUDE_NEXT, PP_ELIF, PP_ELSE, PP_ENDIF, PP_IF, PP_IFDEF, PP_IFNDEF, PP_UNDEF, PP_PRAGMA, PP_ERROR, PP_WARNING }; public: pp (pp_environment &__env); inline std::back_insert_iterator > include_paths_inserter (); inline void push_include_path (std::string const &__path); inline std::vector::iterator include_paths_begin (); inline std::vector::iterator include_paths_end (); inline std::vector::const_iterator include_paths_begin () const; inline std::vector::const_iterator include_paths_end () const; template inline _InputIterator eval_expression (_InputIterator __first, _InputIterator __last, Value *result); template void file (std::string const &filename, _OutputIterator __result); template void file (FILE *fp, _OutputIterator __result); template void operator () (_InputIterator __first, _InputIterator __last, _OutputIterator __result); private: inline bool file_isdir (std::string const &__filename) const; inline bool file_exists (std::string const &__filename) const; FILE *find_include_file (std::string const &__filename, std::string *__filepath, INCLUDE_POLICY __include_policy, bool __skip_current_path = false) const; inline int skipping() const; bool test_if_level(); inline std::string fix_file_path (std::string const &filename) const; inline bool is_absolute (std::string const &filename) const; PP_DIRECTIVE_TYPE find_directive (char const *__directive, std::size_t __size) const; template bool find_header_protection (_InputIterator __first, _InputIterator __last, std::string *__prot); template _InputIterator skip (_InputIterator __first, _InputIterator __last); template _InputIterator eval_primary(_InputIterator __first, _InputIterator __last, Value *result); template _InputIterator eval_multiplicative(_InputIterator __first, _InputIterator __last, Value *result); template _InputIterator eval_additive(_InputIterator __first, _InputIterator __last, Value *result); template _InputIterator eval_shift(_InputIterator __first, _InputIterator __last, Value *result); template _InputIterator eval_relational(_InputIterator __first, _InputIterator __last, Value *result); template _InputIterator eval_equality(_InputIterator __first, _InputIterator __last, Value *result); template _InputIterator eval_and(_InputIterator __first, _InputIterator __last, Value *result); template _InputIterator eval_xor(_InputIterator __first, _InputIterator __last, Value *result); template _InputIterator eval_or(_InputIterator __first, _InputIterator __last, Value *result); template _InputIterator eval_logical_and(_InputIterator __first, _InputIterator __last, Value *result); template _InputIterator eval_logical_or(_InputIterator __first, _InputIterator __last, Value *result); template _InputIterator eval_constant_expression(_InputIterator __first, _InputIterator __last, Value *result); template _InputIterator handle_directive(char const *__directive, std::size_t __size, _InputIterator __first, _InputIterator __last, _OutputIterator __result); template _InputIterator handle_include(bool skip_current_path, _InputIterator __first, _InputIterator __last, _OutputIterator __result); template _InputIterator handle_define (_InputIterator __first, _InputIterator __last); template _InputIterator handle_if (_InputIterator __first, _InputIterator __last); template _InputIterator handle_else (_InputIterator __first, _InputIterator __last); template _InputIterator handle_elif (_InputIterator __first, _InputIterator __last); template _InputIterator handle_endif (_InputIterator __first, _InputIterator __last); template _InputIterator handle_ifdef (bool check_undefined, _InputIterator __first, _InputIterator __last); template _InputIterator handle_undef(_InputIterator __first, _InputIterator __last); template inline char peek_char (_InputIterator __first, _InputIterator __last); template _InputIterator next_token (_InputIterator __first, _InputIterator __last, int *kind); }; } // namespace rpp #endif // PP_ENGINE_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/rpp/pp-environment.h000066400000000000000000000101441170724227300253000ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef PP_ENVIRONMENT_H #define PP_ENVIRONMENT_H #include #include namespace rpp { class pp_environment { public: typedef std::vector::const_iterator const_iterator; public: pp_environment (): current_line (0), _M_hash_size (4093) { _M_base = (pp_macro **) memset (new pp_macro* [_M_hash_size], 0, _M_hash_size * sizeof (pp_macro*)); } ~pp_environment () { for (std::size_t i = 0; i < _M_macros.size (); ++i) delete _M_macros [i]; delete [] _M_base; } const_iterator first_macro () const { return _M_macros.begin (); } const_iterator last_macro () const { return _M_macros.end (); } inline void bind (pp_fast_string const *__name, pp_macro const &__macro) { std::size_t h = hash_code (*__name) % _M_hash_size; pp_macro *m = new pp_macro (__macro); m->name = __name; m->next = _M_base [h]; m->hash_code = h; _M_base [h] = m; _M_macros.push_back (m); if (_M_macros.size() == _M_hash_size) rehash(); } inline void unbind (pp_fast_string const *__name) { if (pp_macro *m = resolve (__name)) m->hidden = true; } inline void unbind (char const *__s, std::size_t __size) { pp_fast_string __tmp (__s, __size); unbind (&__tmp); } inline pp_macro *resolve (pp_fast_string const *__name) const { std::size_t h = hash_code (*__name) % _M_hash_size; pp_macro *it = _M_base [h]; while (it && it->name && it->hash_code == h && (*it->name != *__name || it->hidden)) it = it->next; return it; } inline pp_macro *resolve (char const *__data, std::size_t __size) const { pp_fast_string const __tmp (__data, __size); return resolve (&__tmp); } std::string current_file; int current_line; private: inline std::size_t hash_code (pp_fast_string const &s) const { std::size_t hash_value = 0; for (std::size_t i = 0; i < s.size (); ++i) hash_value = (hash_value << 5) - hash_value + s.at (i); return hash_value; } void rehash() { delete[] _M_base; _M_hash_size <<= 1; _M_base = (pp_macro **) memset (new pp_macro* [_M_hash_size], 0, _M_hash_size * sizeof(pp_macro*)); for (std::size_t index = 0; index < _M_macros.size (); ++index) { pp_macro *elt = _M_macros [index]; std::size_t h = hash_code (*elt->name) % _M_hash_size; elt->next = _M_base [h]; elt->hash_code = h; _M_base [h] = elt; } } private: std::vector _M_macros; pp_macro **_M_base; std::size_t _M_hash_size; }; } // namespace rpp #endif // PP_ENVIRONMENT_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/rpp/pp-fwd.h000066400000000000000000000033171170724227300235200ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef PP_FWD_H #define PP_FWD_H namespace rpp { template class pp_string; typedef pp_string pp_fast_string; #endif // PP_FWD_H } // namespace rpp // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/rpp/pp-internal.h000066400000000000000000000070401170724227300245510ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef PP_INTERNAL_H #define PP_INTERNAL_H #include #include namespace rpp { namespace _PP_internal { inline void extract_file_path (const std::string &__filename, std::string *__filepath) { std::size_t __index = __filename.rfind (PATH_SEPARATOR); if (__index == std::string::npos) *__filepath = "/"; else __filepath->assign (__filename, 0, __index + 1); } template void output_line(const std::string &__filename, int __line, _OutputIterator __result) { std::string __msg; __msg += "# "; char __line_descr[16]; pp_snprintf (__line_descr, 16, "%d", __line); __msg += __line_descr; __msg += " \""; if (__filename.empty ()) __msg += ""; else __msg += __filename; __msg += "\"\n"; std::copy (__msg.begin (), __msg.end (), __result); } template inline bool comment_p (_InputIterator __first, _InputIterator __last) /*const*/ { if (__first == __last) return false; if (*__first != '/') return false; if (++__first == __last) return false; return (*__first == '/' || *__first == '*'); } struct _Compare_string: public std::binary_function { inline bool operator () (pp_fast_string const *__lhs, pp_fast_string const *__rhs) const { return *__lhs < *__rhs; } }; struct _Equal_to_string: public std::binary_function { inline bool operator () (pp_fast_string const *__lhs, pp_fast_string const *__rhs) const { return *__lhs == *__rhs; } }; struct _Hash_string: public std::unary_function { inline std::size_t operator () (pp_fast_string const *__s) const { char const *__ptr = __s->begin (); std::size_t __size = __s->size (); std::size_t __h = 0; for (std::size_t i = 0; i < __size; ++i) __h = (__h << 5) - __h + __ptr [i]; return __h; } }; } // _PP_internal } // namespace rpp #endif // PP_INTERNAL_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/rpp/pp-iterator.h000066400000000000000000000054161170724227300245730ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef PP_ITERATOR_H #define PP_ITERATOR_H #include namespace rpp { class pp_null_output_iterator : public std::iterator { public: pp_null_output_iterator() {} template pp_null_output_iterator &operator=(_Tp const &) { return *this; } inline pp_null_output_iterator &operator * () { return *this; } inline pp_null_output_iterator &operator ++ () { return *this; } inline pp_null_output_iterator operator ++ (int) { return *this; } }; template class pp_output_iterator : public std::iterator { std::string &_M_result; public: explicit pp_output_iterator(std::string &__result): _M_result (__result) {} inline pp_output_iterator &operator=(typename _Container::const_reference __v) { if (_M_result.capacity () == _M_result.size ()) _M_result.reserve (_M_result.capacity () << 2); _M_result.push_back(__v); return *this; } inline pp_output_iterator &operator * () { return *this; } inline pp_output_iterator &operator ++ () { return *this; } inline pp_output_iterator operator ++ (int) { return *this; } }; } // namespace rpp #endif // PP_ITERATOR_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/rpp/pp-macro-expander.h000066400000000000000000000321651170724227300256500ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef PP_MACRO_EXPANDER_H #define PP_MACRO_EXPANDER_H #include namespace rpp { struct pp_frame { pp_macro *expanding_macro; std::vector *actuals; pp_frame (pp_macro *__expanding_macro, std::vector *__actuals): expanding_macro (__expanding_macro), actuals (__actuals) {} }; class pp_macro_expander { pp_environment &env; pp_frame *frame; pp_skip_number skip_number; pp_skip_identifier skip_identifier; pp_skip_string_literal skip_string_literal; pp_skip_char_literal skip_char_literal; pp_skip_argument skip_argument; pp_skip_comment_or_divop skip_comment_or_divop; pp_skip_blanks skip_blanks; pp_skip_whitespaces skip_whitespaces; std::string const *resolve_formal (pp_fast_string const *__name) { assert (__name != 0); if (! frame) return 0; assert (frame->expanding_macro != 0); std::vector const formals = frame->expanding_macro->formals; for (std::size_t index = 0; index < formals.size(); ++index) { pp_fast_string const *formal = formals[index]; if (*formal != *__name) continue; else if (frame->actuals && index < frame->actuals->size()) return &(*frame->actuals)[index]; else assert (0); // internal error? } return 0; } public: // attributes int lines; int generated_lines; public: pp_macro_expander (pp_environment &__env, pp_frame *__frame = 0): env (__env), frame (__frame), lines (0), generated_lines (0) {} template _InputIterator operator () (_InputIterator __first, _InputIterator __last, _OutputIterator __result) { generated_lines = 0; __first = skip_blanks (__first, __last); lines = skip_blanks.lines; while (__first != __last) { if (*__first == '\n') { *__result++ = *__first; ++lines; __first = skip_blanks (++__first, __last); lines += skip_blanks.lines; if (__first != __last && *__first == '#') break; } else if (*__first == '#') { __first = skip_blanks (++__first, __last); lines += skip_blanks.lines; _InputIterator end_id = skip_identifier (__first, __last); // ### rewrite: not safe char name_buffer[512], *cp = name_buffer; std::copy (__first, end_id, cp); std::size_t name_size = end_id - __first; name_buffer[name_size] = '\0'; pp_fast_string fast_name (name_buffer, name_size); if (std::string const *actual = resolve_formal (&fast_name)) { *__result++ = '\"'; for (std::string::const_iterator it = skip_whitespaces (actual->begin (), actual->end ()); it != actual->end (); ++it) { if (*it == '"') { *__result++ = '\\'; *__result++ = *it; } else if (*it == '\n') { *__result++ = '"'; *__result++ = '\n'; *__result++ = '"'; } else *__result++ = *it; } *__result++ = '\"'; __first = end_id; } else *__result++ = '#'; // ### warning message? } else if (*__first == '\"') { _InputIterator next_pos = skip_string_literal (__first, __last); lines += skip_string_literal.lines; std::copy (__first, next_pos, __result); __first = next_pos; } else if (*__first == '\'') { _InputIterator next_pos = skip_char_literal (__first, __last); lines += skip_char_literal.lines; std::copy (__first, next_pos, __result); __first = next_pos; } else if (_PP_internal::comment_p (__first, __last)) { __first = skip_comment_or_divop (__first, __last); int n = skip_comment_or_divop.lines; lines += n; while (n-- > 0) *__result++ = '\n'; } else if (pp_isspace (*__first)) { for (; __first != __last; ++__first) { if (*__first == '\n' || !pp_isspace (*__first)) break; } *__result = ' '; } else if (pp_isdigit (*__first)) { _InputIterator next_pos = skip_number (__first, __last); lines += skip_number.lines; std::copy (__first, next_pos, __result); __first = next_pos; } else if (pp_isalpha (*__first) || *__first == '_') { _InputIterator name_begin = __first; _InputIterator name_end = skip_identifier (__first, __last); __first = name_end; // advance // search for the paste token _InputIterator next = skip_blanks (__first, __last); if (next != __last && *next == '#') { ++next; if (next != __last && *next == '#') __first = skip_blanks(++next, __last); } // ### rewrite: not safe std::ptrdiff_t name_size; #if defined(__SUNPRO_CC) std::distance (name_begin, name_end, name_size); #else name_size = std::distance (name_begin, name_end); #endif assert (name_size >= 0 && name_size < 512); char name_buffer[512], *cp = name_buffer; std::size_t __size = name_end - name_begin; std::copy (name_begin, name_end, cp); name_buffer[__size] = '\0'; pp_fast_string fast_name (name_buffer, name_size); if (std::string const *actual = resolve_formal (&fast_name)) { std::copy (actual->begin (), actual->end (), __result); continue; } static bool hide_next = false; // ### remove me pp_macro *macro = env.resolve (name_buffer, name_size); if (! macro || macro->hidden || hide_next) { hide_next = ! strcmp (name_buffer, "defined"); if (__size == 8 && name_buffer [0] == '_' && name_buffer [1] == '_') { if (! strcmp (name_buffer, "__LINE__")) { char buf [16]; char *end = buf + pp_snprintf (buf, 16, "%d", env.current_line + lines); std::copy (&buf [0], end, __result); continue; } else if (! strcmp (name_buffer, "__FILE__")) { __result++ = '"'; std::copy (env.current_file.begin (), env.current_file.end (), __result); // ### quote __result++ = '"'; continue; } } std::copy (name_begin, name_end, __result); continue; } if (! macro->function_like) { pp_macro *m = 0; if (macro->definition) { macro->hidden = true; std::string __tmp; __tmp.reserve (256); pp_macro_expander expand_macro (env); expand_macro (macro->definition->begin (), macro->definition->end (), std::back_inserter (__tmp)); generated_lines += expand_macro.lines; if (! __tmp.empty ()) { std::string::iterator __begin_id = skip_whitespaces (__tmp.begin (), __tmp.end ()); std::string::iterator __end_id = skip_identifier (__begin_id, __tmp.end ()); if (__end_id == __tmp.end ()) { std::string __id; __id.assign (__begin_id, __end_id); std::size_t x; #if defined(__SUNPRO_CC) std::distance (__begin_id, __end_id, x); #else x = std::distance (__begin_id, __end_id); #endif m = env.resolve (__id.c_str (), x); } if (! m) std::copy (__tmp.begin (), __tmp.end (), __result); } macro->hidden = false; } if (! m) continue; macro = m; } // function like macro _InputIterator arg_it = skip_whitespaces (__first, __last); if (arg_it == __last || *arg_it != '(') { std::copy (name_begin, name_end, __result); lines += skip_whitespaces.lines; __first = arg_it; continue; } std::vector actuals; actuals.reserve (5); ++arg_it; // skip '(' pp_macro_expander expand_actual (env, frame); _InputIterator arg_end = skip_argument_variadics (actuals, macro, arg_it, __last); if (arg_it != arg_end) { std::string actual (arg_it, arg_end); actuals.resize (actuals.size() + 1); actuals.back ().reserve (255); expand_actual (actual.begin (), actual.end(), std::back_inserter (actuals.back())); arg_it = arg_end; } while (arg_it != __last && *arg_end == ',') { ++arg_it; // skip ',' arg_end = skip_argument_variadics (actuals, macro, arg_it, __last); std::string actual (arg_it, arg_end); actuals.resize (actuals.size() + 1); actuals.back ().reserve (255); expand_actual (actual.begin (), actual.end(), std::back_inserter (actuals.back())); arg_it = arg_end; } assert (arg_it != __last && *arg_it == ')'); ++arg_it; // skip ')' __first = arg_it; #if 0 // ### enable me assert ((macro->variadics && macro->formals.size () >= actuals.size ()) || macro->formals.size() == actuals.size()); #endif pp_frame frame (macro, &actuals); pp_macro_expander expand_macro (env, &frame); macro->hidden = true; expand_macro (macro->definition->begin (), macro->definition->end (), __result); macro->hidden = false; generated_lines += expand_macro.lines; } else *__result++ = *__first++; } return __first; } template _InputIterator skip_argument_variadics (std::vector const &__actuals, pp_macro *__macro, _InputIterator __first, _InputIterator __last) { _InputIterator arg_end = skip_argument (__first, __last); while (__macro->variadics && __first != arg_end && arg_end != __last && *arg_end == ',' && (__actuals.size () + 1) == __macro->formals.size ()) { arg_end = skip_argument (++arg_end, __last); } return arg_end; } }; } // namespace rpp #endif // PP_MACRO_EXPANDER_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/rpp/pp-macro.h000066400000000000000000000043471170724227300240450ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef PP_MACRO_H #define PP_MACRO_H namespace rpp { struct pp_macro { #if defined (PP_WITH_MACRO_POSITION) pp_fast_string const *file; #endif pp_fast_string const *name; pp_fast_string const *definition; std::vector formals; union { int unsigned state; struct { int unsigned hidden: 1; int unsigned function_like: 1; int unsigned variadics: 1; }; }; int lines; pp_macro *next; std::size_t hash_code; inline pp_macro(): #if defined (PP_WITH_MACRO_POSITION) file (0), #endif name (0), definition (0), state (0), lines (0), next (0), hash_code (0) {} }; } // namespace rpp #endif // PP_MACRO_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/rpp/pp-main.cpp000066400000000000000000000176701170724227300242260ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include "pp.h" using namespace rpp; #ifndef GCC_MACHINE # define GCC_MACHINE "i386-redhat-linux" #endif #ifndef GCC_VERSION # define GCC_VERSION "4.1.1" #endif void usage () { std::cerr << "usage: rpp file.cpp" << std::endl; ::exit (EXIT_FAILURE); } void dump_macros (pp_environment &env, pp &, std::ostream &__out) { for (pp_environment::const_iterator it = env.first_macro (); it != env.last_macro (); ++it) { pp_macro const *m = *it; if (m->hidden) continue; std::string id (m->name->begin (), m->name->end ()); __out << "#define " << id; if (m->function_like) { __out << "("; for (std::size_t i = 0; i < m->formals.size (); ++i) { if (i != 0) __out << ", "; pp_fast_string const *f = m->formals [i]; std::string name (f->begin (), f->end ()); __out << name; } if (m->variadics) __out << "..."; __out << ")"; } __out << "\t"; if (m->definition) { std::string def (m->definition->begin (), m->definition->end ()); __out << def; } __out << std::endl; } } int main (int, char *argv []) { char const *input_file = 0; char const *output_file = 0; char const *include_pch_file = 0; bool opt_help = false; bool opt_dump_macros = false; bool opt_pch = false; pp_environment env; pp preprocess(env); std::string result; result.reserve (20 * 1024); // 20K pp_output_iterator out (result); pp_null_output_iterator null_out; preprocess.push_include_path ("/usr/include"); preprocess.push_include_path ("/usr/lib/gcc/" GCC_MACHINE "/" GCC_VERSION "/include"); preprocess.push_include_path ("/usr/include/c++/" GCC_VERSION); preprocess.push_include_path ("/usr/include/c++/" GCC_VERSION "/" GCC_MACHINE); std::string extra_args; while (const char *arg = *++argv) { if (arg [0] != '-') input_file = arg; else if (! strcmp (arg, "-help")) opt_help = true; else if (! strcmp (arg, "-dM")) opt_dump_macros = true; else if (! strcmp (arg, "-pch")) opt_pch = true; else if (! strcmp (arg, "-msse")) { pp_macro __macro; __macro.name = pp_symbol::get ("__SSE__", 7); env.bind (__macro.name, __macro); __macro.name = pp_symbol::get ("__MMX__", 7); env.bind (__macro.name, __macro); } else if (! strcmp (arg, "-include")) { if (argv [1]) include_pch_file = *++argv; } else if (! strncmp (arg, "-o", 2)) { arg += 2; if (! arg [0] && argv [1]) arg = *++argv; if (arg) output_file = arg; } else if (! strncmp (arg, "-conf", 8)) { if (argv [1]) preprocess.file (*++argv, null_out); } else if (! strncmp (arg, "-I", 2)) { arg += 2; if (! arg [0] && argv [1]) arg = *++argv; if (arg) preprocess.push_include_path (arg); } else if (! strncmp (arg, "-U", 2)) { arg += 2; if (! arg [0] && argv [1]) arg = *++argv; if (arg) { env.unbind (arg, strlen (arg)); } } else if (! strncmp (arg, "-D", 2)) { arg += 2; if (! arg [0] && argv [1]) arg = *++argv; if (arg) { pp_macro __macro; char const *end = arg; char const *eq = 0; for (; *end; ++end) { if (*end == '=') eq = end; } if (eq != 0) { __macro.name = pp_symbol::get (arg, eq - arg); __macro.definition = pp_symbol::get (eq + 1, end - (eq + 1)); } else { __macro.name = pp_symbol::get (arg, end - arg); __macro.definition = 0; } env.bind (__macro.name, __macro); } } else { extra_args += " "; extra_args += arg; } } if (! input_file || opt_help) { usage (); return EXIT_FAILURE; } std::string __ifile (input_file); bool is_c_file = false; if (__ifile.size () > 2 && __ifile [__ifile.size () - 1] == 'c' && __ifile [__ifile.size () - 2] == '.') { is_c_file = true; env.unbind ("__cplusplus", 11); pp_macro __macro; __macro.name = pp_symbol::get ("__null"); __macro.definition = pp_symbol::get ("((void*) 0)"); env.bind (__macro.name, __macro); // turn off the pch include_pch_file = 0; } else if (include_pch_file) { std::string __pch (include_pch_file); __pch += ".gch/c++.conf"; //std::cerr << "*** pch file " << __pch << std::endl; preprocess.file (__pch, null_out); } if (opt_dump_macros) { preprocess.file (input_file, null_out); dump_macros (env, preprocess, std::cout); return EXIT_SUCCESS; } preprocess.file (input_file, out); if (opt_pch) { if (! output_file) { std::cerr << "*** WARNING expected a file name" << std::endl; return EXIT_FAILURE; } std::string __conf_file (output_file); __conf_file += ".conf"; std::ofstream __out; __out.open (__conf_file.c_str ()); dump_macros (env, preprocess, __out); __out.close (); std::string __pp_file (output_file); __pp_file += ".i"; __out.open (__pp_file.c_str ()); __out.write (result.c_str (), result.size ()); __out.close (); return EXIT_SUCCESS; } std::ostream *__out = &std::cout; std::ofstream __ofile; if (output_file) { std::string __output_file_name (output_file); __ofile.open (output_file); __out = &__ofile; } if (include_pch_file) { std::string __pch (include_pch_file); __pch += ".gch/c++.i"; std::ifstream __in (__pch.c_str ()); char buffer [1024]; while (__in.read (buffer, 1024)) __out->write (buffer, 1024); __in.close (); } __out->write (result.c_str (), result.size ()); if (output_file) __ofile.close (); return EXIT_SUCCESS; } // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/rpp/pp-qt-configuration000066400000000000000000000006671170724227300260100ustar00rootroot00000000000000#define __cplusplus 1 #define __STDC__ // Qt #define QOBJECTDEFS_H // not yet supported #define Q_SLOTS slots #define Q_SIGNALS signals #define Q_FLAGS(a) #define Q_PRIVATE_SLOT(a, b) #define Q_DECLARE_INTERFACE(a,b) #define Q_INTERFACES(a) #define Q_GADGET #define Q_OVERRIDE(a) #define Q_OS_OS2 #define Q_NO_USING_KEYWORD // There are symbols in Qt that exist in Debug but // not in release #define QT_NO_DEBUG #define QT_JAMBI_RUN qtscriptgenerator-src-0.2.0/generator/parser/rpp/pp-scanner.h000066400000000000000000000204271170724227300243720ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef PP_SCANNER_H #define PP_SCANNER_H namespace rpp { struct pp_skip_blanks { int lines; template _InputIterator operator () (_InputIterator __first, _InputIterator __last) { lines = 0; for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) { if (*__first == '\\') { _InputIterator __begin = __first; ++__begin; if (__begin != __last && *__begin == '\n') ++__first; else break; } else if (*__first == '\n' || !pp_isspace (*__first)) break; } return __first; } }; struct pp_skip_whitespaces { int lines; template _InputIterator operator () (_InputIterator __first, _InputIterator __last) { lines = 0; for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) { if (! pp_isspace (*__first)) break; } return __first; } }; struct pp_skip_comment_or_divop { int lines; template _InputIterator operator () (_InputIterator __first, _InputIterator __last) { enum { MAYBE_BEGIN, BEGIN, MAYBE_END, END, IN_COMMENT, IN_CXX_COMMENT } state (MAYBE_BEGIN); lines = 0; for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) { switch (state) { default: assert (0); break; case MAYBE_BEGIN: if (*__first != '/') return __first; state = BEGIN; break; case BEGIN: if (*__first == '*') state = IN_COMMENT; else if (*__first == '/') state = IN_CXX_COMMENT; else return __first; break; case IN_COMMENT: if (*__first == '*') state = MAYBE_END; break; case IN_CXX_COMMENT: if (*__first == '\n') return __first; break; case MAYBE_END: if (*__first == '/') state = END; else if (*__first != '*') state = IN_COMMENT; break; case END: return __first; } } return __first; } }; struct pp_skip_identifier { int lines; template _InputIterator operator () (_InputIterator __first, _InputIterator __last) { lines = 0; for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) { if (! pp_isalnum (*__first) && *__first != '_') break; } return __first; } }; struct pp_skip_number { int lines; template _InputIterator operator () (_InputIterator __first, _InputIterator __last) { lines = 0; for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) { if (! pp_isalnum (*__first) && *__first != '.') break; } return __first; } }; struct pp_skip_string_literal { int lines; template _InputIterator operator () (_InputIterator __first, _InputIterator __last) { enum { BEGIN, IN_STRING, QUOTE, END } state (BEGIN); lines = 0; for (; __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) { switch (state) { default: assert (0); break; case BEGIN: if (*__first != '\"') return __first; state = IN_STRING; break; case IN_STRING: assert (*__first != '\n'); if (*__first == '\"') state = END; else if (*__first == '\\') state = QUOTE; break; case QUOTE: state = IN_STRING; break; case END: return __first; } } return __first; } }; struct pp_skip_char_literal { int lines; template _InputIterator operator () (_InputIterator __first, _InputIterator __last) { enum { BEGIN, IN_STRING, QUOTE, END } state (BEGIN); lines = 0; for (; state != END && __first != __last; lines += (*__first != '\n' ? 0 : 1), ++__first) { switch (state) { default: assert (0); break; case BEGIN: if (*__first != '\'') return __first; state = IN_STRING; break; case IN_STRING: assert (*__first != '\n'); if (*__first == '\'') state = END; else if (*__first == '\\') state = QUOTE; break; case QUOTE: state = IN_STRING; break; } } return __first; } }; struct pp_skip_argument { pp_skip_identifier skip_number; pp_skip_identifier skip_identifier; pp_skip_string_literal skip_string_literal; pp_skip_char_literal skip_char_literal; pp_skip_comment_or_divop skip_comment_or_divop; int lines; template _InputIterator operator () (_InputIterator __first, _InputIterator __last) { int depth = 0; lines = 0; while (__first != __last) { if (!depth && (*__first == ')' || *__first == ',')) break; else if (*__first == '(') ++depth, ++__first; else if (*__first == ')') --depth, ++__first; else if (*__first == '\"') { __first = skip_string_literal (__first, __last); lines += skip_string_literal.lines; } else if (*__first == '\'') { __first = skip_char_literal (__first, __last); lines += skip_char_literal.lines; } else if (*__first == '/') { __first = skip_comment_or_divop (__first, __last); lines += skip_comment_or_divop.lines; } else if (pp_isalpha (*__first) || *__first == '_') { __first = skip_identifier (__first, __last); lines += skip_identifier.lines; } else if (pp_isdigit (*__first)) { __first = skip_number (__first, __last); lines += skip_number.lines; } else if (*__first == '\n') { ++__first; ++lines; } else ++__first; } return __first; } }; } // namespace rpp #endif // PP_SCANNER_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/rpp/pp-string.h000066400000000000000000000063131170724227300242450ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef PP_STRING_H #define PP_STRING_H namespace rpp { template class pp_string { typedef std::char_traits<_CharT> traits_type; typedef std::size_t size_type; _CharT const *_M_begin; std::size_t _M_size; public: inline pp_string (): _M_begin (0), _M_size(0) {} explicit pp_string (std::string const &__s): _M_begin (__s.c_str ()), _M_size (__s.size ()) {} inline pp_string (_CharT const *__begin, std::size_t __size): _M_begin (__begin), _M_size (__size) {} inline _CharT const *begin () const { return _M_begin; } inline _CharT const *end () const { return _M_begin + _M_size; } inline _CharT at (std::size_t index) const { return _M_begin [index]; } inline std::size_t size () const { return _M_size; } inline int compare (pp_string const &__other) const { size_type const __size = this->size(); size_type const __osize = __other.size(); size_type const __len = std::min (__size, __osize); int __r = traits_type::compare (_M_begin, __other._M_begin, __len); if (!__r) __r = (int) (__size - __osize); return __r; } inline bool operator == (pp_string const &__other) const { return compare (__other) == 0; } inline bool operator != (pp_string const &__other) const { return compare (__other) != 0; } inline bool operator < (pp_string const &__other) const { return compare (__other) < 0; } inline bool operator == (char const *s) const { std::size_t n = strlen (s); if (n != _M_size) return false; return ! strncmp (_M_begin, s, n); } inline bool operator != (char const *s) const { return ! operator == (s); } }; } // namespace rpp #endif // PP_STRING_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/rpp/pp-symbol.h000066400000000000000000000055701170724227300242500ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef PP_SYMBOL_H #define PP_SYMBOL_H namespace rpp { class pp_symbol { static rxx_allocator &allocator_instance () { static rxx_allocator__allocator; return __allocator; } public: static int &N() { static int __N; return __N; } static pp_fast_string const *get (char const *__data, std::size_t __size) { ++N(); char *data = allocator_instance ().allocate (__size + 1); memcpy(data, __data, __size); data[__size] = '\0'; char *where = allocator_instance ().allocate (sizeof (pp_fast_string)); return new (where) pp_fast_string (data, __size); } template static pp_fast_string const *get (_InputIterator __first, _InputIterator __last) { ++N(); std::ptrdiff_t __size; #if defined(__SUNPRO_CC) std::distance (__first, __last, __size); #else __size = std::distance (__first, __last); #endif assert (__size >= 0 && __size < 512); char *data = allocator_instance ().allocate (__size + 1); std::copy (__first, __last, data); data[__size] = '\0'; char *where = allocator_instance ().allocate (sizeof (pp_fast_string)); return new (where) pp_fast_string (data, __size); } static pp_fast_string const *get(std::string const &__s) { return get (__s.c_str (), __s.size ()); } }; } // namespace rpp #endif // PP_SYMBOL_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/rpp/pp.h000066400000000000000000000052071170724227300227420ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef PP_H #define PP_H #if defined(_WIN64) || defined(WIN64) || defined(__WIN64__) \ || defined(_WIN32) || defined(WIN32) || defined(__WIN32__) # define PP_OS_WIN #endif #include #include #include #include #include #include #include #include #include #ifdef HAVE_MMAP # include #endif #include #include #if (_MSC_VER >= 1400) # define FILENO _fileno #else # define FILENO fileno #endif #if defined (PP_OS_WIN) # define PATH_SEPARATOR '\\' #else # define PATH_SEPARATOR '/' #endif #if defined (RPP_JAMBI) # include "rxx_allocator.h" #else # include "rpp-allocator.h" #endif #if defined (_MSC_VER) # define pp_snprintf _snprintf #else # define pp_snprintf snprintf #endif #include "pp-fwd.h" #include "pp-cctype.h" #include "pp-string.h" #include "pp-symbol.h" #include "pp-internal.h" #include "pp-iterator.h" #include "pp-macro.h" #include "pp-environment.h" #include "pp-scanner.h" #include "pp-macro-expander.h" #include "pp-engine.h" #include "pp-engine-bits.h" #endif // PP_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/rpp/preprocessor.cpp000066400000000000000000000107161170724227300254050ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "preprocessor.h" #include // register callback for include hooks static void includeFileHook(const std::string &, const std::string &, FILE *); #define PP_HOOK_ON_FILE_INCLUDED(A, B, C) includeFileHook(A, B, C) #include "pp.h" using namespace rpp; #include class PreprocessorPrivate { public: QByteArray result; pp_environment env; QStringList includePaths; void initPP(pp &proc) { foreach(QString path, includePaths) proc.push_include_path(path.toStdString()); } }; QHash includedFiles; void includeFileHook(const std::string &fileName, const std::string &filePath, FILE *) { includedFiles[QString::fromStdString(fileName)].append(QString::fromStdString(filePath)); } Preprocessor::Preprocessor() { d = new PreprocessorPrivate; includedFiles.clear(); } Preprocessor::~Preprocessor() { delete d; } void Preprocessor::processFile(const QString &fileName) { pp proc(d->env); d->initPP(proc); d->result.reserve(d->result.size() + 20 * 1024); d->result += "# 1 \"" + fileName.toLatin1() + "\"\n"; // ### REMOVE ME proc.file(fileName.toLocal8Bit().constData(), std::back_inserter(d->result)); } void Preprocessor::processString(const QByteArray &str) { pp proc(d->env); d->initPP(proc); proc(str.begin(), str.end(), std::back_inserter(d->result)); } QByteArray Preprocessor::result() const { return d->result; } void Preprocessor::addIncludePaths(const QStringList &includePaths) { d->includePaths += includePaths; } QStringList Preprocessor::macroNames() const { QStringList macros; pp_environment::const_iterator it = d->env.first_macro(); while (it != d->env.last_macro()) { const pp_macro *m = *it; macros += QString::fromLatin1(m->name->begin(), m->name->size()); ++it; } return macros; } QList Preprocessor::macros() const { QList items; pp_environment::const_iterator it = d->env.first_macro(); while (it != d->env.last_macro()) { const pp_macro *m = *it; MacroItem item; item.name = QString::fromLatin1(m->name->begin(), m->name->size()); item.definition = QString::fromLatin1(m->definition->begin(), m->definition->size()); for (size_t i = 0; i < m->formals.size(); ++i) { item.parameters += QString::fromLatin1(m->formals[i]->begin(), m->formals[i]->size()); } item.isFunctionLike = m->function_like; #ifdef PP_WITH_MACRO_POSITION item.fileName = QString::fromLatin1(m->file->begin(), m->file->size()); #endif items += item; ++it; } return items; } /* int main() { Preprocessor pp; QStringList paths; paths << "/usr/include"; pp.addIncludePaths(paths); pp.processFile("pp-configuration"); pp.processFile("/usr/include/stdio.h"); qDebug() << pp.result(); return 0; } */ qtscriptgenerator-src-0.2.0/generator/parser/rpp/preprocessor.h000066400000000000000000000044061170724227300250510ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef PREPROCESSOR_H #define PREPROCESSOR_H #include #include #include class QByteArray; class PreprocessorPrivate; class Preprocessor { public: Preprocessor(); ~Preprocessor(); void processFile(const QString &fileName); void processString(const QByteArray &str); void addIncludePaths(const QStringList &includePaths); QByteArray result() const; QStringList macroNames() const; struct MacroItem { QString name; QStringList parameters; QString definition; bool isFunctionLike; #ifdef PP_WITH_MACRO_POSITION QString fileName; #endif }; QList macros() const; private: Q_DISABLE_COPY(Preprocessor) PreprocessorPrivate *d; }; #endif qtscriptgenerator-src-0.2.0/generator/parser/rpp/rpp.pri000066400000000000000000000010031170724227300234550ustar00rootroot00000000000000SOURCES += \ $$RXXPATH/rpp/preprocessor.cpp HEADERS += \ $$RXXPATH/rpp/pp-cctype.h \ $$RXXPATH/rpp/pp-engine-bits.h \ $$RXXPATH/rpp/pp-engine.h \ $$RXXPATH/rpp/pp-environment.h \ $$RXXPATH/rpp/pp-fwd.h \ $$RXXPATH/rpp/pp-internal.h \ $$RXXPATH/rpp/pp-iterator.h \ $$RXXPATH/rpp/pp-macro-expander.h \ $$RXXPATH/rpp/pp-macro.h \ $$RXXPATH/rpp/pp-scanner.h \ $$RXXPATH/rpp/pp-string.h \ $$RXXPATH/rpp/pp-symbol.h \ $$RXXPATH/rpp/pp.h \ $$RXXPATH/rpp/preprocessor.h INCLUDEPATH += $$PWD $$RXXPATH/rpp qtscriptgenerator-src-0.2.0/generator/parser/rxx.pri000066400000000000000000000031061170724227300227020ustar00rootroot00000000000000 isEmpty(RXXPATH):RXXPATH = $$PWD INCLUDEPATH += $$RXXPATH DEFINES += RXX_ALLOCATOR_INIT_0 HEADERS += $$RXXPATH/ast.h \ $$RXXPATH/lexer.h \ $$RXXPATH/list.h \ $$RXXPATH/parser.h \ $$RXXPATH/rxx_allocator.h \ $$RXXPATH/rpp-allocator.h \ $$RXXPATH/smallobject.h \ $$RXXPATH/tokens.h \ $$RXXPATH/symbol.h \ $$RXXPATH/control.h \ $$RXXPATH/visitor.h \ $$RXXPATH/default_visitor.h \ $$RXXPATH/dumptree.h \ $$RXXPATH/binder.h \ $$RXXPATH/codemodel.h \ $$RXXPATH/codemodel_pointer.h \ $$RXXPATH/codemodel_fwd.h \ $$RXXPATH/type_compiler.h \ $$RXXPATH/name_compiler.h \ $$RXXPATH/declarator_compiler.h \ $$RXXPATH/class_compiler.h \ $$RXXPATH/codemodel_finder.h \ $$RXXPATH/compiler_utils.h SOURCES += $$RXXPATH/ast.cpp \ $$RXXPATH/lexer.cpp \ $$RXXPATH/list.cpp \ $$RXXPATH/parser.cpp \ $$RXXPATH/smallobject.cpp \ $$RXXPATH/control.cpp \ $$RXXPATH/visitor.cpp \ $$RXXPATH/default_visitor.cpp \ $$RXXPATH/dumptree.cpp \ $$RXXPATH/tokens.cpp \ $$RXXPATH/binder.cpp \ $$RXXPATH/codemodel.cpp \ $$RXXPATH/type_compiler.cpp \ $$RXXPATH/name_compiler.cpp \ $$RXXPATH/declarator_compiler.cpp \ $$RXXPATH/class_compiler.cpp \ $$RXXPATH/codemodel_finder.cpp \ $$RXXPATH/compiler_utils.cpp qtscriptgenerator-src-0.2.0/generator/parser/rxx.pro000066400000000000000000000004241170724227300227100ustar00rootroot00000000000000# File generated by kdevelop's qmake manager. # ------------------------------------------- # Subdir relative project main directory: . # Target is an application: r++0 include(rxx.pri) SOURCES += main.cpp TEMPLATE = app QT = core TARGET = r++0 CONFIG += debug_and_release qtscriptgenerator-src-0.2.0/generator/parser/rxx_allocator.h000066400000000000000000000072521170724227300244050ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef RXX_ALLOCATOR_H #define RXX_ALLOCATOR_H #include #include #include #include template class rxx_allocator { public: typedef _Tp value_type; typedef _Tp* pointer; typedef const _Tp* const_pointer; typedef _Tp& reference; typedef const _Tp& const_reference; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; static const size_type max_block_count = size_type(-1); static const size_type _S_block_size = 1 << 16; // 64K rxx_allocator() { _M_block_index = max_block_count; _M_current_index = 0; _M_storage = 0; _M_current_block = 0; } ~rxx_allocator() { for (size_type index = 0; index < _M_block_index + 1; ++index) delete[] _M_storage[index]; ::free(_M_storage); } pointer address(reference __val) { return &__val; } const_pointer address(const_reference __val) const { return &__val; } pointer allocate(size_type __n, const void* = 0) { const size_type bytes = __n * sizeof(_Tp); if (_M_current_block == 0 || _S_block_size < _M_current_index + bytes) { ++_M_block_index; _M_storage = reinterpret_cast (::realloc(_M_storage, sizeof(char*) * (1 + _M_block_index))); _M_current_block = _M_storage[_M_block_index] = reinterpret_cast (new char[_S_block_size]); #if defined(RXX_ALLOCATOR_INIT_0) // ### make it a policy ::memset(_M_current_block, 0, _S_block_size); #endif _M_current_index = 0; } pointer p = reinterpret_cast (_M_current_block + _M_current_index); _M_current_index += bytes; return p; } void deallocate(pointer __p, size_type __n) {} size_type max_size() const { return size_type(-1) / sizeof(_Tp); } void contruct(pointer __p, const_reference __val) { new (__p) _Tp(__val); } void destruct(pointer __p) { __p->~_Tp(); } private: template struct rebind { typedef rxx_allocator<_Tp1> other; }; template rxx_allocator(const rxx_allocator<_Tp1> &__o) {} private: size_type _M_block_index; size_type _M_current_index; char *_M_current_block; char **_M_storage; }; #endif // RXX_ALLOCATOR_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/smallobject.cpp000066400000000000000000000030701170724227300243500ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "smallobject.h" // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/smallobject.h000066400000000000000000000035001170724227300240130ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef SMALLOBJECT_H #define SMALLOBJECT_H #include "rxx_allocator.h" #include class pool { rxx_allocator __alloc; public: inline void *allocate(std::size_t __size); }; inline void *pool::allocate(std::size_t __size) { return __alloc.allocate(__size); } #endif // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/symbol.h000066400000000000000000000063551170724227300230340ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef SYMBOL_H #define SYMBOL_H #include #include #include #include struct NameSymbol { const char *data; std::size_t count; inline QString as_string() const { return QString::fromUtf8(data, (int) count); } inline bool operator == (const NameSymbol &other) const { return count == other.count && std::strncmp(data, other.data, count) == 0; } protected: inline NameSymbol() {} inline NameSymbol(const char *d, std::size_t c) : data(d), count(c) {} private: void operator = (const NameSymbol &); friend class NameTable; }; inline uint qHash(const NameSymbol &r) { uint hash_value = 0; for (std::size_t i=0; i &r) { uint hash_value = 0; for (std::size_t i=0; i KeyType; typedef QHash ContainerType; public: NameTable() {} ~NameTable() { qDeleteAll(_M_storage); } inline const NameSymbol *findOrInsert(const char *str, std::size_t len) { KeyType key(str, len); NameSymbol *name = _M_storage.value(key); if (!name) { name = new NameSymbol(str, len); _M_storage.insert(key, name); } return name; } inline std::size_t count() const { return _M_storage.size(); } private: ContainerType _M_storage; private: NameTable(const NameTable &other); void operator = (const NameTable &other); }; #endif // SYMBOL_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/tokens.cpp000066400000000000000000000124321170724227300233560ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include "tokens.h" static char const * const _S_token_names[] = { "K_DCOP", "Q_OBJECT", "Q_PROPERTY", "__attribute__", "__typeof", "and", "and_eq", "arrow", "asm", "assign", "auto", "bitand", "bitor", "bool", "break", "case", "catch", "char", "char_literal", "class", "comment", "compl", "concat", "const", "const_cast", "continue", "decr", "default", "delete", "do", "double", "dynamic_cast", "ellipsis", "else", "emit", "enum", "eq", "explicit", "export", "extern", "false", "float", "for", "friend", "geq", "goto", "identifier", "if", "incr", "inline", "int", "k_dcop", "k_dcop_signals", "leq", "long", "mutable", "namespace", "new", "not", "not_eq", "number_literal", "operator", "or", "or_eq", "preproc", "private", "protected", "ptrmem", "public", "register", "reinterpret_cast", "return", "scope", "shift", "short", "signals", "signed", "sizeof", "slots", "static", "static_cast", "string_literal", "struct", "switch", "template", "this", "throw", "true", "try", "typedef", "typeid", "typename", "union", "unsigned", "using", "virtual", "void", "volatile", "wchar_t", "while", "whitespaces", "xor", "xor_eq", "Q_ENUMS" }; static char _S_printable[][2] = { { char(32), '\0' }, { char(33), '\0' }, { char(34), '\0' }, { char(35), '\0' }, { char(36), '\0' }, { char(37), '\0' }, { char(38), '\0' }, { char(39), '\0' }, { char(40), '\0' }, { char(41), '\0' }, { char(42), '\0' }, { char(43), '\0' }, { char(44), '\0' }, { char(45), '\0' }, { char(46), '\0' }, { char(47), '\0' }, { char(48), '\0' }, { char(49), '\0' }, { char(50), '\0' }, { char(51), '\0' }, { char(52), '\0' }, { char(53), '\0' }, { char(54), '\0' }, { char(55), '\0' }, { char(56), '\0' }, { char(57), '\0' }, { char(58), '\0' }, { char(59), '\0' }, { char(60), '\0' }, { char(61), '\0' }, { char(62), '\0' }, { char(63), '\0' }, { char(64), '\0' }, { char(65), '\0' }, { char(66), '\0' }, { char(67), '\0' }, { char(68), '\0' }, { char(69), '\0' }, { char(70), '\0' }, { char(71), '\0' }, { char(72), '\0' }, { char(73), '\0' }, { char(74), '\0' }, { char(75), '\0' }, { char(76), '\0' }, { char(77), '\0' }, { char(78), '\0' }, { char(79), '\0' }, { char(80), '\0' }, { char(81), '\0' }, { char(82), '\0' }, { char(83), '\0' }, { char(84), '\0' }, { char(85), '\0' }, { char(86), '\0' }, { char(87), '\0' }, { char(88), '\0' }, { char(89), '\0' }, { char(90), '\0' }, { char(91), '\0' }, { char(92), '\0' }, { char(93), '\0' }, { char(94), '\0' }, { char(95), '\0' }, { char(96), '\0' }, { char(97), '\0' }, { char(98), '\0' }, { char(99), '\0' }, { char(100), '\0' }, { char(101), '\0' }, { char(102), '\0' }, { char(103), '\0' }, { char(104), '\0' }, { char(105), '\0' }, { char(106), '\0' }, { char(107), '\0' }, { char(108), '\0' }, { char(109), '\0' }, { char(110), '\0' }, { char(111), '\0' }, { char(112), '\0' }, { char(113), '\0' }, { char(114), '\0' }, { char(115), '\0' }, { char(116), '\0' }, { char(117), '\0' }, { char(118), '\0' }, { char(119), '\0' }, { char(120), '\0' }, { char(121), '\0' }, { char(122), '\0' }, { char(123), '\0' }, { char(124), '\0' }, { char(125), '\0' }, { char(126), '\0' }, { char(127), '\0' }, }; char const *token_name(int token) { if (token == 0) { return "eof"; } else if (token >= 32 && token <= 127) { return _S_printable[token - 32]; } else if (token >= 1000) { return _S_token_names[token - 1000]; } Q_ASSERT(0); return 0; } // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/tokens.h000066400000000000000000000070601170724227300230240ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef TOKENS_H #define TOKENS_H enum TOKEN_KIND { Token_EOF = 0, Token_K_DCOP = 1000, Token_Q_OBJECT, Token_Q_PROPERTY, Token___attribute__, Token___typeof, Token_and, Token_and_eq, Token_arrow, Token_asm, Token_assign, Token_auto, Token_bitand, Token_bitor, Token_bool, Token_break, Token_case, Token_catch, Token_char, Token_char_literal, Token_class, Token_comment, Token_compl, Token_concat, Token_const, Token_const_cast, Token_continue, Token_decr, Token_default, Token_delete, Token_do, Token_double, Token_dynamic_cast, Token_ellipsis, Token_else, Token_emit, Token_enum, Token_eq, Token_explicit, Token_export, Token_extern, Token_false, Token_float, Token_for, Token_friend, Token_geq, Token_goto, Token_identifier, Token_if, Token_incr, Token_inline, Token_int, Token_k_dcop, Token_k_dcop_signals, Token_leq, Token_long, Token_mutable, Token_namespace, Token_new, Token_not, Token_not_eq, Token_number_literal, Token_operator, Token_or, Token_or_eq, Token_preproc, Token_private, Token_protected, Token_ptrmem, Token_public, Token_register, Token_reinterpret_cast, Token_return, Token_scope, Token_shift, Token_short, Token_signals, Token_signed, Token_sizeof, Token_slots, Token_static, Token_static_cast, Token_string_literal, Token_struct, Token_switch, Token_template, Token_this, Token_throw, Token_true, Token_try, Token_typedef, Token_typeid, Token_typename, Token_union, Token_unsigned, Token_using, Token_virtual, Token_void, Token_volatile, Token_wchar_t, Token_while, Token_whitespaces, Token_xor, Token_xor_eq, Token_Q_ENUMS, Token_Q_INVOKABLE, TOKEN_KIND_COUNT }; char const *token_name(int token); #endif // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/type_compiler.cpp000066400000000000000000000074531170724227300247350ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ #include "type_compiler.h" #include "name_compiler.h" #include "lexer.h" #include "symbol.h" #include "tokens.h" #include "binder.h" #include TypeCompiler::TypeCompiler(Binder *binder) : _M_binder (binder), _M_token_stream(binder->tokenStream ()) { } void TypeCompiler::run(TypeSpecifierAST *node) { _M_type.clear(); _M_cv.clear(); visit(node); if (node && node->cv) { const ListNode *it = node->cv->toFront(); const ListNode *end = it; do { int kind = _M_token_stream->kind(it->element); if (! _M_cv.contains(kind)) _M_cv.append(kind); it = it->next; } while (it != end); } } void TypeCompiler::visitClassSpecifier(ClassSpecifierAST *node) { visit(node->name); } void TypeCompiler::visitEnumSpecifier(EnumSpecifierAST *node) { visit(node->name); } void TypeCompiler::visitElaboratedTypeSpecifier(ElaboratedTypeSpecifierAST *node) { visit(node->name); } void TypeCompiler::visitSimpleTypeSpecifier(SimpleTypeSpecifierAST *node) { if (const ListNode *it = node->integrals) { it = it->toFront(); const ListNode *end = it; QString current_item; do { std::size_t token = it->element; current_item += token_name(_M_token_stream->kind(token)); current_item += " "; it = it->next; } while (it != end); _M_type += current_item.trimmed(); } else if (node->type_of) { // ### implement me _M_type += QLatin1String("typeof<...>"); } visit(node->name); } void TypeCompiler::visitName(NameAST *node) { NameCompiler name_cc(_M_binder); name_cc.run(node); _M_type = name_cc.qualifiedName(); } QStringList TypeCompiler::cvString() const { QStringList lst; foreach (int q, cv()) { if (q == Token_const) lst.append(QLatin1String("const")); else if (q == Token_volatile) lst.append(QLatin1String("volatile")); } return lst; } bool TypeCompiler::isConstant() const { return _M_cv.contains(Token_const); } bool TypeCompiler::isVolatile() const { return _M_cv.contains(Token_volatile); } // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/type_compiler.h000066400000000000000000000047621170724227300244020ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef TYPE_COMPILER_H #define TYPE_COMPILER_H #include "default_visitor.h" #include #include #include class TokenStream; class Binder; class TypeCompiler: protected DefaultVisitor { public: TypeCompiler(Binder *binder); inline QStringList qualifiedName() const { return _M_type; } inline QList cv() const { return _M_cv; } bool isConstant() const; bool isVolatile() const; QStringList cvString() const; void run(TypeSpecifierAST *node); protected: virtual void visitClassSpecifier(ClassSpecifierAST *node); virtual void visitEnumSpecifier(EnumSpecifierAST *node); virtual void visitElaboratedTypeSpecifier(ElaboratedTypeSpecifierAST *node); virtual void visitSimpleTypeSpecifier(SimpleTypeSpecifierAST *node); virtual void visitName(NameAST *node); private: Binder *_M_binder; TokenStream *_M_token_stream; QStringList _M_type; QList _M_cv; }; #endif // TYPE_COMPILER_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/visitor.cpp000066400000000000000000000170471170724227300235610ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "visitor.h" Visitor::visitor_fun_ptr Visitor::_S_table[AST::NODE_KIND_COUNT] = { 0, reinterpret_cast(&Visitor::visitAccessSpecifier), reinterpret_cast(&Visitor::visitAsmDefinition), reinterpret_cast(&Visitor::visitBaseClause), reinterpret_cast(&Visitor::visitBaseSpecifier), reinterpret_cast(&Visitor::visitBinaryExpression), reinterpret_cast(&Visitor::visitCastExpression), reinterpret_cast(&Visitor::visitClassMemberAccess), reinterpret_cast(&Visitor::visitClassSpecifier), reinterpret_cast(&Visitor::visitCompoundStatement), reinterpret_cast(&Visitor::visitCondition), reinterpret_cast(&Visitor::visitConditionalExpression), reinterpret_cast(&Visitor::visitCppCastExpression), reinterpret_cast(&Visitor::visitCtorInitializer), reinterpret_cast(&Visitor::visitDeclarationStatement), reinterpret_cast(&Visitor::visitDeclarator), reinterpret_cast(&Visitor::visitDeleteExpression), reinterpret_cast(&Visitor::visitDoStatement), reinterpret_cast(&Visitor::visitElaboratedTypeSpecifier), reinterpret_cast(&Visitor::visitEnumSpecifier), reinterpret_cast(&Visitor::visitEnumerator), reinterpret_cast(&Visitor::visitExceptionSpecification), reinterpret_cast(&Visitor::visitExpressionOrDeclarationStatement), reinterpret_cast(&Visitor::visitExpressionStatement), reinterpret_cast(&Visitor::visitForStatement), reinterpret_cast(&Visitor::visitFunctionCall), reinterpret_cast(&Visitor::visitFunctionDefinition), reinterpret_cast(&Visitor::visitIfStatement), reinterpret_cast(&Visitor::visitIncrDecrExpression), reinterpret_cast(&Visitor::visitInitDeclarator), reinterpret_cast(&Visitor::visitInitializer), reinterpret_cast(&Visitor::visitInitializerClause), reinterpret_cast(&Visitor::visitLabeledStatement), reinterpret_cast(&Visitor::visitLinkageBody), reinterpret_cast(&Visitor::visitLinkageSpecification), reinterpret_cast(&Visitor::visitMemInitializer), reinterpret_cast(&Visitor::visitName), reinterpret_cast(&Visitor::visitNamespace), reinterpret_cast(&Visitor::visitNamespaceAliasDefinition), reinterpret_cast(&Visitor::visitNewDeclarator), reinterpret_cast(&Visitor::visitNewExpression), reinterpret_cast(&Visitor::visitNewInitializer), reinterpret_cast(&Visitor::visitNewTypeId), reinterpret_cast(&Visitor::visitOperator), reinterpret_cast(&Visitor::visitOperatorFunctionId), reinterpret_cast(&Visitor::visitParameterDeclaration), reinterpret_cast(&Visitor::visitParameterDeclarationClause), reinterpret_cast(&Visitor::visitPostfixExpression), reinterpret_cast(&Visitor::visitPrimaryExpression), reinterpret_cast(&Visitor::visitPtrOperator), reinterpret_cast(&Visitor::visitPtrToMember), reinterpret_cast(&Visitor::visitReturnStatement), reinterpret_cast(&Visitor::visitSimpleDeclaration), reinterpret_cast(&Visitor::visitSimpleTypeSpecifier), reinterpret_cast(&Visitor::visitSizeofExpression), reinterpret_cast(&Visitor::visitStringLiteral), reinterpret_cast(&Visitor::visitSubscriptExpression), reinterpret_cast(&Visitor::visitSwitchStatement), reinterpret_cast(&Visitor::visitTemplateArgument), reinterpret_cast(&Visitor::visitTemplateDeclaration), reinterpret_cast(&Visitor::visitTemplateParameter), reinterpret_cast(&Visitor::visitThrowExpression), reinterpret_cast(&Visitor::visitTranslationUnit), reinterpret_cast(&Visitor::visitTryBlockStatement), reinterpret_cast(&Visitor::visitTypeId), reinterpret_cast(&Visitor::visitTypeIdentification), reinterpret_cast(&Visitor::visitTypeParameter), reinterpret_cast(&Visitor::visitTypedef), reinterpret_cast(&Visitor::visitUnaryExpression), reinterpret_cast(&Visitor::visitUnqualifiedName), reinterpret_cast(&Visitor::visitUsing), reinterpret_cast(&Visitor::visitUsingDirective), reinterpret_cast(&Visitor::visitWhileStatement), reinterpret_cast(&Visitor::visitWinDeclSpec), reinterpret_cast(&Visitor::visitQProperty), reinterpret_cast(&Visitor::visitForwardDeclarationSpecifier), reinterpret_cast(&Visitor::visitQEnums) }; Visitor::Visitor() { } Visitor::~Visitor() { } void Visitor::visit(AST *node) { if (node) (this->*_S_table[node->kind])(node); } // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/parser/visitor.h000066400000000000000000000151401170724227300232160ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef VISITOR_H #define VISITOR_H #include "ast.h" class Visitor { public: Visitor(); virtual ~Visitor(); virtual void visit(AST *node); protected: virtual void visitAccessSpecifier(AccessSpecifierAST *) {} virtual void visitAsmDefinition(AsmDefinitionAST *) {} virtual void visitBaseClause(BaseClauseAST *) {} virtual void visitBaseSpecifier(BaseSpecifierAST *) {} virtual void visitBinaryExpression(BinaryExpressionAST *) {} virtual void visitCastExpression(CastExpressionAST *) {} virtual void visitClassMemberAccess(ClassMemberAccessAST *) {} virtual void visitClassSpecifier(ClassSpecifierAST *) {} virtual void visitCompoundStatement(CompoundStatementAST *) {} virtual void visitCondition(ConditionAST *) {} virtual void visitConditionalExpression(ConditionalExpressionAST *) {} virtual void visitCppCastExpression(CppCastExpressionAST *) {} virtual void visitCtorInitializer(CtorInitializerAST *) {} virtual void visitDeclarationStatement(DeclarationStatementAST *) {} virtual void visitDeclarator(DeclaratorAST *) {} virtual void visitDeleteExpression(DeleteExpressionAST *) {} virtual void visitDoStatement(DoStatementAST *) {} virtual void visitElaboratedTypeSpecifier(ElaboratedTypeSpecifierAST *) {} virtual void visitEnumSpecifier(EnumSpecifierAST *) {} virtual void visitEnumerator(EnumeratorAST *) {} virtual void visitExceptionSpecification(ExceptionSpecificationAST *) {} virtual void visitExpressionOrDeclarationStatement(ExpressionOrDeclarationStatementAST *) {} virtual void visitExpressionStatement(ExpressionStatementAST *) {} virtual void visitForStatement(ForStatementAST *) {} virtual void visitFunctionCall(FunctionCallAST *) {} virtual void visitFunctionDefinition(FunctionDefinitionAST *) {} virtual void visitIfStatement(IfStatementAST *) {} virtual void visitIncrDecrExpression(IncrDecrExpressionAST *) {} virtual void visitInitDeclarator(InitDeclaratorAST *) {} virtual void visitInitializer(InitializerAST *) {} virtual void visitInitializerClause(InitializerClauseAST *) {} virtual void visitLabeledStatement(LabeledStatementAST *) {} virtual void visitLinkageBody(LinkageBodyAST *) {} virtual void visitLinkageSpecification(LinkageSpecificationAST *) {} virtual void visitMemInitializer(MemInitializerAST *) {} virtual void visitName(NameAST *) {} virtual void visitNamespace(NamespaceAST *) {} virtual void visitNamespaceAliasDefinition(NamespaceAliasDefinitionAST *) {} virtual void visitNewDeclarator(NewDeclaratorAST *) {} virtual void visitNewExpression(NewExpressionAST *) {} virtual void visitNewInitializer(NewInitializerAST *) {} virtual void visitNewTypeId(NewTypeIdAST *) {} virtual void visitOperator(OperatorAST *) {} virtual void visitOperatorFunctionId(OperatorFunctionIdAST *) {} virtual void visitParameterDeclaration(ParameterDeclarationAST *) {} virtual void visitParameterDeclarationClause(ParameterDeclarationClauseAST *) {} virtual void visitPostfixExpression(PostfixExpressionAST *) {} virtual void visitPrimaryExpression(PrimaryExpressionAST *) {} virtual void visitPtrOperator(PtrOperatorAST *) {} virtual void visitPtrToMember(PtrToMemberAST *) {} virtual void visitReturnStatement(ReturnStatementAST *) {} virtual void visitSimpleDeclaration(SimpleDeclarationAST *) {} virtual void visitSimpleTypeSpecifier(SimpleTypeSpecifierAST *) {} virtual void visitSizeofExpression(SizeofExpressionAST *) {} virtual void visitStringLiteral(StringLiteralAST *) {} virtual void visitSubscriptExpression(SubscriptExpressionAST *) {} virtual void visitSwitchStatement(SwitchStatementAST *) {} virtual void visitTemplateArgument(TemplateArgumentAST *) {} virtual void visitTemplateDeclaration(TemplateDeclarationAST *) {} virtual void visitTemplateParameter(TemplateParameterAST *) {} virtual void visitThrowExpression(ThrowExpressionAST *) {} virtual void visitTranslationUnit(TranslationUnitAST *) {} virtual void visitTryBlockStatement(TryBlockStatementAST *) {} virtual void visitTypeId(TypeIdAST *) {} virtual void visitTypeIdentification(TypeIdentificationAST *) {} virtual void visitTypeParameter(TypeParameterAST *) {} virtual void visitTypedef(TypedefAST *) {} virtual void visitUnaryExpression(UnaryExpressionAST *) {} virtual void visitUnqualifiedName(UnqualifiedNameAST *) {} virtual void visitUsing(UsingAST *) {} virtual void visitUsingDirective(UsingDirectiveAST *) {} virtual void visitWhileStatement(WhileStatementAST *) {} virtual void visitWinDeclSpec(WinDeclSpecAST *) {} virtual void visitQProperty(QPropertyAST *) {} virtual void visitForwardDeclarationSpecifier(ForwardDeclarationSpecifierAST *) {} virtual void visitQEnums(QEnumsAST *) {} private: typedef void (Visitor::*visitor_fun_ptr)(AST *); static visitor_fun_ptr _S_table[]; }; template void visitNodes(Visitor *v, const ListNode<_Tp> *nodes) { if (!nodes) return; const ListNode<_Tp> *it = nodes->toFront(), *end = it; do { v->visit(it->element); it = it->next; } while (it != end); } #endif // VISITOR_H // kate: space-indent on; indent-width 2; replace-tabs on; qtscriptgenerator-src-0.2.0/generator/prigenerator.cpp000066400000000000000000000054031170724227300232600ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "prigenerator.h" #include "reporthandler.h" #include "fileout.h" void PriGenerator::addHeader(const QString &folder, const QString &header) { priHash[folder].headers << header; } void PriGenerator::addSource(const QString &folder, const QString &source) { priHash[folder].sources << source; } void PriGenerator::generate() { QHashIterator pri(priHash); while (pri.hasNext()) { pri.next(); QStringList list = pri.value().headers; if (list.isEmpty()) continue; QString folder = pri.key(); FileOut file(m_out_dir + "/generated_cpp/" + folder + "/" + folder + ".pri"); file.stream << "HEADERS += \\\n"; qSort(list.begin(), list.end()); foreach (const QString &entry, list) { file.stream << " $$PWD/" << entry << " \\\n"; } file.stream << "\n"; file.stream << "SOURCES += \\\n"; list = pri.value().sources; qSort(list.begin(), list.end()); foreach (const QString &entry, list) { file.stream << " $$PWD/" << entry << " \\\n"; } file.stream << " $$PWD/" << folder << "_init.cpp\n"; if (file.done()) ++m_num_generated_written; ++m_num_generated; } } qtscriptgenerator-src-0.2.0/generator/prigenerator.h000066400000000000000000000037001170724227300227230ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef PRIGENERATOR_H #define PRIGENERATOR_H #include "generator.h" #include #include struct Pri { QStringList headers; QStringList sources; }; class PriGenerator : public Generator { Q_OBJECT public: virtual void generate(); void addHeader(const QString &folder, const QString &header); void addSource(const QString &folder, const QString &source); private: QHash priHash; }; #endif // PRIGENERATOR_H qtscriptgenerator-src-0.2.0/generator/qtscript_masterinclude.h000066400000000000000000001206741170724227300250240ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #define QT_NO_STL #include #include #include #include #include #include #include #ifndef QT_NO_XMLPATTERNS # include #endif #ifndef QT_NO_WEBKIT # include #endif #ifndef QT_NO_PHONON # include #endif #include "../qtbindings/qtscript_core/qtscriptconcurrent.h" #ifndef QT_NO_OPENGL #define GL_ACCUM 0x0100 #define GL_LOAD 0x0101 #define GL_RETURN 0x0102 #define GL_MULT 0x0103 #define GL_ADD 0x0104 /* AlphaFunction */ #define GL_NEVER 0x0200 #define GL_LESS 0x0201 #define GL_EQUAL 0x0202 #define GL_LEQUAL 0x0203 #define GL_GREATER 0x0204 #define GL_NOTEQUAL 0x0205 #define GL_GEQUAL 0x0206 #define GL_ALWAYS 0x0207 /* AttribMask */ #define GL_CURRENT_BIT 0x00000001 #define GL_POINT_BIT 0x00000002 #define GL_LINE_BIT 0x00000004 #define GL_POLYGON_BIT 0x00000008 #define GL_POLYGON_STIPPLE_BIT 0x00000010 #define GL_PIXEL_MODE_BIT 0x00000020 #define GL_LIGHTING_BIT 0x00000040 #define GL_FOG_BIT 0x00000080 #define GL_DEPTH_BUFFER_BIT 0x00000100 #define GL_ACCUM_BUFFER_BIT 0x00000200 #define GL_STENCIL_BUFFER_BIT 0x00000400 #define GL_VIEWPORT_BIT 0x00000800 #define GL_TRANSFORM_BIT 0x00001000 #define GL_ENABLE_BIT 0x00002000 #define GL_COLOR_BUFFER_BIT 0x00004000 #define GL_HINT_BIT 0x00008000 #define GL_EVAL_BIT 0x00010000 #define GL_LIST_BIT 0x00020000 #define GL_TEXTURE_BIT 0x00040000 #define GL_SCISSOR_BIT 0x00080000 #define GL_ALL_ATTRIB_BITS 0x000fffff /* BeginMode */ #define GL_POINTS 0x0000 #define GL_LINES 0x0001 #define GL_LINE_LOOP 0x0002 #define GL_LINE_STRIP 0x0003 #define GL_TRIANGLES 0x0004 #define GL_TRIANGLE_STRIP 0x0005 #define GL_TRIANGLE_FAN 0x0006 #define GL_QUADS 0x0007 #define GL_QUAD_STRIP 0x0008 #define GL_POLYGON 0x0009 /* BlendingFactorDest */ #define GL_ZERO 0 #define GL_ONE 1 #define GL_SRC_COLOR 0x0300 #define GL_ONE_MINUS_SRC_COLOR 0x0301 #define GL_SRC_ALPHA 0x0302 #define GL_ONE_MINUS_SRC_ALPHA 0x0303 #define GL_DST_ALPHA 0x0304 #define GL_ONE_MINUS_DST_ALPHA 0x0305 /* BlendingFactorSrc */ /* GL_ZERO */ /* GL_ONE */ #define GL_DST_COLOR 0x0306 #define GL_ONE_MINUS_DST_COLOR 0x0307 #define GL_SRC_ALPHA_SATURATE 0x0308 /* GL_SRC_ALPHA */ /* GL_ONE_MINUS_SRC_ALPHA */ /* GL_DST_ALPHA */ /* GL_ONE_MINUS_DST_ALPHA */ /* Boolean */ #define GL_TRUE 1 #define GL_FALSE 0 /* ClearBufferMask */ /* GL_COLOR_BUFFER_BIT */ /* GL_ACCUM_BUFFER_BIT */ /* GL_STENCIL_BUFFER_BIT */ /* GL_DEPTH_BUFFER_BIT */ /* ClientArrayType */ /* GL_VERTEX_ARRAY */ /* GL_NORMAL_ARRAY */ /* GL_COLOR_ARRAY */ /* GL_INDEX_ARRAY */ /* GL_TEXTURE_COORD_ARRAY */ /* GL_EDGE_FLAG_ARRAY */ /* ClipPlaneName */ #define GL_CLIP_PLANE0 0x3000 #define GL_CLIP_PLANE1 0x3001 #define GL_CLIP_PLANE2 0x3002 #define GL_CLIP_PLANE3 0x3003 #define GL_CLIP_PLANE4 0x3004 #define GL_CLIP_PLANE5 0x3005 /* ColorMaterialFace */ /* GL_FRONT */ /* GL_BACK */ /* GL_FRONT_AND_BACK */ /* ColorMaterialParameter */ /* GL_AMBIENT */ /* GL_DIFFUSE */ /* GL_SPECULAR */ /* GL_EMISSION */ /* GL_AMBIENT_AND_DIFFUSE */ /* ColorPointerType */ /* GL_BYTE */ /* GL_UNSIGNED_BYTE */ /* GL_SHORT */ /* GL_UNSIGNED_SHORT */ /* GL_INT */ /* GL_UNSIGNED_INT */ /* GL_FLOAT */ /* GL_DOUBLE */ /* CullFaceMode */ /* GL_FRONT */ /* GL_BACK */ /* GL_FRONT_AND_BACK */ /* DataType */ #define GL_BYTE 0x1400 #define GL_UNSIGNED_BYTE 0x1401 #define GL_SHORT 0x1402 #define GL_UNSIGNED_SHORT 0x1403 #define GL_INT 0x1404 #define GL_UNSIGNED_INT 0x1405 #define GL_FLOAT 0x1406 #define GL_2_BYTES 0x1407 #define GL_3_BYTES 0x1408 #define GL_4_BYTES 0x1409 #define GL_DOUBLE 0x140A /* DepthFunction */ /* GL_NEVER */ /* GL_LESS */ /* GL_EQUAL */ /* GL_LEQUAL */ /* GL_GREATER */ /* GL_NOTEQUAL */ /* GL_GEQUAL */ /* GL_ALWAYS */ /* DrawBufferMode */ #define GL_NONE 0 #define GL_FRONT_LEFT 0x0400 #define GL_FRONT_RIGHT 0x0401 #define GL_BACK_LEFT 0x0402 #define GL_BACK_RIGHT 0x0403 #define GL_FRONT 0x0404 #define GL_BACK 0x0405 #define GL_LEFT 0x0406 #define GL_RIGHT 0x0407 #define GL_FRONT_AND_BACK 0x0408 #define GL_AUX0 0x0409 #define GL_AUX1 0x040A #define GL_AUX2 0x040B #define GL_AUX3 0x040C /* Enable */ /* GL_FOG */ /* GL_LIGHTING */ /* GL_TEXTURE_1D */ /* GL_TEXTURE_2D */ /* GL_LINE_STIPPLE */ /* GL_POLYGON_STIPPLE */ /* GL_CULL_FACE */ /* GL_ALPHA_TEST */ /* GL_BLEND */ /* GL_INDEX_LOGIC_OP */ /* GL_COLOR_LOGIC_OP */ /* GL_DITHER */ /* GL_STENCIL_TEST */ /* GL_DEPTH_TEST */ /* GL_CLIP_PLANE0 */ /* GL_CLIP_PLANE1 */ /* GL_CLIP_PLANE2 */ /* GL_CLIP_PLANE3 */ /* GL_CLIP_PLANE4 */ /* GL_CLIP_PLANE5 */ /* GL_LIGHT0 */ /* GL_LIGHT1 */ /* GL_LIGHT2 */ /* GL_LIGHT3 */ /* GL_LIGHT4 */ /* GL_LIGHT5 */ /* GL_LIGHT6 */ /* GL_LIGHT7 */ /* GL_TEXTURE_GEN_S */ /* GL_TEXTURE_GEN_T */ /* GL_TEXTURE_GEN_R */ /* GL_TEXTURE_GEN_Q */ /* GL_MAP1_VERTEX_3 */ /* GL_MAP1_VERTEX_4 */ /* GL_MAP1_COLOR_4 */ /* GL_MAP1_INDEX */ /* GL_MAP1_NORMAL */ /* GL_MAP1_TEXTURE_COORD_1 */ /* GL_MAP1_TEXTURE_COORD_2 */ /* GL_MAP1_TEXTURE_COORD_3 */ /* GL_MAP1_TEXTURE_COORD_4 */ /* GL_MAP2_VERTEX_3 */ /* GL_MAP2_VERTEX_4 */ /* GL_MAP2_COLOR_4 */ /* GL_MAP2_INDEX */ /* GL_MAP2_NORMAL */ /* GL_MAP2_TEXTURE_COORD_1 */ /* GL_MAP2_TEXTURE_COORD_2 */ /* GL_MAP2_TEXTURE_COORD_3 */ /* GL_MAP2_TEXTURE_COORD_4 */ /* GL_POINT_SMOOTH */ /* GL_LINE_SMOOTH */ /* GL_POLYGON_SMOOTH */ /* GL_SCISSOR_TEST */ /* GL_COLOR_MATERIAL */ /* GL_NORMALIZE */ /* GL_AUTO_NORMAL */ /* GL_VERTEX_ARRAY */ /* GL_NORMAL_ARRAY */ /* GL_COLOR_ARRAY */ /* GL_INDEX_ARRAY */ /* GL_TEXTURE_COORD_ARRAY */ /* GL_EDGE_FLAG_ARRAY */ /* GL_POLYGON_OFFSET_POINT */ /* GL_POLYGON_OFFSET_LINE */ /* GL_POLYGON_OFFSET_FILL */ /* ErrorCode */ #define GL_NO_ERROR 0 #define GL_INVALID_ENUM 0x0500 #define GL_INVALID_VALUE 0x0501 #define GL_INVALID_OPERATION 0x0502 #define GL_STACK_OVERFLOW 0x0503 #define GL_STACK_UNDERFLOW 0x0504 #define GL_OUT_OF_MEMORY 0x0505 /* FeedBackMode */ #define GL_2D 0x0600 #define GL_3D 0x0601 #define GL_3D_COLOR 0x0602 #define GL_3D_COLOR_TEXTURE 0x0603 #define GL_4D_COLOR_TEXTURE 0x0604 /* FeedBackToken */ #define GL_PASS_THROUGH_TOKEN 0x0700 #define GL_POINT_TOKEN 0x0701 #define GL_LINE_TOKEN 0x0702 #define GL_POLYGON_TOKEN 0x0703 #define GL_BITMAP_TOKEN 0x0704 #define GL_DRAW_PIXEL_TOKEN 0x0705 #define GL_COPY_PIXEL_TOKEN 0x0706 #define GL_LINE_RESET_TOKEN 0x0707 /* FogMode */ /* GL_LINEAR */ #define GL_EXP 0x0800 #define GL_EXP2 0x0801 /* FogParameter */ /* GL_FOG_COLOR */ /* GL_FOG_DENSITY */ /* GL_FOG_END */ /* GL_FOG_INDEX */ /* GL_FOG_MODE */ /* GL_FOG_START */ /* FrontFaceDirection */ #define GL_CW 0x0900 #define GL_CCW 0x0901 /* GetMapTarget */ #define GL_COEFF 0x0A00 #define GL_ORDER 0x0A01 #define GL_DOMAIN 0x0A02 /* GetPixelMap */ /* GL_PIXEL_MAP_I_TO_I */ /* GL_PIXEL_MAP_S_TO_S */ /* GL_PIXEL_MAP_I_TO_R */ /* GL_PIXEL_MAP_I_TO_G */ /* GL_PIXEL_MAP_I_TO_B */ /* GL_PIXEL_MAP_I_TO_A */ /* GL_PIXEL_MAP_R_TO_R */ /* GL_PIXEL_MAP_G_TO_G */ /* GL_PIXEL_MAP_B_TO_B */ /* GL_PIXEL_MAP_A_TO_A */ /* GetPointerTarget */ /* GL_VERTEX_ARRAY_POINTER */ /* GL_NORMAL_ARRAY_POINTER */ /* GL_COLOR_ARRAY_POINTER */ /* GL_INDEX_ARRAY_POINTER */ /* GL_TEXTURE_COORD_ARRAY_POINTER */ /* GL_EDGE_FLAG_ARRAY_POINTER */ /* GetTarget */ #define GL_CURRENT_COLOR 0x0B00 #define GL_CURRENT_INDEX 0x0B01 #define GL_CURRENT_NORMAL 0x0B02 #define GL_CURRENT_TEXTURE_COORDS 0x0B03 #define GL_CURRENT_RASTER_COLOR 0x0B04 #define GL_CURRENT_RASTER_INDEX 0x0B05 #define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 #define GL_CURRENT_RASTER_POSITION 0x0B07 #define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 #define GL_CURRENT_RASTER_DISTANCE 0x0B09 #define GL_POINT_SMOOTH 0x0B10 #define GL_POINT_SIZE 0x0B11 #define GL_POINT_SIZE_RANGE 0x0B12 #define GL_POINT_SIZE_GRANULARITY 0x0B13 #define GL_LINE_SMOOTH 0x0B20 #define GL_LINE_WIDTH 0x0B21 #define GL_LINE_WIDTH_RANGE 0x0B22 #define GL_LINE_WIDTH_GRANULARITY 0x0B23 #define GL_LINE_STIPPLE 0x0B24 #define GL_LINE_STIPPLE_PATTERN 0x0B25 #define GL_LINE_STIPPLE_REPEAT 0x0B26 #define GL_LIST_MODE 0x0B30 #define GL_MAX_LIST_NESTING 0x0B31 #define GL_LIST_BASE 0x0B32 #define GL_LIST_INDEX 0x0B33 #define GL_POLYGON_MODE 0x0B40 #define GL_POLYGON_SMOOTH 0x0B41 #define GL_POLYGON_STIPPLE 0x0B42 #define GL_EDGE_FLAG 0x0B43 #define GL_CULL_FACE 0x0B44 #define GL_CULL_FACE_MODE 0x0B45 #define GL_FRONT_FACE 0x0B46 #define GL_LIGHTING 0x0B50 #define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 #define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 #define GL_LIGHT_MODEL_AMBIENT 0x0B53 #define GL_SHADE_MODEL 0x0B54 #define GL_COLOR_MATERIAL_FACE 0x0B55 #define GL_COLOR_MATERIAL_PARAMETER 0x0B56 #define GL_COLOR_MATERIAL 0x0B57 #define GL_FOG 0x0B60 #define GL_FOG_INDEX 0x0B61 #define GL_FOG_DENSITY 0x0B62 #define GL_FOG_START 0x0B63 #define GL_FOG_END 0x0B64 #define GL_FOG_MODE 0x0B65 #define GL_FOG_COLOR 0x0B66 #define GL_DEPTH_RANGE 0x0B70 #define GL_DEPTH_TEST 0x0B71 #define GL_DEPTH_WRITEMASK 0x0B72 #define GL_DEPTH_CLEAR_VALUE 0x0B73 #define GL_DEPTH_FUNC 0x0B74 #define GL_ACCUM_CLEAR_VALUE 0x0B80 #define GL_STENCIL_TEST 0x0B90 #define GL_STENCIL_CLEAR_VALUE 0x0B91 #define GL_STENCIL_FUNC 0x0B92 #define GL_STENCIL_VALUE_MASK 0x0B93 #define GL_STENCIL_FAIL 0x0B94 #define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 #define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 #define GL_STENCIL_REF 0x0B97 #define GL_STENCIL_WRITEMASK 0x0B98 #define GL_MATRIX_MODE 0x0BA0 #define GL_NORMALIZE 0x0BA1 #define GL_VIEWPORT 0x0BA2 #define GL_MODELVIEW_STACK_DEPTH 0x0BA3 #define GL_PROJECTION_STACK_DEPTH 0x0BA4 #define GL_TEXTURE_STACK_DEPTH 0x0BA5 #define GL_MODELVIEW_MATRIX 0x0BA6 #define GL_PROJECTION_MATRIX 0x0BA7 #define GL_TEXTURE_MATRIX 0x0BA8 #define GL_ATTRIB_STACK_DEPTH 0x0BB0 #define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 #define GL_ALPHA_TEST 0x0BC0 #define GL_ALPHA_TEST_FUNC 0x0BC1 #define GL_ALPHA_TEST_REF 0x0BC2 #define GL_DITHER 0x0BD0 #define GL_BLEND_DST 0x0BE0 #define GL_BLEND_SRC 0x0BE1 #define GL_BLEND 0x0BE2 #define GL_LOGIC_OP_MODE 0x0BF0 #define GL_INDEX_LOGIC_OP 0x0BF1 #define GL_COLOR_LOGIC_OP 0x0BF2 #define GL_AUX_BUFFERS 0x0C00 #define GL_DRAW_BUFFER 0x0C01 #define GL_READ_BUFFER 0x0C02 #define GL_SCISSOR_BOX 0x0C10 #define GL_SCISSOR_TEST 0x0C11 #define GL_INDEX_CLEAR_VALUE 0x0C20 #define GL_INDEX_WRITEMASK 0x0C21 #define GL_COLOR_CLEAR_VALUE 0x0C22 #define GL_COLOR_WRITEMASK 0x0C23 #define GL_INDEX_MODE 0x0C30 #define GL_RGBA_MODE 0x0C31 #define GL_DOUBLEBUFFER 0x0C32 #define GL_STEREO 0x0C33 #define GL_RENDER_MODE 0x0C40 #define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 #define GL_POINT_SMOOTH_HINT 0x0C51 #define GL_LINE_SMOOTH_HINT 0x0C52 #define GL_POLYGON_SMOOTH_HINT 0x0C53 #define GL_FOG_HINT 0x0C54 #define GL_TEXTURE_GEN_S 0x0C60 #define GL_TEXTURE_GEN_T 0x0C61 #define GL_TEXTURE_GEN_R 0x0C62 #define GL_TEXTURE_GEN_Q 0x0C63 #define GL_PIXEL_MAP_I_TO_I 0x0C70 #define GL_PIXEL_MAP_S_TO_S 0x0C71 #define GL_PIXEL_MAP_I_TO_R 0x0C72 #define GL_PIXEL_MAP_I_TO_G 0x0C73 #define GL_PIXEL_MAP_I_TO_B 0x0C74 #define GL_PIXEL_MAP_I_TO_A 0x0C75 #define GL_PIXEL_MAP_R_TO_R 0x0C76 #define GL_PIXEL_MAP_G_TO_G 0x0C77 #define GL_PIXEL_MAP_B_TO_B 0x0C78 #define GL_PIXEL_MAP_A_TO_A 0x0C79 #define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 #define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 #define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 #define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 #define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 #define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 #define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 #define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 #define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 #define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 #define GL_UNPACK_SWAP_BYTES 0x0CF0 #define GL_UNPACK_LSB_FIRST 0x0CF1 #define GL_UNPACK_ROW_LENGTH 0x0CF2 #define GL_UNPACK_SKIP_ROWS 0x0CF3 #define GL_UNPACK_SKIP_PIXELS 0x0CF4 #define GL_UNPACK_ALIGNMENT 0x0CF5 #define GL_PACK_SWAP_BYTES 0x0D00 #define GL_PACK_LSB_FIRST 0x0D01 #define GL_PACK_ROW_LENGTH 0x0D02 #define GL_PACK_SKIP_ROWS 0x0D03 #define GL_PACK_SKIP_PIXELS 0x0D04 #define GL_PACK_ALIGNMENT 0x0D05 #define GL_MAP_COLOR 0x0D10 #define GL_MAP_STENCIL 0x0D11 #define GL_INDEX_SHIFT 0x0D12 #define GL_INDEX_OFFSET 0x0D13 #define GL_RED_SCALE 0x0D14 #define GL_RED_BIAS 0x0D15 #define GL_ZOOM_X 0x0D16 #define GL_ZOOM_Y 0x0D17 #define GL_GREEN_SCALE 0x0D18 #define GL_GREEN_BIAS 0x0D19 #define GL_BLUE_SCALE 0x0D1A #define GL_BLUE_BIAS 0x0D1B #define GL_ALPHA_SCALE 0x0D1C #define GL_ALPHA_BIAS 0x0D1D #define GL_DEPTH_SCALE 0x0D1E #define GL_DEPTH_BIAS 0x0D1F #define GL_MAX_EVAL_ORDER 0x0D30 #define GL_MAX_LIGHTS 0x0D31 #define GL_MAX_CLIP_PLANES 0x0D32 #define GL_MAX_TEXTURE_SIZE 0x0D33 #define GL_MAX_PIXEL_MAP_TABLE 0x0D34 #define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 #define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 #define GL_MAX_NAME_STACK_DEPTH 0x0D37 #define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 #define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 #define GL_MAX_VIEWPORT_DIMS 0x0D3A #define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B #define GL_SUBPIXEL_BITS 0x0D50 #define GL_INDEX_BITS 0x0D51 #define GL_RED_BITS 0x0D52 #define GL_GREEN_BITS 0x0D53 #define GL_BLUE_BITS 0x0D54 #define GL_ALPHA_BITS 0x0D55 #define GL_DEPTH_BITS 0x0D56 #define GL_STENCIL_BITS 0x0D57 #define GL_ACCUM_RED_BITS 0x0D58 #define GL_ACCUM_GREEN_BITS 0x0D59 #define GL_ACCUM_BLUE_BITS 0x0D5A #define GL_ACCUM_ALPHA_BITS 0x0D5B #define GL_NAME_STACK_DEPTH 0x0D70 #define GL_AUTO_NORMAL 0x0D80 #define GL_MAP1_COLOR_4 0x0D90 #define GL_MAP1_INDEX 0x0D91 #define GL_MAP1_NORMAL 0x0D92 #define GL_MAP1_TEXTURE_COORD_1 0x0D93 #define GL_MAP1_TEXTURE_COORD_2 0x0D94 #define GL_MAP1_TEXTURE_COORD_3 0x0D95 #define GL_MAP1_TEXTURE_COORD_4 0x0D96 #define GL_MAP1_VERTEX_3 0x0D97 #define GL_MAP1_VERTEX_4 0x0D98 #define GL_MAP2_COLOR_4 0x0DB0 #define GL_MAP2_INDEX 0x0DB1 #define GL_MAP2_NORMAL 0x0DB2 #define GL_MAP2_TEXTURE_COORD_1 0x0DB3 #define GL_MAP2_TEXTURE_COORD_2 0x0DB4 #define GL_MAP2_TEXTURE_COORD_3 0x0DB5 #define GL_MAP2_TEXTURE_COORD_4 0x0DB6 #define GL_MAP2_VERTEX_3 0x0DB7 #define GL_MAP2_VERTEX_4 0x0DB8 #define GL_MAP1_GRID_DOMAIN 0x0DD0 #define GL_MAP1_GRID_SEGMENTS 0x0DD1 #define GL_MAP2_GRID_DOMAIN 0x0DD2 #define GL_MAP2_GRID_SEGMENTS 0x0DD3 #define GL_TEXTURE_1D 0x0DE0 #define GL_TEXTURE_2D 0x0DE1 #define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 #define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 #define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 #define GL_SELECTION_BUFFER_POINTER 0x0DF3 #define GL_SELECTION_BUFFER_SIZE 0x0DF4 /* GL_TEXTURE_BINDING_1D */ /* GL_TEXTURE_BINDING_2D */ /* GL_VERTEX_ARRAY */ /* GL_NORMAL_ARRAY */ /* GL_COLOR_ARRAY */ /* GL_INDEX_ARRAY */ /* GL_TEXTURE_COORD_ARRAY */ /* GL_EDGE_FLAG_ARRAY */ /* GL_VERTEX_ARRAY_SIZE */ /* GL_VERTEX_ARRAY_TYPE */ /* GL_VERTEX_ARRAY_STRIDE */ /* GL_NORMAL_ARRAY_TYPE */ /* GL_NORMAL_ARRAY_STRIDE */ /* GL_COLOR_ARRAY_SIZE */ /* GL_COLOR_ARRAY_TYPE */ /* GL_COLOR_ARRAY_STRIDE */ /* GL_INDEX_ARRAY_TYPE */ /* GL_INDEX_ARRAY_STRIDE */ /* GL_TEXTURE_COORD_ARRAY_SIZE */ /* GL_TEXTURE_COORD_ARRAY_TYPE */ /* GL_TEXTURE_COORD_ARRAY_STRIDE */ /* GL_EDGE_FLAG_ARRAY_STRIDE */ /* GL_POLYGON_OFFSET_FACTOR */ /* GL_POLYGON_OFFSET_UNITS */ /* GetTextureParameter */ /* GL_TEXTURE_MAG_FILTER */ /* GL_TEXTURE_MIN_FILTER */ /* GL_TEXTURE_WRAP_S */ /* GL_TEXTURE_WRAP_T */ #define GL_TEXTURE_WIDTH 0x1000 #define GL_TEXTURE_HEIGHT 0x1001 #define GL_TEXTURE_INTERNAL_FORMAT 0x1003 #define GL_TEXTURE_BORDER_COLOR 0x1004 #define GL_TEXTURE_BORDER 0x1005 /* GL_TEXTURE_RED_SIZE */ /* GL_TEXTURE_GREEN_SIZE */ /* GL_TEXTURE_BLUE_SIZE */ /* GL_TEXTURE_ALPHA_SIZE */ /* GL_TEXTURE_LUMINANCE_SIZE */ /* GL_TEXTURE_INTENSITY_SIZE */ /* GL_TEXTURE_PRIORITY */ /* GL_TEXTURE_RESIDENT */ /* HintMode */ #define GL_DONT_CARE 0x1100 #define GL_FASTEST 0x1101 #define GL_NICEST 0x1102 /* HintTarget */ /* GL_PERSPECTIVE_CORRECTION_HINT */ /* GL_POINT_SMOOTH_HINT */ /* GL_LINE_SMOOTH_HINT */ /* GL_POLYGON_SMOOTH_HINT */ /* GL_FOG_HINT */ /* GL_PHONG_HINT */ /* IndexPointerType */ /* GL_SHORT */ /* GL_INT */ /* GL_FLOAT */ /* GL_DOUBLE */ /* LightModelParameter */ /* GL_LIGHT_MODEL_AMBIENT */ /* GL_LIGHT_MODEL_LOCAL_VIEWER */ /* GL_LIGHT_MODEL_TWO_SIDE */ /* LightName */ #define GL_LIGHT0 0x4000 #define GL_LIGHT1 0x4001 #define GL_LIGHT2 0x4002 #define GL_LIGHT3 0x4003 #define GL_LIGHT4 0x4004 #define GL_LIGHT5 0x4005 #define GL_LIGHT6 0x4006 #define GL_LIGHT7 0x4007 /* LightParameter */ #define GL_AMBIENT 0x1200 #define GL_DIFFUSE 0x1201 #define GL_SPECULAR 0x1202 #define GL_POSITION 0x1203 #define GL_SPOT_DIRECTION 0x1204 #define GL_SPOT_EXPONENT 0x1205 #define GL_SPOT_CUTOFF 0x1206 #define GL_CONSTANT_ATTENUATION 0x1207 #define GL_LINEAR_ATTENUATION 0x1208 #define GL_QUADRATIC_ATTENUATION 0x1209 /* InterleavedArrays */ /* GL_V2F */ /* GL_V3F */ /* GL_C4UB_V2F */ /* GL_C4UB_V3F */ /* GL_C3F_V3F */ /* GL_N3F_V3F */ /* GL_C4F_N3F_V3F */ /* GL_T2F_V3F */ /* GL_T4F_V4F */ /* GL_T2F_C4UB_V3F */ /* GL_T2F_C3F_V3F */ /* GL_T2F_N3F_V3F */ /* GL_T2F_C4F_N3F_V3F */ /* GL_T4F_C4F_N3F_V4F */ /* ListMode */ #define GL_COMPILE 0x1300 #define GL_COMPILE_AND_EXECUTE 0x1301 /* ListNameType */ /* GL_BYTE */ /* GL_UNSIGNED_BYTE */ /* GL_SHORT */ /* GL_UNSIGNED_SHORT */ /* GL_INT */ /* GL_UNSIGNED_INT */ /* GL_FLOAT */ /* GL_2_BYTES */ /* GL_3_BYTES */ /* GL_4_BYTES */ /* LogicOp */ #define GL_CLEAR 0x1500 #define GL_AND 0x1501 #define GL_AND_REVERSE 0x1502 #define GL_COPY 0x1503 #define GL_AND_INVERTED 0x1504 #define GL_NOOP 0x1505 #define GL_XOR 0x1506 #define GL_OR 0x1507 #define GL_NOR 0x1508 #define GL_EQUIV 0x1509 #define GL_INVERT 0x150A #define GL_OR_REVERSE 0x150B #define GL_COPY_INVERTED 0x150C #define GL_OR_INVERTED 0x150D #define GL_NAND 0x150E #define GL_SET 0x150F /* MapTarget */ /* GL_MAP1_COLOR_4 */ /* GL_MAP1_INDEX */ /* GL_MAP1_NORMAL */ /* GL_MAP1_TEXTURE_COORD_1 */ /* GL_MAP1_TEXTURE_COORD_2 */ /* GL_MAP1_TEXTURE_COORD_3 */ /* GL_MAP1_TEXTURE_COORD_4 */ /* GL_MAP1_VERTEX_3 */ /* GL_MAP1_VERTEX_4 */ /* GL_MAP2_COLOR_4 */ /* GL_MAP2_INDEX */ /* GL_MAP2_NORMAL */ /* GL_MAP2_TEXTURE_COORD_1 */ /* GL_MAP2_TEXTURE_COORD_2 */ /* GL_MAP2_TEXTURE_COORD_3 */ /* GL_MAP2_TEXTURE_COORD_4 */ /* GL_MAP2_VERTEX_3 */ /* GL_MAP2_VERTEX_4 */ /* MaterialFace */ /* GL_FRONT */ /* GL_BACK */ /* GL_FRONT_AND_BACK */ /* MaterialParameter */ #define GL_EMISSION 0x1600 #define GL_SHININESS 0x1601 #define GL_AMBIENT_AND_DIFFUSE 0x1602 #define GL_COLOR_INDEXES 0x1603 /* GL_AMBIENT */ /* GL_DIFFUSE */ /* GL_SPECULAR */ /* MatrixMode */ #define GL_MODELVIEW 0x1700 #define GL_PROJECTION 0x1701 #define GL_TEXTURE 0x1702 /* MeshMode1 */ /* GL_POINT */ /* GL_LINE */ /* MeshMode2 */ /* GL_POINT */ /* GL_LINE */ /* GL_FILL */ /* NormalPointerType */ /* GL_BYTE */ /* GL_SHORT */ /* GL_INT */ /* GL_FLOAT */ /* GL_DOUBLE */ /* PixelCopyType */ #define GL_COLOR 0x1800 #define GL_DEPTH 0x1801 #define GL_STENCIL 0x1802 /* PixelFormat */ #define GL_COLOR_INDEX 0x1900 #define GL_STENCIL_INDEX 0x1901 #define GL_DEPTH_COMPONENT 0x1902 #define GL_RED 0x1903 #define GL_GREEN 0x1904 #define GL_BLUE 0x1905 #define GL_ALPHA 0x1906 #define GL_RGB 0x1907 #define GL_RGBA 0x1908 #define GL_LUMINANCE 0x1909 #define GL_LUMINANCE_ALPHA 0x190A /* PixelMap */ /* GL_PIXEL_MAP_I_TO_I */ /* GL_PIXEL_MAP_S_TO_S */ /* GL_PIXEL_MAP_I_TO_R */ /* GL_PIXEL_MAP_I_TO_G */ /* GL_PIXEL_MAP_I_TO_B */ /* GL_PIXEL_MAP_I_TO_A */ /* GL_PIXEL_MAP_R_TO_R */ /* GL_PIXEL_MAP_G_TO_G */ /* GL_PIXEL_MAP_B_TO_B */ /* GL_PIXEL_MAP_A_TO_A */ /* PixelStore */ /* GL_UNPACK_SWAP_BYTES */ /* GL_UNPACK_LSB_FIRST */ /* GL_UNPACK_ROW_LENGTH */ /* GL_UNPACK_SKIP_ROWS */ /* GL_UNPACK_SKIP_PIXELS */ /* GL_UNPACK_ALIGNMENT */ /* GL_PACK_SWAP_BYTES */ /* GL_PACK_LSB_FIRST */ /* GL_PACK_ROW_LENGTH */ /* GL_PACK_SKIP_ROWS */ /* GL_PACK_SKIP_PIXELS */ /* GL_PACK_ALIGNMENT */ /* PixelTransfer */ /* GL_MAP_COLOR */ /* GL_MAP_STENCIL */ /* GL_INDEX_SHIFT */ /* GL_INDEX_OFFSET */ /* GL_RED_SCALE */ /* GL_RED_BIAS */ /* GL_GREEN_SCALE */ /* GL_GREEN_BIAS */ /* GL_BLUE_SCALE */ /* GL_BLUE_BIAS */ /* GL_ALPHA_SCALE */ /* GL_ALPHA_BIAS */ /* GL_DEPTH_SCALE */ /* GL_DEPTH_BIAS */ /* PixelType */ #define GL_BITMAP 0x1A00 /* GL_BYTE */ /* GL_UNSIGNED_BYTE */ /* GL_SHORT */ /* GL_UNSIGNED_SHORT */ /* GL_INT */ /* GL_UNSIGNED_INT */ /* GL_FLOAT */ /* PolygonMode */ #define GL_POINT 0x1B00 #define GL_LINE 0x1B01 #define GL_FILL 0x1B02 /* ReadBufferMode */ /* GL_FRONT_LEFT */ /* GL_FRONT_RIGHT */ /* GL_BACK_LEFT */ /* GL_BACK_RIGHT */ /* GL_FRONT */ /* GL_BACK */ /* GL_LEFT */ /* GL_RIGHT */ /* GL_AUX0 */ /* GL_AUX1 */ /* GL_AUX2 */ /* GL_AUX3 */ /* RenderingMode */ #define GL_RENDER 0x1C00 #define GL_FEEDBACK 0x1C01 #define GL_SELECT 0x1C02 /* ShadingModel */ #define GL_FLAT 0x1D00 #define GL_SMOOTH 0x1D01 /* StencilFunction */ /* GL_NEVER */ /* GL_LESS */ /* GL_EQUAL */ /* GL_LEQUAL */ /* GL_GREATER */ /* GL_NOTEQUAL */ /* GL_GEQUAL */ /* GL_ALWAYS */ /* StencilOp */ /* GL_ZERO */ #define GL_KEEP 0x1E00 #define GL_REPLACE 0x1E01 #define GL_INCR 0x1E02 #define GL_DECR 0x1E03 /* GL_INVERT */ /* StringName */ #define GL_VENDOR 0x1F00 #define GL_RENDERER 0x1F01 #define GL_VERSION 0x1F02 #define GL_EXTENSIONS 0x1F03 /* TextureCoordName */ #define GL_S 0x2000 #define GL_T 0x2001 #define GL_R 0x2002 #define GL_Q 0x2003 /* TexCoordPointerType */ /* GL_SHORT */ /* GL_INT */ /* GL_FLOAT */ /* GL_DOUBLE */ /* TextureEnvMode */ #define GL_MODULATE 0x2100 #define GL_DECAL 0x2101 /* GL_BLEND */ /* GL_REPLACE */ /* TextureEnvParameter */ #define GL_TEXTURE_ENV_MODE 0x2200 #define GL_TEXTURE_ENV_COLOR 0x2201 /* TextureEnvTarget */ #define GL_TEXTURE_ENV 0x2300 /* TextureGenMode */ #define GL_EYE_LINEAR 0x2400 #define GL_OBJECT_LINEAR 0x2401 #define GL_SPHERE_MAP 0x2402 /* TextureGenParameter */ #define GL_TEXTURE_GEN_MODE 0x2500 #define GL_OBJECT_PLANE 0x2501 #define GL_EYE_PLANE 0x2502 /* TextureMagFilter */ #define GL_NEAREST 0x2600 #define GL_LINEAR 0x2601 /* TextureMinFilter */ /* GL_NEAREST */ /* GL_LINEAR */ #define GL_NEAREST_MIPMAP_NEAREST 0x2700 #define GL_LINEAR_MIPMAP_NEAREST 0x2701 #define GL_NEAREST_MIPMAP_LINEAR 0x2702 #define GL_LINEAR_MIPMAP_LINEAR 0x2703 /* TextureParameterName */ #define GL_TEXTURE_MAG_FILTER 0x2800 #define GL_TEXTURE_MIN_FILTER 0x2801 #define GL_TEXTURE_WRAP_S 0x2802 #define GL_TEXTURE_WRAP_T 0x2803 /* GL_TEXTURE_BORDER_COLOR */ /* GL_TEXTURE_PRIORITY */ /* TextureTarget */ /* GL_TEXTURE_1D */ /* GL_TEXTURE_2D */ /* GL_PROXY_TEXTURE_1D */ /* GL_PROXY_TEXTURE_2D */ /* TextureWrapMode */ #define GL_CLAMP 0x2900 #define GL_REPEAT 0x2901 /* VertexPointerType */ /* GL_SHORT */ /* GL_INT */ /* GL_FLOAT */ /* GL_DOUBLE */ /* ClientAttribMask */ #define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 #define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 #define GL_CLIENT_ALL_ATTRIB_BITS 0xffffffff /* polygon_offset */ #define GL_POLYGON_OFFSET_FACTOR 0x8038 #define GL_POLYGON_OFFSET_UNITS 0x2A00 #define GL_POLYGON_OFFSET_POINT 0x2A01 #define GL_POLYGON_OFFSET_LINE 0x2A02 #define GL_POLYGON_OFFSET_FILL 0x8037 /* texture */ #define GL_ALPHA4 0x803B #define GL_ALPHA8 0x803C #define GL_ALPHA12 0x803D #define GL_ALPHA16 0x803E #define GL_LUMINANCE4 0x803F #define GL_LUMINANCE8 0x8040 #define GL_LUMINANCE12 0x8041 #define GL_LUMINANCE16 0x8042 #define GL_LUMINANCE4_ALPHA4 0x8043 #define GL_LUMINANCE6_ALPHA2 0x8044 #define GL_LUMINANCE8_ALPHA8 0x8045 #define GL_LUMINANCE12_ALPHA4 0x8046 #define GL_LUMINANCE12_ALPHA12 0x8047 #define GL_LUMINANCE16_ALPHA16 0x8048 #define GL_INTENSITY 0x8049 #define GL_INTENSITY4 0x804A #define GL_INTENSITY8 0x804B #define GL_INTENSITY12 0x804C #define GL_INTENSITY16 0x804D #define GL_R3_G3_B2 0x2A10 #define GL_RGB4 0x804F #define GL_RGB5 0x8050 #define GL_RGB8 0x8051 #define GL_RGB10 0x8052 #define GL_RGB12 0x8053 #define GL_RGB16 0x8054 #define GL_RGBA2 0x8055 #define GL_RGBA4 0x8056 #define GL_RGB5_A1 0x8057 #define GL_RGBA8 0x8058 #define GL_RGB10_A2 0x8059 #define GL_RGBA12 0x805A #define GL_RGBA16 0x805B #define GL_TEXTURE_RED_SIZE 0x805C #define GL_TEXTURE_GREEN_SIZE 0x805D #define GL_TEXTURE_BLUE_SIZE 0x805E #define GL_TEXTURE_ALPHA_SIZE 0x805F #define GL_TEXTURE_LUMINANCE_SIZE 0x8060 #define GL_TEXTURE_INTENSITY_SIZE 0x8061 #define GL_PROXY_TEXTURE_1D 0x8063 #define GL_PROXY_TEXTURE_2D 0x8064 /* texture_object */ #define GL_TEXTURE_PRIORITY 0x8066 #define GL_TEXTURE_RESIDENT 0x8067 #define GL_TEXTURE_BINDING_1D 0x8068 #define GL_TEXTURE_BINDING_2D 0x8069 /* vertex_array */ #define GL_VERTEX_ARRAY 0x8074 #define GL_NORMAL_ARRAY 0x8075 #define GL_COLOR_ARRAY 0x8076 #define GL_INDEX_ARRAY 0x8077 #define GL_TEXTURE_COORD_ARRAY 0x8078 #define GL_EDGE_FLAG_ARRAY 0x8079 #define GL_VERTEX_ARRAY_SIZE 0x807A #define GL_VERTEX_ARRAY_TYPE 0x807B #define GL_VERTEX_ARRAY_STRIDE 0x807C #define GL_NORMAL_ARRAY_TYPE 0x807E #define GL_NORMAL_ARRAY_STRIDE 0x807F #define GL_COLOR_ARRAY_SIZE 0x8081 #define GL_COLOR_ARRAY_TYPE 0x8082 #define GL_COLOR_ARRAY_STRIDE 0x8083 #define GL_INDEX_ARRAY_TYPE 0x8085 #define GL_INDEX_ARRAY_STRIDE 0x8086 #define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 #define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 #define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A #define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C #define GL_VERTEX_ARRAY_POINTER 0x808E #define GL_NORMAL_ARRAY_POINTER 0x808F #define GL_COLOR_ARRAY_POINTER 0x8090 #define GL_INDEX_ARRAY_POINTER 0x8091 #define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 #define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 #define GL_V2F 0x2A20 #define GL_V3F 0x2A21 #define GL_C4UB_V2F 0x2A22 #define GL_C4UB_V3F 0x2A23 #define GL_C3F_V3F 0x2A24 #define GL_N3F_V3F 0x2A25 #define GL_C4F_N3F_V3F 0x2A26 #define GL_T2F_V3F 0x2A27 #define GL_T4F_V4F 0x2A28 #define GL_T2F_C4UB_V3F 0x2A29 #define GL_T2F_C3F_V3F 0x2A2A #define GL_T2F_N3F_V3F 0x2A2B #define GL_T2F_C4F_N3F_V3F 0x2A2C #define GL_T4F_C4F_N3F_V4F 0x2A2D /* Extensions */ #define GL_EXT_vertex_array 1 #define GL_EXT_bgra 1 #define GL_EXT_paletted_texture 1 #define GL_WIN_swap_hint 1 #define GL_WIN_draw_range_elements 1 // #define GL_WIN_phong_shading 1 // #define GL_WIN_specular_fog 1 /* EXT_vertex_array */ #define GL_VERTEX_ARRAY_EXT 0x8074 #define GL_NORMAL_ARRAY_EXT 0x8075 #define GL_COLOR_ARRAY_EXT 0x8076 #define GL_INDEX_ARRAY_EXT 0x8077 #define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 #define GL_EDGE_FLAG_ARRAY_EXT 0x8079 #define GL_VERTEX_ARRAY_SIZE_EXT 0x807A #define GL_VERTEX_ARRAY_TYPE_EXT 0x807B #define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C #define GL_VERTEX_ARRAY_COUNT_EXT 0x807D #define GL_NORMAL_ARRAY_TYPE_EXT 0x807E #define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F #define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 #define GL_COLOR_ARRAY_SIZE_EXT 0x8081 #define GL_COLOR_ARRAY_TYPE_EXT 0x8082 #define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 #define GL_COLOR_ARRAY_COUNT_EXT 0x8084 #define GL_INDEX_ARRAY_TYPE_EXT 0x8085 #define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 #define GL_INDEX_ARRAY_COUNT_EXT 0x8087 #define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 #define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 #define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A #define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B #define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C #define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D #define GL_VERTEX_ARRAY_POINTER_EXT 0x808E #define GL_NORMAL_ARRAY_POINTER_EXT 0x808F #define GL_COLOR_ARRAY_POINTER_EXT 0x8090 #define GL_INDEX_ARRAY_POINTER_EXT 0x8091 #define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 #define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 #define GL_DOUBLE_EXT GL_DOUBLE /* EXT_bgra */ #define GL_BGR_EXT 0x80E0 #define GL_BGRA_EXT 0x80E1 /* EXT_paletted_texture */ /* These must match the GL_COLOR_TABLE_*_SGI enumerants */ #define GL_COLOR_TABLE_FORMAT_EXT 0x80D8 #define GL_COLOR_TABLE_WIDTH_EXT 0x80D9 #define GL_COLOR_TABLE_RED_SIZE_EXT 0x80DA #define GL_COLOR_TABLE_GREEN_SIZE_EXT 0x80DB #define GL_COLOR_TABLE_BLUE_SIZE_EXT 0x80DC #define GL_COLOR_TABLE_ALPHA_SIZE_EXT 0x80DD #define GL_COLOR_TABLE_LUMINANCE_SIZE_EXT 0x80DE #define GL_COLOR_TABLE_INTENSITY_SIZE_EXT 0x80DF #define GL_COLOR_INDEX1_EXT 0x80E2 #define GL_COLOR_INDEX2_EXT 0x80E3 #define GL_COLOR_INDEX4_EXT 0x80E4 #define GL_COLOR_INDEX8_EXT 0x80E5 #define GL_COLOR_INDEX12_EXT 0x80E6 #define GL_COLOR_INDEX16_EXT 0x80E7 /* WIN_draw_range_elements */ #define GL_MAX_ELEMENTS_VERTICES_WIN 0x80E8 #define GL_MAX_ELEMENTS_INDICES_WIN 0x80E9 /* WIN_phong_shading */ #define GL_PHONG_WIN 0x80EA #define GL_PHONG_HINT_WIN 0x80EB /* WIN_specular_fog */ #define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC /* For compatibility with OpenGL v1.0 */ #define GL_LOGIC_OP GL_INDEX_LOGIC_OP #define GL_TEXTURE_COMPONENTS GL_TEXTURE_INTERNAL_FORMAT #include #endif // QT_NO_OPENGL qtscriptgenerator-src-0.2.0/generator/reporthandler.cpp000066400000000000000000000046561170724227300234410ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "reporthandler.h" #include "typesystem.h" int ReportHandler::m_warning_count = 0; int ReportHandler::m_suppressed_count = 0; QString ReportHandler::m_context; ReportHandler::DebugLevel ReportHandler::m_debug_level = NoDebug; QSet ReportHandler::m_reported_warnings; void ReportHandler::warning(const QString &text) { QString warningText = QString("WARNING(%1) :: %2").arg(m_context).arg(text); TypeDatabase *db = TypeDatabase::instance(); if (db && db->isSuppressedWarning(warningText)) { ++m_suppressed_count; } else if (!m_reported_warnings.contains(warningText)) { qDebug(qPrintable(warningText)); ++m_warning_count; m_reported_warnings.insert(warningText); } } void ReportHandler::debug(DebugLevel level, const QString &text) { if (m_debug_level == NoDebug) return; if (level <= m_debug_level) qDebug(" - DEBUG(%s) :: %s", qPrintable(m_context), qPrintable(text)); } qtscriptgenerator-src-0.2.0/generator/reporthandler.h000066400000000000000000000051121170724227300230720ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef REPORTHANDLER_H #define REPORTHANDLER_H #include #include class ReportHandler { public: enum DebugLevel { NoDebug, SparseDebug, MediumDebug, FullDebug }; static void setContext(const QString &context) { m_context = context; } static DebugLevel debugLevel() { return m_debug_level; } static void setDebugLevel(DebugLevel level) { m_debug_level = level; } static int warningCount() { return m_warning_count; } static int suppressedCount() { return m_suppressed_count; } static void warning(const QString &str); static void debugSparse(const QString &str) { debug(SparseDebug, str); } static void debugMedium(const QString &str) { debug(MediumDebug, str); } static void debugFull(const QString &str) { debug(FullDebug, str); } static void debug(DebugLevel level, const QString &str); private: static int m_warning_count; static int m_suppressed_count; static DebugLevel m_debug_level; static QString m_context; static QSet m_reported_warnings; }; #endif // REPORTHANDLER_H qtscriptgenerator-src-0.2.0/generator/setupgenerator.cpp000066400000000000000000000355321170724227300236340ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "setupgenerator.h" #include "reporthandler.h" #include "fileout.h" //#define Q_SCRIPT_LAZY_GENERATOR void SetupGenerator::addClass(const AbstractMetaClass *cls) { packHash[cls->package()].append(cls); } void writeQtScriptQtBindingsLicense(QTextStream &stream); void maybeDeclareMetaType(QTextStream &stream, const QString &typeName, QSet ®isteredTypeNames); bool hasDefaultConstructor(const AbstractMetaClass *meta_class); void SetupGenerator::generate() { QHashIterator > pack(packHash); while (pack.hasNext()) { pack.next(); QList list = pack.value(); if (list.isEmpty()) continue; QString packName = pack.key(); QStringList components = packName.split("."); if ((components.size() > 2) && (components.at(0) == "com") && (components.at(1) == "trolltech")) { // kill com.trolltech in key components.removeAt(0); components.removeAt(0); } packName.replace(".", "_"); { FileOut initFile(m_out_dir + "/generated_cpp/" + packName + "/" + packName + "_init.cpp"); QTextStream &s = initFile.stream; if (FileOut::license) writeQtScriptQtBindingsLicense(s); s << "#include " << endl << "#include " << endl; #ifdef Q_SCRIPT_LAZY_GENERATOR s << "#include " << endl << "#include " << endl; #endif s << endl; // declare individual class creation functions foreach (const AbstractMetaClass *cls, list) { s << "QScriptValue qtscript_create_" << cls->name() << "_class(QScriptEngine *engine);" << endl; } s << endl; // write table of class names { s << "static const char * const qtscript_" << packName << "_class_names[] = {" << endl; bool needComma = false; foreach (const AbstractMetaClass *cls, list) { s << " "; if (needComma) s << ", "; s << "\"" << cls->name() << "\"" << endl; needComma = true; } s << "};" << endl << endl; } // write table of function pointers { s << "typedef QScriptValue (*QtBindingCreator)(QScriptEngine *engine);" << endl; s << "static const QtBindingCreator qtscript_" << packName << "_class_functions[] = {" << endl; bool needComma = false; foreach (const AbstractMetaClass *cls, list) { s << " "; if (needComma) s << ", "; s << "qtscript_create_" << cls->name() << "_class" << endl; needComma = true; } s << "};" << endl << endl; } #ifdef Q_SCRIPT_LAZY_GENERATOR { // declare meta-types QSet registeredTypeNames = m_qmetatype_declared_typenames; foreach (const AbstractMetaClass *cls, list) { if (cls->isNamespace()) continue; QString name = cls->qualifiedCppName(); if (cls->typeEntry()->isValue() && ::hasDefaultConstructor(cls)) maybeDeclareMetaType(s, name, registeredTypeNames); maybeDeclareMetaType(s, name + "*", registeredTypeNames); } s << endl; // write table of metatype-ids s << "static const int qtscript_" << packName << "_metatype_ids[] = {" << endl; for (int i = 0; i < list.size(); ++i) { const AbstractMetaClass *cls = list.at(i); s << " "; if (i > 0) s << ", "; if (cls->isNamespace()) { s << "-1, -1"; } else { QString name = cls->qualifiedCppName(); if (cls->typeEntry()->isValue() && ::hasDefaultConstructor(cls)) s << "qMetaTypeId<" << name << ">()"; else s << "-1"; s << ", qMetaTypeId<" << name << "*>()"; } s << endl; } s << "};" << endl << endl; } // write the fake prototype class { s << "class qtscript_" << packName << "_FakePrototype : public QScriptClass" << endl << "{" << endl << "public:" << endl << " qtscript_" << packName << "_FakePrototype(QScriptEngine *engine)" << endl << " : QScriptClass(engine) {}" << endl << endl << " QueryFlags queryProperty(const QScriptValue &fake," << endl << " const QScriptString &name, QueryFlags flags, uint *)" << endl << " {" << endl << " if (fake.prototype().isValid())" << endl << " return 0;" << endl << " int classIndex = fake.data().toInt32();" << endl << " const char *className = qtscript_" << packName << "_class_names[classIndex];" << endl // << " qDebug() << \"faking\" << className;" << endl << " QScriptValue extensionObject = engine()->globalObject();" << endl << " QScriptValue ctor = extensionObject.property(className);" << endl << " QScriptValue genuine = ctor.property(\"prototype\");" << endl << " Q_ASSERT(genuine.isObject());" << endl << " const_cast(fake).setPrototype(genuine);" << endl << " if (!genuine.property(name).isValid())" << endl << " flags &= ~HandlesReadAccess;" << endl << " return flags & ~HandlesWriteAccess;" << endl << " }" << endl << endl << " QScriptValue property(const QScriptValue &fake, " << "const QScriptString &name, uint)" << endl << " {" << endl << " return fake.prototype().property(name, QScriptValue::ResolveLocal);" << endl << " }" << endl << "};" << endl << endl; } // write the lazy class loader { s << "static QScriptValue qtscript_" << packName << "_getSetClass(" << "QScriptContext *context, QScriptEngine *engine)" << endl << "{" << endl << " QScriptValue target = context->thisObject();" << endl << " int classIndex = context->callee().data().toInt32();" << endl << " const char *className = qtscript_" << packName << "_class_names[classIndex];" << endl << " qDebug() << \"loading\" << className;" << endl << " target.setProperty(className, QScriptValue(), " << "QScriptValue::PropertyGetter|QScriptValue::PropertySetter);" << endl << " if (context->argumentCount() == 1) {" << endl << " target.setProperty(className, context->argument(0));" << endl << " } else {" << endl << " target.setProperty(className, qtscript_" << packName << "_class_functions[classIndex](engine)," << endl << " QScriptValue::SkipInEnumeration);" << endl << " }" << endl << " return target.property(className);" << endl << "}" << endl << endl; } #endif // bindings init function s << "void qtscript_initialize_" << packName << "_bindings(QScriptValue &extensionObject)" << endl << "{" << endl << " QScriptEngine *engine = extensionObject.engine();" << endl; #ifdef Q_SCRIPT_LAZY_GENERATOR s << " qtscript_" << packName << "_FakePrototype *fakeProtoClass;" << endl << " fakeProtoClass = new qtscript_" << packName << "_FakePrototype(engine);" << endl; #endif s << " for (int i = 0; i < " << list.size() << "; ++i) {" << endl #ifndef Q_SCRIPT_LAZY_GENERATOR << " extensionObject.setProperty(qtscript_" << packName << "_class_names[i]," << endl << " qtscript_" << packName << "_class_functions[i](engine)," << endl << " QScriptValue::SkipInEnumeration);" << endl #else << " QScriptValue classIndex(engine, i);" << endl << " QScriptValue fakeCtor = engine->newFunction(qtscript_" << packName << "_getSetClass);" << endl << " fakeCtor.setData(classIndex);" << endl << " extensionObject.setProperty(qtscript_" << packName << "_class_names[i]," << endl << " fakeCtor, QScriptValue::PropertyGetter|QScriptValue::PropertySetter" << "|QScriptValue::SkipInEnumeration);" << endl << " QScriptValue fakeProto = engine->newObject(fakeProtoClass, classIndex);" << endl << " fakeProto.setPrototype(QScriptValue());" << endl << " if (qtscript_" << packName << "_metatype_ids[i*2] != -1)" << endl << " engine->setDefaultPrototype(qtscript_" << packName << "_metatype_ids[i*2], fakeProto);" << endl << " if (qtscript_" << packName << "_metatype_ids[i*2+1] != -1)" << endl << " engine->setDefaultPrototype(qtscript_" << packName << "_metatype_ids[i*2+1], fakeProto);" << endl #endif << " }" << endl << "}" << endl; if (initFile.done()) ++m_num_generated_written; ++m_num_generated; } { FileOut pluginFile(m_out_dir + "/generated_cpp/" + packName + "/plugin.cpp"); QTextStream &s = pluginFile.stream; if (FileOut::license) writeQtScriptQtBindingsLicense(s); s << "#include " << endl << "#include " << endl << "#include " << endl << endl; // declare the init function s << "void qtscript_initialize_" << packName << "_bindings(QScriptValue &);" << endl << endl; // plugin class declaration s << "class " << packName << "_ScriptPlugin : public QScriptExtensionPlugin" << endl << "{" << endl << "public:" << endl << " QStringList keys() const;" << endl << " void initialize(const QString &key, QScriptEngine *engine);" << endl << "};" << endl << "" << endl; // keys() s << "QStringList " << packName << "_ScriptPlugin::keys() const" << endl << "{" << endl << " QStringList list;" << endl; { QString key; for (int i = 0; i < components.size(); ++i) { if (i > 0) key.append("."); key.append(components.at(i)); s << " list << QLatin1String(\"" << key << "\");" << endl; } } s << " return list;" << endl << "}" << endl; // initialize() s << endl << "void " << packName << "_ScriptPlugin::initialize(const QString &key, QScriptEngine *engine)" << endl << "{"; { QString key; for (int i = 0; i < components.size(); ++i) { s << endl << " "; if (i > 0) { key.append("."); s << "} else "; } key.append(components.at(i)); s << "if (key == QLatin1String(\"" << key << "\")) {"; } } s << endl << " QScriptValue extensionObject = "; // ### generalize if (packName == "com.trolltech.qt.phonon") s << "setupPackage(\"phonon\", engine)"; else s << "engine->globalObject()"; s << ";" << endl; s << " qtscript_initialize_" << packName << "_bindings(extensionObject);" << endl; s << " } else {" << endl << " Q_ASSERT_X(false, \"" << packName << "::initialize\", qPrintable(key));" << endl << " }" << endl << "}" << endl << endl; s << "Q_EXPORT_STATIC_PLUGIN(" << packName << "_ScriptPlugin)" << endl << "Q_EXPORT_PLUGIN2(qtscript_" << packName.toLower() << ", " << packName << "_ScriptPlugin)" << endl; if (pluginFile.done()) ++m_num_generated_written; ++m_num_generated; } } } qtscriptgenerator-src-0.2.0/generator/setupgenerator.h000066400000000000000000000035001170724227300232670ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef SETUPGENERATOR_H #define SETUPGENERATOR_H #include "generator.h" #include "metaqtscript.h" class SetupGenerator : public Generator { Q_OBJECT public: virtual void generate(); void addClass(const AbstractMetaClass *cls); private: QHash > packHash; }; #endif // SETUPGENERATOR_H qtscriptgenerator-src-0.2.0/generator/shellgenerator.cpp000066400000000000000000000161531170724227300236010ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "shellgenerator.h" #include "reporthandler.h" #include "metaqtscript.h" bool ShellGenerator::shouldGenerate(const AbstractMetaClass *meta_class) const { uint cg = meta_class->typeEntry()->codeGeneration(); return ((cg & TypeEntry::GenerateCode) != 0) && meta_class->generateShellClass(); } void ShellGenerator::writeTypeInfo(QTextStream &s, const AbstractMetaType *type, Option options) { if ((options & OriginalTypeDescription) && !type->originalTypeDescription().isEmpty()) { s << type->originalTypeDescription(); return; } if (type->isArray()) { writeTypeInfo(s, type->arrayElementType(), options); if (options & ArrayAsPointer) { s << "*"; } else { s << "[" << type->arrayElementCount() << "]"; } return; } const TypeEntry *te = type->typeEntry(); if (type->isConstant() && !(options & ExcludeConst)) s << "const "; if ((options & EnumAsInts) && (te->isEnum() || te->isFlags())) { s << "int"; } else if (te->isFlags()) { s << ((FlagsTypeEntry *) te)->originalName(); } else { s << fixCppTypeName(te->qualifiedCppName()); } if (type->instantiations().size() > 0 && (!type->isContainer() || (static_cast(te))->type() != ContainerTypeEntry::StringListContainer)) { s << '<'; QList args = type->instantiations(); bool nested_template = false; for (int i=0; iisContainer(); writeTypeInfo(s, args.at(i)); } if (nested_template) s << ' '; s << '>'; } s << QString(type->indirections(), '*'); if (type->isReference() && !(options & ExcludeReference)) s << "&"; if (!(options & SkipName)) s << ' '; } void ShellGenerator::writeFunctionArguments(QTextStream &s, const AbstractMetaArgumentList &arguments, Option option, int numArguments) { if (numArguments < 0) numArguments = arguments.size(); for (int i=0; itype(), option); if (!(option & SkipName)) s << " " << arg->argumentName(); if ((option & IncludeDefaultExpression) && !arg->originalDefaultValueExpression().isEmpty()) { s << " = "; QString expr = arg->originalDefaultValueExpression(); if (arg->type()->typeEntry()->isEnum() && expr.indexOf("::") < 0) s << ((EnumTypeEntry *)arg->type()->typeEntry())->qualifier() << "::"; s << expr; } } } /*! * Writes the function \a meta_function signature to the textstream \a s. * * The \a name_prefix can be used to give the function name a prefix, * like "__public_" or "__override_" and \a classname_prefix can * be used to give the class name a prefix. * * The \a option flags can be used to tweak various parameters, such as * showing static, original vs renamed name, underscores for space etc. * * The \a extra_arguments list is a list of extra arguments on the * form "bool static_call". */ void ShellGenerator::writeFunctionSignature(QTextStream &s, const AbstractMetaFunction *meta_function, const AbstractMetaClass *implementor, const QString &name_prefix, Option option, const QString &classname_prefix, const QStringList &extra_arguments, int numArguments) { // ### remove the implementor AbstractMetaType *function_type = meta_function->type(); if (meta_function->isStatic() && (option & ShowStatic)) s << "static "; if ((option & SkipReturnType) == 0) { if (function_type) { writeTypeInfo(s, function_type, option); s << " "; } else if (!meta_function->isConstructor()) { s << "void "; } } if (implementor) { if (classname_prefix.isEmpty()) s << shellClassName(implementor) << "::"; else s << classname_prefix << implementor->name() << "::"; } QString function_name; if (option & OriginalName) function_name = meta_function->originalName(); else function_name = meta_function->name(); if (option & UnderscoreSpaces) function_name = function_name.replace(' ', '_'); if (meta_function->isConstructor()) function_name = shellClassName(meta_function->ownerClass()); s << name_prefix << function_name; if (meta_function->attributes() & AbstractMetaAttributes::SetterFunction) s << "_setter"; else if (meta_function->attributes() & AbstractMetaAttributes::GetterFunction) s << "_getter"; s << "("; writeFunctionArguments(s, meta_function->arguments(), option, numArguments); // The extra arguments... for (int i=0; i 0 || meta_function->arguments().size() != 0) s << ", "; s << extra_arguments.at(i); } s << ")"; if (meta_function->isConstant()) s << " const"; if (!meta_function->exception().isEmpty()) s << " " << meta_function->exception(); } qtscriptgenerator-src-0.2.0/generator/shellgenerator.h000066400000000000000000000060021170724227300232360ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef SHELLGENERATOR_H #define SHELLGENERATOR_H #include "generator.h" #include "metaqtscript.h" #include "prigenerator.h" class ShellGenerator : public Generator { Q_OBJECT public: virtual QString subDirectoryForClass(const AbstractMetaClass *cls) const { return "generated_cpp/" + cls->package().replace(".", "_") + "/"; } static void writeTypeInfo(QTextStream &s, const AbstractMetaType *type, Option option = NoOption); static void writeFunctionSignature(QTextStream &s, const AbstractMetaFunction *meta_function, const AbstractMetaClass *implementor = 0, const QString &name_prefix = QString(), Option option = NoOption, const QString &classname_prefix = QString(), const QStringList &extra_arguments = QStringList(), int numArguments = -1); static void writeFunctionArguments(QTextStream &s, const AbstractMetaArgumentList &arguments, Option option = NoOption, int numArguments = -1); bool shouldGenerate(const AbstractMetaClass *meta_class) const; static QString shellClassName(const AbstractMetaClass *meta_class) { return meta_class->generateShellClass() ? "QtScriptShell_" + meta_class->name() : meta_class->qualifiedCppName(); } protected: PriGenerator *priGenerator; }; #endif // SHELLGENERATOR_H qtscriptgenerator-src-0.2.0/generator/shellheadergenerator.cpp000066400000000000000000000107641170724227300247540ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "shellheadergenerator.h" #include "fileout.h" #include #include QString ShellHeaderGenerator::fileNameForClass(const AbstractMetaClass *meta_class) const { return QString("qtscriptshell_%1.h").arg(meta_class->name()); } void writeQtScriptQtBindingsLicense(QTextStream &stream); void ShellHeaderGenerator::write(QTextStream &s, const AbstractMetaClass *meta_class) { if (FileOut::license) writeQtScriptQtBindingsLicense(s); QString include_block = "QTSCRIPTSHELL_" + meta_class->name().toUpper() + "_H"; s << "#ifndef " << include_block << endl << "#define " << include_block << endl << endl; Include inc = meta_class->typeEntry()->include(); s << "#include "; if (inc.type == Include::IncludePath) s << "<"; else s << "\""; s << inc.name; if (inc.type == Include::IncludePath) s << ">"; else s << "\""; s << endl << endl; s << "#include " << endl << endl; QString packName = meta_class->package().replace(".", "_"); if (!meta_class->generateShellClass()) { s << "#endif" << endl << endl; priGenerator->addHeader(packName, fileNameForClass(meta_class)); return ; } s << "class " << shellClassName(meta_class) << " : public " << meta_class->qualifiedCppName() << endl << "{" << endl; s << "public:" << endl; foreach (const AbstractMetaFunction *function, meta_class->functions()) { if (function->isConstructor() && !function->isPrivate()) { s << " "; writeFunctionSignature(s, function, 0, QString(), Option(IncludeDefaultExpression | OriginalName | ShowStatic)); s << ";" << endl; } } s << " ~" << shellClassName(meta_class) << "()"; if (!meta_class->destructorException().isEmpty()) s << " " << meta_class->destructorException(); s << ";" << endl; s << endl; AbstractMetaFunctionList functions = meta_class->queryFunctions( AbstractMetaClass:: VirtualFunctions | AbstractMetaClass::WasVisible | AbstractMetaClass::NotRemovedFromTargetLang ); for (int i = 0; i < functions.size(); ++i) { s << " "; writeFunctionSignature(s, functions.at(i), 0, QString(), Option(IncludeDefaultExpression | OriginalName | ShowStatic | UnderscoreSpaces)); s << ";" << endl; } writeInjectedCode(s, meta_class); s << endl << " QScriptValue __qtscript_self;" << endl; s << "};" << endl << endl << "#endif // " << include_block << endl; priGenerator->addHeader(packName, fileNameForClass(meta_class)); } void ShellHeaderGenerator::writeInjectedCode(QTextStream &s, const AbstractMetaClass *meta_class) { CodeSnipList code_snips = meta_class->typeEntry()->codeSnips(); foreach (const CodeSnip &cs, code_snips) { if (cs.language == TypeSystem::ShellDeclaration) { s << cs.code() << endl; } } } qtscriptgenerator-src-0.2.0/generator/shellheadergenerator.h000066400000000000000000000037761170724227300244260ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef SHELL_HEADER_GENERATOR #define SHELL_HEADER_GENERATOR #include "shellgenerator.h" #include "metaqtscript.h" class ShellHeaderGenerator : public ShellGenerator { Q_OBJECT public: ShellHeaderGenerator(PriGenerator *pri) { priGenerator = pri; } virtual QString fileNameForClass(const AbstractMetaClass *cls) const; void write(QTextStream &s, const AbstractMetaClass *meta_class); void writeInjectedCode(QTextStream &s, const AbstractMetaClass *meta_class); }; #endif // SHELL_HEADER_GENERATOR qtscriptgenerator-src-0.2.0/generator/shellimplgenerator.cpp000066400000000000000000000207001170724227300244540ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "shellimplgenerator.h" #include "reporthandler.h" #include "fileout.h" extern void declareFunctionMetaTypes(QTextStream &stream, const AbstractMetaFunctionList &functions, QSet ®isteredTypeNames); QString ShellImplGenerator::fileNameForClass(const AbstractMetaClass *meta_class) const { return QString("qtscriptshell_%1.cpp").arg(meta_class->name()); } static bool include_less_than(const Include &a, const Include &b) { return a.name < b.name; } static void writeHelperCode(QTextStream &s, const AbstractMetaClass *) { s << "#define QTSCRIPT_IS_GENERATED_FUNCTION(fun) ((fun.data().toUInt32() & 0xFFFF0000) == 0xBABE0000)" << endl; s << endl; } void writeQtScriptQtBindingsLicense(QTextStream &stream); void ShellImplGenerator::write(QTextStream &s, const AbstractMetaClass *meta_class) { if (FileOut::license) writeQtScriptQtBindingsLicense(s); QString packName = meta_class->package().replace(".", "_"); priGenerator->addSource(packName, fileNameForClass(meta_class)); s << "#include \"qtscriptshell_" << meta_class->name() << ".h\"" << endl << endl; if (!meta_class->generateShellClass()) return; s << "#include " << endl; IncludeList list = meta_class->typeEntry()->extraIncludes(); qSort(list.begin(), list.end(), include_less_than); foreach (const Include &inc, list) { if (inc.type == Include::TargetLangImport) continue; s << "#include "; if (inc.type == Include::LocalPath) s << "\""; else s << "<"; s << inc.name; if (inc.type == Include::LocalPath) s << "\""; else s << ">"; s << endl; } s << endl; writeHelperCode(s, meta_class); // find constructors AbstractMetaFunctionList ctors; ctors = meta_class->queryFunctions(AbstractMetaClass::Constructors | AbstractMetaClass::WasVisible | AbstractMetaClass::NotRemovedFromTargetLang); // find member functions AbstractMetaFunctionList functions = meta_class->queryFunctions( AbstractMetaClass:: VirtualFunctions | AbstractMetaClass::WasVisible | AbstractMetaClass::NotRemovedFromTargetLang ); // write metatype declarations { QSet registeredTypeNames = m_qmetatype_declared_typenames; declareFunctionMetaTypes(s, functions, registeredTypeNames); s << endl; } // write constructors foreach (const AbstractMetaFunction *ctor, ctors) { s << "QtScriptShell_" << meta_class->name() << "::"; writeFunctionSignature(s, ctor, 0, QString(), Option(OriginalName | ShowStatic)); s << endl; s << " : " << meta_class->qualifiedCppName() << "("; AbstractMetaArgumentList args = ctor->arguments(); for (int i = 0; i < args.size(); ++i) { if (i > 0) s << ", "; s << args.at(i)->argumentName(); } s << ")" << " {}" << endl << endl; } // write destructor s << "QtScriptShell_" << meta_class->name() << "::" << "~QtScriptShell_" << meta_class->name() << "()"; if (!meta_class->destructorException().isEmpty()) s << " " << meta_class->destructorException(); s << " {}" << endl << endl; // write member functions for (int i = 0; i < functions.size(); ++i) { AbstractMetaFunction *fun = functions.at(i); writeFunctionSignature(s, fun, meta_class, QString(), Option(OriginalName | ShowStatic | UnderscoreSpaces), "QtScriptShell_"); s << endl << "{" << endl; QString scriptFunctionName = fun->name(); { QPropertySpec *read = 0; for (const AbstractMetaClass *cls = meta_class; !read && cls; cls = cls->baseClass()) read = cls->propertySpecForRead(fun->name()); if (read && (read->name() == fun->name())) { // use different name to avoid infinite recursion // ### not sure if this is the best solution though... scriptFunctionName.prepend("_qs_"); } } s << " QScriptValue _q_function = __qtscript_self.property(\"" << scriptFunctionName << "\");" << endl; s << " if (!_q_function.isFunction() || QTSCRIPT_IS_GENERATED_FUNCTION(_q_function)" << endl << " || (__qtscript_self.propertyFlags(\"" << scriptFunctionName << "\") & QScriptValue::QObjectMember)) {" << endl; AbstractMetaArgumentList args = fun->arguments(); s << " "; if (fun->isAbstract()) { s << "qFatal(\"" << meta_class->name() << "::" << fun->name() << "() is abstract!\");" << endl; } else { // call the C++ implementation if (fun->type()) s << "return "; s << meta_class->qualifiedCppName() << "::" << fun->originalName() << "("; for (int i = 0; i < args.size(); ++i) { if (i > 0) s << ", "; s << args.at(i)->argumentName(); } s << ");" << endl; } s << " } else {" << endl; // call the script function if (args.size() > 0) s << " QScriptEngine *_q_engine = __qtscript_self.engine();" << endl; s << " "; if (fun->type()) { s << "return qscriptvalue_cast<"; writeTypeInfo(s, fun->type()); s << ">("; } s << "_q_function.call(__qtscript_self"; if (args.size() > 0) { s << "," << endl; s << " QScriptValueList()"; int i = 0; for (int j = 0; j < args.size(); ++j) { if (fun->argumentRemoved(j+1)) continue; s << endl << " << "; s << "qScriptValueFromValue(_q_engine, "; AbstractMetaType *atype = args.at(j)->type(); QString asig = atype->cppSignature(); bool constCastArg = asig.endsWith('*') && asig.startsWith("const "); if (constCastArg) s << "const_cast<" << asig.mid(6) << ">("; s << args.at(i)->argumentName() << ")"; if (constCastArg) s << ")"; ++i; } } s << ")"; if (fun->type()) s << ")"; s << ";" << endl; s << " }" << endl; s << "}" << endl << endl; } } void ShellImplGenerator::writeInjectedCode(QTextStream &s, const AbstractMetaClass *meta_class) { CodeSnipList code_snips = meta_class->typeEntry()->codeSnips(); foreach (const CodeSnip &cs, code_snips) { if (cs.language == TypeSystem::ShellCode) { s << cs.code() << endl; } } } qtscriptgenerator-src-0.2.0/generator/shellimplgenerator.h000066400000000000000000000037651170724227300241350ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef SHELLIMPLGENERATOR_H #define SHELLIMPLGENERATOR_H #include "shellgenerator.h" #include "metaqtscript.h" class ShellImplGenerator : public ShellGenerator { Q_OBJECT public: ShellImplGenerator(PriGenerator *pri) { priGenerator = pri; } virtual QString fileNameForClass(const AbstractMetaClass *cls) const; void write(QTextStream &s, const AbstractMetaClass *meta_class); void writeInjectedCode(QTextStream &s, const AbstractMetaClass *meta_class); }; #endif // SHELLIMPLGENERATOR_H qtscriptgenerator-src-0.2.0/generator/typeparser.cpp000066400000000000000000000170121170724227300227540ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "typeparser.h" #include #include class Scanner { public: enum Token { StarToken, AmpersandToken, LessThanToken, ColonToken, CommaToken, OpenParenToken, CloseParenToken, SquareBegin, SquareEnd, GreaterThanToken, ConstToken, Identifier, NoToken }; Scanner(const QString &s) : m_pos(0), m_length(s.length()), m_chars(s.constData()) { } Token nextToken(); QString identifier() const; private: int m_pos; int m_length; int m_token_start; const QChar *m_chars; }; QString Scanner::identifier() const { return QString(m_chars + m_token_start, m_pos - m_token_start); } Scanner::Token Scanner::nextToken() { Token tok = NoToken; // remove whitespace while (m_pos < m_length && m_chars[m_pos] == ' ') { ++m_pos; } m_token_start = m_pos; while (m_pos < m_length) { const QChar &c = m_chars[m_pos]; if (tok == NoToken) { switch (c.toLatin1()) { case '*': tok = StarToken; break; case '&': tok = AmpersandToken; break; case '<': tok = LessThanToken; break; case '>': tok = GreaterThanToken; break; case ',': tok = CommaToken; break; case '(': tok = OpenParenToken; break; case ')': tok = CloseParenToken; break; case '[': tok = SquareBegin; break; case ']' : tok = SquareEnd; break; case ':': tok = ColonToken; Q_ASSERT(m_pos + 1 < m_length); ++m_pos; break; default: if (c.isLetterOrNumber() || c == '_') tok = Identifier; else qFatal("Unrecognized character in lexer: %c", c.toLatin1()); break; } } if (tok <= GreaterThanToken) { ++m_pos; break; } if (tok == Identifier) { if (c.isLetterOrNumber() || c == '_') ++m_pos; else break; } } if (tok == Identifier && m_pos - m_token_start == 5) { if (m_chars[m_token_start] == 'c' && m_chars[m_token_start + 1] == 'o' && m_chars[m_token_start + 2] == 'n' && m_chars[m_token_start + 3] == 's' && m_chars[m_token_start + 4] == 't') tok = ConstToken; } return tok; } TypeParser::Info TypeParser::parse(const QString &str) { Scanner scanner(str); Info info; QStack stack; stack.push(&info); bool colon_prefix = false; bool in_array = false; QString array; Scanner::Token tok = scanner.nextToken(); while (tok != Scanner::NoToken) { // switch (tok) { // case Scanner::StarToken: printf(" - *\n"); break; // case Scanner::AmpersandToken: printf(" - &\n"); break; // case Scanner::LessThanToken: printf(" - <\n"); break; // case Scanner::GreaterThanToken: printf(" - >\n"); break; // case Scanner::ColonToken: printf(" - ::\n"); break; // case Scanner::CommaToken: printf(" - ,\n"); break; // case Scanner::ConstToken: printf(" - const\n"); break; // case Scanner::SquareBegin: printf(" - [\n"); break; // case Scanner::SquareEnd: printf(" - ]\n"); break; // case Scanner::Identifier: printf(" - '%s'\n", qPrintable(scanner.identifier())); break; // default: // break; // } switch (tok) { case Scanner::StarToken: ++stack.top()->indirections; break; case Scanner::AmpersandToken: stack.top()->is_reference = true; break; case Scanner::LessThanToken: stack.top()->template_instantiations << Info(); stack.push(&stack.top()->template_instantiations.last()); break; case Scanner::CommaToken: stack.pop(); stack.top()->template_instantiations << Info(); stack.push(&stack.top()->template_instantiations.last()); break; case Scanner::GreaterThanToken: stack.pop(); break; case Scanner::ColonToken: colon_prefix = true; break; case Scanner::ConstToken: stack.top()->is_constant = true; break; case Scanner::OpenParenToken: // function pointers not supported case Scanner::CloseParenToken: { Info i; i.is_busted = true; return i; } case Scanner::Identifier: if (in_array) { array = scanner.identifier(); } else if (colon_prefix || stack.top()->qualified_name.isEmpty()) { stack.top()->qualified_name << scanner.identifier(); colon_prefix = false; } else { stack.top()->qualified_name.last().append(" " + scanner.identifier()); } break; case Scanner::SquareBegin: in_array = true; break; case Scanner::SquareEnd: in_array = false; stack.top()->arrays += array; break; default: break; } tok = scanner.nextToken(); } return info; } QString TypeParser::Info::instantiationName() const { QString s(qualified_name.join("::")); if (!template_instantiations.isEmpty()) { s += '<'; for (int i=0; i #include #include class TypeParser { public: struct Info { Info() : is_reference(false), is_constant(false), is_busted(false), indirections(0) { } QStringList qualified_name; QStringList arrays; QList template_instantiations; uint is_reference : 1; uint is_constant : 1; uint is_busted : 1; uint indirections : 5; QString toString() const; QString instantiationName() const; }; static Info parse(const QString &str); }; #endif // TYPEPARSER_H qtscriptgenerator-src-0.2.0/generator/typesystem.cpp000066400000000000000000002272171170724227300230160ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "typesystem.h" #include "generator.h" #include "customtypes.h" #include #include #include QString strings_Object = QLatin1String("Object"); QString strings_String = QLatin1String("String"); QString strings_Thread = QLatin1String("Thread"); QString strings_char = QLatin1String("char"); QString strings_java_lang = QLatin1String("java.lang"); QString strings_jchar = QLatin1String("jchar"); QString strings_jobject = QLatin1String("jobject"); static void addRemoveFunctionToTemplates(TypeDatabase *db); class StackElement { public: enum ElementType { None = 0x0, // Type tags (0x1, ... , 0xff) ObjectTypeEntry = 0x1, ValueTypeEntry = 0x2, InterfaceTypeEntry = 0x3, NamespaceTypeEntry = 0x4, ComplexTypeEntryMask = 0xf, // Non-complex type tags (0x10, 0x20, ... , 0xf0) PrimitiveTypeEntry = 0x10, EnumTypeEntry = 0x20, TypeEntryMask = 0xff, // Simple tags (0x100, 0x200, ... , 0xf00) ExtraIncludes = 0x100, Include = 0x200, ModifyFunction = 0x300, ModifyField = 0x400, Root = 0x500, CustomMetaConstructor = 0x600, CustomMetaDestructor = 0x700, ArgumentMap = 0x800, SuppressedWarning = 0x900, Rejection = 0xa00, LoadTypesystem = 0xb00, RejectEnumValue = 0xc00, Template = 0xd00, TemplateInstanceEnum = 0xe00, Replace = 0xf00, SimpleMask = 0xf00, // Code snip tags (0x1000, 0x2000, ... , 0xf000) InjectCode = 0x1000, InjectCodeInFunction = 0x2000, CodeSnipMask = 0xf000, // Function modifier tags (0x010000, 0x020000, ... , 0xf00000) Access = 0x010000, Removal = 0x020000, Rename = 0x040000, ModifyArgument = 0x080000, FunctionModifiers = 0xff0000, // Argument modifier tags (0x01000000 ... 0xf0000000) ConversionRule = 0x01000000, ReplaceType = 0x02000000, ReplaceDefaultExpression = 0x04000000, RemoveArgument = 0x08000000, DefineOwnership = 0x10000000, RemoveDefaultExpression = 0x20000000, NoNullPointers = 0x40000000, ReferenceCount = 0x80000000, ArgumentModifiers = 0xff000000 }; StackElement(StackElement *p) : entry(0), type(None), parent(p){ } TypeEntry *entry; ElementType type; StackElement *parent; union { TemplateInstance *templateInstance; TemplateEntry *templateEntry; CustomFunction *customFunction; } value; }; class Handler : public QXmlDefaultHandler { public: Handler(TypeDatabase *database, bool generate) : m_database(database), m_generate(generate ? TypeEntry::GenerateAll : TypeEntry::GenerateForSubclass) { m_current_enum = 0; current = 0; tagNames["rejection"] = StackElement::Rejection; tagNames["primitive-type"] = StackElement::PrimitiveTypeEntry; tagNames["object-type"] = StackElement::ObjectTypeEntry; tagNames["value-type"] = StackElement::ValueTypeEntry; tagNames["interface-type"] = StackElement::InterfaceTypeEntry; tagNames["namespace-type"] = StackElement::NamespaceTypeEntry; tagNames["enum-type"] = StackElement::EnumTypeEntry; tagNames["extra-includes"] = StackElement::ExtraIncludes; tagNames["include"] = StackElement::Include; tagNames["inject-code"] = StackElement::InjectCode; tagNames["modify-function"] = StackElement::ModifyFunction; tagNames["modify-field"] = StackElement::ModifyField; tagNames["access"] = StackElement::Access; tagNames["remove"] = StackElement::Removal; tagNames["rename"] = StackElement::Rename; tagNames["typesystem"] = StackElement::Root; tagNames["custom-constructor"] = StackElement::CustomMetaConstructor; tagNames["custom-destructor"] = StackElement::CustomMetaDestructor; tagNames["argument-map"] = StackElement::ArgumentMap; tagNames["suppress-warning"] = StackElement::SuppressedWarning; tagNames["load-typesystem"] = StackElement::LoadTypesystem; tagNames["define-ownership"] = StackElement::DefineOwnership; tagNames["replace-default-expression"] = StackElement::ReplaceDefaultExpression; tagNames["reject-enum-value"] = StackElement::RejectEnumValue; tagNames["replace-type"] = StackElement::ReplaceType; tagNames["conversion-rule"] = StackElement::ConversionRule; tagNames["modify-argument"] = StackElement::ModifyArgument; tagNames["remove-argument"] = StackElement::RemoveArgument; tagNames["remove-default-expression"] = StackElement::RemoveDefaultExpression; tagNames["template"] = StackElement::Template; tagNames["insert-template"] = StackElement::TemplateInstanceEnum; tagNames["replace"] = StackElement::Replace; tagNames["no-null-pointer"] = StackElement::NoNullPointers; tagNames["reference-count"] = StackElement::ReferenceCount; } bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &atts); bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName); QString errorString() const { return m_error; } bool error(const QXmlParseException &exception); bool fatalError(const QXmlParseException &exception); bool warning(const QXmlParseException &exception); bool characters(const QString &ch); private: void fetchAttributeValues(const QString &name, const QXmlAttributes &atts, QHash *acceptedAttributes); bool importFileElement(const QXmlAttributes &atts); bool convertBoolean(const QString &, const QString &, bool); TypeDatabase *m_database; StackElement* current; QString m_defaultPackage; QString m_defaultSuperclass; QString m_error; TypeEntry::CodeGeneration m_generate; EnumTypeEntry *m_current_enum; CodeSnipList m_code_snips; FunctionModificationList m_function_mods; FieldModificationList m_field_mods; QHash tagNames; }; bool Handler::error(const QXmlParseException &e) { qWarning("Error: line=%d, column=%d, message=%s\n", e.lineNumber(), e.columnNumber(), qPrintable(e.message())); return false; } bool Handler::fatalError(const QXmlParseException &e) { qWarning("Fatal error: line=%d, column=%d, message=%s\n", e.lineNumber(), e.columnNumber(), qPrintable(e.message())); return false; } bool Handler::warning(const QXmlParseException &e) { qWarning("Warning: line=%d, column=%d, message=%s\n", e.lineNumber(), e.columnNumber(), qPrintable(e.message())); return false; } void Handler::fetchAttributeValues(const QString &name, const QXmlAttributes &atts, QHash *acceptedAttributes) { Q_ASSERT(acceptedAttributes != 0); for (int i=0; icontains(key)) { ReportHandler::warning(QString("Unknown attribute for '%1': '%2'").arg(name).arg(key)); } else { (*acceptedAttributes)[key] = val; } } } bool Handler::endElement(const QString &, const QString &localName, const QString &) { QString tagName = localName.toLower(); if(tagName == "import-file") return true; if (!current) return true; switch (current->type) { case StackElement::ObjectTypeEntry: case StackElement::ValueTypeEntry: case StackElement::InterfaceTypeEntry: case StackElement::NamespaceTypeEntry: { ComplexTypeEntry *centry = static_cast(current->entry); centry->setFunctionModifications(m_function_mods); centry->setFieldModifications(m_field_mods); centry->setCodeSnips(m_code_snips); if (centry->designatedInterface()) { centry->designatedInterface()->setCodeSnips(m_code_snips); centry->designatedInterface()->setFunctionModifications(m_function_mods); } m_code_snips = CodeSnipList(); m_function_mods = FunctionModificationList(); m_field_mods = FieldModificationList(); } break; case StackElement::CustomMetaConstructor: { current->entry->setCustomConstructor(*current->value.customFunction); delete current->value.customFunction; } break; case StackElement::CustomMetaDestructor: { current->entry->setCustomDestructor(*current->value.customFunction); delete current->value.customFunction; } break; case StackElement::EnumTypeEntry: m_current_enum = 0; break; case StackElement::Template: m_database->addTemplate(current->value.templateEntry); break; case StackElement::TemplateInstanceEnum: if(current->parent->type == StackElement::InjectCode){ m_code_snips.last().addTemplateInstance(current->value.templateInstance); }else if(current->parent->type == StackElement::Template){ current->parent->value.templateEntry->addTemplateInstance(current->value.templateInstance); }else if(current->parent->type == StackElement::CustomMetaConstructor || current->parent->type == StackElement::CustomMetaConstructor){ current->parent->value.customFunction->addTemplateInstance(current->value.templateInstance); }else if(current->parent->type == StackElement::ConversionRule){ m_function_mods.last().argument_mods.last().conversion_rules.last().addTemplateInstance(current->value.templateInstance); }else if(current->parent->type == StackElement::InjectCodeInFunction){ m_function_mods.last().snips.last().addTemplateInstance(current->value.templateInstance); } break; default: break; } StackElement *child = current; current=current->parent; delete(child); return true; } bool Handler::characters(const QString &ch) { if(current->type == StackElement::Template){ current->value.templateEntry->addCode(ch); return true; } if (current->type == StackElement::CustomMetaConstructor || current->type == StackElement::CustomMetaDestructor){ current->value.customFunction->addCode(ch); return true; } if (current->type == StackElement::ConversionRule){ m_function_mods.last().argument_mods.last().conversion_rules.last().addCode(ch); return true; } if (current->parent){ if ((current->type & StackElement::CodeSnipMask) != 0) { switch (current->parent->type) { case StackElement::Root: ((TypeSystemTypeEntry *) current->parent->entry)->snips.last().addCode(ch); break; case StackElement::ModifyFunction: m_function_mods.last().snips.last().addCode(ch); break; case StackElement::NamespaceTypeEntry: case StackElement::ObjectTypeEntry: case StackElement::ValueTypeEntry: case StackElement::InterfaceTypeEntry: m_code_snips.last().addCode(ch); break; default: Q_ASSERT(false); }; return true; } } return true; } bool Handler::importFileElement(const QXmlAttributes &atts) { QString fileName = atts.value("name"); if(fileName.isEmpty()){ m_error = "Required attribute 'name' missing for include-file tag."; return false; } QFile file(fileName); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { file.setFileName(":/trolltech/generator/" + fileName); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { m_error = QString("Could not open file: '%1'").arg(fileName); return false; } } QString quoteFrom = atts.value("quote-after-line"); bool foundFromOk = quoteFrom.isEmpty(); bool from = quoteFrom.isEmpty(); QString quoteTo = atts.value("quote-before-line"); bool foundToOk = quoteTo.isEmpty(); bool to = true; QTextStream in(&file); while (!in.atEnd()) { QString line = in.readLine(); if(from && to && line.contains(quoteTo)) { to = false; foundToOk = true; break; } if(from && to) characters(line + "\n"); if(!from && line.contains(quoteFrom)) { from = true; foundFromOk = true; } } if(!foundFromOk || !foundToOk){ QString fromError = QString("Could not find quote-after-line='%1' in file '%2'.").arg(quoteFrom).arg(fileName); QString toError = QString("Could not find quote-before-line='%1' in file '%2'.").arg(quoteTo).arg(fileName); if(!foundToOk) m_error = toError; if(!foundFromOk) m_error = fromError; if(!foundFromOk && !foundToOk) m_error = fromError + " " + toError; return false; } return true; } bool Handler::convertBoolean(const QString &_value, const QString &attributeName, bool defaultValue) { QString value = _value.toLower(); if (value == "true" || value == "yes") { return true; } else if (value == "false" || value == "no") { return false; } else { QString warn = QString("Boolean value '%1' not supported in attribute '%2'. Use 'yes' or 'no'. Defaulting to '%3'.") .arg(value).arg(attributeName).arg(defaultValue ? "yes" : "no"); ReportHandler::warning(warn); return defaultValue; } } bool Handler::startElement(const QString &, const QString &n, const QString &, const QXmlAttributes &atts) { QString tagName = n.toLower(); if(tagName == "import-file"){ return importFileElement(atts); } std::auto_ptr element(new StackElement(current)); if (!tagNames.contains(tagName)) { m_error = QString("Unknown tag name: '%1'").arg(tagName); return false; } element->type = tagNames[tagName]; if (element->type & StackElement::TypeEntryMask) { if (current->type != StackElement::Root) { m_error = "Nested types not supported"; return false; } QHash attributes; attributes["name"] = QString(); switch (element->type) { case StackElement::PrimitiveTypeEntry: attributes["java-name"] = QString(); attributes["jni-name"] = QString(); attributes["preferred-conversion"] = "yes"; attributes["preferred-java-type"] = "yes"; break; case StackElement::EnumTypeEntry: attributes["flags"] = "no"; attributes["upper-bound"] = QString(); attributes["lower-bound"] = QString(); attributes["force-integer"] = "no"; attributes["extensible"] = "no"; break; case StackElement::ObjectTypeEntry: case StackElement::ValueTypeEntry: attributes["force-abstract"] = QString("no"); attributes["deprecated"] = QString("no"); // fall throooough case StackElement::InterfaceTypeEntry: attributes["default-superclass"] = m_defaultSuperclass; attributes["polymorphic-id-expression"] = QString(); attributes["delete-in-main-thread"] = QString("no"); // fall through case StackElement::NamespaceTypeEntry: attributes["java-name"] = QString(); attributes["package"] = m_defaultPackage; attributes["expense-cost"] = "1"; attributes["expense-limit"] = "none"; attributes["polymorphic-base"] = QString("no"); attributes["generate"] = QString("yes"); attributes["target-type"] = QString(); attributes["generic-class"] = QString("no"); break; default: ; // nada }; fetchAttributeValues(tagName, atts, &attributes); QString name = attributes["name"]; // We need to be able to have duplicate primitive type entries, or it's not possible to // cover all primitive java types (which we need to do in order to support fake // meta objects) if (element->type != StackElement::PrimitiveTypeEntry) { TypeEntry *tmp = m_database->findType(name); if (tmp != 0) { ReportHandler::warning(QString("Duplicate type entry: '%1'").arg(name)); } } if (name.isEmpty()) { m_error = "no 'name' attribute specified"; return false; } switch (element->type) { case StackElement::PrimitiveTypeEntry: { QString java_name = attributes["java-name"]; QString jni_name = attributes["jni-name"]; QString preferred_conversion = attributes["preferred-conversion"].toLower(); QString preferred_java_type = attributes["preferred-java-type"].toLower(); if (java_name.isEmpty()) java_name = name; if (jni_name.isEmpty()) jni_name = name; PrimitiveTypeEntry *type = new PrimitiveTypeEntry(name); type->setCodeGeneration(m_generate); type->setTargetLangName(java_name); type->setJniName(jni_name); type->setPreferredConversion(convertBoolean(preferred_conversion, "preferred-conversion", true)); type->setPreferredTargetLangType(convertBoolean(preferred_java_type, "preferred-java-type", true)); element->entry = type; } break; case StackElement::EnumTypeEntry: { QStringList names = name.split(QLatin1String("::")); if (names.size() == 1) { m_current_enum = new EnumTypeEntry(QString(), name); } else m_current_enum = new EnumTypeEntry(QStringList(names.mid(0, names.size() - 1)).join("::"), names.last()); element->entry = m_current_enum; m_current_enum->setCodeGeneration(m_generate); m_current_enum->setTargetLangPackage(m_defaultPackage); m_current_enum->setUpperBound(attributes["upper-bound"]); m_current_enum->setLowerBound(attributes["lower-bound"]); m_current_enum->setForceInteger(convertBoolean(attributes["force-integer"], "force-integer", false)); m_current_enum->setExtensible(convertBoolean(attributes["extensible"], "extensible", false)); // put in the flags parallel... if (!attributes["flags"].isEmpty() && attributes["flags"].toLower() != "no") { FlagsTypeEntry *ftype = new FlagsTypeEntry("QFlags<" + name + ">"); ftype->setOriginator(m_current_enum); ftype->setOriginalName(attributes["flags"]); ftype->setCodeGeneration(m_generate); QString origname = ftype->originalName(); QStringList lst = origname.split("::"); if (QStringList(lst.mid(0, lst.size() - 1)).join("::") != m_current_enum->javaQualifier()) { ReportHandler::warning(QString("enum %1 and flags %2 differ in qualifiers") .arg(m_current_enum->javaQualifier()) .arg(lst.at(0))); } ftype->setFlagsName(lst.last()); m_current_enum->setFlags(ftype); m_database->addFlagsType(ftype); m_database->addType(ftype); } } break; case StackElement::InterfaceTypeEntry: { ObjectTypeEntry *otype = new ObjectTypeEntry(name); QString javaName = attributes["java-name"]; if (javaName.isEmpty()) javaName = name; InterfaceTypeEntry *itype = new InterfaceTypeEntry(InterfaceTypeEntry::interfaceName(javaName)); if (!convertBoolean(attributes["generate"], "generate", true)) itype->setCodeGeneration(TypeEntry::GenerateForSubclass); else itype->setCodeGeneration(m_generate); otype->setDesignatedInterface(itype); itype->setOrigin(otype); element->entry = otype; } // fall through case StackElement::NamespaceTypeEntry: if (element->entry == 0) { element->entry = new NamespaceTypeEntry(name); } // fall through case StackElement::ObjectTypeEntry: if (element->entry == 0) { element->entry = new ObjectTypeEntry(name); } // fall through case StackElement::ValueTypeEntry: { if (element->entry == 0) { element->entry = new ValueTypeEntry(name); } ComplexTypeEntry *ctype = static_cast(element->entry); ctype->setTargetLangPackage(attributes["package"]); ctype->setDefaultSuperclass(attributes["default-superclass"]); ctype->setGenericClass(convertBoolean(attributes["generic-class"], "generic-class", false)); if (!convertBoolean(attributes["generate"], "generate", true)) element->entry->setCodeGeneration(TypeEntry::GenerateForSubclass); else element->entry->setCodeGeneration(m_generate); QString javaName = attributes["java-name"]; if (!javaName.isEmpty()) ctype->setTargetLangName(javaName); // The expense policy QString limit = attributes["expense-limit"]; if (!limit.isEmpty() && limit != "none") { ExpensePolicy ep; ep.limit = limit.toInt(); ep.cost = attributes["expense-cost"]; ctype->setExpensePolicy(ep); } ctype->setIsPolymorphicBase(convertBoolean(attributes["polymorphic-base"], "polymorphic-base", false)); ctype->setPolymorphicIdValue(attributes["polymorphic-id-expression"]); if (element->type == StackElement::ObjectTypeEntry || element->type == StackElement::ValueTypeEntry) { if (convertBoolean(attributes["force-abstract"], "force-abstract", false)) ctype->setTypeFlags(ctype->typeFlags() | ComplexTypeEntry::ForceAbstract); if (convertBoolean(attributes["deprecated"], "deprecated", false)) ctype->setTypeFlags(ctype->typeFlags() | ComplexTypeEntry::Deprecated); } if (element->type == StackElement::InterfaceTypeEntry || element->type == StackElement::ValueTypeEntry || element->type == StackElement::ObjectTypeEntry) { if (convertBoolean(attributes["delete-in-main-thread"], "delete-in-main-thread", false)) ctype->setTypeFlags(ctype->typeFlags() | ComplexTypeEntry::DeleteInMainThread); } QString targetType = attributes["target-type"]; if (!targetType.isEmpty() && element->entry->isComplex()) static_cast(element->entry)->setTargetType(targetType); // ctype->setInclude(Include(Include::IncludePath, ctype->name())); ctype = ctype->designatedInterface(); if (ctype != 0) ctype->setTargetLangPackage(attributes["package"]); } break; default: Q_ASSERT(false); }; if (element->entry) m_database->addType(element->entry); else ReportHandler::warning(QString("Type: %1 was rejected by typesystem").arg(name)); } else if (element->type != StackElement::None) { bool topLevel = element->type == StackElement::Root || element->type == StackElement::SuppressedWarning || element->type == StackElement::Rejection || element->type == StackElement::LoadTypesystem || element->type == StackElement::InjectCode || element->type == StackElement::Template; if (!topLevel && current->type == StackElement::Root) { m_error = QString("Tag requires parent: '%1'").arg(tagName); return false; } StackElement topElement = current==0 ? StackElement(0) : *current; element->entry = topElement.entry; QHash attributes; switch (element->type) { case StackElement::Root: attributes["package"] = QString(); attributes["default-superclass"] = QString(); break; case StackElement::LoadTypesystem: attributes["name"] = QString(); attributes["generate"] = "yes"; break; case StackElement::NoNullPointers: attributes["default-value"] = QString(); break; case StackElement::SuppressedWarning: attributes["text"] = QString(); break; case StackElement::ReplaceDefaultExpression: attributes["with"] = QString(); break; case StackElement::DefineOwnership: attributes["class"] = "java"; attributes["owner"] = ""; break; case StackElement::ModifyFunction: attributes["signature"] = QString(); attributes["access"] = QString(); attributes["remove"] = QString(); attributes["rename"] = QString(); attributes["deprecated"] = QString("no"); attributes["associated-to"] = QString(); attributes["virtual-slot"] = QString("no"); break; case StackElement::ModifyArgument: attributes["index"] = QString(); attributes["replace-value"] = QString(); attributes["invalidate-after-use"] = QString("no"); break; case StackElement::ModifyField: attributes["name"] = QString(); attributes["write"] = "true"; attributes["read"] = "true"; break; case StackElement::Access: attributes["modifier"] = QString(); break; case StackElement::Include: attributes["file-name"] = QString(); attributes["location"] = QString(); break; case StackElement::CustomMetaConstructor: attributes["name"] = topElement.entry->name().toLower() + "_create"; attributes["param-name"] = "copy"; break; case StackElement::CustomMetaDestructor: attributes["name"] = topElement.entry->name().toLower() + "_delete"; attributes["param-name"] = "copy"; break; case StackElement::ReplaceType: attributes["modified-type"] = QString(); break; case StackElement::InjectCode: attributes["class"] = "java"; attributes["position"] = "beginning"; break; case StackElement::ConversionRule: attributes["class"] = ""; break; case StackElement::RejectEnumValue: attributes["name"] = ""; break; case StackElement::ArgumentMap: attributes["index"] = "1"; attributes["meta-name"] = QString(); break; case StackElement::Rename: attributes["to"] = QString(); break; case StackElement::Rejection: attributes["class"] = "*"; attributes["function-name"] = "*"; attributes["field-name"] = "*"; attributes["enum-name"] = "*"; break; case StackElement::Removal: attributes["class"] = "all"; break; case StackElement::Template: attributes["name"] = QString(); break; case StackElement::TemplateInstanceEnum: attributes["name"] = QString(); break; case StackElement::Replace: attributes["from"] = QString(); attributes["to"] = QString(); break; case StackElement::ReferenceCount: attributes["action"] = QString(); attributes["variable-name"] = QString(); attributes["thread-safe"] = QString("no"); attributes["declare-variable"] = QString(); attributes["access"] = QString("private"); attributes["conditional"] = QString(""); break; default: ; // nada }; if (attributes.count() > 0) fetchAttributeValues(tagName, atts, &attributes); switch (element->type) { case StackElement::Root: m_defaultPackage = attributes["package"]; m_defaultSuperclass = attributes["default-superclass"]; element->type = StackElement::Root; element->entry = new TypeSystemTypeEntry(m_defaultPackage); TypeDatabase::instance()->addType(element->entry); break; case StackElement::LoadTypesystem: { QString name = attributes["name"]; if (name.isEmpty()) { m_error = "No typesystem name specified"; return false; } if (!m_database->parseFile(name, convertBoolean(attributes["generate"], "generate", true))) { m_error = QString("Failed to parse: '%1'").arg(name); return false; } } break; case StackElement::RejectEnumValue: { if (!m_current_enum) { m_error = " node must be used inside a node"; return false; } QString name = attributes["name"]; bool added = false; if (!name.isEmpty()) { added = true; m_current_enum->addEnumValueRejection(name); } } break; case StackElement::ReplaceType: { if (topElement.type != StackElement::ModifyArgument) { m_error = "Type replacement can only be specified for argument modifications"; return false; } if (attributes["modified-type"].isEmpty()) { m_error = "Type replacement requires 'modified-type' attribute"; return false; } m_function_mods.last().argument_mods.last().modified_type = attributes["modified-type"]; } break; case StackElement::ConversionRule: { if (topElement.type != StackElement::ModifyArgument) { m_error = "Conversion rules can only be specified for argument modification"; return false; } static QHash languageNames; if (languageNames.isEmpty()) { languageNames["native"] = TypeSystem::NativeCode; languageNames["shell"] = TypeSystem::ShellCode; } CodeSnip snip; QString languageAttribute = attributes["class"].toLower(); TypeSystem::Language lang = languageNames.value(languageAttribute, TypeSystem::NoLanguage); if (lang == TypeSystem::NoLanguage) { m_error = QString("unsupported class attribute: '%1'").arg(languageAttribute); return false; } snip.language = lang; m_function_mods.last().argument_mods.last().conversion_rules.append(snip); } break; case StackElement::ModifyArgument: { if (topElement.type != StackElement::ModifyFunction) { m_error = QString::fromLatin1("argument modification requires function" " modification as parent, was %1") .arg(topElement.type, 0, 16); return false; } QString index = attributes["index"]; if (index == "return") index = "0"; else if (index == "this") index = "-1"; bool ok = false; int idx = index.toInt(&ok); if (!ok) { m_error = QString("Cannot convert '%1' to integer").arg(index); return false; } QString replace_value = attributes["replace-value"]; if (!replace_value.isEmpty() && idx != 0) { m_error = QString("replace-value is only supported for return values (index=0)."); return false; } ArgumentModification argumentModification = ArgumentModification(idx); argumentModification.replace_value = replace_value; argumentModification.reset_after_use = convertBoolean(attributes["invalidate-after-use"], "invalidate-after-use", false); m_function_mods.last().argument_mods.append(argumentModification); } break; case StackElement::NoNullPointers: { if (topElement.type != StackElement::ModifyArgument) { m_error = "no-null-pointer requires argument modification as parent"; return false; } m_function_mods.last().argument_mods.last().no_null_pointers = true; if (m_function_mods.last().argument_mods.last().index == 0) { m_function_mods.last().argument_mods.last().null_pointer_default_value = attributes["default-value"]; } else if (!attributes["default-value"].isEmpty()) { ReportHandler::warning("default values for null pointer guards are only effective for return values"); } } break; case StackElement::DefineOwnership: { if (topElement.type != StackElement::ModifyArgument) { m_error = "define-ownership requires argument modification as parent"; return false; } static QHash languageNames; if (languageNames.isEmpty()) { languageNames["java"] = TypeSystem::TargetLangCode; languageNames["shell"] = TypeSystem::ShellCode; } QString classAttribute = attributes["class"].toLower(); TypeSystem::Language lang = languageNames.value(classAttribute, TypeSystem::NoLanguage); if (lang == TypeSystem::NoLanguage) { m_error = QString("unsupported class attribute: '%1'").arg(classAttribute); return false; } static QHash ownershipNames; if (ownershipNames.isEmpty()) { ownershipNames["java"] = TypeSystem::TargetLangOwnership; ownershipNames["c++"] = TypeSystem::CppOwnership; ownershipNames["default"] = TypeSystem::DefaultOwnership; } QString ownershipAttribute = attributes["owner"].toLower(); TypeSystem::Ownership owner = ownershipNames.value(ownershipAttribute, TypeSystem::InvalidOwnership); if (owner == TypeSystem::InvalidOwnership) { m_error = QString("unsupported owner attribute: '%1'").arg(ownershipAttribute); return false; } m_function_mods.last().argument_mods.last().ownerships[lang] = owner; } break; case StackElement::SuppressedWarning: if (attributes["text"].isEmpty()) ReportHandler::warning("Suppressed warning with no text specified"); else m_database->addSuppressedWarning(attributes["text"]); break; case StackElement::ArgumentMap: { if (!(topElement.type & StackElement::CodeSnipMask)) { m_error = "Argument maps requires code injection as parent"; return false; } bool ok; int pos = attributes["index"].toInt(&ok); if (!ok) { m_error = QString("Can't convert position '%1' to integer") .arg(attributes["position"]); return false; } if (pos <= 0) { m_error = QString("Argument position %1 must be a positive number").arg(pos); return false; } QString meta_name = attributes["meta-name"]; if (meta_name.isEmpty()) { ReportHandler::warning("Empty meta name in argument map"); } if (topElement.type == StackElement::InjectCodeInFunction) { m_function_mods.last().snips.last().argumentMap[pos] = meta_name; } else { ReportHandler::warning("Argument maps are only useful for injection of code " "into functions."); } } break; case StackElement::Removal: { if (topElement.type != StackElement::ModifyFunction) { m_error = "Function modification parent required"; return false; } static QHash languageNames; if (languageNames.isEmpty()) { languageNames["java"] = TypeSystem::TargetLangAndNativeCode; languageNames["all"] = TypeSystem::All; } QString languageAttribute = attributes["class"].toLower(); TypeSystem::Language lang = languageNames.value(languageAttribute, TypeSystem::NoLanguage); if (lang == TypeSystem::NoLanguage) { m_error = QString("unsupported class attribute: '%1'").arg(languageAttribute); return false; } m_function_mods.last().removal = lang; } break; case StackElement::Rename: case StackElement::Access: { if (topElement.type != StackElement::ModifyField && topElement.type != StackElement::ModifyFunction) { m_error = "Function or field modification parent required"; return false; } Modification *mod = 0; if (topElement.type == StackElement::ModifyFunction) mod = &m_function_mods.last(); else mod = &m_field_mods.last(); QString modifier; if (element->type == StackElement::Rename) { modifier = "rename"; QString renamed_to = attributes["to"]; if (renamed_to.isEmpty()) { m_error = "Rename modifier requires 'to' attribute"; return false; } if (topElement.type == StackElement::ModifyFunction) mod->setRenamedTo(renamed_to); else mod->setRenamedTo(renamed_to); } else { modifier = attributes["modifier"].toLower(); } if (modifier.isEmpty()) { m_error = "No access modification specified"; return false; } static QHash modifierNames; if (modifierNames.isEmpty()) { modifierNames["private"] = Modification::Private; modifierNames["public"] = Modification::Public; modifierNames["protected"] = Modification::Protected; modifierNames["friendly"] = Modification::Friendly; modifierNames["rename"] = Modification::Rename; modifierNames["final"] = Modification::Final; modifierNames["non-final"] = Modification::NonFinal; } if (!modifierNames.contains(modifier)) { m_error = QString("Unknown access modifier: '%1'").arg(modifier); return false; } mod->modifiers |= modifierNames[modifier]; } break; case StackElement::RemoveArgument: if (topElement.type != StackElement::ModifyArgument) { m_error = "Removing argument requires argument modification as parent"; return false; } m_function_mods.last().argument_mods.last().removed = true; break; case StackElement::ModifyField: { QString name = attributes["name"]; if (name.isEmpty()) break; FieldModification fm; fm.name = name; fm.modifiers = 0; QString read = attributes["read"]; QString write = attributes["write"]; if (read == "true") fm.modifiers |= FieldModification::Readable; if (write == "true") fm.modifiers |= FieldModification::Writable; m_field_mods << fm; } break; case StackElement::ModifyFunction: { if (!(topElement.type & StackElement::ComplexTypeEntryMask)) { m_error = QString::fromLatin1("Modify function requires complex type as parent" ", was=%1").arg(topElement.type, 0, 16); return false; } QString signature = attributes["signature"]; signature = QMetaObject::normalizedSignature(signature.toLocal8Bit().constData()); if (signature.isEmpty()) { m_error = "No signature for modified function"; return false; } FunctionModification mod; mod.signature = signature; QString access = attributes["access"].toLower(); if (!access.isEmpty()) { if (access == QLatin1String("private")) mod.modifiers |= Modification::Private; else if (access == QLatin1String("protected")) mod.modifiers |= Modification::Protected; else if (access == QLatin1String("public")) mod.modifiers |= Modification::Public; else if (access == QLatin1String("final")) mod.modifiers |= Modification::Final; else if (access == QLatin1String("non-final")) mod.modifiers |= Modification::NonFinal; else { m_error = QString::fromLatin1("Bad access type '%1'").arg(access); return false; } } if (convertBoolean(attributes["deprecated"], "deprecated", false)) { mod.modifiers |= Modification::Deprecated; } QString remove = attributes["remove"].toLower(); if (!remove.isEmpty()) { if (remove == QLatin1String("all")) mod.removal = TypeSystem::All; else if (remove == QLatin1String("java")) mod.removal = TypeSystem::TargetLangAndNativeCode; else { m_error = QString::fromLatin1("Bad removal type '%1'").arg(remove); return false; } } QString rename = attributes["rename"]; if (!rename.isEmpty()) { mod.renamedToName = rename; mod.modifiers |= Modification::Rename; } QString association = attributes["associated-to"]; if (!association.isEmpty()) mod.association = association; mod.modifiers |= (convertBoolean(attributes["virtual-slot"], "virtual-slot", false) ? Modification::VirtualSlot : 0); m_function_mods << mod; } break; case StackElement::ReplaceDefaultExpression: if (!(topElement.type & StackElement::ModifyArgument)) { m_error = "Replace default expression only allowed as child of argument modification"; return false; } if (attributes["with"].isEmpty()) { m_error = "Default expression replaced with empty string. Use remove-default-expression instead."; return false; } m_function_mods.last().argument_mods.last().replaced_default_expression = attributes["with"]; break; case StackElement::RemoveDefaultExpression: m_function_mods.last().argument_mods.last().removed_default_expression = true; break; case StackElement::CustomMetaConstructor: case StackElement::CustomMetaDestructor: { CustomFunction *func = new CustomFunction(attributes["name"]); func->param_name = attributes["param-name"]; element->value.customFunction = func; } break; case StackElement::ReferenceCount: { if (topElement.type != StackElement::ModifyArgument) { m_error = "reference-count must be child of modify-argument"; return false; } ReferenceCount rc; rc.threadSafe = convertBoolean(attributes["thread-safe"], "thread-safe", false); static QHash actions; if (actions.isEmpty()) { actions["add"] = ReferenceCount::Add; actions["add-all"] = ReferenceCount::AddAll; actions["remove"] = ReferenceCount::Remove; actions["set"] = ReferenceCount::Set; actions["ignore"] = ReferenceCount::Ignore; } rc.action = actions.value(attributes["action"].toLower(), ReferenceCount::Invalid); rc.variableName = attributes["variable-name"]; if (rc.action != ReferenceCount::Ignore && rc.variableName.isEmpty()) { m_error = "variable-name attribute must be specified"; return false; } rc.declareVariable = attributes["declare-variable"]; rc.conditional = attributes["conditional"]; static QHash accessRights; if (accessRights.isEmpty()) { accessRights["private"] = ReferenceCount::Private; accessRights["public"] = ReferenceCount::Public; accessRights["protected"] = ReferenceCount::Protected; accessRights["friendly"] = ReferenceCount::Friendly; } rc.access = accessRights.value(attributes["access"].toLower(), 0); if (rc.access == 0) { m_error = "unrecognized access value: " + attributes["access"]; return false; } if (rc.action == ReferenceCount::Invalid) { m_error = "unrecognized value for action attribute. supported actions:"; foreach (QString action, actions.keys()) m_error += " " + action; } m_function_mods.last().argument_mods.last().referenceCounts.append(rc); } break; case StackElement::InjectCode: { if (((topElement.type & StackElement::ComplexTypeEntryMask) == 0) && (topElement.type != StackElement::ModifyFunction) && (topElement.type != StackElement::Root)) { m_error = "wrong parent type for code injection"; return false; } static QHash languageNames; if (languageNames.isEmpty()) { languageNames["java"] = TypeSystem::TargetLangCode; languageNames["native"] = TypeSystem::NativeCode; languageNames["shell"] = TypeSystem::ShellCode; languageNames["shell-declaration"] = TypeSystem::ShellDeclaration; languageNames["library-initializer"] = TypeSystem::PackageInitializer; languageNames["destructor-function"] = TypeSystem::DestructorFunction; languageNames["constructors"] = TypeSystem::Constructors; languageNames["interface"] = TypeSystem::Interface; } QString className = attributes["class"].toLower(); if (!languageNames.contains(className)) { m_error = QString("Invalid class specifier: '%1'").arg(className); return false; } static QHash positionNames; if (positionNames.isEmpty()) { positionNames["beginning"] = CodeSnip::Beginning; positionNames["end"] = CodeSnip::End; // QtScript positionNames["prototype-initialization"] = CodeSnip::PrototypeInitialization; positionNames["constructor-initialization"] = CodeSnip::ConstructorInitialization; positionNames["constructor"] = CodeSnip::Constructor; } QString position = attributes["position"].toLower(); if (!positionNames.contains(position)) { m_error = QString("Invalid position: '%1'").arg(position); return false; } CodeSnip snip; snip.language = languageNames[className]; snip.position = positionNames[position]; if (snip.language == TypeSystem::Interface && topElement.type != StackElement::InterfaceTypeEntry) { m_error = "Interface code injections must be direct child of an interface type entry"; return false; } if (topElement.type == StackElement::ModifyFunction) { FunctionModification mod = m_function_mods.last(); if (snip.language == TypeSystem::ShellDeclaration) { m_error = "no function implementation in shell declaration in which to inject code"; return false; } m_function_mods.last().snips << snip; element->type = StackElement::InjectCodeInFunction; } else if (topElement.type == StackElement::Root) { ((TypeSystemTypeEntry *) element->entry)->snips << snip; } else if (topElement.type != StackElement::Root) { m_code_snips << snip; } } break; case StackElement::Include: { QString location = attributes["location"].toLower(); static QHash locationNames; if (locationNames.isEmpty()) { locationNames["global"] = Include::IncludePath; locationNames["local"] = Include::LocalPath; locationNames["java"] = Include::TargetLangImport; } if (!locationNames.contains(location)) { m_error = QString("Location not recognized: '%1'").arg(location); return false; } Include::IncludeType loc = locationNames[location]; Include inc(loc, attributes["file-name"]); ComplexTypeEntry *ctype = static_cast(element->entry); if (topElement.type & StackElement::ComplexTypeEntryMask) { ctype->setInclude(inc); } else if (topElement.type == StackElement::ExtraIncludes) { ctype->addExtraInclude(inc); } else { m_error = "Only supported parents are complex types and extra-includes"; return false; } inc = ctype->include(); IncludeList lst = ctype->extraIncludes(); ctype = ctype->designatedInterface(); if (ctype != 0) { ctype->setExtraIncludes(lst); ctype->setInclude(inc); } } break; case StackElement::Rejection: { QString cls = attributes["class"]; QString function = attributes["function-name"]; QString field = attributes["field-name"]; QString enum_ = attributes["enum-name"]; if (cls == "*" && function == "*" && field == "*" && enum_ == "*") { m_error = "bad reject entry, neither 'class', 'function-name' nor " "'field' specified"; return false; } m_database->addRejection(cls, function, field, enum_); } break; case StackElement::Template: element->value.templateEntry = new TemplateEntry(attributes["name"]); break; case StackElement::TemplateInstanceEnum: if (!(topElement.type & StackElement::CodeSnipMask) && (topElement.type != StackElement::Template) && (topElement.type != StackElement::CustomMetaConstructor) && (topElement.type != StackElement::CustomMetaDestructor) && (topElement.type != StackElement::ConversionRule)) { m_error = "Can only insert templates into code snippets, templates, custom-constructors, custom-destructors or conversion-rule."; return false; } element->value.templateInstance = new TemplateInstance(attributes["name"]); break; case StackElement::Replace: if (topElement.type != StackElement::TemplateInstanceEnum) { m_error = "Can only insert replace rules into insert-template."; return false; } element->parent->value.templateInstance->addReplaceRule(attributes["from"],attributes["to"]); break; default: break; // nada }; } current = element.release(); return true; } TypeDatabase *TypeDatabase::instance() { static TypeDatabase *db = new TypeDatabase(); return db; } TypeDatabase::TypeDatabase() : m_suppressWarnings(true) { addType(new StringTypeEntry("QString")); StringTypeEntry *e = new StringTypeEntry("QLatin1String"); e->setPreferredConversion(false); addType(e); e = new StringTypeEntry("QStringRef"); e->setPreferredConversion(false); addType(e); e = new StringTypeEntry("QXmlStreamStringRef"); e->setPreferredConversion(false); addType(e); addType(new CharTypeEntry("QChar")); CharTypeEntry *c = new CharTypeEntry("QLatin1Char"); c->setPreferredConversion(false); addType(c); { VariantTypeEntry *qvariant = new VariantTypeEntry("QVariant"); qvariant->setCodeGeneration(TypeEntry::GenerateNothing); addType(qvariant); } { JObjectWrapperTypeEntry *wrapper = new JObjectWrapperTypeEntry("JObjectWrapper"); wrapper->setCodeGeneration(TypeEntry::GenerateNothing); addType(wrapper); } addType(new ThreadTypeEntry()); addType(new VoidTypeEntry()); // Predefined containers... addType(new ContainerTypeEntry("QList", ContainerTypeEntry::ListContainer)); addType(new ContainerTypeEntry("QStringList", ContainerTypeEntry::StringListContainer)); addType(new ContainerTypeEntry("QLinkedList", ContainerTypeEntry::LinkedListContainer)); addType(new ContainerTypeEntry("QVector", ContainerTypeEntry::VectorContainer)); addType(new ContainerTypeEntry("QStack", ContainerTypeEntry::StackContainer)); addType(new ContainerTypeEntry("QSet", ContainerTypeEntry::SetContainer)); addType(new ContainerTypeEntry("QMap", ContainerTypeEntry::MapContainer)); addType(new ContainerTypeEntry("QHash", ContainerTypeEntry::HashContainer)); addType(new ContainerTypeEntry("QPair", ContainerTypeEntry::PairContainer)); addType(new ContainerTypeEntry("QQueue", ContainerTypeEntry::QueueContainer)); addType(new ContainerTypeEntry("QMultiMap", ContainerTypeEntry::MultiMapContainer)); // Custom types... // ### QtScript: no custom handling of QModelIndex for now // addType(new QModelIndexTypeEntry()); addRemoveFunctionToTemplates(this); } bool TypeDatabase::parseFile(const QString &filename, bool generate) { QFile file(filename); Q_ASSERT(file.exists()); QXmlInputSource source(&file); int count = m_entries.size(); QXmlSimpleReader reader; Handler handler(this, generate); reader.setContentHandler(&handler); reader.setErrorHandler(&handler); bool ok = reader.parse(&source, false); int newCount = m_entries.size(); ReportHandler::debugSparse(QString::fromLatin1("Parsed: '%1', %2 new entries") .arg(filename) .arg(newCount - count)); return ok; } QString PrimitiveTypeEntry::javaObjectName() const { static QHash table; if (table.isEmpty()) { table["boolean"] = "Boolean"; table["byte"] = "Byte"; table["char"] = "Character"; table["short"] = "Short"; table["int"] = "Integer"; table["long"] = "Long"; table["float"] = "Float"; table["double"] = "Double"; } Q_ASSERT(table.contains(targetLangName())); return table[targetLangName()]; } ContainerTypeEntry *TypeDatabase::findContainerType(const QString &name) { QString template_name = name; int pos = name.indexOf('<'); if (pos > 0) template_name = name.left(pos); TypeEntry *type_entry = findType(template_name); if (type_entry && type_entry->isContainer()) return static_cast(type_entry); return 0; } PrimitiveTypeEntry *TypeDatabase::findTargetLangPrimitiveType(const QString &java_name) { foreach (QList entries, m_entries.values()) { foreach (TypeEntry *e, entries) { if (e && e->isPrimitive()) { PrimitiveTypeEntry *pe = static_cast(e); if (pe->targetLangName() == java_name && pe->preferredConversion()) return pe; } } } return 0; } IncludeList TypeDatabase::extraIncludes(const QString &className) { ComplexTypeEntry *typeEntry = findComplexType(className); if (typeEntry != 0) return typeEntry->extraIncludes(); else return IncludeList(); } QString Include::toString() const { if (type == IncludePath) return "#include <" + name + '>'; else if (type == LocalPath) return "#include \"" + name + "\""; else return "import " + name + ";"; } QString Modification::accessModifierString() const { if (isPrivate()) return "private"; if (isProtected()) return "protected"; if (isPublic()) return "public"; if (isFriendly()) return "friendly"; return QString(); } FunctionModificationList ComplexTypeEntry::functionModifications(const QString &signature) const { FunctionModificationList lst; for (int i=0; ifindType(m_qualifier); if (te != 0) return te->targetLangName(); else return m_qualifier; } QString EnumTypeEntry::jniName() const { return "jint"; } QString FlagsTypeEntry::jniName() const { return "jint"; } void EnumTypeEntry::addEnumValueRedirection(const QString &rejected, const QString &usedValue) { m_enum_redirections << EnumValueRedirection(rejected, usedValue); } QString EnumTypeEntry::enumValueRedirection(const QString &value) const { for (int i=0; ijavaQualifier() + "." + targetLangName(); } void TypeDatabase::addRejection(const QString &class_name, const QString &function_name, const QString &field_name, const QString &enum_name) { TypeRejection r; r.class_name = class_name; r.function_name = function_name; r.field_name = field_name; r.enum_name = enum_name; m_rejections << r; } bool TypeDatabase::isClassRejected(const QString &class_name) { if (!m_rebuild_classes.isEmpty()) return !m_rebuild_classes.contains(class_name); foreach (const TypeRejection &r, m_rejections) if (r.class_name == class_name && r.function_name == "*" && r.field_name == "*" && r.enum_name == "*") { return true; } return false; } bool TypeDatabase::isEnumRejected(const QString &class_name, const QString &enum_name) { foreach (const TypeRejection &r, m_rejections) { if (r.enum_name == enum_name && (r.class_name == class_name || r.class_name == "*")) { return true; } } return false; } bool TypeDatabase::isFunctionRejected(const QString &class_name, const QString &function_name) { foreach (const TypeRejection &r, m_rejections) if (r.function_name == function_name && (r.class_name == class_name || r.class_name == "*")) return true; return false; } bool TypeDatabase::isFieldRejected(const QString &class_name, const QString &field_name) { foreach (const TypeRejection &r, m_rejections) if (r.field_name == field_name && (r.class_name == class_name || r.class_name == "*")) return true; return false; } FlagsTypeEntry *TypeDatabase::findFlagsType(const QString &name) const { FlagsTypeEntry *fte = (FlagsTypeEntry *) findType(name); return fte ? fte : (FlagsTypeEntry *) m_flags_entries.value(name); } QString TypeDatabase::globalNamespaceClassName(const TypeEntry * /*entry*/) { return QLatin1String("Global"); } /*! * The Visual Studio 2002 compiler doesn't support these symbols, * which our typedefs unforntuatly expand to. */ QString fixCppTypeName(const QString &name) { if (name == "long long") return "qint64"; else if (name == "unsigned long long") return "quint64"; return name; } QString formattedCodeHelper(QTextStream &s, Indentor &indentor, QStringList &lines) { bool multilineComment = false; bool lastEmpty = true; QString lastLine; while (!lines.isEmpty()) { const QString line = lines.takeFirst().trimmed(); if (line.isEmpty()) { if (!lastEmpty) s << endl; lastEmpty = true; continue; } else { lastEmpty = false; } if (line.startsWith("/*")) multilineComment = true; if (multilineComment) { s << indentor; if (line.startsWith("*")) s << " "; s << line << endl; if (line.endsWith("*/")) multilineComment = false; } else if (line.startsWith("}")) { return line; } else if (line.endsWith("}")) { s << indentor << line << endl; return 0; } else if(line.endsWith("{")) { s << indentor << line << endl; QString tmp; { Indentation indent(indentor); tmp = formattedCodeHelper(s, indentor, lines); } if (!tmp.isNull()) { s << indentor << tmp << endl; } lastLine = tmp; continue; } else { s << indentor; if (!lastLine.isEmpty() && !lastLine.endsWith(";") && !line.startsWith("@") && !line.startsWith("//") && !lastLine.startsWith("//") && !lastLine.endsWith("}") && !line.startsWith("{")) s << " "; s << line << endl; } lastLine = line; } return 0; } QTextStream &CodeSnip::formattedCode(QTextStream &s, Indentor &indentor) const { QStringList lst(code().split("\n")); while (!lst.isEmpty()) { QString tmp = formattedCodeHelper(s, indentor, lst); if (!tmp.isNull()) { s << indentor << tmp << endl; } } s.flush(); return s; } QString TemplateInstance::expandCode() const{ TemplateEntry *templateEntry = TypeDatabase::instance()->findTemplate(m_name); if(templateEntry){ QString res = templateEntry->code(); foreach(QString key, replaceRules.keys()){ res.replace(key, replaceRules[key]); } return "// TEMPLATE - " + m_name + " - START" + res + "// TEMPLATE - " + m_name + " - END"; } else{ ReportHandler::warning("insert-template referring to non-existing template '" + m_name + "'"); } return QString(); } QString CodeSnipAbstract::code() const{ QString res; foreach(CodeSnipFragment *codeFrag, codeList){ res.append(codeFrag->code()); } return res; } QString CodeSnipFragment::code() const{ if(m_instance) return m_instance->expandCode(); else return m_code; } QString FunctionModification::toString() const { QString str = signature + QLatin1String("->"); if (modifiers & AccessModifierMask) { switch (modifiers & AccessModifierMask) { case Private: str += QLatin1String("private"); break; case Protected: str += QLatin1String("protected"); break; case Public: str += QLatin1String("public"); break; case Friendly: str += QLatin1String("friendly"); break; } } if (modifiers & Final) str += QLatin1String("final"); if (modifiers & NonFinal) str += QLatin1String("non-final"); if (modifiers & Readable) str += QLatin1String("readable"); if (modifiers & Writable) str += QLatin1String("writable"); if (modifiers & CodeInjection) { foreach (CodeSnip s, snips) { str += QLatin1String("\n//code injection:\n"); str += s.code(); } } if (modifiers & Rename) str += QLatin1String("renamed:") + renamedToName; if (modifiers & Deprecated) str += QLatin1String("deprecate"); if (modifiers & ReplaceExpression) str += QLatin1String("replace-expression"); return str; } static void removeFunction(ComplexTypeEntry *e, const char *signature) { FunctionModification mod; mod.signature = QMetaObject::normalizedSignature(signature); mod.removal = TypeSystem::All; e->addFunctionModification(mod); } static void injectCode(ComplexTypeEntry *e, const char *signature, const QByteArray &code, const ArgumentMap &args) { CodeSnip snip; snip.language = TypeSystem::NativeCode; snip.position = CodeSnip::Beginning; snip.addCode(QString::fromLatin1(code)); snip.argumentMap = args; FunctionModification mod; mod.signature = QMetaObject::normalizedSignature(signature); mod.snips << snip; mod.modifiers = Modification::CodeInjection; e->addFunctionModification(mod); } static void addRemoveFunctionToTemplates(TypeDatabase *db) { ContainerTypeEntry *qvector = db->findContainerType(QLatin1String("QVector")); removeFunction(qvector, "constData() const"); removeFunction(qvector, "data() const"); removeFunction(qvector, "data()"); removeFunction(qvector, "first()"); removeFunction(qvector, "last()"); removeFunction(qvector, "operator[](int)"); removeFunction(qvector, "operator[](int) const"); removeFunction(qvector, "operator=(QVector)"); ContainerTypeEntry *qlist = db->findContainerType(QLatin1String("QList")); removeFunction(qlist, "constData() const"); removeFunction(qlist, "data() const"); removeFunction(qlist, "data()"); removeFunction(qlist, "back()"); removeFunction(qlist, "front()"); removeFunction(qlist, "first()"); removeFunction(qlist, "last()"); removeFunction(qlist, "operator[](int)"); removeFunction(qlist, "operator[](int) const"); removeFunction(qlist, "operator=(QList)"); ContainerTypeEntry *qqueue = db->findContainerType(QLatin1String("QQueue")); removeFunction(qqueue, "head() const"); // QtScript: The next part is Java-specific, skip it for now... return; ArgumentMap args1; args1[1] = QLatin1String("$1"); ArgumentMap args2 = args1; args2[2] = QLatin1String("$2"); QByteArray code = "\nif ($1 >= __qt_this->size() || $1 < 0) {" "\n __jni_env->ThrowNew(__jni_env->FindClass(\"java/lang/IndexOutOfBoundsException\")," "\n QString::fromLatin1(\"Accessing container of size %3 at %4\")" "\n .arg(__qt_this->size()).arg($1).toLatin1());" "\n return;" "\n}"; QByteArray code_with_return = QByteArray(code).replace("return;", "return 0;"); QByteArray code_index_length = "\nif ($1 < 0 || $2 < 0 || ($1 + $2) >= __qt_this->size()) {" "\n __jni_env->ThrowNew(__jni_env->FindClass(\"java/lang/IndexOutOfBoundsException\")," "\n QString::fromLatin1(\"Accessing container of size %3 from %4 to %5\")" "\n .arg(__qt_this->size()).arg($1).arg($1+$2).toLatin1());" "\n return;" "\n}"; QByteArray code_non_empty = "\nif (__qt_this->isEmpty()) {" "\n __jni_env->ThrowNew(__jni_env->FindClass(\"java/lang/IndexOutOfBoundsException\")," "\n QString::fromLatin1(\"Accessing empty container...\").toLatin1());" "\n return;" "\n}"; QByteArray code_two_indices = "\nif ($1 < 0 || $2 < 0 || $1 >= __qt_this->size() || $2 >= __qt_this->size()) {" "\n __jni_env->ThrowNew(__jni_env->FindClass(\"java/lang/IndexOutOfBoundsException\")," "\n QString::fromLatin1(\"Accessing container of size %3 from %4 to %5\")" "\n .arg(__qt_this->size()).arg($1).arg($1+$2).toLatin1());" "\n return;" "\n}"; { // QVector safty... injectCode(qvector, "at(int) const", code_with_return, args1); injectCode(qvector, "replace(int,T)", code, args1); injectCode(qvector, "remove(int)", code, args1); injectCode(qvector, "remove(int, int)", code_index_length, args2); injectCode(qvector, "pop_back()", code_non_empty, ArgumentMap()); injectCode(qvector, "pop_front()", code_non_empty, ArgumentMap()); } { // QList safty... injectCode(qlist, "at(int) const", code_with_return, args1); injectCode(qlist, "replace(int, T)", code, args1); injectCode(qlist, "pop_back()", code_non_empty, ArgumentMap()); injectCode(qlist, "pop_front()", code_non_empty, ArgumentMap()); injectCode(qlist, "swap(int, int)", code_two_indices, args2); injectCode(qlist, "move(int, int)", code_two_indices, args2); injectCode(qlist, "removeAt(int)", code, args1); injectCode(qlist, "takeAt(int)", code_with_return, args1); } } qtscriptgenerator-src-0.2.0/generator/typesystem.h000066400000000000000000001066331170724227300224610ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef TYPESYSTEM_H #define TYPESYSTEM_H #include #include #include #include #include class Indentor; class AbstractMetaType; class QTextStream; class EnumTypeEntry; class FlagsTypeEntry; extern QString strings_Object; extern QString strings_String; extern QString strings_Thread; extern QString strings_char; extern QString strings_java_lang; extern QString strings_jchar; extern QString strings_jobject; struct Include { enum IncludeType { IncludePath, LocalPath, TargetLangImport }; Include() : type(IncludePath) { } Include(IncludeType t, const QString &nam) : type(t), name(nam) { }; bool isValid() { return !name.isEmpty(); } IncludeType type; QString name; QString toString() const; bool operator<(const Include &other) const { return name < other.name; } }; typedef QList IncludeList; typedef QMap ArgumentMap; class TemplateInstance; namespace TypeSystem { enum Language { NoLanguage = 0x0000, TargetLangCode = 0x0001, NativeCode = 0x0002, ShellCode = 0x0004, ShellDeclaration = 0x0008, PackageInitializer = 0x0010, DestructorFunction = 0x0020, Constructors = 0x0040, Interface = 0x0080, // masks All = TargetLangCode | NativeCode | ShellCode | ShellDeclaration | PackageInitializer | Constructors | Interface | DestructorFunction, JavaAndNativeCode = TargetLangCode | NativeCode, TargetLangAndNativeCode = TargetLangCode | NativeCode }; enum Ownership { InvalidOwnership, DefaultOwnership, TargetLangOwnership, CppOwnership }; }; struct ReferenceCount { ReferenceCount() : threadSafe(false), access(Public) { } enum Action { // 0x01 - 0xff Invalid = 0x00, Add = 0x01, AddAll = 0x02, Remove = 0x04, Set = 0x08, Ignore = 0x10, ActionsMask = 0xff, Padding = 0xffffffff }; enum Flag { // 0x100 - 0xf00 ThreadSafe = 0x100, Static = 0x200, DeclareVariable = 0x400, FlagsMask = 0xf00 }; enum Access { // 0x1000 - 0xf000 Private = 0x1000, Protected = 0x2000, Friendly = 0x3000, Public = 0x4000, AccessMask = 0xf000 }; Action action; QString variableName; QString conditional; QString declareVariable; uint threadSafe : 1; uint access; }; class CodeSnipFragment{ private: const QString m_code; TemplateInstance *m_instance; public: CodeSnipFragment(const QString &code) : m_code(code), m_instance(0) {} CodeSnipFragment(TemplateInstance *instance) : m_instance(instance) {} QString code() const; }; class CodeSnipAbstract{ public: QString code() const; void addCode(const QString &code){ codeList.append(new CodeSnipFragment(code)); } void addTemplateInstance(TemplateInstance *ti){ codeList.append(new CodeSnipFragment(ti)); } QList codeList; }; class CustomFunction : public CodeSnipAbstract { public: CustomFunction(const QString &n = QString()) : name(n) { } QString name; QString param_name; }; class TemplateEntry : public CodeSnipAbstract { public: TemplateEntry(const QString &name) : m_name(name) { }; QString name() const { return m_name; }; private: QString m_name; }; typedef QHash TemplateEntryHash; class TemplateInstance { public: TemplateInstance(const QString &name) : m_name(name) {} void addReplaceRule(const QString &name, const QString &value){ replaceRules[name]=value; } QString expandCode() const; QString name() const { return m_name; } private: const QString m_name; QHash replaceRules; }; class CodeSnip : public CodeSnipAbstract { public: enum Position { Beginning, End, AfterThis, // QtScript PrototypeInitialization, ConstructorInitialization, Constructor }; CodeSnip() : language(TypeSystem::TargetLangCode) { } CodeSnip(TypeSystem::Language lang) : language(lang) { } // Very simple, easy to make code ugly if you try QTextStream &formattedCode(QTextStream &s, Indentor &indentor) const; TypeSystem::Language language; Position position; ArgumentMap argumentMap; }; typedef QList CodeSnipList; struct ArgumentModification { ArgumentModification(int idx) : removed_default_expression(false), removed(false), no_null_pointers(false), index(idx) {} // Should the default expression be removed? uint removed_default_expression : 1; uint removed : 1; uint no_null_pointers : 1; uint reset_after_use : 1; // The index of this argument int index; // Reference count flags for this argument QList referenceCounts; // The text given for the new type of the argument QString modified_type; QString replace_value; // The code to be used to construct a return value when no_null_pointers is true and // the returned value is null. If no_null_pointers is true and this string is // empty, then the base class implementation will be used (or a default construction // if there is no implementation) QString null_pointer_default_value; // The text of the new default expression of the argument QString replaced_default_expression; // The new definition of ownership for a specific argument QHash ownerships; // Different conversion rules CodeSnipList conversion_rules; }; struct Modification { enum Modifiers { Private = 0x0001, Protected = 0x0002, Public = 0x0003, Friendly = 0x0004, AccessModifierMask = 0x000f, Final = 0x0010, NonFinal = 0x0020, FinalMask = Final | NonFinal, Readable = 0x0100, Writable = 0x0200, CodeInjection = 0x1000, Rename = 0x2000, Deprecated = 0x4000, ReplaceExpression = 0x8000, VirtualSlot = 0x10000 | NonFinal }; Modification() : modifiers(0) { } bool isAccessModifier() const { return modifiers & AccessModifierMask; } Modifiers accessModifier() const { return Modifiers(modifiers & AccessModifierMask); } bool isPrivate() const { return accessModifier() == Private; } bool isProtected() const { return accessModifier() == Protected; } bool isPublic() const { return accessModifier() == Public; } bool isFriendly() const { return accessModifier() == Friendly; } bool isFinal() const { return modifiers & Final; } bool isNonFinal() const { return modifiers & NonFinal; } bool isVirtualSlot() const { return (modifiers & VirtualSlot) == VirtualSlot; } QString accessModifierString() const; bool isDeprecated() const { return modifiers & Deprecated; } void setRenamedTo(const QString &name) { renamedToName = name; } QString renamedTo() const { return renamedToName; } bool isRenameModifier() const { return modifiers & Rename; } uint modifiers; QString renamedToName; }; struct FunctionModification: public Modification { FunctionModification() : removal(TypeSystem::NoLanguage) { } bool isCodeInjection() const { return modifiers & CodeInjection; } bool isRemoveModifier() const { return removal != TypeSystem::NoLanguage; } QString toString() const; QString signature; QString association; CodeSnipList snips; TypeSystem::Language removal; QList argument_mods; }; typedef QList FunctionModificationList; struct FieldModification: public Modification { bool isReadable() const { return modifiers & Readable; } bool isWritable() const { return modifiers & Writable; } QString name; }; typedef QList FieldModificationList; struct ExpensePolicy { ExpensePolicy() : limit(-1) { } int limit; QString cost; bool isValid() const { return limit >= 0; } }; class InterfaceTypeEntry; class ObjectTypeEntry; class TypeEntry { public: enum Type { PrimitiveType, VoidType, FlagsType, EnumType, TemplateArgumentType, ThreadType, BasicValueType, StringType, ContainerType, InterfaceType, ObjectType, NamespaceType, VariantType, JObjectWrapperType, CharType, ArrayType, TypeSystemType, CustomType, }; enum CodeGeneration { GenerateTargetLang = 0x0001, GenerateCpp = 0x0002, GenerateForSubclass = 0x0004, GenerateNothing = 0, GenerateAll = 0xffff, GenerateCode = GenerateTargetLang | GenerateCpp }; TypeEntry(const QString &name, Type t) : m_name(name), m_type(t), m_code_generation(GenerateAll), m_preferred_conversion(true) { }; virtual ~TypeEntry() { } Type type() const { return m_type; } bool isPrimitive() const { return m_type == PrimitiveType; } bool isEnum() const { return m_type == EnumType; } bool isFlags() const { return m_type == FlagsType; } bool isInterface() const { return m_type == InterfaceType; } bool isObject() const { return m_type == ObjectType; } bool isString() const { return m_type == StringType; } bool isChar() const { return m_type == CharType; } bool isNamespace() const { return m_type == NamespaceType; } bool isContainer() const { return m_type == ContainerType; } bool isVariant() const { return m_type == VariantType; } bool isJObjectWrapper() const { return m_type == JObjectWrapperType; } bool isArray() const { return m_type == ArrayType; } bool isTemplateArgument() const { return m_type == TemplateArgumentType; } bool isVoid() const { return m_type == VoidType; } bool isThread() const { return m_type == ThreadType; } bool isCustom() const { return m_type == CustomType; } bool isBasicValue() const { return m_type == BasicValueType; } bool isTypeSystem() const { return m_type == TypeSystemType; } virtual bool preferredConversion() const { return m_preferred_conversion; } virtual void setPreferredConversion(bool b) { m_preferred_conversion = b; } // The type's name in C++, fully qualified QString name() const { return m_name; } uint codeGeneration() const { return m_code_generation; } void setCodeGeneration(uint cg) { m_code_generation = cg; } virtual QString qualifiedCppName() const { return m_name; } // Its type's name in JNI virtual QString jniName() const { return m_name; } // The type's name in TargetLang virtual QString targetLangName() const { return m_name; } // The type to lookup when converting to TargetLang virtual QString lookupName() const { return targetLangName(); } // The package virtual QString javaPackage() const { return QString(); } virtual QString qualifiedTargetLangName() const { QString pkg = javaPackage(); if (pkg.isEmpty()) return targetLangName(); return pkg + '.' + targetLangName(); } virtual InterfaceTypeEntry *designatedInterface() const { return 0; } void setCustomConstructor(const CustomFunction &func) { m_customConstructor = func; } CustomFunction customConstructor() const { return m_customConstructor; } void setCustomDestructor(const CustomFunction &func) { m_customDestructor = func; } CustomFunction customDestructor() const { return m_customDestructor; } virtual bool isValue() const { return false; } virtual bool isComplex() const { return false; } virtual bool isNativeIdBased() const { return false; } private: QString m_name; Type m_type; uint m_code_generation; CustomFunction m_customConstructor; CustomFunction m_customDestructor; bool m_preferred_conversion; }; typedef QHash > TypeEntryHash; typedef QHash SingleTypeEntryHash; class TypeSystemTypeEntry : public TypeEntry { public: TypeSystemTypeEntry(const QString &name) : TypeEntry(name, TypeSystemType) { }; QList snips; }; class ThreadTypeEntry : public TypeEntry { public: ThreadTypeEntry() : TypeEntry("QThread", ThreadType) { setCodeGeneration(GenerateNothing); } QString jniName() const { return strings_jobject; } QString targetLangName() const { return strings_Thread; } QString javaPackage() const { return strings_java_lang; } }; class VoidTypeEntry : public TypeEntry { public: VoidTypeEntry() : TypeEntry("void", VoidType) { } }; class TemplateArgumentEntry : public TypeEntry { public: TemplateArgumentEntry(const QString &name) : TypeEntry(name, TemplateArgumentType), m_ordinal(0) { } int ordinal() const { return m_ordinal; } void setOrdinal(int o) { m_ordinal = o; } private: int m_ordinal; }; class ArrayTypeEntry : public TypeEntry { public: ArrayTypeEntry(const TypeEntry *nested_type) : TypeEntry("Array", ArrayType), m_nested_type(nested_type) { Q_ASSERT(m_nested_type); } void setNestedTypeEntry(TypeEntry *nested) { m_nested_type = nested; } const TypeEntry *nestedTypeEntry() const { return m_nested_type; } QString targetLangName() const { return m_nested_type->targetLangName() + "[]"; } QString jniName() const { if (m_nested_type->isPrimitive()) return m_nested_type->jniName() + "Array"; else return "jobjectArray"; } private: const TypeEntry *m_nested_type; }; class PrimitiveTypeEntry : public TypeEntry { public: PrimitiveTypeEntry(const QString &name) : TypeEntry(name, PrimitiveType), m_preferred_conversion(true), m_preferred_java_type(true) { } QString targetLangName() const { return m_java_name; } void setTargetLangName(const QString &targetLangName) { m_java_name = targetLangName; } QString jniName() const { return m_jni_name; } void setJniName(const QString &jniName) { m_jni_name = jniName; } QString javaObjectFullName() const { return javaObjectPackage() + "." + javaObjectName(); } QString javaObjectName() const; QString javaObjectPackage() const { return strings_java_lang; } virtual bool preferredConversion() const { return m_preferred_conversion; } virtual void setPreferredConversion(bool b) { m_preferred_conversion = b; } virtual bool preferredTargetLangType() const { return m_preferred_java_type; } virtual void setPreferredTargetLangType(bool b) { m_preferred_java_type = b; } private: QString m_java_name; QString m_jni_name; uint m_preferred_conversion : 1; uint m_preferred_java_type : 1; }; struct EnumValueRedirection { EnumValueRedirection(const QString &rej, const QString &us) : rejected(rej), used(us) { } QString rejected; QString used; }; class EnumTypeEntry : public TypeEntry { public: EnumTypeEntry(const QString &nspace, const QString &enumName) : TypeEntry(nspace.isEmpty() ? enumName : nspace + QLatin1String("::") + enumName, EnumType), m_flags(0), m_extensible(false) { m_qualifier = nspace; m_java_name = enumName; } QString javaPackage() const { return m_package_name; } void setTargetLangPackage(const QString &package) { m_package_name = package; } QString targetLangName() const { return m_java_name; } QString javaQualifier() const; QString qualifiedTargetLangName() const { QString pkg = javaPackage(); if (pkg.isEmpty()) return javaQualifier() + '.' + targetLangName(); return pkg + '.' + javaQualifier() + '.' + targetLangName(); } QString jniName() const; Include include() const { return m_include; } void setInclude(const Include &inc) { m_include = inc; } QString qualifier() const { return m_qualifier; } void setQualifier(const QString &q) { m_qualifier = q; } virtual bool preferredConversion() const { return false; } bool isBoundsChecked() const { return m_lower_bound.isEmpty() && m_upper_bound.isEmpty(); } QString upperBound() const { return m_upper_bound; } void setUpperBound(const QString &bound) { m_upper_bound = bound; } QString lowerBound() const { return m_lower_bound; } void setLowerBound(const QString &bound) { m_lower_bound = bound; } void setFlags(FlagsTypeEntry *flags) { m_flags = flags; } FlagsTypeEntry *flags() const { return m_flags; } bool isExtensible() const { return m_extensible; } void setExtensible(bool is) { m_extensible = is; } bool isEnumValueRejected(const QString &name) { return m_rejected_enums.contains(name); } void addEnumValueRejection(const QString &name) { m_rejected_enums << name; } QStringList enumValueRejections() const { return m_rejected_enums; } void addEnumValueRedirection(const QString &rejected, const QString &usedValue); QString enumValueRedirection(const QString &value) const; bool forceInteger() const { return m_force_integer; } void setForceInteger(bool force) { m_force_integer = force; } private: Include m_include; QString m_package_name; QString m_qualifier; QString m_java_name; QString m_lower_bound; QString m_upper_bound; QStringList m_rejected_enums; QList m_enum_redirections; FlagsTypeEntry *m_flags; bool m_extensible; bool m_force_integer; }; class FlagsTypeEntry : public TypeEntry { public: FlagsTypeEntry(const QString &name) : TypeEntry(name, FlagsType), m_enum(0) { } QString qualifiedTargetLangName() const; QString targetLangName() const { return m_java_name; } QString jniName() const; virtual bool preferredConversion() const { return false; } QString originalName() const { return m_original_name; } void setOriginalName(const QString &s) { m_original_name = s; } QString flagsName() const { return m_java_name; } void setFlagsName(const QString &name) { m_java_name = name; } bool forceInteger() const { return m_enum->forceInteger(); } EnumTypeEntry *originator() const { return m_enum; } void setOriginator(EnumTypeEntry *e) { m_enum = e; } QString javaPackage() const { return m_enum->javaPackage(); } private: QString m_original_name; QString m_java_name; EnumTypeEntry *m_enum; }; class ComplexTypeEntry : public TypeEntry { public: enum TypeFlag { ForceAbstract = 0x1, DeleteInMainThread = 0x2, Deprecated = 0x4 }; typedef QFlags TypeFlags; ComplexTypeEntry(const QString &name, Type t) : TypeEntry(QString(name).replace("::", "_"), t), m_qualified_cpp_name(name), m_qobject(false), m_polymorphic_base(false), m_generic_class(false), m_type_flags(0) { Include inc; inc.name = "QVariant"; inc.type = Include::IncludePath; addExtraInclude(inc); } bool isComplex() const { return true; } IncludeList extraIncludes() const { return m_extra_includes; } void setExtraIncludes(const IncludeList &includes) { m_extra_includes = includes; } void addExtraInclude(const Include &include) { if (!m_includes_used.value(include.name, false)) { m_extra_includes << include; m_includes_used[include.name] = true; } } ComplexTypeEntry *copy() const { ComplexTypeEntry *centry = new ComplexTypeEntry(name(), type()); centry->setInclude(include()); centry->setExtraIncludes(extraIncludes()); centry->setFunctionModifications(functionModifications()); centry->setFieldModifications(fieldModifications()); centry->setQObject(isQObject()); centry->setDefaultSuperclass(defaultSuperclass()); centry->setCodeSnips(codeSnips()); centry->setTargetLangPackage(javaPackage()); return centry; } void setLookupName(const QString &name) { m_lookup_name = name; } virtual QString lookupName() const { return m_lookup_name.isEmpty() ? targetLangName() : m_lookup_name; } QString jniName() const { return strings_jobject; } Include include() const { return m_include; } void setInclude(const Include &inc) { m_include = inc; } void setTypeFlags(TypeFlags flags) { m_type_flags = flags; } TypeFlags typeFlags() const { return m_type_flags; } CodeSnipList codeSnips() const { return m_code_snips; } void setCodeSnips(const CodeSnipList &codeSnips) { m_code_snips = codeSnips; } void addCodeSnip(const CodeSnip &codeSnip) { m_code_snips << codeSnip; } FunctionModificationList functionModifications() const { return m_function_mods; } void setFunctionModifications(const FunctionModificationList &functionModifications) { m_function_mods = functionModifications; } void addFunctionModification(const FunctionModification &functionModification) { m_function_mods << functionModification; } FunctionModificationList functionModifications(const QString &signature) const; FieldModification fieldModification(const QString &name) const; void setFieldModifications(const FieldModificationList &mods) { m_field_mods = mods; } FieldModificationList fieldModifications() const { return m_field_mods; } QString javaPackage() const { return m_package; } void setTargetLangPackage(const QString &package) { m_package = package; } bool isQObject() const { return m_qobject; } void setQObject(bool qobject) { m_qobject = qobject; } QString defaultSuperclass() const { return m_default_superclass; } void setDefaultSuperclass(const QString &sc) { m_default_superclass = sc; } virtual QString qualifiedCppName() const { return m_qualified_cpp_name; } void setIsPolymorphicBase(bool on) { m_polymorphic_base = on; } bool isPolymorphicBase() const { return m_polymorphic_base; } void setPolymorphicIdValue(const QString &value) { m_polymorphic_id_value = value; } QString polymorphicIdValue() const { return m_polymorphic_id_value; } void setExpensePolicy(const ExpensePolicy &policy) { m_expense_policy = policy; } const ExpensePolicy &expensePolicy() const { return m_expense_policy; } QString targetType() const { return m_target_type; } void setTargetType(const QString &code) { m_target_type = code; } QString targetLangName() const { return m_java_name.isEmpty() ? TypeEntry::targetLangName() : m_java_name; } void setTargetLangName(const QString &name) { m_java_name = name; } bool isGenericClass() const { return m_generic_class; } void setGenericClass(bool isGeneric) { m_generic_class = isGeneric; } private: IncludeList m_extra_includes; Include m_include; QHash m_includes_used; FunctionModificationList m_function_mods; FieldModificationList m_field_mods; CodeSnipList m_code_snips; QString m_package; QString m_default_superclass; QString m_qualified_cpp_name; QString m_java_name; uint m_qobject : 1; uint m_polymorphic_base : 1; uint m_generic_class : 1; QString m_polymorphic_id_value; QString m_lookup_name; QString m_target_type; ExpensePolicy m_expense_policy; TypeFlags m_type_flags; }; class ContainerTypeEntry : public ComplexTypeEntry { public: enum Type { NoContainer, ListContainer, StringListContainer, LinkedListContainer, VectorContainer, StackContainer, QueueContainer, SetContainer, MapContainer, MultiMapContainer, HashContainer, MultiHashContainer, PairContainer, }; ContainerTypeEntry(const QString &name, Type type) : ComplexTypeEntry(name, ContainerType) { m_type = type; setCodeGeneration(GenerateForSubclass); } Type type() const { return m_type; } QString targetLangName() const; QString javaPackage() const; QString qualifiedCppName() const; private: Type m_type; }; class NamespaceTypeEntry : public ComplexTypeEntry { public: NamespaceTypeEntry(const QString &name) : ComplexTypeEntry(name, NamespaceType) { } }; class ValueTypeEntry : public ComplexTypeEntry { public: ValueTypeEntry(const QString &name) : ComplexTypeEntry(name, BasicValueType) { } bool isValue() const { return true; } virtual bool isNativeIdBased() const { return true; } protected: ValueTypeEntry(const QString &name, Type t) : ComplexTypeEntry(name, t) { } }; class StringTypeEntry : public ValueTypeEntry { public: StringTypeEntry(const QString &name) : ValueTypeEntry(name, StringType) { setCodeGeneration(GenerateNothing); } QString jniName() const { return strings_jobject; } QString targetLangName() const { return strings_String; } QString javaPackage() const { return strings_java_lang; } virtual bool isNativeIdBased() const { return false; } }; class CharTypeEntry : public ValueTypeEntry { public: CharTypeEntry(const QString &name) : ValueTypeEntry(name, CharType) { setCodeGeneration(GenerateNothing); } QString jniName() const { return strings_jchar; } QString targetLangName() const { return strings_char; } QString javaPackage() const { return QString(); } virtual bool isNativeIdBased() const { return false; } }; class JObjectWrapperTypeEntry: public ValueTypeEntry { public: JObjectWrapperTypeEntry(const QString &name) : ValueTypeEntry(name, JObjectWrapperType) { } QString jniName() const { return strings_jobject; } QString targetLangName() const { return strings_Object; } QString javaPackage() const { return strings_java_lang; } bool isNativeIdBased() const { return false; } }; class VariantTypeEntry: public ValueTypeEntry { public: VariantTypeEntry(const QString &name) : ValueTypeEntry(name, VariantType) { } QString jniName() const { return strings_jobject; } QString targetLangName() const { return strings_Object; } QString javaPackage() const { return strings_java_lang; } virtual bool isNativeIdBased() const { return false; } }; class InterfaceTypeEntry : public ComplexTypeEntry { public: InterfaceTypeEntry(const QString &name) : ComplexTypeEntry(name, InterfaceType) { } static QString interfaceName(const QString &name) { return name + "Interface"; } ObjectTypeEntry *origin() const { return m_origin; } void setOrigin(ObjectTypeEntry *origin) { m_origin = origin; } virtual bool isNativeIdBased() const { return true; } virtual QString qualifiedCppName() const { return ComplexTypeEntry::qualifiedCppName().left(ComplexTypeEntry::qualifiedCppName().length() - interfaceName("").length()); } private: ObjectTypeEntry *m_origin; }; class ObjectTypeEntry : public ComplexTypeEntry { public: ObjectTypeEntry(const QString &name) : ComplexTypeEntry(name, ObjectType), m_interface(0) { } InterfaceTypeEntry *designatedInterface() const { return m_interface; } void setDesignatedInterface(InterfaceTypeEntry *entry) { m_interface = entry; } virtual bool isNativeIdBased() const { return true; } private: InterfaceTypeEntry *m_interface; }; class CustomTypeEntry : public ComplexTypeEntry { public: CustomTypeEntry(const QString &name) : ComplexTypeEntry(name, CustomType) { } virtual void generateCppJavaToQt(QTextStream &s, const AbstractMetaType *java_type, const QString &env_name, const QString &qt_name, const QString &java_name) const = 0; virtual void generateCppQtToJava(QTextStream &s, const AbstractMetaType *java_type, const QString &env_name, const QString &qt_name, const QString &java_name) const = 0; }; struct TypeRejection { QString class_name; QString function_name; QString field_name; QString enum_name; }; class TypeDatabase { public: TypeDatabase(); static TypeDatabase *instance(); QList extraIncludes(const QString &className); inline PrimitiveTypeEntry *findPrimitiveType(const QString &name); inline ComplexTypeEntry *findComplexType(const QString &name); inline ObjectTypeEntry *findObjectType(const QString &name); inline NamespaceTypeEntry *findNamespaceType(const QString &name); ContainerTypeEntry *findContainerType(const QString &name); TypeEntry *findType(const QString &name) const { QList entries = findTypes(name); foreach (TypeEntry *entry, entries) { if (entry != 0 && (!entry->isPrimitive() || static_cast(entry)->preferredTargetLangType())) { return entry; } } return 0; } QList findTypes(const QString &name) const { return m_entries.value(name); } TypeEntryHash allEntries() { return m_entries; } SingleTypeEntryHash entries() { TypeEntryHash entries = allEntries(); SingleTypeEntryHash returned; QList keys = entries.keys(); foreach(QString key, keys) { returned[key] = findType(key); } return returned; } PrimitiveTypeEntry *findTargetLangPrimitiveType(const QString &java_name); void addRejection(const QString &class_name, const QString &function_name, const QString &field_name, const QString &enum_name); bool isClassRejected(const QString &class_name); bool isFunctionRejected(const QString &class_name, const QString &function_name); bool isFieldRejected(const QString &class_name, const QString &field_name); bool isEnumRejected(const QString &class_name, const QString &enum_name); void addType(TypeEntry *e) { m_entries[e->qualifiedCppName()].append(e); } SingleTypeEntryHash flagsEntries() const { return m_flags_entries; } FlagsTypeEntry *findFlagsType(const QString &name) const; void addFlagsType(FlagsTypeEntry *fte) { m_flags_entries[fte->originalName()] = fte; } TemplateEntry *findTemplate(const QString &name) { return m_templates[name]; } void addTemplate(TemplateEntry *t) { m_templates[t->name()] = t; } void setSuppressWarnings(bool on) { m_suppressWarnings = on; } void addSuppressedWarning(const QString &s) { m_suppressedWarnings.append(s); } bool isSuppressedWarning(const QString &s) { if (!m_suppressWarnings) return false; foreach (const QString &_warning, m_suppressedWarnings) { QString warning(QString(_warning).replace("\\*", "&place_holder_for_asterisk;")); QStringList segs = warning.split("*", QString::SkipEmptyParts); if (segs.size() == 0) continue ; int i = 0; int pos = s.indexOf(QString(segs.at(i++)).replace("&place_holder_for_asterisk;", "*")); //qDebug() << "s == " << s << ", warning == " << segs; while (pos != -1) { if (i == segs.size()) return true; pos = s.indexOf(QString(segs.at(i++)).replace("&place_holder_for_asterisk;", "*"), pos); } } return false; } void setRebuildClasses(const QStringList &cls) { m_rebuild_classes = cls; } static QString globalNamespaceClassName(const TypeEntry *te); QString filename() const { return "typesystem.txt"; } bool parseFile(const QString &filename, bool generate = true); private: bool m_suppressWarnings; TypeEntryHash m_entries; SingleTypeEntryHash m_flags_entries; TemplateEntryHash m_templates; QStringList m_suppressedWarnings; QList m_rejections; QStringList m_rebuild_classes; }; inline PrimitiveTypeEntry *TypeDatabase::findPrimitiveType(const QString &name) { QList entries = findTypes(name); foreach (TypeEntry *entry, entries) { if (entry != 0 && entry->isPrimitive() && static_cast(entry)->preferredTargetLangType()) return static_cast(entry); } return 0; } inline ComplexTypeEntry *TypeDatabase::findComplexType(const QString &name) { TypeEntry *entry = findType(name); if (entry != 0 && entry->isComplex()) return static_cast(entry); else return 0; } inline ObjectTypeEntry *TypeDatabase::findObjectType(const QString &name) { TypeEntry *entry = findType(name); if (entry != 0 && entry->isObject()) return static_cast(entry); else return 0; } inline NamespaceTypeEntry *TypeDatabase::findNamespaceType(const QString &name) { TypeEntry *entry = findType(name); if (entry != 0 && entry->isNamespace()) return static_cast(entry); else return 0; } QString fixCppTypeName(const QString &name); #endif // TYPESYSTEM_H qtscriptgenerator-src-0.2.0/generator/typesystem_core-common.xml000066400000000000000000002140561170724227300253270ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/typesystem_core-qtscript.xml000066400000000000000000001737351170724227300257200ustar00rootroot00000000000000 QFile & %out% = *qscriptvalue_cast<QFile*>(%in%); QFile & %out% = *qscriptvalue_cast<QFile*>(%in%); QFile & %out% = *qscriptvalue_cast<QFile*>(%in%); Q_DECLARE_METATYPE(QScriptValue) QScriptValue %out%; if (!__ok) %out% = context->engine()->nullValue(); else %out% = QScriptValue(context->engine(), double(%in%)).toObject(); Q_DECLARE_METATYPE(QScriptValue) bool __result; bool & %out% = __result; bool %out% = __result; unsigned char __result; unsigned char & %out% = __result; int %out% = __result; int __result; int & %out% = __result; int %out% = __result; uint __result; uint & %out% = __result; uint %out% = __result; qint64 __result; qint64 & %out% = __result; qint64 %out% = __result; unsigned long long __result; unsigned long long & %out% = __result; unsigned long long %out% = __result; float __result; float & %out% = __result; float %out% = __result; double __result; double & %out% = __result; double %out% = __result; short __result; short & %out% = __result; short %out% = __result; unsigned short __result; unsigned short & %out% = __result; unsigned short %out% = __result; char __result; char & %out% = __result; int %out% = __result; short __result; short & %out% = __result; short %out% = __result; int __result; int & %out% = __result; int %out% = __result; unsigned short __result; unsigned short & %out% = __result; unsigned short %out% = __result; unsigned int __result; unsigned int & %out% = __result; unsigned int %out% = __result; qlonglong __result; qlonglong & %out% = __result; qlonglong %out% = __result; qulonglong __result; qulonglong & %out% = __result; qulonglong %out% = __result; float __result; float & %out% = __result; float %out% = __result; double __result; double & %out% = __result; double %out% = __result; QXmlStreamReader & %out% = *qscriptvalue_cast<QXmlStreamReader*>(%in%); qtscriptgenerator-src-0.2.0/generator/typesystem_core.xml000066400000000000000000004025131170724227300240360ustar00rootroot00000000000000 Q_DECLARE_METATYPE(QScriptValue) QScriptValue %out%; if (!__ok) %out% = context->engine()->nullValue(); else %out% = QScriptValue(context->engine(), double(%in%)).toObject(); QFile & %out% = *qscriptvalue_cast<QFile*>(%in%); QFile & %out% = *qscriptvalue_cast<QFile*>(%in%); Q_DECLARE_METATYPE(QScriptValue) QFile & %out% = *qscriptvalue_cast<QFile*>(%in%); bool __result; bool & %out% = __result; bool %out% = __result; unsigned char __result; unsigned char & %out% = __result; int %out% = __result; int __result; int & %out% = __result; int %out% = __result; uint __result; uint & %out% = __result; uint %out% = __result; qint64 __result; qint64 & %out% = __result; qint64 %out% = __result; unsigned long long __result; unsigned long long & %out% = __result; unsigned long long %out% = __result; float __result; float & %out% = __result; float %out% = __result; double __result; double & %out% = __result; double %out% = __result; short __result; short & %out% = __result; short %out% = __result; unsigned short __result; unsigned short & %out% = __result; unsigned short %out% = __result; char __result; char & %out% = __result; int %out% = __result; short __result; short & %out% = __result; short %out% = __result; int __result; int & %out% = __result; int %out% = __result; unsigned short __result; unsigned short & %out% = __result; unsigned short %out% = __result; unsigned int __result; unsigned int & %out% = __result; unsigned int %out% = __result; qlonglong __result; qlonglong & %out% = __result; qlonglong %out% = __result; qulonglong __result; qulonglong & %out% = __result; qulonglong %out% = __result; float __result; float & %out% = __result; float %out% = __result; double __result; double & %out% = __result; double %out% = __result; QXmlStreamReader & %out% = *qscriptvalue_cast<QXmlStreamReader*>(%in%); qtscriptgenerator-src-0.2.0/generator/typesystem_gui-common.xml000066400000000000000000007240431170724227300251650ustar00rootroot00000000000000 return new QTreeWidgetItemIterator(*copy); delete copy; return new QInputMethodEvent::Attribute(copy->type, copy->start, copy->length, copy->value); delete copy; return new QConicalGradient(copy->center(), copy->angle()); delete copy; return new QFontInfo(*copy); delete copy; return new QRadialGradient(copy->center(), copy->radius(), copy->focalPoint()); delete copy; return new QColormap(*copy); delete copy; return new QFontMetricsF(*copy); delete copy; return new QFontMetrics(*copy); delete copy; Q_UNUSED(copy) qWarning("Copying empty QGradient object"); return new QGradient(); delete copy; QLinearGradient *lg = new QLinearGradient(copy->start(), copy->finalStop()); lg->setSpread(copy->spread()); lg->setStops(copy->stops()); return (void *) lg; delete copy; if (%1 != null) disableGarbageCollection(); if (%1 != null) disableGarbageCollection(); if (%2 != null) disableGarbageCollection(); > qtscriptgenerator-src-0.2.0/generator/typesystem_gui-qtscript.xml000066400000000000000000000600661170724227300255440ustar00rootroot00000000000000 if ((context->argumentCount() == 1) && (qMetaTypeId<QTextFormat>() == context->argument(0).toVariant().userType())) { QTextFormat _q_arg0 = qscriptvalue_cast<QTextFormat>(context->argument(0)); QTextFormat _q_cpp_result(_q_arg0); QScriptValue _q_result = context->engine()->newVariant(context->thisObject(), qVariantFromValue(_q_cpp_result)); return _q_result; } QGradient & %out% = *qscriptvalue_cast<QGradient*>(%in%); QScriptValue %out%_orig = %in%; QWidget* %out% = qscriptvalue_cast<QWidget*>(%out%_orig); if (%out% != 0) context->engine()->newQObject(%out%_orig, %out%, QScriptEngine::QtOwnership); QFontInfo & %out% = *qscriptvalue_cast<QFontInfo*>(%in%); Q_DECLARE_METATYPE(QScriptValue) Q_DECLARE_METATYPE(QScriptValue) QModelIndex moveCursor(QAbstractItemView::CursorAction, Qt::KeyboardModifiers) { return QModelIndex(); } qtscriptgenerator-src-0.2.0/generator/typesystem_gui.xml000066400000000000000000007773071170724227300237120ustar00rootroot00000000000000 if ((context->argumentCount() == 1) && (qMetaTypeId<QTextFormat>() == context->argument(0).toVariant().userType())) { QTextFormat _q_arg0 = qscriptvalue_cast<QTextFormat>(context->argument(0)); QTextFormat _q_cpp_result(_q_arg0); QScriptValue _q_result = context->engine()->newVariant(context->thisObject(), qVariantFromValue(_q_cpp_result)); return _q_result; } return new QTreeWidgetItemIterator(*copy); delete copy; return new QInputMethodEvent::Attribute(copy->type, copy->start, copy->length, copy->value); delete copy; return new QConicalGradient(copy->center(), copy->angle()); delete copy; return new QFontInfo(*copy); delete copy; QFontInfo & %out% = *qscriptvalue_cast<QFontInfo*>(%in%); return new QRadialGradient(copy->center(), copy->radius(), copy->focalPoint()); delete copy; return new QColormap(*copy); delete copy; QGradient & %out% = *qscriptvalue_cast<QGradient*>(%in%); return new QFontMetricsF(*copy); delete copy; return new QFontMetrics(*copy); delete copy; Q_UNUSED(copy) qWarning("Copying empty QGradient object"); return new QGradient(); delete copy; QLinearGradient *lg = new QLinearGradient(copy->start(), copy->finalStop()); lg->setSpread(copy->spread()); lg->setStops(copy->stops()); return (void *) lg; delete copy; if (%1 != null) disableGarbageCollection(); QModelIndex moveCursor(QAbstractItemView::CursorAction, Qt::KeyboardModifiers) { return QModelIndex(); } Q_DECLARE_METATYPE(QScriptValue) Q_DECLARE_METATYPE(QScriptValue) QScriptValue %out%_orig = %in%; QWidget* %out% = qscriptvalue_cast<QWidget*>(%out%_orig); if (%out% != 0) context->engine()->newQObject(%out%_orig, %out%, QScriptEngine::QtOwnership); if (%1 != null) disableGarbageCollection(); if (%2 != null) disableGarbageCollection(); > qtscriptgenerator-src-0.2.0/generator/typesystem_network-common.xml000066400000000000000000000232031170724227300260600ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/typesystem_network-qtscript.xml000066400000000000000000000045521170724227300264470ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/typesystem_network.xml000066400000000000000000000270721170724227300246020ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/typesystem_opengl-common.xml000066400000000000000000000132101170724227300256500ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/typesystem_opengl-qtscript.xml000066400000000000000000000004421170724227300262340ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/typesystem_opengl.xml000066400000000000000000000134201170724227300243650ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/typesystem_phonon-common.xml000066400000000000000000000426521170724227300257010ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/typesystem_phonon-qtscript.xml000066400000000000000000000063251170724227300262570ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/typesystem_phonon.xml000066400000000000000000000475631170724227300244210ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/typesystem_sql-common.xml000066400000000000000000000123441170724227300251720ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/typesystem_sql-qtscript.xml000066400000000000000000000005071170724227300255510ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/typesystem_sql.xml000066400000000000000000000127141170724227300237050ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/typesystem_svg-common.xml000066400000000000000000000030071170724227300251660ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/typesystem_svg-qtscript.xml000066400000000000000000000001741170724227300255510ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/typesystem_svg.xml000066400000000000000000000031251170724227300237010ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/typesystem_uitools.xml000066400000000000000000000001441170724227300245760ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/typesystem_webkit-common.xml000066400000000000000000000277501170724227300256670ustar00rootroot00000000000000 return new QWebHistoryItem(*copy); delete copy; qtscriptgenerator-src-0.2.0/generator/typesystem_webkit-qtscript.xml000066400000000000000000000007071170724227300262410ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/typesystem_webkit.xml000066400000000000000000000302731170724227300243730ustar00rootroot00000000000000 return new QWebHistoryItem(*copy); delete copy; qtscriptgenerator-src-0.2.0/generator/typesystem_xml-common.xml000066400000000000000000000322131170724227300251700ustar00rootroot00000000000000 QXmlNamespaceSupport *clone = new QXmlNamespaceSupport; clone->setPrefix("", copy->uri("")); QStringList prefixes = copy->prefixes(); for (int i=0; i<prefixes.size(); ++i) clone->setPrefix(prefixes.at(i), copy->uri(prefixes.at(i))); return clone; delete (QXmlNamespaceSupport *)copy; qtscriptgenerator-src-0.2.0/generator/typesystem_xml-qtscript.xml000066400000000000000000000027541170724227300255600ustar00rootroot00000000000000 QTextStream & %out% = *qscriptvalue_cast<QTextStream*>(%in%); QTextStream & %out% = *qscriptvalue_cast<QTextStream*>(%in%); qtscriptgenerator-src-0.2.0/generator/typesystem_xml.xml000066400000000000000000000345571170724227300237170ustar00rootroot00000000000000 QTextStream & %out% = *qscriptvalue_cast<QTextStream*>(%in%); QTextStream & %out% = *qscriptvalue_cast<QTextStream*>(%in%); QXmlNamespaceSupport *clone = new QXmlNamespaceSupport; clone->setPrefix("", copy->uri("")); QStringList prefixes = copy->prefixes(); for (int i=0; i<prefixes.size(); ++i) clone->setPrefix(prefixes.at(i), copy->uri(prefixes.at(i))); return clone; delete (QXmlNamespaceSupport *)copy; qtscriptgenerator-src-0.2.0/generator/typesystem_xmlpatterns-common.xml000066400000000000000000000274651170724227300267660ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/typesystem_xmlpatterns-qtscript.xml000066400000000000000000000005121170724227300273270ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/generator/typesystem_xmlpatterns.xml000066400000000000000000000277331170724227300254760ustar00rootroot00000000000000 qtscriptgenerator-src-0.2.0/qtbindings/000077500000000000000000000000001170724227300202255ustar00rootroot00000000000000qtscriptgenerator-src-0.2.0/qtbindings/qs_eval/000077500000000000000000000000001170724227300216575ustar00rootroot00000000000000qtscriptgenerator-src-0.2.0/qtbindings/qs_eval/main.cpp000066400000000000000000000174171170724227300233210ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #if QT_VERSION >= 0x040500 #include #endif #include #include #include #include #include static bool wantsToQuit; static QScriptValue qtscript_quit(QScriptContext *ctx, QScriptEngine *eng) { Q_UNUSED(ctx); wantsToQuit = true; return eng->undefinedValue(); } static QScriptValue qtscript_describe(QScriptContext *ctx, QScriptEngine *eng) { QStringList result; QScriptValue obj = ctx->argument(0); while (obj.isObject()) { QScriptValueIterator it(obj); while (it.hasNext()) { it.next(); result.append(it.name()); } obj = obj.prototype(); } return eng->toScriptValue(result); } static void interactive(QScriptEngine *eng) { QScriptValue global = eng->globalObject(); QScriptValue quitFunction = eng->newFunction(qtscript_quit); if (!global.property(QLatin1String("exit")).isValid()) global.setProperty(QLatin1String("exit"), quitFunction); if (!global.property(QLatin1String("quit")).isValid()) global.setProperty(QLatin1String("quit"), quitFunction); wantsToQuit = false; global.setProperty(QLatin1String("describe"), eng->newFunction(qtscript_describe)); QTextStream qin(stdin, QFile::ReadOnly); const char *qscript_prompt = "qs> "; const char *dot_prompt = ".... "; const char *prompt = qscript_prompt; QString code; forever { QString line; printf("%s", prompt); fflush(stdout); line = qin.readLine(); if (line.isNull()) break; code += line; code += QLatin1Char('\n'); if (line.trimmed().isEmpty()) { continue; } else if (! eng->canEvaluate(code)) { prompt = dot_prompt; } else { QScriptValue result = eng->evaluate(code, QLatin1String("typein")); code.clear(); prompt = qscript_prompt; if (! result.isUndefined()) fprintf(stderr, "%s\n", qPrintable(result.toString())); if (wantsToQuit) break; } } } static QScriptValue importExtension(QScriptContext *context, QScriptEngine *engine) { return engine->importExtension(context->argument(0).toString()); } int main(int argc, char *argv[]) { QApplication *app; if (argc >= 2 && !qstrcmp(argv[1], "-tty")) app = new QApplication(argc, argv, QApplication::Tty); else app = new QApplication(argc, argv); QDir dir(QApplication::applicationDirPath()); if (dir.dirName() == QLatin1String("debug") || dir.dirName() == QLatin1String("release")) dir.cdUp(); dir.cdUp(); dir.cdUp(); if (!dir.cd("plugins")) { fprintf(stderr, "plugins folder does not exist -- did you build the bindings?\n"); return(-1); } QStringList paths = app->libraryPaths(); paths << dir.absolutePath(); app->setLibraryPaths(paths); QScriptEngine *eng = new QScriptEngine(); QStringList extensions; extensions << "qt.core" << "qt.gui" << "qt.xml" << "qt.svg" << "qt.network" << "qt.sql" << "qt.opengl" << "qt.webkit" << "qt.xmlpatterns" << "qt.uitools"; QStringList failExtensions; foreach (const QString &ext, extensions) { QScriptValue ret = eng->importExtension(ext); if (ret.isError()) failExtensions.append(ext); } if (!failExtensions.isEmpty()) { if (failExtensions.size() == extensions.size()) { qWarning("Failed to import Qt bindings!\n" "Plugins directory searched: %s/script\n" "Make sure that the bindings have been built, " "and that this executable and the plugins are " "using compatible Qt libraries.", qPrintable(dir.absolutePath())); } else { qWarning("Failed to import some Qt bindings: %s\n" "Plugins directory searched: %s/script\n" "Make sure that the bindings have been built, " "and that this executable and the plugins are " "using compatible Qt libraries.", qPrintable(failExtensions.join(", ")), qPrintable(dir.absolutePath())); } } #if QT_VERSION >= 0x040500 QScriptEngineDebugger *dbg = new QScriptEngineDebugger(); dbg->attachTo(eng); #endif QScriptValue globalObject = eng->globalObject(); globalObject.setProperty("qApp", eng->newQObject(app)); { QScriptValue qscript = eng->newObject(); qscript.setProperty("importExtension", eng->newFunction(importExtension)); globalObject.property("qt").setProperty("script", qscript); } if (! *++argv) { interactive(eng); return EXIT_SUCCESS; } while (const char *arg = *argv++) { QString fn = QString::fromLocal8Bit(arg); if (fn == QLatin1String("-i")) { interactive(eng); break; } QString contents; int lineNumber = 1; if (fn == QLatin1String("-")) { QTextStream stream(stdin, QFile::ReadOnly); contents = stream.readAll(); } else { QFile file(fn); if (file.open(QFile::ReadOnly)) { QTextStream stream(&file); contents = stream.readAll(); file.close(); // strip off #!/usr/bin/env qscript line if (contents.startsWith("#!")) { contents.remove(0, contents.indexOf("\n")); ++lineNumber; } } } if (contents.isEmpty()) continue; QScriptValue r = eng->evaluate(contents, fn, lineNumber); if (eng->hasUncaughtException()) { QStringList backtrace = eng->uncaughtExceptionBacktrace(); fprintf (stderr, " %s\n%s\n\n", qPrintable(r.toString()), qPrintable(backtrace.join("\n"))); return EXIT_FAILURE; } } delete eng; #if QT_VERSION >= 0x040500 delete dbg; #endif delete app; return EXIT_SUCCESS; } qtscriptgenerator-src-0.2.0/qtbindings/qs_eval/qs_eval.pro000066400000000000000000000002601170724227300240310ustar00rootroot00000000000000QT = core gui script win32: CONFIG += console mac:CONFIG -= app_bundle SOURCES += main.cpp TOO_OLD_LIST=$$find(QT_VERSION, ^4\.[0-4]) count(TOO_OLD_LIST, 0): QT += scripttools qtscriptgenerator-src-0.2.0/qtbindings/qtbindings.pro000066400000000000000000000004051170724227300231100ustar00rootroot00000000000000TEMPLATE = subdirs SUBDIRS = qtscript_core \ qtscript_gui \ qtscript_network \ qtscript_opengl \ qtscript_sql \ qtscript_svg \ qtscript_xml \ qtscript_phonon \ qtscript_webkit \ qtscript_xmlpatterns \ qtscript_uitools \ qs_eval qtscriptgenerator-src-0.2.0/qtbindings/qtbindingsbase.pri000066400000000000000000000003041170724227300237330ustar00rootroot00000000000000TEMPLATE = lib DEPENDPATH += . INCLUDEPATH += . DESTDIR = $$PWD/../plugins/script QT += script CONFIG += debug_and_release GENERATEDCPP = $$PWD/../generated_cpp TARGET=$$qtLibraryTarget($$TARGET) qtscriptgenerator-src-0.2.0/qtbindings/qtscript_core/000077500000000000000000000000001170724227300231065ustar00rootroot00000000000000qtscriptgenerator-src-0.2.0/qtbindings/qtscript_core/qtscript_core.pro000066400000000000000000000002711170724227300265110ustar00rootroot00000000000000TARGET = qtscript_core include(../qtbindingsbase.pri) SOURCES += $$GENERATEDCPP/com_trolltech_qt_core/plugin.cpp include($$GENERATEDCPP/com_trolltech_qt_core/com_trolltech_qt_core.pri) qtscriptgenerator-src-0.2.0/qtbindings/qtscript_core/qtscriptconcurrent.h000066400000000000000000000041701170724227300272350ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef QTSCRIPTCONCURRENT_H #define QTSCRIPTCONCURRENT_H #ifndef QT_NO_CONCURRENT #include #include #include #include typedef QFutureWatcher QtScriptVoidFutureWatcher; typedef QFuture QtScriptVoidFuture; typedef QFutureSynchronizer QtScriptVoidFutureSynchronizer; typedef QFuture QtScriptFuture; typedef QFutureWatcher QtScriptFutureWatcher; typedef QFutureSynchronizer QtScriptFutureSynchronizer; typedef QFutureIterator QtScriptFutureIterator; #endif // QT_NO_CONCURRENT #endif qtscriptgenerator-src-0.2.0/qtbindings/qtscript_gui/000077500000000000000000000000001170724227300227425ustar00rootroot00000000000000qtscriptgenerator-src-0.2.0/qtbindings/qtscript_gui/qtscript_gui.pro000066400000000000000000000002651170724227300262040ustar00rootroot00000000000000TARGET = qtscript_gui include(../qtbindingsbase.pri) SOURCES += $$GENERATEDCPP/com_trolltech_qt_gui/plugin.cpp include($$GENERATEDCPP/com_trolltech_qt_gui/com_trolltech_qt_gui.pri) qtscriptgenerator-src-0.2.0/qtbindings/qtscript_network/000077500000000000000000000000001170724227300236475ustar00rootroot00000000000000qtscriptgenerator-src-0.2.0/qtbindings/qtscript_network/qtscript_network.pro000066400000000000000000000003351170724227300300140ustar00rootroot00000000000000TARGET = qtscript_network include(../qtbindingsbase.pri) QT -= gui QT += network SOURCES += $$GENERATEDCPP/com_trolltech_qt_network/plugin.cpp include($$GENERATEDCPP/com_trolltech_qt_network/com_trolltech_qt_network.pri) qtscriptgenerator-src-0.2.0/qtbindings/qtscript_opengl/000077500000000000000000000000001170724227300234425ustar00rootroot00000000000000qtscriptgenerator-src-0.2.0/qtbindings/qtscript_opengl/qtscript_opengl.pro000066400000000000000000000003161170724227300274010ustar00rootroot00000000000000TARGET = qtscript_opengl include(../qtbindingsbase.pri) QT += opengl SOURCES += $$GENERATEDCPP/com_trolltech_qt_opengl/plugin.cpp include($$GENERATEDCPP/com_trolltech_qt_opengl/com_trolltech_qt_opengl.pri) qtscriptgenerator-src-0.2.0/qtbindings/qtscript_phonon/000077500000000000000000000000001170724227300234575ustar00rootroot00000000000000qtscriptgenerator-src-0.2.0/qtbindings/qtscript_phonon/qtscript_phonon.pro000066400000000000000000000003161170724227300274330ustar00rootroot00000000000000TARGET = qtscript_phonon include(../qtbindingsbase.pri) QT += phonon SOURCES += $$GENERATEDCPP/com_trolltech_qt_phonon/plugin.cpp include($$GENERATEDCPP/com_trolltech_qt_phonon/com_trolltech_qt_phonon.pri) qtscriptgenerator-src-0.2.0/qtbindings/qtscript_sql/000077500000000000000000000000001170724227300227555ustar00rootroot00000000000000qtscriptgenerator-src-0.2.0/qtbindings/qtscript_sql/qtscript_sql.pro000066400000000000000000000003111170724227300262220ustar00rootroot00000000000000TARGET = qtscript_sql include(../qtbindingsbase.pri) QT -= gui QT += sql SOURCES += $$GENERATEDCPP/com_trolltech_qt_sql/plugin.cpp include($$GENERATEDCPP/com_trolltech_qt_sql/com_trolltech_qt_sql.pri) qtscriptgenerator-src-0.2.0/qtbindings/qtscript_svg/000077500000000000000000000000001170724227300227555ustar00rootroot00000000000000qtscriptgenerator-src-0.2.0/qtbindings/qtscript_svg/qtscript_svg.pro000066400000000000000000000002771170724227300262350ustar00rootroot00000000000000TARGET = qtscript_svg include(../qtbindingsbase.pri) QT += svg SOURCES += $$GENERATEDCPP/com_trolltech_qt_svg/plugin.cpp include($$GENERATEDCPP/com_trolltech_qt_svg/com_trolltech_qt_svg.pri) qtscriptgenerator-src-0.2.0/qtbindings/qtscript_uitools/000077500000000000000000000000001170724227300236545ustar00rootroot00000000000000qtscriptgenerator-src-0.2.0/qtbindings/qtscript_uitools/qtscript_uitools.pro000066400000000000000000000003271170724227300300270ustar00rootroot00000000000000TARGET = qtscript_uitools include(../qtbindingsbase.pri) CONFIG += uitools SOURCES += $$GENERATEDCPP/com_trolltech_qt_uitools/plugin.cpp include($$GENERATEDCPP/com_trolltech_qt_uitools/com_trolltech_qt_uitools.pri) qtscriptgenerator-src-0.2.0/qtbindings/qtscript_webkit/000077500000000000000000000000001170724227300234435ustar00rootroot00000000000000qtscriptgenerator-src-0.2.0/qtbindings/qtscript_webkit/qtscript_webkit.pro000066400000000000000000000003261170724227300274040ustar00rootroot00000000000000TARGET = qtscript_webkit include(../qtbindingsbase.pri) QT += network webkit SOURCES += $$GENERATEDCPP/com_trolltech_qt_webkit/plugin.cpp include($$GENERATEDCPP/com_trolltech_qt_webkit/com_trolltech_qt_webkit.pri) qtscriptgenerator-src-0.2.0/qtbindings/qtscript_xml/000077500000000000000000000000001170724227300227565ustar00rootroot00000000000000qtscriptgenerator-src-0.2.0/qtbindings/qtscript_xml/qtscript_xml.pro000066400000000000000000000003111170724227300262240ustar00rootroot00000000000000TARGET = qtscript_xml include(../qtbindingsbase.pri) QT -= gui QT += xml SOURCES += $$GENERATEDCPP/com_trolltech_qt_xml/plugin.cpp include($$GENERATEDCPP/com_trolltech_qt_xml/com_trolltech_qt_xml.pri) qtscriptgenerator-src-0.2.0/qtbindings/qtscript_xmlpatterns/000077500000000000000000000000001170724227300245375ustar00rootroot00000000000000qtscriptgenerator-src-0.2.0/qtbindings/qtscript_xmlpatterns/qtscript_xmlpatterns.pro000066400000000000000000000003711170724227300315740ustar00rootroot00000000000000TARGET = qtscript_xmlpatterns include(../qtbindingsbase.pri) QT -= gui QT += xmlpatterns network SOURCES += $$GENERATEDCPP/com_trolltech_qt_xmlpatterns/plugin.cpp include($$GENERATEDCPP/com_trolltech_qt_xmlpatterns/com_trolltech_qt_xmlpatterns.pri) qtscriptgenerator-src-0.2.0/tools/000077500000000000000000000000001170724227300172235ustar00rootroot00000000000000qtscriptgenerator-src-0.2.0/tools/qsexec/000077500000000000000000000000001170724227300205135ustar00rootroot00000000000000qtscriptgenerator-src-0.2.0/tools/qsexec/README.TXT000066400000000000000000000030511170724227300220500ustar00rootroot00000000000000Runs QtScript code from the command line. USAGE ----- qsexec Runs QtScript in interactive mode, i.e. presents a prompt and executes commands as given. qsexec FILE [ARGS ...] Runs the script in FILE with the given command line arguments (see SCRIPT EXTENSIONS below). qsexec -f FILE1 [FILE2 ...] Runs all the scripts FILE1 FILE2 ... consecutively sharing the same engine. SCRIPT EXTENSIONS ----------------- The qsexec tool adds some useful functionality to the global object: - qs.system.os A string that specifies the operating system the script is run on (e.g. "linux", "windows", "mac"). - qs.script.args Array containing the strings given as [args ...] on the command line (single file mode only). - qs.script.absoluteFilePath File system path (including the file name) of the script that is processed at the moment as a string. - qs.script.absolutePath File system path (excluding the file name) of the script that is processed at the moment as a string. - qs.script.importExtension(name) Lets the script resolve and load the script extension with the given name. - qs.script.include(fileName) Dynamically loads and executes the script in the given file (relative to the currently processed file or absolute). Multiple includes of the same file result in only one execution of the file (only the first include triggers the execution). NOTE ---- The qsexec tool doesn't import any script extensions (like qt.core) itself. A script that needs a script extension has to load it via qs.script.importExtension("myextension"); qtscriptgenerator-src-0.2.0/tools/qsexec/src/000077500000000000000000000000001170724227300213025ustar00rootroot00000000000000qtscriptgenerator-src-0.2.0/tools/qsexec/src/main.cpp000066400000000000000000000214741170724227300227420ustar00rootroot00000000000000/**************************************************************************** ** ** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the Qt Script Generator project on Qt Labs. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include #include #include #include #include namespace { void printUsage() { QFile info(QCoreApplication::applicationDirPath()+"/README.TXT"); if (!info.exists() || !info.open(QFile::ReadOnly)) { qDebug() << "Can't read README.TXT"; } else { QTextStream stream(&info); qDebug() << stream.readAll(); info.close(); } } bool loadFile(QString fileName, QScriptEngine *engine) { // avoid loading files more than once static QSet loadedFiles; QFileInfo fileInfo(fileName); QString absoluteFileName = fileInfo.absoluteFilePath(); QString absolutePath = fileInfo.absolutePath(); QString canonicalFileName = fileInfo.canonicalFilePath(); if (loadedFiles.contains(canonicalFileName)) { return true; } loadedFiles.insert(canonicalFileName); QString path = fileInfo.path(); // load the file QFile file(fileName); if (file.open(QFile::ReadOnly)) { QTextStream stream(&file); QString contents = stream.readAll(); file.close(); int endlineIndex = contents.indexOf('\n'); QString line = contents.left(endlineIndex); int lineNumber = 1; // strip off #!/usr/bin/env qscript line if (line.startsWith("#!")) { contents.remove(0, endlineIndex+1); ++lineNumber; } // set qt.script.absoluteFilePath QScriptValue script = engine->globalObject().property("qs").property("script"); QScriptValue oldFilePathValue = script.property("absoluteFilePath"); QScriptValue oldPathValue = script.property("absolutePath"); script.setProperty("absoluteFilePath", engine->toScriptValue(absoluteFileName)); script.setProperty("absolutePath", engine->toScriptValue(absolutePath)); QScriptValue r = engine->evaluate(contents, fileName, lineNumber); if (engine->hasUncaughtException()) { QStringList backtrace = engine->uncaughtExceptionBacktrace(); qDebug() << QString(" %1\n%2\n\n").arg(r.toString()).arg(backtrace.join("\n")); return true; } script.setProperty("absoluteFilePath", oldFilePathValue); // if we come from includeScript(), or whereever script.setProperty("absolutePath", oldPathValue); // if we come from includeScript(), or whereever } else { return false; } return true; } QScriptValue includeScript(QScriptContext *context, QScriptEngine *engine) { QString currentFileName = engine->globalObject().property("qs").property("script").property("absoluteFilePath").toString(); QFileInfo currentFileInfo(currentFileName); QString path = currentFileInfo.path(); QString importFile = context->argument(0).toString(); QFileInfo importInfo(importFile); if (importInfo.isRelative()) { importFile = path + "/" + importInfo.filePath(); } if (!loadFile(importFile, engine)) { return context->throwError(QString("Failed to resolve include: %1").arg(importFile)); } return engine->toScriptValue(true); } QScriptValue importExtension(QScriptContext *context, QScriptEngine *engine) { return engine->importExtension(context->argument(0).toString()); } bool stopInteractiveMode; QScriptValue exitInteractiveMode(QScriptContext *context, QScriptEngine *engine) { Q_UNUSED(context); stopInteractiveMode = true; return engine->undefinedValue(); } void interactiveMode(QScriptEngine *engine) { engine->globalObject().setProperty("quit", engine->newFunction(exitInteractiveMode)); qDebug() << "Running in interactive mode. Press Ctrl+C or call quit() to stop."; QTextStream input(stdin, QFile::ReadOnly); const char *qtScriptPrompt = "qs> "; const char *dotPrompt = ".... "; const char *prompt = qtScriptPrompt; QString code; stopInteractiveMode = false; while (!stopInteractiveMode) { QString line; printf("%s", prompt); fflush(stdout); line = input.readLine(); if (line.isNull()) break; code += line; code += QLatin1Char('\n'); if (line.trimmed().isEmpty()) { continue; } else if (!engine->canEvaluate(code)) { prompt = dotPrompt; } else { QScriptValue result = engine->evaluate(code, QLatin1String("stdin")); code.clear(); prompt = qtScriptPrompt; if (!result.isUndefined()) fprintf(stderr, "%s\n", qPrintable(result.toString())); } } } } // namespace int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); QStringList paths = QStringList() << QCoreApplication::applicationDirPath() + "/../../plugins"; app.setLibraryPaths(paths); QScriptEngine *engine = new QScriptEngine(); QScriptValue global = engine->globalObject(); // add the qt object global.setProperty("qs", engine->newObject()); // add a 'script' object QScriptValue script = engine->newObject(); global.property("qs").setProperty("script", script); // add a 'system' object QScriptValue system = engine->newObject(); global.property("qs").setProperty("system", system); // add os information to qt.system.os #ifdef Q_OS_WIN32 QScriptValue osName = engine->toScriptValue(QString("windows")); #elif defined(Q_OS_LINUX) QScriptValue osName = engine->toScriptValue(QString("linux")); #elif defined(Q_OS_MAC) QScriptValue osName = engine->toScriptValue(QString("mac")); #elif defined(Q_OS_UNIX) QScriptValue osName = engine->toScriptValue(QString("unix")); #endif system.setProperty("os", osName); // add environment variables to qt.system.env QMap envMap; QStringList envList = QProcess::systemEnvironment(); foreach (const QString &entry, envList) { QStringList keyVal = entry.split('='); if (keyVal.size() == 1) envMap.insert(keyVal.at(0), QString()); else envMap.insert(keyVal.at(0), keyVal.at(1)); } system.setProperty("env", engine->toScriptValue(envMap)); // add the include functionality to qt.script.include script.setProperty("include", engine->newFunction(includeScript)); // add the importExtension functionality to qt.script.importExtension script.setProperty("importExtension", engine->newFunction(importExtension)); QStringList args = QCoreApplication::arguments(); args.takeFirst(); if (args.isEmpty()) { interactiveMode(engine); } else if (args.size() == 1 && (args.at(0) == "-help" || args.at(0) == "--help" || args.at(0) == "-h" || args.at(0) == "/h")) { printUsage(); } else { // read script file and execute QStringList files; bool singlefile = (args.at(0) != "-f"); if (singlefile) { files << args.takeFirst(); // add arguments to qt.script.arguments script.setProperty("args", engine->toScriptValue(args)); } else { args.takeFirst(); files += args; } foreach (const QString &fileName, files) { if (!loadFile(fileName, engine)) { qDebug() << "Failed:" << fileName; return EXIT_FAILURE; } } } delete engine; return EXIT_SUCCESS; } qtscriptgenerator-src-0.2.0/tools/qsexec/src/qsexec.pro000066400000000000000000000002031170724227300233070ustar00rootroot00000000000000TEMPLATE = app TARGET = qsexec DESTDIR = ../ QT = core script win32:CONFIG+=console mac:CONFIG-=app_bundle SOURCES += main.cpp