summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2011-11-22 02:59:34 -0600
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2011-11-22 02:59:34 -0600
commit6c4cc3653e8dd7668295f3e659b7eb4dc571b67c (patch)
treea559fd71fc982e35a4f984d85a5c9d92b764ae8c
downloadsip4-tqt-6c4cc365.tar.gz
sip4-tqt-6c4cc365.zip
Initial import of SIP4 for Qt3
-rw-r--r--LICENSE48
-rw-r--r--LICENSE-GPL2344
-rw-r--r--LICENSE-GPL3678
-rw-r--r--NEWS363
-rw-r--r--README33
-rw-r--r--configure.py471
-rw-r--r--custom/custom.c60
-rw-r--r--custom/customw.c64
-rw-r--r--custom/mkcustom.py87
-rw-r--r--doc/html/_sources/annotations.txt805
-rw-r--r--doc/html/_sources/build_system.txt843
-rw-r--r--doc/html/_sources/builtin.txt50
-rw-r--r--doc/html/_sources/c_api.txt1721
-rw-r--r--doc/html/_sources/command_line.txt137
-rw-r--r--doc/html/_sources/directives.txt2109
-rw-r--r--doc/html/_sources/distutils.txt41
-rw-r--r--doc/html/_sources/embedding.txt62
-rw-r--r--doc/html/_sources/incompatibilities.txt198
-rw-r--r--doc/html/_sources/index.txt20
-rw-r--r--doc/html/_sources/installation.txt169
-rw-r--r--doc/html/_sources/introduction.txt169
-rw-r--r--doc/html/_sources/python_api.txt282
-rw-r--r--doc/html/_sources/specification_files.txt499
-rw-r--r--doc/html/_sources/using.txt662
-rw-r--r--doc/html/_static/basic.css417
-rw-r--r--doc/html/_static/default.css218
-rw-r--r--doc/html/_static/doctools.js232
-rw-r--r--doc/html/_static/file.pngbin0 -> 392 bytes
-rw-r--r--doc/html/_static/jquery.js4376
-rw-r--r--doc/html/_static/minus.pngbin0 -> 199 bytes
-rw-r--r--doc/html/_static/plus.pngbin0 -> 199 bytes
-rw-r--r--doc/html/_static/pygments.css61
-rw-r--r--doc/html/_static/searchtools.js467
-rw-r--r--doc/html/annotations.html901
-rw-r--r--doc/html/build_system.html1182
-rw-r--r--doc/html/builtin.html138
-rw-r--r--doc/html/c_api.html2166
-rw-r--r--doc/html/command_line.html259
-rw-r--r--doc/html/directives.html2045
-rw-r--r--doc/html/distutils.html141
-rw-r--r--doc/html/embedding.html162
-rw-r--r--doc/html/genindex.html784
-rw-r--r--doc/html/incompatibilities.html281
-rw-r--r--doc/html/index.html167
-rw-r--r--doc/html/installation.html277
-rw-r--r--doc/html/introduction.html239
-rw-r--r--doc/html/modindex.html107
-rw-r--r--doc/html/objects.inv214
-rw-r--r--doc/html/python_api.html528
-rw-r--r--doc/html/search.html97
-rw-r--r--doc/html/searchindex.js1
-rw-r--r--doc/html/specification_files.html612
-rw-r--r--doc/html/using.html731
-rw-r--r--sipdistutils.py148
-rw-r--r--sipgen/export.c1136
-rw-r--r--sipgen/gencode.c13733
-rw-r--r--sipgen/heap.c131
-rw-r--r--sipgen/lexer.c3500
-rw-r--r--sipgen/lexer.l628
-rw-r--r--sipgen/main.c515
-rw-r--r--sipgen/parser.c9975
-rw-r--r--sipgen/parser.h309
-rw-r--r--sipgen/parser.y6385
-rw-r--r--sipgen/sip.h1180
-rw-r--r--sipgen/sipgen.sbf19
-rw-r--r--sipgen/transform.c3445
-rw-r--r--siplib/apiversions.c295
-rw-r--r--siplib/bool.cpp22
-rw-r--r--siplib/descriptors.c305
-rw-r--r--siplib/objmap.c282
-rw-r--r--siplib/qtlib.c659
-rw-r--r--siplib/sip.h1587
-rw-r--r--siplib/sipint.h149
-rw-r--r--siplib/siplib.c10501
-rw-r--r--siplib/siplib.sbf19
-rw-r--r--siplib/threads.c226
-rw-r--r--siplib/voidptr.c579
-rw-r--r--siputils.py2525
-rw-r--r--siputils.py.orig2528
-rw-r--r--specs/aix-g++79
-rw-r--r--specs/aix-g++-6479
-rw-r--r--specs/aix-xlc82
-rw-r--r--specs/aix-xlc-6484
-rw-r--r--specs/bsdi-g++84
-rw-r--r--specs/cygwin-g++86
-rw-r--r--specs/darwin-g++89
-rw-r--r--specs/dgux-g++77
-rw-r--r--specs/freebsd-g++80
-rw-r--r--specs/freebsd-g++3480
-rw-r--r--specs/freebsd-g++4080
-rw-r--r--specs/freebsd-icc105
-rw-r--r--specs/hpux-acc103
-rw-r--r--specs/hpux-acc-64124
-rw-r--r--specs/hpux-acc-o64123
-rw-r--r--specs/hpux-cc100
-rw-r--r--specs/hpux-g++85
-rw-r--r--specs/hpux-g++-6485
-rw-r--r--specs/hpuxi-acc122
-rw-r--r--specs/hpuxi-acc-64122
-rw-r--r--specs/hurd-g++77
-rw-r--r--specs/irix-cc113
-rw-r--r--specs/irix-cc-64113
-rw-r--r--specs/irix-cc-o3289
-rw-r--r--specs/irix-g++84
-rw-r--r--specs/irix-g++-6484
-rw-r--r--specs/linux-arm-g++90
-rw-r--r--specs/linux-arm-thumb-g++90
-rw-r--r--specs/linux-armv6-g++90
-rw-r--r--specs/linux-cxx78
-rw-r--r--specs/linux-ecc-6484
-rw-r--r--specs/linux-g++90
-rw-r--r--specs/linux-g++-3290
-rw-r--r--specs/linux-g++-6493
-rw-r--r--specs/linux-icc94
-rw-r--r--specs/linux-kcc93
-rw-r--r--specs/linux-kylix82
-rw-r--r--specs/linux-lsb90
-rw-r--r--specs/linux-pgcc82
-rw-r--r--specs/lynxos-g++85
-rw-r--r--specs/macx-g++97
-rw-r--r--specs/macx-mwerks25
-rw-r--r--specs/macx-pbuilder83
-rwxr-xr-xspecs/macx-xcode83
-rw-r--r--specs/macx-xlc94
-rw-r--r--specs/netbsd-g++80
-rw-r--r--specs/openbsd-g++81
-rw-r--r--specs/qnx-g++81
-rw-r--r--specs/reliant-cds85
-rw-r--r--specs/reliant-cds-6485
-rw-r--r--specs/sco-cc78
-rw-r--r--specs/sco-g++77
-rw-r--r--specs/solaris-cc85
-rw-r--r--specs/solaris-cc-64102
-rw-r--r--specs/solaris-g++87
-rw-r--r--specs/solaris-g++-64104
-rw-r--r--specs/tru64-cxx79
-rw-r--r--specs/tru64-g++79
-rw-r--r--specs/unixware-cc84
-rw-r--r--specs/unixware-g++81
-rw-r--r--specs/win32-borland90
-rw-r--r--specs/win32-g++102
-rw-r--r--specs/win32-icc87
-rw-r--r--specs/win32-msvc86
-rw-r--r--specs/win32-msvc.net88
-rw-r--r--specs/win32-msvc200588
-rw-r--r--specs/win32-msvc200888
-rw-r--r--specs/win32-watcom69
-rw-r--r--sphinx/annotations.rst805
-rw-r--r--sphinx/build_system.rst843
-rw-r--r--sphinx/builtin.rst50
-rw-r--r--sphinx/c_api.rst1721
-rw-r--r--sphinx/command_line.rst137
-rw-r--r--sphinx/conf.py231
-rw-r--r--sphinx/directives.rst2109
-rw-r--r--sphinx/distutils.rst41
-rw-r--r--sphinx/embedding.rst62
-rw-r--r--sphinx/incompatibilities.rst198
-rw-r--r--sphinx/index.rst20
-rw-r--r--sphinx/installation.rst169
-rw-r--r--sphinx/introduction.rst169
-rw-r--r--sphinx/python_api.rst282
-rw-r--r--sphinx/specification_files.rst499
-rw-r--r--sphinx/using.rst662
163 files changed, 101505 insertions, 0 deletions
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..b257009
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,48 @@
+RIVERBANK COMPUTING LIMITED LICENSE AGREEMENT FOR SIP
+
+1. This LICENSE AGREEMENT is between Riverbank Computing Limited ("Riverbank"),
+and the Individual or Organization ("Licensee") accessing and otherwise using
+SIP software in source or binary form and its associated documentation. SIP
+comprises a software tool for generating Python bindings for software C and C++
+libraries, and a Python extension module used at runtime by those generated
+bindings.
+
+2. Subject to the terms and conditions of this License Agreement, Riverbank
+hereby grants Licensee a nonexclusive, royalty-free, world-wide license to
+reproduce, analyze, test, perform and/or display publicly, prepare derivative
+works, distribute, and otherwise use SIP alone or in any derivative version,
+provided, however, that Riverbank's License Agreement and Riverbank's notice of
+copyright, e.g., "Copyright (c) 2010 Riverbank Computing Limited; All Rights
+Reserved" are retained in SIP alone or in any derivative version prepared by
+Licensee.
+
+3. In the event Licensee prepares a derivative work that is based on or
+incorporates SIP or any part thereof, and wants to make the derivative work
+available to others as provided herein, then Licensee hereby agrees to include
+in any such work a brief summary of the changes made to SIP.
+
+4. Licensee may not use SIP to generate Python bindings for any C or C++
+library for which bindings are already provided by Riverbank.
+
+5. Riverbank is making SIP available to Licensee on an "AS IS" basis.
+RIVERBANK MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY
+OF EXAMPLE, BUT NOT LIMITATION, RIVERBANK MAKES NO AND DISCLAIMS ANY
+REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR
+PURPOSE OR THAT THE USE OF SIP WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
+
+6. RIVERBANK SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF SIP FOR ANY
+INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING,
+DISTRIBUTING, OR OTHERWISE USING SIP, OR ANY DERIVATIVE THEREOF, EVEN IF
+ADVISED OF THE POSSIBILITY THEREOF.
+
+7. This License Agreement will automatically terminate upon a material breach
+of its terms and conditions.
+
+8. Nothing in this License Agreement shall be deemed to create any relationship
+of agency, partnership, or joint venture between Riverbank and Licensee. This
+License Agreement does not grant permission to use Riverbank trademarks or
+trade name in a trademark sense to endorse or promote products or services of
+Licensee, or any third party.
+
+9. By copying, installing or otherwise using SIP, Licensee agrees to be bound
+by the terms and conditions of this License Agreement.
diff --git a/LICENSE-GPL2 b/LICENSE-GPL2
new file mode 100644
index 0000000..91c52c9
--- /dev/null
+++ b/LICENSE-GPL2
@@ -0,0 +1,344 @@
+-------------------------------------------------------------------------
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
+-------------------------------------------------------------------------
diff --git a/LICENSE-GPL3 b/LICENSE-GPL3
new file mode 100644
index 0000000..de2dcce
--- /dev/null
+++ b/LICENSE-GPL3
@@ -0,0 +1,678 @@
+-------------------------------------------------------------------------
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If 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 convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+
+-------------------------------------------------------------------------
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..b187a97
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,363 @@
+v4.10.5 16th July 2010
+ - A bug fix release for Python v3 and Python v2.7.
+
+v4.10.4 15th July 2010
+ - Use capsules when being built for Python v2.7 to work around an apparent
+ bug in the support for PyCObject.
+
+v4.10.3 12th July 2010
+ - Added support for Q_SLOT, Q_SLOTS, Q_SIGNAL and Q_SIGNALS.
+ - Added the /__len__/ function annotation.
+
+v4.10.2 16th April 2010
+ - A bug fix release.
+
+v4.10.1 17th March 2010
+ - Added the /NoCopy/ function and argument annotations.
+
+v4.10 14th January 2010
+ - Added the sip.voidptr.ascapsule() method.
+ - Added the -P command line option to build modules with "protected"
+ redefined to "public" if supported by the platform. This can result in
+ significantly smaller modules.
+ - Added the -o command line option to automatically generate docstrings.
+ - Added the -k command line option and /KeywordArgs/ and /NoKeywordArgs/
+ function annotations to support keyword arguments.
+ - Added the /Default/ exception annotation.
+ - Added the /DocType/ argument, function, mapped type and variable
+ annotation.
+ - Added the /DocValue/ argument annotation.
+ - Added the %Docstring directive to specify explicit docstrings for classes,
+ functions and methods.
+ - Added sipError to %MethodCode to allow user errors to be distinguished from
+ interpreter errors.
+ - Added sipBadCallableArg() to the C API.
+ - Added support for configuring and building outside of the source tree.
+
+v4.9.3 23rd November 2009
+ - A bug fix release.
+
+v4.9.2 20th November 2009
+ - A bug fix release.
+
+v4.9.1 23rd October 2009
+ - A bug fix release.
+
+v4.9 26th September 2009
+ - Added support for __iter__ and __next__. (__next__ is used for Python v2
+ as well as v3.)
+ - Added the %API directive.
+ - Added the /API/ annotation.
+ - Added sipIsAPIEnabled() to the C API.
+ - Added sip.getapi() and sip.setapi() to the Python API.
+ - Added sip.ispyowned() to the Python API.
+ - Mapped types can now act as a namespace for enums and static methods.
+ - The /Array/ annotation can now be applied to classes and mapped types.
+ - The /NoArgParser/ annotation can now be applied to methods as well as
+ functions.
+ - Added the --arch flag to configure.py to specify which MacOS/X
+ architectures are built.
+ - SIP is now also licensed under the GPL v2 and v3.
+
+v4.8.2 27th July 2009
+ - Added the /AllowNone/ class annotation.
+
+v4.8.1 16th June 2009
+ - Added support for defining a private assignment operator to suppress the
+ possible generation of an assignment helper.
+
+v4.8 5th June 2009
+ - Added support for Python v3.
+ - Added the %BIGetBufferCode and %BIReleaseBufferCode to support the buffer
+ interface of Python v3.
+ - Added the %DefaultMetatype directive and the /Metatype/ class annotation to
+ allow the meta-type of a wrapped type to be changed.
+ - Added the %DefaultSupertype directive and the /Supertype/ class annotation
+ to allow the super-type of a wrapped type to be changed.
+ - Added the sip.simplewrapper type to be used as a super-type for wrapped
+ types that don't take part in parent/child relationships.
+ - Added the %InitialisationCode directive.
+ - Added the /KeepReference/ argument annotation.
+ - Added the /Encoding/ argument, function, typedef and variable annotation.
+ - super() now works as expected with wrapped types.
+ - Added support for __floordiv__, __ifloordiv__, __truediv__, __itruediv__
+ and __index__.
+ - __bool__ is a synonym for __nonzero__.
+ - Sphinx is now used for the documentation.
+ - Many additions and deprecations in the API to eliminate the differences
+ between classes and mapped types. (See the documentation for the details.)
+
+v4.7.9 17th November 2008
+ - A bug fix release.
+
+v4.7.8 8th November 2008
+ - Added the /Deprecated/ class and function annotation (based on a patch from
+ Lorenzo Berni).
+ - Templates now support instance variables and enums.
+ - A Python int object can now be used whenever an enum is expected without
+ needing to explicitly cast it using the enum's constructor. The
+ /Constrained/ argument annotation can be used to suppress this behaviour.
+ - typedef type names are now used in string representations of types (e.g. in
+ the names of mapped types) to reflect what the programmer sees rather than
+ what the compiler sees. The /NoTypeName/ typedef annotation can be used to
+ suppress this behaviour.
+
+v4.7.7 8th August 2008
+ - C++ structs are now properly handled as a class with a default public
+ section.
+ - sip.dump() now includes the object's first child wrapper.
+
+v4.7.6 20th May 2008
+ - Added the -s flag to configure.py to specify the SDK directory to use when
+ building universal binaries on MacOS/X.
+ - Added support for MSVC 2008 to the build system.
+ - Added support for v10.x of the Intel compiler and removed support for
+ earlier versions.
+ - MSVC 2008 is the default platform when using Python v2.6.
+
+v4.7.5 13th May 2008
+ - The sip.voidptr type has an optional size associated with it and supports
+ const void *. If a size is associated then it also supports Python's
+ buffer protocol.
+ - Added sipConvertToVoidPtr() to the SIP API.
+ - Added sipConvertFromConstVoidPtr(), sipConvertFromConstVoidPtrAndSize(),
+ sipConvertFromVoidPtr() and sipConvertFromVoidPtrAndSize() to the SIP API.
+ - Added the /ResultSize/ argument annotation to specify the size of a block
+ of memory returned as a void * or const void *.
+ - Added the /NoArgParser/ function annotation to give %MethodCode complete
+ responsibility for argument parsing.
+ - Added the /NoRelease/ mapped type annotation to specify that the
+ sipReleaseMappedType() function is not supported.
+ - The /ArraySize/ annotation now supports arrays with more than 2^31
+ elements.
+ - %GetCode and %SetCode for class attributes now have access to the
+ referencing type object.
+ - Any object that supports the Python buffer protocol can now be passed as a
+ char or char * argument.
+
+v4.7.4 12th February 2008
+ - The build system handles the directory structure used by Leopard's Python
+ installation.
+ - Added support for /Transfer/ as a constructor annotation.
+
+v4.7.3 6th December 2007
+ - Added support for automatically generating missing complementary
+ comparision operators. Note that this introduces a potential compatibility
+ problem - see the documentation for details.
+
+v4.7.2 5th December 2007
+ - Added the /SingleShot/ argument annotation.
+ - Added the /TransferThis/ function annotation.
+
+v4.7.1 28th September 2007
+ - A bug fix release.
+
+v4.7 30th July 2007
+ - Added %PickleCode to allow handwritten code to pickle a wrapped C++
+ instance or C structure.
+ - Added %CompositeModule to create modules that are composites of ordinary
+ modules.
+ - Added %ConsolidatedModule (and the -p command line option) to create
+ modules that contain all the wrapper code on behalf of ordinary modules.
+ - Added the dump() function to the sip module.
+ - Added sipTransferBreak() to the SIP API.
+ - Added support for /Transfer/ as a function annotation.
+
+v4.6 10th April 2007
+ - Added support for wchar_t.
+ - The -g command line option releases the GIL whenever a call is made to the
+ wrapped library.
+ - Added the /HoldGIL/ annotation to explicitly retain the GIL when calling a
+ particular function in the wrapped library.
+ - Added sipFindClass() and sipFindNamedEnum() to the public API.
+ - /TransferThis/ may be specified more than once.
+ - Added support for __truediv__ and __itruediv__.
+ - The SIP code generator and module may be built as universal binaries under
+ MacOS/X using the -n command line option to configure.py.
+
+v4.5.2 9th December 2006
+ - A bug fix release.
+
+v4.5.1 9th December 2006
+ - Added the SIP_SSIZE_T type to help write PEP 353 compliant handwritten
+ code.
+
+v4.5 4th November 2006
+ - Added support for Python v2.5.
+ - Added sip_config_args to sipconfig.py.
+ - sip.voidptr now implements __hex__().
+ - Added sip.delete() to call a C++ instance's destructor, or return a C
+ structure to the heap.
+ - Added sip.isdeleted() to check if a C++ instance or C structure has been
+ destroyed or returned to the heap.
+ - Added sip.setdeleted() to mark that a C++ instance or C structure has been
+ destroyed or returned to the heap.
+ - Added support for pure virtual destructors.
+ - Added the __dtor__() method to allow Python code to be called from a C++
+ destructor.
+ - Added the /NoDefaultCtors/ class annotation.
+ - The generated API files are now more complete and use Python types rather
+ than C/C++ types.
+ - Added support for embedding manifests for MSVC 2005.
+
+v4.4.5 10th June 2006
+ - A bug fix release.
+
+v4.4.4 8th June 2006
+ - Added %ExportedHeaderCode and %UnitCode.
+ - Added sipExportSymbol() and sipImportSymbol() to the public API.
+
+v4.4.3 27th April 2006
+ - A bug fix release.
+
+v4.4.2 23rd April 2006
+ - A bug fix release.
+
+v4.4.1 3rd April 2006
+ - A bug fix release.
+
+v4.4 24th March 2006
+ - The major number of the internal API has changed so it will be necessary
+ to regenerate all modules.
+ - This release introduces small incompatibilities that may affect handwritten
+ code. See the documentation for the details.
+ - Module names specified with %Module and %CModule can now include periods to
+ denote a Python package structure.
+ - Namespaces can be split across multiple Python modules.
+ - Class templates are now supported and instantiated using "typedef".
+ - Mapped type templates are now supported and instantiated automatically.
+ - Global operators are now supported.
+ - Operator casts in classes are now supported.
+ - C/C++ signed char type is now treated as a separate type to char.
+ - C/C++ long and unsigned long types are now wrapped as Python long objects
+ rather than Python integer objects.
+ - C/C++ long long and unsigned long long types are now supported.
+ - unsigned short and unsigned int are now implemented as long objects instead
+ of integer objects.
+ - Classes can now be declared using the /External/ annotation and be defined
+ in another, unspecified, module.
+ - /TransferThis/ can now be used in non-factory methods to change the
+ ownership to a different C++ instance or to change it to Python.
+ - /Constrained/ can now be used with booleans.
+ - Added support for Python's buffer interface, %BIGetCharBufferCode,
+ %BIGetReadBufferCode, %BIGetSegCountCode and %BIGetWriteBufferCode.
+ - The "user" member has been added to the sipWrapper structure and can be
+ used for any purpose by handwritten code.
+ - Function argument names are now parsed, but otherwise ignored.
+ - The "explicit" keyword is now parsed, but otherwise ignored.
+ - Added the /DelayDtor/ class annotation which given more control over the
+ order in which instances are deleted when an application terminates.
+ - Added support for the SIP_PYTYPE pseudo-type that represents a Python
+ type object.
+ - Added support for ellipsis (ie. "...") in function arguments. Any
+ remaining arguments will be gathered as a Python tuple.
+ - Add support for the /NoDerived/ annotation for Python class constructors
+ that have no C/C++ equivalent.
+ - The sipSelfWasArg boolean is now available to the %MethodCode of
+ non-abstract, virtual methods to indicate whether the class implementation
+ of the method rather than the virtual implementation should be called.
+ %MethodCode for non-abstract, virtual, protected methods must now call the
+ sipProtectVirt wrapper (rather than sipProtect).
+ - sipCanConvertToInstance(), sipConvertToInstance(),
+ sipForceConvertToInstance(), sipReleaseInstance(),
+ sipConvertFromInstance(), sipConvertFromNewInstance(),
+ sipCanConvertToMappedType(), sipConvertToMappedType(),
+ sipForceConvertToMappedType(), sipReleaseMappedType(),
+ sipConvertFromMappedType() and sipFindMappedType() have been added to the
+ SIP API.
+ - sipLong_AsUnsignedLong() has been added, primarily as a workaround for a
+ bug in Python v2.3.x and earlier.
+ - Added the 't', 'u', 'C' and 'D' format characters to sipParseResult().
+ - Added the 't', 'u', 'B', 'C' and 'D' format characters to sipBuildResult().
+ - Responsibility for interpreting and implementing the /Transfer/ and
+ /TransferBack/ annotations has been pushed down to %ConvertToTypeCode and
+ %ConvertFromTypeCode. The generated type convertors sipForceConvertTo_*()
+ and sipConvertFrom_*() have been deprecated.
+ - Added the %SIPNoEmitters directive for PyQt4.
+ - Added support for the __hash__ Python special method.
+ - The __getitem__ Python special method no longer requires %MethodCode.
+ - All of the calls to Qt have been moved out of the sip module and into PyQt.
+ The generated sipconfig.py file no longer contains any Qt specific
+ information. These changes mean that SIP can support PyQt v3 and v4 at the
+ same time.
+ - Static methods can now be defined as Qt slots.
+ - Removed SIP_BUILD from sip.h.
+ - The -c, -l, -q and -x flags to configure.py have been removed.
+ - Added the PythonModuleMakefile class to the build system for installing
+ pure Python modules.
+ - Added the create_wrapper() function to the build system for creating
+ platform dependent executable wrappers for Python scripts.
+ - Added Configuration.platform to the build system.
+
+v4.3.2 14th November 2005
+ - The sipdistutils.py script has contributed by Giovanni Bajo that enables
+ SIP extension modules to be built with distutils.
+
+v4.3.1 10th September 2005
+ - A bug fix release.
+
+v4.3 30th August 2005
+ - The major number of the internal API has changed so it will be necessary
+ to regenerate all modules.
+ - C structures can now have constructors and a destructor defined so that
+ they can be made to behave more Pythonically.
+ - %TypeHeaderCode can now be used in namespaces.
+ - Added sip.SIP_VERSION_STR.
+ - Added support for Python's cyclic garbage collector, %GCTraverseCode and
+ %GCClearCode.
+ - Deprecated sipTransfer() and sip.transfer().
+ - Added sipTransferTo, sipTransferBack(), sip.transferto() and
+ sip.transferback().
+ - Added support for sipCppRet in %ConvertSubClassCode.
+ - Added support for %GetCode and %SetCode for instance variables and
+ structure members.
+ - Added support for %Exception and %RaiseCode.
+ - Added support for __pos__ and __abs__.
+ - sip.voidptr instances can now be created from Python.
+ - The ascobject() method has been added to sip.voidptr.
+ - Added the -c flag to configure.py to explicitly specify the location of
+ the qconfig.h file.
+
+v4.2.1 6th March 2005
+ - Restored the pre-4.2 behaviour of Python exceptions raised in virtual
+ re-implementations.
+ - %Timeline can now be used more than once in a module.
+
+v4.2 19th February 2005
+ - The /PyName/ annotation can now be applied to classes, namespaces,
+ enums, enum members and variables.
+ - Added the %PreInitialisationCode directive and is subject to version
+ control. %PostInitialisationCode is now subject to version control.
+ - Named enums now have distinct types and so can be differentiated from
+ integers in function signatures.
+ - The handling of Qt signals has changed so that "foreign" signals (ie.
+ those raised by ActiveX controls) can be handled.
+ - The voidptr, wrapper and wrappertype types are now exposed in the sip
+ module.
+ - Virtual and abstract operators are now supported.
+ - The __call__ slot no longer requires %MethodCode.
+ - Any Python exceptions raised in virtual re-implementations are now
+ detected when they occur.
+ - sip.cast() can now cast downwards as well as upwards.
+ - Added sip.SIP_VERSION.
+ - The -k flag to configure.py can now be used to build modules as builtins
+ to custom interpreters.
+ - The build system now strips modules and only exports the module
+ initialisation function by default (when supported by the platform).
+
+v4.1.1 24th September 2004
+ - A bug fix release.
+
+v4.1 20th September 2004
+ - Added the cast() method to the sip module.
+ - Added limited support for protected classes.
+ - Added the /Abstract/ class annotation.
+ - Added support for typedefs that define pointers to functions.
+ - The SIP_PYCALLABLE type now supports the /AllowNone/ annotation.
+ - Added support for MSVC.NET to the build system.
+
+v4.0.1 6th July 2004
+ - A bug fix release.
+
+v4.0 23rd June 2004
+ - The release of SIP v4.
diff --git a/README b/README
new file mode 100644
index 0000000..e9adfeb
--- /dev/null
+++ b/README
@@ -0,0 +1,33 @@
+SIP - C/C++ Bindings Generator for Python v2 and v3
+===================================================
+
+The SIP documentation (including installation instructions) can be found in the
+``doc`` directory.
+
+
+Building from the Mercurial Repository
+--------------------------------------
+
+If you are using a copy of SIP cloned from the Mercurial repository, or are
+using a Mercurial archive, then you have to prepare it first before you follow
+the normal installation instructions.
+
+The preparation is done using the ``build.py`` script which can be found in the
+same directory as this ``README`` file. If it isn't there then you probably
+have a packaged release and should just follow the normal installation
+instructions.
+
+The ``build.py`` script requires that ``flex`` and ``bison``, and the Mercurial
+Python bindings are installed. If you want to create the HTML documentation
+then Sphinx must also be installed.
+
+To prepare run the following::
+
+ python build.py prepare
+
+Note that ``build.py`` is a Python v2 script.
+
+Now you can follow the normal installation instructions.
+
+The ``build.py`` script has other useful commands, use the ``--help`` option to
+see the details.
diff --git a/configure.py b/configure.py
new file mode 100644
index 0000000..e099137
--- /dev/null
+++ b/configure.py
@@ -0,0 +1,471 @@
+# This script handles the SIP configuration and generates the Makefiles.
+#
+# Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com>
+#
+# This file is part of SIP.
+#
+# This copy of SIP is licensed for use under the terms of the SIP License
+# Agreement. See the file LICENSE for more details.
+#
+# This copy of SIP may also used under the terms of the GNU General Public
+# License v2 or v3 as published by the Free Software Foundation which can be
+# found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
+#
+# SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+
+import sys
+import os
+import glob
+import optparse
+from distutils import sysconfig
+
+import siputils
+
+
+# Initialise the globals.
+sip_version = 0x040a05
+sip_version_str = "4.10.5"
+py_version = sys.hexversion >> 8
+plat_py_site_dir = None
+plat_py_inc_dir = None
+plat_py_conf_inc_dir = None
+plat_py_lib_dir = None
+plat_sip_dir = None
+plat_bin_dir = None
+platform_specs = []
+src_dir = os.path.dirname(os.path.abspath(__file__))
+
+# Constants.
+DEFAULT_MACOSX_ARCH = 'i386 ppc'
+MACOSX_SDK_DIR = '/Developer/SDKs'
+
+# Command line options.
+default_platform = None
+default_sipbindir = None
+default_sipmoddir = None
+default_sipincdir = None
+default_sipsipdir = None
+
+# The names of build macros extracted from the platform specific configuration
+# files.
+build_macro_names = [
+ "DEFINES", "CONFIG",
+ "CC",
+ "CFLAGS",
+ "CFLAGS_RELEASE", "CFLAGS_DEBUG",
+ "CFLAGS_CONSOLE", "CFLAGS_SHLIB", "CFLAGS_THREAD",
+ "CFLAGS_MT", "CFLAGS_MT_DBG", "CFLAGS_MT_DLL", "CFLAGS_MT_DLLDBG",
+ "CFLAGS_EXCEPTIONS_ON", "CFLAGS_EXCEPTIONS_OFF",
+ "CFLAGS_RTTI_ON", "CFLAGS_RTTI_OFF",
+ "CFLAGS_STL_ON", "CFLAGS_STL_OFF",
+ "CFLAGS_WARN_ON", "CFLAGS_WARN_OFF",
+ "CHK_DIR_EXISTS", "COPY",
+ "CXX",
+ "CXXFLAGS",
+ "CXXFLAGS_RELEASE", "CXXFLAGS_DEBUG",
+ "CXXFLAGS_CONSOLE", "CXXFLAGS_SHLIB", "CXXFLAGS_THREAD",
+ "CXXFLAGS_MT", "CXXFLAGS_MT_DBG", "CXXFLAGS_MT_DLL", "CXXFLAGS_MT_DLLDBG",
+ "CXXFLAGS_EXCEPTIONS_ON", "CXXFLAGS_EXCEPTIONS_OFF",
+ "CXXFLAGS_RTTI_ON", "CXXFLAGS_RTTI_OFF",
+ "CXXFLAGS_STL_ON", "CXXFLAGS_STL_OFF",
+ "CXXFLAGS_WARN_ON", "CXXFLAGS_WARN_OFF",
+ "DEL_FILE",
+ "EXTENSION_SHLIB", "EXTENSION_PLUGIN",
+ "INCDIR", "INCDIR_X11", "INCDIR_OPENGL",
+ "LIBS_CORE", "LIBS_GUI", "LIBS_NETWORK", "LIBS_OPENGL", "LIBS_WEBKIT",
+ "LINK", "LINK_SHLIB", "AIX_SHLIB", "LINK_SHLIB_CMD",
+ "LFLAGS", "LFLAGS_CONSOLE", "LFLAGS_CONSOLE_DLL", "LFLAGS_DEBUG",
+ "LFLAGS_DLL",
+ "LFLAGS_PLUGIN", "LFLAGS_RELEASE", "LFLAGS_SHLIB", "LFLAGS_SONAME",
+ "LFLAGS_THREAD", "LFLAGS_WINDOWS", "LFLAGS_WINDOWS_DLL", "LFLAGS_OPENGL",
+ "LIBDIR", "LIBDIR_X11", "LIBDIR_OPENGL",
+ "LIBS", "LIBS_CONSOLE", "LIBS_RT",
+ "LIBS_RTMT", "LIBS_THREAD", "LIBS_WINDOWS", "LIBS_X11",
+ "MAKEFILE_GENERATOR",
+ "MKDIR",
+ "RPATH",
+ "AR", "RANLIB", "LIB", "STRIP"
+]
+
+
+def show_platforms():
+ """Display the different platform/compilers.
+ """
+ sys.stdout.write("""
+The following platform/compiler configurations are supported:
+
+""")
+
+ platform_specs.sort()
+ sys.stdout.write(siputils.format(", ".join(platform_specs), leftmargin=2))
+ sys.stdout.write("\n\n")
+
+
+def show_macros():
+ """Display the different build macros.
+ """
+ sys.stdout.write("""
+The following options may be used to adjust the compiler configuration:
+
+""")
+
+ build_macro_names.sort()
+ sys.stdout.write(siputils.format(", ".join(build_macro_names), leftmargin=2))
+ sys.stdout.write("\n\n")
+
+
+def set_defaults():
+ """Set up the defaults for values that can be set on the command line.
+ """
+ global default_platform, default_sipbindir, default_sipmoddir
+ global default_sipincdir, default_sipsipdir
+
+ # Set the platform specific default specification.
+ platdefaults = {
+ "aix": "aix-xlc",
+ "bsd": "bsdi-g++",
+ "cygwin": "cygwin-g++",
+ "darwin": "macx-g++",
+ "dgux": "dgux-g++",
+ "freebsd": "freebsd-g++",
+ "gnu": "hurd-g++",
+ "hp-ux": "hpux-acc",
+ "irix": "irix-cc",
+ "linux": "linux-g++",
+ "lynxos": "lynxos-g++",
+ "netbsd": "netbsd-g++",
+ "openbsd": "openbsd-g++",
+ "openunix": "unixware-cc",
+ "osf1": "tru64-cxx",
+ "qnx": "qnx-g++",
+ "reliantunix": "reliant-cds",
+ "sco_sv": "sco-cc",
+ "sinix": "reliant-cds",
+ "sunos5": "solaris-cc",
+ "ultrix": "ultrix-g++",
+ "unix_sv": "unixware-g++",
+ "unixware": "unixware-cc"
+ }
+
+ default_platform = "none"
+
+ if sys.platform == "win32":
+ if py_version >= 0x020600:
+ default_platform = "win32-msvc2008"
+ elif py_version >= 0x020400:
+ default_platform = "win32-msvc.net"
+ else:
+ default_platform = "win32-msvc"
+ else:
+ for pd in list(platdefaults.keys()):
+ if sys.platform[:len(pd)] == pd:
+ default_platform = platdefaults[pd]
+ break
+
+ default_sipbindir = plat_bin_dir
+ default_sipmoddir = plat_py_site_dir
+ default_sipincdir = plat_py_inc_dir
+ default_sipsipdir = plat_sip_dir
+
+
+def inform_user():
+ """Tell the user the option values that are going to be used.
+ """
+ siputils.inform("The SIP code generator will be installed in %s." % opts.sipbindir)
+ siputils.inform("The SIP module will be installed in %s." % opts.sipmoddir)
+ siputils.inform("The SIP header file will be installed in %s." % opts.sipincdir)
+ siputils.inform("The default directory to install .sip files in is %s." % opts.sipsipdir)
+ siputils.inform("The platform/compiler configuration is %s." % opts.platform)
+
+ if opts.arch:
+ siputils.inform("MacOS/X binaries will be created for %s." % (", ".join(opts.arch.split())))
+
+ if opts.universal:
+ siputils.inform("MacOS/X universal binaries will be created using %s." % opts.universal)
+
+
+def set_platform_directories():
+ """Initialise the global variables relating to platform specific
+ directories.
+ """
+ global plat_py_site_dir, plat_py_inc_dir, plat_py_conf_inc_dir
+ global plat_bin_dir, plat_py_lib_dir, plat_sip_dir
+
+ # We trust distutils for some stuff.
+ plat_py_site_dir = sysconfig.get_python_lib(plat_specific=1)
+ plat_py_inc_dir = sysconfig.get_python_inc()
+ plat_py_conf_inc_dir = os.path.dirname(sysconfig.get_config_h_filename())
+
+ if sys.platform == "win32":
+ plat_py_lib_dir = sys.prefix + "\\libs"
+ plat_bin_dir = sys.exec_prefix
+ plat_sip_dir = sys.prefix + "\\sip"
+ else:
+ lib_dir = sysconfig.get_python_lib(plat_specific=1, standard_lib=1)
+
+ plat_py_lib_dir = lib_dir + "/config"
+ plat_bin_dir = sys.exec_prefix + "/bin"
+ plat_sip_dir = sys.prefix + "/share/sip"
+
+
+def create_config(module, template, macros):
+ """Create the SIP configuration module so that it can be imported by build
+ scripts.
+
+ module is the module file name.
+ template is the template file name.
+ macros is the dictionary of build macros.
+ """
+ siputils.inform("Creating %s..." % module)
+
+ content = {
+ "sip_config_args": sys.argv[1:],
+ "sip_version": sip_version,
+ "sip_version_str": sip_version_str,
+ "platform": opts.platform,
+ "sip_bin": os.path.join(opts.sipbindir, "sip"),
+ "sip_inc_dir": opts.sipincdir,
+ "sip_mod_dir": opts.sipmoddir,
+ "default_bin_dir": plat_bin_dir,
+ "default_mod_dir": plat_py_site_dir,
+ "default_sip_dir": opts.sipsipdir,
+ "py_version": py_version,
+ "py_inc_dir": plat_py_inc_dir,
+ "py_conf_inc_dir": plat_py_conf_inc_dir,
+ "py_lib_dir": plat_py_lib_dir,
+ "universal": opts.universal,
+ "arch": opts.arch
+ }
+
+ siputils.create_config_module(module, template, content, macros)
+
+
+def create_makefiles(macros):
+ """Create the Makefiles.
+
+ macros is the dictionary of platform specific build macros.
+ """
+ # Bootstrap. Make sure we get the right one.
+ sys.path.insert(0, os.path.curdir)
+ import sipconfig
+
+ cfg = sipconfig.Configuration()
+
+ cfg.set_build_macros(macros)
+
+ sipconfig.inform("Creating top level Makefile...")
+
+ sipconfig.ParentMakefile(
+ configuration=cfg,
+ subdirs=["sipgen", "siplib"],
+ installs=(["sipconfig.py", os.path.join(src_dir, "sipdistutils.py")],
+ cfg.sip_mod_dir)
+ ).generate()
+
+ sipconfig.inform("Creating sip code generator Makefile...")
+
+ sipconfig.ProgramMakefile(
+ configuration=cfg,
+ build_file=os.path.join(src_dir, "sipgen", "sipgen.sbf"),
+ dir="sipgen",
+ install_dir=os.path.dirname(cfg.sip_bin),
+ console=1,
+ warnings=0,
+ universal=opts.universal,
+ arch=opts.arch
+ ).generate()
+
+ sipconfig.inform("Creating sip module Makefile...")
+
+ makefile = sipconfig.ModuleMakefile(
+ configuration=cfg,
+ build_file=os.path.join(src_dir, "siplib", "siplib.sbf"),
+ dir="siplib",
+ install_dir=cfg.sip_mod_dir,
+ installs=([os.path.join(src_dir, "siplib", "sip.h")], cfg.sip_inc_dir),
+ console=1,
+ warnings=0,
+ static=opts.static,
+ debug=opts.debug,
+ universal=opts.universal,
+ arch=opts.arch
+ )
+
+ makefile.generate()
+
+
+def create_optparser():
+ """Create the parser for the command line.
+ """
+ def store_abspath(option, opt_str, value, parser):
+ setattr(parser.values, option.dest, os.path.abspath(value))
+
+ p = optparse.OptionParser(usage="python %prog [opts] [macro=value] "
+ "[macro+=value]", version=sip_version_str)
+
+ # Note: we don't use %default to be compatible with Python 2.3.
+ p.add_option("-k", "--static", action="store_true", default=False,
+ dest="static", help="build the SIP module as a static library")
+ p.add_option("-p", "--platform", action="store",
+ default=default_platform, type="string", metavar="PLATFORM",
+ dest="platform", help="the platform/compiler configuration "
+ "[default: %s]" % default_platform)
+ p.add_option("-u", "--debug", action="store_true", default=False,
+ help="build with debugging symbols")
+
+ if sys.platform == 'darwin':
+ # Get the latest SDK to use as the default.
+ sdks = glob.glob(MACOSX_SDK_DIR + '/MacOSX*.sdk')
+ if len(sdks) > 0:
+ sdks.sort()
+ _, default_sdk = os.path.split(sdks[-1])
+ else:
+ default_sdk = 'MacOSX10.4u.sdk'
+
+ g = optparse.OptionGroup(p, title="MacOS X Configuration")
+ g.add_option("--arch", action="append", default=[], dest="arch",
+ choices=["i386", "x86_64", "ppc"],
+ help="build for architecture ARCH")
+ g.add_option("-n", "--universal", action="store_true", default=False,
+ dest="universal",
+ help="build the SIP code generator and module as universal "
+ "binaries")
+ g.add_option("-s", "--sdk", action="store", default=default_sdk,
+ type="string", metavar="SDK", dest="sdk",
+ help="the name of the SDK used when building universal "
+ "binaries [default: %s]" % default_sdk)
+ p.add_option_group(g)
+
+ # Querying.
+ g = optparse.OptionGroup(p, title="Query")
+ g.add_option("--show-platforms", action="store_true", default=False,
+ dest="show_platforms", help="show the list of supported "
+ "platform/compiler configurations")
+ g.add_option("--show-build-macros", action="store_true", default=False,
+ dest="show_build_macros", help="show the list of supported build "
+ "macros")
+ p.add_option_group(g)
+
+ # Installation.
+ g = optparse.OptionGroup(p, title="Installation")
+ g.add_option("-b", "--bindir", action="callback",
+ default=default_sipbindir, type="string", metavar="DIR",
+ dest="sipbindir", callback=store_abspath, help="where the SIP "
+ "code generator will be installed [default: %s]" %
+ default_sipbindir)
+ g.add_option("-d", "--destdir", action="callback",
+ default=default_sipmoddir, type="string", metavar="DIR",
+ dest="sipmoddir", callback=store_abspath, help="where the SIP "
+ "module will be installed [default: %s]" % default_sipmoddir)
+ g.add_option("-e", "--incdir", action="callback",
+ default=default_sipincdir, type="string", metavar="DIR",
+ dest="sipincdir", callback=store_abspath, help="where the SIP "
+ "header file will be installed [default: %s]" % default_sipincdir)
+ g.add_option("-v", "--sipdir", action="callback",
+ default=default_sipsipdir, type="string", metavar="DIR",
+ dest="sipsipdir", callback=store_abspath, help="where .sip files "
+ "are normally installed [default: %s]" % default_sipsipdir)
+ p.add_option_group(g)
+
+ return p
+
+
+def main(argv):
+ """Create the configuration module module.
+
+ argv is the list of command line arguments.
+ """
+ siputils.inform("This is SIP %s for Python %s on %s." % (sip_version_str, sys.version.split()[0], sys.platform))
+
+ if py_version < 0x020300:
+ siputils.error("This version of SIP requires Python v2.3 or later.")
+
+ # Basic initialisation.
+ set_platform_directories()
+
+ # Build up the list of valid specs.
+ for s in os.listdir(os.path.join(src_dir, "specs")):
+ platform_specs.append(s)
+
+ # Parse the command line.
+ global opts
+
+ set_defaults()
+ p = create_optparser()
+ opts, args = p.parse_args()
+
+ # Make sure MacOS specific options get initialised.
+ if sys.platform != 'darwin':
+ opts.universal = ''
+ opts.arch = []
+ opts.sdk = ''
+
+ # Handle the query options.
+ if opts.show_platforms or opts.show_build_macros:
+ if opts.show_platforms:
+ show_platforms()
+
+ if opts.show_build_macros:
+ show_macros()
+
+ sys.exit()
+
+ # Convert the list 'arch' option to a string. Multiple architectures
+ # imply a universal binary.
+ if len(opts.arch) > 1:
+ opts.universal = True
+
+ opts.arch = ' '.join(opts.arch)
+
+ # Convert the boolean 'universal' option to a string.
+ if opts.universal:
+ if '/' in opts.sdk:
+ opts.universal = os.path.abspath(opts.sdk)
+ else:
+ opts.universal = MACOSX_SDK_DIR + '/' + opts.sdk
+
+ if not os.path.isdir(opts.universal):
+ siputils.error("Unable to find the SDK directory %s. Use the --sdk flag to specify the name of the SDK or its full path." % opts.universal)
+
+ if opts.arch == '':
+ opts.arch = DEFAULT_MACOSX_ARCH
+ else:
+ opts.universal = ''
+
+ # Get the platform specific macros for building.
+ macros = siputils.parse_build_macros(
+ os.path.join(src_dir, "specs", opts.platform), build_macro_names,
+ args)
+
+ if macros is None:
+ p.print_help()
+ sys.exit(2)
+
+ # Tell the user what's been found.
+ inform_user()
+
+ # Install the configuration module.
+ create_config("sipconfig.py", os.path.join(src_dir, "siputils.py"),
+ macros)
+
+ # Create the Makefiles.
+ create_makefiles(macros)
+
+
+###############################################################################
+# The script starts here.
+###############################################################################
+
+if __name__ == "__main__":
+ try:
+ main(sys.argv)
+ except SystemExit:
+ raise
+ except:
+ sys.stderr.write(
+"""An internal error occured. Please report all the output from the program,
+including the following traceback, to support@riverbankcomputing.com.
+""")
+ raise
diff --git a/custom/custom.c b/custom/custom.c
new file mode 100644
index 0000000..e5ec2d2
--- /dev/null
+++ b/custom/custom.c
@@ -0,0 +1,60 @@
+/*
+ * This file is the basis of a custom Python interpreter. Use it for Linux,
+ * UNIX and Windows (console). You will also need to edit mkcustom.py.
+ */
+
+
+#include <Python.h>
+
+
+int main(int argc, char **argv)
+{
+ /*
+ * Declare the module initialisation function for each module you want
+ * to be a builtin in the custom interpreter. The name of the function
+ * will be the name of the module with "init" prepended. The modules
+ * must be built as static libraries (using the -k flag to configure.py
+ * for SIP and PyQt).
+ */
+
+ /* The sip module will be builtin. */
+ extern void initsip(void);
+
+ /*
+ * Uncomment these (and in the structure below) to include the PyQt
+ * modules as builtins.
+ */
+/* extern void initqt(void);*/
+/* extern void initqtaxcontainer(void);*/
+/* extern void initqtcanvas(void);*/
+/* extern void initqtext(void);*/
+/* extern void initqtgl(void);*/
+/* extern void initqtnetwork(void);*/
+/* extern void initqtsql(void);*/
+/* extern void initqttable(void);*/
+/* extern void initqtui(void);*/
+/* extern void initqtxml(void);*/
+
+ /*
+ * This structure specifies the names and initialisation functions of
+ * the builtin modules.
+ */
+ struct _inittab builtin_modules[] = {
+ {"sip", initsip},
+/* {"qt", initqt},*/
+/* {"qtaxcontainer", initqtaxcontainer},*/
+/* {"qtcanvas", initqtcanvas},*/
+/* {"qtext", initqtext},*/
+/* {"qtgl", initqtgl},*/
+/* {"qtnetwork", initqtnetwork},*/
+/* {"qtsql", initqtsql},*/
+/* {"qttable", initqttable},*/
+/* {"qtui", initqtui},*/
+/* {"qtxml", initqtxml},*/
+ {NULL, NULL}
+ };
+
+ PyImport_ExtendInittab(builtin_modules);
+
+ return Py_Main(argc, argv);
+}
diff --git a/custom/customw.c b/custom/customw.c
new file mode 100644
index 0000000..5877076
--- /dev/null
+++ b/custom/customw.c
@@ -0,0 +1,64 @@
+/*
+ * This file is the basis of a custom Python interpreter. Use it for Windows
+ * (non-console). You will also need to edit mkcustom.py.
+ */
+
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include <Python.h>
+
+
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine, int nCmdShow)
+{
+ /*
+ * Declare the module initialisation function for each module you want
+ * to be a builtin in the custom interpreter. The name of the function
+ * will be the name of the module with "init" prepended. The modules
+ * must be built as static libraries (using the -k flag to configure.py
+ * for SIP and PyQt).
+ */
+
+ /* The sip module will be builtin. */
+ extern void initsip(void);
+
+ /*
+ * Uncomment these (and in the structure below) to include the PyQt
+ * modules as builtins.
+ */
+/* extern void initqt(void);*/
+/* extern void initqtaxcontainer(void);*/
+/* extern void initqtcanvas(void);*/
+/* extern void initqtext(void);*/
+/* extern void initqtgl(void);*/
+/* extern void initqtnetwork(void);*/
+/* extern void initqtsql(void);*/
+/* extern void initqttable(void);*/
+/* extern void initqtui(void);*/
+/* extern void initqtxml(void);*/
+
+ /*
+ * This structure specifies the names and initialisation functions of
+ * the builtin modules.
+ */
+ struct _inittab builtin_modules[] = {
+ {"sip", initsip},
+/* {"qt", initqt},*/
+/* {"qtaxcontainer", initqtaxcontainer},*/
+/* {"qtcanvas", initqtcanvas},*/
+/* {"qtext", initqtext},*/
+/* {"qtgl", initqtgl},*/
+/* {"qtnetwork", initqtnetwork},*/
+/* {"qtsql", initqtsql},*/
+/* {"qttable", initqttable},*/
+/* {"qtui", initqtui},*/
+/* {"qtxml", initqtxml},*/
+ {NULL, NULL}
+ };
+
+ PyImport_ExtendInittab(builtin_modules);
+
+ return Py_Main(__argc, __argv);
+}
diff --git a/custom/mkcustom.py b/custom/mkcustom.py
new file mode 100644
index 0000000..0e8deab
--- /dev/null
+++ b/custom/mkcustom.py
@@ -0,0 +1,87 @@
+"""This Python script uses the SIP build system to create a Makefile for
+building a custom Python interpreter. The script doesn't take any command line
+flags - just edit it to suit your needs. You will also need to edit custom.c
+or customw.c.
+"""
+
+
+import sys
+import sipconfig
+
+
+# Get the SIP configuration.
+cfg = sipconfig.Configuration()
+
+
+# This is the name of the interpreter executable (excluding any platform
+# specific extension.
+InterpreterName = "custom"
+
+# Set this to True to create a non-console interpreter on Windows (ie. a custom
+# version of pythonw). Make sure you make changes to customw.c rather than
+# custom.c. It is ignored on other platforms.
+WindowsInterpreter = False
+
+# Set this to the list of the name of modules to be builtin to the custom
+# interpreter. The modules must also be added to custom.c and/or customw.c.
+Modules = ["sip"]
+#Modules = ["sip", "qt", "qtaxcontainer", "qtcanvas", "qtext", "qtgl",
+# "qtnetwork", "qtsql", "qttable", "qtui", "qtxml"]
+
+# Set this to the name of the directory containing the static modules.
+ModuleDirectory = cfg.default_mod_dir
+
+# Set this to the list of additional libraries to link with the custom
+# interpreter.
+ExtraLibraries = []
+#ExtraLibraries = ["qassistantclient"]
+
+# Set this to the list of additional directory names to search for any
+# additional libraries.
+ExtraLibraryDirectories = []
+
+# Set this to the name of the directory containing the Python library.
+PythonLibraryDirectory = cfg.py_lib_dir
+
+
+# Make platform specific modifications.
+if sys.platform == "linux2":
+ ExtraLibraries.append("util")
+
+
+# Create a dictionary describing the target and source files to be passed to
+# the SIP build system.
+build = {}
+
+if sys.platform == "win32" and WindowsInterpreter:
+ build["target"] = InterpreterName + "w"
+ build["sources"] = "customw.c"
+ console = False
+else:
+ build["target"] = InterpreterName
+ build["sources"] = "custom.c"
+ console = True
+
+# Assume Qt support is required if Qt support was enabled in the sip module.
+qt = (cfg.qt_version > 0)
+
+# Create the Makefile instance.
+mf = sipconfig.ProgramMakefile(cfg, build, python=True, console=console, qt=qt)
+
+# Modify the Makefile according to the values set above.
+mf.extra_lib_dirs.extend(ExtraLibraryDirectories)
+mf.extra_lib_dirs.append(ModuleDirectory)
+mf.extra_lib_dirs.append(PythonLibraryDirectory)
+
+mf.extra_libs.extend(Modules)
+
+if sys.platform == "win32":
+ pylib = "python%u%u"
+else:
+ pylib = "python%u.%u"
+
+mf.extra_libs.append(pylib % ((cfg.py_version >> 16), ((cfg.py_version >> 8) & 0xff)))
+mf.extra_libs.extend(ExtraLibraries)
+
+# Generate the Makefile itself.
+mf.generate()
diff --git a/doc/html/_sources/annotations.txt b/doc/html/_sources/annotations.txt
new file mode 100644
index 0000000..05ab847
--- /dev/null
+++ b/doc/html/_sources/annotations.txt
@@ -0,0 +1,805 @@
+Annotations
+===========
+
+In this section we describe each of the annotations that can be used in
+specification files.
+
+Annotations can either be :ref:`argument annotations <ref-arg-annos>`,
+:ref:`class annotations <ref-class-annos>`, :ref:`mapped type annotations
+<ref-mapped-type-annos>`, :ref:`enum annotations <ref-enum-annos>`,
+:ref:`exception annotations <ref-exception-annos>`, :ref:`function annotations
+<ref-function-annos>`, :ref:`license annotations <ref-license-annos>`,
+:ref:`typedef annotations <ref-typedef-annos>` or :ref:`variable annotations
+<ref-variable-annos>` depending on the context in which they can be used.
+
+Annotations are placed between forward slashes (``/``). Multiple annotations
+are comma separated within the slashes.
+
+Annotations have a type and, possibly, a value. The type determines the
+format of the value. The name of an annotation and its value are separated by
+``=``.
+
+Annotations can have one of the following types:
+
+*boolean*
+ This type of annotation has no value and is implicitly true.
+
+*name*
+ The value is a name that is compatible with a C/C++ identifier. In some
+ cases the value is optional.
+
+*dotted name*
+ The value is a name that is compatible with an identifier preceded by a
+ Python scope.
+
+*string*
+ The value is a double quoted string.
+
+*API range*
+ The value is the name of an API (defined using the :directive:`%API`
+ directive) separated by a range of version numbers with a colon.
+
+ The range of version numbers is a pair of numbers separated by a hyphen
+ specifying the lower and upper bounds of the range. A version number is
+ within the range if it is greater or equal to the lower bound and less
+ than the upper bound. Each bound can be omitted meaning that the range is
+ unbounded in that direction.
+
+ For example::
+
+ # This is part of the PyQt4 API up to but excluding v2.
+ void hex() /API=PyQt4:-2/
+
+ # This is part of the PyQt4 API starting from v2.
+ void hex() /PyName=hex_, API=PyQt4:2-/
+
+The following example shows argument and function annotations::
+
+ void exec(QWidget * /Transfer/) /ReleaseGIL, PyName=call_exec/;
+
+Note that the current version of SIP does not complain about unknown
+annotations, or annotations used out of their correct context.
+
+
+.. _ref-arg-annos:
+
+Argument Annotations
+--------------------
+
+.. argument-annotation:: AllowNone
+
+ This boolean annotation specifies that the value of the corresponding
+ argument (which should be either :stype:`SIP_PYCALLABLE`,
+ :stype:`SIP_PYDICT`, :stype:`SIP_PYLIST`, :stype:`SIP_PYSLICE`,
+ :stype:`SIP_PYTUPLE` or :stype:`SIP_PYTYPE`) may be ``None``.
+
+
+.. argument-annotation:: Array
+
+ This boolean annotation specifies that the corresponding argument refers
+ to an array.
+
+ The argument should be either a pointer to a wrapped type, a ``char *`` or
+ a ``unsigned char *``. If the argument is a character array then the
+ annotation also implies the :aanno:`Encoding` annotation with an encoding
+ of ``"None"``.
+
+ There must be a corresponding argument with the :aanno:`ArraySize`
+ annotation specified. The annotation may only be specified once in a list
+ of arguments.
+
+
+.. argument-annotation:: ArraySize
+
+ This boolean annotation specifies that the corresponding argument (which
+ should be either ``short``, ``unsigned short``, ``int``, ``unsigned``,
+ ``long`` or ``unsigned long``) refers to the size of an array. There must
+ be a corresponding argument with the :aanno:`Array` annotation specified.
+ The annotation may only be specified once in a list of arguments.
+
+
+.. argument-annotation:: Constrained
+
+ Python will automatically convert between certain compatible types. For
+ example, if a floating pointer number is expected and an integer supplied,
+ then the integer will be converted appropriately. This can cause problems
+ when wrapping C or C++ functions with similar signatures. For example::
+
+ // The wrapper for this function will also accept an integer argument
+ // which Python will automatically convert to a floating point number.
+ void foo(double);
+
+ // The wrapper for this function will never get used.
+ void foo(int);
+
+ This boolean annotation specifies that the corresponding argument (which
+ should be either ``bool``, ``int``, ``float``, ``double``, ``enum`` or a
+ wrapped class) must match the type without any automatic conversions. In
+ the context of a wrapped class the invocation of any
+ :directive:`%ConvertToTypeCode` is suppressed.
+
+ The following example gets around the above problem::
+
+ // The wrapper for this function will only accept floating point
+ // numbers.
+ void foo(double /Constrained/);
+
+ // The wrapper for this function will be used for anything that Python
+ // can convert to an integer, except for floating point numbers.
+ void foo(int);
+
+
+.. argument-annotation:: DocType
+
+ .. versionadded:: 4.10
+
+ This string annotation specifies the type of the argument as it will appear
+ in any generated docstrings. It is usually used with arguments of type
+ :stype:`SIP_PYOBJECT` to provide a more specific type.
+
+
+.. argument-annotation:: DocValue
+
+ .. versionadded:: 4.10
+
+ This string annotation specifies the default value of the argument as it
+ will appear in any generated docstrings.
+
+
+.. argument-annotation:: Encoding
+
+ This string annotation specifies that the corresponding argument (which
+ should be either ``char``, ``const char``, ``char *`` or ``const char *``)
+ refers to an encoded character or ``'\0'`` terminated encoded string with
+ the specified encoding. The encoding can be either ``"ASCII"``,
+ ``"Latin-1"``, ``"UTF-8"`` or ``"None"``. An encoding of ``"None"`` means
+ that the corresponding argument refers to an unencoded character or string.
+
+ The default encoding is specified by the :directive:`%DefaultEncoding`
+ directive. If the directive is not specified then ``None`` is used.
+
+ Python v3 will use the ``bytes`` type to represent the argument if the
+ encoding is ``"None"`` and the ``str`` type otherwise.
+
+ Python v2 will use the ``str`` type to represent the argument if the
+ encoding is ``"None"`` and the ``unicode`` type otherwise.
+
+
+.. argument-annotation:: GetWrapper
+
+ This boolean annotation is only ever used in conjunction with handwritten
+ code specified with the :directive:`%MethodCode` directive. It causes an
+ extra variable to be generated for the corresponding argument which is a
+ pointer to the Python object that wraps the argument.
+
+ See the :directive:`%MethodCode` directive for more detail.
+
+
+.. argument-annotation:: In
+
+ This boolean annotation is used to specify that the corresponding argument
+ (which should be a pointer type) is used to pass a value to the function.
+
+ For pointers to wrapped C structures or C++ class instances, ``char *`` and
+ ``unsigned char *`` then this annotation is assumed unless the :aanno:`Out`
+ annotation is specified.
+
+ For pointers to other types then this annotation must be explicitly
+ specified if required. The argument will be dereferenced to obtain the
+ actual value.
+
+ Both :aanno:`In` and :aanno:`Out` may be specified for the same argument.
+
+
+.. argument-annotation:: KeepReference
+
+ This boolean annotation is used to specify that a reference to the
+ corresponding argument should be kept to ensure that the object is not
+ garbage collected. If the method is called again with a new argument then
+ the reference to the previous argument is discarded. Note that ownership
+ of the argument is not changed.
+
+
+.. argument-annotation:: NoCopy
+
+ .. versionadded:: 4.10.1
+
+ This boolean annotation is used with arguments of virtual methods that are
+ a ``const`` reference to a class. Normally, if the class defines a copy
+ constructor then a copy of the returned reference is automatically created
+ and wrapped before being passed to a Python reimplementation of the method.
+ The copy will be owned by Python. This means that the reimplementation may
+ take a reference to the argument without having to make an explicit copy.
+
+ If the annotation is specified then the copy is not made and the original
+ reference is wrapped instead and will be owned by C++.
+
+
+.. argument-annotation:: Out
+
+ This boolean annotation is used to specify that the corresponding argument
+ (which should be a pointer type) is used by the function to return a value
+ as an element of a tuple.
+
+ For pointers to wrapped C structures or C++ class instances, ``char *`` and
+ ``unsigned char *`` then this annotation must be explicitly specified if
+ required.
+
+ For pointers to other types then this annotation is assumed unless the
+ :aanno:`In` annotation is specified.
+
+ Both :aanno:`In` and :aanno:`Out` may be specified for the same argument.
+
+
+.. argument-annotation:: ResultSize
+
+ This boolean annotation is used with functions or methods that return a
+ ``void *`` or ``const void *``. It identifies an argument that defines the
+ size of the block of memory whose address is being returned. This allows
+ the ``sip.voidptr`` object that wraps the address to support the Python
+ buffer protocol and allows the memory to be read and updated when wrapped
+ by the Python ``buffer()`` builtin.
+
+
+.. argument-annotation:: SingleShot
+
+ This boolean annotation is used only with arguments of type
+ :stype:`SIP_RXOBJ_CON` to specify that the signal connected to the slot
+ will only ever be emitted once. This prevents a certain class of memory
+ leaks.
+
+
+.. argument-annotation:: Transfer
+
+ This boolean annotation is used to specify that ownership of the
+ corresponding argument (which should be a wrapped C structure or C++ class
+ instance) is transferred from Python to C++. In addition, if the argument
+ is of a class method, then it is associated with the class instance with
+ regard to the cyclic garbage collector.
+
+ See :ref:`ref-object-ownership` for more detail.
+
+
+.. argument-annotation:: TransferBack
+
+ This boolean annotation is used to specify that ownership of the
+ corresponding argument (which should be a wrapped C structure or C++ class
+ instance) is transferred back to Python from C++. In addition, any
+ association of the argument with regard to the cyclic garbage collector
+ with another instance is removed.
+
+ See :ref:`ref-object-ownership` for more detail.
+
+
+.. argument-annotation:: TransferThis
+
+ This boolean annotation is only used in C++ constructors or methods. In
+ the context of a constructor or factory method it specifies that ownership
+ of the instance being created is transferred from Python to C++ if the
+ corresponding argument (which should be a wrapped C structure or C++ class
+ instance) is not ``None``. In addition, the newly created instance is
+ associated with the argument with regard to the cyclic garbage collector.
+
+ In the context of a non-factory method it specifies that ownership of
+ ``this`` is transferred from Python to C++ if the corresponding argument is
+ not ``None``. If it is ``None`` then ownership is transferred to Python.
+
+ The annotation may be used more that once, in which case ownership is
+ transferred to last instance that is not ``None``.
+
+ See :ref:`ref-object-ownership` for more detail.
+
+
+.. _ref-class-annos:
+
+Class Annotations
+-----------------
+
+.. class-annotation:: Abstract
+
+ This boolean annotation is used to specify that the class has additional
+ pure virtual methods that have not been specified and so it cannot be
+ instantiated or sub-classed from Python.
+
+
+.. class-annotation:: AllowNone
+
+ .. versionadded:: 4.8.2
+
+ Normally when a Python object is converted to a C/C++ instance ``None``
+ is handled automatically before the class's
+ :directive:`%ConvertToTypeCode` is called. This boolean annotation
+ specifies that the handling of ``None`` will be left to the
+ :directive:`%ConvertToTypeCode`. The annotation is ignored if the class
+ does not have any :directive:`%ConvertToTypeCode`.
+
+
+.. class-annotation:: API
+
+ .. versionadded:: 4.9
+
+ This API range annotation is used to specify an API and corresponding
+ range of version numbers that the class is enabled for.
+
+ If a class or mapped type has different implementations enabled for
+ different ranges of version numbers then those ranges must not overlap.
+
+ See :ref:`ref-incompat-apis` for more detail.
+
+
+.. class-annotation:: DelayDtor
+
+ This boolean annotation is used to specify that the class's destructor
+ should not be called until the Python interpreter exits. It would normally
+ only be applied to singleton classes.
+
+ When the Python interpreter exits the order in which any wrapped instances
+ are garbage collected is unpredictable. However, the underlying C or C++
+ instances may need to be destroyed in a certain order. If this annotation
+ is specified then when the wrapped instance is garbage collected the C or
+ C++ instance is not destroyed but instead added to a list of delayed
+ instances. When the interpreter exits then the function
+ :cfunc:`sipDelayedDtors()` is called with the list of delayed instances.
+ :cfunc:`sipDelayedDtors()` can then choose to call (or ignore) the
+ destructors in any desired order.
+
+ The :cfunc:`sipDelayedDtors()` function must be specified using the
+ :directive:`%ModuleCode` directive.
+
+.. cfunction:: void sipDelayedDtors(const sipDelayedDtor *dd_list)
+
+ :param dd_list:
+ the linked list of delayed instances.
+
+.. ctype:: sipDelayedDtor
+
+ This structure describes a particular delayed destructor.
+
+ .. cmember:: const char *dd_name
+
+ This is the name of the class excluding any package or module name.
+
+ .. cmember:: void *dd_ptr
+
+ This is the address of the C or C++ instance to be destroyed. It's
+ exact type depends on the value of :cmember:`dd_isderived`.
+
+ .. cmember:: int dd_isderived
+
+ This is non-zero if the type of :cmember:`dd_ptr` is actually the
+ generated derived class. This allows the correct destructor to be
+ called. See :ref:`ref-derived-classes`.
+
+ .. cmember:: sipDelayedDtor *dd_next
+
+ This is the address of the next entry in the list or zero if this is
+ the last one.
+
+ Note that the above applies only to C and C++ instances that are owned by
+ Python.
+
+
+.. class-annotation:: Deprecated
+
+ This boolean annotation is used to specify that the class is deprecated.
+ It is the equivalent of annotating all the class's constructors, function
+ and methods as being deprecated.
+
+
+.. class-annotation:: External
+
+ This boolean annotation is used to specify that the class is defined in
+ another module. Declarations of external classes are private to the module
+ in which they appear.
+
+
+.. class-annotation:: Metatype
+
+ This dotted name annotation specifies the name of the Python type object
+ (i.e. the value of the ``tp_name`` field) used as the meta-type used when
+ creating the type object for this C structure or C++ type.
+
+ See the section :ref:`ref-types-metatypes` for more details.
+
+
+.. class-annotation:: NoDefaultCtors
+
+ This boolean annotation is used to suppress the automatic generation of
+ default constructors for the class.
+
+
+.. class-annotation:: PyName
+
+ This name annotation specifies an alternative name for the class being
+ wrapped which is used when it is referred to from Python. It is required
+ when a class name is the same as a Python keyword. It may also be used to
+ avoid name clashes with other objects (e.g. enums, exceptions, functions)
+ that have the same name in the same C++ scope.
+
+
+.. class-annotation:: Supertype
+
+ This dotted name annotation specifies the name of the Python type object
+ (i.e. the value of the ``tp_name`` field) used as the super-type used when
+ creating the type object for this C structure or C++ type.
+
+ See the section :ref:`ref-types-metatypes` for more details.
+
+
+.. _ref-mapped-type-annos:
+
+Mapped Type Annotations
+-----------------------
+
+.. mapped-type-annotation:: AllowNone
+
+ Normally when a Python object is converted to a C/C++ instance ``None``
+ is handled automatically before the mapped type's
+ :directive:`%ConvertToTypeCode` is called. This boolean annotation
+ specifies that the handling of ``None`` will be left to the
+ :directive:`%ConvertToTypeCode`.
+
+
+.. mapped-type-annotation:: API
+
+ .. versionadded:: 4.9
+
+ This API range annotation is used to specify an API and corresponding
+ range of version numbers that the mapped type is enabled for.
+
+ If a class or mapped type has different implementations enabled for
+ different ranges of version numbers then those ranges must not overlap.
+
+ See :ref:`ref-incompat-apis` for more detail.
+
+
+.. mapped-type-annotation:: DocType
+
+ .. versionadded:: 4.10
+
+ This string annotation specifies the name of the type as it will appear in
+ any generated docstrings.
+
+
+.. mapped-type-annotation:: NoRelease
+
+ This boolean annotation is used to specify that the mapped type does not
+ support the :cfunc:`sipReleaseType()` function. Any
+ :directive:`%ConvertToTypeCode` should not create temporary instances of
+ the mapped type, i.e. it should not return :cmacro:`SIP_TEMPORARY`.
+
+
+.. _ref-enum-annos:
+
+Enum Annotations
+----------------
+
+.. enum-annotation:: PyName
+
+ This name annotation specifies an alternative name for the enum or enum
+ member being wrapped which is used when it is referred to from Python. It
+ is required when an enum or enum member name is the same as a Python
+ keyword. It may also be used to avoid name clashes with other objects
+ (e.g. classes, exceptions, functions) that have the same name in the same
+ C++ scope.
+
+
+.. _ref-exception-annos:
+
+Exception Annotations
+---------------------
+
+.. exception-annotation:: Default
+
+ This boolean annotation specifies that the exception being defined will be
+ used as the default exception to be caught if a function or constructor
+ does not have a ``throw`` clause.
+
+.. exception-annotation:: PyName
+
+ This name annotation specifies an alternative name for the exception being
+ defined which is used when it is referred to from Python. It is required
+ when an exception name is the same as a Python keyword. It may also be
+ used to avoid name clashes with other objects (e.g. classes, enums,
+ functions) that have the same name.
+
+
+.. _ref-function-annos:
+
+Function Annotations
+--------------------
+
+.. function-annotation:: API
+
+ .. versionadded:: 4.9
+
+ This API range annotation is used to specify an API and corresponding
+ range of version numbers that the function is enabled for.
+
+ See :ref:`ref-incompat-apis` for more detail.
+
+
+.. function-annotation:: AutoGen
+
+ This optional name annotation is used with class methods to specify that
+ the method be automatically included in all sub-classes. The value is the
+ name of a feature (specified using the :directive:`%Feature` directive)
+ which must be enabled for the method to be generated.
+
+
+.. function-annotation:: Default
+
+ This boolean annotation is only used with C++ constructors. Sometimes SIP
+ needs to create a class instance. By default it uses a constructor with no
+ compulsory arguments if one is specified. (SIP will automatically generate
+ a constructor with no arguments if no constructors are specified.) This
+ annotation is used to explicitly specify which constructor to use. Zero is
+ passed as the value of any arguments to the constructor.
+
+
+.. function-annotation:: Deprecated
+
+ This boolean annotation is used to specify that the constructor or function
+ is deprecated. A deprecation warning is issued whenever the constructor or
+ function is called.
+
+
+.. function-annotation:: DocType
+
+ .. versionadded:: 4.10
+
+ This string annotation specifies the name of the type of the returned value
+ as it will appear in any generated docstrings. It is usually used with
+ values of type :stype:`SIP_PYOBJECT` to provide a more specific type.
+
+
+.. function-annotation:: Factory
+
+ This boolean annotation specifies that the value returned by the function
+ (which should be a wrapped C structure or C++ class instance) is a newly
+ created instance and is owned by Python.
+
+ See :ref:`ref-object-ownership` for more detail.
+
+
+.. function-annotation:: HoldGIL
+
+ This boolean annotation specifies that the Python Global Interpreter Lock
+ (GIL) is not released before the call to the underlying C or C++ function.
+ See :ref:`ref-gil` and the :fanno:`ReleaseGIL` annotation.
+
+
+.. function-annotation:: KeywordArgs
+
+ .. versionadded:: 4.10
+
+ This boolean annotation specifies that the argument parser generated for
+ this function will support passing the parameters using Python's keyword
+ argument syntax. Keyword arguments cannot be used for functions that have
+ unnamed arguments or use an ellipsis to designate that the function has a
+ variable number of arguments.
+
+
+.. function-annotation:: __len__
+
+ .. versionadded:: 4.10.3
+
+ This boolean annotation specifies that a ``__len__()`` method should be
+ automatically generated that will use the method being annotated to compute
+ the value that the ``__len__()`` method will return.
+
+
+.. function-annotation:: NewThread
+
+ This boolean annotation specifies that the function will create a new
+ thread.
+
+
+.. function-annotation:: NoArgParser
+
+ This boolean annotation is used with methods and global functions to
+ specify that the supplied :directive:`%MethodCode` will handle the parsing
+ of the arguments.
+
+
+.. function-annotation:: NoCopy
+
+ .. versionadded:: 4.10.1
+
+ This boolean annotation is used with methods and global functions that
+ return a ``const`` reference to a class. Normally, if the class defines a
+ copy constructor then a copy of the returned reference is automatically
+ created and wrapped. The copy will be owned by Python.
+
+ If the annotation is specified then the copy is not made and the original
+ reference is wrapped instead and will be owned by C++.
+
+
+.. function-annotation:: NoDerived
+
+ This boolean annotation is only used with C++ constructors. In many cases
+ SIP generates a derived class for each class being wrapped (see
+ :ref:`ref-derived-classes`). This derived class contains constructors with
+ the same C++ signatures as the class being wrapped. Sometimes you may want
+ to define a Python constructor that has no corresponding C++ constructor.
+ This annotation is used to suppress the generation of the constructor in
+ the derived class.
+
+
+.. function-annotation:: NoKeywordArgs
+
+ .. versionadded:: 4.10
+
+ This boolean annotation specifies that the argument parser generated for
+ this function will not support passing the parameters using Python's
+ keyword argument syntax. In other words, the argument parser will only
+ support only normal positional arguments. This annotation is useful when
+ the default setting of allowing keyword arguments has been changed via the
+ command line, but you would still like certain functions to only support
+ positional arguments.
+
+
+.. function-annotation:: Numeric
+
+ This boolean annotation specifies that the operator should be interpreted
+ as a numeric operator rather than a sequence operator. Python uses the
+ ``+`` operator for adding numbers and concatanating sequences, and the
+ ``*`` operator for multiplying numbers and repeating sequences. SIP tries
+ to work out which is meant by looking at other operators that have been
+ defined for the type. If it finds either ``-``, ``-=``, ``/``, ``/=``,
+ ``%`` or ``%=`` defined then it assumes that ``+``, ``+=``, ``*`` and
+ ``*=`` should be numeric operators. Otherwise, if it finds either ``[]``,
+ :meth:`__getitem__`, :meth:`__setitem__` or :meth:`__delitem__` defined
+ then it assumes that they should be sequence operators. This annotation is
+ used to force SIP to treat the operator as numeric.
+
+
+.. function-annotation:: PostHook
+
+ This name annotation is used to specify the name of a Python builtin that
+ is called immediately after the call to the underlying C or C++ function or
+ any handwritten code. The builtin is not called if an error occurred. It
+ is primarily used to integrate with debuggers.
+
+
+.. function-annotation:: PreHook
+
+ This name annotation is used to specify the name of a Python builtin that
+ is called immediately after the function's arguments have been successfully
+ parsed and before the call to the underlying C or C++ function or any
+ handwritten code. It is primarily used to integrate with debuggers.
+
+
+.. function-annotation:: PyName
+
+ This name annotation specifies an alternative name for the function being
+ wrapped which is used when it is referred to from Python. It is required
+ when a function or method name is the same as a Python keyword. It may
+ also be used to avoid name clashes with other objects (e.g. classes, enums,
+ exceptions) that have the same name in the same C++ scope.
+
+
+.. function-annotation:: ReleaseGIL
+
+ This boolean annotation specifies that the Python Global Interpreter Lock
+ (GIL) is released before the call to the underlying C or C++ function and
+ reacquired afterwards. It should be used for functions that might block or
+ take a significant amount of time to execute. See :ref:`ref-gil` and the
+ :fanno:`HoldGIL` annotation.
+
+
+.. function-annotation:: Transfer
+
+ This boolean annotation specifies that ownership of the value returned by
+ the function (which should be a wrapped C structure or C++ class instance)
+ is transferred to C++. It is only used in the context of a class
+ constructor or a method.
+
+ In the case of methods returned values (unless they are new references to
+ already wrapped values) are normally owned by C++ anyway. However, in
+ addition, an association between the returned value and the instance
+ containing the method is created with regard to the cyclic garbage
+ collector.
+
+ See :ref:`ref-object-ownership` for more detail.
+
+
+.. function-annotation:: TransferBack
+
+ This boolean annotation specifies that ownership of the value returned by
+ the function (which should be a wrapped C structure or C++ class instance)
+ is transferred back to Python from C++. Normally returned values (unless
+ they are new references to already wrapped values) are owned by C++. In
+ addition, any association of the returned value with regard to the cyclic
+ garbage collector with another instance is removed.
+
+ See :ref:`ref-object-ownership` for more detail.
+
+
+.. function-annotation:: TransferThis
+
+ This boolean annotation specifies that ownership of ``this`` is transferred
+ from Python to C++.
+
+ See :ref:`ref-object-ownership` for more detail.
+
+
+.. _ref-license-annos:
+
+License Annotations
+-------------------
+
+.. license-annotation:: Licensee
+
+ This optional string annotation specifies the license's licensee. No
+ restrictions are placed on the contents of the string.
+
+ See the :directive:`%License` directive.
+
+
+.. license-annotation:: Signature
+
+ This optional string annotation specifies the license's signature. No
+ restrictions are placed on the contents of the string.
+
+ See the :directive:`%License` directive.
+
+
+.. license-annotation:: Timestamp
+
+ This optional string annotation specifies the license's timestamp. No
+ restrictions are placed on the contents of the string.
+
+ See the :directive:`%License` directive.
+
+
+.. license-annotation:: Type
+
+ This string annotation specifies the license's type. No restrictions are
+ placed on the contents of the string.
+
+ See the :directive:`%License` directive.
+
+
+.. _ref-typedef-annos:
+
+Typedef Annotations
+-------------------
+
+.. typedef-annotation:: NoTypeName
+
+ This boolean annotation specifies that the definition of the type rather
+ than the name of the type being defined should be used in the generated
+ code.
+
+ Normally a typedef would be defined as follows::
+
+ typedef bool MyBool;
+
+ This would result in ``MyBool`` being used in the generated code.
+
+ Specifying the annotation means that ``bool`` will be used in the generated
+ code instead.
+
+
+.. _ref-variable-annos:
+
+Variable Annotations
+--------------------
+
+.. variable-annotation:: DocType
+
+ .. versionadded:: 4.10
+
+ This string annotation specifies the name of the type of the variable as it
+ will appear in any generated docstrings. It is usually used with variables
+ of type :stype:`SIP_PYOBJECT` to provide a more specific type.
+
+
+.. variable-annotation:: PyName
+
+ This name annotation specifies an alternative name for the variable being
+ wrapped which is used when it is referred to from Python. It is required
+ when a variable name is the same as a Python keyword. It may also be used
+ to avoid name clashes with other objects (e.g. classes, functions) that
+ have the same name in the same C++ scope.
diff --git a/doc/html/_sources/build_system.txt b/doc/html/_sources/build_system.txt
new file mode 100644
index 0000000..292836a
--- /dev/null
+++ b/doc/html/_sources/build_system.txt
@@ -0,0 +1,843 @@
+.. _ref-build-system:
+
+The Build System
+================
+
+.. module:: sipconfig
+
+The purpose of the build system is to make it easy for you to write
+configuration scripts in Python for your own bindings. The build system takes
+care of the details of particular combinations of platform and compiler. It
+supports over 50 different platform/compiler combinations.
+
+The build system is implemented as a pure Python module called :mod:`sipconfig`
+that contains a number of classes and functions. Using this module you can
+write bespoke configuration scripts (e.g. PyQt's ``configure.py``) or use it
+with other Python based build systems (e.g.
+`Distutils <http://www.python.org/sigs/distutils-sig/distutils.html>`_ and
+`SCons <http://www.scons.org>`_).
+
+An important feature of SIP is the ability to generate bindings that are built
+on top of existing bindings. For example, both
+`PyKDE <http://www.riverbankcomputing.com/software/pykde/>`_ and
+`PyQwt <http://pyqwt.sourceforge.net/>`_ are built on top of PyQt but all three
+packages are maintained by different developers. To make this easier PyQt
+includes its own configuration module, ``pyqtconfig``, that contains additional
+classes intended to be used by the configuration scripts of bindings built on
+top of PyQt. The SIP build system includes facilities that do a lot of the
+work of creating these additional configuration modules.
+
+
+.. function:: create_config_module(module, template, content[, macros=None])
+
+ This creates a configuration module (e.g. ``pyqtconfig``) from a template
+ file and a string.
+
+ :param module:
+ the name of the configuration module file to create.
+ :param template:
+ the name of the template file.
+ :param content:
+ a string which replaces every occurence of the pattern
+ ``@SIP_CONFIGURATION@`` in the template file. The content string is
+ usually created from a Python dictionary using
+ :func:`sipconfig.create_content()`. *content* may also be a
+ dictionary, in which case :func:`sipconfig.create_content()` is
+ automatically called to convert it to a string.
+ :param macros:
+ an optional dictionary of platform specific build macros. It is only
+ used if :func:`sipconfig.create_content()` is called automatically to
+ convert a *content* dictionary to a string.
+
+
+.. function:: create_content(dict[, macros=None]) -> string
+
+ This converts a Python dictionary to a string that can be parsed by the
+ Python interpreter and converted back to an equivalent dictionary. It is
+ typically used to generate the content string for
+ :func:`sipconfig.create_config_module()`.
+
+ :param dict:
+ the Python dictionary to convert.
+ :param macros:
+ the optional dictionary of platform specific build macros.
+ :return:
+ the string representation of the dictionary.
+
+
+.. function:: create_wrapper(script, wrapper[, gui=0[, use_arch='']]) -> string
+
+ This creates a platform dependent executable wrapper around a Python
+ script.
+
+ :param script:
+ the full pathname of the script.
+ :param wrapper:
+ the full pathname of the wrapper to create, excluding any platform
+ specific extension.
+ :param gui:
+ is non-zero if a GUI enabled version of the interpreter should be used
+ on platforms that require it.
+ :param use_arch:
+ is the MacOS/X architecture to invoke python with.
+ :return:
+ the platform specific name of the wrapper.
+
+
+.. function:: error(msg)
+
+ This displays an error message on ``stderr`` and calls ``sys.exit(1)``.
+
+ :param msg:
+ the text of the message and should not include any newline characters.
+
+
+.. function:: format(msg[, leftmargin=0[, rightmargin=78]]) -> string
+
+ This formats a message by inserting newline characters at appropriate
+ places.
+
+ :param msg:
+ the text of the message and should not include any newline characters.
+ :param leftmargin:
+ the optional position of the left margin.
+ :param rightmargin:
+ the optional position of the right margin.
+ :return:
+ the formatted message.
+
+
+.. function:: inform(msg)
+
+ This displays an information message on ``stdout``.
+
+ :param msg:
+ the text of the message and should not include any newline characters.
+
+
+.. function:: parse_build_macros(filename, names[, overrides=None[, properties=None]]) -> dict
+
+ This parses a ``qmake`` compatible file of build system macros and converts
+ it to a dictionary. A macro is a name/value pair. Individual macros may
+ be augmented or replaced.
+
+ :param filename:
+ the name of the file to parse.
+ :param names:
+ the list of the macro names to extract from the file.
+ :param overrides:
+ the optional list of macro names and values that modify those found in
+ the file. They are of the form ``name=value`` (in which case the value
+ replaces the value found in the file) or ``name+=value`` (in which case
+ the value is appended to the value found in the file).
+ :param properties:
+ the optional dictionary of property name and values that are used to
+ resolve any expressions of the form ``$[name]`` in the file.
+ :return:
+ the dictionary of parsed macros or ``None`` if any of the overrides
+ were invalid.
+
+
+.. function:: read_version(filename, description[, numdefine=None[, strdefine=None]]) -> integer, string
+
+ This extracts version information for a package from a file, usually a C or
+ C++ header file. The version information must each be specified as a
+ ``#define`` of a numeric (hexadecimal or decimal) value and/or a string
+ value.
+
+ :param filename:
+ the name of the file to read.
+ :param description:
+ a descriptive name of the package used in error messages.
+ :param numdefine:
+ the optional name of the ``#define`` of the version as a number. If it
+ is ``None`` then the numeric version is ignored.
+ :param strdefine:
+ the optional name of the ``#define`` of the version as a string. If it
+ is ``None`` then the string version is ignored.
+ :return:
+ a tuple of the numeric and string versions. :func:`sipconfig.error()`
+ is called if either were required but could not be found.
+
+
+.. function:: version_to_sip_tag(version, tags, description) -> string
+
+ This converts a version number to a SIP version tag. SIP uses the
+ :directive:`%Timeline` directive to define the chronology of the different
+ versions of the C/C++ library being wrapped. Typically it is not necessary
+ to define a version tag for every version of the library, but only for
+ those versions that affect the library's API as SIP sees it.
+
+ :param version:
+ the numeric version number of the C/C++ library being wrapped. If it
+ is negative then the latest version is assumed. (This is typically
+ useful if a snapshot is indicated by a negative version number.)
+ :param tags:
+ the dictionary of SIP version tags keyed by the corresponding C/C++
+ library version number. The tag used is the one with the smallest key
+ (i.e. earliest version) that is greater than *version*.
+ :param description:
+ a descriptive name of the C/C++ library used in error messages.
+ :return:
+ the SIP version tag. :func:`sipconfig.error()` is called if the C/C++
+ library version number did not correspond to a SIP version tag.
+
+
+.. function:: version_to_string(v) -> string
+
+ This converts a 3 part version number encoded as a hexadecimal value to a
+ string.
+
+ :param v:
+ the version number.
+ :return:
+ a string.
+
+
+.. class:: Configuration
+
+ This class encapsulates configuration values that can be accessed as
+ instance objects. A sub-class may provide a dictionary of additional
+ configuration values in its constructor the elements of which will have
+ precedence over the super-class's values.
+
+ The following configuration values are provided:
+
+ .. attribute:: default_bin_dir
+
+ The name of the directory where executables should be installed by
+ default.
+
+ .. attribute:: default_mod_dir
+
+ The name of the directory where SIP generated modules should be
+ installed by default.
+
+ .. attribute:: default_sip_dir
+
+ The name of the base directory where the ``.sip`` files for SIP
+ generated modules should be installed by default. A sub-directory with
+ the same name as the module should be created and its ``.sip`` files
+ should be installed in the sub-directory. The ``.sip`` files only need
+ to be installed if you might want to build other bindings based on
+ them.
+
+ .. attribute:: platform
+
+ The name of the platform/compiler for which the build system has been
+ configured for.
+
+ .. attribute:: py_conf_inc_dir
+
+ The name of the directory containing the ``pyconfig.h`` header file.
+
+ .. attribute:: py_inc_dir
+
+ The name of the directory containing the ``Python.h`` header file.
+
+ .. attribute:: py_lib_dir
+
+ The name of the directory containing the Python interpreter library.
+
+ .. attribute:: py_version
+
+ The Python version as a 3 part hexadecimal number (e.g. v2.3.3 is
+ represented as ``0x020303``).
+
+ .. attribute:: sip_bin
+
+ The full pathname of the SIP executable.
+
+ .. attribute:: sip_config_args
+
+ The command line passed to ``configure.py`` when SIP was configured.
+
+ .. attribute:: sip_inc_dir
+
+ The name of the directory containing the ``sip.h`` header file.
+
+ .. attribute:: sip_mod_dir
+
+ The name of the directory containing the SIP module.
+
+ .. attribute:: sip_version
+
+ The SIP version as a 3 part hexadecimal number (e.g. v4.0.0 is
+ represented as ``0x040000``).
+
+ .. attribute:: sip_version_str
+
+ The SIP version as a string. For development snapshots it will start
+ with ``snapshot-``.
+
+ .. attribute:: universal
+
+ The name of the MacOS/X SDK used when creating universal binaries.
+
+ .. attribute:: arch
+
+ The space separated MacOS/X architectures to build.
+
+ .. method:: __init__([sub_cfg=None])
+
+ :param sub_cfg:
+ an optional list of sub-class configurations. It should only be
+ used by the ``__init__()`` method of a sub-class to append its own
+ dictionary of configuration values before passing the list to its
+ super-class.
+
+ .. method:: build_macros() -> dict
+
+ Get the dictionary of platform specific build macros.
+
+ :return:
+ the macros dictionary.
+
+ .. method:: set_build_macros(macros)
+
+ Set the dictionary of platform specific build macros to be used when
+ generating Makefiles. Normally there is no need to change the default
+ macros.
+
+ :param macros:
+ the macros dictionary.
+
+
+.. class:: Makefile
+
+ This class encapsulates a Makefile. It is intended to be sub-classed to
+ generate Makefiles for particular purposes. It handles all platform and
+ compiler specific flags, but allows them to be adjusted to suit the
+ requirements of a particular module or program. These are defined using a
+ number of macros which can be accessed as instance attributes.
+
+ The following instance attributes are provided to help in fine tuning the
+ generated Makefile:
+
+ .. attribute:: chkdir
+
+ A string that will check for the existence of a directory.
+
+ .. attribute:: config
+
+ A reference to the *configuration* argument that was passed to
+ :meth:`Makefile.__init__`.
+
+ .. attribute:: console
+
+ A reference to the *console* argument that was passed to the
+ :meth:`Makefile.__init__`.
+
+ .. attribute:: copy
+
+ A string that will copy a file.
+
+ .. attribute:: extra_cflags
+
+ A list of additional flags passed to the C compiler.
+
+ .. attribute:: extra_cxxflags
+
+ A list of additional flags passed to the C++ compiler.
+
+ .. attribute:: extra_defines
+
+ A list of additional macro names passed to the C/C++ preprocessor.
+
+ .. attribute:: extra_include_dirs
+
+ A list of additional include directories passed to the C/C++
+ preprocessor.
+
+ .. attribute:: extra_lflags
+
+ A list of additional flags passed to the linker.
+
+ .. attribute:: extra_lib_dirs
+
+ A list of additional library directories passed to the linker.
+
+ .. attribute:: extra_libs
+
+ A list of additional libraries passed to the linker. The names of the
+ libraries must be in platform neutral form (i.e. without any platform
+ specific prefixes, version numbers or extensions).
+
+ .. attribute:: generator
+
+ A string that defines the platform specific style of Makefile. The
+ only supported values are ``UNIX``, ``MSVC``, ``MSVC.NET``, ``MINGW``
+ and ``BMAKE``.
+
+ .. attribute:: mkdir
+
+ A string that will create a directory.
+
+ .. attribute:: rm
+
+ A string that will remove a file.
+
+ .. method:: __init__(configuration[, console=0[, qt=0[, opengl=0[, python=0[, threaded=0[, warnings=None[, debug=0[, dir=None[, makefile="Makefile"[, installs=None[, universal=None[, arch=None]]]]]]]]]]]])
+
+ :param configuration:
+ the current configuration and is an instance of the
+ :class:`Configuration` class or a sub-class.
+ :param console:
+ is set if the target is a console (rather than GUI) target. This
+ only affects Windows and is ignored on other platforms.
+ :param qt:
+ is set if the target uses Qt. For Qt v4 a list of Qt libraries may
+ be specified and a simple non-zero value implies QtCore and QtGui.
+ :param opengl:
+ is set if the target uses OpenGL.
+ :param python:
+ is set if the target uses Python.h.
+ :param threaded:
+ is set if the target requires thread support. It is set
+ automatically if the target uses Qt and Qt has thread support
+ enabled.
+ :param warnings:
+ is set if compiler warning messages should be enabled. The default
+ of ``None`` means that warnings are enabled for SIP v4.x and
+ disabled for SIP v3.x.
+ :param debug:
+ is set if debugging symbols should be generated.
+ :param dir:
+ the name of the directory where build files are read from (if they
+ are not absolute file names) and Makefiles are written to. The
+ default of ``None`` means the current directory is used.
+ :param makefile:
+ the name of the generated Makefile.
+ :param installs:
+ the list of extra install targets. Each element is a two part
+ list, the first of which is the source and the second is the
+ destination. If the source is another list then it is a list of
+ source files and the destination is a directory.
+ :param universal:
+ the name of the SDK if universal binaries are to be created under
+ MacOS/X. If it is ``None`` then the value is taken from the
+ configuration.
+ :param arch:
+ the space separated MacOS/X architectures to build. If it is
+ ``None`` then the value is taken from the configuration.
+
+ .. method:: clean_build_file_objects(mfile, build)
+
+ This generates the Makefile commands that will remove any files
+ generated during the build of the default target.
+
+ :param mfile:
+ the Python file object of the Makefile.
+ :param build:
+ the dictionary created from parsing the build file.
+
+ .. method:: finalise()
+
+ This is called just before the Makefile is generated to ensure that it
+ is fully configured. It must be reimplemented by a sub-class.
+
+ .. method:: generate()
+
+ This generates the Makefile.
+
+ .. method:: generate_macros_and_rules(mfile)
+
+ This is the default implementation of the Makefile macros and rules
+ generation.
+
+ :param mfile:
+ the Python file object of the Makefile.
+
+ .. method:: generate_target_clean(mfile)
+
+ This is the default implementation of the Makefile clean target
+ generation.
+
+ :param mfile:
+ the Python file object of the Makefile.
+
+ .. method:: generate_target_default(mfile)
+
+ This is the default implementation of the Makefile default target
+ generation.
+
+ :param mfile:
+ the Python file object of the Makefile.
+
+ .. method:: generate_target_install(mfile)
+
+ This is the default implementation of the Makefile install target
+ generation.
+
+ :param mfile:
+ the Python file object of the Makefile.
+
+ .. method:: install_file(mfile, src, dst[, strip=0])
+
+ This generates the Makefile commands to install one or more files to a
+ directory.
+
+ :param mfile:
+ the Python file object of the Makefile.
+ :param src:
+ the name of a single file to install or a list of a number of files
+ to install.
+ :param dst:
+ the name of the destination directory.
+ :param strip:
+ is set if the files should be stripped of unneeded symbols after
+ having been installed.
+
+ .. method:: optional_list(name) -> list
+
+ This returns an optional Makefile macro as a list.
+
+ :param name:
+ the name of the macro.
+ :return:
+ the macro as a list.
+
+ .. method:: optional_string(name[, default=""])
+
+ This returns an optional Makefile macro as a string.
+
+ :param name:
+ the name of the macro.
+ :param default:
+ the optional default value of the macro.
+ :return:
+ the macro as a string.
+
+ .. method:: parse_build_file(filename) -> dict
+
+ This parses a build file (created with the :option:`-b <sip -b>` SIP
+ command line option) and converts it to a dictionary. It can also
+ validate an existing dictionary created through other means.
+
+ :param filename: is the name of the build file, or is a dictionary to
+ be validated. A valid dictionary will contain the name of the
+ target to build (excluding any platform specific extension) keyed
+ by ``target``; the names of all source files keyed by ``sources``;
+ and, optionally, the names of all header files keyed by
+ ``headers``.
+ :return:
+ a dictionary corresponding to the parsed build file.
+
+ .. method:: platform_lib(clib[, framework=0]) -> string
+
+ This converts a library name to a platform specific form.
+
+ :param clib:
+ the name of the library in cannonical form.
+ :param framework:
+ is set if the library is implemented as a MacOS framework.
+ :return:
+ the platform specific name.
+
+ .. method:: ready()
+
+ This is called to ensure that the Makefile is fully configured. It is
+ normally called automatically when needed.
+
+ .. method:: required_string(name) -> string
+
+ This returns a required Makefile macro as a string.
+
+ :param name:
+ the name of the macro.
+ :return:
+ the macro as a string. An exception is raised if the macro does
+ not exist or has an empty value.
+
+
+.. class:: ModuleMakefile
+
+ This class is derived from :class:`sipconfig.Makefile`.
+
+ This class encapsulates a Makefile to build a generic Python extension
+ module.
+
+ .. method:: __init__(self, configuration, build_file[, install_dir=None[, static=0[, console=0[, opengl=0[, threaded=0[, warnings=None[, debug=0[, dir=None[, makefile="Makefile"[, installs=None[, strip=1[, export_all=0[, universal=None[, arch=None]]]]]]]]]]]]]])
+
+ :param configuration:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param build_file:
+ the name of the build file. Build files are generated using the
+ :option:`-b <sip -b>` SIP command line option.
+ :param install_dir:
+ the name of the directory where the module will be optionally
+ installed.
+ :param static:
+ is set if the module should be built as a static library (see
+ :ref:`ref-builtin`).
+ :param console:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param qt:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param opengl:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param threaded:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param warnings:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param debug:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param dir:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param makefile:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param installs:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param strip:
+ is set if the module should be stripped of unneeded symbols after
+ installation. It is ignored if either *debug* or *static* is set,
+ or if the platform doesn't support it.
+ :param export_all:
+ is set if all of the module's symbols should be exported rather
+ than just the module's initialisation function. Exporting all
+ symbols increases the size of the module and slows down module load
+ times but may avoid problems with modules that use C++ exceptions.
+ All symbols are exported if either *debug* or *static* is set, or
+ if the platform doesn't support it.
+ :param universal:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param arch:
+ see :meth:`sipconfig.Makefile.__init__`.
+
+ .. method:: finalise()
+
+ This is a reimplementation of :meth:`sipconfig.Makefile.finalise`.
+
+ .. method:: generate_macros_and_rules(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_macros_and_rules`.
+
+ .. method:: generate_target_clean(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_target_clean`.
+
+ .. method:: generate_target_default(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_target_default`.
+
+ .. method:: generate_target_install(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_target_install`.
+
+ .. method:: module_as_lib(mname) -> string
+
+ This gets the name of a SIP v3.x module for when it is used as a
+ library to be linked against. An exception will be raised if it is
+ used with SIP v4.x modules.
+
+ :param mname:
+ the name of the module.
+ :return:
+ the corresponding library name.
+
+
+.. class:: ParentMakefile
+
+ This class is derived from :class:`sipconfig.Makefile`.
+
+ This class encapsulates a Makefile that sits above a number of other
+ Makefiles in sub-directories.
+
+ .. method:: __init__(self, configuration, subdirs[, dir=None[, makefile[="Makefile"[, installs=None]]]])
+
+ :param configuration:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param subdirs:
+ the sequence of sub-directories.
+ :param dir:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param makefile:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param installs:
+ see :meth:`sipconfig.Makefile.__init__`.
+
+ .. method:: generate_macros_and_rules(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_macros_and_rules`.
+
+ .. method:: generate_target_clean(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_target_clean`.
+
+ .. method:: generate_target_default(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_target_default`.
+
+ .. method:: generate_target_install(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_target_install`.
+
+.. class:: ProgramMakefile
+
+ This class is derived from :class:`sipconfig.Makefile`.
+
+ This class encapsulates a Makefile to build an executable program.
+
+ .. method:: __init__(configuration[, build_file=None[, install_dir=None[, console=0[, qt=0[, opengl=0[, python=0[, threaded=0[, warnings=None[, debug=0[, dir=None[, makefile="Makefile"[, installs=None[, universal=None[, arch=None]]]]]]]]]]]]]])
+
+ :param configuration:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param build_file:
+ the name of the optional build file. Build files are generated
+ using the :option:`-b <sip -b>` SIP command line option.
+ :param install_dir:
+ the name of the directory where the executable program will be
+ optionally installed.
+ :param console:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param qt:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param opengl:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param python:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param threaded:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param warnings:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param debug:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param dir:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param makefile:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param installs:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param universal:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param arch:
+ see :meth:`sipconfig.Makefile.__init__`.
+
+ .. method:: build_command(source) -> string, string
+
+ This creates a single command line that will create an executable
+ program from a single source file.
+
+ :param source:
+ the name of the source file.
+ :return:
+ a tuple of the name of the executable that will be created and the
+ command line.
+
+ .. method:: finalise()
+
+ This is a reimplementation of :meth:`sipconfig.Makefile.finalise`.
+
+ .. method:: generate_macros_and_rules(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_macros_and_rules`.
+
+ .. method:: generate_target_clean(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_target_clean`.
+
+ .. method:: generate_target_default(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_target_default`.
+
+ .. method:: generate_target_install(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_target_install`.
+
+
+.. class:: PythonModuleMakefile
+
+ This class is derived from :class:`sipconfig.Makefile`.
+
+ This class encapsulates a Makefile that installs a pure Python module.
+
+ .. method:: __init__(self, configuration, dstdir[, srcdir=None[, dir=None[, makefile="Makefile"[, installs=None]]]])
+
+ :param configuration:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param dstdir:
+ the name of the directory in which the module's Python code will be
+ installed.
+ :param srcdir:
+ the name of the directory (relative to *dir*) containing the
+ module's Python code. It defaults to the same directory.
+ :param dir:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param makefile:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param installs:
+ see :meth:`sipconfig.Makefile.__init__`.
+
+ .. method:: generate_macros_and_rules(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_macros_and_rules`.
+
+ .. method:: generate_target_install(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_target_install`.
+
+
+.. class:: SIPModuleMakefile
+
+ This class is derived from :class:`sipconfig.ModuleMakefile`.
+
+ This class encapsulates a Makefile to build a SIP generated Python
+ extension module.
+
+ .. method:: __init__(self, configuration, build_file[, install_dir=None[, static=0[, console=0[, opengl=0[, threaded=0[, warnings=None[, debug=0[, dir=None[, makefile="Makefile"[, installs=None[, strip=1[, export_all=0[, universal=None[, arch=None[, prot_is_public=0]]]]]]]]]]]]]]])
+
+ :param configuration:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param build_file:
+ see :meth:`sipconfig.ModuleMakefile.__init__`.
+ :param install_dir:
+ see :meth:`sipconfig.ModuleMakefile.__init__`.
+ :param static:
+ see :meth:`sipconfig.ModuleMakefile.__init__`.
+ :param console:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param qt:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param opengl:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param threaded:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param warnings:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param debug:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param dir:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param makefile:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param installs:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param strip:
+ see :meth:`sipconfig.ModuleMakefile.__init__`.
+ :param export_all:
+ see :meth:`sipconfig.ModuleMakefile.__init__`.
+ :param universal:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param arch:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param prot_is_public:
+ is set if ``protected`` should be redefined as ``public`` when
+ compiling the generated module.
+
+ .. method:: finalise()
+
+ This is a reimplementation of :meth:`sipconfig.Makefile.finalise`.
diff --git a/doc/html/_sources/builtin.txt b/doc/html/_sources/builtin.txt
new file mode 100644
index 0000000..58c7019
--- /dev/null
+++ b/doc/html/_sources/builtin.txt
@@ -0,0 +1,50 @@
+.. _ref-builtin:
+
+Builtin Modules and Custom Interpreters
+=======================================
+
+Sometimes you want to create a custom Python interpreter with some modules
+built in to the interpreter itself rather than being dynamically loaded. To
+do this the module must be created as a static library and linked with a
+custom stub and the normal Python library.
+
+To build the SIP module as a static library you must pass the ``-k`` command
+line option to ``configure.py``. You should then build and install SIP as
+normal. (Note that, because the module is now a static library, you will not
+be able to import it.)
+
+To build a module you have created for your own library you must modify your
+own configuration script to pass a non-zero value as the ``static`` argument
+of the ``__init__()`` method of the :class:`sipconfig.ModuleMakefile` class (or
+any derived class you have created). Normally you would make this configurable
+using a command line option in the same way that SIP's ``configure.py`` handles
+it.
+
+The next stage is to create a custom stub and a Makefile. The SIP distribution
+contains a directory called ``custom`` which contains example stubs and a
+Python script that will create a correct Makefile. Note that, if your copy of
+SIP was part of a standard Linux distribution, the ``custom`` directory may
+not be installed on your system.
+
+The ``custom`` directory contains the following files. They are provided as
+examples - each needs to be modified according to your particular
+requirements.
+
+ - ``mkcustom.py`` is a Python script that will create a Makefile which is
+ then used to build the custom interpreter. Comments in the file describe
+ how it should be modified.
+
+ - ``custom.c`` is a stub for a custom interpreter on Linux/UNIX. It
+ should also be used for a custom console interpreter on Windows (i.e.
+ like ``python.exe``). Comments in the file describe how it should be
+ modified.
+
+ - ``customw.c`` is a stub for a custom GUI interpreter on Windows (i.e.
+ like ``pythonw.exe``). Comments in the file describe how it should be
+ modified.
+
+Note that this technique does not restrict how the interpreter can be used.
+For example, it still allows users to write their own applications that can
+import your builtin modules. If you want to prevent users from doing that,
+perhaps to protect a proprietary API, then take a look at the
+`VendorID <http://www.riverbankcomputing.com/software/vendorid/>`__ package.
diff --git a/doc/html/_sources/c_api.txt b/doc/html/_sources/c_api.txt
new file mode 100644
index 0000000..782056c
--- /dev/null
+++ b/doc/html/_sources/c_api.txt
@@ -0,0 +1,1721 @@
+.. _ref-c-api:
+
+C API for Handwritten Code
+==========================
+
+In this section we describe the API that can be used by handwritten code in
+specification files.
+
+
+.. cmacro:: SIP_API_MAJOR_NR
+
+ This is a C preprocessor symbol that defines the major number of the SIP
+ API. Its value is a number. There is no direct relationship between this
+ and the SIP version number.
+
+
+.. cmacro:: SIP_API_MINOR_NR
+
+ This is a C preprocessor symbol that defines the minor number of the SIP
+ API. Its value is a number. There is no direct relationship between this
+ and the SIP version number.
+
+
+.. cmacro:: SIP_BLOCK_THREADS
+
+ This is a C preprocessor macro that will make sure the Python Global
+ Interpreter Lock (GIL) is acquired. Python API calls must only be made
+ when the GIL has been acquired. There must be a corresponding
+ :cmacro:`SIP_UNBLOCK_THREADS` at the same lexical scope.
+
+
+.. cmacro:: SIP_NO_CONVERTORS
+
+ This is a flag used by various type convertors that suppresses the use of a
+ type's :directive:`%ConvertToTypeCode`.
+
+
+.. cmacro:: SIP_NOT_NONE
+
+ This is a flag used by various type convertors that causes the conversion
+ to fail if the Python object being converted is ``Py_None``.
+
+
+.. cmacro:: SIP_PROTECTED_IS_PUBLIC
+
+ .. versionadded:: 4.10
+
+ This is a C preprocessor macro that is set automatically by the build
+ system to specify that the generated code is being compiled with
+ ``protected`` redefined as ``public``. This allows handwritten code to
+ determine if the generated helper functions for accessing protected C++
+ functions are available (see :directive:`%MethodCode`).
+
+
+.. cmacro:: SIP_SSIZE_T
+
+ This is a C preprocessor macro that is defined as ``Py_ssize_t`` for Python
+ v2.5 and later, and as ``int`` for earlier versions of Python. It makes it
+ easier to write PEP 353 compliant handwritten code.
+
+
+.. cmacro:: SIP_UNBLOCK_THREADS
+
+ This is a C preprocessor macro that will restore the Python Global
+ Interpreter Lock (GIL) to the state it was prior to the corresponding
+ :cmacro:`SIP_BLOCK_THREADS`.
+
+
+.. cmacro:: SIP_VERSION
+
+ This is a C preprocessor symbol that defines the SIP version number
+ represented as a 3 part hexadecimal number (e.g. v4.0.0 is represented as
+ ``0x040000``).
+
+
+.. cmacro:: SIP_VERSION_STR
+
+ This is a C preprocessor symbol that defines the SIP version number
+ represented as a string. For development snapshots it will start with
+ ``snapshot-``.
+
+
+.. cfunction:: sipErrorState sipBadCallableArg(int arg_nr, PyObject *arg)
+
+ .. versionadded:: 4.10
+
+ This is called from :directive:`%MethodCode` to raise a Python exception
+ when an argument to a function, a C++ constructor or method is found to
+ have an unexpected type. This should be used when the
+ :directive:`%MethodCode` does additional type checking of the supplied
+ arguments.
+
+ :param arg_nr:
+ the number of the argument. Arguments are numbered from 0 but are
+ numbered from 1 in the detail of the exception.
+ :param arg:
+ the argument.
+ :return:
+ the value that should be assigned to ``sipError``.
+
+
+.. cfunction:: void sipBadCatcherResult(PyObject *method)
+
+ This raises a Python exception when the result of a Python reimplementation
+ of a C++ method doesn't have the expected type. It is normally called by
+ handwritten code specified with the :directive:`%VirtualCatcherCode`
+ directive.
+
+ :param method:
+ the Python method and would normally be the supplied ``sipMethod``.
+
+
+.. cfunction:: void sipBadLengthForSlice(SIP_SSIZE_T seqlen, SIP_SSIZE_T slicelen)
+
+ This raises a Python exception when the length of a slice object is
+ inappropriate for a sequence-like object. It is normally called by
+ handwritten code specified for :meth:`__setitem__` methods.
+
+ :param seqlen:
+ the length of the sequence.
+ :param slicelen:
+ the length of the slice.
+
+
+.. cfunction:: PyObject *sipBuildResult(int *iserr, const char *format, ...)
+
+ This creates a Python object based on a format string and associated
+ values in a similar way to the Python :cfunc:`Py_BuildValue()` function.
+
+ :param iserr:
+ if this is not ``NULL`` then the location it points to is set to a
+ non-zero value.
+ :param format:
+ the string of format characters.
+ :return:
+ If there was an error then ``NULL`` is returned and a Python exception
+ is raised.
+
+ If the format string begins and ends with parentheses then a tuple of
+ objects is created. If it contains more than one format character then
+ parentheses must be specified.
+
+ In the following description the first letter is the format character, the
+ entry in parentheses is the Python object type that the format character
+ will create, and the entry in brackets are the types of the C/C++ values
+ to be passed.
+
+ ``a`` (string) [char]
+ Convert a C/C++ ``char`` to a Python v2 or v3 string object.
+
+ ``b`` (boolean) [int]
+ Convert a C/C++ ``int`` to a Python boolean.
+
+ ``c`` (string/bytes) [char]
+ Convert a C/C++ ``char`` to a Python v2 string object or a Python v3
+ bytes object.
+
+ ``d`` (float) [double]
+ Convert a C/C++ ``double`` to a Python floating point number.
+
+ ``e`` (integer) [enum]
+ Convert an anonymous C/C++ ``enum`` to a Python integer.
+
+ ``f`` (float) [float]
+ Convert a C/C++ ``float`` to a Python floating point number.
+
+ ``g`` (string/bytes) [char \*, :cmacro:`SIP_SSIZE_T`]
+ Convert a C/C++ character array and its length to a Python v2 string
+ object or a Python v3 bytes object. If the array is ``NULL`` then the
+ length is ignored and the result is ``Py_None``.
+
+ ``h`` (integer) [short]
+ Convert a C/C++ ``short`` to a Python integer.
+
+ ``i`` (integer) [int]
+ Convert a C/C++ ``int`` to a Python integer.
+
+ ``l`` (long) [long]
+ Convert a C/C++ ``long`` to a Python integer.
+
+ ``m`` (long) [unsigned long]
+ Convert a C/C++ ``unsigned long`` to a Python long.
+
+ ``n`` (long) [long long]
+ Convert a C/C++ ``long long`` to a Python long.
+
+ ``o`` (long) [unsigned long long]
+ Convert a C/C++ ``unsigned long long`` to a Python long.
+
+ ``r`` (wrapped instance) [*type* \*, :cmacro:`SIP_SSIZE_T`, const :ctype:`sipTypeDef` \*]
+ Convert an array of C structures, C++ classes or mapped type instances
+ to a Python tuple. Note that copies of the array elements are made.
+
+ ``s`` (string/bytes) [char \*]
+ Convert a C/C++ ``'\0'`` terminated string to a Python v2 string object
+ or a Python v3 bytes object. If the string pointer is ``NULL`` then
+ the result is ``Py_None``.
+
+ ``t`` (long) [unsigned short]
+ Convert a C/C++ ``unsigned short`` to a Python long.
+
+ ``u`` (long) [unsigned int]
+ Convert a C/C++ ``unsigned int`` to a Python long.
+
+ ``w`` (unicode/string) [wchar_t]
+ Convert a C/C++ wide character to a Python v2 unicode object or a
+ Python v3 string object.
+
+ ``x`` (unicode/string) [wchar_t \*]
+ Convert a C/C++ ``L'\0'`` terminated wide character string to a Python
+ v2 unicode object or a Python v3 string object. If the string pointer
+ is ``NULL`` then the result is ``Py_None``.
+
+ ``A`` (string) [char \*]
+ Convert a C/C++ ``'\0'`` terminated string to a Python v2 or v3 string
+ object. If the string pointer is ``NULL`` then the result is
+ ``Py_None``.
+
+ ``B`` (wrapped instance) [*type* \*, :ctype:`sipWrapperType` \*, PyObject \*]
+ Convert a new C structure or a new C++ class instance to a Python class
+ instance object. Ownership of the structure or instance is determined
+ by the ``PyObject *`` argument. If it is ``NULL`` and the instance has
+ already been wrapped then the ownership is unchanged. If it is
+ ``NULL`` or ``Py_None`` then ownership will be with Python. Otherwise
+ ownership will be with C/C++ and the instance associated with the
+ ``PyObject *`` argument. The Python class is influenced by any
+ applicable :directive:`%ConvertToSubClassCode` code.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use ``N``.
+
+ ``C`` (wrapped instance) [*type* \*, :ctype:`sipWrapperType` \*, PyObject \*]
+ Convert a C structure or a C++ class instance to a Python class
+ instance object. If the structure or class instance has already been
+ wrapped then the result is a new reference to the existing class
+ instance object. Ownership of the structure or instance is determined
+ by the ``PyObject *`` argument. If it is ``NULL`` and the instance has
+ already been wrapped then the ownership is unchanged. If it is
+ ``NULL`` and the instance is newly wrapped then ownership will be with
+ C/C++. If it is ``Py_None`` then ownership is transferred to Python
+ via a call to :cfunc:`sipTransferBack()`. Otherwise ownership is
+ transferred to C/C++ and the instance associated with the
+ ``PyObject *`` argument via a call to :cfunc:`sipTransferTo()`. The
+ Python class is influenced by any applicable
+ :directive:`%ConvertToSubClassCode` code.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use ``D``.
+
+ ``D`` (wrapped instance) [*type* \*, const :ctype:`sipTypeDef` \*, PyObject \*]
+ Convert a C structure, C++ class or mapped type instance to a Python
+ object. If the instance has already been wrapped then the result is a
+ new reference to the existing object. Ownership of the instance is
+ determined by the ``PyObject *`` argument. If it is ``NULL`` and the
+ instance has already been wrapped then the ownership is unchanged. If
+ it is ``NULL`` and the instance is newly wrapped then ownership will be
+ with C/C++. If it is ``Py_None`` then ownership is transferred to
+ Python via a call to :cfunc:`sipTransferBack()`. Otherwise ownership
+ is transferred to C/C++ and the instance associated with the
+ ``PyObject *`` argument via a call to :cfunc:`sipTransferTo()`. The
+ Python class is influenced by any applicable
+ :directive:`%ConvertToSubClassCode` code.
+
+ ``E`` (wrapped enum) [enum, PyTypeObject \*]
+ Convert a named C/C++ ``enum`` to an instance of the corresponding
+ Python named enum type.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use ``F``.
+
+ ``F`` (wrapped enum) [enum, :ctype:`sipTypeDef` \*]
+ Convert a named C/C++ ``enum`` to an instance of the corresponding
+ Python named enum type.
+
+ ``G`` (unicode) [wchar_t \*, :cmacro:`SIP_SSIZE_T`]
+ Convert a C/C++ wide character array and its length to a Python unicode
+ object. If the array is ``NULL`` then the length is ignored and the
+ result is ``Py_None``.
+
+ ``N`` (wrapped instance) [*type* \*, :ctype:`sipTypeDef` \*, PyObject \*]
+ Convert a new C structure, C++ class or mapped type instance to a
+ Python object. Ownership of the instance is determined by the
+ ``PyObject *`` argument. If it is ``NULL`` and the instance has
+ already been wrapped then the ownership is unchanged. If it is
+ ``NULL`` or ``Py_None`` then ownership will be with Python. Otherwise
+ ownership will be with C/C++ and the instance associated with the
+ ``PyObject *`` argument. The Python class is influenced by any
+ applicable :directive:`%ConvertToSubClassCode` code.
+
+ ``R`` (object) [PyObject \*]
+ The result is value passed without any conversions. The reference
+ count is unaffected, i.e. a reference is taken.
+
+ ``S`` (object) [PyObject \*]
+ The result is value passed without any conversions. The reference
+ count is incremented.
+
+ ``V`` (sip.voidptr) [void \*]
+ Convert a C/C++ ``void *`` Python :class:`sip.voidptr` object.
+
+
+.. cfunction:: PyObject *sipCallMethod(int *iserr, PyObject *method, const char *format, ...)
+
+ This calls a Python method passing a tuple of arguments based on a format
+ string and associated values in a similar way to the Python
+ :cfunc:`PyObject_CallObject()` function.
+
+ :param iserr:
+ if this is not ``NULL`` then the location it points to is set to a
+ non-zero value if there was an error.
+ :param method:
+ the Python bound method to call.
+ :param format:
+ the string of format characters (see :cfunc:`sipBuildResult()`).
+ :return:
+ If there was an error then ``NULL`` is returned and a Python exception
+ is raised.
+
+ It is normally called by handwritten code specified with the
+ :directive:`%VirtualCatcherCode` directive with method being the supplied
+ ``sipMethod``.
+
+
+.. cfunction:: int sipCanConvertToEnum(PyObject *obj, const sipTypeDef *td)
+
+ This checks if a Python object can be converted to a named enum.
+
+ :param obj:
+ the Python object.
+ :param td:
+ the enum's :ref:`generated type structure <ref-type-structures>`.
+ :return:
+ a non-zero value if the object can be converted.
+
+
+.. cfunction:: int sipCanConvertToInstance(PyObject *obj, sipWrapperType *type, int flags)
+
+ This checks if a Python object can be converted to an instance of a C
+ structure or C++ class.
+
+ :param obj:
+ the Python object.
+ :param type:
+ the C/C++ type's :ref:`generated type object <ref-type-objects>`.
+ :param flags:
+ any combination of the :cmacro:`SIP_NOT_NONE` and
+ :cmacro:`SIP_NO_CONVERTORS` flags.
+ :return:
+ a non-zero value if the object can be converted.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipCanConvertToType()`.
+
+
+.. cfunction:: int sipCanConvertToMappedType(PyObject *obj, const sipMappedType *mt, int flags)
+
+ This checks if a Python object can be converted to an instance of a C
+ structure or C++ class which has been implemented as a mapped type.
+
+ :param obj:
+ the Python object.
+ :param mt:
+ the opaque structure returned by :cfunc:`sipFindMappedType()`.
+ :param flags:
+ this may be the :cmacro:`SIP_NOT_NONE` flag.
+ :return:
+ a non-zero value if the object can be converted.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipCanConvertToType()`.
+
+
+.. cfunction:: int sipCanConvertToType(PyObject *obj, const sipTypeDef *td, int flags)
+
+ This checks if a Python object can be converted to an instance of a C
+ structure, C++ class or mapped type.
+
+ :param obj:
+ the Python object.
+ :param td:
+ the C/C++ type's :ref:`generated type structure <ref-type-structures>`.
+ :param flags:
+ any combination of the :cmacro:`SIP_NOT_NONE` and
+ :cmacro:`SIP_NO_CONVERTORS` flags.
+ :return:
+ a non-zero value if the object can be converted.
+
+
+.. cfunction:: PyObject *sipClassName(PyObject *obj)
+
+ This gets the class name of a wrapped instance as a Python string. It
+ comes with a reference.
+
+ :param obj:
+ the wrapped instance.
+ :return:
+ the name of the instance's class.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use the
+ following::
+
+ PyString_FromString(obj->ob_type->tp_name)
+
+
+.. cfunction:: PyObject *sipConvertFromConstVoidPtr(const void *cpp)
+
+ This creates a :class:`sip.voidptr` object for a memory address. The
+ object will not be writeable and has no associated size.
+
+ :param cpp:
+ the memory address.
+ :return:
+ the :class:`sip.voidptr` object.
+
+
+.. cfunction:: PyObject *sipConvertFromConstVoidPtrAndSize(const void *cpp, SIP_SSIZE_T size)
+
+ This creates a :class:`sip.voidptr` object for a memory address. The
+ object will not be writeable and can be used as an immutable buffer object.
+
+ :param cpp:
+ the memory address.
+ :param size:
+ the size associated with the address.
+ :return:
+ the :class:`sip.voidptr` object.
+
+
+.. cfunction:: PyObject *sipConvertFromEnum(int eval, const sipTypeDef *td)
+
+ This converts a named C/C++ ``enum`` to an instance of the corresponding
+ generated Python type.
+
+ :param eval:
+ the enumerated value to convert.
+ :param td:
+ the enum's :ref:`generated type structure <ref-type-structures>`.
+ :return:
+ the Python object.
+
+
+.. cfunction:: PyObject *sipConvertFromInstance(void *cpp, sipWrapperType *type, PyObject *transferObj)
+
+ This converts a C structure or a C++ class instance to an instance of the
+ corresponding generated Python type.
+
+ :param cpp:
+ the C/C++ instance.
+ :param type:
+ the type's :ref:`generated type object <ref-type-objects>`.
+ :param transferObj:
+ this controls the ownership of the returned value.
+ :return:
+ the Python object.
+
+ If the C/C++ instance has already been wrapped then the result is a
+ new reference to the existing class instance object.
+
+ If *transferObj* is ``NULL`` and the instance has already been wrapped then
+ the ownership is unchanged.
+
+ If *transferObj* is ``NULL`` and the instance is newly wrapped then
+ ownership will be with C/C++.
+
+ If *transferObj* is ``Py_None`` then ownership is transferred to Python via
+ a call to :cfunc:`sipTransferBack()`.
+
+ Otherwise ownership is transferred to C/C++ and the instance associated
+ with *transferObj* via a call to :cfunc:`sipTransferTo()`.
+
+ The Python type is influenced by any applicable
+ :directive:`%ConvertToSubClassCode` code.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipConvertFromType()`.
+
+
+.. cfunction:: PyObject *sipConvertFromMappedType(void *cpp, const sipMappedType *mt, PyObject *transferObj)
+
+ This converts a C structure or a C++ class instance wrapped as a mapped
+ type to an instance of the corresponding generated Python type.
+
+ :param cpp:
+ the C/C++ instance.
+ :param mt:
+ the opaque structure returned by :cfunc:`sipFindMappedType()`.
+ :param transferObj:
+ this controls the ownership of the returned value.
+ :return:
+ the Python object.
+
+ If *transferObj* is ``NULL`` then the ownership is unchanged.
+
+ If *transferObj* is ``Py_None`` then ownership is transferred to Python
+ via a call to :cfunc:`sipTransferBack()`.
+
+ Otherwise ownership is transferred to C/C++ and the instance associated
+ with *transferObj* argument via a call to :cfunc:`sipTransferTo()`.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipConvertFromType()`.
+
+
+.. cfunction:: PyObject *sipConvertFromNamedEnum(int eval, PyTypeObject *type)
+
+ This converts a named C/C++ ``enum`` to an instance of the corresponding
+ generated Python type.
+
+ :param eval:
+ the enumerated value to convert.
+ :param type:
+ the enum's :ref:`generated type object <ref-type-objects>`.
+ :return:
+ the Python object.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipConvertFromEnum()`.
+
+
+.. cfunction:: PyObject *sipConvertFromNewInstance(void *cpp, sipWrapperType *type, PyObject *transferObj)
+
+ This converts a new C structure or a C++ class instance to an instance of
+ the corresponding generated Python type.
+
+ :param cpp:
+ the C/C++ instance.
+ :param type:
+ the type's :ref:`generated type object <ref-type-objects>`.
+ :param transferObj:
+ this controls the ownership of the returned value.
+ :return:
+ the Python object.
+
+ If *transferObj* is ``NULL`` or ``Py_None`` then ownership will be with
+ Python.
+
+ Otherwise ownership will be with C/C++ and the instance associated with
+ *transferObj*.
+
+ The Python type is influenced by any applicable
+ :directive:`%ConvertToSubClassCode` code.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipConvertFromNewType()`.
+
+
+.. cfunction:: PyObject *sipConvertFromNewType(void *cpp, const sipTypeDef *td, PyObject *transferObj)
+
+ This converts a new C structure or a C++ class instance to an instance of
+ the corresponding generated Python type.
+
+ :param cpp:
+ the C/C++ instance.
+ :param td:
+ the type's :ref:`generated type structure <ref-type-structures>`.
+ :param transferObj:
+ this controls the ownership of the returned value.
+ :return:
+ the Python object.
+
+ If *transferObj* is ``NULL`` or ``Py_None`` then ownership will be with
+ Python.
+
+ Otherwise ownership will be with C/C++ and the instance associated with
+ *transferObj*.
+
+ The Python type is influenced by any applicable
+ :directive:`%ConvertToSubClassCode` code.
+
+
+.. cfunction:: SIP_SSIZE_T sipConvertFromSequenceIndex(SIP_SSIZE_T idx, SIP_SSIZE_T len)
+
+ This converts a Python sequence index (i.e. where a negative value refers
+ to the offset from the end of the sequence) to a C/C++ array index. If the
+ index was out of range then a negative value is returned and a Python
+ exception raised.
+
+ :param idx:
+ the sequence index.
+ :param len:
+ the length of the sequence.
+ :return:
+ the unsigned array index.
+
+
+.. cfunction:: int sipConvertFromSliceObject(PyObject *slice, SIP_SSIZE_T length, SIP_SSIZE_T *start, SIP_SSIZE_T *stop, SIP_SSIZE_T *step, SIP_SSIZE_T *slicelength)
+
+ This is a thin wrapper around the Python :cfunc:`PySlice_GetIndicesEx()`
+ function provided to make it easier to write handwritten code that is
+ compatible with SIP v3.x and versions of Python earlier that v2.3.
+
+
+.. cfunction:: PyObject *sipConvertFromType(void *cpp, const sipTypeDef *td, PyObject *transferObj)
+
+ This converts a C structure or a C++ class instance to an instance of the
+ corresponding generated Python type.
+
+ :param cpp:
+ the C/C++ instance.
+ :param td:
+ the type's :ref:`generated type structure <ref-type-structures>`.
+ :param transferObj:
+ this controls the ownership of the returned value.
+ :return:
+ the Python object.
+
+ If the C/C++ instance has already been wrapped then the result is a new
+ reference to the existing object.
+
+ If *transferObj* is ``NULL`` and the instance has already been wrapped then
+ the ownership is unchanged.
+
+ If *transferObj* is ``NULL`` and the instance is newly wrapped then
+ ownership will be with C/C++.
+
+ If *transferObj* is ``Py_None`` then ownership is transferred to Python via
+ a call to :cfunc:`sipTransferBack()`.
+
+ Otherwise ownership is transferred to C/C++ and the instance associated
+ with *transferObj* via a call to :cfunc:`sipTransferTo()`.
+
+ The Python class is influenced by any applicable
+ :directive:`%ConvertToSubClassCode` code.
+
+
+.. cfunction:: PyObject *sipConvertFromVoidPtr(void *cpp)
+
+ This creates a :class:`sip.voidptr` object for a memory address. The
+ object will be writeable but has no associated size.
+
+ :param cpp:
+ the memory address.
+ :return:
+ the :class:`sip.voidptr` object.
+
+
+.. cfunction:: PyObject *sipConvertFromVoidPtrAndSize(void *cpp, SIP_SSIZE_T size)
+
+ This creates a :class:`sip.voidptr` object for a memory address. The
+ object will be writeable and can be used as a mutable buffer object.
+
+ :param cpp:
+ the memory address.
+ :param size:
+ the size associated with the address.
+ :return:
+ the :class:`sip.voidptr` object.
+
+
+.. cfunction:: void *sipConvertToInstance(PyObject *obj, sipWrapperType *type, PyObject *transferObj, int flags, int *state, int *iserr)
+
+ This converts a Python object to an instance of a C structure or C++ class
+ assuming that a previous call to :cfunc:`sipCanConvertToInstance()` has
+ been successful.
+
+ :param obj:
+ the Python object.
+ :param type:
+ the type's :ref:`generated type object <ref-type-objects>`.
+ :param transferObj:
+ this controls any ownership changes to *obj*.
+ :param flags:
+ any combination of the :cmacro:`SIP_NOT_NONE` and
+ :cmacro:`SIP_NO_CONVERTORS` flags.
+ :param state:
+ the state of the returned C/C++ instance is returned via this pointer.
+ :param iserr:
+ the error flag is passed and updated via this pointer.
+ :return:
+ the C/C++ instance.
+
+ If *transferObj* is ``NULL`` then the ownership is unchanged.
+
+ If *transferObj* is ``Py_None`` then ownership is transferred to Python via
+ a call to :cfunc:`sipTransferBack()`.
+
+ Otherwise ownership is transferred to C/C++ and *obj* associated with
+ *transferObj* via a call to :cfunc:`sipTransferTo()`.
+
+ If *state* is not ``NULL`` then the location it points to is set to
+ describe the state of the returned C/C++ instance and is the value returned
+ by any :directive:`%ConvertToTypeCode`. The calling code must then release
+ the value at some point to prevent a memory leak by calling
+ :cfunc:`sipReleaseInstance()`.
+
+ If there is an error then the location *iserr* points to is set to a
+ non-zero value. If it was initially a non-zero value then the conversion
+ isn't attempted in the first place. (This allows several calls to be made
+ that share the same error flag so that it only needs to be tested once
+ rather than after each call.)
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipConvertToType()`.
+
+
+.. cfunction:: void *sipConvertToMappedType(PyObject *obj, const sipMappedType *mt, PyObject *transferObj, int flags, int *state, int *iserr)
+
+ This converts a Python object to an instance of a C structure or C++
+ class that is implemented as a mapped type assuming that a previous call to
+ :cfunc:`sipCanConvertToMappedType()` has been successful.
+
+ :param obj:
+ the Python object.
+ :param mt:
+ the opaque structure returned by :cfunc:`sipFindMappedType()`.
+ :param transferObj:
+ this controls any ownership changes to *obj*.
+ :param flags:
+ this may be the :cmacro:`SIP_NOT_NONE` flag.
+ :param state:
+ the state of the returned C/C++ instance is returned via this pointer.
+ :param iserr:
+ the error flag is passed and updated via this pointer.
+ :return:
+ the C/C++ instance.
+
+ If *transferObj* is ``NULL`` then the ownership is unchanged.
+
+ If *transferObj* is ``Py_None`` then ownership is transferred to Python via
+ a call to :cfunc:`sipTransferBack()`.
+
+ Otherwise ownership is transferred to C/C++ and *obj* associated with
+ *transferObj* via a call to :cfunc:`sipTransferTo()`.
+
+ If *state* is not ``NULL`` then the location it points to is set to
+ describe the state of the returned C/C++ instance and is the value returned
+ by any :directive:`%ConvertToTypeCode`. The calling code must then release
+ the value at some point to prevent a memory leak by calling
+ :cfunc:`sipReleaseMappedType()`.
+
+ If there is an error then the location *iserr* points to is set to a
+ non-zero value. If it was initially a non-zero value then the conversion
+ isn't attempted in the first place. (This allows several calls to be made
+ that share the same error flag so that it only needs to be tested once
+ rather than after each call.)
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipConvertToType()`
+
+
+.. cfunction:: void *sipConvertToType(PyObject *obj, const sipTypeDef *td, PyObject *transferObj, int flags, int *state, int *iserr)
+
+ This converts a Python object to an instance of a C structure, C++ class or
+ mapped type assuming that a previous call to :cfunc:`sipCanConvertToType()`
+ has been successful.
+
+ :param obj:
+ the Python object.
+ :param td:
+ the type's :ref:`generated type structure <ref-type-structures>`.
+ :param transferObj:
+ this controls any ownership changes to *obj*.
+ :param flags:
+ any combination of the :cmacro:`SIP_NOT_NONE` and
+ :cmacro:`SIP_NO_CONVERTORS` flags.
+ :param state:
+ the state of the returned C/C++ instance is returned via this pointer.
+ :param iserr:
+ the error flag is passed and updated via this pointer.
+ :return:
+ the C/C++ instance.
+
+ If *transferObj* is ``NULL`` then the ownership is unchanged. If it is
+ ``Py_None`` then ownership is transferred to Python via a call to
+ :cfunc:`sipTransferBack()`.
+
+ Otherwise ownership is transferred to C/C++ and *obj* associated with
+ *transferObj* via a call to :cfunc:`sipTransferTo()`.
+
+ If *state* is not ``NULL`` then the location it points to is set to
+ describe the state of the returned C/C++ instance and is the value returned
+ by any :directive:`%ConvertToTypeCode`. The calling code must then release
+ the value at some point to prevent a memory leak by calling
+ :cfunc:`sipReleaseType()`.
+
+ If there is an error then the location *iserr* points to is set to a
+ non-zero value. If it was initially a non-zero value then the conversion
+ isn't attempted in the first place. (This allows several calls to be made
+ that share the same error flag so that it only needs to be tested once
+ rather than after each call.)
+
+
+.. cfunction:: void *sipConvertToVoidPtr(PyObject *obj)
+
+ This converts a Python object to a memory address.
+ :cfunc:`PyErr_Occurred()` must be used to determine if the conversion was
+ successful.
+
+ :param obj:
+ the Python object which may be ``Py_None``, a :class:`sip.voidptr` or a
+ :ctype:`PyCObject`.
+ :return:
+ the memory address.
+
+
+.. cfunction:: int sipExportSymbol(const char *name, void *sym)
+
+ Python does not allow extension modules to directly access symbols in
+ another extension module. This exports a symbol, referenced by a name,
+ that can subsequently be imported, using :cfunc:`sipImportSymbol()`, by
+ another module.
+
+ :param name:
+ the name of the symbol.
+ :param sym:
+ the value of the symbol.
+ :return:
+ 0 if there was no error. A negative value is returned if *name* is
+ already associated with a symbol or there was some other error.
+
+
+.. cfunction:: sipWrapperType *sipFindClass(const char *type)
+
+ This returns a pointer to the :ref:`generated type object
+ <ref-type-objects` corresponding to a C/C++ type.
+
+ :param type:
+ the C/C++ declaration of the type.
+ :return:
+ the generated type object. This will not change and may be saved in a
+ static cache. ``NULL`` is returned if the C/C++ type doesn't exist.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipFindType()`.
+
+
+.. cfunction:: const sipMappedType *sipFindMappedType(const char *type)
+
+ This returns a pointer to an opaque structure describing a mapped type.
+
+ :param type:
+ the C/C++ declaration of the type.
+ :return:
+ the opaque structure. This will not change and may be saved in a
+ static cache. ``NULL`` is returned if the C/C++ type doesn't exist.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipFindType()`.
+
+
+.. cfunction:: PyTypeObject *sipFindNamedEnum(const char *type)
+
+ This returns a pointer to the :ref:`generated Python type object
+ <ref-enum-type-objects>` corresponding to a named C/C++ enum.
+
+ :param type:
+ the C/C++ declaration of the enum.
+ :return:
+ the generated Python type object. This will not change and may be
+ saved in a static cache. ``NULL`` is returned if the C/C++ enum
+ doesn't exist.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipFindType()`.
+
+
+.. cfunction:: const sipTypeDef *sipFindType(const char *type)
+
+ This returns a pointer to the :ref:`generated type structure
+ <ref-type-structures>` corresponding to a C/C++ type.
+
+ :param type:
+ the C/C++ declaration of the type.
+ :return:
+ the generated type structure. This will not change and may be saved in
+ a static cache. ``NULL`` is returned if the C/C++ type doesn't exist.
+
+
+.. cfunction:: void *sipForceConvertToInstance(PyObject *obj, sipWrapperType *type, PyObject *transferObj, int flags, int *state, int *iserr)
+
+ This converts a Python object to an instance of a C structure or C++ class
+ by calling :cfunc:`sipCanConvertToInstance()` and, if it is successfull,
+ calling :cfunc:`sipConvertToInstance()`.
+
+ See :cfunc:`sipConvertToInstance()` for a full description of the
+ arguments.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipForceConvertToType()`.
+
+
+.. cfunction:: void *sipForceConvertToMappedType(PyObject *obj, const sipMappedType *mt, PyObject *transferObj, int flags, int *state, int *iserr)
+
+ This converts a Python object to an instance of a C structure or C++ class
+ which has been implemented as a mapped type by calling
+ :cfunc:`sipCanConvertToMappedType()` and, if it is successfull, calling
+ :cfunc:`sipConvertToMappedType()`.
+
+ See :cfunc:`sipConvertToMappedType()` for a full description of the
+ arguments.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipForceConvertToType()`.
+
+
+.. cfunction:: void *sipForceConvertToType(PyObject *obj, const sipTypeDef *td, PyObject *transferObj, int flags, int *state, int *iserr)
+
+ This converts a Python object to an instance of a C structure, C++ class or
+ mapped type by calling :cfunc:`sipCanConvertToType()` and, if it is
+ successfull, calling :cfunc:`sipConvertToType()`.
+
+ See :cfunc:`sipConvertToType()` for a full description of the arguments.
+
+
+.. cfunction:: void sipFree(void *mem)
+
+ This returns an area of memory allocated by :cfunc:`sipMalloc()` to the
+ heap.
+
+ :param mem:
+ the memory address.
+
+
+.. cfunction:: PyObject *sipGetPyObject(void *cppptr, const sipTypeDef *td)
+
+ This returns a borrowed reference to the Python object for a C structure or
+ C++ class instance.
+
+ :param cppptr:
+ the pointer to the C/C++ instance.
+ :param td:
+ the :ref:`generated type structure <ref-type-structures>` corresponding
+ to the C/C++ type.
+ :return:
+ the Python object or ``NULL`` (and no exception is raised) if the
+ C/C++ instance hasn't been wrapped.
+
+
+.. cfunction:: int sipGetState(PyObject *transferObj)
+
+ The :directive:`%ConvertToTypeCode` directive requires that the provided
+ code returns an ``int`` describing the state of the converted value. The
+ state usually depends on any transfers of ownership that have been
+ requested. This is a convenience function that returns the correct state
+ when the converted value is a temporary.
+
+ :param transferObj:
+ the object that describes the requested transfer of ownership.
+ :return:
+ the state of the converted value.
+
+
+.. cfunction:: PyObject *sipGetWrapper(void *cppptr, sipWrapperType *type)
+
+ This returns a borrowed reference to the wrapped instance object for a C
+ structure or C++ class instance.
+
+ :param cppptr:
+ the pointer to the C/C++ instance.
+ :param type:
+ the :ref:`generated type object <ref-type-objects>` corresponding to
+ the C/C++ type.
+ :return:
+ the Python object or ``NULL`` (and no exception is raised) if the
+ C/C++ instance hasn't been wrapped.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipGetPyObject()`.
+
+
+.. cfunction:: void *sipImportSymbol(const char *name)
+
+ Python does not allow extension modules to directly access symbols in
+ another extension module. This imports a symbol, referenced by a name,
+ that has previously been exported, using :cfunc:`sipExportSymbol()`, by
+ another module.
+
+ :param name:
+ the name of the symbol.
+ :return:
+ the value of the symbol. ``NULL`` is returned if there is no such
+ symbol.
+
+
+.. ctype:: sipIntTypeClassMap
+
+ This C structure is used with :cfunc:`sipMapIntToClass()` to define a
+ mapping between integer based RTTI and :ref:`generated type objects
+ <ref-type-objects>`. The structure elements are as follows.
+
+ .. cmember:: int typeInt
+
+ The integer RTTI.
+
+ .. cmember:: sipWrapperType **pyType.
+
+ A pointer to the corresponding generated type object.
+
+ .. note::
+ This is deprecated from SIP v4.8.
+
+
+.. cfunction:: int sipIsAPIEnabled(const char *name, int from, int to)
+
+ .. versionadded:: 4.9
+
+ This checks to see if the current version number of an API falls within a
+ given range. See :ref:`ref-incompat-apis` for more detail.
+
+ :param name:
+ the name of the API.
+ :param from:
+ the lower bound of the range. For the API to be enabled its version
+ number must be greater than or equal to *from*. If *from* is 0 then
+ this check isn't made.
+ :param to:
+ the upper bound of the range. For the API to be enabled its version
+ number must be less than *to*. If *to* is 0 then this check isn't
+ made.
+ :return:
+ a non-zero value if the API is enabled.
+
+
+.. cfunction:: unsigned long sipLong_AsUnsignedLong(PyObject *obj)
+
+ This function is a thin wrapper around :cfunc:`PyLong_AsUnsignedLong()`
+ that works around a bug in Python v2.3.x and earlier when converting
+ integer objects.
+
+
+.. cfunction:: void *sipMalloc(size_t nbytes)
+
+ This allocates an area of memory on the heap using the Python
+ :cfunc:`PyMem_Malloc()` function. The memory is freed by calling
+ :cfunc:`sipFree()`.
+
+ :param nbytes:
+ the number of bytes to allocate.
+ :return:
+ the memory address. If there was an error then ``NULL`` is returned
+ and a Python exception raised.
+
+
+.. cfunction:: sipWrapperType *sipMapIntToClass(int type, const sipIntTypeClassMap *map, int maplen)
+
+ This can be used in :directive:`%ConvertToSubClassCode` code as a
+ convenient way of converting integer based RTTI to the corresponding
+ :ref:`generated type object <ref-type-objects>`.
+
+ :param type:
+ the integer RTTI.
+ :param map:
+ the table of known RTTI and the corresponding type objects (see
+ :ctype:`sipIntTypeClassMap`). The entries in the table must be sorted
+ in ascending order of RTTI.
+ :param maplen:
+ the number of entries in the table.
+ :return:
+ the corresponding type object, or ``NULL`` if *type* wasn't in *map*.
+
+ .. note::
+ This is deprecated from SIP v4.8.
+
+
+.. cfunction:: sipWrapperType *sipMapStringToClass(char *type, const sipStringTypeClassMap *map, int maplen)
+
+ This can be used in :directive:`%ConvertToSubClassCode` code as a
+ convenient way of converting ``'\0'`` terminated string based RTTI to the
+ corresponding :ref:`generated type object <ref-type-objects>`.
+
+ :param type:
+ the string RTTI.
+ :param map:
+ the table of known RTTI and the corresponding type objects (see
+ :ctype:`sipStringTypeClassMap`). The entries in the table must be
+ sorted in ascending order of RTTI.
+ :param maplen:
+ the number of entries in the table.
+ :return:
+ the corresponding type object, or ``NULL`` if *type* wasn't in *map*.
+
+ .. note::
+ This is deprecated from SIP v4.8.
+
+
+.. cfunction:: int sipParseResult(int *iserr, PyObject *method, PyObject *result, const char *format, ...)
+
+ This converts a Python object (usually returned by a method) to C/C++ based
+ on a format string and associated values in a similar way to the Python
+ :cfunc:`PyArg_ParseTuple()` function.
+
+ :param iserr:
+ if this is not ``NULL`` then the location it points to is set to a
+ non-zero value if there was an error.
+ :param method:
+ the Python method that returned *result*.
+ :param result:
+ the Python object returned by *method*.
+ :param format:
+ the format string.
+ :return:
+ 0 if there was no error. Otherwise a negative value is returned, and
+ an exception raised.
+
+ This is normally called by handwritten code specified with the
+ :directive:`%VirtualCatcherCode` directive with *method* being the supplied
+ ``sipMethod`` and *result* being the value returned by
+ :cfunc:`sipCallMethod()`.
+
+ If *format* begins and ends with parentheses then *result* must be a Python
+ tuple and the rest of *format* is applied to the tuple contents.
+
+ In the following description the first letter is the format character, the
+ entry in parentheses is the Python object type that the format character
+ will convert, and the entry in brackets are the types of the C/C++ values
+ to be passed.
+
+ ``ae`` (object) [char \*]
+ Convert a Python string-like object of length 1 to a C/C++ ``char``
+ according to the encoding ``e``. ``e`` can either be ``A`` for ASCII,
+ ``L`` for Latin-1, or ``8`` for UTF-8. For Python v2 the object may be
+ either a string or a unicode object that can be encoded. For Python v3
+ the object may either be a bytes object or a string object that can be
+ encoded. An object that supports the buffer protocol may also be used.
+
+ ``b`` (integer) [bool \*]
+ Convert a Python integer to a C/C++ ``bool``.
+
+ ``c`` (string/bytes) [char \*]
+ Convert a Python v2 string object or a Python v3 bytes object of length
+ 1 to a C/C++ ``char``.
+
+ ``d`` (float) [double \*]
+ Convert a Python floating point number to a C/C++ ``double``.
+
+ ``e`` (integer) [enum \*]
+ Convert a Python integer to an anonymous C/C++ ``enum``.
+
+ ``f`` (float) [float \*]
+ Convert a Python floating point number to a C/C++ ``float``.
+
+ ``g`` (string/bytes) [const char \*\*, :cmacro:`SIP_SSIZE_T` \*]
+ Convert a Python v2 string object or a Python v3 bytes object to a
+ C/C++ character array and its length. If the Python object is
+ ``Py_None`` then the array and length are ``NULL`` and zero
+ respectively.
+
+ ``h`` (integer) [short \*]
+ Convert a Python integer to a C/C++ ``short``.
+
+ ``i`` (integer) [int \*]
+ Convert a Python integer to a C/C++ ``int``.
+
+ ``l`` (long) [long \*]
+ Convert a Python long to a C/C++ ``long``.
+
+ ``m`` (long) [unsigned long \*]
+ Convert a Python long to a C/C++ ``unsigned long``.
+
+ ``n`` (long) [long long \*]
+ Convert a Python long to a C/C++ ``long long``.
+
+ ``o`` (long) [unsigned long long \*]
+ Convert a Python long to a C/C++ ``unsigned long long``.
+
+ ``s`` (string/bytes) [const char \*\*]
+ Convert a Python v2 string object or a Python v3 bytes object to a
+ C/C++ ``'\0'`` terminated string. If the Python object is ``Py_None``
+ then the string is ``NULL``.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use ``B``.
+
+ ``t`` (long) [unsigned short \*]
+ Convert a Python long to a C/C++ ``unsigned short``.
+
+ ``u`` (long) [unsigned int \*]
+ Convert a Python long to a C/C++ ``unsigned int``.
+
+ ``w`` (unicode/string) [wchar_t \*]
+ Convert a Python v2 string or unicode object or a Python v3 string
+ object of length 1 to a C/C++ wide character.
+
+ ``x`` (unicode/string) [wchar_t \*\*]
+ Convert a Python v2 string or unicode object or a Python v3 string
+ object to a C/C++ ``L'\0'`` terminated wide character string. If the
+ Python object is ``Py_None`` then the string is ``NULL``.
+
+ ``Ae`` (object) [int, const char \*\*]
+ Convert a Python string-like object to a C/C++ ``'\0'`` terminated
+ string according to the encoding ``e``. ``e`` can either be ``A`` for
+ ASCII, ``L`` for Latin-1, or ``8`` for UTF-8. If the Python object is
+ ``Py_None`` then the string is ``NULL``. The integer uniquely
+ identifies the object in the context defined by the ``S`` format
+ character and allows an extra reference to the object to be kept to
+ ensure that the string remains valid. For Python v2 the object may be
+ either a string or a unicode object that can be encoded. For Python v3
+ the object may either be a bytes object or a string object that can be
+ encoded. An object that supports the buffer protocol may also be used.
+
+ ``B`` (string/bytes) [int, const char \*\*]
+ Convert a Python v2 string object or a Python v3 bytes object to a
+ C/C++ ``'\0'`` terminated string. If the Python object is ``Py_None``
+ then the string is ``NULL``. The integer uniquely identifies the
+ object in the context defined by the ``S`` format character and allows
+ an extra reference to the object to be kept to ensure that the string
+ remains valid.
+
+ ``Cf`` (wrapped class) [:ctype:`sipWrapperType` \*, int \*, void \*\*]
+ Convert a Python object to a C structure or a C++ class instance and
+ return its state as described in :cfunc:`sipConvertToInstance()`.
+ ``f`` is a combination of the following flags encoded as an ASCII
+ character by adding ``0`` to the combined value:
+
+ 0x01 disallows the conversion of ``Py_None`` to ``NULL``
+
+ 0x02 implements the :fanno:`Factory` and :fanno:`TransferBack`
+ annotations
+
+ 0x04 suppresses the return of the state of the returned C/C++
+ instance. Note that the ``int *`` used to return the state is
+ not passed if this flag is specified.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use ``Hf``.
+
+ ``Df`` (wrapped instance) [const :ctype:`sipTypeDef` \*, int \*, void \*\*]
+ Convert a Python object to a C structure, C++ class or mapped type
+ instance and return its state as described in
+ :cfunc:`sipConvertToType()`. ``f`` is a combination of the following
+ flags encoded as an ASCII character by adding ``0`` to the combined
+ value:
+
+ 0x01 disallows the conversion of ``Py_None`` to ``NULL``
+
+ 0x02 implements the :fanno:`Factory` and :fanno:`TransferBack`
+ annotations
+
+ 0x04 suppresses the return of the state of the returned C/C++
+ instance. Note that the ``int *`` used to return the state is
+ not passed if this flag is specified.
+
+ .. note::
+ This is deprecated from SIP v4.10.1. Instead you should use
+ ``Hf``.
+
+ ``E`` (wrapped enum) [PyTypeObject \*, enum \*]
+ Convert a Python named enum type to the corresponding C/C++ ``enum``.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use ``F``.
+
+ ``F`` (wrapped enum) [:ctype:`sipTypeDef` \*, enum \*]
+ Convert a Python named enum type to the corresponding C/C++ ``enum``.
+
+ ``G`` (unicode/string) [wchar_t \*\*, :cmacro:`SIP_SSIZE_T` \*]
+ Convert a Python v2 string or unicode object or a Python v3 string
+ object to a C/C++ wide character array and its length. If the Python
+ object is ``Py_None`` then the array and length are ``NULL`` and zero
+ respectively.
+
+ ``Hf`` (wrapped instance) [const :ctype:`sipTypeDef` \*, int \*, void \*\*]
+ Convert a Python object to a C structure, C++ class or mapped type
+ instance as described in :cfunc:`sipConvertToType()`. ``f`` is a
+ combination of the following flags encoded as an ASCII character by
+ adding ``0`` to the combined value:
+
+ 0x01 disallows the conversion of ``Py_None`` to ``NULL``
+
+ 0x02 implements the :fanno:`Factory` and :fanno:`TransferBack`
+ annotations
+
+ 0x04 returns a copy of the C/C++ instance.
+
+ ``N`` (object) [PyTypeObject \*, :PyObject \*\*]
+ A Python object is checked to see if it is a certain type and then
+ returned without any conversions. The reference count is incremented.
+ The Python object may be ``Py_None``.
+
+ ``O`` (object) [PyObject \*\*]
+ A Python object is returned without any conversions. The reference
+ count is incremented.
+
+ ``S`` [:ctype:`sipSimpleWrapper` \*]
+ This format character, if used, must be the first. It is used with
+ other format characters to define a context and doesn't itself convert
+ an argument.
+
+ ``T`` (object) [PyTypeObject \*, PyObject \*\*]
+ A Python object is checked to see if it is a certain type and then
+ returned without any conversions. The reference count is incremented.
+ The Python object may not be ``Py_None``.
+
+ ``V`` (:class:`sip.voidptr`) [void \*]
+ Convert a Python :class:`sip.voidptr` object to a C/C++ ``void *``.
+
+ ``Z`` (object) []
+ Check that a Python object is ``Py_None``. No value is returned.
+
+
+.. cfunction:: int sipRegisterAttributeGetter(const sipTypeDef *td, sipAttrGetterFunc getter)
+
+ This registers a handler that will called just before SIP needs to get an
+ attribute from a wrapped type's dictionary for the first time. The handler
+ must then populate the type's dictionary with any lazy attributes.
+
+ :param td:
+ the optional :ref:`generated type structure <ref-type-structures>` that
+ determines which types the handler will be called for.
+ :param getter:
+ the handler function.
+ :return:
+ 0 if there was no error, otherwise -1 is returned.
+
+ If *td* is not ``NULL`` then the handler will only be called for types with
+ that type or that are sub-classed from it. Otherwise the handler will be
+ called for all types.
+
+ A handler has the following signature.
+
+ int handler(const :ctype:`sipTypeDef` \*td, PyObject \*dict)
+
+ *td* is the generated type definition of the type whose dictionary is
+ to be populated.
+
+ *dict* is the dictionary to be populated.
+
+ 0 if there was no error, otherwise -1 is returned.
+
+ See the section :ref:`ref-lazy-type-attributes` for more details.
+
+
+.. cfunction:: int sipRegisterPyType(PyTypeObject *type)
+
+ This registers a Python type object that can be used as the meta-type or
+ super-type of a wrapped C++ type.
+
+ :param type:
+ the type object.
+ :return:
+ 0 if there was no error, otherwise -1 is returned.
+
+ See the section :ref:`ref-types-metatypes` for more details.
+
+
+.. cfunction:: void sipReleaseInstance(void *cpp, sipWrapperType *type, int state)
+
+ This destroys a wrapped C/C++ instance if it was a temporary instance. It
+ is called after a call to either :cfunc:`sipConvertToInstance()` or
+ :cfunc:`sipForceConvertToInstance()`.
+
+ :param cpp:
+ the C/C++ instance.
+ :param type:
+ the type's :ref:`generated type object <ref-type-objects>`.
+ :param state:
+ describes the state of the C/C++ instance.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipReleaseType()`.
+
+
+.. cfunction:: void sipReleaseMappedType(void *cpp, const sipMappedType *mt, int state)
+
+ This destroys a wrapped C/C++ mapped type if it was a temporary instance.
+ It is called after a call to either :cfunc:`sipConvertToMappedType()` or
+ :cfunc:`sipForceConvertToMappedType()`.
+
+ :param cpp:
+ the C/C++ instance.
+ :param mt:
+ the opaque structure returned by :cfunc:`sipFindMappedType()`.
+ :param state:
+ describes the state of the C/C++ instance.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipReleaseType()`.
+
+
+.. cfunction:: void sipReleaseType(void *cpp, const sipTypeDef *td, int state)
+
+ This destroys a wrapped C/C++ or mapped type instance if it was a temporary
+ instance. It is called after a call to either :cfunc:`sipConvertToType()`
+ or :cfunc:`sipForceConvertToType()`.
+
+ :param cpp:
+ the C/C++ instance.
+ :param td:
+ the type's :ref:`generated type structure <ref-type-structures>`.
+ :param state:
+ describes the state of the C/C++ instance.
+
+
+.. cfunction:: const char *sipResolveTypedef(const char *name)
+
+ This returns the value of a C/C++ typedef.
+
+ :param name:
+ the name of the typedef.
+ :return:
+ the value of the typedef or ``NULL`` if there was no such typedef.
+
+
+.. ctype:: sipSimpleWrapper
+
+ This is a C structure that represents a Python wrapped instance whose type
+ is :class:`sip.simplewrapper`. It is an extension of the ``PyObject``
+ structure and so may be safely cast to it.
+
+ .. cmember:: PyObject *user
+
+ This can be used for any purpose by handwritten code and will
+ automatically be garbage collected at the appropriate time.
+
+
+.. cvar:: PyTypeObject *sipSimpleWrapper_Type
+
+ This is the type of a :ctype:`sipSimpleWrapper` structure and is the C
+ implementation of :class:`sip.simplewrapper`. It may be safely cast to
+ :ctype:`sipWrapperType`.
+
+
+.. ctype:: sipStringTypeClassMap
+
+ This C structure is used with :cfunc:`sipMapStringToClass()` to define a
+ mapping between ``'\0'`` terminated string based RTTI and
+ :ref:`ref-type-objects`. The structure elements are as follows.
+
+ .. cmember:: char *typeString
+
+ The ``'\0'`` terminated string RTTI.
+
+ .. cmember:: sipWrapperType **pyType.
+
+ A pointer to the corresponding generated type object.
+
+ .. note::
+ This is deprecated from SIP v4.8.
+
+
+.. cfunction:: void sipTransferBack(PyObject *obj)
+
+ This transfers ownership of a Python wrapped instance to Python (see
+ :ref:`ref-object-ownership`).
+
+ :param obj:
+ the wrapped instance.
+
+ In addition, any association of the instance with regard to the cyclic
+ garbage collector with another instance is removed.
+
+
+.. cfunction:: void sipTransferBreak(PyObject *obj)
+
+ Any association of a Python wrapped instance with regard to the cyclic
+ garbage collector with another instance is removed. Ownership of the
+ instance should be with C++.
+
+ :param obj:
+ the wrapped instance.
+
+
+.. cfunction:: void sipTransferTo(PyObject *obj, PyObject *owner)
+
+ This transfers ownership of a Python wrapped instance to C++ (see
+ :ref:`ref-object-ownership`).
+
+ :param obj:
+ the wrapped instance.
+ :param owner:
+ an optional wrapped instance that *obj* becomes associated with with
+ regard to the cyclic garbage collector. If *owner* is ``NULL`` then no
+ such association is made. If *owner* is the same value as *obj* then
+ any reference cycles involving *obj* can never be detected or broken by
+ the cyclic garbage collector. Responsibility for calling the C++
+ instance's destructor is always transfered to C++.
+
+
+.. cfunction:: PyTypeObject *sipTypeAsPyTypeObject(sipTypeDef *td)
+
+ This returns a pointer to the Python type object that SIP creates for a
+ :ref:`generated type structure <ref-type-structures>`.
+
+ :param td:
+ the type structure.
+ :return:
+ the Python type object. If the type structure refers to a mapped type
+ then ``NULL`` will be returned.
+
+ If the type structure refers to a C structure or C++ class then the
+ Python type object may be safely cast to a :ctype:`sipWrapperType`.
+
+
+.. cfunction:: const sipTypeDef *sipTypeFromPyTypeObject(PyTypeObject *py_type)
+
+ This returns the :ref:`generated type structure <ref-type-structures>` for
+ a Python type object.
+
+ :param py_type:
+ the Python type object.
+ :return:
+ the type structure or ``NULL`` if the Python type object doesn't
+ correspond to a type structure.
+
+
+.. cfunction:: int sipTypeIsClass(sipTypeDef *td)
+
+ This checks if a :ref:`generated type structure <ref-type-structures>`
+ refers to a C structure or C++ class.
+
+ :param td:
+ the type structure.
+ :return:
+ a non-zero value if the type structure refers to a structure or class.
+
+
+.. cfunction:: int sipTypeIsEnum(sipTypeDef *td)
+
+ This checks if a :ref:`generated type structure <ref-type-structures>`
+ refers to a named enum.
+
+ :param td:
+ the type structure.
+ :return:
+ a non-zero value if the type structure refers to an enum.
+
+
+.. cfunction:: int sipTypeIsMapped(sipTypeDef *td)
+
+ This checks if a :ref:`generated type structure <ref-type-structures>`
+ refers to a mapped type.
+
+ :param td:
+ the type structure.
+ :return:
+ a non-zero value if the type structure refers to a mapped type.
+
+
+.. cfunction:: int sipTypeIsNamespace(sipTypeDef *td)
+
+ This checks if a :ref:`generated type structure <ref-type-structures>`
+ refers to a C++ namespace.
+
+ :param td:
+ the type structure.
+ :return:
+ a non-zero value if the type structure refers to a namespace.
+
+
+.. cfunction:: const char *sipTypeName(const sipTypeDef *td)
+
+ This returns the C/C++ name of a wrapped type.
+
+ :param td:
+ the type's :ref:`generated type structure <ref-type-structures>`.
+ :return:
+ the name of the C/C++ type.
+
+
+.. cfunction:: const sipTypeDef *sipTypeScope(const sipTypeDef *td)
+
+ This returns the :ref:`generated type structure <ref-type-structures>` of
+ the enclosing scope of another generated type structure.
+
+ :param td:
+ the type structure.
+ :return:
+ the type structure of the scope or ``NULL`` if the type has no scope.
+
+
+.. cvar:: PyTypeObject *sipVoidPtr_Type
+
+ This is the type of a ``PyObject`` structure that is used to wrap a
+ ``void *``.
+
+
+.. ctype:: sipWrapper
+
+ This is a C structure that represents a Python wrapped instance whose type
+ is :class:`sip.wrapper`. It is an extension of the
+ :ctype:`sipSimpleWrapper` and ``PyObject`` structures and so may be safely
+ cast to both.
+
+
+.. cfunction:: int sipWrapper_Check(PyObject *obj)
+
+ This checks if a Python object is a wrapped instance.
+
+ :param obj:
+ the Python object.
+ :return:
+ a non-zero value if the Python object is a wrapped instance.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use the
+ following::
+
+ PyObject_TypeCheck(obj, sipWrapper_Type)
+
+
+.. cvar:: PyTypeObject *sipWrapper_Type
+
+ This is the type of a :ctype:`sipWrapper` structure and is the C
+ implementation of :class:`sip.wrapper`. It may be safely cast to
+ :ctype:`sipWrapperType`.
+
+
+.. ctype:: sipWrapperType
+
+ This is a C structure that represents a SIP generated type object. It is
+ an extension of the ``PyTypeObject`` structure (which is itself an
+ extension of the ``PyObject`` structure) and so may be safely cast to
+ ``PyTypeObject`` (and ``PyObject``).
+
+
+.. cvar:: PyTypeObject *sipWrapperType_Type
+
+ This is the type of a :ctype:`sipWrapperType` structure and is the C
+ implementation of :class:`sip.wrappertype`.
+
+
+.. _ref-type-structures:
+
+Generated Type Structures
+-------------------------
+
+SIP generates an opaque type structure for each C structure, C++ class, C++
+namespace, named enum or mapped type being wrapped. These are
+:ctype:`sipTypeDef` structures and are used extensively by the SIP API.
+
+The names of these structure are prefixed by ``sipType_``.
+
+For those structures that correspond to C structures, C++ classes, C++
+namespaces or named enums the remaining part of the name is the fully
+qualified name of the structure, class, namespace or enum name. Any ``::``
+scope separators are replaced by an underscore. For example, the type object
+for class ``Klass`` is ``sipType_Klass``.
+
+For those structure that correspond to mapped types the remaining part of the
+name is generated by SIP. The only way for handwritten code to obtain a
+pointer to a structure for a mapped type is to use :cfunc:`sipFindType()`.
+
+The type structures of all imported types are available to handwritten code.
+
+
+.. _ref-type-objects:
+
+Generated Type Objects
+----------------------
+
+SIP generates a :ctype:`sipWrapperType` type object for each C structure or
+C++ class being wrapped.
+
+These objects are named with the structure or class name prefixed by
+``sipClass_``. For example, the type object for class ``Klass`` is
+``sipClass_Klass``.
+
+.. note::
+ Using these names is deprecated from SIP v4.8. Instead use the
+ corresponding generated type structure (see :ref:`ref-type-structures`) and
+ :cfunc:`sipTypeAsPyTypeObject()`.
+
+
+.. _ref-enum-type-objects:
+
+Generated Named Enum Type Objects
+---------------------------------
+
+SIP generates a type object for each named enum being wrapped. These are
+PyTypeObject structures. (Anonymous enums are wrapped as Python integers.)
+
+These objects are named with the fully qualified enum name (i.e. including any
+enclosing scope) prefixed by ``sipEnum_``. For example, the type object for
+enum ``Enum`` defined in class ``Klass`` is ``sipEnum_Klass_Enum``.
+
+.. note::
+ Using these names is deprecated from SIP v4.8. Instead use the
+ corresponding generated type structure (see :ref:`ref-type-structures`) and
+ :cfunc:`sipTypeAsPyTypeObject()`.
+
+
+.. _ref-derived-classes:
+
+Generated Derived Classes
+-------------------------
+
+For most C++ classes being wrapped SIP generates a derived class with the same
+name prefixed by ``sip``. For example, the derived class for class ``Klass``
+is ``sipKlass``.
+
+If a C++ class doesn't have any virtual or protected methods in it or any of
+it's super-class hierarchy, or does not emit any Qt signals, then a derived
+class is not generated.
+
+Most of the time handwritten code should ignore the derived classes. The only
+exception is that handwritten constructor code specified using the
+:directive:`%MethodCode` directive should call the derived class's constructor
+(which has the same C++ signature) rather then the wrapped class's constructor.
+
+
+.. _ref-exception-objects:
+
+Generated Exception Objects
+---------------------------
+
+SIP generates a Python object for each exception defined with the
+:directive:`%Exception` directive.
+
+These objects are named with the fully qualified exception name (i.e. including
+any enclosing scope) prefixed by ``sipException_``. For example, the type
+object for enum ``Except`` defined in class ``Klass`` is
+``sipException_Klass_Except``.
+
+The objects of all imported exceptions are available to handwritten code.
diff --git a/doc/html/_sources/command_line.txt b/doc/html/_sources/command_line.txt
new file mode 100644
index 0000000..9c50cf4
--- /dev/null
+++ b/doc/html/_sources/command_line.txt
@@ -0,0 +1,137 @@
+.. _ref-command-line:
+
+The SIP Command Line
+====================
+
+The syntax of the SIP command line is::
+
+ sip [options] [specification]
+
+``specification`` is the name of the specification file for the module. If it
+is omitted then ``stdin`` is used.
+
+The full set of command line options is:
+
+.. program:: sip
+
+.. cmdoption:: -h
+
+ Display a help message.
+
+.. cmdoption:: -V
+
+ Display the SIP version number.
+
+.. cmdoption:: -a <FILE>
+
+ The name of the QScintilla API file to generate. This file contains a
+ description of the module API in a form that the QScintilla editor
+ component can use for auto-completion and call tips. (The file may also be
+ used by the SciTE editor but must be sorted first.) By default the file is
+ not generated.
+
+.. cmdoption:: -b <FILE>
+
+ The name of the build file to generate. This file contains the information
+ about the module needed by the :ref:`SIP build system <ref-build-system>`
+ to generate a platform and compiler specific Makefile for the module. By
+ default the file is not generated.
+
+.. cmdoption:: -c <DIR>
+
+ The name of the directory (which must exist) into which all of the
+ generated C or C++ code is placed. By default no code is generated.
+
+.. cmdoption:: -d <FILE>
+
+ The name of the documentation file to generate. Documentation is included
+ in specification files using the :directive:`%Doc` and
+ :directive:`%ExportedDoc` directives. By default the file is not
+ generated.
+
+.. cmdoption:: -e
+
+ Support for C++ exceptions is enabled. This causes all calls to C++ code
+ to be enclosed in ``try``/``catch`` blocks and C++ exceptions to be
+ converted to Python exceptions. By default exception support is disabled.
+
+.. cmdoption:: -g
+
+ The Python GIL is released before making any calls to the C/C++ library
+ being wrapped and reacquired afterwards. See :ref:`ref-gil` and the
+ :fanno:`ReleaseGIL` and :fanno:`HoldGIL` annotations.
+
+.. cmdoption:: -I <DIR>
+
+ The directory is added to the list of directories searched when looking for
+ a specification file given in an :directive:`%Include` or
+ :directive:`%Import` directive. This option may be given any number of
+ times.
+
+.. cmdoption:: -j <NUMBER>
+
+ The generated code is split into the given number of files. This makes it
+ easier to use the parallel build facility of most modern implementations of
+ ``make``. By default 1 file is generated for each C structure or C++
+ class.
+
+.. cmdoption:: -k
+
+ .. versionadded:: 4.10
+
+ All functions and methods will, by default, support passing parameters
+ using the Python keyword argument syntax.
+
+.. cmdoption:: -o
+
+ .. versionadded:: 4.10
+
+ Docstrings will be automatically generated that describe the signature of
+ all functions, methods and constructors.
+
+.. cmdoption:: -p <MODULE>
+
+ The name of the :directive:`%ConsolidatedModule` which will contain the
+ wrapper code for this component module.
+
+.. cmdoption:: -P
+
+ .. versionadded:: 4.10
+
+ By default SIP generates code to provide access to protected C++ functions
+ from Python. On some platforms (notably Linux, but not Windows) this code
+ can be avoided if the ``protected`` keyword is redefined as ``public``
+ during compilation. This can result in a significant reduction in the size
+ of a generated Python module. This option disables the generation of the
+ extra code.
+
+.. cmdoption:: -r
+
+ Debugging statements that trace the execution of the bindings are
+ automatically generated. By default the statements are not generated.
+
+.. cmdoption:: -s <SUFFIX>
+
+ The suffix to use for generated C or C++ source files. By default ``.c``
+ is used for C and ``.cpp`` for C++.
+
+.. cmdoption:: -t <TAG>
+
+ The SIP version tag (declared using a :directive:`%Timeline` directive) or
+ the SIP platform tag (declared using the :directive:`%Platforms` directive)
+ to generate code for. This option may be given any number of times so long
+ as the tags do not conflict.
+
+.. cmdoption:: -w
+
+ The display of warning messages is enabled. By default warning messages
+ are disabled.
+
+.. cmdoption:: -x <FEATURE>
+
+ The feature (declared using the :directive:`%Feature` directive) is
+ disabled.
+
+.. cmdoption:: -z <FILE>
+
+ The name of a file containing more command line options.
diff --git a/doc/html/_sources/directives.txt b/doc/html/_sources/directives.txt
new file mode 100644
index 0000000..7e3a2e0
--- /dev/null
+++ b/doc/html/_sources/directives.txt
@@ -0,0 +1,2109 @@
+Directives
+==========
+
+In this section we describe each of the directives that can be used in
+specification files. All directives begin with ``%`` as the first
+non-whitespace character in a line.
+
+Some directives have arguments or contain blocks of code or documentation. In
+the following descriptions these are shown in *italics*. Optional arguments
+are enclosed in [*brackets*].
+
+Some directives are used to specify handwritten code. Handwritten code must
+not define names that start with the prefix ``sip``.
+
+
+.. directive:: %AccessCode
+
+.. parsed-literal::
+
+ %AccessCode
+ *code*
+ %End
+
+This directive is used immediately after the declaration of an instance of a
+wrapped class or structure, or a pointer to such an instance. You use it to
+provide handwritten code that overrides the default behaviour.
+
+For example::
+
+ class Klass;
+
+ Klass *klassInstance;
+ %AccessCode
+ // In this contrived example the C++ library we are wrapping defines
+ // klassInstance as Klass ** (which SIP doesn't support) so we
+ // explicitly dereference it.
+ if (klassInstance && *klassInstance)
+ return *klassInstance;
+
+ // This will get converted to None.
+ return 0;
+ %End
+
+
+.. directive:: %API
+
+.. versionadded:: 4.9
+
+.. parsed-literal::
+
+ %API *name* *version*
+
+This directive is used to define an API and set its default version number. A
+version number must be greater than or equal to 1.
+
+See :ref:`ref-incompat-apis` for more detail.
+
+For example::
+
+ %API PyQt4 1
+
+
+.. directive:: %BIGetBufferCode
+
+.. parsed-literal::
+
+ %BIGetBufferCode
+ *code*
+ %End
+
+This directive (along with :directive:`%BIReleaseBufferCode`) is used to
+specify code that implements the buffer interface of Python v3. If Python v2
+is being used then this is ignored.
+
+The following variables are made available to the handwritten code:
+
+Py_buffer \*sipBuffer
+ This is a pointer to the Python buffer structure that the handwritten code
+ must populate.
+
+*type* \*sipCpp
+ This is a pointer to the structure or class instance. Its *type* is a
+ pointer to the structure or class.
+
+int sipFlags
+ These are the flags that specify what elements of the ``sipBuffer``
+ structure must be populated.
+
+int sipRes
+ The handwritten code should set this to 0 if there was no error or -1 if
+ there was an error.
+
+PyObject \*sipSelf
+ This is the Python object that wraps the structure or class instance, i.e.
+ ``self``.
+
+
+.. directive:: %BIGetCharBufferCode
+
+.. parsed-literal::
+
+ %BIGetCharBufferCode
+ *code*
+ %End
+
+This directive (along with :directive:`%BIGetReadBufferCode`,
+:directive:`%BIGetSegCountCode` and :directive:`%BIGetWriteBufferCode`) is used
+to specify code that implements the buffer interface of Python v2. If Python
+v3 is being used then this is ignored.
+
+The following variables are made available to the handwritten code:
+
+*type* \*sipCpp
+ This is a pointer to the structure or class instance. Its *type* is a
+ pointer to the structure or class.
+
+void \*\*sipPtrPtr
+ This is the pointer used to return the address of the character buffer.
+
+:cmacro:`SIP_SSIZE_T` sipRes
+ The handwritten code should set this to the length of the character buffer
+ or -1 if there was an error.
+
+:cmacro:`SIP_SSIZE_T` sipSegment
+ This is the number of the segment of the character buffer.
+
+PyObject \*sipSelf
+ This is the Python object that wraps the structure or class instance, i.e.
+ ``self``.
+
+
+.. directive:: %BIGetReadBufferCode
+
+.. parsed-literal::
+
+ %BIGetReadBufferCode
+ *code*
+ %End
+
+This directive (along with :directive:`%BIGetCharBufferCode`,
+:directive:`%BIGetSegCountCode` and :directive:`%BIGetWriteBufferCode`) is used
+to specify code that implements the buffer interface of Python v2. If
+Python v3 is being used then this is ignored.
+
+The following variables are made available to the handwritten code:
+
+*type* \*sipCpp
+ This is a pointer to the structure or class instance. Its *type* is a
+ pointer to the structure or class.
+
+void \*\*sipPtrPtr
+ This is the pointer used to return the address of the read buffer.
+
+:cmacro:`SIP_SSIZE_T` sipRes
+ The handwritten code should set this to the length of the read buffer or
+ -1 if there was an error.
+
+:cmacro:`SIP_SSIZE_T` sipSegment
+ This is the number of the segment of the read buffer.
+
+PyObject \*sipSelf
+ This is the Python object that wraps the structure or class instance, i.e.
+ ``self``.
+
+
+.. directive:: %BIGetSegCountCode
+
+.. parsed-literal::
+
+ %BIGetSegCountCode
+ *code*
+ %End
+
+This directive (along with :directive:`%BIGetCharBufferCode`,
+:directive:`%BIGetReadBufferCode` and :directive:`%BIGetWriteBufferCode`) is
+used to specify code that implements the buffer interface of Python v2. If
+Python v3 is being used then this is ignored.
+
+The following variables are made available to the handwritten code:
+
+*type* \*sipCpp
+ This is a pointer to the structure or class instance. Its *type* is a
+ pointer to the structure or class.
+
+:cmacro:`SIP_SSIZE_T` \*sipLenPtr
+ This is the pointer used to return the total length in bytes of all
+ segments of the buffer.
+
+:cmacro:`SIP_SSIZE_T` sipRes
+ The handwritten code should set this to the number of segments that make
+ up the buffer.
+
+PyObject \*sipSelf
+ This is the Python object that wraps the structure or class instance, i.e.
+ ``self``.
+
+
+.. directive:: %BIGetWriteBufferCode
+
+.. parsed-literal::
+
+ %BIGetWriteBufferCode
+ *code*
+ %End
+
+This directive (along with :directive:`%BIGetCharBufferCode`,
+:directive:`%BIGetReadBufferCode` and :directive:`%BIGetSegCountCode` is used
+to specify code that implements the buffer interface of Python v2. If Python
+v3 is being used then this is ignored.
+
+The following variables are made available to the handwritten code:
+
+*type* \*sipCpp
+ This is a pointer to the structure or class instance. Its *type* is a
+ pointer to the structure or class.
+
+void \*\*sipPtrPtr
+ This is the pointer used to return the address of the write buffer.
+
+:cmacro:`SIP_SSIZE_T` sipRes
+ The handwritten code should set this to the length of the write buffer or
+ -1 if there was an error.
+
+:cmacro:`SIP_SSIZE_T` sipSegment
+ This is the number of the segment of the write buffer.
+
+PyObject \*sipSelf
+ This is the Python object that wraps the structure or class instance, i.e.
+ ``self``.
+
+
+.. directive:: %BIReleaseBufferCode
+
+.. parsed-literal::
+
+ %BIReleaseBufferCode
+ *code*
+ %End
+
+This directive (along with :directive:`%BIGetBufferCode`) is used to specify
+code that implements the buffer interface of Python v3. If Python v2 is being
+used then this is ignored.
+
+The following variables are made available to the handwritten code:
+
+Py_buffer \*sipBuffer
+ This is a pointer to the Python buffer structure.
+
+*type* \*sipCpp
+ This is a pointer to the structure or class instance. Its *type* is a
+ pointer to the structure or class.
+
+PyObject \*sipSelf
+ This is the Python object that wraps the structure or class instance, i.e.
+ ``self``.
+
+
+.. directive:: %CModule
+
+.. parsed-literal::
+
+ %CModule *name* [*version*]
+
+This directive is used to identify that the library being wrapped is a C
+library and to define the name of the module and it's optional version number.
+
+See the :directive:`%Module` directive for an explanation of the version
+number.
+
+For example::
+
+ %CModule dbus 1
+
+
+.. directive:: %CompositeModule
+
+.. parsed-literal::
+
+ %CompositeModule *name*
+
+A composite module is one that merges a number of related SIP generated
+modules. For example, a module that merges the modules ``a_mod``, ``b_mod``
+and ``c_mod`` is equivalent to the following pure Python module::
+
+ from a_mod import *
+ from b_mod import *
+ from c_mod import *
+
+Clearly the individual modules should not define module-level objects with the
+same name.
+
+This directive is used to specify the name of a composite module. Any
+subsequent :directive:`%CModule` or :directive:`%Module` directive is
+interpreted as defining a component module.
+
+For example::
+
+ %CompositeModule PyQt4.Qt
+ %Include QtCore/QtCoremod.sip
+ %Include QtGui/QtGuimod.sip
+
+The main purpose of a composite module is as a programmer convenience as they
+don't have to remember which which individual module an object is defined in.
+
+
+.. directive:: %ConsolidatedModule
+
+.. parsed-literal::
+
+ %ConsolidatedModule *name*
+
+A consolidated module is one that consolidates the wrapper code of a number of
+SIP generated modules (refered to as component modules in this context).
+
+This directive is used to specify the name of a consolidated module. Any
+subsequent :directive:`%CModule` or :directive:`%Module` directive is
+interpreted as defining a component module.
+
+For example::
+
+ %ConsolidatedModule PyQt4._qt
+ %Include QtCore/QtCoremod.sip
+ %Include QtGui/QtGuimod.sip
+
+A consolidated module is not intended to be explicitly imported by an
+application. Instead it is imported by its component modules when they
+themselves are imported.
+
+Normally the wrapper code is contained in the component module and is linked
+against the corresponding C or C++ library. The advantage of a consolidated
+module is that it allows all of the wrapped C or C++ libraries to be linked
+against a single module. If the linking is done statically then deployment of
+generated modules can be greatly simplified.
+
+It follows that a component module can be built in one of two ways, as a
+normal standalone module, or as a component of a consolidated module. When
+building as a component the ``-p`` command line option should be used to
+specify the name of the consolidated module.
+
+
+.. directive:: %ConvertFromTypeCode
+
+.. parsed-literal::
+
+ %ConvertFromTypeCode
+ *code*
+ %End
+
+This directive is used as part of the :directive:`%MappedType` directive to
+specify the handwritten code that converts an instance of a mapped type to a
+Python object.
+
+The following variables are made available to the handwritten code:
+
+*type* \*sipCpp
+ This is a pointer to the instance of the mapped type to be converted. It
+ will never be zero as the conversion from zero to ``Py_None`` is handled
+ before the handwritten code is called.
+
+PyObject \*sipTransferObj
+ This specifies any desired ownership changes to the returned object. If it
+ is ``NULL`` then the ownership should be left unchanged. If it is
+ ``Py_None`` then ownership should be transferred to Python. Otherwise
+ ownership should be transferred to C/C++ and the returned object associated
+ with *sipTransferObj*. The code can choose to interpret these changes in
+ any way. For example, if the code is converting a C++ container of wrapped
+ classes to a Python list it is likely that the ownership changes should be
+ made to each element of the list.
+
+The handwritten code must explicitly return a ``PyObject *``. If there was an
+error then a Python exception must be raised and ``NULL`` returned.
+
+The following example converts a ``QList<QWidget *>`` instance to a Python
+list of ``QWidget`` instances::
+
+ %ConvertFromTypeCode
+ PyObject *l;
+
+ // Create the Python list of the correct length.
+ if ((l = PyList_New(sipCpp->size())) == NULL)
+ return NULL;
+
+ // Go through each element in the C++ instance and convert it to a
+ // wrapped QWidget.
+ for (int i = 0; i < sipCpp->size(); ++i)
+ {
+ QWidget *w = sipCpp->at(i);
+ PyObject *wobj;
+
+ // Get the Python wrapper for the QWidget instance, creating a new
+ // one if necessary, and handle any ownership transfer.
+ if ((wobj = sipConvertFromType(w, sipType_QWidget, sipTransferObj)) == NULL)
+ {
+ // There was an error so garbage collect the Python list.
+ Py_DECREF(l);
+ return NULL;
+ }
+
+ // Add the wrapper to the list.
+ PyList_SET_ITEM(l, i, wobj);
+ }
+
+ // Return the Python list.
+ return l;
+ %End
+
+
+.. directive:: %ConvertToSubClassCode
+
+.. parsed-literal::
+
+ %ConvertToSubClassCode
+ *code*
+ %End
+
+When SIP needs to wrap a C++ class instance it first checks to make sure it
+hasn't already done so. If it has then it just returns a new reference to the
+corresponding Python object. Otherwise it creates a new Python object of the
+appropriate type. In C++ a function may be defined to return an instance of a
+certain class, but can often return a sub-class instead.
+
+This directive is used to specify handwritten code that exploits any available
+real-time type information (RTTI) to see if there is a more specific Python
+type that can be used when wrapping the C++ instance. The RTTI may be
+provided by the compiler or by the C++ instance itself.
+
+The directive is included in the specification of one of the classes that the
+handwritten code handles the type conversion for. It doesn't matter which
+one, but a sensible choice would be the one at the root of that class
+hierarchy in the module.
+
+Note that if a class hierarchy extends over a number of modules then this
+directive should be used in each of those modules to handle the part of the
+hierarchy defined in that module. SIP will ensure that the different pieces
+of code are called in the right order to determine the most specific Python
+type to use.
+
+The following variables are made available to the handwritten code:
+
+*type* \*sipCpp
+ This is a pointer to the C++ class instance.
+
+void \*\*sipCppRet
+ When the sub-class is derived from more than one super-class then it is
+ possible that the C++ address of the instance as the sub-class is
+ different to that of the super-class. If so, then this must be set to the
+ C++ address of the instance when cast (usually using ``static_cast``)
+ from the super-class to the sub-class.
+
+const sipTypeDef \*sipType
+ The handwritten code must set this to the SIP generated type structure
+ that corresponds to the class instance. (The type structure for class
+ ``Klass`` is ``sipType_Klass``.) If the RTTI of the class instance isn't
+ recognised then ``sipType`` must be set to ``NULL``. The code doesn't
+ have to recognise the exact class, only the most specific sub-class that
+ it can.
+
+sipWrapperType \*sipClass
+ The handwritten code must set this to the SIP generated Python type object
+ that corresponds to the class instance. (The type object for class
+ ``Klass`` is ``sipClass_Klass``.) If the RTTI of the class instance isn't
+ recognised then ``sipClass`` must be set to ``NULL``. The code doesn't
+ have to recognise the exact class, only the most specific sub-class that
+ it can.
+
+ This is deprecated from SIP v4.8. Instead you should use ``sipType``.
+
+The handwritten code must not explicitly return.
+
+The following example shows the sub-class conversion code for ``QEvent`` based
+class hierarchy in PyQt::
+
+ class QEvent
+ {
+ %ConvertToSubClassCode
+ // QEvent sub-classes provide a unique type ID.
+ switch (sipCpp->type())
+ {
+ case QEvent::Timer:
+ sipType = sipType_QTimerEvent;
+ break;
+
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ sipType = sipType_QKeyEvent;
+ break;
+
+ // Skip the remaining event types to keep the example short.
+
+ default:
+ // We don't recognise the type.
+ sipType = NULL;
+ }
+ %End
+
+ // The rest of the class specification.
+
+ };
+
+
+.. directive:: %ConvertToTypeCode
+
+.. parsed-literal::
+
+ %ConvertToTypeCode
+ *code*
+ %End
+
+This directive is used to specify the handwritten code that converts a Python
+object to a mapped type instance and to handle any ownership transfers. It is
+used as part of the :directive:`%MappedType` directive and as part of a class
+specification. The code is also called to determine if the Python object is of
+the correct type prior to conversion.
+
+When used as part of a class specification it can automatically convert
+additional types of Python object. For example, PyQt uses it in the
+specification of the ``QString`` class to allow Python string objects and
+unicode objects to be used wherever ``QString`` instances are expected.
+
+The following variables are made available to the handwritten code:
+
+int \*sipIsErr
+ If this is ``NULL`` then the code is being asked to check the type of the
+ Python object. The check must not have any side effects. Otherwise the
+ code is being asked to convert the Python object and a non-zero value
+ should be returned through this pointer if an error occurred during the
+ conversion.
+
+PyObject \*sipPy
+ This is the Python object to be converted.
+
+*type* \*\*sipCppPtr
+ This is a pointer through which the address of the mapped type instance (or
+ zero if appropriate) is returned. Its value is undefined if ``sipIsErr``
+ is ``NULL``.
+
+PyObject \*sipTransferObj
+ This specifies any desired ownership changes to *sipPy*. If it is ``NULL``
+ then the ownership should be left unchanged. If it is ``Py_None`` then
+ ownership should be transferred to Python. Otherwise ownership should be
+ transferred to C/C++ and *sipPy* associated with *sipTransferObj*. The
+ code can choose to interpret these changes in any way.
+
+The handwritten code must explicitly return an ``int`` the meaning of which
+depends on the value of ``sipIsErr``.
+
+If ``sipIsErr`` is ``NULL`` then a non-zero value is returned if the Python
+object has a type that can be converted to the mapped type. Otherwise zero is
+returned.
+
+If ``sipIsErr`` is not ``NULL`` then a combination of the following flags is
+returned.
+
+ - :cmacro:`SIP_TEMPORARY` is set to indicate that the returned instance
+ is a temporary and should be released to avoid a memory leak.
+
+ - :cmacro:`SIP_DERIVED_CLASS` is set to indicate that the type of the
+ returned instance is a derived class. See
+ :ref:`ref-derived-classes`.
+
+The following example converts a Python list of ``QPoint`` instances to a
+``QList<QPoint>`` instance::
+
+ %ConvertToTypeCode
+ // See if we are just being asked to check the type of the Python
+ // object.
+ if (!sipIsErr)
+ {
+ // Checking whether or not None has been passed instead of a list
+ // has already been done.
+ if (!PyList_Check(sipPy))
+ return 0;
+
+ // Check the type of each element. We specify SIP_NOT_NONE to
+ // disallow None because it is a list of QPoint, not of a pointer
+ // to a QPoint, so None isn't appropriate.
+ for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i)
+ if (!sipCanConvertToType(PyList_GET_ITEM(sipPy, i),
+ sipType_QPoint, SIP_NOT_NONE))
+ return 0;
+
+ // The type is valid.
+ return 1;
+ }
+
+ // Create the instance on the heap.
+ QList<QPoint> *ql = new QList<QPoint>;
+
+ for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i)
+ {
+ QPoint *qp;
+ int state;
+
+ // Get the address of the element's C++ instance. Note that, in
+ // this case, we don't apply any ownership changes to the list
+ // elements, only to the list itself.
+ qp = reinterpret_cast<QPoint *>(sipConvertToType(
+ PyList_GET_ITEM(sipPy, i),
+ sipType_QPoint, 0,
+ SIP_NOT_NONE,
+ &state, sipIsErr));
+
+ // Deal with any errors.
+ if (*sipIsErr)
+ {
+ sipReleaseType(qp, sipType_QPoint, state);
+
+ // Tidy up.
+ delete ql;
+
+ // There is no temporary instance.
+ return 0;
+ }
+
+ ql->append(*qp);
+
+ // A copy of the QPoint was appended to the list so we no longer
+ // need it. It may be a temporary instance that should be
+ // destroyed, or a wrapped instance that should not be destroyed.
+ // sipReleaseType() will do the right thing.
+ sipReleaseType(qp, sipType_QPoint, state);
+ }
+
+ // Return the instance.
+ *sipCppPtr = ql;
+
+ // The instance should be regarded as temporary (and be destroyed as
+ // soon as it has been used) unless it has been transferred from
+ // Python. sipGetState() is a convenience function that implements
+ // this common transfer behaviour.
+ return sipGetState(sipTransferObj);
+ %End
+
+When used in a class specification the handwritten code replaces the code that
+would normally be automatically generated. This means that the handwritten
+code must also handle instances of the class itself and not just the additional
+types that are being supported. This should be done by making calls to
+:cfunc:`sipCanConvertToType()` to check the object type and
+:cfunc:`sipConvertToType()` to convert the object. The
+:cmacro:`SIP_NO_CONVERTORS` flag *must* be passed to both these functions to
+prevent recursive calls to the handwritten code.
+
+
+.. directive:: %Copying
+
+.. parsed-literal::
+
+ %Copying
+ *text*
+ %End
+
+This directive is used to specify some arbitrary text that will be included at
+the start of all source files generated by SIP. It is normally used to
+include copyright and licensing terms.
+
+For example::
+
+ %Copying
+ Copyright (c) 2009 Riverbank Computing Limited
+ %End
+
+
+.. directive:: %DefaultEncoding
+
+.. parsed-literal::
+
+ %DefaultEncoding *string*
+
+This directive is used to specify the default encoding used for ``char``,
+``const char``, ``char *`` or ``const char *`` values. The encoding can be
+either ``"ASCII"``, ``"Latin-1"``, ``"UTF-8"`` or ``"None"``. An encoding of
+``"None"`` means that the value is unencoded. The default can be overridden
+for a particular value using the :aanno:`Encoding` annotation. If the
+directive is not specified then ``"None"`` is used.
+
+For example::
+
+ %DefaultEncoding "Latin-1"
+
+
+.. directive:: %DefaultMetatype
+
+.. parsed-literal::
+
+ %DefaultMetatype *dotted-name*
+
+This directive is used to specify the Python type that should be used as the
+meta-type for any C/C++ data type defined in the same module, and by importing
+modules, that doesn't have an explicit meta-type.
+
+If this is not specified then ``sip.wrappertype`` is used.
+
+You can also use the :canno:`Metatype` class annotation to specify the
+meta-type used by a particular C/C++ type.
+
+See the section :ref:`ref-types-metatypes` for more details.
+
+For example::
+
+ %DefaultMetatype PyQt4.QtCore.pyqtWrapperType
+
+
+.. directive:: %DefaultSupertype
+
+.. parsed-literal::
+
+ %DefaultSupertype *dotted-name*
+
+This directive is used to specify the Python type that should be used as the
+super-type for any C/C++ data type defined in the same module that doesn't have
+an explicit super-type.
+
+If this is not specified then ``sip.wrapper`` is used.
+
+You can also use the :canno:`Supertype` class annotation to specify the
+super-type used by a particular C/C++ type.
+
+See the section :ref:`ref-types-metatypes` for more details.
+
+For example::
+
+ %DefaultSupertype sip.simplewrapper
+
+
+.. directive:: %Doc
+
+.. parsed-literal::
+
+ %Doc
+ *text*
+ %End
+
+This directive is used to specify some arbitrary text that will be extracted
+by SIP when the ``-d`` command line option is used. The directive can be
+specified any number of times and SIP will concatenate all the separate pieces
+of text in the order that it sees them.
+
+Documentation that is specified using this directive is local to the module in
+which it appears. It is ignored by modules that :directive:`%Import` it. Use
+the :directive:`%ExportedDoc` directive for documentation that should be
+included by all modules that :directive:`%Import` this one.
+
+For example::
+
+ %Doc
+ <h1>An Example</h1>
+ <p>
+ This fragment of documentation is HTML and is local to the module in
+ which it is defined.
+ </p>
+ %End
+
+
+.. directive:: %Docstring
+
+.. parsed-literal::
+
+ %Docstring
+ *text*
+ %End
+
+.. versionadded:: 4.10
+
+This directive is used to specify explicit docstrings for classes, functions
+and methods.
+
+The docstring of a class is made up of the docstring specified for the class
+itself, with the docstrings specified for each contructor appended.
+
+The docstring of a function or method is made up of the concatenated docstrings
+specified for each of the overloads.
+
+Specifying an explicit docstring will prevent SIP from generating an automatic
+docstring that describes the Python signature of a function or method overload.
+This means that SIP will generate less informative exceptions (i.e. without a
+full signature) when it fails to match a set of arguments to any function or
+method overload.
+
+For example::
+
+ class Klass
+ {
+ %Docstring
+ This will be at the start of the class's docstring.
+ %End
+
+ public:
+ Klass();
+ %Docstring
+ This will be appended to the class's docstring.
+ %End
+ };
+
+
+.. directive:: %End
+
+This isn't a directive in itself, but is used to terminate a number of
+directives that allow a block of handwritten code or text to be specified.
+
+
+.. directive:: %Exception
+
+.. parsed-literal::
+
+ %Exception *name* [(*base-exception)]
+ {
+ [*header-code*]
+ *raise-code*
+ };
+
+This directive is used to define new Python exceptions, or to provide a stub
+for existing Python exceptions. It allows handwritten code to be provided
+that implements the translation between C++ exceptions and Python exceptions.
+The arguments to ``throw ()`` specifiers must either be names of classes or the
+names of Python exceptions defined by this directive.
+
+*name* is the name of the exception.
+
+*base-exception* is the optional base exception. This may be either one of
+the standard Python exceptions or one defined with a previous
+:directive:`%Exception` directive.
+
+*header-code* is the optional :directive:`%TypeHeaderCode` used to specify any
+external interface to the exception being defined.
+
+*raise-code* is the :directive:`%RaiseCode` used to specify the handwritten
+code that converts a reference to the C++ exception to the Python exception.
+
+For example::
+
+ %Exception std::exception(SIP_Exception) /PyName=StdException/
+ {
+ %TypeHeaderCode
+ #include <exception>
+ %End
+ %RaiseCode
+ const char *detail = sipExceptionRef.what();
+
+ SIP_BLOCK_THREADS
+ PyErr_SetString(sipException_std_exception, detail);
+ SIP_UNBLOCK_THREADS
+ %End
+ };
+
+In this example we map the standard C++ exception to a new Python exception.
+The new exception is called ``StdException`` and is derived from the standard
+Python exception ``Exception``.
+
+An exception may be annotated with :xanno:`Default` to specify that it should
+be caught by default if there is no ``throw`` clause.
+
+
+.. directive:: %ExportedDoc
+
+.. parsed-literal::
+
+ %ExportedDoc
+ *text*
+ %End
+
+This directive is used to specify some arbitrary text that will be extracted
+by SIP when the ``-d`` command line option is used. The directive can be
+specified any number of times and SIP will concatenate all the separate pieces
+of text in the order that it sees them.
+
+Documentation that is specified using this directive will also be included by
+modules that :directive:`%Import` it.
+
+For example::
+
+ %ExportedDoc
+ ==========
+ An Example
+ ==========
+
+ This fragment of documentation is reStructuredText and will appear in the
+ module in which it is defined and all modules that %Import it.
+ %End
+
+
+.. directive:: %ExportedHeaderCode
+
+.. parsed-literal::
+
+ %ExportedHeaderCode
+ *code*
+ %End
+
+This directive is used to specify handwritten code, typically the declarations
+of types, that is placed in a header file that is included by all generated
+code for all modules. It should not include function declarations because
+Python modules should not explicitly call functions in another Python module.
+
+See also :directive:`%ModuleCode` and :directive:`%ModuleHeaderCode`.
+
+
+.. directive:: %Feature
+
+.. parsed-literal::
+
+ %Feature *name*
+
+This directive is used to declare a feature. Features (along with
+:directive:`%Platforms` and :directive:`%Timeline`) are used by the
+:directive:`%If` directive to control whether or not parts of a specification
+are processed or ignored.
+
+Features are mutually independent of each other - any combination of features
+may be enabled or disable. By default all features are enabled. The SIP
+``-x`` command line option is used to disable a feature.
+
+If a feature is enabled then SIP will automatically generate a corresponding C
+preprocessor symbol for use by handwritten code. The symbol is the name of
+the feature prefixed by ``SIP_FEATURE_``.
+
+For example::
+
+ %Feature FOO_SUPPORT
+
+ %If (FOO_SUPPORT)
+ void foo();
+ %End
+
+
+.. directive:: %GCClearCode
+
+.. parsed-literal::
+
+ %GCClearCode
+ *code*
+ %End
+
+Python has a cyclic garbage collector which can identify and release unneeded
+objects even when their reference counts are not zero. If a wrapped C
+structure or C++ class keeps its own reference to a Python object then, if the
+garbage collector is to do its job, it needs to provide some handwritten code
+to traverse and potentially clear those embedded references.
+
+See the section *Supporting cyclic garbage collection* in `Embedding and
+Extending the Python Interpreter <http://www.python.org/dev/doc/devel/ext/>`__
+for the details.
+
+This directive is used to specify the code that clears any embedded references.
+(See :directive:`%GCTraverseCode` for specifying the code that traverses any
+embedded references.)
+
+The following variables are made available to the handwritten code:
+
+*type* \*sipCpp
+ This is a pointer to the structure or class instance. Its *type* is a
+ pointer to the structure or class.
+
+int sipRes
+ The handwritten code should set this to the result to be returned.
+
+The following simplified example is taken from PyQt. The ``QCustomEvent``
+class allows arbitary data to be attached to the event. In PyQt this data is
+always a Python object and so should be handled by the garbage collector::
+
+ %GCClearCode
+ PyObject *obj;
+
+ // Get the object.
+ obj = reinterpret_cast<PyObject *>(sipCpp->data());
+
+ // Clear the pointer.
+ sipCpp->setData(0);
+
+ // Clear the reference.
+ Py_XDECREF(obj);
+
+ // Report no error.
+ sipRes = 0;
+ %End
+
+
+.. directive:: %GCTraverseCode
+
+.. parsed-literal::
+
+ %GCTraverseCode
+ *code*
+ %End
+
+This directive is used to specify the code that traverses any embedded
+references for Python's cyclic garbage collector. (See
+:directive:`%GCClearCode` for a full explanation.)
+
+The following variables are made available to the handwritten code:
+
+*type* \*sipCpp
+ This is a pointer to the structure or class instance. Its *type* is a
+ pointer to the structure or class.
+
+visitproc sipVisit
+ This is the visit function provided by the garbage collector.
+
+void \*sipArg
+ This is the argument to the visit function provided by the garbage
+ collector.
+
+int sipRes
+ The handwritten code should set this to the result to be returned.
+
+The following simplified example is taken from PyQt's ``QCustomEvent`` class::
+
+ %GCTraverseCode
+ PyObject *obj;
+
+ // Get the object.
+ obj = reinterpret_cast<PyObject *>(sipCpp->data());
+
+ // Call the visit function if there was an object.
+ if (obj)
+ sipRes = sipVisit(obj, sipArg);
+ else
+ sipRes = 0;
+ %End
+
+
+.. directive:: %GetCode
+
+.. parsed-literal::
+
+ %GetCode
+ *code*
+ %End
+
+This directive is used after the declaration of a C++ class variable or C
+structure member to specify handwritten code to convert it to a Python object.
+It is usually used to handle types that SIP cannot deal with automatically.
+
+The following variables are made available to the handwritten code:
+
+*type* \*sipCpp
+ This is a pointer to the structure or class instance. Its *type* is a
+ pointer to the structure or class. It is not made available if the
+ variable being wrapped is a static class variable.
+
+PyObject \*sipPy
+ The handwritten code must set this to the Python representation of the
+ class variable or structure member. If there is an error then the code
+ must raise an exception and set this to ``NULL``.
+
+PyObject \*sipPyType
+ If the variable being wrapped is a static class variable then this is the
+ Python type object of the class from which the variable was referenced
+ (*not* the class in which it is defined). It may be safely cast to a
+ PyTypeObject \* or a sipWrapperType \*.
+
+For example::
+
+ struct Entity
+ {
+ /*
+ * In this contrived example the C library we are wrapping actually
+ * defines this as char buffer[100] which SIP cannot handle
+ * automatically.
+ */
+ char *buffer;
+ %GetCode
+ sipPy = PyString_FromStringAndSize(sipCpp->buffer, 100);
+ %End
+ %SetCode
+ char *ptr;
+ int length;
+
+ if (PyString_AsStringAndSize(sipPy, &ptr, &length) == -1)
+ sipErr = 1;
+ else if (length != 100)
+ {
+ /*
+ * Raise an exception because the length isn't exactly right.
+ */
+
+ PyErr_SetString(PyExc_ValueError, "an Entity.buffer must be exactly 100 bytes");
+ sipErr = 1;
+ }
+ else
+ memcpy(sipCpp->buffer, ptr, 100);
+ %End
+ }
+
+
+.. directive:: %If
+
+.. parsed-literal::
+
+ %If (*expression*)
+ *specification*
+ %End
+
+where
+
+.. parsed-literal::
+
+ *expression* ::= [*ored-qualifiers* | *range*]
+
+ *ored-qualifiers* ::= [*qualifier* | *qualifier* **||** *ored-qualifiers*]
+
+ *qualifier* ::= [**!**] [*feature* | *platform*]
+
+ *range* ::= [*version*] **-** [*version*]
+
+This directive is used in conjunction with features (see
+:directive:`%Feature`), platforms (see :directive:`%Platforms`) and versions
+(see :directive:`%Timeline`) to control whether or not parts of a specification
+are processed or not.
+
+A *range* of versions means all versions starting with the lower bound up to
+but excluding the upper bound. If the lower bound is omitted then it is
+interpreted as being before the earliest version. If the upper bound is
+omitted then it is interpreted as being after the latest version.
+
+For example::
+
+ %Feature SUPPORT_FOO
+ %Platforms {WIN32_PLATFORM POSIX_PLATFORM MACOS_PLATFORM}
+ %Timeline {V1_0 V1_1 V2_0 V3_0}
+
+ %If (!SUPPORT_FOO)
+ // Process this if the SUPPORT_FOO feature is disabled.
+ %End
+
+ %If (POSIX_PLATFORM || MACOS_PLATFORM)
+ // Process this if either the POSIX_PLATFORM or MACOS_PLATFORM
+ // platforms are enabled.
+ %End
+
+ %If (V1_0 - V2_0)
+ // Process this if either V1_0 or V1_1 is enabled.
+ %End
+
+ %If (V2_0 - )
+ // Process this if either V2_0 or V3_0 is enabled.
+ %End
+
+ %If ( - )
+ // Always process this.
+ %End
+
+Note that this directive is not implemented as a preprocessor. Only the
+following parts of a specification are affected by it:
+
+ - :directive:`%API`
+ - ``class``
+ - :directive:`%ConvertFromTypeCode`
+ - :directive:`%ConvertToSubClassCode`
+ - :directive:`%ConvertToTypeCode`
+ - ``enum``
+ - :directive:`%DefaultEncoding`
+ - :directive:`%DefaultMetatype`
+ - :directive:`%DefaultSupertype`
+ - :directive:`%ExportedHeaderCode`
+ - functions
+ - :directive:`%GCClearCode`
+ - :directive:`%GCTraverseCode`
+ - :directive:`%If`
+ - :directive:`%InitialisationCode`
+ - :directive:`%MappedType`
+ - :directive:`%MethodCode`
+ - :directive:`%ModuleCode`
+ - :directive:`%ModuleHeaderCode`
+ - ``namespace``
+ - :directive:`%PostInitialisationCode`
+ - :directive:`%PreInitialisationCode`
+ - ``struct``
+ - ``typedef``
+ - :directive:`%TypeCode`
+ - :directive:`%TypeHeaderCode`
+ - :directive:`%UnitCode`
+ - variables
+ - :directive:`%VirtualCatcherCode`
+
+Also note that the only way to specify the logical and of qualifiers is to use
+nested :directive:`%If` directives.
+
+
+.. directive:: %Import
+
+.. parsed-literal::
+
+ %Import *filename*
+
+This directive is used to import the specification of another module. This is
+needed if the current module makes use of any types defined in the imported
+module, e.g. as an argument to a function, or to sub-class.
+
+If *filename* cannot be opened then SIP prepends *filename* with the name of
+the directory containing the current specification file (i.e. the one
+containing the :directive:`%Import` directive) and tries again. If this also
+fails then SIP prepends *filename* with each of the directories, in turn,
+specified by the ``-I`` command line option.
+
+For example::
+
+ %Import qt/qtmod.sip
+
+
+.. directive:: %Include
+
+.. parsed-literal::
+
+ %Include *filename*
+
+This directive is used to include contents of another file as part of the
+specification of the current module. It is the equivalent of the C
+preprocessor's ``#include`` directive and is used to structure a large module
+specification into manageable pieces.
+
+:directive:`%Include` follows the same search process as :directive:`%Import`
+when trying to open *filename*.
+
+For example::
+
+ %Include qwidget.sip
+
+
+.. directive:: %InitialisationCode
+
+.. parsed-literal::
+
+ %InitialisationCode
+ *code*
+ %End
+
+This directive is used to specify handwritten code that is embedded in-line
+in the generated module initialisation code after the SIP module has been
+imported but before the module itself has been initialised.
+
+It is typically used to call :cfunc:`sipRegisterPyType()`.
+
+For example::
+
+ %InitialisationCode
+ // The code will be executed when the module is first imported, after
+ // the SIP module has been imported, but before other module-specific
+ // initialisation has been completed.
+ %End
+
+
+.. directive:: %License
+
+.. parsed-literal::
+
+ %License /*license-annotations*/
+
+This directive is used to specify the contents of an optional license
+dictionary. The license dictionary is called :data:`__license__` and is stored
+in the module dictionary. The elements of the dictionary are specified using
+the :lanno:`Licensee`, :lanno:`Signature`, :lanno:`Timestamp` and :lanno:`Type`
+annotations. Only the :lanno:`Type` annotation is compulsory.
+
+Note that this directive isn't an attempt to impose any licensing restrictions
+on a module. It is simply a method for easily embedding licensing information
+in a module so that it is accessible to Python scripts.
+
+For example::
+
+ %License /Type="GPL"/
+
+
+.. directive:: %MappedType
+
+.. parsed-literal::
+
+ template<*type-list*>
+ %MappedType *type*
+ {
+ [*header-code*]
+ [*convert-to-code*]
+ [*convert-from-code*]
+ };
+
+ %MappedType *type*
+ {
+ [*header-code*]
+ [*convert-to-code*]
+ [*convert-from-code*]
+ };
+
+This directive is used to define an automatic mapping between a C or C++ type
+and a Python type. It can be used as part of a template, or to map a specific
+type.
+
+When used as part of a template *type* cannot itself refer to a template. Any
+occurrences of any of the type names (but not any ``*`` or ``&``) in
+*type-list* will be replaced by the actual type names used when the template is
+instantiated. Template mapped types are instantiated automatically as required
+(unlike template classes which are only instantiated using ``typedef``).
+
+Any explicit mapped type will be used in preference to any template that maps
+the same type, ie. a template will not be automatically instantiated if there
+is an explicit mapped type.
+
+*header-code* is the :directive:`%TypeHeaderCode` used to specify the library
+interface to the type being mapped.
+
+*convert-to-code* is the :directive:`%ConvertToTypeCode` used to specify the
+handwritten code that converts a Python object to an instance of the mapped
+type.
+
+*convert-from-code* is the :directive:`%ConvertFromTypeCode` used to specify
+the handwritten code that converts an instance of the mapped type to a Python
+object.
+
+For example::
+
+ template<Type *>
+ %MappedType QList
+ {
+ %TypeHeaderCode
+ // Include the library interface to the type being mapped.
+ #include <qlist.h>
+ %End
+
+ %ConvertToTypeCode
+ // See if we are just being asked to check the type of the Python
+ // object.
+ if (sipIsErr == NULL)
+ {
+ // Check it is a list.
+ if (!PyList_Check(sipPy))
+ return 0;
+
+ // Now check each element of the list is of the type we expect.
+ // The template is for a pointer type so we don't disallow None.
+ for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i)
+ if (!sipCanConvertToType(PyList_GET_ITEM(sipPy, i),
+ sipType_Type, 0))
+ return 0;
+
+ return 1;
+ }
+
+ // Create the instance on the heap.
+ QList<Type *> *ql = new QList<Type *>;
+
+ for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i)
+ {
+ // Use the SIP API to convert the Python object to the
+ // corresponding C++ instance. Note that we apply any ownership
+ // transfer to the list itself, not the individual elements.
+ Type *t = reinterpret_cast<Type *>(sipConvertToType(
+ PyList_GET_ITEM(sipPy, i),
+ sipType_Type, 0, 0, 0,
+ sipIsErr));
+
+ if (*sipIsErr)
+ {
+ // Tidy up.
+ delete ql;
+
+ // There is nothing on the heap.
+ return 0;
+ }
+
+ // Add the pointer to the C++ instance.
+ ql->append(t);
+ }
+
+ // Return the instance on the heap.
+ *sipCppPtr = ql;
+
+ // Apply the normal transfer.
+ return sipGetState(sipTransferObj);
+ %End
+
+ %ConvertFromTypeCode
+ PyObject *l;
+
+ // Create the Python list of the correct length.
+ if ((l = PyList_New(sipCpp->size())) == NULL)
+ return NULL;
+
+ // Go through each element in the C++ instance and convert it to the
+ // corresponding Python object.
+ for (int i = 0; i < sipCpp->size(); ++i)
+ {
+ Type *t = sipCpp->at(i);
+ PyObject *tobj;
+
+ if ((tobj = sipConvertFromType(t, sipType_Type, sipTransferObj)) == NULL)
+ {
+ // There was an error so garbage collect the Python list.
+ Py_DECREF(l);
+ return NULL;
+ }
+
+ PyList_SET_ITEM(l, i, tobj);
+ }
+
+ // Return the Python list.
+ return l;
+ %End
+ }
+
+Using this we can use, for example, ``QList<QObject *>`` throughout the
+module's specification files (and in any module that imports this one). The
+generated code will automatically map this to and from a Python list of QObject
+instances when appropriate.
+
+
+.. directive:: %MethodCode
+
+.. parsed-literal::
+
+ %MethodCode
+ *code*
+ %End
+
+This directive is used as part of the specification of a global function, class
+method, operator, constructor or destructor to specify handwritten code that
+replaces the normally generated call to the function being wrapped. It is
+usually used to handle argument types and results that SIP cannot deal with
+automatically.
+
+Normally the specified code is embedded in-line after the function's arguments
+have been successfully converted from Python objects to their C or C++
+equivalents. In this case the specified code must not include any ``return``
+statements.
+
+However if the :fanno:`NoArgParser` annotation has been used then the specified
+code is also responsible for parsing the arguments. No other code is generated
+by SIP and the specified code must include a ``return`` statement.
+
+In the context of a destructor the specified code is embedded in-line in the
+Python type's deallocation function. Unlike other contexts it supplements
+rather than replaces the normally generated code, so it must not include code
+to return the C structure or C++ class instance to the heap. The code is only
+called if ownership of the structure or class is with Python.
+
+The specified code must also handle the Python Global Interpreter Lock (GIL).
+If compatibility with SIP v3.x is required then the GIL must be released
+immediately before the C++ call and reacquired immediately afterwards as shown
+in this example fragment::
+
+ Py_BEGIN_ALLOW_THREADS
+ sipCpp->foo();
+ Py_END_ALLOW_THREADS
+
+If compatibility with SIP v3.x is not required then this is optional but
+should be done if the C++ function might block the current thread or take a
+significant amount of time to execute. (See :ref:`ref-gil` and the
+:fanno:`ReleaseGIL` and :fanno:`HoldGIL` annotations.)
+
+If the :fanno:`NoArgParser` annotation has not been used then the following
+variables are made available to the handwritten code:
+
+*type* a0
+ There is a variable for each argument of the Python signature (excluding
+ any ``self`` argument) named ``a0``, ``a1``, etc. The *type* of the
+ variable is the same as the type defined in the specification with the
+ following exceptions:
+
+ - if the argument is only used to return a value (e.g. it is an ``int *``
+ without an :aanno:`In` annotation) then the type has one less level of
+ indirection (e.g. it will be an ``int``)
+ - if the argument is a structure or class (or a reference or a pointer to a
+ structure or class) then *type* will always be a pointer to the structure
+ or class.
+
+ Note that handwritten code for destructors never has any arguments.
+
+PyObject \*a0Wrapper
+ This variable is made available only if the :aanno:`GetWrapper` annotation
+ is specified for the corresponding argument. The variable is a pointer to
+ the Python object that wraps the argument.
+
+*type* \*sipCpp
+ If the directive is used in the context of a class constructor then this
+ must be set by the handwritten code to the constructed instance. If it is
+ set to ``0`` and no Python exception is raised then SIP will continue to
+ try other Python signatures.
+
+ If the directive is used in the context of a method (but not the standard
+ binary operator methods, e.g. :meth:`__add__`) or a destructor then this is
+ a pointer to the C structure or C++ class instance.
+
+ Its *type* is a pointer to the structure or class.
+
+ Standard binary operator methods follow the same convention as global
+ functions and instead define two arguments called ``a0`` and ``a1``.
+
+sipErrorState sipError
+ The handwritten code should set this to either ``sipErrorContinue`` or
+ ``sipErrorFail``, and raise an appropriate Python exception, if an error
+ is detected. Its initial value will be ``sipErrorNone``.
+
+ When ``sipErrorContinue`` is used, SIP will remember the exception as the
+ reason why the particular overloaded callable could not be invoked. It
+ will then continue to try the next overloaded callable. It is typically
+ used by code that needs to do additional type checking of the callable's
+ arguments.
+
+ When ``sipErrorFail1`` is used, SIP will report the exception immediately
+ and will not attempt to invoke other overloaded callables.
+
+ ``sipError`` is not provided for destructors.
+
+int sipIsErr
+ The handwritten code should set this to a non-zero value, and raise an
+ appropriate Python exception, if an error is detected. This is the
+ equivalent of setting ``sipError`` to ``sipErrorFail``. Its initial value
+ will be ``0``.
+
+ ``sipIsErr`` is not provided for destructors.
+
+*type* sipRes
+ The handwritten code should set this to the result to be returned. The
+ *type* of the variable is the same as the type defined in the Python
+ signature in the specification with the following exception:
+
+ - if the argument is a structure or class (or a reference or a pointer to a
+ structure or class) then *type* will always be a pointer to the structure
+ or class.
+
+ ``sipRes`` is not provided for inplace operators (e.g. ``+=`` or
+ :meth:`__imul__`) as their results are handled automatically, nor for class
+ constructors or destructors.
+
+PyObject \*sipSelf
+ If the directive is used in the context of a class constructor, destructor
+ or method then this is the Python object that wraps the structure or class
+ instance, i.e. ``self``.
+
+bool sipSelfWasArg
+ This is only made available for non-abstract, virtual methods. It is set
+ if ``self`` was explicitly passed as the first argument of the method
+ rather than being bound to the method. In other words, the call was::
+
+ Klass.foo(self, ...)
+
+ rather than::
+
+ self.foo(...)
+
+If the :fanno:`NoArgParser` annotation has been used then only the following
+variables are made available to the handwritten code:
+
+PyObject \*sipArgs
+ This is the tuple of arguments.
+
+PyObject \*sipKwds
+ This is the dictionary of keyword arguments.
+
+The following is a complete example::
+
+ class Klass
+ {
+ public:
+ virtual int foo(SIP_PYTUPLE);
+ %MethodCode
+ // The C++ API takes a 2 element array of integers but passing a
+ // two element tuple is more Pythonic.
+
+ int iarr[2];
+
+ if (PyArg_ParseTuple(a0, "ii", &iarr[0], &iarr[1]))
+ {
+ Py_BEGIN_ALLOW_THREADS
+ sipRes = sipSelfWasArg ? sipCpp->Klass::foo(iarr)
+ : sipCpp->foo(iarr);
+ Py_END_ALLOW_THREADS
+ }
+ else
+ {
+ // PyArg_ParseTuple() will have raised the exception.
+ sipIsErr = 1;
+ }
+ %End
+ };
+
+As the example is a virtual method [#]_, note the use of ``sipSelfWasArg`` to
+determine exactly which implementation of ``foo()`` to call.
+
+If a method is in the ``protected`` section of a C++ class then SIP generates
+helpers that provide access to method. However, these are not available if
+the Python module is being built with ``protected`` redefined as ``public``.
+
+The following pattern should be used to cover all possibilities::
+
+ #if defined(SIP_PROTECTED_IS_PUBLIC)
+ sipRes = sipSelfWasArg ? sipCpp->Klass::foo(iarr)
+ : sipCpp->foo(iarr);
+ #else
+ sipRes = sipCpp->sipProtectVirt_foo(sipSelfWasArg, iarr);
+ #endif
+
+If a method is in the ``protected`` section of a C++ class but is not virtual
+then the pattern should instead be::
+
+ #if defined(SIP_PROTECTED_IS_PUBLIC)
+ sipRes = sipCpp->foo(iarr);
+ #else
+ sipRes = sipCpp->sipProtect_foo(iarr);
+ #endif
+
+.. [#] See :directive:`%VirtualCatcherCode` for a description of how SIP
+ generated code handles the reimplementation of C++ virtual methods in
+ Python.
+
+
+.. directive:: %Module
+
+.. parsed-literal::
+
+ %Module *name* [*version*]
+
+This directive is used to identify that the library being wrapped is a C++
+library and to define the name of the module and it's optional version number.
+
+The name may contain periods to specify that the module is part of a Python
+package.
+
+The optional version number is useful if you (or others) might create other
+modules that build on this module, i.e. if another module might
+:directive:`%Import` this module. Under the covers, a module exports an API
+that is used by modules that :directive:`%Import` it and the API is given a
+version number. A module built on that module knows the version number of the
+API that it is expecting. If, when the modules are imported at run-time, the
+version numbers do not match then a Python exception is raised. The dependent
+module must then be re-built using the correct specification files for the base
+module.
+
+The version number should be incremented whenever a module is changed. Some
+changes don't affect the exported API, but it is good practice to change the
+version number anyway.
+
+For example::
+
+ %Module qt 5
+
+
+.. directive:: %ModuleCode
+
+.. parsed-literal::
+
+ %ModuleCode
+ *code*
+ %End
+
+This directive is used to specify handwritten code, typically the
+implementations of utility functions, that can be called by other handwritten
+code in the module.
+
+For example::
+
+ %ModuleCode
+ // Print an object on stderr for debugging purposes.
+ void dump_object(PyObject *o)
+ {
+ PyObject_Print(o, stderr, 0);
+ fprintf(stderr, "\n");
+ }
+ %End
+
+See also :directive:`%ExportedHeaderCode` and :directive:`%ModuleHeaderCode`.
+
+
+.. directive:: %ModuleHeaderCode
+
+.. parsed-literal::
+
+ %ModuleHeaderCode
+ *code*
+ %End
+
+This directive is used to specify handwritten code, typically the declarations
+of utility functions, that is placed in a header file that is included by all
+generated code for the same module.
+
+For example::
+
+ %ModuleHeaderCode
+ void dump_object(PyObject *o);
+ %End
+
+See also :directive:`%ExportedHeaderCode` and :directive:`%ModuleCode`.
+
+
+.. directive:: %OptionalInclude
+
+.. parsed-literal::
+
+ %OptionalInclude *filename*
+
+This directive is identical to the :directive:`%Include` directive except that
+SIP silently continues processing if *filename* could not be opened.
+
+For example::
+
+ %OptionalInclude license.sip
+
+
+.. directive:: %PickleCode
+
+.. parsed-literal::
+
+ %PickleCode
+ *code*
+ %End
+
+This directive is used to specify handwritten code to pickle a C structure or
+C++ class instance.
+
+The following variables are made available to the handwritten code:
+
+*type* \*sipCpp
+ This is a pointer to the structure or class instance. Its *type* is a
+ pointer to the structure or class.
+
+PyObject \*sipRes
+ The handwritten code must set this to a tuple of the arguments that will
+ be passed to the type's __init__() method when the structure or class
+ instance is unpickled. If there is an error then the code must raise an
+ exception and set this to ``NULL``.
+
+For example::
+
+ class Point
+ {
+ Point(int x, y);
+
+ int x() const;
+ int y() const;
+
+ %PickleCode
+ sipRes = Py_BuildValue("ii", sipCpp->x(), sipCpp->y());
+ %End
+ }
+
+Note that SIP works around the Python limitation that prevents nested types
+being pickled.
+
+Both named and unnamed enums can be pickled automatically without providing any
+handwritten code.
+
+
+.. directive:: %Platforms
+
+.. parsed-literal::
+
+ %Platforms {*name* *name* ...}
+
+This directive is used to declare a set of platforms. Platforms (along with
+:directive:`%Feature` and :directive:`%Timeline`) are used by the
+:directive:`%If` directive to control whether or not parts of a specification
+are processed or ignored.
+
+Platforms are mutually exclusive - only one platform can be enabled at a time.
+By default all platforms are disabled. The SIP ``-t`` command line option is
+used to enable a platform.
+
+For example::
+
+ %Platforms {WIN32_PLATFORM POSIX_PLATFORM MACOS_PLATFORM}
+
+ %If (WIN32_PLATFORM)
+ void undocumented();
+ %End
+
+ %If (POSIX_PLATFORM)
+ void documented();
+ %End
+
+
+.. directive:: %PostInitialisationCode
+
+.. parsed-literal::
+
+ %PostInitialisationCode
+ *code*
+ %End
+
+This directive is used to specify handwritten code that is embedded in-line
+at the very end of the generated module initialisation code.
+
+The following variables are made available to the handwritten code:
+
+PyObject \*sipModule
+ This is the module object returned by ``Py_InitModule()``.
+
+PyObject \*sipModuleDict
+ This is the module's dictionary object returned by ``Py_ModuleGetDict()``.
+
+For example::
+
+ %PostInitialisationCode
+ // The code will be executed when the module is first imported and
+ // after all other initialisation has been completed.
+ %End
+
+
+.. directive:: %PreInitialisationCode
+
+.. parsed-literal::
+
+ %PreInitialisationCode
+ *code*
+ %End
+
+This directive is used to specify handwritten code that is embedded in-line
+at the very start of the generated module initialisation code.
+
+For example::
+
+ %PreInitialisationCode
+ // The code will be executed when the module is first imported and
+ // before other initialisation has been completed.
+ %End
+
+
+.. directive:: %RaiseCode
+
+.. parsed-literal::
+
+ %RaiseCode
+ *code*
+ %End
+
+This directive is used as part of the definition of an exception using the
+:directive:`%Exception` directive to specify handwritten code that raises a
+Python exception when a C++ exception has been caught. The code is embedded
+in-line as the body of a C++ ``catch ()`` clause.
+
+The specified code must handle the Python Global Interpreter Lock (GIL) if
+necessary. The GIL must be acquired before any calls to the Python API and
+released after the last call as shown in this example fragment::
+
+ SIP_BLOCK_THREADS
+ PyErr_SetNone(PyErr_Exception);
+ SIP_UNBLOCK_THREADS
+
+Finally, the specified code must not include any ``return`` statements.
+
+The following variable is made available to the handwritten code:
+
+*type* &sipExceptionRef
+ This is a reference to the caught C++ exception. The *type* of the
+ reference is the same as the type defined in the ``throw ()`` specifier.
+
+See the :directive:`%Exception` directive for an example.
+
+
+.. directive:: %SetCode
+
+.. parsed-literal::
+
+ %SetCode
+ *code*
+ %End
+
+This directive is used after the declaration of a C++ class variable or C
+structure member to specify handwritten code to convert it from a Python
+object. It is usually used to handle types that SIP cannot deal with
+automatically.
+
+The following variables are made available to the handwritten code:
+
+*type* \*sipCpp
+ This is a pointer to the structure or class instance. Its *type* is a
+ pointer to the structure or class. It is not made available if the
+ variable being wrapped is a static class variable.
+
+int sipErr
+ If the conversion failed then the handwritten code should raise a Python
+ exception and set this to a non-zero value. Its initial value will be
+ automatically set to zero.
+
+PyObject \*sipPy
+ This is the Python object that the handwritten code should convert.
+
+PyObject \*sipPyType
+ If the variable being wrapped is a static class variable then this is the
+ Python type object of the class from which the variable was referenced
+ (*not* the class in which it is defined). It may be safely cast to a
+ PyTypeObject \* or a sipWrapperType \*.
+
+See the :directive:`%GetCode` directive for an example.
+
+
+.. directive:: %Timeline
+
+.. parsed-literal::
+
+ %Timeline {*name* *name* ...}
+
+This directive is used to declare a set of versions released over a period of
+time. Versions (along with :directive:`%Feature` and :directive:`%Platforms`)
+are used by the :directive:`%If` directive to control whether or not parts of a
+specification are processed or ignored.
+
+Versions are mutually exclusive - only one version can be enabled at a time.
+By default all versions are disabled. The SIP ``-t`` command line option is
+used to enable a version.
+
+For example::
+
+ %Timeline {V1_0 V1_1 V2_0 V3_0}
+
+ %If (V1_0 - V2_0)
+ void foo();
+ %End
+
+ %If (V2_0 -)
+ void foo(int = 0);
+ %End
+
+:directive:`%Timeline` can be used any number of times in a module to allow
+multiple libraries to be wrapped in the same module.
+
+
+.. directive:: %TypeCode
+
+.. parsed-literal::
+
+ %TypeCode
+ *code*
+ %End
+
+This directive is used as part of the specification of a C structure or a C++
+class to specify handwritten code, typically the implementations of utility
+functions, that can be called by other handwritten code in the structure or
+class.
+
+For example::
+
+ class Klass
+ {
+ %TypeCode
+ // Print an instance on stderr for debugging purposes.
+ static void dump_klass(const Klass *k)
+ {
+ fprintf(stderr,"Klass %s at %p\n", k->name(), k);
+ }
+ %End
+
+ // The rest of the class specification.
+
+ };
+
+Because the scope of the code is normally within the generated file that
+implements the type, any utility functions would normally be declared
+``static``. However a naming convention should still be adopted to prevent
+clashes of function names within a module in case the SIP ``-j`` command line
+option is used.
+
+
+.. directive:: %TypeHeaderCode
+
+.. parsed-literal::
+
+ %TypeHeaderCode
+ *code*
+ %End
+
+This directive is used to specify handwritten code that defines the interface
+to a C or C++ type being wrapped, either a structure, a class, or a template.
+It is used within a class definition or a :directive:`%MappedType` directive.
+
+Normally *code* will be a pre-processor ``#include`` statement.
+
+For example::
+
+ // Wrap the Klass class.
+ class Klass
+ {
+ %TypeHeaderCode
+ #include <klass.h>
+ %End
+
+ // The rest of the class specification.
+ };
+
+
+.. directive:: %UnitCode
+
+.. parsed-literal::
+
+ %UnitCode
+ *code*
+ %End
+
+This directive is used to specify handwritten code that it included at the very
+start of a generated compilation unit (ie. C or C++ source file). It is
+typically used to ``#include`` a C++ precompiled header file.
+
+
+.. directive:: %VirtualCatcherCode
+
+.. parsed-literal::
+
+ %VirtualCatcherCode
+ *code*
+ %End
+
+For most classes there are corresponding :ref:`generated derived classes
+<ref-derived-classes>` that contain reimplementations of the class's virtual
+methods. These methods (which SIP calls catchers) determine if there is a
+corresponding Python reimplementation and call it if so. If there is no Python
+reimplementation then the method in the original class is called instead.
+
+This directive is used to specify handwritten code that replaces the normally
+generated call to the Python reimplementation and the handling of any returned
+results. It is usually used to handle argument types and results that SIP
+cannot deal with automatically.
+
+This directive can also be used in the context of a class destructor to
+specify handwritten code that is embedded in-line in the internal derived
+class's destructor.
+
+In the context of a method the Python Global Interpreter Lock (GIL) is
+automatically acquired before the specified code is executed and automatically
+released afterwards.
+
+In the context of a destructor the specified code must handle the GIL. The
+GIL must be acquired before any calls to the Python API and released after the
+last call as shown in this example fragment::
+
+ SIP_BLOCK_THREADS
+ Py_DECREF(obj);
+ SIP_UNBLOCK_THREADS
+
+The following variables are made available to the handwritten code in the
+context of a method:
+
+*type* a0
+ There is a variable for each argument of the C++ signature named ``a0``,
+ ``a1``, etc. The *type* of the variable is the same as the type defined in
+ the specification.
+
+int a0Key
+ There is a variable for each argument of the C++ signature that has a type
+ where it is important to ensure that the corresponding Python object is not
+ garbage collected too soon. This only applies to output arguments that
+ return ``'\0'`` terminated strings. The variable would normally be passed
+ to :cfunc:`sipParseResult()` using either the ``A`` or ``B`` format
+ characters.
+
+int sipIsErr
+ The handwritten code should set this to a non-zero value, and raise an
+ appropriate Python exception, if an error is detected.
+
+PyObject \*sipMethod
+ This object is the Python reimplementation of the virtual C++ method. It
+ is normally passed to :cfunc:`sipCallMethod()`.
+
+*type* sipRes
+ The handwritten code should set this to the result to be returned. The
+ *type* of the variable is the same as the type defined in the C++ signature
+ in the specification.
+
+int sipResKey
+ This variable is only made available if the result has a type where it is
+ important to ensure that the corresponding Python object is not garbage
+ collected too soon. This only applies to ``'\0'`` terminated strings. The
+ variable would normally be passed to :cfunc:`sipParseResult()` using either
+ the ``A`` or ``B`` format characters.
+
+sipSimpleWrapper \*sipPySelf
+ This variable is only made available if either the ``a0Key`` or
+ ``sipResKey`` are made available. It defines the context within which keys
+ are unique. The variable would normally be passed to
+ :cfunc:`sipParseResult()` using the ``S`` format character.
+
+No variables are made available in the context of a destructor.
+
+For example::
+
+ class Klass
+ {
+ public:
+ virtual int foo(SIP_PYTUPLE) [int (int *)];
+ %MethodCode
+ // The C++ API takes a 2 element array of integers but passing a
+ // two element tuple is more Pythonic.
+
+ int iarr[2];
+
+ if (PyArg_ParseTuple(a0, "ii", &iarr[0], &iarr[1]))
+ {
+ Py_BEGIN_ALLOW_THREADS
+ sipRes = sipCpp->Klass::foo(iarr);
+ Py_END_ALLOW_THREADS
+ }
+ else
+ {
+ // PyArg_ParseTuple() will have raised the exception.
+ sipIsErr = 1;
+ }
+ %End
+ %VirtualCatcherCode
+ // Convert the 2 element array of integers to the two element
+ // tuple.
+
+ PyObject *result;
+
+ result = sipCallMethod(&sipIsErr, sipMethod, "ii", a0[0], a0[1]);
+
+ if (result != NULL)
+ {
+ // Convert the result to the C++ type.
+ sipParseResult(&sipIsErr, sipMethod, result, "i", &sipRes);
+
+ Py_DECREF(result);
+ }
+ %End
+ };
diff --git a/doc/html/_sources/distutils.txt b/doc/html/_sources/distutils.txt
new file mode 100644
index 0000000..21a6b36
--- /dev/null
+++ b/doc/html/_sources/distutils.txt
@@ -0,0 +1,41 @@
+.. _ref-distutils:
+
+Building Your Extension with distutils
+======================================
+
+To build the example in :ref:`ref-simple-c++-example` using distutils, it is
+sufficient to create a standard ``setup.py``, listing ``word.sip`` among the
+files to build, and hook-up SIP into distutils::
+
+ from distutils.core import setup, Extension
+ import sipdistutils
+
+ setup(
+ name = 'word',
+ versione = '1.0',
+ ext_modules=[
+ Extension("word", ["word.sip", "word.cpp"]),
+ ],
+
+ cmdclass = {'build_ext': sipdistutils.build_ext}
+ )
+
+As we can see, the above is a normal distutils setup script, with just a
+special line which is needed so that SIP can see and process ``word.sip``.
+Then, running ``setup.py build`` will build our extension module.
+
+If you want to use any of sip's command-line options described in
+:ref:`ref-command-line`, there is a new option available for the
+``build_ext`` command in distutils: ``--sip-opts``. So you can either invoke
+distutils as follows::
+
+ $ python setup.py build_ext --sip-opts="-e -g" build
+
+or you can leverage distutils' config file support by creating a ``setup.cfg``
+file in the supported system or local paths (eg: in the same directory of
+``setup.py``) with these contents::
+
+ [build_ext]
+ sip-opts = -e -g
+
+and then run ``setup.py build`` as usual.
diff --git a/doc/html/_sources/embedding.txt b/doc/html/_sources/embedding.txt
new file mode 100644
index 0000000..114e3e8
--- /dev/null
+++ b/doc/html/_sources/embedding.txt
@@ -0,0 +1,62 @@
+Using the C API when Embedding
+==============================
+
+The :ref:`C API <ref-c-api>` is intended to be called from handwritten code in
+SIP generated modules. However it is also often necessary to call it from C or
+C++ applications that embed the Python interpreter and need to pass C or C++
+instances between the application and the interpreter.
+
+The API is exported by the SIP module as a ``sipAPIDef`` data structure
+containing a set of function pointers. The data structure is defined in the
+SIP header file ``sip.h``. The data structure is wrapped as a Python
+``PyCObject`` object and is referenced by the name ``_C_API`` in the SIP
+module dictionary.
+
+Each member of the data structure is a pointer to one of the functions of the
+SIP API. The name of the member can be derived from the function name by
+replacing the ``sip`` prefix with ``api`` and converting each word in the
+name to lower case and preceding it with an underscore. For example:
+
+ ``sipExportSymbol`` becomes ``api_export_symbol``
+
+ ``sipWrapperCheck`` becomes ``api_wrapper_check``
+
+Note that the type objects that SIP generates for a wrapped module (see
+:ref:`ref-type-structures`, :ref:`ref-enum-type-objects` and
+:ref:`ref-exception-objects`) cannot be refered to directly and must be
+obtained using the :cfunc:`sipFindType()` function. Of course, the
+corresponding modules must already have been imported into the interpreter.
+
+The following code fragment shows how to get a pointer to the ``sipAPIDef``
+data structure::
+
+ #include <sip.h>
+
+ const sipAPIDef *get_sip_api()
+ {
+ PyObject *sip_module;
+ PyObject *sip_module_dict;
+ PyObject *c_api;
+
+ /* Import the SIP module. */
+ sip_module = PyImport_ImportModule("sip");
+
+ if (sip_module == NULL)
+ return NULL;
+
+ /* Get the module's dictionary. */
+ sip_module_dict = PyModule_GetDict(sip_module);
+
+ /* Get the "_C_API" attribute. */
+ c_api = PyDict_GetItemString(sip_module_dict, "_C_API");
+
+ if (c_api == NULL)
+ return NULL;
+
+ /* Sanity check that it is the right type. */
+ if (!PyCObject_Check(c_api))
+ return NULL;
+
+ /* Get the actual pointer from the object. */
+ return (const sipAPIDef *)PyCObject_AsVoidPtr(c_api);
+ }
diff --git a/doc/html/_sources/incompatibilities.txt b/doc/html/_sources/incompatibilities.txt
new file mode 100644
index 0000000..a006e4f
--- /dev/null
+++ b/doc/html/_sources/incompatibilities.txt
@@ -0,0 +1,198 @@
+Potential Incompatibilities with Earlier Versions
+=================================================
+
+This section describes incompatibilities introduced by particular versions of
+SIP. Normally these are the removal of previously deprecated features.
+
+
+SIP v4.10.1
+-----------
+
+Newly Deprecated Features
+*************************
+
+The following parts of the :ref:`C API <ref-c-api>` are now deprecated (but
+still supported).
+
+- The ``D`` format character of :cfunc:`sipParseResult()`.
+
+
+SIP v4.8
+--------
+
+__truediv__
+***********
+
+Prior to this version the :meth:`__div__` special method implicitly defined the
+:meth:`__truediv__` special method. From this version the :meth:`__truediv__`
+special method must be explicitly defined.
+
+
+sipWrapper user Member
+**********************
+
+Prior to this version the :ctype:`sipWrapper` structure had a member called
+:ctype:`user` which is available for handwritten code to use. From this
+version :ctype:`user` is a member of the :ctype:`sipSimpleWrapper` structure.
+
+:ctype:`sipWrapper` pointers can be safely cast to :ctype:`sipSimpleWrapper`
+pointers, so if your code does something like::
+
+ ((sipWrapper *)obj)->user = an_object_reference;
+
+then you just need to change it to::
+
+ ((sipSimpleWrapper *)obj)->user = an_object_reference;
+
+
+Removal of Previously Deprecated Features
+*****************************************
+
+The following parts of the :ref:`C API <ref-c-api>` have been removed.
+
+- The ``a``, ``A``, ``M``, ``N``, ``O``, ``P`` and ``T`` format characters
+ from :cfunc:`sipBuildResult()` and :cfunc:`sipCallMethod()`.
+
+- The ``a``, ``A``, ``L`` and ``M`` format characters from
+ :cfunc:`sipParseResult()`.
+
+- :cfunc:`sipConvertToCpp()`
+
+- :cfunc:`sipIsSubClassInstance()`
+
+- :cfunc:`sipTransfer()`
+
+- The :func:`transfer` function of the :mod:`sip` module.
+
+- The old-style generated type convertors.
+
+In addition the :option:`-a` command line option to :file:`configure.py` has
+been removed.
+
+
+Removal of PyQt-specific Features
+*********************************
+
+The following PyQt-specific support functions have been removed.
+
+- :cfunc:`sipConnectRx()`
+
+- :cfunc:`sipDisconnectRx()`
+
+- :cfunc:`sipEmitSlot()`
+
+- :cfunc:`sipGetSender()`
+
+
+Newly Deprecated Features
+*************************
+
+The following parts of the :ref:`C API <ref-c-api>` are now deprecated (but
+still supported).
+
+- The :ref:`ref-type-objects`.
+
+- The :ref:`ref-enum-type-objects`.
+
+- :cfunc:`sipConvertFromInstance()`
+
+- :cfunc:`sipConvertFromMappedType()`
+
+- :cfunc:`sipConvertFromNamedEnum()`
+
+- :cfunc:`sipConvertFromNewInstance()`
+
+- :cfunc:`sipCanConvertToInstance()`
+
+- :cfunc:`sipCanConvertToMappedType()`
+
+- :cfunc:`sipConvertToInstance()`
+
+- :cfunc:`sipConvertToMappedType()`
+
+- :cfunc:`sipForceConvertToInstance()`
+
+- :cfunc:`sipForceConvertToMappedType()`
+
+- :cfunc:`sipClassName()`
+
+- :cfunc:`sipFindClass()`
+
+- :cfunc:`sipFindNamedEnum()`
+
+- :cfunc:`sipFindMappedType()`
+
+- :cfunc:`sipGetWrapper()`
+
+- :cfunc:`sipReleaseInstance()`
+
+- :cfunc:`sipReleaseMappedType()`
+
+- :cfunc:`sipWrapper_Check()`
+
+- The ``B``, ``C`` and ``E`` format characters of :cfunc:`sipBuildResult()` and
+ :cfunc:`sipCallMethod()`.
+
+- The ``s``, ``C`` and ``E`` format characters of :cfunc:`sipParseResult()`.
+
+
+SIP v4.7.8
+----------
+
+Automatic int to Enum Conversions
+*********************************
+
+This version allows a Python ``int`` object to be passed whenever an enum is
+expected. This can mean that two signatures that were different with prior
+versions are now the same as far as Python is concerned.
+
+The :aanno:`Constrained` argument annotation can now be applied to an enum
+argument to revert to the earlier behaviour.
+
+
+SIP v4.7.3
+----------
+
+Complementary Comparison Operators
+**********************************
+
+Prior to this version SIP did not automatically generate missing complementary
+comparison operators. Typically this was worked around by adding them
+explicitly to the .sip files, even though they weren't implemented in C++ and
+relied on the C++ compiler calling the complementary operator that was
+implemented.
+
+A necessary change to the code generator meant that this not longer worked and
+so SIP was changed to automatically generate any missing complementary
+operators. If you have added such operators explicitly then you should remove
+them or make them dependent on the particular version of SIP.
+
+
+SIP v4.4
+--------
+
+%ConvertFromTypeCode and %ConvertToTypeCode
+*******************************************
+
+Handwritten :directive:`%ConvertFromTypeCode` and
+:directive:`%ConvertToTypeCode` now have the responsibility for implementing
+the :aanno:`Transfer` and :aanno:`TransferBack` annotations.
+
+
+SIP_BUILD
+*********
+
+The :cmacro:`SIP_BUILD` C preprocessor symbol has been removed.
+
+
+Newly Deprecated Features
+*************************
+
+The following parts of the :ref:`C API <ref-c-api>` are now deprecated (but
+still supported).
+
+- The old-style generated type convertors.
+
+- :cfunc:`sipConvertToCpp()`
+
+- :cfunc:`sipIsSubClassInstance()`
diff --git a/doc/html/_sources/index.txt b/doc/html/_sources/index.txt
new file mode 100644
index 0000000..ac9289c
--- /dev/null
+++ b/doc/html/_sources/index.txt
@@ -0,0 +1,20 @@
+SIP Reference Guide
+===================
+
+.. toctree::
+ :maxdepth: 2
+
+ introduction
+ incompatibilities
+ installation
+ using
+ command_line
+ specification_files
+ directives
+ annotations
+ c_api
+ embedding
+ python_api
+ build_system
+ distutils
+ builtin
diff --git a/doc/html/_sources/installation.txt b/doc/html/_sources/installation.txt
new file mode 100644
index 0000000..3f9f823
--- /dev/null
+++ b/doc/html/_sources/installation.txt
@@ -0,0 +1,169 @@
+Installation
+============
+
+Downloading
+-----------
+
+You can get the latest release of the SIP source code from
+http://www.riverbankcomputing.com/software/sip/download.
+
+SIP is also included with all of the major Linux distributions. However, it
+may be a version or two out of date.
+
+
+Configuring
+-----------
+
+After unpacking the source package (either a ``.tar.gz`` or a ``.zip`` file
+depending on your platform) you should then check for any ``README`` files
+that relate to your platform.
+
+Next you need to configure SIP by executing the ``configure.py`` script. For
+example::
+
+ python configure.py
+
+This assumes that the Python interpreter is on your path. Something like the
+following may be appropriate on Windows::
+
+ c:\python26\python configure.py
+
+If you have multiple versions of Python installed then make sure you use the
+interpreter for which you wish SIP to generate bindings for.
+
+The full set of command line options is:
+
+.. program:: configure.py
+
+.. cmdoption:: --version
+
+ Display the SIP version number.
+
+.. cmdoption:: -h, --help
+
+ Display a help message.
+
+.. cmdoption:: --arch <ARCH>
+
+ Binaries for the MacOS/X architecture ``<ARCH>`` will be built. This
+ option should be given once for each architecture to be built. Specifying
+ more than one architecture will cause a universal binary to be created.
+
+.. cmdoption:: -b <DIR>, --bindir <DIR>
+
+ The SIP code generator will be installed in the directory ``<DIR>``.
+
+.. cmdoption:: -d <DIR>, --destdir <DIR>
+
+ The SIP module will be installed in the directory ``<DIR>``.
+
+.. cmdoption:: -e <DIR>, --incdir <DIR>
+
+ The SIP header file will be installed in the directory ``<DIR>``.
+
+.. cmdoption:: -k, --static
+
+ The SIP module will be built as a static library. This is useful when
+ building the SIP module as a Python builtin (see :ref:`ref-builtin`).
+
+.. cmdoption:: -n, --universal
+
+ The SIP code generator and module will be built as universal binaries
+ under MacOS/X. If the :option:`--arch <configure.py --arch>` option has
+ not been specified then the universal binary will include the ``i386`` and
+ ``ppc`` architectures.
+
+.. cmdoption:: -p <PLATFORM>, --platform <PLATFORM>
+
+ Explicitly specify the platform/compiler to be used by the build system,
+ otherwise a platform specific default will be used. The
+ :option:`--show-platforms <configure.py --show-platforms>` option will
+ display all the supported platform/compilers.
+
+.. cmdoption:: -s <SDK>, --sdk <SDK>
+
+ If the :option:`--universal <configure.py -n>` option was given then this
+ specifies the name of the SDK directory. If a path is not given then it is
+ assumed to be a sub-directory of ``/Developer/SDKs``.
+
+.. cmdoption:: -u, --debug
+
+ The SIP module will be built with debugging symbols.
+
+.. cmdoption:: -v <DIR>, --sipdir <DIR>
+
+ By default ``.sip`` files will be installed in the directory ``<DIR>``.
+
+.. cmdoption:: --show-platforms
+
+ The list of all supported platform/compilers will be displayed.
+
+.. cmdoption:: --show-build-macros
+
+ The list of all available build macros will be displayed.
+
+The ``configure.py`` script takes many other options that allows the build
+system to be finely tuned. These are of the form ``name=value`` or
+``name+=value``. The :option:`--show-build-macros <configure.py
+--show-build-macros>` option will display each supported ``name``, although not
+all are applicable to all platforms.
+
+The ``name=value`` form means that ``value`` will replace the existing value of
+``name``.
+
+The ``name+=value`` form means that ``value`` will be appended to the existing
+value of ``name``.
+
+For example, the following will disable support for C++ exceptions (and so
+reduce the size of module binaries) when used with GCC::
+
+ python configure.py CXXFLAGS+=-fno-exceptions
+
+A pure Python module called ``sipconfig.py`` is generated by ``configure.py``.
+This defines each ``name`` and its corresponding ``value``. Looking at it will
+give you a good idea of how the build system uses the different options. It is
+covered in detail in :ref:`ref-build-system`.
+
+
+Configuring for MinGW
+*********************
+
+SIP, and the modules it generates, can be built with MinGW, the Windows port of
+GCC. You must use the :option:`--platform <configure.py -p>` command line
+option to specify the correct platform. For example::
+
+ c:\python26\python configure.py --platform win32-g++
+
+
+Configuring for the Borland C++ Compiler
+****************************************
+
+SIP, and the modules it generates, can be built with the free Borland C++
+compiler. You must use the :option:`--platform <configure.py -p>` command line
+option to specify the correct platform. For example::
+
+ c:\python26\python configure.py --platform win32-borland
+
+You must also make sure you have a Borland-compatible version of the Python
+library. If you are using the standard Python distribution (built using the
+Microsoft compiler) then you must convert the format of the Python library.
+For example::
+
+ coff2omf python26.lib python26_bcpp.lib
+
+
+Building
+--------
+
+The next step is to build SIP by running your platform's ``make`` command. For
+example::
+
+ make
+
+The final step is to install SIP by running the following command::
+
+ make install
+
+(Depending on your system you may require root or administrator privileges.)
+
+This will install the various SIP components.
diff --git a/doc/html/_sources/introduction.txt b/doc/html/_sources/introduction.txt
new file mode 100644
index 0000000..8515243
--- /dev/null
+++ b/doc/html/_sources/introduction.txt
@@ -0,0 +1,169 @@
+Introduction
+============
+
+This is the reference guide for SIP 4.10.5. SIP is a tool for
+automatically generating `Python <http://www.python.org>`__ bindings for C and
+C++ libraries. SIP was originally developed in 1998 for
+`PyQt <http://www.riverbankcomputing.com/software/pyqt>`__ - the Python
+bindings for the Qt GUI toolkit - but is suitable for generating bindings for
+any C or C++ library.
+
+This version of SIP generates bindings for Python v2.3 or later, including
+Python v3.
+
+There are many other similar tools available. One of the original such tools
+is `SWIG <http://www.swig.org>`__ and, in fact, SIP is so called because it
+started out as a small SWIG. Unlike SWIG, SIP is specifically designed for
+bringing together Python and C/C++ and goes to great lengths to make the
+integration as tight as possible.
+
+The homepage for SIP is http://www.riverbankcomputing.com/software/sip. Here
+you will always find the latest stable version and the latest version of this
+documentation.
+
+SIP can also be downloaded from the
+`Mercurial <http://mercurial.selenic.com/>`__ repository at
+http://www.riverbankcomputing.com/hg/sip.
+
+
+License
+-------
+
+SIP is licensed under similar terms as Python itself. SIP is also licensed
+under the GPL (both v2 and v3). It is your choice as to which license you
+use. If you choose the GPL then any bindings you create must be distributed
+under the terms of the GPL.
+
+
+Features
+--------
+
+SIP, and the bindings it produces, have the following features:
+
+- bindings are fast to load and minimise memory consumption especially when
+ only a small sub-set of a large library is being used
+
+- automatic conversion between standard Python and C/C++ data types
+
+- overloading of functions and methods with different argument signatures
+
+- support for Python's keyword argument syntax
+
+- support for both explicitly specified and automatically generated docstrings
+
+- access to a C++ class's protected methods
+
+- the ability to define a Python class that is a sub-class of a C++ class,
+ including abstract C++ classes
+
+- Python sub-classes can implement the :meth:`__dtor__` method which will be
+ called from the C++ class's virtual destructor
+
+- support for ordinary C++ functions, class methods, static class methods,
+ virtual class methods and abstract class methods
+
+- the ability to re-implement C++ virtual and abstract methods in Python
+
+- support for global and class variables
+
+- support for global and class operators
+
+- support for C++ namespaces
+
+- support for C++ templates
+
+- support for C++ exceptions and wrapping them as Python exceptions
+
+- the automatic generation of complementary rich comparison slots
+
+- support for deprecation warnings
+
+- the ability to define mappings between C++ classes and similar Python data
+ types that are automatically invoked
+
+- the ability to automatically exploit any available run time type information
+ to ensure that the class of a Python instance object matches the class of the
+ corresponding C++ instance
+
+- the ability to change the type and meta-type of the Python object used to
+ wrap a C/C++ data type
+
+- full support of the Python global interpreter lock, including the ability to
+ specify that a C++ function of method may block, therefore allowing the lock
+ to be released and other Python threads to run
+
+- support for consolidated modules where the generated wrapper code for a
+ number of related modules may be included in a single, possibly private,
+ module
+
+- support for the concept of ownership of a C++ instance (i.e. what part of the
+ code is responsible for calling the instance's destructor) and how the
+ ownership may change during the execution of an application
+
+- the ability to generate bindings for a C++ class library that itself is built
+ on another C++ class library which also has had bindings generated so that
+ the different bindings integrate and share code properly
+
+- a sophisticated versioning system that allows the full lifetime of a C++
+ class library, including any platform specific or optional features, to be
+ described in a single set of specification files
+
+- the ability to include documentation in the specification files which can be
+ extracted and subsequently processed by external tools
+
+- the ability to include copyright notices and licensing information in the
+ specification files that is automatically included in all generated source
+ code
+
+- a build system, written in Python, that you can extend to configure, compile
+ and install your own bindings without worrying about platform specific issues
+
+- support for building your extensions using distutils
+
+- SIP, and the bindings it produces, runs under UNIX, Linux, Windows and
+ MacOS/X
+
+
+SIP Components
+--------------
+
+SIP comprises a number of different components.
+
+- The SIP code generator (:program:`sip`). This processes :file:`.sip`
+ specification files and generates C or C++ bindings. It is covered in detail
+ in :ref:`ref-using`.
+
+- The SIP header file (:file:`sip.h`). This contains definitions and data
+ structures needed by the generated C and C++ code.
+
+- The SIP module (:file:`sip.so` or :file:`sip.pyd`). This is a Python
+ extension module that is imported automatically by SIP generated bindings and
+ provides them with some common utility functions. See also
+ :ref:`ref-python-api`.
+
+- The SIP build system (:file:`sipconfig.py`). This is a pure Python module
+ that is created when SIP is configured and encapsulates all the necessary
+ information about your system including relevant directory names, compiler
+ and linker flags, and version numbers. It also includes several Python
+ classes and functions which help you write configuration scripts for your own
+ bindings. It is covered in detail in :ref:`ref-build-system`.
+
+- The SIP distutils extension (:file:`sipdistutils.py`). This is a distutils
+ extension that can be used to build your extension modules using distutils
+ and is an alternative to writing configuration scripts with the SIP build
+ system. This can be as simple as adding your .sip files to the list of files
+ needed to build the extension module. It is covered in detail in
+ :ref:`ref-distutils`.
+
+
+Qt Support
+----------
+
+SIP has specific support for the creation of bindings based on Nokia's Qt
+toolkit.
+
+The SIP code generator understands the signal/slot type safe callback mechanism
+that Qt uses to connect objects together. This allows applications to define
+new Python signals, and allows any Python callable object to be used as a slot.
+
+SIP itself does not require Qt to be installed.
diff --git a/doc/html/_sources/python_api.txt b/doc/html/_sources/python_api.txt
new file mode 100644
index 0000000..fa90411
--- /dev/null
+++ b/doc/html/_sources/python_api.txt
@@ -0,0 +1,282 @@
+.. _ref-python-api:
+
+Python API for Applications
+===========================
+
+.. module:: sip
+
+The main purpose of the :mod:`sip` module is to provide functionality common to
+all SIP generated bindings. It is loaded automatically and most of the time
+you will completely ignore it. However, it does expose some functionality that
+can be used by applications.
+
+
+.. function:: cast(obj, type) -> object
+
+ This does the Python equivalent of casting a C++ instance to one of its
+ sub or super-class types.
+
+ :param obj:
+ the Python object.
+ :param type:
+ the type.
+ :return:
+ a new Python object is that wraps the same C++ instance as *obj*, but
+ has the type *type*.
+
+
+.. function:: delete(obj)
+
+ For C++ instances this calls the C++ destructor. For C structures it
+ returns the structure's memory to the heap.
+
+ :param obj:
+ the Python object.
+
+
+.. function:: dump(obj)
+
+ This displays various bits of useful information about the internal state
+ of the Python object that wraps a C++ instance or C structure.
+
+ :param obj:
+ the Python object.
+
+
+.. function:: getapi(name) -> version
+
+ .. versionadded:: 4.9
+
+ This returns the version number that has been set for an API. The version
+ number is either set explicitly by a call to :func:`sip.setapi` or
+ implicitly by importing the module that defines it.
+
+ :param name:
+ the name of the API.
+ :return:
+ The version number that has been set for the API. An exception will
+ be raised if the API is unknown.
+
+
+.. function:: isdeleted(obj) -> bool
+
+ This checks if the C++ instance or C structure has been deleted and
+ returned to the heap.
+
+ :param obj:
+ the Python object.
+ :return:
+ ``True`` if the C/C++ instance has been deleted.
+
+
+.. function:: ispyowned(obj) -> bool
+
+ This checks if the C++ instance or C structure is owned by Python.
+
+ :param obj:
+ the Python object.
+ :return:
+ ``True`` if the C/C++ instance is owned by Python.
+
+
+.. function:: setapi(name, version)
+
+ .. versionadded:: 4.9
+
+ This sets the version number of an API. An exception is raised if a
+ different version number has already been set, either explicitly by a
+ previous call, or implicitly by importing the module that defines it.
+
+ :param name:
+ the name of the API.
+ :param version:
+ The version number to set for the API. Version numbers must be
+ greater than or equal to 1.
+
+
+.. function:: setdeleted(obj)
+
+ This marks the C++ instance or C structure as having been deleted and
+ returned to the heap so that future references to it raise an exception
+ rather than cause a program crash. Normally SIP handles such things
+ automatically, but there may be circumstances where this isn't possible.
+
+ :param obj:
+ the Python object.
+
+
+.. function:: settracemask(mask)
+
+ If the bindings have been created with SIP's :option:`-r <sip -r>` command
+ line option then the generated code will include debugging statements that
+ trace the execution of the code. (It is particularly useful when trying to
+ understand the operation of a C++ library's virtual function calls.)
+
+ :param mask:
+ the mask that determines which debugging statements are enabled.
+
+ Debugging statements are generated at the following points:
+
+ - in a C++ virtual function (*mask* is ``0x0001``)
+ - in a C++ constructor (*mask* is ``0x0002``)
+ - in a C++ destructor (*mask* is ``0x0004``)
+ - in a Python type's __init__ method (*mask* is ``0x0008``)
+ - in a Python type's __del__ method (*mask* is ``0x0010``)
+ - in a Python type's ordinary method (*mask* is ``0x0020``).
+
+ By default the trace mask is zero and all debugging statements are
+ disabled.
+
+
+.. data:: SIP_VERSION
+
+ This is a Python integer object that represents the SIP version number as
+ a 3 part hexadecimal number (e.g. v4.0.0 is represented as ``0x040000``).
+ It was first implemented in SIP v4.2.
+
+
+.. data:: SIP_VERSION_STR
+
+ This is a Python string object that defines the SIP version number as
+ represented as a string. For development snapshots it will start with
+ ``snapshot-``. It was first implemented in SIP v4.3.
+
+
+.. function:: transferback(obj)
+
+ This function is a wrapper around :cfunc:`sipTransferBack()`.
+
+
+.. function:: transferto(obj, owner)
+
+ This function is a wrapper around :cfunc:`sipTransferTo()`.
+
+
+.. function:: unwrapinstance(obj) -> integer
+
+ This returns the address, as an integer, of a wrapped C/C++ structure or
+ class instance.
+
+ :param obj:
+ the Python object.
+ :return:
+ an integer that is the address of the C/C++ instance.
+
+
+.. class:: voidptr
+
+ This is the type object for the type SIP uses to represent a C/C++
+ ``void *``. It may have a size associated with the address in which case
+ the Python buffer protocol is supported. This means that the memory can
+ be treated as a mutable array of bytes when wrapped with the ``buffer()``
+ builtin. The type has the following methods.
+
+ .. method:: __init__(address[, size=-1[, writeable=True]])
+
+ :param address:
+ the address, either another :class:`sip.voidptr`, ``None``, a
+ Python Capsule, a Python CObject, or an integer.
+ :param size:
+ the optional associated size of the block of memory and is negative
+ if the size is not known.
+ :param writeable:
+ set if the memory is writeable. If it is not specified, and
+ *address* is a :class:`sip.voidptr` instance then its value will be
+ used.
+
+ .. method:: __int__() -> integer
+
+ This returns the address as an integer.
+
+ :return:
+ the integer address.
+
+ .. method:: __hex__() -> string
+
+ This returns the address as a hexadecimal string.
+
+ :return:
+ the hexadecimal string address.
+
+ .. method:: ascapsule() -> capsule
+
+ .. versionadded:: 4.10
+
+ This returns the address as an unnamed Python Capsule. This requires
+ Python v3.1 or later or Python v2.7 or later.
+
+ :return:
+ the Capsule.
+
+ .. method:: ascobject() -> cObject
+
+ This returns the address as a Python CObject. This is deprecated with
+ Python v3.1 or later.
+
+ :return:
+ the CObject.
+
+ .. method:: asstring([size=-1]) -> string/bytes
+
+ This returns a copy of the block of memory as a Python v2 string object
+ or a Python v3 bytes object.
+
+ :param size:
+ the number of bytes to copy. If it is negative then the size
+ associated with the address is used. If there is no associated
+ size then an exception is raised.
+ :return:
+ the string or bytes object.
+
+ .. method:: getsize() -> integer
+
+ This returns the size associated with the address.
+
+ :return:
+ the associated size which will be negative if there is none.
+
+ .. method:: setsize(size)
+
+ This sets the size associated with the address.
+
+ :param size:
+ the size to associate. If it is negative then no size is
+ associated.
+
+ .. method:: getwriteable() -> bool
+
+ This returns the writeable state of the memory.
+
+ :return:
+ ``True`` if the memory is writeable.
+
+ .. method:: setwriteable(writeable)
+
+ This sets the writeable state of the memory.
+
+ :param writeable:
+ the writeable state to set.
+
+
+.. function:: wrapinstance(addr, type) -> object
+
+ This wraps a C structure or C++ class instance in a Python object. If the
+ instance has already been wrapped then a new reference to the existing
+ object is returned.
+
+ :param addr:
+ the address of the instance as a number.
+ :param type:
+ the Python type of the instance.
+ :return:
+ the Python object that wraps the instance.
+
+
+.. class:: wrapper
+
+ This is the type object of the base type of all instances wrapped by SIP.
+
+
+.. class:: wrappertype
+
+ This is the type object of the metatype of the :class:`sip.wrapper` type.
diff --git a/doc/html/_sources/specification_files.txt b/doc/html/_sources/specification_files.txt
new file mode 100644
index 0000000..6ba3aba
--- /dev/null
+++ b/doc/html/_sources/specification_files.txt
@@ -0,0 +1,499 @@
+SIP Specification Files
+=======================
+
+A SIP specification consists of some C/C++ type and function declarations and
+some directives. The declarations may contain annotations which provide SIP
+with additional information that cannot be expressed in C/C++. SIP does not
+include a full C/C++ parser.
+
+It is important to understand that a SIP specification describes the Python
+API, i.e. the API available to the Python programmer when they ``import`` the
+generated module. It does not have to accurately represent the underlying
+C/C++ library. There is nothing wrong with omitting functions that make
+little sense in a Python context, or adding functions implemented with
+handwritten code that have no C/C++ equivalent. It is even possible (and
+sometimes necessary) to specify a different super-class hierarchy for a C++
+class. All that matters is that the generated code compiles properly.
+
+In most cases the Python API matches the C/C++ API. In some cases handwritten
+code (see :directive:`%MethodCode`) is used to map from one to the other
+without SIP having to know the details itself. However, there are a few cases
+where SIP generates a thin wrapper around a C++ method or constructor (see
+:ref:`ref-derived-classes`) and needs to know the exact C++ signature. To deal
+with these cases SIP allows two signatures to be specified. For example::
+
+ class Klass
+ {
+ public:
+ // The Python signature is a tuple, but the underlying C++ signature
+ // is a 2 element array.
+ Klass(SIP_PYTUPLE) [(int *)];
+ %MethodCode
+ int iarr[2];
+
+ if (PyArg_ParseTuple(a0, "ii", &iarr[0], &iarr[1]))
+ {
+ // Note that we use the SIP generated derived class
+ // constructor.
+ Py_BEGIN_ALLOW_THREADS
+ sipCpp = new sipKlass(iarr);
+ Py_END_ALLOW_THREADS
+ }
+ %End
+ };
+
+
+Syntax Definition
+-----------------
+
+The following is a semi-formal description of the syntax of a specification
+file.
+
+.. parsed-literal::
+
+ *specification* ::= {*module-statement*}
+
+ *module-statement* ::= [*module-directive* | *statement*]
+
+ *module-directive* ::= [
+ :directive:`%API` |
+ :directive:`%CModule` |
+ :directive:`%CompositeModule` |
+ :directive:`%ConsolidatedModule` |
+ :directive:`%Copying` |
+ :directive:`%DefaultEncoding` |
+ :directive:`%DefaultMetatype` |
+ :directive:`%DefaultSupertype` |
+ :directive:`%Doc` |
+ :directive:`%ExportedDoc` |
+ :directive:`%ExportedHeaderCode` |
+ :directive:`%Feature` |
+ :directive:`%Import` |
+ :directive:`%Include` |
+ :directive:`%InitialisationCode` |
+ :directive:`%License` |
+ :directive:`%MappedType` |
+ :directive:`%Module` |
+ :directive:`%ModuleCode` |
+ :directive:`%ModuleHeaderCode` |
+ :directive:`%OptionalInclude` |
+ :directive:`%Platforms` |
+ :directive:`%PreInitialisationCode` |
+ :directive:`%PostInitialisationCode` |
+ :directive:`%Timeline` |
+ :directive:`%UnitCode` |
+ *mapped-type-template*]
+
+ *statement* :: [*class-statement* | *function* | *variable*]
+
+ *class-statement* :: [
+ :directive:`%If` |
+ *class* |
+ *class-template* |
+ *enum* |
+ *namespace* |
+ *opaque-class* |
+ *operator* |
+ *struct* |
+ *typedef* |
+ *exception*]
+
+ *class* ::= **class** *name* [**:** *super-classes*] [*class-annotations*]
+ **{** {*class-line*} **};**
+
+ *super-classes* ::= *name* [**,** *super-classes*]
+
+ *class-line* ::= [
+ *class-statement* |
+ :directive:`%BIGetBufferCode` |
+ :directive:`%BIGetReadBufferCode` |
+ :directive:`%BIGetWriteBufferCode` |
+ :directive:`%BIGetSegCountCode` |
+ :directive:`%BIGetCharBufferCode` |
+ :directive:`%BIReleaseBufferCode` |
+ :directive:`%ConvertToSubClassCode` |
+ :directive:`%ConvertToTypeCode` |
+ :directive:`%Docstring` |
+ :directive:`%GCClearCode` |
+ :directive:`%GCTraverseCode` |
+ :directive:`%PickleCode` |
+ :directive:`%TypeCode` |
+ :directive:`%TypeHeaderCode` |
+ *constructor* |
+ *destructor* |
+ *method* |
+ *static-method* |
+ *virtual-method* |
+ *special-method* |
+ *operator* |
+ *virtual-operator* |
+ *class-variable* |
+ **public:** |
+ **public Q_SLOTS:** |
+ **public slots:** |
+ **protected:** |
+ **protected Q_SLOTS:** |
+ **protected slots:** |
+ **private:** |
+ **private Q_SLOTS:** |
+ **private slots:** |
+ **Q_SIGNALS:** |
+ **signals:**]
+
+ *constructor* ::= [**explicit**] *name* **(** [*argument-list*] **)**
+ [*exceptions*] [*function-annotations*]
+ [*c++-constructor-signature*] **;** [:directive:`%Docstring`]
+ [:directive:`%MethodCode`]
+
+ *c++-constructor-signature* ::= **[(** [*argument-list*] **)]**
+
+ *destructor* ::= [**virtual**] **~** *name* **()** [*exceptions*] [**= 0**]
+ [*function-annotations*] **;** [:directive:`%MethodCode`]
+ [:directive:`%VirtualCatcherCode`]
+
+ *method* ::= [**Q_SIGNAL**] [**Q_SLOT**] *type* *name* **(**
+ [*argument-list*] **)** [**const**] [*exceptions*] [**= 0**]
+ [*function-annotations*] [*c++-signature*] **;**
+ [:directive:`%Docstring`] [:directive:`%MethodCode`]
+
+ *c++-signature* ::= **[** *type* **(** [*argument-list*] **)]**
+
+ *static-method* ::= **static** *function*
+
+ *virtual-method* ::= [**Q_SIGNAL**] [**Q_SLOT**] **virtual** *type* *name*
+ **(** [*argument-list*] **)** [**const**] [*exceptions*] [**= 0**]
+ [*function-annotations*] [*c++-signature*] **;**
+ [:directive:`%MethodCode`] [:directive:`%VirtualCatcherCode`]
+
+ *special-method* ::= *type* *special-method-name*
+ **(** [*argument-list*] **)** [*function-annotations*] **;**
+ [:directive:`%MethodCode`]
+
+ *special-method-name* ::= [**__abs__** | **__add__** | **__and__** |
+ **__bool__** | **__call__** | **__cmp__** | **__contains__** |
+ **__delitem__** | **__div__** | **__eq__** | **__float__** |
+ **__floordiv__** | **__ge__** | **__getitem__** | **__gt__** |
+ **__hash__** | **__iadd__** | **__iand__** | **__idiv__** |
+ **__ifloordiv__** | **__ilshift__** | **__imod__** | **__imul__** |
+ **__index__** | **__int__** | **__invert__** | **__ior__** |
+ **__irshift__** | **__isub__** | **__iter__** | **__itruediv__** |
+ **__ixor__** | **__le__** | **__len__** | **__long__** |
+ **__lshift__** | **__lt__** | **__mod__** | **__mul__** |
+ **__ne__** | **__neg__** | **__next__** | **__nonzero__** |
+ **__or__** | **__pos__** | **__repr__** | **__rshift__** |
+ **__setitem__** | **__str__** | **__sub__** | **__truediv__** |
+ **__xor__**]
+
+ *operator* ::= *operator-type*
+ **(** [*argument-list*] **)** [**const**] [*exceptions*]
+ [*function-annotations*] **;** [:directive:`%MethodCode`]
+
+ *virtual-operator* ::= **virtual** *operator-type*
+ **(** [*argument-list*] **)** [**const**] [*exceptions*] [**= 0**]
+ [*function-annotations*] **;** [:directive:`%MethodCode`]
+ [:directive:`%VirtualCatcherCode`]
+
+ *operatator-type* ::= [ *operator-function* | *operator-cast* ]
+
+ *operator-function* ::= *type* **operator** *operator-name*
+
+ *operator-cast* ::= **operator** *type*
+
+ *operator-name* ::= [**+** | **-** | ***** | **/** | **%** | **&** |
+ **|** | **^** | **<<** | **>>** | **+=** | **-=** | ***=** |
+ **/=** | **%=** | **&=** | **|=** | **^=** | **<<=** | **>>=** |
+ **~** | **()** | **[]** | **<** | **<=** | **==** | **!=** |
+ **>** | **>>=** | **=**]
+
+ *class-variable* ::= [**static**] *variable*
+
+ *class-template* :: = **template** **<** *type-list* **>** *class*
+
+ *mapped-type-template* :: = **template** **<** *type-list* **>**
+ :directive:`%MappedType`
+
+ *enum* ::= **enum** [*name*] [*enum-annotations*] **{** {*enum-line*} **};**
+
+ *enum-line* ::= [:directive:`%If` | *name* [*enum-annotations*] **,**
+
+ *function* ::= *type* *name* **(** [*argument-list*] **)** [*exceptions*]
+ [*function-annotations*] **;** [:directive:`%Docstring`]
+ [:directive:`%MethodCode`]
+
+ *namespace* ::= **namespace** *name* **{** {*namespace-line*} **};**
+
+ *namespace-line* ::= [:directive:`%TypeHeaderCode` | *statement*]
+
+ *opaque-class* ::= **class** *scoped-name* **;**
+
+ *struct* ::= **struct** *name* **{** {*class-line*} **};**
+
+ *typedef* ::= **typedef** [*typed-name* | *function-pointer*]
+ *typedef-annotations* **;**
+
+ *variable*::= *typed-name* [*variable-annotations*] **;**
+ [:directive:`%AccessCode`] [:directive:`%GetCode`]
+ [:directive:`%SetCode`]
+
+ *exception* ::= :directive:`%Exception` *exception-name* [*exception-base*]
+ **{** [:directive:`%TypeHeaderCode`] :directive:`%RaiseCode` **};**
+
+ *exception-name* ::= *scoped-name*
+
+ *exception-base* ::= **(** [*exception-name* | *python-exception*] **)**
+
+ *python-exception* ::= [**SIP_Exception** | **SIP_StopIteration** |
+ **SIP_StandardError** | **SIP_ArithmeticError** |
+ **SIP_LookupError** | **SIP_AssertionError** |
+ **SIP_AttributeError** | **SIP_EOFError** |
+ **SIP_FloatingPointError** | **SIP_EnvironmentError** |
+ **SIP_IOError** | **SIP_OSError** | **SIP_ImportError** |
+ **SIP_IndexError** | **SIP_KeyError** | **SIP_KeyboardInterrupt** |
+ **SIP_MemoryError** | **SIP_NameError** | **SIP_OverflowError** |
+ **SIP_RuntimeError** | **SIP_NotImplementedError** |
+ **SIP_SyntaxError** | **SIP_IndentationError** | **SIP_TabError** |
+ **SIP_ReferenceError** | **SIP_SystemError** | **SIP_SystemExit** |
+ **SIP_TypeError** | **SIP_UnboundLocalError** |
+ **SIP_UnicodeError** | **SIP_UnicodeEncodeError** |
+ **SIP_UnicodeDecodeError** | **SIP_UnicodeTranslateError** |
+ **SIP_ValueError** | **SIP_ZeroDivisionError** |
+ **SIP_WindowsError** | **SIP_VMSError**]
+
+ *exceptions* ::= **throw (** [*exception-list*] **)**
+
+ *exception-list* ::= *scoped-name* [**,** *exception-list*]
+
+ *argument-list* ::= *argument* [**,** *argument-list*] [**,** **...**]
+
+ *argument* ::= [
+ *type* [*name*] [*argument-annotations*] [*default-value*] |
+ :stype:`SIP_ANYSLOT` [*default-value*] |
+ :stype:`SIP_QOBJECT` |
+ :stype:`SIP_RXOBJ_CON` |
+ :stype:`SIP_RXOBJ_DIS` |
+ :stype:`SIP_SIGNAL` [*default-value*] |
+ :stype:`SIP_SLOT` [*default-value*] |
+ :stype:`SIP_SLOT_CON` |
+ :stype:`SIP_SLOT_DIS`]
+
+ *default-value* ::= **=** *expression*
+
+ *expression* ::= [*value* | *value* *binary-operator* *expression*]
+
+ *value* ::= [*unary-operator*] *simple-value*
+
+ *simple-value* ::= [*scoped-name* | *function-call* | *real-value* |
+ *integer-value* | *boolean-value* | *string-value* |
+ *character-value*]
+
+ *typed-name*::= *type* *name*
+
+ *function-pointer*::= *type* **(*** *name* **)(** [*type-list*] **)**
+
+ *type-list* ::= *type* [**,** *type-list*]
+
+ *function-call* ::= *scoped-name* **(** [*value-list*] **)**
+
+ *value-list* ::= *value* [**,** *value-list*]
+
+ *real-value* ::= a floating point number
+
+ *integer-value* ::= a number
+
+ *boolean-value* ::= [**true** | **false**]
+
+ *string-value* ::= **"** {*character*} **"**
+
+ *character-value* ::= **'** *character* **'**
+
+ *unary-operator* ::= [**!** | **~** | **-** | **+**]
+
+ *binary-operator* ::= [**-** | **+** | ***** | **/** | **&** | **|**]
+
+ *argument-annotations* ::= see :ref:`ref-arg-annos`
+
+ *class-annotations* ::= see :ref:`ref-class-annos`
+
+ *enum-annotations* ::= see :ref:`ref-enum-annos`
+
+ *function-annotations* ::= see :ref:`ref-function-annos`
+
+ *typedef-annotations* ::= see :ref:`ref-typedef-annos`
+
+ *variable-annotations* ::= see :ref:`ref-variable-annos`
+
+ *type* ::= [**const**] *base-type* {*****} [**&**]
+
+ *type-list* ::= *type* [**,** *type-list*]
+
+ *base-type* ::= [*scoped-name* | *template* | **struct** *scoped-name* |
+ **char** | **signed char** | **unsigned char** | **wchar_t** |
+ **int** | **unsigned** | **unsigned int** |
+ **short** | **unsigned short** |
+ **long** | **unsigned long** |
+ **long long** | **unsigned long long** |
+ **float** | **double** |
+ **bool** |
+ **void** |
+ :stype:`SIP_PYCALLABLE` |
+ :stype:`SIP_PYDICT` |
+ :stype:`SIP_PYLIST` |
+ :stype:`SIP_PYOBJECT` |
+ :stype:`SIP_PYSLICE` |
+ :stype:`SIP_PYTUPLE` |
+ :stype:`SIP_PYTYPE`]
+
+ *scoped-name* ::= *name* [**::** *scoped-name*]
+
+ *template* ::= *scoped-name* **<** *type-list* **>**
+
+ *dotted-name* ::= *name* [**.** *dotted-name*]
+
+ *name* ::= _A-Za-z {_A-Za-z0-9}
+
+Here is a short list of differences between C++ and the subset supported by
+SIP that might trip you up.
+
+ - SIP does not support the use of ``[]`` in types. Use pointers instead.
+
+ - A global ``operator`` can only be defined if its first argument is a
+ class or a named enum that has been wrapped in the same module.
+
+ - Variables declared outside of a class are effectively read-only.
+
+ - A class's list of super-classes doesn't not include any access specifier
+ (e.g. ``public``).
+
+
+Variable Numbers of Arguments
+-----------------------------
+
+SIP supports the use of ``...`` as the last part of a function signature. Any
+remaining arguments are collected as a Python tuple.
+
+
+Additional SIP Types
+--------------------
+
+SIP supports a number of additional data types that can be used in Python
+signatures.
+
+
+.. sip-type:: SIP_ANYSLOT
+
+This is both a ``const char *`` and a ``PyObject *`` that is used as the type
+of the member instead of ``const char *`` in functions that implement the
+connection or disconnection of an explicitly generated signal to a slot.
+Handwritten code must be provided to interpret the conversion correctly.
+
+
+.. sip-type:: SIP_PYCALLABLE
+
+This is a ``PyObject *`` that is a Python callable object.
+
+
+.. sip-type:: SIP_PYDICT
+
+This is a ``PyObject *`` that is a Python dictionary object.
+
+
+.. sip-type:: SIP_PYLIST
+
+This is a ``PyObject *`` that is a Python list object.
+
+
+.. sip-type:: SIP_PYOBJECT
+
+This is a ``PyObject *`` of any Python type.
+
+
+.. sip-type:: SIP_PYSLICE
+
+This is a ``PyObject *`` that is a Python slice object.
+
+
+.. sip-type:: SIP_PYTUPLE
+
+This is a ``PyObject *`` that is a Python tuple object.
+
+
+.. sip-type:: SIP_PYTYPE
+
+This is a ``PyObject *`` that is a Python type object.
+
+
+.. sip-type:: SIP_QOBJECT
+
+This is a ``QObject *`` that is a C++ instance of a class derived from Qt's
+``QObject`` class.
+
+
+.. sip-type:: SIP_RXOBJ_CON
+
+This is a ``QObject *`` that is a C++ instance of a class derived from Qt's
+``QObject`` class. It is used as the type of the receiver instead of ``const
+QObject *`` in functions that implement a connection to a slot.
+
+
+.. sip-type:: SIP_RXOBJ_DIS
+
+This is a ``QObject *`` that is a C++ instance of a class derived from Qt's
+``QObject`` class. It is used as the type of the receiver instead of ``const
+QObject *`` in functions that implement a disconnection from a slot.
+
+
+.. sip-type:: SIP_SIGNAL
+
+This is a ``const char *`` that is used as the type of the signal instead of
+``const char *`` in functions that implement the connection or disconnection
+of an explicitly generated signal to a slot.
+
+
+.. sip-type:: SIP_SLOT
+
+This is a ``const char *`` that is used as the type of the member instead of
+``const char *`` in functions that implement the connection or disconnection
+of an explicitly generated signal to a slot.
+
+
+.. sip-type:: SIP_SLOT_CON
+
+This is a ``const char *`` that is used as the type of the member instead of
+``const char *`` in functions that implement the connection of an internally
+generated signal to a slot. The type includes a comma separated list of types
+that is the C++ signature of of the signal.
+
+To take an example, ``QAccel::connectItem()`` connects an internally generated
+signal to a slot. The signal is emitted when the keyboard accelerator is
+activated and it has a single integer argument that is the ID of the
+accelerator. The C++ signature is::
+
+ bool connectItem(int id, const QObject *receiver, const char *member);
+
+The corresponding SIP specification is::
+
+ bool connectItem(int, SIP_RXOBJ_CON, SIP_SLOT_CON(int));
+
+
+.. sip-type:: SIP_SLOT_DIS
+
+This is a ``const char *`` that is used as the type of the member instead of
+``const char *`` in functions that implement the disconnection of an
+internally generated signal to a slot. The type includes a comma separated
+list of types that is the C++ signature of of the signal.
+
+
+Classic Division and True Division
+----------------------------------
+
+SIP supports the ``__div__`` and ``__truediv__`` special methods (and the
+corresponding inplace versions) for both Python v2 and v3.
+
+For Python v2 the ``__div__`` method will be used for both classic and true
+division if a ``__truediv__`` method is not defined.
+
+For Python v3 the ``__div__`` method will be used for true division if a
+``__truediv__`` method is not defined.
+
+For all versions of Python, if both methods are defined then ``__div__``
+should be defined first.
diff --git a/doc/html/_sources/using.txt b/doc/html/_sources/using.txt
new file mode 100644
index 0000000..ff121ce
--- /dev/null
+++ b/doc/html/_sources/using.txt
@@ -0,0 +1,662 @@
+.. _ref-using:
+
+Using SIP
+=========
+
+Bindings are generated by the SIP code generator from a number of specification
+files, typically with a ``.sip`` extension. Specification files look very
+similar to C and C++ header files, but often with additional information (in
+the form of a *directive* or an *annotation*) and code so that the bindings
+generated can be finely tuned.
+
+
+.. _ref-simple-c++-example:
+
+A Simple C++ Example
+--------------------
+
+We start with a simple example. Let's say you have a (fictional) C++ library
+that implements a single class called ``Word``. The class has one constructor
+that takes a ``\0`` terminated character string as its single argument. The
+class has one method called ``reverse()`` which takes no arguments and returns
+a ``\0`` terminated character string. The interface to the class is defined in
+a header file called ``word.h`` which might look something like this::
+
+ // Define the interface to the word library.
+
+ class Word {
+ const char *the_word;
+
+ public:
+ Word(const char *w);
+
+ char *reverse() const;
+ };
+
+The corresponding SIP specification file would then look something like this::
+
+ // Define the SIP wrapper to the word library.
+
+ %Module word 0
+
+ class Word {
+
+ %TypeHeaderCode
+ #include <word.h>
+ %End
+
+ public:
+ Word(const char *w);
+
+ char *reverse() const;
+ };
+
+Obviously a SIP specification file looks very much like a C++ (or C) header
+file, but SIP does not include a full C++ parser. Let's look at the
+differences between the two files.
+
+ - The :directive:`%Module` directive has been added [#]_. This is used to
+ name the Python module that is being created and to give it a
+ *generation* number. In this example these are ``word`` and ``0``
+ respectively. The generation number is effectively the version number of
+ the module.
+
+ - The :directive:`%TypeHeaderCode` directive has been added. The text
+ between this and the following :directive:`%End` directive is included
+ literally in the code that SIP generates. Normally it is used, as in
+ this case, to ``#include`` the corresponding C++ (or C) header file [#]_.
+
+ - The declaration of the private variable ``this_word`` has been removed.
+ SIP does not support access to either private or protected instance
+ variables.
+
+If we want to we can now generate the C++ code in the current directory by
+running the following command::
+
+ sip -c . word.sip
+
+However, that still leaves us with the task of compiling the generated code and
+linking it against all the necessary libraries. It's much easier to use the
+:ref:`SIP build system <ref-build-system>` to do the whole thing.
+
+Using the SIP build system is simply a matter of writing a small Python script.
+In this simple example we will assume that the ``word`` library we are wrapping
+and it's header file are installed in standard system locations and will be
+found by the compiler and linker without having to specify any additional
+flags. In a more realistic example your Python script may take command line
+options, or search a set of directories to deal with different configurations
+and installations.
+
+This is the simplest script (conventionally called ``configure.py``)::
+
+ import os
+ import sipconfig
+
+ # The name of the SIP build file generated by SIP and used by the build
+ # system.
+ build_file = "word.sbf"
+
+ # Get the SIP configuration information.
+ config = sipconfig.Configuration()
+
+ # Run SIP to generate the code.
+ os.system(" ".join([config.sip_bin, "-c", ".", "-b", build_file, "word.sip"]))
+
+ # Create the Makefile.
+ makefile = sipconfig.SIPModuleMakefile(config, build_file)
+
+ # Add the library we are wrapping. The name doesn't include any platform
+ # specific prefixes or extensions (e.g. the "lib" prefix on UNIX, or the
+ # ".dll" extension on Windows).
+ makefile.extra_libs = ["word"]
+
+ # Generate the Makefile itself.
+ makefile.generate()
+
+Hopefully this script is self-documenting. The key parts are the
+``Configuration`` and ``SIPModuleMakefile`` classes. The build system contains
+other Makefile classes, for example to build programs or to call other
+Makefiles in sub-directories.
+
+After running the script (using the Python interpreter the extension module is
+being created for) the generated C++ code and ``Makefile`` will be in the
+current directory.
+
+To compile and install the extension module, just run the following
+commands [#]_::
+
+ make
+ make install
+
+That's all there is to it.
+
+See :ref:`ref-distutils` for an example of how to build this example using
+distutils.
+
+.. [#] All SIP directives start with a ``%`` as the first non-whitespace
+ character of a line.
+.. [#] SIP includes many code directives like this. They differ in where the
+ supplied code is placed by SIP in the generated code.
+.. [#] On Windows you might run ``nmake`` or ``mingw32-make`` instead.
+
+
+A Simple C Example
+------------------
+
+Let's now look at a very similar example of wrapping a fictional C library::
+
+ /* Define the interface to the word library. */
+
+ struct Word {
+ const char *the_word;
+ };
+
+ struct Word *create_word(const char *w);
+ char *reverse(struct Word *word);
+
+The corresponding SIP specification file would then look something like this::
+
+ /* Define the SIP wrapper to the word library. */
+
+ %CModule word 0
+
+ struct Word {
+
+ %TypeHeaderCode
+ #include <word.h>
+ %End
+
+ const char *the_word;
+ };
+
+ struct Word *create_word(const char *w) /Factory/;
+ char *reverse(struct Word *word);
+
+Again, let's look at the differences between the two files.
+
+ - The :directive:`%CModule` directive has been added. This has the same
+ syntax as the :directive:`%Module` directive used in the previous example
+ but tells SIP that the library being wrapped is implemented in C rather
+ than C++.
+
+ - The :directive:`%TypeHeaderCode` directive has been added.
+
+ - The :fanno:`Factory` annotation has been added to the ``create_word()``
+ function. This tells SIP that a newly created structure is being
+ returned and it is owned by Python.
+
+The ``configure.py`` build system script described in the previous example can
+be used for this example without change.
+
+
+A More Complex C++ Example
+--------------------------
+
+In this last example we will wrap a fictional C++ library that contains a class
+that is derived from a Qt class. This will demonstrate how SIP allows a class
+hierarchy to be split across multiple Python extension modules, and will
+introduce SIP's versioning system.
+
+The library contains a single C++ class called ``Hello`` which is derived from
+Qt's ``QLabel`` class. It behaves just like ``QLabel`` except that the text
+in the label is hard coded to be ``Hello World``. To make the example more
+interesting we'll also say that the library only supports Qt v4.2 and later,
+and also includes a function called ``setDefault()`` that is not implemented
+in the Windows version of the library.
+
+The ``hello.h`` header file looks something like this::
+
+ // Define the interface to the hello library.
+
+ #include <qlabel.h>
+ #include <qwidget.h>
+ #include <qstring.h>
+
+ class Hello : public QLabel {
+ // This is needed by the Qt Meta-Object Compiler.
+ Q_OBJECT
+
+ public:
+ Hello(QWidget *parent = 0);
+
+ private:
+ // Prevent instances from being copied.
+ Hello(const Hello &);
+ Hello &operator=(const Hello &);
+ };
+
+ #if !defined(Q_OS_WIN)
+ void setDefault(const QString &def);
+ #endif
+
+The corresponding SIP specification file would then look something like this::
+
+ // Define the SIP wrapper to the hello library.
+
+ %Module hello 0
+
+ %Import QtGui/QtGuimod.sip
+
+ %If (Qt_4_2_0 -)
+
+ class Hello : QLabel {
+
+ %TypeHeaderCode
+ #include <hello.h>
+ %End
+
+ public:
+ Hello(QWidget *parent /TransferThis/ = 0);
+
+ private:
+ Hello(const Hello &);
+ };
+
+ %If (!WS_WIN)
+ void setDefault(const QString &def);
+ %End
+
+ %End
+
+Again we look at the differences, but we'll skip those that we've looked at in
+previous examples.
+
+ - The :directive:`%Import` directive has been added to specify that we are
+ extending the class hierarchy defined in the file ``QtGui/QtGuimod.sip``.
+ This file is part of PyQt. The build system will take care of finding
+ the file's exact location.
+
+ - The :directive:`%If` directive has been added to specify that everything
+ [#]_ up to the matching :directive:`%End` directive only applies to Qt
+ v4.2 and later. ``Qt_4_2_0`` is a *tag* defined in ``QtCoremod.sip``
+ [#]_ using the :directive:`%Timeline` directive. :directive:`%Timeline`
+ is used to define a tag for each version of a library's API you are
+ wrapping allowing you to maintain all the different versions in a single
+ SIP specification. The build system provides support to ``configure.py``
+ scripts for working out the correct tags to use according to which
+ version of the library is actually installed.
+
+ - The ``public`` keyword used in defining the super-classes has been
+ removed. This is not supported by SIP.
+
+ - The :aanno:`TransferThis` annotation has been added to the constructor's
+ argument. It specifies that if the argument is not 0 (i.e. the ``Hello``
+ instance being constructed has a parent) then ownership of the instance
+ is transferred from Python to C++. It is needed because Qt maintains
+ objects (i.e. instances derived from the ``QObject`` class) in a
+ hierachy. When an object is destroyed all of its children are also
+ automatically destroyed. It is important, therefore, that the Python
+ garbage collector doesn't also try and destroy them. This is covered in
+ more detail in :ref:`ref-object-ownership`. SIP provides many other
+ annotations that can be applied to arguments, functions and classes.
+ Multiple annotations are separated by commas. Annotations may have
+ values.
+
+ - The ``=`` operator has been removed. This operator is not supported by
+ SIP.
+
+ - The :directive:`%If` directive has been added to specify that everything
+ up to the matching :directive:`%End` directive does not apply to Windows.
+ ``WS_WIN`` is another tag defined by PyQt, this time using the
+ :directive:`%Platforms` directive. Tags defined by the
+ :directive:`%Platforms` directive are mutually exclusive, i.e. only one
+ may be valid at a time [#]_.
+
+One question you might have at this point is why bother to define the private
+copy constructor when it can never be called from Python? The answer is to
+prevent the automatic generation of a public copy constructor.
+
+We now look at the ``configure.py`` script. This is a little different to the
+script in the previous examples for two related reasons.
+
+Firstly, PyQt includes a pure Python module called ``pyqtconfig`` that extends
+the SIP build system for modules, like our example, that build on top of PyQt.
+It deals with the details of which version of Qt is being used (i.e. it
+determines what the correct tags are) and where it is installed. This is
+called a module's configuration module.
+
+Secondly, we generate a configuration module (called ``helloconfig``) for our
+own ``hello`` module. There is no need to do this, but if there is a chance
+that somebody else might want to extend your C++ library then it would make
+life easier for them.
+
+Now we have two scripts. First the ``configure.py`` script::
+
+ import os
+ import sipconfig
+ from PyQt4 import pyqtconfig
+
+ # The name of the SIP build file generated by SIP and used by the build
+ # system.
+ build_file = "hello.sbf"
+
+ # Get the PyQt configuration information.
+ config = pyqtconfig.Configuration()
+
+ # Get the extra SIP flags needed by the imported PyQt modules. Note that
+ # this normally only includes those flags (-x and -t) that relate to SIP's
+ # versioning system.
+ pyqt_sip_flags = config.pyqt_sip_flags
+
+ # Run SIP to generate the code. Note that we tell SIP where to find the qt
+ # module's specification files using the -I flag.
+ os.system(" ".join([config.sip_bin, "-c", ".", "-b", build_file, "-I", config.pyqt_sip_dir, pyqt_sip_flags, "hello.sip"]))
+
+ # We are going to install the SIP specification file for this module and
+ # its configuration module.
+ installs = []
+
+ installs.append(["hello.sip", os.path.join(config.default_sip_dir, "hello")])
+
+ installs.append(["helloconfig.py", config.default_mod_dir])
+
+ # Create the Makefile. The QtGuiModuleMakefile class provided by the
+ # pyqtconfig module takes care of all the extra preprocessor, compiler and
+ # linker flags needed by the Qt library.
+ makefile = pyqtconfig.QtGuiModuleMakefile(
+ configuration=config,
+ build_file=build_file,
+ installs=installs
+ )
+
+ # Add the library we are wrapping. The name doesn't include any platform
+ # specific prefixes or extensions (e.g. the "lib" prefix on UNIX, or the
+ # ".dll" extension on Windows).
+ makefile.extra_libs = ["hello"]
+
+ # Generate the Makefile itself.
+ makefile.generate()
+
+ # Now we create the configuration module. This is done by merging a Python
+ # dictionary (whose values are normally determined dynamically) with a
+ # (static) template.
+ content = {
+ # Publish where the SIP specifications for this module will be
+ # installed.
+ "hello_sip_dir": config.default_sip_dir,
+
+ # Publish the set of SIP flags needed by this module. As these are the
+ # same flags needed by the qt module we could leave it out, but this
+ # allows us to change the flags at a later date without breaking
+ # scripts that import the configuration module.
+ "hello_sip_flags": pyqt_sip_flags
+ }
+
+ # This creates the helloconfig.py module from the helloconfig.py.in
+ # template and the dictionary.
+ sipconfig.create_config_module("helloconfig.py", "helloconfig.py.in", content)
+
+Next we have the ``helloconfig.py.in`` template script::
+
+ from PyQt4 import pyqtconfig
+
+ # These are installation specific values created when Hello was configured.
+ # The following line will be replaced when this template is used to create
+ # the final configuration module.
+ # @SIP_CONFIGURATION@
+
+ class Configuration(pyqtconfig.Configuration):
+ """The class that represents Hello configuration values.
+ """
+ def __init__(self, sub_cfg=None):
+ """Initialise an instance of the class.
+
+ sub_cfg is the list of sub-class configurations. It should be None
+ when called normally.
+ """
+ # This is all standard code to be copied verbatim except for the
+ # name of the module containing the super-class.
+ if sub_cfg:
+ cfg = sub_cfg
+ else:
+ cfg = []
+
+ cfg.append(_pkg_config)
+
+ pyqtconfig.Configuration.__init__(self, cfg)
+
+ class HelloModuleMakefile(pyqtconfig.QtGuiModuleMakefile):
+ """The Makefile class for modules that %Import hello.
+ """
+ def finalise(self):
+ """Finalise the macros.
+ """
+ # Make sure our C++ library is linked.
+ self.extra_libs.append("hello")
+
+ # Let the super-class do what it needs to.
+ pyqtconfig.QtGuiModuleMakefile.finalise(self)
+
+Again, we hope that the scripts are self documenting.
+
+.. [#] Some parts of a SIP specification aren't subject to version control.
+.. [#] Actually in ``versions.sip``. PyQt uses the :directive:`%Include`
+ directive to split the SIP specification for Qt across a large number of
+ separate ``.sip`` files.
+.. [#] Tags can also be defined by the :directive:`%Feature` directive. These
+ tags are not mutually exclusive, i.e. any number may be valid at a time.
+
+
+.. _ref-object-ownership:
+
+Ownership of Objects
+--------------------
+
+When a C++ instance is wrapped a corresponding Python object is created. The
+Python object behaves as you would expect in regard to garbage collection - it
+is garbage collected when its reference count reaches zero. What then happens
+to the corresponding C++ instance? The obvious answer might be that the
+instance's destructor is called. However the library API may say that when the
+instance is passed to a particular function, the library takes ownership of the
+instance, i.e. responsibility for calling the instance's destructor is
+transferred from the SIP generated module to the library.
+
+Ownership of an instance may also be associated with another instance. The
+implication being that the owned instance will automatically be destroyed if
+the owning instance is destroyed. SIP keeps track of these relationships to
+ensure that Python's cyclic garbage collector can detect and break any
+reference cycles between the owning and owned instances. The association is
+implemented as the owning instance taking a reference to the owned instance.
+
+The TransferThis, Transfer and TransferBack annotations are used to specify
+where, and it what direction, transfers of ownership happen. It is very
+important that these are specified correctly to avoid crashes (where both
+Python and C++ call the destructor) and memory leaks (where neither Python and
+C++ call the destructor).
+
+This applies equally to C structures where the structure is returned to the
+heap using the ``free()`` function.
+
+See also :cfunc:`sipTransferTo()`, :cfunc:`sipTransferBack()` and
+:cfunc:`sipTransferBreak()`.
+
+
+.. _ref-types-metatypes:
+
+Types and Meta-types
+--------------------
+
+Every Python object (with the exception of the :class:`object` object itself)
+has a meta-type and at least one super-type. By default an object's meta-type
+is the meta-type of its first super-type.
+
+SIP implements two super-types, :class:`sip.simplewrapper` and
+:class:`sip.wrapper`, and a meta-type, :class:`sip.wrappertype`.
+
+:class:`sip.simplewrapper` is the super-type of :class:`sip.wrapper`. The
+super-type of :class:`sip.simplewrapper` is :class:`object`.
+
+:class:`sip.wrappertype` is the meta-type of both :class:`sip.simplewrapper`
+and :class:`sip.wrapper`. The super-type of :class:`sip.wrappertype` is
+:class:`type`.
+
+:class:`sip.wrapper` supports the concept of object ownership described in
+:ref:`ref-object-ownership` and, by default, is the super-type of all the types
+that SIP generates.
+
+:class:`sip.simplewrapper` does not support the concept of object ownership but
+SIP generated types that are sub-classed from it have Python objects that take
+less memory.
+
+SIP allows a class's meta-type and super-type to be explicitly specified using
+the :canno:`Metatype` and :canno:`Supertype` class annotations.
+
+SIP also allows the default meta-type and super-type to be changed for a module
+using the :directive:`%DefaultMetatype` and :directive:`%DefaultSupertype`
+directives. Unlike the default super-type, the default meta-type is inherited
+by importing modules.
+
+If you want to use your own meta-type or super-type then they must be
+sub-classed from one of the SIP provided types. Your types must be registered
+using :cfunc:`sipRegisterPyType()`. This is normally done in code specified
+using the :directive:`%InitialisationCode` directive.
+
+As an example, PyQt4 uses :directive:`%DefaultMetatype` to specify a new
+meta-type that handles the interaction with Qt's own meta-type system. It also
+uses :directive:`%DefaultSupertype` to specify that the smaller
+:class:`sip.simplewrapper` super-type is normally used. Finally it uses
+:canno:`Supertype` as an annotation of the ``QObject`` class to override the
+default and use :class:`sip.wrapper` as the super-type so that the parent/child
+relationships of ``QObject`` instances are properly maintained.
+
+
+.. _ref-lazy-type-attributes:
+
+Lazy Type Attributes
+--------------------
+
+Instead of populating a wrapped type's dictionary with its attributes (or
+descriptors for those attributes) SIP only creates objects for those attributes
+when they are actually needed. This is done to reduce the memory footprint and
+start up time when used to wrap large libraries with hundreds of classes and
+tens of thousands of attributes.
+
+SIP allows you to extend the handling of lazy attributes to your own attribute
+types by allowing you to register an attribute getter handler (using
+:cfunc:`sipRegisterAttributeGetter()`). This will be called just before a
+type's dictionary is accessed for the first time.
+
+
+Support for Python's Buffer Interface
+-------------------------------------
+
+SIP supports Python's buffer interface in that whenever C/C++ requires a
+``char`` or ``char *`` type then any Python type that supports the buffer
+interface (including ordinary Python strings) can be used.
+
+If a buffer is made up of a number of segments then all but the first will be
+ignored.
+
+
+Support for Wide Characters
+---------------------------
+
+SIP v4.6 introduced support for wide characters (i.e. the ``wchar_t`` type).
+Python's C API includes support for converting between unicode objects and wide
+character strings and arrays. When converting from a unicode object to wide
+characters SIP creates the string or array on the heap (using memory allocated
+using :cfunc:`sipMalloc()`). This then raises the problem of how this memory
+is subsequently freed.
+
+The following describes how SIP handles this memory in the different situations
+where this is an issue.
+
+ - When a wide string or array is passed to a function or method then the
+ memory is freed (using :cfunc:`sipFree()`) after than function or method
+ returns.
+
+ - When a wide string or array is returned from a virtual method then SIP
+ does not free the memory until the next time the method is called.
+
+ - When an assignment is made to a wide string or array instance variable
+ then SIP does not first free the instance's current string or array.
+
+
+.. _ref-gil:
+
+The Python Global Interpreter Lock
+----------------------------------
+
+Python's Global Interpretor Lock (GIL) must be acquired before calls can be
+made to the Python API. It should also be released when a potentially
+blocking call to C/C++ library is made in order to allow other Python threads
+to be executed. In addition, some C/C++ libraries may implement their own
+locking strategies that conflict with the GIL causing application deadlocks.
+SIP provides ways of specifying when the GIL is released and acquired to
+ensure that locking problems can be avoided.
+
+SIP always ensures that the GIL is acquired before making calls to the Python
+API. By default SIP does not release the GIL when making calls to the C/C++
+library being wrapped. The :fanno:`ReleaseGIL` annotation can be used to
+override this behaviour when required.
+
+If SIP is given the :option:`-g <sip -g>` command line option then the default
+behaviour is changed and SIP releases the GIL every time is makes calls to the
+C/C++ library being wrapped. The :fanno:`HoldGIL` annotation can be used to
+override this behaviour when required.
+
+
+.. _ref-incompat-apis:
+
+Managing Incompatible APIs
+--------------------------
+
+.. versionadded:: 4.9
+
+Sometimes it is necessary to change the way something is wrapped in a way that
+introduces an incompatibility. For example a new feature of Python may
+suggest that something may be wrapped in a different way to exploit that
+feature.
+
+SIP's :directive:`%Feature` directive could be used to provide two different
+implementations. However this would mean that the choice between the two
+implementations would have to be made when building the generated module
+potentially causing all sorts of deployment problems. It may also require
+applications to work out which implementation was available and to change
+their behaviour accordingly.
+
+Instead SIP provides limited support for providing multiple implementations
+(of classes, mapped types and functions) that can be selected by an
+application at run-time. It is then up to the application developer how they
+want to manage the migration from the old API to the new, incompatible API.
+
+This support is implemented in three parts.
+
+Firstly the :directive:`%API` directive is used to define the name of an API
+and its default version number. The default version number is the one used if
+an application doesn't explicitly set the version number to use.
+
+Secondly the :canno:`API class <API>`, :manno:`mapped type <API>` or
+:fanno:`function <API>` annotation is applied accordingly to specify the API
+and range of version numbers that a particular class, mapped type or function
+implementation should be enabled for.
+
+Finally the application calls :func:`sip.setapi` to specify the version number
+of the API that should be enabled. This call must be made before any module
+that has multiple implementations is imported for the first time.
+
+Note this mechanism is not intended as a way or providing equally valid
+alternative APIs. For example::
+
+ %API MyAPI 1
+
+ class Foo
+ {
+ public:
+ void bar();
+ };
+
+ class Baz : Foo
+ {
+ public:
+ void bar() /API=MyAPI:2-/;
+ };
+
+If the following Python code is executed then an exception will be raised::
+
+ b = Baz()
+ b.bar()
+
+This is because when version 1 of the *MyAPI* API (the default) is enabled
+there is no *Baz.bar()* implementation and *Foo.bar()* will not be called
+instead as might be expected.
diff --git a/doc/html/_static/basic.css b/doc/html/_static/basic.css
new file mode 100644
index 0000000..a04d654
--- /dev/null
+++ b/doc/html/_static/basic.css
@@ -0,0 +1,417 @@
+/**
+ * Sphinx stylesheet -- basic theme
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+/* -- main layout ----------------------------------------------------------- */
+
+div.clearer {
+ clear: both;
+}
+
+/* -- relbar ---------------------------------------------------------------- */
+
+div.related {
+ width: 100%;
+ font-size: 90%;
+}
+
+div.related h3 {
+ display: none;
+}
+
+div.related ul {
+ margin: 0;
+ padding: 0 0 0 10px;
+ list-style: none;
+}
+
+div.related li {
+ display: inline;
+}
+
+div.related li.right {
+ float: right;
+ margin-right: 5px;
+}
+
+/* -- sidebar --------------------------------------------------------------- */
+
+div.sphinxsidebarwrapper {
+ padding: 10px 5px 0 10px;
+}
+
+div.sphinxsidebar {
+ float: left;
+ width: 230px;
+ margin-left: -100%;
+ font-size: 90%;
+}
+
+div.sphinxsidebar ul {
+ list-style: none;
+}
+
+div.sphinxsidebar ul ul,
+div.sphinxsidebar ul.want-points {
+ margin-left: 20px;
+ list-style: square;
+}
+
+div.sphinxsidebar ul ul {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+div.sphinxsidebar form {
+ margin-top: 10px;
+}
+
+div.sphinxsidebar input {
+ border: 1px solid #98dbcc;
+ font-family: sans-serif;
+ font-size: 1em;
+}
+
+img {
+ border: 0;
+}
+
+/* -- search page ----------------------------------------------------------- */
+
+ul.search {
+ margin: 10px 0 0 20px;
+ padding: 0;
+}
+
+ul.search li {
+ padding: 5px 0 5px 20px;
+ background-image: url(file.png);
+ background-repeat: no-repeat;
+ background-position: 0 7px;
+}
+
+ul.search li a {
+ font-weight: bold;
+}
+
+ul.search li div.context {
+ color: #888;
+ margin: 2px 0 0 30px;
+ text-align: left;
+}
+
+ul.keywordmatches li.goodmatch a {
+ font-weight: bold;
+}
+
+/* -- index page ------------------------------------------------------------ */
+
+table.contentstable {
+ width: 90%;
+}
+
+table.contentstable p.biglink {
+ line-height: 150%;
+}
+
+a.biglink {
+ font-size: 1.3em;
+}
+
+span.linkdescr {
+ font-style: italic;
+ padding-top: 5px;
+ font-size: 90%;
+}
+
+/* -- general index --------------------------------------------------------- */
+
+table.indextable td {
+ text-align: left;
+ vertical-align: top;
+}
+
+table.indextable dl, table.indextable dd {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+table.indextable tr.pcap {
+ height: 10px;
+}
+
+table.indextable tr.cap {
+ margin-top: 10px;
+ background-color: #f2f2f2;
+}
+
+img.toggler {
+ margin-right: 3px;
+ margin-top: 3px;
+ cursor: pointer;
+}
+
+/* -- general body styles --------------------------------------------------- */
+
+a.headerlink {
+ visibility: hidden;
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink {
+ visibility: visible;
+}
+
+div.body p.caption {
+ text-align: inherit;
+}
+
+div.body td {
+ text-align: left;
+}
+
+.field-list ul {
+ padding-left: 1em;
+}
+
+.first {
+ margin-top: 0 !important;
+}
+
+p.rubric {
+ margin-top: 30px;
+ font-weight: bold;
+}
+
+/* -- sidebars -------------------------------------------------------------- */
+
+div.sidebar {
+ margin: 0 0 0.5em 1em;
+ border: 1px solid #ddb;
+ padding: 7px 7px 0 7px;
+ background-color: #ffe;
+ width: 40%;
+ float: right;
+}
+
+p.sidebar-title {
+ font-weight: bold;
+}
+
+/* -- topics ---------------------------------------------------------------- */
+
+div.topic {
+ border: 1px solid #ccc;
+ padding: 7px 7px 0 7px;
+ margin: 10px 0 10px 0;
+}
+
+p.topic-title {
+ font-size: 1.1em;
+ font-weight: bold;
+ margin-top: 10px;
+}
+
+/* -- admonitions ----------------------------------------------------------- */
+
+div.admonition {
+ margin-top: 10px;
+ margin-bottom: 10px;
+ padding: 7px;
+}
+
+div.admonition dt {
+ font-weight: bold;
+}
+
+div.admonition dl {
+ margin-bottom: 0;
+}
+
+p.admonition-title {
+ margin: 0px 10px 5px 0px;
+ font-weight: bold;
+}
+
+div.body p.centered {
+ text-align: center;
+ margin-top: 25px;
+}
+
+/* -- tables ---------------------------------------------------------------- */
+
+table.docutils {
+ border: 0;
+ border-collapse: collapse;
+}
+
+table.docutils td, table.docutils th {
+ padding: 1px 8px 1px 0;
+ border-top: 0;
+ border-left: 0;
+ border-right: 0;
+ border-bottom: 1px solid #aaa;
+}
+
+table.field-list td, table.field-list th {
+ border: 0 !important;
+}
+
+table.footnote td, table.footnote th {
+ border: 0 !important;
+}
+
+th {
+ text-align: left;
+ padding-right: 5px;
+}
+
+/* -- other body styles ----------------------------------------------------- */
+
+dl {
+ margin-bottom: 15px;
+}
+
+dd p {
+ margin-top: 0px;
+}
+
+dd ul, dd table {
+ margin-bottom: 10px;
+}
+
+dd {
+ margin-top: 3px;
+ margin-bottom: 10px;
+ margin-left: 30px;
+}
+
+dt:target, .highlight {
+ background-color: #fbe54e;
+}
+
+dl.glossary dt {
+ font-weight: bold;
+ font-size: 1.1em;
+}
+
+.field-list ul {
+ margin: 0;
+ padding-left: 1em;
+}
+
+.field-list p {
+ margin: 0;
+}
+
+.refcount {
+ color: #060;
+}
+
+.optional {
+ font-size: 1.3em;
+}
+
+.versionmodified {
+ font-style: italic;
+}
+
+.system-message {
+ background-color: #fda;
+ padding: 5px;
+ border: 3px solid red;
+}
+
+.footnote:target {
+ background-color: #ffa
+}
+
+.line-block {
+ display: block;
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+
+.line-block .line-block {
+ margin-top: 0;
+ margin-bottom: 0;
+ margin-left: 1.5em;
+}
+
+/* -- code displays --------------------------------------------------------- */
+
+pre {
+ overflow: auto;
+}
+
+td.linenos pre {
+ padding: 5px 0px;
+ border: 0;
+ background-color: transparent;
+ color: #aaa;
+}
+
+table.highlighttable {
+ margin-left: 0.5em;
+}
+
+table.highlighttable td {
+ padding: 0 0.5em 0 0.5em;
+}
+
+tt.descname {
+ background-color: transparent;
+ font-weight: bold;
+ font-size: 1.2em;
+}
+
+tt.descclassname {
+ background-color: transparent;
+}
+
+tt.xref, a tt {
+ background-color: transparent;
+ font-weight: bold;
+}
+
+h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
+ background-color: transparent;
+}
+
+/* -- math display ---------------------------------------------------------- */
+
+img.math {
+ vertical-align: middle;
+}
+
+div.body div.math p {
+ text-align: center;
+}
+
+span.eqno {
+ float: right;
+}
+
+/* -- printout stylesheet --------------------------------------------------- */
+
+@media print {
+ div.document,
+ div.documentwrapper,
+ div.bodywrapper {
+ margin: 0 !important;
+ width: 100%;
+ }
+
+ div.sphinxsidebar,
+ div.related,
+ div.footer,
+ #top-link {
+ display: none;
+ }
+}
diff --git a/doc/html/_static/default.css b/doc/html/_static/default.css
new file mode 100644
index 0000000..42ed6ec
--- /dev/null
+++ b/doc/html/_static/default.css
@@ -0,0 +1,218 @@
+/**
+ * Sphinx stylesheet -- default theme
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+@import url("basic.css");
+
+/* -- page layout ----------------------------------------------------------- */
+
+body {
+ font-family: sans-serif;
+ font-size: 100%;
+ background-color: #11303d;
+ color: #000;
+ margin: 0;
+ padding: 0;
+}
+
+div.document {
+ background-color: #1c4e63;
+}
+
+div.documentwrapper {
+ float: left;
+ width: 100%;
+}
+
+div.bodywrapper {
+ margin: 0 0 0 230px;
+}
+
+div.body {
+ background-color: #ffffff;
+ color: #000000;
+ padding: 0 20px 30px 20px;
+}
+
+div.footer {
+ color: #ffffff;
+ width: 100%;
+ padding: 9px 0 9px 0;
+ text-align: center;
+ font-size: 75%;
+}
+
+div.footer a {
+ color: #ffffff;
+ text-decoration: underline;
+}
+
+div.related {
+ background-color: #133f52;
+ line-height: 30px;
+ color: #ffffff;
+}
+
+div.related a {
+ color: #ffffff;
+}
+
+div.sphinxsidebar {
+}
+
+div.sphinxsidebar h3 {
+ font-family: 'Trebuchet MS', sans-serif;
+ color: #ffffff;
+ font-size: 1.4em;
+ font-weight: normal;
+ margin: 0;
+ padding: 0;
+}
+
+div.sphinxsidebar h3 a {
+ color: #ffffff;
+}
+
+div.sphinxsidebar h4 {
+ font-family: 'Trebuchet MS', sans-serif;
+ color: #ffffff;
+ font-size: 1.3em;
+ font-weight: normal;
+ margin: 5px 0 0 0;
+ padding: 0;
+}
+
+div.sphinxsidebar p {
+ color: #ffffff;
+}
+
+div.sphinxsidebar p.topless {
+ margin: 5px 10px 10px 10px;
+}
+
+div.sphinxsidebar ul {
+ margin: 10px;
+ padding: 0;
+ color: #ffffff;
+}
+
+div.sphinxsidebar a {
+ color: #98dbcc;
+}
+
+div.sphinxsidebar input {
+ border: 1px solid #98dbcc;
+ font-family: sans-serif;
+ font-size: 1em;
+}
+
+/* -- body styles ----------------------------------------------------------- */
+
+a {
+ color: #355f7c;
+ text-decoration: none;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+div.body p, div.body dd, div.body li {
+ text-align: justify;
+ line-height: 130%;
+}
+
+div.body h1,
+div.body h2,
+div.body h3,
+div.body h4,
+div.body h5,
+div.body h6 {
+ font-family: 'Trebuchet MS', sans-serif;
+ background-color: #f2f2f2;
+ font-weight: normal;
+ color: #20435c;
+ border-bottom: 1px solid #ccc;
+ margin: 20px -20px 10px -20px;
+ padding: 3px 0 3px 10px;
+}
+
+div.body h1 { margin-top: 0; font-size: 200%; }
+div.body h2 { font-size: 160%; }
+div.body h3 { font-size: 140%; }
+div.body h4 { font-size: 120%; }
+div.body h5 { font-size: 110%; }
+div.body h6 { font-size: 100%; }
+
+a.headerlink {
+ color: #c60f0f;
+ font-size: 0.8em;
+ padding: 0 4px 0 4px;
+ text-decoration: none;
+}
+
+a.headerlink:hover {
+ background-color: #c60f0f;
+ color: white;
+}
+
+div.body p, div.body dd, div.body li {
+ text-align: justify;
+ line-height: 130%;
+}
+
+div.admonition p.admonition-title + p {
+ display: inline;
+}
+
+div.note {
+ background-color: #eee;
+ border: 1px solid #ccc;
+}
+
+div.seealso {
+ background-color: #ffc;
+ border: 1px solid #ff6;
+}
+
+div.topic {
+ background-color: #eee;
+}
+
+div.warning {
+ background-color: #ffe4e4;
+ border: 1px solid #f66;
+}
+
+p.admonition-title {
+ display: inline;
+}
+
+p.admonition-title:after {
+ content: ":";
+}
+
+pre {
+ padding: 5px;
+ background-color: #eeffcc;
+ color: #333333;
+ line-height: 120%;
+ border: 1px solid #ac9;
+ border-left: none;
+ border-right: none;
+}
+
+tt {
+ background-color: #ecf0f3;
+ padding: 0 1px 0 1px;
+ font-size: 0.95em;
+}
+
+.warning tt {
+ background: #efc2c2;
+}
+
+.note tt {
+ background: #d6d6d6;
+} \ No newline at end of file
diff --git a/doc/html/_static/doctools.js b/doc/html/_static/doctools.js
new file mode 100644
index 0000000..9447678
--- /dev/null
+++ b/doc/html/_static/doctools.js
@@ -0,0 +1,232 @@
+/// XXX: make it cross browser
+
+/**
+ * make the code below compatible with browsers without
+ * an installed firebug like debugger
+ */
+if (!window.console || !console.firebug) {
+ var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
+ "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
+ window.console = {};
+ for (var i = 0; i < names.length; ++i)
+ window.console[names[i]] = function() {}
+}
+
+/**
+ * small helper function to urldecode strings
+ */
+jQuery.urldecode = function(x) {
+ return decodeURIComponent(x).replace(/\+/g, ' ');
+}
+
+/**
+ * small helper function to urlencode strings
+ */
+jQuery.urlencode = encodeURIComponent;
+
+/**
+ * This function returns the parsed url parameters of the
+ * current request. Multiple values per key are supported,
+ * it will always return arrays of strings for the value parts.
+ */
+jQuery.getQueryParameters = function(s) {
+ if (typeof s == 'undefined')
+ s = document.location.search;
+ var parts = s.substr(s.indexOf('?') + 1).split('&');
+ var result = {};
+ for (var i = 0; i < parts.length; i++) {
+ var tmp = parts[i].split('=', 2);
+ var key = jQuery.urldecode(tmp[0]);
+ var value = jQuery.urldecode(tmp[1]);
+ if (key in result)
+ result[key].push(value);
+ else
+ result[key] = [value];
+ }
+ return result;
+}
+
+/**
+ * small function to check if an array contains
+ * a given item.
+ */
+jQuery.contains = function(arr, item) {
+ for (var i = 0; i < arr.length; i++) {
+ if (arr[i] == item)
+ return true;
+ }
+ return false;
+}
+
+/**
+ * highlight a given string on a jquery object by wrapping it in
+ * span elements with the given class name.
+ */
+jQuery.fn.highlightText = function(text, className) {
+ function highlight(node) {
+ if (node.nodeType == 3) {
+ var val = node.nodeValue;
+ var pos = val.toLowerCase().indexOf(text);
+ if (pos >= 0 && !jQuery.className.has(node.parentNode, className)) {
+ var span = document.createElement("span");
+ span.className = className;
+ span.appendChild(document.createTextNode(val.substr(pos, text.length)));
+ node.parentNode.insertBefore(span, node.parentNode.insertBefore(
+ document.createTextNode(val.substr(pos + text.length)),
+ node.nextSibling));
+ node.nodeValue = val.substr(0, pos);
+ }
+ }
+ else if (!jQuery(node).is("button, select, textarea")) {
+ jQuery.each(node.childNodes, function() {
+ highlight(this)
+ });
+ }
+ }
+ return this.each(function() {
+ highlight(this);
+ });
+}
+
+/**
+ * Small JavaScript module for the documentation.
+ */
+var Documentation = {
+
+ init : function() {
+ this.fixFirefoxAnchorBug();
+ this.highlightSearchWords();
+ this.initModIndex();
+ },
+
+ /**
+ * i18n support
+ */
+ TRANSLATIONS : {},
+ PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; },
+ LOCALE : 'unknown',
+
+ // gettext and ngettext don't access this so that the functions
+ // can savely bound to a different name (_ = Documentation.gettext)
+ gettext : function(string) {
+ var translated = Documentation.TRANSLATIONS[string];
+ if (typeof translated == 'undefined')
+ return string;
+ return (typeof translated == 'string') ? translated : translated[0];
+ },
+
+ ngettext : function(singular, plural, n) {
+ var translated = Documentation.TRANSLATIONS[singular];
+ if (typeof translated == 'undefined')
+ return (n == 1) ? singular : plural;
+ return translated[Documentation.PLURALEXPR(n)];
+ },
+
+ addTranslations : function(catalog) {
+ for (var key in catalog.messages)
+ this.TRANSLATIONS[key] = catalog.messages[key];
+ this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
+ this.LOCALE = catalog.locale;
+ },
+
+ /**
+ * add context elements like header anchor links
+ */
+ addContextElements : function() {
+ $('div[id] > :header:first').each(function() {
+ $('<a class="headerlink">\u00B6</a>').
+ attr('href', '#' + this.id).
+ attr('title', _('Permalink to this headline')).
+ appendTo(this);
+ });
+ $('dt[id]').each(function() {
+ $('<a class="headerlink">\u00B6</a>').
+ attr('href', '#' + this.id).
+ attr('title', _('Permalink to this definition')).
+ appendTo(this);
+ });
+ },
+
+ /**
+ * workaround a firefox stupidity
+ */
+ fixFirefoxAnchorBug : function() {
+ if (document.location.hash && $.browser.mozilla)
+ window.setTimeout(function() {
+ document.location.href += '';
+ }, 10);
+ },
+
+ /**
+ * highlight the search words provided in the url in the text
+ */
+ highlightSearchWords : function() {
+ var params = $.getQueryParameters();
+ var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
+ if (terms.length) {
+ var body = $('div.body');
+ window.setTimeout(function() {
+ $.each(terms, function() {
+ body.highlightText(this.toLowerCase(), 'highlight');
+ });
+ }, 10);
+ $('<li class="highlight-link"><a href="javascript:Documentation.' +
+ 'hideSearchWords()">' + _('Hide Search Matches') + '</a></li>')
+ .appendTo($('.sidebar .this-page-menu'));
+ }
+ },
+
+ /**
+ * init the modindex toggle buttons
+ */
+ initModIndex : function() {
+ var togglers = $('img.toggler').click(function() {
+ var src = $(this).attr('src');
+ var idnum = $(this).attr('id').substr(7);
+ console.log($('tr.cg-' + idnum).toggle());
+ if (src.substr(-9) == 'minus.png')
+ $(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
+ else
+ $(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
+ }).css('display', '');
+ if (DOCUMENTATION_OPTIONS.COLLAPSE_MODINDEX) {
+ togglers.click();
+ }
+ },
+
+ /**
+ * helper function to hide the search marks again
+ */
+ hideSearchWords : function() {
+ $('.sidebar .this-page-menu li.highlight-link').fadeOut(300);
+ $('span.highlight').removeClass('highlight');
+ },
+
+ /**
+ * make the url absolute
+ */
+ makeURL : function(relativeURL) {
+ return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
+ },
+
+ /**
+ * get the current relative url
+ */
+ getCurrentURL : function() {
+ var path = document.location.pathname;
+ var parts = path.split(/\//);
+ $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
+ if (this == '..')
+ parts.pop();
+ });
+ var url = parts.join('/');
+ return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
+ }
+};
+
+// quick alias for translations
+_ = Documentation.gettext;
+
+$(document).ready(function() {
+ Documentation.init();
+});
diff --git a/doc/html/_static/file.png b/doc/html/_static/file.png
new file mode 100644
index 0000000..d18082e
--- /dev/null
+++ b/doc/html/_static/file.png
Binary files differ
diff --git a/doc/html/_static/jquery.js b/doc/html/_static/jquery.js
new file mode 100644
index 0000000..9263574
--- /dev/null
+++ b/doc/html/_static/jquery.js
@@ -0,0 +1,4376 @@
+/*!
+ * jQuery JavaScript Library v1.3.2
+ * http://jquery.com/
+ *
+ * Copyright (c) 2009 John Resig
+ * Dual licensed under the MIT and GPL licenses.
+ * http://docs.jquery.com/License
+ *
+ * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
+ * Revision: 6246
+ */
+(function(){
+
+var
+ // Will speed up references to window, and allows munging its name.
+ window = this,
+ // Will speed up references to undefined, and allows munging its name.
+ undefined,
+ // Map over jQuery in case of overwrite
+ _jQuery = window.jQuery,
+ // Map over the $ in case of overwrite
+ _$ = window.$,
+
+ jQuery = window.jQuery = window.$ = function( selector, context ) {
+ // The jQuery object is actually just the init constructor 'enhanced'
+ return new jQuery.fn.init( selector, context );
+ },
+
+ // A simple way to check for HTML strings or ID strings
+ // (both of which we optimize for)
+ quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,
+ // Is it a simple selector
+ isSimple = /^.[^:#\[\.,]*$/;
+
+jQuery.fn = jQuery.prototype = {
+ init: function( selector, context ) {
+ // Make sure that a selection was provided
+ selector = selector || document;
+
+ // Handle $(DOMElement)
+ if ( selector.nodeType ) {
+ this[0] = selector;
+ this.length = 1;
+ this.context = selector;
+ return this;
+ }
+ // Handle HTML strings
+ if ( typeof selector === "string" ) {
+ // Are we dealing with HTML string or an ID?
+ var match = quickExpr.exec( selector );
+
+ // Verify a match, and that no context was specified for #id
+ if ( match && (match[1] || !context) ) {
+
+ // HANDLE: $(html) -> $(array)
+ if ( match[1] )
+ selector = jQuery.clean( [ match[1] ], context );
+
+ // HANDLE: $("#id")
+ else {
+ var elem = document.getElementById( match[3] );
+
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( elem && elem.id != match[3] )
+ return jQuery().find( selector );
+
+ // Otherwise, we inject the element directly into the jQuery object
+ var ret = jQuery( elem || [] );
+ ret.context = document;
+ ret.selector = selector;
+ return ret;
+ }
+
+ // HANDLE: $(expr, [context])
+ // (which is just equivalent to: $(content).find(expr)
+ } else
+ return jQuery( context ).find( selector );
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction( selector ) )
+ return jQuery( document ).ready( selector );
+
+ // Make sure that old selector state is passed along
+ if ( selector.selector && selector.context ) {
+ this.selector = selector.selector;
+ this.context = selector.context;
+ }
+
+ return this.setArray(jQuery.isArray( selector ) ?
+ selector :
+ jQuery.makeArray(selector));
+ },
+
+ // Start with an empty selector
+ selector: "",
+
+ // The current version of jQuery being used
+ jquery: "1.3.2",
+
+ // The number of elements contained in the matched element set
+ size: function() {
+ return this.length;
+ },
+
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
+ get: function( num ) {
+ return num === undefined ?
+
+ // Return a 'clean' array
+ Array.prototype.slice.call( this ) :
+
+ // Return just the object
+ this[ num ];
+ },
+
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack: function( elems, name, selector ) {
+ // Build a new jQuery matched element set
+ var ret = jQuery( elems );
+
+ // Add the old object onto the stack (as a reference)
+ ret.prevObject = this;
+
+ ret.context = this.context;
+
+ if ( name === "find" )
+ ret.selector = this.selector + (this.selector ? " " : "") + selector;
+ else if ( name )
+ ret.selector = this.selector + "." + name + "(" + selector + ")";
+
+ // Return the newly-formed element set
+ return ret;
+ },
+
+ // Force the current matched set of elements to become
+ // the specified array of elements (destroying the stack in the process)
+ // You should use pushStack() in order to do this, but maintain the stack
+ setArray: function( elems ) {
+ // Resetting the length to 0, then using the native Array push
+ // is a super-fast way to populate an object with array-like properties
+ this.length = 0;
+ Array.prototype.push.apply( this, elems );
+
+ return this;
+ },
+
+ // Execute a callback for every element in the matched set.
+ // (You can seed the arguments with an array of args, but this is
+ // only used internally.)
+ each: function( callback, args ) {
+ return jQuery.each( this, callback, args );
+ },
+
+ // Determine the position of an element within
+ // the matched set of elements
+ index: function( elem ) {
+ // Locate the position of the desired element
+ return jQuery.inArray(
+ // If it receives a jQuery object, the first element is used
+ elem && elem.jquery ? elem[0] : elem
+ , this );
+ },
+
+ attr: function( name, value, type ) {
+ var options = name;
+
+ // Look for the case where we're accessing a style value
+ if ( typeof name === "string" )
+ if ( value === undefined )
+ return this[0] && jQuery[ type || "attr" ]( this[0], name );
+
+ else {
+ options = {};
+ options[ name ] = value;
+ }
+
+ // Check to see if we're setting style values
+ return this.each(function(i){
+ // Set all the styles
+ for ( name in options )
+ jQuery.attr(
+ type ?
+ this.style :
+ this,
+ name, jQuery.prop( this, options[ name ], type, i, name )
+ );
+ });
+ },
+
+ css: function( key, value ) {
+ // ignore negative width and height values
+ if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
+ value = undefined;
+ return this.attr( key, value, "curCSS" );
+ },
+
+ text: function( text ) {
+ if ( typeof text !== "object" && text != null )
+ return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
+
+ var ret = "";
+
+ jQuery.each( text || this, function(){
+ jQuery.each( this.childNodes, function(){
+ if ( this.nodeType != 8 )
+ ret += this.nodeType != 1 ?
+ this.nodeValue :
+ jQuery.fn.text( [ this ] );
+ });
+ });
+
+ return ret;
+ },
+
+ wrapAll: function( html ) {
+ if ( this[0] ) {
+ // The elements to wrap the target around
+ var wrap = jQuery( html, this[0].ownerDocument ).clone();
+
+ if ( this[0].parentNode )
+ wrap.insertBefore( this[0] );
+
+ wrap.map(function(){
+ var elem = this;
+
+ while ( elem.firstChild )
+ elem = elem.firstChild;
+
+ return elem;
+ }).append(this);
+ }
+
+ return this;
+ },
+
+ wrapInner: function( html ) {
+ return this.each(function(){
+ jQuery( this ).contents().wrapAll( html );
+ });
+ },
+
+ wrap: function( html ) {
+ return this.each(function(){
+ jQuery( this ).wrapAll( html );
+ });
+ },
+
+ append: function() {
+ return this.domManip(arguments, true, function(elem){
+ if (this.nodeType == 1)
+ this.appendChild( elem );
+ });
+ },
+
+ prepend: function() {
+ return this.domManip(arguments, true, function(elem){
+ if (this.nodeType == 1)
+ this.insertBefore( elem, this.firstChild );
+ });
+ },
+
+ before: function() {
+ return this.domManip(arguments, false, function(elem){
+ this.parentNode.insertBefore( elem, this );
+ });
+ },
+
+ after: function() {
+ return this.domManip(arguments, false, function(elem){
+ this.parentNode.insertBefore( elem, this.nextSibling );
+ });
+ },
+
+ end: function() {
+ return this.prevObject || jQuery( [] );
+ },
+
+ // For internal use only.
+ // Behaves like an Array's method, not like a jQuery method.
+ push: [].push,
+ sort: [].sort,
+ splice: [].splice,
+
+ find: function( selector ) {
+ if ( this.length === 1 ) {
+ var ret = this.pushStack( [], "find", selector );
+ ret.length = 0;
+ jQuery.find( selector, this[0], ret );
+ return ret;
+ } else {
+ return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){
+ return jQuery.find( selector, elem );
+ })), "find", selector );
+ }
+ },
+
+ clone: function( events ) {
+ // Do the clone
+ var ret = this.map(function(){
+ if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
+ // IE copies events bound via attachEvent when
+ // using cloneNode. Calling detachEvent on the
+ // clone will also remove the events from the orignal
+ // In order to get around this, we use innerHTML.
+ // Unfortunately, this means some modifications to
+ // attributes in IE that are actually only stored
+ // as properties will not be copied (such as the
+ // the name attribute on an input).
+ var html = this.outerHTML;
+ if ( !html ) {
+ var div = this.ownerDocument.createElement("div");
+ div.appendChild( this.cloneNode(true) );
+ html = div.innerHTML;
+ }
+
+ return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0];
+ } else
+ return this.cloneNode(true);
+ });
+
+ // Copy the events from the original to the clone
+ if ( events === true ) {
+ var orig = this.find("*").andSelf(), i = 0;
+
+ ret.find("*").andSelf().each(function(){
+ if ( this.nodeName !== orig[i].nodeName )
+ return;
+
+ var events = jQuery.data( orig[i], "events" );
+
+ for ( var type in events ) {
+ for ( var handler in events[ type ] ) {
+ jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
+ }
+ }
+
+ i++;
+ });
+ }
+
+ // Return the cloned set
+ return ret;
+ },
+
+ filter: function( selector ) {
+ return this.pushStack(
+ jQuery.isFunction( selector ) &&
+ jQuery.grep(this, function(elem, i){
+ return selector.call( elem, i );
+ }) ||
+
+ jQuery.multiFilter( selector, jQuery.grep(this, function(elem){
+ return elem.nodeType === 1;
+ }) ), "filter", selector );
+ },
+
+ closest: function( selector ) {
+ var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null,
+ closer = 0;
+
+ return this.map(function(){
+ var cur = this;
+ while ( cur && cur.ownerDocument ) {
+ if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) {
+ jQuery.data(cur, "closest", closer);
+ return cur;
+ }
+ cur = cur.parentNode;
+ closer++;
+ }
+ });
+ },
+
+ not: function( selector ) {
+ if ( typeof selector === "string" )
+ // test special case where just one selector is passed in
+ if ( isSimple.test( selector ) )
+ return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector );
+ else
+ selector = jQuery.multiFilter( selector, this );
+
+ var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
+ return this.filter(function() {
+ return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
+ });
+ },
+
+ add: function( selector ) {
+ return this.pushStack( jQuery.unique( jQuery.merge(
+ this.get(),
+ typeof selector === "string" ?
+ jQuery( selector ) :
+ jQuery.makeArray( selector )
+ )));
+ },
+
+ is: function( selector ) {
+ return !!selector && jQuery.multiFilter( selector, this ).length > 0;
+ },
+
+ hasClass: function( selector ) {
+ return !!selector && this.is( "." + selector );
+ },
+
+ val: function( value ) {
+ if ( value === undefined ) {
+ var elem = this[0];
+
+ if ( elem ) {
+ if( jQuery.nodeName( elem, 'option' ) )
+ return (elem.attributes.value || {}).specified ? elem.value : elem.text;
+
+ // We need to handle select boxes special
+ if ( jQuery.nodeName( elem, "select" ) ) {
+ var index = elem.selectedIndex,
+ values = [],
+ options = elem.options,
+ one = elem.type == "select-one";
+
+ // Nothing was selected
+ if ( index < 0 )
+ return null;
+
+ // Loop through all the selected options
+ for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+ var option = options[ i ];
+
+ if ( option.selected ) {
+ // Get the specifc value for the option
+ value = jQuery(option).val();
+
+ // We don't need an array for one selects
+ if ( one )
+ return value;
+
+ // Multi-Selects return an array
+ values.push( value );
+ }
+ }
+
+ return values;
+ }
+
+ // Everything else, we just grab the value
+ return (elem.value || "").replace(/\r/g, "");
+
+ }
+
+ return undefined;
+ }
+
+ if ( typeof value === "number" )
+ value += '';
+
+ return this.each(function(){
+ if ( this.nodeType != 1 )
+ return;
+
+ if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) )
+ this.checked = (jQuery.inArray(this.value, value) >= 0 ||
+ jQuery.inArray(this.name, value) >= 0);
+
+ else if ( jQuery.nodeName( this, "select" ) ) {
+ var values = jQuery.makeArray(value);
+
+ jQuery( "option", this ).each(function(){
+ this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
+ jQuery.inArray( this.text, values ) >= 0);
+ });
+
+ if ( !values.length )
+ this.selectedIndex = -1;
+
+ } else
+ this.value = value;
+ });
+ },
+
+ html: function( value ) {
+ return value === undefined ?
+ (this[0] ?
+ this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") :
+ null) :
+ this.empty().append( value );
+ },
+
+ replaceWith: function( value ) {
+ return this.after( value ).remove();
+ },
+
+ eq: function( i ) {
+ return this.slice( i, +i + 1 );
+ },
+
+ slice: function() {
+ return this.pushStack( Array.prototype.slice.apply( this, arguments ),
+ "slice", Array.prototype.slice.call(arguments).join(",") );
+ },
+
+ map: function( callback ) {
+ return this.pushStack( jQuery.map(this, function(elem, i){
+ return callback.call( elem, i, elem );
+ }));
+ },
+
+ andSelf: function() {
+ return this.add( this.prevObject );
+ },
+
+ domManip: function( args, table, callback ) {
+ if ( this[0] ) {
+ var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
+ scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
+ first = fragment.firstChild;
+
+ if ( first )
+ for ( var i = 0, l = this.length; i < l; i++ )
+ callback.call( root(this[i], first), this.length > 1 || i > 0 ?
+ fragment.cloneNode(true) : fragment );
+
+ if ( scripts )
+ jQuery.each( scripts, evalScript );
+ }
+
+ return this;
+
+ function root( elem, cur ) {
+ return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
+ (elem.getElementsByTagName("tbody")[0] ||
+ elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
+ elem;
+ }
+ }
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+function evalScript( i, elem ) {
+ if ( elem.src )
+ jQuery.ajax({
+ url: elem.src,
+ async: false,
+ dataType: "script"
+ });
+
+ else
+ jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+
+ if ( elem.parentNode )
+ elem.parentNode.removeChild( elem );
+}
+
+function now(){
+ return +new Date;
+}
+
+jQuery.extend = jQuery.fn.extend = function() {
+ // copy reference to target object
+ var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
+
+ // Handle a deep copy situation
+ if ( typeof target === "boolean" ) {
+ deep = target;
+ target = arguments[1] || {};
+ // skip the boolean and the target
+ i = 2;
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target !== "object" && !jQuery.isFunction(target) )
+ target = {};
+
+ // extend jQuery itself if only one argument is passed
+ if ( length == i ) {
+ target = this;
+ --i;
+ }
+
+ for ( ; i < length; i++ )
+ // Only deal with non-null/undefined values
+ if ( (options = arguments[ i ]) != null )
+ // Extend the base object
+ for ( var name in options ) {
+ var src = target[ name ], copy = options[ name ];
+
+ // Prevent never-ending loop
+ if ( target === copy )
+ continue;
+
+ // Recurse if we're merging object values
+ if ( deep && copy && typeof copy === "object" && !copy.nodeType )
+ target[ name ] = jQuery.extend( deep,
+ // Never move original objects, clone them
+ src || ( copy.length != null ? [ ] : { } )
+ , copy );
+
+ // Don't bring in undefined values
+ else if ( copy !== undefined )
+ target[ name ] = copy;
+
+ }
+
+ // Return the modified object
+ return target;
+};
+
+// exclude the following css properties to add px
+var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
+ // cache defaultView
+ defaultView = document.defaultView || {},
+ toString = Object.prototype.toString;
+
+jQuery.extend({
+ noConflict: function( deep ) {
+ window.$ = _$;
+
+ if ( deep )
+ window.jQuery = _jQuery;
+
+ return jQuery;
+ },
+
+ // See test/unit/core.js for details concerning isFunction.
+ // Since version 1.3, DOM methods and functions like alert
+ // aren't supported. They return false on IE (#2968).
+ isFunction: function( obj ) {
+ return toString.call(obj) === "[object Function]";
+ },
+
+ isArray: function( obj ) {
+ return toString.call(obj) === "[object Array]";
+ },
+
+ // check if an element is in a (or is an) XML document
+ isXMLDoc: function( elem ) {
+ return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
+ !!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument );
+ },
+
+ // Evalulates a script in a global context
+ globalEval: function( data ) {
+ if ( data && /\S/.test(data) ) {
+ // Inspired by code by Andrea Giammarchi
+ // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
+ var head = document.getElementsByTagName("head")[0] || document.documentElement,
+ script = document.createElement("script");
+
+ script.type = "text/javascript";
+ if ( jQuery.support.scriptEval )
+ script.appendChild( document.createTextNode( data ) );
+ else
+ script.text = data;
+
+ // Use insertBefore instead of appendChild to circumvent an IE6 bug.
+ // This arises when a base node is used (#2709).
+ head.insertBefore( script, head.firstChild );
+ head.removeChild( script );
+ }
+ },
+
+ nodeName: function( elem, name ) {
+ return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
+ },
+
+ // args is for internal usage only
+ each: function( object, callback, args ) {
+ var name, i = 0, length = object.length;
+
+ if ( args ) {
+ if ( length === undefined ) {
+ for ( name in object )
+ if ( callback.apply( object[ name ], args ) === false )
+ break;
+ } else
+ for ( ; i < length; )
+ if ( callback.apply( object[ i++ ], args ) === false )
+ break;
+
+ // A special, fast, case for the most common use of each
+ } else {
+ if ( length === undefined ) {
+ for ( name in object )
+ if ( callback.call( object[ name ], name, object[ name ] ) === false )
+ break;
+ } else
+ for ( var value = object[0];
+ i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
+ }
+
+ return object;
+ },
+
+ prop: function( elem, value, type, i, name ) {
+ // Handle executable functions
+ if ( jQuery.isFunction( value ) )
+ value = value.call( elem, i );
+
+ // Handle passing in a number to a CSS property
+ return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ?
+ value + "px" :
+ value;
+ },
+
+ className: {
+ // internal only, use addClass("class")
+ add: function( elem, classNames ) {
+ jQuery.each((classNames || "").split(/\s+/), function(i, className){
+ if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
+ elem.className += (elem.className ? " " : "") + className;
+ });
+ },
+
+ // internal only, use removeClass("class")
+ remove: function( elem, classNames ) {
+ if (elem.nodeType == 1)
+ elem.className = classNames !== undefined ?
+ jQuery.grep(elem.className.split(/\s+/), function(className){
+ return !jQuery.className.has( classNames, className );
+ }).join(" ") :
+ "";
+ },
+
+ // internal only, use hasClass("class")
+ has: function( elem, className ) {
+ return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
+ }
+ },
+
+ // A method for quickly swapping in/out CSS properties to get correct calculations
+ swap: function( elem, options, callback ) {
+ var old = {};
+ // Remember the old values, and insert the new ones
+ for ( var name in options ) {
+ old[ name ] = elem.style[ name ];
+ elem.style[ name ] = options[ name ];
+ }
+
+ callback.call( elem );
+
+ // Revert the old values
+ for ( var name in options )
+ elem.style[ name ] = old[ name ];
+ },
+
+ css: function( elem, name, force, extra ) {
+ if ( name == "width" || name == "height" ) {
+ var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
+
+ function getWH() {
+ val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
+
+ if ( extra === "border" )
+ return;
+
+ jQuery.each( which, function() {
+ if ( !extra )
+ val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
+ if ( extra === "margin" )
+ val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
+ else
+ val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
+ });
+ }
+
+ if ( elem.offsetWidth !== 0 )
+ getWH();
+ else
+ jQuery.swap( elem, props, getWH );
+
+ return Math.max(0, Math.round(val));
+ }
+
+ return jQuery.curCSS( elem, name, force );
+ },
+
+ curCSS: function( elem, name, force ) {
+ var ret, style = elem.style;
+
+ // We need to handle opacity special in IE
+ if ( name == "opacity" && !jQuery.support.opacity ) {
+ ret = jQuery.attr( style, "opacity" );
+
+ return ret == "" ?
+ "1" :
+ ret;
+ }
+
+ // Make sure we're using the right name for getting the float value
+ if ( name.match( /float/i ) )
+ name = styleFloat;
+
+ if ( !force && style && style[ name ] )
+ ret = style[ name ];
+
+ else if ( defaultView.getComputedStyle ) {
+
+ // Only "float" is needed here
+ if ( name.match( /float/i ) )
+ name = "float";
+
+ name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
+
+ var computedStyle = defaultView.getComputedStyle( elem, null );
+
+ if ( computedStyle )
+ ret = computedStyle.getPropertyValue( name );
+
+ // We should always get a number back from opacity
+ if ( name == "opacity" && ret == "" )
+ ret = "1";
+
+ } else if ( elem.currentStyle ) {
+ var camelCase = name.replace(/\-(\w)/g, function(all, letter){
+ return letter.toUpperCase();
+ });
+
+ ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
+
+ // From the awesome hack by Dean Edwards
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+ // If we're not dealing with a regular pixel number
+ // but a number that has a weird ending, we need to convert it to pixels
+ if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
+ // Remember the original values
+ var left = style.left, rsLeft = elem.runtimeStyle.left;
+
+ // Put in the new values to get a computed value out
+ elem.runtimeStyle.left = elem.currentStyle.left;
+ style.left = ret || 0;
+ ret = style.pixelLeft + "px";
+
+ // Revert the changed values
+ style.left = left;
+ elem.runtimeStyle.left = rsLeft;
+ }
+ }
+
+ return ret;
+ },
+
+ clean: function( elems, context, fragment ) {
+ context = context || document;
+
+ // !context.createElement fails in IE with an error but returns typeof 'object'
+ if ( typeof context.createElement === "undefined" )
+ context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
+
+ // If a single string is passed in and it's a single tag
+ // just do a createElement and skip the rest
+ if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
+ var match = /^<(\w+)\s*\/?>$/.exec(elems[0]);
+ if ( match )
+ return [ context.createElement( match[1] ) ];
+ }
+
+ var ret = [], scripts = [], div = context.createElement("div");
+
+ jQuery.each(elems, function(i, elem){
+ if ( typeof elem === "number" )
+ elem += '';
+
+ if ( !elem )
+ return;
+
+ // Convert html string into DOM nodes
+ if ( typeof elem === "string" ) {
+ // Fix "XHTML"-style tags in all browsers
+ elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
+ return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
+ all :
+ front + "></" + tag + ">";
+ });
+
+ // Trim whitespace, otherwise indexOf won't work as expected
+ var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase();
+
+ var wrap =
+ // option or optgroup
+ !tags.indexOf("<opt") &&
+ [ 1, "<select multiple='multiple'>", "</select>" ] ||
+
+ !tags.indexOf("<leg") &&
+ [ 1, "<fieldset>", "</fieldset>" ] ||
+
+ tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
+ [ 1, "<table>", "</table>" ] ||
+
+ !tags.indexOf("<tr") &&
+ [ 2, "<table><tbody>", "</tbody></table>" ] ||
+
+ // <thead> matched above
+ (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
+ [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
+
+ !tags.indexOf("<col") &&
+ [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
+
+ // IE can't serialize <link> and <script> tags normally
+ !jQuery.support.htmlSerialize &&
+ [ 1, "div<div>", "</div>" ] ||
+
+ [ 0, "", "" ];
+
+ // Go to html and back, then peel off extra wrappers
+ div.innerHTML = wrap[1] + elem + wrap[2];
+
+ // Move to the right depth
+ while ( wrap[0]-- )
+ div = div.lastChild;
+
+ // Remove IE's autoinserted <tbody> from table fragments
+ if ( !jQuery.support.tbody ) {
+
+ // String was a <table>, *may* have spurious <tbody>
+ var hasBody = /<tbody/i.test(elem),
+ tbody = !tags.indexOf("<table") && !hasBody ?
+ div.firstChild && div.firstChild.childNodes :
+
+ // String was a bare <thead> or <tfoot>
+ wrap[1] == "<table>" && !hasBody ?
+ div.childNodes :
+ [];
+
+ for ( var j = tbody.length - 1; j >= 0 ; --j )
+ if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
+ tbody[ j ].parentNode.removeChild( tbody[ j ] );
+
+ }
+
+ // IE completely kills leading whitespace when innerHTML is used
+ if ( !jQuery.support.leadingWhitespace && /^\s/.test( elem ) )
+ div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
+
+ elem = jQuery.makeArray( div.childNodes );
+ }
+
+ if ( elem.nodeType )
+ ret.push( elem );
+ else
+ ret = jQuery.merge( ret, elem );
+
+ });
+
+ if ( fragment ) {
+ for ( var i = 0; ret[i]; i++ ) {
+ if ( jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
+ scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
+ } else {
+ if ( ret[i].nodeType === 1 )
+ ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
+ fragment.appendChild( ret[i] );
+ }
+ }
+
+ return scripts;
+ }
+
+ return ret;
+ },
+
+ attr: function( elem, name, value ) {
+ // don't set attributes on text and comment nodes
+ if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
+ return undefined;
+
+ var notxml = !jQuery.isXMLDoc( elem ),
+ // Whether we are setting (or getting)
+ set = value !== undefined;
+
+ // Try to normalize/fix the name
+ name = notxml && jQuery.props[ name ] || name;
+
+ // Only do all the following if this is a node (faster for style)
+ // IE elem.getAttribute passes even for style
+ if ( elem.tagName ) {
+
+ // These attributes require special treatment
+ var special = /href|src|style/.test( name );
+
+ // Safari mis-reports the default selected property of a hidden option
+ // Accessing the parent's selectedIndex property fixes it
+ if ( name == "selected" && elem.parentNode )
+ elem.parentNode.selectedIndex;
+
+ // If applicable, access the attribute via the DOM 0 way
+ if ( name in elem && notxml && !special ) {
+ if ( set ){
+ // We can't allow the type property to be changed (since it causes problems in IE)
+ if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
+ throw "type property can't be changed";
+
+ elem[ name ] = value;
+ }
+
+ // browsers index elements by id/name on forms, give priority to attributes.
+ if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
+ return elem.getAttributeNode( name ).nodeValue;
+
+ // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+ if ( name == "tabIndex" ) {
+ var attributeNode = elem.getAttributeNode( "tabIndex" );
+ return attributeNode && attributeNode.specified
+ ? attributeNode.value
+ : elem.nodeName.match(/(button|input|object|select|textarea)/i)
+ ? 0
+ : elem.nodeName.match(/^(a|area)$/i) && elem.href
+ ? 0
+ : undefined;
+ }
+
+ return elem[ name ];
+ }
+
+ if ( !jQuery.support.style && notxml && name == "style" )
+ return jQuery.attr( elem.style, "cssText", value );
+
+ if ( set )
+ // convert the value to a string (all browsers do this but IE) see #1070
+ elem.setAttribute( name, "" + value );
+
+ var attr = !jQuery.support.hrefNormalized && notxml && special
+ // Some attributes require a special call on IE
+ ? elem.getAttribute( name, 2 )
+ : elem.getAttribute( name );
+
+ // Non-existent attributes return null, we normalize to undefined
+ return attr === null ? undefined : attr;
+ }
+
+ // elem is actually elem.style ... set the style
+
+ // IE uses filters for opacity
+ if ( !jQuery.support.opacity && name == "opacity" ) {
+ if ( set ) {
+ // IE has trouble with opacity if it does not have layout
+ // Force it by setting the zoom level
+ elem.zoom = 1;
+
+ // Set the alpha filter to set the opacity
+ elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
+ (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
+ }
+
+ return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
+ (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
+ "";
+ }
+
+ name = name.replace(/-([a-z])/ig, function(all, letter){
+ return letter.toUpperCase();
+ });
+
+ if ( set )
+ elem[ name ] = value;
+
+ return elem[ name ];
+ },
+
+ trim: function( text ) {
+ return (text || "").replace( /^\s+|\s+$/g, "" );
+ },
+
+ makeArray: function( array ) {
+ var ret = [];
+
+ if( array != null ){
+ var i = array.length;
+ // The window, strings (and functions) also have 'length'
+ if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval )
+ ret[0] = array;
+ else
+ while( i )
+ ret[--i] = array[i];
+ }
+
+ return ret;
+ },
+
+ inArray: function( elem, array ) {
+ for ( var i = 0, length = array.length; i < length; i++ )
+ // Use === because on IE, window == document
+ if ( array[ i ] === elem )
+ return i;
+
+ return -1;
+ },
+
+ merge: function( first, second ) {
+ // We have to loop this way because IE & Opera overwrite the length
+ // expando of getElementsByTagName
+ var i = 0, elem, pos = first.length;
+ // Also, we need to make sure that the correct elements are being returned
+ // (IE returns comment nodes in a '*' query)
+ if ( !jQuery.support.getAll ) {
+ while ( (elem = second[ i++ ]) != null )
+ if ( elem.nodeType != 8 )
+ first[ pos++ ] = elem;
+
+ } else
+ while ( (elem = second[ i++ ]) != null )
+ first[ pos++ ] = elem;
+
+ return first;
+ },
+
+ unique: function( array ) {
+ var ret = [], done = {};
+
+ try {
+
+ for ( var i = 0, length = array.length; i < length; i++ ) {
+ var id = jQuery.data( array[ i ] );
+
+ if ( !done[ id ] ) {
+ done[ id ] = true;
+ ret.push( array[ i ] );
+ }
+ }
+
+ } catch( e ) {
+ ret = array;
+ }
+
+ return ret;
+ },
+
+ grep: function( elems, callback, inv ) {
+ var ret = [];
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( var i = 0, length = elems.length; i < length; i++ )
+ if ( !inv != !callback( elems[ i ], i ) )
+ ret.push( elems[ i ] );
+
+ return ret;
+ },
+
+ map: function( elems, callback ) {
+ var ret = [];
+
+ // Go through the array, translating each of the items to their
+ // new value (or values).
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
+ var value = callback( elems[ i ], i );
+
+ if ( value != null )
+ ret[ ret.length ] = value;
+ }
+
+ return ret.concat.apply( [], ret );
+ }
+});
+
+// Use of jQuery.browser is deprecated.
+// It's included for backwards compatibility and plugins,
+// although they should work to migrate away.
+
+var userAgent = navigator.userAgent.toLowerCase();
+
+// Figure out what browser is being used
+jQuery.browser = {
+ version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
+ safari: /webkit/.test( userAgent ),
+ opera: /opera/.test( userAgent ),
+ msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
+ mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
+};
+
+jQuery.each({
+ parent: function(elem){return elem.parentNode;},
+ parents: function(elem){return jQuery.dir(elem,"parentNode");},
+ next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
+ prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
+ nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
+ prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
+ siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
+ children: function(elem){return jQuery.sibling(elem.firstChild);},
+ contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
+}, function(name, fn){
+ jQuery.fn[ name ] = function( selector ) {
+ var ret = jQuery.map( this, fn );
+
+ if ( selector && typeof selector == "string" )
+ ret = jQuery.multiFilter( selector, ret );
+
+ return this.pushStack( jQuery.unique( ret ), name, selector );
+ };
+});
+
+jQuery.each({
+ appendTo: "append",
+ prependTo: "prepend",
+ insertBefore: "before",
+ insertAfter: "after",
+ replaceAll: "replaceWith"
+}, function(name, original){
+ jQuery.fn[ name ] = function( selector ) {
+ var ret = [], insert = jQuery( selector );
+
+ for ( var i = 0, l = insert.length; i < l; i++ ) {
+ var elems = (i > 0 ? this.clone(true) : this).get();
+ jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
+ ret = ret.concat( elems );
+ }
+
+ return this.pushStack( ret, name, selector );
+ };
+});
+
+jQuery.each({
+ removeAttr: function( name ) {
+ jQuery.attr( this, name, "" );
+ if (this.nodeType == 1)
+ this.removeAttribute( name );
+ },
+
+ addClass: function( classNames ) {
+ jQuery.className.add( this, classNames );
+ },
+
+ removeClass: function( classNames ) {
+ jQuery.className.remove( this, classNames );
+ },
+
+ toggleClass: function( classNames, state ) {
+ if( typeof state !== "boolean" )
+ state = !jQuery.className.has( this, classNames );
+ jQuery.className[ state ? "add" : "remove" ]( this, classNames );
+ },
+
+ remove: function( selector ) {
+ if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
+ // Prevent memory leaks
+ jQuery( "*", this ).add([this]).each(function(){
+ jQuery.event.remove(this);
+ jQuery.removeData(this);
+ });
+ if (this.parentNode)
+ this.parentNode.removeChild( this );
+ }
+ },
+
+ empty: function() {
+ // Remove element nodes and prevent memory leaks
+ jQuery(this).children().remove();
+
+ // Remove any remaining nodes
+ while ( this.firstChild )
+ this.removeChild( this.firstChild );
+ }
+}, function(name, fn){
+ jQuery.fn[ name ] = function(){
+ return this.each( fn, arguments );
+ };
+});
+
+// Helper function used by the dimensions and offset modules
+function num(elem, prop) {
+ return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
+}
+var expando = "jQuery" + now(), uuid = 0, windowData = {};
+
+jQuery.extend({
+ cache: {},
+
+ data: function( elem, name, data ) {
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var id = elem[ expando ];
+
+ // Compute a unique ID for the element
+ if ( !id )
+ id = elem[ expando ] = ++uuid;
+
+ // Only generate the data cache if we're
+ // trying to access or manipulate it
+ if ( name && !jQuery.cache[ id ] )
+ jQuery.cache[ id ] = {};
+
+ // Prevent overriding the named cache with undefined values
+ if ( data !== undefined )
+ jQuery.cache[ id ][ name ] = data;
+
+ // Return the named cache data, or the ID for the element
+ return name ?
+ jQuery.cache[ id ][ name ] :
+ id;
+ },
+
+ removeData: function( elem, name ) {
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var id = elem[ expando ];
+
+ // If we want to remove a specific section of the element's data
+ if ( name ) {
+ if ( jQuery.cache[ id ] ) {
+ // Remove the section of cache data
+ delete jQuery.cache[ id ][ name ];
+
+ // If we've removed all the data, remove the element's cache
+ name = "";
+
+ for ( name in jQuery.cache[ id ] )
+ break;
+
+ if ( !name )
+ jQuery.removeData( elem );
+ }
+
+ // Otherwise, we want to remove all of the element's data
+ } else {
+ // Clean up the element expando
+ try {
+ delete elem[ expando ];
+ } catch(e){
+ // IE has trouble directly removing the expando
+ // but it's ok with using removeAttribute
+ if ( elem.removeAttribute )
+ elem.removeAttribute( expando );
+ }
+
+ // Completely remove the data cache
+ delete jQuery.cache[ id ];
+ }
+ },
+ queue: function( elem, type, data ) {
+ if ( elem ){
+
+ type = (type || "fx") + "queue";
+
+ var q = jQuery.data( elem, type );
+
+ if ( !q || jQuery.isArray(data) )
+ q = jQuery.data( elem, type, jQuery.makeArray(data) );
+ else if( data )
+ q.push( data );
+
+ }
+ return q;
+ },
+
+ dequeue: function( elem, type ){
+ var queue = jQuery.queue( elem, type ),
+ fn = queue.shift();
+
+ if( !type || type === "fx" )
+ fn = queue[0];
+
+ if( fn !== undefined )
+ fn.call(elem);
+ }
+});
+
+jQuery.fn.extend({
+ data: function( key, value ){
+ var parts = key.split(".");
+ parts[1] = parts[1] ? "." + parts[1] : "";
+
+ if ( value === undefined ) {
+ var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+
+ if ( data === undefined && this.length )
+ data = jQuery.data( this[0], key );
+
+ return data === undefined && parts[1] ?
+ this.data( parts[0] ) :
+ data;
+ } else
+ return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
+ jQuery.data( this, key, value );
+ });
+ },
+
+ removeData: function( key ){
+ return this.each(function(){
+ jQuery.removeData( this, key );
+ });
+ },
+ queue: function(type, data){
+ if ( typeof type !== "string" ) {
+ data = type;
+ type = "fx";
+ }
+
+ if ( data === undefined )
+ return jQuery.queue( this[0], type );
+
+ return this.each(function(){
+ var queue = jQuery.queue( this, type, data );
+
+ if( type == "fx" && queue.length == 1 )
+ queue[0].call(this);
+ });
+ },
+ dequeue: function(type){
+ return this.each(function(){
+ jQuery.dequeue( this, type );
+ });
+ }
+});/*!
+ * Sizzle CSS Selector Engine - v0.9.3
+ * Copyright 2009, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+(function(){
+
+var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,
+ done = 0,
+ toString = Object.prototype.toString;
+
+var Sizzle = function(selector, context, results, seed) {
+ results = results || [];
+ context = context || document;
+
+ if ( context.nodeType !== 1 && context.nodeType !== 9 )
+ return [];
+
+ if ( !selector || typeof selector !== "string" ) {
+ return results;
+ }
+
+ var parts = [], m, set, checkSet, check, mode, extra, prune = true;
+
+ // Reset the position of the chunker regexp (start from head)
+ chunker.lastIndex = 0;
+
+ while ( (m = chunker.exec(selector)) !== null ) {
+ parts.push( m[1] );
+
+ if ( m[2] ) {
+ extra = RegExp.rightContext;
+ break;
+ }
+ }
+
+ if ( parts.length > 1 && origPOS.exec( selector ) ) {
+ if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
+ set = posProcess( parts[0] + parts[1], context );
+ } else {
+ set = Expr.relative[ parts[0] ] ?
+ [ context ] :
+ Sizzle( parts.shift(), context );
+
+ while ( parts.length ) {
+ selector = parts.shift();
+
+ if ( Expr.relative[ selector ] )
+ selector += parts.shift();
+
+ set = posProcess( selector, set );
+ }
+ }
+ } else {
+ var ret = seed ?
+ { expr: parts.pop(), set: makeArray(seed) } :
+ Sizzle.find( parts.pop(), parts.length === 1 && context.parentNode ? context.parentNode : context, isXML(context) );
+ set = Sizzle.filter( ret.expr, ret.set );
+
+ if ( parts.length > 0 ) {
+ checkSet = makeArray(set);
+ } else {
+ prune = false;
+ }
+
+ while ( parts.length ) {
+ var cur = parts.pop(), pop = cur;
+
+ if ( !Expr.relative[ cur ] ) {
+ cur = "";
+ } else {
+ pop = parts.pop();
+ }
+
+ if ( pop == null ) {
+ pop = context;
+ }
+
+ Expr.relative[ cur ]( checkSet, pop, isXML(context) );
+ }
+ }
+
+ if ( !checkSet ) {
+ checkSet = set;
+ }
+
+ if ( !checkSet ) {
+ throw "Syntax error, unrecognized expression: " + (cur || selector);
+ }
+
+ if ( toString.call(checkSet) === "[object Array]" ) {
+ if ( !prune ) {
+ results.push.apply( results, checkSet );
+ } else if ( context.nodeType === 1 ) {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
+ results.push( set[i] );
+ }
+ }
+ } else {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+ results.push( set[i] );
+ }
+ }
+ }
+ } else {
+ makeArray( checkSet, results );
+ }
+
+ if ( extra ) {
+ Sizzle( extra, context, results, seed );
+
+ if ( sortOrder ) {
+ hasDuplicate = false;
+ results.sort(sortOrder);
+
+ if ( hasDuplicate ) {
+ for ( var i = 1; i < results.length; i++ ) {
+ if ( results[i] === results[i-1] ) {
+ results.splice(i--, 1);
+ }
+ }
+ }
+ }
+ }
+
+ return results;
+};
+
+Sizzle.matches = function(expr, set){
+ return Sizzle(expr, null, null, set);
+};
+
+Sizzle.find = function(expr, context, isXML){
+ var set, match;
+
+ if ( !expr ) {
+ return [];
+ }
+
+ for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
+ var type = Expr.order[i], match;
+
+ if ( (match = Expr.match[ type ].exec( expr )) ) {
+ var left = RegExp.leftContext;
+
+ if ( left.substr( left.length - 1 ) !== "\\" ) {
+ match[1] = (match[1] || "").replace(/\\/g, "");
+ set = Expr.find[ type ]( match, context, isXML );
+ if ( set != null ) {
+ expr = expr.replace( Expr.match[ type ], "" );
+ break;
+ }
+ }
+ }
+ }
+
+ if ( !set ) {
+ set = context.getElementsByTagName("*");
+ }
+
+ return {set: set, expr: expr};
+};
+
+Sizzle.filter = function(expr, set, inplace, not){
+ var old = expr, result = [], curLoop = set, match, anyFound,
+ isXMLFilter = set && set[0] && isXML(set[0]);
+
+ while ( expr && set.length ) {
+ for ( var type in Expr.filter ) {
+ if ( (match = Expr.match[ type ].exec( expr )) != null ) {
+ var filter = Expr.filter[ type ], found, item;
+ anyFound = false;
+
+ if ( curLoop == result ) {
+ result = [];
+ }
+
+ if ( Expr.preFilter[ type ] ) {
+ match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
+
+ if ( !match ) {
+ anyFound = found = true;
+ } else if ( match === true ) {
+ continue;
+ }
+ }
+
+ if ( match ) {
+ for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
+ if ( item ) {
+ found = filter( item, match, i, curLoop );
+ var pass = not ^ !!found;
+
+ if ( inplace && found != null ) {
+ if ( pass ) {
+ anyFound = true;
+ } else {
+ curLoop[i] = false;
+ }
+ } else if ( pass ) {
+ result.push( item );
+ anyFound = true;
+ }
+ }
+ }
+ }
+
+ if ( found !== undefined ) {
+ if ( !inplace ) {
+ curLoop = result;
+ }
+
+ expr = expr.replace( Expr.match[ type ], "" );
+
+ if ( !anyFound ) {
+ return [];
+ }
+
+ break;
+ }
+ }
+ }
+
+ // Improper expression
+ if ( expr == old ) {
+ if ( anyFound == null ) {
+ throw "Syntax error, unrecognized expression: " + expr;
+ } else {
+ break;
+ }
+ }
+
+ old = expr;
+ }
+
+ return curLoop;
+};
+
+var Expr = Sizzle.selectors = {
+ order: [ "ID", "NAME", "TAG" ],
+ match: {
+ ID: /#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
+ CLASS: /\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
+ NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,
+ ATTR: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
+ TAG: /^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,
+ CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
+ POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
+ PSEUDO: /:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
+ },
+ attrMap: {
+ "class": "className",
+ "for": "htmlFor"
+ },
+ attrHandle: {
+ href: function(elem){
+ return elem.getAttribute("href");
+ }
+ },
+ relative: {
+ "+": function(checkSet, part, isXML){
+ var isPartStr = typeof part === "string",
+ isTag = isPartStr && !/\W/.test(part),
+ isPartStrNotTag = isPartStr && !isTag;
+
+ if ( isTag && !isXML ) {
+ part = part.toUpperCase();
+ }
+
+ for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
+ if ( (elem = checkSet[i]) ) {
+ while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
+
+ checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
+ elem || false :
+ elem === part;
+ }
+ }
+
+ if ( isPartStrNotTag ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ },
+ ">": function(checkSet, part, isXML){
+ var isPartStr = typeof part === "string";
+
+ if ( isPartStr && !/\W/.test(part) ) {
+ part = isXML ? part : part.toUpperCase();
+
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ var parent = elem.parentNode;
+ checkSet[i] = parent.nodeName === part ? parent : false;
+ }
+ }
+ } else {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ checkSet[i] = isPartStr ?
+ elem.parentNode :
+ elem.parentNode === part;
+ }
+ }
+
+ if ( isPartStr ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ }
+ },
+ "": function(checkSet, part, isXML){
+ var doneName = done++, checkFn = dirCheck;
+
+ if ( !part.match(/\W/) ) {
+ var nodeCheck = part = isXML ? part : part.toUpperCase();
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
+ },
+ "~": function(checkSet, part, isXML){
+ var doneName = done++, checkFn = dirCheck;
+
+ if ( typeof part === "string" && !part.match(/\W/) ) {
+ var nodeCheck = part = isXML ? part : part.toUpperCase();
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
+ }
+ },
+ find: {
+ ID: function(match, context, isXML){
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ return m ? [m] : [];
+ }
+ },
+ NAME: function(match, context, isXML){
+ if ( typeof context.getElementsByName !== "undefined" ) {
+ var ret = [], results = context.getElementsByName(match[1]);
+
+ for ( var i = 0, l = results.length; i < l; i++ ) {
+ if ( results[i].getAttribute("name") === match[1] ) {
+ ret.push( results[i] );
+ }
+ }
+
+ return ret.length === 0 ? null : ret;
+ }
+ },
+ TAG: function(match, context){
+ return context.getElementsByTagName(match[1]);
+ }
+ },
+ preFilter: {
+ CLASS: function(match, curLoop, inplace, result, not, isXML){
+ match = " " + match[1].replace(/\\/g, "") + " ";
+
+ if ( isXML ) {
+ return match;
+ }
+
+ for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
+ if ( elem ) {
+ if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
+ if ( !inplace )
+ result.push( elem );
+ } else if ( inplace ) {
+ curLoop[i] = false;
+ }
+ }
+ }
+
+ return false;
+ },
+ ID: function(match){
+ return match[1].replace(/\\/g, "");
+ },
+ TAG: function(match, curLoop){
+ for ( var i = 0; curLoop[i] === false; i++ ){}
+ return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
+ },
+ CHILD: function(match){
+ if ( match[1] == "nth" ) {
+ // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+ var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
+ match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
+ !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
+
+ // calculate the numbers (first)n+(last) including if they are negative
+ match[2] = (test[1] + (test[2] || 1)) - 0;
+ match[3] = test[3] - 0;
+ }
+
+ // TODO: Move to normal caching system
+ match[0] = done++;
+
+ return match;
+ },
+ ATTR: function(match, curLoop, inplace, result, not, isXML){
+ var name = match[1].replace(/\\/g, "");
+
+ if ( !isXML && Expr.attrMap[name] ) {
+ match[1] = Expr.attrMap[name];
+ }
+
+ if ( match[2] === "~=" ) {
+ match[4] = " " + match[4] + " ";
+ }
+
+ return match;
+ },
+ PSEUDO: function(match, curLoop, inplace, result, not){
+ if ( match[1] === "not" ) {
+ // If we're dealing with a complex expression, or a simple one
+ if ( match[3].match(chunker).length > 1 || /^\w/.test(match[3]) ) {
+ match[3] = Sizzle(match[3], null, null, curLoop);
+ } else {
+ var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
+ if ( !inplace ) {
+ result.push.apply( result, ret );
+ }
+ return false;
+ }
+ } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
+ return true;
+ }
+
+ return match;
+ },
+ POS: function(match){
+ match.unshift( true );
+ return match;
+ }
+ },
+ filters: {
+ enabled: function(elem){
+ return elem.disabled === false && elem.type !== "hidden";
+ },
+ disabled: function(elem){
+ return elem.disabled === true;
+ },
+ checked: function(elem){
+ return elem.checked === true;
+ },
+ selected: function(elem){
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ elem.parentNode.selectedIndex;
+ return elem.selected === true;
+ },
+ parent: function(elem){
+ return !!elem.firstChild;
+ },
+ empty: function(elem){
+ return !elem.firstChild;
+ },
+ has: function(elem, i, match){
+ return !!Sizzle( match[3], elem ).length;
+ },
+ header: function(elem){
+ return /h\d/i.test( elem.nodeName );
+ },
+ text: function(elem){
+ return "text" === elem.type;
+ },
+ radio: function(elem){
+ return "radio" === elem.type;
+ },
+ checkbox: function(elem){
+ return "checkbox" === elem.type;
+ },
+ file: function(elem){
+ return "file" === elem.type;
+ },
+ password: function(elem){
+ return "password" === elem.type;
+ },
+ submit: function(elem){
+ return "submit" === elem.type;
+ },
+ image: function(elem){
+ return "image" === elem.type;
+ },
+ reset: function(elem){
+ return "reset" === elem.type;
+ },
+ button: function(elem){
+ return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
+ },
+ input: function(elem){
+ return /input|select|textarea|button/i.test(elem.nodeName);
+ }
+ },
+ setFilters: {
+ first: function(elem, i){
+ return i === 0;
+ },
+ last: function(elem, i, match, array){
+ return i === array.length - 1;
+ },
+ even: function(elem, i){
+ return i % 2 === 0;
+ },
+ odd: function(elem, i){
+ return i % 2 === 1;
+ },
+ lt: function(elem, i, match){
+ return i < match[3] - 0;
+ },
+ gt: function(elem, i, match){
+ return i > match[3] - 0;
+ },
+ nth: function(elem, i, match){
+ return match[3] - 0 == i;
+ },
+ eq: function(elem, i, match){
+ return match[3] - 0 == i;
+ }
+ },
+ filter: {
+ PSEUDO: function(elem, match, i, array){
+ var name = match[1], filter = Expr.filters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ } else if ( name === "contains" ) {
+ return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
+ } else if ( name === "not" ) {
+ var not = match[3];
+
+ for ( var i = 0, l = not.length; i < l; i++ ) {
+ if ( not[i] === elem ) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ },
+ CHILD: function(elem, match){
+ var type = match[1], node = elem;
+ switch (type) {
+ case 'only':
+ case 'first':
+ while (node = node.previousSibling) {
+ if ( node.nodeType === 1 ) return false;
+ }
+ if ( type == 'first') return true;
+ node = elem;
+ case 'last':
+ while (node = node.nextSibling) {
+ if ( node.nodeType === 1 ) return false;
+ }
+ return true;
+ case 'nth':
+ var first = match[2], last = match[3];
+
+ if ( first == 1 && last == 0 ) {
+ return true;
+ }
+
+ var doneName = match[0],
+ parent = elem.parentNode;
+
+ if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
+ var count = 0;
+ for ( node = parent.firstChild; node; node = node.nextSibling ) {
+ if ( node.nodeType === 1 ) {
+ node.nodeIndex = ++count;
+ }
+ }
+ parent.sizcache = doneName;
+ }
+
+ var diff = elem.nodeIndex - last;
+ if ( first == 0 ) {
+ return diff == 0;
+ } else {
+ return ( diff % first == 0 && diff / first >= 0 );
+ }
+ }
+ },
+ ID: function(elem, match){
+ return elem.nodeType === 1 && elem.getAttribute("id") === match;
+ },
+ TAG: function(elem, match){
+ return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
+ },
+ CLASS: function(elem, match){
+ return (" " + (elem.className || elem.getAttribute("class")) + " ")
+ .indexOf( match ) > -1;
+ },
+ ATTR: function(elem, match){
+ var name = match[1],
+ result = Expr.attrHandle[ name ] ?
+ Expr.attrHandle[ name ]( elem ) :
+ elem[ name ] != null ?
+ elem[ name ] :
+ elem.getAttribute( name ),
+ value = result + "",
+ type = match[2],
+ check = match[4];
+
+ return result == null ?
+ type === "!=" :
+ type === "=" ?
+ value === check :
+ type === "*=" ?
+ value.indexOf(check) >= 0 :
+ type === "~=" ?
+ (" " + value + " ").indexOf(check) >= 0 :
+ !check ?
+ value && result !== false :
+ type === "!=" ?
+ value != check :
+ type === "^=" ?
+ value.indexOf(check) === 0 :
+ type === "$=" ?
+ value.substr(value.length - check.length) === check :
+ type === "|=" ?
+ value === check || value.substr(0, check.length + 1) === check + "-" :
+ false;
+ },
+ POS: function(elem, match, i, array){
+ var name = match[2], filter = Expr.setFilters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ }
+ }
+ }
+};
+
+var origPOS = Expr.match.POS;
+
+for ( var type in Expr.match ) {
+ Expr.match[ type ] = RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
+}
+
+var makeArray = function(array, results) {
+ array = Array.prototype.slice.call( array );
+
+ if ( results ) {
+ results.push.apply( results, array );
+ return results;
+ }
+
+ return array;
+};
+
+// Perform a simple check to determine if the browser is capable of
+// converting a NodeList to an array using builtin methods.
+try {
+ Array.prototype.slice.call( document.documentElement.childNodes );
+
+// Provide a fallback method if it does not work
+} catch(e){
+ makeArray = function(array, results) {
+ var ret = results || [];
+
+ if ( toString.call(array) === "[object Array]" ) {
+ Array.prototype.push.apply( ret, array );
+ } else {
+ if ( typeof array.length === "number" ) {
+ for ( var i = 0, l = array.length; i < l; i++ ) {
+ ret.push( array[i] );
+ }
+ } else {
+ for ( var i = 0; array[i]; i++ ) {
+ ret.push( array[i] );
+ }
+ }
+ }
+
+ return ret;
+ };
+}
+
+var sortOrder;
+
+if ( document.documentElement.compareDocumentPosition ) {
+ sortOrder = function( a, b ) {
+ var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+} else if ( "sourceIndex" in document.documentElement ) {
+ sortOrder = function( a, b ) {
+ var ret = a.sourceIndex - b.sourceIndex;
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+} else if ( document.createRange ) {
+ sortOrder = function( a, b ) {
+ var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
+ aRange.selectNode(a);
+ aRange.collapse(true);
+ bRange.selectNode(b);
+ bRange.collapse(true);
+ var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+}
+
+// Check to see if the browser returns elements by name when
+// querying by getElementById (and provide a workaround)
+(function(){
+ // We're going to inject a fake input element with a specified name
+ var form = document.createElement("form"),
+ id = "script" + (new Date).getTime();
+ form.innerHTML = "<input name='" + id + "'/>";
+
+ // Inject it into the root element, check its status, and remove it quickly
+ var root = document.documentElement;
+ root.insertBefore( form, root.firstChild );
+
+ // The workaround has to do additional checks after a getElementById
+ // Which slows things down for other browsers (hence the branching)
+ if ( !!document.getElementById( id ) ) {
+ Expr.find.ID = function(match, context, isXML){
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
+ }
+ };
+
+ Expr.filter.ID = function(elem, match){
+ var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+ return elem.nodeType === 1 && node && node.nodeValue === match;
+ };
+ }
+
+ root.removeChild( form );
+})();
+
+(function(){
+ // Check to see if the browser returns only elements
+ // when doing getElementsByTagName("*")
+
+ // Create a fake element
+ var div = document.createElement("div");
+ div.appendChild( document.createComment("") );
+
+ // Make sure no comments are found
+ if ( div.getElementsByTagName("*").length > 0 ) {
+ Expr.find.TAG = function(match, context){
+ var results = context.getElementsByTagName(match[1]);
+
+ // Filter out possible comments
+ if ( match[1] === "*" ) {
+ var tmp = [];
+
+ for ( var i = 0; results[i]; i++ ) {
+ if ( results[i].nodeType === 1 ) {
+ tmp.push( results[i] );
+ }
+ }
+
+ results = tmp;
+ }
+
+ return results;
+ };
+ }
+
+ // Check to see if an attribute returns normalized href attributes
+ div.innerHTML = "<a href='#'></a>";
+ if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
+ div.firstChild.getAttribute("href") !== "#" ) {
+ Expr.attrHandle.href = function(elem){
+ return elem.getAttribute("href", 2);
+ };
+ }
+})();
+
+if ( document.querySelectorAll ) (function(){
+ var oldSizzle = Sizzle, div = document.createElement("div");
+ div.innerHTML = "<p class='TEST'></p>";
+
+ // Safari can't handle uppercase or unicode characters when
+ // in quirks mode.
+ if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
+ return;
+ }
+
+ Sizzle = function(query, context, extra, seed){
+ context = context || document;
+
+ // Only use querySelectorAll on non-XML documents
+ // (ID selectors don't work in non-HTML documents)
+ if ( !seed && context.nodeType === 9 && !isXML(context) ) {
+ try {
+ return makeArray( context.querySelectorAll(query), extra );
+ } catch(e){}
+ }
+
+ return oldSizzle(query, context, extra, seed);
+ };
+
+ Sizzle.find = oldSizzle.find;
+ Sizzle.filter = oldSizzle.filter;
+ Sizzle.selectors = oldSizzle.selectors;
+ Sizzle.matches = oldSizzle.matches;
+})();
+
+if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
+ var div = document.createElement("div");
+ div.innerHTML = "<div class='test e'></div><div class='test'></div>";
+
+ // Opera can't find a second classname (in 9.6)
+ if ( div.getElementsByClassName("e").length === 0 )
+ return;
+
+ // Safari caches class attributes, doesn't catch changes (in 3.2)
+ div.lastChild.className = "e";
+
+ if ( div.getElementsByClassName("e").length === 1 )
+ return;
+
+ Expr.order.splice(1, 0, "CLASS");
+ Expr.find.CLASS = function(match, context, isXML) {
+ if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
+ return context.getElementsByClassName(match[1]);
+ }
+ };
+})();
+
+function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ var sibDir = dir == "previousSibling" && !isXML;
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ if ( sibDir && elem.nodeType === 1 ){
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+ elem = elem[dir];
+ var match = false;
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 && !isXML ){
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+
+ if ( elem.nodeName === cur ) {
+ match = elem;
+ break;
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ var sibDir = dir == "previousSibling" && !isXML;
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ if ( sibDir && elem.nodeType === 1 ) {
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+ elem = elem[dir];
+ var match = false;
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 ) {
+ if ( !isXML ) {
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+ if ( typeof cur !== "string" ) {
+ if ( elem === cur ) {
+ match = true;
+ break;
+ }
+
+ } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
+ match = elem;
+ break;
+ }
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+var contains = document.compareDocumentPosition ? function(a, b){
+ return a.compareDocumentPosition(b) & 16;
+} : function(a, b){
+ return a !== b && (a.contains ? a.contains(b) : true);
+};
+
+var isXML = function(elem){
+ return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
+ !!elem.ownerDocument && isXML( elem.ownerDocument );
+};
+
+var posProcess = function(selector, context){
+ var tmpSet = [], later = "", match,
+ root = context.nodeType ? [context] : context;
+
+ // Position selectors must be done after the filter
+ // And so must :not(positional) so we move all PSEUDOs to the end
+ while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
+ later += match[0];
+ selector = selector.replace( Expr.match.PSEUDO, "" );
+ }
+
+ selector = Expr.relative[selector] ? selector + "*" : selector;
+
+ for ( var i = 0, l = root.length; i < l; i++ ) {
+ Sizzle( selector, root[i], tmpSet );
+ }
+
+ return Sizzle.filter( later, tmpSet );
+};
+
+// EXPOSE
+jQuery.find = Sizzle;
+jQuery.filter = Sizzle.filter;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.filters;
+
+Sizzle.selectors.filters.hidden = function(elem){
+ return elem.offsetWidth === 0 || elem.offsetHeight === 0;
+};
+
+Sizzle.selectors.filters.visible = function(elem){
+ return elem.offsetWidth > 0 || elem.offsetHeight > 0;
+};
+
+Sizzle.selectors.filters.animated = function(elem){
+ return jQuery.grep(jQuery.timers, function(fn){
+ return elem === fn.elem;
+ }).length;
+};
+
+jQuery.multiFilter = function( expr, elems, not ) {
+ if ( not ) {
+ expr = ":not(" + expr + ")";
+ }
+
+ return Sizzle.matches(expr, elems);
+};
+
+jQuery.dir = function( elem, dir ){
+ var matched = [], cur = elem[dir];
+ while ( cur && cur != document ) {
+ if ( cur.nodeType == 1 )
+ matched.push( cur );
+ cur = cur[dir];
+ }
+ return matched;
+};
+
+jQuery.nth = function(cur, result, dir, elem){
+ result = result || 1;
+ var num = 0;
+
+ for ( ; cur; cur = cur[dir] )
+ if ( cur.nodeType == 1 && ++num == result )
+ break;
+
+ return cur;
+};
+
+jQuery.sibling = function(n, elem){
+ var r = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType == 1 && n != elem )
+ r.push( n );
+ }
+
+ return r;
+};
+
+return;
+
+window.Sizzle = Sizzle;
+
+})();
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code originated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+ // Bind an event to an element
+ // Original by Dean Edwards
+ add: function(elem, types, handler, data) {
+ if ( elem.nodeType == 3 || elem.nodeType == 8 )
+ return;
+
+ // For whatever reason, IE has trouble passing the window object
+ // around, causing it to be cloned in the process
+ if ( elem.setInterval && elem != window )
+ elem = window;
+
+ // Make sure that the function being executed has a unique ID
+ if ( !handler.guid )
+ handler.guid = this.guid++;
+
+ // if data is passed, bind to handler
+ if ( data !== undefined ) {
+ // Create temporary function pointer to original handler
+ var fn = handler;
+
+ // Create unique handler function, wrapped around original handler
+ handler = this.proxy( fn );
+
+ // Store data in unique handler
+ handler.data = data;
+ }
+
+ // Init the element's event structure
+ var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
+ handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
+ // Handle the second event of a trigger and when
+ // an event is called after a page has unloaded
+ return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
+ jQuery.event.handle.apply(arguments.callee.elem, arguments) :
+ undefined;
+ });
+ // Add elem as a property of the handle function
+ // This is to prevent a memory leak with non-native
+ // event in IE.
+ handle.elem = elem;
+
+ // Handle multiple events separated by a space
+ // jQuery(...).bind("mouseover mouseout", fn);
+ jQuery.each(types.split(/\s+/), function(index, type) {
+ // Namespaced event handlers
+ var namespaces = type.split(".");
+ type = namespaces.shift();
+ handler.type = namespaces.slice().sort().join(".");
+
+ // Get the current list of functions bound to this event
+ var handlers = events[type];
+
+ if ( jQuery.event.specialAll[type] )
+ jQuery.event.specialAll[type].setup.call(elem, data, namespaces);
+
+ // Init the event handler queue
+ if (!handlers) {
+ handlers = events[type] = {};
+
+ // Check for a special event handler
+ // Only use addEventListener/attachEvent if the special
+ // events handler returns false
+ if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem, data, namespaces) === false ) {
+ // Bind the global event handler to the element
+ if (elem.addEventListener)
+ elem.addEventListener(type, handle, false);
+ else if (elem.attachEvent)
+ elem.attachEvent("on" + type, handle);
+ }
+ }
+
+ // Add the function to the element's handler list
+ handlers[handler.guid] = handler;
+
+ // Keep track of which events have been used, for global triggering
+ jQuery.event.global[type] = true;
+ });
+
+ // Nullify elem to prevent memory leaks in IE
+ elem = null;
+ },
+
+ guid: 1,
+ global: {},
+
+ // Detach an event or set of events from an element
+ remove: function(elem, types, handler) {
+ // don't do events on text and comment nodes
+ if ( elem.nodeType == 3 || elem.nodeType == 8 )
+ return;
+
+ var events = jQuery.data(elem, "events"), ret, index;
+
+ if ( events ) {
+ // Unbind all events for the element
+ if ( types === undefined || (typeof types === "string" && types.charAt(0) == ".") )
+ for ( var type in events )
+ this.remove( elem, type + (types || "") );
+ else {
+ // types is actually an event object here
+ if ( types.type ) {
+ handler = types.handler;
+ types = types.type;
+ }
+
+ // Handle multiple events seperated by a space
+ // jQuery(...).unbind("mouseover mouseout", fn);
+ jQuery.each(types.split(/\s+/), function(index, type){
+ // Namespaced event handlers
+ var namespaces = type.split(".");
+ type = namespaces.shift();
+ var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
+
+ if ( events[type] ) {
+ // remove the given handler for the given type
+ if ( handler )
+ delete events[type][handler.guid];
+
+ // remove all handlers for the given type
+ else
+ for ( var handle in events[type] )
+ // Handle the removal of namespaced events
+ if ( namespace.test(events[type][handle].type) )
+ delete events[type][handle];
+
+ if ( jQuery.event.specialAll[type] )
+ jQuery.event.specialAll[type].teardown.call(elem, namespaces);
+
+ // remove generic event handler if no more handlers exist
+ for ( ret in events[type] ) break;
+ if ( !ret ) {
+ if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem, namespaces) === false ) {
+ if (elem.removeEventListener)
+ elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
+ else if (elem.detachEvent)
+ elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
+ }
+ ret = null;
+ delete events[type];
+ }
+ }
+ });
+ }
+
+ // Remove the expando if it's no longer used
+ for ( ret in events ) break;
+ if ( !ret ) {
+ var handle = jQuery.data( elem, "handle" );
+ if ( handle ) handle.elem = null;
+ jQuery.removeData( elem, "events" );
+ jQuery.removeData( elem, "handle" );
+ }
+ }
+ },
+
+ // bubbling is internal
+ trigger: function( event, data, elem, bubbling ) {
+ // Event object or event type
+ var type = event.type || event;
+
+ if( !bubbling ){
+ event = typeof event === "object" ?
+ // jQuery.Event object
+ event[expando] ? event :
+ // Object literal
+ jQuery.extend( jQuery.Event(type), event ) :
+ // Just the event type (string)
+ jQuery.Event(type);
+
+ if ( type.indexOf("!") >= 0 ) {
+ event.type = type = type.slice(0, -1);
+ event.exclusive = true;
+ }
+
+ // Handle a global trigger
+ if ( !elem ) {
+ // Don't bubble custom events when global (to avoid too much overhead)
+ event.stopPropagation();
+ // Only trigger if we've ever bound an event for it
+ if ( this.global[type] )
+ jQuery.each( jQuery.cache, function(){
+ if ( this.events && this.events[type] )
+ jQuery.event.trigger( event, data, this.handle.elem );
+ });
+ }
+
+ // Handle triggering a single element
+
+ // don't do events on text and comment nodes
+ if ( !elem || elem.nodeType == 3 || elem.nodeType == 8 )
+ return undefined;
+
+ // Clean up in case it is reused
+ event.result = undefined;
+ event.target = elem;
+
+ // Clone the incoming data, if any
+ data = jQuery.makeArray(data);
+ data.unshift( event );
+ }
+
+ event.currentTarget = elem;
+
+ // Trigger the event, it is assumed that "handle" is a function
+ var handle = jQuery.data(elem, "handle");
+ if ( handle )
+ handle.apply( elem, data );
+
+ // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
+ if ( (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
+ event.result = false;
+
+ // Trigger the native events (except for clicks on links)
+ if ( !bubbling && elem[type] && !event.isDefaultPrevented() && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
+ this.triggered = true;
+ try {
+ elem[ type ]();
+ // prevent IE from throwing an error for some hidden elements
+ } catch (e) {}
+ }
+
+ this.triggered = false;
+
+ if ( !event.isPropagationStopped() ) {
+ var parent = elem.parentNode || elem.ownerDocument;
+ if ( parent )
+ jQuery.event.trigger(event, data, parent, true);
+ }
+ },
+
+ handle: function(event) {
+ // returned undefined or false
+ var all, handlers;
+
+ event = arguments[0] = jQuery.event.fix( event || window.event );
+ event.currentTarget = this;
+
+ // Namespaced event handlers
+ var namespaces = event.type.split(".");
+ event.type = namespaces.shift();
+
+ // Cache this now, all = true means, any handler
+ all = !namespaces.length && !event.exclusive;
+
+ var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
+
+ handlers = ( jQuery.data(this, "events") || {} )[event.type];
+
+ for ( var j in handlers ) {
+ var handler = handlers[j];
+
+ // Filter the functions by class
+ if ( all || namespace.test(handler.type) ) {
+ // Pass in a reference to the handler function itself
+ // So that we can later remove it
+ event.handler = handler;
+ event.data = handler.data;
+
+ var ret = handler.apply(this, arguments);
+
+ if( ret !== undefined ){
+ event.result = ret;
+ if ( ret === false ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+
+ if( event.isImmediatePropagationStopped() )
+ break;
+
+ }
+ }
+ },
+
+ props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+
+ fix: function(event) {
+ if ( event[expando] )
+ return event;
+
+ // store a copy of the original event object
+ // and "clone" to set read-only properties
+ var originalEvent = event;
+ event = jQuery.Event( originalEvent );
+
+ for ( var i = this.props.length, prop; i; ){
+ prop = this.props[ --i ];
+ event[ prop ] = originalEvent[ prop ];
+ }
+
+ // Fix target property, if necessary
+ if ( !event.target )
+ event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
+
+ // check if target is a textnode (safari)
+ if ( event.target.nodeType == 3 )
+ event.target = event.target.parentNode;
+
+ // Add relatedTarget, if necessary
+ if ( !event.relatedTarget && event.fromElement )
+ event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
+
+ // Calculate pageX/Y if missing and clientX/Y available
+ if ( event.pageX == null && event.clientX != null ) {
+ var doc = document.documentElement, body = document.body;
+ event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
+ event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
+ }
+
+ // Add which for key events
+ if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
+ event.which = event.charCode || event.keyCode;
+
+ // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+ if ( !event.metaKey && event.ctrlKey )
+ event.metaKey = event.ctrlKey;
+
+ // Add which for click: 1 == left; 2 == middle; 3 == right
+ // Note: button is not normalized, so don't use it
+ if ( !event.which && event.button )
+ event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+
+ return event;
+ },
+
+ proxy: function( fn, proxy ){
+ proxy = proxy || function(){ return fn.apply(this, arguments); };
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
+ // So proxy can be declared as an argument
+ return proxy;
+ },
+
+ special: {
+ ready: {
+ // Make sure the ready event is setup
+ setup: bindReady,
+ teardown: function() {}
+ }
+ },
+
+ specialAll: {
+ live: {
+ setup: function( selector, namespaces ){
+ jQuery.event.add( this, namespaces[0], liveHandler );
+ },
+ teardown: function( namespaces ){
+ if ( namespaces.length ) {
+ var remove = 0, name = RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)");
+
+ jQuery.each( (jQuery.data(this, "events").live || {}), function(){
+ if ( name.test(this.type) )
+ remove++;
+ });
+
+ if ( remove < 1 )
+ jQuery.event.remove( this, namespaces[0], liveHandler );
+ }
+ }
+ }
+ }
+};
+
+jQuery.Event = function( src ){
+ // Allow instantiation without the 'new' keyword
+ if( !this.preventDefault )
+ return new jQuery.Event(src);
+
+ // Event object
+ if( src && src.type ){
+ this.originalEvent = src;
+ this.type = src.type;
+ // Event type
+ }else
+ this.type = src;
+
+ // timeStamp is buggy for some events on Firefox(#3843)
+ // So we won't rely on the native value
+ this.timeStamp = now();
+
+ // Mark it as fixed
+ this[expando] = true;
+};
+
+function returnFalse(){
+ return false;
+}
+function returnTrue(){
+ return true;
+}
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+ preventDefault: function() {
+ this.isDefaultPrevented = returnTrue;
+
+ var e = this.originalEvent;
+ if( !e )
+ return;
+ // if preventDefault exists run it on the original event
+ if (e.preventDefault)
+ e.preventDefault();
+ // otherwise set the returnValue property of the original event to false (IE)
+ e.returnValue = false;
+ },
+ stopPropagation: function() {
+ this.isPropagationStopped = returnTrue;
+
+ var e = this.originalEvent;
+ if( !e )
+ return;
+ // if stopPropagation exists run it on the original event
+ if (e.stopPropagation)
+ e.stopPropagation();
+ // otherwise set the cancelBubble property of the original event to true (IE)
+ e.cancelBubble = true;
+ },
+ stopImmediatePropagation:function(){
+ this.isImmediatePropagationStopped = returnTrue;
+ this.stopPropagation();
+ },
+ isDefaultPrevented: returnFalse,
+ isPropagationStopped: returnFalse,
+ isImmediatePropagationStopped: returnFalse
+};
+// Checks if an event happened on an element within another element
+// Used in jQuery.event.special.mouseenter and mouseleave handlers
+var withinElement = function(event) {
+ // Check if mouse(over|out) are still within the same parent element
+ var parent = event.relatedTarget;
+ // Traverse up the tree
+ while ( parent && parent != this )
+ try { parent = parent.parentNode; }
+ catch(e) { parent = this; }
+
+ if( parent != this ){
+ // set the correct event type
+ event.type = event.data;
+ // handle event if we actually just moused on to a non sub-element
+ jQuery.event.handle.apply( this, arguments );
+ }
+};
+
+jQuery.each({
+ mouseover: 'mouseenter',
+ mouseout: 'mouseleave'
+}, function( orig, fix ){
+ jQuery.event.special[ fix ] = {
+ setup: function(){
+ jQuery.event.add( this, orig, withinElement, fix );
+ },
+ teardown: function(){
+ jQuery.event.remove( this, orig, withinElement );
+ }
+ };
+});
+
+jQuery.fn.extend({
+ bind: function( type, data, fn ) {
+ return type == "unload" ? this.one(type, data, fn) : this.each(function(){
+ jQuery.event.add( this, type, fn || data, fn && data );
+ });
+ },
+
+ one: function( type, data, fn ) {
+ var one = jQuery.event.proxy( fn || data, function(event) {
+ jQuery(this).unbind(event, one);
+ return (fn || data).apply( this, arguments );
+ });
+ return this.each(function(){
+ jQuery.event.add( this, type, one, fn && data);
+ });
+ },
+
+ unbind: function( type, fn ) {
+ return this.each(function(){
+ jQuery.event.remove( this, type, fn );
+ });
+ },
+
+ trigger: function( type, data ) {
+ return this.each(function(){
+ jQuery.event.trigger( type, data, this );
+ });
+ },
+
+ triggerHandler: function( type, data ) {
+ if( this[0] ){
+ var event = jQuery.Event(type);
+ event.preventDefault();
+ event.stopPropagation();
+ jQuery.event.trigger( event, data, this[0] );
+ return event.result;
+ }
+ },
+
+ toggle: function( fn ) {
+ // Save reference to arguments for access in closure
+ var args = arguments, i = 1;
+
+ // link all the functions, so any of them can unbind this click handler
+ while( i < args.length )
+ jQuery.event.proxy( fn, args[i++] );
+
+ return this.click( jQuery.event.proxy( fn, function(event) {
+ // Figure out which function to execute
+ this.lastToggle = ( this.lastToggle || 0 ) % i;
+
+ // Make sure that clicks stop
+ event.preventDefault();
+
+ // and execute the function
+ return args[ this.lastToggle++ ].apply( this, arguments ) || false;
+ }));
+ },
+
+ hover: function(fnOver, fnOut) {
+ return this.mouseenter(fnOver).mouseleave(fnOut);
+ },
+
+ ready: function(fn) {
+ // Attach the listeners
+ bindReady();
+
+ // If the DOM is already ready
+ if ( jQuery.isReady )
+ // Execute the function immediately
+ fn.call( document, jQuery );
+
+ // Otherwise, remember the function for later
+ else
+ // Add the function to the wait list
+ jQuery.readyList.push( fn );
+
+ return this;
+ },
+
+ live: function( type, fn ){
+ var proxy = jQuery.event.proxy( fn );
+ proxy.guid += this.selector + type;
+
+ jQuery(document).bind( liveConvert(type, this.selector), this.selector, proxy );
+
+ return this;
+ },
+
+ die: function( type, fn ){
+ jQuery(document).unbind( liveConvert(type, this.selector), fn ? { guid: fn.guid + this.selector + type } : null );
+ return this;
+ }
+});
+
+function liveHandler( event ){
+ var check = RegExp("(^|\\.)" + event.type + "(\\.|$)"),
+ stop = true,
+ elems = [];
+
+ jQuery.each(jQuery.data(this, "events").live || [], function(i, fn){
+ if ( check.test(fn.type) ) {
+ var elem = jQuery(event.target).closest(fn.data)[0];
+ if ( elem )
+ elems.push({ elem: elem, fn: fn });
+ }
+ });
+
+ elems.sort(function(a,b) {
+ return jQuery.data(a.elem, "closest") - jQuery.data(b.elem, "closest");
+ });
+
+ jQuery.each(elems, function(){
+ if ( this.fn.call(this.elem, event, this.fn.data) === false )
+ return (stop = false);
+ });
+
+ return stop;
+}
+
+function liveConvert(type, selector){
+ return ["live", type, selector.replace(/\./g, "`").replace(/ /g, "|")].join(".");
+}
+
+jQuery.extend({
+ isReady: false,
+ readyList: [],
+ // Handle when the DOM is ready
+ ready: function() {
+ // Make sure that the DOM is not already loaded
+ if ( !jQuery.isReady ) {
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If there are functions bound, to execute
+ if ( jQuery.readyList ) {
+ // Execute all of them
+ jQuery.each( jQuery.readyList, function(){
+ this.call( document, jQuery );
+ });
+
+ // Reset the list of functions
+ jQuery.readyList = null;
+ }
+
+ // Trigger any bound ready events
+ jQuery(document).triggerHandler("ready");
+ }
+ }
+});
+
+var readyBound = false;
+
+function bindReady(){
+ if ( readyBound ) return;
+ readyBound = true;
+
+ // Mozilla, Opera and webkit nightlies currently support this event
+ if ( document.addEventListener ) {
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", function(){
+ document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
+ jQuery.ready();
+ }, false );
+
+ // If IE event model is used
+ } else if ( document.attachEvent ) {
+ // ensure firing before onload,
+ // maybe late but safe also for iframes
+ document.attachEvent("onreadystatechange", function(){
+ if ( document.readyState === "complete" ) {
+ document.detachEvent( "onreadystatechange", arguments.callee );
+ jQuery.ready();
+ }
+ });
+
+ // If IE and not an iframe
+ // continually check to see if the document is ready
+ if ( document.documentElement.doScroll && window == window.top ) (function(){
+ if ( jQuery.isReady ) return;
+
+ try {
+ // If IE is used, use the trick by Diego Perini
+ // http://javascript.nwbox.com/IEContentLoaded/
+ document.documentElement.doScroll("left");
+ } catch( error ) {
+ setTimeout( arguments.callee, 0 );
+ return;
+ }
+
+ // and execute any waiting functions
+ jQuery.ready();
+ })();
+ }
+
+ // A fallback to window.onload, that will always work
+ jQuery.event.add( window, "load", jQuery.ready );
+}
+
+jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
+ "mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave," +
+ "change,select,submit,keydown,keypress,keyup,error").split(","), function(i, name){
+
+ // Handle event binding
+ jQuery.fn[name] = function(fn){
+ return fn ? this.bind(name, fn) : this.trigger(name);
+ };
+});
+
+// Prevent memory leaks in IE
+// And prevent errors on refresh with events like mouseover in other browsers
+// Window isn't included so as not to unbind existing unload events
+jQuery( window ).bind( 'unload', function(){
+ for ( var id in jQuery.cache )
+ // Skip the window
+ if ( id != 1 && jQuery.cache[ id ].handle )
+ jQuery.event.remove( jQuery.cache[ id ].handle.elem );
+});
+(function(){
+
+ jQuery.support = {};
+
+ var root = document.documentElement,
+ script = document.createElement("script"),
+ div = document.createElement("div"),
+ id = "script" + (new Date).getTime();
+
+ div.style.display = "none";
+ div.innerHTML = ' <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';
+
+ var all = div.getElementsByTagName("*"),
+ a = div.getElementsByTagName("a")[0];
+
+ // Can't get basic test support
+ if ( !all || !all.length || !a ) {
+ return;
+ }
+
+ jQuery.support = {
+ // IE strips leading whitespace when .innerHTML is used
+ leadingWhitespace: div.firstChild.nodeType == 3,
+
+ // Make sure that tbody elements aren't automatically inserted
+ // IE will insert them into empty tables
+ tbody: !div.getElementsByTagName("tbody").length,
+
+ // Make sure that you can get all elements in an <object> element
+ // IE 7 always returns no results
+ objectAll: !!div.getElementsByTagName("object")[0]
+ .getElementsByTagName("*").length,
+
+ // Make sure that link elements get serialized correctly by innerHTML
+ // This requires a wrapper element in IE
+ htmlSerialize: !!div.getElementsByTagName("link").length,
+
+ // Get the style information from getAttribute
+ // (IE uses .cssText insted)
+ style: /red/.test( a.getAttribute("style") ),
+
+ // Make sure that URLs aren't manipulated
+ // (IE normalizes it by default)
+ hrefNormalized: a.getAttribute("href") === "/a",
+
+ // Make sure that element opacity exists
+ // (IE uses filter instead)
+ opacity: a.style.opacity === "0.5",
+
+ // Verify style float existence
+ // (IE uses styleFloat instead of cssFloat)
+ cssFloat: !!a.style.cssFloat,
+
+ // Will be defined later
+ scriptEval: false,
+ noCloneEvent: true,
+ boxModel: null
+ };
+
+ script.type = "text/javascript";
+ try {
+ script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
+ } catch(e){}
+
+ root.insertBefore( script, root.firstChild );
+
+ // Make sure that the execution of code works by injecting a script
+ // tag with appendChild/createTextNode
+ // (IE doesn't support this, fails, and uses .text instead)
+ if ( window[ id ] ) {
+ jQuery.support.scriptEval = true;
+ delete window[ id ];
+ }
+
+ root.removeChild( script );
+
+ if ( div.attachEvent && div.fireEvent ) {
+ div.attachEvent("onclick", function(){
+ // Cloning a node shouldn't copy over any
+ // bound event handlers (IE does this)
+ jQuery.support.noCloneEvent = false;
+ div.detachEvent("onclick", arguments.callee);
+ });
+ div.cloneNode(true).fireEvent("onclick");
+ }
+
+ // Figure out if the W3C box model works as expected
+ // document.body must exist before we can do this
+ jQuery(function(){
+ var div = document.createElement("div");
+ div.style.width = div.style.paddingLeft = "1px";
+
+ document.body.appendChild( div );
+ jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
+ document.body.removeChild( div ).style.display = 'none';
+ });
+})();
+
+var styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat";
+
+jQuery.props = {
+ "for": "htmlFor",
+ "class": "className",
+ "float": styleFloat,
+ cssFloat: styleFloat,
+ styleFloat: styleFloat,
+ readonly: "readOnly",
+ maxlength: "maxLength",
+ cellspacing: "cellSpacing",
+ rowspan: "rowSpan",
+ tabindex: "tabIndex"
+};
+jQuery.fn.extend({
+ // Keep a copy of the old load
+ _load: jQuery.fn.load,
+
+ load: function( url, params, callback ) {
+ if ( typeof url !== "string" )
+ return this._load( url );
+
+ var off = url.indexOf(" ");
+ if ( off >= 0 ) {
+ var selector = url.slice(off, url.length);
+ url = url.slice(0, off);
+ }
+
+ // Default to a GET request
+ var type = "GET";
+
+ // If the second parameter was provided
+ if ( params )
+ // If it's a function
+ if ( jQuery.isFunction( params ) ) {
+ // We assume that it's the callback
+ callback = params;
+ params = null;
+
+ // Otherwise, build a param string
+ } else if( typeof params === "object" ) {
+ params = jQuery.param( params );
+ type = "POST";
+ }
+
+ var self = this;
+
+ // Request the remote document
+ jQuery.ajax({
+ url: url,
+ type: type,
+ dataType: "html",
+ data: params,
+ complete: function(res, status){
+ // If successful, inject the HTML into all the matched elements
+ if ( status == "success" || status == "notmodified" )
+ // See if a selector was specified
+ self.html( selector ?
+ // Create a dummy div to hold the results
+ jQuery("<div/>")
+ // inject the contents of the document in, removing the scripts
+ // to avoid any 'Permission Denied' errors in IE
+ .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
+
+ // Locate the specified elements
+ .find(selector) :
+
+ // If not, just inject the full result
+ res.responseText );
+
+ if( callback )
+ self.each( callback, [res.responseText, status, res] );
+ }
+ });
+ return this;
+ },
+
+ serialize: function() {
+ return jQuery.param(this.serializeArray());
+ },
+ serializeArray: function() {
+ return this.map(function(){
+ return this.elements ? jQuery.makeArray(this.elements) : this;
+ })
+ .filter(function(){
+ return this.name && !this.disabled &&
+ (this.checked || /select|textarea/i.test(this.nodeName) ||
+ /text|hidden|password|search/i.test(this.type));
+ })
+ .map(function(i, elem){
+ var val = jQuery(this).val();
+ return val == null ? null :
+ jQuery.isArray(val) ?
+ jQuery.map( val, function(val, i){
+ return {name: elem.name, value: val};
+ }) :
+ {name: elem.name, value: val};
+ }).get();
+ }
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
+ jQuery.fn[o] = function(f){
+ return this.bind(o, f);
+ };
+});
+
+var jsc = now();
+
+jQuery.extend({
+
+ get: function( url, data, callback, type ) {
+ // shift arguments if data argument was ommited
+ if ( jQuery.isFunction( data ) ) {
+ callback = data;
+ data = null;
+ }
+
+ return jQuery.ajax({
+ type: "GET",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ getScript: function( url, callback ) {
+ return jQuery.get(url, null, callback, "script");
+ },
+
+ getJSON: function( url, data, callback ) {
+ return jQuery.get(url, data, callback, "json");
+ },
+
+ post: function( url, data, callback, type ) {
+ if ( jQuery.isFunction( data ) ) {
+ callback = data;
+ data = {};
+ }
+
+ return jQuery.ajax({
+ type: "POST",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ ajaxSetup: function( settings ) {
+ jQuery.extend( jQuery.ajaxSettings, settings );
+ },
+
+ ajaxSettings: {
+ url: location.href,
+ global: true,
+ type: "GET",
+ contentType: "application/x-www-form-urlencoded",
+ processData: true,
+ async: true,
+ /*
+ timeout: 0,
+ data: null,
+ username: null,
+ password: null,
+ */
+ // Create the request object; Microsoft failed to properly
+ // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
+ // This function can be overriden by calling jQuery.ajaxSetup
+ xhr:function(){
+ return window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
+ },
+ accepts: {
+ xml: "application/xml, text/xml",
+ html: "text/html",
+ script: "text/javascript, application/javascript",
+ json: "application/json, text/javascript",
+ text: "text/plain",
+ _default: "*/*"
+ }
+ },
+
+ // Last-Modified header cache for next request
+ lastModified: {},
+
+ ajax: function( s ) {
+ // Extend the settings, but re-extend 's' so that it can be
+ // checked again later (in the test suite, specifically)
+ s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
+
+ var jsonp, jsre = /=\?(&|$)/g, status, data,
+ type = s.type.toUpperCase();
+
+ // convert data if not already a string
+ if ( s.data && s.processData && typeof s.data !== "string" )
+ s.data = jQuery.param(s.data);
+
+ // Handle JSONP Parameter Callbacks
+ if ( s.dataType == "jsonp" ) {
+ if ( type == "GET" ) {
+ if ( !s.url.match(jsre) )
+ s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
+ } else if ( !s.data || !s.data.match(jsre) )
+ s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
+ s.dataType = "json";
+ }
+
+ // Build temporary JSONP function
+ if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
+ jsonp = "jsonp" + jsc++;
+
+ // Replace the =? sequence both in the query string and the data
+ if ( s.data )
+ s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
+ s.url = s.url.replace(jsre, "=" + jsonp + "$1");
+
+ // We need to make sure
+ // that a JSONP style response is executed properly
+ s.dataType = "script";
+
+ // Handle JSONP-style loading
+ window[ jsonp ] = function(tmp){
+ data = tmp;
+ success();
+ complete();
+ // Garbage collect
+ window[ jsonp ] = undefined;
+ try{ delete window[ jsonp ]; } catch(e){}
+ if ( head )
+ head.removeChild( script );
+ };
+ }
+
+ if ( s.dataType == "script" && s.cache == null )
+ s.cache = false;
+
+ if ( s.cache === false && type == "GET" ) {
+ var ts = now();
+ // try replacing _= if it is there
+ var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
+ // if nothing was replaced, add timestamp to the end
+ s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
+ }
+
+ // If data is available, append data to url for get requests
+ if ( s.data && type == "GET" ) {
+ s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
+
+ // IE likes to send both get and post data, prevent this
+ s.data = null;
+ }
+
+ // Watch for a new set of requests
+ if ( s.global && ! jQuery.active++ )
+ jQuery.event.trigger( "ajaxStart" );
+
+ // Matches an absolute URL, and saves the domain
+ var parts = /^(\w+:)?\/\/([^\/?#]+)/.exec( s.url );
+
+ // If we're requesting a remote document
+ // and trying to load JSON or Script with a GET
+ if ( s.dataType == "script" && type == "GET" && parts
+ && ( parts[1] && parts[1] != location.protocol || parts[2] != location.host )){
+
+ var head = document.getElementsByTagName("head")[0];
+ var script = document.createElement("script");
+ script.src = s.url;
+ if (s.scriptCharset)
+ script.charset = s.scriptCharset;
+
+ // Handle Script loading
+ if ( !jsonp ) {
+ var done = false;
+
+ // Attach handlers for all browsers
+ script.onload = script.onreadystatechange = function(){
+ if ( !done && (!this.readyState ||
+ this.readyState == "loaded" || this.readyState == "complete") ) {
+ done = true;
+ success();
+ complete();
+
+ // Handle memory leak in IE
+ script.onload = script.onreadystatechange = null;
+ head.removeChild( script );
+ }
+ };
+ }
+
+ head.appendChild(script);
+
+ // We handle everything using the script element injection
+ return undefined;
+ }
+
+ var requestDone = false;
+
+ // Create the request object
+ var xhr = s.xhr();
+
+ // Open the socket
+ // Passing null username, generates a login popup on Opera (#2865)
+ if( s.username )
+ xhr.open(type, s.url, s.async, s.username, s.password);
+ else
+ xhr.open(type, s.url, s.async);
+
+ // Need an extra try/catch for cross domain requests in Firefox 3
+ try {
+ // Set the correct header, if data is being sent
+ if ( s.data )
+ xhr.setRequestHeader("Content-Type", s.contentType);
+
+ // Set the If-Modified-Since header, if ifModified mode.
+ if ( s.ifModified )
+ xhr.setRequestHeader("If-Modified-Since",
+ jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
+
+ // Set header so the called script knows that it's an XMLHttpRequest
+ xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+
+ // Set the Accepts header for the server, depending on the dataType
+ xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
+ s.accepts[ s.dataType ] + ", */*" :
+ s.accepts._default );
+ } catch(e){}
+
+ // Allow custom headers/mimetypes and early abort
+ if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active )
+ jQuery.event.trigger( "ajaxStop" );
+ // close opended socket
+ xhr.abort();
+ return false;
+ }
+
+ if ( s.global )
+ jQuery.event.trigger("ajaxSend", [xhr, s]);
+
+ // Wait for a response to come back
+ var onreadystatechange = function(isTimeout){
+ // The request was aborted, clear the interval and decrement jQuery.active
+ if (xhr.readyState == 0) {
+ if (ival) {
+ // clear poll interval
+ clearInterval(ival);
+ ival = null;
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active )
+ jQuery.event.trigger( "ajaxStop" );
+ }
+ // The transfer is complete and the data is available, or the request timed out
+ } else if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
+ requestDone = true;
+
+ // clear poll interval
+ if (ival) {
+ clearInterval(ival);
+ ival = null;
+ }
+
+ status = isTimeout == "timeout" ? "timeout" :
+ !jQuery.httpSuccess( xhr ) ? "error" :
+ s.ifModified && jQuery.httpNotModified( xhr, s.url ) ? "notmodified" :
+ "success";
+
+ if ( status == "success" ) {
+ // Watch for, and catch, XML document parse errors
+ try {
+ // process the data (runs the xml through httpData regardless of callback)
+ data = jQuery.httpData( xhr, s.dataType, s );
+ } catch(e) {
+ status = "parsererror";
+ }
+ }
+
+ // Make sure that the request was successful or notmodified
+ if ( status == "success" ) {
+ // Cache Last-Modified header, if ifModified mode.
+ var modRes;
+ try {
+ modRes = xhr.getResponseHeader("Last-Modified");
+ } catch(e) {} // swallow exception thrown by FF if header is not available
+
+ if ( s.ifModified && modRes )
+ jQuery.lastModified[s.url] = modRes;
+
+ // JSONP handles its own success callback
+ if ( !jsonp )
+ success();
+ } else
+ jQuery.handleError(s, xhr, status);
+
+ // Fire the complete handlers
+ complete();
+
+ if ( isTimeout )
+ xhr.abort();
+
+ // Stop memory leaks
+ if ( s.async )
+ xhr = null;
+ }
+ };
+
+ if ( s.async ) {
+ // don't attach the handler to the request, just poll it instead
+ var ival = setInterval(onreadystatechange, 13);
+
+ // Timeout checker
+ if ( s.timeout > 0 )
+ setTimeout(function(){
+ // Check to see if the request is still happening
+ if ( xhr && !requestDone )
+ onreadystatechange( "timeout" );
+ }, s.timeout);
+ }
+
+ // Send the data
+ try {
+ xhr.send(s.data);
+ } catch(e) {
+ jQuery.handleError(s, xhr, null, e);
+ }
+
+ // firefox 1.5 doesn't fire statechange for sync requests
+ if ( !s.async )
+ onreadystatechange();
+
+ function success(){
+ // If a local callback was specified, fire it and pass it the data
+ if ( s.success )
+ s.success( data, status );
+
+ // Fire the global callback
+ if ( s.global )
+ jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
+ }
+
+ function complete(){
+ // Process result
+ if ( s.complete )
+ s.complete(xhr, status);
+
+ // The request was completed
+ if ( s.global )
+ jQuery.event.trigger( "ajaxComplete", [xhr, s] );
+
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active )
+ jQuery.event.trigger( "ajaxStop" );
+ }
+
+ // return XMLHttpRequest to allow aborting the request etc.
+ return xhr;
+ },
+
+ handleError: function( s, xhr, status, e ) {
+ // If a local callback was specified, fire it
+ if ( s.error ) s.error( xhr, status, e );
+
+ // Fire the global callback
+ if ( s.global )
+ jQuery.event.trigger( "ajaxError", [xhr, s, e] );
+ },
+
+ // Counter for holding the number of active queries
+ active: 0,
+
+ // Determines if an XMLHttpRequest was successful or not
+ httpSuccess: function( xhr ) {
+ try {
+ // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
+ return !xhr.status && location.protocol == "file:" ||
+ ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223;
+ } catch(e){}
+ return false;
+ },
+
+ // Determines if an XMLHttpRequest returns NotModified
+ httpNotModified: function( xhr, url ) {
+ try {
+ var xhrRes = xhr.getResponseHeader("Last-Modified");
+
+ // Firefox always returns 200. check Last-Modified date
+ return xhr.status == 304 || xhrRes == jQuery.lastModified[url];
+ } catch(e){}
+ return false;
+ },
+
+ httpData: function( xhr, type, s ) {
+ var ct = xhr.getResponseHeader("content-type"),
+ xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,
+ data = xml ? xhr.responseXML : xhr.responseText;
+
+ if ( xml && data.documentElement.tagName == "parsererror" )
+ throw "parsererror";
+
+ // Allow a pre-filtering function to sanitize the response
+ // s != null is checked to keep backwards compatibility
+ if( s && s.dataFilter )
+ data = s.dataFilter( data, type );
+
+ // The filter can actually parse the response
+ if( typeof data === "string" ){
+
+ // If the type is "script", eval it in global context
+ if ( type == "script" )
+ jQuery.globalEval( data );
+
+ // Get the JavaScript object, if JSON is used.
+ if ( type == "json" )
+ data = window["eval"]("(" + data + ")");
+ }
+
+ return data;
+ },
+
+ // Serialize an array of form elements or a set of
+ // key/values into a query string
+ param: function( a ) {
+ var s = [ ];
+
+ function add( key, value ){
+ s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
+ };
+
+ // If an array was passed in, assume that it is an array
+ // of form elements
+ if ( jQuery.isArray(a) || a.jquery )
+ // Serialize the form elements
+ jQuery.each( a, function(){
+ add( this.name, this.value );
+ });
+
+ // Otherwise, assume that it's an object of key/value pairs
+ else
+ // Serialize the key/values
+ for ( var j in a )
+ // If the value is an array then the key names need to be repeated
+ if ( jQuery.isArray(a[j]) )
+ jQuery.each( a[j], function(){
+ add( j, this );
+ });
+ else
+ add( j, jQuery.isFunction(a[j]) ? a[j]() : a[j] );
+
+ // Return the resulting serialization
+ return s.join("&").replace(/%20/g, "+");
+ }
+
+});
+var elemdisplay = {},
+ timerId,
+ fxAttrs = [
+ // height animations
+ [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
+ // width animations
+ [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
+ // opacity animations
+ [ "opacity" ]
+ ];
+
+function genFx( type, num ){
+ var obj = {};
+ jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function(){
+ obj[ this ] = type;
+ });
+ return obj;
+}
+
+jQuery.fn.extend({
+ show: function(speed,callback){
+ if ( speed ) {
+ return this.animate( genFx("show", 3), speed, callback);
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ){
+ var old = jQuery.data(this[i], "olddisplay");
+
+ this[i].style.display = old || "";
+
+ if ( jQuery.css(this[i], "display") === "none" ) {
+ var tagName = this[i].tagName, display;
+
+ if ( elemdisplay[ tagName ] ) {
+ display = elemdisplay[ tagName ];
+ } else {
+ var elem = jQuery("<" + tagName + " />").appendTo("body");
+
+ display = elem.css("display");
+ if ( display === "none" )
+ display = "block";
+
+ elem.remove();
+
+ elemdisplay[ tagName ] = display;
+ }
+
+ jQuery.data(this[i], "olddisplay", display);
+ }
+ }
+
+ // Set the display of the elements in a second loop
+ // to avoid the constant reflow
+ for ( var i = 0, l = this.length; i < l; i++ ){
+ this[i].style.display = jQuery.data(this[i], "olddisplay") || "";
+ }
+
+ return this;
+ }
+ },
+
+ hide: function(speed,callback){
+ if ( speed ) {
+ return this.animate( genFx("hide", 3), speed, callback);
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ){
+ var old = jQuery.data(this[i], "olddisplay");
+ if ( !old && old !== "none" )
+ jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
+ }
+
+ // Set the display of the elements in a second loop
+ // to avoid the constant reflow
+ for ( var i = 0, l = this.length; i < l; i++ ){
+ this[i].style.display = "none";
+ }
+
+ return this;
+ }
+ },
+
+ // Save the old toggle function
+ _toggle: jQuery.fn.toggle,
+
+ toggle: function( fn, fn2 ){
+ var bool = typeof fn === "boolean";
+
+ return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
+ this._toggle.apply( this, arguments ) :
+ fn == null || bool ?
+ this.each(function(){
+ var state = bool ? fn : jQuery(this).is(":hidden");
+ jQuery(this)[ state ? "show" : "hide" ]();
+ }) :
+ this.animate(genFx("toggle", 3), fn, fn2);
+ },
+
+ fadeTo: function(speed,to,callback){
+ return this.animate({opacity: to}, speed, callback);
+ },
+
+ animate: function( prop, speed, easing, callback ) {
+ var optall = jQuery.speed(speed, easing, callback);
+
+ return this[ optall.queue === false ? "each" : "queue" ](function(){
+
+ var opt = jQuery.extend({}, optall), p,
+ hidden = this.nodeType == 1 && jQuery(this).is(":hidden"),
+ self = this;
+
+ for ( p in prop ) {
+ if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
+ return opt.complete.call(this);
+
+ if ( ( p == "height" || p == "width" ) && this.style ) {
+ // Store display property
+ opt.display = jQuery.css(this, "display");
+
+ // Make sure that nothing sneaks out
+ opt.overflow = this.style.overflow;
+ }
+ }
+
+ if ( opt.overflow != null )
+ this.style.overflow = "hidden";
+
+ opt.curAnim = jQuery.extend({}, prop);
+
+ jQuery.each( prop, function(name, val){
+ var e = new jQuery.fx( self, opt, name );
+
+ if ( /toggle|show|hide/.test(val) )
+ e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
+ else {
+ var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
+ start = e.cur(true) || 0;
+
+ if ( parts ) {
+ var end = parseFloat(parts[2]),
+ unit = parts[3] || "px";
+
+ // We need to compute starting value
+ if ( unit != "px" ) {
+ self.style[ name ] = (end || 1) + unit;
+ start = ((end || 1) / e.cur(true)) * start;
+ self.style[ name ] = start + unit;
+ }
+
+ // If a +=/-= token was provided, we're doing a relative animation
+ if ( parts[1] )
+ end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
+
+ e.custom( start, end, unit );
+ } else
+ e.custom( start, val, "" );
+ }
+ });
+
+ // For JS strict compliance
+ return true;
+ });
+ },
+
+ stop: function(clearQueue, gotoEnd){
+ var timers = jQuery.timers;
+
+ if (clearQueue)
+ this.queue([]);
+
+ this.each(function(){
+ // go in reverse order so anything added to the queue during the loop is ignored
+ for ( var i = timers.length - 1; i >= 0; i-- )
+ if ( timers[i].elem == this ) {
+ if (gotoEnd)
+ // force the next step to be the last
+ timers[i](true);
+ timers.splice(i, 1);
+ }
+ });
+
+ // start the next in the queue if the last step wasn't forced
+ if (!gotoEnd)
+ this.dequeue();
+
+ return this;
+ }
+
+});
+
+// Generate shortcuts for custom animations
+jQuery.each({
+ slideDown: genFx("show", 1),
+ slideUp: genFx("hide", 1),
+ slideToggle: genFx("toggle", 1),
+ fadeIn: { opacity: "show" },
+ fadeOut: { opacity: "hide" }
+}, function( name, props ){
+ jQuery.fn[ name ] = function( speed, callback ){
+ return this.animate( props, speed, callback );
+ };
+});
+
+jQuery.extend({
+
+ speed: function(speed, easing, fn) {
+ var opt = typeof speed === "object" ? speed : {
+ complete: fn || !fn && easing ||
+ jQuery.isFunction( speed ) && speed,
+ duration: speed,
+ easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
+ };
+
+ opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+ jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
+
+ // Queueing
+ opt.old = opt.complete;
+ opt.complete = function(){
+ if ( opt.queue !== false )
+ jQuery(this).dequeue();
+ if ( jQuery.isFunction( opt.old ) )
+ opt.old.call( this );
+ };
+
+ return opt;
+ },
+
+ easing: {
+ linear: function( p, n, firstNum, diff ) {
+ return firstNum + diff * p;
+ },
+ swing: function( p, n, firstNum, diff ) {
+ return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
+ }
+ },
+
+ timers: [],
+
+ fx: function( elem, options, prop ){
+ this.options = options;
+ this.elem = elem;
+ this.prop = prop;
+
+ if ( !options.orig )
+ options.orig = {};
+ }
+
+});
+
+jQuery.fx.prototype = {
+
+ // Simple function for setting a style value
+ update: function(){
+ if ( this.options.step )
+ this.options.step.call( this.elem, this.now, this );
+
+ (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+
+ // Set display property to block for height/width animations
+ if ( ( this.prop == "height" || this.prop == "width" ) && this.elem.style )
+ this.elem.style.display = "block";
+ },
+
+ // Get the current size
+ cur: function(force){
+ if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) )
+ return this.elem[ this.prop ];
+
+ var r = parseFloat(jQuery.css(this.elem, this.prop, force));
+ return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
+ },
+
+ // Start an animation from one number to another
+ custom: function(from, to, unit){
+ this.startTime = now();
+ this.start = from;
+ this.end = to;
+ this.unit = unit || this.unit || "px";
+ this.now = this.start;
+ this.pos = this.state = 0;
+
+ var self = this;
+ function t(gotoEnd){
+ return self.step(gotoEnd);
+ }
+
+ t.elem = this.elem;
+
+ if ( t() && jQuery.timers.push(t) && !timerId ) {
+ timerId = setInterval(function(){
+ var timers = jQuery.timers;
+
+ for ( var i = 0; i < timers.length; i++ )
+ if ( !timers[i]() )
+ timers.splice(i--, 1);
+
+ if ( !timers.length ) {
+ clearInterval( timerId );
+ timerId = undefined;
+ }
+ }, 13);
+ }
+ },
+
+ // Simple 'show' function
+ show: function(){
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
+ this.options.show = true;
+
+ // Begin the animation
+ // Make sure that we start at a small width/height to avoid any
+ // flash of content
+ this.custom(this.prop == "width" || this.prop == "height" ? 1 : 0, this.cur());
+
+ // Start by showing the element
+ jQuery(this.elem).show();
+ },
+
+ // Simple 'hide' function
+ hide: function(){
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
+ this.options.hide = true;
+
+ // Begin the animation
+ this.custom(this.cur(), 0);
+ },
+
+ // Each step of an animation
+ step: function(gotoEnd){
+ var t = now();
+
+ if ( gotoEnd || t >= this.options.duration + this.startTime ) {
+ this.now = this.end;
+ this.pos = this.state = 1;
+ this.update();
+
+ this.options.curAnim[ this.prop ] = true;
+
+ var done = true;
+ for ( var i in this.options.curAnim )
+ if ( this.options.curAnim[i] !== true )
+ done = false;
+
+ if ( done ) {
+ if ( this.options.display != null ) {
+ // Reset the overflow
+ this.elem.style.overflow = this.options.overflow;
+
+ // Reset the display
+ this.elem.style.display = this.options.display;
+ if ( jQuery.css(this.elem, "display") == "none" )
+ this.elem.style.display = "block";
+ }
+
+ // Hide the element if the "hide" operation was done
+ if ( this.options.hide )
+ jQuery(this.elem).hide();
+
+ // Reset the properties, if the item has been hidden or shown
+ if ( this.options.hide || this.options.show )
+ for ( var p in this.options.curAnim )
+ jQuery.attr(this.elem.style, p, this.options.orig[p]);
+
+ // Execute the complete function
+ this.options.complete.call( this.elem );
+ }
+
+ return false;
+ } else {
+ var n = t - this.startTime;
+ this.state = n / this.options.duration;
+
+ // Perform the easing function, defaults to swing
+ this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
+ this.now = this.start + ((this.end - this.start) * this.pos);
+
+ // Perform the next step of the animation
+ this.update();
+ }
+
+ return true;
+ }
+
+};
+
+jQuery.extend( jQuery.fx, {
+ speeds:{
+ slow: 600,
+ fast: 200,
+ // Default speed
+ _default: 400
+ },
+ step: {
+
+ opacity: function(fx){
+ jQuery.attr(fx.elem.style, "opacity", fx.now);
+ },
+
+ _default: function(fx){
+ if ( fx.elem.style && fx.elem.style[ fx.prop ] != null )
+ fx.elem.style[ fx.prop ] = fx.now + fx.unit;
+ else
+ fx.elem[ fx.prop ] = fx.now;
+ }
+ }
+});
+if ( document.documentElement["getBoundingClientRect"] )
+ jQuery.fn.offset = function() {
+ if ( !this[0] ) return { top: 0, left: 0 };
+ if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
+ var box = this[0].getBoundingClientRect(), doc = this[0].ownerDocument, body = doc.body, docElem = doc.documentElement,
+ clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
+ top = box.top + (self.pageYOffset || jQuery.boxModel && docElem.scrollTop || body.scrollTop ) - clientTop,
+ left = box.left + (self.pageXOffset || jQuery.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
+ return { top: top, left: left };
+ };
+else
+ jQuery.fn.offset = function() {
+ if ( !this[0] ) return { top: 0, left: 0 };
+ if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
+ jQuery.offset.initialized || jQuery.offset.initialize();
+
+ var elem = this[0], offsetParent = elem.offsetParent, prevOffsetParent = elem,
+ doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
+ body = doc.body, defaultView = doc.defaultView,
+ prevComputedStyle = defaultView.getComputedStyle(elem, null),
+ top = elem.offsetTop, left = elem.offsetLeft;
+
+ while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
+ computedStyle = defaultView.getComputedStyle(elem, null);
+ top -= elem.scrollTop, left -= elem.scrollLeft;
+ if ( elem === offsetParent ) {
+ top += elem.offsetTop, left += elem.offsetLeft;
+ if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.tagName)) )
+ top += parseInt( computedStyle.borderTopWidth, 10) || 0,
+ left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
+ prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
+ }
+ if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" )
+ top += parseInt( computedStyle.borderTopWidth, 10) || 0,
+ left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
+ prevComputedStyle = computedStyle;
+ }
+
+ if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" )
+ top += body.offsetTop,
+ left += body.offsetLeft;
+
+ if ( prevComputedStyle.position === "fixed" )
+ top += Math.max(docElem.scrollTop, body.scrollTop),
+ left += Math.max(docElem.scrollLeft, body.scrollLeft);
+
+ return { top: top, left: left };
+ };
+
+jQuery.offset = {
+ initialize: function() {
+ if ( this.initialized ) return;
+ var body = document.body, container = document.createElement('div'), innerDiv, checkDiv, table, td, rules, prop, bodyMarginTop = body.style.marginTop,
+ html = '<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';
+
+ rules = { position: 'absolute', top: 0, left: 0, margin: 0, border: 0, width: '1px', height: '1px', visibility: 'hidden' };
+ for ( prop in rules ) container.style[prop] = rules[prop];
+
+ container.innerHTML = html;
+ body.insertBefore(container, body.firstChild);
+ innerDiv = container.firstChild, checkDiv = innerDiv.firstChild, td = innerDiv.nextSibling.firstChild.firstChild;
+
+ this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
+ this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
+
+ innerDiv.style.overflow = 'hidden', innerDiv.style.position = 'relative';
+ this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
+
+ body.style.marginTop = '1px';
+ this.doesNotIncludeMarginInBodyOffset = (body.offsetTop === 0);
+ body.style.marginTop = bodyMarginTop;
+
+ body.removeChild(container);
+ this.initialized = true;
+ },
+
+ bodyOffset: function(body) {
+ jQuery.offset.initialized || jQuery.offset.initialize();
+ var top = body.offsetTop, left = body.offsetLeft;
+ if ( jQuery.offset.doesNotIncludeMarginInBodyOffset )
+ top += parseInt( jQuery.curCSS(body, 'marginTop', true), 10 ) || 0,
+ left += parseInt( jQuery.curCSS(body, 'marginLeft', true), 10 ) || 0;
+ return { top: top, left: left };
+ }
+};
+
+
+jQuery.fn.extend({
+ position: function() {
+ var left = 0, top = 0, results;
+
+ if ( this[0] ) {
+ // Get *real* offsetParent
+ var offsetParent = this.offsetParent(),
+
+ // Get correct offsets
+ offset = this.offset(),
+ parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
+
+ // Subtract element margins
+ // note: when an element has margin: auto the offsetLeft and marginLeft
+ // are the same in Safari causing offset.left to incorrectly be 0
+ offset.top -= num( this, 'marginTop' );
+ offset.left -= num( this, 'marginLeft' );
+
+ // Add offsetParent borders
+ parentOffset.top += num( offsetParent, 'borderTopWidth' );
+ parentOffset.left += num( offsetParent, 'borderLeftWidth' );
+
+ // Subtract the two offsets
+ results = {
+ top: offset.top - parentOffset.top,
+ left: offset.left - parentOffset.left
+ };
+ }
+
+ return results;
+ },
+
+ offsetParent: function() {
+ var offsetParent = this[0].offsetParent || document.body;
+ while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') )
+ offsetParent = offsetParent.offsetParent;
+ return jQuery(offsetParent);
+ }
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( ['Left', 'Top'], function(i, name) {
+ var method = 'scroll' + name;
+
+ jQuery.fn[ method ] = function(val) {
+ if (!this[0]) return null;
+
+ return val !== undefined ?
+
+ // Set the scroll offset
+ this.each(function() {
+ this == window || this == document ?
+ window.scrollTo(
+ !i ? val : jQuery(window).scrollLeft(),
+ i ? val : jQuery(window).scrollTop()
+ ) :
+ this[ method ] = val;
+ }) :
+
+ // Return the scroll offset
+ this[0] == window || this[0] == document ?
+ self[ i ? 'pageYOffset' : 'pageXOffset' ] ||
+ jQuery.boxModel && document.documentElement[ method ] ||
+ document.body[ method ] :
+ this[0][ method ];
+ };
+});
+// Create innerHeight, innerWidth, outerHeight and outerWidth methods
+jQuery.each([ "Height", "Width" ], function(i, name){
+
+ var tl = i ? "Left" : "Top", // top or left
+ br = i ? "Right" : "Bottom", // bottom or right
+ lower = name.toLowerCase();
+
+ // innerHeight and innerWidth
+ jQuery.fn["inner" + name] = function(){
+ return this[0] ?
+ jQuery.css( this[0], lower, false, "padding" ) :
+ null;
+ };
+
+ // outerHeight and outerWidth
+ jQuery.fn["outer" + name] = function(margin) {
+ return this[0] ?
+ jQuery.css( this[0], lower, false, margin ? "margin" : "border" ) :
+ null;
+ };
+
+ var type = name.toLowerCase();
+
+ jQuery.fn[ type ] = function( size ) {
+ // Get window width or height
+ return this[0] == window ?
+ // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
+ document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] ||
+ document.body[ "client" + name ] :
+
+ // Get document width or height
+ this[0] == document ?
+ // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+ Math.max(
+ document.documentElement["client" + name],
+ document.body["scroll" + name], document.documentElement["scroll" + name],
+ document.body["offset" + name], document.documentElement["offset" + name]
+ ) :
+
+ // Get or set width or height on the element
+ size === undefined ?
+ // Get width or height on the element
+ (this.length ? jQuery.css( this[0], type ) : null) :
+
+ // Set the width or height on the element (default to pixels if value is unitless)
+ this.css( type, typeof size === "string" ? size : size + "px" );
+ };
+
+});
+})();
diff --git a/doc/html/_static/minus.png b/doc/html/_static/minus.png
new file mode 100644
index 0000000..da1c562
--- /dev/null
+++ b/doc/html/_static/minus.png
Binary files differ
diff --git a/doc/html/_static/plus.png b/doc/html/_static/plus.png
new file mode 100644
index 0000000..b3cb374
--- /dev/null
+++ b/doc/html/_static/plus.png
Binary files differ
diff --git a/doc/html/_static/pygments.css b/doc/html/_static/pygments.css
new file mode 100644
index 0000000..1f2d2b6
--- /dev/null
+++ b/doc/html/_static/pygments.css
@@ -0,0 +1,61 @@
+.hll { background-color: #ffffcc }
+.c { color: #408090; font-style: italic } /* Comment */
+.err { border: 1px solid #FF0000 } /* Error */
+.k { color: #007020; font-weight: bold } /* Keyword */
+.o { color: #666666 } /* Operator */
+.cm { color: #408090; font-style: italic } /* Comment.Multiline */
+.cp { color: #007020 } /* Comment.Preproc */
+.c1 { color: #408090; font-style: italic } /* Comment.Single */
+.cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
+.gd { color: #A00000 } /* Generic.Deleted */
+.ge { font-style: italic } /* Generic.Emph */
+.gr { color: #FF0000 } /* Generic.Error */
+.gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.gi { color: #00A000 } /* Generic.Inserted */
+.go { color: #303030 } /* Generic.Output */
+.gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
+.gs { font-weight: bold } /* Generic.Strong */
+.gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.gt { color: #0040D0 } /* Generic.Traceback */
+.kc { color: #007020; font-weight: bold } /* Keyword.Constant */
+.kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
+.kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
+.kp { color: #007020 } /* Keyword.Pseudo */
+.kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
+.kt { color: #902000 } /* Keyword.Type */
+.m { color: #208050 } /* Literal.Number */
+.s { color: #4070a0 } /* Literal.String */
+.na { color: #4070a0 } /* Name.Attribute */
+.nb { color: #007020 } /* Name.Builtin */
+.nc { color: #0e84b5; font-weight: bold } /* Name.Class */
+.no { color: #60add5 } /* Name.Constant */
+.nd { color: #555555; font-weight: bold } /* Name.Decorator */
+.ni { color: #d55537; font-weight: bold } /* Name.Entity */
+.ne { color: #007020 } /* Name.Exception */
+.nf { color: #06287e } /* Name.Function */
+.nl { color: #002070; font-weight: bold } /* Name.Label */
+.nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
+.nt { color: #062873; font-weight: bold } /* Name.Tag */
+.nv { color: #bb60d5 } /* Name.Variable */
+.ow { color: #007020; font-weight: bold } /* Operator.Word */
+.w { color: #bbbbbb } /* Text.Whitespace */
+.mf { color: #208050 } /* Literal.Number.Float */
+.mh { color: #208050 } /* Literal.Number.Hex */
+.mi { color: #208050 } /* Literal.Number.Integer */
+.mo { color: #208050 } /* Literal.Number.Oct */
+.sb { color: #4070a0 } /* Literal.String.Backtick */
+.sc { color: #4070a0 } /* Literal.String.Char */
+.sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
+.s2 { color: #4070a0 } /* Literal.String.Double */
+.se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
+.sh { color: #4070a0 } /* Literal.String.Heredoc */
+.si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
+.sx { color: #c65d09 } /* Literal.String.Other */
+.sr { color: #235388 } /* Literal.String.Regex */
+.s1 { color: #4070a0 } /* Literal.String.Single */
+.ss { color: #517918 } /* Literal.String.Symbol */
+.bp { color: #007020 } /* Name.Builtin.Pseudo */
+.vc { color: #bb60d5 } /* Name.Variable.Class */
+.vg { color: #bb60d5 } /* Name.Variable.Global */
+.vi { color: #bb60d5 } /* Name.Variable.Instance */
+.il { color: #208050 } /* Literal.Number.Integer.Long */ \ No newline at end of file
diff --git a/doc/html/_static/searchtools.js b/doc/html/_static/searchtools.js
new file mode 100644
index 0000000..e022625
--- /dev/null
+++ b/doc/html/_static/searchtools.js
@@ -0,0 +1,467 @@
+/**
+ * helper function to return a node containing the
+ * search summary for a given text. keywords is a list
+ * of stemmed words, hlwords is the list of normal, unstemmed
+ * words. the first one is used to find the occurance, the
+ * latter for highlighting it.
+ */
+
+jQuery.makeSearchSummary = function(text, keywords, hlwords) {
+ var textLower = text.toLowerCase();
+ var start = 0;
+ $.each(keywords, function() {
+ var i = textLower.indexOf(this.toLowerCase());
+ if (i > -1)
+ start = i;
+ });
+ start = Math.max(start - 120, 0);
+ var excerpt = ((start > 0) ? '...' : '') +
+ $.trim(text.substr(start, 240)) +
+ ((start + 240 - text.length) ? '...' : '');
+ var rv = $('<div class="context"></div>').text(excerpt);
+ $.each(hlwords, function() {
+ rv = rv.highlightText(this, 'highlight');
+ });
+ return rv;
+}
+
+/**
+ * Porter Stemmer
+ */
+var PorterStemmer = function() {
+
+ var step2list = {
+ ational: 'ate',
+ tional: 'tion',
+ enci: 'ence',
+ anci: 'ance',
+ izer: 'ize',
+ bli: 'ble',
+ alli: 'al',
+ entli: 'ent',
+ eli: 'e',
+ ousli: 'ous',
+ ization: 'ize',
+ ation: 'ate',
+ ator: 'ate',
+ alism: 'al',
+ iveness: 'ive',
+ fulness: 'ful',
+ ousness: 'ous',
+ aliti: 'al',
+ iviti: 'ive',
+ biliti: 'ble',
+ logi: 'log'
+ };
+
+ var step3list = {
+ icate: 'ic',
+ ative: '',
+ alize: 'al',
+ iciti: 'ic',
+ ical: 'ic',
+ ful: '',
+ ness: ''
+ };
+
+ var c = "[^aeiou]"; // consonant
+ var v = "[aeiouy]"; // vowel
+ var C = c + "[^aeiouy]*"; // consonant sequence
+ var V = v + "[aeiou]*"; // vowel sequence
+
+ var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
+ var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
+ var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
+ var s_v = "^(" + C + ")?" + v; // vowel in stem
+
+ this.stemWord = function (w) {
+ var stem;
+ var suffix;
+ var firstch;
+ var origword = w;
+
+ if (w.length < 3)
+ return w;
+
+ var re;
+ var re2;
+ var re3;
+ var re4;
+
+ firstch = w.substr(0,1);
+ if (firstch == "y")
+ w = firstch.toUpperCase() + w.substr(1);
+
+ // Step 1a
+ re = /^(.+?)(ss|i)es$/;
+ re2 = /^(.+?)([^s])s$/;
+
+ if (re.test(w))
+ w = w.replace(re,"$1$2");
+ else if (re2.test(w))
+ w = w.replace(re2,"$1$2");
+
+ // Step 1b
+ re = /^(.+?)eed$/;
+ re2 = /^(.+?)(ed|ing)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ re = new RegExp(mgr0);
+ if (re.test(fp[1])) {
+ re = /.$/;
+ w = w.replace(re,"");
+ }
+ }
+ else if (re2.test(w)) {
+ var fp = re2.exec(w);
+ stem = fp[1];
+ re2 = new RegExp(s_v);
+ if (re2.test(stem)) {
+ w = stem;
+ re2 = /(at|bl|iz)$/;
+ re3 = new RegExp("([^aeiouylsz])\\1$");
+ re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+ if (re2.test(w))
+ w = w + "e";
+ else if (re3.test(w)) {
+ re = /.$/;
+ w = w.replace(re,"");
+ }
+ else if (re4.test(w))
+ w = w + "e";
+ }
+ }
+
+ // Step 1c
+ re = /^(.+?)y$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = new RegExp(s_v);
+ if (re.test(stem))
+ w = stem + "i";
+ }
+
+ // Step 2
+ re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ suffix = fp[2];
+ re = new RegExp(mgr0);
+ if (re.test(stem))
+ w = stem + step2list[suffix];
+ }
+
+ // Step 3
+ re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ suffix = fp[2];
+ re = new RegExp(mgr0);
+ if (re.test(stem))
+ w = stem + step3list[suffix];
+ }
+
+ // Step 4
+ re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
+ re2 = /^(.+?)(s|t)(ion)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = new RegExp(mgr1);
+ if (re.test(stem))
+ w = stem;
+ }
+ else if (re2.test(w)) {
+ var fp = re2.exec(w);
+ stem = fp[1] + fp[2];
+ re2 = new RegExp(mgr1);
+ if (re2.test(stem))
+ w = stem;
+ }
+
+ // Step 5
+ re = /^(.+?)e$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = new RegExp(mgr1);
+ re2 = new RegExp(meq1);
+ re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+ if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
+ w = stem;
+ }
+ re = /ll$/;
+ re2 = new RegExp(mgr1);
+ if (re.test(w) && re2.test(w)) {
+ re = /.$/;
+ w = w.replace(re,"");
+ }
+
+ // and turn initial Y back to y
+ if (firstch == "y")
+ w = firstch.toLowerCase() + w.substr(1);
+ return w;
+ }
+}
+
+
+/**
+ * Search Module
+ */
+var Search = {
+
+ _index : null,
+ _queued_query : null,
+ _pulse_status : -1,
+
+ init : function() {
+ var params = $.getQueryParameters();
+ if (params.q) {
+ var query = params.q[0];
+ $('input[name="q"]')[0].value = query;
+ this.performSearch(query);
+ }
+ },
+
+ /**
+ * Sets the index
+ */
+ setIndex : function(index) {
+ var q;
+ this._index = index;
+ if ((q = this._queued_query) !== null) {
+ this._queued_query = null;
+ Search.query(q);
+ }
+ },
+
+ hasIndex : function() {
+ return this._index !== null;
+ },
+
+ deferQuery : function(query) {
+ this._queued_query = query;
+ },
+
+ stopPulse : function() {
+ this._pulse_status = 0;
+ },
+
+ startPulse : function() {
+ if (this._pulse_status >= 0)
+ return;
+ function pulse() {
+ Search._pulse_status = (Search._pulse_status + 1) % 4;
+ var dotString = '';
+ for (var i = 0; i < Search._pulse_status; i++)
+ dotString += '.';
+ Search.dots.text(dotString);
+ if (Search._pulse_status > -1)
+ window.setTimeout(pulse, 500);
+ };
+ pulse();
+ },
+
+ /**
+ * perform a search for something
+ */
+ performSearch : function(query) {
+ // create the required interface elements
+ this.out = $('#search-results');
+ this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
+ this.dots = $('<span></span>').appendTo(this.title);
+ this.status = $('<p style="display: none"></p>').appendTo(this.out);
+ this.output = $('<ul class="search"/>').appendTo(this.out);
+
+ $('#search-progress').text(_('Preparing search...'));
+ this.startPulse();
+
+ // index already loaded, the browser was quick!
+ if (this.hasIndex())
+ this.query(query);
+ else
+ this.deferQuery(query);
+ },
+
+ query : function(query) {
+ // stem the searchterms and add them to the
+ // correct list
+ var stemmer = new PorterStemmer();
+ var searchterms = [];
+ var excluded = [];
+ var hlterms = [];
+ var tmp = query.split(/\s+/);
+ var object = (tmp.length == 1) ? tmp[0].toLowerCase() : null;
+ for (var i = 0; i < tmp.length; i++) {
+ // stem the word
+ var word = stemmer.stemWord(tmp[i]).toLowerCase();
+ // select the correct list
+ if (word[0] == '-') {
+ var toAppend = excluded;
+ word = word.substr(1);
+ }
+ else {
+ var toAppend = searchterms;
+ hlterms.push(tmp[i].toLowerCase());
+ }
+ // only add if not already in the list
+ if (!$.contains(toAppend, word))
+ toAppend.push(word);
+ };
+ var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" "));
+
+ console.debug('SEARCH: searching for:');
+ console.info('required: ', searchterms);
+ console.info('excluded: ', excluded);
+
+ // prepare search
+ var filenames = this._index.filenames;
+ var titles = this._index.titles;
+ var terms = this._index.terms;
+ var descrefs = this._index.descrefs;
+ var modules = this._index.modules;
+ var desctypes = this._index.desctypes;
+ var fileMap = {};
+ var files = null;
+ var objectResults = [];
+ var regularResults = [];
+ $('#search-progress').empty();
+
+ // lookup as object
+ if (object != null) {
+ for (var module in modules) {
+ if (module.indexOf(object) > -1) {
+ fn = modules[module];
+ descr = _('module, in ') + titles[fn];
+ objectResults.push([filenames[fn], module, '#module-'+module, descr]);
+ }
+ }
+ for (var prefix in descrefs) {
+ for (var name in descrefs[prefix]) {
+ var fullname = (prefix ? prefix + '.' : '') + name;
+ if (fullname.toLowerCase().indexOf(object) > -1) {
+ match = descrefs[prefix][name];
+ descr = desctypes[match[1]] + _(', in ') + titles[match[0]];
+ objectResults.push([filenames[match[0]], fullname, '#'+fullname, descr]);
+ }
+ }
+ }
+ }
+
+ // sort results descending
+ objectResults.sort(function(a, b) {
+ return (a[1] > b[1]) ? -1 : ((a[1] < b[1]) ? 1 : 0);
+ });
+
+
+ // perform the search on the required terms
+ for (var i = 0; i < searchterms.length; i++) {
+ var word = searchterms[i];
+ // no match but word was a required one
+ if ((files = terms[word]) == null)
+ break;
+ if (files.length == undefined) {
+ files = [files];
+ }
+ // create the mapping
+ for (var j = 0; j < files.length; j++) {
+ var file = files[j];
+ if (file in fileMap)
+ fileMap[file].push(word);
+ else
+ fileMap[file] = [word];
+ }
+ }
+
+ // now check if the files don't contain excluded terms
+ for (var file in fileMap) {
+ var valid = true;
+
+ // check if all requirements are matched
+ if (fileMap[file].length != searchterms.length)
+ continue;
+
+ // ensure that none of the excluded terms is in the
+ // search result.
+ for (var i = 0; i < excluded.length; i++) {
+ if (terms[excluded[i]] == file ||
+ $.contains(terms[excluded[i]] || [], file)) {
+ valid = false;
+ break;
+ }
+ }
+
+ // if we have still a valid result we can add it
+ // to the result list
+ if (valid)
+ regularResults.push([filenames[file], titles[file], '', null]);
+ }
+
+ // delete unused variables in order to not waste
+ // memory until list is retrieved completely
+ delete filenames, titles, terms;
+
+ // now sort the regular results descending by title
+ regularResults.sort(function(a, b) {
+ var left = a[1].toLowerCase();
+ var right = b[1].toLowerCase();
+ return (left > right) ? -1 : ((left < right) ? 1 : 0);
+ });
+
+ // combine both
+ var results = regularResults.concat(objectResults);
+
+ // print the results
+ var resultCount = results.length;
+ function displayNextItem() {
+ // results left, load the summary and display it
+ if (results.length) {
+ var item = results.pop();
+ var listItem = $('<li style="display:none"></li>');
+ listItem.append($('<a/>').attr(
+ 'href',
+ item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
+ highlightstring + item[2]).html(item[1]));
+ if (item[3]) {
+ listItem.append($('<span> (' + item[3] + ')</span>'));
+ Search.output.append(listItem);
+ listItem.slideDown(5, function() {
+ displayNextItem();
+ });
+ } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
+ $.get('_sources/' + item[0] + '.txt', function(data) {
+ listItem.append($.makeSearchSummary(data, searchterms, hlterms));
+ Search.output.append(listItem);
+ listItem.slideDown(5, function() {
+ displayNextItem();
+ });
+ });
+ } else {
+ // no source available, just display title
+ Search.output.append(listItem);
+ listItem.slideDown(5, function() {
+ displayNextItem();
+ });
+ }
+ }
+ // search finished, update title and status message
+ else {
+ Search.stopPulse();
+ Search.title.text(_('Search Results'));
+ if (!resultCount)
+ Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
+ else
+ Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
+ Search.status.fadeIn(500);
+ }
+ }
+ displayNextItem();
+ }
+}
+
+$(document).ready(function() {
+ Search.init();
+});
diff --git a/doc/html/annotations.html b/doc/html/annotations.html
new file mode 100644
index 0000000..fc76524
--- /dev/null
+++ b/doc/html/annotations.html
@@ -0,0 +1,901 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>Annotations &mdash; SIP 4.10.5 Reference Guide</title>
+ <link rel="stylesheet" href="_static/default.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '#',
+ VERSION: '4.10.5',
+ COLLAPSE_MODINDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="top" title="SIP 4.10.5 Reference Guide" href="index.html" />
+ <link rel="next" title="C API for Handwritten Code" href="c_api.html" />
+ <link rel="prev" title="Directives" href="directives.html" />
+ </head>
+ <body>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ accesskey="M">modules</a> |</li>
+ <li class="right" >
+ <a href="c_api.html" title="C API for Handwritten Code"
+ accesskey="N">next</a> |</li>
+ <li class="right" >
+ <a href="directives.html" title="Directives"
+ accesskey="P">previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+ <div class="body">
+
+ <div class="section" id="annotations">
+<h1>Annotations<a class="headerlink" href="#annotations" title="Permalink to this headline">¶</a></h1>
+<p>In this section we describe each of the annotations that can be used in
+specification files.</p>
+<p>Annotations can either be <a class="reference internal" href="#ref-arg-annos"><em>argument annotations</em></a>,
+<a class="reference internal" href="#ref-class-annos"><em>class annotations</em></a>, <a class="reference internal" href="#ref-mapped-type-annos"><em>mapped type annotations</em></a>, <a class="reference internal" href="#ref-enum-annos"><em>enum annotations</em></a>,
+<a class="reference internal" href="#ref-exception-annos"><em>exception annotations</em></a>, <a class="reference internal" href="#ref-function-annos"><em>function annotations</em></a>, <a class="reference internal" href="#ref-license-annos"><em>license annotations</em></a>,
+<a class="reference internal" href="#ref-typedef-annos"><em>typedef annotations</em></a> or <a class="reference internal" href="#ref-variable-annos"><em>variable annotations</em></a> depending on the context in which they can be used.</p>
+<p>Annotations are placed between forward slashes (<tt class="docutils literal"><span class="pre">/</span></tt>). Multiple annotations
+are comma separated within the slashes.</p>
+<p>Annotations have a type and, possibly, a value. The type determines the
+format of the value. The name of an annotation and its value are separated by
+<tt class="docutils literal"><span class="pre">=</span></tt>.</p>
+<p>Annotations can have one of the following types:</p>
+<dl class="docutils">
+<dt><em>boolean</em></dt>
+<dd>This type of annotation has no value and is implicitly true.</dd>
+<dt><em>name</em></dt>
+<dd>The value is a name that is compatible with a C/C++ identifier. In some
+cases the value is optional.</dd>
+<dt><em>dotted name</em></dt>
+<dd>The value is a name that is compatible with an identifier preceded by a
+Python scope.</dd>
+<dt><em>string</em></dt>
+<dd>The value is a double quoted string.</dd>
+<dt><em>API range</em></dt>
+<dd><p class="first">The value is the name of an API (defined using the <a class="reference external" href="directives.html#directive-%API"><tt class="xref docutils literal"><span class="pre">%API</span></tt></a>
+directive) separated by a range of version numbers with a colon.</p>
+<p>The range of version numbers is a pair of numbers separated by a hyphen
+specifying the lower and upper bounds of the range. A version number is
+within the range if it is greater or equal to the lower bound and less
+than the upper bound. Each bound can be omitted meaning that the range is
+unbounded in that direction.</p>
+<p>For example:</p>
+<div class="last highlight-python"><pre># This is part of the PyQt4 API up to but excluding v2.
+void hex() /API=PyQt4:-2/
+
+# This is part of the PyQt4 API starting from v2.
+void hex() /PyName=hex_, API=PyQt4:2-/</pre>
+</div>
+</dd>
+</dl>
+<p>The following example shows argument and function annotations:</p>
+<div class="highlight-python"><pre>void exec(QWidget * /Transfer/) /ReleaseGIL, PyName=call_exec/;</pre>
+</div>
+<p>Note that the current version of SIP does not complain about unknown
+annotations, or annotations used out of their correct context.</p>
+<div class="section" id="argument-annotations">
+<span id="ref-arg-annos"></span><h2>Argument Annotations<a class="headerlink" href="#argument-annotations" title="Permalink to this headline">¶</a></h2>
+<dl class="argument-annotation">
+<dt id="aanno-AllowNone">
+<tt class="descname">AllowNone</tt><a class="headerlink" href="#aanno-AllowNone" title="Permalink to this definition">¶</a></dt>
+<dd>This boolean annotation specifies that the value of the corresponding
+argument (which should be either <a class="reference external" href="specification_files.html#stype-SIP_PYCALLABLE"><tt class="xref docutils literal"><span class="pre">SIP_PYCALLABLE</span></tt></a>,
+<a class="reference external" href="specification_files.html#stype-SIP_PYDICT"><tt class="xref docutils literal"><span class="pre">SIP_PYDICT</span></tt></a>, <a class="reference external" href="specification_files.html#stype-SIP_PYLIST"><tt class="xref docutils literal"><span class="pre">SIP_PYLIST</span></tt></a>, <a class="reference external" href="specification_files.html#stype-SIP_PYSLICE"><tt class="xref docutils literal"><span class="pre">SIP_PYSLICE</span></tt></a>,
+<a class="reference external" href="specification_files.html#stype-SIP_PYTUPLE"><tt class="xref docutils literal"><span class="pre">SIP_PYTUPLE</span></tt></a> or <a class="reference external" href="specification_files.html#stype-SIP_PYTYPE"><tt class="xref docutils literal"><span class="pre">SIP_PYTYPE</span></tt></a>) may be <tt class="xref docutils literal"><span class="pre">None</span></tt>.</dd></dl>
+
+<dl class="argument-annotation">
+<dt id="aanno-Array">
+<tt class="descname">Array</tt><a class="headerlink" href="#aanno-Array" title="Permalink to this definition">¶</a></dt>
+<dd><p>This boolean annotation specifies that the corresponding argument refers
+to an array.</p>
+<p>The argument should be either a pointer to a wrapped type, a <tt class="docutils literal"><span class="pre">char</span> <span class="pre">*</span></tt> or
+a <tt class="docutils literal"><span class="pre">unsigned</span> <span class="pre">char</span> <span class="pre">*</span></tt>. If the argument is a character array then the
+annotation also implies the <a class="reference internal" href="#aanno-Encoding"><tt class="xref docutils literal"><span class="pre">Encoding</span></tt></a> annotation with an encoding
+of <tt class="docutils literal"><span class="pre">&quot;None&quot;</span></tt>.</p>
+<p>There must be a corresponding argument with the <a class="reference internal" href="#aanno-ArraySize"><tt class="xref docutils literal"><span class="pre">ArraySize</span></tt></a>
+annotation specified. The annotation may only be specified once in a list
+of arguments.</p>
+</dd></dl>
+
+<dl class="argument-annotation">
+<dt id="aanno-ArraySize">
+<tt class="descname">ArraySize</tt><a class="headerlink" href="#aanno-ArraySize" title="Permalink to this definition">¶</a></dt>
+<dd>This boolean annotation specifies that the corresponding argument (which
+should be either <tt class="docutils literal"><span class="pre">short</span></tt>, <tt class="docutils literal"><span class="pre">unsigned</span> <span class="pre">short</span></tt>, <tt class="docutils literal"><span class="pre">int</span></tt>, <tt class="docutils literal"><span class="pre">unsigned</span></tt>,
+<tt class="docutils literal"><span class="pre">long</span></tt> or <tt class="docutils literal"><span class="pre">unsigned</span> <span class="pre">long</span></tt>) refers to the size of an array. There must
+be a corresponding argument with the <a class="reference internal" href="#aanno-Array"><tt class="xref docutils literal"><span class="pre">Array</span></tt></a> annotation specified.
+The annotation may only be specified once in a list of arguments.</dd></dl>
+
+<dl class="argument-annotation">
+<dt id="aanno-Constrained">
+<tt class="descname">Constrained</tt><a class="headerlink" href="#aanno-Constrained" title="Permalink to this definition">¶</a></dt>
+<dd><p>Python will automatically convert between certain compatible types. For
+example, if a floating pointer number is expected and an integer supplied,
+then the integer will be converted appropriately. This can cause problems
+when wrapping C or C++ functions with similar signatures. For example:</p>
+<div class="highlight-python"><pre>// The wrapper for this function will also accept an integer argument
+// which Python will automatically convert to a floating point number.
+void foo(double);
+
+// The wrapper for this function will never get used.
+void foo(int);</pre>
+</div>
+<p>This boolean annotation specifies that the corresponding argument (which
+should be either <tt class="docutils literal"><span class="pre">bool</span></tt>, <tt class="docutils literal"><span class="pre">int</span></tt>, <tt class="docutils literal"><span class="pre">float</span></tt>, <tt class="docutils literal"><span class="pre">double</span></tt>, <tt class="docutils literal"><span class="pre">enum</span></tt> or a
+wrapped class) must match the type without any automatic conversions. In
+the context of a wrapped class the invocation of any
+<a class="reference external" href="directives.html#directive-%ConvertToTypeCode"><tt class="xref docutils literal"><span class="pre">%ConvertToTypeCode</span></tt></a> is suppressed.</p>
+<p>The following example gets around the above problem:</p>
+<div class="highlight-python"><pre>// The wrapper for this function will only accept floating point
+// numbers.
+void foo(double /Constrained/);
+
+// The wrapper for this function will be used for anything that Python
+// can convert to an integer, except for floating point numbers.
+void foo(int);</pre>
+</div>
+</dd></dl>
+
+<dl class="argument-annotation">
+<dt id="aanno-DocType">
+<tt class="descname">DocType</tt><a class="headerlink" href="#aanno-DocType" title="Permalink to this definition">¶</a></dt>
+<dd><p>
+<span class="versionmodified">New in version 4.10.</span></p>
+<p>This string annotation specifies the type of the argument as it will appear
+in any generated docstrings. It is usually used with arguments of type
+<a class="reference external" href="specification_files.html#stype-SIP_PYOBJECT"><tt class="xref docutils literal"><span class="pre">SIP_PYOBJECT</span></tt></a> to provide a more specific type.</p>
+</dd></dl>
+
+<dl class="argument-annotation">
+<dt id="aanno-DocValue">
+<tt class="descname">DocValue</tt><a class="headerlink" href="#aanno-DocValue" title="Permalink to this definition">¶</a></dt>
+<dd><p>
+<span class="versionmodified">New in version 4.10.</span></p>
+<p>This string annotation specifies the default value of the argument as it
+will appear in any generated docstrings.</p>
+</dd></dl>
+
+<dl class="argument-annotation">
+<dt id="aanno-Encoding">
+<tt class="descname">Encoding</tt><a class="headerlink" href="#aanno-Encoding" title="Permalink to this definition">¶</a></dt>
+<dd><p>This string annotation specifies that the corresponding argument (which
+should be either <tt class="docutils literal"><span class="pre">char</span></tt>, <tt class="docutils literal"><span class="pre">const</span> <span class="pre">char</span></tt>, <tt class="docutils literal"><span class="pre">char</span> <span class="pre">*</span></tt> or <tt class="docutils literal"><span class="pre">const</span> <span class="pre">char</span> <span class="pre">*</span></tt>)
+refers to an encoded character or <tt class="docutils literal"><span class="pre">'\0'</span></tt> terminated encoded string with
+the specified encoding. The encoding can be either <tt class="docutils literal"><span class="pre">&quot;ASCII&quot;</span></tt>,
+<tt class="docutils literal"><span class="pre">&quot;Latin-1&quot;</span></tt>, <tt class="docutils literal"><span class="pre">&quot;UTF-8&quot;</span></tt> or <tt class="docutils literal"><span class="pre">&quot;None&quot;</span></tt>. An encoding of <tt class="docutils literal"><span class="pre">&quot;None&quot;</span></tt> means
+that the corresponding argument refers to an unencoded character or string.</p>
+<p>The default encoding is specified by the <a class="reference external" href="directives.html#directive-%DefaultEncoding"><tt class="xref docutils literal"><span class="pre">%DefaultEncoding</span></tt></a>
+directive. If the directive is not specified then <tt class="xref docutils literal"><span class="pre">None</span></tt> is used.</p>
+<p>Python v3 will use the <tt class="docutils literal"><span class="pre">bytes</span></tt> type to represent the argument if the
+encoding is <tt class="docutils literal"><span class="pre">&quot;None&quot;</span></tt> and the <tt class="docutils literal"><span class="pre">str</span></tt> type otherwise.</p>
+<p>Python v2 will use the <tt class="docutils literal"><span class="pre">str</span></tt> type to represent the argument if the
+encoding is <tt class="docutils literal"><span class="pre">&quot;None&quot;</span></tt> and the <tt class="docutils literal"><span class="pre">unicode</span></tt> type otherwise.</p>
+</dd></dl>
+
+<dl class="argument-annotation">
+<dt id="aanno-GetWrapper">
+<tt class="descname">GetWrapper</tt><a class="headerlink" href="#aanno-GetWrapper" title="Permalink to this definition">¶</a></dt>
+<dd><p>This boolean annotation is only ever used in conjunction with handwritten
+code specified with the <a class="reference external" href="directives.html#directive-%MethodCode"><tt class="xref docutils literal"><span class="pre">%MethodCode</span></tt></a> directive. It causes an
+extra variable to be generated for the corresponding argument which is a
+pointer to the Python object that wraps the argument.</p>
+<p>See the <a class="reference external" href="directives.html#directive-%MethodCode"><tt class="xref docutils literal"><span class="pre">%MethodCode</span></tt></a> directive for more detail.</p>
+</dd></dl>
+
+<dl class="argument-annotation">
+<dt id="aanno-In">
+<tt class="descname">In</tt><a class="headerlink" href="#aanno-In" title="Permalink to this definition">¶</a></dt>
+<dd><p>This boolean annotation is used to specify that the corresponding argument
+(which should be a pointer type) is used to pass a value to the function.</p>
+<p>For pointers to wrapped C structures or C++ class instances, <tt class="docutils literal"><span class="pre">char</span> <span class="pre">*</span></tt> and
+<tt class="docutils literal"><span class="pre">unsigned</span> <span class="pre">char</span> <span class="pre">*</span></tt> then this annotation is assumed unless the <a class="reference internal" href="#aanno-Out"><tt class="xref docutils literal"><span class="pre">Out</span></tt></a>
+annotation is specified.</p>
+<p>For pointers to other types then this annotation must be explicitly
+specified if required. The argument will be dereferenced to obtain the
+actual value.</p>
+<p>Both <a class="reference internal" href="#aanno-In"><tt class="xref docutils literal"><span class="pre">In</span></tt></a> and <a class="reference internal" href="#aanno-Out"><tt class="xref docutils literal"><span class="pre">Out</span></tt></a> may be specified for the same argument.</p>
+</dd></dl>
+
+<dl class="argument-annotation">
+<dt id="aanno-KeepReference">
+<tt class="descname">KeepReference</tt><a class="headerlink" href="#aanno-KeepReference" title="Permalink to this definition">¶</a></dt>
+<dd>This boolean annotation is used to specify that a reference to the
+corresponding argument should be kept to ensure that the object is not
+garbage collected. If the method is called again with a new argument then
+the reference to the previous argument is discarded. Note that ownership
+of the argument is not changed.</dd></dl>
+
+<dl class="argument-annotation">
+<dt id="aanno-NoCopy">
+<tt class="descname">NoCopy</tt><a class="headerlink" href="#aanno-NoCopy" title="Permalink to this definition">¶</a></dt>
+<dd><p>
+<span class="versionmodified">New in version 4.10.1.</span></p>
+<p>This boolean annotation is used with arguments of virtual methods that are
+a <tt class="docutils literal"><span class="pre">const</span></tt> reference to a class. Normally, if the class defines a copy
+constructor then a copy of the returned reference is automatically created
+and wrapped before being passed to a Python reimplementation of the method.
+The copy will be owned by Python. This means that the reimplementation may
+take a reference to the argument without having to make an explicit copy.</p>
+<p>If the annotation is specified then the copy is not made and the original
+reference is wrapped instead and will be owned by C++.</p>
+</dd></dl>
+
+<dl class="argument-annotation">
+<dt id="aanno-Out">
+<tt class="descname">Out</tt><a class="headerlink" href="#aanno-Out" title="Permalink to this definition">¶</a></dt>
+<dd><p>This boolean annotation is used to specify that the corresponding argument
+(which should be a pointer type) is used by the function to return a value
+as an element of a tuple.</p>
+<p>For pointers to wrapped C structures or C++ class instances, <tt class="docutils literal"><span class="pre">char</span> <span class="pre">*</span></tt> and
+<tt class="docutils literal"><span class="pre">unsigned</span> <span class="pre">char</span> <span class="pre">*</span></tt> then this annotation must be explicitly specified if
+required.</p>
+<p>For pointers to other types then this annotation is assumed unless the
+<a class="reference internal" href="#aanno-In"><tt class="xref docutils literal"><span class="pre">In</span></tt></a> annotation is specified.</p>
+<p>Both <a class="reference internal" href="#aanno-In"><tt class="xref docutils literal"><span class="pre">In</span></tt></a> and <a class="reference internal" href="#aanno-Out"><tt class="xref docutils literal"><span class="pre">Out</span></tt></a> may be specified for the same argument.</p>
+</dd></dl>
+
+<dl class="argument-annotation">
+<dt id="aanno-ResultSize">
+<tt class="descname">ResultSize</tt><a class="headerlink" href="#aanno-ResultSize" title="Permalink to this definition">¶</a></dt>
+<dd>This boolean annotation is used with functions or methods that return a
+<tt class="docutils literal"><span class="pre">void</span> <span class="pre">*</span></tt> or <tt class="docutils literal"><span class="pre">const</span> <span class="pre">void</span> <span class="pre">*</span></tt>. It identifies an argument that defines the
+size of the block of memory whose address is being returned. This allows
+the <tt class="docutils literal"><span class="pre">sip.voidptr</span></tt> object that wraps the address to support the Python
+buffer protocol and allows the memory to be read and updated when wrapped
+by the Python <tt class="docutils literal"><span class="pre">buffer()</span></tt> builtin.</dd></dl>
+
+<dl class="argument-annotation">
+<dt id="aanno-SingleShot">
+<tt class="descname">SingleShot</tt><a class="headerlink" href="#aanno-SingleShot" title="Permalink to this definition">¶</a></dt>
+<dd>This boolean annotation is used only with arguments of type
+<a class="reference external" href="specification_files.html#stype-SIP_RXOBJ_CON"><tt class="xref docutils literal"><span class="pre">SIP_RXOBJ_CON</span></tt></a> to specify that the signal connected to the slot
+will only ever be emitted once. This prevents a certain class of memory
+leaks.</dd></dl>
+
+<dl class="argument-annotation">
+<dt id="aanno-Transfer">
+<tt class="descname">Transfer</tt><a class="headerlink" href="#aanno-Transfer" title="Permalink to this definition">¶</a></dt>
+<dd><p>This boolean annotation is used to specify that ownership of the
+corresponding argument (which should be a wrapped C structure or C++ class
+instance) is transferred from Python to C++. In addition, if the argument
+is of a class method, then it is associated with the class instance with
+regard to the cyclic garbage collector.</p>
+<p>See <a class="reference external" href="using.html#ref-object-ownership"><em>Ownership of Objects</em></a> for more detail.</p>
+</dd></dl>
+
+<dl class="argument-annotation">
+<dt id="aanno-TransferBack">
+<tt class="descname">TransferBack</tt><a class="headerlink" href="#aanno-TransferBack" title="Permalink to this definition">¶</a></dt>
+<dd><p>This boolean annotation is used to specify that ownership of the
+corresponding argument (which should be a wrapped C structure or C++ class
+instance) is transferred back to Python from C++. In addition, any
+association of the argument with regard to the cyclic garbage collector
+with another instance is removed.</p>
+<p>See <a class="reference external" href="using.html#ref-object-ownership"><em>Ownership of Objects</em></a> for more detail.</p>
+</dd></dl>
+
+<dl class="argument-annotation">
+<dt id="aanno-TransferThis">
+<tt class="descname">TransferThis</tt><a class="headerlink" href="#aanno-TransferThis" title="Permalink to this definition">¶</a></dt>
+<dd><p>This boolean annotation is only used in C++ constructors or methods. In
+the context of a constructor or factory method it specifies that ownership
+of the instance being created is transferred from Python to C++ if the
+corresponding argument (which should be a wrapped C structure or C++ class
+instance) is not <tt class="xref docutils literal"><span class="pre">None</span></tt>. In addition, the newly created instance is
+associated with the argument with regard to the cyclic garbage collector.</p>
+<p>In the context of a non-factory method it specifies that ownership of
+<tt class="docutils literal"><span class="pre">this</span></tt> is transferred from Python to C++ if the corresponding argument is
+not <tt class="xref docutils literal"><span class="pre">None</span></tt>. If it is <tt class="xref docutils literal"><span class="pre">None</span></tt> then ownership is transferred to Python.</p>
+<p>The annotation may be used more that once, in which case ownership is
+transferred to last instance that is not <tt class="xref docutils literal"><span class="pre">None</span></tt>.</p>
+<p>See <a class="reference external" href="using.html#ref-object-ownership"><em>Ownership of Objects</em></a> for more detail.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="class-annotations">
+<span id="ref-class-annos"></span><h2>Class Annotations<a class="headerlink" href="#class-annotations" title="Permalink to this headline">¶</a></h2>
+<dl class="class-annotation">
+<dt id="canno-Abstract">
+<tt class="descname">Abstract</tt><a class="headerlink" href="#canno-Abstract" title="Permalink to this definition">¶</a></dt>
+<dd>This boolean annotation is used to specify that the class has additional
+pure virtual methods that have not been specified and so it cannot be
+instantiated or sub-classed from Python.</dd></dl>
+
+<dl class="class-annotation">
+<dt id="canno-AllowNone">
+<tt class="descname">AllowNone</tt><a class="headerlink" href="#canno-AllowNone" title="Permalink to this definition">¶</a></dt>
+<dd><p>
+<span class="versionmodified">New in version 4.8.2.</span></p>
+<p>Normally when a Python object is converted to a C/C++ instance <tt class="xref docutils literal"><span class="pre">None</span></tt>
+is handled automatically before the class&#8217;s
+<a class="reference external" href="directives.html#directive-%ConvertToTypeCode"><tt class="xref docutils literal"><span class="pre">%ConvertToTypeCode</span></tt></a> is called. This boolean annotation
+specifies that the handling of <tt class="xref docutils literal"><span class="pre">None</span></tt> will be left to the
+<a class="reference external" href="directives.html#directive-%ConvertToTypeCode"><tt class="xref docutils literal"><span class="pre">%ConvertToTypeCode</span></tt></a>. The annotation is ignored if the class
+does not have any <a class="reference external" href="directives.html#directive-%ConvertToTypeCode"><tt class="xref docutils literal"><span class="pre">%ConvertToTypeCode</span></tt></a>.</p>
+</dd></dl>
+
+<dl class="class-annotation">
+<dt id="canno-API">
+<tt class="descname">API</tt><a class="headerlink" href="#canno-API" title="Permalink to this definition">¶</a></dt>
+<dd><p>
+<span class="versionmodified">New in version 4.9.</span></p>
+<p>This API range annotation is used to specify an API and corresponding
+range of version numbers that the class is enabled for.</p>
+<p>If a class or mapped type has different implementations enabled for
+different ranges of version numbers then those ranges must not overlap.</p>
+<p>See <a class="reference external" href="using.html#ref-incompat-apis"><em>Managing Incompatible APIs</em></a> for more detail.</p>
+</dd></dl>
+
+<dl class="class-annotation">
+<dt id="canno-DelayDtor">
+<tt class="descname">DelayDtor</tt><a class="headerlink" href="#canno-DelayDtor" title="Permalink to this definition">¶</a></dt>
+<dd><p>This boolean annotation is used to specify that the class&#8217;s destructor
+should not be called until the Python interpreter exits. It would normally
+only be applied to singleton classes.</p>
+<p>When the Python interpreter exits the order in which any wrapped instances
+are garbage collected is unpredictable. However, the underlying C or C++
+instances may need to be destroyed in a certain order. If this annotation
+is specified then when the wrapped instance is garbage collected the C or
+C++ instance is not destroyed but instead added to a list of delayed
+instances. When the interpreter exits then the function
+<a title="sipDelayedDtors" class="reference internal" href="#sipDelayedDtors"><tt class="xref docutils literal"><span class="pre">sipDelayedDtors()</span></tt></a> is called with the list of delayed instances.
+<a title="sipDelayedDtors" class="reference internal" href="#sipDelayedDtors"><tt class="xref docutils literal"><span class="pre">sipDelayedDtors()</span></tt></a> can then choose to call (or ignore) the
+destructors in any desired order.</p>
+<p>The <a title="sipDelayedDtors" class="reference internal" href="#sipDelayedDtors"><tt class="xref docutils literal"><span class="pre">sipDelayedDtors()</span></tt></a> function must be specified using the
+<a class="reference external" href="directives.html#directive-%ModuleCode"><tt class="xref docutils literal"><span class="pre">%ModuleCode</span></tt></a> directive.</p>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipDelayedDtors">
+void <tt class="descname">sipDelayedDtors</tt><big>(</big>const <a title="sipDelayedDtor" class="reference internal" href="#sipDelayedDtor">sipDelayedDtor</a><em> *dd_list</em><big>)</big><a class="headerlink" href="#sipDelayedDtors" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>dd_list</em> &#8211; the linked list of delayed instances.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="ctype">
+<dt id="sipDelayedDtor">
+<tt class="descname">sipDelayedDtor</tt><a class="headerlink" href="#sipDelayedDtor" title="Permalink to this definition">¶</a></dt>
+<dd><p>This structure describes a particular delayed destructor.</p>
+<dl class="cmember">
+<dt id="dd_name">
+const char *<tt class="descname">dd_name</tt><a class="headerlink" href="#dd_name" title="Permalink to this definition">¶</a></dt>
+<dd>This is the name of the class excluding any package or module name.</dd></dl>
+
+<dl class="cmember">
+<dt id="dd_ptr">
+void *<tt class="descname">dd_ptr</tt><a class="headerlink" href="#dd_ptr" title="Permalink to this definition">¶</a></dt>
+<dd>This is the address of the C or C++ instance to be destroyed. It&#8217;s
+exact type depends on the value of <a title="dd_isderived" class="reference internal" href="#dd_isderived"><tt class="xref docutils literal"><span class="pre">dd_isderived</span></tt></a>.</dd></dl>
+
+<dl class="cmember">
+<dt id="dd_isderived">
+int <tt class="descname">dd_isderived</tt><a class="headerlink" href="#dd_isderived" title="Permalink to this definition">¶</a></dt>
+<dd>This is non-zero if the type of <a title="dd_ptr" class="reference internal" href="#dd_ptr"><tt class="xref docutils literal"><span class="pre">dd_ptr</span></tt></a> is actually the
+generated derived class. This allows the correct destructor to be
+called. See <a class="reference external" href="c_api.html#ref-derived-classes"><em>Generated Derived Classes</em></a>.</dd></dl>
+
+<dl class="cmember">
+<dt id="dd_next">
+<a title="sipDelayedDtor" class="reference internal" href="#sipDelayedDtor">sipDelayedDtor</a> *<tt class="descname">dd_next</tt><a class="headerlink" href="#dd_next" title="Permalink to this definition">¶</a></dt>
+<dd>This is the address of the next entry in the list or zero if this is
+the last one.</dd></dl>
+
+<p>Note that the above applies only to C and C++ instances that are owned by
+Python.</p>
+</dd></dl>
+
+<dl class="class-annotation">
+<dt id="canno-Deprecated">
+<tt class="descname">Deprecated</tt><a class="headerlink" href="#canno-Deprecated" title="Permalink to this definition">¶</a></dt>
+<dd>This boolean annotation is used to specify that the class is deprecated.
+It is the equivalent of annotating all the class&#8217;s constructors, function
+and methods as being deprecated.</dd></dl>
+
+<dl class="class-annotation">
+<dt id="canno-External">
+<tt class="descname">External</tt><a class="headerlink" href="#canno-External" title="Permalink to this definition">¶</a></dt>
+<dd>This boolean annotation is used to specify that the class is defined in
+another module. Declarations of external classes are private to the module
+in which they appear.</dd></dl>
+
+<dl class="class-annotation">
+<dt id="canno-Metatype">
+<tt class="descname">Metatype</tt><a class="headerlink" href="#canno-Metatype" title="Permalink to this definition">¶</a></dt>
+<dd><p>This dotted name annotation specifies the name of the Python type object
+(i.e. the value of the <tt class="docutils literal"><span class="pre">tp_name</span></tt> field) used as the meta-type used when
+creating the type object for this C structure or C++ type.</p>
+<p>See the section <a class="reference external" href="using.html#ref-types-metatypes"><em>Types and Meta-types</em></a> for more details.</p>
+</dd></dl>
+
+<dl class="class-annotation">
+<dt id="canno-NoDefaultCtors">
+<tt class="descname">NoDefaultCtors</tt><a class="headerlink" href="#canno-NoDefaultCtors" title="Permalink to this definition">¶</a></dt>
+<dd>This boolean annotation is used to suppress the automatic generation of
+default constructors for the class.</dd></dl>
+
+<dl class="class-annotation">
+<dt id="canno-PyName">
+<tt class="descname">PyName</tt><a class="headerlink" href="#canno-PyName" title="Permalink to this definition">¶</a></dt>
+<dd>This name annotation specifies an alternative name for the class being
+wrapped which is used when it is referred to from Python. It is required
+when a class name is the same as a Python keyword. It may also be used to
+avoid name clashes with other objects (e.g. enums, exceptions, functions)
+that have the same name in the same C++ scope.</dd></dl>
+
+<dl class="class-annotation">
+<dt id="canno-Supertype">
+<tt class="descname">Supertype</tt><a class="headerlink" href="#canno-Supertype" title="Permalink to this definition">¶</a></dt>
+<dd><p>This dotted name annotation specifies the name of the Python type object
+(i.e. the value of the <tt class="docutils literal"><span class="pre">tp_name</span></tt> field) used as the super-type used when
+creating the type object for this C structure or C++ type.</p>
+<p>See the section <a class="reference external" href="using.html#ref-types-metatypes"><em>Types and Meta-types</em></a> for more details.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="mapped-type-annotations">
+<span id="ref-mapped-type-annos"></span><h2>Mapped Type Annotations<a class="headerlink" href="#mapped-type-annotations" title="Permalink to this headline">¶</a></h2>
+<dl class="mapped-type-annotation">
+<dt id="manno-AllowNone">
+<tt class="descname">AllowNone</tt><a class="headerlink" href="#manno-AllowNone" title="Permalink to this definition">¶</a></dt>
+<dd>Normally when a Python object is converted to a C/C++ instance <tt class="xref docutils literal"><span class="pre">None</span></tt>
+is handled automatically before the mapped type&#8217;s
+<a class="reference external" href="directives.html#directive-%ConvertToTypeCode"><tt class="xref docutils literal"><span class="pre">%ConvertToTypeCode</span></tt></a> is called. This boolean annotation
+specifies that the handling of <tt class="xref docutils literal"><span class="pre">None</span></tt> will be left to the
+<a class="reference external" href="directives.html#directive-%ConvertToTypeCode"><tt class="xref docutils literal"><span class="pre">%ConvertToTypeCode</span></tt></a>.</dd></dl>
+
+<dl class="mapped-type-annotation">
+<dt id="manno-API">
+<tt class="descname">API</tt><a class="headerlink" href="#manno-API" title="Permalink to this definition">¶</a></dt>
+<dd><p>
+<span class="versionmodified">New in version 4.9.</span></p>
+<p>This API range annotation is used to specify an API and corresponding
+range of version numbers that the mapped type is enabled for.</p>
+<p>If a class or mapped type has different implementations enabled for
+different ranges of version numbers then those ranges must not overlap.</p>
+<p>See <a class="reference external" href="using.html#ref-incompat-apis"><em>Managing Incompatible APIs</em></a> for more detail.</p>
+</dd></dl>
+
+<dl class="mapped-type-annotation">
+<dt id="manno-DocType">
+<tt class="descname">DocType</tt><a class="headerlink" href="#manno-DocType" title="Permalink to this definition">¶</a></dt>
+<dd><p>
+<span class="versionmodified">New in version 4.10.</span></p>
+<p>This string annotation specifies the name of the type as it will appear in
+any generated docstrings.</p>
+</dd></dl>
+
+<dl class="mapped-type-annotation">
+<dt id="manno-NoRelease">
+<tt class="descname">NoRelease</tt><a class="headerlink" href="#manno-NoRelease" title="Permalink to this definition">¶</a></dt>
+<dd>This boolean annotation is used to specify that the mapped type does not
+support the <a title="sipReleaseType" class="reference external" href="c_api.html#sipReleaseType"><tt class="xref docutils literal"><span class="pre">sipReleaseType()</span></tt></a> function. Any
+<a class="reference external" href="directives.html#directive-%ConvertToTypeCode"><tt class="xref docutils literal"><span class="pre">%ConvertToTypeCode</span></tt></a> should not create temporary instances of
+the mapped type, i.e. it should not return <tt class="xref docutils literal"><span class="pre">SIP_TEMPORARY</span></tt>.</dd></dl>
+
+</div>
+<div class="section" id="enum-annotations">
+<span id="ref-enum-annos"></span><h2>Enum Annotations<a class="headerlink" href="#enum-annotations" title="Permalink to this headline">¶</a></h2>
+<dl class="enum-annotation">
+<dt id="eanno-PyName">
+<tt class="descname">PyName</tt><a class="headerlink" href="#eanno-PyName" title="Permalink to this definition">¶</a></dt>
+<dd>This name annotation specifies an alternative name for the enum or enum
+member being wrapped which is used when it is referred to from Python. It
+is required when an enum or enum member name is the same as a Python
+keyword. It may also be used to avoid name clashes with other objects
+(e.g. classes, exceptions, functions) that have the same name in the same
+C++ scope.</dd></dl>
+
+</div>
+<div class="section" id="exception-annotations">
+<span id="ref-exception-annos"></span><h2>Exception Annotations<a class="headerlink" href="#exception-annotations" title="Permalink to this headline">¶</a></h2>
+<dl class="exception-annotation">
+<dt id="xanno-Default">
+<tt class="descname">Default</tt><a class="headerlink" href="#xanno-Default" title="Permalink to this definition">¶</a></dt>
+<dd>This boolean annotation specifies that the exception being defined will be
+used as the default exception to be caught if a function or constructor
+does not have a <tt class="docutils literal"><span class="pre">throw</span></tt> clause.</dd></dl>
+
+<dl class="exception-annotation">
+<dt id="xanno-PyName">
+<tt class="descname">PyName</tt><a class="headerlink" href="#xanno-PyName" title="Permalink to this definition">¶</a></dt>
+<dd>This name annotation specifies an alternative name for the exception being
+defined which is used when it is referred to from Python. It is required
+when an exception name is the same as a Python keyword. It may also be
+used to avoid name clashes with other objects (e.g. classes, enums,
+functions) that have the same name.</dd></dl>
+
+</div>
+<div class="section" id="function-annotations">
+<span id="ref-function-annos"></span><h2>Function Annotations<a class="headerlink" href="#function-annotations" title="Permalink to this headline">¶</a></h2>
+<dl class="function-annotation">
+<dt id="fanno-API">
+<tt class="descname">API</tt><a class="headerlink" href="#fanno-API" title="Permalink to this definition">¶</a></dt>
+<dd><p>
+<span class="versionmodified">New in version 4.9.</span></p>
+<p>This API range annotation is used to specify an API and corresponding
+range of version numbers that the function is enabled for.</p>
+<p>See <a class="reference external" href="using.html#ref-incompat-apis"><em>Managing Incompatible APIs</em></a> for more detail.</p>
+</dd></dl>
+
+<dl class="function-annotation">
+<dt id="fanno-AutoGen">
+<tt class="descname">AutoGen</tt><a class="headerlink" href="#fanno-AutoGen" title="Permalink to this definition">¶</a></dt>
+<dd>This optional name annotation is used with class methods to specify that
+the method be automatically included in all sub-classes. The value is the
+name of a feature (specified using the <a class="reference external" href="directives.html#directive-%Feature"><tt class="xref docutils literal"><span class="pre">%Feature</span></tt></a> directive)
+which must be enabled for the method to be generated.</dd></dl>
+
+<dl class="function-annotation">
+<dt id="fanno-Default">
+<tt class="descname">Default</tt><a class="headerlink" href="#fanno-Default" title="Permalink to this definition">¶</a></dt>
+<dd>This boolean annotation is only used with C++ constructors. Sometimes SIP
+needs to create a class instance. By default it uses a constructor with no
+compulsory arguments if one is specified. (SIP will automatically generate
+a constructor with no arguments if no constructors are specified.) This
+annotation is used to explicitly specify which constructor to use. Zero is
+passed as the value of any arguments to the constructor.</dd></dl>
+
+<dl class="function-annotation">
+<dt id="fanno-Deprecated">
+<tt class="descname">Deprecated</tt><a class="headerlink" href="#fanno-Deprecated" title="Permalink to this definition">¶</a></dt>
+<dd>This boolean annotation is used to specify that the constructor or function
+is deprecated. A deprecation warning is issued whenever the constructor or
+function is called.</dd></dl>
+
+<dl class="function-annotation">
+<dt id="fanno-DocType">
+<tt class="descname">DocType</tt><a class="headerlink" href="#fanno-DocType" title="Permalink to this definition">¶</a></dt>
+<dd><p>
+<span class="versionmodified">New in version 4.10.</span></p>
+<p>This string annotation specifies the name of the type of the returned value
+as it will appear in any generated docstrings. It is usually used with
+values of type <a class="reference external" href="specification_files.html#stype-SIP_PYOBJECT"><tt class="xref docutils literal"><span class="pre">SIP_PYOBJECT</span></tt></a> to provide a more specific type.</p>
+</dd></dl>
+
+<dl class="function-annotation">
+<dt id="fanno-Factory">
+<tt class="descname">Factory</tt><a class="headerlink" href="#fanno-Factory" title="Permalink to this definition">¶</a></dt>
+<dd><p>This boolean annotation specifies that the value returned by the function
+(which should be a wrapped C structure or C++ class instance) is a newly
+created instance and is owned by Python.</p>
+<p>See <a class="reference external" href="using.html#ref-object-ownership"><em>Ownership of Objects</em></a> for more detail.</p>
+</dd></dl>
+
+<dl class="function-annotation">
+<dt id="fanno-HoldGIL">
+<tt class="descname">HoldGIL</tt><a class="headerlink" href="#fanno-HoldGIL" title="Permalink to this definition">¶</a></dt>
+<dd>This boolean annotation specifies that the Python Global Interpreter Lock
+(GIL) is not released before the call to the underlying C or C++ function.
+See <a class="reference external" href="using.html#ref-gil"><em>The Python Global Interpreter Lock</em></a> and the <a class="reference internal" href="#fanno-ReleaseGIL"><tt class="xref docutils literal"><span class="pre">ReleaseGIL</span></tt></a> annotation.</dd></dl>
+
+<dl class="function-annotation">
+<dt id="fanno-KeywordArgs">
+<tt class="descname">KeywordArgs</tt><a class="headerlink" href="#fanno-KeywordArgs" title="Permalink to this definition">¶</a></dt>
+<dd><p>
+<span class="versionmodified">New in version 4.10.</span></p>
+<p>This boolean annotation specifies that the argument parser generated for
+this function will support passing the parameters using Python&#8217;s keyword
+argument syntax. Keyword arguments cannot be used for functions that have
+unnamed arguments or use an ellipsis to designate that the function has a
+variable number of arguments.</p>
+</dd></dl>
+
+<dl class="function-annotation">
+<dt id="fanno-__len__">
+<tt class="descname">__len__</tt><a class="headerlink" href="#fanno-__len__" title="Permalink to this definition">¶</a></dt>
+<dd><p>
+<span class="versionmodified">New in version 4.10.3.</span></p>
+<p>This boolean annotation specifies that a <tt class="docutils literal"><span class="pre">__len__()</span></tt> method should be
+automatically generated that will use the method being annotated to compute
+the value that the <tt class="docutils literal"><span class="pre">__len__()</span></tt> method will return.</p>
+</dd></dl>
+
+<dl class="function-annotation">
+<dt id="fanno-NewThread">
+<tt class="descname">NewThread</tt><a class="headerlink" href="#fanno-NewThread" title="Permalink to this definition">¶</a></dt>
+<dd>This boolean annotation specifies that the function will create a new
+thread.</dd></dl>
+
+<dl class="function-annotation">
+<dt id="fanno-NoArgParser">
+<tt class="descname">NoArgParser</tt><a class="headerlink" href="#fanno-NoArgParser" title="Permalink to this definition">¶</a></dt>
+<dd>This boolean annotation is used with methods and global functions to
+specify that the supplied <a class="reference external" href="directives.html#directive-%MethodCode"><tt class="xref docutils literal"><span class="pre">%MethodCode</span></tt></a> will handle the parsing
+of the arguments.</dd></dl>
+
+<dl class="function-annotation">
+<dt id="fanno-NoCopy">
+<tt class="descname">NoCopy</tt><a class="headerlink" href="#fanno-NoCopy" title="Permalink to this definition">¶</a></dt>
+<dd><p>
+<span class="versionmodified">New in version 4.10.1.</span></p>
+<p>This boolean annotation is used with methods and global functions that
+return a <tt class="docutils literal"><span class="pre">const</span></tt> reference to a class. Normally, if the class defines a
+copy constructor then a copy of the returned reference is automatically
+created and wrapped. The copy will be owned by Python.</p>
+<p>If the annotation is specified then the copy is not made and the original
+reference is wrapped instead and will be owned by C++.</p>
+</dd></dl>
+
+<dl class="function-annotation">
+<dt id="fanno-NoDerived">
+<tt class="descname">NoDerived</tt><a class="headerlink" href="#fanno-NoDerived" title="Permalink to this definition">¶</a></dt>
+<dd>This boolean annotation is only used with C++ constructors. In many cases
+SIP generates a derived class for each class being wrapped (see
+<a class="reference external" href="c_api.html#ref-derived-classes"><em>Generated Derived Classes</em></a>). This derived class contains constructors with
+the same C++ signatures as the class being wrapped. Sometimes you may want
+to define a Python constructor that has no corresponding C++ constructor.
+This annotation is used to suppress the generation of the constructor in
+the derived class.</dd></dl>
+
+<dl class="function-annotation">
+<dt id="fanno-NoKeywordArgs">
+<tt class="descname">NoKeywordArgs</tt><a class="headerlink" href="#fanno-NoKeywordArgs" title="Permalink to this definition">¶</a></dt>
+<dd><p>
+<span class="versionmodified">New in version 4.10.</span></p>
+<p>This boolean annotation specifies that the argument parser generated for
+this function will not support passing the parameters using Python&#8217;s
+keyword argument syntax. In other words, the argument parser will only
+support only normal positional arguments. This annotation is useful when
+the default setting of allowing keyword arguments has been changed via the
+command line, but you would still like certain functions to only support
+positional arguments.</p>
+</dd></dl>
+
+<dl class="function-annotation">
+<dt id="fanno-Numeric">
+<tt class="descname">Numeric</tt><a class="headerlink" href="#fanno-Numeric" title="Permalink to this definition">¶</a></dt>
+<dd>This boolean annotation specifies that the operator should be interpreted
+as a numeric operator rather than a sequence operator. Python uses the
+<tt class="docutils literal"><span class="pre">+</span></tt> operator for adding numbers and concatanating sequences, and the
+<tt class="docutils literal"><span class="pre">*</span></tt> operator for multiplying numbers and repeating sequences. SIP tries
+to work out which is meant by looking at other operators that have been
+defined for the type. If it finds either <tt class="docutils literal"><span class="pre">-</span></tt>, <tt class="docutils literal"><span class="pre">-=</span></tt>, <tt class="docutils literal"><span class="pre">/</span></tt>, <tt class="docutils literal"><span class="pre">/=</span></tt>,
+<tt class="docutils literal"><span class="pre">%</span></tt> or <tt class="docutils literal"><span class="pre">%=</span></tt> defined then it assumes that <tt class="docutils literal"><span class="pre">+</span></tt>, <tt class="docutils literal"><span class="pre">+=</span></tt>, <tt class="docutils literal"><span class="pre">*</span></tt> and
+<tt class="docutils literal"><span class="pre">*=</span></tt> should be numeric operators. Otherwise, if it finds either <tt class="docutils literal"><span class="pre">[]</span></tt>,
+<tt class="xref docutils literal"><span class="pre">__getitem__()</span></tt>, <tt class="xref docutils literal"><span class="pre">__setitem__()</span></tt> or <tt class="xref docutils literal"><span class="pre">__delitem__()</span></tt> defined
+then it assumes that they should be sequence operators. This annotation is
+used to force SIP to treat the operator as numeric.</dd></dl>
+
+<dl class="function-annotation">
+<dt id="fanno-PostHook">
+<tt class="descname">PostHook</tt><a class="headerlink" href="#fanno-PostHook" title="Permalink to this definition">¶</a></dt>
+<dd>This name annotation is used to specify the name of a Python builtin that
+is called immediately after the call to the underlying C or C++ function or
+any handwritten code. The builtin is not called if an error occurred. It
+is primarily used to integrate with debuggers.</dd></dl>
+
+<dl class="function-annotation">
+<dt id="fanno-PreHook">
+<tt class="descname">PreHook</tt><a class="headerlink" href="#fanno-PreHook" title="Permalink to this definition">¶</a></dt>
+<dd>This name annotation is used to specify the name of a Python builtin that
+is called immediately after the function&#8217;s arguments have been successfully
+parsed and before the call to the underlying C or C++ function or any
+handwritten code. It is primarily used to integrate with debuggers.</dd></dl>
+
+<dl class="function-annotation">
+<dt id="fanno-PyName">
+<tt class="descname">PyName</tt><a class="headerlink" href="#fanno-PyName" title="Permalink to this definition">¶</a></dt>
+<dd>This name annotation specifies an alternative name for the function being
+wrapped which is used when it is referred to from Python. It is required
+when a function or method name is the same as a Python keyword. It may
+also be used to avoid name clashes with other objects (e.g. classes, enums,
+exceptions) that have the same name in the same C++ scope.</dd></dl>
+
+<dl class="function-annotation">
+<dt id="fanno-ReleaseGIL">
+<tt class="descname">ReleaseGIL</tt><a class="headerlink" href="#fanno-ReleaseGIL" title="Permalink to this definition">¶</a></dt>
+<dd>This boolean annotation specifies that the Python Global Interpreter Lock
+(GIL) is released before the call to the underlying C or C++ function and
+reacquired afterwards. It should be used for functions that might block or
+take a significant amount of time to execute. See <a class="reference external" href="using.html#ref-gil"><em>The Python Global Interpreter Lock</em></a> and the
+<a class="reference internal" href="#fanno-HoldGIL"><tt class="xref docutils literal"><span class="pre">HoldGIL</span></tt></a> annotation.</dd></dl>
+
+<dl class="function-annotation">
+<dt id="fanno-Transfer">
+<tt class="descname">Transfer</tt><a class="headerlink" href="#fanno-Transfer" title="Permalink to this definition">¶</a></dt>
+<dd><p>This boolean annotation specifies that ownership of the value returned by
+the function (which should be a wrapped C structure or C++ class instance)
+is transferred to C++. It is only used in the context of a class
+constructor or a method.</p>
+<p>In the case of methods returned values (unless they are new references to
+already wrapped values) are normally owned by C++ anyway. However, in
+addition, an association between the returned value and the instance
+containing the method is created with regard to the cyclic garbage
+collector.</p>
+<p>See <a class="reference external" href="using.html#ref-object-ownership"><em>Ownership of Objects</em></a> for more detail.</p>
+</dd></dl>
+
+<dl class="function-annotation">
+<dt id="fanno-TransferBack">
+<tt class="descname">TransferBack</tt><a class="headerlink" href="#fanno-TransferBack" title="Permalink to this definition">¶</a></dt>
+<dd><p>This boolean annotation specifies that ownership of the value returned by
+the function (which should be a wrapped C structure or C++ class instance)
+is transferred back to Python from C++. Normally returned values (unless
+they are new references to already wrapped values) are owned by C++. In
+addition, any association of the returned value with regard to the cyclic
+garbage collector with another instance is removed.</p>
+<p>See <a class="reference external" href="using.html#ref-object-ownership"><em>Ownership of Objects</em></a> for more detail.</p>
+</dd></dl>
+
+<dl class="function-annotation">
+<dt id="fanno-TransferThis">
+<tt class="descname">TransferThis</tt><a class="headerlink" href="#fanno-TransferThis" title="Permalink to this definition">¶</a></dt>
+<dd><p>This boolean annotation specifies that ownership of <tt class="docutils literal"><span class="pre">this</span></tt> is transferred
+from Python to C++.</p>
+<p>See <a class="reference external" href="using.html#ref-object-ownership"><em>Ownership of Objects</em></a> for more detail.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="license-annotations">
+<span id="ref-license-annos"></span><h2>License Annotations<a class="headerlink" href="#license-annotations" title="Permalink to this headline">¶</a></h2>
+<dl class="license-annotation">
+<dt id="lanno-Licensee">
+<tt class="descname">Licensee</tt><a class="headerlink" href="#lanno-Licensee" title="Permalink to this definition">¶</a></dt>
+<dd><p>This optional string annotation specifies the license&#8217;s licensee. No
+restrictions are placed on the contents of the string.</p>
+<p>See the <a class="reference external" href="directives.html#directive-%License"><tt class="xref docutils literal"><span class="pre">%License</span></tt></a> directive.</p>
+</dd></dl>
+
+<dl class="license-annotation">
+<dt id="lanno-Signature">
+<tt class="descname">Signature</tt><a class="headerlink" href="#lanno-Signature" title="Permalink to this definition">¶</a></dt>
+<dd><p>This optional string annotation specifies the license&#8217;s signature. No
+restrictions are placed on the contents of the string.</p>
+<p>See the <a class="reference external" href="directives.html#directive-%License"><tt class="xref docutils literal"><span class="pre">%License</span></tt></a> directive.</p>
+</dd></dl>
+
+<dl class="license-annotation">
+<dt id="lanno-Timestamp">
+<tt class="descname">Timestamp</tt><a class="headerlink" href="#lanno-Timestamp" title="Permalink to this definition">¶</a></dt>
+<dd><p>This optional string annotation specifies the license&#8217;s timestamp. No
+restrictions are placed on the contents of the string.</p>
+<p>See the <a class="reference external" href="directives.html#directive-%License"><tt class="xref docutils literal"><span class="pre">%License</span></tt></a> directive.</p>
+</dd></dl>
+
+<dl class="license-annotation">
+<dt id="lanno-Type">
+<tt class="descname">Type</tt><a class="headerlink" href="#lanno-Type" title="Permalink to this definition">¶</a></dt>
+<dd><p>This string annotation specifies the license&#8217;s type. No restrictions are
+placed on the contents of the string.</p>
+<p>See the <a class="reference external" href="directives.html#directive-%License"><tt class="xref docutils literal"><span class="pre">%License</span></tt></a> directive.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="typedef-annotations">
+<span id="ref-typedef-annos"></span><h2>Typedef Annotations<a class="headerlink" href="#typedef-annotations" title="Permalink to this headline">¶</a></h2>
+<dl class="typedef-annotation">
+<dt id="tanno-NoTypeName">
+<tt class="descname">NoTypeName</tt><a class="headerlink" href="#tanno-NoTypeName" title="Permalink to this definition">¶</a></dt>
+<dd><p>This boolean annotation specifies that the definition of the type rather
+than the name of the type being defined should be used in the generated
+code.</p>
+<p>Normally a typedef would be defined as follows:</p>
+<div class="highlight-python"><pre>typedef bool MyBool;</pre>
+</div>
+<p>This would result in <tt class="docutils literal"><span class="pre">MyBool</span></tt> being used in the generated code.</p>
+<p>Specifying the annotation means that <tt class="docutils literal"><span class="pre">bool</span></tt> will be used in the generated
+code instead.</p>
+</dd></dl>
+
+</div>
+<div class="section" id="variable-annotations">
+<span id="ref-variable-annos"></span><h2>Variable Annotations<a class="headerlink" href="#variable-annotations" title="Permalink to this headline">¶</a></h2>
+<dl class="variable-annotation">
+<dt id="vanno-DocType">
+<tt class="descname">DocType</tt><a class="headerlink" href="#vanno-DocType" title="Permalink to this definition">¶</a></dt>
+<dd><p>
+<span class="versionmodified">New in version 4.10.</span></p>
+<p>This string annotation specifies the name of the type of the variable as it
+will appear in any generated docstrings. It is usually used with variables
+of type <a class="reference external" href="specification_files.html#stype-SIP_PYOBJECT"><tt class="xref docutils literal"><span class="pre">SIP_PYOBJECT</span></tt></a> to provide a more specific type.</p>
+</dd></dl>
+
+<dl class="variable-annotation">
+<dt id="vanno-PyName">
+<tt class="descname">PyName</tt><a class="headerlink" href="#vanno-PyName" title="Permalink to this definition">¶</a></dt>
+<dd>This name annotation specifies an alternative name for the variable being
+wrapped which is used when it is referred to from Python. It is required
+when a variable name is the same as a Python keyword. It may also be used
+to avoid name clashes with other objects (e.g. classes, functions) that
+have the same name in the same C++ scope.</dd></dl>
+
+</div>
+</div>
+
+
+ </div>
+ </div>
+ </div>
+ <div class="sphinxsidebar">
+ <div class="sphinxsidebarwrapper">
+ <h3><a href="index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference external" href="#">Annotations</a><ul>
+<li><a class="reference external" href="#argument-annotations">Argument Annotations</a></li>
+<li><a class="reference external" href="#class-annotations">Class Annotations</a></li>
+<li><a class="reference external" href="#mapped-type-annotations">Mapped Type Annotations</a></li>
+<li><a class="reference external" href="#enum-annotations">Enum Annotations</a></li>
+<li><a class="reference external" href="#exception-annotations">Exception Annotations</a></li>
+<li><a class="reference external" href="#function-annotations">Function Annotations</a></li>
+<li><a class="reference external" href="#license-annotations">License Annotations</a></li>
+<li><a class="reference external" href="#typedef-annotations">Typedef Annotations</a></li>
+<li><a class="reference external" href="#variable-annotations">Variable Annotations</a></li>
+</ul>
+</li>
+</ul>
+
+ <h4>Previous topic</h4>
+ <p class="topless"><a href="directives.html"
+ title="previous chapter">Directives</a></p>
+ <h4>Next topic</h4>
+ <p class="topless"><a href="c_api.html"
+ title="next chapter">C API for Handwritten Code</a></p>
+ <div id="searchbox" style="display: none">
+ <h3>Quick search</h3>
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" size="18" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ <p class="searchtip" style="font-size: 90%">
+ Enter search terms or a module, class or function name.
+ </p>
+ </div>
+ <script type="text/javascript">$('#searchbox').show(0);</script>
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ >modules</a> |</li>
+ <li class="right" >
+ <a href="c_api.html" title="C API for Handwritten Code"
+ >next</a> |</li>
+ <li class="right" >
+ <a href="directives.html" title="Directives"
+ >previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+ <div class="footer">
+ &copy; Copyright 2010 Riverbank Computing Limited.
+ Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.4.
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/build_system.html b/doc/html/build_system.html
new file mode 100644
index 0000000..11016d4
--- /dev/null
+++ b/doc/html/build_system.html
@@ -0,0 +1,1182 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>The Build System &mdash; SIP 4.10.5 Reference Guide</title>
+ <link rel="stylesheet" href="_static/default.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '#',
+ VERSION: '4.10.5',
+ COLLAPSE_MODINDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="top" title="SIP 4.10.5 Reference Guide" href="index.html" />
+ <link rel="next" title="Building Your Extension with distutils" href="distutils.html" />
+ <link rel="prev" title="Python API for Applications" href="python_api.html" />
+ </head>
+ <body>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ accesskey="M">modules</a> |</li>
+ <li class="right" >
+ <a href="distutils.html" title="Building Your Extension with distutils"
+ accesskey="N">next</a> |</li>
+ <li class="right" >
+ <a href="python_api.html" title="Python API for Applications"
+ accesskey="P">previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+ <div class="body">
+
+ <div class="section" id="module-sipconfig">
+<span id="ref-build-system"></span><h1>The Build System<a class="headerlink" href="#module-sipconfig" title="Permalink to this headline">¶</a></h1>
+<p>The purpose of the build system is to make it easy for you to write
+configuration scripts in Python for your own bindings. The build system takes
+care of the details of particular combinations of platform and compiler. It
+supports over 50 different platform/compiler combinations.</p>
+<p>The build system is implemented as a pure Python module called <tt class="xref docutils literal"><span class="pre">sipconfig</span></tt>
+that contains a number of classes and functions. Using this module you can
+write bespoke configuration scripts (e.g. PyQt&#8217;s <tt class="docutils literal"><span class="pre">configure.py</span></tt>) or use it
+with other Python based build systems (e.g.
+<a class="reference external" href="http://www.python.org/sigs/distutils-sig/distutils.html">Distutils</a> and
+<a class="reference external" href="http://www.scons.org">SCons</a>).</p>
+<p>An important feature of SIP is the ability to generate bindings that are built
+on top of existing bindings. For example, both
+<a class="reference external" href="http://www.riverbankcomputing.com/software/pykde/">PyKDE</a> and
+<a class="reference external" href="http://pyqwt.sourceforge.net/">PyQwt</a> are built on top of PyQt but all three
+packages are maintained by different developers. To make this easier PyQt
+includes its own configuration module, <tt class="docutils literal"><span class="pre">pyqtconfig</span></tt>, that contains additional
+classes intended to be used by the configuration scripts of bindings built on
+top of PyQt. The SIP build system includes facilities that do a lot of the
+work of creating these additional configuration modules.</p>
+<dl class="function">
+<dt id="sipconfig.create_config_module">
+<tt class="descclassname">sipconfig.</tt><tt class="descname">create_config_module</tt><big>(</big><em>module</em>, <em>template</em>, <em>content</em><span class="optional">[</span>, <em>macros=None</em><span class="optional">]</span><big>)</big><a class="headerlink" href="#sipconfig.create_config_module" title="Permalink to this definition">¶</a></dt>
+<dd><p>This creates a configuration module (e.g. <tt class="docutils literal"><span class="pre">pyqtconfig</span></tt>) from a template
+file and a string.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><em>module</em> &#8211; the name of the configuration module file to create.</li>
+<li><em>template</em> &#8211; the name of the template file.</li>
+<li><em>content</em> &#8211; a string which replaces every occurence of the pattern
+<tt class="docutils literal"><span class="pre">&#64;SIP_CONFIGURATION&#64;</span></tt> in the template file. The content string is
+usually created from a Python dictionary using
+<a title="sipconfig.create_content" class="reference internal" href="#sipconfig.create_content"><tt class="xref docutils literal"><span class="pre">sipconfig.create_content()</span></tt></a>. <em>content</em> may also be a
+dictionary, in which case <a title="sipconfig.create_content" class="reference internal" href="#sipconfig.create_content"><tt class="xref docutils literal"><span class="pre">sipconfig.create_content()</span></tt></a> is
+automatically called to convert it to a string.</li>
+<li><em>macros</em> &#8211; an optional dictionary of platform specific build macros. It is only
+used if <a title="sipconfig.create_content" class="reference internal" href="#sipconfig.create_content"><tt class="xref docutils literal"><span class="pre">sipconfig.create_content()</span></tt></a> is called automatically to
+convert a <em>content</em> dictionary to a string.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="sipconfig.create_content">
+<tt class="descclassname">sipconfig.</tt><tt class="descname">create_content</tt><big>(</big><em>dict</em><span class="optional">[</span>, <em>macros=None</em><span class="optional">]</span><big>)</big> &rarr; string<a class="headerlink" href="#sipconfig.create_content" title="Permalink to this definition">¶</a></dt>
+<dd><p>This converts a Python dictionary to a string that can be parsed by the
+Python interpreter and converted back to an equivalent dictionary. It is
+typically used to generate the content string for
+<a title="sipconfig.create_config_module" class="reference internal" href="#sipconfig.create_config_module"><tt class="xref docutils literal"><span class="pre">sipconfig.create_config_module()</span></tt></a>.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>dict</em> &#8211; the Python dictionary to convert.</li>
+<li><em>macros</em> &#8211; the optional dictionary of platform specific build macros.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the string representation of the dictionary.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="sipconfig.create_wrapper">
+<tt class="descclassname">sipconfig.</tt><tt class="descname">create_wrapper</tt><big>(</big><em>script</em>, <em>wrapper</em><span class="optional">[</span>, <em>gui=0</em><span class="optional">[</span>, <em>use_arch=''</em><span class="optional">]</span><span class="optional">]</span><big>)</big> &rarr; string<a class="headerlink" href="#sipconfig.create_wrapper" title="Permalink to this definition">¶</a></dt>
+<dd><p>This creates a platform dependent executable wrapper around a Python
+script.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>script</em> &#8211; the full pathname of the script.</li>
+<li><em>wrapper</em> &#8211; the full pathname of the wrapper to create, excluding any platform
+specific extension.</li>
+<li><em>gui</em> &#8211; is non-zero if a GUI enabled version of the interpreter should be used
+on platforms that require it.</li>
+<li><em>use_arch</em> &#8211; is the MacOS/X architecture to invoke python with.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the platform specific name of the wrapper.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="sipconfig.error">
+<tt class="descclassname">sipconfig.</tt><tt class="descname">error</tt><big>(</big><em>msg</em><big>)</big><a class="headerlink" href="#sipconfig.error" title="Permalink to this definition">¶</a></dt>
+<dd><p>This displays an error message on <tt class="docutils literal"><span class="pre">stderr</span></tt> and calls <tt class="docutils literal"><span class="pre">sys.exit(1)</span></tt>.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>msg</em> &#8211; the text of the message and should not include any newline characters.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="sipconfig.format">
+<tt class="descclassname">sipconfig.</tt><tt class="descname">format</tt><big>(</big><em>msg</em><span class="optional">[</span>, <em>leftmargin=0</em><span class="optional">[</span>, <em>rightmargin=78</em><span class="optional">]</span><span class="optional">]</span><big>)</big> &rarr; string<a class="headerlink" href="#sipconfig.format" title="Permalink to this definition">¶</a></dt>
+<dd><p>This formats a message by inserting newline characters at appropriate
+places.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>msg</em> &#8211; the text of the message and should not include any newline characters.</li>
+<li><em>leftmargin</em> &#8211; the optional position of the left margin.</li>
+<li><em>rightmargin</em> &#8211; the optional position of the right margin.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the formatted message.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="sipconfig.inform">
+<tt class="descclassname">sipconfig.</tt><tt class="descname">inform</tt><big>(</big><em>msg</em><big>)</big><a class="headerlink" href="#sipconfig.inform" title="Permalink to this definition">¶</a></dt>
+<dd><p>This displays an information message on <tt class="docutils literal"><span class="pre">stdout</span></tt>.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>msg</em> &#8211; the text of the message and should not include any newline characters.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="sipconfig.parse_build_macros">
+<tt class="descclassname">sipconfig.</tt><tt class="descname">parse_build_macros</tt><big>(</big><em>filename</em>, <em>names</em><span class="optional">[</span>, <em>overrides=None</em><span class="optional">[</span>, <em>properties=None</em><span class="optional">]</span><span class="optional">]</span><big>)</big> &rarr; dict<a class="headerlink" href="#sipconfig.parse_build_macros" title="Permalink to this definition">¶</a></dt>
+<dd><p>This parses a <tt class="docutils literal"><span class="pre">qmake</span></tt> compatible file of build system macros and converts
+it to a dictionary. A macro is a name/value pair. Individual macros may
+be augmented or replaced.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>filename</em> &#8211; the name of the file to parse.</li>
+<li><em>names</em> &#8211; the list of the macro names to extract from the file.</li>
+<li><em>overrides</em> &#8211; the optional list of macro names and values that modify those found in
+the file. They are of the form <tt class="docutils literal"><span class="pre">name=value</span></tt> (in which case the value
+replaces the value found in the file) or <tt class="docutils literal"><span class="pre">name+=value</span></tt> (in which case
+the value is appended to the value found in the file).</li>
+<li><em>properties</em> &#8211; the optional dictionary of property name and values that are used to
+resolve any expressions of the form <tt class="docutils literal"><span class="pre">$[name]</span></tt> in the file.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the dictionary of parsed macros or <tt class="xref docutils literal"><span class="pre">None</span></tt> if any of the overrides
+were invalid.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="sipconfig.read_version">
+<tt class="descclassname">sipconfig.</tt><tt class="descname">read_version</tt><big>(</big><em>filename</em>, <em>description</em><span class="optional">[</span>, <em>numdefine=None</em><span class="optional">[</span>, <em>strdefine=None</em><span class="optional">]</span><span class="optional">]</span><big>)</big> &rarr; integer, string<a class="headerlink" href="#sipconfig.read_version" title="Permalink to this definition">¶</a></dt>
+<dd><p>This extracts version information for a package from a file, usually a C or
+C++ header file. The version information must each be specified as a
+<tt class="docutils literal"><span class="pre">#define</span></tt> of a numeric (hexadecimal or decimal) value and/or a string
+value.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>filename</em> &#8211; the name of the file to read.</li>
+<li><em>description</em> &#8211; a descriptive name of the package used in error messages.</li>
+<li><em>numdefine</em> &#8211; the optional name of the <tt class="docutils literal"><span class="pre">#define</span></tt> of the version as a number. If it
+is <tt class="xref docutils literal"><span class="pre">None</span></tt> then the numeric version is ignored.</li>
+<li><em>strdefine</em> &#8211; the optional name of the <tt class="docutils literal"><span class="pre">#define</span></tt> of the version as a string. If it
+is <tt class="xref docutils literal"><span class="pre">None</span></tt> then the string version is ignored.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">a tuple of the numeric and string versions. <a title="sipconfig.error" class="reference internal" href="#sipconfig.error"><tt class="xref docutils literal"><span class="pre">sipconfig.error()</span></tt></a>
+is called if either were required but could not be found.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="sipconfig.version_to_sip_tag">
+<tt class="descclassname">sipconfig.</tt><tt class="descname">version_to_sip_tag</tt><big>(</big><em>version</em>, <em>tags</em>, <em>description</em><big>)</big> &rarr; string<a class="headerlink" href="#sipconfig.version_to_sip_tag" title="Permalink to this definition">¶</a></dt>
+<dd><p>This converts a version number to a SIP version tag. SIP uses the
+<a class="reference external" href="directives.html#directive-%Timeline"><tt class="xref docutils literal"><span class="pre">%Timeline</span></tt></a> directive to define the chronology of the different
+versions of the C/C++ library being wrapped. Typically it is not necessary
+to define a version tag for every version of the library, but only for
+those versions that affect the library&#8217;s API as SIP sees it.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>version</em> &#8211; the numeric version number of the C/C++ library being wrapped. If it
+is negative then the latest version is assumed. (This is typically
+useful if a snapshot is indicated by a negative version number.)</li>
+<li><em>tags</em> &#8211; the dictionary of SIP version tags keyed by the corresponding C/C++
+library version number. The tag used is the one with the smallest key
+(i.e. earliest version) that is greater than <em>version</em>.</li>
+<li><em>description</em> &#8211; a descriptive name of the C/C++ library used in error messages.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the SIP version tag. <a title="sipconfig.error" class="reference internal" href="#sipconfig.error"><tt class="xref docutils literal"><span class="pre">sipconfig.error()</span></tt></a> is called if the C/C++
+library version number did not correspond to a SIP version tag.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="sipconfig.version_to_string">
+<tt class="descclassname">sipconfig.</tt><tt class="descname">version_to_string</tt><big>(</big><em>v</em><big>)</big> &rarr; string<a class="headerlink" href="#sipconfig.version_to_string" title="Permalink to this definition">¶</a></dt>
+<dd><p>This converts a 3 part version number encoded as a hexadecimal value to a
+string.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>v</em> &#8211; the version number.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">a string.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="class">
+<dt id="sipconfig.Configuration">
+<em class="property">class </em><tt class="descclassname">sipconfig.</tt><tt class="descname">Configuration</tt><a class="headerlink" href="#sipconfig.Configuration" title="Permalink to this definition">¶</a></dt>
+<dd><p>This class encapsulates configuration values that can be accessed as
+instance objects. A sub-class may provide a dictionary of additional
+configuration values in its constructor the elements of which will have
+precedence over the super-class&#8217;s values.</p>
+<p>The following configuration values are provided:</p>
+<dl class="attribute">
+<dt id="sipconfig.Configuration.default_bin_dir">
+<tt class="descname">default_bin_dir</tt><a class="headerlink" href="#sipconfig.Configuration.default_bin_dir" title="Permalink to this definition">¶</a></dt>
+<dd>The name of the directory where executables should be installed by
+default.</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Configuration.default_mod_dir">
+<tt class="descname">default_mod_dir</tt><a class="headerlink" href="#sipconfig.Configuration.default_mod_dir" title="Permalink to this definition">¶</a></dt>
+<dd>The name of the directory where SIP generated modules should be
+installed by default.</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Configuration.default_sip_dir">
+<tt class="descname">default_sip_dir</tt><a class="headerlink" href="#sipconfig.Configuration.default_sip_dir" title="Permalink to this definition">¶</a></dt>
+<dd>The name of the base directory where the <tt class="docutils literal"><span class="pre">.sip</span></tt> files for SIP
+generated modules should be installed by default. A sub-directory with
+the same name as the module should be created and its <tt class="docutils literal"><span class="pre">.sip</span></tt> files
+should be installed in the sub-directory. The <tt class="docutils literal"><span class="pre">.sip</span></tt> files only need
+to be installed if you might want to build other bindings based on
+them.</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Configuration.platform">
+<tt class="descname">platform</tt><a class="headerlink" href="#sipconfig.Configuration.platform" title="Permalink to this definition">¶</a></dt>
+<dd>The name of the platform/compiler for which the build system has been
+configured for.</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Configuration.py_conf_inc_dir">
+<tt class="descname">py_conf_inc_dir</tt><a class="headerlink" href="#sipconfig.Configuration.py_conf_inc_dir" title="Permalink to this definition">¶</a></dt>
+<dd>The name of the directory containing the <tt class="docutils literal"><span class="pre">pyconfig.h</span></tt> header file.</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Configuration.py_inc_dir">
+<tt class="descname">py_inc_dir</tt><a class="headerlink" href="#sipconfig.Configuration.py_inc_dir" title="Permalink to this definition">¶</a></dt>
+<dd>The name of the directory containing the <tt class="docutils literal"><span class="pre">Python.h</span></tt> header file.</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Configuration.py_lib_dir">
+<tt class="descname">py_lib_dir</tt><a class="headerlink" href="#sipconfig.Configuration.py_lib_dir" title="Permalink to this definition">¶</a></dt>
+<dd>The name of the directory containing the Python interpreter library.</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Configuration.py_version">
+<tt class="descname">py_version</tt><a class="headerlink" href="#sipconfig.Configuration.py_version" title="Permalink to this definition">¶</a></dt>
+<dd>The Python version as a 3 part hexadecimal number (e.g. v2.3.3 is
+represented as <tt class="docutils literal"><span class="pre">0x020303</span></tt>).</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Configuration.sip_bin">
+<tt class="descname">sip_bin</tt><a class="headerlink" href="#sipconfig.Configuration.sip_bin" title="Permalink to this definition">¶</a></dt>
+<dd>The full pathname of the SIP executable.</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Configuration.sip_config_args">
+<tt class="descname">sip_config_args</tt><a class="headerlink" href="#sipconfig.Configuration.sip_config_args" title="Permalink to this definition">¶</a></dt>
+<dd>The command line passed to <tt class="docutils literal"><span class="pre">configure.py</span></tt> when SIP was configured.</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Configuration.sip_inc_dir">
+<tt class="descname">sip_inc_dir</tt><a class="headerlink" href="#sipconfig.Configuration.sip_inc_dir" title="Permalink to this definition">¶</a></dt>
+<dd>The name of the directory containing the <tt class="docutils literal"><span class="pre">sip.h</span></tt> header file.</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Configuration.sip_mod_dir">
+<tt class="descname">sip_mod_dir</tt><a class="headerlink" href="#sipconfig.Configuration.sip_mod_dir" title="Permalink to this definition">¶</a></dt>
+<dd>The name of the directory containing the SIP module.</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Configuration.sip_version">
+<tt class="descname">sip_version</tt><a class="headerlink" href="#sipconfig.Configuration.sip_version" title="Permalink to this definition">¶</a></dt>
+<dd>The SIP version as a 3 part hexadecimal number (e.g. v4.0.0 is
+represented as <tt class="docutils literal"><span class="pre">0x040000</span></tt>).</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Configuration.sip_version_str">
+<tt class="descname">sip_version_str</tt><a class="headerlink" href="#sipconfig.Configuration.sip_version_str" title="Permalink to this definition">¶</a></dt>
+<dd>The SIP version as a string. For development snapshots it will start
+with <tt class="docutils literal"><span class="pre">snapshot-</span></tt>.</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Configuration.universal">
+<tt class="descname">universal</tt><a class="headerlink" href="#sipconfig.Configuration.universal" title="Permalink to this definition">¶</a></dt>
+<dd>The name of the MacOS/X SDK used when creating universal binaries.</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Configuration.arch">
+<tt class="descname">arch</tt><a class="headerlink" href="#sipconfig.Configuration.arch" title="Permalink to this definition">¶</a></dt>
+<dd>The space separated MacOS/X architectures to build.</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.Configuration.__init__">
+<tt class="descname">__init__</tt><big>(</big><span class="optional">[</span><em>sub_cfg=None</em><span class="optional">]</span><big>)</big><a class="headerlink" href="#sipconfig.Configuration.__init__" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>sub_cfg</em> &#8211; an optional list of sub-class configurations. It should only be
+used by the <tt class="docutils literal"><span class="pre">__init__()</span></tt> method of a sub-class to append its own
+dictionary of configuration values before passing the list to its
+super-class.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.Configuration.build_macros">
+<tt class="descname">build_macros</tt><big>(</big><big>)</big> &rarr; dict<a class="headerlink" href="#sipconfig.Configuration.build_macros" title="Permalink to this definition">¶</a></dt>
+<dd><p>Get the dictionary of platform specific build macros.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the macros dictionary.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.Configuration.set_build_macros">
+<tt class="descname">set_build_macros</tt><big>(</big><em>macros</em><big>)</big><a class="headerlink" href="#sipconfig.Configuration.set_build_macros" title="Permalink to this definition">¶</a></dt>
+<dd><p>Set the dictionary of platform specific build macros to be used when
+generating Makefiles. Normally there is no need to change the default
+macros.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>macros</em> &#8211; the macros dictionary.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="sipconfig.Makefile">
+<em class="property">class </em><tt class="descclassname">sipconfig.</tt><tt class="descname">Makefile</tt><a class="headerlink" href="#sipconfig.Makefile" title="Permalink to this definition">¶</a></dt>
+<dd><p>This class encapsulates a Makefile. It is intended to be sub-classed to
+generate Makefiles for particular purposes. It handles all platform and
+compiler specific flags, but allows them to be adjusted to suit the
+requirements of a particular module or program. These are defined using a
+number of macros which can be accessed as instance attributes.</p>
+<p>The following instance attributes are provided to help in fine tuning the
+generated Makefile:</p>
+<dl class="attribute">
+<dt id="sipconfig.Makefile.chkdir">
+<tt class="descname">chkdir</tt><a class="headerlink" href="#sipconfig.Makefile.chkdir" title="Permalink to this definition">¶</a></dt>
+<dd>A string that will check for the existence of a directory.</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Makefile.config">
+<tt class="descname">config</tt><a class="headerlink" href="#sipconfig.Makefile.config" title="Permalink to this definition">¶</a></dt>
+<dd>A reference to the <em>configuration</em> argument that was passed to
+<a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">Makefile.__init__()</span></tt></a>.</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Makefile.console">
+<tt class="descname">console</tt><a class="headerlink" href="#sipconfig.Makefile.console" title="Permalink to this definition">¶</a></dt>
+<dd>A reference to the <em>console</em> argument that was passed to the
+<a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">Makefile.__init__()</span></tt></a>.</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Makefile.copy">
+<tt class="descname">copy</tt><a class="headerlink" href="#sipconfig.Makefile.copy" title="Permalink to this definition">¶</a></dt>
+<dd>A string that will copy a file.</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Makefile.extra_cflags">
+<tt class="descname">extra_cflags</tt><a class="headerlink" href="#sipconfig.Makefile.extra_cflags" title="Permalink to this definition">¶</a></dt>
+<dd>A list of additional flags passed to the C compiler.</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Makefile.extra_cxxflags">
+<tt class="descname">extra_cxxflags</tt><a class="headerlink" href="#sipconfig.Makefile.extra_cxxflags" title="Permalink to this definition">¶</a></dt>
+<dd>A list of additional flags passed to the C++ compiler.</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Makefile.extra_defines">
+<tt class="descname">extra_defines</tt><a class="headerlink" href="#sipconfig.Makefile.extra_defines" title="Permalink to this definition">¶</a></dt>
+<dd>A list of additional macro names passed to the C/C++ preprocessor.</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Makefile.extra_include_dirs">
+<tt class="descname">extra_include_dirs</tt><a class="headerlink" href="#sipconfig.Makefile.extra_include_dirs" title="Permalink to this definition">¶</a></dt>
+<dd>A list of additional include directories passed to the C/C++
+preprocessor.</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Makefile.extra_lflags">
+<tt class="descname">extra_lflags</tt><a class="headerlink" href="#sipconfig.Makefile.extra_lflags" title="Permalink to this definition">¶</a></dt>
+<dd>A list of additional flags passed to the linker.</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Makefile.extra_lib_dirs">
+<tt class="descname">extra_lib_dirs</tt><a class="headerlink" href="#sipconfig.Makefile.extra_lib_dirs" title="Permalink to this definition">¶</a></dt>
+<dd>A list of additional library directories passed to the linker.</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Makefile.extra_libs">
+<tt class="descname">extra_libs</tt><a class="headerlink" href="#sipconfig.Makefile.extra_libs" title="Permalink to this definition">¶</a></dt>
+<dd>A list of additional libraries passed to the linker. The names of the
+libraries must be in platform neutral form (i.e. without any platform
+specific prefixes, version numbers or extensions).</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Makefile.generator">
+<tt class="descname">generator</tt><a class="headerlink" href="#sipconfig.Makefile.generator" title="Permalink to this definition">¶</a></dt>
+<dd>A string that defines the platform specific style of Makefile. The
+only supported values are <tt class="docutils literal"><span class="pre">UNIX</span></tt>, <tt class="docutils literal"><span class="pre">MSVC</span></tt>, <tt class="docutils literal"><span class="pre">MSVC.NET</span></tt>, <tt class="docutils literal"><span class="pre">MINGW</span></tt>
+and <tt class="docutils literal"><span class="pre">BMAKE</span></tt>.</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Makefile.mkdir">
+<tt class="descname">mkdir</tt><a class="headerlink" href="#sipconfig.Makefile.mkdir" title="Permalink to this definition">¶</a></dt>
+<dd>A string that will create a directory.</dd></dl>
+
+<dl class="attribute">
+<dt id="sipconfig.Makefile.rm">
+<tt class="descname">rm</tt><a class="headerlink" href="#sipconfig.Makefile.rm" title="Permalink to this definition">¶</a></dt>
+<dd>A string that will remove a file.</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.Makefile.__init__">
+<tt class="descname">__init__</tt><big>(</big><em>configuration</em><span class="optional">[</span>, <em>console=0</em><span class="optional">[</span>, <em>qt=0</em><span class="optional">[</span>, <em>opengl=0</em><span class="optional">[</span>, <em>python=0</em><span class="optional">[</span>, <em>threaded=0</em><span class="optional">[</span>, <em>warnings=None</em><span class="optional">[</span>, <em>debug=0</em><span class="optional">[</span>, <em>dir=None</em><span class="optional">[</span>, <em>makefile=&quot;Makefile&quot;</em><span class="optional">[</span>, <em>installs=None</em><span class="optional">[</span>, <em>universal=None</em><span class="optional">[</span>, <em>arch=None</em><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><big>)</big><a class="headerlink" href="#sipconfig.Makefile.__init__" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><em>configuration</em> &#8211; the current configuration and is an instance of the
+<a title="sipconfig.Configuration" class="reference internal" href="#sipconfig.Configuration"><tt class="xref docutils literal"><span class="pre">Configuration</span></tt></a> class or a sub-class.</li>
+<li><em>console</em> &#8211; is set if the target is a console (rather than GUI) target. This
+only affects Windows and is ignored on other platforms.</li>
+<li><em>qt</em> &#8211; is set if the target uses Qt. For Qt v4 a list of Qt libraries may
+be specified and a simple non-zero value implies QtCore and QtGui.</li>
+<li><em>opengl</em> &#8211; is set if the target uses OpenGL.</li>
+<li><em>python</em> &#8211; is set if the target uses Python.h.</li>
+<li><em>threaded</em> &#8211; is set if the target requires thread support. It is set
+automatically if the target uses Qt and Qt has thread support
+enabled.</li>
+<li><em>warnings</em> &#8211; is set if compiler warning messages should be enabled. The default
+of <tt class="xref docutils literal"><span class="pre">None</span></tt> means that warnings are enabled for SIP v4.x and
+disabled for SIP v3.x.</li>
+<li><em>debug</em> &#8211; is set if debugging symbols should be generated.</li>
+<li><em>dir</em> &#8211; the name of the directory where build files are read from (if they
+are not absolute file names) and Makefiles are written to. The
+default of <tt class="xref docutils literal"><span class="pre">None</span></tt> means the current directory is used.</li>
+<li><em>makefile</em> &#8211; the name of the generated Makefile.</li>
+<li><em>installs</em> &#8211; the list of extra install targets. Each element is a two part
+list, the first of which is the source and the second is the
+destination. If the source is another list then it is a list of
+source files and the destination is a directory.</li>
+<li><em>universal</em> &#8211; the name of the SDK if universal binaries are to be created under
+MacOS/X. If it is <tt class="xref docutils literal"><span class="pre">None</span></tt> then the value is taken from the
+configuration.</li>
+<li><em>arch</em> &#8211; the space separated MacOS/X architectures to build. If it is
+<tt class="xref docutils literal"><span class="pre">None</span></tt> then the value is taken from the configuration.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.Makefile.clean_build_file_objects">
+<tt class="descname">clean_build_file_objects</tt><big>(</big><em>mfile</em>, <em>build</em><big>)</big><a class="headerlink" href="#sipconfig.Makefile.clean_build_file_objects" title="Permalink to this definition">¶</a></dt>
+<dd><p>This generates the Makefile commands that will remove any files
+generated during the build of the default target.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><em>mfile</em> &#8211; the Python file object of the Makefile.</li>
+<li><em>build</em> &#8211; the dictionary created from parsing the build file.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.Makefile.finalise">
+<tt class="descname">finalise</tt><big>(</big><big>)</big><a class="headerlink" href="#sipconfig.Makefile.finalise" title="Permalink to this definition">¶</a></dt>
+<dd>This is called just before the Makefile is generated to ensure that it
+is fully configured. It must be reimplemented by a sub-class.</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.Makefile.generate">
+<tt class="descname">generate</tt><big>(</big><big>)</big><a class="headerlink" href="#sipconfig.Makefile.generate" title="Permalink to this definition">¶</a></dt>
+<dd>This generates the Makefile.</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.Makefile.generate_macros_and_rules">
+<tt class="descname">generate_macros_and_rules</tt><big>(</big><em>mfile</em><big>)</big><a class="headerlink" href="#sipconfig.Makefile.generate_macros_and_rules" title="Permalink to this definition">¶</a></dt>
+<dd><p>This is the default implementation of the Makefile macros and rules
+generation.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>mfile</em> &#8211; the Python file object of the Makefile.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.Makefile.generate_target_clean">
+<tt class="descname">generate_target_clean</tt><big>(</big><em>mfile</em><big>)</big><a class="headerlink" href="#sipconfig.Makefile.generate_target_clean" title="Permalink to this definition">¶</a></dt>
+<dd><p>This is the default implementation of the Makefile clean target
+generation.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>mfile</em> &#8211; the Python file object of the Makefile.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.Makefile.generate_target_default">
+<tt class="descname">generate_target_default</tt><big>(</big><em>mfile</em><big>)</big><a class="headerlink" href="#sipconfig.Makefile.generate_target_default" title="Permalink to this definition">¶</a></dt>
+<dd><p>This is the default implementation of the Makefile default target
+generation.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>mfile</em> &#8211; the Python file object of the Makefile.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.Makefile.generate_target_install">
+<tt class="descname">generate_target_install</tt><big>(</big><em>mfile</em><big>)</big><a class="headerlink" href="#sipconfig.Makefile.generate_target_install" title="Permalink to this definition">¶</a></dt>
+<dd><p>This is the default implementation of the Makefile install target
+generation.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>mfile</em> &#8211; the Python file object of the Makefile.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.Makefile.install_file">
+<tt class="descname">install_file</tt><big>(</big><em>mfile</em>, <em>src</em>, <em>dst</em><span class="optional">[</span>, <em>strip=0</em><span class="optional">]</span><big>)</big><a class="headerlink" href="#sipconfig.Makefile.install_file" title="Permalink to this definition">¶</a></dt>
+<dd><p>This generates the Makefile commands to install one or more files to a
+directory.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><em>mfile</em> &#8211; the Python file object of the Makefile.</li>
+<li><em>src</em> &#8211; the name of a single file to install or a list of a number of files
+to install.</li>
+<li><em>dst</em> &#8211; the name of the destination directory.</li>
+<li><em>strip</em> &#8211; is set if the files should be stripped of unneeded symbols after
+having been installed.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.Makefile.optional_list">
+<tt class="descname">optional_list</tt><big>(</big><em>name</em><big>)</big> &rarr; list<a class="headerlink" href="#sipconfig.Makefile.optional_list" title="Permalink to this definition">¶</a></dt>
+<dd><p>This returns an optional Makefile macro as a list.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>name</em> &#8211; the name of the macro.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the macro as a list.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.Makefile.optional_string">
+<tt class="descname">optional_string</tt><big>(</big><em>name</em><span class="optional">[</span>, <em>default=&quot;&quot;</em><span class="optional">]</span><big>)</big><a class="headerlink" href="#sipconfig.Makefile.optional_string" title="Permalink to this definition">¶</a></dt>
+<dd><p>This returns an optional Makefile macro as a string.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>name</em> &#8211; the name of the macro.</li>
+<li><em>default</em> &#8211; the optional default value of the macro.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the macro as a string.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.Makefile.parse_build_file">
+<tt class="descname">parse_build_file</tt><big>(</big><em>filename</em><big>)</big> &rarr; dict<a class="headerlink" href="#sipconfig.Makefile.parse_build_file" title="Permalink to this definition">¶</a></dt>
+<dd><p>This parses a build file (created with the <a class="reference external" href="command_line.html#cmdoption-sip-b"><em class="xref">-b</em></a> SIP
+command line option) and converts it to a dictionary. It can also
+validate an existing dictionary created through other means.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>filename</em> &#8211; is the name of the build file, or is a dictionary to
+be validated. A valid dictionary will contain the name of the
+target to build (excluding any platform specific extension) keyed
+by <tt class="docutils literal"><span class="pre">target</span></tt>; the names of all source files keyed by <tt class="docutils literal"><span class="pre">sources</span></tt>;
+and, optionally, the names of all header files keyed by
+<tt class="docutils literal"><span class="pre">headers</span></tt>.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">a dictionary corresponding to the parsed build file.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.Makefile.platform_lib">
+<tt class="descname">platform_lib</tt><big>(</big><em>clib</em><span class="optional">[</span>, <em>framework=0</em><span class="optional">]</span><big>)</big> &rarr; string<a class="headerlink" href="#sipconfig.Makefile.platform_lib" title="Permalink to this definition">¶</a></dt>
+<dd><p>This converts a library name to a platform specific form.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>clib</em> &#8211; the name of the library in cannonical form.</li>
+<li><em>framework</em> &#8211; is set if the library is implemented as a MacOS framework.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the platform specific name.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.Makefile.ready">
+<tt class="descname">ready</tt><big>(</big><big>)</big><a class="headerlink" href="#sipconfig.Makefile.ready" title="Permalink to this definition">¶</a></dt>
+<dd>This is called to ensure that the Makefile is fully configured. It is
+normally called automatically when needed.</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.Makefile.required_string">
+<tt class="descname">required_string</tt><big>(</big><em>name</em><big>)</big> &rarr; string<a class="headerlink" href="#sipconfig.Makefile.required_string" title="Permalink to this definition">¶</a></dt>
+<dd><p>This returns a required Makefile macro as a string.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>name</em> &#8211; the name of the macro.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the macro as a string. An exception is raised if the macro does
+not exist or has an empty value.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="sipconfig.ModuleMakefile">
+<em class="property">class </em><tt class="descclassname">sipconfig.</tt><tt class="descname">ModuleMakefile</tt><a class="headerlink" href="#sipconfig.ModuleMakefile" title="Permalink to this definition">¶</a></dt>
+<dd><p>This class is derived from <a title="sipconfig.Makefile" class="reference internal" href="#sipconfig.Makefile"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile</span></tt></a>.</p>
+<p>This class encapsulates a Makefile to build a generic Python extension
+module.</p>
+<dl class="method">
+<dt id="sipconfig.ModuleMakefile.__init__">
+<tt class="descname">__init__</tt><big>(</big><em>self</em>, <em>configuration</em>, <em>build_file</em><span class="optional">[</span>, <em>install_dir=None</em><span class="optional">[</span>, <em>static=0</em><span class="optional">[</span>, <em>console=0</em><span class="optional">[</span>, <em>opengl=0</em><span class="optional">[</span>, <em>threaded=0</em><span class="optional">[</span>, <em>warnings=None</em><span class="optional">[</span>, <em>debug=0</em><span class="optional">[</span>, <em>dir=None</em><span class="optional">[</span>, <em>makefile=&quot;Makefile&quot;</em><span class="optional">[</span>, <em>installs=None</em><span class="optional">[</span>, <em>strip=1</em><span class="optional">[</span>, <em>export_all=0</em><span class="optional">[</span>, <em>universal=None</em><span class="optional">[</span>, <em>arch=None</em><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><big>)</big><a class="headerlink" href="#sipconfig.ModuleMakefile.__init__" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><em>configuration</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>build_file</em> &#8211; the name of the build file. Build files are generated using the
+<a class="reference external" href="command_line.html#cmdoption-sip-b"><em class="xref">-b</em></a> SIP command line option.</li>
+<li><em>install_dir</em> &#8211; the name of the directory where the module will be optionally
+installed.</li>
+<li><em>static</em> &#8211; is set if the module should be built as a static library (see
+<a class="reference external" href="builtin.html#ref-builtin"><em>Builtin Modules and Custom Interpreters</em></a>).</li>
+<li><em>console</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>qt</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>opengl</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>threaded</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>warnings</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>debug</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>dir</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>makefile</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>installs</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>strip</em> &#8211; is set if the module should be stripped of unneeded symbols after
+installation. It is ignored if either <em>debug</em> or <em>static</em> is set,
+or if the platform doesn&#8217;t support it.</li>
+<li><em>export_all</em> &#8211; is set if all of the module&#8217;s symbols should be exported rather
+than just the module&#8217;s initialisation function. Exporting all
+symbols increases the size of the module and slows down module load
+times but may avoid problems with modules that use C++ exceptions.
+All symbols are exported if either <em>debug</em> or <em>static</em> is set, or
+if the platform doesn&#8217;t support it.</li>
+<li><em>universal</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>arch</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.ModuleMakefile.finalise">
+<tt class="descname">finalise</tt><big>(</big><big>)</big><a class="headerlink" href="#sipconfig.ModuleMakefile.finalise" title="Permalink to this definition">¶</a></dt>
+<dd>This is a reimplementation of <a title="sipconfig.Makefile.finalise" class="reference internal" href="#sipconfig.Makefile.finalise"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.finalise()</span></tt></a>.</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.ModuleMakefile.generate_macros_and_rules">
+<tt class="descname">generate_macros_and_rules</tt><big>(</big><em>mfile</em><big>)</big><a class="headerlink" href="#sipconfig.ModuleMakefile.generate_macros_and_rules" title="Permalink to this definition">¶</a></dt>
+<dd>This is a reimplementation of
+<a title="sipconfig.Makefile.generate_macros_and_rules" class="reference internal" href="#sipconfig.Makefile.generate_macros_and_rules"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.generate_macros_and_rules()</span></tt></a>.</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.ModuleMakefile.generate_target_clean">
+<tt class="descname">generate_target_clean</tt><big>(</big><em>mfile</em><big>)</big><a class="headerlink" href="#sipconfig.ModuleMakefile.generate_target_clean" title="Permalink to this definition">¶</a></dt>
+<dd>This is a reimplementation of
+<a title="sipconfig.Makefile.generate_target_clean" class="reference internal" href="#sipconfig.Makefile.generate_target_clean"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.generate_target_clean()</span></tt></a>.</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.ModuleMakefile.generate_target_default">
+<tt class="descname">generate_target_default</tt><big>(</big><em>mfile</em><big>)</big><a class="headerlink" href="#sipconfig.ModuleMakefile.generate_target_default" title="Permalink to this definition">¶</a></dt>
+<dd>This is a reimplementation of
+<a title="sipconfig.Makefile.generate_target_default" class="reference internal" href="#sipconfig.Makefile.generate_target_default"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.generate_target_default()</span></tt></a>.</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.ModuleMakefile.generate_target_install">
+<tt class="descname">generate_target_install</tt><big>(</big><em>mfile</em><big>)</big><a class="headerlink" href="#sipconfig.ModuleMakefile.generate_target_install" title="Permalink to this definition">¶</a></dt>
+<dd>This is a reimplementation of
+<a title="sipconfig.Makefile.generate_target_install" class="reference internal" href="#sipconfig.Makefile.generate_target_install"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.generate_target_install()</span></tt></a>.</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.ModuleMakefile.module_as_lib">
+<tt class="descname">module_as_lib</tt><big>(</big><em>mname</em><big>)</big> &rarr; string<a class="headerlink" href="#sipconfig.ModuleMakefile.module_as_lib" title="Permalink to this definition">¶</a></dt>
+<dd><p>This gets the name of a SIP v3.x module for when it is used as a
+library to be linked against. An exception will be raised if it is
+used with SIP v4.x modules.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>mname</em> &#8211; the name of the module.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the corresponding library name.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="sipconfig.ParentMakefile">
+<em class="property">class </em><tt class="descclassname">sipconfig.</tt><tt class="descname">ParentMakefile</tt><a class="headerlink" href="#sipconfig.ParentMakefile" title="Permalink to this definition">¶</a></dt>
+<dd><p>This class is derived from <a title="sipconfig.Makefile" class="reference internal" href="#sipconfig.Makefile"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile</span></tt></a>.</p>
+<p>This class encapsulates a Makefile that sits above a number of other
+Makefiles in sub-directories.</p>
+<dl class="method">
+<dt id="sipconfig.ParentMakefile.__init__">
+<tt class="descname">__init__</tt><big>(</big><em>self</em>, <em>configuration</em>, <em>subdirs</em><span class="optional">[</span>, <em>dir=None</em><span class="optional">[</span>, <em>makefile</em><span class="optional">[</span>, <em>=&quot;Makefile&quot;</em><span class="optional">[</span>, <em>installs=None</em><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><big>)</big><a class="headerlink" href="#sipconfig.ParentMakefile.__init__" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><em>configuration</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>subdirs</em> &#8211; the sequence of sub-directories.</li>
+<li><em>dir</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>makefile</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>installs</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.ParentMakefile.generate_macros_and_rules">
+<tt class="descname">generate_macros_and_rules</tt><big>(</big><em>mfile</em><big>)</big><a class="headerlink" href="#sipconfig.ParentMakefile.generate_macros_and_rules" title="Permalink to this definition">¶</a></dt>
+<dd>This is a reimplementation of
+<a title="sipconfig.Makefile.generate_macros_and_rules" class="reference internal" href="#sipconfig.Makefile.generate_macros_and_rules"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.generate_macros_and_rules()</span></tt></a>.</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.ParentMakefile.generate_target_clean">
+<tt class="descname">generate_target_clean</tt><big>(</big><em>mfile</em><big>)</big><a class="headerlink" href="#sipconfig.ParentMakefile.generate_target_clean" title="Permalink to this definition">¶</a></dt>
+<dd>This is a reimplementation of
+<a title="sipconfig.Makefile.generate_target_clean" class="reference internal" href="#sipconfig.Makefile.generate_target_clean"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.generate_target_clean()</span></tt></a>.</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.ParentMakefile.generate_target_default">
+<tt class="descname">generate_target_default</tt><big>(</big><em>mfile</em><big>)</big><a class="headerlink" href="#sipconfig.ParentMakefile.generate_target_default" title="Permalink to this definition">¶</a></dt>
+<dd>This is a reimplementation of
+<a title="sipconfig.Makefile.generate_target_default" class="reference internal" href="#sipconfig.Makefile.generate_target_default"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.generate_target_default()</span></tt></a>.</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.ParentMakefile.generate_target_install">
+<tt class="descname">generate_target_install</tt><big>(</big><em>mfile</em><big>)</big><a class="headerlink" href="#sipconfig.ParentMakefile.generate_target_install" title="Permalink to this definition">¶</a></dt>
+<dd>This is a reimplementation of
+<a title="sipconfig.Makefile.generate_target_install" class="reference internal" href="#sipconfig.Makefile.generate_target_install"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.generate_target_install()</span></tt></a>.</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="sipconfig.ProgramMakefile">
+<em class="property">class </em><tt class="descclassname">sipconfig.</tt><tt class="descname">ProgramMakefile</tt><a class="headerlink" href="#sipconfig.ProgramMakefile" title="Permalink to this definition">¶</a></dt>
+<dd><p>This class is derived from <a title="sipconfig.Makefile" class="reference internal" href="#sipconfig.Makefile"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile</span></tt></a>.</p>
+<p>This class encapsulates a Makefile to build an executable program.</p>
+<dl class="method">
+<dt id="sipconfig.ProgramMakefile.__init__">
+<tt class="descname">__init__</tt><big>(</big><em>configuration</em><span class="optional">[</span>, <em>build_file=None</em><span class="optional">[</span>, <em>install_dir=None</em><span class="optional">[</span>, <em>console=0</em><span class="optional">[</span>, <em>qt=0</em><span class="optional">[</span>, <em>opengl=0</em><span class="optional">[</span>, <em>python=0</em><span class="optional">[</span>, <em>threaded=0</em><span class="optional">[</span>, <em>warnings=None</em><span class="optional">[</span>, <em>debug=0</em><span class="optional">[</span>, <em>dir=None</em><span class="optional">[</span>, <em>makefile=&quot;Makefile&quot;</em><span class="optional">[</span>, <em>installs=None</em><span class="optional">[</span>, <em>universal=None</em><span class="optional">[</span>, <em>arch=None</em><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><big>)</big><a class="headerlink" href="#sipconfig.ProgramMakefile.__init__" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><em>configuration</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>build_file</em> &#8211; the name of the optional build file. Build files are generated
+using the <a class="reference external" href="command_line.html#cmdoption-sip-b"><em class="xref">-b</em></a> SIP command line option.</li>
+<li><em>install_dir</em> &#8211; the name of the directory where the executable program will be
+optionally installed.</li>
+<li><em>console</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>qt</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>opengl</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>python</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>threaded</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>warnings</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>debug</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>dir</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>makefile</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>installs</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>universal</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>arch</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.ProgramMakefile.build_command">
+<tt class="descname">build_command</tt><big>(</big><em>source</em><big>)</big> &rarr; string, string<a class="headerlink" href="#sipconfig.ProgramMakefile.build_command" title="Permalink to this definition">¶</a></dt>
+<dd><p>This creates a single command line that will create an executable
+program from a single source file.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>source</em> &#8211; the name of the source file.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">a tuple of the name of the executable that will be created and the
+command line.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.ProgramMakefile.finalise">
+<tt class="descname">finalise</tt><big>(</big><big>)</big><a class="headerlink" href="#sipconfig.ProgramMakefile.finalise" title="Permalink to this definition">¶</a></dt>
+<dd>This is a reimplementation of <a title="sipconfig.Makefile.finalise" class="reference internal" href="#sipconfig.Makefile.finalise"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.finalise()</span></tt></a>.</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.ProgramMakefile.generate_macros_and_rules">
+<tt class="descname">generate_macros_and_rules</tt><big>(</big><em>mfile</em><big>)</big><a class="headerlink" href="#sipconfig.ProgramMakefile.generate_macros_and_rules" title="Permalink to this definition">¶</a></dt>
+<dd>This is a reimplementation of
+<a title="sipconfig.Makefile.generate_macros_and_rules" class="reference internal" href="#sipconfig.Makefile.generate_macros_and_rules"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.generate_macros_and_rules()</span></tt></a>.</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.ProgramMakefile.generate_target_clean">
+<tt class="descname">generate_target_clean</tt><big>(</big><em>mfile</em><big>)</big><a class="headerlink" href="#sipconfig.ProgramMakefile.generate_target_clean" title="Permalink to this definition">¶</a></dt>
+<dd>This is a reimplementation of
+<a title="sipconfig.Makefile.generate_target_clean" class="reference internal" href="#sipconfig.Makefile.generate_target_clean"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.generate_target_clean()</span></tt></a>.</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.ProgramMakefile.generate_target_default">
+<tt class="descname">generate_target_default</tt><big>(</big><em>mfile</em><big>)</big><a class="headerlink" href="#sipconfig.ProgramMakefile.generate_target_default" title="Permalink to this definition">¶</a></dt>
+<dd>This is a reimplementation of
+<a title="sipconfig.Makefile.generate_target_default" class="reference internal" href="#sipconfig.Makefile.generate_target_default"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.generate_target_default()</span></tt></a>.</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.ProgramMakefile.generate_target_install">
+<tt class="descname">generate_target_install</tt><big>(</big><em>mfile</em><big>)</big><a class="headerlink" href="#sipconfig.ProgramMakefile.generate_target_install" title="Permalink to this definition">¶</a></dt>
+<dd>This is a reimplementation of
+<a title="sipconfig.Makefile.generate_target_install" class="reference internal" href="#sipconfig.Makefile.generate_target_install"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.generate_target_install()</span></tt></a>.</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="sipconfig.PythonModuleMakefile">
+<em class="property">class </em><tt class="descclassname">sipconfig.</tt><tt class="descname">PythonModuleMakefile</tt><a class="headerlink" href="#sipconfig.PythonModuleMakefile" title="Permalink to this definition">¶</a></dt>
+<dd><p>This class is derived from <a title="sipconfig.Makefile" class="reference internal" href="#sipconfig.Makefile"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile</span></tt></a>.</p>
+<p>This class encapsulates a Makefile that installs a pure Python module.</p>
+<dl class="method">
+<dt id="sipconfig.PythonModuleMakefile.__init__">
+<tt class="descname">__init__</tt><big>(</big><em>self</em>, <em>configuration</em>, <em>dstdir</em><span class="optional">[</span>, <em>srcdir=None</em><span class="optional">[</span>, <em>dir=None</em><span class="optional">[</span>, <em>makefile=&quot;Makefile&quot;</em><span class="optional">[</span>, <em>installs=None</em><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><big>)</big><a class="headerlink" href="#sipconfig.PythonModuleMakefile.__init__" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><em>configuration</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>dstdir</em> &#8211; the name of the directory in which the module&#8217;s Python code will be
+installed.</li>
+<li><em>srcdir</em> &#8211; the name of the directory (relative to <em>dir</em>) containing the
+module&#8217;s Python code. It defaults to the same directory.</li>
+<li><em>dir</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>makefile</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>installs</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.PythonModuleMakefile.generate_macros_and_rules">
+<tt class="descname">generate_macros_and_rules</tt><big>(</big><em>mfile</em><big>)</big><a class="headerlink" href="#sipconfig.PythonModuleMakefile.generate_macros_and_rules" title="Permalink to this definition">¶</a></dt>
+<dd>This is a reimplementation of
+<a title="sipconfig.Makefile.generate_macros_and_rules" class="reference internal" href="#sipconfig.Makefile.generate_macros_and_rules"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.generate_macros_and_rules()</span></tt></a>.</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.PythonModuleMakefile.generate_target_install">
+<tt class="descname">generate_target_install</tt><big>(</big><em>mfile</em><big>)</big><a class="headerlink" href="#sipconfig.PythonModuleMakefile.generate_target_install" title="Permalink to this definition">¶</a></dt>
+<dd>This is a reimplementation of
+<a title="sipconfig.Makefile.generate_target_install" class="reference internal" href="#sipconfig.Makefile.generate_target_install"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.generate_target_install()</span></tt></a>.</dd></dl>
+
+</dd></dl>
+
+<dl class="class">
+<dt id="sipconfig.SIPModuleMakefile">
+<em class="property">class </em><tt class="descclassname">sipconfig.</tt><tt class="descname">SIPModuleMakefile</tt><a class="headerlink" href="#sipconfig.SIPModuleMakefile" title="Permalink to this definition">¶</a></dt>
+<dd><p>This class is derived from <a title="sipconfig.ModuleMakefile" class="reference internal" href="#sipconfig.ModuleMakefile"><tt class="xref docutils literal"><span class="pre">sipconfig.ModuleMakefile</span></tt></a>.</p>
+<p>This class encapsulates a Makefile to build a SIP generated Python
+extension module.</p>
+<dl class="method">
+<dt id="sipconfig.SIPModuleMakefile.__init__">
+<tt class="descname">__init__</tt><big>(</big><em>self</em>, <em>configuration</em>, <em>build_file</em><span class="optional">[</span>, <em>install_dir=None</em><span class="optional">[</span>, <em>static=0</em><span class="optional">[</span>, <em>console=0</em><span class="optional">[</span>, <em>opengl=0</em><span class="optional">[</span>, <em>threaded=0</em><span class="optional">[</span>, <em>warnings=None</em><span class="optional">[</span>, <em>debug=0</em><span class="optional">[</span>, <em>dir=None</em><span class="optional">[</span>, <em>makefile=&quot;Makefile&quot;</em><span class="optional">[</span>, <em>installs=None</em><span class="optional">[</span>, <em>strip=1</em><span class="optional">[</span>, <em>export_all=0</em><span class="optional">[</span>, <em>universal=None</em><span class="optional">[</span>, <em>arch=None</em><span class="optional">[</span>, <em>prot_is_public=0</em><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><big>)</big><a class="headerlink" href="#sipconfig.SIPModuleMakefile.__init__" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><em>configuration</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>build_file</em> &#8211; see <a title="sipconfig.ModuleMakefile.__init__" class="reference internal" href="#sipconfig.ModuleMakefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.ModuleMakefile.__init__()</span></tt></a>.</li>
+<li><em>install_dir</em> &#8211; see <a title="sipconfig.ModuleMakefile.__init__" class="reference internal" href="#sipconfig.ModuleMakefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.ModuleMakefile.__init__()</span></tt></a>.</li>
+<li><em>static</em> &#8211; see <a title="sipconfig.ModuleMakefile.__init__" class="reference internal" href="#sipconfig.ModuleMakefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.ModuleMakefile.__init__()</span></tt></a>.</li>
+<li><em>console</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>qt</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>opengl</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>threaded</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>warnings</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>debug</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>dir</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>makefile</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>installs</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>strip</em> &#8211; see <a title="sipconfig.ModuleMakefile.__init__" class="reference internal" href="#sipconfig.ModuleMakefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.ModuleMakefile.__init__()</span></tt></a>.</li>
+<li><em>export_all</em> &#8211; see <a title="sipconfig.ModuleMakefile.__init__" class="reference internal" href="#sipconfig.ModuleMakefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.ModuleMakefile.__init__()</span></tt></a>.</li>
+<li><em>universal</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>arch</em> &#8211; see <a title="sipconfig.Makefile.__init__" class="reference internal" href="#sipconfig.Makefile.__init__"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.__init__()</span></tt></a>.</li>
+<li><em>prot_is_public</em> &#8211; is set if <tt class="docutils literal"><span class="pre">protected</span></tt> should be redefined as <tt class="docutils literal"><span class="pre">public</span></tt> when
+compiling the generated module.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sipconfig.SIPModuleMakefile.finalise">
+<tt class="descname">finalise</tt><big>(</big><big>)</big><a class="headerlink" href="#sipconfig.SIPModuleMakefile.finalise" title="Permalink to this definition">¶</a></dt>
+<dd>This is a reimplementation of <a title="sipconfig.Makefile.finalise" class="reference internal" href="#sipconfig.Makefile.finalise"><tt class="xref docutils literal"><span class="pre">sipconfig.Makefile.finalise()</span></tt></a>.</dd></dl>
+
+</dd></dl>
+
+</div>
+
+
+ </div>
+ </div>
+ </div>
+ <div class="sphinxsidebar">
+ <div class="sphinxsidebarwrapper">
+ <h4>Previous topic</h4>
+ <p class="topless"><a href="python_api.html"
+ title="previous chapter">Python API for Applications</a></p>
+ <h4>Next topic</h4>
+ <p class="topless"><a href="distutils.html"
+ title="next chapter">Building Your Extension with distutils</a></p>
+ <div id="searchbox" style="display: none">
+ <h3>Quick search</h3>
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" size="18" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ <p class="searchtip" style="font-size: 90%">
+ Enter search terms or a module, class or function name.
+ </p>
+ </div>
+ <script type="text/javascript">$('#searchbox').show(0);</script>
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ >modules</a> |</li>
+ <li class="right" >
+ <a href="distutils.html" title="Building Your Extension with distutils"
+ >next</a> |</li>
+ <li class="right" >
+ <a href="python_api.html" title="Python API for Applications"
+ >previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+ <div class="footer">
+ &copy; Copyright 2010 Riverbank Computing Limited.
+ Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.4.
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/builtin.html b/doc/html/builtin.html
new file mode 100644
index 0000000..e8ba2ec
--- /dev/null
+++ b/doc/html/builtin.html
@@ -0,0 +1,138 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>Builtin Modules and Custom Interpreters &mdash; SIP 4.10.5 Reference Guide</title>
+ <link rel="stylesheet" href="_static/default.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '#',
+ VERSION: '4.10.5',
+ COLLAPSE_MODINDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="top" title="SIP 4.10.5 Reference Guide" href="index.html" />
+ <link rel="prev" title="Building Your Extension with distutils" href="distutils.html" />
+ </head>
+ <body>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ accesskey="M">modules</a> |</li>
+ <li class="right" >
+ <a href="distutils.html" title="Building Your Extension with distutils"
+ accesskey="P">previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+ <div class="body">
+
+ <div class="section" id="builtin-modules-and-custom-interpreters">
+<span id="ref-builtin"></span><h1>Builtin Modules and Custom Interpreters<a class="headerlink" href="#builtin-modules-and-custom-interpreters" title="Permalink to this headline">¶</a></h1>
+<p>Sometimes you want to create a custom Python interpreter with some modules
+built in to the interpreter itself rather than being dynamically loaded. To
+do this the module must be created as a static library and linked with a
+custom stub and the normal Python library.</p>
+<p>To build the SIP module as a static library you must pass the <tt class="docutils literal"><span class="pre">-k</span></tt> command
+line option to <tt class="docutils literal"><span class="pre">configure.py</span></tt>. You should then build and install SIP as
+normal. (Note that, because the module is now a static library, you will not
+be able to import it.)</p>
+<p>To build a module you have created for your own library you must modify your
+own configuration script to pass a non-zero value as the <tt class="docutils literal"><span class="pre">static</span></tt> argument
+of the <tt class="docutils literal"><span class="pre">__init__()</span></tt> method of the <a title="sipconfig.ModuleMakefile" class="reference external" href="build_system.html#sipconfig.ModuleMakefile"><tt class="xref docutils literal"><span class="pre">sipconfig.ModuleMakefile</span></tt></a> class (or
+any derived class you have created). Normally you would make this configurable
+using a command line option in the same way that SIP&#8217;s <tt class="docutils literal"><span class="pre">configure.py</span></tt> handles
+it.</p>
+<p>The next stage is to create a custom stub and a Makefile. The SIP distribution
+contains a directory called <tt class="docutils literal"><span class="pre">custom</span></tt> which contains example stubs and a
+Python script that will create a correct Makefile. Note that, if your copy of
+SIP was part of a standard Linux distribution, the <tt class="docutils literal"><span class="pre">custom</span></tt> directory may
+not be installed on your system.</p>
+<p>The <tt class="docutils literal"><span class="pre">custom</span></tt> directory contains the following files. They are provided as
+examples - each needs to be modified according to your particular
+requirements.</p>
+<blockquote>
+<ul class="simple">
+<li><tt class="docutils literal"><span class="pre">mkcustom.py</span></tt> is a Python script that will create a Makefile which is
+then used to build the custom interpreter. Comments in the file describe
+how it should be modified.</li>
+<li><tt class="docutils literal"><span class="pre">custom.c</span></tt> is a stub for a custom interpreter on Linux/UNIX. It
+should also be used for a custom console interpreter on Windows (i.e.
+like <tt class="docutils literal"><span class="pre">python.exe</span></tt>). Comments in the file describe how it should be
+modified.</li>
+<li><tt class="docutils literal"><span class="pre">customw.c</span></tt> is a stub for a custom GUI interpreter on Windows (i.e.
+like <tt class="docutils literal"><span class="pre">pythonw.exe</span></tt>). Comments in the file describe how it should be
+modified.</li>
+</ul>
+</blockquote>
+<p>Note that this technique does not restrict how the interpreter can be used.
+For example, it still allows users to write their own applications that can
+import your builtin modules. If you want to prevent users from doing that,
+perhaps to protect a proprietary API, then take a look at the
+<a class="reference external" href="http://www.riverbankcomputing.com/software/vendorid/">VendorID</a> package.</p>
+</div>
+
+
+ </div>
+ </div>
+ </div>
+ <div class="sphinxsidebar">
+ <div class="sphinxsidebarwrapper">
+ <h4>Previous topic</h4>
+ <p class="topless"><a href="distutils.html"
+ title="previous chapter">Building Your Extension with distutils</a></p>
+ <div id="searchbox" style="display: none">
+ <h3>Quick search</h3>
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" size="18" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ <p class="searchtip" style="font-size: 90%">
+ Enter search terms or a module, class or function name.
+ </p>
+ </div>
+ <script type="text/javascript">$('#searchbox').show(0);</script>
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ >modules</a> |</li>
+ <li class="right" >
+ <a href="distutils.html" title="Building Your Extension with distutils"
+ >previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+ <div class="footer">
+ &copy; Copyright 2010 Riverbank Computing Limited.
+ Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.4.
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/c_api.html b/doc/html/c_api.html
new file mode 100644
index 0000000..b761f8a
--- /dev/null
+++ b/doc/html/c_api.html
@@ -0,0 +1,2166 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>C API for Handwritten Code &mdash; SIP 4.10.5 Reference Guide</title>
+ <link rel="stylesheet" href="_static/default.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '#',
+ VERSION: '4.10.5',
+ COLLAPSE_MODINDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="top" title="SIP 4.10.5 Reference Guide" href="index.html" />
+ <link rel="next" title="Using the C API when Embedding" href="embedding.html" />
+ <link rel="prev" title="Annotations" href="annotations.html" />
+ </head>
+ <body>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ accesskey="M">modules</a> |</li>
+ <li class="right" >
+ <a href="embedding.html" title="Using the C API when Embedding"
+ accesskey="N">next</a> |</li>
+ <li class="right" >
+ <a href="annotations.html" title="Annotations"
+ accesskey="P">previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+ <div class="body">
+
+ <div class="section" id="c-api-for-handwritten-code">
+<span id="ref-c-api"></span><h1>C API for Handwritten Code<a class="headerlink" href="#c-api-for-handwritten-code" title="Permalink to this headline">¶</a></h1>
+<p>In this section we describe the API that can be used by handwritten code in
+specification files.</p>
+<dl class="cmacro">
+<dt id="SIP_API_MAJOR_NR">
+<tt class="descname">SIP_API_MAJOR_NR</tt><a class="headerlink" href="#SIP_API_MAJOR_NR" title="Permalink to this definition">¶</a></dt>
+<dd>This is a C preprocessor symbol that defines the major number of the SIP
+API. Its value is a number. There is no direct relationship between this
+and the SIP version number.</dd></dl>
+
+<dl class="cmacro">
+<dt id="SIP_API_MINOR_NR">
+<tt class="descname">SIP_API_MINOR_NR</tt><a class="headerlink" href="#SIP_API_MINOR_NR" title="Permalink to this definition">¶</a></dt>
+<dd>This is a C preprocessor symbol that defines the minor number of the SIP
+API. Its value is a number. There is no direct relationship between this
+and the SIP version number.</dd></dl>
+
+<dl class="cmacro">
+<dt id="SIP_BLOCK_THREADS">
+<tt class="descname">SIP_BLOCK_THREADS</tt><a class="headerlink" href="#SIP_BLOCK_THREADS" title="Permalink to this definition">¶</a></dt>
+<dd>This is a C preprocessor macro that will make sure the Python Global
+Interpreter Lock (GIL) is acquired. Python API calls must only be made
+when the GIL has been acquired. There must be a corresponding
+<a title="SIP_UNBLOCK_THREADS" class="reference internal" href="#SIP_UNBLOCK_THREADS"><tt class="xref docutils literal"><span class="pre">SIP_UNBLOCK_THREADS</span></tt></a> at the same lexical scope.</dd></dl>
+
+<dl class="cmacro">
+<dt id="SIP_NO_CONVERTORS">
+<tt class="descname">SIP_NO_CONVERTORS</tt><a class="headerlink" href="#SIP_NO_CONVERTORS" title="Permalink to this definition">¶</a></dt>
+<dd>This is a flag used by various type convertors that suppresses the use of a
+type&#8217;s <a class="reference external" href="directives.html#directive-%ConvertToTypeCode"><tt class="xref docutils literal"><span class="pre">%ConvertToTypeCode</span></tt></a>.</dd></dl>
+
+<dl class="cmacro">
+<dt id="SIP_NOT_NONE">
+<tt class="descname">SIP_NOT_NONE</tt><a class="headerlink" href="#SIP_NOT_NONE" title="Permalink to this definition">¶</a></dt>
+<dd>This is a flag used by various type convertors that causes the conversion
+to fail if the Python object being converted is <tt class="docutils literal"><span class="pre">Py_None</span></tt>.</dd></dl>
+
+<dl class="cmacro">
+<dt id="SIP_PROTECTED_IS_PUBLIC">
+<tt class="descname">SIP_PROTECTED_IS_PUBLIC</tt><a class="headerlink" href="#SIP_PROTECTED_IS_PUBLIC" title="Permalink to this definition">¶</a></dt>
+<dd><p>
+<span class="versionmodified">New in version 4.10.</span></p>
+<p>This is a C preprocessor macro that is set automatically by the build
+system to specify that the generated code is being compiled with
+<tt class="docutils literal"><span class="pre">protected</span></tt> redefined as <tt class="docutils literal"><span class="pre">public</span></tt>. This allows handwritten code to
+determine if the generated helper functions for accessing protected C++
+functions are available (see <a class="reference external" href="directives.html#directive-%MethodCode"><tt class="xref docutils literal"><span class="pre">%MethodCode</span></tt></a>).</p>
+</dd></dl>
+
+<dl class="cmacro">
+<dt id="SIP_SSIZE_T">
+<tt class="descname">SIP_SSIZE_T</tt><a class="headerlink" href="#SIP_SSIZE_T" title="Permalink to this definition">¶</a></dt>
+<dd>This is a C preprocessor macro that is defined as <tt class="docutils literal"><span class="pre">Py_ssize_t</span></tt> for Python
+v2.5 and later, and as <tt class="docutils literal"><span class="pre">int</span></tt> for earlier versions of Python. It makes it
+easier to write PEP 353 compliant handwritten code.</dd></dl>
+
+<dl class="cmacro">
+<dt id="SIP_UNBLOCK_THREADS">
+<tt class="descname">SIP_UNBLOCK_THREADS</tt><a class="headerlink" href="#SIP_UNBLOCK_THREADS" title="Permalink to this definition">¶</a></dt>
+<dd>This is a C preprocessor macro that will restore the Python Global
+Interpreter Lock (GIL) to the state it was prior to the corresponding
+<a title="SIP_BLOCK_THREADS" class="reference internal" href="#SIP_BLOCK_THREADS"><tt class="xref docutils literal"><span class="pre">SIP_BLOCK_THREADS</span></tt></a>.</dd></dl>
+
+<dl class="cmacro">
+<dt id="SIP_VERSION">
+<tt class="descname">SIP_VERSION</tt><a class="headerlink" href="#SIP_VERSION" title="Permalink to this definition">¶</a></dt>
+<dd>This is a C preprocessor symbol that defines the SIP version number
+represented as a 3 part hexadecimal number (e.g. v4.0.0 is represented as
+<tt class="docutils literal"><span class="pre">0x040000</span></tt>).</dd></dl>
+
+<dl class="cmacro">
+<dt id="SIP_VERSION_STR">
+<tt class="descname">SIP_VERSION_STR</tt><a class="headerlink" href="#SIP_VERSION_STR" title="Permalink to this definition">¶</a></dt>
+<dd>This is a C preprocessor symbol that defines the SIP version number
+represented as a string. For development snapshots it will start with
+<tt class="docutils literal"><span class="pre">snapshot-</span></tt>.</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipBadCallableArg">
+sipErrorState <tt class="descname">sipBadCallableArg</tt><big>(</big>int<em> arg_nr</em>, PyObject<em> *arg</em><big>)</big><a class="headerlink" href="#sipBadCallableArg" title="Permalink to this definition">¶</a></dt>
+<dd><p>
+<span class="versionmodified">New in version 4.10.</span></p>
+<p>This is called from <a class="reference external" href="directives.html#directive-%MethodCode"><tt class="xref docutils literal"><span class="pre">%MethodCode</span></tt></a> to raise a Python exception
+when an argument to a function, a C++ constructor or method is found to
+have an unexpected type. This should be used when the
+<a class="reference external" href="directives.html#directive-%MethodCode"><tt class="xref docutils literal"><span class="pre">%MethodCode</span></tt></a> does additional type checking of the supplied
+arguments.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>arg_nr</em> &#8211; the number of the argument. Arguments are numbered from 0 but are
+numbered from 1 in the detail of the exception.</li>
+<li><em>arg</em> &#8211; the argument.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the value that should be assigned to <tt class="docutils literal"><span class="pre">sipError</span></tt>.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipBadCatcherResult">
+void <tt class="descname">sipBadCatcherResult</tt><big>(</big>PyObject<em> *method</em><big>)</big><a class="headerlink" href="#sipBadCatcherResult" title="Permalink to this definition">¶</a></dt>
+<dd><p>This raises a Python exception when the result of a Python reimplementation
+of a C++ method doesn&#8217;t have the expected type. It is normally called by
+handwritten code specified with the <a class="reference external" href="directives.html#directive-%VirtualCatcherCode"><tt class="xref docutils literal"><span class="pre">%VirtualCatcherCode</span></tt></a>
+directive.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>method</em> &#8211; the Python method and would normally be the supplied <tt class="docutils literal"><span class="pre">sipMethod</span></tt>.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipBadLengthForSlice">
+void <tt class="descname">sipBadLengthForSlice</tt><big>(</big><a title="SIP_SSIZE_T" class="reference internal" href="#SIP_SSIZE_T">SIP_SSIZE_T</a><em> seqlen</em>, <a title="SIP_SSIZE_T" class="reference internal" href="#SIP_SSIZE_T">SIP_SSIZE_T</a><em> slicelen</em><big>)</big><a class="headerlink" href="#sipBadLengthForSlice" title="Permalink to this definition">¶</a></dt>
+<dd><p>This raises a Python exception when the length of a slice object is
+inappropriate for a sequence-like object. It is normally called by
+handwritten code specified for <tt class="xref docutils literal"><span class="pre">__setitem__()</span></tt> methods.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><em>seqlen</em> &#8211; the length of the sequence.</li>
+<li><em>slicelen</em> &#8211; the length of the slice.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipBuildResult">
+PyObject *<tt class="descname">sipBuildResult</tt><big>(</big>int<em> *iserr</em>, const char<em> *format</em>, ...<big>)</big><a class="headerlink" href="#sipBuildResult" title="Permalink to this definition">¶</a></dt>
+<dd><p>This creates a Python object based on a format string and associated
+values in a similar way to the Python <tt class="xref docutils literal"><span class="pre">Py_BuildValue()</span></tt> function.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>iserr</em> &#8211; if this is not <tt class="docutils literal"><span class="pre">NULL</span></tt> then the location it points to is set to a
+non-zero value.</li>
+<li><em>format</em> &#8211; the string of format characters.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">If there was an error then <tt class="docutils literal"><span class="pre">NULL</span></tt> is returned and a Python exception
+is raised.</p>
+</td>
+</tr>
+</tbody>
+</table>
+<p>If the format string begins and ends with parentheses then a tuple of
+objects is created. If it contains more than one format character then
+parentheses must be specified.</p>
+<p>In the following description the first letter is the format character, the
+entry in parentheses is the Python object type that the format character
+will create, and the entry in brackets are the types of the C/C++ values
+to be passed.</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">a</span></tt> (string) [char]</dt>
+<dd>Convert a C/C++ <tt class="docutils literal"><span class="pre">char</span></tt> to a Python v2 or v3 string object.</dd>
+<dt><tt class="docutils literal"><span class="pre">b</span></tt> (boolean) [int]</dt>
+<dd>Convert a C/C++ <tt class="docutils literal"><span class="pre">int</span></tt> to a Python boolean.</dd>
+<dt><tt class="docutils literal"><span class="pre">c</span></tt> (string/bytes) [char]</dt>
+<dd>Convert a C/C++ <tt class="docutils literal"><span class="pre">char</span></tt> to a Python v2 string object or a Python v3
+bytes object.</dd>
+<dt><tt class="docutils literal"><span class="pre">d</span></tt> (float) [double]</dt>
+<dd>Convert a C/C++ <tt class="docutils literal"><span class="pre">double</span></tt> to a Python floating point number.</dd>
+<dt><tt class="docutils literal"><span class="pre">e</span></tt> (integer) [enum]</dt>
+<dd>Convert an anonymous C/C++ <tt class="docutils literal"><span class="pre">enum</span></tt> to a Python integer.</dd>
+<dt><tt class="docutils literal"><span class="pre">f</span></tt> (float) [float]</dt>
+<dd>Convert a C/C++ <tt class="docutils literal"><span class="pre">float</span></tt> to a Python floating point number.</dd>
+<dt><tt class="docutils literal"><span class="pre">g</span></tt> (string/bytes) [char *, <a title="SIP_SSIZE_T" class="reference internal" href="#SIP_SSIZE_T"><tt class="xref docutils literal"><span class="pre">SIP_SSIZE_T</span></tt></a>]</dt>
+<dd>Convert a C/C++ character array and its length to a Python v2 string
+object or a Python v3 bytes object. If the array is <tt class="docutils literal"><span class="pre">NULL</span></tt> then the
+length is ignored and the result is <tt class="docutils literal"><span class="pre">Py_None</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">h</span></tt> (integer) [short]</dt>
+<dd>Convert a C/C++ <tt class="docutils literal"><span class="pre">short</span></tt> to a Python integer.</dd>
+<dt><tt class="docutils literal"><span class="pre">i</span></tt> (integer) [int]</dt>
+<dd>Convert a C/C++ <tt class="docutils literal"><span class="pre">int</span></tt> to a Python integer.</dd>
+<dt><tt class="docutils literal"><span class="pre">l</span></tt> (long) [long]</dt>
+<dd>Convert a C/C++ <tt class="docutils literal"><span class="pre">long</span></tt> to a Python integer.</dd>
+<dt><tt class="docutils literal"><span class="pre">m</span></tt> (long) [unsigned long]</dt>
+<dd>Convert a C/C++ <tt class="docutils literal"><span class="pre">unsigned</span> <span class="pre">long</span></tt> to a Python long.</dd>
+<dt><tt class="docutils literal"><span class="pre">n</span></tt> (long) [long long]</dt>
+<dd>Convert a C/C++ <tt class="docutils literal"><span class="pre">long</span> <span class="pre">long</span></tt> to a Python long.</dd>
+<dt><tt class="docutils literal"><span class="pre">o</span></tt> (long) [unsigned long long]</dt>
+<dd>Convert a C/C++ <tt class="docutils literal"><span class="pre">unsigned</span> <span class="pre">long</span> <span class="pre">long</span></tt> to a Python long.</dd>
+<dt><tt class="docutils literal"><span class="pre">r</span></tt> (wrapped instance) [<em>type</em> *, <a title="SIP_SSIZE_T" class="reference internal" href="#SIP_SSIZE_T"><tt class="xref docutils literal"><span class="pre">SIP_SSIZE_T</span></tt></a>, const <tt class="xref docutils literal"><span class="pre">sipTypeDef</span></tt> *]</dt>
+<dd>Convert an array of C structures, C++ classes or mapped type instances
+to a Python tuple. Note that copies of the array elements are made.</dd>
+<dt><tt class="docutils literal"><span class="pre">s</span></tt> (string/bytes) [char *]</dt>
+<dd>Convert a C/C++ <tt class="docutils literal"><span class="pre">'\0'</span></tt> terminated string to a Python v2 string object
+or a Python v3 bytes object. If the string pointer is <tt class="docutils literal"><span class="pre">NULL</span></tt> then
+the result is <tt class="docutils literal"><span class="pre">Py_None</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">t</span></tt> (long) [unsigned short]</dt>
+<dd>Convert a C/C++ <tt class="docutils literal"><span class="pre">unsigned</span> <span class="pre">short</span></tt> to a Python long.</dd>
+<dt><tt class="docutils literal"><span class="pre">u</span></tt> (long) [unsigned int]</dt>
+<dd>Convert a C/C++ <tt class="docutils literal"><span class="pre">unsigned</span> <span class="pre">int</span></tt> to a Python long.</dd>
+<dt><tt class="docutils literal"><span class="pre">w</span></tt> (unicode/string) [wchar_t]</dt>
+<dd>Convert a C/C++ wide character to a Python v2 unicode object or a
+Python v3 string object.</dd>
+<dt><tt class="docutils literal"><span class="pre">x</span></tt> (unicode/string) [wchar_t *]</dt>
+<dd>Convert a C/C++ <tt class="docutils literal"><span class="pre">L'\0'</span></tt> terminated wide character string to a Python
+v2 unicode object or a Python v3 string object. If the string pointer
+is <tt class="docutils literal"><span class="pre">NULL</span></tt> then the result is <tt class="docutils literal"><span class="pre">Py_None</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">A</span></tt> (string) [char *]</dt>
+<dd>Convert a C/C++ <tt class="docutils literal"><span class="pre">'\0'</span></tt> terminated string to a Python v2 or v3 string
+object. If the string pointer is <tt class="docutils literal"><span class="pre">NULL</span></tt> then the result is
+<tt class="docutils literal"><span class="pre">Py_None</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">B</span></tt> (wrapped instance) [<em>type</em> *, <a title="sipWrapperType" class="reference internal" href="#sipWrapperType"><tt class="xref docutils literal"><span class="pre">sipWrapperType</span></tt></a> *, PyObject *]</dt>
+<dd><p class="first">Convert a new C structure or a new C++ class instance to a Python class
+instance object. Ownership of the structure or instance is determined
+by the <tt class="docutils literal"><span class="pre">PyObject</span> <span class="pre">*</span></tt> argument. If it is <tt class="docutils literal"><span class="pre">NULL</span></tt> and the instance has
+already been wrapped then the ownership is unchanged. If it is
+<tt class="docutils literal"><span class="pre">NULL</span></tt> or <tt class="docutils literal"><span class="pre">Py_None</span></tt> then ownership will be with Python. Otherwise
+ownership will be with C/C++ and the instance associated with the
+<tt class="docutils literal"><span class="pre">PyObject</span> <span class="pre">*</span></tt> argument. The Python class is influenced by any
+applicable <a class="reference external" href="directives.html#directive-%ConvertToSubClassCode"><tt class="xref docutils literal"><span class="pre">%ConvertToSubClassCode</span></tt></a> code.</p>
+<div class="last admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8. Instead you should use <tt class="docutils literal"><span class="pre">N</span></tt>.</p>
+</div>
+</dd>
+<dt><tt class="docutils literal"><span class="pre">C</span></tt> (wrapped instance) [<em>type</em> *, <a title="sipWrapperType" class="reference internal" href="#sipWrapperType"><tt class="xref docutils literal"><span class="pre">sipWrapperType</span></tt></a> *, PyObject *]</dt>
+<dd><p class="first">Convert a C structure or a C++ class instance to a Python class
+instance object. If the structure or class instance has already been
+wrapped then the result is a new reference to the existing class
+instance object. Ownership of the structure or instance is determined
+by the <tt class="docutils literal"><span class="pre">PyObject</span> <span class="pre">*</span></tt> argument. If it is <tt class="docutils literal"><span class="pre">NULL</span></tt> and the instance has
+already been wrapped then the ownership is unchanged. If it is
+<tt class="docutils literal"><span class="pre">NULL</span></tt> and the instance is newly wrapped then ownership will be with
+C/C++. If it is <tt class="docutils literal"><span class="pre">Py_None</span></tt> then ownership is transferred to Python
+via a call to <a title="sipTransferBack" class="reference internal" href="#sipTransferBack"><tt class="xref docutils literal"><span class="pre">sipTransferBack()</span></tt></a>. Otherwise ownership is
+transferred to C/C++ and the instance associated with the
+<tt class="docutils literal"><span class="pre">PyObject</span> <span class="pre">*</span></tt> argument via a call to <a title="sipTransferTo" class="reference internal" href="#sipTransferTo"><tt class="xref docutils literal"><span class="pre">sipTransferTo()</span></tt></a>. The
+Python class is influenced by any applicable
+<a class="reference external" href="directives.html#directive-%ConvertToSubClassCode"><tt class="xref docutils literal"><span class="pre">%ConvertToSubClassCode</span></tt></a> code.</p>
+<div class="last admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8. Instead you should use <tt class="docutils literal"><span class="pre">D</span></tt>.</p>
+</div>
+</dd>
+<dt><tt class="docutils literal"><span class="pre">D</span></tt> (wrapped instance) [<em>type</em> *, const <tt class="xref docutils literal"><span class="pre">sipTypeDef</span></tt> *, PyObject *]</dt>
+<dd>Convert a C structure, C++ class or mapped type instance to a Python
+object. If the instance has already been wrapped then the result is a
+new reference to the existing object. Ownership of the instance is
+determined by the <tt class="docutils literal"><span class="pre">PyObject</span> <span class="pre">*</span></tt> argument. If it is <tt class="docutils literal"><span class="pre">NULL</span></tt> and the
+instance has already been wrapped then the ownership is unchanged. If
+it is <tt class="docutils literal"><span class="pre">NULL</span></tt> and the instance is newly wrapped then ownership will be
+with C/C++. If it is <tt class="docutils literal"><span class="pre">Py_None</span></tt> then ownership is transferred to
+Python via a call to <a title="sipTransferBack" class="reference internal" href="#sipTransferBack"><tt class="xref docutils literal"><span class="pre">sipTransferBack()</span></tt></a>. Otherwise ownership
+is transferred to C/C++ and the instance associated with the
+<tt class="docutils literal"><span class="pre">PyObject</span> <span class="pre">*</span></tt> argument via a call to <a title="sipTransferTo" class="reference internal" href="#sipTransferTo"><tt class="xref docutils literal"><span class="pre">sipTransferTo()</span></tt></a>. The
+Python class is influenced by any applicable
+<a class="reference external" href="directives.html#directive-%ConvertToSubClassCode"><tt class="xref docutils literal"><span class="pre">%ConvertToSubClassCode</span></tt></a> code.</dd>
+<dt><tt class="docutils literal"><span class="pre">E</span></tt> (wrapped enum) [enum, PyTypeObject *]</dt>
+<dd><p class="first">Convert a named C/C++ <tt class="docutils literal"><span class="pre">enum</span></tt> to an instance of the corresponding
+Python named enum type.</p>
+<div class="last admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8. Instead you should use <tt class="docutils literal"><span class="pre">F</span></tt>.</p>
+</div>
+</dd>
+<dt><tt class="docutils literal"><span class="pre">F</span></tt> (wrapped enum) [enum, <tt class="xref docutils literal"><span class="pre">sipTypeDef</span></tt> *]</dt>
+<dd>Convert a named C/C++ <tt class="docutils literal"><span class="pre">enum</span></tt> to an instance of the corresponding
+Python named enum type.</dd>
+<dt><tt class="docutils literal"><span class="pre">G</span></tt> (unicode) [wchar_t *, <a title="SIP_SSIZE_T" class="reference internal" href="#SIP_SSIZE_T"><tt class="xref docutils literal"><span class="pre">SIP_SSIZE_T</span></tt></a>]</dt>
+<dd>Convert a C/C++ wide character array and its length to a Python unicode
+object. If the array is <tt class="docutils literal"><span class="pre">NULL</span></tt> then the length is ignored and the
+result is <tt class="docutils literal"><span class="pre">Py_None</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">N</span></tt> (wrapped instance) [<em>type</em> *, <tt class="xref docutils literal"><span class="pre">sipTypeDef</span></tt> *, PyObject *]</dt>
+<dd>Convert a new C structure, C++ class or mapped type instance to a
+Python object. Ownership of the instance is determined by the
+<tt class="docutils literal"><span class="pre">PyObject</span> <span class="pre">*</span></tt> argument. If it is <tt class="docutils literal"><span class="pre">NULL</span></tt> and the instance has
+already been wrapped then the ownership is unchanged. If it is
+<tt class="docutils literal"><span class="pre">NULL</span></tt> or <tt class="docutils literal"><span class="pre">Py_None</span></tt> then ownership will be with Python. Otherwise
+ownership will be with C/C++ and the instance associated with the
+<tt class="docutils literal"><span class="pre">PyObject</span> <span class="pre">*</span></tt> argument. The Python class is influenced by any
+applicable <a class="reference external" href="directives.html#directive-%ConvertToSubClassCode"><tt class="xref docutils literal"><span class="pre">%ConvertToSubClassCode</span></tt></a> code.</dd>
+<dt><tt class="docutils literal"><span class="pre">R</span></tt> (object) [PyObject *]</dt>
+<dd>The result is value passed without any conversions. The reference
+count is unaffected, i.e. a reference is taken.</dd>
+<dt><tt class="docutils literal"><span class="pre">S</span></tt> (object) [PyObject *]</dt>
+<dd>The result is value passed without any conversions. The reference
+count is incremented.</dd>
+<dt><tt class="docutils literal"><span class="pre">V</span></tt> (sip.voidptr) [void *]</dt>
+<dd>Convert a C/C++ <tt class="docutils literal"><span class="pre">void</span> <span class="pre">*</span></tt> Python <a title="sip.voidptr" class="reference external" href="python_api.html#sip.voidptr"><tt class="xref docutils literal"><span class="pre">sip.voidptr</span></tt></a> object.</dd>
+</dl>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipCallMethod">
+PyObject *<tt class="descname">sipCallMethod</tt><big>(</big>int<em> *iserr</em>, PyObject<em> *method</em>, const char<em> *format</em>, ...<big>)</big><a class="headerlink" href="#sipCallMethod" title="Permalink to this definition">¶</a></dt>
+<dd><p>This calls a Python method passing a tuple of arguments based on a format
+string and associated values in a similar way to the Python
+<tt class="xref docutils literal"><span class="pre">PyObject_CallObject()</span></tt> function.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>iserr</em> &#8211; if this is not <tt class="docutils literal"><span class="pre">NULL</span></tt> then the location it points to is set to a
+non-zero value if there was an error.</li>
+<li><em>method</em> &#8211; the Python bound method to call.</li>
+<li><em>format</em> &#8211; the string of format characters (see <a title="sipBuildResult" class="reference internal" href="#sipBuildResult"><tt class="xref docutils literal"><span class="pre">sipBuildResult()</span></tt></a>).</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">If there was an error then <tt class="docutils literal"><span class="pre">NULL</span></tt> is returned and a Python exception
+is raised.</p>
+</td>
+</tr>
+</tbody>
+</table>
+<p>It is normally called by handwritten code specified with the
+<a class="reference external" href="directives.html#directive-%VirtualCatcherCode"><tt class="xref docutils literal"><span class="pre">%VirtualCatcherCode</span></tt></a> directive with method being the supplied
+<tt class="docutils literal"><span class="pre">sipMethod</span></tt>.</p>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipCanConvertToEnum">
+int <tt class="descname">sipCanConvertToEnum</tt><big>(</big>PyObject<em> *obj</em>, const sipTypeDef<em> *td</em><big>)</big><a class="headerlink" href="#sipCanConvertToEnum" title="Permalink to this definition">¶</a></dt>
+<dd><p>This checks if a Python object can be converted to a named enum.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>obj</em> &#8211; the Python object.</li>
+<li><em>td</em> &#8211; the enum&#8217;s <a class="reference internal" href="#ref-type-structures"><em>generated type structure</em></a>.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">a non-zero value if the object can be converted.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipCanConvertToInstance">
+int <tt class="descname">sipCanConvertToInstance</tt><big>(</big>PyObject<em> *obj</em>, <a title="sipWrapperType" class="reference internal" href="#sipWrapperType">sipWrapperType</a><em> *type</em>, int<em> flags</em><big>)</big><a class="headerlink" href="#sipCanConvertToInstance" title="Permalink to this definition">¶</a></dt>
+<dd><p>This checks if a Python object can be converted to an instance of a C
+structure or C++ class.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>obj</em> &#8211; the Python object.</li>
+<li><em>type</em> &#8211; the C/C++ type&#8217;s <a class="reference internal" href="#ref-type-objects"><em>generated type object</em></a>.</li>
+<li><em>flags</em> &#8211; any combination of the <a title="SIP_NOT_NONE" class="reference internal" href="#SIP_NOT_NONE"><tt class="xref docutils literal"><span class="pre">SIP_NOT_NONE</span></tt></a> and
+<a title="SIP_NO_CONVERTORS" class="reference internal" href="#SIP_NO_CONVERTORS"><tt class="xref docutils literal"><span class="pre">SIP_NO_CONVERTORS</span></tt></a> flags.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">a non-zero value if the object can be converted.</p>
+</td>
+</tr>
+</tbody>
+</table>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8. Instead you should use
+<a title="sipCanConvertToType" class="reference internal" href="#sipCanConvertToType"><tt class="xref docutils literal"><span class="pre">sipCanConvertToType()</span></tt></a>.</p>
+</div>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipCanConvertToMappedType">
+int <tt class="descname">sipCanConvertToMappedType</tt><big>(</big>PyObject<em> *obj</em>, const sipMappedType<em> *mt</em>, int<em> flags</em><big>)</big><a class="headerlink" href="#sipCanConvertToMappedType" title="Permalink to this definition">¶</a></dt>
+<dd><p>This checks if a Python object can be converted to an instance of a C
+structure or C++ class which has been implemented as a mapped type.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>obj</em> &#8211; the Python object.</li>
+<li><em>mt</em> &#8211; the opaque structure returned by <a title="sipFindMappedType" class="reference internal" href="#sipFindMappedType"><tt class="xref docutils literal"><span class="pre">sipFindMappedType()</span></tt></a>.</li>
+<li><em>flags</em> &#8211; this may be the <a title="SIP_NOT_NONE" class="reference internal" href="#SIP_NOT_NONE"><tt class="xref docutils literal"><span class="pre">SIP_NOT_NONE</span></tt></a> flag.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">a non-zero value if the object can be converted.</p>
+</td>
+</tr>
+</tbody>
+</table>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8. Instead you should use
+<a title="sipCanConvertToType" class="reference internal" href="#sipCanConvertToType"><tt class="xref docutils literal"><span class="pre">sipCanConvertToType()</span></tt></a>.</p>
+</div>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipCanConvertToType">
+int <tt class="descname">sipCanConvertToType</tt><big>(</big>PyObject<em> *obj</em>, const sipTypeDef<em> *td</em>, int<em> flags</em><big>)</big><a class="headerlink" href="#sipCanConvertToType" title="Permalink to this definition">¶</a></dt>
+<dd><p>This checks if a Python object can be converted to an instance of a C
+structure, C++ class or mapped type.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>obj</em> &#8211; the Python object.</li>
+<li><em>td</em> &#8211; the C/C++ type&#8217;s <a class="reference internal" href="#ref-type-structures"><em>generated type structure</em></a>.</li>
+<li><em>flags</em> &#8211; any combination of the <a title="SIP_NOT_NONE" class="reference internal" href="#SIP_NOT_NONE"><tt class="xref docutils literal"><span class="pre">SIP_NOT_NONE</span></tt></a> and
+<a title="SIP_NO_CONVERTORS" class="reference internal" href="#SIP_NO_CONVERTORS"><tt class="xref docutils literal"><span class="pre">SIP_NO_CONVERTORS</span></tt></a> flags.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">a non-zero value if the object can be converted.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipClassName">
+PyObject *<tt class="descname">sipClassName</tt><big>(</big>PyObject<em> *obj</em><big>)</big><a class="headerlink" href="#sipClassName" title="Permalink to this definition">¶</a></dt>
+<dd><p>This gets the class name of a wrapped instance as a Python string. It
+comes with a reference.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>obj</em> &#8211; the wrapped instance.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the name of the instance&#8217;s class.</td>
+</tr>
+</tbody>
+</table>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p>This is deprecated from SIP v4.8. Instead you should use the
+following:</p>
+<div class="last highlight-python"><pre>PyString_FromString(obj-&gt;ob_type-&gt;tp_name)</pre>
+</div>
+</div>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipConvertFromConstVoidPtr">
+PyObject *<tt class="descname">sipConvertFromConstVoidPtr</tt><big>(</big>const void<em> *cpp</em><big>)</big><a class="headerlink" href="#sipConvertFromConstVoidPtr" title="Permalink to this definition">¶</a></dt>
+<dd><p>This creates a <a title="sip.voidptr" class="reference external" href="python_api.html#sip.voidptr"><tt class="xref docutils literal"><span class="pre">sip.voidptr</span></tt></a> object for a memory address. The
+object will not be writeable and has no associated size.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>cpp</em> &#8211; the memory address.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the <a title="sip.voidptr" class="reference external" href="python_api.html#sip.voidptr"><tt class="xref docutils literal"><span class="pre">sip.voidptr</span></tt></a> object.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipConvertFromConstVoidPtrAndSize">
+PyObject *<tt class="descname">sipConvertFromConstVoidPtrAndSize</tt><big>(</big>const void<em> *cpp</em>, <a title="SIP_SSIZE_T" class="reference internal" href="#SIP_SSIZE_T">SIP_SSIZE_T</a><em> size</em><big>)</big><a class="headerlink" href="#sipConvertFromConstVoidPtrAndSize" title="Permalink to this definition">¶</a></dt>
+<dd><p>This creates a <a title="sip.voidptr" class="reference external" href="python_api.html#sip.voidptr"><tt class="xref docutils literal"><span class="pre">sip.voidptr</span></tt></a> object for a memory address. The
+object will not be writeable and can be used as an immutable buffer object.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>cpp</em> &#8211; the memory address.</li>
+<li><em>size</em> &#8211; the size associated with the address.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the <a title="sip.voidptr" class="reference external" href="python_api.html#sip.voidptr"><tt class="xref docutils literal"><span class="pre">sip.voidptr</span></tt></a> object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipConvertFromEnum">
+PyObject *<tt class="descname">sipConvertFromEnum</tt><big>(</big>int<em> eval</em>, const sipTypeDef<em> *td</em><big>)</big><a class="headerlink" href="#sipConvertFromEnum" title="Permalink to this definition">¶</a></dt>
+<dd><p>This converts a named C/C++ <tt class="docutils literal"><span class="pre">enum</span></tt> to an instance of the corresponding
+generated Python type.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>eval</em> &#8211; the enumerated value to convert.</li>
+<li><em>td</em> &#8211; the enum&#8217;s <a class="reference internal" href="#ref-type-structures"><em>generated type structure</em></a>.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the Python object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipConvertFromInstance">
+PyObject *<tt class="descname">sipConvertFromInstance</tt><big>(</big>void<em> *cpp</em>, <a title="sipWrapperType" class="reference internal" href="#sipWrapperType">sipWrapperType</a><em> *type</em>, PyObject<em> *transferObj</em><big>)</big><a class="headerlink" href="#sipConvertFromInstance" title="Permalink to this definition">¶</a></dt>
+<dd><p>This converts a C structure or a C++ class instance to an instance of the
+corresponding generated Python type.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>cpp</em> &#8211; the C/C++ instance.</li>
+<li><em>type</em> &#8211; the type&#8217;s <a class="reference internal" href="#ref-type-objects"><em>generated type object</em></a>.</li>
+<li><em>transferObj</em> &#8211; this controls the ownership of the returned value.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the Python object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+<p>If the C/C++ instance has already been wrapped then the result is a
+new reference to the existing class instance object.</p>
+<p>If <em>transferObj</em> is <tt class="docutils literal"><span class="pre">NULL</span></tt> and the instance has already been wrapped then
+the ownership is unchanged.</p>
+<p>If <em>transferObj</em> is <tt class="docutils literal"><span class="pre">NULL</span></tt> and the instance is newly wrapped then
+ownership will be with C/C++.</p>
+<p>If <em>transferObj</em> is <tt class="docutils literal"><span class="pre">Py_None</span></tt> then ownership is transferred to Python via
+a call to <a title="sipTransferBack" class="reference internal" href="#sipTransferBack"><tt class="xref docutils literal"><span class="pre">sipTransferBack()</span></tt></a>.</p>
+<p>Otherwise ownership is transferred to C/C++ and the instance associated
+with <em>transferObj</em> via a call to <a title="sipTransferTo" class="reference internal" href="#sipTransferTo"><tt class="xref docutils literal"><span class="pre">sipTransferTo()</span></tt></a>.</p>
+<p>The Python type is influenced by any applicable
+<a class="reference external" href="directives.html#directive-%ConvertToSubClassCode"><tt class="xref docutils literal"><span class="pre">%ConvertToSubClassCode</span></tt></a> code.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8. Instead you should use
+<a title="sipConvertFromType" class="reference internal" href="#sipConvertFromType"><tt class="xref docutils literal"><span class="pre">sipConvertFromType()</span></tt></a>.</p>
+</div>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipConvertFromMappedType">
+PyObject *<tt class="descname">sipConvertFromMappedType</tt><big>(</big>void<em> *cpp</em>, const sipMappedType<em> *mt</em>, PyObject<em> *transferObj</em><big>)</big><a class="headerlink" href="#sipConvertFromMappedType" title="Permalink to this definition">¶</a></dt>
+<dd><p>This converts a C structure or a C++ class instance wrapped as a mapped
+type to an instance of the corresponding generated Python type.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>cpp</em> &#8211; the C/C++ instance.</li>
+<li><em>mt</em> &#8211; the opaque structure returned by <a title="sipFindMappedType" class="reference internal" href="#sipFindMappedType"><tt class="xref docutils literal"><span class="pre">sipFindMappedType()</span></tt></a>.</li>
+<li><em>transferObj</em> &#8211; this controls the ownership of the returned value.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the Python object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+<p>If <em>transferObj</em> is <tt class="docutils literal"><span class="pre">NULL</span></tt> then the ownership is unchanged.</p>
+<p>If <em>transferObj</em> is <tt class="docutils literal"><span class="pre">Py_None</span></tt> then ownership is transferred to Python
+via a call to <a title="sipTransferBack" class="reference internal" href="#sipTransferBack"><tt class="xref docutils literal"><span class="pre">sipTransferBack()</span></tt></a>.</p>
+<p>Otherwise ownership is transferred to C/C++ and the instance associated
+with <em>transferObj</em> argument via a call to <a title="sipTransferTo" class="reference internal" href="#sipTransferTo"><tt class="xref docutils literal"><span class="pre">sipTransferTo()</span></tt></a>.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8. Instead you should use
+<a title="sipConvertFromType" class="reference internal" href="#sipConvertFromType"><tt class="xref docutils literal"><span class="pre">sipConvertFromType()</span></tt></a>.</p>
+</div>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipConvertFromNamedEnum">
+PyObject *<tt class="descname">sipConvertFromNamedEnum</tt><big>(</big>int<em> eval</em>, PyTypeObject<em> *type</em><big>)</big><a class="headerlink" href="#sipConvertFromNamedEnum" title="Permalink to this definition">¶</a></dt>
+<dd><p>This converts a named C/C++ <tt class="docutils literal"><span class="pre">enum</span></tt> to an instance of the corresponding
+generated Python type.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>eval</em> &#8211; the enumerated value to convert.</li>
+<li><em>type</em> &#8211; the enum&#8217;s <a class="reference internal" href="#ref-type-objects"><em>generated type object</em></a>.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the Python object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8. Instead you should use
+<a title="sipConvertFromEnum" class="reference internal" href="#sipConvertFromEnum"><tt class="xref docutils literal"><span class="pre">sipConvertFromEnum()</span></tt></a>.</p>
+</div>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipConvertFromNewInstance">
+PyObject *<tt class="descname">sipConvertFromNewInstance</tt><big>(</big>void<em> *cpp</em>, <a title="sipWrapperType" class="reference internal" href="#sipWrapperType">sipWrapperType</a><em> *type</em>, PyObject<em> *transferObj</em><big>)</big><a class="headerlink" href="#sipConvertFromNewInstance" title="Permalink to this definition">¶</a></dt>
+<dd><p>This converts a new C structure or a C++ class instance to an instance of
+the corresponding generated Python type.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>cpp</em> &#8211; the C/C++ instance.</li>
+<li><em>type</em> &#8211; the type&#8217;s <a class="reference internal" href="#ref-type-objects"><em>generated type object</em></a>.</li>
+<li><em>transferObj</em> &#8211; this controls the ownership of the returned value.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the Python object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+<p>If <em>transferObj</em> is <tt class="docutils literal"><span class="pre">NULL</span></tt> or <tt class="docutils literal"><span class="pre">Py_None</span></tt> then ownership will be with
+Python.</p>
+<p>Otherwise ownership will be with C/C++ and the instance associated with
+<em>transferObj</em>.</p>
+<p>The Python type is influenced by any applicable
+<a class="reference external" href="directives.html#directive-%ConvertToSubClassCode"><tt class="xref docutils literal"><span class="pre">%ConvertToSubClassCode</span></tt></a> code.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8. Instead you should use
+<a title="sipConvertFromNewType" class="reference internal" href="#sipConvertFromNewType"><tt class="xref docutils literal"><span class="pre">sipConvertFromNewType()</span></tt></a>.</p>
+</div>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipConvertFromNewType">
+PyObject *<tt class="descname">sipConvertFromNewType</tt><big>(</big>void<em> *cpp</em>, const sipTypeDef<em> *td</em>, PyObject<em> *transferObj</em><big>)</big><a class="headerlink" href="#sipConvertFromNewType" title="Permalink to this definition">¶</a></dt>
+<dd><p>This converts a new C structure or a C++ class instance to an instance of
+the corresponding generated Python type.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>cpp</em> &#8211; the C/C++ instance.</li>
+<li><em>td</em> &#8211; the type&#8217;s <a class="reference internal" href="#ref-type-structures"><em>generated type structure</em></a>.</li>
+<li><em>transferObj</em> &#8211; this controls the ownership of the returned value.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the Python object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+<p>If <em>transferObj</em> is <tt class="docutils literal"><span class="pre">NULL</span></tt> or <tt class="docutils literal"><span class="pre">Py_None</span></tt> then ownership will be with
+Python.</p>
+<p>Otherwise ownership will be with C/C++ and the instance associated with
+<em>transferObj</em>.</p>
+<p>The Python type is influenced by any applicable
+<a class="reference external" href="directives.html#directive-%ConvertToSubClassCode"><tt class="xref docutils literal"><span class="pre">%ConvertToSubClassCode</span></tt></a> code.</p>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipConvertFromSequenceIndex">
+<a title="SIP_SSIZE_T" class="reference internal" href="#SIP_SSIZE_T">SIP_SSIZE_T</a> <tt class="descname">sipConvertFromSequenceIndex</tt><big>(</big><a title="SIP_SSIZE_T" class="reference internal" href="#SIP_SSIZE_T">SIP_SSIZE_T</a><em> idx</em>, <a title="SIP_SSIZE_T" class="reference internal" href="#SIP_SSIZE_T">SIP_SSIZE_T</a><em> len</em><big>)</big><a class="headerlink" href="#sipConvertFromSequenceIndex" title="Permalink to this definition">¶</a></dt>
+<dd><p>This converts a Python sequence index (i.e. where a negative value refers
+to the offset from the end of the sequence) to a C/C++ array index. If the
+index was out of range then a negative value is returned and a Python
+exception raised.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>idx</em> &#8211; the sequence index.</li>
+<li><em>len</em> &#8211; the length of the sequence.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the unsigned array index.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipConvertFromSliceObject">
+int <tt class="descname">sipConvertFromSliceObject</tt><big>(</big>PyObject<em> *slice</em>, <a title="SIP_SSIZE_T" class="reference internal" href="#SIP_SSIZE_T">SIP_SSIZE_T</a><em> length</em>, <a title="SIP_SSIZE_T" class="reference internal" href="#SIP_SSIZE_T">SIP_SSIZE_T</a><em> *start</em>, <a title="SIP_SSIZE_T" class="reference internal" href="#SIP_SSIZE_T">SIP_SSIZE_T</a><em> *stop</em>, <a title="SIP_SSIZE_T" class="reference internal" href="#SIP_SSIZE_T">SIP_SSIZE_T</a><em> *step</em>, <a title="SIP_SSIZE_T" class="reference internal" href="#SIP_SSIZE_T">SIP_SSIZE_T</a><em> *slicelength</em><big>)</big><a class="headerlink" href="#sipConvertFromSliceObject" title="Permalink to this definition">¶</a></dt>
+<dd>This is a thin wrapper around the Python <tt class="xref docutils literal"><span class="pre">PySlice_GetIndicesEx()</span></tt>
+function provided to make it easier to write handwritten code that is
+compatible with SIP v3.x and versions of Python earlier that v2.3.</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipConvertFromType">
+PyObject *<tt class="descname">sipConvertFromType</tt><big>(</big>void<em> *cpp</em>, const sipTypeDef<em> *td</em>, PyObject<em> *transferObj</em><big>)</big><a class="headerlink" href="#sipConvertFromType" title="Permalink to this definition">¶</a></dt>
+<dd><p>This converts a C structure or a C++ class instance to an instance of the
+corresponding generated Python type.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>cpp</em> &#8211; the C/C++ instance.</li>
+<li><em>td</em> &#8211; the type&#8217;s <a class="reference internal" href="#ref-type-structures"><em>generated type structure</em></a>.</li>
+<li><em>transferObj</em> &#8211; this controls the ownership of the returned value.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the Python object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+<p>If the C/C++ instance has already been wrapped then the result is a new
+reference to the existing object.</p>
+<p>If <em>transferObj</em> is <tt class="docutils literal"><span class="pre">NULL</span></tt> and the instance has already been wrapped then
+the ownership is unchanged.</p>
+<p>If <em>transferObj</em> is <tt class="docutils literal"><span class="pre">NULL</span></tt> and the instance is newly wrapped then
+ownership will be with C/C++.</p>
+<p>If <em>transferObj</em> is <tt class="docutils literal"><span class="pre">Py_None</span></tt> then ownership is transferred to Python via
+a call to <a title="sipTransferBack" class="reference internal" href="#sipTransferBack"><tt class="xref docutils literal"><span class="pre">sipTransferBack()</span></tt></a>.</p>
+<p>Otherwise ownership is transferred to C/C++ and the instance associated
+with <em>transferObj</em> via a call to <a title="sipTransferTo" class="reference internal" href="#sipTransferTo"><tt class="xref docutils literal"><span class="pre">sipTransferTo()</span></tt></a>.</p>
+<p>The Python class is influenced by any applicable
+<a class="reference external" href="directives.html#directive-%ConvertToSubClassCode"><tt class="xref docutils literal"><span class="pre">%ConvertToSubClassCode</span></tt></a> code.</p>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipConvertFromVoidPtr">
+PyObject *<tt class="descname">sipConvertFromVoidPtr</tt><big>(</big>void<em> *cpp</em><big>)</big><a class="headerlink" href="#sipConvertFromVoidPtr" title="Permalink to this definition">¶</a></dt>
+<dd><p>This creates a <a title="sip.voidptr" class="reference external" href="python_api.html#sip.voidptr"><tt class="xref docutils literal"><span class="pre">sip.voidptr</span></tt></a> object for a memory address. The
+object will be writeable but has no associated size.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>cpp</em> &#8211; the memory address.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the <a title="sip.voidptr" class="reference external" href="python_api.html#sip.voidptr"><tt class="xref docutils literal"><span class="pre">sip.voidptr</span></tt></a> object.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipConvertFromVoidPtrAndSize">
+PyObject *<tt class="descname">sipConvertFromVoidPtrAndSize</tt><big>(</big>void<em> *cpp</em>, <a title="SIP_SSIZE_T" class="reference internal" href="#SIP_SSIZE_T">SIP_SSIZE_T</a><em> size</em><big>)</big><a class="headerlink" href="#sipConvertFromVoidPtrAndSize" title="Permalink to this definition">¶</a></dt>
+<dd><p>This creates a <a title="sip.voidptr" class="reference external" href="python_api.html#sip.voidptr"><tt class="xref docutils literal"><span class="pre">sip.voidptr</span></tt></a> object for a memory address. The
+object will be writeable and can be used as a mutable buffer object.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>cpp</em> &#8211; the memory address.</li>
+<li><em>size</em> &#8211; the size associated with the address.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the <a title="sip.voidptr" class="reference external" href="python_api.html#sip.voidptr"><tt class="xref docutils literal"><span class="pre">sip.voidptr</span></tt></a> object.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipConvertToInstance">
+void *<tt class="descname">sipConvertToInstance</tt><big>(</big>PyObject<em> *obj</em>, <a title="sipWrapperType" class="reference internal" href="#sipWrapperType">sipWrapperType</a><em> *type</em>, PyObject<em> *transferObj</em>, int<em> flags</em>, int<em> *state</em>, int<em> *iserr</em><big>)</big><a class="headerlink" href="#sipConvertToInstance" title="Permalink to this definition">¶</a></dt>
+<dd><p>This converts a Python object to an instance of a C structure or C++ class
+assuming that a previous call to <a title="sipCanConvertToInstance" class="reference internal" href="#sipCanConvertToInstance"><tt class="xref docutils literal"><span class="pre">sipCanConvertToInstance()</span></tt></a> has
+been successful.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>obj</em> &#8211; the Python object.</li>
+<li><em>type</em> &#8211; the type&#8217;s <a class="reference internal" href="#ref-type-objects"><em>generated type object</em></a>.</li>
+<li><em>transferObj</em> &#8211; this controls any ownership changes to <em>obj</em>.</li>
+<li><em>flags</em> &#8211; any combination of the <a title="SIP_NOT_NONE" class="reference internal" href="#SIP_NOT_NONE"><tt class="xref docutils literal"><span class="pre">SIP_NOT_NONE</span></tt></a> and
+<a title="SIP_NO_CONVERTORS" class="reference internal" href="#SIP_NO_CONVERTORS"><tt class="xref docutils literal"><span class="pre">SIP_NO_CONVERTORS</span></tt></a> flags.</li>
+<li><em>state</em> &#8211; the state of the returned C/C++ instance is returned via this pointer.</li>
+<li><em>iserr</em> &#8211; the error flag is passed and updated via this pointer.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the C/C++ instance.</p>
+</td>
+</tr>
+</tbody>
+</table>
+<p>If <em>transferObj</em> is <tt class="docutils literal"><span class="pre">NULL</span></tt> then the ownership is unchanged.</p>
+<p>If <em>transferObj</em> is <tt class="docutils literal"><span class="pre">Py_None</span></tt> then ownership is transferred to Python via
+a call to <a title="sipTransferBack" class="reference internal" href="#sipTransferBack"><tt class="xref docutils literal"><span class="pre">sipTransferBack()</span></tt></a>.</p>
+<p>Otherwise ownership is transferred to C/C++ and <em>obj</em> associated with
+<em>transferObj</em> via a call to <a title="sipTransferTo" class="reference internal" href="#sipTransferTo"><tt class="xref docutils literal"><span class="pre">sipTransferTo()</span></tt></a>.</p>
+<p>If <em>state</em> is not <tt class="docutils literal"><span class="pre">NULL</span></tt> then the location it points to is set to
+describe the state of the returned C/C++ instance and is the value returned
+by any <a class="reference external" href="directives.html#directive-%ConvertToTypeCode"><tt class="xref docutils literal"><span class="pre">%ConvertToTypeCode</span></tt></a>. The calling code must then release
+the value at some point to prevent a memory leak by calling
+<a title="sipReleaseInstance" class="reference internal" href="#sipReleaseInstance"><tt class="xref docutils literal"><span class="pre">sipReleaseInstance()</span></tt></a>.</p>
+<p>If there is an error then the location <em>iserr</em> points to is set to a
+non-zero value. If it was initially a non-zero value then the conversion
+isn&#8217;t attempted in the first place. (This allows several calls to be made
+that share the same error flag so that it only needs to be tested once
+rather than after each call.)</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8. Instead you should use
+<a title="sipConvertToType" class="reference internal" href="#sipConvertToType"><tt class="xref docutils literal"><span class="pre">sipConvertToType()</span></tt></a>.</p>
+</div>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipConvertToMappedType">
+void *<tt class="descname">sipConvertToMappedType</tt><big>(</big>PyObject<em> *obj</em>, const sipMappedType<em> *mt</em>, PyObject<em> *transferObj</em>, int<em> flags</em>, int<em> *state</em>, int<em> *iserr</em><big>)</big><a class="headerlink" href="#sipConvertToMappedType" title="Permalink to this definition">¶</a></dt>
+<dd><p>This converts a Python object to an instance of a C structure or C++
+class that is implemented as a mapped type assuming that a previous call to
+<a title="sipCanConvertToMappedType" class="reference internal" href="#sipCanConvertToMappedType"><tt class="xref docutils literal"><span class="pre">sipCanConvertToMappedType()</span></tt></a> has been successful.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>obj</em> &#8211; the Python object.</li>
+<li><em>mt</em> &#8211; the opaque structure returned by <a title="sipFindMappedType" class="reference internal" href="#sipFindMappedType"><tt class="xref docutils literal"><span class="pre">sipFindMappedType()</span></tt></a>.</li>
+<li><em>transferObj</em> &#8211; this controls any ownership changes to <em>obj</em>.</li>
+<li><em>flags</em> &#8211; this may be the <a title="SIP_NOT_NONE" class="reference internal" href="#SIP_NOT_NONE"><tt class="xref docutils literal"><span class="pre">SIP_NOT_NONE</span></tt></a> flag.</li>
+<li><em>state</em> &#8211; the state of the returned C/C++ instance is returned via this pointer.</li>
+<li><em>iserr</em> &#8211; the error flag is passed and updated via this pointer.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the C/C++ instance.</p>
+</td>
+</tr>
+</tbody>
+</table>
+<p>If <em>transferObj</em> is <tt class="docutils literal"><span class="pre">NULL</span></tt> then the ownership is unchanged.</p>
+<p>If <em>transferObj</em> is <tt class="docutils literal"><span class="pre">Py_None</span></tt> then ownership is transferred to Python via
+a call to <a title="sipTransferBack" class="reference internal" href="#sipTransferBack"><tt class="xref docutils literal"><span class="pre">sipTransferBack()</span></tt></a>.</p>
+<p>Otherwise ownership is transferred to C/C++ and <em>obj</em> associated with
+<em>transferObj</em> via a call to <a title="sipTransferTo" class="reference internal" href="#sipTransferTo"><tt class="xref docutils literal"><span class="pre">sipTransferTo()</span></tt></a>.</p>
+<p>If <em>state</em> is not <tt class="docutils literal"><span class="pre">NULL</span></tt> then the location it points to is set to
+describe the state of the returned C/C++ instance and is the value returned
+by any <a class="reference external" href="directives.html#directive-%ConvertToTypeCode"><tt class="xref docutils literal"><span class="pre">%ConvertToTypeCode</span></tt></a>. The calling code must then release
+the value at some point to prevent a memory leak by calling
+<a title="sipReleaseMappedType" class="reference internal" href="#sipReleaseMappedType"><tt class="xref docutils literal"><span class="pre">sipReleaseMappedType()</span></tt></a>.</p>
+<p>If there is an error then the location <em>iserr</em> points to is set to a
+non-zero value. If it was initially a non-zero value then the conversion
+isn&#8217;t attempted in the first place. (This allows several calls to be made
+that share the same error flag so that it only needs to be tested once
+rather than after each call.)</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8. Instead you should use
+<a title="sipConvertToType" class="reference internal" href="#sipConvertToType"><tt class="xref docutils literal"><span class="pre">sipConvertToType()</span></tt></a></p>
+</div>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipConvertToType">
+void *<tt class="descname">sipConvertToType</tt><big>(</big>PyObject<em> *obj</em>, const sipTypeDef<em> *td</em>, PyObject<em> *transferObj</em>, int<em> flags</em>, int<em> *state</em>, int<em> *iserr</em><big>)</big><a class="headerlink" href="#sipConvertToType" title="Permalink to this definition">¶</a></dt>
+<dd><p>This converts a Python object to an instance of a C structure, C++ class or
+mapped type assuming that a previous call to <a title="sipCanConvertToType" class="reference internal" href="#sipCanConvertToType"><tt class="xref docutils literal"><span class="pre">sipCanConvertToType()</span></tt></a>
+has been successful.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>obj</em> &#8211; the Python object.</li>
+<li><em>td</em> &#8211; the type&#8217;s <a class="reference internal" href="#ref-type-structures"><em>generated type structure</em></a>.</li>
+<li><em>transferObj</em> &#8211; this controls any ownership changes to <em>obj</em>.</li>
+<li><em>flags</em> &#8211; any combination of the <a title="SIP_NOT_NONE" class="reference internal" href="#SIP_NOT_NONE"><tt class="xref docutils literal"><span class="pre">SIP_NOT_NONE</span></tt></a> and
+<a title="SIP_NO_CONVERTORS" class="reference internal" href="#SIP_NO_CONVERTORS"><tt class="xref docutils literal"><span class="pre">SIP_NO_CONVERTORS</span></tt></a> flags.</li>
+<li><em>state</em> &#8211; the state of the returned C/C++ instance is returned via this pointer.</li>
+<li><em>iserr</em> &#8211; the error flag is passed and updated via this pointer.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the C/C++ instance.</p>
+</td>
+</tr>
+</tbody>
+</table>
+<p>If <em>transferObj</em> is <tt class="docutils literal"><span class="pre">NULL</span></tt> then the ownership is unchanged. If it is
+<tt class="docutils literal"><span class="pre">Py_None</span></tt> then ownership is transferred to Python via a call to
+<a title="sipTransferBack" class="reference internal" href="#sipTransferBack"><tt class="xref docutils literal"><span class="pre">sipTransferBack()</span></tt></a>.</p>
+<p>Otherwise ownership is transferred to C/C++ and <em>obj</em> associated with
+<em>transferObj</em> via a call to <a title="sipTransferTo" class="reference internal" href="#sipTransferTo"><tt class="xref docutils literal"><span class="pre">sipTransferTo()</span></tt></a>.</p>
+<p>If <em>state</em> is not <tt class="docutils literal"><span class="pre">NULL</span></tt> then the location it points to is set to
+describe the state of the returned C/C++ instance and is the value returned
+by any <a class="reference external" href="directives.html#directive-%ConvertToTypeCode"><tt class="xref docutils literal"><span class="pre">%ConvertToTypeCode</span></tt></a>. The calling code must then release
+the value at some point to prevent a memory leak by calling
+<a title="sipReleaseType" class="reference internal" href="#sipReleaseType"><tt class="xref docutils literal"><span class="pre">sipReleaseType()</span></tt></a>.</p>
+<p>If there is an error then the location <em>iserr</em> points to is set to a
+non-zero value. If it was initially a non-zero value then the conversion
+isn&#8217;t attempted in the first place. (This allows several calls to be made
+that share the same error flag so that it only needs to be tested once
+rather than after each call.)</p>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipConvertToVoidPtr">
+void *<tt class="descname">sipConvertToVoidPtr</tt><big>(</big>PyObject<em> *obj</em><big>)</big><a class="headerlink" href="#sipConvertToVoidPtr" title="Permalink to this definition">¶</a></dt>
+<dd><p>This converts a Python object to a memory address.
+<tt class="xref docutils literal"><span class="pre">PyErr_Occurred()</span></tt> must be used to determine if the conversion was
+successful.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>obj</em> &#8211; the Python object which may be <tt class="docutils literal"><span class="pre">Py_None</span></tt>, a <a title="sip.voidptr" class="reference external" href="python_api.html#sip.voidptr"><tt class="xref docutils literal"><span class="pre">sip.voidptr</span></tt></a> or a
+<tt class="xref docutils literal"><span class="pre">PyCObject</span></tt>.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the memory address.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipExportSymbol">
+int <tt class="descname">sipExportSymbol</tt><big>(</big>const char<em> *name</em>, void<em> *sym</em><big>)</big><a class="headerlink" href="#sipExportSymbol" title="Permalink to this definition">¶</a></dt>
+<dd><p>Python does not allow extension modules to directly access symbols in
+another extension module. This exports a symbol, referenced by a name,
+that can subsequently be imported, using <a title="sipImportSymbol" class="reference internal" href="#sipImportSymbol"><tt class="xref docutils literal"><span class="pre">sipImportSymbol()</span></tt></a>, by
+another module.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>name</em> &#8211; the name of the symbol.</li>
+<li><em>sym</em> &#8211; the value of the symbol.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">0 if there was no error. A negative value is returned if <em>name</em> is
+already associated with a symbol or there was some other error.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipFindClass">
+<a title="sipWrapperType" class="reference internal" href="#sipWrapperType">sipWrapperType</a> *<tt class="descname">sipFindClass</tt><big>(</big>const char<em> *type</em><big>)</big><a class="headerlink" href="#sipFindClass" title="Permalink to this definition">¶</a></dt>
+<dd><p>This returns a pointer to the <a class="reference internal" href="#ref-type-objects"><em>generated type object
+</em></a> corresponding to a C/C++ type.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>type</em> &#8211; the C/C++ declaration of the type.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the generated type object. This will not change and may be saved in a
+static cache. <tt class="docutils literal"><span class="pre">NULL</span></tt> is returned if the C/C++ type doesn&#8217;t exist.</td>
+</tr>
+</tbody>
+</table>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8. Instead you should use
+<a title="sipFindType" class="reference internal" href="#sipFindType"><tt class="xref docutils literal"><span class="pre">sipFindType()</span></tt></a>.</p>
+</div>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipFindMappedType">
+const sipMappedType *<tt class="descname">sipFindMappedType</tt><big>(</big>const char<em> *type</em><big>)</big><a class="headerlink" href="#sipFindMappedType" title="Permalink to this definition">¶</a></dt>
+<dd><p>This returns a pointer to an opaque structure describing a mapped type.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>type</em> &#8211; the C/C++ declaration of the type.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the opaque structure. This will not change and may be saved in a
+static cache. <tt class="docutils literal"><span class="pre">NULL</span></tt> is returned if the C/C++ type doesn&#8217;t exist.</td>
+</tr>
+</tbody>
+</table>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8. Instead you should use
+<a title="sipFindType" class="reference internal" href="#sipFindType"><tt class="xref docutils literal"><span class="pre">sipFindType()</span></tt></a>.</p>
+</div>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipFindNamedEnum">
+PyTypeObject *<tt class="descname">sipFindNamedEnum</tt><big>(</big>const char<em> *type</em><big>)</big><a class="headerlink" href="#sipFindNamedEnum" title="Permalink to this definition">¶</a></dt>
+<dd><p>This returns a pointer to the <a class="reference internal" href="#ref-enum-type-objects"><em>generated Python type object</em></a> corresponding to a named C/C++ enum.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>type</em> &#8211; the C/C++ declaration of the enum.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the generated Python type object. This will not change and may be
+saved in a static cache. <tt class="docutils literal"><span class="pre">NULL</span></tt> is returned if the C/C++ enum
+doesn&#8217;t exist.</td>
+</tr>
+</tbody>
+</table>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8. Instead you should use
+<a title="sipFindType" class="reference internal" href="#sipFindType"><tt class="xref docutils literal"><span class="pre">sipFindType()</span></tt></a>.</p>
+</div>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipFindType">
+const sipTypeDef *<tt class="descname">sipFindType</tt><big>(</big>const char<em> *type</em><big>)</big><a class="headerlink" href="#sipFindType" title="Permalink to this definition">¶</a></dt>
+<dd><p>This returns a pointer to the <a class="reference internal" href="#ref-type-structures"><em>generated type structure</em></a> corresponding to a C/C++ type.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>type</em> &#8211; the C/C++ declaration of the type.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the generated type structure. This will not change and may be saved in
+a static cache. <tt class="docutils literal"><span class="pre">NULL</span></tt> is returned if the C/C++ type doesn&#8217;t exist.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipForceConvertToInstance">
+void *<tt class="descname">sipForceConvertToInstance</tt><big>(</big>PyObject<em> *obj</em>, <a title="sipWrapperType" class="reference internal" href="#sipWrapperType">sipWrapperType</a><em> *type</em>, PyObject<em> *transferObj</em>, int<em> flags</em>, int<em> *state</em>, int<em> *iserr</em><big>)</big><a class="headerlink" href="#sipForceConvertToInstance" title="Permalink to this definition">¶</a></dt>
+<dd><p>This converts a Python object to an instance of a C structure or C++ class
+by calling <a title="sipCanConvertToInstance" class="reference internal" href="#sipCanConvertToInstance"><tt class="xref docutils literal"><span class="pre">sipCanConvertToInstance()</span></tt></a> and, if it is successfull,
+calling <a title="sipConvertToInstance" class="reference internal" href="#sipConvertToInstance"><tt class="xref docutils literal"><span class="pre">sipConvertToInstance()</span></tt></a>.</p>
+<p>See <a title="sipConvertToInstance" class="reference internal" href="#sipConvertToInstance"><tt class="xref docutils literal"><span class="pre">sipConvertToInstance()</span></tt></a> for a full description of the
+arguments.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8. Instead you should use
+<a title="sipForceConvertToType" class="reference internal" href="#sipForceConvertToType"><tt class="xref docutils literal"><span class="pre">sipForceConvertToType()</span></tt></a>.</p>
+</div>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipForceConvertToMappedType">
+void *<tt class="descname">sipForceConvertToMappedType</tt><big>(</big>PyObject<em> *obj</em>, const sipMappedType<em> *mt</em>, PyObject<em> *transferObj</em>, int<em> flags</em>, int<em> *state</em>, int<em> *iserr</em><big>)</big><a class="headerlink" href="#sipForceConvertToMappedType" title="Permalink to this definition">¶</a></dt>
+<dd><p>This converts a Python object to an instance of a C structure or C++ class
+which has been implemented as a mapped type by calling
+<a title="sipCanConvertToMappedType" class="reference internal" href="#sipCanConvertToMappedType"><tt class="xref docutils literal"><span class="pre">sipCanConvertToMappedType()</span></tt></a> and, if it is successfull, calling
+<a title="sipConvertToMappedType" class="reference internal" href="#sipConvertToMappedType"><tt class="xref docutils literal"><span class="pre">sipConvertToMappedType()</span></tt></a>.</p>
+<p>See <a title="sipConvertToMappedType" class="reference internal" href="#sipConvertToMappedType"><tt class="xref docutils literal"><span class="pre">sipConvertToMappedType()</span></tt></a> for a full description of the
+arguments.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8. Instead you should use
+<a title="sipForceConvertToType" class="reference internal" href="#sipForceConvertToType"><tt class="xref docutils literal"><span class="pre">sipForceConvertToType()</span></tt></a>.</p>
+</div>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipForceConvertToType">
+void *<tt class="descname">sipForceConvertToType</tt><big>(</big>PyObject<em> *obj</em>, const sipTypeDef<em> *td</em>, PyObject<em> *transferObj</em>, int<em> flags</em>, int<em> *state</em>, int<em> *iserr</em><big>)</big><a class="headerlink" href="#sipForceConvertToType" title="Permalink to this definition">¶</a></dt>
+<dd><p>This converts a Python object to an instance of a C structure, C++ class or
+mapped type by calling <a title="sipCanConvertToType" class="reference internal" href="#sipCanConvertToType"><tt class="xref docutils literal"><span class="pre">sipCanConvertToType()</span></tt></a> and, if it is
+successfull, calling <a title="sipConvertToType" class="reference internal" href="#sipConvertToType"><tt class="xref docutils literal"><span class="pre">sipConvertToType()</span></tt></a>.</p>
+<p>See <a title="sipConvertToType" class="reference internal" href="#sipConvertToType"><tt class="xref docutils literal"><span class="pre">sipConvertToType()</span></tt></a> for a full description of the arguments.</p>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipFree">
+void <tt class="descname">sipFree</tt><big>(</big>void<em> *mem</em><big>)</big><a class="headerlink" href="#sipFree" title="Permalink to this definition">¶</a></dt>
+<dd><p>This returns an area of memory allocated by <a title="sipMalloc" class="reference internal" href="#sipMalloc"><tt class="xref docutils literal"><span class="pre">sipMalloc()</span></tt></a> to the
+heap.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>mem</em> &#8211; the memory address.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipGetPyObject">
+PyObject *<tt class="descname">sipGetPyObject</tt><big>(</big>void<em> *cppptr</em>, const sipTypeDef<em> *td</em><big>)</big><a class="headerlink" href="#sipGetPyObject" title="Permalink to this definition">¶</a></dt>
+<dd><p>This returns a borrowed reference to the Python object for a C structure or
+C++ class instance.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>cppptr</em> &#8211; the pointer to the C/C++ instance.</li>
+<li><em>td</em> &#8211; the <a class="reference internal" href="#ref-type-structures"><em>generated type structure</em></a> corresponding
+to the C/C++ type.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the Python object or <tt class="docutils literal"><span class="pre">NULL</span></tt> (and no exception is raised) if the
+C/C++ instance hasn&#8217;t been wrapped.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipGetState">
+int <tt class="descname">sipGetState</tt><big>(</big>PyObject<em> *transferObj</em><big>)</big><a class="headerlink" href="#sipGetState" title="Permalink to this definition">¶</a></dt>
+<dd><p>The <a class="reference external" href="directives.html#directive-%ConvertToTypeCode"><tt class="xref docutils literal"><span class="pre">%ConvertToTypeCode</span></tt></a> directive requires that the provided
+code returns an <tt class="docutils literal"><span class="pre">int</span></tt> describing the state of the converted value. The
+state usually depends on any transfers of ownership that have been
+requested. This is a convenience function that returns the correct state
+when the converted value is a temporary.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>transferObj</em> &#8211; the object that describes the requested transfer of ownership.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the state of the converted value.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipGetWrapper">
+PyObject *<tt class="descname">sipGetWrapper</tt><big>(</big>void<em> *cppptr</em>, <a title="sipWrapperType" class="reference internal" href="#sipWrapperType">sipWrapperType</a><em> *type</em><big>)</big><a class="headerlink" href="#sipGetWrapper" title="Permalink to this definition">¶</a></dt>
+<dd><p>This returns a borrowed reference to the wrapped instance object for a C
+structure or C++ class instance.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>cppptr</em> &#8211; the pointer to the C/C++ instance.</li>
+<li><em>type</em> &#8211; the <a class="reference internal" href="#ref-type-objects"><em>generated type object</em></a> corresponding to
+the C/C++ type.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the Python object or <tt class="docutils literal"><span class="pre">NULL</span></tt> (and no exception is raised) if the
+C/C++ instance hasn&#8217;t been wrapped.</p>
+</td>
+</tr>
+</tbody>
+</table>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8. Instead you should use
+<a title="sipGetPyObject" class="reference internal" href="#sipGetPyObject"><tt class="xref docutils literal"><span class="pre">sipGetPyObject()</span></tt></a>.</p>
+</div>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipImportSymbol">
+void *<tt class="descname">sipImportSymbol</tt><big>(</big>const char<em> *name</em><big>)</big><a class="headerlink" href="#sipImportSymbol" title="Permalink to this definition">¶</a></dt>
+<dd><p>Python does not allow extension modules to directly access symbols in
+another extension module. This imports a symbol, referenced by a name,
+that has previously been exported, using <a title="sipExportSymbol" class="reference internal" href="#sipExportSymbol"><tt class="xref docutils literal"><span class="pre">sipExportSymbol()</span></tt></a>, by
+another module.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>name</em> &#8211; the name of the symbol.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the value of the symbol. <tt class="docutils literal"><span class="pre">NULL</span></tt> is returned if there is no such
+symbol.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="ctype">
+<dt id="sipIntTypeClassMap">
+<tt class="descname">sipIntTypeClassMap</tt><a class="headerlink" href="#sipIntTypeClassMap" title="Permalink to this definition">¶</a></dt>
+<dd><p>This C structure is used with <a title="sipMapIntToClass" class="reference internal" href="#sipMapIntToClass"><tt class="xref docutils literal"><span class="pre">sipMapIntToClass()</span></tt></a> to define a
+mapping between integer based RTTI and <a class="reference internal" href="#ref-type-objects"><em>generated type objects</em></a>. The structure elements are as follows.</p>
+<dl class="cmember">
+<dt id="typeInt">
+int <tt class="descname">typeInt</tt><a class="headerlink" href="#typeInt" title="Permalink to this definition">¶</a></dt>
+<dd>The integer RTTI.</dd></dl>
+
+<dl class="cmember">
+<dt>
+<tt class="descname">sipWrapperType **pyType.</tt></dt>
+<dd>A pointer to the corresponding generated type object.</dd></dl>
+
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8.</p>
+</div>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipIsAPIEnabled">
+int <tt class="descname">sipIsAPIEnabled</tt><big>(</big>const char<em> *name</em>, int<em> from</em>, int<em> to</em><big>)</big><a class="headerlink" href="#sipIsAPIEnabled" title="Permalink to this definition">¶</a></dt>
+<dd><p>
+<span class="versionmodified">New in version 4.9.</span></p>
+<p>This checks to see if the current version number of an API falls within a
+given range. See <a class="reference external" href="using.html#ref-incompat-apis"><em>Managing Incompatible APIs</em></a> for more detail.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>name</em> &#8211; the name of the API.</li>
+<li><em>from</em> &#8211; the lower bound of the range. For the API to be enabled its version
+number must be greater than or equal to <em>from</em>. If <em>from</em> is 0 then
+this check isn&#8217;t made.</li>
+<li><em>to</em> &#8211; the upper bound of the range. For the API to be enabled its version
+number must be less than <em>to</em>. If <em>to</em> is 0 then this check isn&#8217;t
+made.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">a non-zero value if the API is enabled.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipLong_AsUnsignedLong">
+unsigned long <tt class="descname">sipLong_AsUnsignedLong</tt><big>(</big>PyObject<em> *obj</em><big>)</big><a class="headerlink" href="#sipLong_AsUnsignedLong" title="Permalink to this definition">¶</a></dt>
+<dd>This function is a thin wrapper around <tt class="xref docutils literal"><span class="pre">PyLong_AsUnsignedLong()</span></tt>
+that works around a bug in Python v2.3.x and earlier when converting
+integer objects.</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipMalloc">
+void *<tt class="descname">sipMalloc</tt><big>(</big>size_t<em> nbytes</em><big>)</big><a class="headerlink" href="#sipMalloc" title="Permalink to this definition">¶</a></dt>
+<dd><p>This allocates an area of memory on the heap using the Python
+<tt class="xref docutils literal"><span class="pre">PyMem_Malloc()</span></tt> function. The memory is freed by calling
+<a title="sipFree" class="reference internal" href="#sipFree"><tt class="xref docutils literal"><span class="pre">sipFree()</span></tt></a>.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>nbytes</em> &#8211; the number of bytes to allocate.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the memory address. If there was an error then <tt class="docutils literal"><span class="pre">NULL</span></tt> is returned
+and a Python exception raised.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipMapIntToClass">
+<a title="sipWrapperType" class="reference internal" href="#sipWrapperType">sipWrapperType</a> *<tt class="descname">sipMapIntToClass</tt><big>(</big>int<em> type</em>, const <a title="sipIntTypeClassMap" class="reference internal" href="#sipIntTypeClassMap">sipIntTypeClassMap</a><em> *map</em>, int<em> maplen</em><big>)</big><a class="headerlink" href="#sipMapIntToClass" title="Permalink to this definition">¶</a></dt>
+<dd><p>This can be used in <a class="reference external" href="directives.html#directive-%ConvertToSubClassCode"><tt class="xref docutils literal"><span class="pre">%ConvertToSubClassCode</span></tt></a> code as a
+convenient way of converting integer based RTTI to the corresponding
+<a class="reference internal" href="#ref-type-objects"><em>generated type object</em></a>.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>type</em> &#8211; the integer RTTI.</li>
+<li><em>map</em> &#8211; the table of known RTTI and the corresponding type objects (see
+<a title="sipIntTypeClassMap" class="reference internal" href="#sipIntTypeClassMap"><tt class="xref docutils literal"><span class="pre">sipIntTypeClassMap</span></tt></a>). The entries in the table must be sorted
+in ascending order of RTTI.</li>
+<li><em>maplen</em> &#8211; the number of entries in the table.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the corresponding type object, or <tt class="docutils literal"><span class="pre">NULL</span></tt> if <em>type</em> wasn&#8217;t in <em>map</em>.</p>
+</td>
+</tr>
+</tbody>
+</table>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8.</p>
+</div>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipMapStringToClass">
+<a title="sipWrapperType" class="reference internal" href="#sipWrapperType">sipWrapperType</a> *<tt class="descname">sipMapStringToClass</tt><big>(</big>char<em> *type</em>, const <a title="sipStringTypeClassMap" class="reference internal" href="#sipStringTypeClassMap">sipStringTypeClassMap</a><em> *map</em>, int<em> maplen</em><big>)</big><a class="headerlink" href="#sipMapStringToClass" title="Permalink to this definition">¶</a></dt>
+<dd><p>This can be used in <a class="reference external" href="directives.html#directive-%ConvertToSubClassCode"><tt class="xref docutils literal"><span class="pre">%ConvertToSubClassCode</span></tt></a> code as a
+convenient way of converting <tt class="docutils literal"><span class="pre">'\0'</span></tt> terminated string based RTTI to the
+corresponding <a class="reference internal" href="#ref-type-objects"><em>generated type object</em></a>.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>type</em> &#8211; the string RTTI.</li>
+<li><em>map</em> &#8211; the table of known RTTI and the corresponding type objects (see
+<a title="sipStringTypeClassMap" class="reference internal" href="#sipStringTypeClassMap"><tt class="xref docutils literal"><span class="pre">sipStringTypeClassMap</span></tt></a>). The entries in the table must be
+sorted in ascending order of RTTI.</li>
+<li><em>maplen</em> &#8211; the number of entries in the table.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the corresponding type object, or <tt class="docutils literal"><span class="pre">NULL</span></tt> if <em>type</em> wasn&#8217;t in <em>map</em>.</p>
+</td>
+</tr>
+</tbody>
+</table>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8.</p>
+</div>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipParseResult">
+int <tt class="descname">sipParseResult</tt><big>(</big>int<em> *iserr</em>, PyObject<em> *method</em>, PyObject<em> *result</em>, const char<em> *format</em>, ...<big>)</big><a class="headerlink" href="#sipParseResult" title="Permalink to this definition">¶</a></dt>
+<dd><p>This converts a Python object (usually returned by a method) to C/C++ based
+on a format string and associated values in a similar way to the Python
+<tt class="xref docutils literal"><span class="pre">PyArg_ParseTuple()</span></tt> function.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>iserr</em> &#8211; if this is not <tt class="docutils literal"><span class="pre">NULL</span></tt> then the location it points to is set to a
+non-zero value if there was an error.</li>
+<li><em>method</em> &#8211; the Python method that returned <em>result</em>.</li>
+<li><em>result</em> &#8211; the Python object returned by <em>method</em>.</li>
+<li><em>format</em> &#8211; the format string.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">0 if there was no error. Otherwise a negative value is returned, and
+an exception raised.</p>
+</td>
+</tr>
+</tbody>
+</table>
+<p>This is normally called by handwritten code specified with the
+<a class="reference external" href="directives.html#directive-%VirtualCatcherCode"><tt class="xref docutils literal"><span class="pre">%VirtualCatcherCode</span></tt></a> directive with <em>method</em> being the supplied
+<tt class="docutils literal"><span class="pre">sipMethod</span></tt> and <em>result</em> being the value returned by
+<a title="sipCallMethod" class="reference internal" href="#sipCallMethod"><tt class="xref docutils literal"><span class="pre">sipCallMethod()</span></tt></a>.</p>
+<p>If <em>format</em> begins and ends with parentheses then <em>result</em> must be a Python
+tuple and the rest of <em>format</em> is applied to the tuple contents.</p>
+<p>In the following description the first letter is the format character, the
+entry in parentheses is the Python object type that the format character
+will convert, and the entry in brackets are the types of the C/C++ values
+to be passed.</p>
+<dl class="docutils">
+<dt><tt class="docutils literal"><span class="pre">ae</span></tt> (object) [char *]</dt>
+<dd>Convert a Python string-like object of length 1 to a C/C++ <tt class="docutils literal"><span class="pre">char</span></tt>
+according to the encoding <tt class="docutils literal"><span class="pre">e</span></tt>. <tt class="docutils literal"><span class="pre">e</span></tt> can either be <tt class="docutils literal"><span class="pre">A</span></tt> for ASCII,
+<tt class="docutils literal"><span class="pre">L</span></tt> for Latin-1, or <tt class="docutils literal"><span class="pre">8</span></tt> for UTF-8. For Python v2 the object may be
+either a string or a unicode object that can be encoded. For Python v3
+the object may either be a bytes object or a string object that can be
+encoded. An object that supports the buffer protocol may also be used.</dd>
+<dt><tt class="docutils literal"><span class="pre">b</span></tt> (integer) [bool *]</dt>
+<dd>Convert a Python integer to a C/C++ <tt class="docutils literal"><span class="pre">bool</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">c</span></tt> (string/bytes) [char *]</dt>
+<dd>Convert a Python v2 string object or a Python v3 bytes object of length
+1 to a C/C++ <tt class="docutils literal"><span class="pre">char</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">d</span></tt> (float) [double *]</dt>
+<dd>Convert a Python floating point number to a C/C++ <tt class="docutils literal"><span class="pre">double</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">e</span></tt> (integer) [enum *]</dt>
+<dd>Convert a Python integer to an anonymous C/C++ <tt class="docutils literal"><span class="pre">enum</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">f</span></tt> (float) [float *]</dt>
+<dd>Convert a Python floating point number to a C/C++ <tt class="docutils literal"><span class="pre">float</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">g</span></tt> (string/bytes) [const char **, <a title="SIP_SSIZE_T" class="reference internal" href="#SIP_SSIZE_T"><tt class="xref docutils literal"><span class="pre">SIP_SSIZE_T</span></tt></a> *]</dt>
+<dd>Convert a Python v2 string object or a Python v3 bytes object to a
+C/C++ character array and its length. If the Python object is
+<tt class="docutils literal"><span class="pre">Py_None</span></tt> then the array and length are <tt class="docutils literal"><span class="pre">NULL</span></tt> and zero
+respectively.</dd>
+<dt><tt class="docutils literal"><span class="pre">h</span></tt> (integer) [short *]</dt>
+<dd>Convert a Python integer to a C/C++ <tt class="docutils literal"><span class="pre">short</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">i</span></tt> (integer) [int *]</dt>
+<dd>Convert a Python integer to a C/C++ <tt class="docutils literal"><span class="pre">int</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">l</span></tt> (long) [long *]</dt>
+<dd>Convert a Python long to a C/C++ <tt class="docutils literal"><span class="pre">long</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">m</span></tt> (long) [unsigned long *]</dt>
+<dd>Convert a Python long to a C/C++ <tt class="docutils literal"><span class="pre">unsigned</span> <span class="pre">long</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">n</span></tt> (long) [long long *]</dt>
+<dd>Convert a Python long to a C/C++ <tt class="docutils literal"><span class="pre">long</span> <span class="pre">long</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">o</span></tt> (long) [unsigned long long *]</dt>
+<dd>Convert a Python long to a C/C++ <tt class="docutils literal"><span class="pre">unsigned</span> <span class="pre">long</span> <span class="pre">long</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">s</span></tt> (string/bytes) [const char **]</dt>
+<dd><p class="first">Convert a Python v2 string object or a Python v3 bytes object to a
+C/C++ <tt class="docutils literal"><span class="pre">'\0'</span></tt> terminated string. If the Python object is <tt class="docutils literal"><span class="pre">Py_None</span></tt>
+then the string is <tt class="docutils literal"><span class="pre">NULL</span></tt>.</p>
+<div class="last admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8. Instead you should use <tt class="docutils literal"><span class="pre">B</span></tt>.</p>
+</div>
+</dd>
+<dt><tt class="docutils literal"><span class="pre">t</span></tt> (long) [unsigned short *]</dt>
+<dd>Convert a Python long to a C/C++ <tt class="docutils literal"><span class="pre">unsigned</span> <span class="pre">short</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">u</span></tt> (long) [unsigned int *]</dt>
+<dd>Convert a Python long to a C/C++ <tt class="docutils literal"><span class="pre">unsigned</span> <span class="pre">int</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">w</span></tt> (unicode/string) [wchar_t *]</dt>
+<dd>Convert a Python v2 string or unicode object or a Python v3 string
+object of length 1 to a C/C++ wide character.</dd>
+<dt><tt class="docutils literal"><span class="pre">x</span></tt> (unicode/string) [wchar_t **]</dt>
+<dd>Convert a Python v2 string or unicode object or a Python v3 string
+object to a C/C++ <tt class="docutils literal"><span class="pre">L'\0'</span></tt> terminated wide character string. If the
+Python object is <tt class="docutils literal"><span class="pre">Py_None</span></tt> then the string is <tt class="docutils literal"><span class="pre">NULL</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">Ae</span></tt> (object) [int, const char **]</dt>
+<dd>Convert a Python string-like object to a C/C++ <tt class="docutils literal"><span class="pre">'\0'</span></tt> terminated
+string according to the encoding <tt class="docutils literal"><span class="pre">e</span></tt>. <tt class="docutils literal"><span class="pre">e</span></tt> can either be <tt class="docutils literal"><span class="pre">A</span></tt> for
+ASCII, <tt class="docutils literal"><span class="pre">L</span></tt> for Latin-1, or <tt class="docutils literal"><span class="pre">8</span></tt> for UTF-8. If the Python object is
+<tt class="docutils literal"><span class="pre">Py_None</span></tt> then the string is <tt class="docutils literal"><span class="pre">NULL</span></tt>. The integer uniquely
+identifies the object in the context defined by the <tt class="docutils literal"><span class="pre">S</span></tt> format
+character and allows an extra reference to the object to be kept to
+ensure that the string remains valid. For Python v2 the object may be
+either a string or a unicode object that can be encoded. For Python v3
+the object may either be a bytes object or a string object that can be
+encoded. An object that supports the buffer protocol may also be used.</dd>
+<dt><tt class="docutils literal"><span class="pre">B</span></tt> (string/bytes) [int, const char **]</dt>
+<dd>Convert a Python v2 string object or a Python v3 bytes object to a
+C/C++ <tt class="docutils literal"><span class="pre">'\0'</span></tt> terminated string. If the Python object is <tt class="docutils literal"><span class="pre">Py_None</span></tt>
+then the string is <tt class="docutils literal"><span class="pre">NULL</span></tt>. The integer uniquely identifies the
+object in the context defined by the <tt class="docutils literal"><span class="pre">S</span></tt> format character and allows
+an extra reference to the object to be kept to ensure that the string
+remains valid.</dd>
+<dt><tt class="docutils literal"><span class="pre">Cf</span></tt> (wrapped class) [<a title="sipWrapperType" class="reference internal" href="#sipWrapperType"><tt class="xref docutils literal"><span class="pre">sipWrapperType</span></tt></a> *, int *, void **]</dt>
+<dd><p class="first">Convert a Python object to a C structure or a C++ class instance and
+return its state as described in <a title="sipConvertToInstance" class="reference internal" href="#sipConvertToInstance"><tt class="xref docutils literal"><span class="pre">sipConvertToInstance()</span></tt></a>.
+<tt class="docutils literal"><span class="pre">f</span></tt> is a combination of the following flags encoded as an ASCII
+character by adding <tt class="docutils literal"><span class="pre">0</span></tt> to the combined value:</p>
+<blockquote>
+<p>0x01 disallows the conversion of <tt class="docutils literal"><span class="pre">Py_None</span></tt> to <tt class="docutils literal"><span class="pre">NULL</span></tt></p>
+<dl class="docutils">
+<dt>0x02 implements the <a class="reference external" href="annotations.html#fanno-Factory"><tt class="xref docutils literal"><span class="pre">Factory</span></tt></a> and <a class="reference external" href="annotations.html#fanno-TransferBack"><tt class="xref docutils literal"><span class="pre">TransferBack</span></tt></a></dt>
+<dd>annotations</dd>
+<dt>0x04 suppresses the return of the state of the returned C/C++</dt>
+<dd>instance. Note that the <tt class="docutils literal"><span class="pre">int</span> <span class="pre">*</span></tt> used to return the state is
+not passed if this flag is specified.</dd>
+</dl>
+</blockquote>
+<div class="last admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8. Instead you should use <tt class="docutils literal"><span class="pre">Hf</span></tt>.</p>
+</div>
+</dd>
+<dt><tt class="docutils literal"><span class="pre">Df</span></tt> (wrapped instance) [const <tt class="xref docutils literal"><span class="pre">sipTypeDef</span></tt> *, int *, void **]</dt>
+<dd><p class="first">Convert a Python object to a C structure, C++ class or mapped type
+instance and return its state as described in
+<a title="sipConvertToType" class="reference internal" href="#sipConvertToType"><tt class="xref docutils literal"><span class="pre">sipConvertToType()</span></tt></a>. <tt class="docutils literal"><span class="pre">f</span></tt> is a combination of the following
+flags encoded as an ASCII character by adding <tt class="docutils literal"><span class="pre">0</span></tt> to the combined
+value:</p>
+<blockquote>
+<p>0x01 disallows the conversion of <tt class="docutils literal"><span class="pre">Py_None</span></tt> to <tt class="docutils literal"><span class="pre">NULL</span></tt></p>
+<dl class="docutils">
+<dt>0x02 implements the <a class="reference external" href="annotations.html#fanno-Factory"><tt class="xref docutils literal"><span class="pre">Factory</span></tt></a> and <a class="reference external" href="annotations.html#fanno-TransferBack"><tt class="xref docutils literal"><span class="pre">TransferBack</span></tt></a></dt>
+<dd>annotations</dd>
+<dt>0x04 suppresses the return of the state of the returned C/C++</dt>
+<dd>instance. Note that the <tt class="docutils literal"><span class="pre">int</span> <span class="pre">*</span></tt> used to return the state is
+not passed if this flag is specified.</dd>
+</dl>
+</blockquote>
+<div class="last admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.10.1. Instead you should use
+<tt class="docutils literal"><span class="pre">Hf</span></tt>.</p>
+</div>
+</dd>
+<dt><tt class="docutils literal"><span class="pre">E</span></tt> (wrapped enum) [PyTypeObject *, enum *]</dt>
+<dd><p class="first">Convert a Python named enum type to the corresponding C/C++ <tt class="docutils literal"><span class="pre">enum</span></tt>.</p>
+<div class="last admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8. Instead you should use <tt class="docutils literal"><span class="pre">F</span></tt>.</p>
+</div>
+</dd>
+<dt><tt class="docutils literal"><span class="pre">F</span></tt> (wrapped enum) [<tt class="xref docutils literal"><span class="pre">sipTypeDef</span></tt> *, enum *]</dt>
+<dd>Convert a Python named enum type to the corresponding C/C++ <tt class="docutils literal"><span class="pre">enum</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">G</span></tt> (unicode/string) [wchar_t **, <a title="SIP_SSIZE_T" class="reference internal" href="#SIP_SSIZE_T"><tt class="xref docutils literal"><span class="pre">SIP_SSIZE_T</span></tt></a> *]</dt>
+<dd>Convert a Python v2 string or unicode object or a Python v3 string
+object to a C/C++ wide character array and its length. If the Python
+object is <tt class="docutils literal"><span class="pre">Py_None</span></tt> then the array and length are <tt class="docutils literal"><span class="pre">NULL</span></tt> and zero
+respectively.</dd>
+<dt><tt class="docutils literal"><span class="pre">Hf</span></tt> (wrapped instance) [const <tt class="xref docutils literal"><span class="pre">sipTypeDef</span></tt> *, int *, void **]</dt>
+<dd><p class="first">Convert a Python object to a C structure, C++ class or mapped type
+instance as described in <a title="sipConvertToType" class="reference internal" href="#sipConvertToType"><tt class="xref docutils literal"><span class="pre">sipConvertToType()</span></tt></a>. <tt class="docutils literal"><span class="pre">f</span></tt> is a
+combination of the following flags encoded as an ASCII character by
+adding <tt class="docutils literal"><span class="pre">0</span></tt> to the combined value:</p>
+<blockquote class="last">
+<p>0x01 disallows the conversion of <tt class="docutils literal"><span class="pre">Py_None</span></tt> to <tt class="docutils literal"><span class="pre">NULL</span></tt></p>
+<dl class="docutils">
+<dt>0x02 implements the <a class="reference external" href="annotations.html#fanno-Factory"><tt class="xref docutils literal"><span class="pre">Factory</span></tt></a> and <a class="reference external" href="annotations.html#fanno-TransferBack"><tt class="xref docutils literal"><span class="pre">TransferBack</span></tt></a></dt>
+<dd>annotations</dd>
+</dl>
+<p>0x04 returns a copy of the C/C++ instance.</p>
+</blockquote>
+</dd>
+<dt><tt class="docutils literal"><span class="pre">N</span></tt> (object) [PyTypeObject *, :PyObject **]</dt>
+<dd>A Python object is checked to see if it is a certain type and then
+returned without any conversions. The reference count is incremented.
+The Python object may be <tt class="docutils literal"><span class="pre">Py_None</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">O</span></tt> (object) [PyObject **]</dt>
+<dd>A Python object is returned without any conversions. The reference
+count is incremented.</dd>
+<dt><tt class="docutils literal"><span class="pre">S</span></tt> [<a title="sipSimpleWrapper" class="reference internal" href="#sipSimpleWrapper"><tt class="xref docutils literal"><span class="pre">sipSimpleWrapper</span></tt></a> *]</dt>
+<dd>This format character, if used, must be the first. It is used with
+other format characters to define a context and doesn&#8217;t itself convert
+an argument.</dd>
+<dt><tt class="docutils literal"><span class="pre">T</span></tt> (object) [PyTypeObject *, PyObject **]</dt>
+<dd>A Python object is checked to see if it is a certain type and then
+returned without any conversions. The reference count is incremented.
+The Python object may not be <tt class="docutils literal"><span class="pre">Py_None</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">V</span></tt> (<a title="sip.voidptr" class="reference external" href="python_api.html#sip.voidptr"><tt class="xref docutils literal"><span class="pre">sip.voidptr</span></tt></a>) [void *]</dt>
+<dd>Convert a Python <a title="sip.voidptr" class="reference external" href="python_api.html#sip.voidptr"><tt class="xref docutils literal"><span class="pre">sip.voidptr</span></tt></a> object to a C/C++ <tt class="docutils literal"><span class="pre">void</span> <span class="pre">*</span></tt>.</dd>
+<dt><tt class="docutils literal"><span class="pre">Z</span></tt> (object) []</dt>
+<dd>Check that a Python object is <tt class="docutils literal"><span class="pre">Py_None</span></tt>. No value is returned.</dd>
+</dl>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipRegisterAttributeGetter">
+int <tt class="descname">sipRegisterAttributeGetter</tt><big>(</big>const sipTypeDef<em> *td</em>, sipAttrGetterFunc<em> getter</em><big>)</big><a class="headerlink" href="#sipRegisterAttributeGetter" title="Permalink to this definition">¶</a></dt>
+<dd><p>This registers a handler that will called just before SIP needs to get an
+attribute from a wrapped type&#8217;s dictionary for the first time. The handler
+must then populate the type&#8217;s dictionary with any lazy attributes.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>td</em> &#8211; the optional <a class="reference internal" href="#ref-type-structures"><em>generated type structure</em></a> that
+determines which types the handler will be called for.</li>
+<li><em>getter</em> &#8211; the handler function.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">0 if there was no error, otherwise -1 is returned.</p>
+</td>
+</tr>
+</tbody>
+</table>
+<p>If <em>td</em> is not <tt class="docutils literal"><span class="pre">NULL</span></tt> then the handler will only be called for types with
+that type or that are sub-classed from it. Otherwise the handler will be
+called for all types.</p>
+<p>A handler has the following signature.</p>
+<p>int handler(const <tt class="xref docutils literal"><span class="pre">sipTypeDef</span></tt> *td, PyObject *dict)</p>
+<blockquote>
+<p><em>td</em> is the generated type definition of the type whose dictionary is
+to be populated.</p>
+<p><em>dict</em> is the dictionary to be populated.</p>
+<p>0 if there was no error, otherwise -1 is returned.</p>
+</blockquote>
+<p>See the section <a class="reference external" href="using.html#ref-lazy-type-attributes"><em>Lazy Type Attributes</em></a> for more details.</p>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipRegisterPyType">
+int <tt class="descname">sipRegisterPyType</tt><big>(</big>PyTypeObject<em> *type</em><big>)</big><a class="headerlink" href="#sipRegisterPyType" title="Permalink to this definition">¶</a></dt>
+<dd><p>This registers a Python type object that can be used as the meta-type or
+super-type of a wrapped C++ type.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>type</em> &#8211; the type object.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">0 if there was no error, otherwise -1 is returned.</td>
+</tr>
+</tbody>
+</table>
+<p>See the section <a class="reference external" href="using.html#ref-types-metatypes"><em>Types and Meta-types</em></a> for more details.</p>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipReleaseInstance">
+void <tt class="descname">sipReleaseInstance</tt><big>(</big>void<em> *cpp</em>, <a title="sipWrapperType" class="reference internal" href="#sipWrapperType">sipWrapperType</a><em> *type</em>, int<em> state</em><big>)</big><a class="headerlink" href="#sipReleaseInstance" title="Permalink to this definition">¶</a></dt>
+<dd><p>This destroys a wrapped C/C++ instance if it was a temporary instance. It
+is called after a call to either <a title="sipConvertToInstance" class="reference internal" href="#sipConvertToInstance"><tt class="xref docutils literal"><span class="pre">sipConvertToInstance()</span></tt></a> or
+<a title="sipForceConvertToInstance" class="reference internal" href="#sipForceConvertToInstance"><tt class="xref docutils literal"><span class="pre">sipForceConvertToInstance()</span></tt></a>.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><em>cpp</em> &#8211; the C/C++ instance.</li>
+<li><em>type</em> &#8211; the type&#8217;s <a class="reference internal" href="#ref-type-objects"><em>generated type object</em></a>.</li>
+<li><em>state</em> &#8211; describes the state of the C/C++ instance.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8. Instead you should use
+<a title="sipReleaseType" class="reference internal" href="#sipReleaseType"><tt class="xref docutils literal"><span class="pre">sipReleaseType()</span></tt></a>.</p>
+</div>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipReleaseMappedType">
+void <tt class="descname">sipReleaseMappedType</tt><big>(</big>void<em> *cpp</em>, const sipMappedType<em> *mt</em>, int<em> state</em><big>)</big><a class="headerlink" href="#sipReleaseMappedType" title="Permalink to this definition">¶</a></dt>
+<dd><p>This destroys a wrapped C/C++ mapped type if it was a temporary instance.
+It is called after a call to either <a title="sipConvertToMappedType" class="reference internal" href="#sipConvertToMappedType"><tt class="xref docutils literal"><span class="pre">sipConvertToMappedType()</span></tt></a> or
+<a title="sipForceConvertToMappedType" class="reference internal" href="#sipForceConvertToMappedType"><tt class="xref docutils literal"><span class="pre">sipForceConvertToMappedType()</span></tt></a>.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><em>cpp</em> &#8211; the C/C++ instance.</li>
+<li><em>mt</em> &#8211; the opaque structure returned by <a title="sipFindMappedType" class="reference internal" href="#sipFindMappedType"><tt class="xref docutils literal"><span class="pre">sipFindMappedType()</span></tt></a>.</li>
+<li><em>state</em> &#8211; describes the state of the C/C++ instance.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8. Instead you should use
+<a title="sipReleaseType" class="reference internal" href="#sipReleaseType"><tt class="xref docutils literal"><span class="pre">sipReleaseType()</span></tt></a>.</p>
+</div>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipReleaseType">
+void <tt class="descname">sipReleaseType</tt><big>(</big>void<em> *cpp</em>, const sipTypeDef<em> *td</em>, int<em> state</em><big>)</big><a class="headerlink" href="#sipReleaseType" title="Permalink to this definition">¶</a></dt>
+<dd><p>This destroys a wrapped C/C++ or mapped type instance if it was a temporary
+instance. It is called after a call to either <a title="sipConvertToType" class="reference internal" href="#sipConvertToType"><tt class="xref docutils literal"><span class="pre">sipConvertToType()</span></tt></a>
+or <a title="sipForceConvertToType" class="reference internal" href="#sipForceConvertToType"><tt class="xref docutils literal"><span class="pre">sipForceConvertToType()</span></tt></a>.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><em>cpp</em> &#8211; the C/C++ instance.</li>
+<li><em>td</em> &#8211; the type&#8217;s <a class="reference internal" href="#ref-type-structures"><em>generated type structure</em></a>.</li>
+<li><em>state</em> &#8211; describes the state of the C/C++ instance.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipResolveTypedef">
+const char *<tt class="descname">sipResolveTypedef</tt><big>(</big>const char<em> *name</em><big>)</big><a class="headerlink" href="#sipResolveTypedef" title="Permalink to this definition">¶</a></dt>
+<dd><p>This returns the value of a C/C++ typedef.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>name</em> &#8211; the name of the typedef.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the value of the typedef or <tt class="docutils literal"><span class="pre">NULL</span></tt> if there was no such typedef.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="ctype">
+<dt id="sipSimpleWrapper">
+<tt class="descname">sipSimpleWrapper</tt><a class="headerlink" href="#sipSimpleWrapper" title="Permalink to this definition">¶</a></dt>
+<dd><p>This is a C structure that represents a Python wrapped instance whose type
+is <tt class="xref docutils literal"><span class="pre">sip.simplewrapper</span></tt>. It is an extension of the <tt class="docutils literal"><span class="pre">PyObject</span></tt>
+structure and so may be safely cast to it.</p>
+<dl class="cmember">
+<dt id="user">
+PyObject *<tt class="descname">user</tt><a class="headerlink" href="#user" title="Permalink to this definition">¶</a></dt>
+<dd>This can be used for any purpose by handwritten code and will
+automatically be garbage collected at the appropriate time.</dd></dl>
+
+</dd></dl>
+
+<dl class="cvar">
+<dt id="sipSimpleWrapper_Type">
+PyTypeObject *<tt class="descname">sipSimpleWrapper_Type</tt><a class="headerlink" href="#sipSimpleWrapper_Type" title="Permalink to this definition">¶</a></dt>
+<dd>This is the type of a <a title="sipSimpleWrapper" class="reference internal" href="#sipSimpleWrapper"><tt class="xref docutils literal"><span class="pre">sipSimpleWrapper</span></tt></a> structure and is the C
+implementation of <tt class="xref docutils literal"><span class="pre">sip.simplewrapper</span></tt>. It may be safely cast to
+<a title="sipWrapperType" class="reference internal" href="#sipWrapperType"><tt class="xref docutils literal"><span class="pre">sipWrapperType</span></tt></a>.</dd></dl>
+
+<dl class="ctype">
+<dt id="sipStringTypeClassMap">
+<tt class="descname">sipStringTypeClassMap</tt><a class="headerlink" href="#sipStringTypeClassMap" title="Permalink to this definition">¶</a></dt>
+<dd><p>This C structure is used with <a title="sipMapStringToClass" class="reference internal" href="#sipMapStringToClass"><tt class="xref docutils literal"><span class="pre">sipMapStringToClass()</span></tt></a> to define a
+mapping between <tt class="docutils literal"><span class="pre">'\0'</span></tt> terminated string based RTTI and
+<a class="reference internal" href="#ref-type-objects"><em>Generated Type Objects</em></a>. The structure elements are as follows.</p>
+<dl class="cmember">
+<dt id="typeString">
+char *<tt class="descname">typeString</tt><a class="headerlink" href="#typeString" title="Permalink to this definition">¶</a></dt>
+<dd>The <tt class="docutils literal"><span class="pre">'\0'</span></tt> terminated string RTTI.</dd></dl>
+
+<dl class="cmember">
+<dt>
+<tt class="descname">sipWrapperType **pyType.</tt></dt>
+<dd>A pointer to the corresponding generated type object.</dd></dl>
+
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">This is deprecated from SIP v4.8.</p>
+</div>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipTransferBack">
+void <tt class="descname">sipTransferBack</tt><big>(</big>PyObject<em> *obj</em><big>)</big><a class="headerlink" href="#sipTransferBack" title="Permalink to this definition">¶</a></dt>
+<dd><p>This transfers ownership of a Python wrapped instance to Python (see
+<a class="reference external" href="using.html#ref-object-ownership"><em>Ownership of Objects</em></a>).</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>obj</em> &#8211; the wrapped instance.</td>
+</tr>
+</tbody>
+</table>
+<p>In addition, any association of the instance with regard to the cyclic
+garbage collector with another instance is removed.</p>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipTransferBreak">
+void <tt class="descname">sipTransferBreak</tt><big>(</big>PyObject<em> *obj</em><big>)</big><a class="headerlink" href="#sipTransferBreak" title="Permalink to this definition">¶</a></dt>
+<dd><p>Any association of a Python wrapped instance with regard to the cyclic
+garbage collector with another instance is removed. Ownership of the
+instance should be with C++.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>obj</em> &#8211; the wrapped instance.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipTransferTo">
+void <tt class="descname">sipTransferTo</tt><big>(</big>PyObject<em> *obj</em>, PyObject<em> *owner</em><big>)</big><a class="headerlink" href="#sipTransferTo" title="Permalink to this definition">¶</a></dt>
+<dd><p>This transfers ownership of a Python wrapped instance to C++ (see
+<a class="reference external" href="using.html#ref-object-ownership"><em>Ownership of Objects</em></a>).</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><em>obj</em> &#8211; the wrapped instance.</li>
+<li><em>owner</em> &#8211; an optional wrapped instance that <em>obj</em> becomes associated with with
+regard to the cyclic garbage collector. If <em>owner</em> is <tt class="docutils literal"><span class="pre">NULL</span></tt> then no
+such association is made. If <em>owner</em> is the same value as <em>obj</em> then
+any reference cycles involving <em>obj</em> can never be detected or broken by
+the cyclic garbage collector. Responsibility for calling the C++
+instance&#8217;s destructor is always transfered to C++.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipTypeAsPyTypeObject">
+PyTypeObject *<tt class="descname">sipTypeAsPyTypeObject</tt><big>(</big>sipTypeDef<em> *td</em><big>)</big><a class="headerlink" href="#sipTypeAsPyTypeObject" title="Permalink to this definition">¶</a></dt>
+<dd><p>This returns a pointer to the Python type object that SIP creates for a
+<a class="reference internal" href="#ref-type-structures"><em>generated type structure</em></a>.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>td</em> &#8211; the type structure.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the Python type object. If the type structure refers to a mapped type
+then <tt class="docutils literal"><span class="pre">NULL</span></tt> will be returned.</td>
+</tr>
+</tbody>
+</table>
+<p>If the type structure refers to a C structure or C++ class then the
+Python type object may be safely cast to a <a title="sipWrapperType" class="reference internal" href="#sipWrapperType"><tt class="xref docutils literal"><span class="pre">sipWrapperType</span></tt></a>.</p>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipTypeFromPyTypeObject">
+const sipTypeDef *<tt class="descname">sipTypeFromPyTypeObject</tt><big>(</big>PyTypeObject<em> *py_type</em><big>)</big><a class="headerlink" href="#sipTypeFromPyTypeObject" title="Permalink to this definition">¶</a></dt>
+<dd><p>This returns the <a class="reference internal" href="#ref-type-structures"><em>generated type structure</em></a> for
+a Python type object.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>py_type</em> &#8211; the Python type object.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the type structure or <tt class="docutils literal"><span class="pre">NULL</span></tt> if the Python type object doesn&#8217;t
+correspond to a type structure.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipTypeIsClass">
+int <tt class="descname">sipTypeIsClass</tt><big>(</big>sipTypeDef<em> *td</em><big>)</big><a class="headerlink" href="#sipTypeIsClass" title="Permalink to this definition">¶</a></dt>
+<dd><p>This checks if a <a class="reference internal" href="#ref-type-structures"><em>generated type structure</em></a>
+refers to a C structure or C++ class.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>td</em> &#8211; the type structure.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">a non-zero value if the type structure refers to a structure or class.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipTypeIsEnum">
+int <tt class="descname">sipTypeIsEnum</tt><big>(</big>sipTypeDef<em> *td</em><big>)</big><a class="headerlink" href="#sipTypeIsEnum" title="Permalink to this definition">¶</a></dt>
+<dd><p>This checks if a <a class="reference internal" href="#ref-type-structures"><em>generated type structure</em></a>
+refers to a named enum.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>td</em> &#8211; the type structure.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">a non-zero value if the type structure refers to an enum.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipTypeIsMapped">
+int <tt class="descname">sipTypeIsMapped</tt><big>(</big>sipTypeDef<em> *td</em><big>)</big><a class="headerlink" href="#sipTypeIsMapped" title="Permalink to this definition">¶</a></dt>
+<dd><p>This checks if a <a class="reference internal" href="#ref-type-structures"><em>generated type structure</em></a>
+refers to a mapped type.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>td</em> &#8211; the type structure.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">a non-zero value if the type structure refers to a mapped type.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipTypeIsNamespace">
+int <tt class="descname">sipTypeIsNamespace</tt><big>(</big>sipTypeDef<em> *td</em><big>)</big><a class="headerlink" href="#sipTypeIsNamespace" title="Permalink to this definition">¶</a></dt>
+<dd><p>This checks if a <a class="reference internal" href="#ref-type-structures"><em>generated type structure</em></a>
+refers to a C++ namespace.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>td</em> &#8211; the type structure.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">a non-zero value if the type structure refers to a namespace.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipTypeName">
+const char *<tt class="descname">sipTypeName</tt><big>(</big>const sipTypeDef<em> *td</em><big>)</big><a class="headerlink" href="#sipTypeName" title="Permalink to this definition">¶</a></dt>
+<dd><p>This returns the C/C++ name of a wrapped type.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>td</em> &#8211; the type&#8217;s <a class="reference internal" href="#ref-type-structures"><em>generated type structure</em></a>.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the name of the C/C++ type.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipTypeScope">
+const sipTypeDef *<tt class="descname">sipTypeScope</tt><big>(</big>const sipTypeDef<em> *td</em><big>)</big><a class="headerlink" href="#sipTypeScope" title="Permalink to this definition">¶</a></dt>
+<dd><p>This returns the <a class="reference internal" href="#ref-type-structures"><em>generated type structure</em></a> of
+the enclosing scope of another generated type structure.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>td</em> &#8211; the type structure.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the type structure of the scope or <tt class="docutils literal"><span class="pre">NULL</span></tt> if the type has no scope.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="cvar">
+<dt id="sipVoidPtr_Type">
+PyTypeObject *<tt class="descname">sipVoidPtr_Type</tt><a class="headerlink" href="#sipVoidPtr_Type" title="Permalink to this definition">¶</a></dt>
+<dd>This is the type of a <tt class="docutils literal"><span class="pre">PyObject</span></tt> structure that is used to wrap a
+<tt class="docutils literal"><span class="pre">void</span> <span class="pre">*</span></tt>.</dd></dl>
+
+<dl class="ctype">
+<dt id="sipWrapper">
+<tt class="descname">sipWrapper</tt><a class="headerlink" href="#sipWrapper" title="Permalink to this definition">¶</a></dt>
+<dd>This is a C structure that represents a Python wrapped instance whose type
+is <a title="sip.wrapper" class="reference external" href="python_api.html#sip.wrapper"><tt class="xref docutils literal"><span class="pre">sip.wrapper</span></tt></a>. It is an extension of the
+<a title="sipSimpleWrapper" class="reference internal" href="#sipSimpleWrapper"><tt class="xref docutils literal"><span class="pre">sipSimpleWrapper</span></tt></a> and <tt class="docutils literal"><span class="pre">PyObject</span></tt> structures and so may be safely
+cast to both.</dd></dl>
+
+<dl class="cfunction">
+<dt id="sipWrapper_Check">
+int <tt class="descname">sipWrapper_Check</tt><big>(</big>PyObject<em> *obj</em><big>)</big><a class="headerlink" href="#sipWrapper_Check" title="Permalink to this definition">¶</a></dt>
+<dd><p>This checks if a Python object is a wrapped instance.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>obj</em> &#8211; the Python object.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">a non-zero value if the Python object is a wrapped instance.</td>
+</tr>
+</tbody>
+</table>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p>This is deprecated from SIP v4.8. Instead you should use the
+following:</p>
+<div class="last highlight-python"><div class="highlight"><pre><span class="n">PyObject_TypeCheck</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">sipWrapper_Type</span><span class="p">)</span>
+</pre></div>
+</div>
+</div>
+</dd></dl>
+
+<dl class="cvar">
+<dt id="sipWrapper_Type">
+PyTypeObject *<tt class="descname">sipWrapper_Type</tt><a class="headerlink" href="#sipWrapper_Type" title="Permalink to this definition">¶</a></dt>
+<dd>This is the type of a <a title="sipWrapper" class="reference internal" href="#sipWrapper"><tt class="xref docutils literal"><span class="pre">sipWrapper</span></tt></a> structure and is the C
+implementation of <a title="sip.wrapper" class="reference external" href="python_api.html#sip.wrapper"><tt class="xref docutils literal"><span class="pre">sip.wrapper</span></tt></a>. It may be safely cast to
+<a title="sipWrapperType" class="reference internal" href="#sipWrapperType"><tt class="xref docutils literal"><span class="pre">sipWrapperType</span></tt></a>.</dd></dl>
+
+<dl class="ctype">
+<dt id="sipWrapperType">
+<tt class="descname">sipWrapperType</tt><a class="headerlink" href="#sipWrapperType" title="Permalink to this definition">¶</a></dt>
+<dd>This is a C structure that represents a SIP generated type object. It is
+an extension of the <tt class="docutils literal"><span class="pre">PyTypeObject</span></tt> structure (which is itself an
+extension of the <tt class="docutils literal"><span class="pre">PyObject</span></tt> structure) and so may be safely cast to
+<tt class="docutils literal"><span class="pre">PyTypeObject</span></tt> (and <tt class="docutils literal"><span class="pre">PyObject</span></tt>).</dd></dl>
+
+<dl class="cvar">
+<dt id="sipWrapperType_Type">
+PyTypeObject *<tt class="descname">sipWrapperType_Type</tt><a class="headerlink" href="#sipWrapperType_Type" title="Permalink to this definition">¶</a></dt>
+<dd>This is the type of a <a title="sipWrapperType" class="reference internal" href="#sipWrapperType"><tt class="xref docutils literal"><span class="pre">sipWrapperType</span></tt></a> structure and is the C
+implementation of <a title="sip.wrappertype" class="reference external" href="python_api.html#sip.wrappertype"><tt class="xref docutils literal"><span class="pre">sip.wrappertype</span></tt></a>.</dd></dl>
+
+<div class="section" id="generated-type-structures">
+<span id="ref-type-structures"></span><h2>Generated Type Structures<a class="headerlink" href="#generated-type-structures" title="Permalink to this headline">¶</a></h2>
+<p>SIP generates an opaque type structure for each C structure, C++ class, C++
+namespace, named enum or mapped type being wrapped. These are
+<tt class="xref docutils literal"><span class="pre">sipTypeDef</span></tt> structures and are used extensively by the SIP API.</p>
+<p>The names of these structure are prefixed by <tt class="docutils literal"><span class="pre">sipType_</span></tt>.</p>
+<p>For those structures that correspond to C structures, C++ classes, C++
+namespaces or named enums the remaining part of the name is the fully
+qualified name of the structure, class, namespace or enum name. Any <tt class="docutils literal"><span class="pre">::</span></tt>
+scope separators are replaced by an underscore. For example, the type object
+for class <tt class="docutils literal"><span class="pre">Klass</span></tt> is <tt class="docutils literal"><span class="pre">sipType_Klass</span></tt>.</p>
+<p>For those structure that correspond to mapped types the remaining part of the
+name is generated by SIP. The only way for handwritten code to obtain a
+pointer to a structure for a mapped type is to use <a title="sipFindType" class="reference internal" href="#sipFindType"><tt class="xref docutils literal"><span class="pre">sipFindType()</span></tt></a>.</p>
+<p>The type structures of all imported types are available to handwritten code.</p>
+</div>
+<div class="section" id="generated-type-objects">
+<span id="ref-type-objects"></span><h2>Generated Type Objects<a class="headerlink" href="#generated-type-objects" title="Permalink to this headline">¶</a></h2>
+<p>SIP generates a <a title="sipWrapperType" class="reference internal" href="#sipWrapperType"><tt class="xref docutils literal"><span class="pre">sipWrapperType</span></tt></a> type object for each C structure or
+C++ class being wrapped.</p>
+<p>These objects are named with the structure or class name prefixed by
+<tt class="docutils literal"><span class="pre">sipClass_</span></tt>. For example, the type object for class <tt class="docutils literal"><span class="pre">Klass</span></tt> is
+<tt class="docutils literal"><span class="pre">sipClass_Klass</span></tt>.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Using these names is deprecated from SIP v4.8. Instead use the
+corresponding generated type structure (see <a class="reference internal" href="#ref-type-structures"><em>Generated Type Structures</em></a>) and
+<a title="sipTypeAsPyTypeObject" class="reference internal" href="#sipTypeAsPyTypeObject"><tt class="xref docutils literal"><span class="pre">sipTypeAsPyTypeObject()</span></tt></a>.</p>
+</div>
+</div>
+<div class="section" id="generated-named-enum-type-objects">
+<span id="ref-enum-type-objects"></span><h2>Generated Named Enum Type Objects<a class="headerlink" href="#generated-named-enum-type-objects" title="Permalink to this headline">¶</a></h2>
+<p>SIP generates a type object for each named enum being wrapped. These are
+PyTypeObject structures. (Anonymous enums are wrapped as Python integers.)</p>
+<p>These objects are named with the fully qualified enum name (i.e. including any
+enclosing scope) prefixed by <tt class="docutils literal"><span class="pre">sipEnum_</span></tt>. For example, the type object for
+enum <tt class="docutils literal"><span class="pre">Enum</span></tt> defined in class <tt class="docutils literal"><span class="pre">Klass</span></tt> is <tt class="docutils literal"><span class="pre">sipEnum_Klass_Enum</span></tt>.</p>
+<div class="admonition note">
+<p class="first admonition-title">Note</p>
+<p class="last">Using these names is deprecated from SIP v4.8. Instead use the
+corresponding generated type structure (see <a class="reference internal" href="#ref-type-structures"><em>Generated Type Structures</em></a>) and
+<a title="sipTypeAsPyTypeObject" class="reference internal" href="#sipTypeAsPyTypeObject"><tt class="xref docutils literal"><span class="pre">sipTypeAsPyTypeObject()</span></tt></a>.</p>
+</div>
+</div>
+<div class="section" id="generated-derived-classes">
+<span id="ref-derived-classes"></span><h2>Generated Derived Classes<a class="headerlink" href="#generated-derived-classes" title="Permalink to this headline">¶</a></h2>
+<p>For most C++ classes being wrapped SIP generates a derived class with the same
+name prefixed by <tt class="docutils literal"><span class="pre">sip</span></tt>. For example, the derived class for class <tt class="docutils literal"><span class="pre">Klass</span></tt>
+is <tt class="docutils literal"><span class="pre">sipKlass</span></tt>.</p>
+<p>If a C++ class doesn&#8217;t have any virtual or protected methods in it or any of
+it&#8217;s super-class hierarchy, or does not emit any Qt signals, then a derived
+class is not generated.</p>
+<p>Most of the time handwritten code should ignore the derived classes. The only
+exception is that handwritten constructor code specified using the
+<a class="reference external" href="directives.html#directive-%MethodCode"><tt class="xref docutils literal"><span class="pre">%MethodCode</span></tt></a> directive should call the derived class&#8217;s constructor
+(which has the same C++ signature) rather then the wrapped class&#8217;s constructor.</p>
+</div>
+<div class="section" id="generated-exception-objects">
+<span id="ref-exception-objects"></span><h2>Generated Exception Objects<a class="headerlink" href="#generated-exception-objects" title="Permalink to this headline">¶</a></h2>
+<p>SIP generates a Python object for each exception defined with the
+<a class="reference external" href="directives.html#directive-%Exception"><tt class="xref docutils literal"><span class="pre">%Exception</span></tt></a> directive.</p>
+<p>These objects are named with the fully qualified exception name (i.e. including
+any enclosing scope) prefixed by <tt class="docutils literal"><span class="pre">sipException_</span></tt>. For example, the type
+object for enum <tt class="docutils literal"><span class="pre">Except</span></tt> defined in class <tt class="docutils literal"><span class="pre">Klass</span></tt> is
+<tt class="docutils literal"><span class="pre">sipException_Klass_Except</span></tt>.</p>
+<p>The objects of all imported exceptions are available to handwritten code.</p>
+</div>
+</div>
+
+
+ </div>
+ </div>
+ </div>
+ <div class="sphinxsidebar">
+ <div class="sphinxsidebarwrapper">
+ <h3><a href="index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference external" href="#">C API for Handwritten Code</a><ul>
+<li><a class="reference external" href="#generated-type-structures">Generated Type Structures</a></li>
+<li><a class="reference external" href="#generated-type-objects">Generated Type Objects</a></li>
+<li><a class="reference external" href="#generated-named-enum-type-objects">Generated Named Enum Type Objects</a></li>
+<li><a class="reference external" href="#generated-derived-classes">Generated Derived Classes</a></li>
+<li><a class="reference external" href="#generated-exception-objects">Generated Exception Objects</a></li>
+</ul>
+</li>
+</ul>
+
+ <h4>Previous topic</h4>
+ <p class="topless"><a href="annotations.html"
+ title="previous chapter">Annotations</a></p>
+ <h4>Next topic</h4>
+ <p class="topless"><a href="embedding.html"
+ title="next chapter">Using the C API when Embedding</a></p>
+ <div id="searchbox" style="display: none">
+ <h3>Quick search</h3>
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" size="18" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ <p class="searchtip" style="font-size: 90%">
+ Enter search terms or a module, class or function name.
+ </p>
+ </div>
+ <script type="text/javascript">$('#searchbox').show(0);</script>
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ >modules</a> |</li>
+ <li class="right" >
+ <a href="embedding.html" title="Using the C API when Embedding"
+ >next</a> |</li>
+ <li class="right" >
+ <a href="annotations.html" title="Annotations"
+ >previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+ <div class="footer">
+ &copy; Copyright 2010 Riverbank Computing Limited.
+ Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.4.
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/command_line.html b/doc/html/command_line.html
new file mode 100644
index 0000000..f20045a
--- /dev/null
+++ b/doc/html/command_line.html
@@ -0,0 +1,259 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>The SIP Command Line &mdash; SIP 4.10.5 Reference Guide</title>
+ <link rel="stylesheet" href="_static/default.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '#',
+ VERSION: '4.10.5',
+ COLLAPSE_MODINDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="top" title="SIP 4.10.5 Reference Guide" href="index.html" />
+ <link rel="next" title="SIP Specification Files" href="specification_files.html" />
+ <link rel="prev" title="Using SIP" href="using.html" />
+ </head>
+ <body>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ accesskey="M">modules</a> |</li>
+ <li class="right" >
+ <a href="specification_files.html" title="SIP Specification Files"
+ accesskey="N">next</a> |</li>
+ <li class="right" >
+ <a href="using.html" title="Using SIP"
+ accesskey="P">previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+ <div class="body">
+
+ <div class="section" id="the-sip-command-line">
+<span id="ref-command-line"></span><h1>The SIP Command Line<a class="headerlink" href="#the-sip-command-line" title="Permalink to this headline">¶</a></h1>
+<p>The syntax of the SIP command line is:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">sip</span> <span class="p">[</span><span class="n">options</span><span class="p">]</span> <span class="p">[</span><span class="n">specification</span><span class="p">]</span>
+</pre></div>
+</div>
+<p><tt class="docutils literal"><span class="pre">specification</span></tt> is the name of the specification file for the module. If it
+is omitted then <tt class="docutils literal"><span class="pre">stdin</span></tt> is used.</p>
+<p>The full set of command line options is:</p>
+<dl class="cmdoption">
+<dt id="cmdoption-sip-h">
+<tt class="descname">-h</tt><tt class="descclassname"></tt><a class="headerlink" href="#cmdoption-sip-h" title="Permalink to this definition">¶</a></dt>
+<dd>Display a help message.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-sip-V">
+<tt class="descname">-V</tt><tt class="descclassname"></tt><a class="headerlink" href="#cmdoption-sip-V" title="Permalink to this definition">¶</a></dt>
+<dd>Display the SIP version number.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-sip-a">
+<tt class="descname">-a</tt><tt class="descclassname"> &lt;FILE&gt;</tt><a class="headerlink" href="#cmdoption-sip-a" title="Permalink to this definition">¶</a></dt>
+<dd>The name of the QScintilla API file to generate. This file contains a
+description of the module API in a form that the QScintilla editor
+component can use for auto-completion and call tips. (The file may also be
+used by the SciTE editor but must be sorted first.) By default the file is
+not generated.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-sip-b">
+<tt class="descname">-b</tt><tt class="descclassname"> &lt;FILE&gt;</tt><a class="headerlink" href="#cmdoption-sip-b" title="Permalink to this definition">¶</a></dt>
+<dd>The name of the build file to generate. This file contains the information
+about the module needed by the <a class="reference external" href="build_system.html#ref-build-system"><em>SIP build system</em></a>
+to generate a platform and compiler specific Makefile for the module. By
+default the file is not generated.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-sip-c">
+<tt class="descname">-c</tt><tt class="descclassname"> &lt;DIR&gt;</tt><a class="headerlink" href="#cmdoption-sip-c" title="Permalink to this definition">¶</a></dt>
+<dd>The name of the directory (which must exist) into which all of the
+generated C or C++ code is placed. By default no code is generated.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-sip-d">
+<tt class="descname">-d</tt><tt class="descclassname"> &lt;FILE&gt;</tt><a class="headerlink" href="#cmdoption-sip-d" title="Permalink to this definition">¶</a></dt>
+<dd>The name of the documentation file to generate. Documentation is included
+in specification files using the <a class="reference external" href="directives.html#directive-%Doc"><tt class="xref docutils literal"><span class="pre">%Doc</span></tt></a> and
+<a class="reference external" href="directives.html#directive-%ExportedDoc"><tt class="xref docutils literal"><span class="pre">%ExportedDoc</span></tt></a> directives. By default the file is not
+generated.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-sip-e">
+<tt class="descname">-e</tt><tt class="descclassname"></tt><a class="headerlink" href="#cmdoption-sip-e" title="Permalink to this definition">¶</a></dt>
+<dd>Support for C++ exceptions is enabled. This causes all calls to C++ code
+to be enclosed in <tt class="docutils literal"><span class="pre">try</span></tt>/<tt class="docutils literal"><span class="pre">catch</span></tt> blocks and C++ exceptions to be
+converted to Python exceptions. By default exception support is disabled.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-sip-g">
+<tt class="descname">-g</tt><tt class="descclassname"></tt><a class="headerlink" href="#cmdoption-sip-g" title="Permalink to this definition">¶</a></dt>
+<dd>The Python GIL is released before making any calls to the C/C++ library
+being wrapped and reacquired afterwards. See <a class="reference external" href="using.html#ref-gil"><em>The Python Global Interpreter Lock</em></a> and the
+<a class="reference external" href="annotations.html#fanno-ReleaseGIL"><tt class="xref docutils literal"><span class="pre">ReleaseGIL</span></tt></a> and <a class="reference external" href="annotations.html#fanno-HoldGIL"><tt class="xref docutils literal"><span class="pre">HoldGIL</span></tt></a> annotations.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-sip-I">
+<tt class="descname">-I</tt><tt class="descclassname"> &lt;DIR&gt;</tt><a class="headerlink" href="#cmdoption-sip-I" title="Permalink to this definition">¶</a></dt>
+<dd>The directory is added to the list of directories searched when looking for
+a specification file given in an <a class="reference external" href="directives.html#directive-%Include"><tt class="xref docutils literal"><span class="pre">%Include</span></tt></a> or
+<a class="reference external" href="directives.html#directive-%Import"><tt class="xref docutils literal"><span class="pre">%Import</span></tt></a> directive. This option may be given any number of
+times.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-sip-j">
+<tt class="descname">-j</tt><tt class="descclassname"> &lt;NUMBER&gt;</tt><a class="headerlink" href="#cmdoption-sip-j" title="Permalink to this definition">¶</a></dt>
+<dd>The generated code is split into the given number of files. This makes it
+easier to use the parallel build facility of most modern implementations of
+<tt class="docutils literal"><span class="pre">make</span></tt>. By default 1 file is generated for each C structure or C++
+class.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-sip-k">
+<tt class="descname">-k</tt><tt class="descclassname"></tt><a class="headerlink" href="#cmdoption-sip-k" title="Permalink to this definition">¶</a></dt>
+<dd><p>
+<span class="versionmodified">New in version 4.10.</span></p>
+<p>All functions and methods will, by default, support passing parameters
+using the Python keyword argument syntax.</p>
+</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-sip-o">
+<tt class="descname">-o</tt><tt class="descclassname"></tt><a class="headerlink" href="#cmdoption-sip-o" title="Permalink to this definition">¶</a></dt>
+<dd><p>
+<span class="versionmodified">New in version 4.10.</span></p>
+<p>Docstrings will be automatically generated that describe the signature of
+all functions, methods and constructors.</p>
+</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-sip-p">
+<tt class="descname">-p</tt><tt class="descclassname"> &lt;MODULE&gt;</tt><a class="headerlink" href="#cmdoption-sip-p" title="Permalink to this definition">¶</a></dt>
+<dd>The name of the <a class="reference external" href="directives.html#directive-%ConsolidatedModule"><tt class="xref docutils literal"><span class="pre">%ConsolidatedModule</span></tt></a> which will contain the
+wrapper code for this component module.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-sip-P">
+<tt class="descname">-P</tt><tt class="descclassname"></tt><a class="headerlink" href="#cmdoption-sip-P" title="Permalink to this definition">¶</a></dt>
+<dd><p>
+<span class="versionmodified">New in version 4.10.</span></p>
+<p>By default SIP generates code to provide access to protected C++ functions
+from Python. On some platforms (notably Linux, but not Windows) this code
+can be avoided if the <tt class="docutils literal"><span class="pre">protected</span></tt> keyword is redefined as <tt class="docutils literal"><span class="pre">public</span></tt>
+during compilation. This can result in a significant reduction in the size
+of a generated Python module. This option disables the generation of the
+extra code.</p>
+</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-sip-r">
+<tt class="descname">-r</tt><tt class="descclassname"></tt><a class="headerlink" href="#cmdoption-sip-r" title="Permalink to this definition">¶</a></dt>
+<dd>Debugging statements that trace the execution of the bindings are
+automatically generated. By default the statements are not generated.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-sip-s">
+<tt class="descname">-s</tt><tt class="descclassname"> &lt;SUFFIX&gt;</tt><a class="headerlink" href="#cmdoption-sip-s" title="Permalink to this definition">¶</a></dt>
+<dd>The suffix to use for generated C or C++ source files. By default <tt class="docutils literal"><span class="pre">.c</span></tt>
+is used for C and <tt class="docutils literal"><span class="pre">.cpp</span></tt> for C++.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-sip-t">
+<tt class="descname">-t</tt><tt class="descclassname"> &lt;TAG&gt;</tt><a class="headerlink" href="#cmdoption-sip-t" title="Permalink to this definition">¶</a></dt>
+<dd>The SIP version tag (declared using a <a class="reference external" href="directives.html#directive-%Timeline"><tt class="xref docutils literal"><span class="pre">%Timeline</span></tt></a> directive) or
+the SIP platform tag (declared using the <a class="reference external" href="directives.html#directive-%Platforms"><tt class="xref docutils literal"><span class="pre">%Platforms</span></tt></a> directive)
+to generate code for. This option may be given any number of times so long
+as the tags do not conflict.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-sip-w">
+<tt class="descname">-w</tt><tt class="descclassname"></tt><a class="headerlink" href="#cmdoption-sip-w" title="Permalink to this definition">¶</a></dt>
+<dd>The display of warning messages is enabled. By default warning messages
+are disabled.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-sip-x">
+<tt class="descname">-x</tt><tt class="descclassname"> &lt;FEATURE&gt;</tt><a class="headerlink" href="#cmdoption-sip-x" title="Permalink to this definition">¶</a></dt>
+<dd>The feature (declared using the <a class="reference external" href="directives.html#directive-%Feature"><tt class="xref docutils literal"><span class="pre">%Feature</span></tt></a> directive) is
+disabled.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-sip-z">
+<tt class="descname">-z</tt><tt class="descclassname"> &lt;FILE&gt;</tt><a class="headerlink" href="#cmdoption-sip-z" title="Permalink to this definition">¶</a></dt>
+<dd>The name of a file containing more command line options.</dd></dl>
+
+</div>
+
+
+ </div>
+ </div>
+ </div>
+ <div class="sphinxsidebar">
+ <div class="sphinxsidebarwrapper">
+ <h4>Previous topic</h4>
+ <p class="topless"><a href="using.html"
+ title="previous chapter">Using SIP</a></p>
+ <h4>Next topic</h4>
+ <p class="topless"><a href="specification_files.html"
+ title="next chapter">SIP Specification Files</a></p>
+ <div id="searchbox" style="display: none">
+ <h3>Quick search</h3>
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" size="18" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ <p class="searchtip" style="font-size: 90%">
+ Enter search terms or a module, class or function name.
+ </p>
+ </div>
+ <script type="text/javascript">$('#searchbox').show(0);</script>
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ >modules</a> |</li>
+ <li class="right" >
+ <a href="specification_files.html" title="SIP Specification Files"
+ >next</a> |</li>
+ <li class="right" >
+ <a href="using.html" title="Using SIP"
+ >previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+ <div class="footer">
+ &copy; Copyright 2010 Riverbank Computing Limited.
+ Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.4.
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/directives.html b/doc/html/directives.html
new file mode 100644
index 0000000..eab1185
--- /dev/null
+++ b/doc/html/directives.html
@@ -0,0 +1,2045 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>Directives &mdash; SIP 4.10.5 Reference Guide</title>
+ <link rel="stylesheet" href="_static/default.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '#',
+ VERSION: '4.10.5',
+ COLLAPSE_MODINDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="top" title="SIP 4.10.5 Reference Guide" href="index.html" />
+ <link rel="next" title="Annotations" href="annotations.html" />
+ <link rel="prev" title="SIP Specification Files" href="specification_files.html" />
+ </head>
+ <body>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ accesskey="M">modules</a> |</li>
+ <li class="right" >
+ <a href="annotations.html" title="Annotations"
+ accesskey="N">next</a> |</li>
+ <li class="right" >
+ <a href="specification_files.html" title="SIP Specification Files"
+ accesskey="P">previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+ <div class="body">
+
+ <div class="section" id="directives">
+<h1>Directives<a class="headerlink" href="#directives" title="Permalink to this headline">¶</a></h1>
+<p>In this section we describe each of the directives that can be used in
+specification files. All directives begin with <tt class="docutils literal"><span class="pre">%</span></tt> as the first
+non-whitespace character in a line.</p>
+<p>Some directives have arguments or contain blocks of code or documentation. In
+the following descriptions these are shown in <em>italics</em>. Optional arguments
+are enclosed in [<em>brackets</em>].</p>
+<p>Some directives are used to specify handwritten code. Handwritten code must
+not define names that start with the prefix <tt class="docutils literal"><span class="pre">sip</span></tt>.</p>
+<dl class="directive">
+<dt id="directive-%AccessCode">
+<tt class="descname">%AccessCode</tt><a class="headerlink" href="#directive-%AccessCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%AccessCode
+ <em>code</em>
+%End
+</pre>
+<p>This directive is used immediately after the declaration of an instance of a
+wrapped class or structure, or a pointer to such an instance. You use it to
+provide handwritten code that overrides the default behaviour.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>class Klass;
+
+Klass *klassInstance;
+%AccessCode
+ // In this contrived example the C++ library we are wrapping defines
+ // klassInstance as Klass ** (which SIP doesn't support) so we
+ // explicitly dereference it.
+ if (klassInstance &amp;&amp; *klassInstance)
+ return *klassInstance;
+
+ // This will get converted to None.
+ return 0;
+%End</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%API">
+<tt class="descname">%API</tt><a class="headerlink" href="#directive-%API" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<p>
+<span class="versionmodified">New in version 4.9.</span></p>
+<pre class="literal-block">
+%API <em>name</em> <em>version</em>
+</pre>
+<p>This directive is used to define an API and set its default version number. A
+version number must be greater than or equal to 1.</p>
+<p>See <a class="reference external" href="using.html#ref-incompat-apis"><em>Managing Incompatible APIs</em></a> for more detail.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>%API PyQt4 1</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%BIGetBufferCode">
+<tt class="descname">%BIGetBufferCode</tt><a class="headerlink" href="#directive-%BIGetBufferCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%BIGetBufferCode
+ <em>code</em>
+%End
+</pre>
+<p>This directive (along with <a class="reference internal" href="#directive-%BIReleaseBufferCode"><tt class="xref docutils literal"><span class="pre">%BIReleaseBufferCode</span></tt></a>) is used to
+specify code that implements the buffer interface of Python v3. If Python v2
+is being used then this is ignored.</p>
+<p>The following variables are made available to the handwritten code:</p>
+<dl class="docutils">
+<dt>Py_buffer *sipBuffer</dt>
+<dd>This is a pointer to the Python buffer structure that the handwritten code
+must populate.</dd>
+<dt><em>type</em> *sipCpp</dt>
+<dd>This is a pointer to the structure or class instance. Its <em>type</em> is a
+pointer to the structure or class.</dd>
+<dt>int sipFlags</dt>
+<dd>These are the flags that specify what elements of the <tt class="docutils literal"><span class="pre">sipBuffer</span></tt>
+structure must be populated.</dd>
+<dt>int sipRes</dt>
+<dd>The handwritten code should set this to 0 if there was no error or -1 if
+there was an error.</dd>
+<dt>PyObject *sipSelf</dt>
+<dd>This is the Python object that wraps the structure or class instance, i.e.
+<tt class="docutils literal"><span class="pre">self</span></tt>.</dd>
+</dl>
+<dl class="directive">
+<dt id="directive-%BIGetCharBufferCode">
+<tt class="descname">%BIGetCharBufferCode</tt><a class="headerlink" href="#directive-%BIGetCharBufferCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%BIGetCharBufferCode
+ <em>code</em>
+%End
+</pre>
+<p>This directive (along with <a class="reference internal" href="#directive-%BIGetReadBufferCode"><tt class="xref docutils literal"><span class="pre">%BIGetReadBufferCode</span></tt></a>,
+<a class="reference internal" href="#directive-%BIGetSegCountCode"><tt class="xref docutils literal"><span class="pre">%BIGetSegCountCode</span></tt></a> and <a class="reference internal" href="#directive-%BIGetWriteBufferCode"><tt class="xref docutils literal"><span class="pre">%BIGetWriteBufferCode</span></tt></a>) is used
+to specify code that implements the buffer interface of Python v2. If Python
+v3 is being used then this is ignored.</p>
+<p>The following variables are made available to the handwritten code:</p>
+<dl class="docutils">
+<dt><em>type</em> *sipCpp</dt>
+<dd>This is a pointer to the structure or class instance. Its <em>type</em> is a
+pointer to the structure or class.</dd>
+<dt>void **sipPtrPtr</dt>
+<dd>This is the pointer used to return the address of the character buffer.</dd>
+<dt><a title="SIP_SSIZE_T" class="reference external" href="c_api.html#SIP_SSIZE_T"><tt class="xref docutils literal"><span class="pre">SIP_SSIZE_T</span></tt></a> sipRes</dt>
+<dd>The handwritten code should set this to the length of the character buffer
+or -1 if there was an error.</dd>
+<dt><a title="SIP_SSIZE_T" class="reference external" href="c_api.html#SIP_SSIZE_T"><tt class="xref docutils literal"><span class="pre">SIP_SSIZE_T</span></tt></a> sipSegment</dt>
+<dd>This is the number of the segment of the character buffer.</dd>
+<dt>PyObject *sipSelf</dt>
+<dd>This is the Python object that wraps the structure or class instance, i.e.
+<tt class="docutils literal"><span class="pre">self</span></tt>.</dd>
+</dl>
+<dl class="directive">
+<dt id="directive-%BIGetReadBufferCode">
+<tt class="descname">%BIGetReadBufferCode</tt><a class="headerlink" href="#directive-%BIGetReadBufferCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%BIGetReadBufferCode
+ <em>code</em>
+%End
+</pre>
+<p>This directive (along with <a class="reference internal" href="#directive-%BIGetCharBufferCode"><tt class="xref docutils literal"><span class="pre">%BIGetCharBufferCode</span></tt></a>,
+<a class="reference internal" href="#directive-%BIGetSegCountCode"><tt class="xref docutils literal"><span class="pre">%BIGetSegCountCode</span></tt></a> and <a class="reference internal" href="#directive-%BIGetWriteBufferCode"><tt class="xref docutils literal"><span class="pre">%BIGetWriteBufferCode</span></tt></a>) is used
+to specify code that implements the buffer interface of Python v2. If
+Python v3 is being used then this is ignored.</p>
+<p>The following variables are made available to the handwritten code:</p>
+<dl class="docutils">
+<dt><em>type</em> *sipCpp</dt>
+<dd>This is a pointer to the structure or class instance. Its <em>type</em> is a
+pointer to the structure or class.</dd>
+<dt>void **sipPtrPtr</dt>
+<dd>This is the pointer used to return the address of the read buffer.</dd>
+<dt><a title="SIP_SSIZE_T" class="reference external" href="c_api.html#SIP_SSIZE_T"><tt class="xref docutils literal"><span class="pre">SIP_SSIZE_T</span></tt></a> sipRes</dt>
+<dd>The handwritten code should set this to the length of the read buffer or
+-1 if there was an error.</dd>
+<dt><a title="SIP_SSIZE_T" class="reference external" href="c_api.html#SIP_SSIZE_T"><tt class="xref docutils literal"><span class="pre">SIP_SSIZE_T</span></tt></a> sipSegment</dt>
+<dd>This is the number of the segment of the read buffer.</dd>
+<dt>PyObject *sipSelf</dt>
+<dd>This is the Python object that wraps the structure or class instance, i.e.
+<tt class="docutils literal"><span class="pre">self</span></tt>.</dd>
+</dl>
+<dl class="directive">
+<dt id="directive-%BIGetSegCountCode">
+<tt class="descname">%BIGetSegCountCode</tt><a class="headerlink" href="#directive-%BIGetSegCountCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%BIGetSegCountCode
+ <em>code</em>
+%End
+</pre>
+<p>This directive (along with <a class="reference internal" href="#directive-%BIGetCharBufferCode"><tt class="xref docutils literal"><span class="pre">%BIGetCharBufferCode</span></tt></a>,
+<a class="reference internal" href="#directive-%BIGetReadBufferCode"><tt class="xref docutils literal"><span class="pre">%BIGetReadBufferCode</span></tt></a> and <a class="reference internal" href="#directive-%BIGetWriteBufferCode"><tt class="xref docutils literal"><span class="pre">%BIGetWriteBufferCode</span></tt></a>) is
+used to specify code that implements the buffer interface of Python v2. If
+Python v3 is being used then this is ignored.</p>
+<p>The following variables are made available to the handwritten code:</p>
+<dl class="docutils">
+<dt><em>type</em> *sipCpp</dt>
+<dd>This is a pointer to the structure or class instance. Its <em>type</em> is a
+pointer to the structure or class.</dd>
+<dt><a title="SIP_SSIZE_T" class="reference external" href="c_api.html#SIP_SSIZE_T"><tt class="xref docutils literal"><span class="pre">SIP_SSIZE_T</span></tt></a> *sipLenPtr</dt>
+<dd>This is the pointer used to return the total length in bytes of all
+segments of the buffer.</dd>
+<dt><a title="SIP_SSIZE_T" class="reference external" href="c_api.html#SIP_SSIZE_T"><tt class="xref docutils literal"><span class="pre">SIP_SSIZE_T</span></tt></a> sipRes</dt>
+<dd>The handwritten code should set this to the number of segments that make
+up the buffer.</dd>
+<dt>PyObject *sipSelf</dt>
+<dd>This is the Python object that wraps the structure or class instance, i.e.
+<tt class="docutils literal"><span class="pre">self</span></tt>.</dd>
+</dl>
+<dl class="directive">
+<dt id="directive-%BIGetWriteBufferCode">
+<tt class="descname">%BIGetWriteBufferCode</tt><a class="headerlink" href="#directive-%BIGetWriteBufferCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%BIGetWriteBufferCode
+ <em>code</em>
+%End
+</pre>
+<p>This directive (along with <a class="reference internal" href="#directive-%BIGetCharBufferCode"><tt class="xref docutils literal"><span class="pre">%BIGetCharBufferCode</span></tt></a>,
+<a class="reference internal" href="#directive-%BIGetReadBufferCode"><tt class="xref docutils literal"><span class="pre">%BIGetReadBufferCode</span></tt></a> and <a class="reference internal" href="#directive-%BIGetSegCountCode"><tt class="xref docutils literal"><span class="pre">%BIGetSegCountCode</span></tt></a> is used
+to specify code that implements the buffer interface of Python v2. If Python
+v3 is being used then this is ignored.</p>
+<p>The following variables are made available to the handwritten code:</p>
+<dl class="docutils">
+<dt><em>type</em> *sipCpp</dt>
+<dd>This is a pointer to the structure or class instance. Its <em>type</em> is a
+pointer to the structure or class.</dd>
+<dt>void **sipPtrPtr</dt>
+<dd>This is the pointer used to return the address of the write buffer.</dd>
+<dt><a title="SIP_SSIZE_T" class="reference external" href="c_api.html#SIP_SSIZE_T"><tt class="xref docutils literal"><span class="pre">SIP_SSIZE_T</span></tt></a> sipRes</dt>
+<dd>The handwritten code should set this to the length of the write buffer or
+-1 if there was an error.</dd>
+<dt><a title="SIP_SSIZE_T" class="reference external" href="c_api.html#SIP_SSIZE_T"><tt class="xref docutils literal"><span class="pre">SIP_SSIZE_T</span></tt></a> sipSegment</dt>
+<dd>This is the number of the segment of the write buffer.</dd>
+<dt>PyObject *sipSelf</dt>
+<dd>This is the Python object that wraps the structure or class instance, i.e.
+<tt class="docutils literal"><span class="pre">self</span></tt>.</dd>
+</dl>
+<dl class="directive">
+<dt id="directive-%BIReleaseBufferCode">
+<tt class="descname">%BIReleaseBufferCode</tt><a class="headerlink" href="#directive-%BIReleaseBufferCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%BIReleaseBufferCode
+ <em>code</em>
+%End
+</pre>
+<p>This directive (along with <a class="reference internal" href="#directive-%BIGetBufferCode"><tt class="xref docutils literal"><span class="pre">%BIGetBufferCode</span></tt></a>) is used to specify
+code that implements the buffer interface of Python v3. If Python v2 is being
+used then this is ignored.</p>
+<p>The following variables are made available to the handwritten code:</p>
+<dl class="docutils">
+<dt>Py_buffer *sipBuffer</dt>
+<dd>This is a pointer to the Python buffer structure.</dd>
+<dt><em>type</em> *sipCpp</dt>
+<dd>This is a pointer to the structure or class instance. Its <em>type</em> is a
+pointer to the structure or class.</dd>
+<dt>PyObject *sipSelf</dt>
+<dd>This is the Python object that wraps the structure or class instance, i.e.
+<tt class="docutils literal"><span class="pre">self</span></tt>.</dd>
+</dl>
+<dl class="directive">
+<dt id="directive-%CModule">
+<tt class="descname">%CModule</tt><a class="headerlink" href="#directive-%CModule" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%CModule <em>name</em> [<em>version</em>]
+</pre>
+<p>This directive is used to identify that the library being wrapped is a C
+library and to define the name of the module and it&#8217;s optional version number.</p>
+<p>See the <a class="reference internal" href="#directive-%Module"><tt class="xref docutils literal"><span class="pre">%Module</span></tt></a> directive for an explanation of the version
+number.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>%CModule dbus 1</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%CompositeModule">
+<tt class="descname">%CompositeModule</tt><a class="headerlink" href="#directive-%CompositeModule" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%CompositeModule <em>name</em>
+</pre>
+<p>A composite module is one that merges a number of related SIP generated
+modules. For example, a module that merges the modules <tt class="docutils literal"><span class="pre">a_mod</span></tt>, <tt class="docutils literal"><span class="pre">b_mod</span></tt>
+and <tt class="docutils literal"><span class="pre">c_mod</span></tt> is equivalent to the following pure Python module:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">a_mod</span> <span class="kn">import</span> <span class="o">*</span>
+<span class="kn">from</span> <span class="nn">b_mod</span> <span class="kn">import</span> <span class="o">*</span>
+<span class="kn">from</span> <span class="nn">c_mod</span> <span class="kn">import</span> <span class="o">*</span>
+</pre></div>
+</div>
+<p>Clearly the individual modules should not define module-level objects with the
+same name.</p>
+<p>This directive is used to specify the name of a composite module. Any
+subsequent <a class="reference internal" href="#directive-%CModule"><tt class="xref docutils literal"><span class="pre">%CModule</span></tt></a> or <a class="reference internal" href="#directive-%Module"><tt class="xref docutils literal"><span class="pre">%Module</span></tt></a> directive is
+interpreted as defining a component module.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>%CompositeModule PyQt4.Qt
+%Include QtCore/QtCoremod.sip
+%Include QtGui/QtGuimod.sip</pre>
+</div>
+<p>The main purpose of a composite module is as a programmer convenience as they
+don&#8217;t have to remember which which individual module an object is defined in.</p>
+<dl class="directive">
+<dt id="directive-%ConsolidatedModule">
+<tt class="descname">%ConsolidatedModule</tt><a class="headerlink" href="#directive-%ConsolidatedModule" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%ConsolidatedModule <em>name</em>
+</pre>
+<p>A consolidated module is one that consolidates the wrapper code of a number of
+SIP generated modules (refered to as component modules in this context).</p>
+<p>This directive is used to specify the name of a consolidated module. Any
+subsequent <a class="reference internal" href="#directive-%CModule"><tt class="xref docutils literal"><span class="pre">%CModule</span></tt></a> or <a class="reference internal" href="#directive-%Module"><tt class="xref docutils literal"><span class="pre">%Module</span></tt></a> directive is
+interpreted as defining a component module.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>%ConsolidatedModule PyQt4._qt
+%Include QtCore/QtCoremod.sip
+%Include QtGui/QtGuimod.sip</pre>
+</div>
+<p>A consolidated module is not intended to be explicitly imported by an
+application. Instead it is imported by its component modules when they
+themselves are imported.</p>
+<p>Normally the wrapper code is contained in the component module and is linked
+against the corresponding C or C++ library. The advantage of a consolidated
+module is that it allows all of the wrapped C or C++ libraries to be linked
+against a single module. If the linking is done statically then deployment of
+generated modules can be greatly simplified.</p>
+<p>It follows that a component module can be built in one of two ways, as a
+normal standalone module, or as a component of a consolidated module. When
+building as a component the <tt class="docutils literal"><span class="pre">-p</span></tt> command line option should be used to
+specify the name of the consolidated module.</p>
+<dl class="directive">
+<dt id="directive-%ConvertFromTypeCode">
+<tt class="descname">%ConvertFromTypeCode</tt><a class="headerlink" href="#directive-%ConvertFromTypeCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%ConvertFromTypeCode
+ <em>code</em>
+%End
+</pre>
+<p>This directive is used as part of the <a class="reference internal" href="#directive-%MappedType"><tt class="xref docutils literal"><span class="pre">%MappedType</span></tt></a> directive to
+specify the handwritten code that converts an instance of a mapped type to a
+Python object.</p>
+<p>The following variables are made available to the handwritten code:</p>
+<dl class="docutils">
+<dt><em>type</em> *sipCpp</dt>
+<dd>This is a pointer to the instance of the mapped type to be converted. It
+will never be zero as the conversion from zero to <tt class="docutils literal"><span class="pre">Py_None</span></tt> is handled
+before the handwritten code is called.</dd>
+<dt>PyObject *sipTransferObj</dt>
+<dd>This specifies any desired ownership changes to the returned object. If it
+is <tt class="docutils literal"><span class="pre">NULL</span></tt> then the ownership should be left unchanged. If it is
+<tt class="docutils literal"><span class="pre">Py_None</span></tt> then ownership should be transferred to Python. Otherwise
+ownership should be transferred to C/C++ and the returned object associated
+with <em>sipTransferObj</em>. The code can choose to interpret these changes in
+any way. For example, if the code is converting a C++ container of wrapped
+classes to a Python list it is likely that the ownership changes should be
+made to each element of the list.</dd>
+</dl>
+<p>The handwritten code must explicitly return a <tt class="docutils literal"><span class="pre">PyObject</span> <span class="pre">*</span></tt>. If there was an
+error then a Python exception must be raised and <tt class="docutils literal"><span class="pre">NULL</span></tt> returned.</p>
+<p>The following example converts a <tt class="docutils literal"><span class="pre">QList&lt;QWidget</span> <span class="pre">*&gt;</span></tt> instance to a Python
+list of <tt class="docutils literal"><span class="pre">QWidget</span></tt> instances:</p>
+<div class="highlight-python"><pre>%ConvertFromTypeCode
+ PyObject *l;
+
+ // Create the Python list of the correct length.
+ if ((l = PyList_New(sipCpp-&gt;size())) == NULL)
+ return NULL;
+
+ // Go through each element in the C++ instance and convert it to a
+ // wrapped QWidget.
+ for (int i = 0; i &lt; sipCpp-&gt;size(); ++i)
+ {
+ QWidget *w = sipCpp-&gt;at(i);
+ PyObject *wobj;
+
+ // Get the Python wrapper for the QWidget instance, creating a new
+ // one if necessary, and handle any ownership transfer.
+ if ((wobj = sipConvertFromType(w, sipType_QWidget, sipTransferObj)) == NULL)
+ {
+ // There was an error so garbage collect the Python list.
+ Py_DECREF(l);
+ return NULL;
+ }
+
+ // Add the wrapper to the list.
+ PyList_SET_ITEM(l, i, wobj);
+ }
+
+ // Return the Python list.
+ return l;
+%End</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%ConvertToSubClassCode">
+<tt class="descname">%ConvertToSubClassCode</tt><a class="headerlink" href="#directive-%ConvertToSubClassCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%ConvertToSubClassCode
+ <em>code</em>
+%End
+</pre>
+<p>When SIP needs to wrap a C++ class instance it first checks to make sure it
+hasn&#8217;t already done so. If it has then it just returns a new reference to the
+corresponding Python object. Otherwise it creates a new Python object of the
+appropriate type. In C++ a function may be defined to return an instance of a
+certain class, but can often return a sub-class instead.</p>
+<p>This directive is used to specify handwritten code that exploits any available
+real-time type information (RTTI) to see if there is a more specific Python
+type that can be used when wrapping the C++ instance. The RTTI may be
+provided by the compiler or by the C++ instance itself.</p>
+<p>The directive is included in the specification of one of the classes that the
+handwritten code handles the type conversion for. It doesn&#8217;t matter which
+one, but a sensible choice would be the one at the root of that class
+hierarchy in the module.</p>
+<p>Note that if a class hierarchy extends over a number of modules then this
+directive should be used in each of those modules to handle the part of the
+hierarchy defined in that module. SIP will ensure that the different pieces
+of code are called in the right order to determine the most specific Python
+type to use.</p>
+<p>The following variables are made available to the handwritten code:</p>
+<dl class="docutils">
+<dt><em>type</em> *sipCpp</dt>
+<dd>This is a pointer to the C++ class instance.</dd>
+<dt>void **sipCppRet</dt>
+<dd>When the sub-class is derived from more than one super-class then it is
+possible that the C++ address of the instance as the sub-class is
+different to that of the super-class. If so, then this must be set to the
+C++ address of the instance when cast (usually using <tt class="docutils literal"><span class="pre">static_cast</span></tt>)
+from the super-class to the sub-class.</dd>
+<dt>const sipTypeDef *sipType</dt>
+<dd>The handwritten code must set this to the SIP generated type structure
+that corresponds to the class instance. (The type structure for class
+<tt class="docutils literal"><span class="pre">Klass</span></tt> is <tt class="docutils literal"><span class="pre">sipType_Klass</span></tt>.) If the RTTI of the class instance isn&#8217;t
+recognised then <tt class="docutils literal"><span class="pre">sipType</span></tt> must be set to <tt class="docutils literal"><span class="pre">NULL</span></tt>. The code doesn&#8217;t
+have to recognise the exact class, only the most specific sub-class that
+it can.</dd>
+<dt>sipWrapperType *sipClass</dt>
+<dd><p class="first">The handwritten code must set this to the SIP generated Python type object
+that corresponds to the class instance. (The type object for class
+<tt class="docutils literal"><span class="pre">Klass</span></tt> is <tt class="docutils literal"><span class="pre">sipClass_Klass</span></tt>.) If the RTTI of the class instance isn&#8217;t
+recognised then <tt class="docutils literal"><span class="pre">sipClass</span></tt> must be set to <tt class="docutils literal"><span class="pre">NULL</span></tt>. The code doesn&#8217;t
+have to recognise the exact class, only the most specific sub-class that
+it can.</p>
+<p class="last">This is deprecated from SIP v4.8. Instead you should use <tt class="docutils literal"><span class="pre">sipType</span></tt>.</p>
+</dd>
+</dl>
+<p>The handwritten code must not explicitly return.</p>
+<p>The following example shows the sub-class conversion code for <tt class="docutils literal"><span class="pre">QEvent</span></tt> based
+class hierarchy in PyQt:</p>
+<div class="highlight-python"><pre>class QEvent
+{
+%ConvertToSubClassCode
+ // QEvent sub-classes provide a unique type ID.
+ switch (sipCpp-&gt;type())
+ {
+ case QEvent::Timer:
+ sipType = sipType_QTimerEvent;
+ break;
+
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ sipType = sipType_QKeyEvent;
+ break;
+
+ // Skip the remaining event types to keep the example short.
+
+ default:
+ // We don't recognise the type.
+ sipType = NULL;
+ }
+%End
+
+ // The rest of the class specification.
+
+};</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%ConvertToTypeCode">
+<tt class="descname">%ConvertToTypeCode</tt><a class="headerlink" href="#directive-%ConvertToTypeCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%ConvertToTypeCode
+ <em>code</em>
+%End
+</pre>
+<p>This directive is used to specify the handwritten code that converts a Python
+object to a mapped type instance and to handle any ownership transfers. It is
+used as part of the <a class="reference internal" href="#directive-%MappedType"><tt class="xref docutils literal"><span class="pre">%MappedType</span></tt></a> directive and as part of a class
+specification. The code is also called to determine if the Python object is of
+the correct type prior to conversion.</p>
+<p>When used as part of a class specification it can automatically convert
+additional types of Python object. For example, PyQt uses it in the
+specification of the <tt class="docutils literal"><span class="pre">QString</span></tt> class to allow Python string objects and
+unicode objects to be used wherever <tt class="docutils literal"><span class="pre">QString</span></tt> instances are expected.</p>
+<p>The following variables are made available to the handwritten code:</p>
+<dl class="docutils">
+<dt>int *sipIsErr</dt>
+<dd>If this is <tt class="docutils literal"><span class="pre">NULL</span></tt> then the code is being asked to check the type of the
+Python object. The check must not have any side effects. Otherwise the
+code is being asked to convert the Python object and a non-zero value
+should be returned through this pointer if an error occurred during the
+conversion.</dd>
+<dt>PyObject *sipPy</dt>
+<dd>This is the Python object to be converted.</dd>
+<dt><em>type</em> **sipCppPtr</dt>
+<dd>This is a pointer through which the address of the mapped type instance (or
+zero if appropriate) is returned. Its value is undefined if <tt class="docutils literal"><span class="pre">sipIsErr</span></tt>
+is <tt class="docutils literal"><span class="pre">NULL</span></tt>.</dd>
+<dt>PyObject *sipTransferObj</dt>
+<dd>This specifies any desired ownership changes to <em>sipPy</em>. If it is <tt class="docutils literal"><span class="pre">NULL</span></tt>
+then the ownership should be left unchanged. If it is <tt class="docutils literal"><span class="pre">Py_None</span></tt> then
+ownership should be transferred to Python. Otherwise ownership should be
+transferred to C/C++ and <em>sipPy</em> associated with <em>sipTransferObj</em>. The
+code can choose to interpret these changes in any way.</dd>
+</dl>
+<p>The handwritten code must explicitly return an <tt class="docutils literal"><span class="pre">int</span></tt> the meaning of which
+depends on the value of <tt class="docutils literal"><span class="pre">sipIsErr</span></tt>.</p>
+<p>If <tt class="docutils literal"><span class="pre">sipIsErr</span></tt> is <tt class="docutils literal"><span class="pre">NULL</span></tt> then a non-zero value is returned if the Python
+object has a type that can be converted to the mapped type. Otherwise zero is
+returned.</p>
+<p>If <tt class="docutils literal"><span class="pre">sipIsErr</span></tt> is not <tt class="docutils literal"><span class="pre">NULL</span></tt> then a combination of the following flags is
+returned.</p>
+<blockquote>
+<ul class="simple">
+<li><tt class="xref docutils literal"><span class="pre">SIP_TEMPORARY</span></tt> is set to indicate that the returned instance
+is a temporary and should be released to avoid a memory leak.</li>
+<li><tt class="xref docutils literal"><span class="pre">SIP_DERIVED_CLASS</span></tt> is set to indicate that the type of the
+returned instance is a derived class. See
+<a class="reference external" href="c_api.html#ref-derived-classes"><em>Generated Derived Classes</em></a>.</li>
+</ul>
+</blockquote>
+<p>The following example converts a Python list of <tt class="docutils literal"><span class="pre">QPoint</span></tt> instances to a
+<tt class="docutils literal"><span class="pre">QList&lt;QPoint&gt;</span></tt> instance:</p>
+<div class="highlight-python"><pre>%ConvertToTypeCode
+ // See if we are just being asked to check the type of the Python
+ // object.
+ if (!sipIsErr)
+ {
+ // Checking whether or not None has been passed instead of a list
+ // has already been done.
+ if (!PyList_Check(sipPy))
+ return 0;
+
+ // Check the type of each element. We specify SIP_NOT_NONE to
+ // disallow None because it is a list of QPoint, not of a pointer
+ // to a QPoint, so None isn't appropriate.
+ for (int i = 0; i &lt; PyList_GET_SIZE(sipPy); ++i)
+ if (!sipCanConvertToType(PyList_GET_ITEM(sipPy, i),
+ sipType_QPoint, SIP_NOT_NONE))
+ return 0;
+
+ // The type is valid.
+ return 1;
+ }
+
+ // Create the instance on the heap.
+ QList&lt;QPoint&gt; *ql = new QList&lt;QPoint&gt;;
+
+ for (int i = 0; i &lt; PyList_GET_SIZE(sipPy); ++i)
+ {
+ QPoint *qp;
+ int state;
+
+ // Get the address of the element's C++ instance. Note that, in
+ // this case, we don't apply any ownership changes to the list
+ // elements, only to the list itself.
+ qp = reinterpret_cast&lt;QPoint *&gt;(sipConvertToType(
+ PyList_GET_ITEM(sipPy, i),
+ sipType_QPoint, 0,
+ SIP_NOT_NONE,
+ &amp;state, sipIsErr));
+
+ // Deal with any errors.
+ if (*sipIsErr)
+ {
+ sipReleaseType(qp, sipType_QPoint, state);
+
+ // Tidy up.
+ delete ql;
+
+ // There is no temporary instance.
+ return 0;
+ }
+
+ ql-&gt;append(*qp);
+
+ // A copy of the QPoint was appended to the list so we no longer
+ // need it. It may be a temporary instance that should be
+ // destroyed, or a wrapped instance that should not be destroyed.
+ // sipReleaseType() will do the right thing.
+ sipReleaseType(qp, sipType_QPoint, state);
+ }
+
+ // Return the instance.
+ *sipCppPtr = ql;
+
+ // The instance should be regarded as temporary (and be destroyed as
+ // soon as it has been used) unless it has been transferred from
+ // Python. sipGetState() is a convenience function that implements
+ // this common transfer behaviour.
+ return sipGetState(sipTransferObj);
+%End</pre>
+</div>
+<p>When used in a class specification the handwritten code replaces the code that
+would normally be automatically generated. This means that the handwritten
+code must also handle instances of the class itself and not just the additional
+types that are being supported. This should be done by making calls to
+<a title="sipCanConvertToType" class="reference external" href="c_api.html#sipCanConvertToType"><tt class="xref docutils literal"><span class="pre">sipCanConvertToType()</span></tt></a> to check the object type and
+<a title="sipConvertToType" class="reference external" href="c_api.html#sipConvertToType"><tt class="xref docutils literal"><span class="pre">sipConvertToType()</span></tt></a> to convert the object. The
+<a title="SIP_NO_CONVERTORS" class="reference external" href="c_api.html#SIP_NO_CONVERTORS"><tt class="xref docutils literal"><span class="pre">SIP_NO_CONVERTORS</span></tt></a> flag <em>must</em> be passed to both these functions to
+prevent recursive calls to the handwritten code.</p>
+<dl class="directive">
+<dt id="directive-%Copying">
+<tt class="descname">%Copying</tt><a class="headerlink" href="#directive-%Copying" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%Copying
+ <em>text</em>
+%End
+</pre>
+<p>This directive is used to specify some arbitrary text that will be included at
+the start of all source files generated by SIP. It is normally used to
+include copyright and licensing terms.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>%Copying
+Copyright (c) 2009 Riverbank Computing Limited
+%End</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%DefaultEncoding">
+<tt class="descname">%DefaultEncoding</tt><a class="headerlink" href="#directive-%DefaultEncoding" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%DefaultEncoding <em>string</em>
+</pre>
+<p>This directive is used to specify the default encoding used for <tt class="docutils literal"><span class="pre">char</span></tt>,
+<tt class="docutils literal"><span class="pre">const</span> <span class="pre">char</span></tt>, <tt class="docutils literal"><span class="pre">char</span> <span class="pre">*</span></tt> or <tt class="docutils literal"><span class="pre">const</span> <span class="pre">char</span> <span class="pre">*</span></tt> values. The encoding can be
+either <tt class="docutils literal"><span class="pre">&quot;ASCII&quot;</span></tt>, <tt class="docutils literal"><span class="pre">&quot;Latin-1&quot;</span></tt>, <tt class="docutils literal"><span class="pre">&quot;UTF-8&quot;</span></tt> or <tt class="docutils literal"><span class="pre">&quot;None&quot;</span></tt>. An encoding of
+<tt class="docutils literal"><span class="pre">&quot;None&quot;</span></tt> means that the value is unencoded. The default can be overridden
+for a particular value using the <a class="reference external" href="annotations.html#aanno-Encoding"><tt class="xref docutils literal"><span class="pre">Encoding</span></tt></a> annotation. If the
+directive is not specified then <tt class="docutils literal"><span class="pre">&quot;None&quot;</span></tt> is used.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>%DefaultEncoding "Latin-1"</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%DefaultMetatype">
+<tt class="descname">%DefaultMetatype</tt><a class="headerlink" href="#directive-%DefaultMetatype" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%DefaultMetatype <em>dotted-name</em>
+</pre>
+<p>This directive is used to specify the Python type that should be used as the
+meta-type for any C/C++ data type defined in the same module, and by importing
+modules, that doesn&#8217;t have an explicit meta-type.</p>
+<p>If this is not specified then <tt class="docutils literal"><span class="pre">sip.wrappertype</span></tt> is used.</p>
+<p>You can also use the <a class="reference external" href="annotations.html#canno-Metatype"><tt class="xref docutils literal"><span class="pre">Metatype</span></tt></a> class annotation to specify the
+meta-type used by a particular C/C++ type.</p>
+<p>See the section <a class="reference external" href="using.html#ref-types-metatypes"><em>Types and Meta-types</em></a> for more details.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>%DefaultMetatype PyQt4.QtCore.pyqtWrapperType</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%DefaultSupertype">
+<tt class="descname">%DefaultSupertype</tt><a class="headerlink" href="#directive-%DefaultSupertype" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%DefaultSupertype <em>dotted-name</em>
+</pre>
+<p>This directive is used to specify the Python type that should be used as the
+super-type for any C/C++ data type defined in the same module that doesn&#8217;t have
+an explicit super-type.</p>
+<p>If this is not specified then <tt class="docutils literal"><span class="pre">sip.wrapper</span></tt> is used.</p>
+<p>You can also use the <a class="reference external" href="annotations.html#canno-Supertype"><tt class="xref docutils literal"><span class="pre">Supertype</span></tt></a> class annotation to specify the
+super-type used by a particular C/C++ type.</p>
+<p>See the section <a class="reference external" href="using.html#ref-types-metatypes"><em>Types and Meta-types</em></a> for more details.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>%DefaultSupertype sip.simplewrapper</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%Doc">
+<tt class="descname">%Doc</tt><a class="headerlink" href="#directive-%Doc" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%Doc
+ <em>text</em>
+%End
+</pre>
+<p>This directive is used to specify some arbitrary text that will be extracted
+by SIP when the <tt class="docutils literal"><span class="pre">-d</span></tt> command line option is used. The directive can be
+specified any number of times and SIP will concatenate all the separate pieces
+of text in the order that it sees them.</p>
+<p>Documentation that is specified using this directive is local to the module in
+which it appears. It is ignored by modules that <a class="reference internal" href="#directive-%Import"><tt class="xref docutils literal"><span class="pre">%Import</span></tt></a> it. Use
+the <a class="reference internal" href="#directive-%ExportedDoc"><tt class="xref docutils literal"><span class="pre">%ExportedDoc</span></tt></a> directive for documentation that should be
+included by all modules that <a class="reference internal" href="#directive-%Import"><tt class="xref docutils literal"><span class="pre">%Import</span></tt></a> this one.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>%Doc
+&lt;h1&gt;An Example&lt;/h1&gt;
+&lt;p&gt;
+This fragment of documentation is HTML and is local to the module in
+which it is defined.
+&lt;/p&gt;
+%End</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%Docstring">
+<tt class="descname">%Docstring</tt><a class="headerlink" href="#directive-%Docstring" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%Docstring
+ <em>text</em>
+%End
+</pre>
+<p>
+<span class="versionmodified">New in version 4.10.</span></p>
+<p>This directive is used to specify explicit docstrings for classes, functions
+and methods.</p>
+<p>The docstring of a class is made up of the docstring specified for the class
+itself, with the docstrings specified for each contructor appended.</p>
+<p>The docstring of a function or method is made up of the concatenated docstrings
+specified for each of the overloads.</p>
+<p>Specifying an explicit docstring will prevent SIP from generating an automatic
+docstring that describes the Python signature of a function or method overload.
+This means that SIP will generate less informative exceptions (i.e. without a
+full signature) when it fails to match a set of arguments to any function or
+method overload.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>class Klass
+{
+%Docstring
+This will be at the start of the class's docstring.
+%End
+
+public:
+ Klass();
+%Docstring
+This will be appended to the class's docstring.
+%End
+};</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%End">
+<tt class="descname">%End</tt><a class="headerlink" href="#directive-%End" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<p>This isn&#8217;t a directive in itself, but is used to terminate a number of
+directives that allow a block of handwritten code or text to be specified.</p>
+<dl class="directive">
+<dt id="directive-%Exception">
+<tt class="descname">%Exception</tt><a class="headerlink" href="#directive-%Exception" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%Exception <em>name</em> [(<em>base-exception)]
+{
+ [*header-code</em>]
+ <em>raise-code</em>
+};
+</pre>
+<p>This directive is used to define new Python exceptions, or to provide a stub
+for existing Python exceptions. It allows handwritten code to be provided
+that implements the translation between C++ exceptions and Python exceptions.
+The arguments to <tt class="docutils literal"><span class="pre">throw</span> <span class="pre">()</span></tt> specifiers must either be names of classes or the
+names of Python exceptions defined by this directive.</p>
+<p><em>name</em> is the name of the exception.</p>
+<p><em>base-exception</em> is the optional base exception. This may be either one of
+the standard Python exceptions or one defined with a previous
+<a class="reference internal" href="#directive-%Exception"><tt class="xref docutils literal"><span class="pre">%Exception</span></tt></a> directive.</p>
+<p><em>header-code</em> is the optional <a class="reference internal" href="#directive-%TypeHeaderCode"><tt class="xref docutils literal"><span class="pre">%TypeHeaderCode</span></tt></a> used to specify any
+external interface to the exception being defined.</p>
+<p><em>raise-code</em> is the <a class="reference internal" href="#directive-%RaiseCode"><tt class="xref docutils literal"><span class="pre">%RaiseCode</span></tt></a> used to specify the handwritten
+code that converts a reference to the C++ exception to the Python exception.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>%Exception std::exception(SIP_Exception) /PyName=StdException/
+{
+%TypeHeaderCode
+#include &lt;exception&gt;
+%End
+%RaiseCode
+ const char *detail = sipExceptionRef.what();
+
+ SIP_BLOCK_THREADS
+ PyErr_SetString(sipException_std_exception, detail);
+ SIP_UNBLOCK_THREADS
+%End
+};</pre>
+</div>
+<p>In this example we map the standard C++ exception to a new Python exception.
+The new exception is called <tt class="docutils literal"><span class="pre">StdException</span></tt> and is derived from the standard
+Python exception <tt class="docutils literal"><span class="pre">Exception</span></tt>.</p>
+<p>An exception may be annotated with <a class="reference external" href="annotations.html#xanno-Default"><tt class="xref docutils literal"><span class="pre">Default</span></tt></a> to specify that it should
+be caught by default if there is no <tt class="docutils literal"><span class="pre">throw</span></tt> clause.</p>
+<dl class="directive">
+<dt id="directive-%ExportedDoc">
+<tt class="descname">%ExportedDoc</tt><a class="headerlink" href="#directive-%ExportedDoc" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%ExportedDoc
+ <em>text</em>
+%End
+</pre>
+<p>This directive is used to specify some arbitrary text that will be extracted
+by SIP when the <tt class="docutils literal"><span class="pre">-d</span></tt> command line option is used. The directive can be
+specified any number of times and SIP will concatenate all the separate pieces
+of text in the order that it sees them.</p>
+<p>Documentation that is specified using this directive will also be included by
+modules that <a class="reference internal" href="#directive-%Import"><tt class="xref docutils literal"><span class="pre">%Import</span></tt></a> it.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>%ExportedDoc
+==========
+An Example
+==========
+
+This fragment of documentation is reStructuredText and will appear in the
+module in which it is defined and all modules that %Import it.
+%End</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%ExportedHeaderCode">
+<tt class="descname">%ExportedHeaderCode</tt><a class="headerlink" href="#directive-%ExportedHeaderCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%ExportedHeaderCode
+ <em>code</em>
+%End
+</pre>
+<p>This directive is used to specify handwritten code, typically the declarations
+of types, that is placed in a header file that is included by all generated
+code for all modules. It should not include function declarations because
+Python modules should not explicitly call functions in another Python module.</p>
+<p>See also <a class="reference internal" href="#directive-%ModuleCode"><tt class="xref docutils literal"><span class="pre">%ModuleCode</span></tt></a> and <a class="reference internal" href="#directive-%ModuleHeaderCode"><tt class="xref docutils literal"><span class="pre">%ModuleHeaderCode</span></tt></a>.</p>
+<dl class="directive">
+<dt id="directive-%Feature">
+<tt class="descname">%Feature</tt><a class="headerlink" href="#directive-%Feature" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%Feature <em>name</em>
+</pre>
+<p>This directive is used to declare a feature. Features (along with
+<a class="reference internal" href="#directive-%Platforms"><tt class="xref docutils literal"><span class="pre">%Platforms</span></tt></a> and <a class="reference internal" href="#directive-%Timeline"><tt class="xref docutils literal"><span class="pre">%Timeline</span></tt></a>) are used by the
+<a class="reference internal" href="#directive-%If"><tt class="xref docutils literal"><span class="pre">%If</span></tt></a> directive to control whether or not parts of a specification
+are processed or ignored.</p>
+<p>Features are mutually independent of each other - any combination of features
+may be enabled or disable. By default all features are enabled. The SIP
+<tt class="docutils literal"><span class="pre">-x</span></tt> command line option is used to disable a feature.</p>
+<p>If a feature is enabled then SIP will automatically generate a corresponding C
+preprocessor symbol for use by handwritten code. The symbol is the name of
+the feature prefixed by <tt class="docutils literal"><span class="pre">SIP_FEATURE_</span></tt>.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>%Feature FOO_SUPPORT
+
+%If (FOO_SUPPORT)
+void foo();
+%End</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%GCClearCode">
+<tt class="descname">%GCClearCode</tt><a class="headerlink" href="#directive-%GCClearCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%GCClearCode
+ <em>code</em>
+%End
+</pre>
+<p>Python has a cyclic garbage collector which can identify and release unneeded
+objects even when their reference counts are not zero. If a wrapped C
+structure or C++ class keeps its own reference to a Python object then, if the
+garbage collector is to do its job, it needs to provide some handwritten code
+to traverse and potentially clear those embedded references.</p>
+<p>See the section <em>Supporting cyclic garbage collection</em> in <a class="reference external" href="http://www.python.org/dev/doc/devel/ext/">Embedding and
+Extending the Python Interpreter</a>
+for the details.</p>
+<p>This directive is used to specify the code that clears any embedded references.
+(See <a class="reference internal" href="#directive-%GCTraverseCode"><tt class="xref docutils literal"><span class="pre">%GCTraverseCode</span></tt></a> for specifying the code that traverses any
+embedded references.)</p>
+<p>The following variables are made available to the handwritten code:</p>
+<dl class="docutils">
+<dt><em>type</em> *sipCpp</dt>
+<dd>This is a pointer to the structure or class instance. Its <em>type</em> is a
+pointer to the structure or class.</dd>
+<dt>int sipRes</dt>
+<dd>The handwritten code should set this to the result to be returned.</dd>
+</dl>
+<p>The following simplified example is taken from PyQt. The <tt class="docutils literal"><span class="pre">QCustomEvent</span></tt>
+class allows arbitary data to be attached to the event. In PyQt this data is
+always a Python object and so should be handled by the garbage collector:</p>
+<div class="highlight-python"><pre>%GCClearCode
+ PyObject *obj;
+
+ // Get the object.
+ obj = reinterpret_cast&lt;PyObject *&gt;(sipCpp-&gt;data());
+
+ // Clear the pointer.
+ sipCpp-&gt;setData(0);
+
+ // Clear the reference.
+ Py_XDECREF(obj);
+
+ // Report no error.
+ sipRes = 0;
+%End</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%GCTraverseCode">
+<tt class="descname">%GCTraverseCode</tt><a class="headerlink" href="#directive-%GCTraverseCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%GCTraverseCode
+ <em>code</em>
+%End
+</pre>
+<p>This directive is used to specify the code that traverses any embedded
+references for Python&#8217;s cyclic garbage collector. (See
+<a class="reference internal" href="#directive-%GCClearCode"><tt class="xref docutils literal"><span class="pre">%GCClearCode</span></tt></a> for a full explanation.)</p>
+<p>The following variables are made available to the handwritten code:</p>
+<dl class="docutils">
+<dt><em>type</em> *sipCpp</dt>
+<dd>This is a pointer to the structure or class instance. Its <em>type</em> is a
+pointer to the structure or class.</dd>
+<dt>visitproc sipVisit</dt>
+<dd>This is the visit function provided by the garbage collector.</dd>
+<dt>void *sipArg</dt>
+<dd>This is the argument to the visit function provided by the garbage
+collector.</dd>
+<dt>int sipRes</dt>
+<dd>The handwritten code should set this to the result to be returned.</dd>
+</dl>
+<p>The following simplified example is taken from PyQt&#8217;s <tt class="docutils literal"><span class="pre">QCustomEvent</span></tt> class:</p>
+<div class="highlight-python"><pre>%GCTraverseCode
+ PyObject *obj;
+
+ // Get the object.
+ obj = reinterpret_cast&lt;PyObject *&gt;(sipCpp-&gt;data());
+
+ // Call the visit function if there was an object.
+ if (obj)
+ sipRes = sipVisit(obj, sipArg);
+ else
+ sipRes = 0;
+%End</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%GetCode">
+<tt class="descname">%GetCode</tt><a class="headerlink" href="#directive-%GetCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%GetCode
+ <em>code</em>
+%End
+</pre>
+<p>This directive is used after the declaration of a C++ class variable or C
+structure member to specify handwritten code to convert it to a Python object.
+It is usually used to handle types that SIP cannot deal with automatically.</p>
+<p>The following variables are made available to the handwritten code:</p>
+<dl class="docutils">
+<dt><em>type</em> *sipCpp</dt>
+<dd>This is a pointer to the structure or class instance. Its <em>type</em> is a
+pointer to the structure or class. It is not made available if the
+variable being wrapped is a static class variable.</dd>
+<dt>PyObject *sipPy</dt>
+<dd>The handwritten code must set this to the Python representation of the
+class variable or structure member. If there is an error then the code
+must raise an exception and set this to <tt class="docutils literal"><span class="pre">NULL</span></tt>.</dd>
+<dt>PyObject *sipPyType</dt>
+<dd>If the variable being wrapped is a static class variable then this is the
+Python type object of the class from which the variable was referenced
+(<em>not</em> the class in which it is defined). It may be safely cast to a
+PyTypeObject * or a sipWrapperType *.</dd>
+</dl>
+<p>For example:</p>
+<div class="highlight-python"><pre>struct Entity
+{
+ /*
+ * In this contrived example the C library we are wrapping actually
+ * defines this as char buffer[100] which SIP cannot handle
+ * automatically.
+ */
+ char *buffer;
+%GetCode
+ sipPy = PyString_FromStringAndSize(sipCpp-&gt;buffer, 100);
+%End
+%SetCode
+ char *ptr;
+ int length;
+
+ if (PyString_AsStringAndSize(sipPy, &amp;ptr, &amp;length) == -1)
+ sipErr = 1;
+ else if (length != 100)
+ {
+ /*
+ * Raise an exception because the length isn't exactly right.
+ */
+
+ PyErr_SetString(PyExc_ValueError, "an Entity.buffer must be exactly 100 bytes");
+ sipErr = 1;
+ }
+ else
+ memcpy(sipCpp-&gt;buffer, ptr, 100);
+%End
+}</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%If">
+<tt class="descname">%If</tt><a class="headerlink" href="#directive-%If" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%If (<em>expression</em>)
+ <em>specification</em>
+%End
+</pre>
+<p>where</p>
+<pre class="literal-block">
+<em>expression</em> ::= [<em>ored-qualifiers</em> | <em>range</em>]
+
+<em>ored-qualifiers</em> ::= [<em>qualifier</em> | <em>qualifier</em> <strong>||</strong> <em>ored-qualifiers</em>]
+
+<em>qualifier</em> ::= [<strong>!</strong>] [<em>feature</em> | <em>platform</em>]
+
+<em>range</em> ::= [<em>version</em>] <strong>-</strong> [<em>version</em>]
+</pre>
+<p>This directive is used in conjunction with features (see
+<a class="reference internal" href="#directive-%Feature"><tt class="xref docutils literal"><span class="pre">%Feature</span></tt></a>), platforms (see <a class="reference internal" href="#directive-%Platforms"><tt class="xref docutils literal"><span class="pre">%Platforms</span></tt></a>) and versions
+(see <a class="reference internal" href="#directive-%Timeline"><tt class="xref docutils literal"><span class="pre">%Timeline</span></tt></a>) to control whether or not parts of a specification
+are processed or not.</p>
+<p>A <em>range</em> of versions means all versions starting with the lower bound up to
+but excluding the upper bound. If the lower bound is omitted then it is
+interpreted as being before the earliest version. If the upper bound is
+omitted then it is interpreted as being after the latest version.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>%Feature SUPPORT_FOO
+%Platforms {WIN32_PLATFORM POSIX_PLATFORM MACOS_PLATFORM}
+%Timeline {V1_0 V1_1 V2_0 V3_0}
+
+%If (!SUPPORT_FOO)
+ // Process this if the SUPPORT_FOO feature is disabled.
+%End
+
+%If (POSIX_PLATFORM || MACOS_PLATFORM)
+ // Process this if either the POSIX_PLATFORM or MACOS_PLATFORM
+ // platforms are enabled.
+%End
+
+%If (V1_0 - V2_0)
+ // Process this if either V1_0 or V1_1 is enabled.
+%End
+
+%If (V2_0 - )
+ // Process this if either V2_0 or V3_0 is enabled.
+%End
+
+%If ( - )
+ // Always process this.
+%End</pre>
+</div>
+<p>Note that this directive is not implemented as a preprocessor. Only the
+following parts of a specification are affected by it:</p>
+<blockquote>
+<ul class="simple">
+<li><a class="reference internal" href="#directive-%API"><tt class="xref docutils literal"><span class="pre">%API</span></tt></a></li>
+<li><tt class="docutils literal"><span class="pre">class</span></tt></li>
+<li><a class="reference internal" href="#directive-%ConvertFromTypeCode"><tt class="xref docutils literal"><span class="pre">%ConvertFromTypeCode</span></tt></a></li>
+<li><a class="reference internal" href="#directive-%ConvertToSubClassCode"><tt class="xref docutils literal"><span class="pre">%ConvertToSubClassCode</span></tt></a></li>
+<li><a class="reference internal" href="#directive-%ConvertToTypeCode"><tt class="xref docutils literal"><span class="pre">%ConvertToTypeCode</span></tt></a></li>
+<li><tt class="docutils literal"><span class="pre">enum</span></tt></li>
+<li><a class="reference internal" href="#directive-%DefaultEncoding"><tt class="xref docutils literal"><span class="pre">%DefaultEncoding</span></tt></a></li>
+<li><a class="reference internal" href="#directive-%DefaultMetatype"><tt class="xref docutils literal"><span class="pre">%DefaultMetatype</span></tt></a></li>
+<li><a class="reference internal" href="#directive-%DefaultSupertype"><tt class="xref docutils literal"><span class="pre">%DefaultSupertype</span></tt></a></li>
+<li><a class="reference internal" href="#directive-%ExportedHeaderCode"><tt class="xref docutils literal"><span class="pre">%ExportedHeaderCode</span></tt></a></li>
+<li>functions</li>
+<li><a class="reference internal" href="#directive-%GCClearCode"><tt class="xref docutils literal"><span class="pre">%GCClearCode</span></tt></a></li>
+<li><a class="reference internal" href="#directive-%GCTraverseCode"><tt class="xref docutils literal"><span class="pre">%GCTraverseCode</span></tt></a></li>
+<li><a class="reference internal" href="#directive-%If"><tt class="xref docutils literal"><span class="pre">%If</span></tt></a></li>
+<li><a class="reference internal" href="#directive-%InitialisationCode"><tt class="xref docutils literal"><span class="pre">%InitialisationCode</span></tt></a></li>
+<li><a class="reference internal" href="#directive-%MappedType"><tt class="xref docutils literal"><span class="pre">%MappedType</span></tt></a></li>
+<li><a class="reference internal" href="#directive-%MethodCode"><tt class="xref docutils literal"><span class="pre">%MethodCode</span></tt></a></li>
+<li><a class="reference internal" href="#directive-%ModuleCode"><tt class="xref docutils literal"><span class="pre">%ModuleCode</span></tt></a></li>
+<li><a class="reference internal" href="#directive-%ModuleHeaderCode"><tt class="xref docutils literal"><span class="pre">%ModuleHeaderCode</span></tt></a></li>
+<li><tt class="docutils literal"><span class="pre">namespace</span></tt></li>
+<li><a class="reference internal" href="#directive-%PostInitialisationCode"><tt class="xref docutils literal"><span class="pre">%PostInitialisationCode</span></tt></a></li>
+<li><a class="reference internal" href="#directive-%PreInitialisationCode"><tt class="xref docutils literal"><span class="pre">%PreInitialisationCode</span></tt></a></li>
+<li><tt class="docutils literal"><span class="pre">struct</span></tt></li>
+<li><tt class="docutils literal"><span class="pre">typedef</span></tt></li>
+<li><a class="reference internal" href="#directive-%TypeCode"><tt class="xref docutils literal"><span class="pre">%TypeCode</span></tt></a></li>
+<li><a class="reference internal" href="#directive-%TypeHeaderCode"><tt class="xref docutils literal"><span class="pre">%TypeHeaderCode</span></tt></a></li>
+<li><a class="reference internal" href="#directive-%UnitCode"><tt class="xref docutils literal"><span class="pre">%UnitCode</span></tt></a></li>
+<li>variables</li>
+<li><a class="reference internal" href="#directive-%VirtualCatcherCode"><tt class="xref docutils literal"><span class="pre">%VirtualCatcherCode</span></tt></a></li>
+</ul>
+</blockquote>
+<p>Also note that the only way to specify the logical and of qualifiers is to use
+nested <a class="reference internal" href="#directive-%If"><tt class="xref docutils literal"><span class="pre">%If</span></tt></a> directives.</p>
+<dl class="directive">
+<dt id="directive-%Import">
+<tt class="descname">%Import</tt><a class="headerlink" href="#directive-%Import" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%Import <em>filename</em>
+</pre>
+<p>This directive is used to import the specification of another module. This is
+needed if the current module makes use of any types defined in the imported
+module, e.g. as an argument to a function, or to sub-class.</p>
+<p>If <em>filename</em> cannot be opened then SIP prepends <em>filename</em> with the name of
+the directory containing the current specification file (i.e. the one
+containing the <a class="reference internal" href="#directive-%Import"><tt class="xref docutils literal"><span class="pre">%Import</span></tt></a> directive) and tries again. If this also
+fails then SIP prepends <em>filename</em> with each of the directories, in turn,
+specified by the <tt class="docutils literal"><span class="pre">-I</span></tt> command line option.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>%Import qt/qtmod.sip</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%Include">
+<tt class="descname">%Include</tt><a class="headerlink" href="#directive-%Include" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%Include <em>filename</em>
+</pre>
+<p>This directive is used to include contents of another file as part of the
+specification of the current module. It is the equivalent of the C
+preprocessor&#8217;s <tt class="docutils literal"><span class="pre">#include</span></tt> directive and is used to structure a large module
+specification into manageable pieces.</p>
+<p><a class="reference internal" href="#directive-%Include"><tt class="xref docutils literal"><span class="pre">%Include</span></tt></a> follows the same search process as <a class="reference internal" href="#directive-%Import"><tt class="xref docutils literal"><span class="pre">%Import</span></tt></a>
+when trying to open <em>filename</em>.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>%Include qwidget.sip</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%InitialisationCode">
+<tt class="descname">%InitialisationCode</tt><a class="headerlink" href="#directive-%InitialisationCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%InitialisationCode
+ <em>code</em>
+%End
+</pre>
+<p>This directive is used to specify handwritten code that is embedded in-line
+in the generated module initialisation code after the SIP module has been
+imported but before the module itself has been initialised.</p>
+<p>It is typically used to call <a title="sipRegisterPyType" class="reference external" href="c_api.html#sipRegisterPyType"><tt class="xref docutils literal"><span class="pre">sipRegisterPyType()</span></tt></a>.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>%InitialisationCode
+ // The code will be executed when the module is first imported, after
+ // the SIP module has been imported, but before other module-specific
+ // initialisation has been completed.
+%End</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%License">
+<tt class="descname">%License</tt><a class="headerlink" href="#directive-%License" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%License /<em>license-annotations</em>/
+</pre>
+<p>This directive is used to specify the contents of an optional license
+dictionary. The license dictionary is called <tt class="xref docutils literal"><span class="pre">__license__</span></tt> and is stored
+in the module dictionary. The elements of the dictionary are specified using
+the <a class="reference external" href="annotations.html#lanno-Licensee"><tt class="xref docutils literal"><span class="pre">Licensee</span></tt></a>, <a class="reference external" href="annotations.html#lanno-Signature"><tt class="xref docutils literal"><span class="pre">Signature</span></tt></a>, <a class="reference external" href="annotations.html#lanno-Timestamp"><tt class="xref docutils literal"><span class="pre">Timestamp</span></tt></a> and <a class="reference external" href="annotations.html#lanno-Type"><tt class="xref docutils literal"><span class="pre">Type</span></tt></a>
+annotations. Only the <a class="reference external" href="annotations.html#lanno-Type"><tt class="xref docutils literal"><span class="pre">Type</span></tt></a> annotation is compulsory.</p>
+<p>Note that this directive isn&#8217;t an attempt to impose any licensing restrictions
+on a module. It is simply a method for easily embedding licensing information
+in a module so that it is accessible to Python scripts.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>%License /Type="GPL"/</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%MappedType">
+<tt class="descname">%MappedType</tt><a class="headerlink" href="#directive-%MappedType" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+template&lt;<em>type-list</em>&gt;
+%MappedType <em>type</em>
+{
+ [<em>header-code</em>]
+ [<em>convert-to-code</em>]
+ [<em>convert-from-code</em>]
+};
+
+%MappedType <em>type</em>
+{
+ [<em>header-code</em>]
+ [<em>convert-to-code</em>]
+ [<em>convert-from-code</em>]
+};
+</pre>
+<p>This directive is used to define an automatic mapping between a C or C++ type
+and a Python type. It can be used as part of a template, or to map a specific
+type.</p>
+<p>When used as part of a template <em>type</em> cannot itself refer to a template. Any
+occurrences of any of the type names (but not any <tt class="docutils literal"><span class="pre">*</span></tt> or <tt class="docutils literal"><span class="pre">&amp;</span></tt>) in
+<em>type-list</em> will be replaced by the actual type names used when the template is
+instantiated. Template mapped types are instantiated automatically as required
+(unlike template classes which are only instantiated using <tt class="docutils literal"><span class="pre">typedef</span></tt>).</p>
+<p>Any explicit mapped type will be used in preference to any template that maps
+the same type, ie. a template will not be automatically instantiated if there
+is an explicit mapped type.</p>
+<p><em>header-code</em> is the <a class="reference internal" href="#directive-%TypeHeaderCode"><tt class="xref docutils literal"><span class="pre">%TypeHeaderCode</span></tt></a> used to specify the library
+interface to the type being mapped.</p>
+<p><em>convert-to-code</em> is the <a class="reference internal" href="#directive-%ConvertToTypeCode"><tt class="xref docutils literal"><span class="pre">%ConvertToTypeCode</span></tt></a> used to specify the
+handwritten code that converts a Python object to an instance of the mapped
+type.</p>
+<p><em>convert-from-code</em> is the <a class="reference internal" href="#directive-%ConvertFromTypeCode"><tt class="xref docutils literal"><span class="pre">%ConvertFromTypeCode</span></tt></a> used to specify
+the handwritten code that converts an instance of the mapped type to a Python
+object.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>template&lt;Type *&gt;
+%MappedType QList
+{
+%TypeHeaderCode
+// Include the library interface to the type being mapped.
+#include &lt;qlist.h&gt;
+%End
+
+%ConvertToTypeCode
+ // See if we are just being asked to check the type of the Python
+ // object.
+ if (sipIsErr == NULL)
+ {
+ // Check it is a list.
+ if (!PyList_Check(sipPy))
+ return 0;
+
+ // Now check each element of the list is of the type we expect.
+ // The template is for a pointer type so we don't disallow None.
+ for (int i = 0; i &lt; PyList_GET_SIZE(sipPy); ++i)
+ if (!sipCanConvertToType(PyList_GET_ITEM(sipPy, i),
+ sipType_Type, 0))
+ return 0;
+
+ return 1;
+ }
+
+ // Create the instance on the heap.
+ QList&lt;Type *&gt; *ql = new QList&lt;Type *&gt;;
+
+ for (int i = 0; i &lt; PyList_GET_SIZE(sipPy); ++i)
+ {
+ // Use the SIP API to convert the Python object to the
+ // corresponding C++ instance. Note that we apply any ownership
+ // transfer to the list itself, not the individual elements.
+ Type *t = reinterpret_cast&lt;Type *&gt;(sipConvertToType(
+ PyList_GET_ITEM(sipPy, i),
+ sipType_Type, 0, 0, 0,
+ sipIsErr));
+
+ if (*sipIsErr)
+ {
+ // Tidy up.
+ delete ql;
+
+ // There is nothing on the heap.
+ return 0;
+ }
+
+ // Add the pointer to the C++ instance.
+ ql-&gt;append(t);
+ }
+
+ // Return the instance on the heap.
+ *sipCppPtr = ql;
+
+ // Apply the normal transfer.
+ return sipGetState(sipTransferObj);
+%End
+
+%ConvertFromTypeCode
+ PyObject *l;
+
+ // Create the Python list of the correct length.
+ if ((l = PyList_New(sipCpp-&gt;size())) == NULL)
+ return NULL;
+
+ // Go through each element in the C++ instance and convert it to the
+ // corresponding Python object.
+ for (int i = 0; i &lt; sipCpp-&gt;size(); ++i)
+ {
+ Type *t = sipCpp-&gt;at(i);
+ PyObject *tobj;
+
+ if ((tobj = sipConvertFromType(t, sipType_Type, sipTransferObj)) == NULL)
+ {
+ // There was an error so garbage collect the Python list.
+ Py_DECREF(l);
+ return NULL;
+ }
+
+ PyList_SET_ITEM(l, i, tobj);
+ }
+
+ // Return the Python list.
+ return l;
+%End
+}</pre>
+</div>
+<p>Using this we can use, for example, <tt class="docutils literal"><span class="pre">QList&lt;QObject</span> <span class="pre">*&gt;</span></tt> throughout the
+module&#8217;s specification files (and in any module that imports this one). The
+generated code will automatically map this to and from a Python list of QObject
+instances when appropriate.</p>
+<dl class="directive">
+<dt id="directive-%MethodCode">
+<tt class="descname">%MethodCode</tt><a class="headerlink" href="#directive-%MethodCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%MethodCode
+ <em>code</em>
+%End
+</pre>
+<p>This directive is used as part of the specification of a global function, class
+method, operator, constructor or destructor to specify handwritten code that
+replaces the normally generated call to the function being wrapped. It is
+usually used to handle argument types and results that SIP cannot deal with
+automatically.</p>
+<p>Normally the specified code is embedded in-line after the function&#8217;s arguments
+have been successfully converted from Python objects to their C or C++
+equivalents. In this case the specified code must not include any <tt class="docutils literal"><span class="pre">return</span></tt>
+statements.</p>
+<p>However if the <a class="reference external" href="annotations.html#fanno-NoArgParser"><tt class="xref docutils literal"><span class="pre">NoArgParser</span></tt></a> annotation has been used then the specified
+code is also responsible for parsing the arguments. No other code is generated
+by SIP and the specified code must include a <tt class="docutils literal"><span class="pre">return</span></tt> statement.</p>
+<p>In the context of a destructor the specified code is embedded in-line in the
+Python type&#8217;s deallocation function. Unlike other contexts it supplements
+rather than replaces the normally generated code, so it must not include code
+to return the C structure or C++ class instance to the heap. The code is only
+called if ownership of the structure or class is with Python.</p>
+<p>The specified code must also handle the Python Global Interpreter Lock (GIL).
+If compatibility with SIP v3.x is required then the GIL must be released
+immediately before the C++ call and reacquired immediately afterwards as shown
+in this example fragment:</p>
+<div class="highlight-python"><pre>Py_BEGIN_ALLOW_THREADS
+sipCpp-&gt;foo();
+Py_END_ALLOW_THREADS</pre>
+</div>
+<p>If compatibility with SIP v3.x is not required then this is optional but
+should be done if the C++ function might block the current thread or take a
+significant amount of time to execute. (See <a class="reference external" href="using.html#ref-gil"><em>The Python Global Interpreter Lock</em></a> and the
+<a class="reference external" href="annotations.html#fanno-ReleaseGIL"><tt class="xref docutils literal"><span class="pre">ReleaseGIL</span></tt></a> and <a class="reference external" href="annotations.html#fanno-HoldGIL"><tt class="xref docutils literal"><span class="pre">HoldGIL</span></tt></a> annotations.)</p>
+<p>If the <a class="reference external" href="annotations.html#fanno-NoArgParser"><tt class="xref docutils literal"><span class="pre">NoArgParser</span></tt></a> annotation has not been used then the following
+variables are made available to the handwritten code:</p>
+<dl class="docutils">
+<dt><em>type</em> a0</dt>
+<dd><p class="first">There is a variable for each argument of the Python signature (excluding
+any <tt class="docutils literal"><span class="pre">self</span></tt> argument) named <tt class="docutils literal"><span class="pre">a0</span></tt>, <tt class="docutils literal"><span class="pre">a1</span></tt>, etc. The <em>type</em> of the
+variable is the same as the type defined in the specification with the
+following exceptions:</p>
+<ul class="simple">
+<li>if the argument is only used to return a value (e.g. it is an <tt class="docutils literal"><span class="pre">int</span> <span class="pre">*</span></tt>
+without an <a class="reference external" href="annotations.html#aanno-In"><tt class="xref docutils literal"><span class="pre">In</span></tt></a> annotation) then the type has one less level of
+indirection (e.g. it will be an <tt class="docutils literal"><span class="pre">int</span></tt>)</li>
+<li>if the argument is a structure or class (or a reference or a pointer to a
+structure or class) then <em>type</em> will always be a pointer to the structure
+or class.</li>
+</ul>
+<p class="last">Note that handwritten code for destructors never has any arguments.</p>
+</dd>
+<dt>PyObject *a0Wrapper</dt>
+<dd>This variable is made available only if the <a class="reference external" href="annotations.html#aanno-GetWrapper"><tt class="xref docutils literal"><span class="pre">GetWrapper</span></tt></a> annotation
+is specified for the corresponding argument. The variable is a pointer to
+the Python object that wraps the argument.</dd>
+<dt><em>type</em> *sipCpp</dt>
+<dd><p class="first">If the directive is used in the context of a class constructor then this
+must be set by the handwritten code to the constructed instance. If it is
+set to <tt class="docutils literal"><span class="pre">0</span></tt> and no Python exception is raised then SIP will continue to
+try other Python signatures.</p>
+<p>If the directive is used in the context of a method (but not the standard
+binary operator methods, e.g. <tt class="xref docutils literal"><span class="pre">__add__()</span></tt>) or a destructor then this is
+a pointer to the C structure or C++ class instance.</p>
+<p>Its <em>type</em> is a pointer to the structure or class.</p>
+<p class="last">Standard binary operator methods follow the same convention as global
+functions and instead define two arguments called <tt class="docutils literal"><span class="pre">a0</span></tt> and <tt class="docutils literal"><span class="pre">a1</span></tt>.</p>
+</dd>
+<dt>sipErrorState sipError</dt>
+<dd><p class="first">The handwritten code should set this to either <tt class="docutils literal"><span class="pre">sipErrorContinue</span></tt> or
+<tt class="docutils literal"><span class="pre">sipErrorFail</span></tt>, and raise an appropriate Python exception, if an error
+is detected. Its initial value will be <tt class="docutils literal"><span class="pre">sipErrorNone</span></tt>.</p>
+<p>When <tt class="docutils literal"><span class="pre">sipErrorContinue</span></tt> is used, SIP will remember the exception as the
+reason why the particular overloaded callable could not be invoked. It
+will then continue to try the next overloaded callable. It is typically
+used by code that needs to do additional type checking of the callable&#8217;s
+arguments.</p>
+<p>When <tt class="docutils literal"><span class="pre">sipErrorFail1</span></tt> is used, SIP will report the exception immediately
+and will not attempt to invoke other overloaded callables.</p>
+<p class="last"><tt class="docutils literal"><span class="pre">sipError</span></tt> is not provided for destructors.</p>
+</dd>
+<dt>int sipIsErr</dt>
+<dd><p class="first">The handwritten code should set this to a non-zero value, and raise an
+appropriate Python exception, if an error is detected. This is the
+equivalent of setting <tt class="docutils literal"><span class="pre">sipError</span></tt> to <tt class="docutils literal"><span class="pre">sipErrorFail</span></tt>. Its initial value
+will be <tt class="docutils literal"><span class="pre">0</span></tt>.</p>
+<p class="last"><tt class="docutils literal"><span class="pre">sipIsErr</span></tt> is not provided for destructors.</p>
+</dd>
+<dt><em>type</em> sipRes</dt>
+<dd><p class="first">The handwritten code should set this to the result to be returned. The
+<em>type</em> of the variable is the same as the type defined in the Python
+signature in the specification with the following exception:</p>
+<ul class="simple">
+<li>if the argument is a structure or class (or a reference or a pointer to a
+structure or class) then <em>type</em> will always be a pointer to the structure
+or class.</li>
+</ul>
+<p class="last"><tt class="docutils literal"><span class="pre">sipRes</span></tt> is not provided for inplace operators (e.g. <tt class="docutils literal"><span class="pre">+=</span></tt> or
+<tt class="xref docutils literal"><span class="pre">__imul__()</span></tt>) as their results are handled automatically, nor for class
+constructors or destructors.</p>
+</dd>
+<dt>PyObject *sipSelf</dt>
+<dd>If the directive is used in the context of a class constructor, destructor
+or method then this is the Python object that wraps the structure or class
+instance, i.e. <tt class="docutils literal"><span class="pre">self</span></tt>.</dd>
+<dt>bool sipSelfWasArg</dt>
+<dd><p class="first">This is only made available for non-abstract, virtual methods. It is set
+if <tt class="docutils literal"><span class="pre">self</span></tt> was explicitly passed as the first argument of the method
+rather than being bound to the method. In other words, the call was:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">Klass</span><span class="o">.</span><span class="n">foo</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">...</span><span class="p">)</span>
+</pre></div>
+</div>
+<p>rather than:</p>
+<div class="last highlight-python"><div class="highlight"><pre><span class="bp">self</span><span class="o">.</span><span class="n">foo</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
+</pre></div>
+</div>
+</dd>
+</dl>
+<p>If the <a class="reference external" href="annotations.html#fanno-NoArgParser"><tt class="xref docutils literal"><span class="pre">NoArgParser</span></tt></a> annotation has been used then only the following
+variables are made available to the handwritten code:</p>
+<dl class="docutils">
+<dt>PyObject *sipArgs</dt>
+<dd>This is the tuple of arguments.</dd>
+<dt>PyObject *sipKwds</dt>
+<dd>This is the dictionary of keyword arguments.</dd>
+</dl>
+<p>The following is a complete example:</p>
+<div class="highlight-python"><pre>class Klass
+{
+public:
+ virtual int foo(SIP_PYTUPLE);
+%MethodCode
+ // The C++ API takes a 2 element array of integers but passing a
+ // two element tuple is more Pythonic.
+
+ int iarr[2];
+
+ if (PyArg_ParseTuple(a0, "ii", &amp;iarr[0], &amp;iarr[1]))
+ {
+ Py_BEGIN_ALLOW_THREADS
+ sipRes = sipSelfWasArg ? sipCpp-&gt;Klass::foo(iarr)
+ : sipCpp-&gt;foo(iarr);
+ Py_END_ALLOW_THREADS
+ }
+ else
+ {
+ // PyArg_ParseTuple() will have raised the exception.
+ sipIsErr = 1;
+ }
+%End
+};</pre>
+</div>
+<p>As the example is a virtual method <a class="footnote-reference" href="#id2" id="id1">[1]</a>, note the use of <tt class="docutils literal"><span class="pre">sipSelfWasArg</span></tt> to
+determine exactly which implementation of <tt class="docutils literal"><span class="pre">foo()</span></tt> to call.</p>
+<p>If a method is in the <tt class="docutils literal"><span class="pre">protected</span></tt> section of a C++ class then SIP generates
+helpers that provide access to method. However, these are not available if
+the Python module is being built with <tt class="docutils literal"><span class="pre">protected</span></tt> redefined as <tt class="docutils literal"><span class="pre">public</span></tt>.</p>
+<p>The following pattern should be used to cover all possibilities:</p>
+<div class="highlight-python"><pre>#if defined(SIP_PROTECTED_IS_PUBLIC)
+ sipRes = sipSelfWasArg ? sipCpp-&gt;Klass::foo(iarr)
+ : sipCpp-&gt;foo(iarr);
+#else
+ sipRes = sipCpp-&gt;sipProtectVirt_foo(sipSelfWasArg, iarr);
+#endif</pre>
+</div>
+<p>If a method is in the <tt class="docutils literal"><span class="pre">protected</span></tt> section of a C++ class but is not virtual
+then the pattern should instead be:</p>
+<div class="highlight-python"><pre>#if defined(SIP_PROTECTED_IS_PUBLIC)
+ sipRes = sipCpp-&gt;foo(iarr);
+#else
+ sipRes = sipCpp-&gt;sipProtect_foo(iarr);
+#endif</pre>
+</div>
+<table class="docutils footnote" frame="void" id="id2" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td>See <a class="reference internal" href="#directive-%VirtualCatcherCode"><tt class="xref docutils literal"><span class="pre">%VirtualCatcherCode</span></tt></a> for a description of how SIP
+generated code handles the reimplementation of C++ virtual methods in
+Python.</td></tr>
+</tbody>
+</table>
+<dl class="directive">
+<dt id="directive-%Module">
+<tt class="descname">%Module</tt><a class="headerlink" href="#directive-%Module" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%Module <em>name</em> [<em>version</em>]
+</pre>
+<p>This directive is used to identify that the library being wrapped is a C++
+library and to define the name of the module and it&#8217;s optional version number.</p>
+<p>The name may contain periods to specify that the module is part of a Python
+package.</p>
+<p>The optional version number is useful if you (or others) might create other
+modules that build on this module, i.e. if another module might
+<a class="reference internal" href="#directive-%Import"><tt class="xref docutils literal"><span class="pre">%Import</span></tt></a> this module. Under the covers, a module exports an API
+that is used by modules that <a class="reference internal" href="#directive-%Import"><tt class="xref docutils literal"><span class="pre">%Import</span></tt></a> it and the API is given a
+version number. A module built on that module knows the version number of the
+API that it is expecting. If, when the modules are imported at run-time, the
+version numbers do not match then a Python exception is raised. The dependent
+module must then be re-built using the correct specification files for the base
+module.</p>
+<p>The version number should be incremented whenever a module is changed. Some
+changes don&#8217;t affect the exported API, but it is good practice to change the
+version number anyway.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>%Module qt 5</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%ModuleCode">
+<tt class="descname">%ModuleCode</tt><a class="headerlink" href="#directive-%ModuleCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%ModuleCode
+ <em>code</em>
+%End
+</pre>
+<p>This directive is used to specify handwritten code, typically the
+implementations of utility functions, that can be called by other handwritten
+code in the module.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>%ModuleCode
+// Print an object on stderr for debugging purposes.
+void dump_object(PyObject *o)
+{
+ PyObject_Print(o, stderr, 0);
+ fprintf(stderr, "\n");
+}
+%End</pre>
+</div>
+<p>See also <a class="reference internal" href="#directive-%ExportedHeaderCode"><tt class="xref docutils literal"><span class="pre">%ExportedHeaderCode</span></tt></a> and <a class="reference internal" href="#directive-%ModuleHeaderCode"><tt class="xref docutils literal"><span class="pre">%ModuleHeaderCode</span></tt></a>.</p>
+<dl class="directive">
+<dt id="directive-%ModuleHeaderCode">
+<tt class="descname">%ModuleHeaderCode</tt><a class="headerlink" href="#directive-%ModuleHeaderCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%ModuleHeaderCode
+ <em>code</em>
+%End
+</pre>
+<p>This directive is used to specify handwritten code, typically the declarations
+of utility functions, that is placed in a header file that is included by all
+generated code for the same module.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>%ModuleHeaderCode
+void dump_object(PyObject *o);
+%End</pre>
+</div>
+<p>See also <a class="reference internal" href="#directive-%ExportedHeaderCode"><tt class="xref docutils literal"><span class="pre">%ExportedHeaderCode</span></tt></a> and <a class="reference internal" href="#directive-%ModuleCode"><tt class="xref docutils literal"><span class="pre">%ModuleCode</span></tt></a>.</p>
+<dl class="directive">
+<dt id="directive-%OptionalInclude">
+<tt class="descname">%OptionalInclude</tt><a class="headerlink" href="#directive-%OptionalInclude" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%OptionalInclude <em>filename</em>
+</pre>
+<p>This directive is identical to the <a class="reference internal" href="#directive-%Include"><tt class="xref docutils literal"><span class="pre">%Include</span></tt></a> directive except that
+SIP silently continues processing if <em>filename</em> could not be opened.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>%OptionalInclude license.sip</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%PickleCode">
+<tt class="descname">%PickleCode</tt><a class="headerlink" href="#directive-%PickleCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%PickleCode
+ <em>code</em>
+%End
+</pre>
+<p>This directive is used to specify handwritten code to pickle a C structure or
+C++ class instance.</p>
+<p>The following variables are made available to the handwritten code:</p>
+<dl class="docutils">
+<dt><em>type</em> *sipCpp</dt>
+<dd>This is a pointer to the structure or class instance. Its <em>type</em> is a
+pointer to the structure or class.</dd>
+<dt>PyObject *sipRes</dt>
+<dd>The handwritten code must set this to a tuple of the arguments that will
+be passed to the type&#8217;s __init__() method when the structure or class
+instance is unpickled. If there is an error then the code must raise an
+exception and set this to <tt class="docutils literal"><span class="pre">NULL</span></tt>.</dd>
+</dl>
+<p>For example:</p>
+<div class="highlight-python"><pre>class Point
+{
+ Point(int x, y);
+
+ int x() const;
+ int y() const;
+
+%PickleCode
+ sipRes = Py_BuildValue("ii", sipCpp-&gt;x(), sipCpp-&gt;y());
+%End
+}</pre>
+</div>
+<p>Note that SIP works around the Python limitation that prevents nested types
+being pickled.</p>
+<p>Both named and unnamed enums can be pickled automatically without providing any
+handwritten code.</p>
+<dl class="directive">
+<dt id="directive-%Platforms">
+<tt class="descname">%Platforms</tt><a class="headerlink" href="#directive-%Platforms" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%Platforms {<em>name</em> <em>name</em> ...}
+</pre>
+<p>This directive is used to declare a set of platforms. Platforms (along with
+<a class="reference internal" href="#directive-%Feature"><tt class="xref docutils literal"><span class="pre">%Feature</span></tt></a> and <a class="reference internal" href="#directive-%Timeline"><tt class="xref docutils literal"><span class="pre">%Timeline</span></tt></a>) are used by the
+<a class="reference internal" href="#directive-%If"><tt class="xref docutils literal"><span class="pre">%If</span></tt></a> directive to control whether or not parts of a specification
+are processed or ignored.</p>
+<p>Platforms are mutually exclusive - only one platform can be enabled at a time.
+By default all platforms are disabled. The SIP <tt class="docutils literal"><span class="pre">-t</span></tt> command line option is
+used to enable a platform.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>%Platforms {WIN32_PLATFORM POSIX_PLATFORM MACOS_PLATFORM}
+
+%If (WIN32_PLATFORM)
+void undocumented();
+%End
+
+%If (POSIX_PLATFORM)
+void documented();
+%End</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%PostInitialisationCode">
+<tt class="descname">%PostInitialisationCode</tt><a class="headerlink" href="#directive-%PostInitialisationCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%PostInitialisationCode
+ <em>code</em>
+%End
+</pre>
+<p>This directive is used to specify handwritten code that is embedded in-line
+at the very end of the generated module initialisation code.</p>
+<p>The following variables are made available to the handwritten code:</p>
+<dl class="docutils">
+<dt>PyObject *sipModule</dt>
+<dd>This is the module object returned by <tt class="docutils literal"><span class="pre">Py_InitModule()</span></tt>.</dd>
+<dt>PyObject *sipModuleDict</dt>
+<dd>This is the module&#8217;s dictionary object returned by <tt class="docutils literal"><span class="pre">Py_ModuleGetDict()</span></tt>.</dd>
+</dl>
+<p>For example:</p>
+<div class="highlight-python"><pre>%PostInitialisationCode
+ // The code will be executed when the module is first imported and
+ // after all other initialisation has been completed.
+%End</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%PreInitialisationCode">
+<tt class="descname">%PreInitialisationCode</tt><a class="headerlink" href="#directive-%PreInitialisationCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%PreInitialisationCode
+ <em>code</em>
+%End
+</pre>
+<p>This directive is used to specify handwritten code that is embedded in-line
+at the very start of the generated module initialisation code.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>%PreInitialisationCode
+ // The code will be executed when the module is first imported and
+ // before other initialisation has been completed.
+%End</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%RaiseCode">
+<tt class="descname">%RaiseCode</tt><a class="headerlink" href="#directive-%RaiseCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%RaiseCode
+ <em>code</em>
+%End
+</pre>
+<p>This directive is used as part of the definition of an exception using the
+<a class="reference internal" href="#directive-%Exception"><tt class="xref docutils literal"><span class="pre">%Exception</span></tt></a> directive to specify handwritten code that raises a
+Python exception when a C++ exception has been caught. The code is embedded
+in-line as the body of a C++ <tt class="docutils literal"><span class="pre">catch</span> <span class="pre">()</span></tt> clause.</p>
+<p>The specified code must handle the Python Global Interpreter Lock (GIL) if
+necessary. The GIL must be acquired before any calls to the Python API and
+released after the last call as shown in this example fragment:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">SIP_BLOCK_THREADS</span>
+<span class="n">PyErr_SetNone</span><span class="p">(</span><span class="n">PyErr_Exception</span><span class="p">);</span>
+<span class="n">SIP_UNBLOCK_THREADS</span>
+</pre></div>
+</div>
+<p>Finally, the specified code must not include any <tt class="docutils literal"><span class="pre">return</span></tt> statements.</p>
+<p>The following variable is made available to the handwritten code:</p>
+<dl class="docutils">
+<dt><em>type</em> &amp;sipExceptionRef</dt>
+<dd>This is a reference to the caught C++ exception. The <em>type</em> of the
+reference is the same as the type defined in the <tt class="docutils literal"><span class="pre">throw</span> <span class="pre">()</span></tt> specifier.</dd>
+</dl>
+<p>See the <a class="reference internal" href="#directive-%Exception"><tt class="xref docutils literal"><span class="pre">%Exception</span></tt></a> directive for an example.</p>
+<dl class="directive">
+<dt id="directive-%SetCode">
+<tt class="descname">%SetCode</tt><a class="headerlink" href="#directive-%SetCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%SetCode
+ <em>code</em>
+%End
+</pre>
+<p>This directive is used after the declaration of a C++ class variable or C
+structure member to specify handwritten code to convert it from a Python
+object. It is usually used to handle types that SIP cannot deal with
+automatically.</p>
+<p>The following variables are made available to the handwritten code:</p>
+<dl class="docutils">
+<dt><em>type</em> *sipCpp</dt>
+<dd>This is a pointer to the structure or class instance. Its <em>type</em> is a
+pointer to the structure or class. It is not made available if the
+variable being wrapped is a static class variable.</dd>
+<dt>int sipErr</dt>
+<dd>If the conversion failed then the handwritten code should raise a Python
+exception and set this to a non-zero value. Its initial value will be
+automatically set to zero.</dd>
+<dt>PyObject *sipPy</dt>
+<dd>This is the Python object that the handwritten code should convert.</dd>
+<dt>PyObject *sipPyType</dt>
+<dd>If the variable being wrapped is a static class variable then this is the
+Python type object of the class from which the variable was referenced
+(<em>not</em> the class in which it is defined). It may be safely cast to a
+PyTypeObject * or a sipWrapperType *.</dd>
+</dl>
+<p>See the <a class="reference internal" href="#directive-%GetCode"><tt class="xref docutils literal"><span class="pre">%GetCode</span></tt></a> directive for an example.</p>
+<dl class="directive">
+<dt id="directive-%Timeline">
+<tt class="descname">%Timeline</tt><a class="headerlink" href="#directive-%Timeline" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%Timeline {<em>name</em> <em>name</em> ...}
+</pre>
+<p>This directive is used to declare a set of versions released over a period of
+time. Versions (along with <a class="reference internal" href="#directive-%Feature"><tt class="xref docutils literal"><span class="pre">%Feature</span></tt></a> and <a class="reference internal" href="#directive-%Platforms"><tt class="xref docutils literal"><span class="pre">%Platforms</span></tt></a>)
+are used by the <a class="reference internal" href="#directive-%If"><tt class="xref docutils literal"><span class="pre">%If</span></tt></a> directive to control whether or not parts of a
+specification are processed or ignored.</p>
+<p>Versions are mutually exclusive - only one version can be enabled at a time.
+By default all versions are disabled. The SIP <tt class="docutils literal"><span class="pre">-t</span></tt> command line option is
+used to enable a version.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>%Timeline {V1_0 V1_1 V2_0 V3_0}
+
+%If (V1_0 - V2_0)
+void foo();
+%End
+
+%If (V2_0 -)
+void foo(int = 0);
+%End</pre>
+</div>
+<p><a class="reference internal" href="#directive-%Timeline"><tt class="xref docutils literal"><span class="pre">%Timeline</span></tt></a> can be used any number of times in a module to allow
+multiple libraries to be wrapped in the same module.</p>
+<dl class="directive">
+<dt id="directive-%TypeCode">
+<tt class="descname">%TypeCode</tt><a class="headerlink" href="#directive-%TypeCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%TypeCode
+ <em>code</em>
+%End
+</pre>
+<p>This directive is used as part of the specification of a C structure or a C++
+class to specify handwritten code, typically the implementations of utility
+functions, that can be called by other handwritten code in the structure or
+class.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>class Klass
+{
+%TypeCode
+// Print an instance on stderr for debugging purposes.
+static void dump_klass(const Klass *k)
+{
+ fprintf(stderr,"Klass %s at %p\n", k-&gt;name(), k);
+}
+%End
+
+ // The rest of the class specification.
+
+};</pre>
+</div>
+<p>Because the scope of the code is normally within the generated file that
+implements the type, any utility functions would normally be declared
+<tt class="docutils literal"><span class="pre">static</span></tt>. However a naming convention should still be adopted to prevent
+clashes of function names within a module in case the SIP <tt class="docutils literal"><span class="pre">-j</span></tt> command line
+option is used.</p>
+<dl class="directive">
+<dt id="directive-%TypeHeaderCode">
+<tt class="descname">%TypeHeaderCode</tt><a class="headerlink" href="#directive-%TypeHeaderCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%TypeHeaderCode
+ <em>code</em>
+%End
+</pre>
+<p>This directive is used to specify handwritten code that defines the interface
+to a C or C++ type being wrapped, either a structure, a class, or a template.
+It is used within a class definition or a <a class="reference internal" href="#directive-%MappedType"><tt class="xref docutils literal"><span class="pre">%MappedType</span></tt></a> directive.</p>
+<p>Normally <em>code</em> will be a pre-processor <tt class="docutils literal"><span class="pre">#include</span></tt> statement.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>// Wrap the Klass class.
+class Klass
+{
+%TypeHeaderCode
+#include &lt;klass.h&gt;
+%End
+
+ // The rest of the class specification.
+};</pre>
+</div>
+<dl class="directive">
+<dt id="directive-%UnitCode">
+<tt class="descname">%UnitCode</tt><a class="headerlink" href="#directive-%UnitCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%UnitCode
+ <em>code</em>
+%End
+</pre>
+<p>This directive is used to specify handwritten code that it included at the very
+start of a generated compilation unit (ie. C or C++ source file). It is
+typically used to <tt class="docutils literal"><span class="pre">#include</span></tt> a C++ precompiled header file.</p>
+<dl class="directive">
+<dt id="directive-%VirtualCatcherCode">
+<tt class="descname">%VirtualCatcherCode</tt><a class="headerlink" href="#directive-%VirtualCatcherCode" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<pre class="literal-block">
+%VirtualCatcherCode
+ <em>code</em>
+%End
+</pre>
+<p>For most classes there are corresponding <a class="reference external" href="c_api.html#ref-derived-classes"><em>generated derived classes</em></a> that contain reimplementations of the class&#8217;s virtual
+methods. These methods (which SIP calls catchers) determine if there is a
+corresponding Python reimplementation and call it if so. If there is no Python
+reimplementation then the method in the original class is called instead.</p>
+<p>This directive is used to specify handwritten code that replaces the normally
+generated call to the Python reimplementation and the handling of any returned
+results. It is usually used to handle argument types and results that SIP
+cannot deal with automatically.</p>
+<p>This directive can also be used in the context of a class destructor to
+specify handwritten code that is embedded in-line in the internal derived
+class&#8217;s destructor.</p>
+<p>In the context of a method the Python Global Interpreter Lock (GIL) is
+automatically acquired before the specified code is executed and automatically
+released afterwards.</p>
+<p>In the context of a destructor the specified code must handle the GIL. The
+GIL must be acquired before any calls to the Python API and released after the
+last call as shown in this example fragment:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">SIP_BLOCK_THREADS</span>
+<span class="n">Py_DECREF</span><span class="p">(</span><span class="n">obj</span><span class="p">);</span>
+<span class="n">SIP_UNBLOCK_THREADS</span>
+</pre></div>
+</div>
+<p>The following variables are made available to the handwritten code in the
+context of a method:</p>
+<dl class="docutils">
+<dt><em>type</em> a0</dt>
+<dd>There is a variable for each argument of the C++ signature named <tt class="docutils literal"><span class="pre">a0</span></tt>,
+<tt class="docutils literal"><span class="pre">a1</span></tt>, etc. The <em>type</em> of the variable is the same as the type defined in
+the specification.</dd>
+<dt>int a0Key</dt>
+<dd>There is a variable for each argument of the C++ signature that has a type
+where it is important to ensure that the corresponding Python object is not
+garbage collected too soon. This only applies to output arguments that
+return <tt class="docutils literal"><span class="pre">'\0'</span></tt> terminated strings. The variable would normally be passed
+to <a title="sipParseResult" class="reference external" href="c_api.html#sipParseResult"><tt class="xref docutils literal"><span class="pre">sipParseResult()</span></tt></a> using either the <tt class="docutils literal"><span class="pre">A</span></tt> or <tt class="docutils literal"><span class="pre">B</span></tt> format
+characters.</dd>
+<dt>int sipIsErr</dt>
+<dd>The handwritten code should set this to a non-zero value, and raise an
+appropriate Python exception, if an error is detected.</dd>
+<dt>PyObject *sipMethod</dt>
+<dd>This object is the Python reimplementation of the virtual C++ method. It
+is normally passed to <a title="sipCallMethod" class="reference external" href="c_api.html#sipCallMethod"><tt class="xref docutils literal"><span class="pre">sipCallMethod()</span></tt></a>.</dd>
+<dt><em>type</em> sipRes</dt>
+<dd>The handwritten code should set this to the result to be returned. The
+<em>type</em> of the variable is the same as the type defined in the C++ signature
+in the specification.</dd>
+<dt>int sipResKey</dt>
+<dd>This variable is only made available if the result has a type where it is
+important to ensure that the corresponding Python object is not garbage
+collected too soon. This only applies to <tt class="docutils literal"><span class="pre">'\0'</span></tt> terminated strings. The
+variable would normally be passed to <a title="sipParseResult" class="reference external" href="c_api.html#sipParseResult"><tt class="xref docutils literal"><span class="pre">sipParseResult()</span></tt></a> using either
+the <tt class="docutils literal"><span class="pre">A</span></tt> or <tt class="docutils literal"><span class="pre">B</span></tt> format characters.</dd>
+<dt>sipSimpleWrapper *sipPySelf</dt>
+<dd>This variable is only made available if either the <tt class="docutils literal"><span class="pre">a0Key</span></tt> or
+<tt class="docutils literal"><span class="pre">sipResKey</span></tt> are made available. It defines the context within which keys
+are unique. The variable would normally be passed to
+<a title="sipParseResult" class="reference external" href="c_api.html#sipParseResult"><tt class="xref docutils literal"><span class="pre">sipParseResult()</span></tt></a> using the <tt class="docutils literal"><span class="pre">S</span></tt> format character.</dd>
+</dl>
+<p>No variables are made available in the context of a destructor.</p>
+<p>For example:</p>
+<div class="highlight-python"><pre>class Klass
+{
+public:
+ virtual int foo(SIP_PYTUPLE) [int (int *)];
+%MethodCode
+ // The C++ API takes a 2 element array of integers but passing a
+ // two element tuple is more Pythonic.
+
+ int iarr[2];
+
+ if (PyArg_ParseTuple(a0, "ii", &amp;iarr[0], &amp;iarr[1]))
+ {
+ Py_BEGIN_ALLOW_THREADS
+ sipRes = sipCpp-&gt;Klass::foo(iarr);
+ Py_END_ALLOW_THREADS
+ }
+ else
+ {
+ // PyArg_ParseTuple() will have raised the exception.
+ sipIsErr = 1;
+ }
+%End
+%VirtualCatcherCode
+ // Convert the 2 element array of integers to the two element
+ // tuple.
+
+ PyObject *result;
+
+ result = sipCallMethod(&amp;sipIsErr, sipMethod, "ii", a0[0], a0[1]);
+
+ if (result != NULL)
+ {
+ // Convert the result to the C++ type.
+ sipParseResult(&amp;sipIsErr, sipMethod, result, "i", &amp;sipRes);
+
+ Py_DECREF(result);
+ }
+%End
+};</pre>
+</div>
+</div>
+
+
+ </div>
+ </div>
+ </div>
+ <div class="sphinxsidebar">
+ <div class="sphinxsidebarwrapper">
+ <h4>Previous topic</h4>
+ <p class="topless"><a href="specification_files.html"
+ title="previous chapter">SIP Specification Files</a></p>
+ <h4>Next topic</h4>
+ <p class="topless"><a href="annotations.html"
+ title="next chapter">Annotations</a></p>
+ <div id="searchbox" style="display: none">
+ <h3>Quick search</h3>
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" size="18" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ <p class="searchtip" style="font-size: 90%">
+ Enter search terms or a module, class or function name.
+ </p>
+ </div>
+ <script type="text/javascript">$('#searchbox').show(0);</script>
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ >modules</a> |</li>
+ <li class="right" >
+ <a href="annotations.html" title="Annotations"
+ >next</a> |</li>
+ <li class="right" >
+ <a href="specification_files.html" title="SIP Specification Files"
+ >previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+ <div class="footer">
+ &copy; Copyright 2010 Riverbank Computing Limited.
+ Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.4.
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/distutils.html b/doc/html/distutils.html
new file mode 100644
index 0000000..9531ffd
--- /dev/null
+++ b/doc/html/distutils.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>Building Your Extension with distutils &mdash; SIP 4.10.5 Reference Guide</title>
+ <link rel="stylesheet" href="_static/default.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '#',
+ VERSION: '4.10.5',
+ COLLAPSE_MODINDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="top" title="SIP 4.10.5 Reference Guide" href="index.html" />
+ <link rel="next" title="Builtin Modules and Custom Interpreters" href="builtin.html" />
+ <link rel="prev" title="The Build System" href="build_system.html" />
+ </head>
+ <body>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ accesskey="M">modules</a> |</li>
+ <li class="right" >
+ <a href="builtin.html" title="Builtin Modules and Custom Interpreters"
+ accesskey="N">next</a> |</li>
+ <li class="right" >
+ <a href="build_system.html" title="The Build System"
+ accesskey="P">previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+ <div class="body">
+
+ <div class="section" id="building-your-extension-with-distutils">
+<span id="ref-distutils"></span><h1>Building Your Extension with distutils<a class="headerlink" href="#building-your-extension-with-distutils" title="Permalink to this headline">¶</a></h1>
+<p>To build the example in <a class="reference external" href="using.html#ref-simple-c-example"><em>A Simple C++ Example</em></a> using distutils, it is
+sufficient to create a standard <tt class="docutils literal"><span class="pre">setup.py</span></tt>, listing <tt class="docutils literal"><span class="pre">word.sip</span></tt> among the
+files to build, and hook-up SIP into distutils:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">distutils.core</span> <span class="kn">import</span> <span class="n">setup</span><span class="p">,</span> <span class="n">Extension</span>
+<span class="kn">import</span> <span class="nn">sipdistutils</span>
+
+<span class="n">setup</span><span class="p">(</span>
+ <span class="n">name</span> <span class="o">=</span> <span class="s">&#39;word&#39;</span><span class="p">,</span>
+ <span class="n">versione</span> <span class="o">=</span> <span class="s">&#39;1.0&#39;</span><span class="p">,</span>
+ <span class="n">ext_modules</span><span class="o">=</span><span class="p">[</span>
+ <span class="n">Extension</span><span class="p">(</span><span class="s">&quot;word&quot;</span><span class="p">,</span> <span class="p">[</span><span class="s">&quot;word.sip&quot;</span><span class="p">,</span> <span class="s">&quot;word.cpp&quot;</span><span class="p">]),</span>
+ <span class="p">],</span>
+
+ <span class="n">cmdclass</span> <span class="o">=</span> <span class="p">{</span><span class="s">&#39;build_ext&#39;</span><span class="p">:</span> <span class="n">sipdistutils</span><span class="o">.</span><span class="n">build_ext</span><span class="p">}</span>
+<span class="p">)</span>
+</pre></div>
+</div>
+<p>As we can see, the above is a normal distutils setup script, with just a
+special line which is needed so that SIP can see and process <tt class="docutils literal"><span class="pre">word.sip</span></tt>.
+Then, running <tt class="docutils literal"><span class="pre">setup.py</span> <span class="pre">build</span></tt> will build our extension module.</p>
+<p>If you want to use any of sip&#8217;s command-line options described in
+<a class="reference external" href="command_line.html#ref-command-line"><em>The SIP Command Line</em></a>, there is a new option available for the
+<tt class="docutils literal"><span class="pre">build_ext</span></tt> command in distutils: <tt class="docutils literal"><span class="pre">--sip-opts</span></tt>. So you can either invoke
+distutils as follows:</p>
+<div class="highlight-python"><pre>$ python setup.py build_ext --sip-opts="-e -g" build</pre>
+</div>
+<p>or you can leverage distutils&#8217; config file support by creating a <tt class="docutils literal"><span class="pre">setup.cfg</span></tt>
+file in the supported system or local paths (eg: in the same directory of
+<tt class="docutils literal"><span class="pre">setup.py</span></tt>) with these contents:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="p">[</span><span class="n">build_ext</span><span class="p">]</span>
+<span class="n">sip</span><span class="o">-</span><span class="n">opts</span> <span class="o">=</span> <span class="o">-</span><span class="n">e</span> <span class="o">-</span><span class="n">g</span>
+</pre></div>
+</div>
+<p>and then run <tt class="docutils literal"><span class="pre">setup.py</span> <span class="pre">build</span></tt> as usual.</p>
+</div>
+
+
+ </div>
+ </div>
+ </div>
+ <div class="sphinxsidebar">
+ <div class="sphinxsidebarwrapper">
+ <h4>Previous topic</h4>
+ <p class="topless"><a href="build_system.html"
+ title="previous chapter">The Build System</a></p>
+ <h4>Next topic</h4>
+ <p class="topless"><a href="builtin.html"
+ title="next chapter">Builtin Modules and Custom Interpreters</a></p>
+ <div id="searchbox" style="display: none">
+ <h3>Quick search</h3>
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" size="18" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ <p class="searchtip" style="font-size: 90%">
+ Enter search terms or a module, class or function name.
+ </p>
+ </div>
+ <script type="text/javascript">$('#searchbox').show(0);</script>
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ >modules</a> |</li>
+ <li class="right" >
+ <a href="builtin.html" title="Builtin Modules and Custom Interpreters"
+ >next</a> |</li>
+ <li class="right" >
+ <a href="build_system.html" title="The Build System"
+ >previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+ <div class="footer">
+ &copy; Copyright 2010 Riverbank Computing Limited.
+ Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.4.
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/embedding.html b/doc/html/embedding.html
new file mode 100644
index 0000000..1a61175
--- /dev/null
+++ b/doc/html/embedding.html
@@ -0,0 +1,162 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>Using the C API when Embedding &mdash; SIP 4.10.5 Reference Guide</title>
+ <link rel="stylesheet" href="_static/default.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '#',
+ VERSION: '4.10.5',
+ COLLAPSE_MODINDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="top" title="SIP 4.10.5 Reference Guide" href="index.html" />
+ <link rel="next" title="Python API for Applications" href="python_api.html" />
+ <link rel="prev" title="C API for Handwritten Code" href="c_api.html" />
+ </head>
+ <body>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ accesskey="M">modules</a> |</li>
+ <li class="right" >
+ <a href="python_api.html" title="Python API for Applications"
+ accesskey="N">next</a> |</li>
+ <li class="right" >
+ <a href="c_api.html" title="C API for Handwritten Code"
+ accesskey="P">previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+ <div class="body">
+
+ <div class="section" id="using-the-c-api-when-embedding">
+<h1>Using the C API when Embedding<a class="headerlink" href="#using-the-c-api-when-embedding" title="Permalink to this headline">¶</a></h1>
+<p>The <a class="reference external" href="c_api.html#ref-c-api"><em>C API</em></a> is intended to be called from handwritten code in
+SIP generated modules. However it is also often necessary to call it from C or
+C++ applications that embed the Python interpreter and need to pass C or C++
+instances between the application and the interpreter.</p>
+<p>The API is exported by the SIP module as a <tt class="docutils literal"><span class="pre">sipAPIDef</span></tt> data structure
+containing a set of function pointers. The data structure is defined in the
+SIP header file <tt class="docutils literal"><span class="pre">sip.h</span></tt>. The data structure is wrapped as a Python
+<tt class="docutils literal"><span class="pre">PyCObject</span></tt> object and is referenced by the name <tt class="docutils literal"><span class="pre">_C_API</span></tt> in the SIP
+module dictionary.</p>
+<p>Each member of the data structure is a pointer to one of the functions of the
+SIP API. The name of the member can be derived from the function name by
+replacing the <tt class="docutils literal"><span class="pre">sip</span></tt> prefix with <tt class="docutils literal"><span class="pre">api</span></tt> and converting each word in the
+name to lower case and preceding it with an underscore. For example:</p>
+<blockquote>
+<p><tt class="docutils literal"><span class="pre">sipExportSymbol</span></tt> becomes <tt class="docutils literal"><span class="pre">api_export_symbol</span></tt></p>
+<p><tt class="docutils literal"><span class="pre">sipWrapperCheck</span></tt> becomes <tt class="docutils literal"><span class="pre">api_wrapper_check</span></tt></p>
+</blockquote>
+<p>Note that the type objects that SIP generates for a wrapped module (see
+<a class="reference external" href="c_api.html#ref-type-structures"><em>Generated Type Structures</em></a>, <a class="reference external" href="c_api.html#ref-enum-type-objects"><em>Generated Named Enum Type Objects</em></a> and
+<a class="reference external" href="c_api.html#ref-exception-objects"><em>Generated Exception Objects</em></a>) cannot be refered to directly and must be
+obtained using the <a title="sipFindType" class="reference external" href="c_api.html#sipFindType"><tt class="xref docutils literal"><span class="pre">sipFindType()</span></tt></a> function. Of course, the
+corresponding modules must already have been imported into the interpreter.</p>
+<p>The following code fragment shows how to get a pointer to the <tt class="docutils literal"><span class="pre">sipAPIDef</span></tt>
+data structure:</p>
+<div class="highlight-python"><pre>#include &lt;sip.h&gt;
+
+const sipAPIDef *get_sip_api()
+{
+ PyObject *sip_module;
+ PyObject *sip_module_dict;
+ PyObject *c_api;
+
+ /* Import the SIP module. */
+ sip_module = PyImport_ImportModule("sip");
+
+ if (sip_module == NULL)
+ return NULL;
+
+ /* Get the module's dictionary. */
+ sip_module_dict = PyModule_GetDict(sip_module);
+
+ /* Get the "_C_API" attribute. */
+ c_api = PyDict_GetItemString(sip_module_dict, "_C_API");
+
+ if (c_api == NULL)
+ return NULL;
+
+ /* Sanity check that it is the right type. */
+ if (!PyCObject_Check(c_api))
+ return NULL;
+
+ /* Get the actual pointer from the object. */
+ return (const sipAPIDef *)PyCObject_AsVoidPtr(c_api);
+}</pre>
+</div>
+</div>
+
+
+ </div>
+ </div>
+ </div>
+ <div class="sphinxsidebar">
+ <div class="sphinxsidebarwrapper">
+ <h4>Previous topic</h4>
+ <p class="topless"><a href="c_api.html"
+ title="previous chapter">C API for Handwritten Code</a></p>
+ <h4>Next topic</h4>
+ <p class="topless"><a href="python_api.html"
+ title="next chapter">Python API for Applications</a></p>
+ <div id="searchbox" style="display: none">
+ <h3>Quick search</h3>
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" size="18" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ <p class="searchtip" style="font-size: 90%">
+ Enter search terms or a module, class or function name.
+ </p>
+ </div>
+ <script type="text/javascript">$('#searchbox').show(0);</script>
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ >modules</a> |</li>
+ <li class="right" >
+ <a href="python_api.html" title="Python API for Applications"
+ >next</a> |</li>
+ <li class="right" >
+ <a href="c_api.html" title="C API for Handwritten Code"
+ >previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+ <div class="footer">
+ &copy; Copyright 2010 Riverbank Computing Limited.
+ Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.4.
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/genindex.html b/doc/html/genindex.html
new file mode 100644
index 0000000..8b714a6
--- /dev/null
+++ b/doc/html/genindex.html
@@ -0,0 +1,784 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>Index &mdash; SIP 4.10.5 Reference Guide</title>
+ <link rel="stylesheet" href="_static/default.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '#',
+ VERSION: '4.10.5',
+ COLLAPSE_MODINDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="top" title="SIP 4.10.5 Reference Guide" href="index.html" />
+ </head>
+ <body>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="#" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ accesskey="M">modules</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+ <div class="body">
+
+
+ <h1 id="index">Index</h1>
+
+ <a href="#Symbols"><strong>Symbols</strong></a> | <a href="#_"><strong>_</strong></a> | <a href="#A"><strong>A</strong></a> | <a href="#B"><strong>B</strong></a> | <a href="#C"><strong>C</strong></a> | <a href="#D"><strong>D</strong></a> | <a href="#E"><strong>E</strong></a> | <a href="#F"><strong>F</strong></a> | <a href="#G"><strong>G</strong></a> | <a href="#H"><strong>H</strong></a> | <a href="#I"><strong>I</strong></a> | <a href="#K"><strong>K</strong></a> | <a href="#L"><strong>L</strong></a> | <a href="#M"><strong>M</strong></a> | <a href="#N"><strong>N</strong></a> | <a href="#O"><strong>O</strong></a> | <a href="#P"><strong>P</strong></a> | <a href="#R"><strong>R</strong></a> | <a href="#S"><strong>S</strong></a> | <a href="#T"><strong>T</strong></a> | <a href="#U"><strong>U</strong></a> | <a href="#V"><strong>V</strong></a> | <a href="#W"><strong>W</strong></a>
+
+ <hr />
+
+
+<h2 id="Symbols">Symbols</h2>
+<table width="100%" class="indextable"><tr><td width="33%" valign="top">
+<dl>
+
+<dt><a href="directives.html#directive-%AccessCode">%AccessCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%API">%API (directive)</a></dt>
+<dt><a href="directives.html#directive-%BIGetBufferCode">%BIGetBufferCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%BIGetCharBufferCode">%BIGetCharBufferCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%BIGetReadBufferCode">%BIGetReadBufferCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%BIGetSegCountCode">%BIGetSegCountCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%BIGetWriteBufferCode">%BIGetWriteBufferCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%BIReleaseBufferCode">%BIReleaseBufferCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%CModule">%CModule (directive)</a></dt>
+<dt><a href="directives.html#directive-%CompositeModule">%CompositeModule (directive)</a></dt>
+<dt><a href="directives.html#directive-%ConsolidatedModule">%ConsolidatedModule (directive)</a></dt>
+<dt><a href="directives.html#directive-%ConvertFromTypeCode">%ConvertFromTypeCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%ConvertToSubClassCode">%ConvertToSubClassCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%ConvertToTypeCode">%ConvertToTypeCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%Copying">%Copying (directive)</a></dt>
+<dt><a href="directives.html#directive-%DefaultEncoding">%DefaultEncoding (directive)</a></dt>
+<dt><a href="directives.html#directive-%DefaultMetatype">%DefaultMetatype (directive)</a></dt>
+<dt><a href="directives.html#directive-%DefaultSupertype">%DefaultSupertype (directive)</a></dt>
+<dt><a href="directives.html#directive-%Doc">%Doc (directive)</a></dt>
+<dt><a href="directives.html#directive-%Docstring">%Docstring (directive)</a></dt>
+<dt><a href="directives.html#directive-%End">%End (directive)</a></dt>
+<dt><a href="directives.html#directive-%Exception">%Exception (directive)</a></dt>
+<dt><a href="directives.html#directive-%ExportedDoc">%ExportedDoc (directive)</a></dt>
+<dt><a href="directives.html#directive-%ExportedHeaderCode">%ExportedHeaderCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%Feature">%Feature (directive)</a></dt>
+<dt><a href="directives.html#directive-%GCClearCode">%GCClearCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%GCTraverseCode">%GCTraverseCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%GetCode">%GetCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%If">%If (directive)</a></dt>
+<dt><a href="directives.html#directive-%Import">%Import (directive)</a></dt>
+<dt><a href="directives.html#directive-%Include">%Include (directive)</a></dt>
+<dt><a href="directives.html#directive-%InitialisationCode">%InitialisationCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%License">%License (directive)</a></dt>
+<dt><a href="directives.html#directive-%MappedType">%MappedType (directive)</a></dt>
+<dt><a href="directives.html#directive-%MethodCode">%MethodCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%Module">%Module (directive)</a></dt>
+<dt><a href="directives.html#directive-%ModuleCode">%ModuleCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%ModuleHeaderCode">%ModuleHeaderCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%OptionalInclude">%OptionalInclude (directive)</a></dt>
+<dt><a href="directives.html#directive-%PickleCode">%PickleCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%Platforms">%Platforms (directive)</a></dt>
+<dt><a href="directives.html#directive-%PostInitialisationCode">%PostInitialisationCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%PreInitialisationCode">%PreInitialisationCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%RaiseCode">%RaiseCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%SetCode">%SetCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%Timeline">%Timeline (directive)</a></dt>
+<dt><a href="directives.html#directive-%TypeCode">%TypeCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%TypeHeaderCode">%TypeHeaderCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%UnitCode">%UnitCode (directive)</a></dt>
+<dt><a href="directives.html#directive-%VirtualCatcherCode">%VirtualCatcherCode (directive)</a></dt>
+<dt>--arch &lt;ARCH&gt;</dt>
+ <dd><dl>
+ <dt><a href="installation.html#cmdoption-configure.py--arch">configure.py command line option</a></dt>
+ </dl></dd>
+<dt>--show-build-macros</dt>
+ <dd><dl>
+ <dt><a href="installation.html#cmdoption-configure.py--show-build-macros">configure.py command line option</a></dt>
+ </dl></dd>
+<dt>--show-platforms</dt>
+ <dd><dl>
+ <dt><a href="installation.html#cmdoption-configure.py--show-platforms">configure.py command line option</a></dt>
+ </dl></dd>
+<dt>--version</dt>
+ <dd><dl>
+ <dt><a href="installation.html#cmdoption-configure.py--version">configure.py command line option</a></dt>
+ </dl></dd>
+<dt>-a &lt;FILE&gt;</dt>
+ <dd><dl>
+ <dt><a href="command_line.html#cmdoption-sip-a">sip command line option</a></dt>
+ </dl></dd></dl></td><td width="33%" valign="top"><dl>
+<dt>-b &lt;DIR&gt;, --bindir &lt;DIR&gt;</dt>
+ <dd><dl>
+ <dt><a href="installation.html#cmdoption-configure.py-b">configure.py command line option</a></dt>
+ </dl></dd>
+<dt>-b &lt;FILE&gt;</dt>
+ <dd><dl>
+ <dt><a href="command_line.html#cmdoption-sip-b">sip command line option</a></dt>
+ </dl></dd>
+<dt>-c &lt;DIR&gt;</dt>
+ <dd><dl>
+ <dt><a href="command_line.html#cmdoption-sip-c">sip command line option</a></dt>
+ </dl></dd>
+<dt>-d &lt;DIR&gt;, --destdir &lt;DIR&gt;</dt>
+ <dd><dl>
+ <dt><a href="installation.html#cmdoption-configure.py-d">configure.py command line option</a></dt>
+ </dl></dd>
+<dt>-d &lt;FILE&gt;</dt>
+ <dd><dl>
+ <dt><a href="command_line.html#cmdoption-sip-d">sip command line option</a></dt>
+ </dl></dd>
+<dt>-e</dt>
+ <dd><dl>
+ <dt><a href="command_line.html#cmdoption-sip-e">sip command line option</a></dt>
+ </dl></dd>
+<dt>-e &lt;DIR&gt;, --incdir &lt;DIR&gt;</dt>
+ <dd><dl>
+ <dt><a href="installation.html#cmdoption-configure.py-e">configure.py command line option</a></dt>
+ </dl></dd>
+<dt>-g</dt>
+ <dd><dl>
+ <dt><a href="command_line.html#cmdoption-sip-g">sip command line option</a></dt>
+ </dl></dd>
+<dt>-h</dt>
+ <dd><dl>
+ <dt><a href="command_line.html#cmdoption-sip-h">sip command line option</a></dt>
+ </dl></dd>
+<dt>-h, --help</dt>
+ <dd><dl>
+ <dt><a href="installation.html#cmdoption-configure.py-h">configure.py command line option</a></dt>
+ </dl></dd>
+<dt>-I &lt;DIR&gt;</dt>
+ <dd><dl>
+ <dt><a href="command_line.html#cmdoption-sip-I">sip command line option</a></dt>
+ </dl></dd>
+<dt>-j &lt;NUMBER&gt;</dt>
+ <dd><dl>
+ <dt><a href="command_line.html#cmdoption-sip-j">sip command line option</a></dt>
+ </dl></dd>
+<dt>-k</dt>
+ <dd><dl>
+ <dt><a href="command_line.html#cmdoption-sip-k">sip command line option</a></dt>
+ </dl></dd>
+<dt>-k, --static</dt>
+ <dd><dl>
+ <dt><a href="installation.html#cmdoption-configure.py-k">configure.py command line option</a></dt>
+ </dl></dd>
+<dt>-n, --universal</dt>
+ <dd><dl>
+ <dt><a href="installation.html#cmdoption-configure.py-n">configure.py command line option</a></dt>
+ </dl></dd>
+<dt>-o</dt>
+ <dd><dl>
+ <dt><a href="command_line.html#cmdoption-sip-o">sip command line option</a></dt>
+ </dl></dd>
+<dt>-P</dt>
+ <dd><dl>
+ <dt><a href="command_line.html#cmdoption-sip-P">sip command line option</a></dt>
+ </dl></dd>
+<dt>-p &lt;MODULE&gt;</dt>
+ <dd><dl>
+ <dt><a href="command_line.html#cmdoption-sip-p">sip command line option</a></dt>
+ </dl></dd>
+<dt>-p &lt;PLATFORM&gt;, --platform &lt;PLATFORM&gt;</dt>
+ <dd><dl>
+ <dt><a href="installation.html#cmdoption-configure.py-p">configure.py command line option</a></dt>
+ </dl></dd>
+<dt>-r</dt>
+ <dd><dl>
+ <dt><a href="command_line.html#cmdoption-sip-r">sip command line option</a></dt>
+ </dl></dd>
+<dt>-s &lt;SDK&gt;, --sdk &lt;SDK&gt;</dt>
+ <dd><dl>
+ <dt><a href="installation.html#cmdoption-configure.py-s">configure.py command line option</a></dt>
+ </dl></dd>
+<dt>-s &lt;SUFFIX&gt;</dt>
+ <dd><dl>
+ <dt><a href="command_line.html#cmdoption-sip-s">sip command line option</a></dt>
+ </dl></dd>
+<dt>-t &lt;TAG&gt;</dt>
+ <dd><dl>
+ <dt><a href="command_line.html#cmdoption-sip-t">sip command line option</a></dt>
+ </dl></dd>
+<dt>-u, --debug</dt>
+ <dd><dl>
+ <dt><a href="installation.html#cmdoption-configure.py-u">configure.py command line option</a></dt>
+ </dl></dd>
+<dt>-V</dt>
+ <dd><dl>
+ <dt><a href="command_line.html#cmdoption-sip-V">sip command line option</a></dt>
+ </dl></dd>
+<dt>-v &lt;DIR&gt;, --sipdir &lt;DIR&gt;</dt>
+ <dd><dl>
+ <dt><a href="installation.html#cmdoption-configure.py-v">configure.py command line option</a></dt>
+ </dl></dd>
+<dt>-w</dt>
+ <dd><dl>
+ <dt><a href="command_line.html#cmdoption-sip-w">sip command line option</a></dt>
+ </dl></dd>
+<dt>-x &lt;FEATURE&gt;</dt>
+ <dd><dl>
+ <dt><a href="command_line.html#cmdoption-sip-x">sip command line option</a></dt>
+ </dl></dd>
+<dt>-z &lt;FILE&gt;</dt>
+ <dd><dl>
+ <dt><a href="command_line.html#cmdoption-sip-z">sip command line option</a></dt>
+ </dl></dd>
+</dl></td></tr></table>
+
+<h2 id="_">_</h2>
+<table width="100%" class="indextable"><tr><td width="33%" valign="top">
+<dl>
+
+<dt><a href="python_api.html#sip.voidptr.__hex__">__hex__() (sip.voidptr method)</a></dt>
+<dt><a href="python_api.html#sip.voidptr.__init__">__init__() (sip.voidptr method)</a></dt>
+ <dd><dl>
+ <dt><a href="build_system.html#sipconfig.Configuration.__init__">(sipconfig.Configuration method)</a></dt>
+ <dt><a href="build_system.html#sipconfig.Makefile.__init__">(sipconfig.Makefile method)</a></dt>
+ <dt><a href="build_system.html#sipconfig.ModuleMakefile.__init__">(sipconfig.ModuleMakefile method)</a></dt>
+ <dt><a href="build_system.html#sipconfig.ParentMakefile.__init__">(sipconfig.ParentMakefile method)</a></dt>
+ <dt><a href="build_system.html#sipconfig.ProgramMakefile.__init__">(sipconfig.ProgramMakefile method)</a></dt>
+ <dt><a href="build_system.html#sipconfig.PythonModuleMakefile.__init__">(sipconfig.PythonModuleMakefile method)</a></dt>
+ <dt><a href="build_system.html#sipconfig.SIPModuleMakefile.__init__">(sipconfig.SIPModuleMakefile method)</a></dt>
+ </dl></dd></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="python_api.html#sip.voidptr.__int__">__int__() (sip.voidptr method)</a></dt>
+<dt><a href="annotations.html#fanno-__len__">__len__ (function annotation)</a></dt>
+</dl></td></tr></table>
+
+<h2 id="A">A</h2>
+<table width="100%" class="indextable"><tr><td width="33%" valign="top">
+<dl>
+
+<dt><a href="annotations.html#canno-Abstract">Abstract (class annotation)</a></dt>
+<dt><a href="annotations.html#aanno-AllowNone">AllowNone (argument annotation)</a></dt>
+ <dd><dl>
+ <dt><a href="annotations.html#canno-AllowNone">(class annotation)</a></dt>
+ <dt><a href="annotations.html#manno-AllowNone">(mapped type annotation)</a></dt>
+ </dl></dd>
+<dt><a href="annotations.html#canno-API">API (class annotation)</a></dt>
+ <dd><dl>
+ <dt><a href="annotations.html#fanno-API">(function annotation)</a></dt>
+ <dt><a href="annotations.html#manno-API">(mapped type annotation)</a></dt>
+ </dl></dd>
+<dt><a href="build_system.html#sipconfig.Configuration.arch">arch (sipconfig.Configuration attribute)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="annotations.html#aanno-Array">Array (argument annotation)</a></dt>
+<dt><a href="annotations.html#aanno-ArraySize">ArraySize (argument annotation)</a></dt>
+<dt><a href="python_api.html#sip.voidptr.ascapsule">ascapsule() (sip.voidptr method)</a></dt>
+<dt><a href="python_api.html#sip.voidptr.ascobject">ascobject() (sip.voidptr method)</a></dt>
+<dt><a href="python_api.html#sip.voidptr.asstring">asstring() (sip.voidptr method)</a></dt>
+<dt><a href="annotations.html#fanno-AutoGen">AutoGen (function annotation)</a></dt>
+</dl></td></tr></table>
+
+<h2 id="B">B</h2>
+<table width="100%" class="indextable"><tr><td width="33%" valign="top">
+<dl>
+
+<dt><a href="build_system.html#sipconfig.ProgramMakefile.build_command">build_command() (sipconfig.ProgramMakefile method)</a></dt>
+<dt><a href="build_system.html#sipconfig.Configuration.build_macros">build_macros() (sipconfig.Configuration method)</a></dt></dl></td><td width="33%" valign="top"><dl>
+</dl></td></tr></table>
+
+<h2 id="C">C</h2>
+<table width="100%" class="indextable"><tr><td width="33%" valign="top">
+<dl>
+
+<dt><a href="python_api.html#sip.cast">cast() (in module sip)</a></dt>
+<dt><a href="build_system.html#sipconfig.Makefile.chkdir">chkdir (sipconfig.Makefile attribute)</a></dt>
+<dt><a href="build_system.html#sipconfig.Makefile.clean_build_file_objects">clean_build_file_objects() (sipconfig.Makefile method)</a></dt>
+<dt><a href="build_system.html#sipconfig.Makefile.config">config (sipconfig.Makefile attribute)</a></dt>
+<dt><a href="build_system.html#sipconfig.Configuration">Configuration (class in sipconfig)</a></dt>
+<dt>configure.py command line option</dt>
+ <dd><dl>
+ <dt><a href="installation.html#cmdoption-configure.py--arch">--arch &lt;ARCH&gt;</a></dt>
+ <dt><a href="installation.html#cmdoption-configure.py--show-build-macros">--show-build-macros</a></dt>
+ <dt><a href="installation.html#cmdoption-configure.py--show-platforms">--show-platforms</a></dt>
+ <dt><a href="installation.html#cmdoption-configure.py--version">--version</a></dt>
+ <dt><a href="installation.html#cmdoption-configure.py-b">-b &lt;DIR&gt;, --bindir &lt;DIR&gt;</a></dt>
+ <dt><a href="installation.html#cmdoption-configure.py-d">-d &lt;DIR&gt;, --destdir &lt;DIR&gt;</a></dt>
+ <dt><a href="installation.html#cmdoption-configure.py-e">-e &lt;DIR&gt;, --incdir &lt;DIR&gt;</a></dt>
+ <dt><a href="installation.html#cmdoption-configure.py-h">-h, --help</a></dt>
+ <dt><a href="installation.html#cmdoption-configure.py-k">-k, --static</a></dt>
+ <dt><a href="installation.html#cmdoption-configure.py-n">-n, --universal</a></dt>
+ <dt><a href="installation.html#cmdoption-configure.py-p">-p &lt;PLATFORM&gt;, --platform &lt;PLATFORM&gt;</a></dt>
+ <dt><a href="installation.html#cmdoption-configure.py-s">-s &lt;SDK&gt;, --sdk &lt;SDK&gt;</a></dt>
+ <dt><a href="installation.html#cmdoption-configure.py-u">-u, --debug</a></dt>
+ <dt><a href="installation.html#cmdoption-configure.py-v">-v &lt;DIR&gt;, --sipdir &lt;DIR&gt;</a></dt>
+ </dl></dd></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="build_system.html#sipconfig.Makefile.console">console (sipconfig.Makefile attribute)</a></dt>
+<dt><a href="annotations.html#aanno-Constrained">Constrained (argument annotation)</a></dt>
+<dt><a href="build_system.html#sipconfig.Makefile.copy">copy (sipconfig.Makefile attribute)</a></dt>
+<dt><a href="build_system.html#sipconfig.create_config_module">create_config_module() (in module sipconfig)</a></dt>
+<dt><a href="build_system.html#sipconfig.create_content">create_content() (in module sipconfig)</a></dt>
+<dt><a href="build_system.html#sipconfig.create_wrapper">create_wrapper() (in module sipconfig)</a></dt>
+</dl></td></tr></table>
+
+<h2 id="D">D</h2>
+<table width="100%" class="indextable"><tr><td width="33%" valign="top">
+<dl>
+
+<dt><a href="annotations.html#dd_isderived">dd_isderived (C member)</a></dt>
+<dt><a href="annotations.html#dd_name">dd_name (C member)</a></dt>
+<dt><a href="annotations.html#dd_next">dd_next (C member)</a></dt>
+<dt><a href="annotations.html#dd_ptr">dd_ptr (C member)</a></dt>
+<dt><a href="annotations.html#xanno-Default">Default (exception annotation)</a></dt>
+ <dd><dl>
+ <dt><a href="annotations.html#fanno-Default">(function annotation)</a></dt>
+ </dl></dd>
+<dt><a href="build_system.html#sipconfig.Configuration.default_bin_dir">default_bin_dir (sipconfig.Configuration attribute)</a></dt>
+<dt><a href="build_system.html#sipconfig.Configuration.default_mod_dir">default_mod_dir (sipconfig.Configuration attribute)</a></dt>
+<dt><a href="build_system.html#sipconfig.Configuration.default_sip_dir">default_sip_dir (sipconfig.Configuration attribute)</a></dt>
+<dt><a href="annotations.html#canno-DelayDtor">DelayDtor (class annotation)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="python_api.html#sip.delete">delete() (in module sip)</a></dt>
+<dt><a href="annotations.html#canno-Deprecated">Deprecated (class annotation)</a></dt>
+ <dd><dl>
+ <dt><a href="annotations.html#fanno-Deprecated">(function annotation)</a></dt>
+ </dl></dd>
+<dt><a href="annotations.html#aanno-DocType">DocType (argument annotation)</a></dt>
+ <dd><dl>
+ <dt><a href="annotations.html#fanno-DocType">(function annotation)</a></dt>
+ <dt><a href="annotations.html#manno-DocType">(mapped type annotation)</a></dt>
+ <dt><a href="annotations.html#vanno-DocType">(variable annotation)</a></dt>
+ </dl></dd>
+<dt><a href="annotations.html#aanno-DocValue">DocValue (argument annotation)</a></dt>
+<dt><a href="python_api.html#sip.dump">dump() (in module sip)</a></dt>
+</dl></td></tr></table>
+
+<h2 id="E">E</h2>
+<table width="100%" class="indextable"><tr><td width="33%" valign="top">
+<dl>
+
+<dt><a href="annotations.html#aanno-Encoding">Encoding (argument annotation)</a></dt>
+<dt><a href="build_system.html#sipconfig.error">error() (in module sipconfig)</a></dt>
+<dt><a href="annotations.html#canno-External">External (class annotation)</a></dt>
+<dt><a href="build_system.html#sipconfig.Makefile.extra_cflags">extra_cflags (sipconfig.Makefile attribute)</a></dt>
+<dt><a href="build_system.html#sipconfig.Makefile.extra_cxxflags">extra_cxxflags (sipconfig.Makefile attribute)</a></dt>
+<dt><a href="build_system.html#sipconfig.Makefile.extra_defines">extra_defines (sipconfig.Makefile attribute)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="build_system.html#sipconfig.Makefile.extra_include_dirs">extra_include_dirs (sipconfig.Makefile attribute)</a></dt>
+<dt><a href="build_system.html#sipconfig.Makefile.extra_lflags">extra_lflags (sipconfig.Makefile attribute)</a></dt>
+<dt><a href="build_system.html#sipconfig.Makefile.extra_lib_dirs">extra_lib_dirs (sipconfig.Makefile attribute)</a></dt>
+<dt><a href="build_system.html#sipconfig.Makefile.extra_libs">extra_libs (sipconfig.Makefile attribute)</a></dt>
+</dl></td></tr></table>
+
+<h2 id="F">F</h2>
+<table width="100%" class="indextable"><tr><td width="33%" valign="top">
+<dl>
+
+<dt><a href="annotations.html#fanno-Factory">Factory (function annotation)</a></dt>
+<dt><a href="build_system.html#sipconfig.Makefile.finalise">finalise() (sipconfig.Makefile method)</a></dt>
+ <dd><dl>
+ <dt><a href="build_system.html#sipconfig.ModuleMakefile.finalise">(sipconfig.ModuleMakefile method)</a></dt>
+ <dt><a href="build_system.html#sipconfig.ProgramMakefile.finalise">(sipconfig.ProgramMakefile method)</a></dt>
+ <dt><a href="build_system.html#sipconfig.SIPModuleMakefile.finalise">(sipconfig.SIPModuleMakefile method)</a></dt>
+ </dl></dd></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="build_system.html#sipconfig.format">format() (in module sipconfig)</a></dt>
+</dl></td></tr></table>
+
+<h2 id="G">G</h2>
+<table width="100%" class="indextable"><tr><td width="33%" valign="top">
+<dl>
+
+<dt><a href="build_system.html#sipconfig.Makefile.generate">generate() (sipconfig.Makefile method)</a></dt>
+<dt><a href="build_system.html#sipconfig.Makefile.generate_macros_and_rules">generate_macros_and_rules() (sipconfig.Makefile method)</a></dt>
+ <dd><dl>
+ <dt><a href="build_system.html#sipconfig.ModuleMakefile.generate_macros_and_rules">(sipconfig.ModuleMakefile method)</a></dt>
+ <dt><a href="build_system.html#sipconfig.ParentMakefile.generate_macros_and_rules">(sipconfig.ParentMakefile method)</a></dt>
+ <dt><a href="build_system.html#sipconfig.ProgramMakefile.generate_macros_and_rules">(sipconfig.ProgramMakefile method)</a></dt>
+ <dt><a href="build_system.html#sipconfig.PythonModuleMakefile.generate_macros_and_rules">(sipconfig.PythonModuleMakefile method)</a></dt>
+ </dl></dd>
+<dt><a href="build_system.html#sipconfig.Makefile.generate_target_clean">generate_target_clean() (sipconfig.Makefile method)</a></dt>
+ <dd><dl>
+ <dt><a href="build_system.html#sipconfig.ModuleMakefile.generate_target_clean">(sipconfig.ModuleMakefile method)</a></dt>
+ <dt><a href="build_system.html#sipconfig.ParentMakefile.generate_target_clean">(sipconfig.ParentMakefile method)</a></dt>
+ <dt><a href="build_system.html#sipconfig.ProgramMakefile.generate_target_clean">(sipconfig.ProgramMakefile method)</a></dt>
+ </dl></dd>
+<dt><a href="build_system.html#sipconfig.Makefile.generate_target_default">generate_target_default() (sipconfig.Makefile method)</a></dt>
+ <dd><dl>
+ <dt><a href="build_system.html#sipconfig.ModuleMakefile.generate_target_default">(sipconfig.ModuleMakefile method)</a></dt>
+ <dt><a href="build_system.html#sipconfig.ParentMakefile.generate_target_default">(sipconfig.ParentMakefile method)</a></dt>
+ <dt><a href="build_system.html#sipconfig.ProgramMakefile.generate_target_default">(sipconfig.ProgramMakefile method)</a></dt>
+ </dl></dd></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="build_system.html#sipconfig.Makefile.generate_target_install">generate_target_install() (sipconfig.Makefile method)</a></dt>
+ <dd><dl>
+ <dt><a href="build_system.html#sipconfig.ModuleMakefile.generate_target_install">(sipconfig.ModuleMakefile method)</a></dt>
+ <dt><a href="build_system.html#sipconfig.ParentMakefile.generate_target_install">(sipconfig.ParentMakefile method)</a></dt>
+ <dt><a href="build_system.html#sipconfig.ProgramMakefile.generate_target_install">(sipconfig.ProgramMakefile method)</a></dt>
+ <dt><a href="build_system.html#sipconfig.PythonModuleMakefile.generate_target_install">(sipconfig.PythonModuleMakefile method)</a></dt>
+ </dl></dd>
+<dt><a href="build_system.html#sipconfig.Makefile.generator">generator (sipconfig.Makefile attribute)</a></dt>
+<dt><a href="python_api.html#sip.getapi">getapi() (in module sip)</a></dt>
+<dt><a href="python_api.html#sip.voidptr.getsize">getsize() (sip.voidptr method)</a></dt>
+<dt><a href="annotations.html#aanno-GetWrapper">GetWrapper (argument annotation)</a></dt>
+<dt><a href="python_api.html#sip.voidptr.getwriteable">getwriteable() (sip.voidptr method)</a></dt>
+</dl></td></tr></table>
+
+<h2 id="H">H</h2>
+<table width="100%" class="indextable"><tr><td width="33%" valign="top">
+<dl>
+
+<dt><a href="annotations.html#fanno-HoldGIL">HoldGIL (function annotation)</a></dt></dl></td><td width="33%" valign="top"><dl>
+</dl></td></tr></table>
+
+<h2 id="I">I</h2>
+<table width="100%" class="indextable"><tr><td width="33%" valign="top">
+<dl>
+
+<dt><a href="annotations.html#aanno-In">In (argument annotation)</a></dt>
+<dt><a href="build_system.html#sipconfig.inform">inform() (in module sipconfig)</a></dt>
+<dt><a href="build_system.html#sipconfig.Makefile.install_file">install_file() (sipconfig.Makefile method)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="python_api.html#sip.isdeleted">isdeleted() (in module sip)</a></dt>
+<dt><a href="python_api.html#sip.ispyowned">ispyowned() (in module sip)</a></dt>
+</dl></td></tr></table>
+
+<h2 id="K">K</h2>
+<table width="100%" class="indextable"><tr><td width="33%" valign="top">
+<dl>
+
+<dt><a href="annotations.html#aanno-KeepReference">KeepReference (argument annotation)</a></dt>
+<dt><a href="annotations.html#fanno-KeywordArgs">KeywordArgs (function annotation)</a></dt></dl></td><td width="33%" valign="top"><dl>
+</dl></td></tr></table>
+
+<h2 id="L">L</h2>
+<table width="100%" class="indextable"><tr><td width="33%" valign="top">
+<dl>
+
+<dt><a href="annotations.html#lanno-Licensee">Licensee (license annotation)</a></dt></dl></td><td width="33%" valign="top"><dl>
+</dl></td></tr></table>
+
+<h2 id="M">M</h2>
+<table width="100%" class="indextable"><tr><td width="33%" valign="top">
+<dl>
+
+<dt><a href="build_system.html#sipconfig.Makefile">Makefile (class in sipconfig)</a></dt>
+<dt><a href="annotations.html#canno-Metatype">Metatype (class annotation)</a></dt>
+<dt><a href="build_system.html#sipconfig.Makefile.mkdir">mkdir (sipconfig.Makefile attribute)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="build_system.html#sipconfig.ModuleMakefile.module_as_lib">module_as_lib() (sipconfig.ModuleMakefile method)</a></dt>
+<dt><a href="build_system.html#sipconfig.ModuleMakefile">ModuleMakefile (class in sipconfig)</a></dt>
+</dl></td></tr></table>
+
+<h2 id="N">N</h2>
+<table width="100%" class="indextable"><tr><td width="33%" valign="top">
+<dl>
+
+<dt><a href="annotations.html#fanno-NewThread">NewThread (function annotation)</a></dt>
+<dt><a href="annotations.html#fanno-NoArgParser">NoArgParser (function annotation)</a></dt>
+<dt><a href="annotations.html#aanno-NoCopy">NoCopy (argument annotation)</a></dt>
+ <dd><dl>
+ <dt><a href="annotations.html#fanno-NoCopy">(function annotation)</a></dt>
+ </dl></dd>
+<dt><a href="annotations.html#canno-NoDefaultCtors">NoDefaultCtors (class annotation)</a></dt>
+<dt><a href="annotations.html#fanno-NoDerived">NoDerived (function annotation)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="annotations.html#fanno-NoKeywordArgs">NoKeywordArgs (function annotation)</a></dt>
+<dt><a href="annotations.html#manno-NoRelease">NoRelease (mapped type annotation)</a></dt>
+<dt><a href="annotations.html#tanno-NoTypeName">NoTypeName (typedef annotation)</a></dt>
+<dt><a href="annotations.html#fanno-Numeric">Numeric (function annotation)</a></dt>
+</dl></td></tr></table>
+
+<h2 id="O">O</h2>
+<table width="100%" class="indextable"><tr><td width="33%" valign="top">
+<dl>
+
+<dt><a href="build_system.html#sipconfig.Makefile.optional_list">optional_list() (sipconfig.Makefile method)</a></dt>
+<dt><a href="build_system.html#sipconfig.Makefile.optional_string">optional_string() (sipconfig.Makefile method)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="annotations.html#aanno-Out">Out (argument annotation)</a></dt>
+</dl></td></tr></table>
+
+<h2 id="P">P</h2>
+<table width="100%" class="indextable"><tr><td width="33%" valign="top">
+<dl>
+
+<dt><a href="build_system.html#sipconfig.ParentMakefile">ParentMakefile (class in sipconfig)</a></dt>
+<dt><a href="build_system.html#sipconfig.Makefile.parse_build_file">parse_build_file() (sipconfig.Makefile method)</a></dt>
+<dt><a href="build_system.html#sipconfig.parse_build_macros">parse_build_macros() (in module sipconfig)</a></dt>
+<dt><a href="build_system.html#sipconfig.Configuration.platform">platform (sipconfig.Configuration attribute)</a></dt>
+<dt><a href="build_system.html#sipconfig.Makefile.platform_lib">platform_lib() (sipconfig.Makefile method)</a></dt>
+<dt><a href="annotations.html#fanno-PostHook">PostHook (function annotation)</a></dt>
+<dt><a href="annotations.html#fanno-PreHook">PreHook (function annotation)</a></dt>
+<dt><a href="build_system.html#sipconfig.ProgramMakefile">ProgramMakefile (class in sipconfig)</a></dt>
+<dt><a href="build_system.html#sipconfig.Configuration.py_conf_inc_dir">py_conf_inc_dir (sipconfig.Configuration attribute)</a></dt>
+<dt><a href="build_system.html#sipconfig.Configuration.py_inc_dir">py_inc_dir (sipconfig.Configuration attribute)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="build_system.html#sipconfig.Configuration.py_lib_dir">py_lib_dir (sipconfig.Configuration attribute)</a></dt>
+<dt><a href="build_system.html#sipconfig.Configuration.py_version">py_version (sipconfig.Configuration attribute)</a></dt>
+<dt><a href="annotations.html#canno-PyName">PyName (class annotation)</a></dt>
+ <dd><dl>
+ <dt><a href="annotations.html#eanno-PyName">(enum annotation)</a></dt>
+ <dt><a href="annotations.html#xanno-PyName">(exception annotation)</a></dt>
+ <dt><a href="annotations.html#fanno-PyName">(function annotation)</a></dt>
+ <dt><a href="annotations.html#vanno-PyName">(variable annotation)</a></dt>
+ </dl></dd>
+<dt><a href="build_system.html#sipconfig.PythonModuleMakefile">PythonModuleMakefile (class in sipconfig)</a></dt>
+</dl></td></tr></table>
+
+<h2 id="R">R</h2>
+<table width="100%" class="indextable"><tr><td width="33%" valign="top">
+<dl>
+
+<dt><a href="build_system.html#sipconfig.read_version">read_version() (in module sipconfig)</a></dt>
+<dt><a href="build_system.html#sipconfig.Makefile.ready">ready() (sipconfig.Makefile method)</a></dt>
+<dt><a href="annotations.html#fanno-ReleaseGIL">ReleaseGIL (function annotation)</a></dt>
+<dt><a href="build_system.html#sipconfig.Makefile.required_string">required_string() (sipconfig.Makefile method)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="annotations.html#aanno-ResultSize">ResultSize (argument annotation)</a></dt>
+<dt><a href="build_system.html#sipconfig.Makefile.rm">rm (sipconfig.Makefile attribute)</a></dt>
+</dl></td></tr></table>
+
+<h2 id="S">S</h2>
+<table width="100%" class="indextable"><tr><td width="33%" valign="top">
+<dl>
+
+<dt><a href="build_system.html#sipconfig.Configuration.set_build_macros">set_build_macros() (sipconfig.Configuration method)</a></dt>
+<dt><a href="python_api.html#sip.setapi">setapi() (in module sip)</a></dt>
+<dt><a href="python_api.html#sip.setdeleted">setdeleted() (in module sip)</a></dt>
+<dt><a href="python_api.html#sip.voidptr.setsize">setsize() (sip.voidptr method)</a></dt>
+<dt><a href="python_api.html#sip.settracemask">settracemask() (in module sip)</a></dt>
+<dt><a href="python_api.html#sip.voidptr.setwriteable">setwriteable() (sip.voidptr method)</a></dt>
+<dt><a href="annotations.html#lanno-Signature">Signature (license annotation)</a></dt>
+<dt><a href="annotations.html#aanno-SingleShot">SingleShot (argument annotation)</a></dt>
+<dt><a href="python_api.html#module-sip">sip (module)</a></dt>
+<dt>sip command line option</dt>
+ <dd><dl>
+ <dt><a href="command_line.html#cmdoption-sip-I">-I &lt;DIR&gt;</a></dt>
+ <dt><a href="command_line.html#cmdoption-sip-P">-P</a></dt>
+ <dt><a href="command_line.html#cmdoption-sip-V">-V</a></dt>
+ <dt><a href="command_line.html#cmdoption-sip-a">-a &lt;FILE&gt;</a></dt>
+ <dt><a href="command_line.html#cmdoption-sip-b">-b &lt;FILE&gt;</a></dt>
+ <dt><a href="command_line.html#cmdoption-sip-c">-c &lt;DIR&gt;</a></dt>
+ <dt><a href="command_line.html#cmdoption-sip-d">-d &lt;FILE&gt;</a></dt>
+ <dt><a href="command_line.html#cmdoption-sip-e">-e</a></dt>
+ <dt><a href="command_line.html#cmdoption-sip-g">-g</a></dt>
+ <dt><a href="command_line.html#cmdoption-sip-h">-h</a></dt>
+ <dt><a href="command_line.html#cmdoption-sip-j">-j &lt;NUMBER&gt;</a></dt>
+ <dt><a href="command_line.html#cmdoption-sip-k">-k</a></dt>
+ <dt><a href="command_line.html#cmdoption-sip-o">-o</a></dt>
+ <dt><a href="command_line.html#cmdoption-sip-p">-p &lt;MODULE&gt;</a></dt>
+ <dt><a href="command_line.html#cmdoption-sip-r">-r</a></dt>
+ <dt><a href="command_line.html#cmdoption-sip-s">-s &lt;SUFFIX&gt;</a></dt>
+ <dt><a href="command_line.html#cmdoption-sip-t">-t &lt;TAG&gt;</a></dt>
+ <dt><a href="command_line.html#cmdoption-sip-w">-w</a></dt>
+ <dt><a href="command_line.html#cmdoption-sip-x">-x &lt;FEATURE&gt;</a></dt>
+ <dt><a href="command_line.html#cmdoption-sip-z">-z &lt;FILE&gt;</a></dt>
+ </dl></dd>
+<dt><a href="specification_files.html#stype-SIP_ANYSLOT">SIP_ANYSLOT (SIP type)</a></dt>
+<dt><a href="c_api.html#SIP_API_MAJOR_NR">SIP_API_MAJOR_NR (C macro)</a></dt>
+<dt><a href="c_api.html#SIP_API_MINOR_NR">SIP_API_MINOR_NR (C macro)</a></dt>
+<dt><a href="build_system.html#sipconfig.Configuration.sip_bin">sip_bin (sipconfig.Configuration attribute)</a></dt>
+<dt><a href="c_api.html#SIP_BLOCK_THREADS">SIP_BLOCK_THREADS (C macro)</a></dt>
+<dt><a href="build_system.html#sipconfig.Configuration.sip_config_args">sip_config_args (sipconfig.Configuration attribute)</a></dt>
+<dt><a href="build_system.html#sipconfig.Configuration.sip_inc_dir">sip_inc_dir (sipconfig.Configuration attribute)</a></dt>
+<dt><a href="build_system.html#sipconfig.Configuration.sip_mod_dir">sip_mod_dir (sipconfig.Configuration attribute)</a></dt>
+<dt><a href="c_api.html#SIP_NO_CONVERTORS">SIP_NO_CONVERTORS (C macro)</a></dt>
+<dt><a href="c_api.html#SIP_NOT_NONE">SIP_NOT_NONE (C macro)</a></dt>
+<dt><a href="c_api.html#SIP_PROTECTED_IS_PUBLIC">SIP_PROTECTED_IS_PUBLIC (C macro)</a></dt>
+<dt><a href="specification_files.html#stype-SIP_PYCALLABLE">SIP_PYCALLABLE (SIP type)</a></dt>
+<dt><a href="specification_files.html#stype-SIP_PYDICT">SIP_PYDICT (SIP type)</a></dt>
+<dt><a href="specification_files.html#stype-SIP_PYLIST">SIP_PYLIST (SIP type)</a></dt>
+<dt><a href="specification_files.html#stype-SIP_PYOBJECT">SIP_PYOBJECT (SIP type)</a></dt>
+<dt><a href="specification_files.html#stype-SIP_PYSLICE">SIP_PYSLICE (SIP type)</a></dt>
+<dt><a href="specification_files.html#stype-SIP_PYTUPLE">SIP_PYTUPLE (SIP type)</a></dt>
+<dt><a href="specification_files.html#stype-SIP_PYTYPE">SIP_PYTYPE (SIP type)</a></dt>
+<dt><a href="specification_files.html#stype-SIP_QOBJECT">SIP_QOBJECT (SIP type)</a></dt>
+<dt><a href="specification_files.html#stype-SIP_RXOBJ_CON">SIP_RXOBJ_CON (SIP type)</a></dt>
+<dt><a href="specification_files.html#stype-SIP_RXOBJ_DIS">SIP_RXOBJ_DIS (SIP type)</a></dt>
+<dt><a href="specification_files.html#stype-SIP_SIGNAL">SIP_SIGNAL (SIP type)</a></dt>
+<dt><a href="specification_files.html#stype-SIP_SLOT">SIP_SLOT (SIP type)</a></dt>
+<dt><a href="specification_files.html#stype-SIP_SLOT_CON">SIP_SLOT_CON (SIP type)</a></dt>
+<dt><a href="specification_files.html#stype-SIP_SLOT_DIS">SIP_SLOT_DIS (SIP type)</a></dt>
+<dt><a href="c_api.html#SIP_SSIZE_T">SIP_SSIZE_T (C macro)</a></dt>
+<dt><a href="c_api.html#SIP_UNBLOCK_THREADS">SIP_UNBLOCK_THREADS (C macro)</a></dt>
+<dt><a href="c_api.html#SIP_VERSION">SIP_VERSION (C macro)</a></dt>
+ <dd><dl>
+ <dt><a href="python_api.html#sip.SIP_VERSION">(in module sip)</a></dt>
+ </dl></dd>
+<dt><a href="build_system.html#sipconfig.Configuration.sip_version">sip_version (sipconfig.Configuration attribute)</a></dt>
+<dt><a href="c_api.html#SIP_VERSION_STR">SIP_VERSION_STR (C macro)</a></dt>
+ <dd><dl>
+ <dt><a href="python_api.html#sip.SIP_VERSION_STR">(in module sip)</a></dt>
+ </dl></dd>
+<dt><a href="build_system.html#sipconfig.Configuration.sip_version_str">sip_version_str (sipconfig.Configuration attribute)</a></dt>
+<dt><a href="c_api.html#sipBadCallableArg">sipBadCallableArg (C function)</a></dt>
+<dt><a href="c_api.html#sipBadCatcherResult">sipBadCatcherResult (C function)</a></dt>
+<dt><a href="c_api.html#sipBadLengthForSlice">sipBadLengthForSlice (C function)</a></dt>
+<dt><a href="c_api.html#sipBuildResult">sipBuildResult (C function)</a></dt>
+<dt><a href="c_api.html#sipCallMethod">sipCallMethod (C function)</a></dt>
+<dt><a href="c_api.html#sipCanConvertToEnum">sipCanConvertToEnum (C function)</a></dt>
+<dt><a href="c_api.html#sipCanConvertToInstance">sipCanConvertToInstance (C function)</a></dt>
+<dt><a href="c_api.html#sipCanConvertToMappedType">sipCanConvertToMappedType (C function)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="c_api.html#sipCanConvertToType">sipCanConvertToType (C function)</a></dt>
+<dt><a href="c_api.html#sipClassName">sipClassName (C function)</a></dt>
+<dt><a href="build_system.html#module-sipconfig">sipconfig (module)</a></dt>
+<dt><a href="c_api.html#sipConvertFromConstVoidPtr">sipConvertFromConstVoidPtr (C function)</a></dt>
+<dt><a href="c_api.html#sipConvertFromConstVoidPtrAndSize">sipConvertFromConstVoidPtrAndSize (C function)</a></dt>
+<dt><a href="c_api.html#sipConvertFromEnum">sipConvertFromEnum (C function)</a></dt>
+<dt><a href="c_api.html#sipConvertFromInstance">sipConvertFromInstance (C function)</a></dt>
+<dt><a href="c_api.html#sipConvertFromMappedType">sipConvertFromMappedType (C function)</a></dt>
+<dt><a href="c_api.html#sipConvertFromNamedEnum">sipConvertFromNamedEnum (C function)</a></dt>
+<dt><a href="c_api.html#sipConvertFromNewInstance">sipConvertFromNewInstance (C function)</a></dt>
+<dt><a href="c_api.html#sipConvertFromNewType">sipConvertFromNewType (C function)</a></dt>
+<dt><a href="c_api.html#sipConvertFromSequenceIndex">sipConvertFromSequenceIndex (C function)</a></dt>
+<dt><a href="c_api.html#sipConvertFromSliceObject">sipConvertFromSliceObject (C function)</a></dt>
+<dt><a href="c_api.html#sipConvertFromType">sipConvertFromType (C function)</a></dt>
+<dt><a href="c_api.html#sipConvertFromVoidPtr">sipConvertFromVoidPtr (C function)</a></dt>
+<dt><a href="c_api.html#sipConvertFromVoidPtrAndSize">sipConvertFromVoidPtrAndSize (C function)</a></dt>
+<dt><a href="c_api.html#sipConvertToInstance">sipConvertToInstance (C function)</a></dt>
+<dt><a href="c_api.html#sipConvertToMappedType">sipConvertToMappedType (C function)</a></dt>
+<dt><a href="c_api.html#sipConvertToType">sipConvertToType (C function)</a></dt>
+<dt><a href="c_api.html#sipConvertToVoidPtr">sipConvertToVoidPtr (C function)</a></dt>
+<dt><a href="annotations.html#sipDelayedDtor">sipDelayedDtor (C type)</a></dt>
+<dt><a href="annotations.html#sipDelayedDtors">sipDelayedDtors (C function)</a></dt>
+<dt><a href="c_api.html#sipExportSymbol">sipExportSymbol (C function)</a></dt>
+<dt><a href="c_api.html#sipFindClass">sipFindClass (C function)</a></dt>
+<dt><a href="c_api.html#sipFindMappedType">sipFindMappedType (C function)</a></dt>
+<dt><a href="c_api.html#sipFindNamedEnum">sipFindNamedEnum (C function)</a></dt>
+<dt><a href="c_api.html#sipFindType">sipFindType (C function)</a></dt>
+<dt><a href="c_api.html#sipForceConvertToInstance">sipForceConvertToInstance (C function)</a></dt>
+<dt><a href="c_api.html#sipForceConvertToMappedType">sipForceConvertToMappedType (C function)</a></dt>
+<dt><a href="c_api.html#sipForceConvertToType">sipForceConvertToType (C function)</a></dt>
+<dt><a href="c_api.html#sipFree">sipFree (C function)</a></dt>
+<dt><a href="c_api.html#sipGetPyObject">sipGetPyObject (C function)</a></dt>
+<dt><a href="c_api.html#sipGetState">sipGetState (C function)</a></dt>
+<dt><a href="c_api.html#sipGetWrapper">sipGetWrapper (C function)</a></dt>
+<dt><a href="c_api.html#sipImportSymbol">sipImportSymbol (C function)</a></dt>
+<dt><a href="c_api.html#sipIntTypeClassMap">sipIntTypeClassMap (C type)</a></dt>
+<dt><a href="c_api.html#sipIsAPIEnabled">sipIsAPIEnabled (C function)</a></dt>
+<dt><a href="c_api.html#sipLong_AsUnsignedLong">sipLong_AsUnsignedLong (C function)</a></dt>
+<dt><a href="c_api.html#sipMalloc">sipMalloc (C function)</a></dt>
+<dt><a href="c_api.html#sipMapIntToClass">sipMapIntToClass (C function)</a></dt>
+<dt><a href="c_api.html#sipMapStringToClass">sipMapStringToClass (C function)</a></dt>
+<dt><a href="build_system.html#sipconfig.SIPModuleMakefile">SIPModuleMakefile (class in sipconfig)</a></dt>
+<dt><a href="c_api.html#sipParseResult">sipParseResult (C function)</a></dt>
+<dt><a href="c_api.html#sipRegisterAttributeGetter">sipRegisterAttributeGetter (C function)</a></dt>
+<dt><a href="c_api.html#sipRegisterPyType">sipRegisterPyType (C function)</a></dt>
+<dt><a href="c_api.html#sipReleaseInstance">sipReleaseInstance (C function)</a></dt>
+<dt><a href="c_api.html#sipReleaseMappedType">sipReleaseMappedType (C function)</a></dt>
+<dt><a href="c_api.html#sipReleaseType">sipReleaseType (C function)</a></dt>
+<dt><a href="c_api.html#sipResolveTypedef">sipResolveTypedef (C function)</a></dt>
+<dt><a href="c_api.html#sipSimpleWrapper">sipSimpleWrapper (C type)</a></dt>
+<dt><a href="c_api.html#sipSimpleWrapper_Type">sipSimpleWrapper_Type (C variable)</a></dt>
+<dt><a href="c_api.html#sipStringTypeClassMap">sipStringTypeClassMap (C type)</a></dt>
+<dt><a href="c_api.html#sipTransferBack">sipTransferBack (C function)</a></dt>
+<dt><a href="c_api.html#sipTransferBreak">sipTransferBreak (C function)</a></dt>
+<dt><a href="c_api.html#sipTransferTo">sipTransferTo (C function)</a></dt>
+<dt><a href="c_api.html#sipTypeAsPyTypeObject">sipTypeAsPyTypeObject (C function)</a></dt>
+<dt><a href="c_api.html#sipTypeFromPyTypeObject">sipTypeFromPyTypeObject (C function)</a></dt>
+<dt><a href="c_api.html#sipTypeIsClass">sipTypeIsClass (C function)</a></dt>
+<dt><a href="c_api.html#sipTypeIsEnum">sipTypeIsEnum (C function)</a></dt>
+<dt><a href="c_api.html#sipTypeIsMapped">sipTypeIsMapped (C function)</a></dt>
+<dt><a href="c_api.html#sipTypeIsNamespace">sipTypeIsNamespace (C function)</a></dt>
+<dt><a href="c_api.html#sipTypeName">sipTypeName (C function)</a></dt>
+<dt><a href="c_api.html#sipTypeScope">sipTypeScope (C function)</a></dt>
+<dt><a href="c_api.html#sipVoidPtr_Type">sipVoidPtr_Type (C variable)</a></dt>
+<dt><a href="c_api.html#sipWrapper">sipWrapper (C type)</a></dt>
+<dt><a href="c_api.html#sipWrapper_Check">sipWrapper_Check (C function)</a></dt>
+<dt><a href="c_api.html#sipWrapper_Type">sipWrapper_Type (C variable)</a></dt>
+<dt><a href="c_api.html#sipWrapperType">sipWrapperType (C type)</a></dt>
+<dt><a href="c_api.html#sipWrapperType_Type">sipWrapperType_Type (C variable)</a></dt>
+<dt><a href="annotations.html#canno-Supertype">Supertype (class annotation)</a></dt>
+</dl></td></tr></table>
+
+<h2 id="T">T</h2>
+<table width="100%" class="indextable"><tr><td width="33%" valign="top">
+<dl>
+
+<dt><a href="annotations.html#lanno-Timestamp">Timestamp (license annotation)</a></dt>
+<dt><a href="annotations.html#aanno-Transfer">Transfer (argument annotation)</a></dt>
+ <dd><dl>
+ <dt><a href="annotations.html#fanno-Transfer">(function annotation)</a></dt>
+ </dl></dd>
+<dt><a href="annotations.html#aanno-TransferBack">TransferBack (argument annotation)</a></dt>
+ <dd><dl>
+ <dt><a href="annotations.html#fanno-TransferBack">(function annotation)</a></dt>
+ </dl></dd>
+<dt><a href="python_api.html#sip.transferback">transferback() (in module sip)</a></dt>
+<dt><a href="annotations.html#aanno-TransferThis">TransferThis (argument annotation)</a></dt>
+ <dd><dl>
+ <dt><a href="annotations.html#fanno-TransferThis">(function annotation)</a></dt>
+ </dl></dd></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="python_api.html#sip.transferto">transferto() (in module sip)</a></dt>
+<dt><a href="annotations.html#lanno-Type">Type (license annotation)</a></dt>
+<dt><a href="c_api.html#typeInt">typeInt (C member)</a></dt>
+<dt><a href="c_api.html#typeString">typeString (C member)</a></dt>
+</dl></td></tr></table>
+
+<h2 id="U">U</h2>
+<table width="100%" class="indextable"><tr><td width="33%" valign="top">
+<dl>
+
+<dt><a href="build_system.html#sipconfig.Configuration.universal">universal (sipconfig.Configuration attribute)</a></dt>
+<dt><a href="python_api.html#sip.unwrapinstance">unwrapinstance() (in module sip)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="c_api.html#user">user (C member)</a></dt>
+</dl></td></tr></table>
+
+<h2 id="V">V</h2>
+<table width="100%" class="indextable"><tr><td width="33%" valign="top">
+<dl>
+
+<dt><a href="build_system.html#sipconfig.version_to_sip_tag">version_to_sip_tag() (in module sipconfig)</a></dt>
+<dt><a href="build_system.html#sipconfig.version_to_string">version_to_string() (in module sipconfig)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="python_api.html#sip.voidptr">voidptr (class in sip)</a></dt>
+</dl></td></tr></table>
+
+<h2 id="W">W</h2>
+<table width="100%" class="indextable"><tr><td width="33%" valign="top">
+<dl>
+
+<dt><a href="python_api.html#sip.wrapinstance">wrapinstance() (in module sip)</a></dt>
+<dt><a href="python_api.html#sip.wrapper">wrapper (class in sip)</a></dt></dl></td><td width="33%" valign="top"><dl>
+<dt><a href="python_api.html#sip.wrappertype">wrappertype (class in sip)</a></dt>
+</dl></td></tr></table>
+
+
+
+ </div>
+ </div>
+ </div>
+ <div class="sphinxsidebar">
+ <div class="sphinxsidebarwrapper">
+
+
+
+ <div id="searchbox" style="display: none">
+ <h3>Quick search</h3>
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" size="18" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ <p class="searchtip" style="font-size: 90%">
+ Enter search terms or a module, class or function name.
+ </p>
+ </div>
+ <script type="text/javascript">$('#searchbox').show(0);</script>
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="#" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ >modules</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+ <div class="footer">
+ &copy; Copyright 2010 Riverbank Computing Limited.
+ Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.4.
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/incompatibilities.html b/doc/html/incompatibilities.html
new file mode 100644
index 0000000..1663016
--- /dev/null
+++ b/doc/html/incompatibilities.html
@@ -0,0 +1,281 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>Potential Incompatibilities with Earlier Versions &mdash; SIP 4.10.5 Reference Guide</title>
+ <link rel="stylesheet" href="_static/default.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '#',
+ VERSION: '4.10.5',
+ COLLAPSE_MODINDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="top" title="SIP 4.10.5 Reference Guide" href="index.html" />
+ <link rel="next" title="Installation" href="installation.html" />
+ <link rel="prev" title="Introduction" href="introduction.html" />
+ </head>
+ <body>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ accesskey="M">modules</a> |</li>
+ <li class="right" >
+ <a href="installation.html" title="Installation"
+ accesskey="N">next</a> |</li>
+ <li class="right" >
+ <a href="introduction.html" title="Introduction"
+ accesskey="P">previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+ <div class="body">
+
+ <div class="section" id="potential-incompatibilities-with-earlier-versions">
+<h1>Potential Incompatibilities with Earlier Versions<a class="headerlink" href="#potential-incompatibilities-with-earlier-versions" title="Permalink to this headline">¶</a></h1>
+<p>This section describes incompatibilities introduced by particular versions of
+SIP. Normally these are the removal of previously deprecated features.</p>
+<div class="section" id="sip-v4-10-1">
+<h2>SIP v4.10.1<a class="headerlink" href="#sip-v4-10-1" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="newly-deprecated-features">
+<h3>Newly Deprecated Features<a class="headerlink" href="#newly-deprecated-features" title="Permalink to this headline">¶</a></h3>
+<p>The following parts of the <a class="reference external" href="c_api.html#ref-c-api"><em>C API</em></a> are now deprecated (but
+still supported).</p>
+<ul class="simple">
+<li>The <tt class="docutils literal"><span class="pre">D</span></tt> format character of <a title="sipParseResult" class="reference external" href="c_api.html#sipParseResult"><tt class="xref docutils literal"><span class="pre">sipParseResult()</span></tt></a>.</li>
+</ul>
+</div>
+</div>
+<div class="section" id="sip-v4-8">
+<h2>SIP v4.8<a class="headerlink" href="#sip-v4-8" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="truediv">
+<h3>__truediv__<a class="headerlink" href="#truediv" title="Permalink to this headline">¶</a></h3>
+<p>Prior to this version the <tt class="xref docutils literal"><span class="pre">__div__()</span></tt> special method implicitly defined the
+<tt class="xref docutils literal"><span class="pre">__truediv__()</span></tt> special method. From this version the <tt class="xref docutils literal"><span class="pre">__truediv__()</span></tt>
+special method must be explicitly defined.</p>
+</div>
+<div class="section" id="sipwrapper-user-member">
+<h3>sipWrapper user Member<a class="headerlink" href="#sipwrapper-user-member" title="Permalink to this headline">¶</a></h3>
+<p>Prior to this version the <a title="sipWrapper" class="reference external" href="c_api.html#sipWrapper"><tt class="xref docutils literal"><span class="pre">sipWrapper</span></tt></a> structure had a member called
+<a title="user" class="reference external" href="c_api.html#user"><tt class="xref docutils literal"><span class="pre">user</span></tt></a> which is available for handwritten code to use. From this
+version <a title="user" class="reference external" href="c_api.html#user"><tt class="xref docutils literal"><span class="pre">user</span></tt></a> is a member of the <a title="sipSimpleWrapper" class="reference external" href="c_api.html#sipSimpleWrapper"><tt class="xref docutils literal"><span class="pre">sipSimpleWrapper</span></tt></a> structure.</p>
+<p><a title="sipWrapper" class="reference external" href="c_api.html#sipWrapper"><tt class="xref docutils literal"><span class="pre">sipWrapper</span></tt></a> pointers can be safely cast to <a title="sipSimpleWrapper" class="reference external" href="c_api.html#sipSimpleWrapper"><tt class="xref docutils literal"><span class="pre">sipSimpleWrapper</span></tt></a>
+pointers, so if your code does something like:</p>
+<div class="highlight-python"><pre>((sipWrapper *)obj)-&gt;user = an_object_reference;</pre>
+</div>
+<p>then you just need to change it to:</p>
+<div class="highlight-python"><pre>((sipSimpleWrapper *)obj)-&gt;user = an_object_reference;</pre>
+</div>
+</div>
+<div class="section" id="removal-of-previously-deprecated-features">
+<h3>Removal of Previously Deprecated Features<a class="headerlink" href="#removal-of-previously-deprecated-features" title="Permalink to this headline">¶</a></h3>
+<p>The following parts of the <a class="reference external" href="c_api.html#ref-c-api"><em>C API</em></a> have been removed.</p>
+<ul class="simple">
+<li>The <tt class="docutils literal"><span class="pre">a</span></tt>, <tt class="docutils literal"><span class="pre">A</span></tt>, <tt class="docutils literal"><span class="pre">M</span></tt>, <tt class="docutils literal"><span class="pre">N</span></tt>, <tt class="docutils literal"><span class="pre">O</span></tt>, <tt class="docutils literal"><span class="pre">P</span></tt> and <tt class="docutils literal"><span class="pre">T</span></tt> format characters
+from <a title="sipBuildResult" class="reference external" href="c_api.html#sipBuildResult"><tt class="xref docutils literal"><span class="pre">sipBuildResult()</span></tt></a> and <a title="sipCallMethod" class="reference external" href="c_api.html#sipCallMethod"><tt class="xref docutils literal"><span class="pre">sipCallMethod()</span></tt></a>.</li>
+<li>The <tt class="docutils literal"><span class="pre">a</span></tt>, <tt class="docutils literal"><span class="pre">A</span></tt>, <tt class="docutils literal"><span class="pre">L</span></tt> and <tt class="docutils literal"><span class="pre">M</span></tt> format characters from
+<a title="sipParseResult" class="reference external" href="c_api.html#sipParseResult"><tt class="xref docutils literal"><span class="pre">sipParseResult()</span></tt></a>.</li>
+<li><tt class="xref docutils literal"><span class="pre">sipConvertToCpp()</span></tt></li>
+<li><tt class="xref docutils literal"><span class="pre">sipIsSubClassInstance()</span></tt></li>
+<li><tt class="xref docutils literal"><span class="pre">sipTransfer()</span></tt></li>
+<li>The <tt class="xref docutils literal"><span class="pre">transfer()</span></tt> function of the <a title="" class="reference external" href="python_api.html#module-sip"><tt class="xref docutils literal"><span class="pre">sip</span></tt></a> module.</li>
+<li>The old-style generated type convertors.</li>
+</ul>
+<p>In addition the <a class="reference external" href="command_line.html#cmdoption-sip-a"><em class="xref">-a</em></a> command line option to <tt class="docutils literal"><span class="pre">configure.py</span></tt> has
+been removed.</p>
+</div>
+<div class="section" id="removal-of-pyqt-specific-features">
+<h3>Removal of PyQt-specific Features<a class="headerlink" href="#removal-of-pyqt-specific-features" title="Permalink to this headline">¶</a></h3>
+<p>The following PyQt-specific support functions have been removed.</p>
+<ul class="simple">
+<li><tt class="xref docutils literal"><span class="pre">sipConnectRx()</span></tt></li>
+<li><tt class="xref docutils literal"><span class="pre">sipDisconnectRx()</span></tt></li>
+<li><tt class="xref docutils literal"><span class="pre">sipEmitSlot()</span></tt></li>
+<li><tt class="xref docutils literal"><span class="pre">sipGetSender()</span></tt></li>
+</ul>
+</div>
+<div class="section" id="id1">
+<h3>Newly Deprecated Features<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h3>
+<p>The following parts of the <a class="reference external" href="c_api.html#ref-c-api"><em>C API</em></a> are now deprecated (but
+still supported).</p>
+<ul class="simple">
+<li>The <a class="reference external" href="c_api.html#ref-type-objects"><em>Generated Type Objects</em></a>.</li>
+<li>The <a class="reference external" href="c_api.html#ref-enum-type-objects"><em>Generated Named Enum Type Objects</em></a>.</li>
+<li><a title="sipConvertFromInstance" class="reference external" href="c_api.html#sipConvertFromInstance"><tt class="xref docutils literal"><span class="pre">sipConvertFromInstance()</span></tt></a></li>
+<li><a title="sipConvertFromMappedType" class="reference external" href="c_api.html#sipConvertFromMappedType"><tt class="xref docutils literal"><span class="pre">sipConvertFromMappedType()</span></tt></a></li>
+<li><a title="sipConvertFromNamedEnum" class="reference external" href="c_api.html#sipConvertFromNamedEnum"><tt class="xref docutils literal"><span class="pre">sipConvertFromNamedEnum()</span></tt></a></li>
+<li><a title="sipConvertFromNewInstance" class="reference external" href="c_api.html#sipConvertFromNewInstance"><tt class="xref docutils literal"><span class="pre">sipConvertFromNewInstance()</span></tt></a></li>
+<li><a title="sipCanConvertToInstance" class="reference external" href="c_api.html#sipCanConvertToInstance"><tt class="xref docutils literal"><span class="pre">sipCanConvertToInstance()</span></tt></a></li>
+<li><a title="sipCanConvertToMappedType" class="reference external" href="c_api.html#sipCanConvertToMappedType"><tt class="xref docutils literal"><span class="pre">sipCanConvertToMappedType()</span></tt></a></li>
+<li><a title="sipConvertToInstance" class="reference external" href="c_api.html#sipConvertToInstance"><tt class="xref docutils literal"><span class="pre">sipConvertToInstance()</span></tt></a></li>
+<li><a title="sipConvertToMappedType" class="reference external" href="c_api.html#sipConvertToMappedType"><tt class="xref docutils literal"><span class="pre">sipConvertToMappedType()</span></tt></a></li>
+<li><a title="sipForceConvertToInstance" class="reference external" href="c_api.html#sipForceConvertToInstance"><tt class="xref docutils literal"><span class="pre">sipForceConvertToInstance()</span></tt></a></li>
+<li><a title="sipForceConvertToMappedType" class="reference external" href="c_api.html#sipForceConvertToMappedType"><tt class="xref docutils literal"><span class="pre">sipForceConvertToMappedType()</span></tt></a></li>
+<li><a title="sipClassName" class="reference external" href="c_api.html#sipClassName"><tt class="xref docutils literal"><span class="pre">sipClassName()</span></tt></a></li>
+<li><a title="sipFindClass" class="reference external" href="c_api.html#sipFindClass"><tt class="xref docutils literal"><span class="pre">sipFindClass()</span></tt></a></li>
+<li><a title="sipFindNamedEnum" class="reference external" href="c_api.html#sipFindNamedEnum"><tt class="xref docutils literal"><span class="pre">sipFindNamedEnum()</span></tt></a></li>
+<li><a title="sipFindMappedType" class="reference external" href="c_api.html#sipFindMappedType"><tt class="xref docutils literal"><span class="pre">sipFindMappedType()</span></tt></a></li>
+<li><a title="sipGetWrapper" class="reference external" href="c_api.html#sipGetWrapper"><tt class="xref docutils literal"><span class="pre">sipGetWrapper()</span></tt></a></li>
+<li><a title="sipReleaseInstance" class="reference external" href="c_api.html#sipReleaseInstance"><tt class="xref docutils literal"><span class="pre">sipReleaseInstance()</span></tt></a></li>
+<li><a title="sipReleaseMappedType" class="reference external" href="c_api.html#sipReleaseMappedType"><tt class="xref docutils literal"><span class="pre">sipReleaseMappedType()</span></tt></a></li>
+<li><a title="sipWrapper_Check" class="reference external" href="c_api.html#sipWrapper_Check"><tt class="xref docutils literal"><span class="pre">sipWrapper_Check()</span></tt></a></li>
+<li>The <tt class="docutils literal"><span class="pre">B</span></tt>, <tt class="docutils literal"><span class="pre">C</span></tt> and <tt class="docutils literal"><span class="pre">E</span></tt> format characters of <a title="sipBuildResult" class="reference external" href="c_api.html#sipBuildResult"><tt class="xref docutils literal"><span class="pre">sipBuildResult()</span></tt></a> and
+<a title="sipCallMethod" class="reference external" href="c_api.html#sipCallMethod"><tt class="xref docutils literal"><span class="pre">sipCallMethod()</span></tt></a>.</li>
+<li>The <tt class="docutils literal"><span class="pre">s</span></tt>, <tt class="docutils literal"><span class="pre">C</span></tt> and <tt class="docutils literal"><span class="pre">E</span></tt> format characters of <a title="sipParseResult" class="reference external" href="c_api.html#sipParseResult"><tt class="xref docutils literal"><span class="pre">sipParseResult()</span></tt></a>.</li>
+</ul>
+</div>
+</div>
+<div class="section" id="sip-v4-7-8">
+<h2>SIP v4.7.8<a class="headerlink" href="#sip-v4-7-8" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="automatic-int-to-enum-conversions">
+<h3>Automatic int to Enum Conversions<a class="headerlink" href="#automatic-int-to-enum-conversions" title="Permalink to this headline">¶</a></h3>
+<p>This version allows a Python <tt class="docutils literal"><span class="pre">int</span></tt> object to be passed whenever an enum is
+expected. This can mean that two signatures that were different with prior
+versions are now the same as far as Python is concerned.</p>
+<p>The <a class="reference external" href="annotations.html#aanno-Constrained"><tt class="xref docutils literal"><span class="pre">Constrained</span></tt></a> argument annotation can now be applied to an enum
+argument to revert to the earlier behaviour.</p>
+</div>
+</div>
+<div class="section" id="sip-v4-7-3">
+<h2>SIP v4.7.3<a class="headerlink" href="#sip-v4-7-3" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="complementary-comparison-operators">
+<h3>Complementary Comparison Operators<a class="headerlink" href="#complementary-comparison-operators" title="Permalink to this headline">¶</a></h3>
+<p>Prior to this version SIP did not automatically generate missing complementary
+comparison operators. Typically this was worked around by adding them
+explicitly to the .sip files, even though they weren&#8217;t implemented in C++ and
+relied on the C++ compiler calling the complementary operator that was
+implemented.</p>
+<p>A necessary change to the code generator meant that this not longer worked and
+so SIP was changed to automatically generate any missing complementary
+operators. If you have added such operators explicitly then you should remove
+them or make them dependent on the particular version of SIP.</p>
+</div>
+</div>
+<div class="section" id="sip-v4-4">
+<h2>SIP v4.4<a class="headerlink" href="#sip-v4-4" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="convertfromtypecode-and-converttotypecode">
+<h3>%ConvertFromTypeCode and %ConvertToTypeCode<a class="headerlink" href="#convertfromtypecode-and-converttotypecode" title="Permalink to this headline">¶</a></h3>
+<p>Handwritten <a class="reference external" href="directives.html#directive-%ConvertFromTypeCode"><tt class="xref docutils literal"><span class="pre">%ConvertFromTypeCode</span></tt></a> and
+<a class="reference external" href="directives.html#directive-%ConvertToTypeCode"><tt class="xref docutils literal"><span class="pre">%ConvertToTypeCode</span></tt></a> now have the responsibility for implementing
+the <a class="reference external" href="annotations.html#aanno-Transfer"><tt class="xref docutils literal"><span class="pre">Transfer</span></tt></a> and <a class="reference external" href="annotations.html#aanno-TransferBack"><tt class="xref docutils literal"><span class="pre">TransferBack</span></tt></a> annotations.</p>
+</div>
+<div class="section" id="sip-build">
+<h3>SIP_BUILD<a class="headerlink" href="#sip-build" title="Permalink to this headline">¶</a></h3>
+<p>The <tt class="xref docutils literal"><span class="pre">SIP_BUILD</span></tt> C preprocessor symbol has been removed.</p>
+</div>
+<div class="section" id="id2">
+<h3>Newly Deprecated Features<a class="headerlink" href="#id2" title="Permalink to this headline">¶</a></h3>
+<p>The following parts of the <a class="reference external" href="c_api.html#ref-c-api"><em>C API</em></a> are now deprecated (but
+still supported).</p>
+<ul class="simple">
+<li>The old-style generated type convertors.</li>
+<li><tt class="xref docutils literal"><span class="pre">sipConvertToCpp()</span></tt></li>
+<li><tt class="xref docutils literal"><span class="pre">sipIsSubClassInstance()</span></tt></li>
+</ul>
+</div>
+</div>
+</div>
+
+
+ </div>
+ </div>
+ </div>
+ <div class="sphinxsidebar">
+ <div class="sphinxsidebarwrapper">
+ <h3><a href="index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference external" href="#">Potential Incompatibilities with Earlier Versions</a><ul>
+<li><a class="reference external" href="#sip-v4-10-1">SIP v4.10.1</a><ul>
+<li><a class="reference external" href="#newly-deprecated-features">Newly Deprecated Features</a></li>
+</ul>
+</li>
+<li><a class="reference external" href="#sip-v4-8">SIP v4.8</a><ul>
+<li><a class="reference external" href="#truediv">__truediv__</a></li>
+<li><a class="reference external" href="#sipwrapper-user-member">sipWrapper user Member</a></li>
+<li><a class="reference external" href="#removal-of-previously-deprecated-features">Removal of Previously Deprecated Features</a></li>
+<li><a class="reference external" href="#removal-of-pyqt-specific-features">Removal of PyQt-specific Features</a></li>
+<li><a class="reference external" href="#id1">Newly Deprecated Features</a></li>
+</ul>
+</li>
+<li><a class="reference external" href="#sip-v4-7-8">SIP v4.7.8</a><ul>
+<li><a class="reference external" href="#automatic-int-to-enum-conversions">Automatic int to Enum Conversions</a></li>
+</ul>
+</li>
+<li><a class="reference external" href="#sip-v4-7-3">SIP v4.7.3</a><ul>
+<li><a class="reference external" href="#complementary-comparison-operators">Complementary Comparison Operators</a></li>
+</ul>
+</li>
+<li><a class="reference external" href="#sip-v4-4">SIP v4.4</a><ul>
+<li><a class="reference external" href="#convertfromtypecode-and-converttotypecode">%ConvertFromTypeCode and %ConvertToTypeCode</a></li>
+<li><a class="reference external" href="#sip-build">SIP_BUILD</a></li>
+<li><a class="reference external" href="#id2">Newly Deprecated Features</a></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+
+ <h4>Previous topic</h4>
+ <p class="topless"><a href="introduction.html"
+ title="previous chapter">Introduction</a></p>
+ <h4>Next topic</h4>
+ <p class="topless"><a href="installation.html"
+ title="next chapter">Installation</a></p>
+ <div id="searchbox" style="display: none">
+ <h3>Quick search</h3>
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" size="18" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ <p class="searchtip" style="font-size: 90%">
+ Enter search terms or a module, class or function name.
+ </p>
+ </div>
+ <script type="text/javascript">$('#searchbox').show(0);</script>
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ >modules</a> |</li>
+ <li class="right" >
+ <a href="installation.html" title="Installation"
+ >next</a> |</li>
+ <li class="right" >
+ <a href="introduction.html" title="Introduction"
+ >previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+ <div class="footer">
+ &copy; Copyright 2010 Riverbank Computing Limited.
+ Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.4.
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/index.html b/doc/html/index.html
new file mode 100644
index 0000000..ed2d37d
--- /dev/null
+++ b/doc/html/index.html
@@ -0,0 +1,167 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>SIP Reference Guide &mdash; SIP 4.10.5 Reference Guide</title>
+ <link rel="stylesheet" href="_static/default.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '#',
+ VERSION: '4.10.5',
+ COLLAPSE_MODINDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="top" title="SIP 4.10.5 Reference Guide" href="#" />
+ <link rel="next" title="Introduction" href="introduction.html" />
+ </head>
+ <body>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ accesskey="M">modules</a> |</li>
+ <li class="right" >
+ <a href="introduction.html" title="Introduction"
+ accesskey="N">next</a> |</li>
+ <li><a href="#">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+ <div class="body">
+
+ <div class="section" id="sip-reference-guide">
+<h1>SIP Reference Guide<a class="headerlink" href="#sip-reference-guide" title="Permalink to this headline">¶</a></h1>
+<ul>
+<li class="toctree-l1"><a class="reference external" href="introduction.html">Introduction</a><ul>
+<li class="toctree-l2"><a class="reference external" href="introduction.html#license">License</a></li>
+<li class="toctree-l2"><a class="reference external" href="introduction.html#features">Features</a></li>
+<li class="toctree-l2"><a class="reference external" href="introduction.html#sip-components">SIP Components</a></li>
+<li class="toctree-l2"><a class="reference external" href="introduction.html#qt-support">Qt Support</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference external" href="incompatibilities.html">Potential Incompatibilities with Earlier Versions</a><ul>
+<li class="toctree-l2"><a class="reference external" href="incompatibilities.html#sip-v4-10-1">SIP v4.10.1</a></li>
+<li class="toctree-l2"><a class="reference external" href="incompatibilities.html#sip-v4-8">SIP v4.8</a></li>
+<li class="toctree-l2"><a class="reference external" href="incompatibilities.html#sip-v4-7-8">SIP v4.7.8</a></li>
+<li class="toctree-l2"><a class="reference external" href="incompatibilities.html#sip-v4-7-3">SIP v4.7.3</a></li>
+<li class="toctree-l2"><a class="reference external" href="incompatibilities.html#sip-v4-4">SIP v4.4</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference external" href="installation.html">Installation</a><ul>
+<li class="toctree-l2"><a class="reference external" href="installation.html#downloading">Downloading</a></li>
+<li class="toctree-l2"><a class="reference external" href="installation.html#configuring">Configuring</a></li>
+<li class="toctree-l2"><a class="reference external" href="installation.html#building">Building</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference external" href="using.html">Using SIP</a><ul>
+<li class="toctree-l2"><a class="reference external" href="using.html#a-simple-c-example">A Simple C++ Example</a></li>
+<li class="toctree-l2"><a class="reference external" href="using.html#id7">A Simple C Example</a></li>
+<li class="toctree-l2"><a class="reference external" href="using.html#a-more-complex-c-example">A More Complex C++ Example</a></li>
+<li class="toctree-l2"><a class="reference external" href="using.html#ownership-of-objects">Ownership of Objects</a></li>
+<li class="toctree-l2"><a class="reference external" href="using.html#types-and-meta-types">Types and Meta-types</a></li>
+<li class="toctree-l2"><a class="reference external" href="using.html#lazy-type-attributes">Lazy Type Attributes</a></li>
+<li class="toctree-l2"><a class="reference external" href="using.html#support-for-python-s-buffer-interface">Support for Python&#8217;s Buffer Interface</a></li>
+<li class="toctree-l2"><a class="reference external" href="using.html#support-for-wide-characters">Support for Wide Characters</a></li>
+<li class="toctree-l2"><a class="reference external" href="using.html#the-python-global-interpreter-lock">The Python Global Interpreter Lock</a></li>
+<li class="toctree-l2"><a class="reference external" href="using.html#managing-incompatible-apis">Managing Incompatible APIs</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference external" href="command_line.html">The SIP Command Line</a></li>
+<li class="toctree-l1"><a class="reference external" href="specification_files.html">SIP Specification Files</a><ul>
+<li class="toctree-l2"><a class="reference external" href="specification_files.html#syntax-definition">Syntax Definition</a></li>
+<li class="toctree-l2"><a class="reference external" href="specification_files.html#variable-numbers-of-arguments">Variable Numbers of Arguments</a></li>
+<li class="toctree-l2"><a class="reference external" href="specification_files.html#additional-sip-types">Additional SIP Types</a></li>
+<li class="toctree-l2"><a class="reference external" href="specification_files.html#classic-division-and-true-division">Classic Division and True Division</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference external" href="directives.html">Directives</a></li>
+<li class="toctree-l1"><a class="reference external" href="annotations.html">Annotations</a><ul>
+<li class="toctree-l2"><a class="reference external" href="annotations.html#argument-annotations">Argument Annotations</a></li>
+<li class="toctree-l2"><a class="reference external" href="annotations.html#class-annotations">Class Annotations</a></li>
+<li class="toctree-l2"><a class="reference external" href="annotations.html#mapped-type-annotations">Mapped Type Annotations</a></li>
+<li class="toctree-l2"><a class="reference external" href="annotations.html#enum-annotations">Enum Annotations</a></li>
+<li class="toctree-l2"><a class="reference external" href="annotations.html#exception-annotations">Exception Annotations</a></li>
+<li class="toctree-l2"><a class="reference external" href="annotations.html#function-annotations">Function Annotations</a></li>
+<li class="toctree-l2"><a class="reference external" href="annotations.html#license-annotations">License Annotations</a></li>
+<li class="toctree-l2"><a class="reference external" href="annotations.html#typedef-annotations">Typedef Annotations</a></li>
+<li class="toctree-l2"><a class="reference external" href="annotations.html#variable-annotations">Variable Annotations</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference external" href="c_api.html">C API for Handwritten Code</a><ul>
+<li class="toctree-l2"><a class="reference external" href="c_api.html#generated-type-structures">Generated Type Structures</a></li>
+<li class="toctree-l2"><a class="reference external" href="c_api.html#generated-type-objects">Generated Type Objects</a></li>
+<li class="toctree-l2"><a class="reference external" href="c_api.html#generated-named-enum-type-objects">Generated Named Enum Type Objects</a></li>
+<li class="toctree-l2"><a class="reference external" href="c_api.html#generated-derived-classes">Generated Derived Classes</a></li>
+<li class="toctree-l2"><a class="reference external" href="c_api.html#generated-exception-objects">Generated Exception Objects</a></li>
+</ul>
+</li>
+<li class="toctree-l1"><a class="reference external" href="embedding.html">Using the C API when Embedding</a></li>
+<li class="toctree-l1"><a class="reference external" href="python_api.html">Python API for Applications</a></li>
+<li class="toctree-l1"><a class="reference external" href="build_system.html">The Build System</a></li>
+<li class="toctree-l1"><a class="reference external" href="distutils.html">Building Your Extension with distutils</a></li>
+<li class="toctree-l1"><a class="reference external" href="builtin.html">Builtin Modules and Custom Interpreters</a></li>
+</ul>
+</div>
+
+
+ </div>
+ </div>
+ </div>
+ <div class="sphinxsidebar">
+ <div class="sphinxsidebarwrapper">
+ <h4>Next topic</h4>
+ <p class="topless"><a href="introduction.html"
+ title="next chapter">Introduction</a></p>
+ <div id="searchbox" style="display: none">
+ <h3>Quick search</h3>
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" size="18" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ <p class="searchtip" style="font-size: 90%">
+ Enter search terms or a module, class or function name.
+ </p>
+ </div>
+ <script type="text/javascript">$('#searchbox').show(0);</script>
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ >modules</a> |</li>
+ <li class="right" >
+ <a href="introduction.html" title="Introduction"
+ >next</a> |</li>
+ <li><a href="#">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+ <div class="footer">
+ &copy; Copyright 2010 Riverbank Computing Limited.
+ Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.4.
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/installation.html b/doc/html/installation.html
new file mode 100644
index 0000000..0769a36
--- /dev/null
+++ b/doc/html/installation.html
@@ -0,0 +1,277 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>Installation &mdash; SIP 4.10.5 Reference Guide</title>
+ <link rel="stylesheet" href="_static/default.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '#',
+ VERSION: '4.10.5',
+ COLLAPSE_MODINDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="top" title="SIP 4.10.5 Reference Guide" href="index.html" />
+ <link rel="next" title="Using SIP" href="using.html" />
+ <link rel="prev" title="Potential Incompatibilities with Earlier Versions" href="incompatibilities.html" />
+ </head>
+ <body>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ accesskey="M">modules</a> |</li>
+ <li class="right" >
+ <a href="using.html" title="Using SIP"
+ accesskey="N">next</a> |</li>
+ <li class="right" >
+ <a href="incompatibilities.html" title="Potential Incompatibilities with Earlier Versions"
+ accesskey="P">previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+ <div class="body">
+
+ <div class="section" id="installation">
+<h1>Installation<a class="headerlink" href="#installation" title="Permalink to this headline">¶</a></h1>
+<div class="section" id="downloading">
+<h2>Downloading<a class="headerlink" href="#downloading" title="Permalink to this headline">¶</a></h2>
+<p>You can get the latest release of the SIP source code from
+<a class="reference external" href="http://www.riverbankcomputing.com/software/sip/download">http://www.riverbankcomputing.com/software/sip/download</a>.</p>
+<p>SIP is also included with all of the major Linux distributions. However, it
+may be a version or two out of date.</p>
+</div>
+<div class="section" id="configuring">
+<h2>Configuring<a class="headerlink" href="#configuring" title="Permalink to this headline">¶</a></h2>
+<p>After unpacking the source package (either a <tt class="docutils literal"><span class="pre">.tar.gz</span></tt> or a <tt class="docutils literal"><span class="pre">.zip</span></tt> file
+depending on your platform) you should then check for any <tt class="docutils literal"><span class="pre">README</span></tt> files
+that relate to your platform.</p>
+<p>Next you need to configure SIP by executing the <tt class="docutils literal"><span class="pre">configure.py</span></tt> script. For
+example:</p>
+<div class="highlight-python"><pre>python configure.py</pre>
+</div>
+<p>This assumes that the Python interpreter is on your path. Something like the
+following may be appropriate on Windows:</p>
+<div class="highlight-python"><pre>c:\python26\python configure.py</pre>
+</div>
+<p>If you have multiple versions of Python installed then make sure you use the
+interpreter for which you wish SIP to generate bindings for.</p>
+<p>The full set of command line options is:</p>
+<dl class="cmdoption">
+<dt id="cmdoption-configure.py--version">
+<tt class="descname">--version</tt><tt class="descclassname"></tt><a class="headerlink" href="#cmdoption-configure.py--version" title="Permalink to this definition">¶</a></dt>
+<dd>Display the SIP version number.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-configure.py-h">
+<tt class="descname">-h</tt><tt class="descclassname"></tt><tt class="descclassname">, </tt><tt class="descname">--help</tt><tt class="descclassname"></tt><a class="headerlink" href="#cmdoption-configure.py-h" title="Permalink to this definition">¶</a></dt>
+<dd>Display a help message.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-configure.py--arch">
+<tt class="descname">--arch</tt><tt class="descclassname"> &lt;ARCH&gt;</tt><a class="headerlink" href="#cmdoption-configure.py--arch" title="Permalink to this definition">¶</a></dt>
+<dd>Binaries for the MacOS/X architecture <tt class="docutils literal"><span class="pre">&lt;ARCH&gt;</span></tt> will be built. This
+option should be given once for each architecture to be built. Specifying
+more than one architecture will cause a universal binary to be created.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-configure.py-b">
+<tt class="descname">-b</tt><tt class="descclassname"> &lt;DIR&gt;</tt><tt class="descclassname">, </tt><tt class="descname">--bindir</tt><tt class="descclassname"> &lt;DIR&gt;</tt><a class="headerlink" href="#cmdoption-configure.py-b" title="Permalink to this definition">¶</a></dt>
+<dd>The SIP code generator will be installed in the directory <tt class="docutils literal"><span class="pre">&lt;DIR&gt;</span></tt>.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-configure.py-d">
+<tt class="descname">-d</tt><tt class="descclassname"> &lt;DIR&gt;</tt><tt class="descclassname">, </tt><tt class="descname">--destdir</tt><tt class="descclassname"> &lt;DIR&gt;</tt><a class="headerlink" href="#cmdoption-configure.py-d" title="Permalink to this definition">¶</a></dt>
+<dd>The SIP module will be installed in the directory <tt class="docutils literal"><span class="pre">&lt;DIR&gt;</span></tt>.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-configure.py-e">
+<tt class="descname">-e</tt><tt class="descclassname"> &lt;DIR&gt;</tt><tt class="descclassname">, </tt><tt class="descname">--incdir</tt><tt class="descclassname"> &lt;DIR&gt;</tt><a class="headerlink" href="#cmdoption-configure.py-e" title="Permalink to this definition">¶</a></dt>
+<dd>The SIP header file will be installed in the directory <tt class="docutils literal"><span class="pre">&lt;DIR&gt;</span></tt>.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-configure.py-k">
+<tt class="descname">-k</tt><tt class="descclassname"></tt><tt class="descclassname">, </tt><tt class="descname">--static</tt><tt class="descclassname"></tt><a class="headerlink" href="#cmdoption-configure.py-k" title="Permalink to this definition">¶</a></dt>
+<dd>The SIP module will be built as a static library. This is useful when
+building the SIP module as a Python builtin (see <a class="reference external" href="builtin.html#ref-builtin"><em>Builtin Modules and Custom Interpreters</em></a>).</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-configure.py-n">
+<tt class="descname">-n</tt><tt class="descclassname"></tt><tt class="descclassname">, </tt><tt class="descname">--universal</tt><tt class="descclassname"></tt><a class="headerlink" href="#cmdoption-configure.py-n" title="Permalink to this definition">¶</a></dt>
+<dd>The SIP code generator and module will be built as universal binaries
+under MacOS/X. If the <a class="reference internal" href="#cmdoption-configure.py--arch"><em class="xref">--arch</em></a> option has
+not been specified then the universal binary will include the <tt class="docutils literal"><span class="pre">i386</span></tt> and
+<tt class="docutils literal"><span class="pre">ppc</span></tt> architectures.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-configure.py-p">
+<tt class="descname">-p</tt><tt class="descclassname"> &lt;PLATFORM&gt;</tt><tt class="descclassname">, </tt><tt class="descname">--platform</tt><tt class="descclassname"> &lt;PLATFORM&gt;</tt><a class="headerlink" href="#cmdoption-configure.py-p" title="Permalink to this definition">¶</a></dt>
+<dd>Explicitly specify the platform/compiler to be used by the build system,
+otherwise a platform specific default will be used. The
+<a class="reference internal" href="#cmdoption-configure.py--show-platforms"><em class="xref">--show-platforms</em></a> option will
+display all the supported platform/compilers.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-configure.py-s">
+<tt class="descname">-s</tt><tt class="descclassname"> &lt;SDK&gt;</tt><tt class="descclassname">, </tt><tt class="descname">--sdk</tt><tt class="descclassname"> &lt;SDK&gt;</tt><a class="headerlink" href="#cmdoption-configure.py-s" title="Permalink to this definition">¶</a></dt>
+<dd>If the <a class="reference internal" href="#cmdoption-configure.py-n"><em class="xref">--universal</em></a> option was given then this
+specifies the name of the SDK directory. If a path is not given then it is
+assumed to be a sub-directory of <tt class="docutils literal"><span class="pre">/Developer/SDKs</span></tt>.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-configure.py-u">
+<tt class="descname">-u</tt><tt class="descclassname"></tt><tt class="descclassname">, </tt><tt class="descname">--debug</tt><tt class="descclassname"></tt><a class="headerlink" href="#cmdoption-configure.py-u" title="Permalink to this definition">¶</a></dt>
+<dd>The SIP module will be built with debugging symbols.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-configure.py-v">
+<tt class="descname">-v</tt><tt class="descclassname"> &lt;DIR&gt;</tt><tt class="descclassname">, </tt><tt class="descname">--sipdir</tt><tt class="descclassname"> &lt;DIR&gt;</tt><a class="headerlink" href="#cmdoption-configure.py-v" title="Permalink to this definition">¶</a></dt>
+<dd>By default <tt class="docutils literal"><span class="pre">.sip</span></tt> files will be installed in the directory <tt class="docutils literal"><span class="pre">&lt;DIR&gt;</span></tt>.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-configure.py--show-platforms">
+<tt class="descname">--show-platforms</tt><tt class="descclassname"></tt><a class="headerlink" href="#cmdoption-configure.py--show-platforms" title="Permalink to this definition">¶</a></dt>
+<dd>The list of all supported platform/compilers will be displayed.</dd></dl>
+
+<dl class="cmdoption">
+<dt id="cmdoption-configure.py--show-build-macros">
+<tt class="descname">--show-build-macros</tt><tt class="descclassname"></tt><a class="headerlink" href="#cmdoption-configure.py--show-build-macros" title="Permalink to this definition">¶</a></dt>
+<dd>The list of all available build macros will be displayed.</dd></dl>
+
+<p>The <tt class="docutils literal"><span class="pre">configure.py</span></tt> script takes many other options that allows the build
+system to be finely tuned. These are of the form <tt class="docutils literal"><span class="pre">name=value</span></tt> or
+<tt class="docutils literal"><span class="pre">name+=value</span></tt>. The <em class="xref">--show-build-macros </em> option will display each supported <tt class="docutils literal"><span class="pre">name</span></tt>, although not
+all are applicable to all platforms.</p>
+<p>The <tt class="docutils literal"><span class="pre">name=value</span></tt> form means that <tt class="docutils literal"><span class="pre">value</span></tt> will replace the existing value of
+<tt class="docutils literal"><span class="pre">name</span></tt>.</p>
+<p>The <tt class="docutils literal"><span class="pre">name+=value</span></tt> form means that <tt class="docutils literal"><span class="pre">value</span></tt> will be appended to the existing
+value of <tt class="docutils literal"><span class="pre">name</span></tt>.</p>
+<p>For example, the following will disable support for C++ exceptions (and so
+reduce the size of module binaries) when used with GCC:</p>
+<div class="highlight-python"><pre>python configure.py CXXFLAGS+=-fno-exceptions</pre>
+</div>
+<p>A pure Python module called <tt class="docutils literal"><span class="pre">sipconfig.py</span></tt> is generated by <tt class="docutils literal"><span class="pre">configure.py</span></tt>.
+This defines each <tt class="docutils literal"><span class="pre">name</span></tt> and its corresponding <tt class="docutils literal"><span class="pre">value</span></tt>. Looking at it will
+give you a good idea of how the build system uses the different options. It is
+covered in detail in <a class="reference external" href="build_system.html#ref-build-system"><em>The Build System</em></a>.</p>
+<div class="section" id="configuring-for-mingw">
+<h3>Configuring for MinGW<a class="headerlink" href="#configuring-for-mingw" title="Permalink to this headline">¶</a></h3>
+<p>SIP, and the modules it generates, can be built with MinGW, the Windows port of
+GCC. You must use the <a class="reference internal" href="#cmdoption-configure.py-p"><em class="xref">--platform</em></a> command line
+option to specify the correct platform. For example:</p>
+<div class="highlight-python"><pre>c:\python26\python configure.py --platform win32-g++</pre>
+</div>
+</div>
+<div class="section" id="configuring-for-the-borland-c-compiler">
+<h3>Configuring for the Borland C++ Compiler<a class="headerlink" href="#configuring-for-the-borland-c-compiler" title="Permalink to this headline">¶</a></h3>
+<p>SIP, and the modules it generates, can be built with the free Borland C++
+compiler. You must use the <a class="reference internal" href="#cmdoption-configure.py-p"><em class="xref">--platform</em></a> command line
+option to specify the correct platform. For example:</p>
+<div class="highlight-python"><pre>c:\python26\python configure.py --platform win32-borland</pre>
+</div>
+<p>You must also make sure you have a Borland-compatible version of the Python
+library. If you are using the standard Python distribution (built using the
+Microsoft compiler) then you must convert the format of the Python library.
+For example:</p>
+<div class="highlight-python"><pre>coff2omf python26.lib python26_bcpp.lib</pre>
+</div>
+</div>
+</div>
+<div class="section" id="building">
+<h2>Building<a class="headerlink" href="#building" title="Permalink to this headline">¶</a></h2>
+<p>The next step is to build SIP by running your platform&#8217;s <tt class="docutils literal"><span class="pre">make</span></tt> command. For
+example:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">make</span>
+</pre></div>
+</div>
+<p>The final step is to install SIP by running the following command:</p>
+<div class="highlight-python"><pre>make install</pre>
+</div>
+<p>(Depending on your system you may require root or administrator privileges.)</p>
+<p>This will install the various SIP components.</p>
+</div>
+</div>
+
+
+ </div>
+ </div>
+ </div>
+ <div class="sphinxsidebar">
+ <div class="sphinxsidebarwrapper">
+ <h3><a href="index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference external" href="#">Installation</a><ul>
+<li><a class="reference external" href="#downloading">Downloading</a></li>
+<li><a class="reference external" href="#configuring">Configuring</a><ul>
+<li><a class="reference external" href="#configuring-for-mingw">Configuring for MinGW</a></li>
+<li><a class="reference external" href="#configuring-for-the-borland-c-compiler">Configuring for the Borland C++ Compiler</a></li>
+</ul>
+</li>
+<li><a class="reference external" href="#building">Building</a></li>
+</ul>
+</li>
+</ul>
+
+ <h4>Previous topic</h4>
+ <p class="topless"><a href="incompatibilities.html"
+ title="previous chapter">Potential Incompatibilities with Earlier Versions</a></p>
+ <h4>Next topic</h4>
+ <p class="topless"><a href="using.html"
+ title="next chapter">Using SIP</a></p>
+ <div id="searchbox" style="display: none">
+ <h3>Quick search</h3>
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" size="18" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ <p class="searchtip" style="font-size: 90%">
+ Enter search terms or a module, class or function name.
+ </p>
+ </div>
+ <script type="text/javascript">$('#searchbox').show(0);</script>
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ >modules</a> |</li>
+ <li class="right" >
+ <a href="using.html" title="Using SIP"
+ >next</a> |</li>
+ <li class="right" >
+ <a href="incompatibilities.html" title="Potential Incompatibilities with Earlier Versions"
+ >previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+ <div class="footer">
+ &copy; Copyright 2010 Riverbank Computing Limited.
+ Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.4.
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/introduction.html b/doc/html/introduction.html
new file mode 100644
index 0000000..c952bf7
--- /dev/null
+++ b/doc/html/introduction.html
@@ -0,0 +1,239 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>Introduction &mdash; SIP 4.10.5 Reference Guide</title>
+ <link rel="stylesheet" href="_static/default.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '#',
+ VERSION: '4.10.5',
+ COLLAPSE_MODINDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="top" title="SIP 4.10.5 Reference Guide" href="index.html" />
+ <link rel="next" title="Potential Incompatibilities with Earlier Versions" href="incompatibilities.html" />
+ <link rel="prev" title="SIP Reference Guide" href="index.html" />
+ </head>
+ <body>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ accesskey="M">modules</a> |</li>
+ <li class="right" >
+ <a href="incompatibilities.html" title="Potential Incompatibilities with Earlier Versions"
+ accesskey="N">next</a> |</li>
+ <li class="right" >
+ <a href="index.html" title="SIP Reference Guide"
+ accesskey="P">previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+ <div class="body">
+
+ <div class="section" id="introduction">
+<h1>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline">¶</a></h1>
+<p>This is the reference guide for SIP 4.10.5. SIP is a tool for
+automatically generating <a class="reference external" href="http://www.python.org">Python</a> bindings for C and
+C++ libraries. SIP was originally developed in 1998 for
+<a class="reference external" href="http://www.riverbankcomputing.com/software/pyqt">PyQt</a> - the Python
+bindings for the Qt GUI toolkit - but is suitable for generating bindings for
+any C or C++ library.</p>
+<p>This version of SIP generates bindings for Python v2.3 or later, including
+Python v3.</p>
+<p>There are many other similar tools available. One of the original such tools
+is <a class="reference external" href="http://www.swig.org">SWIG</a> and, in fact, SIP is so called because it
+started out as a small SWIG. Unlike SWIG, SIP is specifically designed for
+bringing together Python and C/C++ and goes to great lengths to make the
+integration as tight as possible.</p>
+<p>The homepage for SIP is <a class="reference external" href="http://www.riverbankcomputing.com/software/sip">http://www.riverbankcomputing.com/software/sip</a>. Here
+you will always find the latest stable version and the latest version of this
+documentation.</p>
+<p>SIP can also be downloaded from the
+<a class="reference external" href="http://mercurial.selenic.com/">Mercurial</a> repository at
+<a class="reference external" href="http://www.riverbankcomputing.com/hg/sip">http://www.riverbankcomputing.com/hg/sip</a>.</p>
+<div class="section" id="license">
+<h2>License<a class="headerlink" href="#license" title="Permalink to this headline">¶</a></h2>
+<p>SIP is licensed under similar terms as Python itself. SIP is also licensed
+under the GPL (both v2 and v3). It is your choice as to which license you
+use. If you choose the GPL then any bindings you create must be distributed
+under the terms of the GPL.</p>
+</div>
+<div class="section" id="features">
+<h2>Features<a class="headerlink" href="#features" title="Permalink to this headline">¶</a></h2>
+<p>SIP, and the bindings it produces, have the following features:</p>
+<ul class="simple">
+<li>bindings are fast to load and minimise memory consumption especially when
+only a small sub-set of a large library is being used</li>
+<li>automatic conversion between standard Python and C/C++ data types</li>
+<li>overloading of functions and methods with different argument signatures</li>
+<li>support for Python&#8217;s keyword argument syntax</li>
+<li>support for both explicitly specified and automatically generated docstrings</li>
+<li>access to a C++ class&#8217;s protected methods</li>
+<li>the ability to define a Python class that is a sub-class of a C++ class,
+including abstract C++ classes</li>
+<li>Python sub-classes can implement the <tt class="xref docutils literal"><span class="pre">__dtor__()</span></tt> method which will be
+called from the C++ class&#8217;s virtual destructor</li>
+<li>support for ordinary C++ functions, class methods, static class methods,
+virtual class methods and abstract class methods</li>
+<li>the ability to re-implement C++ virtual and abstract methods in Python</li>
+<li>support for global and class variables</li>
+<li>support for global and class operators</li>
+<li>support for C++ namespaces</li>
+<li>support for C++ templates</li>
+<li>support for C++ exceptions and wrapping them as Python exceptions</li>
+<li>the automatic generation of complementary rich comparison slots</li>
+<li>support for deprecation warnings</li>
+<li>the ability to define mappings between C++ classes and similar Python data
+types that are automatically invoked</li>
+<li>the ability to automatically exploit any available run time type information
+to ensure that the class of a Python instance object matches the class of the
+corresponding C++ instance</li>
+<li>the ability to change the type and meta-type of the Python object used to
+wrap a C/C++ data type</li>
+<li>full support of the Python global interpreter lock, including the ability to
+specify that a C++ function of method may block, therefore allowing the lock
+to be released and other Python threads to run</li>
+<li>support for consolidated modules where the generated wrapper code for a
+number of related modules may be included in a single, possibly private,
+module</li>
+<li>support for the concept of ownership of a C++ instance (i.e. what part of the
+code is responsible for calling the instance&#8217;s destructor) and how the
+ownership may change during the execution of an application</li>
+<li>the ability to generate bindings for a C++ class library that itself is built
+on another C++ class library which also has had bindings generated so that
+the different bindings integrate and share code properly</li>
+<li>a sophisticated versioning system that allows the full lifetime of a C++
+class library, including any platform specific or optional features, to be
+described in a single set of specification files</li>
+<li>the ability to include documentation in the specification files which can be
+extracted and subsequently processed by external tools</li>
+<li>the ability to include copyright notices and licensing information in the
+specification files that is automatically included in all generated source
+code</li>
+<li>a build system, written in Python, that you can extend to configure, compile
+and install your own bindings without worrying about platform specific issues</li>
+<li>support for building your extensions using distutils</li>
+<li>SIP, and the bindings it produces, runs under UNIX, Linux, Windows and
+MacOS/X</li>
+</ul>
+</div>
+<div class="section" id="sip-components">
+<h2>SIP Components<a class="headerlink" href="#sip-components" title="Permalink to this headline">¶</a></h2>
+<p>SIP comprises a number of different components.</p>
+<ul class="simple">
+<li>The SIP code generator (<strong>sip</strong>). This processes <tt class="docutils literal"><span class="pre">.sip</span></tt>
+specification files and generates C or C++ bindings. It is covered in detail
+in <a class="reference external" href="using.html#ref-using"><em>Using SIP</em></a>.</li>
+<li>The SIP header file (<tt class="docutils literal"><span class="pre">sip.h</span></tt>). This contains definitions and data
+structures needed by the generated C and C++ code.</li>
+<li>The SIP module (<tt class="docutils literal"><span class="pre">sip.so</span></tt> or <tt class="docutils literal"><span class="pre">sip.pyd</span></tt>). This is a Python
+extension module that is imported automatically by SIP generated bindings and
+provides them with some common utility functions. See also
+<a class="reference external" href="python_api.html#ref-python-api"><em>Python API for Applications</em></a>.</li>
+<li>The SIP build system (<tt class="docutils literal"><span class="pre">sipconfig.py</span></tt>). This is a pure Python module
+that is created when SIP is configured and encapsulates all the necessary
+information about your system including relevant directory names, compiler
+and linker flags, and version numbers. It also includes several Python
+classes and functions which help you write configuration scripts for your own
+bindings. It is covered in detail in <a class="reference external" href="build_system.html#ref-build-system"><em>The Build System</em></a>.</li>
+<li>The SIP distutils extension (<tt class="docutils literal"><span class="pre">sipdistutils.py</span></tt>). This is a distutils
+extension that can be used to build your extension modules using distutils
+and is an alternative to writing configuration scripts with the SIP build
+system. This can be as simple as adding your .sip files to the list of files
+needed to build the extension module. It is covered in detail in
+<a class="reference external" href="distutils.html#ref-distutils"><em>Building Your Extension with distutils</em></a>.</li>
+</ul>
+</div>
+<div class="section" id="qt-support">
+<h2>Qt Support<a class="headerlink" href="#qt-support" title="Permalink to this headline">¶</a></h2>
+<p>SIP has specific support for the creation of bindings based on Nokia&#8217;s Qt
+toolkit.</p>
+<p>The SIP code generator understands the signal/slot type safe callback mechanism
+that Qt uses to connect objects together. This allows applications to define
+new Python signals, and allows any Python callable object to be used as a slot.</p>
+<p>SIP itself does not require Qt to be installed.</p>
+</div>
+</div>
+
+
+ </div>
+ </div>
+ </div>
+ <div class="sphinxsidebar">
+ <div class="sphinxsidebarwrapper">
+ <h3><a href="index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference external" href="#">Introduction</a><ul>
+<li><a class="reference external" href="#license">License</a></li>
+<li><a class="reference external" href="#features">Features</a></li>
+<li><a class="reference external" href="#sip-components">SIP Components</a></li>
+<li><a class="reference external" href="#qt-support">Qt Support</a></li>
+</ul>
+</li>
+</ul>
+
+ <h4>Previous topic</h4>
+ <p class="topless"><a href="index.html"
+ title="previous chapter">SIP Reference Guide</a></p>
+ <h4>Next topic</h4>
+ <p class="topless"><a href="incompatibilities.html"
+ title="next chapter">Potential Incompatibilities with Earlier Versions</a></p>
+ <div id="searchbox" style="display: none">
+ <h3>Quick search</h3>
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" size="18" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ <p class="searchtip" style="font-size: 90%">
+ Enter search terms or a module, class or function name.
+ </p>
+ </div>
+ <script type="text/javascript">$('#searchbox').show(0);</script>
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ >modules</a> |</li>
+ <li class="right" >
+ <a href="incompatibilities.html" title="Potential Incompatibilities with Earlier Versions"
+ >next</a> |</li>
+ <li class="right" >
+ <a href="index.html" title="SIP Reference Guide"
+ >previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+ <div class="footer">
+ &copy; Copyright 2010 Riverbank Computing Limited.
+ Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.4.
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/modindex.html b/doc/html/modindex.html
new file mode 100644
index 0000000..2548832
--- /dev/null
+++ b/doc/html/modindex.html
@@ -0,0 +1,107 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>Global Module Index &mdash; SIP 4.10.5 Reference Guide</title>
+ <link rel="stylesheet" href="_static/default.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '#',
+ VERSION: '4.10.5',
+ COLLAPSE_MODINDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="top" title="SIP 4.10.5 Reference Guide" href="index.html" />
+
+
+ <script type="text/javascript">
+ DOCUMENTATION_OPTIONS.COLLAPSE_MODINDEX = true;
+ </script>
+
+
+ </head>
+ <body>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="#" title="Global Module Index"
+ accesskey="M">modules</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+ <div class="body">
+
+
+ <h1 id="global-module-index">Global Module Index</h1>
+ <a href="#cap-S"><strong>S</strong></a>
+ <hr/>
+
+ <table width="100%" class="indextable" cellspacing="0" cellpadding="2"><tr class="pcap"><td></td><td>&nbsp;</td><td></td></tr>
+ <tr class="cap"><td></td><td><a name="cap-S"><strong>S</strong></a></td><td></td></tr><tr>
+ <td></td>
+ <td>
+ <a href="python_api.html#module-sip"><tt class="xref">sip</tt></a></td><td>
+ <em></em></td></tr><tr>
+ <td></td>
+ <td>
+ <a href="build_system.html#module-sipconfig"><tt class="xref">sipconfig</tt></a></td><td>
+ <em></em></td></tr>
+ </table>
+
+
+ </div>
+ </div>
+ </div>
+ <div class="sphinxsidebar">
+ <div class="sphinxsidebarwrapper">
+ <div id="searchbox" style="display: none">
+ <h3>Quick search</h3>
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" size="18" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ <p class="searchtip" style="font-size: 90%">
+ Enter search terms or a module, class or function name.
+ </p>
+ </div>
+ <script type="text/javascript">$('#searchbox').show(0);</script>
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="#" title="Global Module Index"
+ >modules</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+ <div class="footer">
+ &copy; Copyright 2010 Riverbank Computing Limited.
+ Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.4.
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/objects.inv b/doc/html/objects.inv
new file mode 100644
index 0000000..c3c7a2d
--- /dev/null
+++ b/doc/html/objects.inv
@@ -0,0 +1,214 @@
+# Sphinx inventory version 1
+# Project: SIP
+# Version: 4.10.5
+sipconfig mod build_system.html
+sip mod python_api.html
+sipGetState cfunction c_api.html
+sipconfig.Makefile.optional_list method build_system.html
+sip.unwrapinstance function python_api.html
+SIP_VERSION cmacro c_api.html
+sipCanConvertToInstance cfunction c_api.html
+sipconfig.Makefile.__init__ method build_system.html
+sipconfig.Makefile.optional_string method build_system.html
+sipconfig.ProgramMakefile.__init__ method build_system.html
+sip.voidptr.__hex__ method python_api.html
+sipconfig.PythonModuleMakefile.__init__ method build_system.html
+sipconfig.Makefile.extra_libs attribute build_system.html
+sipconfig.Configuration.py_lib_dir attribute build_system.html
+sip.isdeleted function python_api.html
+sipFindMappedType cfunction c_api.html
+SIP_API_MAJOR_NR cmacro c_api.html
+sipLong_AsUnsignedLong cfunction c_api.html
+sipTransferTo cfunction c_api.html
+sipConvertFromEnum cfunction c_api.html
+sipconfig.create_wrapper function build_system.html
+sipconfig.Configuration.py_inc_dir attribute build_system.html
+sipIntTypeClassMap ctype c_api.html
+dd_name cmember annotations.html
+sipconfig.ProgramMakefile.generate_target_default method build_system.html
+sipconfig.SIPModuleMakefile class build_system.html
+sipconfig.Configuration.default_bin_dir attribute build_system.html
+sipconfig.ProgramMakefile.build_command method build_system.html
+sipconfig.ModuleMakefile.generate_target_install method build_system.html
+sipconfig.Configuration.build_macros method build_system.html
+sipconfig.Configuration.__init__ method build_system.html
+sipconfig.Makefile.generate method build_system.html
+sipReleaseType cfunction c_api.html
+sip.transferback function python_api.html
+sip.voidptr.asstring method python_api.html
+SIP_NO_CONVERTORS cmacro c_api.html
+sipconfig.Makefile.install_file method build_system.html
+sipResolveTypedef cfunction c_api.html
+sipTypeName cfunction c_api.html
+sipConvertToInstance cfunction c_api.html
+sip.voidptr.__int__ method python_api.html
+sipconfig.Makefile.finalise method build_system.html
+sipconfig.format function build_system.html
+sipMapIntToClass cfunction c_api.html
+sipconfig.SIPModuleMakefile.finalise method build_system.html
+sipconfig.Makefile.config attribute build_system.html
+sipFindType cfunction c_api.html
+sipconfig.Configuration.py_conf_inc_dir attribute build_system.html
+sipWrapperType ctype c_api.html
+sipConvertFromType cfunction c_api.html
+sipconfig.inform function build_system.html
+sipconfig.Makefile.extra_cflags attribute build_system.html
+sipconfig.ProgramMakefile.generate_macros_and_rules method build_system.html
+sipTypeIsEnum cfunction c_api.html
+sipconfig.ParentMakefile.generate_target_default method build_system.html
+sipSimpleWrapper_Type cvar c_api.html
+sipconfig.ModuleMakefile.generate_target_clean method build_system.html
+sipconfig.ParentMakefile class build_system.html
+sipForceConvertToMappedType cfunction c_api.html
+sipconfig.Makefile.rm attribute build_system.html
+sipconfig.Makefile.generator attribute build_system.html
+sipTypeIsNamespace cfunction c_api.html
+sipconfig.Makefile.generate_target_default method build_system.html
+sipCanConvertToType cfunction c_api.html
+sipconfig.Configuration.universal attribute build_system.html
+sipConvertFromConstVoidPtrAndSize cfunction c_api.html
+sipconfig.Makefile.platform_lib method build_system.html
+typeString cmember c_api.html
+sip.voidptr.__init__ method python_api.html
+sipTypeIsMapped cfunction c_api.html
+sipconfig.Configuration.set_build_macros method build_system.html
+sipconfig.Makefile.mkdir attribute build_system.html
+sipForceConvertToType cfunction c_api.html
+sipconfig.ParentMakefile.generate_macros_and_rules method build_system.html
+dd_next cmember annotations.html
+sip.voidptr.ascapsule method python_api.html
+sip.SIP_VERSION_STR data python_api.html
+sipExportSymbol cfunction c_api.html
+sipconfig.Configuration.sip_version_str attribute build_system.html
+sipconfig.version_to_sip_tag function build_system.html
+sipconfig.PythonModuleMakefile.generate_macros_and_rules method build_system.html
+sipconfig.Makefile.extra_lflags attribute build_system.html
+sipBadLengthForSlice cfunction c_api.html
+sipConvertToMappedType cfunction c_api.html
+sipconfig.version_to_string function build_system.html
+sipconfig.ProgramMakefile.generate_target_clean method build_system.html
+sipTypeAsPyTypeObject cfunction c_api.html
+sipIsAPIEnabled cfunction c_api.html
+sipconfig.Makefile.extra_lib_dirs attribute build_system.html
+dd_ptr cmember annotations.html
+sipconfig.PythonModuleMakefile class build_system.html
+sipconfig.error function build_system.html
+sip.voidptr.getwriteable method python_api.html
+sipconfig.Makefile.generate_target_clean method build_system.html
+sipForceConvertToInstance cfunction c_api.html
+sipConvertFromVoidPtrAndSize cfunction c_api.html
+sipconfig.Makefile.extra_cxxflags attribute build_system.html
+sip.wrapinstance function python_api.html
+sip.voidptr.getsize method python_api.html
+sipconfig.ProgramMakefile class build_system.html
+sip.wrappertype class python_api.html
+sipReleaseMappedType cfunction c_api.html
+sipStringTypeClassMap ctype c_api.html
+sipconfig.Makefile.extra_defines attribute build_system.html
+SIP_API_MINOR_NR cmacro c_api.html
+sipconfig.Configuration class build_system.html
+sipconfig.Makefile.generate_macros_and_rules method build_system.html
+sipFree cfunction c_api.html
+sip.voidptr.ascobject method python_api.html
+sipVoidPtr_Type cvar c_api.html
+sipconfig.ParentMakefile.__init__ method build_system.html
+sipconfig.Makefile.ready method build_system.html
+sipconfig.Makefile.required_string method build_system.html
+sipRegisterAttributeGetter cfunction c_api.html
+sip.ispyowned function python_api.html
+sipconfig.ParentMakefile.generate_target_install method build_system.html
+sipSimpleWrapper ctype c_api.html
+sipconfig.Configuration.default_mod_dir attribute build_system.html
+SIP_NOT_NONE cmacro c_api.html
+sipConvertFromNewType cfunction c_api.html
+sipTypeFromPyTypeObject cfunction c_api.html
+SIP_PROTECTED_IS_PUBLIC cmacro c_api.html
+sipconfig.ModuleMakefile.__init__ method build_system.html
+sipconfig.Configuration.sip_bin attribute build_system.html
+SIP_VERSION_STR cmacro c_api.html
+sipConvertToType cfunction c_api.html
+sipconfig.Makefile.generate_target_install method build_system.html
+sipClassName cfunction c_api.html
+sip.voidptr.setsize method python_api.html
+sipDelayedDtor ctype annotations.html
+sipconfig.SIPModuleMakefile.__init__ method build_system.html
+sipconfig.Configuration.sip_inc_dir attribute build_system.html
+sipconfig.parse_build_macros function build_system.html
+sipConvertFromInstance cfunction c_api.html
+sipconfig.Configuration.py_version attribute build_system.html
+sipWrapperType_Type cvar c_api.html
+sipConvertFromNewInstance cfunction c_api.html
+sipTransferBack cfunction c_api.html
+sipconfig.Configuration.default_sip_dir attribute build_system.html
+sipConvertFromMappedType cfunction c_api.html
+sipconfig.Configuration.sip_version attribute build_system.html
+sipWrapper_Type cvar c_api.html
+sipconfig.ModuleMakefile.finalise method build_system.html
+sipconfig.Configuration.sip_config_args attribute build_system.html
+dd_isderived cmember annotations.html
+sipconfig.read_version function build_system.html
+sipConvertFromConstVoidPtr cfunction c_api.html
+sipTypeIsClass cfunction c_api.html
+sipBadCatcherResult cfunction c_api.html
+sip.delete function python_api.html
+sipGetPyObject cfunction c_api.html
+sipconfig.Makefile class build_system.html
+SIP_UNBLOCK_THREADS cmacro c_api.html
+sipReleaseInstance cfunction c_api.html
+sip.transferto function python_api.html
+sip.voidptr.setwriteable method python_api.html
+sipconfig.ProgramMakefile.generate_target_install method build_system.html
+sipconfig.create_config_module function build_system.html
+sipWrapper_Check cfunction c_api.html
+sipConvertFromSequenceIndex cfunction c_api.html
+sipTransferBreak cfunction c_api.html
+typeInt cmember c_api.html
+sipMapStringToClass cfunction c_api.html
+sipConvertFromSliceObject cfunction c_api.html
+sipTypeScope cfunction c_api.html
+sipImportSymbol cfunction c_api.html
+sipconfig.Configuration.platform attribute build_system.html
+sipconfig.ModuleMakefile.module_as_lib method build_system.html
+sipconfig.PythonModuleMakefile.generate_target_install method build_system.html
+sip.getapi function python_api.html
+sip.cast function python_api.html
+sip.voidptr class python_api.html
+sipconfig.Makefile.chkdir attribute build_system.html
+sipDelayedDtors cfunction annotations.html
+sipRegisterPyType cfunction c_api.html
+sipconfig.Makefile.clean_build_file_objects method build_system.html
+sipconfig.Makefile.parse_build_file method build_system.html
+sipconfig.create_content function build_system.html
+sipConvertFromNamedEnum cfunction c_api.html
+SIP_BLOCK_THREADS cmacro c_api.html
+sipconfig.Makefile.copy attribute build_system.html
+sip.setdeleted function python_api.html
+sip.setapi function python_api.html
+sipconfig.ParentMakefile.generate_target_clean method build_system.html
+sipconfig.Makefile.extra_include_dirs attribute build_system.html
+sipGetWrapper cfunction c_api.html
+sipconfig.ModuleMakefile.generate_target_default method build_system.html
+sipconfig.ProgramMakefile.finalise method build_system.html
+sipBadCallableArg cfunction c_api.html
+sipMalloc cfunction c_api.html
+sipFindNamedEnum cfunction c_api.html
+user cmember c_api.html
+sipCanConvertToEnum cfunction c_api.html
+sipconfig.Makefile.console attribute build_system.html
+sipCanConvertToMappedType cfunction c_api.html
+sipWrapper ctype c_api.html
+sip.wrapper class python_api.html
+sipCallMethod cfunction c_api.html
+sipconfig.Configuration.arch attribute build_system.html
+sip.SIP_VERSION data python_api.html
+sipParseResult cfunction c_api.html
+sipBuildResult cfunction c_api.html
+sip.settracemask function python_api.html
+sipFindClass cfunction c_api.html
+sipconfig.ModuleMakefile class build_system.html
+sipconfig.ModuleMakefile.generate_macros_and_rules method build_system.html
+sipconfig.Configuration.sip_mod_dir attribute build_system.html
+sipConvertToVoidPtr cfunction c_api.html
+sip.dump function python_api.html
+SIP_SSIZE_T cmacro c_api.html
+sipConvertFromVoidPtr cfunction c_api.html
diff --git a/doc/html/python_api.html b/doc/html/python_api.html
new file mode 100644
index 0000000..633ac2a
--- /dev/null
+++ b/doc/html/python_api.html
@@ -0,0 +1,528 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>Python API for Applications &mdash; SIP 4.10.5 Reference Guide</title>
+ <link rel="stylesheet" href="_static/default.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '#',
+ VERSION: '4.10.5',
+ COLLAPSE_MODINDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="top" title="SIP 4.10.5 Reference Guide" href="index.html" />
+ <link rel="next" title="The Build System" href="build_system.html" />
+ <link rel="prev" title="Using the C API when Embedding" href="embedding.html" />
+ </head>
+ <body>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ accesskey="M">modules</a> |</li>
+ <li class="right" >
+ <a href="build_system.html" title="The Build System"
+ accesskey="N">next</a> |</li>
+ <li class="right" >
+ <a href="embedding.html" title="Using the C API when Embedding"
+ accesskey="P">previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+ <div class="body">
+
+ <div class="section" id="module-sip">
+<span id="ref-python-api"></span><h1>Python API for Applications<a class="headerlink" href="#module-sip" title="Permalink to this headline">¶</a></h1>
+<p>The main purpose of the <tt class="xref docutils literal"><span class="pre">sip</span></tt> module is to provide functionality common to
+all SIP generated bindings. It is loaded automatically and most of the time
+you will completely ignore it. However, it does expose some functionality that
+can be used by applications.</p>
+<dl class="function">
+<dt id="sip.cast">
+<tt class="descclassname">sip.</tt><tt class="descname">cast</tt><big>(</big><em>obj</em>, <em>type</em><big>)</big> &rarr; object<a class="headerlink" href="#sip.cast" title="Permalink to this definition">¶</a></dt>
+<dd><p>This does the Python equivalent of casting a C++ instance to one of its
+sub or super-class types.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>obj</em> &#8211; the Python object.</li>
+<li><em>type</em> &#8211; the type.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">a new Python object is that wraps the same C++ instance as <em>obj</em>, but
+has the type <em>type</em>.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="sip.delete">
+<tt class="descclassname">sip.</tt><tt class="descname">delete</tt><big>(</big><em>obj</em><big>)</big><a class="headerlink" href="#sip.delete" title="Permalink to this definition">¶</a></dt>
+<dd><p>For C++ instances this calls the C++ destructor. For C structures it
+returns the structure&#8217;s memory to the heap.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>obj</em> &#8211; the Python object.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="sip.dump">
+<tt class="descclassname">sip.</tt><tt class="descname">dump</tt><big>(</big><em>obj</em><big>)</big><a class="headerlink" href="#sip.dump" title="Permalink to this definition">¶</a></dt>
+<dd><p>This displays various bits of useful information about the internal state
+of the Python object that wraps a C++ instance or C structure.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>obj</em> &#8211; the Python object.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="sip.getapi">
+<tt class="descclassname">sip.</tt><tt class="descname">getapi</tt><big>(</big><em>name</em><big>)</big> &rarr; version<a class="headerlink" href="#sip.getapi" title="Permalink to this definition">¶</a></dt>
+<dd><p>
+<span class="versionmodified">New in version 4.9.</span></p>
+<p>This returns the version number that has been set for an API. The version
+number is either set explicitly by a call to <a title="sip.setapi" class="reference internal" href="#sip.setapi"><tt class="xref docutils literal"><span class="pre">sip.setapi()</span></tt></a> or
+implicitly by importing the module that defines it.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>name</em> &#8211; the name of the API.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">The version number that has been set for the API. An exception will
+be raised if the API is unknown.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="sip.isdeleted">
+<tt class="descclassname">sip.</tt><tt class="descname">isdeleted</tt><big>(</big><em>obj</em><big>)</big> &rarr; bool<a class="headerlink" href="#sip.isdeleted" title="Permalink to this definition">¶</a></dt>
+<dd><p>This checks if the C++ instance or C structure has been deleted and
+returned to the heap.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>obj</em> &#8211; the Python object.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="xref docutils literal"><span class="pre">True</span></tt> if the C/C++ instance has been deleted.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="sip.ispyowned">
+<tt class="descclassname">sip.</tt><tt class="descname">ispyowned</tt><big>(</big><em>obj</em><big>)</big> &rarr; bool<a class="headerlink" href="#sip.ispyowned" title="Permalink to this definition">¶</a></dt>
+<dd><p>This checks if the C++ instance or C structure is owned by Python.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>obj</em> &#8211; the Python object.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="xref docutils literal"><span class="pre">True</span></tt> if the C/C++ instance is owned by Python.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="sip.setapi">
+<tt class="descclassname">sip.</tt><tt class="descname">setapi</tt><big>(</big><em>name</em>, <em>version</em><big>)</big><a class="headerlink" href="#sip.setapi" title="Permalink to this definition">¶</a></dt>
+<dd><p>
+<span class="versionmodified">New in version 4.9.</span></p>
+<p>This sets the version number of an API. An exception is raised if a
+different version number has already been set, either explicitly by a
+previous call, or implicitly by importing the module that defines it.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><em>name</em> &#8211; the name of the API.</li>
+<li><em>version</em> &#8211; The version number to set for the API. Version numbers must be
+greater than or equal to 1.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="sip.setdeleted">
+<tt class="descclassname">sip.</tt><tt class="descname">setdeleted</tt><big>(</big><em>obj</em><big>)</big><a class="headerlink" href="#sip.setdeleted" title="Permalink to this definition">¶</a></dt>
+<dd><p>This marks the C++ instance or C structure as having been deleted and
+returned to the heap so that future references to it raise an exception
+rather than cause a program crash. Normally SIP handles such things
+automatically, but there may be circumstances where this isn&#8217;t possible.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>obj</em> &#8211; the Python object.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="function">
+<dt id="sip.settracemask">
+<tt class="descclassname">sip.</tt><tt class="descname">settracemask</tt><big>(</big><em>mask</em><big>)</big><a class="headerlink" href="#sip.settracemask" title="Permalink to this definition">¶</a></dt>
+<dd><p>If the bindings have been created with SIP&#8217;s <a class="reference external" href="command_line.html#cmdoption-sip-r"><em class="xref">-r</em></a> command
+line option then the generated code will include debugging statements that
+trace the execution of the code. (It is particularly useful when trying to
+understand the operation of a C++ library&#8217;s virtual function calls.)</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>mask</em> &#8211; the mask that determines which debugging statements are enabled.</td>
+</tr>
+</tbody>
+</table>
+<p>Debugging statements are generated at the following points:</p>
+<ul class="simple">
+<li>in a C++ virtual function (<em>mask</em> is <tt class="docutils literal"><span class="pre">0x0001</span></tt>)</li>
+<li>in a C++ constructor (<em>mask</em> is <tt class="docutils literal"><span class="pre">0x0002</span></tt>)</li>
+<li>in a C++ destructor (<em>mask</em> is <tt class="docutils literal"><span class="pre">0x0004</span></tt>)</li>
+<li>in a Python type&#8217;s __init__ method (<em>mask</em> is <tt class="docutils literal"><span class="pre">0x0008</span></tt>)</li>
+<li>in a Python type&#8217;s __del__ method (<em>mask</em> is <tt class="docutils literal"><span class="pre">0x0010</span></tt>)</li>
+<li>in a Python type&#8217;s ordinary method (<em>mask</em> is <tt class="docutils literal"><span class="pre">0x0020</span></tt>).</li>
+</ul>
+<p>By default the trace mask is zero and all debugging statements are
+disabled.</p>
+</dd></dl>
+
+<dl class="data">
+<dt id="sip.SIP_VERSION">
+<tt class="descclassname">sip.</tt><tt class="descname">SIP_VERSION</tt><a class="headerlink" href="#sip.SIP_VERSION" title="Permalink to this definition">¶</a></dt>
+<dd>This is a Python integer object that represents the SIP version number as
+a 3 part hexadecimal number (e.g. v4.0.0 is represented as <tt class="docutils literal"><span class="pre">0x040000</span></tt>).
+It was first implemented in SIP v4.2.</dd></dl>
+
+<dl class="data">
+<dt id="sip.SIP_VERSION_STR">
+<tt class="descclassname">sip.</tt><tt class="descname">SIP_VERSION_STR</tt><a class="headerlink" href="#sip.SIP_VERSION_STR" title="Permalink to this definition">¶</a></dt>
+<dd>This is a Python string object that defines the SIP version number as
+represented as a string. For development snapshots it will start with
+<tt class="docutils literal"><span class="pre">snapshot-</span></tt>. It was first implemented in SIP v4.3.</dd></dl>
+
+<dl class="function">
+<dt id="sip.transferback">
+<tt class="descclassname">sip.</tt><tt class="descname">transferback</tt><big>(</big><em>obj</em><big>)</big><a class="headerlink" href="#sip.transferback" title="Permalink to this definition">¶</a></dt>
+<dd>This function is a wrapper around <a title="sipTransferBack" class="reference external" href="c_api.html#sipTransferBack"><tt class="xref docutils literal"><span class="pre">sipTransferBack()</span></tt></a>.</dd></dl>
+
+<dl class="function">
+<dt id="sip.transferto">
+<tt class="descclassname">sip.</tt><tt class="descname">transferto</tt><big>(</big><em>obj</em>, <em>owner</em><big>)</big><a class="headerlink" href="#sip.transferto" title="Permalink to this definition">¶</a></dt>
+<dd>This function is a wrapper around <a title="sipTransferTo" class="reference external" href="c_api.html#sipTransferTo"><tt class="xref docutils literal"><span class="pre">sipTransferTo()</span></tt></a>.</dd></dl>
+
+<dl class="function">
+<dt id="sip.unwrapinstance">
+<tt class="descclassname">sip.</tt><tt class="descname">unwrapinstance</tt><big>(</big><em>obj</em><big>)</big> &rarr; integer<a class="headerlink" href="#sip.unwrapinstance" title="Permalink to this definition">¶</a></dt>
+<dd><p>This returns the address, as an integer, of a wrapped C/C++ structure or
+class instance.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>obj</em> &#8211; the Python object.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">an integer that is the address of the C/C++ instance.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="class">
+<dt id="sip.voidptr">
+<em class="property">class </em><tt class="descclassname">sip.</tt><tt class="descname">voidptr</tt><a class="headerlink" href="#sip.voidptr" title="Permalink to this definition">¶</a></dt>
+<dd><p>This is the type object for the type SIP uses to represent a C/C++
+<tt class="docutils literal"><span class="pre">void</span> <span class="pre">*</span></tt>. It may have a size associated with the address in which case
+the Python buffer protocol is supported. This means that the memory can
+be treated as a mutable array of bytes when wrapped with the <tt class="docutils literal"><span class="pre">buffer()</span></tt>
+builtin. The type has the following methods.</p>
+<dl class="method">
+<dt id="sip.voidptr.__init__">
+<tt class="descname">__init__</tt><big>(</big><em>address</em><span class="optional">[</span>, <em>size=-1</em><span class="optional">[</span>, <em>writeable=True</em><span class="optional">]</span><span class="optional">]</span><big>)</big><a class="headerlink" href="#sip.voidptr.__init__" title="Permalink to this definition">¶</a></dt>
+<dd><table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><em>address</em> &#8211; the address, either another <a title="sip.voidptr" class="reference internal" href="#sip.voidptr"><tt class="xref docutils literal"><span class="pre">sip.voidptr</span></tt></a>, <tt class="xref docutils literal"><span class="pre">None</span></tt>, a
+Python Capsule, a Python CObject, or an integer.</li>
+<li><em>size</em> &#8211; the optional associated size of the block of memory and is negative
+if the size is not known.</li>
+<li><em>writeable</em> &#8211; set if the memory is writeable. If it is not specified, and
+<em>address</em> is a <a title="sip.voidptr" class="reference internal" href="#sip.voidptr"><tt class="xref docutils literal"><span class="pre">sip.voidptr</span></tt></a> instance then its value will be
+used.</li>
+</ul>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sip.voidptr.__int__">
+<tt class="descname">__int__</tt><big>(</big><big>)</big> &rarr; integer<a class="headerlink" href="#sip.voidptr.__int__" title="Permalink to this definition">¶</a></dt>
+<dd><p>This returns the address as an integer.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the integer address.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sip.voidptr.__hex__">
+<tt class="descname">__hex__</tt><big>(</big><big>)</big> &rarr; string<a class="headerlink" href="#sip.voidptr.__hex__" title="Permalink to this definition">¶</a></dt>
+<dd><p>This returns the address as a hexadecimal string.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the hexadecimal string address.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sip.voidptr.ascapsule">
+<tt class="descname">ascapsule</tt><big>(</big><big>)</big> &rarr; capsule<a class="headerlink" href="#sip.voidptr.ascapsule" title="Permalink to this definition">¶</a></dt>
+<dd><p>
+<span class="versionmodified">New in version 4.10.</span></p>
+<p>This returns the address as an unnamed Python Capsule. This requires
+Python v3.1 or later or Python v2.7 or later.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the Capsule.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sip.voidptr.ascobject">
+<tt class="descname">ascobject</tt><big>(</big><big>)</big> &rarr; cObject<a class="headerlink" href="#sip.voidptr.ascobject" title="Permalink to this definition">¶</a></dt>
+<dd><p>This returns the address as a Python CObject. This is deprecated with
+Python v3.1 or later.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the CObject.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sip.voidptr.asstring">
+<tt class="descname">asstring</tt><big>(</big><span class="optional">[</span><em>size=-1</em><span class="optional">]</span><big>)</big> &rarr; string/bytes<a class="headerlink" href="#sip.voidptr.asstring" title="Permalink to this definition">¶</a></dt>
+<dd><p>This returns a copy of the block of memory as a Python v2 string object
+or a Python v3 bytes object.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>size</em> &#8211; the number of bytes to copy. If it is negative then the size
+associated with the address is used. If there is no associated
+size then an exception is raised.</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the string or bytes object.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sip.voidptr.getsize">
+<tt class="descname">getsize</tt><big>(</big><big>)</big> &rarr; integer<a class="headerlink" href="#sip.voidptr.getsize" title="Permalink to this definition">¶</a></dt>
+<dd><p>This returns the size associated with the address.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body">the associated size which will be negative if there is none.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sip.voidptr.setsize">
+<tt class="descname">setsize</tt><big>(</big><em>size</em><big>)</big><a class="headerlink" href="#sip.voidptr.setsize" title="Permalink to this definition">¶</a></dt>
+<dd><p>This sets the size associated with the address.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>size</em> &#8211; the size to associate. If it is negative then no size is
+associated.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sip.voidptr.getwriteable">
+<tt class="descname">getwriteable</tt><big>(</big><big>)</big> &rarr; bool<a class="headerlink" href="#sip.voidptr.getwriteable" title="Permalink to this definition">¶</a></dt>
+<dd><p>This returns the writeable state of the memory.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="xref docutils literal"><span class="pre">True</span></tt> if the memory is writeable.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="method">
+<dt id="sip.voidptr.setwriteable">
+<tt class="descname">setwriteable</tt><big>(</big><em>writeable</em><big>)</big><a class="headerlink" href="#sip.voidptr.setwriteable" title="Permalink to this definition">¶</a></dt>
+<dd><p>This sets the writeable state of the memory.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameter:</th><td class="field-body"><em>writeable</em> &#8211; the writeable state to set.</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+</dd></dl>
+
+<dl class="function">
+<dt id="sip.wrapinstance">
+<tt class="descclassname">sip.</tt><tt class="descname">wrapinstance</tt><big>(</big><em>addr</em>, <em>type</em><big>)</big> &rarr; object<a class="headerlink" href="#sip.wrapinstance" title="Permalink to this definition">¶</a></dt>
+<dd><p>This wraps a C structure or C++ class instance in a Python object. If the
+instance has already been wrapped then a new reference to the existing
+object is returned.</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><em>addr</em> &#8211; the address of the instance as a number.</li>
+<li><em>type</em> &#8211; the Python type of the instance.</li>
+</ul>
+</td>
+</tr>
+<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">the Python object that wraps the instance.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</dd></dl>
+
+<dl class="class">
+<dt id="sip.wrapper">
+<em class="property">class </em><tt class="descclassname">sip.</tt><tt class="descname">wrapper</tt><a class="headerlink" href="#sip.wrapper" title="Permalink to this definition">¶</a></dt>
+<dd>This is the type object of the base type of all instances wrapped by SIP.</dd></dl>
+
+<dl class="class">
+<dt id="sip.wrappertype">
+<em class="property">class </em><tt class="descclassname">sip.</tt><tt class="descname">wrappertype</tt><a class="headerlink" href="#sip.wrappertype" title="Permalink to this definition">¶</a></dt>
+<dd>This is the type object of the metatype of the <a title="sip.wrapper" class="reference internal" href="#sip.wrapper"><tt class="xref docutils literal"><span class="pre">sip.wrapper</span></tt></a> type.</dd></dl>
+
+</div>
+
+
+ </div>
+ </div>
+ </div>
+ <div class="sphinxsidebar">
+ <div class="sphinxsidebarwrapper">
+ <h4>Previous topic</h4>
+ <p class="topless"><a href="embedding.html"
+ title="previous chapter">Using the C API when Embedding</a></p>
+ <h4>Next topic</h4>
+ <p class="topless"><a href="build_system.html"
+ title="next chapter">The Build System</a></p>
+ <div id="searchbox" style="display: none">
+ <h3>Quick search</h3>
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" size="18" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ <p class="searchtip" style="font-size: 90%">
+ Enter search terms or a module, class or function name.
+ </p>
+ </div>
+ <script type="text/javascript">$('#searchbox').show(0);</script>
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ >modules</a> |</li>
+ <li class="right" >
+ <a href="build_system.html" title="The Build System"
+ >next</a> |</li>
+ <li class="right" >
+ <a href="embedding.html" title="Using the C API when Embedding"
+ >previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+ <div class="footer">
+ &copy; Copyright 2010 Riverbank Computing Limited.
+ Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.4.
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/search.html b/doc/html/search.html
new file mode 100644
index 0000000..143be9c
--- /dev/null
+++ b/doc/html/search.html
@@ -0,0 +1,97 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>Search &mdash; SIP 4.10.5 Reference Guide</title>
+ <link rel="stylesheet" href="_static/default.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '#',
+ VERSION: '4.10.5',
+ COLLAPSE_MODINDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <script type="text/javascript" src="_static/searchtools.js"></script>
+ <link rel="top" title="SIP 4.10.5 Reference Guide" href="index.html" />
+ </head>
+ <body>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ accesskey="M">modules</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+ <div class="body">
+
+ <h1 id="search-documentation">Search</h1>
+ <div id="fallback" class="admonition warning">
+ <script type="text/javascript">$('#fallback').hide();</script>
+ <p>
+ Please activate JavaScript to enable the search
+ functionality.
+ </p>
+ </div>
+ <p>
+ From here you can search these documents. Enter your search
+ words into the box below and click "search". Note that the search
+ function will automatically search for all of the words. Pages
+ containing fewer words won't appear in the result list.
+ </p>
+ <form action="" method="get">
+ <input type="text" name="q" value="" />
+ <input type="submit" value="search" />
+ <span id="search-progress" style="padding-left: 10px"></span>
+ </form>
+
+ <div id="search-results">
+
+ </div>
+
+ </div>
+ </div>
+ </div>
+ <div class="sphinxsidebar">
+ <div class="sphinxsidebarwrapper">
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ >modules</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+
+ <div class="footer">
+ &copy; Copyright 2010 Riverbank Computing Limited.
+ Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.4.
+ </div>
+ <script type="text/javascript" src="searchindex.js"></script>
+
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/searchindex.js b/doc/html/searchindex.js
new file mode 100644
index 0000000..2099b9d
--- /dev/null
+++ b/doc/html/searchindex.js
@@ -0,0 +1 @@
+Search.setIndex({desctypes:{"0":"cfunction","1":"method","2":"function","3":"cmacro","4":"attribute","5":"ctype","6":"cmember","7":"class","8":"cvar","9":"data"},terms:{sipcanconverttoinst:[9,4],sipconvertfromtyp:[10,4],secondli:13,prefix:[0,13,10,11,4],mkcustom:7,whose:[13,8,4],accur:12,"const":[4,10,11,12,13,8],cmdclass:3,pylist_set_item:10,under:[0,5,10,2],qlabel:13,everi:[0,13],ascapsul:14,"void":[4,14,10,12,13,8],affect:[0,10],"__nonzero__":12,factori:[13,8,4],sip_pydict:[12,8],initialis:[0,13,10],sipconvertfromvoidptrands:4,abil:[0,5],direct:[0,1,4,6,10,12,13,8],second:0,b_mod:10,module_as_lib:0,even:[12,9,10],neg:[0,14,4],qpoint:10,"new":[3,4,5,8,10,12,13,14],net:0,ever:8,sipdisconnectrx:9,getsiz:14,q_os_win:13,mem:4,never:[13,10,8,4],here:[5,12],debugg:8,path:[13,2,3],interpret:[0,1,2,4,5,6,7,10,11,12,13,8],incdir:2,adopt:10,create_cont:0,create_word:13,sip_derived_class:10,mkdir:0,default_sip_dir:[0,13],unix:[0,5,7,13],pythonmodulemakefil:0,total:10,unit:10,describ:[3,4,5,6,7,9,10,12,13,8],would:[13,7,10,8,4],sipregisterattributegett:[13,4],call:[0,2,4,5,6,7,8,9,10,11,12,13,14],python26:2,type:[1,4,5,8,9,10,11,12,13,14],until:[13,8],autogen:8,successful:4,relat:[5,10,2,13],notic:5,warn:[0,5,6,8],"__iter__":12,sipimportsymbol:4,must:[0,2,4,5,6,7,8,9,10,11,12,13,14],join:13,restor:4,arbitari:10,setup:3,work:[0,4,9,10,13,8],sipbadcallablearg:4,root:[10,2],could:[0,13,10],overrid:[0,13,10],give:[13,2],indic:[0,10],want:[0,13,7,8,3],sip_module_dict:11,slicelen:4,unsign:[12,8,4],end:[12,13,10,4],quot:8,ordinari:[5,13,14],how:[2,5,7,10,11,13],answer:13,place:[0,4,6,10,13,8],coff2omf:2,config:[0,13,3],bindir:2,updat:[8,4],after:[0,2,4,10,13,8],sipwrapp:[9,4],"_pkg_config":13,py_buff:10,befor:[0,4,6,10,13,8],wrong:12,nokeywordarg:8,arch:[0,2],parallel:6,demonstr:13,attempt:[10,4],opaqu:[12,4],c_mod:10,exclud:[0,10,8],maintain:[0,13],finalis:[0,13],exclus:[13,10],get_sip_api:11,order:[13,10,8,4],origin:[5,10,8],composit:10,over:[0,10],becaus:[5,13,7,10],privileg:2,keyboard:12,pyerr_setstr:10,delaydtor:8,easier:[0,13,6,4],this_word:13,thei:[0,7,9,10,12,13,8],fragment:[10,11],safe:[5,9,10,4],"break":[13,10],singleshot:8,choic:[5,13,10],bigetreadbuffercod:[12,10],unpickl:10,each:[0,2,4,6,7,10,11,13,8],debug:[0,6,10,2,14],bigetsegcountcod:[12,10],side:10,mean:[0,2,8,9,10,13,14],v1_0:10,v1_1:10,sipcanconverttomappedtyp:[9,4],sipemitslot:9,collector:[13,10,8,4],unbound:8,sip_nameerror:12,goe:5,newli:[13,9,8,4],pycobject:[11,4],content:[0,3,4,10,13,8],pyqtconfig:[0,13],allownon:8,build_fil:[0,13],situat:13,free:[13,2],standard:[2,3,5,7,10,13],"__setitem__":[12,8,4],voidptr:[8,14,4],precompil:10,foo_support:10,extra_cflag:0,v3_0:10,isn:[10,14,4],setwrit:14,"__or__":12,rang:[13,10,8,4],siperr:10,python26_bcpp:2,independ:10,restrict:[7,10,8],hook:3,unlik:[5,13,10],mingw:[0,2],messag:[0,6,2],wasn:4,sip_keyerror:12,iserr:4,top:[0,13],sometim:[12,13,7,8],fiction:13,mercuri:5,too:10,consol:[0,7],namespac:[5,12,10,4],tool:5,lower:[10,8,11,4],sipcanconverttotyp:[10,4],read_vers:0,reinterpret_cast:10,target:0,keyword:[5,10,6,8,13],provid:[0,4,5,6,8,7,10,12,13,14],zero:[0,4,8,7,10,13,14],sipexceptionref:10,matter:[12,13,10],wchar_t:[12,13,4],sip_lookuperror:12,modern:6,increment:[10,4],incompat:[1,4,9,10,13,8],sipwrappertyp:[10,4],pydict_getitemstr:11,simplifi:10,though:9,sipself:10,object:[0,1,4,5,8,9,10,11,12,13,14],lexic:4,letter:4,don:10,doc:[12,10,6],doe:[0,4,5,7,8,9,12,13,14],declar:[4,6,10,12,13,8],unchang:[10,4],dot:[12,10,8],"__str__":12,syntax:[1,5,6,12,13,8],qstring:[13,10],identifi:[10,8,4],siperror:[10,4],involv:4,absolut:0,pystring_fromstr:4,acquir:[13,10,4],configur:[0,1,2,5,7,9,13],sip_build:9,dd_name:8,qwidget:[13,10,8],"__call__":12,stop:4,report:10,bar:13,emb:11,baz:13,method:[0,4,5,6,7,8,9,10,12,13,14],sipclass:10,pyexc_valueerror:10,set_build_macro:0,result:[10,6,8,4],respons:[5,13,9,10,4],fail:[10,4],subject:13,sip_unicodetranslateerror:12,hopefulli:13,simplest:13,sip_zerodivisionerror:12,clean_build_file_object:0,handwritten:[1,4,9,10,11,12,8],accord:[13,7,4],extend:[5,13,10],sip_overflowerror:12,extens:[0,1,3,4,5,13],lazi:[1,13,4],preprocessor:[0,13,9,10,4],rtti:[10,4],protect:[0,4,5,6,7,10,12,13],expos:14,howev:[2,8,10,11,12,13,14],against:[0,13,10],sipfindclass:[9,4],logic:10,fno:2,com:[5,2],create_wrapp:0,seqlen:4,getwrit:14,setapi:[13,14],guid:[5,1],assum:[0,13,2,8,4],three:[0,13],been:[0,2,4,8,9,10,11,12,13,14],much:13,siptypeismap:4,interest:13,q_signal:12,"__len__":[12,8],sipconvertfrominst:[9,4],life:13,suppress:[8,4],argument:[0,1,4,5,6,7,9,10,12,13,8],child:13,"catch":[10,6],riverbankcomput:[5,2],wobj:10,qtcoremod:[13,10],ident:10,visitproc:10,properti:0,weren:9,"__ge__":12,have:[0,2,4,5,7,8,9,10,11,12,13,14],sip_slot_con:12,tabl:4,toolkit:5,sever:[5,4],sipselfwasarg:10,docvalu:8,receiv:12,suggest:13,make:[0,2,4,5,6,7,9,10,12,13,8],export_al:0,bigetbuffercod:[12,10],complex:[1,13],split:[13,6],sipgetsend:9,complet:[10,6,14],sip_api_major_nr:4,"__idiv__":12,rais:[0,13,10,14,4],ownership:[1,4,5,10,13,8],qaccel:12,tune:[0,13,2],redefin:[0,10,6,4],kept:[8,4],siptypeisclass:4,inherit:13,sip_importerror:12,thi:[0,2,4,5,6,7,8,9,10,12,13,14],endif:[13,10],programm:[12,10],everyth:13,left:[0,10,8],sip_keyboardinterrupt:12,protocol:[8,14,4],just:[0,3,4,9,10,13],gctraversecod:[12,10],previous:[9,4],easi:0,had:[5,9],sip_eoferror:12,qtguimod:[13,10],siptypeaspytypeobject:4,els:[13,10],save:4,opt:3,applic:[1,2,4,5,7,10,11,13,14],wai:[13,7,10,4],specif:[0,1,2,4,5,6,9,10,12,13,8],arbitrari:10,"__long__":12,sip_syntaxerror:12,cxxflag:2,underli:[12,8],www:[5,2],pymem_malloc:4,old:[13,9],deal:[12,13,10],sip_indentationerror:12,intern:[12,10,14],indirect:10,successfulli:[10,8],"__iand__":12,sipissubclassinst:9,buffer:[1,4,14,10,13,8],simplewrapp:[13,10,4],foo:[13,10,8],dd_next:8,"__ne__":12,sensibl:10,repositori:5,sipenum_:4,"super":[0,4,8,10,12,13,14],customw:7,pyarg_parsetupl:[12,10,4],py_modulegetdict:10,obj:[9,10,14,4],chronolog:0,"__mul__":12,produc:5,ppc:2,py_decref:10,regist:[13,4],"__dtor__":5,encod:[0,10,8,4],bound:[10,8,4],down:0,right:[0,10,11],"__and__":12,sipcanconverttoenum:4,often:[13,10,11],accordingli:13,suffici:3,segment:[13,10],support:[0,1,2,3,4,5,6,8,9,10,12,13,14],why:[13,10],avail:[2,3,4,5,9,10,12,13],reli:9,extra_cxxflag:0,siptransf:9,siptype_qpoint:10,gil:[10,6,8,13,4],qtcore:[0,10],"__isub__":12,form:[0,6,2,13],forc:8,heap:[13,10,14,4],"true":[12,1,14,8],arrays:8,sipgetpyobject:4,tell:13,sip_except:[12,10],minor:4,hierachi:13,sip_unicodeerror:12,emit:[12,8,4],featur:[0,1,5,6,9,10,12,13,8],initialisationcod:[12,13,10],classic:[12,1],sipforceconverttoinst:[9,4],"abstract":[5,10,8],exist:[0,2,4,6,10,14],trip:12,bmake:0,py_lib_dir:0,when:[0,1,2,4,5,6,8,10,11,12,13,14],test:4,asstr:14,intend:[0,13,10,11],sipenum_klass_enum:4,sipsimplewrapp:[9,10,4],longer:[9,10],sip_pyslic:[12,8],ignor:[0,4,14,10,13,8],sipcppptr:10,time:[0,4,5,6,8,10,13,14],leftmargin:0,sip_attributeerror:12,concept:[5,13],skip:[13,10],global:[1,4,5,6,10,12,13,8],signific:[10,6,8],supplement:10,raisecod:[12,10],"__rshift__":12,depend:[0,2,4,9,10,8],unpack:2,decim:0,riverbank:10,cobject:14,sip_mod_dir:0,sourc:[0,5,6,2,10],string:[0,4,8,10,12,13,14],extra_lib_dir:0,convertfromtypecod:[9,10],"__bool__":12,word:[13,10,11,3,8],exact:[12,13,10,8],administr:2,level:10,did:[0,9],gui:[0,5,7],pylist_new:10,"0x0001":14,sipstringtypeclassmap:4,dir:[0,6,2],prevent:[13,7,10,8,4],core:3,sipvoidptr_typ:4,sign:12,minimis:5,port:2,appear:[10,8],gcclearcod:[12,10],current:[0,13,10,8,4],qscintilla:6,sipdelayeddtor:8,iarr:[12,10],deriv:[0,1,4,7,10,11,12,13,8],gener:[0,1,2,4,5,6,8,9,10,11,12,13,14],explicitli:[2,5,8,9,10,12,13,14],address:[8,10,14,4],"__hex__":14,sip_runtimeerror:12,along:10,"__repr__":12,convertor:[9,4],extra:[0,13,6,8,4],modul:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14],prefer:10,pyobject_typecheck:4,sip_slot_di:12,instal:[0,1,2,5,7,13],sipregisterpytyp:[13,10,4],moduleheadercod:[12,10],memori:[4,5,14,10,13,8],univers:[0,2],visit:10,sipfindnamedenum:[9,4],siptypenam:4,msg:0,scope:[12,10,8,4],siptype_qtimerev:10,sip_pytupl:[12,10,8],scite:6,pyqwt:0,claus:[10,8],templat:[0,5,10,12,13],pyerr_except:10,uniqu:[10,4],descriptor:13,can:[0,2,3,4,5,6,7,8,9,10,11,12,13,14],purpos:[0,10,14,4],encapsul:[0,5],isdelet:14,occur:[0,10,8],alwai:[5,13,10,4],multipl:[10,2,8,13],"__license__":10,sipmalloc:[13,4],sip_protected_is_publ:[10,4],write:[0,4,5,7,10,13],pure:[0,2,5,10,13,8],sip_memoryerror:12,map:[1,4,5,10,12,13,8],"__next__":12,sipmodulemakefil:[0,13],mai:[0,2,4,5,6,8,7,10,12,13,14],underscor:[11,4],data:[5,12,10,11],practic:10,sipcallmethod:[9,10,4],sip_qobject:12,stdin:6,explicit:[12,10,8],inform:[0,5,6,10,12,13,14],"switch":10,preced:[0,8,11],combin:[0,10,4],callabl:[5,12,10],converttosubclasscod:[12,10,4],wrapinst:14,size_t:4,still:[13,9,10,7,8],pointer:[4,9,10,11,12,8],dynam:[13,7],entiti:10,conjunct:[10,8],disconnect:12,platform:[0,2,5,6,10,12,13],window:[0,2,5,6,7,13],main:[10,14],non:[0,4,7,10,13,8],"float":[12,8,4],siplenptr:10,contriv:10,initi:[10,4],qcustomev:10,now:[13,9,10,7],nor:10,introduct:[5,1],pykd:0,term:[5,10],name:[0,1,2,3,4,5,6,8,9,10,11,12,13,14],realist:13,transferback:[13,9,14,8,4],revers:13,revert:9,separ:[0,4,10,12,13,8],sipsimplewrapper_typ:4,sip_pycal:[12,8],compil:[0,2,4,5,6,9,10,12,13],sip_vers:[0,14,4],sip_standarderror:12,replac:[0,2,4,10,11,13],individu:[0,10],continu:10,wrap:[0,4,5,6,8,10,11,12,13,14],sipconvertfromsliceobject:4,happen:13,py_ssize_t:4,shown:10,settracemask:14,sipforceconverttomappedtyp:[9,4],space:0,"0x0010":14,bespok:0,correct:[2,4,7,10,13,8],earlier:[1,9,4],migrat:13,"byte":[8,10,14,4],unpredict:8,care:[0,13],setdefault:13,sipconverttovoidptr:4,thing:[13,10,14],pyslice_getindicesex:4,first:[0,4,6,10,12,13,14],oper:[5,8,9,10,12,13,14],reimplement:[0,10,8,4],directli:[11,4],onc:[2,8,4],arrai:[4,14,10,12,13,8],pyimport_importmodul:11,dump_object:10,open:10,sip_configur:[0,13],size:[0,2,4,6,8,10,14],given:[6,10,2,13,4],silent:10,convent:10,sippi:10,caught:[10,8],convention:13,conveni:[10,4],editor:6,especi:5,copi:[0,4,8,7,10,12,13,14],specifi:[0,2,4,5,8,10,12,13,14],pyqt4:[13,10,8],enclos:[10,6,4],than:[0,2,4,8,7,10,13,14],virtualcatchercod:[12,10,4],wide:[1,13,4],py_vers:0,were:[0,9],posit:[0,8],pre:10,sai:13,ani:[0,2,3,4,5,6,7,9,10,12,13,8],properli:[5,12,13],techniqu:7,sipconvertfromsequenceindex:4,note:[4,7,10,11,12,13,8],take:[0,2,7,10,12,13,8],noth:[12,10],begin:[10,4],sure:[10,2,13,4],trace:[6,14],normal:[0,3,4,7,8,9,10,13,14],multipli:8,sipforceconverttotyp:4,pair:[0,8],homepag:5,later:[5,13,14,4],picklecod:[12,10],show:[10,2,8,11],"0x020303":0,"__irshift__":12,slot:[5,12,8],sipgetst:[10,4],onli:[0,4,5,10,12,13,8],slow:0,activ:12,state:[10,14,4],api_export_symbol:11,dict:[0,4],variou:[2,14,4],get:[0,2,4,10,11,13,8],cannon:0,soon:10,cannot:[12,10,8,11],requir:[0,2,4,5,8,7,10,13,14],mybool:8,borrow:4,pynam:[10,8],hellomodulemakefil:13,where:[0,4,5,10,12,13,14],pytyp:4,prehook:8,sipcpp:[12,10],concern:9,arg_nr:4,detect:[13,10,4],sippytyp:10,accesscod:[12,10],enumer:4,label:13,between:[4,5,10,11,12,13,8],"import":[0,3,4,5,6,7,10,11,12,13,14],across:13,sipwrappercheck:11,parent:13,style:[0,9],cycl:[13,4],setcod:[12,10],come:4,"0x0020":14,programmakefil:0,sipresolvetypedef:4,mani:[5,13,2,8],among:3,acceler:12,undocu:10,period:10,exploit:[5,13,10],colon:8,build_command:0,default_bin_dir:0,mark:14,siparg:10,derefer:10,thousand:13,ascobject:14,sip_indexerror:12,"__eq__":12,those:[0,13,10,8,4],"case":[0,8,10,11,12,13,14],defaultmetatyp:[12,13,10],py_typ:4,"__mod__":12,sip_arithmeticerror:12,cast:[12,9,10,14,4],invok:[0,5,10,3],invoc:8,sipreleasetyp:[10,8,4],margin:0,advantag:10,stdout:0,support_foo:10,them:[0,5,9,10,13],worri:5,myapi:13,ascii:[10,8,4],concatan:8,"__init__":[0,13,7,10,14],develop:[0,2,4,5,13,14],etc:10,same:[0,3,4,7,8,9,10,12,13,14],check:[0,2,4,10,11,14],ispyown:14,binari:[0,10,2,12],html:10,document:[5,10,6,13],metatyp:[13,10,14,8],nest:10,sipmethod:[10,4],footprint:13,appropri:[0,10,2,8,4],macro:[0,13,2,4],without:[0,4,5,10,12,13,8],sipmappedtyp:4,dereferenc:8,"__int__":[12,14],execut:[0,2,5,6,8,10,13,14],tip:6,rest:[10,4],releasegil:[10,6,8,13],siptransferobj:10,tobj:10,struct:[12,13,10],except:[0,1,2,4,5,6,8,10,11,12,13,14],littl:[12,13],real:[12,10],around:[0,4,8,9,10,12,14],read:[0,12,10,8],swig:5,world:13,part:[0,4,5,7,8,9,10,12,13,14],sip_ssize_t:[10,4],saniti:11,whitespac:[13,10],integ:[0,4,14,10,12,8],either:[0,2,3,4,8,10,13,14],output:10,manag:[1,10,8,13,4],wrappertyp:[13,10,14,4],pyconfig:0,ascend:4,slice:[12,4],definit:[1,4,5,10,12,8],siperrorfail:10,sip_assertionerror:12,exit:[0,8],notabl:6,freed:[13,4],mname:0,garbag:[13,10,8,4],cppptr:4,fulli:[0,4],immut:4,"throw":[12,10,8],comparison:[5,9],methodcod:[12,10,8,4],sip_stopiter:12,sipprotectvirt_foo:10,processor:10,slash:8,strip:0,pyobject_callobject:4,your:[0,1,2,3,5,7,9,13],macos_platform:10,generate_target_default:0,fast:5,mingw32:13,area:4,aren:13,hex:8,modulemakefil:[0,7],start:[0,4,5,8,10,13,14],compliant:4,interfac:[1,10,13],prot_is_publ:0,lot:0,timelin:[0,10,6,12,13],"__invert__":12,tupl:[0,12,10,8,4],py_end_allow_thread:[12,10],nmake:13,rightmargin:0,"default":[0,2,6,8,10,12,13,14],pylist_get_s:10,"__le__":12,embed:[1,10,11],deadlock:13,holdgil:[10,6,8,13],expect:[13,9,10,8,4],creat:[0,2,3,4,5,8,7,10,13,14],certain:[10,8,4],a0kei:10,file:[0,1,2,3,4,5,6,7,9,10,11,12,13,8],sip_taberror:12,again:[13,10,8],readi:0,q_object:13,reduct:6,tight:5,valid:[0,13,10,4],pathnam:0,you:[0,2,3,4,5,7,8,9,10,12,13,14],architectur:[0,2],noderiv:8,sequenc:[0,8,4],symbol:[0,10,9,2,4],docstr:[5,10,6,12,8],track:13,reduc:[13,2],directori:[0,2,3,5,6,7,10,13],descript:[0,10,6,12,4],stdexcept:10,py_initmodul:10,potenti:[1,9,10,13],cpp:[6,3,4],dst:0,represent:[0,10],all:[0,2,4,5,6,8,10,12,13,14],unencod:[10,8],capsul:14,sipconvertfrommappedtyp:[9,4],follow:[0,2,3,4,5,7,8,9,10,11,12,13,14],ptr:10,qt_4_2_0:13,"__cmp__":12,program:[0,13,14],sip_ioerror:12,sip_feature_:10,dd_isderiv:8,setdelet:14,introduc:[13,9],sipvisit:10,liter:13,far:9,util:[5,10],mechan:[5,13],fall:4,veri:[13,10],sipcppret:10,list:[0,2,3,5,6,10,12,13,8],posthook:8,siptypescop:4,adjust:0,hello_sip_flag:13,stderr:[0,10],small:[5,13],py_begin_allow_thread:[12,10],py_inc_dir:0,platform_lib:0,ten:13,interpretor:13,pyobject:[12,10,11,4],keeprefer:8,"__truediv__":[12,9],design:[5,8],pass:[0,4,6,7,9,10,11,13,8],what:[5,13,10],sub:[0,2,4,5,8,10,13,14],sipconverttoinst:[9,4],section:[9,10,8,4],abl:7,overload:[5,10],delet:[10,14],version:[0,1,2,3,4,5,6,8,9,10,12,13,14],"public":[0,4,6,10,12,13],hasn:[10,4],full:[0,2,4,5,6,10,12,13],themselv:10,sipfindmappedtyp:[9,4],sophist:5,behaviour:[13,9,10],sip_vmserror:12,modifi:[0,7],valu:[0,2,4,8,7,10,12,13,14],search:[10,6,13],helloconfig:13,"__xor__":12,prior:[9,10,4],amount:[10,8],via:[8,4],deprec:[4,5,8,9,10,14],inappropri:4,sipbadlengthforslic:4,select:13,hexadecim:[0,14,4],win32_platform:10,sip_sign:12,two:[0,2,9,10,12,13],taken:[0,10,4],sip_oserror:12,more:[0,1,2,4,6,10,13,8],desir:[10,8],sip_block_thread:[10,4],c_api:11,hundr:13,ital:10,flag:[0,5,10,13,4],bireleasebuffercod:[12,10],particular:[0,7,9,10,13,8],known:[14,4],destin:0,cach:4,none:[0,13,10,14,8],sipprotect_foo:10,remain:[12,10,4],pylist_check:10,v2_0:10,def:13,share:[5,4],accept:8,sipreleaseinst:[9,4],cours:11,newlin:0,rather:[0,4,8,7,10,13,14],anoth:[0,4,5,8,10,13,14],siperrorcontinu:10,divis:[12,1],sipinttypeclassmap:4,simpl:[0,1,3,5,12,13],referenc:[10,11,4],api_wrapper_check:11,sip_windowserror:12,compulsori:[10,8],sipconfig:[0,5,7,2,13],generate_target_instal:0,associ:[13,8,10,14,4],circumst:14,"short":[12,10,8,4],qtgui:[0,13,10],required_str:0,children:13,caus:[2,4,6,14,13,8],callback:5,help:[0,5,6,2],a_mod:10,i386:2,through:[0,10],hierarchi:[12,13,10,4],implicitli:[9,14,8],paramet:[0,8,6,14,4],typedef:[12,1,10,8,4],scon:0,might:[0,12,10,8,13],good:[10,2],"return":[0,4,8,10,11,13,14],timestamp:[10,8],exportedheadercod:[12,10],framework:0,somebodi:13,converttotypecod:[12,9,10,8,4],complain:8,"0x0008":14,easili:10,alreadi:[8,10,14,11,4],compris:5,found:[0,13,4],unicod:[13,10,8,4],"0x0004":14,inplac:[12,10],"0x0002":14,hard:13,idea:2,connect:[5,12,8],notypenam:8,event:10,setsiz:14,publish:13,print:10,occurr:10,siptype_klass:[10,4],qualifi:[10,4],sipwrapper_typ:4,reason:[13,10],base:[0,4,5,10,12,14],sbf:13,ask:10,earliest:[0,10],pylist_get_item:10,thread:[0,5,10,8,13],pycobject_check:11,omit:[12,10,6,8],perhap:7,lifetim:5,assign:[13,4],siptypeisnamespac:4,major:[2,4],default_mod_dir:[0,13],obviou:13,upper:[10,8,4],number:[0,1,2,4,5,6,8,10,12,13,14],extern:[5,10,8],done:[13,10],construct:[13,10],stabl:5,miss:9,build_ext:3,"__float__":12,gpl:[5,10],differ:[0,2,5,8,9,10,12,13,14],script:[0,2,3,5,7,10,13],interact:13,least:13,mfile:0,"__ixor__":12,store:10,option:[0,2,3,4,5,6,7,8,9,10,13,14],relationship:[13,4],siptransferbreak:[13,4],getter:[13,4],pars:[0,10,8],std:10,version_to_sip_tag:0,cyclic:[13,10,8,4],remov:[0,13,9,8,4],sip_api_minor_nr:4,str:8,consumpt:5,chkdir:0,comput:[10,8],create_config_modul:[0,13],tp_name:[8,4],packag:[0,10,7,2,8],"null":[10,11,4],sipkwd:10,"0x040000":[0,14,4],built:[0,5,7,10,2],lib:[13,2],self:[0,13,10],"__div__":[12,9],also:[0,2,4,5,6,7,10,11,13,8],build:[0,1,2,3,4,5,6,7,10,13],distribut:[5,7,2],exec:8,klassinst:10,previou:[13,8,10,14,4],defaultencod:[12,10,8],most:[12,10,6,14,4],maco:[0,5,2],addr:14,clear:10,cover:[5,10,2,13],transferobj:4,supertyp:[13,10,8],extra_lflag:0,latest:[0,5,10,2],microsoft:2,getcod:[12,10],particularli:14,sip_rxobj_con:[12,8],unitcod:[12,10],fine:[0,13,2],find:[5,13,8],copyright:[5,10],keyreleas:10,express:[0,12,10],py_non:[10,4],mappedtyp:[12,10],setdata:10,"_c_api":11,catcher:10,whenev:[13,9,10,8],common:[5,10,14],sip_unboundlocalerror:12,noreleas:8,set:[0,2,4,5,6,8,10,11,13,14],dump:14,mutabl:[14,4],extra_include_dir:0,sipr:10,arg:4,"__imod__":12,pythonw:7,call_exec:8,someth:[13,9,2],siptypeisenum:4,smallest:0,subdir:0,altern:[5,13,8],signatur:[4,5,6,9,10,12,8],latin:[10,8,4],numer:[0,8],disallow:[10,4],sipiserr:10,complementari:[5,9],popul:[13,10,4],both:[0,4,5,10,12,13,8],last:[12,13,10,8],license:[10,8],operat:12,context:[12,10,8,4],connectitem:12,load:[0,5,7,14],sipclass_klass:[10,4],simpli:[13,10],point:[4,14,10,12,13,8],instanti:[10,8],header:[0,2,5,10,11,13],linux:[5,6,7,2],throughout:10,compositemodul:[12,10],static_cast:10,empti:0,destructor:[4,5,8,10,12,13,14],extra_defin:0,strategi:13,sipconvertfromnamedenum:[9,4],convert:[0,2,4,6,10,11,13,8],sipreskei:10,understand:[5,12,14],"__lshift__":12,nodefaultctor:8,look:[6,7,2,8,13],sipreleasemappedtyp:[9,4],abov:[0,8,3],error:[0,10,8,4],"__hash__":12,anonym:4,sip_pylist:[12,8],sip_slot:12,readm:2,itself:[4,5,7,10,12,13],pytypeobject:[10,4],pyqt_sip_flag:13,sipmapstringtoclass:4,conflict:[13,6],behav:13,sym:4,temporari:[10,8,4],user:[9,7,4],"__add__":[12,10],wherev:10,chang:[0,4,5,9,10,13,8],travers:10,task:13,equival:[0,12,10,14,8],entri:[8,4],parenthes:4,pickl:10,sipflag:10,"__neg__":12,sip_rxobj_di:12,explan:10,getapi:14,dump_klass:10,siperrornon:10,restructuredtext:10,appli:[13,9,10,8,4],subsequ:[5,13,10,4],sip_pytyp:[12,8],format:[0,2,4,9,10,8],"__gt__":12,bit:14,pystring_fromstringands:10,formal:12,semi:12,signal:[5,12,8,4],resolv:0,collect:[12,13,10,8,4],api:[0,1,4,5,6,7,8,9,10,11,12,13,14],maplen:4,version_to_str:0,nbyte:4,sip_floatingpointerror:12,creation:5,some:[4,5,6,8,7,10,12,13,14],back:[0,8],siptype_qwidget:10,transferthi:[13,8],pep:4,larg:[5,13,10],recognis:10,pystring_asstringands:10,run:[5,10,2,3,13],siptransferto:[13,14,4],reach:13,step:[2,4],impos:10,sipconverttomappedtyp:[9,4],idx:4,block:[5,6,14,10,13,8],primarili:8,within:[10,8,4],ellipsi:8,hex_:8,ensur:[0,4,5,10,13,8],next:[10,7,2,8,13],question:13,"long":[12,6,8,4],custom:[0,1,7,2],handler:[13,4],sipseg:10,suit:0,forward:8,doctyp:8,sipmoduledict:10,siptype_qkeyev:10,link:[0,13,7,10,8],translat:10,line:[0,1,2,3,6,7,8,9,10,12,13,14],sdk:[0,2],getwrapp:[10,8],concaten:10,utf:[10,8,4],consist:12,bigetcharbuffercod:[12,10],py_buildvalu:[10,4],similar:[5,13,8,4],install_fil:0,sipconvertfromconstvoidptr:4,newthread:8,dd_list:8,sip_unicodeencodeerror:12,parser:[12,13,8],doesn:[0,12,10,13,4],repres:[0,4,14,12,13,8],"char":[12,13,10,8,4],sipdir:2,sipmodul:10,invalid:0,keywordarg:8,bracket:[10,4],librari:[0,2,5,6,7,10,12,13,14],clean:0,eval:4,unaffect:4,an_object_refer:9,leak:[13,10,8,4],hello:13,sip_referenceerror:12,install_dir:0,code:[0,1,2,4,5,6,8,9,10,11,12,13,14],sipconvertfromenum:4,results:8,qtguimodulemakefil:13,the_word:13,privat:[5,12,8,13],sens:12,generate_target_clean:0,sip_valueerror:12,sip_no_convertor:[10,4],typeheadercod:[12,13,10],sipconnectrx:9,siperrorfail1:10,relev:5,tri:[10,8],sipbuildresult:[9,4],"try":[10,6,14,13],refer:[0,1,4,5,8,10,11,13,14],sub_cfg:[0,13],sipdistutil:[5,3],impli:[0,8],smaller:13,cfg:[13,3],contructor:10,download:[5,1,2],append:[0,10,2,13],compat:[0,10,2,8,4],index:4,defaultsupertyp:[12,13,10],access:[0,4,5,6,10,12,13],sipexception_:4,consolid:[5,10],parse_build_macro:0,len:4,bodi:10,let:13,becom:[11,4],great:5,convers:[4,5,9,10,12,8],broken:4,pycobject_asvoidptr:11,typic:[0,13,9,10],chanc:13,siptype_typ:10,sip_not_non:[10,4],"boolean":[12,8,4],sipptrptr:10,sipexception_klass_except:4,from:[0,2,3,4,5,6,7,9,10,11,12,13,8],zip:2,doubl:[12,8,4],qobject:[12,13,10],implic:13,few:12,sip_unblock_thread:[10,4],sort:[13,6,4],rich:5,src:0,greatli:10,augment:0,annot:[1,4,6,9,10,12,13,8],bigetwritebuffercod:[12,10],obvious:13,thin:[12,4],proprietari:7,control:[13,10,4],sipgetwrapp:[9,4],tar:2,process:[5,10,3],lock:[1,4,5,6,10,13,8],tag:[0,13,6],fprintf:10,msvc:0,delai:8,gcc:2,sip:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14],sit:0,pyqt:[0,5,9,10,13],"__pos__":12,instead:[12,13,10,8,4],preinitialisationcod:[12,10],overridden:10,pymodule_getdict:11,alloc:[13,4],bind:[0,2,5,6,13,14],correspond:[0,2,4,5,10,11,12,13,8],element:[0,12,10,8,4],issu:[5,13,8],siperrorst:[10,4],allow:[0,2,4,5,7,9,10,12,13,8],siptypefrompytypeobject:4,typecod:[12,10],siptransferback:[13,14,4],comma:[12,13,8],py_conf_inc_dir:0,sipconvertfromnewinst:[9,4],destroi:[13,10,8,4],srcdir:0,therefor:[5,13],sipfre:[13,4],crash:[13,14],greater:[0,8,10,14,4],"__getitem__":[12,8],python:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14],auto:6,generate_macros_and_rul:0,nokia:5,qmake:0,"__delitem__":[12,8],postinitialisationcod:[12,10],anyth:8,modulecod:[12,10,8],subset:12,meta:[1,4,5,10,13,8],"static":[0,2,4,5,7,10,12,13],sipklass:[12,4],our:[13,3],special:[12,9,3],out:[5,13,2,8,4],variabl:[1,5,10,12,13,8],influenc:4,stub:[7,10],suitabl:5,rel:0,leverag:3,vendorid:7,q_slot:12,standalon:10,qtmod:10,dictionari:[0,4,10,11,12,13],releas:[2,4,5,6,10,13,8],afterward:[10,6,8],unnam:[10,14,8],opengl:0,timer:10,keep:[13,10],sipconvertfromnewtyp:4,length:[5,10,4],outsid:12,optional_list:0,softwar:[5,2],suffix:6,date:[13,2],owner:[14,4],parse_build_fil:0,facil:[0,6],typestr:4,transferto:14,dd_ptr:8,unknown:[14,8],licens:[5,1,10,12,8],sipparseresult:[9,10,4],system:[0,1,2,3,4,5,6,7,13],wrapper:[0,4,5,6,8,10,12,13,14],attach:10,termin:[13,10,8,4],"final":[10,2,13],sipclass_:4,"__del__":14,sip_systemexit:12,exactli:10,cmodul:[12,13,10],qevent:10,bother:13,see:[0,2,3,4,5,6,10,11,12,13,8],structur:[1,4,5,6,8,9,10,11,13,14],charact:[0,1,4,9,10,12,13,8],nocopi:8,slicelength:4,sipapidef:11,linker:[0,5,13],clearli:10,clib:0,sip_inc_dir:0,pyqt_sip_dir:13,need:[0,2,3,4,5,6,7,9,10,11,12,13,8],turn:10,tidi:10,verbatim:13,sip_typeerror:12,"0x04":4,"0x01":4,"0x02":4,builtin:[0,1,2,8,7,14],"_qt":10,which:[0,2,3,4,5,6,7,8,9,10,12,13,14],singl:[0,5,10,12,13],regard:[13,10,8,4],unless:[10,8],clash:[10,8],deploy:[13,10],pyd:5,"class":[0,1,4,5,6,8,7,10,12,13,14],siptype_:4,request:4,snapshot:[0,14,4],determin:[13,8,10,14,4],siptyp:10,constrain:[9,8],keypress:10,fact:5,extra_lib:[0,13],a0wrapp:10,text:[0,13,10],bring:5,sip_unicodedecodeerror:12,dbu:10,anywai:[10,8],locat:[13,4],sip_config_arg:0,should:[0,2,4,7,9,10,12,13,8],local:[10,3],hope:13,meant:[9,8],memcpi:10,increas:0,extract:[0,5,10],enabl:[0,4,6,8,10,13,14],sipconverttotyp:[10,4],possibl:[5,12,10,14,8],integr:[5,8],contain:[0,4,5,6,7,10,11,12,13,8],pylong_asunsignedlong:4,attribut:[0,1,13,11,4],sipexportsymbol:[11,4],sipwrappertype_typ:4,pyobject_print:10,correctli:[12,13],pattern:[0,10],dll:13,written:[0,5],neither:13,kei:[0,13,10],"__ifloordiv__":12,job:10,strdefin:0,"__ilshift__":12,addit:[0,1,4,9,10,12,13,8],consolidatedmodul:[12,10,6],use_arch:0,equal:[13,8,10,14,4],"__ior__":12,instanc:[0,4,5,8,10,11,12,13,14],comment:7,hyphen:8,py_xdecref:10,respect:[13,4],siplong_asunsignedlong:4,compon:[5,1,6,2,10],treat:[14,8],immedi:[10,8],"__itruediv__":12,ob_typ:4,togeth:5,sipbuff:10,dstdir:0,"__iadd__":12,defin:[0,2,4,5,8,9,10,11,12,13,14],typeint:4,"__floordiv__":12,"__sub__":12,noargpars:[10,8],helper:[10,4],reacquir:[10,6,8],sip_version_str:[0,14,4],sipattrgetterfunc:4,sip_temporari:[10,8],unneed:[0,10],member:[12,9,10,8,11],handl:[0,8,7,10,13,14],sip_environmenterror:12,http:[5,2],sipmapinttoclass:4,effect:[12,13,10],dealloc:10,distutil:[0,1,13,3,5],sipisapien:4,firstli:13,whole:13,ext_modul:3,exampl:[0,1,2,3,4,7,10,11,12,13,8],command:[0,1,2,3,6,7,8,9,10,13,14],choos:[5,10,8],undefin:10,usual:[0,10,8,3,4],unari:12,less:[13,10,8,4],obtain:[8,11,4],optional_str:0,"__lt__":12,prepend:10,field:8,makefil:[0,13,7,6],sip_anyslot:12,add:[13,10],ws_win:13,match:[5,12,10,8,13],sip_bin:[0,13],piec:10,siptypedef:[10,4],know:[12,10],recurs:10,insert:0,pyerr_occur:4,like:[2,4,7,9,10,13,8],success:4,build_macro:0,necessari:[0,5,9,10,11,12,13],suppli:[13,8,4],destdir:2,"export":[0,10,11,4],sippyself:10,win32:2,borland:2,"__contains__":12,qlist:10,avoid:[0,10,6,8,13],numdefin:0,overlap:8,leav:13,hello_sip_dir:13,sipconvertfromconstvoidptrands:4,"enum":[1,4,9,10,11,12,8],although:2,offset:4,stage:7,about:[5,6,14,8],actual:[13,10,8,11],"__imul__":[12,10],sipconverttocpp:9,statement:[12,10,6,14],includ:[0,2,4,5,6,8,10,11,12,13,14],constructor:[0,4,6,8,10,12,13,14],fals:12,discard:8,disabl:[0,6,10,2,14],own:[0,5,8,7,10,13,14],sipwrapper_check:[9,4],automat:[0,4,5,6,8,9,10,13,14],pyqtwrappertyp:10,"__abs__":12,merg:[13,10],transfer:[13,9,10,8,4],sip_notimplementederror:12,sipconvertfromvoidptr:4,sip_modul:11,"function":[0,1,4,5,6,8,9,10,11,12,13,14],unexpect:4,sip_systemerror:12,neutral:0,sipfindtyp:[11,4],bug:4,count:[13,10,4],made:[13,10,8,4],parentmakefil:0,whether:10,wish:2,writeabl:[14,4],displai:[0,6,2,14],limit:[13,10],otherwis:[10,2,8,4],problem:[0,13,8],"int":[12,9,10,8,4],mask:14,dure:[0,5,10,6],sipbadcatcherresult:4,filenam:[0,10],posix_platform:10,implement:[0,4,5,6,8,9,10,12,13,14],sipexception_std_except:10,mutual:[13,10],sip_pyobject:[12,8],detail:[0,2,4,5,10,12,13,8],virtual:[4,5,8,10,12,13,14],other:[0,2,4,5,10,12,13,8],bool:[12,8,10,14,4],futur:14,rememb:10,unwrapinst:14,repeat:8,pyerr_setnon:10,exporteddoc:[12,10,6],singleton:8,optionalinclud:[12,10],rule:0,klass:[12,10,4],"__index__":12,sipclassnam:[9,4]},titles:["The Build System","SIP Reference Guide","Installation","Building Your Extension with distutils","C API for Handwritten Code","Introduction","The SIP Command Line","Builtin Modules and Custom Interpreters","Annotations","Potential Incompatibilities with Earlier Versions","Directives","Using the C API when Embedding","SIP Specification Files","Using SIP","Python API for Applications"],modules:{sipconfig:0,sip:14},descrefs:{"":{sipGetState:[4,0],sipTransferTo:[4,0],SIP_VERSION:[4,3],sipSimpleWrapper:[4,5],sipFindMappedType:[4,0],SIP_API_MAJOR_NR:[4,3],sipLong_AsUnsignedLong:[4,0],sipConvertFromEnum:[4,0],sipIntTypeClassMap:[4,5],dd_name:[8,6],sipConvertFromInstance:[4,0],sipReleaseType:[4,0],SIP_NO_CONVERTORS:[4,3],sipTypeName:[4,0],sipConvertToInstance:[4,0],sipMapIntToClass:[4,0],sipFindType:[4,0],sipConvertFromType:[4,0],sipTypeIsEnum:[4,0],sipSimpleWrapper_Type:[4,8],sipConvertFromSliceObject:[4,0],sipForceConvertToMappedType:[4,0],sipTypeIsNamespace:[4,0],sipConvertToVoidPtr:[4,0],sipCanConvertToType:[4,0],sipCanConvertToInstance:[4,0],sipConvertFromConstVoidPtrAndSize:[4,0],typeString:[4,6],sipForceConvertToType:[4,0],dd_next:[8,6],sipExportSymbol:[4,0],sipBadLengthForSlice:[4,0],sipConvertToMappedType:[4,0],sipTypeAsPyTypeObject:[4,0],sipIsAPIEnabled:[4,0],sipTypeFromPyTypeObject:[4,0],sipForceConvertToInstance:[4,0],sipConvertFromVoidPtrAndSize:[4,0],sipReleaseMappedType:[4,0],sipStringTypeClassMap:[4,5],SIP_API_MINOR_NR:[4,3],sipVoidPtr_Type:[4,8],sipFree:[4,0],sipRegisterAttributeGetter:[4,0],sipConvertToType:[4,0],sipWrapperType:[4,5],sipConvertFromNewType:[4,0],SIP_PROTECTED_IS_PUBLIC:[4,3],dd_ptr:[8,6],sipConvertFromSequenceIndex:[4,0],SIP_VERSION_STR:[4,3],sipTypeIsMapped:[4,0],SIP_NOT_NONE:[4,3],sipClassName:[4,0],sipMapStringToClass:[4,0],sipWrapperType_Type:[4,8],sipConvertFromNewInstance:[4,0],sipTransferBack:[4,0],sipMalloc:[4,0],sipConvertFromMappedType:[4,0],sipWrapper:[4,5],dd_isderived:[8,6],sipConvertFromConstVoidPtr:[4,0],sipTypeIsClass:[4,0],sipBadCatcherResult:[4,0],sipGetPyObject:[4,0],SIP_UNBLOCK_THREADS:[4,3],sipDelayedDtor:[8,5],sipReleaseInstance:[4,0],sipWrapper_Check:[4,0],sipTransferBreak:[4,0],typeInt:[4,6],sipTypeScope:[4,0],sipImportSymbol:[4,0],sipDelayedDtors:[8,0],sipFindClass:[4,0],sipResolveTypedef:[4,0],sipConvertFromNamedEnum:[4,0],SIP_BLOCK_THREADS:[4,3],sipGetWrapper:[4,0],sipBadCallableArg:[4,0],sipFindNamedEnum:[4,0],user:[4,6],sipCanConvertToEnum:[4,0],sipCanConvertToMappedType:[4,0],sipWrapper_Type:[4,8],sipCallMethod:[4,0],sipParseResult:[4,0],sipBuildResult:[4,0],sipRegisterPyType:[4,0],SIP_SSIZE_T:[4,3],sipConvertFromVoidPtr:[4,0]},"sipconfig.PythonModuleMakefile":{generate_target_install:[0,1],generate_macros_and_rules:[0,1],"__init__":[0,1]},sip:{transferto:[14,2],getapi:[14,2],settracemask:[14,2],setdeleted:[14,2],dump:[14,2],transferback:[14,2],SIP_VERSION_STR:[14,9],ispyowned:[14,2],wrapper:[14,7],cast:[14,2],unwrapinstance:[14,2],setapi:[14,2],wrapinstance:[14,2],SIP_VERSION:[14,9],voidptr:[14,7],wrappertype:[14,7],isdeleted:[14,2],"delete":[14,2]},"sip.voidptr":{"__int__":[14,1],getwriteable:[14,1],setwriteable:[14,1],ascobject:[14,1],ascapsule:[14,1],getsize:[14,1],"__hex__":[14,1],asstring:[14,1],setsize:[14,1],"__init__":[14,1]},"sipconfig.ProgramMakefile":{generate_target_default:[0,1],build_command:[0,1],generate_macros_and_rules:[0,1],generate_target_clean:[0,1],generate_target_install:[0,1],finalise:[0,1],"__init__":[0,1]},"sipconfig.ParentMakefile":{generate_target_clean:[0,1],generate_target_install:[0,1],generate_target_default:[0,1],generate_macros_and_rules:[0,1],"__init__":[0,1]},sipconfig:{create_config_module:[0,2],ModuleMakefile:[0,7],Configuration:[0,7],create_wrapper:[0,2],version_to_sip_tag:[0,2],format:[0,2],parse_build_macros:[0,2],create_content:[0,2],ParentMakefile:[0,7],Makefile:[0,7],read_version:[0,2],inform:[0,2],error:[0,2],version_to_string:[0,2],ProgramMakefile:[0,7],SIPModuleMakefile:[0,7],PythonModuleMakefile:[0,7]},"sipconfig.ModuleMakefile":{generate_target_default:[0,1],generate_macros_and_rules:[0,1],generate_target_clean:[0,1],module_as_lib:[0,1],generate_target_install:[0,1],finalise:[0,1],"__init__":[0,1]},"sipconfig.Makefile":{chkdir:[0,4],platform_lib:[0,1],install_file:[0,1],ready:[0,1],extra_libs:[0,4],"__init__":[0,1],generate_target_default:[0,1],console:[0,4],generator:[0,4],extra_include_dirs:[0,4],clean_build_file_objects:[0,1],mkdir:[0,4],extra_cflags:[0,4],rm:[0,4],extra_lib_dirs:[0,4],config:[0,4],finalise:[0,1],required_string:[0,1],extra_cxxflags:[0,4],extra_lflags:[0,4],parse_build_file:[0,1],generate_target_clean:[0,1],copy:[0,4],generate_target_install:[0,1],generate:[0,1],optional_string:[0,1],optional_list:[0,1],generate_macros_and_rules:[0,1],extra_defines:[0,4]},"sipconfig.SIPModuleMakefile":{finalise:[0,1],"__init__":[0,1]},"sipconfig.Configuration":{set_build_macros:[0,1],default_mod_dir:[0,4],default_bin_dir:[0,4],platform:[0,4],universal:[0,4],sip_version:[0,4],sip_config_args:[0,4],default_sip_dir:[0,4],sip_mod_dir:[0,4],build_macros:[0,1],py_inc_dir:[0,4],sip_inc_dir:[0,4],py_conf_inc_dir:[0,4],py_version:[0,4],py_lib_dir:[0,4],arch:[0,4],sip_version_str:[0,4],"__init__":[0,1],sip_bin:[0,4]}},filenames:["build_system","index","installation","distutils","c_api","introduction","command_line","builtin","annotations","incompatibilities","directives","embedding","specification_files","using","python_api"]}) \ No newline at end of file
diff --git a/doc/html/specification_files.html b/doc/html/specification_files.html
new file mode 100644
index 0000000..e408fe4
--- /dev/null
+++ b/doc/html/specification_files.html
@@ -0,0 +1,612 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>SIP Specification Files &mdash; SIP 4.10.5 Reference Guide</title>
+ <link rel="stylesheet" href="_static/default.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '#',
+ VERSION: '4.10.5',
+ COLLAPSE_MODINDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="top" title="SIP 4.10.5 Reference Guide" href="index.html" />
+ <link rel="next" title="Directives" href="directives.html" />
+ <link rel="prev" title="The SIP Command Line" href="command_line.html" />
+ </head>
+ <body>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ accesskey="M">modules</a> |</li>
+ <li class="right" >
+ <a href="directives.html" title="Directives"
+ accesskey="N">next</a> |</li>
+ <li class="right" >
+ <a href="command_line.html" title="The SIP Command Line"
+ accesskey="P">previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+ <div class="body">
+
+ <div class="section" id="sip-specification-files">
+<h1>SIP Specification Files<a class="headerlink" href="#sip-specification-files" title="Permalink to this headline">¶</a></h1>
+<p>A SIP specification consists of some C/C++ type and function declarations and
+some directives. The declarations may contain annotations which provide SIP
+with additional information that cannot be expressed in C/C++. SIP does not
+include a full C/C++ parser.</p>
+<p>It is important to understand that a SIP specification describes the Python
+API, i.e. the API available to the Python programmer when they <tt class="docutils literal"><span class="pre">import</span></tt> the
+generated module. It does not have to accurately represent the underlying
+C/C++ library. There is nothing wrong with omitting functions that make
+little sense in a Python context, or adding functions implemented with
+handwritten code that have no C/C++ equivalent. It is even possible (and
+sometimes necessary) to specify a different super-class hierarchy for a C++
+class. All that matters is that the generated code compiles properly.</p>
+<p>In most cases the Python API matches the C/C++ API. In some cases handwritten
+code (see <a class="reference external" href="directives.html#directive-%MethodCode"><tt class="xref docutils literal"><span class="pre">%MethodCode</span></tt></a>) is used to map from one to the other
+without SIP having to know the details itself. However, there are a few cases
+where SIP generates a thin wrapper around a C++ method or constructor (see
+<a class="reference external" href="c_api.html#ref-derived-classes"><em>Generated Derived Classes</em></a>) and needs to know the exact C++ signature. To deal
+with these cases SIP allows two signatures to be specified. For example:</p>
+<div class="highlight-python"><pre>class Klass
+{
+public:
+ // The Python signature is a tuple, but the underlying C++ signature
+ // is a 2 element array.
+ Klass(SIP_PYTUPLE) [(int *)];
+%MethodCode
+ int iarr[2];
+
+ if (PyArg_ParseTuple(a0, "ii", &amp;iarr[0], &amp;iarr[1]))
+ {
+ // Note that we use the SIP generated derived class
+ // constructor.
+ Py_BEGIN_ALLOW_THREADS
+ sipCpp = new sipKlass(iarr);
+ Py_END_ALLOW_THREADS
+ }
+%End
+};</pre>
+</div>
+<div class="section" id="syntax-definition">
+<h2>Syntax Definition<a class="headerlink" href="#syntax-definition" title="Permalink to this headline">¶</a></h2>
+<p>The following is a semi-formal description of the syntax of a specification
+file.</p>
+<pre class="literal-block">
+<em>specification</em> ::= {<em>module-statement</em>}
+
+<em>module-statement</em> ::= [<em>module-directive</em> | <em>statement</em>]
+
+<em>module-directive</em> ::= [
+ <a class="reference external" href="directives.html#directive-%API"><tt class="xref docutils literal"><span class="pre">%API</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%CModule"><tt class="xref docutils literal"><span class="pre">%CModule</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%CompositeModule"><tt class="xref docutils literal"><span class="pre">%CompositeModule</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%ConsolidatedModule"><tt class="xref docutils literal"><span class="pre">%ConsolidatedModule</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%Copying"><tt class="xref docutils literal"><span class="pre">%Copying</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%DefaultEncoding"><tt class="xref docutils literal"><span class="pre">%DefaultEncoding</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%DefaultMetatype"><tt class="xref docutils literal"><span class="pre">%DefaultMetatype</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%DefaultSupertype"><tt class="xref docutils literal"><span class="pre">%DefaultSupertype</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%Doc"><tt class="xref docutils literal"><span class="pre">%Doc</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%ExportedDoc"><tt class="xref docutils literal"><span class="pre">%ExportedDoc</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%ExportedHeaderCode"><tt class="xref docutils literal"><span class="pre">%ExportedHeaderCode</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%Feature"><tt class="xref docutils literal"><span class="pre">%Feature</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%Import"><tt class="xref docutils literal"><span class="pre">%Import</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%Include"><tt class="xref docutils literal"><span class="pre">%Include</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%InitialisationCode"><tt class="xref docutils literal"><span class="pre">%InitialisationCode</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%License"><tt class="xref docutils literal"><span class="pre">%License</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%MappedType"><tt class="xref docutils literal"><span class="pre">%MappedType</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%Module"><tt class="xref docutils literal"><span class="pre">%Module</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%ModuleCode"><tt class="xref docutils literal"><span class="pre">%ModuleCode</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%ModuleHeaderCode"><tt class="xref docutils literal"><span class="pre">%ModuleHeaderCode</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%OptionalInclude"><tt class="xref docutils literal"><span class="pre">%OptionalInclude</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%Platforms"><tt class="xref docutils literal"><span class="pre">%Platforms</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%PreInitialisationCode"><tt class="xref docutils literal"><span class="pre">%PreInitialisationCode</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%PostInitialisationCode"><tt class="xref docutils literal"><span class="pre">%PostInitialisationCode</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%Timeline"><tt class="xref docutils literal"><span class="pre">%Timeline</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%UnitCode"><tt class="xref docutils literal"><span class="pre">%UnitCode</span></tt></a> |
+ <em>mapped-type-template</em>]
+
+<em>statement</em> :: [<em>class-statement</em> | <em>function</em> | <em>variable</em>]
+
+<em>class-statement</em> :: [
+ <a class="reference external" href="directives.html#directive-%If"><tt class="xref docutils literal"><span class="pre">%If</span></tt></a> |
+ <em>class</em> |
+ <em>class-template</em> |
+ <em>enum</em> |
+ <em>namespace</em> |
+ <em>opaque-class</em> |
+ <em>operator</em> |
+ <em>struct</em> |
+ <em>typedef</em> |
+ <em>exception</em>]
+
+<em>class</em> ::= <strong>class</strong> <em>name</em> [<strong>:</strong> <em>super-classes</em>] [<em>class-annotations</em>]
+ <strong>{</strong> {<em>class-line</em>} <strong>};</strong>
+
+<em>super-classes</em> ::= <em>name</em> [<strong>,</strong> <em>super-classes</em>]
+
+<em>class-line</em> ::= [
+ <em>class-statement</em> |
+ <a class="reference external" href="directives.html#directive-%BIGetBufferCode"><tt class="xref docutils literal"><span class="pre">%BIGetBufferCode</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%BIGetReadBufferCode"><tt class="xref docutils literal"><span class="pre">%BIGetReadBufferCode</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%BIGetWriteBufferCode"><tt class="xref docutils literal"><span class="pre">%BIGetWriteBufferCode</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%BIGetSegCountCode"><tt class="xref docutils literal"><span class="pre">%BIGetSegCountCode</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%BIGetCharBufferCode"><tt class="xref docutils literal"><span class="pre">%BIGetCharBufferCode</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%BIReleaseBufferCode"><tt class="xref docutils literal"><span class="pre">%BIReleaseBufferCode</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%ConvertToSubClassCode"><tt class="xref docutils literal"><span class="pre">%ConvertToSubClassCode</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%ConvertToTypeCode"><tt class="xref docutils literal"><span class="pre">%ConvertToTypeCode</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%Docstring"><tt class="xref docutils literal"><span class="pre">%Docstring</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%GCClearCode"><tt class="xref docutils literal"><span class="pre">%GCClearCode</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%GCTraverseCode"><tt class="xref docutils literal"><span class="pre">%GCTraverseCode</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%PickleCode"><tt class="xref docutils literal"><span class="pre">%PickleCode</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%TypeCode"><tt class="xref docutils literal"><span class="pre">%TypeCode</span></tt></a> |
+ <a class="reference external" href="directives.html#directive-%TypeHeaderCode"><tt class="xref docutils literal"><span class="pre">%TypeHeaderCode</span></tt></a> |
+ <em>constructor</em> |
+ <em>destructor</em> |
+ <em>method</em> |
+ <em>static-method</em> |
+ <em>virtual-method</em> |
+ <em>special-method</em> |
+ <em>operator</em> |
+ <em>virtual-operator</em> |
+ <em>class-variable</em> |
+ <strong>public:</strong> |
+ <strong>public Q_SLOTS:</strong> |
+ <strong>public slots:</strong> |
+ <strong>protected:</strong> |
+ <strong>protected Q_SLOTS:</strong> |
+ <strong>protected slots:</strong> |
+ <strong>private:</strong> |
+ <strong>private Q_SLOTS:</strong> |
+ <strong>private slots:</strong> |
+ <strong>Q_SIGNALS:</strong> |
+ <strong>signals:</strong>]
+
+<em>constructor</em> ::= [<strong>explicit</strong>] <em>name</em> <strong>(</strong> [<em>argument-list</em>] <strong>)</strong>
+ [<em>exceptions</em>] [<em>function-annotations</em>]
+ [<em>c++-constructor-signature</em>] <strong>;</strong> [<a class="reference external" href="directives.html#directive-%Docstring"><tt class="xref docutils literal"><span class="pre">%Docstring</span></tt></a>]
+ [<a class="reference external" href="directives.html#directive-%MethodCode"><tt class="xref docutils literal"><span class="pre">%MethodCode</span></tt></a>]
+
+<em>c++-constructor-signature</em> ::= <strong>[(</strong> [<em>argument-list</em>] <strong>)]</strong>
+
+<em>destructor</em> ::= [<strong>virtual</strong>] <strong>~</strong> <em>name</em> <strong>()</strong> [<em>exceptions</em>] [<strong>= 0</strong>]
+ [<em>function-annotations</em>] <strong>;</strong> [<a class="reference external" href="directives.html#directive-%MethodCode"><tt class="xref docutils literal"><span class="pre">%MethodCode</span></tt></a>]
+ [<a class="reference external" href="directives.html#directive-%VirtualCatcherCode"><tt class="xref docutils literal"><span class="pre">%VirtualCatcherCode</span></tt></a>]
+
+<em>method</em> ::= [<strong>Q_SIGNAL</strong>] [<strong>Q_SLOT</strong>] <em>type</em> <em>name</em> <strong>(</strong>
+ [<em>argument-list</em>] <strong>)</strong> [<strong>const</strong>] [<em>exceptions</em>] [<strong>= 0</strong>]
+ [<em>function-annotations</em>] [<em>c++-signature</em>] <strong>;</strong>
+ [<a class="reference external" href="directives.html#directive-%Docstring"><tt class="xref docutils literal"><span class="pre">%Docstring</span></tt></a>] [<a class="reference external" href="directives.html#directive-%MethodCode"><tt class="xref docutils literal"><span class="pre">%MethodCode</span></tt></a>]
+
+<em>c++-signature</em> ::= <strong>[</strong> <em>type</em> <strong>(</strong> [<em>argument-list</em>] <strong>)]</strong>
+
+<em>static-method</em> ::= <strong>static</strong> <em>function</em>
+
+<em>virtual-method</em> ::= [<strong>Q_SIGNAL</strong>] [<strong>Q_SLOT</strong>] <strong>virtual</strong> <em>type</em> <em>name</em>
+ <strong>(</strong> [<em>argument-list</em>] <strong>)</strong> [<strong>const</strong>] [<em>exceptions</em>] [<strong>= 0</strong>]
+ [<em>function-annotations</em>] [<em>c++-signature</em>] <strong>;</strong>
+ [<a class="reference external" href="directives.html#directive-%MethodCode"><tt class="xref docutils literal"><span class="pre">%MethodCode</span></tt></a>] [<a class="reference external" href="directives.html#directive-%VirtualCatcherCode"><tt class="xref docutils literal"><span class="pre">%VirtualCatcherCode</span></tt></a>]
+
+<em>special-method</em> ::= <em>type</em> <em>special-method-name</em>
+ <strong>(</strong> [<em>argument-list</em>] <strong>)</strong> [<em>function-annotations</em>] <strong>;</strong>
+ [<a class="reference external" href="directives.html#directive-%MethodCode"><tt class="xref docutils literal"><span class="pre">%MethodCode</span></tt></a>]
+
+<em>special-method-name</em> ::= [<strong>__abs__</strong> | <strong>__add__</strong> | <strong>__and__</strong> |
+ <strong>__bool__</strong> | <strong>__call__</strong> | <strong>__cmp__</strong> | <strong>__contains__</strong> |
+ <strong>__delitem__</strong> | <strong>__div__</strong> | <strong>__eq__</strong> | <strong>__float__</strong> |
+ <strong>__floordiv__</strong> | <strong>__ge__</strong> | <strong>__getitem__</strong> | <strong>__gt__</strong> |
+ <strong>__hash__</strong> | <strong>__iadd__</strong> | <strong>__iand__</strong> | <strong>__idiv__</strong> |
+ <strong>__ifloordiv__</strong> | <strong>__ilshift__</strong> | <strong>__imod__</strong> | <strong>__imul__</strong> |
+ <strong>__index__</strong> | <strong>__int__</strong> | <strong>__invert__</strong> | <strong>__ior__</strong> |
+ <strong>__irshift__</strong> | <strong>__isub__</strong> | <strong>__iter__</strong> | <strong>__itruediv__</strong> |
+ <strong>__ixor__</strong> | <strong>__le__</strong> | <strong>__len__</strong> | <strong>__long__</strong> |
+ <strong>__lshift__</strong> | <strong>__lt__</strong> | <strong>__mod__</strong> | <strong>__mul__</strong> |
+ <strong>__ne__</strong> | <strong>__neg__</strong> | <strong>__next__</strong> | <strong>__nonzero__</strong> |
+ <strong>__or__</strong> | <strong>__pos__</strong> | <strong>__repr__</strong> | <strong>__rshift__</strong> |
+ <strong>__setitem__</strong> | <strong>__str__</strong> | <strong>__sub__</strong> | <strong>__truediv__</strong> |
+ <strong>__xor__</strong>]
+
+<em>operator</em> ::= <em>operator-type</em>
+ <strong>(</strong> [<em>argument-list</em>] <strong>)</strong> [<strong>const</strong>] [<em>exceptions</em>]
+ [<em>function-annotations</em>] <strong>;</strong> [<a class="reference external" href="directives.html#directive-%MethodCode"><tt class="xref docutils literal"><span class="pre">%MethodCode</span></tt></a>]
+
+<em>virtual-operator</em> ::= <strong>virtual</strong> <em>operator-type</em>
+ <strong>(</strong> [<em>argument-list</em>] <strong>)</strong> [<strong>const</strong>] [<em>exceptions</em>] [<strong>= 0</strong>]
+ [<em>function-annotations</em>] <strong>;</strong> [<a class="reference external" href="directives.html#directive-%MethodCode"><tt class="xref docutils literal"><span class="pre">%MethodCode</span></tt></a>]
+ [<a class="reference external" href="directives.html#directive-%VirtualCatcherCode"><tt class="xref docutils literal"><span class="pre">%VirtualCatcherCode</span></tt></a>]
+
+<em>operatator-type</em> ::= [ <em>operator-function</em> | <em>operator-cast</em> ]
+
+<em>operator-function</em> ::= <em>type</em> <strong>operator</strong> <em>operator-name</em>
+
+<em>operator-cast</em> ::= <strong>operator</strong> <em>type</em>
+
+<em>operator-name</em> ::= [<strong>+</strong> | <strong>-</strong> | <strong>*</strong> | <strong>/</strong> | <strong>%</strong> | <strong>&amp;</strong> |
+ <strong>|</strong> | <strong>^</strong> | <strong>&lt;&lt;</strong> | <strong>&gt;&gt;</strong> | <strong>+=</strong> | <strong>-=</strong> | <strong>*=</strong> |
+ <strong>/=</strong> | <strong>%=</strong> | <strong>&amp;=</strong> | <strong>|=</strong> | <strong>^=</strong> | <strong>&lt;&lt;=</strong> | <strong>&gt;&gt;=</strong> |
+ <strong>~</strong> | <strong>()</strong> | <strong>[]</strong> | <strong>&lt;</strong> | <strong>&lt;=</strong> | <strong>==</strong> | <strong>!=</strong> |
+ <strong>&gt;</strong> | <strong>&gt;&gt;=</strong> | <strong>=</strong>]
+
+<em>class-variable</em> ::= [<strong>static</strong>] <em>variable</em>
+
+<em>class-template</em> :: = <strong>template</strong> <strong>&lt;</strong> <em>type-list</em> <strong>&gt;</strong> <em>class</em>
+
+<em>mapped-type-template</em> :: = <strong>template</strong> <strong>&lt;</strong> <em>type-list</em> <strong>&gt;</strong>
+ <a class="reference external" href="directives.html#directive-%MappedType"><tt class="xref docutils literal"><span class="pre">%MappedType</span></tt></a>
+
+<em>enum</em> ::= <strong>enum</strong> [<em>name</em>] [<em>enum-annotations</em>] <strong>{</strong> {<em>enum-line</em>} <strong>};</strong>
+
+<em>enum-line</em> ::= [<a class="reference external" href="directives.html#directive-%If"><tt class="xref docutils literal"><span class="pre">%If</span></tt></a> | <em>name</em> [<em>enum-annotations</em>] <strong>,</strong>
+
+<em>function</em> ::= <em>type</em> <em>name</em> <strong>(</strong> [<em>argument-list</em>] <strong>)</strong> [<em>exceptions</em>]
+ [<em>function-annotations</em>] <strong>;</strong> [<a class="reference external" href="directives.html#directive-%Docstring"><tt class="xref docutils literal"><span class="pre">%Docstring</span></tt></a>]
+ [<a class="reference external" href="directives.html#directive-%MethodCode"><tt class="xref docutils literal"><span class="pre">%MethodCode</span></tt></a>]
+
+<em>namespace</em> ::= <strong>namespace</strong> <em>name</em> <strong>{</strong> {<em>namespace-line</em>} <strong>};</strong>
+
+<em>namespace-line</em> ::= [<a class="reference external" href="directives.html#directive-%TypeHeaderCode"><tt class="xref docutils literal"><span class="pre">%TypeHeaderCode</span></tt></a> | <em>statement</em>]
+
+<em>opaque-class</em> ::= <strong>class</strong> <em>scoped-name</em> <strong>;</strong>
+
+<em>struct</em> ::= <strong>struct</strong> <em>name</em> <strong>{</strong> {<em>class-line</em>} <strong>};</strong>
+
+<em>typedef</em> ::= <strong>typedef</strong> [<em>typed-name</em> | <em>function-pointer</em>]
+ <em>typedef-annotations</em> <strong>;</strong>
+
+<em>variable</em>::= <em>typed-name</em> [<em>variable-annotations</em>] <strong>;</strong>
+ [<a class="reference external" href="directives.html#directive-%AccessCode"><tt class="xref docutils literal"><span class="pre">%AccessCode</span></tt></a>] [<a class="reference external" href="directives.html#directive-%GetCode"><tt class="xref docutils literal"><span class="pre">%GetCode</span></tt></a>]
+ [<a class="reference external" href="directives.html#directive-%SetCode"><tt class="xref docutils literal"><span class="pre">%SetCode</span></tt></a>]
+
+<em>exception</em> ::= <a class="reference external" href="directives.html#directive-%Exception"><tt class="xref docutils literal"><span class="pre">%Exception</span></tt></a> <em>exception-name</em> [<em>exception-base</em>]
+ <strong>{</strong> [<a class="reference external" href="directives.html#directive-%TypeHeaderCode"><tt class="xref docutils literal"><span class="pre">%TypeHeaderCode</span></tt></a>] <a class="reference external" href="directives.html#directive-%RaiseCode"><tt class="xref docutils literal"><span class="pre">%RaiseCode</span></tt></a> <strong>};</strong>
+
+<em>exception-name</em> ::= <em>scoped-name</em>
+
+<em>exception-base</em> ::= <strong>(</strong> [<em>exception-name</em> | <em>python-exception</em>] <strong>)</strong>
+
+<em>python-exception</em> ::= [<strong>SIP_Exception</strong> | <strong>SIP_StopIteration</strong> |
+ <strong>SIP_StandardError</strong> | <strong>SIP_ArithmeticError</strong> |
+ <strong>SIP_LookupError</strong> | <strong>SIP_AssertionError</strong> |
+ <strong>SIP_AttributeError</strong> | <strong>SIP_EOFError</strong> |
+ <strong>SIP_FloatingPointError</strong> | <strong>SIP_EnvironmentError</strong> |
+ <strong>SIP_IOError</strong> | <strong>SIP_OSError</strong> | <strong>SIP_ImportError</strong> |
+ <strong>SIP_IndexError</strong> | <strong>SIP_KeyError</strong> | <strong>SIP_KeyboardInterrupt</strong> |
+ <strong>SIP_MemoryError</strong> | <strong>SIP_NameError</strong> | <strong>SIP_OverflowError</strong> |
+ <strong>SIP_RuntimeError</strong> | <strong>SIP_NotImplementedError</strong> |
+ <strong>SIP_SyntaxError</strong> | <strong>SIP_IndentationError</strong> | <strong>SIP_TabError</strong> |
+ <strong>SIP_ReferenceError</strong> | <strong>SIP_SystemError</strong> | <strong>SIP_SystemExit</strong> |
+ <strong>SIP_TypeError</strong> | <strong>SIP_UnboundLocalError</strong> |
+ <strong>SIP_UnicodeError</strong> | <strong>SIP_UnicodeEncodeError</strong> |
+ <strong>SIP_UnicodeDecodeError</strong> | <strong>SIP_UnicodeTranslateError</strong> |
+ <strong>SIP_ValueError</strong> | <strong>SIP_ZeroDivisionError</strong> |
+ <strong>SIP_WindowsError</strong> | <strong>SIP_VMSError</strong>]
+
+<em>exceptions</em> ::= <strong>throw (</strong> [<em>exception-list</em>] <strong>)</strong>
+
+<em>exception-list</em> ::= <em>scoped-name</em> [<strong>,</strong> <em>exception-list</em>]
+
+<em>argument-list</em> ::= <em>argument</em> [<strong>,</strong> <em>argument-list</em>] [<strong>,</strong> <strong>...</strong>]
+
+<em>argument</em> ::= [
+ <em>type</em> [<em>name</em>] [<em>argument-annotations</em>] [<em>default-value</em>] |
+ <a class="reference internal" href="#stype-SIP_ANYSLOT"><tt class="xref docutils literal"><span class="pre">SIP_ANYSLOT</span></tt></a> [<em>default-value</em>] |
+ <a class="reference internal" href="#stype-SIP_QOBJECT"><tt class="xref docutils literal"><span class="pre">SIP_QOBJECT</span></tt></a> |
+ <a class="reference internal" href="#stype-SIP_RXOBJ_CON"><tt class="xref docutils literal"><span class="pre">SIP_RXOBJ_CON</span></tt></a> |
+ <a class="reference internal" href="#stype-SIP_RXOBJ_DIS"><tt class="xref docutils literal"><span class="pre">SIP_RXOBJ_DIS</span></tt></a> |
+ <a class="reference internal" href="#stype-SIP_SIGNAL"><tt class="xref docutils literal"><span class="pre">SIP_SIGNAL</span></tt></a> [<em>default-value</em>] |
+ <a class="reference internal" href="#stype-SIP_SLOT"><tt class="xref docutils literal"><span class="pre">SIP_SLOT</span></tt></a> [<em>default-value</em>] |
+ <a class="reference internal" href="#stype-SIP_SLOT_CON"><tt class="xref docutils literal"><span class="pre">SIP_SLOT_CON</span></tt></a> |
+ <a class="reference internal" href="#stype-SIP_SLOT_DIS"><tt class="xref docutils literal"><span class="pre">SIP_SLOT_DIS</span></tt></a>]
+
+<em>default-value</em> ::= <strong>=</strong> <em>expression</em>
+
+<em>expression</em> ::= [<em>value</em> | <em>value</em> <em>binary-operator</em> <em>expression</em>]
+
+<em>value</em> ::= [<em>unary-operator</em>] <em>simple-value</em>
+
+<em>simple-value</em> ::= [<em>scoped-name</em> | <em>function-call</em> | <em>real-value</em> |
+ <em>integer-value</em> | <em>boolean-value</em> | <em>string-value</em> |
+ <em>character-value</em>]
+
+<em>typed-name</em>::= <em>type</em> <em>name</em>
+
+<em>function-pointer</em>::= <em>type</em> <strong>(*</strong> <em>name</em> <strong>)(</strong> [<em>type-list</em>] <strong>)</strong>
+
+<em>type-list</em> ::= <em>type</em> [<strong>,</strong> <em>type-list</em>]
+
+<em>function-call</em> ::= <em>scoped-name</em> <strong>(</strong> [<em>value-list</em>] <strong>)</strong>
+
+<em>value-list</em> ::= <em>value</em> [<strong>,</strong> <em>value-list</em>]
+
+<em>real-value</em> ::= a floating point number
+
+<em>integer-value</em> ::= a number
+
+<em>boolean-value</em> ::= [<strong>true</strong> | <strong>false</strong>]
+
+<em>string-value</em> ::= <strong>&#8220;</strong> {<em>character</em>} <strong>&#8220;</strong>
+
+<em>character-value</em> ::= <strong>&#8216;</strong> <em>character</em> <strong>&#8216;</strong>
+
+<em>unary-operator</em> ::= [<strong>!</strong> | <strong>~</strong> | <strong>-</strong> | <strong>+</strong>]
+
+<em>binary-operator</em> ::= [<strong>-</strong> | <strong>+</strong> | <strong>*</strong> | <strong>/</strong> | <strong>&amp;</strong> | <strong>|</strong>]
+
+<em>argument-annotations</em> ::= see <a class="reference external" href="annotations.html#ref-arg-annos"><em>Argument Annotations</em></a>
+
+<em>class-annotations</em> ::= see <a class="reference external" href="annotations.html#ref-class-annos"><em>Class Annotations</em></a>
+
+<em>enum-annotations</em> ::= see <a class="reference external" href="annotations.html#ref-enum-annos"><em>Enum Annotations</em></a>
+
+<em>function-annotations</em> ::= see <a class="reference external" href="annotations.html#ref-function-annos"><em>Function Annotations</em></a>
+
+<em>typedef-annotations</em> ::= see <a class="reference external" href="annotations.html#ref-typedef-annos"><em>Typedef Annotations</em></a>
+
+<em>variable-annotations</em> ::= see <a class="reference external" href="annotations.html#ref-variable-annos"><em>Variable Annotations</em></a>
+
+<em>type</em> ::= [<strong>const</strong>] <em>base-type</em> {<strong>*</strong>} [<strong>&amp;</strong>]
+
+<em>type-list</em> ::= <em>type</em> [<strong>,</strong> <em>type-list</em>]
+
+<em>base-type</em> ::= [<em>scoped-name</em> | <em>template</em> | <strong>struct</strong> <em>scoped-name</em> |
+ <strong>char</strong> | <strong>signed char</strong> | <strong>unsigned char</strong> | <strong>wchar_t</strong> |
+ <strong>int</strong> | <strong>unsigned</strong> | <strong>unsigned int</strong> |
+ <strong>short</strong> | <strong>unsigned short</strong> |
+ <strong>long</strong> | <strong>unsigned long</strong> |
+ <strong>long long</strong> | <strong>unsigned long long</strong> |
+ <strong>float</strong> | <strong>double</strong> |
+ <strong>bool</strong> |
+ <strong>void</strong> |
+ <a class="reference internal" href="#stype-SIP_PYCALLABLE"><tt class="xref docutils literal"><span class="pre">SIP_PYCALLABLE</span></tt></a> |
+ <a class="reference internal" href="#stype-SIP_PYDICT"><tt class="xref docutils literal"><span class="pre">SIP_PYDICT</span></tt></a> |
+ <a class="reference internal" href="#stype-SIP_PYLIST"><tt class="xref docutils literal"><span class="pre">SIP_PYLIST</span></tt></a> |
+ <a class="reference internal" href="#stype-SIP_PYOBJECT"><tt class="xref docutils literal"><span class="pre">SIP_PYOBJECT</span></tt></a> |
+ <a class="reference internal" href="#stype-SIP_PYSLICE"><tt class="xref docutils literal"><span class="pre">SIP_PYSLICE</span></tt></a> |
+ <a class="reference internal" href="#stype-SIP_PYTUPLE"><tt class="xref docutils literal"><span class="pre">SIP_PYTUPLE</span></tt></a> |
+ <a class="reference internal" href="#stype-SIP_PYTYPE"><tt class="xref docutils literal"><span class="pre">SIP_PYTYPE</span></tt></a>]
+
+<em>scoped-name</em> ::= <em>name</em> [<strong>::</strong> <em>scoped-name</em>]
+
+<em>template</em> ::= <em>scoped-name</em> <strong>&lt;</strong> <em>type-list</em> <strong>&gt;</strong>
+
+<em>dotted-name</em> ::= <em>name</em> [<strong>.</strong> <em>dotted-name</em>]
+
+<em>name</em> ::= _A-Za-z {_A-Za-z0-9}
+</pre>
+<p>Here is a short list of differences between C++ and the subset supported by
+SIP that might trip you up.</p>
+<blockquote>
+<ul class="simple">
+<li>SIP does not support the use of <tt class="docutils literal"><span class="pre">[]</span></tt> in types. Use pointers instead.</li>
+<li>A global <tt class="docutils literal"><span class="pre">operator</span></tt> can only be defined if its first argument is a
+class or a named enum that has been wrapped in the same module.</li>
+<li>Variables declared outside of a class are effectively read-only.</li>
+<li>A class&#8217;s list of super-classes doesn&#8217;t not include any access specifier
+(e.g. <tt class="docutils literal"><span class="pre">public</span></tt>).</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="variable-numbers-of-arguments">
+<h2>Variable Numbers of Arguments<a class="headerlink" href="#variable-numbers-of-arguments" title="Permalink to this headline">¶</a></h2>
+<p>SIP supports the use of <tt class="docutils literal"><span class="pre">...</span></tt> as the last part of a function signature. Any
+remaining arguments are collected as a Python tuple.</p>
+</div>
+<div class="section" id="additional-sip-types">
+<h2>Additional SIP Types<a class="headerlink" href="#additional-sip-types" title="Permalink to this headline">¶</a></h2>
+<p>SIP supports a number of additional data types that can be used in Python
+signatures.</p>
+<dl class="sip-type">
+<dt id="stype-SIP_ANYSLOT">
+<tt class="descname">SIP_ANYSLOT</tt><a class="headerlink" href="#stype-SIP_ANYSLOT" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<p>This is both a <tt class="docutils literal"><span class="pre">const</span> <span class="pre">char</span> <span class="pre">*</span></tt> and a <tt class="docutils literal"><span class="pre">PyObject</span> <span class="pre">*</span></tt> that is used as the type
+of the member instead of <tt class="docutils literal"><span class="pre">const</span> <span class="pre">char</span> <span class="pre">*</span></tt> in functions that implement the
+connection or disconnection of an explicitly generated signal to a slot.
+Handwritten code must be provided to interpret the conversion correctly.</p>
+<dl class="sip-type">
+<dt id="stype-SIP_PYCALLABLE">
+<tt class="descname">SIP_PYCALLABLE</tt><a class="headerlink" href="#stype-SIP_PYCALLABLE" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<p>This is a <tt class="docutils literal"><span class="pre">PyObject</span> <span class="pre">*</span></tt> that is a Python callable object.</p>
+<dl class="sip-type">
+<dt id="stype-SIP_PYDICT">
+<tt class="descname">SIP_PYDICT</tt><a class="headerlink" href="#stype-SIP_PYDICT" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<p>This is a <tt class="docutils literal"><span class="pre">PyObject</span> <span class="pre">*</span></tt> that is a Python dictionary object.</p>
+<dl class="sip-type">
+<dt id="stype-SIP_PYLIST">
+<tt class="descname">SIP_PYLIST</tt><a class="headerlink" href="#stype-SIP_PYLIST" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<p>This is a <tt class="docutils literal"><span class="pre">PyObject</span> <span class="pre">*</span></tt> that is a Python list object.</p>
+<dl class="sip-type">
+<dt id="stype-SIP_PYOBJECT">
+<tt class="descname">SIP_PYOBJECT</tt><a class="headerlink" href="#stype-SIP_PYOBJECT" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<p>This is a <tt class="docutils literal"><span class="pre">PyObject</span> <span class="pre">*</span></tt> of any Python type.</p>
+<dl class="sip-type">
+<dt id="stype-SIP_PYSLICE">
+<tt class="descname">SIP_PYSLICE</tt><a class="headerlink" href="#stype-SIP_PYSLICE" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<p>This is a <tt class="docutils literal"><span class="pre">PyObject</span> <span class="pre">*</span></tt> that is a Python slice object.</p>
+<dl class="sip-type">
+<dt id="stype-SIP_PYTUPLE">
+<tt class="descname">SIP_PYTUPLE</tt><a class="headerlink" href="#stype-SIP_PYTUPLE" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<p>This is a <tt class="docutils literal"><span class="pre">PyObject</span> <span class="pre">*</span></tt> that is a Python tuple object.</p>
+<dl class="sip-type">
+<dt id="stype-SIP_PYTYPE">
+<tt class="descname">SIP_PYTYPE</tt><a class="headerlink" href="#stype-SIP_PYTYPE" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<p>This is a <tt class="docutils literal"><span class="pre">PyObject</span> <span class="pre">*</span></tt> that is a Python type object.</p>
+<dl class="sip-type">
+<dt id="stype-SIP_QOBJECT">
+<tt class="descname">SIP_QOBJECT</tt><a class="headerlink" href="#stype-SIP_QOBJECT" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<p>This is a <tt class="docutils literal"><span class="pre">QObject</span> <span class="pre">*</span></tt> that is a C++ instance of a class derived from Qt&#8217;s
+<tt class="docutils literal"><span class="pre">QObject</span></tt> class.</p>
+<dl class="sip-type">
+<dt id="stype-SIP_RXOBJ_CON">
+<tt class="descname">SIP_RXOBJ_CON</tt><a class="headerlink" href="#stype-SIP_RXOBJ_CON" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<p>This is a <tt class="docutils literal"><span class="pre">QObject</span> <span class="pre">*</span></tt> that is a C++ instance of a class derived from Qt&#8217;s
+<tt class="docutils literal"><span class="pre">QObject</span></tt> class. It is used as the type of the receiver instead of <tt class="docutils literal"><span class="pre">const</span>
+<span class="pre">QObject</span> <span class="pre">*</span></tt> in functions that implement a connection to a slot.</p>
+<dl class="sip-type">
+<dt id="stype-SIP_RXOBJ_DIS">
+<tt class="descname">SIP_RXOBJ_DIS</tt><a class="headerlink" href="#stype-SIP_RXOBJ_DIS" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<p>This is a <tt class="docutils literal"><span class="pre">QObject</span> <span class="pre">*</span></tt> that is a C++ instance of a class derived from Qt&#8217;s
+<tt class="docutils literal"><span class="pre">QObject</span></tt> class. It is used as the type of the receiver instead of <tt class="docutils literal"><span class="pre">const</span>
+<span class="pre">QObject</span> <span class="pre">*</span></tt> in functions that implement a disconnection from a slot.</p>
+<dl class="sip-type">
+<dt id="stype-SIP_SIGNAL">
+<tt class="descname">SIP_SIGNAL</tt><a class="headerlink" href="#stype-SIP_SIGNAL" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<p>This is a <tt class="docutils literal"><span class="pre">const</span> <span class="pre">char</span> <span class="pre">*</span></tt> that is used as the type of the signal instead of
+<tt class="docutils literal"><span class="pre">const</span> <span class="pre">char</span> <span class="pre">*</span></tt> in functions that implement the connection or disconnection
+of an explicitly generated signal to a slot.</p>
+<dl class="sip-type">
+<dt id="stype-SIP_SLOT">
+<tt class="descname">SIP_SLOT</tt><a class="headerlink" href="#stype-SIP_SLOT" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<p>This is a <tt class="docutils literal"><span class="pre">const</span> <span class="pre">char</span> <span class="pre">*</span></tt> that is used as the type of the member instead of
+<tt class="docutils literal"><span class="pre">const</span> <span class="pre">char</span> <span class="pre">*</span></tt> in functions that implement the connection or disconnection
+of an explicitly generated signal to a slot.</p>
+<dl class="sip-type">
+<dt id="stype-SIP_SLOT_CON">
+<tt class="descname">SIP_SLOT_CON</tt><a class="headerlink" href="#stype-SIP_SLOT_CON" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<p>This is a <tt class="docutils literal"><span class="pre">const</span> <span class="pre">char</span> <span class="pre">*</span></tt> that is used as the type of the member instead of
+<tt class="docutils literal"><span class="pre">const</span> <span class="pre">char</span> <span class="pre">*</span></tt> in functions that implement the connection of an internally
+generated signal to a slot. The type includes a comma separated list of types
+that is the C++ signature of of the signal.</p>
+<p>To take an example, <tt class="docutils literal"><span class="pre">QAccel::connectItem()</span></tt> connects an internally generated
+signal to a slot. The signal is emitted when the keyboard accelerator is
+activated and it has a single integer argument that is the ID of the
+accelerator. The C++ signature is:</p>
+<div class="highlight-python"><pre>bool connectItem(int id, const QObject *receiver, const char *member);</pre>
+</div>
+<p>The corresponding SIP specification is:</p>
+<div class="highlight-python"><pre>bool connectItem(int, SIP_RXOBJ_CON, SIP_SLOT_CON(int));</pre>
+</div>
+<dl class="sip-type">
+<dt id="stype-SIP_SLOT_DIS">
+<tt class="descname">SIP_SLOT_DIS</tt><a class="headerlink" href="#stype-SIP_SLOT_DIS" title="Permalink to this definition">¶</a></dt>
+<dd></dd></dl>
+
+<p>This is a <tt class="docutils literal"><span class="pre">const</span> <span class="pre">char</span> <span class="pre">*</span></tt> that is used as the type of the member instead of
+<tt class="docutils literal"><span class="pre">const</span> <span class="pre">char</span> <span class="pre">*</span></tt> in functions that implement the disconnection of an
+internally generated signal to a slot. The type includes a comma separated
+list of types that is the C++ signature of of the signal.</p>
+</div>
+<div class="section" id="classic-division-and-true-division">
+<h2>Classic Division and True Division<a class="headerlink" href="#classic-division-and-true-division" title="Permalink to this headline">¶</a></h2>
+<p>SIP supports the <tt class="docutils literal"><span class="pre">__div__</span></tt> and <tt class="docutils literal"><span class="pre">__truediv__</span></tt> special methods (and the
+corresponding inplace versions) for both Python v2 and v3.</p>
+<p>For Python v2 the <tt class="docutils literal"><span class="pre">__div__</span></tt> method will be used for both classic and true
+division if a <tt class="docutils literal"><span class="pre">__truediv__</span></tt> method is not defined.</p>
+<p>For Python v3 the <tt class="docutils literal"><span class="pre">__div__</span></tt> method will be used for true division if a
+<tt class="docutils literal"><span class="pre">__truediv__</span></tt> method is not defined.</p>
+<p>For all versions of Python, if both methods are defined then <tt class="docutils literal"><span class="pre">__div__</span></tt>
+should be defined first.</p>
+</div>
+</div>
+
+
+ </div>
+ </div>
+ </div>
+ <div class="sphinxsidebar">
+ <div class="sphinxsidebarwrapper">
+ <h3><a href="index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference external" href="#">SIP Specification Files</a><ul>
+<li><a class="reference external" href="#syntax-definition">Syntax Definition</a></li>
+<li><a class="reference external" href="#variable-numbers-of-arguments">Variable Numbers of Arguments</a></li>
+<li><a class="reference external" href="#additional-sip-types">Additional SIP Types</a></li>
+<li><a class="reference external" href="#classic-division-and-true-division">Classic Division and True Division</a></li>
+</ul>
+</li>
+</ul>
+
+ <h4>Previous topic</h4>
+ <p class="topless"><a href="command_line.html"
+ title="previous chapter">The SIP Command Line</a></p>
+ <h4>Next topic</h4>
+ <p class="topless"><a href="directives.html"
+ title="next chapter">Directives</a></p>
+ <div id="searchbox" style="display: none">
+ <h3>Quick search</h3>
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" size="18" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ <p class="searchtip" style="font-size: 90%">
+ Enter search terms or a module, class or function name.
+ </p>
+ </div>
+ <script type="text/javascript">$('#searchbox').show(0);</script>
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ >modules</a> |</li>
+ <li class="right" >
+ <a href="directives.html" title="Directives"
+ >next</a> |</li>
+ <li class="right" >
+ <a href="command_line.html" title="The SIP Command Line"
+ >previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+ <div class="footer">
+ &copy; Copyright 2010 Riverbank Computing Limited.
+ Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.4.
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/doc/html/using.html b/doc/html/using.html
new file mode 100644
index 0000000..5ff6786
--- /dev/null
+++ b/doc/html/using.html
@@ -0,0 +1,731 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+ <title>Using SIP &mdash; SIP 4.10.5 Reference Guide</title>
+ <link rel="stylesheet" href="_static/default.css" type="text/css" />
+ <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
+ <script type="text/javascript">
+ var DOCUMENTATION_OPTIONS = {
+ URL_ROOT: '#',
+ VERSION: '4.10.5',
+ COLLAPSE_MODINDEX: false,
+ FILE_SUFFIX: '.html',
+ HAS_SOURCE: true
+ };
+ </script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <link rel="top" title="SIP 4.10.5 Reference Guide" href="index.html" />
+ <link rel="next" title="The SIP Command Line" href="command_line.html" />
+ <link rel="prev" title="Installation" href="installation.html" />
+ </head>
+ <body>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ accesskey="I">index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ accesskey="M">modules</a> |</li>
+ <li class="right" >
+ <a href="command_line.html" title="The SIP Command Line"
+ accesskey="N">next</a> |</li>
+ <li class="right" >
+ <a href="installation.html" title="Installation"
+ accesskey="P">previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+
+ <div class="document">
+ <div class="documentwrapper">
+ <div class="bodywrapper">
+ <div class="body">
+
+ <div class="section" id="using-sip">
+<span id="ref-using"></span><h1>Using SIP<a class="headerlink" href="#using-sip" title="Permalink to this headline">¶</a></h1>
+<p>Bindings are generated by the SIP code generator from a number of specification
+files, typically with a <tt class="docutils literal"><span class="pre">.sip</span></tt> extension. Specification files look very
+similar to C and C++ header files, but often with additional information (in
+the form of a <em>directive</em> or an <em>annotation</em>) and code so that the bindings
+generated can be finely tuned.</p>
+<div class="section" id="a-simple-c-example">
+<span id="ref-simple-c-example"></span><h2>A Simple C++ Example<a class="headerlink" href="#a-simple-c-example" title="Permalink to this headline">¶</a></h2>
+<p>We start with a simple example. Let&#8217;s say you have a (fictional) C++ library
+that implements a single class called <tt class="docutils literal"><span class="pre">Word</span></tt>. The class has one constructor
+that takes a <tt class="docutils literal"><span class="pre">\0</span></tt> terminated character string as its single argument. The
+class has one method called <tt class="docutils literal"><span class="pre">reverse()</span></tt> which takes no arguments and returns
+a <tt class="docutils literal"><span class="pre">\0</span></tt> terminated character string. The interface to the class is defined in
+a header file called <tt class="docutils literal"><span class="pre">word.h</span></tt> which might look something like this:</p>
+<div class="highlight-python"><pre>// Define the interface to the word library.
+
+class Word {
+ const char *the_word;
+
+public:
+ Word(const char *w);
+
+ char *reverse() const;
+};</pre>
+</div>
+<p>The corresponding SIP specification file would then look something like this:</p>
+<div class="highlight-python"><pre>// Define the SIP wrapper to the word library.
+
+%Module word 0
+
+class Word {
+
+%TypeHeaderCode
+#include &lt;word.h&gt;
+%End
+
+public:
+ Word(const char *w);
+
+ char *reverse() const;
+};</pre>
+</div>
+<p>Obviously a SIP specification file looks very much like a C++ (or C) header
+file, but SIP does not include a full C++ parser. Let&#8217;s look at the
+differences between the two files.</p>
+<blockquote>
+<ul class="simple">
+<li>The <a class="reference external" href="directives.html#directive-%Module"><tt class="xref docutils literal"><span class="pre">%Module</span></tt></a> directive has been added <a class="footnote-reference" href="#id4" id="id1">[1]</a>. This is used to
+name the Python module that is being created and to give it a
+<em>generation</em> number. In this example these are <tt class="docutils literal"><span class="pre">word</span></tt> and <tt class="docutils literal"><span class="pre">0</span></tt>
+respectively. The generation number is effectively the version number of
+the module.</li>
+<li>The <a class="reference external" href="directives.html#directive-%TypeHeaderCode"><tt class="xref docutils literal"><span class="pre">%TypeHeaderCode</span></tt></a> directive has been added. The text
+between this and the following <a class="reference external" href="directives.html#directive-%End"><tt class="xref docutils literal"><span class="pre">%End</span></tt></a> directive is included
+literally in the code that SIP generates. Normally it is used, as in
+this case, to <tt class="docutils literal"><span class="pre">#include</span></tt> the corresponding C++ (or C) header file <a class="footnote-reference" href="#id5" id="id2">[2]</a>.</li>
+<li>The declaration of the private variable <tt class="docutils literal"><span class="pre">this_word</span></tt> has been removed.
+SIP does not support access to either private or protected instance
+variables.</li>
+</ul>
+</blockquote>
+<p>If we want to we can now generate the C++ code in the current directory by
+running the following command:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">sip</span> <span class="o">-</span><span class="n">c</span> <span class="o">.</span> <span class="n">word</span><span class="o">.</span><span class="n">sip</span>
+</pre></div>
+</div>
+<p>However, that still leaves us with the task of compiling the generated code and
+linking it against all the necessary libraries. It&#8217;s much easier to use the
+<a class="reference external" href="build_system.html#ref-build-system"><em>SIP build system</em></a> to do the whole thing.</p>
+<p>Using the SIP build system is simply a matter of writing a small Python script.
+In this simple example we will assume that the <tt class="docutils literal"><span class="pre">word</span></tt> library we are wrapping
+and it&#8217;s header file are installed in standard system locations and will be
+found by the compiler and linker without having to specify any additional
+flags. In a more realistic example your Python script may take command line
+options, or search a set of directories to deal with different configurations
+and installations.</p>
+<p>This is the simplest script (conventionally called <tt class="docutils literal"><span class="pre">configure.py</span></tt>):</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">os</span>
+<span class="kn">import</span> <span class="nn">sipconfig</span>
+
+<span class="c"># The name of the SIP build file generated by SIP and used by the build</span>
+<span class="c"># system.</span>
+<span class="n">build_file</span> <span class="o">=</span> <span class="s">&quot;word.sbf&quot;</span>
+
+<span class="c"># Get the SIP configuration information.</span>
+<span class="n">config</span> <span class="o">=</span> <span class="n">sipconfig</span><span class="o">.</span><span class="n">Configuration</span><span class="p">()</span>
+
+<span class="c"># Run SIP to generate the code.</span>
+<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="s">&quot; &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">config</span><span class="o">.</span><span class="n">sip_bin</span><span class="p">,</span> <span class="s">&quot;-c&quot;</span><span class="p">,</span> <span class="s">&quot;.&quot;</span><span class="p">,</span> <span class="s">&quot;-b&quot;</span><span class="p">,</span> <span class="n">build_file</span><span class="p">,</span> <span class="s">&quot;word.sip&quot;</span><span class="p">]))</span>
+
+<span class="c"># Create the Makefile.</span>
+<span class="n">makefile</span> <span class="o">=</span> <span class="n">sipconfig</span><span class="o">.</span><span class="n">SIPModuleMakefile</span><span class="p">(</span><span class="n">config</span><span class="p">,</span> <span class="n">build_file</span><span class="p">)</span>
+
+<span class="c"># Add the library we are wrapping. The name doesn&#39;t include any platform</span>
+<span class="c"># specific prefixes or extensions (e.g. the &quot;lib&quot; prefix on UNIX, or the</span>
+<span class="c"># &quot;.dll&quot; extension on Windows).</span>
+<span class="n">makefile</span><span class="o">.</span><span class="n">extra_libs</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;word&quot;</span><span class="p">]</span>
+
+<span class="c"># Generate the Makefile itself.</span>
+<span class="n">makefile</span><span class="o">.</span><span class="n">generate</span><span class="p">()</span>
+</pre></div>
+</div>
+<p>Hopefully this script is self-documenting. The key parts are the
+<tt class="docutils literal"><span class="pre">Configuration</span></tt> and <tt class="docutils literal"><span class="pre">SIPModuleMakefile</span></tt> classes. The build system contains
+other Makefile classes, for example to build programs or to call other
+Makefiles in sub-directories.</p>
+<p>After running the script (using the Python interpreter the extension module is
+being created for) the generated C++ code and <tt class="docutils literal"><span class="pre">Makefile</span></tt> will be in the
+current directory.</p>
+<p>To compile and install the extension module, just run the following
+commands <a class="footnote-reference" href="#id6" id="id3">[3]</a>:</p>
+<div class="highlight-python"><pre>make
+make install</pre>
+</div>
+<p>That&#8217;s all there is to it.</p>
+<p>See <a class="reference external" href="distutils.html#ref-distutils"><em>Building Your Extension with distutils</em></a> for an example of how to build this example using
+distutils.</p>
+<table class="docutils footnote" frame="void" id="id4" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td>All SIP directives start with a <tt class="docutils literal"><span class="pre">%</span></tt> as the first non-whitespace
+character of a line.</td></tr>
+</tbody>
+</table>
+<table class="docutils footnote" frame="void" id="id5" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id2">[2]</a></td><td>SIP includes many code directives like this. They differ in where the
+supplied code is placed by SIP in the generated code.</td></tr>
+</tbody>
+</table>
+<table class="docutils footnote" frame="void" id="id6" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id3">[3]</a></td><td>On Windows you might run <tt class="docutils literal"><span class="pre">nmake</span></tt> or <tt class="docutils literal"><span class="pre">mingw32-make</span></tt> instead.</td></tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="id7">
+<h2>A Simple C Example<a class="headerlink" href="#id7" title="Permalink to this headline">¶</a></h2>
+<p>Let&#8217;s now look at a very similar example of wrapping a fictional C library:</p>
+<div class="highlight-python"><pre>/* Define the interface to the word library. */
+
+struct Word {
+ const char *the_word;
+};
+
+struct Word *create_word(const char *w);
+char *reverse(struct Word *word);</pre>
+</div>
+<p>The corresponding SIP specification file would then look something like this:</p>
+<div class="highlight-python"><pre>/* Define the SIP wrapper to the word library. */
+
+%CModule word 0
+
+struct Word {
+
+%TypeHeaderCode
+#include &lt;word.h&gt;
+%End
+
+ const char *the_word;
+};
+
+struct Word *create_word(const char *w) /Factory/;
+char *reverse(struct Word *word);</pre>
+</div>
+<p>Again, let&#8217;s look at the differences between the two files.</p>
+<blockquote>
+<ul class="simple">
+<li>The <a class="reference external" href="directives.html#directive-%CModule"><tt class="xref docutils literal"><span class="pre">%CModule</span></tt></a> directive has been added. This has the same
+syntax as the <a class="reference external" href="directives.html#directive-%Module"><tt class="xref docutils literal"><span class="pre">%Module</span></tt></a> directive used in the previous example
+but tells SIP that the library being wrapped is implemented in C rather
+than C++.</li>
+<li>The <a class="reference external" href="directives.html#directive-%TypeHeaderCode"><tt class="xref docutils literal"><span class="pre">%TypeHeaderCode</span></tt></a> directive has been added.</li>
+<li>The <a class="reference external" href="annotations.html#fanno-Factory"><tt class="xref docutils literal"><span class="pre">Factory</span></tt></a> annotation has been added to the <tt class="docutils literal"><span class="pre">create_word()</span></tt>
+function. This tells SIP that a newly created structure is being
+returned and it is owned by Python.</li>
+</ul>
+</blockquote>
+<p>The <tt class="docutils literal"><span class="pre">configure.py</span></tt> build system script described in the previous example can
+be used for this example without change.</p>
+</div>
+<div class="section" id="a-more-complex-c-example">
+<h2>A More Complex C++ Example<a class="headerlink" href="#a-more-complex-c-example" title="Permalink to this headline">¶</a></h2>
+<p>In this last example we will wrap a fictional C++ library that contains a class
+that is derived from a Qt class. This will demonstrate how SIP allows a class
+hierarchy to be split across multiple Python extension modules, and will
+introduce SIP&#8217;s versioning system.</p>
+<p>The library contains a single C++ class called <tt class="docutils literal"><span class="pre">Hello</span></tt> which is derived from
+Qt&#8217;s <tt class="docutils literal"><span class="pre">QLabel</span></tt> class. It behaves just like <tt class="docutils literal"><span class="pre">QLabel</span></tt> except that the text
+in the label is hard coded to be <tt class="docutils literal"><span class="pre">Hello</span> <span class="pre">World</span></tt>. To make the example more
+interesting we&#8217;ll also say that the library only supports Qt v4.2 and later,
+and also includes a function called <tt class="docutils literal"><span class="pre">setDefault()</span></tt> that is not implemented
+in the Windows version of the library.</p>
+<p>The <tt class="docutils literal"><span class="pre">hello.h</span></tt> header file looks something like this:</p>
+<div class="highlight-python"><pre>// Define the interface to the hello library.
+
+#include &lt;qlabel.h&gt;
+#include &lt;qwidget.h&gt;
+#include &lt;qstring.h&gt;
+
+class Hello : public QLabel {
+ // This is needed by the Qt Meta-Object Compiler.
+ Q_OBJECT
+
+public:
+ Hello(QWidget *parent = 0);
+
+private:
+ // Prevent instances from being copied.
+ Hello(const Hello &amp;);
+ Hello &amp;operator=(const Hello &amp;);
+};
+
+#if !defined(Q_OS_WIN)
+void setDefault(const QString &amp;def);
+#endif</pre>
+</div>
+<p>The corresponding SIP specification file would then look something like this:</p>
+<div class="highlight-python"><pre>// Define the SIP wrapper to the hello library.
+
+%Module hello 0
+
+%Import QtGui/QtGuimod.sip
+
+%If (Qt_4_2_0 -)
+
+class Hello : QLabel {
+
+%TypeHeaderCode
+#include &lt;hello.h&gt;
+%End
+
+public:
+ Hello(QWidget *parent /TransferThis/ = 0);
+
+private:
+ Hello(const Hello &amp;);
+};
+
+%If (!WS_WIN)
+void setDefault(const QString &amp;def);
+%End
+
+%End</pre>
+</div>
+<p>Again we look at the differences, but we&#8217;ll skip those that we&#8217;ve looked at in
+previous examples.</p>
+<blockquote>
+<ul class="simple">
+<li>The <a class="reference external" href="directives.html#directive-%Import"><tt class="xref docutils literal"><span class="pre">%Import</span></tt></a> directive has been added to specify that we are
+extending the class hierarchy defined in the file <tt class="docutils literal"><span class="pre">QtGui/QtGuimod.sip</span></tt>.
+This file is part of PyQt. The build system will take care of finding
+the file&#8217;s exact location.</li>
+<li>The <a class="reference external" href="directives.html#directive-%If"><tt class="xref docutils literal"><span class="pre">%If</span></tt></a> directive has been added to specify that everything
+<a class="footnote-reference" href="#id11" id="id8">[4]</a> up to the matching <a class="reference external" href="directives.html#directive-%End"><tt class="xref docutils literal"><span class="pre">%End</span></tt></a> directive only applies to Qt
+v4.2 and later. <tt class="docutils literal"><span class="pre">Qt_4_2_0</span></tt> is a <em>tag</em> defined in <tt class="docutils literal"><span class="pre">QtCoremod.sip</span></tt>
+<a class="footnote-reference" href="#id12" id="id9">[5]</a> using the <a class="reference external" href="directives.html#directive-%Timeline"><tt class="xref docutils literal"><span class="pre">%Timeline</span></tt></a> directive. <a class="reference external" href="directives.html#directive-%Timeline"><tt class="xref docutils literal"><span class="pre">%Timeline</span></tt></a>
+is used to define a tag for each version of a library&#8217;s API you are
+wrapping allowing you to maintain all the different versions in a single
+SIP specification. The build system provides support to <tt class="docutils literal"><span class="pre">configure.py</span></tt>
+scripts for working out the correct tags to use according to which
+version of the library is actually installed.</li>
+<li>The <tt class="docutils literal"><span class="pre">public</span></tt> keyword used in defining the super-classes has been
+removed. This is not supported by SIP.</li>
+<li>The <a class="reference external" href="annotations.html#aanno-TransferThis"><tt class="xref docutils literal"><span class="pre">TransferThis</span></tt></a> annotation has been added to the constructor&#8217;s
+argument. It specifies that if the argument is not 0 (i.e. the <tt class="docutils literal"><span class="pre">Hello</span></tt>
+instance being constructed has a parent) then ownership of the instance
+is transferred from Python to C++. It is needed because Qt maintains
+objects (i.e. instances derived from the <tt class="docutils literal"><span class="pre">QObject</span></tt> class) in a
+hierachy. When an object is destroyed all of its children are also
+automatically destroyed. It is important, therefore, that the Python
+garbage collector doesn&#8217;t also try and destroy them. This is covered in
+more detail in <a class="reference internal" href="#ref-object-ownership"><em>Ownership of Objects</em></a>. SIP provides many other
+annotations that can be applied to arguments, functions and classes.
+Multiple annotations are separated by commas. Annotations may have
+values.</li>
+<li>The <tt class="docutils literal"><span class="pre">=</span></tt> operator has been removed. This operator is not supported by
+SIP.</li>
+<li>The <a class="reference external" href="directives.html#directive-%If"><tt class="xref docutils literal"><span class="pre">%If</span></tt></a> directive has been added to specify that everything
+up to the matching <a class="reference external" href="directives.html#directive-%End"><tt class="xref docutils literal"><span class="pre">%End</span></tt></a> directive does not apply to Windows.
+<tt class="docutils literal"><span class="pre">WS_WIN</span></tt> is another tag defined by PyQt, this time using the
+<a class="reference external" href="directives.html#directive-%Platforms"><tt class="xref docutils literal"><span class="pre">%Platforms</span></tt></a> directive. Tags defined by the
+<a class="reference external" href="directives.html#directive-%Platforms"><tt class="xref docutils literal"><span class="pre">%Platforms</span></tt></a> directive are mutually exclusive, i.e. only one
+may be valid at a time <a class="footnote-reference" href="#id13" id="id10">[6]</a>.</li>
+</ul>
+</blockquote>
+<p>One question you might have at this point is why bother to define the private
+copy constructor when it can never be called from Python? The answer is to
+prevent the automatic generation of a public copy constructor.</p>
+<p>We now look at the <tt class="docutils literal"><span class="pre">configure.py</span></tt> script. This is a little different to the
+script in the previous examples for two related reasons.</p>
+<p>Firstly, PyQt includes a pure Python module called <tt class="docutils literal"><span class="pre">pyqtconfig</span></tt> that extends
+the SIP build system for modules, like our example, that build on top of PyQt.
+It deals with the details of which version of Qt is being used (i.e. it
+determines what the correct tags are) and where it is installed. This is
+called a module&#8217;s configuration module.</p>
+<p>Secondly, we generate a configuration module (called <tt class="docutils literal"><span class="pre">helloconfig</span></tt>) for our
+own <tt class="docutils literal"><span class="pre">hello</span></tt> module. There is no need to do this, but if there is a chance
+that somebody else might want to extend your C++ library then it would make
+life easier for them.</p>
+<p>Now we have two scripts. First the <tt class="docutils literal"><span class="pre">configure.py</span></tt> script:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">os</span>
+<span class="kn">import</span> <span class="nn">sipconfig</span>
+<span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">pyqtconfig</span>
+
+<span class="c"># The name of the SIP build file generated by SIP and used by the build</span>
+<span class="c"># system.</span>
+<span class="n">build_file</span> <span class="o">=</span> <span class="s">&quot;hello.sbf&quot;</span>
+
+<span class="c"># Get the PyQt configuration information.</span>
+<span class="n">config</span> <span class="o">=</span> <span class="n">pyqtconfig</span><span class="o">.</span><span class="n">Configuration</span><span class="p">()</span>
+
+<span class="c"># Get the extra SIP flags needed by the imported PyQt modules. Note that</span>
+<span class="c"># this normally only includes those flags (-x and -t) that relate to SIP&#39;s</span>
+<span class="c"># versioning system.</span>
+<span class="n">pyqt_sip_flags</span> <span class="o">=</span> <span class="n">config</span><span class="o">.</span><span class="n">pyqt_sip_flags</span>
+
+<span class="c"># Run SIP to generate the code. Note that we tell SIP where to find the qt</span>
+<span class="c"># module&#39;s specification files using the -I flag.</span>
+<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="s">&quot; &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">config</span><span class="o">.</span><span class="n">sip_bin</span><span class="p">,</span> <span class="s">&quot;-c&quot;</span><span class="p">,</span> <span class="s">&quot;.&quot;</span><span class="p">,</span> <span class="s">&quot;-b&quot;</span><span class="p">,</span> <span class="n">build_file</span><span class="p">,</span> <span class="s">&quot;-I&quot;</span><span class="p">,</span> <span class="n">config</span><span class="o">.</span><span class="n">pyqt_sip_dir</span><span class="p">,</span> <span class="n">pyqt_sip_flags</span><span class="p">,</span> <span class="s">&quot;hello.sip&quot;</span><span class="p">]))</span>
+
+<span class="c"># We are going to install the SIP specification file for this module and</span>
+<span class="c"># its configuration module.</span>
+<span class="n">installs</span> <span class="o">=</span> <span class="p">[]</span>
+
+<span class="n">installs</span><span class="o">.</span><span class="n">append</span><span class="p">([</span><span class="s">&quot;hello.sip&quot;</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">config</span><span class="o">.</span><span class="n">default_sip_dir</span><span class="p">,</span> <span class="s">&quot;hello&quot;</span><span class="p">)])</span>
+
+<span class="n">installs</span><span class="o">.</span><span class="n">append</span><span class="p">([</span><span class="s">&quot;helloconfig.py&quot;</span><span class="p">,</span> <span class="n">config</span><span class="o">.</span><span class="n">default_mod_dir</span><span class="p">])</span>
+
+<span class="c"># Create the Makefile. The QtGuiModuleMakefile class provided by the</span>
+<span class="c"># pyqtconfig module takes care of all the extra preprocessor, compiler and</span>
+<span class="c"># linker flags needed by the Qt library.</span>
+<span class="n">makefile</span> <span class="o">=</span> <span class="n">pyqtconfig</span><span class="o">.</span><span class="n">QtGuiModuleMakefile</span><span class="p">(</span>
+ <span class="n">configuration</span><span class="o">=</span><span class="n">config</span><span class="p">,</span>
+ <span class="n">build_file</span><span class="o">=</span><span class="n">build_file</span><span class="p">,</span>
+ <span class="n">installs</span><span class="o">=</span><span class="n">installs</span>
+<span class="p">)</span>
+
+<span class="c"># Add the library we are wrapping. The name doesn&#39;t include any platform</span>
+<span class="c"># specific prefixes or extensions (e.g. the &quot;lib&quot; prefix on UNIX, or the</span>
+<span class="c"># &quot;.dll&quot; extension on Windows).</span>
+<span class="n">makefile</span><span class="o">.</span><span class="n">extra_libs</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;hello&quot;</span><span class="p">]</span>
+
+<span class="c"># Generate the Makefile itself.</span>
+<span class="n">makefile</span><span class="o">.</span><span class="n">generate</span><span class="p">()</span>
+
+<span class="c"># Now we create the configuration module. This is done by merging a Python</span>
+<span class="c"># dictionary (whose values are normally determined dynamically) with a</span>
+<span class="c"># (static) template.</span>
+<span class="n">content</span> <span class="o">=</span> <span class="p">{</span>
+ <span class="c"># Publish where the SIP specifications for this module will be</span>
+ <span class="c"># installed.</span>
+ <span class="s">&quot;hello_sip_dir&quot;</span><span class="p">:</span> <span class="n">config</span><span class="o">.</span><span class="n">default_sip_dir</span><span class="p">,</span>
+
+ <span class="c"># Publish the set of SIP flags needed by this module. As these are the</span>
+ <span class="c"># same flags needed by the qt module we could leave it out, but this</span>
+ <span class="c"># allows us to change the flags at a later date without breaking</span>
+ <span class="c"># scripts that import the configuration module.</span>
+ <span class="s">&quot;hello_sip_flags&quot;</span><span class="p">:</span> <span class="n">pyqt_sip_flags</span>
+<span class="p">}</span>
+
+<span class="c"># This creates the helloconfig.py module from the helloconfig.py.in</span>
+<span class="c"># template and the dictionary.</span>
+<span class="n">sipconfig</span><span class="o">.</span><span class="n">create_config_module</span><span class="p">(</span><span class="s">&quot;helloconfig.py&quot;</span><span class="p">,</span> <span class="s">&quot;helloconfig.py.in&quot;</span><span class="p">,</span> <span class="n">content</span><span class="p">)</span>
+</pre></div>
+</div>
+<p>Next we have the <tt class="docutils literal"><span class="pre">helloconfig.py.in</span></tt> template script:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">PyQt4</span> <span class="kn">import</span> <span class="n">pyqtconfig</span>
+
+<span class="c"># These are installation specific values created when Hello was configured.</span>
+<span class="c"># The following line will be replaced when this template is used to create</span>
+<span class="c"># the final configuration module.</span>
+<span class="c"># @SIP_CONFIGURATION@</span>
+
+<span class="k">class</span> <span class="nc">Configuration</span><span class="p">(</span><span class="n">pyqtconfig</span><span class="o">.</span><span class="n">Configuration</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;The class that represents Hello configuration values.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sub_cfg</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Initialise an instance of the class.</span>
+
+<span class="sd"> sub_cfg is the list of sub-class configurations. It should be None</span>
+<span class="sd"> when called normally.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="c"># This is all standard code to be copied verbatim except for the</span>
+ <span class="c"># name of the module containing the super-class.</span>
+ <span class="k">if</span> <span class="n">sub_cfg</span><span class="p">:</span>
+ <span class="n">cfg</span> <span class="o">=</span> <span class="n">sub_cfg</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">cfg</span> <span class="o">=</span> <span class="p">[]</span>
+
+ <span class="n">cfg</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">_pkg_config</span><span class="p">)</span>
+
+ <span class="n">pyqtconfig</span><span class="o">.</span><span class="n">Configuration</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cfg</span><span class="p">)</span>
+
+<span class="k">class</span> <span class="nc">HelloModuleMakefile</span><span class="p">(</span><span class="n">pyqtconfig</span><span class="o">.</span><span class="n">QtGuiModuleMakefile</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;The Makefile class for modules that %Import hello.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="k">def</span> <span class="nf">finalise</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="sd">&quot;&quot;&quot;Finalise the macros.</span>
+<span class="sd"> &quot;&quot;&quot;</span>
+ <span class="c"># Make sure our C++ library is linked.</span>
+ <span class="bp">self</span><span class="o">.</span><span class="n">extra_libs</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;hello&quot;</span><span class="p">)</span>
+
+ <span class="c"># Let the super-class do what it needs to.</span>
+ <span class="n">pyqtconfig</span><span class="o">.</span><span class="n">QtGuiModuleMakefile</span><span class="o">.</span><span class="n">finalise</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
+</pre></div>
+</div>
+<p>Again, we hope that the scripts are self documenting.</p>
+<table class="docutils footnote" frame="void" id="id11" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id8">[4]</a></td><td>Some parts of a SIP specification aren&#8217;t subject to version control.</td></tr>
+</tbody>
+</table>
+<table class="docutils footnote" frame="void" id="id12" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id9">[5]</a></td><td>Actually in <tt class="docutils literal"><span class="pre">versions.sip</span></tt>. PyQt uses the <a class="reference external" href="directives.html#directive-%Include"><tt class="xref docutils literal"><span class="pre">%Include</span></tt></a>
+directive to split the SIP specification for Qt across a large number of
+separate <tt class="docutils literal"><span class="pre">.sip</span></tt> files.</td></tr>
+</tbody>
+</table>
+<table class="docutils footnote" frame="void" id="id13" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id10">[6]</a></td><td>Tags can also be defined by the <a class="reference external" href="directives.html#directive-%Feature"><tt class="xref docutils literal"><span class="pre">%Feature</span></tt></a> directive. These
+tags are not mutually exclusive, i.e. any number may be valid at a time.</td></tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="ownership-of-objects">
+<span id="ref-object-ownership"></span><h2>Ownership of Objects<a class="headerlink" href="#ownership-of-objects" title="Permalink to this headline">¶</a></h2>
+<p>When a C++ instance is wrapped a corresponding Python object is created. The
+Python object behaves as you would expect in regard to garbage collection - it
+is garbage collected when its reference count reaches zero. What then happens
+to the corresponding C++ instance? The obvious answer might be that the
+instance&#8217;s destructor is called. However the library API may say that when the
+instance is passed to a particular function, the library takes ownership of the
+instance, i.e. responsibility for calling the instance&#8217;s destructor is
+transferred from the SIP generated module to the library.</p>
+<p>Ownership of an instance may also be associated with another instance. The
+implication being that the owned instance will automatically be destroyed if
+the owning instance is destroyed. SIP keeps track of these relationships to
+ensure that Python&#8217;s cyclic garbage collector can detect and break any
+reference cycles between the owning and owned instances. The association is
+implemented as the owning instance taking a reference to the owned instance.</p>
+<p>The TransferThis, Transfer and TransferBack annotations are used to specify
+where, and it what direction, transfers of ownership happen. It is very
+important that these are specified correctly to avoid crashes (where both
+Python and C++ call the destructor) and memory leaks (where neither Python and
+C++ call the destructor).</p>
+<p>This applies equally to C structures where the structure is returned to the
+heap using the <tt class="docutils literal"><span class="pre">free()</span></tt> function.</p>
+<p>See also <a title="sipTransferTo" class="reference external" href="c_api.html#sipTransferTo"><tt class="xref docutils literal"><span class="pre">sipTransferTo()</span></tt></a>, <a title="sipTransferBack" class="reference external" href="c_api.html#sipTransferBack"><tt class="xref docutils literal"><span class="pre">sipTransferBack()</span></tt></a> and
+<a title="sipTransferBreak" class="reference external" href="c_api.html#sipTransferBreak"><tt class="xref docutils literal"><span class="pre">sipTransferBreak()</span></tt></a>.</p>
+</div>
+<div class="section" id="types-and-meta-types">
+<span id="ref-types-metatypes"></span><h2>Types and Meta-types<a class="headerlink" href="#types-and-meta-types" title="Permalink to this headline">¶</a></h2>
+<p>Every Python object (with the exception of the <tt class="xref docutils literal"><span class="pre">object</span></tt> object itself)
+has a meta-type and at least one super-type. By default an object&#8217;s meta-type
+is the meta-type of its first super-type.</p>
+<p>SIP implements two super-types, <tt class="xref docutils literal"><span class="pre">sip.simplewrapper</span></tt> and
+<a title="sip.wrapper" class="reference external" href="python_api.html#sip.wrapper"><tt class="xref docutils literal"><span class="pre">sip.wrapper</span></tt></a>, and a meta-type, <a title="sip.wrappertype" class="reference external" href="python_api.html#sip.wrappertype"><tt class="xref docutils literal"><span class="pre">sip.wrappertype</span></tt></a>.</p>
+<p><tt class="xref docutils literal"><span class="pre">sip.simplewrapper</span></tt> is the super-type of <a title="sip.wrapper" class="reference external" href="python_api.html#sip.wrapper"><tt class="xref docutils literal"><span class="pre">sip.wrapper</span></tt></a>. The
+super-type of <tt class="xref docutils literal"><span class="pre">sip.simplewrapper</span></tt> is <tt class="xref docutils literal"><span class="pre">object</span></tt>.</p>
+<p><a title="sip.wrappertype" class="reference external" href="python_api.html#sip.wrappertype"><tt class="xref docutils literal"><span class="pre">sip.wrappertype</span></tt></a> is the meta-type of both <tt class="xref docutils literal"><span class="pre">sip.simplewrapper</span></tt>
+and <a title="sip.wrapper" class="reference external" href="python_api.html#sip.wrapper"><tt class="xref docutils literal"><span class="pre">sip.wrapper</span></tt></a>. The super-type of <a title="sip.wrappertype" class="reference external" href="python_api.html#sip.wrappertype"><tt class="xref docutils literal"><span class="pre">sip.wrappertype</span></tt></a> is
+<tt class="xref docutils literal"><span class="pre">type</span></tt>.</p>
+<p><a title="sip.wrapper" class="reference external" href="python_api.html#sip.wrapper"><tt class="xref docutils literal"><span class="pre">sip.wrapper</span></tt></a> supports the concept of object ownership described in
+<a class="reference internal" href="#ref-object-ownership"><em>Ownership of Objects</em></a> and, by default, is the super-type of all the types
+that SIP generates.</p>
+<p><tt class="xref docutils literal"><span class="pre">sip.simplewrapper</span></tt> does not support the concept of object ownership but
+SIP generated types that are sub-classed from it have Python objects that take
+less memory.</p>
+<p>SIP allows a class&#8217;s meta-type and super-type to be explicitly specified using
+the <a class="reference external" href="annotations.html#canno-Metatype"><tt class="xref docutils literal"><span class="pre">Metatype</span></tt></a> and <a class="reference external" href="annotations.html#canno-Supertype"><tt class="xref docutils literal"><span class="pre">Supertype</span></tt></a> class annotations.</p>
+<p>SIP also allows the default meta-type and super-type to be changed for a module
+using the <a class="reference external" href="directives.html#directive-%DefaultMetatype"><tt class="xref docutils literal"><span class="pre">%DefaultMetatype</span></tt></a> and <a class="reference external" href="directives.html#directive-%DefaultSupertype"><tt class="xref docutils literal"><span class="pre">%DefaultSupertype</span></tt></a>
+directives. Unlike the default super-type, the default meta-type is inherited
+by importing modules.</p>
+<p>If you want to use your own meta-type or super-type then they must be
+sub-classed from one of the SIP provided types. Your types must be registered
+using <a title="sipRegisterPyType" class="reference external" href="c_api.html#sipRegisterPyType"><tt class="xref docutils literal"><span class="pre">sipRegisterPyType()</span></tt></a>. This is normally done in code specified
+using the <a class="reference external" href="directives.html#directive-%InitialisationCode"><tt class="xref docutils literal"><span class="pre">%InitialisationCode</span></tt></a> directive.</p>
+<p>As an example, PyQt4 uses <a class="reference external" href="directives.html#directive-%DefaultMetatype"><tt class="xref docutils literal"><span class="pre">%DefaultMetatype</span></tt></a> to specify a new
+meta-type that handles the interaction with Qt&#8217;s own meta-type system. It also
+uses <a class="reference external" href="directives.html#directive-%DefaultSupertype"><tt class="xref docutils literal"><span class="pre">%DefaultSupertype</span></tt></a> to specify that the smaller
+<tt class="xref docutils literal"><span class="pre">sip.simplewrapper</span></tt> super-type is normally used. Finally it uses
+<a class="reference external" href="annotations.html#canno-Supertype"><tt class="xref docutils literal"><span class="pre">Supertype</span></tt></a> as an annotation of the <tt class="docutils literal"><span class="pre">QObject</span></tt> class to override the
+default and use <a title="sip.wrapper" class="reference external" href="python_api.html#sip.wrapper"><tt class="xref docutils literal"><span class="pre">sip.wrapper</span></tt></a> as the super-type so that the parent/child
+relationships of <tt class="docutils literal"><span class="pre">QObject</span></tt> instances are properly maintained.</p>
+</div>
+<div class="section" id="lazy-type-attributes">
+<span id="ref-lazy-type-attributes"></span><h2>Lazy Type Attributes<a class="headerlink" href="#lazy-type-attributes" title="Permalink to this headline">¶</a></h2>
+<p>Instead of populating a wrapped type&#8217;s dictionary with its attributes (or
+descriptors for those attributes) SIP only creates objects for those attributes
+when they are actually needed. This is done to reduce the memory footprint and
+start up time when used to wrap large libraries with hundreds of classes and
+tens of thousands of attributes.</p>
+<p>SIP allows you to extend the handling of lazy attributes to your own attribute
+types by allowing you to register an attribute getter handler (using
+<a title="sipRegisterAttributeGetter" class="reference external" href="c_api.html#sipRegisterAttributeGetter"><tt class="xref docutils literal"><span class="pre">sipRegisterAttributeGetter()</span></tt></a>). This will be called just before a
+type&#8217;s dictionary is accessed for the first time.</p>
+</div>
+<div class="section" id="support-for-python-s-buffer-interface">
+<h2>Support for Python&#8217;s Buffer Interface<a class="headerlink" href="#support-for-python-s-buffer-interface" title="Permalink to this headline">¶</a></h2>
+<p>SIP supports Python&#8217;s buffer interface in that whenever C/C++ requires a
+<tt class="docutils literal"><span class="pre">char</span></tt> or <tt class="docutils literal"><span class="pre">char</span> <span class="pre">*</span></tt> type then any Python type that supports the buffer
+interface (including ordinary Python strings) can be used.</p>
+<p>If a buffer is made up of a number of segments then all but the first will be
+ignored.</p>
+</div>
+<div class="section" id="support-for-wide-characters">
+<h2>Support for Wide Characters<a class="headerlink" href="#support-for-wide-characters" title="Permalink to this headline">¶</a></h2>
+<p>SIP v4.6 introduced support for wide characters (i.e. the <tt class="docutils literal"><span class="pre">wchar_t</span></tt> type).
+Python&#8217;s C API includes support for converting between unicode objects and wide
+character strings and arrays. When converting from a unicode object to wide
+characters SIP creates the string or array on the heap (using memory allocated
+using <a title="sipMalloc" class="reference external" href="c_api.html#sipMalloc"><tt class="xref docutils literal"><span class="pre">sipMalloc()</span></tt></a>). This then raises the problem of how this memory
+is subsequently freed.</p>
+<p>The following describes how SIP handles this memory in the different situations
+where this is an issue.</p>
+<blockquote>
+<ul class="simple">
+<li>When a wide string or array is passed to a function or method then the
+memory is freed (using <a title="sipFree" class="reference external" href="c_api.html#sipFree"><tt class="xref docutils literal"><span class="pre">sipFree()</span></tt></a>) after than function or method
+returns.</li>
+<li>When a wide string or array is returned from a virtual method then SIP
+does not free the memory until the next time the method is called.</li>
+<li>When an assignment is made to a wide string or array instance variable
+then SIP does not first free the instance&#8217;s current string or array.</li>
+</ul>
+</blockquote>
+</div>
+<div class="section" id="the-python-global-interpreter-lock">
+<span id="ref-gil"></span><h2>The Python Global Interpreter Lock<a class="headerlink" href="#the-python-global-interpreter-lock" title="Permalink to this headline">¶</a></h2>
+<p>Python&#8217;s Global Interpretor Lock (GIL) must be acquired before calls can be
+made to the Python API. It should also be released when a potentially
+blocking call to C/C++ library is made in order to allow other Python threads
+to be executed. In addition, some C/C++ libraries may implement their own
+locking strategies that conflict with the GIL causing application deadlocks.
+SIP provides ways of specifying when the GIL is released and acquired to
+ensure that locking problems can be avoided.</p>
+<p>SIP always ensures that the GIL is acquired before making calls to the Python
+API. By default SIP does not release the GIL when making calls to the C/C++
+library being wrapped. The <a class="reference external" href="annotations.html#fanno-ReleaseGIL"><tt class="xref docutils literal"><span class="pre">ReleaseGIL</span></tt></a> annotation can be used to
+override this behaviour when required.</p>
+<p>If SIP is given the <a class="reference external" href="command_line.html#cmdoption-sip-g"><em class="xref">-g</em></a> command line option then the default
+behaviour is changed and SIP releases the GIL every time is makes calls to the
+C/C++ library being wrapped. The <a class="reference external" href="annotations.html#fanno-HoldGIL"><tt class="xref docutils literal"><span class="pre">HoldGIL</span></tt></a> annotation can be used to
+override this behaviour when required.</p>
+</div>
+<div class="section" id="managing-incompatible-apis">
+<span id="ref-incompat-apis"></span><h2>Managing Incompatible APIs<a class="headerlink" href="#managing-incompatible-apis" title="Permalink to this headline">¶</a></h2>
+<p>
+<span class="versionmodified">New in version 4.9.</span></p>
+<p>Sometimes it is necessary to change the way something is wrapped in a way that
+introduces an incompatibility. For example a new feature of Python may
+suggest that something may be wrapped in a different way to exploit that
+feature.</p>
+<p>SIP&#8217;s <a class="reference external" href="directives.html#directive-%Feature"><tt class="xref docutils literal"><span class="pre">%Feature</span></tt></a> directive could be used to provide two different
+implementations. However this would mean that the choice between the two
+implementations would have to be made when building the generated module
+potentially causing all sorts of deployment problems. It may also require
+applications to work out which implementation was available and to change
+their behaviour accordingly.</p>
+<p>Instead SIP provides limited support for providing multiple implementations
+(of classes, mapped types and functions) that can be selected by an
+application at run-time. It is then up to the application developer how they
+want to manage the migration from the old API to the new, incompatible API.</p>
+<p>This support is implemented in three parts.</p>
+<p>Firstly the <a class="reference external" href="directives.html#directive-%API"><tt class="xref docutils literal"><span class="pre">%API</span></tt></a> directive is used to define the name of an API
+and its default version number. The default version number is the one used if
+an application doesn&#8217;t explicitly set the version number to use.</p>
+<p>Secondly the <a class="reference external" href="annotations.html#canno-API"><tt class="xref docutils literal"><span class="pre">API</span> <span class="pre">class</span></tt></a>, <a class="reference external" href="annotations.html#manno-API"><tt class="xref docutils literal"><span class="pre">mapped</span> <span class="pre">type</span></tt></a> or
+<a class="reference external" href="annotations.html#fanno-API"><tt class="xref docutils literal"><span class="pre">function</span></tt></a> annotation is applied accordingly to specify the API
+and range of version numbers that a particular class, mapped type or function
+implementation should be enabled for.</p>
+<p>Finally the application calls <a title="sip.setapi" class="reference external" href="python_api.html#sip.setapi"><tt class="xref docutils literal"><span class="pre">sip.setapi()</span></tt></a> to specify the version number
+of the API that should be enabled. This call must be made before any module
+that has multiple implementations is imported for the first time.</p>
+<p>Note this mechanism is not intended as a way or providing equally valid
+alternative APIs. For example:</p>
+<div class="highlight-python"><pre>%API MyAPI 1
+
+class Foo
+{
+public:
+ void bar();
+};
+
+class Baz : Foo
+{
+public:
+ void bar() /API=MyAPI:2-/;
+};</pre>
+</div>
+<p>If the following Python code is executed then an exception will be raised:</p>
+<div class="highlight-python"><div class="highlight"><pre><span class="n">b</span> <span class="o">=</span> <span class="n">Baz</span><span class="p">()</span>
+<span class="n">b</span><span class="o">.</span><span class="n">bar</span><span class="p">()</span>
+</pre></div>
+</div>
+<p>This is because when version 1 of the <em>MyAPI</em> API (the default) is enabled
+there is no <em>Baz.bar()</em> implementation and <em>Foo.bar()</em> will not be called
+instead as might be expected.</p>
+</div>
+</div>
+
+
+ </div>
+ </div>
+ </div>
+ <div class="sphinxsidebar">
+ <div class="sphinxsidebarwrapper">
+ <h3><a href="index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference external" href="#">Using SIP</a><ul>
+<li><a class="reference external" href="#a-simple-c-example">A Simple C++ Example</a></li>
+<li><a class="reference external" href="#id7">A Simple C Example</a></li>
+<li><a class="reference external" href="#a-more-complex-c-example">A More Complex C++ Example</a></li>
+<li><a class="reference external" href="#ownership-of-objects">Ownership of Objects</a></li>
+<li><a class="reference external" href="#types-and-meta-types">Types and Meta-types</a></li>
+<li><a class="reference external" href="#lazy-type-attributes">Lazy Type Attributes</a></li>
+<li><a class="reference external" href="#support-for-python-s-buffer-interface">Support for Python&#8217;s Buffer Interface</a></li>
+<li><a class="reference external" href="#support-for-wide-characters">Support for Wide Characters</a></li>
+<li><a class="reference external" href="#the-python-global-interpreter-lock">The Python Global Interpreter Lock</a></li>
+<li><a class="reference external" href="#managing-incompatible-apis">Managing Incompatible APIs</a></li>
+</ul>
+</li>
+</ul>
+
+ <h4>Previous topic</h4>
+ <p class="topless"><a href="installation.html"
+ title="previous chapter">Installation</a></p>
+ <h4>Next topic</h4>
+ <p class="topless"><a href="command_line.html"
+ title="next chapter">The SIP Command Line</a></p>
+ <div id="searchbox" style="display: none">
+ <h3>Quick search</h3>
+ <form class="search" action="search.html" method="get">
+ <input type="text" name="q" size="18" />
+ <input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
+ </form>
+ <p class="searchtip" style="font-size: 90%">
+ Enter search terms or a module, class or function name.
+ </p>
+ </div>
+ <script type="text/javascript">$('#searchbox').show(0);</script>
+ </div>
+ </div>
+ <div class="clearer"></div>
+ </div>
+ <div class="related">
+ <h3>Navigation</h3>
+ <ul>
+ <li class="right" style="margin-right: 10px">
+ <a href="genindex.html" title="General Index"
+ >index</a></li>
+ <li class="right" >
+ <a href="modindex.html" title="Global Module Index"
+ >modules</a> |</li>
+ <li class="right" >
+ <a href="command_line.html" title="The SIP Command Line"
+ >next</a> |</li>
+ <li class="right" >
+ <a href="installation.html" title="Installation"
+ >previous</a> |</li>
+ <li><a href="index.html">SIP 4.10.5 Reference Guide</a> &raquo;</li>
+ </ul>
+ </div>
+ <div class="footer">
+ &copy; Copyright 2010 Riverbank Computing Limited.
+ Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.4.
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/sipdistutils.py b/sipdistutils.py
new file mode 100644
index 0000000..6994989
--- /dev/null
+++ b/sipdistutils.py
@@ -0,0 +1,148 @@
+# Subclasses disutils.command.build_ext,
+# replacing it with a SIP version that compiles .sip -> .cpp
+# before calling the original build_ext command.
+# Written by Giovanni Bajo <rasky at develer dot com>
+# Based on Pyrex.Distutils, written by Graham Fawcett and Darrel Gallion.
+
+import distutils.command.build_ext
+from distutils.dep_util import newer, newer_group
+import os
+import sys
+from hashlib import sha1
+
+build_ext_base = distutils.command.build_ext.build_ext
+
+def replace_suffix(path, new_suffix):
+ return os.path.splitext(path)[0] + new_suffix
+
+class build_ext (build_ext_base):
+
+ description = "Compiler SIP descriptions, then build C/C++ extensions (compile/link to build directory)"
+
+ user_options = build_ext_base.user_options[:]
+ user_options = [opt for opt in user_options if not opt[0].startswith("swig")]
+ user_options += [
+ ('sip-opts=', None,
+ "list of sip command line options"),
+ ]
+
+ def initialize_options (self):
+ build_ext_base.initialize_options(self)
+ self.sip_opts = None
+
+ def finalize_options (self):
+ build_ext_base.finalize_options(self)
+ if self.sip_opts is None:
+ self.sip_opts = []
+ else:
+ self.sip_opts = self.sip_opts.split(' ')
+
+ def _get_sip_output_list(self, sbf):
+ """
+ Parse the sbf file specified to extract the name of the generated source
+ files. Make them absolute assuming they reside in the temp directory.
+ """
+ for L in file(sbf):
+ key, value = L.split("=", 1)
+ if key.strip() == "sources":
+ out = []
+ for o in value.split():
+ out.append(os.path.join(self.build_temp, o))
+ return out
+
+ raise RuntimeError("cannot parse SIP-generated '%s'" % sbf)
+
+ def _find_sip(self):
+ import sipconfig
+ cfg = sipconfig.Configuration()
+ if os.name == "nt":
+ if not os.path.splitext(os.path.basename(cfg.sip_bin))[1]:
+ return cfg.sip_bin + ".exe"
+ return cfg.sip_bin
+
+ def _sip_inc_dir(self):
+ import sipconfig
+ cfg = sipconfig.Configuration()
+ return cfg.sip_inc_dir
+
+ def _sip_sipfiles_dir(self):
+ import sipconfig
+ cfg = sipconfig.Configuration()
+ return cfg.default_sip_dir
+
+ def _sip_calc_signature(self):
+ sip_bin = self._find_sip()
+ return sha1(open(sip_bin, "rb").read()).hexdigest()
+
+ def _sip_signature_file(self):
+ return os.path.join(self.build_temp, "sip.signature")
+
+ def build_extension (self, ext):
+ oldforce = self.force
+
+ if not self.force:
+ sip_sources = [source for source in ext.sources if source.endswith('.sip')]
+ if sip_sources:
+ sigfile = self._sip_signature_file()
+ if not os.path.isfile(sigfile):
+ self.force = True
+ else:
+ old_sig = open(sigfile).read()
+ new_sig = self._sip_calc_signature()
+ if old_sig != new_sig:
+ self.force = True
+
+ build_ext_base.build_extension(self, ext)
+
+ self.force = oldforce
+
+ def swig_sources (self, sources, extension=None):
+ if not self.extensions:
+ return
+
+ # Add the SIP include directory to the include path
+ if extension is not None:
+ extension.include_dirs.append(self._sip_inc_dir())
+ depends = extension.depends
+ else:
+ # pre-2.4 compatibility
+ self.include_dirs.append(self._sip_inc_dir())
+ depends = [] # ?
+
+ # Filter dependencies list: we are interested only in .sip files,
+ # since the main .sip files can only depend on additional .sip
+ # files. For instance, if a .h changes, there is no need to
+ # run sip again.
+ depends = [f for f in depends if os.path.splitext(f)[1] == ".sip"]
+
+ # Create the temporary directory if it does not exist already
+ if not os.path.isdir(self.build_temp):
+ os.makedirs(self.build_temp)
+
+ # Collect the names of the source (.sip) files
+ sip_sources = []
+ sip_sources = [source for source in sources if source.endswith('.sip')]
+ other_sources = [source for source in sources if not source.endswith('.sip')]
+ generated_sources = []
+
+ sip_bin = self._find_sip()
+
+ for sip in sip_sources:
+ # Use the sbf file as dependency check
+ sipbasename = os.path.basename(sip)
+ sbf = os.path.join(self.build_temp, replace_suffix(sipbasename, ".sbf"))
+ if newer_group([sip]+depends, sbf) or self.force:
+ self._sip_compile(sip_bin, sip, sbf)
+ open(self._sip_signature_file(), "w").write(self._sip_calc_signature())
+ out = self._get_sip_output_list(sbf)
+ generated_sources.extend(out)
+
+ return generated_sources + other_sources
+
+ def _sip_compile(self, sip_bin, source, sbf):
+ self.spawn([sip_bin] + self.sip_opts +
+ ["-c", self.build_temp,
+ "-b", sbf,
+ "-I", self._sip_sipfiles_dir(),
+ source])
+
diff --git a/sipgen/export.c b/sipgen/export.c
new file mode 100644
index 0000000..641ea32
--- /dev/null
+++ b/sipgen/export.c
@@ -0,0 +1,1136 @@
+/*
+ * The XML and API file generator module for SIP.
+ *
+ * Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com>
+ *
+ * This file is part of SIP.
+ *
+ * This copy of SIP is licensed for use under the terms of the SIP License
+ * Agreement. See the file LICENSE for more details.
+ *
+ * This copy of SIP may also used under the terms of the GNU General Public
+ * License v2 or v3 as published by the Free Software Foundation which can be
+ * found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
+ *
+ * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+
+#include "sip.h"
+
+
+#define XML_VERSION_NR 0 /* The schema version number. */
+
+/* Icon numbers. The values are those used by the eric IDE. */
+#define CLASS_ID 1
+#define METHOD_ID 4
+#define VARIABLE_ID 7
+#define ENUM_ID 10
+
+
+static void apiEnums(sipSpec *pt, moduleDef *mod, classDef *scope, FILE *fp);
+static void apiVars(sipSpec *pt, moduleDef *mod, classDef *scope, FILE *fp);
+static int apiCtor(sipSpec *pt, moduleDef *mod, classDef *scope, ctorDef *ct,
+ int sec, FILE *fp);
+static int apiOverload(sipSpec *pt, moduleDef *mod, classDef *scope,
+ overDef *od, int sec, FILE *fp);
+static int apiArgument(sipSpec *pt, argDef *ad, int out, int need_comma,
+ int sec, int names, int defaults, int in_str, FILE *fp);
+static void xmlClass(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp);
+static void xmlEnums(sipSpec *pt, moduleDef *mod, classDef *scope, int indent,
+ FILE *fp);
+static void xmlVars(sipSpec *pt, moduleDef *mod, classDef *scope, int indent,
+ FILE *fp);
+static void xmlFunction(sipSpec *pt, classDef *scope, memberDef *md,
+ overDef *oloads, int indent, FILE *fp);
+static int xmlCtor(sipSpec *pt, classDef *scope, ctorDef *ct, int sec,
+ int indent, FILE *fp);
+static int xmlOverload(sipSpec *pt, classDef *scope, memberDef *md,
+ overDef *od, classDef *xtnds, int stat, int sec, int indent, FILE *fp);
+static void xmlCppSignature(FILE *fp, overDef *od);
+static void xmlArgument(sipSpec *pt, argDef *ad, const char *dir, int res_xfer,
+ int sec, int indent, FILE *fp);
+static void xmlType(sipSpec *pt, argDef *ad, int sec, FILE *fp);
+static void xmlIndent(int indent, FILE *fp);
+static const char *dirAttribute(argDef *ad);
+static void exportDefaultValue(argDef *ad, int in_str, FILE *fp);
+static const char *pyType(sipSpec *pt, argDef *ad, int sec, classDef **scope);
+
+
+/*
+ * Generate the API file.
+ */
+void generateAPI(sipSpec *pt, moduleDef *mod, const char *apiFile)
+{
+ overDef *od;
+ classDef *cd;
+ FILE *fp;
+
+ /* Generate the file. */
+ if ((fp = fopen(apiFile, "w")) == NULL)
+ fatal("Unable to create file \"%s\"\n", apiFile);
+
+ apiEnums(pt, mod, NULL, fp);
+ apiVars(pt, mod, NULL, fp);
+
+ for (od = mod->overs; od != NULL; od = od->next)
+ {
+ if (od->common->module != mod)
+ continue;
+
+ if (od->common->slot != no_slot)
+ continue;
+
+ if (apiOverload(pt, mod, NULL, od, FALSE, fp))
+ apiOverload(pt, mod, NULL, od, TRUE, fp);
+ }
+
+ for (cd = pt->classes; cd != NULL; cd = cd->next)
+ {
+ ctorDef *ct;
+
+ if (cd->iff->module != mod)
+ continue;
+
+ if (isExternal(cd))
+ continue;
+
+ apiEnums(pt, mod, cd, fp);
+ apiVars(pt, mod, cd, fp);
+
+ for (ct = cd->ctors; ct != NULL; ct = ct->next)
+ {
+ if (isPrivateCtor(ct))
+ continue;
+
+ if (apiCtor(pt, mod, cd, ct, FALSE, fp))
+ apiCtor(pt, mod, cd, ct, TRUE, fp);
+ }
+
+ for (od = cd->overs; od != NULL; od = od->next)
+ {
+ if (isPrivate(od))
+ continue;
+
+ if (od->common->slot != no_slot)
+ continue;
+
+ if (apiOverload(pt, mod, cd, od, FALSE, fp))
+ apiOverload(pt, mod, cd, od, TRUE, fp);
+ }
+ }
+
+ fclose(fp);
+}
+
+
+/*
+ * Generate an API ctor.
+ */
+static int apiCtor(sipSpec *pt, moduleDef *mod, classDef *scope, ctorDef *ct,
+ int sec, FILE *fp)
+{
+ int need_sec = FALSE, need_comma, a;
+
+ /* Do the callable type form. */
+ fprintf(fp, "%s.", mod->name);
+ prScopedPythonName(fp, scope->ecd, scope->pyname->text);
+ fprintf(fp, "?%d(", CLASS_ID);
+
+ need_comma = FALSE;
+
+ for (a = 0; a < ct->pysig.nrArgs; ++a)
+ {
+ argDef *ad = &ct->pysig.args[a];
+
+ need_comma = apiArgument(pt, ad, FALSE, need_comma, sec, TRUE, TRUE,
+ FALSE, fp);
+
+ if (ad->atype == rxcon_type || ad->atype == rxdis_type)
+ need_sec = TRUE;
+ }
+
+ fprintf(fp, ")\n");
+
+ /* Do the call __init__ form. */
+ fprintf(fp, "%s.", mod->name);
+ prScopedPythonName(fp, scope->ecd, scope->pyname->text);
+ fprintf(fp, ".__init__?%d(self", CLASS_ID);
+
+ for (a = 0; a < ct->pysig.nrArgs; ++a)
+ apiArgument(pt, &ct->pysig.args[a], FALSE, TRUE, sec, TRUE, TRUE,
+ FALSE, fp);
+
+ fprintf(fp, ")\n");
+
+ return need_sec;
+}
+
+
+/*
+ * Generate the APIs for all the enums in a scope.
+ */
+static void apiEnums(sipSpec *pt, moduleDef *mod, classDef *scope, FILE *fp)
+{
+ enumDef *ed;
+
+ for (ed = pt->enums; ed != NULL; ed = ed->next)
+ {
+ enumMemberDef *emd;
+
+ if (ed->module != mod)
+ continue;
+
+ if (ed->ecd != scope)
+ continue;
+
+ if (ed->pyname != NULL)
+ {
+ fprintf(fp, "%s.", mod->name);
+ prScopedPythonName(fp, ed->ecd, ed->pyname->text);
+ fprintf(fp, "?%d\n", ENUM_ID);
+ }
+
+ for (emd = ed->members; emd != NULL; emd = emd->next)
+ {
+ fprintf(fp, "%s.", mod->name);
+ prScopedPythonName(fp, ed->ecd, emd->pyname->text);
+ fprintf(fp, "?%d\n", ENUM_ID);
+ }
+ }
+}
+
+
+/*
+ * Generate the APIs for all the variables in a scope.
+ */
+static void apiVars(sipSpec *pt, moduleDef *mod, classDef *scope, FILE *fp)
+{
+ varDef *vd;
+
+ for (vd = pt->vars; vd != NULL; vd = vd->next)
+ {
+ if (vd->module != mod)
+ continue;
+
+ if (vd->ecd != scope)
+ continue;
+
+ fprintf(fp, "%s.", mod->name);
+ prScopedPythonName(fp, vd->ecd, vd->pyname->text);
+ fprintf(fp, "?%d\n", VARIABLE_ID);
+ }
+}
+
+
+/*
+ * Generate a single API overload.
+ */
+static int apiOverload(sipSpec *pt, moduleDef *mod, classDef *scope,
+ overDef *od, int sec, FILE *fp)
+{
+ int need_sec;
+
+ fprintf(fp, "%s.", mod->name);
+ prScopedPythonName(fp, scope, od->common->pyname->text);
+ fprintf(fp, "?%d", METHOD_ID);
+
+ need_sec = prPythonSignature(pt, fp, &od->pysig, sec, TRUE, TRUE, FALSE,
+ FALSE);
+
+ fprintf(fp, "\n");
+
+ return need_sec;
+}
+
+
+/*
+ * Generate the API for an argument.
+ */
+static int apiArgument(sipSpec *pt, argDef *ad, int out, int need_comma,
+ int sec, int names, int defaults, int in_str, FILE *fp)
+{
+ const char *tname;
+ classDef *tscope;
+
+ if (isArraySize(ad))
+ return need_comma;
+
+ if (sec && (ad->atype == slotcon_type || ad->atype == slotdis_type))
+ return need_comma;
+
+ if ((tname = pyType(pt, ad, sec, &tscope)) == NULL)
+ return need_comma;
+
+ if (need_comma)
+ fprintf(fp, ", ");
+
+ prScopedPythonName(fp, tscope, tname);
+
+ /*
+ * Handle the default value is required, but ignore it if it is an output
+ * only argument.
+ */
+ if (defaults && ad->defval && !out)
+ {
+ if (names && ad->name != NULL)
+ fprintf(fp, " %s", ad->name->text);
+
+ fprintf(fp, "=");
+ prcode(fp, "%M");
+ exportDefaultValue(ad, in_str, fp);
+ prcode(fp, "%M");
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Generate the XML export file.
+ */
+void generateXML(sipSpec *pt, moduleDef *mod, const char *xmlFile)
+{
+ FILE *fp;
+ classDef *cd;
+ memberDef *md;
+
+ if ((fp = fopen(xmlFile, "w")) == NULL)
+ fatal("Unable to create file \"%s\"\n", xmlFile);
+
+ fprintf(fp, "<?xml version=\"1.0\"?>\n");
+ fprintf(fp, "<Module version=\"%u\" name=\"%s\">\n",
+ XML_VERSION_NR, mod->name);
+
+ /*
+ * Note that we don't yet handle mapped types, templates or exceptions.
+ */
+
+ for (cd = pt->classes; cd != NULL; cd = cd->next)
+ {
+ if (cd->iff->module != mod)
+ continue;
+
+ if (isExternal(cd))
+ continue;
+
+ xmlClass(pt, mod, cd, fp);
+ }
+
+ for (cd = mod->proxies; cd != NULL; cd = cd->next)
+ xmlClass(pt, mod, cd, fp);
+
+ xmlEnums(pt, mod, NULL, 1, fp);
+ xmlVars(pt, mod, NULL, 1, fp);
+
+ for (md = mod->othfuncs; md != NULL; md = md->next)
+ xmlFunction(pt, NULL, md, mod->overs, 1, fp);
+
+ fprintf(fp, "</Module>\n");
+
+ fclose(fp);
+}
+
+
+/*
+ * Generate the XML for a class.
+ */
+static void xmlClass(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp)
+{
+ int indent = 1;
+ ctorDef *ct;
+ memberDef *md;
+
+ if (isOpaque(cd))
+ {
+ xmlIndent(indent, fp);
+ fprintf(fp, "<OpaqueClass name=\"");
+ prScopedPythonName(fp, cd->ecd, cd->pyname->text);
+ fprintf(fp, "\"/>\n");
+
+ return;
+ }
+
+ xmlIndent(indent++, fp);
+ fprintf(fp, "<Class name=\"");
+ prScopedPythonName(fp, cd->ecd, cd->pyname->text);
+ fprintf(fp, "\"");
+
+ if (cd->picklecode != NULL)
+ fprintf(fp, " pickle=\"1\"");
+
+ if (cd->convtocode != NULL)
+ fprintf(fp, " convert=\"1\"");
+
+ if (cd->real != NULL)
+ fprintf(fp, " extends=\"%s\"", cd->real->iff->module->name);
+
+ if (cd->supers != NULL)
+ {
+ classList *cl;
+
+ fprintf(fp, " inherits=\"");
+
+ for (cl = cd->supers; cl != NULL; cl = cl->next)
+ {
+ if (cl != cd->supers)
+ fprintf(fp, " ");
+
+ prScopedPythonName(fp, cl->cd->ecd, cl->cd->pyname->text);
+ }
+
+ fprintf(fp, "\"");
+ }
+
+ fprintf(fp, ">\n");
+
+ xmlEnums(pt, mod, cd, indent, fp);
+ xmlVars(pt, mod, cd, indent, fp);
+
+ for (ct = cd->ctors; ct != NULL; ct = ct->next)
+ {
+ if (isPrivateCtor(ct))
+ continue;
+
+ if (xmlCtor(pt, cd, ct, FALSE, indent, fp))
+ xmlCtor(pt, cd, ct, TRUE, indent, fp);
+ }
+
+ for (md = cd->members; md != NULL; md = md->next)
+ xmlFunction(pt, cd, md, cd->overs, indent, fp);
+
+ xmlIndent(--indent, fp);
+ fprintf(fp, "</Class>\n");
+}
+
+
+/*
+ * Generate the XML for all the enums in a scope.
+ */
+static void xmlEnums(sipSpec *pt, moduleDef *mod, classDef *scope, int indent,
+ FILE *fp)
+{
+ enumDef *ed;
+
+ for (ed = pt->enums; ed != NULL; ed = ed->next)
+ {
+ if (ed->module != mod)
+ continue;
+
+ if (ed->ecd != scope)
+ continue;
+
+ if (ed->pyname != NULL)
+ {
+ enumMemberDef *emd;
+
+ xmlIndent(indent++, fp);
+ fprintf(fp, "<Enum name=\"");
+ prScopedPythonName(fp, ed->ecd, ed->pyname->text);
+ fprintf(fp, "\">\n");
+
+ for (emd = ed->members; emd != NULL; emd = emd->next)
+ {
+ xmlIndent(indent, fp);
+ fprintf(fp, "<EnumMember name=\"");
+ prScopedPythonName(fp, ed->ecd, emd->pyname->text);
+ fprintf(fp, "\"/>\n");
+ }
+
+ xmlIndent(--indent, fp);
+ fprintf(fp, "</Enum>\n");
+ }
+ else
+ {
+ enumMemberDef *emd;
+
+ for (emd = ed->members; emd != NULL; emd = emd->next)
+ {
+ xmlIndent(indent, fp);
+ fprintf(fp, "<Member name=\"");
+ prScopedPythonName(fp, ed->ecd, emd->pyname->text);
+ fprintf(fp, "\" const=\"1\" typename=\"int\"/>\n");
+ }
+ }
+ }
+}
+
+
+/*
+ * Generate the XML for all the variables in a scope.
+ */
+static void xmlVars(sipSpec *pt, moduleDef *mod, classDef *scope, int indent,
+ FILE *fp)
+{
+ varDef *vd;
+
+ for (vd = pt->vars; vd != NULL; vd = vd->next)
+ {
+ if (vd->module != mod)
+ continue;
+
+ if (vd->ecd != scope)
+ continue;
+
+ xmlIndent(indent, fp);
+ fprintf(fp, "<Member name=\"");
+ prScopedPythonName(fp, vd->ecd, vd->pyname->text);
+ fprintf(fp, "\"");
+
+ if (isConstArg(&vd->type) || scope == NULL)
+ fprintf(fp, " const=\"1\"");
+
+ if (isStaticVar(vd))
+ fprintf(fp, " static=\"1\"");
+
+ xmlType(pt, &vd->type, FALSE, fp);
+ fprintf(fp, "/>\n");
+ }
+}
+
+
+/*
+ * Generate the XML for a ctor.
+ */
+static int xmlCtor(sipSpec *pt, classDef *scope, ctorDef *ct, int sec,
+ int indent, FILE *fp)
+{
+ int a, need_sec;
+
+ xmlIndent(indent++, fp);
+ fprintf(fp, "<Function name=\"");
+ prScopedPythonName(fp, scope, "__init__");
+ fprintf(fp, "\"");
+
+ /* Handle the trivial case. */
+ if (ct->pysig.nrArgs == 0)
+ {
+ fprintf(fp, "/>\n");
+ return FALSE;
+ }
+
+ fprintf(fp, ">\n");
+
+ need_sec = FALSE;
+
+ for (a = 0; a < ct->pysig.nrArgs; ++a)
+ {
+ argDef *ad = &ct->pysig.args[a];
+
+ xmlArgument(pt, ad, dirAttribute(ad), FALSE, sec, indent, fp);
+
+ if (ad->atype == rxcon_type || ad->atype == rxdis_type)
+ need_sec = TRUE;
+ }
+
+ xmlIndent(--indent, fp);
+ fprintf(fp, "</Function>\n");
+
+ return need_sec;
+}
+
+
+/*
+ * Generate the XML for a function.
+ */
+static void xmlFunction(sipSpec *pt, classDef *scope, memberDef *md,
+ overDef *oloads, int indent, FILE *fp)
+{
+ overDef *od;
+ const char *default_str = "default=\"1\" ";
+
+ for (od = oloads; od != NULL; od = od->next)
+ {
+ int isstat;
+ classDef *xtnds;
+
+ if (od->common != md)
+ continue;
+
+ if (isPrivate(od))
+ continue;
+
+ if (isSignal(od))
+ {
+ xmlIndent(indent, fp);
+ fprintf(fp, "<Signal %sname=\"", default_str);
+ prScopedPythonName(fp, scope, md->pyname->text);
+ fprintf(fp, "\" sig=\"");
+ xmlCppSignature(fp, od);
+ fprintf(fp, "\"/>\n");
+
+ default_str = "";
+
+ continue;
+ }
+
+ xtnds = NULL;
+ isstat = (scope == NULL || scope->iff->type == namespace_iface || isStatic(od));
+
+ if (scope == NULL && md->slot != no_slot && od->pysig.args[0].atype == class_type)
+ {
+ xtnds = od->pysig.args[0].u.cd;
+ isstat = FALSE;
+ }
+
+ if (xmlOverload(pt, scope, md, od, xtnds, isstat, FALSE, indent, fp))
+ xmlOverload(pt, scope, md, od, xtnds, isstat, TRUE, indent, fp);
+ }
+}
+
+
+/*
+ * Generate the XML for an overload.
+ */
+static int xmlOverload(sipSpec *pt, classDef *scope, memberDef *md,
+ overDef *od, classDef *xtnds, int stat, int sec, int indent, FILE *fp)
+{
+ int a, need_sec, no_res;
+
+ xmlIndent(indent++, fp);
+ fprintf(fp, "<Function name=\"");
+ prScopedPythonName(fp, scope, md->pyname->text);
+ fprintf(fp, "\"");
+
+ if (isAbstract(od))
+ fprintf(fp, " abstract=\"1\"");
+
+ if (stat)
+ fprintf(fp, " static=\"1\"");
+
+ if (isSlot(od))
+ {
+ fprintf(fp, " slot=\"");
+ xmlCppSignature(fp, od);
+ fprintf(fp, "\"");
+ }
+
+ if (xtnds != NULL)
+ {
+ fprintf(fp, " extends=\"");
+ prScopedPythonName(fp, xtnds->ecd, xtnds->pyname->text);
+ fprintf(fp, "\"");
+ }
+
+ no_res = (od->pysig.result.atype == void_type && od->pysig.result.nrderefs == 0);
+
+ /* Handle the trivial case. */
+ if (no_res && od->pysig.nrArgs == 0)
+ {
+ fprintf(fp, "/>\n");
+ return FALSE;
+ }
+
+ fprintf(fp, ">\n");
+
+ if (!no_res)
+ xmlArgument(pt, &od->pysig.result, "out", isResultTransferredBack(od),
+ FALSE, indent, fp);
+
+ need_sec = FALSE;
+
+ for (a = 0; a < od->pysig.nrArgs; ++a)
+ {
+ argDef *ad = &od->pysig.args[a];
+
+ /* Ignore the first argument of number slots. */
+ if (isNumberSlot(md) && a == 0 && od->pysig.nrArgs == 2)
+ continue;
+
+ xmlArgument(pt, ad, dirAttribute(ad), FALSE, sec, indent, fp);
+
+ if (ad->atype == rxcon_type || ad->atype == rxdis_type)
+ need_sec = TRUE;
+ }
+
+ xmlIndent(--indent, fp);
+ fprintf(fp, "</Function>\n");
+
+ return need_sec;
+}
+
+
+/*
+ * Generate the XML for a C++ signature.
+ */
+static void xmlCppSignature(FILE *fp, overDef *od)
+{
+ prcode(fp, "%M");
+ prOverloadDecl(fp, NULL, od, TRUE);
+ prcode(fp, "%M");
+}
+
+
+/*
+ * Convert an arguments direction to an XML attribute value.
+ */
+static const char *dirAttribute(argDef *ad)
+{
+ if (isInArg(ad))
+ {
+ if (isOutArg(ad))
+ return "inout";
+
+ return NULL;
+ }
+
+ return "out";
+}
+
+
+/*
+ * Generate the XML for an argument.
+ */
+static void xmlArgument(sipSpec *pt, argDef *ad, const char *dir, int res_xfer,
+ int sec, int indent, FILE *fp)
+{
+ if (isArraySize(ad))
+ return;
+
+ if (sec && (ad->atype == slotcon_type || ad->atype == slotdis_type))
+ return;
+
+ xmlIndent(indent, fp);
+ fprintf(fp, "<Argument");
+ xmlType(pt, ad, sec, fp);
+
+ if (dir != NULL)
+ fprintf(fp, " dir=\"%s\"", dir);
+
+ if (isAllowNone(ad))
+ fprintf(fp, " allownone=\"1\"");
+
+ if (isTransferred(ad))
+ fprintf(fp, " transfer=\"to\"");
+ else if (isThisTransferred(ad))
+ fprintf(fp, " transfer=\"this\"");
+ else if (res_xfer || isTransferredBack(ad))
+ fprintf(fp, " transfer=\"back\"");
+
+ /*
+ * Handle the default value, but ignore it if it is an output only
+ * argument.
+ */
+ if (ad->defval && (dir == NULL || strcmp(dir, "out") != 0))
+ {
+ prcode(fp, " default=\"%M");
+ exportDefaultValue(ad, FALSE, fp);
+ prcode(fp, "%M\"");
+ }
+
+ fprintf(fp, "/>\n");
+}
+
+
+/*
+ * Generate the XML for a type.
+ */
+static void xmlType(sipSpec *pt, argDef *ad, int sec, FILE *fp)
+{
+ const char *type_type = NULL, *type_name;
+ classDef *type_scope;
+
+ fprintf(fp, " typename=\"");
+
+ switch (ad->atype)
+ {
+ case class_type:
+ type_type = (isOpaque(ad->u.cd) ? "opaque" : "class");
+ break;
+
+ case enum_type:
+ if (ad->u.ed->pyname != NULL)
+ type_type = "enum";
+ break;
+
+ case rxcon_type:
+ case rxdis_type:
+ if (!sec)
+ type_type = "class";
+ break;
+
+ case qobject_type:
+ type_type = "class";
+ break;
+
+ case slotcon_type:
+ case slotdis_type:
+ {
+ int a;
+
+ prcode(fp, "SLOT(");
+
+ for (a = 0; a < ad->u.sa->nrArgs; ++a)
+ {
+ if (a > 0)
+ prcode(fp, ", ");
+
+ prcode(fp, "%M%B%M", &ad->u.sa->args[a]);
+ }
+
+ prcode(fp, ")");
+ }
+
+ break;
+
+ case mapped_type:
+ type_type = "mappedtype";
+ break;
+ }
+
+ if ((type_name = pyType(pt, ad, sec, &type_scope)) != NULL)
+ prScopedPythonName(fp, type_scope, type_name);
+
+ fprintf(fp, "\"");
+
+ if (type_type != NULL)
+ fprintf(fp, " typetype=\"%s\"", type_type);
+
+ if (ad->name != NULL)
+ fprintf(fp, " name=\"%s\"", ad->name->text);
+}
+
+
+/*
+ * Generate the indentation for a line.
+ */
+static void xmlIndent(int indent, FILE *fp)
+{
+ while (indent-- > 0)
+ fprintf(fp, " ");
+}
+
+
+/*
+ * Export the default value of an argument.
+ */
+static void exportDefaultValue(argDef *ad, int in_str, FILE *fp)
+{
+ /* Use any explicitly provided documentation. */
+ if (ad->docval != NULL)
+ {
+ prcode(fp, "%s", ad->docval);
+ return;
+ }
+
+ /* Translate some special cases. */
+ if (ad->defval->next == NULL && ad->defval->vtype == numeric_value)
+ {
+ if (ad->nrderefs > 0 && ad->defval->u.vnum == 0)
+ {
+ prcode(fp, "None");
+ return;
+ }
+
+ if (ad->atype == bool_type || ad->atype == cbool_type)
+ {
+ prcode(fp, ad->defval->u.vnum ? "True" : "False");
+ return;
+ }
+ }
+
+ generateExpression(ad->defval, in_str, fp);
+}
+
+
+/*
+ * Get the Python representation of a type.
+ */
+static const char *pyType(sipSpec *pt, argDef *ad, int sec, classDef **scope)
+{
+ const char *type_name;
+
+ *scope = NULL;
+
+ /* Use any explicit documented type. */
+ if (ad->doctype != NULL)
+ return ad->doctype;
+
+ /* For classes and mapped types we need the default implementation. */
+ if (ad->atype == class_type || ad->atype == mapped_type)
+ {
+ classDef *def_cd = NULL;
+ mappedTypeDef *def_mtd = NULL;
+ ifaceFileDef *iff;
+
+ if (ad->atype == class_type)
+ {
+ iff = ad->u.cd->iff;
+
+ if (iff->api_range == NULL)
+ {
+ /* There is only one implementation. */
+ def_cd = ad->u.cd;
+ iff = NULL;
+ }
+ }
+ else
+ {
+ iff = ad->u.mtd->iff;
+
+ if (iff->api_range == NULL)
+ {
+ /* There is only one implementation. */
+ def_mtd = ad->u.mtd;
+ iff = NULL;
+ }
+ }
+
+ if (iff != NULL)
+ {
+ int def_api;
+
+ /* Find the default implementation. */
+ def_api = findAPI(pt, iff->api_range->api_name->text)->from;
+
+ for (iff = iff->first_alt; iff != NULL; iff = iff->next_alt)
+ {
+ apiVersionRangeDef *avd = iff->api_range;
+
+ if (avd->from > 0 && avd->from > def_api)
+ continue;
+
+ if (avd->to > 0 && avd->to <= def_api)
+ continue;
+
+ /* It's within range. */
+ break;
+ }
+
+ /* Find the corresponding class or mapped type. */
+ for (def_cd = pt->classes; def_cd != NULL; def_cd = def_cd->next)
+ if (def_cd->iff == iff)
+ break;
+
+ if (def_cd == NULL)
+ for (def_mtd = pt->mappedtypes; def_mtd != NULL; def_mtd = def_mtd->next)
+ if (def_mtd->iff == iff)
+ break;
+ }
+
+ /* Now handle the correct implementation. */
+ if (def_cd != NULL)
+ {
+ *scope = def_cd->ecd;
+ type_name = def_cd->pyname->text;
+ }
+ else
+ {
+ /*
+ * Give a hint that /DocType/ should be used, or there is no
+ * default implementation.
+ */
+ type_name = "unknown-type";
+
+ if (def_mtd != NULL)
+ {
+ if (def_mtd->doctype != NULL)
+ type_name = def_mtd->doctype;
+ else if (def_mtd->pyname != NULL)
+ type_name = def_mtd->pyname->text;
+ }
+ }
+
+ return type_name;
+ }
+
+ switch (ad->atype)
+ {
+ case struct_type:
+ case void_type:
+ type_name = "sip.voidptr";
+ break;
+
+ case enum_type:
+ if (ad->u.ed->pyname != NULL)
+ {
+ type_name = ad->u.ed->pyname->text;
+ *scope = ad->u.ed->ecd;
+ }
+ else
+ type_name = "int";
+ break;
+
+ case signal_type:
+ type_name = "SIGNAL()";
+ break;
+
+ case slot_type:
+ type_name = "SLOT()";
+ break;
+
+ case rxcon_type:
+ case rxdis_type:
+ if (sec)
+ type_name = "callable";
+ else
+ type_name = "QObject";
+
+ break;
+
+ case qobject_type:
+ type_name = "QObject";
+ break;
+
+ case ustring_type:
+ case string_type:
+ case sstring_type:
+ case wstring_type:
+ case ascii_string_type:
+ case latin1_string_type:
+ case utf8_string_type:
+ type_name = "str";
+ break;
+
+ case ushort_type:
+ case uint_type:
+ case long_type:
+ case longlong_type:
+ case ulong_type:
+ case ulonglong_type:
+ case short_type:
+ case int_type:
+ case cint_type:
+ type_name = "int";
+ break;
+
+ case float_type:
+ case cfloat_type:
+ case double_type:
+ case cdouble_type:
+ type_name = "float";
+ break;
+
+ case bool_type:
+ case cbool_type:
+ type_name = "bool";
+ break;
+
+ case pyobject_type:
+ type_name = "object";
+ break;
+
+ case pytuple_type:
+ type_name = "tuple";
+ break;
+
+ case pylist_type:
+ type_name = "list";
+ break;
+
+ case pydict_type:
+ type_name = "dict";
+ break;
+
+ case pycallable_type:
+ type_name = "callable";
+ break;
+
+ case pyslice_type:
+ type_name = "slice";
+ break;
+
+ case pytype_type:
+ type_name = "type";
+ break;
+
+ case ellipsis_type:
+ type_name = "...";
+ break;
+
+ case slotcon_type:
+ case anyslot_type:
+ type_name = "SLOT()";
+ break;
+
+ default:
+ type_name = NULL;
+ }
+
+ return type_name;
+}
+
+
+/*
+ * Generate a scoped Python name.
+ */
+void prScopedPythonName(FILE *fp, classDef *scope, const char *pyname)
+{
+ if (scope != NULL)
+ {
+ prScopedPythonName(fp, scope->ecd, NULL);
+ fprintf(fp, "%s.", scope->pyname->text);
+ }
+
+ if (pyname != NULL)
+ fprintf(fp, "%s", pyname);
+}
+
+
+/*
+ * Generate a Python signature.
+ */
+int prPythonSignature(sipSpec *pt, FILE *fp, signatureDef *sd, int sec,
+ int names, int defaults, int in_str, int is_signal)
+{
+ int need_sec = FALSE, need_comma = FALSE, is_res, nr_out, a;
+
+ fprintf(fp, "%c", (is_signal ? '[' : '('));
+
+ nr_out = 0;
+
+ for (a = 0; a < sd->nrArgs; ++a)
+ {
+ argDef *ad = &sd->args[a];
+
+ if (isOutArg(ad))
+ ++nr_out;
+
+ if (!isInArg(ad))
+ continue;
+
+ need_comma = apiArgument(pt, ad, FALSE, need_comma, sec, names,
+ defaults, in_str, fp);
+
+ if (ad->atype == rxcon_type || ad->atype == rxdis_type)
+ need_sec = TRUE;
+ }
+
+ fprintf(fp, "%c", (is_signal ? ']' : ')'));
+
+ is_res = !((sd->result.atype == void_type && sd->result.nrderefs == 0) ||
+ (sd->result.doctype != NULL && sd->result.doctype[0] == '\0'));
+
+ if (is_res || nr_out > 0)
+ {
+ fprintf(fp, " -> ");
+
+ if ((is_res && nr_out > 0) || nr_out > 1)
+ fprintf(fp, "(");
+
+ if (is_res)
+ need_comma = apiArgument(pt, &sd->result, TRUE, FALSE, sec, FALSE,
+ FALSE, in_str, fp);
+ else
+ need_comma = FALSE;
+
+ for (a = 0; a < sd->nrArgs; ++a)
+ {
+ argDef *ad = &sd->args[a];
+
+ if (isOutArg(ad))
+ /* We don't want the name in the result tuple. */
+ need_comma = apiArgument(pt, ad, TRUE, need_comma, sec, FALSE,
+ FALSE, in_str, fp);
+ }
+
+ if ((is_res && nr_out > 0) || nr_out > 1)
+ fprintf(fp, ")");
+ }
+
+ return need_sec;
+}
diff --git a/sipgen/gencode.c b/sipgen/gencode.c
new file mode 100644
index 0000000..b0c3d01
--- /dev/null
+++ b/sipgen/gencode.c
@@ -0,0 +1,13733 @@
+/*
+ * The code generator module for SIP.
+ *
+ * Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com>
+ *
+ * This file is part of SIP.
+ *
+ * This copy of SIP is licensed for use under the terms of the SIP License
+ * Agreement. See the file LICENSE for more details.
+ *
+ * This copy of SIP may also used under the terms of the GNU General Public
+ * License v2 or v3 as published by the Free Software Foundation which can be
+ * found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
+ *
+ * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "sip.h"
+
+
+/* Return the base (ie. C/C++) name of a super-type or meta-type. */
+#define smtypeName(sm) (strrchr((sm)->name->text, '.') + 1)
+
+/* Return TRUE if a wrapped variable can be set. */
+#define canSetVariable(vd) ((vd)->type.nrderefs != 0 || !isConstArg(&(vd)->type))
+
+
+/* Control what generateCalledArgs() actually generates. */
+typedef enum {
+ Declaration,
+ Definition
+} funcArgType;
+
+
+/* An entry in the sorted array of methods. */
+typedef struct {
+ memberDef *md; /* The method. */
+} sortedMethTab;
+
+
+static int currentLineNr; /* Current output line number. */
+static const char *currentFileName; /* Current output file name. */
+static int previousLineNr; /* Previous output line number. */
+static const char *previousFileName; /* Previous output file name. */
+static int exceptions; /* Set if exceptions are enabled. */
+static int tracing; /* Set if tracing is enabled. */
+static int generating_c; /* Set if generating C. */
+static int release_gil; /* Set if always releasing the GIL. */
+static const char *prcode_last = NULL; /* The last prcode format string. */
+static int prcode_xml = FALSE; /* Set if prcode is XML aware. */
+static int docstrings; /* Set if generating docstrings. */
+
+
+static void generateDocumentation(sipSpec *pt, const char *docFile);
+static void generateBuildFile(sipSpec *pt, const char *buildFile,
+ const char *srcSuffix, const char *consModule);
+static void generateBuildFileSources(sipSpec *pt, moduleDef *mod,
+ const char *srcSuffix, FILE *fp);
+static void generateInternalAPIHeader(sipSpec *pt, moduleDef *mod,
+ const char *codeDir, stringList *xsl);
+static void generateCpp(sipSpec *pt, moduleDef *mod, const char *codeDir,
+ const char *srcSuffix, int parts, stringList *xsl);
+static void generateCompositeCpp(sipSpec *pt, const char *codeDir);
+static void generateConsolidatedCpp(sipSpec *pt, const char *codeDir,
+ const char *srcSuffix);
+static void generateComponentCpp(sipSpec *pt, const char *codeDir,
+ const char *consModule);
+static void generateSipImport(moduleDef *mod, FILE *fp);
+static void generateSipImportVariables(FILE *fp);
+static void generateModInitStart(moduleDef *mod, int gen_c, FILE *fp);
+static void generateModDefinition(moduleDef *mod, const char *methods,
+ FILE *fp);
+static void generateIfaceCpp(sipSpec *, ifaceFileDef *, const char *,
+ const char *, FILE *);
+static void generateMappedTypeCpp(mappedTypeDef *mtd, sipSpec *pt, FILE *fp);
+static void generateImportedMappedTypeAPI(mappedTypeDef *mtd, sipSpec *pt,
+ moduleDef *mod, FILE *fp);
+static void generateMappedTypeAPI(sipSpec *pt, mappedTypeDef *mtd, FILE *fp);
+static void generateClassCpp(classDef *cd, sipSpec *pt, FILE *fp);
+static void generateImportedClassAPI(classDef *cd, sipSpec *pt, moduleDef *mod,
+ FILE *fp);
+static void generateClassAPI(classDef *cd, sipSpec *pt, FILE *fp);
+static void generateClassFunctions(sipSpec *pt, moduleDef *mod, classDef *cd,
+ FILE *fp);
+static void generateShadowCode(sipSpec *pt, moduleDef *mod, classDef *cd,
+ FILE *fp);
+static void generateFunction(sipSpec *, memberDef *, overDef *, classDef *,
+ classDef *, moduleDef *, FILE *);
+static void generateFunctionBody(overDef *, classDef *, mappedTypeDef *,
+ classDef *, int deref, moduleDef *, FILE *);
+static void generateTypeDefinition(sipSpec *pt, classDef *cd, FILE *fp);
+static void generateTypeInit(classDef *, moduleDef *, FILE *);
+static void generateCppCodeBlock(codeBlock *, FILE *);
+static void generateUsedIncludes(ifaceFileList *iffl, FILE *fp);
+static void generateModuleAPI(sipSpec *pt, moduleDef *mod, FILE *fp);
+static void generateImportedModuleAPI(sipSpec *pt, moduleDef *mod,
+ moduleDef *immod, FILE *fp);
+static void generateShadowClassDeclaration(sipSpec *, classDef *, FILE *);
+static int hasConvertToCode(argDef *ad);
+static void deleteOuts(signatureDef *sd, FILE *fp);
+static void deleteTemps(signatureDef *sd, FILE *fp);
+static void gc_ellipsis(signatureDef *sd, FILE *fp);
+static void generateCallArgs(signatureDef *, signatureDef *, FILE *);
+static void generateCalledArgs(ifaceFileDef *, signatureDef *, funcArgType,
+ int, FILE *);
+static void generateVariable(ifaceFileDef *, argDef *, int, FILE *);
+static void generateNamedValueType(ifaceFileDef *, argDef *, char *, FILE *);
+static void generateBaseType(ifaceFileDef *, argDef *, int, FILE *);
+static void generateNamedBaseType(ifaceFileDef *, argDef *, char *, int,
+ FILE *);
+static void generateTupleBuilder(signatureDef *, FILE *);
+static void generateEmitters(classDef *cd, FILE *fp);
+static void generateEmitter(classDef *, visibleList *, FILE *);
+static void generateVirtualHandler(virtHandlerDef *vhd, FILE *fp);
+static void generateVirtHandlerErrorReturn(argDef *res, const char *indent,
+ FILE *fp);
+static void generateVirtualCatcher(moduleDef *mod, classDef *cd, int virtNr,
+ virtOverDef *vod, FILE *fp);
+static void generateVirtHandlerCall(moduleDef *mod, classDef *cd,
+ virtOverDef *vod, argDef *res, const char *indent, FILE *fp);
+static void generateUnambiguousClass(classDef *cd, classDef *scope, FILE *fp);
+static void generateProtectedEnums(sipSpec *, classDef *, FILE *);
+static void generateProtectedDeclarations(classDef *, FILE *);
+static void generateProtectedDefinitions(classDef *, FILE *);
+static void generateProtectedCallArgs(signatureDef *sd, FILE *fp);
+static void generateConstructorCall(classDef *, ctorDef *, int, int,
+ moduleDef *, FILE *);
+static void generateHandleResult(overDef *, int, int, char *, FILE *);
+static void generateOrdinaryFunction(sipSpec *pt, moduleDef *mod,
+ classDef *c_scope, mappedTypeDef *mt_scope, memberDef *md, FILE *fp);
+static void generateSimpleFunctionCall(fcallDef *, FILE *);
+static void generateFunctionCall(classDef *c_scope, mappedTypeDef *mt_scope,
+ ifaceFileDef *o_scope, overDef *od, int deref, moduleDef *mod,
+ FILE *fp);
+static void generateCppFunctionCall(ifaceFileDef *scope,
+ ifaceFileDef *o_scope, overDef *od, FILE *fp);
+static void generateSlotArg(signatureDef *sd, int argnr, FILE *fp);
+static void generateComparisonSlotCall(ifaceFileDef *scope, overDef *od,
+ const char *op, const char *cop, int deref, FILE *fp);
+static void generateBinarySlotCall(ifaceFileDef *scope, overDef *od,
+ const char *op, int deref, FILE *fp);
+static void generateNumberSlotCall(overDef *od, char *op, FILE *fp);
+static void generateVariableGetter(ifaceFileDef *, varDef *, FILE *);
+static void generateVariableSetter(ifaceFileDef *, varDef *, FILE *);
+static int generateObjToCppConversion(argDef *, FILE *);
+static void generateVarMember(varDef *vd, FILE *fp);
+static int generateVoidPointers(sipSpec *pt, moduleDef *mod, classDef *cd,
+ FILE *fp);
+static int generateChars(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp);
+static int generateStrings(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp);
+static sortedMethTab *createFunctionTable(memberDef *, int *);
+static sortedMethTab *createMethodTable(classDef *, int *);
+static int generateMappedTypeMethodTable(sipSpec *pt, mappedTypeDef *mtd,
+ FILE *fp);
+static int generateClassMethodTable(sipSpec *pt, classDef *cd, FILE *fp);
+static void prMethodTable(sipSpec *pt, sortedMethTab *mtable, int nr,
+ ifaceFileDef *iff, overDef *overs, FILE *fp);
+static void generateEnumMacros(sipSpec *pt, moduleDef *mod, classDef *cd,
+ mappedTypeDef *mtd, FILE *fp);
+static int generateEnumMemberTable(sipSpec *pt, moduleDef *mod, classDef *cd,
+ mappedTypeDef *mtd, FILE *fp);
+static int generateInts(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp);
+static int generateLongs(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp);
+static int generateUnsignedLongs(sipSpec *pt, moduleDef *mod, classDef *cd,
+ FILE *fp);
+static int generateLongLongs(sipSpec *pt, moduleDef *mod, classDef *cd,
+ FILE *fp);
+static int generateUnsignedLongLongs(sipSpec *pt, moduleDef *mod, classDef *cd,
+ FILE *fp);
+static int generateVariableType(sipSpec *pt, moduleDef *mod, classDef *cd,
+ argType atype, const char *eng, const char *s1, const char *s2,
+ FILE *fp);
+static int generateDoubles(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp);
+static int generateClasses(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp);
+static void generateTypesInline(sipSpec *pt, moduleDef *mod, FILE *fp);
+static void generateAccessFunctions(sipSpec *pt, moduleDef *mod, classDef *cd,
+ FILE *fp);
+static void generateConvertToDefinitions(mappedTypeDef *, classDef *, FILE *);
+static void generateEncodedType(moduleDef *mod, classDef *cd, int last,
+ FILE *fp);
+static int generateArgParser(signatureDef *sd, classDef *c_scope,
+ mappedTypeDef *mt_scope, ctorDef *ct, overDef *od, int secCall,
+ FILE *fp);
+static void generateTry(throwArgs *, FILE *);
+static void generateCatch(throwArgs *ta, signatureDef *sd, moduleDef *mod,
+ FILE *fp);
+static void generateCatchBlock(exceptionDef *xd, signatureDef *sd, FILE *fp);
+static void generateThrowSpecifier(throwArgs *, FILE *);
+static void generateSlot(moduleDef *mod, classDef *cd, enumDef *ed,
+ memberDef *md, FILE *fp);
+static void generateCastZero(argDef *ad, FILE *fp);
+static void generateCallDefaultCtor(ctorDef *ct, FILE *fp);
+static int countVirtuals(classDef *);
+static int skipOverload(overDef *, memberDef *, classDef *, classDef *, int);
+static int compareMethTab(const void *, const void *);
+static int compareEnumMembers(const void *, const void *);
+static char *getSubFormatChar(char, argDef *);
+static char *createIfaceFileName(const char *, ifaceFileDef *, const char *);
+static FILE *createCompilationUnit(moduleDef *mod, const char *fname,
+ const char *description);
+static FILE *createFile(moduleDef *mod, const char *fname,
+ const char *description);
+static void closeFile(FILE *);
+static void prScopedName(FILE *fp, scopedNameDef *snd, char *sep);
+static void prTypeName(FILE *fp, argDef *ad);
+static void prScopedClassName(FILE *fp, ifaceFileDef *scope, classDef *cd);
+static int isZeroArgSlot(memberDef *md);
+static int isMultiArgSlot(memberDef *md);
+static int isIntArgSlot(memberDef *md);
+static int isInplaceNumberSlot(memberDef *md);
+static int isInplaceSequenceSlot(memberDef *md);
+static int needErrorFlag(codeBlock *cb);
+static int needOldErrorFlag(codeBlock *cb);
+static int needNewInstance(argDef *ad);
+static int needDealloc(classDef *cd);
+static const char *getBuildResultFormat(argDef *ad);
+static const char *getParseResultFormat(argDef *ad, int res_isref, int xfervh);
+static void generateParseResultExtraArgs(argDef *ad, int argnr, FILE *fp);
+static char *makePartName(const char *codeDir, const char *mname, int part,
+ const char *srcSuffix);
+static void fakeProtectedArgs(signatureDef *sd);
+static void normaliseArgs(signatureDef *);
+static void restoreArgs(signatureDef *);
+static const char *slotName(slotType st);
+static void ints_intro(classDef *cd, FILE *fp);
+static const char *argName(const char *name, codeBlock *cb);
+static int usedInCode(codeBlock *code, const char *str);
+static void generateDefaultValue(argDef *ad, int argnr, FILE *fp);
+static void generateClassFromVoid(classDef *cd, const char *cname,
+ const char *vname, FILE *fp);
+static void generateMappedTypeFromVoid(mappedTypeDef *mtd, const char *cname,
+ const char *vname, FILE *fp);
+static int generateSubClassConvertors(sipSpec *pt, moduleDef *mod, FILE *fp);
+static void generateNameCache(sipSpec *pt, FILE *fp);
+static const char *resultOwner(overDef *od);
+static void prCachedName(FILE *fp, nameDef *nd, const char *prefix);
+static void generateSignalTableEntry(sipSpec *pt, classDef *cd, overDef *sig,
+ memberDef *md, int membernr, FILE *fp);
+static void generateTypesTable(sipSpec *pt, moduleDef *mod, FILE *fp);
+static int py2OnlySlot(slotType st);
+static int py2_5LaterSlot(slotType st);
+static int keepPyReference(argDef *ad);
+static int isDuplicateProtected(classDef *cd, overDef *target);
+static char getEncoding(argType atype);
+static void generateTypeDefName(ifaceFileDef *iff, FILE *fp);
+static void generateTypeDefLink(sipSpec *pt, ifaceFileDef *iff, FILE *fp);
+static int overloadHasDocstring(sipSpec *pt, overDef *od, memberDef *md);
+static int hasDocstring(sipSpec *pt, overDef *od, memberDef *md,
+ ifaceFileDef *scope);
+static void generateDocstring(sipSpec *pt, overDef *overs, memberDef *md,
+ const char *scope_name, classDef *scope_scope, FILE *fp);
+static int overloadHasClassDocstring(sipSpec *pt, ctorDef *ct);
+static int hasClassDocstring(sipSpec *pt, classDef *cd);
+static void generateClassDocstring(sipSpec *pt, classDef *cd, FILE *fp);
+static int isDefaultAPI(sipSpec *pt, apiVersionRangeDef *avd);
+static void generateExplicitDocstring(codeBlock *docstring, FILE *fp);
+static int copyConstRefArg(argDef *ad);
+
+
+/*
+ * Generate the code from a specification.
+ */
+void generateCode(sipSpec *pt, char *codeDir, char *buildfile, char *docFile,
+ const char *srcSuffix, int except, int trace, int releaseGIL,
+ int parts, stringList *xsl, const char *consModule, int docs)
+{
+ exceptions = except;
+ tracing = trace;
+ release_gil = releaseGIL;
+ generating_c = pt->genc;
+ docstrings = docs;
+
+ if (srcSuffix == NULL)
+ srcSuffix = (generating_c ? ".c" : ".cpp");
+
+ /* Generate the documentation. */
+ if (docFile != NULL)
+ generateDocumentation(pt,docFile);
+
+ /* Generate the code. */
+ if (codeDir != NULL)
+ {
+ if (isComposite(pt->module))
+ generateCompositeCpp(pt, codeDir);
+ else if (isConsolidated(pt->module))
+ {
+ moduleDef *mod;
+
+ for (mod = pt->modules; mod != NULL; mod = mod->next)
+ if (mod->container == pt->module)
+ generateCpp(pt, mod, codeDir, srcSuffix, parts, xsl);
+
+ generateConsolidatedCpp(pt, codeDir, srcSuffix);
+ }
+ else if (consModule != NULL)
+ generateComponentCpp(pt, codeDir, consModule);
+ else
+ generateCpp(pt, pt->module, codeDir, srcSuffix, parts, xsl);
+ }
+
+ /* Generate the build file. */
+ if (buildfile != NULL)
+ generateBuildFile(pt, buildfile, srcSuffix, consModule);
+}
+
+
+/*
+ * Generate the documentation.
+ */
+static void generateDocumentation(sipSpec *pt, const char *docFile)
+{
+ FILE *fp;
+ codeBlock *cb;
+
+ fp = createFile(pt->module, docFile, NULL);
+
+ for (cb = pt->docs; cb != NULL; cb = cb->next)
+ fputs(cb->frag, fp);
+
+ closeFile(fp);
+}
+
+
+/*
+ * Generate the build file.
+ */
+static void generateBuildFile(sipSpec *pt, const char *buildFile,
+ const char *srcSuffix, const char *consModule)
+{
+ const char *mname = pt->module->name;
+ FILE *fp;
+
+ fp = createFile(pt->module, buildFile, NULL);
+
+ prcode(fp, "target = %s\nsources =", mname);
+
+ if (isComposite(pt->module))
+ prcode(fp, " sip%scmodule.c", mname);
+ else if (isConsolidated(pt->module))
+ {
+ moduleDef *mod;
+
+ for (mod = pt->modules; mod != NULL; mod = mod->next)
+ if (mod->container == pt->module)
+ generateBuildFileSources(pt, mod, srcSuffix, fp);
+
+ prcode(fp, " sip%scmodule%s", mname, srcSuffix);
+ }
+ else if (consModule == NULL)
+ generateBuildFileSources(pt, pt->module, srcSuffix, fp);
+ else
+ prcode(fp, " sip%scmodule.c", mname);
+
+ if (isConsolidated(pt->module))
+ {
+ moduleDef *mod;
+
+ prcode(fp, "\nheaders =");
+
+ for (mod = pt->modules; mod != NULL; mod = mod->next)
+ if (mod->container == pt->module)
+ prcode(fp, " sipAPI%s.h", mod->name);
+ }
+ else if (!isComposite(pt->module) && consModule == NULL)
+ prcode(fp, "\nheaders = sipAPI%s.h", mname);
+
+ prcode(fp, "\n");
+
+ closeFile(fp);
+}
+
+
+/*
+ * Generate the list of source files for a module.
+ */
+static void generateBuildFileSources(sipSpec *pt, moduleDef *mod,
+ const char *srcSuffix, FILE *fp)
+{
+ const char *mname = mod->name;
+
+ if (mod->parts)
+ {
+ int p;
+
+ for (p = 0; p < mod->parts; ++p)
+ prcode(fp, " sip%spart%d%s", mname, p, srcSuffix);
+ }
+ else
+ {
+ ifaceFileDef *iff;
+
+ prcode(fp, " sip%scmodule%s", mname, srcSuffix);
+
+ for (iff = pt->ifacefiles; iff != NULL; iff = iff->next)
+ {
+ if (iff->module != mod)
+ continue;
+
+ if (iff->type == exception_iface)
+ continue;
+
+ if (iff->api_range != NULL)
+ prcode(fp, " sip%s%F_%d%s", mname, iff->fqcname, iff->api_range->index, srcSuffix);
+ else
+ prcode(fp, " sip%s%F%s", mname, iff->fqcname, srcSuffix);
+ }
+ }
+}
+
+
+/*
+ * Generate an expression in C++.
+ */
+void generateExpression(valueDef *vd, int in_str, FILE *fp)
+{
+ while (vd != NULL)
+ {
+ if (vd->vunop != '\0')
+ prcode(fp,"%c",vd->vunop);
+
+ switch (vd->vtype)
+ {
+ case qchar_value:
+ prcode(fp,"'%c'",vd->u.vqchar);
+ break;
+
+ case string_value:
+ {
+ const char *quote = (in_str ? "\\\"" : "\"");
+
+ prcode(fp,"%s%s%s", quote, vd->u.vstr, quote);
+ }
+
+ break;
+
+ case numeric_value:
+ prcode(fp,"%l",vd->u.vnum);
+ break;
+
+ case real_value:
+ prcode(fp,"%g",vd->u.vreal);
+ break;
+
+ case scoped_value:
+ if (prcode_xml)
+ prScopedName(fp, vd->u.vscp, ".");
+ else
+ prcode(fp, "%S", vd->u.vscp);
+
+ break;
+
+ case fcall_value:
+ generateSimpleFunctionCall(vd->u.fcd,fp);
+ break;
+ }
+
+ if (vd->vbinop != '\0')
+ prcode(fp,"%c",vd->vbinop);
+
+ vd = vd->next;
+ }
+}
+
+
+/*
+ * Generate the C++ internal module API header file.
+ */
+static void generateInternalAPIHeader(sipSpec *pt, moduleDef *mod,
+ const char *codeDir, stringList *xsl)
+{
+ char *hfile;
+ const char *mname = mod->name;
+ int noIntro;
+ FILE *fp;
+ nameDef *nd;
+ moduleDef *imp;
+ moduleListDef *mld;
+
+ hfile = concat(codeDir, "/sipAPI", mname, ".h",NULL);
+ fp = createFile(mod, hfile, "Internal module API header file.");
+
+ /* Include files. */
+
+ prcode(fp,
+"\n"
+"#ifndef _%sAPI_H\n"
+"#define _%sAPI_H\n"
+"\n"
+"\n"
+"#include <sip.h>\n"
+ , mname
+ , mname);
+
+ if (pluginPyQt4(pt))
+ prcode(fp,
+"\n"
+"#include <QMetaType>\n"
+ );
+
+ /* Define the enabled features. */
+ noIntro = TRUE;
+
+ for (imp = pt->modules; imp != NULL; imp = imp->next)
+ {
+ qualDef *qd;
+
+ for (qd = imp->qualifiers; qd != NULL; qd = qd->next)
+ if (qd->qtype == feature_qualifier && !excludedFeature(xsl, qd))
+ {
+ if (noIntro)
+ {
+ prcode(fp,
+"\n"
+"/* These are the features that are enabled. */\n"
+ );
+
+ noIntro = FALSE;
+ }
+
+ prcode(fp,
+"#define SIP_FEATURE_%s\n"
+ , qd->name);
+ }
+ }
+
+ if (!noIntro)
+ prcode(fp,
+"\n"
+ );
+
+ generateCppCodeBlock(pt->exphdrcode, fp);
+ generateCppCodeBlock(mod->hdrcode, fp);
+
+ /* Shortcuts that hide the messy detail of the APIs. */
+ noIntro = TRUE;
+
+ for (nd = pt->namecache; nd != NULL; nd = nd->next)
+ {
+ if (!isUsedName(nd))
+ continue;
+
+ if (noIntro)
+ {
+ prcode(fp,
+"\n"
+"/*\n"
+" * Convenient names to refer to various strings defined in this module.\n"
+" * Only the class names are part of the public API.\n"
+" */\n"
+ );
+
+ noIntro = FALSE;
+ }
+
+ prcode(fp,
+"#define %n %d\n"
+"#define %N &sipStrings_%s[%d]\n"
+ , nd, (int)nd->offset
+ , nd, pt->module->name, (int)nd->offset);
+ }
+
+ prcode(fp,
+"\n"
+"#define sipMalloc sipAPI_%s->api_malloc\n"
+"#define sipFree sipAPI_%s->api_free\n"
+"#define sipBuildResult sipAPI_%s->api_build_result\n"
+"#define sipCallMethod sipAPI_%s->api_call_method\n"
+"#define sipParseResult sipAPI_%s->api_parse_result\n"
+"#define sipParseArgs sipAPI_%s->api_parse_args\n"
+"#define sipParseKwdArgs sipAPI_%s->api_parse_kwd_args\n"
+"#define sipParsePair sipAPI_%s->api_parse_pair\n"
+"#define sipCommonDtor sipAPI_%s->api_common_dtor\n"
+"#define sipConvertFromSequenceIndex sipAPI_%s->api_convert_from_sequence_index\n"
+"#define sipConvertFromVoidPtr sipAPI_%s->api_convert_from_void_ptr\n"
+"#define sipConvertToVoidPtr sipAPI_%s->api_convert_to_void_ptr\n"
+"#define sipAddException sipAPI_%s->api_add_exception\n"
+"#define sipNoFunction sipAPI_%s->api_no_function\n"
+"#define sipNoMethod sipAPI_%s->api_no_method\n"
+"#define sipAbstractMethod sipAPI_%s->api_abstract_method\n"
+"#define sipBadClass sipAPI_%s->api_bad_class\n"
+"#define sipBadCatcherResult sipAPI_%s->api_bad_catcher_result\n"
+"#define sipBadCallableArg sipAPI_%s->api_bad_callable_arg\n"
+"#define sipBadOperatorArg sipAPI_%s->api_bad_operator_arg\n"
+"#define sipTrace sipAPI_%s->api_trace\n"
+"#define sipTransferBack sipAPI_%s->api_transfer_back\n"
+"#define sipTransferTo sipAPI_%s->api_transfer_to\n"
+"#define sipTransferBreak sipAPI_%s->api_transfer_break\n"
+"#define sipSimpleWrapper_Type sipAPI_%s->api_simplewrapper_type\n"
+"#define sipWrapper_Type sipAPI_%s->api_wrapper_type\n"
+"#define sipWrapperType_Type sipAPI_%s->api_wrappertype_type\n"
+"#define sipVoidPtr_Type sipAPI_%s->api_voidptr_type\n"
+"#define sipGetPyObject sipAPI_%s->api_get_pyobject\n"
+"#define sipGetCppPtr sipAPI_%s->api_get_cpp_ptr\n"
+"#define sipGetComplexCppPtr sipAPI_%s->api_get_complex_cpp_ptr\n"
+"#define sipIsPyMethod sipAPI_%s->api_is_py_method\n"
+"#define sipCallHook sipAPI_%s->api_call_hook\n"
+"#define sipStartThread sipAPI_%s->api_start_thread\n"
+"#define sipEndThread sipAPI_%s->api_end_thread\n"
+"#define sipConnectRx sipAPI_%s->api_connect_rx\n"
+"#define sipDisconnectRx sipAPI_%s->api_disconnect_rx\n"
+"#define sipRaiseUnknownException sipAPI_%s->api_raise_unknown_exception\n"
+"#define sipRaiseTypeException sipAPI_%s->api_raise_type_exception\n"
+"#define sipBadLengthForSlice sipAPI_%s->api_bad_length_for_slice\n"
+"#define sipAddTypeInstance sipAPI_%s->api_add_type_instance\n"
+"#define sipGetAddress sipAPI_%s->api_get_address\n"
+"#define sipFreeSipslot sipAPI_%s->api_free_sipslot\n"
+"#define sipSameSlot sipAPI_%s->api_same_slot\n"
+"#define sipPySlotExtend sipAPI_%s->api_pyslot_extend\n"
+"#define sipConvertRx sipAPI_%s->api_convert_rx\n"
+"#define sipAddDelayedDtor sipAPI_%s->api_add_delayed_dtor\n"
+"#define sipCanConvertToType sipAPI_%s->api_can_convert_to_type\n"
+"#define sipConvertToType sipAPI_%s->api_convert_to_type\n"
+"#define sipForceConvertToType sipAPI_%s->api_force_convert_to_type\n"
+"#define sipCanConvertToEnum sipAPI_%s->api_can_convert_to_enum\n"
+"#define sipReleaseType sipAPI_%s->api_release_type\n"
+"#define sipConvertFromType sipAPI_%s->api_convert_from_type\n"
+"#define sipConvertFromNewType sipAPI_%s->api_convert_from_new_type\n"
+"#define sipConvertFromEnum sipAPI_%s->api_convert_from_enum\n"
+"#define sipGetState sipAPI_%s->api_get_state\n"
+"#define sipLong_AsUnsignedLong sipAPI_%s->api_long_as_unsigned_long\n"
+"#define sipExportSymbol sipAPI_%s->api_export_symbol\n"
+"#define sipImportSymbol sipAPI_%s->api_import_symbol\n"
+"#define sipFindType sipAPI_%s->api_find_type\n"
+"#define sipFindNamedEnum sipAPI_%s->api_find_named_enum\n"
+"#define sipBytes_AsChar sipAPI_%s->api_bytes_as_char\n"
+"#define sipBytes_AsString sipAPI_%s->api_bytes_as_string\n"
+"#define sipString_AsASCIIChar sipAPI_%s->api_string_as_ascii_char\n"
+"#define sipString_AsASCIIString sipAPI_%s->api_string_as_ascii_string\n"
+"#define sipString_AsLatin1Char sipAPI_%s->api_string_as_latin1_char\n"
+"#define sipString_AsLatin1String sipAPI_%s->api_string_as_latin1_string\n"
+"#define sipString_AsUTF8Char sipAPI_%s->api_string_as_utf8_char\n"
+"#define sipString_AsUTF8String sipAPI_%s->api_string_as_utf8_string\n"
+"#define sipUnicode_AsWChar sipAPI_%s->api_unicode_as_wchar\n"
+"#define sipUnicode_AsWString sipAPI_%s->api_unicode_as_wstring\n"
+"#define sipConvertFromConstVoidPtr sipAPI_%s->api_convert_from_const_void_ptr\n"
+"#define sipConvertFromVoidPtrAndSize sipAPI_%s->api_convert_from_void_ptr_and_size\n"
+"#define sipConvertFromConstVoidPtrAndSize sipAPI_%s->api_convert_from_const_void_ptr_and_size\n"
+"#define sipInvokeSlot sipAPI_%s->api_invoke_slot\n"
+"#define sipSaveSlot sipAPI_%s->api_save_slot\n"
+"#define sipClearAnySlotReference sipAPI_%s->api_clear_any_slot_reference\n"
+"#define sipVisitSlot sipAPI_%s->api_visit_slot\n"
+"#define sipWrappedTypeName(wt) ((wt)->type->td_cname)\n"
+"#define sipDeprecated sipAPI_%s->api_deprecated\n"
+"#define sipKeepReference sipAPI_%s->api_keep_reference\n"
+"#define sipRegisterPyType sipAPI_%s->api_register_py_type\n"
+"#define sipTypeFromPyTypeObject sipAPI_%s->api_type_from_py_type_object\n"
+"#define sipTypeScope sipAPI_%s->api_type_scope\n"
+"#define sipResolveTypedef sipAPI_%s->api_resolve_typedef\n"
+"#define sipRegisterAttributeGetter sipAPI_%s->api_register_attribute_getter\n"
+"#define sipIsAPIEnabled sipAPI_%s->api_is_api_enabled\n"
+"#define sipExportModule sipAPI_%s->api_export_module\n"
+"#define sipInitModule sipAPI_%s->api_init_module\n"
+"\n"
+"/* These are deprecated. */\n"
+"#define sipMapStringToClass sipAPI_%s->api_map_string_to_class\n"
+"#define sipMapIntToClass sipAPI_%s->api_map_int_to_class\n"
+"#define sipFindClass sipAPI_%s->api_find_class\n"
+"#define sipFindMappedType sipAPI_%s->api_find_mapped_type\n"
+"#define sipWrapper_Check(w) PyObject_TypeCheck((w), sipAPI_%s->api_wrapper_type)\n"
+"#define sipGetWrapper(p, wt) sipGetPyObject((p), (wt)->type)\n"
+"#define sipReleaseInstance(p, wt, s) sipReleaseType((p), (wt)->type, (s))\n"
+"#define sipReleaseMappedType sipReleaseType\n"
+"#define sipCanConvertToInstance(o, wt, f) sipCanConvertToType((o), (wt)->type, (f))\n"
+"#define sipCanConvertToMappedType sipCanConvertToType\n"
+"#define sipConvertToInstance(o, wt, t, f, s, e) sipConvertToType((o), (wt)->type, (t), (f), (s), (e))\n"
+"#define sipConvertToMappedType sipConvertToType\n"
+"#define sipForceConvertToInstance(o, wt, t, f, s, e) sipForceConvertToType((o), (wt)->type, (t), (f), (s), (e))\n"
+"#define sipForceConvertToMappedType sipForceConvertToType\n"
+"#define sipConvertFromInstance(p, wt, t) sipConvertFromType((p), (wt)->type, (t))\n"
+"#define sipConvertFromMappedType sipConvertFromType\n"
+"#define sipConvertFromNamedEnum(v, pt) sipConvertFromEnum((v), ((sipEnumTypeObject *)(pt))->type)\n"
+"#define sipConvertFromNewInstance(p, wt, t) sipConvertFromNewType((p), (wt)->type, (t))\n"
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname
+ ,mname);
+
+ /* The name strings. */
+ prcode(fp,
+"\n"
+"/* The strings used by this module. */\n"
+"extern const char sipStrings_%s[];\n"
+ , pt->module->name);
+
+ /* The unscoped enum macros. */
+ generateEnumMacros(pt, mod, NULL, NULL, fp);
+
+ generateModuleAPI(pt, mod, fp);
+
+ prcode(fp,
+"\n"
+"/* The SIP API, this module's API and the APIs of any imported modules. */\n"
+"extern const sipAPIDef *sipAPI_%s;\n"
+"extern sipExportedModuleDef sipModuleAPI_%s;\n"
+ , mname
+ , mname, mname);
+
+ for (mld = mod->allimports; mld != NULL; mld = mld->next)
+ {
+ generateImportedModuleAPI(pt, mod, mld->module, fp);
+
+ prcode(fp,
+"extern const sipExportedModuleDef *sipModuleAPI_%s_%s;\n"
+ , mname, mld->module->name);
+ }
+
+ if (pluginPyQt4(pt))
+ prcode(fp,
+"\n"
+"typedef const QMetaObject *(*sip_qt_metaobject_func)(sipSimpleWrapper *,sipTypeDef *);\n"
+"extern sip_qt_metaobject_func sip_%s_qt_metaobject;\n"
+"\n"
+"typedef int (*sip_qt_metacall_func)(sipSimpleWrapper *,sipTypeDef *,QMetaObject::Call,int,void **);\n"
+"extern sip_qt_metacall_func sip_%s_qt_metacall;\n"
+"\n"
+"typedef int (*sip_qt_metacast_func)(sipSimpleWrapper *,sipTypeDef *,const char *);\n"
+"extern sip_qt_metacast_func sip_%s_qt_metacast;\n"
+ , mname
+ , mname
+ , mname);
+
+ /*
+ * Note that we don't forward declare the virtual handlers. This is
+ * because we would need to #include everything needed for their argument
+ * types.
+ */
+ prcode(fp,
+"\n"
+"#endif\n"
+ );
+
+ closeFile(fp);
+ free(hfile);
+}
+
+
+/*
+ * Return the filename of a source code part on the heap.
+ */
+static char *makePartName(const char *codeDir, const char *mname, int part,
+ const char *srcSuffix)
+{
+ char buf[50];
+
+ sprintf(buf, "part%d", part);
+
+ return concat(codeDir, "/sip", mname, buf, srcSuffix, NULL);
+}
+
+
+/*
+ * Generate the C code for a composite module.
+ */
+static void generateCompositeCpp(sipSpec *pt, const char *codeDir)
+{
+ char *cppfile;
+ moduleDef *mod;
+ FILE *fp;
+
+ cppfile = concat(codeDir, "/sip", pt->module->name, "cmodule.c", NULL);
+ fp = createCompilationUnit(pt->module, cppfile, "Composite module code.");
+
+ prcode(fp,
+"\n"
+"#include <Python.h>\n"
+"\n"
+"\n"
+"static void sip_import_component_module(PyObject *d, const char *name)\n"
+"{\n"
+"#if PY_VERSION_HEX >= 0x02050000\n"
+" PyObject *mod = PyImport_ImportModule(name);\n"
+"#else\n"
+" PyObject *mod = PyImport_ImportModule((char *)name);\n"
+"#endif\n"
+"\n"
+" /*\n"
+" * Note that we don't complain if the module can't be imported. This\n"
+" * is a favour to Linux distro packagers who like to split PyQt into\n"
+" * different sub-packages.\n"
+" */\n"
+" if (mod)\n"
+" {\n"
+" PyDict_Merge(d, PyModule_GetDict(mod), 0);\n"
+" Py_DECREF(mod);\n"
+" }\n"
+"}\n"
+ );
+
+ generateModInitStart(pt->module, TRUE, fp);
+ generateModDefinition(pt->module, "NULL", fp);
+
+ prcode(fp,
+"\n"
+" PyObject *sipModule, *sipModuleDict;\n"
+"\n"
+"#if PY_MAJOR_VERSION >= 3\n"
+" sipModule = PyModule_Create(&sip_module_def);\n"
+"#else\n"
+" sipModule = Py_InitModule(\"%s\", 0);\n"
+"#endif\n"
+"\n"
+" if (sipModule == NULL)\n"
+" SIP_MODULE_RETURN(NULL);\n"
+"\n"
+" sipModuleDict = PyModule_GetDict(sipModule);\n"
+"\n"
+ , pt->module->fullname->text);
+
+ for (mod = pt->modules; mod != NULL; mod = mod->next)
+ if (mod->container == pt->module)
+ prcode(fp,
+" sip_import_component_module(sipModuleDict, \"%s\");\n"
+ , mod->fullname->text);
+
+ prcode(fp,
+"\n"
+" PyErr_Clear();\n"
+"\n"
+" SIP_MODULE_RETURN(sipModule);\n"
+"}\n"
+ );
+
+ closeFile(fp);
+ free(cppfile);
+}
+
+
+/*
+ * Generate the C/C++ code for a consolidated module.
+ */
+static void generateConsolidatedCpp(sipSpec *pt, const char *codeDir,
+ const char *srcSuffix)
+{
+ char *cppfile;
+ const char *mname = pt->module->name;
+ moduleDef *mod;
+ FILE *fp;
+
+ cppfile = concat(codeDir, "/sip", mname, "cmodule", srcSuffix, NULL);
+ fp = createCompilationUnit(pt->module, cppfile, "Consolidated module code.");
+
+ prcode(fp,
+"\n"
+"#include <Python.h>\n"
+"#include <string.h>\n"
+"#include <sip.h>\n"
+ );
+
+ generateNameCache(pt, fp);
+
+ prcode(fp,
+"\n"
+"\n"
+"/* The component module initialisers. */\n"
+ );
+
+ /* Declare the component module initialisers. */
+ for (mod = pt->modules; mod != NULL; mod = mod->next)
+ if (mod->container == pt->module)
+ prcode(fp,
+"#if PY_MAJOR_VERSION >= 3\n"
+"extern PyObject *sip_init_%s(void);\n"
+"#else\n"
+"extern void sip_init_%s(void);\n"
+"#endif\n"
+ , mod->name
+ , mod->name);
+
+ /* Generate the init function. */
+ prcode(fp,
+"\n"
+"\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static PyObject *sip_init(PyObject *, PyObject *);}\n"
+ );
+
+ prcode(fp,
+"static PyObject *sip_init(PyObject *%s, PyObject *arg)\n"
+"{\n"
+" struct component {\n"
+" const char *name;\n"
+"#if PY_MAJOR_VERSION >= 3\n"
+" PyObject *(*init)(void);\n"
+"#else\n"
+" void (*init)(void);\n"
+"#endif\n"
+" };\n"
+"\n"
+" static struct component components[] = {\n"
+ , (generating_c ? "self" : ""));
+
+ for (mod = pt->modules; mod != NULL; mod = mod->next)
+ if (mod->container == pt->module)
+ prcode(fp,
+" {\"%s\", sip_init_%s},\n"
+ , mod->fullname->text, mod->name);
+
+ prcode(fp,
+" {NULL, NULL}\n"
+" };\n"
+"\n"
+" const char *name;\n"
+" struct component *scd;\n"
+"\n"
+"#if PY_MAJOR_VERSION >= 3\n"
+" name = PyBytes_AsString(arg);\n"
+"#else\n"
+" name = PyString_AsString(arg);\n"
+"#endif\n"
+"\n"
+" if (name == NULL)\n"
+" return NULL;\n"
+"\n"
+" for (scd = components; scd->name != NULL; ++scd)\n"
+" if (strcmp(scd->name, name) == 0)\n"
+"#if PY_MAJOR_VERSION >= 3\n"
+" return (*scd->init)();\n"
+"#else\n"
+" {\n"
+" (*scd->init)();\n"
+"\n"
+" Py_INCREF(Py_None);\n"
+" return Py_None;\n"
+" }\n"
+"#endif\n"
+"\n"
+" PyErr_Format(PyExc_ImportError, \"unknown component module %%s\", name);\n"
+"\n"
+" return NULL;\n"
+"}\n"
+ );
+
+ generateModInitStart(pt->module, generating_c, fp);
+
+ prcode(fp,
+" static PyMethodDef sip_methods[] = {\n"
+" {SIP_MLNAME_CAST(\"init\"), sip_init, METH_O, NULL},\n"
+" {NULL, NULL, 0, NULL}\n"
+" };\n"
+ );
+
+ generateModDefinition(pt->module, "sip_methods", fp);
+
+ prcode(fp,
+"\n"
+"#if PY_MAJOR_VERSION >= 3\n"
+" return PyModule_Create(&sip_module_def);\n"
+"#else\n"
+" Py_InitModule(\"%s\", sip_methods);\n"
+"#endif\n"
+"}\n"
+ , mname);
+
+ closeFile(fp);
+ free(cppfile);
+}
+
+
+/*
+ * Generate the C/C++ code for a component module.
+ */
+static void generateComponentCpp(sipSpec *pt, const char *codeDir,
+ const char *consModule)
+{
+ char *cppfile;
+ FILE *fp;
+
+ cppfile = concat(codeDir, "/sip", pt->module->name, "cmodule.c", NULL);
+ fp = createCompilationUnit(pt->module, cppfile, "Component module code.");
+
+ prcode(fp,
+"\n"
+"#include <Python.h>\n"
+ );
+
+ generateModInitStart(pt->module, TRUE, fp);
+ generateModDefinition(pt->module, "NULL", fp);
+
+ prcode(fp,
+" PyObject *sip_mod, *sip_result;\n"
+"\n"
+" /* Import the consolidated module. */\n"
+" if ((sip_mod = PyImport_ImportModule(\"%s\")) == NULL)\n"
+" SIP_MODULE_RETURN(NULL);\n"
+"\n"
+ , consModule);
+
+ prcode(fp,
+" /* Ask the consolidated module to do the initialistion. */\n"
+"#if PY_MAJOR_VERSION >= 3\n"
+" sip_result = PyObject_CallMethod(sip_mod, \"init\", \"y\", \"%s\");\n"
+"#else\n"
+" sip_result = PyObject_CallMethod(sip_mod, \"init\", \"s\", \"%s\");\n"
+"#endif\n"
+" Py_DECREF(sip_mod);\n"
+"\n"
+"#if PY_MAJOR_VERSION >= 3\n"
+" return sip_result;\n"
+"#else\n"
+" Py_XDECREF(sip_result);\n"
+"#endif\n"
+"}\n"
+ , pt->module->fullname->text
+ , pt->module->fullname->text);
+
+ closeFile(fp);
+ free(cppfile);
+}
+
+
+/*
+ * Generate the name cache definition.
+ */
+static void generateNameCache(sipSpec *pt, FILE *fp)
+{
+ nameDef *nd;
+
+ prcode(fp,
+"\n"
+"/* Define the strings used by this module. */\n"
+ );
+
+ if (isConsolidated(pt->module))
+ prcode(fp,
+"extern const char sipStrings_%s[];\n"
+ , pt->module->name);
+
+ prcode(fp,
+"const char sipStrings_%s[] = {\n"
+ , pt->module->name);
+
+ for (nd = pt->namecache; nd != NULL; nd = nd->next)
+ {
+ const char *cp;
+
+ if (!isUsedName(nd) || isSubstring(nd))
+ continue;
+
+ prcode(fp, " ");
+
+ for (cp = nd->text; *cp != '\0'; ++cp)
+ prcode(fp, "'%c', ", *cp);
+
+ prcode(fp, "0,\n");
+ }
+
+ prcode(fp, "};\n");
+}
+
+
+/*
+ * Generate the C/C++ code.
+ */
+static void generateCpp(sipSpec *pt, moduleDef *mod, const char *codeDir,
+ const char *srcSuffix, int parts, stringList *xsl)
+{
+ char *cppfile;
+ const char *mname = mod->name;
+ int nrSccs = 0, files_in_part, max_per_part, this_part, mod_nr, enum_idx;
+ int is_inst_class, is_inst_voidp, is_inst_char, is_inst_string;
+ int is_inst_int, is_inst_long, is_inst_ulong, is_inst_longlong;
+ int is_inst_ulonglong, is_inst_double, nr_enummembers, is_api_versions;
+ int is_versioned_functions;
+ int hasexternal = FALSE, slot_extenders = FALSE, ctor_extenders = FALSE;
+ FILE *fp;
+ moduleListDef *mld;
+ classDef *cd;
+ memberDef *md;
+ enumDef *ed;
+ ifaceFileDef *iff;
+ virtHandlerDef *vhd;
+ exceptionDef *xd;
+
+ /* Calculate the number of files in each part. */
+ if (parts)
+ {
+ int nr_files = 1;
+
+ for (iff = pt->ifacefiles; iff != NULL; iff = iff->next)
+ if (iff->module == mod && iff->type != exception_iface)
+ ++nr_files;
+
+ max_per_part = (nr_files + parts - 1) / parts;
+ files_in_part = 1;
+ this_part = 0;
+
+ cppfile = makePartName(codeDir, mname, 0, srcSuffix);
+ }
+ else
+ cppfile = concat(codeDir, "/sip", mname, "cmodule", srcSuffix, NULL);
+
+ fp = createCompilationUnit(mod, cppfile, "Module code.");
+
+ prcode(fp,
+"\n"
+"#include \"sipAPI%s.h\"\n"
+ , mname);
+
+ /*
+ * Include the library headers for types used by virtual handlers, module
+ * level functions, module level variables and Qt meta types.
+ */
+ generateUsedIncludes(mod->used, fp);
+
+ /*
+ * If there should be a Qt support API then generate stubs values for the
+ * optional parts. These should be undefined in %ModuleCode if a C++
+ * implementation is provided.
+ */
+ if (mod->qobjclass >= 0)
+ prcode(fp,
+"\n"
+"#define sipQtCreateUniversalSignal 0\n"
+"#define sipQtFindUniversalSignal 0\n"
+"#define sipQtEmitSignal 0\n"
+"#define sipQtConnectPySignal 0\n"
+"#define sipQtDisconnectPySignal 0\n"
+ );
+
+ /* Define the names. */
+ if (mod->container == NULL)
+ generateNameCache(pt, fp);
+
+ /* Generate the C++ code blocks. */
+ generateCppCodeBlock(mod->cppcode, fp);
+
+ /* Generate any virtual handler declarations. */
+ for (vhd = mod->virthandlers; vhd != NULL; vhd = vhd->next)
+ if (!isDuplicateVH(vhd))
+ generateVirtualHandler(vhd, fp);
+
+ /* Generate the global functions. */
+ for (md = mod->othfuncs; md != NULL; md = md->next)
+ if (md->slot == no_slot)
+ generateOrdinaryFunction(pt, mod, NULL, NULL, md, fp);
+ else
+ {
+ overDef *od;
+
+ /*
+ * Make sure that there is still an overload and we haven't moved
+ * them all to classes.
+ */
+ for (od = mod->overs; od != NULL; od = od->next)
+ if (od->common == md)
+ {
+ generateSlot(mod, NULL, NULL, md, fp);
+ slot_extenders = TRUE;
+ break;
+ }
+ }
+
+ /* Generate any class specific ctor or slot extenders. */
+ for (cd = mod->proxies; cd != NULL; cd = cd->next)
+ {
+ if (cd->ctors != NULL)
+ {
+ generateTypeInit(cd, mod, fp);
+ ctor_extenders = TRUE;
+ }
+
+ for (md = cd->members; md != NULL; md = md->next)
+ {
+ generateSlot(mod, cd, NULL, md, fp);
+ slot_extenders = TRUE;
+ }
+ }
+
+ /* Generate any ctor extender table. */
+ if (ctor_extenders)
+ {
+ prcode(fp,
+"\n"
+"static sipInitExtenderDef initExtenders[] = {\n"
+ );
+
+ for (cd = mod->proxies; cd != NULL; cd = cd->next)
+ if (cd->ctors != NULL)
+ {
+ prcode(fp,
+" {%P, init_%L, ", cd->iff->api_range, cd->iff);
+
+ generateEncodedType(mod, cd, 0, fp);
+
+ prcode(fp, ", NULL},\n"
+ );
+ }
+
+ prcode(fp,
+" {-1, NULL, {0, 0, 0}, NULL}\n"
+"};\n"
+ );
+ }
+
+ /* Generate any slot extender table. */
+ if (slot_extenders)
+ {
+ prcode(fp,
+"\n"
+"static sipPySlotExtenderDef slotExtenders[] = {\n"
+ );
+
+ for (md = mod->othfuncs; md != NULL; md = md->next)
+ {
+ overDef *od;
+
+ if (md->slot == no_slot)
+ continue;
+
+ for (od = mod->overs; od != NULL; od = od->next)
+ if (od->common == md)
+ {
+ if (py2OnlySlot(md->slot))
+ prcode(fp,
+"#if PY_MAJOR_VERSION < 3\n"
+ );
+ else if (py2_5LaterSlot(md->slot))
+ prcode(fp,
+"#if PY_VERSION_HEX >= 0x02050000\n"
+ );
+
+ prcode(fp,
+" {(void *)slot_%s, %s, {0, 0, 0}},\n"
+ , md->pyname->text, slotName(md->slot));
+
+ if (py2OnlySlot(md->slot) || py2_5LaterSlot(md->slot))
+ prcode(fp,
+"#endif\n"
+ );
+
+ break;
+ }
+ }
+
+ for (cd = mod->proxies; cd != NULL; cd = cd->next)
+ for (md = cd->members; md != NULL; md = md->next)
+ {
+ if (py2OnlySlot(md->slot))
+ prcode(fp,
+"#if PY_MAJOR_VERSION < 3\n"
+ );
+ else if (py2_5LaterSlot(md->slot))
+ prcode(fp,
+"#if PY_VERSION_HEX >= 0x02050000\n"
+ );
+
+ prcode(fp,
+" {(void *)slot_%L_%s, %s, ", cd->iff, md->pyname->text, slotName(md->slot));
+
+ generateEncodedType(mod, cd, 0, fp);
+
+ prcode(fp, "},\n"
+ );
+
+ if (py2OnlySlot(md->slot) || py2_5LaterSlot(md->slot))
+ prcode(fp,
+"#endif\n"
+ );
+ }
+
+ prcode(fp,
+" {NULL, (sipPySlotType)0, {0, 0, 0}}\n"
+"};\n"
+ );
+ }
+
+ /* Generate the global access functions. */
+ generateAccessFunctions(pt, mod, NULL, fp);
+
+ /* Generate any sub-class convertors. */
+ nrSccs = generateSubClassConvertors(pt, mod, fp);
+
+ /* Generate the external classes table if needed. */
+ for (cd = pt->classes; cd != NULL; cd = cd->next)
+ {
+ if (!isExternal(cd))
+ continue;
+
+ if (cd->iff->module != mod)
+ continue;
+
+ if (!hasexternal)
+ {
+ prcode(fp,
+"\n"
+"\n"
+"/* This defines each external type declared in this module, */\n"
+"static sipExternalTypeDef externalTypesTable[] = {\n"
+ );
+
+ hasexternal = TRUE;
+ }
+
+ prcode(fp,
+" {%d, \"", cd->iff->ifacenr);
+ prScopedName(fp, classFQCName(cd), ".");
+ prcode(fp,"\"},\n"
+ );
+ }
+
+ if (hasexternal)
+ prcode(fp,
+" {-1, NULL}\n"
+"};\n"
+ );
+
+ /* Generate any enum slot tables. */
+ for (ed = pt->enums; ed != NULL; ed = ed->next)
+ {
+ memberDef *slot;
+
+ if (ed->module != mod || ed->fqcname == NULL)
+ continue;
+
+ if (ed->slots == NULL)
+ continue;
+
+ for (slot = ed->slots; slot != NULL; slot = slot->next)
+ generateSlot(mod, NULL, ed, slot, fp);
+
+ prcode(fp,
+"\n"
+"static sipPySlotDef slots_%C[] = {\n"
+ , ed->fqcname);
+
+ for (slot = ed->slots; slot != NULL; slot = slot->next)
+ {
+ const char *stype;
+
+ if ((stype = slotName(slot->slot)) != NULL)
+ {
+ if (py2OnlySlot(slot->slot))
+ prcode(fp,
+"#if PY_MAJOR_VERSION < 3\n"
+ );
+ else if (py2_5LaterSlot(slot->slot))
+ prcode(fp,
+"#if PY_VERSION_HEX >= 0x02050000\n"
+ );
+
+ prcode(fp,
+" {(void *)slot_%C_%s, %s},\n"
+ , ed->fqcname, slot->pyname->text, stype);
+
+ if (py2OnlySlot(slot->slot) || py2_5LaterSlot(slot->slot))
+ prcode(fp,
+"#endif\n"
+ );
+ }
+ }
+
+ prcode(fp,
+" {0, (sipPySlotType)0}\n"
+"};\n"
+"\n"
+ );
+ }
+
+ /* Generate the enum type structures. */
+ enum_idx = 0;
+
+ for (ed = pt->enums; ed != NULL; ed = ed->next)
+ {
+ int type_nr = -1;
+ apiVersionRangeDef *avr = NULL;
+
+ if (ed->module != mod || ed->fqcname == NULL)
+ continue;
+
+ if (ed->ecd != NULL)
+ {
+ if (isTemplateClass(ed->ecd))
+ continue;
+
+ type_nr = ed->ecd->iff->first_alt->ifacenr;
+ avr = ed->ecd->iff->api_range;
+ }
+ else if (ed->emtd != NULL)
+ {
+ type_nr = ed->emtd->iff->first_alt->ifacenr;
+ avr = ed->emtd->iff->api_range;
+ }
+
+ if (enum_idx == 0)
+ {
+ prcode(fp,
+"static sipEnumTypeDef enumTypes[] = {\n"
+ );
+ }
+
+ ed->enum_idx = enum_idx++;
+
+ prcode(fp,
+" {{%P, ", avr);
+
+ if (ed->next_alt != NULL)
+ prcode(fp, "&enumTypes[%d].etd_base", ed->next_alt->enum_idx);
+ else
+ prcode(fp, "0");
+
+ prcode(fp, ", 0, SIP_TYPE_ENUM, %n, {0}}, %n, %d, ", ed->cname, ed->pyname, type_nr);
+
+ if (ed->slots != NULL)
+ prcode(fp, "slots_%C", ed->fqcname);
+ else
+ prcode(fp, "NULL");
+
+ prcode(fp, "},\n"
+ );
+ }
+
+ if (enum_idx != 0)
+ prcode(fp,
+"};\n"
+ );
+
+ nr_enummembers = generateEnumMemberTable(pt, mod, NULL, NULL, fp);
+
+ /* Generate the types table. */
+ if (mod->nrtypes > 0)
+ generateTypesTable(pt, mod, fp);
+
+ if (mod->nrtypedefs > 0)
+ {
+ typedefDef *td;
+
+ prcode(fp,
+"\n"
+"\n"
+"/*\n"
+" * These define each typedef in this module.\n"
+" */\n"
+"static sipTypedefDef typedefsTable[] = {\n"
+ );
+
+ for (td = pt->typedefs; td != NULL; td = td->next)
+ {
+ if (td->module != mod)
+ continue;
+
+ prcode(fp,
+" {\"%S\", \"", td->fqname);
+
+ /* The default behaviour isn't right in a couple of cases. */
+ if (td->type.atype == longlong_type)
+ prcode(fp, "long long");
+ else if (td->type.atype == ulonglong_type)
+ prcode(fp, "unsigned long long");
+ else
+ prcode(fp, "%b", &td->type);
+
+ prcode(fp, "\"},\n"
+ );
+ }
+
+ prcode(fp,
+"};\n"
+ );
+ }
+
+ if (mod->nrvirthandlers > 0)
+ {
+ prcode(fp,
+"\n"
+"\n"
+"/*\n"
+" * This defines the virtual handlers that this module implements and can be\n"
+" * used by other modules.\n"
+" */\n"
+"static sipVirtHandlerFunc virtHandlersTable[] = {\n"
+ );
+
+ for (vhd = mod->virthandlers; vhd != NULL; vhd = vhd->next)
+ if (!isDuplicateVH(vhd))
+ prcode(fp,
+" (sipVirtHandlerFunc)sipVH_%s_%d,\n"
+ , mname, vhd->virthandlernr);
+
+ prcode(fp,
+"};\n"
+ );
+ }
+
+ if (mod->allimports != NULL)
+ {
+ prcode(fp,
+"\n"
+"\n"
+"/* This defines the modules that this module needs to import. */\n"
+"static sipImportedModuleDef importsTable[] = {\n"
+ );
+
+ for (mld = mod->allimports; mld != NULL; mld = mld->next)
+ prcode(fp,
+" {\"%s\", %d, NULL},\n"
+ , mld->module->fullname->text, mld->module->version);
+
+ prcode(fp,
+" {NULL, -1, NULL}\n"
+"};\n"
+ );
+ }
+
+ if (nrSccs > 0)
+ {
+ prcode(fp,
+"\n"
+"\n"
+"/* This defines the class sub-convertors that this module defines. */\n"
+"static sipSubClassConvertorDef convertorsTable[] = {\n"
+ );
+
+ for (cd = pt->classes; cd != NULL; cd = cd->next)
+ {
+ if (cd->iff->module != mod)
+ continue;
+
+ if (cd->convtosubcode == NULL)
+ continue;
+
+ prcode(fp,
+" {sipSubClass_%C, ",classFQCName(cd));
+
+ generateEncodedType(mod, cd->subbase, 0, fp);
+
+ prcode(fp,", NULL},\n");
+ }
+
+ prcode(fp,
+" {NULL, {0, 0, 0}, NULL}\n"
+"};\n"
+ );
+ }
+
+ /* Generate any license information. */
+ if (mod->license != NULL)
+ {
+ licenseDef *ld = mod->license;
+
+ prcode(fp,
+"\n"
+"\n"
+"/* Define the module's license. */\n"
+"static sipLicenseDef module_license = {\n"
+ );
+
+ prcode(fp,
+" \"%s\",\n"
+ , ld->type);
+
+ if (ld->licensee != NULL)
+ prcode(fp,
+" \"%s\",\n"
+ , ld->licensee);
+ else
+ prcode(fp,
+" NULL,\n"
+ );
+
+ if (ld->timestamp != NULL)
+ prcode(fp,
+" \"%s\",\n"
+ , ld->timestamp);
+ else
+ prcode(fp,
+" NULL,\n"
+ );
+
+ if (ld->sig != NULL)
+ prcode(fp,
+" \"%s\"\n"
+ , ld->sig);
+ else
+ prcode(fp,
+" NULL\n"
+ );
+
+ prcode(fp,
+"};\n"
+ );
+ }
+
+ /* Generate each instance table. */
+ is_inst_class = generateClasses(pt, mod, NULL, fp);
+ is_inst_voidp = generateVoidPointers(pt, mod, NULL, fp);
+ is_inst_char = generateChars(pt, mod, NULL, fp);
+ is_inst_string = generateStrings(pt, mod, NULL, fp);
+ is_inst_int = generateInts(pt, mod, NULL, fp);
+ is_inst_long = generateLongs(pt, mod, NULL, fp);
+ is_inst_ulong = generateUnsignedLongs(pt, mod, NULL, fp);
+ is_inst_longlong = generateLongLongs(pt, mod, NULL, fp);
+ is_inst_ulonglong = generateUnsignedLongLongs(pt, mod, NULL, fp);
+ is_inst_double = generateDoubles(pt, mod, NULL, fp);
+
+ /* Generate any exceptions table. */
+ if (mod->nrexceptions > 0)
+ prcode(fp,
+"\n"
+"\n"
+"static PyObject *exceptionsTable[%d];\n"
+ , mod->nrexceptions);
+
+ /* Generate any API versions table. */
+ if (mod->api_ranges != NULL || mod->api_versions != NULL)
+ {
+ apiVersionRangeDef *avr;
+
+ is_api_versions = TRUE;
+
+ prcode(fp,
+"\n"
+"\n"
+"/* This defines the API versions and ranges in use. */\n"
+"static int apiVersions[] = {");
+
+ for (avr = mod->api_ranges; avr != NULL; avr = avr->next)
+ prcode(fp, "%n, %d, %d, ", avr->api_name, avr->from, avr->to);
+
+ for (avr = mod->api_versions; avr != NULL; avr = avr->next)
+ prcode(fp, "%n, %d, -1, ", avr->api_name, avr->from);
+
+ prcode(fp, "-1};\n"
+ );
+ }
+ else
+ is_api_versions = FALSE;
+
+ /* Generate any versioned global functions. */
+ is_versioned_functions = FALSE;
+
+ for (md = mod->othfuncs; md != NULL; md = md->next)
+ if (md->slot == no_slot)
+ {
+ overDef *od;
+ int has_docstring;
+
+ if (notVersioned(md))
+ continue;
+
+ if (!is_versioned_functions)
+ {
+ prcode(fp,
+"\n"
+"\n"
+"/* This defines the global functions where all overloads are versioned. */\n"
+"static sipVersionedFunctionDef versionedFunctions[] = {\n"
+ );
+
+ is_versioned_functions = TRUE;
+ }
+
+ has_docstring = FALSE;
+
+ if (md->docstring != NULL || (docstrings && hasDocstring(pt, mod->overs, md, NULL)))
+ has_docstring = TRUE;
+
+ /*
+ * Every overload has an entry to capture all the version ranges.
+ */
+ for (od = mod->overs; od != NULL; od = od->next)
+ {
+ if (od->common != md)
+ continue;
+
+ prcode(fp,
+" {%n, ", md->pyname);
+
+ if (noArgParser(md) || useKeywordArgsFunction(md))
+ prcode(fp, "(PyCFunction)func_%s, METH_VARARGS|METH_KEYWORDS", md->pyname->text);
+ else
+ prcode(fp, "func_%s, METH_VARARGS", md->pyname->text);
+
+ if (has_docstring)
+ prcode(fp, ", doc_%s", md->pyname->text);
+ else
+ prcode(fp, ", NULL");
+
+ prcode(fp, ", %P},\n"
+ , od->api_range);
+ }
+ }
+
+ if (is_versioned_functions)
+ prcode(fp,
+" {-1, 0, 0, 0, -1}\n"
+"};\n"
+ );
+
+ /* Generate any Qt support API. */
+ if (mod->qobjclass >= 0)
+ prcode(fp,
+"\n"
+"\n"
+"/* This defines the Qt support API. */\n"
+"\n"
+"static sipQtAPI qtAPI = {\n"
+" &typesTable[%d],\n"
+" sipQtCreateUniversalSignal,\n"
+" sipQtFindUniversalSignal,\n"
+" sipQtCreateUniversalSlot,\n"
+" sipQtDestroyUniversalSlot,\n"
+" sipQtFindSlot,\n"
+" sipQtConnect,\n"
+" sipQtDisconnect,\n"
+" sipQtSameSignalSlotName,\n"
+" sipQtFindSipslot,\n"
+" sipQtEmitSignal,\n"
+" sipQtConnectPySignal,\n"
+" sipQtDisconnectPySignal\n"
+"};\n"
+ , mod->qobjclass);
+
+ prcode(fp,
+"\n"
+"\n"
+"/* This defines this module. */\n"
+"sipExportedModuleDef sipModuleAPI_%s = {\n"
+" 0,\n"
+" SIP_API_MINOR_NR,\n"
+" %n,\n"
+" 0,\n"
+" %d,\n"
+" sipStrings_%s,\n"
+" %s,\n"
+" %s,\n"
+" %d,\n"
+" %s,\n"
+" %s,\n"
+" %d,\n"
+" %s,\n"
+" %d,\n"
+" %s,\n"
+" %s,\n"
+" %s,\n"
+" {%s, %s, %s, %s, %s, %s, %s, %s, %s, %s},\n"
+" %s,\n"
+" %s,\n"
+" %s,\n"
+" %s,\n"
+" %s,\n"
+" NULL,\n"
+" %s,\n"
+" %s\n"
+"};\n"
+ , mname
+ , mod->fullname
+ , mod->version
+ , pt->module->name
+ , mod->allimports != NULL ? "importsTable" : "NULL"
+ , mod->qobjclass >= 0 ? "&qtAPI" : "NULL"
+ , mod->nrtypes
+ , mod->nrtypes > 0 ? "typesTable" : "NULL"
+ , hasexternal ? "externalTypesTable" : "NULL"
+ , nr_enummembers
+ , nr_enummembers > 0 ? "enummembers" : "NULL"
+ , mod->nrtypedefs
+ , mod->nrtypedefs > 0 ? "typedefsTable" : "NULL"
+ , mod->nrvirthandlers > 0 ? "virtHandlersTable" : "NULL"
+ , nrSccs > 0 ? "convertorsTable" : "NULL"
+ , is_inst_class ? "typeInstances" : "NULL"
+ , is_inst_voidp ? "voidPtrInstances" : "NULL"
+ , is_inst_char ? "charInstances" : "NULL"
+ , is_inst_string ? "stringInstances" : "NULL"
+ , is_inst_int ? "intInstances" : "NULL"
+ , is_inst_long ? "longInstances" : "NULL"
+ , is_inst_ulong ? "unsignedLongInstances" : "NULL"
+ , is_inst_longlong ? "longLongInstances" : "NULL"
+ , is_inst_ulonglong ? "unsignedLongLongInstances" : "NULL"
+ , is_inst_double ? "doubleInstances" : "NULL"
+ , mod->license != NULL ? "&module_license" : "NULL"
+ , mod->nrexceptions > 0 ? "exceptionsTable" : "NULL"
+ , slot_extenders ? "slotExtenders" : "NULL"
+ , ctor_extenders ? "initExtenders" : "NULL"
+ , hasDelayedDtors(mod) ? "sipDelayedDtors" : "NULL"
+ , is_api_versions ? "apiVersions" : "NULL"
+ , is_versioned_functions ? "versionedFunctions" : "NULL");
+
+ /* Generate the storage for the external API pointers. */
+ prcode(fp,
+"\n"
+"\n"
+"/* The SIP API and the APIs of any imported modules. */\n"
+"const sipAPIDef *sipAPI_%s;\n"
+ , mname);
+
+ for (mld = mod->allimports; mld != NULL; mld = mld->next)
+ prcode(fp,
+"const sipExportedModuleDef *sipModuleAPI_%s_%s;\n"
+ , mname, mld->module->name);
+
+ if (pluginPyQt4(pt))
+ prcode(fp,
+"\n"
+"sip_qt_metaobject_func sip_%s_qt_metaobject;\n"
+"sip_qt_metacall_func sip_%s_qt_metacall;\n"
+"sip_qt_metacast_func sip_%s_qt_metacast;\n"
+ , mname
+ , mname
+ , mname);
+
+ /* Generate the Python module initialisation function. */
+
+ if (mod->container == pt->module)
+ prcode(fp,
+"\n"
+"#if PY_MAJOR_VERSION >= 3\n"
+"#define SIP_MODULE_DISCARD(r) Py_DECREF(r)\n"
+"#define SIP_MODULE_RETURN(r) return (r)\n"
+"PyObject *sip_init_%s()\n"
+"#else\n"
+"#define SIP_MODULE_DISCARD(r)\n"
+"#define SIP_MODULE_RETURN(r) return\n"
+"void sip_init_%s()\n"
+"#endif\n"
+"{\n"
+ , mname
+ , mname);
+ else
+ generateModInitStart(pt->module, generating_c, fp);
+
+ /* Generate the global functions. */
+
+ prcode(fp,
+" static PyMethodDef sip_methods[] = {\n"
+ );
+
+ for (md = mod->othfuncs; md != NULL; md = md->next)
+ if (md->slot == no_slot)
+ {
+ int has_docstring;
+
+ if (!notVersioned(md))
+ continue;
+
+ has_docstring = FALSE;
+
+ if (md->docstring != NULL || (docstrings && hasDocstring(pt, mod->overs, md, NULL)))
+ has_docstring = TRUE;
+
+ prcode(fp,
+" {SIP_MLNAME_CAST(%N), ", md->pyname);
+
+ if (noArgParser(md) || useKeywordArgsFunction(md))
+ prcode(fp, "(PyCFunction)func_%s, METH_VARARGS|METH_KEYWORDS", md->pyname->text);
+ else
+ prcode(fp, "func_%s, METH_VARARGS", md->pyname->text);
+
+ if (has_docstring)
+ prcode(fp, ", SIP_MLDOC_CAST(doc_%s)},\n"
+ , md->pyname->text);
+ else
+ prcode(fp, ", NULL},\n"
+ );
+ }
+
+ prcode(fp,
+" {0, 0, 0, 0}\n"
+" };\n"
+ );
+
+ generateModDefinition(mod, "sip_methods", fp);
+
+ prcode(fp,
+"\n"
+" PyObject *sipModule, *sipModuleDict;\n"
+ );
+
+ generateSipImportVariables(fp);
+
+ /* Generate any pre-initialisation code. */
+ generateCppCodeBlock(mod->preinitcode, fp);
+
+ prcode(fp,
+" /* Initialise the module and get it's dictionary. */\n"
+"#if PY_MAJOR_VERSION >= 3\n"
+" sipModule = PyModule_Create(&sip_module_def);\n"
+"#elif PY_VERSION_HEX >= 0x02050000\n"
+" sipModule = Py_InitModule(%N, sip_methods);\n"
+"#else\n"
+ , mod->fullname);
+
+ if (generating_c)
+ prcode(fp,
+" sipModule = Py_InitModule((char *)%N, sip_methods);\n"
+ , mod->fullname);
+ else
+ prcode(fp,
+" sipModule = Py_InitModule(const_cast<char *>(%N), sip_methods);\n"
+ , mod->fullname);
+
+ prcode(fp,
+"#endif\n"
+"\n"
+" if (sipModule == NULL)\n"
+" SIP_MODULE_RETURN(NULL);\n"
+"\n"
+" sipModuleDict = PyModule_GetDict(sipModule);\n"
+"\n"
+ );
+
+ generateSipImport(mod, fp);
+
+ /* Generate any initialisation code. */
+ generateCppCodeBlock(mod->initcode, fp);
+
+ prcode(fp,
+" /* Export the module and publish it's API. */\n"
+" if (sipExportModule(&sipModuleAPI_%s,SIP_API_MAJOR_NR,SIP_API_MINOR_NR,0) < 0)\n"
+" {\n"
+"#if !defined(SIP_USE_PYCAPSULE)\n"
+" Py_DECREF(sip_sipmod);\n"
+"#endif\n"
+" SIP_MODULE_DISCARD(sipModule);\n"
+" SIP_MODULE_RETURN(0);\n"
+" }\n"
+ , mname);
+
+ if (pluginPyQt4(pt))
+ {
+ /* Import the helpers. */
+ prcode(fp,
+"\n"
+" sip_%s_qt_metaobject = (sip_qt_metaobject_func)sipImportSymbol(\"qtcore_qt_metaobject\");\n"
+" sip_%s_qt_metacall = (sip_qt_metacall_func)sipImportSymbol(\"qtcore_qt_metacall\");\n"
+" sip_%s_qt_metacast = (sip_qt_metacast_func)sipImportSymbol(\"qtcore_qt_metacast\");\n"
+"\n"
+ , mname
+ , mname
+ , mname);
+ }
+
+ prcode(fp,
+" /* Initialise the module now all its dependencies have been set up. */\n"
+" if (sipInitModule(&sipModuleAPI_%s,sipModuleDict) < 0)\n"
+" {\n"
+"#if !defined(SIP_USE_PYCAPSULE)\n"
+" Py_DECREF(sip_sipmod);\n"
+"#endif\n"
+" SIP_MODULE_DISCARD(sipModule);\n"
+" SIP_MODULE_RETURN(0);\n"
+" }\n"
+ , mname);
+
+ mod_nr = 0;
+
+ for (mld = mod->allimports; mld != NULL; mld = mld->next)
+ {
+ if (mod_nr == 0)
+ prcode(fp,
+"\n"
+" /* Get the APIs of the modules that this one is dependent on. */\n"
+ );
+
+ prcode(fp,
+" sipModuleAPI_%s_%s = sipModuleAPI_%s.em_imports[%d].im_module;\n"
+ , mname, mld->module->name, mname, mod_nr);
+
+ ++mod_nr;
+ }
+
+ generateTypesInline(pt, mod, fp);
+
+ /* Create any exceptions. */
+ for (xd = pt->exceptions; xd != NULL; xd = xd->next)
+ {
+ if (xd->iff->module != mod)
+ continue;
+
+ if (xd->iff->type != exception_iface)
+ continue;
+
+ if (xd->exceptionnr < 0)
+ continue;
+
+ prcode(fp,
+"\n"
+" if ((exceptionsTable[%d] = PyErr_NewException(\n"
+"#if PY_MAJOR_VERSION >= 3\n"
+" \"%s.%s\",\n"
+"#else\n"
+" const_cast<char *>(\"%s.%s\"),\n"
+"#endif\n"
+" "
+ , xd->exceptionnr
+ , xd->iff->module->name, xd->pyname
+ , xd->iff->module->name, xd->pyname);
+
+ if (xd->bibase != NULL)
+ prcode(fp, "PyExc_%s", xd->bibase);
+ else if (xd->base->iff->module == mod)
+ prcode(fp, "exceptionsTable[%d]", xd->base->exceptionnr);
+ else
+ prcode(fp, "sipException_%C", xd->base->iff->fqcname);
+
+ prcode(fp, ",NULL)) == NULL || PyDict_SetItemString(sipModuleDict,\"%s\",exceptionsTable[%d]) < 0)\n"
+" {\n"
+"#if !defined(SIP_USE_PYCAPSULE)\n"
+" Py_DECREF(sip_sipmod);\n"
+"#endif\n"
+" SIP_MODULE_DISCARD(sipModule);\n"
+" SIP_MODULE_RETURN(0);\n"
+" }\n"
+ , xd->pyname, xd->exceptionnr);
+ }
+
+ /* Generate any post-initialisation code. */
+ generateCppCodeBlock(mod->postinitcode, fp);
+
+ prcode(fp,
+"\n"
+" SIP_MODULE_RETURN(sipModule);\n"
+"}\n"
+ );
+
+ /* Generate the interface source files. */
+ for (iff = pt->ifacefiles; iff != NULL; iff = iff->next)
+ if (iff->module == mod && iff->type != exception_iface)
+ {
+ if (parts && files_in_part++ == max_per_part)
+ {
+ /* Close the old part. */
+ closeFile(fp);
+ free(cppfile);
+
+ /* Create a new one. */
+ files_in_part = 1;
+ ++this_part;
+
+ cppfile = makePartName(codeDir, mname, this_part, srcSuffix);
+ fp = createCompilationUnit(mod, cppfile, "Module code.");
+
+ prcode(fp,
+"\n"
+"#include \"sipAPI%s.h\"\n"
+ , mname);
+ }
+
+ generateIfaceCpp(pt, iff, codeDir, srcSuffix, (parts ? fp : NULL));
+ }
+
+ closeFile(fp);
+ free(cppfile);
+
+ /* How many parts we actually generated. */
+ if (parts)
+ parts = this_part + 1;
+
+ mod->parts = parts;
+
+ generateInternalAPIHeader(pt, mod, codeDir, xsl);
+}
+
+
+/*
+ * Generate the types table for a module.
+ */
+static void generateTypesTable(sipSpec *pt, moduleDef *mod, FILE *fp)
+{
+ int i;
+ argDef *ad;
+ const char *type_suffix;
+
+ type_suffix = (pluginPyQt4(pt) || pluginPyQt3(pt)) ? ".super" : "";
+
+ prcode(fp,
+"\n"
+"\n"
+"/*\n"
+" * This defines each type in this module.\n"
+" */\n"
+"static sipTypeDef *typesTable[] = {\n"
+ );
+
+ for (ad = mod->types, i = 0; i < mod->nrtypes; ++i, ++ad)
+ {
+ switch (ad->atype)
+ {
+ case class_type:
+ if (isExternal(ad->u.cd))
+ prcode(fp,
+" 0,\n"
+ );
+ else
+ prcode(fp,
+" &sipTypeDef_%s_%L%s.ctd_base,\n"
+ , mod->name, ad->u.cd->iff, type_suffix);
+
+ break;
+
+ case mapped_type:
+ prcode(fp,
+" &sipTypeDef_%s_%L.mtd_base,\n"
+ , mod->name, ad->u.mtd->iff);
+ break;
+
+ case enum_type:
+ prcode(fp,
+" &enumTypes[%d].etd_base,\n"
+ , ad->u.ed->enum_idx);
+ break;
+ }
+ }
+
+ prcode(fp,
+"};\n"
+ );
+}
+
+
+/*
+ * Generate the code to import the sip module and get its API.
+ */
+static void generateSipImport(moduleDef *mod, FILE *fp)
+{
+ prcode(fp,
+" /* Get the SIP module's API. */\n"
+"#if defined(SIP_USE_PYCAPSULE)\n"
+"\n"
+ );
+
+ if (generating_c)
+ prcode(fp,
+" sipAPI_%s = (const sipAPIDef *)PyCapsule_Import(\"sip._C_API\", 0);\n"
+ , mod->name);
+ else
+ prcode(fp,
+" sipAPI_%s = reinterpret_cast<const sipAPIDef *>(PyCapsule_Import(\"sip._C_API\", 0));\n"
+ , mod->name);
+
+ prcode(fp,
+"\n"
+" if (sipAPI_%s == NULL)\n"
+" {\n"
+" SIP_MODULE_DISCARD(sipModule);\n"
+" SIP_MODULE_RETURN(NULL);\n"
+" }\n"
+"\n"
+"#else\n"
+"\n"
+"#if PY_VERSION_HEX >= 0x02050000\n"
+" sip_sipmod = PyImport_ImportModule(\"sip\");\n"
+"#else\n"
+ , mod->name);
+
+ if (generating_c)
+ prcode(fp,
+" sip_sipmod = PyImport_ImportModule((char *)\"sip\");\n"
+ );
+ else
+ prcode(fp,
+" sip_sipmod = PyImport_ImportModule(const_cast<char *>(\"sip\"));\n"
+ );
+
+ prcode(fp,
+"#endif\n"
+"\n"
+" if (sip_sipmod == NULL)\n"
+" {\n"
+" SIP_MODULE_DISCARD(sipModule);\n"
+" SIP_MODULE_RETURN(NULL);\n"
+" }\n"
+"\n"
+" sip_capiobj = PyDict_GetItemString(PyModule_GetDict(sip_sipmod), \"_C_API\");\n"
+"\n"
+" if (sip_capiobj == NULL || !PyCObject_Check(sip_capiobj))\n"
+" {\n"
+" Py_DECREF(sip_sipmod);\n"
+" SIP_MODULE_DISCARD(sipModule);\n"
+" SIP_MODULE_RETURN(NULL);\n"
+" }\n"
+"\n"
+ );
+
+ if (generating_c)
+ prcode(fp,
+" sipAPI_%s = (const sipAPIDef *)PyCObject_AsVoidPtr(sip_capiobj);\n"
+ , mod->name);
+ else
+ prcode(fp,
+" sipAPI_%s = reinterpret_cast<const sipAPIDef *>(PyCObject_AsVoidPtr(sip_capiobj));\n"
+ , mod->name);
+
+ prcode(fp,
+"\n"
+"#endif\n"
+"\n"
+ );
+}
+
+
+/*
+ * Generate the variables needed by generateSipImport().
+ */
+static void generateSipImportVariables(FILE *fp)
+{
+ prcode(fp,
+"#if !defined(SIP_USE_PYCAPSULE)\n"
+" PyObject *sip_sipmod, *sip_capiobj;\n"
+"#endif\n"
+"\n"
+ );
+}
+
+
+/*
+ * Generate the start of the Python module initialisation function.
+ */
+static void generateModInitStart(moduleDef *mod, int gen_c, FILE *fp)
+{
+ prcode(fp,
+"\n"
+"\n"
+"/* The Python module initialisation function. */\n"
+"#if PY_MAJOR_VERSION >= 3\n"
+"#define SIP_MODULE_ENTRY PyInit_%s\n"
+"#define SIP_MODULE_TYPE PyObject *\n"
+"#define SIP_MODULE_DISCARD(r) Py_DECREF(r)\n"
+"#define SIP_MODULE_RETURN(r) return (r)\n"
+"#else\n"
+"#define SIP_MODULE_ENTRY init%s\n"
+"#define SIP_MODULE_TYPE void\n"
+"#define SIP_MODULE_DISCARD(r)\n"
+"#define SIP_MODULE_RETURN(r) return\n"
+"#endif\n"
+"\n"
+"#if defined(SIP_STATIC_MODULE)\n"
+"%sSIP_MODULE_TYPE SIP_MODULE_ENTRY()\n"
+"#else\n"
+"PyMODINIT_FUNC SIP_MODULE_ENTRY()\n"
+"#endif\n"
+"{\n"
+ , mod->name
+ , mod->name
+ , (gen_c ? "" : "extern \"C\" "));
+}
+
+
+/*
+ * Generate the Python v3 module definition structure.
+ */
+static void generateModDefinition(moduleDef *mod, const char *methods,
+ FILE *fp)
+{
+ prcode(fp,
+"\n"
+"#if PY_MAJOR_VERSION >= 3\n"
+" static PyModuleDef sip_module_def = {\n"
+" PyModuleDef_HEAD_INIT,\n"
+" \"%s\",\n"
+" NULL,\n"
+" -1,\n"
+" %s,\n"
+" NULL,\n"
+" NULL,\n"
+" NULL,\n"
+" NULL\n"
+" };\n"
+"#endif\n"
+ , mod->fullname->text
+ , methods);
+}
+
+
+/*
+ * Generate all the sub-class convertors for a module.
+ */
+static int generateSubClassConvertors(sipSpec *pt, moduleDef *mod, FILE *fp)
+{
+ int nrSccs = 0;
+ classDef *cd;
+
+ for (cd = pt->classes; cd != NULL; cd = cd->next)
+ {
+ int needs_sipClass;
+
+ if (cd->iff->module != mod)
+ continue;
+
+ if (cd->convtosubcode == NULL)
+ continue;
+
+ prcode(fp,
+"\n"
+"\n"
+"/* Convert to a sub-class if possible. */\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static const sipTypeDef *sipSubClass_%C(void **);}\n"
+ , classFQCName(cd));
+
+ /* Allow the deprecated use of sipClass rather than sipType. */
+ needs_sipClass = usedInCode(cd->convtosubcode, "sipClass");
+
+ prcode(fp,
+"static const sipTypeDef *sipSubClass_%C(void **sipCppRet)\n"
+"{\n"
+" %S *sipCpp = reinterpret_cast<%S *>(*sipCppRet);\n"
+ , classFQCName(cd)
+ , classFQCName(cd->subbase), classFQCName(cd->subbase));
+
+ if (needs_sipClass)
+ prcode(fp,
+" sipWrapperType *sipClass;\n"
+"\n"
+ );
+ else
+ prcode(fp,
+" const sipTypeDef *sipType;\n"
+"\n"
+ );
+
+ generateCppCodeBlock(cd->convtosubcode, fp);
+
+ if (needs_sipClass)
+ prcode(fp,
+"\n"
+" return (sipClass ? sipClass->type : 0);\n"
+"}\n"
+ );
+ else
+ prcode(fp,
+"\n"
+" return sipType;\n"
+"}\n"
+ );
+
+ ++nrSccs;
+ }
+
+ return nrSccs;
+}
+
+
+/*
+ * Generate the structure representing an encoded type.
+ */
+static void generateEncodedType(moduleDef *mod, classDef *cd, int last,
+ FILE *fp)
+{
+ moduleDef *cmod = cd->iff->module;
+
+ prcode(fp, "{%u, ", cd->iff->first_alt->ifacenr);
+
+ if (cmod == mod)
+ prcode(fp, "255");
+ else
+ {
+ int mod_nr = 0;
+ moduleListDef *mld;
+
+ for (mld = mod->allimports; mld != NULL; mld = mld->next)
+ {
+ if (mld->module == cmod)
+ {
+ prcode(fp, "%u", mod_nr);
+ break;
+ }
+
+ ++mod_nr;
+ }
+ }
+
+ prcode(fp, ", %u}", last);
+}
+
+
+/*
+ * Generate an ordinary function.
+ */
+static void generateOrdinaryFunction(sipSpec *pt, moduleDef *mod,
+ classDef *c_scope, mappedTypeDef *mt_scope, memberDef *md, FILE *fp)
+{
+ overDef *od;
+ int need_intro, has_auto_docstring;
+ ifaceFileDef *scope;
+ classDef *scope_scope;
+ const char *scope_name, *kw_fw_decl, *kw_decl;
+
+ if (mt_scope != NULL)
+ {
+ scope = mt_scope->iff;
+ scope_name = mt_scope->pyname->text;
+ scope_scope = NULL;
+ od = mt_scope->overs;
+ }
+ else if (c_scope != NULL)
+ {
+ scope = c_scope->iff;
+ scope_name = c_scope->pyname->text;
+ scope_scope = NULL;
+ od = c_scope->overs;
+ }
+ else
+ {
+ scope = NULL;
+ scope_name = NULL;
+ scope_scope = NULL;
+ od = mod->overs;
+ }
+
+ prcode(fp,
+"\n"
+"\n"
+ );
+
+ /* Generate the docstrings. */
+ has_auto_docstring = FALSE;
+
+ if (md->docstring != NULL || (docstrings && hasDocstring(pt, od, md, scope)))
+ {
+ if (scope != NULL)
+ prcode(fp,
+"PyDoc_STRVAR(doc_%L_%s, ", scope, md->pyname->text);
+ else
+ prcode(fp,
+"PyDoc_STRVAR(doc_%s, " , md->pyname->text);
+
+ if (md->docstring != NULL)
+ {
+ generateExplicitDocstring(md->docstring, fp);
+ }
+ else
+ {
+ generateDocstring(pt, od, md, scope_name, scope_scope, fp);
+ has_auto_docstring = TRUE;
+ }
+
+ prcode(fp, ");\n"
+"\n"
+ );
+ }
+
+ if (noArgParser(md) || useKeywordArgsFunction(md))
+ {
+ kw_fw_decl = ", PyObject *";
+ kw_decl = ", PyObject *sipKwds";
+ }
+ else
+ {
+ kw_fw_decl = "";
+ kw_decl = "";
+ }
+
+ if (scope != NULL)
+ {
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static PyObject *meth_%L_%s(PyObject *, PyObject *%s);}\n"
+ , scope, md->pyname->text, kw_fw_decl);
+
+ prcode(fp,
+"static PyObject *meth_%L_%s(PyObject *, PyObject *sipArgs%s)\n"
+ , scope, md->pyname->text, kw_decl);
+ }
+ else
+ {
+ const char *self = (generating_c ? "sipSelf" : "");
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static PyObject *func_%s(PyObject *,PyObject *%s);}\n"
+ , md->pyname->text, kw_fw_decl);
+
+ prcode(fp,
+"static PyObject *func_%s(PyObject *%s,PyObject *sipArgs%s)\n"
+ , md->pyname->text, self, kw_decl);
+ }
+
+ prcode(fp,
+"{\n"
+ );
+
+ need_intro = TRUE;
+
+ while (od != NULL)
+ {
+ if (od->common == md)
+ {
+ if (noArgParser(md))
+ {
+ generateCppCodeBlock(od->methodcode, fp);
+ break;
+ }
+
+ if (need_intro)
+ {
+ prcode(fp,
+" PyObject *sipParseErr = NULL;\n"
+ );
+
+ need_intro = FALSE;
+ }
+
+ generateFunctionBody(od, c_scope, mt_scope, c_scope, TRUE, mod, fp);
+ }
+
+ od = od->next;
+ }
+
+ if (!need_intro)
+ {
+ prcode(fp,
+"\n"
+" /* Raise an exception if the arguments couldn't be parsed. */\n"
+" sipNoFunction(sipParseErr, %N, ", md->pyname);
+
+ if (has_auto_docstring)
+ {
+ if (scope != NULL)
+ prcode(fp, "doc_%L_%s", scope, md->pyname->text);
+ else
+ prcode(fp, "doc_%s", md->pyname->text);
+ }
+ else
+ {
+ prcode(fp, "NULL");
+ }
+
+ prcode(fp, ");\n"
+"\n"
+" return NULL;\n"
+ );
+ }
+
+ prcode(fp,
+"}\n"
+ );
+}
+
+
+/*
+ * Generate the table of enum members for a scope. Return the number of them.
+ */
+static int generateEnumMemberTable(sipSpec *pt, moduleDef *mod, classDef *cd,
+ mappedTypeDef *mtd, FILE *fp)
+{
+ int i, nr_members;
+ enumDef *ed;
+ enumMemberDef **etab, **et;
+
+ /* First we count how many. */
+
+ nr_members = 0;
+
+ for (ed = pt->enums; ed != NULL; ed = ed->next)
+ {
+ enumMemberDef *emd;
+
+ if (ed->module != mod)
+ continue;
+
+ if (cd != NULL)
+ {
+ if (ed->ecd != cd)
+ continue;
+ }
+ else if (mtd != NULL)
+ {
+ if (ed->emtd != mtd)
+ continue;
+ }
+ else if (ed->ecd != NULL || ed->emtd != NULL || ed->fqcname == NULL)
+ {
+ continue;
+ }
+
+ for (emd = ed->members; emd != NULL; emd = emd->next)
+ ++nr_members;
+ }
+
+ if (nr_members == 0)
+ return 0;
+
+ /* Create a table so they can be sorted. */
+
+ etab = sipCalloc(nr_members, sizeof (enumMemberDef *));
+
+ et = etab;
+
+ for (ed = pt->enums; ed != NULL; ed = ed->next)
+ {
+ enumMemberDef *emd;
+
+ if (ed->module != mod)
+ continue;
+
+ if (cd != NULL)
+ {
+ if (ed->ecd != cd)
+ continue;
+ }
+ else if (mtd != NULL)
+ {
+ if (ed->emtd != mtd)
+ continue;
+ }
+ else if (ed->ecd != NULL || ed->emtd != NULL || ed->fqcname == NULL)
+ {
+ continue;
+ }
+
+ for (emd = ed->members; emd != NULL; emd = emd->next)
+ *et++ = emd;
+ }
+
+ qsort(etab, nr_members, sizeof (enumMemberDef *), compareEnumMembers);
+
+ /* Now generate the table. */
+
+ if (cd == NULL && mtd == NULL)
+ {
+ prcode(fp,
+"\n"
+"/* These are the enum members of all global enums. */\n"
+"static sipEnumMemberDef enummembers[] = {\n"
+ );
+ }
+ else
+ {
+ ifaceFileDef *iff = (cd != NULL ? cd->iff : mtd->iff);
+
+ prcode(fp,
+"\n"
+"static sipEnumMemberDef enummembers_%L[] = {\n"
+ , iff);
+ }
+
+ for (i = 0; i < nr_members; ++i)
+ {
+ enumMemberDef *emd;
+
+ emd = etab[i];
+
+ prcode(fp,
+" {%N, ", emd->pyname);
+
+ if (cd != NULL)
+ {
+ if (isProtectedEnum(emd->ed))
+ prcode(fp, "sip%C::", classFQCName(cd));
+ else if (isProtectedClass(cd))
+ prcode(fp, "%U::", cd);
+ else
+ prcode(fp, "%S::", classFQCName(cd));
+ }
+ else if (mtd != NULL)
+ {
+ prcode(fp, "%S::", mtd->iff->fqcname);
+ }
+
+ prcode(fp, "%s, %d},\n", emd->cname, emd->ed->first_alt->enumnr);
+ }
+
+ prcode(fp,
+"};\n"
+ );
+
+ return nr_members;
+}
+
+
+/*
+ * The qsort helper to compare two enumMemberDef structures based on the name
+ * of the enum member.
+ */
+static int compareEnumMembers(const void *m1,const void *m2)
+{
+ return strcmp((*(enumMemberDef **)m1)->pyname->text,
+ (*(enumMemberDef **)m2)->pyname->text);
+}
+
+
+/*
+ * Generate the access functions for the variables.
+ */
+static void generateAccessFunctions(sipSpec *pt, moduleDef *mod, classDef *cd,
+ FILE *fp)
+{
+ varDef *vd;
+
+ for (vd = pt->vars; vd != NULL; vd = vd->next)
+ {
+ if (vd->accessfunc == NULL)
+ continue;
+
+ if (vd->ecd != cd || vd->module != mod)
+ continue;
+
+ prcode(fp,
+"\n"
+"\n"
+"/* Access function. */\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static void *access_%C();}\n"
+ , vd->fqcname);
+
+ prcode(fp,
+"static void *access_%C()\n"
+"{\n"
+ , vd->fqcname);
+
+ generateCppCodeBlock(vd->accessfunc, fp);
+
+ prcode(fp,
+"}\n"
+ );
+ }
+}
+
+
+/*
+ * Generate the inline code to add a set of generated type instances to a
+ * dictionary.
+ */
+static void generateTypesInline(sipSpec *pt, moduleDef *mod, FILE *fp)
+{
+ int noIntro;
+ varDef *vd;
+
+ noIntro = TRUE;
+
+ for (vd = pt->vars; vd != NULL; vd = vd->next)
+ {
+ if (vd->module != mod)
+ continue;
+
+ if (vd->type.atype != class_type && vd->type.atype != mapped_type && vd->type.atype != enum_type)
+ continue;
+
+ if (needsHandler(vd))
+ continue;
+
+ /* Skip classes that don't need inline code. */
+ if (generating_c || vd->accessfunc != NULL || vd->type.nrderefs != 0)
+ continue;
+
+ if (noIntro)
+ {
+ prcode(fp,
+"\n"
+" /*\n"
+" * Define the class, mapped type and enum instances that have to be\n"
+" * added inline.\n"
+" */\n"
+ );
+
+ noIntro = FALSE;
+ }
+
+ prcode(fp,
+" sipAddTypeInstance(");
+
+ if (vd->ecd == NULL)
+ prcode(fp, "sipModuleDict");
+ else
+ prcode(fp, "(PyObject *)sipTypeAsPyTypeObject(sipType_%C)", classFQCName(vd->ecd));
+
+ prcode(fp, ",%N,", vd->pyname);
+
+ if (isConstArg(&vd->type))
+ prcode(fp, "const_cast<%b *>(&%S)", &vd->type, vd->fqcname);
+ else
+ prcode(fp, "&%S", vd->fqcname);
+
+ if (vd->type.atype == class_type)
+ prcode(fp, ",sipType_%C);\n"
+ , classFQCName(vd->type.u.cd));
+ else if (vd->type.atype == enum_type)
+ prcode(fp, ",sipType_%C);\n"
+ , vd->type.u.ed->fqcname);
+ else
+ prcode(fp, ",sipType_%T);\n"
+ , &vd->type);
+ }
+}
+
+
+/*
+ * Generate the code to add a set of class instances to a dictionary. Return
+ * TRUE if there was at least one.
+ */
+static int generateClasses(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp)
+{
+ int noIntro;
+ varDef *vd;
+
+ noIntro = TRUE;
+
+ for (vd = pt->vars; vd != NULL; vd = vd->next)
+ {
+ if (vd->ecd != cd || vd->module != mod)
+ continue;
+
+ if (vd->type.atype != class_type && (vd->type.atype != enum_type || vd->type.u.ed->fqcname == NULL))
+ continue;
+
+ if (needsHandler(vd))
+ continue;
+
+ /*
+ * Skip ordinary C++ class instances which need to be done with inline
+ * code rather than through a static table. This is because C++ does
+ * not guarantee the order in which the table and the instance will be
+ * created. So far this has only been seen to be a problem when
+ * statically linking SIP generated modules on Windows.
+ */
+ if (!generating_c && vd->accessfunc == NULL && vd->type.nrderefs == 0)
+ continue;
+
+ if (noIntro)
+ {
+ if (cd != NULL)
+ prcode(fp,
+"\n"
+"\n"
+"/* Define the class and enum instances to be added to this type dictionary. */\n"
+"static sipTypeInstanceDef typeInstances_%C[] = {\n"
+ , classFQCName(cd));
+ else
+ prcode(fp,
+"\n"
+"\n"
+"/* Define the class and enum instances to be added to this module dictionary. */\n"
+"static sipTypeInstanceDef typeInstances[] = {\n"
+ );
+
+ noIntro = FALSE;
+ }
+
+ prcode(fp,
+" {%N, ", vd->pyname);
+
+ if (vd->type.atype == class_type)
+ {
+ scopedNameDef *vcname = classFQCName(vd->type.u.cd);
+
+ if (vd->accessfunc != NULL)
+ {
+ prcode(fp, "(void *)access_%C, &sipType_%C, SIP_ACCFUNC", vd->fqcname, vcname);
+ }
+ else if (vd->type.nrderefs != 0)
+ {
+ prcode(fp, "&%S, &sipType_%C, SIP_INDIRECT", vd->fqcname, vcname);
+ }
+ else if (isConstArg(&vd->type))
+ {
+ prcode(fp, "const_cast<%b *>(&%S), &sipType_%C, 0", &vd->type, vd->fqcname, vcname);
+ }
+ else
+ {
+ prcode(fp, "&%S, &sipType_%C, 0", vd->fqcname, vcname);
+ }
+ }
+ else
+ {
+ prcode(fp, "&%S, &sipType_%C, 0", vd->fqcname, vd->type.u.ed->fqcname);
+ }
+
+ prcode(fp, "},\n"
+ );
+ }
+
+ if (!noIntro)
+ prcode(fp,
+" {0, 0, 0, 0}\n"
+"};\n"
+ );
+
+ return !noIntro;
+}
+
+
+/*
+ * Generate the code to add a set of void pointers to a dictionary. Return
+ * TRUE if there was at least one.
+ */
+static int generateVoidPointers(sipSpec *pt, moduleDef *mod, classDef *cd,
+ FILE *fp)
+{
+ int noIntro;
+ varDef *vd;
+
+ noIntro = TRUE;
+
+ for (vd = pt->vars; vd != NULL; vd = vd->next)
+ {
+ if (vd->ecd != cd || vd->module != mod)
+ continue;
+
+ if (vd->type.atype != void_type && vd->type.atype != struct_type)
+ continue;
+
+ if (needsHandler(vd))
+ continue;
+
+ if (noIntro)
+ {
+ if (cd != NULL)
+ prcode(fp,
+"\n"
+"\n"
+"/* Define the void pointers to be added to this type dictionary. */\n"
+"static sipVoidPtrInstanceDef voidPtrInstances_%C[] = {\n"
+ , classFQCName(cd));
+ else
+ prcode(fp,
+"\n"
+"\n"
+"/* Define the void pointers to be added to this module dictionary. */\n"
+"static sipVoidPtrInstanceDef voidPtrInstances[] = {\n"
+ );
+
+ noIntro = FALSE;
+ }
+
+ if (isConstArg(&vd->type))
+ prcode(fp,
+" {%N, const_cast<%b *>(%S)},\n"
+ , vd->pyname, &vd->type, vd->fqcname);
+ else
+ prcode(fp,
+" {%N, %S},\n"
+ , vd->pyname, vd->fqcname);
+ }
+
+ if (!noIntro)
+ prcode(fp,
+" {0, 0}\n"
+"};\n"
+ );
+
+ return !noIntro;
+}
+
+
+/*
+ * Generate the code to add a set of characters to a dictionary. Return TRUE
+ * if there was at least one.
+ */
+static int generateChars(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp)
+{
+ int noIntro;
+ varDef *vd;
+
+ noIntro = TRUE;
+
+ for (vd = pt->vars; vd != NULL; vd = vd->next)
+ {
+ argType vtype = vd->type.atype;
+
+ if (vd->ecd != cd || vd->module != mod)
+ continue;
+
+ if (!((vtype == ascii_string_type || vtype == latin1_string_type || vtype == utf8_string_type || vtype == sstring_type || vtype == ustring_type || vtype == string_type || vtype == wstring_type) && vd->type.nrderefs == 0))
+ continue;
+
+ if (needsHandler(vd))
+ continue;
+
+ if (noIntro)
+ {
+ if (cd != NULL)
+ prcode(fp,
+"\n"
+"\n"
+"/* Define the chars to be added to this type dictionary. */\n"
+"static sipCharInstanceDef charInstances_%C[] = {\n"
+ , classFQCName(cd));
+ else
+ prcode(fp,
+"\n"
+"\n"
+"/* Define the chars to be added to this module dictionary. */\n"
+"static sipCharInstanceDef charInstances[] = {\n"
+ );
+
+ noIntro = FALSE;
+ }
+
+ prcode(fp,
+" {%N, %S, '%c'},\n"
+ , vd->pyname, vd->fqcname, getEncoding(vtype));
+ }
+
+ if (!noIntro)
+ prcode(fp,
+" {0, 0, 0}\n"
+"};\n"
+ );
+
+ return !noIntro;
+}
+
+
+/*
+ * Generate the code to add a set of strings to a dictionary. Return TRUE if
+ * there is at least one.
+ */
+static int generateStrings(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp)
+{
+ int noIntro;
+ varDef *vd;
+
+ noIntro = TRUE;
+
+ for (vd = pt->vars; vd != NULL; vd = vd->next)
+ {
+ argType vtype = vd->type.atype;
+
+ if (vd->ecd != cd || vd->module != mod)
+ continue;
+
+ if (!((vtype == ascii_string_type || vtype == latin1_string_type || vtype == utf8_string_type || vtype == sstring_type || vtype == ustring_type || vtype == string_type || vtype == wstring_type) && vd->type.nrderefs != 0))
+ continue;
+
+ if (needsHandler(vd))
+ continue;
+
+ if (noIntro)
+ {
+ if (cd != NULL)
+ prcode(fp,
+"\n"
+"\n"
+"/* Define the strings to be added to this type dictionary. */\n"
+"static sipStringInstanceDef stringInstances_%C[] = {\n"
+ , classFQCName(cd));
+ else
+ prcode(fp,
+"\n"
+"\n"
+"/* Define the strings to be added to this module dictionary. */\n"
+"static sipStringInstanceDef stringInstances[] = {\n"
+ );
+
+ noIntro = FALSE;
+ }
+
+ prcode(fp,
+" {%N, %S, '%c'},\n"
+ , vd->pyname, vd->fqcname, getEncoding(vtype));
+ }
+
+ if (!noIntro)
+ prcode(fp,
+" {0, 0, 0}\n"
+"};\n"
+ );
+
+ return !noIntro;
+}
+
+
+/*
+ * Generate the code to add a set of ints to a dictionary. Return TRUE if
+ * there was at least one.
+ */
+static int generateInts(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp)
+{
+ int noIntro;
+ varDef *vd;
+ enumDef *ed;
+
+ noIntro = TRUE;
+
+ for (vd = pt->vars; vd != NULL; vd = vd->next)
+ {
+ argType vtype = vd->type.atype;
+
+ if (vd->ecd != cd || vd->module != mod)
+ continue;
+
+ if (!(vtype == enum_type || vtype == ushort_type ||
+ vtype == short_type || vtype == uint_type ||
+ vtype == cint_type || vtype == int_type ||
+ vtype == bool_type || vtype == cbool_type))
+ continue;
+
+ if (needsHandler(vd))
+ continue;
+
+ /* Named enums are handled elsewhere. */
+ if (vtype == enum_type && vd->type.u.ed->fqcname != NULL)
+ continue;
+
+ if (noIntro)
+ {
+ ints_intro(cd, fp);
+ noIntro = FALSE;
+ }
+
+ prcode(fp,
+" {%N, %S},\n"
+ , vd->pyname, vd->fqcname);
+ }
+
+ /* Now do global anonymous enums. */
+ if (cd == NULL)
+ for (ed = pt->enums; ed != NULL; ed = ed->next)
+ {
+ enumMemberDef *em;
+
+ if (ed->ecd != cd || ed->module != mod)
+ continue;
+
+ if (ed->fqcname != NULL)
+ continue;
+
+ for (em = ed->members; em != NULL; em = em->next)
+ {
+ if (noIntro)
+ {
+ ints_intro(cd, fp);
+ noIntro = FALSE;
+ }
+
+ prcode(fp,
+" {%N, %s},\n"
+ , em->pyname, em->cname);
+ }
+ }
+
+ if (!noIntro)
+ prcode(fp,
+" {0, 0}\n"
+"};\n"
+ );
+
+ return !noIntro;
+}
+
+
+/*
+ * Generate the intro for a table of int instances.
+ */
+static void ints_intro(classDef *cd, FILE *fp)
+{
+ if (cd != NULL)
+ prcode(fp,
+"\n"
+"\n"
+"/* Define the ints to be added to this type dictionary. */\n"
+"static sipIntInstanceDef intInstances_%C[] = {\n"
+ ,classFQCName(cd));
+ else
+ prcode(fp,
+"\n"
+"\n"
+"/* Define the ints to be added to this module dictionary. */\n"
+"static sipIntInstanceDef intInstances[] = {\n"
+ );
+}
+
+
+/*
+ * Generate the code to add a set of longs to a dictionary. Return TRUE if
+ * there was at least one.
+ */
+static int generateLongs(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp)
+{
+ return generateVariableType(pt, mod, cd, long_type, "long", "Long", "long", fp);
+}
+
+
+/*
+ * Generate the code to add a set of unsigned longs to a dictionary. Return
+ * TRUE if there was at least one.
+ */
+static int generateUnsignedLongs(sipSpec *pt, moduleDef *mod, classDef *cd,
+ FILE *fp)
+{
+ return generateVariableType(pt, mod, cd, ulong_type, "unsigned long", "UnsignedLong", "unsignedLong", fp);
+}
+
+
+/*
+ * Generate the code to add a set of long longs to a dictionary. Return TRUE
+ * if there was at least one.
+ */
+static int generateLongLongs(sipSpec *pt, moduleDef *mod, classDef *cd,
+ FILE *fp)
+{
+ return generateVariableType(pt, mod, cd, longlong_type, "long long", "LongLong", "longLong", fp);
+}
+
+
+/*
+ * Generate the code to add a set of unsigned long longs to a dictionary.
+ * Return TRUE if there was at least one.
+ */
+static int generateUnsignedLongLongs(sipSpec *pt, moduleDef *mod, classDef *cd,
+ FILE *fp)
+{
+ return generateVariableType(pt, mod, cd, ulonglong_type, "unsigned long long", "UnsignedLongLong", "unsignedLongLong", fp);
+}
+
+
+/*
+ * Generate the code to add a set of a particular type to a dictionary. Return
+ * TRUE if there was at least one.
+ */
+static int generateVariableType(sipSpec *pt, moduleDef *mod, classDef *cd,
+ argType atype, const char *eng, const char *s1, const char *s2,
+ FILE *fp)
+{
+ int noIntro;
+ varDef *vd;
+
+ noIntro = TRUE;
+
+ for (vd = pt->vars; vd != NULL; vd = vd->next)
+ {
+ argType vtype = vd->type.atype;
+
+ if (vd->ecd != cd || vd->module != mod)
+ continue;
+
+ if (vtype != atype)
+ continue;
+
+ if (needsHandler(vd))
+ continue;
+
+ if (noIntro)
+ {
+ if (cd != NULL)
+ prcode(fp,
+"\n"
+"\n"
+"/* Define the %ss to be added to this type dictionary. */\n"
+"static sip%sInstanceDef %sInstances_%C[] = {\n"
+ , eng
+ , s1, s2, classFQCName(cd));
+ else
+ prcode(fp,
+"\n"
+"\n"
+"/* Define the %ss to be added to this module dictionary. */\n"
+"static sip%sInstanceDef %sInstances[] = {\n"
+ , eng
+ , s1, s2);
+
+ noIntro = FALSE;
+ }
+
+ prcode(fp,
+" {%N, %S},\n"
+ , vd->pyname, vd->fqcname);
+ }
+
+ if (!noIntro)
+ prcode(fp,
+" {0, 0}\n"
+"};\n"
+ );
+
+ return !noIntro;
+}
+
+
+/*
+ * Generate the code to add a set of doubles to a dictionary. Return TRUE if
+ * there was at least one.
+ */
+static int generateDoubles(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp)
+{
+ int noIntro;
+ varDef *vd;
+
+ noIntro = TRUE;
+
+ for (vd = pt->vars; vd != NULL; vd = vd->next)
+ {
+ argType vtype = vd->type.atype;
+
+ if (vd->ecd != cd || vd->module != mod)
+ continue;
+
+ if (!(vtype == float_type || vtype == cfloat_type || vtype == double_type || vtype == cdouble_type))
+ continue;
+
+ if (needsHandler(vd))
+ continue;
+
+ if (noIntro)
+ {
+ if (cd != NULL)
+ prcode(fp,
+"\n"
+"\n"
+"/* Define the doubles to be added to this type dictionary. */\n"
+"static sipDoubleInstanceDef doubleInstances_%C[] = {\n"
+ , classFQCName(cd));
+ else
+ prcode(fp,
+"\n"
+"\n"
+"/* Define the doubles to be added to this module dictionary. */\n"
+"static sipDoubleInstanceDef doubleInstances[] = {\n"
+ );
+
+ noIntro = FALSE;
+ }
+
+ prcode(fp,
+" {%N, %S},\n"
+ , vd->pyname, vd->fqcname);
+ }
+
+ if (!noIntro)
+ prcode(fp,
+" {0, 0}\n"
+"};\n"
+ );
+
+ return !noIntro;
+}
+
+
+/*
+ * Generate the C/C++ code for an interface.
+ */
+static void generateIfaceCpp(sipSpec *pt, ifaceFileDef *iff,
+ const char *codeDir, const char *srcSuffix, FILE *master)
+{
+ char *cppfile;
+ const char *cmname = iff->module->name;
+ classDef *cd;
+ mappedTypeDef *mtd;
+ FILE *fp;
+
+ if (master == NULL)
+ {
+ cppfile = createIfaceFileName(codeDir,iff,srcSuffix);
+ fp = createCompilationUnit(iff->module, cppfile, "Interface wrapper code.");
+
+ prcode(fp,
+"\n"
+"#include \"sipAPI%s.h\"\n"
+ , cmname);
+ }
+ else
+ fp = master;
+
+ prcode(fp,
+"\n"
+ );
+
+ generateCppCodeBlock(iff->hdrcode, fp);
+ generateUsedIncludes(iff->used, fp);
+
+ for (cd = pt->classes; cd != NULL; cd = cd->next)
+ {
+ /*
+ * Protected classes must be generated in the interface file of the
+ * enclosing scope.
+ */
+ if (isProtectedClass(cd))
+ continue;
+
+ if (cd->iff == iff && !isExternal(cd))
+ {
+ classDef *pcd;
+
+ generateClassCpp(cd, pt, fp);
+
+ /* Generate any enclosed protected classes. */
+ for (pcd = pt->classes; pcd != NULL; pcd = pcd->next)
+ if (isProtectedClass(pcd) && pcd->ecd == cd)
+ generateClassCpp(pcd, pt, fp);
+ }
+ }
+
+ for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next)
+ if (mtd->iff == iff)
+ generateMappedTypeCpp(mtd, pt, fp);
+
+ if (master == NULL)
+ {
+ closeFile(fp);
+ free(cppfile);
+ }
+}
+
+
+/*
+ * Return a filename for an interface C++ or header file on the heap.
+ */
+static char *createIfaceFileName(const char *codeDir, ifaceFileDef *iff,
+ const char *suffix)
+{
+ char *fn;
+ scopedNameDef *snd;
+
+ fn = concat(codeDir,"/sip",iff->module->name,NULL);
+
+ for (snd = iff->fqcname; snd != NULL; snd = snd->next)
+ append(&fn,snd->name);
+
+ if (iff->api_range != NULL)
+ {
+ char buf[50];
+
+ sprintf(buf, "_%d", iff->api_range->index);
+ append(&fn, buf);
+ }
+
+ append(&fn,suffix);
+
+ return fn;
+}
+
+
+/*
+ * Generate the C++ code for a mapped type version.
+ */
+static void generateMappedTypeCpp(mappedTypeDef *mtd, sipSpec *pt, FILE *fp)
+{
+ int need_xfer, nr_methods, nr_enums;
+ memberDef *md;
+
+ if (!noRelease(mtd))
+ {
+ /* Generate the assignment helper. */
+ prcode(fp,
+"\n"
+"\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static void assign_%L(void *, SIP_SSIZE_T, const void *);}\n"
+ , mtd->iff);
+
+ prcode(fp,
+"static void assign_%L(void *sipDst, SIP_SSIZE_T sipDstIdx, const void *sipSrc)\n"
+"{\n"
+ , mtd->iff);
+
+ if (generating_c)
+ prcode(fp,
+" ((%b *)sipDst)[sipDstIdx] = *((const %b *)sipSrc);\n"
+ , &mtd->type, &mtd->type);
+ else
+ prcode(fp,
+" reinterpret_cast<%b *>(sipDst)[sipDstIdx] = *reinterpret_cast<const %b *>(sipSrc);\n"
+ , &mtd->type, &mtd->type);
+
+ prcode(fp,
+"}\n"
+ );
+
+ /* Generate the array allocation helper. */
+ prcode(fp,
+"\n"
+"\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static void *array_%L(SIP_SSIZE_T);}\n"
+ , mtd->iff);
+
+ prcode(fp,
+"static void *array_%L(SIP_SSIZE_T sipNrElem)\n"
+"{\n"
+ , mtd->iff);
+
+ if (generating_c)
+ prcode(fp,
+" return sipMalloc(sizeof (%b) * sipNrElem);\n"
+ , &mtd->type);
+ else
+ prcode(fp,
+" return new %b[sipNrElem];\n"
+ , &mtd->type);
+
+ prcode(fp,
+"}\n"
+ );
+
+ /* Generate the copy helper. */
+ prcode(fp,
+"\n"
+"\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static void *copy_%L(const void *, SIP_SSIZE_T);}\n"
+ , mtd->iff);
+
+ prcode(fp,
+"static void *copy_%L(const void *sipSrc, SIP_SSIZE_T sipSrcIdx)\n"
+"{\n"
+ , mtd->iff);
+
+ if (generating_c)
+ prcode(fp,
+" %b *sipPtr = sipMalloc(sizeof (%b));\n"
+" *sipPtr = ((const %b *)sipSrc)[sipSrcIdx];\n"
+"\n"
+" return sipPtr;\n"
+ , &mtd->type, &mtd->type
+ , &mtd->type);
+ else
+ prcode(fp,
+" return new %b(reinterpret_cast<const %b *>(sipSrc)[sipSrcIdx]);\n"
+ , &mtd->type, &mtd->type);
+
+ prcode(fp,
+"}\n"
+ );
+
+ prcode(fp,
+"\n"
+"\n"
+"/* Call the mapped type's destructor. */\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static void release_%L(void *, int);}\n"
+ , mtd->iff);
+
+ prcode(fp,
+"static void release_%L(void *ptr, int%s)\n"
+"{\n"
+ , mtd->iff, (generating_c ? " status" : ""));
+
+ if (release_gil)
+ prcode(fp,
+" Py_BEGIN_ALLOW_THREADS\n"
+ );
+
+ if (generating_c)
+ prcode(fp,
+" sipFree(ptr);\n"
+ );
+ else
+ prcode(fp,
+" delete reinterpret_cast<%b *>(ptr);\n"
+ , &mtd->type);
+
+ if (release_gil)
+ prcode(fp,
+" Py_END_ALLOW_THREADS\n"
+ );
+
+ prcode(fp,
+"}\n"
+"\n"
+ );
+ }
+
+ generateConvertToDefinitions(mtd,NULL,fp);
+
+ /* Generate the from type convertor. */
+
+ need_xfer = (generating_c || usedInCode(mtd->convfromcode, "sipTransferObj"));
+
+ prcode(fp,
+"\n"
+"\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static PyObject *convertFrom_%L(void *, PyObject *);}\n"
+ , mtd->iff);
+
+ prcode(fp,
+"static PyObject *convertFrom_%L(void *sipCppV,PyObject *%s)\n"
+"{\n"
+" ", mtd->iff, (need_xfer ? "sipTransferObj" : ""));
+
+ generateMappedTypeFromVoid(mtd, "sipCpp", "sipCppV", fp);
+
+ prcode(fp, ";\n"
+"\n"
+ );
+
+ generateCppCodeBlock(mtd->convfromcode,fp);
+
+ prcode(fp,
+"}\n"
+ );
+
+ /* Generate the static methods. */
+ for (md = mtd->members; md != NULL; md = md->next)
+ generateOrdinaryFunction(pt, mtd->iff->module, NULL, mtd, md, fp);
+
+ nr_methods = generateMappedTypeMethodTable(pt, mtd, fp);
+
+ nr_enums = generateEnumMemberTable(pt, mtd->iff->module, NULL, mtd, fp);
+
+ prcode(fp,
+"\n"
+"\n"
+"sipMappedTypeDef ");
+
+ generateTypeDefName(mtd->iff, fp);
+
+ prcode(fp, " = {\n"
+" {\n"
+" %P,\n"
+" "
+ , mtd->iff->api_range);
+
+ generateTypeDefLink(pt, mtd->iff, fp);
+
+ prcode(fp, ",\n"
+" 0,\n"
+" %sSIP_TYPE_MAPPED,\n"
+" %n,\n"
+" {0}\n"
+" },\n"
+" {\n"
+ , (handlesNone(mtd) ? "SIP_TYPE_ALLOW_NONE|" : "")
+ , mtd->cname);
+
+ if (nr_enums == 0)
+ prcode(fp,
+" -1,\n"
+ );
+ else
+ prcode(fp,
+" %n,\n"
+ , mtd->pyname);
+
+ prcode(fp,
+" {0, 0, 1},\n"
+ );
+
+ if (nr_methods == 0)
+ prcode(fp,
+" 0, 0,\n"
+ );
+ else
+ prcode(fp,
+" %d, methods_%L,\n"
+ , nr_methods, mtd->iff);
+
+ if (nr_enums == 0)
+ prcode(fp,
+" 0, 0,\n"
+ );
+ else
+ prcode(fp,
+" %d, enummembers_%L,\n"
+ , nr_enums, mtd->iff);
+
+ prcode(fp,
+" 0, 0,\n"
+" {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}\n"
+" },\n"
+ );
+
+ if (noRelease(mtd))
+ prcode(fp,
+" 0,\n"
+" 0,\n"
+" 0,\n"
+" 0,\n"
+ );
+ else
+ prcode(fp,
+" assign_%L,\n"
+" array_%L,\n"
+" copy_%L,\n"
+" release_%L,\n"
+ , mtd->iff
+ , mtd->iff
+ , mtd->iff
+ , mtd->iff);
+
+ prcode(fp,
+" convertTo_%L,\n"
+" convertFrom_%L\n"
+ , mtd->iff
+ , mtd->iff);
+
+ prcode(fp,
+"};\n"
+ );
+}
+
+
+/*
+ * Generate the name of the type structure for a class or mapped type.
+ */
+static void generateTypeDefName(ifaceFileDef *iff, FILE *fp)
+{
+ prcode(fp, "sipTypeDef_%s_%L", iff->module->name, iff);
+}
+
+
+/*
+ * Generate the link to a type structure implementing an alternate API.
+ */
+static void generateTypeDefLink(sipSpec *pt, ifaceFileDef *iff, FILE *fp)
+{
+ if (iff->next_alt != NULL)
+ {
+ prcode(fp, "&");
+ generateTypeDefName(iff->next_alt, fp);
+
+ if (iff->next_alt->type == mappedtype_iface)
+ prcode(fp, ".mtd_base");
+ else if (pluginPyQt3(pt) || pluginPyQt4(pt))
+ prcode(fp, ".super.ctd_base");
+ else
+ prcode(fp, ".ctd_base");
+ }
+ else
+ prcode(fp, "0");
+}
+
+
+/*
+ * Generate the C++ code for a class.
+ */
+static void generateClassCpp(classDef *cd, sipSpec *pt, FILE *fp)
+{
+ moduleDef *mod = cd->iff->module;
+
+ /* Generate any local class code. */
+
+ generateCppCodeBlock(cd->cppcode, fp);
+
+ generateClassFunctions(pt, mod, cd, fp);
+
+ generateAccessFunctions(pt, mod, cd, fp);
+
+ if (cd->iff->type != namespace_iface)
+ generateConvertToDefinitions(NULL,cd,fp);
+
+ /* The type definition structure. */
+ generateTypeDefinition(pt, cd, fp);
+}
+
+
+/*
+ * Return a sorted array of relevant functions for a namespace.
+ */
+
+static sortedMethTab *createFunctionTable(memberDef *members, int *nrp)
+{
+ int nr;
+ sortedMethTab *mtab, *mt;
+ memberDef *md;
+
+ /* First we need to count the number of applicable functions. */
+ nr = 0;
+
+ for (md = members; md != NULL; md = md->next)
+ ++nr;
+
+ if ((*nrp = nr) == 0)
+ return NULL;
+
+ /* Create the table of methods. */
+ mtab = sipCalloc(nr, sizeof (sortedMethTab));
+
+ /* Initialise the table. */
+ mt = mtab;
+
+ for (md = members; md != NULL; md = md->next)
+ {
+ mt->md = md;
+ ++mt;
+ }
+
+ /* Finally, sort the table. */
+ qsort(mtab,nr,sizeof (sortedMethTab),compareMethTab);
+
+ return mtab;
+}
+
+
+/*
+ * Return a sorted array of relevant methods (either lazy or non-lazy) for a
+ * class.
+ */
+static sortedMethTab *createMethodTable(classDef *cd, int *nrp)
+{
+ int nr;
+ visibleList *vl;
+ sortedMethTab *mtab, *mt;
+
+ /*
+ * First we need to count the number of applicable methods. Only provide
+ * an entry point if there is at least one overload that is defined in this
+ * class and is a non-abstract function or slot. We allow private (even
+ * though we don't actually generate code) because we need to intercept the
+ * name before it reaches a more public version further up the class
+ * hierarchy. We add the ctor and any variable handlers as special
+ * entries.
+ */
+ nr = 0;
+
+ for (vl = cd->visible; vl != NULL; vl = vl->next)
+ {
+ overDef *od;
+
+ if (vl->m->slot != no_slot)
+ continue;
+
+ for (od = vl->cd->overs; od != NULL; od = od->next)
+ {
+ /*
+ * Skip protected methods if we don't have the means to handle
+ * them.
+ */
+ if (isProtected(od) && !hasShadow(cd))
+ continue;
+
+ if (skipOverload(od,vl->m,cd,vl->cd,TRUE))
+ continue;
+
+ ++nr;
+
+ break;
+ }
+ }
+
+ if ((*nrp = nr) == 0)
+ return NULL;
+
+ /* Create the table of methods. */
+
+ mtab = sipCalloc(nr, sizeof (sortedMethTab));
+
+ /* Initialise the table. */
+
+ mt = mtab;
+
+ for (vl = cd->visible; vl != NULL; vl = vl->next)
+ {
+ int need_method;
+ overDef *od;
+
+ if (vl->m->slot != no_slot)
+ continue;
+
+ need_method = FALSE;
+
+ for (od = vl->cd->overs; od != NULL; od = od->next)
+ {
+ /*
+ * Skip protected methods if we don't have the means to handle
+ * them.
+ */
+ if (isProtected(od) && !hasShadow(cd))
+ continue;
+
+ if (!skipOverload(od,vl->m,cd,vl->cd,TRUE))
+ need_method = TRUE;
+ }
+
+ if (need_method)
+ {
+ mt->md = vl->m;
+ ++mt;
+ }
+ }
+
+ /* Finally sort the table. */
+
+ qsort(mtab,nr,sizeof (sortedMethTab),compareMethTab);
+
+ return mtab;
+}
+
+
+/*
+ * The qsort helper to compare two sortedMethTab structures based on the Python
+ * name of the method.
+ */
+
+static int compareMethTab(const void *m1,const void *m2)
+{
+ return strcmp(((sortedMethTab *)m1)->md->pyname->text,
+ ((sortedMethTab *)m2)->md->pyname->text);
+}
+
+
+/*
+ * Generate the sorted table of static methods for a mapped type and return
+ * the number of entries.
+ */
+static int generateMappedTypeMethodTable(sipSpec *pt, mappedTypeDef *mtd,
+ FILE *fp)
+{
+ int nr;
+ sortedMethTab *mtab;
+
+ mtab = createFunctionTable(mtd->members, &nr);
+
+ if (mtab != NULL)
+ {
+ prMethodTable(pt, mtab, nr, mtd->iff, mtd->overs, fp);
+ free(mtab);
+ }
+
+ return nr;
+}
+
+
+/*
+ * Generate the sorted table of methods for a class and return the number of
+ * entries.
+ */
+static int generateClassMethodTable(sipSpec *pt, classDef *cd, FILE *fp)
+{
+ int nr;
+ sortedMethTab *mtab;
+
+ mtab = (cd->iff->type == namespace_iface) ?
+ createFunctionTable(cd->members, &nr) :
+ createMethodTable(cd, &nr);
+
+ if (mtab != NULL)
+ {
+ prMethodTable(pt, mtab, nr, cd->iff, cd->overs, fp);
+ free(mtab);
+ }
+
+ return nr;
+}
+
+
+/*
+ * Generate a method table for a class or mapped type.
+ */
+static void prMethodTable(sipSpec *pt, sortedMethTab *mtable, int nr,
+ ifaceFileDef *iff, overDef *overs, FILE *fp)
+{
+ int i;
+
+ prcode(fp,
+"\n"
+"\n"
+"static PyMethodDef methods_%L[] = {\n"
+ , iff);
+
+ for (i = 0; i < nr; ++i)
+ {
+ memberDef *md = mtable[i].md;
+ const char *cast, *flags;
+ int has_docstring;
+
+ if (noArgParser(md) || useKeywordArgsFunction(md))
+ {
+ cast = "(PyCFunction)";
+ flags = "|METH_KEYWORDS";
+ }
+ else
+ {
+ cast = "";
+ flags = "";
+ }
+
+ /* Save the index in the table. */
+ md->membernr = i;
+
+ has_docstring = FALSE;
+
+ if (md->docstring != NULL || (docstrings && hasDocstring(pt, overs, md, iff)))
+ has_docstring = TRUE;
+
+ prcode(fp,
+" {SIP_MLNAME_CAST(%N), %smeth_%L_%s, METH_VARARGS%s, ", md->pyname, cast, iff, md->pyname->text, flags);
+
+ if (has_docstring)
+ prcode(fp, "SIP_MLDOC_CAST(doc_%L_%s)", iff, md->pyname->text);
+ else
+ prcode(fp, "NULL");
+
+ prcode(fp, "}%s\n"
+ , ((i + 1) < nr) ? "," : "");
+ }
+
+ prcode(fp,
+"};\n"
+ );
+}
+
+
+/*
+ * Generate the "to type" convertor definitions.
+ */
+
+static void generateConvertToDefinitions(mappedTypeDef *mtd,classDef *cd,
+ FILE *fp)
+{
+ codeBlock *convtocode;
+ ifaceFileDef *iff;
+ argDef type;
+
+ memset(&type, 0, sizeof (argDef));
+
+ if (cd != NULL)
+ {
+ convtocode = cd->convtocode;
+ iff = cd->iff;
+
+ type.atype = class_type;
+ type.u.cd = cd;
+ }
+ else
+ {
+ convtocode = mtd->convtocode;
+ iff = mtd->iff;
+
+ type.atype = mapped_type;
+ type.u.mtd = mtd;
+ }
+
+ /* Generate the type convertors. */
+
+ if (convtocode != NULL)
+ {
+ int need_py, need_ptr, need_iserr, need_xfer;
+
+ /*
+ * Sometimes type convertors are just stubs that set the error
+ * flag, so check if we actually need everything so that we
+ * can avoid compiler warnings.
+ */
+ need_py = (generating_c || usedInCode(convtocode, "sipPy"));
+ need_ptr = (generating_c || usedInCode(convtocode, "sipCppPtr"));
+ need_iserr = (generating_c || usedInCode(convtocode, "sipIsErr"));
+ need_xfer = (generating_c || usedInCode(convtocode, "sipTransferObj"));
+
+ prcode(fp,
+"\n"
+"\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static int convertTo_%L(PyObject *, void **, int *, PyObject *);}\n"
+ , iff);
+
+ prcode(fp,
+"static int convertTo_%L(PyObject *%s,void **%s,int *%s,PyObject *%s)\n"
+"{\n"
+ , iff, (need_py ? "sipPy" : ""), (need_ptr ? "sipCppPtrV" : ""), (need_iserr ? "sipIsErr" : ""), (need_xfer ? "sipTransferObj" : ""));
+
+ if (need_ptr)
+ {
+ if (generating_c)
+ prcode(fp,
+" %b **sipCppPtr = (%b **)sipCppPtrV;\n"
+"\n"
+ , &type, &type);
+ else
+ prcode(fp,
+" %b **sipCppPtr = reinterpret_cast<%b **>(sipCppPtrV);\n"
+"\n"
+ , &type, &type);
+ }
+
+ generateCppCodeBlock(convtocode,fp);
+
+ prcode(fp,
+"}\n"
+ );
+ }
+}
+
+
+/*
+ * Generate a variable getter.
+ */
+static void generateVariableGetter(ifaceFileDef *scope, varDef *vd, FILE *fp)
+{
+ argType atype = vd->type.atype;
+ const char *first_arg, *last_arg;
+ int needsNew;
+
+ if (generating_c || !isStaticVar(vd))
+ first_arg = "sipSelf";
+ else
+ first_arg = "";
+
+ last_arg = (generating_c || usedInCode(vd->getcode, "sipPyType")) ? "sipPyType" : "";
+
+ prcode(fp,
+"\n"
+"\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static PyObject *varget_%C(void *, PyObject *);}\n"
+ , vd->fqcname);
+
+ prcode(fp,
+"static PyObject *varget_%C(void *%s, PyObject *%s)\n"
+"{\n"
+ , vd->fqcname, first_arg, last_arg);
+
+ if (vd->getcode != NULL)
+ {
+ prcode(fp,
+" PyObject *sipPy;\n"
+ );
+ }
+ else
+ {
+ prcode(fp,
+" ");
+
+ generateNamedValueType(scope, &vd->type, "sipVal", fp);
+
+ prcode(fp, ";\n"
+ );
+ }
+
+ if (!isStaticVar(vd))
+ {
+ if (generating_c)
+ prcode(fp,
+" %S *sipCpp = (%S *)sipSelf;\n"
+ , classFQCName(vd->ecd), classFQCName(vd->ecd));
+ else
+ prcode(fp,
+" %S *sipCpp = reinterpret_cast<%S *>(sipSelf);\n"
+ , classFQCName(vd->ecd), classFQCName(vd->ecd));
+
+ prcode(fp,
+"\n"
+ );
+ }
+
+ /* Handle any handwritten getter. */
+ if (vd->getcode != NULL)
+ {
+ generateCppCodeBlock(vd->getcode, fp);
+
+ prcode(fp,
+"\n"
+" return sipPy;\n"
+"}\n"
+ );
+
+ return;
+ }
+
+ needsNew = ((atype == class_type || atype == mapped_type) && vd->type.nrderefs == 0 && isConstArg(&vd->type));
+
+ if (needsNew)
+ {
+ if (generating_c)
+ prcode(fp,
+" *sipVal = ");
+ else
+ prcode(fp,
+" sipVal = new %b(", &vd->type);
+ }
+ else
+ {
+ prcode(fp,
+" sipVal = ");
+
+ if ((atype == class_type || atype == mapped_type) && vd->type.nrderefs == 0)
+ prcode(fp, "&");
+ }
+
+ generateVarMember(vd, fp);
+
+ prcode(fp, "%s;\n"
+"\n"
+ , ((needsNew && !generating_c) ? ")" : ""));
+
+ switch (atype)
+ {
+ case mapped_type:
+ case class_type:
+ {
+ ifaceFileDef *iff;
+
+ if (atype == mapped_type)
+ iff = vd->type.u.mtd->iff;
+ else
+ iff = vd->type.u.cd->iff;
+
+ prcode(fp,
+" return sipConvertFrom%sType(", (needsNew ? "New" : ""));
+
+ if (isConstArg(&vd->type))
+ prcode(fp, "const_cast<%b *>(sipVal)", &vd->type);
+ else
+ prcode(fp, "sipVal");
+
+ prcode(fp, ",sipType_%C, NULL);\n"
+ , iff->fqcname);
+ }
+
+ break;
+
+ case bool_type:
+ case cbool_type:
+ prcode(fp,
+" return PyBool_FromLong(sipVal);\n"
+ );
+
+ break;
+
+ case ascii_string_type:
+ if (vd->type.nrderefs == 0)
+ prcode(fp,
+" return PyUnicode_DecodeASCII(&sipVal, 1, NULL);\n"
+ );
+ else
+ prcode(fp,
+" if (sipVal == NULL)\n"
+" {\n"
+" Py_INCREF(Py_None);\n"
+" return Py_None;\n"
+" }\n"
+"\n"
+" return PyUnicode_DecodeASCII(sipVal, strlen(sipVal), NULL);\n"
+ );
+
+ break;
+
+ case latin1_string_type:
+ if (vd->type.nrderefs == 0)
+ prcode(fp,
+" return PyUnicode_DecodeLatin1(&sipVal, 1, NULL);\n"
+ );
+ else
+ prcode(fp,
+" if (sipVal == NULL)\n"
+" {\n"
+" Py_INCREF(Py_None);\n"
+" return Py_None;\n"
+" }\n"
+"\n"
+" return PyUnicode_DecodeLatin1(sipVal, strlen(sipVal), NULL);\n"
+ );
+
+ break;
+
+ case utf8_string_type:
+ if (vd->type.nrderefs == 0)
+ prcode(fp,
+"#if PY_MAJOR_VERSION >= 3\n"
+" return PyUnicode_FromStringAndSize(&sipVal, 1);\n"
+"#else\n"
+" return PyUnicode_DecodeUTF8(&sipVal, 1, NULL);\n"
+"#endif\n"
+ );
+ else
+ prcode(fp,
+" if (sipVal == NULL)\n"
+" {\n"
+" Py_INCREF(Py_None);\n"
+" return Py_None;\n"
+" }\n"
+"\n"
+"#if PY_MAJOR_VERSION >= 3\n"
+" return PyUnicode_FromString(sipVal);\n"
+"#else\n"
+" return PyUnicode_DecodeUTF8(sipVal, strlen(sipVal), NULL);\n"
+"#endif\n"
+ );
+
+ break;
+
+ case sstring_type:
+ case ustring_type:
+ case string_type:
+ {
+ const char *cast = ((atype != string_type) ? "(char *)" : "");
+
+ if (vd->type.nrderefs == 0)
+ prcode(fp,
+" return SIPBytes_FromStringAndSize(%s&sipVal, 1);\n"
+ , cast);
+ else
+ prcode(fp,
+" if (sipVal == NULL)\n"
+" {\n"
+" Py_INCREF(Py_None);\n"
+" return Py_None;\n"
+" }\n"
+"\n"
+" return SIPBytes_FromString(%ssipVal);\n"
+ , cast);
+ }
+
+ break;
+
+ case wstring_type:
+ if (vd->type.nrderefs == 0)
+ prcode(fp,
+" return PyUnicode_FromWideChar(&sipVal, 1);\n"
+ );
+ else
+ prcode(fp,
+" if (sipVal == NULL)\n"
+" {\n"
+" Py_INCREF(Py_None);\n"
+" return Py_None;\n"
+" }\n"
+"\n"
+" return PyUnicode_FromWideChar(sipVal, (SIP_SSIZE_T)wcslen(sipVal));\n"
+ );
+
+ break;
+
+ case float_type:
+ case cfloat_type:
+ prcode(fp,
+" return PyFloat_FromDouble((double)sipVal);\n"
+ );
+ break;
+
+ case double_type:
+ case cdouble_type:
+ prcode(fp,
+" return PyFloat_FromDouble(sipVal);\n"
+ );
+ break;
+
+ case enum_type:
+ if (vd->type.u.ed->fqcname != NULL)
+ {
+ prcode(fp,
+" return sipConvertFromEnum(sipVal, sipType_%C);\n"
+ , vd->type.u.ed->fqcname);
+
+ break;
+ }
+
+ /* Drop through. */
+
+ case short_type:
+ case cint_type:
+ case int_type:
+ prcode(fp,
+" return SIPLong_FromLong(sipVal);\n"
+ );
+ break;
+
+ case long_type:
+ prcode(fp,
+" return PyLong_FromLong(sipVal);\n"
+ );
+ break;
+
+ case ushort_type:
+ case uint_type:
+ case ulong_type:
+ prcode(fp,
+" return PyLong_FromUnsignedLong(sipVal);\n"
+ );
+ break;
+
+ case longlong_type:
+ prcode(fp,
+" return PyLong_FromLongLong(sipVal);\n"
+ );
+ break;
+
+ case ulonglong_type:
+ prcode(fp,
+" return PyLong_FromUnsignedLongLong(sipVal);\n"
+ );
+ break;
+
+ case struct_type:
+ case void_type:
+ prcode(fp,
+" return sipConvertFrom%sVoidPtr(sipVal);\n"
+ , (isConstArg(&vd->type) ? "Const" : ""));
+ break;
+
+ case pyobject_type:
+ case pytuple_type:
+ case pylist_type:
+ case pydict_type:
+ case pycallable_type:
+ case pyslice_type:
+ case pytype_type:
+ prcode(fp,
+" Py_XINCREF(sipVal);\n"
+" return sipVal;\n"
+ );
+ break;
+ }
+
+ prcode(fp,
+"}\n"
+ );
+}
+
+
+/*
+ * Generate a variable setter.
+ */
+static void generateVariableSetter(ifaceFileDef *scope, varDef *vd, FILE *fp)
+{
+ argType atype = vd->type.atype;
+ const char *first_arg, *last_arg;
+ char *deref;
+ int might_be_temp, keep;
+
+ keep = keepPyReference(&vd->type);
+
+ if (generating_c || !isStaticVar(vd))
+ first_arg = "sipSelf";
+ else
+ first_arg = "";
+
+ if (generating_c || (!isStaticVar(vd) && keep))
+ last_arg = "sipPySelf";
+ else
+ last_arg = "";
+
+ prcode(fp,
+"\n"
+"\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static int varset_%C(void *, PyObject *, PyObject *);}\n"
+ , vd->fqcname);
+
+ prcode(fp,
+"static int varset_%C(void *%s, PyObject *sipPy, PyObject *%s)\n"
+"{\n"
+ , vd->fqcname, first_arg, last_arg);
+
+ if (vd->setcode == NULL)
+ {
+ prcode(fp,
+" ");
+
+ generateNamedValueType(scope, &vd->type, "sipVal", fp);
+
+ prcode(fp, ";\n"
+ );
+ }
+
+ if (!isStaticVar(vd))
+ {
+ if (generating_c)
+ prcode(fp,
+" %S *sipCpp = (%S *)sipSelf;\n"
+ , classFQCName(vd->ecd), classFQCName(vd->ecd));
+ else
+ prcode(fp,
+" %S *sipCpp = reinterpret_cast<%S *>(sipSelf);\n"
+ , classFQCName(vd->ecd), classFQCName(vd->ecd));
+
+ prcode(fp,
+"\n"
+ );
+ }
+
+ /* Handle any handwritten setter. */
+ if (vd->setcode != NULL)
+ {
+ prcode(fp,
+" int sipErr = 0;\n"
+"\n"
+ );
+
+ generateCppCodeBlock(vd->setcode, fp);
+
+ prcode(fp,
+"\n"
+" return (sipErr ? -1 : 0);\n"
+"}\n"
+ );
+
+ return;
+ }
+
+ if (vd->type.nrderefs == 0 && (atype == mapped_type || (atype == class_type && vd->type.u.cd->convtocode != NULL)))
+ prcode(fp,
+" int sipValState;\n"
+ );
+
+ if (atype == class_type || atype == mapped_type)
+ prcode(fp,
+" int sipIsErr = 0;\n"
+"\n"
+ );
+
+ might_be_temp = generateObjToCppConversion(&vd->type, fp);
+
+ deref = "";
+
+ if (atype == class_type || atype == mapped_type)
+ {
+ if (vd->type.nrderefs == 0)
+ deref = "*";
+
+ prcode(fp,
+"\n"
+" if (sipIsErr)\n"
+" return -1;\n"
+"\n"
+ );
+ }
+ else
+ {
+ prcode(fp,
+"\n"
+" if (PyErr_Occurred() != NULL)\n"
+" return -1;\n"
+"\n"
+ );
+ }
+
+ if (atype == pyobject_type || atype == pytuple_type ||
+ atype == pylist_type || atype == pydict_type ||
+ atype == pycallable_type || atype == pyslice_type ||
+ atype == pytype_type)
+ {
+ prcode(fp,
+" Py_XDECREF(");
+
+ generateVarMember(vd, fp);
+
+ prcode(fp, ");\n"
+" Py_INCREF(sipVal);\n"
+"\n"
+ );
+ }
+
+ prcode(fp,
+" ");
+
+ generateVarMember(vd, fp);
+
+ prcode(fp, " = %ssipVal;\n"
+ , deref);
+
+ /* Note that wchar_t * leaks here. */
+
+ if (might_be_temp)
+ prcode(fp,
+"\n"
+" sipReleaseType(sipVal, sipType_%C, sipValState);\n"
+ , classFQCName(vd->type.u.cd));
+ else if (vd->type.atype == mapped_type && vd->type.nrderefs == 0 && !noRelease(vd->type.u.mtd))
+ prcode(fp,
+"\n"
+" sipReleaseType(sipVal, sipType_%T, sipValState);\n"
+ , &vd->type);
+
+ /* Generate the code to keep the object alive while we use its data. */
+ if (keep)
+ {
+ if (isStaticVar(vd))
+ {
+ prcode(fp,
+"\n"
+" static PyObject *sipKeep = 0;\n"
+"\n"
+" Py_XDECREF(sipKeep);\n"
+" sipKeep = sipPy;\n"
+" Py_INCREF(sipKeep);\n"
+ );
+ }
+ else
+ {
+ vd->type.key = scope->module->next_key++;
+
+ prcode(fp,
+"\n"
+" sipKeepReference(sipPySelf, %d, sipPy);\n"
+ , vd->type.key);
+ }
+ }
+
+ prcode(fp,
+"\n"
+" return 0;\n"
+"}\n"
+ );
+}
+
+
+/*
+ * Generate the member variable of a class.
+ */
+static void generateVarMember(varDef *vd, FILE *fp)
+{
+ if (isStaticVar(vd))
+ prcode(fp,"%S::",classFQCName(vd->ecd));
+ else
+ prcode(fp,"sipCpp->");
+
+ prcode(fp, "%s", scopedNameTail(vd->fqcname));
+}
+
+
+/*
+ * Generate the declaration of a variable that is initialised from a Python
+ * object. Return TRUE if the value might be a temporary on the heap.
+ */
+static int generateObjToCppConversion(argDef *ad,FILE *fp)
+{
+ int might_be_temp = FALSE;
+ char *rhs = NULL;
+
+ prcode(fp,
+" sipVal = ");
+
+ switch (ad->atype)
+ {
+ case mapped_type:
+ {
+ const char *tail;
+
+ if (generating_c)
+ {
+ prcode(fp, "(%b *)", ad);
+ tail = "";
+ }
+ else
+ {
+ prcode(fp, "reinterpret_cast<%b *>(", ad);
+ tail = ")";
+ }
+
+ /* Note that we don't support /Transfer/ but could do. */
+
+ prcode(fp, "sipForceConvertToType(sipPy,sipType_%T,NULL,%s,%s,&sipIsErr)", ad, (ad->nrderefs ? "0" : "SIP_NOT_NONE"), (ad->nrderefs ? "NULL" : "&sipValState"));
+
+ prcode(fp, "%s;\n"
+ , tail);
+ }
+ break;
+
+ case class_type:
+ {
+ const char *tail;
+
+ if (ad->nrderefs == 0 && ad->u.cd->convtocode != NULL)
+ might_be_temp = TRUE;
+
+ if (generating_c)
+ {
+ prcode(fp, "(%b *)", ad);
+ tail = "";
+ }
+ else
+ {
+ prcode(fp, "reinterpret_cast<%b *>(", ad);
+ tail = ")";
+ }
+
+ /*
+ * Note that we don't support /Transfer/ but could do. We could
+ * also support /Constrained/ (so long as we also supported it for
+ * all types).
+ */
+
+ prcode(fp, "sipForceConvertToType(sipPy,sipType_%C,NULL,%s,%s,&sipIsErr)", classFQCName(ad->u.cd), (ad->nrderefs ? "0" : "SIP_NOT_NONE"), (might_be_temp ? "&sipValState" : "NULL"));
+
+ prcode(fp, "%s;\n"
+ , tail);
+ }
+ break;
+
+ case enum_type:
+ prcode(fp, "(%E)SIPLong_AsLong(sipPy);\n"
+ , ad->u.ed);
+ break;
+
+ case sstring_type:
+ if (ad->nrderefs == 0)
+ rhs = "(signed char)sipBytes_AsChar(sipPy)";
+ else if (isConstArg(ad))
+ rhs = "(const signed char *)sipBytes_AsString(sipPy)";
+ else
+ rhs = "(signed char *)sipBytes_AsString(sipPy)";
+ break;
+
+ case ustring_type:
+ if (ad->nrderefs == 0)
+ rhs = "(unsigned char)sipBytes_AsChar(sipPy)";
+ else if (isConstArg(ad))
+ rhs = "(const unsigned char *)sipBytes_AsString(sipPy)";
+ else
+ rhs = "(unsigned char *)sipBytes_AsString(sipPy)";
+ break;
+
+ case ascii_string_type:
+ if (ad->nrderefs == 0)
+ rhs = "sipString_AsASCIIChar(sipPy)";
+ else if (isConstArg(ad))
+ rhs = "sipString_AsASCIIString(&sipPy)";
+ else
+ rhs = "(char *)sipString_AsASCIIString(&sipPy)";
+ break;
+
+ case latin1_string_type:
+ if (ad->nrderefs == 0)
+ rhs = "sipString_AsLatin1Char(sipPy)";
+ else if (isConstArg(ad))
+ rhs = "sipString_AsLatin1String(&sipPy)";
+ else
+ rhs = "(char *)sipString_AsLatin1String(&sipPy)";
+ break;
+
+ case utf8_string_type:
+ if (ad->nrderefs == 0)
+ rhs = "sipString_AsUTF8Char(sipPy)";
+ else if (isConstArg(ad))
+ rhs = "sipString_AsUTF8String(&sipPy)";
+ else
+ rhs = "(char *)sipString_AsUTF8String(&sipPy)";
+ break;
+
+ case string_type:
+ if (ad->nrderefs == 0)
+ rhs = "sipBytes_AsChar(sipPy)";
+ else if (isConstArg(ad))
+ rhs = "sipBytes_AsString(sipPy)";
+ else
+ rhs = "(const *)sipBytes_AsString(sipPy)";
+ break;
+
+ case wstring_type:
+ if (ad->nrderefs == 0)
+ rhs = "sipUnicode_AsWChar(sipPy)";
+ else
+ rhs = "sipUnicode_AsWString(sipPy)";
+ break;
+
+ case float_type:
+ case cfloat_type:
+ rhs = "(float)PyFloat_AsDouble(sipPy)";
+ break;
+
+ case double_type:
+ case cdouble_type:
+ rhs = "PyFloat_AsDouble(sipPy)";
+ break;
+
+ case bool_type:
+ case cbool_type:
+ rhs = "(bool)SIPLong_AsLong(sipPy)";
+ break;
+
+ case ushort_type:
+ rhs = "(unsigned short)sipLong_AsUnsignedLong(sipPy)";
+ break;
+
+ case short_type:
+ rhs = "(short)SIPLong_AsLong(sipPy)";
+ break;
+
+ case uint_type:
+ rhs = "(unsigned)sipLong_AsUnsignedLong(sipPy)";
+ break;
+
+ case int_type:
+ case cint_type:
+ rhs = "(int)SIPLong_AsLong(sipPy)";
+ break;
+
+ case ulong_type:
+ rhs = "sipLong_AsUnsignedLong(sipPy)";
+ break;
+
+ case long_type:
+ rhs = "PyLong_AsLong(sipPy)";
+ break;
+
+ case ulonglong_type:
+ rhs = "PyLong_AsUnsignedLongLong(sipPy)";
+ break;
+
+ case longlong_type:
+ rhs = "PyLong_AsLongLong(sipPy)";
+ break;
+
+ case struct_type:
+ prcode(fp, "(struct %S *)sipConvertToVoidPtr(sipPy);\n"
+ , ad->u.sname);
+ break;
+
+ case void_type:
+ rhs = "sipConvertToVoidPtr(sipPy)";
+ break;
+
+ case pyobject_type:
+ case pytuple_type:
+ case pylist_type:
+ case pydict_type:
+ case pycallable_type:
+ case pyslice_type:
+ case pytype_type:
+ rhs = "sipPy";
+ break;
+ }
+
+ if (rhs != NULL)
+ prcode(fp, "%s;\n"
+ , rhs);
+
+ return might_be_temp;
+}
+
+
+/*
+ * Returns TRUE if the given method is a slot that takes zero arguments.
+ */
+static int isZeroArgSlot(memberDef *md)
+{
+ slotType st = md->slot;
+
+ return (st == str_slot || st == int_slot || st == long_slot ||
+ st == float_slot || st == invert_slot || st == neg_slot ||
+ st == len_slot || st == bool_slot || st == pos_slot ||
+ st == abs_slot || st == repr_slot || st == hash_slot ||
+ st == index_slot || st == iter_slot || st == next_slot);
+}
+
+
+/*
+ * Returns TRUE if the given method is a slot that takes more than one
+ * argument.
+ */
+static int isMultiArgSlot(memberDef *md)
+{
+ slotType st = md->slot;
+
+ return (st == setitem_slot || st == call_slot);
+}
+
+
+/*
+ * Returns TRUE if the given method is a slot that returns void (ie. nothing
+ * other than an error indicator).
+ */
+int isVoidReturnSlot(memberDef *md)
+{
+ slotType st = md->slot;
+
+ return (st == setitem_slot || st == delitem_slot);
+}
+
+
+/*
+ * Returns TRUE if the given method is a slot that returns int.
+ */
+int isIntReturnSlot(memberDef *md)
+{
+ slotType st = md->slot;
+
+ return (st == bool_slot || st == contains_slot || st == cmp_slot);
+}
+
+
+/*
+ * Returns TRUE if the given method is a slot that returns SIP_SSIZE_T.
+ */
+int isSSizeReturnSlot(memberDef *md)
+{
+ slotType st = md->slot;
+
+ return (st == len_slot);
+}
+
+
+/*
+ * Returns TRUE if the given method is a slot that returns long.
+ */
+int isLongReturnSlot(memberDef *md)
+{
+ slotType st = md->slot;
+
+ return (st == hash_slot);
+}
+
+
+/*
+ * Returns TRUE if the given method is a slot that takes an int argument.
+ */
+static int isIntArgSlot(memberDef *md)
+{
+ slotType st = md->slot;
+
+ return (st == repeat_slot || st == irepeat_slot);
+}
+
+
+/*
+ * Returns TRUE if the given method is an inplace number slot.
+ */
+static int isInplaceNumberSlot(memberDef *md)
+{
+ slotType st = md->slot;
+
+ return (st == iadd_slot || st == isub_slot || st == imul_slot ||
+ st == idiv_slot || st == imod_slot || st == ifloordiv_slot ||
+ st == itruediv_slot || st == ior_slot || st == ixor_slot ||
+ st == iand_slot || st == ilshift_slot || st == irshift_slot);
+}
+
+
+/*
+ * Returns TRUE if the given method is an inplace sequence slot.
+ */
+static int isInplaceSequenceSlot(memberDef *md)
+{
+ slotType st = md->slot;
+
+ return (st == iconcat_slot || st == irepeat_slot);
+}
+
+
+/*
+ * Returns TRUE if the given method is a number slot.
+ */
+int isNumberSlot(memberDef *md)
+{
+ slotType st = md->slot;
+
+ return (st == add_slot || st == sub_slot || st == mul_slot ||
+ st == div_slot || st == mod_slot || st == floordiv_slot ||
+ st == truediv_slot || st == and_slot || st == or_slot ||
+ st == xor_slot || st == lshift_slot || st == rshift_slot);
+}
+
+
+/*
+ * Returns TRUE if the given method is a rich compare slot.
+ */
+int isRichCompareSlot(memberDef *md)
+{
+ slotType st = md->slot;
+
+ return (st == lt_slot || st == le_slot || st == eq_slot ||
+ st == ne_slot || st == gt_slot || st == ge_slot);
+}
+
+
+/*
+ * Generate a Python slot handler for either a class, an enum or an extender.
+ */
+static void generateSlot(moduleDef *mod, classDef *cd, enumDef *ed,
+ memberDef *md, FILE *fp)
+{
+ char *arg_str, *prefix, *ret_type;
+ int ret_int, nr_args;
+ overDef *od, *overs;
+ scopedNameDef *fqcname;
+ nameDef *pyname;
+
+ if (ed != NULL)
+ {
+ prefix = "Type";
+ pyname = ed->pyname;
+ fqcname = ed->fqcname;
+ overs = ed->overs;
+ }
+ else if (cd != NULL)
+ {
+ prefix = "Type";
+ pyname = cd->pyname;
+ fqcname = classFQCName(cd);
+ overs = cd->overs;
+ }
+ else
+ {
+ prefix = NULL;
+ pyname = NULL;
+ fqcname = NULL;
+ overs = mod->overs;
+ }
+
+ if (isVoidReturnSlot(md) || isIntReturnSlot(md))
+ {
+ ret_int = TRUE;
+ ret_type = "int ";
+ }
+ else
+ {
+ ret_int = FALSE;
+
+ if (isSSizeReturnSlot(md))
+ ret_type = "SIP_SSIZE_T ";
+ else if (isLongReturnSlot(md))
+ ret_type = "long ";
+ else
+ ret_type = "PyObject *";
+ }
+
+ if (isIntArgSlot(md))
+ {
+ nr_args = 0;
+ arg_str = "PyObject *sipSelf,int a0";
+ }
+ else if (isMultiArgSlot(md))
+ {
+ nr_args = 2;
+ arg_str = "PyObject *sipSelf,PyObject *sipArgs";
+ }
+ else if (isZeroArgSlot(md))
+ {
+ nr_args = 0;
+ arg_str = "PyObject *sipSelf";
+ }
+ else if (isNumberSlot(md))
+ {
+ nr_args = 2;
+ arg_str = "PyObject *sipArg0,PyObject *sipArg1";
+ }
+ else
+ {
+ nr_args = 1;
+ arg_str = "PyObject *sipSelf,PyObject *sipArg";
+ }
+
+ prcode(fp,
+"\n"
+"\n"
+ );
+
+ if (py2OnlySlot(md->slot))
+ prcode(fp,
+"#if PY_MAJOR_VERSION < 3\n"
+ );
+ else if (py2_5LaterSlot(md->slot))
+ prcode(fp,
+"#if PY_VERSION_HEX >= 0x02050000\n"
+ );
+
+ if (!generating_c)
+ {
+ prcode(fp,
+"extern \"C\" {static %sslot_", ret_type);
+
+ if (cd != NULL)
+ prcode(fp, "%L_", cd->iff);
+ else if (fqcname != NULL)
+ prcode(fp, "%C_", fqcname);
+
+ prcode(fp, "%s(%s);}\n"
+ , md->pyname->text, arg_str);
+ }
+
+ prcode(fp,
+"static %sslot_", ret_type);
+
+ if (cd != NULL)
+ prcode(fp, "%L_", cd->iff);
+ else if (fqcname != NULL)
+ prcode(fp, "%C_", fqcname);
+
+ prcode(fp, "%s(%s)\n"
+"{\n"
+ , md->pyname->text, arg_str);
+
+ if (isInplaceNumberSlot(md))
+ prcode(fp,
+" if (!PyObject_TypeCheck(sipSelf, sipTypeAsPyTypeObject(sip%s_%C)))\n"
+" {\n"
+" Py_INCREF(Py_NotImplemented);\n"
+" return Py_NotImplemented;\n"
+" }\n"
+"\n"
+ , prefix, fqcname);
+
+ if (!isNumberSlot(md))
+ {
+ if (cd != NULL)
+ prcode(fp,
+" %S *sipCpp = reinterpret_cast<%S *>(sipGetCppPtr((sipSimpleWrapper *)sipSelf,sipType_%C));\n"
+"\n"
+" if (!sipCpp)\n"
+" return %s;\n"
+"\n"
+ , fqcname, fqcname, fqcname
+ , (md->slot == cmp_slot ? "-2" : (ret_int ? "-1" : "0")));
+ else
+ prcode(fp,
+" %S sipCpp = static_cast<%S>(SIPLong_AsLong(sipSelf));\n"
+"\n"
+ , fqcname, fqcname);
+ }
+
+ if (nr_args > 0)
+ prcode(fp,
+" PyObject *sipParseErr = NULL;\n"
+ );
+
+ for (od = overs; od != NULL; od = od->next)
+ if (od->common == md && isAbstract(od))
+ {
+ prcode(fp,
+" PyObject *sipOrigSelf = sipSelf;\n"
+ );
+
+ break;
+ }
+
+ for (od = overs; od != NULL; od = od->next)
+ if (od->common == md)
+ generateFunctionBody(od, cd, NULL, cd, (ed == NULL && !dontDerefSelf(od)), mod, fp);
+
+ if (nr_args > 0)
+ {
+ switch (md->slot)
+ {
+ case cmp_slot:
+ prcode(fp,
+"\n"
+" return 2;\n"
+ );
+ break;
+
+ case concat_slot:
+ case iconcat_slot:
+ case repeat_slot:
+ case irepeat_slot:
+ prcode(fp,
+"\n"
+" /* Raise an exception if the argument couldn't be parsed. */\n"
+" sipBadOperatorArg(sipSelf,sipArg,%s);\n"
+"\n"
+" return NULL;\n"
+ ,slotName(md->slot));
+ break;
+
+ default:
+ if (isNumberSlot(md) || isRichCompareSlot(md) || isInplaceNumberSlot(md))
+ {
+ prcode(fp,
+"\n"
+" Py_XDECREF(sipParseErr);\n"
+"\n"
+" if (sipParseErr == Py_None)\n"
+" return NULL;\n"
+ );
+ }
+
+ if (isNumberSlot(md) || isRichCompareSlot(md))
+ {
+ /* We can't extend enum slots. */
+ if (cd == NULL)
+ prcode(fp,
+"\n"
+" Py_INCREF(Py_NotImplemented);\n"
+" return Py_NotImplemented;\n"
+ );
+ else if (isNumberSlot(md))
+ prcode(fp,
+"\n"
+" return sipPySlotExtend(&sipModuleAPI_%s,%s,NULL,sipArg0,sipArg1);\n"
+ , mod->name, slotName(md->slot));
+ else
+ prcode(fp,
+"\n"
+" return sipPySlotExtend(&sipModuleAPI_%s,%s,sipType_%C,sipSelf,sipArg);\n"
+ , mod->name, slotName(md->slot), fqcname);
+ }
+ else if (isInplaceNumberSlot(md))
+ {
+ prcode(fp,
+"\n"
+" PyErr_Clear();\n"
+"\n"
+" Py_INCREF(Py_NotImplemented);\n"
+" return Py_NotImplemented;\n"
+ );
+ }
+ else
+ {
+ prcode(fp,
+"\n"
+" /* Raise an exception if the arguments couldn't be parsed. */\n"
+" sipNoMethod(sipParseErr, %N, %N, NULL);\n"
+"\n"
+" return %s;\n"
+ , pyname, md->pyname
+ ,ret_int ? "-1" : "0");
+ }
+ }
+ }
+
+ prcode(fp,
+"}\n"
+ );
+
+ if (py2OnlySlot(md->slot) || py2_5LaterSlot(md->slot))
+ prcode(fp,
+"#endif\n"
+ );
+}
+
+
+/*
+ * Generate the member functions for a class.
+ */
+static void generateClassFunctions(sipSpec *pt, moduleDef *mod, classDef *cd,
+ FILE *fp)
+{
+ visibleList *vl;
+ memberDef *md;
+
+ /* Any shadow code. */
+ if (hasShadow(cd))
+ {
+ generateShadowClassDeclaration(pt, cd, fp);
+ generateShadowCode(pt, mod, cd, fp);
+ }
+
+ /* The member functions. */
+ for (vl = cd->visible; vl != NULL; vl = vl->next)
+ if (vl->m->slot == no_slot)
+ generateFunction(pt, vl->m, vl->cd->overs, cd, vl->cd, mod, fp);
+
+ /* The slot functions. */
+ for (md = cd->members; md != NULL; md = md->next)
+ if (cd->iff->type == namespace_iface)
+ generateOrdinaryFunction(pt, mod, cd, NULL, md, fp);
+ else if (md->slot != no_slot && md->slot != unicode_slot)
+ generateSlot(mod, cd, NULL, md, fp);
+
+ if (cd->iff->type != namespace_iface && !generating_c)
+ {
+ classList *cl;
+ int need_ptr, need_cast_ptr, need_state;
+
+ /* The cast function. */
+ prcode(fp,
+"\n"
+"\n"
+"/* Cast a pointer to a type somewhere in its superclass hierarchy. */\n"
+"extern \"C\" {static void *cast_%L(void *, const sipTypeDef *);}\n"
+"static void *cast_%L(void *ptr, const sipTypeDef *targetType)\n"
+"{\n"
+ , cd->iff
+ , cd->iff);
+
+ if (cd->supers != NULL)
+ prcode(fp,
+" void *res;\n"
+"\n"
+ );
+
+ prcode(fp,
+" if (targetType == sipType_%C)\n"
+" return ptr;\n"
+ ,classFQCName(cd));
+
+ for (cl = cd->supers; cl != NULL; cl = cl->next)
+ {
+ scopedNameDef *sname = cl->cd->iff->fqcname;
+
+ prcode(fp,
+"\n"
+" if ((res = ((const sipClassTypeDef *)sipType_%C)->ctd_cast((%S *)(%S *)ptr,targetType)) != NULL)\n"
+" return res;\n"
+ ,sname,sname,classFQCName(cd));
+ }
+
+ prcode(fp,
+"\n"
+" return NULL;\n"
+"}\n"
+ );
+
+ /* Generate the release function without compiler warnings. */
+ need_ptr = need_cast_ptr = need_state = FALSE;
+
+ if (cd->dealloccode != NULL)
+ need_ptr = need_cast_ptr = usedInCode(cd->dealloccode, "sipCpp");
+
+ if (canCreate(cd) || isPublicDtor(cd))
+ {
+ if (hasShadow(cd))
+ need_ptr = need_state = TRUE;
+ else if (isPublicDtor(cd))
+ need_ptr = TRUE;
+ }
+
+ prcode(fp,
+"\n"
+"\n"
+"/* Call the instance's destructor. */\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static void release_%L(void *, int);}\n"
+ , cd->iff);
+
+ prcode(fp,
+"static void release_%L(void *%s,int%s)\n"
+"{\n"
+ , cd->iff, (need_ptr ? "sipCppV" : ""), (need_state ? " sipState" : ""));
+
+ if (cd->dealloccode != NULL)
+ {
+ if (need_cast_ptr)
+ {
+ prcode(fp,
+" ");
+
+ generateClassFromVoid(cd, "sipCpp", "sipCppV", fp);
+
+ prcode(fp, ";\n"
+"\n"
+ );
+ }
+
+ generateCppCodeBlock(cd->dealloccode, fp);
+
+ prcode(fp,
+"\n"
+ );
+ }
+
+ if (canCreate(cd) || isPublicDtor(cd))
+ {
+ int rgil = ((release_gil || isReleaseGILDtor(cd)) && !isHoldGILDtor(cd));
+
+ /*
+ * If there is an explicit public dtor then assume there is some
+ * way to call it which we haven't worked out (because we don't
+ * fully understand C++).
+ */
+
+ if (rgil)
+ prcode(fp,
+" Py_BEGIN_ALLOW_THREADS\n"
+"\n"
+ );
+
+ if (hasShadow(cd))
+ {
+ prcode(fp,
+" if (sipState & SIP_DERIVED_CLASS)\n"
+" delete reinterpret_cast<sip%C *>(sipCppV);\n"
+ , classFQCName(cd));
+
+ if (isPublicDtor(cd))
+ prcode(fp,
+" else\n"
+" delete reinterpret_cast<%U *>(sipCppV);\n"
+ , cd);
+ }
+ else if (isPublicDtor(cd))
+ prcode(fp,
+" delete reinterpret_cast<%U *>(sipCppV);\n"
+ , cd);
+
+ if (rgil)
+ prcode(fp,
+"\n"
+" Py_END_ALLOW_THREADS\n"
+ );
+ }
+
+ prcode(fp,
+"}\n"
+ );
+ }
+
+ /* The traverse function. */
+ if (cd->travcode != NULL)
+ {
+ prcode(fp,
+"\n"
+"\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static int traverse_%C(void *, visitproc, void *);}\n"
+ , classFQCName(cd));
+
+ prcode(fp,
+"static int traverse_%C(void *sipCppV,visitproc sipVisit,void *sipArg)\n"
+"{\n"
+" ", classFQCName(cd));
+
+ generateClassFromVoid(cd, "sipCpp", "sipCppV", fp);
+
+ prcode(fp, ";\n"
+" int sipRes;\n"
+"\n"
+ );
+
+ generateCppCodeBlock(cd->travcode, fp);
+
+ prcode(fp,
+"\n"
+" return sipRes;\n"
+"}\n"
+ );
+ }
+
+ /* The clear function. */
+ if (cd->clearcode != NULL)
+ {
+ prcode(fp,
+"\n"
+"\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static int clear_%C(void *);}\n"
+ , classFQCName(cd));
+
+ prcode(fp,
+"static int clear_%C(void *sipCppV)\n"
+"{\n"
+" ", classFQCName(cd));
+
+ generateClassFromVoid(cd, "sipCpp", "sipCppV", fp);
+
+ prcode(fp, ";\n"
+" int sipRes;\n"
+"\n"
+ );
+
+ generateCppCodeBlock(cd->clearcode, fp);
+
+ prcode(fp,
+"\n"
+" return sipRes;\n"
+"}\n"
+ );
+ }
+
+ /* The buffer interface functions. */
+ if (cd->getbufcode != NULL)
+ {
+ int need_cpp = usedInCode(cd->getbufcode, "sipCpp");
+
+ prcode(fp,
+"\n"
+"\n"
+"#if PY_MAJOR_VERSION >= 3\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static int getbuffer_%C(PyObject *, void *, Py_buffer *, int);}\n"
+ , classFQCName(cd));
+
+ prcode(fp,
+"static int getbuffer_%C(PyObject *%s, void *%s, Py_buffer *sipBuffer, int %s)\n"
+"{\n"
+ , classFQCName(cd), argName("sipSelf", cd->getbufcode), (generating_c || need_cpp ? "sipCppV" : ""), argName("sipFlags", cd->getbufcode));
+
+ if (need_cpp)
+ {
+ prcode(fp, " ");
+ generateClassFromVoid(cd, "sipCpp", "sipCppV", fp);
+ prcode(fp, ";\n"
+ );
+ }
+
+ prcode(fp,
+" int sipRes;\n"
+"\n"
+ );
+
+ generateCppCodeBlock(cd->getbufcode, fp);
+
+ prcode(fp,
+"\n"
+" return sipRes;\n"
+"}\n"
+"#endif\n"
+ );
+ }
+
+ if (cd->releasebufcode != NULL)
+ {
+ prcode(fp,
+"\n"
+"\n"
+"#if PY_MAJOR_VERSION >= 3\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static void releasebuffer_%C(PyObject *, void *, Py_buffer *);}\n"
+ , classFQCName(cd));
+
+ prcode(fp,
+"static void releasebuffer_%C(PyObject *%s, void *sipCppV, Py_buffer *)\n"
+"{\n"
+" ", classFQCName(cd)
+ , argName("sipSelf", cd->releasebufcode));
+
+ generateClassFromVoid(cd, "sipCpp", "sipCppV", fp);
+
+ prcode(fp, ";\n"
+"\n"
+ );
+
+ generateCppCodeBlock(cd->releasebufcode, fp);
+
+ prcode(fp,
+"}\n"
+"#endif\n"
+ );
+ }
+
+ if (cd->readbufcode != NULL)
+ {
+ prcode(fp,
+"\n"
+"\n"
+"#if PY_MAJOR_VERSION < 3\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static SIP_SSIZE_T getreadbuffer_%C(PyObject *, void *, SIP_SSIZE_T, void **);}\n"
+ , classFQCName(cd));
+
+ prcode(fp,
+"static SIP_SSIZE_T getreadbuffer_%C(PyObject *%s, void *sipCppV, SIP_SSIZE_T %s, void **%s)\n"
+"{\n"
+" ", classFQCName(cd)
+ , argName("sipSelf", cd->readbufcode)
+ , argName("sipSegment", cd->readbufcode)
+ , argName("sipPtrPtr", cd->readbufcode));
+
+ generateClassFromVoid(cd, "sipCpp", "sipCppV", fp);
+
+ prcode(fp, ";\n"
+" SIP_SSIZE_T sipRes;\n"
+"\n"
+ );
+
+ generateCppCodeBlock(cd->readbufcode, fp);
+
+ prcode(fp,
+"\n"
+" return sipRes;\n"
+"}\n"
+"#endif\n"
+ );
+ }
+
+ if (cd->writebufcode != NULL)
+ {
+ prcode(fp,
+"\n"
+"\n"
+"#if PY_MAJOR_VERSION < 3\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static SIP_SSIZE_T getwritebuffer_%C(PyObject *, void *, SIP_SSIZE_T, void **);}\n"
+ , classFQCName(cd));
+
+ prcode(fp,
+"static SIP_SSIZE_T getwritebuffer_%C(PyObject *%s, void *sipCppV, SIP_SSIZE_T %s, void **%s)\n"
+"{\n"
+" ", classFQCName(cd)
+ , argName("sipSelf", cd->writebufcode)
+ , argName("sipSegment", cd->writebufcode)
+ , argName("sipPtrPtr", cd->writebufcode));
+
+ generateClassFromVoid(cd, "sipCpp", "sipCppV", fp);
+
+ prcode(fp, ";\n"
+" SIP_SSIZE_T sipRes;\n"
+"\n"
+ );
+
+ generateCppCodeBlock(cd->writebufcode, fp);
+
+ prcode(fp,
+"\n"
+" return sipRes;\n"
+"}\n"
+"#endif\n"
+ );
+ }
+
+ if (cd->segcountcode != NULL)
+ {
+ prcode(fp,
+"\n"
+"\n"
+"#if PY_MAJOR_VERSION < 3\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static SIP_SSIZE_T getsegcount_%C(PyObject *, void *, SIP_SSIZE_T *);}\n"
+ , classFQCName(cd));
+
+ prcode(fp,
+"static SIP_SSIZE_T getsegcount_%C(PyObject *%s, void *sipCppV, SIP_SSIZE_T *%s)\n"
+"{\n"
+" ", classFQCName(cd)
+ , argName("sipSelf", cd->segcountcode)
+ , argName("sipLenPtr", cd->segcountcode));
+
+ generateClassFromVoid(cd, "sipCpp", "sipCppV", fp);
+
+ prcode(fp, ";\n"
+" SIP_SSIZE_T sipRes;\n"
+"\n"
+ );
+
+ generateCppCodeBlock(cd->segcountcode, fp);
+
+ prcode(fp,
+"\n"
+" return sipRes;\n"
+"}\n"
+"#endif\n"
+ );
+ }
+
+ if (cd->charbufcode != NULL)
+ {
+ prcode(fp,
+"\n"
+"\n"
+"#if PY_MAJOR_VERSION < 3\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static SIP_SSIZE_T getcharbuffer_%C(PyObject *, void *, SIP_SSIZE_T, void **);}\n"
+ , classFQCName(cd));
+
+ prcode(fp,
+"static SIP_SSIZE_T getcharbuffer_%C(PyObject *%s, void *sipCppV, SIP_SSIZE_T %s, void **%s)\n"
+"{\n"
+" ", classFQCName(cd)
+ , argName("sipSelf", cd->charbufcode)
+ , argName("sipSegment", cd->charbufcode)
+ , argName("sipPtrPtr", cd->charbufcode));
+
+ generateClassFromVoid(cd, "sipCpp", "sipCppV", fp);
+
+ prcode(fp, ";\n"
+" SIP_SSIZE_T sipRes;\n"
+"\n"
+ );
+
+ generateCppCodeBlock(cd->charbufcode, fp);
+
+ prcode(fp,
+"\n"
+" return sipRes;\n"
+"}\n"
+"#endif\n"
+ );
+ }
+
+ /* The pickle function. */
+ if (cd->picklecode != NULL)
+ {
+ prcode(fp,
+"\n"
+"\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static PyObject *pickle_%C(void *);}\n"
+ , classFQCName(cd));
+
+ prcode(fp,
+"static PyObject *pickle_%C(void *sipCppV)\n"
+"{\n"
+" ", classFQCName(cd));
+
+ generateClassFromVoid(cd, "sipCpp", "sipCppV", fp);
+
+ prcode(fp, ";\n"
+" PyObject *sipRes;\n"
+"\n"
+ );
+
+ generateCppCodeBlock(cd->picklecode, fp);
+
+ prcode(fp,
+"\n"
+" return sipRes;\n"
+"}\n"
+ );
+ }
+
+ if (generating_c || assignmentHelper(cd))
+ {
+ /* The assignment helper. */
+ prcode(fp,
+"\n"
+"\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static void assign_%L(void *, SIP_SSIZE_T, const void *);}\n"
+ , cd->iff);
+
+ prcode(fp,
+"static void assign_%L(void *sipDst, SIP_SSIZE_T sipDstIdx, const void *sipSrc)\n"
+"{\n"
+ , cd->iff);
+
+ if (generating_c)
+ prcode(fp,
+" ((%S *)sipDst)[sipDstIdx] = *((const %S *)sipSrc);\n"
+ , classFQCName(cd), classFQCName(cd));
+ else
+ prcode(fp,
+" reinterpret_cast<%S *>(sipDst)[sipDstIdx] = *reinterpret_cast<const %S *>(sipSrc);\n"
+ , classFQCName(cd), classFQCName(cd));
+
+ prcode(fp,
+"}\n"
+ );
+
+ /* The array allocation helper. */
+ prcode(fp,
+"\n"
+"\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static void *array_%L(SIP_SSIZE_T);}\n"
+ , cd->iff);
+
+ prcode(fp,
+"static void *array_%L(SIP_SSIZE_T sipNrElem)\n"
+"{\n"
+ , cd->iff);
+
+ if (generating_c)
+ prcode(fp,
+" return sipMalloc(sizeof (%S) * sipNrElem);\n"
+ , classFQCName(cd));
+ else
+ prcode(fp,
+" return new %S[sipNrElem];\n"
+ , classFQCName(cd));
+
+ prcode(fp,
+"}\n"
+ );
+
+ /* The copy helper. */
+ prcode(fp,
+"\n"
+"\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static void *copy_%L(const void *, SIP_SSIZE_T);}\n"
+ , cd->iff);
+
+ prcode(fp,
+"static void *copy_%L(const void *sipSrc, SIP_SSIZE_T sipSrcIdx)\n"
+"{\n"
+ , cd->iff);
+
+ if (generating_c)
+ prcode(fp,
+" %S *sipPtr = sipMalloc(sizeof (%S));\n"
+" *sipPtr = ((const %S *)sipSrc)[sipSrcIdx];\n"
+"\n"
+" return sipPtr;\n"
+ , classFQCName(cd), classFQCName(cd)
+ , classFQCName(cd));
+ else
+ prcode(fp,
+" return new %S(reinterpret_cast<const %S *>(sipSrc)[sipSrcIdx]);\n"
+ , classFQCName(cd), classFQCName(cd));
+
+ prcode(fp,
+"}\n"
+ );
+ }
+
+ /* The dealloc function. */
+ if (needDealloc(cd))
+ {
+ prcode(fp,
+"\n"
+"\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static void dealloc_%L(sipSimpleWrapper *);}\n"
+ , cd->iff);
+
+ prcode(fp,
+"static void dealloc_%L(sipSimpleWrapper *sipSelf)\n"
+"{\n"
+ , cd->iff);
+
+ if (tracing)
+ prcode(fp,
+" sipTrace(SIP_TRACE_DEALLOCS,\"dealloc_%L()\\n\");\n"
+"\n"
+ , cd->iff);
+
+ /* Disable the virtual handlers. */
+ if (hasShadow(cd))
+ prcode(fp,
+" if (sipIsDerived(sipSelf))\n"
+" reinterpret_cast<sip%C *>(sipSelf->u.cppPtr)->sipPySelf = NULL;\n"
+"\n"
+ ,classFQCName(cd));
+
+ if (generating_c || isPublicDtor(cd) || (hasShadow(cd) && isProtectedDtor(cd)))
+ {
+ prcode(fp,
+" if (sipIsPyOwned(sipSelf))\n"
+" {\n"
+ );
+
+ if (isDelayedDtor(cd))
+ prcode(fp,
+" sipAddDelayedDtor(sipSelf);\n"
+ );
+ else if (generating_c)
+ prcode(fp,
+" sipFree(sipSelf->u.cppPtr);\n"
+ );
+ else
+ prcode(fp,
+" release_%L(sipSelf->u.cppPtr,%s);\n"
+ , cd->iff, (hasShadow(cd) ? "sipSelf->flags" : "0"));
+
+ prcode(fp,
+" }\n"
+ );
+ }
+
+ prcode(fp,
+"}\n"
+ );
+ }
+
+ /* The type initialisation function. */
+ if (canCreate(cd))
+ generateTypeInit(cd, mod, fp);
+}
+
+
+/*
+ * Generate the shadow (derived) class code.
+ */
+static void generateShadowCode(sipSpec *pt, moduleDef *mod, classDef *cd,
+ FILE *fp)
+{
+ int nrVirts, virtNr;
+ virtOverDef *vod;
+ ctorDef *ct;
+
+ nrVirts = countVirtuals(cd);
+
+ /* Generate the wrapper class constructors. */
+
+ for (ct = cd->ctors; ct != NULL; ct = ct->next)
+ {
+ ctorDef *dct;
+
+ if (isPrivateCtor(ct))
+ continue;
+
+ if (ct->cppsig == NULL)
+ continue;
+
+ /* Check we haven't already handled this C++ signature. */
+ for (dct = cd->ctors; dct != ct; dct = dct->next)
+ if (dct->cppsig != NULL && sameSignature(dct->cppsig, ct->cppsig, TRUE))
+ break;
+
+ if (dct != ct)
+ continue;
+
+ prcode(fp,
+"\n"
+"sip%C::sip%C(",classFQCName(cd),classFQCName(cd));
+
+ generateCalledArgs(cd->iff, ct->cppsig, Definition, TRUE, fp);
+
+ prcode(fp,")%X: %S(",ct->exceptions,classFQCName(cd));
+
+ generateProtectedCallArgs(ct->cppsig, fp);
+
+ prcode(fp,"), sipPySelf(0)\n"
+"{\n"
+ );
+
+ if (tracing)
+ {
+ prcode(fp,
+" sipTrace(SIP_TRACE_CTORS,\"sip%C::sip%C(",classFQCName(cd),classFQCName(cd));
+ generateCalledArgs(cd->iff, ct->cppsig, Declaration, TRUE, fp);
+ prcode(fp,")%X (this=0x%%08x)\\n\",this);\n"
+"\n"
+ ,ct->exceptions);
+ }
+
+ if (nrVirts > 0)
+ prcode(fp,
+" memset(sipPyMethods, 0, sizeof (sipPyMethods));\n"
+ );
+
+ prcode(fp,
+"}\n"
+ );
+ }
+
+ /* The destructor. */
+
+ if (!isPrivateDtor(cd))
+ {
+ prcode(fp,
+"\n"
+"sip%C::~sip%C()%X\n"
+"{\n"
+ ,classFQCName(cd),classFQCName(cd),cd->dtorexceptions);
+
+ if (tracing)
+ prcode(fp,
+" sipTrace(SIP_TRACE_DTORS,\"sip%C::~sip%C()%X (this=0x%%08x)\\n\",this);\n"
+"\n"
+ ,classFQCName(cd),classFQCName(cd),cd->dtorexceptions);
+
+ if (cd->dtorcode != NULL)
+ generateCppCodeBlock(cd->dtorcode,fp);
+
+ prcode(fp,
+" sipCommonDtor(sipPySelf);\n"
+"}\n"
+ );
+ }
+
+ /* The meta methods if required. */
+ if (pluginPyQt4(pt) && isQObjectSubClass(cd))
+ {
+ if (!noPyQt4QMetaObject(cd))
+ prcode(fp,
+"\n"
+"const QMetaObject *sip%C::metaObject() const\n"
+"{\n"
+" return sip_%s_qt_metaobject(sipPySelf,sipType_%C);\n"
+"}\n"
+ , classFQCName(cd)
+ , mod->name, classFQCName(cd));
+
+ prcode(fp,
+"\n"
+"int sip%C::qt_metacall(QMetaObject::Call _c,int _id,void **_a)\n"
+"{\n"
+" _id = %S::qt_metacall(_c,_id,_a);\n"
+"\n"
+" if (_id >= 0)\n"
+" _id = sip_%s_qt_metacall(sipPySelf,sipType_%C,_c,_id,_a);\n"
+"\n"
+" return _id;\n"
+"}\n"
+"\n"
+"void *sip%C::qt_metacast(const char *_clname)\n"
+"{\n"
+" return (sip_%s_qt_metacast && sip_%s_qt_metacast(sipPySelf,sipType_%C,_clname)) ? this : %S::qt_metacast(_clname);\n"
+"}\n"
+ , classFQCName(cd)
+ , classFQCName(cd)
+ , mod->name, classFQCName(cd)
+ , classFQCName(cd)
+ , mod->name, mod->name, classFQCName(cd), classFQCName(cd));
+ }
+
+ /* Generate the virtual catchers. */
+
+ virtNr = 0;
+
+ for (vod = cd->vmembers; vod != NULL; vod = vod->next)
+ {
+ overDef *od = &vod->o;
+ virtOverDef *dvod;
+
+ if (isPrivate(od))
+ continue;
+
+ /*
+ * Check we haven't already handled this C++ signature. The same C++
+ * signature should only appear more than once for overloads that are
+ * enabled for different APIs and that differ in their /In/ and/or
+ * /Out/ annotations.
+ */
+ for (dvod = cd->vmembers; dvod != vod; dvod = dvod->next)
+ if (strcmp(dvod->o.cppname, od->cppname) == 0 && sameSignature(dvod->o.cppsig, od->cppsig, TRUE))
+ break;
+
+ if (dvod == vod)
+ generateVirtualCatcher(mod, cd, virtNr++, vod, fp);
+ }
+
+ /* Generate the wrapper around each protected member function. */
+
+ generateProtectedDefinitions(cd,fp);
+
+ /* Generate the emitters if needed. */
+ if (pluginPyQt3(pt))
+ generateEmitters(cd, fp);
+}
+
+
+/*
+ * Generate the emitter functions.
+ */
+static void generateEmitters(classDef *cd, FILE *fp)
+{
+ int noIntro;
+ visibleList *vl;
+
+ for (vl = cd->visible; vl != NULL; vl = vl->next)
+ {
+ overDef *od;
+
+ for (od = vl->cd->overs; od != NULL; od = od->next)
+ if (od->common == vl->m && isSignal(od))
+ {
+ generateEmitter(cd,vl,fp);
+ break;
+ }
+ }
+
+ /* Generate the table of signals to support fan-outs. */
+
+ noIntro = TRUE;
+
+ for (vl = cd->visible; vl != NULL; vl = vl->next)
+ {
+ overDef *od;
+
+ for (od = vl->cd->overs; od != NULL; od = od->next)
+ if (od->common == vl->m && isSignal(od))
+ {
+ if (noIntro)
+ {
+ setHasSigSlots(cd);
+
+ prcode(fp,
+"\n"
+"static pyqt3QtSignal signals_%C[] = {\n"
+ ,classFQCName(cd));
+
+ noIntro = FALSE;
+ }
+
+ prcode(fp,
+" {%N, %C_emit_%s},\n"
+ ,vl->m->pyname,classFQCName(cd),vl->m->pyname->text);
+
+ break;
+ }
+ }
+
+ if (!noIntro)
+ prcode(fp,
+" {NULL, NULL}\n"
+"};\n"
+ );
+}
+
+
+/*
+ * Generate the protected enums for a class.
+ */
+static void generateProtectedEnums(sipSpec *pt,classDef *cd,FILE *fp)
+{
+ enumDef *ed;
+
+ for (ed = pt->enums; ed != NULL; ed = ed->next)
+ {
+ char *eol;
+ mroDef *mro;
+ enumMemberDef *emd;
+
+ if (!isProtectedEnum(ed))
+ continue;
+
+ /* See if the class defining the enum is in our class hierachy. */
+ for (mro = cd->mro; mro != NULL; mro = mro->next)
+ if (mro->cd == ed->ecd)
+ break;
+
+ if (mro == NULL)
+ continue;
+
+ prcode(fp,
+"\n"
+" /* Expose this protected enum. */\n"
+" enum");
+
+ if (ed->fqcname != NULL)
+ prcode(fp," sip%s",scopedNameTail(ed->fqcname));
+
+ prcode(fp," {");
+
+ eol = "\n";
+
+ for (emd = ed->members; emd != NULL; emd = emd->next)
+ {
+ prcode(fp,"%s"
+" %s = %S::%s",eol,emd->cname,classFQCName(ed->ecd),emd->cname);
+
+ eol = ",\n";
+ }
+
+ prcode(fp,"\n"
+" };\n"
+ );
+ }
+}
+
+
+/*
+ * Generate the catcher for a virtual function.
+ */
+static void generateVirtualCatcher(moduleDef *mod, classDef *cd, int virtNr,
+ virtOverDef *vod, FILE *fp)
+{
+ overDef *od = &vod->o;
+ argDef *res;
+ apiVersionRangeDef *avr;
+
+ normaliseArgs(od->cppsig);
+
+ res = &od->cppsig->result;
+
+ if (res->atype == void_type && res->nrderefs == 0)
+ res = NULL;
+
+ prcode(fp,
+"\n");
+
+ generateBaseType(cd->iff, &od->cppsig->result, TRUE, fp);
+
+ prcode(fp," sip%C::%O(",classFQCName(cd),od);
+ generateCalledArgs(cd->iff, od->cppsig, Definition, TRUE, fp);
+ prcode(fp,")%s%X\n"
+"{\n"
+ ,(isConst(od) ? " const" : ""),od->exceptions);
+
+ if (tracing)
+ {
+ prcode(fp,
+" sipTrace(SIP_TRACE_CATCHERS,\"");
+
+ generateBaseType(cd->iff, &od->cppsig->result, TRUE, fp);
+ prcode(fp," sip%C::%O(",classFQCName(cd),od);
+ generateCalledArgs(cd->iff, od->cppsig, Declaration, TRUE, fp);
+ prcode(fp,")%s%X (this=0x%%08x)\\n\",this);\n"
+"\n"
+ ,(isConst(od) ? " const" : ""),od->exceptions);
+ }
+
+ restoreArgs(od->cppsig);
+
+ prcode(fp,
+" sip_gilstate_t sipGILState;\n"
+" PyObject *meth;\n"
+"\n"
+" meth = sipIsPyMethod(&sipGILState,");
+
+ if (isConst(od))
+ prcode(fp, "const_cast<char *>(");
+
+ prcode(fp,"&sipPyMethods[%d]",virtNr);
+
+ if (isConst(od))
+ prcode(fp,")");
+
+ prcode(fp,",sipPySelf,");
+
+ if (isAbstract(od))
+ prcode(fp, "%N", cd->pyname);
+ else
+ prcode(fp,"NULL");
+
+ prcode(fp,",%N);\n"
+"\n"
+ ,od->common->pyname);
+
+ prcode(fp,
+" if (!meth)\n"
+ );
+
+ if (isAbstract(od))
+ generateVirtHandlerErrorReturn(res, " ", fp);
+ else
+ {
+ int a;
+
+ if (res == NULL)
+ prcode(fp,
+" {\n"
+" ");
+ else
+ prcode(fp,
+" return ");
+
+ generateUnambiguousClass(cd,vod->scope,fp);
+
+ prcode(fp,"::%O(",od);
+
+ for (a = 0; a < od->cppsig->nrArgs; ++a)
+ prcode(fp,"%sa%d",(a == 0 ? "" : ","),a);
+
+ prcode(fp,");\n"
+ );
+
+ if (res == NULL)
+ prcode(fp,
+" return;\n"
+" }\n"
+ );
+ }
+
+ /*
+ * If this overload doesn't have an API version assume that there are none
+ * that do.
+ */
+ avr = od->api_range;
+
+ if (avr == NULL)
+ {
+ prcode(fp,
+"\n"
+ );
+
+ generateVirtHandlerCall(mod, cd, vod, res, " ", fp);
+ }
+ else
+ {
+ virtOverDef *versioned_vod = vod;
+
+ do
+ {
+ prcode(fp,
+"\n"
+" if (sipIsAPIEnabled(%N, %d, %d))\n"
+" {\n"
+ , avr->api_name, avr->from, avr->to);
+
+ generateVirtHandlerCall(mod, cd, versioned_vod, res, " ", fp);
+
+ if (res == NULL)
+ prcode(fp,
+" return;\n"
+ );
+
+ prcode(fp,
+" }\n"
+ );
+
+ /* Find the next overload. */
+ while ((versioned_vod = versioned_vod->next) != NULL)
+ {
+ if (strcmp(versioned_vod->o.cppname, od->cppname) == 0 && sameSignature(versioned_vod->o.cppsig, od->cppsig, TRUE))
+ {
+ avr = versioned_vod->o.api_range;
+
+ /* Check that it has an API specified. */
+ if (avr == NULL)
+ {
+ fatalScopedName(classFQCName(cd));
+ fatal("::");
+ prOverloadName(stderr, od);
+ fatal(" has versioned and unversioned overloads\n");
+ }
+
+ break;
+ }
+ }
+ }
+ while (versioned_vod != NULL);
+
+ prcode(fp,
+"\n"
+ );
+
+ if (isAbstract(od))
+ generateVirtHandlerErrorReturn(res, " ", fp);
+ else
+ {
+ int a;
+
+ prcode(fp, " %s", (res != NULL ? "return " : ""));
+
+ generateUnambiguousClass(cd, vod->scope, fp);
+
+ prcode(fp, "::%O(", od);
+
+ for (a = 0; a < od->cppsig->nrArgs; ++a)
+ prcode(fp, "%sa%d", (a == 0 ? "" : ","), a);
+
+ prcode(fp,");\n"
+ );
+ }
+ }
+
+ prcode(fp,
+"}\n"
+ );
+}
+
+
+/*
+ * Generate a call to a single virtual handler.
+ */
+static void generateVirtHandlerCall(moduleDef *mod, classDef *cd,
+ virtOverDef *vod, argDef *res, const char *indent, FILE *fp)
+{
+ overDef *od = &vod->o;
+ virtHandlerDef *vhd = od->virthandler;
+ signatureDef saved;
+ argDef *ad;
+ int a, args_keep = FALSE, result_keep = FALSE;
+
+ if (isNewThread(od))
+ prcode(fp,
+"%ssipStartThread();\n"
+"\n"
+ , indent);
+
+ saved = *vhd->cppsig;
+ fakeProtectedArgs(vhd->cppsig);
+
+ if (vhd->module == mod)
+ {
+ prcode(fp,
+"%sextern ", indent);
+
+ generateBaseType(cd->iff, &od->cppsig->result, FALSE, fp);
+
+ prcode(fp, " sipVH_%s_%d(sip_gilstate_t,PyObject *", vhd->module->name, vhd->virthandlernr);
+ }
+ else
+ {
+ prcode(fp,
+"%stypedef ", indent);
+
+ generateBaseType(cd->iff, &od->cppsig->result, FALSE, fp);
+
+ prcode(fp, " (*sipVH_%s_%d)(sip_gilstate_t,PyObject *", vhd->module->name, vhd->virthandlernr);
+ }
+
+ if (vhd->cppsig->nrArgs > 0)
+ {
+ prcode(fp, ",");
+ generateCalledArgs(cd->iff, vhd->cppsig, Declaration, FALSE, fp);
+ }
+
+ *vhd->cppsig = saved;
+
+ /* Add extra arguments for all the references we need to keep. */
+ if (res != NULL && keepPyReference(res))
+ {
+ result_keep = TRUE;
+ res->key = mod->next_key++;
+ prcode(fp, ",int");
+ }
+
+ for (ad = od->cppsig->args, a = 0; a < od->cppsig->nrArgs; ++a, ++ad)
+ if (isOutArg(ad) && keepPyReference(ad))
+ {
+ args_keep = TRUE;
+ ad->key = mod->next_key++;
+ prcode(fp, ",int");
+ }
+
+ if (result_keep || args_keep)
+ prcode(fp, ",sipSimpleWrapper *");
+
+ prcode(fp,");\n"
+"\n"
+"%s", indent);
+
+ if (!isNewThread(od) && res != NULL)
+ prcode(fp, "return ");
+
+ if (vhd->module == mod)
+ prcode(fp, "sipVH_%s_%d", vhd->module->name,vhd->virthandlernr);
+ else
+ prcode(fp, "((sipVH_%s_%d)(sipModuleAPI_%s_%s->em_virthandlers[%d]))", vhd->module->name, vhd->virthandlernr, mod->name, vhd->module->name, vhd->virthandlernr);
+
+ prcode(fp,"(sipGILState,meth");
+
+ for (ad = od->cppsig->args, a = 0; a < od->cppsig->nrArgs; ++a, ++ad)
+ {
+ if (ad->atype == class_type && isProtectedClass(ad->u.cd))
+ prcode(fp, ",%sa%d", ((isReference(ad) || ad->nrderefs == 0) ? "&" : ""), a);
+ else if (ad->atype == enum_type && isProtectedEnum(ad->u.ed))
+ prcode(fp, ",(%E)a%d", ad->u.ed, a);
+ else
+ prcode(fp,",a%d",a);
+ }
+
+ /* Pass the keys to maintain the kept references. */
+ if (result_keep)
+ prcode(fp, ",%d", res->key);
+
+ if (args_keep)
+ for (ad = od->cppsig->args, a = 0; a < od->cppsig->nrArgs; ++a, ++ad)
+ if (isOutArg(ad) && keepPyReference(ad))
+ prcode(fp, ",%d", ad->key);
+
+ if (result_keep || args_keep)
+ prcode(fp, ",sipPySelf");
+
+ prcode(fp,");\n"
+ );
+
+ if (isNewThread(od))
+ prcode(fp,
+"\n"
+"%sSIP_BLOCK_THREADS\n"
+"%ssipEndThread();\n"
+"%sSIP_UNBLOCK_THREADS\n"
+ , indent
+ , indent
+ , indent);
+
+}
+
+
+/*
+ * Generate the scope of the near class of a virtual taking duplicate
+ * super-classes into account.
+ */
+static void generateUnambiguousClass(classDef *cd,classDef *scope,FILE *fp)
+{
+ mroDef *mro;
+
+ /* See if the near class has a duplicate. */
+ for (mro = cd->mro; mro != NULL; mro = mro->next)
+ if (mro->cd == scope)
+ {
+ if (hasDuplicateSuper(mro))
+ {
+ mroDef *guardc;
+
+ /*
+ * Backtrack to find the class that directly
+ * sub-classes the duplicated one. This will
+ * be the one that disambiguates the duplicated
+ * one.
+ */
+ guardc = mro;
+
+ while (guardc != cd->mro)
+ {
+ mroDef *sub;
+ classList *cl;
+
+ for (sub = cd->mro; sub->next != guardc; sub = sub->next)
+ ;
+
+ for (cl = sub->cd->supers; cl != NULL; cl = cl->next)
+ if (cl->cd == mro->cd)
+ {
+ prcode(fp,"%S",classFQCName(sub->cd));
+
+ return;
+ }
+
+ /* Try the previous one. */
+ guardc = sub;
+ }
+ }
+
+ break;
+ }
+
+ /* If we got here there is nothing to worry about. */
+ prcode(fp,"%S",classFQCName(scope));
+}
+
+
+/*
+ * Generate a cast to zero.
+ */
+static void generateCastZero(argDef *ad,FILE *fp)
+{
+ if (ad->atype == enum_type)
+ prcode(fp,"(%E)",ad->u.ed);
+
+ prcode(fp,"0");
+}
+
+
+/*
+ * Generate the return statement for a virtual handler when there has been an
+ * error (ie. there is nothing sensible to return).
+ */
+static void generateVirtHandlerErrorReturn(argDef *res, const char *indent,
+ FILE *fp)
+{
+ prcode(fp,
+"%sreturn", indent);
+
+ if (res == NULL)
+ {
+ prcode(fp,";\n"
+ );
+
+ return;
+ }
+
+ prcode(fp," ");
+
+ if (res->atype == mapped_type && res->nrderefs == 0)
+ {
+ argDef res_noconstref;
+
+ /*
+ * We don't know anything about the mapped type so we just hope
+ * is has a default ctor.
+ */
+
+ if (isReference(res))
+ prcode(fp,"*new ");
+
+ res_noconstref = *res;
+ resetIsConstArg(&res_noconstref);
+ resetIsReference(&res_noconstref);
+ prcode(fp,"%B()",&res_noconstref);
+ }
+ else if (res->atype == class_type && res->nrderefs == 0)
+ {
+ ctorDef *ct = res->u.cd->defctor;
+
+ /*
+ * If we don't have a suitable ctor then the generated code
+ * will issue an error message.
+ */
+ if (ct != NULL && isPublicCtor(ct) && ct->cppsig != NULL)
+ {
+ argDef res_noconstref;
+
+ /*
+ * If this is a badly designed class. We can only
+ * generate correct code by leaking memory.
+ */
+ if (isReference(res))
+ prcode(fp,"*new ");
+
+ res_noconstref = *res;
+ resetIsConstArg(&res_noconstref);
+ resetIsReference(&res_noconstref);
+ prcode(fp,"%B",&res_noconstref);
+
+ generateCallDefaultCtor(ct,fp);
+ }
+ else
+ {
+ fatalScopedName(classFQCName(res->u.cd));
+ fatal(" must have a default constructor\n");
+ }
+ }
+ else
+ generateCastZero(res,fp);
+
+ prcode(fp,";\n"
+ );
+}
+
+
+/*
+ * Generate the call to a default ctor.
+ */
+static void generateCallDefaultCtor(ctorDef *ct, FILE *fp)
+{
+ int a;
+
+ prcode(fp, "(");
+
+ for (a = 0; a < ct->cppsig->nrArgs; ++a)
+ {
+ argDef *ad = &ct->cppsig->args[a];
+ argType atype = ad->atype;
+
+ if (ad->defval != NULL)
+ break;
+
+ if (a > 0)
+ prcode(fp, ",");
+
+ /* Do what we can to provide type information to the compiler. */
+ if (atype == class_type && ad->nrderefs > 0 && !isReference(ad))
+ prcode(fp, "static_cast<%B>(0)", ad);
+ else if (atype == enum_type)
+ prcode(fp, "static_cast<%E>(0)", ad->u.ed);
+ else if (atype == float_type || atype == cfloat_type)
+ prcode(fp, "0.0F");
+ else if (atype == double_type || atype == cdouble_type)
+ prcode(fp, "0.0");
+ else if (atype == uint_type)
+ prcode(fp, "0U");
+ else if (atype == long_type || atype == longlong_type)
+ prcode(fp, "0L");
+ else if (atype == ulong_type || atype == ulonglong_type)
+ prcode(fp, "0UL");
+ else if ((atype == ascii_string_type || atype == latin1_string_type || atype == utf8_string_type || atype == ustring_type || atype == sstring_type || atype == string_type) && ad->nrderefs == 0)
+ prcode(fp, "'\\0'");
+ else if (atype == wstring_type && ad->nrderefs == 0)
+ prcode(fp, "L'\\0'");
+ else
+ prcode(fp, "0");
+ }
+
+ prcode(fp, ")");
+}
+
+
+/*
+ * Generate the emitter function for a signal.
+ */
+static void generateEmitter(classDef *cd, visibleList *vl, FILE *fp)
+{
+ const char *pname = vl->m->pyname->text;
+ overDef *od;
+
+ prcode(fp,
+"\n"
+"int sip%C::sipEmit_%s(PyObject *sipArgs)\n"
+"{\n"
+" PyObject *sipParseErr = NULL;\n"
+ ,classFQCName(cd),pname);
+
+ for (od = vl->cd->overs; od != NULL; od = od->next)
+ {
+ int rgil = ((release_gil || isReleaseGIL(od)) && !isHoldGIL(od));
+
+ if (od->common != vl->m || !isSignal(od))
+ continue;
+
+ /*
+ * Generate the code that parses the args and emits the appropriate
+ * overloaded signal.
+ */
+ prcode(fp,
+"\n"
+" {\n"
+ );
+
+ generateArgParser(&od->pysig, cd, NULL, NULL, NULL, FALSE, fp);
+
+ prcode(fp,
+" {\n"
+ );
+
+ if (rgil)
+ prcode(fp,
+" Py_BEGIN_ALLOW_THREADS\n"
+ );
+
+ prcode(fp,
+" emit %s("
+ ,od->cppname);
+
+ generateCallArgs(od->cppsig, &od->pysig, fp);
+
+ prcode(fp,");\n"
+ );
+
+ if (rgil)
+ prcode(fp,
+" Py_END_ALLOW_THREADS\n"
+ );
+
+ deleteTemps(&od->pysig, fp);
+
+ prcode(fp,
+"\n"
+" return 0;\n"
+" }\n"
+" }\n"
+ );
+ }
+
+ prcode(fp,
+"\n"
+" sipNoMethod(sipParseErr, %N, %N, NULL);\n"
+"\n"
+" return -1;\n"
+"}\n"
+"\n"
+ , cd->pyname, vl->m->pyname);
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static int %C_emit_%s(sipSimpleWrapper *, PyObject *);}\n"
+ , classFQCName(cd), pname);
+
+ prcode(fp,
+"static int %C_emit_%s(sipSimpleWrapper *sw,PyObject *sipArgs)\n"
+"{\n"
+" sip%C *ptr = reinterpret_cast<sip%C *>(sipGetComplexCppPtr(sw));\n"
+"\n"
+" return (ptr ? ptr->sipEmit_%s(sipArgs) : -1);\n"
+"}\n"
+ ,classFQCName(cd),pname
+ ,classFQCName(cd),classFQCName(cd)
+ ,pname);
+}
+
+
+/*
+ * Generate the declarations of the protected wrapper functions for a class.
+ */
+static void generateProtectedDeclarations(classDef *cd,FILE *fp)
+{
+ int noIntro;
+ visibleList *vl;
+
+ noIntro = TRUE;
+
+ for (vl = cd->visible; vl != NULL; vl = vl->next)
+ {
+ overDef *od;
+
+ if (vl->m->slot != no_slot)
+ continue;
+
+ for (od = vl->cd->overs; od != NULL; od = od->next)
+ {
+ if (od->common != vl->m || !isProtected(od))
+ continue;
+
+ /*
+ * Check we haven't already handled this signature (eg. if we have
+ * specified the same method with different Python names.
+ */
+ if (isDuplicateProtected(cd, od))
+ continue;
+
+ if (noIntro)
+ {
+ prcode(fp,
+"\n"
+" /*\n"
+" * There is a public method for every protected method visible from\n"
+" * this class.\n"
+" */\n"
+ );
+
+ noIntro = FALSE;
+ }
+
+ prcode(fp,
+" ");
+
+ if (isStatic(od))
+ prcode(fp,"static ");
+
+ generateBaseType(cd->iff, &od->cppsig->result, TRUE, fp);
+
+ if (!isStatic(od) && !isAbstract(od) && (isVirtual(od) || isVirtualReimp(od)))
+ {
+ prcode(fp, " sipProtectVirt_%s(bool", od->cppname);
+
+ if (od->cppsig->nrArgs > 0)
+ prcode(fp, ",");
+ }
+ else
+ prcode(fp, " sipProtect_%s(", od->cppname);
+
+ generateCalledArgs(cd->iff, od->cppsig, Declaration, TRUE, fp);
+ prcode(fp,")%s;\n"
+ ,(isConst(od) ? " const" : ""));
+ }
+ }
+}
+
+
+/*
+ * Generate the definitions of the protected wrapper functions for a class.
+ */
+static void generateProtectedDefinitions(classDef *cd,FILE *fp)
+{
+ visibleList *vl;
+
+ for (vl = cd->visible; vl != NULL; vl = vl->next)
+ {
+ overDef *od;
+
+ if (vl->m->slot != no_slot)
+ continue;
+
+ for (od = vl->cd->overs; od != NULL; od = od->next)
+ {
+ char *mname = od->cppname;
+ int parens;
+ argDef *res;
+
+ if (od->common != vl->m || !isProtected(od))
+ continue;
+
+ /*
+ * Check we haven't already handled this signature (eg. if we have
+ * specified the same method with different Python names.
+ */
+ if (isDuplicateProtected(cd, od))
+ continue;
+
+ prcode(fp,
+"\n"
+ );
+
+ generateBaseType(cd->iff, &od->cppsig->result, TRUE, fp);
+
+ if (!isStatic(od) && !isAbstract(od) && (isVirtual(od) || isVirtualReimp(od)))
+ {
+ prcode(fp, " sip%C::sipProtectVirt_%s(bool sipSelfWasArg", classFQCName(cd), mname);
+
+ if (od->cppsig->nrArgs > 0)
+ prcode(fp, ",");
+ }
+ else
+ prcode(fp, " sip%C::sipProtect_%s(", classFQCName(cd), mname);
+
+ generateCalledArgs(cd->iff, od->cppsig, Definition, TRUE, fp);
+ prcode(fp,")%s\n"
+"{\n"
+ ,(isConst(od) ? " const" : ""));
+
+ parens = 1;
+
+ res = &od->cppsig->result;
+
+ if (res->atype == void_type && res->nrderefs == 0)
+ prcode(fp,
+" ");
+ else
+ {
+ prcode(fp,
+" return ");
+
+ if (res->atype == class_type && isProtectedClass(res->u.cd))
+ {
+ prcode(fp,"static_cast<%U *>(",res->u.cd);
+ ++parens;
+ }
+ else if (res->atype == enum_type && isProtectedEnum(res->u.ed))
+ /*
+ * One or two older compilers can't handle a static_cast
+ * here so we revert to a C-style cast.
+ */
+ prcode(fp,"(%E)",res->u.ed);
+ }
+
+ if (!isAbstract(od))
+ {
+ if (isVirtual(od) || isVirtualReimp(od))
+ {
+ prcode(fp, "(sipSelfWasArg ? %S::%s(", classFQCName(vl->cd), mname);
+
+ generateProtectedCallArgs(od->cppsig, fp);
+
+ prcode(fp, ") : ");
+ ++parens;
+ }
+ else
+ prcode(fp, "%S::", classFQCName(vl->cd));
+ }
+
+ prcode(fp,"%s(",mname);
+
+ generateProtectedCallArgs(od->cppsig, fp);
+
+ while (parens--)
+ prcode(fp,")");
+
+ prcode(fp,";\n"
+"}\n"
+ );
+ }
+ }
+}
+
+
+/*
+ * Return TRUE if a protected method is a duplicate.
+ */
+static int isDuplicateProtected(classDef *cd, overDef *target)
+{
+ visibleList *vl;
+
+ for (vl = cd->visible; vl != NULL; vl = vl->next)
+ {
+ overDef *od;
+
+ if (vl->m->slot != no_slot)
+ continue;
+
+ for (od = vl->cd->overs; od != NULL; od = od->next)
+ {
+ if (od->common != vl->m || !isProtected(od))
+ continue;
+
+ if (od == target)
+ return FALSE;
+
+ if (strcmp(od->cppname, target->cppname) == 0 && sameSignature(od->cppsig, target->cppsig, TRUE))
+ return TRUE;
+ }
+ }
+
+ /* We should never actually get here. */
+ return FALSE;
+}
+
+
+/*
+ * Generate the arguments for a call to a protected method.
+ */
+static void generateProtectedCallArgs(signatureDef *sd, FILE *fp)
+{
+ int a;
+
+ for (a = 0; a < sd->nrArgs; ++a)
+ {
+ argDef *ad = &sd->args[a];
+
+ if (a > 0)
+ prcode(fp, ",");
+
+ if (ad->atype == enum_type && isProtectedEnum(ad->u.ed))
+ prcode(fp, "(%S)", ad->u.ed->fqcname);
+
+ prcode(fp, "a%d", a);
+ }
+}
+
+
+/*
+ * Generate the function that does most of the work to handle a particular
+ * virtual function.
+ */
+static void generateVirtualHandler(virtHandlerDef *vhd, FILE *fp)
+{
+ int a, nrvals, res_isref, need_self;
+ argDef *res, res_noconstref, *ad;
+ signatureDef saved;
+
+ res = &vhd->cppsig->result;
+
+ res_isref = FALSE;
+
+ if (res->atype == void_type && res->nrderefs == 0)
+ res = NULL;
+ else
+ {
+ /*
+ * If we are returning a reference to an instance then we take care to
+ * handle Python errors but still return a valid C++ instance.
+ */
+ if ((res->atype == class_type || res->atype == mapped_type) && res->nrderefs == 0)
+ {
+ if (isReference(res))
+ res_isref = TRUE;
+ }
+
+ res_noconstref = *res;
+ resetIsConstArg(&res_noconstref);
+ resetIsReference(&res_noconstref);
+ }
+
+ prcode(fp,
+"\n"
+ );
+
+ saved = *vhd->cppsig;
+ fakeProtectedArgs(vhd->cppsig);
+
+ generateBaseType(NULL, &vhd->cppsig->result, FALSE, fp);
+
+ prcode(fp," sipVH_%s_%d(sip_gilstate_t sipGILState,PyObject *sipMethod"
+ , vhd->module->name, vhd->virthandlernr);
+
+ if (vhd->cppsig->nrArgs > 0)
+ {
+ prcode(fp,",");
+ generateCalledArgs(NULL, vhd->cppsig, Definition, FALSE, fp);
+ }
+
+ *vhd->cppsig = saved;
+
+ /* Declare the extra arguments for kept references. */
+ need_self = FALSE;
+
+ if (res != NULL && keepPyReference(res))
+ {
+ need_self = TRUE;
+ prcode(fp, ",int");
+
+ if (vhd->virtcode == NULL || usedInCode(vhd->virtcode, "sipResKey"))
+ prcode(fp, " sipResKey");
+ }
+
+ for (ad = vhd->cppsig->args, a = 0; a < vhd->cppsig->nrArgs; ++a, ++ad)
+ if (isOutArg(ad) && keepPyReference(ad))
+ {
+ need_self = TRUE;
+ prcode(fp, ",int a%dKey", a);
+ }
+
+ if (need_self)
+ {
+ prcode(fp, ",sipSimpleWrapper *");
+
+ if (vhd->virtcode == NULL || usedInCode(vhd->virtcode, "sipPySelf"))
+ prcode(fp, "sipPySelf");
+ }
+
+ prcode(fp,")\n"
+"{\n"
+ );
+
+ if (res != NULL)
+ {
+ prcode(fp, " ");
+
+ /*
+ * wchar_t * return values are always on the heap. To reduce memory
+ * leaks we keep the last result around until we have a new one. This
+ * means that ownership of the return value stays with the function
+ * returning it - which is consistent with how other types work, even
+ * thought it may not be what's required in all cases. Note that we
+ * should do this in the code that calls the handler instead of here
+ * (as we do with strings) so that it doesn't get shared between all
+ * callers.
+ */
+ if (res->atype == wstring_type && res->nrderefs == 1)
+ prcode(fp, "static ");
+
+ generateBaseType(NULL, &res_noconstref, FALSE, fp);
+
+ prcode(fp," %ssipRes",(res_isref ? "*" : ""));
+
+ if ((res->atype == class_type || res->atype == mapped_type) && res->nrderefs == 0)
+ {
+ if (res->atype == class_type)
+ {
+ ctorDef *ct = res->u.cd->defctor;
+
+ if (ct != NULL && isPublicCtor(ct) && ct->cppsig != NULL && ct->cppsig->nrArgs > 0 && ct->cppsig->args[0].defval == NULL)
+ generateCallDefaultCtor(ct,fp);
+ }
+ }
+ else
+ {
+ /*
+ * We initialise the result to try and suppress a
+ * compiler warning.
+ */
+ prcode(fp," = ");
+ generateCastZero(res,fp);
+ }
+
+ prcode(fp,";\n"
+ );
+
+ if (res->atype == wstring_type && res->nrderefs == 1)
+ prcode(fp,
+"\n"
+" if (sipRes)\n"
+" {\n"
+" // Return any previous result to the heap.\n"
+" sipFree(%s);\n"
+" sipRes = 0;\n"
+" }\n"
+"\n"
+ , (isConstArg(res) ? "const_cast<wchar_t *>(sipRes)" : "sipRes"));
+ }
+
+ if (vhd->virtcode != NULL)
+ {
+ int error_flag = needErrorFlag(vhd->virtcode);
+ int old_error_flag = needOldErrorFlag(vhd->virtcode);
+
+ if (error_flag)
+ prcode(fp,
+" sipErrorState sipError = sipErrorNone;\n"
+ );
+ else if (old_error_flag)
+ prcode(fp,
+" int sipIsErr = 0;\n"
+ );
+
+ prcode(fp,
+"\n"
+ );
+
+ generateCppCodeBlock(vhd->virtcode,fp);
+
+ if (error_flag || old_error_flag)
+ prcode(fp,
+"\n"
+" if (%s)\n"
+" PyErr_Print();\n"
+ , (error_flag ? "sipError != sipErrorNone" : "sipIsErr"));
+
+ prcode(fp,
+"\n"
+" Py_DECREF(sipMethod);\n"
+"\n"
+" SIP_RELEASE_GIL(sipGILState)\n"
+ );
+
+ if (res != NULL)
+ prcode(fp,
+"\n"
+" return sipRes;\n"
+ );
+
+ prcode(fp,
+"}\n"
+ );
+
+ return;
+ }
+
+ /* See how many values we expect. */
+ nrvals = (res != NULL ? 1 : 0);
+
+ for (a = 0; a < vhd->pysig->nrArgs; ++a)
+ if (isOutArg(&vhd->pysig->args[a]))
+ ++nrvals;
+
+ /* Call the method. */
+ prcode(fp,
+" PyObject *resObj = sipCallMethod(0,sipMethod,");
+
+ saved = *vhd->pysig;
+ fakeProtectedArgs(vhd->pysig);
+ generateTupleBuilder(vhd->pysig, fp);
+ *vhd->pysig = saved;
+
+ prcode(fp,");\n"
+"\n"
+" %s (!resObj || sipParseResult(0,sipMethod,resObj,\"",(res_isref ? "int sipIsErr =" : "if"));
+
+ /* Build the format string. */
+ if (need_self)
+ prcode(fp, "S");
+
+ if (nrvals == 0)
+ prcode(fp,"Z");
+ else
+ {
+ if (nrvals > 1)
+ prcode(fp,"(");
+
+ if (res != NULL)
+ prcode(fp, "%s", getParseResultFormat(res, res_isref, isTransferVH(vhd)));
+
+ for (a = 0; a < vhd->pysig->nrArgs; ++a)
+ {
+ argDef *ad = &vhd->pysig->args[a];
+
+ if (isOutArg(ad))
+ prcode(fp, "%s", getParseResultFormat(ad, FALSE, FALSE));
+ }
+
+ if (nrvals > 1)
+ prcode(fp,")");
+ }
+
+ prcode(fp,"\"");
+
+ if (need_self)
+ prcode(fp, ",sipPySelf");
+
+ /* Pass the destination pointers. */
+ if (res != NULL)
+ {
+ generateParseResultExtraArgs(res, -1, fp);
+ prcode(fp, ",&sipRes");
+ }
+
+ for (a = 0; a < vhd->pysig->nrArgs; ++a)
+ {
+ argDef *ad = &vhd->pysig->args[a];
+
+ if (isOutArg(ad))
+ {
+ generateParseResultExtraArgs(ad, a, fp);
+ prcode(fp,",%sa%d",(isReference(ad) ? "&" : ""),a);
+ }
+ }
+
+ if (res_isref)
+ prcode(fp,") < 0);\n"
+"\n"
+" if (sipIsErr)\n"
+ );
+ else
+ prcode(fp,") < 0)\n"
+ );
+
+ prcode(fp,
+" PyErr_Print();\n"
+ );
+
+ prcode(fp,
+"\n"
+" Py_XDECREF(resObj);\n"
+" Py_DECREF(sipMethod);\n"
+"\n"
+" SIP_RELEASE_GIL(sipGILState)\n"
+ );
+
+ if (res != NULL)
+ {
+ if (res_isref)
+ {
+ prcode(fp,
+"\n"
+" if (sipIsErr)\n"
+ );
+
+ generateVirtHandlerErrorReturn(res, " ", fp);
+ }
+
+ prcode(fp,
+"\n"
+" return %ssipRes;\n"
+ ,(res_isref ? "*" : ""));
+ }
+
+ prcode(fp,
+"}\n"
+ );
+}
+
+
+/*
+ * Generate the extra arguments needed by sipParseResult() for a particular
+ * type.
+ */
+static void generateParseResultExtraArgs(argDef *ad, int argnr, FILE *fp)
+{
+ switch (ad->atype)
+ {
+ case mapped_type:
+ prcode(fp, ",sipType_%T", ad);
+ break;
+
+ case class_type:
+ prcode(fp, ",sipType_%C", classFQCName(ad->u.cd));
+ break;
+
+ case pytuple_type:
+ prcode(fp,",&PyTuple_Type");
+ break;
+
+ case pylist_type:
+ prcode(fp,",&PyList_Type");
+ break;
+
+ case pydict_type:
+ prcode(fp,",&PyDict_Type");
+ break;
+
+ case pyslice_type:
+ prcode(fp,",&PySlice_Type");
+ break;
+
+ case pytype_type:
+ prcode(fp,",&PyType_Type");
+ break;
+
+ case enum_type:
+ if (ad->u.ed->fqcname != NULL)
+ prcode(fp, ",sipType_%C", ad->u.ed->fqcname);
+ break;
+
+ default:
+ if (keepPyReference(ad))
+ {
+ if (argnr < 0)
+ prcode(fp, ",sipResKey");
+ else
+ prcode(fp, ",a%dKey", argnr);
+ }
+ }
+}
+
+
+/*
+ * Return the format characters used by sipParseResult() for a particular type.
+ */
+static const char *getParseResultFormat(argDef *ad, int res_isref, int xfervh)
+{
+ switch (ad->atype)
+ {
+ case mapped_type:
+ case fake_void_type:
+ case class_type:
+ {
+ static const char *type_formats[] = {
+ "H0", "H1", "H2", "H3", "H4", "H5", "H6", "H7"
+ };
+
+ int f = 0x00;
+
+ if (ad->nrderefs == 0)
+ {
+ f |= 0x01;
+
+ if (!res_isref)
+ f |= 0x04;
+ }
+
+ if (xfervh)
+ f |= 0x02;
+
+ return type_formats[f];
+ }
+
+ case bool_type:
+ case cbool_type:
+ return "b";
+
+ case ascii_string_type:
+ return ((ad->nrderefs == 0) ? "aA" : "AA");
+
+ case latin1_string_type:
+ return ((ad->nrderefs == 0) ? "aL" : "AL");
+
+ case utf8_string_type:
+ return ((ad->nrderefs == 0) ? "a8" : "A8");
+
+ case sstring_type:
+ case ustring_type:
+ case string_type:
+ return ((ad->nrderefs == 0) ? "c" : "B");
+
+ case wstring_type:
+ return ((ad->nrderefs == 0) ? "w" : "x");
+
+ case enum_type:
+ return ((ad->u.ed->fqcname != NULL) ? "F" : "e");
+
+ case ushort_type:
+ return "t";
+
+ case short_type:
+ return "h";
+
+ case int_type:
+ case cint_type:
+ return "i";
+
+ case uint_type:
+ return "u";
+
+ case long_type:
+ return "l";
+
+ case ulong_type:
+ return "m";
+
+ case longlong_type:
+ return "n";
+
+ case ulonglong_type:
+ return "o";
+
+ case void_type:
+ case struct_type:
+ return "V";
+
+ case float_type:
+ case cfloat_type:
+ return "f";
+
+ case double_type:
+ case cdouble_type:
+ return "d";
+
+ case pyobject_type:
+ return "O";
+
+ case pytuple_type:
+ case pylist_type:
+ case pydict_type:
+ case pyslice_type:
+ case pytype_type:
+ return (isAllowNone(ad) ? "N" : "T");
+ }
+
+ /* We should never get here. */
+ return " ";
+}
+
+
+/*
+ * Generate the code to build a tuple of Python arguments.
+ */
+static void generateTupleBuilder(signatureDef *sd,FILE *fp)
+{
+ int a, arraylenarg;
+
+ prcode(fp,"\"");
+
+ for (a = 0; a < sd->nrArgs; ++a)
+ {
+ char *fmt = "";
+ argDef *ad = &sd->args[a];
+
+ if (!isInArg(ad))
+ continue;
+
+ switch (ad->atype)
+ {
+ case ascii_string_type:
+ if (ad->nrderefs == 0 || (ad->nrderefs == 1 && isOutArg(ad)))
+ fmt = "aA";
+ else
+ fmt = "AA";
+
+ break;
+
+ case latin1_string_type:
+ if (ad->nrderefs == 0 || (ad->nrderefs == 1 && isOutArg(ad)))
+ fmt = "aL";
+ else
+ fmt = "AL";
+
+ break;
+
+ case utf8_string_type:
+ if (ad->nrderefs == 0 || (ad->nrderefs == 1 && isOutArg(ad)))
+ fmt = "a8";
+ else
+ fmt = "A8";
+
+ break;
+
+ case sstring_type:
+ case ustring_type:
+ case string_type:
+ if (ad->nrderefs == 0 || (ad->nrderefs == 1 && isOutArg(ad)))
+ fmt = "c";
+ else if (isArray(ad))
+ fmt = "g";
+ else
+ fmt = "s";
+
+ break;
+
+ case wstring_type:
+ if (ad->nrderefs == 0 || (ad->nrderefs == 1 && isOutArg(ad)))
+ fmt = "w";
+ else if (isArray(ad))
+ fmt = "G";
+ else
+ fmt = "x";
+
+ break;
+
+ case bool_type:
+ case cbool_type:
+ fmt = "b";
+ break;
+
+ case enum_type:
+ fmt = (ad->u.ed->fqcname != NULL) ? "F" : "e";
+ break;
+
+ case cint_type:
+ fmt = "i";
+ break;
+
+ case uint_type:
+ if (isArraySize(ad))
+ arraylenarg = a;
+ else
+ fmt = "u";
+
+ break;
+
+ case int_type:
+ if (isArraySize(ad))
+ arraylenarg = a;
+ else
+ fmt = "i";
+
+ break;
+
+ case ushort_type:
+ if (isArraySize(ad))
+ arraylenarg = a;
+ else
+ fmt = "t";
+
+ break;
+
+ case short_type:
+ if (isArraySize(ad))
+ arraylenarg = a;
+ else
+ fmt = "h";
+
+ break;
+
+ case long_type:
+ if (isArraySize(ad))
+ arraylenarg = a;
+ else
+ fmt = "l";
+
+ break;
+
+ case ulong_type:
+ if (isArraySize(ad))
+ arraylenarg = a;
+ else
+ fmt = "m";
+
+ break;
+
+ case longlong_type:
+ if (isArraySize(ad))
+ arraylenarg = a;
+ else
+ fmt = "n";
+
+ break;
+
+ case ulonglong_type:
+ if (isArraySize(ad))
+ arraylenarg = a;
+ else
+ fmt = "o";
+
+ break;
+
+ case struct_type:
+ case void_type:
+ fmt = "V";
+ break;
+
+ case float_type:
+ case cfloat_type:
+ fmt = "f";
+ break;
+
+ case double_type:
+ case cdouble_type:
+ fmt = "d";
+ break;
+
+ case signal_type:
+ case slot_type:
+ case slotcon_type:
+ case slotdis_type:
+ fmt = "s";
+ break;
+
+ case mapped_type:
+ case class_type:
+ if (isArray(ad))
+ {
+ fmt = "r";
+ break;
+ }
+
+ if (copyConstRefArg(ad))
+ {
+ fmt = "N";
+ break;
+ }
+
+ /* Drop through. */
+
+ case fake_void_type:
+ case rxcon_type:
+ case rxdis_type:
+ case qobject_type:
+ fmt = "D";
+ break;
+
+ case pyobject_type:
+ case pytuple_type:
+ case pylist_type:
+ case pydict_type:
+ case pycallable_type:
+ case pyslice_type:
+ case pytype_type:
+ fmt = "S";
+ break;
+ }
+
+ prcode(fp,fmt);
+ }
+
+ prcode(fp,"\"");
+
+ for (a = 0; a < sd->nrArgs; ++a)
+ {
+ int derefs;
+ argDef *ad = &sd->args[a];
+
+ if (!isInArg(ad))
+ continue;
+
+ derefs = ad->nrderefs;
+
+ switch (ad->atype)
+ {
+ case ascii_string_type:
+ case latin1_string_type:
+ case utf8_string_type:
+ case sstring_type:
+ case ustring_type:
+ case string_type:
+ case wstring_type:
+ if (!(ad->nrderefs == 0 || (ad->nrderefs == 1 && isOutArg(ad))))
+ --derefs;
+
+ break;
+
+ case mapped_type:
+ case fake_void_type:
+ case class_type:
+ if (ad->nrderefs > 0)
+ --derefs;
+
+ break;
+
+ case struct_type:
+ case void_type:
+ --derefs;
+ break;
+ }
+
+ if (ad->atype == mapped_type || ad->atype == class_type ||
+ ad->atype == rxcon_type || ad->atype == rxdis_type ||
+ ad->atype == qobject_type || ad->atype == fake_void_type)
+ {
+ int copy = copyConstRefArg(ad);
+
+ prcode(fp,",");
+
+ if (copy)
+ {
+ prcode(fp,"new %b(",ad);
+ }
+ else
+ {
+ if (isConstArg(ad))
+ prcode(fp,"const_cast<%b *>(",ad);
+
+ if (ad->nrderefs == 0)
+ prcode(fp,"&");
+ else
+ while (derefs-- != 0)
+ prcode(fp,"*");
+ }
+
+ prcode(fp,"a%d",a);
+
+ if (copy || isConstArg(ad))
+ prcode(fp,")");
+
+ if (isArray(ad))
+ prcode(fp, ",(SIP_SSIZE_T)a%d", arraylenarg);
+
+ if (ad->atype == mapped_type)
+ prcode(fp, ",sipType_%T", ad);
+ else if (ad->atype == fake_void_type || ad->atype == class_type)
+ prcode(fp, ",sipType_%C", classFQCName(ad->u.cd));
+ else
+ prcode(fp,",sipType_QObject");
+
+ if (!isArray(ad))
+ prcode(fp, ",NULL");
+ }
+ else
+ {
+ if (!isArraySize(ad))
+ {
+ prcode(fp, ",");
+
+ while (derefs-- != 0)
+ prcode(fp, "*");
+
+ prcode(fp, "a%d", a);
+ }
+
+ if (isArray(ad))
+ prcode(fp, ",(SIP_SSIZE_T)a%d", arraylenarg);
+ else if (ad->atype == enum_type && ad->u.ed->fqcname != NULL)
+ prcode(fp, ",sipType_%C", ad->u.ed->fqcname);
+ }
+ }
+}
+
+
+/*
+ * Generate the library header #include directives required by either a class
+ * or a module.
+ */
+static void generateUsedIncludes(ifaceFileList *iffl, FILE *fp)
+{
+ prcode(fp,
+"\n"
+ );
+
+ while (iffl != NULL)
+ {
+ generateCppCodeBlock(iffl->iff->hdrcode, fp);
+ iffl = iffl->next;
+ }
+}
+
+
+/*
+ * Generate the API details for a module.
+ */
+static void generateModuleAPI(sipSpec *pt, moduleDef *mod, FILE *fp)
+{
+ classDef *cd;
+ mappedTypeDef *mtd;
+ exceptionDef *xd;
+
+ for (cd = pt->classes; cd != NULL; cd = cd->next)
+ if (cd->iff->module == mod)
+ generateClassAPI(cd, pt, fp);
+
+ for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next)
+ if (mtd->iff->module == mod)
+ generateMappedTypeAPI(pt, mtd, fp);
+
+ for (xd = pt->exceptions; xd != NULL; xd = xd->next)
+ if (xd->iff->module == mod && xd->exceptionnr >= 0)
+ prcode(fp,
+"\n"
+"#define sipException_%C sipModuleAPI_%s.em_exceptions[%d]\n"
+ , xd->iff->fqcname, mod->name, xd->exceptionnr);
+}
+
+
+/*
+ * Generate the API details for an imported module.
+ */
+static void generateImportedModuleAPI(sipSpec *pt, moduleDef *mod,
+ moduleDef *immod, FILE *fp)
+{
+ classDef *cd;
+ mappedTypeDef *mtd;
+ exceptionDef *xd;
+
+ for (cd = pt->classes; cd != NULL; cd = cd->next)
+ if (cd->iff->module == immod && !isExternal(cd))
+ generateImportedClassAPI(cd, pt, mod, fp);
+
+ for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next)
+ if (mtd->iff->module == immod)
+ generateImportedMappedTypeAPI(mtd, pt, mod, fp);
+
+ for (xd = pt->exceptions; xd != NULL; xd = xd->next)
+ if (xd->iff->module == immod && xd->exceptionnr >= 0)
+ prcode(fp,
+"\n"
+"#define sipException_%C sipModuleAPI_%s_%s->em_exceptions[%d]\n"
+ , xd->iff->fqcname, mod->name, xd->iff->module->name, xd->exceptionnr);
+}
+
+
+/*
+ * Generate the API details for an imported mapped type.
+ */
+static void generateImportedMappedTypeAPI(mappedTypeDef *mtd, sipSpec *pt,
+ moduleDef *mod, FILE *fp)
+{
+ /* Ignore alternate API implementations. */
+ if (mtd->iff->first_alt == mtd->iff)
+ {
+ const char *mname = mod->name;
+ const char *imname = mtd->iff->module->name;
+ argDef type;
+
+ memset(&type, 0, sizeof (argDef));
+
+ type.atype = mapped_type;
+ type.u.mtd = mtd;
+
+ prcode(fp,
+"\n"
+"#define sipType_%T sipModuleAPI_%s_%s->em_types[%d]\n"
+ , &type, mname, imname, mtd->iff->ifacenr);
+ }
+
+ generateEnumMacros(pt, mod, NULL, mtd, fp);
+}
+
+
+/*
+ * Generate the API details for a mapped type.
+ */
+static void generateMappedTypeAPI(sipSpec *pt, mappedTypeDef *mtd, FILE *fp)
+{
+ argDef type;
+
+ memset(&type, 0, sizeof (argDef));
+
+ type.atype = mapped_type;
+ type.u.mtd = mtd;
+
+ if (mtd->iff->first_alt == mtd->iff)
+ prcode(fp,
+"\n"
+"#define sipType_%T sipModuleAPI_%s.em_types[%d]\n"
+ , &type, mtd->iff->module->name, mtd->iff->ifacenr);
+
+ prcode(fp,
+"\n"
+"extern sipMappedTypeDef sipTypeDef_%s_%L;\n"
+ , mtd->iff->module->name, mtd->iff);
+
+ generateEnumMacros(pt, mtd->iff->module, NULL, mtd, fp);
+}
+
+
+/*
+ * Generate the API details for an imported class.
+ */
+static void generateImportedClassAPI(classDef *cd, sipSpec *pt, moduleDef *mod,
+ FILE *fp)
+{
+ prcode(fp,
+"\n"
+ );
+
+ /* Ignore alternate API implementations. */
+ if (cd->iff->first_alt == cd->iff)
+ {
+ const char *mname = mod->name;
+ const char *imname = cd->iff->module->name;
+
+ if (cd->iff->type == namespace_iface)
+ prcode(fp,
+"#if !defined(sipType_%L)\n"
+ , cd->iff);
+
+ prcode(fp,
+"#define sipType_%C sipModuleAPI_%s_%s->em_types[%d]\n"
+"#define sipClass_%C sipModuleAPI_%s_%s->em_types[%d]->u.td_wrapper_type\n"
+ , classFQCName(cd), mname, imname, cd->iff->ifacenr
+ , classFQCName(cd), mname, imname, cd->iff->ifacenr);
+
+ if (cd->iff->type == namespace_iface)
+ prcode(fp,
+"#endif\n"
+ );
+ }
+
+ generateEnumMacros(pt, mod, cd, NULL, fp);
+}
+
+
+/*
+ * Generate the C++ API for a class.
+ */
+static void generateClassAPI(classDef *cd, sipSpec *pt, FILE *fp)
+{
+ const char *mname = cd->iff->module->name;
+
+ prcode(fp,
+"\n"
+ );
+
+ if (cd->real == NULL && cd->iff->first_alt == cd->iff)
+ prcode(fp,
+"#define sipType_%C sipModuleAPI_%s.em_types[%d]\n"
+"#define sipClass_%C sipModuleAPI_%s.em_types[%d]->u.td_wrapper_type\n"
+ , classFQCName(cd), mname, cd->iff->ifacenr
+ , classFQCName(cd), mname, cd->iff->ifacenr);
+
+ generateEnumMacros(pt, cd->iff->module, cd, NULL, fp);
+
+ if (!isExternal(cd))
+ {
+ const char *type_prefix;
+
+ if (pluginPyQt4(pt))
+ type_prefix = "pyqt4";
+ else if (pluginPyQt3(pt))
+ type_prefix = "pyqt3";
+ else
+ type_prefix = "sip";
+
+ prcode(fp,
+"\n"
+"extern %sClassTypeDef sipTypeDef_%s_%L;\n"
+ , type_prefix, mname, cd->iff);
+ }
+}
+
+
+/*
+ * Generate the sipEnum_* macros.
+ */
+static void generateEnumMacros(sipSpec *pt, moduleDef *mod, classDef *cd,
+ mappedTypeDef *mtd, FILE *fp)
+{
+ enumDef *ed;
+ int noIntro = TRUE;
+
+ for (ed = pt->enums; ed != NULL; ed = ed->next)
+ {
+ if (ed->fqcname == NULL)
+ continue;
+
+ if (ed->first_alt != ed)
+ continue;
+
+ if (cd != NULL)
+ {
+ if (ed->ecd != cd)
+ continue;
+ }
+ else if (mtd != NULL)
+ {
+ if (ed->emtd != mtd)
+ continue;
+ }
+ else if (ed->ecd != NULL || ed->emtd != NULL)
+ {
+ continue;
+ }
+
+ if (noIntro)
+ {
+ prcode(fp,
+"\n"
+ );
+
+ noIntro = FALSE;
+ }
+
+ if (mod == ed->module)
+ prcode(fp,
+"#define sipType_%C sipModuleAPI_%s.em_types[%d]\n"
+"#define sipEnum_%C sipModuleAPI_%s.em_types[%d]->u.td_py_type\n"
+ , ed->fqcname, mod->name, ed->enumnr
+ , ed->fqcname, mod->name, ed->enumnr);
+ else
+ prcode(fp,
+"#define sipType_%C sipModuleAPI_%s_%s->em_types[%d]\n"
+"#define sipEnum_%C sipModuleAPI_%s_%s->em_types[%d]->u.td_py_type\n"
+ , ed->fqcname, mod->name, ed->module->name, ed->enumnr
+ , ed->fqcname, mod->name, ed->module->name, ed->enumnr);
+ }
+}
+
+
+/*
+ * Generate the shadow class declaration.
+ */
+static void generateShadowClassDeclaration(sipSpec *pt,classDef *cd,FILE *fp)
+{
+ int noIntro, nrVirts;
+ ctorDef *ct;
+ virtOverDef *vod;
+ classDef *pcd;
+
+ prcode(fp,
+"\n"
+"\n"
+"class sip%C : public %S\n"
+"{\n"
+"public:\n"
+ ,classFQCName(cd),classFQCName(cd));
+
+ /* Define a shadow class for any protected classes we have. */
+
+ for (pcd = pt->classes; pcd != NULL; pcd = pcd->next)
+ {
+ mroDef *mro;
+
+ if (!isProtectedClass(pcd))
+ continue;
+
+ /* See if the class defining the class is in our class hierachy. */
+ for (mro = cd->mro; mro != NULL; mro = mro->next)
+ if (mro->cd == pcd->ecd)
+ break;
+
+ if (mro == NULL)
+ continue;
+
+ prcode(fp,
+" class sip%s : public %s {\n"
+" public:\n"
+ , classBaseName(pcd), classBaseName(pcd));
+
+ generateProtectedEnums(pt, pcd, fp);
+
+ prcode(fp,
+" };\n"
+"\n"
+ );
+ }
+
+ /* The constructor declarations. */
+
+ for (ct = cd->ctors; ct != NULL; ct = ct->next)
+ {
+ ctorDef *dct;
+
+ if (isPrivateCtor(ct))
+ continue;
+
+ if (ct->cppsig == NULL)
+ continue;
+
+ /* Check we haven't already handled this C++ signature. */
+ for (dct = cd->ctors; dct != ct; dct = dct->next)
+ if (dct->cppsig != NULL && sameSignature(dct->cppsig, ct->cppsig, TRUE))
+ break;
+
+ if (dct != ct)
+ continue;
+
+ prcode(fp,
+" sip%C(",classFQCName(cd));
+
+ generateCalledArgs(cd->iff, ct->cppsig, Declaration, TRUE, fp);
+
+ prcode(fp,")%X;\n"
+ ,ct->exceptions);
+ }
+
+ /* The destructor. */
+
+ if (!isPrivateDtor(cd))
+ prcode(fp,
+" %s~sip%C()%X;\n"
+ ,(cd->vmembers != NULL ? "virtual " : ""),classFQCName(cd),cd->dtorexceptions);
+
+ /* The metacall methods if required. */
+ if (pluginPyQt4(pt) && isQObjectSubClass(cd))
+ {
+ prcode(fp,
+"\n"
+" int qt_metacall(QMetaObject::Call,int,void **);\n"
+" void *qt_metacast(const char *);\n"
+ );
+
+ if (!noPyQt4QMetaObject(cd))
+ prcode(fp,
+" const QMetaObject *metaObject() const;\n"
+ );
+ }
+
+ /* The exposure of protected enums. */
+
+ generateProtectedEnums(pt,cd,fp);
+
+ /* The wrapper around each protected member function. */
+
+ generateProtectedDeclarations(cd,fp);
+
+ /* The public wrapper around each signal emitter. */
+ if (pluginPyQt3(pt))
+ {
+ visibleList *vl;
+
+ noIntro = TRUE;
+
+ for (vl = cd->visible; vl != NULL; vl = vl->next)
+ {
+ overDef *od;
+
+ if (vl->m->slot != no_slot)
+ continue;
+
+ for (od = vl->cd->overs; od != NULL; od = od->next)
+ {
+ if (od->common != vl->m || !isSignal(od))
+ continue;
+
+ if (noIntro)
+ {
+ prcode(fp,
+"\n"
+" /*\n"
+" * There is a public method for every Qt signal that can be emitted\n"
+" * by this object. This function is called by Python to emit the\n"
+" * signal.\n"
+" */\n"
+ );
+
+ noIntro = FALSE;
+ }
+
+ prcode(fp,
+" int sipEmit_%s(PyObject *);\n"
+ ,vl->m->pyname->text);
+
+ break;
+ }
+ }
+ }
+
+ /* The catcher around each virtual function in the hierarchy. */
+ noIntro = TRUE;
+
+ for (vod = cd->vmembers; vod != NULL; vod = vod->next)
+ {
+ overDef *od = &vod->o;
+ virtOverDef *dvod;
+
+ if (isPrivate(od))
+ continue;
+
+ /* Check we haven't already handled this C++ signature. */
+ for (dvod = cd->vmembers; dvod != vod; dvod = dvod->next)
+ if (strcmp(dvod->o.cppname,od->cppname) == 0 && sameSignature(dvod->o.cppsig,od->cppsig,TRUE))
+ break;
+
+ if (dvod != vod)
+ continue;
+
+ if (noIntro)
+ {
+ prcode(fp,
+"\n"
+" /*\n"
+" * There is a protected method for every virtual method visible from\n"
+" * this class.\n"
+" */\n"
+"protected:\n"
+ );
+
+ noIntro = FALSE;
+ }
+
+ prcode(fp,
+" ");
+
+ prOverloadDecl(fp, cd->iff, od, FALSE);
+ prcode(fp, ";\n");
+ }
+
+ prcode(fp,
+"\n"
+"public:\n"
+" sipSimpleWrapper *sipPySelf;\n"
+ );
+
+ /* The private declarations. */
+
+ prcode(fp,
+"\n"
+"private:\n"
+" sip%C(const sip%C &);\n"
+" sip%C &operator = (const sip%C &);\n"
+ ,classFQCName(cd),classFQCName(cd)
+ ,classFQCName(cd),classFQCName(cd));
+
+ if ((nrVirts = countVirtuals(cd)) > 0)
+ prcode(fp,
+"\n"
+" char sipPyMethods[%d];\n"
+ ,nrVirts);
+
+ prcode(fp,
+"};\n"
+ );
+}
+
+
+/*
+ * Generate the C++ declaration for an overload.
+ */
+void prOverloadDecl(FILE *fp, ifaceFileDef *scope, overDef *od, int defval)
+{
+ int a;
+
+ normaliseArgs(od->cppsig);
+
+ generateBaseType(scope, &od->cppsig->result, TRUE, fp);
+
+ prcode(fp, " %O(", od);
+
+ for (a = 0; a < od->cppsig->nrArgs; ++a)
+ {
+ argDef *ad = &od->cppsig->args[a];
+
+ if (a > 0)
+ prcode(fp, ",");
+
+ generateBaseType(scope, ad, TRUE, fp);
+
+ if (defval && ad->defval != NULL)
+ {
+ prcode(fp, " = ");
+ generateExpression(ad->defval, FALSE, fp);
+ }
+ }
+
+ prcode(fp, ")%s%X", (isConst(od) ? " const" : ""), od->exceptions);
+
+ restoreArgs(od->cppsig);
+}
+
+
+/*
+ * Generate typed arguments for a declaration or a definition.
+ */
+static void generateCalledArgs(ifaceFileDef *scope, signatureDef *sd,
+ funcArgType ftype, int use_typename, FILE *fp)
+{
+ char name[50];
+ int a;
+
+ for (a = 0; a < sd->nrArgs; ++a)
+ {
+ argDef *ad = &sd->args[a];
+
+ if (a > 0)
+ prcode(fp,",");
+
+ if (ftype == Definition)
+ sprintf(name, "a%d", a);
+ else
+ name[0] = '\0';
+
+ generateNamedBaseType(scope, ad, name, use_typename, fp);
+ }
+}
+
+
+/*
+ * Generate typed arguments for a call.
+ */
+static void generateCallArgs(signatureDef *sd, signatureDef *py_sd, FILE *fp)
+{
+ int a;
+
+ for (a = 0; a < sd->nrArgs; ++a)
+ {
+ char *ind = NULL;
+ argDef *ad, *py_ad;
+
+ if (a > 0)
+ prcode(fp,",");
+
+ ad = &sd->args[a];
+
+ /* See if the argument needs dereferencing or it's address taking. */
+ switch (ad->atype)
+ {
+ case ascii_string_type:
+ case latin1_string_type:
+ case utf8_string_type:
+ case sstring_type:
+ case ustring_type:
+ case string_type:
+ case wstring_type:
+ if (ad->nrderefs > (isOutArg(ad) ? 0 : 1))
+ ind = "&";
+
+ break;
+
+ case mapped_type:
+ case class_type:
+ if (ad->nrderefs == 2)
+ ind = "&";
+ else if (ad->nrderefs == 0)
+ ind = "*";
+
+ break;
+
+ case struct_type:
+ case void_type:
+ if (ad->nrderefs == 2)
+ ind = "&";
+
+ break;
+
+ default:
+ if (ad->nrderefs == 1)
+ ind = "&";
+ }
+
+ if (ind != NULL)
+ prcode(fp, ind);
+
+ /*
+ * See if we need to cast a Python void * to the correct C/C++ pointer
+ * type.
+ */
+ if (py_sd != sd)
+ {
+ py_ad = &py_sd->args[a];
+
+ if (py_ad->atype != void_type || ad->atype == void_type || py_ad->nrderefs != ad->nrderefs)
+ py_ad = NULL;
+ }
+ else
+ py_ad = NULL;
+
+ if (py_ad == NULL)
+ {
+ if (isArraySize(ad))
+ prcode(fp, "(%b)", ad);
+
+ prcode(fp, "a%d", a);
+ }
+ else if (generating_c)
+ prcode(fp, "(%b *)a%d", ad, a);
+ else
+ prcode(fp, "reinterpret_cast<%b *>(a%d)", ad, a);
+ }
+}
+
+
+/*
+ * Generate the declaration of a named variable to hold a result from a C++
+ * function call.
+ */
+static void generateNamedValueType(ifaceFileDef *scope, argDef *ad,
+ char *name, FILE *fp)
+{
+ argDef mod = *ad;
+
+ if (ad->nrderefs == 0)
+ {
+ if (ad->atype == class_type || ad->atype == mapped_type)
+ mod.nrderefs = 1;
+ else
+ resetIsConstArg(&mod);
+ }
+
+ resetIsReference(&mod);
+ generateNamedBaseType(scope, &mod, name, TRUE, fp);
+}
+
+
+/*
+ * Generate a C++ type.
+ */
+static void generateBaseType(ifaceFileDef *scope, argDef *ad,
+ int use_typename, FILE *fp)
+{
+ generateNamedBaseType(scope, ad, "", use_typename, fp);
+}
+
+
+/*
+ * Generate a C++ type and name.
+ */
+static void generateNamedBaseType(ifaceFileDef *scope, argDef *ad, char *name,
+ int use_typename, FILE *fp)
+{
+ typedefDef *td = ad->original_type;
+ int nr_derefs = ad->nrderefs;
+ int is_reference = isReference(ad);
+
+ if (use_typename && td != NULL && !noTypeName(td) && !isArraySize(ad))
+ {
+ if (isConstArg(ad) && !isConstArg(&td->type))
+ prcode(fp, "const ");
+
+ nr_derefs -= td->type.nrderefs;
+
+ if (isReference(&td->type))
+ is_reference = FALSE;
+
+ prcode(fp, "%S", td->fqname);
+ }
+ else
+ {
+ /*
+ * A function type is handled differently because of the position of
+ * the name.
+ */
+ if (ad->atype == function_type)
+ {
+ int i;
+ signatureDef *sig = ad->u.sa;
+
+ generateBaseType(scope, &sig->result, TRUE, fp);
+
+ prcode(fp," (");
+
+ for (i = 0; i < nr_derefs; ++i)
+ prcode(fp, "*");
+
+ prcode(fp, "%s)(",name);
+ generateCalledArgs(scope, sig, Declaration, use_typename, fp);
+ prcode(fp, ")");
+
+ return;
+ }
+
+ if (isConstArg(ad))
+ prcode(fp, "const ");
+
+ switch (ad->atype)
+ {
+ case sstring_type:
+ prcode(fp, "signed char");
+ break;
+
+ case ustring_type:
+ prcode(fp, "unsigned char");
+ break;
+
+ case wstring_type:
+ prcode(fp, "wchar_t");
+ break;
+
+ case signal_type:
+ case slot_type:
+ case anyslot_type:
+ case slotcon_type:
+ case slotdis_type:
+ nr_derefs = 1;
+
+ /* Drop through. */
+
+ case ascii_string_type:
+ case latin1_string_type:
+ case utf8_string_type:
+ case string_type:
+ prcode(fp, "char");
+ break;
+
+ case ushort_type:
+ prcode(fp, "unsigned short");
+ break;
+
+ case short_type:
+ prcode(fp, "short");
+ break;
+
+ case uint_type:
+ prcode(fp, "unsigned");
+ break;
+
+ case int_type:
+ case cint_type:
+ prcode(fp, "int");
+ break;
+
+ case ssize_type:
+ prcode(fp, "SIP_SSIZE_T");
+ break;
+
+ case ulong_type:
+ prcode(fp, "unsigned long");
+ break;
+
+ case long_type:
+ prcode(fp, "long");
+ break;
+
+ case ulonglong_type:
+ prcode(fp, "unsigned PY_LONG_LONG");
+ break;
+
+ case longlong_type:
+ prcode(fp, "PY_LONG_LONG");
+ break;
+
+ case struct_type:
+ prcode(fp, "struct %S", ad->u.sname);
+ break;
+
+ case fake_void_type:
+ case void_type:
+ prcode(fp, "void");
+ break;
+
+ case bool_type:
+ case cbool_type:
+ prcode(fp, "bool");
+ break;
+
+ case float_type:
+ case cfloat_type:
+ prcode(fp, "float");
+ break;
+
+ case double_type:
+ case cdouble_type:
+ prcode(fp, "double");
+ break;
+
+ case defined_type:
+ /*
+ * The only defined types still remaining are arguments to
+ * templates and default values.
+ */
+ if (prcode_xml)
+ prScopedName(fp, ad->u.snd, ".");
+ else
+ prcode(fp, "%S", ad->u.snd);
+ break;
+
+ case rxcon_type:
+ case rxdis_type:
+ nr_derefs = 1;
+ prcode(fp, "QObject");
+ break;
+
+ case mapped_type:
+ generateBaseType(scope, &ad->u.mtd->type, TRUE, fp);
+ break;
+
+ case class_type:
+ prcode(fp, "%V", scope, ad->u.cd);
+ break;
+
+ case template_type:
+ {
+ static const char tail[] = ">";
+ int a;
+ templateDef *td = ad->u.td;
+
+ prcode(fp, "%S%s", td->fqname, (prcode_xml ? "&lt;" : "<"));
+
+ for (a = 0; a < td->types.nrArgs; ++a)
+ {
+ if (a > 0)
+ prcode(fp, ",");
+
+ generateBaseType(scope, &td->types.args[a], TRUE, fp);
+ }
+
+ if (prcode_last == tail)
+ prcode(fp, " ");
+
+ prcode(fp, (prcode_xml ? "&gt;" : tail));
+ break;
+ }
+
+ case enum_type:
+ prcode(fp, "%E", ad->u.ed);
+ break;
+
+ case pyobject_type:
+ case pytuple_type:
+ case pylist_type:
+ case pydict_type:
+ case pycallable_type:
+ case pyslice_type:
+ case pytype_type:
+ case qobject_type:
+ case ellipsis_type:
+ prcode(fp, "PyObject *");
+ break;
+ }
+ }
+
+ if (nr_derefs > 0)
+ {
+ int i;
+
+ prcode(fp, " ");
+
+ for (i = 0; i < nr_derefs; ++i)
+ prcode(fp, "*");
+ }
+
+ if (is_reference)
+ prcode(fp, (prcode_xml ? "&amp;" : "&"));
+
+ if (*name != '\0')
+ {
+ if (nr_derefs == 0)
+ prcode(fp, " ");
+
+ prcode(fp, name);
+ }
+}
+
+
+/*
+ * Generate the definition of an argument variable and any supporting
+ * variables.
+ */
+static void generateVariable(ifaceFileDef *scope, argDef *ad, int argnr,
+ FILE *fp)
+{
+ argType atype = ad->atype;
+ argDef orig;
+
+ if (isInArg(ad) && ad->defval != NULL &&
+ (atype == class_type || atype == mapped_type) &&
+ (ad->nrderefs == 0 || isReference(ad)))
+ {
+ /*
+ * Generate something to hold the default value as it cannot be
+ * assigned straight away.
+ */
+ prcode(fp,
+" %A a%ddef = ", scope, ad, argnr);
+
+ generateExpression(ad->defval, FALSE, fp);
+
+ prcode(fp,";\n"
+ );
+ }
+
+ /* Adjust the type so we have the type that will really handle it. */
+
+ orig = *ad;
+
+ switch (atype)
+ {
+ case ascii_string_type:
+ case latin1_string_type:
+ case utf8_string_type:
+ case sstring_type:
+ case ustring_type:
+ case string_type:
+ case wstring_type:
+ if (!isReference(ad))
+ {
+ if (ad->nrderefs == 2)
+ ad->nrderefs = 1;
+ else if (ad->nrderefs == 1 && isOutArg(ad))
+ ad->nrderefs = 0;
+ }
+
+ break;
+
+ case mapped_type:
+ case class_type:
+ case void_type:
+ case struct_type:
+ ad->nrderefs = 1;
+ break;
+
+ default:
+ ad->nrderefs = 0;
+ }
+
+ /* Array sizes are always SIP_SSIZE_T. */
+ if (isArraySize(ad))
+ ad->atype = ssize_type;
+
+ resetIsReference(ad);
+
+ if (ad->nrderefs == 0)
+ resetIsConstArg(ad);
+
+ prcode(fp,
+" %A a%d", scope, ad, argnr);
+
+ if (atype == anyslot_type)
+ prcode(fp, "Name");
+
+ *ad = orig;
+
+ generateDefaultValue(ad, argnr, fp);
+
+ prcode(fp,";\n"
+ );
+
+ /* Some types have supporting variables. */
+ if (isInArg(ad))
+ {
+ if (isGetWrapper(ad))
+ prcode(fp,
+" PyObject *a%dWrapper%s;\n"
+ , argnr, (ad->defval != NULL ? " = 0" : ""));
+ else if (keepReference(ad))
+ prcode(fp,
+" PyObject *a%dKeep%s;\n"
+ , argnr, (ad->defval != NULL ? " = 0" : ""));
+
+ switch (atype)
+ {
+ case class_type:
+ if (ad->u.cd->convtocode != NULL && !isConstrained(ad))
+ prcode(fp,
+" int a%dState = 0;\n"
+ ,argnr);
+
+ break;
+
+ case mapped_type:
+ if (!noRelease(ad->u.mtd) && !isConstrained(ad))
+ prcode(fp,
+" int a%dState = 0;\n"
+ ,argnr);
+
+ break;
+
+ case ascii_string_type:
+ case latin1_string_type:
+ case utf8_string_type:
+ if (!keepReference(ad) && ad->nrderefs == 1)
+ prcode(fp,
+" PyObject *a%dKeep%s;\n"
+ , argnr, (ad->defval != NULL ? " = 0" : ""));
+
+ break;
+
+ case anyslot_type:
+ prcode(fp,
+" PyObject *a%dCallable", argnr);
+ generateDefaultValue(ad, argnr, fp);
+ prcode(fp, ";\n"
+ );
+ break;
+ }
+ }
+}
+
+
+/*
+ * Generate a default value.
+ */
+static void generateDefaultValue(argDef *ad, int argnr, FILE *fp)
+{
+ if (isInArg(ad) && ad->defval != NULL)
+ {
+ prcode(fp," = ");
+
+ if ((ad->atype == class_type || ad->atype == mapped_type) &&
+ (ad->nrderefs == 0 || isReference(ad)))
+ prcode(fp, "&a%ddef", argnr);
+ else
+ generateExpression(ad->defval, FALSE, fp);
+ }
+}
+
+
+/*
+ * Generate a simple function call.
+ */
+static void generateSimpleFunctionCall(fcallDef *fcd,FILE *fp)
+{
+ int i;
+
+ prcode(fp, "%B(", &fcd->type);
+
+ for (i = 0; i < fcd->nrArgs; ++i)
+ {
+ if (i > 0)
+ prcode(fp,",");
+
+ generateExpression(fcd->args[i], FALSE, fp);
+ }
+
+ prcode(fp,")");
+}
+
+
+/*
+ * Generate the type structure that contains all the information needed by the
+ * meta-type. A sub-set of this is used to extend namespaces.
+ */
+static void generateTypeDefinition(sipSpec *pt, classDef *cd, FILE *fp)
+{
+ const char *mname, *sep, *type_prefix;
+ int is_slots, is_signals, nr_methods, nr_enums, nr_vars, embedded;
+ int is_inst_class, is_inst_voidp, is_inst_char, is_inst_string;
+ int is_inst_int, is_inst_long, is_inst_ulong, is_inst_longlong;
+ int is_inst_ulonglong, is_inst_double, has_docstring;
+ memberDef *md;
+ moduleDef *mod;
+
+ mod = cd->iff->module;
+ mname = mod->name;
+
+ if (cd->supers != NULL)
+ {
+ classList *cl;
+
+ prcode(fp,
+"\n"
+"\n"
+"/* Define this type's super-types. */\n"
+"static sipEncodedTypeDef supers_%C[] = {", classFQCName(cd));
+
+ for (cl = cd->supers; cl != NULL; cl = cl->next)
+ {
+ if (cl != cd->supers)
+ prcode(fp, ", ");
+
+ generateEncodedType(mod, cl->cd, (cl->next == NULL), fp);
+ }
+
+ prcode(fp,"};\n"
+ );
+ }
+
+ /* Generate the slots table. */
+ is_slots = FALSE;
+
+ for (md = cd->members; md != NULL; md = md->next)
+ {
+ const char *stype;
+
+ if (md->slot == no_slot)
+ continue;
+
+ if (!is_slots)
+ {
+ prcode(fp,
+"\n"
+"\n"
+"/* Define this type's Python slots. */\n"
+"static sipPySlotDef slots_%L[] = {\n"
+ , cd->iff);
+
+ is_slots = TRUE;
+ }
+
+ if ((stype = slotName(md->slot)) != NULL)
+ {
+ if (py2OnlySlot(md->slot))
+ prcode(fp,
+"#if PY_MAJOR_VERSION < 3\n"
+ );
+ else if (py2_5LaterSlot(md->slot))
+ prcode(fp,
+"#if PY_VERSION_HEX >= 0x02050000\n"
+ );
+
+ prcode(fp,
+" {(void *)slot_%L_%s, %s},\n"
+ , cd->iff, md->pyname->text, stype);
+
+ if (py2OnlySlot(md->slot) || py2_5LaterSlot(md->slot))
+ prcode(fp,
+"#endif\n"
+ );
+ }
+ }
+
+ if (is_slots)
+ prcode(fp,
+" {0, (sipPySlotType)0}\n"
+"};\n"
+ );
+
+ /* Generate the attributes tables. */
+ nr_methods = generateClassMethodTable(pt, cd, fp);
+ nr_enums = generateEnumMemberTable(pt, mod, cd, NULL, fp);
+
+ /* Generate the PyQt4 signals table. */
+ is_signals = FALSE;
+
+ if (pluginPyQt4(pt) && isQObjectSubClass(cd))
+ {
+ /* The signals must be grouped by name. */
+ for (md = cd->members; md != NULL; md = md->next)
+ {
+ overDef *od;
+ int membernr = md->membernr;
+
+ for (od = cd->overs; od != NULL; od = od->next)
+ {
+ int a, nr_args;
+
+ if (od->common != md || !isSignal(od))
+ continue;
+
+ if (membernr >= 0)
+ {
+ /* See if there is a non-signal overload. */
+
+ overDef *nsig;
+
+ for (nsig = cd->overs; nsig != NULL; nsig = nsig->next)
+ if (nsig != od && nsig->common == md && !isSignal(nsig))
+ break;
+
+ if (nsig == NULL)
+ membernr = -1;
+ }
+
+ if (!is_signals)
+ {
+ is_signals = TRUE;
+
+ prcode(fp,
+"\n"
+"\n"
+"/* Define this type's PyQt4 signals. */\n"
+"static const pyqt4QtSignal pyqt4_signals_%C[] = {\n"
+ , classFQCName(cd));
+ }
+
+ /*
+ * Default arguments are handled as multiple signals. We make
+ * sure the largest is first and the smallest last.
+ */
+ generateSignalTableEntry(pt, cd, od, md, membernr, fp);
+ membernr = -1;
+
+ nr_args = od->cppsig->nrArgs;
+
+ for (a = nr_args - 1; a >= 0; --a)
+ {
+ if (od->cppsig->args[a].defval == NULL)
+ break;
+
+ od->cppsig->nrArgs = a;
+ generateSignalTableEntry(pt, cd, od, md, -1, fp);
+ }
+
+ od->cppsig->nrArgs = nr_args;
+ }
+ }
+
+ if (is_signals)
+ prcode(fp,
+" {0, 0, 0}\n"
+"};\n"
+ );
+ }
+
+ /* Generate the variable handlers. */
+ nr_vars = 0;
+
+ if (hasVarHandlers(cd))
+ {
+ varDef *vd;
+
+ for (vd = pt->vars; vd != NULL; vd = vd->next)
+ if (vd->ecd == cd && needsHandler(vd))
+ {
+ ++nr_vars;
+
+ generateVariableGetter(cd->iff, vd, fp);
+
+ if (canSetVariable(vd))
+ generateVariableSetter(cd->iff, vd, fp);
+ }
+
+ /* Generate the variable table. */
+ prcode(fp,
+"\n"
+"sipVariableDef variables_%L[] = {\n"
+ , cd->iff);
+
+ for (vd = pt->vars; vd != NULL; vd = vd->next)
+ if (vd->ecd == cd && needsHandler(vd))
+ {
+ prcode(fp,
+" {%N, varget_%C, ", vd->pyname, vd->fqcname);
+
+ if (canSetVariable(vd))
+ prcode(fp, "varset_%C", vd->fqcname);
+ else
+ prcode(fp, "NULL");
+
+ prcode(fp, ", %d},\n"
+ , (isStaticVar(vd) ? 1 : 0));
+ }
+
+ prcode(fp,
+"};\n"
+ );
+ }
+
+ /* Generate each instance table. */
+ is_inst_class = generateClasses(pt, mod, cd, fp);
+ is_inst_voidp = generateVoidPointers(pt, mod, cd, fp);
+ is_inst_char = generateChars(pt, mod, cd, fp);
+ is_inst_string = generateStrings(pt, mod, cd, fp);
+ is_inst_int = generateInts(pt, mod, cd, fp);
+ is_inst_long = generateLongs(pt, mod, cd, fp);
+ is_inst_ulong = generateUnsignedLongs(pt, mod, cd, fp);
+ is_inst_longlong = generateLongLongs(pt, mod, cd, fp);
+ is_inst_ulonglong = generateUnsignedLongLongs(pt, mod, cd, fp);
+ is_inst_double = generateDoubles(pt, mod, cd, fp);
+
+ /* Generate the docstrings. */
+ has_docstring = FALSE;
+
+ if (cd->docstring != NULL || (docstrings && hasClassDocstring(pt, cd)))
+ {
+ prcode(fp,
+"\n"
+"PyDoc_STRVAR(doc_%L, ", cd->iff);
+
+ if (cd->docstring != NULL)
+ generateExplicitDocstring(cd->docstring, fp);
+ else
+ generateClassDocstring(pt, cd, fp);
+
+ prcode(fp, ");\n"
+ );
+
+ has_docstring = TRUE;
+ }
+
+ if (pluginPyQt4(pt))
+ {
+ type_prefix = "pyqt4";
+ embedded = TRUE;
+ }
+ else if (pluginPyQt3(pt))
+ {
+ type_prefix = "pyqt3";
+ embedded = TRUE;
+ }
+ else
+ {
+ type_prefix = "sip";
+ embedded = FALSE;
+ }
+
+ prcode(fp,
+"\n"
+"\n"
+"%sClassTypeDef ", type_prefix);
+
+ generateTypeDefName(cd->iff, fp);
+
+ prcode(fp, " = {\n"
+"%s"
+" {\n"
+" %P,\n"
+" "
+ , (embedded ? "{\n" : "")
+ , cd->iff->api_range);
+
+ generateTypeDefLink(pt, cd->iff, fp);
+
+ prcode(fp, ",\n"
+" 0,\n"
+" ");
+
+ sep = "";
+
+ if (isAbstractClass(cd))
+ {
+ prcode(fp, "%sSIP_TYPE_ABSTRACT", sep);
+ sep = "|";
+ }
+
+ if (cd->subbase != NULL)
+ {
+ prcode(fp, "%sSIP_TYPE_SCC", sep);
+ sep = "|";
+ }
+
+ if (classHandlesNone(cd))
+ {
+ prcode(fp, "%sSIP_TYPE_ALLOW_NONE", sep);
+ sep = "|";
+ }
+
+ if (cd->iff->type == namespace_iface)
+ {
+ prcode(fp, "%sSIP_TYPE_NAMESPACE", sep);
+ sep = "|";
+ }
+ else
+ {
+ prcode(fp, "%sSIP_TYPE_CLASS", sep);
+ sep = "|";
+ }
+
+ if (*sep == '\0')
+ prcode(fp, "0");
+
+ prcode(fp, ",\n");
+
+ prcode(fp,
+" %n,\n"
+" {0}\n"
+" },\n"
+" {\n"
+ , cd->iff->name);
+
+ if (cd->real == NULL)
+ prcode(fp,
+" %n,\n"
+ , cd->pyname);
+ else
+ prcode(fp,
+" -1,\n"
+ );
+
+ prcode(fp, " ");
+
+ if (cd->real != NULL)
+ generateEncodedType(mod, cd->real, 0, fp);
+ else if (cd->ecd != NULL)
+ generateEncodedType(mod, cd->ecd, 0, fp);
+ else
+ prcode(fp, "{0, 0, 1}");
+
+ prcode(fp, ",\n"
+ );
+
+ if (nr_methods == 0)
+ prcode(fp,
+" 0, 0,\n"
+ );
+ else
+ prcode(fp,
+" %d, methods_%L,\n"
+ , nr_methods, cd->iff);
+
+ if (nr_enums == 0)
+ prcode(fp,
+" 0, 0,\n"
+ );
+ else
+ prcode(fp,
+" %d, enummembers_%L,\n"
+ , nr_enums, cd->iff);
+
+ if (nr_vars == 0)
+ prcode(fp,
+" 0, 0,\n"
+ );
+ else
+ prcode(fp,
+" %d, variables_%L,\n"
+ , nr_vars, cd->iff);
+
+ prcode(fp,
+" {");
+
+ if (is_inst_class)
+ prcode(fp, "typeInstances_%C, ", classFQCName(cd));
+ else
+ prcode(fp, "0, ");
+
+ if (is_inst_voidp)
+ prcode(fp, "voidPtrInstances_%C, ", classFQCName(cd));
+ else
+ prcode(fp, "0, ");
+
+ if (is_inst_char)
+ prcode(fp, "charInstances_%C, ", classFQCName(cd));
+ else
+ prcode(fp, "0, ");
+
+ if (is_inst_string)
+ prcode(fp, "stringInstances_%C, ", classFQCName(cd));
+ else
+ prcode(fp, "0, ");
+
+ if (is_inst_int)
+ prcode(fp, "intInstances_%C, ", classFQCName(cd));
+ else
+ prcode(fp, "0, ");
+
+ if (is_inst_long)
+ prcode(fp, "longInstances_%C, ", classFQCName(cd));
+ else
+ prcode(fp, "0, ");
+
+ if (is_inst_ulong)
+ prcode(fp, "unsignedLongInstances_%C, ", classFQCName(cd));
+ else
+ prcode(fp, "0, ");
+
+ if (is_inst_longlong)
+ prcode(fp, "longLongInstances_%C, ", classFQCName(cd));
+ else
+ prcode(fp,"0, ");
+
+ if (is_inst_ulonglong)
+ prcode(fp, "unsignedLongLongInstances_%C, ", classFQCName(cd));
+ else
+ prcode(fp, "0, ");
+
+ if (is_inst_double)
+ prcode(fp, "doubleInstances_%C", classFQCName(cd));
+ else
+ prcode(fp, "0");
+
+ prcode(fp,"},\n"
+" },\n"
+ );
+
+ if (has_docstring)
+ prcode(fp,
+" doc_%L,\n"
+ , cd->iff);
+ else
+ prcode(fp,
+" 0,\n"
+ );
+
+ if (cd->metatype != NULL)
+ prcode(fp,
+" %n,\n"
+ , cd->metatype);
+ else
+ prcode(fp,
+" -1,\n"
+ );
+
+ if (cd->supertype != NULL)
+ prcode(fp,
+" %n,\n"
+ , cd->supertype);
+ else
+ prcode(fp,
+" -1,\n"
+ );
+
+ if (cd->supers != NULL)
+ prcode(fp,
+" supers_%C,\n"
+ , classFQCName(cd));
+ else
+ prcode(fp,
+" 0,\n"
+ );
+
+ if (is_slots)
+ prcode(fp,
+" slots_%L,\n"
+ , cd->iff);
+ else
+ prcode(fp,
+" 0,\n"
+ );
+
+ if (canCreate(cd))
+ prcode(fp,
+" init_%L,\n"
+ , cd->iff);
+ else
+ prcode(fp,
+" 0,\n"
+ );
+
+ if (cd->travcode != NULL)
+ prcode(fp,
+" traverse_%C,\n"
+ , classFQCName(cd));
+ else
+ prcode(fp,
+" 0,\n"
+ );
+
+ if (cd->clearcode != NULL)
+ prcode(fp,
+" clear_%C,\n"
+ , classFQCName(cd));
+ else
+ prcode(fp,
+" 0,\n"
+ );
+
+ prcode(fp,
+"#if PY_MAJOR_VERSION >= 3\n"
+ );
+
+ if (cd->getbufcode != NULL)
+ prcode(fp,
+" getbuffer_%C,\n"
+ , classFQCName(cd));
+ else
+ prcode(fp,
+" 0,\n"
+ );
+
+ if (cd->releasebufcode != NULL)
+ prcode(fp,
+" releasebuffer_%C,\n"
+ , classFQCName(cd));
+ else
+ prcode(fp,
+" 0,\n"
+ );
+
+ prcode(fp,
+"#else\n"
+ );
+
+ if (cd->readbufcode != NULL)
+ prcode(fp,
+" getreadbuffer_%C,\n"
+ , classFQCName(cd));
+ else
+ prcode(fp,
+" 0,\n"
+ );
+
+ if (cd->writebufcode != NULL)
+ prcode(fp,
+" getwritebuffer_%C,\n"
+ , classFQCName(cd));
+ else
+ prcode(fp,
+" 0,\n"
+ );
+
+ if (cd->segcountcode != NULL)
+ prcode(fp,
+" getsegcount_%C,\n"
+ , classFQCName(cd));
+ else
+ prcode(fp,
+" 0,\n"
+ );
+
+ if (cd->charbufcode != NULL)
+ prcode(fp,
+" getcharbuffer_%C,\n"
+ , classFQCName(cd));
+ else
+ prcode(fp,
+" 0,\n"
+ );
+
+ prcode(fp,
+"#endif\n"
+ );
+
+ if (needDealloc(cd))
+ prcode(fp,
+" dealloc_%L,\n"
+ , cd->iff);
+ else
+ prcode(fp,
+" 0,\n"
+ );
+
+ if (generating_c || assignmentHelper(cd))
+ prcode(fp,
+" assign_%L,\n"
+" array_%L,\n"
+" copy_%L,\n"
+ , cd->iff
+ , cd->iff
+ , cd->iff);
+ else
+ prcode(fp,
+" 0,\n"
+" 0,\n"
+" 0,\n"
+ );
+
+ if (cd->iff->type == namespace_iface || generating_c)
+ prcode(fp,
+" 0,\n"
+" 0,\n"
+ );
+ else
+ prcode(fp,
+" release_%L,\n"
+" cast_%L,\n"
+ , cd->iff
+ , cd->iff);
+
+ if (cd->iff->type == namespace_iface)
+ prcode(fp,
+" 0,\n"
+ );
+ else
+ {
+ if (cd->convtocode != NULL)
+ prcode(fp,
+" convertTo_%L,\n"
+ , cd->iff);
+ else
+ prcode(fp,
+" 0,\n"
+ );
+ }
+
+ prcode(fp,
+" 0,\n"
+ );
+
+ if (cd->picklecode != NULL)
+ prcode(fp,
+" pickle_%C\n"
+ , classFQCName(cd));
+ else
+ prcode(fp,
+" 0\n"
+ );
+
+ if (embedded)
+ prcode(fp,
+"},\n"
+ );
+
+ if (pluginPyQt3(pt))
+ {
+ if (hasSigSlots(cd))
+ prcode(fp,
+" signals_%C\n"
+ , classFQCName(cd));
+ else
+ prcode(fp,
+" 0\n"
+ );
+ }
+
+ if (pluginPyQt4(pt))
+ {
+ if (isQObjectSubClass(cd) && !noPyQt4QMetaObject(cd))
+ prcode(fp,
+" &%U::staticMetaObject,\n"
+ , cd);
+ else
+ prcode(fp,
+" 0,\n"
+ );
+
+ prcode(fp,
+" %u,\n"
+ , cd->pyqt4_flags);
+
+ if (is_signals)
+ prcode(fp,
+" pyqt4_signals_%C\n"
+ , classFQCName(cd));
+ else
+ prcode(fp,
+" 0\n"
+ );
+ }
+
+ prcode(fp,
+"};\n"
+ );
+}
+
+
+/*
+ * Generate an entry in the PyQt4 signal table.
+ */
+static void generateSignalTableEntry(sipSpec *pt, classDef *cd, overDef *sig,
+ memberDef *md, int membernr, FILE *fp)
+{
+ prcode(fp,
+" {\"%s(", sig->cppname);
+
+ generateCalledArgs(cd->iff, sig->cppsig, Declaration, TRUE, fp);
+
+ prcode(fp,")\", ");
+
+ if (docstrings)
+ {
+ fprintf(fp, "\"\\1");
+ prScopedPythonName(fp, cd->ecd, cd->pyname->text);
+ fprintf(fp, ".%s", md->pyname->text);
+ prPythonSignature(pt, fp, &sig->pysig, FALSE, FALSE, FALSE, FALSE,
+ TRUE);
+ fprintf(fp, "\", ");
+ }
+ else
+ {
+ prcode(fp, "0, ");
+ }
+
+ if (membernr >= 0)
+ prcode(fp, "&methods_%L[%d]", cd->iff, membernr);
+ else
+ prcode(fp, "0");
+
+ prcode(fp,"},\n"
+ );
+}
+
+
+/*
+ * Return TRUE if the slot is specific to Python v2.
+ */
+static int py2OnlySlot(slotType st)
+{
+ /*
+ * Note that we place interpretations on div_slot and idiv_slot for Python
+ * v3 so they are not included.
+ */
+ return (st == long_slot || st == cmp_slot);
+}
+
+
+/*
+ * Return TRUE if the slot is specific to Python v2.5 and later.
+ */
+static int py2_5LaterSlot(slotType st)
+{
+ return (st == index_slot);
+}
+
+
+/*
+ * Return the sip module's string equivalent of a slot.
+ */
+static const char *slotName(slotType st)
+{
+ const char *sn;
+
+ switch (st)
+ {
+ case str_slot:
+ sn = "str_slot";
+ break;
+
+ case int_slot:
+ sn = "int_slot";
+ break;
+
+ case long_slot:
+ sn = "long_slot";
+ break;
+
+ case float_slot:
+ sn = "float_slot";
+ break;
+
+ case len_slot:
+ sn = "len_slot";
+ break;
+
+ case contains_slot:
+ sn = "contains_slot";
+ break;
+
+ case add_slot:
+ sn = "add_slot";
+ break;
+
+ case concat_slot:
+ sn = "concat_slot";
+ break;
+
+ case sub_slot:
+ sn = "sub_slot";
+ break;
+
+ case mul_slot:
+ sn = "mul_slot";
+ break;
+
+ case repeat_slot:
+ sn = "repeat_slot";
+ break;
+
+ case div_slot:
+ sn = "div_slot";
+ break;
+
+ case mod_slot:
+ sn = "mod_slot";
+ break;
+
+ case floordiv_slot:
+ sn = "floordiv_slot";
+ break;
+
+ case truediv_slot:
+ sn = "truediv_slot";
+ break;
+
+ case and_slot:
+ sn = "and_slot";
+ break;
+
+ case or_slot:
+ sn = "or_slot";
+ break;
+
+ case xor_slot:
+ sn = "xor_slot";
+ break;
+
+ case lshift_slot:
+ sn = "lshift_slot";
+ break;
+
+ case rshift_slot:
+ sn = "rshift_slot";
+ break;
+
+ case iadd_slot:
+ sn = "iadd_slot";
+ break;
+
+ case iconcat_slot:
+ sn = "iconcat_slot";
+ break;
+
+ case isub_slot:
+ sn = "isub_slot";
+ break;
+
+ case imul_slot:
+ sn = "imul_slot";
+ break;
+
+ case irepeat_slot:
+ sn = "irepeat_slot";
+ break;
+
+ case idiv_slot:
+ sn = "idiv_slot";
+ break;
+
+ case imod_slot:
+ sn = "imod_slot";
+ break;
+
+ case ifloordiv_slot:
+ sn = "ifloordiv_slot";
+ break;
+
+ case itruediv_slot:
+ sn = "itruediv_slot";
+ break;
+
+ case iand_slot:
+ sn = "iand_slot";
+ break;
+
+ case ior_slot:
+ sn = "ior_slot";
+ break;
+
+ case ixor_slot:
+ sn = "ixor_slot";
+ break;
+
+ case ilshift_slot:
+ sn = "ilshift_slot";
+ break;
+
+ case irshift_slot:
+ sn = "irshift_slot";
+ break;
+
+ case invert_slot:
+ sn = "invert_slot";
+ break;
+
+ case call_slot:
+ sn = "call_slot";
+ break;
+
+ case getitem_slot:
+ sn = "getitem_slot";
+ break;
+
+ case setitem_slot:
+ sn = "setitem_slot";
+ break;
+
+ case delitem_slot:
+ sn = "delitem_slot";
+ break;
+
+ case lt_slot:
+ sn = "lt_slot";
+ break;
+
+ case le_slot:
+ sn = "le_slot";
+ break;
+
+ case eq_slot:
+ sn = "eq_slot";
+ break;
+
+ case ne_slot:
+ sn = "ne_slot";
+ break;
+
+ case gt_slot:
+ sn = "gt_slot";
+ break;
+
+ case ge_slot:
+ sn = "ge_slot";
+ break;
+
+ case cmp_slot:
+ sn = "cmp_slot";
+ break;
+
+ case bool_slot:
+ sn = "bool_slot";
+ break;
+
+ case neg_slot:
+ sn = "neg_slot";
+ break;
+
+ case pos_slot:
+ sn = "pos_slot";
+ break;
+
+ case abs_slot:
+ sn = "abs_slot";
+ break;
+
+ case repr_slot:
+ sn = "repr_slot";
+ break;
+
+ case hash_slot:
+ sn = "hash_slot";
+ break;
+
+ case index_slot:
+ sn = "index_slot";
+ break;
+
+ case iter_slot:
+ sn = "iter_slot";
+ break;
+
+ case next_slot:
+ sn = "next_slot";
+ break;
+
+ default:
+ sn = NULL;
+ }
+
+ return sn;
+}
+
+
+/*
+ * Generate the initialisation function or cast operators for the type.
+ */
+static void generateTypeInit(classDef *cd, moduleDef *mod, FILE *fp)
+{
+ ctorDef *ct;
+ int need_self, need_owner;
+
+ /*
+ * See if we need to name the self and owner arguments so that we can
+ * avoid a compiler warning about an unused argument.
+ */
+ need_self = (generating_c || hasShadow(cd));
+ need_owner = generating_c;
+
+ for (ct = cd->ctors; ct != NULL; ct = ct->next)
+ {
+ if (usedInCode(ct->methodcode, "sipSelf"))
+ need_self = TRUE;
+
+ if (isResultTransferredCtor(ct))
+ need_owner = TRUE;
+ else
+ {
+ int a;
+
+ for (a = 0; a < ct->pysig.nrArgs; ++a)
+ if (isThisTransferred(&ct->pysig.args[a]))
+ {
+ need_owner = TRUE;
+ break;
+ }
+ }
+ }
+
+ prcode(fp,
+"\n"
+"\n"
+ );
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static void *init_%L(sipSimpleWrapper *, PyObject *, PyObject *, PyObject **, PyObject **, PyObject **);}\n"
+ , cd->iff);
+
+ prcode(fp,
+"static void *init_%L(sipSimpleWrapper *%s, PyObject *sipArgs, PyObject *sipKwds, PyObject **sipUnused, PyObject **%s, PyObject **sipParseErr)\n"
+"{\n"
+ , cd->iff, (need_self ? "sipSelf" : ""), (need_owner ? "sipOwner" : ""));
+
+ if (hasShadow(cd))
+ prcode(fp,
+" sip%C *sipCpp = 0;\n"
+ ,classFQCName(cd));
+ else
+ prcode(fp,
+" %U *sipCpp = 0;\n"
+ ,cd);
+
+ if (tracing)
+ prcode(fp,
+"\n"
+" sipTrace(SIP_TRACE_INITS,\"init_%L()\\n\");\n"
+ , cd->iff);
+
+ /*
+ * Generate the code that parses the Python arguments and calls the
+ * correct constructor.
+ */
+ for (ct = cd->ctors; ct != NULL; ct = ct->next)
+ {
+ int needSecCall, error_flag, old_error_flag;
+ apiVersionRangeDef *avr;
+
+ if (isPrivateCtor(ct))
+ continue;
+
+ avr = ct->api_range;
+
+ prcode(fp,
+"\n"
+ );
+
+ if (avr != NULL)
+ prcode(fp,
+" if (sipIsAPIEnabled(%N, %d, %d))\n"
+ , avr->api_name, avr->from, avr->to);
+
+ prcode(fp,
+" {\n"
+ );
+
+ if (ct->methodcode != NULL)
+ {
+ error_flag = needErrorFlag(ct->methodcode);
+ old_error_flag = needOldErrorFlag(ct->methodcode);
+ }
+ else
+ {
+ error_flag = old_error_flag = FALSE;
+ }
+
+ needSecCall = generateArgParser(&ct->pysig, cd, NULL, ct, NULL, FALSE,
+ fp);
+ generateConstructorCall(cd, ct, error_flag, old_error_flag, mod, fp);
+
+ if (needSecCall)
+ {
+ prcode(fp,
+" }\n"
+"\n"
+ );
+
+ if (avr != NULL)
+ prcode(fp,
+" if (sipIsAPIEnabled(%N, %d, %d))\n"
+ , avr->api_name, avr->from, avr->to);
+
+ prcode(fp,
+" {\n"
+ );
+
+ generateArgParser(&ct->pysig, cd, NULL, ct, NULL, TRUE, fp);
+ generateConstructorCall(cd, ct, error_flag, old_error_flag, mod,
+ fp);
+ }
+
+ prcode(fp,
+" }\n"
+ );
+ }
+
+ prcode(fp,
+"\n"
+" return NULL;\n"
+"}\n"
+ );
+}
+
+
+/*
+ * Count the number of virtual members in a class.
+ */
+static int countVirtuals(classDef *cd)
+{
+ int nrvirts;
+ virtOverDef *vod;
+
+ nrvirts = 0;
+
+ for (vod = cd->vmembers; vod != NULL; vod = vod->next)
+ if (!isPrivate(&vod->o))
+ ++nrvirts;
+
+ return nrvirts;
+}
+
+
+/*
+ * Generate the try block for a call.
+ */
+static void generateTry(throwArgs *ta,FILE *fp)
+{
+ /*
+ * Generate the block if there was no throw specifier, or a non-empty
+ * throw specifier.
+ */
+ if (exceptions && (ta == NULL || ta->nrArgs > 0))
+ prcode(fp,
+" try\n"
+" {\n"
+ );
+}
+
+
+/*
+ * Generate the catch blocks for a call.
+ */
+static void generateCatch(throwArgs *ta, signatureDef *sd, moduleDef *mod,
+ FILE *fp)
+{
+ /*
+ * Generate the block if there was no throw specifier, or a non-empty
+ * throw specifier.
+ */
+ if (exceptions && (ta == NULL || ta->nrArgs > 0))
+ {
+ prcode(fp,
+" }\n"
+ );
+
+ if (ta != NULL)
+ {
+ int a;
+
+ for (a = 0; a < ta->nrArgs; ++a)
+ generateCatchBlock(ta->args[a], sd, fp);
+ }
+ else if (mod->defexception != NULL)
+ {
+ generateCatchBlock(mod->defexception, sd, fp);
+ }
+
+ prcode(fp,
+" catch (...)\n"
+" {\n"
+ );
+
+ if (release_gil)
+ prcode(fp,
+" Py_BLOCK_THREADS\n"
+"\n"
+ );
+
+ deleteOuts(sd, fp);
+ deleteTemps(sd, fp);
+
+ prcode(fp,
+" sipRaiseUnknownException();\n"
+" return NULL;\n"
+" }\n"
+ );
+ }
+}
+
+
+/*
+ * Generate a single catch block.
+ */
+static void generateCatchBlock(exceptionDef *xd, signatureDef *sd, FILE *fp)
+{
+ scopedNameDef *ename = xd->iff->fqcname;
+
+ prcode(fp,
+" catch (%S &%s)\n"
+" {\n"
+ ,ename,(xd->cd != NULL || usedInCode(xd->raisecode, "sipExceptionRef")) ? "sipExceptionRef" : "");
+
+ if (release_gil)
+ prcode(fp,
+"\n"
+" Py_BLOCK_THREADS\n"
+ );
+
+ deleteOuts(sd, fp);
+ deleteTemps(sd, fp);
+
+ /* See if the exception is a wrapped class. */
+ if (xd->cd != NULL)
+ prcode(fp,
+" /* Hope that there is a valid copy ctor. */\n"
+" %S *sipExceptionCopy = new %S(sipExceptionRef);\n"
+"\n"
+" sipRaiseTypeException(sipType_%C,sipExceptionCopy);\n"
+ , ename, ename
+ , ename);
+ else
+ generateCppCodeBlock(xd->raisecode, fp);
+
+ prcode(fp,
+"\n"
+" return NULL;\n"
+" }\n"
+ );
+}
+
+
+/*
+ * Generate a throw specifier.
+ */
+static void generateThrowSpecifier(throwArgs *ta,FILE *fp)
+{
+ if (exceptions && ta != NULL)
+ {
+ int a;
+
+ prcode(fp," throw(");
+
+ for (a = 0; a < ta->nrArgs; ++a)
+ {
+ if (a > 0)
+ prcode(fp,",");
+
+ prcode(fp,"%S",ta->args[a]->iff->fqcname);
+ }
+
+ prcode(fp,")");
+ }
+}
+
+
+/*
+ * Generate a single constructor call.
+ */
+static void generateConstructorCall(classDef *cd, ctorDef *ct, int error_flag,
+ int old_error_flag, moduleDef *mod, FILE *fp)
+{
+ prcode(fp,
+" {\n"
+ );
+
+ if (error_flag)
+ prcode(fp,
+" sipErrorState sipError = sipErrorNone;\n"
+"\n"
+ );
+ else if (old_error_flag)
+ prcode(fp,
+" int sipIsErr = 0;\n"
+"\n"
+ );
+
+ if (isDeprecatedCtor(ct))
+ /* Note that any temporaries will leak if an exception is raised. */
+ prcode(fp,
+" if (sipDeprecated(%N,NULL) < 0)\n"
+" return NULL;\n"
+"\n"
+ , cd->pyname);
+
+ /* Call any pre-hook. */
+ if (ct->prehook != NULL)
+ prcode(fp,
+" sipCallHook(\"%s\");\n"
+"\n"
+ ,ct->prehook);
+
+ if (ct->methodcode != NULL)
+ generateCppCodeBlock(ct->methodcode,fp);
+ else if (generating_c)
+ prcode(fp,
+" sipCpp = sipMalloc(sizeof (%S));\n"
+ ,classFQCName(cd));
+ else
+ {
+ int rgil = ((release_gil || isReleaseGILCtor(ct)) && !isHoldGILCtor(ct));
+
+ if (rgil)
+ prcode(fp,
+" Py_BEGIN_ALLOW_THREADS\n"
+ );
+
+ generateTry(ct->exceptions,fp);
+
+ if (hasShadow(cd))
+ prcode(fp,
+" sipCpp = new sip%C(",classFQCName(cd));
+ else
+ prcode(fp,
+" sipCpp = new %U(",cd);
+
+ if (isCastCtor(ct))
+ {
+ classDef *ocd;
+
+ /* We have to fiddle the type to generate the correct code. */
+ ocd = ct->pysig.args[0].u.cd;
+ ct->pysig.args[0].u.cd = cd;
+ prcode(fp, "a0->operator %B()", &ct->pysig.args[0]);
+ ct->pysig.args[0].u.cd = ocd;
+ }
+ else
+ generateCallArgs(ct->cppsig, &ct->pysig, fp);
+
+ prcode(fp,");\n"
+ );
+
+ generateCatch(ct->exceptions, &ct->pysig, mod, fp);
+
+ if (rgil)
+ prcode(fp,
+" Py_END_ALLOW_THREADS\n"
+ );
+
+ /*
+ * This is a bit of a hack to say we want the result transferred. We
+ * don't simply call sipTransferTo() because the wrapper object hasn't
+ * been fully initialised yet.
+ */
+ if (isResultTransferredCtor(ct))
+ prcode(fp,
+"\n"
+" *sipOwner = Py_None;\n"
+ );
+ }
+
+ gc_ellipsis(&ct->pysig, fp);
+
+ deleteTemps(&ct->pysig, fp);
+
+ prcode(fp,
+"\n"
+ );
+
+ if (error_flag)
+ {
+ prcode(fp,
+" if (sipError == sipErrorNone)\n"
+ );
+
+ if (hasShadow(cd) || ct->posthook != NULL)
+ prcode(fp,
+" {\n"
+ );
+
+ if (hasShadow(cd))
+ prcode(fp,
+" sipCpp->sipPySelf = sipSelf;\n"
+"\n"
+ );
+
+ /* Call any post-hook. */
+ if (ct->posthook != NULL)
+ prcode(fp,
+" sipCallHook(\"%s\");\n"
+"\n"
+ , ct->posthook);
+
+ prcode(fp,
+" return sipCpp;\n"
+ );
+
+ if (hasShadow(cd) || ct->posthook != NULL)
+ prcode(fp,
+" }\n"
+ );
+
+ prcode(fp,
+"\n"
+" if (sipUnused)\n"
+" {\n"
+" Py_XDECREF(*sipUnused);\n"
+" }\n"
+"\n"
+" sipAddException(sipError, sipParseErr);\n"
+"\n"
+" if (sipError == sipErrorFail)\n"
+" return NULL;\n"
+ );
+ }
+ else
+ {
+ if (old_error_flag)
+ {
+ prcode(fp,
+" if (sipIsErr)\n"
+" {\n"
+" if (sipUnused)\n"
+" {\n"
+" Py_XDECREF(*sipUnused);\n"
+" }\n"
+"\n"
+" sipAddException(sipErrorFail, sipParseErr);\n"
+" return NULL;\n"
+" }\n"
+"\n"
+ );
+ }
+
+ if (hasShadow(cd))
+ prcode(fp,
+" sipCpp->sipPySelf = sipSelf;\n"
+"\n"
+ );
+
+ /* Call any post-hook. */
+ if (ct->posthook != NULL)
+ prcode(fp,
+" sipCallHook(\"%s\");\n"
+"\n"
+ , ct->posthook);
+
+ prcode(fp,
+" return sipCpp;\n"
+ );
+ }
+
+ prcode(fp,
+" }\n"
+ );
+}
+
+
+/*
+ * See if a member overload should be skipped.
+ */
+static int skipOverload(overDef *od,memberDef *md,classDef *cd,classDef *ccd,
+ int want_local)
+{
+ /* Skip if it's not the right name. */
+ if (od->common != md)
+ return TRUE;
+
+ /* Skip if it's a signal. */
+ if (isSignal(od))
+ return TRUE;
+
+ /* Skip if it's a private abstract. */
+ if (isAbstract(od) && isPrivate(od))
+ return TRUE;
+
+ /*
+ * If we are disallowing them, skip if it's not in the current class
+ * unless it is protected.
+ */
+ if (want_local && !isProtected(od) && ccd != cd)
+ return TRUE;
+
+ return FALSE;
+}
+
+
+/*
+ * Generate a class member function.
+ */
+static void generateFunction(sipSpec *pt, memberDef *md, overDef *overs,
+ classDef *cd, classDef *ocd, moduleDef *mod, FILE *fp)
+{
+ overDef *od;
+ int need_method, need_self, need_args, need_selfarg, need_orig_self, need_kwds;
+
+ /*
+ * Check that there is at least one overload that needs to be handled.
+ * See if we can avoid naming the "self" argument (and suppress a
+ * compiler warning). See if we need to remember if "self" was explicitly
+ * passed as an argument. See if we need to handle keyword arguments.
+ */
+ need_method = need_self = need_args = need_selfarg = need_orig_self = need_kwds = FALSE;
+
+ for (od = overs; od != NULL; od = od->next)
+ {
+ /*
+ * Skip protected methods if we don't have the means to handle
+ * them.
+ */
+ if (isProtected(od) && !hasShadow(cd))
+ continue;
+
+ if (!skipOverload(od,md,cd,ocd,TRUE))
+ {
+ need_method = TRUE;
+
+ if (!isPrivate(od))
+ {
+ need_args = TRUE;
+
+ if (!isStatic(od))
+ {
+ need_self = TRUE;
+
+ if (isAbstract(od))
+ need_orig_self = TRUE;
+ else if (isVirtual(od) || isVirtualReimp(od) || usedInCode(od->methodcode, "sipSelfWasArg"))
+ need_selfarg = TRUE;
+ }
+
+ if (useKeywordArgs(od))
+ need_kwds = TRUE;
+ }
+ }
+ }
+
+ if (need_method)
+ {
+ const char *pname = md->pyname->text;
+ int has_auto_docstring;
+
+ prcode(fp,
+"\n"
+"\n"
+ );
+
+ /* Generate the docstrings. */
+ has_auto_docstring = FALSE;
+
+ if (md->docstring != NULL || (docstrings && hasDocstring(pt, overs, md, cd->iff)))
+ {
+ prcode(fp,
+"PyDoc_STRVAR(doc_%L_%s, " , cd->iff, pname);
+
+ if (md->docstring != NULL)
+ {
+ generateExplicitDocstring(md->docstring, fp);
+ }
+ else
+ {
+ generateDocstring(pt, overs, md, cd->pyname->text, cd->ecd, fp);
+ has_auto_docstring = TRUE;
+ }
+
+ prcode(fp, ");\n"
+"\n"
+ );
+ }
+
+ if (!generating_c)
+ prcode(fp,
+"extern \"C\" {static PyObject *meth_%L_%s(PyObject *, PyObject *%s);}\n"
+ , cd->iff, pname, (noArgParser(md) || need_kwds ? ", PyObject *" : ""));
+
+ prcode(fp,
+"static PyObject *meth_%L_%s(PyObject *%s, PyObject *%s%s)\n"
+"{\n"
+ , cd->iff, pname, (need_self ? "sipSelf" : ""), (need_args ? "sipArgs" : ""), (noArgParser(md) || need_kwds ? ", PyObject *sipKwds" : ""));
+
+ if (tracing)
+ prcode(fp,
+" sipTrace(SIP_TRACE_METHODS,\"meth_%L_%s()\\n\");\n"
+"\n"
+ , cd->iff, pname);
+
+ if (!noArgParser(md))
+ {
+ if (need_args)
+ prcode(fp,
+" PyObject *sipParseErr = NULL;\n"
+ );
+
+ if (need_selfarg)
+ {
+ /*
+ * This determines if we call the explicitly scoped version or
+ * the unscoped version (which will then go via the vtable).
+ *
+ * - If the call was unbound and self was passed as the first
+ * argument (ie. Foo.meth(self)) then we always want to call
+ * the explicitly scoped version.
+ *
+ * - If the call was bound then we only call the unscoped
+ * version in case there is a C++ reimplementation that
+ * Python knows nothing about. Otherwise, if the call was
+ * invoked by super() within a Python reimplementation then
+ * the Python reimplementation would be called recursively.
+ */
+ prcode(fp,
+" bool sipSelfWasArg = (!sipSelf || sipIsDerived((sipSimpleWrapper *)sipSelf));\n"
+ );
+ }
+
+ if (need_orig_self)
+ {
+ /*
+ * This is similar to the above but for abstract methods. We
+ * allow the (potential) recursion because it means that the
+ * concrete implementation can be put in a mixin and it will
+ * all work.
+ */
+ prcode(fp,
+" PyObject *sipOrigSelf = sipSelf;\n"
+ );
+ }
+ }
+
+ for (od = overs; od != NULL; od = od->next)
+ {
+ /* If we are handling one variant then we must handle them all. */
+ if (skipOverload(od, md, cd, ocd, FALSE))
+ continue;
+
+ if (isPrivate(od))
+ continue;
+
+ if (noArgParser(md))
+ {
+ generateCppCodeBlock(od->methodcode, fp);
+ break;
+ }
+
+ generateFunctionBody(od, cd, NULL, ocd, TRUE, mod, fp);
+ }
+
+ if (!noArgParser(md))
+ {
+ prcode(fp,
+"\n"
+" /* Raise an exception if the arguments couldn't be parsed. */\n"
+" sipNoMethod(%s, %N, %N, ", (need_args ? "sipParseErr" : "NULL"), cd->pyname, md->pyname);
+
+ if (has_auto_docstring)
+ prcode(fp, "doc_%L_%s", cd->iff, pname);
+ else
+ prcode(fp, "NULL");
+
+ prcode(fp, ");\n"
+"\n"
+" return NULL;\n"
+ );
+ }
+
+ prcode(fp,
+"}\n"
+ );
+ }
+}
+
+
+/*
+ * Generate the function calls for a particular overload.
+ */
+static void generateFunctionBody(overDef *od, classDef *c_scope,
+ mappedTypeDef *mt_scope, classDef *ocd, int deref, moduleDef *mod,
+ FILE *fp)
+{
+ int needSecCall;
+ signatureDef saved;
+ ifaceFileDef *o_scope;
+ apiVersionRangeDef *avr;
+
+ if (mt_scope != NULL)
+ o_scope = mt_scope->iff;
+ else if (ocd != NULL)
+ o_scope = ocd->iff;
+ else
+ o_scope = NULL;
+
+ if (o_scope != NULL)
+ avr = od->api_range;
+ else
+ avr = NULL;
+
+ if (avr != NULL)
+ prcode(fp,
+"\n"
+" if (sipIsAPIEnabled(%N, %d, %d))\n"
+" {\n"
+ , avr->api_name, avr->from, avr->to);
+ else
+ prcode(fp,
+"\n"
+" {\n"
+ );
+
+ /* In case we have to fiddle with it. */
+ saved = od->pysig;
+
+ if (isNumberSlot(od->common))
+ {
+ /*
+ * Number slots must have two arguments because we parse them slightly
+ * differently.
+ */
+ if (od->pysig.nrArgs == 1)
+ {
+ od->pysig.nrArgs = 2;
+ od->pysig.args[1] = od->pysig.args[0];
+
+ /* Insert self in the right place. */
+ od->pysig.args[0].atype = class_type;
+ od->pysig.args[0].name = NULL;
+ od->pysig.args[0].argflags = ARG_IS_REF|ARG_IN;
+ od->pysig.args[0].nrderefs = 0;
+ od->pysig.args[0].defval = NULL;
+ od->pysig.args[0].original_type = NULL;
+ od->pysig.args[0].u.cd = ocd;
+ }
+
+ generateArgParser(&od->pysig, c_scope, mt_scope, NULL, od, FALSE, fp);
+ needSecCall = FALSE;
+ }
+ else if (isIntArgSlot(od->common) || isZeroArgSlot(od->common))
+ needSecCall = FALSE;
+ else
+ needSecCall = generateArgParser(&od->pysig, c_scope, mt_scope, NULL, od, FALSE, fp);
+
+ generateFunctionCall(c_scope, mt_scope, o_scope, od, deref, mod, fp);
+
+ if (needSecCall)
+ {
+ prcode(fp,
+" }\n"
+"\n"
+" {\n"
+ );
+
+ generateArgParser(&od->pysig, c_scope, mt_scope, NULL, od, TRUE, fp);
+ generateFunctionCall(c_scope, mt_scope, o_scope, od, deref, mod, fp);
+ }
+
+ prcode(fp,
+" }\n"
+ );
+
+ od->pysig = saved;
+}
+
+
+/*
+ * Generate the code to handle the result of a call to a member function.
+ */
+static void generateHandleResult(overDef *od, int isNew, int result_size,
+ char *prefix, FILE *fp)
+{
+ char *vname, vnamebuf[50];
+ int a, nrvals, only, has_owner;
+ argDef *res, *ad;
+
+ res = &od->pysig.result;
+
+ if (res->atype == void_type && res->nrderefs == 0)
+ res = NULL;
+
+ /* See if we are returning 0, 1 or more values. */
+ nrvals = 0;
+
+ if (res != NULL)
+ {
+ only = -1;
+ ++nrvals;
+ }
+
+ has_owner = FALSE;
+
+ for (a = 0; a < od->pysig.nrArgs; ++a)
+ {
+ if (isOutArg(&od->pysig.args[a]))
+ {
+ only = a;
+ ++nrvals;
+ }
+
+ if (isThisTransferred(&od->pysig.args[a]))
+ has_owner = TRUE;
+ }
+
+ /* Handle the trivial case. */
+ if (nrvals == 0)
+ {
+ prcode(fp,
+" Py_INCREF(Py_None);\n"
+" %s Py_None;\n"
+ ,prefix);
+
+ return;
+ }
+
+ /* Handle results that are classes or mapped types separately. */
+ if (res != NULL)
+ {
+ ifaceFileDef *iff;
+
+ if (res->atype == mapped_type)
+ iff = res->u.mtd->iff;
+ else if (res->atype == class_type)
+ iff = res->u.cd->iff;
+ else
+ iff = NULL;
+
+ if (iff != NULL)
+ {
+ if (isNew || isFactory(od))
+ {
+ prcode(fp,
+" %s sipConvertFromNewType(",(nrvals == 1 ? prefix : "PyObject *sipResObj ="));
+
+ if (isConstArg(res))
+ prcode(fp,"const_cast<%b *>(sipRes)",res);
+ else
+ prcode(fp,"sipRes");
+
+ prcode(fp,",sipType_%C,%s);\n"
+ , iff->fqcname, ((has_owner && isFactory(od)) ? "(PyObject *)sipOwner" : "NULL"));
+
+ /*
+ * Shortcut if this is the only value returned.
+ */
+ if (nrvals == 1)
+ return;
+ }
+ else
+ {
+ prcode(fp,
+" %s sipConvertFromType(",(nrvals == 1 ? prefix : "PyObject *sipResObj ="));
+
+ if (isConstArg(res))
+ prcode(fp,"const_cast<%b *>(sipRes)",res);
+ else
+ prcode(fp,"sipRes");
+
+ prcode(fp, ",sipType_%C,%s);\n"
+ , iff->fqcname, resultOwner(od));
+
+ /*
+ * Shortcut if this is the only value returned.
+ */
+ if (nrvals == 1)
+ return;
+ }
+ }
+ }
+
+ /* If there are multiple values then build a tuple. */
+ if (nrvals > 1)
+ {
+ prcode(fp,
+" %s sipBuildResult(0,\"(",prefix);
+
+ /* Build the format string. */
+ if (res != NULL)
+ prcode(fp, "%s", ((res->atype == mapped_type || res->atype == class_type) ? "R" : getBuildResultFormat(res)));
+
+ for (a = 0; a < od->pysig.nrArgs; ++a)
+ {
+ argDef *ad = &od->pysig.args[a];
+
+ if (isOutArg(ad))
+ prcode(fp, "%s", getBuildResultFormat(ad));
+ }
+
+ prcode(fp,")\"");
+
+ /* Pass the values for conversion. */
+ if (res != NULL)
+ {
+ prcode(fp, ",sipRes");
+
+ if (res->atype == mapped_type || res->atype == class_type)
+ prcode(fp, "Obj");
+ else if (res->atype == enum_type && res->u.ed->fqcname != NULL)
+ prcode(fp, ",sipType_%C", res->u.ed->fqcname);
+ }
+
+ for (a = 0; a < od->pysig.nrArgs; ++a)
+ {
+ argDef *ad = &od->pysig.args[a];
+
+ if (isOutArg(ad))
+ {
+ prcode(fp, ",a%d", a);
+
+ if (ad->atype == mapped_type)
+ prcode(fp, ",sipType_%T,%s", ad, (isTransferredBack(ad) ? "Py_None" : "NULL"));
+ else if (ad->atype == class_type)
+ prcode(fp, ",sipType_%C,%s", classFQCName(ad->u.cd), (isTransferredBack(ad) ? "Py_None" : "NULL"));
+ else if (ad->atype == enum_type && ad->u.ed->fqcname != NULL)
+ prcode(fp,",sipType_%C", ad->u.ed->fqcname);
+ }
+ }
+
+ prcode(fp,");\n"
+ );
+
+ /* All done for multiple values. */
+ return;
+ }
+
+ /* Deal with the only returned value. */
+ if (only < 0)
+ {
+ ad = res;
+ vname = "sipRes";
+ }
+ else
+ {
+ ad = &od->pysig.args[only];
+
+ sprintf(vnamebuf,"a%d",only);
+ vname = vnamebuf;
+ }
+
+ switch (ad->atype)
+ {
+ case mapped_type:
+ case class_type:
+ {
+ int needNew = needNewInstance(ad);
+ ifaceFileDef *iff;
+
+ if (ad->atype == mapped_type)
+ iff = ad->u.mtd->iff;
+ else
+ iff = ad->u.cd->iff;
+
+ prcode(fp,
+" %s sipConvertFrom%sType(", prefix, (needNew ? "New" : ""));
+
+ if (isConstArg(ad))
+ prcode(fp,"const_cast<%b *>(%s)",ad,vname);
+ else
+ prcode(fp,"%s",vname);
+
+ prcode(fp, ",sipType_%C,", iff->fqcname);
+
+ if (needNew || !isTransferredBack(ad))
+ prcode(fp, "NULL);\n");
+ else
+ prcode(fp, "Py_None);\n");
+ }
+
+ break;
+
+ case bool_type:
+ case cbool_type:
+ prcode(fp,
+" %s PyBool_FromLong(%s);\n"
+ ,prefix,vname);
+
+ break;
+
+ case ascii_string_type:
+ if (ad->nrderefs == 0)
+ prcode(fp,
+" %s PyUnicode_DecodeASCII(&%s, 1, NULL);\n"
+ , prefix, vname);
+ else
+ prcode(fp,
+" if (%s == NULL)\n"
+" {\n"
+" Py_INCREF(Py_None);\n"
+" return Py_None;\n"
+" }\n"
+"\n"
+" %s PyUnicode_DecodeASCII(%s, strlen(%s), NULL);\n"
+ , vname
+ , prefix, vname, vname);
+
+ break;
+
+ case latin1_string_type:
+ if (ad->nrderefs == 0)
+ prcode(fp,
+" %s PyUnicode_DecodeLatin1(&%s, 1, NULL);\n"
+ , prefix, vname);
+ else
+ prcode(fp,
+" if (%s == NULL)\n"
+" {\n"
+" Py_INCREF(Py_None);\n"
+" return Py_None;\n"
+" }\n"
+"\n"
+" %s PyUnicode_DecodeLatin1(%s, strlen(%s), NULL);\n"
+ , vname
+ , prefix, vname, vname);
+
+ break;
+
+ case utf8_string_type:
+ if (ad->nrderefs == 0)
+ prcode(fp,
+"#if PY_MAJOR_VERSION >= 3\n"
+" %s PyUnicode_FromStringAndSize(&%s, 1);\n"
+"#else\n"
+" %s PyUnicode_DecodeUTF8(&%s, 1, NULL);\n"
+"#endif\n"
+ , prefix, vname
+ , prefix, vname);
+ else
+ prcode(fp,
+" if (%s == NULL)\n"
+" {\n"
+" Py_INCREF(Py_None);\n"
+" return Py_None;\n"
+" }\n"
+"\n"
+"#if PY_MAJOR_VERSION >= 3\n"
+" %s PyUnicode_FromString(%s);\n"
+"#else\n"
+" %s PyUnicode_DecodeUTF8(%s, strlen(%s), NULL);\n"
+"#endif\n"
+ , vname
+ , prefix, vname
+ , prefix, vname, vname);
+
+ break;
+
+ case sstring_type:
+ case ustring_type:
+ case string_type:
+ if (ad->nrderefs == 0)
+ prcode(fp,
+" %s SIPBytes_FromStringAndSize(%s&%s,1);\n"
+ ,prefix,(ad->atype != string_type) ? "(char *)" : "",vname);
+ else
+ prcode(fp,
+" if (%s == NULL)\n"
+" {\n"
+" Py_INCREF(Py_None);\n"
+" return Py_None;\n"
+" }\n"
+"\n"
+" %s SIPBytes_FromString(%s%s);\n"
+ ,vname
+ ,prefix,(ad->atype != string_type) ? "(char *)" : "",vname);
+
+ break;
+
+ case wstring_type:
+ if (ad->nrderefs == 0)
+ prcode(fp,
+" %s PyUnicode_FromWideChar(&%s,1);\n"
+ , prefix, vname);
+ else
+ prcode(fp,
+" if (%s == NULL)\n"
+" {\n"
+" Py_INCREF(Py_None);\n"
+" return Py_None;\n"
+" }\n"
+"\n"
+" %s PyUnicode_FromWideChar(%s,(SIP_SSIZE_T)wcslen(%s));\n"
+ , vname
+ , prefix, vname, vname);
+
+ break;
+
+ case enum_type:
+ if (ad->u.ed->fqcname != NULL)
+ {
+ prcode(fp,
+" %s sipConvertFromEnum(%s,sipType_%C);\n"
+ , prefix, vname, ad->u.ed->fqcname);
+
+ break;
+ }
+
+ /* Drop through. */
+
+ case short_type:
+ case int_type:
+ case cint_type:
+ prcode(fp,
+" %s SIPLong_FromLong(%s);\n"
+ ,prefix,vname);
+
+ break;
+
+ case long_type:
+ prcode(fp,
+" %s PyLong_FromLong(%s);\n"
+ ,prefix,vname);
+
+ break;
+
+ case ushort_type:
+ case uint_type:
+ case ulong_type:
+ prcode(fp,
+" %s PyLong_FromUnsignedLong(%s);\n"
+ ,prefix,vname);
+
+ break;
+
+ case longlong_type:
+ prcode(fp,
+" %s PyLong_FromLongLong(%s);\n"
+ ,prefix,vname);
+
+ break;
+
+ case ulonglong_type:
+ prcode(fp,
+" %s PyLong_FromUnsignedLongLong(%s);\n"
+ ,prefix,vname);
+
+ break;
+
+ case void_type:
+ {
+ const char *cnst = (isConstArg(ad) ? "Const" : "");
+
+ if (result_size < 0)
+ prcode(fp,
+" %s sipConvertFrom%sVoidPtr(%s);\n"
+ , prefix, cnst, vname);
+ else
+ prcode(fp,
+" %s sipConvertFrom%sVoidPtrAndSize(%s,a%d);\n"
+ , prefix, cnst, vname, result_size);
+ }
+
+ break;
+
+ case struct_type:
+ prcode(fp,
+" %s sipConvertFrom%sVoidPtr(%s);\n"
+ , prefix, (isConstArg(ad) ? "Const" : ""), vname);
+ break;
+
+ case float_type:
+ case cfloat_type:
+ prcode(fp,
+" %s PyFloat_FromDouble((double)%s);\n"
+ ,prefix,vname);
+
+ break;
+
+ case double_type:
+ case cdouble_type:
+ prcode(fp,
+" %s PyFloat_FromDouble(%s);\n"
+ ,prefix,vname);
+
+ break;
+
+ case pyobject_type:
+ case pytuple_type:
+ case pylist_type:
+ case pydict_type:
+ case pycallable_type:
+ case pyslice_type:
+ case pytype_type:
+ prcode(fp,
+" %s %s;\n"
+ ,prefix,vname);
+
+ break;
+ }
+}
+
+
+/*
+ * Return the owner of a method result.
+ */
+static const char *resultOwner(overDef *od)
+{
+ if (isResultTransferredBack(od))
+ return "Py_None";
+
+ if (isResultTransferred(od))
+ return "sipSelf";
+
+ return "NULL";
+}
+
+
+/*
+ * Return the format string used by sipBuildResult() for a particular type.
+ */
+static const char *getBuildResultFormat(argDef *ad)
+{
+ switch (ad->atype)
+ {
+ case fake_void_type:
+ case mapped_type:
+ case class_type:
+ if (needNewInstance(ad))
+ return "N";
+
+ return "D";
+
+ case bool_type:
+ case cbool_type:
+ return "b";
+
+ case ascii_string_type:
+ return (ad->nrderefs > (isOutArg(ad) ? 1 : 0)) ? "AA" : "aA";
+
+ case latin1_string_type:
+ return (ad->nrderefs > (isOutArg(ad) ? 1 : 0)) ? "AL" : "aL";
+
+ case utf8_string_type:
+ return (ad->nrderefs > (isOutArg(ad) ? 1 : 0)) ? "A8" : "a8";
+
+ case sstring_type:
+ case ustring_type:
+ case string_type:
+ return (ad->nrderefs > (isOutArg(ad) ? 1 : 0)) ? "s" : "c";
+
+ case wstring_type:
+ return (ad->nrderefs > (isOutArg(ad) ? 1 : 0)) ? "x" : "w";
+
+ case enum_type:
+ return (ad->u.ed->fqcname != NULL) ? "F" : "e";
+
+ case short_type:
+ return "h";
+
+ case ushort_type:
+ return "t";
+
+ case int_type:
+ case cint_type:
+ return "i";
+
+ case uint_type:
+ return "u";
+
+ case long_type:
+ return "l";
+
+ case ulong_type:
+ return "m";
+
+ case longlong_type:
+ return "n";
+
+ case ulonglong_type:
+ return "o";
+
+ case void_type:
+ case struct_type:
+ return "V";
+
+ case float_type:
+ case cfloat_type:
+ return "f";
+
+ case double_type:
+ case cdouble_type:
+ return "d";
+
+ case pyobject_type:
+ case pytuple_type:
+ case pylist_type:
+ case pydict_type:
+ case pycallable_type:
+ case pyslice_type:
+ case pytype_type:
+ return "R";
+ }
+
+ /* We should never get here. */
+ return "";
+}
+
+
+/*
+ * Return TRUE if an argument (or result) should be copied because it is a
+ * const reference to a type.
+ */
+static int copyConstRefArg(argDef *ad)
+{
+ if (!noCopy(ad) && (ad->atype == class_type || ad->atype == mapped_type) && ad->nrderefs == 0)
+ {
+ /* Make a copy if it is not a reference or it is a const reference. */
+ if (!isReference(ad) || isConstArg(ad))
+ {
+ /* If it is a class then we must be able to copy it. */
+ if (ad->atype != class_type || !(cannotCopy(ad->u.cd) || isAbstractClass(ad->u.cd)))
+ {
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+
+/*
+ * Generate a function call.
+ */
+static void generateFunctionCall(classDef *c_scope, mappedTypeDef *mt_scope,
+ ifaceFileDef *o_scope, overDef *od, int deref, moduleDef *mod,
+ FILE *fp)
+{
+ int needsNew, error_flag, old_error_flag, newline, is_result, result_size,
+ a, deltemps;
+ const char *error_value;
+ argDef *res = &od->pysig.result, orig_res;
+ ifaceFileDef *scope;
+ nameDef *pyname;
+
+ if (mt_scope != NULL)
+ {
+ scope = mt_scope->iff;
+ pyname = mt_scope->pyname;
+ }
+ else if (c_scope != NULL)
+ {
+ scope = c_scope->iff;
+ pyname = c_scope->pyname;
+ }
+ else
+ {
+ scope = NULL;
+ pyname = NULL;
+ }
+
+ prcode(fp,
+" {\n"
+ );
+
+ /*
+ * If there is no shadow class then protected methods can never be
+ * called.
+ */
+ if (isProtected(od) && !hasShadow(c_scope))
+ {
+ prcode(fp,
+" /* Never reached. */\n"
+" }\n"
+ );
+
+ return;
+ }
+
+ /* Save the full result type as we may want to fiddle with it. */
+ orig_res = *res;
+
+ /* See if we need to make a copy of the result on the heap. */
+ needsNew = copyConstRefArg(res);
+
+ if (needsNew)
+ resetIsConstArg(res);
+
+ /* See if sipRes is needed. */
+ is_result = (!isInplaceNumberSlot(od->common) &&
+ !isInplaceSequenceSlot(od->common) &&
+ (res->atype != void_type || res->nrderefs != 0));
+
+ newline = FALSE;
+
+ if (is_result)
+ {
+ prcode(fp,
+" ");
+
+ generateNamedValueType(scope, res, "sipRes", fp);
+
+ /*
+ * The typical %MethodCode usually causes a compiler warning,
+ * so we initialise the result in that case to try and suppress
+ * it.
+ */
+ if (od->methodcode != NULL)
+ {
+ prcode(fp," = ");
+
+ generateCastZero(res,fp);
+ }
+
+ prcode(fp,";\n"
+ );
+
+ newline = TRUE;
+ }
+
+ result_size = -1;
+ deltemps = TRUE;
+
+ for (a = 0; a < od->pysig.nrArgs; ++a)
+ {
+ argDef *ad = &od->pysig.args[a];
+
+ if (isResultSize(ad))
+ result_size = a;
+
+ /*
+ * If we have an In,Out argument that has conversion code then we delay
+ * the destruction of any temporary variables until after we have
+ * converted the outputs.
+ */
+ if (isInArg(ad) && isOutArg(ad) && hasConvertToCode(ad) && deltemps)
+ {
+ deltemps = FALSE;
+
+ prcode(fp,
+" PyObject *sipResult;\n"
+ );
+
+ newline = TRUE;
+ }
+
+ /*
+ * If we are returning a class via an output only reference or pointer
+ * then we need an instance on the heap.
+ */
+ if (needNewInstance(ad))
+ {
+ prcode(fp,
+" a%d = new %b();\n"
+ ,a,ad);
+
+ newline = TRUE;
+ }
+ }
+
+ error_flag = old_error_flag = FALSE;
+
+ if (od->methodcode != NULL)
+ {
+ /* See if the handwritten code seems to be using the error flag. */
+ if (needErrorFlag(od->methodcode))
+ {
+ prcode(fp,
+" sipErrorState sipError = sipErrorNone;\n"
+ );
+
+ newline = TRUE;
+ error_flag = TRUE;
+ }
+ else if (needOldErrorFlag(od->methodcode))
+ {
+ prcode(fp,
+" int sipIsErr = 0;\n"
+ );
+
+ newline = TRUE;
+ old_error_flag = TRUE;
+ }
+ }
+
+ if (newline)
+ prcode(fp,
+"\n"
+ );
+
+ /* If it is abstract make sure that self was bound. */
+ if (isAbstract(od))
+ prcode(fp,
+" if (!sipOrigSelf)\n"
+" {\n"
+" sipAbstractMethod(%N, %N);\n"
+" return NULL;\n"
+" }\n"
+"\n"
+ , c_scope->pyname, od->common->pyname);
+
+ if (isDeprecated(od))
+ {
+ /* Note that any temporaries will leak if an exception is raised. */
+ if (pyname != NULL)
+ prcode(fp,
+" if (sipDeprecated(%N,%N) < 0)\n"
+ , pyname, od->common->pyname);
+ else
+ prcode(fp,
+" if (sipDeprecated(NULL,%N) < 0)\n"
+ , od->common->pyname);
+
+ prcode(fp,
+" return %s;\n"
+"\n"
+ , ((isVoidReturnSlot(od->common) || isIntReturnSlot(od->common) || isSSizeReturnSlot(od->common) || isLongReturnSlot(od->common)) ? "-1" : "NULL"));
+ }
+
+ /* Call any pre-hook. */
+ if (od->prehook != NULL)
+ prcode(fp,
+" sipCallHook(\"%s\");\n"
+"\n"
+ ,od->prehook);
+
+ if (od->methodcode != NULL)
+ generateCppCodeBlock(od->methodcode,fp);
+ else
+ {
+ int rgil = ((release_gil || isReleaseGIL(od)) && !isHoldGIL(od));
+
+ if (needsNew && generating_c)
+ {
+ prcode(fp,
+" if ((sipRes = (%b *)sipMalloc(sizeof (%b))) == NULL)\n"
+" {\n"
+ ,res,res);
+
+ gc_ellipsis(&od->pysig, fp);
+
+ prcode(fp,
+" return NULL;\n"
+" }\n"
+"\n"
+ );
+ }
+
+ if (rgil)
+ prcode(fp,
+" Py_BEGIN_ALLOW_THREADS\n"
+ );
+
+ generateTry(od->exceptions,fp);
+
+ prcode(fp,
+" ");
+
+ if (od->common->slot != cmp_slot && is_result)
+ {
+ /* Construct a copy on the heap if needed. */
+ if (needsNew)
+ {
+ if (generating_c)
+ prcode(fp,"*sipRes = ");
+ else
+ prcode(fp,"sipRes = new %b(",res);
+ }
+ else
+ {
+ prcode(fp,"sipRes = ");
+
+ /* See if we need the address of the result. */
+ if ((res->atype == class_type || res->atype == mapped_type) && (res->nrderefs == 0 || isReference(res)))
+ prcode(fp,"&");
+ }
+ }
+
+ switch (od->common->slot)
+ {
+ case no_slot:
+ generateCppFunctionCall(scope, o_scope, od, fp);
+ break;
+
+ case getitem_slot:
+ prcode(fp, "(*sipCpp)[");
+ generateSlotArg(&od->pysig, 0, fp);
+ prcode(fp,"]");
+ break;
+
+ case call_slot:
+ prcode(fp, "(*sipCpp)(");
+ generateCallArgs(od->cppsig, &od->pysig, fp);
+ prcode(fp,")");
+ break;
+
+ case int_slot:
+ case long_slot:
+ case float_slot:
+ prcode(fp, "*sipCpp");
+ break;
+
+ case add_slot:
+ generateNumberSlotCall(od,"+",fp);
+ break;
+
+ case concat_slot:
+ generateBinarySlotCall(scope, od, "+", deref, fp);
+ break;
+
+ case sub_slot:
+ generateNumberSlotCall(od,"-",fp);
+ break;
+
+ case mul_slot:
+ generateNumberSlotCall(od,"*",fp);
+ break;
+
+ case repeat_slot:
+ generateBinarySlotCall(scope, od, "*", deref, fp);
+ break;
+
+ case div_slot:
+ case truediv_slot:
+ generateNumberSlotCall(od,"/",fp);
+ break;
+
+ case mod_slot:
+ generateNumberSlotCall(od,"%",fp);
+ break;
+
+ case and_slot:
+ generateNumberSlotCall(od,"&",fp);
+ break;
+
+ case or_slot:
+ generateNumberSlotCall(od,"|",fp);
+ break;
+
+ case xor_slot:
+ generateNumberSlotCall(od,"^",fp);
+ break;
+
+ case lshift_slot:
+ generateNumberSlotCall(od,"<<",fp);
+ break;
+
+ case rshift_slot:
+ generateNumberSlotCall(od,">>",fp);
+ break;
+
+ case iadd_slot:
+ case iconcat_slot:
+ generateBinarySlotCall(scope, od, "+=", deref, fp);
+ break;
+
+ case isub_slot:
+ generateBinarySlotCall(scope, od, "-=", deref, fp);
+ break;
+
+ case imul_slot:
+ case irepeat_slot:
+ generateBinarySlotCall(scope, od, "*=", deref, fp);
+ break;
+
+ case idiv_slot:
+ case itruediv_slot:
+ generateBinarySlotCall(scope, od, "/=", deref, fp);
+ break;
+
+ case imod_slot:
+ generateBinarySlotCall(scope, od, "%=", deref, fp);
+ break;
+
+ case iand_slot:
+ generateBinarySlotCall(scope, od, "&=", deref, fp);
+ break;
+
+ case ior_slot:
+ generateBinarySlotCall(scope, od, "|=", deref, fp);
+ break;
+
+ case ixor_slot:
+ generateBinarySlotCall(scope, od, "^=", deref, fp);
+ break;
+
+ case ilshift_slot:
+ generateBinarySlotCall(scope, od, "<<=", deref, fp);
+ break;
+
+ case irshift_slot:
+ generateBinarySlotCall(scope, od, ">>=", deref, fp);
+ break;
+
+ case invert_slot:
+ prcode(fp, "~(*sipCpp)");
+ break;
+
+ case lt_slot:
+ generateComparisonSlotCall(scope, od, "<", ">=", deref, fp);
+ break;
+
+ case le_slot:
+ generateComparisonSlotCall(scope, od, "<=", ">", deref, fp);
+ break;
+
+ case eq_slot:
+ generateComparisonSlotCall(scope, od, "==", "!=", deref, fp);
+ break;
+
+ case ne_slot:
+ generateComparisonSlotCall(scope, od, "!=", "==", deref, fp);
+ break;
+
+ case gt_slot:
+ generateComparisonSlotCall(scope, od, ">", "<=", deref, fp);
+ break;
+
+ case ge_slot:
+ generateComparisonSlotCall(scope, od, ">=", "<", deref, fp);
+ break;
+
+ case neg_slot:
+ prcode(fp, "-(*sipCpp)");
+ break;
+
+ case pos_slot:
+ prcode(fp, "+(*sipCpp)");
+ break;
+
+ case cmp_slot:
+ prcode(fp,"if ");
+ generateBinarySlotCall(scope, od, "<", deref, fp);
+ prcode(fp,"\n"
+" sipRes = -1;\n"
+" else if ");
+ generateBinarySlotCall(scope, od, ">", deref, fp);
+ prcode(fp,"\n"
+" sipRes = 1;\n"
+" else\n"
+" sipRes = 0");
+
+ break;
+ }
+
+ if (needsNew && !generating_c)
+ prcode(fp,")");
+
+ prcode(fp,";\n"
+ );
+
+ generateCatch(od->exceptions, &od->pysig, mod, fp);
+
+ if (rgil)
+ prcode(fp,
+" Py_END_ALLOW_THREADS\n"
+ );
+ }
+
+ for (a = 0; a < od->pysig.nrArgs; ++a)
+ {
+ argDef *ad = &od->pysig.args[a];
+
+ if (!isInArg(ad))
+ continue;
+
+ /* Handle any /KeepReference/ arguments. */
+ if (keepReference(ad))
+ {
+ prcode(fp,
+"\n"
+" sipKeepReference(sipSelf, %d, a%d%s);\n"
+ , ad->key, a, (((ad->atype == ascii_string_type || ad->atype == latin1_string_type || ad->atype == utf8_string_type) && ad->nrderefs == 1) || !isGetWrapper(ad) ? "Keep" : "Wrapper"));
+ }
+
+ /* Handle /TransferThis/ for non-factory methods. */
+ if (!isFactory(od) && isThisTransferred(ad))
+ {
+ prcode(fp,
+"\n"
+" if (sipOwner)\n"
+" sipTransferTo(sipSelf, (PyObject *)sipOwner);\n"
+" else\n"
+" sipTransferBack(sipSelf);\n"
+ );
+ }
+ }
+
+ if (isThisTransferredMeth(od))
+ prcode(fp,
+"\n"
+" sipTransferTo(sipSelf, NULL);\n"
+ );
+
+ gc_ellipsis(&od->pysig, fp);
+
+ if (deltemps && !isZeroArgSlot(od->common))
+ deleteTemps(&od->pysig, fp);
+
+ prcode(fp,
+"\n"
+ );
+
+ /* Handle the error flag if it was used. */
+ error_value = ((isVoidReturnSlot(od->common) || isIntReturnSlot(od->common) || isSSizeReturnSlot(od->common) || isLongReturnSlot(od->common)) ? "-1" : "0");
+
+ if (error_flag)
+ {
+ prcode(fp,
+" if (sipError == sipErrorFail)\n"
+" return %s;\n"
+"\n"
+" if (sipError == sipErrorNone)\n"
+" {\n"
+ , error_value);
+ }
+ else if (old_error_flag)
+ {
+ prcode(fp,
+" if (sipIsErr)\n"
+" return %s;\n"
+"\n"
+ , error_value);
+ }
+
+ /* Call any post-hook. */
+ if (od->posthook != NULL)
+ prcode(fp,
+"\n"
+" sipCallHook(\"%s\");\n"
+ ,od->posthook);
+
+ if (isVoidReturnSlot(od->common))
+ prcode(fp,
+" return 0;\n"
+ );
+ else if (isInplaceNumberSlot(od->common) || isInplaceSequenceSlot(od->common))
+ prcode(fp,
+" Py_INCREF(sipSelf);\n"
+" return sipSelf;\n"
+ );
+ else if (isIntReturnSlot(od->common) || isSSizeReturnSlot(od->common) || isLongReturnSlot(od->common))
+ prcode(fp,
+" return sipRes;\n"
+ );
+ else
+ {
+ generateHandleResult(od, needsNew, result_size,
+ (deltemps ? "return" : "sipResult ="), fp);
+
+ /* Delete the temporaries now if we haven't already done so. */
+ if (!deltemps)
+ {
+ deleteTemps(&od->pysig, fp);
+
+ prcode(fp,
+"\n"
+" return sipResult;\n"
+ );
+ }
+ }
+
+ if (error_flag)
+ prcode(fp,
+" }\n"
+"\n"
+" sipAddException(sipError, &sipParseErr);\n"
+ );
+
+ prcode(fp,
+" }\n"
+ );
+
+ /* Restore the full type of the result. */
+ *res = orig_res;
+}
+
+
+/*
+ * Generate a call to a C++ function.
+ */
+static void generateCppFunctionCall(ifaceFileDef *scope,
+ ifaceFileDef *o_scope, overDef *od, FILE *fp)
+{
+ char *mname = od->cppname;
+ int parens = 1;
+
+ /*
+ * If the function is protected then call the public wrapper. If it is
+ * virtual then call the explicit scoped function if "self" was passed as
+ * the first argument.
+ */
+
+ if (scope == NULL)
+ prcode(fp, "%s(", mname);
+ else if (scope->type == namespace_iface)
+ prcode(fp, "%S::%s(", scope->fqcname, mname);
+ else if (isStatic(od))
+ {
+ if (isProtected(od))
+ prcode(fp, "sip%C::sipProtect_%s(", scope->fqcname, mname);
+ else
+ prcode(fp, "%S::%s(", o_scope->fqcname, mname);
+ }
+ else if (isProtected(od))
+ {
+ if (!isAbstract(od) && (isVirtual(od) || isVirtualReimp(od)))
+ {
+ prcode(fp, "sipCpp->sipProtectVirt_%s(sipSelfWasArg", mname);
+
+ if (od->cppsig->nrArgs > 0)
+ prcode(fp, ",");
+ }
+ else
+ prcode(fp, "sipCpp->sipProtect_%s(", mname);
+ }
+ else if (!isAbstract(od) && (isVirtual(od) || isVirtualReimp(od)))
+ {
+ prcode(fp, "(sipSelfWasArg ? sipCpp->%S::%s(", o_scope->fqcname, mname);
+ generateCallArgs(od->cppsig, &od->pysig, fp);
+ prcode(fp, ") : sipCpp->%s(", mname);
+ ++parens;
+ }
+ else
+ prcode(fp, "sipCpp->%s(", mname);
+
+ generateCallArgs(od->cppsig, &od->pysig, fp);
+
+ while (parens--)
+ prcode(fp, ")");
+}
+
+
+/*
+ * Generate argument to a slot.
+ */
+static void generateSlotArg(signatureDef *sd, int argnr, FILE *fp)
+{
+ argDef *ad;
+ int deref;
+
+ ad = &sd->args[argnr];
+ deref = ((ad->atype == class_type || ad->atype == mapped_type) && ad->nrderefs == 0);
+
+ prcode(fp, "%sa%d", (deref ? "*" : ""), argnr);
+}
+
+
+/*
+ * Generate the call to a comparison slot method.
+ */
+static void generateComparisonSlotCall(ifaceFileDef *scope, overDef *od,
+ const char *op, const char *cop, int deref, FILE *fp)
+{
+ if (isComplementary(od))
+ {
+ op = cop;
+ prcode(fp, "!");
+ }
+
+ if (!isGlobal(od))
+ {
+ const char *deref_s = (deref ? "->" : ".");
+
+ if (isAbstract(od))
+ prcode(fp, "sipCpp%soperator%s(", deref_s, op);
+ else
+ prcode(fp, "sipCpp%s%S::operator%s(", deref_s, scope->fqcname, op);
+ }
+ else if (deref)
+ prcode(fp, "operator%s((*sipCpp), ", op);
+ else
+ prcode(fp, "operator%s(sipCpp, ", op);
+
+ generateSlotArg(&od->pysig, 0, fp);
+ prcode(fp, ")");
+}
+
+
+/*
+ * Generate the call to a binary (non-number) slot method.
+ */
+static void generateBinarySlotCall(ifaceFileDef *scope, overDef *od,
+ const char *op, int deref, FILE *fp)
+{
+ generateComparisonSlotCall(scope, od, op, "", deref, fp);
+}
+
+
+/*
+ * Generate the call to a binary number slot method.
+ */
+static void generateNumberSlotCall(overDef *od, char *op, FILE *fp)
+{
+ prcode(fp, "(");
+ generateSlotArg(&od->pysig, 0, fp);
+ prcode(fp, " %s ", op);
+ generateSlotArg(&od->pysig, 1, fp);
+ prcode(fp, ")");
+}
+
+
+/*
+ * Generate the argument variables for a member function/constructor/operator.
+ */
+static int generateArgParser(signatureDef *sd, classDef *c_scope,
+ mappedTypeDef *mt_scope, ctorDef *ct, overDef *od, int secCall,
+ FILE *fp)
+{
+ int a, isQtSlot, optargs, arraylenarg, sigarg, handle_self, single_arg;
+ int slotconarg, slotdisarg, need_owner;
+ ifaceFileDef *scope;
+
+ if (mt_scope != NULL)
+ scope = mt_scope->iff;
+ else if (c_scope != NULL)
+ {
+ /* If the class is just a namespace, then ignore it. */
+ if (c_scope->iff->type == namespace_iface)
+ {
+ c_scope = NULL;
+ scope = NULL;
+ }
+ else
+ scope = c_scope->iff;
+ }
+ else
+ scope = NULL;
+
+ handle_self = (od != NULL && od->common->slot == no_slot && !isStatic(od) && c_scope != NULL);
+
+ /* Assume there isn't a Qt slot. */
+ isQtSlot = FALSE;
+
+ /*
+ * Generate the local variables that will hold the parsed arguments and
+ * values returned via arguments.
+ */
+ sigarg = -1;
+ need_owner = FALSE;
+
+ for (a = 0; a < sd->nrArgs; ++a)
+ {
+ argDef *ad = &sd->args[a];
+
+ switch (ad->atype)
+ {
+ case signal_type:
+ sigarg = a;
+ break;
+
+ case rxcon_type:
+ case rxdis_type:
+ isQtSlot = TRUE;
+ break;
+
+ case slotcon_type:
+ slotconarg = a;
+ break;
+
+ case slotdis_type:
+ slotdisarg = a;
+ break;
+ }
+
+ if (isArraySize(ad))
+ arraylenarg = a;
+
+ generateVariable(scope, ad, a, fp);
+
+ if (isThisTransferred(ad))
+ need_owner = TRUE;
+ }
+
+ if (od != NULL && need_owner)
+ prcode(fp,
+" sipWrapper *sipOwner = 0;\n"
+ );
+
+ if (handle_self)
+ {
+ if (isProtected(od) && hasShadow(c_scope))
+ prcode(fp,
+" sip%C *sipCpp;\n"
+ , classFQCName(c_scope));
+ else
+ prcode(fp,
+" %U *sipCpp;\n"
+ , c_scope);
+
+ prcode(fp,
+"\n"
+ );
+ }
+ else if (sd->nrArgs != 0)
+ prcode(fp,
+"\n"
+ );
+
+ /* Generate the call to the parser function. */
+ single_arg = FALSE;
+
+ if (od != NULL && isNumberSlot(od->common))
+ {
+ prcode(fp,
+" if (sipParsePair(%ssipParseErr, sipArg0, sipArg1, \"", (ct != NULL ? "" : "&"));
+ }
+ else if ((od != NULL && useKeywordArgsFunction(od->common)) || ct != NULL)
+ {
+ int this_uses_kwds;
+
+ /*
+ * We handle keywords if we might have been passed some (because one of
+ * the overloads uses them or we are a ctor). However this particular
+ * overload might not have any.
+ */
+ this_uses_kwds = ((od != NULL && useKeywordArgs(od)) || (ct != NULL && useKeywordArgsCtor(ct)));
+
+ if (this_uses_kwds)
+ {
+ int a;
+
+ prcode(fp,
+" static const char *sipKwdList[] = {\n"
+ );
+
+ for (a = 0; a < sd->nrArgs; ++a)
+ {
+ nameDef *nd = sd->args[a].name;
+
+ if (nd != NULL)
+ prcode(fp,
+" %N,\n"
+ , nd);
+ else
+ prcode(fp,
+" NULL,\n"
+ );
+ }
+
+ prcode(fp,
+ " };\n"
+ "\n"
+ );
+ }
+
+ prcode(fp,
+" if (sipParseKwdArgs(%ssipParseErr, sipArgs, sipKwds, %s, %s, \"", (ct != NULL ? "" : "&"), (this_uses_kwds ? "sipKwdList" : "NULL"), (ct != NULL ? "sipUnused" : "NULL"));
+ }
+ else
+ {
+ single_arg = (od != NULL && od->common->slot != no_slot && !isMultiArgSlot(od->common));
+
+ prcode(fp,
+" if (sipParseArgs(%ssipParseErr, sipArg%s, \"", (ct != NULL ? "" : "&"), (single_arg ? "" : "s"));
+ }
+
+ /* Generate the format string. */
+ optargs = FALSE;
+
+ if (single_arg)
+ prcode(fp, "1");
+
+ if (handle_self)
+ prcode(fp,"%c",(isReallyProtected(od) ? 'p' : 'B'));
+ else if (isQtSlot && od == NULL)
+ prcode(fp,"C");
+
+ for (a = 0; a < sd->nrArgs; ++a)
+ {
+ char *fmt = "";
+ argDef *ad = &sd->args[a];
+
+ if (!isInArg(ad))
+ continue;
+
+ if (ad->defval != NULL && !optargs)
+ {
+ prcode(fp,"|");
+ optargs = TRUE;
+ }
+
+ switch (ad->atype)
+ {
+ case ascii_string_type:
+ if (ad->nrderefs == 0 || (isOutArg(ad) && ad->nrderefs == 1))
+ fmt = "aA";
+ else
+ fmt = "AA";
+
+ break;
+
+ case latin1_string_type:
+ if (ad->nrderefs == 0 || (isOutArg(ad) && ad->nrderefs == 1))
+ fmt = "aL";
+ else
+ fmt = "AL";
+
+ break;
+
+ case utf8_string_type:
+ if (ad->nrderefs == 0 || (isOutArg(ad) && ad->nrderefs == 1))
+ fmt = "a8";
+ else
+ fmt = "A8";
+
+ break;
+
+ case sstring_type:
+ case ustring_type:
+ case string_type:
+ if (ad->nrderefs == 0 || (isOutArg(ad) && ad->nrderefs == 1))
+ fmt = "c";
+ else if (isArray(ad))
+ fmt = "k";
+ else
+ fmt = "s";
+
+ break;
+
+ case wstring_type:
+ if (ad->nrderefs == 0 || (isOutArg(ad) && ad->nrderefs == 1))
+ fmt = "w";
+ else if (isArray(ad))
+ fmt = "K";
+ else
+ fmt = "x";
+
+ break;
+
+ case enum_type:
+ if (ad->u.ed->fqcname == NULL)
+ fmt = "e";
+ else if (isConstrained(ad))
+ fmt = "XE";
+ else
+ fmt = "E";
+ break;
+
+ case bool_type:
+ fmt = "b";
+ break;
+
+ case cbool_type:
+ fmt = "Xb";
+ break;
+
+ case int_type:
+ if (!isArraySize(ad))
+ fmt = "i";
+
+ break;
+
+ case uint_type:
+ if (!isArraySize(ad))
+ fmt = "u";
+
+ break;
+
+ case cint_type:
+ fmt = "Xi";
+ break;
+
+ case short_type:
+ if (!isArraySize(ad))
+ fmt = "h";
+
+ break;
+
+ case ushort_type:
+ if (!isArraySize(ad))
+ fmt = "t";
+
+ break;
+
+ case long_type:
+ if (!isArraySize(ad))
+ fmt = "l";
+
+ break;
+
+ case ulong_type:
+ if (!isArraySize(ad))
+ fmt = "m";
+
+ break;
+
+ case longlong_type:
+ if (!isArraySize(ad))
+ fmt = "n";
+
+ break;
+
+ case ulonglong_type:
+ if (!isArraySize(ad))
+ fmt = "o";
+
+ break;
+
+ case struct_type:
+ case void_type:
+ fmt = "v";
+ break;
+
+ case float_type:
+ fmt = "f";
+ break;
+
+ case cfloat_type:
+ fmt = "Xf";
+ break;
+
+ case double_type:
+ fmt = "d";
+ break;
+
+ case cdouble_type:
+ fmt = "Xd";
+ break;
+
+ case signal_type:
+ fmt = "G";
+ break;
+
+ case slot_type:
+ fmt = "S";
+ break;
+
+ case anyslot_type:
+ fmt = "U";
+ break;
+
+ case slotcon_type:
+ case slotdis_type:
+ fmt = (secCall ? "" : "S");
+ break;
+
+ case rxcon_type:
+ fmt = (secCall ? (isSingleShot(ad) ? "g" : "y") : "q");
+ break;
+
+ case rxdis_type:
+ fmt = (secCall ? "Y" : "Q");
+ break;
+
+ case mapped_type:
+ case class_type:
+ if (isArray(ad))
+ {
+ if (ad->nrderefs != 1 || !isInArg(ad) || isReference(ad))
+ fatal("Mapped type or class with /Array/ is not a pointer\n");
+
+ if (ad->atype == mapped_type && noRelease(ad->u.mtd))
+ fatal("Mapped type does not support /Array/\n");
+
+ if (ad->atype == class_type && !(generating_c || assignmentHelper(ad->u.cd)))
+ {
+ fatalScopedName(classFQCName(ad->u.cd));
+ fatal(" does not support /Array/\n");
+ }
+
+ fmt = "r";
+ }
+ else
+ {
+ fmt = getSubFormatChar('J', ad);
+ }
+
+ break;
+
+ case pyobject_type:
+ fmt = getSubFormatChar('P',ad);
+ break;
+
+ case pytuple_type:
+ case pylist_type:
+ case pydict_type:
+ case pyslice_type:
+ case pytype_type:
+ fmt = (isAllowNone(ad) ? "N" : "T");
+ break;
+
+ case pycallable_type:
+ fmt = (isAllowNone(ad) ? "H" : "F");
+ break;
+
+ case qobject_type:
+ fmt = "R";
+ break;
+
+ case ellipsis_type:
+ fmt = "W";
+ break;
+ }
+
+ /*
+ * Get the wrapper if explicitly asked for or we are going to keep a
+ * reference to. However if it is an encoded string then we will get
+ * the actual wrapper from the format character.
+ */
+ if (isGetWrapper(ad) || (keepReference(ad) && ad->atype != ascii_string_type && ad->atype != latin1_string_type && ad->atype != utf8_string_type) || (keepReference(ad) && ad->nrderefs != 1))
+ prcode(fp, "@");
+
+ prcode(fp,fmt);
+ }
+
+ prcode(fp,"\"");
+
+ /* Generate the parameters corresponding to the format string. */
+
+ if (handle_self)
+ prcode(fp,", &sipSelf, sipType_%C, &sipCpp",classFQCName(c_scope));
+ else if (isQtSlot && od == NULL)
+ prcode(fp,", sipSelf");
+
+ for (a = 0; a < sd->nrArgs; ++a)
+ {
+ argDef *ad = &sd->args[a];
+
+ if (!isInArg(ad))
+ continue;
+
+ /* Use the wrapper name if it was explicitly asked for. */
+ if (isGetWrapper(ad))
+ prcode(fp, ", &a%dWrapper", a);
+ else if (keepReference(ad))
+ prcode(fp, ", &a%dKeep", a);
+
+ switch (ad->atype)
+ {
+ case mapped_type:
+ prcode(fp, ", sipType_%T,&a%d", ad, a);
+
+ if (isArray(ad))
+ {
+ prcode(fp,", &a%d",arraylenarg);
+ }
+ else if (!isConstrained(ad))
+ {
+ if (noRelease(ad->u.mtd))
+ prcode(fp, ",NULL");
+ else
+ prcode(fp, ", &a%dState", a);
+ }
+
+ break;
+
+ case class_type:
+ prcode(fp, ", sipType_%T, &a%d", ad, a);
+
+ if (isArray(ad))
+ {
+ prcode(fp,", &a%d",arraylenarg);
+ }
+ else
+ {
+ if (isThisTransferred(ad))
+ prcode(fp, ", %ssipOwner", (ct != NULL ? "" : "&"));
+
+ if (ad->u.cd->convtocode != NULL && !isConstrained(ad))
+ prcode(fp, ", &a%dState", a);
+ }
+
+ break;
+
+ case ascii_string_type:
+ if (!keepReference(ad) && ad->nrderefs == 1)
+ prcode(fp, ", &a%dKeep", a);
+
+ prcode(fp, ", &a%d", a);
+ break;
+
+ case latin1_string_type:
+ if (!keepReference(ad) && ad->nrderefs == 1)
+ prcode(fp, ", &a%dKeep", a);
+
+ prcode(fp, ", &a%d", a);
+ break;
+
+ case utf8_string_type:
+ if (!keepReference(ad) && ad->nrderefs == 1)
+ prcode(fp, ", &a%dKeep", a);
+
+ prcode(fp, ", &a%d", a);
+ break;
+
+ case rxcon_type:
+ {
+ if (sigarg > 0)
+ prcode(fp,", a%d",sigarg);
+ else
+ {
+ prcode(fp,", \"(");
+
+ generateCalledArgs(scope, sd->args[slotconarg].u.sa, Declaration, TRUE, fp);
+
+ prcode(fp,")\"");
+ }
+
+ prcode(fp,", &a%d, &a%d",a,slotconarg);
+
+ break;
+ }
+
+ case rxdis_type:
+ {
+ prcode(fp,", \"(");
+
+ generateCalledArgs(scope, sd->args[slotdisarg].u.sa, Declaration, TRUE, fp);
+
+ prcode(fp,")\", &a%d, &a%d",a,slotdisarg);
+
+ break;
+ }
+
+ case slotcon_type:
+ case slotdis_type:
+ if (!secCall)
+ prcode(fp,", &a%d",a);
+
+ break;
+
+ case anyslot_type:
+ prcode(fp, ", &a%dName, &a%dCallable", a, a);
+ break;
+
+ case pytuple_type:
+ prcode(fp,", &PyTuple_Type, &a%d",a);
+ break;
+
+ case pylist_type:
+ prcode(fp,", &PyList_Type, &a%d",a);
+ break;
+
+ case pydict_type:
+ prcode(fp,", &PyDict_Type, &a%d",a);
+ break;
+
+ case pyslice_type:
+ prcode(fp,", &PySlice_Type, &a%d",a);
+ break;
+
+ case pytype_type:
+ prcode(fp,", &PyType_Type, &a%d",a);
+ break;
+
+ case enum_type:
+ if (ad->u.ed->fqcname != NULL)
+ prcode(fp, ", sipType_%C", ad->u.ed->fqcname);
+
+ prcode(fp,", &a%d",a);
+ break;
+
+ default:
+ if (!isArraySize(ad))
+ prcode(fp,", &a%d",a);
+
+ if (isArray(ad))
+ prcode(fp,", &a%d",arraylenarg);
+ }
+ }
+
+ prcode(fp,"))\n");
+
+ return isQtSlot;
+}
+
+
+/*
+ * Get the format character string for something that has sub-formats.
+ */
+
+static char *getSubFormatChar(char fc, argDef *ad)
+{
+ static char fmt[3];
+ char flags;
+
+ flags = 0;
+
+ if (isTransferred(ad))
+ flags |= 0x02;
+
+ if (isTransferredBack(ad))
+ flags |= 0x04;
+
+ if (ad->atype == class_type || ad->atype == mapped_type)
+ {
+ if (ad->nrderefs == 0)
+ flags |= 0x01;
+
+ if (isThisTransferred(ad))
+ flags |= 0x10;
+
+ if (isConstrained(ad) || (ad->atype == class_type && ad->u.cd->convtocode == NULL))
+ flags |= 0x08;
+ }
+
+ fmt[0] = fc;
+ fmt[1] = '0' + flags;
+ fmt[2] = '\0';
+
+ return fmt;
+}
+
+
+/*
+ * Return TRUE if a type has %ConvertToTypeCode.
+ */
+static int hasConvertToCode(argDef *ad)
+{
+ codeBlock *convtocode;
+
+ if (ad->atype == class_type && !isConstrained(ad))
+ convtocode = ad->u.cd->convtocode;
+ else if (ad->atype == mapped_type && !isConstrained(ad))
+ convtocode = ad->u.mtd->convtocode;
+ else
+ convtocode = NULL;
+
+ return (convtocode != NULL);
+}
+
+
+/*
+ * Garbage collect any ellipsis argument.
+ */
+static void gc_ellipsis(signatureDef *sd, FILE *fp)
+{
+ if (sd->nrArgs > 0 && sd->args[sd->nrArgs - 1].atype == ellipsis_type)
+ prcode(fp,
+"\n"
+" Py_DECREF(a%d);\n"
+ , sd->nrArgs - 1);
+}
+
+
+/*
+ * Delete any instances created to hold /Out/ arguments.
+ */
+static void deleteOuts(signatureDef *sd, FILE *fp)
+{
+ int a;
+
+ for (a = 0; a < sd->nrArgs; ++a)
+ {
+ argDef *ad = &sd->args[a];
+
+ if (needNewInstance(ad))
+ prcode(fp,
+" delete a%d;\n"
+ , a);
+ }
+}
+
+
+
+/*
+ * Delete any temporary variables on the heap created by type convertors.
+ */
+static void deleteTemps(signatureDef *sd, FILE *fp)
+{
+ int a;
+
+ for (a = 0; a < sd->nrArgs; ++a)
+ {
+ argDef *ad = &sd->args[a];
+
+ if (isArray(ad) && (ad->atype == mapped_type || ad->atype == class_type))
+ {
+ if (generating_c)
+ prcode(fp,
+" sipFree(a%d);\n"
+ , a);
+ else
+ prcode(fp,
+" delete[] a%d;\n"
+ , a);
+
+ continue;
+ }
+
+ if (!isInArg(ad))
+ continue;
+
+ if ((ad->atype == ascii_string_type || ad->atype == latin1_string_type || ad->atype == utf8_string_type) && ad->nrderefs == 1)
+ {
+ prcode(fp,
+" Py_%sDECREF(a%dKeep);\n"
+ , (ad->defval != NULL ? "X" : ""), a);
+ }
+ else if (ad->atype == wstring_type && ad->nrderefs == 1)
+ {
+ if (generating_c || !isConstArg(ad))
+ prcode(fp,
+" sipFree(a%d);\n"
+ , a);
+ else
+ prcode(fp,
+" sipFree(const_cast<wchar_t *>(a%d));\n"
+ , a);
+ }
+ else if (hasConvertToCode(ad))
+ {
+ if (ad->atype == mapped_type && noRelease(ad->u.mtd))
+ continue;
+
+ if (generating_c || !isConstArg(ad))
+ prcode(fp,
+" sipReleaseType(a%d,sipType_%T,a%dState);\n"
+ , a, ad, a);
+ else
+ prcode(fp,
+" sipReleaseType(const_cast<%b *>(a%d),sipType_%T,a%dState);\n"
+ , ad, a, ad, a);
+ }
+ }
+}
+
+
+/*
+ * Generate a C++ code block.
+ */
+static void generateCppCodeBlock(codeBlock *code, FILE *fp)
+{
+ int reset_line = FALSE;
+ codeBlock *cb;
+
+ for (cb = code; cb != NULL; cb = cb->next)
+ {
+ const char *cp;
+
+ /*
+ * Fragmented fragments (possibly created when applying template types)
+ * don't have a filename.
+ */
+ if ((cp = cb->filename) != NULL)
+ {
+ reset_line = TRUE;
+
+ prcode(fp,
+"#line %d \"", cb->linenr);
+
+ while (*cp != '\0')
+ {
+ prcode(fp, "%c", *cp);
+
+ if (*cp == '\\')
+ prcode(fp, "\\");
+
+ ++cp;
+ }
+
+ prcode(fp, "\"\n"
+ );
+ }
+
+ prcode(fp, "%s", cb->frag);
+ }
+
+ if (reset_line)
+ {
+ const char *bn;
+
+ /* Just use the base name. */
+ if ((bn = strrchr(currentFileName, '/')) != NULL)
+ ++bn;
+ else
+ bn = currentFileName;
+
+ prcode(fp,
+"#line %d \"%s\"\n"
+ , currentLineNr + 1, bn);
+ }
+}
+
+
+/*
+ * Create a source file.
+ */
+static FILE *createCompilationUnit(moduleDef *mod, const char *fname,
+ const char *description)
+{
+ FILE *fp = createFile(mod, fname, description);
+
+ if (fp != NULL)
+ generateCppCodeBlock(mod->unitcode, fp);
+
+ return fp;
+}
+
+
+/*
+ * Create a file with an optional standard header.
+ */
+static FILE *createFile(moduleDef *mod, const char *fname,
+ const char *description)
+{
+ FILE *fp;
+
+ /* Create the file. */
+ if ((fp = fopen(fname, "w")) == NULL)
+ fatal("Unable to create file \"%s\"\n",fname);
+
+ /* The "stack" doesn't have to be very deep. */
+ previousLineNr = currentLineNr;
+ currentLineNr = 1;
+ previousFileName = currentFileName;
+ currentFileName = fname;
+
+ if (description != NULL)
+ {
+ int needComment;
+ codeBlock *cb;
+ time_t now;
+
+ /* Write the header. */
+ now = time(NULL);
+
+ prcode(fp,
+"/*\n"
+" * %s\n"
+" *\n"
+" * Generated by SIP %s on %s"
+ ,description
+ ,sipVersion,ctime(&now));
+
+ if (mod->copying != NULL)
+ prcode(fp,
+" *\n"
+ );
+
+ needComment = TRUE;
+
+ for (cb = mod->copying; cb != NULL; cb = cb->next)
+ {
+ const char *cp;
+
+ for (cp = cb->frag; *cp != '\0'; ++cp)
+ {
+ if (needComment)
+ {
+ needComment = FALSE;
+ prcode(fp," * ");
+ }
+
+ prcode(fp,"%c",*cp);
+
+ if (*cp == '\n')
+ needComment = TRUE;
+ }
+ }
+
+ prcode(fp,
+" */\n"
+ );
+ }
+
+ return fp;
+}
+
+
+/*
+ * Close a file and report any errors.
+ */
+static void closeFile(FILE *fp)
+{
+ if (ferror(fp))
+ fatal("Error writing to \"%s\"\n",currentFileName);
+
+ if (fclose(fp))
+ fatal("Error closing \"%s\"\n",currentFileName);
+
+ currentLineNr = previousLineNr;
+ currentFileName = previousFileName;
+}
+
+
+/*
+ * Print formatted code.
+ */
+void prcode(FILE *fp, const char *fmt, ...)
+{
+ char ch;
+ va_list ap;
+
+ prcode_last = fmt;
+
+ va_start(ap,fmt);
+
+ while ((ch = *fmt++) != '\0')
+ if (ch == '%')
+ {
+ ch = *fmt++;
+
+ switch (ch)
+ {
+ case 'c':
+ {
+ char c = (char)va_arg(ap,int);
+
+ if (c == '\n')
+ ++currentLineNr;
+
+ fputc(c,fp);
+ break;
+ }
+
+ case 's':
+ {
+ const char *cp = va_arg(ap,const char *);
+
+ while (*cp != '\0')
+ {
+ if (*cp == '\n')
+ ++currentLineNr;
+
+ fputc(*cp,fp);
+ ++cp;
+ }
+
+ break;
+ }
+
+ case 'l':
+ fprintf(fp,"%ld",va_arg(ap,long));
+ break;
+
+ case 'u':
+ fprintf(fp,"%u",va_arg(ap,unsigned));
+ break;
+
+ case 'd':
+ fprintf(fp,"%d",va_arg(ap,int));
+ break;
+
+ case 'g':
+ fprintf(fp,"%g",va_arg(ap,double));
+ break;
+
+ case 'x':
+ fprintf(fp,"0x%08x",va_arg(ap,unsigned));
+ break;
+
+ case '\0':
+ fputc('%',fp);
+ --fmt;
+ break;
+
+ case '\n':
+ fputc('\n',fp);
+ ++currentLineNr;
+ break;
+
+ case 'b':
+ {
+ argDef *ad, orig;
+
+ ad = va_arg(ap,argDef *);
+ orig = *ad;
+
+ resetIsConstArg(ad);
+ resetIsReference(ad);
+ ad->nrderefs = 0;
+
+ generateBaseType(NULL, ad, TRUE, fp);
+
+ *ad = orig;
+
+ break;
+ }
+
+ case 'M':
+ prcode_xml = !prcode_xml;
+ break;
+
+ case 'A':
+ {
+ ifaceFileDef *scope = va_arg(ap, ifaceFileDef *);
+ argDef *ad = va_arg(ap, argDef *);
+
+ generateBaseType(scope, ad, TRUE, fp);
+ break;
+ }
+
+ case 'B':
+ generateBaseType(NULL, va_arg(ap,argDef *),TRUE, fp);
+ break;
+
+ case 'T':
+ prTypeName(fp, va_arg(ap,argDef *));
+ break;
+
+ case 'I':
+ {
+ int indent = va_arg(ap,int);
+
+ while (indent-- > 0)
+ fputc('\t',fp);
+
+ break;
+ }
+
+ case 'N':
+ {
+ nameDef *nd = va_arg(ap,nameDef *);
+
+ prCachedName(fp, nd, "sipName_");
+ break;
+ }
+
+ case 'n':
+ {
+ nameDef *nd = va_arg(ap,nameDef *);
+
+ prCachedName(fp, nd, "sipNameNr_");
+ break;
+ }
+
+ case 'E':
+ {
+ enumDef *ed = va_arg(ap,enumDef *);
+
+ if (ed->fqcname == NULL || isProtectedEnum(ed))
+ fprintf(fp,"int");
+ else
+ prScopedName(fp,ed->fqcname,"::");
+
+ break;
+ }
+
+ case 'F':
+ prScopedName(fp,va_arg(ap,scopedNameDef *),"");
+ break;
+
+ case 'C':
+ prScopedName(fp,va_arg(ap,scopedNameDef *),"_");
+ break;
+
+ case 'L':
+ {
+ ifaceFileDef *iff = va_arg(ap, ifaceFileDef *);
+
+ prScopedName(fp, iff->fqcname, "_");
+
+ if (iff->api_range != NULL)
+ fprintf(fp, "_%d", iff->api_range->index);
+
+ break;
+ }
+
+ case 'P':
+ {
+ apiVersionRangeDef *avr = va_arg(ap, apiVersionRangeDef *);
+
+ fprintf(fp, "%d", (avr != NULL ? avr->index : -1));
+
+ break;
+ }
+
+ case 'S':
+ if (generating_c)
+ fprintf(fp,"struct ");
+
+ prScopedName(fp,va_arg(ap,scopedNameDef *),"::");
+ break;
+
+ case 'U':
+ {
+ classDef *cd = va_arg(ap, classDef *);
+
+ if (generating_c)
+ fprintf(fp,"struct ");
+
+ prScopedClassName(fp, cd->iff, cd);
+ break;
+ }
+
+ case 'V':
+ {
+ ifaceFileDef *scope = va_arg(ap, ifaceFileDef *);
+ classDef *cd = va_arg(ap, classDef *);
+
+ if (generating_c)
+ fprintf(fp,"struct ");
+
+ prScopedClassName(fp, scope, cd);
+ break;
+ }
+
+ case 'O':
+ prOverloadName(fp, va_arg(ap, overDef *));
+ break;
+
+ case 'X':
+ generateThrowSpecifier(va_arg(ap,throwArgs *),fp);
+ break;
+
+ default:
+ fputc(ch,fp);
+ }
+ }
+ else if (ch == '\n')
+ {
+ fputc('\n',fp);
+ ++currentLineNr;
+ }
+ else
+ fputc(ch,fp);
+
+ va_end(ap);
+}
+
+
+/*
+ * Generate the symbolic name of a cached name.
+ */
+static void prCachedName(FILE *fp, nameDef *nd, const char *prefix)
+{
+ prcode(fp, "%s", prefix);
+
+ /*
+ * If the name seems to be a template then just use the offset to ensure
+ * that it is unique.
+ */
+ if (strchr(nd->text, '<') != NULL)
+ prcode(fp, "%d", nd->offset);
+ else
+ {
+ const char *cp;
+
+ /* Handle C++ and Python scopes. */
+ for (cp = nd->text; *cp != '\0'; ++cp)
+ {
+ char ch = *cp;
+
+ if (ch == ':' || ch == '.')
+ ch = '_';
+
+ prcode(fp, "%c", ch);
+ }
+ }
+}
+
+
+/*
+ * Generate the C++ name of an overloaded function.
+ */
+void prOverloadName(FILE *fp, overDef *od)
+{
+ char *pt1, *pt2;
+
+ pt1 = "operator";
+
+ switch (od->common->slot)
+ {
+ case add_slot:
+ pt2 = "+";
+ break;
+
+ case sub_slot:
+ pt2 = "-";
+ break;
+
+ case mul_slot:
+ pt2 = "*";
+ break;
+
+ case div_slot:
+ case truediv_slot:
+ pt2 = "/";
+ break;
+
+ case mod_slot:
+ pt2 = "%";
+ break;
+
+ case and_slot:
+ pt2 = "&";
+ break;
+
+ case or_slot:
+ pt2 = "|";
+ break;
+
+ case xor_slot:
+ pt2 = "^";
+ break;
+
+ case lshift_slot:
+ pt2 = "<<";
+ break;
+
+ case rshift_slot:
+ pt2 = ">>";
+ break;
+
+ case iadd_slot:
+ pt2 = "+=";
+ break;
+
+ case isub_slot:
+ pt2 = "-=";
+ break;
+
+ case imul_slot:
+ pt2 = "*=";
+ break;
+
+ case idiv_slot:
+ case itruediv_slot:
+ pt2 = "/=";
+ break;
+
+ case imod_slot:
+ pt2 = "%=";
+ break;
+
+ case iand_slot:
+ pt2 = "&=";
+ break;
+
+ case ior_slot:
+ pt2 = "|=";
+ break;
+
+ case ixor_slot:
+ pt2 = "^=";
+ break;
+
+ case ilshift_slot:
+ pt2 = "<<=";
+ break;
+
+ case irshift_slot:
+ pt2 = ">>=";
+ break;
+
+ case invert_slot:
+ pt2 = "~";
+ break;
+
+ case call_slot:
+ pt2 = "()";
+ break;
+
+ case getitem_slot:
+ pt2 = "[]";
+ break;
+
+ case lt_slot:
+ pt2 = "<";
+ break;
+
+ case le_slot:
+ pt2 = "<=";
+ break;
+
+ case eq_slot:
+ pt2 = "==";
+ break;
+
+ case ne_slot:
+ pt2 = "!=";
+ break;
+
+ case gt_slot:
+ pt2 = ">";
+ break;
+
+ case ge_slot:
+ pt2 = ">=";
+ break;
+
+ default:
+ pt1 = "";
+ pt2 = od->cppname;
+ }
+
+ fprintf(fp, "%s%s", pt1, pt2);
+}
+
+
+/*
+ * Generate a scoped name with the given separator string.
+ */
+static void prScopedName(FILE *fp,scopedNameDef *snd,char *sep)
+{
+ while (snd != NULL)
+ {
+ fprintf(fp,"%s",snd->name);
+
+ if ((snd = snd->next) != NULL)
+ fprintf(fp,"%s",sep);
+ }
+}
+
+
+/*
+ * Generate a scoped class name.
+ */
+static void prScopedClassName(FILE *fp, ifaceFileDef *scope, classDef *cd)
+{
+ /* Protected classes have to be explicitly scoped. */
+ if (isProtectedClass(cd))
+ {
+ /* This should never happen. */
+ if (scope == NULL)
+ scope = cd->iff;
+
+ prcode(fp, "sip%C::sip%s", scope->fqcname, classBaseName(cd));
+ }
+ else
+ {
+ scopedNameDef *snd = classFQCName(cd);
+
+ while (snd != NULL)
+ {
+ fprintf(fp,"%s",snd->name);
+
+ if ((snd = snd->next) != NULL)
+ fprintf(fp, "::");
+ }
+ }
+}
+
+
+/*
+ * Generate a type name to be used as part of an identifier name.
+ */
+static void prTypeName(FILE *fp, argDef *ad)
+{
+ scopedNameDef *snd;
+
+ switch (ad->atype)
+ {
+ case struct_type:
+ snd = ad->u.sname;
+ break;
+
+ case defined_type:
+ snd = ad->u.snd;
+ break;
+
+ case enum_type:
+ snd = ad->u.ed->fqcname;
+ break;
+
+ case mapped_type:
+ snd = ad->u.mtd->iff->fqcname;
+ break;
+
+ case class_type:
+ snd = classFQCName(ad->u.cd);
+ break;
+
+ default:
+ /* This should never happen. */
+ snd = NULL;
+ }
+
+ if (snd != NULL)
+ prcode(fp, "%C", snd);
+}
+
+
+/*
+ * Return TRUE if handwritten code uses the error flag.
+ */
+static int needErrorFlag(codeBlock *cb)
+{
+ return usedInCode(cb, "sipError");
+}
+
+
+/*
+ * Return TRUE if handwritten code uses the deprecated error flag.
+ */
+static int needOldErrorFlag(codeBlock *cb)
+{
+ return usedInCode(cb, "sipIsErr");
+}
+
+
+/*
+ * Return TRUE if the argument type means an instance needs to be created on
+ * the heap to pass back to Python.
+ */
+static int needNewInstance(argDef *ad)
+{
+ return ((ad->atype == mapped_type || ad->atype == class_type) &&
+ ((isReference(ad) && ad->nrderefs == 0) || (!isReference(ad) && ad->nrderefs == 1)) &&
+ !isInArg(ad) && isOutArg(ad));
+}
+
+
+/*
+ * Convert any protected arguments (ie. those whose type is unavailable outside
+ * of a shadow class) to a fundamental type to be used instead (with suitable
+ * casts).
+ */
+static void fakeProtectedArgs(signatureDef *sd)
+{
+ int a;
+ argDef *ad = sd->args;
+
+ for (a = 0; a < sd->nrArgs; ++a)
+ {
+ if (ad->atype == class_type && isProtectedClass(ad->u.cd))
+ {
+ ad->atype = fake_void_type;
+ ad->nrderefs = 1;
+ resetIsReference(ad);
+ }
+ else if (ad->atype == enum_type && isProtectedEnum(ad->u.ed))
+ ad->atype = int_type;
+
+ ++ad;
+ }
+}
+
+
+/*
+ * Reset and save any argument flags so that the signature will be rendered
+ * exactly as defined in C++.
+ */
+static void normaliseArgs(signatureDef *sd)
+{
+ int a;
+ argDef *ad = sd->args;
+
+ for (a = 0; a < sd->nrArgs; ++a)
+ {
+ if (ad->atype == class_type && isProtectedClass(ad->u.cd))
+ {
+ resetIsProtectedClass(ad->u.cd);
+ setWasProtectedClass(ad->u.cd);
+ }
+ else if (ad->atype == enum_type && isProtectedEnum(ad->u.ed))
+ {
+ resetIsProtectedEnum(ad->u.ed);
+ setWasProtectedEnum(ad->u.ed);
+ }
+
+ ++ad;
+ }
+}
+
+
+/*
+ * Restore any argument flags modified by normaliseArgs().
+ */
+static void restoreArgs(signatureDef *sd)
+{
+ int a;
+ argDef *ad = sd->args;
+
+ for (a = 0; a < sd->nrArgs; ++a)
+ {
+ if (ad->atype == class_type && wasProtectedClass(ad->u.cd))
+ {
+ resetWasProtectedClass(ad->u.cd);
+ setIsProtectedClass(ad->u.cd);
+ }
+ else if (ad->atype == enum_type && wasProtectedEnum(ad->u.ed))
+ {
+ resetWasProtectedEnum(ad->u.ed);
+ setIsProtectedEnum(ad->u.ed);
+ }
+
+ ++ad;
+ }
+}
+
+
+/*
+ * Return TRUE if a dealloc function is needed for a class.
+ */
+static int needDealloc(classDef *cd)
+{
+ if (cd->iff->type == namespace_iface)
+ return FALSE;
+
+ /* All of these conditions cause some code to be generated. */
+
+ if (tracing)
+ return TRUE;
+
+ if (generating_c)
+ return TRUE;
+
+ if (cd->dealloccode != NULL)
+ return TRUE;
+
+ if (isPublicDtor(cd))
+ return TRUE;
+
+ if (hasShadow(cd))
+ return TRUE;
+
+ return FALSE;
+}
+
+
+/*
+ * Return the argument name to use in a function definition for handwritten
+ * code.
+ */
+static const char *argName(const char *name, codeBlock *cb)
+{
+ static const char noname[] = "";
+
+ /* Always use the name in C code. */
+ if (generating_c)
+ return name;
+
+ /* Use the name if it is used in the handwritten code. */
+ if (usedInCode(cb, name))
+ return name;
+
+ /* Don't use the name and avoid a compiler warning. */
+ return noname;
+}
+
+
+/*
+ * Returns TRUE if a string is used in a code block.
+ */
+static int usedInCode(codeBlock *code, const char *str)
+{
+ while (code != NULL)
+ {
+ if (strstr(code->frag, str) != NULL)
+ return TRUE;
+
+ code = code->next;
+ }
+
+ return FALSE;
+}
+
+
+/*
+ * Generate an assignment statement from a void * variable to a class instance
+ * variable.
+ */
+static void generateClassFromVoid(classDef *cd, const char *cname,
+ const char *vname, FILE *fp)
+{
+ if (generating_c)
+ prcode(fp, "%S *%s = (%S *)%s", classFQCName(cd), cname, classFQCName(cd), vname);
+ else
+ prcode(fp, "%S *%s = reinterpret_cast<%S *>(%s)", classFQCName(cd), cname, classFQCName(cd), vname);
+}
+
+
+/*
+ * Generate an assignment statement from a void * variable to a mapped type
+ * variable.
+ */
+static void generateMappedTypeFromVoid(mappedTypeDef *mtd, const char *cname,
+ const char *vname, FILE *fp)
+{
+ if (generating_c)
+ prcode(fp, "%b *%s = (%b *)%s", &mtd->type, cname, &mtd->type, vname);
+ else
+ prcode(fp, "%b *%s = reinterpret_cast<%b *>(%s)", &mtd->type, cname, &mtd->type, vname);
+}
+
+
+/*
+ * Returns TRUE if the argument has a type that requires an extra reference to
+ * the originating object to be kept.
+ */
+static int keepPyReference(argDef *ad)
+{
+ if (ad->atype == ascii_string_type || ad->atype == latin1_string_type ||
+ ad->atype == utf8_string_type || ad->atype == ustring_type ||
+ ad->atype == sstring_type || ad->atype == string_type)
+ {
+ if (!isReference(ad) && ad->nrderefs > 0)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/*
+ * Return the encoding character for the given type.
+ */
+static char getEncoding(argType atype)
+{
+ char encoding;
+
+ switch (atype)
+ {
+ case ascii_string_type:
+ encoding = 'A';
+ break;
+
+ case latin1_string_type:
+ encoding = 'L';
+ break;
+
+ case utf8_string_type:
+ encoding = '8';
+ break;
+
+ default:
+ encoding = 'N';
+ }
+
+ return encoding;
+}
+
+
+/*
+ * Return TRUE if a docstring can be automatically generated for a function
+ * overload.
+ */
+static int overloadHasDocstring(sipSpec *pt, overDef *od, memberDef *md)
+{
+ if (isPrivate(od) || isSignal(od))
+ return FALSE;
+
+ if (od->common != md)
+ return FALSE;
+
+ /* If it is versioned then make sure it is the default API. */
+ return isDefaultAPI(pt, od->api_range);
+}
+
+
+/*
+ * Return TRUE if a docstring can be automatically generated for a function.
+ */
+static int hasDocstring(sipSpec *pt, overDef *overs, memberDef *md,
+ ifaceFileDef *scope)
+{
+ overDef *od;
+
+ if (noArgParser(md))
+ return FALSE;
+
+ if (scope != NULL && !isDefaultAPI(pt, scope->api_range))
+ return FALSE;
+
+ for (od = overs; od != NULL; od = od->next)
+ if (overloadHasDocstring(pt, od, md))
+ return TRUE;
+
+ return FALSE;
+}
+
+
+/*
+ * Generate the docstring for a function or method.
+ */
+static void generateDocstring(sipSpec *pt, overDef *overs, memberDef *md,
+ const char *scope_name, classDef *scope_scope, FILE *fp)
+{
+ const char *sep = NULL;
+ overDef *od;
+
+ for (od = overs; od != NULL; od = od->next)
+ {
+ int need_sec;
+
+ if (!overloadHasDocstring(pt, od, md))
+ continue;
+
+ if (sep == NULL)
+ {
+ fprintf(fp, "\"");
+ sep = "\\n\"\n \"";
+ }
+ else
+ {
+ fprintf(fp, "%s", sep);
+ }
+
+ prScopedPythonName(fp, scope_scope, scope_name);
+
+ if (scope_name != NULL)
+ fprintf(fp, ".");
+
+ fprintf(fp, "%s", md->pyname->text);
+ need_sec = prPythonSignature(pt, fp, &od->pysig, FALSE, TRUE, TRUE,
+ TRUE, FALSE);
+ ++currentLineNr;
+
+ if (need_sec)
+ {
+ fprintf(fp, "%s", sep);
+
+ prScopedPythonName(fp, scope_scope, scope_name);
+
+ if (scope_name != NULL)
+ fprintf(fp, ".");
+
+ fprintf(fp, "%s", md->pyname->text);
+ prPythonSignature(pt, fp, &od->pysig, TRUE, TRUE, TRUE, TRUE,
+ FALSE);
+ ++currentLineNr;
+ }
+ }
+
+ if (sep != NULL)
+ fprintf(fp, "\"");
+}
+
+
+/*
+ * Return TRUE if a docstring can be automatically generated for a class
+ * overload.
+ */
+static int overloadHasClassDocstring(sipSpec *pt, ctorDef *ct)
+{
+ if (isPrivateCtor(ct))
+ return FALSE;
+
+ /* If it is versioned then make sure it is the default API. */
+ return isDefaultAPI(pt, ct->api_range);
+}
+
+
+/*
+ * Return TRUE if a docstring can be automatically generated for a class.
+ */
+static int hasClassDocstring(sipSpec *pt, classDef *cd)
+{
+ ctorDef *ct;
+
+ if (!canCreate(cd))
+ return FALSE;
+
+ if (!isDefaultAPI(pt, cd->iff->api_range))
+ return FALSE;
+
+ for (ct = cd->ctors; ct != NULL; ct = ct->next)
+ if (overloadHasClassDocstring(pt, ct))
+ return TRUE;
+
+ return FALSE;
+}
+
+
+/*
+ * Generate the docstring for a class.
+ */
+static void generateClassDocstring(sipSpec *pt, classDef *cd, FILE *fp)
+{
+ const char *sep = NULL;
+ ctorDef *ct;
+
+ for (ct = cd->ctors; ct != NULL; ct = ct->next)
+ {
+ int need_sec;
+
+ if (!overloadHasClassDocstring(pt, ct))
+ continue;
+
+ if (sep == NULL)
+ {
+ fprintf(fp, "\"\\1");
+ sep = "\\n\"\n \"";
+ }
+ else
+ {
+ fprintf(fp, "%s", sep);
+ }
+
+ prScopedPythonName(fp, cd->ecd, cd->pyname->text);
+ need_sec = prPythonSignature(pt, fp, &ct->pysig, FALSE, TRUE, TRUE,
+ TRUE, FALSE);
+ ++currentLineNr;
+
+ if (need_sec)
+ {
+ fprintf(fp, "%s", sep);
+
+ prScopedPythonName(fp, cd->ecd, cd->pyname->text);
+ prPythonSignature(pt, fp, &ct->pysig, TRUE, TRUE, TRUE, TRUE,
+ FALSE);
+ ++currentLineNr;
+ }
+ }
+
+ if (sep != NULL)
+ fprintf(fp, "\"");
+}
+
+
+/*
+ * Returns TRUE if the given API version corresponds to the default.
+ */
+static int isDefaultAPI(sipSpec *pt, apiVersionRangeDef *avd)
+{
+ int def_api;
+
+ /* Handle the trivial case. */
+ if (avd == NULL)
+ return TRUE;
+
+ def_api = findAPI(pt, avd->api_name->text)->from;
+
+ if (avd->from > 0 && avd->from > def_api)
+ return FALSE;
+
+ if (avd->to > 0 && avd->to <= def_api)
+ return FALSE;
+
+ return TRUE;
+}
+
+
+/*
+ * Generate an explicit docstring.
+ */
+static void generateExplicitDocstring(codeBlock *docstring, FILE *fp)
+{
+ const char *sep = NULL;
+ codeBlock *cb;
+
+ for (cb = docstring; cb != NULL; cb = cb->next)
+ {
+ const char *cp;
+
+ if (sep == NULL)
+ {
+ prcode(fp, "\"");
+ sep = "\\n\"\n \"";
+ }
+ else
+ {
+ prcode(fp, "%s", sep);
+ }
+
+ for (cp = cb->frag; *cp != '\0'; ++cp)
+ {
+ if (*cp == '\n')
+ {
+ /* Ignore if this is the last character of the fragment. */
+ if (cp[1] != '\0')
+ prcode(fp, "%s", sep);
+ }
+ else
+ {
+ if (*cp == '\\' || *cp == '\"')
+ prcode(fp, "\\");
+
+ prcode(fp, "%c", *cp);
+ }
+ }
+ }
+
+ if (sep != NULL)
+ prcode(fp, "\"");
+}
diff --git a/sipgen/heap.c b/sipgen/heap.c
new file mode 100644
index 0000000..a4b42ba
--- /dev/null
+++ b/sipgen/heap.c
@@ -0,0 +1,131 @@
+/*
+ * Wrappers around standard functions that use the heap.
+ *
+ * Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com>
+ *
+ * This file is part of SIP.
+ *
+ * This copy of SIP is licensed for use under the terms of the SIP License
+ * Agreement. See the file LICENSE for more details.
+ *
+ * This copy of SIP may also used under the terms of the GNU General Public
+ * License v2 or v3 as published by the Free Software Foundation which can be
+ * found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
+ *
+ * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include "sip.h"
+
+
+static void nomem(void);
+
+
+/*
+ * Wrap malloc() and handle any errors.
+ */
+void *sipMalloc(size_t n)
+{
+ void *h;
+
+ if ((h = malloc(n)) == NULL)
+ nomem();
+
+ memset(h, 0, n);
+
+ return h;
+}
+
+
+/*
+ * Wrap calloc() and handle any errors.
+ */
+void *sipCalloc(size_t nr, size_t n)
+{
+ void *h;
+
+ if ((h = calloc(nr, n)) == NULL)
+ nomem();
+
+ return h;
+}
+
+
+/*
+ * Wrap strdup() and handle any errors.
+ */
+char *sipStrdup(const char *s)
+{
+ char *h;
+
+ if ((h = strdup(s)) == NULL)
+ nomem();
+
+ return h;
+}
+
+
+/*
+ * Return a string on the heap which is the concatenation of all the arguments.
+ */
+char *concat(const char *s, ...)
+{
+ const char *sp;
+ char *new;
+ size_t len;
+ va_list ap;
+
+ /* Find the length of the final string. */
+
+ len = 1;
+ va_start(ap,s);
+
+ for (sp = s; sp != NULL; sp = va_arg(ap, const char *))
+ len += strlen(sp);
+
+ va_end(ap);
+
+ /* Create the new string. */
+
+ new = sipMalloc(len);
+ *new = '\0';
+
+ va_start(ap,s);
+
+ for (sp = s; sp != NULL; sp = va_arg(ap, const char *))
+ strcat(new,sp);
+
+ va_end(ap);
+
+ return new;
+}
+
+
+/*
+ * Append a string to another that is on the heap.
+ */
+
+void append(char **s, const char *new)
+{
+ if ((*s = realloc(*s,strlen(*s) + strlen(new) + 1)) == NULL)
+ nomem();
+
+ strcat(*s,new);
+}
+
+
+/*
+ * Display a standard error message when the heap is exhausted.
+ */
+
+static void nomem(void)
+{
+ fatal("Unable to allocate memory on the heap\n");
+}
diff --git a/sipgen/lexer.c b/sipgen/lexer.c
new file mode 100644
index 0000000..06309e1
--- /dev/null
+++ b/sipgen/lexer.c
@@ -0,0 +1,3500 @@
+#line 2 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.c"
+
+#line 4 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.c"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 35
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart(yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+extern int yyleng;
+
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = (yy_hold_char); \
+ YY_RESTORE_YY_MORE_OFFSET \
+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr) )
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+ : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart (FILE *input_file );
+void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE yy_create_buffer (FILE *file,int size );
+void yy_delete_buffer (YY_BUFFER_STATE b );
+void yy_flush_buffer (YY_BUFFER_STATE b );
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer );
+void yypop_buffer_state (void );
+
+static void yyensure_buffer_stack (void );
+static void yy_load_buffer_state (void );
+static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file );
+
+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size );
+YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len );
+
+void *yyalloc (yy_size_t );
+void *yyrealloc (void *,yy_size_t );
+void yyfree (void * );
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+typedef unsigned char YY_CHAR;
+
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int yylineno;
+
+int yylineno = 1;
+
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[] );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ (yytext_ptr) = yy_bp; \
+ yyleng = (size_t) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
+ *yy_cp = '\0'; \
+ (yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 125
+#define YY_END_OF_BUFFER 126
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_accept[859] =
+ { 0,
+ 0, 0, 0, 0, 0, 0, 126, 124, 74, 75,
+ 124, 124, 124, 78, 124, 77, 77, 124, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 124, 74, 124,
+ 123, 122, 123, 87, 85, 87, 0, 82, 0, 83,
+ 78, 77, 0, 81, 78, 81, 81, 78, 84, 76,
+ 78, 0, 56, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 57, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 86, 78, 0, 73, 0,
+ 0, 78, 76, 79, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 36, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 17, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 78, 49, 80, 80, 80,
+
+ 34, 32, 80, 80, 80, 42, 80, 80, 80, 37,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 47, 80, 80, 80, 40, 80, 0, 0,
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 115, 20, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 121, 80, 80, 80, 80, 80, 80, 80, 21, 45,
+ 80, 80, 48, 38, 80, 80, 80, 80, 80, 35,
+ 80, 80, 29, 80, 80, 80, 53, 80, 80, 80,
+
+ 80, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 80, 31, 80, 80, 80, 80, 80, 80, 39, 80,
+ 80, 80, 80, 80, 23, 80, 43, 46, 22, 80,
+ 80, 80, 80, 80, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 80, 30, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 25,
+ 80, 26, 80, 50, 80, 41, 33, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 6, 0,
+ 0, 0, 0, 0, 0, 7, 0, 0, 0, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 28, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 66, 54, 80, 52, 80, 55, 44, 7,
+ 0, 0, 0, 0, 0, 0, 0, 8, 0, 0,
+
+ 0, 88, 0, 0, 0, 0, 13, 0, 0, 119,
+ 4, 0, 14, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 120, 0, 0, 0, 0,
+ 0, 27, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 51, 24, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 117, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 11, 100,
+ 0, 98, 0, 80, 80, 61, 60, 80, 80, 80,
+ 64, 80, 80, 65, 80, 80, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 114, 16, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 12, 0, 0, 0, 113, 0, 0,
+ 67, 80, 80, 63, 59, 72, 80, 80, 80, 80,
+ 118, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 15, 101, 99, 0, 0, 111, 0, 0, 0, 0,
+ 0, 80, 58, 80, 80, 70, 71, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 116, 0, 104, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 80, 68, 69, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 62, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 112, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 103, 0, 0, 0, 0, 0, 94, 0, 105, 0,
+ 0, 0, 0, 0, 10, 0, 0, 0, 0, 2,
+ 18, 0, 0, 0, 0, 5, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 19, 0,
+ 0, 93, 0, 0, 0, 0, 0, 109, 0, 0,
+ 0, 0, 0, 90, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 9, 0, 0, 92, 96, 0, 0,
+ 102, 110, 107, 0, 106, 89, 0, 0, 0, 108,
+ 0, 0, 0, 91, 0, 95, 97, 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 1, 5, 1, 1, 6, 1, 7, 1,
+ 1, 8, 9, 1, 10, 11, 12, 13, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 15, 1, 1,
+ 1, 1, 1, 1, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 26,
+ 1, 1, 1, 1, 41, 1, 42, 43, 44, 45,
+
+ 46, 47, 48, 49, 50, 26, 51, 52, 53, 54,
+ 55, 56, 26, 57, 58, 59, 60, 61, 62, 63,
+ 64, 26, 1, 65, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int32_t yy_meta[66] =
+ { 0,
+ 1, 1, 2, 1, 1, 1, 1, 1, 1, 3,
+ 3, 3, 4, 4, 1, 4, 4, 4, 4, 4,
+ 4, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 4, 4, 4, 4, 4, 4, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 1
+ } ;
+
+static yyconst flex_int16_t yy_base[867] =
+ { 0,
+ 0, 64, 1770, 65, 64, 66, 1772, 1774, 1774, 1774,
+ 70, 73, 68, 73, 80, 84, 88, 1756, 79, 96,
+ 100, 103, 106, 111, 114, 118, 126, 132, 138, 141,
+ 144, 147, 163, 177, 184, 180, 187, 1705, 94, 226,
+ 1774, 1774, 1749, 1774, 1774, 1756, 159, 1774, 164, 1774,
+ 219, 256, 167, 191, 261, 170, 196, 204, 1774, 0,
+ 1774, 0, 1774, 207, 268, 217, 273, 276, 279, 282,
+ 286, 289, 299, 302, 305, 308, 315, 318, 322, 325,
+ 331, 334, 340, 343, 350, 354, 357, 368, 372, 377,
+ 382, 387, 391, 396, 1774, 218, 430, 102, 1743, 49,
+
+ 130, 195, 1720, 218, 362, 1715, 358, 1708, 362, 1721,
+ 1716, 120, 1707, 1710, 1705, 1774, 409, 425, 408, 126,
+ 414, 454, 0, 0, 459, 466, 462, 469, 472, 477,
+ 484, 487, 494, 497, 500, 503, 506, 512, 515, 521,
+ 526, 529, 540, 543, 552, 555, 558, 561, 564, 569,
+ 572, 579, 583, 586, 591, 597, 1727, 197, 1711, 284,
+ 389, 213, 1704, 1705, 1730, 1709, 112, 1697, 490, 1704,
+ 1706, 1704, 329, 1706, 287, 1688, 1774, 1690, 326, 1701,
+ 396, 1685, 1698, 1683, 1697, 460, 1682, 1693, 1688, 1678,
+ 1683, 1679, 1684, 1676, 1687, 591, 616, 619, 632, 636,
+
+ 639, 643, 646, 649, 653, 661, 664, 667, 670, 673,
+ 676, 679, 682, 685, 688, 691, 699, 705, 708, 715,
+ 725, 732, 736, 741, 744, 750, 754, 757, 409, 1687,
+ 1686, 1673, 1683, 1774, 1681, 1680, 1679, 1679, 1667, 498,
+ 1658, 1679, 1662, 1774, 1673, 1663, 1658, 1664, 1658, 1696,
+ 1658, 1660, 1652, 1664, 1663, 1652, 1658, 1646, 1655, 1653,
+ 1644, 1654, 1642, 461, 1642, 1681, 1652, 1651, 1637, 1636,
+ 1774, 760, 763, 768, 771, 789, 792, 796, 805, 814,
+ 817, 822, 825, 828, 831, 834, 837, 840, 844, 847,
+ 850, 858, 861, 864, 867, 870, 879, 887, 894, 899,
+
+ 903, 1636, 1633, 1634, 1632, 1638, 1629, 1633, 1632, 1640,
+ 1635, 1624, 1624, 1626, 1624, 1620, 1633, 1636, 1622, 1619,
+ 1615, 1624, 1619, 1625, 1625, 1615, 1617, 1613, 1615, 1619,
+ 1615, 1640, 1609, 1598, 1615, 1605, 1607, 592, 1640, 1597,
+ 906, 909, 913, 920, 917, 946, 949, 952, 925, 955,
+ 958, 962, 967, 973, 976, 979, 982, 985, 991, 996,
+ 999, 1004, 1008, 1011, 1604, 1597, 1007, 1608, 1601, 1594,
+ 1599, 1593, 1595, 1596, 1590, 1587, 1586, 1587, 1601, 1581,
+ 1596, 1581, 1594, 1596, 1579, 1586, 1590, 1589, 1587, 1578,
+ 1585, 1575, 1575, 1574, 1577, 1567, 1607, 1579, 1573, 1567,
+
+ 1575, 1565, 1577, 1016, 1019, 1023, 1037, 1051, 1054, 1057,
+ 1061, 1069, 1072, 1075, 1079, 1083, 1088, 1091, 1100, 1103,
+ 1109, 1112, 1115, 1118, 1121, 1126, 1129, 1572, 1599, 1556,
+ 1566, 1568, 1567, 1555, 1569, 1564, 1559, 1558, 1548, 1558,
+ 1546, 1554, 1553, 1556, 1555, 1543, 1553, 1552, 1774, 1551,
+ 1544, 1549, 1542, 1558, 1574, 593, 1549, 1572, 1532, 1774,
+ 1538, 1528, 1537, 1530, 1538, 1529, 1537, 1539, 1535, 1527,
+ 1133, 1138, 1141, 1152, 1148, 1161, 1164, 1167, 1173, 1179,
+ 1182, 1185, 1198, 1201, 1204, 1207, 1210, 1213, 1216, 1774,
+ 1523, 1530, 1534, 1533, 1526, 1523, 1514, 1774, 1512, 1525,
+
+ 513, 1774, 756, 1515, 1513, 1522, 1774, 1548, 1508, 1774,
+ 1774, 1514, 1774, 1517, 1498, 1506, 1505, 1513, 1506, 1502,
+ 1503, 1496, 1504, 1498, 1507, 1774, 1505, 1504, 1504, 1502,
+ 1529, 1219, 1222, 1226, 1230, 1233, 1236, 1248, 1251, 1259,
+ 1262, 1265, 1271, 1274, 1277, 1284, 1501, 1498, 1487, 1498,
+ 1524, 1482, 1494, 1493, 1496, 1480, 1481, 1481, 1488, 1473,
+ 1484, 1477, 253, 1475, 1471, 1470, 1774, 1471, 1481, 1480,
+ 1482, 1499, 1477, 1463, 1470, 1477, 1464, 1471, 1774, 1774,
+ 1470, 1774, 1473, 1289, 1292, 1299, 1302, 1305, 1308, 1315,
+ 1319, 1322, 1326, 1329, 1336, 1339, 1468, 1467, 1495, 1494,
+
+ 1455, 1463, 1491, 1479, 1447, 1450, 551, 1460, 1444, 1446,
+ 1774, 1774, 1446, 1454, 1454, 1452, 1455, 1450, 1449, 1448,
+ 1448, 1438, 1445, 1774, 1448, 1437, 1470, 1774, 1430, 1427,
+ 1342, 1348, 1357, 1360, 1363, 1366, 1369, 1372, 1375, 1378,
+ 1774, 1428, 1424, 1423, 1422, 1464, 1420, 1424, 1432, 1424,
+ 1416, 1411, 1419, 1431, 1426, 1427, 1428, 1423, 1450, 1408,
+ 1774, 1774, 1774, 1420, 1421, 1774, 1410, 1386, 1379, 1405,
+ 1378, 1383, 1390, 1395, 1403, 1406, 1409, 1393, 1362, 1361,
+ 1349, 1338, 1350, 1346, 1319, 1327, 1318, 1300, 1310, 1284,
+ 1285, 1774, 1277, 1774, 1266, 1257, 1248, 1245, 1241, 1232,
+
+ 1222, 1209, 1208, 1415, 1418, 1421, 1199, 1204, 1202, 1176,
+ 1159, 1158, 1143, 1174, 1136, 1169, 1135, 1130, 1105, 1097,
+ 1108, 1101, 1087, 1116, 1057, 1058, 1065, 1060, 1059, 1050,
+ 1428, 1032, 1030, 1013, 1040, 1009, 1008, 1000, 996, 988,
+ 990, 1021, 984, 980, 948, 947, 953, 944, 926, 935,
+ 933, 893, 1774, 905, 892, 900, 888, 885, 885, 861,
+ 844, 854, 850, 848, 850, 831, 837, 837, 811, 847,
+ 1774, 846, 808, 784, 763, 771, 1774, 800, 1774, 795,
+ 794, 764, 748, 778, 1774, 735, 775, 733, 743, 1774,
+ 1774, 741, 730, 702, 703, 1774, 690, 684, 678, 677,
+
+ 675, 682, 705, 667, 660, 652, 648, 620, 1774, 595,
+ 592, 1774, 580, 580, 587, 578, 577, 1774, 564, 568,
+ 553, 532, 539, 1774, 482, 473, 446, 473, 413, 407,
+ 391, 386, 375, 1774, 344, 301, 1774, 1774, 330, 284,
+ 1774, 1774, 1774, 277, 1774, 1774, 261, 247, 192, 1774,
+ 175, 166, 119, 1774, 57, 1774, 1774, 1774, 1440, 1444,
+ 1448, 1452, 1454, 1456, 1460, 74
+ } ;
+
+static yyconst flex_int16_t yy_def[867] =
+ { 0,
+ 858, 1, 859, 859, 860, 860, 858, 858, 858, 858,
+ 861, 862, 858, 863, 858, 858, 858, 858, 864, 864,
+ 864, 864, 864, 864, 864, 864, 864, 864, 864, 864,
+ 864, 864, 864, 864, 864, 864, 864, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 861, 858, 862, 858,
+ 858, 858, 863, 863, 863, 863, 863, 863, 858, 865,
+ 858, 866, 858, 864, 864, 864, 864, 864, 864, 864,
+ 864, 864, 864, 864, 864, 864, 864, 864, 864, 864,
+ 864, 864, 864, 864, 864, 864, 864, 864, 864, 864,
+ 864, 864, 864, 864, 858, 858, 858, 858, 858, 858,
+
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 863, 858,
+ 863, 863, 865, 866, 864, 864, 864, 864, 864, 864,
+ 864, 864, 864, 864, 864, 864, 864, 864, 864, 864,
+ 864, 864, 864, 864, 864, 864, 864, 864, 864, 864,
+ 864, 864, 864, 864, 864, 864, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 864, 864, 864, 864,
+
+ 864, 864, 864, 864, 864, 864, 864, 864, 864, 864,
+ 864, 864, 864, 864, 864, 864, 864, 864, 864, 864,
+ 864, 864, 864, 864, 864, 864, 864, 864, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 864, 864, 864, 864, 864, 864, 864, 864, 864,
+ 864, 864, 864, 864, 864, 864, 864, 864, 864, 864,
+ 864, 864, 864, 864, 864, 864, 864, 864, 864, 864,
+
+ 864, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 864, 864, 864, 864, 864, 864, 864, 864, 864, 864,
+ 864, 864, 864, 864, 864, 864, 864, 864, 864, 864,
+ 864, 864, 864, 864, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+
+ 858, 858, 858, 864, 864, 864, 864, 864, 864, 864,
+ 864, 864, 864, 864, 864, 864, 864, 864, 864, 864,
+ 864, 864, 864, 864, 864, 864, 864, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 864, 864, 864, 864, 864, 864, 864, 864, 864, 864,
+ 864, 864, 864, 864, 864, 864, 864, 864, 864, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 864, 864, 864, 864, 864, 864, 864, 864, 864,
+ 864, 864, 864, 864, 864, 864, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 864, 864, 864, 864, 864, 864, 864,
+ 864, 864, 864, 864, 864, 864, 858, 858, 858, 858,
+
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 864, 864, 864, 864, 864, 864, 864, 864, 864, 864,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 864, 864, 864, 864, 864, 864, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+
+ 858, 858, 858, 864, 864, 864, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 864, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 0, 858, 858,
+ 858, 858, 858, 858, 858, 858
+ } ;
+
+static yyconst flex_int16_t yy_nxt[1840] =
+ { 0,
+ 8, 9, 10, 9, 11, 8, 12, 8, 8, 13,
+ 14, 15, 16, 17, 18, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 20, 19,
+ 19, 21, 19, 22, 19, 19, 19, 19, 19, 19,
+ 19, 19, 23, 24, 25, 26, 27, 19, 19, 28,
+ 19, 29, 19, 30, 31, 32, 19, 33, 34, 35,
+ 36, 37, 19, 19, 38, 39, 45, 42, 45, 40,
+ 43, 46, 48, 46, 48, 50, 168, 124, 51, 50,
+ 52, 52, 53, 54, 53, 55, 55, 59, 53, 56,
+ 53, 60, 57, 58, 51, 96, 52, 52, 51, 97,
+
+ 52, 52, 857, 169, 61, 53, 56, 53, 61, 53,
+ 56, 53, 53, 56, 53, 53, 56, 53, 57, 58,
+ 53, 56, 53, 53, 56, 53, 67, 53, 56, 53,
+ 61, 65, 165, 236, 61, 53, 56, 53, 196, 196,
+ 66, 53, 56, 53, 237, 166, 62, 53, 56, 53,
+ 53, 56, 53, 53, 56, 53, 53, 56, 53, 69,
+ 68, 48, 70, 48, 856, 71, 50, 75, 72, 191,
+ 50, 73, 53, 56, 53, 170, 53, 76, 53, 53,
+ 74, 53, 79, 192, 171, 77, 53, 56, 53, 53,
+ 56, 53, 78, 53, 56, 53, 53, 56, 53, 80,
+
+ 53, 119, 53, 81, 120, 121, 82, 53, 122, 122,
+ 855, 83, 84, 53, 85, 53, 53, 56, 53, 96,
+ 854, 86, 87, 97, 168, 88, 53, 56, 53, 92,
+ 94, 117, 117, 89, 93, 175, 853, 91, 118, 61,
+ 90, 98, 99, 100, 101, 102, 103, 104, 172, 105,
+ 126, 229, 106, 107, 232, 108, 109, 173, 110, 111,
+ 112, 113, 114, 176, 118, 61, 51, 233, 52, 52,
+ 53, 613, 53, 55, 55, 614, 61, 53, 56, 53,
+ 57, 58, 53, 56, 53, 53, 56, 53, 53, 56,
+ 53, 53, 56, 53, 125, 53, 56, 53, 53, 56,
+
+ 53, 852, 61, 127, 248, 851, 57, 58, 53, 56,
+ 53, 53, 56, 53, 53, 56, 53, 53, 56, 53,
+ 129, 249, 850, 130, 53, 56, 53, 53, 56, 53,
+ 128, 53, 56, 53, 53, 56, 53, 172, 849, 131,
+ 53, 56, 53, 53, 56, 53, 230, 848, 132, 53,
+ 56, 53, 53, 56, 53, 847, 135, 134, 133, 53,
+ 56, 53, 136, 53, 56, 53, 53, 56, 53, 252,
+ 140, 138, 245, 137, 139, 253, 143, 53, 56, 53,
+ 141, 53, 56, 53, 246, 142, 53, 56, 53, 846,
+ 145, 53, 56, 53, 144, 147, 53, 56, 53, 181,
+
+ 53, 56, 53, 182, 146, 53, 56, 53, 177, 149,
+ 148, 185, 183, 186, 178, 179, 187, 53, 188, 53,
+ 845, 117, 117, 53, 150, 53, 122, 122, 118, 61,
+ 844, 151, 152, 120, 120, 177, 843, 196, 196, 153,
+ 155, 178, 231, 154, 156, 157, 255, 158, 159, 160,
+ 103, 256, 842, 161, 118, 61, 106, 162, 841, 108,
+ 163, 239, 302, 53, 164, 53, 122, 122, 53, 56,
+ 53, 53, 56, 53, 58, 53, 56, 53, 53, 56,
+ 53, 53, 56, 53, 333, 197, 53, 56, 53, 198,
+ 840, 334, 199, 53, 56, 53, 53, 56, 53, 839,
+
+ 58, 261, 200, 53, 56, 53, 53, 56, 53, 53,
+ 56, 53, 53, 56, 53, 53, 56, 53, 838, 262,
+ 201, 53, 56, 53, 53, 56, 53, 837, 202, 205,
+ 53, 56, 53, 556, 203, 53, 56, 53, 53, 56,
+ 53, 204, 239, 240, 209, 241, 206, 557, 207, 53,
+ 56, 53, 53, 56, 53, 309, 836, 208, 310, 210,
+ 211, 53, 56, 53, 53, 56, 53, 53, 56, 53,
+ 53, 56, 53, 53, 56, 53, 835, 212, 53, 56,
+ 53, 53, 56, 53, 651, 652, 213, 214, 53, 56,
+ 53, 215, 53, 56, 53, 53, 56, 53, 834, 216,
+
+ 53, 56, 53, 196, 196, 217, 53, 56, 53, 400,
+ 517, 61, 833, 218, 401, 518, 219, 223, 832, 221,
+ 220, 831, 830, 222, 224, 53, 56, 53, 53, 56,
+ 53, 829, 225, 828, 827, 227, 826, 61, 228, 825,
+ 272, 53, 56, 53, 226, 53, 56, 53, 53, 56,
+ 53, 274, 53, 56, 53, 53, 56, 53, 53, 56,
+ 53, 273, 53, 56, 53, 824, 275, 276, 277, 278,
+ 53, 56, 53, 53, 56, 53, 53, 56, 53, 53,
+ 56, 53, 53, 56, 53, 53, 56, 53, 53, 56,
+ 53, 53, 56, 53, 53, 56, 53, 53, 56, 53,
+
+ 53, 56, 53, 279, 281, 823, 822, 280, 53, 56,
+ 53, 821, 283, 282, 53, 56, 53, 53, 56, 53,
+ 286, 820, 819, 287, 53, 56, 53, 818, 284, 817,
+ 288, 816, 815, 285, 53, 56, 53, 289, 814, 813,
+ 291, 53, 56, 53, 292, 53, 56, 53, 812, 290,
+ 53, 56, 53, 53, 56, 53, 811, 294, 295, 53,
+ 56, 53, 293, 53, 56, 53, 53, 56, 53, 53,
+ 56, 53, 53, 56, 53, 558, 296, 53, 56, 53,
+ 53, 56, 53, 559, 810, 298, 809, 808, 341, 560,
+ 807, 299, 806, 297, 805, 804, 343, 342, 53, 56,
+
+ 53, 53, 56, 53, 803, 53, 56, 53, 802, 300,
+ 344, 801, 800, 301, 53, 56, 53, 799, 345, 347,
+ 798, 797, 348, 53, 56, 53, 53, 56, 53, 796,
+ 346, 53, 56, 53, 53, 56, 53, 53, 56, 53,
+ 53, 56, 53, 53, 56, 53, 53, 56, 53, 53,
+ 56, 53, 795, 53, 56, 53, 53, 56, 53, 53,
+ 56, 53, 349, 794, 793, 350, 792, 53, 56, 53,
+ 53, 56, 53, 53, 56, 53, 53, 56, 53, 53,
+ 56, 53, 791, 354, 790, 789, 351, 355, 53, 56,
+ 53, 788, 352, 787, 786, 353, 53, 56, 53, 785,
+
+ 784, 356, 357, 53, 56, 53, 783, 358, 53, 56,
+ 53, 360, 53, 56, 53, 53, 56, 53, 53, 56,
+ 53, 404, 53, 56, 53, 359, 53, 56, 53, 53,
+ 56, 53, 361, 413, 53, 56, 53, 407, 408, 782,
+ 363, 781, 405, 364, 780, 779, 409, 362, 778, 410,
+ 777, 776, 406, 411, 412, 53, 56, 53, 53, 56,
+ 53, 53, 56, 53, 53, 56, 53, 53, 56, 53,
+ 415, 53, 56, 53, 775, 414, 53, 56, 53, 774,
+ 773, 416, 53, 56, 53, 53, 56, 53, 53, 56,
+ 53, 53, 56, 53, 53, 56, 53, 772, 771, 418,
+
+ 53, 56, 53, 770, 417, 53, 56, 53, 53, 56,
+ 53, 769, 420, 53, 56, 53, 419, 53, 56, 53,
+ 53, 56, 53, 430, 431, 53, 56, 53, 53, 56,
+ 53, 421, 53, 56, 53, 768, 422, 767, 766, 432,
+ 433, 765, 471, 764, 434, 424, 53, 56, 53, 425,
+ 763, 762, 473, 761, 423, 760, 472, 759, 758, 426,
+ 53, 56, 53, 53, 56, 53, 53, 56, 53, 427,
+ 53, 56, 53, 476, 474, 757, 756, 475, 53, 56,
+ 53, 53, 56, 53, 53, 56, 53, 477, 53, 56,
+ 53, 481, 53, 56, 53, 755, 480, 53, 56, 53,
+
+ 53, 56, 53, 754, 478, 753, 752, 482, 479, 53,
+ 56, 53, 53, 56, 53, 751, 750, 483, 53, 56,
+ 53, 53, 56, 53, 53, 56, 53, 53, 56, 53,
+ 53, 56, 53, 749, 485, 53, 56, 53, 53, 56,
+ 53, 748, 53, 56, 53, 747, 484, 53, 56, 53,
+ 53, 56, 53, 746, 487, 745, 486, 53, 56, 53,
+ 488, 53, 56, 53, 533, 489, 532, 534, 744, 535,
+ 53, 56, 53, 53, 56, 53, 53, 56, 53, 743,
+ 742, 536, 53, 56, 53, 537, 741, 538, 53, 56,
+ 53, 53, 56, 53, 53, 56, 53, 539, 541, 740,
+
+ 543, 739, 738, 540, 737, 736, 542, 53, 56, 53,
+ 53, 56, 53, 53, 56, 53, 53, 56, 53, 53,
+ 56, 53, 53, 56, 53, 53, 56, 53, 53, 56,
+ 53, 53, 56, 53, 735, 53, 56, 53, 544, 53,
+ 56, 53, 53, 56, 53, 53, 56, 53, 734, 545,
+ 733, 584, 585, 732, 546, 588, 730, 53, 56, 53,
+ 53, 56, 53, 729, 586, 589, 728, 587, 53, 56,
+ 53, 53, 56, 53, 53, 56, 53, 590, 591, 592,
+ 53, 56, 53, 53, 56, 53, 53, 56, 53, 727,
+ 726, 595, 596, 53, 56, 53, 725, 594, 53, 56,
+
+ 53, 53, 56, 53, 724, 593, 723, 632, 53, 56,
+ 53, 53, 56, 53, 53, 56, 53, 53, 56, 53,
+ 722, 721, 633, 631, 53, 56, 53, 634, 53, 56,
+ 53, 53, 56, 53, 635, 53, 56, 53, 53, 56,
+ 53, 720, 719, 637, 638, 53, 56, 53, 53, 56,
+ 53, 53, 56, 53, 718, 717, 636, 53, 56, 53,
+ 716, 715, 640, 714, 672, 639, 53, 56, 53, 53,
+ 56, 53, 53, 56, 53, 53, 56, 53, 53, 56,
+ 53, 53, 56, 53, 53, 56, 53, 53, 56, 53,
+ 713, 673, 53, 56, 53, 675, 712, 711, 674, 53,
+
+ 56, 53, 710, 676, 53, 56, 53, 709, 708, 704,
+ 707, 677, 53, 56, 53, 53, 56, 53, 53, 56,
+ 53, 703, 702, 705, 53, 56, 53, 53, 56, 53,
+ 53, 56, 53, 701, 731, 700, 706, 53, 56, 53,
+ 41, 41, 41, 41, 44, 44, 44, 44, 47, 47,
+ 47, 47, 49, 49, 49, 49, 56, 56, 64, 64,
+ 123, 699, 123, 123, 698, 697, 696, 695, 694, 693,
+ 692, 691, 690, 689, 688, 687, 686, 685, 684, 683,
+ 682, 681, 680, 679, 678, 671, 670, 669, 668, 667,
+ 666, 665, 664, 663, 662, 661, 660, 659, 658, 657,
+
+ 656, 655, 654, 653, 650, 649, 648, 647, 646, 645,
+ 644, 643, 642, 641, 630, 629, 628, 627, 626, 625,
+ 624, 623, 622, 621, 620, 619, 618, 617, 616, 615,
+ 612, 611, 610, 609, 608, 607, 606, 605, 604, 603,
+ 602, 601, 600, 599, 598, 597, 583, 582, 581, 580,
+ 579, 578, 577, 576, 575, 574, 573, 572, 571, 570,
+ 569, 568, 567, 566, 565, 564, 563, 562, 561, 555,
+ 554, 553, 552, 551, 550, 549, 548, 547, 531, 530,
+ 529, 528, 527, 526, 525, 524, 523, 522, 521, 520,
+ 519, 516, 515, 514, 513, 512, 511, 510, 509, 508,
+
+ 507, 506, 505, 504, 503, 502, 501, 500, 499, 498,
+ 497, 496, 495, 494, 493, 492, 491, 490, 470, 469,
+ 468, 467, 466, 465, 464, 463, 462, 461, 460, 459,
+ 458, 457, 456, 455, 454, 453, 452, 451, 450, 449,
+ 448, 447, 446, 445, 444, 443, 442, 441, 440, 439,
+ 438, 437, 436, 435, 429, 428, 403, 402, 399, 398,
+ 397, 396, 395, 394, 393, 392, 391, 390, 389, 388,
+ 387, 386, 385, 384, 383, 382, 381, 380, 379, 378,
+ 377, 376, 375, 374, 373, 372, 371, 370, 369, 368,
+ 367, 366, 365, 309, 340, 339, 338, 337, 336, 335,
+
+ 332, 331, 330, 329, 328, 327, 326, 325, 324, 323,
+ 322, 321, 320, 319, 318, 317, 316, 315, 314, 313,
+ 312, 311, 308, 307, 306, 305, 304, 303, 256, 252,
+ 245, 271, 270, 269, 268, 267, 266, 265, 264, 263,
+ 260, 259, 258, 257, 254, 251, 250, 247, 244, 243,
+ 242, 238, 235, 234, 191, 186, 170, 165, 195, 194,
+ 193, 190, 189, 184, 180, 174, 167, 116, 115, 95,
+ 63, 858, 42, 7, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858
+ } ;
+
+static yyconst flex_int16_t yy_chk[1840] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 2, 5, 4, 6, 2,
+ 4, 5, 11, 6, 11, 12, 100, 866, 13, 12,
+ 13, 13, 14, 14, 14, 14, 14, 15, 19, 19,
+ 19, 15, 14, 14, 16, 39, 16, 16, 17, 39,
+
+ 17, 17, 855, 100, 16, 20, 20, 20, 17, 21,
+ 21, 21, 22, 22, 22, 23, 23, 23, 14, 14,
+ 24, 24, 24, 25, 25, 25, 22, 26, 26, 26,
+ 16, 20, 98, 167, 17, 27, 27, 27, 120, 120,
+ 21, 28, 28, 28, 167, 98, 16, 29, 29, 29,
+ 30, 30, 30, 31, 31, 31, 32, 32, 32, 24,
+ 23, 47, 24, 47, 853, 24, 49, 27, 25, 112,
+ 49, 26, 33, 33, 33, 101, 53, 27, 53, 56,
+ 26, 56, 30, 112, 101, 28, 34, 34, 34, 36,
+ 36, 36, 29, 35, 35, 35, 37, 37, 37, 31,
+
+ 54, 54, 54, 32, 57, 57, 32, 57, 57, 57,
+ 852, 33, 33, 58, 33, 58, 64, 64, 64, 96,
+ 851, 33, 34, 96, 158, 34, 66, 66, 66, 36,
+ 37, 51, 51, 34, 36, 104, 849, 35, 51, 51,
+ 34, 40, 40, 40, 40, 40, 40, 40, 102, 40,
+ 66, 158, 40, 40, 162, 40, 40, 102, 40, 40,
+ 40, 40, 40, 104, 51, 51, 52, 162, 52, 52,
+ 55, 563, 55, 55, 55, 563, 52, 65, 65, 65,
+ 55, 55, 67, 67, 67, 68, 68, 68, 69, 69,
+ 69, 70, 70, 70, 65, 71, 71, 71, 72, 72,
+
+ 72, 848, 52, 67, 175, 847, 55, 55, 73, 73,
+ 73, 74, 74, 74, 75, 75, 75, 76, 76, 76,
+ 69, 175, 844, 70, 77, 77, 77, 78, 78, 78,
+ 68, 79, 79, 79, 80, 80, 80, 160, 840, 71,
+ 81, 81, 81, 82, 82, 82, 160, 839, 72, 83,
+ 83, 83, 84, 84, 84, 836, 75, 74, 73, 85,
+ 85, 85, 76, 86, 86, 86, 87, 87, 87, 179,
+ 80, 78, 173, 77, 79, 179, 82, 88, 88, 88,
+ 81, 89, 89, 89, 173, 81, 90, 90, 90, 835,
+ 84, 91, 91, 91, 83, 86, 92, 92, 92, 107,
+
+ 93, 93, 93, 107, 85, 94, 94, 94, 105, 87,
+ 86, 109, 107, 109, 105, 105, 109, 119, 109, 119,
+ 833, 117, 117, 121, 88, 121, 121, 121, 117, 117,
+ 832, 89, 90, 118, 118, 161, 831, 118, 118, 91,
+ 93, 161, 161, 92, 94, 97, 181, 97, 97, 97,
+ 97, 181, 830, 97, 117, 117, 97, 97, 829, 97,
+ 97, 229, 229, 122, 97, 122, 122, 122, 125, 125,
+ 125, 127, 127, 127, 122, 126, 126, 126, 128, 128,
+ 128, 129, 129, 129, 264, 125, 130, 130, 130, 126,
+ 828, 264, 126, 131, 131, 131, 132, 132, 132, 827,
+
+ 122, 186, 127, 133, 133, 133, 134, 134, 134, 135,
+ 135, 135, 136, 136, 136, 137, 137, 137, 826, 186,
+ 128, 138, 138, 138, 139, 139, 139, 825, 129, 132,
+ 140, 140, 140, 501, 130, 141, 141, 141, 142, 142,
+ 142, 131, 169, 169, 136, 169, 133, 501, 134, 143,
+ 143, 143, 144, 144, 144, 240, 823, 135, 240, 138,
+ 139, 145, 145, 145, 146, 146, 146, 147, 147, 147,
+ 148, 148, 148, 149, 149, 149, 822, 140, 150, 150,
+ 150, 151, 151, 151, 607, 607, 141, 142, 152, 152,
+ 152, 143, 153, 153, 153, 154, 154, 154, 821, 144,
+
+ 155, 155, 155, 196, 196, 145, 156, 156, 156, 338,
+ 456, 196, 820, 146, 338, 456, 147, 151, 819, 149,
+ 148, 817, 816, 150, 152, 197, 197, 197, 198, 198,
+ 198, 815, 153, 814, 813, 155, 811, 196, 156, 810,
+ 198, 199, 199, 199, 154, 200, 200, 200, 201, 201,
+ 201, 200, 202, 202, 202, 203, 203, 203, 204, 204,
+ 204, 199, 205, 205, 205, 808, 200, 200, 200, 200,
+ 206, 206, 206, 207, 207, 207, 208, 208, 208, 209,
+ 209, 209, 210, 210, 210, 211, 211, 211, 212, 212,
+ 212, 213, 213, 213, 214, 214, 214, 215, 215, 215,
+
+ 216, 216, 216, 203, 205, 807, 806, 204, 217, 217,
+ 217, 805, 208, 207, 218, 218, 218, 219, 219, 219,
+ 212, 804, 803, 213, 220, 220, 220, 802, 209, 801,
+ 214, 800, 799, 211, 221, 221, 221, 215, 798, 797,
+ 217, 222, 222, 222, 217, 223, 223, 223, 795, 216,
+ 224, 224, 224, 225, 225, 225, 794, 219, 220, 226,
+ 226, 226, 218, 227, 227, 227, 228, 228, 228, 272,
+ 272, 272, 273, 273, 273, 503, 221, 274, 274, 274,
+ 275, 275, 275, 503, 793, 224, 792, 789, 272, 503,
+ 788, 225, 787, 222, 786, 784, 274, 273, 276, 276,
+
+ 276, 277, 277, 277, 783, 278, 278, 278, 782, 226,
+ 275, 781, 780, 228, 279, 279, 279, 778, 276, 278,
+ 776, 775, 278, 280, 280, 280, 281, 281, 281, 774,
+ 277, 282, 282, 282, 283, 283, 283, 284, 284, 284,
+ 285, 285, 285, 286, 286, 286, 287, 287, 287, 288,
+ 288, 288, 773, 289, 289, 289, 290, 290, 290, 291,
+ 291, 291, 281, 772, 770, 282, 769, 292, 292, 292,
+ 293, 293, 293, 294, 294, 294, 295, 295, 295, 296,
+ 296, 296, 768, 288, 767, 766, 285, 289, 297, 297,
+ 297, 765, 286, 764, 763, 287, 298, 298, 298, 762,
+
+ 761, 291, 292, 299, 299, 299, 760, 294, 300, 300,
+ 300, 296, 301, 301, 301, 341, 341, 341, 342, 342,
+ 342, 341, 343, 343, 343, 295, 345, 345, 345, 344,
+ 344, 344, 298, 345, 349, 349, 349, 344, 344, 759,
+ 300, 758, 342, 301, 757, 756, 344, 299, 755, 344,
+ 754, 752, 343, 344, 344, 346, 346, 346, 347, 347,
+ 347, 348, 348, 348, 350, 350, 350, 351, 351, 351,
+ 347, 352, 352, 352, 751, 346, 353, 353, 353, 750,
+ 749, 348, 354, 354, 354, 355, 355, 355, 356, 356,
+ 356, 357, 357, 357, 358, 358, 358, 748, 747, 351,
+
+ 359, 359, 359, 746, 350, 360, 360, 360, 361, 361,
+ 361, 745, 353, 362, 362, 362, 352, 363, 363, 363,
+ 364, 364, 364, 367, 367, 404, 404, 404, 405, 405,
+ 405, 354, 406, 406, 406, 744, 356, 743, 742, 367,
+ 367, 741, 404, 740, 367, 361, 407, 407, 407, 362,
+ 739, 738, 407, 737, 360, 736, 406, 735, 734, 363,
+ 408, 408, 408, 409, 409, 409, 410, 410, 410, 364,
+ 411, 411, 411, 410, 408, 733, 732, 409, 412, 412,
+ 412, 413, 413, 413, 414, 414, 414, 411, 415, 415,
+ 415, 414, 416, 416, 416, 730, 413, 417, 417, 417,
+
+ 418, 418, 418, 729, 412, 728, 727, 415, 412, 419,
+ 419, 419, 420, 420, 420, 726, 725, 416, 421, 421,
+ 421, 422, 422, 422, 423, 423, 423, 424, 424, 424,
+ 425, 425, 425, 724, 418, 426, 426, 426, 427, 427,
+ 427, 723, 471, 471, 471, 722, 417, 472, 472, 472,
+ 473, 473, 473, 721, 421, 720, 419, 475, 475, 475,
+ 423, 474, 474, 474, 472, 425, 471, 473, 719, 474,
+ 476, 476, 476, 477, 477, 477, 478, 478, 478, 718,
+ 717, 475, 479, 479, 479, 476, 716, 477, 480, 480,
+ 480, 481, 481, 481, 482, 482, 482, 478, 480, 715,
+
+ 482, 714, 713, 479, 712, 711, 481, 483, 483, 483,
+ 484, 484, 484, 485, 485, 485, 486, 486, 486, 487,
+ 487, 487, 488, 488, 488, 489, 489, 489, 532, 532,
+ 532, 533, 533, 533, 710, 534, 534, 534, 483, 535,
+ 535, 535, 536, 536, 536, 537, 537, 537, 709, 485,
+ 708, 533, 534, 707, 487, 537, 703, 538, 538, 538,
+ 539, 539, 539, 702, 535, 538, 701, 536, 540, 540,
+ 540, 541, 541, 541, 542, 542, 542, 539, 540, 541,
+ 543, 543, 543, 544, 544, 544, 545, 545, 545, 700,
+ 699, 544, 544, 546, 546, 546, 698, 543, 584, 584,
+
+ 584, 585, 585, 585, 697, 542, 696, 585, 586, 586,
+ 586, 587, 587, 587, 588, 588, 588, 589, 589, 589,
+ 695, 693, 588, 584, 590, 590, 590, 589, 591, 591,
+ 591, 592, 592, 592, 590, 593, 593, 593, 594, 594,
+ 594, 691, 690, 593, 593, 595, 595, 595, 596, 596,
+ 596, 631, 631, 631, 689, 688, 592, 632, 632, 632,
+ 687, 686, 596, 685, 632, 595, 633, 633, 633, 634,
+ 634, 634, 635, 635, 635, 636, 636, 636, 637, 637,
+ 637, 638, 638, 638, 639, 639, 639, 640, 640, 640,
+ 684, 633, 672, 672, 672, 638, 683, 682, 637, 673,
+
+ 673, 673, 681, 639, 674, 674, 674, 680, 679, 672,
+ 678, 640, 675, 675, 675, 676, 676, 676, 677, 677,
+ 677, 671, 670, 674, 704, 704, 704, 705, 705, 705,
+ 706, 706, 706, 669, 704, 668, 675, 731, 731, 731,
+ 859, 859, 859, 859, 860, 860, 860, 860, 861, 861,
+ 861, 861, 862, 862, 862, 862, 863, 863, 864, 864,
+ 865, 667, 865, 865, 665, 664, 660, 659, 658, 657,
+ 656, 655, 654, 653, 652, 651, 650, 649, 648, 647,
+ 646, 645, 644, 643, 642, 630, 629, 627, 626, 625,
+ 623, 622, 621, 620, 619, 618, 617, 616, 615, 614,
+
+ 613, 610, 609, 608, 606, 605, 604, 603, 602, 601,
+ 600, 599, 598, 597, 583, 581, 578, 577, 576, 575,
+ 574, 573, 572, 571, 570, 569, 568, 566, 565, 564,
+ 562, 561, 560, 559, 558, 557, 556, 555, 554, 553,
+ 552, 551, 550, 549, 548, 547, 531, 530, 529, 528,
+ 527, 525, 524, 523, 522, 521, 520, 519, 518, 517,
+ 516, 515, 514, 512, 509, 508, 506, 505, 504, 500,
+ 499, 497, 496, 495, 494, 493, 492, 491, 470, 469,
+ 468, 467, 466, 465, 464, 463, 462, 461, 459, 458,
+ 457, 455, 454, 453, 452, 451, 450, 448, 447, 446,
+
+ 445, 444, 443, 442, 441, 440, 439, 438, 437, 436,
+ 435, 434, 433, 432, 431, 430, 429, 428, 403, 402,
+ 401, 400, 399, 398, 397, 396, 395, 394, 393, 392,
+ 391, 390, 389, 388, 387, 386, 385, 384, 383, 382,
+ 381, 380, 379, 378, 377, 376, 375, 374, 373, 372,
+ 371, 370, 369, 368, 366, 365, 340, 339, 337, 336,
+ 335, 334, 333, 332, 331, 330, 329, 328, 327, 326,
+ 325, 324, 323, 322, 321, 320, 319, 318, 317, 316,
+ 315, 314, 313, 312, 311, 310, 309, 308, 307, 306,
+ 305, 304, 303, 302, 270, 269, 268, 267, 266, 265,
+
+ 263, 262, 261, 260, 259, 258, 257, 256, 255, 254,
+ 253, 252, 251, 250, 249, 248, 247, 246, 245, 243,
+ 242, 241, 239, 238, 237, 236, 235, 233, 232, 231,
+ 230, 195, 194, 193, 192, 191, 190, 189, 188, 187,
+ 185, 184, 183, 182, 180, 178, 176, 174, 172, 171,
+ 170, 168, 166, 165, 164, 163, 159, 157, 115, 114,
+ 113, 111, 110, 108, 106, 103, 99, 46, 43, 38,
+ 18, 7, 3, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858, 858,
+ 858, 858, 858, 858, 858, 858, 858, 858, 858
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int yy_flex_debug;
+int yy_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+/*
+ * The SIP lexer.
+ *
+ * Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com>
+ *
+ * This file is part of SIP.
+ *
+ * This copy of SIP is licensed for use under the terms of the SIP License
+ * Agreement. See the file LICENSE for more details.
+ *
+ * This copy of SIP may also used under the terms of the GNU General Public
+ * License v2 or v3 as published by the Free Software Foundation which can be
+ * found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
+ *
+ * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#line 20 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "sip.h"
+#include "parser.h"
+
+
+#ifndef FLEX_SCANNER
+#error "Only flex is supported at the moment"
+#endif
+
+
+#define YY_NO_UNISTD_H
+#define YY_FATAL_ERROR(s) fatallex(s)
+
+#define MAX_INCLUDE_DEPTH 10
+#define MAX_CODE_LINE_LENGTH 1000
+
+
+static struct inputFile {
+ int lineno; /* The line number. */
+ YY_BUFFER_STATE bs; /* The flex buffer state handle. */
+ char *name; /* The file name. */
+ char *cwd; /* The path part of the file name. */
+ parserContext pc; /* The parser context. */
+} inputFileStack[MAX_INCLUDE_DEPTH];
+
+static int currentFile = -1; /* Index of the current input file. */
+static char codeLine[MAX_CODE_LINE_LENGTH + 2]; /* The current code line. */
+static int codeIdx = -1; /* Index of next code character. */
+
+static FILE *openFile(const char *);
+static void fatallex(char *);
+
+
+#line 1203 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.c"
+
+#define INITIAL 0
+#define code 1
+#define ccomment 2
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy (void );
+
+int yyget_debug (void );
+
+void yyset_debug (int debug_flag );
+
+YY_EXTRA_TYPE yyget_extra (void );
+
+void yyset_extra (YY_EXTRA_TYPE user_defined );
+
+FILE *yyget_in (void );
+
+void yyset_in (FILE * in_str );
+
+FILE *yyget_out (void );
+
+void yyset_out (FILE * out_str );
+
+int yyget_leng (void );
+
+char *yyget_text (void );
+
+int yyget_lineno (void );
+
+void yyset_lineno (int line_number );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap (void );
+#else
+extern int yywrap (void );
+#endif
+#endif
+
+ static void yyunput (int c,char *buf_ptr );
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ size_t n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex (void);
+
+#define YY_DECL int yylex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ if ( yyleng > 0 ) \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
+ (yytext[yyleng - 1] == '\n'); \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+
+#line 60 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+
+
+#line 1398 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.c"
+
+ if ( !(yy_init) )
+ {
+ (yy_init) = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! (yy_start) )
+ (yy_start) = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE );
+ }
+
+ yy_load_buffer_state( );
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = (yy_c_buf_p);
+
+ /* Support of yytext. */
+ *yy_cp = (yy_hold_char);
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = (yy_start);
+ yy_current_state += YY_AT_BOL();
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 859 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 1774 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = (yy_hold_char);
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 62 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_API;}
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 63 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_DEFENCODING;}
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 64 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_PLUGIN;}
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 65 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_INCLUDE;}
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 66 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_OPTINCLUDE;}
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 67 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_IMPORT;}
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 68 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_MODULE;}
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 69 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_CMODULE;}
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 70 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_CONSMODULE;}
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 71 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_COMPOMODULE;}
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 72 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_TIMELINE;}
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 73 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_PLATFORMS;}
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 74 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_FEATURE;}
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 75 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_LICENSE;}
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 76 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_MAPPEDTYPE;}
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 77 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_EXCEPTION;}
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 78 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_IF;}
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 79 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_DEFMETATYPE;}
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 80 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_DEFSUPERTYPE;}
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 81 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_END;}
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 82 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_CLASS;}
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 83 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_STRUCT;}
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 84 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_PUBLIC;}
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 85 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_PROTECTED;}
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 86 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_PRIVATE;}
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 87 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_SIGNALS;}
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 88 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_SIGNALS;}
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 89 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_SIGNAL_METHOD;}
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 90 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_SLOTS;}
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 91 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_SLOTS;}
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 92 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_SLOT_METHOD;}
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 93 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_CHAR;}
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 94 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_WCHAR_T;}
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 95 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_BOOL;}
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 96 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_SHORT;}
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 97 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_INT;}
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 98 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_LONG;}
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 99 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_FLOAT;}
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 100 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_DOUBLE;}
+ YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 101 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_VOID;}
+ YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 102 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_VIRTUAL;}
+ YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 103 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_ENUM;}
+ YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 104 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_SIGNED;}
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 105 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_UNSIGNED;}
+ YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 106 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_CONST;}
+ YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 107 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_STATIC;}
+ YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 108 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_TRUE;}
+ YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 109 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_FALSE;}
+ YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 110 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_NULL;}
+ YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 111 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_TYPEDEF;}
+ YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 112 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_NAMESPACE;}
+ YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 113 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_OPERATOR;}
+ YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 114 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_THROW;}
+ YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 115 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_EXPLICIT;}
+ YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 116 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_TEMPLATE;}
+ YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 117 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_SCOPE;}
+ YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 118 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_LOGICAL_OR;}
+ YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 119 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_PYOBJECT;}
+ YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 120 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_PYTUPLE;}
+ YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 121 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_PYLIST;}
+ YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 122 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_PYDICT;}
+ YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 123 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_PYCALLABLE;}
+ YY_BREAK
+case 63:
+YY_RULE_SETUP
+#line 124 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_PYSLICE;}
+ YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 125 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_PYTYPE;}
+ YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 126 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_SIPSIGNAL;}
+ YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 127 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_SIPSLOT;}
+ YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 128 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_SIPANYSLOT;}
+ YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 129 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_SIPRXCON;}
+ YY_BREAK
+case 69:
+YY_RULE_SETUP
+#line 130 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_SIPRXDIS;}
+ YY_BREAK
+case 70:
+YY_RULE_SETUP
+#line 131 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_SIPSLOTCON;}
+ YY_BREAK
+case 71:
+YY_RULE_SETUP
+#line 132 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_SIPSLOTDIS;}
+ YY_BREAK
+case 72:
+YY_RULE_SETUP
+#line 133 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_QOBJECT;}
+ YY_BREAK
+case 73:
+YY_RULE_SETUP
+#line 134 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{return TK_ELLIPSIS;}
+ YY_BREAK
+case 74:
+YY_RULE_SETUP
+#line 137 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* Ignore whitespace. */
+ ;
+}
+ YY_BREAK
+case 75:
+/* rule 75 can match eol */
+YY_RULE_SETUP
+#line 141 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* Maintain the line number. */
+ ++inputFileStack[currentFile].lineno;
+
+ if (codeIdx == 0)
+ {
+ BEGIN code;
+ }
+}
+ YY_BREAK
+case 76:
+YY_RULE_SETUP
+#line 150 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* Ignore C++ style comments. */
+ ;
+}
+ YY_BREAK
+case 77:
+YY_RULE_SETUP
+#line 155 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* A signed decimal number. */
+ yylval.number = strtol(yytext,NULL,0);
+ return TK_NUMBER;
+}
+ YY_BREAK
+case 78:
+YY_RULE_SETUP
+#line 161 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{/* A floating point number. */
+ yylval.real = strtod(yytext,NULL);
+ return TK_REAL;
+}
+ YY_BREAK
+case 79:
+YY_RULE_SETUP
+#line 167 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* An unsigned hexadecimal number. */
+ yylval.number = strtol(yytext,NULL,16);
+ return TK_NUMBER;
+}
+ YY_BREAK
+case 80:
+YY_RULE_SETUP
+#line 173 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* An identifier name. */
+ yylval.text = sipStrdup(yytext);
+ return TK_NAME;
+}
+ YY_BREAK
+case 81:
+YY_RULE_SETUP
+#line 179 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* A relative pathname. */
+ yylval.text = sipStrdup(yytext);
+ return TK_PATHNAME;
+}
+ YY_BREAK
+case 82:
+/* rule 82 can match eol */
+YY_RULE_SETUP
+#line 185 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* A double-quoted string. */
+ char *dp, *sp;
+
+ /* Copy the string without the quotes. */
+
+ yylval.text = sipMalloc(strlen(yytext) + 1);
+
+ dp = yylval.text;
+ sp = yytext;
+
+ while (*sp != '\0')
+ {
+ if (*sp != '"')
+ *dp++ = *sp;
+
+ ++sp;
+ }
+
+ *dp = '\0';
+
+ return TK_STRING;
+}
+ YY_BREAK
+case 83:
+/* rule 83 can match eol */
+YY_RULE_SETUP
+#line 209 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* A single-quoted character. */
+ if (strlen(yytext) != 3)
+ fatallex("Exactly one character expected between single quotes");
+
+ yylval.qchar = yytext[1];
+
+ return TK_QCHAR;
+}
+ YY_BREAK
+case 84:
+YY_RULE_SETUP
+#line 219 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* Ignore C-style comments. */
+ BEGIN ccomment;
+}
+ YY_BREAK
+case 85:
+/* rule 85 can match eol */
+YY_RULE_SETUP
+#line 222 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{
+ ++inputFileStack[currentFile].lineno;
+}
+ YY_BREAK
+case 86:
+YY_RULE_SETUP
+#line 225 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{
+ BEGIN INITIAL;
+}
+ YY_BREAK
+case 87:
+YY_RULE_SETUP
+#line 228 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{
+ ;
+}
+ YY_BREAK
+case 88:
+YY_RULE_SETUP
+#line 233 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The software license. */
+ codeIdx = 0;
+ return TK_COPYING;
+}
+ YY_BREAK
+case 89:
+YY_RULE_SETUP
+#line 238 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a from-type code block. */
+ codeIdx = 0;
+ return TK_FROMTYPE;
+}
+ YY_BREAK
+case 90:
+YY_RULE_SETUP
+#line 243 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a to-type code block. */
+ codeIdx = 0;
+ return TK_TOTYPE;
+}
+ YY_BREAK
+case 91:
+YY_RULE_SETUP
+#line 248 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a to-sub-class code block. */
+ codeIdx = 0;
+ return TK_TOSUBCLASS;
+}
+ YY_BREAK
+case 92:
+YY_RULE_SETUP
+#line 253 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of an exported header code block. */
+ codeIdx = 0;
+ return TK_EXPHEADERCODE;
+}
+ YY_BREAK
+case 93:
+YY_RULE_SETUP
+#line 258 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a module header code block. */
+ codeIdx = 0;
+ return TK_MODHEADERCODE;
+}
+ YY_BREAK
+case 94:
+YY_RULE_SETUP
+#line 263 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a type header code block. */
+ codeIdx = 0;
+ return TK_TYPEHEADERCODE;
+}
+ YY_BREAK
+case 95:
+YY_RULE_SETUP
+#line 268 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a pre-initialisation code block. */
+ codeIdx = 0;
+ return TK_PREINITCODE;
+}
+ YY_BREAK
+case 96:
+YY_RULE_SETUP
+#line 273 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of an initialisation code block. */
+ codeIdx = 0;
+ return TK_INITCODE;
+}
+ YY_BREAK
+case 97:
+YY_RULE_SETUP
+#line 278 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a post-initialisation code block. */
+ codeIdx = 0;
+ return TK_POSTINITCODE;
+}
+ YY_BREAK
+case 98:
+YY_RULE_SETUP
+#line 283 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a unit code block. */
+ codeIdx = 0;
+ return TK_UNITCODE;
+}
+ YY_BREAK
+case 99:
+YY_RULE_SETUP
+#line 288 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a module code block. */
+ codeIdx = 0;
+ return TK_MODCODE;
+}
+ YY_BREAK
+case 100:
+YY_RULE_SETUP
+#line 293 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a type code block. */
+ codeIdx = 0;
+ return TK_TYPECODE;
+}
+ YY_BREAK
+case 101:
+YY_RULE_SETUP
+#line 298 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a C++ method code block. */
+ codeIdx = 0;
+ return TK_METHODCODE;
+}
+ YY_BREAK
+case 102:
+YY_RULE_SETUP
+#line 303 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a C++ virtual code block. */
+ codeIdx = 0;
+ return TK_VIRTUALCATCHERCODE;
+}
+ YY_BREAK
+case 103:
+YY_RULE_SETUP
+#line 308 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a traverse code block. */
+ codeIdx = 0;
+ return TK_TRAVERSECODE;
+}
+ YY_BREAK
+case 104:
+YY_RULE_SETUP
+#line 313 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a clear code block. */
+ codeIdx = 0;
+ return TK_CLEARCODE;
+}
+ YY_BREAK
+case 105:
+YY_RULE_SETUP
+#line 318 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a get buffer code block. */
+ codeIdx = 0;
+ return TK_GETBUFFERCODE;
+}
+ YY_BREAK
+case 106:
+YY_RULE_SETUP
+#line 323 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a release buffer code block. */
+ codeIdx = 0;
+ return TK_RELEASEBUFFERCODE;
+}
+ YY_BREAK
+case 107:
+YY_RULE_SETUP
+#line 328 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a read buffer code block. */
+ codeIdx = 0;
+ return TK_READBUFFERCODE;
+}
+ YY_BREAK
+case 108:
+YY_RULE_SETUP
+#line 333 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a write buffer code block. */
+ codeIdx = 0;
+ return TK_WRITEBUFFERCODE;
+}
+ YY_BREAK
+case 109:
+YY_RULE_SETUP
+#line 338 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a segment count code block. */
+ codeIdx = 0;
+ return TK_SEGCOUNTCODE;
+}
+ YY_BREAK
+case 110:
+YY_RULE_SETUP
+#line 343 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a char buffer code block. */
+ codeIdx = 0;
+ return TK_CHARBUFFERCODE;
+}
+ YY_BREAK
+case 111:
+YY_RULE_SETUP
+#line 348 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a pickle code block. */
+ codeIdx = 0;
+ return TK_PICKLECODE;
+}
+ YY_BREAK
+case 112:
+YY_RULE_SETUP
+#line 353 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a pre-Python code block. */
+ codeIdx = 0;
+ return TK_PREPYCODE;
+}
+ YY_BREAK
+case 113:
+YY_RULE_SETUP
+#line 358 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a raise exception code block. */
+ codeIdx = 0;
+ return TK_RAISECODE;
+}
+ YY_BREAK
+case 114:
+YY_RULE_SETUP
+#line 363 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a docstring block. */
+ codeIdx = 0;
+ return TK_DOCSTRING;
+}
+ YY_BREAK
+case 115:
+YY_RULE_SETUP
+#line 368 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a documentation block. */
+ codeIdx = 0;
+ return TK_DOC;
+}
+ YY_BREAK
+case 116:
+YY_RULE_SETUP
+#line 373 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of an exported documentation block. */
+ codeIdx = 0;
+ return TK_EXPORTEDDOC;
+}
+ YY_BREAK
+case 117:
+YY_RULE_SETUP
+#line 378 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a Makefile code block. */
+ codeIdx = 0;
+ return TK_MAKEFILE;
+}
+ YY_BREAK
+case 118:
+YY_RULE_SETUP
+#line 383 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of an access code block. */
+ codeIdx = 0;
+ return TK_ACCESSCODE;
+}
+ YY_BREAK
+case 119:
+YY_RULE_SETUP
+#line 388 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a get code block. */
+ codeIdx = 0;
+ return TK_GETCODE;
+}
+ YY_BREAK
+case 120:
+YY_RULE_SETUP
+#line 393 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The start of a set code block. */
+ codeIdx = 0;
+ return TK_SETCODE;
+}
+ YY_BREAK
+case 121:
+YY_RULE_SETUP
+#line 398 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The end of a code block. */
+ BEGIN INITIAL;
+ codeIdx = -1;
+ return TK_END;
+}
+ YY_BREAK
+case 122:
+/* rule 122 can match eol */
+YY_RULE_SETUP
+#line 404 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The end of a code line . */
+ struct inputFile *ifp;
+
+ codeLine[codeIdx] = '\n';
+ codeLine[codeIdx + 1] = '\0';
+ codeIdx = 0;
+
+ ifp = &inputFileStack[currentFile];
+
+ yylval.codeb = sipMalloc(sizeof (codeBlock));
+
+ yylval.codeb -> frag = sipStrdup(codeLine);
+ yylval.codeb -> linenr = ifp -> lineno++;
+ yylval.codeb -> filename = sipStrdup(ifp -> name);
+ yylval.codeb -> next = NULL;
+
+ return TK_CODELINE;
+}
+ YY_BREAK
+case 123:
+YY_RULE_SETUP
+#line 423 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* The contents of a code line. */
+ if (codeIdx == MAX_CODE_LINE_LENGTH)
+ fatallex("Line is too long");
+
+ codeLine[codeIdx++] = yytext[0];
+}
+ YY_BREAK
+case 124:
+YY_RULE_SETUP
+#line 430 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+{ /* Anything else is returned as is. */
+ return yytext[0];
+}
+ YY_BREAK
+case 125:
+YY_RULE_SETUP
+#line 434 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+ECHO;
+ YY_BREAK
+#line 2301 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.c"
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(code):
+case YY_STATE_EOF(ccomment):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = (yy_hold_char);
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++(yy_c_buf_p);
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = (yy_c_buf_p);
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ (yy_did_buffer_switch_on_eof) = 0;
+
+ if ( yywrap( ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) =
+ (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ (yy_c_buf_p) =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = (yytext_ptr);
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+ else
+ {
+ int num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+ int yy_c_buf_p_offset =
+ (int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ (yy_n_chars), (size_t) num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ if ( (yy_n_chars) == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart(yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ }
+
+ (yy_n_chars) += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (void)
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = (yy_start);
+ yy_current_state += YY_AT_BOL();
+
+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 859 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
+{
+ register int yy_is_jam;
+ register char *yy_cp = (yy_c_buf_p);
+
+ register YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 859 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 858);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+ static void yyunput (int c, register char * yy_bp )
+{
+ register char *yy_cp;
+
+ yy_cp = (yy_c_buf_p);
+
+ /* undo effects of setting up yytext */
+ *yy_cp = (yy_hold_char);
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = (yy_n_chars) + 2;
+ register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ register char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+ (yytext_ptr) = yy_bp;
+ (yy_hold_char) = *yy_cp;
+ (yy_c_buf_p) = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (void)
+#else
+ static int input (void)
+#endif
+
+{
+ int c;
+
+ *(yy_c_buf_p) = (yy_hold_char);
+
+ if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ /* This was really a NUL. */
+ *(yy_c_buf_p) = '\0';
+
+ else
+ { /* need more input */
+ int offset = (yy_c_buf_p) - (yytext_ptr);
+ ++(yy_c_buf_p);
+
+ switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart(yyin );
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap( ) )
+ return EOF;
+
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) = (yytext_ptr) + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
+ *(yy_c_buf_p) = '\0'; /* preserve yytext */
+ (yy_hold_char) = *++(yy_c_buf_p);
+
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ *
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void yyrestart (FILE * input_file )
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE );
+ }
+
+ yy_init_buffer(YY_CURRENT_BUFFER,input_file );
+ yy_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
+{
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
+ */
+ yyensure_buffer_stack ();
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ yy_load_buffer_state( );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void yy_load_buffer_state (void)
+{
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ *
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size )
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer(b,file );
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ *
+ */
+ void yy_delete_buffer (YY_BUFFER_STATE b )
+{
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yyfree((void *) b->yy_ch_buf );
+
+ yyfree((void *) b );
+}
+
+#ifndef __cplusplus
+extern int isatty (int );
+#endif /* __cplusplus */
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file )
+
+{
+ int oerrno = errno;
+
+ yy_flush_buffer(b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ *
+ */
+ void yy_flush_buffer (YY_BUFFER_STATE b )
+{
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ yy_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ *
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+ if (new_buffer == NULL)
+ return;
+
+ yyensure_buffer_stack();
+
+ /* This block is copied from yy_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ (yy_buffer_stack_top)++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ *
+ */
+void yypop_buffer_state (void)
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (void)
+{
+ int num_to_alloc;
+
+ if (!(yy_buffer_stack)) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ (yy_buffer_stack_max) = num_to_alloc;
+ (yy_buffer_stack_top) = 0;
+ return;
+ }
+
+ if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = (yy_buffer_stack_max) + grow_size;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
+ ((yy_buffer_stack),
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+ (yy_buffer_stack_max) = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer(b );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ *
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
+{
+
+ return yy_scan_bytes(yystr,strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len )
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = _yybytes_len + 2;
+ buf = (char *) yyalloc(n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer(buf,n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = (yy_hold_char); \
+ (yy_c_buf_p) = yytext + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ *
+ */
+int yyget_lineno (void)
+{
+
+ return yylineno;
+}
+
+/** Get the input stream.
+ *
+ */
+FILE *yyget_in (void)
+{
+ return yyin;
+}
+
+/** Get the output stream.
+ *
+ */
+FILE *yyget_out (void)
+{
+ return yyout;
+}
+
+/** Get the length of the current token.
+ *
+ */
+int yyget_leng (void)
+{
+ return yyleng;
+}
+
+/** Get the current token.
+ *
+ */
+
+char *yyget_text (void)
+{
+ return yytext;
+}
+
+/** Set the current line number.
+ * @param line_number
+ *
+ */
+void yyset_lineno (int line_number )
+{
+
+ yylineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ *
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE * in_str )
+{
+ yyin = in_str ;
+}
+
+void yyset_out (FILE * out_str )
+{
+ yyout = out_str ;
+}
+
+int yyget_debug (void)
+{
+ return yy_flex_debug;
+}
+
+void yyset_debug (int bdebug )
+{
+ yy_flex_debug = bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from yylex_destroy(), so don't allocate here.
+ */
+
+ (yy_buffer_stack) = 0;
+ (yy_buffer_stack_top) = 0;
+ (yy_buffer_stack_max) = 0;
+ (yy_c_buf_p) = (char *) 0;
+ (yy_init) = 0;
+ (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
+#else
+ yyin = (FILE *) 0;
+ yyout = (FILE *) 0;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * yylex_init()
+ */
+ return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy (void)
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ yypop_buffer_state();
+ }
+
+ /* Destroy the stack itself. */
+ yyfree((yy_buffer_stack) );
+ (yy_buffer_stack) = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * yylex() is called, initialization will occur. */
+ yy_init_globals( );
+
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *yyalloc (yy_size_t size )
+{
+ return (void *) malloc( size );
+}
+
+void *yyrealloc (void * ptr, yy_size_t size )
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void yyfree (void * ptr )
+{
+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 434 "/home/phil/hg/sip/sip-4.10.5/sipgen/lexer.l"
+
+
+
+/*
+ * Hook into EOF handling. Return 0 if there is more to process.
+ */
+
+int yywrap()
+{
+ char *cwd;
+ struct inputFile *ifp;
+
+ if ((cwd = inputFileStack[currentFile].cwd) != NULL)
+ free(cwd);
+
+ ifp = &inputFileStack[currentFile--];
+
+ /* Tell the parser if this is the end of a file. */
+
+ parserEOF(ifp -> name, &ifp -> pc);
+
+ /* Tidy up this file. */
+
+ fclose(yyin);
+ free(ifp -> name);
+
+ /* See if this was the original file. */
+
+ if (currentFile < 0)
+ return 1;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER);
+ yy_switch_to_buffer(ifp -> bs);
+
+ return 0;
+}
+
+
+/*
+ * Set up an input file to be read by the lexer, opening it if necessary. TRUE
+ * is returned if the file has not already been read.
+ */
+int setInputFile(FILE *open_fp, parserContext *pc, int optional)
+{
+ static stringList *all = NULL;
+ char *cwd, *fullname = NULL;
+ FILE *fp = open_fp;
+
+ if (currentFile >= MAX_INCLUDE_DEPTH - 1)
+ fatal("Too many nested %%Include, %%OptionalInclude or %%Import statements\n");
+
+ if (fp != NULL || (fp = openFile(pc->filename)) != NULL)
+ fullname = sipStrdup(pc->filename);
+ else
+ {
+ char *cwd;
+
+ /* Try the directory that contains the current file. */
+ if (currentFile >= 0 && (cwd = inputFileStack[currentFile].cwd) != NULL)
+ {
+ fullname = concat(cwd, "/", pc->filename, NULL);
+
+ if ((fp = openFile(fullname)) == NULL)
+ {
+ free(fullname);
+ fullname = NULL;
+ }
+ }
+ }
+
+ /* Try the include path if we haven't found anything yet. */
+ if (fullname == NULL)
+ {
+ stringList *sl;
+
+ fullname = NULL;
+
+ for (sl = includeDirList; sl != NULL; sl = sl -> next)
+ {
+ if (fullname != NULL)
+ free(fullname);
+
+ fullname = concat(sl->s, "/", pc->filename, NULL);
+
+ if ((fp = openFile(fullname)) != NULL)
+ break;
+ }
+
+ if (fp == NULL)
+ {
+ if (optional)
+ return FALSE;
+
+ fatal("Unable to find file \"%s\"\n", pc->filename);
+ }
+ }
+
+ /*
+ * If we have just opened the file, make sure that we haven't already read
+ * it. While it should never happen with normal modules (if the user
+ * doesn't specify recursive %Imports or %Includes) it is likely to happen
+ * with consolidated modules.
+ */
+ if (open_fp == NULL)
+ {
+ stringList *sl;
+
+ for (sl = all; sl != NULL; sl = sl->next)
+ if (strcmp(sl->s, fullname) == 0)
+ {
+ fclose(fp);
+ return FALSE;
+ }
+ }
+
+ /* Remember the filename. */
+ appendString(&all, sipStrdup(fullname));
+
+ yyin = fp;
+
+ ++currentFile;
+
+ /* Remember the directory containing the new file and make it "current". */
+ if ((cwd = strchr(fullname, '/')) != NULL)
+ {
+ cwd = sipStrdup(fullname);
+ *strrchr(cwd,'/') = '\0';
+ }
+
+ inputFileStack[currentFile].lineno = 1;
+ inputFileStack[currentFile].name = fullname;
+ inputFileStack[currentFile].pc = *pc;
+ inputFileStack[currentFile].cwd = cwd;
+
+ if (currentFile > 0)
+ {
+ inputFileStack[currentFile].bs = YY_CURRENT_BUFFER;
+ yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE));
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Open a file for reading or return NULL if it doesn't exist. Any other error
+ * is fatal.
+ */
+static FILE *openFile(const char *name)
+{
+ FILE *fp;
+
+ if ((fp = fopen(name,"r")) == NULL && errno != ENOENT)
+ fatal("Error in opening file %s\n",name);
+
+ return fp;
+}
+
+
+/*
+ * Handle fatal yacc errors.
+ */
+void yyerror(char *s)
+{
+ if (currentFile < 0)
+ fatal("%s\n", s);
+
+ fatal("%s:%d: %s\n",
+ inputFileStack[currentFile].name,
+ inputFileStack[currentFile].lineno,
+ s);
+}
+
+
+/*
+ * Handle warnings while parsing.
+ */
+void yywarning(char *s)
+{
+ warning("%s:%d: %s\n",
+ inputFileStack[currentFile].name,
+ inputFileStack[currentFile].lineno,
+ s);
+}
+
+
+/*
+ * Handle fatal lex errors.
+ */
+static void fatallex(char *s)
+{
+ fatal("%s:%d: Lexical analyser error: %s\n",
+ inputFileStack[currentFile].name,
+ inputFileStack[currentFile].lineno,
+ s);
+}
+
diff --git a/sipgen/lexer.l b/sipgen/lexer.l
new file mode 100644
index 0000000..35fb9c2
--- /dev/null
+++ b/sipgen/lexer.l
@@ -0,0 +1,628 @@
+/*
+ * The SIP lexer.
+ *
+ * Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com>
+ *
+ * This file is part of SIP.
+ *
+ * This copy of SIP is licensed for use under the terms of the SIP License
+ * Agreement. See the file LICENSE for more details.
+ *
+ * This copy of SIP may also used under the terms of the GNU General Public
+ * License v2 or v3 as published by the Free Software Foundation which can be
+ * found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
+ *
+ * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+%{
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "sip.h"
+#include "parser.h"
+
+
+#ifndef FLEX_SCANNER
+#error "Only flex is supported at the moment"
+#endif
+
+
+#define YY_NO_UNISTD_H
+#define YY_FATAL_ERROR(s) fatallex(s)
+
+#define MAX_INCLUDE_DEPTH 10
+#define MAX_CODE_LINE_LENGTH 1000
+
+
+static struct inputFile {
+ int lineno; /* The line number. */
+ YY_BUFFER_STATE bs; /* The flex buffer state handle. */
+ char *name; /* The file name. */
+ char *cwd; /* The path part of the file name. */
+ parserContext pc; /* The parser context. */
+} inputFileStack[MAX_INCLUDE_DEPTH];
+
+static int currentFile = -1; /* Index of the current input file. */
+static char codeLine[MAX_CODE_LINE_LENGTH + 2]; /* The current code line. */
+static int codeIdx = -1; /* Index of next code character. */
+
+static FILE *openFile(const char *);
+static void fatallex(char *);
+%}
+
+%x code
+%x ccomment
+
+%%
+
+^[ \t]*%API {return TK_API;}
+^[ \t]*%DefaultEncoding {return TK_DEFENCODING;}
+^[ \t]*%Plugin {return TK_PLUGIN;}
+^[ \t]*%Include {return TK_INCLUDE;}
+^[ \t]*%OptionalInclude {return TK_OPTINCLUDE;}
+^[ \t]*%Import {return TK_IMPORT;}
+^[ \t]*%Module {return TK_MODULE;}
+^[ \t]*%CModule {return TK_CMODULE;}
+^[ \t]*%ConsolidatedModule {return TK_CONSMODULE;}
+^[ \t]*%CompositeModule {return TK_COMPOMODULE;}
+^[ \t]*%Timeline {return TK_TIMELINE;}
+^[ \t]*%Platforms {return TK_PLATFORMS;}
+^[ \t]*%Feature {return TK_FEATURE;}
+^[ \t]*%License {return TK_LICENSE;}
+^[ \t]*%MappedType {return TK_MAPPEDTYPE;}
+^[ \t]*%Exception {return TK_EXCEPTION;}
+^[ \t]*%If {return TK_IF;}
+^[ \t]*%DefaultMetatype {return TK_DEFMETATYPE;}
+^[ \t]*%DefaultSupertype {return TK_DEFSUPERTYPE;}
+<INITIAL>^[ \t]*%End {return TK_END;}
+class {return TK_CLASS;}
+struct {return TK_STRUCT;}
+public {return TK_PUBLIC;}
+protected {return TK_PROTECTED;}
+private {return TK_PRIVATE;}
+signals {return TK_SIGNALS;}
+Q_SIGNALS {return TK_SIGNALS;}
+Q_SIGNAL {return TK_SIGNAL_METHOD;}
+slots {return TK_SLOTS;}
+Q_SLOTS {return TK_SLOTS;}
+Q_SLOT {return TK_SLOT_METHOD;}
+char {return TK_CHAR;}
+wchar_t {return TK_WCHAR_T;}
+bool {return TK_BOOL;}
+short {return TK_SHORT;}
+int {return TK_INT;}
+long {return TK_LONG;}
+float {return TK_FLOAT;}
+double {return TK_DOUBLE;}
+void {return TK_VOID;}
+virtual {return TK_VIRTUAL;}
+enum {return TK_ENUM;}
+signed {return TK_SIGNED;}
+unsigned {return TK_UNSIGNED;}
+const {return TK_CONST;}
+static {return TK_STATIC;}
+true {return TK_TRUE;}
+false {return TK_FALSE;}
+NULL {return TK_NULL;}
+typedef {return TK_TYPEDEF;}
+namespace {return TK_NAMESPACE;}
+operator {return TK_OPERATOR;}
+throw {return TK_THROW;}
+explicit {return TK_EXPLICIT;}
+template {return TK_TEMPLATE;}
+:: {return TK_SCOPE;}
+\|\| {return TK_LOGICAL_OR;}
+SIP_PYOBJECT {return TK_PYOBJECT;}
+SIP_PYTUPLE {return TK_PYTUPLE;}
+SIP_PYLIST {return TK_PYLIST;}
+SIP_PYDICT {return TK_PYDICT;}
+SIP_PYCALLABLE {return TK_PYCALLABLE;}
+SIP_PYSLICE {return TK_PYSLICE;}
+SIP_PYTYPE {return TK_PYTYPE;}
+SIP_SIGNAL {return TK_SIPSIGNAL;}
+SIP_SLOT {return TK_SIPSLOT;}
+SIP_ANYSLOT {return TK_SIPANYSLOT;}
+SIP_RXOBJ_CON {return TK_SIPRXCON;}
+SIP_RXOBJ_DIS {return TK_SIPRXDIS;}
+SIP_SLOT_CON {return TK_SIPSLOTCON;}
+SIP_SLOT_DIS {return TK_SIPSLOTDIS;}
+SIP_QOBJECT {return TK_QOBJECT;}
+\.\.\. {return TK_ELLIPSIS;}
+
+
+[ \t\r] { /* Ignore whitespace. */
+ ;
+}
+
+\n { /* Maintain the line number. */
+ ++inputFileStack[currentFile].lineno;
+
+ if (codeIdx == 0)
+ {
+ BEGIN code;
+ }
+}
+
+\/\/.* { /* Ignore C++ style comments. */
+ ;
+}
+
+
+-?[0-9]+ { /* A signed decimal number. */
+ yylval.number = strtol(yytext,NULL,0);
+ return TK_NUMBER;
+}
+
+
+-?(([0-9]+)|([0-9]*\.[0-9]*)([eE][-+]?[0-9]+)?)[fF]? {/* A floating point number. */
+ yylval.real = strtod(yytext,NULL);
+ return TK_REAL;
+}
+
+
+0x[0-9a-fA-F]+ { /* An unsigned hexadecimal number. */
+ yylval.number = strtol(yytext,NULL,16);
+ return TK_NUMBER;
+}
+
+
+[_A-Za-z][_A-Za-z0-9]* { /* An identifier name. */
+ yylval.text = sipStrdup(yytext);
+ return TK_NAME;
+}
+
+
+[._A-Za-z][._/A-Za-z0-9\-]*[._A-Za-z0-9] { /* A relative pathname. */
+ yylval.text = sipStrdup(yytext);
+ return TK_PATHNAME;
+}
+
+
+\"[^"\n]*["\n] { /* A double-quoted string. */
+ char *dp, *sp;
+
+ /* Copy the string without the quotes. */
+
+ yylval.text = sipMalloc(strlen(yytext) + 1);
+
+ dp = yylval.text;
+ sp = yytext;
+
+ while (*sp != '\0')
+ {
+ if (*sp != '"')
+ *dp++ = *sp;
+
+ ++sp;
+ }
+
+ *dp = '\0';
+
+ return TK_STRING;
+}
+
+
+\'[^'\n]*['\n] { /* A single-quoted character. */
+ if (strlen(yytext) != 3)
+ fatallex("Exactly one character expected between single quotes");
+
+ yylval.qchar = yytext[1];
+
+ return TK_QCHAR;
+}
+
+
+\/\* { /* Ignore C-style comments. */
+ BEGIN ccomment;
+}
+<ccomment>\n {
+ ++inputFileStack[currentFile].lineno;
+}
+<ccomment>\*\/ {
+ BEGIN INITIAL;
+}
+<ccomment>. {
+ ;
+}
+
+
+^%Copying { /* The software license. */
+ codeIdx = 0;
+ return TK_COPYING;
+}
+
+^%ConvertFromTypeCode { /* The start of a from-type code block. */
+ codeIdx = 0;
+ return TK_FROMTYPE;
+}
+
+^%ConvertToTypeCode { /* The start of a to-type code block. */
+ codeIdx = 0;
+ return TK_TOTYPE;
+}
+
+^%ConvertToSubClassCode { /* The start of a to-sub-class code block. */
+ codeIdx = 0;
+ return TK_TOSUBCLASS;
+}
+
+^%ExportedHeaderCode { /* The start of an exported header code block. */
+ codeIdx = 0;
+ return TK_EXPHEADERCODE;
+}
+
+^%ModuleHeaderCode { /* The start of a module header code block. */
+ codeIdx = 0;
+ return TK_MODHEADERCODE;
+}
+
+^%TypeHeaderCode { /* The start of a type header code block. */
+ codeIdx = 0;
+ return TK_TYPEHEADERCODE;
+}
+
+^%PreInitialisationCode { /* The start of a pre-initialisation code block. */
+ codeIdx = 0;
+ return TK_PREINITCODE;
+}
+
+^%InitialisationCode { /* The start of an initialisation code block. */
+ codeIdx = 0;
+ return TK_INITCODE;
+}
+
+^%PostInitialisationCode { /* The start of a post-initialisation code block. */
+ codeIdx = 0;
+ return TK_POSTINITCODE;
+}
+
+^%UnitCode { /* The start of a unit code block. */
+ codeIdx = 0;
+ return TK_UNITCODE;
+}
+
+^%ModuleCode { /* The start of a module code block. */
+ codeIdx = 0;
+ return TK_MODCODE;
+}
+
+^%TypeCode { /* The start of a type code block. */
+ codeIdx = 0;
+ return TK_TYPECODE;
+}
+
+^%MethodCode { /* The start of a C++ method code block. */
+ codeIdx = 0;
+ return TK_METHODCODE;
+}
+
+^%VirtualCatcherCode { /* The start of a C++ virtual code block. */
+ codeIdx = 0;
+ return TK_VIRTUALCATCHERCODE;
+}
+
+^%GCTraverseCode { /* The start of a traverse code block. */
+ codeIdx = 0;
+ return TK_TRAVERSECODE;
+}
+
+^%GCClearCode { /* The start of a clear code block. */
+ codeIdx = 0;
+ return TK_CLEARCODE;
+}
+
+^%BIGetBufferCode { /* The start of a get buffer code block. */
+ codeIdx = 0;
+ return TK_GETBUFFERCODE;
+}
+
+^%BIReleaseBufferCode { /* The start of a release buffer code block. */
+ codeIdx = 0;
+ return TK_RELEASEBUFFERCODE;
+}
+
+^%BIGetReadBufferCode { /* The start of a read buffer code block. */
+ codeIdx = 0;
+ return TK_READBUFFERCODE;
+}
+
+^%BIGetWriteBufferCode { /* The start of a write buffer code block. */
+ codeIdx = 0;
+ return TK_WRITEBUFFERCODE;
+}
+
+^%BIGetSegCountCode { /* The start of a segment count code block. */
+ codeIdx = 0;
+ return TK_SEGCOUNTCODE;
+}
+
+^%BIGetCharBufferCode { /* The start of a char buffer code block. */
+ codeIdx = 0;
+ return TK_CHARBUFFERCODE;
+}
+
+^%PickleCode { /* The start of a pickle code block. */
+ codeIdx = 0;
+ return TK_PICKLECODE;
+}
+
+^%PrePythonCode { /* The start of a pre-Python code block. */
+ codeIdx = 0;
+ return TK_PREPYCODE;
+}
+
+^%RaiseCode { /* The start of a raise exception code block. */
+ codeIdx = 0;
+ return TK_RAISECODE;
+}
+
+^%Docstring { /* The start of a docstring block. */
+ codeIdx = 0;
+ return TK_DOCSTRING;
+}
+
+^%Doc { /* The start of a documentation block. */
+ codeIdx = 0;
+ return TK_DOC;
+}
+
+^%ExportedDoc { /* The start of an exported documentation block. */
+ codeIdx = 0;
+ return TK_EXPORTEDDOC;
+}
+
+^%Makefile { /* The start of a Makefile code block. */
+ codeIdx = 0;
+ return TK_MAKEFILE;
+}
+
+^%AccessCode { /* The start of an access code block. */
+ codeIdx = 0;
+ return TK_ACCESSCODE;
+}
+
+^%GetCode { /* The start of a get code block. */
+ codeIdx = 0;
+ return TK_GETCODE;
+}
+
+^%SetCode { /* The start of a set code block. */
+ codeIdx = 0;
+ return TK_SETCODE;
+}
+
+<code>^%End { /* The end of a code block. */
+ BEGIN INITIAL;
+ codeIdx = -1;
+ return TK_END;
+}
+
+<code>\n { /* The end of a code line . */
+ struct inputFile *ifp;
+
+ codeLine[codeIdx] = '\n';
+ codeLine[codeIdx + 1] = '\0';
+ codeIdx = 0;
+
+ ifp = &inputFileStack[currentFile];
+
+ yylval.codeb = sipMalloc(sizeof (codeBlock));
+
+ yylval.codeb -> frag = sipStrdup(codeLine);
+ yylval.codeb -> linenr = ifp -> lineno++;
+ yylval.codeb -> filename = sipStrdup(ifp -> name);
+ yylval.codeb -> next = NULL;
+
+ return TK_CODELINE;
+}
+
+<code>. { /* The contents of a code line. */
+ if (codeIdx == MAX_CODE_LINE_LENGTH)
+ fatallex("Line is too long");
+
+ codeLine[codeIdx++] = yytext[0];
+}
+
+. { /* Anything else is returned as is. */
+ return yytext[0];
+}
+
+%%
+
+/*
+ * Hook into EOF handling. Return 0 if there is more to process.
+ */
+
+int yywrap()
+{
+ char *cwd;
+ struct inputFile *ifp;
+
+ if ((cwd = inputFileStack[currentFile].cwd) != NULL)
+ free(cwd);
+
+ ifp = &inputFileStack[currentFile--];
+
+ /* Tell the parser if this is the end of a file. */
+
+ parserEOF(ifp -> name, &ifp -> pc);
+
+ /* Tidy up this file. */
+
+ fclose(yyin);
+ free(ifp -> name);
+
+ /* See if this was the original file. */
+
+ if (currentFile < 0)
+ return 1;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER);
+ yy_switch_to_buffer(ifp -> bs);
+
+ return 0;
+}
+
+
+/*
+ * Set up an input file to be read by the lexer, opening it if necessary. TRUE
+ * is returned if the file has not already been read.
+ */
+int setInputFile(FILE *open_fp, parserContext *pc, int optional)
+{
+ static stringList *all = NULL;
+ char *cwd, *fullname = NULL;
+ FILE *fp = open_fp;
+
+ if (currentFile >= MAX_INCLUDE_DEPTH - 1)
+ fatal("Too many nested %%Include, %%OptionalInclude or %%Import statements\n");
+
+ if (fp != NULL || (fp = openFile(pc->filename)) != NULL)
+ fullname = sipStrdup(pc->filename);
+ else
+ {
+ char *cwd;
+
+ /* Try the directory that contains the current file. */
+ if (currentFile >= 0 && (cwd = inputFileStack[currentFile].cwd) != NULL)
+ {
+ fullname = concat(cwd, "/", pc->filename, NULL);
+
+ if ((fp = openFile(fullname)) == NULL)
+ {
+ free(fullname);
+ fullname = NULL;
+ }
+ }
+ }
+
+ /* Try the include path if we haven't found anything yet. */
+ if (fullname == NULL)
+ {
+ stringList *sl;
+
+ fullname = NULL;
+
+ for (sl = includeDirList; sl != NULL; sl = sl -> next)
+ {
+ if (fullname != NULL)
+ free(fullname);
+
+ fullname = concat(sl->s, "/", pc->filename, NULL);
+
+ if ((fp = openFile(fullname)) != NULL)
+ break;
+ }
+
+ if (fp == NULL)
+ {
+ if (optional)
+ return FALSE;
+
+ fatal("Unable to find file \"%s\"\n", pc->filename);
+ }
+ }
+
+ /*
+ * If we have just opened the file, make sure that we haven't already read
+ * it. While it should never happen with normal modules (if the user
+ * doesn't specify recursive %Imports or %Includes) it is likely to happen
+ * with consolidated modules.
+ */
+ if (open_fp == NULL)
+ {
+ stringList *sl;
+
+ for (sl = all; sl != NULL; sl = sl->next)
+ if (strcmp(sl->s, fullname) == 0)
+ {
+ fclose(fp);
+ return FALSE;
+ }
+ }
+
+ /* Remember the filename. */
+ appendString(&all, sipStrdup(fullname));
+
+ yyin = fp;
+
+ ++currentFile;
+
+ /* Remember the directory containing the new file and make it "current". */
+ if ((cwd = strchr(fullname, '/')) != NULL)
+ {
+ cwd = sipStrdup(fullname);
+ *strrchr(cwd,'/') = '\0';
+ }
+
+ inputFileStack[currentFile].lineno = 1;
+ inputFileStack[currentFile].name = fullname;
+ inputFileStack[currentFile].pc = *pc;
+ inputFileStack[currentFile].cwd = cwd;
+
+ if (currentFile > 0)
+ {
+ inputFileStack[currentFile].bs = YY_CURRENT_BUFFER;
+ yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE));
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Open a file for reading or return NULL if it doesn't exist. Any other error
+ * is fatal.
+ */
+static FILE *openFile(const char *name)
+{
+ FILE *fp;
+
+ if ((fp = fopen(name,"r")) == NULL && errno != ENOENT)
+ fatal("Error in opening file %s\n",name);
+
+ return fp;
+}
+
+
+/*
+ * Handle fatal yacc errors.
+ */
+void yyerror(char *s)
+{
+ if (currentFile < 0)
+ fatal("%s\n", s);
+
+ fatal("%s:%d: %s\n",
+ inputFileStack[currentFile].name,
+ inputFileStack[currentFile].lineno,
+ s);
+}
+
+
+/*
+ * Handle warnings while parsing.
+ */
+void yywarning(char *s)
+{
+ warning("%s:%d: %s\n",
+ inputFileStack[currentFile].name,
+ inputFileStack[currentFile].lineno,
+ s);
+}
+
+
+/*
+ * Handle fatal lex errors.
+ */
+static void fatallex(char *s)
+{
+ fatal("%s:%d: Lexical analyser error: %s\n",
+ inputFileStack[currentFile].name,
+ inputFileStack[currentFile].lineno,
+ s);
+}
diff --git a/sipgen/main.c b/sipgen/main.c
new file mode 100644
index 0000000..4cf81f1
--- /dev/null
+++ b/sipgen/main.c
@@ -0,0 +1,515 @@
+/*
+ * The main module for SIP.
+ *
+ * Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com>
+ *
+ * This file is part of SIP.
+ *
+ * This copy of SIP is licensed for use under the terms of the SIP License
+ * Agreement. See the file LICENSE for more details.
+ *
+ * This copy of SIP may also used under the terms of the GNU General Public
+ * License v2 or v3 as published by the Free Software Foundation which can be
+ * found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
+ *
+ * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "sip.h"
+
+
+#ifndef PACKAGE
+#define PACKAGE "sip"
+#endif
+
+#define VERSION "4.10.5"
+
+
+/* Global variables - see sip.h for their meaning. */
+char *sipVersion;
+stringList *includeDirList;
+
+static char *sipPackage = PACKAGE;
+static int warnings = FALSE;
+
+
+static void help(void);
+static void version(void);
+static void usage(void);
+static char parseopt(int,char **,char *,char **,int *,char **);
+static int parseInt(char *,char);
+
+
+int main(int argc, char **argv)
+{
+ char *filename, *docFile, *codeDir, *srcSuffix, *flagFile, *consModule;
+ char arg, *optarg, *buildFile, *apiFile, *xmlFile;
+ int optnr, exceptions, tracing, releaseGIL, parts, kwdArgs, protHack, docs;
+ FILE *file;
+ sipSpec spec;
+ stringList *versions, *xfeatures;
+
+ /* Initialise. */
+ sipVersion = VERSION;
+ includeDirList = NULL;
+ versions = NULL;
+ xfeatures = NULL;
+ buildFile = NULL;
+ codeDir = NULL;
+ docFile = NULL;
+ srcSuffix = NULL;
+ flagFile = NULL;
+ apiFile = NULL;
+ xmlFile = NULL;
+ consModule = NULL;
+ exceptions = FALSE;
+ tracing = FALSE;
+ releaseGIL = FALSE;
+ parts = 0;
+ kwdArgs = FALSE;
+ protHack = FALSE;
+ docs = FALSE;
+
+ /* Parse the command line. */
+ optnr = 1;
+
+ while ((arg = parseopt(argc, argv, "hVa:b:ec:d:gI:j:km:op:Prs:t:wx:z:", &flagFile, &optnr, &optarg)) != '\0')
+ switch (arg)
+ {
+ case 'o':
+ /* Generate docstrings. */
+ docs = TRUE;
+ break;
+
+ case 'p':
+ /* The name of the consolidated module. */
+ consModule = optarg;
+ break;
+
+ case 'P':
+ /* Enable the protected/public hack. */
+ protHack = TRUE;
+ break;
+
+ case 'a':
+ /* Where to generate the API file. */
+ apiFile = optarg;
+ break;
+
+ case 'm':
+ /* Where to generate the XML file. */
+ xmlFile = optarg;
+ break;
+
+ case 'b':
+ /* Generate a build file. */
+ buildFile = optarg;
+ break;
+
+ case 'e':
+ /* Enable exceptions. */
+ exceptions = TRUE;
+ break;
+
+ case 'g':
+ /* Always release the GIL. */
+ releaseGIL = TRUE;
+ break;
+
+ case 'j':
+ /* Generate the code in this number of parts. */
+ parts = parseInt(optarg,'j');
+ break;
+
+ case 'z':
+ /* Read a file for the next flags. */
+ if (flagFile != NULL)
+ fatal("The -z flag cannot be specified in an argument file\n");
+
+ flagFile = optarg;
+ break;
+
+ case 'c':
+ /* Where to generate the code. */
+ codeDir = optarg;
+ break;
+
+ case 'd':
+ /* Where to generate the documentation. */
+ docFile = optarg;
+ break;
+
+ case 't':
+ /* Which platform or version to generate code for. */
+ appendString(&versions,optarg);
+ break;
+
+ case 'x':
+ /* Which features are disabled. */
+ appendString(&xfeatures,optarg);
+ break;
+
+ case 'I':
+ /* Where to get included files from. */
+ appendString(&includeDirList,optarg);
+ break;
+
+ case 'r':
+ /* Enable tracing. */
+ tracing = TRUE;
+ break;
+
+ case 's':
+ /* The suffix to use for source files. */
+ srcSuffix = optarg;
+ break;
+
+ case 'w':
+ /* Enable warning messages. */
+ warnings = TRUE;
+ break;
+
+ case 'k':
+ /* Allow keyword arguments in functions and methods. */
+ kwdArgs = TRUE;
+ break;
+
+ case 'h':
+ /* Help message. */
+ help();
+ break;
+
+ case 'V':
+ /* Display the version number. */
+ version();
+ break;
+
+ default:
+ usage();
+ }
+
+ if (optnr < argc)
+ {
+ file = NULL;
+ filename = argv[optnr++];
+
+ if (optnr < argc)
+ usage();
+ }
+ else
+ {
+ file = stdin;
+ filename = "stdin";
+ }
+
+ /* Parse the input file. */
+ parse(&spec, file, filename, versions, xfeatures, kwdArgs, protHack);
+
+ /* Verify and transform the parse tree. */
+ transform(&spec);
+
+ /* Generate code. */
+ generateCode(&spec, codeDir, buildFile, docFile, srcSuffix, exceptions,
+ tracing, releaseGIL, parts, xfeatures, consModule, docs);
+
+ /* Generate the API file. */
+ if (apiFile != NULL)
+ generateAPI(&spec, spec.module, apiFile);
+
+ /* Generate the XML export. */
+ if (xmlFile != NULL)
+ generateXML(&spec, spec.module, xmlFile);
+
+ /* All done. */
+ return 0;
+}
+
+
+/*
+ * Parse the next command line argument - similar to UNIX getopts(). Allow a
+ * flag to specify that a file contains further arguments.
+ */
+static char parseopt(int argc, char **argv, char *opts, char **flags,
+ int *optnrp, char **optargp)
+{
+ char arg, *op, *fname;
+ int optnr;
+ static FILE *fp = NULL;
+
+ /* Deal with any file first. */
+
+ fname = *flags;
+
+ if (fname != NULL && fp == NULL && (fp = fopen(fname,"r")) == NULL)
+ fatal("Unable to open %s\n",fname);
+
+ if (fp != NULL)
+ {
+ char buf[200], *cp, *fname;
+ int ch;
+
+ fname = *flags;
+ cp = buf;
+
+ while ((ch = fgetc(fp)) != EOF)
+ {
+ /* Skip leading whitespace. */
+
+ if (cp == buf && isspace(ch))
+ continue;
+
+ if (ch == '\n')
+ break;
+
+ if (cp == &buf[sizeof (buf) - 1])
+ fatal("A flag in %s is too long\n",fname);
+
+ *cp++ = (char)ch;
+ }
+
+ *cp = '\0';
+
+ if (ch == EOF)
+ {
+ fclose(fp);
+ fp = NULL;
+ *flags = NULL;
+ }
+
+ /*
+ * Get the option character and any optional argument from the
+ * line.
+ */
+
+ if (buf[0] != '\0')
+ {
+ if (buf[0] != '-' || buf[1] == '\0')
+ fatal("An non-flag was given in %s\n",fname);
+
+ arg = buf[1];
+
+ /* Find any optional argument. */
+
+ for (cp = &buf[2]; *cp != '\0'; ++cp)
+ if (!isspace(*cp))
+ break;
+
+ if (*cp == '\0')
+ cp = NULL;
+ else
+ cp = sipStrdup(cp);
+
+ *optargp = cp;
+
+ if ((op = strchr(opts,arg)) == NULL)
+ fatal("An invalid flag was given in %s\n",fname);
+
+ if (op[1] == ':' && cp == NULL)
+ fatal("Missing flag argument in %s\n",fname);
+
+ if (op[1] != ':' && cp != NULL)
+ fatal("Unexpected flag argument in %s\n",fname);
+
+ return arg;
+ }
+ }
+
+ /* Check there is an argument and it is a switch. */
+
+ optnr = *optnrp;
+
+ if (optnr >= argc || argv[optnr] == NULL || argv[optnr][0] != '-')
+ return '\0';
+
+ /* Check it is a valid switch. */
+
+ arg = argv[optnr][1];
+
+ if (arg == '\0' || (op = strchr(opts,arg)) == NULL)
+ usage();
+
+ /* Check for the switch parameter, if any. */
+
+ if (op[1] == ':')
+ {
+ if (argv[optnr][2] != '\0')
+ {
+ *optargp = &argv[optnr][2];
+ ++optnr;
+ }
+ else if (optnr + 1 >= argc || argv[optnr + 1] == NULL)
+ usage();
+ else
+ {
+ *optargp = argv[optnr + 1];
+ optnr += 2;
+ }
+ }
+ else if (argv[optnr][2] != '\0')
+ usage();
+ else
+ {
+ *optargp = NULL;
+ ++optnr;
+ }
+
+ *optnrp = optnr;
+
+ return arg;
+}
+
+
+/*
+ * Parse an integer option.
+ */
+static int parseInt(char *arg, char opt)
+{
+ char *endptr;
+ int val;
+
+ val = strtol(arg, &endptr, 10);
+
+ if (*arg == '\0' || *endptr != '\0')
+ fatal("Invalid integer argument for -%c flag\n", opt);
+
+ return val;
+}
+
+
+/*
+ * Append a string to a list of them.
+ */
+void appendString(stringList **headp, const char *s)
+{
+ stringList *sl;
+
+ /* Create the new entry. */
+
+ sl = sipMalloc(sizeof (stringList));
+
+ sl -> s = s;
+ sl -> next = NULL;
+
+ /* Append it to the list. */
+
+ while (*headp != NULL)
+ headp = &(*headp) -> next;
+
+ *headp = sl;
+}
+
+
+/*
+ * Display a warning message.
+ */
+void warning(char *fmt,...)
+{
+ static int start = TRUE;
+
+ va_list ap;
+
+ if (!warnings)
+ return;
+
+ if (start)
+ {
+ fprintf(stderr,"%s: Warning: ",sipPackage);
+ start = FALSE;
+ }
+
+ va_start(ap,fmt);
+ vfprintf(stderr,fmt,ap);
+ va_end(ap);
+
+ if (strchr(fmt,'\n') != NULL)
+ start = TRUE;
+}
+
+
+/*
+ * Display all or part of a one line error message describing a fatal error.
+ * If the message is complete (it has a newline) then the program exits.
+ */
+void fatal(char *fmt,...)
+{
+ static int start = TRUE;
+
+ va_list ap;
+
+ if (start)
+ {
+ fprintf(stderr,"%s: ",sipPackage);
+ start = FALSE;
+ }
+
+ va_start(ap,fmt);
+ vfprintf(stderr,fmt,ap);
+ va_end(ap);
+
+ if (strchr(fmt,'\n') != NULL)
+ exit(1);
+}
+
+
+/*
+ * Display the SIP version number on stdout and exit with zero exit status.
+ */
+static void version(void)
+{
+ printf("%s\n",sipVersion);
+ exit(0);
+}
+
+
+/*
+ * Display the help message on stdout and exit with zero exit status.
+ */
+static void help(void)
+{
+ printf(
+"Usage:\n"
+" %s [-h] [-V] [-a file] [-b file] [-c dir] [-d file] [-e] [-g] [-I dir] [-j #] [-k] [-m file] [-o] [-p module] [-P] [-r] [-s suffix] [-t tag] [-w] [-x feature] [-z file] [file]\n"
+"where:\n"
+" -h display this help message\n"
+" -V display the %s version number\n"
+" -a file the name of the QScintilla API file [default not generated]\n"
+" -b file the name of the build file [default none generated]\n"
+" -c dir the name of the code directory [default not generated]\n"
+" -d file the name of the documentation file [default not generated]\n"
+" -e enable support for exceptions [default disabled]\n"
+" -g always release and reacquire the GIL [default only when specified]\n"
+" -I dir look in this directory when including files\n"
+" -j # split the generated code into # files [default 1 per class]\n"
+" -k support keyword arguments in functions and methods\n"
+" -m file the name of the XML export file [default not generated]\n"
+" -o enable the automatic generation of docstrings [default disabled]\n"
+" -p module the name of the consolidated module that this is a component of\n"
+" -P enable the protected/public hack\n"
+" -r generate code with tracing enabled [default disabled]\n"
+" -s suffix the suffix to use for C or C++ source files [default \".c\" or \".cpp\"]\n"
+" -t tag the version/platform to generate code for\n"
+" -w enable warning messages\n"
+" -x feature this feature is disabled\n"
+" -z file the name of a file containing more command line flags\n"
+" file the name of the specification file [default stdin]\n"
+ , sipPackage, sipPackage);
+
+ exit(0);
+}
+
+
+/*
+ * Display the usage message.
+ */
+static void usage(void)
+{
+ fatal("Usage: %s [-h] [-V] [-a file] [-b file] [-c dir] [-d file] [-e] [-g] [-I dir] [-j #] [-k] [-m file] [-o] [-p module] [-P] [-r] [-s suffix] [-t tag] [-w] [-x feature] [-z file] [file]\n", sipPackage);
+}
diff --git a/sipgen/parser.c b/sipgen/parser.c
new file mode 100644
index 0000000..5c51d1d
--- /dev/null
+++ b/sipgen/parser.c
@@ -0,0 +1,9975 @@
+
+/* A Bison parser, made by GNU Bison 2.4.1. */
+
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "2.4.1"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Push parsers. */
+#define YYPUSH 0
+
+/* Pull parsers. */
+#define YYPULL 1
+
+/* Using locations. */
+#define YYLSP_NEEDED 0
+
+
+
+/* Copy the first part of user declarations. */
+
+/* Line 189 of yacc.c */
+#line 19 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "sip.h"
+
+
+#define MAX_NESTED_IF 10
+#define MAX_NESTED_SCOPE 10
+
+#define inMainModule() (currentSpec->module == currentModule || currentModule->container != NULL)
+
+
+static sipSpec *currentSpec; /* The current spec being parsed. */
+static stringList *neededQualifiers; /* The list of required qualifiers. */
+static stringList *excludedQualifiers; /* The list of excluded qualifiers. */
+static moduleDef *currentModule; /* The current module being parsed. */
+static mappedTypeDef *currentMappedType; /* The current mapped type. */
+static enumDef *currentEnum; /* The current enum being parsed. */
+static int sectionFlags; /* The current section flags. */
+static int currentOverIsVirt; /* Set if the overload is virtual. */
+static int currentCtorIsExplicit; /* Set if the ctor is explicit. */
+static int currentIsStatic; /* Set if the current is static. */
+static int currentIsSignal; /* Set if the current is Q_SIGNAL. */
+static int currentIsSlot; /* Set if the current is Q_SLOT. */
+static int currentIsTemplate; /* Set if the current is a template. */
+static char *previousFile; /* The file just parsed. */
+static parserContext currentContext; /* The current context. */
+static int skipStackPtr; /* The skip stack pointer. */
+static int skipStack[MAX_NESTED_IF]; /* Stack of skip flags. */
+static classDef *scopeStack[MAX_NESTED_SCOPE]; /* The scope stack. */
+static int sectFlagsStack[MAX_NESTED_SCOPE]; /* The section flags stack. */
+static int currentScopeIdx; /* The scope stack index. */
+static int currentTimelineOrder; /* The current timeline order. */
+static classList *currentSupers; /* The current super-class list. */
+static int defaultKwdArgs; /* Support keyword arguments by default. */
+static int makeProtPublic; /* Treat protected items as public. */
+
+
+static const char *getPythonName(optFlags *optflgs, const char *cname);
+static classDef *findClass(sipSpec *pt, ifaceFileType iftype,
+ apiVersionRangeDef *api_range, scopedNameDef *fqname);
+static classDef *findClassWithInterface(sipSpec *pt, ifaceFileDef *iff);
+static classDef *newClass(sipSpec *pt, ifaceFileType iftype,
+ apiVersionRangeDef *api_range, scopedNameDef *snd);
+static void finishClass(sipSpec *, moduleDef *, classDef *, optFlags *);
+static exceptionDef *findException(sipSpec *pt, scopedNameDef *fqname, int new);
+static mappedTypeDef *newMappedType(sipSpec *,argDef *, optFlags *);
+static enumDef *newEnum(sipSpec *pt, moduleDef *mod, mappedTypeDef *mt_scope,
+ char *name, optFlags *of, int flags);
+static void instantiateClassTemplate(sipSpec *pt, moduleDef *mod, classDef *scope, scopedNameDef *fqname, classTmplDef *tcd, templateDef *td);
+static void newTypedef(sipSpec *, moduleDef *, char *, argDef *, optFlags *);
+static void newVar(sipSpec *, moduleDef *, char *, int, argDef *, optFlags *,
+ codeBlock *, codeBlock *, codeBlock *);
+static void newCtor(char *, int, signatureDef *, optFlags *, codeBlock *,
+ throwArgs *, signatureDef *, int, codeBlock *);
+static void newFunction(sipSpec *, moduleDef *, classDef *, mappedTypeDef *,
+ int, int, int, int, int, char *, signatureDef *, int, int, optFlags *,
+ codeBlock *, codeBlock *, throwArgs *, signatureDef *, codeBlock *);
+static optFlag *findOptFlag(optFlags *,char *,flagType);
+static memberDef *findFunction(sipSpec *, moduleDef *, classDef *,
+ mappedTypeDef *, const char *, int, int, int);
+static void checkAttributes(sipSpec *, moduleDef *, classDef *,
+ mappedTypeDef *, const char *, int);
+static void newModule(FILE *fp, char *filename);
+static moduleDef *allocModule();
+static void parseFile(FILE *fp, char *name, moduleDef *prevmod, int optional);
+static void handleEOF(void);
+static void handleEOM(void);
+static qualDef *findQualifier(const char *name);
+static scopedNameDef *text2scopedName(ifaceFileDef *scope, char *text);
+static scopedNameDef *scopeScopedName(ifaceFileDef *scope,
+ scopedNameDef *name);
+static void pushScope(classDef *);
+static void popScope(void);
+static classDef *currentScope(void);
+static void newQualifier(moduleDef *,int,int,char *,qualType);
+static void newImport(char *filename);
+static int timePeriod(char *,char *);
+static int platOrFeature(char *,int);
+static int isNeeded(qualDef *);
+static int notSkipping(void);
+static void getHooks(optFlags *,char **,char **);
+static int getTransfer(optFlags *optflgs);
+static int getReleaseGIL(optFlags *optflgs);
+static int getHoldGIL(optFlags *optflgs);
+static int getDeprecated(optFlags *optflgs);
+static int getAllowNone(optFlags *optflgs);
+static const char *getDocType(optFlags *optflgs);
+static const char *getDocValue(optFlags *optflgs);
+static void templateSignature(signatureDef *sd, int result, classTmplDef *tcd, templateDef *td, classDef *ncd);
+static void templateType(argDef *ad, classTmplDef *tcd, templateDef *td, classDef *ncd);
+static int search_back(const char *end, const char *start, const char *target);
+static char *type2string(argDef *ad);
+static char *scopedNameToString(scopedNameDef *name);
+static void addUsedFromCode(sipSpec *pt, ifaceFileList **used, const char *sname);
+static int sameName(scopedNameDef *snd, const char *sname);
+static int stringFind(stringList *sl, const char *s);
+static void setModuleName(sipSpec *pt, moduleDef *mod, const char *fullname);
+static int foundInScope(scopedNameDef *fq_name, scopedNameDef *rel_name);
+static void defineClass(scopedNameDef *snd, classList *supers, optFlags *of);
+static classDef *completeClass(scopedNameDef *snd, optFlags *of, int has_def);
+static memberDef *instantiateTemplateMethods(memberDef *tmd, moduleDef *mod);
+static void instantiateTemplateEnums(sipSpec *pt, classTmplDef *tcd,
+ templateDef *td, classDef *cd, ifaceFileList **used,
+ scopedNameDef *type_names, scopedNameDef *type_values);
+static void instantiateTemplateVars(sipSpec *pt, classTmplDef *tcd,
+ templateDef *td, classDef *cd, ifaceFileList **used,
+ scopedNameDef *type_names, scopedNameDef *type_values);
+static overDef *instantiateTemplateOverloads(sipSpec *pt, overDef *tod,
+ memberDef *tmethods, memberDef *methods, classTmplDef *tcd,
+ templateDef *td, classDef *cd, ifaceFileList **used,
+ scopedNameDef *type_names, scopedNameDef *type_values);
+static void resolveAnyTypedef(sipSpec *pt, argDef *ad);
+static void addVariable(sipSpec *pt, varDef *vd);
+static void applyTypeFlags(moduleDef *mod, argDef *ad, optFlags *flags);
+static argType convertEncoding(const char *encoding);
+static apiVersionRangeDef *getAPIRange(optFlags *optflgs);
+static apiVersionRangeDef *convertAPIRange(moduleDef *mod, nameDef *name,
+ int from, int to);
+static char *convertFeaturedString(char *fs);
+static scopedNameDef *text2scopePart(char *text);
+static int usesKeywordArgs(optFlags *optflgs, signatureDef *sd);
+static char *strip(char *s);
+static int isEnabledFeature(const char *name);
+
+
+/* Line 189 of yacc.c */
+#line 202 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.c"
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table. */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ TK_API = 258,
+ TK_DEFENCODING = 259,
+ TK_PLUGIN = 260,
+ TK_DOCSTRING = 261,
+ TK_DOC = 262,
+ TK_EXPORTEDDOC = 263,
+ TK_MAKEFILE = 264,
+ TK_ACCESSCODE = 265,
+ TK_GETCODE = 266,
+ TK_SETCODE = 267,
+ TK_PREINITCODE = 268,
+ TK_INITCODE = 269,
+ TK_POSTINITCODE = 270,
+ TK_UNITCODE = 271,
+ TK_MODCODE = 272,
+ TK_TYPECODE = 273,
+ TK_PREPYCODE = 274,
+ TK_COPYING = 275,
+ TK_MAPPEDTYPE = 276,
+ TK_CODELINE = 277,
+ TK_IF = 278,
+ TK_END = 279,
+ TK_NAME = 280,
+ TK_PATHNAME = 281,
+ TK_STRING = 282,
+ TK_VIRTUALCATCHERCODE = 283,
+ TK_TRAVERSECODE = 284,
+ TK_CLEARCODE = 285,
+ TK_GETBUFFERCODE = 286,
+ TK_RELEASEBUFFERCODE = 287,
+ TK_READBUFFERCODE = 288,
+ TK_WRITEBUFFERCODE = 289,
+ TK_SEGCOUNTCODE = 290,
+ TK_CHARBUFFERCODE = 291,
+ TK_PICKLECODE = 292,
+ TK_METHODCODE = 293,
+ TK_FROMTYPE = 294,
+ TK_TOTYPE = 295,
+ TK_TOSUBCLASS = 296,
+ TK_INCLUDE = 297,
+ TK_OPTINCLUDE = 298,
+ TK_IMPORT = 299,
+ TK_EXPHEADERCODE = 300,
+ TK_MODHEADERCODE = 301,
+ TK_TYPEHEADERCODE = 302,
+ TK_MODULE = 303,
+ TK_CMODULE = 304,
+ TK_CONSMODULE = 305,
+ TK_COMPOMODULE = 306,
+ TK_CLASS = 307,
+ TK_STRUCT = 308,
+ TK_PUBLIC = 309,
+ TK_PROTECTED = 310,
+ TK_PRIVATE = 311,
+ TK_SIGNALS = 312,
+ TK_SIGNAL_METHOD = 313,
+ TK_SLOTS = 314,
+ TK_SLOT_METHOD = 315,
+ TK_BOOL = 316,
+ TK_SHORT = 317,
+ TK_INT = 318,
+ TK_LONG = 319,
+ TK_FLOAT = 320,
+ TK_DOUBLE = 321,
+ TK_CHAR = 322,
+ TK_WCHAR_T = 323,
+ TK_VOID = 324,
+ TK_PYOBJECT = 325,
+ TK_PYTUPLE = 326,
+ TK_PYLIST = 327,
+ TK_PYDICT = 328,
+ TK_PYCALLABLE = 329,
+ TK_PYSLICE = 330,
+ TK_PYTYPE = 331,
+ TK_VIRTUAL = 332,
+ TK_ENUM = 333,
+ TK_SIGNED = 334,
+ TK_UNSIGNED = 335,
+ TK_SCOPE = 336,
+ TK_LOGICAL_OR = 337,
+ TK_CONST = 338,
+ TK_STATIC = 339,
+ TK_SIPSIGNAL = 340,
+ TK_SIPSLOT = 341,
+ TK_SIPANYSLOT = 342,
+ TK_SIPRXCON = 343,
+ TK_SIPRXDIS = 344,
+ TK_SIPSLOTCON = 345,
+ TK_SIPSLOTDIS = 346,
+ TK_NUMBER = 347,
+ TK_REAL = 348,
+ TK_TYPEDEF = 349,
+ TK_NAMESPACE = 350,
+ TK_TIMELINE = 351,
+ TK_PLATFORMS = 352,
+ TK_FEATURE = 353,
+ TK_LICENSE = 354,
+ TK_QCHAR = 355,
+ TK_TRUE = 356,
+ TK_FALSE = 357,
+ TK_NULL = 358,
+ TK_OPERATOR = 359,
+ TK_THROW = 360,
+ TK_QOBJECT = 361,
+ TK_EXCEPTION = 362,
+ TK_RAISECODE = 363,
+ TK_EXPLICIT = 364,
+ TK_TEMPLATE = 365,
+ TK_ELLIPSIS = 366,
+ TK_DEFMETATYPE = 367,
+ TK_DEFSUPERTYPE = 368
+ };
+#endif
+/* Tokens. */
+#define TK_API 258
+#define TK_DEFENCODING 259
+#define TK_PLUGIN 260
+#define TK_DOCSTRING 261
+#define TK_DOC 262
+#define TK_EXPORTEDDOC 263
+#define TK_MAKEFILE 264
+#define TK_ACCESSCODE 265
+#define TK_GETCODE 266
+#define TK_SETCODE 267
+#define TK_PREINITCODE 268
+#define TK_INITCODE 269
+#define TK_POSTINITCODE 270
+#define TK_UNITCODE 271
+#define TK_MODCODE 272
+#define TK_TYPECODE 273
+#define TK_PREPYCODE 274
+#define TK_COPYING 275
+#define TK_MAPPEDTYPE 276
+#define TK_CODELINE 277
+#define TK_IF 278
+#define TK_END 279
+#define TK_NAME 280
+#define TK_PATHNAME 281
+#define TK_STRING 282
+#define TK_VIRTUALCATCHERCODE 283
+#define TK_TRAVERSECODE 284
+#define TK_CLEARCODE 285
+#define TK_GETBUFFERCODE 286
+#define TK_RELEASEBUFFERCODE 287
+#define TK_READBUFFERCODE 288
+#define TK_WRITEBUFFERCODE 289
+#define TK_SEGCOUNTCODE 290
+#define TK_CHARBUFFERCODE 291
+#define TK_PICKLECODE 292
+#define TK_METHODCODE 293
+#define TK_FROMTYPE 294
+#define TK_TOTYPE 295
+#define TK_TOSUBCLASS 296
+#define TK_INCLUDE 297
+#define TK_OPTINCLUDE 298
+#define TK_IMPORT 299
+#define TK_EXPHEADERCODE 300
+#define TK_MODHEADERCODE 301
+#define TK_TYPEHEADERCODE 302
+#define TK_MODULE 303
+#define TK_CMODULE 304
+#define TK_CONSMODULE 305
+#define TK_COMPOMODULE 306
+#define TK_CLASS 307
+#define TK_STRUCT 308
+#define TK_PUBLIC 309
+#define TK_PROTECTED 310
+#define TK_PRIVATE 311
+#define TK_SIGNALS 312
+#define TK_SIGNAL_METHOD 313
+#define TK_SLOTS 314
+#define TK_SLOT_METHOD 315
+#define TK_BOOL 316
+#define TK_SHORT 317
+#define TK_INT 318
+#define TK_LONG 319
+#define TK_FLOAT 320
+#define TK_DOUBLE 321
+#define TK_CHAR 322
+#define TK_WCHAR_T 323
+#define TK_VOID 324
+#define TK_PYOBJECT 325
+#define TK_PYTUPLE 326
+#define TK_PYLIST 327
+#define TK_PYDICT 328
+#define TK_PYCALLABLE 329
+#define TK_PYSLICE 330
+#define TK_PYTYPE 331
+#define TK_VIRTUAL 332
+#define TK_ENUM 333
+#define TK_SIGNED 334
+#define TK_UNSIGNED 335
+#define TK_SCOPE 336
+#define TK_LOGICAL_OR 337
+#define TK_CONST 338
+#define TK_STATIC 339
+#define TK_SIPSIGNAL 340
+#define TK_SIPSLOT 341
+#define TK_SIPANYSLOT 342
+#define TK_SIPRXCON 343
+#define TK_SIPRXDIS 344
+#define TK_SIPSLOTCON 345
+#define TK_SIPSLOTDIS 346
+#define TK_NUMBER 347
+#define TK_REAL 348
+#define TK_TYPEDEF 349
+#define TK_NAMESPACE 350
+#define TK_TIMELINE 351
+#define TK_PLATFORMS 352
+#define TK_FEATURE 353
+#define TK_LICENSE 354
+#define TK_QCHAR 355
+#define TK_TRUE 356
+#define TK_FALSE 357
+#define TK_NULL 358
+#define TK_OPERATOR 359
+#define TK_THROW 360
+#define TK_QOBJECT 361
+#define TK_EXCEPTION 362
+#define TK_RAISECODE 363
+#define TK_EXPLICIT 364
+#define TK_TEMPLATE 365
+#define TK_ELLIPSIS 366
+#define TK_DEFMETATYPE 367
+#define TK_DEFSUPERTYPE 368
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+{
+
+/* Line 214 of yacc.c */
+#line 147 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+
+ char qchar;
+ char *text;
+ long number;
+ double real;
+ argDef memArg;
+ signatureDef signature;
+ signatureDef *optsignature;
+ throwArgs *throwlist;
+ codeBlock *codeb;
+ valueDef value;
+ valueDef *valp;
+ optFlags optflags;
+ optFlag flag;
+ scopedNameDef *scpvalp;
+ fcallDef fcall;
+ int boolean;
+ exceptionDef exceptionbase;
+ classDef *klass;
+
+
+
+/* Line 214 of yacc.c */
+#line 487 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.c"
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+/* Copy the second part of user declarations. */
+
+
+/* Line 264 of yacc.c */
+#line 499 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.c"
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions. */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int yyi)
+#else
+static int
+YYID (yyi)
+ int yyi;
+#endif
+{
+ return yyi;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined _STDLIB_H \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yytype_int16 yyss_alloc;
+ YYSTYPE yyvs_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (YYID (0))
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
+ Stack = &yyptr->Stack_alloc; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (YYID (0))
+
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 4
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 1193
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 136
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 151
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 372
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 637
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 368
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const yytype_uint8 yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 119, 2, 2, 2, 134, 126, 2,
+ 117, 118, 124, 123, 121, 120, 2, 125, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 131, 116,
+ 129, 122, 130, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 132, 2, 133, 135, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 114, 127, 115, 128, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+ 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112, 113
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const yytype_uint16 yyprhs[] =
+{
+ 0, 0, 3, 5, 8, 9, 12, 14, 16, 18,
+ 20, 22, 24, 26, 28, 30, 32, 34, 36, 38,
+ 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
+ 60, 62, 64, 66, 68, 70, 72, 74, 76, 78,
+ 80, 82, 84, 86, 88, 90, 92, 94, 96, 99,
+ 102, 106, 116, 117, 121, 124, 125, 131, 132, 139,
+ 144, 146, 149, 151, 154, 157, 159, 161, 175, 176,
+ 184, 186, 189, 190, 196, 198, 201, 203, 206, 207,
+ 213, 215, 218, 220, 225, 227, 230, 234, 239, 241,
+ 245, 247, 250, 253, 256, 259, 262, 266, 268, 270,
+ 272, 274, 275, 277, 280, 283, 286, 287, 290, 291,
+ 294, 295, 298, 301, 304, 307, 310, 311, 313, 316,
+ 319, 322, 325, 328, 331, 334, 337, 340, 343, 346,
+ 349, 352, 355, 358, 361, 364, 367, 372, 375, 377,
+ 380, 381, 390, 391, 393, 394, 396, 397, 399, 401,
+ 404, 406, 408, 413, 414, 416, 417, 420, 421, 424,
+ 426, 430, 432, 434, 436, 438, 440, 442, 443, 445,
+ 447, 449, 451, 454, 456, 460, 462, 464, 469, 471,
+ 473, 475, 477, 479, 481, 483, 484, 486, 490, 496,
+ 508, 509, 510, 519, 520, 524, 529, 530, 531, 540,
+ 541, 544, 546, 550, 552, 553, 557, 559, 562, 564,
+ 566, 568, 570, 572, 574, 576, 578, 580, 582, 584,
+ 586, 588, 590, 592, 594, 596, 598, 600, 602, 604,
+ 606, 608, 611, 614, 618, 622, 626, 629, 630, 632,
+ 644, 645, 649, 651, 662, 663, 669, 670, 677, 678,
+ 680, 695, 703, 718, 732, 734, 736, 738, 740, 742,
+ 744, 746, 748, 751, 754, 757, 760, 763, 766, 769,
+ 772, 775, 778, 782, 786, 788, 791, 794, 796, 799,
+ 802, 805, 807, 810, 811, 813, 814, 817, 818, 822,
+ 824, 828, 830, 834, 836, 842, 844, 846, 849, 850,
+ 852, 853, 856, 857, 860, 862, 863, 865, 869, 874,
+ 879, 884, 888, 892, 899, 906, 910, 913, 914, 918,
+ 919, 923, 925, 926, 930, 932, 934, 936, 937, 941,
+ 943, 951, 956, 960, 964, 965, 967, 968, 971, 973,
+ 978, 981, 984, 986, 988, 991, 993, 995, 998, 1001,
+ 1005, 1007, 1009, 1011, 1014, 1017, 1019, 1021, 1023, 1025,
+ 1027, 1029, 1031, 1033, 1035, 1037, 1039, 1041, 1045, 1046,
+ 1051, 1052, 1054
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yytype_int16 yyrhs[] =
+{
+ 137, 0, -1, 138, -1, 137, 138, -1, -1, 139,
+ 140, -1, 177, -1, 175, -1, 176, -1, 143, -1,
+ 187, -1, 181, -1, 182, -1, 183, -1, 144, -1,
+ 164, -1, 159, -1, 163, -1, 172, -1, 142, -1,
+ 173, -1, 174, -1, 188, -1, 189, -1, 201, -1,
+ 203, -1, 204, -1, 205, -1, 206, -1, 207, -1,
+ 208, -1, 209, -1, 210, -1, 148, -1, 150, -1,
+ 141, -1, 168, -1, 171, -1, 156, -1, 232, -1,
+ 238, -1, 235, -1, 145, -1, 231, -1, 213, -1,
+ 255, -1, 278, -1, 190, -1, 4, 27, -1, 5,
+ 25, -1, 3, 25, 92, -1, 107, 227, 146, 259,
+ 114, 191, 147, 115, 116, -1, -1, 117, 227, 118,
+ -1, 108, 211, -1, -1, 21, 283, 259, 149, 152,
+ -1, -1, 237, 21, 283, 259, 151, 152, -1, 114,
+ 153, 115, 116, -1, 154, -1, 153, 154, -1, 190,
+ -1, 39, 211, -1, 40, 211, -1, 213, -1, 155,
+ -1, 84, 279, 25, 117, 267, 118, 257, 285, 259,
+ 253, 116, 264, 265, -1, -1, 95, 25, 157, 114,
+ 158, 115, 116, -1, 141, -1, 158, 141, -1, -1,
+ 97, 160, 114, 161, 115, -1, 162, -1, 161, 162,
+ -1, 25, -1, 98, 25, -1, -1, 96, 165, 114,
+ 166, 115, -1, 167, -1, 166, 167, -1, 25, -1,
+ 23, 117, 170, 118, -1, 25, -1, 119, 25, -1,
+ 169, 82, 25, -1, 169, 82, 119, 25, -1, 169,
+ -1, 216, 120, 216, -1, 24, -1, 99, 259, -1,
+ 112, 179, -1, 113, 179, -1, 50, 179, -1, 51,
+ 179, -1, 178, 179, 180, -1, 48, -1, 49, -1,
+ 25, -1, 26, -1, -1, 92, -1, 42, 26, -1,
+ 43, 26, -1, 44, 26, -1, -1, 10, 211, -1,
+ -1, 11, 211, -1, -1, 12, 211, -1, 20, 211,
+ -1, 45, 211, -1, 46, 211, -1, 47, 211, -1,
+ -1, 190, -1, 29, 211, -1, 30, 211, -1, 31,
+ 211, -1, 32, 211, -1, 33, 211, -1, 34, 211,
+ -1, 35, 211, -1, 36, 211, -1, 37, 211, -1,
+ 17, 211, -1, 18, 211, -1, 13, 211, -1, 14,
+ 211, -1, 15, 211, -1, 16, 211, -1, 19, 211,
+ -1, 7, 211, -1, 8, 211, -1, 9, 26, 215,
+ 211, -1, 212, 24, -1, 22, -1, 212, 22, -1,
+ -1, 78, 216, 259, 214, 114, 217, 115, 116, -1,
+ -1, 26, -1, -1, 25, -1, -1, 218, -1, 219,
+ -1, 218, 219, -1, 168, -1, 171, -1, 25, 221,
+ 259, 220, -1, -1, 121, -1, -1, 122, 226, -1,
+ -1, 122, 223, -1, 226, -1, 223, 224, 226, -1,
+ 120, -1, 123, -1, 124, -1, 125, -1, 126, -1,
+ 127, -1, -1, 119, -1, 128, -1, 120, -1, 123,
+ -1, 225, 229, -1, 228, -1, 227, 81, 228, -1,
+ 25, -1, 227, -1, 283, 117, 230, 118, -1, 93,
+ -1, 92, -1, 101, -1, 102, -1, 103, -1, 27,
+ -1, 100, -1, -1, 223, -1, 230, 121, 223, -1,
+ 94, 279, 25, 259, 116, -1, 94, 279, 117, 282,
+ 25, 118, 117, 284, 118, 259, 116, -1, -1, -1,
+ 53, 227, 233, 241, 259, 234, 244, 116, -1, -1,
+ 237, 236, 238, -1, 110, 129, 284, 130, -1, -1,
+ -1, 52, 227, 239, 241, 259, 240, 244, 116, -1,
+ -1, 131, 242, -1, 243, -1, 242, 121, 243, -1,
+ 227, -1, -1, 114, 245, 115, -1, 246, -1, 245,
+ 246, -1, 168, -1, 171, -1, 156, -1, 232, -1,
+ 238, -1, 145, -1, 231, -1, 213, -1, 263, -1,
+ 202, -1, 190, -1, 192, -1, 193, -1, 194, -1,
+ 195, -1, 196, -1, 197, -1, 198, -1, 199, -1,
+ 200, -1, 249, -1, 248, -1, 270, -1, 41, 211,
+ -1, 40, 211, -1, 54, 247, 131, -1, 55, 247,
+ 131, -1, 56, 247, 131, -1, 57, 131, -1, -1,
+ 59, -1, 254, 128, 25, 117, 118, 285, 258, 259,
+ 116, 265, 266, -1, -1, 109, 250, 251, -1, 251,
+ -1, 25, 117, 267, 118, 285, 259, 252, 116, 264,
+ 265, -1, -1, 132, 117, 267, 118, 133, -1, -1,
+ 132, 279, 117, 267, 118, 133, -1, -1, 77, -1,
+ 279, 25, 117, 267, 118, 257, 285, 258, 259, 253,
+ 116, 264, 265, 266, -1, 279, 104, 122, 117, 279,
+ 118, 116, -1, 279, 104, 256, 117, 267, 118, 257,
+ 285, 258, 259, 253, 116, 265, 266, -1, 104, 279,
+ 117, 267, 118, 257, 285, 258, 259, 253, 116, 265,
+ 266, -1, 123, -1, 120, -1, 124, -1, 125, -1,
+ 134, -1, 126, -1, 127, -1, 135, -1, 129, 129,
+ -1, 130, 130, -1, 123, 122, -1, 120, 122, -1,
+ 124, 122, -1, 125, 122, -1, 134, 122, -1, 126,
+ 122, -1, 127, 122, -1, 135, 122, -1, 129, 129,
+ 122, -1, 130, 130, 122, -1, 128, -1, 117, 118,
+ -1, 132, 133, -1, 129, -1, 129, 122, -1, 122,
+ 122, -1, 119, 122, -1, 130, -1, 130, 122, -1,
+ -1, 83, -1, -1, 122, 92, -1, -1, 125, 260,
+ 125, -1, 261, -1, 260, 121, 261, -1, 25, -1,
+ 25, 122, 262, -1, 179, -1, 25, 131, 180, 120,
+ 180, -1, 27, -1, 92, -1, 6, 211, -1, -1,
+ 263, -1, -1, 38, 211, -1, -1, 28, 211, -1,
+ 268, -1, -1, 269, -1, 268, 121, 269, -1, 85,
+ 216, 259, 222, -1, 86, 216, 259, 222, -1, 87,
+ 216, 259, 222, -1, 88, 216, 259, -1, 89, 216,
+ 259, -1, 90, 117, 267, 118, 216, 259, -1, 91,
+ 117, 267, 118, 216, 259, -1, 106, 216, 259, -1,
+ 280, 222, -1, -1, 58, 271, 273, -1, -1, 60,
+ 272, 273, -1, 273, -1, -1, 84, 274, 275, -1,
+ 275, -1, 276, -1, 278, -1, -1, 77, 277, 255,
+ -1, 255, -1, 279, 25, 259, 116, 184, 185, 186,
+ -1, 83, 283, 282, 281, -1, 283, 282, 281, -1,
+ 279, 216, 259, -1, -1, 126, -1, -1, 282, 124,
+ -1, 227, -1, 227, 129, 284, 130, -1, 53, 227,
+ -1, 80, 62, -1, 62, -1, 80, -1, 80, 63,
+ -1, 63, -1, 64, -1, 80, 64, -1, 64, 64,
+ -1, 80, 64, 64, -1, 65, -1, 66, -1, 61,
+ -1, 79, 67, -1, 80, 67, -1, 67, -1, 68,
+ -1, 69, -1, 70, -1, 71, -1, 72, -1, 73,
+ -1, 74, -1, 75, -1, 76, -1, 111, -1, 279,
+ -1, 284, 121, 279, -1, -1, 105, 117, 286, 118,
+ -1, -1, 227, -1, 286, 121, 227, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const yytype_uint16 yyrline[] =
+{
+ 0, 350, 350, 351, 354, 354, 373, 374, 375, 376,
+ 377, 378, 379, 380, 381, 382, 383, 384, 385, 386,
+ 387, 388, 389, 393, 397, 401, 402, 403, 404, 405,
+ 406, 407, 408, 409, 410, 411, 414, 415, 416, 417,
+ 418, 419, 420, 421, 422, 423, 424, 425, 438, 447,
+ 452, 478, 517, 521, 595, 600, 600, 606, 606, 656,
+ 670, 671, 674, 678, 687, 696, 697, 700, 714, 714,
+ 751, 752, 755, 755, 782, 783, 786, 791, 796, 796,
+ 821, 822, 825, 830, 843, 846, 849, 852, 857, 858,
+ 863, 869, 896, 907, 918, 931, 944, 977, 980, 985,
+ 986, 1002, 1005, 1008, 1013, 1018, 1023, 1026, 1031, 1034,
+ 1039, 1042, 1047, 1052, 1057, 1062, 1067, 1070, 1073, 1078,
+ 1083, 1088, 1093, 1098, 1103, 1108, 1113, 1118, 1123, 1128,
+ 1134, 1140, 1146, 1152, 1161, 1167, 1172, 1178, 1181, 1182,
+ 1193, 1193, 1205, 1208, 1213, 1216, 1221, 1222, 1225, 1226,
+ 1229, 1230, 1231, 1259, 1260, 1263, 1264, 1267, 1270, 1275,
+ 1276, 1294, 1297, 1300, 1303, 1306, 1309, 1314, 1317, 1320,
+ 1323, 1326, 1331, 1349, 1350, 1358, 1363, 1372, 1382, 1386,
+ 1390, 1394, 1398, 1402, 1406, 1412, 1417, 1423, 1441, 1448,
+ 1473, 1479, 1473, 1494, 1494, 1520, 1525, 1531, 1525, 1543,
+ 1544, 1547, 1548, 1551, 1590, 1593, 1598, 1599, 1602, 1603,
+ 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1620, 1624, 1628,
+ 1639, 1650, 1661, 1672, 1683, 1694, 1705, 1716, 1727, 1728,
+ 1729, 1730, 1741, 1752, 1759, 1766, 1773, 1782, 1785, 1790,
+ 1844, 1844, 1845, 1848, 1875, 1878, 1885, 1888, 1896, 1899,
+ 1904, 1922, 1942, 1971, 2049, 2050, 2051, 2052, 2053, 2054,
+ 2055, 2056, 2057, 2058, 2059, 2060, 2061, 2062, 2063, 2064,
+ 2065, 2066, 2067, 2068, 2069, 2070, 2071, 2072, 2073, 2074,
+ 2075, 2076, 2077, 2080, 2083, 2088, 2091, 2099, 2102, 2108,
+ 2112, 2124, 2128, 2134, 2138, 2161, 2165, 2171, 2176, 2179,
+ 2182, 2185, 2190, 2193, 2198, 2246, 2251, 2257, 2284, 2293,
+ 2302, 2311, 2322, 2330, 2344, 2358, 2364, 2371, 2371, 2372,
+ 2372, 2373, 2377, 2377, 2378, 2382, 2383, 2387, 2387, 2388,
+ 2391, 2426, 2431, 2438, 2510, 2513, 2521, 2524, 2529, 2537,
+ 2548, 2563, 2567, 2571, 2575, 2579, 2583, 2587, 2591, 2595,
+ 2599, 2603, 2607, 2611, 2615, 2619, 2623, 2627, 2631, 2635,
+ 2639, 2643, 2647, 2651, 2655, 2659, 2665, 2671, 2687, 2690,
+ 2698, 2704, 2711
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "TK_API", "TK_DEFENCODING", "TK_PLUGIN",
+ "TK_DOCSTRING", "TK_DOC", "TK_EXPORTEDDOC", "TK_MAKEFILE",
+ "TK_ACCESSCODE", "TK_GETCODE", "TK_SETCODE", "TK_PREINITCODE",
+ "TK_INITCODE", "TK_POSTINITCODE", "TK_UNITCODE", "TK_MODCODE",
+ "TK_TYPECODE", "TK_PREPYCODE", "TK_COPYING", "TK_MAPPEDTYPE",
+ "TK_CODELINE", "TK_IF", "TK_END", "TK_NAME", "TK_PATHNAME", "TK_STRING",
+ "TK_VIRTUALCATCHERCODE", "TK_TRAVERSECODE", "TK_CLEARCODE",
+ "TK_GETBUFFERCODE", "TK_RELEASEBUFFERCODE", "TK_READBUFFERCODE",
+ "TK_WRITEBUFFERCODE", "TK_SEGCOUNTCODE", "TK_CHARBUFFERCODE",
+ "TK_PICKLECODE", "TK_METHODCODE", "TK_FROMTYPE", "TK_TOTYPE",
+ "TK_TOSUBCLASS", "TK_INCLUDE", "TK_OPTINCLUDE", "TK_IMPORT",
+ "TK_EXPHEADERCODE", "TK_MODHEADERCODE", "TK_TYPEHEADERCODE", "TK_MODULE",
+ "TK_CMODULE", "TK_CONSMODULE", "TK_COMPOMODULE", "TK_CLASS", "TK_STRUCT",
+ "TK_PUBLIC", "TK_PROTECTED", "TK_PRIVATE", "TK_SIGNALS",
+ "TK_SIGNAL_METHOD", "TK_SLOTS", "TK_SLOT_METHOD", "TK_BOOL", "TK_SHORT",
+ "TK_INT", "TK_LONG", "TK_FLOAT", "TK_DOUBLE", "TK_CHAR", "TK_WCHAR_T",
+ "TK_VOID", "TK_PYOBJECT", "TK_PYTUPLE", "TK_PYLIST", "TK_PYDICT",
+ "TK_PYCALLABLE", "TK_PYSLICE", "TK_PYTYPE", "TK_VIRTUAL", "TK_ENUM",
+ "TK_SIGNED", "TK_UNSIGNED", "TK_SCOPE", "TK_LOGICAL_OR", "TK_CONST",
+ "TK_STATIC", "TK_SIPSIGNAL", "TK_SIPSLOT", "TK_SIPANYSLOT",
+ "TK_SIPRXCON", "TK_SIPRXDIS", "TK_SIPSLOTCON", "TK_SIPSLOTDIS",
+ "TK_NUMBER", "TK_REAL", "TK_TYPEDEF", "TK_NAMESPACE", "TK_TIMELINE",
+ "TK_PLATFORMS", "TK_FEATURE", "TK_LICENSE", "TK_QCHAR", "TK_TRUE",
+ "TK_FALSE", "TK_NULL", "TK_OPERATOR", "TK_THROW", "TK_QOBJECT",
+ "TK_EXCEPTION", "TK_RAISECODE", "TK_EXPLICIT", "TK_TEMPLATE",
+ "TK_ELLIPSIS", "TK_DEFMETATYPE", "TK_DEFSUPERTYPE", "'{'", "'}'", "';'",
+ "'('", "')'", "'!'", "'-'", "','", "'='", "'+'", "'*'", "'/'", "'&'",
+ "'|'", "'~'", "'<'", "'>'", "':'", "'['", "']'", "'%'", "'^'", "$accept",
+ "specification", "statement", "$@1", "modstatement", "nsstatement",
+ "defencoding", "plugin", "api", "exception", "baseexception",
+ "raisecode", "mappedtype", "$@2", "mappedtypetmpl", "$@3",
+ "mtdefinition", "mtbody", "mtline", "mtfunction", "namespace", "$@4",
+ "nsbody", "platforms", "$@5", "platformlist", "platform", "feature",
+ "timeline", "$@6", "qualifierlist", "qualifiername", "ifstart",
+ "oredqualifiers", "qualifiers", "ifend", "license", "defmetatype",
+ "defsupertype", "consmodule", "compmodule", "module", "modlang",
+ "dottedname", "optnumber", "include", "optinclude", "import",
+ "optaccesscode", "optgetcode", "optsetcode", "copying", "exphdrcode",
+ "modhdrcode", "typehdrcode", "opttypehdrcode", "travcode", "clearcode",
+ "getbufcode", "releasebufcode", "readbufcode", "writebufcode",
+ "segcountcode", "charbufcode", "picklecode", "modcode", "typecode",
+ "preinitcode", "initcode", "postinitcode", "unitcode", "prepycode",
+ "doc", "exporteddoc", "makefile", "codeblock", "codelines", "enum",
+ "$@7", "optfilename", "optname", "optenumbody", "enumbody", "enumline",
+ "optcomma", "optenumassign", "optassign", "expr", "binop", "optunop",
+ "value", "scopedname", "scopepart", "simplevalue", "exprlist", "typedef",
+ "struct", "$@8", "$@9", "classtmpl", "$@10", "template", "class", "$@11",
+ "$@12", "superclasses", "superlist", "superclass", "optclassbody",
+ "classbody", "classline", "optslot", "dtor", "ctor", "$@13",
+ "simplector", "optctorsig", "optsig", "optvirtual", "function",
+ "operatorname", "optconst", "optabstract", "optflags", "flaglist",
+ "flag", "flagvalue", "docstring", "optdocstring", "methodcode",
+ "virtualcatchercode", "arglist", "rawarglist", "argvalue", "varmember",
+ "$@14", "$@15", "simple_varmem", "$@16", "varmem", "member", "$@17",
+ "variable", "cpptype", "argtype", "optref", "deref", "basetype",
+ "cpptypelist", "optexceptions", "exceptionlist", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const yytype_uint16 yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
+ 295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
+ 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
+ 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,
+ 325, 326, 327, 328, 329, 330, 331, 332, 333, 334,
+ 335, 336, 337, 338, 339, 340, 341, 342, 343, 344,
+ 345, 346, 347, 348, 349, 350, 351, 352, 353, 354,
+ 355, 356, 357, 358, 359, 360, 361, 362, 363, 364,
+ 365, 366, 367, 368, 123, 125, 59, 40, 41, 33,
+ 45, 44, 61, 43, 42, 47, 38, 124, 126, 60,
+ 62, 58, 91, 93, 37, 94
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint16 yyr1[] =
+{
+ 0, 136, 137, 137, 139, 138, 140, 140, 140, 140,
+ 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+ 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+ 140, 140, 140, 140, 140, 140, 141, 141, 141, 141,
+ 141, 141, 141, 141, 141, 141, 141, 141, 142, 143,
+ 144, 145, 146, 146, 147, 149, 148, 151, 150, 152,
+ 153, 153, 154, 154, 154, 154, 154, 155, 157, 156,
+ 158, 158, 160, 159, 161, 161, 162, 163, 165, 164,
+ 166, 166, 167, 168, 169, 169, 169, 169, 170, 170,
+ 171, 172, 173, 174, 175, 176, 177, 178, 178, 179,
+ 179, 180, 180, 181, 182, 183, 184, 184, 185, 185,
+ 186, 186, 187, 188, 189, 190, 191, 191, 192, 193,
+ 194, 195, 196, 197, 198, 199, 200, 201, 202, 203,
+ 204, 205, 206, 207, 208, 209, 210, 211, 212, 212,
+ 214, 213, 215, 215, 216, 216, 217, 217, 218, 218,
+ 219, 219, 219, 220, 220, 221, 221, 222, 222, 223,
+ 223, 224, 224, 224, 224, 224, 224, 225, 225, 225,
+ 225, 225, 226, 227, 227, 228, 229, 229, 229, 229,
+ 229, 229, 229, 229, 229, 230, 230, 230, 231, 231,
+ 233, 234, 232, 236, 235, 237, 239, 240, 238, 241,
+ 241, 242, 242, 243, 244, 244, 245, 245, 246, 246,
+ 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
+ 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
+ 246, 246, 246, 246, 246, 246, 246, 247, 247, 248,
+ 250, 249, 249, 251, 252, 252, 253, 253, 254, 254,
+ 255, 255, 255, 255, 256, 256, 256, 256, 256, 256,
+ 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
+ 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
+ 256, 256, 256, 257, 257, 258, 258, 259, 259, 260,
+ 260, 261, 261, 262, 262, 262, 262, 263, 264, 264,
+ 265, 265, 266, 266, 267, 268, 268, 268, 269, 269,
+ 269, 269, 269, 269, 269, 269, 269, 271, 270, 272,
+ 270, 270, 274, 273, 273, 275, 275, 277, 276, 276,
+ 278, 279, 279, 280, 281, 281, 282, 282, 283, 283,
+ 283, 283, 283, 283, 283, 283, 283, 283, 283, 283,
+ 283, 283, 283, 283, 283, 283, 283, 283, 283, 283,
+ 283, 283, 283, 283, 283, 283, 284, 284, 285, 285,
+ 286, 286, 286
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 1, 2, 0, 2, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
+ 3, 9, 0, 3, 2, 0, 5, 0, 6, 4,
+ 1, 2, 1, 2, 2, 1, 1, 13, 0, 7,
+ 1, 2, 0, 5, 1, 2, 1, 2, 0, 5,
+ 1, 2, 1, 4, 1, 2, 3, 4, 1, 3,
+ 1, 2, 2, 2, 2, 2, 3, 1, 1, 1,
+ 1, 0, 1, 2, 2, 2, 0, 2, 0, 2,
+ 0, 2, 2, 2, 2, 2, 0, 1, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 4, 2, 1, 2,
+ 0, 8, 0, 1, 0, 1, 0, 1, 1, 2,
+ 1, 1, 4, 0, 1, 0, 2, 0, 2, 1,
+ 3, 1, 1, 1, 1, 1, 1, 0, 1, 1,
+ 1, 1, 2, 1, 3, 1, 1, 4, 1, 1,
+ 1, 1, 1, 1, 1, 0, 1, 3, 5, 11,
+ 0, 0, 8, 0, 3, 4, 0, 0, 8, 0,
+ 2, 1, 3, 1, 0, 3, 1, 2, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 3, 3, 3, 2, 0, 1, 11,
+ 0, 3, 1, 10, 0, 5, 0, 6, 0, 1,
+ 14, 7, 14, 13, 1, 1, 1, 1, 1, 1,
+ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 3, 3, 1, 2, 2, 1, 2, 2,
+ 2, 1, 2, 0, 1, 0, 2, 0, 3, 1,
+ 3, 1, 3, 1, 5, 1, 1, 2, 0, 1,
+ 0, 2, 0, 2, 1, 0, 1, 3, 4, 4,
+ 4, 3, 3, 6, 6, 3, 2, 0, 3, 0,
+ 3, 1, 0, 3, 1, 1, 1, 0, 3, 1,
+ 7, 4, 3, 3, 0, 1, 0, 2, 1, 4,
+ 2, 2, 1, 1, 2, 1, 1, 2, 2, 3,
+ 1, 1, 1, 2, 2, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 3, 0, 4,
+ 0, 1, 3
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint16 yydefact[] =
+{
+ 4, 4, 2, 0, 1, 3, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 90, 175, 0, 0, 0, 0, 0, 0, 97,
+ 98, 0, 0, 0, 0, 352, 342, 345, 346, 350,
+ 351, 355, 356, 357, 358, 359, 360, 361, 362, 363,
+ 364, 144, 0, 343, 0, 0, 0, 78, 72, 0,
+ 287, 0, 0, 0, 365, 0, 0, 5, 35, 19,
+ 9, 14, 42, 33, 34, 38, 16, 17, 15, 36,
+ 37, 18, 20, 21, 7, 8, 6, 0, 11, 12,
+ 13, 10, 22, 23, 47, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, 44, 338, 173, 43, 39, 41,
+ 193, 40, 45, 46, 0, 336, 0, 48, 49, 138,
+ 134, 0, 135, 142, 129, 130, 131, 132, 127, 133,
+ 112, 0, 287, 144, 103, 104, 105, 113, 114, 115,
+ 99, 100, 94, 95, 196, 190, 348, 145, 287, 353,
+ 341, 344, 347, 354, 336, 0, 68, 0, 0, 77,
+ 0, 91, 0, 52, 0, 92, 93, 101, 0, 0,
+ 0, 0, 287, 0, 334, 50, 139, 137, 143, 0,
+ 340, 55, 84, 0, 88, 0, 0, 199, 199, 140,
+ 349, 334, 287, 336, 0, 0, 0, 291, 0, 289,
+ 305, 0, 287, 366, 0, 102, 96, 174, 0, 287,
+ 194, 305, 0, 0, 0, 255, 0, 254, 256, 257,
+ 259, 260, 274, 277, 281, 0, 258, 261, 0, 337,
+ 335, 332, 136, 0, 85, 0, 83, 144, 0, 287,
+ 287, 0, 331, 0, 0, 0, 82, 0, 80, 76,
+ 0, 74, 0, 0, 288, 144, 144, 144, 144, 144,
+ 0, 0, 144, 0, 304, 306, 144, 157, 0, 0,
+ 0, 195, 339, 57, 0, 106, 275, 280, 265, 0,
+ 279, 264, 266, 267, 269, 270, 278, 262, 282, 263,
+ 276, 268, 271, 305, 0, 56, 86, 0, 89, 203,
+ 200, 201, 197, 191, 146, 188, 0, 70, 0, 193,
+ 79, 81, 73, 75, 99, 295, 296, 293, 292, 290,
+ 287, 287, 287, 287, 287, 305, 305, 287, 283, 0,
+ 287, 167, 316, 53, 116, 367, 0, 283, 0, 108,
+ 0, 272, 273, 0, 0, 0, 0, 0, 60, 66,
+ 62, 65, 87, 0, 204, 204, 155, 150, 151, 0,
+ 147, 148, 0, 0, 71, 101, 157, 157, 157, 311,
+ 312, 0, 0, 315, 284, 368, 307, 333, 168, 170,
+ 171, 169, 158, 0, 159, 117, 0, 58, 368, 107,
+ 0, 110, 0, 283, 63, 64, 0, 0, 61, 202,
+ 248, 0, 0, 167, 287, 0, 149, 0, 69, 0,
+ 308, 309, 310, 144, 144, 0, 285, 161, 162, 163,
+ 164, 165, 166, 167, 183, 179, 178, 184, 180, 181,
+ 182, 176, 172, 0, 0, 0, 285, 109, 0, 330,
+ 251, 368, 0, 59, 0, 0, 175, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 237, 237,
+ 237, 0, 317, 319, 327, 322, 240, 213, 210, 208,
+ 209, 218, 219, 220, 221, 222, 223, 224, 225, 226,
+ 227, 217, 215, 214, 211, 212, 248, 206, 229, 228,
+ 242, 0, 329, 216, 230, 321, 324, 325, 326, 198,
+ 192, 156, 153, 141, 0, 101, 287, 287, 370, 0,
+ 287, 160, 167, 54, 0, 287, 111, 285, 305, 297,
+ 128, 305, 118, 119, 120, 121, 122, 123, 124, 125,
+ 126, 232, 231, 238, 0, 0, 0, 236, 0, 0,
+ 0, 0, 0, 205, 207, 0, 154, 152, 287, 294,
+ 313, 314, 371, 0, 286, 246, 186, 0, 51, 246,
+ 287, 0, 0, 233, 234, 235, 327, 318, 320, 328,
+ 0, 323, 0, 241, 0, 0, 369, 0, 0, 0,
+ 177, 167, 0, 246, 283, 368, 0, 0, 189, 372,
+ 0, 300, 187, 298, 0, 368, 287, 368, 305, 0,
+ 302, 299, 300, 300, 287, 244, 285, 0, 301, 0,
+ 253, 302, 302, 246, 0, 0, 287, 0, 303, 250,
+ 252, 0, 305, 298, 0, 247, 298, 0, 300, 300,
+ 300, 0, 243, 302, 67, 245, 239
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int16 yydefgoto[] =
+{
+ -1, 1, 2, 3, 67, 68, 69, 70, 71, 72,
+ 202, 435, 73, 233, 74, 336, 295, 347, 348, 349,
+ 75, 194, 308, 76, 158, 250, 251, 77, 78, 157,
+ 247, 248, 79, 184, 185, 80, 81, 82, 83, 84,
+ 85, 86, 87, 142, 206, 88, 89, 90, 339, 391,
+ 439, 91, 92, 93, 94, 386, 472, 473, 474, 475,
+ 476, 477, 478, 479, 480, 95, 481, 96, 97, 98,
+ 99, 100, 101, 102, 103, 120, 121, 104, 241, 179,
+ 148, 359, 360, 361, 547, 404, 332, 382, 423, 383,
+ 384, 105, 106, 432, 557, 107, 108, 188, 355, 109,
+ 171, 309, 111, 187, 354, 239, 300, 301, 401, 486,
+ 487, 534, 488, 489, 542, 490, 615, 579, 491, 492,
+ 228, 375, 510, 161, 198, 199, 318, 601, 602, 600,
+ 610, 263, 264, 265, 494, 538, 539, 495, 541, 496,
+ 497, 540, 498, 266, 267, 231, 174, 115, 204, 416,
+ 553
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -544
+static const yytype_int16 yypact[] =
+{
+ -544, 62, -544, 558, -544, -544, 76, 88, 126, 144,
+ 144, 150, 144, 144, 144, 144, 144, 144, 144, 1082,
+ 87, -544, -544, 159, 183, 190, 144, 144, 144, -544,
+ -544, 165, 165, 189, 189, -544, -544, -544, 154, -544,
+ -544, -544, -544, -544, -544, -544, -544, -544, -544, -544,
+ -544, 203, 169, 97, 1082, 321, 212, -544, -544, 213,
+ 114, 321, 189, 111, -544, 165, 165, -544, -544, -544,
+ -544, -544, -544, -544, -544, -544, -544, -544, -544, -544,
+ -544, -544, -544, -544, -544, -544, -544, 165, -544, -544,
+ -544, -544, -544, -544, -544, -544, -544, -544, -544, -544,
+ -544, -544, -544, -544, -544, -26, -544, -544, -544, -544,
+ 220, -544, -544, -544, 9, -544, 153, -544, -544, -544,
+ -544, 63, -544, 216, -544, -544, -544, -544, -544, -544,
+ -544, 189, 114, 2, -544, -544, -544, -544, -544, -544,
+ -544, -544, -544, -544, 167, 8, -544, -544, 114, -544,
+ -544, -544, 182, -544, -544, 12, -544, 135, 138, -544,
+ 228, -544, 137, -18, 321, -544, -544, 164, 189, 321,
+ 1082, 205, -11, 395, 81, -544, -544, -544, -544, 144,
+ 167, -544, 139, 235, 179, 145, 146, 133, 133, -544,
+ -544, 81, 114, -544, 151, 242, 244, 148, -65, -544,
+ 924, 189, 114, -544, -54, -544, -544, -544, -44, 114,
+ -544, 924, 155, 156, 157, 158, -6, 160, 181, 185,
+ 186, 187, -544, -56, -12, 140, 191, 193, 161, -544,
+ -544, -544, -544, 162, -544, 11, -544, 203, 189, 114,
+ 114, 196, -544, 195, 4, 872, -544, 18, -544, -544,
+ 20, -544, 71, 228, -544, 203, 203, 203, 203, 203,
+ 199, 200, 203, 163, 202, -544, 203, 198, -27, 207,
+ 321, -544, -544, -544, 194, 262, -544, -544, -544, 321,
+ -544, -544, -544, -544, -544, -544, -544, 209, -544, 210,
+ -544, -544, -544, 924, 110, -544, -544, 299, -544, 167,
+ 204, -544, -544, -544, 188, -544, 211, -544, 811, -544,
+ -544, -544, -544, -544, 206, -544, -544, -544, -544, -544,
+ 114, 114, 114, 114, 114, 924, 924, 114, 255, 924,
+ 114, 64, -544, -544, 280, -544, 162, 255, 144, 328,
+ 223, -544, -544, 224, 144, 144, 321, 41, -544, -544,
+ -544, -544, -544, 189, 226, 226, 221, -544, -544, 230,
+ 188, -544, 231, 233, -544, 164, 198, 198, 198, -544,
+ -544, 229, 232, -544, -544, 246, -544, -544, -544, -544,
+ -544, -544, 75, 400, -544, -544, 245, -544, 246, -544,
+ 144, 340, 238, 255, -544, -544, 330, 240, -544, -544,
+ 748, 241, 243, 64, 114, 247, -544, 321, -544, 248,
+ -544, -544, -544, 203, 203, 249, 236, -544, -544, -544,
+ -544, -544, -544, 64, -544, -544, -544, -544, -544, -544,
+ -544, -34, -544, 250, 144, 254, 236, -544, 144, -544,
+ -544, 246, 253, -544, 144, 144, 256, 144, 144, 144,
+ 144, 144, 144, 144, 144, 144, 144, 144, 302, 302,
+ 302, 234, -544, -544, 251, -544, -544, -544, -544, -544,
+ -544, -544, -544, -544, -544, -544, -544, -544, -544, -544,
+ -544, -544, -544, -544, -544, -544, 654, -544, -544, -544,
+ -544, 274, -544, -544, -544, -544, -544, -544, -544, -544,
+ -544, -544, 260, -544, 37, 164, 114, 114, 189, 270,
+ 114, -544, 54, -544, 259, 114, -544, 236, 924, -544,
+ -544, 924, -544, -544, -544, -544, -544, -544, -544, -544,
+ -544, -544, -544, -544, 272, 277, 278, -544, 976, 976,
+ 222, 1029, 339, -544, -544, 346, -544, -544, 114, -544,
+ -544, -544, 167, 50, -544, 279, 75, 68, -544, 279,
+ 114, 258, 294, -544, -544, -544, -544, -544, -544, -544,
+ 16, -544, 256, -544, 296, 261, -544, 189, 321, 298,
+ -544, 64, 300, 279, 255, 246, 301, 303, -544, 167,
+ 305, 334, 75, 411, 304, 246, 114, 246, 924, 144,
+ 391, -544, 334, 334, 114, 297, 236, 308, -544, 144,
+ -544, 391, 391, 279, 313, 315, 114, 316, -544, -544,
+ -544, 317, 924, 411, 320, -544, 411, 332, 334, 334,
+ 334, 318, -544, 391, -544, -544, -544
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yytype_int16 yypgoto[] =
+{
+ -544, -544, 451, -544, -544, -203, -544, -544, -544, -369,
+ -544, -544, -544, -544, -544, -544, 118, -544, 108, -544,
+ -350, -544, -544, -544, -544, -544, 208, -544, -544, -544,
+ -544, 239, -278, -544, -544, -276, -544, -544, -544, -544,
+ -544, -544, -544, -8, -335, -544, -544, -544, -544, -544,
+ -544, -544, -544, -544, -269, -544, -544, -544, -544, -544,
+ -544, -544, -544, -544, -544, -544, -544, -544, -544, -544,
+ -544, -544, -544, -544, -544, -10, -544, -254, -544, -544,
+ -114, -544, -544, 96, -544, -544, -133, -474, -544, -544,
+ -359, -23, 289, -544, -544, -349, -348, -544, -544, -544,
+ -544, 456, -150, -544, -544, 290, -544, 124, 127, -544,
+ -3, -263, -544, -544, -544, -61, -544, -513, -544, 6,
+ -544, -322, -413, -100, -544, 237, -544, -339, -420, -449,
+ -543, -199, -544, 166, -544, -544, -544, -313, -544, -53,
+ -544, -544, 10, -2, -544, 306, -119, -5, -149, -366,
+ -544
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -341
+static const yytype_int16 yytable[] =
+{
+ 122, 114, 124, 125, 126, 127, 128, 129, 130, 112,
+ 144, 145, 274, 113, 132, 388, 137, 138, 139, 186,
+ 208, 210, 436, 515, 143, 350, 357, 182, 358, 306,
+ 409, 467, 181, -340, 172, 191, 296, 192, 556, 163,
+ 351, 586, 307, 246, 501, 249, 582, 168, 189, 154,
+ 468, 483, 484, 155, 168, 168, 253, 165, 166, 162,
+ 254, 493, 4, 168, 511, 385, 286, 270, 619, 620,
+ 594, 441, 212, 287, 244, 517, 271, 270, 350, 167,
+ 344, 345, 357, -338, 358, 176, 272, 177, 28, 168,
+ 636, 333, 243, 351, 343, 169, 314, 141, 315, 201,
+ 621, 116, 269, 169, 560, 364, 211, 592, 180, 273,
+ 288, 279, -340, 173, 160, 117, 280, 467, 289, 51,
+ 173, 183, 469, 298, 470, 346, 371, 372, 229, 193,
+ 297, 471, -340, 310, -340, 312, 468, 483, 484, 302,
+ 303, 320, 321, 322, 323, 324, 482, 493, 327, 344,
+ 345, 118, 330, 611, 612, 548, 397, 28, 270, 150,
+ 151, 152, 203, 316, 153, 209, 119, 203, 576, 232,
+ 549, 577, -185, 378, 379, -185, 123, 380, 268, 632,
+ 633, 634, 381, 378, 379, 134, 580, 380, 51, 581,
+ 140, 141, 381, 616, 346, 417, 535, 536, 418, 419,
+ 420, 421, 422, 628, 133, 229, 630, 230, 469, 135,
+ 470, 20, 21, 356, 22, 299, 136, 471, 146, 596,
+ 366, 367, 368, 369, 370, 567, 568, 373, 147, 604,
+ 377, 606, 482, 410, 411, 412, 149, 156, 159, 160,
+ 164, 170, 178, 114, 317, 175, 190, 22, 168, 195,
+ 485, 112, 196, 197, 200, 113, 205, 33, 504, -145,
+ 234, 235, 595, 236, 238, 245, 237, 246, 335, 249,
+ 252, 275, 338, 290, 276, 131, 294, 340, 293, 277,
+ 278, 328, 281, 35, 36, 37, 38, 39, 40, 41,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 506,
+ 507, 52, 53, 282, 502, 54, 114, 283, 284, 285,
+ 304, 305, 337, 291, 112, 292, 325, 326, 113, 561,
+ 331, 334, 562, 329, 352, 353, 61, 28, 389, 362,
+ 299, 341, 342, 64, 394, 395, 485, 365, 374, 390,
+ 400, 392, 393, 403, 396, 405, 22, 413, 407, 408,
+ 414, 415, 438, 434, 440, 442, 443, 499, 509, 500,
+ 431, 533, 554, 503, 572, 537, 508, 512, 505, 514,
+ 518, 574, 599, 521, 131, 558, 584, 588, 433, -249,
+ 437, 546, 35, 36, 37, 38, 39, 40, 41, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 114, 607,
+ 52, 53, 545, 563, 54, 203, 550, 551, 564, 565,
+ 555, 578, 585, 587, 591, 559, 593, 444, 211, 609,
+ 603, 597, 598, 627, 513, 22, 617, 424, 516, 614,
+ 622, 623, 64, 626, 519, 520, 629, 522, 523, 524,
+ 525, 526, 527, 528, 529, 530, 531, 532, 575, 625,
+ 631, 635, 5, 131, 387, 398, 406, 207, 313, 110,
+ 583, 35, 36, 37, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 399, 240, 52,
+ 53, 573, 402, 544, 114, 552, 311, 0, 571, 0,
+ 319, 0, 425, 426, 0, 376, 605, 242, 0, 0,
+ 427, 428, 429, 430, 613, 0, 0, 0, 0, 0,
+ 0, 64, 213, 0, 214, 215, 624, 216, 217, 218,
+ 219, 220, 221, 222, 223, 224, 0, 225, 0, 226,
+ 227, 0, 0, 0, 0, 0, 114, 114, 570, 114,
+ 0, 0, 0, 0, 0, 0, 569, 0, 0, 0,
+ 0, 0, 0, 0, 589, 0, 0, 0, 0, 0,
+ 0, 6, 7, 8, 0, 9, 10, 11, 0, 0,
+ 0, 12, 13, 14, 15, 16, 590, 17, 18, 19,
+ 0, 20, 21, 22, 0, 0, 0, 0, 0, 608,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 618,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 0, 0, 0, 0, 0, 0, 0, 35,
+ 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 0, 51, 52, 53, 0,
+ 0, 54, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 55, 56, 57, 58, 59, 60, 0, 0,
+ 444, 0, 61, 0, 0, 62, 0, 0, 63, 64,
+ 65, 66, 445, 0, 0, 0, 0, 20, 21, 446,
+ 0, 0, 0, 447, 448, 449, 450, 451, 452, 453,
+ 454, 455, 0, 0, 456, 457, 0, 0, 0, 0,
+ 0, 28, 0, 0, 0, 0, 33, 34, 458, 459,
+ 460, 461, 462, 0, 463, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 464, 51, 52, 53, 0, 0, 54, 465, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 55, 56,
+ 0, 0, 0, 0, 444, 0, 0, 0, 61, 0,
+ 0, 62, 0, 466, 0, 64, 445, 0, 0, 543,
+ 0, 20, 21, 446, 0, 0, 0, 447, 448, 449,
+ 450, 451, 452, 453, 454, 455, 0, 0, 456, 457,
+ 0, 0, 0, 0, 0, 28, 0, 0, 0, 0,
+ 33, 34, 458, 459, 460, 461, 462, 0, 463, 35,
+ 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 464, 51, 52, 53, 0,
+ 0, 54, 465, 0, 20, 21, 22, 0, 0, 0,
+ 0, 0, 55, 56, 0, 0, 0, 0, 0, 0,
+ 0, 0, 61, 0, 0, 62, 0, 466, 28, 64,
+ 0, 0, 0, 33, 34, 0, 0, 0, 0, 0,
+ 0, 0, 35, 36, 37, 38, 39, 40, 41, 42,
+ 43, 44, 45, 46, 47, 48, 49, 50, 0, 51,
+ 52, 53, 0, 0, 54, 20, 21, 22, 0, 0,
+ 0, 0, 0, 0, 0, 55, 56, 0, 0, 0,
+ 0, 0, 0, 0, 0, 61, 0, 0, 62, 28,
+ 0, 63, 64, 0, 33, 34, 363, 0, 0, 0,
+ 0, 0, 0, 35, 36, 37, 38, 39, 40, 41,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 22,
+ 51, 52, 53, 0, 0, 54, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 55, 56, 0, 0,
+ 0, 0, 0, 0, 0, 0, 61, 131, 0, 62,
+ 0, 0, 63, 64, 0, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 22, 0, 52, 53, 0, 0, 54, 0, 255,
+ 256, 257, 258, 259, 260, 261, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 131,
+ 262, 0, 0, 0, 0, 64, 0, 35, 36, 37,
+ 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 566, 22, 52, 53, 0, 0, 54,
+ 465, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 61, 0, 131, 0, 0, 0, 0, 64, 0, 0,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 566, 22, 52, 53,
+ 0, 0, 54, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 61, 0, 131, 0, 0, 0, 0,
+ 64, 0, 0, 35, 36, 37, 38, 39, 40, 41,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 0,
+ 0, 52, 53, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 64
+};
+
+static const yytype_int16 yycheck[] =
+{
+ 10, 3, 12, 13, 14, 15, 16, 17, 18, 3,
+ 33, 34, 211, 3, 19, 337, 26, 27, 28, 133,
+ 169, 171, 388, 436, 32, 294, 304, 25, 304, 25,
+ 365, 400, 132, 25, 25, 154, 25, 25, 512, 62,
+ 294, 25, 245, 25, 403, 25, 559, 81, 148, 54,
+ 400, 400, 400, 55, 81, 81, 121, 65, 66, 61,
+ 125, 400, 0, 81, 423, 334, 122, 121, 611, 612,
+ 583, 393, 172, 129, 193, 441, 130, 121, 347, 87,
+ 39, 40, 360, 117, 360, 22, 130, 24, 47, 81,
+ 633, 118, 192, 347, 293, 129, 25, 26, 27, 117,
+ 613, 25, 202, 129, 517, 308, 117, 581, 131, 209,
+ 122, 117, 104, 104, 125, 27, 122, 486, 130, 78,
+ 104, 119, 400, 237, 400, 84, 325, 326, 124, 117,
+ 119, 400, 124, 115, 126, 115, 486, 486, 486, 239,
+ 240, 255, 256, 257, 258, 259, 400, 486, 262, 39,
+ 40, 25, 266, 602, 603, 118, 115, 47, 121, 62,
+ 63, 64, 164, 92, 67, 170, 22, 169, 118, 179,
+ 505, 121, 118, 119, 120, 121, 26, 123, 201, 628,
+ 629, 630, 128, 119, 120, 26, 118, 123, 78, 121,
+ 25, 26, 128, 606, 84, 120, 459, 460, 123, 124,
+ 125, 126, 127, 623, 117, 124, 626, 126, 486, 26,
+ 486, 23, 24, 25, 25, 238, 26, 486, 64, 585,
+ 320, 321, 322, 323, 324, 538, 539, 327, 25, 595,
+ 330, 597, 486, 366, 367, 368, 67, 25, 25, 125,
+ 129, 21, 26, 245, 252, 92, 64, 25, 81, 114,
+ 400, 245, 114, 25, 117, 245, 92, 52, 407, 120,
+ 25, 82, 584, 118, 131, 114, 120, 25, 270, 25,
+ 122, 116, 10, 133, 118, 53, 114, 279, 117, 122,
+ 122, 118, 122, 61, 62, 63, 64, 65, 66, 67,
+ 68, 69, 70, 71, 72, 73, 74, 75, 76, 413,
+ 414, 79, 80, 122, 404, 83, 308, 122, 122, 122,
+ 114, 116, 118, 122, 308, 122, 117, 117, 308, 518,
+ 122, 114, 521, 121, 25, 121, 104, 47, 338, 118,
+ 353, 122, 122, 111, 344, 345, 486, 131, 83, 11,
+ 114, 118, 118, 122, 346, 115, 25, 118, 117, 116,
+ 118, 105, 12, 108, 116, 25, 116, 116, 122, 116,
+ 383, 59, 92, 116, 25, 131, 117, 117, 120, 115,
+ 117, 25, 38, 117, 53, 116, 118, 116, 383, 128,
+ 390, 121, 61, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, 71, 72, 73, 74, 75, 76, 400, 598,
+ 79, 80, 128, 131, 83, 407, 506, 507, 131, 131,
+ 510, 132, 118, 117, 116, 515, 116, 6, 117, 28,
+ 116, 118, 117, 622, 434, 25, 118, 27, 438, 132,
+ 117, 116, 111, 116, 444, 445, 116, 447, 448, 449,
+ 450, 451, 452, 453, 454, 455, 456, 457, 548, 133,
+ 118, 133, 1, 53, 336, 347, 360, 168, 250, 3,
+ 560, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+ 70, 71, 72, 73, 74, 75, 76, 353, 188, 79,
+ 80, 542, 355, 486, 486, 508, 247, -1, 541, -1,
+ 253, -1, 92, 93, -1, 329, 596, 191, -1, -1,
+ 100, 101, 102, 103, 604, -1, -1, -1, -1, -1,
+ -1, 111, 117, -1, 119, 120, 616, 122, 123, 124,
+ 125, 126, 127, 128, 129, 130, -1, 132, -1, 134,
+ 135, -1, -1, -1, -1, -1, 538, 539, 540, 541,
+ -1, -1, -1, -1, -1, -1, 540, -1, -1, -1,
+ -1, -1, -1, -1, 577, -1, -1, -1, -1, -1,
+ -1, 3, 4, 5, -1, 7, 8, 9, -1, -1,
+ -1, 13, 14, 15, 16, 17, 578, 19, 20, 21,
+ -1, 23, 24, 25, -1, -1, -1, -1, -1, 599,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 609,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, -1, -1, -1, -1, -1, -1, -1, 61,
+ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, -1, 78, 79, 80, -1,
+ -1, 83, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 94, 95, 96, 97, 98, 99, -1, -1,
+ 6, -1, 104, -1, -1, 107, -1, -1, 110, 111,
+ 112, 113, 18, -1, -1, -1, -1, 23, 24, 25,
+ -1, -1, -1, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, -1, -1, 40, 41, -1, -1, -1, -1,
+ -1, 47, -1, -1, -1, -1, 52, 53, 54, 55,
+ 56, 57, 58, -1, 60, 61, 62, 63, 64, 65,
+ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
+ 76, 77, 78, 79, 80, -1, -1, 83, 84, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 94, 95,
+ -1, -1, -1, -1, 6, -1, -1, -1, 104, -1,
+ -1, 107, -1, 109, -1, 111, 18, -1, -1, 115,
+ -1, 23, 24, 25, -1, -1, -1, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, -1, -1, 40, 41,
+ -1, -1, -1, -1, -1, 47, -1, -1, -1, -1,
+ 52, 53, 54, 55, 56, 57, 58, -1, 60, 61,
+ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, 79, 80, -1,
+ -1, 83, 84, -1, 23, 24, 25, -1, -1, -1,
+ -1, -1, 94, 95, -1, -1, -1, -1, -1, -1,
+ -1, -1, 104, -1, -1, 107, -1, 109, 47, 111,
+ -1, -1, -1, 52, 53, -1, -1, -1, -1, -1,
+ -1, -1, 61, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, 71, 72, 73, 74, 75, 76, -1, 78,
+ 79, 80, -1, -1, 83, 23, 24, 25, -1, -1,
+ -1, -1, -1, -1, -1, 94, 95, -1, -1, -1,
+ -1, -1, -1, -1, -1, 104, -1, -1, 107, 47,
+ -1, 110, 111, -1, 52, 53, 115, -1, -1, -1,
+ -1, -1, -1, 61, 62, 63, 64, 65, 66, 67,
+ 68, 69, 70, 71, 72, 73, 74, 75, 76, 25,
+ 78, 79, 80, -1, -1, 83, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 94, 95, -1, -1,
+ -1, -1, -1, -1, -1, -1, 104, 53, -1, 107,
+ -1, -1, 110, 111, -1, 61, 62, 63, 64, 65,
+ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
+ 76, 25, -1, 79, 80, -1, -1, 83, -1, 85,
+ 86, 87, 88, 89, 90, 91, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 53,
+ 106, -1, -1, -1, -1, 111, -1, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
+ 74, 75, 76, 77, 25, 79, 80, -1, -1, 83,
+ 84, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 104, -1, 53, -1, -1, -1, -1, 111, -1, -1,
+ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+ 71, 72, 73, 74, 75, 76, 77, 25, 79, 80,
+ -1, -1, 83, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 104, -1, 53, -1, -1, -1, -1,
+ 111, -1, -1, 61, 62, 63, 64, 65, 66, 67,
+ 68, 69, 70, 71, 72, 73, 74, 75, 76, -1,
+ -1, 79, 80, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 111
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const yytype_uint16 yystos[] =
+{
+ 0, 137, 138, 139, 0, 138, 3, 4, 5, 7,
+ 8, 9, 13, 14, 15, 16, 17, 19, 20, 21,
+ 23, 24, 25, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 61, 62, 63, 64, 65,
+ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
+ 76, 78, 79, 80, 83, 94, 95, 96, 97, 98,
+ 99, 104, 107, 110, 111, 112, 113, 140, 141, 142,
+ 143, 144, 145, 148, 150, 156, 159, 163, 164, 168,
+ 171, 172, 173, 174, 175, 176, 177, 178, 181, 182,
+ 183, 187, 188, 189, 190, 201, 203, 204, 205, 206,
+ 207, 208, 209, 210, 213, 227, 228, 231, 232, 235,
+ 237, 238, 255, 278, 279, 283, 25, 27, 25, 22,
+ 211, 212, 211, 26, 211, 211, 211, 211, 211, 211,
+ 211, 53, 283, 117, 26, 26, 26, 211, 211, 211,
+ 25, 26, 179, 179, 227, 227, 64, 25, 216, 67,
+ 62, 63, 64, 67, 283, 279, 25, 165, 160, 25,
+ 125, 259, 279, 227, 129, 179, 179, 179, 81, 129,
+ 21, 236, 25, 104, 282, 92, 22, 24, 26, 215,
+ 227, 259, 25, 119, 169, 170, 216, 239, 233, 259,
+ 64, 282, 25, 117, 157, 114, 114, 25, 260, 261,
+ 117, 117, 146, 279, 284, 92, 180, 228, 284, 283,
+ 238, 117, 259, 117, 119, 120, 122, 123, 124, 125,
+ 126, 127, 128, 129, 130, 132, 134, 135, 256, 124,
+ 126, 281, 211, 149, 25, 82, 118, 120, 131, 241,
+ 241, 214, 281, 259, 282, 114, 25, 166, 167, 25,
+ 161, 162, 122, 121, 125, 85, 86, 87, 88, 89,
+ 90, 91, 106, 267, 268, 269, 279, 280, 227, 259,
+ 121, 130, 130, 259, 267, 116, 118, 122, 122, 117,
+ 122, 122, 122, 122, 122, 122, 122, 129, 122, 130,
+ 133, 122, 122, 117, 114, 152, 25, 119, 216, 227,
+ 242, 243, 259, 259, 114, 116, 25, 141, 158, 237,
+ 115, 167, 115, 162, 25, 27, 92, 179, 262, 261,
+ 216, 216, 216, 216, 216, 117, 117, 216, 118, 121,
+ 216, 122, 222, 118, 114, 279, 151, 118, 10, 184,
+ 279, 122, 122, 267, 39, 40, 84, 153, 154, 155,
+ 190, 213, 25, 121, 240, 234, 25, 168, 171, 217,
+ 218, 219, 118, 115, 141, 131, 259, 259, 259, 259,
+ 259, 267, 267, 259, 83, 257, 269, 259, 119, 120,
+ 123, 128, 223, 225, 226, 190, 191, 152, 257, 211,
+ 11, 185, 118, 118, 211, 211, 279, 115, 154, 243,
+ 114, 244, 244, 122, 221, 115, 219, 117, 116, 180,
+ 222, 222, 222, 118, 118, 105, 285, 120, 123, 124,
+ 125, 126, 127, 224, 27, 92, 93, 100, 101, 102,
+ 103, 227, 229, 283, 108, 147, 285, 211, 12, 186,
+ 116, 257, 25, 116, 6, 18, 25, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 40, 41, 54, 55,
+ 56, 57, 58, 60, 77, 84, 109, 145, 156, 168,
+ 171, 190, 192, 193, 194, 195, 196, 197, 198, 199,
+ 200, 202, 213, 231, 232, 238, 245, 246, 248, 249,
+ 251, 254, 255, 263, 270, 273, 275, 276, 278, 116,
+ 116, 226, 259, 116, 284, 120, 216, 216, 117, 122,
+ 258, 226, 117, 211, 115, 258, 211, 285, 117, 211,
+ 211, 117, 211, 211, 211, 211, 211, 211, 211, 211,
+ 211, 211, 211, 59, 247, 247, 247, 131, 271, 272,
+ 277, 274, 250, 115, 246, 128, 121, 220, 118, 180,
+ 259, 259, 227, 286, 92, 259, 223, 230, 116, 259,
+ 258, 267, 267, 131, 131, 131, 77, 273, 273, 255,
+ 279, 275, 25, 251, 25, 259, 118, 121, 132, 253,
+ 118, 121, 253, 259, 118, 118, 25, 117, 116, 227,
+ 279, 116, 223, 116, 253, 257, 285, 118, 117, 38,
+ 265, 263, 264, 116, 285, 259, 285, 267, 211, 28,
+ 266, 265, 265, 259, 132, 252, 258, 118, 211, 266,
+ 266, 253, 117, 116, 259, 133, 116, 267, 264, 116,
+ 264, 118, 265, 265, 265, 133, 266
+};
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+
+#define YYFAIL goto yyerrlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
+ YYPOPSTACK (1); \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (YYID (0))
+
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (YYID (N)) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+ while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+#endif
+{
+ if (!yyvaluep)
+ return;
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+ YYUSE (yyoutput);
+# endif
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+#endif
+{
+ if (yytype < YYNTOKENS)
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+ YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+#else
+static void
+yy_stack_print (yybottom, yytop)
+ yytype_int16 *yybottom;
+ yytype_int16 *yytop;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; yybottom <= yytop; yybottom++)
+ {
+ int yybot = *yybottom;
+ YYFPRINTF (stderr, " %d", yybot);
+ }
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
+#else
+static void
+yy_reduce_print (yyvsp, yyrule)
+ YYSTYPE *yyvsp;
+ int yyrule;
+#endif
+{
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ unsigned long int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ YYFPRINTF (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ );
+ YYFPRINTF (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyvsp, Rule); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined __GLIBC__ && defined _STRING_H
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+ const char *yystr;
+#endif
+{
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
+ continue;
+ return yylen;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+#endif
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ YYSIZE_T yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into YYRESULT an error message about the unexpected token
+ YYCHAR while in state YYSTATE. Return the number of bytes copied,
+ including the terminating null byte. If YYRESULT is null, do not
+ copy anything; just return the number of bytes that would be
+ copied. As a special case, return 0 if an ordinary "syntax error"
+ message will do. Return YYSIZE_MAXIMUM if overflow occurs during
+ size calculation. */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
+{
+ int yyn = yypact[yystate];
+
+ if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+ return 0;
+ else
+ {
+ int yytype = YYTRANSLATE (yychar);
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ int yysize_overflow = 0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ int yyx;
+
+# if 0
+ /* This is so xgettext sees the translatable formats that are
+ constructed on the fly. */
+ YY_("syntax error, unexpected %s");
+ YY_("syntax error, unexpected %s, expecting %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+ char *yyfmt;
+ char const *yyf;
+ static char const yyunexpected[] = "syntax error, unexpected %s";
+ static char const yyexpecting[] = ", expecting %s";
+ static char const yyor[] = " or %s";
+ char yyformat[sizeof yyunexpected
+ + sizeof yyexpecting - 1
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+ * (sizeof yyor - 1))];
+ char const *yyprefix = yyexpecting;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 1;
+
+ yyarg[0] = yytname[yytype];
+ yyfmt = yystpcpy (yyformat, yyunexpected);
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ yyformat[sizeof yyunexpected - 1] = '\0';
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+ yyfmt = yystpcpy (yyfmt, yyprefix);
+ yyprefix = yyor;
+ }
+
+ yyf = YY_(yyformat);
+ yysize1 = yysize + yystrlen (yyf);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+
+ if (yysize_overflow)
+ return YYSIZE_MAXIMUM;
+
+ if (yyresult)
+ {
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ char *yyp = yyresult;
+ int yyi = 0;
+ while ((*yyp = *yyf) != '\0')
+ {
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyf += 2;
+ }
+ else
+ {
+ yyp++;
+ yyf++;
+ }
+ }
+ }
+ return yysize;
+ }
+}
+#endif /* YYERROR_VERBOSE */
+
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep)
+ const char *yymsg;
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ YYUSE (yyvaluep);
+
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ switch (yytype)
+ {
+
+ default:
+ break;
+ }
+}
+
+/* Prevent warnings from -Wmissing-prototypes. */
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+/* The lookahead symbol. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far. */
+int yynerrs;
+
+
+
+/*-------------------------.
+| yyparse or yypush_parse. |
+`-------------------------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+
+
+ int yystate;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+
+ /* The stacks and their tools:
+ `yyss': related to states.
+ `yyvs': related to semantic values.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs;
+ YYSTYPE *yyvsp;
+
+ YYSIZE_T yystacksize;
+
+ int yyn;
+ int yyresult;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken;
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ yytoken = 0;
+ yyss = yyssa;
+ yyvs = yyvsa;
+ yystacksize = YYINITDEPTH;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+ yyssp = yyss;
+ yyvsp = yyvs;
+
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ yytype_int16 *yyss1 = yyss;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyexhaustedlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yytype_int16 *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss_alloc, yyss);
+ YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+ /* Do appropriate processing given the current state. Read a
+ lookahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to lookahead token. */
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the lookahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the shifted token. */
+ yychar = YYEMPTY;
+
+ yystate = yyn;
+ *++yyvsp = yylval;
+
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 4:
+
+/* Line 1455 of yacc.c */
+#line 354 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ /*
+ * We don't do these in parserEOF() because the parser is reading
+ * ahead and that would be too early.
+ */
+
+ if (previousFile != NULL)
+ {
+ handleEOF();
+
+ if (currentContext.prevmod != NULL)
+ handleEOM();
+
+ free(previousFile);
+ previousFile = NULL;
+ }
+ }
+ break;
+
+ case 22:
+
+/* Line 1455 of yacc.c */
+#line 389 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ appendCodeBlock(&currentSpec->exphdrcode, (yyvsp[(1) - (1)].codeb));
+ }
+ break;
+
+ case 23:
+
+/* Line 1455 of yacc.c */
+#line 393 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ appendCodeBlock(&currentModule->hdrcode, (yyvsp[(1) - (1)].codeb));
+ }
+ break;
+
+ case 24:
+
+/* Line 1455 of yacc.c */
+#line 397 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ appendCodeBlock(&currentModule->cppcode, (yyvsp[(1) - (1)].codeb));
+ }
+ break;
+
+ case 47:
+
+/* Line 1455 of yacc.c */
+#line 425 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ if (scope == NULL)
+ yyerror("%TypeHeaderCode can only be used in a namespace, class or mapped type");
+
+ appendCodeBlock(&scope->iff->hdrcode, (yyvsp[(1) - (1)].codeb));
+ }
+ }
+ break;
+
+ case 48:
+
+/* Line 1455 of yacc.c */
+#line 438 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ if ((currentModule->encoding = convertEncoding((yyvsp[(2) - (2)].text))) == no_type)
+ yyerror("The value of %DefaultEncoding must be one of \"ASCII\", \"Latin-1\", \"UTF-8\" or \"None\"");
+ }
+ }
+ break;
+
+ case 49:
+
+/* Line 1455 of yacc.c */
+#line 447 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ appendString(&currentSpec->plugins, (yyvsp[(2) - (2)].text));
+ }
+ break;
+
+ case 50:
+
+/* Line 1455 of yacc.c */
+#line 452 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ apiVersionRangeDef *avd;
+
+ if (findAPI(currentSpec, (yyvsp[(2) - (3)].text)) != NULL)
+ yyerror("The API name in the %API directive has already been defined");
+
+ if ((yyvsp[(3) - (3)].number) < 1)
+ yyerror("The version number in the %API directive must be greater than or equal to 1");
+
+ avd = sipMalloc(sizeof (apiVersionRangeDef));
+
+ avd->api_name = cacheName(currentSpec, (yyvsp[(2) - (3)].text));
+ avd->from = (yyvsp[(3) - (3)].number);
+ avd->to = -1;
+
+ avd->next = currentModule->api_versions;
+ currentModule->api_versions = avd;
+
+ if (inMainModule())
+ setIsUsedName(avd->api_name);
+ }
+ }
+ break;
+
+ case 51:
+
+/* Line 1455 of yacc.c */
+#line 478 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ exceptionDef *xd;
+ const char *pyname;
+
+ if (currentSpec->genc)
+ yyerror("%Exception not allowed in a C module");
+
+ pyname = getPythonName(&(yyvsp[(4) - (9)].optflags), scopedNameTail((yyvsp[(2) - (9)].scpvalp)));
+
+ checkAttributes(currentSpec, currentModule, NULL, NULL,
+ pyname, FALSE);
+
+ xd = findException(currentSpec, (yyvsp[(2) - (9)].scpvalp), TRUE);
+
+ if (xd->cd != NULL)
+ yyerror("%Exception name has already been seen as a class name - it must be defined before being used");
+
+ if (xd->iff->module != NULL)
+ yyerror("The %Exception has already been defined");
+
+ /* Complete the definition. */
+ xd->iff->module = currentModule;
+ xd->iff->hdrcode = (yyvsp[(6) - (9)].codeb);
+ xd->pyname = pyname;
+ xd->bibase = (yyvsp[(3) - (9)].exceptionbase).bibase;
+ xd->base = (yyvsp[(3) - (9)].exceptionbase).base;
+ xd->raisecode = (yyvsp[(7) - (9)].codeb);
+
+ if (findOptFlag(&(yyvsp[(4) - (9)].optflags), "Default", bool_flag) != NULL)
+ currentModule->defexception = xd;
+
+ if (xd->bibase != NULL || xd->base != NULL)
+ xd->exceptionnr = currentModule->nrexceptions++;
+ }
+ }
+ break;
+
+ case 52:
+
+/* Line 1455 of yacc.c */
+#line 517 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.exceptionbase).bibase = NULL;
+ (yyval.exceptionbase).base = NULL;
+ }
+ break;
+
+ case 53:
+
+/* Line 1455 of yacc.c */
+#line 521 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ exceptionDef *xd;
+
+ (yyval.exceptionbase).bibase = NULL;
+ (yyval.exceptionbase).base = NULL;
+
+ /* See if it is a defined exception. */
+ for (xd = currentSpec->exceptions; xd != NULL; xd = xd->next)
+ if (compareScopedNames(xd->iff->fqcname, (yyvsp[(2) - (3)].scpvalp)) == 0)
+ {
+ (yyval.exceptionbase).base = xd;
+ break;
+ }
+
+ if (xd == NULL && (yyvsp[(2) - (3)].scpvalp)->next == NULL && strncmp((yyvsp[(2) - (3)].scpvalp)->name, "SIP_", 4) == 0)
+ {
+ /* See if it is a builtin exception. */
+
+ static char *builtins[] = {
+ "Exception",
+ "StopIteration",
+ "StandardError",
+ "ArithmeticError",
+ "LookupError",
+ "AssertionError",
+ "AttributeError",
+ "EOFError",
+ "FloatingPointError",
+ "EnvironmentError",
+ "IOError",
+ "OSError",
+ "ImportError",
+ "IndexError",
+ "KeyError",
+ "KeyboardInterrupt",
+ "MemoryError",
+ "NameError",
+ "OverflowError",
+ "RuntimeError",
+ "NotImplementedError",
+ "SyntaxError",
+ "IndentationError",
+ "TabError",
+ "ReferenceError",
+ "SystemError",
+ "SystemExit",
+ "TypeError",
+ "UnboundLocalError",
+ "UnicodeError",
+ "UnicodeEncodeError",
+ "UnicodeDecodeError",
+ "UnicodeTranslateError",
+ "ValueError",
+ "ZeroDivisionError",
+ "WindowsError",
+ "VMSError",
+ NULL
+ };
+
+ char **cp;
+
+ for (cp = builtins; *cp != NULL; ++cp)
+ if (strcmp((yyvsp[(2) - (3)].scpvalp)->name + 4, *cp) == 0)
+ {
+ (yyval.exceptionbase).bibase = *cp;
+ break;
+ }
+ }
+
+ if ((yyval.exceptionbase).bibase == NULL && (yyval.exceptionbase).base == NULL)
+ yyerror("Unknown exception base type");
+ }
+ break;
+
+ case 54:
+
+/* Line 1455 of yacc.c */
+#line 595 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = (yyvsp[(2) - (2)].codeb);
+ }
+ break;
+
+ case 55:
+
+/* Line 1455 of yacc.c */
+#line 600 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ currentMappedType = newMappedType(currentSpec, &(yyvsp[(2) - (3)].memArg), &(yyvsp[(3) - (3)].optflags));
+ }
+ break;
+
+ case 57:
+
+/* Line 1455 of yacc.c */
+#line 606 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ int a;
+
+ if (currentSpec->genc)
+ yyerror("%MappedType templates not allowed in a C module");
+
+ /* Check the template arguments are basic types or simple names. */
+ for (a = 0; a < (yyvsp[(1) - (4)].signature).nrArgs; ++a)
+ {
+ argDef *ad = &(yyvsp[(1) - (4)].signature).args[a];
+
+ if (ad->atype == defined_type && ad->u.snd->next != NULL)
+ yyerror("%MappedType template arguments must be simple names");
+ }
+
+ if ((yyvsp[(3) - (4)].memArg).atype != template_type)
+ yyerror("%MappedType template must map a template type");
+
+ if (notSkipping())
+ {
+ mappedTypeTmplDef *mtt;
+ ifaceFileDef *iff;
+
+ /* Check a template hasn't already been provided. */
+ for (mtt = currentSpec->mappedtypetemplates; mtt != NULL; mtt = mtt->next)
+ if (compareScopedNames(mtt->mt->type.u.td->fqname, (yyvsp[(3) - (4)].memArg).u.td->fqname) == 0 && sameTemplateSignature(&mtt->mt->type.u.td->types, &(yyvsp[(3) - (4)].memArg).u.td->types, TRUE))
+ yyerror("%MappedType template for this type has already been defined");
+
+ (yyvsp[(3) - (4)].memArg).nrderefs = 0;
+ (yyvsp[(3) - (4)].memArg).argflags = 0;
+
+ mtt = sipMalloc(sizeof (mappedTypeTmplDef));
+
+ mtt->sig = (yyvsp[(1) - (4)].signature);
+ mtt->mt = allocMappedType(currentSpec, &(yyvsp[(3) - (4)].memArg));
+ mtt->mt->doctype = getDocType(&(yyvsp[(4) - (4)].optflags));
+ mtt->next = currentSpec->mappedtypetemplates;
+
+ currentSpec->mappedtypetemplates = mtt;
+
+ currentMappedType = mtt->mt;
+
+ /* Create a dummy interface file. */
+ iff = sipMalloc(sizeof (ifaceFileDef));
+ iff->hdrcode = NULL;
+ mtt->mt->iff = iff;
+ }
+ }
+ break;
+
+ case 59:
+
+/* Line 1455 of yacc.c */
+#line 656 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ if (currentMappedType->convfromcode == NULL)
+ yyerror("%MappedType must have a %ConvertFromTypeCode directive");
+
+ if (currentMappedType->convtocode == NULL)
+ yyerror("%MappedType must have a %ConvertToTypeCode directive");
+
+ currentMappedType = NULL;
+ }
+ }
+ break;
+
+ case 62:
+
+/* Line 1455 of yacc.c */
+#line 674 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ appendCodeBlock(&currentMappedType->iff->hdrcode, (yyvsp[(1) - (1)].codeb));
+ }
+ break;
+
+ case 63:
+
+/* Line 1455 of yacc.c */
+#line 678 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ if (currentMappedType -> convfromcode != NULL)
+ yyerror("%MappedType has more than one %ConvertFromTypeCode directive");
+
+ currentMappedType -> convfromcode = (yyvsp[(2) - (2)].codeb);
+ }
+ }
+ break;
+
+ case 64:
+
+/* Line 1455 of yacc.c */
+#line 687 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ if (currentMappedType -> convtocode != NULL)
+ yyerror("%MappedType has more than one %ConvertToTypeCode directive");
+
+ currentMappedType -> convtocode = (yyvsp[(2) - (2)].codeb);
+ }
+ }
+ break;
+
+ case 67:
+
+/* Line 1455 of yacc.c */
+#line 700 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ applyTypeFlags(currentModule, &(yyvsp[(2) - (13)].memArg), &(yyvsp[(9) - (13)].optflags));
+
+ (yyvsp[(5) - (13)].signature).result = (yyvsp[(2) - (13)].memArg);
+
+ newFunction(currentSpec, currentModule, NULL,
+ currentMappedType, 0, TRUE, FALSE, FALSE, FALSE, (yyvsp[(3) - (13)].text),
+ &(yyvsp[(5) - (13)].signature), (yyvsp[(7) - (13)].number), FALSE, &(yyvsp[(9) - (13)].optflags), (yyvsp[(13) - (13)].codeb), NULL, (yyvsp[(8) - (13)].throwlist), (yyvsp[(10) - (13)].optsignature), (yyvsp[(12) - (13)].codeb));
+ }
+ }
+ break;
+
+ case 68:
+
+/* Line 1455 of yacc.c */
+#line 714 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (currentSpec -> genc)
+ yyerror("namespace definition not allowed in a C module");
+
+ if (notSkipping())
+ {
+ classDef *ns, *c_scope;
+ ifaceFileDef *scope;
+
+ if ((c_scope = currentScope()) != NULL)
+ scope = c_scope->iff;
+ else
+ scope = NULL;
+
+ ns = newClass(currentSpec, namespace_iface, NULL,
+ text2scopedName(scope, (yyvsp[(2) - (2)].text)));
+
+ pushScope(ns);
+
+ sectionFlags = 0;
+ }
+ }
+ break;
+
+ case 69:
+
+/* Line 1455 of yacc.c */
+#line 735 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ if (inMainModule())
+ {
+ classDef *ns = currentScope();
+
+ setIsUsedName(ns->iff->name);
+ setIsUsedName(ns->pyname);
+ }
+
+ popScope();
+ }
+ }
+ break;
+
+ case 72:
+
+/* Line 1455 of yacc.c */
+#line 755 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ qualDef *qd;
+
+ for (qd = currentModule -> qualifiers; qd != NULL; qd = qd -> next)
+ if (qd -> qtype == platform_qualifier)
+ yyerror("%Platforms has already been defined for this module");
+ }
+ break;
+
+ case 73:
+
+/* Line 1455 of yacc.c */
+#line 762 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ qualDef *qd;
+ int nrneeded;
+
+ /*
+ * Check that exactly one platform in the set was
+ * requested.
+ */
+
+ nrneeded = 0;
+
+ for (qd = currentModule -> qualifiers; qd != NULL; qd = qd -> next)
+ if (qd -> qtype == platform_qualifier && isNeeded(qd))
+ ++nrneeded;
+
+ if (nrneeded > 1)
+ yyerror("No more than one of these %Platforms must be specified with the -t flag");
+ }
+ break;
+
+ case 76:
+
+/* Line 1455 of yacc.c */
+#line 786 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ newQualifier(currentModule,-1,-1,(yyvsp[(1) - (1)].text),platform_qualifier);
+ }
+ break;
+
+ case 77:
+
+/* Line 1455 of yacc.c */
+#line 791 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ newQualifier(currentModule,-1,-1,(yyvsp[(2) - (2)].text),feature_qualifier);
+ }
+ break;
+
+ case 78:
+
+/* Line 1455 of yacc.c */
+#line 796 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ currentTimelineOrder = 0;
+ }
+ break;
+
+ case 79:
+
+/* Line 1455 of yacc.c */
+#line 799 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ qualDef *qd;
+ int nrneeded;
+
+ /*
+ * Check that exactly one time slot in the set was
+ * requested.
+ */
+
+ nrneeded = 0;
+
+ for (qd = currentModule -> qualifiers; qd != NULL; qd = qd -> next)
+ if (qd -> qtype == time_qualifier && isNeeded(qd))
+ ++nrneeded;
+
+ if (nrneeded > 1)
+ yyerror("At most one of this %Timeline must be specified with the -t flag");
+
+ currentModule -> nrtimelines++;
+ }
+ break;
+
+ case 82:
+
+/* Line 1455 of yacc.c */
+#line 825 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ newQualifier(currentModule,currentModule -> nrtimelines,currentTimelineOrder++,(yyvsp[(1) - (1)].text),time_qualifier);
+ }
+ break;
+
+ case 83:
+
+/* Line 1455 of yacc.c */
+#line 830 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (skipStackPtr >= MAX_NESTED_IF)
+ yyerror("Internal error: increase the value of MAX_NESTED_IF");
+
+ /* Nested %Ifs are implicit logical ands. */
+
+ if (skipStackPtr > 0)
+ (yyvsp[(3) - (4)].boolean) = ((yyvsp[(3) - (4)].boolean) && skipStack[skipStackPtr - 1]);
+
+ skipStack[skipStackPtr++] = (yyvsp[(3) - (4)].boolean);
+ }
+ break;
+
+ case 84:
+
+/* Line 1455 of yacc.c */
+#line 843 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.boolean) = platOrFeature((yyvsp[(1) - (1)].text),FALSE);
+ }
+ break;
+
+ case 85:
+
+/* Line 1455 of yacc.c */
+#line 846 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.boolean) = platOrFeature((yyvsp[(2) - (2)].text),TRUE);
+ }
+ break;
+
+ case 86:
+
+/* Line 1455 of yacc.c */
+#line 849 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.boolean) = (platOrFeature((yyvsp[(3) - (3)].text),FALSE) || (yyvsp[(1) - (3)].boolean));
+ }
+ break;
+
+ case 87:
+
+/* Line 1455 of yacc.c */
+#line 852 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.boolean) = (platOrFeature((yyvsp[(4) - (4)].text),TRUE) || (yyvsp[(1) - (4)].boolean));
+ }
+ break;
+
+ case 89:
+
+/* Line 1455 of yacc.c */
+#line 858 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.boolean) = timePeriod((yyvsp[(1) - (3)].text),(yyvsp[(3) - (3)].text));
+ }
+ break;
+
+ case 90:
+
+/* Line 1455 of yacc.c */
+#line 863 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (skipStackPtr-- <= 0)
+ yyerror("Too many %End directives");
+ }
+ break;
+
+ case 91:
+
+/* Line 1455 of yacc.c */
+#line 869 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ optFlag *of;
+
+ if ((yyvsp[(2) - (2)].optflags).nrFlags == 0)
+ yyerror("%License details not specified");
+
+ if ((of = findOptFlag(&(yyvsp[(2) - (2)].optflags),"Type",string_flag)) == NULL)
+ yyerror("%License type not specified");
+
+ currentModule -> license = sipMalloc(sizeof (licenseDef));
+
+ currentModule -> license -> type = of -> fvalue.sval;
+
+ currentModule -> license -> licensee =
+ ((of = findOptFlag(&(yyvsp[(2) - (2)].optflags),"Licensee",string_flag)) != NULL)
+ ? of -> fvalue.sval : NULL;
+
+ currentModule -> license -> timestamp =
+ ((of = findOptFlag(&(yyvsp[(2) - (2)].optflags),"Timestamp",string_flag)) != NULL)
+ ? of -> fvalue.sval : NULL;
+
+ currentModule -> license -> sig =
+ ((of = findOptFlag(&(yyvsp[(2) - (2)].optflags),"Signature",string_flag)) != NULL)
+ ? of -> fvalue.sval : NULL;
+ }
+ break;
+
+ case 92:
+
+/* Line 1455 of yacc.c */
+#line 896 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ if (currentModule->defmetatype != NULL)
+ yyerror("%DefaultMetatype has already been defined for this module");
+
+ currentModule->defmetatype = cacheName(currentSpec, (yyvsp[(2) - (2)].text));
+ }
+ }
+ break;
+
+ case 93:
+
+/* Line 1455 of yacc.c */
+#line 907 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ if (currentModule->defsupertype != NULL)
+ yyerror("%DefaultSupertype has already been defined for this module");
+
+ currentModule->defsupertype = cacheName(currentSpec, (yyvsp[(2) - (2)].text));
+ }
+ }
+ break;
+
+ case 94:
+
+/* Line 1455 of yacc.c */
+#line 918 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ /* Make sure this is the first mention of a module. */
+ if (currentSpec->module != currentModule)
+ yyerror("A %ConsolidatedModule cannot be %Imported");
+
+ if (currentModule->fullname != NULL)
+ yyerror("%ConsolidatedModule must appear before any %Module or %CModule directive");
+
+ setModuleName(currentSpec, currentModule, (yyvsp[(2) - (2)].text));
+ setIsConsolidated(currentModule);
+ }
+ break;
+
+ case 95:
+
+/* Line 1455 of yacc.c */
+#line 931 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ /* Make sure this is the first mention of a module. */
+ if (currentSpec->module != currentModule)
+ yyerror("A %CompositeModule cannot be %Imported");
+
+ if (currentModule->fullname != NULL)
+ yyerror("%CompositeModule must appear before any %Module or %CModule directive");
+
+ setModuleName(currentSpec, currentModule, (yyvsp[(2) - (2)].text));
+ setIsComposite(currentModule);
+ }
+ break;
+
+ case 96:
+
+/* Line 1455 of yacc.c */
+#line 944 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ /* Check the module hasn't already been defined. */
+
+ moduleDef *mod;
+
+ for (mod = currentSpec->modules; mod != NULL; mod = mod->next)
+ if (mod->fullname != NULL && strcmp(mod->fullname->text, (yyvsp[(2) - (3)].text)) == 0)
+ yyerror("Module is already defined");
+
+ /*
+ * If we are in a container module then create a component module
+ * and make it current.
+ */
+ if (isContainer(currentModule) || currentModule->container != NULL)
+ {
+ mod = allocModule();
+
+ mod->file = currentContext.filename;
+ mod->container = (isContainer(currentModule) ? currentModule : currentModule->container);
+
+ currentModule = mod;
+ }
+
+ setModuleName(currentSpec, currentModule, (yyvsp[(2) - (3)].text));
+ currentModule->version = (yyvsp[(3) - (3)].number);
+
+ if (currentSpec->genc < 0)
+ currentSpec->genc = (yyvsp[(1) - (3)].boolean);
+ else if (currentSpec->genc != (yyvsp[(1) - (3)].boolean))
+ yyerror("Cannot mix C and C++ modules");
+ }
+ break;
+
+ case 97:
+
+/* Line 1455 of yacc.c */
+#line 977 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.boolean) = FALSE;
+ }
+ break;
+
+ case 98:
+
+/* Line 1455 of yacc.c */
+#line 980 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.boolean) = TRUE;
+ }
+ break;
+
+ case 100:
+
+/* Line 1455 of yacc.c */
+#line 986 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ /*
+ * The grammar design is a bit broken and this is the easiest way
+ * to allow periods in names.
+ */
+
+ char *cp;
+
+ for (cp = (yyvsp[(1) - (1)].text); *cp != '\0'; ++cp)
+ if (*cp != '.' && *cp != '_' && !isalnum(*cp))
+ yyerror("Invalid character in name");
+
+ (yyval.text) = (yyvsp[(1) - (1)].text);
+ }
+ break;
+
+ case 101:
+
+/* Line 1455 of yacc.c */
+#line 1002 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.number) = -1;
+ }
+ break;
+
+ case 103:
+
+/* Line 1455 of yacc.c */
+#line 1008 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ parseFile(NULL, (yyvsp[(2) - (2)].text), NULL, FALSE);
+ }
+ break;
+
+ case 104:
+
+/* Line 1455 of yacc.c */
+#line 1013 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ parseFile(NULL, (yyvsp[(2) - (2)].text), NULL, TRUE);
+ }
+ break;
+
+ case 105:
+
+/* Line 1455 of yacc.c */
+#line 1018 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ newImport((yyvsp[(2) - (2)].text));
+ }
+ break;
+
+ case 106:
+
+/* Line 1455 of yacc.c */
+#line 1023 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = NULL;
+ }
+ break;
+
+ case 107:
+
+/* Line 1455 of yacc.c */
+#line 1026 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = (yyvsp[(2) - (2)].codeb);
+ }
+ break;
+
+ case 108:
+
+/* Line 1455 of yacc.c */
+#line 1031 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = NULL;
+ }
+ break;
+
+ case 109:
+
+/* Line 1455 of yacc.c */
+#line 1034 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = (yyvsp[(2) - (2)].codeb);
+ }
+ break;
+
+ case 110:
+
+/* Line 1455 of yacc.c */
+#line 1039 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = NULL;
+ }
+ break;
+
+ case 111:
+
+/* Line 1455 of yacc.c */
+#line 1042 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = (yyvsp[(2) - (2)].codeb);
+ }
+ break;
+
+ case 112:
+
+/* Line 1455 of yacc.c */
+#line 1047 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ appendCodeBlock(&currentModule->copying, (yyvsp[(2) - (2)].codeb));
+ }
+ break;
+
+ case 113:
+
+/* Line 1455 of yacc.c */
+#line 1052 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = (yyvsp[(2) - (2)].codeb);
+ }
+ break;
+
+ case 114:
+
+/* Line 1455 of yacc.c */
+#line 1057 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = (yyvsp[(2) - (2)].codeb);
+ }
+ break;
+
+ case 115:
+
+/* Line 1455 of yacc.c */
+#line 1062 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = (yyvsp[(2) - (2)].codeb);
+ }
+ break;
+
+ case 116:
+
+/* Line 1455 of yacc.c */
+#line 1067 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = NULL;
+ }
+ break;
+
+ case 118:
+
+/* Line 1455 of yacc.c */
+#line 1073 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = (yyvsp[(2) - (2)].codeb);
+ }
+ break;
+
+ case 119:
+
+/* Line 1455 of yacc.c */
+#line 1078 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = (yyvsp[(2) - (2)].codeb);
+ }
+ break;
+
+ case 120:
+
+/* Line 1455 of yacc.c */
+#line 1083 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = (yyvsp[(2) - (2)].codeb);
+ }
+ break;
+
+ case 121:
+
+/* Line 1455 of yacc.c */
+#line 1088 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = (yyvsp[(2) - (2)].codeb);
+ }
+ break;
+
+ case 122:
+
+/* Line 1455 of yacc.c */
+#line 1093 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = (yyvsp[(2) - (2)].codeb);
+ }
+ break;
+
+ case 123:
+
+/* Line 1455 of yacc.c */
+#line 1098 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = (yyvsp[(2) - (2)].codeb);
+ }
+ break;
+
+ case 124:
+
+/* Line 1455 of yacc.c */
+#line 1103 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = (yyvsp[(2) - (2)].codeb);
+ }
+ break;
+
+ case 125:
+
+/* Line 1455 of yacc.c */
+#line 1108 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = (yyvsp[(2) - (2)].codeb);
+ }
+ break;
+
+ case 126:
+
+/* Line 1455 of yacc.c */
+#line 1113 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = (yyvsp[(2) - (2)].codeb);
+ }
+ break;
+
+ case 127:
+
+/* Line 1455 of yacc.c */
+#line 1118 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = (yyvsp[(2) - (2)].codeb);
+ }
+ break;
+
+ case 128:
+
+/* Line 1455 of yacc.c */
+#line 1123 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = (yyvsp[(2) - (2)].codeb);
+ }
+ break;
+
+ case 129:
+
+/* Line 1455 of yacc.c */
+#line 1128 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ appendCodeBlock(&currentModule->preinitcode, (yyvsp[(2) - (2)].codeb));
+ }
+ break;
+
+ case 130:
+
+/* Line 1455 of yacc.c */
+#line 1134 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ appendCodeBlock(&currentModule->initcode, (yyvsp[(2) - (2)].codeb));
+ }
+ break;
+
+ case 131:
+
+/* Line 1455 of yacc.c */
+#line 1140 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ appendCodeBlock(&currentModule->postinitcode, (yyvsp[(2) - (2)].codeb));
+ }
+ break;
+
+ case 132:
+
+/* Line 1455 of yacc.c */
+#line 1146 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ appendCodeBlock(&currentModule->unitcode, (yyvsp[(2) - (2)].codeb));
+ }
+ break;
+
+ case 133:
+
+/* Line 1455 of yacc.c */
+#line 1152 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ /*
+ * This is a no-op and is retained for compatibility
+ * until the last use of it (by SIP v3) can be removed
+ * from PyQt.
+ */
+ }
+ break;
+
+ case 134:
+
+/* Line 1455 of yacc.c */
+#line 1161 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (inMainModule())
+ appendCodeBlock(&currentSpec -> docs,(yyvsp[(2) - (2)].codeb));
+ }
+ break;
+
+ case 135:
+
+/* Line 1455 of yacc.c */
+#line 1167 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ appendCodeBlock(&currentSpec -> docs,(yyvsp[(2) - (2)].codeb));
+ }
+ break;
+
+ case 136:
+
+/* Line 1455 of yacc.c */
+#line 1172 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (inMainModule())
+ yywarning("%Makefile is ignored, please use the -b flag instead");
+ }
+ break;
+
+ case 139:
+
+/* Line 1455 of yacc.c */
+#line 1182 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = (yyvsp[(1) - (2)].codeb);
+
+ append(&(yyval.codeb)->frag, (yyvsp[(2) - (2)].codeb)->frag);
+
+ free((yyvsp[(2) - (2)].codeb)->frag);
+ free((char *)(yyvsp[(2) - (2)].codeb)->filename);
+ free((yyvsp[(2) - (2)].codeb));
+ }
+ break;
+
+ case 140:
+
+/* Line 1455 of yacc.c */
+#line 1193 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ if (sectionFlags != 0 && (sectionFlags & ~(SECT_IS_PUBLIC | SECT_IS_PROT)) != 0)
+ yyerror("Class enums must be in the public or protected sections");
+
+ currentEnum = newEnum(currentSpec, currentModule,
+ currentMappedType, (yyvsp[(2) - (3)].text), &(yyvsp[(3) - (3)].optflags), sectionFlags);
+ }
+ }
+ break;
+
+ case 142:
+
+/* Line 1455 of yacc.c */
+#line 1205 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.text) = NULL;
+ }
+ break;
+
+ case 143:
+
+/* Line 1455 of yacc.c */
+#line 1208 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.text) = (yyvsp[(1) - (1)].text);
+ }
+ break;
+
+ case 144:
+
+/* Line 1455 of yacc.c */
+#line 1213 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.text) = NULL;
+ }
+ break;
+
+ case 145:
+
+/* Line 1455 of yacc.c */
+#line 1216 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.text) = (yyvsp[(1) - (1)].text);
+ }
+ break;
+
+ case 152:
+
+/* Line 1455 of yacc.c */
+#line 1231 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ enumMemberDef *emd, **tail;
+
+ /* Note that we don't use the assigned value. */
+ emd = sipMalloc(sizeof (enumMemberDef));
+
+ emd -> pyname = cacheName(currentSpec, getPythonName(&(yyvsp[(3) - (4)].optflags), (yyvsp[(1) - (4)].text)));
+ emd -> cname = (yyvsp[(1) - (4)].text);
+ emd -> ed = currentEnum;
+ emd -> next = NULL;
+
+ checkAttributes(currentSpec, currentModule, emd->ed->ecd,
+ emd->ed->emtd, emd->pyname->text, FALSE);
+
+ /* Append to preserve the order. */
+ for (tail = &currentEnum->members; *tail != NULL; tail = &(*tail)->next)
+ ;
+
+ *tail = emd;
+
+ if (inMainModule())
+ setIsUsedName(emd -> pyname);
+ }
+ }
+ break;
+
+ case 157:
+
+/* Line 1455 of yacc.c */
+#line 1267 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.valp) = NULL;
+ }
+ break;
+
+ case 158:
+
+/* Line 1455 of yacc.c */
+#line 1270 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.valp) = (yyvsp[(2) - (2)].valp);
+ }
+ break;
+
+ case 160:
+
+/* Line 1455 of yacc.c */
+#line 1276 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ valueDef *vd;
+
+ if ((yyvsp[(1) - (3)].valp) -> vtype == string_value || (yyvsp[(3) - (3)].valp) -> vtype == string_value)
+ yyerror("Invalid binary operator for string");
+
+ /* Find the last value in the existing expression. */
+
+ for (vd = (yyvsp[(1) - (3)].valp); vd -> next != NULL; vd = vd -> next)
+ ;
+
+ vd -> vbinop = (yyvsp[(2) - (3)].qchar);
+ vd -> next = (yyvsp[(3) - (3)].valp);
+
+ (yyval.valp) = (yyvsp[(1) - (3)].valp);
+ }
+ break;
+
+ case 161:
+
+/* Line 1455 of yacc.c */
+#line 1294 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.qchar) = '-';
+ }
+ break;
+
+ case 162:
+
+/* Line 1455 of yacc.c */
+#line 1297 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.qchar) = '+';
+ }
+ break;
+
+ case 163:
+
+/* Line 1455 of yacc.c */
+#line 1300 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.qchar) = '*';
+ }
+ break;
+
+ case 164:
+
+/* Line 1455 of yacc.c */
+#line 1303 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.qchar) = '/';
+ }
+ break;
+
+ case 165:
+
+/* Line 1455 of yacc.c */
+#line 1306 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.qchar) = '&';
+ }
+ break;
+
+ case 166:
+
+/* Line 1455 of yacc.c */
+#line 1309 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.qchar) = '|';
+ }
+ break;
+
+ case 167:
+
+/* Line 1455 of yacc.c */
+#line 1314 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.qchar) = '\0';
+ }
+ break;
+
+ case 168:
+
+/* Line 1455 of yacc.c */
+#line 1317 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.qchar) = '!';
+ }
+ break;
+
+ case 169:
+
+/* Line 1455 of yacc.c */
+#line 1320 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.qchar) = '~';
+ }
+ break;
+
+ case 170:
+
+/* Line 1455 of yacc.c */
+#line 1323 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.qchar) = '-';
+ }
+ break;
+
+ case 171:
+
+/* Line 1455 of yacc.c */
+#line 1326 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.qchar) = '+';
+ }
+ break;
+
+ case 172:
+
+/* Line 1455 of yacc.c */
+#line 1331 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if ((yyvsp[(1) - (2)].qchar) != '\0' && (yyvsp[(2) - (2)].value).vtype == string_value)
+ yyerror("Invalid unary operator for string");
+
+ /*
+ * Convert the value to a simple expression on the
+ * heap.
+ */
+
+ (yyval.valp) = sipMalloc(sizeof (valueDef));
+
+ *(yyval.valp) = (yyvsp[(2) - (2)].value);
+ (yyval.valp) -> vunop = (yyvsp[(1) - (2)].qchar);
+ (yyval.valp) -> vbinop = '\0';
+ (yyval.valp) -> next = NULL;
+ }
+ break;
+
+ case 174:
+
+/* Line 1455 of yacc.c */
+#line 1350 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (currentSpec -> genc)
+ yyerror("Scoped names are not allowed in a C module");
+
+ appendScopedName(&(yyvsp[(1) - (3)].scpvalp),(yyvsp[(3) - (3)].scpvalp));
+ }
+ break;
+
+ case 175:
+
+/* Line 1455 of yacc.c */
+#line 1358 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.scpvalp) = text2scopePart((yyvsp[(1) - (1)].text));
+ }
+ break;
+
+ case 176:
+
+/* Line 1455 of yacc.c */
+#line 1363 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ /*
+ * We let the C++ compiler decide if the value is a valid one - no
+ * point in building a full C++ parser here.
+ */
+
+ (yyval.value).vtype = scoped_value;
+ (yyval.value).u.vscp = (yyvsp[(1) - (1)].scpvalp);
+ }
+ break;
+
+ case 177:
+
+/* Line 1455 of yacc.c */
+#line 1372 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ fcallDef *fcd;
+
+ fcd = sipMalloc(sizeof (fcallDef));
+ *fcd = (yyvsp[(3) - (4)].fcall);
+ fcd -> type = (yyvsp[(1) - (4)].memArg);
+
+ (yyval.value).vtype = fcall_value;
+ (yyval.value).u.fcd = fcd;
+ }
+ break;
+
+ case 178:
+
+/* Line 1455 of yacc.c */
+#line 1382 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.value).vtype = real_value;
+ (yyval.value).u.vreal = (yyvsp[(1) - (1)].real);
+ }
+ break;
+
+ case 179:
+
+/* Line 1455 of yacc.c */
+#line 1386 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.value).vtype = numeric_value;
+ (yyval.value).u.vnum = (yyvsp[(1) - (1)].number);
+ }
+ break;
+
+ case 180:
+
+/* Line 1455 of yacc.c */
+#line 1390 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.value).vtype = numeric_value;
+ (yyval.value).u.vnum = 1;
+ }
+ break;
+
+ case 181:
+
+/* Line 1455 of yacc.c */
+#line 1394 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.value).vtype = numeric_value;
+ (yyval.value).u.vnum = 0;
+ }
+ break;
+
+ case 182:
+
+/* Line 1455 of yacc.c */
+#line 1398 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.value).vtype = numeric_value;
+ (yyval.value).u.vnum = 0;
+ }
+ break;
+
+ case 183:
+
+/* Line 1455 of yacc.c */
+#line 1402 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.value).vtype = string_value;
+ (yyval.value).u.vstr = (yyvsp[(1) - (1)].text);
+ }
+ break;
+
+ case 184:
+
+/* Line 1455 of yacc.c */
+#line 1406 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.value).vtype = qchar_value;
+ (yyval.value).u.vqchar = (yyvsp[(1) - (1)].qchar);
+ }
+ break;
+
+ case 185:
+
+/* Line 1455 of yacc.c */
+#line 1412 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ /* No values. */
+
+ (yyval.fcall).nrArgs = 0;
+ }
+ break;
+
+ case 186:
+
+/* Line 1455 of yacc.c */
+#line 1417 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ /* The single or first expression. */
+
+ (yyval.fcall).args[0] = (yyvsp[(1) - (1)].valp);
+ (yyval.fcall).nrArgs = 1;
+ }
+ break;
+
+ case 187:
+
+/* Line 1455 of yacc.c */
+#line 1423 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ /* Check that it wasn't ...(,expression...). */
+
+ if ((yyval.fcall).nrArgs == 0)
+ yyerror("First argument to function call is missing");
+
+ /* Check there is room. */
+
+ if ((yyvsp[(1) - (3)].fcall).nrArgs == MAX_NR_ARGS)
+ yyerror("Too many arguments to function call");
+
+ (yyval.fcall) = (yyvsp[(1) - (3)].fcall);
+
+ (yyval.fcall).args[(yyval.fcall).nrArgs] = (yyvsp[(3) - (3)].valp);
+ (yyval.fcall).nrArgs++;
+ }
+ break;
+
+ case 188:
+
+/* Line 1455 of yacc.c */
+#line 1441 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ applyTypeFlags(currentModule, &(yyvsp[(2) - (5)].memArg), &(yyvsp[(4) - (5)].optflags));
+ newTypedef(currentSpec, currentModule, (yyvsp[(3) - (5)].text), &(yyvsp[(2) - (5)].memArg), &(yyvsp[(4) - (5)].optflags));
+ }
+ }
+ break;
+
+ case 189:
+
+/* Line 1455 of yacc.c */
+#line 1448 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ signatureDef *sig;
+ argDef ftype;
+
+ applyTypeFlags(currentModule, &(yyvsp[(2) - (11)].memArg), &(yyvsp[(10) - (11)].optflags));
+
+ memset(&ftype, 0, sizeof (argDef));
+
+ /* Create the full signature on the heap. */
+ sig = sipMalloc(sizeof (signatureDef));
+ *sig = (yyvsp[(8) - (11)].signature);
+ sig->result = (yyvsp[(2) - (11)].memArg);
+
+ /* Create the full type. */
+ ftype.atype = function_type;
+ ftype.nrderefs = (yyvsp[(4) - (11)].number);
+ ftype.u.sa = sig;
+
+ newTypedef(currentSpec, currentModule, (yyvsp[(5) - (11)].text), &ftype, &(yyvsp[(10) - (11)].optflags));
+ }
+ }
+ break;
+
+ case 190:
+
+/* Line 1455 of yacc.c */
+#line 1473 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (currentSpec -> genc && (yyvsp[(2) - (2)].scpvalp)->next != NULL)
+ yyerror("Namespaces not allowed in a C module");
+
+ if (notSkipping())
+ currentSupers = NULL;
+ }
+ break;
+
+ case 191:
+
+/* Line 1455 of yacc.c */
+#line 1479 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ if (currentSpec->genc && currentSupers != NULL)
+ yyerror("Super-classes not allowed in a C module struct");
+
+ defineClass((yyvsp[(2) - (5)].scpvalp), currentSupers, &(yyvsp[(5) - (5)].optflags));
+ sectionFlags = SECT_IS_PUBLIC;
+ }
+ }
+ break;
+
+ case 192:
+
+/* Line 1455 of yacc.c */
+#line 1488 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ completeClass((yyvsp[(2) - (8)].scpvalp), &(yyvsp[(5) - (8)].optflags), (yyvsp[(7) - (8)].boolean));
+ }
+ break;
+
+ case 193:
+
+/* Line 1455 of yacc.c */
+#line 1494 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {currentIsTemplate = TRUE;}
+ break;
+
+ case 194:
+
+/* Line 1455 of yacc.c */
+#line 1494 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (currentSpec->genc)
+ yyerror("Class templates not allowed in a C module");
+
+ if (notSkipping())
+ {
+ classTmplDef *tcd;
+
+ /*
+ * Make sure there is room for the extra class name argument.
+ */
+ if ((yyvsp[(1) - (3)].signature).nrArgs == MAX_NR_ARGS)
+ yyerror("Internal error - increase the value of MAX_NR_ARGS");
+
+ tcd = sipMalloc(sizeof (classTmplDef));
+ tcd->sig = (yyvsp[(1) - (3)].signature);
+ tcd->cd = (yyvsp[(3) - (3)].klass);
+ tcd->next = currentSpec->classtemplates;
+
+ currentSpec->classtemplates = tcd;
+ }
+
+ currentIsTemplate = FALSE;
+ }
+ break;
+
+ case 195:
+
+/* Line 1455 of yacc.c */
+#line 1520 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.signature) = (yyvsp[(3) - (4)].signature);
+ }
+ break;
+
+ case 196:
+
+/* Line 1455 of yacc.c */
+#line 1525 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (currentSpec->genc)
+ yyerror("Class definition not allowed in a C module");
+
+ if (notSkipping())
+ currentSupers = NULL;
+ }
+ break;
+
+ case 197:
+
+/* Line 1455 of yacc.c */
+#line 1531 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ defineClass((yyvsp[(2) - (5)].scpvalp), currentSupers, &(yyvsp[(5) - (5)].optflags));
+ sectionFlags = SECT_IS_PRIVATE;
+ }
+ }
+ break;
+
+ case 198:
+
+/* Line 1455 of yacc.c */
+#line 1537 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ (yyval.klass) = completeClass((yyvsp[(2) - (8)].scpvalp), &(yyvsp[(5) - (8)].optflags), (yyvsp[(7) - (8)].boolean));
+ }
+ break;
+
+ case 203:
+
+/* Line 1455 of yacc.c */
+#line 1551 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ argDef ad;
+ classDef *super;
+ scopedNameDef *snd = (yyvsp[(1) - (1)].scpvalp);
+
+ /*
+ * This is a hack to allow typedef'ed classes to be used before
+ * we have resolved the typedef definitions. Unlike elsewhere,
+ * we require that the typedef is defined before being used.
+ */
+ for (;;)
+ {
+ ad.atype = no_type;
+ ad.argflags = 0;
+ ad.nrderefs = 0;
+ ad.original_type = NULL;
+
+ searchTypedefs(currentSpec, snd, &ad);
+
+ if (ad.atype != defined_type)
+ break;
+
+ if (ad.nrderefs != 0 || isConstArg(&ad) || isReference(&ad))
+ break;
+
+ snd = ad.u.snd;
+ }
+
+ if (ad.atype != no_type)
+ yyerror("Super-class list contains an invalid type");
+
+ super = findClass(currentSpec, class_iface, NULL, snd);
+ appendToClassList(&currentSupers, super);
+ }
+ }
+ break;
+
+ case 204:
+
+/* Line 1455 of yacc.c */
+#line 1590 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.boolean) = FALSE;
+ }
+ break;
+
+ case 205:
+
+/* Line 1455 of yacc.c */
+#line 1593 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.boolean) = TRUE;
+ }
+ break;
+
+ case 216:
+
+/* Line 1455 of yacc.c */
+#line 1610 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ /* Make sure this is before any ctor docstrings. */
+ (yyvsp[(1) - (1)].codeb)->next = scope->docstring;
+ scope->docstring = (yyvsp[(1) - (1)].codeb);
+ }
+ }
+ break;
+
+ case 217:
+
+/* Line 1455 of yacc.c */
+#line 1620 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ appendCodeBlock(&currentScope()->cppcode, (yyvsp[(1) - (1)].codeb));
+ }
+ break;
+
+ case 218:
+
+/* Line 1455 of yacc.c */
+#line 1624 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ appendCodeBlock(&currentScope()->iff->hdrcode, (yyvsp[(1) - (1)].codeb));
+ }
+ break;
+
+ case 219:
+
+/* Line 1455 of yacc.c */
+#line 1628 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ if (scope->travcode != NULL)
+ yyerror("%GCTraverseCode already given for class");
+
+ scope->travcode = (yyvsp[(1) - (1)].codeb);
+ }
+ }
+ break;
+
+ case 220:
+
+/* Line 1455 of yacc.c */
+#line 1639 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ if (scope->clearcode != NULL)
+ yyerror("%GCClearCode already given for class");
+
+ scope->clearcode = (yyvsp[(1) - (1)].codeb);
+ }
+ }
+ break;
+
+ case 221:
+
+/* Line 1455 of yacc.c */
+#line 1650 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ if (scope->getbufcode != NULL)
+ yyerror("%BIGetBufferCode already given for class");
+
+ scope->getbufcode = (yyvsp[(1) - (1)].codeb);
+ }
+ }
+ break;
+
+ case 222:
+
+/* Line 1455 of yacc.c */
+#line 1661 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ if (scope->releasebufcode != NULL)
+ yyerror("%BIReleaseBufferCode already given for class");
+
+ scope->releasebufcode = (yyvsp[(1) - (1)].codeb);
+ }
+ }
+ break;
+
+ case 223:
+
+/* Line 1455 of yacc.c */
+#line 1672 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ if (scope->readbufcode != NULL)
+ yyerror("%BIGetReadBufferCode already given for class");
+
+ scope->readbufcode = (yyvsp[(1) - (1)].codeb);
+ }
+ }
+ break;
+
+ case 224:
+
+/* Line 1455 of yacc.c */
+#line 1683 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ if (scope->writebufcode != NULL)
+ yyerror("%BIGetWriteBufferCode already given for class");
+
+ scope->writebufcode = (yyvsp[(1) - (1)].codeb);
+ }
+ }
+ break;
+
+ case 225:
+
+/* Line 1455 of yacc.c */
+#line 1694 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ if (scope->segcountcode != NULL)
+ yyerror("%BIGetSegCountCode already given for class");
+
+ scope->segcountcode = (yyvsp[(1) - (1)].codeb);
+ }
+ }
+ break;
+
+ case 226:
+
+/* Line 1455 of yacc.c */
+#line 1705 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ if (scope->charbufcode != NULL)
+ yyerror("%BIGetCharBufferCode already given for class");
+
+ scope->charbufcode = (yyvsp[(1) - (1)].codeb);
+ }
+ }
+ break;
+
+ case 227:
+
+/* Line 1455 of yacc.c */
+#line 1716 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ if (scope->picklecode != NULL)
+ yyerror("%PickleCode already given for class");
+
+ scope->picklecode = (yyvsp[(1) - (1)].codeb);
+ }
+ }
+ break;
+
+ case 231:
+
+/* Line 1455 of yacc.c */
+#line 1730 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ if (scope->convtosubcode != NULL)
+ yyerror("Class has more than one %ConvertToSubClassCode directive");
+
+ scope->convtosubcode = (yyvsp[(2) - (2)].codeb);
+ }
+ }
+ break;
+
+ case 232:
+
+/* Line 1455 of yacc.c */
+#line 1741 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ if (scope->convtocode != NULL)
+ yyerror("Class has more than one %ConvertToTypeCode directive");
+
+ scope->convtocode = (yyvsp[(2) - (2)].codeb);
+ }
+ }
+ break;
+
+ case 233:
+
+/* Line 1455 of yacc.c */
+#line 1752 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (currentSpec -> genc)
+ yyerror("public section not allowed in a C module");
+
+ if (notSkipping())
+ sectionFlags = SECT_IS_PUBLIC | (yyvsp[(2) - (3)].number);
+ }
+ break;
+
+ case 234:
+
+/* Line 1455 of yacc.c */
+#line 1759 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (currentSpec -> genc)
+ yyerror("protected section not allowed in a C module");
+
+ if (notSkipping())
+ sectionFlags = SECT_IS_PROT | (yyvsp[(2) - (3)].number);
+ }
+ break;
+
+ case 235:
+
+/* Line 1455 of yacc.c */
+#line 1766 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (currentSpec -> genc)
+ yyerror("private section not allowed in a C module");
+
+ if (notSkipping())
+ sectionFlags = SECT_IS_PRIVATE | (yyvsp[(2) - (3)].number);
+ }
+ break;
+
+ case 236:
+
+/* Line 1455 of yacc.c */
+#line 1773 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (currentSpec -> genc)
+ yyerror("signals section not allowed in a C module");
+
+ if (notSkipping())
+ sectionFlags = SECT_IS_SIGNAL;
+ }
+ break;
+
+ case 237:
+
+/* Line 1455 of yacc.c */
+#line 1782 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.number) = 0;
+ }
+ break;
+
+ case 238:
+
+/* Line 1455 of yacc.c */
+#line 1785 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.number) = SECT_IS_SLOT;
+ }
+ break;
+
+ case 239:
+
+/* Line 1455 of yacc.c */
+#line 1790 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ /* Note that we allow non-virtual dtors in C modules. */
+
+ if (notSkipping())
+ {
+ classDef *cd = currentScope();
+
+ if (strcmp(classBaseName(cd),(yyvsp[(3) - (11)].text)) != 0)
+ yyerror("Destructor doesn't have the same name as its class");
+
+ if (isDtor(cd))
+ yyerror("Destructor has already been defined");
+
+ if (currentSpec -> genc && (yyvsp[(10) - (11)].codeb) == NULL)
+ yyerror("Destructor in C modules must include %MethodCode");
+
+ cd -> dealloccode = (yyvsp[(10) - (11)].codeb);
+ cd -> dtorcode = (yyvsp[(11) - (11)].codeb);
+ cd -> dtorexceptions = (yyvsp[(6) - (11)].throwlist);
+
+ /*
+ * Note that we don't apply the protected/public hack to dtors
+ * as it (I think) may change the behaviour of the wrapped API.
+ */
+ cd->classflags |= sectionFlags;
+
+ if ((yyvsp[(7) - (11)].number))
+ {
+ if (!(yyvsp[(1) - (11)].number))
+ yyerror("Abstract destructor must be virtual");
+
+ setIsAbstractClass(cd);
+ }
+
+ /*
+ * The class has a shadow if we have a virtual dtor or some
+ * dtor code.
+ */
+ if ((yyvsp[(1) - (11)].number) || (yyvsp[(11) - (11)].codeb) != NULL)
+ {
+ if (currentSpec -> genc)
+ yyerror("Virtual destructor or %VirtualCatcherCode not allowed in a C module");
+
+ setHasShadow(cd);
+ }
+
+ if (getReleaseGIL(&(yyvsp[(8) - (11)].optflags)))
+ setIsReleaseGILDtor(cd);
+ else if (getHoldGIL(&(yyvsp[(8) - (11)].optflags)))
+ setIsHoldGILDtor(cd);
+ }
+ }
+ break;
+
+ case 240:
+
+/* Line 1455 of yacc.c */
+#line 1844 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {currentCtorIsExplicit = TRUE;}
+ break;
+
+ case 243:
+
+/* Line 1455 of yacc.c */
+#line 1848 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ /* Note that we allow ctors in C modules. */
+
+ if (notSkipping())
+ {
+ if (currentSpec -> genc)
+ {
+ if ((yyvsp[(10) - (10)].codeb) == NULL && (yyvsp[(3) - (10)].signature).nrArgs != 0)
+ yyerror("Constructors with arguments in C modules must include %MethodCode");
+
+ if (currentCtorIsExplicit)
+ yyerror("Explicit constructors not allowed in a C module");
+ }
+
+ if ((sectionFlags & (SECT_IS_PUBLIC | SECT_IS_PROT | SECT_IS_PRIVATE)) == 0)
+ yyerror("Constructor must be in the public, private or protected sections");
+
+ newCtor((yyvsp[(1) - (10)].text), sectionFlags, &(yyvsp[(3) - (10)].signature), &(yyvsp[(6) - (10)].optflags), (yyvsp[(10) - (10)].codeb), (yyvsp[(5) - (10)].throwlist), (yyvsp[(7) - (10)].optsignature),
+ currentCtorIsExplicit, (yyvsp[(9) - (10)].codeb));
+ }
+
+ free((yyvsp[(1) - (10)].text));
+
+ currentCtorIsExplicit = FALSE;
+ }
+ break;
+
+ case 244:
+
+/* Line 1455 of yacc.c */
+#line 1875 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.optsignature) = NULL;
+ }
+ break;
+
+ case 245:
+
+/* Line 1455 of yacc.c */
+#line 1878 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.optsignature) = sipMalloc(sizeof (signatureDef));
+
+ *(yyval.optsignature) = (yyvsp[(3) - (5)].signature);
+ }
+ break;
+
+ case 246:
+
+/* Line 1455 of yacc.c */
+#line 1885 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.optsignature) = NULL;
+ }
+ break;
+
+ case 247:
+
+/* Line 1455 of yacc.c */
+#line 1888 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.optsignature) = sipMalloc(sizeof (signatureDef));
+
+ *(yyval.optsignature) = (yyvsp[(4) - (6)].signature);
+ (yyval.optsignature) -> result = (yyvsp[(2) - (6)].memArg);
+ }
+ break;
+
+ case 248:
+
+/* Line 1455 of yacc.c */
+#line 1896 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.number) = FALSE;
+ }
+ break;
+
+ case 249:
+
+/* Line 1455 of yacc.c */
+#line 1899 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.number) = TRUE;
+ }
+ break;
+
+ case 250:
+
+/* Line 1455 of yacc.c */
+#line 1904 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ applyTypeFlags(currentModule, &(yyvsp[(1) - (14)].memArg), &(yyvsp[(9) - (14)].optflags));
+
+ (yyvsp[(4) - (14)].signature).result = (yyvsp[(1) - (14)].memArg);
+
+ newFunction(currentSpec, currentModule, currentScope(), NULL,
+ sectionFlags, currentIsStatic, currentIsSignal,
+ currentIsSlot, currentOverIsVirt, (yyvsp[(2) - (14)].text), &(yyvsp[(4) - (14)].signature), (yyvsp[(6) - (14)].number), (yyvsp[(8) - (14)].number), &(yyvsp[(9) - (14)].optflags),
+ (yyvsp[(13) - (14)].codeb), (yyvsp[(14) - (14)].codeb), (yyvsp[(7) - (14)].throwlist), (yyvsp[(10) - (14)].optsignature), (yyvsp[(12) - (14)].codeb));
+ }
+
+ currentIsStatic = FALSE;
+ currentIsSignal = FALSE;
+ currentIsSlot = FALSE;
+ currentOverIsVirt = FALSE;
+ }
+ break;
+
+ case 251:
+
+/* Line 1455 of yacc.c */
+#line 1922 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ /*
+ * It looks like an assignment operator (though we don't bother to
+ * check the types) so make sure it is private.
+ */
+ if (notSkipping())
+ {
+ classDef *cd = currentScope();
+
+ if (cd == NULL || !(sectionFlags & SECT_IS_PRIVATE))
+ yyerror("Assignment operators may only be defined as private");
+
+ setCannotAssign(cd);
+ }
+
+ currentIsStatic = FALSE;
+ currentIsSignal = FALSE;
+ currentIsSlot = FALSE;
+ currentOverIsVirt = FALSE;
+ }
+ break;
+
+ case 252:
+
+/* Line 1455 of yacc.c */
+#line 1942 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ classDef *cd = currentScope();
+
+ applyTypeFlags(currentModule, &(yyvsp[(1) - (14)].memArg), &(yyvsp[(10) - (14)].optflags));
+
+ /* Handle the unary '+' and '-' operators. */
+ if ((cd != NULL && (yyvsp[(5) - (14)].signature).nrArgs == 0) || (cd == NULL && (yyvsp[(5) - (14)].signature).nrArgs == 1))
+ {
+ if (strcmp((yyvsp[(3) - (14)].text), "__add__") == 0)
+ (yyvsp[(3) - (14)].text) = "__pos__";
+ else if (strcmp((yyvsp[(3) - (14)].text), "__sub__") == 0)
+ (yyvsp[(3) - (14)].text) = "__neg__";
+ }
+
+ (yyvsp[(5) - (14)].signature).result = (yyvsp[(1) - (14)].memArg);
+
+ newFunction(currentSpec, currentModule, cd, NULL,
+ sectionFlags, currentIsStatic, currentIsSignal,
+ currentIsSlot, currentOverIsVirt, (yyvsp[(3) - (14)].text), &(yyvsp[(5) - (14)].signature), (yyvsp[(7) - (14)].number), (yyvsp[(9) - (14)].number),
+ &(yyvsp[(10) - (14)].optflags), (yyvsp[(13) - (14)].codeb), (yyvsp[(14) - (14)].codeb), (yyvsp[(8) - (14)].throwlist), (yyvsp[(11) - (14)].optsignature), NULL);
+ }
+
+ currentIsStatic = FALSE;
+ currentIsSignal = FALSE;
+ currentIsSlot = FALSE;
+ currentOverIsVirt = FALSE;
+ }
+ break;
+
+ case 253:
+
+/* Line 1455 of yacc.c */
+#line 1971 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ char *sname;
+ classDef *scope = currentScope();
+
+ if (scope == NULL || (yyvsp[(4) - (13)].signature).nrArgs != 0)
+ yyerror("Operator casts must be specified in a class and have no arguments");
+
+ applyTypeFlags(currentModule, &(yyvsp[(2) - (13)].memArg), &(yyvsp[(9) - (13)].optflags));
+
+ switch ((yyvsp[(2) - (13)].memArg).atype)
+ {
+ case defined_type:
+ sname = NULL;
+ break;
+
+ case bool_type:
+ case cbool_type:
+ case short_type:
+ case ushort_type:
+ case int_type:
+ case cint_type:
+ case uint_type:
+ sname = "__int__";
+ break;
+
+ case long_type:
+ case ulong_type:
+ case longlong_type:
+ case ulonglong_type:
+ sname = "__long__";
+ break;
+
+ case float_type:
+ case cfloat_type:
+ case double_type:
+ case cdouble_type:
+ sname = "__float__";
+ break;
+
+ default:
+ yyerror("Unsupported operator cast");
+ }
+
+ if (sname != NULL)
+ {
+ (yyvsp[(4) - (13)].signature).result = (yyvsp[(2) - (13)].memArg);
+
+ newFunction(currentSpec, currentModule, scope, NULL,
+ sectionFlags, currentIsStatic, currentIsSignal,
+ currentIsSlot, currentOverIsVirt, sname, &(yyvsp[(4) - (13)].signature), (yyvsp[(6) - (13)].number),
+ (yyvsp[(8) - (13)].number), &(yyvsp[(9) - (13)].optflags), (yyvsp[(12) - (13)].codeb), (yyvsp[(13) - (13)].codeb), (yyvsp[(7) - (13)].throwlist), (yyvsp[(10) - (13)].optsignature), NULL);
+ }
+ else
+ {
+ argList *al;
+
+ /* Check it doesn't already exist. */
+ for (al = scope->casts; al != NULL; al = al->next)
+ if (compareScopedNames((yyvsp[(2) - (13)].memArg).u.snd, al->arg.u.snd) == 0)
+ yyerror("This operator cast has already been specified in this class");
+
+ al = sipMalloc(sizeof (argList));
+ al->arg = (yyvsp[(2) - (13)].memArg);
+ al->next = scope->casts;
+
+ scope->casts = al;
+ }
+ }
+
+ currentIsStatic = FALSE;
+ currentIsSignal = FALSE;
+ currentIsSlot = FALSE;
+ currentOverIsVirt = FALSE;
+ }
+ break;
+
+ case 254:
+
+/* Line 1455 of yacc.c */
+#line 2049 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__add__";}
+ break;
+
+ case 255:
+
+/* Line 1455 of yacc.c */
+#line 2050 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__sub__";}
+ break;
+
+ case 256:
+
+/* Line 1455 of yacc.c */
+#line 2051 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__mul__";}
+ break;
+
+ case 257:
+
+/* Line 1455 of yacc.c */
+#line 2052 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__div__";}
+ break;
+
+ case 258:
+
+/* Line 1455 of yacc.c */
+#line 2053 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__mod__";}
+ break;
+
+ case 259:
+
+/* Line 1455 of yacc.c */
+#line 2054 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__and__";}
+ break;
+
+ case 260:
+
+/* Line 1455 of yacc.c */
+#line 2055 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__or__";}
+ break;
+
+ case 261:
+
+/* Line 1455 of yacc.c */
+#line 2056 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__xor__";}
+ break;
+
+ case 262:
+
+/* Line 1455 of yacc.c */
+#line 2057 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__lshift__";}
+ break;
+
+ case 263:
+
+/* Line 1455 of yacc.c */
+#line 2058 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__rshift__";}
+ break;
+
+ case 264:
+
+/* Line 1455 of yacc.c */
+#line 2059 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__iadd__";}
+ break;
+
+ case 265:
+
+/* Line 1455 of yacc.c */
+#line 2060 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__isub__";}
+ break;
+
+ case 266:
+
+/* Line 1455 of yacc.c */
+#line 2061 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__imul__";}
+ break;
+
+ case 267:
+
+/* Line 1455 of yacc.c */
+#line 2062 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__idiv__";}
+ break;
+
+ case 268:
+
+/* Line 1455 of yacc.c */
+#line 2063 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__imod__";}
+ break;
+
+ case 269:
+
+/* Line 1455 of yacc.c */
+#line 2064 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__iand__";}
+ break;
+
+ case 270:
+
+/* Line 1455 of yacc.c */
+#line 2065 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__ior__";}
+ break;
+
+ case 271:
+
+/* Line 1455 of yacc.c */
+#line 2066 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__ixor__";}
+ break;
+
+ case 272:
+
+/* Line 1455 of yacc.c */
+#line 2067 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__ilshift__";}
+ break;
+
+ case 273:
+
+/* Line 1455 of yacc.c */
+#line 2068 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__irshift__";}
+ break;
+
+ case 274:
+
+/* Line 1455 of yacc.c */
+#line 2069 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__invert__";}
+ break;
+
+ case 275:
+
+/* Line 1455 of yacc.c */
+#line 2070 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__call__";}
+ break;
+
+ case 276:
+
+/* Line 1455 of yacc.c */
+#line 2071 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__getitem__";}
+ break;
+
+ case 277:
+
+/* Line 1455 of yacc.c */
+#line 2072 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__lt__";}
+ break;
+
+ case 278:
+
+/* Line 1455 of yacc.c */
+#line 2073 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__le__";}
+ break;
+
+ case 279:
+
+/* Line 1455 of yacc.c */
+#line 2074 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__eq__";}
+ break;
+
+ case 280:
+
+/* Line 1455 of yacc.c */
+#line 2075 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__ne__";}
+ break;
+
+ case 281:
+
+/* Line 1455 of yacc.c */
+#line 2076 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__gt__";}
+ break;
+
+ case 282:
+
+/* Line 1455 of yacc.c */
+#line 2077 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {(yyval.text) = "__ge__";}
+ break;
+
+ case 283:
+
+/* Line 1455 of yacc.c */
+#line 2080 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.number) = FALSE;
+ }
+ break;
+
+ case 284:
+
+/* Line 1455 of yacc.c */
+#line 2083 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.number) = TRUE;
+ }
+ break;
+
+ case 285:
+
+/* Line 1455 of yacc.c */
+#line 2088 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.number) = 0;
+ }
+ break;
+
+ case 286:
+
+/* Line 1455 of yacc.c */
+#line 2091 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if ((yyvsp[(2) - (2)].number) != 0)
+ yyerror("Abstract virtual function '= 0' expected");
+
+ (yyval.number) = TRUE;
+ }
+ break;
+
+ case 287:
+
+/* Line 1455 of yacc.c */
+#line 2099 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.optflags).nrFlags = 0;
+ }
+ break;
+
+ case 288:
+
+/* Line 1455 of yacc.c */
+#line 2102 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.optflags) = (yyvsp[(2) - (3)].optflags);
+ }
+ break;
+
+ case 289:
+
+/* Line 1455 of yacc.c */
+#line 2108 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.optflags).flags[0] = (yyvsp[(1) - (1)].flag);
+ (yyval.optflags).nrFlags = 1;
+ }
+ break;
+
+ case 290:
+
+/* Line 1455 of yacc.c */
+#line 2112 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ /* Check there is room. */
+
+ if ((yyvsp[(1) - (3)].optflags).nrFlags == MAX_NR_FLAGS)
+ yyerror("Too many optional flags");
+
+ (yyval.optflags) = (yyvsp[(1) - (3)].optflags);
+
+ (yyval.optflags).flags[(yyval.optflags).nrFlags++] = (yyvsp[(3) - (3)].flag);
+ }
+ break;
+
+ case 291:
+
+/* Line 1455 of yacc.c */
+#line 2124 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.flag).ftype = bool_flag;
+ (yyval.flag).fname = (yyvsp[(1) - (1)].text);
+ }
+ break;
+
+ case 292:
+
+/* Line 1455 of yacc.c */
+#line 2128 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.flag) = (yyvsp[(3) - (3)].flag);
+ (yyval.flag).fname = (yyvsp[(1) - (3)].text);
+ }
+ break;
+
+ case 293:
+
+/* Line 1455 of yacc.c */
+#line 2134 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.flag).ftype = (strchr((yyvsp[(1) - (1)].text), '.') != NULL) ? dotted_name_flag : name_flag;
+ (yyval.flag).fvalue.sval = (yyvsp[(1) - (1)].text);
+ }
+ break;
+
+ case 294:
+
+/* Line 1455 of yacc.c */
+#line 2138 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ apiVersionRangeDef *avd;
+ int from, to;
+
+ (yyval.flag).ftype = api_range_flag;
+
+ /* Check that the API is known. */
+ if ((avd = findAPI(currentSpec, (yyvsp[(1) - (5)].text))) == NULL)
+ yyerror("unknown API name in API annotation");
+
+ if (inMainModule())
+ setIsUsedName(avd->api_name);
+
+ /* Unbounded values are represented by 0. */
+ if ((from = (yyvsp[(3) - (5)].number)) < 0)
+ from = 0;
+
+ if ((to = (yyvsp[(5) - (5)].number)) < 0)
+ to = 0;
+
+ (yyval.flag).fvalue.aval = convertAPIRange(currentModule, avd->api_name,
+ from, to);
+ }
+ break;
+
+ case 295:
+
+/* Line 1455 of yacc.c */
+#line 2161 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.flag).ftype = string_flag;
+ (yyval.flag).fvalue.sval = convertFeaturedString((yyvsp[(1) - (1)].text));
+ }
+ break;
+
+ case 296:
+
+/* Line 1455 of yacc.c */
+#line 2165 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.flag).ftype = integer_flag;
+ (yyval.flag).fvalue.ival = (yyvsp[(1) - (1)].number);
+ }
+ break;
+
+ case 297:
+
+/* Line 1455 of yacc.c */
+#line 2171 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = (yyvsp[(2) - (2)].codeb);
+ }
+ break;
+
+ case 298:
+
+/* Line 1455 of yacc.c */
+#line 2176 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = NULL;
+ }
+ break;
+
+ case 300:
+
+/* Line 1455 of yacc.c */
+#line 2182 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = NULL;
+ }
+ break;
+
+ case 301:
+
+/* Line 1455 of yacc.c */
+#line 2185 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = (yyvsp[(2) - (2)].codeb);
+ }
+ break;
+
+ case 302:
+
+/* Line 1455 of yacc.c */
+#line 2190 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = NULL;
+ }
+ break;
+
+ case 303:
+
+/* Line 1455 of yacc.c */
+#line 2193 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.codeb) = (yyvsp[(2) - (2)].codeb);
+ }
+ break;
+
+ case 304:
+
+/* Line 1455 of yacc.c */
+#line 2198 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ int a, nrrxcon, nrrxdis, nrslotcon, nrslotdis, nrarray, nrarraysize;
+
+ nrrxcon = nrrxdis = nrslotcon = nrslotdis = nrarray = nrarraysize = 0;
+
+ for (a = 0; a < (yyvsp[(1) - (1)].signature).nrArgs; ++a)
+ {
+ argDef *ad = &(yyvsp[(1) - (1)].signature).args[a];
+
+ switch (ad -> atype)
+ {
+ case rxcon_type:
+ ++nrrxcon;
+ break;
+
+ case rxdis_type:
+ ++nrrxdis;
+ break;
+
+ case slotcon_type:
+ ++nrslotcon;
+ break;
+
+ case slotdis_type:
+ ++nrslotdis;
+ break;
+ }
+
+ if (isArray(ad))
+ ++nrarray;
+
+ if (isArraySize(ad))
+ ++nrarraysize;
+ }
+
+ if (nrrxcon != nrslotcon || nrrxcon > 1)
+ yyerror("SIP_RXOBJ_CON and SIP_SLOT_CON must both be given and at most once");
+
+ if (nrrxdis != nrslotdis || nrrxdis > 1)
+ yyerror("SIP_RXOBJ_DIS and SIP_SLOT_DIS must both be given and at most once");
+
+ if (nrarray != nrarraysize || nrarray > 1)
+ yyerror("/Array/ and /ArraySize/ must both be given and at most once");
+
+ (yyval.signature) = (yyvsp[(1) - (1)].signature);
+ }
+ break;
+
+ case 305:
+
+/* Line 1455 of yacc.c */
+#line 2246 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ /* No arguments. */
+
+ (yyval.signature).nrArgs = 0;
+ }
+ break;
+
+ case 306:
+
+/* Line 1455 of yacc.c */
+#line 2251 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ /* The single or first argument. */
+
+ (yyval.signature).args[0] = (yyvsp[(1) - (1)].memArg);
+ (yyval.signature).nrArgs = 1;
+ }
+ break;
+
+ case 307:
+
+/* Line 1455 of yacc.c */
+#line 2257 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ /* Check that it wasn't ...(,arg...). */
+ if ((yyvsp[(1) - (3)].signature).nrArgs == 0)
+ yyerror("First argument of the list is missing");
+
+ /* Check there is nothing after an ellipsis. */
+ if ((yyvsp[(1) - (3)].signature).args[(yyvsp[(1) - (3)].signature).nrArgs - 1].atype == ellipsis_type)
+ yyerror("An ellipsis must be at the end of the argument list");
+
+ /*
+ * If this argument has no default value, then the
+ * previous one mustn't either.
+ */
+ if ((yyvsp[(3) - (3)].memArg).defval == NULL && (yyvsp[(1) - (3)].signature).args[(yyvsp[(1) - (3)].signature).nrArgs - 1].defval != NULL)
+ yyerror("Compulsory argument given after optional argument");
+
+ /* Check there is room. */
+ if ((yyvsp[(1) - (3)].signature).nrArgs == MAX_NR_ARGS)
+ yyerror("Internal error - increase the value of MAX_NR_ARGS");
+
+ (yyval.signature) = (yyvsp[(1) - (3)].signature);
+
+ (yyval.signature).args[(yyval.signature).nrArgs] = (yyvsp[(3) - (3)].memArg);
+ (yyval.signature).nrArgs++;
+ }
+ break;
+
+ case 308:
+
+/* Line 1455 of yacc.c */
+#line 2284 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.memArg).atype = signal_type;
+ (yyval.memArg).argflags = ARG_IS_CONST;
+ (yyval.memArg).nrderefs = 0;
+ (yyval.memArg).name = cacheName(currentSpec, (yyvsp[(2) - (4)].text));
+ (yyval.memArg).defval = (yyvsp[(4) - (4)].valp);
+
+ currentSpec -> sigslots = TRUE;
+ }
+ break;
+
+ case 309:
+
+/* Line 1455 of yacc.c */
+#line 2293 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.memArg).atype = slot_type;
+ (yyval.memArg).argflags = ARG_IS_CONST;
+ (yyval.memArg).nrderefs = 0;
+ (yyval.memArg).name = cacheName(currentSpec, (yyvsp[(2) - (4)].text));
+ (yyval.memArg).defval = (yyvsp[(4) - (4)].valp);
+
+ currentSpec -> sigslots = TRUE;
+ }
+ break;
+
+ case 310:
+
+/* Line 1455 of yacc.c */
+#line 2302 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.memArg).atype = anyslot_type;
+ (yyval.memArg).argflags = ARG_IS_CONST;
+ (yyval.memArg).nrderefs = 0;
+ (yyval.memArg).name = cacheName(currentSpec, (yyvsp[(2) - (4)].text));
+ (yyval.memArg).defval = (yyvsp[(4) - (4)].valp);
+
+ currentSpec -> sigslots = TRUE;
+ }
+ break;
+
+ case 311:
+
+/* Line 1455 of yacc.c */
+#line 2311 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.memArg).atype = rxcon_type;
+ (yyval.memArg).argflags = 0;
+ (yyval.memArg).nrderefs = 0;
+ (yyval.memArg).name = cacheName(currentSpec, (yyvsp[(2) - (3)].text));
+
+ if (findOptFlag(&(yyvsp[(3) - (3)].optflags), "SingleShot", bool_flag) != NULL)
+ (yyval.memArg).argflags |= ARG_SINGLE_SHOT;
+
+ currentSpec -> sigslots = TRUE;
+ }
+ break;
+
+ case 312:
+
+/* Line 1455 of yacc.c */
+#line 2322 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.memArg).atype = rxdis_type;
+ (yyval.memArg).argflags = 0;
+ (yyval.memArg).nrderefs = 0;
+ (yyval.memArg).name = cacheName(currentSpec, (yyvsp[(2) - (3)].text));
+
+ currentSpec -> sigslots = TRUE;
+ }
+ break;
+
+ case 313:
+
+/* Line 1455 of yacc.c */
+#line 2330 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.memArg).atype = slotcon_type;
+ (yyval.memArg).argflags = ARG_IS_CONST;
+ (yyval.memArg).nrderefs = 0;
+ (yyval.memArg).name = cacheName(currentSpec, (yyvsp[(5) - (6)].text));
+
+ memset(&(yyvsp[(3) - (6)].signature).result, 0, sizeof (argDef));
+ (yyvsp[(3) - (6)].signature).result.atype = void_type;
+
+ (yyval.memArg).u.sa = sipMalloc(sizeof (signatureDef));
+ *(yyval.memArg).u.sa = (yyvsp[(3) - (6)].signature);
+
+ currentSpec -> sigslots = TRUE;
+ }
+ break;
+
+ case 314:
+
+/* Line 1455 of yacc.c */
+#line 2344 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.memArg).atype = slotdis_type;
+ (yyval.memArg).argflags = ARG_IS_CONST;
+ (yyval.memArg).nrderefs = 0;
+ (yyval.memArg).name = cacheName(currentSpec, (yyvsp[(5) - (6)].text));
+
+ memset(&(yyvsp[(3) - (6)].signature).result, 0, sizeof (argDef));
+ (yyvsp[(3) - (6)].signature).result.atype = void_type;
+
+ (yyval.memArg).u.sa = sipMalloc(sizeof (signatureDef));
+ *(yyval.memArg).u.sa = (yyvsp[(3) - (6)].signature);
+
+ currentSpec -> sigslots = TRUE;
+ }
+ break;
+
+ case 315:
+
+/* Line 1455 of yacc.c */
+#line 2358 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.memArg).atype = qobject_type;
+ (yyval.memArg).argflags = 0;
+ (yyval.memArg).nrderefs = 0;
+ (yyval.memArg).name = cacheName(currentSpec, (yyvsp[(2) - (3)].text));
+ }
+ break;
+
+ case 316:
+
+/* Line 1455 of yacc.c */
+#line 2364 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.memArg) = (yyvsp[(1) - (2)].memArg);
+ (yyval.memArg).defval = (yyvsp[(2) - (2)].valp);
+ }
+ break;
+
+ case 317:
+
+/* Line 1455 of yacc.c */
+#line 2371 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {currentIsSignal = TRUE;}
+ break;
+
+ case 319:
+
+/* Line 1455 of yacc.c */
+#line 2372 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {currentIsSlot = TRUE;}
+ break;
+
+ case 322:
+
+/* Line 1455 of yacc.c */
+#line 2377 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {currentIsStatic = TRUE;}
+ break;
+
+ case 327:
+
+/* Line 1455 of yacc.c */
+#line 2387 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {currentOverIsVirt = TRUE;}
+ break;
+
+ case 330:
+
+/* Line 1455 of yacc.c */
+#line 2391 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (notSkipping())
+ {
+ /* Check the section. */
+
+ if (sectionFlags != 0)
+ {
+ if ((sectionFlags & SECT_IS_PUBLIC) == 0)
+ yyerror("Class variables must be in the public section");
+
+ if (!currentIsStatic && (yyvsp[(5) - (7)].codeb) != NULL)
+ yyerror("%AccessCode cannot be specified for non-static class variables");
+ }
+
+ if (currentIsStatic && currentSpec -> genc)
+ yyerror("Cannot have static members in a C structure");
+
+ applyTypeFlags(currentModule, &(yyvsp[(1) - (7)].memArg), &(yyvsp[(3) - (7)].optflags));
+
+ if ((yyvsp[(6) - (7)].codeb) != NULL || (yyvsp[(7) - (7)].codeb) != NULL)
+ {
+ if ((yyvsp[(5) - (7)].codeb) != NULL)
+ yyerror("Cannot mix %AccessCode and %GetCode or %SetCode");
+
+ if (currentScope() == NULL)
+ yyerror("Cannot specify %GetCode or %SetCode for global variables");
+ }
+
+ newVar(currentSpec,currentModule,(yyvsp[(2) - (7)].text),currentIsStatic,&(yyvsp[(1) - (7)].memArg),&(yyvsp[(3) - (7)].optflags),(yyvsp[(5) - (7)].codeb),(yyvsp[(6) - (7)].codeb),(yyvsp[(7) - (7)].codeb));
+ }
+
+ currentIsStatic = FALSE;
+ }
+ break;
+
+ case 331:
+
+/* Line 1455 of yacc.c */
+#line 2426 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.memArg) = (yyvsp[(2) - (4)].memArg);
+ (yyval.memArg).nrderefs += (yyvsp[(3) - (4)].number);
+ (yyval.memArg).argflags |= ARG_IS_CONST | (yyvsp[(4) - (4)].number);
+ }
+ break;
+
+ case 332:
+
+/* Line 1455 of yacc.c */
+#line 2431 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.memArg) = (yyvsp[(1) - (3)].memArg);
+ (yyval.memArg).nrderefs += (yyvsp[(2) - (3)].number);
+ (yyval.memArg).argflags |= (yyvsp[(3) - (3)].number);
+ }
+ break;
+
+ case 333:
+
+/* Line 1455 of yacc.c */
+#line 2438 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.memArg) = (yyvsp[(1) - (3)].memArg);
+ (yyval.memArg).name = cacheName(currentSpec, (yyvsp[(2) - (3)].text));
+
+ if (getAllowNone(&(yyvsp[(3) - (3)].optflags)))
+ (yyval.memArg).argflags |= ARG_ALLOW_NONE;
+
+ if (findOptFlag(&(yyvsp[(3) - (3)].optflags),"GetWrapper",bool_flag) != NULL)
+ (yyval.memArg).argflags |= ARG_GET_WRAPPER;
+
+ if (findOptFlag(&(yyvsp[(3) - (3)].optflags),"Array",bool_flag) != NULL)
+ (yyval.memArg).argflags |= ARG_ARRAY;
+
+ if (findOptFlag(&(yyvsp[(3) - (3)].optflags),"ArraySize",bool_flag) != NULL)
+ (yyval.memArg).argflags |= ARG_ARRAY_SIZE;
+
+ if (getTransfer(&(yyvsp[(3) - (3)].optflags)))
+ (yyval.memArg).argflags |= ARG_XFERRED;
+
+ if (findOptFlag(&(yyvsp[(3) - (3)].optflags),"TransferThis",bool_flag) != NULL)
+ (yyval.memArg).argflags |= ARG_THIS_XFERRED;
+
+ if (findOptFlag(&(yyvsp[(3) - (3)].optflags),"TransferBack",bool_flag) != NULL)
+ (yyval.memArg).argflags |= ARG_XFERRED_BACK;
+
+ if (findOptFlag(&(yyvsp[(3) - (3)].optflags), "KeepReference", bool_flag) != NULL)
+ {
+ (yyval.memArg).argflags |= ARG_KEEP_REF;
+ (yyval.memArg).key = currentModule->next_key++;
+ }
+
+ if (findOptFlag(&(yyvsp[(3) - (3)].optflags),"In",bool_flag) != NULL)
+ (yyval.memArg).argflags |= ARG_IN;
+
+ if (findOptFlag(&(yyvsp[(3) - (3)].optflags),"Out",bool_flag) != NULL)
+ (yyval.memArg).argflags |= ARG_OUT;
+
+ if (findOptFlag(&(yyvsp[(3) - (3)].optflags), "ResultSize", bool_flag) != NULL)
+ (yyval.memArg).argflags |= ARG_RESULT_SIZE;
+
+ if (findOptFlag(&(yyvsp[(3) - (3)].optflags), "NoCopy", bool_flag) != NULL)
+ (yyval.memArg).argflags |= ARG_NO_COPY;
+
+ if (findOptFlag(&(yyvsp[(3) - (3)].optflags),"Constrained",bool_flag) != NULL)
+ {
+ (yyval.memArg).argflags |= ARG_CONSTRAINED;
+
+ switch ((yyval.memArg).atype)
+ {
+ case bool_type:
+ (yyval.memArg).atype = cbool_type;
+ break;
+
+ case int_type:
+ (yyval.memArg).atype = cint_type;
+ break;
+
+ case float_type:
+ (yyval.memArg).atype = cfloat_type;
+ break;
+
+ case double_type:
+ (yyval.memArg).atype = cdouble_type;
+ break;
+ }
+ }
+
+ applyTypeFlags(currentModule, &(yyval.memArg), &(yyvsp[(3) - (3)].optflags));
+ (yyval.memArg).docval = getDocValue(&(yyvsp[(3) - (3)].optflags));
+ }
+ break;
+
+ case 334:
+
+/* Line 1455 of yacc.c */
+#line 2510 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.number) = 0;
+ }
+ break;
+
+ case 335:
+
+/* Line 1455 of yacc.c */
+#line 2513 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (currentSpec -> genc)
+ yyerror("References not allowed in a C module");
+
+ (yyval.number) = ARG_IS_REF;
+ }
+ break;
+
+ case 336:
+
+/* Line 1455 of yacc.c */
+#line 2521 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.number) = 0;
+ }
+ break;
+
+ case 337:
+
+/* Line 1455 of yacc.c */
+#line 2524 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.number) = (yyvsp[(1) - (2)].number) + 1;
+ }
+ break;
+
+ case 338:
+
+/* Line 1455 of yacc.c */
+#line 2529 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = defined_type;
+ (yyval.memArg).u.snd = (yyvsp[(1) - (1)].scpvalp);
+
+ /* Try and resolve typedefs as early as possible. */
+ resolveAnyTypedef(currentSpec, &(yyval.memArg));
+ }
+ break;
+
+ case 339:
+
+/* Line 1455 of yacc.c */
+#line 2537 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ templateDef *td;
+
+ td = sipMalloc(sizeof(templateDef));
+ td->fqname = (yyvsp[(1) - (4)].scpvalp);
+ td->types = (yyvsp[(3) - (4)].signature);
+
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = template_type;
+ (yyval.memArg).u.td = td;
+ }
+ break;
+
+ case 340:
+
+/* Line 1455 of yacc.c */
+#line 2548 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+
+ /* In a C module all structures must be defined. */
+ if (currentSpec -> genc)
+ {
+ (yyval.memArg).atype = defined_type;
+ (yyval.memArg).u.snd = (yyvsp[(2) - (2)].scpvalp);
+ }
+ else
+ {
+ (yyval.memArg).atype = struct_type;
+ (yyval.memArg).u.sname = (yyvsp[(2) - (2)].scpvalp);
+ }
+ }
+ break;
+
+ case 341:
+
+/* Line 1455 of yacc.c */
+#line 2563 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = ushort_type;
+ }
+ break;
+
+ case 342:
+
+/* Line 1455 of yacc.c */
+#line 2567 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = short_type;
+ }
+ break;
+
+ case 343:
+
+/* Line 1455 of yacc.c */
+#line 2571 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = uint_type;
+ }
+ break;
+
+ case 344:
+
+/* Line 1455 of yacc.c */
+#line 2575 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = uint_type;
+ }
+ break;
+
+ case 345:
+
+/* Line 1455 of yacc.c */
+#line 2579 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = int_type;
+ }
+ break;
+
+ case 346:
+
+/* Line 1455 of yacc.c */
+#line 2583 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = long_type;
+ }
+ break;
+
+ case 347:
+
+/* Line 1455 of yacc.c */
+#line 2587 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = ulong_type;
+ }
+ break;
+
+ case 348:
+
+/* Line 1455 of yacc.c */
+#line 2591 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = longlong_type;
+ }
+ break;
+
+ case 349:
+
+/* Line 1455 of yacc.c */
+#line 2595 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = ulonglong_type;
+ }
+ break;
+
+ case 350:
+
+/* Line 1455 of yacc.c */
+#line 2599 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = float_type;
+ }
+ break;
+
+ case 351:
+
+/* Line 1455 of yacc.c */
+#line 2603 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = double_type;
+ }
+ break;
+
+ case 352:
+
+/* Line 1455 of yacc.c */
+#line 2607 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = bool_type;
+ }
+ break;
+
+ case 353:
+
+/* Line 1455 of yacc.c */
+#line 2611 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = sstring_type;
+ }
+ break;
+
+ case 354:
+
+/* Line 1455 of yacc.c */
+#line 2615 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = ustring_type;
+ }
+ break;
+
+ case 355:
+
+/* Line 1455 of yacc.c */
+#line 2619 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = string_type;
+ }
+ break;
+
+ case 356:
+
+/* Line 1455 of yacc.c */
+#line 2623 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = wstring_type;
+ }
+ break;
+
+ case 357:
+
+/* Line 1455 of yacc.c */
+#line 2627 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = void_type;
+ }
+ break;
+
+ case 358:
+
+/* Line 1455 of yacc.c */
+#line 2631 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = pyobject_type;
+ }
+ break;
+
+ case 359:
+
+/* Line 1455 of yacc.c */
+#line 2635 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = pytuple_type;
+ }
+ break;
+
+ case 360:
+
+/* Line 1455 of yacc.c */
+#line 2639 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = pylist_type;
+ }
+ break;
+
+ case 361:
+
+/* Line 1455 of yacc.c */
+#line 2643 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = pydict_type;
+ }
+ break;
+
+ case 362:
+
+/* Line 1455 of yacc.c */
+#line 2647 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = pycallable_type;
+ }
+ break;
+
+ case 363:
+
+/* Line 1455 of yacc.c */
+#line 2651 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = pyslice_type;
+ }
+ break;
+
+ case 364:
+
+/* Line 1455 of yacc.c */
+#line 2655 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = pytype_type;
+ }
+ break;
+
+ case 365:
+
+/* Line 1455 of yacc.c */
+#line 2659 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ memset(&(yyval.memArg), 0, sizeof (argDef));
+ (yyval.memArg).atype = ellipsis_type;
+ }
+ break;
+
+ case 366:
+
+/* Line 1455 of yacc.c */
+#line 2665 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ /* The single or first type. */
+
+ (yyval.signature).args[0] = (yyvsp[(1) - (1)].memArg);
+ (yyval.signature).nrArgs = 1;
+ }
+ break;
+
+ case 367:
+
+/* Line 1455 of yacc.c */
+#line 2671 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ /* Check there is nothing after an ellipsis. */
+ if ((yyvsp[(1) - (3)].signature).args[(yyvsp[(1) - (3)].signature).nrArgs - 1].atype == ellipsis_type)
+ yyerror("An ellipsis must be at the end of the argument list");
+
+ /* Check there is room. */
+ if ((yyvsp[(1) - (3)].signature).nrArgs == MAX_NR_ARGS)
+ yyerror("Internal error - increase the value of MAX_NR_ARGS");
+
+ (yyval.signature) = (yyvsp[(1) - (3)].signature);
+
+ (yyval.signature).args[(yyval.signature).nrArgs] = (yyvsp[(3) - (3)].memArg);
+ (yyval.signature).nrArgs++;
+ }
+ break;
+
+ case 368:
+
+/* Line 1455 of yacc.c */
+#line 2687 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ (yyval.throwlist) = NULL;
+ }
+ break;
+
+ case 369:
+
+/* Line 1455 of yacc.c */
+#line 2690 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ if (currentSpec->genc)
+ yyerror("Exceptions not allowed in a C module");
+
+ (yyval.throwlist) = (yyvsp[(3) - (4)].throwlist);
+ }
+ break;
+
+ case 370:
+
+/* Line 1455 of yacc.c */
+#line 2698 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ /* Empty list so use a blank. */
+
+ (yyval.throwlist) = sipMalloc(sizeof (throwArgs));
+ (yyval.throwlist) -> nrArgs = 0;
+ }
+ break;
+
+ case 371:
+
+/* Line 1455 of yacc.c */
+#line 2704 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ /* The only or first exception. */
+
+ (yyval.throwlist) = sipMalloc(sizeof (throwArgs));
+ (yyval.throwlist) -> nrArgs = 1;
+ (yyval.throwlist) -> args[0] = findException(currentSpec, (yyvsp[(1) - (1)].scpvalp), FALSE);
+ }
+ break;
+
+ case 372:
+
+/* Line 1455 of yacc.c */
+#line 2711 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+ {
+ /* Check that it wasn't ...(,arg...). */
+
+ if ((yyvsp[(1) - (3)].throwlist) -> nrArgs == 0)
+ yyerror("First exception of throw specifier is missing");
+
+ /* Check there is room. */
+
+ if ((yyvsp[(1) - (3)].throwlist) -> nrArgs == MAX_NR_ARGS)
+ yyerror("Internal error - increase the value of MAX_NR_ARGS");
+
+ (yyval.throwlist) = (yyvsp[(1) - (3)].throwlist);
+ (yyval.throwlist) -> args[(yyval.throwlist) -> nrArgs++] = findException(currentSpec, (yyvsp[(3) - (3)].scpvalp), FALSE);
+ }
+ break;
+
+
+
+/* Line 1455 of yacc.c */
+#line 6104 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.c"
+ default: break;
+ }
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if ! YYERROR_VERBOSE
+ yyerror (YY_("syntax error"));
+#else
+ {
+ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+ {
+ YYSIZE_T yyalloc = 2 * yysize;
+ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+ yyalloc = YYSTACK_ALLOC_MAXIMUM;
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+ if (yymsg)
+ yymsg_alloc = yyalloc;
+ else
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ }
+ }
+
+ if (0 < yysize && yysize <= yymsg_alloc)
+ {
+ (void) yysyntax_error (yymsg, yystate, yychar);
+ yyerror (yymsg);
+ }
+ else
+ {
+ yyerror (YY_("syntax error"));
+ if (yysize != 0)
+ goto yyexhaustedlab;
+ }
+ }
+#endif
+ }
+
+
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (/*CONSTCOND*/ 0)
+ goto yyerrorlab;
+
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ *++yyvsp = yylval;
+
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#if !defined(yyoverflow) || YYERROR_VERBOSE
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+ if (yychar != YYEMPTY)
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval);
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ /* Make sure YYID is used. */
+ return YYID (yyresult);
+}
+
+
+
+/* Line 1675 of yacc.c */
+#line 2727 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+
+
+
+/*
+ * Parse the specification.
+ */
+void parse(sipSpec *spec, FILE *fp, char *filename, stringList *tsl,
+ stringList *xfl, int kwdArgs, int protHack)
+{
+ classTmplDef *tcd;
+
+ /* Initialise the spec. */
+
+ spec->modules = NULL;
+ spec->namecache = NULL;
+ spec->ifacefiles = NULL;
+ spec->classes = NULL;
+ spec->classtemplates = NULL;
+ spec->exceptions = NULL;
+ spec->mappedtypes = NULL;
+ spec->mappedtypetemplates = NULL;
+ spec->enums = NULL;
+ spec->vars = NULL;
+ spec->typedefs = NULL;
+ spec->exphdrcode = NULL;
+ spec->docs = NULL;
+ spec->sigslots = FALSE;
+ spec->genc = -1;
+ spec->plugins = NULL;
+
+ currentSpec = spec;
+ neededQualifiers = tsl;
+ excludedQualifiers = xfl;
+ currentModule = NULL;
+ currentMappedType = NULL;
+ currentOverIsVirt = FALSE;
+ currentCtorIsExplicit = FALSE;
+ currentIsStatic = FALSE;
+ currentIsSignal = FALSE;
+ currentIsSlot = FALSE;
+ currentIsTemplate = FALSE;
+ previousFile = NULL;
+ skipStackPtr = 0;
+ currentScopeIdx = 0;
+ sectionFlags = 0;
+ defaultKwdArgs = kwdArgs;
+ makeProtPublic = protHack;
+
+ newModule(fp, filename);
+ spec->module = currentModule;
+
+ yyparse();
+
+ handleEOF();
+ handleEOM();
+
+ /*
+ * Go through each template class and remove it from the list of classes.
+ */
+ for (tcd = spec->classtemplates; tcd != NULL; tcd = tcd->next)
+ {
+ classDef **cdp;
+
+ for (cdp = &spec->classes; *cdp != NULL; cdp = &(*cdp)->next)
+ if (*cdp == tcd->cd)
+ {
+ ifaceFileDef **ifdp;
+
+ /* Remove the interface file as well. */
+ for (ifdp = &spec->ifacefiles; *ifdp != NULL; ifdp = &(*ifdp)->next)
+ if (*ifdp == tcd->cd->iff)
+ {
+ *ifdp = (*ifdp)->next;
+ break;
+ }
+
+ *cdp = (*cdp)->next;
+ break;
+ }
+ }
+}
+
+
+/*
+ * Tell the parser that a complete file has now been read.
+ */
+void parserEOF(char *name, parserContext *pc)
+{
+ previousFile = sipStrdup(name);
+ currentContext = *pc;
+}
+
+
+/*
+ * Append a class definition to a class list if it doesn't already appear.
+ * Append is needed specifically for the list of super-classes because the
+ * order is important to Python.
+ */
+void appendToClassList(classList **clp,classDef *cd)
+{
+ classList *new;
+
+ /* Find the end of the list. */
+
+ while (*clp != NULL)
+ {
+ if ((*clp) -> cd == cd)
+ return;
+
+ clp = &(*clp) -> next;
+ }
+
+ new = sipMalloc(sizeof (classList));
+
+ new -> cd = cd;
+ new -> next = NULL;
+
+ *clp = new;
+}
+
+
+/*
+ * Create a new module for the current specification and make it current.
+ */
+static void newModule(FILE *fp, char *filename)
+{
+ moduleDef *mod;
+
+ parseFile(fp, filename, currentModule, FALSE);
+
+ mod = allocModule();
+ mod->file = filename;
+
+ if (currentModule != NULL)
+ mod->defexception = currentModule->defexception;
+
+ currentModule = mod;
+}
+
+
+/*
+ * Allocate and initialise the memory for a new module.
+ */
+static moduleDef *allocModule()
+{
+ moduleDef *newmod, **tailp;
+
+ newmod = sipMalloc(sizeof (moduleDef));
+
+ newmod->version = -1;
+ newmod->encoding = no_type;
+ newmod->qobjclass = -1;
+ newmod->nrvirthandlers = -1;
+ newmod->next_key = 1;
+
+ /*
+ * The consolidated module support needs these to be in order that they
+ * appeared.
+ */
+ for (tailp = &currentSpec->modules; *tailp != NULL; tailp = &(*tailp)->next)
+ ;
+
+ *tailp = newmod;
+
+ return newmod;
+}
+
+
+/*
+ * Switch to parsing a new file.
+ */
+static void parseFile(FILE *fp, char *name, moduleDef *prevmod, int optional)
+{
+ parserContext pc;
+
+ pc.filename = name;
+ pc.ifdepth = skipStackPtr;
+ pc.prevmod = prevmod;
+
+ if (setInputFile(fp, &pc, optional))
+ currentContext = pc;
+}
+
+
+/*
+ * Find an interface file, or create a new one.
+ */
+ifaceFileDef *findIfaceFile(sipSpec *pt, moduleDef *mod, scopedNameDef *fqname,
+ ifaceFileType iftype, apiVersionRangeDef *api_range, argDef *ad)
+{
+ ifaceFileDef *iff, *first_alt = NULL;
+
+ /* See if the name is already used. */
+
+ for (iff = pt->ifacefiles; iff != NULL; iff = iff->next)
+ {
+ if (compareScopedNames(iff->fqcname, fqname) != 0)
+ continue;
+
+ /*
+ * If they are both versioned then assume the user knows what they are
+ * doing.
+ */
+ if (iff->api_range != NULL && api_range != NULL && iff->module == mod)
+ {
+ /* Remember the first of the alternate APIs. */
+ if ((first_alt = iff->first_alt) == NULL)
+ first_alt = iff;
+
+ break;
+ }
+
+ /*
+ * They must be the same type except that we allow a class if we want
+ * an exception. This is because we allow classes to be used before
+ * they are defined.
+ */
+ if (iff->type != iftype)
+ if (iftype != exception_iface || iff->type != class_iface)
+ yyerror("A class, exception, namespace or mapped type has already been defined with the same name");
+
+ /* Ignore an external class declared in another module. */
+ if (iftype == class_iface && iff->module != mod)
+ {
+ classDef *cd;
+
+ for (cd = pt->classes; cd != NULL; cd = cd->next)
+ if (cd->iff == iff)
+ break;
+
+ if (cd != NULL && iff->module != NULL && isExternal(cd))
+ continue;
+ }
+
+ /*
+ * If this is a mapped type with the same name defined in a different
+ * module, then check that this type isn't the same as any of the
+ * mapped types defined in that module.
+ */
+ if (iftype == mappedtype_iface && iff->module != mod)
+ {
+ mappedTypeDef *mtd;
+
+ /*
+ * This is a bit of a cheat. With consolidated modules it's
+ * possible to have two implementations of a mapped type in
+ * different branches of the module hierarchy. We assume that, if
+ * there really are multiple implementations in the same branch,
+ * then it will be picked up in a non-consolidated build.
+ */
+ if (isConsolidated(pt->module))
+ continue;
+
+ for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next)
+ {
+ if (mtd->iff != iff)
+ continue;
+
+ if (ad->atype != template_type ||
+ mtd->type.atype != template_type ||
+ sameBaseType(ad, &mtd->type))
+ yyerror("Mapped type has already been defined in another module");
+ }
+
+ /*
+ * If we got here then we have a mapped type based on an existing
+ * template, but with unique parameters. We don't want to use
+ * interface files from other modules, so skip this one.
+ */
+
+ continue;
+ }
+
+ /* Ignore a namespace defined in another module. */
+ if (iftype == namespace_iface && iff->module != mod)
+ continue;
+
+ return iff;
+ }
+
+ iff = sipMalloc(sizeof (ifaceFileDef));
+
+ iff->name = cacheName(pt, scopedNameToString(fqname));
+ iff->api_range = api_range;
+
+ if (first_alt != NULL)
+ {
+ iff->first_alt = first_alt;
+ iff->next_alt = first_alt->next_alt;
+
+ first_alt->next_alt = iff;
+ }
+ else
+ {
+ /* This is the first alternate so point to itself. */
+ iff->first_alt = iff;
+ }
+
+ iff->type = iftype;
+ iff->ifacenr = -1;
+ iff->fqcname = fqname;
+ iff->module = NULL;
+ iff->hdrcode = NULL;
+ iff->used = NULL;
+ iff->next = pt->ifacefiles;
+
+ pt->ifacefiles = iff;
+
+ return iff;
+}
+
+
+/*
+ * Find a class definition in a parse tree.
+ */
+static classDef *findClass(sipSpec *pt, ifaceFileType iftype,
+ apiVersionRangeDef *api_range, scopedNameDef *fqname)
+{
+ return findClassWithInterface(pt, findIfaceFile(pt, currentModule, fqname, iftype, api_range, NULL));
+}
+
+
+/*
+ * Find a class definition given an existing interface file.
+ */
+static classDef *findClassWithInterface(sipSpec *pt, ifaceFileDef *iff)
+{
+ classDef *cd;
+
+ for (cd = pt -> classes; cd != NULL; cd = cd -> next)
+ if (cd -> iff == iff)
+ return cd;
+
+ /* Create a new one. */
+ cd = sipMalloc(sizeof (classDef));
+
+ cd->iff = iff;
+ cd->pyname = cacheName(pt, classBaseName(cd));
+ cd->next = pt->classes;
+
+ pt->classes = cd;
+
+ return cd;
+}
+
+
+/*
+ * Add an interface file to an interface file list if it isn't already there.
+ */
+void addToUsedList(ifaceFileList **ifflp, ifaceFileDef *iff)
+{
+ /* Make sure we don't try to add an interface file to its own list. */
+ if (&iff->used != ifflp)
+ {
+ ifaceFileList *iffl;
+
+ while ((iffl = *ifflp) != NULL)
+ {
+ /* Don't bother if it is already there. */
+ if (iffl->iff == iff)
+ return;
+
+ ifflp = &iffl -> next;
+ }
+
+ iffl = sipMalloc(sizeof (ifaceFileList));
+
+ iffl->iff = iff;
+ iffl->next = NULL;
+
+ *ifflp = iffl;
+ }
+}
+
+
+/*
+ * Find an undefined (or create a new) exception definition in a parse tree.
+ */
+static exceptionDef *findException(sipSpec *pt, scopedNameDef *fqname, int new)
+{
+ exceptionDef *xd, **tail;
+ ifaceFileDef *iff;
+ classDef *cd;
+
+ iff = findIfaceFile(pt, currentModule, fqname, exception_iface, NULL, NULL);
+
+ /* See if it is an existing one. */
+ for (xd = pt->exceptions; xd != NULL; xd = xd->next)
+ if (xd->iff == iff)
+ return xd;
+
+ /*
+ * If it is an exception interface file then we have never seen this
+ * name before. We require that exceptions are defined before being
+ * used, but don't make the same requirement of classes (for reasons of
+ * backwards compatibility). Therefore the name must be reinterpreted
+ * as a (as yet undefined) class.
+ */
+ if (new)
+ {
+ if (iff->type == exception_iface)
+ cd = NULL;
+ else
+ yyerror("There is already a class with the same name or the exception has been used before being defined");
+ }
+ else
+ {
+ if (iff->type == exception_iface)
+ iff->type = class_iface;
+
+ cd = findClassWithInterface(pt, iff);
+ }
+
+ /* Create a new one. */
+ xd = sipMalloc(sizeof (exceptionDef));
+
+ xd->exceptionnr = -1;
+ xd->iff = iff;
+ xd->pyname = NULL;
+ xd->cd = cd;
+ xd->bibase = NULL;
+ xd->base = NULL;
+ xd->raisecode = NULL;
+ xd->next = NULL;
+
+ /* Append it to the list. */
+ for (tail = &pt->exceptions; *tail != NULL; tail = &(*tail)->next)
+ ;
+
+ *tail = xd;
+
+ return xd;
+}
+
+
+/*
+ * Find an undefined (or create a new) class definition in a parse tree.
+ */
+static classDef *newClass(sipSpec *pt, ifaceFileType iftype,
+ apiVersionRangeDef *api_range, scopedNameDef *fqname)
+{
+ int flags;
+ classDef *cd, *scope;
+ codeBlock *hdrcode;
+
+ if (sectionFlags & SECT_IS_PRIVATE)
+ yyerror("Classes, structs and namespaces must be in the public or protected sections");
+
+ flags = 0;
+
+ if ((scope = currentScope()) != NULL)
+ {
+ if (sectionFlags & SECT_IS_PROT && !makeProtPublic)
+ {
+ flags = CLASS_IS_PROTECTED;
+
+ if (scope->iff->type == class_iface)
+ setHasShadow(scope);
+ }
+
+ /* Header code from outer scopes is also included. */
+ hdrcode = scope->iff->hdrcode;
+ }
+ else
+ hdrcode = NULL;
+
+ if (pt -> genc)
+ {
+ /* C structs are always global types. */
+ while (fqname -> next != NULL)
+ fqname = fqname -> next;
+
+ scope = NULL;
+ }
+
+ cd = findClass(pt, iftype, api_range, fqname);
+
+ /* Check it hasn't already been defined. */
+ if (iftype != namespace_iface && cd->iff->module != NULL)
+ yyerror("The struct/class has already been defined");
+
+ /* Complete the initialisation. */
+ cd->classflags |= flags;
+ cd->ecd = scope;
+ cd->iff->module = currentModule;
+
+ if (currentIsTemplate)
+ setIsTemplateClass(cd);
+
+ appendCodeBlock(&cd->iff->hdrcode, hdrcode);
+
+ /* See if it is a namespace extender. */
+ if (iftype == namespace_iface)
+ {
+ classDef *ns;
+
+ for (ns = pt->classes; ns != NULL; ns = ns->next)
+ {
+ if (ns == cd)
+ continue;
+
+ if (ns->iff->type != namespace_iface)
+ continue;
+
+ if (compareScopedNames(ns->iff->fqcname, fqname) != 0)
+ continue;
+
+ cd->real = ns;
+ break;
+ }
+ }
+
+ return cd;
+}
+
+
+/*
+ * Tidy up after finishing a class definition.
+ */
+static void finishClass(sipSpec *pt, moduleDef *mod, classDef *cd,
+ optFlags *of)
+{
+ const char *pyname;
+ optFlag *flg;
+
+ /* Get the Python name and see if it is different to the C++ name. */
+ pyname = getPythonName(of, classBaseName(cd));
+
+ cd->pyname = NULL;
+ checkAttributes(pt, mod, cd->ecd, NULL, pyname, FALSE);
+ cd->pyname = cacheName(pt, pyname);
+
+ if ((flg = findOptFlag(of, "Metatype", dotted_name_flag)) != NULL)
+ cd->metatype = cacheName(pt, flg->fvalue.sval);
+
+ if ((flg = findOptFlag(of, "Supertype", dotted_name_flag)) != NULL)
+ cd->supertype = cacheName(pt, flg->fvalue.sval);
+
+ if ((flg = findOptFlag(of, "PyQt4Flags", integer_flag)) != NULL)
+ cd->pyqt4_flags = flg->fvalue.ival;
+
+ if (findOptFlag(of, "PyQt4NoQMetaObject", bool_flag) != NULL)
+ setPyQt4NoQMetaObject(cd);
+
+ if (isOpaque(cd))
+ {
+ if (findOptFlag(of, "External", bool_flag) != NULL)
+ setIsExternal(cd);
+ }
+ else
+ {
+ int seq_might, seq_not;
+ memberDef *md;
+
+ if (findOptFlag(of, "NoDefaultCtors", bool_flag) != NULL)
+ setNoDefaultCtors(cd);
+
+ if (cd -> ctors == NULL)
+ {
+ if (!noDefaultCtors(cd))
+ {
+ /* Provide a default ctor. */
+
+ cd->ctors = sipMalloc(sizeof (ctorDef));
+
+ cd->ctors->ctorflags = SECT_IS_PUBLIC;
+ cd->ctors->pysig.result.atype = void_type;
+ cd->ctors->cppsig = &cd->ctors->pysig;
+
+ cd->defctor = cd->ctors;
+
+ setCanCreate(cd);
+ }
+ }
+ else if (cd -> defctor == NULL)
+ {
+ ctorDef *ct, *last = NULL;
+
+ for (ct = cd -> ctors; ct != NULL; ct = ct -> next)
+ {
+ if (!isPublicCtor(ct))
+ continue;
+
+ if (ct -> pysig.nrArgs == 0 || ct -> pysig.args[0].defval != NULL)
+ {
+ cd -> defctor = ct;
+ break;
+ }
+
+ if (last == NULL)
+ last = ct;
+ }
+
+ /* The last resort is the first public ctor. */
+ if (cd->defctor == NULL)
+ cd->defctor = last;
+ }
+
+ if (getDeprecated(of))
+ setIsDeprecatedClass(cd);
+
+ if (cd->convtocode != NULL && getAllowNone(of))
+ setClassHandlesNone(cd);
+
+ if (findOptFlag(of,"Abstract",bool_flag) != NULL)
+ {
+ setIsAbstractClass(cd);
+ setIsIncomplete(cd);
+ resetCanCreate(cd);
+ }
+
+ /* We assume a public dtor if nothing specific was provided. */
+ if (!isDtor(cd))
+ setIsPublicDtor(cd);
+
+ if (findOptFlag(of, "DelayDtor", bool_flag) != NULL)
+ {
+ setIsDelayedDtor(cd);
+ setHasDelayedDtors(mod);
+ }
+
+ /*
+ * There are subtle differences between the add and concat methods and
+ * the multiply and repeat methods. The number versions can have their
+ * operands swapped and may return NotImplemented. If the user has
+ * used the /Numeric/ annotation or there are other numeric operators
+ * then we use add/multiply. Otherwise, if there are indexing
+ * operators then we use concat/repeat.
+ */
+ seq_might = seq_not = FALSE;
+
+ for (md = cd -> members; md != NULL; md = md -> next)
+ switch (md -> slot)
+ {
+ case getitem_slot:
+ case setitem_slot:
+ case delitem_slot:
+ /* This might be a sequence. */
+ seq_might = TRUE;
+ break;
+
+ case sub_slot:
+ case isub_slot:
+ case div_slot:
+ case idiv_slot:
+ case mod_slot:
+ case imod_slot:
+ case floordiv_slot:
+ case ifloordiv_slot:
+ case truediv_slot:
+ case itruediv_slot:
+ case pos_slot:
+ case neg_slot:
+ /* This is definately not a sequence. */
+ seq_not = TRUE;
+ break;
+ }
+
+ if (!seq_not && seq_might)
+ for (md = cd -> members; md != NULL; md = md -> next)
+ {
+ /* Ignore if the user has been explicit. */
+ if (isNumeric(md))
+ continue;
+
+ switch (md -> slot)
+ {
+ case add_slot:
+ md -> slot = concat_slot;
+ break;
+
+ case iadd_slot:
+ md -> slot = iconcat_slot;
+ break;
+
+ case mul_slot:
+ md -> slot = repeat_slot;
+ break;
+
+ case imul_slot:
+ md -> slot = irepeat_slot;
+ break;
+ }
+ }
+ }
+
+ if (inMainModule())
+ {
+ setIsUsedName(cd->iff->name);
+ setIsUsedName(cd->pyname);
+ }
+}
+
+
+/*
+ * Return the encoded name of a template (ie. including its argument types) as
+ * a scoped name.
+ */
+scopedNameDef *encodedTemplateName(templateDef *td)
+{
+ int a;
+ scopedNameDef *snd;
+
+ snd = copyScopedName(td->fqname);
+
+ for (a = 0; a < td->types.nrArgs; ++a)
+ {
+ char buf[50];
+ int flgs;
+ scopedNameDef *arg_snd;
+ argDef *ad = &td->types.args[a];
+
+ flgs = 0;
+
+ if (isConstArg(ad))
+ flgs += 1;
+
+ if (isReference(ad))
+ flgs += 2;
+
+ /* We use numbers so they don't conflict with names. */
+ sprintf(buf, "%02d%d%d", ad->atype, flgs, ad->nrderefs);
+
+ switch (ad->atype)
+ {
+ case defined_type:
+ arg_snd = copyScopedName(ad->u.snd);
+ break;
+
+ case template_type:
+ arg_snd = encodedTemplateName(ad->u.td);
+ break;
+
+ case struct_type:
+ arg_snd = copyScopedName(ad->u.sname);
+ break;
+
+ default:
+ arg_snd = NULL;
+ }
+
+ /*
+ * Replace the first element of the argument name with a copy with the
+ * encoding prepended.
+ */
+ if (arg_snd != NULL)
+ arg_snd->name = concat(buf, arg_snd->name, NULL);
+ else
+ arg_snd = text2scopePart(sipStrdup(buf));
+
+ appendScopedName(&snd, arg_snd);
+ }
+
+ return snd;
+}
+
+
+/*
+ * Create a new mapped type.
+ */
+static mappedTypeDef *newMappedType(sipSpec *pt, argDef *ad, optFlags *of)
+{
+ mappedTypeDef *mtd;
+ scopedNameDef *snd;
+ ifaceFileDef *iff;
+ const char *cname;
+
+ /* Check that the type is one we want to map. */
+ switch (ad->atype)
+ {
+ case defined_type:
+ snd = ad->u.snd;
+ cname = scopedNameTail(snd);
+ break;
+
+ case template_type:
+ snd = encodedTemplateName(ad->u.td);
+ cname = NULL;
+ break;
+
+ case struct_type:
+ snd = ad->u.sname;
+ cname = scopedNameTail(snd);
+ break;
+
+ default:
+ yyerror("Invalid type for %MappedType");
+ }
+
+ iff = findIfaceFile(pt, currentModule, snd, mappedtype_iface,
+ getAPIRange(of), ad);
+
+ /* Check it hasn't already been defined. */
+ for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next)
+ if (mtd->iff == iff)
+ {
+ /*
+ * We allow types based on the same template but with different
+ * arguments.
+ */
+ if (ad->atype != template_type || sameBaseType(ad, &mtd->type))
+ yyerror("Mapped type has already been defined in this module");
+ }
+
+ /* The module may not have been set yet. */
+ iff->module = currentModule;
+
+ /* Create a new mapped type. */
+ mtd = allocMappedType(pt, ad);
+
+ if (cname != NULL)
+ mtd->pyname = cacheName(pt, getPythonName(of, cname));
+
+ if (findOptFlag(of, "NoRelease", bool_flag) != NULL)
+ setNoRelease(mtd);
+
+ if (getAllowNone(of))
+ setHandlesNone(mtd);
+
+ mtd->doctype = getDocType(of);
+
+ mtd->iff = iff;
+ mtd->next = pt->mappedtypes;
+
+ pt->mappedtypes = mtd;
+
+ if (inMainModule())
+ {
+ setIsUsedName(mtd->cname);
+
+ if (mtd->pyname)
+ setIsUsedName(mtd->pyname);
+ }
+
+ return mtd;
+}
+
+
+/*
+ * Allocate, intialise and return a mapped type structure.
+ */
+mappedTypeDef *allocMappedType(sipSpec *pt, argDef *type)
+{
+ mappedTypeDef *mtd;
+
+ mtd = sipMalloc(sizeof (mappedTypeDef));
+
+ mtd->type = *type;
+ mtd->type.argflags = 0;
+ mtd->type.nrderefs = 0;
+
+ mtd->cname = cacheName(pt, type2string(&mtd->type));
+
+ return mtd;
+}
+
+
+/*
+ * Create a new enum.
+ */
+static enumDef *newEnum(sipSpec *pt, moduleDef *mod, mappedTypeDef *mt_scope,
+ char *name, optFlags *of, int flags)
+{
+ enumDef *ed, *first_alt, *next_alt;
+ classDef *c_scope;
+ ifaceFileDef *scope;
+
+ if (mt_scope != NULL)
+ {
+ scope = mt_scope->iff;
+ c_scope = NULL;
+ }
+ else
+ {
+ if ((c_scope = currentScope()) != NULL)
+ scope = c_scope->iff;
+ else
+ scope = NULL;
+ }
+
+ ed = sipMalloc(sizeof (enumDef));
+
+ /* Assume the enum isn't versioned. */
+ first_alt = ed;
+ next_alt = NULL;
+
+ if (name != NULL)
+ {
+ ed->pyname = cacheName(pt, getPythonName(of, name));
+ checkAttributes(pt, mod, c_scope, mt_scope, ed->pyname->text, FALSE);
+
+ ed->fqcname = text2scopedName(scope, name);
+ ed->cname = cacheName(pt, scopedNameToString(ed->fqcname));
+
+ if (inMainModule())
+ {
+ setIsUsedName(ed->pyname);
+ setIsUsedName(ed->cname);
+ }
+
+ /* If the scope is versioned then look for any alternate. */
+ if (scope != NULL && scope->api_range != NULL)
+ {
+ enumDef *alt;
+
+ for (alt = pt->enums; alt != NULL; alt = alt->next)
+ {
+ if (alt->module != mod || alt->fqcname == NULL)
+ continue;
+
+ if (compareScopedNames(alt->fqcname, ed->fqcname) == 0)
+ {
+ first_alt = alt->first_alt;
+ next_alt = first_alt->next_alt;
+ first_alt->next_alt = ed;
+
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ ed->pyname = NULL;
+ ed->fqcname = NULL;
+ ed->cname = NULL;
+ }
+
+ if (flags & SECT_IS_PROT && makeProtPublic)
+ {
+ flags &= ~SECT_IS_PROT;
+ flags |= SECT_IS_PUBLIC;
+ }
+
+ ed->enumflags = flags;
+ ed->enumnr = -1;
+ ed->ecd = c_scope;
+ ed->emtd = mt_scope;
+ ed->first_alt = first_alt;
+ ed->next_alt = next_alt;
+ ed->module = mod;
+ ed->members = NULL;
+ ed->slots = NULL;
+ ed->overs = NULL;
+ ed->next = pt -> enums;
+
+ pt->enums = ed;
+
+ return ed;
+}
+
+
+/*
+ * Get the type values and (optionally) the type names for substitution in
+ * handwritten code.
+ */
+void appendTypeStrings(scopedNameDef *ename, signatureDef *patt, signatureDef *src, signatureDef *known, scopedNameDef **names, scopedNameDef **values)
+{
+ int a;
+
+ for (a = 0; a < patt->nrArgs; ++a)
+ {
+ argDef *pad = &patt->args[a];
+
+ if (pad->atype == defined_type)
+ {
+ char *nam = NULL, *val;
+ argDef *sad;
+
+ /*
+ * If the type names are already known then check that this is one
+ * of them.
+ */
+ if (known == NULL)
+ nam = scopedNameTail(pad->u.snd);
+ else if (pad->u.snd->next == NULL)
+ {
+ int k;
+
+ for (k = 0; k < known->nrArgs; ++k)
+ {
+ /* Skip base types. */
+ if (known->args[k].atype != defined_type)
+ continue;
+
+ if (strcmp(pad->u.snd->name, known->args[k].u.snd->name) == 0)
+ {
+ nam = pad->u.snd->name;
+ break;
+ }
+ }
+ }
+
+ if (nam == NULL)
+ continue;
+
+ /* Add the name. */
+ appendScopedName(names, text2scopePart(nam));
+
+ /*
+ * Add the corresponding value. For defined types we don't want
+ * any indirection or references.
+ */
+ sad = &src->args[a];
+
+ if (sad->atype == defined_type)
+ val = scopedNameToString(sad->u.snd);
+ else
+ val = type2string(sad);
+
+ appendScopedName(values, text2scopePart(val));
+ }
+ else if (pad->atype == template_type)
+ {
+ argDef *sad = &src->args[a];
+
+ /* These checks shouldn't be necessary, but... */
+ if (sad->atype == template_type && pad->u.td->types.nrArgs == sad->u.td->types.nrArgs)
+ appendTypeStrings(ename, &pad->u.td->types, &sad->u.td->types, known, names, values);
+ }
+ }
+}
+
+
+/*
+ * Convert a type to a string on the heap. The string will use the minimum
+ * whitespace while still remaining valid C++.
+ */
+static char *type2string(argDef *ad)
+{
+ int i, on_heap = FALSE;
+ int nr_derefs = ad->nrderefs;
+ int is_reference = isReference(ad);
+ char *s;
+
+ /* Use the original type if possible. */
+ if (ad->original_type != NULL && !noTypeName(ad->original_type))
+ {
+ s = scopedNameToString(ad->original_type->fqname);
+ on_heap = TRUE;
+
+ nr_derefs -= ad->original_type->type.nrderefs;
+
+ if (isReference(&ad->original_type->type))
+ is_reference = FALSE;
+ }
+ else
+ switch (ad->atype)
+ {
+ case template_type:
+ {
+ templateDef *td = ad->u.td;
+
+ s = scopedNameToString(td->fqname);
+ append(&s, "<");
+
+ for (i = 0; i < td->types.nrArgs; ++i)
+ {
+ char *sub_type = type2string(&td->types.args[i]);
+
+ if (i > 0)
+ append(&s, ",");
+
+ append(&s, sub_type);
+ free(sub_type);
+ }
+
+ if (s[strlen(s) - 1] == '>')
+ append(&s, " >");
+ else
+ append(&s, ">");
+
+ on_heap = TRUE;
+ break;
+ }
+
+ case struct_type:
+ s = scopedNameToString(ad->u.sname);
+ on_heap = TRUE;
+ break;
+
+ case defined_type:
+ s = scopedNameToString(ad->u.snd);
+ on_heap = TRUE;
+ break;
+
+ case ustring_type:
+ s = "unsigned char";
+ break;
+
+ case ascii_string_type:
+ case latin1_string_type:
+ case utf8_string_type:
+ case string_type:
+ s = "char";
+ break;
+
+ case sstring_type:
+ s = "signed char";
+ break;
+
+ case wstring_type:
+ s = "wchar_t";
+ break;
+
+ case ushort_type:
+ s = "unsigned short";
+ break;
+
+ case short_type:
+ s = "short";
+ break;
+
+ case uint_type:
+ s = "unsigned int";
+ break;
+
+ case int_type:
+ case cint_type:
+ s = "int";
+ break;
+
+ case ulong_type:
+ s = "unsigned long";
+ break;
+
+ case long_type:
+ s = "long";
+ break;
+
+ case ulonglong_type:
+ s = "unsigned long long";
+ break;
+
+ case longlong_type:
+ s = "long long";
+ break;
+
+ case float_type:
+ case cfloat_type:
+ s = "float";
+ break;
+
+ case double_type:
+ case cdouble_type:
+ s = "double";
+ break;
+
+ case bool_type:
+ case cbool_type:
+ s = "bool";
+ break;
+
+ default:
+ fatal("Unsupported type argument to type2string(): %d\n", ad->atype);
+ }
+
+ /* Make sure the string is on the heap. */
+ if (!on_heap)
+ s = sipStrdup(s);
+
+ while (nr_derefs-- > 0)
+ append(&s, "*");
+
+ if (is_reference)
+ append(&s, "&");
+
+ return s;
+}
+
+
+/*
+ * Convert a scoped name to a string on the heap.
+ */
+static char *scopedNameToString(scopedNameDef *name)
+{
+ static const char scope_string[] = "::";
+ size_t len;
+ scopedNameDef *snd;
+ char *s, *dp;
+
+ /* Work out the length of buffer needed. */
+ len = 0;
+
+ for (snd = name; snd != NULL; snd = snd->next)
+ {
+ len += strlen(snd->name);
+
+ if (snd->next != NULL)
+ {
+ /* Ignore the encoded part of template names. */
+ if (isdigit(snd->next->name[0]))
+ break;
+
+ len += strlen(scope_string);
+ }
+ }
+
+ /* Allocate and populate the buffer. */
+ dp = s = sipMalloc(len + 1);
+
+ for (snd = name; snd != NULL; snd = snd->next)
+ {
+ strcpy(dp, snd->name);
+ dp += strlen(snd->name);
+
+ if (snd->next != NULL)
+ {
+ /* Ignore the encoded part of template names. */
+ if (isdigit(snd->next->name[0]))
+ break;
+
+ strcpy(dp, scope_string);
+ dp += strlen(scope_string);
+ }
+ }
+
+ return s;
+}
+
+
+/*
+ * Instantiate a class template.
+ */
+static void instantiateClassTemplate(sipSpec *pt, moduleDef *mod,
+ classDef *scope, scopedNameDef *fqname, classTmplDef *tcd,
+ templateDef *td)
+{
+ scopedNameDef *type_names, *type_values;
+ classDef *cd;
+ ctorDef *oct, **cttail;
+ argDef *ad;
+ ifaceFileList *iffl, **used;
+
+ type_names = type_values = NULL;
+ appendTypeStrings(classFQCName(tcd->cd), &tcd->sig, &td->types, NULL, &type_names, &type_values);
+
+ /*
+ * Add a mapping from the template name to the instantiated name. If we
+ * have got this far we know there is room for it.
+ */
+ ad = &tcd->sig.args[tcd->sig.nrArgs++];
+ memset(ad, 0, sizeof (argDef));
+ ad->atype = defined_type;
+ ad->u.snd = classFQCName(tcd->cd);
+
+ appendScopedName(&type_names, text2scopePart(scopedNameTail(classFQCName(tcd->cd))));
+ appendScopedName(&type_values, text2scopePart(scopedNameToString(fqname)));
+
+ /* Create the new class. */
+ cd = sipMalloc(sizeof (classDef));
+
+ /* Start with a shallow copy. */
+ *cd = *tcd->cd;
+
+ resetIsTemplateClass(cd);
+ cd->pyname = cacheName(pt, scopedNameTail(fqname));
+ cd->td = td;
+
+ /* Handle the interface file. */
+ cd->iff = findIfaceFile(pt, mod, fqname, class_iface,
+ (scope != NULL ? scope->iff->api_range : NULL), NULL);
+ cd->iff->module = mod;
+
+ /* Make a copy of the used list and add the enclosing scope. */
+ used = &cd->iff->used;
+
+ for (iffl = tcd->cd->iff->used; iffl != NULL; iffl = iffl->next)
+ addToUsedList(used, iffl->iff);
+
+ /* Include any scope header code. */
+ if (scope != NULL)
+ appendCodeBlock(&cd->iff->hdrcode, scope->iff->hdrcode);
+
+ if (inMainModule())
+ {
+ setIsUsedName(cd->iff->name);
+ setIsUsedName(cd->pyname);
+ }
+
+ cd->ecd = currentScope();
+
+ /* Handle the enums. */
+ instantiateTemplateEnums(pt, tcd, td, cd, used, type_names, type_values);
+
+ /* Handle the variables. */
+ instantiateTemplateVars(pt, tcd, td, cd, used, type_names, type_values);
+
+ /* Handle the ctors. */
+ cd->ctors = NULL;
+ cttail = &cd->ctors;
+
+ for (oct = tcd->cd->ctors; oct != NULL; oct = oct->next)
+ {
+ ctorDef *nct = sipMalloc(sizeof (ctorDef));
+
+ /* Start with a shallow copy. */
+ *nct = *oct;
+
+ templateSignature(&nct->pysig, FALSE, tcd, td, cd);
+
+ if (oct->cppsig == NULL)
+ nct->cppsig = NULL;
+ else if (oct->cppsig == &oct->pysig)
+ nct->cppsig = &nct->pysig;
+ else
+ {
+ nct->cppsig = sipMalloc(sizeof (signatureDef));
+
+ *nct->cppsig = *oct->cppsig;
+
+ templateSignature(nct->cppsig, FALSE, tcd, td, cd);
+ }
+
+ nct->methodcode = templateCode(pt, used, nct->methodcode, type_names, type_values);
+
+ nct->next = NULL;
+ *cttail = nct;
+ cttail = &nct->next;
+
+ /* Handle the default ctor. */
+ if (tcd->cd->defctor == oct)
+ cd->defctor = nct;
+ }
+
+ cd->dealloccode = templateCode(pt, used, cd->dealloccode, type_names, type_values);
+ cd->dtorcode = templateCode(pt, used, cd->dtorcode, type_names, type_values);
+
+ /* Handle the methods. */
+ cd->members = instantiateTemplateMethods(tcd->cd->members, mod);
+ cd->overs = instantiateTemplateOverloads(pt, tcd->cd->overs,
+ tcd->cd->members, cd->members, tcd, td, cd, used, type_names,
+ type_values);
+
+ cd->cppcode = templateCode(pt, used, cd->cppcode, type_names, type_values);
+ cd->iff->hdrcode = templateCode(pt, used, cd->iff->hdrcode, type_names, type_values);
+ cd->convtosubcode = templateCode(pt, used, cd->convtosubcode, type_names, type_values);
+ cd->convtocode = templateCode(pt, used, cd->convtocode, type_names, type_values);
+ cd->travcode = templateCode(pt, used, cd->travcode, type_names, type_values);
+ cd->clearcode = templateCode(pt, used, cd->clearcode, type_names, type_values);
+ cd->getbufcode = templateCode(pt, used, cd->getbufcode, type_names, type_values);
+ cd->releasebufcode = templateCode(pt, used, cd->releasebufcode, type_names, type_values);
+ cd->readbufcode = templateCode(pt, used, cd->readbufcode, type_names, type_values);
+ cd->writebufcode = templateCode(pt, used, cd->writebufcode, type_names, type_values);
+ cd->segcountcode = templateCode(pt, used, cd->segcountcode, type_names, type_values);
+ cd->charbufcode = templateCode(pt, used, cd->charbufcode, type_names, type_values);
+ cd->picklecode = templateCode(pt, used, cd->picklecode, type_names, type_values);
+ cd->next = pt->classes;
+
+ pt->classes = cd;
+
+ tcd->sig.nrArgs--;
+
+ freeScopedName(type_names);
+ freeScopedName(type_values);
+}
+
+
+/*
+ * Instantiate the methods of a template class.
+ */
+static memberDef *instantiateTemplateMethods(memberDef *tmd, moduleDef *mod)
+{
+ memberDef *md, *methods, **mdtail;
+
+ methods = NULL;
+ mdtail = &methods;
+
+ for (md = tmd; md != NULL; md = md->next)
+ {
+ memberDef *nmd = sipMalloc(sizeof (memberDef));
+
+ /* Start with a shallow copy. */
+ *nmd = *md;
+
+ nmd->module = mod;
+
+ if (inMainModule())
+ setIsUsedName(nmd->pyname);
+
+ nmd->next = NULL;
+ *mdtail = nmd;
+ mdtail = &nmd->next;
+ }
+
+ return methods;
+}
+
+
+/*
+ * Instantiate the overloads of a template class.
+ */
+static overDef *instantiateTemplateOverloads(sipSpec *pt, overDef *tod,
+ memberDef *tmethods, memberDef *methods, classTmplDef *tcd,
+ templateDef *td, classDef *cd, ifaceFileList **used,
+ scopedNameDef *type_names, scopedNameDef *type_values)
+{
+ overDef *od, *overloads, **odtail;
+
+ overloads = NULL;
+ odtail = &overloads;
+
+ for (od = tod; od != NULL; od = od->next)
+ {
+ overDef *nod = sipMalloc(sizeof (overDef));
+ memberDef *nmd, *omd;
+
+ /* Start with a shallow copy. */
+ *nod = *od;
+
+ for (nmd = methods, omd = tmethods; omd != NULL; omd = omd->next, nmd = nmd->next)
+ if (omd == od->common)
+ {
+ nod->common = nmd;
+ break;
+ }
+
+ templateSignature(&nod->pysig, TRUE, tcd, td, cd);
+
+ if (od->cppsig == &od->pysig)
+ nod->cppsig = &nod->pysig;
+ else
+ {
+ nod->cppsig = sipMalloc(sizeof (signatureDef));
+
+ *nod->cppsig = *od->cppsig;
+
+ templateSignature(nod->cppsig, TRUE, tcd, td, cd);
+ }
+
+ nod->methodcode = templateCode(pt, used, nod->methodcode, type_names, type_values);
+
+ /* Handle any virtual handler. */
+ if (od->virthandler != NULL)
+ {
+ moduleDef *mod = cd->iff->module;
+
+ nod->virthandler = sipMalloc(sizeof (virtHandlerDef));
+
+ /* Start with a shallow copy. */
+ *nod->virthandler = *od->virthandler;
+
+ if (od->virthandler->cppsig == &od->pysig)
+ nod->virthandler->cppsig = &nod->pysig;
+ else
+ {
+ nod->virthandler->cppsig = sipMalloc(sizeof (signatureDef));
+
+ *nod->virthandler->cppsig = *od->virthandler->cppsig;
+
+ templateSignature(nod->virthandler->cppsig, TRUE, tcd, td, cd);
+ }
+
+ nod->virthandler->module = mod;
+ nod->virthandler->virtcode = templateCode(pt, used, nod->virthandler->virtcode, type_names, type_values);
+ nod->virthandler->next = mod->virthandlers;
+
+ mod->virthandlers = nod->virthandler;
+ }
+
+ nod->next = NULL;
+ *odtail = nod;
+ odtail = &nod->next;
+ }
+
+ return overloads;
+}
+
+
+/*
+ * Instantiate the enums of a template class.
+ */
+static void instantiateTemplateEnums(sipSpec *pt, classTmplDef *tcd,
+ templateDef *td, classDef *cd, ifaceFileList **used,
+ scopedNameDef *type_names, scopedNameDef *type_values)
+{
+ enumDef *ted;
+ moduleDef *mod = cd->iff->module;
+
+ for (ted = pt->enums; ted != NULL; ted = ted->next)
+ if (ted->ecd == tcd->cd)
+ {
+ enumDef *ed;
+ enumMemberDef *temd;
+
+ ed = sipMalloc(sizeof (enumDef));
+
+ /* Start with a shallow copy. */
+ *ed = *ted;
+
+ if (ed->fqcname != NULL)
+ {
+ ed->fqcname = text2scopedName(cd->iff,
+ scopedNameTail(ed->fqcname));
+ ed->cname = cacheName(pt, scopedNameToString(ed->fqcname));
+ }
+
+ if (inMainModule())
+ {
+ if (ed->pyname != NULL)
+ setIsUsedName(ed->pyname);
+
+ if (ed->cname != NULL)
+ setIsUsedName(ed->cname);
+ }
+
+ ed->ecd = cd;
+ ed->first_alt = ed;
+ ed->module = mod;
+ ed->members = NULL;
+
+ for (temd = ted->members; temd != NULL; temd = temd->next)
+ {
+ enumMemberDef *emd;
+
+ emd = sipMalloc(sizeof (enumMemberDef));
+
+ /* Start with a shallow copy. */
+ *emd = *temd;
+ emd->ed = ed;
+
+ emd->next = ed->members;
+ ed->members = emd;
+ }
+
+ ed->slots = instantiateTemplateMethods(ted->slots, mod);
+ ed->overs = instantiateTemplateOverloads(pt, ted->overs,
+ ted->slots, ed->slots, tcd, td, cd, used, type_names,
+ type_values);
+
+ ed->next = pt->enums;
+ pt->enums = ed;
+ }
+}
+
+
+/*
+ * Instantiate the variables of a template class.
+ */
+static void instantiateTemplateVars(sipSpec *pt, classTmplDef *tcd,
+ templateDef *td, classDef *cd, ifaceFileList **used,
+ scopedNameDef *type_names, scopedNameDef *type_values)
+{
+ varDef *tvd;
+
+ for (tvd = pt->vars; tvd != NULL; tvd = tvd->next)
+ if (tvd->ecd == tcd->cd)
+ {
+ varDef *vd;
+
+ vd = sipMalloc(sizeof (varDef));
+
+ /* Start with a shallow copy. */
+ *vd = *tvd;
+
+ if (inMainModule())
+ setIsUsedName(vd->pyname);
+
+ vd->fqcname = text2scopedName(cd->iff,
+ scopedNameTail(vd->fqcname));
+ vd->ecd = cd;
+ vd->module = cd->iff->module;
+
+ templateType(&vd->type, tcd, td, cd);
+
+ vd->accessfunc = templateCode(pt, used, vd->accessfunc, type_names, type_values);
+ vd->getcode = templateCode(pt, used, vd->getcode, type_names, type_values);
+ vd->setcode = templateCode(pt, used, vd->setcode, type_names, type_values);
+
+ addVariable(pt, vd);
+ }
+}
+
+
+/*
+ * Replace any template arguments in a signature.
+ */
+static void templateSignature(signatureDef *sd, int result, classTmplDef *tcd, templateDef *td, classDef *ncd)
+{
+ int a;
+
+ if (result)
+ templateType(&sd->result, tcd, td, ncd);
+
+ for (a = 0; a < sd->nrArgs; ++a)
+ templateType(&sd->args[a], tcd, td, ncd);
+}
+
+
+/*
+ * Replace any template arguments in a type.
+ */
+static void templateType(argDef *ad, classTmplDef *tcd, templateDef *td, classDef *ncd)
+{
+ int a;
+ char *name;
+
+ /* Descend into any sub-templates. */
+ if (ad->atype == template_type)
+ {
+ templateDef *new_td = sipMalloc(sizeof (templateDef));
+
+ /* Make a deep copy of the template definition. */
+ *new_td = *ad->u.td;
+ ad->u.td = new_td;
+
+ templateSignature(&ad->u.td->types, FALSE, tcd, td, ncd);
+
+ return;
+ }
+
+ /* Ignore if it isn't an unscoped name. */
+ if (ad->atype != defined_type || ad->u.snd->next != NULL)
+ return;
+
+ name = ad->u.snd->name;
+
+ for (a = 0; a < tcd->sig.nrArgs - 1; ++a)
+ if (strcmp(name, scopedNameTail(tcd->sig.args[a].u.snd)) == 0)
+ {
+ argDef *tad = &td->types.args[a];
+
+ ad->atype = tad->atype;
+
+ /* We take the constrained flag from the real type. */
+ resetIsConstrained(ad);
+
+ if (isConstrained(tad))
+ setIsConstrained(ad);
+
+ ad->u = tad->u;
+
+ return;
+ }
+
+ /* Handle the class name itself. */
+ if (strcmp(name, scopedNameTail(classFQCName(tcd->cd))) == 0)
+ {
+ ad->atype = class_type;
+ ad->u.cd = ncd;
+ ad->original_type = NULL;
+ }
+}
+
+
+/*
+ * Replace any template arguments in a literal code block.
+ */
+codeBlock *templateCode(sipSpec *pt, ifaceFileList **used, codeBlock *ocb,
+ scopedNameDef *names, scopedNameDef *values)
+{
+ codeBlock *ncb = NULL, **tail = &ncb;
+
+ while (ocb != NULL)
+ {
+ char *at = ocb->frag;
+
+ do
+ {
+ char *first = NULL;
+ codeBlock *cb;
+ scopedNameDef *nam, *val, *nam_first, *val_first;
+
+ /*
+ * Go through the rest of this fragment looking for each of the
+ * types and the name of the class itself.
+ */
+ nam = names;
+ val = values;
+
+ while (nam != NULL && val != NULL)
+ {
+ char *cp;
+
+ if ((cp = strstr(at, nam->name)) != NULL)
+ if (first == NULL || first > cp)
+ {
+ nam_first = nam;
+ val_first = val;
+ first = cp;
+ }
+
+ nam = nam->next;
+ val = val->next;
+ }
+
+ /* Create the new fragment. */
+ cb = sipMalloc(sizeof (codeBlock));
+
+ if (at == ocb->frag)
+ {
+ cb->filename = ocb->filename;
+ cb->linenr = ocb->linenr;
+ }
+ else
+ cb->filename = NULL;
+
+ cb->next = NULL;
+ *tail = cb;
+ tail = &cb->next;
+
+ /* See if anything was found. */
+ if (first == NULL)
+ {
+ /* We can just point to this. */
+ cb->frag = at;
+
+ /* All done with this one. */
+ at = NULL;
+ }
+ else
+ {
+ static char *gen_names[] = {
+ "sipType_",
+ "sipClass_",
+ "sipEnum_",
+ "sipException_",
+ NULL
+ };
+
+ char *dp, *sp, **gn;
+ int genname = FALSE;
+
+ /*
+ * If the context in which the text is used is in the name of a
+ * SIP generated object then translate any "::" scoping to "_".
+ */
+ for (gn = gen_names; *gn != NULL; ++gn)
+ if (search_back(first, at, *gn))
+ {
+ addUsedFromCode(pt, used, val_first->name);
+ genname = TRUE;
+ break;
+ }
+
+ /* Fragment the fragment. */
+ cb->frag = sipMalloc(first - at + strlen(val_first->name) + 1);
+
+ strncpy(cb->frag, at, first - at);
+
+ dp = &cb->frag[first - at];
+ sp = val_first->name;
+
+ if (genname)
+ {
+ char gch;
+
+ while ((gch = *sp++) != '\0')
+ if (gch == ':' && *sp == ':')
+ {
+ *dp++ = '_';
+ ++sp;
+ }
+ else
+ *dp++ = gch;
+
+ *dp = '\0';
+ }
+ else
+ strcpy(dp, sp);
+
+ /* Move past the replaced text. */
+ at = first + strlen(nam_first->name);
+ }
+ }
+ while (at != NULL && *at != '\0');
+
+ ocb = ocb->next;
+ }
+
+ return ncb;
+}
+
+
+/*
+ * Return TRUE if the text at the end of a string matches the target string.
+ */
+static int search_back(const char *end, const char *start, const char *target)
+{
+ size_t tlen = strlen(target);
+
+ if (start + tlen >= end)
+ return FALSE;
+
+ return (strncmp(end - tlen, target, tlen) == 0);
+}
+
+
+/*
+ * Add any needed interface files based on handwritten code.
+ */
+static void addUsedFromCode(sipSpec *pt, ifaceFileList **used, const char *sname)
+{
+ ifaceFileDef *iff;
+ enumDef *ed;
+
+ for (iff = pt->ifacefiles; iff != NULL; iff = iff->next)
+ {
+ if (iff->type != class_iface && iff->type != exception_iface)
+ continue;
+
+ if (sameName(iff->fqcname, sname))
+ {
+ addToUsedList(used, iff);
+ return;
+ }
+ }
+
+ for (ed = pt->enums; ed != NULL; ed = ed->next)
+ {
+ if (ed->ecd == NULL)
+ continue;
+
+ if (sameName(ed->fqcname, sname))
+ {
+ addToUsedList(used, ed->ecd->iff);
+ return;
+ }
+ }
+}
+
+
+/*
+ * Compare a scoped name with its string equivalent.
+ */
+static int sameName(scopedNameDef *snd, const char *sname)
+{
+ while (snd != NULL && *sname != '\0')
+ {
+ const char *sp = snd->name;
+
+ while (*sp != '\0' && *sname != ':' && *sname != '\0')
+ if (*sp++ != *sname++)
+ return FALSE;
+
+ if (*sp != '\0' || (*sname != ':' && *sname != '\0'))
+ return FALSE;
+
+ snd = snd->next;
+
+ if (*sname == ':')
+ sname += 2;
+ }
+
+ return (snd == NULL && *sname == '\0');
+}
+
+
+/*
+ * Compare a (possibly) relative scoped name with a fully qualified scoped name
+ * while taking the current scope into account.
+ */
+static int foundInScope(scopedNameDef *fq_name, scopedNameDef *rel_name)
+{
+ classDef *scope;
+
+ for (scope = currentScope(); scope != NULL; scope = scope->ecd)
+ {
+ scopedNameDef *snd;
+ int found;
+
+ snd = copyScopedName(classFQCName(scope));
+ appendScopedName(&snd, copyScopedName(rel_name));
+
+ found = (compareScopedNames(fq_name, snd) == 0);
+
+ freeScopedName(snd);
+
+ if (found)
+ return TRUE;
+ }
+
+ return compareScopedNames(fq_name, rel_name) == 0;
+}
+
+
+/*
+ * Create a new typedef.
+ */
+static void newTypedef(sipSpec *pt, moduleDef *mod, char *name, argDef *type,
+ optFlags *optflgs)
+{
+ typedefDef *td, **tdp;
+ scopedNameDef *fqname;
+ classDef *scope;
+
+ scope = currentScope();
+ fqname = text2scopedName((scope != NULL ? scope->iff : NULL), name);
+
+ /* See if we are instantiating a template class. */
+ if (type->atype == template_type)
+ {
+ classTmplDef *tcd;
+ templateDef *td = type->u.td;
+
+ for (tcd = pt->classtemplates; tcd != NULL; tcd = tcd->next)
+ if (foundInScope(tcd->cd->iff->fqcname, td->fqname) &&
+ sameTemplateSignature(&tcd->sig, &td->types, FALSE))
+ {
+ instantiateClassTemplate(pt, mod, scope, fqname, tcd, td);
+
+ /* All done. */
+ return;
+ }
+ }
+
+ /*
+ * Check it doesn't already exist and find the position in the sorted list
+ * where it should be put.
+ */
+ for (tdp = &pt->typedefs; *tdp != NULL; tdp = &(*tdp)->next)
+ {
+ int res = compareScopedNames((*tdp)->fqname, fqname);
+
+ if (res == 0)
+ {
+ fatalScopedName(fqname);
+ fatal(" already defined\n");
+ }
+
+ if (res > 0)
+ break;
+ }
+
+ td = sipMalloc(sizeof (typedefDef));
+
+ td->tdflags = 0;
+ td->fqname = fqname;
+ td->ecd = scope;
+ td->module = mod;
+ td->type = *type;
+
+ td->next = *tdp;
+ *tdp = td;
+
+ if (findOptFlag(optflgs, "NoTypeName", bool_flag) != NULL)
+ setNoTypeName(td);
+
+ mod->nrtypedefs++;
+}
+
+
+/*
+ * Speculatively try and resolve any typedefs. In some cases (eg. when
+ * comparing template signatures) it helps to use the real type if it is known.
+ * Note that this wouldn't be necessary if we required that all types be known
+ * before they are used.
+ */
+static void resolveAnyTypedef(sipSpec *pt, argDef *ad)
+{
+ argDef orig = *ad;
+
+ while (ad->atype == defined_type)
+ {
+ ad->atype = no_type;
+ searchTypedefs(pt, ad->u.snd, ad);
+
+ /*
+ * Don't resolve to a template type as it may be superceded later on
+ * by a more specific mapped type.
+ */
+ if (ad->atype == no_type || ad->atype == template_type)
+ {
+ *ad = orig;
+ break;
+ }
+ }
+}
+
+
+/*
+ * Return TRUE if the template signatures are the same. A deep comparison is
+ * used for mapped type templates where we want to recurse into any nested
+ * templates.
+ */
+int sameTemplateSignature(signatureDef *tmpl_sd, signatureDef *args_sd,
+ int deep)
+{
+ int a;
+
+ if (tmpl_sd->nrArgs != args_sd->nrArgs)
+ return FALSE;
+
+ for (a = 0; a < tmpl_sd->nrArgs; ++a)
+ {
+ argDef *tmpl_ad = &tmpl_sd->args[a];
+ argDef *args_ad = &args_sd->args[a];
+
+ /*
+ * If we are doing a shallow comparision (ie. for class templates) then
+ * a type name in the template signature matches anything in the
+ * argument signature.
+ */
+ if (tmpl_ad->atype == defined_type && !deep)
+ continue;
+
+ /*
+ * For type names only compare the references and pointers, and do the
+ * same for any nested templates.
+ */
+ if (tmpl_ad->atype == defined_type && args_ad->atype == defined_type)
+ {
+ if (isReference(tmpl_ad) != isReference(args_ad) || tmpl_ad->nrderefs != args_ad->nrderefs)
+ return FALSE;
+ }
+ else if (tmpl_ad->atype == template_type && args_ad->atype == template_type)
+ {
+ if (!sameTemplateSignature(&tmpl_ad->u.td->types, &args_ad->u.td->types, deep))
+ return FALSE;
+ }
+ else if (!sameBaseType(tmpl_ad, args_ad))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Create a new variable.
+ */
+static void newVar(sipSpec *pt,moduleDef *mod,char *name,int isstatic,
+ argDef *type,optFlags *of,codeBlock *acode,codeBlock *gcode,
+ codeBlock *scode)
+{
+ varDef *var;
+ classDef *escope = currentScope();
+ nameDef *nd = cacheName(pt,getPythonName(of,name));
+
+ if (inMainModule())
+ setIsUsedName(nd);
+
+ checkAttributes(pt, mod, escope, NULL, nd->text, FALSE);
+
+ var = sipMalloc(sizeof (varDef));
+
+ var->pyname = nd;
+ var->fqcname = text2scopedName((escope != NULL ? escope->iff : NULL),
+ name);
+ var->ecd = escope;
+ var->module = mod;
+ var->varflags = 0;
+ var->type = *type;
+ var->accessfunc = acode;
+ var->getcode = gcode;
+ var->setcode = scode;
+
+ if (isstatic || (escope != NULL && escope->iff->type == namespace_iface))
+ setIsStaticVar(var);
+
+ addVariable(pt, var);
+}
+
+
+/*
+ * Create a new ctor.
+ */
+static void newCtor(char *name, int sectFlags, signatureDef *args,
+ optFlags *optflgs, codeBlock *methodcode, throwArgs *exceptions,
+ signatureDef *cppsig, int explicit, codeBlock *docstring)
+{
+ ctorDef *ct, **ctp;
+ classDef *cd = currentScope();
+
+ /* Check the name of the constructor. */
+ if (strcmp(classBaseName(cd), name) != 0)
+ yyerror("Constructor doesn't have the same name as its class");
+
+ if (docstring != NULL)
+ appendCodeBlock(&cd->docstring, docstring);
+
+ /* Add to the list of constructors. */
+ ct = sipMalloc(sizeof (ctorDef));
+
+ if (sectFlags & SECT_IS_PROT && makeProtPublic)
+ {
+ sectFlags &= ~SECT_IS_PROT;
+ sectFlags |= SECT_IS_PUBLIC;
+ }
+
+ /* Allow the signature to be used like an function signature. */
+ memset(&args->result, 0, sizeof (argDef));
+ args->result.atype = void_type;
+
+ ct->ctorflags = sectFlags;
+ ct->api_range = getAPIRange(optflgs);
+ ct->pysig = *args;
+ ct->cppsig = (cppsig != NULL ? cppsig : &ct->pysig);
+ ct->exceptions = exceptions;
+ ct->methodcode = methodcode;
+
+ if (!isPrivateCtor(ct))
+ setCanCreate(cd);
+
+ if (isProtectedCtor(ct))
+ setHasShadow(cd);
+
+ if (explicit)
+ setIsExplicitCtor(ct);
+
+ getHooks(optflgs, &ct->prehook, &ct->posthook);
+
+ if (getReleaseGIL(optflgs))
+ setIsReleaseGILCtor(ct);
+ else if (getHoldGIL(optflgs))
+ setIsHoldGILCtor(ct);
+
+ if (getTransfer(optflgs))
+ setIsResultTransferredCtor(ct);
+
+ if (getDeprecated(optflgs))
+ setIsDeprecatedCtor(ct);
+
+ if (!isPrivateCtor(ct) && usesKeywordArgs(optflgs, &ct->pysig))
+ setUseKeywordArgsCtor(ct);
+
+ if (findOptFlag(optflgs, "NoDerived", bool_flag) != NULL)
+ {
+ if (cppsig != NULL)
+ yyerror("The /NoDerived/ annotation cannot be used with a C++ signature");
+
+ if (methodcode == NULL)
+ yyerror("The /NoDerived/ annotation must be used with %MethodCode");
+
+ ct->cppsig = NULL;
+ }
+
+ if (findOptFlag(optflgs, "Default", bool_flag) != NULL)
+ {
+ if (cd->defctor != NULL)
+ yyerror("A constructor with the /Default/ annotation has already been defined");
+
+ cd->defctor = ct;
+ }
+
+ /* Append to the list. */
+ for (ctp = &cd->ctors; *ctp != NULL; ctp = &(*ctp)->next)
+ ;
+
+ *ctp = ct;
+}
+
+
+/*
+ * Create a new function.
+ */
+static void newFunction(sipSpec *pt, moduleDef *mod, classDef *c_scope,
+ mappedTypeDef *mt_scope, int sflags, int isstatic, int issignal,
+ int isslot, int isvirt, char *name, signatureDef *sig, int isconst,
+ int isabstract, optFlags *optflgs, codeBlock *methodcode,
+ codeBlock *vcode, throwArgs *exceptions, signatureDef *cppsig,
+ codeBlock *docstring)
+{
+ int factory, xferback, no_arg_parser;
+ overDef *od, **odp, **headp;
+ optFlag *of;
+ virtHandlerDef *vhd;
+
+ /* Extra checks for a C module. */
+ if (pt->genc)
+ {
+ if (c_scope != NULL)
+ yyerror("Function declaration not allowed in a struct in a C module");
+
+ if (isstatic)
+ yyerror("Static functions not allowed in a C module");
+
+ if (exceptions != NULL)
+ yyerror("Exceptions not allowed in a C module");
+ }
+
+ if (mt_scope != NULL)
+ headp = &mt_scope->overs;
+ else if (c_scope != NULL)
+ headp = &c_scope->overs;
+ else
+ headp = &mod->overs;
+
+ /* See if it is a factory method. */
+ if (findOptFlag(optflgs, "Factory", bool_flag) != NULL)
+ factory = TRUE;
+ else
+ {
+ int a;
+
+ factory = FALSE;
+
+ /* Check /TransferThis/ wasn't specified. */
+ if (c_scope == NULL || isstatic)
+ for (a = 0; a < sig->nrArgs; ++a)
+ if (isThisTransferred(&sig->args[a]))
+ yyerror("/TransferThis/ may only be specified in constructors and class methods");
+ }
+
+ /* See if the result is to be returned to Python ownership. */
+ xferback = (findOptFlag(optflgs, "TransferBack", bool_flag) != NULL);
+
+ if (factory && xferback)
+ yyerror("/TransferBack/ and /Factory/ cannot both be specified");
+
+ /* Create a new overload definition. */
+
+ od = sipMalloc(sizeof (overDef));
+
+ /* Set the overload flags. */
+
+ if ((sflags & SECT_IS_PROT) && makeProtPublic)
+ {
+ sflags &= ~SECT_IS_PROT;
+ sflags |= SECT_IS_PUBLIC | OVER_REALLY_PROT;
+ }
+
+ od->overflags = sflags;
+
+ if (issignal)
+ {
+ resetIsSlot(od);
+ setIsSignal(od);
+ }
+ else if (isslot)
+ {
+ resetIsSignal(od);
+ setIsSlot(od);
+ }
+
+ if (factory)
+ setIsFactory(od);
+
+ if (xferback)
+ setIsResultTransferredBack(od);
+
+ if (getTransfer(optflgs))
+ setIsResultTransferred(od);
+
+ if (findOptFlag(optflgs, "TransferThis", bool_flag) != NULL)
+ setIsThisTransferredMeth(od);
+
+ if (isProtected(od))
+ setHasShadow(c_scope);
+
+ if ((isSlot(od) || isSignal(od)) && !isPrivate(od))
+ {
+ if (isSignal(od))
+ setHasShadow(c_scope);
+
+ pt->sigslots = TRUE;
+ }
+
+ if (isSignal(od) && (methodcode != NULL || vcode != NULL))
+ yyerror("Cannot provide code for signals");
+
+ if (isstatic)
+ {
+ if (isSignal(od))
+ yyerror("Static functions cannot be signals");
+
+ if (isvirt)
+ yyerror("Static functions cannot be virtual");
+
+ setIsStatic(od);
+ }
+
+ if (isconst)
+ setIsConst(od);
+
+ if (isabstract)
+ {
+ if (sflags == 0)
+ yyerror("Non-class function specified as abstract");
+
+ setIsAbstract(od);
+ }
+
+ if ((of = findOptFlag(optflgs, "AutoGen", opt_name_flag)) != NULL)
+ {
+ if (of->fvalue.sval == NULL || isEnabledFeature(of->fvalue.sval))
+ setIsAutoGen(od);
+ }
+
+ if (isvirt)
+ {
+ if (isSignal(od) && pluginPyQt3(pt))
+ yyerror("Virtual signals aren't supported");
+
+ setIsVirtual(od);
+ setHasShadow(c_scope);
+
+ vhd = sipMalloc(sizeof (virtHandlerDef));
+
+ vhd->virthandlernr = -1;
+ vhd->vhflags = 0;
+ vhd->pysig = &od->pysig;
+ vhd->cppsig = (cppsig != NULL ? cppsig : &od->pysig);
+ vhd->virtcode = vcode;
+
+ if (factory || xferback)
+ setIsTransferVH(vhd);
+
+ /*
+ * Only add it to the module's virtual handlers if we are not in a
+ * class template.
+ */
+ if (!currentIsTemplate)
+ {
+ vhd->module = mod;
+
+ vhd->next = mod->virthandlers;
+ mod->virthandlers = vhd;
+ }
+ }
+ else
+ {
+ if (vcode != NULL)
+ yyerror("%VirtualCatcherCode provided for non-virtual function");
+
+ vhd = NULL;
+ }
+
+ od->cppname = name;
+ od->pysig = *sig;
+ od->cppsig = (cppsig != NULL ? cppsig : &od->pysig);
+ od->exceptions = exceptions;
+ od->methodcode = methodcode;
+ od->virthandler = vhd;
+
+ no_arg_parser = (findOptFlag(optflgs, "NoArgParser", bool_flag) != NULL);
+
+ if (no_arg_parser)
+ {
+ if (methodcode == NULL)
+ yyerror("%MethodCode must be supplied if /NoArgParser/ is specified");
+ }
+
+ if (findOptFlag(optflgs, "NoCopy", bool_flag) != NULL)
+ setNoCopy(&od->pysig.result);
+
+ od->common = findFunction(pt, mod, c_scope, mt_scope,
+ getPythonName(optflgs, name), (methodcode != NULL), sig->nrArgs,
+ no_arg_parser);
+
+ if (docstring != NULL)
+ appendCodeBlock(&od->common->docstring, docstring);
+
+ od->api_range = getAPIRange(optflgs);
+
+ if (od->api_range == NULL)
+ setNotVersioned(od->common);
+
+ if (findOptFlag(optflgs, "Numeric", bool_flag) != NULL)
+ setIsNumeric(od->common);
+
+ /* Methods that run in new threads must be virtual. */
+ if (findOptFlag(optflgs, "NewThread", bool_flag) != NULL)
+ {
+ argDef *res;
+
+ if (!isvirt)
+ yyerror("/NewThread/ may only be specified for virtual functions");
+
+ /*
+ * This is an arbitary limitation to make the code generator slightly
+ * easier - laziness on my part.
+ */
+ res = &od->cppsig->result;
+
+ if (res->atype != void_type || res->nrderefs != 0)
+ yyerror("/NewThread/ may only be specified for void functions");
+
+ setIsNewThread(od);
+ }
+
+ getHooks(optflgs, &od->prehook, &od->posthook);
+
+ if (getReleaseGIL(optflgs))
+ setIsReleaseGIL(od);
+ else if (getHoldGIL(optflgs))
+ setIsHoldGIL(od);
+
+ if (getDeprecated(optflgs))
+ setIsDeprecated(od);
+
+ if (!isPrivate(od) && !isSignal(od) && od->common->slot == no_slot && usesKeywordArgs(optflgs, &od->pysig))
+ {
+ setUseKeywordArgs(od);
+ setUseKeywordArgsFunction(od->common);
+ }
+
+ /* See if we want to auto-generate a __len__() method. */
+ if (findOptFlag(optflgs, "__len__", bool_flag) != NULL)
+ {
+ overDef *len;
+
+ len = sipMalloc(sizeof (overDef));
+
+ len->cppname = "__len__";
+ len->overflags = SECT_IS_PUBLIC;
+ len->pysig.result.atype = ssize_type;
+ len->pysig.nrArgs = 0;
+ len->cppsig = &len->pysig;
+
+ len->common = findFunction(pt, mod, c_scope, mt_scope, len->cppname,
+ TRUE, 0, FALSE);
+
+ if ((len->methodcode = od->methodcode) == NULL)
+ {
+ char *buf = sipStrdup(" sipRes = (SIP_SSIZE_T)sipCpp->");
+ codeBlock *code;
+
+ append(&buf, od->cppname);
+ append(&buf, "();\n");
+
+ code = sipMalloc(sizeof (codeBlock));
+
+ code->frag = buf;
+ code->filename = "Auto-generated";
+ code->linenr = 0;
+ code->next = NULL;
+
+ len->methodcode = code;
+ }
+
+ len->next = NULL;
+
+ od->next = len;
+ }
+ else
+ {
+ od->next = NULL;
+ }
+
+ /* Append to the list. */
+ for (odp = headp; *odp != NULL; odp = &(*odp)->next)
+ ;
+
+ *odp = od;
+}
+
+
+/*
+ * Return the Python name based on the C/C++ name and any /PyName/ annotation.
+ */
+static const char *getPythonName(optFlags *optflgs, const char *cname)
+{
+ const char *pname;
+ optFlag *of;
+
+ if ((of = findOptFlag(optflgs, "PyName", name_flag)) != NULL)
+ pname = of->fvalue.sval;
+ else
+ pname = cname;
+
+ return pname;
+}
+
+
+/*
+ * Cache a name in a module. Entries in the cache are stored in order of
+ * decreasing length.
+ */
+nameDef *cacheName(sipSpec *pt, const char *name)
+{
+ nameDef *nd, **ndp;
+ size_t len;
+
+ /* Allow callers to be lazy about checking if there is really a name. */
+ if (name == NULL)
+ return NULL;
+
+ /* Skip entries that are too large. */
+ ndp = &pt->namecache;
+ len = strlen(name);
+
+ while (*ndp != NULL && (*ndp)->len > len)
+ ndp = &(*ndp)->next;
+
+ /* Check entries that are the right length. */
+ for (nd = *ndp; nd != NULL && nd->len == len; nd = nd->next)
+ if (memcmp(nd->text, name, len) == 0)
+ return nd;
+
+ /* Create a new one. */
+ nd = sipMalloc(sizeof (nameDef));
+
+ nd->nameflags = 0;
+ nd->text = name;
+ nd->len = len;
+ nd->next = *ndp;
+
+ *ndp = nd;
+
+ return nd;
+}
+
+
+/*
+ * Find (or create) an overloaded function name.
+ */
+static memberDef *findFunction(sipSpec *pt, moduleDef *mod, classDef *c_scope,
+ mappedTypeDef *mt_scope, const char *pname, int hwcode, int nrargs,
+ int no_arg_parser)
+{
+ static struct slot_map {
+ const char *name; /* The slot name. */
+ slotType type; /* The corresponding type. */
+ int needs_hwcode; /* Set if handwritten code is required. */
+ int nrargs; /* Nr. of arguments. */
+ } slot_table[] = {
+ {"__str__", str_slot, TRUE, 0},
+ {"__unicode__", unicode_slot, TRUE, 0},
+ {"__int__", int_slot, FALSE, 0},
+ {"__long__", long_slot, FALSE, 0},
+ {"__float__", float_slot, FALSE, 0},
+ {"__len__", len_slot, TRUE, 0},
+ {"__contains__", contains_slot, TRUE, 1},
+ {"__add__", add_slot, FALSE, 1},
+ {"__sub__", sub_slot, FALSE, 1},
+ {"__mul__", mul_slot, FALSE, 1},
+ {"__div__", div_slot, FALSE, 1},
+ {"__mod__", mod_slot, FALSE, 1},
+ {"__floordiv__", floordiv_slot, TRUE, 1},
+ {"__truediv__", truediv_slot, FALSE, 1},
+ {"__and__", and_slot, FALSE, 1},
+ {"__or__", or_slot, FALSE, 1},
+ {"__xor__", xor_slot, FALSE, 1},
+ {"__lshift__", lshift_slot, FALSE, 1},
+ {"__rshift__", rshift_slot, FALSE, 1},
+ {"__iadd__", iadd_slot, FALSE, 1},
+ {"__isub__", isub_slot, FALSE, 1},
+ {"__imul__", imul_slot, FALSE, 1},
+ {"__idiv__", idiv_slot, FALSE, 1},
+ {"__imod__", imod_slot, FALSE, 1},
+ {"__ifloordiv__", ifloordiv_slot, TRUE, 1},
+ {"__itruediv__", itruediv_slot, FALSE, 1},
+ {"__iand__", iand_slot, FALSE, 1},
+ {"__ior__", ior_slot, FALSE, 1},
+ {"__ixor__", ixor_slot, FALSE, 1},
+ {"__ilshift__", ilshift_slot, FALSE, 1},
+ {"__irshift__", irshift_slot, FALSE, 1},
+ {"__invert__", invert_slot, FALSE, 0},
+ {"__call__", call_slot, FALSE, -1},
+ {"__getitem__", getitem_slot, FALSE, 1},
+ {"__setitem__", setitem_slot, TRUE, 2},
+ {"__delitem__", delitem_slot, TRUE, 1},
+ {"__lt__", lt_slot, FALSE, 1},
+ {"__le__", le_slot, FALSE, 1},
+ {"__eq__", eq_slot, FALSE, 1},
+ {"__ne__", ne_slot, FALSE, 1},
+ {"__gt__", gt_slot, FALSE, 1},
+ {"__ge__", ge_slot, FALSE, 1},
+ {"__cmp__", cmp_slot, FALSE, 1},
+ {"__bool__", bool_slot, TRUE, 0},
+ {"__nonzero__", bool_slot, TRUE, 0},
+ {"__neg__", neg_slot, FALSE, 0},
+ {"__pos__", pos_slot, FALSE, 0},
+ {"__abs__", abs_slot, TRUE, 0},
+ {"__repr__", repr_slot, TRUE, 0},
+ {"__hash__", hash_slot, TRUE, 0},
+ {"__index__", index_slot, TRUE, 0},
+ {"__iter__", iter_slot, TRUE, 0},
+ {"__next__", next_slot, TRUE, 0},
+ {NULL}
+ };
+
+ memberDef *md, **flist;
+ struct slot_map *sm;
+ slotType st;
+
+ /* Get the slot type. */
+ st = no_slot;
+
+ for (sm = slot_table; sm->name != NULL; ++sm)
+ if (strcmp(sm->name, pname) == 0)
+ {
+ if (sm->needs_hwcode && !hwcode)
+ yyerror("This Python slot requires %MethodCode");
+
+ if (sm->nrargs >= 0)
+ {
+ if (mt_scope == NULL && c_scope == NULL)
+ {
+ /* Global operators need one extra argument. */
+ if (sm -> nrargs + 1 != nrargs)
+ yyerror("Incorrect number of arguments to global operator");
+ }
+ else if (sm->nrargs != nrargs)
+ yyerror("Incorrect number of arguments to Python slot");
+ }
+
+ st = sm->type;
+
+ break;
+ }
+
+ /* Check there is no name clash. */
+ checkAttributes(pt, mod, c_scope, mt_scope, pname, TRUE);
+
+ /* See if it already exists. */
+ if (mt_scope != NULL)
+ flist = &mt_scope->members;
+ else if (c_scope != NULL)
+ flist = &c_scope->members;
+ else
+ flist = &mod->othfuncs;
+
+ for (md = *flist; md != NULL; md = md->next)
+ if (strcmp(md->pyname->text, pname) == 0 && md->module == mod)
+ break;
+
+ if (md == NULL)
+ {
+ /* Create a new one. */
+ md = sipMalloc(sizeof (memberDef));
+
+ md->pyname = cacheName(pt, pname);
+ md->memberflags = 0;
+ md->slot = st;
+ md->module = mod;
+ md->next = *flist;
+
+ *flist = md;
+
+ if (inMainModule())
+ setIsUsedName(md->pyname);
+
+ if (no_arg_parser)
+ setNoArgParser(md);
+ }
+ else if (noArgParser(md))
+ yyerror("Another overload has already been defined that is annotated as /NoArgParser/");
+
+ /* Global operators are a subset. */
+ if (mt_scope == NULL && c_scope == NULL && st != no_slot && st != neg_slot && st != pos_slot && !isNumberSlot(md) && !isRichCompareSlot(md))
+ yyerror("Global operators must be either numeric or comparison operators");
+
+ return md;
+}
+
+
+/*
+ * Search a set of flags for a particular one and check its type.
+ */
+static optFlag *findOptFlag(optFlags *flgs,char *name,flagType ft)
+{
+ int f;
+
+ for (f = 0; f < flgs -> nrFlags; ++f)
+ {
+ optFlag *of = &flgs -> flags[f];
+
+ if (strcmp(of -> fname,name) == 0)
+ {
+ /*
+ * An optional name can look like a boolean or a name.
+ */
+
+ if (ft == opt_name_flag)
+ {
+ if (of -> ftype == bool_flag)
+ {
+ of -> ftype = opt_name_flag;
+ of -> fvalue.sval = NULL;
+ }
+ else if (of -> ftype == name_flag)
+ of -> ftype = opt_name_flag;
+ }
+
+ if (ft != of -> ftype)
+ yyerror("Optional flag has a value of the wrong type");
+
+ return of;
+ }
+ }
+
+ return NULL;
+}
+
+
+/*
+ * A name is going to be used as a Python attribute name within a Python scope
+ * (ie. a Python dictionary), so check against what we already know is going in
+ * the same scope in case there is a clash.
+ */
+static void checkAttributes(sipSpec *pt, moduleDef *mod, classDef *py_c_scope,
+ mappedTypeDef *py_mt_scope, const char *attr, int isfunc)
+{
+ enumDef *ed;
+ varDef *vd;
+ classDef *cd;
+
+ /* Check the enums. */
+
+ for (ed = pt->enums; ed != NULL; ed = ed->next)
+ {
+ enumMemberDef *emd;
+
+ if (ed->pyname == NULL)
+ continue;
+
+ if (py_c_scope != NULL)
+ {
+ if (ed->ecd != py_c_scope)
+ continue;
+ }
+ else if (py_mt_scope != NULL)
+ {
+ if (ed->emtd != py_mt_scope)
+ continue;
+ }
+ else if (ed->ecd != NULL || ed->emtd != NULL)
+ {
+ continue;
+ }
+
+ if (strcmp(ed->pyname->text, attr) == 0)
+ yyerror("There is already an enum in scope with the same Python name");
+
+ for (emd = ed->members; emd != NULL; emd = emd->next)
+ if (strcmp(emd->pyname->text, attr) == 0)
+ yyerror("There is already an enum member in scope with the same Python name");
+ }
+
+ /*
+ * Only check the members if this attribute isn't a member because we
+ * can handle members with the same name in the same scope.
+ */
+ if (!isfunc)
+ {
+ memberDef *md, *membs;
+ overDef *overs;
+
+ if (py_mt_scope != NULL)
+ {
+ membs = py_mt_scope->members;
+ overs = py_mt_scope->overs;
+ }
+ else if (py_c_scope != NULL)
+ {
+ membs = py_c_scope->members;
+ overs = py_c_scope->overs;
+ }
+ else
+ {
+ membs = mod->othfuncs;
+ overs = mod->overs;
+ }
+
+ for (md = membs; md != NULL; md = md->next)
+ {
+ overDef *od;
+
+ if (strcmp(md->pyname->text, attr) != 0)
+ continue;
+
+ /* Check for a conflict with all overloads. */
+ for (od = overs; od != NULL; od = od->next)
+ {
+ if (od->common != md)
+ continue;
+
+ yyerror("There is already a function in scope with the same Python name");
+ }
+ }
+ }
+
+ /* If the scope was a mapped type then that's all we have to check. */
+ if (py_mt_scope != NULL)
+ return;
+
+ /* Check the variables. */
+ for (vd = pt->vars; vd != NULL; vd = vd->next)
+ {
+ if (vd->ecd != py_c_scope)
+ continue;
+
+ if (strcmp(vd->pyname->text,attr) == 0)
+ yyerror("There is already a variable in scope with the same Python name");
+ }
+
+ /* Check the classes. */
+ for (cd = pt->classes; cd != NULL; cd = cd->next)
+ {
+ if (cd->ecd != py_c_scope || cd->pyname == NULL)
+ continue;
+
+ if (strcmp(cd->pyname->text, attr) == 0 && !isExternal(cd))
+ yyerror("There is already a class or namespace in scope with the same Python name");
+ }
+
+ /* Check the exceptions. */
+ if (py_c_scope == NULL)
+ {
+ exceptionDef *xd;
+
+ for (xd = pt->exceptions; xd != NULL; xd = xd->next)
+ if (xd->pyname != NULL && strcmp(xd->pyname, attr) == 0)
+ yyerror("There is already an exception with the same Python name");
+ }
+}
+
+
+/*
+ * Append a code block to a list of them. Append is needed to give the
+ * specifier easy control over the order of the documentation.
+ */
+void appendCodeBlock(codeBlock **headp, codeBlock *new)
+{
+ while (*headp != NULL)
+ headp = &(*headp)->next;
+
+ *headp = new;
+}
+
+
+/*
+ * Handle the end of a fully parsed a file.
+ */
+static void handleEOF()
+{
+ /*
+ * Check that the number of nested if's is the same as when we started
+ * the file.
+ */
+
+ if (skipStackPtr > currentContext.ifdepth)
+ fatal("Too many %%If statements in %s\n", previousFile);
+
+ if (skipStackPtr < currentContext.ifdepth)
+ fatal("Too many %%End statements in %s\n", previousFile);
+}
+
+
+/*
+ * Handle the end of a fully parsed a module.
+ */
+static void handleEOM()
+{
+ moduleDef *from;
+
+ /* Check it has been named. */
+ if (currentModule->name == NULL)
+ fatal("No %%Module has been specified for module defined in %s\n",
+ previousFile);
+
+ from = currentContext.prevmod;
+
+ if (from != NULL && from->encoding == no_type)
+ from->encoding = currentModule->encoding;
+
+ /* The previous module is now current. */
+ currentModule = from;
+}
+
+
+/*
+ * Find an existing qualifier.
+ */
+static qualDef *findQualifier(const char *name)
+{
+ moduleDef *mod;
+
+ for (mod = currentSpec->modules; mod != NULL; mod = mod->next)
+ {
+ qualDef *qd;
+
+ for (qd = mod->qualifiers; qd != NULL; qd = qd->next)
+ if (strcmp(qd->name, name) == 0)
+ return qd;
+ }
+
+ return NULL;
+}
+
+
+/*
+ * Find an existing API.
+ */
+apiVersionRangeDef *findAPI(sipSpec *pt, const char *name)
+{
+ moduleDef *mod;
+
+ for (mod = pt->modules; mod != NULL; mod = mod->next)
+ {
+ apiVersionRangeDef *avd;
+
+ for (avd = mod->api_versions; avd != NULL; avd = avd->next)
+ if (strcmp(avd->api_name->text, name) == 0)
+ return avd;
+ }
+
+ return NULL;
+}
+
+
+/*
+ * Return a copy of a scoped name.
+ */
+scopedNameDef *copyScopedName(scopedNameDef *snd)
+{
+ scopedNameDef *head;
+
+ head = NULL;
+
+ while (snd != NULL)
+ {
+ appendScopedName(&head,text2scopePart(snd -> name));
+ snd = snd -> next;
+ }
+
+ return head;
+}
+
+
+/*
+ * Append a name to a list of scopes.
+ */
+void appendScopedName(scopedNameDef **headp,scopedNameDef *newsnd)
+{
+ while (*headp != NULL)
+ headp = &(*headp) -> next;
+
+ *headp = newsnd;
+}
+
+
+/*
+ * Free a scoped name - but not the text itself.
+ */
+void freeScopedName(scopedNameDef *snd)
+{
+ while (snd != NULL)
+ {
+ scopedNameDef *next = snd -> next;
+
+ free(snd);
+
+ snd = next;
+ }
+}
+
+
+/*
+ * Convert a text string to a scope part structure.
+ */
+static scopedNameDef *text2scopePart(char *text)
+{
+ scopedNameDef *snd;
+
+ snd = sipMalloc(sizeof (scopedNameDef));
+
+ snd->name = text;
+ snd->next = NULL;
+
+ return snd;
+}
+
+
+/*
+ * Convert a text string to a fully scoped name.
+ */
+static scopedNameDef *text2scopedName(ifaceFileDef *scope, char *text)
+{
+ return scopeScopedName(scope, text2scopePart(text));
+}
+
+
+/*
+ * Prepend any current scope to a scoped name.
+ */
+static scopedNameDef *scopeScopedName(ifaceFileDef *scope, scopedNameDef *name)
+{
+ scopedNameDef *snd;
+
+ snd = (scope != NULL ? copyScopedName(scope->fqcname) : NULL);
+
+ appendScopedName(&snd, name);
+
+ return snd;
+}
+
+
+/*
+ * Return a pointer to the tail part of a scoped name.
+ */
+char *scopedNameTail(scopedNameDef *snd)
+{
+ if (snd == NULL)
+ return NULL;
+
+ while (snd -> next != NULL)
+ snd = snd -> next;
+
+ return snd -> name;
+}
+
+
+/*
+ * Push the given scope onto the scope stack.
+ */
+static void pushScope(classDef *scope)
+{
+ if (currentScopeIdx >= MAX_NESTED_SCOPE)
+ fatal("Internal error: increase the value of MAX_NESTED_SCOPE\n");
+
+ scopeStack[currentScopeIdx] = scope;
+ sectFlagsStack[currentScopeIdx] = sectionFlags;
+
+ ++currentScopeIdx;
+}
+
+
+/*
+ * Pop the scope stack.
+ */
+static void popScope(void)
+{
+ if (currentScopeIdx > 0)
+ sectionFlags = sectFlagsStack[--currentScopeIdx];
+}
+
+
+/*
+ * Return non-zero if the current input should be parsed rather than be
+ * skipped.
+ */
+static int notSkipping()
+{
+ return (skipStackPtr == 0 ? TRUE : skipStack[skipStackPtr - 1]);
+}
+
+
+/*
+ * Return the value of an expression involving a time period.
+ */
+static int timePeriod(char *lname,char *uname)
+{
+ int this, line;
+ qualDef *qd, *lower, *upper;
+ moduleDef *mod;
+
+ if (lname == NULL)
+ lower = NULL;
+ else if ((lower = findQualifier(lname)) == NULL || lower -> qtype != time_qualifier)
+ yyerror("Lower bound is not a time version");
+
+ if (uname == NULL)
+ upper = NULL;
+ else if ((upper = findQualifier(uname)) == NULL || upper -> qtype != time_qualifier)
+ yyerror("Upper bound is not a time version");
+
+ /* Sanity checks on the bounds. */
+
+ if (lower == NULL && upper == NULL)
+ yyerror("Lower and upper bounds cannot both be omitted");
+
+ if (lower != NULL && upper != NULL)
+ {
+ if (lower -> module != upper -> module || lower -> line != upper -> line)
+ yyerror("Lower and upper bounds are from different timelines");
+
+ if (lower == upper)
+ yyerror("Lower and upper bounds must be different");
+
+ if (lower -> order > upper -> order)
+ yyerror("Later version specified as lower bound");
+ }
+
+ /* Go through each slot in the relevant timeline. */
+
+ if (lower != NULL)
+ {
+ mod = lower -> module;
+ line = lower -> line;
+ }
+ else
+ {
+ mod = upper -> module;
+ line = upper -> line;
+ }
+
+ this = FALSE;
+
+ for (qd = mod -> qualifiers; qd != NULL; qd = qd -> next)
+ {
+ if (qd -> qtype != time_qualifier || qd -> line != line)
+ continue;
+
+ if (lower != NULL && qd -> order < lower -> order)
+ continue;
+
+ if (upper != NULL && qd -> order >= upper -> order)
+ continue;
+
+ /*
+ * This is within the required range so if it is also needed
+ * then the expression is true.
+ */
+
+ if (isNeeded(qd))
+ {
+ this = TRUE;
+ break;
+ }
+ }
+
+ return this;
+}
+
+
+/*
+ * Return the value of an expression involving a single platform or feature.
+ */
+static int platOrFeature(char *name,int optnot)
+{
+ int this;
+ qualDef *qd;
+
+ if ((qd = findQualifier(name)) == NULL || qd -> qtype == time_qualifier)
+ yyerror("No such platform or feature");
+
+ /* Assume this sub-expression is false. */
+
+ this = FALSE;
+
+ if (qd -> qtype == feature_qualifier)
+ {
+ if (!excludedFeature(excludedQualifiers,qd))
+ this = TRUE;
+ }
+ else if (isNeeded(qd))
+ this = TRUE;
+
+ if (optnot)
+ this = !this;
+
+ return this;
+}
+
+
+/*
+ * Return TRUE if the given qualifier is excluded.
+ */
+int excludedFeature(stringList *xsl,qualDef *qd)
+{
+ while (xsl != NULL)
+ {
+ if (strcmp(qd -> name,xsl -> s) == 0)
+ return TRUE;
+
+ xsl = xsl -> next;
+ }
+
+ return FALSE;
+}
+
+
+/*
+ * Return TRUE if the given qualifier is needed.
+ */
+static int isNeeded(qualDef *qd)
+{
+ stringList *sl;
+
+ for (sl = neededQualifiers; sl != NULL; sl = sl -> next)
+ if (strcmp(qd -> name,sl -> s) == 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+
+/*
+ * Return the current scope. currentScope() is only valid if notSkipping()
+ * returns non-zero.
+ */
+static classDef *currentScope(void)
+{
+ return (currentScopeIdx > 0 ? scopeStack[currentScopeIdx - 1] : NULL);
+}
+
+
+/*
+ * Create a new qualifier.
+ */
+static void newQualifier(moduleDef *mod, int line, int order, char *name,
+ qualType qt)
+{
+ qualDef *qd;
+
+ /* Check it doesn't already exist. */
+
+ if (findQualifier(name) != NULL)
+ yyerror("Version is already defined");
+
+ qd = sipMalloc(sizeof (qualDef));
+ qd->name = name;
+ qd->qtype = qt;
+ qd->module = mod;
+ qd->line = line;
+ qd->order = order;
+ qd->next = mod -> qualifiers;
+ mod->qualifiers = qd;
+}
+
+
+/*
+ * Create a new imported module.
+ */
+static void newImport(char *filename)
+{
+ moduleDef *from, *mod;
+ moduleListDef *mld;
+
+ /* Create a new module if it has not already been defined. */
+ for (mod = currentSpec->modules; mod != NULL; mod = mod->next)
+ if (strcmp(mod->file, filename) == 0)
+ break;
+
+ from = currentModule;
+
+ if (mod == NULL)
+ {
+ newModule(NULL, filename);
+ mod = currentModule;
+ }
+ else if (from->encoding == no_type)
+ {
+ /* Import any defaults from the already parsed module. */
+ from->encoding = mod->encoding;
+ }
+
+ /* Add the new import unless it has already been imported. */
+ for (mld = from->imports; mld != NULL; mld = mld->next)
+ if (mld->module == mod)
+ return;
+
+ mld = sipMalloc(sizeof (moduleListDef));
+ mld->module = mod;
+ mld->next = from->imports;
+
+ from->imports = mld;
+}
+
+
+/*
+ * Set up pointers to hook names.
+ */
+static void getHooks(optFlags *optflgs,char **pre,char **post)
+{
+ optFlag *of;
+
+ if ((of = findOptFlag(optflgs,"PreHook",name_flag)) != NULL)
+ *pre = of -> fvalue.sval;
+ else
+ *pre = NULL;
+
+ if ((of = findOptFlag(optflgs,"PostHook",name_flag)) != NULL)
+ *post = of -> fvalue.sval;
+ else
+ *post = NULL;
+}
+
+
+/*
+ * Get the /Transfer/ option flag.
+ */
+static int getTransfer(optFlags *optflgs)
+{
+ return (findOptFlag(optflgs, "Transfer", bool_flag) != NULL);
+}
+
+
+/*
+ * Get the /ReleaseGIL/ option flag.
+ */
+static int getReleaseGIL(optFlags *optflgs)
+{
+ return (findOptFlag(optflgs, "ReleaseGIL", bool_flag) != NULL);
+}
+
+
+/*
+ * Get the /HoldGIL/ option flag.
+ */
+static int getHoldGIL(optFlags *optflgs)
+{
+ return (findOptFlag(optflgs, "HoldGIL", bool_flag) != NULL);
+}
+
+
+/*
+ * Get the /Deprecated/ option flag.
+ */
+static int getDeprecated(optFlags *optflgs)
+{
+ return (findOptFlag(optflgs, "Deprecated", bool_flag) != NULL);
+}
+
+
+/*
+ * Get the /AllowNone/ option flag.
+ */
+static int getAllowNone(optFlags *optflgs)
+{
+ return (findOptFlag(optflgs, "AllowNone", bool_flag) != NULL);
+}
+
+
+/*
+ * Get the /DocType/ option flag.
+ */
+static const char *getDocType(optFlags *optflgs)
+{
+ optFlag *of = findOptFlag(optflgs, "DocType", string_flag);
+
+ if (of == NULL)
+ return NULL;
+
+ return of->fvalue.sval;
+}
+
+
+/*
+ * Get the /DocValue/ option flag.
+ */
+static const char *getDocValue(optFlags *optflgs)
+{
+ optFlag *of = findOptFlag(optflgs, "DocValue", string_flag);
+
+ if (of == NULL)
+ return NULL;
+
+ return of->fvalue.sval;
+}
+
+
+/*
+ * Return TRUE if the PyQt3 plugin was specified.
+ */
+int pluginPyQt3(sipSpec *pt)
+{
+ return stringFind(pt->plugins, "PyQt3");
+}
+
+
+/*
+ * Return TRUE if the PyQt4 plugin was specified.
+ */
+int pluginPyQt4(sipSpec *pt)
+{
+ return stringFind(pt->plugins, "PyQt4");
+}
+
+
+/*
+ * Return TRUE if a list of strings contains a given entry.
+ */
+static int stringFind(stringList *sl, const char *s)
+{
+ while (sl != NULL)
+ {
+ if (strcmp(sl->s, s) == 0)
+ return TRUE;
+
+ sl = sl->next;
+ }
+
+ return FALSE;
+}
+
+
+/*
+ * Set the name of a module.
+ */
+static void setModuleName(sipSpec *pt, moduleDef *mod, const char *fullname)
+{
+ mod->fullname = cacheName(pt, fullname);
+
+ if (inMainModule())
+ setIsUsedName(mod->fullname);
+
+ if ((mod->name = strrchr(fullname, '.')) != NULL)
+ mod->name++;
+ else
+ mod->name = fullname;
+}
+
+
+/*
+ * Define a new class and set its name.
+ */
+static void defineClass(scopedNameDef *snd, classList *supers, optFlags *of)
+{
+ classDef *cd, *c_scope = currentScope();
+
+ cd = newClass(currentSpec, class_iface, getAPIRange(of),
+ scopeScopedName((c_scope != NULL ? c_scope->iff : NULL), snd));
+ cd->supers = supers;
+
+ pushScope(cd);
+}
+
+
+/*
+ * Complete the definition of a class.
+ */
+static classDef *completeClass(scopedNameDef *snd, optFlags *of, int has_def)
+{
+ classDef *cd = currentScope();
+
+ /* See if the class was defined or just declared. */
+ if (has_def)
+ {
+ if (snd->next != NULL)
+ yyerror("A scoped name cannot be given in a class/struct definition");
+
+ }
+ else if (cd->supers != NULL)
+ yyerror("Class/struct has super-classes but no definition");
+ else
+ setIsOpaque(cd);
+
+ finishClass(currentSpec, currentModule, cd, of);
+ popScope();
+
+ /*
+ * Check that external classes have only been declared at the global scope.
+ */
+ if (isExternal(cd) && currentScope() != NULL)
+ yyerror("External classes/structs can only be declared in the global scope");
+
+ return cd;
+}
+
+
+/*
+ * Add a variable to the list so that the list remains sorted.
+ */
+static void addVariable(sipSpec *pt, varDef *vd)
+{
+ varDef **at = &pt->vars;
+
+ while (*at != NULL)
+ {
+ if (strcmp(vd->pyname->text, (*at)->pyname->text) < 0)
+ break;
+
+ at = &(*at)->next;
+ }
+
+ vd->next = *at;
+ *at = vd;
+}
+
+
+/*
+ * Update a type according to optional flags.
+ */
+static void applyTypeFlags(moduleDef *mod, argDef *ad, optFlags *flags)
+{
+ ad->doctype = getDocType(flags);
+
+ if (ad->atype == string_type && !isArray(ad) && !isReference(ad))
+ {
+ optFlag *of;
+
+ if ((of = findOptFlag(flags, "Encoding", string_flag)) == NULL)
+ {
+ if (mod->encoding != no_type)
+ ad->atype = mod->encoding;
+ else
+ ad->atype = string_type;
+ }
+ else if ((ad->atype = convertEncoding(of->fvalue.sval)) == no_type)
+ yyerror("The value of the /Encoding/ annotation must be one of \"ASCII\", \"Latin-1\", \"UTF-8\" or \"None\"");
+ }
+}
+
+
+/*
+ * Return the argument type for a string with the given encoding or no_type if
+ * the encoding was invalid.
+ */
+static argType convertEncoding(const char *encoding)
+{
+ if (strcmp(encoding, "ASCII") == 0)
+ return ascii_string_type;
+
+ if (strcmp(encoding, "Latin-1") == 0)
+ return latin1_string_type;
+
+ if (strcmp(encoding, "UTF-8") == 0)
+ return utf8_string_type;
+
+ if (strcmp(encoding, "None") == 0)
+ return string_type;
+
+ return no_type;
+}
+
+
+/*
+ * Get the /API/ option flag.
+ */
+static apiVersionRangeDef *getAPIRange(optFlags *optflgs)
+{
+ optFlag *of;
+
+ if ((of = findOptFlag(optflgs, "API", api_range_flag)) == NULL)
+ return NULL;
+
+ return of->fvalue.aval;
+}
+
+
+/*
+ * Return the API range structure and version number corresponding to the
+ * given API range.
+ */
+static apiVersionRangeDef *convertAPIRange(moduleDef *mod, nameDef *name,
+ int from, int to)
+{
+ int index;
+ apiVersionRangeDef *avd, **avdp;
+
+ /* Handle the trivial case. */
+ if (from == 0 && to == 0)
+ return NULL;
+
+ for (index = 0, avdp = &mod->api_ranges; (*avdp) != NULL; avdp = &(*avdp)->next, ++index)
+ {
+ avd = *avdp;
+
+ if (avd->api_name == name && avd->from == from && avd->to == to)
+ return avd;
+ }
+
+ /* The new one must be appended so that version numbers remain valid. */
+ avd = sipMalloc(sizeof (apiVersionRangeDef));
+
+ avd->api_name = name;
+ avd->from = from;
+ avd->to = to;
+ avd->index = index;
+
+ avd->next = NULL;
+ *avdp = avd;
+
+ return avd;
+}
+
+
+/*
+ * Return TRUE if a signature with annotations uses keyword arguments.
+ */
+static int usesKeywordArgs(optFlags *optflgs, signatureDef *sd)
+{
+ int kwd_args_anno, no_kwd_args_anno;
+
+ kwd_args_anno = (findOptFlag(optflgs, "KeywordArgs", bool_flag) != NULL);
+ no_kwd_args_anno = (findOptFlag(optflgs, "NoKeywordArgs", bool_flag) != NULL);
+
+ /*
+ * An ellipsis cannot be used with keyword arguments. Only complain if it
+ * has been explicitly requested.
+ */
+ if (kwd_args_anno && sd->nrArgs > 0 && sd->args[sd->nrArgs - 1].atype == ellipsis_type)
+ yyerror("/KeywordArgs/ cannot be specified for calls with a variable number of arguments");
+
+ if ((defaultKwdArgs || kwd_args_anno) && !no_kwd_args_anno)
+ {
+ int a, is_name = FALSE;
+
+ /*
+ * Mark argument names as being used and check there is at least one.
+ */
+ for (a = 0; a < sd->nrArgs; ++a)
+ {
+ nameDef *nd = sd->args[a].name;
+
+ if (sd->args[a].name != NULL)
+ {
+ setIsUsedName(nd);
+ is_name = TRUE;
+ }
+ }
+
+ return is_name;
+ }
+
+ return FALSE;
+}
+
+
+/*
+ * Extract the version of a string value optionally associated with a
+ * particular feature.
+ */
+static char *convertFeaturedString(char *fs)
+{
+ while (fs != NULL)
+ {
+ char *next, *value;
+
+ /* Individual values are ';' separated. */
+ if ((next = strchr(fs, ';')) != NULL)
+ *next++ = '\0';
+
+ /* Features and values are ':' separated. */
+ if ((value = strchr(fs, ':')) == NULL)
+ {
+ /* This is an unconditional value so just return it. */
+ return strip(fs);
+ }
+
+ *value++ = '\0';
+
+ if (isEnabledFeature(strip(fs)))
+ return strip(value);
+
+ fs = next;
+ }
+
+ /* No value was enabled. */
+ return NULL;
+}
+
+
+/*
+ * Return the stripped version of a string.
+ */
+static char *strip(char *s)
+{
+ while (*s == ' ')
+ ++s;
+
+ if (*s != '\0')
+ {
+ char *cp = &s[strlen(s) - 1];
+
+ while (*cp == ' ')
+ *cp-- = '\0';
+ }
+
+ return s;
+}
+
+
+/*
+ * Return TRUE if the given feature is enabled.
+ */
+static int isEnabledFeature(const char *name)
+{
+ qualDef *qd;
+
+ if ((qd = findQualifier(name)) == NULL || qd->qtype != feature_qualifier)
+ yyerror("No such feature");
+
+ return !excludedFeature(excludedQualifiers, qd);
+}
+
diff --git a/sipgen/parser.h b/sipgen/parser.h
new file mode 100644
index 0000000..1d3c05a
--- /dev/null
+++ b/sipgen/parser.h
@@ -0,0 +1,309 @@
+
+/* A Bison parser, made by GNU Bison 2.4.1. */
+
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ TK_API = 258,
+ TK_DEFENCODING = 259,
+ TK_PLUGIN = 260,
+ TK_DOCSTRING = 261,
+ TK_DOC = 262,
+ TK_EXPORTEDDOC = 263,
+ TK_MAKEFILE = 264,
+ TK_ACCESSCODE = 265,
+ TK_GETCODE = 266,
+ TK_SETCODE = 267,
+ TK_PREINITCODE = 268,
+ TK_INITCODE = 269,
+ TK_POSTINITCODE = 270,
+ TK_UNITCODE = 271,
+ TK_MODCODE = 272,
+ TK_TYPECODE = 273,
+ TK_PREPYCODE = 274,
+ TK_COPYING = 275,
+ TK_MAPPEDTYPE = 276,
+ TK_CODELINE = 277,
+ TK_IF = 278,
+ TK_END = 279,
+ TK_NAME = 280,
+ TK_PATHNAME = 281,
+ TK_STRING = 282,
+ TK_VIRTUALCATCHERCODE = 283,
+ TK_TRAVERSECODE = 284,
+ TK_CLEARCODE = 285,
+ TK_GETBUFFERCODE = 286,
+ TK_RELEASEBUFFERCODE = 287,
+ TK_READBUFFERCODE = 288,
+ TK_WRITEBUFFERCODE = 289,
+ TK_SEGCOUNTCODE = 290,
+ TK_CHARBUFFERCODE = 291,
+ TK_PICKLECODE = 292,
+ TK_METHODCODE = 293,
+ TK_FROMTYPE = 294,
+ TK_TOTYPE = 295,
+ TK_TOSUBCLASS = 296,
+ TK_INCLUDE = 297,
+ TK_OPTINCLUDE = 298,
+ TK_IMPORT = 299,
+ TK_EXPHEADERCODE = 300,
+ TK_MODHEADERCODE = 301,
+ TK_TYPEHEADERCODE = 302,
+ TK_MODULE = 303,
+ TK_CMODULE = 304,
+ TK_CONSMODULE = 305,
+ TK_COMPOMODULE = 306,
+ TK_CLASS = 307,
+ TK_STRUCT = 308,
+ TK_PUBLIC = 309,
+ TK_PROTECTED = 310,
+ TK_PRIVATE = 311,
+ TK_SIGNALS = 312,
+ TK_SIGNAL_METHOD = 313,
+ TK_SLOTS = 314,
+ TK_SLOT_METHOD = 315,
+ TK_BOOL = 316,
+ TK_SHORT = 317,
+ TK_INT = 318,
+ TK_LONG = 319,
+ TK_FLOAT = 320,
+ TK_DOUBLE = 321,
+ TK_CHAR = 322,
+ TK_WCHAR_T = 323,
+ TK_VOID = 324,
+ TK_PYOBJECT = 325,
+ TK_PYTUPLE = 326,
+ TK_PYLIST = 327,
+ TK_PYDICT = 328,
+ TK_PYCALLABLE = 329,
+ TK_PYSLICE = 330,
+ TK_PYTYPE = 331,
+ TK_VIRTUAL = 332,
+ TK_ENUM = 333,
+ TK_SIGNED = 334,
+ TK_UNSIGNED = 335,
+ TK_SCOPE = 336,
+ TK_LOGICAL_OR = 337,
+ TK_CONST = 338,
+ TK_STATIC = 339,
+ TK_SIPSIGNAL = 340,
+ TK_SIPSLOT = 341,
+ TK_SIPANYSLOT = 342,
+ TK_SIPRXCON = 343,
+ TK_SIPRXDIS = 344,
+ TK_SIPSLOTCON = 345,
+ TK_SIPSLOTDIS = 346,
+ TK_NUMBER = 347,
+ TK_REAL = 348,
+ TK_TYPEDEF = 349,
+ TK_NAMESPACE = 350,
+ TK_TIMELINE = 351,
+ TK_PLATFORMS = 352,
+ TK_FEATURE = 353,
+ TK_LICENSE = 354,
+ TK_QCHAR = 355,
+ TK_TRUE = 356,
+ TK_FALSE = 357,
+ TK_NULL = 358,
+ TK_OPERATOR = 359,
+ TK_THROW = 360,
+ TK_QOBJECT = 361,
+ TK_EXCEPTION = 362,
+ TK_RAISECODE = 363,
+ TK_EXPLICIT = 364,
+ TK_TEMPLATE = 365,
+ TK_ELLIPSIS = 366,
+ TK_DEFMETATYPE = 367,
+ TK_DEFSUPERTYPE = 368
+ };
+#endif
+/* Tokens. */
+#define TK_API 258
+#define TK_DEFENCODING 259
+#define TK_PLUGIN 260
+#define TK_DOCSTRING 261
+#define TK_DOC 262
+#define TK_EXPORTEDDOC 263
+#define TK_MAKEFILE 264
+#define TK_ACCESSCODE 265
+#define TK_GETCODE 266
+#define TK_SETCODE 267
+#define TK_PREINITCODE 268
+#define TK_INITCODE 269
+#define TK_POSTINITCODE 270
+#define TK_UNITCODE 271
+#define TK_MODCODE 272
+#define TK_TYPECODE 273
+#define TK_PREPYCODE 274
+#define TK_COPYING 275
+#define TK_MAPPEDTYPE 276
+#define TK_CODELINE 277
+#define TK_IF 278
+#define TK_END 279
+#define TK_NAME 280
+#define TK_PATHNAME 281
+#define TK_STRING 282
+#define TK_VIRTUALCATCHERCODE 283
+#define TK_TRAVERSECODE 284
+#define TK_CLEARCODE 285
+#define TK_GETBUFFERCODE 286
+#define TK_RELEASEBUFFERCODE 287
+#define TK_READBUFFERCODE 288
+#define TK_WRITEBUFFERCODE 289
+#define TK_SEGCOUNTCODE 290
+#define TK_CHARBUFFERCODE 291
+#define TK_PICKLECODE 292
+#define TK_METHODCODE 293
+#define TK_FROMTYPE 294
+#define TK_TOTYPE 295
+#define TK_TOSUBCLASS 296
+#define TK_INCLUDE 297
+#define TK_OPTINCLUDE 298
+#define TK_IMPORT 299
+#define TK_EXPHEADERCODE 300
+#define TK_MODHEADERCODE 301
+#define TK_TYPEHEADERCODE 302
+#define TK_MODULE 303
+#define TK_CMODULE 304
+#define TK_CONSMODULE 305
+#define TK_COMPOMODULE 306
+#define TK_CLASS 307
+#define TK_STRUCT 308
+#define TK_PUBLIC 309
+#define TK_PROTECTED 310
+#define TK_PRIVATE 311
+#define TK_SIGNALS 312
+#define TK_SIGNAL_METHOD 313
+#define TK_SLOTS 314
+#define TK_SLOT_METHOD 315
+#define TK_BOOL 316
+#define TK_SHORT 317
+#define TK_INT 318
+#define TK_LONG 319
+#define TK_FLOAT 320
+#define TK_DOUBLE 321
+#define TK_CHAR 322
+#define TK_WCHAR_T 323
+#define TK_VOID 324
+#define TK_PYOBJECT 325
+#define TK_PYTUPLE 326
+#define TK_PYLIST 327
+#define TK_PYDICT 328
+#define TK_PYCALLABLE 329
+#define TK_PYSLICE 330
+#define TK_PYTYPE 331
+#define TK_VIRTUAL 332
+#define TK_ENUM 333
+#define TK_SIGNED 334
+#define TK_UNSIGNED 335
+#define TK_SCOPE 336
+#define TK_LOGICAL_OR 337
+#define TK_CONST 338
+#define TK_STATIC 339
+#define TK_SIPSIGNAL 340
+#define TK_SIPSLOT 341
+#define TK_SIPANYSLOT 342
+#define TK_SIPRXCON 343
+#define TK_SIPRXDIS 344
+#define TK_SIPSLOTCON 345
+#define TK_SIPSLOTDIS 346
+#define TK_NUMBER 347
+#define TK_REAL 348
+#define TK_TYPEDEF 349
+#define TK_NAMESPACE 350
+#define TK_TIMELINE 351
+#define TK_PLATFORMS 352
+#define TK_FEATURE 353
+#define TK_LICENSE 354
+#define TK_QCHAR 355
+#define TK_TRUE 356
+#define TK_FALSE 357
+#define TK_NULL 358
+#define TK_OPERATOR 359
+#define TK_THROW 360
+#define TK_QOBJECT 361
+#define TK_EXCEPTION 362
+#define TK_RAISECODE 363
+#define TK_EXPLICIT 364
+#define TK_TEMPLATE 365
+#define TK_ELLIPSIS 366
+#define TK_DEFMETATYPE 367
+#define TK_DEFSUPERTYPE 368
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+{
+
+/* Line 1676 of yacc.c */
+#line 147 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.y"
+
+ char qchar;
+ char *text;
+ long number;
+ double real;
+ argDef memArg;
+ signatureDef signature;
+ signatureDef *optsignature;
+ throwArgs *throwlist;
+ codeBlock *codeb;
+ valueDef value;
+ valueDef *valp;
+ optFlags optflags;
+ optFlag flag;
+ scopedNameDef *scpvalp;
+ fcallDef fcall;
+ int boolean;
+ exceptionDef exceptionbase;
+ classDef *klass;
+
+
+
+/* Line 1676 of yacc.c */
+#line 301 "/home/phil/hg/sip/sip-4.10.5/sipgen/parser.h"
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+extern YYSTYPE yylval;
+
+
diff --git a/sipgen/parser.y b/sipgen/parser.y
new file mode 100644
index 0000000..4000e7d
--- /dev/null
+++ b/sipgen/parser.y
@@ -0,0 +1,6385 @@
+/*
+ * The SIP parser.
+ *
+ * Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com>
+ *
+ * This file is part of SIP.
+ *
+ * This copy of SIP is licensed for use under the terms of the SIP License
+ * Agreement. See the file LICENSE for more details.
+ *
+ * This copy of SIP may also used under the terms of the GNU General Public
+ * License v2 or v3 as published by the Free Software Foundation which can be
+ * found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
+ *
+ * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+%{
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "sip.h"
+
+
+#define MAX_NESTED_IF 10
+#define MAX_NESTED_SCOPE 10
+
+#define inMainModule() (currentSpec->module == currentModule || currentModule->container != NULL)
+
+
+static sipSpec *currentSpec; /* The current spec being parsed. */
+static stringList *neededQualifiers; /* The list of required qualifiers. */
+static stringList *excludedQualifiers; /* The list of excluded qualifiers. */
+static moduleDef *currentModule; /* The current module being parsed. */
+static mappedTypeDef *currentMappedType; /* The current mapped type. */
+static enumDef *currentEnum; /* The current enum being parsed. */
+static int sectionFlags; /* The current section flags. */
+static int currentOverIsVirt; /* Set if the overload is virtual. */
+static int currentCtorIsExplicit; /* Set if the ctor is explicit. */
+static int currentIsStatic; /* Set if the current is static. */
+static int currentIsSignal; /* Set if the current is Q_SIGNAL. */
+static int currentIsSlot; /* Set if the current is Q_SLOT. */
+static int currentIsTemplate; /* Set if the current is a template. */
+static char *previousFile; /* The file just parsed. */
+static parserContext currentContext; /* The current context. */
+static int skipStackPtr; /* The skip stack pointer. */
+static int skipStack[MAX_NESTED_IF]; /* Stack of skip flags. */
+static classDef *scopeStack[MAX_NESTED_SCOPE]; /* The scope stack. */
+static int sectFlagsStack[MAX_NESTED_SCOPE]; /* The section flags stack. */
+static int currentScopeIdx; /* The scope stack index. */
+static int currentTimelineOrder; /* The current timeline order. */
+static classList *currentSupers; /* The current super-class list. */
+static int defaultKwdArgs; /* Support keyword arguments by default. */
+static int makeProtPublic; /* Treat protected items as public. */
+
+
+static const char *getPythonName(optFlags *optflgs, const char *cname);
+static classDef *findClass(sipSpec *pt, ifaceFileType iftype,
+ apiVersionRangeDef *api_range, scopedNameDef *fqname);
+static classDef *findClassWithInterface(sipSpec *pt, ifaceFileDef *iff);
+static classDef *newClass(sipSpec *pt, ifaceFileType iftype,
+ apiVersionRangeDef *api_range, scopedNameDef *snd);
+static void finishClass(sipSpec *, moduleDef *, classDef *, optFlags *);
+static exceptionDef *findException(sipSpec *pt, scopedNameDef *fqname, int new);
+static mappedTypeDef *newMappedType(sipSpec *,argDef *, optFlags *);
+static enumDef *newEnum(sipSpec *pt, moduleDef *mod, mappedTypeDef *mt_scope,
+ char *name, optFlags *of, int flags);
+static void instantiateClassTemplate(sipSpec *pt, moduleDef *mod, classDef *scope, scopedNameDef *fqname, classTmplDef *tcd, templateDef *td);
+static void newTypedef(sipSpec *, moduleDef *, char *, argDef *, optFlags *);
+static void newVar(sipSpec *, moduleDef *, char *, int, argDef *, optFlags *,
+ codeBlock *, codeBlock *, codeBlock *);
+static void newCtor(char *, int, signatureDef *, optFlags *, codeBlock *,
+ throwArgs *, signatureDef *, int, codeBlock *);
+static void newFunction(sipSpec *, moduleDef *, classDef *, mappedTypeDef *,
+ int, int, int, int, int, char *, signatureDef *, int, int, optFlags *,
+ codeBlock *, codeBlock *, throwArgs *, signatureDef *, codeBlock *);
+static optFlag *findOptFlag(optFlags *,char *,flagType);
+static memberDef *findFunction(sipSpec *, moduleDef *, classDef *,
+ mappedTypeDef *, const char *, int, int, int);
+static void checkAttributes(sipSpec *, moduleDef *, classDef *,
+ mappedTypeDef *, const char *, int);
+static void newModule(FILE *fp, char *filename);
+static moduleDef *allocModule();
+static void parseFile(FILE *fp, char *name, moduleDef *prevmod, int optional);
+static void handleEOF(void);
+static void handleEOM(void);
+static qualDef *findQualifier(const char *name);
+static scopedNameDef *text2scopedName(ifaceFileDef *scope, char *text);
+static scopedNameDef *scopeScopedName(ifaceFileDef *scope,
+ scopedNameDef *name);
+static void pushScope(classDef *);
+static void popScope(void);
+static classDef *currentScope(void);
+static void newQualifier(moduleDef *,int,int,char *,qualType);
+static void newImport(char *filename);
+static int timePeriod(char *,char *);
+static int platOrFeature(char *,int);
+static int isNeeded(qualDef *);
+static int notSkipping(void);
+static void getHooks(optFlags *,char **,char **);
+static int getTransfer(optFlags *optflgs);
+static int getReleaseGIL(optFlags *optflgs);
+static int getHoldGIL(optFlags *optflgs);
+static int getDeprecated(optFlags *optflgs);
+static int getAllowNone(optFlags *optflgs);
+static const char *getDocType(optFlags *optflgs);
+static const char *getDocValue(optFlags *optflgs);
+static void templateSignature(signatureDef *sd, int result, classTmplDef *tcd, templateDef *td, classDef *ncd);
+static void templateType(argDef *ad, classTmplDef *tcd, templateDef *td, classDef *ncd);
+static int search_back(const char *end, const char *start, const char *target);
+static char *type2string(argDef *ad);
+static char *scopedNameToString(scopedNameDef *name);
+static void addUsedFromCode(sipSpec *pt, ifaceFileList **used, const char *sname);
+static int sameName(scopedNameDef *snd, const char *sname);
+static int stringFind(stringList *sl, const char *s);
+static void setModuleName(sipSpec *pt, moduleDef *mod, const char *fullname);
+static int foundInScope(scopedNameDef *fq_name, scopedNameDef *rel_name);
+static void defineClass(scopedNameDef *snd, classList *supers, optFlags *of);
+static classDef *completeClass(scopedNameDef *snd, optFlags *of, int has_def);
+static memberDef *instantiateTemplateMethods(memberDef *tmd, moduleDef *mod);
+static void instantiateTemplateEnums(sipSpec *pt, classTmplDef *tcd,
+ templateDef *td, classDef *cd, ifaceFileList **used,
+ scopedNameDef *type_names, scopedNameDef *type_values);
+static void instantiateTemplateVars(sipSpec *pt, classTmplDef *tcd,
+ templateDef *td, classDef *cd, ifaceFileList **used,
+ scopedNameDef *type_names, scopedNameDef *type_values);
+static overDef *instantiateTemplateOverloads(sipSpec *pt, overDef *tod,
+ memberDef *tmethods, memberDef *methods, classTmplDef *tcd,
+ templateDef *td, classDef *cd, ifaceFileList **used,
+ scopedNameDef *type_names, scopedNameDef *type_values);
+static void resolveAnyTypedef(sipSpec *pt, argDef *ad);
+static void addVariable(sipSpec *pt, varDef *vd);
+static void applyTypeFlags(moduleDef *mod, argDef *ad, optFlags *flags);
+static argType convertEncoding(const char *encoding);
+static apiVersionRangeDef *getAPIRange(optFlags *optflgs);
+static apiVersionRangeDef *convertAPIRange(moduleDef *mod, nameDef *name,
+ int from, int to);
+static char *convertFeaturedString(char *fs);
+static scopedNameDef *text2scopePart(char *text);
+static int usesKeywordArgs(optFlags *optflgs, signatureDef *sd);
+static char *strip(char *s);
+static int isEnabledFeature(const char *name);
+%}
+
+%union {
+ char qchar;
+ char *text;
+ long number;
+ double real;
+ argDef memArg;
+ signatureDef signature;
+ signatureDef *optsignature;
+ throwArgs *throwlist;
+ codeBlock *codeb;
+ valueDef value;
+ valueDef *valp;
+ optFlags optflags;
+ optFlag flag;
+ scopedNameDef *scpvalp;
+ fcallDef fcall;
+ int boolean;
+ exceptionDef exceptionbase;
+ classDef *klass;
+}
+
+%token TK_API
+%token TK_DEFENCODING
+%token TK_PLUGIN
+%token TK_DOCSTRING
+%token TK_DOC
+%token TK_EXPORTEDDOC
+%token TK_MAKEFILE
+%token TK_ACCESSCODE
+%token TK_GETCODE
+%token TK_SETCODE
+%token TK_PREINITCODE
+%token TK_INITCODE
+%token TK_POSTINITCODE
+%token TK_UNITCODE
+%token TK_MODCODE
+%token TK_TYPECODE
+%token TK_PREPYCODE
+%token TK_COPYING
+%token TK_MAPPEDTYPE
+%token <codeb> TK_CODELINE
+%token TK_IF
+%token TK_END
+%token <text> TK_NAME
+%token <text> TK_PATHNAME
+%token <text> TK_STRING
+%token TK_VIRTUALCATCHERCODE
+%token TK_TRAVERSECODE
+%token TK_CLEARCODE
+%token TK_GETBUFFERCODE
+%token TK_RELEASEBUFFERCODE
+%token TK_READBUFFERCODE
+%token TK_WRITEBUFFERCODE
+%token TK_SEGCOUNTCODE
+%token TK_CHARBUFFERCODE
+%token TK_PICKLECODE
+%token TK_METHODCODE
+%token TK_FROMTYPE
+%token TK_TOTYPE
+%token TK_TOSUBCLASS
+%token TK_INCLUDE
+%token TK_OPTINCLUDE
+%token TK_IMPORT
+%token TK_EXPHEADERCODE
+%token TK_MODHEADERCODE
+%token TK_TYPEHEADERCODE
+%token TK_MODULE
+%token TK_CMODULE
+%token TK_CONSMODULE
+%token TK_COMPOMODULE
+%token TK_CLASS
+%token TK_STRUCT
+%token TK_PUBLIC
+%token TK_PROTECTED
+%token TK_PRIVATE
+%token TK_SIGNALS
+%token TK_SIGNAL_METHOD
+%token TK_SLOTS
+%token TK_SLOT_METHOD
+%token TK_BOOL
+%token TK_SHORT
+%token TK_INT
+%token TK_LONG
+%token TK_FLOAT
+%token TK_DOUBLE
+%token TK_CHAR
+%token TK_WCHAR_T
+%token TK_VOID
+%token TK_PYOBJECT
+%token TK_PYTUPLE
+%token TK_PYLIST
+%token TK_PYDICT
+%token TK_PYCALLABLE
+%token TK_PYSLICE
+%token TK_PYTYPE
+%token TK_VIRTUAL
+%token TK_ENUM
+%token TK_SIGNED
+%token TK_UNSIGNED
+%token TK_SCOPE
+%token TK_LOGICAL_OR
+%token TK_CONST
+%token TK_STATIC
+%token TK_SIPSIGNAL
+%token TK_SIPSLOT
+%token TK_SIPANYSLOT
+%token TK_SIPRXCON
+%token TK_SIPRXDIS
+%token TK_SIPSLOTCON
+%token TK_SIPSLOTDIS
+%token <number> TK_NUMBER
+%token <real> TK_REAL
+%token TK_TYPEDEF
+%token TK_NAMESPACE
+%token TK_TIMELINE
+%token TK_PLATFORMS
+%token TK_FEATURE
+%token TK_LICENSE
+%token <qchar> TK_QCHAR
+%token TK_TRUE
+%token TK_FALSE
+%token TK_NULL
+%token TK_OPERATOR
+%token TK_THROW
+%token TK_QOBJECT
+%token TK_EXCEPTION
+%token TK_RAISECODE
+%token TK_EXPLICIT
+%token TK_TEMPLATE
+%token TK_ELLIPSIS
+%token TK_DEFMETATYPE
+%token TK_DEFSUPERTYPE
+
+%type <memArg> argvalue
+%type <memArg> argtype
+%type <memArg> cpptype
+%type <memArg> basetype
+%type <signature> template
+%type <signature> arglist
+%type <signature> rawarglist
+%type <signature> cpptypelist
+%type <optsignature> optsig
+%type <optsignature> optctorsig
+%type <throwlist> optexceptions
+%type <throwlist> exceptionlist
+%type <number> optslot
+%type <number> optref
+%type <number> optconst
+%type <number> optvirtual
+%type <number> optabstract
+%type <number> deref
+%type <number> optnumber
+%type <value> simplevalue
+%type <valp> value
+%type <valp> expr
+%type <valp> optassign
+%type <codeb> optaccesscode
+%type <codeb> optgetcode
+%type <codeb> optsetcode
+%type <codeb> exphdrcode
+%type <codeb> modhdrcode
+%type <codeb> typehdrcode
+%type <codeb> opttypehdrcode
+%type <codeb> travcode
+%type <codeb> clearcode
+%type <codeb> getbufcode
+%type <codeb> releasebufcode
+%type <codeb> readbufcode
+%type <codeb> writebufcode
+%type <codeb> segcountcode
+%type <codeb> charbufcode
+%type <codeb> picklecode
+%type <codeb> modcode
+%type <codeb> typecode
+%type <codeb> codeblock
+%type <codeb> codelines
+%type <codeb> virtualcatchercode
+%type <codeb> methodcode
+%type <codeb> raisecode
+%type <codeb> docstring
+%type <codeb> optdocstring
+%type <text> operatorname
+%type <text> optfilename
+%type <text> optname
+%type <text> dottedname
+%type <optflags> optflags
+%type <optflags> flaglist
+%type <flag> flag
+%type <flag> flagvalue
+%type <qchar> optunop
+%type <qchar> binop
+%type <scpvalp> scopepart
+%type <scpvalp> scopedname
+%type <fcall> exprlist
+%type <boolean> qualifiers
+%type <boolean> oredqualifiers
+%type <boolean> modlang
+%type <boolean> optclassbody
+%type <exceptionbase> baseexception
+%type <klass> class
+
+%%
+
+specification: statement
+ | specification statement
+ ;
+
+statement: {
+ /*
+ * We don't do these in parserEOF() because the parser is reading
+ * ahead and that would be too early.
+ */
+
+ if (previousFile != NULL)
+ {
+ handleEOF();
+
+ if (currentContext.prevmod != NULL)
+ handleEOM();
+
+ free(previousFile);
+ previousFile = NULL;
+ }
+ } modstatement
+ ;
+
+modstatement: module
+ | consmodule
+ | compmodule
+ | plugin
+ | copying
+ | include
+ | optinclude
+ | import
+ | api
+ | timeline
+ | platforms
+ | feature
+ | license
+ | defencoding
+ | defmetatype
+ | defsupertype
+ | exphdrcode {
+ if (notSkipping())
+ appendCodeBlock(&currentSpec->exphdrcode, $1);
+ }
+ | modhdrcode {
+ if (notSkipping())
+ appendCodeBlock(&currentModule->hdrcode, $1);
+ }
+ | modcode {
+ if (notSkipping())
+ appendCodeBlock(&currentModule->cppcode, $1);
+ }
+ | preinitcode
+ | initcode
+ | postinitcode
+ | unitcode
+ | prepycode
+ | doc
+ | exporteddoc
+ | makefile
+ | mappedtype
+ | mappedtypetmpl
+ | nsstatement
+ ;
+
+nsstatement: ifstart
+ | ifend
+ | namespace
+ | struct
+ | class
+ | classtmpl
+ | exception
+ | typedef
+ | enum
+ | function
+ | variable
+ | typehdrcode {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ if (scope == NULL)
+ yyerror("%TypeHeaderCode can only be used in a namespace, class or mapped type");
+
+ appendCodeBlock(&scope->iff->hdrcode, $1);
+ }
+ }
+ ;
+
+defencoding: TK_DEFENCODING TK_STRING {
+ if (notSkipping())
+ {
+ if ((currentModule->encoding = convertEncoding($2)) == no_type)
+ yyerror("The value of %DefaultEncoding must be one of \"ASCII\", \"Latin-1\", \"UTF-8\" or \"None\"");
+ }
+ }
+ ;
+
+plugin: TK_PLUGIN TK_NAME {
+ appendString(&currentSpec->plugins, $2);
+ }
+ ;
+
+api: TK_API TK_NAME TK_NUMBER {
+ if (notSkipping())
+ {
+ apiVersionRangeDef *avd;
+
+ if (findAPI(currentSpec, $2) != NULL)
+ yyerror("The API name in the %API directive has already been defined");
+
+ if ($3 < 1)
+ yyerror("The version number in the %API directive must be greater than or equal to 1");
+
+ avd = sipMalloc(sizeof (apiVersionRangeDef));
+
+ avd->api_name = cacheName(currentSpec, $2);
+ avd->from = $3;
+ avd->to = -1;
+
+ avd->next = currentModule->api_versions;
+ currentModule->api_versions = avd;
+
+ if (inMainModule())
+ setIsUsedName(avd->api_name);
+ }
+ }
+ ;
+
+exception: TK_EXCEPTION scopedname baseexception optflags '{' opttypehdrcode raisecode '}' ';' {
+ if (notSkipping())
+ {
+ exceptionDef *xd;
+ const char *pyname;
+
+ if (currentSpec->genc)
+ yyerror("%Exception not allowed in a C module");
+
+ pyname = getPythonName(&$4, scopedNameTail($2));
+
+ checkAttributes(currentSpec, currentModule, NULL, NULL,
+ pyname, FALSE);
+
+ xd = findException(currentSpec, $2, TRUE);
+
+ if (xd->cd != NULL)
+ yyerror("%Exception name has already been seen as a class name - it must be defined before being used");
+
+ if (xd->iff->module != NULL)
+ yyerror("The %Exception has already been defined");
+
+ /* Complete the definition. */
+ xd->iff->module = currentModule;
+ xd->iff->hdrcode = $6;
+ xd->pyname = pyname;
+ xd->bibase = $3.bibase;
+ xd->base = $3.base;
+ xd->raisecode = $7;
+
+ if (findOptFlag(&$4, "Default", bool_flag) != NULL)
+ currentModule->defexception = xd;
+
+ if (xd->bibase != NULL || xd->base != NULL)
+ xd->exceptionnr = currentModule->nrexceptions++;
+ }
+ }
+ ;
+
+baseexception: {
+ $$.bibase = NULL;
+ $$.base = NULL;
+ }
+ | '(' scopedname ')' {
+ exceptionDef *xd;
+
+ $$.bibase = NULL;
+ $$.base = NULL;
+
+ /* See if it is a defined exception. */
+ for (xd = currentSpec->exceptions; xd != NULL; xd = xd->next)
+ if (compareScopedNames(xd->iff->fqcname, $2) == 0)
+ {
+ $$.base = xd;
+ break;
+ }
+
+ if (xd == NULL && $2->next == NULL && strncmp($2->name, "SIP_", 4) == 0)
+ {
+ /* See if it is a builtin exception. */
+
+ static char *builtins[] = {
+ "Exception",
+ "StopIteration",
+ "StandardError",
+ "ArithmeticError",
+ "LookupError",
+ "AssertionError",
+ "AttributeError",
+ "EOFError",
+ "FloatingPointError",
+ "EnvironmentError",
+ "IOError",
+ "OSError",
+ "ImportError",
+ "IndexError",
+ "KeyError",
+ "KeyboardInterrupt",
+ "MemoryError",
+ "NameError",
+ "OverflowError",
+ "RuntimeError",
+ "NotImplementedError",
+ "SyntaxError",
+ "IndentationError",
+ "TabError",
+ "ReferenceError",
+ "SystemError",
+ "SystemExit",
+ "TypeError",
+ "UnboundLocalError",
+ "UnicodeError",
+ "UnicodeEncodeError",
+ "UnicodeDecodeError",
+ "UnicodeTranslateError",
+ "ValueError",
+ "ZeroDivisionError",
+ "WindowsError",
+ "VMSError",
+ NULL
+ };
+
+ char **cp;
+
+ for (cp = builtins; *cp != NULL; ++cp)
+ if (strcmp($2->name + 4, *cp) == 0)
+ {
+ $$.bibase = *cp;
+ break;
+ }
+ }
+
+ if ($$.bibase == NULL && $$.base == NULL)
+ yyerror("Unknown exception base type");
+ }
+ ;
+
+raisecode: TK_RAISECODE codeblock {
+ $$ = $2;
+ }
+ ;
+
+mappedtype: TK_MAPPEDTYPE basetype optflags {
+ if (notSkipping())
+ currentMappedType = newMappedType(currentSpec, &$2, &$3);
+ } mtdefinition
+ ;
+
+mappedtypetmpl: template TK_MAPPEDTYPE basetype optflags {
+ int a;
+
+ if (currentSpec->genc)
+ yyerror("%MappedType templates not allowed in a C module");
+
+ /* Check the template arguments are basic types or simple names. */
+ for (a = 0; a < $1.nrArgs; ++a)
+ {
+ argDef *ad = &$1.args[a];
+
+ if (ad->atype == defined_type && ad->u.snd->next != NULL)
+ yyerror("%MappedType template arguments must be simple names");
+ }
+
+ if ($3.atype != template_type)
+ yyerror("%MappedType template must map a template type");
+
+ if (notSkipping())
+ {
+ mappedTypeTmplDef *mtt;
+ ifaceFileDef *iff;
+
+ /* Check a template hasn't already been provided. */
+ for (mtt = currentSpec->mappedtypetemplates; mtt != NULL; mtt = mtt->next)
+ if (compareScopedNames(mtt->mt->type.u.td->fqname, $3.u.td->fqname) == 0 && sameTemplateSignature(&mtt->mt->type.u.td->types, &$3.u.td->types, TRUE))
+ yyerror("%MappedType template for this type has already been defined");
+
+ $3.nrderefs = 0;
+ $3.argflags = 0;
+
+ mtt = sipMalloc(sizeof (mappedTypeTmplDef));
+
+ mtt->sig = $1;
+ mtt->mt = allocMappedType(currentSpec, &$3);
+ mtt->mt->doctype = getDocType(&$4);
+ mtt->next = currentSpec->mappedtypetemplates;
+
+ currentSpec->mappedtypetemplates = mtt;
+
+ currentMappedType = mtt->mt;
+
+ /* Create a dummy interface file. */
+ iff = sipMalloc(sizeof (ifaceFileDef));
+ iff->hdrcode = NULL;
+ mtt->mt->iff = iff;
+ }
+ } mtdefinition
+ ;
+
+mtdefinition: '{' mtbody '}' ';' {
+ if (notSkipping())
+ {
+ if (currentMappedType->convfromcode == NULL)
+ yyerror("%MappedType must have a %ConvertFromTypeCode directive");
+
+ if (currentMappedType->convtocode == NULL)
+ yyerror("%MappedType must have a %ConvertToTypeCode directive");
+
+ currentMappedType = NULL;
+ }
+ }
+ ;
+
+mtbody: mtline
+ | mtbody mtline
+ ;
+
+mtline: typehdrcode {
+ if (notSkipping())
+ appendCodeBlock(&currentMappedType->iff->hdrcode, $1);
+ }
+ | TK_FROMTYPE codeblock {
+ if (notSkipping())
+ {
+ if (currentMappedType -> convfromcode != NULL)
+ yyerror("%MappedType has more than one %ConvertFromTypeCode directive");
+
+ currentMappedType -> convfromcode = $2;
+ }
+ }
+ | TK_TOTYPE codeblock {
+ if (notSkipping())
+ {
+ if (currentMappedType -> convtocode != NULL)
+ yyerror("%MappedType has more than one %ConvertToTypeCode directive");
+
+ currentMappedType -> convtocode = $2;
+ }
+ }
+ | enum
+ | mtfunction
+ ;
+
+mtfunction: TK_STATIC cpptype TK_NAME '(' arglist ')' optconst optexceptions optflags optsig ';' optdocstring methodcode {
+ if (notSkipping())
+ {
+ applyTypeFlags(currentModule, &$2, &$9);
+
+ $5.result = $2;
+
+ newFunction(currentSpec, currentModule, NULL,
+ currentMappedType, 0, TRUE, FALSE, FALSE, FALSE, $3,
+ &$5, $7, FALSE, &$9, $13, NULL, $8, $10, $12);
+ }
+ }
+ ;
+
+namespace: TK_NAMESPACE TK_NAME {
+ if (currentSpec -> genc)
+ yyerror("namespace definition not allowed in a C module");
+
+ if (notSkipping())
+ {
+ classDef *ns, *c_scope;
+ ifaceFileDef *scope;
+
+ if ((c_scope = currentScope()) != NULL)
+ scope = c_scope->iff;
+ else
+ scope = NULL;
+
+ ns = newClass(currentSpec, namespace_iface, NULL,
+ text2scopedName(scope, $2));
+
+ pushScope(ns);
+
+ sectionFlags = 0;
+ }
+ } '{' nsbody '}' ';' {
+ if (notSkipping())
+ {
+ if (inMainModule())
+ {
+ classDef *ns = currentScope();
+
+ setIsUsedName(ns->iff->name);
+ setIsUsedName(ns->pyname);
+ }
+
+ popScope();
+ }
+ }
+ ;
+
+nsbody: nsstatement
+ | nsbody nsstatement
+ ;
+
+platforms: TK_PLATFORMS {
+ qualDef *qd;
+
+ for (qd = currentModule -> qualifiers; qd != NULL; qd = qd -> next)
+ if (qd -> qtype == platform_qualifier)
+ yyerror("%Platforms has already been defined for this module");
+ }
+ '{' platformlist '}' {
+ qualDef *qd;
+ int nrneeded;
+
+ /*
+ * Check that exactly one platform in the set was
+ * requested.
+ */
+
+ nrneeded = 0;
+
+ for (qd = currentModule -> qualifiers; qd != NULL; qd = qd -> next)
+ if (qd -> qtype == platform_qualifier && isNeeded(qd))
+ ++nrneeded;
+
+ if (nrneeded > 1)
+ yyerror("No more than one of these %Platforms must be specified with the -t flag");
+ }
+ ;
+
+platformlist: platform
+ | platformlist platform
+ ;
+
+platform: TK_NAME {
+ newQualifier(currentModule,-1,-1,$1,platform_qualifier);
+ }
+ ;
+
+feature: TK_FEATURE TK_NAME {
+ newQualifier(currentModule,-1,-1,$2,feature_qualifier);
+ }
+ ;
+
+timeline: TK_TIMELINE {
+ currentTimelineOrder = 0;
+ }
+ '{' qualifierlist '}' {
+ qualDef *qd;
+ int nrneeded;
+
+ /*
+ * Check that exactly one time slot in the set was
+ * requested.
+ */
+
+ nrneeded = 0;
+
+ for (qd = currentModule -> qualifiers; qd != NULL; qd = qd -> next)
+ if (qd -> qtype == time_qualifier && isNeeded(qd))
+ ++nrneeded;
+
+ if (nrneeded > 1)
+ yyerror("At most one of this %Timeline must be specified with the -t flag");
+
+ currentModule -> nrtimelines++;
+ }
+ ;
+
+qualifierlist: qualifiername
+ | qualifierlist qualifiername
+ ;
+
+qualifiername: TK_NAME {
+ newQualifier(currentModule,currentModule -> nrtimelines,currentTimelineOrder++,$1,time_qualifier);
+ }
+ ;
+
+ifstart: TK_IF '(' qualifiers ')' {
+ if (skipStackPtr >= MAX_NESTED_IF)
+ yyerror("Internal error: increase the value of MAX_NESTED_IF");
+
+ /* Nested %Ifs are implicit logical ands. */
+
+ if (skipStackPtr > 0)
+ $3 = ($3 && skipStack[skipStackPtr - 1]);
+
+ skipStack[skipStackPtr++] = $3;
+ }
+ ;
+
+oredqualifiers: TK_NAME {
+ $$ = platOrFeature($1,FALSE);
+ }
+ | '!' TK_NAME {
+ $$ = platOrFeature($2,TRUE);
+ }
+ | oredqualifiers TK_LOGICAL_OR TK_NAME {
+ $$ = (platOrFeature($3,FALSE) || $1);
+ }
+ | oredqualifiers TK_LOGICAL_OR '!' TK_NAME {
+ $$ = (platOrFeature($4,TRUE) || $1);
+ }
+ ;
+
+qualifiers: oredqualifiers
+ | optname '-' optname {
+ $$ = timePeriod($1,$3);
+ }
+ ;
+
+ifend: TK_END {
+ if (skipStackPtr-- <= 0)
+ yyerror("Too many %End directives");
+ }
+ ;
+
+license: TK_LICENSE optflags {
+ optFlag *of;
+
+ if ($2.nrFlags == 0)
+ yyerror("%License details not specified");
+
+ if ((of = findOptFlag(&$2,"Type",string_flag)) == NULL)
+ yyerror("%License type not specified");
+
+ currentModule -> license = sipMalloc(sizeof (licenseDef));
+
+ currentModule -> license -> type = of -> fvalue.sval;
+
+ currentModule -> license -> licensee =
+ ((of = findOptFlag(&$2,"Licensee",string_flag)) != NULL)
+ ? of -> fvalue.sval : NULL;
+
+ currentModule -> license -> timestamp =
+ ((of = findOptFlag(&$2,"Timestamp",string_flag)) != NULL)
+ ? of -> fvalue.sval : NULL;
+
+ currentModule -> license -> sig =
+ ((of = findOptFlag(&$2,"Signature",string_flag)) != NULL)
+ ? of -> fvalue.sval : NULL;
+ }
+ ;
+
+defmetatype:TK_DEFMETATYPE dottedname {
+ if (notSkipping())
+ {
+ if (currentModule->defmetatype != NULL)
+ yyerror("%DefaultMetatype has already been defined for this module");
+
+ currentModule->defmetatype = cacheName(currentSpec, $2);
+ }
+ }
+ ;
+
+defsupertype: TK_DEFSUPERTYPE dottedname {
+ if (notSkipping())
+ {
+ if (currentModule->defsupertype != NULL)
+ yyerror("%DefaultSupertype has already been defined for this module");
+
+ currentModule->defsupertype = cacheName(currentSpec, $2);
+ }
+ }
+ ;
+
+consmodule: TK_CONSMODULE dottedname {
+ /* Make sure this is the first mention of a module. */
+ if (currentSpec->module != currentModule)
+ yyerror("A %ConsolidatedModule cannot be %Imported");
+
+ if (currentModule->fullname != NULL)
+ yyerror("%ConsolidatedModule must appear before any %Module or %CModule directive");
+
+ setModuleName(currentSpec, currentModule, $2);
+ setIsConsolidated(currentModule);
+ }
+ ;
+
+compmodule: TK_COMPOMODULE dottedname {
+ /* Make sure this is the first mention of a module. */
+ if (currentSpec->module != currentModule)
+ yyerror("A %CompositeModule cannot be %Imported");
+
+ if (currentModule->fullname != NULL)
+ yyerror("%CompositeModule must appear before any %Module or %CModule directive");
+
+ setModuleName(currentSpec, currentModule, $2);
+ setIsComposite(currentModule);
+ }
+ ;
+
+module: modlang dottedname optnumber {
+ /* Check the module hasn't already been defined. */
+
+ moduleDef *mod;
+
+ for (mod = currentSpec->modules; mod != NULL; mod = mod->next)
+ if (mod->fullname != NULL && strcmp(mod->fullname->text, $2) == 0)
+ yyerror("Module is already defined");
+
+ /*
+ * If we are in a container module then create a component module
+ * and make it current.
+ */
+ if (isContainer(currentModule) || currentModule->container != NULL)
+ {
+ mod = allocModule();
+
+ mod->file = currentContext.filename;
+ mod->container = (isContainer(currentModule) ? currentModule : currentModule->container);
+
+ currentModule = mod;
+ }
+
+ setModuleName(currentSpec, currentModule, $2);
+ currentModule->version = $3;
+
+ if (currentSpec->genc < 0)
+ currentSpec->genc = $1;
+ else if (currentSpec->genc != $1)
+ yyerror("Cannot mix C and C++ modules");
+ }
+ ;
+
+modlang: TK_MODULE {
+ $$ = FALSE;
+ }
+ | TK_CMODULE {
+ $$ = TRUE;
+ }
+ ;
+
+dottedname: TK_NAME
+ | TK_PATHNAME {
+ /*
+ * The grammar design is a bit broken and this is the easiest way
+ * to allow periods in names.
+ */
+
+ char *cp;
+
+ for (cp = $1; *cp != '\0'; ++cp)
+ if (*cp != '.' && *cp != '_' && !isalnum(*cp))
+ yyerror("Invalid character in name");
+
+ $$ = $1;
+ }
+ ;
+
+optnumber: {
+ $$ = -1;
+ }
+ | TK_NUMBER
+ ;
+
+include: TK_INCLUDE TK_PATHNAME {
+ parseFile(NULL, $2, NULL, FALSE);
+ }
+ ;
+
+optinclude: TK_OPTINCLUDE TK_PATHNAME {
+ parseFile(NULL, $2, NULL, TRUE);
+ }
+ ;
+
+import: TK_IMPORT TK_PATHNAME {
+ newImport($2);
+ }
+ ;
+
+optaccesscode: {
+ $$ = NULL;
+ }
+ | TK_ACCESSCODE codeblock {
+ $$ = $2;
+ }
+ ;
+
+optgetcode: {
+ $$ = NULL;
+ }
+ | TK_GETCODE codeblock {
+ $$ = $2;
+ }
+ ;
+
+optsetcode: {
+ $$ = NULL;
+ }
+ | TK_SETCODE codeblock {
+ $$ = $2;
+ }
+ ;
+
+copying: TK_COPYING codeblock {
+ appendCodeBlock(&currentModule->copying, $2);
+ }
+ ;
+
+exphdrcode: TK_EXPHEADERCODE codeblock {
+ $$ = $2;
+ }
+ ;
+
+modhdrcode: TK_MODHEADERCODE codeblock {
+ $$ = $2;
+ }
+ ;
+
+typehdrcode: TK_TYPEHEADERCODE codeblock {
+ $$ = $2;
+ }
+ ;
+
+opttypehdrcode: {
+ $$ = NULL;
+ }
+ | typehdrcode
+ ;
+
+travcode: TK_TRAVERSECODE codeblock {
+ $$ = $2;
+ }
+ ;
+
+clearcode: TK_CLEARCODE codeblock {
+ $$ = $2;
+ }
+ ;
+
+getbufcode: TK_GETBUFFERCODE codeblock {
+ $$ = $2;
+ }
+ ;
+
+releasebufcode: TK_RELEASEBUFFERCODE codeblock {
+ $$ = $2;
+ }
+ ;
+
+readbufcode: TK_READBUFFERCODE codeblock {
+ $$ = $2;
+ }
+ ;
+
+writebufcode: TK_WRITEBUFFERCODE codeblock {
+ $$ = $2;
+ }
+ ;
+
+segcountcode: TK_SEGCOUNTCODE codeblock {
+ $$ = $2;
+ }
+ ;
+
+charbufcode: TK_CHARBUFFERCODE codeblock {
+ $$ = $2;
+ }
+ ;
+
+picklecode: TK_PICKLECODE codeblock {
+ $$ = $2;
+ }
+ ;
+
+modcode: TK_MODCODE codeblock {
+ $$ = $2;
+ }
+ ;
+
+typecode: TK_TYPECODE codeblock {
+ $$ = $2;
+ }
+ ;
+
+preinitcode: TK_PREINITCODE codeblock {
+ if (notSkipping())
+ appendCodeBlock(&currentModule->preinitcode, $2);
+ }
+ ;
+
+initcode: TK_INITCODE codeblock {
+ if (notSkipping())
+ appendCodeBlock(&currentModule->initcode, $2);
+ }
+ ;
+
+postinitcode: TK_POSTINITCODE codeblock {
+ if (notSkipping())
+ appendCodeBlock(&currentModule->postinitcode, $2);
+ }
+ ;
+
+unitcode: TK_UNITCODE codeblock {
+ if (notSkipping())
+ appendCodeBlock(&currentModule->unitcode, $2);
+ }
+ ;
+
+prepycode: TK_PREPYCODE codeblock {
+ /*
+ * This is a no-op and is retained for compatibility
+ * until the last use of it (by SIP v3) can be removed
+ * from PyQt.
+ */
+ }
+ ;
+
+doc: TK_DOC codeblock {
+ if (inMainModule())
+ appendCodeBlock(&currentSpec -> docs,$2);
+ }
+ ;
+
+exporteddoc: TK_EXPORTEDDOC codeblock {
+ appendCodeBlock(&currentSpec -> docs,$2);
+ }
+ ;
+
+makefile: TK_MAKEFILE TK_PATHNAME optfilename codeblock {
+ if (inMainModule())
+ yywarning("%Makefile is ignored, please use the -b flag instead");
+ }
+ ;
+
+codeblock: codelines TK_END
+ ;
+
+codelines: TK_CODELINE
+ | codelines TK_CODELINE {
+ $$ = $1;
+
+ append(&$$->frag, $2->frag);
+
+ free($2->frag);
+ free((char *)$2->filename);
+ free($2);
+ }
+ ;
+
+enum: TK_ENUM optname optflags {
+ if (notSkipping())
+ {
+ if (sectionFlags != 0 && (sectionFlags & ~(SECT_IS_PUBLIC | SECT_IS_PROT)) != 0)
+ yyerror("Class enums must be in the public or protected sections");
+
+ currentEnum = newEnum(currentSpec, currentModule,
+ currentMappedType, $2, &$3, sectionFlags);
+ }
+ } '{' optenumbody '}' ';'
+ ;
+
+optfilename: {
+ $$ = NULL;
+ }
+ | TK_PATHNAME {
+ $$ = $1;
+ }
+ ;
+
+optname: {
+ $$ = NULL;
+ }
+ | TK_NAME {
+ $$ = $1;
+ }
+ ;
+
+optenumbody:
+ | enumbody
+ ;
+
+enumbody: enumline
+ | enumbody enumline
+ ;
+
+enumline: ifstart
+ | ifend
+ | TK_NAME optenumassign optflags optcomma {
+ if (notSkipping())
+ {
+ enumMemberDef *emd, **tail;
+
+ /* Note that we don't use the assigned value. */
+ emd = sipMalloc(sizeof (enumMemberDef));
+
+ emd -> pyname = cacheName(currentSpec, getPythonName(&$3, $1));
+ emd -> cname = $1;
+ emd -> ed = currentEnum;
+ emd -> next = NULL;
+
+ checkAttributes(currentSpec, currentModule, emd->ed->ecd,
+ emd->ed->emtd, emd->pyname->text, FALSE);
+
+ /* Append to preserve the order. */
+ for (tail = &currentEnum->members; *tail != NULL; tail = &(*tail)->next)
+ ;
+
+ *tail = emd;
+
+ if (inMainModule())
+ setIsUsedName(emd -> pyname);
+ }
+ }
+ ;
+
+optcomma:
+ | ','
+ ;
+
+optenumassign:
+ | '=' value
+ ;
+
+optassign: {
+ $$ = NULL;
+ }
+ | '=' expr {
+ $$ = $2;
+ }
+ ;
+
+expr: value
+ | expr binop value {
+ valueDef *vd;
+
+ if ($1 -> vtype == string_value || $3 -> vtype == string_value)
+ yyerror("Invalid binary operator for string");
+
+ /* Find the last value in the existing expression. */
+
+ for (vd = $1; vd -> next != NULL; vd = vd -> next)
+ ;
+
+ vd -> vbinop = $2;
+ vd -> next = $3;
+
+ $$ = $1;
+ }
+ ;
+
+binop: '-' {
+ $$ = '-';
+ }
+ | '+' {
+ $$ = '+';
+ }
+ | '*' {
+ $$ = '*';
+ }
+ | '/' {
+ $$ = '/';
+ }
+ | '&' {
+ $$ = '&';
+ }
+ | '|' {
+ $$ = '|';
+ }
+ ;
+
+optunop: {
+ $$ = '\0';
+ }
+ | '!' {
+ $$ = '!';
+ }
+ | '~' {
+ $$ = '~';
+ }
+ | '-' {
+ $$ = '-';
+ }
+ | '+' {
+ $$ = '+';
+ }
+ ;
+
+value: optunop simplevalue {
+ if ($1 != '\0' && $2.vtype == string_value)
+ yyerror("Invalid unary operator for string");
+
+ /*
+ * Convert the value to a simple expression on the
+ * heap.
+ */
+
+ $$ = sipMalloc(sizeof (valueDef));
+
+ *$$ = $2;
+ $$ -> vunop = $1;
+ $$ -> vbinop = '\0';
+ $$ -> next = NULL;
+ }
+ ;
+
+scopedname: scopepart
+ | scopedname TK_SCOPE scopepart {
+ if (currentSpec -> genc)
+ yyerror("Scoped names are not allowed in a C module");
+
+ appendScopedName(&$1,$3);
+ }
+ ;
+
+scopepart: TK_NAME {
+ $$ = text2scopePart($1);
+ }
+ ;
+
+simplevalue: scopedname {
+ /*
+ * We let the C++ compiler decide if the value is a valid one - no
+ * point in building a full C++ parser here.
+ */
+
+ $$.vtype = scoped_value;
+ $$.u.vscp = $1;
+ }
+ | basetype '(' exprlist ')' {
+ fcallDef *fcd;
+
+ fcd = sipMalloc(sizeof (fcallDef));
+ *fcd = $3;
+ fcd -> type = $1;
+
+ $$.vtype = fcall_value;
+ $$.u.fcd = fcd;
+ }
+ | TK_REAL {
+ $$.vtype = real_value;
+ $$.u.vreal = $1;
+ }
+ | TK_NUMBER {
+ $$.vtype = numeric_value;
+ $$.u.vnum = $1;
+ }
+ | TK_TRUE {
+ $$.vtype = numeric_value;
+ $$.u.vnum = 1;
+ }
+ | TK_FALSE {
+ $$.vtype = numeric_value;
+ $$.u.vnum = 0;
+ }
+ | TK_NULL {
+ $$.vtype = numeric_value;
+ $$.u.vnum = 0;
+ }
+ | TK_STRING {
+ $$.vtype = string_value;
+ $$.u.vstr = $1;
+ }
+ | TK_QCHAR {
+ $$.vtype = qchar_value;
+ $$.u.vqchar = $1;
+ }
+ ;
+
+exprlist: {
+ /* No values. */
+
+ $$.nrArgs = 0;
+ }
+ | expr {
+ /* The single or first expression. */
+
+ $$.args[0] = $1;
+ $$.nrArgs = 1;
+ }
+ | exprlist ',' expr {
+ /* Check that it wasn't ...(,expression...). */
+
+ if ($$.nrArgs == 0)
+ yyerror("First argument to function call is missing");
+
+ /* Check there is room. */
+
+ if ($1.nrArgs == MAX_NR_ARGS)
+ yyerror("Too many arguments to function call");
+
+ $$ = $1;
+
+ $$.args[$$.nrArgs] = $3;
+ $$.nrArgs++;
+ }
+ ;
+
+typedef: TK_TYPEDEF cpptype TK_NAME optflags ';' {
+ if (notSkipping())
+ {
+ applyTypeFlags(currentModule, &$2, &$4);
+ newTypedef(currentSpec, currentModule, $3, &$2, &$4);
+ }
+ }
+ | TK_TYPEDEF cpptype '(' deref TK_NAME ')' '(' cpptypelist ')' optflags ';' {
+ if (notSkipping())
+ {
+ signatureDef *sig;
+ argDef ftype;
+
+ applyTypeFlags(currentModule, &$2, &$10);
+
+ memset(&ftype, 0, sizeof (argDef));
+
+ /* Create the full signature on the heap. */
+ sig = sipMalloc(sizeof (signatureDef));
+ *sig = $8;
+ sig->result = $2;
+
+ /* Create the full type. */
+ ftype.atype = function_type;
+ ftype.nrderefs = $4;
+ ftype.u.sa = sig;
+
+ newTypedef(currentSpec, currentModule, $5, &ftype, &$10);
+ }
+ }
+ ;
+
+struct: TK_STRUCT scopedname {
+ if (currentSpec -> genc && $2->next != NULL)
+ yyerror("Namespaces not allowed in a C module");
+
+ if (notSkipping())
+ currentSupers = NULL;
+ } superclasses optflags {
+ if (notSkipping())
+ {
+ if (currentSpec->genc && currentSupers != NULL)
+ yyerror("Super-classes not allowed in a C module struct");
+
+ defineClass($2, currentSupers, &$5);
+ sectionFlags = SECT_IS_PUBLIC;
+ }
+ } optclassbody ';' {
+ if (notSkipping())
+ completeClass($2, &$5, $7);
+ }
+ ;
+
+classtmpl: template {currentIsTemplate = TRUE;} class {
+ if (currentSpec->genc)
+ yyerror("Class templates not allowed in a C module");
+
+ if (notSkipping())
+ {
+ classTmplDef *tcd;
+
+ /*
+ * Make sure there is room for the extra class name argument.
+ */
+ if ($1.nrArgs == MAX_NR_ARGS)
+ yyerror("Internal error - increase the value of MAX_NR_ARGS");
+
+ tcd = sipMalloc(sizeof (classTmplDef));
+ tcd->sig = $1;
+ tcd->cd = $3;
+ tcd->next = currentSpec->classtemplates;
+
+ currentSpec->classtemplates = tcd;
+ }
+
+ currentIsTemplate = FALSE;
+ }
+ ;
+
+template: TK_TEMPLATE '<' cpptypelist '>' {
+ $$ = $3;
+ }
+ ;
+
+class: TK_CLASS scopedname {
+ if (currentSpec->genc)
+ yyerror("Class definition not allowed in a C module");
+
+ if (notSkipping())
+ currentSupers = NULL;
+ } superclasses optflags {
+ if (notSkipping())
+ {
+ defineClass($2, currentSupers, &$5);
+ sectionFlags = SECT_IS_PRIVATE;
+ }
+ } optclassbody ';' {
+ if (notSkipping())
+ $$ = completeClass($2, &$5, $7);
+ }
+ ;
+
+superclasses:
+ | ':' superlist
+ ;
+
+superlist: superclass
+ | superlist ',' superclass
+ ;
+
+superclass: scopedname {
+ if (notSkipping())
+ {
+ argDef ad;
+ classDef *super;
+ scopedNameDef *snd = $1;
+
+ /*
+ * This is a hack to allow typedef'ed classes to be used before
+ * we have resolved the typedef definitions. Unlike elsewhere,
+ * we require that the typedef is defined before being used.
+ */
+ for (;;)
+ {
+ ad.atype = no_type;
+ ad.argflags = 0;
+ ad.nrderefs = 0;
+ ad.original_type = NULL;
+
+ searchTypedefs(currentSpec, snd, &ad);
+
+ if (ad.atype != defined_type)
+ break;
+
+ if (ad.nrderefs != 0 || isConstArg(&ad) || isReference(&ad))
+ break;
+
+ snd = ad.u.snd;
+ }
+
+ if (ad.atype != no_type)
+ yyerror("Super-class list contains an invalid type");
+
+ super = findClass(currentSpec, class_iface, NULL, snd);
+ appendToClassList(&currentSupers, super);
+ }
+ }
+ ;
+
+optclassbody: {
+ $$ = FALSE;
+ }
+ | '{' classbody '}' {
+ $$ = TRUE;
+ }
+ ;
+
+classbody: classline
+ | classbody classline
+ ;
+
+classline: ifstart
+ | ifend
+ | namespace
+ | struct
+ | class
+ | exception
+ | typedef
+ | enum
+ | docstring {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ /* Make sure this is before any ctor docstrings. */
+ $1->next = scope->docstring;
+ scope->docstring = $1;
+ }
+ }
+ | typecode {
+ if (notSkipping())
+ appendCodeBlock(&currentScope()->cppcode, $1);
+ }
+ | typehdrcode {
+ if (notSkipping())
+ appendCodeBlock(&currentScope()->iff->hdrcode, $1);
+ }
+ | travcode {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ if (scope->travcode != NULL)
+ yyerror("%GCTraverseCode already given for class");
+
+ scope->travcode = $1;
+ }
+ }
+ | clearcode {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ if (scope->clearcode != NULL)
+ yyerror("%GCClearCode already given for class");
+
+ scope->clearcode = $1;
+ }
+ }
+ | getbufcode {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ if (scope->getbufcode != NULL)
+ yyerror("%BIGetBufferCode already given for class");
+
+ scope->getbufcode = $1;
+ }
+ }
+ | releasebufcode {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ if (scope->releasebufcode != NULL)
+ yyerror("%BIReleaseBufferCode already given for class");
+
+ scope->releasebufcode = $1;
+ }
+ }
+ | readbufcode {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ if (scope->readbufcode != NULL)
+ yyerror("%BIGetReadBufferCode already given for class");
+
+ scope->readbufcode = $1;
+ }
+ }
+ | writebufcode {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ if (scope->writebufcode != NULL)
+ yyerror("%BIGetWriteBufferCode already given for class");
+
+ scope->writebufcode = $1;
+ }
+ }
+ | segcountcode {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ if (scope->segcountcode != NULL)
+ yyerror("%BIGetSegCountCode already given for class");
+
+ scope->segcountcode = $1;
+ }
+ }
+ | charbufcode {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ if (scope->charbufcode != NULL)
+ yyerror("%BIGetCharBufferCode already given for class");
+
+ scope->charbufcode = $1;
+ }
+ }
+ | picklecode {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ if (scope->picklecode != NULL)
+ yyerror("%PickleCode already given for class");
+
+ scope->picklecode = $1;
+ }
+ }
+ | ctor
+ | dtor
+ | varmember
+ | TK_TOSUBCLASS codeblock {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ if (scope->convtosubcode != NULL)
+ yyerror("Class has more than one %ConvertToSubClassCode directive");
+
+ scope->convtosubcode = $2;
+ }
+ }
+ | TK_TOTYPE codeblock {
+ if (notSkipping())
+ {
+ classDef *scope = currentScope();
+
+ if (scope->convtocode != NULL)
+ yyerror("Class has more than one %ConvertToTypeCode directive");
+
+ scope->convtocode = $2;
+ }
+ }
+ | TK_PUBLIC optslot ':' {
+ if (currentSpec -> genc)
+ yyerror("public section not allowed in a C module");
+
+ if (notSkipping())
+ sectionFlags = SECT_IS_PUBLIC | $2;
+ }
+ | TK_PROTECTED optslot ':' {
+ if (currentSpec -> genc)
+ yyerror("protected section not allowed in a C module");
+
+ if (notSkipping())
+ sectionFlags = SECT_IS_PROT | $2;
+ }
+ | TK_PRIVATE optslot ':' {
+ if (currentSpec -> genc)
+ yyerror("private section not allowed in a C module");
+
+ if (notSkipping())
+ sectionFlags = SECT_IS_PRIVATE | $2;
+ }
+ | TK_SIGNALS ':' {
+ if (currentSpec -> genc)
+ yyerror("signals section not allowed in a C module");
+
+ if (notSkipping())
+ sectionFlags = SECT_IS_SIGNAL;
+ }
+ ;
+
+optslot: {
+ $$ = 0;
+ }
+ | TK_SLOTS {
+ $$ = SECT_IS_SLOT;
+ }
+ ;
+
+dtor: optvirtual '~' TK_NAME '(' ')' optexceptions optabstract optflags ';' methodcode virtualcatchercode {
+ /* Note that we allow non-virtual dtors in C modules. */
+
+ if (notSkipping())
+ {
+ classDef *cd = currentScope();
+
+ if (strcmp(classBaseName(cd),$3) != 0)
+ yyerror("Destructor doesn't have the same name as its class");
+
+ if (isDtor(cd))
+ yyerror("Destructor has already been defined");
+
+ if (currentSpec -> genc && $10 == NULL)
+ yyerror("Destructor in C modules must include %MethodCode");
+
+ cd -> dealloccode = $10;
+ cd -> dtorcode = $11;
+ cd -> dtorexceptions = $6;
+
+ /*
+ * Note that we don't apply the protected/public hack to dtors
+ * as it (I think) may change the behaviour of the wrapped API.
+ */
+ cd->classflags |= sectionFlags;
+
+ if ($7)
+ {
+ if (!$1)
+ yyerror("Abstract destructor must be virtual");
+
+ setIsAbstractClass(cd);
+ }
+
+ /*
+ * The class has a shadow if we have a virtual dtor or some
+ * dtor code.
+ */
+ if ($1 || $11 != NULL)
+ {
+ if (currentSpec -> genc)
+ yyerror("Virtual destructor or %VirtualCatcherCode not allowed in a C module");
+
+ setHasShadow(cd);
+ }
+
+ if (getReleaseGIL(&$8))
+ setIsReleaseGILDtor(cd);
+ else if (getHoldGIL(&$8))
+ setIsHoldGILDtor(cd);
+ }
+ }
+ ;
+
+ctor: TK_EXPLICIT {currentCtorIsExplicit = TRUE;} simplector
+ | simplector
+ ;
+
+simplector: TK_NAME '(' arglist ')' optexceptions optflags optctorsig ';' optdocstring methodcode {
+ /* Note that we allow ctors in C modules. */
+
+ if (notSkipping())
+ {
+ if (currentSpec -> genc)
+ {
+ if ($10 == NULL && $3.nrArgs != 0)
+ yyerror("Constructors with arguments in C modules must include %MethodCode");
+
+ if (currentCtorIsExplicit)
+ yyerror("Explicit constructors not allowed in a C module");
+ }
+
+ if ((sectionFlags & (SECT_IS_PUBLIC | SECT_IS_PROT | SECT_IS_PRIVATE)) == 0)
+ yyerror("Constructor must be in the public, private or protected sections");
+
+ newCtor($1, sectionFlags, &$3, &$6, $10, $5, $7,
+ currentCtorIsExplicit, $9);
+ }
+
+ free($1);
+
+ currentCtorIsExplicit = FALSE;
+ }
+ ;
+
+optctorsig: {
+ $$ = NULL;
+ }
+ | '[' '(' arglist ')' ']' {
+ $$ = sipMalloc(sizeof (signatureDef));
+
+ *$$ = $3;
+ }
+ ;
+
+optsig: {
+ $$ = NULL;
+ }
+ | '[' cpptype '(' arglist ')' ']' {
+ $$ = sipMalloc(sizeof (signatureDef));
+
+ *$$ = $4;
+ $$ -> result = $2;
+ }
+ ;
+
+optvirtual: {
+ $$ = FALSE;
+ }
+ | TK_VIRTUAL {
+ $$ = TRUE;
+ }
+ ;
+
+function: cpptype TK_NAME '(' arglist ')' optconst optexceptions optabstract optflags optsig ';' optdocstring methodcode virtualcatchercode {
+ if (notSkipping())
+ {
+ applyTypeFlags(currentModule, &$1, &$9);
+
+ $4.result = $1;
+
+ newFunction(currentSpec, currentModule, currentScope(), NULL,
+ sectionFlags, currentIsStatic, currentIsSignal,
+ currentIsSlot, currentOverIsVirt, $2, &$4, $6, $8, &$9,
+ $13, $14, $7, $10, $12);
+ }
+
+ currentIsStatic = FALSE;
+ currentIsSignal = FALSE;
+ currentIsSlot = FALSE;
+ currentOverIsVirt = FALSE;
+ }
+ | cpptype TK_OPERATOR '=' '(' cpptype ')' ';' {
+ /*
+ * It looks like an assignment operator (though we don't bother to
+ * check the types) so make sure it is private.
+ */
+ if (notSkipping())
+ {
+ classDef *cd = currentScope();
+
+ if (cd == NULL || !(sectionFlags & SECT_IS_PRIVATE))
+ yyerror("Assignment operators may only be defined as private");
+
+ setCannotAssign(cd);
+ }
+
+ currentIsStatic = FALSE;
+ currentIsSignal = FALSE;
+ currentIsSlot = FALSE;
+ currentOverIsVirt = FALSE;
+ }
+ | cpptype TK_OPERATOR operatorname '(' arglist ')' optconst optexceptions optabstract optflags optsig ';' methodcode virtualcatchercode {
+ if (notSkipping())
+ {
+ classDef *cd = currentScope();
+
+ applyTypeFlags(currentModule, &$1, &$10);
+
+ /* Handle the unary '+' and '-' operators. */
+ if ((cd != NULL && $5.nrArgs == 0) || (cd == NULL && $5.nrArgs == 1))
+ {
+ if (strcmp($3, "__add__") == 0)
+ $3 = "__pos__";
+ else if (strcmp($3, "__sub__") == 0)
+ $3 = "__neg__";
+ }
+
+ $5.result = $1;
+
+ newFunction(currentSpec, currentModule, cd, NULL,
+ sectionFlags, currentIsStatic, currentIsSignal,
+ currentIsSlot, currentOverIsVirt, $3, &$5, $7, $9,
+ &$10, $13, $14, $8, $11, NULL);
+ }
+
+ currentIsStatic = FALSE;
+ currentIsSignal = FALSE;
+ currentIsSlot = FALSE;
+ currentOverIsVirt = FALSE;
+ }
+ | TK_OPERATOR cpptype '(' arglist ')' optconst optexceptions optabstract optflags optsig ';' methodcode virtualcatchercode {
+ if (notSkipping())
+ {
+ char *sname;
+ classDef *scope = currentScope();
+
+ if (scope == NULL || $4.nrArgs != 0)
+ yyerror("Operator casts must be specified in a class and have no arguments");
+
+ applyTypeFlags(currentModule, &$2, &$9);
+
+ switch ($2.atype)
+ {
+ case defined_type:
+ sname = NULL;
+ break;
+
+ case bool_type:
+ case cbool_type:
+ case short_type:
+ case ushort_type:
+ case int_type:
+ case cint_type:
+ case uint_type:
+ sname = "__int__";
+ break;
+
+ case long_type:
+ case ulong_type:
+ case longlong_type:
+ case ulonglong_type:
+ sname = "__long__";
+ break;
+
+ case float_type:
+ case cfloat_type:
+ case double_type:
+ case cdouble_type:
+ sname = "__float__";
+ break;
+
+ default:
+ yyerror("Unsupported operator cast");
+ }
+
+ if (sname != NULL)
+ {
+ $4.result = $2;
+
+ newFunction(currentSpec, currentModule, scope, NULL,
+ sectionFlags, currentIsStatic, currentIsSignal,
+ currentIsSlot, currentOverIsVirt, sname, &$4, $6,
+ $8, &$9, $12, $13, $7, $10, NULL);
+ }
+ else
+ {
+ argList *al;
+
+ /* Check it doesn't already exist. */
+ for (al = scope->casts; al != NULL; al = al->next)
+ if (compareScopedNames($2.u.snd, al->arg.u.snd) == 0)
+ yyerror("This operator cast has already been specified in this class");
+
+ al = sipMalloc(sizeof (argList));
+ al->arg = $2;
+ al->next = scope->casts;
+
+ scope->casts = al;
+ }
+ }
+
+ currentIsStatic = FALSE;
+ currentIsSignal = FALSE;
+ currentIsSlot = FALSE;
+ currentOverIsVirt = FALSE;
+ }
+ ;
+
+operatorname: '+' {$$ = "__add__";}
+ | '-' {$$ = "__sub__";}
+ | '*' {$$ = "__mul__";}
+ | '/' {$$ = "__div__";}
+ | '%' {$$ = "__mod__";}
+ | '&' {$$ = "__and__";}
+ | '|' {$$ = "__or__";}
+ | '^' {$$ = "__xor__";}
+ | '<' '<' {$$ = "__lshift__";}
+ | '>' '>' {$$ = "__rshift__";}
+ | '+' '=' {$$ = "__iadd__";}
+ | '-' '=' {$$ = "__isub__";}
+ | '*' '=' {$$ = "__imul__";}
+ | '/' '=' {$$ = "__idiv__";}
+ | '%' '=' {$$ = "__imod__";}
+ | '&' '=' {$$ = "__iand__";}
+ | '|' '=' {$$ = "__ior__";}
+ | '^' '=' {$$ = "__ixor__";}
+ | '<' '<' '=' {$$ = "__ilshift__";}
+ | '>' '>' '=' {$$ = "__irshift__";}
+ | '~' {$$ = "__invert__";}
+ | '(' ')' {$$ = "__call__";}
+ | '[' ']' {$$ = "__getitem__";}
+ | '<' {$$ = "__lt__";}
+ | '<' '=' {$$ = "__le__";}
+ | '=' '=' {$$ = "__eq__";}
+ | '!' '=' {$$ = "__ne__";}
+ | '>' {$$ = "__gt__";}
+ | '>' '=' {$$ = "__ge__";}
+ ;
+
+optconst: {
+ $$ = FALSE;
+ }
+ | TK_CONST {
+ $$ = TRUE;
+ }
+ ;
+
+optabstract: {
+ $$ = 0;
+ }
+ | '=' TK_NUMBER {
+ if ($2 != 0)
+ yyerror("Abstract virtual function '= 0' expected");
+
+ $$ = TRUE;
+ }
+ ;
+
+optflags: {
+ $$.nrFlags = 0;
+ }
+ | '/' flaglist '/' {
+ $$ = $2;
+ }
+ ;
+
+
+flaglist: flag {
+ $$.flags[0] = $1;
+ $$.nrFlags = 1;
+ }
+ | flaglist ',' flag {
+ /* Check there is room. */
+
+ if ($1.nrFlags == MAX_NR_FLAGS)
+ yyerror("Too many optional flags");
+
+ $$ = $1;
+
+ $$.flags[$$.nrFlags++] = $3;
+ }
+ ;
+
+flag: TK_NAME {
+ $$.ftype = bool_flag;
+ $$.fname = $1;
+ }
+ | TK_NAME '=' flagvalue {
+ $$ = $3;
+ $$.fname = $1;
+ }
+ ;
+
+flagvalue: dottedname {
+ $$.ftype = (strchr($1, '.') != NULL) ? dotted_name_flag : name_flag;
+ $$.fvalue.sval = $1;
+ }
+ | TK_NAME ':' optnumber '-' optnumber {
+ apiVersionRangeDef *avd;
+ int from, to;
+
+ $$.ftype = api_range_flag;
+
+ /* Check that the API is known. */
+ if ((avd = findAPI(currentSpec, $1)) == NULL)
+ yyerror("unknown API name in API annotation");
+
+ if (inMainModule())
+ setIsUsedName(avd->api_name);
+
+ /* Unbounded values are represented by 0. */
+ if ((from = $3) < 0)
+ from = 0;
+
+ if ((to = $5) < 0)
+ to = 0;
+
+ $$.fvalue.aval = convertAPIRange(currentModule, avd->api_name,
+ from, to);
+ }
+ | TK_STRING {
+ $$.ftype = string_flag;
+ $$.fvalue.sval = convertFeaturedString($1);
+ }
+ | TK_NUMBER {
+ $$.ftype = integer_flag;
+ $$.fvalue.ival = $1;
+ }
+ ;
+
+docstring: TK_DOCSTRING codeblock {
+ $$ = $2;
+ }
+ ;
+
+optdocstring: {
+ $$ = NULL;
+ }
+ | docstring
+ ;
+
+methodcode: {
+ $$ = NULL;
+ }
+ | TK_METHODCODE codeblock {
+ $$ = $2;
+ }
+ ;
+
+virtualcatchercode: {
+ $$ = NULL;
+ }
+ | TK_VIRTUALCATCHERCODE codeblock {
+ $$ = $2;
+ }
+ ;
+
+arglist: rawarglist {
+ int a, nrrxcon, nrrxdis, nrslotcon, nrslotdis, nrarray, nrarraysize;
+
+ nrrxcon = nrrxdis = nrslotcon = nrslotdis = nrarray = nrarraysize = 0;
+
+ for (a = 0; a < $1.nrArgs; ++a)
+ {
+ argDef *ad = &$1.args[a];
+
+ switch (ad -> atype)
+ {
+ case rxcon_type:
+ ++nrrxcon;
+ break;
+
+ case rxdis_type:
+ ++nrrxdis;
+ break;
+
+ case slotcon_type:
+ ++nrslotcon;
+ break;
+
+ case slotdis_type:
+ ++nrslotdis;
+ break;
+ }
+
+ if (isArray(ad))
+ ++nrarray;
+
+ if (isArraySize(ad))
+ ++nrarraysize;
+ }
+
+ if (nrrxcon != nrslotcon || nrrxcon > 1)
+ yyerror("SIP_RXOBJ_CON and SIP_SLOT_CON must both be given and at most once");
+
+ if (nrrxdis != nrslotdis || nrrxdis > 1)
+ yyerror("SIP_RXOBJ_DIS and SIP_SLOT_DIS must both be given and at most once");
+
+ if (nrarray != nrarraysize || nrarray > 1)
+ yyerror("/Array/ and /ArraySize/ must both be given and at most once");
+
+ $$ = $1;
+ }
+ ;
+
+rawarglist: {
+ /* No arguments. */
+
+ $$.nrArgs = 0;
+ }
+ | argvalue {
+ /* The single or first argument. */
+
+ $$.args[0] = $1;
+ $$.nrArgs = 1;
+ }
+ | rawarglist ',' argvalue {
+ /* Check that it wasn't ...(,arg...). */
+ if ($1.nrArgs == 0)
+ yyerror("First argument of the list is missing");
+
+ /* Check there is nothing after an ellipsis. */
+ if ($1.args[$1.nrArgs - 1].atype == ellipsis_type)
+ yyerror("An ellipsis must be at the end of the argument list");
+
+ /*
+ * If this argument has no default value, then the
+ * previous one mustn't either.
+ */
+ if ($3.defval == NULL && $1.args[$1.nrArgs - 1].defval != NULL)
+ yyerror("Compulsory argument given after optional argument");
+
+ /* Check there is room. */
+ if ($1.nrArgs == MAX_NR_ARGS)
+ yyerror("Internal error - increase the value of MAX_NR_ARGS");
+
+ $$ = $1;
+
+ $$.args[$$.nrArgs] = $3;
+ $$.nrArgs++;
+ }
+ ;
+
+argvalue: TK_SIPSIGNAL optname optflags optassign {
+ $$.atype = signal_type;
+ $$.argflags = ARG_IS_CONST;
+ $$.nrderefs = 0;
+ $$.name = cacheName(currentSpec, $2);
+ $$.defval = $4;
+
+ currentSpec -> sigslots = TRUE;
+ }
+ | TK_SIPSLOT optname optflags optassign {
+ $$.atype = slot_type;
+ $$.argflags = ARG_IS_CONST;
+ $$.nrderefs = 0;
+ $$.name = cacheName(currentSpec, $2);
+ $$.defval = $4;
+
+ currentSpec -> sigslots = TRUE;
+ }
+ | TK_SIPANYSLOT optname optflags optassign {
+ $$.atype = anyslot_type;
+ $$.argflags = ARG_IS_CONST;
+ $$.nrderefs = 0;
+ $$.name = cacheName(currentSpec, $2);
+ $$.defval = $4;
+
+ currentSpec -> sigslots = TRUE;
+ }
+ | TK_SIPRXCON optname optflags {
+ $$.atype = rxcon_type;
+ $$.argflags = 0;
+ $$.nrderefs = 0;
+ $$.name = cacheName(currentSpec, $2);
+
+ if (findOptFlag(&$3, "SingleShot", bool_flag) != NULL)
+ $$.argflags |= ARG_SINGLE_SHOT;
+
+ currentSpec -> sigslots = TRUE;
+ }
+ | TK_SIPRXDIS optname optflags {
+ $$.atype = rxdis_type;
+ $$.argflags = 0;
+ $$.nrderefs = 0;
+ $$.name = cacheName(currentSpec, $2);
+
+ currentSpec -> sigslots = TRUE;
+ }
+ | TK_SIPSLOTCON '(' arglist ')' optname optflags {
+ $$.atype = slotcon_type;
+ $$.argflags = ARG_IS_CONST;
+ $$.nrderefs = 0;
+ $$.name = cacheName(currentSpec, $5);
+
+ memset(&$3.result, 0, sizeof (argDef));
+ $3.result.atype = void_type;
+
+ $$.u.sa = sipMalloc(sizeof (signatureDef));
+ *$$.u.sa = $3;
+
+ currentSpec -> sigslots = TRUE;
+ }
+ | TK_SIPSLOTDIS '(' arglist ')' optname optflags {
+ $$.atype = slotdis_type;
+ $$.argflags = ARG_IS_CONST;
+ $$.nrderefs = 0;
+ $$.name = cacheName(currentSpec, $5);
+
+ memset(&$3.result, 0, sizeof (argDef));
+ $3.result.atype = void_type;
+
+ $$.u.sa = sipMalloc(sizeof (signatureDef));
+ *$$.u.sa = $3;
+
+ currentSpec -> sigslots = TRUE;
+ }
+ | TK_QOBJECT optname optflags {
+ $$.atype = qobject_type;
+ $$.argflags = 0;
+ $$.nrderefs = 0;
+ $$.name = cacheName(currentSpec, $2);
+ }
+ | argtype optassign {
+ $$ = $1;
+ $$.defval = $2;
+ }
+ ;
+
+varmember:
+ TK_SIGNAL_METHOD {currentIsSignal = TRUE;} simple_varmem
+ | TK_SLOT_METHOD {currentIsSlot = TRUE;} simple_varmem
+ | simple_varmem
+ ;
+
+simple_varmem:
+ TK_STATIC {currentIsStatic = TRUE;} varmem
+ | varmem
+ ;
+
+varmem:
+ member
+ | variable
+ ;
+
+member:
+ TK_VIRTUAL {currentOverIsVirt = TRUE;} function
+ | function
+ ;
+
+variable: cpptype TK_NAME optflags ';' optaccesscode optgetcode optsetcode {
+ if (notSkipping())
+ {
+ /* Check the section. */
+
+ if (sectionFlags != 0)
+ {
+ if ((sectionFlags & SECT_IS_PUBLIC) == 0)
+ yyerror("Class variables must be in the public section");
+
+ if (!currentIsStatic && $5 != NULL)
+ yyerror("%AccessCode cannot be specified for non-static class variables");
+ }
+
+ if (currentIsStatic && currentSpec -> genc)
+ yyerror("Cannot have static members in a C structure");
+
+ applyTypeFlags(currentModule, &$1, &$3);
+
+ if ($6 != NULL || $7 != NULL)
+ {
+ if ($5 != NULL)
+ yyerror("Cannot mix %AccessCode and %GetCode or %SetCode");
+
+ if (currentScope() == NULL)
+ yyerror("Cannot specify %GetCode or %SetCode for global variables");
+ }
+
+ newVar(currentSpec,currentModule,$2,currentIsStatic,&$1,&$3,$5,$6,$7);
+ }
+
+ currentIsStatic = FALSE;
+ }
+ ;
+
+cpptype: TK_CONST basetype deref optref {
+ $$ = $2;
+ $$.nrderefs += $3;
+ $$.argflags |= ARG_IS_CONST | $4;
+ }
+ | basetype deref optref {
+ $$ = $1;
+ $$.nrderefs += $2;
+ $$.argflags |= $3;
+ }
+ ;
+
+argtype: cpptype optname optflags {
+ $$ = $1;
+ $$.name = cacheName(currentSpec, $2);
+
+ if (getAllowNone(&$3))
+ $$.argflags |= ARG_ALLOW_NONE;
+
+ if (findOptFlag(&$3,"GetWrapper",bool_flag) != NULL)
+ $$.argflags |= ARG_GET_WRAPPER;
+
+ if (findOptFlag(&$3,"Array",bool_flag) != NULL)
+ $$.argflags |= ARG_ARRAY;
+
+ if (findOptFlag(&$3,"ArraySize",bool_flag) != NULL)
+ $$.argflags |= ARG_ARRAY_SIZE;
+
+ if (getTransfer(&$3))
+ $$.argflags |= ARG_XFERRED;
+
+ if (findOptFlag(&$3,"TransferThis",bool_flag) != NULL)
+ $$.argflags |= ARG_THIS_XFERRED;
+
+ if (findOptFlag(&$3,"TransferBack",bool_flag) != NULL)
+ $$.argflags |= ARG_XFERRED_BACK;
+
+ if (findOptFlag(&$3, "KeepReference", bool_flag) != NULL)
+ {
+ $$.argflags |= ARG_KEEP_REF;
+ $$.key = currentModule->next_key++;
+ }
+
+ if (findOptFlag(&$3,"In",bool_flag) != NULL)
+ $$.argflags |= ARG_IN;
+
+ if (findOptFlag(&$3,"Out",bool_flag) != NULL)
+ $$.argflags |= ARG_OUT;
+
+ if (findOptFlag(&$3, "ResultSize", bool_flag) != NULL)
+ $$.argflags |= ARG_RESULT_SIZE;
+
+ if (findOptFlag(&$3, "NoCopy", bool_flag) != NULL)
+ $$.argflags |= ARG_NO_COPY;
+
+ if (findOptFlag(&$3,"Constrained",bool_flag) != NULL)
+ {
+ $$.argflags |= ARG_CONSTRAINED;
+
+ switch ($$.atype)
+ {
+ case bool_type:
+ $$.atype = cbool_type;
+ break;
+
+ case int_type:
+ $$.atype = cint_type;
+ break;
+
+ case float_type:
+ $$.atype = cfloat_type;
+ break;
+
+ case double_type:
+ $$.atype = cdouble_type;
+ break;
+ }
+ }
+
+ applyTypeFlags(currentModule, &$$, &$3);
+ $$.docval = getDocValue(&$3);
+ }
+ ;
+
+optref: {
+ $$ = 0;
+ }
+ | '&' {
+ if (currentSpec -> genc)
+ yyerror("References not allowed in a C module");
+
+ $$ = ARG_IS_REF;
+ }
+ ;
+
+deref: {
+ $$ = 0;
+ }
+ | deref '*' {
+ $$ = $1 + 1;
+ }
+ ;
+
+basetype: scopedname {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = defined_type;
+ $$.u.snd = $1;
+
+ /* Try and resolve typedefs as early as possible. */
+ resolveAnyTypedef(currentSpec, &$$);
+ }
+ | scopedname '<' cpptypelist '>' {
+ templateDef *td;
+
+ td = sipMalloc(sizeof(templateDef));
+ td->fqname = $1;
+ td->types = $3;
+
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = template_type;
+ $$.u.td = td;
+ }
+ | TK_STRUCT scopedname {
+ memset(&$$, 0, sizeof (argDef));
+
+ /* In a C module all structures must be defined. */
+ if (currentSpec -> genc)
+ {
+ $$.atype = defined_type;
+ $$.u.snd = $2;
+ }
+ else
+ {
+ $$.atype = struct_type;
+ $$.u.sname = $2;
+ }
+ }
+ | TK_UNSIGNED TK_SHORT {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = ushort_type;
+ }
+ | TK_SHORT {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = short_type;
+ }
+ | TK_UNSIGNED {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = uint_type;
+ }
+ | TK_UNSIGNED TK_INT {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = uint_type;
+ }
+ | TK_INT {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = int_type;
+ }
+ | TK_LONG {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = long_type;
+ }
+ | TK_UNSIGNED TK_LONG {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = ulong_type;
+ }
+ | TK_LONG TK_LONG {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = longlong_type;
+ }
+ | TK_UNSIGNED TK_LONG TK_LONG {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = ulonglong_type;
+ }
+ | TK_FLOAT {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = float_type;
+ }
+ | TK_DOUBLE {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = double_type;
+ }
+ | TK_BOOL {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = bool_type;
+ }
+ | TK_SIGNED TK_CHAR {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = sstring_type;
+ }
+ | TK_UNSIGNED TK_CHAR {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = ustring_type;
+ }
+ | TK_CHAR {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = string_type;
+ }
+ | TK_WCHAR_T {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = wstring_type;
+ }
+ | TK_VOID {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = void_type;
+ }
+ | TK_PYOBJECT {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = pyobject_type;
+ }
+ | TK_PYTUPLE {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = pytuple_type;
+ }
+ | TK_PYLIST {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = pylist_type;
+ }
+ | TK_PYDICT {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = pydict_type;
+ }
+ | TK_PYCALLABLE {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = pycallable_type;
+ }
+ | TK_PYSLICE {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = pyslice_type;
+ }
+ | TK_PYTYPE {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = pytype_type;
+ }
+ | TK_ELLIPSIS {
+ memset(&$$, 0, sizeof (argDef));
+ $$.atype = ellipsis_type;
+ }
+ ;
+
+cpptypelist: cpptype {
+ /* The single or first type. */
+
+ $$.args[0] = $1;
+ $$.nrArgs = 1;
+ }
+ | cpptypelist ',' cpptype {
+ /* Check there is nothing after an ellipsis. */
+ if ($1.args[$1.nrArgs - 1].atype == ellipsis_type)
+ yyerror("An ellipsis must be at the end of the argument list");
+
+ /* Check there is room. */
+ if ($1.nrArgs == MAX_NR_ARGS)
+ yyerror("Internal error - increase the value of MAX_NR_ARGS");
+
+ $$ = $1;
+
+ $$.args[$$.nrArgs] = $3;
+ $$.nrArgs++;
+ }
+ ;
+
+optexceptions: {
+ $$ = NULL;
+ }
+ | TK_THROW '(' exceptionlist ')' {
+ if (currentSpec->genc)
+ yyerror("Exceptions not allowed in a C module");
+
+ $$ = $3;
+ }
+ ;
+
+exceptionlist: {
+ /* Empty list so use a blank. */
+
+ $$ = sipMalloc(sizeof (throwArgs));
+ $$ -> nrArgs = 0;
+ }
+ | scopedname {
+ /* The only or first exception. */
+
+ $$ = sipMalloc(sizeof (throwArgs));
+ $$ -> nrArgs = 1;
+ $$ -> args[0] = findException(currentSpec, $1, FALSE);
+ }
+ | exceptionlist ',' scopedname {
+ /* Check that it wasn't ...(,arg...). */
+
+ if ($1 -> nrArgs == 0)
+ yyerror("First exception of throw specifier is missing");
+
+ /* Check there is room. */
+
+ if ($1 -> nrArgs == MAX_NR_ARGS)
+ yyerror("Internal error - increase the value of MAX_NR_ARGS");
+
+ $$ = $1;
+ $$ -> args[$$ -> nrArgs++] = findException(currentSpec, $3, FALSE);
+ }
+ ;
+
+%%
+
+
+/*
+ * Parse the specification.
+ */
+void parse(sipSpec *spec, FILE *fp, char *filename, stringList *tsl,
+ stringList *xfl, int kwdArgs, int protHack)
+{
+ classTmplDef *tcd;
+
+ /* Initialise the spec. */
+
+ spec->modules = NULL;
+ spec->namecache = NULL;
+ spec->ifacefiles = NULL;
+ spec->classes = NULL;
+ spec->classtemplates = NULL;
+ spec->exceptions = NULL;
+ spec->mappedtypes = NULL;
+ spec->mappedtypetemplates = NULL;
+ spec->enums = NULL;
+ spec->vars = NULL;
+ spec->typedefs = NULL;
+ spec->exphdrcode = NULL;
+ spec->docs = NULL;
+ spec->sigslots = FALSE;
+ spec->genc = -1;
+ spec->plugins = NULL;
+
+ currentSpec = spec;
+ neededQualifiers = tsl;
+ excludedQualifiers = xfl;
+ currentModule = NULL;
+ currentMappedType = NULL;
+ currentOverIsVirt = FALSE;
+ currentCtorIsExplicit = FALSE;
+ currentIsStatic = FALSE;
+ currentIsSignal = FALSE;
+ currentIsSlot = FALSE;
+ currentIsTemplate = FALSE;
+ previousFile = NULL;
+ skipStackPtr = 0;
+ currentScopeIdx = 0;
+ sectionFlags = 0;
+ defaultKwdArgs = kwdArgs;
+ makeProtPublic = protHack;
+
+ newModule(fp, filename);
+ spec->module = currentModule;
+
+ yyparse();
+
+ handleEOF();
+ handleEOM();
+
+ /*
+ * Go through each template class and remove it from the list of classes.
+ */
+ for (tcd = spec->classtemplates; tcd != NULL; tcd = tcd->next)
+ {
+ classDef **cdp;
+
+ for (cdp = &spec->classes; *cdp != NULL; cdp = &(*cdp)->next)
+ if (*cdp == tcd->cd)
+ {
+ ifaceFileDef **ifdp;
+
+ /* Remove the interface file as well. */
+ for (ifdp = &spec->ifacefiles; *ifdp != NULL; ifdp = &(*ifdp)->next)
+ if (*ifdp == tcd->cd->iff)
+ {
+ *ifdp = (*ifdp)->next;
+ break;
+ }
+
+ *cdp = (*cdp)->next;
+ break;
+ }
+ }
+}
+
+
+/*
+ * Tell the parser that a complete file has now been read.
+ */
+void parserEOF(char *name, parserContext *pc)
+{
+ previousFile = sipStrdup(name);
+ currentContext = *pc;
+}
+
+
+/*
+ * Append a class definition to a class list if it doesn't already appear.
+ * Append is needed specifically for the list of super-classes because the
+ * order is important to Python.
+ */
+void appendToClassList(classList **clp,classDef *cd)
+{
+ classList *new;
+
+ /* Find the end of the list. */
+
+ while (*clp != NULL)
+ {
+ if ((*clp) -> cd == cd)
+ return;
+
+ clp = &(*clp) -> next;
+ }
+
+ new = sipMalloc(sizeof (classList));
+
+ new -> cd = cd;
+ new -> next = NULL;
+
+ *clp = new;
+}
+
+
+/*
+ * Create a new module for the current specification and make it current.
+ */
+static void newModule(FILE *fp, char *filename)
+{
+ moduleDef *mod;
+
+ parseFile(fp, filename, currentModule, FALSE);
+
+ mod = allocModule();
+ mod->file = filename;
+
+ if (currentModule != NULL)
+ mod->defexception = currentModule->defexception;
+
+ currentModule = mod;
+}
+
+
+/*
+ * Allocate and initialise the memory for a new module.
+ */
+static moduleDef *allocModule()
+{
+ moduleDef *newmod, **tailp;
+
+ newmod = sipMalloc(sizeof (moduleDef));
+
+ newmod->version = -1;
+ newmod->encoding = no_type;
+ newmod->qobjclass = -1;
+ newmod->nrvirthandlers = -1;
+ newmod->next_key = 1;
+
+ /*
+ * The consolidated module support needs these to be in order that they
+ * appeared.
+ */
+ for (tailp = &currentSpec->modules; *tailp != NULL; tailp = &(*tailp)->next)
+ ;
+
+ *tailp = newmod;
+
+ return newmod;
+}
+
+
+/*
+ * Switch to parsing a new file.
+ */
+static void parseFile(FILE *fp, char *name, moduleDef *prevmod, int optional)
+{
+ parserContext pc;
+
+ pc.filename = name;
+ pc.ifdepth = skipStackPtr;
+ pc.prevmod = prevmod;
+
+ if (setInputFile(fp, &pc, optional))
+ currentContext = pc;
+}
+
+
+/*
+ * Find an interface file, or create a new one.
+ */
+ifaceFileDef *findIfaceFile(sipSpec *pt, moduleDef *mod, scopedNameDef *fqname,
+ ifaceFileType iftype, apiVersionRangeDef *api_range, argDef *ad)
+{
+ ifaceFileDef *iff, *first_alt = NULL;
+
+ /* See if the name is already used. */
+
+ for (iff = pt->ifacefiles; iff != NULL; iff = iff->next)
+ {
+ if (compareScopedNames(iff->fqcname, fqname) != 0)
+ continue;
+
+ /*
+ * If they are both versioned then assume the user knows what they are
+ * doing.
+ */
+ if (iff->api_range != NULL && api_range != NULL && iff->module == mod)
+ {
+ /* Remember the first of the alternate APIs. */
+ if ((first_alt = iff->first_alt) == NULL)
+ first_alt = iff;
+
+ break;
+ }
+
+ /*
+ * They must be the same type except that we allow a class if we want
+ * an exception. This is because we allow classes to be used before
+ * they are defined.
+ */
+ if (iff->type != iftype)
+ if (iftype != exception_iface || iff->type != class_iface)
+ yyerror("A class, exception, namespace or mapped type has already been defined with the same name");
+
+ /* Ignore an external class declared in another module. */
+ if (iftype == class_iface && iff->module != mod)
+ {
+ classDef *cd;
+
+ for (cd = pt->classes; cd != NULL; cd = cd->next)
+ if (cd->iff == iff)
+ break;
+
+ if (cd != NULL && iff->module != NULL && isExternal(cd))
+ continue;
+ }
+
+ /*
+ * If this is a mapped type with the same name defined in a different
+ * module, then check that this type isn't the same as any of the
+ * mapped types defined in that module.
+ */
+ if (iftype == mappedtype_iface && iff->module != mod)
+ {
+ mappedTypeDef *mtd;
+
+ /*
+ * This is a bit of a cheat. With consolidated modules it's
+ * possible to have two implementations of a mapped type in
+ * different branches of the module hierarchy. We assume that, if
+ * there really are multiple implementations in the same branch,
+ * then it will be picked up in a non-consolidated build.
+ */
+ if (isConsolidated(pt->module))
+ continue;
+
+ for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next)
+ {
+ if (mtd->iff != iff)
+ continue;
+
+ if (ad->atype != template_type ||
+ mtd->type.atype != template_type ||
+ sameBaseType(ad, &mtd->type))
+ yyerror("Mapped type has already been defined in another module");
+ }
+
+ /*
+ * If we got here then we have a mapped type based on an existing
+ * template, but with unique parameters. We don't want to use
+ * interface files from other modules, so skip this one.
+ */
+
+ continue;
+ }
+
+ /* Ignore a namespace defined in another module. */
+ if (iftype == namespace_iface && iff->module != mod)
+ continue;
+
+ return iff;
+ }
+
+ iff = sipMalloc(sizeof (ifaceFileDef));
+
+ iff->name = cacheName(pt, scopedNameToString(fqname));
+ iff->api_range = api_range;
+
+ if (first_alt != NULL)
+ {
+ iff->first_alt = first_alt;
+ iff->next_alt = first_alt->next_alt;
+
+ first_alt->next_alt = iff;
+ }
+ else
+ {
+ /* This is the first alternate so point to itself. */
+ iff->first_alt = iff;
+ }
+
+ iff->type = iftype;
+ iff->ifacenr = -1;
+ iff->fqcname = fqname;
+ iff->module = NULL;
+ iff->hdrcode = NULL;
+ iff->used = NULL;
+ iff->next = pt->ifacefiles;
+
+ pt->ifacefiles = iff;
+
+ return iff;
+}
+
+
+/*
+ * Find a class definition in a parse tree.
+ */
+static classDef *findClass(sipSpec *pt, ifaceFileType iftype,
+ apiVersionRangeDef *api_range, scopedNameDef *fqname)
+{
+ return findClassWithInterface(pt, findIfaceFile(pt, currentModule, fqname, iftype, api_range, NULL));
+}
+
+
+/*
+ * Find a class definition given an existing interface file.
+ */
+static classDef *findClassWithInterface(sipSpec *pt, ifaceFileDef *iff)
+{
+ classDef *cd;
+
+ for (cd = pt -> classes; cd != NULL; cd = cd -> next)
+ if (cd -> iff == iff)
+ return cd;
+
+ /* Create a new one. */
+ cd = sipMalloc(sizeof (classDef));
+
+ cd->iff = iff;
+ cd->pyname = cacheName(pt, classBaseName(cd));
+ cd->next = pt->classes;
+
+ pt->classes = cd;
+
+ return cd;
+}
+
+
+/*
+ * Add an interface file to an interface file list if it isn't already there.
+ */
+void addToUsedList(ifaceFileList **ifflp, ifaceFileDef *iff)
+{
+ /* Make sure we don't try to add an interface file to its own list. */
+ if (&iff->used != ifflp)
+ {
+ ifaceFileList *iffl;
+
+ while ((iffl = *ifflp) != NULL)
+ {
+ /* Don't bother if it is already there. */
+ if (iffl->iff == iff)
+ return;
+
+ ifflp = &iffl -> next;
+ }
+
+ iffl = sipMalloc(sizeof (ifaceFileList));
+
+ iffl->iff = iff;
+ iffl->next = NULL;
+
+ *ifflp = iffl;
+ }
+}
+
+
+/*
+ * Find an undefined (or create a new) exception definition in a parse tree.
+ */
+static exceptionDef *findException(sipSpec *pt, scopedNameDef *fqname, int new)
+{
+ exceptionDef *xd, **tail;
+ ifaceFileDef *iff;
+ classDef *cd;
+
+ iff = findIfaceFile(pt, currentModule, fqname, exception_iface, NULL, NULL);
+
+ /* See if it is an existing one. */
+ for (xd = pt->exceptions; xd != NULL; xd = xd->next)
+ if (xd->iff == iff)
+ return xd;
+
+ /*
+ * If it is an exception interface file then we have never seen this
+ * name before. We require that exceptions are defined before being
+ * used, but don't make the same requirement of classes (for reasons of
+ * backwards compatibility). Therefore the name must be reinterpreted
+ * as a (as yet undefined) class.
+ */
+ if (new)
+ {
+ if (iff->type == exception_iface)
+ cd = NULL;
+ else
+ yyerror("There is already a class with the same name or the exception has been used before being defined");
+ }
+ else
+ {
+ if (iff->type == exception_iface)
+ iff->type = class_iface;
+
+ cd = findClassWithInterface(pt, iff);
+ }
+
+ /* Create a new one. */
+ xd = sipMalloc(sizeof (exceptionDef));
+
+ xd->exceptionnr = -1;
+ xd->iff = iff;
+ xd->pyname = NULL;
+ xd->cd = cd;
+ xd->bibase = NULL;
+ xd->base = NULL;
+ xd->raisecode = NULL;
+ xd->next = NULL;
+
+ /* Append it to the list. */
+ for (tail = &pt->exceptions; *tail != NULL; tail = &(*tail)->next)
+ ;
+
+ *tail = xd;
+
+ return xd;
+}
+
+
+/*
+ * Find an undefined (or create a new) class definition in a parse tree.
+ */
+static classDef *newClass(sipSpec *pt, ifaceFileType iftype,
+ apiVersionRangeDef *api_range, scopedNameDef *fqname)
+{
+ int flags;
+ classDef *cd, *scope;
+ codeBlock *hdrcode;
+
+ if (sectionFlags & SECT_IS_PRIVATE)
+ yyerror("Classes, structs and namespaces must be in the public or protected sections");
+
+ flags = 0;
+
+ if ((scope = currentScope()) != NULL)
+ {
+ if (sectionFlags & SECT_IS_PROT && !makeProtPublic)
+ {
+ flags = CLASS_IS_PROTECTED;
+
+ if (scope->iff->type == class_iface)
+ setHasShadow(scope);
+ }
+
+ /* Header code from outer scopes is also included. */
+ hdrcode = scope->iff->hdrcode;
+ }
+ else
+ hdrcode = NULL;
+
+ if (pt -> genc)
+ {
+ /* C structs are always global types. */
+ while (fqname -> next != NULL)
+ fqname = fqname -> next;
+
+ scope = NULL;
+ }
+
+ cd = findClass(pt, iftype, api_range, fqname);
+
+ /* Check it hasn't already been defined. */
+ if (iftype != namespace_iface && cd->iff->module != NULL)
+ yyerror("The struct/class has already been defined");
+
+ /* Complete the initialisation. */
+ cd->classflags |= flags;
+ cd->ecd = scope;
+ cd->iff->module = currentModule;
+
+ if (currentIsTemplate)
+ setIsTemplateClass(cd);
+
+ appendCodeBlock(&cd->iff->hdrcode, hdrcode);
+
+ /* See if it is a namespace extender. */
+ if (iftype == namespace_iface)
+ {
+ classDef *ns;
+
+ for (ns = pt->classes; ns != NULL; ns = ns->next)
+ {
+ if (ns == cd)
+ continue;
+
+ if (ns->iff->type != namespace_iface)
+ continue;
+
+ if (compareScopedNames(ns->iff->fqcname, fqname) != 0)
+ continue;
+
+ cd->real = ns;
+ break;
+ }
+ }
+
+ return cd;
+}
+
+
+/*
+ * Tidy up after finishing a class definition.
+ */
+static void finishClass(sipSpec *pt, moduleDef *mod, classDef *cd,
+ optFlags *of)
+{
+ const char *pyname;
+ optFlag *flg;
+
+ /* Get the Python name and see if it is different to the C++ name. */
+ pyname = getPythonName(of, classBaseName(cd));
+
+ cd->pyname = NULL;
+ checkAttributes(pt, mod, cd->ecd, NULL, pyname, FALSE);
+ cd->pyname = cacheName(pt, pyname);
+
+ if ((flg = findOptFlag(of, "Metatype", dotted_name_flag)) != NULL)
+ cd->metatype = cacheName(pt, flg->fvalue.sval);
+
+ if ((flg = findOptFlag(of, "Supertype", dotted_name_flag)) != NULL)
+ cd->supertype = cacheName(pt, flg->fvalue.sval);
+
+ if ((flg = findOptFlag(of, "PyQt4Flags", integer_flag)) != NULL)
+ cd->pyqt4_flags = flg->fvalue.ival;
+
+ if (findOptFlag(of, "PyQt4NoQMetaObject", bool_flag) != NULL)
+ setPyQt4NoQMetaObject(cd);
+
+ if (isOpaque(cd))
+ {
+ if (findOptFlag(of, "External", bool_flag) != NULL)
+ setIsExternal(cd);
+ }
+ else
+ {
+ int seq_might, seq_not;
+ memberDef *md;
+
+ if (findOptFlag(of, "NoDefaultCtors", bool_flag) != NULL)
+ setNoDefaultCtors(cd);
+
+ if (cd -> ctors == NULL)
+ {
+ if (!noDefaultCtors(cd))
+ {
+ /* Provide a default ctor. */
+
+ cd->ctors = sipMalloc(sizeof (ctorDef));
+
+ cd->ctors->ctorflags = SECT_IS_PUBLIC;
+ cd->ctors->pysig.result.atype = void_type;
+ cd->ctors->cppsig = &cd->ctors->pysig;
+
+ cd->defctor = cd->ctors;
+
+ setCanCreate(cd);
+ }
+ }
+ else if (cd -> defctor == NULL)
+ {
+ ctorDef *ct, *last = NULL;
+
+ for (ct = cd -> ctors; ct != NULL; ct = ct -> next)
+ {
+ if (!isPublicCtor(ct))
+ continue;
+
+ if (ct -> pysig.nrArgs == 0 || ct -> pysig.args[0].defval != NULL)
+ {
+ cd -> defctor = ct;
+ break;
+ }
+
+ if (last == NULL)
+ last = ct;
+ }
+
+ /* The last resort is the first public ctor. */
+ if (cd->defctor == NULL)
+ cd->defctor = last;
+ }
+
+ if (getDeprecated(of))
+ setIsDeprecatedClass(cd);
+
+ if (cd->convtocode != NULL && getAllowNone(of))
+ setClassHandlesNone(cd);
+
+ if (findOptFlag(of,"Abstract",bool_flag) != NULL)
+ {
+ setIsAbstractClass(cd);
+ setIsIncomplete(cd);
+ resetCanCreate(cd);
+ }
+
+ /* We assume a public dtor if nothing specific was provided. */
+ if (!isDtor(cd))
+ setIsPublicDtor(cd);
+
+ if (findOptFlag(of, "DelayDtor", bool_flag) != NULL)
+ {
+ setIsDelayedDtor(cd);
+ setHasDelayedDtors(mod);
+ }
+
+ /*
+ * There are subtle differences between the add and concat methods and
+ * the multiply and repeat methods. The number versions can have their
+ * operands swapped and may return NotImplemented. If the user has
+ * used the /Numeric/ annotation or there are other numeric operators
+ * then we use add/multiply. Otherwise, if there are indexing
+ * operators then we use concat/repeat.
+ */
+ seq_might = seq_not = FALSE;
+
+ for (md = cd -> members; md != NULL; md = md -> next)
+ switch (md -> slot)
+ {
+ case getitem_slot:
+ case setitem_slot:
+ case delitem_slot:
+ /* This might be a sequence. */
+ seq_might = TRUE;
+ break;
+
+ case sub_slot:
+ case isub_slot:
+ case div_slot:
+ case idiv_slot:
+ case mod_slot:
+ case imod_slot:
+ case floordiv_slot:
+ case ifloordiv_slot:
+ case truediv_slot:
+ case itruediv_slot:
+ case pos_slot:
+ case neg_slot:
+ /* This is definately not a sequence. */
+ seq_not = TRUE;
+ break;
+ }
+
+ if (!seq_not && seq_might)
+ for (md = cd -> members; md != NULL; md = md -> next)
+ {
+ /* Ignore if the user has been explicit. */
+ if (isNumeric(md))
+ continue;
+
+ switch (md -> slot)
+ {
+ case add_slot:
+ md -> slot = concat_slot;
+ break;
+
+ case iadd_slot:
+ md -> slot = iconcat_slot;
+ break;
+
+ case mul_slot:
+ md -> slot = repeat_slot;
+ break;
+
+ case imul_slot:
+ md -> slot = irepeat_slot;
+ break;
+ }
+ }
+ }
+
+ if (inMainModule())
+ {
+ setIsUsedName(cd->iff->name);
+ setIsUsedName(cd->pyname);
+ }
+}
+
+
+/*
+ * Return the encoded name of a template (ie. including its argument types) as
+ * a scoped name.
+ */
+scopedNameDef *encodedTemplateName(templateDef *td)
+{
+ int a;
+ scopedNameDef *snd;
+
+ snd = copyScopedName(td->fqname);
+
+ for (a = 0; a < td->types.nrArgs; ++a)
+ {
+ char buf[50];
+ int flgs;
+ scopedNameDef *arg_snd;
+ argDef *ad = &td->types.args[a];
+
+ flgs = 0;
+
+ if (isConstArg(ad))
+ flgs += 1;
+
+ if (isReference(ad))
+ flgs += 2;
+
+ /* We use numbers so they don't conflict with names. */
+ sprintf(buf, "%02d%d%d", ad->atype, flgs, ad->nrderefs);
+
+ switch (ad->atype)
+ {
+ case defined_type:
+ arg_snd = copyScopedName(ad->u.snd);
+ break;
+
+ case template_type:
+ arg_snd = encodedTemplateName(ad->u.td);
+ break;
+
+ case struct_type:
+ arg_snd = copyScopedName(ad->u.sname);
+ break;
+
+ default:
+ arg_snd = NULL;
+ }
+
+ /*
+ * Replace the first element of the argument name with a copy with the
+ * encoding prepended.
+ */
+ if (arg_snd != NULL)
+ arg_snd->name = concat(buf, arg_snd->name, NULL);
+ else
+ arg_snd = text2scopePart(sipStrdup(buf));
+
+ appendScopedName(&snd, arg_snd);
+ }
+
+ return snd;
+}
+
+
+/*
+ * Create a new mapped type.
+ */
+static mappedTypeDef *newMappedType(sipSpec *pt, argDef *ad, optFlags *of)
+{
+ mappedTypeDef *mtd;
+ scopedNameDef *snd;
+ ifaceFileDef *iff;
+ const char *cname;
+
+ /* Check that the type is one we want to map. */
+ switch (ad->atype)
+ {
+ case defined_type:
+ snd = ad->u.snd;
+ cname = scopedNameTail(snd);
+ break;
+
+ case template_type:
+ snd = encodedTemplateName(ad->u.td);
+ cname = NULL;
+ break;
+
+ case struct_type:
+ snd = ad->u.sname;
+ cname = scopedNameTail(snd);
+ break;
+
+ default:
+ yyerror("Invalid type for %MappedType");
+ }
+
+ iff = findIfaceFile(pt, currentModule, snd, mappedtype_iface,
+ getAPIRange(of), ad);
+
+ /* Check it hasn't already been defined. */
+ for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next)
+ if (mtd->iff == iff)
+ {
+ /*
+ * We allow types based on the same template but with different
+ * arguments.
+ */
+ if (ad->atype != template_type || sameBaseType(ad, &mtd->type))
+ yyerror("Mapped type has already been defined in this module");
+ }
+
+ /* The module may not have been set yet. */
+ iff->module = currentModule;
+
+ /* Create a new mapped type. */
+ mtd = allocMappedType(pt, ad);
+
+ if (cname != NULL)
+ mtd->pyname = cacheName(pt, getPythonName(of, cname));
+
+ if (findOptFlag(of, "NoRelease", bool_flag) != NULL)
+ setNoRelease(mtd);
+
+ if (getAllowNone(of))
+ setHandlesNone(mtd);
+
+ mtd->doctype = getDocType(of);
+
+ mtd->iff = iff;
+ mtd->next = pt->mappedtypes;
+
+ pt->mappedtypes = mtd;
+
+ if (inMainModule())
+ {
+ setIsUsedName(mtd->cname);
+
+ if (mtd->pyname)
+ setIsUsedName(mtd->pyname);
+ }
+
+ return mtd;
+}
+
+
+/*
+ * Allocate, intialise and return a mapped type structure.
+ */
+mappedTypeDef *allocMappedType(sipSpec *pt, argDef *type)
+{
+ mappedTypeDef *mtd;
+
+ mtd = sipMalloc(sizeof (mappedTypeDef));
+
+ mtd->type = *type;
+ mtd->type.argflags = 0;
+ mtd->type.nrderefs = 0;
+
+ mtd->cname = cacheName(pt, type2string(&mtd->type));
+
+ return mtd;
+}
+
+
+/*
+ * Create a new enum.
+ */
+static enumDef *newEnum(sipSpec *pt, moduleDef *mod, mappedTypeDef *mt_scope,
+ char *name, optFlags *of, int flags)
+{
+ enumDef *ed, *first_alt, *next_alt;
+ classDef *c_scope;
+ ifaceFileDef *scope;
+
+ if (mt_scope != NULL)
+ {
+ scope = mt_scope->iff;
+ c_scope = NULL;
+ }
+ else
+ {
+ if ((c_scope = currentScope()) != NULL)
+ scope = c_scope->iff;
+ else
+ scope = NULL;
+ }
+
+ ed = sipMalloc(sizeof (enumDef));
+
+ /* Assume the enum isn't versioned. */
+ first_alt = ed;
+ next_alt = NULL;
+
+ if (name != NULL)
+ {
+ ed->pyname = cacheName(pt, getPythonName(of, name));
+ checkAttributes(pt, mod, c_scope, mt_scope, ed->pyname->text, FALSE);
+
+ ed->fqcname = text2scopedName(scope, name);
+ ed->cname = cacheName(pt, scopedNameToString(ed->fqcname));
+
+ if (inMainModule())
+ {
+ setIsUsedName(ed->pyname);
+ setIsUsedName(ed->cname);
+ }
+
+ /* If the scope is versioned then look for any alternate. */
+ if (scope != NULL && scope->api_range != NULL)
+ {
+ enumDef *alt;
+
+ for (alt = pt->enums; alt != NULL; alt = alt->next)
+ {
+ if (alt->module != mod || alt->fqcname == NULL)
+ continue;
+
+ if (compareScopedNames(alt->fqcname, ed->fqcname) == 0)
+ {
+ first_alt = alt->first_alt;
+ next_alt = first_alt->next_alt;
+ first_alt->next_alt = ed;
+
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ ed->pyname = NULL;
+ ed->fqcname = NULL;
+ ed->cname = NULL;
+ }
+
+ if (flags & SECT_IS_PROT && makeProtPublic)
+ {
+ flags &= ~SECT_IS_PROT;
+ flags |= SECT_IS_PUBLIC;
+ }
+
+ ed->enumflags = flags;
+ ed->enumnr = -1;
+ ed->ecd = c_scope;
+ ed->emtd = mt_scope;
+ ed->first_alt = first_alt;
+ ed->next_alt = next_alt;
+ ed->module = mod;
+ ed->members = NULL;
+ ed->slots = NULL;
+ ed->overs = NULL;
+ ed->next = pt -> enums;
+
+ pt->enums = ed;
+
+ return ed;
+}
+
+
+/*
+ * Get the type values and (optionally) the type names for substitution in
+ * handwritten code.
+ */
+void appendTypeStrings(scopedNameDef *ename, signatureDef *patt, signatureDef *src, signatureDef *known, scopedNameDef **names, scopedNameDef **values)
+{
+ int a;
+
+ for (a = 0; a < patt->nrArgs; ++a)
+ {
+ argDef *pad = &patt->args[a];
+
+ if (pad->atype == defined_type)
+ {
+ char *nam = NULL, *val;
+ argDef *sad;
+
+ /*
+ * If the type names are already known then check that this is one
+ * of them.
+ */
+ if (known == NULL)
+ nam = scopedNameTail(pad->u.snd);
+ else if (pad->u.snd->next == NULL)
+ {
+ int k;
+
+ for (k = 0; k < known->nrArgs; ++k)
+ {
+ /* Skip base types. */
+ if (known->args[k].atype != defined_type)
+ continue;
+
+ if (strcmp(pad->u.snd->name, known->args[k].u.snd->name) == 0)
+ {
+ nam = pad->u.snd->name;
+ break;
+ }
+ }
+ }
+
+ if (nam == NULL)
+ continue;
+
+ /* Add the name. */
+ appendScopedName(names, text2scopePart(nam));
+
+ /*
+ * Add the corresponding value. For defined types we don't want
+ * any indirection or references.
+ */
+ sad = &src->args[a];
+
+ if (sad->atype == defined_type)
+ val = scopedNameToString(sad->u.snd);
+ else
+ val = type2string(sad);
+
+ appendScopedName(values, text2scopePart(val));
+ }
+ else if (pad->atype == template_type)
+ {
+ argDef *sad = &src->args[a];
+
+ /* These checks shouldn't be necessary, but... */
+ if (sad->atype == template_type && pad->u.td->types.nrArgs == sad->u.td->types.nrArgs)
+ appendTypeStrings(ename, &pad->u.td->types, &sad->u.td->types, known, names, values);
+ }
+ }
+}
+
+
+/*
+ * Convert a type to a string on the heap. The string will use the minimum
+ * whitespace while still remaining valid C++.
+ */
+static char *type2string(argDef *ad)
+{
+ int i, on_heap = FALSE;
+ int nr_derefs = ad->nrderefs;
+ int is_reference = isReference(ad);
+ char *s;
+
+ /* Use the original type if possible. */
+ if (ad->original_type != NULL && !noTypeName(ad->original_type))
+ {
+ s = scopedNameToString(ad->original_type->fqname);
+ on_heap = TRUE;
+
+ nr_derefs -= ad->original_type->type.nrderefs;
+
+ if (isReference(&ad->original_type->type))
+ is_reference = FALSE;
+ }
+ else
+ switch (ad->atype)
+ {
+ case template_type:
+ {
+ templateDef *td = ad->u.td;
+
+ s = scopedNameToString(td->fqname);
+ append(&s, "<");
+
+ for (i = 0; i < td->types.nrArgs; ++i)
+ {
+ char *sub_type = type2string(&td->types.args[i]);
+
+ if (i > 0)
+ append(&s, ",");
+
+ append(&s, sub_type);
+ free(sub_type);
+ }
+
+ if (s[strlen(s) - 1] == '>')
+ append(&s, " >");
+ else
+ append(&s, ">");
+
+ on_heap = TRUE;
+ break;
+ }
+
+ case struct_type:
+ s = scopedNameToString(ad->u.sname);
+ on_heap = TRUE;
+ break;
+
+ case defined_type:
+ s = scopedNameToString(ad->u.snd);
+ on_heap = TRUE;
+ break;
+
+ case ustring_type:
+ s = "unsigned char";
+ break;
+
+ case ascii_string_type:
+ case latin1_string_type:
+ case utf8_string_type:
+ case string_type:
+ s = "char";
+ break;
+
+ case sstring_type:
+ s = "signed char";
+ break;
+
+ case wstring_type:
+ s = "wchar_t";
+ break;
+
+ case ushort_type:
+ s = "unsigned short";
+ break;
+
+ case short_type:
+ s = "short";
+ break;
+
+ case uint_type:
+ s = "unsigned int";
+ break;
+
+ case int_type:
+ case cint_type:
+ s = "int";
+ break;
+
+ case ulong_type:
+ s = "unsigned long";
+ break;
+
+ case long_type:
+ s = "long";
+ break;
+
+ case ulonglong_type:
+ s = "unsigned long long";
+ break;
+
+ case longlong_type:
+ s = "long long";
+ break;
+
+ case float_type:
+ case cfloat_type:
+ s = "float";
+ break;
+
+ case double_type:
+ case cdouble_type:
+ s = "double";
+ break;
+
+ case bool_type:
+ case cbool_type:
+ s = "bool";
+ break;
+
+ default:
+ fatal("Unsupported type argument to type2string(): %d\n", ad->atype);
+ }
+
+ /* Make sure the string is on the heap. */
+ if (!on_heap)
+ s = sipStrdup(s);
+
+ while (nr_derefs-- > 0)
+ append(&s, "*");
+
+ if (is_reference)
+ append(&s, "&");
+
+ return s;
+}
+
+
+/*
+ * Convert a scoped name to a string on the heap.
+ */
+static char *scopedNameToString(scopedNameDef *name)
+{
+ static const char scope_string[] = "::";
+ size_t len;
+ scopedNameDef *snd;
+ char *s, *dp;
+
+ /* Work out the length of buffer needed. */
+ len = 0;
+
+ for (snd = name; snd != NULL; snd = snd->next)
+ {
+ len += strlen(snd->name);
+
+ if (snd->next != NULL)
+ {
+ /* Ignore the encoded part of template names. */
+ if (isdigit(snd->next->name[0]))
+ break;
+
+ len += strlen(scope_string);
+ }
+ }
+
+ /* Allocate and populate the buffer. */
+ dp = s = sipMalloc(len + 1);
+
+ for (snd = name; snd != NULL; snd = snd->next)
+ {
+ strcpy(dp, snd->name);
+ dp += strlen(snd->name);
+
+ if (snd->next != NULL)
+ {
+ /* Ignore the encoded part of template names. */
+ if (isdigit(snd->next->name[0]))
+ break;
+
+ strcpy(dp, scope_string);
+ dp += strlen(scope_string);
+ }
+ }
+
+ return s;
+}
+
+
+/*
+ * Instantiate a class template.
+ */
+static void instantiateClassTemplate(sipSpec *pt, moduleDef *mod,
+ classDef *scope, scopedNameDef *fqname, classTmplDef *tcd,
+ templateDef *td)
+{
+ scopedNameDef *type_names, *type_values;
+ classDef *cd;
+ ctorDef *oct, **cttail;
+ argDef *ad;
+ ifaceFileList *iffl, **used;
+
+ type_names = type_values = NULL;
+ appendTypeStrings(classFQCName(tcd->cd), &tcd->sig, &td->types, NULL, &type_names, &type_values);
+
+ /*
+ * Add a mapping from the template name to the instantiated name. If we
+ * have got this far we know there is room for it.
+ */
+ ad = &tcd->sig.args[tcd->sig.nrArgs++];
+ memset(ad, 0, sizeof (argDef));
+ ad->atype = defined_type;
+ ad->u.snd = classFQCName(tcd->cd);
+
+ appendScopedName(&type_names, text2scopePart(scopedNameTail(classFQCName(tcd->cd))));
+ appendScopedName(&type_values, text2scopePart(scopedNameToString(fqname)));
+
+ /* Create the new class. */
+ cd = sipMalloc(sizeof (classDef));
+
+ /* Start with a shallow copy. */
+ *cd = *tcd->cd;
+
+ resetIsTemplateClass(cd);
+ cd->pyname = cacheName(pt, scopedNameTail(fqname));
+ cd->td = td;
+
+ /* Handle the interface file. */
+ cd->iff = findIfaceFile(pt, mod, fqname, class_iface,
+ (scope != NULL ? scope->iff->api_range : NULL), NULL);
+ cd->iff->module = mod;
+
+ /* Make a copy of the used list and add the enclosing scope. */
+ used = &cd->iff->used;
+
+ for (iffl = tcd->cd->iff->used; iffl != NULL; iffl = iffl->next)
+ addToUsedList(used, iffl->iff);
+
+ /* Include any scope header code. */
+ if (scope != NULL)
+ appendCodeBlock(&cd->iff->hdrcode, scope->iff->hdrcode);
+
+ if (inMainModule())
+ {
+ setIsUsedName(cd->iff->name);
+ setIsUsedName(cd->pyname);
+ }
+
+ cd->ecd = currentScope();
+
+ /* Handle the enums. */
+ instantiateTemplateEnums(pt, tcd, td, cd, used, type_names, type_values);
+
+ /* Handle the variables. */
+ instantiateTemplateVars(pt, tcd, td, cd, used, type_names, type_values);
+
+ /* Handle the ctors. */
+ cd->ctors = NULL;
+ cttail = &cd->ctors;
+
+ for (oct = tcd->cd->ctors; oct != NULL; oct = oct->next)
+ {
+ ctorDef *nct = sipMalloc(sizeof (ctorDef));
+
+ /* Start with a shallow copy. */
+ *nct = *oct;
+
+ templateSignature(&nct->pysig, FALSE, tcd, td, cd);
+
+ if (oct->cppsig == NULL)
+ nct->cppsig = NULL;
+ else if (oct->cppsig == &oct->pysig)
+ nct->cppsig = &nct->pysig;
+ else
+ {
+ nct->cppsig = sipMalloc(sizeof (signatureDef));
+
+ *nct->cppsig = *oct->cppsig;
+
+ templateSignature(nct->cppsig, FALSE, tcd, td, cd);
+ }
+
+ nct->methodcode = templateCode(pt, used, nct->methodcode, type_names, type_values);
+
+ nct->next = NULL;
+ *cttail = nct;
+ cttail = &nct->next;
+
+ /* Handle the default ctor. */
+ if (tcd->cd->defctor == oct)
+ cd->defctor = nct;
+ }
+
+ cd->dealloccode = templateCode(pt, used, cd->dealloccode, type_names, type_values);
+ cd->dtorcode = templateCode(pt, used, cd->dtorcode, type_names, type_values);
+
+ /* Handle the methods. */
+ cd->members = instantiateTemplateMethods(tcd->cd->members, mod);
+ cd->overs = instantiateTemplateOverloads(pt, tcd->cd->overs,
+ tcd->cd->members, cd->members, tcd, td, cd, used, type_names,
+ type_values);
+
+ cd->cppcode = templateCode(pt, used, cd->cppcode, type_names, type_values);
+ cd->iff->hdrcode = templateCode(pt, used, cd->iff->hdrcode, type_names, type_values);
+ cd->convtosubcode = templateCode(pt, used, cd->convtosubcode, type_names, type_values);
+ cd->convtocode = templateCode(pt, used, cd->convtocode, type_names, type_values);
+ cd->travcode = templateCode(pt, used, cd->travcode, type_names, type_values);
+ cd->clearcode = templateCode(pt, used, cd->clearcode, type_names, type_values);
+ cd->getbufcode = templateCode(pt, used, cd->getbufcode, type_names, type_values);
+ cd->releasebufcode = templateCode(pt, used, cd->releasebufcode, type_names, type_values);
+ cd->readbufcode = templateCode(pt, used, cd->readbufcode, type_names, type_values);
+ cd->writebufcode = templateCode(pt, used, cd->writebufcode, type_names, type_values);
+ cd->segcountcode = templateCode(pt, used, cd->segcountcode, type_names, type_values);
+ cd->charbufcode = templateCode(pt, used, cd->charbufcode, type_names, type_values);
+ cd->picklecode = templateCode(pt, used, cd->picklecode, type_names, type_values);
+ cd->next = pt->classes;
+
+ pt->classes = cd;
+
+ tcd->sig.nrArgs--;
+
+ freeScopedName(type_names);
+ freeScopedName(type_values);
+}
+
+
+/*
+ * Instantiate the methods of a template class.
+ */
+static memberDef *instantiateTemplateMethods(memberDef *tmd, moduleDef *mod)
+{
+ memberDef *md, *methods, **mdtail;
+
+ methods = NULL;
+ mdtail = &methods;
+
+ for (md = tmd; md != NULL; md = md->next)
+ {
+ memberDef *nmd = sipMalloc(sizeof (memberDef));
+
+ /* Start with a shallow copy. */
+ *nmd = *md;
+
+ nmd->module = mod;
+
+ if (inMainModule())
+ setIsUsedName(nmd->pyname);
+
+ nmd->next = NULL;
+ *mdtail = nmd;
+ mdtail = &nmd->next;
+ }
+
+ return methods;
+}
+
+
+/*
+ * Instantiate the overloads of a template class.
+ */
+static overDef *instantiateTemplateOverloads(sipSpec *pt, overDef *tod,
+ memberDef *tmethods, memberDef *methods, classTmplDef *tcd,
+ templateDef *td, classDef *cd, ifaceFileList **used,
+ scopedNameDef *type_names, scopedNameDef *type_values)
+{
+ overDef *od, *overloads, **odtail;
+
+ overloads = NULL;
+ odtail = &overloads;
+
+ for (od = tod; od != NULL; od = od->next)
+ {
+ overDef *nod = sipMalloc(sizeof (overDef));
+ memberDef *nmd, *omd;
+
+ /* Start with a shallow copy. */
+ *nod = *od;
+
+ for (nmd = methods, omd = tmethods; omd != NULL; omd = omd->next, nmd = nmd->next)
+ if (omd == od->common)
+ {
+ nod->common = nmd;
+ break;
+ }
+
+ templateSignature(&nod->pysig, TRUE, tcd, td, cd);
+
+ if (od->cppsig == &od->pysig)
+ nod->cppsig = &nod->pysig;
+ else
+ {
+ nod->cppsig = sipMalloc(sizeof (signatureDef));
+
+ *nod->cppsig = *od->cppsig;
+
+ templateSignature(nod->cppsig, TRUE, tcd, td, cd);
+ }
+
+ nod->methodcode = templateCode(pt, used, nod->methodcode, type_names, type_values);
+
+ /* Handle any virtual handler. */
+ if (od->virthandler != NULL)
+ {
+ moduleDef *mod = cd->iff->module;
+
+ nod->virthandler = sipMalloc(sizeof (virtHandlerDef));
+
+ /* Start with a shallow copy. */
+ *nod->virthandler = *od->virthandler;
+
+ if (od->virthandler->cppsig == &od->pysig)
+ nod->virthandler->cppsig = &nod->pysig;
+ else
+ {
+ nod->virthandler->cppsig = sipMalloc(sizeof (signatureDef));
+
+ *nod->virthandler->cppsig = *od->virthandler->cppsig;
+
+ templateSignature(nod->virthandler->cppsig, TRUE, tcd, td, cd);
+ }
+
+ nod->virthandler->module = mod;
+ nod->virthandler->virtcode = templateCode(pt, used, nod->virthandler->virtcode, type_names, type_values);
+ nod->virthandler->next = mod->virthandlers;
+
+ mod->virthandlers = nod->virthandler;
+ }
+
+ nod->next = NULL;
+ *odtail = nod;
+ odtail = &nod->next;
+ }
+
+ return overloads;
+}
+
+
+/*
+ * Instantiate the enums of a template class.
+ */
+static void instantiateTemplateEnums(sipSpec *pt, classTmplDef *tcd,
+ templateDef *td, classDef *cd, ifaceFileList **used,
+ scopedNameDef *type_names, scopedNameDef *type_values)
+{
+ enumDef *ted;
+ moduleDef *mod = cd->iff->module;
+
+ for (ted = pt->enums; ted != NULL; ted = ted->next)
+ if (ted->ecd == tcd->cd)
+ {
+ enumDef *ed;
+ enumMemberDef *temd;
+
+ ed = sipMalloc(sizeof (enumDef));
+
+ /* Start with a shallow copy. */
+ *ed = *ted;
+
+ if (ed->fqcname != NULL)
+ {
+ ed->fqcname = text2scopedName(cd->iff,
+ scopedNameTail(ed->fqcname));
+ ed->cname = cacheName(pt, scopedNameToString(ed->fqcname));
+ }
+
+ if (inMainModule())
+ {
+ if (ed->pyname != NULL)
+ setIsUsedName(ed->pyname);
+
+ if (ed->cname != NULL)
+ setIsUsedName(ed->cname);
+ }
+
+ ed->ecd = cd;
+ ed->first_alt = ed;
+ ed->module = mod;
+ ed->members = NULL;
+
+ for (temd = ted->members; temd != NULL; temd = temd->next)
+ {
+ enumMemberDef *emd;
+
+ emd = sipMalloc(sizeof (enumMemberDef));
+
+ /* Start with a shallow copy. */
+ *emd = *temd;
+ emd->ed = ed;
+
+ emd->next = ed->members;
+ ed->members = emd;
+ }
+
+ ed->slots = instantiateTemplateMethods(ted->slots, mod);
+ ed->overs = instantiateTemplateOverloads(pt, ted->overs,
+ ted->slots, ed->slots, tcd, td, cd, used, type_names,
+ type_values);
+
+ ed->next = pt->enums;
+ pt->enums = ed;
+ }
+}
+
+
+/*
+ * Instantiate the variables of a template class.
+ */
+static void instantiateTemplateVars(sipSpec *pt, classTmplDef *tcd,
+ templateDef *td, classDef *cd, ifaceFileList **used,
+ scopedNameDef *type_names, scopedNameDef *type_values)
+{
+ varDef *tvd;
+
+ for (tvd = pt->vars; tvd != NULL; tvd = tvd->next)
+ if (tvd->ecd == tcd->cd)
+ {
+ varDef *vd;
+
+ vd = sipMalloc(sizeof (varDef));
+
+ /* Start with a shallow copy. */
+ *vd = *tvd;
+
+ if (inMainModule())
+ setIsUsedName(vd->pyname);
+
+ vd->fqcname = text2scopedName(cd->iff,
+ scopedNameTail(vd->fqcname));
+ vd->ecd = cd;
+ vd->module = cd->iff->module;
+
+ templateType(&vd->type, tcd, td, cd);
+
+ vd->accessfunc = templateCode(pt, used, vd->accessfunc, type_names, type_values);
+ vd->getcode = templateCode(pt, used, vd->getcode, type_names, type_values);
+ vd->setcode = templateCode(pt, used, vd->setcode, type_names, type_values);
+
+ addVariable(pt, vd);
+ }
+}
+
+
+/*
+ * Replace any template arguments in a signature.
+ */
+static void templateSignature(signatureDef *sd, int result, classTmplDef *tcd, templateDef *td, classDef *ncd)
+{
+ int a;
+
+ if (result)
+ templateType(&sd->result, tcd, td, ncd);
+
+ for (a = 0; a < sd->nrArgs; ++a)
+ templateType(&sd->args[a], tcd, td, ncd);
+}
+
+
+/*
+ * Replace any template arguments in a type.
+ */
+static void templateType(argDef *ad, classTmplDef *tcd, templateDef *td, classDef *ncd)
+{
+ int a;
+ char *name;
+
+ /* Descend into any sub-templates. */
+ if (ad->atype == template_type)
+ {
+ templateDef *new_td = sipMalloc(sizeof (templateDef));
+
+ /* Make a deep copy of the template definition. */
+ *new_td = *ad->u.td;
+ ad->u.td = new_td;
+
+ templateSignature(&ad->u.td->types, FALSE, tcd, td, ncd);
+
+ return;
+ }
+
+ /* Ignore if it isn't an unscoped name. */
+ if (ad->atype != defined_type || ad->u.snd->next != NULL)
+ return;
+
+ name = ad->u.snd->name;
+
+ for (a = 0; a < tcd->sig.nrArgs - 1; ++a)
+ if (strcmp(name, scopedNameTail(tcd->sig.args[a].u.snd)) == 0)
+ {
+ argDef *tad = &td->types.args[a];
+
+ ad->atype = tad->atype;
+
+ /* We take the constrained flag from the real type. */
+ resetIsConstrained(ad);
+
+ if (isConstrained(tad))
+ setIsConstrained(ad);
+
+ ad->u = tad->u;
+
+ return;
+ }
+
+ /* Handle the class name itself. */
+ if (strcmp(name, scopedNameTail(classFQCName(tcd->cd))) == 0)
+ {
+ ad->atype = class_type;
+ ad->u.cd = ncd;
+ ad->original_type = NULL;
+ }
+}
+
+
+/*
+ * Replace any template arguments in a literal code block.
+ */
+codeBlock *templateCode(sipSpec *pt, ifaceFileList **used, codeBlock *ocb,
+ scopedNameDef *names, scopedNameDef *values)
+{
+ codeBlock *ncb = NULL, **tail = &ncb;
+
+ while (ocb != NULL)
+ {
+ char *at = ocb->frag;
+
+ do
+ {
+ char *first = NULL;
+ codeBlock *cb;
+ scopedNameDef *nam, *val, *nam_first, *val_first;
+
+ /*
+ * Go through the rest of this fragment looking for each of the
+ * types and the name of the class itself.
+ */
+ nam = names;
+ val = values;
+
+ while (nam != NULL && val != NULL)
+ {
+ char *cp;
+
+ if ((cp = strstr(at, nam->name)) != NULL)
+ if (first == NULL || first > cp)
+ {
+ nam_first = nam;
+ val_first = val;
+ first = cp;
+ }
+
+ nam = nam->next;
+ val = val->next;
+ }
+
+ /* Create the new fragment. */
+ cb = sipMalloc(sizeof (codeBlock));
+
+ if (at == ocb->frag)
+ {
+ cb->filename = ocb->filename;
+ cb->linenr = ocb->linenr;
+ }
+ else
+ cb->filename = NULL;
+
+ cb->next = NULL;
+ *tail = cb;
+ tail = &cb->next;
+
+ /* See if anything was found. */
+ if (first == NULL)
+ {
+ /* We can just point to this. */
+ cb->frag = at;
+
+ /* All done with this one. */
+ at = NULL;
+ }
+ else
+ {
+ static char *gen_names[] = {
+ "sipType_",
+ "sipClass_",
+ "sipEnum_",
+ "sipException_",
+ NULL
+ };
+
+ char *dp, *sp, **gn;
+ int genname = FALSE;
+
+ /*
+ * If the context in which the text is used is in the name of a
+ * SIP generated object then translate any "::" scoping to "_".
+ */
+ for (gn = gen_names; *gn != NULL; ++gn)
+ if (search_back(first, at, *gn))
+ {
+ addUsedFromCode(pt, used, val_first->name);
+ genname = TRUE;
+ break;
+ }
+
+ /* Fragment the fragment. */
+ cb->frag = sipMalloc(first - at + strlen(val_first->name) + 1);
+
+ strncpy(cb->frag, at, first - at);
+
+ dp = &cb->frag[first - at];
+ sp = val_first->name;
+
+ if (genname)
+ {
+ char gch;
+
+ while ((gch = *sp++) != '\0')
+ if (gch == ':' && *sp == ':')
+ {
+ *dp++ = '_';
+ ++sp;
+ }
+ else
+ *dp++ = gch;
+
+ *dp = '\0';
+ }
+ else
+ strcpy(dp, sp);
+
+ /* Move past the replaced text. */
+ at = first + strlen(nam_first->name);
+ }
+ }
+ while (at != NULL && *at != '\0');
+
+ ocb = ocb->next;
+ }
+
+ return ncb;
+}
+
+
+/*
+ * Return TRUE if the text at the end of a string matches the target string.
+ */
+static int search_back(const char *end, const char *start, const char *target)
+{
+ size_t tlen = strlen(target);
+
+ if (start + tlen >= end)
+ return FALSE;
+
+ return (strncmp(end - tlen, target, tlen) == 0);
+}
+
+
+/*
+ * Add any needed interface files based on handwritten code.
+ */
+static void addUsedFromCode(sipSpec *pt, ifaceFileList **used, const char *sname)
+{
+ ifaceFileDef *iff;
+ enumDef *ed;
+
+ for (iff = pt->ifacefiles; iff != NULL; iff = iff->next)
+ {
+ if (iff->type != class_iface && iff->type != exception_iface)
+ continue;
+
+ if (sameName(iff->fqcname, sname))
+ {
+ addToUsedList(used, iff);
+ return;
+ }
+ }
+
+ for (ed = pt->enums; ed != NULL; ed = ed->next)
+ {
+ if (ed->ecd == NULL)
+ continue;
+
+ if (sameName(ed->fqcname, sname))
+ {
+ addToUsedList(used, ed->ecd->iff);
+ return;
+ }
+ }
+}
+
+
+/*
+ * Compare a scoped name with its string equivalent.
+ */
+static int sameName(scopedNameDef *snd, const char *sname)
+{
+ while (snd != NULL && *sname != '\0')
+ {
+ const char *sp = snd->name;
+
+ while (*sp != '\0' && *sname != ':' && *sname != '\0')
+ if (*sp++ != *sname++)
+ return FALSE;
+
+ if (*sp != '\0' || (*sname != ':' && *sname != '\0'))
+ return FALSE;
+
+ snd = snd->next;
+
+ if (*sname == ':')
+ sname += 2;
+ }
+
+ return (snd == NULL && *sname == '\0');
+}
+
+
+/*
+ * Compare a (possibly) relative scoped name with a fully qualified scoped name
+ * while taking the current scope into account.
+ */
+static int foundInScope(scopedNameDef *fq_name, scopedNameDef *rel_name)
+{
+ classDef *scope;
+
+ for (scope = currentScope(); scope != NULL; scope = scope->ecd)
+ {
+ scopedNameDef *snd;
+ int found;
+
+ snd = copyScopedName(classFQCName(scope));
+ appendScopedName(&snd, copyScopedName(rel_name));
+
+ found = (compareScopedNames(fq_name, snd) == 0);
+
+ freeScopedName(snd);
+
+ if (found)
+ return TRUE;
+ }
+
+ return compareScopedNames(fq_name, rel_name) == 0;
+}
+
+
+/*
+ * Create a new typedef.
+ */
+static void newTypedef(sipSpec *pt, moduleDef *mod, char *name, argDef *type,
+ optFlags *optflgs)
+{
+ typedefDef *td, **tdp;
+ scopedNameDef *fqname;
+ classDef *scope;
+
+ scope = currentScope();
+ fqname = text2scopedName((scope != NULL ? scope->iff : NULL), name);
+
+ /* See if we are instantiating a template class. */
+ if (type->atype == template_type)
+ {
+ classTmplDef *tcd;
+ templateDef *td = type->u.td;
+
+ for (tcd = pt->classtemplates; tcd != NULL; tcd = tcd->next)
+ if (foundInScope(tcd->cd->iff->fqcname, td->fqname) &&
+ sameTemplateSignature(&tcd->sig, &td->types, FALSE))
+ {
+ instantiateClassTemplate(pt, mod, scope, fqname, tcd, td);
+
+ /* All done. */
+ return;
+ }
+ }
+
+ /*
+ * Check it doesn't already exist and find the position in the sorted list
+ * where it should be put.
+ */
+ for (tdp = &pt->typedefs; *tdp != NULL; tdp = &(*tdp)->next)
+ {
+ int res = compareScopedNames((*tdp)->fqname, fqname);
+
+ if (res == 0)
+ {
+ fatalScopedName(fqname);
+ fatal(" already defined\n");
+ }
+
+ if (res > 0)
+ break;
+ }
+
+ td = sipMalloc(sizeof (typedefDef));
+
+ td->tdflags = 0;
+ td->fqname = fqname;
+ td->ecd = scope;
+ td->module = mod;
+ td->type = *type;
+
+ td->next = *tdp;
+ *tdp = td;
+
+ if (findOptFlag(optflgs, "NoTypeName", bool_flag) != NULL)
+ setNoTypeName(td);
+
+ mod->nrtypedefs++;
+}
+
+
+/*
+ * Speculatively try and resolve any typedefs. In some cases (eg. when
+ * comparing template signatures) it helps to use the real type if it is known.
+ * Note that this wouldn't be necessary if we required that all types be known
+ * before they are used.
+ */
+static void resolveAnyTypedef(sipSpec *pt, argDef *ad)
+{
+ argDef orig = *ad;
+
+ while (ad->atype == defined_type)
+ {
+ ad->atype = no_type;
+ searchTypedefs(pt, ad->u.snd, ad);
+
+ /*
+ * Don't resolve to a template type as it may be superceded later on
+ * by a more specific mapped type.
+ */
+ if (ad->atype == no_type || ad->atype == template_type)
+ {
+ *ad = orig;
+ break;
+ }
+ }
+}
+
+
+/*
+ * Return TRUE if the template signatures are the same. A deep comparison is
+ * used for mapped type templates where we want to recurse into any nested
+ * templates.
+ */
+int sameTemplateSignature(signatureDef *tmpl_sd, signatureDef *args_sd,
+ int deep)
+{
+ int a;
+
+ if (tmpl_sd->nrArgs != args_sd->nrArgs)
+ return FALSE;
+
+ for (a = 0; a < tmpl_sd->nrArgs; ++a)
+ {
+ argDef *tmpl_ad = &tmpl_sd->args[a];
+ argDef *args_ad = &args_sd->args[a];
+
+ /*
+ * If we are doing a shallow comparision (ie. for class templates) then
+ * a type name in the template signature matches anything in the
+ * argument signature.
+ */
+ if (tmpl_ad->atype == defined_type && !deep)
+ continue;
+
+ /*
+ * For type names only compare the references and pointers, and do the
+ * same for any nested templates.
+ */
+ if (tmpl_ad->atype == defined_type && args_ad->atype == defined_type)
+ {
+ if (isReference(tmpl_ad) != isReference(args_ad) || tmpl_ad->nrderefs != args_ad->nrderefs)
+ return FALSE;
+ }
+ else if (tmpl_ad->atype == template_type && args_ad->atype == template_type)
+ {
+ if (!sameTemplateSignature(&tmpl_ad->u.td->types, &args_ad->u.td->types, deep))
+ return FALSE;
+ }
+ else if (!sameBaseType(tmpl_ad, args_ad))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Create a new variable.
+ */
+static void newVar(sipSpec *pt,moduleDef *mod,char *name,int isstatic,
+ argDef *type,optFlags *of,codeBlock *acode,codeBlock *gcode,
+ codeBlock *scode)
+{
+ varDef *var;
+ classDef *escope = currentScope();
+ nameDef *nd = cacheName(pt,getPythonName(of,name));
+
+ if (inMainModule())
+ setIsUsedName(nd);
+
+ checkAttributes(pt, mod, escope, NULL, nd->text, FALSE);
+
+ var = sipMalloc(sizeof (varDef));
+
+ var->pyname = nd;
+ var->fqcname = text2scopedName((escope != NULL ? escope->iff : NULL),
+ name);
+ var->ecd = escope;
+ var->module = mod;
+ var->varflags = 0;
+ var->type = *type;
+ var->accessfunc = acode;
+ var->getcode = gcode;
+ var->setcode = scode;
+
+ if (isstatic || (escope != NULL && escope->iff->type == namespace_iface))
+ setIsStaticVar(var);
+
+ addVariable(pt, var);
+}
+
+
+/*
+ * Create a new ctor.
+ */
+static void newCtor(char *name, int sectFlags, signatureDef *args,
+ optFlags *optflgs, codeBlock *methodcode, throwArgs *exceptions,
+ signatureDef *cppsig, int explicit, codeBlock *docstring)
+{
+ ctorDef *ct, **ctp;
+ classDef *cd = currentScope();
+
+ /* Check the name of the constructor. */
+ if (strcmp(classBaseName(cd), name) != 0)
+ yyerror("Constructor doesn't have the same name as its class");
+
+ if (docstring != NULL)
+ appendCodeBlock(&cd->docstring, docstring);
+
+ /* Add to the list of constructors. */
+ ct = sipMalloc(sizeof (ctorDef));
+
+ if (sectFlags & SECT_IS_PROT && makeProtPublic)
+ {
+ sectFlags &= ~SECT_IS_PROT;
+ sectFlags |= SECT_IS_PUBLIC;
+ }
+
+ /* Allow the signature to be used like an function signature. */
+ memset(&args->result, 0, sizeof (argDef));
+ args->result.atype = void_type;
+
+ ct->ctorflags = sectFlags;
+ ct->api_range = getAPIRange(optflgs);
+ ct->pysig = *args;
+ ct->cppsig = (cppsig != NULL ? cppsig : &ct->pysig);
+ ct->exceptions = exceptions;
+ ct->methodcode = methodcode;
+
+ if (!isPrivateCtor(ct))
+ setCanCreate(cd);
+
+ if (isProtectedCtor(ct))
+ setHasShadow(cd);
+
+ if (explicit)
+ setIsExplicitCtor(ct);
+
+ getHooks(optflgs, &ct->prehook, &ct->posthook);
+
+ if (getReleaseGIL(optflgs))
+ setIsReleaseGILCtor(ct);
+ else if (getHoldGIL(optflgs))
+ setIsHoldGILCtor(ct);
+
+ if (getTransfer(optflgs))
+ setIsResultTransferredCtor(ct);
+
+ if (getDeprecated(optflgs))
+ setIsDeprecatedCtor(ct);
+
+ if (!isPrivateCtor(ct) && usesKeywordArgs(optflgs, &ct->pysig))
+ setUseKeywordArgsCtor(ct);
+
+ if (findOptFlag(optflgs, "NoDerived", bool_flag) != NULL)
+ {
+ if (cppsig != NULL)
+ yyerror("The /NoDerived/ annotation cannot be used with a C++ signature");
+
+ if (methodcode == NULL)
+ yyerror("The /NoDerived/ annotation must be used with %MethodCode");
+
+ ct->cppsig = NULL;
+ }
+
+ if (findOptFlag(optflgs, "Default", bool_flag) != NULL)
+ {
+ if (cd->defctor != NULL)
+ yyerror("A constructor with the /Default/ annotation has already been defined");
+
+ cd->defctor = ct;
+ }
+
+ /* Append to the list. */
+ for (ctp = &cd->ctors; *ctp != NULL; ctp = &(*ctp)->next)
+ ;
+
+ *ctp = ct;
+}
+
+
+/*
+ * Create a new function.
+ */
+static void newFunction(sipSpec *pt, moduleDef *mod, classDef *c_scope,
+ mappedTypeDef *mt_scope, int sflags, int isstatic, int issignal,
+ int isslot, int isvirt, char *name, signatureDef *sig, int isconst,
+ int isabstract, optFlags *optflgs, codeBlock *methodcode,
+ codeBlock *vcode, throwArgs *exceptions, signatureDef *cppsig,
+ codeBlock *docstring)
+{
+ int factory, xferback, no_arg_parser;
+ overDef *od, **odp, **headp;
+ optFlag *of;
+ virtHandlerDef *vhd;
+
+ /* Extra checks for a C module. */
+ if (pt->genc)
+ {
+ if (c_scope != NULL)
+ yyerror("Function declaration not allowed in a struct in a C module");
+
+ if (isstatic)
+ yyerror("Static functions not allowed in a C module");
+
+ if (exceptions != NULL)
+ yyerror("Exceptions not allowed in a C module");
+ }
+
+ if (mt_scope != NULL)
+ headp = &mt_scope->overs;
+ else if (c_scope != NULL)
+ headp = &c_scope->overs;
+ else
+ headp = &mod->overs;
+
+ /* See if it is a factory method. */
+ if (findOptFlag(optflgs, "Factory", bool_flag) != NULL)
+ factory = TRUE;
+ else
+ {
+ int a;
+
+ factory = FALSE;
+
+ /* Check /TransferThis/ wasn't specified. */
+ if (c_scope == NULL || isstatic)
+ for (a = 0; a < sig->nrArgs; ++a)
+ if (isThisTransferred(&sig->args[a]))
+ yyerror("/TransferThis/ may only be specified in constructors and class methods");
+ }
+
+ /* See if the result is to be returned to Python ownership. */
+ xferback = (findOptFlag(optflgs, "TransferBack", bool_flag) != NULL);
+
+ if (factory && xferback)
+ yyerror("/TransferBack/ and /Factory/ cannot both be specified");
+
+ /* Create a new overload definition. */
+
+ od = sipMalloc(sizeof (overDef));
+
+ /* Set the overload flags. */
+
+ if ((sflags & SECT_IS_PROT) && makeProtPublic)
+ {
+ sflags &= ~SECT_IS_PROT;
+ sflags |= SECT_IS_PUBLIC | OVER_REALLY_PROT;
+ }
+
+ od->overflags = sflags;
+
+ if (issignal)
+ {
+ resetIsSlot(od);
+ setIsSignal(od);
+ }
+ else if (isslot)
+ {
+ resetIsSignal(od);
+ setIsSlot(od);
+ }
+
+ if (factory)
+ setIsFactory(od);
+
+ if (xferback)
+ setIsResultTransferredBack(od);
+
+ if (getTransfer(optflgs))
+ setIsResultTransferred(od);
+
+ if (findOptFlag(optflgs, "TransferThis", bool_flag) != NULL)
+ setIsThisTransferredMeth(od);
+
+ if (isProtected(od))
+ setHasShadow(c_scope);
+
+ if ((isSlot(od) || isSignal(od)) && !isPrivate(od))
+ {
+ if (isSignal(od))
+ setHasShadow(c_scope);
+
+ pt->sigslots = TRUE;
+ }
+
+ if (isSignal(od) && (methodcode != NULL || vcode != NULL))
+ yyerror("Cannot provide code for signals");
+
+ if (isstatic)
+ {
+ if (isSignal(od))
+ yyerror("Static functions cannot be signals");
+
+ if (isvirt)
+ yyerror("Static functions cannot be virtual");
+
+ setIsStatic(od);
+ }
+
+ if (isconst)
+ setIsConst(od);
+
+ if (isabstract)
+ {
+ if (sflags == 0)
+ yyerror("Non-class function specified as abstract");
+
+ setIsAbstract(od);
+ }
+
+ if ((of = findOptFlag(optflgs, "AutoGen", opt_name_flag)) != NULL)
+ {
+ if (of->fvalue.sval == NULL || isEnabledFeature(of->fvalue.sval))
+ setIsAutoGen(od);
+ }
+
+ if (isvirt)
+ {
+ if (isSignal(od) && pluginPyQt3(pt))
+ yyerror("Virtual signals aren't supported");
+
+ setIsVirtual(od);
+ setHasShadow(c_scope);
+
+ vhd = sipMalloc(sizeof (virtHandlerDef));
+
+ vhd->virthandlernr = -1;
+ vhd->vhflags = 0;
+ vhd->pysig = &od->pysig;
+ vhd->cppsig = (cppsig != NULL ? cppsig : &od->pysig);
+ vhd->virtcode = vcode;
+
+ if (factory || xferback)
+ setIsTransferVH(vhd);
+
+ /*
+ * Only add it to the module's virtual handlers if we are not in a
+ * class template.
+ */
+ if (!currentIsTemplate)
+ {
+ vhd->module = mod;
+
+ vhd->next = mod->virthandlers;
+ mod->virthandlers = vhd;
+ }
+ }
+ else
+ {
+ if (vcode != NULL)
+ yyerror("%VirtualCatcherCode provided for non-virtual function");
+
+ vhd = NULL;
+ }
+
+ od->cppname = name;
+ od->pysig = *sig;
+ od->cppsig = (cppsig != NULL ? cppsig : &od->pysig);
+ od->exceptions = exceptions;
+ od->methodcode = methodcode;
+ od->virthandler = vhd;
+
+ no_arg_parser = (findOptFlag(optflgs, "NoArgParser", bool_flag) != NULL);
+
+ if (no_arg_parser)
+ {
+ if (methodcode == NULL)
+ yyerror("%MethodCode must be supplied if /NoArgParser/ is specified");
+ }
+
+ if (findOptFlag(optflgs, "NoCopy", bool_flag) != NULL)
+ setNoCopy(&od->pysig.result);
+
+ od->common = findFunction(pt, mod, c_scope, mt_scope,
+ getPythonName(optflgs, name), (methodcode != NULL), sig->nrArgs,
+ no_arg_parser);
+
+ if (docstring != NULL)
+ appendCodeBlock(&od->common->docstring, docstring);
+
+ od->api_range = getAPIRange(optflgs);
+
+ if (od->api_range == NULL)
+ setNotVersioned(od->common);
+
+ if (findOptFlag(optflgs, "Numeric", bool_flag) != NULL)
+ setIsNumeric(od->common);
+
+ /* Methods that run in new threads must be virtual. */
+ if (findOptFlag(optflgs, "NewThread", bool_flag) != NULL)
+ {
+ argDef *res;
+
+ if (!isvirt)
+ yyerror("/NewThread/ may only be specified for virtual functions");
+
+ /*
+ * This is an arbitary limitation to make the code generator slightly
+ * easier - laziness on my part.
+ */
+ res = &od->cppsig->result;
+
+ if (res->atype != void_type || res->nrderefs != 0)
+ yyerror("/NewThread/ may only be specified for void functions");
+
+ setIsNewThread(od);
+ }
+
+ getHooks(optflgs, &od->prehook, &od->posthook);
+
+ if (getReleaseGIL(optflgs))
+ setIsReleaseGIL(od);
+ else if (getHoldGIL(optflgs))
+ setIsHoldGIL(od);
+
+ if (getDeprecated(optflgs))
+ setIsDeprecated(od);
+
+ if (!isPrivate(od) && !isSignal(od) && od->common->slot == no_slot && usesKeywordArgs(optflgs, &od->pysig))
+ {
+ setUseKeywordArgs(od);
+ setUseKeywordArgsFunction(od->common);
+ }
+
+ /* See if we want to auto-generate a __len__() method. */
+ if (findOptFlag(optflgs, "__len__", bool_flag) != NULL)
+ {
+ overDef *len;
+
+ len = sipMalloc(sizeof (overDef));
+
+ len->cppname = "__len__";
+ len->overflags = SECT_IS_PUBLIC;
+ len->pysig.result.atype = ssize_type;
+ len->pysig.nrArgs = 0;
+ len->cppsig = &len->pysig;
+
+ len->common = findFunction(pt, mod, c_scope, mt_scope, len->cppname,
+ TRUE, 0, FALSE);
+
+ if ((len->methodcode = od->methodcode) == NULL)
+ {
+ char *buf = sipStrdup(" sipRes = (SIP_SSIZE_T)sipCpp->");
+ codeBlock *code;
+
+ append(&buf, od->cppname);
+ append(&buf, "();\n");
+
+ code = sipMalloc(sizeof (codeBlock));
+
+ code->frag = buf;
+ code->filename = "Auto-generated";
+ code->linenr = 0;
+ code->next = NULL;
+
+ len->methodcode = code;
+ }
+
+ len->next = NULL;
+
+ od->next = len;
+ }
+ else
+ {
+ od->next = NULL;
+ }
+
+ /* Append to the list. */
+ for (odp = headp; *odp != NULL; odp = &(*odp)->next)
+ ;
+
+ *odp = od;
+}
+
+
+/*
+ * Return the Python name based on the C/C++ name and any /PyName/ annotation.
+ */
+static const char *getPythonName(optFlags *optflgs, const char *cname)
+{
+ const char *pname;
+ optFlag *of;
+
+ if ((of = findOptFlag(optflgs, "PyName", name_flag)) != NULL)
+ pname = of->fvalue.sval;
+ else
+ pname = cname;
+
+ return pname;
+}
+
+
+/*
+ * Cache a name in a module. Entries in the cache are stored in order of
+ * decreasing length.
+ */
+nameDef *cacheName(sipSpec *pt, const char *name)
+{
+ nameDef *nd, **ndp;
+ size_t len;
+
+ /* Allow callers to be lazy about checking if there is really a name. */
+ if (name == NULL)
+ return NULL;
+
+ /* Skip entries that are too large. */
+ ndp = &pt->namecache;
+ len = strlen(name);
+
+ while (*ndp != NULL && (*ndp)->len > len)
+ ndp = &(*ndp)->next;
+
+ /* Check entries that are the right length. */
+ for (nd = *ndp; nd != NULL && nd->len == len; nd = nd->next)
+ if (memcmp(nd->text, name, len) == 0)
+ return nd;
+
+ /* Create a new one. */
+ nd = sipMalloc(sizeof (nameDef));
+
+ nd->nameflags = 0;
+ nd->text = name;
+ nd->len = len;
+ nd->next = *ndp;
+
+ *ndp = nd;
+
+ return nd;
+}
+
+
+/*
+ * Find (or create) an overloaded function name.
+ */
+static memberDef *findFunction(sipSpec *pt, moduleDef *mod, classDef *c_scope,
+ mappedTypeDef *mt_scope, const char *pname, int hwcode, int nrargs,
+ int no_arg_parser)
+{
+ static struct slot_map {
+ const char *name; /* The slot name. */
+ slotType type; /* The corresponding type. */
+ int needs_hwcode; /* Set if handwritten code is required. */
+ int nrargs; /* Nr. of arguments. */
+ } slot_table[] = {
+ {"__str__", str_slot, TRUE, 0},
+ {"__unicode__", unicode_slot, TRUE, 0},
+ {"__int__", int_slot, FALSE, 0},
+ {"__long__", long_slot, FALSE, 0},
+ {"__float__", float_slot, FALSE, 0},
+ {"__len__", len_slot, TRUE, 0},
+ {"__contains__", contains_slot, TRUE, 1},
+ {"__add__", add_slot, FALSE, 1},
+ {"__sub__", sub_slot, FALSE, 1},
+ {"__mul__", mul_slot, FALSE, 1},
+ {"__div__", div_slot, FALSE, 1},
+ {"__mod__", mod_slot, FALSE, 1},
+ {"__floordiv__", floordiv_slot, TRUE, 1},
+ {"__truediv__", truediv_slot, FALSE, 1},
+ {"__and__", and_slot, FALSE, 1},
+ {"__or__", or_slot, FALSE, 1},
+ {"__xor__", xor_slot, FALSE, 1},
+ {"__lshift__", lshift_slot, FALSE, 1},
+ {"__rshift__", rshift_slot, FALSE, 1},
+ {"__iadd__", iadd_slot, FALSE, 1},
+ {"__isub__", isub_slot, FALSE, 1},
+ {"__imul__", imul_slot, FALSE, 1},
+ {"__idiv__", idiv_slot, FALSE, 1},
+ {"__imod__", imod_slot, FALSE, 1},
+ {"__ifloordiv__", ifloordiv_slot, TRUE, 1},
+ {"__itruediv__", itruediv_slot, FALSE, 1},
+ {"__iand__", iand_slot, FALSE, 1},
+ {"__ior__", ior_slot, FALSE, 1},
+ {"__ixor__", ixor_slot, FALSE, 1},
+ {"__ilshift__", ilshift_slot, FALSE, 1},
+ {"__irshift__", irshift_slot, FALSE, 1},
+ {"__invert__", invert_slot, FALSE, 0},
+ {"__call__", call_slot, FALSE, -1},
+ {"__getitem__", getitem_slot, FALSE, 1},
+ {"__setitem__", setitem_slot, TRUE, 2},
+ {"__delitem__", delitem_slot, TRUE, 1},
+ {"__lt__", lt_slot, FALSE, 1},
+ {"__le__", le_slot, FALSE, 1},
+ {"__eq__", eq_slot, FALSE, 1},
+ {"__ne__", ne_slot, FALSE, 1},
+ {"__gt__", gt_slot, FALSE, 1},
+ {"__ge__", ge_slot, FALSE, 1},
+ {"__cmp__", cmp_slot, FALSE, 1},
+ {"__bool__", bool_slot, TRUE, 0},
+ {"__nonzero__", bool_slot, TRUE, 0},
+ {"__neg__", neg_slot, FALSE, 0},
+ {"__pos__", pos_slot, FALSE, 0},
+ {"__abs__", abs_slot, TRUE, 0},
+ {"__repr__", repr_slot, TRUE, 0},
+ {"__hash__", hash_slot, TRUE, 0},
+ {"__index__", index_slot, TRUE, 0},
+ {"__iter__", iter_slot, TRUE, 0},
+ {"__next__", next_slot, TRUE, 0},
+ {NULL}
+ };
+
+ memberDef *md, **flist;
+ struct slot_map *sm;
+ slotType st;
+
+ /* Get the slot type. */
+ st = no_slot;
+
+ for (sm = slot_table; sm->name != NULL; ++sm)
+ if (strcmp(sm->name, pname) == 0)
+ {
+ if (sm->needs_hwcode && !hwcode)
+ yyerror("This Python slot requires %MethodCode");
+
+ if (sm->nrargs >= 0)
+ {
+ if (mt_scope == NULL && c_scope == NULL)
+ {
+ /* Global operators need one extra argument. */
+ if (sm -> nrargs + 1 != nrargs)
+ yyerror("Incorrect number of arguments to global operator");
+ }
+ else if (sm->nrargs != nrargs)
+ yyerror("Incorrect number of arguments to Python slot");
+ }
+
+ st = sm->type;
+
+ break;
+ }
+
+ /* Check there is no name clash. */
+ checkAttributes(pt, mod, c_scope, mt_scope, pname, TRUE);
+
+ /* See if it already exists. */
+ if (mt_scope != NULL)
+ flist = &mt_scope->members;
+ else if (c_scope != NULL)
+ flist = &c_scope->members;
+ else
+ flist = &mod->othfuncs;
+
+ for (md = *flist; md != NULL; md = md->next)
+ if (strcmp(md->pyname->text, pname) == 0 && md->module == mod)
+ break;
+
+ if (md == NULL)
+ {
+ /* Create a new one. */
+ md = sipMalloc(sizeof (memberDef));
+
+ md->pyname = cacheName(pt, pname);
+ md->memberflags = 0;
+ md->slot = st;
+ md->module = mod;
+ md->next = *flist;
+
+ *flist = md;
+
+ if (inMainModule())
+ setIsUsedName(md->pyname);
+
+ if (no_arg_parser)
+ setNoArgParser(md);
+ }
+ else if (noArgParser(md))
+ yyerror("Another overload has already been defined that is annotated as /NoArgParser/");
+
+ /* Global operators are a subset. */
+ if (mt_scope == NULL && c_scope == NULL && st != no_slot && st != neg_slot && st != pos_slot && !isNumberSlot(md) && !isRichCompareSlot(md))
+ yyerror("Global operators must be either numeric or comparison operators");
+
+ return md;
+}
+
+
+/*
+ * Search a set of flags for a particular one and check its type.
+ */
+static optFlag *findOptFlag(optFlags *flgs,char *name,flagType ft)
+{
+ int f;
+
+ for (f = 0; f < flgs -> nrFlags; ++f)
+ {
+ optFlag *of = &flgs -> flags[f];
+
+ if (strcmp(of -> fname,name) == 0)
+ {
+ /*
+ * An optional name can look like a boolean or a name.
+ */
+
+ if (ft == opt_name_flag)
+ {
+ if (of -> ftype == bool_flag)
+ {
+ of -> ftype = opt_name_flag;
+ of -> fvalue.sval = NULL;
+ }
+ else if (of -> ftype == name_flag)
+ of -> ftype = opt_name_flag;
+ }
+
+ if (ft != of -> ftype)
+ yyerror("Optional flag has a value of the wrong type");
+
+ return of;
+ }
+ }
+
+ return NULL;
+}
+
+
+/*
+ * A name is going to be used as a Python attribute name within a Python scope
+ * (ie. a Python dictionary), so check against what we already know is going in
+ * the same scope in case there is a clash.
+ */
+static void checkAttributes(sipSpec *pt, moduleDef *mod, classDef *py_c_scope,
+ mappedTypeDef *py_mt_scope, const char *attr, int isfunc)
+{
+ enumDef *ed;
+ varDef *vd;
+ classDef *cd;
+
+ /* Check the enums. */
+
+ for (ed = pt->enums; ed != NULL; ed = ed->next)
+ {
+ enumMemberDef *emd;
+
+ if (ed->pyname == NULL)
+ continue;
+
+ if (py_c_scope != NULL)
+ {
+ if (ed->ecd != py_c_scope)
+ continue;
+ }
+ else if (py_mt_scope != NULL)
+ {
+ if (ed->emtd != py_mt_scope)
+ continue;
+ }
+ else if (ed->ecd != NULL || ed->emtd != NULL)
+ {
+ continue;
+ }
+
+ if (strcmp(ed->pyname->text, attr) == 0)
+ yyerror("There is already an enum in scope with the same Python name");
+
+ for (emd = ed->members; emd != NULL; emd = emd->next)
+ if (strcmp(emd->pyname->text, attr) == 0)
+ yyerror("There is already an enum member in scope with the same Python name");
+ }
+
+ /*
+ * Only check the members if this attribute isn't a member because we
+ * can handle members with the same name in the same scope.
+ */
+ if (!isfunc)
+ {
+ memberDef *md, *membs;
+ overDef *overs;
+
+ if (py_mt_scope != NULL)
+ {
+ membs = py_mt_scope->members;
+ overs = py_mt_scope->overs;
+ }
+ else if (py_c_scope != NULL)
+ {
+ membs = py_c_scope->members;
+ overs = py_c_scope->overs;
+ }
+ else
+ {
+ membs = mod->othfuncs;
+ overs = mod->overs;
+ }
+
+ for (md = membs; md != NULL; md = md->next)
+ {
+ overDef *od;
+
+ if (strcmp(md->pyname->text, attr) != 0)
+ continue;
+
+ /* Check for a conflict with all overloads. */
+ for (od = overs; od != NULL; od = od->next)
+ {
+ if (od->common != md)
+ continue;
+
+ yyerror("There is already a function in scope with the same Python name");
+ }
+ }
+ }
+
+ /* If the scope was a mapped type then that's all we have to check. */
+ if (py_mt_scope != NULL)
+ return;
+
+ /* Check the variables. */
+ for (vd = pt->vars; vd != NULL; vd = vd->next)
+ {
+ if (vd->ecd != py_c_scope)
+ continue;
+
+ if (strcmp(vd->pyname->text,attr) == 0)
+ yyerror("There is already a variable in scope with the same Python name");
+ }
+
+ /* Check the classes. */
+ for (cd = pt->classes; cd != NULL; cd = cd->next)
+ {
+ if (cd->ecd != py_c_scope || cd->pyname == NULL)
+ continue;
+
+ if (strcmp(cd->pyname->text, attr) == 0 && !isExternal(cd))
+ yyerror("There is already a class or namespace in scope with the same Python name");
+ }
+
+ /* Check the exceptions. */
+ if (py_c_scope == NULL)
+ {
+ exceptionDef *xd;
+
+ for (xd = pt->exceptions; xd != NULL; xd = xd->next)
+ if (xd->pyname != NULL && strcmp(xd->pyname, attr) == 0)
+ yyerror("There is already an exception with the same Python name");
+ }
+}
+
+
+/*
+ * Append a code block to a list of them. Append is needed to give the
+ * specifier easy control over the order of the documentation.
+ */
+void appendCodeBlock(codeBlock **headp, codeBlock *new)
+{
+ while (*headp != NULL)
+ headp = &(*headp)->next;
+
+ *headp = new;
+}
+
+
+/*
+ * Handle the end of a fully parsed a file.
+ */
+static void handleEOF()
+{
+ /*
+ * Check that the number of nested if's is the same as when we started
+ * the file.
+ */
+
+ if (skipStackPtr > currentContext.ifdepth)
+ fatal("Too many %%If statements in %s\n", previousFile);
+
+ if (skipStackPtr < currentContext.ifdepth)
+ fatal("Too many %%End statements in %s\n", previousFile);
+}
+
+
+/*
+ * Handle the end of a fully parsed a module.
+ */
+static void handleEOM()
+{
+ moduleDef *from;
+
+ /* Check it has been named. */
+ if (currentModule->name == NULL)
+ fatal("No %%Module has been specified for module defined in %s\n",
+ previousFile);
+
+ from = currentContext.prevmod;
+
+ if (from != NULL && from->encoding == no_type)
+ from->encoding = currentModule->encoding;
+
+ /* The previous module is now current. */
+ currentModule = from;
+}
+
+
+/*
+ * Find an existing qualifier.
+ */
+static qualDef *findQualifier(const char *name)
+{
+ moduleDef *mod;
+
+ for (mod = currentSpec->modules; mod != NULL; mod = mod->next)
+ {
+ qualDef *qd;
+
+ for (qd = mod->qualifiers; qd != NULL; qd = qd->next)
+ if (strcmp(qd->name, name) == 0)
+ return qd;
+ }
+
+ return NULL;
+}
+
+
+/*
+ * Find an existing API.
+ */
+apiVersionRangeDef *findAPI(sipSpec *pt, const char *name)
+{
+ moduleDef *mod;
+
+ for (mod = pt->modules; mod != NULL; mod = mod->next)
+ {
+ apiVersionRangeDef *avd;
+
+ for (avd = mod->api_versions; avd != NULL; avd = avd->next)
+ if (strcmp(avd->api_name->text, name) == 0)
+ return avd;
+ }
+
+ return NULL;
+}
+
+
+/*
+ * Return a copy of a scoped name.
+ */
+scopedNameDef *copyScopedName(scopedNameDef *snd)
+{
+ scopedNameDef *head;
+
+ head = NULL;
+
+ while (snd != NULL)
+ {
+ appendScopedName(&head,text2scopePart(snd -> name));
+ snd = snd -> next;
+ }
+
+ return head;
+}
+
+
+/*
+ * Append a name to a list of scopes.
+ */
+void appendScopedName(scopedNameDef **headp,scopedNameDef *newsnd)
+{
+ while (*headp != NULL)
+ headp = &(*headp) -> next;
+
+ *headp = newsnd;
+}
+
+
+/*
+ * Free a scoped name - but not the text itself.
+ */
+void freeScopedName(scopedNameDef *snd)
+{
+ while (snd != NULL)
+ {
+ scopedNameDef *next = snd -> next;
+
+ free(snd);
+
+ snd = next;
+ }
+}
+
+
+/*
+ * Convert a text string to a scope part structure.
+ */
+static scopedNameDef *text2scopePart(char *text)
+{
+ scopedNameDef *snd;
+
+ snd = sipMalloc(sizeof (scopedNameDef));
+
+ snd->name = text;
+ snd->next = NULL;
+
+ return snd;
+}
+
+
+/*
+ * Convert a text string to a fully scoped name.
+ */
+static scopedNameDef *text2scopedName(ifaceFileDef *scope, char *text)
+{
+ return scopeScopedName(scope, text2scopePart(text));
+}
+
+
+/*
+ * Prepend any current scope to a scoped name.
+ */
+static scopedNameDef *scopeScopedName(ifaceFileDef *scope, scopedNameDef *name)
+{
+ scopedNameDef *snd;
+
+ snd = (scope != NULL ? copyScopedName(scope->fqcname) : NULL);
+
+ appendScopedName(&snd, name);
+
+ return snd;
+}
+
+
+/*
+ * Return a pointer to the tail part of a scoped name.
+ */
+char *scopedNameTail(scopedNameDef *snd)
+{
+ if (snd == NULL)
+ return NULL;
+
+ while (snd -> next != NULL)
+ snd = snd -> next;
+
+ return snd -> name;
+}
+
+
+/*
+ * Push the given scope onto the scope stack.
+ */
+static void pushScope(classDef *scope)
+{
+ if (currentScopeIdx >= MAX_NESTED_SCOPE)
+ fatal("Internal error: increase the value of MAX_NESTED_SCOPE\n");
+
+ scopeStack[currentScopeIdx] = scope;
+ sectFlagsStack[currentScopeIdx] = sectionFlags;
+
+ ++currentScopeIdx;
+}
+
+
+/*
+ * Pop the scope stack.
+ */
+static void popScope(void)
+{
+ if (currentScopeIdx > 0)
+ sectionFlags = sectFlagsStack[--currentScopeIdx];
+}
+
+
+/*
+ * Return non-zero if the current input should be parsed rather than be
+ * skipped.
+ */
+static int notSkipping()
+{
+ return (skipStackPtr == 0 ? TRUE : skipStack[skipStackPtr - 1]);
+}
+
+
+/*
+ * Return the value of an expression involving a time period.
+ */
+static int timePeriod(char *lname,char *uname)
+{
+ int this, line;
+ qualDef *qd, *lower, *upper;
+ moduleDef *mod;
+
+ if (lname == NULL)
+ lower = NULL;
+ else if ((lower = findQualifier(lname)) == NULL || lower -> qtype != time_qualifier)
+ yyerror("Lower bound is not a time version");
+
+ if (uname == NULL)
+ upper = NULL;
+ else if ((upper = findQualifier(uname)) == NULL || upper -> qtype != time_qualifier)
+ yyerror("Upper bound is not a time version");
+
+ /* Sanity checks on the bounds. */
+
+ if (lower == NULL && upper == NULL)
+ yyerror("Lower and upper bounds cannot both be omitted");
+
+ if (lower != NULL && upper != NULL)
+ {
+ if (lower -> module != upper -> module || lower -> line != upper -> line)
+ yyerror("Lower and upper bounds are from different timelines");
+
+ if (lower == upper)
+ yyerror("Lower and upper bounds must be different");
+
+ if (lower -> order > upper -> order)
+ yyerror("Later version specified as lower bound");
+ }
+
+ /* Go through each slot in the relevant timeline. */
+
+ if (lower != NULL)
+ {
+ mod = lower -> module;
+ line = lower -> line;
+ }
+ else
+ {
+ mod = upper -> module;
+ line = upper -> line;
+ }
+
+ this = FALSE;
+
+ for (qd = mod -> qualifiers; qd != NULL; qd = qd -> next)
+ {
+ if (qd -> qtype != time_qualifier || qd -> line != line)
+ continue;
+
+ if (lower != NULL && qd -> order < lower -> order)
+ continue;
+
+ if (upper != NULL && qd -> order >= upper -> order)
+ continue;
+
+ /*
+ * This is within the required range so if it is also needed
+ * then the expression is true.
+ */
+
+ if (isNeeded(qd))
+ {
+ this = TRUE;
+ break;
+ }
+ }
+
+ return this;
+}
+
+
+/*
+ * Return the value of an expression involving a single platform or feature.
+ */
+static int platOrFeature(char *name,int optnot)
+{
+ int this;
+ qualDef *qd;
+
+ if ((qd = findQualifier(name)) == NULL || qd -> qtype == time_qualifier)
+ yyerror("No such platform or feature");
+
+ /* Assume this sub-expression is false. */
+
+ this = FALSE;
+
+ if (qd -> qtype == feature_qualifier)
+ {
+ if (!excludedFeature(excludedQualifiers,qd))
+ this = TRUE;
+ }
+ else if (isNeeded(qd))
+ this = TRUE;
+
+ if (optnot)
+ this = !this;
+
+ return this;
+}
+
+
+/*
+ * Return TRUE if the given qualifier is excluded.
+ */
+int excludedFeature(stringList *xsl,qualDef *qd)
+{
+ while (xsl != NULL)
+ {
+ if (strcmp(qd -> name,xsl -> s) == 0)
+ return TRUE;
+
+ xsl = xsl -> next;
+ }
+
+ return FALSE;
+}
+
+
+/*
+ * Return TRUE if the given qualifier is needed.
+ */
+static int isNeeded(qualDef *qd)
+{
+ stringList *sl;
+
+ for (sl = neededQualifiers; sl != NULL; sl = sl -> next)
+ if (strcmp(qd -> name,sl -> s) == 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+
+/*
+ * Return the current scope. currentScope() is only valid if notSkipping()
+ * returns non-zero.
+ */
+static classDef *currentScope(void)
+{
+ return (currentScopeIdx > 0 ? scopeStack[currentScopeIdx - 1] : NULL);
+}
+
+
+/*
+ * Create a new qualifier.
+ */
+static void newQualifier(moduleDef *mod, int line, int order, char *name,
+ qualType qt)
+{
+ qualDef *qd;
+
+ /* Check it doesn't already exist. */
+
+ if (findQualifier(name) != NULL)
+ yyerror("Version is already defined");
+
+ qd = sipMalloc(sizeof (qualDef));
+ qd->name = name;
+ qd->qtype = qt;
+ qd->module = mod;
+ qd->line = line;
+ qd->order = order;
+ qd->next = mod -> qualifiers;
+ mod->qualifiers = qd;
+}
+
+
+/*
+ * Create a new imported module.
+ */
+static void newImport(char *filename)
+{
+ moduleDef *from, *mod;
+ moduleListDef *mld;
+
+ /* Create a new module if it has not already been defined. */
+ for (mod = currentSpec->modules; mod != NULL; mod = mod->next)
+ if (strcmp(mod->file, filename) == 0)
+ break;
+
+ from = currentModule;
+
+ if (mod == NULL)
+ {
+ newModule(NULL, filename);
+ mod = currentModule;
+ }
+ else if (from->encoding == no_type)
+ {
+ /* Import any defaults from the already parsed module. */
+ from->encoding = mod->encoding;
+ }
+
+ /* Add the new import unless it has already been imported. */
+ for (mld = from->imports; mld != NULL; mld = mld->next)
+ if (mld->module == mod)
+ return;
+
+ mld = sipMalloc(sizeof (moduleListDef));
+ mld->module = mod;
+ mld->next = from->imports;
+
+ from->imports = mld;
+}
+
+
+/*
+ * Set up pointers to hook names.
+ */
+static void getHooks(optFlags *optflgs,char **pre,char **post)
+{
+ optFlag *of;
+
+ if ((of = findOptFlag(optflgs,"PreHook",name_flag)) != NULL)
+ *pre = of -> fvalue.sval;
+ else
+ *pre = NULL;
+
+ if ((of = findOptFlag(optflgs,"PostHook",name_flag)) != NULL)
+ *post = of -> fvalue.sval;
+ else
+ *post = NULL;
+}
+
+
+/*
+ * Get the /Transfer/ option flag.
+ */
+static int getTransfer(optFlags *optflgs)
+{
+ return (findOptFlag(optflgs, "Transfer", bool_flag) != NULL);
+}
+
+
+/*
+ * Get the /ReleaseGIL/ option flag.
+ */
+static int getReleaseGIL(optFlags *optflgs)
+{
+ return (findOptFlag(optflgs, "ReleaseGIL", bool_flag) != NULL);
+}
+
+
+/*
+ * Get the /HoldGIL/ option flag.
+ */
+static int getHoldGIL(optFlags *optflgs)
+{
+ return (findOptFlag(optflgs, "HoldGIL", bool_flag) != NULL);
+}
+
+
+/*
+ * Get the /Deprecated/ option flag.
+ */
+static int getDeprecated(optFlags *optflgs)
+{
+ return (findOptFlag(optflgs, "Deprecated", bool_flag) != NULL);
+}
+
+
+/*
+ * Get the /AllowNone/ option flag.
+ */
+static int getAllowNone(optFlags *optflgs)
+{
+ return (findOptFlag(optflgs, "AllowNone", bool_flag) != NULL);
+}
+
+
+/*
+ * Get the /DocType/ option flag.
+ */
+static const char *getDocType(optFlags *optflgs)
+{
+ optFlag *of = findOptFlag(optflgs, "DocType", string_flag);
+
+ if (of == NULL)
+ return NULL;
+
+ return of->fvalue.sval;
+}
+
+
+/*
+ * Get the /DocValue/ option flag.
+ */
+static const char *getDocValue(optFlags *optflgs)
+{
+ optFlag *of = findOptFlag(optflgs, "DocValue", string_flag);
+
+ if (of == NULL)
+ return NULL;
+
+ return of->fvalue.sval;
+}
+
+
+/*
+ * Return TRUE if the PyQt3 plugin was specified.
+ */
+int pluginPyQt3(sipSpec *pt)
+{
+ return stringFind(pt->plugins, "PyQt3");
+}
+
+
+/*
+ * Return TRUE if the PyQt4 plugin was specified.
+ */
+int pluginPyQt4(sipSpec *pt)
+{
+ return stringFind(pt->plugins, "PyQt4");
+}
+
+
+/*
+ * Return TRUE if a list of strings contains a given entry.
+ */
+static int stringFind(stringList *sl, const char *s)
+{
+ while (sl != NULL)
+ {
+ if (strcmp(sl->s, s) == 0)
+ return TRUE;
+
+ sl = sl->next;
+ }
+
+ return FALSE;
+}
+
+
+/*
+ * Set the name of a module.
+ */
+static void setModuleName(sipSpec *pt, moduleDef *mod, const char *fullname)
+{
+ mod->fullname = cacheName(pt, fullname);
+
+ if (inMainModule())
+ setIsUsedName(mod->fullname);
+
+ if ((mod->name = strrchr(fullname, '.')) != NULL)
+ mod->name++;
+ else
+ mod->name = fullname;
+}
+
+
+/*
+ * Define a new class and set its name.
+ */
+static void defineClass(scopedNameDef *snd, classList *supers, optFlags *of)
+{
+ classDef *cd, *c_scope = currentScope();
+
+ cd = newClass(currentSpec, class_iface, getAPIRange(of),
+ scopeScopedName((c_scope != NULL ? c_scope->iff : NULL), snd));
+ cd->supers = supers;
+
+ pushScope(cd);
+}
+
+
+/*
+ * Complete the definition of a class.
+ */
+static classDef *completeClass(scopedNameDef *snd, optFlags *of, int has_def)
+{
+ classDef *cd = currentScope();
+
+ /* See if the class was defined or just declared. */
+ if (has_def)
+ {
+ if (snd->next != NULL)
+ yyerror("A scoped name cannot be given in a class/struct definition");
+
+ }
+ else if (cd->supers != NULL)
+ yyerror("Class/struct has super-classes but no definition");
+ else
+ setIsOpaque(cd);
+
+ finishClass(currentSpec, currentModule, cd, of);
+ popScope();
+
+ /*
+ * Check that external classes have only been declared at the global scope.
+ */
+ if (isExternal(cd) && currentScope() != NULL)
+ yyerror("External classes/structs can only be declared in the global scope");
+
+ return cd;
+}
+
+
+/*
+ * Add a variable to the list so that the list remains sorted.
+ */
+static void addVariable(sipSpec *pt, varDef *vd)
+{
+ varDef **at = &pt->vars;
+
+ while (*at != NULL)
+ {
+ if (strcmp(vd->pyname->text, (*at)->pyname->text) < 0)
+ break;
+
+ at = &(*at)->next;
+ }
+
+ vd->next = *at;
+ *at = vd;
+}
+
+
+/*
+ * Update a type according to optional flags.
+ */
+static void applyTypeFlags(moduleDef *mod, argDef *ad, optFlags *flags)
+{
+ ad->doctype = getDocType(flags);
+
+ if (ad->atype == string_type && !isArray(ad) && !isReference(ad))
+ {
+ optFlag *of;
+
+ if ((of = findOptFlag(flags, "Encoding", string_flag)) == NULL)
+ {
+ if (mod->encoding != no_type)
+ ad->atype = mod->encoding;
+ else
+ ad->atype = string_type;
+ }
+ else if ((ad->atype = convertEncoding(of->fvalue.sval)) == no_type)
+ yyerror("The value of the /Encoding/ annotation must be one of \"ASCII\", \"Latin-1\", \"UTF-8\" or \"None\"");
+ }
+}
+
+
+/*
+ * Return the argument type for a string with the given encoding or no_type if
+ * the encoding was invalid.
+ */
+static argType convertEncoding(const char *encoding)
+{
+ if (strcmp(encoding, "ASCII") == 0)
+ return ascii_string_type;
+
+ if (strcmp(encoding, "Latin-1") == 0)
+ return latin1_string_type;
+
+ if (strcmp(encoding, "UTF-8") == 0)
+ return utf8_string_type;
+
+ if (strcmp(encoding, "None") == 0)
+ return string_type;
+
+ return no_type;
+}
+
+
+/*
+ * Get the /API/ option flag.
+ */
+static apiVersionRangeDef *getAPIRange(optFlags *optflgs)
+{
+ optFlag *of;
+
+ if ((of = findOptFlag(optflgs, "API", api_range_flag)) == NULL)
+ return NULL;
+
+ return of->fvalue.aval;
+}
+
+
+/*
+ * Return the API range structure and version number corresponding to the
+ * given API range.
+ */
+static apiVersionRangeDef *convertAPIRange(moduleDef *mod, nameDef *name,
+ int from, int to)
+{
+ int index;
+ apiVersionRangeDef *avd, **avdp;
+
+ /* Handle the trivial case. */
+ if (from == 0 && to == 0)
+ return NULL;
+
+ for (index = 0, avdp = &mod->api_ranges; (*avdp) != NULL; avdp = &(*avdp)->next, ++index)
+ {
+ avd = *avdp;
+
+ if (avd->api_name == name && avd->from == from && avd->to == to)
+ return avd;
+ }
+
+ /* The new one must be appended so that version numbers remain valid. */
+ avd = sipMalloc(sizeof (apiVersionRangeDef));
+
+ avd->api_name = name;
+ avd->from = from;
+ avd->to = to;
+ avd->index = index;
+
+ avd->next = NULL;
+ *avdp = avd;
+
+ return avd;
+}
+
+
+/*
+ * Return TRUE if a signature with annotations uses keyword arguments.
+ */
+static int usesKeywordArgs(optFlags *optflgs, signatureDef *sd)
+{
+ int kwd_args_anno, no_kwd_args_anno;
+
+ kwd_args_anno = (findOptFlag(optflgs, "KeywordArgs", bool_flag) != NULL);
+ no_kwd_args_anno = (findOptFlag(optflgs, "NoKeywordArgs", bool_flag) != NULL);
+
+ /*
+ * An ellipsis cannot be used with keyword arguments. Only complain if it
+ * has been explicitly requested.
+ */
+ if (kwd_args_anno && sd->nrArgs > 0 && sd->args[sd->nrArgs - 1].atype == ellipsis_type)
+ yyerror("/KeywordArgs/ cannot be specified for calls with a variable number of arguments");
+
+ if ((defaultKwdArgs || kwd_args_anno) && !no_kwd_args_anno)
+ {
+ int a, is_name = FALSE;
+
+ /*
+ * Mark argument names as being used and check there is at least one.
+ */
+ for (a = 0; a < sd->nrArgs; ++a)
+ {
+ nameDef *nd = sd->args[a].name;
+
+ if (sd->args[a].name != NULL)
+ {
+ setIsUsedName(nd);
+ is_name = TRUE;
+ }
+ }
+
+ return is_name;
+ }
+
+ return FALSE;
+}
+
+
+/*
+ * Extract the version of a string value optionally associated with a
+ * particular feature.
+ */
+static char *convertFeaturedString(char *fs)
+{
+ while (fs != NULL)
+ {
+ char *next, *value;
+
+ /* Individual values are ';' separated. */
+ if ((next = strchr(fs, ';')) != NULL)
+ *next++ = '\0';
+
+ /* Features and values are ':' separated. */
+ if ((value = strchr(fs, ':')) == NULL)
+ {
+ /* This is an unconditional value so just return it. */
+ return strip(fs);
+ }
+
+ *value++ = '\0';
+
+ if (isEnabledFeature(strip(fs)))
+ return strip(value);
+
+ fs = next;
+ }
+
+ /* No value was enabled. */
+ return NULL;
+}
+
+
+/*
+ * Return the stripped version of a string.
+ */
+static char *strip(char *s)
+{
+ while (*s == ' ')
+ ++s;
+
+ if (*s != '\0')
+ {
+ char *cp = &s[strlen(s) - 1];
+
+ while (*cp == ' ')
+ *cp-- = '\0';
+ }
+
+ return s;
+}
+
+
+/*
+ * Return TRUE if the given feature is enabled.
+ */
+static int isEnabledFeature(const char *name)
+{
+ qualDef *qd;
+
+ if ((qd = findQualifier(name)) == NULL || qd->qtype != feature_qualifier)
+ yyerror("No such feature");
+
+ return !excludedFeature(excludedQualifiers, qd);
+}
diff --git a/sipgen/sip.h b/sipgen/sip.h
new file mode 100644
index 0000000..624a1ee
--- /dev/null
+++ b/sipgen/sip.h
@@ -0,0 +1,1180 @@
+/*
+ * The main header file for SIP.
+ *
+ * Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com>
+ *
+ * This file is part of SIP.
+ *
+ * This copy of SIP is licensed for use under the terms of the SIP License
+ * Agreement. See the file LICENSE for more details.
+ *
+ * This copy of SIP may also used under the terms of the GNU General Public
+ * License v2 or v3 as published by the Free Software Foundation which can be
+ * found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
+ *
+ * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#ifndef SIP_H
+#define SIP_H
+
+#include <stdio.h>
+#include <sys/types.h>
+
+
+#ifdef TRUE
+#undef TRUE
+#endif
+
+#ifdef FALSE
+#undef FALSE
+#endif
+
+#define TRUE 1
+#define FALSE 0
+
+
+#define DEFAULT_OFILE_EXT ".o" /* Default object file extension. */
+
+#define MAX_NR_ARGS 20 /* Max. nr. args. to a function or template. */
+
+
+/* For convenience. */
+
+#define classBaseName(cd) scopedNameTail((cd)->iff->fqcname)
+#define classFQCName(cd) ((cd)->iff->fqcname)
+
+
+/* Handle module flags. */
+
+#define MOD_HAS_DELAYED_DTORS 0x0001 /* It has a class with a delayed dtor. */
+#define MOD_IS_CONSOLIDATED 0x0002 /* It is a consolidated module. */
+#define MOD_IS_COMPOSITE 0x0004 /* It is a composite module. */
+#define MOD_IS_TRANSFORMED 0x0008 /* It's types have been transformed. */
+
+#define hasDelayedDtors(m) ((m)->modflags & MOD_HAS_DELAYED_DTORS)
+#define setHasDelayedDtors(m) ((m)->modflags |= MOD_HAS_DELAYED_DTORS)
+#define isConsolidated(m) ((m)->modflags & MOD_IS_CONSOLIDATED)
+#define setIsConsolidated(m) ((m)->modflags |= MOD_IS_CONSOLIDATED)
+#define isComposite(m) ((m)->modflags & MOD_IS_COMPOSITE)
+#define setIsComposite(m) ((m)->modflags |= MOD_IS_COMPOSITE)
+#define isContainer(m) ((m)->modflags & (MOD_IS_CONSOLIDATED | MOD_IS_COMPOSITE))
+#define setIsTransformed(m) ((m)->modflags |= MOD_IS_TRANSFORMED)
+#define isTransformed(m) ((m)->modflags & MOD_IS_TRANSFORMED)
+
+
+/* Handle section flags. */
+
+#define SECT_IS_PUBLIC 0x01 /* It is public. */
+#define SECT_IS_PROT 0x02 /* It is protected. */
+#define SECT_IS_PRIVATE 0x04 /* It is private. */
+#define SECT_IS_SLOT 0x08 /* It is a slot. */
+#define SECT_IS_SIGNAL 0x10 /* It is a signal. */
+#define SECT_MASK 0x1f /* The mask of all flags. */
+
+
+/* Handle class flags. These are combined with the section flags. */
+
+#define CLASS_HAS_SIGSLOTS 0x00000200 /* It has signals or slots. */
+#define CLASS_IS_ABSTRACT 0x00000400 /* It is an abstract class. */
+#define CLASS_HAS_SHADOW 0x00000800 /* It is has a shadow class. */
+#define CLASS_IS_OPAQUE 0x00001000 /* It is opaque. */
+#define CLASS_HAS_VAR_HANDLERS 0x00002000 /* It has variable handlers. */
+#define CLASS_DTOR_RELEASE_GIL 0x00004000 /* The dtor releases the GIL. */
+#define CLASS_IS_PROTECTED 0x00008000 /* It is protected. */
+#define CLASS_IS_PROTECTED_SAV 0x00010000 /* It is protected (saved). */
+#define CLASS_IS_INCOMPLETE 0x00020000 /* The specification is incomplete. */
+#define CLASS_CAN_CREATE 0x00040000 /* It has usable ctors. */
+#define CLASS_IS_EXTERNAL 0x00080000 /* It is external. */
+#define CLASS_IS_DELAYED_DTOR 0x00100000 /* The dtor is delayed. */
+#define CLASS_NO_DEFAULT_CTORS 0x00200000 /* Don't create default ctors. */
+#define CLASS_QOBJECT_SUB 0x00400000 /* It is derived from QObject. */
+#define CLASS_DTOR_HOLD_GIL 0x00800000 /* The dtor holds the GIL. */
+#define CLASS_ASSIGN_HELPER 0x01000000 /* Generate an assignment helper. */
+#define CLASS_NO_QMETAOBJECT 0x02000000 /* It has no QMetaObject. */
+#define CLASS_IS_TEMPLATE 0x04000000 /* It is a template class. */
+#define CLASS_IS_DEPRECATED 0x08000000 /* It is deprecated. */
+#define CLASS_CANNOT_COPY 0x10000000 /* It cannot be copied. */
+#define CLASS_CANNOT_ASSIGN 0x20000000 /* It cannot be assigned. */
+#define CLASS_ALLOW_NONE 0x40000000 /* The class will handle None. */
+
+#define hasSigSlots(cd) ((cd)->classflags & CLASS_HAS_SIGSLOTS)
+#define setHasSigSlots(cd) ((cd)->classflags |= CLASS_HAS_SIGSLOTS)
+#define isAbstractClass(cd) ((cd)->classflags & CLASS_IS_ABSTRACT)
+#define setIsAbstractClass(cd) ((cd)->classflags |= CLASS_IS_ABSTRACT)
+#define hasShadow(cd) ((cd)->classflags & CLASS_HAS_SHADOW)
+#define setHasShadow(cd) ((cd)->classflags |= CLASS_HAS_SHADOW)
+#define resetHasShadow(cd) ((cd)->classflags &= ~CLASS_HAS_SHADOW)
+#define isOpaque(cd) ((cd)->classflags & CLASS_IS_OPAQUE)
+#define setIsOpaque(cd) ((cd)->classflags |= CLASS_IS_OPAQUE)
+#define hasVarHandlers(cd) ((cd)->classflags & CLASS_HAS_VAR_HANDLERS)
+#define setHasVarHandlers(cd) ((cd)->classflags |= CLASS_HAS_VAR_HANDLERS)
+#define isProtectedClass(cd) ((cd)->classflags & CLASS_IS_PROTECTED)
+#define setIsProtectedClass(cd) ((cd)->classflags |= CLASS_IS_PROTECTED)
+#define resetIsProtectedClass(cd) ((cd)->classflags &= ~CLASS_IS_PROTECTED)
+#define wasProtectedClass(cd) ((cd)->classflags & CLASS_IS_PROTECTED_SAV)
+#define setWasProtectedClass(cd) ((cd)->classflags |= CLASS_IS_PROTECTED_SAV)
+#define resetWasProtectedClass(cd) ((cd)->classflags &= ~CLASS_IS_PROTECTED_SAV)
+#define isReleaseGILDtor(cd) ((cd)->classflags & CLASS_DTOR_RELEASE_GIL)
+#define setIsReleaseGILDtor(cd) ((cd)->classflags |= CLASS_DTOR_RELEASE_GIL)
+#define isIncomplete(cd) ((cd)->classflags & CLASS_IS_INCOMPLETE)
+#define setIsIncomplete(cd) ((cd)->classflags |= CLASS_IS_INCOMPLETE)
+#define canCreate(cd) ((cd)->classflags & CLASS_CAN_CREATE)
+#define setCanCreate(cd) ((cd)->classflags |= CLASS_CAN_CREATE)
+#define resetCanCreate(cd) ((cd)->classflags &= ~CLASS_CAN_CREATE)
+#define isExternal(cd) ((cd)->classflags & CLASS_IS_EXTERNAL)
+#define setIsExternal(cd) ((cd)->classflags |= CLASS_IS_EXTERNAL)
+#define isDelayedDtor(cd) ((cd)->classflags & CLASS_IS_DELAYED_DTOR)
+#define setIsDelayedDtor(cd) ((cd)->classflags |= CLASS_IS_DELAYED_DTOR)
+#define noDefaultCtors(cd) ((cd)->classflags & CLASS_NO_DEFAULT_CTORS)
+#define setNoDefaultCtors(cd) ((cd)->classflags |= CLASS_NO_DEFAULT_CTORS)
+#define isQObjectSubClass(cd) ((cd)->classflags & CLASS_QOBJECT_SUB)
+#define setIsQObjectSubClass(cd) ((cd)->classflags |= CLASS_QOBJECT_SUB)
+#define isHoldGILDtor(cd) ((cd)->classflags & CLASS_DTOR_HOLD_GIL)
+#define setIsHoldGILDtor(cd) ((cd)->classflags |= CLASS_DTOR_HOLD_GIL)
+#define assignmentHelper(cd) ((cd)->classflags & CLASS_ASSIGN_HELPER)
+#define setAssignmentHelper(cd) ((cd)->classflags |= CLASS_ASSIGN_HELPER)
+#define noPyQt4QMetaObject(cd) ((cd)->classflags & CLASS_NO_QMETAOBJECT)
+#define setPyQt4NoQMetaObject(cd) ((cd)->classflags |= CLASS_NO_QMETAOBJECT)
+#define isTemplateClass(cd) ((cd)->classflags & CLASS_IS_TEMPLATE)
+#define setIsTemplateClass(cd) ((cd)->classflags |= CLASS_IS_TEMPLATE)
+#define resetIsTemplateClass(cd) ((cd)->classflags &= ~CLASS_IS_TEMPLATE)
+#define isDeprecatedClass(cd) ((cd)->classflags & CLASS_IS_DEPRECATED)
+#define setIsDeprecatedClass(cd) ((cd)->classflags |= CLASS_IS_DEPRECATED)
+#define cannotCopy(cd) ((cd)->classflags & CLASS_CANNOT_COPY)
+#define setCannotCopy(cd) ((cd)->classflags |= CLASS_CANNOT_COPY)
+#define cannotAssign(cd) ((cd)->classflags & CLASS_CANNOT_ASSIGN)
+#define setCannotAssign(cd) ((cd)->classflags |= CLASS_CANNOT_ASSIGN)
+#define classHandlesNone(cd) ((cd)->classflags & CLASS_ALLOW_NONE)
+#define setClassHandlesNone(cd) ((cd)->classflags |= CLASS_ALLOW_NONE)
+
+#define isPublicDtor(cd) ((cd)->classflags & SECT_IS_PUBLIC)
+#define setIsPublicDtor(cd) ((cd)->classflags |= SECT_IS_PUBLIC)
+#define isProtectedDtor(cd) ((cd)->classflags & SECT_IS_PROT)
+#define isPrivateDtor(cd) ((cd)->classflags & SECT_IS_PRIVATE)
+
+#define isDtor(cd) ((cd)->classflags & (SECT_IS_PUBLIC | SECT_IS_PROT | SECT_IS_PRIVATE))
+
+
+/* Handle ctor flags. These are combined with the section flags. */
+
+#define CTOR_RELEASE_GIL 0x00000100 /* The ctor releases the GIL. */
+#define CTOR_EXPLICIT 0x00000200 /* The ctor is explicit. */
+#define CTOR_CAST 0x00000400 /* The ctor is a cast. */
+#define CTOR_HOLD_GIL 0x00000800 /* The ctor holds the GIL. */
+#define CTOR_XFERRED 0x00001000 /* Ownership is transferred. */
+#define CTOR_IS_DEPRECATED 0x00002000 /* The ctor is deprecated. */
+#define CTOR_KEYWORD_ARGS 0x00004000 /* The ctor allows keyword arguments. */
+
+#define isPublicCtor(c) ((c)->ctorflags & SECT_IS_PUBLIC)
+#define setIsPublicCtor(c) ((c)->ctorflags |= SECT_IS_PUBLIC)
+#define isProtectedCtor(c) ((c)->ctorflags & SECT_IS_PROT)
+#define setIsProtectedCtor(c) ((c)->ctorflags |= SECT_IS_PROT)
+#define isPrivateCtor(c) ((c)->ctorflags & SECT_IS_PRIVATE)
+#define setIsPrivateCtor(c) ((c)->ctorflags |= SECT_IS_PRIVATE)
+
+#define isReleaseGILCtor(c) ((c)->ctorflags & CTOR_RELEASE_GIL)
+#define setIsReleaseGILCtor(c) ((c)->ctorflags |= CTOR_RELEASE_GIL)
+#define isExplicitCtor(c) ((c)->ctorflags & CTOR_EXPLICIT)
+#define setIsExplicitCtor(c) ((c)->ctorflags |= CTOR_EXPLICIT)
+#define isCastCtor(c) ((c)->ctorflags & CTOR_CAST)
+#define isHoldGILCtor(c) ((c)->ctorflags & CTOR_HOLD_GIL)
+#define setIsHoldGILCtor(c) ((c)->ctorflags |= CTOR_HOLD_GIL)
+#define isResultTransferredCtor(c) ((c)->ctorflags & CTOR_XFERRED)
+#define setIsResultTransferredCtor(c) ((c)->ctorflags |= CTOR_XFERRED)
+#define isDeprecatedCtor(c) ((c)->ctorflags & CTOR_IS_DEPRECATED)
+#define setIsDeprecatedCtor(c) ((c)->ctorflags |= CTOR_IS_DEPRECATED)
+#define useKeywordArgsCtor(c) ((c)->ctorflags & CTOR_KEYWORD_ARGS)
+#define setUseKeywordArgsCtor(c) ((c)->ctorflags |= CTOR_KEYWORD_ARGS)
+
+
+/* Handle member flags. */
+
+#define MEMBR_NUMERIC 0x0001 /* It is a numeric slot. */
+#define MEMBR_NO_ARG_PARSER 0x0002 /* Don't generate an argument parser. */
+#define MEMBR_NOT_VERSIONED 0x0004 /* There is an unversioned overload. */
+#define MEMBR_KEYWORD_ARGS 0x0008 /* It allows keyword arguments. */
+
+#define isNumeric(m) ((m)->memberflags & MEMBR_NUMERIC)
+#define setIsNumeric(m) ((m)->memberflags |= MEMBR_NUMERIC)
+#define noArgParser(m) ((m)->memberflags & MEMBR_NO_ARG_PARSER)
+#define setNoArgParser(m) ((m)->memberflags |= MEMBR_NO_ARG_PARSER)
+#define notVersioned(m) ((m)->memberflags & MEMBR_NOT_VERSIONED)
+#define setNotVersioned(m) ((m)->memberflags |= MEMBR_NOT_VERSIONED)
+#define useKeywordArgsFunction(m) ((m)->memberflags & MEMBR_KEYWORD_ARGS)
+#define setUseKeywordArgsFunction(m) ((m)->memberflags |= MEMBR_KEYWORD_ARGS)
+
+
+/* Handle enum flags. These are combined with the section flags. */
+
+#define ENUM_WAS_PROT 0x00000100 /* It was defined as protected. */
+
+#define isProtectedEnum(e) ((e)->enumflags & SECT_IS_PROT)
+#define setIsProtectedEnum(e) ((e)->enumflags |= SECT_IS_PROT)
+#define resetIsProtectedEnum(e) ((e)->enumflags &= ~SECT_IS_PROT)
+
+#define wasProtectedEnum(e) ((e)->enumflags & ENUM_WAS_PROT)
+#define setWasProtectedEnum(e) ((e)->enumflags |= ENUM_WAS_PROT)
+#define resetWasProtectedEnum(e) ((e)->enumflags &= ~ENUM_WAS_PROT)
+
+
+/* Handle hierarchy flags. */
+
+#define HIER_IS_DUPLICATE 0x0001 /* It is a super class duplicate. */
+#define HIER_HAS_DUPLICATE 0x0002 /* It has a super class duplicate. */
+#define HIER_BEING_SET 0x0004 /* The MRO is being set. */
+
+#define isDuplicateSuper(m) ((m)->mroflags & HIER_IS_DUPLICATE)
+#define setIsDuplicateSuper(m) ((m)->mroflags |= HIER_IS_DUPLICATE)
+#define hasDuplicateSuper(m) ((m)->mroflags & HIER_HAS_DUPLICATE)
+#define setHasDuplicateSuper(m) ((m)->mroflags |= HIER_HAS_DUPLICATE)
+#define hierBeingSet(m) ((m)->mroflags & HIER_BEING_SET)
+#define setHierBeingSet(m) ((m)->mroflags |= HIER_BEING_SET)
+#define resetHierBeingSet(m) ((m)->mroflags &= ~HIER_BEING_SET)
+
+
+/* Handle overload flags. These are combined with the section flags. */
+
+#define OVER_IS_VIRTUAL 0x00000100 /* It is virtual. */
+#define OVER_IS_ABSTRACT 0x00000200 /* It is abstract. */
+#define OVER_IS_CONST 0x00000400 /* It is a const function. */
+#define OVER_IS_STATIC 0x00000800 /* It is a static function. */
+#define OVER_IS_AUTOGEN 0x00001000 /* It is auto-generated. */
+#define OVER_IS_NEW_THREAD 0x00002000 /* It is in a new thread. */
+#define OVER_IS_FACTORY 0x00004000 /* It is a factory method. */
+#define OVER_XFERRED_BACK 0x00008000 /* Ownership is transferred back. */
+#define OVER_XFERRED 0x00010000 /* Ownership is transferred. */
+#define OVER_IS_VIRTUAL_REIMP 0x00020000 /* It is a re-implementation of a virtual. */
+#define OVER_DONT_DEREF_SELF 0x00040000 /* For comparison operators, don't dereference self. */
+#define OVER_HOLD_GIL 0x00080000 /* The function holds the GIL. */
+#define OVER_RELEASE_GIL 0x00100000 /* The function releases the GIL. */
+#define OVER_THIS_XFERRED 0x00200000 /* Ownership of this is transferred. */
+#define OVER_IS_GLOBAL 0x00400000 /* It is a global operator. */
+#define OVER_IS_COMPLEMENTARY 0x00800000 /* It is a complementary operator. */
+#define OVER_IS_DEPRECATED 0x01000000 /* It is deprecated. */
+#define OVER_KEYWORD_ARGS 0x02000000 /* It allows keyword arguments. */
+#define OVER_REALLY_PROT 0x04000000 /* It really is protected. */
+
+#define isPublic(o) ((o)->overflags & SECT_IS_PUBLIC)
+#define setIsPublic(o) ((o)->overflags |= SECT_IS_PUBLIC)
+#define isProtected(o) ((o)->overflags & SECT_IS_PROT)
+#define setIsProtected(o) ((o)->overflags |= SECT_IS_PROT)
+#define isPrivate(o) ((o)->overflags & SECT_IS_PRIVATE)
+#define setIsPrivate(o) ((o)->overflags |= SECT_IS_PRIVATE)
+#define isSlot(o) ((o)->overflags & SECT_IS_SLOT)
+#define setIsSlot(o) ((o)->overflags |= SECT_IS_SLOT)
+#define resetIsSlot(o) ((o)->overflags &= ~SECT_IS_SLOT)
+#define isSignal(o) ((o)->overflags & SECT_IS_SIGNAL)
+#define setIsSignal(o) ((o)->overflags |= SECT_IS_SIGNAL)
+#define resetIsSignal(o) ((o)->overflags &= ~SECT_IS_SIGNAL)
+
+#define isVirtual(o) ((o)->overflags & OVER_IS_VIRTUAL)
+#define setIsVirtual(o) ((o)->overflags |= OVER_IS_VIRTUAL)
+#define resetIsVirtual(o) ((o)->overflags &= ~OVER_IS_VIRTUAL)
+#define isAbstract(o) ((o)->overflags & OVER_IS_ABSTRACT)
+#define setIsAbstract(o) ((o)->overflags |= OVER_IS_ABSTRACT)
+#define isConst(o) ((o)->overflags & OVER_IS_CONST)
+#define setIsConst(o) ((o)->overflags |= OVER_IS_CONST)
+#define isStatic(o) ((o)->overflags & OVER_IS_STATIC)
+#define setIsStatic(o) ((o)->overflags |= OVER_IS_STATIC)
+#define isAutoGen(o) ((o)->overflags & OVER_IS_AUTOGEN)
+#define setIsAutoGen(o) ((o)->overflags |= OVER_IS_AUTOGEN)
+#define resetIsAutoGen(o) ((o)->overflags &= ~OVER_IS_AUTOGEN)
+#define isNewThread(o) ((o)->overflags & OVER_IS_NEW_THREAD)
+#define setIsNewThread(o) ((o)->overflags |= OVER_IS_NEW_THREAD)
+#define isFactory(o) ((o)->overflags & OVER_IS_FACTORY)
+#define setIsFactory(o) ((o)->overflags |= OVER_IS_FACTORY)
+#define isResultTransferredBack(o) ((o)->overflags & OVER_XFERRED_BACK)
+#define setIsResultTransferredBack(o) ((o)->overflags |= OVER_XFERRED_BACK)
+#define isResultTransferred(o) ((o)->overflags & OVER_XFERRED)
+#define setIsResultTransferred(o) ((o)->overflags |= OVER_XFERRED)
+#define isVirtualReimp(o) ((o)->overflags & OVER_IS_VIRTUAL_REIMP)
+#define setIsVirtualReimp(o) ((o)->overflags |= OVER_IS_VIRTUAL_REIMP)
+#define dontDerefSelf(o) ((o)->overflags & OVER_DONT_DEREF_SELF)
+#define setDontDerefSelf(o) ((o)->overflags |= OVER_DONT_DEREF_SELF)
+#define isHoldGIL(o) ((o)->overflags & OVER_HOLD_GIL)
+#define setIsHoldGIL(o) ((o)->overflags |= OVER_HOLD_GIL)
+#define isReleaseGIL(o) ((o)->overflags & OVER_RELEASE_GIL)
+#define setIsReleaseGIL(o) ((o)->overflags |= OVER_RELEASE_GIL)
+#define isThisTransferredMeth(o) ((o)->overflags & OVER_THIS_XFERRED)
+#define setIsThisTransferredMeth(o) ((o)->overflags |= OVER_THIS_XFERRED)
+#define isGlobal(o) ((o)->overflags & OVER_IS_GLOBAL)
+#define setIsGlobal(o) ((o)->overflags |= OVER_IS_GLOBAL)
+#define isComplementary(o) ((o)->overflags & OVER_IS_COMPLEMENTARY)
+#define setIsComplementary(o) ((o)->overflags |= OVER_IS_COMPLEMENTARY)
+#define isDeprecated(o) ((o)->overflags & OVER_IS_DEPRECATED)
+#define setIsDeprecated(o) ((o)->overflags |= OVER_IS_DEPRECATED)
+#define useKeywordArgs(o) ((o)->overflags & OVER_KEYWORD_ARGS)
+#define setUseKeywordArgs(o) ((o)->overflags |= OVER_KEYWORD_ARGS)
+#define isReallyProtected(o) ((o)->overflags & OVER_REALLY_PROT)
+#define setIsReallyProtected(o) ((o)->overflags |= OVER_REALLY_PROT)
+
+
+/* Handle variable flags. */
+
+#define VAR_IS_STATIC 0x01 /* It is a static variable. */
+#define VAR_NEEDS_HANDLER 0x02 /* It the variable needs a handler. */
+
+#define isStaticVar(v) ((v)->varflags & VAR_IS_STATIC)
+#define setIsStaticVar(v) ((v)->varflags |= VAR_IS_STATIC)
+#define needsHandler(v) ((v)->varflags & VAR_NEEDS_HANDLER)
+#define setNeedsHandler(v) ((v)->varflags |= VAR_NEEDS_HANDLER)
+
+
+/* Handle argument flags. */
+
+#define ARG_IS_REF 0x0001 /* It is a reference. */
+#define ARG_IS_CONST 0x0002 /* It is a const. */
+#define ARG_XFERRED 0x0004 /* Ownership is transferred. */
+#define ARG_THIS_XFERRED 0x0008 /* Ownership of this is transferred. */
+#define ARG_XFERRED_BACK 0x0010 /* Ownership is transferred back. */
+#define ARG_ARRAY 0x0020 /* Used as an array. */
+#define ARG_ARRAY_SIZE 0x0040 /* Used as an array size. */
+#define ARG_ALLOW_NONE 0x0080 /* Allow None as a value. */
+#define ARG_GET_WRAPPER 0x0100 /* Get the wrapper object. */
+#define ARG_IN 0x0200 /* It passes an argument. */
+#define ARG_OUT 0x0400 /* It returns a result. */
+#define ARG_CONSTRAINED 0x0800 /* Suppress type conversion. */
+#define ARG_SINGLE_SHOT 0x1000 /* The slot is only ever fired once. */
+#define ARG_RESULT_SIZE 0x2000 /* It defines the result size. */
+#define ARG_KEEP_REF 0x4000 /* Keep a reference. */
+#define ARG_NO_COPY 0x8000 /* Disable copying of const references. */
+
+#define isReference(a) ((a)->argflags & ARG_IS_REF)
+#define setIsReference(a) ((a)->argflags |= ARG_IS_REF)
+#define resetIsReference(a) ((a)->argflags &= ~ARG_IS_REF)
+#define isConstArg(a) ((a)->argflags & ARG_IS_CONST)
+#define setIsConstArg(a) ((a)->argflags |= ARG_IS_CONST)
+#define resetIsConstArg(a) ((a)->argflags &= ~ARG_IS_CONST)
+#define isTransferred(a) ((a)->argflags & ARG_XFERRED)
+#define setIsTransferred(a) ((a)->argflags |= ARG_XFERRED)
+#define isThisTransferred(a) ((a)->argflags & ARG_THIS_XFERRED)
+#define setIsThisTransferred(a) ((a)->argflags |= ARG_THIS_XFERRED)
+#define isTransferredBack(a) ((a)->argflags & ARG_XFERRED_BACK)
+#define setIsTransferredBack(a) ((a)->argflags |= ARG_XFERRED_BACK)
+#define isArray(a) ((a)->argflags & ARG_ARRAY)
+#define setArray(a) ((a)->argflags |= ARG_ARRAY)
+#define isArraySize(a) ((a)->argflags & ARG_ARRAY_SIZE)
+#define setArraySize(a) ((a)->argflags |= ARG_ARRAY_SIZE)
+#define isAllowNone(a) ((a)->argflags & ARG_ALLOW_NONE)
+#define setAllowNone(a) ((a)->argflags |= ARG_ALLOW_NONE)
+#define isGetWrapper(a) ((a)->argflags & ARG_GET_WRAPPER)
+#define setGetWrapper(a) ((a)->argflags |= ARG_GET_WRAPPER)
+#define isInArg(a) ((a)->argflags & ARG_IN)
+#define setIsInArg(a) ((a)->argflags |= ARG_IN)
+#define isOutArg(a) ((a)->argflags & ARG_OUT)
+#define setIsOutArg(a) ((a)->argflags |= ARG_OUT)
+#define isConstrained(a) ((a)->argflags & ARG_CONSTRAINED)
+#define setIsConstrained(a) ((a)->argflags |= ARG_CONSTRAINED)
+#define resetIsConstrained(a) ((a)->argflags &= ~ARG_CONSTRAINED)
+#define isSingleShot(a) ((a)->argflags & ARG_SINGLE_SHOT)
+#define isResultSize(a) ((a)->argflags & ARG_RESULT_SIZE)
+#define setResultSize(a) ((a)->argflags |= ARG_RESULT_SIZE)
+#define keepReference(a) ((a)->argflags & ARG_KEEP_REF)
+#define setKeepReference(a) ((a)->argflags |= ARG_KEEP_REF)
+#define noCopy(a) ((a)->argflags & ARG_NO_COPY)
+#define setNoCopy(a) ((a)->argflags |= ARG_NO_COPY)
+
+
+/* Handle name flags. */
+
+#define NAME_IS_USED 0x01 /* It is used in the main module. */
+#define NAME_IS_SUBSTR 0x02 /* It is a substring of another. */
+
+#define isUsedName(n) ((n)->nameflags & NAME_IS_USED)
+#define setIsUsedName(n) ((n)->nameflags |= NAME_IS_USED)
+#define resetIsUsedName(n) ((n)->nameflags &= ~NAME_IS_USED)
+#define isSubstring(n) ((n)->nameflags & NAME_IS_SUBSTR)
+#define setIsSubstring(n) ((n)->nameflags |= NAME_IS_SUBSTR)
+
+
+/* Handle virtual handler flags. */
+
+#define VH_IS_DUPLICATE 0x01 /* It is a duplicate. */
+#define VH_TRANSFERS 0x02 /* It transfers ownership of the result. */
+
+#define isDuplicateVH(vh) ((vh)->vhflags & VH_IS_DUPLICATE)
+#define setIsDuplicateVH(vh) ((vh)->vhflags |= VH_IS_DUPLICATE)
+#define resetIsDuplicateVH(vh) ((vh)->vhflags &= ~VH_IS_DUPLICATE)
+#define isTransferVH(vh) ((vh)->vhflags & VH_TRANSFERS)
+#define setIsTransferVH(vh) ((vh)->vhflags |= VH_TRANSFERS)
+
+
+/* Handle mapped type flags. */
+
+#define MT_NO_RELEASE 0x01 /* Do not generate a release function. */
+#define MT_ALLOW_NONE 0x02 /* The mapped type will handle None. */
+
+#define noRelease(mt) ((mt)->mtflags & MT_NO_RELEASE)
+#define setNoRelease(mt) ((mt)->mtflags |= MT_NO_RELEASE)
+#define handlesNone(mt) ((mt)->mtflags & MT_ALLOW_NONE)
+#define setHandlesNone(mt) ((mt)->mtflags |= MT_ALLOW_NONE)
+
+
+/* Handle typedef flags. */
+
+#define TD_NO_TYPE_NAME 0x01 /* Do not use the typedef name. */
+
+#define noTypeName(td) ((td)->tdflags & TD_NO_TYPE_NAME)
+#define setNoTypeName(td) ((td)->tdflags |= TD_NO_TYPE_NAME)
+
+
+/* Slot types. */
+
+typedef enum {
+ str_slot,
+ unicode_slot,
+ int_slot,
+ long_slot,
+ float_slot,
+ len_slot,
+ contains_slot,
+ add_slot,
+ concat_slot,
+ sub_slot,
+ mul_slot,
+ repeat_slot,
+ div_slot,
+ mod_slot,
+ floordiv_slot,
+ truediv_slot,
+ and_slot,
+ or_slot,
+ xor_slot,
+ lshift_slot,
+ rshift_slot,
+ iadd_slot,
+ iconcat_slot,
+ isub_slot,
+ imul_slot,
+ irepeat_slot,
+ idiv_slot,
+ imod_slot,
+ ifloordiv_slot,
+ itruediv_slot,
+ iand_slot,
+ ior_slot,
+ ixor_slot,
+ ilshift_slot,
+ irshift_slot,
+ invert_slot,
+ call_slot,
+ getitem_slot,
+ setitem_slot,
+ delitem_slot,
+ lt_slot,
+ le_slot,
+ eq_slot,
+ ne_slot,
+ gt_slot,
+ ge_slot,
+ cmp_slot,
+ bool_slot,
+ neg_slot,
+ pos_slot,
+ abs_slot,
+ repr_slot,
+ hash_slot,
+ index_slot,
+ iter_slot,
+ next_slot,
+ no_slot
+} slotType;
+
+
+/*
+ * Argument types. Always add new ones at the end because the numeric values
+ * can appear in generated code.
+ */
+typedef enum {
+ no_type,
+ defined_type,
+ class_type,
+ struct_type,
+ void_type,
+ enum_type,
+ template_type,
+ signal_type,
+ slot_type,
+ rxcon_type,
+ rxdis_type,
+ slotcon_type,
+ slotdis_type,
+ ustring_type,
+ string_type,
+ short_type,
+ ushort_type,
+ cint_type,
+ int_type,
+ uint_type,
+ long_type,
+ ulong_type,
+ float_type,
+ cfloat_type,
+ double_type,
+ cdouble_type,
+ bool_type,
+ mapped_type,
+ pyobject_type,
+ pytuple_type,
+ pylist_type,
+ pydict_type,
+ pycallable_type,
+ pyslice_type,
+ qobject_type,
+ function_type,
+ pytype_type,
+ ellipsis_type,
+ longlong_type,
+ ulonglong_type,
+ anyslot_type,
+ cbool_type,
+ sstring_type,
+ wstring_type,
+ fake_void_type,
+ ssize_type,
+ ascii_string_type,
+ latin1_string_type,
+ utf8_string_type
+} argType;
+
+
+/* Value types. */
+
+typedef enum {
+ qchar_value,
+ string_value,
+ numeric_value,
+ real_value,
+ scoped_value,
+ fcall_value
+} valueType;
+
+
+/* Version types. */
+
+typedef enum {
+ time_qualifier,
+ platform_qualifier,
+ feature_qualifier
+} qualType;
+
+
+/* Interface file types. */
+
+typedef enum {
+ exception_iface,
+ mappedtype_iface,
+ namespace_iface,
+ class_iface
+} ifaceFileType;
+
+
+/* A software license. */
+
+typedef struct {
+ char *type; /* The license type. */
+ char *licensee; /* The licensee. */
+ char *timestamp; /* The timestamp. */
+ char *sig; /* The signature. */
+} licenseDef;
+
+
+/* A version qualifier. */
+
+typedef struct _qualDef {
+ char *name; /* The qualifier name. */
+ qualType qtype; /* The qualifier type. */
+ struct _moduleDef *module; /* The defining module. */
+ int line; /* Timeline if it is a time. */
+ int order; /* Order if it is a time. */
+ struct _qualDef *next; /* Next in the list. */
+} qualDef;
+
+
+/* A scoped name. */
+
+typedef struct _scopedNameDef {
+ char *name; /* The name. */
+ struct _scopedNameDef *next; /* Next in the scope list. */
+} scopedNameDef;
+
+
+/* A name. */
+
+typedef struct _nameDef {
+ int nameflags; /* The name flags. */
+ const char *text; /* The text of the name. */
+ size_t len; /* The length of the name. */
+ size_t offset; /* The offset in the string pool. */
+ struct _nameDef *next; /* Next in the list. */
+} nameDef;
+
+
+/* A literal code block. */
+
+typedef struct _codeBlock {
+ char *frag; /* The code itself. */
+ const char *filename; /* The original file. */
+ int linenr; /* The line in the file. */
+ struct _codeBlock *next; /* Next in the list. */
+} codeBlock;
+
+
+/* The arguments to a throw specifier. */
+
+typedef struct _throwArgs {
+ int nrArgs; /* The number of arguments. */
+ struct _exceptionDef *args[MAX_NR_ARGS]; /* The arguments. */
+} throwArgs;
+
+
+/* An exception. */
+
+typedef struct _exceptionDef {
+ int exceptionnr; /* The exception number. */
+ struct _ifaceFileDef *iff; /* The interface file. */
+ const char *pyname; /* The exception Python name. */
+ struct _classDef *cd; /* The exception class. */
+ char *bibase; /* The builtin base exception. */
+ struct _exceptionDef *base; /* The defined base exception. */
+ codeBlock *raisecode; /* Raise exception code. */
+ struct _exceptionDef *next; /* The next in the list. */
+} exceptionDef;
+
+
+/* A value. */
+
+typedef struct _valueDef {
+ valueType vtype; /* The type. */
+ char vunop; /* Any unary operator. */
+ char vbinop; /* Any binary operator. */
+ union {
+ char vqchar; /* Quoted character value. */
+ long vnum; /* Numeric value. */
+ double vreal; /* Real value. */
+ char *vstr; /* String value. */
+ scopedNameDef *vscp; /* Scoped value. */
+ struct _fcallDef *fcd; /* Function call. */
+ } u;
+ struct _valueDef *next; /* Next in the expression. */
+} valueDef;
+
+
+/* A member function argument (or result). */
+
+typedef struct {
+ argType atype; /* The type. */
+ nameDef *name; /* The name. */
+ const char *doctype; /* The documented type. */
+ int argflags; /* The argument flags. */
+ int nrderefs; /* Nr. of dereferences. */
+ valueDef *defval; /* The default value. */
+ const char *docval; /* The documented value. */
+ int key; /* The optional /KeepReference/ key. */
+ struct _typedefDef *original_type; /* The original type if typedef'd. */
+ union {
+ struct _signatureDef *sa; /* If it is a function. */
+ struct _templateDef *td; /* If it is a template. */
+ struct _scopedNameDef *snd; /* If it is a defined type. */
+ struct _classDef *cd; /* If it is a class. */
+ struct _enumDef *ed; /* If it is an enum. */
+ struct _scopedNameDef *sname; /* If it is a struct. */
+ struct _mappedTypeDef *mtd; /* If it is a mapped type. */
+ } u;
+} argDef;
+
+
+
+/* An entry in a linked argument list. */
+typedef struct _argList {
+ argDef arg; /* The argument itself. */
+ struct _argList *next; /* Next in the list. */
+} argList;
+
+
+/* A function call. */
+
+typedef struct _fcallDef {
+ argDef type; /* The type. */
+ int nrArgs; /* The number of arguments. */
+ struct _valueDef *args[MAX_NR_ARGS]; /* The arguments. */
+} fcallDef;
+
+
+/* An API version range definition. */
+typedef struct _apiVersionRangeDef {
+ nameDef *api_name; /* The API name. */
+ int from; /* The lower bound. */
+ int to; /* The upper bound. */
+ int index; /* The range index. */
+ struct _apiVersionRangeDef *next; /* The next in the list. */
+} apiVersionRangeDef;
+
+
+/* A module definition. */
+typedef struct _moduleDef {
+ nameDef *fullname; /* The full module name. */
+ const char *name; /* The module base name. */
+ int version; /* The module version. */
+ apiVersionRangeDef *api_versions; /* The defined APIs. */
+ apiVersionRangeDef *api_ranges; /* The list of API version ranges. */
+ int modflags; /* The module flags. */
+ int qobjclass; /* QObject class, -1 if none. */
+ struct _memberDef *othfuncs; /* List of other functions. */
+ struct _overDef *overs; /* Global overloads. */
+ argType encoding; /* The default string encoding. */
+ nameDef *defmetatype; /* The optional default meta-type. */
+ nameDef *defsupertype; /* The optional default super-type. */
+ struct _exceptionDef *defexception; /* The default exception. */
+ codeBlock *hdrcode; /* Header code. */
+ codeBlock *cppcode; /* Global C++ code. */
+ codeBlock *copying; /* Software license. */
+ codeBlock *preinitcode; /* Pre-initialisation code. */
+ codeBlock *initcode; /* Initialisation code. */
+ codeBlock *postinitcode; /* Post-initialisation code. */
+ codeBlock *unitcode; /* Compilation unit code. */
+ int parts; /* The number of parts generated. */
+ char *file; /* The filename. */
+ qualDef *qualifiers; /* The list of qualifiers. */
+ argDef *types; /* The array of numbered types. */
+ int nrtypes; /* The number of numbered types. */
+ int nrtimelines; /* The nr. of timelines. */
+ int nrexceptions; /* The nr. of exceptions. */
+ int nrtypedefs; /* The nr. of typedefs. */
+ int nrvirthandlers; /* The nr. of virtual handlers. */
+ int next_key; /* The next key to allocate. */
+ struct _virtHandlerDef *virthandlers; /* The virtual handlers. */
+ licenseDef *license; /* The software license. */
+ struct _classDef *proxies; /* The list of proxy classes. */
+ struct _moduleDef *container; /* The container module, if any. */
+ struct _ifaceFileList *used; /* Interface files used. */
+ struct _moduleListDef *allimports; /* The list of all imports. */
+ struct _moduleListDef *imports; /* The list of direct imports. */
+ struct _moduleDef *next; /* Next in the list. */
+} moduleDef;
+
+
+/* An entry in a linked module list. */
+typedef struct _moduleListDef {
+ moduleDef *module; /* The module itself. */
+ struct _moduleListDef *next; /* The next in the list. */
+} moduleListDef;
+
+
+/* An interface file definition. */
+
+typedef struct _ifaceFileDef {
+ nameDef *name; /* The name. */
+ apiVersionRangeDef *api_range; /* The optional API version range. */
+ struct _ifaceFileDef *first_alt; /* The first alternate API. */
+ struct _ifaceFileDef *next_alt; /* The next alternate API. */
+ ifaceFileType type; /* Interface file type. */
+ int ifacenr; /* The index into the types table. */
+ scopedNameDef *fqcname; /* The fully qualified C++ name. */
+ moduleDef *module; /* The owning module. */
+ codeBlock *hdrcode; /* Header code. */
+ struct _ifaceFileList *used; /* Interface files used. */
+ struct _ifaceFileDef *next; /* Next in the list. */
+} ifaceFileDef;
+
+
+/* An entry in a linked interface file list. */
+
+typedef struct _ifaceFileList {
+ ifaceFileDef *iff; /* The interface file itself. */
+ struct _ifaceFileList *next; /* Next in the list. */
+} ifaceFileList;
+
+
+/* A mapped type. */
+
+typedef struct _mappedTypeDef {
+ int mtflags; /* The mapped type flags. */
+ argDef type; /* The type being mapped. */
+ nameDef *pyname; /* The Python name. */
+ nameDef *cname; /* The C/C++ name. */
+ const char *doctype; /* The documented type. */
+ ifaceFileDef *iff; /* The interface file. */
+ struct _memberDef *members; /* The static member functions. */
+ struct _overDef *overs; /* The static overloads. */
+ codeBlock *convfromcode; /* Convert from C++ code. */
+ codeBlock *convtocode; /* Convert to C++ code. */
+ struct _mappedTypeDef *next; /* Next in the list. */
+} mappedTypeDef;
+
+
+/* A function signature. */
+
+typedef struct _signatureDef {
+ argDef result; /* The result. */
+ int nrArgs; /* The number of arguments. */
+ argDef args[MAX_NR_ARGS]; /* The arguments. */
+} signatureDef;
+
+
+/* A list of function signatures. */
+
+typedef struct _signatureList {
+ struct _signatureDef *sd; /* The signature. */
+ struct _signatureList *next; /* Next in the list. */
+} signatureList;
+
+
+/* A template type. */
+
+typedef struct _templateDef {
+ scopedNameDef *fqname; /* The name. */
+ signatureDef types; /* The types. */
+} templateDef;
+
+
+/* A list of virtual handlers. */
+
+typedef struct _virtHandlerDef {
+ int virthandlernr; /* The nr. of the virtual handler. */
+ int vhflags; /* The virtual handler flags. */
+ signatureDef *pysig; /* The Python signature. */
+ signatureDef *cppsig; /* The C++ signature. */
+ struct _moduleDef *module; /* The defining module. */
+ codeBlock *virtcode; /* Virtual handler code. */
+ struct _virtHandlerDef *next; /* Next in the list. */
+} virtHandlerDef;
+
+
+/* A typedef definition. */
+
+typedef struct _typedefDef {
+ int tdflags; /* The typedef flags. */
+ scopedNameDef *fqname; /* The fully qualified name. */
+ struct _classDef *ecd; /* The enclosing class. */
+ moduleDef *module; /* The owning module. */
+ argDef type; /* The actual type. */
+ struct _typedefDef *next; /* Next in the list. */
+} typedefDef;
+
+
+/* A variable definition. */
+
+typedef struct _varDef {
+ nameDef *pyname; /* The variable Python name. */
+ scopedNameDef *fqcname; /* The fully qualified C/C++ name. */
+ struct _classDef *ecd; /* The enclosing class. */
+ moduleDef *module; /* The owning module. */
+ int varflags; /* The variable flags. */
+ argDef type; /* The actual type. */
+ codeBlock *accessfunc; /* The access function. */
+ codeBlock *getcode; /* The get code. */
+ codeBlock *setcode; /* The set code. */
+ struct _varDef *next; /* Next in the list. */
+} varDef;
+
+
+/* An overloaded member function definition. */
+
+typedef struct _overDef {
+ char *cppname; /* The C++ name. */
+ int overflags; /* The overload flags. */
+ struct _memberDef *common; /* Common parts. */
+ apiVersionRangeDef *api_range; /* The optional API version range. */
+ signatureDef pysig; /* The Python signature. */
+ signatureDef *cppsig; /* The C++ signature. */
+ throwArgs *exceptions; /* The exceptions. */
+ codeBlock *methodcode; /* Method code. */
+ virtHandlerDef *virthandler; /* The virtual handler. */
+ char *prehook; /* The pre-hook name. */
+ char *posthook; /* The post-hook name. */
+ struct _overDef *next; /* Next in the list. */
+} overDef;
+
+
+/* An overloaded constructor definition. */
+
+typedef struct _ctorDef {
+ int ctorflags; /* The ctor flags. */
+ apiVersionRangeDef *api_range; /* The optional API version range. */
+ signatureDef pysig; /* The Python signature. */
+ signatureDef *cppsig; /* The C++ signature, NULL if /NoDerived/. */
+ throwArgs *exceptions; /* The exceptions. */
+ codeBlock *methodcode; /* Method code. */
+ char *prehook; /* The pre-hook name. */
+ char *posthook; /* The post-hook name. */
+ struct _ctorDef *next; /* Next in the list. */
+} ctorDef;
+
+
+/* An enumerated type member definition. */
+
+typedef struct _enumMemberDef {
+ nameDef *pyname; /* The Python name. */
+ char *cname; /* The C/C++ name. */
+ struct _enumDef *ed; /* The enclosing enum. */
+ struct _enumMemberDef *next; /* Next in the list. */
+} enumMemberDef;
+
+
+/* An enumerated type definition. */
+
+typedef struct _enumDef {
+ int enumflags; /* The enum flags. */
+ nameDef *pyname; /* The Python name (may be NULL). */
+ scopedNameDef *fqcname; /* The C/C++ name (may be NULL). */
+ nameDef *cname; /* The C/C++ name (may be NULL). */
+ struct _enumDef *first_alt; /* The first alternate API. */
+ struct _enumDef *next_alt; /* The next alternate API. */
+ int enumnr; /* The enum number. */
+ int enum_idx; /* The enum index within the module. */
+ struct _classDef *ecd; /* The enclosing class, if any. */
+ struct _mappedTypeDef *emtd; /* The enclosing mapped type, if any. */
+ moduleDef *module; /* The owning module. */
+ enumMemberDef *members; /* The list of members. */
+ struct _memberDef *slots; /* The list of slots. */
+ struct _overDef *overs; /* The list of slot overloads. */
+ struct _enumDef *next; /* Next in the list. */
+} enumDef;
+
+
+/* An member function definition. */
+
+typedef struct _memberDef {
+ nameDef *pyname; /* The Python name. */
+ int memberflags; /* The member flags. */
+ int membernr; /* The index in the method table. */
+ slotType slot; /* The slot type. */
+ moduleDef *module; /* The owning module. */
+ codeBlock *docstring; /* The overloads docstrings. */
+ struct _memberDef *next; /* Next in the list. */
+} memberDef;
+
+
+/* A list of visible member functions. */
+
+typedef struct _visibleList {
+ memberDef *m; /* The member definition. */
+ struct _classDef *cd; /* The class. */
+ struct _visibleList *next; /* Next in the list. */
+} visibleList;
+
+
+/* An entry in a linked class list. */
+
+typedef struct _classList {
+ struct _classDef *cd; /* The class itself. */
+ struct _classList *next; /* Next in the list. */
+} classList;
+
+
+/* A virtual overload definition. */
+
+typedef struct _virtOverDef {
+ overDef o; /* The overload. */
+ struct _classDef *scope; /* The overload scope. */
+ struct _virtOverDef *next; /* Next in the list. */
+} virtOverDef;
+
+
+/* A class that appears in a class's hierarchy. */
+
+typedef struct _mroDef {
+ struct _classDef *cd; /* The class. */
+ int mroflags; /* The hierarchy flags. */
+ struct _mroDef *next; /* The next in the list. */
+} mroDef;
+
+
+/* A class definition. */
+
+typedef struct _classDef {
+ int classflags; /* The class flags. */
+ int pyqt4_flags; /* The PyQt4 specific flags. */
+ nameDef *pyname; /* The Python name. */
+ ifaceFileDef *iff; /* The interface file. */
+ struct _classDef *ecd; /* The enclosing scope. */
+ struct _classDef *real; /* The real class if this is a proxy or extender. */
+ classList *supers; /* The parent classes. */
+ mroDef *mro; /* The super-class hierarchy. */
+ nameDef *metatype; /* The meta-type. */
+ nameDef *supertype; /* The super-type. */
+ templateDef *td; /* The instantiated template. */
+ ctorDef *ctors; /* The constructors. */
+ ctorDef *defctor; /* The default ctor. */
+ codeBlock *dealloccode; /* Handwritten dealloc code. */
+ codeBlock *dtorcode; /* Handwritten dtor code. */
+ throwArgs *dtorexceptions; /* The dtor exceptions. */
+ memberDef *members; /* The member functions. */
+ overDef *overs; /* The overloads. */
+ argList *casts; /* The operator casts. */
+ virtOverDef *vmembers; /* The virtual members. */
+ visibleList *visible; /* The visible members. */
+ codeBlock *cppcode; /* Class C++ code. */
+ codeBlock *convtosubcode; /* Convert to sub C++ code. */
+ struct _classDef *subbase; /* Sub-class base class. */
+ codeBlock *docstring; /* Ctor docstrings. */
+ codeBlock *convtocode; /* Convert to C++ code. */
+ codeBlock *travcode; /* Traverse code. */
+ codeBlock *clearcode; /* Clear code. */
+ codeBlock *getbufcode; /* Get buffer code (Python v3). */
+ codeBlock *releasebufcode; /* Release buffer code (Python v3). */
+ codeBlock *readbufcode; /* Read buffer code (Python v2). */
+ codeBlock *writebufcode; /* Write buffer code (Python v2). */
+ codeBlock *segcountcode; /* Segment count code (Python v2). */
+ codeBlock *charbufcode; /* Character buffer code (Python v2). */
+ codeBlock *picklecode; /* Pickle code. */
+ struct _classDef *next; /* Next in the list. */
+} classDef;
+
+
+/* A class template definition. */
+
+typedef struct _classTmplDef {
+ signatureDef sig; /* The template arguments. */
+ classDef *cd; /* The class itself. */
+ struct _classTmplDef *next; /* The next in the list. */
+} classTmplDef;
+
+
+/* A mapped type template definition. */
+
+typedef struct _mappedTypeTmplDef {
+ signatureDef sig; /* The template arguments. */
+ mappedTypeDef *mt; /* The mapped type itself. */
+ struct _mappedTypeTmplDef *next; /* The next in the list. */
+} mappedTypeTmplDef;
+
+
+/* The parse tree corresponding to the specification file. */
+
+typedef struct {
+ moduleDef *module; /* The module being generated. */
+ moduleDef *modules; /* The list of modules. */
+ nameDef *namecache; /* The name cache. */
+ ifaceFileDef *ifacefiles; /* The list of interface files. */
+ classDef *classes; /* The list of classes. */
+ classTmplDef *classtemplates; /* The list of class templates. */
+ exceptionDef *exceptions; /* The list of exceptions. */
+ mappedTypeDef *mappedtypes; /* The mapped types. */
+ mappedTypeTmplDef *mappedtypetemplates; /* The list of mapped type templates. */
+ enumDef *enums; /* List of enums. */
+ varDef *vars; /* List of variables. */
+ typedefDef *typedefs; /* List of typedefs. */
+ codeBlock *exphdrcode; /* Exported header code. */
+ codeBlock *docs; /* Documentation. */
+ int sigslots; /* Set if signals or slots are used. */
+ int genc; /* Set if we are generating C code. */
+ struct _stringList *plugins; /* The list of plugins. */
+} sipSpec;
+
+
+/* A list of strings. */
+
+typedef struct _stringList {
+ const char *s; /* The string. */
+ struct _stringList *next; /* The next in the list. */
+} stringList;
+
+
+/* File specific context information for the parser. */
+
+typedef struct _parserContext {
+ const char *filename; /* The %Import or %Include filename. */
+ int ifdepth; /* The depth of nested if's. */
+ moduleDef *prevmod; /* The previous module. */
+} parserContext;
+
+
+extern char *sipVersion; /* The version of SIP. */
+extern stringList *includeDirList; /* The include directory list for SIP files. */
+
+
+void parse(sipSpec *, FILE *, char *, stringList *, stringList *, int, int);
+void parserEOF(char *,parserContext *);
+void transform(sipSpec *);
+void generateCode(sipSpec *, char *, char *, char *, const char *, int, int,
+ int, int, stringList *, const char *, int);
+void generateAPI(sipSpec *pt, moduleDef *mod, const char *apiFile);
+void generateXML(sipSpec *pt, moduleDef *mod, const char *xmlFile);
+void generateExpression(valueDef *vd, int in_str, FILE *fp);
+void warning(char *,...);
+void fatal(char *,...);
+void fatalScopedName(scopedNameDef *);
+int setInputFile(FILE *open_fp, parserContext *pc, int optional);
+void *sipMalloc(size_t n);
+void *sipCalloc(size_t nr, size_t n);
+char *sipStrdup(const char *);
+char *concat(const char *, ...);
+void append(char **, const char *);
+void addToUsedList(ifaceFileList **, ifaceFileDef *);
+int excludedFeature(stringList *,qualDef *);
+int sameSignature(signatureDef *,signatureDef *,int);
+int sameTemplateSignature(signatureDef *tmpl_sd, signatureDef *args_sd,
+ int deep);
+int compareScopedNames(scopedNameDef *snd1, scopedNameDef *snd2);
+int sameBaseType(argDef *,argDef *);
+char *scopedNameTail(scopedNameDef *);
+scopedNameDef *copyScopedName(scopedNameDef *);
+void appendScopedName(scopedNameDef **,scopedNameDef *);
+void freeScopedName(scopedNameDef *);
+void appendToClassList(classList **,classDef *);
+void appendCodeBlock(codeBlock **headp, codeBlock *new);
+void prcode(FILE *fp, const char *fmt, ...);
+void prOverloadName(FILE *fp, overDef *od);
+void prOverloadDecl(FILE *fp, ifaceFileDef *scope, overDef *od, int defval);
+void prScopedPythonName(FILE *fp, classDef *scope, const char *pyname);
+int prPythonSignature(sipSpec *pt, FILE *fp, signatureDef *sd, int sec,
+ int names, int defaults, int in_str, int is_signal);
+void searchTypedefs(sipSpec *pt, scopedNameDef *snd, argDef *ad);
+int isIntReturnSlot(memberDef *md);
+int isSSizeReturnSlot(memberDef *md);
+int isLongReturnSlot(memberDef *md);
+int isVoidReturnSlot(memberDef *md);
+int isNumberSlot(memberDef *md);
+int isRichCompareSlot(memberDef *md);
+mappedTypeDef *allocMappedType(sipSpec *pt, argDef *type);
+void appendString(stringList **headp, const char *s);
+void appendTypeStrings(scopedNameDef *ename, signatureDef *patt, signatureDef *src, signatureDef *known, scopedNameDef **names, scopedNameDef **values);
+codeBlock *templateCode(sipSpec *pt, ifaceFileList **used, codeBlock *ocb, scopedNameDef *names, scopedNameDef *values);
+ifaceFileDef *findIfaceFile(sipSpec *pt, moduleDef *mod,
+ scopedNameDef *fqname, ifaceFileType iftype,
+ apiVersionRangeDef *api_range, argDef *ad);
+int pluginPyQt3(sipSpec *pt);
+int pluginPyQt4(sipSpec *pt);
+void yywarning(char *);
+nameDef *cacheName(sipSpec *pt, const char *name);
+scopedNameDef *encodedTemplateName(templateDef *td);
+apiVersionRangeDef *findAPI(sipSpec *pt, const char *name);
+
+
+/* These are only here because bison publically references them. */
+
+/* Represent a set of option flags. */
+
+#define MAX_NR_FLAGS 5
+
+typedef enum {
+ bool_flag,
+ string_flag,
+ name_flag,
+ opt_name_flag,
+ dotted_name_flag,
+ integer_flag,
+ api_range_flag
+} flagType;
+
+typedef struct {
+ char *fname; /* The flag name. */
+ flagType ftype; /* The flag type. */
+ union { /* The flag value. */
+ char *sval; /* A string value. */
+ long ival; /* An integer value. */
+ apiVersionRangeDef *aval; /* An API range value. */
+ } fvalue;
+} optFlag;
+
+typedef struct {
+ int nrFlags; /* The number of flags. */
+ optFlag flags[MAX_NR_FLAGS]; /* Each flag. */
+} optFlags;
+
+#endif
diff --git a/sipgen/sipgen.sbf b/sipgen/sipgen.sbf
new file mode 100644
index 0000000..3542663
--- /dev/null
+++ b/sipgen/sipgen.sbf
@@ -0,0 +1,19 @@
+# This is the build file for the code generator.
+#
+# Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com>
+#
+# This file is part of SIP.
+#
+# This copy of SIP is licensed for use under the terms of the SIP License
+# Agreement. See the file LICENSE for more details.
+#
+# This copy of SIP may also used under the terms of the GNU General Public
+# License v2 or v3 as published by the Free Software Foundation which can be
+# found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
+#
+# SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+target = sip
+sources = main.c transform.c gencode.c export.c heap.c parser.c lexer.c
+headers = sip.h parser.h
diff --git a/sipgen/transform.c b/sipgen/transform.c
new file mode 100644
index 0000000..d24260f
--- /dev/null
+++ b/sipgen/transform.c
@@ -0,0 +1,3445 @@
+/*
+ * The parse tree transformation module for SIP.
+ *
+ * Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com>
+ *
+ * This file is part of SIP.
+ *
+ * This copy of SIP is licensed for use under the terms of the SIP License
+ * Agreement. See the file LICENSE for more details.
+ *
+ * This copy of SIP may also used under the terms of the GNU General Public
+ * License v2 or v3 as published by the Free Software Foundation which can be
+ * found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
+ *
+ * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#include <stddef.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "sip.h"
+
+
+static int samePythonSignature(signatureDef *sd1, signatureDef *sd2);
+static int nextSignificantArg(signatureDef *sd, int a);
+static int sameArgType(argDef *a1, argDef *a2, int strict);
+static int supportedType(classDef *,overDef *,argDef *,int);
+static int sameOverload(overDef *od1, overDef *od2);
+static int sameVirtualHandler(virtHandlerDef *vhd1,virtHandlerDef *vhd2);
+static int isSubClass(classDef *cc,classDef *pc);
+static void setAllImports(moduleDef *mod);
+static void addUniqueModule(moduleDef *mod, moduleDef *imp);
+static void ensureInput(classDef *,overDef *,argDef *);
+static void defaultInput(argDef *);
+static void defaultOutput(argDef *ad);
+static void createSortedNumberedTypesTable(sipSpec *pt, moduleDef *mod);
+static int compareTypes(const void *t1, const void *t2);
+static void addAutoOverload(sipSpec *,classDef *,overDef *);
+static void ifaceFileIsUsed(ifaceFileList **used, argDef *ad);
+static void ifaceFilesAreUsedByOverload(ifaceFileList **used, overDef *od);
+static void ifaceFilesAreUsedBySignature(ifaceFileList **used,
+ signatureDef *sd);
+static void scopeDefaultValue(sipSpec *,classDef *,argDef *);
+static void setHierarchy(sipSpec *,classDef *,classDef *,classList **);
+static void transformModules(sipSpec *pt, moduleDef *mod);
+static void transformCtors(sipSpec *,classDef *);
+static void transformCasts(sipSpec *,classDef *);
+static void addDefaultCopyCtor(classDef *);
+static void transformScopeOverloads(sipSpec *pt, classDef *c_scope,
+ mappedTypeDef *mt_scope, overDef *overs);
+static void transformVariableList(sipSpec *pt, moduleDef *mod);
+static void transformMappedTypes(sipSpec *pt, moduleDef *mod);
+static void getVisibleMembers(sipSpec *,classDef *);
+static void getVirtuals(sipSpec *pt,classDef *cd);
+static void getClassVirtuals(classDef *,classDef *);
+static void transformTypedefs(sipSpec *pt, moduleDef *mod);
+static void resolveMappedTypeTypes(sipSpec *,mappedTypeDef *);
+static void resolveCtorTypes(sipSpec *,classDef *,ctorDef *);
+static void resolveFuncTypes(sipSpec *pt, moduleDef *mod, classDef *c_scope,
+ mappedTypeDef *mt_scope, overDef *od);
+static void resolvePySigTypes(sipSpec *,moduleDef *,classDef *,overDef *,signatureDef *,int);
+static void resolveVariableType(sipSpec *,varDef *);
+static void fatalNoDefinedType(scopedNameDef *);
+static void getBaseType(sipSpec *,moduleDef *,classDef *,argDef *);
+static void searchClassScope(sipSpec *,classDef *,scopedNameDef *,argDef *);
+static void searchMappedTypes(sipSpec *,moduleDef *,scopedNameDef *,argDef *);
+static void searchEnums(sipSpec *,scopedNameDef *,argDef *);
+static void searchClasses(sipSpec *,moduleDef *mod,scopedNameDef *,argDef *);
+static void appendToMRO(mroDef *,mroDef ***,classDef *);
+static void moveMainModuleCastsSlots(sipSpec *pt, moduleDef *mod);
+static void moveClassCasts(sipSpec *pt, moduleDef *mod, classDef *cd);
+static void moveGlobalSlot(sipSpec *pt, moduleDef *mod, memberDef *gmd);
+static classDef *findAltClassImplementation(sipSpec *pt, mappedTypeDef *mtd);
+static void filterMainModuleVirtualHandlers(moduleDef *mod);
+static void filterModuleVirtualHandlers(moduleDef *mod);
+static ifaceFileDef *getIfaceFile(argDef *ad);
+static mappedTypeDef *instantiateMappedTypeTemplate(sipSpec *pt, moduleDef *mod, mappedTypeTmplDef *mtt, argDef *type);
+static classDef *getProxy(moduleDef *mod, classDef *cd);
+static int generatingCodeForModule(sipSpec *pt, moduleDef *mod);
+static void checkAssignmentHelper(sipSpec *pt, classDef *cd);
+static void addComplementarySlots(sipSpec *pt, classDef *cd);
+static void addComplementarySlot(sipSpec *pt, classDef *cd, memberDef *md,
+ slotType cslot, const char *cslot_name);
+static void resolveInstantiatedClassTemplate(sipSpec *pt, argDef *type);
+static void setStringPoolOffsets(sipSpec *pt);
+static const char *templateString(const char *src, scopedNameDef *names,
+ scopedNameDef *values);
+
+
+/*
+ * Transform the parse tree.
+ */
+
+void transform(sipSpec *pt)
+{
+ moduleDef *mod;
+ classDef *cd, *rev, **tail;
+ classList *newl;
+ overDef *od;
+
+ /*
+ * The class list has the main module's classes at the front and the ones
+ * from the module at the most nested %Import at the end. This affects
+ * some of the following algorithms. We have to have consistency whenever
+ * a module is used. To achieve this we reverse the order of the classes.
+ */
+ rev = NULL;
+ cd = pt -> classes;
+
+ while (cd != NULL)
+ {
+ classDef *next = cd -> next;
+
+ cd -> next = rev;
+ rev = cd;
+
+ /*
+ * Mark any QObject class. This flag will ripple through all derived
+ * classes when we set the hierarchy.
+ */
+ if (strcmp(classBaseName(cd), "QObject") == 0)
+ setIsQObjectSubClass(cd);
+
+ cd = next;
+ }
+
+ pt -> classes = rev;
+
+ /*
+ * Build the list of all imports for each module and check each has been
+ * named.
+ */
+ for (mod = pt->modules; mod != NULL; mod = mod->next)
+ {
+ if (mod->name == NULL)
+ fatal("A module is missing a %%Module or %%CModule directive\n");
+
+ setAllImports(mod);
+ }
+
+ /*
+ * Set the default meta-type for the main module if it doesn't have one
+ * explicitly set.
+ */
+ if (pt->module->defmetatype == NULL)
+ {
+ moduleListDef *mld;
+
+ for (mld = pt->module->allimports; mld != NULL; mld = mld->next)
+ {
+ if (mld->module->defmetatype == NULL)
+ continue;
+
+ if (pt->module->defmetatype == NULL)
+ pt->module->defmetatype = mld->module->defmetatype;
+ else if (pt->module->defmetatype != mld->module->defmetatype)
+ fatal("The %s module has imported different default meta-types %s and %s\n",
+ pt->module->fullname->text,
+ pt->module->defmetatype->text,
+ mld->module->defmetatype->text);
+ }
+ }
+
+ /* Check each class has been defined. */
+ for (cd = pt -> classes; cd != NULL; cd = cd -> next)
+ if (cd -> iff -> module == NULL)
+ {
+ fatalScopedName(classFQCName(cd));
+ fatal(" has not been defined\n");
+ }
+
+ /*
+ * Set the super-class hierarchy for each class and re-order the list of
+ * classes so that no class appears before a super class or an enclosing
+ * scope class.
+ */
+ newl = NULL;
+
+ for (cd = pt -> classes; cd != NULL; cd = cd -> next)
+ setHierarchy(pt,cd,cd,&newl);
+
+ /* Replace the old list with the new one. */
+ tail = &pt -> classes;
+
+ while (newl != NULL)
+ {
+ classList *cl = newl;
+
+ *tail = cl -> cd;
+ tail = &cl -> cd -> next;
+
+ newl = cl -> next;
+ free(cl);
+ }
+
+ *tail = NULL;
+
+ /* Transform the various types in the modules. */
+ if (isConsolidated(pt->module))
+ {
+ /* Transform the modules included by the consolidated module. */
+ for (mod = pt->modules->next; mod != NULL; mod = mod->next)
+ transformModules(pt, mod);
+ }
+ else
+ {
+ transformModules(pt, pt->modules);
+ }
+
+ /* Handle default ctors now that the argument types are resolved. */
+ if (!pt->genc)
+ for (cd = pt->classes; cd != NULL; cd = cd->next)
+ if (!noDefaultCtors(cd) && !isOpaque(cd) && cd->iff->type != namespace_iface)
+ addDefaultCopyCtor(cd);
+
+ /* Create the array of numbered types sorted by type name. */
+ for (mod = pt->modules; mod != NULL; mod = mod->next)
+ createSortedNumberedTypesTable(pt, mod);
+
+ /* Add any automatically generated methods. */
+ for (cd = pt -> classes; cd != NULL; cd = cd -> next)
+ for (od = cd -> overs; od != NULL; od = od -> next)
+ if (isAutoGen(od))
+ addAutoOverload(pt,cd,od);
+
+ /*
+ * Move casts and slots around to their correct classes (if in the same
+ * module) or create proxies for them (if cross-module).
+ */
+ if (!pt->genc)
+ for (mod = pt->modules; mod != NULL; mod = mod->next)
+ if (generatingCodeForModule(pt, mod))
+ moveMainModuleCastsSlots(pt, mod);
+
+ /* Automatically generate missing complementary slots. */
+ if (!pt->genc)
+ {
+ for (cd = pt->classes; cd != NULL; cd = cd->next)
+ addComplementarySlots(pt, cd);
+
+ for (mod = pt->modules; mod != NULL; mod = mod->next)
+ if (generatingCodeForModule(pt, mod))
+ for (cd = mod->proxies; cd != NULL; cd = cd->next)
+ addComplementarySlots(pt, cd);
+ }
+
+ /* Generate the different class views. */
+ for (cd = pt->classes; cd != NULL; cd = cd->next)
+ if (cd->iff->type == class_iface)
+ {
+ /* Get the list of visible member functions. */
+ getVisibleMembers(pt, cd);
+
+ /* Get the virtual members. */
+ if (hasShadow(cd))
+ getVirtuals(pt, cd);
+ }
+ else if (cd->iff->type == namespace_iface)
+ for (od = cd->overs; od != NULL; od = od->next)
+ ifaceFilesAreUsedByOverload(&cd->iff->used, od);
+
+ /*
+ * Filter the virtuals of all component modules (if consolidated) or the
+ * main module (if not).
+ */
+ for (mod = pt->modules; mod != NULL; mod = mod->next)
+ {
+ if (generatingCodeForModule(pt, mod))
+ {
+ filterMainModuleVirtualHandlers(mod);
+
+ for (od = mod->overs; od != NULL; od = od->next)
+ ifaceFilesAreUsedByOverload(&mod->used, od);
+ }
+
+ /* Update proxies with some information from the real classes. */
+ for (cd = mod->proxies; cd != NULL; cd = cd->next)
+ cd->iff->ifacenr = cd->real->iff->ifacenr;
+ }
+
+ /* Mark classes that can have an assignment helper. */
+ for (cd = pt->classes; cd != NULL; cd = cd->next)
+ checkAssignmentHelper(pt, cd);
+
+ setStringPoolOffsets(pt);
+}
+
+
+/*
+ * Transform a module and the modules it imports.
+ */
+static void transformModules(sipSpec *pt, moduleDef *mod)
+{
+ classDef *cd;
+ moduleListDef *mld;
+
+ /* Handle the trivial case. */
+ if (isTransformed(mod))
+ return;
+
+ /*
+ * The modules on which this one depends must be done first because they
+ * might generate new template-based types and they must be defined in the
+ * right module.
+ */
+ for (mld = mod->imports; mld != NULL; mld = mld->next)
+ transformModules(pt, mld->module);
+
+ /* Transform typedefs, variables and global functions. */
+ transformTypedefs(pt, mod);
+ transformVariableList(pt, mod);
+ transformScopeOverloads(pt, NULL, NULL, mod->overs);
+
+ /* Transform class ctors, functions and casts. */
+ for (cd = pt->classes; cd != NULL; cd = cd->next)
+ {
+ if (cd->iff->module == mod)
+ {
+ transformCtors(pt, cd);
+
+ if (!pt->genc)
+ {
+ transformScopeOverloads(pt, cd, NULL, cd->overs);
+ transformCasts(pt, cd);
+ }
+ }
+ }
+
+ /* Transform mapped types based on templates. */
+ transformMappedTypes(pt, mod);
+
+ setIsTransformed(mod);
+}
+
+
+/*
+ * Set the offset into the string pool for every used name.
+ */
+static void setStringPoolOffsets(sipSpec *pt)
+{
+ nameDef *nd;
+ size_t offset = 0;
+
+ for (nd = pt->namecache; nd != NULL; nd = nd->next)
+ {
+ size_t len;
+ nameDef *prev;
+
+ if (!isUsedName(nd))
+ continue;
+
+ /* See if the tail of a previous used name could be used instead. */
+ len = nd->len;
+
+ for (prev = pt->namecache; prev->len > len; prev = prev->next)
+ {
+ size_t pos;
+
+ if (!isUsedName(prev) || isSubstring(prev))
+ continue;
+
+ pos = prev->len - len;
+
+ if (memcmp(&prev->text[pos], nd->text, len) == 0)
+ {
+ setIsSubstring(nd);
+ nd->offset = prev->offset + pos;
+ break;
+ }
+ }
+
+ if (!isSubstring(nd))
+ {
+ nd->offset = offset;
+ offset += len + 1;
+ }
+ }
+}
+
+
+/*
+ * Add any missing complementary slots to a class. This emulates the C++
+ * behaviour of automatically interpreting (for example) >= as !<.
+ */
+static void addComplementarySlots(sipSpec *pt, classDef *cd)
+{
+ memberDef *md;
+
+ for (md = cd->members; md != NULL; md = md->next)
+ switch (md->slot)
+ {
+ case lt_slot:
+ addComplementarySlot(pt, cd, md, ge_slot, "__ge__");
+ break;
+
+ case le_slot:
+ addComplementarySlot(pt, cd, md, gt_slot, "__gt__");
+ break;
+
+ case gt_slot:
+ addComplementarySlot(pt, cd, md, le_slot, "__le__");
+ break;
+
+ case ge_slot:
+ addComplementarySlot(pt, cd, md, lt_slot, "__lt__");
+ break;
+
+ case eq_slot:
+ addComplementarySlot(pt, cd, md, ne_slot, "__ne__");
+ break;
+
+ case ne_slot:
+ addComplementarySlot(pt, cd, md, eq_slot, "__eq__");
+ break;
+ }
+}
+
+
+/*
+ * Add a complementary slot if it is missing.
+ */
+static void addComplementarySlot(sipSpec *pt, classDef *cd, memberDef *md,
+ slotType cslot, const char *cslot_name)
+{
+ overDef *od1;
+ memberDef *md2 = NULL;
+
+ for (od1 = cd->overs; od1 != NULL; od1 = od1->next)
+ {
+ overDef *od2;
+
+ if (od1->common != md || isComplementary(od1) || od1->methodcode != NULL)
+ continue;
+
+ /* Try and find an existing complementary slot. */
+ for (od2 = cd->overs; od2 != NULL; od2 = od2->next)
+ if (od2->common->slot == cslot && sameSignature(&od1->pysig, &od2->pysig, TRUE))
+ break;
+
+ /*
+ * If there is an explicit complementary slot then there is nothing to
+ * do.
+ */
+ if (od2 != NULL)
+ continue;
+
+ /* Create a new member if needed. */
+ if (md2 == NULL)
+ {
+ for (md2 = cd->members; md2 != NULL; md2 = md2->next)
+ if (md2->slot == cslot)
+ break;
+
+ if (md2 == NULL)
+ {
+ md2 = sipMalloc(sizeof (memberDef));
+
+ md2->pyname = cacheName(pt, cslot_name);
+ md2->memberflags = md->memberflags;
+ md2->slot = cslot;
+ md2->module = md->module;
+
+ md2->next = cd->members;
+ cd->members = md2;
+
+ if (isUsedName(md->pyname))
+ setIsUsedName(md2->pyname);
+ }
+ }
+
+ /* Create the complementary slot. */
+ od2 = sipMalloc(sizeof (overDef));
+
+ *od2 = *od1;
+ resetIsVirtual(od2);
+ setIsComplementary(od2);
+ od2->common = md2;
+
+ od2->next = cd->overs;
+ cd->overs = od2;
+ }
+}
+
+
+/*
+ * See if a class supports an assignment helper.
+ */
+static void checkAssignmentHelper(sipSpec *pt, classDef *cd)
+{
+ int pub_def_ctor, pub_copy_ctor;
+ ctorDef *ct;
+
+ /*
+ * We register types with Qt if the class is not abstract, doesn't have a
+ * private assignment operator, has a public default ctor, a public copy
+ * ctor and a public dtor.
+ */
+ if (isAbstractClass(cd))
+ return;
+
+ if (cannotAssign(cd))
+ return;
+
+ if (!isPublicDtor(cd))
+ return;
+
+ pub_def_ctor = pub_copy_ctor = FALSE;
+
+ for (ct = cd->ctors; ct != NULL; ct = ct->next)
+ {
+ if (ct->cppsig == NULL || !isPublicCtor(ct))
+ continue;
+
+ if (ct->cppsig->nrArgs == 0 || ct->cppsig->args[0].defval != NULL)
+ {
+ /*
+ * The ctor either has no arguments or all arguments have defaults.
+ */
+ pub_def_ctor = TRUE;
+ }
+ else if (ct->cppsig->nrArgs == 1)
+ {
+ argDef *ad = &ct->cppsig->args[0];
+ classDef *arg_cd;
+
+ if (ad->atype == class_type)
+ arg_cd = ad->u.cd;
+ else if (ad->atype == mapped_type)
+ arg_cd = findAltClassImplementation(pt, ad->u.mtd);
+ else
+ arg_cd = NULL;
+
+ if (arg_cd == cd && isReference(ad) && isConstArg(ad) &&
+ ad->nrderefs == 0 && ad->defval == NULL)
+ pub_copy_ctor = TRUE;
+ }
+ }
+
+ if (pub_def_ctor && pub_copy_ctor)
+ {
+ setAssignmentHelper(cd);
+ addToUsedList(&cd->iff->module->used, cd->iff);
+ }
+}
+
+
+/*
+ * Set the list of all imports for a module. The list is ordered so that a
+ * module appears before any module that imports it.
+ */
+static void setAllImports(moduleDef *mod)
+{
+ moduleListDef *mld;
+
+ /*
+ * Handle the trivial case where there are no imports, or the list has
+ * already been done.
+ */
+ if (mod->imports == NULL || mod->allimports != NULL)
+ return;
+
+ /* Make sure all the direct imports are done first. */
+ for (mld = mod->imports; mld != NULL; mld = mld->next)
+ setAllImports(mld->module);
+
+ /*
+ * Now build the list from our direct imports lists but ignoring
+ * duplicates.
+ */
+ for (mld = mod->imports; mld != NULL; mld = mld->next)
+ {
+ moduleListDef *amld;
+
+ for (amld = mld->module->allimports; amld != NULL; amld = amld->next)
+ addUniqueModule(mod, amld->module);
+
+ addUniqueModule(mod, mld->module);
+ }
+}
+
+
+/*
+ * Append a module to the list of all imported modules if it isn't already
+ * there.
+ */
+static void addUniqueModule(moduleDef *mod, moduleDef *imp)
+{
+ moduleListDef **tail;
+
+ for (tail = &mod->allimports; *tail != NULL; tail = &(*tail)->next)
+ if ((*tail)->module == imp)
+ return;
+
+ *tail = sipMalloc(sizeof (moduleListDef));
+
+ (*tail)->module = imp;
+ (*tail)->next = NULL;
+}
+
+
+/*
+ * Move the casts and slots to the correct place for a main module (ie. one we
+ * are generating code for).
+ */
+static void moveMainModuleCastsSlots(sipSpec *pt, moduleDef *mod)
+{
+ classDef *cd;
+ memberDef *md;
+
+ for (cd = pt->classes; cd != NULL; cd = cd->next)
+ if (cd->iff->module == mod)
+ moveClassCasts(pt, mod, cd);
+
+ for (md = mod->othfuncs; md != NULL; md = md->next)
+ if (md->slot != no_slot && md->module == mod)
+ moveGlobalSlot(pt, mod, md);
+}
+
+
+/*
+ * Move any class casts to its correct class, or publish as a ctor extender.
+ */
+static void moveClassCasts(sipSpec *pt, moduleDef *mod, classDef *cd)
+{
+ argList *al;
+
+ for (al = cd->casts; al != NULL; al = al->next)
+ {
+ classDef *dcd = al->arg.u.cd;
+ ctorDef *ct, **ctp;
+ argDef *ad;
+
+ if (al->arg.atype == class_type)
+ dcd = al->arg.u.cd;
+ else
+ /* Previous error checking means this will always work. */
+ dcd = findAltClassImplementation(pt, al->arg.u.mtd);
+
+ /*
+ * If the destination class is in a different module then use
+ * a proxy.
+ */
+ if (dcd->iff->module != mod)
+ dcd = getProxy(mod, dcd);
+
+ /* Create the new ctor. */
+ ct = sipMalloc(sizeof (ctorDef));
+
+ ct->ctorflags = SECT_IS_PUBLIC | CTOR_CAST;
+ ct->cppsig = &ct->pysig;
+
+ /* Add the source class as the only argument. */
+ ct->pysig.result.atype = void_type;
+ ad = &ct->pysig.args[0];
+
+ ad->atype = class_type;
+ ad->name = NULL;
+ ad->argflags = ARG_IN | (al->arg.argflags & (ARG_IS_REF | ARG_IS_CONST));
+ ad->nrderefs = al->arg.nrderefs;
+ ad->defval = NULL;
+ ad->u.cd = cd;
+
+ ifaceFileIsUsed(&dcd->iff->used, ad);
+
+ ct->pysig.nrArgs = 1;
+
+ /* Append it to the list. */
+ for (ctp = &dcd->ctors; *ctp != NULL; ctp = &(*ctp)->next)
+ if (sameSignature(&(*ctp)->pysig, &ct->pysig, FALSE))
+ {
+ fatal("operator ");
+ fatalScopedName(classFQCName(dcd));
+ fatal("::");
+ fatalScopedName(classFQCName(dcd));
+ fatal("(");
+ fatalScopedName(classFQCName(cd));
+ fatal(") already defined\n");
+ }
+
+ *ctp = ct;
+ }
+}
+
+
+/*
+ * If possible, move a global slot to its correct class.
+ */
+static void moveGlobalSlot(sipSpec *pt, moduleDef *mod, memberDef *gmd)
+{
+ overDef **odp = &mod->overs, *od;
+
+ while ((od = *odp) != NULL)
+ {
+ int second;
+ argDef *arg0, *arg1;
+ memberDef *md, **mdhead;
+ overDef **odhead;
+ moduleDef *mod;
+ nameDef *nd;
+
+ if (od->common != gmd)
+ {
+ odp = &od->next;
+ continue;
+ }
+
+ /*
+ * We know that the slot has the right number of arguments, but the
+ * first or second one needs to be a class or enum defined in the same
+ * module. Otherwise we leave it as it is and publish it as a slot
+ * extender.
+ */
+ arg0 = &od->pysig.args[0];
+ arg1 = &od->pysig.args[1];
+
+ mdhead = NULL;
+ second = FALSE;
+ nd = NULL;
+
+ if (arg0->atype == class_type)
+ {
+ mdhead = &arg0->u.cd->members;
+ odhead = &arg0->u.cd->overs;
+ mod = arg0->u.cd->iff->module;
+ }
+ else if (arg0->atype == mapped_type)
+ {
+ classDef *cd = findAltClassImplementation(pt, arg0->u.mtd);
+
+ if (cd != NULL)
+ {
+ mdhead = &cd->members;
+ odhead = &cd->overs;
+ mod = cd->iff->module;
+ }
+ }
+ else if (arg0->atype == enum_type)
+ {
+ mdhead = &arg0->u.ed->slots;
+ odhead = &arg0->u.ed->overs;
+ mod = arg0->u.ed->module;
+ nd = arg0->u.ed->pyname;
+ }
+ else if (arg1->atype == class_type)
+ {
+ mdhead = &arg1->u.cd->members;
+ odhead = &arg1->u.cd->overs;
+ mod = arg1->u.cd->iff->module;
+ second = TRUE;
+ }
+ else if (arg1->atype == mapped_type)
+ {
+ classDef *cd = findAltClassImplementation(pt, arg1->u.mtd);
+
+ if (cd != NULL)
+ {
+ mdhead = &cd->members;
+ odhead = &cd->overs;
+ mod = cd->iff->module;
+ second = TRUE;
+ }
+ }
+ else if (arg1->atype == enum_type)
+ {
+ mdhead = &arg1->u.ed->slots;
+ odhead = &arg1->u.ed->overs;
+ mod = arg1->u.ed->module;
+ nd = arg1->u.ed->pyname;
+ second = TRUE;
+ }
+
+ if (mdhead == NULL)
+ {
+ fatal("One of the arguments of ");
+ prOverloadName(stderr, od);
+ fatal(" must be a class or enum\n");
+ }
+
+ /*
+ * For rich comparisons the first argument must be a class or an enum.
+ * For cross-module slots then it may only be a class. (This latter
+ * limitation is artificial, but is unlikely to be a problem in
+ * practice.)
+ */
+ if (isRichCompareSlot(gmd))
+ {
+ if (second)
+ {
+ fatal("The first argument of ");
+ prOverloadName(stderr, od);
+ fatal(" must be a class or enum\n");
+ }
+
+ if (mod != gmd->module && arg0->atype == enum_type)
+ {
+ fatal("The first argument of ");
+ prOverloadName(stderr, od);
+ fatal(" must be a class\n");
+ }
+ }
+
+ if (mod != gmd->module)
+ {
+ if (isRichCompareSlot(gmd))
+ {
+ classDef *pcd = getProxy(mod, arg0->u.cd);
+ memberDef *pmd;
+ overDef *pod;
+
+ /* Create a new proxy member if needed. */
+ for (pmd = pcd->members; pmd != NULL; pmd = pmd->next)
+ if (pmd->slot == gmd->slot)
+ break;
+
+ if (pmd == NULL)
+ {
+ pmd = sipMalloc(sizeof (memberDef));
+
+ pmd->pyname = gmd->pyname;
+ pmd->memberflags = 0;
+ pmd->slot = gmd->slot;
+ pmd->module = mod;
+ pmd->next = pcd->members;
+
+ pcd->members = pmd;
+ }
+
+ /* Add the proxy overload. */
+ pod = sipMalloc(sizeof (overDef));
+
+ *pod = *od;
+ pod->common = pmd;
+ pod->next = pcd->overs;
+
+ pcd->overs = pod;
+
+ /* Remove the first argument. */
+ pod->pysig.args[0] = pod->pysig.args[1];
+ pod->pysig.nrArgs = 1;
+
+ /* Remove from the list. */
+ *odp = od->next;
+ }
+ else
+ odp = &od->next;
+
+ continue;
+ }
+
+ /* Remove from the list. */
+ *odp = od->next;
+
+ /* The only time we need the name of an enum is when it has slots. */
+ if (nd != NULL)
+ setIsUsedName(nd);
+
+ /* See if there is already a member or create a new one. */
+ for (md = *mdhead; md != NULL; md = md->next)
+ if (md->slot == gmd->slot)
+ break;
+
+ if (md == NULL)
+ {
+ md = sipMalloc(sizeof (memberDef));
+
+ *md = *gmd;
+
+ md->module = mod;
+ md->next = *mdhead;
+
+ *mdhead = md;
+ }
+
+ /* Move the overload to the end of the destination list. */
+ setIsPublic(od);
+ setIsGlobal(od);
+ od->common = md;
+ od->next = NULL;
+
+ while (*odhead != NULL)
+ odhead = &(*odhead)->next;
+
+ *odhead = od;
+
+ /* Remove the first argument of comparison operators. */
+ if (isRichCompareSlot(md))
+ {
+ /* Remember if the argument was a pointer. */
+ if (arg0->nrderefs > 0)
+ setDontDerefSelf(od);
+
+ *arg0 = *arg1;
+ od->pysig.nrArgs = 1;
+ }
+ }
+}
+
+
+/*
+ * Return an alternative class implementation of a mapped type if there is
+ * one. Note that we cheat as we assume there is one going to be one (as
+ * there will be in PyQt at the moment).
+ */
+static classDef *findAltClassImplementation(sipSpec *pt, mappedTypeDef *mtd)
+{
+ ifaceFileDef *iff = mtd->iff->first_alt;
+
+ while (iff != NULL)
+ {
+ if (iff->type == class_iface)
+ {
+ classDef *cd;
+
+ for (cd = pt->classes; cd != NULL; cd = cd->next)
+ if (cd->iff == iff)
+ return cd;
+ }
+
+ iff = iff->next_alt;
+ }
+
+ return NULL;
+}
+
+
+/*
+ * Create a proxy for a class if it doesn't already exist. Proxies are used as
+ * containers for cross-module extenders.
+ */
+static classDef *getProxy(moduleDef *mod, classDef *cd)
+{
+ classDef *pcd;
+
+ for (pcd = mod->proxies; pcd != NULL; pcd = pcd->next)
+ if (pcd->iff == cd->iff)
+ return pcd;
+
+ pcd = sipMalloc(sizeof (classDef));
+
+ pcd->pyname = cd->pyname;
+ pcd->iff = cd->iff;
+ pcd->ecd = cd->ecd;
+ pcd->real = cd;
+ pcd->supers = cd->supers;
+ pcd->mro = cd->mro;
+ pcd->next = mod->proxies;
+
+ mod->proxies = pcd;
+
+ return pcd;
+}
+
+
+/*
+ * Filter the virtual handlers for a main module (ie. one we are generating
+ * code for.
+ */
+static void filterMainModuleVirtualHandlers(moduleDef *mod)
+{
+ moduleListDef *mld;
+ virtHandlerDef *vhd;
+
+ /*
+ * Remove redundant virtual handlers. It's important that earlier, ie.
+ * those at the deepest level of %Import, are done first.
+ */
+ for (mld = mod->allimports; mld != NULL; mld = mld->next)
+ filterModuleVirtualHandlers(mld->module);
+
+ filterModuleVirtualHandlers(mod);
+
+ /*
+ * Make sure we have the interface files for all types from other modules
+ * that are used in virtual handlers implemented in this module.
+ */
+ for (vhd = mod->virthandlers; vhd != NULL; vhd = vhd->next)
+ if (!isDuplicateVH(vhd))
+ ifaceFilesAreUsedBySignature(&mod->used, vhd->cppsig);
+}
+
+
+/*
+ * Go through the virtual handlers filtering those that can duplicate earlier
+ * ones. Make sure each virtual is numbered within its module, and according
+ * to their position in the list (ignoring duplicates).
+ */
+static void filterModuleVirtualHandlers(moduleDef *mod)
+{
+ virtHandlerDef *vhd;
+
+ /* See if it has already been done for this module. */
+ if (mod->nrvirthandlers >= 0)
+ return;
+
+ mod->nrvirthandlers = 0;
+
+ for (vhd = mod->virthandlers; vhd != NULL; vhd = vhd->next)
+ {
+ virtHandlerDef *best, *best_thismod, *hd;
+
+ best = best_thismod = NULL;
+
+ /*
+ * If this has handwritten code then we will want to use it.
+ * Otherwise, look for a handler in earlier modules.
+ */
+ if (vhd->virtcode == NULL)
+ {
+ moduleListDef *mld;
+
+ for (mld = mod->allimports; mld != NULL && mld->module != mod; mld = mld->next)
+ {
+ for (hd = mld->module->virthandlers; hd != NULL; hd = hd->next)
+ if (sameVirtualHandler(vhd, hd))
+ {
+ best = hd;
+ break;
+ }
+
+ /*
+ * No need to check later modules as this will either be the
+ * right one, or a duplicate of the right one.
+ */
+ if (best != NULL)
+ break;
+ }
+ }
+
+ /*
+ * Find the best candidate in this module in case we want to give it
+ * our handwritten code.
+ */
+ for (hd = mod->virthandlers; hd != vhd; hd = hd->next)
+ if (sameVirtualHandler(vhd, hd))
+ {
+ best_thismod = hd;
+ break;
+ }
+
+ /*
+ * We don't use this one if it doesn't have virtual code and there is
+ * an alternative, or if it does have virtual code and there is already
+ * an alternative in the same module which doesn't have virtual code.
+ */
+ if ((vhd->virtcode == NULL && (best != NULL || best_thismod != NULL)) ||
+ (vhd->virtcode != NULL && best_thismod != NULL && best_thismod->virtcode == NULL))
+ {
+ virtHandlerDef *saved;
+
+ /*
+ * If the alternative is in the same module and we have virtual
+ * code then give it to the alternative. Note that there is a bug
+ * here. If there are three handlers, the first without code and
+ * the second and third with code then which code is transfered to
+ * the first is down to luck. We should really only transfer code
+ * to methods that are known to be re-implementations - just having
+ * the same signature isn't enough.
+ */
+ if (best_thismod != NULL)
+ {
+ if (best_thismod->virtcode == NULL && vhd->virtcode != NULL)
+ {
+ best_thismod->virtcode = vhd->virtcode;
+ resetIsDuplicateVH(best_thismod);
+ }
+
+ best = best_thismod;
+ }
+
+ /* Use the better one in place of this one. */
+ saved = vhd->next;
+ *vhd = *best;
+ setIsDuplicateVH(vhd);
+ vhd->next = saved;
+ }
+ else
+ vhd->virthandlernr = mod->nrvirthandlers++;
+ }
+}
+
+
+/*
+ * Add an overload that is automatically generated (typically by Qt's moc).
+ */
+static void addAutoOverload(sipSpec *pt,classDef *autocd,overDef *autood)
+{
+ classDef *cd;
+
+ /* Find every class that has this one in its hierarchy. */
+
+ for (cd = pt -> classes; cd != NULL; cd = cd -> next)
+ {
+ mroDef *mro;
+
+ if (cd == autocd)
+ continue;
+
+ for (mro = cd -> mro; mro != NULL; mro = mro -> next)
+ if (mro -> cd == autocd)
+ {
+ memberDef *md;
+ overDef *od;
+
+ /* Another overload may already exist. */
+
+ for (md = cd -> members; md != NULL; md = md -> next)
+ if (md -> pyname == autood -> common -> pyname)
+ break;
+
+ if (md == NULL)
+ {
+ md = sipMalloc(sizeof (memberDef));
+
+ md -> pyname = autood -> common -> pyname;
+ md -> memberflags = autood -> common -> memberflags;
+ md -> slot = autood -> common -> slot;
+ md -> module = cd -> iff -> module;
+ md -> next = cd -> members;
+ cd -> members = md;
+ }
+
+ od = sipMalloc(sizeof (overDef));
+
+ *od = *autood;
+ od -> common = md;
+ od -> next = cd -> overs;
+ cd -> overs = od;
+
+ resetIsAutoGen(od);
+
+ if (generatingCodeForModule(pt, cd->iff->module))
+ setIsUsedName(md -> pyname);
+
+ break;
+ }
+ }
+}
+
+
+/*
+ * Set the complete hierarchy for a class.
+ */
+static void setHierarchy(sipSpec *pt, classDef *base, classDef *cd,
+ classList **head)
+{
+ mroDef **tailp = &cd->mro;
+
+ /* See if it has already been done. */
+ if (cd->mro != NULL)
+ return;
+
+ if (cd->ecd != NULL)
+ {
+ setHierarchy(pt, base, cd->ecd, head);
+
+ if (isDeprecatedClass(cd->ecd))
+ setIsDeprecatedClass(cd);
+ }
+
+ if (cd->iff->type == class_iface)
+ {
+ classList *cl;
+
+ /* The first thing is itself. */
+ appendToMRO(cd->mro, &tailp, cd);
+
+ if (cd->convtosubcode != NULL)
+ cd->subbase = cd;
+
+ /* Now do it's superclasses. */
+ setHierBeingSet(cd->mro);
+
+ for (cl = cd->supers; cl != NULL; cl = cl->next)
+ {
+ mroDef *mro;
+
+ if (cl->cd->mro != NULL && hierBeingSet(cl->cd->mro))
+ {
+ fatal("Recursive class hierarchy detected: ");
+ fatalScopedName(classFQCName(cd));
+ fatal(" and ");
+ fatalScopedName(classFQCName(cl->cd));
+ fatal("\n");
+ }
+
+ /* Make sure the super-class's hierarchy has been done. */
+ setHierarchy(pt, base, cl->cd, head);
+
+ /* Append the super-classes hierarchy. */
+ for (mro = cl->cd->mro; mro != NULL; mro = mro->next)
+ {
+ appendToMRO(cd->mro, &tailp, mro->cd);
+
+ if (isDeprecatedClass(mro->cd))
+ setIsDeprecatedClass(cd);
+
+ /*
+ * If the super-class is a QObject sub-class then this one is
+ * as well.
+ */
+ if (isQObjectSubClass(mro->cd))
+ setIsQObjectSubClass(cd);
+
+ /*
+ * If the super-class can't be assigned to then this one
+ * cannot either.
+ */
+ if (cannotAssign(mro->cd))
+ setCannotAssign(cd);
+
+ /*
+ * If the super-class has a shadow then this one should have
+ * one as well.
+ */
+ if (hasShadow(mro->cd))
+ setHasShadow(cd);
+
+ /*
+ * Ensure that the sub-class base class is the furthest up the
+ * hierarchy.
+ */
+ if (mro->cd->subbase != NULL)
+ cd->subbase = mro->cd->subbase;
+ }
+ }
+
+ resetHierBeingSet(cd->mro);
+
+ /*
+ * If the class doesn't have an explicit meta-type then inherit from
+ * the module's default.
+ */
+ if (cd->metatype == NULL && cd->supers == NULL)
+ cd->metatype = cd->iff->module->defmetatype;
+
+ if (cd->metatype != NULL && generatingCodeForModule(pt, cd->iff->module))
+ setIsUsedName(cd->metatype);
+
+ /*
+ * If the class doesn't have an explicit super-type then inherit from
+ * the module's default.
+ */
+ if (cd->supertype == NULL && cd->supers == NULL)
+ cd->supertype = cd->iff->module->defsupertype;
+
+ if (cd->supertype != NULL && strcmp(cd->supertype->text, "sip.wrapper") == 0)
+ cd->supertype = NULL;
+
+ if (cd->supertype != NULL && generatingCodeForModule(pt, cd->iff->module))
+ setIsUsedName(cd->supertype);
+ }
+
+ /*
+ * Make sure that the module in which a sub-class convertor will be created
+ * knows about the base class.
+ */
+ if (cd->subbase != NULL)
+ addToUsedList(&cd->iff->module->used, cd->subbase->iff);
+
+ /*
+ * We can't have a shadow if the specification is incomplete, there is
+ * a private dtor, there are no none-private ctors or there are private
+ * abstract methods.
+ */
+ if (isIncomplete(cd) || isPrivateDtor(cd) || !canCreate(cd))
+ resetHasShadow(cd);
+ else
+ {
+ overDef *od;
+
+ /*
+ * Note that we should be able to provide better support for
+ * abstract private methods than we do at the moment.
+ */
+ for (od = cd->overs; od != NULL; od = od->next)
+ if (isAbstract(od) && isPrivate(od))
+ {
+ resetHasShadow(cd);
+
+ /*
+ * It also means we cannot create an instance
+ * from Python.
+ */
+ resetCanCreate(cd);
+
+ break;
+ }
+ }
+
+ /* Add it to the new list. */
+ appendToClassList(head,cd);
+}
+
+
+/*
+ * Append a class definition to an mro list
+ */
+static void appendToMRO(mroDef *head,mroDef ***tailp,classDef *cd)
+{
+ mroDef *mro, *new;
+
+ new = sipMalloc(sizeof (mroDef));
+
+ new -> cd = cd;
+ new -> mroflags = 0;
+ new -> next = NULL;
+
+ /* See if it is a duplicate. */
+
+ for (mro = head; mro != NULL; mro = mro -> next)
+ if (mro -> cd == cd)
+ {
+ setIsDuplicateSuper(new);
+
+ if (!isDuplicateSuper(mro))
+ setHasDuplicateSuper(mro);
+
+ break;
+ }
+
+ /* Append to the list and update the tail pointer. */
+ **tailp = new;
+ *tailp = &new -> next;
+}
+
+
+/*
+ * Get the base types for all typedefs of a module.
+ */
+static void transformTypedefs(sipSpec *pt, moduleDef *mod)
+{
+ typedefDef *td;
+
+ for (td = pt->typedefs; td != NULL; td = td->next)
+ if (td->module == mod)
+ getBaseType(pt, td->module, td->ecd, &td->type);
+}
+
+
+/*
+ * Transform the data types for mapped types based on a template.
+ */
+static void transformMappedTypes(sipSpec *pt, moduleDef *mod)
+{
+ mappedTypeDef *mt;
+
+ for (mt = pt->mappedtypes; mt != NULL; mt = mt->next)
+ {
+ if (mt->iff->module == mod)
+ {
+ if (mt->type.atype == template_type)
+ resolveMappedTypeTypes(pt, mt);
+ else
+ transformScopeOverloads(pt, NULL, mt, mt->overs);
+ }
+ }
+}
+
+
+/*
+ * Transform the data types for a list of ctors.
+ */
+static void transformCtors(sipSpec *pt, classDef *cd)
+{
+ ctorDef *ct;
+
+ for (ct = cd->ctors; ct != NULL; ct = ct->next)
+ {
+ ctorDef *prev;
+
+ resolveCtorTypes(pt, cd, ct);
+
+ /*
+ * Now check that the Python signature doesn't conflict with an
+ * earlier one.
+ */
+ for (prev = cd->ctors; prev != ct; prev = prev->next)
+ if (samePythonSignature(&prev->pysig, &ct->pysig))
+ {
+ fatalScopedName(classFQCName(cd));
+ fatal(" has ctors with the same Python signature\n");
+ }
+
+ if (isDeprecatedClass(cd))
+ setIsDeprecatedCtor(ct);
+ }
+}
+
+
+/*
+ * Transform the data type for a list of casts.
+ */
+static void transformCasts(sipSpec *pt, classDef *cd)
+{
+ argList *al;
+
+ for (al = cd->casts; al != NULL; al = al->next)
+ {
+ classDef *dcd;
+
+ getBaseType(pt, cd->iff->module, cd, &al->arg);
+
+ if (al->arg.atype == class_type)
+ dcd = al->arg.u.cd;
+ else if (al->arg.atype == mapped_type)
+ dcd = findAltClassImplementation(pt, al->arg.u.mtd);
+ else
+ dcd = NULL;
+
+ if (dcd == NULL)
+ {
+ fatalScopedName(classFQCName(cd));
+ fatal(" operator cast must be to a class\n");
+ }
+ }
+}
+
+
+/*
+ * Add a default copy ctor if required.
+ */
+static void addDefaultCopyCtor(classDef *cd)
+{
+ ctorDef *copyct, **tailp;
+ mroDef *mro;
+
+ /* See if there is a private copy ctor in the hierarchy. */
+ for (mro = cd->mro; mro != NULL; mro = mro->next)
+ {
+ ctorDef *ct;
+
+ if (isDuplicateSuper(mro))
+ continue;
+
+ for (ct = mro->cd->ctors; ct != NULL; ct = ct->next)
+ {
+ argDef *ad = &ct -> pysig.args[0];
+
+ /* See if is a copy ctor. */
+ if (ct->pysig.nrArgs == 1 && ad->nrderefs == 0 && isReference(ad))
+ {
+ ifaceFileDef *iff;
+
+ /* To check the type we have to look at all versions. */
+ if (ad->atype == class_type)
+ iff = ad->u.cd->iff;
+ else if (ad->atype == mapped_type)
+ iff = ad->u.mtd->iff;
+ else
+ continue;
+
+ for (iff = iff->first_alt; iff != NULL; iff = iff->next_alt)
+ if (mro->cd->iff == iff)
+ break;
+
+ if (iff != NULL)
+ break;
+ }
+ }
+
+ if (ct != NULL)
+ {
+ /* If the copy ctor is private then the class can't be copied. */
+ if (isPrivateCtor(ct))
+ {
+ setCannotCopy(cd);
+ return;
+ }
+
+ /*
+ * If the ctor is in the class itself then there is nothing to do.
+ */
+ if (mro == cd->mro)
+ return;
+
+ /* Otherwise we need to create a default. */
+ break;
+ }
+ }
+
+ /* Create a default public copy ctor. */
+ copyct = sipMalloc(sizeof (ctorDef));
+
+ copyct->ctorflags = SECT_IS_PUBLIC;
+ copyct->pysig.nrArgs = 1;
+ copyct->pysig.result.atype = void_type;
+ copyct->pysig.args[0].atype = class_type;
+ copyct->pysig.args[0].u.cd = cd;
+ copyct->pysig.args[0].argflags = (ARG_IS_REF | ARG_IS_CONST | ARG_IN);
+ copyct->pysig.args[0].nrderefs = 0;
+ copyct->pysig.args[0].defval = NULL;
+
+ copyct->cppsig = &copyct->pysig;
+
+ if (isDeprecatedClass(cd))
+ setIsDeprecatedCtor(copyct);
+
+ /* Append it to the list. */
+ for (tailp = &cd->ctors; *tailp != NULL; tailp = &(*tailp)->next)
+ ;
+
+ *tailp = copyct;
+}
+
+
+/*
+ * Transform the data types for a list of overloads.
+ */
+static void transformScopeOverloads(sipSpec *pt, classDef *c_scope,
+ mappedTypeDef *mt_scope, overDef *overs)
+{
+ overDef *od;
+
+ for (od = overs; od != NULL; od = od->next)
+ {
+ overDef *prev;
+
+ resolveFuncTypes(pt, od->common->module, c_scope, mt_scope, od);
+
+ /*
+ * Now check that the Python signature doesn't conflict with an earlier
+ * one.
+ */
+ for (prev = overs; prev != od; prev = prev->next)
+ {
+ if (prev->common != od->common)
+ continue;
+
+ /* They can only conflict if one is unversioned. */
+ if (prev->api_range != NULL && od->api_range != NULL)
+ continue;
+
+ if (samePythonSignature(&prev->pysig, &od->pysig))
+ {
+ ifaceFileDef *iff;
+
+ if (mt_scope != NULL)
+ iff = mt_scope->iff;
+ else if (c_scope != NULL)
+ iff = c_scope->iff;
+ else
+ iff = NULL;
+
+ if (iff != NULL)
+ {
+ fatalScopedName(iff->fqcname);
+ fatal("::");
+ }
+
+ fatal("%s() has overloaded functions with the same Python signature\n", od->common->pyname->text);
+ }
+ }
+
+ if (c_scope != NULL && isDeprecatedClass(c_scope))
+ setIsDeprecated(od);
+ }
+}
+
+
+/*
+ * Transform the data types for the variables of a module.
+ */
+static void transformVariableList(sipSpec *pt, moduleDef *mod)
+{
+ varDef *vd;
+
+ for (vd = pt->vars; vd != NULL; vd = vd->next)
+ if (vd->module == mod)
+ if (vd->ecd == NULL || !isTemplateClass(vd->ecd))
+ resolveVariableType(pt, vd);
+}
+
+
+/*
+ * Set the list of visible member functions for a class.
+ */
+static void getVisibleMembers(sipSpec *pt, classDef *cd)
+{
+ mroDef *mro;
+
+ cd->visible = NULL;
+
+ for (mro = cd->mro; mro != NULL; mro = mro->next)
+ {
+ memberDef *md;
+ classDef *mrocd;
+
+ if (isDuplicateSuper(mro))
+ continue;
+
+ mrocd = mro->cd;
+
+ for (md = mrocd->members; md != NULL; md = md->next)
+ {
+ visibleList *vl;
+
+ /*
+ * See if it is already in the list. This has the desired side
+ * effect of eliminating any functions that have an implementation
+ * closer to this class in the hierarchy. This is the only reason
+ * to define private functions.
+ */
+ for (vl = cd->visible; vl != NULL; vl = vl->next)
+ if (vl->m->pyname == md->pyname)
+ break;
+
+ /* See if it is a new member function. */
+ if (vl == NULL)
+ {
+ overDef *od;
+
+ vl = sipMalloc(sizeof (visibleList));
+
+ vl->m = md;
+ vl->cd = mrocd;
+ vl->next = cd->visible;
+
+ cd->visible = vl;
+
+ for (od = mrocd->overs; od != NULL; od = od->next)
+ if (od->common == md)
+ {
+ if (isAbstract(od))
+ setIsAbstractClass(cd);
+
+ ifaceFilesAreUsedByOverload(&cd->iff->used, od);
+
+ /* See if we need the name. */
+ if (!generatingCodeForModule(pt, cd->iff->module))
+ continue;
+
+ if (isProtected(od) || (isSignal(od) && pluginPyQt3(pt)))
+ setIsUsedName(md->pyname);
+
+ /* Make we have any API name. */
+ if (od->api_range != NULL)
+ setIsUsedName(od->api_range->api_name);
+ }
+ }
+ }
+ }
+}
+
+
+/*
+ * Get all the virtuals for a particular class.
+ */
+static void getVirtuals(sipSpec *pt, classDef *cd)
+{
+ mroDef *mro;
+ virtOverDef *vod;
+
+ for (mro = cd->mro; mro != NULL; mro = mro->next)
+ {
+ if (isDuplicateSuper(mro))
+ continue;
+
+ getClassVirtuals(cd, mro->cd);
+ }
+
+ /*
+ * Identify any re-implementations of virtuals. We have to do this for all
+ * classes, not just those in the module we are generating code for.
+ */
+ for (vod = cd->vmembers; vod != NULL; vod = vod->next)
+ {
+ overDef *od;
+
+ for (od = cd->overs; od != NULL; od = od->next)
+ {
+ if (isVirtual(od))
+ continue;
+
+ if (strcmp(vod->o.cppname, od->cppname) == 0 && sameOverload(&vod->o, od))
+ {
+ setIsVirtualReimp(od);
+ break;
+ }
+ }
+
+ /*
+ * If this class is defined in the main module make sure we get the API
+ * files for all the visible virtuals.
+ */
+ if (generatingCodeForModule(pt, cd->iff->module))
+ {
+ /* Make sure we get the name. */
+ setIsUsedName(vod->o.common->pyname);
+ }
+ }
+}
+
+
+/*
+ * Get the list of visible virtual functions for a class.
+ */
+static void getClassVirtuals(classDef *base, classDef *cd)
+{
+ overDef *od;
+
+ for (od = cd->overs; od != NULL; od = od->next)
+ {
+ virtOverDef **tailp, *vod;
+
+ if (!isVirtual(od) || isPrivate(od))
+ continue;
+
+ /*
+ * See if a virtual of this name and signature is already in the list.
+ */
+ for (tailp = &base->vmembers; (vod = *tailp) != NULL; tailp = &vod->next)
+ if (strcmp(vod->o.cppname, od->cppname) == 0 && sameOverload(&vod->o, od))
+ break;
+
+ if (vod == NULL)
+ {
+ /*
+ * See if there is a non-virtual reimplementation nearer in the
+ * class hierarchy.
+ */
+
+ mroDef *mro;
+ classDef *scope = NULL;
+ overDef *eod;
+
+ for (mro = base->mro; mro->cd != cd; mro = mro->next)
+ {
+ if (isDuplicateSuper(mro))
+ continue;
+
+ /*
+ * Ignore classes that are on a different branch of the class
+ * hierarchy.
+ */
+ if (!isSubClass(mro->cd, cd))
+ continue;
+
+ for (eod = mro->cd->overs; eod != NULL; eod = eod->next)
+ if (strcmp(eod->cppname, od->cppname) == 0 && sameSignature(eod->cppsig, od->cppsig, TRUE) && isConst(eod) == isConst(od) && !isAbstract(eod))
+ {
+ scope = mro->cd;
+ break;
+ }
+
+ if (scope != NULL)
+ break;
+ }
+
+ vod = sipMalloc(sizeof (virtOverDef));
+
+ vod->o = *od;
+ vod->scope = (scope != NULL ? scope : cd);
+ vod->next = NULL;
+
+ *tailp = vod;
+
+ /*
+ * If there was a nearer reimplementation then we use its
+ * protection and abstract flags.
+ */
+ if (scope != NULL)
+ {
+ vod->o.overflags &= ~(SECT_MASK | OVER_IS_ABSTRACT);
+ vod->o.overflags |= (SECT_MASK | OVER_IS_ABSTRACT) & eod->overflags;
+ }
+ }
+ }
+}
+
+
+/*
+ * Return TRUE is a class is derived from another.
+ */
+static int isSubClass(classDef *cc,classDef *pc)
+{
+ mroDef *mro;
+
+ /*
+ * In other words, does the parent class appear in the child class's
+ * MRO list.
+ */
+ for (mro = cc -> mro; mro != NULL; mro = mro -> next)
+ if (mro -> cd == pc)
+ return TRUE;
+
+ return FALSE;
+}
+
+
+/*
+ * Resolve the types of a mapped type based on a template.
+ */
+static void resolveMappedTypeTypes(sipSpec *pt, mappedTypeDef *mt)
+{
+ int a;
+ signatureDef *sd = &mt->type.u.td->types;
+
+ for (a = 0; a < sd->nrArgs; ++a)
+ {
+ argDef *ad = &sd->args[a];
+
+ /* Leave templates as they are. */
+ if (ad->atype != template_type)
+ getBaseType(pt, mt->iff->module, NULL, ad);
+ }
+
+ /* Make sure that the signature result won't cause problems. */
+ sd->result.atype = no_type;
+
+ ifaceFilesAreUsedBySignature(&mt->iff->used, sd);
+}
+
+
+/*
+ * Resolve the types of a ctor.
+ */
+static void resolveCtorTypes(sipSpec *pt,classDef *scope,ctorDef *ct)
+{
+ int a;
+
+ /* Handle any C++ signature. */
+ if (ct->cppsig != NULL && ct->cppsig != &ct->pysig)
+ for (a = 0; a < ct -> cppsig -> nrArgs; ++a)
+ getBaseType(pt, scope->iff->module, scope, &ct->cppsig->args[a]);
+
+ /* Handle the Python signature. */
+ for (a = 0; a < ct -> pysig.nrArgs; ++a)
+ {
+ argDef *ad = &ct -> pysig.args[a];
+
+ getBaseType(pt, scope->iff->module, scope, ad);
+
+ if (!supportedType(scope,NULL,ad,FALSE) && (ct -> cppsig == &ct -> pysig || ct -> methodcode == NULL))
+ {
+ fatalScopedName(classFQCName(scope));
+ fatal(" unsupported ctor argument type - provide %%MethodCode and a C++ signature\n");
+ }
+
+ ifaceFileIsUsed(&scope->iff->used, ad);
+ scopeDefaultValue(pt, scope, ad);
+ }
+}
+
+
+/*
+ * Resolve the types of a function.
+ */
+static void resolveFuncTypes(sipSpec *pt, moduleDef *mod, classDef *c_scope,
+ mappedTypeDef *mt_scope, overDef *od)
+{
+ argDef *res;
+
+ /* Handle any C++ signature. */
+ if (od->cppsig != &od->pysig)
+ {
+ int a;
+
+ getBaseType(pt,mod, c_scope, &od->cppsig->result);
+
+ for (a = 0; a < od->cppsig->nrArgs; ++a)
+ getBaseType(pt, mod, c_scope, &od->cppsig->args[a]);
+ }
+
+ /* Handle the Python signature. */
+ resolvePySigTypes(pt, mod, c_scope, od, &od->pysig, isSignal(od));
+
+ res = &od->pysig.result;
+
+ /* These slots must return SIP_SSIZE_T (or int - deprecated). */
+ if (isSSizeReturnSlot(od->common))
+ if ((res->atype != ssize_type && res->atype != int_type) || res->nrderefs != 0 ||
+ isReference(res) || isConstArg(res))
+ fatal("%s slots must return SIP_SSIZE_T\n",
+ od->common->pyname->text);
+
+ /* These slots must return int. */
+ if (isIntReturnSlot(od->common))
+ if (res->atype != int_type || res->nrderefs != 0 ||
+ isReference(res) || isConstArg(res))
+ fatal("%s slots must return int\n", od->common->pyname->text);
+
+ /* These slots must return void. */
+ if (isVoidReturnSlot(od->common))
+ if (res->atype != void_type || res->nrderefs != 0 ||
+ isReference(res) || isConstArg(res))
+ fatal("%s slots must return void\n", od->common->pyname->text);
+
+ /* These slots must return long. */
+ if (isLongReturnSlot(od->common))
+ if (res->atype != long_type || res->nrderefs != 0 ||
+ isReference(res) || isConstArg(res))
+ fatal("%s slots must return long\n", od->common->pyname->text);
+}
+
+
+/*
+ * Resolve the types of a Python signature.
+ */
+static void resolvePySigTypes(sipSpec *pt, moduleDef *mod, classDef *scope,
+ overDef *od, signatureDef *pysig, int issignal)
+{
+ int a;
+ argDef *res = &pysig -> result;
+
+ if (res -> atype != void_type || res -> nrderefs != 0)
+ {
+ if (issignal)
+ {
+ if (scope != NULL)
+ {
+ fatalScopedName(classFQCName(scope));
+ fatal("::");
+ }
+
+ fatal("%s() signals must return void\n",od -> cppname);
+ }
+
+ getBaseType(pt, mod, scope, res);
+
+ /* Results must be simple. */
+ if (!supportedType(scope,od,res,FALSE) && (od -> cppsig == &od -> pysig || od -> methodcode == NULL))
+ {
+ if (scope != NULL)
+ {
+ fatalScopedName(classFQCName(scope));
+ fatal("::");
+ }
+
+ fatal("%s() unsupported function return type - provide %%MethodCode and a %s signature\n",od -> cppname,(pt -> genc ? "C" : "C++"));
+ }
+ }
+
+ for (a = 0; a < pysig -> nrArgs; ++a)
+ {
+ argDef *ad = &pysig -> args[a];
+
+ getBaseType(pt, mod, scope, ad);
+
+ if (ad -> atype == slotcon_type)
+ resolvePySigTypes(pt, mod, scope, od, ad->u.sa, TRUE);
+
+ /*
+ * Note signal arguments are restricted in their types because we don't
+ * (yet) support handwritten code for them.
+ */
+ if (issignal)
+ {
+ if (!supportedType(scope,od,ad,FALSE))
+ {
+ if (scope != NULL)
+ {
+ fatalScopedName(classFQCName(scope));
+ fatal("::");
+ }
+
+ fatal("%s() unsupported signal argument type\n", od->cppname);
+ }
+ }
+ else if (!supportedType(scope,od,ad,TRUE) && (od -> cppsig == &od -> pysig || od -> methodcode == NULL || (isVirtual(od) && od -> virthandler -> virtcode == NULL)))
+ {
+ if (scope != NULL)
+ {
+ fatalScopedName(classFQCName(scope));
+ fatal("::");
+ }
+
+ if (isVirtual(od))
+ fatal("%s() unsupported function argument type - provide %%MethodCode, a valid %%VirtualCatcherCode and a valid C++ signature\n",od -> cppname);
+
+ fatal("%s() unsupported function argument type - provide %%MethodCode and a valid %s signature\n",od -> cppname,(pt -> genc ? "C" : "C++"));
+ }
+
+ if (scope != NULL)
+ scopeDefaultValue(pt,scope,ad);
+ }
+}
+
+
+/*
+ * Resolve the type of a variable.
+ */
+static void resolveVariableType(sipSpec *pt, varDef *vd)
+{
+ int bad = TRUE;
+ argDef *vtype = &vd->type;
+
+ getBaseType(pt, vd->module, vd->ecd, vtype);
+
+ switch (vtype->atype)
+ {
+ case mapped_type:
+ case class_type:
+ /* Class, Class & and Class * are supported. */
+
+ if (vtype->nrderefs <= 1)
+ bad = FALSE;
+ break;
+
+ case ascii_string_type:
+ case latin1_string_type:
+ case utf8_string_type:
+ case sstring_type:
+ case ustring_type:
+ case string_type:
+ case wstring_type:
+ /*
+ * (signed/unsigned) char, (signed/unsigned) char *, wchar_t, wchar_t *
+ * are supported.
+ */
+
+ if (!isReference(vtype) && vtype->nrderefs <= 1)
+ bad = FALSE;
+ break;
+
+ case cfloat_type:
+ case float_type:
+ case cdouble_type:
+ case double_type:
+ case enum_type:
+ case bool_type:
+ case cbool_type:
+ case ushort_type:
+ case short_type:
+ case uint_type:
+ case cint_type:
+ case int_type:
+ case ulong_type:
+ case long_type:
+ case ulonglong_type:
+ case longlong_type:
+ case ssize_type:
+ case pyobject_type:
+ case pytuple_type:
+ case pylist_type:
+ case pydict_type:
+ case pycallable_type:
+ case pyslice_type:
+ case pytype_type:
+ /* These are supported without pointers or references. */
+
+ if (!isReference(vtype) && vtype->nrderefs == 0)
+ bad = FALSE;
+ break;
+
+ case struct_type:
+ case void_type:
+ /* A simple pointer is supported. */
+
+ if (!isReference(vtype) && vtype->nrderefs == 1)
+ bad = FALSE;
+ break;
+ }
+
+ if (bad && (vd->getcode == NULL || vd->setcode == NULL))
+ {
+ fatalScopedName(vd->fqcname);
+ fatal(" has an unsupported type - provide %%GetCode and %%SetCode\n");
+ }
+
+ if (vtype->atype != class_type && vd->accessfunc != NULL)
+ {
+ fatalScopedName(vd->fqcname);
+ fatal(" has %%AccessCode but isn't a class instance\n");
+ }
+
+ if (vd->ecd != NULL)
+ ifaceFileIsUsed(&vd->ecd->iff->used, vtype);
+ else
+ ifaceFileIsUsed(&vd->module->used, vtype);
+
+ /* Scoped variables need a handler unless they have %AccessCode. */
+ if (vd->ecd != NULL && vd->accessfunc == NULL)
+ {
+ setNeedsHandler(vd);
+ setHasVarHandlers(vd->ecd);
+ }
+}
+
+
+/*
+ * See if a type is supported by the generated code.
+ */
+static int supportedType(classDef *cd,overDef *od,argDef *ad,int outputs)
+{
+ switch (ad -> atype)
+ {
+ case anyslot_type:
+ /*
+ * This must be an input, and must also have handwritten code.
+ */
+
+ ensureInput(cd,od,ad);
+ return FALSE;
+
+ case signal_type:
+ case slot_type:
+ case rxcon_type:
+ case rxdis_type:
+ case slotcon_type:
+ case slotdis_type:
+ case qobject_type:
+ case ellipsis_type:
+ /* These can only appear in argument lists without * or &. */
+
+ ensureInput(cd,od,ad);
+ return TRUE;
+
+ case ascii_string_type:
+ case latin1_string_type:
+ case utf8_string_type:
+ case sstring_type:
+ case ustring_type:
+ case string_type:
+ case wstring_type:
+ if (isReference(ad))
+ {
+ if (outputs && ad -> nrderefs <= 1)
+ {
+ defaultOutput(ad);
+ return TRUE;
+ }
+ }
+ else if (ad -> nrderefs == 0)
+ {
+ ensureInput(cd,od,ad);
+ return TRUE;
+ }
+ else if (ad -> nrderefs == 1)
+ {
+ if (outputs)
+ defaultInput(ad);
+ else
+ ensureInput(cd,od,ad);
+
+ return TRUE;
+ }
+ else if (ad -> nrderefs == 2 && outputs)
+ {
+ defaultOutput(ad);
+ return TRUE;
+ }
+
+ break;
+
+ case cfloat_type:
+ case float_type:
+ case cdouble_type:
+ case double_type:
+ case enum_type:
+ case bool_type:
+ case cbool_type:
+ case ushort_type:
+ case short_type:
+ case uint_type:
+ case cint_type:
+ case int_type:
+ case ulong_type:
+ case long_type:
+ case ulonglong_type:
+ case longlong_type:
+ case ssize_type:
+ case pyobject_type:
+ case pytuple_type:
+ case pylist_type:
+ case pydict_type:
+ case pycallable_type:
+ case pyslice_type:
+ case pytype_type:
+ if (isReference(ad))
+ {
+ if (ad -> nrderefs == 0 && outputs)
+ {
+ defaultOutput(ad);
+ return TRUE;
+ }
+ }
+ else if (ad -> nrderefs == 0)
+ {
+ ensureInput(cd,od,ad);
+ return TRUE;
+ }
+ else if (ad -> nrderefs == 1 && outputs)
+ {
+ defaultOutput(ad);
+ return TRUE;
+ }
+
+ break;
+
+ case mapped_type:
+ case class_type:
+ if (isReference(ad))
+ {
+ if (ad -> nrderefs == 0)
+ {
+ defaultInput(ad);
+ return TRUE;
+ }
+ else if (ad -> nrderefs == 1 && outputs)
+ {
+ defaultOutput(ad);
+ return TRUE;
+ }
+ }
+ else if (ad -> nrderefs == 0)
+ {
+ ensureInput(cd,od,ad);
+ return TRUE;
+ }
+ else if (ad -> nrderefs == 1)
+ {
+ if (outputs)
+ defaultInput(ad);
+ else
+ ensureInput(cd,od,ad);
+
+ return TRUE;
+ }
+ else if (ad -> nrderefs == 2 && outputs)
+ {
+ defaultOutput(ad);
+ return TRUE;
+ }
+
+ break;
+
+ case struct_type:
+ case void_type:
+ if (isReference(ad))
+ {
+ if (ad -> nrderefs == 1 && outputs)
+ {
+ defaultOutput(ad);
+ return TRUE;
+ }
+ }
+ else if (ad -> nrderefs == 1)
+ {
+ ensureInput(cd,od,ad);
+ return TRUE;
+ }
+ else if (ad -> nrderefs == 2 && outputs)
+ {
+ defaultOutput(ad);
+ return TRUE;
+ }
+
+ break;
+ }
+
+ /* Unsupported if we got this far. */
+ return FALSE;
+}
+
+
+/*
+ * Ensure the direction of an argument is an input.
+ */
+static void ensureInput(classDef *cd,overDef *od,argDef *ad)
+{
+ if (isOutArg(ad))
+ {
+ if (cd != NULL)
+ {
+ fatalScopedName(classFQCName(cd));
+ fatal("::");
+ }
+
+ if (od != NULL)
+ fatal("%s",od -> cppname);
+
+ fatal("() invalid argument type for /Out/\n");
+ }
+
+ setIsInArg(ad);
+}
+
+
+/*
+ * Default the direction of an argument to an input.
+ */
+static void defaultInput(argDef *ad)
+{
+ if (!isInArg(ad) && !isOutArg(ad))
+ setIsInArg(ad);
+}
+
+
+/*
+ * Default the direction of an argument to an output unless the argument is
+ * const.
+ */
+static void defaultOutput(argDef *ad)
+{
+ if (!isOutArg(ad) && !isInArg(ad))
+ {
+ if (isConstArg(ad))
+ setIsInArg(ad);
+ else
+ setIsOutArg(ad);
+ }
+}
+
+
+/*
+ * Put a scoped name to stderr.
+ */
+void fatalScopedName(scopedNameDef *snd)
+{
+ while (snd != NULL)
+ {
+ fatal("%s",snd -> name);
+
+ snd = snd -> next;
+
+ if (snd != NULL)
+ fatal("::");
+ }
+}
+
+
+/*
+ * Compare two overloads and return TRUE if they are the same.
+ */
+static int sameOverload(overDef *od1, overDef *od2)
+{
+ /* They must both be enabled for the same API. */
+ if (od1->api_range != od2->api_range)
+ return FALSE;
+
+ /* They must both be const, or both not. */
+ if (isConst(od1) != isConst(od2))
+ return FALSE;
+
+ return sameSignature(&od1->pysig, &od2->pysig, TRUE);
+}
+
+
+/*
+ * Compare two virtual handlers and return TRUE if they are the same.
+ */
+static int sameVirtualHandler(virtHandlerDef *vhd1,virtHandlerDef *vhd2)
+{
+ int a;
+
+ if (isTransferVH(vhd1) != isTransferVH(vhd2))
+ return FALSE;
+
+ if (!sameArgType(&vhd1->pysig->result, &vhd2->pysig->result, TRUE))
+ return FALSE;
+
+ if (!sameSignature(vhd1->pysig, vhd2->pysig, TRUE))
+ return FALSE;
+
+ /* Take into account the argument directions in the Python signatures. */
+ for (a = 0; a < vhd1->pysig->nrArgs; ++a)
+ {
+ int dir1 = (vhd1->pysig->args[a].argflags & (ARG_IN | ARG_OUT));
+ int dir2 = (vhd2->pysig->args[a].argflags & (ARG_IN | ARG_OUT));
+
+ if (dir1 != dir2)
+ return FALSE;
+ }
+
+ if (vhd1->pysig == vhd1->cppsig && vhd2->pysig == vhd2->cppsig)
+ return TRUE;
+
+ if (!sameArgType(&vhd1->cppsig->result, &vhd2->cppsig->result, TRUE))
+ return FALSE;
+
+ return sameSignature(vhd1->cppsig, vhd2->cppsig, TRUE);
+}
+
+
+/*
+ * Compare two signatures and return TRUE if they are the same.
+ */
+int sameSignature(signatureDef *sd1,signatureDef *sd2,int strict)
+{
+ int a;
+
+ if (strict)
+ {
+ /* The number of arguments must be the same. */
+ if (sd1 -> nrArgs != sd2 -> nrArgs)
+ return FALSE;
+ }
+ else
+ {
+ int na1, na2;
+
+ /* We only count the compulsory arguments. */
+ na1 = 0;
+
+ for (a = 0; a < sd1 -> nrArgs; ++a)
+ {
+ if (sd1 -> args[a].defval != NULL)
+ break;
+
+ ++na1;
+ }
+
+ na2 = 0;
+
+ for (a = 0; a < sd2 -> nrArgs; ++a)
+ {
+ if (sd2 -> args[a].defval != NULL)
+ break;
+
+ ++na2;
+ }
+
+ if (na1 != na2)
+ return FALSE;
+ }
+
+ /* The arguments must be the same. */
+ for (a = 0; a < sd1 -> nrArgs; ++a)
+ {
+ if (!strict && sd1 -> args[a].defval != NULL)
+ break;
+
+ if (!sameArgType(&sd1 -> args[a],&sd2 -> args[a],strict))
+ return FALSE;
+ }
+
+ /* Must be the same if we've got this far. */
+ return TRUE;
+}
+
+
+#define pyAsString(t) ((t) == ustring_type || (t) == sstring_type || \
+ (t) == string_type || (t) == ascii_string_type || \
+ (t) == latin1_string_type || (t) == utf8_string_type)
+#define pyAsFloat(t) ((t) == cfloat_type || (t) == float_type || \
+ (t) == cdouble_type || (t) == double_type)
+#define pyAsInt(t) ((t) == bool_type || (t) == ssize_type || \
+ (t) == short_type || (t) == ushort_type || \
+ (t) == cint_type || (t) == int_type || (t) == uint_type)
+#define pyAsLong(t) ((t) == long_type || (t) == longlong_type)
+#define pyAsULong(t) ((t) == ulong_type || (t) == ulonglong_type)
+#define pyAsAuto(t) ((t) == bool_type || \
+ (t) == short_type || (t) == ushort_type || \
+ (t) == int_type || (t) == uint_type || \
+ (t) == float_type || (t) == double_type)
+#define pyIsConstrained(t) ((t) == cbool_type || (t) == cint_type || \
+ (t) == cfloat_type || (t) == cdouble_type)
+
+/*
+ * Compare two argument types and return TRUE if they are the same. "strict"
+ * means as C++ would see it, rather than Python.
+ */
+static int sameArgType(argDef *a1, argDef *a2, int strict)
+{
+ /* The references must be the same. */
+ if (isReference(a1) != isReference(a2) || a1->nrderefs != a2->nrderefs)
+ return FALSE;
+
+ if (strict)
+ {
+ /* The const should be the same. */
+ if (isConstArg(a1) != isConstArg(a2))
+ return FALSE;
+
+ return sameBaseType(a1,a2);
+ }
+
+ /* If both are constrained fundamental types then the types must match. */
+ if (pyIsConstrained(a1->atype) && pyIsConstrained(a2->atype))
+ return (a1->atype == a2->atype);
+
+ /* An unconstrained enum also acts as a (very) constrained int. */
+ if ((pyAsInt(a1->atype) && a2->atype == enum_type && !isConstrained(a2)) ||
+ (a1->atype == enum_type && !isConstrained(a1) && pyAsInt(a2->atype)))
+ return TRUE;
+
+ /* Python will see all these as strings. */
+ if (pyAsString(a1->atype) && pyAsString(a2->atype))
+ return TRUE;
+
+ /* Python will see all these as floats. */
+ if (pyAsFloat(a1->atype) && pyAsFloat(a2->atype))
+ return TRUE;
+
+ /* Python will see all these as ints. */
+ if (pyAsInt(a1->atype) && pyAsInt(a2->atype))
+ return TRUE;
+
+ /* Python will see all these as longs. */
+ if (pyAsLong(a1->atype) && pyAsLong(a2->atype))
+ return TRUE;
+
+ /* Python will see all these as unsigned longs. */
+ if (pyAsULong(a1->atype) && pyAsULong(a2->atype))
+ return TRUE;
+
+ /* Python will automatically convert between these. */
+ if (pyAsAuto(a1->atype) && pyAsAuto(a2->atype))
+ return TRUE;
+
+ /* All the special cases have been handled. */
+ return sameBaseType(a1, a2);
+}
+
+
+/*
+ * Compare two basic types and return TRUE if they are the same.
+ */
+int sameBaseType(argDef *a1, argDef *a2)
+{
+ /* The types must be the same. */
+ if (a1->atype != a2->atype)
+ {
+ /*
+ * If we are comparing a template with those that have already been
+ * used to instantiate a class or mapped type then we need to compare
+ * with the class or mapped type name.
+ */
+ if (a1->atype == class_type && a2->atype == defined_type)
+ return compareScopedNames(a1->u.cd->iff->fqcname, a2->u.snd) == 0;
+
+ if (a1->atype == defined_type && a2->atype == class_type)
+ return compareScopedNames(a1->u.snd, a2->u.cd->iff->fqcname) == 0;
+
+ if (a1->atype == mapped_type && a2->atype == defined_type)
+ return compareScopedNames(a1->u.mtd->iff->fqcname, a2->u.snd) == 0;
+
+ if (a1->atype == defined_type && a2->atype == mapped_type)
+ return compareScopedNames(a1->u.snd, a2->u.mtd->iff->fqcname) == 0;
+
+ return FALSE;
+ }
+
+ switch (a1->atype)
+ {
+ case class_type:
+ if (a1->u.cd != a2->u.cd)
+ return FALSE;
+
+ break;
+
+ case enum_type:
+ if (a1->u.ed != a2->u.ed)
+ return FALSE;
+
+ break;
+
+ case slotcon_type:
+ case slotdis_type:
+ if (!sameSignature(a1->u.sa, a2->u.sa, TRUE))
+ return FALSE;
+
+ break;
+
+ case template_type:
+ {
+ int a;
+ templateDef *td1, *td2;
+
+ td1 = a1->u.td;
+ td2 = a2->u.td;
+
+ if (compareScopedNames(td1->fqname, td2->fqname) != 0 ||
+ td1->types.nrArgs != td2->types.nrArgs)
+ return FALSE;
+
+ for (a = 0; a < td1->types.nrArgs; ++a)
+ if (!sameBaseType(&td1->types.args[a], &td2->types.args[a]))
+ return FALSE;
+
+ break;
+ }
+
+ case struct_type:
+ if (compareScopedNames(a1->u.sname, a2->u.sname) != 0)
+ return FALSE;
+
+ break;
+
+ case defined_type:
+ if (compareScopedNames(a1->u.snd, a2->u.snd) != 0)
+ return FALSE;
+
+ break;
+
+ case mapped_type:
+ if (a1->u.mtd != a2->u.mtd)
+ return FALSE;
+
+ break;
+ }
+
+ /* Must be the same if we've got this far. */
+ return TRUE;
+}
+
+
+/*
+ * See if two Python signatures are the same as far as Python is concerned.
+ */
+static int samePythonSignature(signatureDef *sd1, signatureDef *sd2)
+{
+ int a1, a2;
+
+ a1 = a2 = -1;
+
+ for (;;)
+ {
+ a1 = nextSignificantArg(sd1, a1);
+ a2 = nextSignificantArg(sd2, a2);
+
+ if (a1 < 0 || a2 < 0)
+ break;
+
+ if (!sameArgType(&sd1->args[a1], &sd2->args[a2], FALSE))
+ return FALSE;
+ }
+
+ return (a1 < 0 && a2 < 0);
+
+}
+
+
+/*
+ * Return the next significant argument from a Python signature (ie. one that
+ * is not optional or an output only argument. Return -1 if there isn't one.
+ */
+static int nextSignificantArg(signatureDef *sd, int a)
+{
+ while (++a < sd->nrArgs)
+ {
+ if (sd->args[a].defval != NULL)
+ break;
+
+ if (isInArg(&sd->args[a]))
+ return a;
+ }
+
+ return -1;
+}
+
+
+/*
+ * The equivalent of strcmp() for scoped names.
+ */
+int compareScopedNames(scopedNameDef *snd1, scopedNameDef *snd2)
+{
+ while (snd1 != NULL && snd2 != NULL)
+ {
+ int res = strcmp(snd1->name, snd2->name);
+
+ if (res != 0)
+ return res;
+
+ snd1 = snd1->next;
+ snd2 = snd2->next;
+ }
+
+ if (snd1 == NULL)
+ return (snd2 == NULL ? 0 : -1);
+
+ return 1;
+}
+
+
+/*
+ * Add an explicit scope to the default value of an argument if possible.
+ */
+
+static void scopeDefaultValue(sipSpec *pt,classDef *cd,argDef *ad)
+{
+ valueDef *vd, **tailp, *newvd;
+
+ /*
+ * We do a quick check to see if we need to do anything. This means
+ * we can limit the times we need to copy the default value. It needs
+ * to be copied because it will be shared by class versions that have
+ * been created on the fly and it may need to be scoped differently for
+ * each of those versions.
+ */
+
+ for (vd = ad -> defval; vd != NULL; vd = vd -> next)
+ if (vd -> vtype == scoped_value && vd -> u.vscp -> next == NULL)
+ break;
+
+ if (vd == NULL)
+ return;
+
+ /*
+ * It's not certain that we will do anything, but we assume we will and
+ * start copying.
+ */
+
+ newvd = NULL;
+ tailp = &newvd;
+
+ for (vd = ad -> defval; vd != NULL; vd = vd -> next)
+ {
+ mroDef *mro;
+ scopedNameDef *origname;
+ valueDef *new;
+
+ /* Make the copy. */
+
+ new = sipMalloc(sizeof (valueDef));
+
+ *new = *vd;
+ *tailp = new;
+ tailp = &new -> next;
+
+ /*
+ * Skip this part of the expression if it isn't a named value
+ * or it already has a scope.
+ */
+
+ if (vd -> vtype != scoped_value || vd -> u.vscp -> next != NULL)
+ continue;
+
+ /*
+ * Search the class hierarchy for an enum value with the same
+ * name. If we don't find one, leave it as it is (the compiler
+ * will find out if this is a problem).
+ */
+
+ origname = vd -> u.vscp;
+
+ for (mro = cd -> mro; mro != NULL; mro = mro -> next)
+ {
+ enumDef *ed;
+
+ if (isDuplicateSuper(mro))
+ continue;
+
+ for (ed = pt -> enums; ed != NULL; ed = ed -> next)
+ {
+ enumMemberDef *emd;
+
+ if (ed -> ecd != mro -> cd)
+ continue;
+
+ for (emd = ed -> members; emd != NULL; emd = emd -> next)
+ if (strcmp(emd -> cname,origname -> name) == 0)
+ {
+ scopedNameDef *snd;
+
+ /*
+ * Take the scope from the
+ * class that the enum was
+ * defined in.
+ */
+
+ snd = copyScopedName(mro -> cd -> iff -> fqcname);
+ appendScopedName(&snd,origname);
+
+ new -> u.vscp = snd;
+
+ /* Nothing more to do. */
+
+ break;
+ }
+
+ if (emd != NULL)
+ break;
+ }
+
+ if (ed != NULL)
+ break;
+ }
+ }
+
+ ad -> defval = newvd;
+}
+
+
+/*
+ * Make sure a type is a base type.
+ */
+static void getBaseType(sipSpec *pt, moduleDef *mod, classDef *c_scope,
+ argDef *type)
+{
+ /* Loop until we've got to a base type. */
+ while (type->atype == defined_type)
+ {
+ scopedNameDef *snd = type->u.snd;
+
+ type->atype = no_type;
+
+ if (c_scope != NULL)
+ searchClassScope(pt, c_scope, snd,type);
+
+ if (type->atype == no_type)
+ searchMappedTypes(pt, mod, snd, type);
+
+ if (type->atype == no_type)
+ searchTypedefs(pt, snd, type);
+
+ if (type->atype == no_type)
+ searchEnums(pt, snd, type);
+
+ if (type->atype == no_type)
+ searchClasses(pt, mod, snd, type);
+
+ if (type->atype == no_type)
+ fatalNoDefinedType(snd);
+ }
+
+ /* Get the base type of any slot arguments. */
+ if (type->atype == slotcon_type || type->atype == slotdis_type)
+ {
+ int sa;
+
+ for (sa = 0; sa < type->u.sa->nrArgs; ++sa)
+ getBaseType(pt, mod, c_scope, &type->u.sa->args[sa]);
+ }
+
+ /* See if the type refers to an instantiated template. */
+ resolveInstantiatedClassTemplate(pt, type);
+
+ /* Replace the base type if it has been mapped. */
+ if (type->atype == struct_type || type->atype == template_type)
+ {
+ searchMappedTypes(pt, mod, NULL, type);
+
+ /*
+ * If we still have a template then see if we need to automatically
+ * instantiate it.
+ */
+ if (type->atype == template_type)
+ {
+ mappedTypeTmplDef *mtt;
+
+ for (mtt = pt->mappedtypetemplates; mtt != NULL; mtt = mtt->next)
+ if (compareScopedNames(type->u.td->fqname, mtt->mt->type.u.td->fqname) == 0 && sameTemplateSignature(&mtt->mt->type.u.td->types, &type->u.td->types, TRUE))
+ {
+ type->u.mtd = instantiateMappedTypeTemplate(pt, mod, mtt, type);
+ type->atype = mapped_type;
+
+ break;
+ }
+ }
+ }
+}
+
+
+/*
+ * If the type corresponds to a previously instantiated class template then
+ * replace it with the class that was created.
+ */
+static void resolveInstantiatedClassTemplate(sipSpec *pt, argDef *type)
+{
+ int a;
+ classDef *cd;
+ templateDef *td;
+ signatureDef *sd;
+
+ if (type->atype != template_type)
+ return;
+
+ td = type->u.td;
+ sd = &td->types;
+
+ for (a = 0; a < sd->nrArgs; ++a)
+ resolveInstantiatedClassTemplate(pt, &sd->args[a]);
+
+ for (cd = pt->classes; cd != NULL; cd = cd->next)
+ if (cd->td != NULL &&
+ compareScopedNames(cd->td->fqname, td->fqname) == 0 &&
+ sameSignature(&cd->td->types, sd, TRUE))
+ {
+ type->atype = class_type;
+ type->u.cd = cd;
+
+ break;
+ }
+}
+
+
+/*
+ * Instantiate a mapped type template and return it.
+ */
+static mappedTypeDef *instantiateMappedTypeTemplate(sipSpec *pt, moduleDef *mod, mappedTypeTmplDef *mtt, argDef *type)
+{
+ scopedNameDef *type_names, *type_values;
+ mappedTypeDef *mtd;
+
+ type_names = type_values = NULL;
+ appendTypeStrings(type->u.td->fqname, &mtt->mt->type.u.td->types, &type->u.td->types, &mtt->sig, &type_names, &type_values);
+
+ mtd = allocMappedType(pt, type);
+
+ if (generatingCodeForModule(pt, mod))
+ setIsUsedName(mtd->cname);
+
+ mtd->iff = findIfaceFile(pt, mod, encodedTemplateName(type->u.td),
+ mappedtype_iface, NULL, type);
+ mtd->iff->module = mod;
+
+ mtd->doctype = templateString(mtt->mt->doctype, type_names, type_values);
+
+ appendCodeBlock(&mtd->iff->hdrcode, templateCode(pt, &mtd->iff->used, mtt->mt->iff->hdrcode, type_names, type_values));
+ mtd->convfromcode = templateCode(pt, &mtd->iff->used, mtt->mt->convfromcode, type_names, type_values);
+ mtd->convtocode = templateCode(pt, &mtd->iff->used, mtt->mt->convtocode, type_names, type_values);
+
+ mtd->next = pt->mappedtypes;
+ pt->mappedtypes = mtd;
+
+ if (type_names != NULL)
+ freeScopedName(type_names);
+
+ if (type_values != NULL)
+ freeScopedName(type_values);
+
+ return mtd;
+}
+
+
+/*
+ * Return a string based on an original with names replaced by corresponding
+ * values.
+ */
+static const char *templateString(const char *src, scopedNameDef *names,
+ scopedNameDef *values)
+{
+ char *dst;
+
+ /* Handle the trivial case. */
+ if (src == NULL)
+ return NULL;
+
+ dst = sipStrdup(src);
+
+ while (names != NULL && values != NULL)
+ {
+ char *cp, *vname = values->name;
+ size_t name_len, value_len;
+
+ name_len = strlen(names->name);
+ value_len = strlen(vname);
+
+ /* Translate any C++ scoping to Python. */
+ while ((cp = strstr(vname, "::")) != NULL)
+ {
+ char *new_vname = sipMalloc(value_len);
+ size_t pos = cp - vname;
+
+ memcpy(new_vname, vname, pos);
+ new_vname[pos] = '.';
+ strcpy(new_vname + pos + 1, cp + 2);
+
+ if (vname != values->name)
+ free(vname);
+
+ vname = new_vname;
+ --value_len;
+ }
+
+ while ((cp = strstr(dst, names->name)) != NULL)
+ {
+ char *new_dst = sipMalloc(strlen(dst) - name_len + value_len + 1);
+
+ memcpy(new_dst, dst, cp - dst);
+ memcpy(new_dst + (cp - dst), vname, value_len);
+ strcpy(new_dst + (cp - dst) + value_len, cp + name_len);
+
+ free(dst);
+ dst = new_dst;
+ }
+
+ if (vname != values->name)
+ free(vname);
+
+ names = names->next;
+ values = values->next;
+ }
+
+ return dst;
+}
+
+
+/*
+ * Search for a name in a scope and return the corresponding type.
+ */
+static void searchClassScope(sipSpec *pt, classDef *c_scope,
+ scopedNameDef *snd, argDef *ad)
+{
+ scopedNameDef *tmpsnd = NULL;
+ mroDef *mro;
+
+ for (mro = c_scope->mro; mro != NULL; mro = mro->next)
+ {
+ if (isDuplicateSuper(mro))
+ continue;
+
+ /* Append the name to the scope and see if it exists. */
+ tmpsnd = copyScopedName(classFQCName(mro->cd));
+ appendScopedName(&tmpsnd, copyScopedName(snd));
+
+ searchMappedTypes(pt, mro->cd->iff->module, tmpsnd, ad);
+
+ if (ad->atype != no_type)
+ break;
+
+ searchTypedefs(pt, tmpsnd, ad);
+
+ if (ad->atype != no_type)
+ break;
+
+ searchEnums(pt, tmpsnd, ad);
+
+ if (ad->atype != no_type)
+ break;
+
+ searchClasses(pt, mro->cd->iff->module, tmpsnd, ad);
+
+ if (ad->atype != no_type)
+ break;
+
+ freeScopedName(tmpsnd);
+ tmpsnd = NULL;
+ }
+
+ if (tmpsnd != NULL)
+ freeScopedName(tmpsnd);
+}
+
+
+/*
+ * Search the mapped types for a name and return the type.
+ */
+
+static void searchMappedTypes(sipSpec *pt, moduleDef *context,
+ scopedNameDef *snd, argDef *ad)
+{
+ mappedTypeDef *mtd;
+ scopedNameDef *oname;
+
+ /* Patch back to defined types so we can use sameBaseType(). */
+ if (snd != NULL)
+ {
+ oname = ad->u.snd;
+ ad->u.snd = snd;
+ ad->atype = defined_type;
+ }
+
+ for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next)
+ if (sameBaseType(ad, &mtd->type))
+ {
+ /*
+ * If we a building a consolidated module and this mapped type is
+ * defined in a different module then see if that other module is
+ * in a different branch of the module hierarchy.
+ */
+ if (isConsolidated(pt->module) && context != mtd->iff->module)
+ {
+ moduleListDef *mld;
+
+ for (mld = context->allimports; mld != NULL; mld = mld->next)
+ if (mld->module == mtd->iff->module)
+ break;
+
+ /* If it's in a different branch then we ignore it. */
+ if (mld == NULL)
+ continue;
+ }
+
+ /* Copy the type. */
+ ad->atype = mapped_type;
+ ad->u.mtd = mtd;
+
+ return;
+ }
+
+ /* Restore because we didn't find anything. */
+ if (snd != NULL)
+ {
+ ad->u.snd = oname;
+ ad->atype = no_type;
+ }
+}
+
+
+/*
+ * Search the typedefs for a name and return the type.
+ */
+void searchTypedefs(sipSpec *pt, scopedNameDef *snd, argDef *ad)
+{
+ typedefDef *td;
+
+ for (td = pt->typedefs; td != NULL; td = td->next)
+ {
+ int res = compareScopedNames(td->fqname, snd);
+
+ if (res == 0)
+ {
+ /* Copy the type. */
+ ad->atype = td->type.atype;
+ ad->argflags |= td->type.argflags;
+ ad->nrderefs += td->type.nrderefs;
+ ad->doctype = td->type.doctype;
+ ad->u = td->type.u;
+
+ if (ad->original_type == NULL)
+ ad->original_type = td;
+
+ break;
+ }
+
+ /* The list is sorted so stop if we have gone too far. */
+ if (res > 0)
+ break;
+ }
+}
+
+
+/*
+ * Search the enums for a name and return the type.
+ */
+static void searchEnums(sipSpec *pt, scopedNameDef *snd, argDef *ad)
+{
+ enumDef *ed;
+
+ for (ed = pt->enums; ed != NULL; ed = ed->next)
+ {
+ if (ed->fqcname == NULL)
+ continue;
+
+ if (compareScopedNames(ed->fqcname, snd) == 0)
+ {
+ ad->atype = enum_type;
+ ad->u.ed = ed;
+
+ break;
+ }
+ }
+}
+
+
+/*
+ * Search the classes for one with a particular name and return it as a type.
+ */
+static void searchClasses(sipSpec *pt, moduleDef *context,
+ scopedNameDef *cname, argDef *ad)
+{
+ classDef *cd;
+
+ for (cd = pt->classes; cd != NULL; cd = cd->next)
+ {
+ /*
+ * Ignore an external class unless it was declared in the same context
+ * (ie. module) as the name is being used.
+ */
+ if (isExternal(cd) && cd->iff->module != context)
+ continue;
+
+ if (compareScopedNames(classFQCName(cd), cname) == 0)
+ {
+ ad->atype = class_type;
+ ad->u.cd = cd;
+
+ break;
+ }
+ }
+}
+
+
+/*
+ * Print an error message describing an undefined type to stderr and terminate.
+ */
+
+static void fatalNoDefinedType(scopedNameDef *snd)
+{
+ fatalScopedName(snd);
+ fatal(" is undefined\n");
+}
+
+
+/*
+ * Make sure all interface files for a signature are used.
+ */
+static void ifaceFilesAreUsedBySignature(ifaceFileList **used, signatureDef *sd)
+{
+ int a;
+
+ ifaceFileIsUsed(used, &sd->result);
+
+ for (a = 0; a < sd->nrArgs; ++a)
+ ifaceFileIsUsed(used, &sd->args[a]);
+}
+
+
+/*
+ * Make sure all interface files for a function are used.
+ */
+static void ifaceFilesAreUsedByOverload(ifaceFileList **used, overDef *od)
+{
+ throwArgs *ta;
+
+ ifaceFilesAreUsedBySignature(used, &od->pysig);
+
+ if (od->cppsig != &od->pysig)
+ ifaceFilesAreUsedBySignature(used, od->cppsig);
+
+ if ((ta = od->exceptions) != NULL)
+ {
+ int a;
+
+ for (a = 0; a < ta->nrArgs; ++a)
+ addToUsedList(used, ta->args[a]->iff);
+ }
+}
+
+
+/*
+ * If a type has an interface file then add it to the the given list of used
+ * interface files so that the header file is #included in the generated code.
+ */
+static void ifaceFileIsUsed(ifaceFileList **used, argDef *ad)
+{
+ ifaceFileDef *iff;
+
+ if ((iff = getIfaceFile(ad)) != NULL)
+ {
+ addToUsedList(used, iff);
+
+ /*
+ * For mapped type templates we also need the template arguments.
+ * These will be in the mapped type's used list (which itself will be
+ * empty for non-template mapped types).
+ */
+ if (ad->atype == mapped_type)
+ {
+ ifaceFileList *iffl = iff->used;
+
+ for (iffl = iff->used; iffl != NULL; iffl = iffl->next)
+ addToUsedList(used, iffl->iff);
+ }
+ }
+}
+
+
+/*
+ * Return the interface file for a type, or NULL if it doesn't have one.
+ */
+static ifaceFileDef *getIfaceFile(argDef *ad)
+{
+ ifaceFileDef *iff;
+
+ switch (ad->atype)
+ {
+ case class_type:
+ iff = ad->u.cd->iff;
+ break;
+
+ case mapped_type:
+ iff = ad->u.mtd->iff;
+ break;
+
+ case enum_type:
+ if (ad->u.ed->fqcname != NULL)
+ {
+ if (ad->u.ed->ecd != NULL)
+ {
+ iff = ad->u.ed->ecd->iff;
+ break;
+ }
+
+ if (ad->u.ed->emtd != NULL)
+ {
+ iff = ad->u.ed->emtd->iff;
+ break;
+ }
+ }
+
+ /* Drop through. */
+
+ default:
+ iff = NULL;
+ }
+
+ return iff;
+}
+
+
+/*
+ * Create the sorted array of numbered types for a module.
+ */
+static void createSortedNumberedTypesTable(sipSpec *pt, moduleDef *mod)
+{
+ classDef *cd;
+ mappedTypeDef *mtd;
+ enumDef *ed;
+ argDef *ad;
+ int i;
+
+ /* Count the how many types there are. */
+ mod->nrtypes = 0;
+
+ for (cd = pt->classes; cd != NULL; cd = cd->next)
+ {
+ if (cd->iff->module != mod)
+ continue;
+
+ if (cd->iff->first_alt != cd->iff)
+ continue;
+
+ mod->nrtypes++;
+ }
+
+ for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next)
+ {
+ if (mtd->iff->module != mod)
+ continue;
+
+ if (mtd->iff->first_alt != mtd->iff)
+ continue;
+
+ mod->nrtypes++;
+ }
+
+ for (ed = pt->enums; ed != NULL; ed = ed->next)
+ {
+ if (ed->module != mod)
+ continue;
+
+ if (ed->fqcname == NULL)
+ continue;
+
+ if (ed->ecd != NULL && isTemplateClass(ed->ecd))
+ continue;
+
+ if (ed->first_alt != ed)
+ continue;
+
+ mod->nrtypes++;
+ }
+
+ if (mod->nrtypes == 0)
+ return;
+
+ /* Allocate and populate the table. */
+ ad = mod->types = sipCalloc(mod->nrtypes, sizeof (argDef));
+
+ for (cd = pt->classes; cd != NULL; cd = cd->next)
+ {
+ if (cd->iff->module != mod)
+ continue;
+
+ if (cd->iff->first_alt != cd->iff)
+ continue;
+
+ ad->atype = class_type;
+ ad->u.cd = cd;
+ ad->name = cd->iff->name;
+
+ ++ad;
+ }
+
+ for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next)
+ {
+ if (mtd->iff->module != mod)
+ continue;
+
+ if (mtd->iff->first_alt != mtd->iff)
+ continue;
+
+ ad->atype = mapped_type;
+ ad->u.mtd = mtd;
+ ad->name = mtd->cname;
+
+ ++ad;
+ }
+
+ for (ed = pt->enums; ed != NULL; ed = ed->next)
+ {
+ if (ed->module != mod)
+ continue;
+
+ if (ed->fqcname == NULL)
+ continue;
+
+ if (ed->ecd != NULL && isTemplateClass(ed->ecd))
+ continue;
+
+ if (ed->first_alt != ed)
+ continue;
+
+ ad->atype = enum_type;
+ ad->u.ed = ed;
+ ad->name = ed->cname;
+
+ ++ad;
+ }
+
+ /* Sort the table and assign type numbers. */
+ qsort(mod->types, mod->nrtypes, sizeof (argDef), compareTypes);
+
+ for (ad = mod->types, i = 0; i < mod->nrtypes; ++i, ++ad)
+ {
+ switch (ad->atype)
+ {
+ case class_type:
+ ad->u.cd->iff->ifacenr = i;
+
+ /* If we find a class called QObject, assume it's Qt. */
+ if (strcmp(ad->name->text, "QObject") == 0)
+ mod->qobjclass = i;
+
+ break;
+
+ case mapped_type:
+ ad->u.mtd->iff->ifacenr = i;
+ break;
+
+ case enum_type:
+ ad->u.ed->enumnr = i;
+ break;
+ }
+ }
+}
+
+
+/*
+ * The qsort helper to compare two generated type names.
+ */
+static int compareTypes(const void *t1, const void *t2)
+{
+ return strcmp(((argDef *)t1)->name->text, ((argDef *)t2)->name->text);
+}
+
+
+/*
+ * Return TRUE if we are generating code for a module, ie. we are a component
+ * of a consolidated module, or the main module where there is no consolidated
+ * module.
+ */
+static int generatingCodeForModule(sipSpec *pt, moduleDef *mod)
+{
+ if (isConsolidated(pt->module))
+ return (pt->module == mod->container);
+
+ return (pt->module == mod);
+}
diff --git a/siplib/apiversions.c b/siplib/apiversions.c
new file mode 100644
index 0000000..7d86c76
--- /dev/null
+++ b/siplib/apiversions.c
@@ -0,0 +1,295 @@
+/*
+ * The implementation of the supprt for setting API versions.
+ *
+ * Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com>
+ *
+ * This file is part of SIP.
+ *
+ * This copy of SIP is licensed for use under the terms of the SIP License
+ * Agreement. See the file LICENSE for more details.
+ *
+ * This copy of SIP may also used under the terms of the GNU General Public
+ * License v2 or v3 as published by the Free Software Foundation which can be
+ * found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
+ *
+ * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#include <Python.h>
+
+#include <string.h>
+
+#include "sip.h"
+#include "sipint.h"
+
+
+/*
+ * The structure that defines the version number of an API.
+ */
+typedef struct _apiVersionDef {
+ /* The name of the API. */
+ const char *api_name;
+
+ /*
+ * The version number of the API. This will either be set explicitly via
+ * a call to sip.setapi() or implicitly by an imported module.
+ */
+ int version_nr;
+
+ /* The next in the list of APIs. */
+ struct _apiVersionDef *next;
+} apiVersionDef;
+
+
+/*
+ * The list of API versions.
+ */
+static apiVersionDef *api_versions = NULL;
+
+
+/*
+ * Forward declarations.
+ */
+static int add_api(const char *api, int version_nr);
+static apiVersionDef *find_api(const char *api);
+
+
+/*
+ * See if a range of versions of a particular API is enabled.
+ */
+int sip_api_is_api_enabled(const char *name, int from, int to)
+{
+ const apiVersionDef *avd;
+
+ if ((avd = find_api(name)) == NULL)
+ return FALSE;
+
+ if (from > 0 && avd->version_nr < from)
+ return FALSE;
+
+ if (to > 0 && avd->version_nr >= to)
+ return FALSE;
+
+ return TRUE;
+}
+
+
+/*
+ * Initialise the the API for a module and return a negative value on error.
+ */
+int sipInitAPI(sipExportedModuleDef *em, PyObject *mod_dict)
+{
+ int *apis, i;
+ sipVersionedFunctionDef *vf;
+ sipTypeDef **tdp;
+
+ /* See if the module defines any APIs. */
+ if ((apis = em->em_versions) != NULL)
+ {
+ while (apis[0] >= 0)
+ {
+ /*
+ * See if it is an API definition rather than a range
+ * definition.
+ */
+ if (apis[2] < 0)
+ {
+ const char *api_name;
+ const apiVersionDef *avd;
+
+ api_name = sipNameFromPool(em, apis[0]);
+
+ /* Use the default version if not already set explicitly. */
+ if ((avd = find_api(api_name)) == NULL)
+ if (add_api(api_name, apis[1]) < 0)
+ return -1;
+ }
+
+ apis += 3;
+ }
+ }
+
+ /* Add any versioned global functions to the module dictionary. */
+ if ((vf = em->em_versioned_functions) != NULL)
+ {
+ while (vf->vf_name >= 0)
+ {
+ if (sipIsRangeEnabled(em, vf->vf_api_range))
+ {
+ const char *func_name = sipNameFromPool(em, vf->vf_name);
+ PyMethodDef *pmd;
+ PyObject *py_func;
+
+ if ((pmd = sip_api_malloc(sizeof (PyMethodDef))) == NULL)
+ return -1;
+
+ pmd->ml_name = SIP_MLNAME_CAST(func_name);
+ pmd->ml_meth = vf->vf_function;
+ pmd->ml_flags = vf->vf_flags;
+ pmd->ml_doc = vf->vf_docstring;
+
+ if ((py_func = PyCFunction_New(pmd, NULL)) == NULL)
+ return -1;
+
+ if (PyDict_SetItemString(mod_dict, func_name, py_func) < 0)
+ {
+ Py_DECREF(py_func);
+ return -1;
+ }
+
+ Py_DECREF(py_func);
+ }
+
+ ++vf;
+ }
+ }
+
+ /* Update the types table according to any version information. */
+ for (tdp = em->em_types, i = 0; i < em->em_nrtypes; ++i, ++tdp)
+ {
+ sipTypeDef *td;
+
+ if ((td = *tdp) != NULL && td->td_version >= 0)
+ {
+ do
+ {
+ if (sipIsRangeEnabled(em, td->td_version))
+ {
+ /* Update the type with the enabled version. */
+ *tdp = td;
+ break;
+ }
+ }
+ while ((td = td->td_next_version) != NULL);
+
+ /*
+ * If there is no enabled version then stub the disabled version
+ * so that we don't lose the name from the (sorted) types table.
+ */
+ if (td == NULL)
+ sipTypeSetStub(*tdp);
+ }
+ }
+
+ return 0;
+}
+
+
+/*
+ * Get the version number for an API.
+ */
+PyObject *sipGetAPI(PyObject *self, PyObject *args)
+{
+ const char *api;
+ const apiVersionDef *avd;
+
+ if (!PyArg_ParseTuple(args, "s:getapi", &api))
+ return NULL;
+
+ if ((avd = find_api(api)) == NULL)
+ {
+ PyErr_Format(PyExc_ValueError, "unknown API '%s'", api);
+ return NULL;
+ }
+
+#if PY_MAJOR_VERSION >= 3
+ return PyLong_FromLong(avd->version_nr);
+#else
+ return PyInt_FromLong(avd->version_nr);
+#endif
+}
+
+
+/*
+ * Set the version number for an API.
+ */
+PyObject *sipSetAPI(PyObject *self, PyObject *args)
+{
+ const char *api;
+ int version_nr;
+ const apiVersionDef *avd;
+
+ if (!PyArg_ParseTuple(args, "si:setapi", &api, &version_nr))
+ return NULL;
+
+ if (version_nr < 1)
+ {
+ PyErr_Format(PyExc_ValueError,
+ "API version numbers must be greater or equal to 1, not %d",
+ version_nr);
+ return NULL;
+ }
+
+ if ((avd = find_api(api)) == NULL)
+ {
+ char *api_copy;
+
+ /* Make a deep copy of the name. */
+ if ((api_copy = sip_api_malloc(strlen(api) + 1)) == NULL)
+ return NULL;
+
+ strcpy(api_copy, api);
+
+ if (add_api(api_copy, version_nr) < 0)
+ return NULL;
+ }
+ else if (avd->version_nr != version_nr)
+ {
+ PyErr_Format(PyExc_ValueError,
+ "API '%s' has already been set to version %d", api,
+ avd->version_nr);
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+/*
+ * Add a new API to the global list returning a negative value on error.
+ */
+static int add_api(const char *api, int version_nr)
+{
+ apiVersionDef *avd;
+
+ if ((avd = sip_api_malloc(sizeof (apiVersionDef))) == NULL)
+ return -1;
+
+ avd->api_name = api;
+ avd->version_nr = version_nr;
+ avd->next = api_versions;
+
+ api_versions = avd;
+
+ return 0;
+}
+
+
+/*
+ * Return the definition for the given API, or NULL if there was none.
+ */
+static apiVersionDef *find_api(const char *api)
+{
+ apiVersionDef *avd;
+
+ for (avd = api_versions; avd != NULL; avd = avd->next)
+ if (strcmp(avd->api_name, api) == 0)
+ break;
+
+ return avd;
+}
+
+
+/*
+ * Return TRUE if a range defined by a range index is enabled.
+ */
+int sipIsRangeEnabled(sipExportedModuleDef *em, int range_index)
+{
+ int *range = &em->em_versions[range_index * 3];
+ const char *api_name = sipNameFromPool(em, range[0]);
+
+ return sip_api_is_api_enabled(api_name, range[1], range[2]);
+}
diff --git a/siplib/bool.cpp b/siplib/bool.cpp
new file mode 100644
index 0000000..8936287
--- /dev/null
+++ b/siplib/bool.cpp
@@ -0,0 +1,22 @@
+// This contains all the C++ code that is needed by the sip module.
+//
+// Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com>
+//
+// This file is part of SIP.
+//
+// This copy of SIP is licensed for use under the terms of the SIP License
+// Agreement. See the file LICENSE for more details.
+//
+// This copy of SIP may also used under the terms of the GNU General Public
+// License v2 or v3 as published by the Free Software Foundation which can be
+// found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
+//
+// SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+
+// Set a C++ bool for the main C implementation of the module.
+extern "C" void sipSetBool(void *ptr, int val)
+{
+ *reinterpret_cast<bool *>(ptr) = val;
+}
diff --git a/siplib/descriptors.c b/siplib/descriptors.c
new file mode 100644
index 0000000..29277c5
--- /dev/null
+++ b/siplib/descriptors.c
@@ -0,0 +1,305 @@
+/*
+ * The implementation of the different descriptors.
+ *
+ * Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com>
+ *
+ * This file is part of SIP.
+ *
+ * This copy of SIP is licensed for use under the terms of the SIP License
+ * Agreement. See the file LICENSE for more details.
+ *
+ * This copy of SIP may also used under the terms of the GNU General Public
+ * License v2 or v3 as published by the Free Software Foundation which can be
+ * found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
+ *
+ * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#include <Python.h>
+
+#include "sip.h"
+#include "sipint.h"
+
+
+/*****************************************************************************
+ * A method descriptor. We don't use the similar Python descriptor because it
+ * doesn't support a method having static and non-static overloads.
+ *****************************************************************************/
+
+
+/* Forward declarations of slots. */
+static PyObject *sipMethodDescr_descr_get(PyObject *self, PyObject *obj,
+ PyObject *type);
+static PyObject *sipMethodDescr_repr(PyObject *self);
+
+
+/*
+ * The object data structure.
+ */
+typedef struct _sipMethodDescr {
+ PyObject_HEAD
+
+ /* The method definition. */
+ PyMethodDef *pmd;
+} sipMethodDescr;
+
+
+/*
+ * The type data structure.
+ */
+PyTypeObject sipMethodDescr_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "sip.methoddescriptor", /* tp_name */
+ sizeof (sipMethodDescr), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ sipMethodDescr_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ sipMethodDescr_descr_get, /* tp_descr_get */
+};
+
+
+/*
+ * Return a new method descriptor for the given method.
+ */
+PyObject *sipMethodDescr_New(PyMethodDef *pmd)
+{
+ PyObject *descr = PyType_GenericAlloc(&sipMethodDescr_Type, 0);
+
+ if (descr != NULL)
+ ((sipMethodDescr *)descr)->pmd = pmd;
+
+ return descr;
+}
+
+
+/*
+ * The descriptor's descriptor get slot.
+ */
+static PyObject *sipMethodDescr_descr_get(PyObject *self, PyObject *obj,
+ PyObject *type)
+{
+ sipMethodDescr *md = (sipMethodDescr *)self;
+
+ if (obj == Py_None)
+ obj = NULL;
+
+ return PyCFunction_New(md->pmd, obj);
+}
+
+
+/*
+ * The descriptor's repr slot. This is for the benefit of cProfile which seems
+ * to determine attribute names differently to the rest of Python.
+ */
+static PyObject *sipMethodDescr_repr(PyObject *self)
+{
+ sipMethodDescr *md = (sipMethodDescr *)self;
+
+ return
+#if PY_MAJOR_VERSION >= 3
+ PyUnicode_FromFormat
+#else
+ PyString_FromFormat
+#endif
+ ("<built-in method %s>", md->pmd->ml_name);
+}
+
+
+/*****************************************************************************
+ * A variable descriptor. We don't use the similar Python descriptor because
+ * it doesn't support static variables.
+ *****************************************************************************/
+
+
+/* Forward declarations of slots. */
+static PyObject *sipVariableDescr_descr_get(PyObject *self, PyObject *obj,
+ PyObject *type);
+static int sipVariableDescr_descr_set(PyObject *self, PyObject *obj,
+ PyObject *value);
+
+
+/*
+ * The object data structure.
+ */
+typedef struct _sipVariableDescr {
+ PyObject_HEAD
+
+ /* The getter/setter definition. */
+ sipVariableDef *vd;
+
+ /* The generated type definition. */
+ const sipTypeDef *td;
+
+ /* The generated container definition. */
+ const sipContainerDef *cod;
+} sipVariableDescr;
+
+
+/*
+ * The type data structure.
+ */
+PyTypeObject sipVariableDescr_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "sip.variabledescriptor", /* tp_name */
+ sizeof (sipVariableDescr), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ sipVariableDescr_descr_get, /* tp_descr_get */
+ sipVariableDescr_descr_set, /* tp_descr_set */
+};
+
+
+/* Forward declarations. */
+static int get_instance_address(sipVariableDescr *vd, PyObject *obj,
+ void **addrp);
+
+
+/*
+ * Return a new method descriptor for the given getter/setter.
+ */
+PyObject *sipVariableDescr_New(sipVariableDef *vd, const sipTypeDef *td,
+ const sipContainerDef *cod)
+{
+ PyObject *descr = PyType_GenericAlloc(&sipVariableDescr_Type, 0);
+
+ if (descr != NULL)
+ {
+ ((sipVariableDescr *)descr)->vd = vd;
+ ((sipVariableDescr *)descr)->td = td;
+ ((sipVariableDescr *)descr)->cod = cod;
+ }
+
+ return descr;
+}
+
+
+/*
+ * The descriptor's descriptor get slot.
+ */
+static PyObject *sipVariableDescr_descr_get(PyObject *self, PyObject *obj,
+ PyObject *type)
+{
+ sipVariableDescr *vd = (sipVariableDescr *)self;
+ void *addr;
+
+ if (get_instance_address(vd, obj, &addr) < 0)
+ return NULL;
+
+ return vd->vd->vd_getter(addr, type);
+}
+
+
+/*
+ * The descriptor's descriptor set slot.
+ */
+static int sipVariableDescr_descr_set(PyObject *self, PyObject *obj,
+ PyObject *value)
+{
+ sipVariableDescr *vd = (sipVariableDescr *)self;
+ void *addr;
+
+ /* Check that the value isn't const. */
+ if (vd->vd->vd_setter == NULL)
+ {
+ PyErr_Format(PyExc_AttributeError,
+ "'%s' object attribute '%s' is read-only",
+ sipPyNameOfContainer(vd->cod, vd->td), vd->vd->vd_name);
+
+ return -1;
+ }
+
+ if (get_instance_address(vd, obj, &addr) < 0)
+ return -1;
+
+ return vd->vd->vd_setter(addr, value, obj);
+}
+
+
+/*
+ * Return the C/C++ address of any instance.
+ */
+static int get_instance_address(sipVariableDescr *vd, PyObject *obj,
+ void **addrp)
+{
+ void *addr;
+
+ if (vd->vd->vd_is_static)
+ {
+ addr = NULL;
+ }
+ else
+ {
+ /* Check that access was via an instance. */
+ if (obj == NULL || obj == Py_None)
+ {
+ PyErr_Format(PyExc_AttributeError,
+ "'%s' object attribute '%s' is an instance attribute",
+ sipPyNameOfContainer(vd->cod, vd->td), vd->vd->vd_name);
+
+ return -1;
+ }
+
+ /* Get the C++ instance. */
+ if ((addr = sip_api_get_cpp_ptr((sipSimpleWrapper *)obj, vd->td)) == NULL)
+ return -1;
+ }
+
+ *addrp = addr;
+
+ return 0;
+}
diff --git a/siplib/objmap.c b/siplib/objmap.c
new file mode 100644
index 0000000..f9c196d
--- /dev/null
+++ b/siplib/objmap.c
@@ -0,0 +1,282 @@
+/*
+ * This module implements a hash table class for mapping C/C++ addresses to the
+ * corresponding wrapped Python object.
+ *
+ * Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com>
+ *
+ * This file is part of SIP.
+ *
+ * This copy of SIP is licensed for use under the terms of the SIP License
+ * Agreement. See the file LICENSE for more details.
+ *
+ * This copy of SIP may also used under the terms of the GNU General Public
+ * License v2 or v3 as published by the Free Software Foundation which can be
+ * found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
+ *
+ * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#include <string.h>
+
+#include "sip.h"
+#include "sipint.h"
+
+
+#define hash_1(k,s) (((unsigned long)(k)) % (s))
+#define hash_2(k,s) ((s) - 2 - (hash_1((k),(s)) % ((s) - 2)))
+
+
+/* Prime numbers to use as hash table sizes. */
+static unsigned long hash_primes[] = {
+ 521, 1031, 2053, 4099,
+ 8209, 16411, 32771, 65537, 131101, 262147,
+ 524309, 1048583, 2097169, 4194319, 8388617, 16777259,
+ 33554467, 67108879, 134217757, 268435459, 536870923, 1073741827,
+ 2147483659U,0
+};
+
+
+static sipHashEntry *newHashTable(unsigned long);
+static sipHashEntry *findHashEntry(sipObjectMap *,void *);
+static void reorganiseMap(sipObjectMap *om);
+
+
+/*
+ * Initialise an object map.
+ */
+void sipOMInit(sipObjectMap *om)
+{
+ om -> primeIdx = 0;
+ om -> unused = om -> size = hash_primes[om -> primeIdx];
+ om -> stale = 0;
+ om -> hash_array = newHashTable(om -> size);
+}
+
+
+/*
+ * Finalise an object map.
+ */
+void sipOMFinalise(sipObjectMap *om)
+{
+ sip_api_free(om -> hash_array);
+}
+
+
+/*
+ * Allocate and initialise a new hash table.
+ */
+static sipHashEntry *newHashTable(unsigned long size)
+{
+ size_t nbytes;
+ sipHashEntry *hashtab;
+
+ nbytes = sizeof (sipHashEntry) * size;
+
+ if ((hashtab = (sipHashEntry *)sip_api_malloc(nbytes)) != NULL)
+ memset(hashtab,0,nbytes);
+
+ return hashtab;
+}
+
+
+/*
+ * Return a pointer to the hash entry that is used, or should be used, for the
+ * given C/C++ address.
+ */
+static sipHashEntry *findHashEntry(sipObjectMap *om,void *key)
+{
+ unsigned long hash, inc;
+ void *hek;
+
+ hash = hash_1(key,om -> size);
+ inc = hash_2(key,om -> size);
+
+ while ((hek = om -> hash_array[hash].key) != NULL && hek != key)
+ hash = (hash + inc) % om -> size;
+
+ return &om -> hash_array[hash];
+}
+
+
+/*
+ * Return the wrapped Python object of a specific type for a C/C++ address or
+ * NULL if it wasn't found.
+ */
+sipSimpleWrapper *sipOMFindObject(sipObjectMap *om, void *key,
+ const sipTypeDef *td)
+{
+ sipHashEntry *he = findHashEntry(om, key);
+ sipSimpleWrapper *sw;
+ PyTypeObject *py_type = sipTypeAsPyTypeObject(td);
+
+ /* Go through each wrapped object at this address. */
+ for (sw = he->first; sw != NULL; sw = sw->next)
+ {
+ /*
+ * If the reference count is 0 then it is in the process of being
+ * deleted, so ignore it. It's not completely clear how this can
+ * happen (but it can) because it implies that the garbage collection
+ * code is being re-entered (and there are guards in place to prevent
+ * this).
+ */
+ if (Py_REFCNT(sw) == 0)
+ continue;
+
+ /*
+ * If this wrapped object is of the given type, or a sub-type of it,
+ * then we assume it is the same C++ object.
+ */
+ if (PyObject_TypeCheck(sw, py_type))
+ return sw;
+ }
+
+ return NULL;
+}
+
+
+/*
+ * Add a C/C++ address and the corresponding wrapped Python object to the map.
+ */
+void sipOMAddObject(sipObjectMap *om, sipSimpleWrapper *val)
+{
+ sipHashEntry *he = findHashEntry(om, val->u.cppPtr);
+
+ /*
+ * If the bucket is in use then we appear to have several objects at the
+ * same address.
+ */
+ if (he -> first != NULL)
+ {
+ /*
+ * This can happen for three reasons. A variable of one class can be
+ * declared at the start of another class. Therefore there are two
+ * objects, of different classes, with the same address. The second
+ * reason is that the old C/C++ object has been deleted by C/C++ but we
+ * didn't get to find out for some reason, and a new C/C++ instance has
+ * been created at the same address. The third reason is if we are in
+ * the process of deleting a Python object but the C++ object gets
+ * wrapped again because the C++ dtor called a method that has been
+ * re-implemented in Python. The absence of the SIP_SHARE_MAP flag
+ * tells us that a new C++ instance has just been created and so we
+ * know the second reason is the correct one so we mark the old
+ * pointers as invalid and reuse the entry. Otherwise we just add this
+ * one to the existing list of objects at this address.
+ */
+ if (!(val->flags & SIP_SHARE_MAP))
+ {
+ sipSimpleWrapper *sw = he->first;
+
+ he->first = NULL;
+
+ while (sw != NULL)
+ {
+ sipSimpleWrapper *next = sw->next;
+
+ /* We are removing it from the map here. */
+ sipSetNotInMap(sw);
+ sip_api_common_dtor(sw);
+
+ sw = next;
+ }
+ }
+
+ val->next = he->first;
+ he->first = val;
+
+ return;
+ }
+
+ /* See if the bucket was unused or stale. */
+ if (he->key == NULL)
+ {
+ he->key = val -> u.cppPtr;
+ om->unused--;
+ }
+ else
+ om->stale--;
+
+ /* Add the rest of the new value. */
+ he->first = val;
+ val->next = NULL;
+
+ reorganiseMap(om);
+}
+
+
+/*
+ * Reorganise a map if it is running short of space.
+ */
+static void reorganiseMap(sipObjectMap *om)
+{
+ unsigned long old_size, i;
+ sipHashEntry *ohe, *old_tab;
+
+ /* Don't bother if it still has more than 12% available. */
+ if (om -> unused > om -> size >> 3)
+ return;
+
+ /*
+ * If reorganising (ie. making the stale buckets unused) using the same
+ * sized table would make 25% available then do that. Otherwise use a
+ * bigger table (if possible).
+ */
+ if (om -> unused + om -> stale < om -> size >> 2 && hash_primes[om -> primeIdx + 1] != 0)
+ om -> primeIdx++;
+
+ old_size = om -> size;
+ old_tab = om -> hash_array;
+
+ om -> unused = om -> size = hash_primes[om -> primeIdx];
+ om -> stale = 0;
+ om -> hash_array = newHashTable(om -> size);
+
+ /* Transfer the entries from the old table to the new one. */
+ ohe = old_tab;
+
+ for (i = 0; i < old_size; ++i)
+ {
+ if (ohe -> key != NULL && ohe -> first != NULL)
+ {
+ *findHashEntry(om,ohe -> key) = *ohe;
+ om -> unused--;
+ }
+
+ ++ohe;
+ }
+
+ sip_api_free(old_tab);
+}
+
+
+/*
+ * Remove a C/C++ object from the table. Return 0 if it was removed
+ * successfully.
+ */
+int sipOMRemoveObject(sipObjectMap *om, sipSimpleWrapper *val)
+{
+ sipHashEntry *he = findHashEntry(om, val->u.cppPtr);
+ sipSimpleWrapper **swp;
+
+ for (swp = &he->first; *swp != NULL; swp = &(*swp)->next)
+ if (*swp == val)
+ {
+ *swp = val->next;
+
+ /*
+ * If the bucket is now empty then count it as stale. Note that we
+ * do not NULL the key and count it as unused because that might
+ * throw out the search for another entry that wanted to go here,
+ * found it already occupied, and was put somewhere else. In other
+ * words, searches must be repeatable until we reorganise the
+ * table.
+ */
+ if (he->first == NULL)
+ om->stale++;
+
+ return 0;
+ }
+
+ return -1;
+}
diff --git a/siplib/qtlib.c b/siplib/qtlib.c
new file mode 100644
index 0000000..ca0817a
--- /dev/null
+++ b/siplib/qtlib.c
@@ -0,0 +1,659 @@
+/*
+ * The SIP library code that implements the interface to the optional module
+ * supplied Qt support.
+ *
+ * Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com>
+ *
+ * This file is part of SIP.
+ *
+ * This copy of SIP is licensed for use under the terms of the SIP License
+ * Agreement. See the file LICENSE for more details.
+ *
+ * This copy of SIP may also used under the terms of the GNU General Public
+ * License v2 or v3 as published by the Free Software Foundation which can be
+ * found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
+ *
+ * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#include <Python.h>
+#include <assert.h>
+#include <string.h>
+
+#include "sip.h"
+#include "sipint.h"
+
+
+/* This is how Qt "types" signals and slots. */
+#define isQtSlot(s) (*(s) == '1')
+#define isQtSignal(s) (*(s) == '2')
+
+
+static PyObject *getWeakRef(PyObject *obj);
+static char *sipStrdup(const char *);
+static void *createUniversalSlot(sipWrapper *txSelf, const char *sig,
+ PyObject *rxObj, const char *slot, const char **member, int flags);
+static void *findSignal(void *txrx, const char **sig);
+static void *newSignal(void *txrx, const char **sig);
+
+
+/*
+ * Find an existing signal.
+ */
+static void *findSignal(void *txrx, const char **sig)
+{
+ if (sipQtSupport->qt_find_universal_signal != NULL)
+ txrx = sipQtSupport->qt_find_universal_signal(txrx, sig);
+
+ return txrx;
+}
+
+
+/*
+ * Return a usable signal, creating a new universal signal if needed.
+ */
+static void *newSignal(void *txrx, const char **sig)
+{
+ void *new_txrx = findSignal(txrx, sig);
+
+ if (new_txrx == NULL && sipQtSupport->qt_create_universal_signal != NULL)
+ new_txrx = sipQtSupport->qt_create_universal_signal(txrx, sig);
+
+ return new_txrx;
+}
+
+
+/*
+ * Create a universal slot. Returns a pointer to it or 0 if there was an
+ * error.
+ */
+static void *createUniversalSlot(sipWrapper *txSelf, const char *sig,
+ PyObject *rxObj, const char *slot, const char **member, int flags)
+{
+ void *us = sipQtSupport->qt_create_universal_slot(txSelf, sig, rxObj, slot,
+ member, flags);
+
+ if (us && txSelf)
+ sipSetPossibleProxy((sipSimpleWrapper *)txSelf);
+
+ return us;
+}
+
+
+/*
+ * Invoke a single slot (Qt or Python) and return the result.
+ */
+PyObject *sip_api_invoke_slot(const sipSlot *slot, PyObject *sigargs)
+{
+ PyObject *sa, *oxtype, *oxvalue, *oxtb, *sfunc, *sref;
+
+ /* Keep some compilers quiet. */
+ oxtype = oxvalue = oxtb = NULL;
+
+ /* Fan out Qt signals. (Only PyQt3 will do this.) */
+ if (slot->name != NULL && slot->name[0] != '\0')
+ {
+ assert(sipQtSupport->qt_emit_signal);
+
+ if (sipQtSupport->qt_emit_signal(slot->pyobj, slot->name, sigargs) < 0)
+ return NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ /* Get the object to call, resolving any weak references. */
+ if (slot->weakSlot == Py_True)
+ {
+ /*
+ * The slot is guaranteed to be Ok because it has an extra reference or
+ * is None.
+ */
+ sref = slot->pyobj;
+ Py_INCREF(sref);
+ }
+ else if (slot -> weakSlot == NULL)
+ sref = NULL;
+ else if ((sref = PyWeakref_GetObject(slot -> weakSlot)) == NULL)
+ return NULL;
+ else
+ Py_INCREF(sref);
+
+ if (sref == Py_None)
+ {
+ /*
+ * If the real object has gone then we pretend everything is Ok. This
+ * mimics the Qt behaviour of not caring if a receiving object has been
+ * deleted.
+ */
+ Py_DECREF(sref);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ if (slot -> pyobj == NULL)
+ {
+ PyObject *self = (sref != NULL ? sref : slot->meth.mself);
+
+ /*
+ * If the receiver wraps a C++ object then ignore the call if it no
+ * longer exists.
+ */
+ if (PyObject_TypeCheck(self, (PyTypeObject *)&sipSimpleWrapper_Type) &&
+ sipGetAddress(self) == NULL)
+ {
+ Py_XDECREF(sref);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+#if PY_MAJOR_VERSION >= 3
+ sfunc = PyMethod_New(slot->meth.mfunc, self);
+#else
+ sfunc = PyMethod_New(slot->meth.mfunc, self, slot->meth.mclass);
+#endif
+
+ if (sfunc == NULL)
+ {
+ Py_XDECREF(sref);
+ return NULL;
+ }
+ }
+ else if (slot -> name != NULL)
+ {
+ char *mname = slot -> name + 1;
+ PyObject *self = (sref != NULL ? sref : slot->pyobj);
+
+ if ((sfunc = PyObject_GetAttrString(self, mname)) == NULL || !PyCFunction_Check(sfunc))
+ {
+ /*
+ * Note that in earlier versions of SIP this error would be
+ * detected when the slot was connected.
+ */
+ PyErr_Format(PyExc_NameError,"Invalid slot %s",mname);
+
+ Py_XDECREF(sfunc);
+ Py_XDECREF(sref);
+ return NULL;
+ }
+ }
+ else
+ {
+ sfunc = slot->pyobj;
+ Py_INCREF(sfunc);
+ }
+
+ /*
+ * We make repeated attempts to call a slot. If we work out that it failed
+ * because of an immediate type error we try again with one less argument.
+ * We keep going until we run out of arguments to drop. This emulates the
+ * Qt ability of the slot to accept fewer arguments than a signal provides.
+ */
+ sa = sigargs;
+ Py_INCREF(sa);
+
+ for (;;)
+ {
+ PyObject *nsa, *xtype, *xvalue, *xtb, *resobj;
+
+ if ((resobj = PyEval_CallObject(sfunc, sa)) != NULL)
+ {
+ Py_DECREF(sfunc);
+ Py_XDECREF(sref);
+
+ /* Remove any previous exception. */
+
+ if (sa != sigargs)
+ {
+ Py_XDECREF(oxtype);
+ Py_XDECREF(oxvalue);
+ Py_XDECREF(oxtb);
+ PyErr_Clear();
+ }
+
+ Py_DECREF(sa);
+
+ return resobj;
+ }
+
+ /* Get the exception. */
+ PyErr_Fetch(&xtype,&xvalue,&xtb);
+
+ /*
+ * See if it is unacceptable. An acceptable failure is a type error
+ * with no traceback - so long as we can still reduce the number of
+ * arguments and try again.
+ */
+ if (!PyErr_GivenExceptionMatches(xtype,PyExc_TypeError) ||
+ xtb != NULL ||
+ PyTuple_GET_SIZE(sa) == 0)
+ {
+ /*
+ * If there is a traceback then we must have called the slot and
+ * the exception was later on - so report the exception as is.
+ */
+ if (xtb != NULL)
+ {
+ if (sa != sigargs)
+ {
+ Py_XDECREF(oxtype);
+ Py_XDECREF(oxvalue);
+ Py_XDECREF(oxtb);
+ }
+
+ PyErr_Restore(xtype,xvalue,xtb);
+ }
+ else if (sa == sigargs)
+ PyErr_Restore(xtype,xvalue,xtb);
+ else
+ {
+ /*
+ * Discard the latest exception and restore the original one.
+ */
+ Py_XDECREF(xtype);
+ Py_XDECREF(xvalue);
+ Py_XDECREF(xtb);
+
+ PyErr_Restore(oxtype,oxvalue,oxtb);
+ }
+
+ break;
+ }
+
+ /* If this is the first attempt, save the exception. */
+ if (sa == sigargs)
+ {
+ oxtype = xtype;
+ oxvalue = xvalue;
+ oxtb = xtb;
+ }
+ else
+ {
+ Py_XDECREF(xtype);
+ Py_XDECREF(xvalue);
+ Py_XDECREF(xtb);
+ }
+
+ /* Create the new argument tuple. */
+ if ((nsa = PyTuple_GetSlice(sa,0,PyTuple_GET_SIZE(sa) - 1)) == NULL)
+ {
+ /* Tidy up. */
+ Py_XDECREF(oxtype);
+ Py_XDECREF(oxvalue);
+ Py_XDECREF(oxtb);
+
+ break;
+ }
+
+ Py_DECREF(sa);
+ sa = nsa;
+ }
+
+ Py_DECREF(sfunc);
+ Py_XDECREF(sref);
+
+ Py_DECREF(sa);
+
+ return NULL;
+}
+
+
+/*
+ * Compare two slots to see if they are the same.
+ */
+int sip_api_same_slot(const sipSlot *sp, PyObject *rxObj, const char *slot)
+{
+ /* See if they are signals or Qt slots, ie. they have a name. */
+ if (slot != NULL)
+ {
+ if (sp->name == NULL || sp->name[0] == '\0')
+ return 0;
+
+ return (sipQtSupport->qt_same_name(sp->name, slot) && sp->pyobj == rxObj);
+ }
+
+ /* See if they are pure Python methods. */
+ if (PyMethod_Check(rxObj))
+ {
+ if (sp->pyobj != NULL)
+ return 0;
+
+ return (sp->meth.mfunc == PyMethod_GET_FUNCTION(rxObj)
+ && sp->meth.mself == PyMethod_GET_SELF(rxObj)
+#if PY_MAJOR_VERSION < 3
+ && sp->meth.mclass == PyMethod_GET_CLASS(rxObj)
+#endif
+ );
+ }
+
+ /* See if they are wrapped C++ methods. */
+ if (PyCFunction_Check(rxObj))
+ {
+ if (sp->name == NULL || sp->name[0] != '\0')
+ return 0;
+
+ return (sp->pyobj == PyCFunction_GET_SELF(rxObj) &&
+ strcmp(&sp->name[1], ((PyCFunctionObject *)rxObj)->m_ml->ml_name) == 0);
+ }
+
+ /* The objects must be the same. */
+ return (sp->pyobj == rxObj);
+}
+
+
+/*
+ * Convert a valid Python signal or slot to an existing universal slot.
+ */
+void *sipGetRx(sipSimpleWrapper *txSelf, const char *sigargs, PyObject *rxObj,
+ const char *slot, const char **memberp)
+{
+ if (slot != NULL)
+ if (isQtSlot(slot) || isQtSignal(slot))
+ {
+ void *rx;
+
+ *memberp = slot;
+
+ if ((rx = sip_api_get_cpp_ptr((sipSimpleWrapper *)rxObj, sipQObjectType)) == NULL)
+ return NULL;
+
+ if (isQtSignal(slot))
+ rx = findSignal(rx, memberp);
+
+ return rx;
+ }
+
+ /*
+ * The slot was either a Python callable or PyQt3 Python signal so there
+ * should be a universal slot.
+ */
+ return sipQtSupport->qt_find_slot(sipGetAddress(txSelf), sigargs, rxObj, slot, memberp);
+}
+
+
+/*
+ * Convert a Python receiver (either a Python signal or slot or a Qt signal or
+ * slot) to a Qt receiver. It is only ever called when the signal is a Qt
+ * signal. Return NULL is there was an error.
+ */
+void *sip_api_convert_rx(sipWrapper *txSelf, const char *sigargs,
+ PyObject *rxObj, const char *slot, const char **memberp, int flags)
+{
+ if (slot == NULL)
+ return createUniversalSlot(txSelf, sigargs, rxObj, NULL, memberp, flags);
+
+ if (isQtSlot(slot) || isQtSignal(slot))
+ {
+ void *rx;
+
+ *memberp = slot;
+
+ if ((rx = sip_api_get_cpp_ptr((sipSimpleWrapper *)rxObj, sipQObjectType)) == NULL)
+ return NULL;
+
+ if (isQtSignal(slot))
+ rx = newSignal(rx, memberp);
+
+ return rx;
+ }
+
+ /* The slot is a Python signal so we need a universal slot to catch it. */
+ return createUniversalSlot(txSelf, sigargs, rxObj, slot, memberp, 0);
+}
+
+
+/*
+ * Connect a Qt signal or a Python signal to a Qt slot, a Qt signal, a Python
+ * slot or a Python signal. This is all possible combinations.
+ */
+PyObject *sip_api_connect_rx(PyObject *txObj, const char *sig, PyObject *rxObj,
+ const char *slot, int type)
+{
+ /* Handle Qt signals. */
+ if (isQtSignal(sig))
+ {
+ void *tx, *rx;
+ const char *member, *real_sig;
+ int res;
+
+ if ((tx = sip_api_get_cpp_ptr((sipSimpleWrapper *)txObj, sipQObjectType)) == NULL)
+ return NULL;
+
+ real_sig = sig;
+
+ if ((tx = newSignal(tx, &real_sig)) == NULL)
+ return NULL;
+
+ if ((rx = sip_api_convert_rx((sipWrapper *)txObj, sig, rxObj, slot, &member, 0)) == NULL)
+ return NULL;
+
+ res = sipQtSupport->qt_connect(tx, real_sig, rx, member, type);
+
+ return PyBool_FromLong(res);
+ }
+
+ /* Handle Python signals. Only PyQt3 will get this far. */
+ assert(sipQtSupport->qt_connect_py_signal);
+
+ if (sipQtSupport->qt_connect_py_signal(txObj, sig, rxObj, slot) < 0)
+ return NULL;
+
+ Py_INCREF(Py_True);
+ return Py_True;
+}
+
+
+/*
+ * Disconnect a signal to a signal or a Qt slot.
+ */
+PyObject *sip_api_disconnect_rx(PyObject *txObj,const char *sig,
+ PyObject *rxObj,const char *slot)
+{
+ /* Handle Qt signals. */
+ if (isQtSignal(sig))
+ {
+ sipSimpleWrapper *txSelf = (sipSimpleWrapper *)txObj;
+ void *tx, *rx;
+ const char *member;
+ int res;
+
+ if ((tx = sip_api_get_cpp_ptr(txSelf, sipQObjectType)) == NULL)
+ return NULL;
+
+ if ((rx = sipGetRx(txSelf, sig, rxObj, slot, &member)) == NULL)
+ {
+ Py_INCREF(Py_False);
+ return Py_False;
+ }
+
+ /* Handle Python signals. */
+ tx = findSignal(tx, &sig);
+
+ res = sipQtSupport->qt_disconnect(tx, sig, rx, member);
+
+ /*
+ * Delete it if it is a universal slot as this will be it's only
+ * connection. If the slot is actually a universal signal then it
+ * should leave it in place.
+ */
+ sipQtSupport->qt_destroy_universal_slot(rx);
+
+ return PyBool_FromLong(res);
+ }
+
+ /* Handle Python signals. Only PyQt3 will get this far. */
+ assert(sipQtSupport->qt_disconnect_py_signal);
+
+ sipQtSupport->qt_disconnect_py_signal(txObj, sig, rxObj, slot);
+
+ Py_INCREF(Py_True);
+ return Py_True;
+}
+
+
+/*
+ * Free the resources of a slot.
+ */
+void sip_api_free_sipslot(sipSlot *slot)
+{
+ if (slot->name != NULL)
+ {
+ sip_api_free(slot->name);
+ }
+ else if (slot->weakSlot == Py_True)
+ {
+ Py_DECREF(slot->pyobj);
+ }
+
+ /* Remove any weak reference. */
+ Py_XDECREF(slot->weakSlot);
+}
+
+
+/*
+ * Implement strdup() using sip_api_malloc().
+ */
+static char *sipStrdup(const char *s)
+{
+ char *d;
+
+ if ((d = (char *)sip_api_malloc(strlen(s) + 1)) != NULL)
+ strcpy(d,s);
+
+ return d;
+}
+
+
+/*
+ * Initialise a slot, returning 0 if there was no error. If the signal was a
+ * Qt signal, then the slot may be a Python signal or a Python slot. If the
+ * signal was a Python signal, then the slot may be anything.
+ */
+int sip_api_save_slot(sipSlot *sp, PyObject *rxObj, const char *slot)
+{
+ sp -> weakSlot = NULL;
+
+ if (slot == NULL)
+ {
+ sp -> name = NULL;
+
+ if (PyMethod_Check(rxObj))
+ {
+ /*
+ * Python creates methods on the fly. We could increment the
+ * reference count to keep it alive, but that would keep "self"
+ * alive as well and would probably be a circular reference.
+ * Instead we remember the component parts and hope they are still
+ * valid when we re-create the method when we need it.
+ */
+ sipSaveMethod(&sp -> meth,rxObj);
+
+ /* Notice if the class instance disappears. */
+ sp -> weakSlot = getWeakRef(sp -> meth.mself);
+
+ /* This acts a flag to say that the slot is a method. */
+ sp -> pyobj = NULL;
+ }
+ else
+ {
+ PyObject *self;
+
+ /*
+ * We know that it is another type of callable, ie. a
+ * function/builtin.
+ */
+
+ if (PyCFunction_Check(rxObj) &&
+ (self = PyCFunction_GET_SELF(rxObj)) != NULL &&
+ PyObject_TypeCheck(self, (PyTypeObject *)&sipSimpleWrapper_Type))
+ {
+ /*
+ * It is a wrapped C++ class method. We can't keep a copy
+ * because they are generated on the fly and we can't take a
+ * reference as that may keep the instance (ie. self) alive.
+ * We therefore treat it as if the user had specified the slot
+ * at "obj, SLOT('meth()')" rather than "obj.meth" (see below).
+ */
+
+ const char *meth;
+
+ /* Get the method name. */
+ meth = ((PyCFunctionObject *)rxObj) -> m_ml -> ml_name;
+
+ if ((sp -> name = (char *)sip_api_malloc(strlen(meth) + 2)) == NULL)
+ return -1;
+
+ /*
+ * Copy the name and set the marker that it needs converting to
+ * a built-in method.
+ */
+ sp -> name[0] = '\0';
+ strcpy(&sp -> name[1],meth);
+
+ sp -> pyobj = self;
+ sp -> weakSlot = getWeakRef(self);
+ }
+ else
+ {
+ /*
+ * Give the slot an extra reference to keep it alive and
+ * remember we have done so by treating weakSlot specially.
+ */
+ Py_INCREF(rxObj);
+ sp->pyobj = rxObj;
+
+ Py_INCREF(Py_True);
+ sp->weakSlot = Py_True;
+ }
+ }
+ }
+ else if ((sp -> name = sipStrdup(slot)) == NULL)
+ return -1;
+ else if (isQtSlot(slot))
+ {
+ /*
+ * The user has decided to connect a Python signal to a Qt slot and
+ * specified the slot as "obj, SLOT('meth()')" rather than "obj.meth".
+ */
+
+ char *tail;
+
+ /* Remove any arguments. */
+ if ((tail = strchr(sp -> name,'(')) != NULL)
+ *tail = '\0';
+
+ /*
+ * A bit of a hack to indicate that this needs converting to a built-in
+ * method.
+ */
+ sp -> name[0] = '\0';
+
+ /* Notice if the class instance disappears. */
+ sp -> weakSlot = getWeakRef(rxObj);
+
+ sp -> pyobj = rxObj;
+ }
+ else
+ /* It's a Qt signal. */
+ sp -> pyobj = rxObj;
+
+ return 0;
+}
+
+
+/*
+ * Return a weak reference to the given object.
+ */
+static PyObject *getWeakRef(PyObject *obj)
+{
+ PyObject *wr;
+
+ if ((wr = PyWeakref_NewRef(obj,NULL)) == NULL)
+ PyErr_Clear();
+
+ return wr;
+}
diff --git a/siplib/sip.h b/siplib/sip.h
new file mode 100644
index 0000000..b22b77c
--- /dev/null
+++ b/siplib/sip.h
@@ -0,0 +1,1587 @@
+/*
+ * The SIP module interface.
+ *
+ * Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com>
+ *
+ * This file is part of SIP.
+ *
+ * This copy of SIP is licensed for use under the terms of the SIP License
+ * Agreement. See the file LICENSE for more details.
+ *
+ * This copy of SIP may also used under the terms of the GNU General Public
+ * License v2 or v3 as published by the Free Software Foundation which can be
+ * found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
+ *
+ * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#ifndef _SIP_H
+#define _SIP_H
+
+
+/*
+ * This gets round a problem with Qt's moc and Python v2.3. Strictly speaking
+ * it's a Qt problem but later versions of Python include a fix for it so we
+ * might as well too.
+ */
+#undef slots
+
+
+#include <Python.h>
+
+/*
+ * There is a mis-feature somewhere with the Borland compiler. This works
+ * around it.
+ */
+#if defined(__BORLANDC__)
+#include <rpc.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Sanity check on the Python version. */
+#if PY_VERSION_HEX < 0x02030000
+#error "This version of SIP requires Python v2.3 or later"
+#endif
+
+
+/*
+ * Define the SIP version number.
+ */
+#define SIP_VERSION 0x040a05
+#define SIP_VERSION_STR "4.10.5"
+
+
+/*
+ * Define the current API version number. SIP must handle modules with the
+ * same major number and with the same or earlier minor number. Whenever data
+ * structure elements are added they must be appended and the minor number
+ * incremented. Whenever data structure elements are removed or the order
+ * changed then the major number must be incremented and the minor number set
+ * to 0.
+ *
+ * History:
+ *
+ * 7.1 Added the 'H' format character to sip_api_parse_result().
+ * Deprecated the 'D' format character of sip_api_parse_result().
+ *
+ * 7.0 Added sip_api_parse_kwd_args().
+ * Added sipErrorState, sip_api_add_exception().
+ * The type initialisation function is now passed a dictionary of keyword
+ * arguments.
+ * All argument parsers now update a set of error messages rather than an
+ * argument count.
+ * The signatures of sip_api_no_function() and sip_api_no_method() have
+ * changed.
+ * Added ctd_docstring to sipClassTypeDef.
+ * Added vf_docstring to sipVersionedFunctionDef.
+ *
+ * 6.0 Added the sipContainerDef structure to define the contents of a class
+ * or mapped type. Restructured sipClassDef and sipMappedTypeDef
+ * accordingly.
+ * Added the 'r' format character to sip_api_parse_args().
+ * Added the 'r' format character to sip_api_call_method() and
+ * sip_api_build_result().
+ * Added the assignment, array and copy allocation helpers.
+ *
+ * 5.0 Added sip_api_is_api_enabled().
+ * Renamed the td_version_nr member of sipTypeDef to be int and where -1
+ * indicates it is not versioned.
+ * Added the em_versions member to sipExportedModuleDef.
+ * Added the em_versioned_functions member to sipExportedModuleDef.
+ *
+ * 4.0 Much refactoring.
+ *
+ * 3.8 Added sip_api_register_qt_metatype() and sip_api_deprecated().
+ * Added qt_register_meta_type() to the Qt support API.
+ * The C/C++ names of enums and types are now always defined in the
+ * relevant structures and don't default to the Python name.
+ * Added the 'XE' format characters to sip_api_parse_args().
+ *
+ * 3.7 Added sip_api_convert_from_const_void_ptr(),
+ * sip_api_convert_from_void_ptr_and_size() and
+ * sip_api_convert_from_const_void_ptr_and_size().
+ * Added the 'g' and 'G' format characters (to replace the now deprecated
+ * 'a' and 'A' format characters) to sip_api_build_result(),
+ * sip_api_call_method() and sip_api_parse_result().
+ * Added the 'k' and 'K' format characters (to replace the now deprecated
+ * 'a' and 'A' format characters) to sip_api_parse_args().
+ * Added sip_api_invoke_slot().
+ * Added sip_api_parse_type().
+ * Added sip_api_is_exact_wrapped_type().
+ * Added sip_api_assign_instance().
+ * Added sip_api_assign_mapped_type().
+ * Added the td_assign and td_qt fields to the sipTypeDef structure.
+ * Added the mt_assign field to the sipMappedType structure.
+ *
+ * 3.6 Added the 'g' format character to sip_api_parse_args().
+ *
+ * 3.5 Added the td_pickle field to the sipTypeDef structure.
+ * Added sip_api_transfer_break().
+ *
+ * 3.4 Added qt_find_connection() to the Qt support API.
+ * Added sip_api_string_as_char(), sip_api_unicode_as_wchar(),
+ * sip_api_unicode_as_wstring(), sip_api_find_class(),
+ * sip_api_find_named_enum() and sip_api_parse_signature().
+ * Added the 'A', 'w' and 'x' format characters to sip_api_parse_args(),
+ * sip_api_parse_result(), sip_api_build_result() and
+ * sip_api_call_method().
+ *
+ * 3.3 Added sip_api_register_int_types().
+ *
+ * 3.2 Added sip_api_export_symbol() and sip_api_import_symbol().
+ *
+ * 3.1 Added sip_api_add_mapped_type_instance().
+ *
+ * 3.0 Moved the Qt support out of the sip module and into PyQt. This is
+ * such a dramatic change that there is no point in attempting to maintain
+ * backwards compatibility.
+ *
+ * 2.0 Added the td_flags field to the sipTypeDef structure.
+ * Added the first_child, sibling_next, sibling_prev and parent fields to
+ * the sipWrapper structure.
+ * Added the td_traverse and td_clear fields to the sipTypeDef structure.
+ * Added the em_api_minor field to the sipExportedModuleDef structure.
+ * Added sip_api_bad_operator_arg().
+ * Added sip_api_wrapper_check().
+ *
+ * 1.1 Added support for __pos__ and __abs__.
+ *
+ * 1.0 Removed all deprecated parts of the API.
+ * Removed the td_proxy field from the sipTypeDef structure.
+ * Removed the create proxy function from the 'q' and 'y' format
+ * characters to sip_api_parse_args().
+ * Removed sip_api_emit_to_slot().
+ * Reworked the enum related structures.
+ *
+ * 0.2 Added the 'H' format character to sip_api_parse_args().
+ *
+ * 0.1 Added sip_api_add_class_instance().
+ * Added the 't' format character to sip_api_parse_args().
+ * Deprecated the 'J' and 'K' format characters to sip_api_parse_result().
+ *
+ * 0.0 Original version.
+ */
+#define SIP_API_MAJOR_NR 7
+#define SIP_API_MINOR_NR 1
+
+
+/* Some compatibility stuff to help with handwritten code for SIP v3. */
+#if !defined(ANY)
+#define ANY void
+#endif
+
+
+/* Some Python compatibility stuff. */
+#if PY_VERSION_HEX >= 0x02050000
+
+#define SIP_SSIZE_T Py_ssize_t
+
+#define SIP_MLNAME_CAST(s) (s)
+#define SIP_MLDOC_CAST(s) (s)
+#define SIP_TPNAME_CAST(s) (s)
+
+#else
+
+#define SIP_SSIZE_T int
+
+#define SIP_MLNAME_CAST(s) ((char *)(s))
+#define SIP_MLDOC_CAST(s) ((char *)(s))
+#define SIP_TPNAME_CAST(s) ((char *)(s))
+
+#endif
+
+#if PY_MAJOR_VERSION >= 3
+
+#define SIPLong_FromLong PyLong_FromLong
+#define SIPLong_AsLong PyLong_AsLong
+
+#define SIPBytes_Check PyBytes_Check
+#define SIPBytes_FromString PyBytes_FromString
+#define SIPBytes_FromStringAndSize PyBytes_FromStringAndSize
+#define SIPBytes_AS_STRING PyBytes_AS_STRING
+#define SIPBytes_GET_SIZE PyBytes_GET_SIZE
+
+#if PY_MINOR_VERSION >= 1
+#define SIP_USE_PYCAPSULE
+#endif
+
+#else
+
+#define SIPLong_FromLong PyInt_FromLong
+#define SIPLong_AsLong PyInt_AsLong
+
+#define SIPBytes_Check PyString_Check
+#define SIPBytes_FromString PyString_FromString
+#define SIPBytes_FromStringAndSize PyString_FromStringAndSize
+#define SIPBytes_AS_STRING PyString_AS_STRING
+#define SIPBytes_GET_SIZE PyString_GET_SIZE
+
+#if PY_MINOR_VERSION >= 7
+#define SIP_USE_PYCAPSULE
+#endif
+
+#endif
+
+#if !defined(Py_REFCNT)
+#define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
+#endif
+
+#if !defined(Py_TYPE)
+#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
+#endif
+
+#if !defined(PyVarObject_HEAD_INIT)
+#define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
+#endif
+
+
+/*
+ * The mask that can be passed to sipTrace().
+ */
+#define SIP_TRACE_CATCHERS 0x0001
+#define SIP_TRACE_CTORS 0x0002
+#define SIP_TRACE_DTORS 0x0004
+#define SIP_TRACE_INITS 0x0008
+#define SIP_TRACE_DEALLOCS 0x0010
+#define SIP_TRACE_METHODS 0x0020
+
+
+/*
+ * Hide some thread dependent stuff.
+ */
+#ifdef WITH_THREAD
+typedef PyGILState_STATE sip_gilstate_t;
+#define SIP_RELEASE_GIL(gs) PyGILState_Release(gs);
+#define SIP_BLOCK_THREADS {PyGILState_STATE sipGIL = PyGILState_Ensure();
+#define SIP_UNBLOCK_THREADS PyGILState_Release(sipGIL);}
+#else
+typedef int sip_gilstate_t;
+#define SIP_RELEASE_GIL(gs)
+#define SIP_BLOCK_THREADS
+#define SIP_UNBLOCK_THREADS
+#endif
+
+
+/*
+ * The meta-type of a wrapper type.
+ */
+typedef struct _sipWrapperType {
+ /*
+ * The super-metatype. This must be first in the structure so that it can
+ * be cast to a PyTypeObject *.
+ */
+ PyHeapTypeObject super;
+
+ /* The generated type structure. */
+ struct _sipTypeDef *type;
+
+ /* The list of init extenders. */
+ struct _sipInitExtenderDef *iextend;
+
+ /* Set if the type's dictionary contains all lazy attributes. */
+ int dict_complete;
+} sipWrapperType;
+
+
+/*
+ * The type of a simple C/C++ wrapper object.
+ */
+typedef struct _sipSimpleWrapper {
+ PyObject_HEAD
+
+ union {
+ /* C/C++ object pointer. */
+ void *cppPtr;
+
+ /* Access function. */
+ void *(*afPtr)();
+ } u;
+
+ /* Object flags. */
+ int flags;
+
+ /* The optional dictionary of extra references keyed by argument number. */
+ PyObject *extra_refs;
+
+ /* For the user to use. */
+ PyObject *user;
+
+ /* The instance dictionary. */
+ PyObject *dict;
+
+ /* Next object at this address. */
+ struct _sipSimpleWrapper *next;
+} sipSimpleWrapper;
+
+
+/*
+ * The type of a C/C++ wrapper object that supports parent/child relationships.
+ */
+typedef struct _sipWrapper {
+ /* The super-type. */
+ sipSimpleWrapper super;
+
+ /* First child object. */
+ struct _sipWrapper *first_child;
+
+ /* Next sibling. */
+ struct _sipWrapper *sibling_next;
+
+ /* Previous sibling. */
+ struct _sipWrapper *sibling_prev;
+
+ /* Owning object. */
+ struct _sipWrapper *parent;
+} sipWrapper;
+
+
+/*
+ * The meta-type of an enum type. (This is exposed only to support the
+ * deprecated sipConvertFromNamedEnum() macro.)
+ */
+typedef struct _sipEnumTypeObject {
+ /*
+ * The super-metatype. This must be first in the structure so that it can
+ * be cast to a PyTypeObject *.
+ */
+ PyHeapTypeObject super;
+
+ /* The generated type structure. */
+ struct _sipTypeDef *type;
+} sipEnumTypeObject;
+
+
+/*
+ * Some convenient function pointers.
+ */
+typedef void *(*sipInitFunc)(sipSimpleWrapper *, PyObject *, PyObject *,
+ PyObject **, PyObject **, PyObject **);
+typedef int (*sipTraverseFunc)(void *, visitproc, void *);
+typedef int (*sipClearFunc)(void *);
+#if PY_MAJOR_VERSION >= 3
+typedef int (*sipGetBufferFunc)(PyObject *, void *, Py_buffer *, int);
+typedef void (*sipReleaseBufferFunc)(PyObject *, void *, Py_buffer *);
+#else
+typedef SIP_SSIZE_T (*sipBufferFunc)(PyObject *, void *, SIP_SSIZE_T, void **);
+typedef SIP_SSIZE_T (*sipSegCountFunc)(PyObject *, void *, SIP_SSIZE_T *);
+#endif
+typedef void (*sipDeallocFunc)(sipSimpleWrapper *);
+typedef void *(*sipCastFunc)(void *, const struct _sipTypeDef *);
+typedef const struct _sipTypeDef *(*sipSubClassConvertFunc)(void **);
+typedef int (*sipConvertToFunc)(PyObject *, void **, int *, PyObject *);
+typedef PyObject *(*sipConvertFromFunc)(void *, PyObject *);
+typedef int (*sipVirtHandlerFunc)(void *, PyObject *, ...);
+typedef void (*sipAssignFunc)(void *, SIP_SSIZE_T, const void *);
+typedef void *(*sipArrayFunc)(SIP_SSIZE_T);
+typedef void *(*sipCopyFunc)(const void *, SIP_SSIZE_T);
+typedef void (*sipReleaseFunc)(void *, int);
+typedef PyObject *(*sipPickleFunc)(void *);
+typedef int (*sipAttrGetterFunc)(const struct _sipTypeDef *, PyObject *);
+typedef PyObject *(*sipVariableGetterFunc)(void *, PyObject *);
+typedef int (*sipVariableSetterFunc)(void *, PyObject *, PyObject *);
+
+
+/*
+ * The information describing an encoded type ID.
+ */
+typedef struct _sipEncodedTypeDef {
+ /* The type number. */
+ unsigned sc_type:16;
+
+ /* The module number (255 for this one). */
+ unsigned sc_module:8;
+
+ /* A context specific flag. */
+ unsigned sc_flag:1;
+} sipEncodedTypeDef;
+
+
+/*
+ * The information describing an enum member.
+ */
+typedef struct _sipEnumMemberDef {
+ /* The member name. */
+ const char *em_name;
+
+ /* The member value. */
+ int em_val;
+
+ /* The member enum, -ve if anonymous. */
+ int em_enum;
+} sipEnumMemberDef;
+
+
+/*
+ * The information describing static instances.
+ */
+typedef struct _sipInstancesDef {
+ /* The types. */
+ struct _sipTypeInstanceDef *id_type;
+
+ /* The void *. */
+ struct _sipVoidPtrInstanceDef *id_voidp;
+
+ /* The chars. */
+ struct _sipCharInstanceDef *id_char;
+
+ /* The strings. */
+ struct _sipStringInstanceDef *id_string;
+
+ /* The ints. */
+ struct _sipIntInstanceDef *id_int;
+
+ /* The longs. */
+ struct _sipLongInstanceDef *id_long;
+
+ /* The unsigned longs. */
+ struct _sipUnsignedLongInstanceDef *id_ulong;
+
+ /* The long longs. */
+ struct _sipLongLongInstanceDef *id_llong;
+
+ /* The unsigned long longs. */
+ struct _sipUnsignedLongLongInstanceDef *id_ullong;
+
+ /* The doubles. */
+ struct _sipDoubleInstanceDef *id_double;
+} sipInstancesDef;
+
+
+/*
+ * The information describing a type initialiser extender.
+ */
+typedef struct _sipInitExtenderDef {
+ /* The API version range index. */
+ int ie_api_range;
+
+ /* The extender function. */
+ sipInitFunc ie_extender;
+
+ /* The class being extended. */
+ sipEncodedTypeDef ie_class;
+
+ /* The next extender for this class. */
+ struct _sipInitExtenderDef *ie_next;
+} sipInitExtenderDef;
+
+
+/*
+ * The information describing a sub-class convertor.
+ */
+typedef struct _sipSubClassConvertorDef {
+ /* The convertor. */
+ sipSubClassConvertFunc scc_convertor;
+
+ /* The encoded base type. */
+ sipEncodedTypeDef scc_base;
+
+ /* The base type. */
+ struct _sipTypeDef *scc_basetype;
+} sipSubClassConvertorDef;
+
+
+/*
+ * The different error states of handwritten code.
+ */
+typedef enum {
+ sipErrorNone, /* There is no error. */
+ sipErrorFail, /* The error is a failure. */
+ sipErrorContinue /* It may not apply if a later operation succeeds. */
+} sipErrorState;
+
+
+/*
+ * The different Python slot types.
+ */
+typedef enum {
+ str_slot, /* __str__ */
+ int_slot, /* __int__ */
+#if PY_MAJOR_VERSION < 3
+ long_slot, /* __long__ */
+#endif
+ float_slot, /* __float__ */
+ len_slot, /* __len__ */
+ contains_slot, /* __contains__ */
+ add_slot, /* __add__ for number */
+ concat_slot, /* __add__ for sequence types */
+ sub_slot, /* __sub__ */
+ mul_slot, /* __mul__ for number types */
+ repeat_slot, /* __mul__ for sequence types */
+ div_slot, /* __div__ */
+ mod_slot, /* __mod__ */
+ floordiv_slot, /* __floordiv__ */
+ truediv_slot, /* __truediv__ */
+ and_slot, /* __and__ */
+ or_slot, /* __or__ */
+ xor_slot, /* __xor__ */
+ lshift_slot, /* __lshift__ */
+ rshift_slot, /* __rshift__ */
+ iadd_slot, /* __iadd__ for number types */
+ iconcat_slot, /* __iadd__ for sequence types */
+ isub_slot, /* __isub__ */
+ imul_slot, /* __imul__ for number types */
+ irepeat_slot, /* __imul__ for sequence types */
+ idiv_slot, /* __idiv__ */
+ imod_slot, /* __imod__ */
+ ifloordiv_slot, /* __ifloordiv__ */
+ itruediv_slot, /* __itruediv__ */
+ iand_slot, /* __iand__ */
+ ior_slot, /* __ior__ */
+ ixor_slot, /* __ixor__ */
+ ilshift_slot, /* __ilshift__ */
+ irshift_slot, /* __irshift__ */
+ invert_slot, /* __invert__ */
+ call_slot, /* __call__ */
+ getitem_slot, /* __getitem__ */
+ setitem_slot, /* __setitem__ */
+ delitem_slot, /* __delitem__ */
+ lt_slot, /* __lt__ */
+ le_slot, /* __le__ */
+ eq_slot, /* __eq__ */
+ ne_slot, /* __ne__ */
+ gt_slot, /* __gt__ */
+ ge_slot, /* __ge__ */
+#if PY_MAJOR_VERSION < 3
+ cmp_slot, /* __cmp__ */
+#endif
+ bool_slot, /* __bool__, __nonzero__ */
+ neg_slot, /* __neg__ */
+ repr_slot, /* __repr__ */
+ hash_slot, /* __hash__ */
+ pos_slot, /* __pos__ */
+ abs_slot, /* __abs__ */
+#if PY_VERSION_HEX >= 0x02050000
+ index_slot, /* __index__ */
+#endif
+ iter_slot, /* __iter__ */
+ next_slot, /* __next__ */
+} sipPySlotType;
+
+
+/*
+ * The information describing a Python slot function.
+ */
+typedef struct _sipPySlotDef {
+ /* The function. */
+ void *psd_func;
+
+ /* The type. */
+ sipPySlotType psd_type;
+} sipPySlotDef;
+
+
+/*
+ * The information describing a Python slot extender.
+ */
+typedef struct _sipPySlotExtenderDef {
+ /* The function. */
+ void *pse_func;
+
+ /* The type. */
+ sipPySlotType pse_type;
+
+ /* The encoded class. */
+ sipEncodedTypeDef pse_class;
+} sipPySlotExtenderDef;
+
+
+/*
+ * The information describing a typedef.
+ */
+typedef struct _sipTypedefDef {
+ /* The typedef name. */
+ const char *tdd_name;
+
+ /* The typedef value. */
+ const char *tdd_type_name;
+} sipTypedefDef;
+
+
+/*
+ * The information describing a variable.
+ */
+typedef struct _sipVariableDef {
+ /* The variable name. */
+ const char *vd_name;
+
+ /* The variable getter. */
+ sipVariableGetterFunc vd_getter;
+
+ /* The variable setter. It is NULL if the variable is const. */
+ sipVariableSetterFunc vd_setter;
+
+ /* This is set if the variable is static. */
+ int vd_is_static;
+} sipVariableDef;
+
+
+/*
+ * The information describing a type, either a C++ class (or C struct), a C++
+ * namespace, a mapped type or a named enum.
+ */
+typedef struct _sipTypeDef {
+ /* The version range index, -1 if the type isn't versioned. */
+ int td_version;
+
+ /* The next version of this type. */
+ struct _sipTypeDef *td_next_version;
+
+ /* The module, 0 if the type hasn't been initialised. */
+ struct _sipExportedModuleDef *td_module;
+
+ /* Type flags, see the sipType*() macros. */
+ int td_flags;
+
+ /* The C/C++ name of the type. */
+ int td_cname;
+
+ /*
+ * The Python type object. This needs to be a union until we remove the
+ * deprecated sipClass_* macros.
+ */
+ union {
+ PyTypeObject *td_py_type;
+ sipWrapperType *td_wrapper_type;
+ } u;
+} sipTypeDef;
+
+
+/*
+ * The information describing a container (ie. a class, namespace or a mapped
+ * type).
+ */
+typedef struct _sipContainerDef {
+ /*
+ * The Python name of the type, -1 if this is a namespace extender (in the
+ * context of a class) or doesn't require a namespace (in the context of a
+ * mapped type). */
+ int cod_name;
+
+ /*
+ * The scoping type or the namespace this is extending if it is a namespace
+ * extender.
+ */
+ sipEncodedTypeDef cod_scope;
+
+ /* The number of lazy methods. */
+ int cod_nrmethods;
+
+ /* The table of lazy methods. */
+ PyMethodDef *cod_methods;
+
+ /* The number of lazy enum members. */
+ int cod_nrenummembers;
+
+ /* The table of lazy enum members. */
+ sipEnumMemberDef *cod_enummembers;
+
+ /* The number of variables. */
+ int cod_nrvariables;
+
+ /* The table of variables. */
+ sipVariableDef *cod_variables;
+
+ /* The static instances. */
+ sipInstancesDef cod_instances;
+} sipContainerDef;
+
+
+/*
+ * The information describing a C++ class (or C struct) or a C++ namespace.
+ */
+typedef struct _sipClassTypeDef {
+ /* The base type information. */
+ sipTypeDef ctd_base;
+
+ /* The container information. */
+ sipContainerDef ctd_container;
+
+ /* The docstring. */
+ const char *ctd_docstring;
+
+ /*
+ * The meta-type name, -1 to use the meta-type of the first super-type
+ * (normally sipWrapperType).
+ */
+ int ctd_metatype;
+
+ /* The super-type name, -1 to use sipWrapper. */
+ int ctd_supertype;
+
+ /* The super-types. */
+ sipEncodedTypeDef *ctd_supers;
+
+ /* The table of Python slots. */
+ sipPySlotDef *ctd_pyslots;
+
+ /* The initialisation function. */
+ sipInitFunc ctd_init;
+
+ /* The traverse function. */
+ sipTraverseFunc ctd_traverse;
+
+ /* The clear function. */
+ sipClearFunc ctd_clear;
+
+#if PY_MAJOR_VERSION >= 3
+ /* The get buffer function. */
+ sipGetBufferFunc ctd_getbuffer;
+
+ /* The release buffer function. */
+ sipReleaseBufferFunc ctd_releasebuffer;
+#else
+ /* The read buffer function. */
+ sipBufferFunc ctd_readbuffer;
+
+ /* The write buffer function. */
+ sipBufferFunc ctd_writebuffer;
+
+ /* The segment count function. */
+ sipSegCountFunc ctd_segcount;
+
+ /* The char buffer function. */
+ sipBufferFunc ctd_charbuffer;
+#endif
+
+ /* The deallocation function. */
+ sipDeallocFunc ctd_dealloc;
+
+ /* The optional assignment function. */
+ sipAssignFunc ctd_assign;
+
+ /* The optional array allocation function. */
+ sipArrayFunc ctd_array;
+
+ /* The optional copy function. */
+ sipCopyFunc ctd_copy;
+
+ /* The release function, 0 if a C strict. */
+ sipReleaseFunc ctd_release;
+
+ /* The cast function, 0 if a C struct. */
+ sipCastFunc ctd_cast;
+
+ /* The optional convert to function. */
+ sipConvertToFunc ctd_cto;
+
+ /* The next namespace extender. */
+ struct _sipClassTypeDef *ctd_nsextender;
+
+ /* The pickle function. */
+ sipPickleFunc ctd_pickle;
+} sipClassTypeDef;
+
+
+/*
+ * The information describing a mapped type.
+ */
+typedef struct _sipMappedTypeDef {
+ /* The base type information. */
+ sipTypeDef mtd_base;
+
+ /* The container information. */
+ sipContainerDef mtd_container;
+
+ /* The optional assignment function. */
+ sipAssignFunc mtd_assign;
+
+ /* The optional array allocation function. */
+ sipArrayFunc mtd_array;
+
+ /* The optional copy function. */
+ sipCopyFunc mtd_copy;
+
+ /* The optional release function. */
+ sipReleaseFunc mtd_release;
+
+ /* The convert to function. */
+ sipConvertToFunc mtd_cto;
+
+ /* The convert from function. */
+ sipConvertFromFunc mtd_cfrom;
+} sipMappedTypeDef;
+
+
+/*
+ * The information describing a named enum.
+ */
+typedef struct _sipEnumTypeDef {
+ /* The base type information. */
+ sipTypeDef etd_base;
+
+ /* The Python name of the enum. */
+ int etd_name;
+
+ /* The scoping type, -1 if it is defined at the module level. */
+ int etd_scope;
+
+ /* The Python slots. */
+ struct _sipPySlotDef *etd_pyslots;
+} sipEnumTypeDef;
+
+
+/*
+ * The information describing an external type.
+ */
+typedef struct _sipExternalTypeDef {
+ /* The index into the type table. */
+ int et_nr;
+
+ /* The name of the type. */
+ const char *et_name;
+} sipExternalTypeDef;
+
+
+/*
+ * The information describing a mapped class. This (and anything that uses it)
+ * is deprecated.
+ */
+typedef sipTypeDef sipMappedType;
+
+
+/*
+ * Defines an entry in the module specific list of delayed dtor calls.
+ */
+typedef struct _sipDelayedDtor {
+ /* The C/C++ instance. */
+ void *dd_ptr;
+
+ /* The class name. */
+ const char *dd_name;
+
+ /* Non-zero if dd_ptr is a derived class instance. */
+ int dd_isderived;
+
+ /* Next in the list. */
+ struct _sipDelayedDtor *dd_next;
+} sipDelayedDtor;
+
+
+/*
+ * Defines an entry in the table of global functions all of whose overloads
+ * are versioned (so their names can't be automatically added to the module
+ * dictionary).
+ */
+typedef struct _sipVersionedFunctionDef {
+ /* The name, -1 marks the end of the table. */
+ int vf_name;
+
+ /* The function itself. */
+ PyCFunction vf_function;
+
+ /* The METH_* flags. */
+ int vf_flags;
+
+ /* The docstring. */
+ const char *vf_docstring;
+
+ /* The API version range index. */
+ int vf_api_range;
+} sipVersionedFunctionDef;
+
+
+/*
+ * The information describing an imported module.
+ */
+typedef struct _sipImportedModuleDef {
+ /* The module name. */
+ const char *im_name;
+
+ /* The required version. */
+ int im_version;
+
+ /* The imported module. */
+ struct _sipExportedModuleDef *im_module;
+} sipImportedModuleDef;
+
+
+/*
+ * The main client module structure.
+ */
+typedef struct _sipExportedModuleDef {
+ /* The next in the list. */
+ struct _sipExportedModuleDef *em_next;
+
+ /* The SIP API minor version number. */
+ unsigned em_api_minor;
+
+ /* The module name. */
+ int em_name;
+
+ /* The module name as an object. */
+ PyObject *em_nameobj;
+
+ /* The module version. */
+ int em_version;
+
+ /* The string pool. */
+ const char *em_strings;
+
+ /* The imported modules. */
+ sipImportedModuleDef *em_imports;
+
+ /* The optional Qt support API. */
+ struct _sipQtAPI *em_qt_api;
+
+ /* The number of types. */
+ int em_nrtypes;
+
+ /* The table of types. */
+ sipTypeDef **em_types;
+
+ /* The table of external types. */
+ sipExternalTypeDef *em_external;
+
+ /* The number of members in global enums. */
+ int em_nrenummembers;
+
+ /* The table of members in global enums. */
+ sipEnumMemberDef *em_enummembers;
+
+ /* The number of typedefs. */
+ int em_nrtypedefs;
+
+ /* The table of typedefs. */
+ sipTypedefDef *em_typedefs;
+
+ /* The table of virtual handlers. */
+ sipVirtHandlerFunc *em_virthandlers;
+
+ /* The sub-class convertors. */
+ sipSubClassConvertorDef *em_convertors;
+
+ /* The static instances. */
+ sipInstancesDef em_instances;
+
+ /* The license. */
+ struct _sipLicenseDef *em_license;
+
+ /* The table of exception types. */
+ PyObject **em_exceptions;
+
+ /* The table of Python slot extenders. */
+ sipPySlotExtenderDef *em_slotextend;
+
+ /* The table of initialiser extenders. */
+ sipInitExtenderDef *em_initextend;
+
+ /* The delayed dtor handler. */
+ void (*em_delayeddtors)(const sipDelayedDtor *);
+
+ /* The list of delayed dtors. */
+ sipDelayedDtor *em_ddlist;
+
+ /*
+ * The array of API version definitions. Each definition takes up 3
+ * elements. If the third element of a 3-tuple is negative then the first
+ * two elements define an API and its default version. All such
+ * definitions will appear at the end of the array. If the first element
+ * of a 3-tuple is negative then that is the last element of the array.
+ */
+ int *em_versions;
+
+ /* The optional table of versioned functions. */
+ sipVersionedFunctionDef *em_versioned_functions;
+} sipExportedModuleDef;
+
+
+/*
+ * The information describing a license to be added to a dictionary.
+ */
+typedef struct _sipLicenseDef {
+ /* The type of license. */
+ const char *lc_type;
+
+ /* The licensee. */
+ const char *lc_licensee;
+
+ /* The timestamp. */
+ const char *lc_timestamp;
+
+ /* The signature. */
+ const char *lc_signature;
+} sipLicenseDef;
+
+
+/*
+ * The information describing a void pointer instance to be added to a
+ * dictionary.
+ */
+typedef struct _sipVoidPtrInstanceDef {
+ /* The void pointer name. */
+ const char *vi_name;
+
+ /* The void pointer value. */
+ void *vi_val;
+} sipVoidPtrInstanceDef;
+
+
+/*
+ * The information describing a char instance to be added to a dictionary.
+ */
+typedef struct _sipCharInstanceDef {
+ /* The char name. */
+ const char *ci_name;
+
+ /* The char value. */
+ char ci_val;
+
+ /* The encoding used, either 'A', 'L', '8' or 'N'. */
+ char ci_encoding;
+} sipCharInstanceDef;
+
+
+/*
+ * The information describing a string instance to be added to a dictionary.
+ */
+typedef struct _sipStringInstanceDef {
+ /* The string name. */
+ const char *si_name;
+
+ /* The string value. */
+ const char *si_val;
+
+ /* The encoding used, either 'A', 'L', '8' or 'N'. */
+ char si_encoding;
+} sipStringInstanceDef;
+
+
+/*
+ * The information describing an int instance to be added to a dictionary.
+ */
+typedef struct _sipIntInstanceDef {
+ /* The int name. */
+ const char *ii_name;
+
+ /* The int value. */
+ int ii_val;
+} sipIntInstanceDef;
+
+
+/*
+ * The information describing a long instance to be added to a dictionary.
+ */
+typedef struct _sipLongInstanceDef {
+ /* The long name. */
+ const char *li_name;
+
+ /* The long value. */
+ long li_val;
+} sipLongInstanceDef;
+
+
+/*
+ * The information describing an unsigned long instance to be added to a
+ * dictionary.
+ */
+typedef struct _sipUnsignedLongInstanceDef {
+ /* The unsigned long name. */
+ const char *uli_name;
+
+ /* The unsigned long value. */
+ unsigned long uli_val;
+} sipUnsignedLongInstanceDef;
+
+
+/*
+ * The information describing a long long instance to be added to a dictionary.
+ */
+typedef struct _sipLongLongInstanceDef {
+ /* The long long name. */
+ const char *lli_name;
+
+ /* The long long value. */
+#if defined(HAVE_LONG_LONG)
+ PY_LONG_LONG lli_val;
+#else
+ long lli_val;
+#endif
+} sipLongLongInstanceDef;
+
+
+/*
+ * The information describing an unsigned long long instance to be added to a
+ * dictionary.
+ */
+typedef struct _sipUnsignedLongLongInstanceDef {
+ /* The unsigned long long name. */
+ const char *ulli_name;
+
+ /* The unsigned long long value. */
+#if defined(HAVE_LONG_LONG)
+ unsigned PY_LONG_LONG ulli_val;
+#else
+ unsigned long ulli_val;
+#endif
+} sipUnsignedLongLongInstanceDef;
+
+
+/*
+ * The information describing a double instance to be added to a dictionary.
+ */
+typedef struct _sipDoubleInstanceDef {
+ /* The double name. */
+ const char *di_name;
+
+ /* The double value. */
+ double di_val;
+} sipDoubleInstanceDef;
+
+
+/*
+ * The information describing a class or enum instance to be added to a
+ * dictionary.
+ */
+typedef struct _sipTypeInstanceDef {
+ /* The type instance name. */
+ const char *ti_name;
+
+ /* The actual instance. */
+ void *ti_ptr;
+
+ /* A pointer to the generated type. */
+ struct _sipTypeDef **ti_type;
+
+ /* The wrapping flags. */
+ int ti_flags;
+} sipTypeInstanceDef;
+
+
+/*
+ * Define a mapping between a wrapped type identified by a string and the
+ * corresponding Python type. This is deprecated.
+ */
+typedef struct _sipStringTypeClassMap {
+ /* The type as a string. */
+ const char *typeString;
+
+ /* A pointer to the Python type. */
+ struct _sipWrapperType **pyType;
+} sipStringTypeClassMap;
+
+
+/*
+ * Define a mapping between a wrapped type identified by an integer and the
+ * corresponding Python type. This is deprecated.
+ */
+typedef struct _sipIntTypeClassMap {
+ /* The type as an integer. */
+ int typeInt;
+
+ /* A pointer to the Python type. */
+ struct _sipWrapperType **pyType;
+} sipIntTypeClassMap;
+
+
+/*
+ * A Python method's component parts. This allows us to re-create the method
+ * without changing the reference counts of the components.
+ */
+typedef struct _sipPyMethod {
+ /* The function. */
+ PyObject *mfunc;
+
+ /* Self if it is a bound method. */
+ PyObject *mself;
+
+#if PY_MAJOR_VERSION < 3
+ /* The class. */
+ PyObject *mclass;
+#endif
+} sipPyMethod;
+
+
+/*
+ * A slot (in the Qt, rather than Python, sense).
+ */
+typedef struct _sipSlot {
+ /* Name if a Qt or Python signal. */
+ char *name;
+
+ /* Signal or Qt slot object. */
+ PyObject *pyobj;
+
+ /* Python slot method, pyobj is NULL. */
+ sipPyMethod meth;
+
+ /* A weak reference to the slot, Py_True if pyobj has an extra reference. */
+ PyObject *weakSlot;
+} sipSlot;
+
+
+/*
+ * The API exported by the SIP module, ie. pointers to all the data and
+ * functions that can be used by generated code.
+ */
+typedef struct _sipAPIDef {
+ /*
+ * This must be the first entry and it's signature must not change so that
+ * version number mismatches can be detected and reported.
+ */
+ int (*api_export_module)(sipExportedModuleDef *client, unsigned api_major,
+ unsigned api_minor, void *unused);
+
+ /*
+ * The following are part of the public API.
+ */
+ PyTypeObject *api_simplewrapper_type;
+ PyTypeObject *api_wrapper_type;
+ PyTypeObject *api_wrappertype_type;
+ PyTypeObject *api_voidptr_type;
+
+ void (*api_bad_catcher_result)(PyObject *method);
+ void (*api_bad_length_for_slice)(SIP_SSIZE_T seqlen, SIP_SSIZE_T slicelen);
+ PyObject *(*api_build_result)(int *isErr, const char *fmt, ...);
+ PyObject *(*api_call_method)(int *isErr, PyObject *method, const char *fmt,
+ ...);
+ PyObject *(*api_connect_rx)(PyObject *txObj, const char *sig,
+ PyObject *rxObj, const char *slot, int type);
+ SIP_SSIZE_T (*api_convert_from_sequence_index)(SIP_SSIZE_T idx,
+ SIP_SSIZE_T len);
+ int (*api_can_convert_to_type)(PyObject *pyObj, const sipTypeDef *td,
+ int flags);
+ void *(*api_convert_to_type)(PyObject *pyObj, const sipTypeDef *td,
+ PyObject *transferObj, int flags, int *statep, int *iserrp);
+ void *(*api_force_convert_to_type)(PyObject *pyObj, const sipTypeDef *td,
+ PyObject *transferObj, int flags, int *statep, int *iserrp);
+ int (*api_can_convert_to_enum)(PyObject *pyObj, const sipTypeDef *td);
+ void (*api_release_type)(void *cpp, const sipTypeDef *td, int state);
+ PyObject *(*api_convert_from_type)(void *cpp, const sipTypeDef *td,
+ PyObject *transferObj);
+ PyObject *(*api_convert_from_new_type)(void *cpp, const sipTypeDef *td,
+ PyObject *transferObj);
+ PyObject *(*api_convert_from_enum)(int eval, const sipTypeDef *td);
+ int (*api_get_state)(PyObject *transferObj);
+ PyObject *(*api_disconnect_rx)(PyObject *txObj, const char *sig,
+ PyObject *rxObj, const char *slot);
+ void (*api_free)(void *mem);
+ PyObject *(*api_get_pyobject)(void *cppPtr, const sipTypeDef *td);
+ void *(*api_malloc)(size_t nbytes);
+ int (*api_parse_result)(int *isErr, PyObject *method, PyObject *res,
+ const char *fmt, ...);
+ void (*api_trace)(unsigned mask, const char *fmt, ...);
+ void (*api_transfer_back)(PyObject *self);
+ void (*api_transfer_to)(PyObject *self, PyObject *owner);
+ void (*api_transfer_break)(PyObject *self);
+ unsigned long (*api_long_as_unsigned_long)(PyObject *o);
+ PyObject *(*api_convert_from_void_ptr)(void *val);
+ PyObject *(*api_convert_from_const_void_ptr)(const void *val);
+ PyObject *(*api_convert_from_void_ptr_and_size)(void *val,
+ SIP_SSIZE_T size);
+ PyObject *(*api_convert_from_const_void_ptr_and_size)(const void *val,
+ SIP_SSIZE_T size);
+ void *(*api_convert_to_void_ptr)(PyObject *obj);
+ int (*api_export_symbol)(const char *name, void *sym);
+ void *(*api_import_symbol)(const char *name);
+ const sipTypeDef *(*api_find_type)(const char *type);
+ int (*api_register_py_type)(PyTypeObject *type);
+ const sipTypeDef *(*api_type_from_py_type_object)(PyTypeObject *py_type);
+ const sipTypeDef *(*api_type_scope)(const sipTypeDef *td);
+ const char *(*api_resolve_typedef)(const char *name);
+ int (*api_register_attribute_getter)(const sipTypeDef *td,
+ sipAttrGetterFunc getter);
+ int (*api_is_api_enabled)(const char *name, int from, int to);
+ sipErrorState (*api_bad_callable_arg)(int arg_nr, PyObject *arg);
+
+ /*
+ * The following are deprecated parts of the public API.
+ */
+ PyTypeObject *(*api_find_named_enum)(const char *type);
+ const sipMappedType *(*api_find_mapped_type)(const char *type);
+ sipWrapperType *(*api_find_class)(const char *type);
+ sipWrapperType *(*api_map_int_to_class)(int typeInt,
+ const sipIntTypeClassMap *map, int maplen);
+ sipWrapperType *(*api_map_string_to_class)(const char *typeString,
+ const sipStringTypeClassMap *map, int maplen);
+
+ /*
+ * The following may be used by Qt support code but no other handwritten
+ * code.
+ */
+ void (*api_free_sipslot)(sipSlot *slot);
+ int (*api_same_slot)(const sipSlot *sp, PyObject *rxObj, const char *slot);
+ void *(*api_convert_rx)(sipWrapper *txSelf, const char *sigargs,
+ PyObject *rxObj, const char *slot, const char **memberp,
+ int flags);
+ PyObject *(*api_invoke_slot)(const sipSlot *slot, PyObject *sigargs);
+ int (*api_save_slot)(sipSlot *sp, PyObject *rxObj, const char *slot);
+ void (*api_clear_any_slot_reference)(sipSlot *slot);
+ int (*api_visit_slot)(sipSlot *slot, visitproc visit, void *arg);
+
+ /*
+ * The following are not part of the public API.
+ */
+ int (*api_init_module)(sipExportedModuleDef *client, PyObject *mod_dict);
+ int (*api_parse_args)(PyObject **parseErrp, PyObject *sipArgs,
+ const char *fmt, ...);
+ int (*api_parse_pair)(PyObject **parseErrp, PyObject *arg0, PyObject *arg1,
+ const char *fmt, ...);
+ void (*api_common_dtor)(sipSimpleWrapper *sipSelf);
+ void (*api_no_function)(PyObject *parseErr, const char *func,
+ const char *doc);
+ void (*api_no_method)(PyObject *parseErr, const char *scope,
+ const char *method, const char *doc);
+ void (*api_abstract_method)(const char *classname, const char *method);
+ void (*api_bad_class)(const char *classname);
+ void *(*api_get_cpp_ptr)(sipSimpleWrapper *w, const sipTypeDef *td);
+ void *(*api_get_complex_cpp_ptr)(sipSimpleWrapper *w);
+ PyObject *(*api_is_py_method)(sip_gilstate_t *gil, char *pymc,
+ sipSimpleWrapper *sipSelf, const char *cname, const char *mname);
+ void (*api_call_hook)(const char *hookname);
+ void (*api_start_thread)(void);
+ void (*api_end_thread)(void);
+ void (*api_raise_unknown_exception)(void);
+ void (*api_raise_type_exception)(const sipTypeDef *td, void *ptr);
+ int (*api_add_type_instance)(PyObject *dict, const char *name,
+ void *cppPtr, const sipTypeDef *td);
+ void (*api_bad_operator_arg)(PyObject *self, PyObject *arg,
+ sipPySlotType st);
+ PyObject *(*api_pyslot_extend)(sipExportedModuleDef *mod, sipPySlotType st,
+ const sipTypeDef *type, PyObject *arg0, PyObject *arg1);
+ void (*api_add_delayed_dtor)(sipSimpleWrapper *w);
+ char (*api_bytes_as_char)(PyObject *obj);
+ const char *(*api_bytes_as_string)(PyObject *obj);
+ char (*api_string_as_ascii_char)(PyObject *obj);
+ const char *(*api_string_as_ascii_string)(PyObject **obj);
+ char (*api_string_as_latin1_char)(PyObject *obj);
+ const char *(*api_string_as_latin1_string)(PyObject **obj);
+ char (*api_string_as_utf8_char)(PyObject *obj);
+ const char *(*api_string_as_utf8_string)(PyObject **obj);
+#if defined(HAVE_WCHAR_H)
+ wchar_t (*api_unicode_as_wchar)(PyObject *obj);
+ wchar_t *(*api_unicode_as_wstring)(PyObject *obj);
+#else
+ int (*api_unicode_as_wchar)(PyObject *obj);
+ int *(*api_unicode_as_wstring)(PyObject *obj);
+#endif
+ int (*api_deprecated)(const char *classname, const char *method);
+ void (*api_keep_reference)(PyObject *self, int key, PyObject *obj);
+ int (*api_parse_kwd_args)(PyObject **parseErrp, PyObject *sipArgs,
+ PyObject *sipKwdArgs, const char **kwdlist, PyObject **unused,
+ const char *fmt, ...);
+ void (*api_add_exception)(sipErrorState es, PyObject **parseErrp);
+} sipAPIDef;
+
+
+/*
+ * The API implementing the optional Qt support.
+ */
+typedef struct _sipQtAPI {
+ sipTypeDef **qt_qobject;
+ void *(*qt_create_universal_signal)(void *, const char **);
+ void *(*qt_find_universal_signal)(void *, const char **);
+ void *(*qt_create_universal_slot)(struct _sipWrapper *, const char *,
+ PyObject *, const char *, const char **, int);
+ void (*qt_destroy_universal_slot)(void *);
+ void *(*qt_find_slot)(void *, const char *, PyObject *, const char *,
+ const char **);
+ int (*qt_connect)(void *, const char *, void *, const char *, int);
+ int (*qt_disconnect)(void *, const char *, void *, const char *);
+ int (*qt_same_name)(const char *, const char *);
+ sipSlot *(*qt_find_sipslot)(void *, void **);
+ int (*qt_emit_signal)(PyObject *, const char *, PyObject *);
+ int (*qt_connect_py_signal)(PyObject *, const char *, PyObject *,
+ const char *);
+ void (*qt_disconnect_py_signal)(PyObject *, const char *, PyObject *,
+ const char *);
+} sipQtAPI;
+
+
+/*
+ * These are flags that can be passed to sipCanConvertToType(),
+ * sipConvertToType() and sipForceConvertToType().
+ */
+#define SIP_NOT_NONE 0x01 /* Disallow None. */
+#define SIP_NO_CONVERTORS 0x02 /* Disable any type convertors. */
+
+
+/*
+ * These are the state flags returned by %ConvertToTypeCode. Note that these
+ * share the same "namespace" as the flags below.
+ */
+#define SIP_TEMPORARY 0x0001 /* A temporary instance. */
+#define SIP_DERIVED_CLASS 0x0002 /* The instance is derived. */
+
+
+/*
+ * These flags are specific to the Qt support API.
+ */
+#define SIP_SINGLE_SHOT 0x01 /* The connection is single shot. */
+
+
+/*
+ * Useful macros, not part of the public API.
+ */
+#define SIP_PY_OWNED 0x0004 /* Owned by Python. */
+#define SIP_INDIRECT 0x0008 /* If there is a level of indirection. */
+#define SIP_ACCFUNC 0x0010 /* If there is an access function. */
+#define SIP_NOT_IN_MAP 0x0020 /* If Python object not in the map. */
+#define SIP_SHARE_MAP 0x0040 /* If the map slot might be occupied. */
+#define SIP_CPP_HAS_REF 0x0080 /* If C/C++ has a reference. */
+#define SIP_POSSIBLE_PROXY 0x0100 /* If there might be a proxy slot. */
+
+#define sipIsPyOwned(w) ((w)->flags & SIP_PY_OWNED)
+#define sipSetPyOwned(w) ((w)->flags |= SIP_PY_OWNED)
+#define sipResetPyOwned(w) ((w)->flags &= ~SIP_PY_OWNED)
+#define sipIsDerived(w) ((w)->flags & SIP_DERIVED_CLASS)
+#define sipIsIndirect(w) ((w)->flags & SIP_INDIRECT)
+#define sipIsAccessFunc(w) ((w)->flags & SIP_ACCFUNC)
+#define sipNotInMap(w) ((w)->flags & SIP_NOT_IN_MAP)
+#define sipSetNotInMap(w) ((w)->flags |= SIP_NOT_IN_MAP)
+#define sipCppHasRef(w) ((w)->flags & SIP_CPP_HAS_REF)
+#define sipSetCppHasRef(w) ((w)->flags |= SIP_CPP_HAS_REF)
+#define sipResetCppHasRef(w) ((w)->flags &= ~SIP_CPP_HAS_REF)
+#define sipPossibleProxy(w) ((w)->flags & SIP_POSSIBLE_PROXY)
+#define sipSetPossibleProxy(w) ((w)->flags |= SIP_POSSIBLE_PROXY)
+
+
+#define SIP_TYPE_TYPE_MASK 0x0007 /* The type type mask. */
+#define SIP_TYPE_CLASS 0x0000 /* If the type is a C++ class. */
+#define SIP_TYPE_NAMESPACE 0x0001 /* If the type is a C++ namespace. */
+#define SIP_TYPE_MAPPED 0x0002 /* If the type is a mapped type. */
+#define SIP_TYPE_ENUM 0x0003 /* If the type is a named enum. */
+#define SIP_TYPE_ABSTRACT 0x0008 /* If the type is abstract. */
+#define SIP_TYPE_SCC 0x0010 /* If the type is subject to sub-class convertors. */
+#define SIP_TYPE_ALLOW_NONE 0x0020 /* If the type can handle None. */
+#define SIP_TYPE_STUB 0x0040 /* If the type is a stub. */
+
+
+/*
+ * The following are part of the public API.
+ */
+#define sipTypeIsClass(td) (((td)->td_flags & SIP_TYPE_TYPE_MASK) == SIP_TYPE_CLASS)
+#define sipTypeIsNamespace(td) (((td)->td_flags & SIP_TYPE_TYPE_MASK) == SIP_TYPE_NAMESPACE)
+#define sipTypeIsMapped(td) (((td)->td_flags & SIP_TYPE_TYPE_MASK) == SIP_TYPE_MAPPED)
+#define sipTypeIsEnum(td) (((td)->td_flags & SIP_TYPE_TYPE_MASK) == SIP_TYPE_ENUM)
+#define sipTypeAsPyTypeObject(td) ((td)->u.td_py_type)
+#define sipTypeName(td) sipNameFromPool((td)->td_module, (td)->td_cname)
+
+#define sipIsExactWrappedType(wt) (sipTypeAsPyTypeObject((wt)->type) == (PyTypeObject *)(wt))
+
+#define sipConvertFromSliceObject(o,len,start,stop,step,slen) \
+ PySlice_GetIndicesEx((PySliceObject *)(o), (len), (start), (stop), \
+ (step), (slen))
+
+
+/*
+ * The following are deprecated parts of the public API.
+ */
+#define sipClassName(w) PyString_FromString(Py_TYPE(w)->tp_name)
+
+
+/*
+ * The following are not part of the public API.
+ */
+#define sipTypeIsAbstract(td) ((td)->td_flags & SIP_TYPE_ABSTRACT)
+#define sipTypeHasSCC(td) ((td)->td_flags & SIP_TYPE_SCC)
+#define sipTypeAllowNone(td) ((td)->td_flags & SIP_TYPE_ALLOW_NONE)
+#define sipTypeIsStub(td) ((td)->td_flags & SIP_TYPE_STUB)
+#define sipTypeSetStub(td) ((td)->td_flags |= SIP_TYPE_STUB)
+
+/*
+ * Get various names from the string pool for various data types.
+ */
+#define sipNameFromPool(em, mr) (&((em)->em_strings)[(mr)])
+#define sipNameOfModule(em) sipNameFromPool((em), (em)->em_name)
+#define sipPyNameOfContainer(cod, td) sipNameFromPool((td)->td_module, (cod)->cod_name)
+#define sipPyNameOfEnum(etd) sipNameFromPool((etd)->etd_base.td_module, (etd)->etd_name)
+
+
+/*
+ * The following are PyQt3-specific extensions. In SIP v5 they will be pushed
+ * out to a plugin supplied by PyQt3.
+ */
+
+typedef int (*pyqt3EmitFunc)(sipSimpleWrapper *, PyObject *);
+
+
+/*
+ * Maps the name of a Qt signal to a wrapper function to emit it.
+ */
+typedef struct _pyqt3QtSignal {
+ /* The signal name. */
+ const char *st_name;
+
+ /* The emitter function. */
+ pyqt3EmitFunc st_emitfunc;
+} pyqt3QtSignal;
+
+
+/*
+ * This is the PyQt3-specific extension to the generated class type structure.
+ */
+typedef struct _pyqt3ClassTypeDef {
+ /*
+ * The super-type structure. This must be first in the structure so that
+ * it can be cast to sipClassTypeDef *.
+ */
+ sipClassTypeDef super;
+
+ /* The emit table for Qt signals. */
+ pyqt3QtSignal *qt3_emit;
+} pyqt3ClassTypeDef;
+
+
+/*
+ * The following are PyQt4-specific extensions. In SIP v5 they will be pushed
+ * out to a plugin supplied by PyQt4.
+ */
+
+/*
+ * The description of a Qt signal for PyQt4.
+ */
+typedef struct _pyqt4QtSignal {
+ /* The C++ name and signature of the signal. */
+ const char *signature;
+
+ /* The optional docstring. */
+ const char *docstring;
+
+ /*
+ * If the signal is an overload of regular methods then this points to the
+ * code that implements those methods.
+ */
+ PyMethodDef *non_signals;
+} pyqt4QtSignal;
+
+
+/*
+ * This is the PyQt4-specific extension to the generated class type structure.
+ */
+typedef struct _pyqt4ClassTypeDef {
+ /*
+ * The super-type structure. This must be first in the structure so that
+ * it can be cast to sipClassTypeDef *.
+ */
+ sipClassTypeDef super;
+
+ /* A pointer to the QObject sub-class's staticMetaObject class variable. */
+ const void *qt4_static_metaobject;
+
+ /*
+ * A set of flags. At the moment only bit 0 is used to say if the type is
+ * derived from QFlags.
+ */
+ unsigned qt4_flags;
+
+ /*
+ * The table of signals emitted by the type. These are grouped by signal
+ * name.
+ */
+ const pyqt4QtSignal *qt4_signals;
+} pyqt4ClassTypeDef;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/siplib/sipint.h b/siplib/sipint.h
new file mode 100644
index 0000000..19a8b1b
--- /dev/null
+++ b/siplib/sipint.h
@@ -0,0 +1,149 @@
+/*
+ * This file defines the SIP library internal interfaces.
+ *
+ * Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com>
+ *
+ * This file is part of SIP.
+ *
+ * This copy of SIP is licensed for use under the terms of the SIP License
+ * Agreement. See the file LICENSE for more details.
+ *
+ * This copy of SIP may also used under the terms of the GNU General Public
+ * License v2 or v3 as published by the Free Software Foundation which can be
+ * found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
+ *
+ * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#ifndef _SIPINT_H
+#define _SIPINT_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#undef TRUE
+#define TRUE 1
+
+#undef FALSE
+#define FALSE 0
+
+
+/*
+ * This defines a single entry in an object map's hash table.
+ */
+typedef struct
+{
+ void *key; /* The C/C++ address. */
+ sipSimpleWrapper *first; /* The first object at this address. */
+} sipHashEntry;
+
+
+/*
+ * This defines the interface to a hash table class for mapping C/C++ addresses
+ * to the corresponding wrapped Python object.
+ */
+typedef struct
+{
+ int primeIdx; /* Index into table sizes. */
+ unsigned long size; /* Size of hash table. */
+ unsigned long unused; /* Nr. unused in hash table. */
+ unsigned long stale; /* Nr. stale in hash table. */
+ sipHashEntry *hash_array; /* Current hash table. */
+} sipObjectMap;
+
+
+/*
+ * Support for the descriptors.
+ */
+extern PyTypeObject sipMethodDescr_Type;
+PyObject *sipMethodDescr_New(PyMethodDef *pmd);
+
+extern PyTypeObject sipVariableDescr_Type;
+PyObject *sipVariableDescr_New(sipVariableDef *vd, const sipTypeDef *td,
+ const sipContainerDef *cod);
+
+
+/*
+ * Support for API versions.
+ */
+PyObject *sipGetAPI(PyObject *self, PyObject *args);
+PyObject *sipSetAPI(PyObject *self, PyObject *args);
+int sip_api_is_api_enabled(const char *name, int from, int to);
+int sipIsRangeEnabled(sipExportedModuleDef *em, int range_index);
+int sipInitAPI(sipExportedModuleDef *em, PyObject *mod_dict);
+
+
+/*
+ * Support for void pointers.
+ */
+extern PyTypeObject sipVoidPtr_Type;
+void *sip_api_convert_to_void_ptr(PyObject *obj);
+PyObject *sip_api_convert_from_void_ptr(void *val);
+PyObject *sip_api_convert_from_const_void_ptr(const void *val);
+PyObject *sip_api_convert_from_void_ptr_and_size(void *val, SIP_SSIZE_T size);
+PyObject *sip_api_convert_from_const_void_ptr_and_size(const void *val,
+ SIP_SSIZE_T size);
+
+
+extern sipQtAPI *sipQtSupport; /* The Qt support API. */
+extern sipWrapperType sipSimpleWrapper_Type; /* The simple wrapper type. */
+extern sipTypeDef *sipQObjectType; /* The QObject type. */
+
+void *sipGetRx(sipSimpleWrapper *txSelf, const char *sigargs, PyObject *rxObj,
+ const char *slot, const char **memberp);
+PyObject *sip_api_connect_rx(PyObject *txObj, const char *sig, PyObject *rxObj,
+ const char *slot, int type);
+PyObject *sip_api_disconnect_rx(PyObject *txObj, const char *sig,
+ PyObject *rxObj,const char *slot);
+
+
+/*
+ * These are part of the SIP API but are also used within the SIP module.
+ */
+void *sip_api_malloc(size_t nbytes);
+void sip_api_free(void *mem);
+void *sip_api_get_cpp_ptr(sipSimpleWrapper *w, const sipTypeDef *td);
+PyObject *sip_api_convert_from_type(void *cppPtr, const sipTypeDef *td,
+ PyObject *transferObj);
+void sip_api_common_dtor(sipSimpleWrapper *sipSelf);
+void sip_api_start_thread(void);
+void sip_api_end_thread(void);
+void sip_api_free_sipslot(sipSlot *slot);
+int sip_api_same_slot(const sipSlot *sp, PyObject *rxObj, const char *slot);
+PyObject *sip_api_invoke_slot(const sipSlot *slot, PyObject *sigargs);
+void *sip_api_convert_rx(sipWrapper *txSelf, const char *sigargs,
+ PyObject *rxObj, const char *slot, const char **memberp, int flags);
+int sip_api_save_slot(sipSlot *sp, PyObject *rxObj, const char *slot);
+
+
+/*
+ * These are not part of the SIP API but are used within the SIP module.
+ */
+void sipSaveMethod(sipPyMethod *pm,PyObject *meth);
+void *sipGetPending(sipWrapper **op, int *fp);
+PyObject *sipWrapSimpleInstance(void *cppPtr, const sipTypeDef *td,
+ sipWrapper *owner, int initflags);
+void *sipConvertRxEx(sipWrapper *txSelf, const char *sigargs,
+ PyObject *rxObj, const char *slot, const char **memberp, int flags);
+
+void sipOMInit(sipObjectMap *om);
+void sipOMFinalise(sipObjectMap *om);
+sipSimpleWrapper *sipOMFindObject(sipObjectMap *om, void *key,
+ const sipTypeDef *td);
+void sipOMAddObject(sipObjectMap *om, sipSimpleWrapper *val);
+int sipOMRemoveObject(sipObjectMap *om, sipSimpleWrapper *val);
+
+void sipSetBool(void *ptr,int val);
+
+void *sipGetAddress(sipSimpleWrapper *w);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/siplib/siplib.c b/siplib/siplib.c
new file mode 100644
index 0000000..f419b6b
--- /dev/null
+++ b/siplib/siplib.c
@@ -0,0 +1,10501 @@
+/*
+ * SIP library code.
+ *
+ * Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com>
+ *
+ * This file is part of SIP.
+ *
+ * This copy of SIP is licensed for use under the terms of the SIP License
+ * Agreement. See the file LICENSE for more details.
+ *
+ * This copy of SIP may also used under the terms of the GNU General Public
+ * License v2 or v3 as published by the Free Software Foundation which can be
+ * found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
+ *
+ * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#include <Python.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "sip.h"
+#include "sipint.h"
+
+
+/* There doesn't seem to be a standard way of checking for C99 support. */
+#if !defined(va_copy)
+#define va_copy(d, s) ((d) = (s))
+#endif
+
+
+/*
+ * The Python metatype for a C++ wrapper type. We inherit everything from the
+ * standard Python metatype except the init and getattro methods and the size
+ * of the type object created is increased to accomodate the extra information
+ * we associate with a wrapped type.
+ */
+
+static PyObject *sipWrapperType_alloc(PyTypeObject *self, SIP_SSIZE_T nitems);
+static PyObject *sipWrapperType_getattro(PyObject *self, PyObject *name);
+static int sipWrapperType_init(sipWrapperType *self, PyObject *args,
+ PyObject *kwds);
+static int sipWrapperType_setattro(PyObject *self, PyObject *name,
+ PyObject *value);
+
+static PyTypeObject sipWrapperType_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "sip.wrappertype", /* tp_name */
+ sizeof (sipWrapperType), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved (Python v3), tp_compare (Python v2) */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ sipWrapperType_getattro, /* tp_getattro */
+ sipWrapperType_setattro, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ (initproc)sipWrapperType_init, /* tp_init */
+ sipWrapperType_alloc, /* tp_alloc */
+ 0, /* tp_new */
+ 0, /* tp_free */
+};
+
+
+/*
+ * The Python type that is the super-type for all C++ wrapper types that
+ * support parent/child relationships.
+ */
+
+static int sipWrapper_clear(sipWrapper *self);
+static void sipWrapper_dealloc(sipWrapper *self);
+static int sipWrapper_traverse(sipWrapper *self, visitproc visit, void *arg);
+
+static sipWrapperType sipWrapper_Type = {
+#if !defined(STACKLESS)
+ {
+#endif
+ {
+ PyVarObject_HEAD_INIT(&sipWrapperType_Type, 0)
+ "sip.wrapper", /* tp_name */
+ sizeof (sipWrapper), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)sipWrapper_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved (Python v3), tp_compare (Python v2) */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)sipWrapper_traverse, /* tp_traverse */
+ (inquiry)sipWrapper_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+ 0, /* tp_free */
+ },
+#if !defined(STACKLESS)
+ },
+#endif
+ 0,
+ 0
+};
+
+
+static void sip_api_bad_catcher_result(PyObject *method);
+static void sip_api_bad_length_for_slice(SIP_SSIZE_T seqlen,
+ SIP_SSIZE_T slicelen);
+static PyObject *sip_api_build_result(int *isErr, const char *fmt, ...);
+static PyObject *sip_api_call_method(int *isErr, PyObject *method,
+ const char *fmt, ...);
+static SIP_SSIZE_T sip_api_convert_from_sequence_index(SIP_SSIZE_T idx,
+ SIP_SSIZE_T len);
+static int sip_api_can_convert_to_type(PyObject *pyObj, const sipTypeDef *td,
+ int flags);
+static void *sip_api_convert_to_type(PyObject *pyObj, const sipTypeDef *td,
+ PyObject *transferObj, int flags, int *statep, int *iserrp);
+static void *sip_api_force_convert_to_type(PyObject *pyObj,
+ const sipTypeDef *td, PyObject *transferObj, int flags, int *statep,
+ int *iserrp);
+static int sip_api_can_convert_to_enum(PyObject *pyObj, const sipTypeDef *td);
+static void sip_api_release_type(void *cpp, const sipTypeDef *td, int state);
+static PyObject *sip_api_convert_from_new_type(void *cpp, const sipTypeDef *td,
+ PyObject *transferObj);
+static int sip_api_get_state(PyObject *transferObj);
+static PyObject *sip_api_get_pyobject(void *cppPtr, const sipTypeDef *td);
+static sipWrapperType *sip_api_map_int_to_class(int typeInt,
+ const sipIntTypeClassMap *map, int maplen);
+static sipWrapperType *sip_api_map_string_to_class(const char *typeString,
+ const sipStringTypeClassMap *map, int maplen);
+static int sip_api_parse_result(int *isErr, PyObject *method, PyObject *res,
+ const char *fmt, ...);
+static void sip_api_trace(unsigned mask,const char *fmt,...);
+static void sip_api_transfer_back(PyObject *self);
+static void sip_api_transfer_to(PyObject *self, PyObject *owner);
+static int sip_api_export_module(sipExportedModuleDef *client,
+ unsigned api_major, unsigned api_minor, void *unused);
+static int sip_api_init_module(sipExportedModuleDef *client,
+ PyObject *mod_dict);
+static int sip_api_parse_args(PyObject **parseErrp, PyObject *sipArgs,
+ const char *fmt, ...);
+static int sip_api_parse_kwd_args(PyObject **parseErrp, PyObject *sipArgs,
+ PyObject *sipKwdArgs, const char **kwdlist, PyObject **unused,
+ const char *fmt, ...);
+static int sip_api_parse_pair(PyObject **parseErrp, PyObject *sipArg0,
+ PyObject *sipArg1, const char *fmt, ...);
+static void sip_api_no_function(PyObject *parseErr, const char *func,
+ const char *doc);
+static void sip_api_no_method(PyObject *parseErr, const char *scope,
+ const char *method, const char *doc);
+static void sip_api_abstract_method(const char *classname, const char *method);
+static void sip_api_bad_class(const char *classname);
+static void *sip_api_get_complex_cpp_ptr(sipSimpleWrapper *sw);
+static PyObject *sip_api_is_py_method(sip_gilstate_t *gil, char *pymc,
+ sipSimpleWrapper *sipSelf, const char *cname, const char *mname);
+static void sip_api_call_hook(const char *hookname);
+static void sip_api_raise_unknown_exception(void);
+static void sip_api_raise_type_exception(const sipTypeDef *td, void *ptr);
+static int sip_api_add_type_instance(PyObject *dict, const char *name,
+ void *cppPtr, const sipTypeDef *td);
+static sipErrorState sip_api_bad_callable_arg(int arg_nr, PyObject *arg);
+static void sip_api_bad_operator_arg(PyObject *self, PyObject *arg,
+ sipPySlotType st);
+static PyObject *sip_api_pyslot_extend(sipExportedModuleDef *mod,
+ sipPySlotType st, const sipTypeDef *td, PyObject *arg0,
+ PyObject *arg1);
+static void sip_api_add_delayed_dtor(sipSimpleWrapper *w);
+static unsigned long sip_api_long_as_unsigned_long(PyObject *o);
+static int sip_api_export_symbol(const char *name, void *sym);
+static void *sip_api_import_symbol(const char *name);
+static const sipTypeDef *sip_api_find_type(const char *type);
+static sipWrapperType *sip_api_find_class(const char *type);
+static const sipMappedType *sip_api_find_mapped_type(const char *type);
+static PyTypeObject *sip_api_find_named_enum(const char *type);
+static char sip_api_bytes_as_char(PyObject *obj);
+static const char *sip_api_bytes_as_string(PyObject *obj);
+static char sip_api_string_as_ascii_char(PyObject *obj);
+static const char *sip_api_string_as_ascii_string(PyObject **obj);
+static char sip_api_string_as_latin1_char(PyObject *obj);
+static const char *sip_api_string_as_latin1_string(PyObject **obj);
+static char sip_api_string_as_utf8_char(PyObject *obj);
+static const char *sip_api_string_as_utf8_string(PyObject **obj);
+#if defined(HAVE_WCHAR_H)
+static wchar_t sip_api_unicode_as_wchar(PyObject *obj);
+static wchar_t *sip_api_unicode_as_wstring(PyObject *obj);
+#else
+static int sip_api_unicode_as_wchar(PyObject *obj);
+static int *sip_api_unicode_as_wstring(PyObject *obj);
+#endif
+static void sip_api_transfer_break(PyObject *self);
+static int sip_api_deprecated(const char *classname, const char *method);
+static int sip_api_register_py_type(PyTypeObject *supertype);
+static PyObject *sip_api_convert_from_enum(int eval, const sipTypeDef *td);
+static const sipTypeDef *sip_api_type_from_py_type_object(PyTypeObject *py_type);
+static const sipTypeDef *sip_api_type_scope(const sipTypeDef *td);
+static const char *sip_api_resolve_typedef(const char *name);
+static int sip_api_register_attribute_getter(const sipTypeDef *td,
+ sipAttrGetterFunc getter);
+static void sip_api_clear_any_slot_reference(sipSlot *slot);
+static int sip_api_visit_slot(sipSlot *slot, visitproc visit, void *arg);
+static void sip_api_keep_reference(PyObject *self, int key, PyObject *obj);
+static void sip_api_add_exception(sipErrorState es, PyObject **parseErrp);
+
+
+/*
+ * The data structure that represents the SIP API.
+ */
+static const sipAPIDef sip_api = {
+ /* This must be first. */
+ sip_api_export_module,
+ /*
+ * The following are part of the public API.
+ */
+ (PyTypeObject *)&sipSimpleWrapper_Type,
+ (PyTypeObject *)&sipWrapper_Type,
+ &sipWrapperType_Type,
+ &sipVoidPtr_Type,
+
+ sip_api_bad_catcher_result,
+ sip_api_bad_length_for_slice,
+ sip_api_build_result,
+ sip_api_call_method,
+ sip_api_connect_rx,
+ sip_api_convert_from_sequence_index,
+ sip_api_can_convert_to_type,
+ sip_api_convert_to_type,
+ sip_api_force_convert_to_type,
+ sip_api_can_convert_to_enum,
+ sip_api_release_type,
+ sip_api_convert_from_type,
+ sip_api_convert_from_new_type,
+ sip_api_convert_from_enum,
+ sip_api_get_state,
+ sip_api_disconnect_rx,
+ sip_api_free,
+ sip_api_get_pyobject,
+ sip_api_malloc,
+ sip_api_parse_result,
+ sip_api_trace,
+ sip_api_transfer_back,
+ sip_api_transfer_to,
+ sip_api_transfer_break,
+ sip_api_long_as_unsigned_long,
+ sip_api_convert_from_void_ptr,
+ sip_api_convert_from_const_void_ptr,
+ sip_api_convert_from_void_ptr_and_size,
+ sip_api_convert_from_const_void_ptr_and_size,
+ sip_api_convert_to_void_ptr,
+ sip_api_export_symbol,
+ sip_api_import_symbol,
+ sip_api_find_type,
+ sip_api_register_py_type,
+ sip_api_type_from_py_type_object,
+ sip_api_type_scope,
+ sip_api_resolve_typedef,
+ sip_api_register_attribute_getter,
+ sip_api_is_api_enabled,
+ sip_api_bad_callable_arg,
+ /*
+ * The following are deprecated parts of the public API.
+ */
+ sip_api_find_named_enum,
+ sip_api_find_mapped_type,
+ sip_api_find_class,
+ sip_api_map_int_to_class,
+ sip_api_map_string_to_class,
+ /*
+ * The following may be used by Qt support code but by no other handwritten
+ * code.
+ */
+ sip_api_free_sipslot,
+ sip_api_same_slot,
+ sip_api_convert_rx,
+ sip_api_invoke_slot,
+ sip_api_save_slot,
+ sip_api_clear_any_slot_reference,
+ sip_api_visit_slot,
+ /*
+ * The following are not part of the public API.
+ */
+ sip_api_init_module,
+ sip_api_parse_args,
+ sip_api_parse_pair,
+ sip_api_common_dtor,
+ sip_api_no_function,
+ sip_api_no_method,
+ sip_api_abstract_method,
+ sip_api_bad_class,
+ sip_api_get_cpp_ptr,
+ sip_api_get_complex_cpp_ptr,
+ sip_api_is_py_method,
+ sip_api_call_hook,
+ sip_api_start_thread,
+ sip_api_end_thread,
+ sip_api_raise_unknown_exception,
+ sip_api_raise_type_exception,
+ sip_api_add_type_instance,
+ sip_api_bad_operator_arg,
+ sip_api_pyslot_extend,
+ sip_api_add_delayed_dtor,
+ sip_api_bytes_as_char,
+ sip_api_bytes_as_string,
+ sip_api_string_as_ascii_char,
+ sip_api_string_as_ascii_string,
+ sip_api_string_as_latin1_char,
+ sip_api_string_as_latin1_string,
+ sip_api_string_as_utf8_char,
+ sip_api_string_as_utf8_string,
+ sip_api_unicode_as_wchar,
+ sip_api_unicode_as_wstring,
+ sip_api_deprecated,
+ sip_api_keep_reference,
+ sip_api_parse_kwd_args,
+ sip_api_add_exception
+};
+
+
+#define AUTO_DOCSTRING '\1' /* Marks an auto class docstring. */
+
+
+/*
+ * These are the format flags supported by argument parsers.
+ */
+#define FMT_AP_DEREF 0x01 /* The pointer will be dereferenced. */
+#define FMT_AP_TRANSFER 0x02 /* Implement /Transfer/. */
+#define FMT_AP_TRANSFER_BACK 0x04 /* Implement /TransferBack/. */
+#define FMT_AP_NO_CONVERTORS 0x08 /* Suppress any convertors. */
+#define FMT_AP_TRANSFER_THIS 0x10 /* Support for /TransferThis/. */
+
+
+/*
+ * These are the format flags supported by result parsers. Deprecated values
+ * have a _DEPR suffix.
+ */
+#define FMT_RP_DEREF 0x01 /* The pointer will be dereferenced. */
+#define FMT_RP_FACTORY 0x02 /* /Factory/ or /TransferBack/. */
+#define FMT_RP_MAKE_COPY 0x04 /* Return a copy of the value. */
+#define FMT_RP_NO_STATE_DEPR 0x04 /* Don't return the C/C++ state. */
+
+
+/*
+ * The different reasons for failing to parse an overload. These include
+ * internal (i.e. non-user) errors.
+ */
+typedef enum {
+ Ok, Unbound, TooFew, TooMany, UnknownKeyword, Duplicate, WrongType, Raised,
+ KeywordNotString, Exception
+} sipParseFailureReason;
+
+
+/*
+ * The description of a failure to parse an overload because of a user error.
+ */
+typedef struct _sipParseFailure {
+ sipParseFailureReason reason; /* The reason for the failure. */
+ const char *detail_str; /* The detail if a string. */
+ PyObject *detail_obj; /* The detail if a Python object. */
+ int arg_nr; /* The wrong positional argument. */
+ const char *arg_name; /* The wrong keyword argument. */
+} sipParseFailure;
+
+
+/*
+ * An entry in a linked list of name/symbol pairs.
+ */
+typedef struct _sipSymbol {
+ const char *name; /* The name. */
+ void *symbol; /* The symbol. */
+ struct _sipSymbol *next; /* The next in the list. */
+} sipSymbol;
+
+
+/*
+ * An entry in a linked list of Python objects.
+ */
+typedef struct _sipPyObject {
+ PyObject *object; /* The Python object. */
+ struct _sipPyObject *next; /* The next in the list. */
+} sipPyObject;
+
+
+/*
+ * An entry in the linked list of attribute getters.
+ */
+typedef struct _sipAttrGetter {
+ PyTypeObject *type; /* The Python type being handled. */
+ sipAttrGetterFunc getter; /* The getter. */
+ struct _sipAttrGetter *next; /* The next in the list. */
+} sipAttrGetter;
+
+
+/*****************************************************************************
+ * The structures to support a Python type to hold a named enum.
+ *****************************************************************************/
+
+static PyObject *sipEnumType_alloc(PyTypeObject *self, SIP_SSIZE_T nitems);
+
+/*
+ * The type data structure. We inherit everything from the standard Python
+ * metatype and the size of the type object created is increased to accomodate
+ * the extra information we associate with a named enum type.
+ */
+static PyTypeObject sipEnumType_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "sip.enumtype", /* tp_name */
+ sizeof (sipEnumTypeObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved (Python v3), tp_compare (Python v2) */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ sipEnumType_alloc, /* tp_alloc */
+ 0, /* tp_new */
+ 0, /* tp_free */
+};
+
+
+sipQtAPI *sipQtSupport = NULL;
+sipTypeDef *sipQObjectType;
+
+
+/*
+ * Various strings as Python objects created as and when needed.
+ */
+static PyObject *licenseName = NULL;
+static PyObject *licenseeName = NULL;
+static PyObject *typeName = NULL;
+static PyObject *timestampName = NULL;
+static PyObject *signatureName = NULL;
+
+static sipObjectMap cppPyMap; /* The C/C++ to Python map. */
+static sipExportedModuleDef *moduleList = NULL; /* List of registered modules. */
+static unsigned traceMask = 0; /* The current trace mask. */
+
+static sipTypeDef *currentType = NULL; /* The type being created. */
+
+static PyObject *type_unpickler; /* The type unpickler function. */
+static PyObject *enum_unpickler; /* The enum unpickler function. */
+static sipSymbol *sipSymbolList = NULL; /* The list of published symbols. */
+static sipAttrGetter *sipAttrGetters = NULL; /* The list of attribute getters. */
+static sipPyObject *sipRegisteredPyTypes = NULL; /* Registered Python types. */
+static PyInterpreterState *sipInterpreter = NULL; /* The interpreter. */
+
+
+static void addClassSlots(sipWrapperType *wt, sipClassTypeDef *ctd);
+static void addTypeSlots(PyHeapTypeObject *heap_to, sipPySlotDef *slots);
+static void *findSlot(PyObject *self, sipPySlotType st);
+static void *findSlotInType(sipPySlotDef *psd, sipPySlotType st);
+static int objobjargprocSlot(PyObject *self, PyObject *arg1, PyObject *arg2,
+ sipPySlotType st);
+static int ssizeobjargprocSlot(PyObject *self, SIP_SSIZE_T arg1,
+ PyObject *arg2, sipPySlotType st);
+static PyObject *buildObject(PyObject *tup, const char *fmt, va_list va);
+static int parseKwdArgs(PyObject **parseErrp, PyObject *sipArgs,
+ PyObject *sipKwdArgs, const char **kwdlist, PyObject **unused,
+ const char *fmt, va_list va_orig);
+static int parsePass1(PyObject **parseErrp, sipSimpleWrapper **selfp,
+ int *selfargp, PyObject *sipArgs, PyObject *sipKwdArgs,
+ const char **kwdlist, PyObject **unused, const char *fmt, va_list va);
+static int parsePass2(sipSimpleWrapper *self, int selfarg, PyObject *sipArgs,
+ PyObject *sipKwdArgs, const char **kwdlist, const char *fmt,
+ va_list va);
+static PyObject *signature_FromDocstring(const char *doc, SIP_SSIZE_T line);
+static PyObject *detail_FromFailure(PyObject *failure_obj);
+static int isQObject(PyObject *obj);
+static int canConvertFromSequence(PyObject *seq, const sipTypeDef *td);
+static int convertFromSequence(PyObject *seq, const sipTypeDef *td,
+ void **array, SIP_SSIZE_T *nr_elem);
+static PyObject *convertToSequence(void *array, SIP_SSIZE_T nr_elem,
+ const sipTypeDef *td);
+static int getSelfFromArgs(sipTypeDef *td, PyObject *args, int argnr,
+ sipSimpleWrapper **selfp);
+static PyObject *createEnumMember(sipTypeDef *td, sipEnumMemberDef *enm);
+static int compareTypedefName(const void *key, const void *el);
+static int checkPointer(void *ptr);
+static void *cast_cpp_ptr(void *ptr, PyTypeObject *src_type,
+ const sipTypeDef *dst_type);
+static void finalise(void);
+static PyObject *getDefaultBases(void);
+static PyObject *getScopeDict(sipTypeDef *td, PyObject *mod_dict,
+ sipExportedModuleDef *client);
+static PyObject *createContainerType(sipContainerDef *cod, sipTypeDef *td,
+ PyObject *bases, PyObject *metatype, PyObject *mod_dict,
+ sipExportedModuleDef *client);
+static int createClassType(sipExportedModuleDef *client, sipClassTypeDef *ctd,
+ PyObject *mod_dict);
+static int createMappedType(sipExportedModuleDef *client,
+ sipMappedTypeDef *mtd, PyObject *mod_dict);
+static sipExportedModuleDef *getModule(PyObject *mname_obj);
+static PyObject *pickle_type(PyObject *obj, PyObject *);
+static PyObject *unpickle_type(PyObject *, PyObject *args);
+static PyObject *pickle_enum(PyObject *obj, PyObject *);
+static PyObject *unpickle_enum(PyObject *, PyObject *args);
+static int setReduce(PyTypeObject *type, PyMethodDef *pickler);
+static int createEnumType(sipExportedModuleDef *client, sipEnumTypeDef *etd,
+ PyObject *mod_dict);
+static PyObject *createTypeDict(PyObject *mname);
+static sipExportedModuleDef *getTypeModule(const sipEncodedTypeDef *enc,
+ sipExportedModuleDef *em);
+static sipTypeDef *getGeneratedType(const sipEncodedTypeDef *enc,
+ sipExportedModuleDef *em);
+static const sipTypeDef *convertSubClass(const sipTypeDef *td, void **cppPtr);
+static void *getPtrTypeDef(sipSimpleWrapper *self,
+ const sipClassTypeDef **ctd);
+static int addInstances(PyObject *dict, sipInstancesDef *id);
+static int addVoidPtrInstances(PyObject *dict, sipVoidPtrInstanceDef *vi);
+static int addCharInstances(PyObject *dict, sipCharInstanceDef *ci);
+static int addStringInstances(PyObject *dict, sipStringInstanceDef *si);
+static int addIntInstances(PyObject *dict, sipIntInstanceDef *ii);
+static int addLongInstances(PyObject *dict, sipLongInstanceDef *li);
+static int addUnsignedLongInstances(PyObject *dict,
+ sipUnsignedLongInstanceDef *uli);
+static int addLongLongInstances(PyObject *dict, sipLongLongInstanceDef *lli);
+static int addUnsignedLongLongInstances(PyObject *dict,
+ sipUnsignedLongLongInstanceDef *ulli);
+static int addDoubleInstances(PyObject *dict, sipDoubleInstanceDef *di);
+static int addTypeInstances(PyObject *dict, sipTypeInstanceDef *ti);
+static int addSingleTypeInstance(PyObject *dict, const char *name,
+ void *cppPtr, const sipTypeDef *td, int initflags);
+static int addLicense(PyObject *dict, sipLicenseDef *lc);
+static PyObject *cast(PyObject *self, PyObject *args);
+static PyObject *callDtor(PyObject *self, PyObject *args);
+static PyObject *dumpWrapper(PyObject *self, PyObject *args);
+static PyObject *isDeleted(PyObject *self, PyObject *args);
+static PyObject *isPyOwned(PyObject *self, PyObject *args);
+static PyObject *setDeleted(PyObject *self, PyObject *args);
+static PyObject *setTraceMask(PyObject *self, PyObject *args);
+static PyObject *wrapInstance(PyObject *self, PyObject *args);
+static PyObject *unwrapInstance(PyObject *self, PyObject *args);
+static PyObject *transferBack(PyObject *self, PyObject *args);
+static PyObject *transferTo(PyObject *self, PyObject *args);
+static void print_object(const char *label, PyObject *obj);
+static void addToParent(sipWrapper *self, sipWrapper *owner);
+static void removeFromParent(sipWrapper *self);
+static void release(void *addr, const sipTypeDef *td, int state);
+static void callPyDtor(sipSimpleWrapper *self);
+static int parseBytes_AsCharArray(PyObject *obj, const char **ap,
+ SIP_SSIZE_T *aszp);
+static int parseBytes_AsChar(PyObject *obj, char *ap);
+static int parseBytes_AsString(PyObject *obj, const char **ap);
+static int parseString_AsASCIIChar(PyObject *obj, char *ap);
+static PyObject *parseString_AsASCIIString(PyObject *obj, const char **ap);
+static int parseString_AsLatin1Char(PyObject *obj, char *ap);
+static PyObject *parseString_AsLatin1String(PyObject *obj, const char **ap);
+static int parseString_AsUTF8Char(PyObject *obj, char *ap);
+static PyObject *parseString_AsUTF8String(PyObject *obj, const char **ap);
+static int parseString_AsEncodedChar(PyObject *bytes, PyObject *obj, char *ap);
+static PyObject *parseString_AsEncodedString(PyObject *bytes, PyObject *obj,
+ const char **ap);
+#if defined(HAVE_WCHAR_H)
+static int parseWCharArray(PyObject *obj, wchar_t **ap, SIP_SSIZE_T *aszp);
+static int convertToWCharArray(PyObject *obj, wchar_t **ap, SIP_SSIZE_T *aszp);
+static int parseWChar(PyObject *obj, wchar_t *ap);
+static int convertToWChar(PyObject *obj, wchar_t *ap);
+static int parseWCharString(PyObject *obj, wchar_t **ap);
+static int convertToWCharString(PyObject *obj, wchar_t **ap);
+#else
+static void raiseNoWChar();
+#endif
+static void *getComplexCppPtr(sipSimpleWrapper *w, const sipTypeDef *td);
+static PyObject *findPyType(const char *name);
+static int addPyObjectToList(sipPyObject **head, PyObject *object);
+static PyObject *getDictFromObject(PyObject *obj);
+static void forgetObject(sipSimpleWrapper *sw);
+static int add_lazy_container_attrs(sipTypeDef *td, sipContainerDef *cod,
+ PyObject *dict);
+static int add_lazy_attrs(sipTypeDef *td);
+static int add_all_lazy_attrs(sipTypeDef *td);
+static int objectify(const char *s, PyObject **objp);
+static void add_failure(PyObject **parseErrp, sipParseFailure *failure);
+static PyObject *bad_type_str(int arg_nr, PyObject *arg);
+
+
+/*
+ * The Python module initialisation function.
+ */
+#if PY_MAJOR_VERSION >= 3
+#define SIP_MODULE_ENTRY PyInit_sip
+#define SIP_MODULE_TYPE PyObject *
+#define SIP_MODULE_DISCARD(m) Py_DECREF(m)
+#define SIP_FATAL(s) return NULL
+#define SIP_MODULE_RETURN(m) return (m)
+#else
+#define SIP_MODULE_ENTRY initsip
+#define SIP_MODULE_TYPE void
+#define SIP_MODULE_DISCARD(m)
+#define SIP_FATAL(s) Py_FatalError(s)
+#define SIP_MODULE_RETURN(m)
+#endif
+
+#if defined(SIP_STATIC_MODULE)
+SIP_MODULE_TYPE SIP_MODULE_ENTRY(void)
+#else
+PyMODINIT_FUNC SIP_MODULE_ENTRY(void)
+#endif
+{
+ static PyMethodDef methods[] = {
+ {"cast", cast, METH_VARARGS, NULL},
+ {"delete", callDtor, METH_VARARGS, NULL},
+ {"dump", dumpWrapper, METH_VARARGS, NULL},
+ {"getapi", sipGetAPI, METH_VARARGS, NULL},
+ {"isdeleted", isDeleted, METH_VARARGS, NULL},
+ {"ispyowned", isPyOwned, METH_VARARGS, NULL},
+ {"setapi", sipSetAPI, METH_VARARGS, NULL},
+ {"setdeleted", setDeleted, METH_VARARGS, NULL},
+ {"settracemask", setTraceMask, METH_VARARGS, NULL},
+ {"transferback", transferBack, METH_VARARGS, NULL},
+ {"transferto", transferTo, METH_VARARGS, NULL},
+ {"wrapinstance", wrapInstance, METH_VARARGS, NULL},
+ {"unwrapinstance", unwrapInstance, METH_VARARGS, NULL},
+ {"_unpickle_type", unpickle_type, METH_VARARGS, NULL},
+ {"_unpickle_enum", unpickle_enum, METH_VARARGS, NULL},
+ {NULL, NULL, 0, NULL}
+ };
+
+#if PY_MAJOR_VERSION >= 3
+ static PyModuleDef module_def = {
+ PyModuleDef_HEAD_INIT,
+ "sip", /* m_name */
+ NULL, /* m_doc */
+ -1, /* m_size */
+ methods, /* m_methods */
+ NULL, /* m_reload */
+ NULL, /* m_traverse */
+ NULL, /* m_clear */
+ NULL, /* m_free */
+ };
+#endif
+
+ int rc;
+ PyObject *mod, *mod_dict, *obj;
+
+#ifdef WITH_THREAD
+ PyEval_InitThreads();
+#endif
+
+ /* Initialise the types. */
+ sipWrapperType_Type.tp_base = &PyType_Type;
+
+ if (PyType_Ready(&sipWrapperType_Type) < 0)
+ SIP_FATAL("sip: Failed to initialise sip.wrappertype type");
+
+ if (PyType_Ready((PyTypeObject *)&sipSimpleWrapper_Type) < 0)
+ SIP_FATAL("sip: Failed to initialise sip.simplewrapper type");
+
+ if (sip_api_register_py_type((PyTypeObject *)&sipSimpleWrapper_Type) < 0)
+ SIP_FATAL("sip: Failed to register sip.simplewrapper type");
+
+#if defined(STACKLESS)
+ sipWrapper_Type.super.tp_base = (PyTypeObject *)&sipSimpleWrapper_Type;
+#elif PY_VERSION_HEX >= 0x02050000
+ sipWrapper_Type.super.ht_type.tp_base = (PyTypeObject *)&sipSimpleWrapper_Type;
+#else
+ sipWrapper_Type.super.type.tp_base = (PyTypeObject *)&sipSimpleWrapper_Type;
+#endif
+
+ if (PyType_Ready((PyTypeObject *)&sipWrapper_Type) < 0)
+ SIP_FATAL("sip: Failed to initialise sip.wrapper type");
+
+ if (PyType_Ready(&sipMethodDescr_Type) < 0)
+ SIP_FATAL("sip: Failed to initialise sip.methoddescriptor type");
+
+ if (PyType_Ready(&sipVariableDescr_Type) < 0)
+ SIP_FATAL("sip: Failed to initialise sip.variabledescriptor type");
+
+ sipEnumType_Type.tp_base = &PyType_Type;
+
+ if (PyType_Ready(&sipEnumType_Type) < 0)
+ SIP_FATAL("sip: Failed to initialise sip.enumtype type");
+
+ if (PyType_Ready(&sipVoidPtr_Type) < 0)
+ SIP_FATAL("sip: Failed to initialise sip.voidptr type");
+
+#if PY_MAJOR_VERSION >= 3
+ mod = PyModule_Create(&module_def);
+#else
+ mod = Py_InitModule("sip", methods);
+#endif
+
+ if (mod == NULL)
+ SIP_FATAL("sip: Failed to intialise sip module");
+
+ mod_dict = PyModule_GetDict(mod);
+
+ /* Get a reference to the pickle helpers. */
+ type_unpickler = PyDict_GetItemString(mod_dict, "_unpickle_type");
+ enum_unpickler = PyDict_GetItemString(mod_dict, "_unpickle_enum");
+
+ if (type_unpickler == NULL || enum_unpickler == NULL)
+ {
+ SIP_MODULE_DISCARD(mod);
+ SIP_FATAL("sip: Failed to get pickle helpers");
+ }
+
+ /* Publish the SIP API. */
+#if defined(SIP_USE_PYCAPSULE)
+ obj = PyCapsule_New((void *)&sip_api, "sip._C_API", NULL);
+#else
+ obj = PyCObject_FromVoidPtr((void *)&sip_api, NULL);
+#endif
+
+ if (obj == NULL)
+ {
+ SIP_MODULE_DISCARD(mod);
+ SIP_FATAL("sip: Failed to create _C_API object");
+ }
+
+ rc = PyDict_SetItemString(mod_dict, "_C_API", obj);
+ Py_DECREF(obj);
+
+ if (rc < 0)
+ {
+ SIP_MODULE_DISCARD(mod);
+ SIP_FATAL("sip: Failed to add _C_API object to module dictionary");
+ }
+
+ /* Add the SIP version number, but don't worry about errors. */
+#if PY_MAJOR_VERSION >= 3
+ obj = PyLong_FromLong(SIP_VERSION);
+#else
+ obj = PyInt_FromLong(SIP_VERSION);
+#endif
+
+ if (obj != NULL)
+ {
+ PyDict_SetItemString(mod_dict, "SIP_VERSION", obj);
+ Py_DECREF(obj);
+ }
+
+#if PY_MAJOR_VERSION >= 3
+ obj = PyUnicode_FromString(SIP_VERSION_STR);
+#else
+ obj = PyString_FromString(SIP_VERSION_STR);
+#endif
+
+ if (obj != NULL)
+ {
+ PyDict_SetItemString(mod_dict, "SIP_VERSION_STR", obj);
+ Py_DECREF(obj);
+ }
+
+ /* Add the type objects, but don't worry about errors. */
+ PyDict_SetItemString(mod_dict, "wrappertype",
+ (PyObject *)&sipWrapperType_Type);
+ PyDict_SetItemString(mod_dict, "simplewrapper",
+ (PyObject *)&sipSimpleWrapper_Type);
+ PyDict_SetItemString(mod_dict, "wrapper", (PyObject *)&sipWrapper_Type);
+ PyDict_SetItemString(mod_dict, "voidptr", (PyObject *)&sipVoidPtr_Type);
+
+ /* Initialise the module if it hasn't already been done. */
+ if (sipInterpreter == NULL)
+ {
+ Py_AtExit(finalise);
+
+ /* Initialise the object map. */
+ sipOMInit(&cppPyMap);
+
+ sipQtSupport = NULL;
+
+ /*
+ * Get the current interpreter. This will be shared between all
+ * threads.
+ */
+ sipInterpreter = PyThreadState_Get()->interp;
+ }
+
+ SIP_MODULE_RETURN(mod);
+}
+
+
+/*
+ * Display a printf() style message to stderr according to the current trace
+ * mask.
+ */
+static void sip_api_trace(unsigned mask, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap,fmt);
+
+ if (mask & traceMask)
+ vfprintf(stderr, fmt, ap);
+
+ va_end(ap);
+}
+
+
+/*
+ * Set the trace mask.
+ */
+static PyObject *setTraceMask(PyObject *self, PyObject *args)
+{
+ unsigned new_mask;
+
+ if (PyArg_ParseTuple(args, "I:settracemask", &new_mask))
+ {
+ traceMask = new_mask;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ return NULL;
+}
+
+
+/*
+ * Dump various bits of potentially useful information to stdout.
+ */
+static PyObject *dumpWrapper(PyObject *self, PyObject *args)
+{
+ sipSimpleWrapper *sw;
+
+ if (PyArg_ParseTuple(args, "O!:dump", &sipSimpleWrapper_Type, &sw))
+ {
+ print_object(NULL, (PyObject *)sw);
+
+#if PY_VERSION_HEX >= 0x02050000
+ printf(" Reference count: %" PY_FORMAT_SIZE_T "d\n", Py_REFCNT(sw));
+#else
+ printf(" Reference count: %d\n", Py_REFCNT(sw));
+#endif
+ printf(" Address of wrapped object: %p\n", sipGetAddress(sw));
+ printf(" To be destroyed by: %s\n", (sipIsPyOwned(sw) ? "Python" : "C/C++"));
+ printf(" Derived class?: %s\n", (sipIsDerived(sw) ? "yes" : "no"));
+
+ if (PyObject_TypeCheck((PyObject *)sw, (PyTypeObject *)&sipWrapper_Type))
+ {
+ sipWrapper *w = (sipWrapper *)sw;
+
+ print_object("Parent wrapper", (PyObject *)w->parent);
+ print_object("Next sibling wrapper", (PyObject *)w->sibling_next);
+ print_object("Previous sibling wrapper",
+ (PyObject *)w->sibling_prev);
+ print_object("First child wrapper", (PyObject *)w->first_child);
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ return NULL;
+}
+
+
+/*
+ * Write a reference to a wrapper to stdout.
+ */
+static void print_object(const char *label, PyObject *obj)
+{
+ if (label != NULL)
+ printf(" %s: ", label);
+
+ if (obj != NULL)
+ PyObject_Print(obj, stdout, 0);
+ else
+ printf("NULL");
+
+ printf("\n");
+}
+
+
+/*
+ * Transfer the ownership of an instance to C/C++.
+ */
+static PyObject *transferTo(PyObject *self, PyObject *args)
+{
+ PyObject *w, *owner;
+
+ if (PyArg_ParseTuple(args, "O!O:transferto", &sipWrapper_Type, &w, &owner))
+ {
+ if (owner == Py_None)
+ owner = NULL;
+ else if (PyObject_TypeCheck(owner, (PyTypeObject *)&sipWrapper_Type))
+ {
+ PyErr_Format(PyExc_TypeError, "transferto() argument 2 must be sip.wrapper, not %s", Py_TYPE(owner)->tp_name);
+ return NULL;
+ }
+
+ sip_api_transfer_to(w, owner);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ return NULL;
+}
+
+
+/*
+ * Transfer the ownership of an instance to Python.
+ */
+static PyObject *transferBack(PyObject *self, PyObject *args)
+{
+ PyObject *w;
+
+ if (PyArg_ParseTuple(args, "O!:transferback", &sipWrapper_Type, &w))
+ {
+ sip_api_transfer_back(w);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ return NULL;
+}
+
+
+/*
+ * Cast an instance to one of it's sub or super-classes by returning a new
+ * Python object with the superclass type wrapping the same C++ instance.
+ */
+static PyObject *cast(PyObject *self, PyObject *args)
+{
+ sipSimpleWrapper *sw;
+ sipWrapperType *wt;
+ const sipTypeDef *td;
+ void *addr;
+ PyTypeObject *ft, *tt;
+
+ if (!PyArg_ParseTuple(args, "O!O!:cast", &sipSimpleWrapper_Type, &sw, &sipWrapperType_Type, &wt))
+ return NULL;
+
+ ft = Py_TYPE(sw);
+ tt = (PyTypeObject *)wt;
+
+ if (ft == tt || PyType_IsSubtype(tt, ft))
+ td = NULL;
+ else if (PyType_IsSubtype(ft, tt))
+ td = wt->type;
+ else
+ {
+ PyErr_SetString(PyExc_TypeError, "argument 1 of sip.cast() must be an instance of a sub or super-type of argument 2");
+ return NULL;
+ }
+
+ if ((addr = sip_api_get_cpp_ptr(sw, td)) == NULL)
+ return NULL;
+
+ /*
+ * We don't put this new object into the map so that the original object is
+ * always found. It would also totally confuse the map logic.
+ */
+ return sipWrapSimpleInstance(addr, wt->type, NULL, (sw->flags | SIP_NOT_IN_MAP) & ~SIP_PY_OWNED);
+}
+
+
+/*
+ * Call an instance's dtor.
+ */
+static PyObject *callDtor(PyObject *self, PyObject *args)
+{
+ sipSimpleWrapper *sw;
+ void *addr;
+ const sipClassTypeDef *ctd;
+
+ if (!PyArg_ParseTuple(args, "O!:delete", &sipSimpleWrapper_Type, &sw))
+ return NULL;
+
+ addr = getPtrTypeDef(sw, &ctd);
+
+ if (checkPointer(addr) < 0)
+ return NULL;
+
+ if (PyObject_TypeCheck((PyObject *)sw, (PyTypeObject *)&sipWrapper_Type))
+ {
+ /*
+ * Transfer ownership to C++ so we don't try to release it again when
+ * the Python object is garbage collected.
+ */
+ removeFromParent((sipWrapper *)sw);
+ sipResetPyOwned(sw);
+ }
+
+ release(addr, (const sipTypeDef *)ctd, sw->flags);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+/*
+ * Check if an instance still exists without raising an exception.
+ */
+static PyObject *isDeleted(PyObject *self, PyObject *args)
+{
+ sipSimpleWrapper *sw;
+ PyObject *res;
+
+ if (!PyArg_ParseTuple(args, "O!:isdeleted", &sipSimpleWrapper_Type, &sw))
+ return NULL;
+
+ res = (sipGetAddress(sw) == NULL ? Py_True : Py_False);
+
+ Py_INCREF(res);
+ return res;
+}
+
+
+/*
+ * Check if an instance is owned by Python or C/C++.
+ */
+static PyObject *isPyOwned(PyObject *self, PyObject *args)
+{
+ sipSimpleWrapper *sw;
+ PyObject *res;
+
+ if (!PyArg_ParseTuple(args, "O!:ispyowned", &sipSimpleWrapper_Type, &sw))
+ return NULL;
+
+ res = (sipIsPyOwned(sw) ? Py_True : Py_False);
+
+ Py_INCREF(res);
+ return res;
+}
+
+
+/*
+ * Mark an instance as having been deleted.
+ */
+static PyObject *setDeleted(PyObject *self, PyObject *args)
+{
+ sipSimpleWrapper *sw;
+
+ if (!PyArg_ParseTuple(args, "O!:setdeleted", &sipSimpleWrapper_Type, &sw))
+ return NULL;
+
+ if (PyObject_TypeCheck((PyObject *)sw, (PyTypeObject *)&sipWrapper_Type))
+ {
+ /*
+ * Transfer ownership to C++ so we don't try to release it when the
+ * Python object is garbage collected.
+ */
+ removeFromParent((sipWrapper *)sw);
+ sipResetPyOwned(sw);
+ }
+
+ sw->u.cppPtr = NULL;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+/*
+ * Unwrap an instance.
+ */
+static PyObject *unwrapInstance(PyObject *self, PyObject *args)
+{
+ sipSimpleWrapper *sw;
+
+ if (PyArg_ParseTuple(args, "O!:unwrapinstance", &sipSimpleWrapper_Type, &sw))
+ {
+ void *addr;
+
+ /*
+ * We just get the pointer but don't try and cast it (which isn't
+ * needed and wouldn't work with the way casts are currently
+ * implemented if we are unwrapping something derived from a wrapped
+ * class).
+ */
+ if ((addr = sip_api_get_cpp_ptr(sw, NULL)) == NULL)
+ return NULL;
+
+ return PyLong_FromVoidPtr(addr);
+ }
+
+ return NULL;
+}
+
+
+/*
+ * Wrap an instance.
+ */
+static PyObject *wrapInstance(PyObject *self, PyObject *args)
+{
+ unsigned long addr;
+ sipWrapperType *wt;
+
+ if (PyArg_ParseTuple(args, "kO!:wrapinstance", &addr, &sipWrapperType_Type, &wt))
+ return sip_api_convert_from_type((void *)addr, wt->type, NULL);
+
+ return NULL;
+}
+
+
+/*
+ * Register a client module. A negative value is returned and an exception
+ * raised if there was an error.
+ */
+static int sip_api_export_module(sipExportedModuleDef *client,
+ unsigned api_major, unsigned api_minor, void *unused)
+{
+ sipExportedModuleDef *em;
+ const char *full_name = sipNameOfModule(client);
+
+ /* Check that we can support it. */
+
+ if (api_major != SIP_API_MAJOR_NR || api_minor > SIP_API_MINOR_NR)
+ {
+#if SIP_API_MINOR_NR > 0
+ PyErr_Format(PyExc_RuntimeError,
+ "the sip module implements API v%d.0 to v%d.%d but the %s module requires API v%d.%d",
+ SIP_API_MAJOR_NR, SIP_API_MAJOR_NR, SIP_API_MINOR_NR,
+ full_name, api_major, api_minor);
+#else
+ PyErr_Format(PyExc_RuntimeError,
+ "the sip module implements API v%d.0 but the %s module requires API v%d.%d",
+ SIP_API_MAJOR_NR, full_name, api_major, api_minor);
+#endif
+
+ return -1;
+ }
+
+ /* Import any required modules. */
+ if (client->em_imports != NULL)
+ {
+ sipImportedModuleDef *im = client->em_imports;
+
+ while (im->im_name != NULL)
+ {
+ PyObject *mod;
+
+ if ((mod = PyImport_ImportModule(im->im_name)) == NULL)
+ return -1;
+
+ for (em = moduleList; em != NULL; em = em->em_next)
+ if (strcmp(sipNameOfModule(em), im->im_name) == 0)
+ break;
+
+ if (em == NULL)
+ {
+ PyErr_Format(PyExc_RuntimeError,
+ "the %s module failed to register with the sip module",
+ im->im_name);
+
+ return -1;
+ }
+
+ /* Check the versions are compatible. */
+ if (im->im_version >= 0 || em->em_version >= 0)
+ if (im->im_version != em->em_version)
+ {
+ PyErr_Format(PyExc_RuntimeError,
+ "the %s module is version %d but the %s module requires version %d",
+ sipNameOfModule(em), em->em_version, full_name,
+ im->im_version);
+
+ return -1;
+ }
+
+ /* Save the imported module. */
+ im->im_module = em;
+
+ ++im;
+ }
+ }
+
+ for (em = moduleList; em != NULL; em = em->em_next)
+ {
+ /* SIP clients must have unique names. */
+ if (strcmp(sipNameOfModule(em), full_name) == 0)
+ {
+ PyErr_Format(PyExc_RuntimeError,
+ "the sip module has already registered a module called %s",
+ full_name);
+
+ return -1;
+ }
+
+ /* Only one module can claim to wrap QObject. */
+ if (em->em_qt_api != NULL && client->em_qt_api != NULL)
+ {
+ PyErr_Format(PyExc_RuntimeError,
+ "the %s and %s modules both wrap the QObject class",
+ full_name, sipNameOfModule(em));
+
+ return -1;
+ }
+ }
+
+ /* Convert the module name to an object. */
+#if PY_MAJOR_VERSION >= 3
+ client->em_nameobj = PyUnicode_FromString(full_name);
+#else
+ client->em_nameobj = PyString_FromString(full_name);
+#endif
+
+ if (client->em_nameobj == NULL)
+ return -1;
+
+ /* Add it to the list of client modules. */
+ client->em_next = moduleList;
+ moduleList = client;
+
+ return 0;
+}
+
+
+/*
+ * Initialise the contents of a client module. By this time anything that
+ * this depends on should have been initialised. A negative value is returned
+ * and an exception raised if there was an error.
+ */
+static int sip_api_init_module(sipExportedModuleDef *client,
+ PyObject *mod_dict)
+{
+ sipExportedModuleDef *em;
+ sipEnumMemberDef *emd;
+ int i;
+
+ /* Handle any API. */
+ if (sipInitAPI(client, mod_dict) < 0)
+ return -1;
+
+ /* Create the module's types. */
+ for (i = 0; i < client->em_nrtypes; ++i)
+ {
+ sipTypeDef *td = client->em_types[i];
+
+ /* Skip external classes. */
+ if (td == NULL)
+ continue;
+
+ /* Skip if already initialised. */
+ if (td->td_module != NULL)
+ continue;
+
+ /* If it is a stub then just set the module so we can get its name. */
+ if (sipTypeIsStub(td))
+ {
+ td->td_module = client;
+ continue;
+ }
+
+ if (sipTypeIsEnum(td))
+ {
+ sipEnumTypeDef *etd = (sipEnumTypeDef *)td;
+
+ if (td->td_version < 0 || sipIsRangeEnabled(client, td->td_version))
+ if (createEnumType(client, etd, mod_dict) < 0)
+ return -1;
+
+ /*
+ * Register the enum pickler for scoped enums (unscoped, ie. those
+ * not nested, don't need special treatment).
+ */
+ if (etd->etd_scope >= 0)
+ {
+ static PyMethodDef md = {
+ "_pickle_enum", pickle_enum, METH_NOARGS, NULL
+ };
+
+ if (setReduce(sipTypeAsPyTypeObject(td), &md) < 0)
+ return -1;
+ }
+ }
+ else if (sipTypeIsMapped(td))
+ {
+ sipMappedTypeDef *mtd = (sipMappedTypeDef *)td;
+
+ /* If there is a name then we need a namespace. */
+ if (mtd->mtd_container.cod_name >= 0)
+ {
+ if (createMappedType(client, mtd, mod_dict) < 0)
+ return -1;
+ }
+ else
+ {
+ td->td_module = client;
+ }
+ }
+ else
+ {
+ sipClassTypeDef *ctd = (sipClassTypeDef *)td;
+
+ /* See if this is a namespace extender. */
+ if (ctd->ctd_container.cod_name < 0)
+ {
+ sipTypeDef *real_nspace;
+ sipClassTypeDef **last;
+
+ ctd->ctd_base.td_module = client;
+
+ real_nspace = getGeneratedType(&ctd->ctd_container.cod_scope,
+ client);
+
+ /* Append this type to the real one. */
+ last = &((sipClassTypeDef *)real_nspace)->ctd_nsextender;
+
+ while (*last != NULL)
+ last = &(*last)->ctd_nsextender;
+
+ *last = ctd;
+
+ /*
+ * Save the real namespace type so that it is the correct scope
+ * for any enums or classes defined in this module.
+ */
+ client->em_types[i] = real_nspace;
+ }
+ else if (createClassType(client, ctd, mod_dict) < 0)
+ return -1;
+ }
+ }
+
+ /* Set any Qt support API. */
+ if (client->em_qt_api != NULL)
+ {
+ sipQtSupport = client->em_qt_api;
+ sipQObjectType = *sipQtSupport->qt_qobject;
+ }
+
+ /* Append any initialiser extenders to the relevant classes. */
+ if (client->em_initextend != NULL)
+ {
+ sipInitExtenderDef *ie = client->em_initextend;
+
+ while (ie->ie_extender != NULL)
+ {
+ sipTypeDef *td = getGeneratedType(&ie->ie_class, client);
+ int enabled;
+
+ if (ie->ie_api_range < 0)
+ enabled = TRUE;
+ else
+ enabled = sipIsRangeEnabled(td->td_module, ie->ie_api_range);
+
+ if (enabled)
+ {
+ sipWrapperType *wt = (sipWrapperType *)sipTypeAsPyTypeObject(td);
+
+ ie->ie_next = wt->iextend;
+ wt->iextend = ie;
+ }
+
+ ++ie;
+ }
+ }
+
+ /* Set the base class object for any sub-class convertors. */
+ if (client->em_convertors != NULL)
+ {
+ sipSubClassConvertorDef *scc = client->em_convertors;
+
+ while (scc->scc_convertor != NULL)
+ {
+ scc->scc_basetype = getGeneratedType(&scc->scc_base, client);
+
+ ++scc;
+ }
+ }
+
+ /* Create the module's enum members. */
+ for (emd = client->em_enummembers, i = 0; i < client->em_nrenummembers; ++i, ++emd)
+ {
+ PyObject *mo;
+
+ if ((mo = sip_api_convert_from_enum(emd->em_val, client->em_types[emd->em_enum])) == NULL)
+ return -1;
+
+ if (PyDict_SetItemString(mod_dict, emd->em_name, mo) < 0)
+ return -1;
+
+ Py_DECREF(mo);
+ }
+
+
+ /*
+ * Add any class static instances. We need to do this once all types are
+ * fully formed because of potential interdependencies.
+ */
+ for (i = 0; i < client->em_nrtypes; ++i)
+ {
+ sipTypeDef *td = client->em_types[i];
+
+ if (td != NULL && !sipTypeIsStub(td) && sipTypeIsClass(td))
+ if (addInstances((sipTypeAsPyTypeObject(td))->tp_dict, &((sipClassTypeDef *)td)->ctd_container.cod_instances) < 0)
+ return -1;
+ }
+
+ /* Add any global static instances. */
+ if (addInstances(mod_dict, &client->em_instances) < 0)
+ return -1;
+
+ /* Add any license. */
+ if (client->em_license != NULL && addLicense(mod_dict, client->em_license) < 0)
+ return -1;
+
+ /* See if the new module satisfies any outstanding external types. */
+ for (em = moduleList; em != NULL; em = em->em_next)
+ {
+ sipExternalTypeDef *etd;
+
+ if (em == client || em->em_external == NULL)
+ continue;
+
+ for (etd = em->em_external; etd->et_nr >= 0; ++etd)
+ {
+ if (etd->et_name == NULL)
+ continue;
+
+ for (i = 0; i < client->em_nrtypes; ++i)
+ {
+ sipTypeDef *td = client->em_types[i];
+
+ if (td != NULL && !sipTypeIsStub(td) && sipTypeIsClass(td))
+ {
+ const char *pyname = sipPyNameOfContainer(
+ &((sipClassTypeDef *)td)->ctd_container, td);
+
+ if (strcmp(etd->et_name, pyname) == 0)
+ {
+ em->em_types[etd->et_nr] = td;
+ etd->et_name = NULL;
+
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+/*
+ * Called by the interpreter to do any final clearing up, just in case the
+ * interpreter will re-start.
+ */
+static void finalise(void)
+{
+ sipExportedModuleDef *em;
+
+ /* Mark the Python API as unavailable. */
+ sipInterpreter = NULL;
+
+ /* Handle any delayed dtors. */
+ for (em = moduleList; em != NULL; em = em->em_next)
+ if (em->em_ddlist != NULL)
+ {
+ em->em_delayeddtors(em->em_ddlist);
+
+ /* Free the list. */
+ do
+ {
+ sipDelayedDtor *dd = em->em_ddlist;
+
+ em->em_ddlist = dd->dd_next;
+ sip_api_free(dd);
+ }
+ while (em->em_ddlist != NULL);
+ }
+
+ licenseName = NULL;
+ licenseeName = NULL;
+ typeName = NULL;
+ timestampName = NULL;
+ signatureName = NULL;
+
+ /* Release all memory we've allocated directly. */
+ sipOMFinalise(&cppPyMap);
+
+ /* Re-initialise those globals that (might) need it. */
+ moduleList = NULL;
+}
+
+
+/*
+ * Register the given Python type.
+ */
+static int sip_api_register_py_type(PyTypeObject *type)
+{
+ return addPyObjectToList(&sipRegisteredPyTypes, (PyObject *)type);
+}
+
+
+/*
+ * Find the registered type with the given name. Raise an exception if it
+ * couldn't be found.
+ */
+static PyObject *findPyType(const char *name)
+{
+ sipPyObject *po;
+
+ for (po = sipRegisteredPyTypes; po != NULL; po = po->next)
+ {
+ PyObject *type = po->object;
+
+ if (strcmp(((PyTypeObject *)type)->tp_name, name) == 0)
+ return type;
+ }
+
+ PyErr_Format(PyExc_RuntimeError, "%s is not a registered type", name);
+
+ return NULL;
+}
+
+
+/*
+ * Add a wrapped C/C++ pointer to the list of delayed dtors.
+ */
+static void sip_api_add_delayed_dtor(sipSimpleWrapper *sw)
+{
+ void *ptr;
+ const sipClassTypeDef *ctd;
+ sipExportedModuleDef *em;
+
+ if ((ptr = getPtrTypeDef(sw, &ctd)) == NULL)
+ return;
+
+ /* Find the defining module. */
+ for (em = moduleList; em != NULL; em = em->em_next)
+ {
+ int i;
+
+ for (i = 0; i < em->em_nrtypes; ++i)
+ if (em->em_types[i] == (const sipTypeDef *)ctd)
+ {
+ sipDelayedDtor *dd;
+
+ if ((dd = sip_api_malloc(sizeof (sipDelayedDtor))) == NULL)
+ return;
+
+ /* Add to the list. */
+ dd->dd_ptr = ptr;
+ dd->dd_name = sipPyNameOfContainer(&ctd->ctd_container,
+ (sipTypeDef *)ctd);
+ dd->dd_isderived = sipIsDerived(sw);
+ dd->dd_next = em->em_ddlist;
+
+ em->em_ddlist = dd;
+
+ return;
+ }
+ }
+}
+
+
+/*
+ * A wrapper around the Python memory allocater that will raise an exception if
+ * if the allocation fails.
+ */
+void *sip_api_malloc(size_t nbytes)
+{
+ void *mem;
+
+ if ((mem = PyMem_Malloc(nbytes)) == NULL)
+ PyErr_NoMemory();
+
+ return mem;
+}
+
+
+/*
+ * A wrapper around the Python memory de-allocater.
+ */
+void sip_api_free(void *mem)
+{
+ PyMem_Free(mem);
+}
+
+
+/*
+ * Extend a Python slot by looking in other modules to see if there is an
+ * extender function that can handle the arguments.
+ */
+static PyObject *sip_api_pyslot_extend(sipExportedModuleDef *mod,
+ sipPySlotType st, const sipTypeDef *td, PyObject *arg0,
+ PyObject *arg1)
+{
+ sipExportedModuleDef *em;
+
+ /* Go through each module. */
+ for (em = moduleList; em != NULL; em = em->em_next)
+ {
+ sipPySlotExtenderDef *ex;
+
+ /* Skip the module that couldn't handle the arguments. */
+ if (em == mod)
+ continue;
+
+ /* Skip if the module doesn't have any extenders. */
+ if (em->em_slotextend == NULL)
+ continue;
+
+ /* Go through each extender. */
+ for (ex = em->em_slotextend; ex->pse_func != NULL; ++ex)
+ {
+ PyObject *res;
+
+ /* Skip if not the right slot type. */
+ if (ex->pse_type != st)
+ continue;
+
+ /* Check against the type if one was given. */
+ if (td != NULL && td != getGeneratedType(&ex->pse_class, NULL))
+ continue;
+
+ PyErr_Clear();
+
+ res = ((binaryfunc)ex->pse_func)(arg0, arg1);
+
+ if (res != Py_NotImplemented)
+ return res;
+ }
+ }
+
+ /* The arguments couldn't handled anywhere. */
+ PyErr_Clear();
+
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+}
+
+
+/*
+ * Call the Python re-implementation of a C++ virtual.
+ */
+static PyObject *sip_api_call_method(int *isErr, PyObject *method,
+ const char *fmt, ...)
+{
+ PyObject *args, *res;
+ va_list va;
+
+ va_start(va,fmt);
+
+ if ((args = PyTuple_New(strlen(fmt))) != NULL && buildObject(args,fmt,va) != NULL)
+ res = PyEval_CallObject(method,args);
+ else
+ {
+ res = NULL;
+
+ if (isErr != NULL)
+ *isErr = TRUE;
+ }
+
+ Py_XDECREF(args);
+
+ va_end(va);
+
+ return res;
+}
+
+
+/*
+ * Build a result object based on a format string.
+ */
+static PyObject *sip_api_build_result(int *isErr, const char *fmt, ...)
+{
+ PyObject *res = NULL;
+ int badfmt, tupsz;
+ va_list va;
+
+ va_start(va,fmt);
+
+ /* Basic validation of the format string. */
+
+ badfmt = FALSE;
+
+ if (*fmt == '(')
+ {
+ char *ep;
+
+ if ((ep = strchr(fmt,')')) == NULL || ep[1] != '\0')
+ badfmt = TRUE;
+ else
+ tupsz = ep - fmt - 1;
+ }
+ else if (strlen(fmt) == 1)
+ tupsz = -1;
+ else
+ badfmt = TRUE;
+
+ if (badfmt)
+ PyErr_Format(PyExc_SystemError,"sipBuildResult(): invalid format string \"%s\"",fmt);
+ else if (tupsz < 0 || (res = PyTuple_New(tupsz)) != NULL)
+ res = buildObject(res,fmt,va);
+
+ va_end(va);
+
+ if (res == NULL && isErr != NULL)
+ *isErr = TRUE;
+
+ return res;
+}
+
+
+/*
+ * Get the values off the stack and put them into an object.
+ */
+static PyObject *buildObject(PyObject *obj, const char *fmt, va_list va)
+{
+ char ch, termch;
+ int i;
+
+ /*
+ * The format string has already been checked that it is properly formed if
+ * it is enclosed in parenthesis.
+ */
+ if (*fmt == '(')
+ {
+ termch = ')';
+ ++fmt;
+ }
+ else
+ termch = '\0';
+
+ i = 0;
+
+ while ((ch = *fmt++) != termch)
+ {
+ PyObject *el;
+
+ switch (ch)
+ {
+ case 'g':
+ {
+ char *s;
+ SIP_SSIZE_T l;
+
+ s = va_arg(va, char *);
+ l = va_arg(va, SIP_SSIZE_T);
+
+ if (s != NULL)
+ {
+ el = SIPBytes_FromStringAndSize(s, l);
+ }
+ else
+ {
+ Py_INCREF(Py_None);
+ el = Py_None;
+ }
+ }
+
+ break;
+
+ case 'G':
+#if defined(HAVE_WCHAR_H)
+ {
+ wchar_t *s;
+ SIP_SSIZE_T l;
+
+ s = va_arg(va, wchar_t *);
+ l = va_arg(va, SIP_SSIZE_T);
+
+ if (s != NULL)
+ el = PyUnicode_FromWideChar(s, l);
+ else
+ {
+ Py_INCREF(Py_None);
+ el = Py_None;
+ }
+ }
+#else
+ raiseNoWChar();
+ el = NULL;
+#endif
+
+ break;
+
+ case 'b':
+ el = PyBool_FromLong(va_arg(va,int));
+ break;
+
+ case 'c':
+ {
+ char c = va_arg(va, int);
+
+ el = SIPBytes_FromStringAndSize(&c, 1);
+ }
+
+ break;
+
+ case 'a':
+ {
+ char c = va_arg(va, int);
+
+#if PY_MAJOR_VERSION >= 3
+ el = PyUnicode_FromStringAndSize(&c, 1);
+#else
+ el = PyString_FromStringAndSize(&c, 1);
+#endif
+ }
+
+ break;
+
+ case 'w':
+#if defined(HAVE_WCHAR_H)
+ {
+ wchar_t c = va_arg(va, int);
+
+ el = PyUnicode_FromWideChar(&c, 1);
+ }
+#else
+ raiseNoWChar();
+ el = NULL;
+#endif
+
+ break;
+
+ case 'E':
+ {
+ /* This is deprecated. */
+
+ int ev = va_arg(va, int);
+ PyTypeObject *et = va_arg(va, PyTypeObject *);
+
+ el = sip_api_convert_from_enum(ev,
+ ((const sipEnumTypeObject *)et)->type);
+ }
+
+ break;
+
+ case 'F':
+ {
+ int ev = va_arg(va, int);
+ const sipTypeDef *td = va_arg(va, const sipTypeDef *);
+
+ el = sip_api_convert_from_enum(ev, td);
+ }
+
+ break;
+
+ case 'd':
+ case 'f':
+ el = PyFloat_FromDouble(va_arg(va,double));
+ break;
+
+ case 'e':
+ case 'h':
+ case 'i':
+#if PY_MAJOR_VERSION >= 3
+ el = PyLong_FromLong(va_arg(va, int));
+#else
+ el = PyInt_FromLong(va_arg(va, int));
+#endif
+ break;
+
+ case 'l':
+ el = PyLong_FromLong(va_arg(va, long));
+ break;
+
+ case 'm':
+ el = PyLong_FromUnsignedLong(va_arg(va, unsigned long));
+ break;
+
+ case 'n':
+#if defined(HAVE_LONG_LONG)
+ el = PyLong_FromLongLong(va_arg(va, PY_LONG_LONG));
+#else
+ el = PyLong_FromLong(va_arg(va, long));
+#endif
+ break;
+
+ case 'o':
+#if defined(HAVE_LONG_LONG)
+ el = PyLong_FromUnsignedLongLong(va_arg(va, unsigned PY_LONG_LONG));
+#else
+ el = PyLong_FromUnsignedLong(va_arg(va, unsigned long));
+#endif
+ break;
+
+ case 's':
+ {
+ char *s = va_arg(va, char *);
+
+ if (s != NULL)
+ {
+ el = SIPBytes_FromString(s);
+ }
+ else
+ {
+ Py_INCREF(Py_None);
+ el = Py_None;
+ }
+ }
+
+ break;
+
+ case 'A':
+ {
+ char *s = va_arg(va, char *);
+
+ if (s != NULL)
+#if PY_MAJOR_VERSION >= 3
+ el = PyUnicode_FromString(s);
+#else
+ el = PyString_FromString(s);
+#endif
+ else
+ {
+ Py_INCREF(Py_None);
+ el = Py_None;
+ }
+ }
+
+ break;
+
+ case 'x':
+#if defined(HAVE_WCHAR_H)
+ {
+ wchar_t *s = va_arg(va, wchar_t *);
+
+ if (s != NULL)
+ el = PyUnicode_FromWideChar(s, (SIP_SSIZE_T)wcslen(s));
+ else
+ {
+ Py_INCREF(Py_None);
+ el = Py_None;
+ }
+ }
+#else
+ raiseNoWChar();
+ el = NULL;
+#endif
+
+ break;
+
+ case 't':
+ case 'u':
+ el = PyLong_FromUnsignedLong(va_arg(va, unsigned));
+ break;
+
+ case 'B':
+ {
+ /* This is deprecated. */
+
+ void *p = va_arg(va,void *);
+ sipWrapperType *wt = va_arg(va, sipWrapperType *);
+ PyObject *xfer = va_arg(va, PyObject *);
+
+ el = sip_api_convert_from_new_type(p, wt->type, xfer);
+ }
+
+ break;
+
+ case 'N':
+ {
+ void *p = va_arg(va, void *);
+ const sipTypeDef *td = va_arg(va, const sipTypeDef *);
+ PyObject *xfer = va_arg(va, PyObject *);
+
+ el = sip_api_convert_from_new_type(p, td, xfer);
+ }
+
+ break;
+
+ case 'C':
+ {
+ /* This is deprecated. */
+
+ void *p = va_arg(va,void *);
+ sipWrapperType *wt = va_arg(va, sipWrapperType *);
+ PyObject *xfer = va_arg(va, PyObject *);
+
+ el = sip_api_convert_from_type(p, wt->type, xfer);
+ }
+
+ break;
+
+ case 'D':
+ {
+ void *p = va_arg(va, void *);
+ const sipTypeDef *td = va_arg(va, const sipTypeDef *);
+ PyObject *xfer = va_arg(va, PyObject *);
+
+ el = sip_api_convert_from_type(p, td, xfer);
+ }
+
+ break;
+
+ case 'r':
+ {
+ void *p = va_arg(va, void *);
+ SIP_SSIZE_T l = va_arg(va, SIP_SSIZE_T);
+ const sipTypeDef *td = va_arg(va, const sipTypeDef *);
+
+ el = convertToSequence(p, l, td);
+ }
+
+ break;
+
+ case 'R':
+ el = va_arg(va,PyObject *);
+ break;
+
+ case 'S':
+ el = va_arg(va,PyObject *);
+ Py_INCREF(el);
+ break;
+
+ case 'V':
+ el = sip_api_convert_from_void_ptr(va_arg(va, void *));
+ break;
+
+ default:
+ PyErr_Format(PyExc_SystemError,"buildObject(): invalid format character '%c'",ch);
+ el = NULL;
+ }
+
+ if (el == NULL)
+ {
+ Py_XDECREF(obj);
+ return NULL;
+ }
+
+ if (obj == NULL)
+ return el;
+
+ PyTuple_SET_ITEM(obj,i,el);
+ ++i;
+ }
+
+ return obj;
+}
+
+
+/*
+ * Parse a result object based on a format string.
+ */
+static int sip_api_parse_result(int *isErr, PyObject *method, PyObject *res,
+ const char *fmt, ...)
+{
+ int tupsz, rc = 0;
+ sipSimpleWrapper *self = NULL;
+ va_list va;
+
+ va_start(va,fmt);
+
+ /* Get self if it is provided. */
+ if (*fmt == 'S')
+ {
+ self = va_arg(va, sipSimpleWrapper *);
+ ++fmt;
+ }
+
+ /* Basic validation of the format string. */
+ if (*fmt == '(')
+ {
+ char ch;
+ const char *cp = ++fmt;
+
+ tupsz = 0;
+
+ while ((ch = *cp++) != ')')
+ {
+ if (ch == '\0')
+ {
+ PyErr_Format(PyExc_SystemError, "sipParseResult(): invalid format string \"%s\"", fmt - 1);
+ rc = -1;
+
+ break;
+ }
+
+ /*
+ * Some format characters have a sub-format so skip the character
+ * and count the sub-format character next time round.
+ */
+ if (strchr("HDC", ch) == NULL)
+ ++tupsz;
+ }
+
+ if (rc == 0)
+ if (!PyTuple_Check(res) || PyTuple_GET_SIZE(res) != tupsz)
+ {
+ sip_api_bad_catcher_result(method);
+ rc = -1;
+ }
+ }
+ else
+ tupsz = -1;
+
+ if (rc == 0)
+ {
+ char ch;
+ int i = 0;
+
+ while ((ch = *fmt++) != '\0' && ch != ')' && rc == 0)
+ {
+ PyObject *arg;
+ int invalid = FALSE;
+
+ if (tupsz > 0)
+ {
+ arg = PyTuple_GET_ITEM(res,i);
+ ++i;
+ }
+ else
+ arg = res;
+
+ switch (ch)
+ {
+ case 'g':
+ {
+ const char **p = va_arg(va, const char **);
+ SIP_SSIZE_T *szp = va_arg(va, SIP_SSIZE_T *);
+
+ if (parseBytes_AsCharArray(arg, p, szp) < 0)
+ invalid = TRUE;
+ }
+
+ break;
+
+ case 'G':
+#if defined(HAVE_WCHAR_H)
+ {
+ wchar_t **p = va_arg(va, wchar_t **);
+ SIP_SSIZE_T *szp = va_arg(va, SIP_SSIZE_T *);
+
+ if (parseWCharArray(arg, p, szp) < 0)
+ invalid = TRUE;
+ }
+#else
+ raiseNoWChar();
+ invalid = TRUE;
+#endif
+
+ break;
+
+ case 'b':
+ {
+ int v = SIPLong_AsLong(arg);
+
+ if (PyErr_Occurred())
+ invalid = TRUE;
+ else
+ sipSetBool(va_arg(va, void *), v);
+ }
+
+ break;
+
+ case 'c':
+ {
+ char *p = va_arg(va, char *);
+
+ if (parseBytes_AsChar(arg, p) < 0)
+ invalid = TRUE;
+ }
+
+ break;
+
+ case 'a':
+ {
+ char *p = va_arg(va, char *);
+ int enc;
+
+ switch (*fmt++)
+ {
+ case 'A':
+ enc = parseString_AsASCIIChar(arg, p);
+ break;
+
+ case 'L':
+ enc = parseString_AsLatin1Char(arg, p);
+ break;
+
+ case '8':
+ enc = parseString_AsUTF8Char(arg, p);
+ break;
+
+ default:
+ enc = -1;
+ }
+
+ if (enc < 0)
+ invalid = TRUE;
+ }
+
+ break;
+
+ case 'w':
+#if defined(HAVE_WCHAR_H)
+ {
+ wchar_t *p = va_arg(va, wchar_t *);
+
+ if (parseWChar(arg, p) < 0)
+ invalid = TRUE;
+ }
+#else
+ raiseNoWChar();
+ invalid = TRUE;
+#endif
+
+ break;
+
+ case 'd':
+ {
+ double v = PyFloat_AsDouble(arg);
+
+ if (PyErr_Occurred())
+ invalid = TRUE;
+ else
+ *va_arg(va,double *) = v;
+ }
+
+ break;
+
+ case 'E':
+ {
+ /* This is deprecated. */
+
+ PyTypeObject *et = va_arg(va, PyTypeObject *);
+ int *p = va_arg(va, int *);
+
+ if (sip_api_can_convert_to_enum(arg, ((sipEnumTypeObject *)et)->type))
+ *p = SIPLong_AsLong(arg);
+ else
+ invalid = TRUE;
+ }
+
+ break;
+
+ case 'F':
+ {
+ sipTypeDef *td = va_arg(va, sipTypeDef *);
+ int *p = va_arg(va, int *);
+
+ if (sip_api_can_convert_to_enum(arg, td))
+ *p = SIPLong_AsLong(arg);
+ else
+ invalid = TRUE;
+ }
+
+ break;
+
+ case 'f':
+ {
+ float v = PyFloat_AsDouble(arg);
+
+ if (PyErr_Occurred())
+ invalid = TRUE;
+ else
+ *va_arg(va,float *) = v;
+ }
+
+ break;
+
+ case 'h':
+ {
+ short v = SIPLong_AsLong(arg);
+
+ if (PyErr_Occurred())
+ invalid = TRUE;
+ else
+ *va_arg(va, short *) = v;
+ }
+
+ break;
+
+ case 't':
+ {
+ unsigned short v = sip_api_long_as_unsigned_long(arg);
+
+ if (PyErr_Occurred())
+ invalid = TRUE;
+ else
+ *va_arg(va,unsigned short *) = v;
+ }
+
+ break;
+
+ case 'e':
+ case 'i':
+ {
+ int v = SIPLong_AsLong(arg);
+
+ if (PyErr_Occurred())
+ invalid = TRUE;
+ else
+ *va_arg(va, int *) = v;
+ }
+
+ break;
+
+ case 'u':
+ {
+ unsigned v = sip_api_long_as_unsigned_long(arg);
+
+ if (PyErr_Occurred())
+ invalid = TRUE;
+ else
+ *va_arg(va,unsigned *) = v;
+ }
+
+ break;
+
+ case 'l':
+ {
+ long v = PyLong_AsLong(arg);
+
+ if (PyErr_Occurred())
+ invalid = TRUE;
+ else
+ *va_arg(va,long *) = v;
+ }
+
+ break;
+
+ case 'm':
+ {
+ unsigned long v = sip_api_long_as_unsigned_long(arg);
+
+ if (PyErr_Occurred())
+ invalid = TRUE;
+ else
+ *va_arg(va, unsigned long *) = v;
+ }
+
+ break;
+
+ case 'n':
+ {
+#if defined(HAVE_LONG_LONG)
+ PY_LONG_LONG v = PyLong_AsLongLong(arg);
+#else
+ long v = PyLong_AsLong(arg);
+#endif
+
+ if (PyErr_Occurred())
+ invalid = TRUE;
+ else
+#if defined(HAVE_LONG_LONG)
+ *va_arg(va, PY_LONG_LONG *) = v;
+#else
+ *va_arg(va, long *) = v;
+#endif
+ }
+
+ break;
+
+ case 'o':
+ {
+#if defined(HAVE_LONG_LONG)
+ unsigned PY_LONG_LONG v = PyLong_AsUnsignedLongLong(arg);
+#else
+ unsigned long v = PyLong_AsUnsignedLong(arg);
+#endif
+
+ if (PyErr_Occurred())
+ invalid = TRUE;
+ else
+#if defined(HAVE_LONG_LONG)
+ *va_arg(va, unsigned PY_LONG_LONG *) = v;
+#else
+ *va_arg(va, unsigned long *) = v;
+#endif
+ }
+
+ break;
+
+ case 's':
+ {
+ /* This is deprecated. */
+
+ const char **p = va_arg(va, const char **);
+
+ if (parseBytes_AsString(arg, p) < 0)
+ invalid = TRUE;
+ }
+
+ break;
+
+ case 'A':
+ {
+ int key = va_arg(va, int);
+ const char **p = va_arg(va, const char **);
+ PyObject *keep;
+
+ switch (*fmt++)
+ {
+ case 'A':
+ keep = parseString_AsASCIIString(arg, p);
+ break;
+
+ case 'L':
+ keep = parseString_AsLatin1String(arg, p);
+ break;
+
+ case '8':
+ keep = parseString_AsUTF8String(arg, p);
+ break;
+
+ default:
+ keep = NULL;
+ }
+
+ if (keep == NULL)
+ invalid = TRUE;
+ else
+ sip_api_keep_reference((PyObject *)self, key, keep);
+ }
+
+ break;
+
+ case 'B':
+ {
+ int key = va_arg(va, int);
+ const char **p = va_arg(va, const char **);
+
+ if (parseBytes_AsString(arg, p) < 0)
+ invalid = TRUE;
+ else
+ {
+ Py_INCREF(arg);
+ sip_api_keep_reference((PyObject *)self, key, arg);
+ }
+ }
+
+ break;
+
+ case 'x':
+#if defined(HAVE_WCHAR_H)
+ {
+ wchar_t **p = va_arg(va, wchar_t **);
+
+ if (parseWCharString(arg, p) < 0)
+ invalid = TRUE;
+ }
+#else
+ raiseNoWChar();
+ invalid = TRUE;
+#endif
+
+ break;
+
+ case 'C':
+ {
+ /* This is deprecated. */
+
+ if (*fmt == '\0')
+ invalid = TRUE;
+ else
+ {
+ int flags = *fmt++ - '0';
+ int iserr = FALSE;
+ sipWrapperType *type;
+ void **cpp;
+ int *state;
+
+ type = va_arg(va, sipWrapperType *);
+
+ if (flags & FMT_RP_NO_STATE_DEPR)
+ state = NULL;
+ else
+ state = va_arg(va, int *);
+
+ cpp = va_arg(va, void **);
+
+ *cpp = sip_api_force_convert_to_type(arg, type->type, (flags & FMT_RP_FACTORY ? arg : NULL), (flags & FMT_RP_DEREF ? SIP_NOT_NONE : 0), state, &iserr);
+
+ if (iserr)
+ invalid = TRUE;
+ }
+ }
+
+ break;
+
+ case 'D':
+ {
+ /* This is deprecated. */
+
+ if (*fmt == '\0')
+ invalid = TRUE;
+ else
+ {
+ int flags = *fmt++ - '0';
+ int iserr = FALSE;
+ const sipTypeDef *td;
+ void **cpp;
+ int *state;
+
+ td = va_arg(va, const sipTypeDef *);
+
+ if (flags & FMT_RP_NO_STATE_DEPR)
+ state = NULL;
+ else
+ state = va_arg(va, int *);
+
+ cpp = va_arg(va, void **);
+
+ *cpp = sip_api_force_convert_to_type(arg, td, (flags & FMT_RP_FACTORY ? arg : NULL), (flags & FMT_RP_DEREF ? SIP_NOT_NONE : 0), state, &iserr);
+
+ if (iserr)
+ invalid = TRUE;
+ }
+ }
+
+ break;
+
+ case 'H':
+ {
+ if (*fmt == '\0')
+ invalid = TRUE;
+ else
+ {
+ int flags = *fmt++ - '0';
+ int iserr = FALSE, state;
+ const sipTypeDef *td;
+ void *cpp, *val;
+
+ td = va_arg(va, const sipTypeDef *);
+ cpp = va_arg(va, void **);
+
+ val = sip_api_force_convert_to_type(arg, td, (flags & FMT_RP_FACTORY ? arg : NULL), (flags & FMT_RP_DEREF ? SIP_NOT_NONE : 0), &state, &iserr);
+
+ if (iserr)
+ {
+ invalid = TRUE;
+ }
+ else if (flags & FMT_RP_MAKE_COPY)
+ {
+ sipAssignFunc assign_helper;
+
+ if (sipTypeIsMapped(td))
+ assign_helper = ((const sipMappedTypeDef *)td)->mtd_assign;
+ else
+ assign_helper = ((const sipClassTypeDef *)td)->ctd_assign;
+
+ assert(assign_helper != NULL);
+
+ assign_helper(cpp, 0, val);
+ sip_api_release_type(val, td, state);
+ }
+ else
+ {
+ *(void **)cpp = val;
+ }
+ }
+ }
+
+ break;
+
+ case 'N':
+ {
+ PyTypeObject *type = va_arg(va,PyTypeObject *);
+ PyObject **p = va_arg(va,PyObject **);
+
+ if (arg == Py_None || PyObject_TypeCheck(arg,type))
+ {
+ Py_INCREF(arg);
+ *p = arg;
+ }
+ else
+ invalid = TRUE;
+ }
+
+ break;
+
+ case 'O':
+ Py_INCREF(arg);
+ *va_arg(va,PyObject **) = arg;
+ break;
+
+ case 'T':
+ {
+ PyTypeObject *type = va_arg(va,PyTypeObject *);
+ PyObject **p = va_arg(va,PyObject **);
+
+ if (PyObject_TypeCheck(arg,type))
+ {
+ Py_INCREF(arg);
+ *p = arg;
+ }
+ else
+ invalid = TRUE;
+ }
+
+ break;
+
+ case 'V':
+ {
+ void *v = sip_api_convert_to_void_ptr(arg);
+
+ if (PyErr_Occurred())
+ invalid = TRUE;
+ else
+ *va_arg(va,void **) = v;
+ }
+
+ break;
+
+ case 'Z':
+ if (arg != Py_None)
+ invalid = TRUE;
+
+ break;
+
+ default:
+ PyErr_Format(PyExc_SystemError,"sipParseResult(): invalid format character '%c'",ch);
+ rc = -1;
+ }
+
+ if (invalid)
+ {
+ sip_api_bad_catcher_result(method);
+ rc = -1;
+ break;
+ }
+ }
+ }
+
+ va_end(va);
+
+ if (isErr != NULL && rc < 0)
+ *isErr = TRUE;
+
+ return rc;
+}
+
+
+/*
+ * A thin wrapper around PyLong_AsUnsignedLong() that works around a bug in
+ * Python versions prior to v2.4 where an integer (or a named enum) causes an
+ * error.
+ */
+static unsigned long sip_api_long_as_unsigned_long(PyObject *o)
+{
+#if PY_VERSION_HEX < 0x02040000
+ if (o != NULL && !PyLong_Check(o) && PyInt_Check(o))
+ {
+ long v = PyInt_AsLong(o);
+
+ if (v < 0)
+ {
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative value to unsigned long");
+
+ return (unsigned long)-1;
+ }
+
+ return v;
+ }
+#endif
+
+ return PyLong_AsUnsignedLong(o);
+}
+
+
+/*
+ * Parse the arguments to a C/C++ function without any side effects.
+ */
+static int sip_api_parse_args(PyObject **parseErrp, PyObject *sipArgs,
+ const char *fmt, ...)
+{
+ int ok;
+ va_list va;
+
+ va_start(va, fmt);
+ ok = parseKwdArgs(parseErrp, sipArgs, NULL, NULL, NULL, fmt, va);
+ va_end(va);
+
+ return ok;
+}
+
+
+/*
+ * Parse the positional and/or keyword arguments to a C/C++ function without
+ * any side effects.
+ */
+static int sip_api_parse_kwd_args(PyObject **parseErrp, PyObject *sipArgs,
+ PyObject *sipKwdArgs, const char **kwdlist, PyObject **unused,
+ const char *fmt, ...)
+{
+ int ok;
+ va_list va;
+
+ /* Initialise the return of any unused keyword arguments. */
+ if (unused != NULL)
+ *unused = NULL;
+
+ va_start(va, fmt);
+ ok = parseKwdArgs(parseErrp, sipArgs, sipKwdArgs, kwdlist, unused, fmt,
+ va);
+ va_end(va);
+
+ /* Release any unused arguments if the parse failed. */
+ if (!ok && unused != NULL)
+ {
+ Py_XDECREF(*unused);
+ }
+
+ return ok;
+}
+
+
+/*
+ * Parse the arguments to a C/C++ function without any side effects.
+ */
+static int parseKwdArgs(PyObject **parseErrp, PyObject *sipArgs,
+ PyObject *sipKwdArgs, const char **kwdlist, PyObject **unused,
+ const char *fmt, va_list va_orig)
+{
+ int no_tmp_tuple, ok, selfarg;
+ sipSimpleWrapper *self;
+ PyObject *single_arg;
+ va_list va;
+
+ /* Previous second pass errors stop subsequent parses. */
+ if (*parseErrp != NULL && !PyList_Check(*parseErrp))
+ return FALSE;
+
+ /*
+ * See if we are parsing a single argument. In current versions we are
+ * told explicitly by the first character of the format string. In earlier
+ * versions we guessed (sometimes wrongly).
+ */
+ if (*fmt == '1')
+ {
+ ++fmt;
+ no_tmp_tuple = FALSE;
+ }
+ else
+ no_tmp_tuple = PyTuple_Check(sipArgs);
+
+ if (no_tmp_tuple)
+ {
+ Py_INCREF(sipArgs);
+ }
+ else if ((single_arg = PyTuple_New(1)) != NULL)
+ {
+ Py_INCREF(sipArgs);
+ PyTuple_SET_ITEM(single_arg, 0, sipArgs);
+
+ sipArgs = single_arg;
+ }
+ else
+ {
+ /* Stop all parsing and indicate an exception has been raised. */
+ Py_XDECREF(*parseErrp);
+ *parseErrp = Py_None;
+ Py_INCREF(Py_None);
+
+ return FALSE;
+ }
+
+ /*
+ * The first pass checks all the types and does conversions that are cheap
+ * and have no side effects.
+ */
+ va_copy(va, va_orig);
+ ok = parsePass1(parseErrp, &self, &selfarg, sipArgs, sipKwdArgs, kwdlist,
+ unused, fmt, va);
+ va_end(va);
+
+ if (ok)
+ {
+ /*
+ * The second pass does any remaining conversions now that we know we
+ * have the right signature.
+ */
+ va_copy(va, va_orig);
+ ok = parsePass2(self, selfarg, sipArgs, sipKwdArgs, kwdlist, fmt, va);
+ va_end(va);
+
+ /* Remove any previous failed parses. */
+ Py_XDECREF(*parseErrp);
+
+ if (ok)
+ {
+ *parseErrp = NULL;
+ }
+ else
+ {
+ /* Indicate that an exception has been raised. */
+ *parseErrp = Py_None;
+ Py_INCREF(Py_None);
+ }
+ }
+
+ Py_DECREF(sipArgs);
+
+ return ok;
+}
+
+
+/*
+ * Return a string as a Python object that describes an argument with an
+ * unexpected type.
+ */
+static PyObject *bad_type_str(int arg_nr, PyObject *arg)
+{
+#if PY_MAJOR_VERSION >= 3
+ return PyUnicode_FromFormat("argument %d has unexpected type '%s'", arg_nr,
+ Py_TYPE(arg)->tp_name);
+#else
+ return PyString_FromFormat("argument %d has unexpected type '%s'", arg_nr,
+ Py_TYPE(arg)->tp_name);
+#endif
+}
+
+
+/*
+ * Adds a failure about an argument with an incorrect type to the current list
+ * of exceptions.
+ */
+static sipErrorState sip_api_bad_callable_arg(int arg_nr, PyObject *arg)
+{
+ PyObject *detail = bad_type_str(arg_nr + 1, arg);
+
+ if (detail == NULL)
+ return sipErrorFail;
+
+ PyErr_SetObject(PyExc_TypeError, detail);
+ Py_DECREF(detail);
+
+ return sipErrorContinue;
+}
+
+
+/*
+ * Adds the current exception to the current list of exceptions (if it is a
+ * user exception) or replace the current list of exceptions.
+ */
+static void sip_api_add_exception(sipErrorState es, PyObject **parseErrp)
+{
+ assert(*parseErrp == NULL);
+
+ if (es == sipErrorContinue)
+ {
+ sipParseFailure failure;
+ PyObject *e_type, *e_traceback;
+
+ /* Get the value of the exception. */
+ PyErr_Fetch(&e_type, &failure.detail_obj, &e_traceback);
+ Py_XDECREF(e_type);
+ Py_XDECREF(e_traceback);
+
+ failure.reason = Exception;
+
+ add_failure(parseErrp, &failure);
+
+ if (failure.reason == Raised)
+ {
+ Py_XDECREF(failure.detail_obj);
+ es = sipErrorFail;
+ }
+ }
+
+ if (es == sipErrorFail)
+ {
+ Py_XDECREF(*parseErrp);
+ *parseErrp = Py_None;
+ Py_INCREF(Py_None);
+ }
+}
+
+
+/*
+ * The dtor for parse failure wrapped in a Python object.
+ */
+#if defined(SIP_USE_PYCAPSULE)
+static void failure_dtor(PyObject *capsule)
+{
+ sipParseFailure *failure = (sipParseFailure *)PyCapsule_GetPointer(capsule, NULL);
+
+ Py_XDECREF(failure->detail_obj);
+
+ sip_api_free(failure);
+}
+#else
+static void failure_dtor(void *ptr)
+{
+ sipParseFailure *failure = (sipParseFailure *)ptr;
+
+ Py_XDECREF(failure->detail_obj);
+
+ sip_api_free(failure);
+}
+#endif
+
+
+/*
+ * Add a parse failure to the current list of exceptions.
+ */
+static void add_failure(PyObject **parseErrp, sipParseFailure *failure)
+{
+ sipParseFailure *failure_copy;
+ PyObject *failure_obj;
+
+ /* Create the list if necessary. */
+ if (*parseErrp == NULL && (*parseErrp = PyList_New(0)) == NULL)
+ {
+ failure->reason = Raised;
+ return;
+ }
+
+ /*
+ * Make a copy of the failure, convert it to a Python object and add it to
+ * the list. We do it this way to make it as lightweight as possible.
+ */
+ if ((failure_copy = sip_api_malloc(sizeof (sipParseFailure))) == NULL)
+ {
+ failure->reason = Raised;
+ return;
+ }
+
+ *failure_copy = *failure;
+
+#if defined(SIP_USE_PYCAPSULE)
+ failure_obj = PyCapsule_New(failure_copy, NULL, failure_dtor);
+#else
+ failure_obj = PyCObject_FromVoidPtr(failure_copy, failure_dtor);
+#endif
+
+ if (failure_obj == NULL)
+ {
+ sip_api_free(failure_copy);
+ failure->reason = Raised;
+ return;
+ }
+
+ /* Ownership of any detail object is now with the wrapped failure. */
+ failure->detail_obj = NULL;
+
+ if (PyList_Append(*parseErrp, failure_obj) < 0)
+ {
+ Py_DECREF(failure_obj);
+ failure->reason = Raised;
+ return;
+ }
+
+ Py_DECREF(failure_obj);
+}
+
+
+/*
+ * Parse a pair of arguments to a C/C++ function without any side effects.
+ */
+static int sip_api_parse_pair(PyObject **parseErrp, PyObject *sipArg0,
+ PyObject *sipArg1, const char *fmt, ...)
+{
+ int ok, selfarg;
+ sipSimpleWrapper *self;
+ PyObject *args;
+ va_list va;
+
+ /* Previous second pass errors stop subsequent parses. */
+ if (*parseErrp != NULL && !PyList_Check(*parseErrp))
+ return FALSE;
+
+ if ((args = PyTuple_New(2)) == NULL)
+ {
+ /* Stop all parsing and indicate an exception has been raised. */
+ Py_XDECREF(*parseErrp);
+ *parseErrp = Py_None;
+ Py_INCREF(Py_None);
+
+ return FALSE;
+ }
+
+ Py_INCREF(sipArg0);
+ PyTuple_SET_ITEM(args, 0, sipArg0);
+
+ Py_INCREF(sipArg1);
+ PyTuple_SET_ITEM(args, 1, sipArg1);
+
+ /*
+ * The first pass checks all the types and does conversions that are cheap
+ * and have no side effects.
+ */
+ va_start(va, fmt);
+ ok = parsePass1(parseErrp, &self, &selfarg, args, NULL, NULL, NULL, fmt,
+ va);
+ va_end(va);
+
+ if (ok)
+ {
+ /*
+ * The second pass does any remaining conversions now that we know we
+ * have the right signature.
+ */
+ va_start(va, fmt);
+ ok = parsePass2(self, selfarg, args, NULL, NULL, fmt, va);
+ va_end(va);
+
+ /* Remove any previous failed parses. */
+ Py_XDECREF(*parseErrp);
+
+ if (ok)
+ {
+ *parseErrp = NULL;
+ }
+ else
+ {
+ /* Indicate that an exception has been raised. */
+ *parseErrp = Py_None;
+ Py_INCREF(Py_None);
+ }
+ }
+
+ Py_DECREF(args);
+
+ return ok;
+}
+
+
+/*
+ * First pass of the argument parse, converting those that can be done so
+ * without any side effects. Return TRUE if the arguments matched.
+ */
+static int parsePass1(PyObject **parseErrp, sipSimpleWrapper **selfp,
+ int *selfargp, PyObject *sipArgs, PyObject *sipKwdArgs,
+ const char **kwdlist, PyObject **unused, const char *fmt, va_list va)
+{
+ int compulsory, argnr, nr_args;
+ SIP_SSIZE_T nr_pos_args, nr_kwd_args, nr_kwd_args_used;
+ sipParseFailure failure;
+
+ failure.reason = Ok;
+ failure.detail_obj = NULL;
+ compulsory = TRUE;
+ argnr = 0;
+ nr_args = 0;
+ nr_pos_args = PyTuple_GET_SIZE(sipArgs);
+ nr_kwd_args = nr_kwd_args_used = 0;
+
+ if (sipKwdArgs != NULL)
+ {
+ assert(PyDict_Check(sipKwdArgs));
+
+ nr_kwd_args = PyDict_Size(sipKwdArgs);
+ }
+
+ /*
+ * Handle those format characters that deal with the "self" argument. They
+ * will always be the first one.
+ */
+ *selfp = NULL;
+ *selfargp = FALSE;
+
+ switch (*fmt++)
+ {
+ case 'B':
+ case 'p':
+ {
+ PyObject *self;
+ sipTypeDef *td;
+
+ self = *va_arg(va, PyObject **);
+ td = va_arg(va, sipTypeDef *);
+ va_arg(va, void **);
+
+ if (self == NULL)
+ {
+ if (!getSelfFromArgs(td, sipArgs, argnr, selfp))
+ {
+ failure.reason = Unbound;
+ failure.detail_str = sipPyNameOfContainer(
+ &((sipClassTypeDef *)td)->ctd_container, td);
+ break;
+ }
+
+ *selfargp = TRUE;
+ ++argnr;
+ }
+ else
+ *selfp = (sipSimpleWrapper *)self;
+
+ break;
+ }
+
+ case 'C':
+ *selfp = (sipSimpleWrapper *)va_arg(va,PyObject *);
+ break;
+
+ default:
+ --fmt;
+ }
+
+ /* Now handle the remaining arguments. */
+ while (failure.reason == Ok)
+ {
+ char ch;
+ PyObject *arg;
+
+ PyErr_Clear();
+
+ /* See if the following arguments are optional. */
+ if ((ch = *fmt++) == '|')
+ {
+ compulsory = FALSE;
+ ch = *fmt++;
+ }
+
+ /* See if we don't expect anything else. */
+
+ if (ch == '\0')
+ {
+ if (argnr < nr_pos_args)
+ {
+ /* There are still positional arguments. */
+ failure.reason = TooMany;
+ }
+ else if (nr_kwd_args_used != nr_kwd_args)
+ {
+ /*
+ * Take a shortcut if no keyword arguments were used and we are
+ * interested in them.
+ */
+ if (nr_kwd_args_used == 0 && unused != NULL)
+ {
+ Py_INCREF(sipKwdArgs);
+ *unused = sipKwdArgs;
+ }
+ else
+ {
+ PyObject *key, *value, *unused_dict = NULL;
+ SIP_SSIZE_T pos = 0;
+
+ /*
+ * Go through the keyword arguments to find any that were
+ * duplicates of positional arguments. For the remaining
+ * ones remember the unused ones if we are interested.
+ */
+ while (PyDict_Next(sipKwdArgs, &pos, &key, &value))
+ {
+ int a;
+
+#if PY_MAJOR_VERSION >= 3
+ if (!PyUnicode_Check(key))
+#else
+ if (!PyString_Check(key))
+#endif
+ {
+ failure.reason = KeywordNotString;
+ failure.detail_obj = key;
+ Py_INCREF(key);
+ break;
+ }
+
+ if (kwdlist != NULL)
+ {
+ /* Get the argument's index if it is one. */
+ for (a = 0; a < nr_args; ++a)
+ {
+ const char *name = kwdlist[a];
+
+ if (name == NULL)
+ continue;
+
+#if PY_MAJOR_VERSION >= 3
+ if (PyUnicode_CompareWithASCIIString(key, name) == 0)
+#else
+ if (strcmp(PyString_AS_STRING(key), name) == 0)
+#endif
+ break;
+ }
+ }
+ else
+ {
+ a = nr_args;
+ }
+
+ if (a == nr_args)
+ {
+ /*
+ * The name doesn't correspond to a keyword
+ * argument.
+ */
+ if (unused == NULL)
+ {
+ /*
+ * It may correspond to a keyword argument of a
+ * different overload.
+ */
+ failure.reason = UnknownKeyword;
+ failure.detail_obj = key;
+ Py_INCREF(key);
+
+ break;
+ }
+
+ /*
+ * Add it to the dictionary of unused arguments
+ * creating it if necessary. Note that if the
+ * unused arguments are actually used by a later
+ * overload then the parse will incorrectly
+ * succeed. This should be picked up (perhaps with
+ * a misleading exception) so long as the code that
+ * handles the unused arguments checks that it can
+ * handle them all.
+ */
+ if (unused_dict == NULL && (*unused = unused_dict = PyDict_New()) == NULL)
+ {
+ failure.reason = Raised;
+ break;
+ }
+
+ if (PyDict_SetItem(unused_dict, key, value) < 0)
+ {
+ failure.reason = Raised;
+ break;
+ }
+ }
+ else if (a < nr_pos_args)
+ {
+ /*
+ * The argument has been given positionally and as
+ * a keyword.
+ */
+ failure.reason = Duplicate;
+ failure.detail_obj = key;
+ Py_INCREF(key);
+ break;
+ }
+ }
+ }
+ }
+
+ break;
+ }
+
+ /* Get the next argument. */
+ arg = NULL;
+ failure.arg_nr = -1;
+ failure.arg_name = NULL;
+
+ if (argnr < nr_pos_args)
+ {
+ arg = PyTuple_GET_ITEM(sipArgs, argnr);
+ failure.arg_nr = argnr + 1;
+ }
+ else if (sipKwdArgs != NULL && kwdlist != NULL)
+ {
+ const char *name = kwdlist[argnr];
+
+ if (name != NULL)
+ {
+ arg = PyDict_GetItemString(sipKwdArgs, name);
+
+ if (arg != NULL)
+ ++nr_kwd_args_used;
+
+ failure.arg_name = name;
+ }
+ }
+
+ ++argnr;
+ ++nr_args;
+
+ if (arg == NULL && compulsory)
+ {
+ if (ch == 'W')
+ {
+ /*
+ * A variable number of arguments was allowed but none were
+ * given.
+ */
+ break;
+ }
+
+ /* An argument was required. */
+ failure.reason = TooFew;
+
+ /*
+ * Check if there were any unused keyword arguments so that we give
+ * a (possibly) more accurate diagnostic in the case that a keyword
+ * argument has been mis-spelled.
+ */
+ if (unused == NULL && sipKwdArgs != NULL && nr_kwd_args_used != nr_kwd_args)
+ {
+ PyObject *key, *value;
+ SIP_SSIZE_T pos = 0;
+
+ while (PyDict_Next(sipKwdArgs, &pos, &key, &value))
+ {
+ int a;
+
+#if PY_MAJOR_VERSION >= 3
+ if (!PyUnicode_Check(key))
+#else
+ if (!PyString_Check(key))
+#endif
+ {
+ failure.reason = KeywordNotString;
+ failure.detail_obj = key;
+ Py_INCREF(key);
+ break;
+ }
+
+ if (kwdlist != NULL)
+ {
+ /* Get the argument's index if it is one. */
+ for (a = 0; a < nr_args; ++a)
+ {
+ const char *name = kwdlist[a];
+
+ if (name == NULL)
+ continue;
+
+#if PY_MAJOR_VERSION >= 3
+ if (PyUnicode_CompareWithASCIIString(key, name) == 0)
+#else
+ if (strcmp(PyString_AS_STRING(key), name) == 0)
+#endif
+ break;
+ }
+ }
+ else
+ {
+ a = nr_args;
+ }
+
+ if (a == nr_args)
+ {
+ failure.reason = UnknownKeyword;
+ failure.detail_obj = key;
+ Py_INCREF(key);
+
+ break;
+ }
+ }
+ }
+
+ break;
+ }
+
+ /*
+ * Handle the format character even if we don't have an argument so
+ * that we skip the right number of arguments.
+ */
+ switch (ch)
+ {
+ case 'W':
+ /* Ellipsis. */
+ break;
+
+ case '@':
+ {
+ /* Implement /GetWrapper/. */
+
+ PyObject **p = va_arg(va, PyObject **);
+
+ if (arg != NULL)
+ *p = arg;
+
+ /* Process the same argument next time round. */
+ --argnr;
+ --nr_args;
+
+ break;
+ }
+
+ case 's':
+ {
+ /* String from a Python bytes or None. */
+
+ const char **p = va_arg(va, const char **);
+
+ if (arg != NULL && parseBytes_AsString(arg, p) < 0)
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+
+ break;
+ }
+
+ case 'A':
+ {
+ /* String from a Python string or None. */
+
+ PyObject **keep = va_arg(va, PyObject **);
+ const char **p = va_arg(va, const char **);
+ char sub_fmt = *fmt++;
+
+ if (arg != NULL)
+ {
+ PyObject *s;
+
+ switch (sub_fmt)
+ {
+ case 'A':
+ s = parseString_AsASCIIString(arg, p);
+ break;
+
+ case 'L':
+ s = parseString_AsLatin1String(arg, p);
+ break;
+
+ case '8':
+ s = parseString_AsUTF8String(arg, p);
+ break;
+ }
+
+ if (s == NULL)
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ else
+ {
+ *keep = s;
+ }
+ }
+
+ break;
+ }
+
+ case 'x':
+#if defined(HAVE_WCHAR_H)
+ {
+ /* Wide string or None. */
+
+ wchar_t **p = va_arg(va, wchar_t **);
+
+ if (arg != NULL && parseWCharString(arg, p) < 0)
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+
+ break;
+ }
+#else
+ raiseNoWChar();
+ failure.reason = Raised;
+ break;
+#endif
+
+ case 'U':
+ {
+ /* Slot name or callable, return the name or callable. */
+
+ char **sname = va_arg(va, char **);
+ PyObject **scall = va_arg(va, PyObject **);
+
+ if (arg != NULL)
+ {
+ *sname = NULL;
+ *scall = NULL;
+
+ if (SIPBytes_Check(arg))
+ {
+ char *s = SIPBytes_AS_STRING(arg);
+
+ if (*s == '1' || *s == '2' || *s == '9')
+ {
+ *sname = s;
+ }
+ else
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ }
+ else if (PyCallable_Check(arg))
+ {
+ *scall = arg;
+ }
+ else if (arg != Py_None)
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ }
+
+ break;
+ }
+
+ case 'S':
+ {
+ /* Slot name, return the name. */
+
+ char **p = va_arg(va, char **);
+
+ if (arg != NULL)
+ {
+ if (SIPBytes_Check(arg))
+ {
+ char *s = SIPBytes_AS_STRING(arg);
+
+ if (*s == '1' || *s == '2' || *s == '9')
+ {
+ *p = s;
+ }
+ else
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ }
+ else
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ }
+
+ break;
+ }
+
+ case 'G':
+ {
+ /* Signal name, return the name. */
+
+ char **p = va_arg(va, char **);
+
+ if (arg != NULL)
+ {
+ if (SIPBytes_Check(arg))
+ {
+ char *s = SIPBytes_AS_STRING(arg);
+
+ if (*s == '2' || *s == '9')
+ {
+ *p = s;
+ }
+ else
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ }
+ else
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ }
+
+ break;
+ }
+
+ case 'r':
+ {
+ /* Sequence of class or mapped type instances. */
+
+ const sipTypeDef *td;
+
+ td = va_arg(va, const sipTypeDef *);
+ va_arg(va, void **);
+ va_arg(va, SIP_SSIZE_T *);
+
+ if (arg != NULL && !canConvertFromSequence(arg, td))
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+
+ break;
+ }
+
+ case 'J':
+ {
+ /* Class or mapped type instance. */
+
+ char sub_fmt = *fmt++;
+ const sipTypeDef *td;
+ int flags = sub_fmt - '0';
+ int iflgs = 0;
+
+ td = va_arg(va, const sipTypeDef *);
+ va_arg(va, void **);
+
+ if (flags & FMT_AP_DEREF)
+ iflgs |= SIP_NOT_NONE;
+
+ if (flags & FMT_AP_TRANSFER_THIS)
+ va_arg(va, PyObject **);
+
+ if (flags & FMT_AP_NO_CONVERTORS)
+ iflgs |= SIP_NO_CONVERTORS;
+ else
+ va_arg(va, int *);
+
+ if (arg != NULL && !sip_api_can_convert_to_type(arg, td, iflgs))
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+
+ break;
+ }
+
+ case 'N':
+ {
+ /* Python object of given type or None. */
+
+ PyTypeObject *type = va_arg(va,PyTypeObject *);
+ PyObject **p = va_arg(va,PyObject **);
+
+ if (arg != NULL)
+ {
+ if (arg == Py_None || PyObject_TypeCheck(arg,type))
+ {
+ *p = arg;
+ }
+ else
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ }
+
+ break;
+ }
+
+ case 'P':
+ {
+ /* Python object of any type with a sub-format. */
+
+ va_arg(va, PyObject **);
+
+ /* Skip the sub-format. */
+ ++fmt;
+
+ break;
+ }
+
+ case 'T':
+ {
+ /* Python object of given type. */
+
+ PyTypeObject *type = va_arg(va, PyTypeObject *);
+ PyObject **p = va_arg(va, PyObject **);
+
+ if (arg != NULL)
+ {
+ if (PyObject_TypeCheck(arg,type))
+ {
+ *p = arg;
+ }
+ else
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ }
+
+ break;
+ }
+
+ case 'R':
+ {
+ /* Sub-class of QObject. */
+
+ PyObject **p = va_arg(va, PyObject **);
+
+ if (arg != NULL)
+ {
+ if (isQObject(arg))
+ {
+ *p = arg;
+ }
+ else
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ }
+
+ break;
+ }
+
+ case 'F':
+ {
+ /* Python callable object. */
+
+ PyObject **p = va_arg(va, PyObject **);
+
+ if (arg != NULL)
+ {
+ if (PyCallable_Check(arg))
+ {
+ *p = arg;
+ }
+ else
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ }
+
+ break;
+ }
+
+ case 'H':
+ {
+ /* Python callable object or None. */
+
+ PyObject **p = va_arg(va, PyObject **);
+
+ if (arg != NULL)
+ {
+ if (arg == Py_None || PyCallable_Check(arg))
+ {
+ *p = arg;
+ }
+ else
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ }
+
+ break;
+ }
+
+ case 'q':
+ {
+ /* Qt receiver to connect. */
+
+ va_arg(va, char *);
+ va_arg(va, void **);
+ va_arg(va, const char **);
+
+ if (arg != NULL && !isQObject(arg))
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+
+ break;
+ }
+
+ case 'Q':
+ {
+ /* Qt receiver to disconnect. */
+
+ va_arg(va, char *);
+ va_arg(va, void **);
+ va_arg(va, const char **);
+
+ if (arg != NULL && !isQObject(arg))
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+
+ break;
+ }
+
+ case 'g':
+ case 'y':
+ {
+ /* Python slot to connect. */
+
+ va_arg(va, char *);
+ va_arg(va, void **);
+ va_arg(va, const char **);
+
+ if (arg != NULL && (sipQtSupport == NULL || !PyCallable_Check(arg)))
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+
+ break;
+ }
+
+ case 'Y':
+ {
+ /* Python slot to disconnect. */
+
+ va_arg(va, char *);
+ va_arg(va, void **);
+ va_arg(va, const char **);
+
+ if (arg != NULL && (sipQtSupport == NULL || !PyCallable_Check(arg)))
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+
+ break;
+ }
+
+ case 'k':
+ {
+ /* Char array or None. */
+
+ const char **p = va_arg(va, const char **);
+ SIP_SSIZE_T *szp = va_arg(va, SIP_SSIZE_T *);
+
+ if (arg != NULL && parseBytes_AsCharArray(arg, p, szp) < 0)
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+
+ break;
+ }
+
+ case 'K':
+#if defined(HAVE_WCHAR_H)
+ {
+ /* Wide char array or None. */
+
+ wchar_t **p = va_arg(va, wchar_t **);
+ SIP_SSIZE_T *szp = va_arg(va, SIP_SSIZE_T *);
+
+ if (arg != NULL && parseWCharArray(arg, p, szp) < 0)
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+
+ break;
+ }
+#else
+ raiseNoWChar();
+ failure.reason = Raised;
+ break
+#endif
+
+ case 'c':
+ {
+ /* Character from a Python bytes. */
+
+ char *p = va_arg(va, char *);
+
+ if (arg != NULL && parseBytes_AsChar(arg, p) < 0)
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+
+ break;
+ }
+
+ case 'a':
+ {
+ /* Character from a Python string. */
+
+ char *p = va_arg(va, char *);
+ char sub_fmt = *fmt++;
+
+ if (arg != NULL)
+ {
+ int enc;
+
+ switch (sub_fmt)
+ {
+ case 'A':
+ enc = parseString_AsASCIIChar(arg, p);
+ break;
+
+ case 'L':
+ enc = parseString_AsLatin1Char(arg, p);
+ break;
+
+ case '8':
+ enc = parseString_AsUTF8Char(arg, p);
+ break;
+ }
+
+ if (enc < 0)
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ }
+
+ break;
+ }
+
+ case 'w':
+#if defined(HAVE_WCHAR_H)
+ {
+ /* Wide character. */
+
+ wchar_t *p = va_arg(va, wchar_t *);
+
+ if (arg != NULL && parseWChar(arg, p) < 0)
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+
+ break;
+ }
+#else
+ raiseNoWChar();
+ failure.reason = Raised;
+ break
+#endif
+
+ case 'b':
+ {
+ /* Bool. */
+
+ void *p = va_arg(va, void *);
+
+ if (arg != NULL)
+ {
+ int v = SIPLong_AsLong(arg);
+
+ if (PyErr_Occurred())
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ else
+ {
+ sipSetBool(p, v);
+ }
+ }
+
+ break;
+ }
+
+ case 'E':
+ {
+ /* Named enum or integer. */
+
+ sipTypeDef *td = va_arg(va, sipTypeDef *);
+
+ va_arg(va, int *);
+
+ if (arg != NULL && !sip_api_can_convert_to_enum(arg, td))
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ }
+
+ break;
+
+ case 'e':
+ case 'i':
+ {
+ /* Integer or anonymous enum. */
+
+ int *p = va_arg(va, int *);
+
+ if (arg != NULL)
+ {
+ int v = SIPLong_AsLong(arg);
+
+ if (PyErr_Occurred())
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ else
+ {
+ *p = v;
+ }
+ }
+
+ break;
+ }
+
+ case 'u':
+ {
+ /* Unsigned integer. */
+
+ unsigned *p = va_arg(va, unsigned *);
+
+ if (arg != NULL)
+ {
+ unsigned v = sip_api_long_as_unsigned_long(arg);
+
+ if (PyErr_Occurred())
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ else
+ {
+ *p = v;
+ }
+ }
+
+ break;
+ }
+
+ case 'h':
+ {
+ /* Short integer. */
+
+ short *p = va_arg(va, short *);
+
+ if (arg != NULL)
+ {
+ short v = SIPLong_AsLong(arg);
+
+ if (PyErr_Occurred())
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ else
+ {
+ *p = v;
+ }
+ }
+
+ break;
+ }
+
+ case 't':
+ {
+ /* Unsigned short integer. */
+
+ unsigned short *p = va_arg(va, unsigned short *);
+
+ if (arg != NULL)
+ {
+ unsigned short v = sip_api_long_as_unsigned_long(arg);
+
+ if (PyErr_Occurred())
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ else
+ {
+ *p = v;
+ }
+ }
+
+ break;
+ }
+
+ case 'l':
+ {
+ /* Long integer. */
+
+ long *p = va_arg(va, long *);
+
+ if (arg != NULL)
+ {
+ long v = PyLong_AsLong(arg);
+
+ if (PyErr_Occurred())
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ else
+ {
+ *p = v;
+ }
+ }
+
+ break;
+ }
+
+ case 'm':
+ {
+ /* Unsigned long integer. */
+
+ unsigned long *p = va_arg(va, unsigned long *);
+
+ if (arg != NULL)
+ {
+ unsigned long v = sip_api_long_as_unsigned_long(arg);
+
+ if (PyErr_Occurred())
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ else
+ {
+ *p = v;
+ }
+ }
+
+ break;
+ }
+
+ case 'n':
+ {
+ /* Long long integer. */
+
+#if defined(HAVE_LONG_LONG)
+ PY_LONG_LONG *p = va_arg(va, PY_LONG_LONG *);
+#else
+ long *p = va_arg(va, long *);
+#endif
+
+ if (arg != NULL)
+ {
+#if defined(HAVE_LONG_LONG)
+ PY_LONG_LONG v = PyLong_AsLongLong(arg);
+#else
+ long v = PyLong_AsLong(arg);
+#endif
+
+ if (PyErr_Occurred())
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ else
+ {
+ *p = v;
+ }
+ }
+
+ break;
+ }
+
+ case 'o':
+ {
+ /* Unsigned long long integer. */
+
+#if defined(HAVE_LONG_LONG)
+ unsigned PY_LONG_LONG *p = va_arg(va, unsigned PY_LONG_LONG *);
+#else
+ unsigned long *p = va_arg(va, unsigned long *);
+#endif
+
+ if (arg != NULL)
+ {
+#if defined(HAVE_LONG_LONG)
+ unsigned PY_LONG_LONG v = PyLong_AsUnsignedLongLong(arg);
+#else
+ unsigned long v = PyLong_AsUnsignedLong(arg);
+#endif
+
+ if (PyErr_Occurred())
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ else
+ {
+ *p = v;
+ }
+ }
+
+ break;
+ }
+
+ case 'f':
+ {
+ /* Float. */
+
+ float *p = va_arg(va, float *);
+
+ if (arg != NULL)
+ {
+ double v = PyFloat_AsDouble(arg);
+
+ if (PyErr_Occurred())
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ else
+ {
+ *p = (float)v;
+ }
+ }
+
+ break;
+ }
+
+ case 'X':
+ {
+ /* Constrained types. */
+
+ char sub_fmt = *fmt++;
+
+ if (sub_fmt == 'E')
+ {
+ /* Named enum. */
+
+ sipTypeDef *td = va_arg(va, sipTypeDef *);
+
+ va_arg(va, int *);
+
+ if (arg != NULL && !PyObject_TypeCheck(arg, sipTypeAsPyTypeObject(td)))
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ }
+ else
+ {
+ void *p = va_arg(va, void *);
+
+ if (arg != NULL)
+ {
+ switch (sub_fmt)
+ {
+ case 'b':
+ {
+ /* Boolean. */
+
+ if (PyBool_Check(arg))
+ {
+ sipSetBool(p, (arg == Py_True));
+ }
+ else
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+
+ break;
+ }
+
+ case 'd':
+ {
+ /* Double float. */
+
+ if (PyFloat_Check(arg))
+ {
+ *(double *)p = PyFloat_AS_DOUBLE(arg);
+ }
+ else
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+
+ break;
+ }
+
+ case 'f':
+ {
+ /* Float. */
+
+ if (PyFloat_Check(arg))
+ {
+ *(float *)p = (float)PyFloat_AS_DOUBLE(arg);
+ }
+ else
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+
+ break;
+ }
+
+ case 'i':
+ {
+ /* Integer. */
+
+#if PY_MAJOR_VERSION >= 3
+ if (PyLong_Check(arg))
+ {
+ *(int *)p = PyLong_AS_LONG(arg);
+ }
+#else
+ if (PyInt_Check(arg))
+ {
+ *(int *)p = PyInt_AS_LONG(arg);
+ }
+#endif
+ else
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+
+ break;
+ }
+ }
+ }
+ }
+
+ break;
+ }
+
+ case 'd':
+ {
+ /* Double float. */
+
+ double *p = va_arg(va,double *);
+
+ if (arg != NULL)
+ {
+ double v = PyFloat_AsDouble(arg);
+
+ if (PyErr_Occurred())
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ else
+ {
+ *p = v;
+ }
+ }
+
+ break;
+ }
+
+ case 'v':
+ {
+ /* Void pointer. */
+
+ void **p = va_arg(va, void **);
+
+ if (arg != NULL)
+ {
+ void *v = sip_api_convert_to_void_ptr(arg);
+
+ if (PyErr_Occurred())
+ {
+ failure.reason = WrongType;
+ failure.detail_obj = arg;
+ Py_INCREF(arg);
+ }
+ else
+ {
+ *p = v;
+ }
+ }
+
+ break;
+ }
+ }
+
+ if (failure.reason == Ok && ch == 'W')
+ {
+ /* An ellipsis matches everything and ends the parse. */
+ break;
+ }
+ }
+
+ /* Handle parse failures appropriately. */
+
+ if (failure.reason == Ok)
+ return TRUE;
+
+ if (failure.reason != Raised)
+ {
+ add_failure(parseErrp, &failure);
+ }
+
+ if (failure.reason == Raised)
+ {
+ Py_XDECREF(failure.detail_obj);
+
+ /*
+ * The error isn't a user error so don't bother with the detail of the
+ * overload.
+ */
+ Py_XDECREF(*parseErrp);
+ *parseErrp = Py_None;
+ Py_INCREF(Py_None);
+ }
+
+ return FALSE;
+}
+
+
+/*
+ * Second pass of the argument parse, converting the remaining ones that might
+ * have side effects. Return TRUE if there was no error.
+ */
+static int parsePass2(sipSimpleWrapper *self, int selfarg, PyObject *sipArgs,
+ PyObject *sipKwdArgs, const char **kwdlist, const char *fmt,
+ va_list va)
+{
+ int a, ok;
+ SIP_SSIZE_T nr_pos_args;
+
+ /* Handle the converions of "self" first. */
+ switch (*fmt++)
+ {
+ case 'B':
+ {
+ /*
+ * The address of a C++ instance when calling one of its public
+ * methods.
+ */
+
+ const sipTypeDef *td;
+ void **p;
+
+ *va_arg(va, PyObject **) = (PyObject *)self;
+ td = va_arg(va, const sipTypeDef *);
+ p = va_arg(va, void **);
+
+ if ((*p = sip_api_get_cpp_ptr(self, td)) == NULL)
+ return FALSE;
+
+ break;
+ }
+
+ case 'p':
+ {
+ /*
+ * The address of a C++ instance when calling one of its protected
+ * methods.
+ */
+
+ const sipTypeDef *td;
+ void **p;
+
+ *va_arg(va, PyObject **) = (PyObject *)self;
+ td = va_arg(va, const sipTypeDef *);
+ p = va_arg(va, void **);
+
+ if ((*p = getComplexCppPtr(self, td)) == NULL)
+ return FALSE;
+
+ break;
+ }
+
+ case 'C':
+ va_arg(va, PyObject *);
+ break;
+
+ default:
+ --fmt;
+ }
+
+ ok = TRUE;
+ nr_pos_args = PyTuple_GET_SIZE(sipArgs);
+
+ for (a = (selfarg ? 1 : 0); *fmt != '\0' && *fmt != 'W' && ok; ++a)
+ {
+ char ch;
+ PyObject *arg;
+
+ /* Skip the optional character. */
+ if ((ch = *fmt++) == '|')
+ ch = *fmt++;
+
+ /* Get the next argument. */
+ arg = NULL;
+
+ if (a < nr_pos_args)
+ {
+ arg = PyTuple_GET_ITEM(sipArgs, a);
+ }
+ else if (sipKwdArgs != NULL)
+ {
+ const char *name = kwdlist[a];
+
+ if (name != NULL)
+ arg = PyDict_GetItemString(sipKwdArgs, name);
+ }
+
+ /*
+ * Do the outstanding conversions. For most types it has already been
+ * done, so we are just skipping the parameters.
+ */
+ switch (ch)
+ {
+ case '@':
+ /* Implement /GetWrapper/. */
+ va_arg(va, PyObject **);
+
+ /* Process the same argument next time round. */
+ --a;
+
+ break;
+
+ case 'q':
+ {
+ /* Qt receiver to connect. */
+
+ char *sig = va_arg(va, char *);
+ void **rx = va_arg(va, void **);
+ const char **slot = va_arg(va, const char **);
+
+ if (arg != NULL)
+ {
+ *rx = sip_api_convert_rx((sipWrapper *)self, sig, arg,
+ *slot, slot, 0);
+
+ if (*rx == NULL)
+ return FALSE;
+ }
+
+ break;
+ }
+
+ case 'Q':
+ {
+ /* Qt receiver to disconnect. */
+
+ char *sig = va_arg(va, char *);
+ void **rx = va_arg(va, void **);
+ const char **slot = va_arg(va, const char **);
+
+ if (arg != NULL)
+ *rx = sipGetRx(self, sig, arg, *slot, slot);
+
+ break;
+ }
+
+ case 'g':
+ {
+ /* Python single shot slot to connect. */
+
+ char *sig = va_arg(va, char *);
+ void **rx = va_arg(va, void **);
+ const char **slot = va_arg(va, const char **);
+
+ if (arg != NULL)
+ {
+ *rx = sip_api_convert_rx((sipWrapper *)self, sig, arg,
+ NULL, slot, SIP_SINGLE_SHOT);
+
+ if (*rx == NULL)
+ return FALSE;
+ }
+
+ break;
+ }
+
+ case 'y':
+ {
+ /* Python slot to connect. */
+
+ char *sig = va_arg(va, char *);
+ void **rx = va_arg(va, void **);
+ const char **slot = va_arg(va, const char **);
+
+ if (arg != NULL)
+ {
+ *rx = sip_api_convert_rx((sipWrapper *)self, sig, arg,
+ NULL, slot, 0);
+
+ if (*rx == NULL)
+ return FALSE;
+ }
+
+ break;
+ }
+
+ case 'Y':
+ {
+ /* Python slot to disconnect. */
+
+ char *sig = va_arg(va, char *);
+ void **rx = va_arg(va, void **);
+ const char **slot = va_arg(va, const char **);
+
+ if (arg != NULL)
+ *rx = sipGetRx(self, sig, arg, NULL, slot);
+
+ break;
+ }
+
+ case 'r':
+ {
+ /* Sequence of class or mapped type instances. */
+
+ const sipTypeDef *td;
+ void **array;
+ SIP_SSIZE_T *nr_elem;
+
+ td = va_arg(va, const sipTypeDef *);
+ array = va_arg(va, void **);
+ nr_elem = va_arg(va, SIP_SSIZE_T *);
+
+ if (arg != NULL && !convertFromSequence(arg, td, array, nr_elem))
+ return FALSE;
+
+ break;
+ }
+
+ case 'J':
+ {
+ /* Class or mapped type instance. */
+
+ int flags = *fmt++ - '0';
+ const sipTypeDef *td;
+ void **p;
+ int iflgs = 0;
+ int *state;
+ PyObject *xfer, **owner;
+
+ td = va_arg(va, const sipTypeDef *);
+ p = va_arg(va, void **);
+
+ if (flags & FMT_AP_TRANSFER)
+ xfer = (self ? (PyObject *)self : arg);
+ else if (flags & FMT_AP_TRANSFER_BACK)
+ xfer = Py_None;
+ else
+ xfer = NULL;
+
+ if (flags & FMT_AP_DEREF)
+ iflgs |= SIP_NOT_NONE;
+
+ if (flags & FMT_AP_TRANSFER_THIS)
+ owner = va_arg(va, PyObject **);
+
+ if (flags & FMT_AP_NO_CONVERTORS)
+ {
+ iflgs |= SIP_NO_CONVERTORS;
+ state = NULL;
+ }
+ else
+ {
+ state = va_arg(va, int *);
+ }
+
+ if (arg != NULL)
+ {
+ int iserr = FALSE;
+
+ *p = sip_api_convert_to_type(arg, td, xfer, iflgs, state,
+ &iserr);
+
+ if (iserr)
+ return FALSE;
+
+ if (flags & FMT_AP_TRANSFER_THIS && *p != NULL)
+ *owner = arg;
+ }
+
+ break;
+ }
+
+ case 'P':
+ {
+ /* Python object of any type with a sub-format. */
+
+ PyObject **p = va_arg(va, PyObject **);
+ int flags = *fmt++ - '0';
+
+ if (arg != NULL)
+ {
+ if (flags & FMT_AP_TRANSFER)
+ {
+ Py_XINCREF(arg);
+ }
+ else if (flags & FMT_AP_TRANSFER_BACK)
+ {
+ Py_XDECREF(arg);
+ }
+
+ *p = arg;
+ }
+
+ break;
+ }
+
+ case 'X':
+ {
+ /* Constrained types. */
+
+ va_arg(va, void *);
+
+ if (*fmt++ == 'E')
+ {
+ /* Named enum. */
+
+ int *p = va_arg(va, int *);
+
+ if (arg != NULL)
+ *p = SIPLong_AsLong(arg);
+ }
+
+ break;
+ }
+
+ case 'E':
+ {
+ /* Named enum. */
+
+ int *p;
+
+ va_arg(va, sipTypeDef *);
+ p = va_arg(va, int *);
+
+ if (arg != NULL)
+ *p = SIPLong_AsLong(arg);
+
+ break;
+ }
+
+ /*
+ * These need special handling because they have a sub-format
+ * character.
+ */
+ case 'A':
+ va_arg(va, void *);
+
+ /* Drop through. */
+
+ case 'a':
+ va_arg(va, void *);
+ fmt++;
+ break;
+
+ /*
+ * Every other argument is a pointer and only differ in how many there
+ * are.
+ */
+ case 'N':
+ case 'T':
+ case 'k':
+ case 'K':
+ va_arg(va, void *);
+
+ /* Drop through. */
+
+ default:
+ va_arg(va, void *);
+ }
+ }
+
+ /* Handle any ellipsis argument. */
+ if (*fmt == 'W')
+ {
+ PyObject *al;
+ int da = 0;
+
+ /* Create a tuple for any remaining arguments. */
+ if ((al = PyTuple_New(nr_pos_args - a)) == NULL)
+ return FALSE;
+
+ while (a < nr_pos_args)
+ {
+ PyObject *arg = PyTuple_GET_ITEM(sipArgs, a);
+
+ /* Add the remaining argument to the tuple. */
+ Py_INCREF(arg);
+ PyTuple_SET_ITEM(al, da, arg);
+
+ ++a;
+ ++da;
+ }
+
+ /* Return the tuple. */
+ *va_arg(va, PyObject **) = al;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Return TRUE if an object is a QObject.
+ */
+static int isQObject(PyObject *obj)
+{
+ return (sipQtSupport != NULL && PyObject_TypeCheck(obj, sipTypeAsPyTypeObject(sipQObjectType)));
+}
+
+
+/*
+ * See if a Python object is a sequence of a particular type.
+ */
+static int canConvertFromSequence(PyObject *seq, const sipTypeDef *td)
+{
+ SIP_SSIZE_T i, size = PySequence_Size(seq);
+
+ if (size < 0)
+ return FALSE;
+
+ for (i = 0; i < size; ++i)
+ {
+ int ok;
+ PyObject *val_obj;
+
+ if ((val_obj = PySequence_GetItem(seq, i)) == NULL)
+ return FALSE;
+
+ ok = sip_api_can_convert_to_type(val_obj, td,
+ SIP_NO_CONVERTORS|SIP_NOT_NONE);
+
+ Py_DECREF(val_obj);
+
+ if (!ok)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Convert a Python sequence to an array that has already "passed"
+ * canConvertFromSequence(). Return TRUE if the conversion was successful.
+ */
+static int convertFromSequence(PyObject *seq, const sipTypeDef *td,
+ void **array, SIP_SSIZE_T *nr_elem)
+{
+ int iserr = 0;
+ SIP_SSIZE_T i, size = PySequence_Size(seq);
+ sipArrayFunc array_helper;
+ sipAssignFunc assign_helper;
+ void *array_mem;
+
+ /* Get the type's helpers. */
+ if (sipTypeIsMapped(td))
+ {
+ array_helper = ((const sipMappedTypeDef *)td)->mtd_array;
+ assign_helper = ((const sipMappedTypeDef *)td)->mtd_assign;
+ }
+ else
+ {
+ array_helper = ((const sipClassTypeDef *)td)->ctd_array;
+ assign_helper = ((const sipClassTypeDef *)td)->ctd_assign;
+ }
+
+ assert(array_helper != NULL);
+ assert(assign_helper != NULL);
+
+ /*
+ * Create the memory for the array of values. Note that this will leak if
+ * there is an error.
+ */
+ array_mem = array_helper(size);
+
+ for (i = 0; i < size; ++i)
+ {
+ PyObject *val_obj;
+ void *val;
+
+ if ((val_obj = PySequence_GetItem(seq, i)) == NULL)
+ return FALSE;
+
+ val = sip_api_convert_to_type(val_obj, td, NULL,
+ SIP_NO_CONVERTORS|SIP_NOT_NONE, NULL, &iserr);
+
+ Py_DECREF(val_obj);
+
+ if (iserr)
+ return FALSE;
+
+ assign_helper(array_mem, i, val);
+ }
+
+ *array = array_mem;
+ *nr_elem = size;
+
+ return TRUE;
+}
+
+
+/*
+ * Convert an array of a type to a Python sequence.
+ */
+static PyObject *convertToSequence(void *array, SIP_SSIZE_T nr_elem,
+ const sipTypeDef *td)
+{
+ SIP_SSIZE_T i;
+ PyObject *seq;
+ sipCopyFunc copy_helper;
+
+ /* Get the type's copy helper. */
+ if (sipTypeIsMapped(td))
+ copy_helper = ((const sipMappedTypeDef *)td)->mtd_copy;
+ else
+ copy_helper = ((const sipClassTypeDef *)td)->ctd_copy;
+
+ assert(copy_helper != NULL);
+
+ if ((seq = PyTuple_New(nr_elem)) == NULL)
+ return NULL;
+
+ for (i = 0; i < nr_elem; ++i)
+ {
+ void *el = copy_helper(array, i);
+ PyObject *el_obj = sip_api_convert_from_new_type(el, td, NULL);
+
+ if (el_obj == NULL)
+ {
+ release(el, td, 0);
+ Py_DECREF(seq);
+ }
+
+ PyTuple_SET_ITEM(seq, i, el_obj);
+ }
+
+ return seq;
+}
+
+
+/*
+ * Carry out actions common to all dtors.
+ */
+void sip_api_common_dtor(sipSimpleWrapper *sipSelf)
+{
+ if (sipSelf != NULL && sipInterpreter != NULL)
+ {
+ PyObject *xtype, *xvalue, *xtb;
+
+ SIP_BLOCK_THREADS
+
+ /* We may be tidying up after an exception so preserve it. */
+ PyErr_Fetch(&xtype, &xvalue, &xtb);
+ callPyDtor(sipSelf);
+ PyErr_Restore(xtype, xvalue, xtb);
+
+ if (!sipNotInMap(sipSelf))
+ sipOMRemoveObject(&cppPyMap, sipSelf);
+
+ /* This no longer points to anything useful. */
+ sipSelf->u.cppPtr = NULL;
+
+ /*
+ * If C/C++ has a reference (and therefore no parent) then remove it.
+ * Otherwise remove the object from any parent.
+ */
+ if (sipCppHasRef(sipSelf))
+ {
+ sipResetCppHasRef(sipSelf);
+ Py_DECREF(sipSelf);
+ }
+ else if (PyObject_TypeCheck((PyObject *)sipSelf, (PyTypeObject *)&sipWrapper_Type))
+ removeFromParent((sipWrapper *)sipSelf);
+
+ SIP_UNBLOCK_THREADS
+ }
+}
+
+
+/*
+ * Call self.__dtor__() if it is implemented.
+ */
+static void callPyDtor(sipSimpleWrapper *self)
+{
+ sip_gilstate_t sipGILState;
+ char pymc = 0;
+ PyObject *meth;
+
+ meth = sip_api_is_py_method(&sipGILState, &pymc, self, NULL, "__dtor__");
+
+ if (meth != NULL)
+ {
+ PyObject *res = sip_api_call_method(0, meth, "", NULL);
+
+ Py_DECREF(meth);
+
+ /* Discard any result. */
+ Py_XDECREF(res);
+
+ /* Handle any error the best we can. */
+ if (PyErr_Occurred())
+ PyErr_Print();
+
+ SIP_RELEASE_GIL(sipGILState);
+ }
+}
+
+
+/*
+ * Add a wrapper to it's parent owner. The wrapper must not currently have a
+ * parent and, therefore, no siblings.
+ */
+static void addToParent(sipWrapper *self, sipWrapper *owner)
+{
+ if (owner->first_child != NULL)
+ {
+ self->sibling_next = owner->first_child;
+ owner->first_child->sibling_prev = self;
+ }
+
+ owner->first_child = self;
+ self->parent = owner;
+
+ /*
+ * The owner holds a real reference so that the cyclic garbage collector
+ * works properly.
+ */
+ Py_INCREF((sipSimpleWrapper *)self);
+}
+
+
+/*
+ * Remove a wrapper from it's parent if it has one.
+ */
+static void removeFromParent(sipWrapper *self)
+{
+ if (self->parent != NULL)
+ {
+ if (self->parent->first_child == self)
+ self->parent->first_child = self->sibling_next;
+
+ if (self->sibling_next != NULL)
+ self->sibling_next->sibling_prev = self->sibling_prev;
+
+ if (self->sibling_prev != NULL)
+ self->sibling_prev->sibling_next = self->sibling_next;
+
+ self->parent = NULL;
+ self->sibling_next = NULL;
+ self->sibling_prev = NULL;
+
+ /*
+ * We must do this last, after all the pointers are correct, because
+ * this is used by the clear slot.
+ */
+ Py_DECREF((sipSimpleWrapper *)self);
+ }
+}
+
+
+/*
+ * Convert a sequence index. Return the index or a negative value if there was
+ * an error.
+ */
+static SIP_SSIZE_T sip_api_convert_from_sequence_index(SIP_SSIZE_T idx,
+ SIP_SSIZE_T len)
+{
+ /* Negative indices start from the other end. */
+ if (idx < 0)
+ idx = len + idx;
+
+ if (idx < 0 || idx >= len)
+ {
+ PyErr_Format(PyExc_IndexError, "sequence index out of range");
+ return -1;
+ }
+
+ return idx;
+}
+
+
+/*
+ * Return a tuple of the base classes of a type that has no explicit
+ * super-type.
+ */
+static PyObject *getDefaultBases(void)
+{
+ static PyObject *default_bases = NULL;
+
+ /* Only do this once. */
+ if (default_bases == NULL)
+ {
+#if PY_VERSION_HEX >= 0x02040000
+ default_bases = PyTuple_Pack(1, (PyObject *)&sipWrapper_Type);
+#else
+ default_bases = Py_BuildValue("(O)", &sipWrapper_Type);
+#endif
+
+ if (default_bases == NULL)
+ return NULL;
+ }
+
+ Py_INCREF(default_bases);
+
+ return default_bases;
+}
+
+
+/*
+ * Return the dictionary of a type.
+ */
+static PyObject *getScopeDict(sipTypeDef *td, PyObject *mod_dict,
+ sipExportedModuleDef *client)
+{
+ /*
+ * Initialise the scoping type if necessary. It will always be in the
+ * same module if it needs doing.
+ */
+ if (sipTypeIsMapped(td))
+ {
+ if (createMappedType(client, (sipMappedTypeDef *)td, mod_dict) < 0)
+ return NULL;
+
+ /* Check that the mapped type can act as a container. */
+ assert(sipTypeAsPyTypeObject(td) != NULL);
+ }
+ else
+ {
+ if (createClassType(client, (sipClassTypeDef *)td, mod_dict) < 0)
+ return NULL;
+ }
+
+ return (sipTypeAsPyTypeObject(td))->tp_dict;
+}
+
+
+/*
+ * Create a container type and return a borrowed reference to it.
+ */
+static PyObject *createContainerType(sipContainerDef *cod, sipTypeDef *td,
+ PyObject *bases, PyObject *metatype, PyObject *mod_dict,
+ sipExportedModuleDef *client)
+{
+ PyObject *py_type, *scope_dict, *typedict, *name, *args;
+
+ /* Get the dictionary to place the type in. */
+ if (cod->cod_scope.sc_flag)
+ {
+ scope_dict = mod_dict;
+ }
+ else if ((scope_dict = getScopeDict(getGeneratedType(&cod->cod_scope, client), mod_dict, client)) == NULL)
+ goto reterr;
+
+ /* Create the type dictionary. */
+ if ((typedict = createTypeDict(client->em_nameobj)) == NULL)
+ goto reterr;
+
+ /* Create an object corresponding to the type name. */
+#if PY_MAJOR_VERSION >= 3
+ name = PyUnicode_FromString(sipPyNameOfContainer(cod, td));
+#else
+ name = PyString_FromString(sipPyNameOfContainer(cod, td));
+#endif
+
+ if (name == NULL)
+ goto reldict;
+
+ /* Create the type by calling the metatype. */
+#if PY_VERSION_HEX >= 0x02040000
+ args = PyTuple_Pack(3, name, bases, typedict);
+#else
+ args = Py_BuildValue("OOO", name, bases, typedict);
+#endif
+
+ if (args == NULL)
+ goto relname;
+
+ /* Pass the type via the back door. */
+ currentType = td;
+
+ if ((py_type = PyObject_Call(metatype, args, NULL)) == NULL)
+ goto relargs;
+
+ /* Add the type to the "parent" dictionary. */
+ if (PyDict_SetItem(scope_dict, name, py_type) < 0)
+ goto reltype;
+
+ Py_DECREF(args);
+ Py_DECREF(name);
+ Py_DECREF(typedict);
+
+ return py_type;
+
+ /* Unwind on error. */
+
+reltype:
+ Py_DECREF(py_type);
+
+relargs:
+ Py_DECREF(args);
+
+relname:
+ Py_DECREF(name);
+
+reldict:
+ Py_DECREF(typedict);
+
+reterr:
+ currentType = NULL;
+ return NULL;
+}
+
+
+/*
+ * Create a single class type object.
+ */
+static int createClassType(sipExportedModuleDef *client, sipClassTypeDef *ctd,
+ PyObject *mod_dict)
+{
+ PyObject *bases, *metatype, *py_type;
+ sipEncodedTypeDef *sup;
+
+ /* Handle the trivial case where we have already been initialised. */
+ if (ctd->ctd_base.td_module != NULL)
+ return 0;
+
+ /* Set this up now to gain access to the string pool. */
+ ctd->ctd_base.td_module = client;
+
+ /* Create the tuple of super-types. */
+ if ((sup = ctd->ctd_supers) == NULL)
+ {
+ if (ctd->ctd_supertype < 0)
+ {
+ bases = getDefaultBases();
+ }
+ else
+ {
+ PyObject *supertype;
+ const char *supertype_name = sipNameFromPool(client,
+ ctd->ctd_supertype);
+
+ if ((supertype = findPyType(supertype_name)) == NULL)
+ goto reterr;
+
+#if PY_VERSION_HEX >= 0x02040000
+ bases = PyTuple_Pack(1, supertype);
+#else
+ bases = Py_BuildValue("(O)", supertype);
+#endif
+ }
+
+ if (bases == NULL)
+ goto reterr;
+ }
+ else
+ {
+ int i, nrsupers = 0;
+
+ do
+ ++nrsupers;
+ while (!sup++->sc_flag);
+
+ if ((bases = PyTuple_New(nrsupers)) == NULL)
+ goto reterr;
+
+ for (sup = ctd->ctd_supers, i = 0; i < nrsupers; ++i, ++sup)
+ {
+ PyObject *st;
+ sipTypeDef *sup_td = getGeneratedType(sup, client);
+
+ /*
+ * Initialise the super-class if necessary. It will always be in
+ * the same module if it needs doing.
+ */
+ if (createClassType(client, (sipClassTypeDef *)sup_td, mod_dict) < 0)
+ goto relbases;
+
+ st = (PyObject *)sipTypeAsPyTypeObject(sup_td);
+
+ Py_INCREF(st);
+ PyTuple_SET_ITEM(bases, i, st);
+ }
+ }
+
+ /*
+ * Use the explicit meta-type if there is one, otherwise use the meta-type
+ * of the first super-type.
+ */
+ if (ctd->ctd_metatype >= 0)
+ {
+ const char *metatype_name = sipNameFromPool(client, ctd->ctd_metatype);
+
+ if ((metatype = findPyType(metatype_name)) == NULL)
+ goto relbases;
+ }
+ else
+ metatype = (PyObject *)Py_TYPE(PyTuple_GET_ITEM(bases, 0));
+
+ if ((py_type = createContainerType(&ctd->ctd_container, (sipTypeDef *)ctd, bases, metatype, mod_dict, client)) == NULL)
+ goto relbases;
+
+ /* Handle the pickle function. */
+ if (ctd->ctd_pickle != NULL)
+ {
+ static PyMethodDef md = {
+ "_pickle_type", pickle_type, METH_NOARGS, NULL
+ };
+
+ if (setReduce((PyTypeObject *)py_type, &md) < 0)
+ goto reltype;
+ }
+
+ /* We can now release our references. */
+ Py_DECREF(bases);
+
+ return 0;
+
+ /* Unwind after an error. */
+
+reltype:
+ Py_DECREF(py_type);
+
+relbases:
+ Py_DECREF(bases);
+
+reterr:
+ ctd->ctd_base.td_module = NULL;
+ return -1;
+}
+
+
+/*
+ * Create a single mapped type object.
+ */
+static int createMappedType(sipExportedModuleDef *client,
+ sipMappedTypeDef *mtd, PyObject *mod_dict)
+{
+ PyObject *bases;
+
+ /* Handle the trivial case where we have already been initialised. */
+ if (mtd->mtd_base.td_module != NULL)
+ return 0;
+
+ /* Set this up now to gain access to the string pool. */
+ mtd->mtd_base.td_module = client;
+
+ /* Create the tuple of super-types. */
+ if ((bases = getDefaultBases()) == NULL)
+ goto reterr;
+
+ if (createContainerType(&mtd->mtd_container, (sipTypeDef *)mtd, bases, (PyObject *)&sipWrapperType_Type, mod_dict, client) == NULL)
+ goto relbases;
+
+ /* We can now release our references. */
+ Py_DECREF(bases);
+
+ return 0;
+
+ /* Unwind after an error. */
+
+relbases:
+ Py_DECREF(bases);
+
+reterr:
+ mtd->mtd_base.td_module = NULL;
+ return -1;
+}
+
+
+/*
+ * Return the module definition for a named module.
+ */
+static sipExportedModuleDef *getModule(PyObject *mname_obj)
+{
+ PyObject *mod;
+ sipExportedModuleDef *em;
+
+ /* Make sure the module is imported. */
+ if ((mod = PyImport_Import(mname_obj)) == NULL)
+ return NULL;
+
+ /* Find the module definition. */
+ for (em = moduleList; em != NULL; em = em->em_next)
+#if PY_MAJOR_VERSION >= 3
+ if (PyUnicode_Compare(mname_obj, em->em_nameobj) == 0)
+#else
+ if (strcmp(PyString_AS_STRING(mname_obj), sipNameOfModule(em)) == 0)
+#endif
+ break;
+
+ Py_DECREF(mod);
+
+ if (em == NULL)
+ {
+#if PY_MAJOR_VERSION >= 3
+ PyErr_Format(PyExc_SystemError, "unable to find to find module: %U",
+ mname_obj);
+#else
+ PyErr_Format(PyExc_SystemError, "unable to find to find module: %s",
+ PyString_AS_STRING(mname_obj));
+#endif
+ }
+
+ return em;
+}
+
+
+/*
+ * The type unpickler.
+ */
+static PyObject *unpickle_type(PyObject *ignore, PyObject *args)
+{
+ PyObject *mname_obj, *init_args;
+ const char *tname;
+ sipExportedModuleDef *em;
+ int i;
+
+ if (!PyArg_ParseTuple(args,
+#if PY_MAJOR_VERSION >= 3
+ "UsO!:_unpickle_type",
+#else
+ "SsO!:_unpickle_type",
+#endif
+ &mname_obj, &tname, &PyTuple_Type, &init_args))
+ return NULL;
+
+ /* Get the module definition. */
+ if ((em = getModule(mname_obj)) == NULL)
+ return NULL;
+
+ /* Find the class type object. */
+ for (i = 0; i < em->em_nrtypes; ++i)
+ {
+ sipTypeDef *td = em->em_types[i];
+
+ if (td != NULL && !sipTypeIsStub(td) && sipTypeIsClass(td))
+ {
+ const char *pyname = sipPyNameOfContainer(
+ &((sipClassTypeDef *)td)->ctd_container, td);
+
+ if (strcmp(pyname, tname) == 0)
+ return PyObject_CallObject((PyObject *)sipTypeAsPyTypeObject(td), init_args);
+ }
+ }
+
+ PyErr_Format(PyExc_SystemError, "unable to find to find type: %s", tname);
+
+ return NULL;
+}
+
+
+/*
+ * The type pickler.
+ */
+static PyObject *pickle_type(PyObject *obj, PyObject *ignore)
+{
+ sipExportedModuleDef *em;
+
+ /* Find the type definition and defining module. */
+ for (em = moduleList; em != NULL; em = em->em_next)
+ {
+ int i;
+
+ for (i = 0; i < em->em_nrtypes; ++i)
+ {
+ sipTypeDef *td = em->em_types[i];
+
+ if (td != NULL && !sipTypeIsStub(td) && sipTypeIsClass(td))
+ if (sipTypeAsPyTypeObject(td) == Py_TYPE(obj))
+ {
+ PyObject *init_args;
+ sipClassTypeDef *ctd = (sipClassTypeDef *)td;
+ const char *pyname = sipPyNameOfContainer(&ctd->ctd_container, td);
+
+ /*
+ * Ask the handwritten pickle code for the tuple of
+ * arguments that will recreate the object.
+ */
+ init_args = ctd->ctd_pickle(sip_api_get_cpp_ptr((sipSimpleWrapper *)obj, NULL));
+
+ if (!PyTuple_Check(init_args))
+ {
+ PyErr_Format(PyExc_TypeError,
+ "%%PickleCode for type %s.%s did not return a tuple",
+ sipNameOfModule(em), pyname);
+
+ return NULL;
+ }
+
+ return Py_BuildValue("O(OsN)", type_unpickler,
+ em->em_nameobj, pyname, init_args);
+ }
+ }
+ }
+
+ /* We should never get here. */
+ PyErr_Format(PyExc_SystemError, "attempt to pickle unknown type '%s'",
+ Py_TYPE(obj)->tp_name);
+
+ return NULL;
+}
+
+
+/*
+ * The enum unpickler.
+ */
+static PyObject *unpickle_enum(PyObject *ignore, PyObject *args)
+{
+ PyObject *mname_obj, *evalue_obj;
+ const char *ename;
+ sipExportedModuleDef *em;
+ int i;
+
+ if (!PyArg_ParseTuple(args,
+#if PY_MAJOR_VERSION >= 3
+ "UsO:_unpickle_enum",
+#else
+ "SsO:_unpickle_enum",
+#endif
+ &mname_obj, &ename, &evalue_obj))
+ return NULL;
+
+ /* Get the module definition. */
+ if ((em = getModule(mname_obj)) == NULL)
+ return NULL;
+
+ /* Find the enum type object. */
+ for (i = 0; i < em->em_nrtypes; ++i)
+ {
+ sipTypeDef *td = em->em_types[i];
+
+ if (td != NULL && !sipTypeIsStub(td) && sipTypeIsEnum(td))
+ if (strcmp(sipPyNameOfEnum((sipEnumTypeDef *)td), ename) == 0)
+ return PyObject_CallFunctionObjArgs((PyObject *)sipTypeAsPyTypeObject(td), evalue_obj, NULL);
+ }
+
+ PyErr_Format(PyExc_SystemError, "unable to find to find enum: %s", ename);
+
+ return NULL;
+}
+
+
+/*
+ * The enum pickler.
+ */
+static PyObject *pickle_enum(PyObject *obj, PyObject *ignore)
+{
+ sipTypeDef *td = ((sipEnumTypeObject *)Py_TYPE(obj))->type;
+
+ return Py_BuildValue("O(Osi)", enum_unpickler, td->td_module->em_nameobj,
+ sipPyNameOfEnum((sipEnumTypeDef *)td),
+#if PY_MAJOR_VERSION >= 3
+ (int)PyLong_AS_LONG(obj)
+#else
+ (int)PyInt_AS_LONG(obj)
+#endif
+ );
+}
+
+
+/*
+ * Set the __reduce__method for a type.
+ */
+static int setReduce(PyTypeObject *type, PyMethodDef *pickler)
+{
+ static PyObject *rstr = NULL;
+ PyObject *descr;
+ int rc;
+
+ if (objectify("__reduce__", &rstr) < 0)
+ return -1;
+
+ /* Create the method descripter. */
+ if ((descr = PyDescr_NewMethod(type, pickler)) == NULL)
+ return -1;
+
+ /*
+ * Save the method. Note that we don't use PyObject_SetAttr() as we want
+ * to bypass any lazy attribute loading (which may not be safe yet).
+ */
+ rc = PyType_Type.tp_setattro((PyObject *)type, rstr, descr);
+
+ Py_DECREF(descr);
+
+ return rc;
+}
+
+
+/*
+ * Create an enum type object.
+ */
+static int createEnumType(sipExportedModuleDef *client, sipEnumTypeDef *etd,
+ PyObject *mod_dict)
+{
+ static PyObject *bases = NULL;
+ PyObject *name, *typedict, *args, *dict;
+ PyTypeObject *py_type;
+
+ etd->etd_base.td_module = client;
+
+ /* Get the dictionary into which the type will be placed. */
+ if (etd->etd_scope < 0)
+ dict = mod_dict;
+ else if ((dict = getScopeDict(client->em_types[etd->etd_scope], mod_dict, client)) == NULL)
+ goto reterr;
+
+ /* Create the base type tuple if it hasn't already been done. */
+ if (bases == NULL)
+ {
+#if PY_MAJOR_VERSION >= 3
+ bases = PyTuple_Pack(1, (PyObject *)&PyLong_Type);
+#elif PY_VERSION_HEX >= 0x02040000
+ bases = PyTuple_Pack(1, (PyObject *)&PyInt_Type);
+#else
+ bases = Py_BuildValue("(O)", &PyInt_Type);
+#endif
+
+ if (bases == NULL)
+ goto reterr;
+ }
+
+ /* Create an object corresponding to the type name. */
+#if PY_MAJOR_VERSION >= 3
+ name = PyUnicode_FromString(sipPyNameOfEnum(etd));
+#else
+ name = PyString_FromString(sipPyNameOfEnum(etd));
+#endif
+
+ if (name == NULL)
+ goto reterr;
+
+ /* Create the type dictionary. */
+ if ((typedict = createTypeDict(client->em_nameobj)) == NULL)
+ goto relname;
+
+ /* Create the type by calling the metatype. */
+#if PY_VERSION_HEX >= 0x02040000
+ args = PyTuple_Pack(3, name, bases, typedict);
+#else
+ args = Py_BuildValue("OOO", name, bases, typedict);
+#endif
+
+ Py_DECREF(typedict);
+
+ if (args == NULL)
+ goto relname;
+
+ /* Pass the type via the back door. */
+ currentType = &etd->etd_base;
+
+ py_type = (PyTypeObject *)PyObject_Call((PyObject *)&sipEnumType_Type, args, NULL);
+
+ Py_DECREF(args);
+
+ if (py_type == NULL)
+ goto relname;
+
+ /* Add the type to the "parent" dictionary. */
+ if (PyDict_SetItem(dict, name, (PyObject *)py_type) < 0)
+ {
+ Py_DECREF((PyObject *)py_type);
+ goto relname;
+ }
+
+ /* We can now release our remaining references. */
+ Py_DECREF(name);
+
+ return 0;
+
+ /* Unwind after an error. */
+
+relname:
+ Py_DECREF(name);
+
+reterr:
+ etd->etd_base.td_module = client;
+ return -1;
+}
+
+
+/*
+ * Create a type dictionary for dynamic type being created in the module with
+ * the specified name.
+ */
+static PyObject *createTypeDict(PyObject *mname)
+{
+ static PyObject *mstr = NULL;
+ PyObject *dict;
+
+ if (objectify("__module__", &mstr) < 0)
+ return NULL;
+
+ /* Create the dictionary. */
+ if ((dict = PyDict_New()) == NULL)
+ return NULL;
+
+ /* We need to set the module name as an attribute for dynamic types. */
+ if (PyDict_SetItem(dict, mstr, mname) < 0)
+ {
+ Py_DECREF(dict);
+ return NULL;
+ }
+
+ return dict;
+}
+
+
+/*
+ * Convert an ASCII string to a Python object if it hasn't already been done.
+ */
+static int objectify(const char *s, PyObject **objp)
+{
+ if (*objp == NULL)
+ {
+#if PY_MAJOR_VERSION >= 3
+ *objp = PyUnicode_FromString(s);
+#else
+ *objp = PyString_FromString(s);
+#endif
+
+ if (*objp == NULL)
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Add a set of static instances to a dictionary.
+ */
+static int addInstances(PyObject *dict, sipInstancesDef *id)
+{
+ if (id->id_type != NULL && addTypeInstances(dict, id->id_type) < 0)
+ return -1;
+
+ if (id->id_voidp != NULL && addVoidPtrInstances(dict,id->id_voidp) < 0)
+ return -1;
+
+ if (id->id_char != NULL && addCharInstances(dict,id->id_char) < 0)
+ return -1;
+
+ if (id->id_string != NULL && addStringInstances(dict,id->id_string) < 0)
+ return -1;
+
+ if (id->id_int != NULL && addIntInstances(dict, id->id_int) < 0)
+ return -1;
+
+ if (id->id_long != NULL && addLongInstances(dict,id->id_long) < 0)
+ return -1;
+
+ if (id->id_ulong != NULL && addUnsignedLongInstances(dict, id->id_ulong) < 0)
+ return -1;
+
+ if (id->id_llong != NULL && addLongLongInstances(dict, id->id_llong) < 0)
+ return -1;
+
+ if (id->id_ullong != NULL && addUnsignedLongLongInstances(dict, id->id_ullong) < 0)
+ return -1;
+
+ if (id->id_double != NULL && addDoubleInstances(dict,id->id_double) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+/*
+ * Get "self" from the argument tuple for a method called as
+ * Class.Method(self, ...) rather than self.Method(...).
+ */
+static int getSelfFromArgs(sipTypeDef *td, PyObject *args, int argnr,
+ sipSimpleWrapper **selfp)
+{
+ PyObject *self;
+
+ /* Get self from the argument tuple. */
+
+ if (argnr >= PyTuple_GET_SIZE(args))
+ return FALSE;
+
+ self = PyTuple_GET_ITEM(args, argnr);
+
+ if (!PyObject_TypeCheck(self, sipTypeAsPyTypeObject(td)))
+ return FALSE;
+
+ *selfp = (sipSimpleWrapper *)self;
+
+ return TRUE;
+}
+
+
+/*
+ * Populate a container's type dictionary.
+ */
+static int add_lazy_container_attrs(sipTypeDef *td, sipContainerDef *cod,
+ PyObject *dict)
+{
+ int i;
+ PyMethodDef *pmd;
+ sipEnumMemberDef *enm;
+ sipVariableDef *vd;
+
+ /* Do the methods. */
+ pmd = cod->cod_methods;
+
+ for (i = 0; i < cod->cod_nrmethods; ++i)
+ {
+ int rc;
+ PyObject *descr;
+
+ if ((descr = sipMethodDescr_New(pmd)) == NULL)
+ return -1;
+
+ rc = PyDict_SetItemString(dict, pmd->ml_name, descr);
+
+ Py_DECREF(descr);
+
+ if (rc < 0)
+ return -1;
+
+ ++pmd;
+ }
+
+ /* Do the enum members. */
+ enm = cod->cod_enummembers;
+
+ for (i = 0; i < cod->cod_nrenummembers; ++i)
+ {
+ int rc;
+ PyObject *val;
+
+ if ((val = createEnumMember(td, enm)) == NULL)
+ return -1;
+
+ rc = PyDict_SetItemString(dict, enm->em_name, val);
+
+ Py_DECREF(val);
+
+ if (rc < 0)
+ return -1;
+
+ ++enm;
+ }
+
+ /* Do the variables. */
+ vd = cod->cod_variables;
+
+ for (i = 0; i < cod->cod_nrvariables; ++i)
+ {
+ int rc;
+ PyObject *descr;
+
+ if ((descr = sipVariableDescr_New(vd, td, cod)) == NULL)
+ return -1;
+
+ rc = PyDict_SetItemString(dict, vd->vd_name, descr);
+
+ Py_DECREF(descr);
+
+ if (rc < 0)
+ return -1;
+
+ ++vd;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Populate a type dictionary with all lazy attributes if it hasn't already
+ * been done.
+ */
+static int add_lazy_attrs(sipTypeDef *td)
+{
+ sipWrapperType *wt = (sipWrapperType *)sipTypeAsPyTypeObject(td);
+ PyObject *dict;
+ sipAttrGetter *ag;
+
+ /* Handle the trivial case. */
+ if (wt->dict_complete)
+ return 0;
+
+ dict = ((PyTypeObject *)wt)->tp_dict;
+
+ if (sipTypeIsMapped(td))
+ {
+ if (add_lazy_container_attrs(td, &((sipMappedTypeDef *)td)->mtd_container, dict) < 0)
+ return -1;
+ }
+ else
+ {
+ sipClassTypeDef *nsx;
+
+ /* Search the possible linked list of namespace extenders. */
+ for (nsx = (sipClassTypeDef *)td; nsx != NULL; nsx = nsx->ctd_nsextender)
+ if (add_lazy_container_attrs((sipTypeDef *)nsx, &nsx->ctd_container, dict) < 0)
+ return -1;
+ }
+
+ /*
+ * Get any lazy attributes from registered getters. This must be done last
+ * to allow any existing attributes to be replaced.
+ */
+ for (ag = sipAttrGetters; ag != NULL; ag = ag->next)
+ if (ag->type == NULL || PyType_IsSubtype((PyTypeObject *)wt, ag->type))
+ if (ag->getter(td, dict) < 0)
+ return -1;
+
+ wt->dict_complete = TRUE;
+
+ return 0;
+}
+
+
+/*
+ * Populate the type dictionary and all its super-types.
+ */
+static int add_all_lazy_attrs(sipTypeDef *td)
+{
+ if (td == NULL)
+ return 0;
+
+ if (add_lazy_attrs(td) < 0)
+ return -1;
+
+ if (sipTypeIsClass(td))
+ {
+ sipClassTypeDef *ctd = (sipClassTypeDef *)td;
+ sipEncodedTypeDef *sup;
+
+ if ((sup = ctd->ctd_supers) != NULL)
+ do
+ {
+ sipTypeDef *sup_td = getGeneratedType(sup, td->td_module);
+
+ if (add_all_lazy_attrs(sup_td) < 0)
+ return -1;
+ }
+ while (!sup++->sc_flag);
+ }
+
+ return 0;
+}
+
+
+/*
+ * Return the generated type structure corresponding to the given Python type
+ * object.
+ */
+static const sipTypeDef *sip_api_type_from_py_type_object(PyTypeObject *py_type)
+{
+ if (PyObject_TypeCheck((PyObject *)py_type, &sipWrapperType_Type))
+ return ((sipWrapperType *)py_type)->type;
+
+ if (PyObject_TypeCheck((PyObject *)py_type, &sipEnumType_Type))
+ return ((sipEnumTypeObject *)py_type)->type;
+
+ return NULL;
+}
+
+
+/*
+ * Return the generated type structure corresponding to the scope of the given
+ * type.
+ */
+static const sipTypeDef *sip_api_type_scope(const sipTypeDef *td)
+{
+ if (sipTypeIsEnum(td))
+ {
+ const sipEnumTypeDef *etd = (const sipEnumTypeDef *)td;
+
+ if (etd->etd_scope >= 0)
+ return td->td_module->em_types[etd->etd_scope];
+ }
+ else
+ {
+ const sipContainerDef *cod;
+
+ if (sipTypeIsMapped(td))
+ cod = &((const sipMappedTypeDef *)td)->mtd_container;
+ else
+ cod = &((const sipClassTypeDef *)td)->ctd_container;
+
+ if (!cod->cod_scope.sc_flag)
+ return getGeneratedType(&cod->cod_scope, td->td_module);
+ }
+
+ return NULL;
+}
+
+
+/*
+ * Return TRUE if an object can be converted to a named enum.
+ */
+static int sip_api_can_convert_to_enum(PyObject *obj, const sipTypeDef *td)
+{
+ assert(sipTypeIsEnum(td));
+
+ /* If the object is an enum then it must be the right enum. */
+ if (PyObject_TypeCheck((PyObject *)Py_TYPE(obj), &sipEnumType_Type))
+ return (PyObject_TypeCheck(obj, sipTypeAsPyTypeObject(td)));
+
+#if PY_MAJOR_VERSION >= 3
+ return PyLong_Check(obj);
+#else
+ return PyInt_Check(obj);
+#endif
+}
+
+
+/*
+ * Create a Python object for an enum member.
+ */
+static PyObject *createEnumMember(sipTypeDef *td, sipEnumMemberDef *enm)
+{
+ if (enm->em_enum < 0)
+#if PY_MAJOR_VERSION >= 3
+ return PyLong_FromLong(enm->em_val);
+#else
+ return PyInt_FromLong(enm->em_val);
+#endif
+
+ return sip_api_convert_from_enum(enm->em_val,
+ td->td_module->em_types[enm->em_enum]);
+}
+
+
+/*
+ * Create a Python object for a member of a named enum.
+ */
+static PyObject *sip_api_convert_from_enum(int eval, const sipTypeDef *td)
+{
+ assert(sipTypeIsEnum(td));
+
+ return PyObject_CallFunction((PyObject *)sipTypeAsPyTypeObject(td), "(i)",
+ eval);
+}
+
+
+/*
+ * Register a getter for unknown attributes.
+ */
+static int sip_api_register_attribute_getter(const sipTypeDef *td,
+ sipAttrGetterFunc getter)
+{
+ sipAttrGetter *ag = sip_api_malloc(sizeof (sipAttrGetter));
+
+ if (ag == NULL)
+ return -1;
+
+ ag->type = sipTypeAsPyTypeObject(td);
+ ag->getter = getter;
+ ag->next = sipAttrGetters;
+
+ sipAttrGetters = ag;
+
+ return 0;
+}
+
+
+/*
+ * Report a function with invalid argument types.
+ */
+static void sip_api_no_function(PyObject *parseErr, const char *func,
+ const char *doc)
+{
+ sip_api_no_method(parseErr, NULL, func, doc);
+}
+
+
+/*
+ * Report a method/function/signal with invalid argument types.
+ */
+static void sip_api_no_method(PyObject *parseErr, const char *scope,
+ const char *method, const char *doc)
+{
+ const char *sep = ".";
+
+ if (scope == NULL)
+ scope = ++sep;
+
+ if (parseErr == NULL)
+ {
+ /*
+ * If we have got this far without trying a parse then there must be no
+ * overloads.
+ */
+ PyErr_Format(PyExc_TypeError, "%s%s%s() is a private method", scope,
+ sep, method);
+ }
+ else if (PyList_Check(parseErr))
+ {
+ PyObject *exc;
+
+ /* There is an entry for each overload that was tried. */
+ if (PyList_GET_SIZE(parseErr) == 1)
+ {
+ PyObject *detail = detail_FromFailure(
+ PyList_GET_ITEM(parseErr, 0));
+
+ if (detail != NULL)
+ {
+ if (doc != NULL)
+ {
+ PyObject *doc_obj = signature_FromDocstring(doc, 0);
+
+ if (doc_obj != NULL)
+ {
+#if PY_MAJOR_VERSION >= 3
+ exc = PyUnicode_FromFormat("%U: %U", doc_obj, detail);
+#else
+ exc = PyString_FromFormat("%s: %s",
+ PyString_AS_STRING(doc_obj),
+ PyString_AS_STRING(detail));
+#endif
+
+ Py_DECREF(doc_obj);
+ }
+ else
+ {
+ exc = NULL;
+ }
+ }
+ else
+ {
+#if PY_MAJOR_VERSION >= 3
+ exc = PyUnicode_FromFormat("%s%s%s(): %U", scope, sep,
+ method, detail);
+#else
+ exc = PyString_FromFormat("%s%s%s(): %s", scope, sep,
+ method, PyString_AS_STRING(detail));
+#endif
+ }
+
+ Py_DECREF(detail);
+ }
+ else
+ {
+ exc = NULL;
+ }
+ }
+ else
+ {
+ static const char *summary = "arguments did not match any overloaded call:";
+
+ SIP_SSIZE_T i;
+
+ if (doc != NULL)
+ {
+#if PY_MAJOR_VERSION >= 3
+ exc = PyUnicode_FromString(summary);
+#else
+ exc = PyString_FromString(summary);
+#endif
+ }
+ else
+ {
+#if PY_MAJOR_VERSION >= 3
+ exc = PyUnicode_FromFormat("%s%s%s(): %s", scope, sep, method,
+ summary);
+#else
+ exc = PyString_FromFormat("%s%s%s(): %s", scope, sep, method,
+ summary);
+#endif
+ }
+
+ for (i = 0; i < PyList_GET_SIZE(parseErr); ++i)
+ {
+ PyObject *failure;
+ PyObject *detail = detail_FromFailure(
+ PyList_GET_ITEM(parseErr, i));
+
+ if (detail != NULL)
+ {
+ if (doc != NULL)
+ {
+ PyObject *doc_obj = signature_FromDocstring(doc, i);
+
+ if (doc_obj != NULL)
+ {
+#if PY_MAJOR_VERSION >= 3
+ failure = PyUnicode_FromFormat("\n %U: %U",
+ doc_obj, detail);
+#else
+ failure = PyString_FromFormat("\n %s: %s",
+ PyString_AS_STRING(doc_obj),
+ PyString_AS_STRING(detail));
+#endif
+
+ Py_DECREF(doc_obj);
+ }
+ else
+ {
+ Py_XDECREF(exc);
+ exc = NULL;
+ break;
+ }
+ }
+ else
+ {
+#if PY_MAJOR_VERSION >= 3
+ failure = PyUnicode_FromFormat("\n overload %zd: %U",
+ i + 1, detail);
+#elif PY_VERSION_HEX >= 0x02050000
+ failure = PyString_FromFormat("\n overload %zd: %s",
+ i + 1, PyString_AS_STRING(detail));
+#else
+ failure = PyString_FromFormat("\n overload %d: %s",
+ i + 1, PyString_AS_STRING(detail));
+#endif
+ }
+
+ Py_DECREF(detail);
+
+#if PY_MAJOR_VERSION >= 3
+ PyUnicode_AppendAndDel(&exc, failure);
+#else
+ PyString_ConcatAndDel(&exc, failure);
+#endif
+ }
+ else
+ {
+ Py_XDECREF(exc);
+ exc = NULL;
+ break;
+ }
+ }
+ }
+
+ if (exc != NULL)
+ {
+ PyErr_SetObject(PyExc_TypeError, exc);
+ Py_DECREF(exc);
+ }
+ }
+ else
+ {
+ /*
+ * None is used as a marker to say that an exception has already been
+ * raised. This won't show which overload we were parsing but it
+ * doesn't really matter as it is a fundamental problem rather than a
+ * user error.
+ */
+ assert(parseErr == Py_None);
+ }
+
+ Py_XDECREF(parseErr);
+}
+
+
+/*
+ * Return a string/unicode object extracted from a particular line of a
+ * docstring.
+ */
+static PyObject *signature_FromDocstring(const char *doc, SIP_SSIZE_T line)
+{
+ const char *eol;
+ SIP_SSIZE_T size = 0;
+
+ /*
+ * Find the start of the line. If there is a non-default versioned
+ * overload that has been enabled then it won't have an entry in the
+ * docstring. This means that the returned signature may be incorrect.
+ */
+ while (line-- > 0)
+ {
+ const char *next = strchr(doc, '\n');
+
+ if (next == NULL)
+ break;
+
+ doc = next + 1;
+ }
+
+ /* Find the last closing parenthesis. */
+ for (eol = doc; *eol != '\n' && *eol != '\0'; ++eol)
+ if (*eol == ')')
+ size = eol - doc + 1;
+
+#if PY_MAJOR_VERSION >= 3
+ return PyUnicode_FromStringAndSize(doc, size);
+#else
+ return PyString_FromStringAndSize(doc, size);
+#endif
+}
+
+
+/*
+ * Return a string/unicode object that describes the given failure.
+ */
+static PyObject *detail_FromFailure(PyObject *failure_obj)
+{
+ sipParseFailure *failure;
+ PyObject *detail;
+
+#if defined(SIP_USE_PYCAPSULE)
+ failure = (sipParseFailure *)PyCapsule_GetPointer(failure_obj, NULL);
+#else
+ failure = (sipParseFailure *)PyCObject_AsVoidPtr(failure_obj);
+#endif
+
+ switch (failure->reason)
+ {
+ case Unbound:
+#if PY_MAJOR_VERSION >= 3
+ detail = PyUnicode_FromFormat(
+ "first argument of unbound method must have type '%s'",
+ failure->detail_str);
+#else
+ detail = PyString_FromFormat(
+ "first argument of unbound method must have type '%s'",
+ failure->detail_str);
+#endif
+ break;
+
+ case TooFew:
+#if PY_MAJOR_VERSION >= 3
+ detail = PyUnicode_FromString("not enough arguments");
+#else
+ detail = PyString_FromString("not enough arguments");
+#endif
+ break;
+
+ case TooMany:
+#if PY_MAJOR_VERSION >= 3
+ detail = PyUnicode_FromString("too many arguments");
+#else
+ detail = PyString_FromString("too many arguments");
+#endif
+ break;
+
+ case KeywordNotString:
+#if PY_MAJOR_VERSION >= 3
+ detail = PyUnicode_FromFormat(
+ "%S keyword argument name is not a string",
+ failure->detail_obj);
+#else
+ {
+ PyObject *str = PyObject_Str(failure->detail_obj);
+
+ if (str != NULL)
+ {
+ detail = PyString_FromFormat(
+ "%s keyword argument name is not a string",
+ PyString_AsString(str));
+
+ Py_DECREF(str);
+ }
+ else
+ {
+ detail = NULL;
+ }
+ }
+#endif
+ break;
+
+ case UnknownKeyword:
+#if PY_MAJOR_VERSION >= 3
+ detail = PyUnicode_FromFormat("'%U' is not a valid keyword argument",
+ failure->detail_obj);
+#else
+ detail = PyString_FromFormat("'%s' is not a valid keyword argument",
+ PyString_AS_STRING(failure->detail_obj));
+#endif
+ break;
+
+ case Duplicate:
+#if PY_MAJOR_VERSION >= 3
+ detail = PyUnicode_FromFormat(
+ "'%U' has already been given as a positional argument",
+ failure->detail_obj);
+#else
+ detail = PyString_FromFormat(
+ "'%s' has already been given as a positional argument",
+ PyString_AS_STRING(failure->detail_obj));
+#endif
+ break;
+
+ case WrongType:
+ if (failure->arg_nr >= 0)
+ {
+ detail = bad_type_str(failure->arg_nr, failure->detail_obj);
+ }
+ else
+ {
+#if PY_MAJOR_VERSION >= 3
+ detail = PyUnicode_FromFormat(
+ "keyword argument '%s' has unexpected type '%s'",
+ failure->arg_name, Py_TYPE(failure->detail_obj)->tp_name);
+#else
+ detail = PyString_FromFormat(
+ "keyword argument '%s' has unexpected type '%s'",
+ failure->arg_name, Py_TYPE(failure->detail_obj)->tp_name);
+#endif
+ }
+
+ break;
+
+ case Exception:
+ detail = failure->detail_obj;
+
+ if (detail)
+ {
+ Py_INCREF(detail);
+ break;
+ }
+
+ /* Drop through. */
+
+ default:
+#if PY_MAJOR_VERSION >= 3
+ detail = PyUnicode_FromString("unknown reason");
+#else
+ detail = PyString_FromString("unknown reason");
+#endif
+ }
+
+ return detail;
+}
+
+
+/*
+ * Report an abstract method called with an unbound self.
+ */
+static void sip_api_abstract_method(const char *classname, const char *method)
+{
+ PyErr_Format(PyExc_TypeError,
+ "%s.%s() is abstract and cannot be called as an unbound method",
+ classname, method);
+}
+
+
+/*
+ * Report a deprecated class or method.
+ */
+static int sip_api_deprecated(const char *classname, const char *method)
+{
+ char buf[100];
+
+ if (classname == NULL)
+ PyOS_snprintf(buf, sizeof (buf), "%s() is deprecated", method);
+ else if (method == NULL)
+ PyOS_snprintf(buf, sizeof (buf), "%s constructor is deprecated",
+ classname);
+ else
+ PyOS_snprintf(buf, sizeof (buf), "%s.%s() is deprecated", classname,
+ method);
+
+#if PY_VERSION_HEX >= 0x02050000
+ return PyErr_WarnEx(PyExc_DeprecationWarning, buf, 1);
+#else
+ return PyErr_Warn(PyExc_DeprecationWarning, buf);
+#endif
+}
+
+
+/*
+ * Report a bad operator argument. Only a small subset of operators need to
+ * be handled (those that don't return Py_NotImplemented).
+ */
+static void sip_api_bad_operator_arg(PyObject *self, PyObject *arg,
+ sipPySlotType st)
+{
+ const char *sn = NULL;
+
+ /* Try and get the text to match a Python exception. */
+
+ switch (st)
+ {
+ case concat_slot:
+ case iconcat_slot:
+ PyErr_Format(PyExc_TypeError,
+ "cannot concatenate '%s' and '%s' objects",
+ Py_TYPE(self)->tp_name, Py_TYPE(arg)->tp_name);
+ break;
+
+ case repeat_slot:
+ sn = "*";
+ break;
+
+ case irepeat_slot:
+ sn = "*=";
+ break;
+
+ default:
+ sn = "unknown";
+ }
+
+ if (sn != NULL)
+ PyErr_Format(PyExc_TypeError,
+ "unsupported operand type(s) for %s: '%s' and '%s'", sn,
+ Py_TYPE(self)->tp_name, Py_TYPE(arg)->tp_name);
+}
+
+
+/*
+ * Report a sequence length that does not match the length of a slice.
+ */
+static void sip_api_bad_length_for_slice(SIP_SSIZE_T seqlen,
+ SIP_SSIZE_T slicelen)
+{
+ PyErr_Format(PyExc_ValueError,
+#if PY_VERSION_HEX >= 0x02050000
+ "attempt to assign sequence of size %zd to slice of size %zd",
+#else
+ "attempt to assign sequence of size %d to slice of size %d",
+#endif
+ seqlen, slicelen);
+}
+
+
+/*
+ * Report a Python object that cannot be converted to a particular class.
+ */
+static void sip_api_bad_class(const char *classname)
+{
+ PyErr_Format(PyExc_TypeError,
+ "cannot convert Python object to an instance of %s", classname);
+}
+
+
+/*
+ * Report a Python member function with an unexpected return type.
+ */
+static void sip_api_bad_catcher_result(PyObject *method)
+{
+ PyObject *mname;
+
+ /*
+ * This is part of the public API so we make no assumptions about the
+ * method object.
+ */
+ if (!PyMethod_Check(method) ||
+ PyMethod_GET_FUNCTION(method) == NULL ||
+ !PyFunction_Check(PyMethod_GET_FUNCTION(method)) ||
+ PyMethod_GET_SELF(method) == NULL)
+ {
+ PyErr_Format(PyExc_TypeError,
+ "invalid argument to sipBadCatcherResult()");
+ return;
+ }
+
+ mname = ((PyFunctionObject *)PyMethod_GET_FUNCTION(method))->func_name;
+
+#if PY_MAJOR_VERSION >= 3
+ PyErr_Format(PyExc_TypeError, "invalid result type from %s.%U()",
+ Py_TYPE(PyMethod_GET_SELF(method))->tp_name, mname);
+#else
+ PyErr_Format(PyExc_TypeError, "invalid result type from %s.%s()",
+ Py_TYPE(PyMethod_GET_SELF(method))->tp_name,
+ PyString_AsString(mname));
+#endif
+}
+
+
+/*
+ * Transfer ownership of a class instance to Python from C/C++.
+ */
+static void sip_api_transfer_back(PyObject *self)
+{
+ if (self != NULL && PyObject_TypeCheck(self, (PyTypeObject *)&sipWrapper_Type))
+ {
+ sipSimpleWrapper *sw = (sipSimpleWrapper *)self;
+
+ if (sipCppHasRef(sw))
+ {
+ sipResetCppHasRef(sw);
+ Py_DECREF(sw);
+ }
+ else
+ removeFromParent((sipWrapper *)sw);
+
+ sipSetPyOwned(sw);
+ }
+}
+
+
+/*
+ * Break the association of a C++ owned Python object with any parent.
+ */
+static void sip_api_transfer_break(PyObject *self)
+{
+ if (self != NULL && PyObject_TypeCheck(self, (PyTypeObject *)&sipWrapper_Type))
+ {
+ sipSimpleWrapper *sw = (sipSimpleWrapper *)self;
+
+ if (sipCppHasRef(sw))
+ {
+ sipResetCppHasRef(sw);
+ Py_DECREF(sw);
+ }
+ else
+ removeFromParent((sipWrapper *)sw);
+ }
+}
+
+
+/*
+ * Transfer ownership of a class instance to C/C++ from Python.
+ */
+static void sip_api_transfer_to(PyObject *self, PyObject *owner)
+{
+ /*
+ * There is a legitimate case where we try to transfer a PyObject that
+ * may not be a SIP generated class. The virtual handler code calls
+ * this function to keep the C/C++ instance alive when it gets rid of
+ * the Python object returned by the Python method. A class may have
+ * handwritten code that converts a regular Python type - so we can't
+ * assume that we can simply cast to sipWrapper.
+ */
+ if (self != NULL &&
+ PyObject_TypeCheck(self, (PyTypeObject *)&sipWrapper_Type) &&
+ (owner == NULL ||
+ PyObject_TypeCheck(owner, (PyTypeObject *)&sipWrapper_Type)))
+ {
+ sipSimpleWrapper *sw = (sipSimpleWrapper *)self;
+
+ /*
+ * Keep the object alive while we do the transfer. If C++ has a
+ * reference then there is no need to increment it, just reset the flag
+ * and the following decrement will bring everything back to the way it
+ * should be.
+ */
+ if (sipCppHasRef(sw))
+ sipResetCppHasRef(sw);
+ else
+ {
+ Py_INCREF(sw);
+ removeFromParent((sipWrapper *)sw);
+ }
+
+ if (owner != NULL)
+ addToParent((sipWrapper *)sw, (sipWrapper *)owner);
+
+ Py_DECREF(sw);
+
+ sipResetPyOwned(sw);
+ }
+}
+
+
+/*
+ * Add a license to a dictionary.
+ */
+static int addLicense(PyObject *dict,sipLicenseDef *lc)
+{
+ int rc;
+ PyObject *ldict, *proxy, *o;
+
+ /* Convert the strings we use to objects if not already done. */
+
+ if (objectify("__license__", &licenseName) < 0)
+ return -1;
+
+ if (objectify("Licensee", &licenseeName) < 0)
+ return -1;
+
+ if (objectify("Type", &typeName) < 0)
+ return -1;
+
+ if (objectify("Timestamp", &timestampName) < 0)
+ return -1;
+
+ if (objectify("Signature", &signatureName) < 0)
+ return -1;
+
+ /* We use a dictionary to hold the license information. */
+ if ((ldict = PyDict_New()) == NULL)
+ return -1;
+
+ /* The license type is compulsory, the rest are optional. */
+ if (lc->lc_type == NULL)
+ goto deldict;
+
+#if PY_MAJOR_VERSION >= 3
+ o = PyUnicode_FromString(lc->lc_type);
+#else
+ o = PyString_FromString(lc->lc_type);
+#endif
+
+ if (o == NULL)
+ goto deldict;
+
+ rc = PyDict_SetItem(ldict,typeName,o);
+ Py_DECREF(o);
+
+ if (rc < 0)
+ goto deldict;
+
+ if (lc->lc_licensee != NULL)
+ {
+#if PY_MAJOR_VERSION >= 3
+ o = PyUnicode_FromString(lc->lc_licensee);
+#else
+ o = PyString_FromString(lc->lc_licensee);
+#endif
+
+ if (o == NULL)
+ goto deldict;
+
+ rc = PyDict_SetItem(ldict,licenseeName,o);
+ Py_DECREF(o);
+
+ if (rc < 0)
+ goto deldict;
+ }
+
+ if (lc->lc_timestamp != NULL)
+ {
+#if PY_MAJOR_VERSION >= 3
+ o = PyUnicode_FromString(lc->lc_timestamp);
+#else
+ o = PyString_FromString(lc->lc_timestamp);
+#endif
+
+ if (o == NULL)
+ goto deldict;
+
+ rc = PyDict_SetItem(ldict,timestampName,o);
+ Py_DECREF(o);
+
+ if (rc < 0)
+ goto deldict;
+ }
+
+ if (lc->lc_signature != NULL)
+ {
+#if PY_MAJOR_VERSION >= 3
+ o = PyUnicode_FromString(lc->lc_signature);
+#else
+ o = PyString_FromString(lc->lc_signature);
+#endif
+
+ if (o == NULL)
+ goto deldict;
+
+ rc = PyDict_SetItem(ldict,signatureName,o);
+ Py_DECREF(o);
+
+ if (rc < 0)
+ goto deldict;
+ }
+
+ /* Create a read-only proxy. */
+ if ((proxy = PyDictProxy_New(ldict)) == NULL)
+ goto deldict;
+
+ Py_DECREF(ldict);
+
+ rc = PyDict_SetItem(dict, licenseName, proxy);
+ Py_DECREF(proxy);
+
+ return rc;
+
+deldict:
+ Py_DECREF(ldict);
+
+ return -1;
+}
+
+
+/*
+ * Add the void pointer instances to a dictionary.
+ */
+static int addVoidPtrInstances(PyObject *dict,sipVoidPtrInstanceDef *vi)
+{
+ while (vi->vi_name != NULL)
+ {
+ int rc;
+ PyObject *w;
+
+ if ((w = sip_api_convert_from_void_ptr(vi->vi_val)) == NULL)
+ return -1;
+
+ rc = PyDict_SetItemString(dict,vi->vi_name,w);
+ Py_DECREF(w);
+
+ if (rc < 0)
+ return -1;
+
+ ++vi;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Add the char instances to a dictionary.
+ */
+static int addCharInstances(PyObject *dict, sipCharInstanceDef *ci)
+{
+ while (ci->ci_name != NULL)
+ {
+ int rc;
+ PyObject *w;
+
+ switch (ci->ci_encoding)
+ {
+ case 'A':
+ w = PyUnicode_DecodeASCII(&ci->ci_val, 1, NULL);
+ break;
+
+ case 'L':
+ w = PyUnicode_DecodeLatin1(&ci->ci_val, 1, NULL);
+ break;
+
+ case '8':
+#if PY_MAJOR_VERSION >= 3
+ w = PyUnicode_FromStringAndSize(&ci->ci_val, 1);
+#else
+ w = PyUnicode_DecodeUTF8(&ci->ci_val, 1, NULL);
+#endif
+ break;
+
+ default:
+ w = SIPBytes_FromStringAndSize(&ci->ci_val, 1);
+ }
+
+ if (w == NULL)
+ return -1;
+
+ rc = PyDict_SetItemString(dict, ci->ci_name, w);
+ Py_DECREF(w);
+
+ if (rc < 0)
+ return -1;
+
+ ++ci;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Add the string instances to a dictionary.
+ */
+static int addStringInstances(PyObject *dict, sipStringInstanceDef *si)
+{
+ while (si->si_name != NULL)
+ {
+ int rc;
+ PyObject *w;
+
+ switch (si->si_encoding)
+ {
+ case 'A':
+ w = PyUnicode_DecodeASCII(si->si_val, strlen(si->si_val), NULL);
+ break;
+
+ case 'L':
+ w = PyUnicode_DecodeLatin1(si->si_val, strlen(si->si_val), NULL);
+ break;
+
+ case '8':
+#if PY_MAJOR_VERSION >= 3
+ w = PyUnicode_FromString(si->si_val);
+#else
+ w = PyUnicode_DecodeUTF8(si->si_val, strlen(si->si_val), NULL);
+#endif
+ break;
+
+ default:
+ w = SIPBytes_FromString(si->si_val);
+ }
+
+ if (w == NULL)
+ return -1;
+
+ rc = PyDict_SetItemString(dict, si->si_name, w);
+ Py_DECREF(w);
+
+ if (rc < 0)
+ return -1;
+
+ ++si;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Add the int instances to a dictionary.
+ */
+static int addIntInstances(PyObject *dict, sipIntInstanceDef *ii)
+{
+ while (ii->ii_name != NULL)
+ {
+ int rc;
+ PyObject *w;
+
+#if PY_MAJOR_VERSION >= 3
+ w = PyLong_FromLong(ii->ii_val);
+#else
+ w = PyInt_FromLong(ii->ii_val);
+#endif
+
+ if (w == NULL)
+ return -1;
+
+ rc = PyDict_SetItemString(dict, ii->ii_name, w);
+ Py_DECREF(w);
+
+ if (rc < 0)
+ return -1;
+
+ ++ii;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Add the long instances to a dictionary.
+ */
+static int addLongInstances(PyObject *dict,sipLongInstanceDef *li)
+{
+ while (li->li_name != NULL)
+ {
+ int rc;
+ PyObject *w;
+
+ if ((w = PyLong_FromLong(li->li_val)) == NULL)
+ return -1;
+
+ rc = PyDict_SetItemString(dict,li->li_name,w);
+ Py_DECREF(w);
+
+ if (rc < 0)
+ return -1;
+
+ ++li;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Add the unsigned long instances to a dictionary.
+ */
+static int addUnsignedLongInstances(PyObject *dict, sipUnsignedLongInstanceDef *uli)
+{
+ while (uli->uli_name != NULL)
+ {
+ int rc;
+ PyObject *w;
+
+ if ((w = PyLong_FromUnsignedLong(uli->uli_val)) == NULL)
+ return -1;
+
+ rc = PyDict_SetItemString(dict, uli->uli_name, w);
+ Py_DECREF(w);
+
+ if (rc < 0)
+ return -1;
+
+ ++uli;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Add the long long instances to a dictionary.
+ */
+static int addLongLongInstances(PyObject *dict, sipLongLongInstanceDef *lli)
+{
+ while (lli->lli_name != NULL)
+ {
+ int rc;
+ PyObject *w;
+
+#if defined(HAVE_LONG_LONG)
+ if ((w = PyLong_FromLongLong(lli->lli_val)) == NULL)
+#else
+ if ((w = PyLong_FromLong(lli->lli_val)) == NULL)
+#endif
+ return -1;
+
+ rc = PyDict_SetItemString(dict, lli->lli_name, w);
+ Py_DECREF(w);
+
+ if (rc < 0)
+ return -1;
+
+ ++lli;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Add the unsigned long long instances to a dictionary.
+ */
+static int addUnsignedLongLongInstances(PyObject *dict, sipUnsignedLongLongInstanceDef *ulli)
+{
+ while (ulli->ulli_name != NULL)
+ {
+ int rc;
+ PyObject *w;
+
+#if defined(HAVE_LONG_LONG)
+ if ((w = PyLong_FromUnsignedLongLong(ulli->ulli_val)) == NULL)
+#else
+ if ((w = PyLong_FromUnsignedLong(ulli->ulli_val)) == NULL)
+#endif
+ return -1;
+
+ rc = PyDict_SetItemString(dict, ulli->ulli_name, w);
+ Py_DECREF(w);
+
+ if (rc < 0)
+ return -1;
+
+ ++ulli;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Add the double instances to a dictionary.
+ */
+static int addDoubleInstances(PyObject *dict,sipDoubleInstanceDef *di)
+{
+ while (di->di_name != NULL)
+ {
+ int rc;
+ PyObject *w;
+
+ if ((w = PyFloat_FromDouble(di->di_val)) == NULL)
+ return -1;
+
+ rc = PyDict_SetItemString(dict,di->di_name,w);
+ Py_DECREF(w);
+
+ if (rc < 0)
+ return -1;
+
+ ++di;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Wrap a set of type instances and add them to a dictionary.
+ */
+static int addTypeInstances(PyObject *dict, sipTypeInstanceDef *ti)
+{
+ while (ti->ti_name != NULL)
+ {
+ if (addSingleTypeInstance(dict, ti->ti_name, ti->ti_ptr, *ti->ti_type, ti->ti_flags) < 0)
+ return -1;
+
+ ++ti;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Wrap a single type instance and add it to a dictionary.
+ */
+static int addSingleTypeInstance(PyObject *dict, const char *name,
+ void *cppPtr, const sipTypeDef *td, int initflags)
+{
+ int rc;
+ PyObject *obj;
+
+ if (sipTypeIsClass(td))
+ {
+ obj = sipWrapSimpleInstance(cppPtr, td, NULL, initflags);
+ }
+ else if (sipTypeIsEnum(td))
+ {
+ obj = sip_api_convert_from_enum(*(int *)cppPtr, td);
+ }
+ else
+ {
+ assert(sipTypeIsMapped(td));
+
+ obj = ((const sipMappedTypeDef *)td)->mtd_cfrom(cppPtr, NULL);
+ }
+
+ if (obj == NULL)
+ return -1;
+
+ rc = PyDict_SetItemString(dict, name, obj);
+ Py_DECREF(obj);
+
+ return rc;
+}
+
+
+/*
+ * Convert a type instance and add it to a dictionary.
+ */
+static int sip_api_add_type_instance(PyObject *dict, const char *name,
+ void *cppPtr, const sipTypeDef *td)
+{
+ return addSingleTypeInstance(getDictFromObject(dict), name, cppPtr, td, 0);
+}
+
+
+/*
+ * Return the instance dictionary for an object if it is a wrapped type.
+ * Otherwise assume that it is a module dictionary.
+ */
+static PyObject *getDictFromObject(PyObject *obj)
+{
+ if (PyObject_TypeCheck(obj, (PyTypeObject *)&sipWrapperType_Type))
+ obj = ((PyTypeObject *)obj)->tp_dict;
+
+ return obj;
+}
+
+
+/*
+ * Return a Python reimplementation corresponding to a C/C++ virtual function,
+ * if any. If one was found then the Python lock is acquired.
+ */
+static PyObject *sip_api_is_py_method(sip_gilstate_t *gil, char *pymc,
+ sipSimpleWrapper *sipSelf, const char *cname, const char *mname)
+{
+ PyObject *mname_obj, *reimp, *mro, *cls;
+ SIP_SSIZE_T i;
+
+
+ /*
+ * This is the most common case (where there is no Python reimplementation)
+ * so we take a fast shortcut without acquiring the GIL.
+ */
+ if (*pymc != 0)
+ return NULL;
+
+ /* We might still have C++ going after the interpreter has gone. */
+ if (sipInterpreter == NULL)
+ return NULL;
+
+ /*
+ * It's possible that the Python object has been deleted but the underlying
+ * C++ instance is still working and trying to handle virtual functions.
+ * Alternatively, an instance has started handling virtual functions before
+ * its ctor has returned. In either case say there is no Python
+ * reimplementation.
+ */
+ if (sipSelf == NULL)
+ return NULL;
+
+ /* Get any reimplementation. */
+
+#ifdef WITH_THREAD
+ *gil = PyGILState_Ensure();
+#endif
+
+#if PY_MAJOR_VERSION >= 3
+ mname_obj = PyUnicode_FromString(mname);
+#else
+ mname_obj = PyString_FromString(mname);
+#endif
+
+ if (mname_obj == NULL)
+ {
+#ifdef WITH_THREAD
+ PyGILState_Release(*gil);
+#endif
+ return NULL;
+ }
+
+ /*
+ * We don't use PyObject_GetAttr() because that might find the generated
+ * C function before a reimplementation defined in a mixin (ie. later in
+ * the MRO).
+ */
+
+ if (sipSelf->dict != NULL)
+ {
+ /* Check the instance dictionary in case it has been monkey patched. */
+ if ((reimp = PyDict_GetItem(sipSelf->dict, mname_obj)) != NULL && PyCallable_Check(reimp))
+ {
+ Py_DECREF(mname_obj);
+
+ Py_INCREF(reimp);
+ return reimp;
+ }
+ }
+
+ cls = (PyObject *)Py_TYPE(sipSelf);
+ mro = ((PyTypeObject *)cls)->tp_mro;
+ assert(PyTuple_Check(mro));
+
+ reimp = NULL;
+
+ for (i = 0; i < PyTuple_GET_SIZE(mro); ++i)
+ {
+ PyObject *cls_dict;
+
+ cls = PyTuple_GET_ITEM(mro, i);
+
+#if PY_MAJOR_VERSION >= 3
+ cls_dict = ((PyTypeObject *)cls)->tp_dict;
+#else
+ // Allow for classic classes as mixins.
+ if (PyClass_Check(cls))
+ cls_dict = ((PyClassObject *)cls)->cl_dict;
+ else
+ cls_dict = ((PyTypeObject *)cls)->tp_dict;
+#endif
+
+ if (cls_dict != NULL && (reimp = PyDict_GetItem(cls_dict, mname_obj)) != NULL)
+ {
+ /*
+ * Check any reimplementation is Python code and is not the wrapped
+ * C++ method.
+ */
+ if (PyMethod_Check(reimp))
+ {
+ /* It's already a method but make sure it is bound. */
+ if (PyMethod_GET_SELF(reimp) != NULL)
+ {
+ Py_INCREF(reimp);
+ }
+ else
+ {
+#if PY_MAJOR_VERSION >= 3
+ reimp = PyMethod_New(PyMethod_GET_FUNCTION(reimp),
+ (PyObject *)sipSelf);
+#else
+ reimp = PyMethod_New(PyMethod_GET_FUNCTION(reimp),
+ (PyObject *)sipSelf, PyMethod_GET_CLASS(reimp));
+#endif
+ }
+
+ break;
+ }
+
+ if (PyFunction_Check(reimp))
+ {
+#if PY_MAJOR_VERSION >= 3
+ reimp = PyMethod_New(reimp, (PyObject *)sipSelf);
+#else
+ reimp = PyMethod_New(reimp, (PyObject *)sipSelf, cls);
+#endif
+
+ break;
+ }
+
+ reimp = NULL;
+ }
+ }
+
+ Py_DECREF(mname_obj);
+
+ if (reimp == NULL)
+ {
+ /* Use the fast track in future. */
+ *pymc = 1;
+
+ if (cname != NULL)
+ {
+ /* Note that this will only be raised once per method. */
+ PyErr_Format(PyExc_NotImplementedError,
+ "%s.%s() is abstract and must be overridden", cname,
+ mname);
+ PyErr_Print();
+ }
+
+#ifdef WITH_THREAD
+ PyGILState_Release(*gil);
+#endif
+ }
+
+ return reimp;
+}
+
+
+/*
+ * Convert a C/C++ pointer to the object that wraps it.
+ */
+static PyObject *sip_api_get_pyobject(void *cppPtr, const sipTypeDef *td)
+{
+ return (PyObject *)sipOMFindObject(&cppPyMap, cppPtr, td);
+}
+
+
+/*
+ * Return the C/C++ pointer from a wrapper without any checks.
+ */
+void *sipGetAddress(sipSimpleWrapper *sw)
+{
+ if (sipIsAccessFunc(sw))
+ return (*sw->u.afPtr)();
+
+ if (sipIsIndirect(sw))
+ return *((void **)sw->u.cppPtr);
+
+ return sw->u.cppPtr;
+}
+
+
+/*
+ * Get the C/C++ pointer for a complex object. Note that not casting the C++
+ * pointer is a bug. However this is only ever called by PyQt3 signal emitter
+ * code and PyQt doesn't contain anything that multiply inherits from QObject.
+ */
+static void *sip_api_get_complex_cpp_ptr(sipSimpleWrapper *sw)
+{
+ return getComplexCppPtr(sw, NULL);
+}
+
+
+/*
+ * Get the C/C++ pointer for a complex object and optionally cast it to the
+ * required type.
+ */
+static void *getComplexCppPtr(sipSimpleWrapper *sw, const sipTypeDef *td)
+{
+ if (!sipIsDerived(sw))
+ {
+ PyErr_SetString(PyExc_RuntimeError,
+ "no access to protected functions or signals for objects not created from Python");
+
+ return NULL;
+ }
+
+ return sip_api_get_cpp_ptr(sw, td);
+}
+
+
+/*
+ * Get the C/C++ pointer from a wrapper and optionally cast it to the required
+ * type.
+ */
+void *sip_api_get_cpp_ptr(sipSimpleWrapper *sw, const sipTypeDef *td)
+{
+ void *ptr = sipGetAddress(sw);
+
+ if (checkPointer(ptr) < 0)
+ return NULL;
+
+ if (td != NULL)
+ {
+ ptr = cast_cpp_ptr(ptr, Py_TYPE(sw), td);
+
+ if (ptr == NULL)
+ PyErr_Format(PyExc_TypeError, "could not convert '%s' to '%s'",
+ Py_TYPE(sw)->tp_name,
+ sipPyNameOfContainer(&((const sipClassTypeDef *)td)->ctd_container, td));
+ }
+
+ return ptr;
+}
+
+
+/*
+ * Cast a C/C++ pointer from a source type to a destination type.
+ */
+static void *cast_cpp_ptr(void *ptr, PyTypeObject *src_type,
+ const sipTypeDef *dst_type)
+{
+ sipCastFunc cast = ((const sipClassTypeDef *)((sipWrapperType *)src_type)->type)->ctd_cast;
+
+ /* C structures don't have cast functions. */
+ if (cast != NULL)
+ ptr = (*cast)(ptr, dst_type);
+
+ return ptr;
+}
+
+
+/*
+ * Check that a pointer is non-NULL.
+ */
+static int checkPointer(void *ptr)
+{
+ if (ptr == NULL)
+ {
+ PyErr_SetString(PyExc_RuntimeError,
+ "underlying C/C++ object has been deleted");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Keep an extra reference to an object.
+ */
+static void sip_api_keep_reference(PyObject *self, int key, PyObject *obj)
+{
+ PyObject *dict, *key_obj;
+
+ /*
+ * If there isn't a "self" to keep the extra reference for later garbage
+ * collection then just take a reference and let it leak. This could
+ * happen, for example, if virtuals were still being called while Python
+ * was shutting down.
+ */
+ if (self == NULL)
+ {
+ Py_XINCREF(obj);
+ return;
+ }
+
+ /* Create the extra references dictionary if needed. */
+ if ((dict = ((sipSimpleWrapper *)self)->extra_refs) == NULL)
+ {
+ if ((dict = PyDict_New()) == NULL)
+ return;
+
+ ((sipSimpleWrapper *)self)->extra_refs = dict;
+ }
+
+#if PY_MAJOR_VERSION >= 3
+ key_obj = PyLong_FromLong(key);
+#else
+ key_obj = PyInt_FromLong(key);
+#endif
+
+ if (key_obj != NULL)
+ {
+ /* This can happen if the argument was optional. */
+ if (obj == NULL)
+ obj = Py_None;
+
+ PyDict_SetItem(dict, key_obj, obj);
+ Py_DECREF(key_obj);
+ }
+}
+
+
+/*
+ * Check to see if a Python object can be converted to a type.
+ */
+static int sip_api_can_convert_to_type(PyObject *pyObj, const sipTypeDef *td,
+ int flags)
+{
+ int ok;
+
+ assert(sipTypeIsClass(td) || sipTypeIsMapped(td));
+
+ /* None is handled outside the type checkers. */
+ if (pyObj == Py_None)
+ {
+ /* If the type explicitly handles None then ignore the flags. */
+ if (sipTypeAllowNone(td))
+ ok = TRUE;
+ else
+ ok = ((flags & SIP_NOT_NONE) == 0);
+ }
+ else
+ {
+ sipConvertToFunc cto;
+
+ if (sipTypeIsClass(td))
+ {
+ cto = ((const sipClassTypeDef *)td)->ctd_cto;
+
+ if (cto == NULL || (flags & SIP_NO_CONVERTORS) != 0)
+ ok = PyObject_TypeCheck(pyObj, sipTypeAsPyTypeObject(td));
+ else
+ ok = cto(pyObj, NULL, NULL, NULL);
+ }
+ else
+ {
+ cto = ((const sipMappedTypeDef *)td)->mtd_cto;
+ ok = cto(pyObj, NULL, NULL, NULL);
+ }
+ }
+
+ return ok;
+}
+
+
+/*
+ * Convert a Python object to a C/C++ pointer, assuming a previous call to
+ * sip_api_can_convert_to_type() has been successful. Allow ownership to be
+ * transferred and any type convertors to be disabled.
+ */
+static void *sip_api_convert_to_type(PyObject *pyObj, const sipTypeDef *td,
+ PyObject *transferObj, int flags, int *statep, int *iserrp)
+{
+ void *cpp = NULL;
+ int state = 0;
+
+ assert(sipTypeIsClass(td) || sipTypeIsMapped(td));
+
+ /* Don't convert if there has already been an error. */
+ if (!*iserrp)
+ {
+ /* Do the conversion. */
+ if (pyObj == Py_None && !sipTypeAllowNone(td))
+ cpp = NULL;
+ else
+ {
+ sipConvertToFunc cto;
+
+ if (sipTypeIsClass(td))
+ {
+ cto = ((const sipClassTypeDef *)td)->ctd_cto;
+
+ if (cto == NULL || (flags & SIP_NO_CONVERTORS) != 0)
+ {
+ if ((cpp = sip_api_get_cpp_ptr((sipSimpleWrapper *)pyObj, td)) == NULL)
+ *iserrp = TRUE;
+ else if (transferObj != NULL)
+ {
+ if (transferObj == Py_None)
+ sip_api_transfer_back(pyObj);
+ else
+ sip_api_transfer_to(pyObj, transferObj);
+ }
+ }
+ else
+ {
+ state = cto(pyObj, &cpp, iserrp, transferObj);
+ }
+ }
+ else
+ {
+ cto = ((const sipMappedTypeDef *)td)->mtd_cto;
+ state = cto(pyObj, &cpp, iserrp, transferObj);
+ }
+ }
+ }
+
+ if (statep != NULL)
+ *statep = state;
+
+ return cpp;
+}
+
+
+/*
+ * Convert a Python object to a C/C++ pointer and raise an exception if it
+ * can't be done.
+ */
+static void *sip_api_force_convert_to_type(PyObject *pyObj,
+ const sipTypeDef *td, PyObject *transferObj, int flags, int *statep,
+ int *iserrp)
+{
+ /* Don't even try if there has already been an error. */
+ if (*iserrp)
+ return NULL;
+
+ /* See if the object's type can be converted. */
+ if (!sip_api_can_convert_to_type(pyObj, td, flags))
+ {
+ if (sipTypeIsMapped(td))
+ PyErr_Format(PyExc_TypeError,
+ "%s cannot be converted to a C/C++ %s in this context",
+ Py_TYPE(pyObj)->tp_name, sipTypeName(td));
+ else
+ PyErr_Format(PyExc_TypeError,
+ "%s cannot be converted to %s.%s in this context",
+ Py_TYPE(pyObj)->tp_name, sipNameOfModule(td->td_module),
+ sipPyNameOfContainer(&((const sipClassTypeDef *)td)->ctd_container, td));
+
+ if (statep != NULL)
+ *statep = 0;
+
+ *iserrp = TRUE;
+ return NULL;
+ }
+
+ /* Do the conversion. */
+ return sip_api_convert_to_type(pyObj, td, transferObj, flags, statep,
+ iserrp);
+}
+
+
+/*
+ * Release a possibly temporary C/C++ instance created by a type convertor.
+ */
+static void sip_api_release_type(void *cpp, const sipTypeDef *td, int state)
+{
+ /* See if there is something to release. */
+ if (state & SIP_TEMPORARY)
+ release(cpp, td, state);
+}
+
+
+/*
+ * Release an instance.
+ */
+static void release(void *addr, const sipTypeDef *td, int state)
+{
+ sipReleaseFunc rel;
+
+ if (sipTypeIsClass(td))
+ {
+ rel = ((const sipClassTypeDef *)td)->ctd_release;
+
+ /*
+ * If there is no release function then it must be a C structure and we
+ * can just free it.
+ */
+ if (rel == NULL)
+ sip_api_free(addr);
+ }
+ else if (sipTypeIsMapped(td))
+ rel = ((const sipMappedTypeDef *)td)->mtd_release;
+ else
+ rel = NULL;
+
+ if (rel != NULL)
+ rel(addr, state);
+}
+
+
+/*
+ * Convert a C/C++ instance to a Python instance.
+ */
+PyObject *sip_api_convert_from_type(void *cpp, const sipTypeDef *td,
+ PyObject *transferObj)
+{
+ PyObject *py;
+
+ assert(sipTypeIsClass(td) || sipTypeIsMapped(td));
+
+ /* Handle None. */
+ if (cpp == NULL)
+ {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ if (sipTypeIsMapped(td))
+ return ((const sipMappedTypeDef *)td)->mtd_cfrom(cpp, transferObj);
+
+ /* Apply any sub-class convertor. */
+ if (sipTypeHasSCC(td))
+ td = convertSubClass(td, &cpp);
+
+ /* See if we have already wrapped it. */
+ if ((py = sip_api_get_pyobject(cpp, td)) != NULL)
+ Py_INCREF(py);
+ else if ((py = sipWrapSimpleInstance(cpp, td, NULL, SIP_SHARE_MAP)) == NULL)
+ return NULL;
+
+ /* Handle any ownership transfer. */
+ if (transferObj != NULL)
+ {
+ if (transferObj == Py_None)
+ sip_api_transfer_back(py);
+ else
+ sip_api_transfer_to(py, transferObj);
+ }
+
+ return py;
+}
+
+
+/*
+ * Convert a new C/C++ instance to a Python instance.
+ */
+static PyObject *sip_api_convert_from_new_type(void *cpp, const sipTypeDef *td,
+ PyObject *transferObj)
+{
+ sipWrapper *owner;
+
+ /* Handle None. */
+ if (cpp == NULL)
+ {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ if (sipTypeIsMapped(td))
+ {
+ PyObject *res = ((const sipMappedTypeDef *)td)->mtd_cfrom(cpp,
+ transferObj);
+
+ if (res != NULL)
+ {
+ /*
+ * We no longer need the C/C++ instance so we release it (unless
+ * its ownership is transferred). This means this call is
+ * semantically equivalent to the case where the type is a wrapped
+ * class.
+ */
+ if (transferObj == NULL || transferObj == Py_None)
+ release(cpp, td, 0);
+ }
+
+ return res;
+ }
+
+ assert(sipTypeIsClass(td));
+
+ /* Apply any sub-class convertor. */
+ if (sipTypeHasSCC(td))
+ td = convertSubClass(td, &cpp);
+
+ /* Handle any ownership transfer. */
+ if (transferObj == NULL || transferObj == Py_None)
+ owner = NULL;
+ else
+ owner = (sipWrapper *)transferObj;
+
+ return sipWrapSimpleInstance(cpp, td, owner, (owner == NULL ? SIP_PY_OWNED : 0));
+}
+
+
+/*
+ * Implement the normal transfer policy for the result of %ConvertToTypeCode,
+ * ie. it is temporary unless it is being transferred from Python.
+ */
+int sip_api_get_state(PyObject *transferObj)
+{
+ return (transferObj == NULL || transferObj == Py_None) ? SIP_TEMPORARY : 0;
+}
+
+
+/*
+ * This is set by sip_api_find_type() before calling bsearch() on the types
+ * table for the module. This is a hack that works around the problem of
+ * unresolved externally defined types.
+ */
+static sipExportedModuleDef *module_searched;
+
+
+/*
+ * The bsearch() helper function for searching the types table.
+ */
+static int compareTypeDef(const void *key, const void *el)
+{
+ const char *s1 = (const char *)key;
+ const char *s2 = NULL;
+ const sipTypeDef *td;
+ char ch1, ch2;
+
+ /* Allow for unresolved externally defined types. */
+ td = *(const sipTypeDef **)el;
+
+ if (td != NULL)
+ s2 = sipTypeName(td);
+ else
+ {
+ sipExternalTypeDef *etd = module_searched->em_external;
+
+ assert(etd != NULL);
+
+ /* Find which external type it is. */
+ while (etd->et_nr >= 0)
+ {
+ const sipTypeDef **tdp = &module_searched->em_types[etd->et_nr];
+
+ if (tdp == (const sipTypeDef **)el)
+ {
+ s2 = etd->et_name;
+ break;
+ }
+
+ ++etd;
+ }
+
+ assert(s2 != NULL);
+ }
+
+ /*
+ * Compare while ignoring spaces so that we don't impose a rigorous naming
+ * standard. This only really affects template-based mapped types.
+ */
+ do
+ {
+ while ((ch1 = *s1++) == ' ')
+ ;
+
+ while ((ch2 = *s2++) == ' ')
+ ;
+
+ /* We might be looking for a pointer or a reference. */
+ if ((ch1 == '*' || ch1 == '&' || ch1 == '\0') && ch2 == '\0')
+ return 0;
+ }
+ while (ch1 == ch2);
+
+ return (ch1 < ch2 ? -1 : 1);
+}
+
+
+/*
+ * Return the type structure for a particular type.
+ */
+static const sipTypeDef *sip_api_find_type(const char *type)
+{
+ sipExportedModuleDef *em;
+
+ for (em = moduleList; em != NULL; em = em->em_next)
+ {
+ sipTypeDef **tdp;
+
+ /* The backdoor to the comparison helper. */
+ module_searched = em;
+
+ tdp = (sipTypeDef **)bsearch((const void *)type,
+ (const void *)em->em_types, em->em_nrtypes,
+ sizeof (sipTypeDef *), compareTypeDef);
+
+ if (tdp != NULL)
+ {
+ /*
+ * Note that this will be NULL for unresolved externally defined
+ * types.
+ */
+ return *tdp;
+ }
+ }
+
+ return NULL;
+}
+
+
+/*
+ * Return the mapped type structure for a particular mapped type. This is
+ * deprecated.
+ */
+static const sipMappedType *sip_api_find_mapped_type(const char *type)
+{
+ const sipTypeDef *td = sip_api_find_type(type);
+
+ if (td != NULL && sipTypeIsMapped(td))
+ return (const sipMappedType *)td;
+
+ return NULL;
+}
+
+
+/*
+ * Return the type structure for a particular class. This is deprecated.
+ */
+static sipWrapperType *sip_api_find_class(const char *type)
+{
+ const sipTypeDef *td = sip_api_find_type(type);
+
+ if (td != NULL && sipTypeIsClass(td))
+ return (sipWrapperType *)sipTypeAsPyTypeObject(td);
+
+ return NULL;
+}
+
+
+/*
+ * Return the type structure for a particular named enum. This is deprecated.
+ */
+static PyTypeObject *sip_api_find_named_enum(const char *type)
+{
+ const sipTypeDef *td = sip_api_find_type(type);
+
+ if (td != NULL && sipTypeIsEnum(td))
+ return sipTypeAsPyTypeObject(td);
+
+ return NULL;
+}
+
+
+/*
+ * Save the components of a Python method.
+ */
+void sipSaveMethod(sipPyMethod *pm, PyObject *meth)
+{
+ pm->mfunc = PyMethod_GET_FUNCTION(meth);
+ pm->mself = PyMethod_GET_SELF(meth);
+#if PY_MAJOR_VERSION < 3
+ pm->mclass = PyMethod_GET_CLASS(meth);
+#endif
+}
+
+
+/*
+ * Call a hook.
+ */
+static void sip_api_call_hook(const char *hookname)
+{
+ PyObject *dictofmods, *mod, *dict, *hook, *res;
+
+ /* Get the dictionary of modules. */
+ if ((dictofmods = PyImport_GetModuleDict()) == NULL)
+ return;
+
+ /* Get the __builtin__ module. */
+ if ((mod = PyDict_GetItemString(dictofmods, "__builtin__")) == NULL)
+ return;
+
+ /* Get it's dictionary. */
+ if ((dict = PyModule_GetDict(mod)) == NULL)
+ return;
+
+ /* Get the function hook. */
+ if ((hook = PyDict_GetItemString(dict, hookname)) == NULL)
+ return;
+
+ /* Call the hook and discard any result. */
+ res = PyObject_CallObject(hook, NULL);
+
+ Py_XDECREF(res);
+}
+
+
+/*
+ * Call any sub-class convertors for a given type returning a pointer to the
+ * sub-type object, and possibly modifying the C++ address (in the case of
+ * multiple inheritence).
+ */
+static const sipTypeDef *convertSubClass(const sipTypeDef *td, void **cppPtr)
+{
+ PyTypeObject *py_type = sipTypeAsPyTypeObject(td);
+ sipExportedModuleDef *em;
+
+ if (*cppPtr == NULL)
+ return NULL;
+
+ /*
+ * Note that this code depends on the fact that a module appears in the
+ * list of modules before any module it imports, ie. sub-class convertors
+ * will be invoked for more specific types first.
+ */
+ for (em = moduleList; em != NULL; em = em->em_next)
+ {
+ sipSubClassConvertorDef *scc;
+
+ if ((scc = em->em_convertors) == NULL)
+ continue;
+
+ while (scc->scc_convertor != NULL)
+ {
+ /*
+ * The base type is the "root" class that may have a number of
+ * convertors each handling a "branch" of the derived tree of
+ * classes. The "root" normally implements the base function that
+ * provides the RTTI used by the convertors and is re-implemented
+ * by derived classes. We therefore see if the target type is a
+ * sub-class of the root, ie. see if the convertor might be able to
+ * convert the target type to something more specific.
+ */
+ if (PyType_IsSubtype(py_type, sipTypeAsPyTypeObject(scc->scc_basetype)))
+ {
+ void *ptr;
+ const sipTypeDef *subtype;
+
+ ptr = cast_cpp_ptr(*cppPtr, py_type, scc->scc_basetype);
+ subtype = (*scc->scc_convertor)(&ptr);
+
+ /*
+ * We are only interested in types that are not super-classes
+ * of the target. This happens either because it is in an
+ * earlier convertor than the one that handles the type or it
+ * is in a later convertor that handles a different branch of
+ * the hierarchy. Either way, the ordering of the modules
+ * ensures that there will be no more than one and that it will
+ * be the right one.
+ */
+ if (subtype != NULL && !PyType_IsSubtype(py_type, sipTypeAsPyTypeObject(subtype)))
+ {
+ *cppPtr = ptr;
+ return subtype;
+ }
+ }
+
+ ++scc;
+ }
+ }
+
+ /*
+ * We haven't found the exact type, so return the most specific type that
+ * it must be. This can happen legitimately if the wrapped library is
+ * returning an internal class that is down-cast to a more generic class.
+ * Also we want this function to be safe when a class doesn't have any
+ * convertors.
+ */
+ return td;
+}
+
+
+/*
+ * The bsearch() helper function for searching a sorted string map table.
+ */
+static int compareStringMapEntry(const void *key,const void *el)
+{
+ return strcmp((const char *)key,((const sipStringTypeClassMap *)el)->typeString);
+}
+
+
+/*
+ * A convenience function for %ConvertToSubClassCode for types represented as a
+ * string. Returns the Python class object or NULL if the type wasn't
+ * recognised. This is deprecated.
+ */
+static sipWrapperType *sip_api_map_string_to_class(const char *typeString,
+ const sipStringTypeClassMap *map, int maplen)
+{
+ sipStringTypeClassMap *me;
+
+ me = (sipStringTypeClassMap *)bsearch((const void *)typeString,
+ (const void *)map,maplen,
+ sizeof (sipStringTypeClassMap),
+ compareStringMapEntry);
+
+ return ((me != NULL) ? *me->pyType : NULL);
+}
+
+
+/*
+ * The bsearch() helper function for searching a sorted integer map table.
+ */
+static int compareIntMapEntry(const void *keyp,const void *el)
+{
+ int key = *(int *)keyp;
+
+ if (key > ((const sipIntTypeClassMap *)el)->typeInt)
+ return 1;
+
+ if (key < ((const sipIntTypeClassMap *)el)->typeInt)
+ return -1;
+
+ return 0;
+}
+
+
+/*
+ * A convenience function for %ConvertToSubClassCode for types represented as
+ * an integer. Returns the Python class object or NULL if the type wasn't
+ * recognised. This is deprecated.
+ */
+static sipWrapperType *sip_api_map_int_to_class(int typeInt,
+ const sipIntTypeClassMap *map, int maplen)
+{
+ sipIntTypeClassMap *me;
+
+ me = (sipIntTypeClassMap *)bsearch((const void *)&typeInt,
+ (const void *)map,maplen,
+ sizeof (sipIntTypeClassMap),
+ compareIntMapEntry);
+
+ return ((me != NULL) ? *me->pyType : NULL);
+}
+
+
+/*
+ * Raise an unknown exception. Make no assumptions about the GIL.
+ */
+static void sip_api_raise_unknown_exception(void)
+{
+ static PyObject *mobj = NULL;
+
+ SIP_BLOCK_THREADS
+
+ objectify("unknown", &mobj);
+
+ PyErr_SetObject(PyExc_Exception, mobj);
+
+ SIP_UNBLOCK_THREADS
+}
+
+
+/*
+ * Raise an exception implemented as a type. Make no assumptions about the
+ * GIL.
+ */
+static void sip_api_raise_type_exception(const sipTypeDef *td, void *ptr)
+{
+ PyObject *self;
+
+ assert(sipTypeIsClass(td));
+
+ SIP_BLOCK_THREADS
+
+ self = sipWrapSimpleInstance(ptr, td, NULL, SIP_PY_OWNED);
+
+ PyErr_SetObject((PyObject *)sipTypeAsPyTypeObject(td), self);
+
+ Py_XDECREF(self);
+
+ SIP_UNBLOCK_THREADS
+}
+
+
+/*
+ * Return the module of an encoded type.
+ */
+static sipExportedModuleDef *getTypeModule(const sipEncodedTypeDef *enc,
+ sipExportedModuleDef *em)
+{
+ if (enc->sc_module != 255)
+ em = em->em_imports[enc->sc_module].im_module;
+
+ return em;
+}
+
+
+/*
+ * Return the generated type structure of an encoded type.
+ */
+static sipTypeDef *getGeneratedType(const sipEncodedTypeDef *enc,
+ sipExportedModuleDef *em)
+{
+ return getTypeModule(enc, em)->em_types[enc->sc_type];
+}
+
+
+/*
+ * Find a particular slot function for a type.
+ */
+static void *findSlot(PyObject *self, sipPySlotType st)
+{
+ void *slot;
+ PyTypeObject *py_type = Py_TYPE(self);
+
+ /* See if it is a wrapper. */
+ if (PyObject_TypeCheck((PyObject *)py_type, &sipWrapperType_Type))
+ {
+ sipClassTypeDef *ctd;
+
+ ctd = (sipClassTypeDef *)((sipWrapperType *)(py_type))->type;
+
+ if (ctd->ctd_pyslots != NULL)
+ slot = findSlotInType(ctd->ctd_pyslots, st);
+ else
+ slot = NULL;
+
+ if (slot == NULL)
+ {
+ sipEncodedTypeDef *sup;
+
+ /* Search any super-types. */
+ if ((sup = ctd->ctd_supers) != NULL)
+ {
+ sipClassTypeDef *sup_ctd;
+
+ do
+ {
+ sup_ctd = (sipClassTypeDef *)getGeneratedType(sup,
+ ctd->ctd_base.td_module);
+
+ if (sup_ctd->ctd_pyslots != NULL)
+ slot = findSlotInType(sup_ctd->ctd_pyslots, st);
+ }
+ while (slot == NULL && !sup++->sc_flag);
+ }
+ }
+ }
+ else
+ {
+ sipEnumTypeDef *etd;
+
+ /* If it is not a wrapper then it must be an enum. */
+ assert(PyObject_TypeCheck((PyObject *)py_type, &sipEnumType_Type));
+
+ etd = (sipEnumTypeDef *)((sipEnumTypeObject *)(py_type))->type;
+
+ assert(etd->etd_pyslots != NULL);
+
+ slot = findSlotInType(etd->etd_pyslots, st);
+ }
+
+ return slot;
+}
+
+
+/*
+ * Find a particular slot function in a particular type.
+ */
+static void *findSlotInType(sipPySlotDef *psd, sipPySlotType st)
+{
+ while (psd->psd_func != NULL)
+ {
+ if (psd->psd_type == st)
+ return psd->psd_func;
+
+ ++psd;
+ }
+
+ return NULL;
+}
+
+
+/*
+ * Return the C/C++ address and the generated class structure for a wrapper.
+ */
+static void *getPtrTypeDef(sipSimpleWrapper *self, const sipClassTypeDef **ctd)
+{
+ *ctd = (const sipClassTypeDef *)((sipWrapperType *)Py_TYPE(self))->type;
+
+ return (sipNotInMap(self) ? NULL : self->u.cppPtr);
+}
+
+
+/*
+ * Handle an objobjargproc slot.
+ */
+static int objobjargprocSlot(PyObject *self, PyObject *arg1, PyObject *arg2,
+ sipPySlotType st)
+{
+ int (*f)(PyObject *, PyObject *);
+ int res;
+
+ f = (int (*)(PyObject *, PyObject *))findSlot(self, st);
+
+ if (f != NULL)
+ {
+ PyObject *args;
+
+ /*
+ * Slot handlers require a single PyObject *. The second argument is
+ * optional.
+ */
+ if (arg2 == NULL)
+ {
+ args = arg1;
+ Py_INCREF(args);
+ }
+ else
+ {
+#if PY_VERSION_HEX >= 0x02040000
+ args = PyTuple_Pack(2, arg1, arg2);
+#else
+ args = Py_BuildValue("(OO)", arg1, arg2);
+#endif
+
+ if (args == NULL)
+ return -1;
+ }
+
+ res = f(self, args);
+ Py_DECREF(args);
+ }
+ else
+ {
+ PyErr_SetNone(PyExc_NotImplementedError);
+ res = -1;
+ }
+
+ return res;
+}
+
+
+/*
+ * Handle an ssizeobjargproc slot.
+ */
+static int ssizeobjargprocSlot(PyObject *self, SIP_SSIZE_T arg1,
+ PyObject *arg2, sipPySlotType st)
+{
+ int (*f)(PyObject *, PyObject *);
+ int res;
+
+ f = (int (*)(PyObject *, PyObject *))findSlot(self, st);
+
+ if (f != NULL)
+ {
+ PyObject *args;
+
+ /*
+ * Slot handlers require a single PyObject *. The second argument is
+ * optional.
+ */
+ if (arg2 == NULL)
+#if PY_MAJOR_VERSION >= 3
+ args = PyLong_FromSsize_t(arg1);
+#elif PY_VERSION_HEX >= 0x02050000
+ args = PyInt_FromSsize_t(arg1);
+#else
+ args = PyInt_FromLong(arg1);
+#endif
+ else
+#if PY_VERSION_HEX >= 0x02050000
+ args = Py_BuildValue("(nO)", arg1, arg2);
+#else
+ args = Py_BuildValue("(iO)", arg1, arg2);
+#endif
+
+ if (args == NULL)
+ return -1;
+
+ res = f(self, args);
+ Py_DECREF(args);
+ }
+ else
+ {
+ PyErr_SetNone(PyExc_NotImplementedError);
+ res = -1;
+ }
+
+ return res;
+}
+
+
+/*
+ * The metatype alloc slot.
+ */
+static PyObject *sipWrapperType_alloc(PyTypeObject *self, SIP_SSIZE_T nitems)
+{
+ PyObject *o;
+
+ /* Call the standard super-metatype alloc. */
+ if ((o = PyType_Type.tp_alloc(self, nitems)) == NULL)
+ return NULL;
+
+ /*
+ * Consume any extra type specific information and use it to initialise the
+ * slots. This only happens for directly wrapped classes (and not
+ * programmer written sub-classes). This must be done in the alloc
+ * function because it is the only place we can break out of the default
+ * new() function before PyType_Ready() is called.
+ */
+ if (currentType != NULL)
+ {
+ ((sipWrapperType *)o)->type = currentType;
+
+ if (sipTypeIsClass(currentType))
+ {
+ const char *docstring = ((sipClassTypeDef *)currentType)->ctd_docstring;
+
+ /*
+ * Skip the marker that identifies the docstring as being
+ * automatically generated.
+ */
+ if (docstring != NULL && *docstring == AUTO_DOCSTRING)
+ ++docstring;
+
+ ((PyTypeObject *)o)->tp_doc = docstring;
+
+ addClassSlots((sipWrapperType *)o, (sipClassTypeDef *)currentType);
+ }
+
+ currentType = NULL;
+ }
+
+ return o;
+}
+
+
+/*
+ * The metatype init slot.
+ */
+static int sipWrapperType_init(sipWrapperType *self, PyObject *args,
+ PyObject *kwds)
+{
+ /* Call the standard super-metatype init. */
+ if (PyType_Type.tp_init((PyObject *)self, args, kwds) < 0)
+ return -1;
+
+ /*
+ * If we don't yet have any extra type specific information (because we are
+ * a programmer defined sub-class) then get it from the (first) super-type.
+ */
+ if (self->type == NULL)
+ {
+ PyTypeObject *base = ((PyTypeObject *)self)->tp_base;
+
+ /*
+ * We allow the class to use this as a meta-type without being derived
+ * from a class that uses it. This allows mixin classes that need
+ * their own meta-type to work so long as their meta-type is derived
+ * from this meta-type. This condition is indicated by the pointer to
+ * the generated type structure being NULL.
+ */
+ if (base != NULL && PyObject_TypeCheck((PyObject *)base, (PyTypeObject *)&sipWrapperType_Type))
+ self->type = ((sipWrapperType *)base)->type;
+ }
+ else
+ {
+ /*
+ * We must be a generated type so remember the type object in the
+ * generated type structure.
+ */
+ assert(self->type->u.td_py_type == NULL);
+
+ self->type->u.td_py_type = (PyTypeObject *)self;
+ }
+
+ return 0;
+}
+
+
+/*
+ * The metatype getattro slot.
+ */
+static PyObject *sipWrapperType_getattro(PyObject *self, PyObject *name)
+{
+ if (add_all_lazy_attrs(((sipWrapperType *)self)->type) < 0)
+ return NULL;
+
+ return PyType_Type.tp_getattro(self, name);
+}
+
+
+/*
+ * The metatype setattro slot.
+ */
+static int sipWrapperType_setattro(PyObject *self, PyObject *name,
+ PyObject *value)
+{
+ if (add_all_lazy_attrs(((sipWrapperType *)self)->type) < 0)
+ return -1;
+
+ return PyType_Type.tp_setattro(self, name, value);
+}
+
+
+/*
+ * The instance new slot.
+ */
+static PyObject *sipSimpleWrapper_new(sipWrapperType *wt, PyObject *args,
+ PyObject *kwds)
+{
+ static PyObject *noargs = NULL;
+ sipTypeDef *td = wt->type;
+ sipContainerDef *cod;
+
+ /* Check the base types are not being used directly. */
+ if (wt == &sipSimpleWrapper_Type || wt == &sipWrapper_Type)
+ {
+ PyErr_Format(PyExc_TypeError,
+ "the %s type cannot be instantiated or sub-classed",
+ ((PyTypeObject *)wt)->tp_name);
+
+ return NULL;
+ }
+
+ if (sipTypeIsMapped(td))
+ cod = &((sipMappedTypeDef *)td)->mtd_container;
+ else
+ cod = &((sipClassTypeDef *)td)->ctd_container;
+
+ /* We need an empty tuple for an empty argument list. */
+ if (noargs == NULL)
+ {
+ noargs = PyTuple_New(0);
+
+ if (noargs == NULL)
+ return NULL;
+ }
+
+ /* See if it is a mapped type. */
+ if (sipTypeIsMapped(td))
+ {
+ PyErr_Format(PyExc_TypeError,
+ "%s.%s represents a mapped type and cannot be instantiated",
+ sipNameOfModule(td->td_module),
+ sipPyNameOfContainer(cod, td));
+
+ return NULL;
+ }
+
+ /* See if it is a namespace. */
+ if (sipTypeIsNamespace(td))
+ {
+ PyErr_Format(PyExc_TypeError,
+ "%s.%s represents a C++ namespace and cannot be instantiated",
+ sipNameOfModule(td->td_module),
+ sipPyNameOfContainer(cod, td));
+
+ return NULL;
+ }
+
+ /*
+ * See if the object is being created explicitly rather than being wrapped.
+ */
+ if (sipGetPending(NULL, NULL) == NULL)
+ {
+ /*
+ * See if it cannot be instantiated or sub-classed from Python, eg.
+ * it's an opaque class. Some restrictions might be overcome with
+ * better SIP support.
+ */
+ if (((sipClassTypeDef *)td)->ctd_init == NULL)
+ {
+ PyErr_Format(PyExc_TypeError,
+ "%s.%s cannot be instantiated or sub-classed",
+ sipNameOfModule(td->td_module),
+ sipPyNameOfContainer(cod, td));
+
+ return NULL;
+ }
+
+ /* See if it is an abstract type. */
+ if (sipTypeIsAbstract(td) && sipIsExactWrappedType(wt))
+ {
+ PyErr_Format(PyExc_TypeError,
+ "%s.%s represents a C++ abstract class and cannot be instantiated",
+ sipNameOfModule(td->td_module),
+ sipPyNameOfContainer(cod, td));
+
+ return NULL;
+ }
+ }
+
+ /* Call the standard super-type new. */
+ return PyBaseObject_Type.tp_new((PyTypeObject *)wt, noargs, NULL);
+}
+
+
+/*
+ * The instance init slot.
+ */
+static int sipSimpleWrapper_init(sipSimpleWrapper *self, PyObject *args,
+ PyObject *kwds)
+{
+ void *sipNew;
+ int sipFlags;
+ sipWrapper *owner;
+ sipWrapperType *wt = (sipWrapperType *)Py_TYPE(self);
+ sipTypeDef *td = wt->type;
+ sipClassTypeDef *ctd = (sipClassTypeDef *)td;
+ PyObject *unused, **unused_p;
+
+ static int got_kw_handler = FALSE;
+ static int (*kw_handler)(PyObject *, void *, PyObject *);
+
+ /*
+ * Get any keyword handler if necessary. In SIP v5 this will be
+ * generalised and not PyQt specific.
+ */
+ if (!got_kw_handler)
+ {
+ kw_handler = sip_api_import_symbol("pyqt_kw_handler");
+ got_kw_handler = TRUE;
+ }
+
+ /*
+ * We are interested in unused keyword arguments if we are creating a
+ * QObject and we have a handler.
+ */
+ unused_p = (kw_handler != NULL && isQObject((PyObject *)self)) ? &unused : NULL;
+ unused = NULL;
+
+ /* Check there is no existing C++ instance waiting to be wrapped. */
+ if ((sipNew = sipGetPending(&owner, &sipFlags)) == NULL)
+ {
+ PyObject *parseErr = NULL;
+
+ /* Call the C++ ctor. */
+ owner = NULL;
+
+ sipNew = ctd->ctd_init(self, args, kwds, unused_p, (PyObject **)&owner,
+ &parseErr);
+
+ if (sipNew != NULL)
+ {
+ sipFlags = SIP_DERIVED_CLASS;
+ }
+ else if (parseErr == NULL)
+ {
+ /*
+ * The C++ ctor must have raised an exception which has been
+ * translated to a Python exception.
+ */
+ return -1;
+ }
+ else
+ {
+ sipInitExtenderDef *ie = wt->iextend;
+
+ assert(parseErr != NULL);
+
+ /*
+ * If we have not found an appropriate overload then try any
+ * extenders.
+ */
+ while (PyList_Check(parseErr) && ie != NULL)
+ {
+ sipNew = ie->ie_extender(self, args, kwds, unused_p,
+ (PyObject **)&owner, &parseErr);
+
+ if (sipNew != NULL)
+ break;
+
+ ie = ie->ie_next;
+ }
+
+ if (sipNew == NULL)
+ {
+ const char *docstring = ctd->ctd_docstring;
+
+ /*
+ * Use the docstring for errors if it was automatically
+ * generated.
+ */
+ if (docstring != NULL)
+ {
+ if (*docstring == AUTO_DOCSTRING)
+ ++docstring;
+ else
+ docstring = NULL;
+ }
+
+ sip_api_no_function(parseErr,
+ sipPyNameOfContainer(&ctd->ctd_container, td),
+ docstring);
+
+ return -1;
+ }
+
+ sipFlags = 0;
+ }
+
+ if (owner == NULL)
+ sipFlags |= SIP_PY_OWNED;
+ else if ((PyObject *)owner == Py_None)
+ {
+ /* This is the hack that means that C++ owns the new instance. */
+ sipFlags |= SIP_CPP_HAS_REF;
+ Py_INCREF(self);
+ owner = NULL;
+ }
+ }
+
+ /*
+ * If there is an owner then we assume that the wrapper supports the
+ * concept.
+ */
+ if (owner != NULL)
+ {
+ assert(PyObject_TypeCheck((PyObject *)self, (PyTypeObject *)&sipWrapper_Type));
+ addToParent((sipWrapper *)self, (sipWrapper *)owner);
+ }
+
+ self->u.cppPtr = sipNew;
+ self->flags = sipFlags;
+
+ if (!sipNotInMap(self))
+ sipOMAddObject(&cppPyMap, self);
+
+ /* If we have unused keyword arguments then we know how to handle them. */
+ if (unused != NULL)
+ {
+ int rc;
+
+ rc = kw_handler((PyObject *)self, sipNew, unused);
+ Py_DECREF(unused);
+
+ if (rc < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/*
+ * The instance traverse slot.
+ */
+static int sipSimpleWrapper_traverse(sipSimpleWrapper *self, visitproc visit,
+ void *arg)
+{
+ int vret;
+ void *ptr;
+ const sipClassTypeDef *ctd;
+
+ /* Call the nearest handwritten traverse code in the class hierachy. */
+ if ((ptr = getPtrTypeDef(self, &ctd)) != NULL)
+ {
+ const sipClassTypeDef *sup_ctd = ctd;
+
+ if (ctd->ctd_traverse == NULL)
+ {
+ sipEncodedTypeDef *sup;
+
+ if ((sup = ctd->ctd_supers) != NULL)
+ do
+ sup_ctd = (sipClassTypeDef *)getGeneratedType(sup, ctd->ctd_base.td_module);
+ while (sup_ctd->ctd_traverse == NULL && !sup++->sc_flag);
+ }
+
+ if (sup_ctd->ctd_traverse != NULL)
+ if ((vret = sup_ctd->ctd_traverse(ptr, visit, arg)) != 0)
+ return vret;
+ }
+
+ if (self->dict != NULL)
+ if ((vret = visit(self->dict, arg)) != 0)
+ return vret;
+
+ if (self->extra_refs != NULL)
+ if ((vret = visit(self->extra_refs, arg)) != 0)
+ return vret;
+
+ if (self->user != NULL)
+ if ((vret = visit(self->user, arg)) != 0)
+ return vret;
+
+ return 0;
+}
+
+
+/*
+ * The instance clear slot.
+ */
+static int sipSimpleWrapper_clear(sipSimpleWrapper *self)
+{
+ int vret = 0;
+ void *ptr;
+ const sipClassTypeDef *ctd;
+ PyObject *tmp;
+
+ /* Call the nearest handwritten clear code in the class hierachy. */
+ if ((ptr = getPtrTypeDef(self, &ctd)) != NULL)
+ {
+ const sipClassTypeDef *sup_ctd = ctd;
+
+ if (ctd->ctd_clear == NULL)
+ {
+ sipEncodedTypeDef *sup;
+
+ if ((sup = ctd->ctd_supers) != NULL)
+ do
+ sup_ctd = (sipClassTypeDef *)getGeneratedType(sup, ctd->ctd_base.td_module);
+ while (sup_ctd->ctd_clear == NULL && !sup++->sc_flag);
+ }
+
+ if (sup_ctd->ctd_clear != NULL)
+ vret = sup_ctd->ctd_clear(ptr);
+ }
+
+ /* Remove the instance dictionary. */
+ tmp = self->dict;
+ self->dict = NULL;
+ Py_XDECREF(tmp);
+
+ /* Remove any extra references dictionary. */
+ tmp = self->extra_refs;
+ self->extra_refs = NULL;
+ Py_XDECREF(tmp);
+
+ /* Remove any user object. */
+ tmp = self->user;
+ self->user = NULL;
+ Py_XDECREF(tmp);
+
+ return vret;
+}
+
+
+#if PY_MAJOR_VERSION >= 3
+/*
+ * The instance get buffer slot for Python v3.
+ */
+static int sipSimpleWrapper_getbuffer(sipSimpleWrapper *self, Py_buffer *buf,
+ int flags)
+{
+ void *ptr;
+ const sipClassTypeDef *ctd;
+
+ if ((ptr = getPtrTypeDef(self, &ctd)) == NULL)
+ return -1;
+
+ return ctd->ctd_getbuffer((PyObject *)self, ptr, buf, flags);
+}
+#endif
+
+
+#if PY_MAJOR_VERSION >= 3
+/*
+ * The instance release buffer slot for Python v3.
+ */
+static void sipSimpleWrapper_releasebuffer(sipSimpleWrapper *self,
+ Py_buffer *buf)
+{
+ void *ptr;
+ const sipClassTypeDef *ctd;
+
+ if ((ptr = getPtrTypeDef(self, &ctd)) == NULL)
+ return -1;
+
+ return ctd->ctd_releasebuffer((PyObject *)self, ptr, buf);
+}
+#endif
+
+
+#if PY_MAJOR_VERSION < 3
+/*
+ * The instance read buffer slot for Python v2.
+ */
+static SIP_SSIZE_T sipSimpleWrapper_getreadbuffer(sipSimpleWrapper *self,
+ SIP_SSIZE_T segment, void **ptrptr)
+{
+ void *ptr;
+ const sipClassTypeDef *ctd;
+
+ if ((ptr = getPtrTypeDef(self, &ctd)) == NULL)
+ return -1;
+
+ return ctd->ctd_readbuffer((PyObject *)self, ptr, segment, ptrptr);
+}
+#endif
+
+
+#if PY_MAJOR_VERSION < 3
+/*
+ * The instance write buffer slot for Python v2.
+ */
+static SIP_SSIZE_T sipSimpleWrapper_getwritebuffer(sipSimpleWrapper *self,
+ SIP_SSIZE_T segment, void **ptrptr)
+{
+ void *ptr;
+ const sipClassTypeDef *ctd;
+
+ if ((ptr = getPtrTypeDef(self, &ctd)) == NULL)
+ return -1;
+
+ return ctd->ctd_writebuffer((PyObject *)self, ptr, segment, ptrptr);
+}
+#endif
+
+
+#if PY_MAJOR_VERSION < 3
+/*
+ * The instance segment count slot for Python v2.
+ */
+static SIP_SSIZE_T sipSimpleWrapper_getsegcount(sipSimpleWrapper *self,
+ SIP_SSIZE_T *lenp)
+{
+ void *ptr;
+ const sipClassTypeDef *ctd;
+
+ if ((ptr = getPtrTypeDef(self, &ctd)) == NULL)
+ return 0;
+
+ return ctd->ctd_segcount((PyObject *)self, ptr, lenp);
+}
+#endif
+
+
+#if PY_MAJOR_VERSION < 3
+/*
+ * The instance char buffer slot for Python v2.
+ */
+static SIP_SSIZE_T sipSimpleWrapper_getcharbuffer(sipSimpleWrapper *self,
+ SIP_SSIZE_T segment, void **ptrptr)
+{
+ void *ptr;
+ const sipClassTypeDef *ctd;
+
+ if ((ptr = getPtrTypeDef(self, &ctd)) == NULL)
+ return -1;
+
+ return ctd->ctd_charbuffer((PyObject *)self, ptr, segment, ptrptr);
+}
+#endif
+
+
+/*
+ * The instance dealloc slot.
+ */
+static void sipSimpleWrapper_dealloc(sipSimpleWrapper *self)
+{
+ forgetObject(self);
+
+ /*
+ * Now that the C++ object no longer exists we can tidy up the Python
+ * object. We used to do this first but that meant lambda slots were
+ * removed too soon (if they were connected to QObject.destroyed()).
+ */
+ sipSimpleWrapper_clear(self);
+
+ /* Call the standard super-type dealloc. */
+ PyBaseObject_Type.tp_dealloc((PyObject *)self);
+}
+
+
+/*
+ * The type call slot. Note that keyword arguments aren't supported.
+ */
+static PyObject *slot_call(PyObject *self,PyObject *args,PyObject *kw)
+{
+ PyObject *(*f)(PyObject *,PyObject *);
+
+ f = (PyObject *(*)(PyObject *,PyObject *))findSlot(self, call_slot);
+
+ assert(f != NULL);
+
+ return f(self,args);
+}
+
+
+/*
+ * The sequence type item slot.
+ */
+static PyObject *slot_sq_item(PyObject *self, SIP_SSIZE_T n)
+{
+ PyObject *(*f)(PyObject *,PyObject *);
+ PyObject *arg, *res;
+
+#if PY_MAJOR_VERSION >= 3
+ arg = PyLong_FromSsize_t(n);
+#elif PY_VERSION_HEX >= 0x02050000
+ arg = PyInt_FromSsize_t(n);
+#else
+ arg = PyInt_FromLong(n);
+#endif
+
+ if (arg == NULL)
+ return NULL;
+
+ f = (PyObject *(*)(PyObject *,PyObject *))findSlot(self, getitem_slot);
+
+ assert(f != NULL);
+
+ res = f(self,arg);
+
+ Py_DECREF(arg);
+
+ return res;
+}
+
+
+/*
+ * The mapping type assign subscript slot.
+ */
+static int slot_mp_ass_subscript(PyObject *self, PyObject *key,
+ PyObject *value)
+{
+ return objobjargprocSlot(self, key, value,
+ (value != NULL ? setitem_slot : delitem_slot));
+}
+
+
+/*
+ * The sequence type assign item slot.
+ */
+static int slot_sq_ass_item(PyObject *self, SIP_SSIZE_T i, PyObject *o)
+{
+ return ssizeobjargprocSlot(self, i, o,
+ (o != NULL ? setitem_slot : delitem_slot));
+}
+
+
+/*
+ * The type rich compare slot.
+ */
+static PyObject *slot_richcompare(PyObject *self, PyObject *arg, int op)
+{
+ PyObject *(*f)(PyObject *,PyObject *);
+ sipPySlotType st;
+
+ /* Convert the operation to a slot type. */
+ switch (op)
+ {
+ case Py_LT:
+ st = lt_slot;
+ break;
+
+ case Py_LE:
+ st = le_slot;
+ break;
+
+ case Py_EQ:
+ st = eq_slot;
+ break;
+
+ case Py_NE:
+ st = ne_slot;
+ break;
+
+ case Py_GT:
+ st = gt_slot;
+ break;
+
+ case Py_GE:
+ st = ge_slot;
+ break;
+ }
+
+ /* It might not exist if not all the above have been implemented. */
+ if ((f = (PyObject *(*)(PyObject *,PyObject *))findSlot(self, st)) == NULL)
+ {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
+ return f(self, arg);
+}
+
+
+/*
+ * The instance getattro slot.
+ */
+static PyObject *sipSimpleWrapper_getattro(PyObject *self, PyObject *name)
+{
+ if (add_all_lazy_attrs(((sipWrapperType *)Py_TYPE(self))->type) < 0)
+ return NULL;
+
+ return PyObject_GenericGetAttr(self, name);
+}
+
+
+/*
+ * The instance setattro slot.
+ */
+static int sipSimpleWrapper_setattro(PyObject *self, PyObject *name,
+ PyObject *value)
+{
+ if (add_all_lazy_attrs(((sipWrapperType *)Py_TYPE(self))->type) < 0)
+ return -1;
+
+ return PyObject_GenericSetAttr(self, name, value);
+}
+
+
+/*
+ * The __dict__ getter.
+ */
+static PyObject *sipSimpleWrapper_get_dict(PyObject *self, void *closure)
+{
+ sipSimpleWrapper *sw = (sipSimpleWrapper *)self;
+
+ /* Create the dictionary if needed. */
+ if (sw->dict == NULL)
+ {
+ sw->dict = PyDict_New();
+
+ if (sw->dict == NULL)
+ return NULL;
+ }
+
+ Py_INCREF(sw->dict);
+ return sw->dict;
+}
+
+
+/*
+ * The __dict__ setter.
+ */
+static int sipSimpleWrapper_set_dict(PyObject *self, PyObject *value,
+ void *closure)
+{
+ sipSimpleWrapper *sw = (sipSimpleWrapper *)self;
+
+ /* Check that any new value really is a dictionary. */
+ if (value != NULL && !PyDict_Check(value))
+ {
+ PyErr_Format(PyExc_TypeError,
+ "__dict__ must be set to a dictionary, not a '%s'",
+ Py_TYPE(value)->tp_name);
+ return -1;
+ }
+
+ Py_XDECREF(sw->dict);
+
+ Py_XINCREF(value);
+ sw->dict = value;
+
+ return 0;
+}
+
+
+/*
+ * The table of getters and setters.
+ */
+static PyGetSetDef sipSimpleWrapper_getset[] = {
+ {(char *)"__dict__", sipSimpleWrapper_get_dict, sipSimpleWrapper_set_dict,
+ NULL, NULL},
+ {NULL, NULL, NULL, NULL, NULL}
+};
+
+
+/*
+ * The type data structure. Note that we pretend to be a mapping object and a
+ * sequence object at the same time. Python will choose one over another,
+ * depending on the context, but we implement as much as we can and don't make
+ * assumptions about which Python will choose.
+ */
+sipWrapperType sipSimpleWrapper_Type = {
+#if !defined(STACKLESS)
+ {
+#endif
+ {
+ PyVarObject_HEAD_INIT(&sipWrapperType_Type, 0)
+ "sip.simplewrapper", /* tp_name */
+ sizeof (sipSimpleWrapper), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)sipSimpleWrapper_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved (Python v3), tp_compare (Python v2) */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ sipSimpleWrapper_getattro, /* tp_getattro */
+ sipSimpleWrapper_setattro, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */
+ 0, /* tp_doc */
+ (traverseproc)sipSimpleWrapper_traverse, /* tp_traverse */
+ (inquiry)sipSimpleWrapper_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ sipSimpleWrapper_getset, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ offsetof(sipSimpleWrapper, dict), /* tp_dictoffset */
+ (initproc)sipSimpleWrapper_init, /* tp_init */
+ 0, /* tp_alloc */
+ (newfunc)sipSimpleWrapper_new, /* tp_new */
+ 0, /* tp_free */
+ },
+#if !defined(STACKLESS)
+ },
+#endif
+ 0,
+ 0
+};
+
+
+/*
+ * The wrapper clear slot.
+ */
+static int sipWrapper_clear(sipWrapper *self)
+{
+ int vret;
+ sipSimpleWrapper *sw = (sipSimpleWrapper *)self;
+
+ vret = sipSimpleWrapper_clear(sw);
+
+ /* Remove any slots connected via a proxy. */
+ if (sipQtSupport != NULL && sipPossibleProxy(sw))
+ {
+ void *tx = sipGetAddress(sw);
+
+ if (tx != NULL)
+ {
+ sipSlot *slot;
+ void *context = NULL;
+
+ while ((slot = sipQtSupport->qt_find_sipslot(tx, &context)) != NULL)
+ {
+ sip_api_clear_any_slot_reference(slot);
+
+ if (context == NULL)
+ break;
+ }
+ }
+ }
+
+ /* Detach children (which will be owned by C/C++). */
+ while ((sw = (sipSimpleWrapper *)self->first_child) != NULL)
+ {
+ /*
+ * Although this object is being garbage collected it doesn't follow
+ * that it's children should be. So we make sure that the child stays
+ * alive and remember we have done so.
+ */
+ Py_INCREF(sw);
+ sipSetCppHasRef(sw);
+
+ removeFromParent(self->first_child);
+ }
+
+ return vret;
+}
+
+
+/*
+ * The wrapper dealloc slot.
+ */
+static void sipWrapper_dealloc(sipWrapper *self)
+{
+ /*
+ * We can't simply call the super-type because things have to be done in a
+ * certain order. The first thing is to get rid of the wrapped instance.
+ */
+ forgetObject((sipSimpleWrapper *)self);
+
+ sipWrapper_clear(self);
+
+ /* Skip the super-type's dealloc. */
+ PyBaseObject_Type.tp_dealloc((PyObject *)self);
+}
+
+
+/*
+ * The wrapper traverse slot.
+ */
+static int sipWrapper_traverse(sipWrapper *self, visitproc visit, void *arg)
+{
+ int vret;
+ sipSimpleWrapper *sw = (sipSimpleWrapper *)self;
+ sipWrapper *w;
+
+ if ((vret = sipSimpleWrapper_traverse(sw, visit, arg)) != 0)
+ return vret;
+
+ /* This should be handwritten code in PyQt. */
+ if (sipQtSupport != NULL)
+ {
+ void *tx = sipGetAddress(sw);
+
+ if (tx != NULL)
+ {
+ sipSlot *slot;
+ void *context = NULL;
+
+ while ((slot = sipQtSupport->qt_find_sipslot(tx, &context)) != NULL)
+ {
+ if ((vret = sip_api_visit_slot(slot, visit, arg)) != 0)
+ return vret;
+
+ if (context == NULL)
+ break;
+ }
+ }
+ }
+
+ for (w = self->first_child; w != NULL; w = w->sibling_next)
+ {
+ /*
+ * We don't traverse if the wrapper is a child of itself. We do this
+ * so that wrapped objects returned by virtual methods with the
+ * /Factory/ don't have those objects collected. This then means that
+ * plugins implemented in Python have a chance of working.
+ */
+ if (w != self)
+ if ((vret = visit((PyObject *)w, arg)) != 0)
+ return vret;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Add the slots for a class type and all its super-types.
+ */
+static void addClassSlots(sipWrapperType *wt, sipClassTypeDef *ctd)
+{
+ /* Add the buffer interface. */
+#if PY_MAJOR_VERSION >= 3
+ if (ctd->ctd_getbuffer != NULL)
+ wt->super.as_buffer.bf_getbuffer = (getbufferproc)sipSimpleWrapper_getbuffer;
+
+ if (ctd->ctd_releasebuffer != NULL)
+ wt->super.as_buffer.bf_releasebuffer = (releasebufferproc)sipSimpleWrapper_releasebuffer;
+#else
+ if (ctd->ctd_readbuffer != NULL)
+#if PY_VERSION_HEX >= 0x02050000
+ wt->super.as_buffer.bf_getreadbuffer = (readbufferproc)sipSimpleWrapper_getreadbuffer;
+#else
+ wt->super.as_buffer.bf_getreadbuffer = (getreadbufferproc)sipSimpleWrapper_getreadbuffer;
+#endif
+
+ if (ctd->ctd_writebuffer != NULL)
+#if PY_VERSION_HEX >= 0x02050000
+ wt->super.as_buffer.bf_getwritebuffer = (writebufferproc)sipSimpleWrapper_getwritebuffer;
+#else
+ wt->super.as_buffer.bf_getwritebuffer = (getwritebufferproc)sipSimpleWrapper_getwritebuffer;
+#endif
+
+ if (ctd->ctd_segcount != NULL)
+#if PY_VERSION_HEX >= 0x02050000
+ wt->super.as_buffer.bf_getsegcount = (segcountproc)sipSimpleWrapper_getsegcount;
+#else
+ wt->super.as_buffer.bf_getsegcount = (getsegcountproc)sipSimpleWrapper_getsegcount;
+#endif
+
+ if (ctd->ctd_charbuffer != NULL)
+#if PY_VERSION_HEX >= 0x02050000
+ wt->super.as_buffer.bf_getcharbuffer = (charbufferproc)sipSimpleWrapper_getcharbuffer;
+#else
+ wt->super.as_buffer.bf_getcharbuffer = (getcharbufferproc)sipSimpleWrapper_getcharbuffer;
+#endif
+#endif
+
+ /* Add the slots for this type. */
+ if (ctd->ctd_pyslots != NULL)
+ addTypeSlots(&wt->super, ctd->ctd_pyslots);
+}
+
+
+/*
+ * Add the slot handler for each slot present in the type.
+ */
+static void addTypeSlots(PyHeapTypeObject *heap_to, sipPySlotDef *slots)
+{
+ PyTypeObject *to;
+ PyNumberMethods *nb;
+ PySequenceMethods *sq;
+ PyMappingMethods *mp;
+ void *f;
+
+ to = (PyTypeObject *)heap_to;
+ nb = &heap_to->as_number;
+ sq = &heap_to->as_sequence;
+ mp = &heap_to->as_mapping;
+
+ while ((f = slots->psd_func) != NULL)
+ switch (slots++->psd_type)
+ {
+ case str_slot:
+ to->tp_str = (reprfunc)f;
+ break;
+
+ case int_slot:
+ if (nb != NULL)
+ nb->nb_int = (unaryfunc)f;
+ break;
+
+#if PY_MAJOR_VERSION < 3
+ case long_slot:
+ if (nb != NULL)
+ nb->nb_long = (unaryfunc)f;
+ break;
+#endif
+
+ case float_slot:
+ if (nb != NULL)
+ nb->nb_float = (unaryfunc)f;
+ break;
+
+ case len_slot:
+ if (mp != NULL)
+#if PY_VERSION_HEX >= 0x02050000
+ mp->mp_length = (lenfunc)f;
+#else
+ mp->mp_length = (inquiry)f;
+#endif
+ if (sq != NULL)
+#if PY_VERSION_HEX >= 0x02050000
+ sq->sq_length = (lenfunc)f;
+#else
+ sq->sq_length = (inquiry)f;
+#endif
+ break;
+
+ case contains_slot:
+ if (sq != NULL)
+ sq->sq_contains = (objobjproc)f;
+ break;
+
+ case add_slot:
+ if (nb != NULL)
+ nb->nb_add = (binaryfunc)f;
+ break;
+
+ case concat_slot:
+ if (sq != NULL)
+ sq->sq_concat = (binaryfunc)f;
+ break;
+
+ case sub_slot:
+ if (nb != NULL)
+ nb->nb_subtract = (binaryfunc)f;
+ break;
+
+ case mul_slot:
+ if (nb != NULL)
+ nb->nb_multiply = (binaryfunc)f;
+ break;
+
+ case repeat_slot:
+ if (sq != NULL)
+#if PY_VERSION_HEX >= 0x02050000
+ sq->sq_repeat = (ssizeargfunc)f;
+#else
+ sq->sq_repeat = (intargfunc)f;
+#endif
+ break;
+
+ case div_slot:
+ if (nb != NULL)
+ {
+ nb->nb_true_divide = (binaryfunc)f;
+#if PY_MAJOR_VERSION < 3
+ nb->nb_divide = (binaryfunc)f;
+#endif
+ }
+ break;
+
+ case mod_slot:
+ if (nb != NULL)
+ nb->nb_remainder = (binaryfunc)f;
+ break;
+
+ case floordiv_slot:
+ if (nb != NULL)
+ nb->nb_floor_divide = (binaryfunc)f;
+ break;
+
+ case truediv_slot:
+ if (nb != NULL)
+ nb->nb_true_divide = (binaryfunc)f;
+ break;
+
+ case and_slot:
+ if (nb != NULL)
+ nb->nb_and = (binaryfunc)f;
+ break;
+
+ case or_slot:
+ if (nb != NULL)
+ nb->nb_or = (binaryfunc)f;
+ break;
+
+ case xor_slot:
+ if (nb != NULL)
+ nb->nb_xor = (binaryfunc)f;
+ break;
+
+ case lshift_slot:
+ if (nb != NULL)
+ nb->nb_lshift = (binaryfunc)f;
+ break;
+
+ case rshift_slot:
+ if (nb != NULL)
+ nb->nb_rshift = (binaryfunc)f;
+ break;
+
+ case iadd_slot:
+ if (nb != NULL)
+ nb->nb_inplace_add = (binaryfunc)f;
+ break;
+
+ case iconcat_slot:
+ if (sq != NULL)
+ sq->sq_inplace_concat = (binaryfunc)f;
+ break;
+
+ case isub_slot:
+ if (nb != NULL)
+ nb->nb_inplace_subtract = (binaryfunc)f;
+ break;
+
+ case imul_slot:
+ if (nb != NULL)
+ nb->nb_inplace_multiply = (binaryfunc)f;
+ break;
+
+ case irepeat_slot:
+ if (sq != NULL)
+#if PY_VERSION_HEX >= 0x02050000
+ sq->sq_inplace_repeat = (ssizeargfunc)f;
+#else
+ sq->sq_inplace_repeat = (intargfunc)f;
+#endif
+ break;
+
+ case idiv_slot:
+ if (nb != NULL)
+ {
+ nb->nb_inplace_true_divide = (binaryfunc)f;
+#if PY_MAJOR_VERSION < 3
+ nb->nb_inplace_divide = (binaryfunc)f;
+#endif
+ }
+ break;
+
+ case imod_slot:
+ if (nb != NULL)
+ nb->nb_inplace_remainder = (binaryfunc)f;
+ break;
+
+ case ifloordiv_slot:
+ if (nb != NULL)
+ nb->nb_inplace_floor_divide = (binaryfunc)f;
+ break;
+
+ case itruediv_slot:
+ if (nb != NULL)
+ nb->nb_inplace_true_divide = (binaryfunc)f;
+ break;
+
+ case iand_slot:
+ if (nb != NULL)
+ nb->nb_inplace_and = (binaryfunc)f;
+ break;
+
+ case ior_slot:
+ if (nb != NULL)
+ nb->nb_inplace_or = (binaryfunc)f;
+ break;
+
+ case ixor_slot:
+ if (nb != NULL)
+ nb->nb_inplace_xor = (binaryfunc)f;
+ break;
+
+ case ilshift_slot:
+ if (nb != NULL)
+ nb->nb_inplace_lshift = (binaryfunc)f;
+ break;
+
+ case irshift_slot:
+ if (nb != NULL)
+ nb->nb_inplace_rshift = (binaryfunc)f;
+ break;
+
+ case invert_slot:
+ if (nb != NULL)
+ nb->nb_invert = (unaryfunc)f;
+ break;
+
+ case call_slot:
+ to->tp_call = slot_call;
+ break;
+
+ case getitem_slot:
+ if (mp != NULL)
+ mp->mp_subscript = (binaryfunc)f;
+ if (sq != NULL)
+ sq->sq_item = slot_sq_item;
+ break;
+
+ case setitem_slot:
+ case delitem_slot:
+ if (mp != NULL)
+ mp->mp_ass_subscript = slot_mp_ass_subscript;
+ if (sq != NULL)
+ sq->sq_ass_item = slot_sq_ass_item;
+ break;
+
+ case lt_slot:
+ case le_slot:
+ case eq_slot:
+ case ne_slot:
+ case gt_slot:
+ case ge_slot:
+ to->tp_richcompare = slot_richcompare;
+ break;
+
+#if PY_MAJOR_VERSION < 3
+ case cmp_slot:
+ to->tp_compare = (cmpfunc)f;
+ break;
+#endif
+
+ case bool_slot:
+ if (nb != NULL)
+#if PY_MAJOR_VERSION >= 3
+ nb->nb_bool = (inquiry)f;
+#else
+ nb->nb_nonzero = (inquiry)f;
+#endif
+ break;
+
+ case neg_slot:
+ if (nb != NULL)
+ nb->nb_negative = (unaryfunc)f;
+ break;
+
+ case repr_slot:
+ to->tp_repr = (reprfunc)f;
+ break;
+
+ case hash_slot:
+ to->tp_hash = (hashfunc)f;
+ break;
+
+ case pos_slot:
+ if (nb != NULL)
+ nb->nb_positive = (unaryfunc)f;
+ break;
+
+ case abs_slot:
+ if (nb != NULL)
+ nb->nb_absolute = (unaryfunc)f;
+ break;
+
+#if PY_VERSION_HEX >= 0x02050000
+ case index_slot:
+ if (nb != NULL)
+ nb->nb_index = (unaryfunc)f;
+ break;
+#endif
+
+ case iter_slot:
+ to->tp_iter = (getiterfunc)f;
+ break;
+
+ case next_slot:
+ to->tp_iternext = (iternextfunc)f;
+ break;
+ }
+}
+
+
+/*
+ * Remove the object from the map and call the C/C++ dtor if we own the
+ * instance.
+ */
+static void forgetObject(sipSimpleWrapper *sw)
+{
+ const sipClassTypeDef *ctd;
+
+ /*
+ * This is needed because we release the GIL when calling a C++ dtor.
+ * Without it the cyclic garbage collector can be invoked from another
+ * thread resulting in a crash.
+ */
+ PyObject_GC_UnTrack((PyObject *)sw);
+
+ if (getPtrTypeDef(sw, &ctd) != NULL)
+ {
+ /*
+ * Remove the object from the map before calling the class specific
+ * dealloc code. This code calls the C++ dtor and may result in
+ * further calls that pass the instance as an argument. If this is
+ * still in the map then it's reference count would be increased (to
+ * one) and bad things happen when it drops back to zero again. (An
+ * example is PyQt events generated during the dtor call being passed
+ * to an event filter implemented in Python.) By removing it from the
+ * map first we ensure that a new Python object is created.
+ */
+ sipOMRemoveObject(&cppPyMap, sw);
+
+ /* Call the C++ dtor if there is one. */
+ if (ctd->ctd_dealloc != NULL)
+ ctd->ctd_dealloc(sw);
+ }
+}
+
+
+/*
+ * If the given name is that of a typedef then the corresponding type is
+ * returned.
+ */
+static const char *sip_api_resolve_typedef(const char *name)
+{
+ const sipExportedModuleDef *em;
+
+ /*
+ * Note that if the same name is defined as more than one type (which is
+ * possible if more than one completely independent modules are being
+ * used) then we might pick the wrong one.
+ */
+ for (em = moduleList; em != NULL; em = em->em_next)
+ {
+ if (em->em_nrtypedefs > 0)
+ {
+ sipTypedefDef *tdd;
+
+ tdd = (sipTypedefDef *)bsearch(name, em->em_typedefs,
+ em->em_nrtypedefs, sizeof (sipTypedefDef),
+ compareTypedefName);
+
+ if (tdd != NULL)
+ return tdd->tdd_type_name;
+ }
+ }
+
+ return NULL;
+}
+
+
+/*
+ * The bsearch() helper function for searching a sorted typedef table.
+ */
+static int compareTypedefName(const void *key, const void *el)
+{
+ return strcmp((const char *)key, ((const sipTypedefDef *)el)->tdd_name);
+}
+
+
+/*
+ * Add the given Python object to the given list. Return 0 if there was no
+ * error.
+ */
+static int addPyObjectToList(sipPyObject **head, PyObject *object)
+{
+ sipPyObject *po;
+
+ if ((po = sip_api_malloc(sizeof (sipPyObject))) == NULL)
+ return -1;
+
+ po->object = object;
+ po->next = *head;
+
+ *head = po;
+
+ return 0;
+}
+
+
+/*
+ * Register a symbol with a name. A negative value is returned if the name was
+ * already registered.
+ */
+static int sip_api_export_symbol(const char *name, void *sym)
+{
+ sipSymbol *ss;
+
+ if (sip_api_import_symbol(name) != NULL)
+ return -1;
+
+ if ((ss = sip_api_malloc(sizeof (sipSymbol))) == NULL)
+ return -1;
+
+ ss->name = name;
+ ss->symbol = sym;
+ ss->next = sipSymbolList;
+
+ sipSymbolList = ss;
+
+ return 0;
+}
+
+
+/*
+ * Return the symbol registered with the given name. NULL is returned if the
+ * name was not registered.
+ */
+static void *sip_api_import_symbol(const char *name)
+{
+ sipSymbol *ss;
+
+ for (ss = sipSymbolList; ss != NULL; ss = ss->next)
+ if (strcmp(ss->name, name) == 0)
+ return ss->symbol;
+
+ return NULL;
+}
+
+
+/*
+ * Visit a slot connected to an object for the cyclic garbage collector. This
+ * is only called externally by PyQt3.
+ */
+static int sip_api_visit_slot(sipSlot *slot, visitproc visit, void *arg)
+{
+ /* See if the slot has an extra reference. */
+ if (slot->weakSlot == Py_True && slot->pyobj != Py_None)
+ return visit(slot->pyobj, arg);
+
+ return 0;
+}
+
+
+/*
+ * Clear a slot if it has an extra reference to keep it alive. This is only
+ * called externally by PyQt3.
+ */
+static void sip_api_clear_any_slot_reference(sipSlot *slot)
+{
+ if (slot->weakSlot == Py_True)
+ {
+ PyObject *xref = slot->pyobj;
+
+ /*
+ * Replace the slot with None. We don't use NULL as this has another
+ * meaning.
+ */
+ Py_INCREF(Py_None);
+ slot->pyobj = Py_None;
+
+ Py_DECREF(xref);
+ }
+}
+
+
+/*
+ * Convert a Python object to a character and raise an exception if there was
+ * an error.
+ */
+static char sip_api_bytes_as_char(PyObject *obj)
+{
+ char ch;
+
+ if (parseBytes_AsChar(obj, &ch) < 0)
+ {
+ PyErr_Format(PyExc_TypeError,
+#if PY_MAJOR_VERSION >= 3
+ "bytes of length 1 expected not '%s'",
+#else
+ "string of length 1 expected not '%s'",
+#endif
+ Py_TYPE(obj)->tp_name);
+
+ return '\0';
+ }
+
+ return ch;
+}
+
+
+/*
+ * Convert a Python object to a string and raise an exception if there was
+ * an error.
+ */
+static const char *sip_api_bytes_as_string(PyObject *obj)
+{
+ const char *a;
+
+ if (parseBytes_AsString(obj, &a) < 0)
+ {
+ PyErr_Format(PyExc_TypeError,
+#if PY_MAJOR_VERSION >= 3
+ "bytes expected not '%s'",
+#else
+ "string expected not '%s'",
+#endif
+ Py_TYPE(obj)->tp_name);
+
+ return NULL;
+ }
+
+ return a;
+}
+
+
+/*
+ * Convert a Python ASCII string object to a character and raise an exception
+ * if there was an error.
+ */
+static char sip_api_string_as_ascii_char(PyObject *obj)
+{
+ char ch;
+
+ if (parseString_AsASCIIChar(obj, &ch) < 0)
+ {
+ /* Use the exception set if it was an encoding error. */
+ if (!PyUnicode_Check(obj) || PyUnicode_GET_SIZE(obj) != 1)
+ PyErr_Format(PyExc_TypeError,
+#if PY_MAJOR_VERSION >= 3
+ "bytes or ASCII string of length 1 expected not '%s'",
+#else
+ "string or ASCII unicode of length 1 expected not '%s'",
+#endif
+ Py_TYPE(obj)->tp_name);
+
+ return '\0';
+ }
+
+ return ch;
+}
+
+
+/*
+ * Parse an ASCII character and return it.
+ */
+static int parseString_AsASCIIChar(PyObject *obj, char *ap)
+{
+ return parseString_AsEncodedChar(PyUnicode_AsASCIIString(obj), obj, ap);
+}
+
+
+/*
+ * Convert a Python Latin-1 string object to a character and raise an exception
+ * if there was an error.
+ */
+static char sip_api_string_as_latin1_char(PyObject *obj)
+{
+ char ch;
+
+ if (parseString_AsLatin1Char(obj, &ch) < 0)
+ {
+ /* Use the exception set if it was an encoding error. */
+ if (!PyUnicode_Check(obj) || PyUnicode_GET_SIZE(obj) != 1)
+ PyErr_Format(PyExc_TypeError,
+#if PY_MAJOR_VERSION >= 3
+ "bytes or Latin-1 string of length 1 expected not '%s'",
+#else
+ "string or Latin-1 unicode of length 1 expected not '%s'",
+#endif
+ Py_TYPE(obj)->tp_name);
+
+ return '\0';
+ }
+
+ return ch;
+}
+
+
+/*
+ * Parse a Latin-1 character and return it.
+ */
+static int parseString_AsLatin1Char(PyObject *obj, char *ap)
+{
+ return parseString_AsEncodedChar(PyUnicode_AsLatin1String(obj), obj, ap);
+}
+
+
+/*
+ * Convert a Python UTF-8 string object to a character and raise an exception
+ * if there was an error.
+ */
+static char sip_api_string_as_utf8_char(PyObject *obj)
+{
+ char ch;
+
+ if (parseString_AsUTF8Char(obj, &ch) < 0)
+ {
+ /* Use the exception set if it was an encoding error. */
+ if (!PyUnicode_Check(obj) || PyUnicode_GET_SIZE(obj) != 1)
+ PyErr_Format(PyExc_TypeError,
+#if PY_MAJOR_VERSION >= 3
+ "bytes or UTF-8 string of length 1 expected not '%s'",
+#else
+ "string or UTF-8 unicode of length 1 expected not '%s'",
+#endif
+ Py_TYPE(obj)->tp_name);
+
+ return '\0';
+ }
+
+ return ch;
+}
+
+
+/*
+ * Parse a UTF-8 character and return it.
+ */
+static int parseString_AsUTF8Char(PyObject *obj, char *ap)
+{
+ return parseString_AsEncodedChar(PyUnicode_AsUTF8String(obj), obj, ap);
+}
+
+
+/*
+ * Parse an encoded character and return it.
+ */
+static int parseString_AsEncodedChar(PyObject *bytes, PyObject *obj, char *ap)
+{
+ SIP_SSIZE_T size;
+
+ if (bytes == NULL)
+ {
+ PyErr_Clear();
+
+ return parseBytes_AsChar(obj, ap);
+ }
+
+ size = SIPBytes_GET_SIZE(bytes);
+
+ if (size != 1)
+ {
+ Py_DECREF(bytes);
+ return -1;
+ }
+
+ *ap = *SIPBytes_AS_STRING(bytes);
+
+ Py_DECREF(bytes);
+
+ return 0;
+}
+
+
+/*
+ * Convert a Python ASCII string object to a string and raise an exception if
+ * there was an error. The object is updated with the one that owns the
+ * string. Note that None is considered an error.
+ */
+static const char *sip_api_string_as_ascii_string(PyObject **obj)
+{
+ PyObject *s = *obj;
+ const char *a;
+
+ if (s == Py_None || (*obj = parseString_AsASCIIString(s, &a)) == NULL)
+ {
+ /* Use the exception set if it was an encoding error. */
+ if (!PyUnicode_Check(s))
+ PyErr_Format(PyExc_TypeError,
+#if PY_MAJOR_VERSION >= 3
+ "bytes or ASCII string expected not '%s'",
+#else
+ "string or ASCII unicode expected not '%s'",
+#endif
+ Py_TYPE(s)->tp_name);
+
+ return NULL;
+ }
+
+ return a;
+}
+
+
+/*
+ * Parse an ASCII string and return it and a new reference to the object that
+ * owns the string.
+ */
+static PyObject *parseString_AsASCIIString(PyObject *obj, const char **ap)
+{
+ return parseString_AsEncodedString(PyUnicode_AsASCIIString(obj), obj, ap);
+}
+
+
+/*
+ * Convert a Python Latin-1 string object to a string and raise an exception if
+ * there was an error. The object is updated with the one that owns the
+ * string. Note that None is considered an error.
+ */
+static const char *sip_api_string_as_latin1_string(PyObject **obj)
+{
+ PyObject *s = *obj;
+ const char *a;
+
+ if (s == Py_None || (*obj = parseString_AsLatin1String(s, &a)) == NULL)
+ {
+ /* Use the exception set if it was an encoding error. */
+ if (!PyUnicode_Check(s))
+ PyErr_Format(PyExc_TypeError,
+#if PY_MAJOR_VERSION >= 3
+ "bytes or Latin-1 string expected not '%s'",
+#else
+ "string or Latin-1 unicode expected not '%s'",
+#endif
+ Py_TYPE(s)->tp_name);
+
+ return NULL;
+ }
+
+ return a;
+}
+
+
+/*
+ * Parse a Latin-1 string and return it and a new reference to the object that
+ * owns the string.
+ */
+static PyObject *parseString_AsLatin1String(PyObject *obj, const char **ap)
+{
+ return parseString_AsEncodedString(PyUnicode_AsLatin1String(obj), obj, ap);
+}
+
+
+/*
+ * Convert a Python UTF-8 string object to a string and raise an exception if
+ * there was an error. The object is updated with the one that owns the
+ * string. Note that None is considered an error.
+ */
+static const char *sip_api_string_as_utf8_string(PyObject **obj)
+{
+ PyObject *s = *obj;
+ const char *a;
+
+ if (s == Py_None || (*obj = parseString_AsUTF8String(s, &a)) == NULL)
+ {
+ /* Use the exception set if it was an encoding error. */
+ if (!PyUnicode_Check(s))
+ PyErr_Format(PyExc_TypeError,
+#if PY_MAJOR_VERSION >= 3
+ "bytes or UTF-8 string expected not '%s'",
+#else
+ "string or UTF-8 unicode expected not '%s'",
+#endif
+ Py_TYPE(s)->tp_name);
+
+ return NULL;
+ }
+
+ return a;
+}
+
+
+/*
+ * Parse a UTF-8 string and return it and a new reference to the object that
+ * owns the string.
+ */
+static PyObject *parseString_AsUTF8String(PyObject *obj, const char **ap)
+{
+ return parseString_AsEncodedString(PyUnicode_AsUTF8String(obj), obj, ap);
+}
+
+
+/*
+ * Parse an encoded string and return it and a new reference to the object that
+ * owns the string.
+ */
+static PyObject *parseString_AsEncodedString(PyObject *bytes, PyObject *obj,
+ const char **ap)
+{
+ if (bytes != NULL)
+ {
+ *ap = SIPBytes_AS_STRING(bytes);
+
+ return bytes;
+ }
+
+ PyErr_Clear();
+
+ if (parseBytes_AsString(obj, ap) < 0)
+ return NULL;
+
+ Py_INCREF(obj);
+
+ return obj;
+}
+
+
+/*
+ * Parse a character array and return it's address and length.
+ */
+static int parseBytes_AsCharArray(PyObject *obj, const char **ap,
+ SIP_SSIZE_T *aszp)
+{
+ if (obj == Py_None)
+ {
+ *ap = NULL;
+ *aszp = 0;
+ }
+ else if (SIPBytes_Check(obj))
+ {
+ *ap = SIPBytes_AS_STRING(obj);
+ *aszp = SIPBytes_GET_SIZE(obj);
+ }
+ else if (PyObject_AsCharBuffer(obj, ap, aszp) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+/*
+ * Parse a character and return it.
+ */
+static int parseBytes_AsChar(PyObject *obj, char *ap)
+{
+ const char *chp;
+ SIP_SSIZE_T sz;
+
+ if (SIPBytes_Check(obj))
+ {
+ chp = SIPBytes_AS_STRING(obj);
+ sz = SIPBytes_GET_SIZE(obj);
+ }
+ else if (PyObject_AsCharBuffer(obj, &chp, &sz) < 0)
+ return -1;
+
+ if (sz != 1)
+ return -1;
+
+ *ap = *chp;
+
+ return 0;
+}
+
+
+/*
+ * Parse a character string and return it.
+ */
+static int parseBytes_AsString(PyObject *obj, const char **ap)
+{
+ SIP_SSIZE_T sz;
+
+ return parseBytes_AsCharArray(obj, ap, &sz);
+}
+
+
+#if defined(HAVE_WCHAR_H)
+/*
+ * Convert a Python object to a wide character.
+ */
+static wchar_t sip_api_unicode_as_wchar(PyObject *obj)
+{
+ wchar_t ch;
+
+ if (parseWChar(obj, &ch) < 0)
+ {
+ PyErr_Format(PyExc_ValueError,
+#if PY_MAJOR_VERSION >= 3
+ "string"
+#else
+ "unicode string"
+#endif
+ " of length 1 expected, not %s", Py_TYPE(obj)->tp_name);
+
+ return L'\0';
+ }
+
+ return ch;
+}
+
+
+/*
+ * Convert a Python object to a wide character string on the heap.
+ */
+static wchar_t *sip_api_unicode_as_wstring(PyObject *obj)
+{
+ wchar_t *p;
+
+ if (parseWCharString(obj, &p) < 0)
+ {
+ PyErr_Format(PyExc_ValueError,
+#if PY_MAJOR_VERSION >= 3
+ "string"
+#else
+ "unicode string"
+#endif
+ " expected, not %s", Py_TYPE(obj)->tp_name);
+
+ return NULL;
+ }
+
+ return p;
+}
+
+
+/*
+ * Parse a wide character array and return it's address and length.
+ */
+static int parseWCharArray(PyObject *obj, wchar_t **ap, SIP_SSIZE_T *aszp)
+{
+ if (obj == Py_None)
+ {
+ *ap = NULL;
+ *aszp = 0;
+
+ return 0;
+ }
+
+ if (PyUnicode_Check(obj))
+ return convertToWCharArray(obj, ap, aszp);
+
+#if PY_MAJOR_VERSION < 3
+ if (PyString_Check(obj))
+ {
+ int rc;
+ PyObject *uobj;
+
+ if ((uobj = PyUnicode_FromObject(obj)) == NULL)
+ return -1;
+
+ rc = convertToWCharArray(uobj, ap, aszp);
+ Py_DECREF(uobj);
+
+ return rc;
+ }
+#endif
+
+ return -1;
+}
+
+
+/*
+ * Convert a Unicode object to a wide character array and return it's address
+ * and length.
+ */
+static int convertToWCharArray(PyObject *obj, wchar_t **ap, SIP_SSIZE_T *aszp)
+{
+ SIP_SSIZE_T ulen;
+ wchar_t *wc;
+
+ ulen = PyUnicode_GET_SIZE(obj);
+
+ if ((wc = sip_api_malloc(ulen * sizeof (wchar_t))) == NULL)
+ return -1;
+
+ ulen = PyUnicode_AsWideChar((PyUnicodeObject *)obj, wc, ulen);
+
+ if (ulen < 0)
+ {
+ sip_api_free(wc);
+ return -1;
+ }
+
+ *ap = wc;
+ *aszp = ulen;
+
+ return 0;
+}
+
+
+/*
+ * Parse a wide character and return it.
+ */
+static int parseWChar(PyObject *obj, wchar_t *ap)
+{
+ if (PyUnicode_Check(obj))
+ return convertToWChar(obj, ap);
+
+#if PY_MAJOR_VERSION < 3
+ if (PyString_Check(obj))
+ {
+ int rc;
+ PyObject *uobj;
+
+ if ((uobj = PyUnicode_FromObject(obj)) == NULL)
+ return -1;
+
+ rc = convertToWChar(uobj, ap);
+ Py_DECREF(uobj);
+
+ return rc;
+ }
+#endif
+
+ return -1;
+}
+
+
+/*
+ * Convert a Unicode object to a wide character and return it.
+ */
+static int convertToWChar(PyObject *obj, wchar_t *ap)
+{
+ if (PyUnicode_GET_SIZE(obj) != 1)
+ return -1;
+
+ if (PyUnicode_AsWideChar((PyUnicodeObject *)obj, ap, 1) != 1)
+ return -1;
+
+ return 0;
+}
+
+
+/*
+ * Parse a wide character string and return a copy on the heap.
+ */
+static int parseWCharString(PyObject *obj, wchar_t **ap)
+{
+ if (obj == Py_None)
+ {
+ *ap = NULL;
+
+ return 0;
+ }
+
+ if (PyUnicode_Check(obj))
+ return convertToWCharString(obj, ap);
+
+#if PY_MAJOR_VERSION < 3
+ if (PyString_Check(obj))
+ {
+ int rc;
+ PyObject *uobj;
+
+ if ((uobj = PyUnicode_FromObject(obj)) == NULL)
+ return -1;
+
+ rc = convertToWCharString(uobj, ap);
+ Py_DECREF(uobj);
+
+ return rc;
+ }
+#endif
+
+ return -1;
+}
+
+
+/*
+ * Convert a Unicode object to a wide character string and return a copy on
+ * the heap.
+ */
+static int convertToWCharString(PyObject *obj, wchar_t **ap)
+{
+ SIP_SSIZE_T ulen;
+ wchar_t *wc;
+
+ ulen = PyUnicode_GET_SIZE(obj);
+
+ if ((wc = sip_api_malloc((ulen + 1) * sizeof (wchar_t))) == NULL)
+ return -1;
+
+ ulen = PyUnicode_AsWideChar((PyUnicodeObject *)obj, wc, ulen);
+
+ if (ulen < 0)
+ {
+ sip_api_free(wc);
+ return -1;
+ }
+
+ wc[ulen] = L'\0';
+
+ *ap = wc;
+
+ return 0;
+}
+
+#else
+
+/*
+ * Convert a Python object to a wide character.
+ */
+static int sip_api_unicode_as_wchar(PyObject *obj)
+{
+ raiseNoWChar();
+
+ return 0;
+}
+
+
+/*
+ * Convert a Python object to a wide character.
+ */
+static int *sip_api_unicode_as_wstring(PyObject *obj)
+{
+ raiseNoWChar();
+
+ return NULL;
+}
+
+
+/*
+ * Report the need for absent wide character support.
+ */
+static void raiseNoWChar()
+{
+ PyErr_SetString(PyExc_SystemError, "sip built without wchar_t support");
+}
+
+#endif
+
+
+/*
+ * The enum type alloc slot.
+ */
+static PyObject *sipEnumType_alloc(PyTypeObject *self, SIP_SSIZE_T nitems)
+{
+ sipEnumTypeObject *py_type;
+ sipPySlotDef *psd;
+
+ assert(currentType != NULL);
+
+ /* Call the standard super-metatype alloc. */
+ if ((py_type = (sipEnumTypeObject *)PyType_Type.tp_alloc(self, nitems)) == NULL)
+ return NULL;
+
+ /*
+ * Set the links between the Python type object and the generated type
+ * structure. Strictly speaking this doesn't need to be done here.
+ */
+ py_type->type = currentType;
+ currentType->u.td_py_type = (PyTypeObject *)py_type;
+
+ /*
+ * Initialise any slots. This must be done here, after the type is
+ * allocated but before PyType_Ready() is called.
+ */
+ if ((psd = ((sipEnumTypeDef *)currentType)->etd_pyslots) != NULL)
+ addTypeSlots(&py_type->super, psd);
+
+ currentType = NULL;
+
+ return (PyObject *)py_type;
+}
diff --git a/siplib/siplib.sbf b/siplib/siplib.sbf
new file mode 100644
index 0000000..79f9a45
--- /dev/null
+++ b/siplib/siplib.sbf
@@ -0,0 +1,19 @@
+# This is the build file for the extension module.
+#
+# Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com>
+#
+# This file is part of SIP.
+#
+# This copy of SIP is licensed for use under the terms of the SIP License
+# Agreement. See the file LICENSE for more details.
+#
+# This copy of SIP may also used under the terms of the GNU General Public
+# License v2 or v3 as published by the Free Software Foundation which can be
+# found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
+#
+# SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+target = sip
+sources = siplib.c apiversions.c descriptors.c qtlib.c threads.c objmap.c voidptr.c bool.cpp
+headers = sip.h sipint.h
diff --git a/siplib/threads.c b/siplib/threads.c
new file mode 100644
index 0000000..0854a0a
--- /dev/null
+++ b/siplib/threads.c
@@ -0,0 +1,226 @@
+/*
+ * Thread support for the SIP library. This module provides the hooks for
+ * C++ classes that provide a thread interface to interact properly with the
+ * Python threading infrastructure.
+ *
+ * Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com>
+ *
+ * This file is part of SIP.
+ *
+ * This copy of SIP is licensed for use under the terms of the SIP License
+ * Agreement. See the file LICENSE for more details.
+ *
+ * This copy of SIP may also used under the terms of the GNU General Public
+ * License v2 or v3 as published by the Free Software Foundation which can be
+ * found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
+ *
+ * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#include "sip.h"
+#include "sipint.h"
+
+
+/*
+ * The data associated with pending request to wrap an object.
+ */
+typedef struct _pendingDef {
+ void *cpp; /* The C/C++ object ot be wrapped. */
+ sipWrapper *owner; /* The owner of the object. */
+ int flags; /* The flags. */
+} pendingDef;
+
+
+#ifdef WITH_THREAD
+
+#include <pythread.h>
+
+
+/*
+ * The per thread data we need to maintain.
+ */
+typedef struct _threadDef {
+ long thr_ident; /* The thread identifier. */
+ pendingDef pending; /* An object waiting to be wrapped. */
+ struct _threadDef *next; /* Next in the list. */
+} threadDef;
+
+
+static threadDef *threads = NULL; /* Linked list of threads. */
+
+
+static threadDef *currentThreadDef(void);
+
+#endif
+
+
+static pendingDef pending; /* An object waiting to be wrapped. */
+
+
+/*
+ * Get the address of any C/C++ object waiting to be wrapped.
+ */
+void *sipGetPending(sipWrapper **op, int *fp)
+{
+ pendingDef *pp;
+
+#ifdef WITH_THREAD
+ threadDef *thread;
+
+ if ((thread = currentThreadDef()) != NULL)
+ pp = &thread->pending;
+ else
+ pp = &pending;
+#else
+ pp = &pending;
+#endif
+
+ if (pp->cpp != NULL)
+ {
+ if (op != NULL)
+ *op = pp->owner;
+
+ if (fp != NULL)
+ *fp = pp->flags;
+ }
+
+ return pp->cpp;
+}
+
+
+/*
+ * Convert a new C/C++ pointer to a Python instance.
+ */
+PyObject *sipWrapSimpleInstance(void *cppPtr, const sipTypeDef *td,
+ sipWrapper *owner, int flags)
+{
+ static PyObject *nullargs = NULL;
+
+ pendingDef old_pending;
+ PyObject *self;
+#ifdef WITH_THREAD
+ threadDef *thread;
+#endif
+
+ if (nullargs == NULL && (nullargs = PyTuple_New(0)) == NULL)
+ return NULL;
+
+ if (cppPtr == NULL)
+ {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ /*
+ * Object creation can trigger the Python garbage collector which in turn
+ * can execute arbitrary Python code which can then call this function
+ * recursively. Therefore we save any existing pending object before
+ * setting the new one.
+ */
+#ifdef WITH_THREAD
+ if ((thread = currentThreadDef()) != NULL)
+ {
+ old_pending = thread->pending;
+
+ thread->pending.cpp = cppPtr;
+ thread->pending.owner = owner;
+ thread->pending.flags = flags;
+ }
+ else
+ {
+ old_pending = pending;
+
+ pending.cpp = cppPtr;
+ pending.owner = owner;
+ pending.flags = flags;
+ }
+#else
+ old_pending = pending;
+
+ pending.cpp = cppPtr;
+ pending.owner = owner;
+ pending.flags = flags;
+#endif
+
+ self = PyObject_Call((PyObject *)sipTypeAsPyTypeObject(td), nullargs, NULL);
+
+#ifdef WITH_THREAD
+ if (thread != NULL)
+ thread->pending = old_pending;
+ else
+ pending = old_pending;
+#else
+ pending = old_pending;
+#endif
+
+ return self;
+}
+
+
+/*
+ * This is called from a newly created thread to initialise some thread local
+ * storage.
+ */
+void sip_api_start_thread(void)
+{
+#ifdef WITH_THREAD
+ threadDef *thread;
+
+ /* Save the thread ID. First, find an empty slot in the list. */
+ for (thread = threads; thread != NULL; thread = thread->next)
+ if (thread->thr_ident == 0)
+ break;
+
+ if (thread == NULL)
+ {
+ thread = sip_api_malloc(sizeof (threadDef));
+ thread->next = threads;
+ threads = thread;
+ }
+
+ if (thread != NULL)
+ {
+ thread->thr_ident = PyThread_get_thread_ident();
+ thread->pending.cpp = NULL;
+ }
+#endif
+}
+
+
+/*
+ * Handle the termination of a thread. The thread state should already have
+ * been handled by the last call to PyGILState_Release().
+ */
+void sip_api_end_thread(void)
+{
+#ifdef WITH_THREAD
+ threadDef *thread;
+
+ /* We have the GIL at this point. */
+ if ((thread = currentThreadDef()) != NULL)
+ thread->thr_ident = 0;
+#endif
+}
+
+
+#ifdef WITH_THREAD
+
+/*
+ * Return the thread data for the current thread or NULL if it wasn't
+ * recognised.
+ */
+static threadDef *currentThreadDef(void)
+{
+ threadDef *thread;
+ long ident = PyThread_get_thread_ident();
+
+ for (thread = threads; thread != NULL; thread = thread->next)
+ if (thread->thr_ident == ident)
+ break;
+
+ return thread;
+}
+
+#endif
diff --git a/siplib/voidptr.c b/siplib/voidptr.c
new file mode 100644
index 0000000..fc26046
--- /dev/null
+++ b/siplib/voidptr.c
@@ -0,0 +1,579 @@
+/*
+ * SIP library code.
+ *
+ * Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com>
+ *
+ * This file is part of SIP.
+ *
+ * This copy of SIP is licensed for use under the terms of the SIP License
+ * Agreement. See the file LICENSE for more details.
+ *
+ * This copy of SIP may also used under the terms of the GNU General Public
+ * License v2 or v3 as published by the Free Software Foundation which can be
+ * found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
+ *
+ * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#include <Python.h>
+
+#include <stddef.h>
+
+#include "sip.h"
+#include "sipint.h"
+
+
+/* The object data structure. */
+typedef struct {
+ PyObject_HEAD
+ void *voidptr;
+ SIP_SSIZE_T size;
+ int rw;
+} sipVoidPtrObject;
+
+
+/* The structure used to hold the results of a voidptr conversion. */
+struct vp_values {
+ void *voidptr;
+ SIP_SSIZE_T size;
+ int rw;
+};
+
+
+static PyObject *make_voidptr(void *voidptr, SIP_SSIZE_T size, int rw);
+static int vp_convertor(PyObject *arg, struct vp_values *vp);
+
+
+/*
+ * Implement __new__ for the type.
+ */
+static PyObject *sipVoidPtr_new(PyTypeObject *subtype, PyObject *args,
+ PyObject *kw)
+{
+ static char *kwlist[] = {"address", "size", "writeable", NULL};
+
+ struct vp_values vp_conversion;
+ SIP_SSIZE_T size = -1;
+ int rw = -1;
+ PyObject *obj;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw,
+#if PY_VERSION_HEX >= 0x02050000
+ "O&|ni:voidptr",
+#else
+ "O&|ii:voidptr",
+#endif
+ kwlist, vp_convertor, &vp_conversion, &size, &rw))
+ return NULL;
+
+ /* Use the explicit size if one was given. */
+ if (size >= 0)
+ vp_conversion.size = size;
+
+ /* Use the explicit writeable flag if one was given. */
+ if (rw >= 0)
+ vp_conversion.rw = rw;
+
+ /* Create the instance. */
+ if ((obj = subtype->tp_alloc(subtype, 0)) == NULL)
+ return NULL;
+
+ /* Save the values. */
+ ((sipVoidPtrObject *)obj)->voidptr = vp_conversion.voidptr;
+ ((sipVoidPtrObject *)obj)->size = vp_conversion.size;
+ ((sipVoidPtrObject *)obj)->rw = vp_conversion.rw;
+
+ return obj;
+}
+
+
+#if PY_MAJOR_VERSION >= 3
+/*
+ * The read buffer implementation for Python v3.
+ */
+static int sipVoidPtr_getbuffer(PyObject *self, Py_buffer *buf, int flags)
+{
+ sipVoidPtrObject *v = (sipVoidPtrObject *)self;
+
+ return PyBuffer_FillInfo(buf, self, v->voidptr, v->size, !v->rw, flags);
+}
+#endif
+
+
+#if PY_MAJOR_VERSION < 3
+/*
+ * The read buffer implementation for Python v2.
+ */
+static SIP_SSIZE_T sipVoidPtr_getbuffer(PyObject *self, SIP_SSIZE_T seg,
+ void **ptr)
+{
+ SIP_SSIZE_T size = ((sipVoidPtrObject *)self)->size;
+
+ if (size < 0 || seg != 0)
+ {
+ PyErr_SetString(PyExc_SystemError, "invalid buffer segment");
+ return -1;
+ }
+
+ *ptr = ((sipVoidPtrObject *)self)->voidptr;
+
+ return size;
+}
+#endif
+
+
+#if PY_MAJOR_VERSION < 3
+/*
+ * The write buffer implementation for Python v2.
+ */
+static SIP_SSIZE_T sipVoidPtr_getwritebuffer(PyObject *self, SIP_SSIZE_T seg,
+ void **ptr)
+{
+ if (((sipVoidPtrObject *)self)->rw)
+ return sipVoidPtr_getbuffer(self, seg, ptr);
+
+ PyErr_SetString(PyExc_TypeError, "the sip.voidptr is not writeable");
+ return -1;
+}
+#endif
+
+
+#if PY_MAJOR_VERSION < 3
+/*
+ * The segment count implementation for Python v2.
+ */
+static SIP_SSIZE_T sipVoidPtr_getsegcount(PyObject *self, SIP_SSIZE_T *lenp)
+{
+ SIP_SSIZE_T segs, len;
+
+ len = ((sipVoidPtrObject *)self)->size;
+ segs = (len < 0 ? 0 : 1);
+
+ if (lenp != NULL)
+ *lenp = len;
+
+ return segs;
+}
+#endif
+
+
+/*
+ * Implement int() for the type.
+ */
+static PyObject *sipVoidPtr_int(sipVoidPtrObject *v)
+{
+ return PyLong_FromVoidPtr(v->voidptr);
+}
+
+
+#if PY_MAJOR_VERSION < 3
+/*
+ * Implement hex() for the type.
+ */
+static PyObject *sipVoidPtr_hex(sipVoidPtrObject *v)
+{
+ char buf[2 + 16 + 1];
+
+ PyOS_snprintf(buf, sizeof (buf), "0x%.*lx", (int)(sizeof (void *) * 2),
+ (unsigned long)v->voidptr);
+
+ return PyString_FromString(buf);
+}
+#endif
+
+
+#if defined(SIP_USE_PYCAPSULE)
+/*
+ * Implement ascapsule() for the type.
+ */
+static PyObject *sipVoidPtr_ascapsule(sipVoidPtrObject *v, PyObject *arg)
+{
+ return PyCapsule_New(v->voidptr, NULL, NULL);
+}
+#endif
+
+
+/*
+ * Implement ascobject() for the type.
+ */
+static PyObject *sipVoidPtr_ascobject(sipVoidPtrObject *v, PyObject *arg)
+{
+ return PyCObject_FromVoidPtr(v->voidptr, NULL);
+}
+
+
+/*
+ * Implement asstring() for the type.
+ */
+static PyObject *sipVoidPtr_asstring(sipVoidPtrObject *v, PyObject *args,
+ PyObject *kw)
+{
+ static char *kwlist[] = {"size", NULL};
+
+ SIP_SSIZE_T size = -1;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw,
+#if PY_VERSION_HEX >= 0x02050000
+ "|n:asstring",
+#else
+ "|i:asstring",
+#endif
+ kwlist, &size))
+ return NULL;
+
+ /* Use the current size if one wasn't explicitly given. */
+ if (size < 0)
+ size = v->size;
+
+ if (size < 0)
+ {
+ PyErr_SetString(PyExc_ValueError,
+ "a size must be given or the sip.voidptr must have a size");
+ return NULL;
+ }
+
+ return SIPBytes_FromStringAndSize(v->voidptr, size);
+}
+
+
+/*
+ * Implement getsize() for the type.
+ */
+static PyObject *sipVoidPtr_getsize(sipVoidPtrObject *v, PyObject *arg)
+{
+#if PY_MAJOR_VERSION >= 3
+ return PyLong_FromSsize_t(v->size);
+#elif PY_VERSION_HEX >= 0x02050000
+ return PyInt_FromSsize_t(v->size);
+#else
+ return PyInt_FromLong(v->size);
+#endif
+}
+
+
+/*
+ * Implement setsize() for the type.
+ */
+static PyObject *sipVoidPtr_setsize(sipVoidPtrObject *v, PyObject *arg)
+{
+ SIP_SSIZE_T size;
+
+#if PY_MAJOR_VERSION >= 3
+ size = PyLong_AsSsize_t(arg);
+#elif PY_VERSION_HEX >= 0x02050000
+ size = PyInt_AsSsize_t(arg);
+#else
+ size = (int)PyInt_AsLong(arg);
+#endif
+
+ if (PyErr_Occurred())
+ return NULL;
+
+ v->size = size;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+/*
+ * Implement getwriteable() for the type.
+ */
+static PyObject *sipVoidPtr_getwriteable(sipVoidPtrObject *v, PyObject *arg)
+{
+ return PyBool_FromLong(v->rw);
+}
+
+
+/*
+ * Implement setwriteable() for the type.
+ */
+static PyObject *sipVoidPtr_setwriteable(sipVoidPtrObject *v, PyObject *arg)
+{
+ int rw;
+
+ rw = (int)SIPLong_AsLong(arg);
+
+ if (PyErr_Occurred())
+ return NULL;
+
+ v->rw = rw;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+/* The methods data structure. */
+static PyMethodDef sipVoidPtr_Methods[] = {
+#if defined(SIP_USE_PYCAPSULE)
+ {"ascapsule", (PyCFunction)sipVoidPtr_ascapsule, METH_NOARGS, NULL},
+#endif
+ {"ascobject", (PyCFunction)sipVoidPtr_ascobject, METH_NOARGS, NULL},
+ {"asstring", (PyCFunction)sipVoidPtr_asstring, METH_KEYWORDS, NULL},
+ {"getsize", (PyCFunction)sipVoidPtr_getsize, METH_NOARGS, NULL},
+ {"setsize", (PyCFunction)sipVoidPtr_setsize, METH_O, NULL},
+ {"getwriteable", (PyCFunction)sipVoidPtr_getwriteable, METH_NOARGS, NULL},
+ {"setwriteable", (PyCFunction)sipVoidPtr_setwriteable, METH_O, NULL},
+ {NULL}
+};
+
+
+/* The number methods data structure. */
+static PyNumberMethods sipVoidPtr_NumberMethods = {
+ 0, /* nb_add */
+ 0, /* nb_subtract */
+ 0, /* nb_multiply */
+#if PY_MAJOR_VERSION < 3
+ 0, /* nb_divide */
+#endif
+ 0, /* nb_remainder */
+ 0, /* nb_divmod */
+ 0, /* nb_power */
+ 0, /* nb_negative */
+ 0, /* nb_positive */
+ 0, /* nb_absolute */
+ 0, /* nb_bool (Python v3), nb_nonzero (Python v2) */
+ 0, /* nb_invert */
+ 0, /* nb_lshift */
+ 0, /* nb_rshift */
+ 0, /* nb_and */
+ 0, /* nb_xor */
+ 0, /* nb_or */
+#if PY_MAJOR_VERSION < 3
+ 0, /* nb_coerce */
+#endif
+ (unaryfunc)sipVoidPtr_int, /* nb_int */
+ 0, /* nb_reserved (Python v3), nb_long (Python v2) */
+ 0, /* nb_float */
+#if PY_MAJOR_VERSION < 3
+ 0, /* nb_oct */
+ (unaryfunc)sipVoidPtr_hex, /* nb_hex */
+#endif
+ 0, /* nb_inplace_add */
+ 0, /* nb_inplace_subtract */
+ 0, /* nb_inplace_multiply */
+#if PY_MAJOR_VERSION < 3
+ 0, /* nb_inplace_divide */
+#endif
+ 0, /* nb_inplace_remainder */
+ 0, /* nb_inplace_power */
+ 0, /* nb_inplace_lshift */
+ 0, /* nb_inplace_rshift */
+ 0, /* nb_inplace_and */
+ 0, /* nb_inplace_xor */
+ 0, /* nb_inplace_or */
+ 0, /* nb_floor_divide */
+ 0, /* nb_true_divide */
+ 0, /* nb_inplace_floor_divide */
+ 0, /* nb_inplace_true_divide */
+#if PY_VERSION_HEX >= 0x02050000
+ 0 /* nb_index */
+#endif
+};
+
+
+/* The buffer methods data structure. */
+static PyBufferProcs sipVoidPtr_BufferProcs = {
+ sipVoidPtr_getbuffer,
+#if PY_MAJOR_VERSION >= 3
+ NULL,
+#else
+ sipVoidPtr_getwritebuffer,
+ sipVoidPtr_getsegcount,
+#if PY_VERSION_HEX >= 0x02050000
+ (charbufferproc)sipVoidPtr_getbuffer
+#else
+ (getcharbufferproc)sipVoidPtr_getbuffer
+#endif
+#endif
+};
+
+
+/* The type data structure. */
+PyTypeObject sipVoidPtr_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "sip.voidptr", /* tp_name */
+ sizeof (sipVoidPtrObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved (Python v3), tp_compare (Python v2) */
+ 0, /* tp_repr */
+ &sipVoidPtr_NumberMethods, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ &sipVoidPtr_BufferProcs, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ sipVoidPtr_Methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ sipVoidPtr_new, /* tp_new */
+};
+
+
+/*
+ * A convenience function to convert a C/C++ void pointer from a Python object.
+ */
+void *sip_api_convert_to_void_ptr(PyObject *obj)
+{
+ if (obj == NULL)
+ {
+ PyErr_SetString(PyExc_TypeError, "sip.voidptr is NULL");
+ return NULL;
+ }
+
+ if (obj == Py_None)
+ return NULL;
+
+ if (PyObject_TypeCheck(obj, &sipVoidPtr_Type))
+ return ((sipVoidPtrObject *)obj)->voidptr;
+
+#if defined(SIP_USE_PYCAPSULE)
+ if (PyCapsule_CheckExact(obj))
+ return PyCapsule_GetPointer(obj, NULL);
+#endif
+
+ if (PyCObject_Check(obj))
+ return PyCObject_AsVoidPtr(obj);
+
+#if PY_MAJOR_VERSION >= 3
+ return PyLong_AsVoidPtr(obj);
+#else
+ return (void *)PyInt_AsLong(obj);
+#endif
+}
+
+
+/*
+ * Convert a C/C++ void pointer to a sip.voidptr object.
+ */
+PyObject *sip_api_convert_from_void_ptr(void *val)
+{
+ return make_voidptr(val, -1, TRUE);
+}
+
+
+/*
+ * Convert a C/C++ void pointer to a sip.voidptr object.
+ */
+PyObject *sip_api_convert_from_const_void_ptr(const void *val)
+{
+ return make_voidptr((void *)val, -1, FALSE);
+}
+
+
+/*
+ * Convert a sized C/C++ void pointer to a sip.voidptr object.
+ */
+PyObject *sip_api_convert_from_void_ptr_and_size(void *val, SIP_SSIZE_T size)
+{
+ return make_voidptr(val, size, TRUE);
+}
+
+
+/*
+ * Convert a sized C/C++ const void pointer to a sip.voidptr object.
+ */
+PyObject *sip_api_convert_from_const_void_ptr_and_size(const void *val,
+ SIP_SSIZE_T size)
+{
+ return make_voidptr((void *)val, size, FALSE);
+}
+
+
+/*
+ * Do the work of converting a void pointer.
+ */
+static PyObject *make_voidptr(void *voidptr, SIP_SSIZE_T size, int rw)
+{
+ sipVoidPtrObject *self;
+
+ if (voidptr == NULL)
+ {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ if ((self = PyObject_NEW(sipVoidPtrObject, &sipVoidPtr_Type)) == NULL)
+ return NULL;
+
+ self->voidptr = voidptr;
+ self->size = size;
+ self->rw = rw;
+
+ return (PyObject *)self;
+}
+
+
+/*
+ * Convert a Python object to the values needed to create a voidptr.
+ */
+static int vp_convertor(PyObject *arg, struct vp_values *vp)
+{
+ void *ptr;
+ SIP_SSIZE_T size = -1;
+ int rw = TRUE;
+
+ if (arg == Py_None)
+ ptr = NULL;
+#if defined(SIP_USE_PYCAPSULE)
+ else if (PyCapsule_CheckExact(arg))
+ ptr = PyCapsule_GetPointer(arg, NULL);
+#endif
+ else if (PyCObject_Check(arg))
+ ptr = PyCObject_AsVoidPtr(arg);
+ else if (PyObject_TypeCheck(arg, &sipVoidPtr_Type))
+ {
+ ptr = ((sipVoidPtrObject *)arg)->voidptr;
+ size = ((sipVoidPtrObject *)arg)->size;
+ rw = ((sipVoidPtrObject *)arg)->rw;
+ }
+ else
+ {
+#if PY_MAJOR_VERSION >= 3
+ ptr = PyLong_AsVoidPtr(arg);
+#else
+ ptr = (void *)PyInt_AsLong(arg);
+#endif
+
+ if (PyErr_Occurred())
+ {
+#if PY_VERSION_HEX >= 0x03010000
+ PyErr_SetString(PyExc_TypeError, "a single integer, CObject, None or another voidptr is required");
+#else
+ PyErr_SetString(PyExc_TypeError, "a single integer, Capsule, CObject, None or another voidptr is required");
+#endif
+ return 0;
+ }
+ }
+
+ vp->voidptr = ptr;
+ vp->size = size;
+ vp->rw = rw;
+
+ return 1;
+}
diff --git a/siputils.py b/siputils.py
new file mode 100644
index 0000000..bb5959e
--- /dev/null
+++ b/siputils.py
@@ -0,0 +1,2525 @@
+# This module is intended to be used by the build/installation scripts of
+# extension modules created with SIP. It provides information about file
+# locations, version numbers etc., and provides some classes and functions.
+#
+# Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com>
+#
+# This file is part of SIP.
+#
+# This copy of SIP is licensed for use under the terms of the SIP License
+# Agreement. See the file LICENSE for more details.
+#
+# This copy of SIP may also used under the terms of the GNU General Public
+# License v2 or v3 as published by the Free Software Foundation which can be
+# found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
+#
+# SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+
+import sys
+import os
+import stat
+import string
+import re
+
+
+# These are installation specific values created when SIP was configured.
+# @SIP_CONFIGURATION@
+
+# The stack of configuration dictionaries.
+_config_stack = []
+
+
+class Configuration(object):
+ """The class that represents SIP configuration values.
+ """
+ def __init__(self, sub_cfg=None):
+ """Initialise an instance of the class.
+
+ sub_cfg is the list of sub-class configurations. It should be None
+ when called normally.
+ """
+ # Find the build macros in the closest imported module from where this
+ # was originally defined.
+ self._macros = None
+
+ for cls in self.__class__.__mro__:
+ if cls is object:
+ continue
+
+ mod = sys.modules[cls.__module__]
+
+ if hasattr(mod, "_default_macros"):
+ self._macros = mod._default_macros
+ break
+
+ if sub_cfg:
+ cfg = sub_cfg
+ else:
+ cfg = []
+
+ cfg.append(_pkg_config)
+
+ global _config_stack
+ _config_stack = cfg
+
+ def __getattr__(self, name):
+ """Allow configuration values and user options to be handled as
+ instance variables.
+
+ name is the name of the configuration value or user option.
+ """
+ for cfg in _config_stack:
+ try:
+ return cfg[name]
+ except KeyError:
+ pass
+
+ raise AttributeError("\"%s\" is not a valid configuration value or user option" % name)
+
+ def build_macros(self):
+ """Return the dictionary of platform specific build macros.
+ """
+ return self._macros
+
+ def set_build_macros(self, macros):
+ """Set the dictionary of build macros to be use when generating
+ Makefiles.
+
+ macros is the dictionary of platform specific build macros.
+ """
+ self._macros = macros
+
+
+class _UniqueList:
+ """A limited list that ensures all its elements are unique.
+ """
+ def __init__(self, value=None):
+ """Initialise the instance.
+
+ value is the initial value of the list.
+ """
+ if value is None:
+ self._list = []
+ else:
+ self._list = value
+
+ def append(self, value):
+ """Append a value to the list if it isn't already present.
+
+ value is the value to append.
+ """
+ if value not in self._list:
+ self._list.append(value)
+
+ def lextend(self, value):
+ """A normal list extend ignoring the uniqueness.
+
+ value is the list of elements to append.
+ """
+ self._list.extend(value)
+
+ def extend(self, value):
+ """Append each element of a value to a list if it isn't already
+ present.
+
+ value is the list of elements to append.
+ """
+ for el in value:
+ self.append(el)
+
+ def as_list(self):
+ """Return the list as a raw list.
+ """
+ return self._list
+
+
+class _Macro:
+ """A macro that can be manipulated as a list.
+ """
+ def __init__(self, name, value):
+ """Initialise the instance.
+
+ name is the name of the macro.
+ value is the initial value of the macro.
+ """
+ self._name = name
+ self.set(value)
+
+ def set(self, value):
+ """Explicitly set the value of the macro.
+
+ value is the new value. It may be a string, a list of strings or a
+ _UniqueList instance.
+ """
+ self._macro = []
+
+ if isinstance(value, _UniqueList):
+ value = value.as_list()
+
+ if type(value) == list:
+ self.extend(value)
+ else:
+ self.append(value)
+
+ def append(self, value):
+ """Append a value to the macro.
+
+ value is the value to append.
+ """
+ if value:
+ self._macro.append(value)
+
+ def extend(self, value):
+ """Append each element of a value to the macro.
+
+ value is the list of elements to append.
+ """
+ for el in value:
+ self.append(el)
+
+ def remove(self, value):
+ """Remove a value from the macro. It doesn't matter if the value
+ wasn't present.
+
+ value is the value to remove.
+ """
+ try:
+ self._macro.remove(value)
+ except:
+ pass
+
+ def as_list(self):
+ """Return the macro as a list.
+ """
+ return self._macro
+
+
+class Makefile:
+ """The base class for the different types of Makefiles.
+ """
+ def __init__(self, configuration, console=0, qt=0, opengl=0, python=0,
+ threaded=0, warnings=1, debug=0, dir=None,
+ makefile="Makefile", installs=None, universal=None,
+ arch=None):
+ """Initialise an instance of the target. All the macros are left
+ unchanged allowing scripts to manipulate them at will.
+
+ configuration is the current configuration.
+ console is set if the target is a console (rather than windows) target.
+ qt is set if the target uses Qt. For Qt v4 a list of Qt libraries may
+ be specified and a simple non-zero value implies QtCore and QtGui.
+ opengl is set if the target uses OpenGL.
+ python is set if the target #includes Python.h.
+ debug is set to generated a debugging version of the target.
+ threaded is set if the target requires thread support. It is
+ automatically set if the target uses Qt and Qt has thread support
+ enabled.
+ warnings is set if compiler warning messages are required.
+ debug is set if debugging symbols should be generated.
+ dir is the directory for build files and Makefiles.
+ makefile is the name of the Makefile.
+ installs is a list of extra install targets. Each element is a two
+ part list, the first of which is the source and the second is the
+ destination. If the source is another list then it is a set of source
+ files and the destination is a directory.
+ universal is the name of the SDK if the target is a MacOS/X universal
+ binary. If it is None then the value is taken from the configuration.
+ arch is the space separated MacOS/X architectures to build. If it is
+ None then it is taken from the configuration.
+ """
+ if qt:
+ if not hasattr(configuration, "qt_version"):
+ error("The target uses Qt but pyqtconfig has not been imported.")
+
+ # For Qt v4 interpret Qt support as meaning link against the core
+ # and GUI libraries (which corresponds to the default qmake
+ # configuration). Also allow a list of Qt v4 modules to be
+ # specified.
+ if configuration.qt_version >= 0x040000:
+ if type(qt) != list:
+ qt = ["QtCore", "QtGui"]
+
+ self._threaded = configuration.qt_threaded
+ else:
+ self._threaded = threaded
+
+ self.config = configuration
+ self.console = console
+ self._qt = qt
+ self._opengl = opengl
+ self._python = python
+ self._warnings = warnings
+ self._debug = debug
+ self._makefile = makefile
+ self._installs = installs
+
+ # Make sure the destination directory is an absolute path.
+ if dir:
+ self.dir = os.path.abspath(dir)
+ else:
+ self.dir = os.path.curdir
+
+ # Assume we are building in the source tree.
+ self._src_dir = self.dir
+
+ if universal is None:
+ self._universal = configuration.universal
+ else:
+ self._universal = universal
+
+ if arch is None:
+ self._arch = configuration.arch
+ else:
+ self._arch = arch
+
+ self._finalised = 0
+
+ # Copy the macros and convert them all to instance lists.
+ macros = configuration.build_macros()
+
+ for m in list(macros.keys()):
+ # Allow the user to override the default.
+ try:
+ val = getattr(configuration, m)
+ except AttributeError:
+ val = macros[m]
+
+ # These require special handling as they are (potentially) a set of
+ # space separated values rather than a single value that might
+ # contain spaces.
+ if m in ("DEFINES", "CONFIG") or m[:6] in ("INCDIR", "LIBDIR"):
+ val = val.split()
+
+ # We also want to treat lists of libraries in the same way so that
+ # duplicates get eliminated.
+ if m[:4] == "LIBS":
+ val = val.split()
+
+ self.__dict__[m] = _Macro(m, val)
+
+ # This is used to alter the configuration more significantly than can
+ # be done with just configuration files.
+ self.generator = self.optional_string("MAKEFILE_GENERATOR", "UNIX")
+
+ # These are what configuration scripts normally only need to change.
+ self.extra_cflags = []
+ self.extra_cxxflags = []
+ self.extra_defines = []
+ self.extra_include_dirs = []
+ self.extra_lflags = []
+ self.extra_lib_dirs = []
+ self.extra_libs = []
+
+ # Get these once and make them available to sub-classes.
+ if sys.platform == "win32":
+ def_copy = "copy"
+ def_rm = "del"
+ def_mkdir = "mkdir"
+ def_chk_dir_exists = "if not exist"
+ else:
+ def_copy = "cp -f"
+ def_rm = "rm -f"
+ def_mkdir = "mkdir -p"
+ def_chk_dir_exists = "test -d"
+
+ self.copy = self.optional_string("COPY", def_copy)
+ self.rm = self.optional_string("DEL_FILE", def_rm)
+ self.mkdir = self.optional_string("MKDIR", def_mkdir)
+ self.chkdir = self.optional_string("CHK_DIR_EXISTS", def_chk_dir_exists)
+
+
+ def finalise(self):
+ """Finalise the macros by doing any consolidation that isn't specific
+ to a Makefile.
+ """
+ # Extract the things we might need from the Windows Qt configuration.
+ # Note that we used to think that if Qt was built with exceptions, RTTI
+ # and STL support enabled then anything that linked against it also
+ # needed the same flags. However, detecting this was broken for some
+ # time and nobody complained. For the moment we'll leave the code in
+ # but it will never be used.
+ if self._qt:
+ wcfg = self.config.qt_winconfig.split()
+ win_shared = ("shared" in wcfg)
+ win_exceptions = ("exceptions" in wcfg)
+ win_rtti = ("rtti" in wcfg)
+ win_stl = ("stl" in wcfg)
+ else:
+ win_shared = 1
+ win_exceptions = 0
+ win_rtti = 0
+ win_stl = 0
+
+ # Get what we are going to transform.
+ cflags = _UniqueList()
+ cflags.extend(self.extra_cflags)
+ cflags.extend(self.optional_list("CFLAGS"))
+
+ cxxflags = _UniqueList()
+ cxxflags.extend(self.extra_cxxflags)
+ cxxflags.extend(self.optional_list("CXXFLAGS"))
+
+ defines = _UniqueList()
+ defines.extend(self.extra_defines)
+ defines.extend(self.optional_list("DEFINES"))
+
+ incdir = _UniqueList(["."])
+ incdir.extend(self.extra_include_dirs)
+ incdir.extend(self.optional_list("INCDIR"))
+
+ lflags = _UniqueList()
+ lflags.extend(self.extra_lflags)
+ lflags.extend(self.optional_list("LFLAGS"))
+
+ libdir = _UniqueList()
+ libdir.extend(self.extra_lib_dirs)
+ libdir.extend(self.optional_list("LIBDIR"))
+
+ # Handle MacOS/X specific configuration.
+ if sys.platform == 'darwin':
+ mac_cflags = []
+ mac_lflags = []
+
+ for a in self._arch.split():
+ aflag = '-arch ' + a
+ mac_cflags.append(aflag)
+ mac_lflags.append(aflag)
+
+ if self._universal:
+ mac_cflags.append('-isysroot %s' % self._universal)
+ mac_lflags.append('-Wl,-syslibroot,%s' % self._universal)
+
+ cflags.lextend(mac_cflags)
+ cxxflags.lextend(mac_cflags)
+ lflags.lextend(mac_lflags)
+
+ # Don't use a unique list as libraries may need to be searched more
+ # than once. Also MacOS/X uses the form "-framework lib" so we don't
+ # want to lose the multiple "-framework".
+ libs = []
+
+ for l in self.extra_libs:
+ libs.append(self.platform_lib(l))
+
+ if self._qt:
+ libs.extend(self._dependent_libs(l))
+
+ libs.extend(self.optional_list("LIBS"))
+
+ rpaths = _UniqueList()
+
+ for l in self.extra_lib_dirs:
+ # Ignore relative directories. This is really a hack to handle
+ # SIP v3 inter-module linking.
+ if os.path.dirname(l) not in ("", ".", ".."):
+ rpaths.append(l)
+
+ if self._python:
+ incdir.append(self.config.py_inc_dir)
+ incdir.append(self.config.py_conf_inc_dir)
+
+ if sys.platform == "cygwin":
+ libdir.append(self.config.py_lib_dir)
+
+ py_lib = "python%u.%u" % ((self.config.py_version >> 16), ((self.config.py_version >> 8) & 0xff))
+ libs.append(self.platform_lib(py_lib))
+ elif sys.platform == "win32":
+ libdir.append(self.config.py_lib_dir)
+
+ py_lib = "python%u%u" % ((self.config.py_version >> 16), ((self.config.py_version >> 8) & 0xff))
+
+ # For Borland use the OMF version of the Python library if it
+ # exists, otherwise assume that Python was built with Borland
+ # and use the normal library.
+ if self.generator == "BMAKE":
+ bpy_lib = py_lib + "_bcpp"
+ bpy_lib_path = os.path.join(self.config.py_lib_dir, self.platform_lib(bpy_lib))
+
+ if os.access(bpy_lib_path, os.F_OK):
+ py_lib = bpy_lib
+
+ if self._debug:
+ py_lib = py_lib + "_d"
+
+ if self.generator != "MINGW":
+ cflags.append("/D_DEBUG")
+ cxxflags.append("/D_DEBUG")
+
+ libs.append(self.platform_lib(py_lib))
+
+ if self.generator in ("MSVC", "MSVC.NET", "BMAKE"):
+ if win_exceptions:
+ cflags_exceptions = "CFLAGS_EXCEPTIONS_ON"
+ cxxflags_exceptions = "CXXFLAGS_EXCEPTIONS_ON"
+ else:
+ cflags_exceptions = "CFLAGS_EXCEPTIONS_OFF"
+ cxxflags_exceptions = "CXXFLAGS_EXCEPTIONS_OFF"
+
+ cflags.extend(self.optional_list(cflags_exceptions))
+ cxxflags.extend(self.optional_list(cxxflags_exceptions))
+
+ if win_rtti:
+ cflags_rtti = "CFLAGS_RTTI_ON"
+ cxxflags_rtti = "CXXFLAGS_RTTI_ON"
+ else:
+ cflags_rtti = "CFLAGS_RTTI_OFF"
+ cxxflags_rtti = "CXXFLAGS_RTTI_OFF"
+
+ cflags.extend(self.optional_list(cflags_rtti))
+ cxxflags.extend(self.optional_list(cxxflags_rtti))
+
+ if win_stl:
+ cflags_stl = "CFLAGS_STL_ON"
+ cxxflags_stl = "CXXFLAGS_STL_ON"
+ else:
+ cflags_stl = "CFLAGS_STL_OFF"
+ cxxflags_stl = "CXXFLAGS_STL_OFF"
+
+ cflags.extend(self.optional_list(cflags_stl))
+ cxxflags.extend(self.optional_list(cxxflags_stl))
+
+ if self._debug:
+ if win_shared:
+ cflags_mt = "CFLAGS_MT_DLLDBG"
+ cxxflags_mt = "CXXFLAGS_MT_DLLDBG"
+ else:
+ cflags_mt = "CFLAGS_MT_DBG"
+ cxxflags_mt = "CXXFLAGS_MT_DBG"
+
+ cflags_debug = "CFLAGS_DEBUG"
+ cxxflags_debug = "CXXFLAGS_DEBUG"
+ lflags_debug = "LFLAGS_DEBUG"
+ else:
+ if win_shared:
+ cflags_mt = "CFLAGS_MT_DLL"
+ cxxflags_mt = "CXXFLAGS_MT_DLL"
+ else:
+ cflags_mt = "CFLAGS_MT"
+ cxxflags_mt = "CXXFLAGS_MT"
+
+ cflags_debug = "CFLAGS_RELEASE"
+ cxxflags_debug = "CXXFLAGS_RELEASE"
+ lflags_debug = "LFLAGS_RELEASE"
+
+ if self.generator in ("MSVC", "MSVC.NET", "BMAKE"):
+ if self._threaded:
+ cflags.extend(self.optional_list(cflags_mt))
+ cxxflags.extend(self.optional_list(cxxflags_mt))
+
+ if self.console:
+ cflags.extend(self.optional_list("CFLAGS_CONSOLE"))
+ cxxflags.extend(self.optional_list("CXXFLAGS_CONSOLE"))
+
+ cflags.extend(self.optional_list(cflags_debug))
+ cxxflags.extend(self.optional_list(cxxflags_debug))
+ lflags.extend(self.optional_list(lflags_debug))
+
+ if self._warnings:
+ cflags_warn = "CFLAGS_WARN_ON"
+ cxxflags_warn = "CXXFLAGS_WARN_ON"
+ else:
+ cflags_warn = "CFLAGS_WARN_OFF"
+ cxxflags_warn = "CXXFLAGS_WARN_OFF"
+
+ cflags.extend(self.optional_list(cflags_warn))
+ cxxflags.extend(self.optional_list(cxxflags_warn))
+
+ if self._threaded:
+ cflags.extend(self.optional_list("CFLAGS_THREAD"))
+ cxxflags.extend(self.optional_list("CXXFLAGS_THREAD"))
+ lflags.extend(self.optional_list("LFLAGS_THREAD"))
+
+ if self._qt:
+ if self.generator != "UNIX" and win_shared:
+ defines.append("QT_DLL")
+
+ if not self._debug:
+ defines.append("QT_NO_DEBUG")
+
+ if self.config.qt_version >= 0x040000:
+ for mod in self._qt:
+ # Note that qmake doesn't define anything for QtHelp.
+ if mod == "QtCore":
+ defines.append("QT_CORE_LIB")
+ elif mod == "QtGui":
+ defines.append("QT_GUI_LIB")
+ elif mod == "QtMultimedia":
+ defines.append("QT_MULTIMEDIA_LIB")
+ elif mod == "QtNetwork":
+ defines.append("QT_NETWORK_LIB")
+ elif mod == "QtOpenGL":
+ defines.append("QT_OPENGL_LIB")
+ elif mod == "QtScript":
+ defines.append("QT_SCRIPT_LIB")
+ elif mod == "QtScriptTools":
+ defines.append("QT_SCRIPTTOOLS_LIB")
+ elif mod == "QtSql":
+ defines.append("QT_SQL_LIB")
+ elif mod == "QtTest":
+ defines.append("QT_TEST_LIB")
+ elif mod == "QtWebKit":
+ defines.append("QT_WEBKIT_LIB")
+ elif mod == "QtXml":
+ defines.append("QT_XML_LIB")
+ elif mod == "QtXmlPatterns":
+ defines.append("QT_XMLPATTERNS_LIB")
+ elif mod == "phonon":
+ defines.append("QT_PHONON_LIB")
+ elif self._threaded:
+ defines.append("QT_THREAD_SUPPORT")
+
+ # Handle library directories.
+ libdir_qt = self.optional_list("LIBDIR_QT")
+ libdir.extend(libdir_qt)
+ rpaths.extend(libdir_qt)
+
+ if self.config.qt_version >= 0x040000:
+ # For Windows: the macros that define the dependencies on
+ # Windows libraries.
+ wdepmap = {
+ "QtCore": "LIBS_CORE",
+ "QtGui": "LIBS_GUI",
+ "QtNetwork": "LIBS_NETWORK",
+ "QtOpenGL": "LIBS_OPENGL",
+ "QtWebKit": "LIBS_WEBKIT"
+ }
+
+ # For Windows: the dependencies between Qt libraries.
+ qdepmap = {
+ "QtAssistant": ("QtNetwork", "QtGui", "QtCore"),
+ "QtGui": ("QtCore", ),
+ "QtHelp": ("QtSql", "QtGui", "QtCore"),
+ "QtMultimedia": ("QtGui", "QtCore"),
+ "QtNetwork": ("QtCore", ),
+ "QtOpenGL": ("QtGui", "QtCore"),
+ "QtScript": ("QtCore", ),
+ "QtScriptTools": ("QtScript", "QtGui", "QtCore"),
+ "QtSql": ("QtCore", ),
+ "QtSvg": ("QtXml", "QtGui", "QtCore"),
+ "QtTest": ("QtGui", "QtCore"),
+ "QtWebKit": ("QtNetwork", "QtGui", "QtCore"),
+ "QtXml": ("QtCore", ),
+ "QtXmlPatterns": ("QtNetwork", "QtCore"),
+ "phonon": ("QtGui", "QtCore"),
+ "QtDesigner": ("QtGui", "QtCore"),
+ "QAxContainer": ("QtGui", "QtCore")
+ }
+
+ # The QtSql .prl file doesn't include QtGui as a dependency (at
+ # least on Linux) so we explcitly set the dependency here for
+ # everything.
+ if "QtSql" in self._qt:
+ if "QtGui" not in self._qt:
+ self._qt.append("QtGui")
+
+ # With Qt v4.2.0, the QtAssistantClient library is now a shared
+ # library on UNIX. The QtAssistantClient .prl file doesn't
+ # include QtGui and QtNetwork as a dependency any longer. This
+ # seems to be a bug in Qt v4.2.0. We explicitly set the
+ # dependencies here.
+ if self.config.qt_version >= 0x040200 and "QtAssistant" in self._qt:
+ if "QtGui" not in self._qt:
+ self._qt.append("QtGui")
+ if "QtNetwork" not in self._qt:
+ self._qt.append("QtNetwork")
+
+ for mod in self._qt:
+ lib = self._qt4_module_to_lib(mod)
+ libs.append(self.platform_lib(lib, self._is_framework(mod)))
+
+ if sys.platform == "win32":
+ # On Windows the dependent libraries seem to be in
+ # qmake.conf rather than the .prl file and the
+ # inter-dependencies between Qt libraries don't seem to
+ # be anywhere.
+ deps = _UniqueList()
+
+ if mod in list(wdepmap.keys()):
+ deps.extend(self.optional_list(wdepmap[mod]))
+
+ if mod in list(qdepmap.keys()):
+ for qdep in qdepmap[mod]:
+ # Ignore the dependency if it is explicitly
+ # linked.
+ if qdep not in self._qt:
+ libs.append(self.platform_lib(self._qt4_module_to_lib(qdep)))
+
+ if qdep in list(wdepmap.keys()):
+ deps.extend(self.optional_list(wdepmap[qdep]))
+
+ libs.extend(deps.as_list())
+ else:
+ libs.extend(self._dependent_libs(lib, self._is_framework(mod)))
+ else:
+ # Windows needs the version number appended if Qt is a DLL.
+ qt_lib = self.config.qt_lib
+
+ if self.generator in ("MSVC", "MSVC.NET", "BMAKE") and win_shared:
+ qt_lib = qt_lib + version_to_string(self.config.qt_version).replace(".", "")
+
+ if self.config.qt_edition == "non-commercial":
+ qt_lib = qt_lib + "nc"
+
+ libs.append(self.platform_lib(qt_lib, self.config.qt_framework))
+ libs.extend(self._dependent_libs(self.config.qt_lib))
+
+ # Handle header directories.
+ try:
+ specd_base = self.config.qt_data_dir
+ except AttributeError:
+ specd_base = self.config.qt_dir
+
+ specd = os.path.join(specd_base, "mkspecs", "default")
+
+ if not os.access(specd, os.F_OK):
+ specd = os.path.join(specd_base, "mkspecs", self.config.platform)
+
+ incdir.append(specd)
+
+ qtincdir = self.optional_list("INCDIR_QT")
+
+ if qtincdir:
+ if self.config.qt_version >= 0x040000:
+ for mod in self._qt:
+ if mod == "QAxContainer":
+ incdir.append(os.path.join(qtincdir[0], "ActiveQt"))
+ elif self._is_framework(mod):
+ if mod == "QtAssistant" and self.config.qt_version < 0x040202:
+ mod = "QtAssistantClient"
+
+ incdir.append(os.path.join(libdir_qt[0], mod + ".framework", "Headers"))
+ else:
+ incdir.append(os.path.join(qtincdir[0], mod))
+
+ # This must go after the module include directories.
+ incdir.extend(qtincdir)
+
+ if self._opengl:
+ incdir.extend(self.optional_list("INCDIR_OPENGL"))
+ lflags.extend(self.optional_list("LFLAGS_OPENGL"))
+ libdir.extend(self.optional_list("LIBDIR_OPENGL"))
+ libs.extend(self.optional_list("LIBS_OPENGL"))
+
+ if self._qt or self._opengl:
+ if self.config.qt_version < 0x040000 or self._opengl or "QtGui" in self._qt:
+ incdir.extend(self.optional_list("INCDIR_X11"))
+ libdir.extend(self.optional_list("LIBDIR_X11"))
+ libs.extend(self.optional_list("LIBS_X11"))
+
+ if self._threaded:
+ libs.extend(self.optional_list("LIBS_THREAD"))
+ libs.extend(self.optional_list("LIBS_RTMT"))
+ else:
+ libs.extend(self.optional_list("LIBS_RT"))
+
+ if self.console:
+ libs.extend(self.optional_list("LIBS_CONSOLE"))
+
+ libs.extend(self.optional_list("LIBS_WINDOWS"))
+
+ lflags.extend(self._platform_rpaths(rpaths.as_list()))
+
+ # Save the transformed values.
+ self.CFLAGS.set(cflags)
+ self.CXXFLAGS.set(cxxflags)
+ self.DEFINES.set(defines)
+ self.INCDIR.set(incdir)
+ self.LFLAGS.set(lflags)
+ self.LIBDIR.set(libdir)
+ self.LIBS.set(libs)
+
+ # Don't do it again because it has side effects.
+ self._finalised = 1
+
+ def _add_manifest(self, target=None):
+ """Add the link flags for creating a manifest file.
+ """
+ if target is None:
+ target = "$(TARGET)"
+
+ self.LFLAGS.append("/MANIFEST")
+ self.LFLAGS.append("/MANIFESTFILE:%s.manifest" % target)
+
+ def _is_framework(self, mod):
+ """Return true if the given Qt module is a framework.
+ """
+ return (self.config.qt_framework and (self.config.qt_version >= 0x040200 or mod != "QtAssistant"))
+
+ def _qt4_module_to_lib(self, mname):
+ """Return the name of the Qt4 library corresponding to a module.
+
+ mname is the name of the module.
+ """
+ if mname == "QtAssistant":
+ if self.config.qt_version >= 0x040202 and sys.platform == "darwin":
+ lib = mname
+ else:
+ lib = "QtAssistantClient"
+ else:
+ lib = mname
+
+ if self._debug:
+ if sys.platform == "win32":
+ lib = lib + "d"
+ elif self.config.qt_version < 0x040200 or sys.platform == "darwin":
+ lib = lib + "_debug"
+
+ if sys.platform == "win32" and "shared" in self.config.qt_winconfig.split():
+ if (mname in ("QtCore", "QtDesigner", "QtGui", "QtHelp",
+ "QtMultimedia", "QtNetwork", "QtOpenGL", "QtScript",
+ "QtScriptTools", "QtSql", "QtSvg", "QtTest",
+ "QtWebKit", "QtXml", "QtXmlPatterns", "phonon") or
+ (self.config.qt_version >= 0x040200 and mname == "QtAssistant")):
+ lib = lib + "4"
+
+ return lib
+
+ def optional_list(self, name):
+ """Return an optional Makefile macro as a list.
+
+ name is the name of the macro.
+ """
+ return self.__dict__[name].as_list()
+
+ def optional_string(self, name, default=""):
+ """Return an optional Makefile macro as a string.
+
+ name is the name of the macro.
+ default is the default value
+ """
+ s = ' '.join(self.optional_list(name))
+
+ if not s:
+ s = default
+
+ return s
+
+ def required_string(self, name):
+ """Return a required Makefile macro as a string.
+
+ name is the name of the macro.
+ """
+ s = self.optional_string(name)
+
+ if not s:
+ raise ValueError("\"%s\" must have a non-empty value" % name)
+
+ return s
+
+ def _platform_rpaths(self, rpaths):
+ """Return a list of platform specific rpath flags.
+
+ rpaths is the cannonical list of rpaths.
+ """
+ flags = []
+ prefix = self.optional_string("RPATH")
+
+ if prefix:
+ for r in rpaths:
+ flags.append(_quote(prefix + r))
+
+ return flags
+
+ def platform_lib(self, clib, framework=0):
+ """Return a library name in platform specific form.
+
+ clib is the library name in cannonical form.
+ framework is set of the library is implemented as a MacOS framework.
+ """
+ if self.generator in ("MSVC", "MSVC.NET", "BMAKE"):
+ plib = clib + ".lib"
+ elif sys.platform == "darwin" and framework:
+ plib = "-framework " + clib
+ else:
+ plib = "-l" + clib
+
+ return plib
+
+ def _dependent_libs(self, clib, framework=0):
+ """Return a list of additional libraries (in platform specific form)
+ that must be linked with a library.
+
+ clib is the library name in cannonical form.
+ framework is set of the library is implemented as a MacOS framework.
+ """
+ prl_libs = []
+
+ if self.generator in ("MSVC", "MSVC.NET", "BMAKE"):
+ prl_name = os.path.join(self.config.qt_lib_dir, clib + ".prl")
+ elif sys.platform == "darwin" and framework:
+ prl_name = os.path.join(self.config.qt_lib_dir, clib + ".framework", clib + ".prl")
+ else:
+ prl_name = os.path.join(self.config.qt_lib_dir, "lib" + clib + ".prl")
+
+ if os.access(prl_name, os.F_OK):
+ try:
+ f = open(prl_name, "r")
+ except IOError:
+ error("Unable to open \"%s\"" % prl_name)
+
+ line = f.readline()
+ while line:
+ line = line.strip()
+ if line and line[0] != "#":
+ eq = line.find("=")
+ if eq > 0 and line[:eq].strip() == "QMAKE_PRL_LIBS":
+ prl_libs = line[eq + 1:].split()
+ break
+
+ line = f.readline()
+
+ f.close()
+
+ return prl_libs
+
+
+ def parse_build_file(self, filename):
+ """
+ Parse a build file and return the corresponding dictionary.
+
+ filename is the name of the build file. If it is a dictionary instead
+ then its contents are validated.
+ """
+ if type(filename) == dict:
+ bfname = "dictionary"
+ bdict = filename
+ else:
+ if os.path.isabs(filename):
+ # We appear to be building out of the source tree.
+ self._src_dir = os.path.dirname(filename)
+ bfname = filename
+ else:
+ bfname = os.path.join(self.dir, filename)
+
+ bdict = {}
+
+ try:
+ f = open(bfname, "r")
+ except IOError:
+ error("Unable to open \"%s\"" % bfname)
+
+ line_nr = 1
+ line = f.readline()
+
+ while line:
+ line = line.strip()
+
+ if line and line[0] != "#":
+ eq = line.find("=")
+
+ if eq <= 0:
+ error("\"%s\" line %d: Line must be in the form 'name = value value...'." % (bfname, line_nr))
+
+ bdict[line[:eq].strip()] = line[eq + 1:].strip()
+
+ line_nr = line_nr + 1
+ line = f.readline()
+
+ f.close()
+
+ # Check the compulsory values.
+ for i in ("target", "sources"):
+ try:
+ bdict[i]
+ except KeyError:
+ error("\"%s\" is missing from \"%s\"." % (i, bfname))
+
+ # Get the optional values.
+ for i in ("headers", "moc_headers"):
+ try:
+ bdict[i]
+ except KeyError:
+ bdict[i] = ""
+
+ # Generate the list of objects.
+ if self.generator in ("MSVC", "MSVC.NET", "BMAKE"):
+ ext = ".obj"
+ else:
+ ext = ".o"
+
+ olist = []
+
+ for f in bdict["sources"].split():
+ root, discard = os.path.splitext(f)
+ olist.append(root + ext)
+
+ for f in bdict["moc_headers"].split():
+ if not self._qt:
+ error("\"%s\" defines \"moc_headers\" for a non-Qt module." % bfname)
+
+ root, discard = os.path.splitext(f)
+ olist.append("moc_" + root + ext)
+
+ bdict["objects"] = ' '.join(olist)
+
+ return bdict
+
+ def clean_build_file_objects(self, mfile, build):
+ """Generate the clean target.
+
+ mfile is the file object.
+ build is the dictionary created from the build file.
+ """
+ mfile.write("\t-%s $(TARGET)\n" % self.rm)
+
+ for f in build["objects"].split():
+ mfile.write("\t-%s %s\n" % (self.rm, f))
+
+ for f in build["moc_headers"].split():
+ root, discard = os.path.splitext(f)
+ mfile.write("\t-%s moc_%s.cpp\n" % (self.rm, root))
+
+ def ready(self):
+ """The Makefile is now ready to be used.
+ """
+ if not self._finalised:
+ self.finalise()
+
+ def generate(self):
+ """Generate the Makefile.
+ """
+ self.ready()
+
+ # Make sure the destination directory exists.
+ try:
+ os.makedirs(self.dir)
+ except:
+ pass
+
+ mfname = os.path.join(self.dir, self._makefile)
+
+ try:
+ mfile = open(mfname, "w")
+ except IOError:
+ error("Unable to create \"%s\"" % mfname)
+
+ self.generate_macros_and_rules(mfile)
+ self.generate_target_default(mfile)
+ self.generate_target_install(mfile)
+
+ if self._installs:
+ if type(self._installs) != list:
+ self._installs = [self._installs]
+
+ for src, dst in self._installs:
+ self.install_file(mfile, src, dst)
+
+ self.generate_target_clean(mfile)
+
+ mfile.close()
+
+ def generate_macros_and_rules(self, mfile):
+ """The default implementation of the macros and rules generation.
+
+ mfile is the file object.
+ """
+ mfile.write("CC = %s\n" % self.required_string("CC"))
+ mfile.write("CXX = %s\n" % self.required_string("CXX"))
+ mfile.write("LINK = %s\n" % self.required_string("LINK"))
+
+ cppflags = []
+
+ if not self._debug:
+ cppflags.append("-DNDEBUG")
+
+ for f in self.optional_list("DEFINES"):
+ cppflags.append("-D" + f)
+
+ for f in self.optional_list("INCDIR"):
+ cppflags.append("-I" + _quote(f))
+
+ libs = []
+
+ if self.generator in ("MSVC", "MSVC.NET"):
+ libdir_prefix = "/LIBPATH:"
+ else:
+ libdir_prefix = "-L"
+
+ for ld in self.optional_list("LIBDIR"):
+ if sys.platform == "darwin" and self.config.qt_framework:
+ fflag = "-F" + _quote(ld)
+ libs.append(fflag)
+ cppflags.append(fflag)
+
+ libs.append(libdir_prefix + _quote(ld))
+
+ libs.extend(self.optional_list("LIBS"))
+
+ mfile.write("CPPFLAGS = %s\n" % ' '.join(cppflags))
+
+ mfile.write("CFLAGS = %s\n" % self.optional_string("CFLAGS"))
+ mfile.write("CXXFLAGS = %s\n" % self.optional_string("CXXFLAGS"))
+ mfile.write("LFLAGS = %s\n" % self.optional_string("LFLAGS"))
+
+ mfile.write("LIBS = %s\n" % ' '.join(libs))
+
+ if self._qt:
+ mfile.write("MOC = %s\n" % _quote(self.required_string("MOC")))
+
+ if self._src_dir != self.dir:
+ mfile.write("VPATH = %s\n\n" % self._src_dir)
+
+ # These probably don't matter.
+ if self.generator == "MINGW":
+ mfile.write(".SUFFIXES: .cpp .cxx .cc .C .c\n\n")
+ elif self.generator == "UNIX":
+ mfile.write(".SUFFIXES: .c .o .cpp .cc .cxx .C\n\n")
+ else:
+ mfile.write(".SUFFIXES: .c .cpp .cc .cxx .C\n\n")
+
+ if self.generator in ("MSVC", "MSVC.NET"):
+ mfile.write("""
+{.}.cpp{}.obj::
+\t$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -Fo @<<
+\t$<
+<<
+
+{.}.cc{}.obj::
+\t$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -Fo @<<
+\t$<
+<<
+
+{.}.cxx{}.obj::
+\t$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -Fo @<<
+\t$<
+<<
+
+{.}.C{}.obj::
+\t$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -Fo @<<
+\t$<
+<<
+
+{.}.c{}.obj::
+\t$(CC) -c $(CFLAGS) $(CPPFLAGS) -Fo @<<
+\t$<
+<<
+""")
+ elif self.generator == "BMAKE":
+ mfile.write("""
+.cpp.obj:
+\t$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o$@ $<
+
+.cc.obj:
+\t$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o$@ $<
+
+.cxx.obj:
+\t$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o$@ $<
+
+.C.obj:
+\t$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o$@ $<
+
+.c.obj:
+\t$(CC) -c $(CFLAGS) $(CPPFLAGS) -o$@ $<
+""")
+ else:
+ mfile.write("""
+.cpp.o:
+\t$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ $<
+
+.cc.o:
+\t$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ $<
+
+.cxx.o:
+\t$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ $<
+
+.C.o:
+\t$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ $<
+
+.c.o:
+\t$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
+""")
+
+ def generate_target_default(self, mfile):
+ """The default implementation of the default target.
+
+ mfile is the file object.
+ """
+ mfile.write("\nall:\n")
+
+ def generate_target_install(self, mfile):
+ """The default implementation of the install target.
+
+ mfile is the file object.
+ """
+ mfile.write("\ninstall:\n")
+
+ def generate_target_clean(self, mfile):
+ """The default implementation of the clean target.
+
+ mfile is the file object.
+ """
+ mfile.write("\nclean:\n")
+
+ def install_file(self, mfile, src, dst, strip=0):
+ """Install one or more files in a directory.
+
+ mfile is the file object.
+ src is the name of a single file to install, or the list of a number of
+ files to install.
+ dst is the name of the destination directory.
+ strip is set if the files should be stripped after been installed.
+ """
+ # Help package builders.
+ if self.generator == "UNIX":
+ dst = "$(DESTDIR)" + dst
+
+ mfile.write("\t@%s %s " % (self.chkdir, _quote(dst)))
+
+ if self.generator == "UNIX":
+ mfile.write("|| ")
+
+ mfile.write("%s %s\n" % (self.mkdir, _quote(dst)))
+
+ if type(src) != list:
+ src = [src]
+
+ # Get the strip command if needed.
+ if strip:
+ strip_cmd = self.optional_string("STRIP")
+
+ if not strip_cmd:
+ strip = 0
+
+ for sf in src:
+ target = _quote(os.path.join(dst, os.path.basename(sf)))
+
+ mfile.write("\t%s %s %s\n" % (self.copy, _quote(sf), target))
+
+ if strip:
+ mfile.write("\t%s %s\n" % (strip_cmd, target))
+
+
+class ParentMakefile(Makefile):
+ """The class that represents a parent Makefile.
+ """
+ def __init__(self, configuration, subdirs, dir=None, makefile="Makefile",
+ installs=None):
+ """Initialise an instance of a parent Makefile.
+
+ subdirs is the sequence of subdirectories.
+ """
+ Makefile.__init__(self, configuration, dir=dir, makefile=makefile, installs=installs)
+
+ self._subdirs = subdirs
+
+ def generate_macros_and_rules(self, mfile):
+ """Generate the macros and rules.
+
+ mfile is the file object.
+ """
+ # We don't want them.
+ pass
+
+ def generate_target_default(self, mfile):
+ """Generate the default target.
+
+ mfile is the file object.
+ """
+ self._subdir_target(mfile)
+
+ def generate_target_install(self, mfile):
+ """Generate the install target.
+
+ mfile is the file object.
+ """
+ self._subdir_target(mfile, "install")
+
+ def generate_target_clean(self, mfile):
+ """Generate the clean target.
+
+ mfile is the file object.
+ """
+ self._subdir_target(mfile, "clean")
+
+ def _subdir_target(self, mfile, target="all"):
+ """Create a target for a list of sub-directories.
+
+ mfile is the file object.
+ target is the name of the target.
+ """
+ if target == "all":
+ tname = ""
+ else:
+ tname = " " + target
+
+ mfile.write("\n" + target + ":\n")
+
+ for d in self._subdirs:
+ if self.generator == "MINGW":
+ mfile.write("\t@$(MAKE) -C %s%s\n" % (d, tname))
+ elif self.generator == "UNIX":
+ mfile.write("\t@(cd %s; $(MAKE)%s)\n" % (d, tname))
+ else:
+ mfile.write("\tcd %s\n" % d)
+ mfile.write("\t$(MAKE)%s\n" % tname)
+ mfile.write("\t@cd ..\n")
+
+
+class PythonModuleMakefile(Makefile):
+ """The class that represents a Python module Makefile.
+ """
+ def __init__(self, configuration, dstdir, srcdir=None, dir=None,
+ makefile="Makefile", installs=None):
+ """Initialise an instance of a parent Makefile.
+
+ dstdir is the name of the directory where the module's Python code will
+ be installed.
+ srcdir is the name of the directory (relative to the directory in which
+ the Makefile will be created) containing the module's Python code. It
+ defaults to the same directory.
+ """
+ Makefile.__init__(self, configuration, dir=dir, makefile=makefile, installs=installs)
+
+ if not srcdir:
+ srcdir = "."
+
+ if dir:
+ self._moddir = os.path.join(dir, srcdir)
+ else:
+ self._moddir = srcdir
+
+ self._srcdir = srcdir
+ self._dstdir = dstdir
+
+ def generate_macros_and_rules(self, mfile):
+ """Generate the macros and rules.
+
+ mfile is the file object.
+ """
+ # We don't want them.
+ pass
+
+ def generate_target_install(self, mfile):
+ """Generate the install target.
+
+ mfile is the file object.
+ """
+ Makefile.generate_target_install(self, mfile)
+
+ for root, dirs, files in os.walk(self._moddir):
+ # Do not recurse into certain directories.
+ for skip in (".svn", "CVS"):
+ if skip in dirs:
+ dirs.remove(skip)
+
+ tail = root[len(self._moddir):]
+ flist = []
+
+ for f in files:
+ if f == "Makefile":
+ continue
+
+ if os.path.isfile(os.path.join(root, f)):
+ flist.append(os.path.join(self._srcdir + tail, f))
+
+ self.install_file(mfile, flist, self._dstdir + tail)
+
+
+class ModuleMakefile(Makefile):
+ """The class that represents a Python extension module Makefile
+ """
+ def __init__(self, configuration, build_file, install_dir=None, static=0,
+ console=0, qt=0, opengl=0, threaded=0, warnings=1, debug=0,
+ dir=None, makefile="Makefile", installs=None, strip=1,
+ export_all=0, universal=None, arch=None):
+ """Initialise an instance of a module Makefile.
+
+ build_file is the file containing the target specific information. If
+ it is a dictionary instead then its contents are validated.
+ install_dir is the directory the target will be installed in.
+ static is set if the module should be built as a static library.
+ strip is set if the module should be stripped of unneeded symbols when
+ installed. The default is 1.
+ export_all is set if all the module's symbols should be exported rather
+ than just the module's initialisation function. Exporting all symbols
+ increases the size of the module and slows down module load times but
+ may avoid problems with modules that use exceptions. The default is 0.
+ """
+ Makefile.__init__(self, configuration, console, qt, opengl, 1, threaded, warnings, debug, dir, makefile, installs, universal, arch)
+
+ self._build = self.parse_build_file(build_file)
+ self._install_dir = install_dir
+ self.static = static
+
+ self._manifest = ("embed_manifest_dll" in self.optional_list("CONFIG"))
+
+ # Don't strip or restrict the exports if this is a debug or static
+ # build.
+ if debug or static:
+ self._strip = 0
+ self._limit_exports = 0
+ else:
+ self._strip = strip
+ self._limit_exports = not export_all
+
+ # Save the target name for later.
+ self._target = self._build["target"]
+
+ # The name of the module entry point is Python version specific.
+ if self.config.py_version >= 0x030000:
+ self._entry_point = "PyInit_%s" % self._target
+ else:
+ self._entry_point = "init%s" % self._target
+
+ if sys.platform != "win32" and static:
+ self._target = "lib" + self._target
+
+ if sys.platform == "win32" and debug:
+ self._target = self._target + "_d"
+
+ def finalise(self):
+ """Finalise the macros common to all module Makefiles.
+ """
+ if self.console:
+ lflags_console = "LFLAGS_CONSOLE"
+ else:
+ lflags_console = "LFLAGS_WINDOWS"
+
+ if self.static:
+ self.DEFINES.append("SIP_STATIC_MODULE")
+ else:
+ self.CFLAGS.extend(self.optional_list("CFLAGS_SHLIB"))
+ self.CXXFLAGS.extend(self.optional_list("CXXFLAGS_SHLIB"))
+
+ lflags_dll = self.optional_list("LFLAGS_DLL")
+
+ if lflags_dll:
+ self.LFLAGS.extend(lflags_dll)
+ elif self.console:
+ lflags_console = "LFLAGS_CONSOLE_DLL"
+ else:
+ lflags_console = "LFLAGS_WINDOWS_DLL"
+
+ if self._manifest:
+ self._add_manifest()
+
+ # We use this to explictly create bundles on MacOS. Apple's Python
+ # can handle extension modules that are bundles or dynamic
+ # libraries, but python.org versions need bundles (unless built
+ # with DYNLOADFILE=dynload_shlib.o).
+ if sys.platform == "darwin":
+ lflags_plugin = ["-bundle"]
+ else:
+ lflags_plugin = self.optional_list("LFLAGS_PLUGIN")
+
+ if not lflags_plugin:
+ lflags_plugin = self.optional_list("LFLAGS_SHLIB")
+
+ self.LFLAGS.extend(lflags_plugin)
+
+ self.LFLAGS.extend(self.optional_list(lflags_console))
+
+ if sys.platform == "darwin":
+ # 'real_prefix' exists if virtualenv is being used.
+ dl = getattr(sys, 'real_prefix', sys.exec_prefix).split(os.sep)
+
+ if "Python.framework" not in dl:
+ error("SIP requires Python to be built as a framework")
+
+ self.LFLAGS.append("-undefined dynamic_lookup")
+
+ Makefile.finalise(self)
+
+ if not self.static:
+ if self.optional_string("AIX_SHLIB"):
+ # AIX needs a lot of special handling.
+ if self.required_string('LINK') == 'g++':
+ # g++ is used for linking.
+ # For SIP v4 and g++:
+ # 1.) Import the python symbols
+ aix_lflags = ['-Wl,-bI:%s/python.exp' % self.config.py_lib_dir]
+
+ if self._limit_exports:
+ aix_lflags.append('-Wl,-bnoexpall')
+ aix_lflags.append('-Wl,-bnoentry')
+ aix_lflags.append('-Wl,-bE:%s.exp' % self._target)
+ else:
+ # IBM VisualAge C++ is used for linking.
+ # For SIP v4 and xlC:
+ # 1.) Create a shared object
+ # 2.) Import the python symbols
+ aix_lflags = ['-qmkshrobj',
+ '-bI:%s/python.exp' % self.config.py_lib_dir]
+
+ if self._limit_exports:
+ aix_lflags.append('-bnoexpall')
+ aix_lflags.append('-bnoentry')
+ aix_lflags.append('-bE:%s.exp' % self._target)
+
+ self.LFLAGS.extend(aix_lflags)
+ else:
+ if self._limit_exports:
+ if sys.platform[:5] == 'linux':
+ self.LFLAGS.extend(['-Wl,--version-script=%s.exp' % self._target])
+ elif sys.platform[:5] == 'sunos':
+ if self.required_string('LINK') == 'g++':
+ self.LFLAGS.extend(['-Wl,-z,noversion', '-Wl,-M,%s.exp' % self._target])
+ else:
+ self.LFLAGS.extend(['-z' 'noversion', '-M', '%s.exp' % self._target])
+ elif sys.platform[:5] == 'hp-ux':
+ self.LFLAGS.extend(['-Wl,+e,%s' % self._entry_point])
+ elif sys.platform[:5] == 'irix' and self.required_string('LINK') != 'g++':
+ # Doesn't work when g++ is used for linking on IRIX.
+ self.LFLAGS.extend(['-Wl,-exported_symbol,%s' % self._entry_point])
+
+ # Force the shared linker if there is one.
+ link_shlib = self.optional_list("LINK_SHLIB")
+
+ if link_shlib:
+ self.LINK.set(link_shlib)
+
+ # This made an appearence in Qt v4.4rc1 and breaks extension modules so
+ # remove it. It was removed at my request but some stupid distros may
+ # have kept it.
+ self.LFLAGS.remove('-Wl,--no-undefined')
+
+ def module_as_lib(self, mname):
+ """Return the name of a SIP v3.x module when it is used as a library.
+ This will raise an exception when used with SIP v4.x modules.
+
+ mname is the name of the module.
+ """
+ raise ValueError("module_as_lib() can only be used with SIP v3.x")
+
+ def generate_macros_and_rules(self, mfile):
+ """Generate the macros and rules generation.
+
+ mfile is the file object.
+ """
+ if self.static:
+ if sys.platform == "win32":
+ ext = "lib"
+ else:
+ ext = "a"
+ else:
+ if sys.platform == "win32":
+ ext = "pyd"
+ elif sys.platform == "darwin":
+ ext = "so"
+ elif sys.platform == "cygwin":
+ ext = "dll"
+ else:
+ ext = self.optional_string("EXTENSION_PLUGIN")
+ if not ext:
+ ext = self.optional_string("EXTENSION_SHLIB", "so")
+
+ mfile.write("TARGET = %s\n" % (self._target + "." + ext))
+ mfile.write("OFILES = %s\n" % self._build["objects"])
+ mfile.write("HFILES = %s %s\n" % (self._build["headers"], self._build["moc_headers"]))
+ mfile.write("\n")
+
+ if self.static:
+ if self.generator in ("MSVC", "MSVC.NET", "BMAKE"):
+ mfile.write("LIB = %s\n" % self.required_string("LIB"))
+ elif self.generator == "MINGW":
+ mfile.write("AR = %s\n" % self.required_string("LIB"))
+ self._ranlib = None
+ else:
+ mfile.write("AR = %s\n" % self.required_string("AR"))
+
+ self._ranlib = self.optional_string("RANLIB")
+
+ if self._ranlib:
+ mfile.write("RANLIB = %s\n" % self._ranlib)
+
+ Makefile.generate_macros_and_rules(self, mfile)
+
+ def generate_target_default(self, mfile):
+ """Generate the default target.
+
+ mfile is the file object.
+ """
+ # Do these first so that it's safe for a sub-class to append additional
+ # commands to the real target, but make sure the default is correct.
+ mfile.write("\nall: $(TARGET)\n")
+ mfile.write("\n$(OFILES): $(HFILES)\n")
+
+ for mf in self._build["moc_headers"].split():
+ root, discard = os.path.splitext(mf)
+ cpp = "moc_" + root + ".cpp"
+
+ mfile.write("\n%s: %s\n" % (cpp, mf))
+ mfile.write("\t$(MOC) -o %s %s\n" % (cpp, mf))
+
+ mfile.write("\n$(TARGET): $(OFILES)\n")
+
+ if self.generator in ("MSVC", "MSVC.NET"):
+ if self.static:
+ mfile.write("\t$(LIB) /OUT:$(TARGET) @<<\n")
+ mfile.write("\t $(OFILES)\n")
+ mfile.write("<<\n")
+ else:
+ mfile.write("\t$(LINK) $(LFLAGS) /OUT:$(TARGET) @<<\n")
+ mfile.write("\t $(OFILES) $(LIBS)\n")
+ mfile.write("<<\n")
+
+ if self._manifest:
+ mfile.write("\tmt -nologo -manifest $(TARGET).manifest -outputresource:$(TARGET);2\n")
+ elif self.generator == "BMAKE":
+ if self.static:
+ mfile.write("\t-%s $(TARGET)\n" % (self.rm))
+ mfile.write("\t$(LIB) $(TARGET) @&&|\n")
+
+ for of in self._build["objects"].split():
+ mfile.write("+%s \\\n" % (of))
+
+ mfile.write("|\n")
+ else:
+ mfile.write("\t$(LINK) @&&|\n")
+ mfile.write("\t$(LFLAGS) $(OFILES) ,$(TARGET),,$(LIBS),%s\n" % (self._target))
+ mfile.write("|\n")
+
+ # Create the .def file that renames the entry point.
+ defname = os.path.join(self.dir, self._target + ".def")
+
+ try:
+ dfile = open(defname, "w")
+ except IOError:
+ error("Unable to create \"%s\"" % defname)
+
+ dfile.write("EXPORTS\n")
+ dfile.write("%s=_%s\n" % (self._entry_point, self._entry_point))
+
+ dfile.close()
+
+ else:
+ if self.static:
+ mfile.write("\t-%s $(TARGET)\n" % self.rm)
+ mfile.write("\t$(AR) $(TARGET) $(OFILES)\n")
+
+ if self._ranlib:
+ mfile.write("\t$(RANLIB) $(TARGET)\n")
+ else:
+ if self._limit_exports:
+ # Create an export file for AIX, Linux and Solaris.
+ if sys.platform[:5] == 'linux':
+ mfile.write("\t@echo '{ global: %s; local: *; };' > %s.exp\n" % (self._entry_point, self._target))
+ elif sys.platform[:5] == 'sunos':
+ mfile.write("\t@echo '{ global: %s; local: *; };' > %s.exp\n" % (self._entry_point, self._target))
+ elif sys.platform[:3] == 'aix':
+ mfile.write("\t@echo '#!' >%s.exp" % self._target)
+ mfile.write("; \\\n\t echo '%s' >>%s.exp\n" % (self._entry_point, self._target))
+
+ mfile.write("\t$(LINK) $(LFLAGS) -o $(TARGET) $(OFILES) $(LIBS)\n")
+
+ def generate_target_install(self, mfile):
+ """Generate the install target.
+
+ mfile is the file object.
+ """
+ if self._install_dir is None:
+ self._install_dir = self.config.default_mod_dir
+
+ mfile.write("\ninstall: $(TARGET)\n")
+ self.install_file(mfile, "$(TARGET)", self._install_dir, self._strip)
+
+ def generate_target_clean(self, mfile):
+ """Generate the clean target.
+
+ mfile is the file object.
+ """
+ mfile.write("\nclean:\n")
+ self.clean_build_file_objects(mfile, self._build)
+
+ if self._manifest and not self.static:
+ mfile.write("\t-%s $(TARGET).manifest\n" % self.rm)
+
+ # Remove any export file on AIX, Linux and Solaris.
+ if self._limit_exports and (sys.platform[:5] == 'linux' or
+ sys.platform[:5] == 'sunos' or
+ sys.platform[:3] == 'aix'):
+ mfile.write("\t-%s %s.exp\n" % (self.rm, self._target))
+
+
+class SIPModuleMakefile(ModuleMakefile):
+ """The class that represents a SIP generated module Makefile.
+ """
+ def __init__(self, configuration, build_file, install_dir=None, static=0,
+ console=0, qt=0, opengl=0, threaded=0, warnings=1, debug=0,
+ dir=None, makefile="Makefile", installs=None, strip=1,
+ export_all=0, universal=None, arch=None, prot_is_public=0):
+ """Initialise an instance of a SIP generated module Makefile.
+
+ prot_is_public is set if "protected" is to be redefined as "public".
+ If the platform's C++ ABI allows it this can significantly reduce the
+ size of the generated code.
+
+ For all other arguments see ModuleMakefile.
+ """
+ ModuleMakefile.__init__(self, configuration, build_file, install_dir,
+ static, console, qt, opengl, threaded, warnings, debug, dir,
+ makefile, installs, strip, export_all, universal, arch)
+
+ self._prot_is_public = prot_is_public
+
+ def finalise(self):
+ """Finalise the macros for a SIP generated module Makefile.
+ """
+ if self._prot_is_public:
+ self.DEFINES.append('SIP_PROTECTED_IS_PUBLIC')
+ self.DEFINES.append('protected=public')
+
+ self.INCDIR.append(self.config.sip_inc_dir)
+
+ ModuleMakefile.finalise(self)
+
+
+class ProgramMakefile(Makefile):
+ """The class that represents a program Makefile.
+ """
+ def __init__(self, configuration, build_file=None, install_dir=None,
+ console=0, qt=0, opengl=0, python=0, threaded=0, warnings=1,
+ debug=0, dir=None, makefile="Makefile", installs=None,
+ universal=None, arch=None):
+ """Initialise an instance of a program Makefile.
+
+ build_file is the file containing the target specific information. If
+ it is a dictionary instead then its contents are validated.
+ install_dir is the directory the target will be installed in.
+ """
+ Makefile.__init__(self, configuration, console, qt, opengl, python, threaded, warnings, debug, dir, makefile, installs, universal, arch)
+
+ self._install_dir = install_dir
+
+ self._manifest = ("embed_manifest_exe" in self.optional_list("CONFIG"))
+ self._target = None
+
+ if build_file:
+ self._build = self.parse_build_file(build_file)
+ else:
+ self._build = None
+
+ def build_command(self, source):
+ """Create a command line that will build an executable. Returns a
+ tuple of the name of the executable and the command line.
+
+ source is the name of the source file.
+ """
+ # The name of the executable.
+ self._target, _ = os.path.splitext(source)
+
+ if sys.platform in ("win32", "cygwin"):
+ exe = self._target + ".exe"
+ else:
+ exe = self._target
+
+ self.ready()
+
+ # The command line.
+ build = []
+
+ build.append(self.required_string("CXX"))
+
+ for a in self._arch.split():
+ build.append('-arch ' + a)
+
+ for f in self.optional_list("DEFINES"):
+ build.append("-D" + f)
+
+ for f in self.optional_list("INCDIR"):
+ build.append("-I" + _quote(f))
+
+ build.extend(self.optional_list("CXXFLAGS"))
+
+ # Borland requires all flags to precede all file names.
+ if self.generator != "BMAKE":
+ build.append(source)
+
+ if self.generator in ("MSVC", "MSVC.NET"):
+ build.append("-Fe")
+ build.append("/link")
+ libdir_prefix = "/LIBPATH:"
+ elif self.generator == "BMAKE":
+ build.append("-e" + exe)
+ libdir_prefix = "-L"
+ else:
+ build.append("-o")
+ build.append(exe)
+ libdir_prefix = "-L"
+
+ for ld in self.optional_list("LIBDIR"):
+ if sys.platform == "darwin" and self.config.qt_framework:
+ build.append("-F" + _quote(ld))
+
+ build.append(libdir_prefix + _quote(ld))
+
+ lflags = self.optional_list("LFLAGS")
+
+ # This is a huge hack demonstrating my lack of understanding of how the
+ # Borland compiler works.
+ if self.generator == "BMAKE":
+ blflags = []
+
+ for lf in lflags:
+ for f in lf.split():
+ # Tell the compiler to pass the flags to the linker.
+ if f[-1] == "-":
+ f = "-l-" + f[1:-1]
+ elif f[0] == "-":
+ f = "-l" + f[1:]
+
+ # Remove any explicit object files otherwise the compiler
+ # will complain that they can't be found, but they don't
+ # seem to be needed.
+ if f[-4:].lower() != ".obj":
+ blflags.append(f)
+
+ lflags = blflags
+
+ build.extend(lflags)
+
+ build.extend(self.optional_list("LIBS"))
+
+ if self.generator == "BMAKE":
+ build.append(source)
+
+ return (exe, ' '.join(build))
+
+ def finalise(self):
+ """Finalise the macros for a program Makefile.
+ """
+ if self.generator in ("MSVC", "MSVC.NET"):
+ self.LFLAGS.append("/INCREMENTAL:NO")
+
+ if self._manifest:
+ self._add_manifest(self._target)
+
+ if self.console:
+ lflags_console = "LFLAGS_CONSOLE"
+ else:
+ lflags_console = "LFLAGS_WINDOWS"
+
+ self.LFLAGS.extend(self.optional_list(lflags_console))
+
+ Makefile.finalise(self)
+
+ def generate_macros_and_rules(self, mfile):
+ """Generate the macros and rules generation.
+
+ mfile is the file object.
+ """
+ if not self._build:
+ raise ValueError("pass a filename as build_file when generating a Makefile")
+
+ target = self._build["target"]
+
+ if sys.platform in ("win32", "cygwin"):
+ target = target + ".exe"
+
+ mfile.write("TARGET = %s\n" % target)
+ mfile.write("OFILES = %s\n" % self._build["objects"])
+ mfile.write("HFILES = %s\n" % self._build["headers"])
+ mfile.write("\n")
+
+ Makefile.generate_macros_and_rules(self, mfile)
+
+ def generate_target_default(self, mfile):
+ """Generate the default target.
+
+ mfile is the file object.
+ """
+ # Do these first so that it's safe for a sub-class to append additional
+ # commands to the real target, but make sure the default is correct.
+ mfile.write("\nall: $(TARGET)\n")
+ mfile.write("\n$(OFILES): $(HFILES)\n")
+
+ for mf in self._build["moc_headers"].split():
+ root, _ = os.path.splitext(mf)
+ cpp = "moc_" + root + ".cpp"
+
+ if self._src_dir != self.dir:
+ mf = os.path.join(self._src_dir, mf)
+
+ mfile.write("\n%s: %s\n" % (cpp, mf))
+ mfile.write("\t$(MOC) -o %s %s\n" % (cpp, mf))
+
+ mfile.write("\n$(TARGET): $(OFILES)\n")
+
+ if self.generator in ("MSVC", "MSVC.NET"):
+ mfile.write("\t$(LINK) $(LFLAGS) /OUT:$(TARGET) @<<\n")
+ mfile.write("\t $(OFILES) $(LIBS)\n")
+ mfile.write("<<\n")
+ elif self.generator == "BMAKE":
+ mfile.write("\t$(LINK) @&&|\n")
+ mfile.write("\t$(LFLAGS) $(OFILES) ,$(TARGET),,$(LIBS),,\n")
+ mfile.write("|\n")
+ else:
+ mfile.write("\t$(LINK) $(LFLAGS) -o $(TARGET) $(OFILES) $(LIBS)\n")
+
+ if self._manifest:
+ mfile.write("\tmt -nologo -manifest $(TARGET).manifest -outputresource:$(TARGET);1\n")
+
+ def generate_target_install(self, mfile):
+ """Generate the install target.
+
+ mfile is the file object.
+ """
+ if self._install_dir is None:
+ self._install_dir = self.config.default_bin_dir
+
+ mfile.write("\ninstall: $(TARGET)\n")
+ self.install_file(mfile, "$(TARGET)", self._install_dir)
+
+ def generate_target_clean(self, mfile):
+ """Generate the clean target.
+
+ mfile is the file object.
+ """
+ mfile.write("\nclean:\n")
+ self.clean_build_file_objects(mfile, self._build)
+
+ if self._manifest:
+ mfile.write("\t-%s $(TARGET).manifest\n" % self.rm)
+
+
+def _quote(s):
+ """Return a string surrounded by double quotes it if contains a space.
+
+ s is the string.
+ """
+ if s.find(" ") >= 0:
+ s = '"' + s + '"'
+
+ return s
+
+
+def version_to_string(v):
+ """Convert a 3 part version number encoded as a hexadecimal value to a
+ string.
+ """
+ return "%u.%u.%u" % (((v >> 16) & 0xff), ((v >> 8) & 0xff), (v & 0xff))
+
+
+def read_version(filename, description, numdefine=None, strdefine=None):
+ """Read the version information for a package from a file. The information
+ is specified as #defines of a numeric (hexadecimal or decimal) value and/or
+ a string value.
+
+ filename is the name of the file.
+ description is the descriptive name of the package.
+ numdefine is the name of the #define of the numeric version. It is ignored
+ if it is None.
+ strdefine is the name of the #define of the string version. It is ignored
+ if it is None.
+
+ Returns a tuple of the version as a number and as a string.
+ """
+ need_num = numdefine is not None
+ need_str = strdefine is not None
+
+ vers = None
+ versstr = None
+
+ f = open(filename)
+ l = f.readline()
+
+ while l and (need_num or need_str):
+ wl = l.split()
+ if len(wl) >= 3 and wl[0] == "#define":
+ if need_num and wl[1] == numdefine:
+ v = wl[2]
+
+ if v[0:2] == "0x":
+ vers = int(v, 16)
+ else:
+ dec = int(v)
+ maj = dec / 100
+ min = (dec % 100) / 10
+ bug = (dec % 10)
+ vers = (maj << 16) + (min << 8) + bug
+
+ need_num = 0
+
+ if need_str and wl[1] == strdefine:
+ # Take account of embedded spaces.
+ versstr = ' '.join(wl[2:])[1:-1]
+ need_str = 0
+
+ l = f.readline()
+
+ f.close()
+
+ if need_num or need_str:
+ error("The %s version number could not be determined by parsing %s." % (description, filename))
+
+ return (vers, versstr)
+
+
+def create_content(cdict, macros=None):
+ """Convert a dictionary to a string (typically to use as the content to a
+ call to create_config_module()). Dictionary values that are strings are
+ quoted. Dictionary values that are lists are converted to quoted strings.
+
+ dict is the dictionary.
+ macros is the optional dictionary of platform specific build macros.
+ """
+ content = "_pkg_config = {\n"
+
+ keys = list(cdict.keys())
+ keys.sort()
+
+ # Format it nicely.
+ width = 0
+
+ for k in keys:
+ klen = len(k)
+
+ if width < klen:
+ width = klen
+
+ for k in keys:
+ val = cdict[k]
+ vtype = type(val)
+ delim = None
+
+ if val is None:
+ val = "None"
+ elif vtype == list:
+ val = ' '.join(val)
+ delim = "'"
+ elif vtype == int:
+ if k.find("version") >= 0:
+ # Assume it's a hexadecimal version number. It doesn't matter
+ # if it isn't, we are just trying to make it look pretty.
+ val = "0x%06x" % val
+ else:
+ val = str(val)
+ else:
+ val = str(val)
+ delim = "'"
+
+ if delim:
+ if "'" in val:
+ delim = "'''"
+
+ val = delim + val + delim
+
+ content = content + " '" + k + "':" + (" " * (width - len(k) + 2)) + val.replace("\\", "\\\\")
+
+ if k != keys[-1]:
+ content = content + ","
+
+ content = content + "\n"
+
+ content = content + "}\n\n"
+
+ # Format the optional macros.
+ content = content + "_default_macros = "
+
+ if macros:
+ content = content + "{\n"
+
+ names = list(macros.keys())
+ names.sort()
+
+ width = 0
+ for c in names:
+ clen = len(c)
+ if width < clen:
+ width = clen
+
+ for c in names:
+ if c == names[-1]:
+ sep = ""
+ else:
+ sep = ","
+
+ val = macros[c]
+ if "'" in val:
+ delim = "'''"
+ else:
+ delim = "'"
+
+ k = "'" + c + "':"
+ content = content + " %-*s %s%s%s%s\n" % (1 + width + 2, k, delim, val.replace("\\", "\\\\"), delim, sep)
+
+ content = content + "}\n"
+ else:
+ content = content + "None\n"
+
+ return content
+
+
+def create_config_module(module, template, content, macros=None):
+ """Create a configuration module by replacing "@" followed by
+ "SIP_CONFIGURATION" followed by "@" in a template file with a content
+ string.
+
+ module is the name of the module file.
+ template is the name of the template file.
+ content is the content string. If it is a dictionary it is first converted
+ to a string using create_content().
+ macros is an optional dictionary of platform specific build macros. It is
+ only used if create_content() is called to convert the content to a string.
+ """
+ if type(content) == dict:
+ content = create_content(content, macros)
+
+ # Allow this file to used as a template.
+ key = "@" + "SIP_CONFIGURATION" + "@"
+
+ df = open(module, "w")
+ sf = open(template, "r")
+
+ line = sf.readline()
+ while line:
+ if line.find(key) >= 0:
+ line = content
+
+ df.write(line)
+
+ line = sf.readline()
+
+
+def version_to_sip_tag(version, tags, description):
+ """Convert a version number to a SIP tag.
+
+ version is the version number. If it is negative then the latest version
+ is assumed. (This is typically useful if a snapshot is indicated by a
+ negative version number.)
+ tags is the dictionary of tags keyed by version number. The tag used is
+ the one with the smallest key (ie. earliest version) that is greater than
+ the given version number.
+ description is the descriptive name of the package used for error messages.
+
+ Returns the corresponding tag.
+ """
+ vl = list(tags.keys())
+ vl.sort()
+
+ # For a snapshot use the latest tag.
+ if version < 0:
+ tag = tags[vl[-1]]
+ else:
+ for v in vl:
+ if version < v:
+ tag = tags[v]
+ break
+ else:
+ error("Unsupported %s version: 0x%06x." % (description, version))
+
+ return tag
+
+
+def error(msg):
+ """Display an error message and terminate.
+
+ msg is the text of the error message.
+ """
+ sys.stderr.write(format("Error: " + msg) + "\n")
+ sys.exit(1)
+
+
+def inform(msg):
+ """Display an information message.
+
+ msg is the text of the error message.
+ """
+ sys.stdout.write(format(msg) + "\n")
+
+
+def format(msg, leftmargin=0, rightmargin=78):
+ """Format a message by inserting line breaks at appropriate places.
+
+ msg is the text of the message.
+ leftmargin is the position of the left margin.
+ rightmargin is the position of the right margin.
+
+ Return the formatted message.
+ """
+ curs = leftmargin
+ fmsg = " " * leftmargin
+
+ for w in msg.split():
+ l = len(w)
+ if curs != leftmargin and curs + l > rightmargin:
+ fmsg = fmsg + "\n" + (" " * leftmargin)
+ curs = leftmargin
+
+ if curs > leftmargin:
+ fmsg = fmsg + " "
+ curs = curs + 1
+
+ fmsg = fmsg + w
+ curs = curs + l
+
+ return fmsg
+
+
+def parse_build_macros(filename, names, overrides=None, properties=None):
+ """Parse a qmake compatible file of build system macros and convert it to a
+ dictionary. A macro is a name/value pair. The dictionary is returned or
+ None if any of the overrides was invalid.
+
+ filename is the name of the file to parse.
+ names is a list of the macro names to extract from the file.
+ overrides is an optional list of macro names and values that modify those
+ found in the file. They are of the form "name=value" (in which case the
+ value replaces the value found in the file) or "name+=value" (in which case
+ the value is appended to the value found in the file).
+ properties is an optional dictionary of property name and values that are
+ used to resolve any expressions of the form "$[name]" in the file.
+ """
+ # Validate and convert the overrides to a dictionary.
+ orides = {}
+
+ if overrides is not None:
+ for oride in overrides:
+ prefix = ""
+ name_end = oride.find("+=")
+
+ if name_end >= 0:
+ prefix = "+"
+ val_start = name_end + 2
+ else:
+ name_end = oride.find("=")
+
+ if name_end >= 0:
+ val_start = name_end + 1
+ else:
+ return None
+
+ name = oride[:name_end]
+
+ if name not in names:
+ return None
+
+ orides[name] = prefix + oride[val_start:]
+
+ # This class defines a file like object that handles the nested include()
+ # directives in qmake files.
+ class qmake_build_file_reader:
+ def __init__(self, filename):
+ self.filename = filename
+ self.currentfile = None
+ self.filestack = []
+ self.pathstack = []
+ self.cond_fname = None
+ self._openfile(filename)
+
+ def _openfile(self, filename):
+ try:
+ f = open(filename, 'r')
+ except IOError:
+ # If this file is conditional then don't raise an error.
+ if self.cond_fname == filename:
+ return
+
+ error("Unable to open %s" % filename)
+
+ if self.currentfile:
+ self.filestack.append(self.currentfile)
+ self.pathstack.append(self.path)
+
+ self.currentfile = f
+ self.path = os.path.dirname(filename)
+
+ def readline(self):
+ line = self.currentfile.readline()
+ sline = line.strip()
+
+ if self.cond_fname and sline == '}':
+ # The current condition is closed.
+ self.cond_fname = None
+ line = self.currentfile.readline()
+ elif sline.startswith('exists(') and sline.endswith('{'):
+ # A new condition is opened so extract the filename.
+ self.cond_fname = self._normalise(sline[:-1].strip()[7:-1].strip())
+ line = self.currentfile.readline()
+ elif sline.startswith('include('):
+ nextfile = self._normalise(sline[8:-1].strip())
+ self._openfile(nextfile)
+ return self.readline()
+
+ if not line and self.filestack:
+ self.currentfile = self.filestack.pop()
+ self.path = self.pathstack.pop()
+ return self.readline()
+
+ return line
+
+ # Normalise a filename by expanding any environment variables and
+ # making sure it is absolute.
+ def _normalise(self, fname):
+ if "$(" in fname:
+ fname = os.path.normpath(self._expandvars(fname))
+
+ if not os.path.isabs(fname):
+ fname = os.path.join(self.path, fname)
+
+ return fname
+
+ # Expand the environment variables in a filename.
+ def _expandvars(self, fname):
+ i = 0
+ while True:
+ m = re.search(r'\$\((\w+)\)', fname[i:])
+ if not m:
+ break
+
+ i, j = m.span(0)
+ name = m.group(1)
+ if name in os.environ:
+ tail = fname[j:]
+ fname = fname[:i] + os.environ[name]
+ i = len(fname)
+ fname += tail
+ else:
+ i = j
+
+ return fname
+
+ f = qmake_build_file_reader(filename)
+
+ # Get everything into a dictionary.
+ raw = {
+ "DIR_SEPARATOR": os.sep,
+ "LITERAL_WHITESPACE": " ",
+ "LITERAL_DOLLAR": "$",
+ "LITERAL_HASH": "#"
+ }
+
+ line = f.readline()
+ while line:
+ # Handle line continuations.
+ while len(line) > 1 and line[-2] == "\\":
+ line = line[:-2]
+
+ next = f.readline()
+
+ if next:
+ line = line + next
+ else:
+ break
+
+ line = line.strip()
+
+ # Ignore comments.
+ if line and line[0] != "#":
+ assstart = line.find("+")
+ if assstart > 0 and line[assstart + 1] == '=':
+ adding = True
+ assend = assstart + 1
+ else:
+ adding = False
+ assstart = line.find("=")
+ assend = assstart
+
+ if assstart > 0:
+ lhs = line[:assstart].strip()
+ rhs = line[assend + 1:].strip()
+
+ # Remove the escapes for any quotes.
+ rhs = rhs.replace(r'\"', '"').replace(r"\'", "'")
+
+ if adding and rhs != "":
+ orig_rhs = raw.get(lhs)
+ if orig_rhs is not None:
+ rhs = orig_rhs + " " + rhs
+
+ raw[lhs] = rhs
+
+ line = f.readline()
+
+ # Go through the raw dictionary extracting the macros we need and
+ # resolving any macro expansions. First of all, make sure every macro has
+ # a value.
+ refined = {}
+
+ for m in names:
+ refined[m] = ""
+
+ macro_prefix = "QMAKE_"
+
+ for lhs in list(raw.keys()):
+ # Strip any prefix.
+ if lhs.find(macro_prefix) == 0:
+ reflhs = lhs[len(macro_prefix):]
+ else:
+ reflhs = lhs
+
+ # See if we are interested in this one.
+ if reflhs not in names:
+ continue
+
+ rhs = raw[lhs]
+
+ # Resolve any references.
+ estart = rhs.find("$$(")
+ mstart = rhs.find("$$")
+
+ while mstart >= 0 and mstart != estart:
+ rstart = mstart + 2
+ if rstart < len(rhs) and rhs[rstart] == "{":
+ rstart = rstart + 1
+ term = "}"
+ elif rstart < len(rhs) and rhs[rstart] == "[":
+ rstart = rstart + 1
+ term = "]"
+ else:
+ term = string.whitespace
+
+ mend = rstart
+ while mend < len(rhs) and rhs[mend] not in term:
+ mend = mend + 1
+
+ lhs = rhs[rstart:mend]
+
+ if term in "}]":
+ mend = mend + 1
+
+ if term == "]":
+ if properties is None or lhs not in list(properties.keys()):
+ error("%s: property '%s' is not defined." % (filename, lhs))
+
+ value = properties[lhs]
+ else:
+ try:
+ value = raw[lhs]
+ except KeyError:
+ # We used to treat this as an error, but Qt v4.3.0 has at
+ # least one case that refers to an undefined macro. If
+ # qmake handles it then this must be the correct behaviour.
+ value = ""
+
+ rhs = rhs[:mstart] + value + rhs[mend:]
+ estart = rhs.find("$$(")
+ mstart = rhs.find("$$")
+
+ # Expand any POSIX style environment variables.
+ pleadin = ["$$(", "$("]
+
+ for pl in pleadin:
+ estart = rhs.find(pl)
+
+ if estart >= 0:
+ nstart = estart + len(pl)
+ break
+ else:
+ estart = -1
+
+ while estart >= 0:
+ eend = rhs[nstart:].find(")")
+
+ if eend < 0:
+ break
+
+ eend = nstart + eend
+
+ name = rhs[nstart:eend]
+
+ try:
+ env = os.environ[name]
+ except KeyError:
+ env = ""
+
+ rhs = rhs[:estart] + env + rhs[eend + 1:]
+
+ for pl in pleadin:
+ estart = rhs.find(pl)
+
+ if estart >= 0:
+ nstart = estart + len(pl)
+ break
+ else:
+ estart = -1
+
+ # Expand any Windows style environment variables.
+ estart = rhs.find("%")
+
+ while estart >= 0:
+ eend = rhs[estart + 1:].find("%")
+
+ if eend < 0:
+ break
+
+ eend = estart + 1 + eend
+
+ name = rhs[estart + 1:eend]
+
+ try:
+ env = os.environ[name]
+ except KeyError:
+ env = ""
+
+ rhs = rhs[:estart] + env + rhs[eend + 1:]
+
+ estart = rhs.find("%")
+
+ refined[reflhs] = rhs
+
+ # Handle the user overrides.
+ for lhs in list(orides.keys()):
+ rhs = refined[lhs]
+ oride = orides[lhs]
+
+ if oride.find("+") == 0:
+ if rhs:
+ rhs = rhs + " " + oride[1:]
+ else:
+ rhs = oride[1:]
+ else:
+ rhs = oride
+
+ refined[lhs] = rhs
+
+ return refined
+
+
+def create_wrapper(script, wrapper, gui=0, use_arch=''):
+ """Create a platform dependent executable wrapper around a Python script.
+
+ script is the full pathname of the script.
+ wrapper is the name of the wrapper file to create.
+ gui is non-zero if a GUI enabled version of the interpreter should be used.
+ use_arch is the MacOS/X architecture to invoke python with.
+
+ Returns the platform specific name of the wrapper.
+ """
+ if sys.platform == "win32":
+ wrapper = wrapper + ".bat"
+
+ wf = open(wrapper, "w")
+
+ if sys.platform == "win32":
+ exe = sys.executable
+
+ if gui:
+ exe = exe[:-4] + "w.exe"
+
+ wf.write("@\"%s\" \"%s\" %%1 %%2 %%3 %%4 %%5 %%6 %%7 %%8 %%9\n" % (exe, script))
+ elif sys.platform == "darwin":
+ # The installation of MacOS's python is a mess that changes from
+ # version to version and where sys.executable is useless.
+
+ if gui:
+ exe = "pythonw"
+ else:
+ exe = "python"
+
+ version = sys.version_info
+ exe = "%s%d.%d" % (exe, version[0], version[1])
+
+ if use_arch:
+ # Note that this may not work with the "standard" interpreter but
+ # should with the "pythonX.Y" version.
+ exe = "arch -%s %s" % (use_arch, exe)
+
+ wf.write("#!/bin/sh\n")
+ wf.write("exec %s %s ${1+\"$@\"}\n" % (exe, script))
+ else:
+ wf.write("#!/bin/sh\n")
+ wf.write("exec %s %s ${1+\"$@\"}\n" % (sys.executable, script))
+
+ wf.close()
+
+ if sys.platform != "win32":
+ sbuf = os.stat(wrapper)
+ mode = sbuf.st_mode
+ mode |= (stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
+
+ os.chmod(wrapper, mode)
+
+ return wrapper
diff --git a/siputils.py.orig b/siputils.py.orig
new file mode 100644
index 0000000..304e0f4
--- /dev/null
+++ b/siputils.py.orig
@@ -0,0 +1,2528 @@
+# This module is intended to be used by the build/installation scripts of
+# extension modules created with SIP. It provides information about file
+# locations, version numbers etc., and provides some classes and functions.
+#
+# Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com>
+#
+# This file is part of SIP.
+#
+# This copy of SIP is licensed for use under the terms of the SIP License
+# Agreement. See the file LICENSE for more details.
+#
+# This copy of SIP may also used under the terms of the GNU General Public
+# License v2 or v3 as published by the Free Software Foundation which can be
+# found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
+#
+# SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+
+import sys
+import os
+import stat
+import string
+import re
+
+
+# These are installation specific values created when SIP was configured.
+# @SIP_CONFIGURATION@
+
+# The stack of configuration dictionaries.
+_config_stack = []
+
+
+class Configuration(object):
+ """The class that represents SIP configuration values.
+ """
+ def __init__(self, sub_cfg=None):
+ """Initialise an instance of the class.
+
+ sub_cfg is the list of sub-class configurations. It should be None
+ when called normally.
+ """
+ # Find the build macros in the closest imported module from where this
+ # was originally defined.
+ self._macros = None
+
+ for cls in self.__class__.__mro__:
+ if cls is object:
+ continue
+
+ mod = sys.modules[cls.__module__]
+
+ if hasattr(mod, "_default_macros"):
+ self._macros = mod._default_macros
+ break
+
+ if sub_cfg:
+ cfg = sub_cfg
+ else:
+ cfg = []
+
+ cfg.append(_pkg_config)
+
+ global _config_stack
+ _config_stack = cfg
+
+ def __getattr__(self, name):
+ """Allow configuration values and user options to be handled as
+ instance variables.
+
+ name is the name of the configuration value or user option.
+ """
+ for cfg in _config_stack:
+ try:
+ return cfg[name]
+ except KeyError:
+ pass
+
+ raise AttributeError("\"%s\" is not a valid configuration value or user option" % name)
+
+ def build_macros(self):
+ """Return the dictionary of platform specific build macros.
+ """
+ return self._macros
+
+ def set_build_macros(self, macros):
+ """Set the dictionary of build macros to be use when generating
+ Makefiles.
+
+ macros is the dictionary of platform specific build macros.
+ """
+ self._macros = macros
+
+
+class _UniqueList:
+ """A limited list that ensures all its elements are unique.
+ """
+ def __init__(self, value=None):
+ """Initialise the instance.
+
+ value is the initial value of the list.
+ """
+ if value is None:
+ self._list = []
+ else:
+ self._list = value
+
+ def append(self, value):
+ """Append a value to the list if it isn't already present.
+
+ value is the value to append.
+ """
+ if value not in self._list:
+ self._list.append(value)
+
+ def lextend(self, value):
+ """A normal list extend ignoring the uniqueness.
+
+ value is the list of elements to append.
+ """
+ self._list.extend(value)
+
+ def extend(self, value):
+ """Append each element of a value to a list if it isn't already
+ present.
+
+ value is the list of elements to append.
+ """
+ for el in value:
+ self.append(el)
+
+ def as_list(self):
+ """Return the list as a raw list.
+ """
+ return self._list
+
+
+class _Macro:
+ """A macro that can be manipulated as a list.
+ """
+ def __init__(self, name, value):
+ """Initialise the instance.
+
+ name is the name of the macro.
+ value is the initial value of the macro.
+ """
+ self._name = name
+ self.set(value)
+
+ def set(self, value):
+ """Explicitly set the value of the macro.
+
+ value is the new value. It may be a string, a list of strings or a
+ _UniqueList instance.
+ """
+ self._macro = []
+
+ if isinstance(value, _UniqueList):
+ value = value.as_list()
+
+ if type(value) == list:
+ self.extend(value)
+ else:
+ self.append(value)
+
+ def append(self, value):
+ """Append a value to the macro.
+
+ value is the value to append.
+ """
+ if value:
+ self._macro.append(value)
+
+ def extend(self, value):
+ """Append each element of a value to the macro.
+
+ value is the list of elements to append.
+ """
+ for el in value:
+ self.append(el)
+
+ def remove(self, value):
+ """Remove a value from the macro. It doesn't matter if the value
+ wasn't present.
+
+ value is the value to remove.
+ """
+ try:
+ self._macro.remove(value)
+ except:
+ pass
+
+ def as_list(self):
+ """Return the macro as a list.
+ """
+ return self._macro
+
+
+class Makefile:
+ """The base class for the different types of Makefiles.
+ """
+ def __init__(self, configuration, console=0, qt=0, opengl=0, python=0,
+ threaded=0, warnings=1, debug=0, dir=None,
+ makefile="Makefile", installs=None, universal=None,
+ arch=None):
+ """Initialise an instance of the target. All the macros are left
+ unchanged allowing scripts to manipulate them at will.
+
+ configuration is the current configuration.
+ console is set if the target is a console (rather than windows) target.
+ qt is set if the target uses Qt. For Qt v4 a list of Qt libraries may
+ be specified and a simple non-zero value implies QtCore and QtGui.
+ opengl is set if the target uses OpenGL.
+ python is set if the target #includes Python.h.
+ debug is set to generated a debugging version of the target.
+ threaded is set if the target requires thread support. It is
+ automatically set if the target uses Qt and Qt has thread support
+ enabled.
+ warnings is set if compiler warning messages are required.
+ debug is set if debugging symbols should be generated.
+ dir is the directory for build files and Makefiles.
+ makefile is the name of the Makefile.
+ installs is a list of extra install targets. Each element is a two
+ part list, the first of which is the source and the second is the
+ destination. If the source is another list then it is a set of source
+ files and the destination is a directory.
+ universal is the name of the SDK if the target is a MacOS/X universal
+ binary. If it is None then the value is taken from the configuration.
+ arch is the space separated MacOS/X architectures to build. If it is
+ None then it is taken from the configuration.
+ """
+ if qt:
+ if not hasattr(configuration, "qt_version"):
+ error("The target uses Qt but pyqtconfig has not been imported.")
+
+ # For Qt v4 interpret Qt support as meaning link against the core
+ # and GUI libraries (which corresponds to the default qmake
+ # configuration). Also allow a list of Qt v4 modules to be
+ # specified.
+ if configuration.qt_version >= 0x040000:
+ if type(qt) != list:
+ qt = ["QtCore", "QtGui"]
+
+ self._threaded = configuration.qt_threaded
+ else:
+ self._threaded = threaded
+
+ self.config = configuration
+ self.console = console
+ self._qt = qt
+ self._opengl = opengl
+ self._python = python
+ self._warnings = warnings
+ self._debug = debug
+ self._makefile = makefile
+ self._installs = installs
+
+ # Make sure the destination directory is an absolute path.
+ if dir:
+ self.dir = os.path.abspath(dir)
+ else:
+ self.dir = os.path.curdir
+
+ # Assume we are building in the source tree.
+ self._src_dir = self.dir
+
+ if universal is None:
+ self._universal = configuration.universal
+ else:
+ self._universal = universal
+
+ if arch is None:
+ self._arch = configuration.arch
+ else:
+ self._arch = arch
+
+ self._finalised = 0
+
+ # Copy the macros and convert them all to instance lists.
+ macros = configuration.build_macros()
+
+ for m in list(macros.keys()):
+ # Allow the user to override the default.
+ try:
+ val = getattr(configuration, m)
+ except AttributeError:
+ val = macros[m]
+
+ # These require special handling as they are (potentially) a set of
+ # space separated values rather than a single value that might
+ # contain spaces.
+ if m in ("DEFINES", "CONFIG") or m[:6] in ("INCDIR", "LIBDIR"):
+ val = val.split()
+
+ # We also want to treat lists of libraries in the same way so that
+ # duplicates get eliminated.
+ if m[:4] == "LIBS":
+ val = val.split()
+
+ self.__dict__[m] = _Macro(m, val)
+
+ # This is used to alter the configuration more significantly than can
+ # be done with just configuration files.
+ self.generator = self.optional_string("MAKEFILE_GENERATOR", "UNIX")
+
+ # These are what configuration scripts normally only need to change.
+ self.extra_cflags = []
+ self.extra_cxxflags = []
+ self.extra_defines = []
+ self.extra_include_dirs = []
+ self.extra_lflags = []
+ self.extra_lib_dirs = []
+ self.extra_libs = []
+
+ # Get these once and make them available to sub-classes.
+ if sys.platform == "win32":
+ def_copy = "copy"
+ def_rm = "del"
+ def_mkdir = "mkdir"
+ def_chk_dir_exists = "if not exist"
+ else:
+ def_copy = "cp -f"
+ def_rm = "rm -f"
+ def_mkdir = "mkdir -p"
+ def_chk_dir_exists = "test -d"
+
+ self.copy = self.optional_string("COPY", def_copy)
+ self.rm = self.optional_string("DEL_FILE", def_rm)
+ self.mkdir = self.optional_string("MKDIR", def_mkdir)
+ self.chkdir = self.optional_string("CHK_DIR_EXISTS", def_chk_dir_exists)
+
+
+ def finalise(self):
+ """Finalise the macros by doing any consolidation that isn't specific
+ to a Makefile.
+ """
+ # Extract the things we might need from the Windows Qt configuration.
+ # Note that we used to think that if Qt was built with exceptions, RTTI
+ # and STL support enabled then anything that linked against it also
+ # needed the same flags. However, detecting this was broken for some
+ # time and nobody complained. For the moment we'll leave the code in
+ # but it will never be used.
+ if self._qt:
+ wcfg = self.config.qt_winconfig.split()
+ win_shared = ("shared" in wcfg)
+ win_exceptions = ("exceptions" in wcfg)
+ win_rtti = ("rtti" in wcfg)
+ win_stl = ("stl" in wcfg)
+ else:
+ win_shared = 1
+ win_exceptions = 0
+ win_rtti = 0
+ win_stl = 0
+
+ # Get what we are going to transform.
+ cflags = _UniqueList()
+ cflags.extend(self.extra_cflags)
+ cflags.extend(self.optional_list("CFLAGS"))
+
+ cxxflags = _UniqueList()
+ cxxflags.extend(self.extra_cxxflags)
+ cxxflags.extend(self.optional_list("CXXFLAGS"))
+
+ defines = _UniqueList()
+ defines.extend(self.extra_defines)
+ defines.extend(self.optional_list("DEFINES"))
+
+ incdir = _UniqueList(["."])
+ incdir.extend(self.extra_include_dirs)
+ incdir.extend(self.optional_list("INCDIR"))
+
+ lflags = _UniqueList()
+ lflags.extend(self.extra_lflags)
+ lflags.extend(self.optional_list("LFLAGS"))
+
+ libdir = _UniqueList()
+ libdir.extend(self.extra_lib_dirs)
+ libdir.extend(self.optional_list("LIBDIR"))
+
+ # Handle MacOS/X specific configuration.
+ if sys.platform == 'darwin':
+ mac_cflags = []
+ mac_lflags = []
+
+ for a in self._arch.split():
+ aflag = '-arch ' + a
+ mac_cflags.append(aflag)
+ mac_lflags.append(aflag)
+
+ if self._universal:
+ mac_cflags.append('-isysroot %s' % self._universal)
+ mac_lflags.append('-Wl,-syslibroot,%s' % self._universal)
+
+ cflags.lextend(mac_cflags)
+ cxxflags.lextend(mac_cflags)
+ lflags.lextend(mac_lflags)
+
+ # Don't use a unique list as libraries may need to be searched more
+ # than once. Also MacOS/X uses the form "-framework lib" so we don't
+ # want to lose the multiple "-framework".
+ libs = []
+
+ for l in self.extra_libs:
+ libs.append(self.platform_lib(l))
+
+ if self._qt:
+ libs.extend(self._dependent_libs(l))
+
+ libs.extend(self.optional_list("LIBS"))
+
+ rpaths = _UniqueList()
+
+ for l in self.extra_lib_dirs:
+ # Ignore relative directories. This is really a hack to handle
+ # SIP v3 inter-module linking.
+ if os.path.dirname(l) not in ("", ".", ".."):
+ rpaths.append(l)
+
+ if self._python:
+ incdir.append(self.config.py_inc_dir)
+ incdir.append(self.config.py_conf_inc_dir)
+
+ if sys.platform == "cygwin":
+ libdir.append(self.config.py_lib_dir)
+
+ py_lib = "python%u.%u" % ((self.config.py_version >> 16), ((self.config.py_version >> 8) & 0xff))
+ libs.append(self.platform_lib(py_lib))
+ elif sys.platform == "win32":
+ libdir.append(self.config.py_lib_dir)
+
+ py_lib = "python%u%u" % ((self.config.py_version >> 16), ((self.config.py_version >> 8) & 0xff))
+
+ # For Borland use the OMF version of the Python library if it
+ # exists, otherwise assume that Python was built with Borland
+ # and use the normal library.
+ if self.generator == "BMAKE":
+ bpy_lib = py_lib + "_bcpp"
+ bpy_lib_path = os.path.join(self.config.py_lib_dir, self.platform_lib(bpy_lib))
+
+ if os.access(bpy_lib_path, os.F_OK):
+ py_lib = bpy_lib
+
+ if self._debug:
+ py_lib = py_lib + "_d"
+
+ if self.generator != "MINGW":
+ cflags.append("/D_DEBUG")
+ cxxflags.append("/D_DEBUG")
+
+ libs.append(self.platform_lib(py_lib))
+
+ if self.generator in ("MSVC", "MSVC.NET", "BMAKE"):
+ if win_exceptions:
+ cflags_exceptions = "CFLAGS_EXCEPTIONS_ON"
+ cxxflags_exceptions = "CXXFLAGS_EXCEPTIONS_ON"
+ else:
+ cflags_exceptions = "CFLAGS_EXCEPTIONS_OFF"
+ cxxflags_exceptions = "CXXFLAGS_EXCEPTIONS_OFF"
+
+ cflags.extend(self.optional_list(cflags_exceptions))
+ cxxflags.extend(self.optional_list(cxxflags_exceptions))
+
+ if win_rtti:
+ cflags_rtti = "CFLAGS_RTTI_ON"
+ cxxflags_rtti = "CXXFLAGS_RTTI_ON"
+ else:
+ cflags_rtti = "CFLAGS_RTTI_OFF"
+ cxxflags_rtti = "CXXFLAGS_RTTI_OFF"
+
+ cflags.extend(self.optional_list(cflags_rtti))
+ cxxflags.extend(self.optional_list(cxxflags_rtti))
+
+ if win_stl:
+ cflags_stl = "CFLAGS_STL_ON"
+ cxxflags_stl = "CXXFLAGS_STL_ON"
+ else:
+ cflags_stl = "CFLAGS_STL_OFF"
+ cxxflags_stl = "CXXFLAGS_STL_OFF"
+
+ cflags.extend(self.optional_list(cflags_stl))
+ cxxflags.extend(self.optional_list(cxxflags_stl))
+
+ if self._debug:
+ if win_shared:
+ cflags_mt = "CFLAGS_MT_DLLDBG"
+ cxxflags_mt = "CXXFLAGS_MT_DLLDBG"
+ else:
+ cflags_mt = "CFLAGS_MT_DBG"
+ cxxflags_mt = "CXXFLAGS_MT_DBG"
+
+ cflags_debug = "CFLAGS_DEBUG"
+ cxxflags_debug = "CXXFLAGS_DEBUG"
+ lflags_debug = "LFLAGS_DEBUG"
+ else:
+ if win_shared:
+ cflags_mt = "CFLAGS_MT_DLL"
+ cxxflags_mt = "CXXFLAGS_MT_DLL"
+ else:
+ cflags_mt = "CFLAGS_MT"
+ cxxflags_mt = "CXXFLAGS_MT"
+
+ cflags_debug = "CFLAGS_RELEASE"
+ cxxflags_debug = "CXXFLAGS_RELEASE"
+ lflags_debug = "LFLAGS_RELEASE"
+
+ if self.generator in ("MSVC", "MSVC.NET", "BMAKE"):
+ if self._threaded:
+ cflags.extend(self.optional_list(cflags_mt))
+ cxxflags.extend(self.optional_list(cxxflags_mt))
+
+ if self.console:
+ cflags.extend(self.optional_list("CFLAGS_CONSOLE"))
+ cxxflags.extend(self.optional_list("CXXFLAGS_CONSOLE"))
+
+ cflags.extend(self.optional_list(cflags_debug))
+ cxxflags.extend(self.optional_list(cxxflags_debug))
+ lflags.extend(self.optional_list(lflags_debug))
+
+ if self._warnings:
+ cflags_warn = "CFLAGS_WARN_ON"
+ cxxflags_warn = "CXXFLAGS_WARN_ON"
+ else:
+ cflags_warn = "CFLAGS_WARN_OFF"
+ cxxflags_warn = "CXXFLAGS_WARN_OFF"
+
+ cflags.extend(self.optional_list(cflags_warn))
+ cxxflags.extend(self.optional_list(cxxflags_warn))
+
+ if self._threaded:
+ cflags.extend(self.optional_list("CFLAGS_THREAD"))
+ cxxflags.extend(self.optional_list("CXXFLAGS_THREAD"))
+ lflags.extend(self.optional_list("LFLAGS_THREAD"))
+
+ if self._qt:
+ if self.generator != "UNIX" and win_shared:
+ defines.append("QT_DLL")
+
+ if not self._debug:
+ defines.append("QT_NO_DEBUG")
+
+ if self.config.qt_version >= 0x040000:
+ for mod in self._qt:
+ # Note that qmake doesn't define anything for QtHelp.
+ if mod == "QtCore":
+ defines.append("QT_CORE_LIB")
+ elif mod == "QtGui":
+ defines.append("QT_GUI_LIB")
+ elif mod == "QtMultimedia":
+ defines.append("QT_MULTIMEDIA_LIB")
+ elif mod == "QtNetwork":
+ defines.append("QT_NETWORK_LIB")
+ elif mod == "QtOpenGL":
+ defines.append("QT_OPENGL_LIB")
+ elif mod == "QtScript":
+ defines.append("QT_SCRIPT_LIB")
+ elif mod == "QtScriptTools":
+ defines.append("QT_SCRIPTTOOLS_LIB")
+ elif mod == "QtSql":
+ defines.append("QT_SQL_LIB")
+ elif mod == "QtTest":
+ defines.append("QT_TEST_LIB")
+ elif mod == "QtWebKit":
+ defines.append("QT_WEBKIT_LIB")
+ elif mod == "QtXml":
+ defines.append("QT_XML_LIB")
+ elif mod == "QtXmlPatterns":
+ defines.append("QT_XMLPATTERNS_LIB")
+ elif mod == "phonon":
+ defines.append("QT_PHONON_LIB")
+ elif self._threaded:
+ defines.append("QT_THREAD_SUPPORT")
+
+ # Handle library directories.
+ libdir_qt = self.optional_list("LIBDIR_QT")
+ libdir.extend(libdir_qt)
+ rpaths.extend(libdir_qt)
+
+ if self.config.qt_version >= 0x040000:
+ # For Windows: the macros that define the dependencies on
+ # Windows libraries.
+ wdepmap = {
+ "QtCore": "LIBS_CORE",
+ "QtGui": "LIBS_GUI",
+ "QtNetwork": "LIBS_NETWORK",
+ "QtOpenGL": "LIBS_OPENGL",
+ "QtWebKit": "LIBS_WEBKIT"
+ }
+
+ # For Windows: the dependencies between Qt libraries.
+ qdepmap = {
+ "QtAssistant": ("QtNetwork", "QtGui", "QtCore"),
+ "QtGui": ("QtCore", ),
+ "QtHelp": ("QtSql", "QtGui", "QtCore"),
+ "QtMultimedia": ("QtGui", "QtCore"),
+ "QtNetwork": ("QtCore", ),
+ "QtOpenGL": ("QtGui", "QtCore"),
+ "QtScript": ("QtCore", ),
+ "QtScriptTools": ("QtScript", "QtGui", "QtCore"),
+ "QtSql": ("QtCore", ),
+ "QtSvg": ("QtXml", "QtGui", "QtCore"),
+ "QtTest": ("QtGui", "QtCore"),
+ "QtWebKit": ("QtNetwork", "QtGui", "QtCore"),
+ "QtXml": ("QtCore", ),
+ "QtXmlPatterns": ("QtNetwork", "QtCore"),
+ "phonon": ("QtGui", "QtCore"),
+ "QtDesigner": ("QtGui", "QtCore"),
+ "QAxContainer": ("QtGui", "QtCore")
+ }
+
+ # The QtSql .prl file doesn't include QtGui as a dependency (at
+ # least on Linux) so we explcitly set the dependency here for
+ # everything.
+ if "QtSql" in self._qt:
+ if "QtGui" not in self._qt:
+ self._qt.append("QtGui")
+
+ # With Qt v4.2.0, the QtAssistantClient library is now a shared
+ # library on UNIX. The QtAssistantClient .prl file doesn't
+ # include QtGui and QtNetwork as a dependency any longer. This
+ # seems to be a bug in Qt v4.2.0. We explicitly set the
+ # dependencies here.
+ if self.config.qt_version >= 0x040200 and "QtAssistant" in self._qt:
+ if "QtGui" not in self._qt:
+ self._qt.append("QtGui")
+ if "QtNetwork" not in self._qt:
+ self._qt.append("QtNetwork")
+
+ for mod in self._qt:
+ lib = self._qt4_module_to_lib(mod)
+ libs.append(self.platform_lib(lib, self._is_framework(mod)))
+
+ if sys.platform == "win32":
+ # On Windows the dependent libraries seem to be in
+ # qmake.conf rather than the .prl file and the
+ # inter-dependencies between Qt libraries don't seem to
+ # be anywhere.
+ deps = _UniqueList()
+
+ if mod in list(wdepmap.keys()):
+ deps.extend(self.optional_list(wdepmap[mod]))
+
+ if mod in list(qdepmap.keys()):
+ for qdep in qdepmap[mod]:
+ # Ignore the dependency if it is explicitly
+ # linked.
+ if qdep not in self._qt:
+ libs.append(self.platform_lib(self._qt4_module_to_lib(qdep)))
+
+ if qdep in list(wdepmap.keys()):
+ deps.extend(self.optional_list(wdepmap[qdep]))
+
+ libs.extend(deps.as_list())
+ else:
+ libs.extend(self._dependent_libs(lib, self._is_framework(mod)))
+ else:
+ # Windows needs the version number appended if Qt is a DLL.
+ qt_lib = self.config.qt_lib
+
+ if self.generator in ("MSVC", "MSVC.NET", "BMAKE") and win_shared:
+ qt_lib = qt_lib + version_to_string(self.config.qt_version).replace(".", "")
+
+ if self.config.qt_edition == "non-commercial":
+ qt_lib = qt_lib + "nc"
+
+ libs.append(self.platform_lib(qt_lib, self.config.qt_framework))
+ libs.extend(self._dependent_libs(self.config.qt_lib))
+
+ # Handle header directories.
+ try:
+ specd_base = self.config.qt_data_dir
+ except AttributeError:
+ specd_base = self.config.qt_dir
+
+ specd = os.path.join(specd_base, "mkspecs", "default")
+
+ if not os.access(specd, os.F_OK):
+ specd = os.path.join(specd_base, "mkspecs", self.config.platform)
+
+ incdir.append(specd)
+
+ qtincdir = self.optional_list("INCDIR_QT")
+
+ if qtincdir:
+ if self.config.qt_version >= 0x040000:
+ for mod in self._qt:
+ if mod == "QAxContainer":
+ incdir.append(os.path.join(qtincdir[0], "ActiveQt"))
+ elif self._is_framework(mod):
+ if mod == "QtAssistant" and self.config.qt_version < 0x040202:
+ mod = "QtAssistantClient"
+
+ incdir.append(os.path.join(libdir_qt[0], mod + ".framework", "Headers"))
+ else:
+ incdir.append(os.path.join(qtincdir[0], mod))
+
+ # This must go after the module include directories.
+ incdir.extend(qtincdir)
+
+ if self._opengl:
+ incdir.extend(self.optional_list("INCDIR_OPENGL"))
+ lflags.extend(self.optional_list("LFLAGS_OPENGL"))
+ libdir.extend(self.optional_list("LIBDIR_OPENGL"))
+ libs.extend(self.optional_list("LIBS_OPENGL"))
+
+ if self._qt or self._opengl:
+ if self.config.qt_version < 0x040000 or self._opengl or "QtGui" in self._qt:
+ incdir.extend(self.optional_list("INCDIR_X11"))
+ libdir.extend(self.optional_list("LIBDIR_X11"))
+ libs.extend(self.optional_list("LIBS_X11"))
+
+ if self._threaded:
+ libs.extend(self.optional_list("LIBS_THREAD"))
+ libs.extend(self.optional_list("LIBS_RTMT"))
+ else:
+ libs.extend(self.optional_list("LIBS_RT"))
+
+ if self.console:
+ libs.extend(self.optional_list("LIBS_CONSOLE"))
+
+ libs.extend(self.optional_list("LIBS_WINDOWS"))
+
+ lflags.extend(self._platform_rpaths(rpaths.as_list()))
+
+ # Save the transformed values.
+ self.CFLAGS.set(cflags)
+ self.CXXFLAGS.set(cxxflags)
+ self.DEFINES.set(defines)
+ self.INCDIR.set(incdir)
+ self.LFLAGS.set(lflags)
+ self.LIBDIR.set(libdir)
+ self.LIBS.set(libs)
+
+ # Don't do it again because it has side effects.
+ self._finalised = 1
+
+ def _add_manifest(self, target=None):
+ """Add the link flags for creating a manifest file.
+ """
+ if target is None:
+ target = "$(TARGET)"
+
+ self.LFLAGS.append("/MANIFEST")
+ self.LFLAGS.append("/MANIFESTFILE:%s.manifest" % target)
+
+ def _is_framework(self, mod):
+ """Return true if the given Qt module is a framework.
+ """
+ return (self.config.qt_framework and (self.config.qt_version >= 0x040200 or mod != "QtAssistant"))
+
+ def _qt4_module_to_lib(self, mname):
+ """Return the name of the Qt4 library corresponding to a module.
+
+ mname is the name of the module.
+ """
+ if mname == "QtAssistant":
+ if self.config.qt_version >= 0x040202 and sys.platform == "darwin":
+ lib = mname
+ else:
+ lib = "QtAssistantClient"
+ else:
+ lib = mname
+
+ if self._debug:
+ if sys.platform == "win32":
+ lib = lib + "d"
+ elif self.config.qt_version < 0x040200 or sys.platform == "darwin":
+ lib = lib + "_debug"
+
+ if sys.platform == "win32" and "shared" in self.config.qt_winconfig.split():
+ if (mname in ("QtCore", "QtDesigner", "QtGui", "QtHelp",
+ "QtMultimedia", "QtNetwork", "QtOpenGL", "QtScript",
+ "QtScriptTools", "QtSql", "QtSvg", "QtTest",
+ "QtWebKit", "QtXml", "QtXmlPatterns", "phonon") or
+ (self.config.qt_version >= 0x040200 and mname == "QtAssistant")):
+ lib = lib + "4"
+
+ return lib
+
+ def optional_list(self, name):
+ """Return an optional Makefile macro as a list.
+
+ name is the name of the macro.
+ """
+ return self.__dict__[name].as_list()
+
+ def optional_string(self, name, default=""):
+ """Return an optional Makefile macro as a string.
+
+ name is the name of the macro.
+ default is the default value
+ """
+ s = ' '.join(self.optional_list(name))
+
+ if not s:
+ s = default
+
+ return s
+
+ def required_string(self, name):
+ """Return a required Makefile macro as a string.
+
+ name is the name of the macro.
+ """
+ s = self.optional_string(name)
+
+ if not s:
+ raise ValueError("\"%s\" must have a non-empty value" % name)
+
+ return s
+
+ def _platform_rpaths(self, rpaths):
+ """Return a list of platform specific rpath flags.
+
+ rpaths is the cannonical list of rpaths.
+ """
+ flags = []
+ prefix = self.optional_string("RPATH")
+
+ if prefix:
+ for r in rpaths:
+ flags.append(_quote(prefix + r))
+
+ return flags
+
+ def platform_lib(self, clib, framework=0):
+ """Return a library name in platform specific form.
+
+ clib is the library name in cannonical form.
+ framework is set of the library is implemented as a MacOS framework.
+ """
+ if self.generator in ("MSVC", "MSVC.NET", "BMAKE"):
+ plib = clib + ".lib"
+ elif sys.platform == "darwin" and framework:
+ plib = "-framework " + clib
+ else:
+ plib = "-l" + clib
+
+ return plib
+
+ def _dependent_libs(self, clib, framework=0):
+ """Return a list of additional libraries (in platform specific form)
+ that must be linked with a library.
+
+ clib is the library name in cannonical form.
+ framework is set of the library is implemented as a MacOS framework.
+ """
+ prl_libs = []
+
+ if self.generator in ("MSVC", "MSVC.NET", "BMAKE"):
+ prl_name = os.path.join(self.config.qt_lib_dir, clib + ".prl")
+ elif sys.platform == "darwin" and framework:
+ prl_name = os.path.join(self.config.qt_lib_dir, clib + ".framework", clib + ".prl")
+ else:
+ prl_name = os.path.join(self.config.qt_lib_dir, "lib" + clib + ".prl")
+
+ if os.access(prl_name, os.F_OK):
+ try:
+ f = open(prl_name, "r")
+ except IOError:
+ error("Unable to open \"%s\"" % prl_name)
+
+ line = f.readline()
+ while line:
+ line = line.strip()
+ if line and line[0] != "#":
+ eq = line.find("=")
+ if eq > 0 and line[:eq].strip() == "QMAKE_PRL_LIBS":
+ prl_libs = line[eq + 1:].split()
+ break
+
+ line = f.readline()
+
+ f.close()
+
+ return prl_libs
+
+
+ def parse_build_file(self, filename):
+ """
+ Parse a build file and return the corresponding dictionary.
+
+ filename is the name of the build file. If it is a dictionary instead
+ then its contents are validated.
+ """
+ if type(filename) == dict:
+ bfname = "dictionary"
+ bdict = filename
+ else:
+ if os.path.isabs(filename):
+ # We appear to be building out of the source tree.
+ self._src_dir = os.path.dirname(filename)
+ bfname = filename
+ else:
+ bfname = os.path.join(self.dir, filename)
+
+ bdict = {}
+
+ try:
+ f = open(bfname, "r")
+ except IOError:
+ error("Unable to open \"%s\"" % bfname)
+
+ line_nr = 1
+ line = f.readline()
+
+ while line:
+ line = line.strip()
+
+ if line and line[0] != "#":
+ eq = line.find("=")
+
+ if eq <= 0:
+ error("\"%s\" line %d: Line must be in the form 'name = value value...'." % (bfname, line_nr))
+
+ bdict[line[:eq].strip()] = line[eq + 1:].strip()
+
+ line_nr = line_nr + 1
+ line = f.readline()
+
+ f.close()
+
+ # Check the compulsory values.
+ for i in ("target", "sources"):
+ try:
+ bdict[i]
+ except KeyError:
+ error("\"%s\" is missing from \"%s\"." % (i, bfname))
+
+ # Get the optional values.
+ for i in ("headers", "moc_headers"):
+ try:
+ bdict[i]
+ except KeyError:
+ bdict[i] = ""
+
+ # Generate the list of objects.
+ if self.generator in ("MSVC", "MSVC.NET", "BMAKE"):
+ ext = ".obj"
+ else:
+ ext = ".o"
+
+ olist = []
+
+ for f in bdict["sources"].split():
+ root, discard = os.path.splitext(f)
+ olist.append(root + ext)
+
+ for f in bdict["moc_headers"].split():
+ if not self._qt:
+ error("\"%s\" defines \"moc_headers\" for a non-Qt module." % bfname)
+
+ root, discard = os.path.splitext(f)
+ olist.append("moc_" + root + ext)
+
+ bdict["objects"] = ' '.join(olist)
+
+ return bdict
+
+ def clean_build_file_objects(self, mfile, build):
+ """Generate the clean target.
+
+ mfile is the file object.
+ build is the dictionary created from the build file.
+ """
+ mfile.write("\t-%s $(TARGET)\n" % self.rm)
+
+ for f in build["objects"].split():
+ mfile.write("\t-%s %s\n" % (self.rm, f))
+
+ for f in build["moc_headers"].split():
+ root, discard = os.path.splitext(f)
+ mfile.write("\t-%s moc_%s.cpp\n" % (self.rm, root))
+
+ def ready(self):
+ """The Makefile is now ready to be used.
+ """
+ if not self._finalised:
+ self.finalise()
+
+ def generate(self):
+ """Generate the Makefile.
+ """
+ self.ready()
+
+ # Make sure the destination directory exists.
+ try:
+ os.makedirs(self.dir)
+ except:
+ pass
+
+ mfname = os.path.join(self.dir, self._makefile)
+
+ try:
+ mfile = open(mfname, "w")
+ except IOError:
+ error("Unable to create \"%s\"" % mfname)
+
+ self.generate_macros_and_rules(mfile)
+ self.generate_target_default(mfile)
+ self.generate_target_install(mfile)
+
+ if self._installs:
+ if type(self._installs) != list:
+ self._installs = [self._installs]
+
+ for src, dst in self._installs:
+ self.install_file(mfile, src, dst)
+
+ self.generate_target_clean(mfile)
+
+ mfile.close()
+
+ def generate_macros_and_rules(self, mfile):
+ """The default implementation of the macros and rules generation.
+
+ mfile is the file object.
+ """
+ mfile.write("CC = %s\n" % self.required_string("CC"))
+ mfile.write("CXX = %s\n" % self.required_string("CXX"))
+ mfile.write("LINK = %s\n" % self.required_string("LINK"))
+
+ cppflags = []
+
+ if not self._debug:
+ cppflags.append("-DNDEBUG")
+
+ for f in self.optional_list("DEFINES"):
+ cppflags.append("-D" + f)
+
+ for f in self.optional_list("INCDIR"):
+ cppflags.append("-I" + _quote(f))
+
+ libs = []
+
+ if self.generator in ("MSVC", "MSVC.NET"):
+ libdir_prefix = "/LIBPATH:"
+ else:
+ libdir_prefix = "-L"
+
+ for ld in self.optional_list("LIBDIR"):
+ if sys.platform == "darwin" and self.config.qt_framework:
+ fflag = "-F" + _quote(ld)
+ libs.append(fflag)
+ cppflags.append(fflag)
+
+ libs.append(libdir_prefix + _quote(ld))
+
+ libs.extend(self.optional_list("LIBS"))
+
+ mfile.write("CPPFLAGS = %s\n" % ' '.join(cppflags))
+
+ mfile.write("CFLAGS = %s\n" % self.optional_string("CFLAGS"))
+ mfile.write("CXXFLAGS = %s\n" % self.optional_string("CXXFLAGS"))
+ mfile.write("LFLAGS = %s\n" % self.optional_string("LFLAGS"))
+
+ mfile.write("LIBS = %s\n" % ' '.join(libs))
+
+ if self._qt:
+ mfile.write("MOC = %s\n" % _quote(self.required_string("MOC")))
+
+ if self._src_dir != self.dir:
+ mfile.write("VPATH = %s\n\n" % self._src_dir)
+
+ # These probably don't matter.
+ if self.generator == "MINGW":
+ mfile.write(".SUFFIXES: .cpp .cxx .cc .C .c\n\n")
+ elif self.generator == "UNIX":
+ mfile.write(".SUFFIXES: .c .o .cpp .cc .cxx .C\n\n")
+ else:
+ mfile.write(".SUFFIXES: .c .cpp .cc .cxx .C\n\n")
+
+ if self.generator in ("MSVC", "MSVC.NET"):
+ mfile.write("""
+{.}.cpp{}.obj::
+\t$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -Fo @<<
+\t$<
+<<
+
+{.}.cc{}.obj::
+\t$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -Fo @<<
+\t$<
+<<
+
+{.}.cxx{}.obj::
+\t$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -Fo @<<
+\t$<
+<<
+
+{.}.C{}.obj::
+\t$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -Fo @<<
+\t$<
+<<
+
+{.}.c{}.obj::
+\t$(CC) -c $(CFLAGS) $(CPPFLAGS) -Fo @<<
+\t$<
+<<
+""")
+ elif self.generator == "BMAKE":
+ mfile.write("""
+.cpp.obj:
+\t$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o$@ $<
+
+.cc.obj:
+\t$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o$@ $<
+
+.cxx.obj:
+\t$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o$@ $<
+
+.C.obj:
+\t$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o$@ $<
+
+.c.obj:
+\t$(CC) -c $(CFLAGS) $(CPPFLAGS) -o$@ $<
+""")
+ else:
+ mfile.write("""
+.cpp.o:
+\t$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ $<
+
+.cc.o:
+\t$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ $<
+
+.cxx.o:
+\t$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ $<
+
+.C.o:
+\t$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ $<
+
+.c.o:
+\t$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
+""")
+
+ def generate_target_default(self, mfile):
+ """The default implementation of the default target.
+
+ mfile is the file object.
+ """
+ mfile.write("\nall:\n")
+
+ def generate_target_install(self, mfile):
+ """The default implementation of the install target.
+
+ mfile is the file object.
+ """
+ mfile.write("\ninstall:\n")
+
+ def generate_target_clean(self, mfile):
+ """The default implementation of the clean target.
+
+ mfile is the file object.
+ """
+ mfile.write("\nclean:\n")
+
+ def install_file(self, mfile, src, dst, strip=0):
+ """Install one or more files in a directory.
+
+ mfile is the file object.
+ src is the name of a single file to install, or the list of a number of
+ files to install.
+ dst is the name of the destination directory.
+ strip is set if the files should be stripped after been installed.
+ """
+ # Help package builders.
+ if self.generator == "UNIX":
+ dst = "$(DESTDIR)" + dst
+
+ mfile.write("\t@%s %s " % (self.chkdir, _quote(dst)))
+
+ if self.generator == "UNIX":
+ mfile.write("|| ")
+
+ mfile.write("%s %s\n" % (self.mkdir, _quote(dst)))
+
+ if type(src) != list:
+ src = [src]
+
+ # Get the strip command if needed.
+ if strip:
+ strip_cmd = self.optional_string("STRIP")
+
+ if not strip_cmd:
+ strip = 0
+
+ for sf in src:
+ target = _quote(os.path.join(dst, os.path.basename(sf)))
+
+ mfile.write("\t%s %s %s\n" % (self.copy, _quote(sf), target))
+
+ if strip:
+ mfile.write("\t%s %s\n" % (strip_cmd, target))
+
+
+class ParentMakefile(Makefile):
+ """The class that represents a parent Makefile.
+ """
+ def __init__(self, configuration, subdirs, dir=None, makefile="Makefile",
+ installs=None):
+ """Initialise an instance of a parent Makefile.
+
+ subdirs is the sequence of subdirectories.
+ """
+ Makefile.__init__(self, configuration, dir=dir, makefile=makefile, installs=installs)
+
+ self._subdirs = subdirs
+
+ def generate_macros_and_rules(self, mfile):
+ """Generate the macros and rules.
+
+ mfile is the file object.
+ """
+ # We don't want them.
+ pass
+
+ def generate_target_default(self, mfile):
+ """Generate the default target.
+
+ mfile is the file object.
+ """
+ self._subdir_target(mfile)
+
+ def generate_target_install(self, mfile):
+ """Generate the install target.
+
+ mfile is the file object.
+ """
+ self._subdir_target(mfile, "install")
+
+ def generate_target_clean(self, mfile):
+ """Generate the clean target.
+
+ mfile is the file object.
+ """
+ self._subdir_target(mfile, "clean")
+
+ def _subdir_target(self, mfile, target="all"):
+ """Create a target for a list of sub-directories.
+
+ mfile is the file object.
+ target is the name of the target.
+ """
+ if target == "all":
+ tname = ""
+ else:
+ tname = " " + target
+
+ mfile.write("\n" + target + ":\n")
+
+ for d in self._subdirs:
+ if self.generator == "MINGW":
+ mfile.write("\t@$(MAKE) -C %s%s\n" % (d, tname))
+ elif self.generator == "UNIX":
+ mfile.write("\t@(cd %s; $(MAKE)%s)\n" % (d, tname))
+ else:
+ mfile.write("\tcd %s\n" % d)
+ mfile.write("\t$(MAKE)%s\n" % tname)
+ mfile.write("\t@cd ..\n")
+
+
+class PythonModuleMakefile(Makefile):
+ """The class that represents a Python module Makefile.
+ """
+ def __init__(self, configuration, dstdir, srcdir=None, dir=None,
+ makefile="Makefile", installs=None):
+ """Initialise an instance of a parent Makefile.
+
+ dstdir is the name of the directory where the module's Python code will
+ be installed.
+ srcdir is the name of the directory (relative to the directory in which
+ the Makefile will be created) containing the module's Python code. It
+ defaults to the same directory.
+ """
+ Makefile.__init__(self, configuration, dir=dir, makefile=makefile, installs=installs)
+
+ if not srcdir:
+ srcdir = "."
+
+ if dir:
+ self._moddir = os.path.join(dir, srcdir)
+ else:
+ self._moddir = srcdir
+
+ self._srcdir = srcdir
+ self._dstdir = dstdir
+
+ def generate_macros_and_rules(self, mfile):
+ """Generate the macros and rules.
+
+ mfile is the file object.
+ """
+ # We don't want them.
+ pass
+
+ def generate_target_install(self, mfile):
+ """Generate the install target.
+
+ mfile is the file object.
+ """
+ Makefile.generate_target_install(self, mfile)
+
+ for root, dirs, files in os.walk(self._moddir):
+ # Do not recurse into certain directories.
+ for skip in (".svn", "CVS"):
+ if skip in dirs:
+ dirs.remove(skip)
+
+ tail = root[len(self._moddir):]
+ flist = []
+
+ for f in files:
+ if f == "Makefile":
+ continue
+
+ if os.path.isfile(os.path.join(root, f)):
+ flist.append(os.path.join(self._srcdir + tail, f))
+
+ self.install_file(mfile, flist, self._dstdir + tail)
+
+
+class ModuleMakefile(Makefile):
+ """The class that represents a Python extension module Makefile
+ """
+ def __init__(self, configuration, build_file, install_dir=None, static=0,
+ console=0, qt=0, opengl=0, threaded=0, warnings=1, debug=0,
+ dir=None, makefile="Makefile", installs=None, strip=1,
+ export_all=0, universal=None, arch=None):
+ """Initialise an instance of a module Makefile.
+
+ build_file is the file containing the target specific information. If
+ it is a dictionary instead then its contents are validated.
+ install_dir is the directory the target will be installed in.
+ static is set if the module should be built as a static library.
+ strip is set if the module should be stripped of unneeded symbols when
+ installed. The default is 1.
+ export_all is set if all the module's symbols should be exported rather
+ than just the module's initialisation function. Exporting all symbols
+ increases the size of the module and slows down module load times but
+ may avoid problems with modules that use exceptions. The default is 0.
+ """
+ Makefile.__init__(self, configuration, console, qt, opengl, 1, threaded, warnings, debug, dir, makefile, installs, universal, arch)
+
+ self._build = self.parse_build_file(build_file)
+ self._install_dir = install_dir
+ self.static = static
+
+ self._manifest = ("embed_manifest_dll" in self.optional_list("CONFIG"))
+
+ # Don't strip or restrict the exports if this is a debug or static
+ # build.
+ if debug or static:
+ self._strip = 0
+ self._limit_exports = 0
+ else:
+ self._strip = strip
+ self._limit_exports = not export_all
+
+ # Save the target name for later.
+ self._target = self._build["target"]
+
+ # The name of the module entry point is Python version specific.
+ if self.config.py_version >= 0x030000:
+ self._entry_point = "PyInit_%s" % self._target
+ else:
+ self._entry_point = "init%s" % self._target
+
+ if sys.platform != "win32" and static:
+ self._target = "lib" + self._target
+
+ if sys.platform == "win32" and debug:
+ self._target = self._target + "_d"
+
+ def finalise(self):
+ """Finalise the macros common to all module Makefiles.
+ """
+ if self.console:
+ lflags_console = "LFLAGS_CONSOLE"
+ else:
+ lflags_console = "LFLAGS_WINDOWS"
+
+ if self.static:
+ self.DEFINES.append("SIP_STATIC_MODULE")
+ else:
+ self.CFLAGS.extend(self.optional_list("CFLAGS_SHLIB"))
+ self.CXXFLAGS.extend(self.optional_list("CXXFLAGS_SHLIB"))
+
+ lflags_dll = self.optional_list("LFLAGS_DLL")
+
+ if lflags_dll:
+ self.LFLAGS.extend(lflags_dll)
+ elif self.console:
+ lflags_console = "LFLAGS_CONSOLE_DLL"
+ else:
+ lflags_console = "LFLAGS_WINDOWS_DLL"
+
+ if self._manifest:
+ self._add_manifest()
+
+ # We use this to explictly create bundles on MacOS. Apple's Python
+ # can handle extension modules that are bundles or dynamic
+ # libraries, but python.org versions need bundles (unless built
+ # with DYNLOADFILE=dynload_shlib.o).
+ if sys.platform == "darwin":
+ lflags_plugin = ["-bundle"]
+ else:
+ lflags_plugin = self.optional_list("LFLAGS_PLUGIN")
+
+ if not lflags_plugin:
+ lflags_plugin = self.optional_list("LFLAGS_SHLIB")
+
+ self.LFLAGS.extend(lflags_plugin)
+
+ self.LFLAGS.extend(self.optional_list(lflags_console))
+
+ if sys.platform == "darwin":
+ # 'real_prefix' exists if virtualenv is being used.
+ dl = getattr(sys, 'real_prefix', sys.exec_prefix).split(os.sep)
+
+ if "Python.framework" not in dl:
+ error("SIP requires Python to be built as a framework")
+
+ self.LFLAGS.append("-undefined dynamic_lookup")
+
+ Makefile.finalise(self)
+
+ if not self.static:
+ if self.optional_string("AIX_SHLIB"):
+ # AIX needs a lot of special handling.
+ if self.required_string('LINK') == 'g++':
+ # g++ is used for linking.
+ # For SIP v4 and g++:
+ # 1.) Import the python symbols
+ aix_lflags = ['-Wl,-bI:%s/python.exp' % self.config.py_lib_dir]
+
+ if self._limit_exports:
+ aix_lflags.append('-Wl,-bnoexpall')
+ aix_lflags.append('-Wl,-bnoentry')
+ aix_lflags.append('-Wl,-bE:%s.exp' % self._target)
+ else:
+ # IBM VisualAge C++ is used for linking.
+ # For SIP v4 and xlC:
+ # 1.) Create a shared object
+ # 2.) Import the python symbols
+ aix_lflags = ['-qmkshrobj',
+ '-bI:%s/python.exp' % self.config.py_lib_dir]
+
+ if self._limit_exports:
+ aix_lflags.append('-bnoexpall')
+ aix_lflags.append('-bnoentry')
+ aix_lflags.append('-bE:%s.exp' % self._target)
+
+ self.LFLAGS.extend(aix_lflags)
+ else:
+ if self._limit_exports:
+ if sys.platform[:5] == 'linux':
+ self.LFLAGS.extend(['-Wl,--version-script=%s.exp' % self._target])
+ elif sys.platform[:5] == 'sunos':
+ if self.required_string('LINK') == 'g++':
+ self.LFLAGS.extend(['-Wl,-z,noversion', '-Wl,-M,%s.exp' % self._target])
+ else:
+ self.LFLAGS.extend(['-z' 'noversion', '-M', '%s.exp' % self._target])
+ elif sys.platform[:5] == 'hp-ux':
+ self.LFLAGS.extend(['-Wl,+e,%s' % self._entry_point])
+ elif sys.platform[:5] == 'irix' and self.required_string('LINK') != 'g++':
+ # Doesn't work when g++ is used for linking on IRIX.
+ self.LFLAGS.extend(['-Wl,-exported_symbol,%s' % self._entry_point])
+
+ # Force the shared linker if there is one.
+ link_shlib = self.optional_list("LINK_SHLIB")
+
+ if link_shlib:
+ self.LINK.set(link_shlib)
+
+ # This made an appearence in Qt v4.4rc1 and breaks extension modules so
+ # remove it. It was removed at my request but some stupid distros may
+ # have kept it.
+ self.LFLAGS.remove('-Wl,--no-undefined')
+
+ def module_as_lib(self, mname):
+ """Return the name of a SIP v3.x module when it is used as a library.
+ This will raise an exception when used with SIP v4.x modules.
+
+ mname is the name of the module.
+ """
+ raise ValueError("module_as_lib() can only be used with SIP v3.x")
+
+ def generate_macros_and_rules(self, mfile):
+ """Generate the macros and rules generation.
+
+ mfile is the file object.
+ """
+ if self.static:
+ if sys.platform == "win32":
+ ext = "lib"
+ else:
+ ext = "a"
+ else:
+ if sys.platform == "win32":
+ ext = "pyd"
+ elif sys.platform == "darwin":
+ ext = "so"
+ elif sys.platform == "cygwin":
+ ext = "dll"
+ else:
+ ext = self.optional_string("EXTENSION_PLUGIN")
+ if not ext:
+ ext = self.optional_string("EXTENSION_SHLIB", "so")
+
+ mfile.write("TARGET = %s\n" % (self._target + "." + ext))
+ mfile.write("OFILES = %s\n" % self._build["objects"])
+ mfile.write("HFILES = %s %s\n" % (self._build["headers"], self._build["moc_headers"]))
+ mfile.write("\n")
+
+ if self.static:
+ if self.generator in ("MSVC", "MSVC.NET", "BMAKE"):
+ mfile.write("LIB = %s\n" % self.required_string("LIB"))
+ elif self.generator == "MINGW":
+ mfile.write("AR = %s\n" % self.required_string("LIB"))
+ self._ranlib = None
+ else:
+ mfile.write("AR = %s\n" % self.required_string("AR"))
+
+ self._ranlib = self.optional_string("RANLIB")
+
+ if self._ranlib:
+ mfile.write("RANLIB = %s\n" % self._ranlib)
+
+ Makefile.generate_macros_and_rules(self, mfile)
+
+ def generate_target_default(self, mfile):
+ """Generate the default target.
+
+ mfile is the file object.
+ """
+ # Do these first so that it's safe for a sub-class to append additional
+ # commands to the real target, but make sure the default is correct.
+ mfile.write("\nall: $(TARGET)\n")
+ mfile.write("\n$(OFILES): $(HFILES)\n")
+
+ for mf in self._build["moc_headers"].split():
+ root, _ = os.path.splitext(mf)
+ cpp = "moc_" + root + ".cpp"
+
+ if self._src_dir != self.dir:
+ mf = os.path.join(self._src_dir, mf)
+
+ mfile.write("\n%s: %s\n" % (cpp, mf))
+ mfile.write("\t$(MOC) -o %s %s\n" % (cpp, mf))
+
+ mfile.write("\n$(TARGET): $(OFILES)\n")
+
+ if self.generator in ("MSVC", "MSVC.NET"):
+ if self.static:
+ mfile.write("\t$(LIB) /OUT:$(TARGET) @<<\n")
+ mfile.write("\t $(OFILES)\n")
+ mfile.write("<<\n")
+ else:
+ mfile.write("\t$(LINK) $(LFLAGS) /OUT:$(TARGET) @<<\n")
+ mfile.write("\t $(OFILES) $(LIBS)\n")
+ mfile.write("<<\n")
+
+ if self._manifest:
+ mfile.write("\tmt -nologo -manifest $(TARGET).manifest -outputresource:$(TARGET);2\n")
+ elif self.generator == "BMAKE":
+ if self.static:
+ mfile.write("\t-%s $(TARGET)\n" % (self.rm))
+ mfile.write("\t$(LIB) $(TARGET) @&&|\n")
+
+ for of in self._build["objects"].split():
+ mfile.write("+%s \\\n" % (of))
+
+ mfile.write("|\n")
+ else:
+ mfile.write("\t$(LINK) @&&|\n")
+ mfile.write("\t$(LFLAGS) $(OFILES) ,$(TARGET),,$(LIBS),%s\n" % (self._target))
+ mfile.write("|\n")
+
+ # Create the .def file that renames the entry point.
+ defname = os.path.join(self.dir, self._target + ".def")
+
+ try:
+ dfile = open(defname, "w")
+ except IOError:
+ error("Unable to create \"%s\"" % defname)
+
+ dfile.write("EXPORTS\n")
+ dfile.write("%s=_%s\n" % (self._entry_point, self._entry_point))
+
+ dfile.close()
+
+ else:
+ if self.static:
+ mfile.write("\t-%s $(TARGET)\n" % self.rm)
+ mfile.write("\t$(AR) $(TARGET) $(OFILES)\n")
+
+ if self._ranlib:
+ mfile.write("\t$(RANLIB) $(TARGET)\n")
+ else:
+ if self._limit_exports:
+ # Create an export file for AIX, Linux and Solaris.
+ if sys.platform[:5] == 'linux':
+ mfile.write("\t@echo '{ global: %s; local: *; };' > %s.exp\n" % (self._entry_point, self._target))
+ elif sys.platform[:5] == 'sunos':
+ mfile.write("\t@echo '{ global: %s; local: *; };' > %s.exp\n" % (self._entry_point, self._target))
+ elif sys.platform[:3] == 'aix':
+ mfile.write("\t@echo '#!' >%s.exp" % self._target)
+ mfile.write("; \\\n\t echo '%s' >>%s.exp\n" % (self._entry_point, self._target))
+
+ mfile.write("\t$(LINK) $(LFLAGS) -o $(TARGET) $(OFILES) $(LIBS)\n")
+
+ def generate_target_install(self, mfile):
+ """Generate the install target.
+
+ mfile is the file object.
+ """
+ if self._install_dir is None:
+ self._install_dir = self.config.default_mod_dir
+
+ mfile.write("\ninstall: $(TARGET)\n")
+ self.install_file(mfile, "$(TARGET)", self._install_dir, self._strip)
+
+ def generate_target_clean(self, mfile):
+ """Generate the clean target.
+
+ mfile is the file object.
+ """
+ mfile.write("\nclean:\n")
+ self.clean_build_file_objects(mfile, self._build)
+
+ if self._manifest and not self.static:
+ mfile.write("\t-%s $(TARGET).manifest\n" % self.rm)
+
+ # Remove any export file on AIX, Linux and Solaris.
+ if self._limit_exports and (sys.platform[:5] == 'linux' or
+ sys.platform[:5] == 'sunos' or
+ sys.platform[:3] == 'aix'):
+ mfile.write("\t-%s %s.exp\n" % (self.rm, self._target))
+
+
+class SIPModuleMakefile(ModuleMakefile):
+ """The class that represents a SIP generated module Makefile.
+ """
+ def __init__(self, configuration, build_file, install_dir=None, static=0,
+ console=0, qt=0, opengl=0, threaded=0, warnings=1, debug=0,
+ dir=None, makefile="Makefile", installs=None, strip=1,
+ export_all=0, universal=None, arch=None, prot_is_public=0):
+ """Initialise an instance of a SIP generated module Makefile.
+
+ prot_is_public is set if "protected" is to be redefined as "public".
+ If the platform's C++ ABI allows it this can significantly reduce the
+ size of the generated code.
+
+ For all other arguments see ModuleMakefile.
+ """
+ ModuleMakefile.__init__(self, configuration, build_file, install_dir,
+ static, console, qt, opengl, threaded, warnings, debug, dir,
+ makefile, installs, strip, export_all, universal, arch)
+
+ self._prot_is_public = prot_is_public
+
+ def finalise(self):
+ """Finalise the macros for a SIP generated module Makefile.
+ """
+ if self._prot_is_public:
+ self.DEFINES.append('SIP_PROTECTED_IS_PUBLIC')
+ self.DEFINES.append('protected=public')
+
+ self.INCDIR.append(self.config.sip_inc_dir)
+
+ ModuleMakefile.finalise(self)
+
+
+class ProgramMakefile(Makefile):
+ """The class that represents a program Makefile.
+ """
+ def __init__(self, configuration, build_file=None, install_dir=None,
+ console=0, qt=0, opengl=0, python=0, threaded=0, warnings=1,
+ debug=0, dir=None, makefile="Makefile", installs=None,
+ universal=None, arch=None):
+ """Initialise an instance of a program Makefile.
+
+ build_file is the file containing the target specific information. If
+ it is a dictionary instead then its contents are validated.
+ install_dir is the directory the target will be installed in.
+ """
+ Makefile.__init__(self, configuration, console, qt, opengl, python, threaded, warnings, debug, dir, makefile, installs, universal, arch)
+
+ self._install_dir = install_dir
+
+ self._manifest = ("embed_manifest_exe" in self.optional_list("CONFIG"))
+ self._target = None
+
+ if build_file:
+ self._build = self.parse_build_file(build_file)
+ else:
+ self._build = None
+
+ def build_command(self, source):
+ """Create a command line that will build an executable. Returns a
+ tuple of the name of the executable and the command line.
+
+ source is the name of the source file.
+ """
+ # The name of the executable.
+ self._target, _ = os.path.splitext(source)
+
+ if sys.platform in ("win32", "cygwin"):
+ exe = self._target + ".exe"
+ else:
+ exe = self._target
+
+ self.ready()
+
+ # The command line.
+ build = []
+
+ build.append(self.required_string("CXX"))
+
+ for a in self._arch.split():
+ build.append('-arch ' + a)
+
+ for f in self.optional_list("DEFINES"):
+ build.append("-D" + f)
+
+ for f in self.optional_list("INCDIR"):
+ build.append("-I" + _quote(f))
+
+ build.extend(self.optional_list("CXXFLAGS"))
+
+ # Borland requires all flags to precede all file names.
+ if self.generator != "BMAKE":
+ build.append(source)
+
+ if self.generator in ("MSVC", "MSVC.NET"):
+ build.append("-Fe")
+ build.append("/link")
+ libdir_prefix = "/LIBPATH:"
+ elif self.generator == "BMAKE":
+ build.append("-e" + exe)
+ libdir_prefix = "-L"
+ else:
+ build.append("-o")
+ build.append(exe)
+ libdir_prefix = "-L"
+
+ for ld in self.optional_list("LIBDIR"):
+ if sys.platform == "darwin" and self.config.qt_framework:
+ build.append("-F" + _quote(ld))
+
+ build.append(libdir_prefix + _quote(ld))
+
+ lflags = self.optional_list("LFLAGS")
+
+ # This is a huge hack demonstrating my lack of understanding of how the
+ # Borland compiler works.
+ if self.generator == "BMAKE":
+ blflags = []
+
+ for lf in lflags:
+ for f in lf.split():
+ # Tell the compiler to pass the flags to the linker.
+ if f[-1] == "-":
+ f = "-l-" + f[1:-1]
+ elif f[0] == "-":
+ f = "-l" + f[1:]
+
+ # Remove any explicit object files otherwise the compiler
+ # will complain that they can't be found, but they don't
+ # seem to be needed.
+ if f[-4:].lower() != ".obj":
+ blflags.append(f)
+
+ lflags = blflags
+
+ build.extend(lflags)
+
+ build.extend(self.optional_list("LIBS"))
+
+ if self.generator == "BMAKE":
+ build.append(source)
+
+ return (exe, ' '.join(build))
+
+ def finalise(self):
+ """Finalise the macros for a program Makefile.
+ """
+ if self.generator in ("MSVC", "MSVC.NET"):
+ self.LFLAGS.append("/INCREMENTAL:NO")
+
+ if self._manifest:
+ self._add_manifest(self._target)
+
+ if self.console:
+ lflags_console = "LFLAGS_CONSOLE"
+ else:
+ lflags_console = "LFLAGS_WINDOWS"
+
+ self.LFLAGS.extend(self.optional_list(lflags_console))
+
+ Makefile.finalise(self)
+
+ def generate_macros_and_rules(self, mfile):
+ """Generate the macros and rules generation.
+
+ mfile is the file object.
+ """
+ if not self._build:
+ raise ValueError("pass a filename as build_file when generating a Makefile")
+
+ target = self._build["target"]
+
+ if sys.platform in ("win32", "cygwin"):
+ target = target + ".exe"
+
+ mfile.write("TARGET = %s\n" % target)
+ mfile.write("OFILES = %s\n" % self._build["objects"])
+ mfile.write("HFILES = %s\n" % self._build["headers"])
+ mfile.write("\n")
+
+ Makefile.generate_macros_and_rules(self, mfile)
+
+ def generate_target_default(self, mfile):
+ """Generate the default target.
+
+ mfile is the file object.
+ """
+ # Do these first so that it's safe for a sub-class to append additional
+ # commands to the real target, but make sure the default is correct.
+ mfile.write("\nall: $(TARGET)\n")
+ mfile.write("\n$(OFILES): $(HFILES)\n")
+
+ for mf in self._build["moc_headers"].split():
+ root, _ = os.path.splitext(mf)
+ cpp = "moc_" + root + ".cpp"
+
+ if self._src_dir != self.dir:
+ mf = os.path.join(self._src_dir, mf)
+
+ mfile.write("\n%s: %s\n" % (cpp, mf))
+ mfile.write("\t$(MOC) -o %s %s\n" % (cpp, mf))
+
+ mfile.write("\n$(TARGET): $(OFILES)\n")
+
+ if self.generator in ("MSVC", "MSVC.NET"):
+ mfile.write("\t$(LINK) $(LFLAGS) /OUT:$(TARGET) @<<\n")
+ mfile.write("\t $(OFILES) $(LIBS)\n")
+ mfile.write("<<\n")
+ elif self.generator == "BMAKE":
+ mfile.write("\t$(LINK) @&&|\n")
+ mfile.write("\t$(LFLAGS) $(OFILES) ,$(TARGET),,$(LIBS),,\n")
+ mfile.write("|\n")
+ else:
+ mfile.write("\t$(LINK) $(LFLAGS) -o $(TARGET) $(OFILES) $(LIBS)\n")
+
+ if self._manifest:
+ mfile.write("\tmt -nologo -manifest $(TARGET).manifest -outputresource:$(TARGET);1\n")
+
+ def generate_target_install(self, mfile):
+ """Generate the install target.
+
+ mfile is the file object.
+ """
+ if self._install_dir is None:
+ self._install_dir = self.config.default_bin_dir
+
+ mfile.write("\ninstall: $(TARGET)\n")
+ self.install_file(mfile, "$(TARGET)", self._install_dir)
+
+ def generate_target_clean(self, mfile):
+ """Generate the clean target.
+
+ mfile is the file object.
+ """
+ mfile.write("\nclean:\n")
+ self.clean_build_file_objects(mfile, self._build)
+
+ if self._manifest:
+ mfile.write("\t-%s $(TARGET).manifest\n" % self.rm)
+
+
+def _quote(s):
+ """Return a string surrounded by double quotes it if contains a space.
+
+ s is the string.
+ """
+ if s.find(" ") >= 0:
+ s = '"' + s + '"'
+
+ return s
+
+
+def version_to_string(v):
+ """Convert a 3 part version number encoded as a hexadecimal value to a
+ string.
+ """
+ return "%u.%u.%u" % (((v >> 16) & 0xff), ((v >> 8) & 0xff), (v & 0xff))
+
+
+def read_version(filename, description, numdefine=None, strdefine=None):
+ """Read the version information for a package from a file. The information
+ is specified as #defines of a numeric (hexadecimal or decimal) value and/or
+ a string value.
+
+ filename is the name of the file.
+ description is the descriptive name of the package.
+ numdefine is the name of the #define of the numeric version. It is ignored
+ if it is None.
+ strdefine is the name of the #define of the string version. It is ignored
+ if it is None.
+
+ Returns a tuple of the version as a number and as a string.
+ """
+ need_num = numdefine is not None
+ need_str = strdefine is not None
+
+ vers = None
+ versstr = None
+
+ f = open(filename)
+ l = f.readline()
+
+ while l and (need_num or need_str):
+ wl = l.split()
+ if len(wl) >= 3 and wl[0] == "#define":
+ if need_num and wl[1] == numdefine:
+ v = wl[2]
+
+ if v[0:2] == "0x":
+ vers = int(v, 16)
+ else:
+ dec = int(v)
+ maj = dec / 100
+ min = (dec % 100) / 10
+ bug = (dec % 10)
+ vers = (maj << 16) + (min << 8) + bug
+
+ need_num = 0
+
+ if need_str and wl[1] == strdefine:
+ # Take account of embedded spaces.
+ versstr = ' '.join(wl[2:])[1:-1]
+ need_str = 0
+
+ l = f.readline()
+
+ f.close()
+
+ if need_num or need_str:
+ error("The %s version number could not be determined by parsing %s." % (description, filename))
+
+ return (vers, versstr)
+
+
+def create_content(cdict, macros=None):
+ """Convert a dictionary to a string (typically to use as the content to a
+ call to create_config_module()). Dictionary values that are strings are
+ quoted. Dictionary values that are lists are converted to quoted strings.
+
+ dict is the dictionary.
+ macros is the optional dictionary of platform specific build macros.
+ """
+ content = "_pkg_config = {\n"
+
+ keys = list(cdict.keys())
+ keys.sort()
+
+ # Format it nicely.
+ width = 0
+
+ for k in keys:
+ klen = len(k)
+
+ if width < klen:
+ width = klen
+
+ for k in keys:
+ val = cdict[k]
+ vtype = type(val)
+ delim = None
+
+ if val is None:
+ val = "None"
+ elif vtype == list:
+ val = ' '.join(val)
+ delim = "'"
+ elif vtype == int:
+ if k.find("version") >= 0:
+ # Assume it's a hexadecimal version number. It doesn't matter
+ # if it isn't, we are just trying to make it look pretty.
+ val = "0x%06x" % val
+ else:
+ val = str(val)
+ else:
+ val = str(val)
+ delim = "'"
+
+ if delim:
+ if "'" in val:
+ delim = "'''"
+
+ val = delim + val + delim
+
+ content = content + " '" + k + "':" + (" " * (width - len(k) + 2)) + val.replace("\\", "\\\\")
+
+ if k != keys[-1]:
+ content = content + ","
+
+ content = content + "\n"
+
+ content = content + "}\n\n"
+
+ # Format the optional macros.
+ content = content + "_default_macros = "
+
+ if macros:
+ content = content + "{\n"
+
+ names = list(macros.keys())
+ names.sort()
+
+ width = 0
+ for c in names:
+ clen = len(c)
+ if width < clen:
+ width = clen
+
+ for c in names:
+ if c == names[-1]:
+ sep = ""
+ else:
+ sep = ","
+
+ val = macros[c]
+ if "'" in val:
+ delim = "'''"
+ else:
+ delim = "'"
+
+ k = "'" + c + "':"
+ content = content + " %-*s %s%s%s%s\n" % (1 + width + 2, k, delim, val.replace("\\", "\\\\"), delim, sep)
+
+ content = content + "}\n"
+ else:
+ content = content + "None\n"
+
+ return content
+
+
+def create_config_module(module, template, content, macros=None):
+ """Create a configuration module by replacing "@" followed by
+ "SIP_CONFIGURATION" followed by "@" in a template file with a content
+ string.
+
+ module is the name of the module file.
+ template is the name of the template file.
+ content is the content string. If it is a dictionary it is first converted
+ to a string using create_content().
+ macros is an optional dictionary of platform specific build macros. It is
+ only used if create_content() is called to convert the content to a string.
+ """
+ if type(content) == dict:
+ content = create_content(content, macros)
+
+ # Allow this file to used as a template.
+ key = "@" + "SIP_CONFIGURATION" + "@"
+
+ df = open(module, "w")
+ sf = open(template, "r")
+
+ line = sf.readline()
+ while line:
+ if line.find(key) >= 0:
+ line = content
+
+ df.write(line)
+
+ line = sf.readline()
+
+
+def version_to_sip_tag(version, tags, description):
+ """Convert a version number to a SIP tag.
+
+ version is the version number. If it is negative then the latest version
+ is assumed. (This is typically useful if a snapshot is indicated by a
+ negative version number.)
+ tags is the dictionary of tags keyed by version number. The tag used is
+ the one with the smallest key (ie. earliest version) that is greater than
+ the given version number.
+ description is the descriptive name of the package used for error messages.
+
+ Returns the corresponding tag.
+ """
+ vl = list(tags.keys())
+ vl.sort()
+
+ # For a snapshot use the latest tag.
+ if version < 0:
+ tag = tags[vl[-1]]
+ else:
+ for v in vl:
+ if version < v:
+ tag = tags[v]
+ break
+ else:
+ error("Unsupported %s version: 0x%06x." % (description, version))
+
+ return tag
+
+
+def error(msg):
+ """Display an error message and terminate.
+
+ msg is the text of the error message.
+ """
+ sys.stderr.write(format("Error: " + msg) + "\n")
+ sys.exit(1)
+
+
+def inform(msg):
+ """Display an information message.
+
+ msg is the text of the error message.
+ """
+ sys.stdout.write(format(msg) + "\n")
+
+
+def format(msg, leftmargin=0, rightmargin=78):
+ """Format a message by inserting line breaks at appropriate places.
+
+ msg is the text of the message.
+ leftmargin is the position of the left margin.
+ rightmargin is the position of the right margin.
+
+ Return the formatted message.
+ """
+ curs = leftmargin
+ fmsg = " " * leftmargin
+
+ for w in msg.split():
+ l = len(w)
+ if curs != leftmargin and curs + l > rightmargin:
+ fmsg = fmsg + "\n" + (" " * leftmargin)
+ curs = leftmargin
+
+ if curs > leftmargin:
+ fmsg = fmsg + " "
+ curs = curs + 1
+
+ fmsg = fmsg + w
+ curs = curs + l
+
+ return fmsg
+
+
+def parse_build_macros(filename, names, overrides=None, properties=None):
+ """Parse a qmake compatible file of build system macros and convert it to a
+ dictionary. A macro is a name/value pair. The dictionary is returned or
+ None if any of the overrides was invalid.
+
+ filename is the name of the file to parse.
+ names is a list of the macro names to extract from the file.
+ overrides is an optional list of macro names and values that modify those
+ found in the file. They are of the form "name=value" (in which case the
+ value replaces the value found in the file) or "name+=value" (in which case
+ the value is appended to the value found in the file).
+ properties is an optional dictionary of property name and values that are
+ used to resolve any expressions of the form "$[name]" in the file.
+ """
+ # Validate and convert the overrides to a dictionary.
+ orides = {}
+
+ if overrides is not None:
+ for oride in overrides:
+ prefix = ""
+ name_end = oride.find("+=")
+
+ if name_end >= 0:
+ prefix = "+"
+ val_start = name_end + 2
+ else:
+ name_end = oride.find("=")
+
+ if name_end >= 0:
+ val_start = name_end + 1
+ else:
+ return None
+
+ name = oride[:name_end]
+
+ if name not in names:
+ return None
+
+ orides[name] = prefix + oride[val_start:]
+
+ # This class defines a file like object that handles the nested include()
+ # directives in qmake files.
+ class qmake_build_file_reader:
+ def __init__(self, filename):
+ self.filename = filename
+ self.currentfile = None
+ self.filestack = []
+ self.pathstack = []
+ self.cond_fname = None
+ self._openfile(filename)
+
+ def _openfile(self, filename):
+ try:
+ f = open(filename, 'r')
+ except IOError:
+ # If this file is conditional then don't raise an error.
+ if self.cond_fname == filename:
+ return
+
+ error("Unable to open %s" % filename)
+
+ if self.currentfile:
+ self.filestack.append(self.currentfile)
+ self.pathstack.append(self.path)
+
+ self.currentfile = f
+ self.path = os.path.dirname(filename)
+
+ def readline(self):
+ line = self.currentfile.readline()
+ sline = line.strip()
+
+ if self.cond_fname and sline == '}':
+ # The current condition is closed.
+ self.cond_fname = None
+ line = self.currentfile.readline()
+ elif sline.startswith('exists(') and sline.endswith('{'):
+ # A new condition is opened so extract the filename.
+ self.cond_fname = self._normalise(sline[:-1].strip()[7:-1].strip())
+ line = self.currentfile.readline()
+ elif sline.startswith('include('):
+ nextfile = self._normalise(sline[8:-1].strip())
+ self._openfile(nextfile)
+ return self.readline()
+
+ if not line and self.filestack:
+ self.currentfile = self.filestack.pop()
+ self.path = self.pathstack.pop()
+ return self.readline()
+
+ return line
+
+ # Normalise a filename by expanding any environment variables and
+ # making sure it is absolute.
+ def _normalise(self, fname):
+ if "$(" in fname:
+ fname = os.path.normpath(self._expandvars(fname))
+
+ if not os.path.isabs(fname):
+ fname = os.path.join(self.path, fname)
+
+ return fname
+
+ # Expand the environment variables in a filename.
+ def _expandvars(self, fname):
+ i = 0
+ while True:
+ m = re.search(r'\$\((\w+)\)', fname[i:])
+ if not m:
+ break
+
+ i, j = m.span(0)
+ name = m.group(1)
+ if name in os.environ:
+ tail = fname[j:]
+ fname = fname[:i] + os.environ[name]
+ i = len(fname)
+ fname += tail
+ else:
+ i = j
+
+ return fname
+
+ f = qmake_build_file_reader(filename)
+
+ # Get everything into a dictionary.
+ raw = {
+ "DIR_SEPARATOR": os.sep,
+ "LITERAL_WHITESPACE": " ",
+ "LITERAL_DOLLAR": "$",
+ "LITERAL_HASH": "#"
+ }
+
+ line = f.readline()
+ while line:
+ # Handle line continuations.
+ while len(line) > 1 and line[-2] == "\\":
+ line = line[:-2]
+
+ next = f.readline()
+
+ if next:
+ line = line + next
+ else:
+ break
+
+ line = line.strip()
+
+ # Ignore comments.
+ if line and line[0] != "#":
+ assstart = line.find("+")
+ if assstart > 0 and line[assstart + 1] == '=':
+ adding = True
+ assend = assstart + 1
+ else:
+ adding = False
+ assstart = line.find("=")
+ assend = assstart
+
+ if assstart > 0:
+ lhs = line[:assstart].strip()
+ rhs = line[assend + 1:].strip()
+
+ # Remove the escapes for any quotes.
+ rhs = rhs.replace(r'\"', '"').replace(r"\'", "'")
+
+ if adding and rhs != "":
+ orig_rhs = raw.get(lhs)
+ if orig_rhs is not None:
+ rhs = orig_rhs + " " + rhs
+
+ raw[lhs] = rhs
+
+ line = f.readline()
+
+ # Go through the raw dictionary extracting the macros we need and
+ # resolving any macro expansions. First of all, make sure every macro has
+ # a value.
+ refined = {}
+
+ for m in names:
+ refined[m] = ""
+
+ macro_prefix = "QMAKE_"
+
+ for lhs in list(raw.keys()):
+ # Strip any prefix.
+ if lhs.find(macro_prefix) == 0:
+ reflhs = lhs[len(macro_prefix):]
+ else:
+ reflhs = lhs
+
+ # See if we are interested in this one.
+ if reflhs not in names:
+ continue
+
+ rhs = raw[lhs]
+
+ # Resolve any references.
+ estart = rhs.find("$$(")
+ mstart = rhs.find("$$")
+
+ while mstart >= 0 and mstart != estart:
+ rstart = mstart + 2
+ if rstart < len(rhs) and rhs[rstart] == "{":
+ rstart = rstart + 1
+ term = "}"
+ elif rstart < len(rhs) and rhs[rstart] == "[":
+ rstart = rstart + 1
+ term = "]"
+ else:
+ term = string.whitespace
+
+ mend = rstart
+ while mend < len(rhs) and rhs[mend] not in term:
+ mend = mend + 1
+
+ lhs = rhs[rstart:mend]
+
+ if term in "}]":
+ mend = mend + 1
+
+ if term == "]":
+ if properties is None or lhs not in list(properties.keys()):
+ error("%s: property '%s' is not defined." % (filename, lhs))
+
+ value = properties[lhs]
+ else:
+ try:
+ value = raw[lhs]
+ except KeyError:
+ # We used to treat this as an error, but Qt v4.3.0 has at
+ # least one case that refers to an undefined macro. If
+ # qmake handles it then this must be the correct behaviour.
+ value = ""
+
+ rhs = rhs[:mstart] + value + rhs[mend:]
+ estart = rhs.find("$$(")
+ mstart = rhs.find("$$")
+
+ # Expand any POSIX style environment variables.
+ pleadin = ["$$(", "$("]
+
+ for pl in pleadin:
+ estart = rhs.find(pl)
+
+ if estart >= 0:
+ nstart = estart + len(pl)
+ break
+ else:
+ estart = -1
+
+ while estart >= 0:
+ eend = rhs[nstart:].find(")")
+
+ if eend < 0:
+ break
+
+ eend = nstart + eend
+
+ name = rhs[nstart:eend]
+
+ try:
+ env = os.environ[name]
+ except KeyError:
+ env = ""
+
+ rhs = rhs[:estart] + env + rhs[eend + 1:]
+
+ for pl in pleadin:
+ estart = rhs.find(pl)
+
+ if estart >= 0:
+ nstart = estart + len(pl)
+ break
+ else:
+ estart = -1
+
+ # Expand any Windows style environment variables.
+ estart = rhs.find("%")
+
+ while estart >= 0:
+ eend = rhs[estart + 1:].find("%")
+
+ if eend < 0:
+ break
+
+ eend = estart + 1 + eend
+
+ name = rhs[estart + 1:eend]
+
+ try:
+ env = os.environ[name]
+ except KeyError:
+ env = ""
+
+ rhs = rhs[:estart] + env + rhs[eend + 1:]
+
+ estart = rhs.find("%")
+
+ refined[reflhs] = rhs
+
+ # Handle the user overrides.
+ for lhs in list(orides.keys()):
+ rhs = refined[lhs]
+ oride = orides[lhs]
+
+ if oride.find("+") == 0:
+ if rhs:
+ rhs = rhs + " " + oride[1:]
+ else:
+ rhs = oride[1:]
+ else:
+ rhs = oride
+
+ refined[lhs] = rhs
+
+ return refined
+
+
+def create_wrapper(script, wrapper, gui=0, use_arch=''):
+ """Create a platform dependent executable wrapper around a Python script.
+
+ script is the full pathname of the script.
+ wrapper is the name of the wrapper file to create.
+ gui is non-zero if a GUI enabled version of the interpreter should be used.
+ use_arch is the MacOS/X architecture to invoke python with.
+
+ Returns the platform specific name of the wrapper.
+ """
+ if sys.platform == "win32":
+ wrapper = wrapper + ".bat"
+
+ wf = open(wrapper, "w")
+
+ if sys.platform == "win32":
+ exe = sys.executable
+
+ if gui:
+ exe = exe[:-4] + "w.exe"
+
+ wf.write("@\"%s\" \"%s\" %%1 %%2 %%3 %%4 %%5 %%6 %%7 %%8 %%9\n" % (exe, script))
+ elif sys.platform == "darwin":
+ # The installation of MacOS's python is a mess that changes from
+ # version to version and where sys.executable is useless.
+
+ if gui:
+ exe = "pythonw"
+ else:
+ exe = "python"
+
+ version = sys.version_info
+ exe = "%s%d.%d" % (exe, version[0], version[1])
+
+ if use_arch:
+ # Note that this may not work with the "standard" interpreter but
+ # should with the "pythonX.Y" version.
+ exe = "arch -%s %s" % (use_arch, exe)
+
+ wf.write("#!/bin/sh\n")
+ wf.write("exec %s %s ${1+\"$@\"}\n" % (exe, script))
+ else:
+ wf.write("#!/bin/sh\n")
+ wf.write("exec %s %s ${1+\"$@\"}\n" % (sys.executable, script))
+
+ wf.close()
+
+ if sys.platform != "win32":
+ sbuf = os.stat(wrapper)
+ mode = sbuf.st_mode
+ mode |= (stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
+
+ os.chmod(wrapper, mode)
+
+ return wrapper
diff --git a/specs/aix-g++ b/specs/aix-g++
new file mode 100644
index 0000000..438185a
--- /dev/null
+++ b/specs/aix-g++
@@ -0,0 +1,79 @@
+#
+# qmake configuration for aix-g++
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -mpowerpc
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB =
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD = -D_THREAD_SAFE
+
+QMAKE_CXX = g++
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /usr/X11R6/include
+QMAKE_LIBDIR_X11 = /usr/X11R6/lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/X11R6/include
+QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+QMAKE_LINK = g++
+QMAKE_LINK_SHLIB = g++
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME =
+QMAKE_LFLAGS_THREAD = -L/usr/lib/threads
+QMAKE_AIX_SHLIB = 1
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lpthreads
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/aix-g++-64 b/specs/aix-g++-64
new file mode 100644
index 0000000..231f3dd
--- /dev/null
+++ b/specs/aix-g++-64
@@ -0,0 +1,79 @@
+#
+# qmake configuration for aix-g++-64
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -maix64
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB =
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD = -D_THREAD_SAFE
+
+QMAKE_CXX = g++
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /usr/X11R6/include
+QMAKE_LIBDIR_X11 = /usr/X11R6/lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/X11R6/include
+QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+QMAKE_LINK = g++
+QMAKE_LINK_SHLIB = g++
+QMAKE_LFLAGS = -maix64
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME =
+QMAKE_LFLAGS_THREAD = -L/usr/lib/threads
+QMAKE_AIX_SHLIB = 1
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lpthreads
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar -X64 cq
+QMAKE_RANLIB = ranlib -X64
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/aix-xlc b/specs/aix-xlc
new file mode 100644
index 0000000..fd288a3
--- /dev/null
+++ b/specs/aix-xlc
@@ -0,0 +1,82 @@
+#
+# qmake configuration for aix-xlc
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = xlc
+QMAKE_CC_THREAD = xlc_r
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -qstrict
+QMAKE_CFLAGS_WARN_ON =
+QMAKE_CFLAGS_WARN_OFF =
+QMAKE_CFLAGS_RELEASE = -O3
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB =
+QMAKE_CFLAGS_YACC =
+QMAKE_CFLAGS_THREAD = -qthreaded
+
+QMAKE_CXX = xlC
+QMAKE_CXX_THREAD = xlC_r
+QMAKE_CXXFLAGS = -+ $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 =
+QMAKE_LIBDIR_X11 =
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL =
+QMAKE_LIBDIR_OPENGL =
+
+QMAKE_LINK = xlC
+QMAKE_LINK_THREAD = xlC_r
+QMAKE_LINK_SHLIB = ld
+QMAKE_LINK_SHLIB_CMD = makeC++SharedLib -p 0 \
+ -o $(TARGET) $(LFLAGS) $(OBJECTS) $(OBJMOC) $(LIBS)
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB =
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME =
+QMAKE_LFLAGS_THREAD = -L/usr/lib/threads
+QMAKE_AIX_SHLIB = 1
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lpthreads
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cq
+QMAKE_RANLIB = ranlib
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/aix-xlc-64 b/specs/aix-xlc-64
new file mode 100644
index 0000000..56501e7
--- /dev/null
+++ b/specs/aix-xlc-64
@@ -0,0 +1,84 @@
+#
+# qmake configuration for aix-xlc
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = xlc
+QMAKE_CC_THREAD = xlc_r
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -qstrict -q64
+# -qwarn64 turns on too many bogus warnings and shadows real warnings
+#QMAKE_CFLAGS_WARN_ON = -qwarn64
+QMAKE_CFLAGS_WARN_ON =
+QMAKE_CFLAGS_WARN_OFF =
+QMAKE_CFLAGS_RELEASE = -O3
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB =
+QMAKE_CFLAGS_YACC =
+QMAKE_CFLAGS_THREAD = -qthreaded
+
+QMAKE_CXX = xlC
+QMAKE_CXX_THREAD = xlC_r
+QMAKE_CXXFLAGS = -+ $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 =
+QMAKE_LIBDIR_X11 =
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL =
+QMAKE_LIBDIR_OPENGL =
+
+QMAKE_LINK = xlC
+QMAKE_LINK_THREAD = xlC_r
+QMAKE_LINK_SHLIB = ld
+QMAKE_LINK_SHLIB_CMD = makeC++SharedLib -p 0 -X 64 \
+ -o $(TARGET) $(LFLAGS) $(OBJECTS) $(OBJMOC) $(LIBS)
+QMAKE_LFLAGS = -q64
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB =
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME =
+QMAKE_LFLAGS_THREAD = -L/usr/lib/threads
+QMAKE_AIX_SHLIB = 1
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lpthreads
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar -X64 cq
+QMAKE_RANLIB = ranlib -X64
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/bsdi-g++ b/specs/bsdi-g++
new file mode 100644
index 0000000..9467536
--- /dev/null
+++ b/specs/bsdi-g++
@@ -0,0 +1,84 @@
+#
+# $Id: bsdi-g++,v 1.2 2004/01/21 18:33:32 phil Exp $
+#
+# qmake configuration for bsdi-g++
+#
+# Written for WindRiver BSD/OS 4.0.
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+
+QMAKE_CC = gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS =
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD =
+
+QMAKE_CXX = g++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /usr/X11R6/include
+QMAKE_LIBDIR_X11 = /usr/X11R6/lib
+QMAKE_INCDIR_QT = $(QTDIR)/include
+QMAKE_LIBDIR_QT = $(QTDIR)/lib
+QMAKE_INCDIR_OPENGL = /usr/X11R6/include
+QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+QMAKE_LINK = g++
+QMAKE_LINK_SHLIB = g++
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,-soname,
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -Wl,-rpath,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_QT = -lqt
+QMAKE_LIBS_QT_THREAD = -lqt-mt
+QMAKE_LIBS_OPENGL = -lGLU -lGL -lXmu
+QMAKE_LIBS_OPENGL_QT = -lGL -lXmu
+QMAKE_LIBS_THREAD =
+
+QMAKE_MOC = $(QTDIR)/bin/moc
+QMAKE_UIC = $(QTDIR)/bin/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
diff --git a/specs/cygwin-g++ b/specs/cygwin-g++
new file mode 100644
index 0000000..09d47d0
--- /dev/null
+++ b/specs/cygwin-g++
@@ -0,0 +1,86 @@
+#
+# $Id: cygwin-g++,v 1.2 2004/01/21 18:33:32 phil Exp $
+#
+# qmake configuration for cygwin-g++
+#
+# Written for Qt/X11 on Cygwin, using the POSIX API.
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release incremental link_prl
+QMAKE_INCREMENTAL_STYLE = sublib
+
+QMAKE_CC = gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = byacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -pipe
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB =
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD = -D_REENTRANT
+
+QMAKE_CXX = g++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /usr/X11R6/include
+QMAKE_LIBDIR_X11 = /usr/X11R6/lib
+QMAKE_INCDIR_QT = $(QTDIR)/include
+QMAKE_LIBDIR_QT = $(QTDIR)/lib
+QMAKE_INCDIR_OPENGL = /usr/X11R6/include
+QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+QMAKE_LINK = g++
+QMAKE_LINK_SHLIB = g++
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,-soname,
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -Wl,-rpath,
+QMAKE_CYGWIN_SHLIB = 1
+QMAKE_CYGWIN_EXE = 1
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_QT = -lqt
+QMAKE_LIBS_QT_THREAD = -lqt-mt
+QMAKE_LIBS_OPENGL = -lGLU -lGL -lXmu
+QMAKE_LIBS_OPENGL_QT = -lGL -lXmu
+QMAKE_LIBS_THREAD = -lpthread
+
+QMAKE_MOC = $(QTDIR)/bin/moc
+QMAKE_UIC = $(QTDIR)/bin/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
diff --git a/specs/darwin-g++ b/specs/darwin-g++
new file mode 100644
index 0000000..11e62dc
--- /dev/null
+++ b/specs/darwin-g++
@@ -0,0 +1,89 @@
+#
+# qmake configuration for darwin-g++
+#
+# Written for Qt/X11 on Darwin and XFree86
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl native_precompiled_headers
+QT += core gui
+DEFINES += __USE_WS_X11__
+
+QMAKE_CC = cc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -pipe
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_EXTENSION_SHLIB = dylib
+QMAKE_EXTENSION_PLUGIN = so
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD =
+
+QMAKE_CXX = c++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD =
+
+QMAKE_INCDIR = /usr/local/include
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /usr/X11R6/include
+QMAKE_LIBDIR_X11 = /usr/X11R6/lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/X11R6/include
+QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+QMAKE_LINK = c++
+QMAKE_LINK_SHLIB = c++
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_APP = -prebind
+QMAKE_LFLAGS_SHLIB = -prebind -dynamiclib -single_module -headerpad_max_install_names
+QMAKE_LFLAGS_PLUGIN = -bundle
+QMAKE_LFLAGS_THREAD =
+
+QMAKE_LFLAGS_VERSION = -current_version$${LITERAL_WHITESPACE}
+QMAKE_LFLAGS_COMPAT_VERSION = -compatibility_version$${LITERAL_WHITESPACE}
+
+QMAKE_RPATH =
+
+QMAKE_LIBS_DYNLOAD =
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD =
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cq
+QMAKE_RANLIB = ranlib -s
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_COPY_FILE = $$QMAKE_COPY
+QMAKE_COPY_DIR = $$QMAKE_COPY -r
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/dgux-g++ b/specs/dgux-g++
new file mode 100644
index 0000000..76e01ac
--- /dev/null
+++ b/specs/dgux-g++
@@ -0,0 +1,77 @@
+#
+# $Id: dgux-g++,v 1.2 2004/01/21 18:33:32 phil Exp $
+#
+# qmake configuration for dgux-g++
+#
+# Written for DG/UX R4.20MU06.
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+
+QMAKE_CC = gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS =
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+QMAKE_CXX = g++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /usr/X11R6/include
+QMAKE_LIBDIR_X11 = /usr/X11R6/lib
+QMAKE_INCDIR_QT = $(QTDIR)/include
+QMAKE_LIBDIR_QT = $(QTDIR)/lib
+QMAKE_INCDIR_OPENGL = /usr/X11R6/include
+QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+QMAKE_LINK = g++
+QMAKE_LINK_SHLIB = g++
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,-h,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_QT = -lqt
+
+QMAKE_LIBS_OPENGL = -lGLU -lGL -lXmu
+QMAKE_LIBS_OPENGL_QT = -lGL -lXmu
+
+QMAKE_MOC = $(QTDIR)/bin/moc
+QMAKE_UIC = $(QTDIR)/bin/uic
+
+QMAKE_AR = ar cq
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
diff --git a/specs/freebsd-g++ b/specs/freebsd-g++
new file mode 100644
index 0000000..7a42410
--- /dev/null
+++ b/specs/freebsd-g++
@@ -0,0 +1,80 @@
+#
+# qmake configuration for freebsd-g++
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -pipe
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD = -pthread -D_THREAD_SAFE
+
+QMAKE_CXX = g++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+# Addon software goes into /usr/local on the BSDs, by default we will look there
+QMAKE_INCDIR = /usr/local/include
+QMAKE_LIBDIR = /usr/local/lib
+QMAKE_INCDIR_X11 = /usr/X11R6/include
+QMAKE_LIBDIR_X11 = /usr/X11R6/lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/X11R6/include
+QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+QMAKE_LINK = g++
+QMAKE_LINK_SHLIB = g++
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,-soname,
+QMAKE_LFLAGS_THREAD = -pthread
+QMAKE_RPATH = -Wl,-rpath,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD =
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD =
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/freebsd-g++34 b/specs/freebsd-g++34
new file mode 100644
index 0000000..24c7786
--- /dev/null
+++ b/specs/freebsd-g++34
@@ -0,0 +1,80 @@
+#
+# qmake configuration for freebsd-g++34 (using g++34 from ports/lang/gcc34)
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = gcc34
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -pipe
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD = -pthread -D_THREAD_SAFE
+
+QMAKE_CXX = g++34
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+# Addon software goes into /usr/local on the BSDs, by default we will look there
+QMAKE_INCDIR = /usr/local/include
+QMAKE_LIBDIR = /usr/local/lib
+QMAKE_INCDIR_X11 = /usr/X11R6/include
+QMAKE_LIBDIR_X11 = /usr/X11R6/lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/X11R6/include
+QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+QMAKE_LINK = g++34
+QMAKE_LINK_SHLIB = g++34
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,-soname,
+QMAKE_LFLAGS_THREAD = -pthread
+QMAKE_RPATH = -Wl,-rpath,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD =
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD =
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/freebsd-g++40 b/specs/freebsd-g++40
new file mode 100644
index 0000000..cb8f58e
--- /dev/null
+++ b/specs/freebsd-g++40
@@ -0,0 +1,80 @@
+#
+# qmake configuration for freebsd-g++40 (using g++40 from ports/lang/gcc40)
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = gcc40
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -pipe
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD = -pthread -D_THREAD_SAFE
+
+QMAKE_CXX = g++40
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+# Addon software goes into /usr/local on the BSDs, by default we will look there
+QMAKE_INCDIR = /usr/local/include
+QMAKE_LIBDIR = /usr/local/lib
+QMAKE_INCDIR_X11 = /usr/X11R6/include
+QMAKE_LIBDIR_X11 = /usr/X11R6/lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/X11R6/include
+QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+QMAKE_LINK = g++40
+QMAKE_LINK_SHLIB = g++40
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,-soname,
+QMAKE_LFLAGS_THREAD = -pthread
+QMAKE_RPATH = -Wl,-rpath,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD =
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD =
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/freebsd-icc b/specs/freebsd-icc
new file mode 100644
index 0000000..71d08b7
--- /dev/null
+++ b/specs/freebsd-icc
@@ -0,0 +1,105 @@
+#
+# qmake configuration for freebsd-icc
+#
+# Written for Intel C++ 7.1 and 8.0 on FreeBSD
+#
+# Note: Some of the remarks from the Intel compiler are disabled (even
+# with 'warn_on' specified):
+#
+# remark #171: invalid type conversion: "int" to "void *"
+# remark #193: zero used for undefined preprocessing identifier
+# remark #279: controlling expression is constant
+# remark #304: access control not specified ("public" by default)
+# remark #310: old-style parameter list (anachronism)
+# remark #383: value copied to temporary, reference to temporary used
+# remark #424: extra ";" ignored
+# remark #444: destructor for base class "Class" is not virtual
+# remark #488: template parameter "T" is not used in declaring the parameter
+# types of function template "function"
+# remark #810: conversion from "type1" to "type2" may loose significant bits
+# remark #858: type qualifier on return type is meaningless
+# remark #967: conversion from "type1" to "type2"; sizes do not match
+# remark #981: operands are evaluated in unspecified order
+# remark #1418: external definition with no prior declaration
+# remark #1419: external declaration in primary source file
+# warning #1476: field uses tail padding of a base class
+# warning #1477: GNU C++ compilers may use bit field padding
+# warning #1572: floating-point equality and inequality comparisons are unreliable
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = icc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -wd858,1572
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -w2 -wd171,193,279,304,310,383,424,444,488,810,967,981,1418,1419,1476,1477
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE =
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -KPIC
+QMAKE_CFLAGS_YACC =
+QMAKE_CFLAGS_THREAD = -D_THREAD_SAFE
+
+QMAKE_CXX = icpc
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+# Addon software goes into /usr/local on the BSDs, by default we will look there
+QMAKE_INCDIR = /usr/local/include
+QMAKE_LIBDIR = /usr/local/lib
+QMAKE_INCDIR_X11 = /usr/X11R6/include
+QMAKE_LIBDIR_X11 = /usr/X11R6/lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/X11R6/include
+QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+QMAKE_LINK = icpc
+QMAKE_LINK_SHLIB = icpc
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Qoption,ld,-soname,
+QMAKE_LFLAGS_THREAD = -mt
+QMAKE_RPATH = -Qoption,ld,-rpath,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD =
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD =
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/hpux-acc b/specs/hpux-acc
new file mode 100644
index 0000000..0a78d97
--- /dev/null
+++ b/specs/hpux-acc
@@ -0,0 +1,103 @@
+#
+# qmake configuration for hpux-acc
+#
+# We define _POSIX_C_SOURCE to 199506L when using threads, therefore
+# we also need to redefine _HPUX_SOURCE. See pthread(3t) for more details.
+#
+# From the "HP aC++ Online Programmer's Guide":
+# Using +DS to Specify Instruction Scheduling:
+# * By default, the compiler performs scheduling tuned for the system
+# on which you are compiling, or, if specified, tuned for the setting
+# of the +DA option.
+#
+# From the online "C/HP-UX Reference Manual":
+# -Aa
+# Enables strict ANSI C compliance.
+# -Ae
+# Enables ANSI C compliance, HP value-added features (as described
+# for +e option), and _HPUX_SOURCE name space macro. It is equivalent
+# to -Aa +e -D_HPUX_SOURCE.
+# +e
+# Enables the following HP value added features while compiling in
+# ANSI C mode: sized enum, long long, long pointers, compiler supplied
+# defaults for missing arguments to intrinsic calls, and $ in identifier
+# HP C extensions.
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = cc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -Ae +DAportable -w
+QMAKE_CFLAGS_WARN_ON =
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = +O1
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = +Z
+QMAKE_CFLAGS_YACC =
+QMAKE_CFLAGS_THREAD = -D_POSIX_C_SOURCE=199506L -D_HPUX_SOURCE
+
+QMAKE_CXX = aCC
+QMAKE_CXXFLAGS = -AA +DAportable -w -D__STRICT_ANSI__ -D_HPUX_SOURCE
+QMAKE_CXXFLAGS_DEPS = +M
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = -D_POSIX_C_SOURCE=199506L
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /usr/include/X11R6
+QMAKE_LIBDIR_X11 = /usr/lib/X11R6
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /opt/graphics/OpenGL/include /usr/contrib/X11R6/include
+QMAKE_LIBDIR_OPENGL = /opt/graphics/OpenGL/lib /usr/contrib/X11R6/lib
+
+QMAKE_LINK = aCC
+QMAKE_LINK_SHLIB = aCC
+QMAKE_LFLAGS = -AA +DAportable -Wl,+s
+QMAKE_LFLAGS_RELEASE = -O
+QMAKE_LFLAGS_DEBUG = -g
+QMAKE_LFLAGS_SHLIB = -b -Wl,-a,shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,+h,
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -Wl,+b,
+QMAKE_HPUX_SHLIB = 1
+QMAKE_EXTENSION_SHLIB = sl
+
+QMAKE_LIBS = -lm
+QMAKE_LIBS_DYNLOAD = -ldld
+QMAKE_LIBS_X11 = -lXext -lX11
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_OPENGL = -lGLU -lGL -lXt
+QMAKE_LIBS_OPENGL_QT = -lGL -lXt
+QMAKE_LIBS_THREAD = -lpthread
+QMAKE_LIBS_YACC = -ly
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/hpux-acc-64 b/specs/hpux-acc-64
new file mode 100644
index 0000000..083c403
--- /dev/null
+++ b/specs/hpux-acc-64
@@ -0,0 +1,124 @@
+#
+# qmake configuration for hpux-n64
+#
+# We define _POSIX_C_SOURCE to 199506L when using threads, therefore
+# we also need to redefine _HPUX_SOURCE.
+# From pthread(3t):
+# Some documentation will recommend the use of -D_REENTRANT for
+# compilation. While this also functions properly, it is considered
+# an obsolescent form.
+# See pthread(3t) for more details.
+#
+# From the "HP aC++ Online Programmer's Guide":
+# When +DA2.0W is specified:
+# * 64-bit SVR4 Executable and Linking Format (ELF) object files
+# are generated for PA-RISC 2.0.
+# * The preprocessor predefined macro, __LP64__ is defined.
+# * The correct path for 64-bit system and language libraries is
+# selected.
+# When +DD32 is specified:
+# * The size of an int, long, or pointer data type is 32-bits.
+# The size of an int data type is 32-bits. The size of a long or
+# pointer data type is 64-bits.
+# * This is the default, currently equivalent to +DA1.1 architecture.
+# When +DD64 is specified:
+# * The size of an int data type is 32-bits. The size of a long or
+# pointer data type is 64-bits.
+# * This is currently equivalent to +DA2.OW architecture.
+# * The preprocessor predefined macro, __LP64__ is defined.
+# Using +DS to Specify Instruction Scheduling:
+# * By default, the compiler performs scheduling tuned for the system
+# on which you are compiling, or, if specified, tuned for the setting
+# of the +DA option.
+#
+# From the online "C/HP-UX Reference Manual":
+# -Aa
+# Enables strict ANSI C compliance.
+# -Ae
+# Enables ANSI C compliance, HP value-added features (as described
+# for +e option), and _HPUX_SOURCE name space macro. It is equivalent
+# to -Aa +e -D_HPUX_SOURCE.
+# +e
+# Enables the following HP value added features while compiling in
+# ANSI C mode: sized enum, long long, long pointers, compiler supplied
+# defaults for missing arguments to intrinsic calls, and $ in identifier
+# HP C extensions.
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = cc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -Ae +DA2.0W -w
+QMAKE_CFLAGS_WARN_ON =
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = +O1
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = +Z
+QMAKE_CFLAGS_YACC =
+QMAKE_CFLAGS_THREAD = -D_POSIX_C_SOURCE=199506L -D_HPUX_SOURCE
+
+QMAKE_CXX = aCC
+QMAKE_CXXFLAGS = -AA +DA2.0W -w -D__STRICT_ANSI__ -D_HPUX_SOURCE
+QMAKE_CXXFLAGS_DEPS = +M
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = -D_POSIX_C_SOURCE=199506L
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /usr/include/X11R6
+QMAKE_LIBDIR_X11 = /usr/lib/X11R6/pa20_64
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /opt/graphics/OpenGL/include /usr/contrib/X11R6/include
+QMAKE_LIBDIR_OPENGL = /opt/graphics/OpenGL/lib/pa20_64 /usr/contrib/X11R6/lib/pa20_64
+
+QMAKE_LINK = aCC
+QMAKE_LINK_SHLIB = aCC
+QMAKE_LFLAGS = -AA +DA2.0W -Wl,+s
+QMAKE_LFLAGS_RELEASE = -O
+QMAKE_LFLAGS_DEBUG = -g
+QMAKE_LFLAGS_SHLIB = -b -Wl,-a,shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,+h,
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -Wl,+b,
+QMAKE_HPUX_SHLIB = 3
+QMAKE_EXTENSION_SHLIB = sl
+
+QMAKE_LIBS = -lm
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_OPENGL = -lGLU -lGL -lXt
+QMAKE_LIBS_OPENGL_QT = -lGL -lXt
+QMAKE_LIBS_THREAD = -lpthread
+QMAKE_LIBS_YACC = -ly
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/hpux-acc-o64 b/specs/hpux-acc-o64
new file mode 100644
index 0000000..e6739a7
--- /dev/null
+++ b/specs/hpux-acc-o64
@@ -0,0 +1,123 @@
+#
+# qmake configuration for hpux-o64
+#
+# We define _POSIX_C_SOURCE to 199506L when using threads, therefore
+# we also need to redefine _HPUX_SOURCE.
+# From pthread(3t):
+# Some documentation will recommend the use of -D_REENTRANT for
+# compilation. While this also functions properly, it is considered
+# an obsolescent form.
+# See pthread(3t) for more details.
+#
+# From the "HP aC++ Online Programmer's Guide":
+# When +DA2.0W is specified:
+# * 64-bit SVR4 Executable and Linking Format (ELF) object files
+# are generated for PA-RISC 2.0.
+# * The preprocessor predefined macro, __LP64__ is defined.
+# * The correct path for 64-bit system and language libraries is
+# selected.
+# When +DD32 is specified:
+# * The size of an int, long, or pointer data type is 32-bits.
+# The size of an int data type is 32-bits. The size of a long or
+# pointer data type is 64-bits.
+# * This is the default, currently equivalent to +DA1.1 architecture.
+# When +DD64 is specified:
+# * The size of an int data type is 32-bits. The size of a long or
+# pointer data type is 64-bits.
+# * This is currently equivalent to +DA2.OW architecture.
+# * The preprocessor predefined macro, __LP64__ is defined.
+# Using +DS to Specify Instruction Scheduling:
+# * By default, the compiler performs scheduling tuned for the system
+# on which you are compiling, or, if specified, tuned for the setting
+# of the +DA option.
+#
+# From the online "C/HP-UX Reference Manual":
+# -Aa
+# Enables strict ANSI C compliance.
+# -Ae
+# Enables ANSI C compliance, HP value-added features (as described
+# for +e option), and _HPUX_SOURCE name space macro. It is equivalent
+# to -Aa +e -D_HPUX_SOURCE.
+# +e
+# Enables the following HP value added features while compiling in
+# ANSI C mode: sized enum, long long, long pointers, compiler supplied
+# defaults for missing arguments to intrinsic calls, and $ in identifier
+# HP C extensions.
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = cc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -Ae +DA2.0 -w
+QMAKE_CFLAGS_WARN_ON =
+QMAKE_CFLAGS_WARN_OFF =
+QMAKE_CFLAGS_RELEASE = -O +Oentrysched +Onolimit
+QMAKE_CFLAGS_DEBUG = -y -g
+QMAKE_CFLAGS_SHLIB = +Z
+QMAKE_CFLAGS_YACC =
+QMAKE_CFLAGS_THREAD = -D_POSIX_C_SOURCE=199506L -D_HPUX_SOURCE
+
+QMAKE_CXX = aCC
+QMAKE_CXXFLAGS = +DA2.0 -w -D__STRICT_ANSI__ -D_HPUX_SOURCE
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = -g
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = -D_POSIX_C_SOURCE=199506L
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /usr/include/X11R6
+QMAKE_LIBDIR_X11 = /usr/lib/X11R6
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /opt/graphics/OpenGL/include /usr/contrib/X11R6/include
+QMAKE_LIBDIR_OPENGL = /opt/graphics/OpenGL/lib /usr/contrib/X11R6/lib
+
+QMAKE_LINK = aCC
+QMAKE_LINK_SHLIB = aCC
+QMAKE_LFLAGS = +DA2.0 -Wl,+s
+QMAKE_LFLAGS_RELEASE = -O
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -b
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,+h,
+QMAKE_RPATH = -Wl,+b,
+QMAKE_HPUX_SHLIB = 2
+QMAKE_EXTENSION_SHLIB = sl
+
+QMAKE_LIBS = -lm
+QMAKE_LIBS_DYNLOAD = -ldld
+QMAKE_LIBS_X11 = -lXext -lX11
+QMAKE_LIBS_X11SM = -lSM -lICE
+
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lpthread
+QMAKE_LIBS_YACC = -ly
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/hpux-cc b/specs/hpux-cc
new file mode 100644
index 0000000..b19dc2b
--- /dev/null
+++ b/specs/hpux-cc
@@ -0,0 +1,100 @@
+#
+# $Id: hpux-cc,v 1.3 2004/03/01 18:40:21 phil Exp $
+#
+# qmake configuration for hpux-cc
+#
+# We define _POSIX_C_SOURCE to 199506L when using threads, therefore
+# we also need to redefine _HPUX_SOURCE.
+# See pthread(3t) for more details.
+#
+# From the "HP aC++ Online Programmer's Guide":
+# Using +DS to Specify Instruction Scheduling:
+# * By default, the compiler performs scheduling tuned for the system
+# on which you are compiling, or, if specified, tuned for the setting
+# of the +DA option.
+#
+# From the online "C/HP-UX Reference Manual":
+# -Aa
+# Enables strict ANSI C compliance.
+# -Ae
+# Enables ANSI C compliance, HP value-added features (as described
+# for +e option), and _HPUX_SOURCE name space macro. It is equivalent
+# to -Aa +e -D_HPUX_SOURCE.
+# +e
+# Enables the following HP value added features while compiling in
+# ANSI C mode: sized enum, long long, long pointers, compiler supplied
+# defaults for missing arguments to intrinsic calls, and $ in identifier
+# HP C extensions.
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+
+QMAKE_CC = cc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -Ae +DA1.1e -w
+QMAKE_CFLAGS_WARN_ON =
+QMAKE_CFLAGS_WARN_OFF =
+QMAKE_CFLAGS_RELEASE = -O
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = +Z
+QMAKE_CFLAGS_YACC =
+
+QMAKE_CXX = CC
+QMAKE_CXXFLAGS = +DA1.1e -w +a1 -D_HPUX_SOURCE
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /usr/include/X11R6
+QMAKE_LIBDIR_X11 = /usr/lib/X11R6
+QMAKE_INCDIR_QT = $(QTDIR)/include
+QMAKE_LIBDIR_QT = $(QTDIR)/lib
+QMAKE_INCDIR_OPENGL = /opt/graphics/OpenGL/include /usr/contrib/X11R6/include
+QMAKE_LIBDIR_OPENGL = /opt/graphics/OpenGL/lib /usr/contrib/X11R6/lib
+
+QMAKE_LINK = CC
+QMAKE_LINK_SHLIB = CC
+# CC generates template code during linking, and so needs -I's
+QMAKE_LFLAGS = +DA1.1e -Wl,+s -L/usr/lib -I$$QMAKE_INCDIR_X11 -I$$QMAKE_INCDIR_QT
+QMAKE_LFLAGS_RELEASE = -O -s
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -b
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,+h,
+QMAKE_RPATH = -Wl,+b,
+QMAKE_HPUX_SHLIB = 1
+
+QMAKE_LIBS = -lm
+QMAKE_LIBS_DYNLOAD = -ldld
+QMAKE_LIBS_X11 = -lXext -lX11
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_QT = -lqt
+
+QMAKE_LIBS_OPENGL = -lGLU -lGL -lXmu
+QMAKE_LIBS_OPENGL_QT = -lGL -lXmu
+
+QMAKE_MOC = $(QTDIR)/bin/moc
+QMAKE_UIC = $(QTDIR)/bin/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
diff --git a/specs/hpux-g++ b/specs/hpux-g++
new file mode 100644
index 0000000..5533993
--- /dev/null
+++ b/specs/hpux-g++
@@ -0,0 +1,85 @@
+#
+# qmake configuration for hpux-g++
+#
+# We define _POSIX_C_SOURCE to 199506L when using threads,
+# therefore we also need to redefine _HPUX_SOURCE.
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl plugin_no_soname
+QT += core gui
+
+QMAKE_CC = gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS =
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD = -D_POSIX_C_SOURCE=199506L -D_HPUX_SOURCE
+
+QMAKE_CXX = g++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -D_HPUX_SOURCE -DGLU_VERSION_1_2
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = -D_POSIX_C_SOURCE=199506L
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 =
+QMAKE_LIBDIR_X11 = /usr/lib/X11R6
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /opt/Mesa/include /usr/contrib/X11R6/include
+QMAKE_LIBDIR_OPENGL = /opt/Mesa/lib /usr/contrib/X11R6/lib
+
+QMAKE_LINK = g++
+QMAKE_LINK_SHLIB = g++
+QMAKE_LFLAGS = -Wl,+s
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -fPIC -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,+h,
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -Wl,+b,
+QMAKE_HPUX_SHLIB = 1
+QMAKE_EXTENSION_SHLIB = sl
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldld
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lpthread
+QMAKE_LIBS_YACC = -ly
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/hpux-g++-64 b/specs/hpux-g++-64
new file mode 100644
index 0000000..0b81fcd
--- /dev/null
+++ b/specs/hpux-g++-64
@@ -0,0 +1,85 @@
+#
+# qmake configuration for hpux-g++-64
+#
+# We define _POSIX_C_SOURCE to 199506L when using threads,
+# therefore we also need to redefine _HPUX_SOURCE.
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS =
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD = -D_POSIX_C_SOURCE=199506L -D_HPUX_SOURCE
+
+QMAKE_CXX = g++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -D_HPUX_SOURCE
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = -D_POSIX_C_SOURCE=199506L
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR = /usr/lib/pa20_64
+QMAKE_INCDIR_X11 = /usr/include/X11R6
+QMAKE_LIBDIR_X11 = /usr/lib/X11R6/pa20_64
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /opt/Mesa/include /usr/contrib/X11R6/include
+QMAKE_LIBDIR_OPENGL = /opt/Mesa/lib/pa20_64 /usr/contrib/X11R6/lib/pa20_64
+
+QMAKE_LINK = g++
+QMAKE_LINK_SHLIB = g++
+QMAKE_LFLAGS = -Wl,+s -lpthread
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -fPIC -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,+h,
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -Wl,+b,
+QMAKE_HPUX_SHLIB = 3
+QMAKE_EXTENSION_SHLIB = sl
+
+QMAKE_LIBS = -lm
+QMAKE_LIBS_DYNLOAD = -ldld
+QMAKE_LIBS_X11 = -lXext -lX11
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lpthread
+QMAKE_LIBS_YACC = -ly
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/hpuxi-acc b/specs/hpuxi-acc
new file mode 100644
index 0000000..1596ac2
--- /dev/null
+++ b/specs/hpuxi-acc
@@ -0,0 +1,122 @@
+#
+# qmake configuration for hpuxi-acc-32
+#
+# We define _POSIX_C_SOURCE to 199506L when using threads, therefore
+# we also need to redefine _HPUX_SOURCE.
+# From pthread(3t):
+# Some documentation will recommend the use of -D_REENTRANT for
+# compilation. While this also functions properly, it is considered
+# an obsolescent form.
+# See pthread(3t) for more details.
+#
+# From the "HP aC++ Online Programmer's Guide":
+# When +DA2.0W is specified:
+# * 64-bit SVR4 Executable and Linking Format (ELF) object files
+# are generated for PA-RISC 2.0.
+# * The preprocessor predefined macro, __LP64__ is defined.
+# * The correct path for 64-bit system and language libraries is
+# selected.
+# When +DD32 is specified:
+# * The size of an int, long, or pointer data type is 32-bits.
+# The size of an int data type is 32-bits. The size of a long or
+# pointer data type is 64-bits.
+# * This is the default, currently equivalent to +DA1.1 architecture.
+# When +DD64 is specified:
+# * The size of an int data type is 32-bits. The size of a long or
+# pointer data type is 64-bits.
+# * This is currently equivalent to +DA2.OW architecture.
+# * The preprocessor predefined macro, __LP64__ is defined.
+# Using +DS to Specify Instruction Scheduling:
+# * By default, the compiler performs scheduling tuned for the system
+# on which you are compiling, or, if specified, tuned for the setting
+# of the +DA option.
+#
+# From the online "C/HP-UX Reference Manual":
+# -Aa
+# Enables strict ANSI C compliance.
+# -Ae
+# Enables ANSI C compliance, HP value-added features (as described
+# for +e option), and _HPUX_SOURCE name space macro. It is equivalent
+# to -Aa +e -D_HPUX_SOURCE.
+# +e
+# Enables the following HP value added features while compiling in
+# ANSI C mode: sized enum, long long, long pointers, compiler supplied
+# defaults for missing arguments to intrinsic calls, and $ in identifier
+# HP C extensions.
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release plugin_no_soname
+QT += core gui
+
+QMAKE_CC = cc
+QMAKE_LEX = lex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = +DD32 +DSitanium -w
+QMAKE_CFLAGS_WARN_ON =
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = +O2 +Osize
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = +Z
+QMAKE_CFLAGS_YACC =
+QMAKE_CFLAGS_THREAD = -D_POSIX_C_SOURCE=199506L -D_HPUX_SOURCE
+
+QMAKE_CXX = aCC
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -D__STRICT_ANSI__ -D_HPUX_SOURCE
+QMAKE_CXXFLAGS_DEPS = +M
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = -D_POSIX_C_SOURCE=199506L
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /usr/include/X11R6
+QMAKE_LIBDIR_X11 = /usr/lib/hpux32/X11R6
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /opt/graphics/OpenGL/include /usr/contrib/X11R6/include
+QMAKE_LIBDIR_OPENGL = /opt/graphics/OpenGL/lib/hpux32 /usr/contrib/X11R6/lib/hpux32
+
+QMAKE_LINK = aCC
+QMAKE_LINK_SHLIB = aCC
+QMAKE_LFLAGS = +DD32 +DSitanium -Wl,+s
+QMAKE_LFLAGS_RELEASE = +O2
+QMAKE_LFLAGS_DEBUG = -g
+QMAKE_LFLAGS_SHLIB = -b -Wl,-a,shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,+h,
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH =
+
+QMAKE_LIBS = -lm
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_OPENGL = -lGLU -lGL -lXt
+QMAKE_LIBS_OPENGL_QT = -lGL -lXt
+QMAKE_LIBS_THREAD = -lpthread
+QMAKE_LIBS_YACC = -ly
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/hpuxi-acc-64 b/specs/hpuxi-acc-64
new file mode 100644
index 0000000..0763d14
--- /dev/null
+++ b/specs/hpuxi-acc-64
@@ -0,0 +1,122 @@
+#
+# qmake configuration for hpuxi-acc-64
+#
+# We define _POSIX_C_SOURCE to 199506L when using threads, therefore
+# we also need to redefine _HPUX_SOURCE.
+# From pthread(3t):
+# Some documentation will recommend the use of -D_REENTRANT for
+# compilation. While this also functions properly, it is considered
+# an obsolescent form.
+# See pthread(3t) for more details.
+#
+# From the "HP aC++ Online Programmer's Guide":
+# When +DA2.0W is specified:
+# * 64-bit SVR4 Executable and Linking Format (ELF) object files
+# are generated for PA-RISC 2.0.
+# * The preprocessor predefined macro, __LP64__ is defined.
+# * The correct path for 64-bit system and language libraries is
+# selected.
+# When +DD32 is specified:
+# * The size of an int, long, or pointer data type is 32-bits.
+# The size of an int data type is 32-bits. The size of a long or
+# pointer data type is 64-bits.
+# * This is the default, currently equivalent to +DA1.1 architecture.
+# When +DD64 is specified:
+# * The size of an int data type is 32-bits. The size of a long or
+# pointer data type is 64-bits.
+# * This is currently equivalent to +DA2.OW architecture.
+# * The preprocessor predefined macro, __LP64__ is defined.
+# Using +DS to Specify Instruction Scheduling:
+# * By default, the compiler performs scheduling tuned for the system
+# on which you are compiling, or, if specified, tuned for the setting
+# of the +DA option.
+#
+# From the online "C/HP-UX Reference Manual":
+# -Aa
+# Enables strict ANSI C compliance.
+# -Ae
+# Enables ANSI C compliance, HP value-added features (as described
+# for +e option), and _HPUX_SOURCE name space macro. It is equivalent
+# to -Aa +e -D_HPUX_SOURCE.
+# +e
+# Enables the following HP value added features while compiling in
+# ANSI C mode: sized enum, long long, long pointers, compiler supplied
+# defaults for missing arguments to intrinsic calls, and $ in identifier
+# HP C extensions.
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release plugin_no_soname
+QT += core gui
+
+QMAKE_CC = cc
+QMAKE_LEX = lex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = +DD64 +DSitanium -w
+QMAKE_CFLAGS_WARN_ON =
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = +O2 +Osize
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = +Z
+QMAKE_CFLAGS_YACC =
+QMAKE_CFLAGS_THREAD = -D_POSIX_C_SOURCE=199506L -D_HPUX_SOURCE
+
+QMAKE_CXX = aCC
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -D__STRICT_ANSI__ -D_HPUX_SOURCE
+QMAKE_CXXFLAGS_DEPS = +M
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = -D_POSIX_C_SOURCE=199506L
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /usr/include/X11R6
+QMAKE_LIBDIR_X11 = /usr/lib/hpux64/X11R6
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /opt/graphics/OpenGL/include /usr/contrib/X11R6/include
+QMAKE_LIBDIR_OPENGL = /opt/graphics/OpenGL/lib/hpux64 /usr/contrib/X11R6/lib/hpux64
+
+QMAKE_LINK = aCC
+QMAKE_LINK_SHLIB = aCC
+QMAKE_LFLAGS = +DD64 +DSitanium -Wl,+s
+QMAKE_LFLAGS_RELEASE = +O2
+QMAKE_LFLAGS_DEBUG = -g
+QMAKE_LFLAGS_SHLIB = -b -Wl,-a,shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,+h,
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH =
+
+QMAKE_LIBS = -lm
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_OPENGL = -lGLU -lGL -lXt
+QMAKE_LIBS_OPENGL_QT = -lGL -lXt
+QMAKE_LIBS_THREAD = -lpthread
+QMAKE_LIBS_YACC = -ly
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/hurd-g++ b/specs/hurd-g++
new file mode 100644
index 0000000..88539e8
--- /dev/null
+++ b/specs/hurd-g++
@@ -0,0 +1,77 @@
+#
+# qmake configuration for hurd-g++
+#
+# Submitted by uch@nop.or.jp as "gnu-g++".
+# Renamed to "hurd-g++" because people were confusing GNU/Hurd with GNU/Linux.
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+QT += core gui
+CONFIG += qt warn_on release link_prl
+
+QMAKE_CC = gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS =
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+QMAKE_CXX = g++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /usr/X11R6/include
+QMAKE_LIBDIR_X11 = /usr/X11R6/lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/X11R6/include
+QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+QMAKE_LINK = g++
+QMAKE_LINK_SHLIB = g++
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,-soname,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/irix-cc b/specs/irix-cc
new file mode 100644
index 0000000..efc47bc
--- /dev/null
+++ b/specs/irix-cc
@@ -0,0 +1,113 @@
+#
+# qmake configuration for irix-cc
+#
+# From cc(1):
+# -n32
+# Generates a (new) 32-bit object. This defaults to -mips3 if
+# -mips4 has not been specified.
+# -LANG: ...
+# The language feature option group controls the source language
+# interpretation assumed by the compiler. The individual controls
+# in this group are as follows:
+# ansi-for-init-scope [ = ( ON|OFF ) ]
+# Enables or disables the ANSI scoping rules for for-init
+# declarations (the scope of the name declared extends to
+# the end of the for statement). This enables the behavior
+# that is required by the C++ standard. The default value
+# is OFF, which is the ARM behavior (the scope of the name
+# declared extends to the end of the block enclosing the for
+# statement).
+# bool [ = ( ON|OFF ) ]
+# Enables or disables the predefined bool data type, along
+# with the predefined values true and false. Use this option
+# only to suppress this type in old code that defines bool
+# itself. Because this option changes the mangling of function
+# names with bool parameters, all files comprising a program
+# should be compiled with consistent options.
+# Default is ON.
+# The _BOOL feature macro can be used in #ifdefs to do conditional
+# compilation based on whether or not this option is enabled.
+# std
+# Enables use of the standard C++ library and standard-
+# conforming iostream library. Specifying this flag also
+# triggers other standard-conforming behavior, such as the
+# new rules for the scope of for loop initializers.
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = cc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -n32 -signed -woff 1209,1355,1375,1424,3303
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -fullwarn
+QMAKE_CFLAGS_WARN_OFF =
+QMAKE_CFLAGS_RELEASE = -O2 -OPT:Olimit=3000
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB =
+QMAKE_CFLAGS_YACC = -woff 1110,1174,3262
+QMAKE_CFLAGS_THREAD =
+
+QMAKE_CXX = CC
+QMAKE_CXXFLAGS = -n32 -signed -LANG:std:libc_in_namespace_std=ON -woff 1209,1355,1375,1424,3303
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD =
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 =
+QMAKE_LIBDIR_X11 =
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL =
+QMAKE_LIBDIR_OPENGL =
+
+QMAKE_LINK = CC
+QMAKE_LINK_SHLIB = CC
+QMAKE_LFLAGS = -n32
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG = -g
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,-soname,
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -Wl,-rpath,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD =
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_OPENGL = -lGLU -lGL -lm
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lpthread
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = CC -ar -o
+QMAKE_RANLIB =
+
+QMAKE_CLEAN = -r $(OBJECTS_DIR)so_locations $(OBJECTS_DIR)ii_files
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/irix-cc-64 b/specs/irix-cc-64
new file mode 100644
index 0000000..f83d1f9
--- /dev/null
+++ b/specs/irix-cc-64
@@ -0,0 +1,113 @@
+#
+# qmake configuration for irix-cc-64
+#
+# From cc(1):
+# -64
+# Generates a 64-bit object. This defaults to -mips4 if -mips3 has
+# not been specified.
+# -LANG: ...
+# The language feature option group controls the source language
+# interpretation assumed by the compiler. The individual controls
+# in this group are as follows:
+# ansi-for-init-scope [ = ( ON|OFF ) ]
+# Enables or disables the ANSI scoping rules for for-init
+# declarations (the scope of the name declared extends to
+# the end of the for statement). This enables the behavior
+# that is required by the C++ standard. The default value
+# is OFF, which is the ARM behavior (the scope of the name
+# declared extends to the end of the block enclosing the for
+# statement).
+# bool [ = ( ON|OFF ) ]
+# Enables or disables the predefined bool data type, along
+# with the predefined values true and false. Use this option
+# only to suppress this type in old code that defines bool
+# itself. Because this option changes the mangling of function
+# names with bool parameters, all files comprising a program
+# should be compiled with consistent options.
+# Default is ON.
+# The _BOOL feature macro can be used in #ifdefs to do conditional
+# compilation based on whether or not this option is enabled.
+# std
+# Enables use of the standard C++ library and standard-
+# conforming iostream library. Specifying this flag also
+# triggers other standard-conforming behavior, such as the
+# new rules for the scope of for loop initializers.
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = cc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -64 -signed -woff 1209,1355,1375,1424,3303
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -fullwarn
+QMAKE_CFLAGS_WARN_OFF =
+QMAKE_CFLAGS_RELEASE = -O2 -OPT:Olimit=3000
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB =
+QMAKE_CFLAGS_YACC = -woff 1110,1174,3262
+QMAKE_CFLAGS_THREAD =
+
+QMAKE_CXX = CC
+QMAKE_CXXFLAGS = -64 -signed -LANG:std:libc_in_namespace_std=ON -woff 1209,1355,1375,1424,3303
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD =
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 =
+QMAKE_LIBDIR_X11 =
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL =
+QMAKE_LIBDIR_OPENGL =
+
+QMAKE_LINK = CC
+QMAKE_LINK_SHLIB = CC
+QMAKE_LFLAGS = -64
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG = -g
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,-soname,
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -Wl,-rpath,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD =
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_OPENGL = -lGLU -lGL -lm
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lpthread
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = CC -ar -o
+QMAKE_RANLIB =
+
+QMAKE_CLEAN = -r $(OBJECTS_DIR)so_locations $(OBJECTS_DIR)ii_files
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/irix-cc-o32 b/specs/irix-cc-o32
new file mode 100644
index 0000000..0e98c77
--- /dev/null
+++ b/specs/irix-cc-o32
@@ -0,0 +1,89 @@
+#
+# $Id: irix-cc-o32,v 1.4 2005/01/29 10:15:15 phil Exp $
+#
+# qmake configuration for irix-cc-o32
+#
+# From cc(1):
+# -o32 or -32
+# Generates an (old) 32-bit object. See the o32(5) man page for
+# option descriptions and details. This defaults to -mips2 if
+# -mips1 has not been specified.
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+
+QMAKE_CC = cc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS = -o32 -signed -woff 3115,3203,3260,3672,3937
+QMAKE_CFLAGS_WARN_ON = -fullwarn
+QMAKE_CFLAGS_WARN_OFF =
+QMAKE_CFLAGS_RELEASE = -O2 -Olimit 3000
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB =
+QMAKE_CFLAGS_YACC = -woff 3203,3262
+QMAKE_CFLAGS_THREAD =
+
+QMAKE_CXX = CC
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD =
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 =
+QMAKE_LIBDIR_X11 =
+QMAKE_INCDIR_QT = $(QTDIR)/include
+QMAKE_LIBDIR_QT = $(QTDIR)/lib
+QMAKE_INCDIR_OPENGL =
+QMAKE_LIBDIR_OPENGL =
+
+QMAKE_LINK = CC
+QMAKE_LINK_SHLIB = CC
+QMAKE_LFLAGS = -o32
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,-soname,
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -Wl,-rpath,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD =
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_QT = -lqt
+QMAKE_LIBS_QT_THREAD = -lqt-mt
+QMAKE_LIBS_OPENGL = -lGLU -lGL -lXmu -lm
+QMAKE_LIBS_OPENGL_QT = -lGL -lXmu
+QMAKE_LIBS_THREAD = -lpthread
+
+QMAKE_MOC = $(QTDIR)/bin/moc
+QMAKE_UIC = $(QTDIR)/bin/uic
+
+QMAKE_AR = ar cq
+QMAKE_RANLIB =
+
+QMAKE_CLEAN = -r $(OBJECTS_DIR)so_locations $(OBJECTS_DIR)ii_files
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
diff --git a/specs/irix-g++ b/specs/irix-g++
new file mode 100644
index 0000000..5deaa1c
--- /dev/null
+++ b/specs/irix-g++
@@ -0,0 +1,84 @@
+#
+# qmake configuration for irix-g++
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS =
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD =
+
+QMAKE_CXX = g++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD =
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 =
+QMAKE_LIBDIR_X11 =
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL =
+QMAKE_LIBDIR_OPENGL =
+
+QMAKE_LINK = g++
+QMAKE_LINK_SHLIB = g++
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared -Wl,-LD_LAYOUT:lgot_buffer=1000
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,-soname,
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -Wl,-rpath,
+
+QMAKE_LIBS = -lC
+QMAKE_LIBS_DYNLOAD =
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+# libGLU is using the SGI C++ library internally and this somehow clashes
+# with the GNU C++ library (similar name mangling and symbol names?)
+# so we add -lC so that the SGI C++ library is used first...
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lpthread
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cq
+QMAKE_RANLIB =
+
+QMAKE_CLEAN = so_locations
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/irix-g++-64 b/specs/irix-g++-64
new file mode 100644
index 0000000..ade0ad3
--- /dev/null
+++ b/specs/irix-g++-64
@@ -0,0 +1,84 @@
+#
+# qmake configuration for irix-g++-64
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -mabi=64
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD =
+
+QMAKE_CXX = g++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD =
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 =
+QMAKE_LIBDIR_X11 =
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL =
+QMAKE_LIBDIR_OPENGL =
+
+QMAKE_LINK = g++
+QMAKE_LINK_SHLIB = g++
+QMAKE_LFLAGS = -mabi=64
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared -Wl,-LD_LAYOUT:lgot_buffer=1000
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,-soname,
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -Wl,-rpath,
+
+QMAKE_LIBS = -lC
+QMAKE_LIBS_DYNLOAD =
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+# libGLU is using the SGI C++ library internally and this somehow clashes
+# with the GNU C++ library (similar name mangling and symbol names?)
+# so we add -lC so that the SGI C++ library is used first...
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lpthread
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cq
+QMAKE_RANLIB =
+
+QMAKE_CLEAN = so_locations
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/linux-arm-g++ b/specs/linux-arm-g++
new file mode 100644
index 0000000..a1e1d4e
--- /dev/null
+++ b/specs/linux-arm-g++
@@ -0,0 +1,90 @@
+#
+# qmake configuration for linux-arm-g++
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release incremental link_prl
+QT += core gui
+QMAKE_INCREMENTAL_STYLE = sublib
+
+QMAKE_CC = arm-linux-gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_YACCFLAGS_MANGLE = -p $base -b $base
+QMAKE_YACC_HEADER = $base.tab.h
+QMAKE_YACC_SOURCE = $base.tab.c
+QMAKE_CFLAGS = -pipe
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD = -D_REENTRANT
+QMAKE_CFLAGS_HIDESYMS = -fvisibility=hidden
+
+QMAKE_CXX = arm-linux-g++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -fno-exceptions -fno-rtti
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+QMAKE_CXXFLAGS_HIDESYMS = $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 =
+QMAKE_LIBDIR_X11 =
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL =
+QMAKE_LIBDIR_OPENGL =
+
+QMAKE_LINK = arm-linux-g++
+QMAKE_LINK_SHLIB = arm-linux-g++
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,-soname,
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -Wl,-rpath,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 =
+QMAKE_LIBS_X11SM =
+QMAKE_LIBS_NIS = -lnsl
+QMAKE_LIBS_OPENGL =
+QMAKE_LIBS_OPENGL_QT =
+QMAKE_LIBS_THREAD = -lpthread
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = arm-linux-ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_COPY_FILE = $(COPY)
+QMAKE_COPY_DIR = $(COPY) -r
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_STRIP = arm-linux-strip
+QMAKE_STRIPFLAGS_LIB += --strip-unneeded
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/linux-arm-thumb-g++ b/specs/linux-arm-thumb-g++
new file mode 100644
index 0000000..31bb345
--- /dev/null
+++ b/specs/linux-arm-thumb-g++
@@ -0,0 +1,90 @@
+#
+# qmake configuration for linux-arm-thumb-g++
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release incremental link_prl
+QT += core gui
+QMAKE_INCREMENTAL_STYLE = sublib
+
+QMAKE_CC = arm-linux-gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_YACCFLAGS_MANGLE = -p $base -b $base
+QMAKE_YACC_HEADER = $base.tab.h
+QMAKE_YACC_SOURCE = $base.tab.c
+QMAKE_CFLAGS = -pipe -mthumb -mthumb-interwork
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD = -D_REENTRANT
+QMAKE_CFLAGS_HIDESYMS = -fvisibility=hidden
+
+QMAKE_CXX = arm-linux-g++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -fno-exceptions -fno-rtti
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+QMAKE_CXXFLAGS_HIDESYMS = $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 =
+QMAKE_LIBDIR_X11 =
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL =
+QMAKE_LIBDIR_OPENGL =
+
+QMAKE_LINK = arm-linux-g++
+QMAKE_LINK_SHLIB = arm-linux-g++
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,-soname,
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -Wl,-rpath,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 =
+QMAKE_LIBS_X11SM =
+QMAKE_LIBS_NIS = -lnsl
+QMAKE_LIBS_OPENGL =
+QMAKE_LIBS_OPENGL_QT =
+QMAKE_LIBS_THREAD = -lpthread
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = arm-linux-ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_COPY_FILE = $(COPY)
+QMAKE_COPY_DIR = $(COPY) -r
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_STRIP = arm-linux-strip
+QMAKE_STRIPFLAGS_LIB += --strip-unneeded
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/linux-armv6-g++ b/specs/linux-armv6-g++
new file mode 100644
index 0000000..92dbfd7
--- /dev/null
+++ b/specs/linux-armv6-g++
@@ -0,0 +1,90 @@
+#
+# qmake configuration for linux-arm-g++
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release incremental link_prl
+QT += core gui
+QMAKE_INCREMENTAL_STYLE = sublib
+
+QMAKE_CC = arm-linux-gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_YACCFLAGS_MANGLE = -p $base -b $base
+QMAKE_YACC_HEADER = $base.tab.h
+QMAKE_YACC_SOURCE = $base.tab.c
+QMAKE_CFLAGS = -pipe -march=armv6
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD = -D_REENTRANT
+QMAKE_CFLAGS_HIDESYMS = -fvisibility=hidden
+
+QMAKE_CXX = arm-linux-g++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -fno-exceptions -fno-rtti
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+QMAKE_CXXFLAGS_HIDESYMS = $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 =
+QMAKE_LIBDIR_X11 =
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL =
+QMAKE_LIBDIR_OPENGL =
+
+QMAKE_LINK = arm-linux-g++
+QMAKE_LINK_SHLIB = arm-linux-g++
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,-soname,
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -Wl,-rpath,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 =
+QMAKE_LIBS_X11SM =
+QMAKE_LIBS_NIS = -lnsl
+QMAKE_LIBS_OPENGL =
+QMAKE_LIBS_OPENGL_QT =
+QMAKE_LIBS_THREAD = -lpthread
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = arm-linux-ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_COPY_FILE = $(COPY)
+QMAKE_COPY_DIR = $(COPY) -r
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_STRIP = arm-linux-strip
+QMAKE_STRIPFLAGS_LIB += --strip-unneeded
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/linux-cxx b/specs/linux-cxx
new file mode 100644
index 0000000..fd5aae2
--- /dev/null
+++ b/specs/linux-cxx
@@ -0,0 +1,78 @@
+#
+# qmake configuration for linux-cxx
+#
+# Written for Compaq C++ for GNU/Linux on Alpha
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = ccc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -w
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON =
+QMAKE_CFLAGS_WARN_OFF =
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB =
+QMAKE_CFLAGS_YACC = -Olimit 1000
+
+QMAKE_CXX = cxx
+QMAKE_CXXFLAGS = -w
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /usr/X11R6/include
+QMAKE_LIBDIR_X11 = /usr/X11R6/lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/X11R6/include
+QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+QMAKE_LINK = cxx
+QMAKE_LINK_SHLIB = cxx
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,-soname,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_NIS = -lnsl
+
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/linux-ecc-64 b/specs/linux-ecc-64
new file mode 100644
index 0000000..a6b4327
--- /dev/null
+++ b/specs/linux-ecc-64
@@ -0,0 +1,84 @@
+#
+# qmake configuration for linux-ecc-64
+#
+# Written for Intel C++ 7.1 and 8.0 for Linux
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = ecc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS =
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON =
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -KPIC
+QMAKE_CFLAGS_YACC =
+QMAKE_CFLAGS_THREAD = -D_REENTRANT
+
+QMAKE_CXX = ecpc
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /usr/X11R6/include
+QMAKE_LIBDIR_X11 = /usr/X11R6/lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/X11R6/include
+QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+QMAKE_LINK = ecpc
+QMAKE_LINK_SHLIB = ecpc
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Qoption,ld,-soname,
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -Qoption,ld,-rpath,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_NIS = -lnsl
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lpthread
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_CLEAN = -r $(OBJECTS_DIR)/ti_files
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/linux-g++ b/specs/linux-g++
new file mode 100644
index 0000000..9d94ff3
--- /dev/null
+++ b/specs/linux-g++
@@ -0,0 +1,90 @@
+#
+# qmake configuration for linux-g++
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release incremental link_prl
+QT += core gui
+QMAKE_INCREMENTAL_STYLE = sublib
+
+QMAKE_CC = gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_YACCFLAGS_MANGLE = -p $base -b $base
+QMAKE_YACC_HEADER = $base.tab.h
+QMAKE_YACC_SOURCE = $base.tab.c
+QMAKE_CFLAGS = -pipe
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD = -D_REENTRANT
+QMAKE_CFLAGS_HIDESYMS = -fvisibility=hidden
+
+QMAKE_CXX = g++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+QMAKE_CXXFLAGS_HIDESYMS = $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /usr/X11R6/include
+QMAKE_LIBDIR_X11 = /usr/X11R6/lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/X11R6/include
+QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+QMAKE_LINK = g++
+QMAKE_LINK_SHLIB = g++
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,-soname,
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -Wl,-rpath,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_NIS = -lnsl
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lpthread
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_COPY_FILE = $(COPY)
+QMAKE_COPY_DIR = $(COPY) -r
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_STRIP = strip
+QMAKE_STRIPFLAGS_LIB += --strip-unneeded
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/linux-g++-32 b/specs/linux-g++-32
new file mode 100644
index 0000000..c0b7b79
--- /dev/null
+++ b/specs/linux-g++-32
@@ -0,0 +1,90 @@
+#
+# qmake configuration for linux-g++
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release incremental link_prl
+QT += core gui
+QMAKE_INCREMENTAL_STYLE = sublib
+
+QMAKE_CC = gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_YACCFLAGS_MANGLE = -p $base -b $base
+QMAKE_YACC_HEADER = $base.tab.h
+QMAKE_YACC_SOURCE = $base.tab.c
+QMAKE_CFLAGS = -m32 -pipe
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD = -D_REENTRANT
+QMAKE_CFLAGS_HIDESYMS = -fvisibility=hidden
+
+QMAKE_CXX = g++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+QMAKE_CXXFLAGS_HIDESYMS = $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /usr/X11R6/include
+QMAKE_LIBDIR_X11 = /usr/X11R6/lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/X11R6/include
+QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+QMAKE_LINK = g++
+QMAKE_LINK_SHLIB = g++
+QMAKE_LFLAGS = -m32
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,-soname,
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -Wl,-rpath,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_NIS = -lnsl
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lpthread
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_COPY_FILE = $(COPY)
+QMAKE_COPY_DIR = $(COPY) -r
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_STRIP = strip
+QMAKE_STRIPFLAGS_LIB += --strip-unneeded
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/linux-g++-64 b/specs/linux-g++-64
new file mode 100644
index 0000000..7bdd3b1
--- /dev/null
+++ b/specs/linux-g++-64
@@ -0,0 +1,93 @@
+#
+# qmake configuration for linux-g++
+#
+# Written for GNU/Linux platforms that have both lib and lib64 directories,
+# like the AMD Opteron.
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release incremental link_prl
+QT += core gui
+QMAKE_INCREMENTAL_STYLE = sublib
+
+QMAKE_CC = gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_YACCFLAGS_MANGLE = -p $base -b $base
+QMAKE_YACC_HEADER = $base.tab.h
+QMAKE_YACC_SOURCE = $base.tab.c
+QMAKE_CFLAGS = -m64 -pipe
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD = -D_REENTRANT
+QMAKE_CFLAGS_HIDESYMS = -fvisibility=hidden
+
+QMAKE_CXX = g++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+QMAKE_CXXFLAGS_HIDESYMS = $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /usr/X11R6/include
+QMAKE_LIBDIR_X11 = /usr/X11R6/lib64
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/X11R6/include
+QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib64
+
+QMAKE_LINK = g++
+QMAKE_LINK_SHLIB = g++
+QMAKE_LFLAGS = -m64
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,-soname,
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -Wl,-rpath,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_NIS = -lnsl
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lpthread
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_COPY_FILE = $(COPY)
+QMAKE_COPY_DIR = $(COPY) -r
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_STRIP = strip
+QMAKE_STRIPFLAGS_LIB += --strip-unneeded
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/linux-icc b/specs/linux-icc
new file mode 100644
index 0000000..26c6e81
--- /dev/null
+++ b/specs/linux-icc
@@ -0,0 +1,94 @@
+#
+# qmake configuration for linux-icc
+#
+# Written for Intel C++ Compiler versions 10.x for GNU/Linux
+#
+# Note: Some of the remarks from the Intel compiler are disabled (even
+# with 'warn_on' specified):
+#
+# warning #654: overloaded virtual function "T::f" is only partially overridden in class "U"
+# warning #1572: floating-point equality and inequality comparisons are unreliable
+#
+
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = icc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -wd654,1572
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON =
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CFLAGS_YACC =
+QMAKE_CFLAGS_THREAD = -D_REENTRANT
+
+QMAKE_CXX = icpc
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_STATIC_LIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /usr/X11R6/include
+QMAKE_LIBDIR_X11 = /usr/X11R6/lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/X11R6/include
+QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+QMAKE_LINK = icpc
+QMAKE_LINK_SHLIB = icpc
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Qoption,ld,-soname,
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -Qoption,ld,-rpath,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_NIS = -lnsl
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lpthread
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_OBJCOPY = objcopy
+QMAKE_RANLIB =
+
+QMAKE_CLEAN = -r $(OBJECTS_DIR)/ti_files
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/linux-kcc b/specs/linux-kcc
new file mode 100644
index 0000000..6a9cf08
--- /dev/null
+++ b/specs/linux-kcc
@@ -0,0 +1,93 @@
+#
+# qmake configuration for linux-kcc
+#
+# Written for KAI C++ 4.0f for GNU/Linux
+#
+# This product has been discontinued, use Intel C++ instead.
+#
+# From the KAI C++ man page for Linux:
+# --[no_]thread_safe
+# [Waive or] Request thread-safe handling of system-allocated objects.
+# To guarantee thread safety, this option must be used when both
+# compiling and linking. Thread-safe C++ is not link-compatible with
+# (the default) non-thread-safe C++.
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = KCC
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = --c --display_error_number --backend -pipe
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON =
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = +K2
+QMAKE_CFLAGS_DEBUG = +K0
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = --diag_suppress 111,177
+QMAKE_CFLAGS_THREAD = --thread_safe
+
+QMAKE_CXX = KCC
+QMAKE_CXXFLAGS = --display_error_number --diag_suppress 611,1142 --backend -pipe
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /usr/X11R6/include
+QMAKE_LIBDIR_X11 = /usr/X11R6/lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/X11R6/include
+QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+QMAKE_LINK = KCC
+QMAKE_LINK_SHLIB = KCC
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB =
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = --soname$$LITERAL_WHITESPACE
+QMAKE_LFLAGS_THREAD = --thread_safe
+QMAKE_RPATH = -rpath$$LITERAL_WHITESPACE
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_NIS = -lnsl
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD =
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_CLEAN = -r $(OBJECTS_DIR)ti_files
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/linux-kylix b/specs/linux-kylix
new file mode 100644
index 0000000..335f839
--- /dev/null
+++ b/specs/linux-kylix
@@ -0,0 +1,82 @@
+#
+# qmake configuration for linux-kylix
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release incremental link_prl
+QT += core gui
+QMAKE_INCREMENTAL_STYLE = sublib
+
+QMAKE_CC = bc++
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS =
+QMAKE_CFLAGS_DEPS = -m
+QMAKE_CFLAGS_WARN_ON = -w
+QMAKE_CFLAGS_WARN_OFF = -w-
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -v -y
+QMAKE_CFLAGS_SHLIB =
+QMAKE_CFLAGS_YACC =
+QMAKE_CFLAGS_THREAD =
+
+QMAKE_CXX = bc++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -P
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /usr/X11R6/include
+QMAKE_LIBDIR_X11 = /usr/X11R6/lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/X11R6/include
+QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+QMAKE_LINK = bc++
+QMAKE_LINK_SHLIB = bc++
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG = -lv -ly
+QMAKE_LFLAGS_SHLIB = -ltD -lTpd
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -lN
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH =
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -llibdl
+QMAKE_LIBS_X11 = -llibXext -llibX11 -llibm
+QMAKE_LIBS_X11SM = -llibSM -llibICE
+QMAKE_LIBS_NIS = -llibnsl
+QMAKE_LIBS_OPENGL = -llibGLU -llibGL -llibXmu
+QMAKE_LIBS_OPENGL_QT = -llibGL -llibXmu
+QMAKE_LIBS_THREAD = -llibpthread
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_STRIP = strip
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/linux-lsb b/specs/linux-lsb
new file mode 100644
index 0000000..9536716
--- /dev/null
+++ b/specs/linux-lsb
@@ -0,0 +1,90 @@
+#
+# qmake configuration for linux-g++
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release incremental link_prl
+QT += core gui
+QMAKE_INCREMENTAL_STYLE = sublib
+
+QMAKE_CC = lsbcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_YACCFLAGS_MANGLE = -p $base -b $base
+QMAKE_YACC_HEADER = $base.tab.h
+QMAKE_YACC_SOURCE = $base.tab.c
+QMAKE_CFLAGS = -pipe
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD = -D_REENTRANT
+QMAKE_CFLAGS_HIDESYMS = -fvisibility=hidden
+
+QMAKE_CXX = lsbc++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+QMAKE_CXXFLAGS_HIDESYMS = $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /usr/X11R6/include
+QMAKE_LIBDIR_X11 = /usr/X11R6/lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/X11R6/include
+QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+QMAKE_LINK = lsbc++
+QMAKE_LINK_SHLIB = lsbc++
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,-soname,
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -Wl,-rpath,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_NIS = -lnsl
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lpthread
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_COPY_FILE = $(COPY)
+QMAKE_COPY_DIR = $(COPY) -r
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_STRIP = strip
+QMAKE_STRIPFLAGS_LIB += --strip-unneeded
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/linux-pgcc b/specs/linux-pgcc
new file mode 100644
index 0000000..fae849d
--- /dev/null
+++ b/specs/linux-pgcc
@@ -0,0 +1,82 @@
+#
+# qmake configuration for linux-pgcc
+#
+# Written for the Portland Group compiler 6.0-5
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = pgcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS =
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON =
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -fast
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fpic
+QMAKE_CFLAGS_YACC =
+QMAKE_CFLAGS_THREAD = -D_REENTRANT
+
+QMAKE_CXX = pgCC
+QMAKE_CXXFLAGS = --display_error_number --diag_suppress815 $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /usr/X11R6/include
+QMAKE_LIBDIR_X11 = /usr/X11R6/lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/X11R6/include
+QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+QMAKE_LINK = pgCC
+QMAKE_LINK_SHLIB = pgCC
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared -fpic
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,-soname,
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -R
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_NIS = -lnsl
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lpthread
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/lynxos-g++ b/specs/lynxos-g++
new file mode 100644
index 0000000..da2ebe7
--- /dev/null
+++ b/specs/lynxos-g++
@@ -0,0 +1,85 @@
+#
+# qmake configuration for lynxos-g++
+#
+# Written for LynxOS 4.0
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release incremental link_prl
+QT += core gui
+QMAKE_INCREMENTAL_STYLE = sublib
+
+QMAKE_CC = gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -pipe
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD = -D_REENTRANT
+
+QMAKE_CXX = g++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /usr/include/X11
+QMAKE_LIBDIR_X11 =
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/include/GL
+QMAKE_LIBDIR_OPENGL =
+
+QMAKE_LINK = g++
+QMAKE_LINK_SHLIB = g++
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,-soname,
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -Wl,-rpath,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_NIS = -lnsl
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lpthread
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_STRIP = strip
+QMAKE_STRIPFLAGS_LIB += --strip-unneeded
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/macx-g++ b/specs/macx-g++
new file mode 100644
index 0000000..d28fda9
--- /dev/null
+++ b/specs/macx-g++
@@ -0,0 +1,97 @@
+#
+# qmake configuration for macx-g++
+#
+# Mac OS X + command-line compiler
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release app_bundle incremental global_init_link_order lib_version_first plugin_no_soname link_prl
+QT += core gui
+QMAKE_INCREMENTAL_STYLE = sublibs
+QMAKE_COMPILER_DEFINES += __APPLE__ __GNUC__
+
+QMAKE_CC = cc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_YACCFLAGS_MANGLE = -p $base -b $base
+QMAKE_YACC_HEADER = $base.tab.h
+QMAKE_YACC_SOURCE = $base.tab.c
+QMAKE_RESOURCE = /Developer/Tools/Rez
+QMAKE_CFLAGS = -pipe
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -Os
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_EXTENSION_SHLIB = dylib
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_HIDESYMS = -fvisibility=hidden
+QMAKE_CFLAGS_PPC = -arch ppc
+QMAKE_CFLAGS_X86 = -arch i386
+
+QMAKE_CXX = c++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_HIDESYMS = $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden
+QMAKE_CXXFLAGS_PPC = $$QMAKE_CFLAGS_PPC
+QMAKE_CXXFLAGS_X86 = $$QMAKE_CFLAGS_X86
+
+QMAKE_LIBDIR =
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /System/Library/Frameworks/OpenGL.framework/Headers \
+ /System/Library/Frameworks/AGL.framework/Headers/
+
+QMAKE_LINK = $$QMAKE_CXX
+QMAKE_FIX_RPATH = install_name_tool -id
+QMAKE_LINK_SHLIB = $$QMAKE_CXX
+QMAKE_LFLAGS = -headerpad_max_install_names
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_APP =
+QMAKE_LFLAGS_SHLIB = -single_module -dynamiclib
+QMAKE_LFLAGS_INCREMENTAL = -undefined suppress -flat_namespace
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -install_name$${LITERAL_WHITESPACE}
+QMAKE_LFLAGS_THREAD =
+QMAKE_LFLAGS_PPC = -arch ppc
+QMAKE_LFLAGS_X86 = -arch i386
+
+QMAKE_LFLAGS_VERSION = -current_version$${LITERAL_WHITESPACE}
+QMAKE_LFLAGS_COMPAT_VERSION = -compatibility_version$${LITERAL_WHITESPACE}
+
+QMAKE_RPATH =
+
+QMAKE_LIBS_DYNLOAD =
+QMAKE_LIBS_OPENGL = -framework OpenGL -framework AGL
+QMAKE_LIBS_OPENGL_QT = $$QMAKE_LIBS_OPENGL
+QMAKE_LIBS_THREAD =
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cq
+QMAKE_RANLIB = ranlib -s
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_COPY_FILE = $$QMAKE_COPY
+QMAKE_COPY_DIR = $$QMAKE_COPY -R
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/macx-mwerks b/specs/macx-mwerks
new file mode 100644
index 0000000..76c425a
--- /dev/null
+++ b/specs/macx-mwerks
@@ -0,0 +1,25 @@
+#
+# qmake configuration for macx-mwerks
+#
+# Mac OS X + Metrowerks compiler
+#
+
+MAKEFILE_GENERATOR = METROWERKS
+TEMPLATE = app
+QT += core gui
+CONFIG += qt release warn_off separate_volume link_prl
+
+DEFINES += QT_NO_STL __MACOSX__ __CF_USE_FRAMEWORK_INCLUDES__
+
+CODEWARRIOR_LINKER = Mach-O PPC Linker
+QMAKE_EXTENSION_SHLIB = dylib
+QMAKE_VOLUMENAME = OS X Volume
+FRAMEWORKPATH = {System}/Library/Frameworks/
+QMAKE_CRT_OBJECTS = crt1.o
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBS = -framework System
+QMAKE_INCDIR_OPENGL = /System/Library/Frameworks/OpenGL.framework/Headers \
+ /System/Library/Frameworks/AGL.framework/Headers/
+QMAKE_LIBS_OPENGL = -framework OpenGL -framework AGL
+QMAKE_LIBS_OPENGL_QT = $$QMAKE_LIBS_OPENGL
+load(qt_config)
diff --git a/specs/macx-pbuilder b/specs/macx-pbuilder
new file mode 100644
index 0000000..1e806d1
--- /dev/null
+++ b/specs/macx-pbuilder
@@ -0,0 +1,83 @@
+#
+# qmake configuration for macx-pbuilder
+#
+# Mac OS X + Project Builder
+#
+
+MAKEFILE_GENERATOR = PROJECTBUILDER
+TEMPLATE = app
+CONFIG += qt warn_on release lib_version_first incremental plugin_no_soname link_prl app_bundle
+QT += core gui
+QMAKE_COMPILER_DEFINES += __APPLE__ __GNUC__
+
+QMAKE_CC =
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_RESOURCE = /Developer/Tools/Rez
+QMAKE_CFLAGS = -pipe
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF =
+QMAKE_CFLAGS_RELEASE = -Os
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_EXTENSION_SHLIB = dylib
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+QMAKE_CXX =
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+
+QMAKE_INCDIR = /usr/local/include \
+ /System/Library/Frameworks/CarbonCore.framework/Headers
+QMAKE_LIBDIR =
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /System/Library/Frameworks/OpenGL.framework/Headers \
+ /System/Library/Frameworks/AGL.framework/Headers/
+
+QMAKE_LINK = c++
+QMAKE_LINK_SHLIB = c++
+QMAKE_LFLAGS = -headerpad_max_install_names
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_APP =
+QMAKE_LFLAGS_SHLIB = -single_module -dynamiclib
+QMAKE_LFLAGS_INCREMENTAL = -undefined suppress -flat_namespace
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+#QMAKE_LFLAGS_SONAME = -install_name$${LITERAL_WHITESPACE}@executable_path/../Frameworks/
+QMAKE_LFLAGS_SONAME = -install_name$${LITERAL_WHITESPACE}
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH =
+
+QMAKE_LIBS_DYNLOAD =
+QMAKE_LIBS_THREAD =
+QMAKE_LIBS_OPENGL = -framework OpenGL -framework AGL
+QMAKE_LIBS_OPENGL_QT = $$QMAKE_LIBS_OPENGL
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cq
+QMAKE_RANLIB = ranlib -s
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_COPY_FILE = $$QMAKE_COPY
+QMAKE_COPY_DIR = $$QMAKE_COPY -R
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/macx-xcode b/specs/macx-xcode
new file mode 100755
index 0000000..d2a5789
--- /dev/null
+++ b/specs/macx-xcode
@@ -0,0 +1,83 @@
+#
+# qmake configuration for macx-xcode
+#
+# Mac OS X + XCode
+#
+
+MAKEFILE_GENERATOR = XCODE
+TEMPLATE = app
+CONFIG += qt warn_on release lib_version_first incremental plugin_no_soname link_prl app_bundle
+QT += core gui
+QMAKE_COMPILER_DEFINES += __APPLE__ __GNUC__
+
+QMAKE_CC =
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_RESOURCE = /Developer/Tools/Rez
+QMAKE_CFLAGS = -pipe
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF =
+QMAKE_CFLAGS_RELEASE = -Os
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_EXTENSION_SHLIB = dylib
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+QMAKE_CXX =
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+
+QMAKE_INCDIR = /usr/local/include \
+ /System/Library/Frameworks/CarbonCore.framework/Headers
+QMAKE_LIBDIR =
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /System/Library/Frameworks/OpenGL.framework/Headers \
+ /System/Library/Frameworks/AGL.framework/Headers/
+
+QMAKE_LINK = c++
+QMAKE_LINK_SHLIB = c++
+QMAKE_LFLAGS = -headerpad_max_install_names
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_APP =
+QMAKE_LFLAGS_SHLIB = -single_module -dynamiclib
+QMAKE_LFLAGS_INCREMENTAL = -undefined suppress -flat_namespace
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+#QMAKE_LFLAGS_SONAME = -install_name$${LITERAL_WHITESPACE}@executable_path/../Frameworks/
+QMAKE_LFLAGS_SONAME = -install_name$${LITERAL_WHITESPACE}
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH =
+
+QMAKE_LIBS_DYNLOAD =
+QMAKE_LIBS_THREAD =
+QMAKE_LIBS_OPENGL = -framework OpenGL -framework AGL
+QMAKE_LIBS_OPENGL_QT = $$QMAKE_LIBS_OPENGL
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cq
+QMAKE_RANLIB = ranlib -s
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_COPY_FILE = $$QMAKE_COPY
+QMAKE_COPY_DIR = $$QMAKE_COPY -R
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/macx-xlc b/specs/macx-xlc
new file mode 100644
index 0000000..262764b
--- /dev/null
+++ b/specs/macx-xlc
@@ -0,0 +1,94 @@
+#
+# qmake configuration for macx-xlc
+#
+# Mac OS X + IBM's XL C/C++ Advanced Edition for Mac OS X
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release app_bundle global_init_link_order lib_version_first plugin_no_soname link_prl
+QT += core gui
+
+QMAKE_CC = xlc
+QMAKE_CC_THREAD = xlc_r
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -qstrict
+QMAKE_CFLAGS_WARN_ON =
+QMAKE_CFLAGS_WARN_OFF =
+QMAKE_CFLAGS_RELEASE = -O3
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_EXTENSION_SHLIB = dylib
+QMAKE_CFLAGS_SHLIB =
+QMAKE_CFLAGS_YACC =
+QMAKE_CFLAGS_THREAD = -qthreaded
+QMAKE_EXTENSION_SHLIB = dylib
+QMAKE_COMPILER_DEFINES += __APPLE__ __xlc__
+
+QMAKE_CXX = xlc++
+QMAKE_CXX_THREAD = xlc++_r
+QMAKE_CXXFLAGS = -+ $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 =
+QMAKE_LIBDIR_X11 =
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /System/Library/Frameworks/OpenGL.framework/Headers \
+ /System/Library/Frameworks/AGL.framework/Headers/
+QMAKE_LIBDIR_OPENGL =
+
+QMAKE_LINK = xlc++
+QMAKE_LINK_THREAD = xlc++_r
+QMAKE_LINK_SHLIB = ld
+#QMAKE_LINK_SHLIB_CMD = makeC++SharedLib -p 0 \
+# -o $(TARGETD) \
+# $(LFLAGS) $(OBJECTS) $(OBJMOC) $(LIBS); \
+# $(AR) lib$(QMAKE_TARGET).a $(TARGETD); \
+# $(RANLIB) lib$(QMAKE_TARGET).a; \
+# mv lib$(QMAKE_TARGET).a $(DESTDIR)
+QMAKE_LFLAGS = -headerpad_max_install_names
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -prebind -qmkshrobj
+QMAKE_LFLAGS_PLUGIN = -bundle
+QMAKE_LFLAGS_SONAME =
+#QMAKE_LFLAGS_THREAD = -L/usr/lib/threads
+#QMAKE_AIX_SHLIB = 1
+#QMAKE_LFLAGS_VERSION = -current_version$${LITERAL_WHITESPACE}
+#QMAKE_LFLAGS_COMPAT_VERSION = -compatibility_version$${LITERAL_WHITESPACE}
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD =
+QMAKE_LIBS_OPENGL = -framework OpenGL -framework AGL
+QMAKE_LIBS_OPENGL_QT = $$QMAKE_LIBS_OPENGL
+#QMAKE_LIBS_THREAD = -lpthreads
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cq
+QMAKE_RANLIB = ranlib -s
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_COPY_FILE = $$QMAKE_COPY
+QMAKE_COPY_DIR = $$QMAKE_COPY -R
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/netbsd-g++ b/specs/netbsd-g++
new file mode 100644
index 0000000..0b112b1
--- /dev/null
+++ b/specs/netbsd-g++
@@ -0,0 +1,80 @@
+#
+# qmake configuration for netbsd-g++
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -pipe
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD = -pthread
+
+QMAKE_CXX = g++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_INCDIR = /usr/local/include
+QMAKE_LIBDIR = /usr/local/lib
+QMAKE_INCDIR_X11 = /usr/X11R6/include
+QMAKE_LIBDIR_X11 = /usr/X11R6/lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/X11R6/include
+QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+QMAKE_LINK = g++
+QMAKE_LINK_SHLIB = g++
+QMAKE_LINK_SHLIB_CMD = $$QMAKE_LINK_SHLIB $$QMAKE_LFLAGS_SHLIB $(LFLAGS) $$QMAKE_LFLAGS -o $(TARGETD) $(OBJECTS) $(OBJMOC) $(LIBS)
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,-soname,
+QMAKE_LFLAGS_THREAD = -pthread
+QMAKE_RPATH = -Wl,-rpath,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD =
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD =
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB = ranlib
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/openbsd-g++ b/specs/openbsd-g++
new file mode 100644
index 0000000..86caacd
--- /dev/null
+++ b/specs/openbsd-g++
@@ -0,0 +1,81 @@
+#
+# qmake configuration for openbsd-g++
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -pipe
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD = -pthread
+
+QMAKE_CXX = g++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_INCDIR = /usr/local/include
+QMAKE_LIBDIR = /usr/local/lib
+QMAKE_INCDIR_X11 = /usr/X11R6/include
+QMAKE_LIBDIR_X11 = /usr/X11R6/lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/X11R6/include
+QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+QMAKE_LINK = g++
+QMAKE_LINK_SHLIB = g++
+QMAKE_LINK_SHLIB_CMD = $$QMAKE_LINK_SHLIB $(LFLAGS) \
+ $$QMAKE_CFLAGS_SHLIB $$QMAKE_LFLAGS \
+ -o $(TARGETD) $(OBJECTS) $(OBJMOC) $(LIBS)
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,-soname,
+QMAKE_LFLAGS_THREAD = -pthread
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD =
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD =
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar q
+QMAKE_RANLIB = ranlib
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/qnx-g++ b/specs/qnx-g++
new file mode 100644
index 0000000..c2411d4
--- /dev/null
+++ b/specs/qnx-g++
@@ -0,0 +1,81 @@
+#
+# qmake configuration for qnx-g++
+#
+# Written for QNX RTOS v6 with X11
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -pipe -fno-inline -fno-pack-struct
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses -fno-inline -fno-pack-struct
+QMAKE_CFLAGS_THREAD = -D_REENTRANT
+
+QMAKE_CXX = g++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /usr/X11R6/include
+QMAKE_LIBDIR_X11 = /usr/X11R6/lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/X11R6/include
+QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+QMAKE_LINK = g++
+QMAKE_LINK_SHLIB = g++
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -Wl,-soname,
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -Wl,-rpath,
+
+QMAKE_LIBS = -lunix
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD =
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/reliant-cds b/specs/reliant-cds
new file mode 100644
index 0000000..fee3a68
--- /dev/null
+++ b/specs/reliant-cds
@@ -0,0 +1,85 @@
+#
+# $Id: reliant-cds,v 1.2 2004/01/21 18:33:32 phil Exp $
+#
+# qmake configuration for reliant-cds
+#
+# Written for Reliant UNIX 5.45 using the CDS++ C/C++ compiler V2.0C.
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+
+QMAKE_CC = cc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS =
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -v
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -KPIC
+QMAKE_CFLAGS_YACC =
+QMAKE_CFLAGS_THREAD = -K pthread
+
+QMAKE_CXX = CC
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /opt/X/include/X11
+QMAKE_LIBDIR_X11 = /opt/X/lib
+QMAKE_INCDIR_QT = $(QTDIR)/include
+QMAKE_LIBDIR_QT = $(QTDIR)/lib
+QMAKE_INCDIR_OPENGL =
+QMAKE_LIBDIR_OPENGL =
+
+QMAKE_LINK = CC
+QMAKE_LINK_SHLIB = CC
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -G
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -h$$LITERAL_WHITESPACE
+QMAKE_LFLAGS_THREAD = -K pthread
+QMAKE_RPATH = -Wl,-Brpath=
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lresolv -lsocket -lnsl -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_QT = -lqt
+QMAKE_LIBS_QT_THREAD = -lqt-mt
+QMAKE_LIBS_OPENGL = -lGLU -lGL -lXmu
+QMAKE_LIBS_OPENGL_QT = -lGL -lXmu
+QMAKE_LIBS_THREAD =
+
+QMAKE_MOC = $(QTDIR)/bin/moc
+QMAKE_UIC = $(QTDIR)/bin/uic
+
+QMAKE_AR = CC -xar -o
+QMAKE_RANLIB =
+
+QMAKE_CLEAN = -r $(OBJECTS_DIR)/Templates.DB
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
diff --git a/specs/reliant-cds-64 b/specs/reliant-cds-64
new file mode 100644
index 0000000..da79224
--- /dev/null
+++ b/specs/reliant-cds-64
@@ -0,0 +1,85 @@
+#
+# $Id: reliant-cds-64,v 1.2 2004/01/21 18:33:32 phil Exp $
+#
+# qmake configuration for reliant-cds-64
+#
+# Written for Reliant UNIX 5.45 using the CDS++ C/C++ compiler V2.0C.
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+
+QMAKE_CC = cc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -Klp64
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -v
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -KPIC
+QMAKE_CFLAGS_YACC =
+QMAKE_CFLAGS_THREAD = -K pthread
+
+QMAKE_CXX = CC
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 = /opt/X/include/X11
+QMAKE_LIBDIR_X11 = /opt/X/lib
+QMAKE_INCDIR_QT = $(QTDIR)/include
+QMAKE_LIBDIR_QT = $(QTDIR)/lib
+QMAKE_INCDIR_OPENGL =
+QMAKE_LIBDIR_OPENGL =
+
+QMAKE_LINK = CC
+QMAKE_LINK_SHLIB = CC
+QMAKE_LFLAGS = -Klp64
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -G
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -h$$LITERAL_WHITESPACE
+QMAKE_LFLAGS_THREAD = -K pthread
+QMAKE_RPATH = -Wl,-Brpath=
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lresolv -lsocket -lnsl -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_QT = -lqt
+QMAKE_LIBS_QT_THREAD = -lqt-mt
+QMAKE_LIBS_OPENGL = -lGLU -lGL -lXmu
+QMAKE_LIBS_OPENGL_QT = -lGL -lXmu
+QMAKE_LIBS_THREAD =
+
+QMAKE_MOC = $(QTDIR)/bin/moc
+QMAKE_UIC = $(QTDIR)/bin/uic
+
+QMAKE_AR = CC -xar -o
+QMAKE_RANLIB =
+
+QMAKE_CLEAN = -r $(OBJECTS_DIR)/Templates.DB
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
diff --git a/specs/sco-cc b/specs/sco-cc
new file mode 100644
index 0000000..8a4a392
--- /dev/null
+++ b/specs/sco-cc
@@ -0,0 +1,78 @@
+#
+# qmake configuration for sco-cc
+#
+# Written for SCO OpenServer with UDK
+#
+# -Wf,--diag_suppress,838
+# turns off warning about missing return types in X headers
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+QT += core gui
+CONFIG += qt warn_on release link_prl
+
+QMAKE_CC = cc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS =
+QMAKE_CFLAGS_WARN_ON =
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -KPIC
+QMAKE_CFLAGS_YACC = -Wf,--diag_suppress,111 -Wf,--diag_suppress,177
+
+QMAKE_CXX = CC
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -Wf,--display_error_number -Wf,--diag_suppress,838
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE -Tused
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 =
+QMAKE_LIBDIR_X11 = /usr/X/lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL =
+QMAKE_LIBDIR_OPENGL =
+
+QMAKE_LINK = CC
+QMAKE_LINK_SHLIB = CC
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -G
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -h$$LITERAL_WHITESPACE
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lresolv -lsocket -lnsl -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+
+QMAKE_LIBS_OPENGL = -lGLU -lGL -lXt
+QMAKE_LIBS_OPENGL_QT = -lGL
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cq
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/sco-g++ b/specs/sco-g++
new file mode 100644
index 0000000..9a488e8
--- /dev/null
+++ b/specs/sco-g++
@@ -0,0 +1,77 @@
+#
+# qmake configuration for sco-g++
+#
+# Written for SCO OpenServer 5.0.6 with Skunkware's compiler
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS =
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+
+QMAKE_CXX = g++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 =
+QMAKE_LIBDIR_X11 =
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL =
+QMAKE_LIBDIR_OPENGL =
+
+QMAKE_LINK = g++
+QMAKE_LINK_SHLIB = g++
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -G
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -h$$LITERAL_WHITESPACE
+QMAKE_RPATH =
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lsocket -lm
+
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/solaris-cc b/specs/solaris-cc
new file mode 100644
index 0000000..3e1f428
--- /dev/null
+++ b/specs/solaris-cc
@@ -0,0 +1,85 @@
+#
+# qmake configuration for solaris-cc
+#
+# Written for Forte Developer 6 and Sun ONE Studio 7 and 8
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = cc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS =
+QMAKE_CFLAGS_DEPS = -xM
+QMAKE_CFLAGS_WARN_ON =
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -KPIC
+QMAKE_CFLAGS_YACC =
+QMAKE_CFLAGS_THREAD = -mt
+
+QMAKE_CXX = CC
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = -O2
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_INCDIR = /usr/sfw/include
+QMAKE_LIBDIR = /usr/sfw/lib
+QMAKE_INCDIR_X11 = /usr/openwin/include
+QMAKE_LIBDIR_X11 = /usr/openwin/lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/openwin/include
+QMAKE_LIBDIR_OPENGL = /usr/openwin/lib
+
+QMAKE_LINK = CC
+QMAKE_LINK_SHLIB = CC
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -G
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -h$$LITERAL_WHITESPACE
+QMAKE_LFLAGS_THREAD = -mt
+QMAKE_RPATH = -R
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lresolv -lsocket -lnsl
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_NIS =
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lpthread -lrt
+QMAKE_LIBS_NETWORK = -lresolv -lsocket -lxnet
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = CC -xar -o
+QMAKE_RANLIB =
+
+QMAKE_CLEAN = -r $(OBJECTS_DIR)Templates.DB $(OBJECTS_DIR)SunWS_cache
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/solaris-cc-64 b/specs/solaris-cc-64
new file mode 100644
index 0000000..cd1af17
--- /dev/null
+++ b/specs/solaris-cc-64
@@ -0,0 +1,102 @@
+#
+# qmake configuration for solaris-cc-64
+#
+# Written for Forte Developer 6 and Sun ONE Studio 7 and 8
+#
+# From the standards(5) manual page:
+# The XNS4 specification is safe for use only in ILP32 (32-bit)
+# environments and should not be used for LP64 (64-bit)
+# application environments. Use XNS5, which has LP64-clean
+# interfaces that are portable across ILP32 and LP64 environments.
+# [...]
+# For platforms supporting the LP64 (64-bit) programming environment
+# where the SC5.0 Compilers have been installed, SUSv2-conforming LP64
+# applications using XNS5 library calls should be built with command
+# lines of the form:
+# c89 $(getconf XBS5_LP64_OFF64_CFLAGS) -D_XOPEN_SOURCE=500 \
+# $(getconf XBS5_LP64_OFF64_LDFLAGS) foo.c -o foo \
+# $(getconf XBS5_LP64_OFF64_LIBS) -lxnet
+# So it appears that _XOPEN_SOURCE=500 should be defined when building
+# 64-bit applications (on Solaris 7 and better). But then __EXTENSIONS__
+# should be defined as well to recover all the default system interface.
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = cc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -xarch=generic64 -D_XOPEN_SOURCE=500 -D__EXTENSIONS__
+QMAKE_CFLAGS_DEPS = -xM
+QMAKE_CFLAGS_WARN_ON =
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -KPIC
+QMAKE_CFLAGS_YACC =
+QMAKE_CFLAGS_THREAD = -mt
+
+QMAKE_CXX = CC
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = -O
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_INCDIR = /usr/sfw/include
+QMAKE_LIBDIR = /usr/sfw/lib/64
+QMAKE_INCDIR_X11 = /usr/openwin/include
+QMAKE_LIBDIR_X11 = /usr/openwin/lib/64
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/openwin/include
+QMAKE_LIBDIR_OPENGL = /usr/openwin/lib/64
+
+QMAKE_LINK = CC
+QMAKE_LINK_SHLIB = CC
+QMAKE_LFLAGS = -xarch=generic64
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -G
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -h$$LITERAL_WHITESPACE
+QMAKE_LFLAGS_THREAD = -mt
+QMAKE_RPATH = -R
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lresolv -lsocket -lnsl
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_NIS =
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lpthread -lrt
+QMAKE_LIBS_NETWORK = -lresolv -lsocket -lxnet
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = CC -xar -o
+QMAKE_RANLIB =
+
+QMAKE_CLEAN = -r $(OBJECTS_DIR)Templates.DB $(OBJECTS_DIR)SunWS_cache
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/solaris-g++ b/specs/solaris-g++
new file mode 100644
index 0000000..09d141d
--- /dev/null
+++ b/specs/solaris-g++
@@ -0,0 +1,87 @@
+#
+# qmake configuration for solaris-g++
+#
+# The X11 header files used to be broken on Solaris until patches were
+# released in early 2001 for Solaris 2.6, 7, and 8. On Solaris 2.5.1
+# or non-patched systems -fpermissive works around the incompatibility
+# between GCC 2.95 or better and Solaris - but we still get warnings
+# because we don't use -isystem.
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS =
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD = -D_REENTRANT
+
+QMAKE_CXX = g++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_INCDIR = /usr/sfw/include
+QMAKE_LIBDIR = /usr/sfw/lib
+QMAKE_INCDIR_X11 = /usr/openwin/include
+QMAKE_LIBDIR_X11 = /usr/openwin/lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/openwin/include
+QMAKE_LIBDIR_OPENGL = /usr/openwin/lib
+
+QMAKE_LINK = g++
+QMAKE_LINK_SHLIB = g++
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG = -g
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -h$$LITERAL_WHITESPACE
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -Wl,-R,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lresolv -lsocket -lnsl
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_NIS =
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lpthread -lrt
+QMAKE_LIBS_NETWORK = -lresolv -lsocket -lxnet
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cq
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/solaris-g++-64 b/specs/solaris-g++-64
new file mode 100644
index 0000000..c85882a
--- /dev/null
+++ b/specs/solaris-g++-64
@@ -0,0 +1,104 @@
+#
+# qmake configuration for solaris-g++64
+#
+# The X11 header files used to be broken on Solaris until patches were
+# released in early 2001 for Solaris 2.6, 7, and 8. On Solaris 2.5.1
+# or non-patched systems -fpermissive works around the incompatibility
+# between GCC 2.95 or better and Solaris - but we still get warnings
+# because we don't use -isystem.
+#
+# From the standards(5) manual page:
+# The XNS4 specification is safe for use only in ILP32 (32-bit)
+# environments and should not be used for LP64 (64-bit)
+# application environments. Use XNS5, which has LP64-clean
+# interfaces that are portable across ILP32 and LP64 environments.
+# [...]
+# For platforms supporting the LP64 (64-bit) programming environment
+# where the SC5.0 Compilers have been installed, SUSv2-conforming LP64
+# applications using XNS5 library calls should be built with command
+# lines of the form:
+# c89 $(getconf XBS5_LP64_OFF64_CFLAGS) -D_XOPEN_SOURCE=500 \
+# $(getconf XBS5_LP64_OFF64_LDFLAGS) foo.c -o foo \
+# $(getconf XBS5_LP64_OFF64_LIBS) -lxnet
+# So it appears that _XOPEN_SOURCE=500 should be defined when building
+# 64-bit applications (on Solaris 7 and better). But then __EXTENSIONS__
+# should be defined as well to recover all the default system interface.
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -m64 -D_XOPEN_SOURCE=500 -D__EXTENSIONS__
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD = -D_REENTRANT
+
+QMAKE_CXX = g++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_INCDIR = /usr/sfw/include
+QMAKE_LIBDIR = /usr/sfw/lib/64
+QMAKE_INCDIR_X11 = /usr/openwin/include
+QMAKE_LIBDIR_X11 = /usr/openwin/lib/64
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL = /usr/openwin/include
+QMAKE_LIBDIR_OPENGL = /usr/openwin/lib/64
+
+QMAKE_LINK = g++
+QMAKE_LINK_SHLIB = g++
+QMAKE_LFLAGS = -m64
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG = -g
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -h$$LITERAL_WHITESPACE
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -Wl,-R,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lresolv -lsocket -lnsl
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_NIS =
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lpthread -lrt
+QMAKE_LIBS_NETWORK = -lresolv -lsocket -lxnet
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cq
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/tru64-cxx b/specs/tru64-cxx
new file mode 100644
index 0000000..b7154be
--- /dev/null
+++ b/specs/tru64-cxx
@@ -0,0 +1,79 @@
+#
+# qmake configuration for tru64-cxx
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl plugin_no_soname
+QT += core gui
+
+QMAKE_CC = cc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS =
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON =
+QMAKE_CFLAGS_WARN_OFF =
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB =
+QMAKE_CFLAGS_YACC = -Olimit 1000
+QMAKE_CFLAGS_THREAD = -pthread
+
+QMAKE_CXX = cxx
+QMAKE_CXXFLAGS = -x cxx -model ansi $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 =
+QMAKE_LIBDIR_X11 =
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL =
+QMAKE_LIBDIR_OPENGL =
+
+QMAKE_LINK = cxx
+QMAKE_LINK_SHLIB = cxx
+QMAKE_LFLAGS = -model ansi
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_THREAD = -pthread
+QMAKE_LFLAGS_SONAME = -soname$$LITERAL_WHITESPACE
+QMAKE_RPATH = -rpath$$LITERAL_WHITESPACE
+
+QMAKE_LIBS = -lm
+QMAKE_LIBS_DYNLOAD =
+QMAKE_LIBS_X11 = -lXext -lX11
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lrt
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/tru64-g++ b/specs/tru64-g++
new file mode 100644
index 0000000..eb3a758
--- /dev/null
+++ b/specs/tru64-g++
@@ -0,0 +1,79 @@
+#
+# qmake configuration for tru64-g++
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl plugin_no_soname
+QT += core gui
+
+QMAKE_CC = gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS =
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD = -D_REENTRANT
+
+QMAKE_CXX = g++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 =
+QMAKE_LIBDIR_X11 =
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL =
+QMAKE_LIBDIR_OPENGL =
+
+QMAKE_LINK = g++
+QMAKE_LINK_SHLIB = g++
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_THREAD =
+QMAKE_LFLAGS_SONAME = -Wl,-soname,
+QMAKE_RPATH = -Wl,-rpath,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD =
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_OPENGL = -lGLU -lGL
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lpthread -lexc -lrt
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cqs
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/unixware-cc b/specs/unixware-cc
new file mode 100644
index 0000000..61b0d7f
--- /dev/null
+++ b/specs/unixware-cc
@@ -0,0 +1,84 @@
+#
+# qmake configuration for unixware-cc
+#
+# Written for UnixWare 7 with UDK or OUDK
+#
+# -Wf,--diag_suppress,838
+# turns off warning about missing return types in X headers
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = cc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS =
+QMAKE_CFLAGS_WARN_ON =
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -KPIC
+QMAKE_CFLAGS_YACC = -Wf,--diag_suppress,111 -Wf,--diag_suppress,177
+QMAKE_CFLAGS_THREAD = -Kthread
+
+QMAKE_CXX = CC
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -Wf,--display_error_number -Wf,--diag_suppress,838
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE -Tused
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 =
+QMAKE_LIBDIR_X11 = /usr/X/lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL =
+QMAKE_LIBDIR_OPENGL =
+
+QMAKE_LINK = CC
+QMAKE_LINK_SHLIB = CC
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -G
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME = -h$$LITERAL_WHITESPACE
+QMAKE_LFLAGS_THREAD = -Kthread
+QMAKE_RPATH = -R
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lresolv -lsocket -lnsl -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+
+QMAKE_LIBS_OPENGL = -lGLU -lGL -lXt
+QMAKE_LIBS_OPENGL_QT = -lGL
+
+QMAKE_LIBS_THREAD =
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cq
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/unixware-g++ b/specs/unixware-g++
new file mode 100644
index 0000000..cd7735e
--- /dev/null
+++ b/specs/unixware-g++
@@ -0,0 +1,81 @@
+#
+# qmake configuration for unixware-g++
+#
+# Written for UnixWare 7 with OSTK
+#
+
+MAKEFILE_GENERATOR = UNIX
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+QT += core gui
+
+QMAKE_CC = gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = yacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS =
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall -W
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_SHLIB = -fPIC
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD =
+
+QMAKE_CXX = g++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR =
+QMAKE_INCDIR_X11 =
+QMAKE_LIBDIR_X11 = /usr/X/lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+QMAKE_INCDIR_OPENGL =
+QMAKE_LIBDIR_OPENGL =
+
+QMAKE_LINK = g++
+QMAKE_LINK_SHLIB = g++
+QMAKE_LFLAGS =
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_SHLIB = -shared
+QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
+QMAKE_LFLAGS_SONAME =
+QMAKE_LFLAGS_THREAD =
+QMAKE_RPATH = -Wl,-R,
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD = -ldl
+QMAKE_LIBS_X11 = -lXext -lX11 -lresolv -lsocket -lnsl -lm
+QMAKE_LIBS_X11SM = -lSM -lICE
+QMAKE_LIBS_OPENGL = -lGLU -lGL -lXt
+QMAKE_LIBS_OPENGL_QT = -lGL
+QMAKE_LIBS_THREAD = -lthread
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
+QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+
+QMAKE_AR = ar cq
+QMAKE_RANLIB =
+
+QMAKE_TAR = tar -cf
+QMAKE_GZIP = gzip -9f
+
+QMAKE_COPY = cp -f
+QMAKE_MOVE = mv -f
+QMAKE_DEL_FILE = rm -f
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
+load(qt_config)
diff --git a/specs/win32-borland b/specs/win32-borland
new file mode 100644
index 0000000..63bf07a
--- /dev/null
+++ b/specs/win32-borland
@@ -0,0 +1,90 @@
+#
+# qmake configuration for win32-borland
+#
+# Written for Borland C++
+#
+
+MAKEFILE_GENERATOR = BMAKE
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl copy_dir_files no_empty_targets cd_change_global debug_and_release debug_and_release_target
+QT += core gui
+DEFINES += UNICODE
+QMAKE_NOFORCE = 1
+QMAKE_COMPILER_DEFINES += __BORLANDC__ WIN32
+
+QMAKE_CC = bcc32
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = byacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -tWR -tWM
+QMAKE_CFLAGS_WARN_ON = -w -w-hid
+QMAKE_CFLAGS_WARN_OFF = -w-
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -v
+QMAKE_CFLAGS_YACC =
+QMAKE_CFLAGS_CONSOLE = -tWC
+
+QMAKE_CXX = $$QMAKE_CC
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_CONSOLE = $$QMAKE_CFLAGS_CONSOLE
+QMAKE_CXXFLAGS_STL_ON =
+QMAKE_CXXFLAGS_STL_OFF =
+QMAKE_CXXFLAGS_RTTI_ON =
+QMAKE_CXXFLAGS_RTTI_OFF = -RT-
+QMAKE_CXXFLAGS_EXCEPTIONS_ON =
+QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -x-
+
+QMAKE_INCDIR =
+QMAKE_LIBDIR = $(BCB)\lib
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+
+QMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -o$obj $src
+QMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -o$@ $<
+QMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o$obj $src
+QMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o$@ $<
+
+QMAKE_LINK = ilink32
+QMAKE_LFLAGS = -c -x -Gn
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG = -v
+QMAKE_LFLAGS_CONSOLE = -ap -Tpe c0x32.obj
+QMAKE_LFLAGS_WINDOWS = -aa -Tpe c0w32.obj
+QMAKE_LFLAGS_DLL= -Gi -aa -Tpd c0d32.obj
+
+QMAKE_LIBS = import32.lib cw32mti.lib
+QMAKE_LIBS_CORE =
+QMAKE_LIBS_GUI =
+QMAKE_LIBS_NETWORK = ws2_32.lib
+QMAKE_LIBS_OPENGL =
+QMAKE_LIBS_COMPAT =
+QMAKE_LIBS_QT_ENTRY = -lqtmain
+
+#QMAKE_LIBS_OPENGL =
+#QMAKE_LFLAGS_OPENGL = /dopengl32.dll
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]\moc.exe
+QMAKE_UIC = $$[QT_INSTALL_BINS]\uic.exe
+QMAKE_IDC = $$[QT_INSTALL_BINS]\idc.exe
+
+QMAKE_IDL = midl
+QMAKE_LIB = tlib /C /P256
+QMAKE_RC = brcc32 -dQ_CC_BOR
+
+QMAKE_ZIP = zip -r -9
+
+QMAKE_COPY = copy /y
+QMAKE_COPY_DIR = xcopy /s /q /y /i
+QMAKE_MOVE = move
+QMAKE_DEL_FILE = del
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = if not exist
+QMAKE_MKDIR = mkdir
+
+load(qt_config)
diff --git a/specs/win32-g++ b/specs/win32-g++
new file mode 100644
index 0000000..0c45103
--- /dev/null
+++ b/specs/win32-g++
@@ -0,0 +1,102 @@
+#
+# qmake configuration for win32-g++
+#
+# Written for MinGW
+#
+
+MAKEFILE_GENERATOR = MINGW
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl copy_dir_files debug_and_release debug_and_release_target precompile_header
+QT += core gui
+DEFINES += UNICODE QT_LARGEFILE_SUPPORT
+QMAKE_COMPILER_DEFINES += __GNUC__ WIN32
+
+QMAKE_EXT_OBJ = .o
+
+QMAKE_CC = gcc
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = byacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS =
+QMAKE_CFLAGS_DEPS = -M
+QMAKE_CFLAGS_WARN_ON = -Wall
+QMAKE_CFLAGS_WARN_OFF = -w
+QMAKE_CFLAGS_RELEASE = -O2
+QMAKE_CFLAGS_DEBUG = -g
+QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
+QMAKE_CFLAGS_THREAD = -mthreads
+
+QMAKE_CXX = g++
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+QMAKE_CXXFLAGS_RTTI_ON = -frtti
+QMAKE_CXXFLAGS_RTTI_OFF = -fno-rtti
+QMAKE_CXXFLAGS_EXCEPTIONS_ON = -fexceptions
+QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -fno-exceptions
+
+QMAKE_INCDIR =
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+
+QMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -o $obj $src
+QMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+QMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $obj $src
+QMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+QMAKE_LINK = g++
+QMAKE_LFLAGS = -mthreads -Wl,-enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc
+QMAKE_LFLAGS_RELEASE = -Wl,-s
+QMAKE_LFLAGS_DEBUG =
+QMAKE_LFLAGS_CONSOLE = -Wl,-subsystem,console
+QMAKE_LFLAGS_WINDOWS = -Wl,-subsystem,windows
+QMAKE_LFLAGS_DLL = -shared
+QMAKE_LINK_OBJECT_MAX = 10
+QMAKE_LINK_OBJECT_SCRIPT= object_script
+
+
+QMAKE_LIBS =
+QMAKE_LIBS_CORE = -lkernel32 -luser32 -lshell32 -luuid -lole32 -ladvapi32 -lws2_32
+QMAKE_LIBS_GUI = -lgdi32 -lcomdlg32 -loleaut32 -limm32 -lwinmm -lwinspool -lws2_32 -lole32 -luuid -luser32
+QMAKE_LIBS_NETWORK = -lws2_32
+QMAKE_LIBS_OPENGL = -lopengl32 -lglu32 -lgdi32 -luser32
+QMAKE_LIBS_COMPAT = -ladvapi32 -lshell32 -lcomdlg32 -luser32 -lgdi32 -lws2_32
+QMAKE_LIBS_QT_ENTRY = -lmingw32 -lqtmain
+
+MINGW_IN_SHELL = $$(MINGW_IN_SHELL)
+isEqual(MINGW_IN_SHELL, 1) {
+ QMAKE_DIR_SEP = /
+ QMAKE_COPY = cp
+ QMAKE_COPY_DIR = xcopy /s /q /y /i
+ QMAKE_MOVE = mv
+ QMAKE_DEL_FILE = rm
+ QMAKE_MKDIR = mkdir
+ QMAKE_DEL_DIR = rmdir
+} else {
+ QMAKE_COPY = copy /y
+ QMAKE_COPY_DIR = xcopy /s /q /y /i
+ QMAKE_MOVE = move
+ QMAKE_DEL_FILE = del
+ QMAKE_MKDIR = mkdir
+ QMAKE_DEL_DIR = rmdir
+}
+QMAKE_MOC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}moc.exe
+QMAKE_UIC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}uic.exe
+QMAKE_IDC = $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}idc.exe
+
+QMAKE_IDL = midl
+QMAKE_LIB = ar -ru
+QMAKE_RC = windres
+
+QMAKE_ZIP = zip -r -9
+
+QMAKE_STRIP = strip
+QMAKE_STRIPFLAGS_LIB += --strip-unneeded
+QMAKE_CHK_DIR_EXISTS = if not exist
+load(qt_config)
diff --git a/specs/win32-icc b/specs/win32-icc
new file mode 100644
index 0000000..ca00e9e
--- /dev/null
+++ b/specs/win32-icc
@@ -0,0 +1,87 @@
+#
+# qmake configuration for win32-icc
+#
+# Written for Intel C++
+#
+
+MAKEFILE_GENERATOR = MSVC
+TEMPLATE = app
+CONFIG += qt warn_on release incremental flat link_prl precompile_header copy_dir_files debug_and_release debug_and_release_target
+QT += core gui
+DEFINES += UNICODE QT_LARGEFILE_SUPPORT
+QMAKE_COMPILER_DEFINES += __INTEL_COMPILER _MSC_VER=1300 WIN32
+
+QMAKE_CC = icl
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = byacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -nologo -Zm200
+QMAKE_CFLAGS_WARN_ON = -W3 /Qwd673
+QMAKE_CFLAGS_WARN_OFF = -W0 /Qwd673
+QMAKE_CFLAGS_RELEASE = -O2 -MD
+QMAKE_CFLAGS_DEBUG = -Zi -MDd
+QMAKE_CFLAGS_YACC =
+
+QMAKE_CXX = $$QMAKE_CC
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS /Zc:forScope
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_STL_ON = -GX
+QMAKE_CXXFLAGS_STL_OFF =
+QMAKE_CXXFLAGS_RTTI_ON = -GR
+QMAKE_CXXFLAGS_RTTI_OFF =
+QMAKE_CXXFLAGS_EXCEPTIONS_ON = -GX
+QMAKE_CXXFLAGS_EXCEPTIONS_OFF =
+
+QMAKE_INCDIR =
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+
+QMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -Fo$obj $src
+QMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -Fo$@ $<
+QMAKE_RUN_CC_IMP_BATCH = $(CC) -c $(CFLAGS) $(INCPATH) -Fo$@ @<<
+QMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$obj $src
+QMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$@ $<
+QMAKE_RUN_CXX_IMP_BATCH = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$@ @<<
+
+QMAKE_LINK = link
+QMAKE_LFLAGS = /NOLOGO
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG = /DEBUG
+QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:console
+QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:windows
+QMAKE_LFLAGS_DLL = /DLL
+QMAKE_LFLAGS_QT_DLL = /BASE:0x39D00000
+
+QMAKE_LIBS =
+QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib ws2_32.lib
+QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib winspool.lib ws2_32.lib ole32.lib user32.lib
+QMAKE_LIBS_NETWORK = ws2_32.lib
+QMAKE_LIBS_OPENGL = opengl32.lib glu32.lib gdi32.lib user32.lib delayimp.lib
+QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
+QMAKE_LIBS_QT_ENTRY = -lqtmain
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]\moc.exe
+QMAKE_UIC = $$[QT_INSTALL_BINS]\uic.exe
+QMAKE_IDC = $$[QT_INSTALL_BINS]\idc.exe
+
+QMAKE_IDL = midl
+QMAKE_LIB = lib /NOLOGO
+QMAKE_RC = rc
+
+QMAKE_ZIP = zip -r -9
+
+QMAKE_COPY = copy /y
+QMAKE_COPY_DIR = xcopy /s /q /y /i
+QMAKE_MOVE = move
+QMAKE_DEL_FILE = del
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = if not exist
+QMAKE_MKDIR = mkdir
+
+DSP_EXTENSION = .dsp
+load(qt_config)
diff --git a/specs/win32-msvc b/specs/win32-msvc
new file mode 100644
index 0000000..2332b6b
--- /dev/null
+++ b/specs/win32-msvc
@@ -0,0 +1,86 @@
+#
+# qmake configuration for win32-msvc
+#
+# Written for Microsoft C++
+#
+
+MAKEFILE_GENERATOR = MSVC
+TEMPLATE = app
+CONFIG += qt warn_on release incremental flat link_prl precompile_header copy_dir_files cd_change_global no_delete_multiple_files debug_and_release debug_and_release_target
+QT += core gui
+DEFINES += UNICODE QT_LARGEFILE_SUPPORT
+QMAKE_COMPILER_DEFINES += _MSC_VER=1200 WIN32
+
+QMAKE_CC = cl
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = byacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -nologo -Zm200
+QMAKE_CFLAGS_WARN_ON = -W3
+QMAKE_CFLAGS_WARN_OFF = -W0
+QMAKE_CFLAGS_RELEASE = -O1 -MD
+QMAKE_CFLAGS_DEBUG = -Zi -MDd
+QMAKE_CFLAGS_YACC =
+
+QMAKE_CXX = $$QMAKE_CC
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_STL_ON = -GX
+QMAKE_CXXFLAGS_STL_OFF =
+QMAKE_CXXFLAGS_RTTI_ON = -GR
+QMAKE_CXXFLAGS_RTTI_OFF =
+QMAKE_CXXFLAGS_EXCEPTIONS_ON = -GX
+QMAKE_CXXFLAGS_EXCEPTIONS_OFF =
+
+QMAKE_INCDIR =
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+
+QMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -Fo$obj $src
+QMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -Fo$@ $<
+QMAKE_RUN_CC_IMP_BATCH = $(CC) -c $(CFLAGS) $(INCPATH) -Fo$@ @<<
+QMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$obj $src
+QMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$@ $<
+QMAKE_RUN_CXX_IMP_BATCH = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$@ @<<
+
+QMAKE_LINK = link
+QMAKE_LFLAGS = /NOLOGO
+QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO
+QMAKE_LFLAGS_DEBUG = /DEBUG
+QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:console
+QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:windows
+QMAKE_LFLAGS_DLL = /DLL
+
+QMAKE_LIBS =
+QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib ws2_32.lib
+QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib winspool.lib ws2_32.lib ole32.lib user32.lib
+QMAKE_LIBS_NETWORK = ws2_32.lib
+QMAKE_LIBS_OPENGL = opengl32.lib glu32.lib gdi32.lib user32.lib delayimp.lib
+QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
+QMAKE_LIBS_QT_ENTRY = -lqtmain
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]\moc.exe
+QMAKE_UIC = $$[QT_INSTALL_BINS]\uic.exe
+QMAKE_IDC = $$[QT_INSTALL_BINS]\idc.exe
+
+QMAKE_IDL = midl
+QMAKE_LIB = lib /NOLOGO
+QMAKE_RC = rc
+
+QMAKE_ZIP = zip -r -9
+
+QMAKE_COPY = copy /y
+QMAKE_COPY_DIR = xcopy /s /q /y /i
+QMAKE_MOVE = move
+QMAKE_DEL_FILE = del
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = if not exist
+QMAKE_MKDIR = mkdir
+
+DSP_EXTENSION = .dsp
+load(qt_config)
diff --git a/specs/win32-msvc.net b/specs/win32-msvc.net
new file mode 100644
index 0000000..5fbb756
--- /dev/null
+++ b/specs/win32-msvc.net
@@ -0,0 +1,88 @@
+#
+# qmake configuration for win32-msvc.net
+#
+# Written for Microsoft C++.NET
+#
+
+MAKEFILE_GENERATOR = MSVC.NET
+TEMPLATE = app
+CONFIG += qt warn_on release incremental flat link_prl precompile_header autogen_precompile_source copy_dir_files debug_and_release debug_and_release_target
+QT += core gui
+DEFINES += UNICODE WIN32 QT_LARGEFILE_SUPPORT
+QMAKE_COMPILER_DEFINES += _MSC_VER=1300 WIN32
+
+QMAKE_CC = cl
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = byacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -nologo -Zm200
+QMAKE_CFLAGS_WARN_ON = -W3
+QMAKE_CFLAGS_WARN_OFF = -W0
+QMAKE_CFLAGS_RELEASE = -O2 -MD
+QMAKE_CFLAGS_DEBUG = -Zi -MDd
+QMAKE_CFLAGS_YACC =
+
+QMAKE_CXX = $$QMAKE_CC
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON -w34100 -w34189
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_STL_ON = -EHsc
+QMAKE_CXXFLAGS_STL_OFF =
+QMAKE_CXXFLAGS_RTTI_ON = -GR
+QMAKE_CXXFLAGS_RTTI_OFF =
+QMAKE_CXXFLAGS_EXCEPTIONS_ON = -EHsc
+QMAKE_CXXFLAGS_EXCEPTIONS_OFF =
+
+QMAKE_INCDIR =
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+
+QMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -Fo$obj $src
+QMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -Fo$@ $<
+QMAKE_RUN_CC_IMP_BATCH = $(CC) -c $(CFLAGS) $(INCPATH) -Fo$@ @<<
+QMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$obj $src
+QMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$@ $<
+QMAKE_RUN_CXX_IMP_BATCH = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$@ @<<
+
+QMAKE_LINK = link
+QMAKE_LFLAGS = /NOLOGO
+QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO
+QMAKE_LFLAGS_DEBUG = /DEBUG
+QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE
+QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS
+QMAKE_LFLAGS_DLL = /DLL
+
+QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib ws2_32.lib
+QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib winspool.lib ws2_32.lib ole32.lib user32.lib
+QMAKE_LIBS_NETWORK = ws2_32.lib
+QMAKE_LIBS_OPENGL = opengl32.lib glu32.lib gdi32.lib user32.lib
+QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
+
+QMAKE_LIBS_QT_ENTRY = -lqtmain
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]\moc.exe
+QMAKE_UIC = $$[QT_INSTALL_BINS]\uic.exe
+QMAKE_IDC = $$[QT_INSTALL_BINS]\idc.exe
+
+QMAKE_IDL = midl
+QMAKE_LIB = lib /NOLOGO
+QMAKE_RC = rc
+
+QMAKE_ZIP = zip -r -9
+
+QMAKE_COPY = copy /y
+QMAKE_COPY_DIR = xcopy /s /q /y /i
+QMAKE_MOVE = move
+QMAKE_DEL_FILE = del
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = if not exist
+QMAKE_MKDIR = mkdir
+
+VCPROJ_EXTENSION = .vcproj
+VCSOLUTION_EXTENSION = .sln
+VCPROJ_KEYWORD = Qt4VSv1.0
+load(qt_config)
diff --git a/specs/win32-msvc2005 b/specs/win32-msvc2005
new file mode 100644
index 0000000..4c9bc38
--- /dev/null
+++ b/specs/win32-msvc2005
@@ -0,0 +1,88 @@
+#
+# qmake configuration for win32-msvc2005
+#
+# Written for Microsoft VC2005.NET
+#
+
+MAKEFILE_GENERATOR = MSVC.NET
+TEMPLATE = app
+CONFIG += qt warn_on release incremental flat link_prl precompile_header autogen_precompile_source copy_dir_files debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe
+QT += core gui
+DEFINES += UNICODE WIN32 QT_LARGEFILE_SUPPORT
+QMAKE_COMPILER_DEFINES += _MSC_VER=1400 WIN32
+
+QMAKE_CC = cl
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = byacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -nologo -Zm200 -Zc:wchar_t-
+QMAKE_CFLAGS_WARN_ON = -W3
+QMAKE_CFLAGS_WARN_OFF = -W0
+QMAKE_CFLAGS_RELEASE = -O2 -MD
+QMAKE_CFLAGS_DEBUG = -Zi -MDd
+QMAKE_CFLAGS_YACC =
+
+QMAKE_CXX = $$QMAKE_CC
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON -w34100 -w34189
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_STL_ON = -EHsc
+QMAKE_CXXFLAGS_STL_OFF =
+QMAKE_CXXFLAGS_RTTI_ON = -GR
+QMAKE_CXXFLAGS_RTTI_OFF =
+QMAKE_CXXFLAGS_EXCEPTIONS_ON = -EHsc
+QMAKE_CXXFLAGS_EXCEPTIONS_OFF =
+
+QMAKE_INCDIR =
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+
+QMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -Fo$obj $src
+QMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -Fo$@ $<
+QMAKE_RUN_CC_IMP_BATCH = $(CC) -c $(CFLAGS) $(INCPATH) -Fo$@ @<<
+QMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$obj $src
+QMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$@ $<
+QMAKE_RUN_CXX_IMP_BATCH = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$@ @<<
+
+QMAKE_LINK = link
+QMAKE_LFLAGS = /NOLOGO
+QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO
+QMAKE_LFLAGS_DEBUG = /DEBUG
+QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE
+QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS \"/MANIFESTDEPENDENCY:type=\'win32\' name=\'Microsoft.Windows.Common-Controls\' version=\'6.0.0.0\' publicKeyToken=\'6595b64144ccf1df\' language=\'*\' processorArchitecture=\'*\'\"
+QMAKE_LFLAGS_DLL = /DLL
+
+QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib ws2_32.lib
+QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib winspool.lib ws2_32.lib ole32.lib user32.lib advapi32.lib
+QMAKE_LIBS_NETWORK = ws2_32.lib
+QMAKE_LIBS_OPENGL = opengl32.lib glu32.lib gdi32.lib user32.lib
+QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
+
+QMAKE_LIBS_QT_ENTRY = -lqtmain
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]\moc.exe
+QMAKE_UIC = $$[QT_INSTALL_BINS]\uic.exe
+QMAKE_IDC = $$[QT_INSTALL_BINS]\idc.exe
+
+QMAKE_IDL = midl
+QMAKE_LIB = lib /NOLOGO
+QMAKE_RC = rc
+
+QMAKE_ZIP = zip -r -9
+
+QMAKE_COPY = copy /y
+QMAKE_COPY_DIR = xcopy /s /q /y /i
+QMAKE_MOVE = move
+QMAKE_DEL_FILE = del
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = if not exist
+QMAKE_MKDIR = mkdir
+
+VCPROJ_EXTENSION = .vcproj
+VCSOLUTION_EXTENSION = .sln
+VCPROJ_KEYWORD = Qt4VSv1.0
+load(qt_config)
diff --git a/specs/win32-msvc2008 b/specs/win32-msvc2008
new file mode 100644
index 0000000..c7f2499
--- /dev/null
+++ b/specs/win32-msvc2008
@@ -0,0 +1,88 @@
+#
+# qmake configuration for win32-msvc2008
+#
+# Written for Microsoft VC2005.NET
+#
+
+MAKEFILE_GENERATOR = MSVC.NET
+TEMPLATE = app
+CONFIG += qt warn_on release incremental flat link_prl precompile_header autogen_precompile_source copy_dir_files debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe
+QT += core gui
+DEFINES += UNICODE WIN32 QT_LARGEFILE_SUPPORT
+QMAKE_COMPILER_DEFINES += _MSC_VER=1500 WIN32
+
+QMAKE_CC = cl
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = byacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -nologo -Zm200 -Zc:wchar_t-
+QMAKE_CFLAGS_WARN_ON = -W3
+QMAKE_CFLAGS_WARN_OFF = -W0
+QMAKE_CFLAGS_RELEASE = -O2 -MD
+QMAKE_CFLAGS_DEBUG = -Zi -MDd
+QMAKE_CFLAGS_YACC =
+
+QMAKE_CXX = $$QMAKE_CC
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON -w34100 -w34189
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+QMAKE_CXXFLAGS_STL_ON = -EHsc
+QMAKE_CXXFLAGS_STL_OFF =
+QMAKE_CXXFLAGS_RTTI_ON = -GR
+QMAKE_CXXFLAGS_RTTI_OFF =
+QMAKE_CXXFLAGS_EXCEPTIONS_ON = -EHsc
+QMAKE_CXXFLAGS_EXCEPTIONS_OFF =
+
+QMAKE_INCDIR =
+QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
+QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
+
+QMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -Fo$obj $src
+QMAKE_RUN_CC_IMP = $(CC) -c $(CFLAGS) $(INCPATH) -Fo$@ $<
+QMAKE_RUN_CC_IMP_BATCH = $(CC) -c $(CFLAGS) $(INCPATH) -Fo$@ @<<
+QMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$obj $src
+QMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$@ $<
+QMAKE_RUN_CXX_IMP_BATCH = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$@ @<<
+
+QMAKE_LINK = link
+QMAKE_LFLAGS = /NOLOGO
+QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO
+QMAKE_LFLAGS_DEBUG = /DEBUG
+QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE
+QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS \"/MANIFESTDEPENDENCY:type=\'win32\' name=\'Microsoft.Windows.Common-Controls\' version=\'6.0.0.0\' publicKeyToken=\'6595b64144ccf1df\' language=\'*\' processorArchitecture=\'*\'\"
+QMAKE_LFLAGS_DLL = /DLL
+
+QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib ws2_32.lib
+QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib winspool.lib ws2_32.lib ole32.lib user32.lib advapi32.lib
+QMAKE_LIBS_NETWORK = ws2_32.lib
+QMAKE_LIBS_OPENGL = opengl32.lib glu32.lib gdi32.lib user32.lib
+QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
+
+QMAKE_LIBS_QT_ENTRY = -lqtmain
+
+QMAKE_MOC = $$[QT_INSTALL_BINS]\moc.exe
+QMAKE_UIC = $$[QT_INSTALL_BINS]\uic.exe
+QMAKE_IDC = $$[QT_INSTALL_BINS]\idc.exe
+
+QMAKE_IDL = midl
+QMAKE_LIB = lib /NOLOGO
+QMAKE_RC = rc
+
+QMAKE_ZIP = zip -r -9
+
+QMAKE_COPY = copy /y
+QMAKE_COPY_DIR = xcopy /s /q /y /i
+QMAKE_MOVE = move
+QMAKE_DEL_FILE = del
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = if not exist
+QMAKE_MKDIR = mkdir
+
+VCPROJ_EXTENSION = .vcproj
+VCSOLUTION_EXTENSION = .sln
+VCPROJ_KEYWORD = Qt4VSv1.0
+load(qt_config)
diff --git a/specs/win32-watcom b/specs/win32-watcom
new file mode 100644
index 0000000..35bde44
--- /dev/null
+++ b/specs/win32-watcom
@@ -0,0 +1,69 @@
+#
+# $Id: win32-watcom,v 1.2 2004/01/21 18:33:33 phil Exp $
+#
+# qmake configuration for win32-watcom
+#
+# Written for Watcom C++, now OpenWatcom.
+#
+
+TEMPLATE = app
+CONFIG += qt warn_on release link_prl
+
+QMAKE_CC = wcl386
+QMAKE_LEX = flex
+QMAKE_LEXFLAGS =
+QMAKE_YACC = byacc
+QMAKE_YACCFLAGS = -d
+QMAKE_CFLAGS = -zq
+QMAKE_CFLAGS_WARN_ON = -w2
+QMAKE_CFLAGS_WARN_OFF = -w0
+QMAKE_CFLAGS_RELEASE = -ox
+QMAKE_CFLAGS_DEBUG = -d2
+QMAKE_CFLAGS_YACC =
+
+QMAKE_CXX = $$QMAKE_CC
+QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
+QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
+QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
+QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
+
+QMAKE_INCDIR =
+QMAKE_INCDIR_QT = $(QTDIR)\include
+
+QMAKE_RUN_CC = $(CC) -c $(CFLAGS) $(INCPATH) -fo=$obj $src
+QMAKE_RUN_CXX = $(CXX) -c $(CXXFLAGS) $(INCPATH) -fo=$obj $src
+
+QMAKE_LINK = wlink
+QMAKE_LFLAGS = op quiet op c
+QMAKE_LFLAGS_RELEASE =
+QMAKE_LFLAGS_DEBUG = d all
+QMAKE_LFLAGS_CONSOLE = sys nt
+QMAKE_LFLAGS_WINDOWS = sys nt_win
+QMAKE_LFLAGS_CONSOLE_DLL= sys nt
+QMAKE_LFLAGS_WINDOWS_DLL= sys nt_win
+
+QMAKE_LIBS =
+QMAKE_LIBS_CONSOLE =
+QMAKE_LIBS_WINDOWS =
+QMAKE_LIBS_QT = %QTDIR%\lib\qt.lib
+QMAKE_LIBS_QT_ENTRY = %QTDIR%\lib\qtmain.lib
+
+QMAKE_LIBS_OPENGL = opengl32.lib
+
+QMAKE_MOC = $(QTDIR)/bin/moc.exe
+QMAKE_UIC = $(QTDIR)/bin/uic.exe
+QMAKE_IDC = $(QTDIR)/bin/idc.exe
+
+QMAKE_LIB = wlib -b -c -n -q -p=512
+QMAKE_RC = rc
+
+QMAKE_ZIP = zip -r -9
+
+QMAKE_COPY = copy
+QMAKE_MOVE = move
+QMAKE_DEL_FILE = del
+QMAKE_DEL_DIR = rmdir
+QMAKE_CHK_DIR_EXISTS = test -d
+QMAKE_MKDIR = mkdir -p
diff --git a/sphinx/annotations.rst b/sphinx/annotations.rst
new file mode 100644
index 0000000..05ab847
--- /dev/null
+++ b/sphinx/annotations.rst
@@ -0,0 +1,805 @@
+Annotations
+===========
+
+In this section we describe each of the annotations that can be used in
+specification files.
+
+Annotations can either be :ref:`argument annotations <ref-arg-annos>`,
+:ref:`class annotations <ref-class-annos>`, :ref:`mapped type annotations
+<ref-mapped-type-annos>`, :ref:`enum annotations <ref-enum-annos>`,
+:ref:`exception annotations <ref-exception-annos>`, :ref:`function annotations
+<ref-function-annos>`, :ref:`license annotations <ref-license-annos>`,
+:ref:`typedef annotations <ref-typedef-annos>` or :ref:`variable annotations
+<ref-variable-annos>` depending on the context in which they can be used.
+
+Annotations are placed between forward slashes (``/``). Multiple annotations
+are comma separated within the slashes.
+
+Annotations have a type and, possibly, a value. The type determines the
+format of the value. The name of an annotation and its value are separated by
+``=``.
+
+Annotations can have one of the following types:
+
+*boolean*
+ This type of annotation has no value and is implicitly true.
+
+*name*
+ The value is a name that is compatible with a C/C++ identifier. In some
+ cases the value is optional.
+
+*dotted name*
+ The value is a name that is compatible with an identifier preceded by a
+ Python scope.
+
+*string*
+ The value is a double quoted string.
+
+*API range*
+ The value is the name of an API (defined using the :directive:`%API`
+ directive) separated by a range of version numbers with a colon.
+
+ The range of version numbers is a pair of numbers separated by a hyphen
+ specifying the lower and upper bounds of the range. A version number is
+ within the range if it is greater or equal to the lower bound and less
+ than the upper bound. Each bound can be omitted meaning that the range is
+ unbounded in that direction.
+
+ For example::
+
+ # This is part of the PyQt4 API up to but excluding v2.
+ void hex() /API=PyQt4:-2/
+
+ # This is part of the PyQt4 API starting from v2.
+ void hex() /PyName=hex_, API=PyQt4:2-/
+
+The following example shows argument and function annotations::
+
+ void exec(QWidget * /Transfer/) /ReleaseGIL, PyName=call_exec/;
+
+Note that the current version of SIP does not complain about unknown
+annotations, or annotations used out of their correct context.
+
+
+.. _ref-arg-annos:
+
+Argument Annotations
+--------------------
+
+.. argument-annotation:: AllowNone
+
+ This boolean annotation specifies that the value of the corresponding
+ argument (which should be either :stype:`SIP_PYCALLABLE`,
+ :stype:`SIP_PYDICT`, :stype:`SIP_PYLIST`, :stype:`SIP_PYSLICE`,
+ :stype:`SIP_PYTUPLE` or :stype:`SIP_PYTYPE`) may be ``None``.
+
+
+.. argument-annotation:: Array
+
+ This boolean annotation specifies that the corresponding argument refers
+ to an array.
+
+ The argument should be either a pointer to a wrapped type, a ``char *`` or
+ a ``unsigned char *``. If the argument is a character array then the
+ annotation also implies the :aanno:`Encoding` annotation with an encoding
+ of ``"None"``.
+
+ There must be a corresponding argument with the :aanno:`ArraySize`
+ annotation specified. The annotation may only be specified once in a list
+ of arguments.
+
+
+.. argument-annotation:: ArraySize
+
+ This boolean annotation specifies that the corresponding argument (which
+ should be either ``short``, ``unsigned short``, ``int``, ``unsigned``,
+ ``long`` or ``unsigned long``) refers to the size of an array. There must
+ be a corresponding argument with the :aanno:`Array` annotation specified.
+ The annotation may only be specified once in a list of arguments.
+
+
+.. argument-annotation:: Constrained
+
+ Python will automatically convert between certain compatible types. For
+ example, if a floating pointer number is expected and an integer supplied,
+ then the integer will be converted appropriately. This can cause problems
+ when wrapping C or C++ functions with similar signatures. For example::
+
+ // The wrapper for this function will also accept an integer argument
+ // which Python will automatically convert to a floating point number.
+ void foo(double);
+
+ // The wrapper for this function will never get used.
+ void foo(int);
+
+ This boolean annotation specifies that the corresponding argument (which
+ should be either ``bool``, ``int``, ``float``, ``double``, ``enum`` or a
+ wrapped class) must match the type without any automatic conversions. In
+ the context of a wrapped class the invocation of any
+ :directive:`%ConvertToTypeCode` is suppressed.
+
+ The following example gets around the above problem::
+
+ // The wrapper for this function will only accept floating point
+ // numbers.
+ void foo(double /Constrained/);
+
+ // The wrapper for this function will be used for anything that Python
+ // can convert to an integer, except for floating point numbers.
+ void foo(int);
+
+
+.. argument-annotation:: DocType
+
+ .. versionadded:: 4.10
+
+ This string annotation specifies the type of the argument as it will appear
+ in any generated docstrings. It is usually used with arguments of type
+ :stype:`SIP_PYOBJECT` to provide a more specific type.
+
+
+.. argument-annotation:: DocValue
+
+ .. versionadded:: 4.10
+
+ This string annotation specifies the default value of the argument as it
+ will appear in any generated docstrings.
+
+
+.. argument-annotation:: Encoding
+
+ This string annotation specifies that the corresponding argument (which
+ should be either ``char``, ``const char``, ``char *`` or ``const char *``)
+ refers to an encoded character or ``'\0'`` terminated encoded string with
+ the specified encoding. The encoding can be either ``"ASCII"``,
+ ``"Latin-1"``, ``"UTF-8"`` or ``"None"``. An encoding of ``"None"`` means
+ that the corresponding argument refers to an unencoded character or string.
+
+ The default encoding is specified by the :directive:`%DefaultEncoding`
+ directive. If the directive is not specified then ``None`` is used.
+
+ Python v3 will use the ``bytes`` type to represent the argument if the
+ encoding is ``"None"`` and the ``str`` type otherwise.
+
+ Python v2 will use the ``str`` type to represent the argument if the
+ encoding is ``"None"`` and the ``unicode`` type otherwise.
+
+
+.. argument-annotation:: GetWrapper
+
+ This boolean annotation is only ever used in conjunction with handwritten
+ code specified with the :directive:`%MethodCode` directive. It causes an
+ extra variable to be generated for the corresponding argument which is a
+ pointer to the Python object that wraps the argument.
+
+ See the :directive:`%MethodCode` directive for more detail.
+
+
+.. argument-annotation:: In
+
+ This boolean annotation is used to specify that the corresponding argument
+ (which should be a pointer type) is used to pass a value to the function.
+
+ For pointers to wrapped C structures or C++ class instances, ``char *`` and
+ ``unsigned char *`` then this annotation is assumed unless the :aanno:`Out`
+ annotation is specified.
+
+ For pointers to other types then this annotation must be explicitly
+ specified if required. The argument will be dereferenced to obtain the
+ actual value.
+
+ Both :aanno:`In` and :aanno:`Out` may be specified for the same argument.
+
+
+.. argument-annotation:: KeepReference
+
+ This boolean annotation is used to specify that a reference to the
+ corresponding argument should be kept to ensure that the object is not
+ garbage collected. If the method is called again with a new argument then
+ the reference to the previous argument is discarded. Note that ownership
+ of the argument is not changed.
+
+
+.. argument-annotation:: NoCopy
+
+ .. versionadded:: 4.10.1
+
+ This boolean annotation is used with arguments of virtual methods that are
+ a ``const`` reference to a class. Normally, if the class defines a copy
+ constructor then a copy of the returned reference is automatically created
+ and wrapped before being passed to a Python reimplementation of the method.
+ The copy will be owned by Python. This means that the reimplementation may
+ take a reference to the argument without having to make an explicit copy.
+
+ If the annotation is specified then the copy is not made and the original
+ reference is wrapped instead and will be owned by C++.
+
+
+.. argument-annotation:: Out
+
+ This boolean annotation is used to specify that the corresponding argument
+ (which should be a pointer type) is used by the function to return a value
+ as an element of a tuple.
+
+ For pointers to wrapped C structures or C++ class instances, ``char *`` and
+ ``unsigned char *`` then this annotation must be explicitly specified if
+ required.
+
+ For pointers to other types then this annotation is assumed unless the
+ :aanno:`In` annotation is specified.
+
+ Both :aanno:`In` and :aanno:`Out` may be specified for the same argument.
+
+
+.. argument-annotation:: ResultSize
+
+ This boolean annotation is used with functions or methods that return a
+ ``void *`` or ``const void *``. It identifies an argument that defines the
+ size of the block of memory whose address is being returned. This allows
+ the ``sip.voidptr`` object that wraps the address to support the Python
+ buffer protocol and allows the memory to be read and updated when wrapped
+ by the Python ``buffer()`` builtin.
+
+
+.. argument-annotation:: SingleShot
+
+ This boolean annotation is used only with arguments of type
+ :stype:`SIP_RXOBJ_CON` to specify that the signal connected to the slot
+ will only ever be emitted once. This prevents a certain class of memory
+ leaks.
+
+
+.. argument-annotation:: Transfer
+
+ This boolean annotation is used to specify that ownership of the
+ corresponding argument (which should be a wrapped C structure or C++ class
+ instance) is transferred from Python to C++. In addition, if the argument
+ is of a class method, then it is associated with the class instance with
+ regard to the cyclic garbage collector.
+
+ See :ref:`ref-object-ownership` for more detail.
+
+
+.. argument-annotation:: TransferBack
+
+ This boolean annotation is used to specify that ownership of the
+ corresponding argument (which should be a wrapped C structure or C++ class
+ instance) is transferred back to Python from C++. In addition, any
+ association of the argument with regard to the cyclic garbage collector
+ with another instance is removed.
+
+ See :ref:`ref-object-ownership` for more detail.
+
+
+.. argument-annotation:: TransferThis
+
+ This boolean annotation is only used in C++ constructors or methods. In
+ the context of a constructor or factory method it specifies that ownership
+ of the instance being created is transferred from Python to C++ if the
+ corresponding argument (which should be a wrapped C structure or C++ class
+ instance) is not ``None``. In addition, the newly created instance is
+ associated with the argument with regard to the cyclic garbage collector.
+
+ In the context of a non-factory method it specifies that ownership of
+ ``this`` is transferred from Python to C++ if the corresponding argument is
+ not ``None``. If it is ``None`` then ownership is transferred to Python.
+
+ The annotation may be used more that once, in which case ownership is
+ transferred to last instance that is not ``None``.
+
+ See :ref:`ref-object-ownership` for more detail.
+
+
+.. _ref-class-annos:
+
+Class Annotations
+-----------------
+
+.. class-annotation:: Abstract
+
+ This boolean annotation is used to specify that the class has additional
+ pure virtual methods that have not been specified and so it cannot be
+ instantiated or sub-classed from Python.
+
+
+.. class-annotation:: AllowNone
+
+ .. versionadded:: 4.8.2
+
+ Normally when a Python object is converted to a C/C++ instance ``None``
+ is handled automatically before the class's
+ :directive:`%ConvertToTypeCode` is called. This boolean annotation
+ specifies that the handling of ``None`` will be left to the
+ :directive:`%ConvertToTypeCode`. The annotation is ignored if the class
+ does not have any :directive:`%ConvertToTypeCode`.
+
+
+.. class-annotation:: API
+
+ .. versionadded:: 4.9
+
+ This API range annotation is used to specify an API and corresponding
+ range of version numbers that the class is enabled for.
+
+ If a class or mapped type has different implementations enabled for
+ different ranges of version numbers then those ranges must not overlap.
+
+ See :ref:`ref-incompat-apis` for more detail.
+
+
+.. class-annotation:: DelayDtor
+
+ This boolean annotation is used to specify that the class's destructor
+ should not be called until the Python interpreter exits. It would normally
+ only be applied to singleton classes.
+
+ When the Python interpreter exits the order in which any wrapped instances
+ are garbage collected is unpredictable. However, the underlying C or C++
+ instances may need to be destroyed in a certain order. If this annotation
+ is specified then when the wrapped instance is garbage collected the C or
+ C++ instance is not destroyed but instead added to a list of delayed
+ instances. When the interpreter exits then the function
+ :cfunc:`sipDelayedDtors()` is called with the list of delayed instances.
+ :cfunc:`sipDelayedDtors()` can then choose to call (or ignore) the
+ destructors in any desired order.
+
+ The :cfunc:`sipDelayedDtors()` function must be specified using the
+ :directive:`%ModuleCode` directive.
+
+.. cfunction:: void sipDelayedDtors(const sipDelayedDtor *dd_list)
+
+ :param dd_list:
+ the linked list of delayed instances.
+
+.. ctype:: sipDelayedDtor
+
+ This structure describes a particular delayed destructor.
+
+ .. cmember:: const char *dd_name
+
+ This is the name of the class excluding any package or module name.
+
+ .. cmember:: void *dd_ptr
+
+ This is the address of the C or C++ instance to be destroyed. It's
+ exact type depends on the value of :cmember:`dd_isderived`.
+
+ .. cmember:: int dd_isderived
+
+ This is non-zero if the type of :cmember:`dd_ptr` is actually the
+ generated derived class. This allows the correct destructor to be
+ called. See :ref:`ref-derived-classes`.
+
+ .. cmember:: sipDelayedDtor *dd_next
+
+ This is the address of the next entry in the list or zero if this is
+ the last one.
+
+ Note that the above applies only to C and C++ instances that are owned by
+ Python.
+
+
+.. class-annotation:: Deprecated
+
+ This boolean annotation is used to specify that the class is deprecated.
+ It is the equivalent of annotating all the class's constructors, function
+ and methods as being deprecated.
+
+
+.. class-annotation:: External
+
+ This boolean annotation is used to specify that the class is defined in
+ another module. Declarations of external classes are private to the module
+ in which they appear.
+
+
+.. class-annotation:: Metatype
+
+ This dotted name annotation specifies the name of the Python type object
+ (i.e. the value of the ``tp_name`` field) used as the meta-type used when
+ creating the type object for this C structure or C++ type.
+
+ See the section :ref:`ref-types-metatypes` for more details.
+
+
+.. class-annotation:: NoDefaultCtors
+
+ This boolean annotation is used to suppress the automatic generation of
+ default constructors for the class.
+
+
+.. class-annotation:: PyName
+
+ This name annotation specifies an alternative name for the class being
+ wrapped which is used when it is referred to from Python. It is required
+ when a class name is the same as a Python keyword. It may also be used to
+ avoid name clashes with other objects (e.g. enums, exceptions, functions)
+ that have the same name in the same C++ scope.
+
+
+.. class-annotation:: Supertype
+
+ This dotted name annotation specifies the name of the Python type object
+ (i.e. the value of the ``tp_name`` field) used as the super-type used when
+ creating the type object for this C structure or C++ type.
+
+ See the section :ref:`ref-types-metatypes` for more details.
+
+
+.. _ref-mapped-type-annos:
+
+Mapped Type Annotations
+-----------------------
+
+.. mapped-type-annotation:: AllowNone
+
+ Normally when a Python object is converted to a C/C++ instance ``None``
+ is handled automatically before the mapped type's
+ :directive:`%ConvertToTypeCode` is called. This boolean annotation
+ specifies that the handling of ``None`` will be left to the
+ :directive:`%ConvertToTypeCode`.
+
+
+.. mapped-type-annotation:: API
+
+ .. versionadded:: 4.9
+
+ This API range annotation is used to specify an API and corresponding
+ range of version numbers that the mapped type is enabled for.
+
+ If a class or mapped type has different implementations enabled for
+ different ranges of version numbers then those ranges must not overlap.
+
+ See :ref:`ref-incompat-apis` for more detail.
+
+
+.. mapped-type-annotation:: DocType
+
+ .. versionadded:: 4.10
+
+ This string annotation specifies the name of the type as it will appear in
+ any generated docstrings.
+
+
+.. mapped-type-annotation:: NoRelease
+
+ This boolean annotation is used to specify that the mapped type does not
+ support the :cfunc:`sipReleaseType()` function. Any
+ :directive:`%ConvertToTypeCode` should not create temporary instances of
+ the mapped type, i.e. it should not return :cmacro:`SIP_TEMPORARY`.
+
+
+.. _ref-enum-annos:
+
+Enum Annotations
+----------------
+
+.. enum-annotation:: PyName
+
+ This name annotation specifies an alternative name for the enum or enum
+ member being wrapped which is used when it is referred to from Python. It
+ is required when an enum or enum member name is the same as a Python
+ keyword. It may also be used to avoid name clashes with other objects
+ (e.g. classes, exceptions, functions) that have the same name in the same
+ C++ scope.
+
+
+.. _ref-exception-annos:
+
+Exception Annotations
+---------------------
+
+.. exception-annotation:: Default
+
+ This boolean annotation specifies that the exception being defined will be
+ used as the default exception to be caught if a function or constructor
+ does not have a ``throw`` clause.
+
+.. exception-annotation:: PyName
+
+ This name annotation specifies an alternative name for the exception being
+ defined which is used when it is referred to from Python. It is required
+ when an exception name is the same as a Python keyword. It may also be
+ used to avoid name clashes with other objects (e.g. classes, enums,
+ functions) that have the same name.
+
+
+.. _ref-function-annos:
+
+Function Annotations
+--------------------
+
+.. function-annotation:: API
+
+ .. versionadded:: 4.9
+
+ This API range annotation is used to specify an API and corresponding
+ range of version numbers that the function is enabled for.
+
+ See :ref:`ref-incompat-apis` for more detail.
+
+
+.. function-annotation:: AutoGen
+
+ This optional name annotation is used with class methods to specify that
+ the method be automatically included in all sub-classes. The value is the
+ name of a feature (specified using the :directive:`%Feature` directive)
+ which must be enabled for the method to be generated.
+
+
+.. function-annotation:: Default
+
+ This boolean annotation is only used with C++ constructors. Sometimes SIP
+ needs to create a class instance. By default it uses a constructor with no
+ compulsory arguments if one is specified. (SIP will automatically generate
+ a constructor with no arguments if no constructors are specified.) This
+ annotation is used to explicitly specify which constructor to use. Zero is
+ passed as the value of any arguments to the constructor.
+
+
+.. function-annotation:: Deprecated
+
+ This boolean annotation is used to specify that the constructor or function
+ is deprecated. A deprecation warning is issued whenever the constructor or
+ function is called.
+
+
+.. function-annotation:: DocType
+
+ .. versionadded:: 4.10
+
+ This string annotation specifies the name of the type of the returned value
+ as it will appear in any generated docstrings. It is usually used with
+ values of type :stype:`SIP_PYOBJECT` to provide a more specific type.
+
+
+.. function-annotation:: Factory
+
+ This boolean annotation specifies that the value returned by the function
+ (which should be a wrapped C structure or C++ class instance) is a newly
+ created instance and is owned by Python.
+
+ See :ref:`ref-object-ownership` for more detail.
+
+
+.. function-annotation:: HoldGIL
+
+ This boolean annotation specifies that the Python Global Interpreter Lock
+ (GIL) is not released before the call to the underlying C or C++ function.
+ See :ref:`ref-gil` and the :fanno:`ReleaseGIL` annotation.
+
+
+.. function-annotation:: KeywordArgs
+
+ .. versionadded:: 4.10
+
+ This boolean annotation specifies that the argument parser generated for
+ this function will support passing the parameters using Python's keyword
+ argument syntax. Keyword arguments cannot be used for functions that have
+ unnamed arguments or use an ellipsis to designate that the function has a
+ variable number of arguments.
+
+
+.. function-annotation:: __len__
+
+ .. versionadded:: 4.10.3
+
+ This boolean annotation specifies that a ``__len__()`` method should be
+ automatically generated that will use the method being annotated to compute
+ the value that the ``__len__()`` method will return.
+
+
+.. function-annotation:: NewThread
+
+ This boolean annotation specifies that the function will create a new
+ thread.
+
+
+.. function-annotation:: NoArgParser
+
+ This boolean annotation is used with methods and global functions to
+ specify that the supplied :directive:`%MethodCode` will handle the parsing
+ of the arguments.
+
+
+.. function-annotation:: NoCopy
+
+ .. versionadded:: 4.10.1
+
+ This boolean annotation is used with methods and global functions that
+ return a ``const`` reference to a class. Normally, if the class defines a
+ copy constructor then a copy of the returned reference is automatically
+ created and wrapped. The copy will be owned by Python.
+
+ If the annotation is specified then the copy is not made and the original
+ reference is wrapped instead and will be owned by C++.
+
+
+.. function-annotation:: NoDerived
+
+ This boolean annotation is only used with C++ constructors. In many cases
+ SIP generates a derived class for each class being wrapped (see
+ :ref:`ref-derived-classes`). This derived class contains constructors with
+ the same C++ signatures as the class being wrapped. Sometimes you may want
+ to define a Python constructor that has no corresponding C++ constructor.
+ This annotation is used to suppress the generation of the constructor in
+ the derived class.
+
+
+.. function-annotation:: NoKeywordArgs
+
+ .. versionadded:: 4.10
+
+ This boolean annotation specifies that the argument parser generated for
+ this function will not support passing the parameters using Python's
+ keyword argument syntax. In other words, the argument parser will only
+ support only normal positional arguments. This annotation is useful when
+ the default setting of allowing keyword arguments has been changed via the
+ command line, but you would still like certain functions to only support
+ positional arguments.
+
+
+.. function-annotation:: Numeric
+
+ This boolean annotation specifies that the operator should be interpreted
+ as a numeric operator rather than a sequence operator. Python uses the
+ ``+`` operator for adding numbers and concatanating sequences, and the
+ ``*`` operator for multiplying numbers and repeating sequences. SIP tries
+ to work out which is meant by looking at other operators that have been
+ defined for the type. If it finds either ``-``, ``-=``, ``/``, ``/=``,
+ ``%`` or ``%=`` defined then it assumes that ``+``, ``+=``, ``*`` and
+ ``*=`` should be numeric operators. Otherwise, if it finds either ``[]``,
+ :meth:`__getitem__`, :meth:`__setitem__` or :meth:`__delitem__` defined
+ then it assumes that they should be sequence operators. This annotation is
+ used to force SIP to treat the operator as numeric.
+
+
+.. function-annotation:: PostHook
+
+ This name annotation is used to specify the name of a Python builtin that
+ is called immediately after the call to the underlying C or C++ function or
+ any handwritten code. The builtin is not called if an error occurred. It
+ is primarily used to integrate with debuggers.
+
+
+.. function-annotation:: PreHook
+
+ This name annotation is used to specify the name of a Python builtin that
+ is called immediately after the function's arguments have been successfully
+ parsed and before the call to the underlying C or C++ function or any
+ handwritten code. It is primarily used to integrate with debuggers.
+
+
+.. function-annotation:: PyName
+
+ This name annotation specifies an alternative name for the function being
+ wrapped which is used when it is referred to from Python. It is required
+ when a function or method name is the same as a Python keyword. It may
+ also be used to avoid name clashes with other objects (e.g. classes, enums,
+ exceptions) that have the same name in the same C++ scope.
+
+
+.. function-annotation:: ReleaseGIL
+
+ This boolean annotation specifies that the Python Global Interpreter Lock
+ (GIL) is released before the call to the underlying C or C++ function and
+ reacquired afterwards. It should be used for functions that might block or
+ take a significant amount of time to execute. See :ref:`ref-gil` and the
+ :fanno:`HoldGIL` annotation.
+
+
+.. function-annotation:: Transfer
+
+ This boolean annotation specifies that ownership of the value returned by
+ the function (which should be a wrapped C structure or C++ class instance)
+ is transferred to C++. It is only used in the context of a class
+ constructor or a method.
+
+ In the case of methods returned values (unless they are new references to
+ already wrapped values) are normally owned by C++ anyway. However, in
+ addition, an association between the returned value and the instance
+ containing the method is created with regard to the cyclic garbage
+ collector.
+
+ See :ref:`ref-object-ownership` for more detail.
+
+
+.. function-annotation:: TransferBack
+
+ This boolean annotation specifies that ownership of the value returned by
+ the function (which should be a wrapped C structure or C++ class instance)
+ is transferred back to Python from C++. Normally returned values (unless
+ they are new references to already wrapped values) are owned by C++. In
+ addition, any association of the returned value with regard to the cyclic
+ garbage collector with another instance is removed.
+
+ See :ref:`ref-object-ownership` for more detail.
+
+
+.. function-annotation:: TransferThis
+
+ This boolean annotation specifies that ownership of ``this`` is transferred
+ from Python to C++.
+
+ See :ref:`ref-object-ownership` for more detail.
+
+
+.. _ref-license-annos:
+
+License Annotations
+-------------------
+
+.. license-annotation:: Licensee
+
+ This optional string annotation specifies the license's licensee. No
+ restrictions are placed on the contents of the string.
+
+ See the :directive:`%License` directive.
+
+
+.. license-annotation:: Signature
+
+ This optional string annotation specifies the license's signature. No
+ restrictions are placed on the contents of the string.
+
+ See the :directive:`%License` directive.
+
+
+.. license-annotation:: Timestamp
+
+ This optional string annotation specifies the license's timestamp. No
+ restrictions are placed on the contents of the string.
+
+ See the :directive:`%License` directive.
+
+
+.. license-annotation:: Type
+
+ This string annotation specifies the license's type. No restrictions are
+ placed on the contents of the string.
+
+ See the :directive:`%License` directive.
+
+
+.. _ref-typedef-annos:
+
+Typedef Annotations
+-------------------
+
+.. typedef-annotation:: NoTypeName
+
+ This boolean annotation specifies that the definition of the type rather
+ than the name of the type being defined should be used in the generated
+ code.
+
+ Normally a typedef would be defined as follows::
+
+ typedef bool MyBool;
+
+ This would result in ``MyBool`` being used in the generated code.
+
+ Specifying the annotation means that ``bool`` will be used in the generated
+ code instead.
+
+
+.. _ref-variable-annos:
+
+Variable Annotations
+--------------------
+
+.. variable-annotation:: DocType
+
+ .. versionadded:: 4.10
+
+ This string annotation specifies the name of the type of the variable as it
+ will appear in any generated docstrings. It is usually used with variables
+ of type :stype:`SIP_PYOBJECT` to provide a more specific type.
+
+
+.. variable-annotation:: PyName
+
+ This name annotation specifies an alternative name for the variable being
+ wrapped which is used when it is referred to from Python. It is required
+ when a variable name is the same as a Python keyword. It may also be used
+ to avoid name clashes with other objects (e.g. classes, functions) that
+ have the same name in the same C++ scope.
diff --git a/sphinx/build_system.rst b/sphinx/build_system.rst
new file mode 100644
index 0000000..292836a
--- /dev/null
+++ b/sphinx/build_system.rst
@@ -0,0 +1,843 @@
+.. _ref-build-system:
+
+The Build System
+================
+
+.. module:: sipconfig
+
+The purpose of the build system is to make it easy for you to write
+configuration scripts in Python for your own bindings. The build system takes
+care of the details of particular combinations of platform and compiler. It
+supports over 50 different platform/compiler combinations.
+
+The build system is implemented as a pure Python module called :mod:`sipconfig`
+that contains a number of classes and functions. Using this module you can
+write bespoke configuration scripts (e.g. PyQt's ``configure.py``) or use it
+with other Python based build systems (e.g.
+`Distutils <http://www.python.org/sigs/distutils-sig/distutils.html>`_ and
+`SCons <http://www.scons.org>`_).
+
+An important feature of SIP is the ability to generate bindings that are built
+on top of existing bindings. For example, both
+`PyKDE <http://www.riverbankcomputing.com/software/pykde/>`_ and
+`PyQwt <http://pyqwt.sourceforge.net/>`_ are built on top of PyQt but all three
+packages are maintained by different developers. To make this easier PyQt
+includes its own configuration module, ``pyqtconfig``, that contains additional
+classes intended to be used by the configuration scripts of bindings built on
+top of PyQt. The SIP build system includes facilities that do a lot of the
+work of creating these additional configuration modules.
+
+
+.. function:: create_config_module(module, template, content[, macros=None])
+
+ This creates a configuration module (e.g. ``pyqtconfig``) from a template
+ file and a string.
+
+ :param module:
+ the name of the configuration module file to create.
+ :param template:
+ the name of the template file.
+ :param content:
+ a string which replaces every occurence of the pattern
+ ``@SIP_CONFIGURATION@`` in the template file. The content string is
+ usually created from a Python dictionary using
+ :func:`sipconfig.create_content()`. *content* may also be a
+ dictionary, in which case :func:`sipconfig.create_content()` is
+ automatically called to convert it to a string.
+ :param macros:
+ an optional dictionary of platform specific build macros. It is only
+ used if :func:`sipconfig.create_content()` is called automatically to
+ convert a *content* dictionary to a string.
+
+
+.. function:: create_content(dict[, macros=None]) -> string
+
+ This converts a Python dictionary to a string that can be parsed by the
+ Python interpreter and converted back to an equivalent dictionary. It is
+ typically used to generate the content string for
+ :func:`sipconfig.create_config_module()`.
+
+ :param dict:
+ the Python dictionary to convert.
+ :param macros:
+ the optional dictionary of platform specific build macros.
+ :return:
+ the string representation of the dictionary.
+
+
+.. function:: create_wrapper(script, wrapper[, gui=0[, use_arch='']]) -> string
+
+ This creates a platform dependent executable wrapper around a Python
+ script.
+
+ :param script:
+ the full pathname of the script.
+ :param wrapper:
+ the full pathname of the wrapper to create, excluding any platform
+ specific extension.
+ :param gui:
+ is non-zero if a GUI enabled version of the interpreter should be used
+ on platforms that require it.
+ :param use_arch:
+ is the MacOS/X architecture to invoke python with.
+ :return:
+ the platform specific name of the wrapper.
+
+
+.. function:: error(msg)
+
+ This displays an error message on ``stderr`` and calls ``sys.exit(1)``.
+
+ :param msg:
+ the text of the message and should not include any newline characters.
+
+
+.. function:: format(msg[, leftmargin=0[, rightmargin=78]]) -> string
+
+ This formats a message by inserting newline characters at appropriate
+ places.
+
+ :param msg:
+ the text of the message and should not include any newline characters.
+ :param leftmargin:
+ the optional position of the left margin.
+ :param rightmargin:
+ the optional position of the right margin.
+ :return:
+ the formatted message.
+
+
+.. function:: inform(msg)
+
+ This displays an information message on ``stdout``.
+
+ :param msg:
+ the text of the message and should not include any newline characters.
+
+
+.. function:: parse_build_macros(filename, names[, overrides=None[, properties=None]]) -> dict
+
+ This parses a ``qmake`` compatible file of build system macros and converts
+ it to a dictionary. A macro is a name/value pair. Individual macros may
+ be augmented or replaced.
+
+ :param filename:
+ the name of the file to parse.
+ :param names:
+ the list of the macro names to extract from the file.
+ :param overrides:
+ the optional list of macro names and values that modify those found in
+ the file. They are of the form ``name=value`` (in which case the value
+ replaces the value found in the file) or ``name+=value`` (in which case
+ the value is appended to the value found in the file).
+ :param properties:
+ the optional dictionary of property name and values that are used to
+ resolve any expressions of the form ``$[name]`` in the file.
+ :return:
+ the dictionary of parsed macros or ``None`` if any of the overrides
+ were invalid.
+
+
+.. function:: read_version(filename, description[, numdefine=None[, strdefine=None]]) -> integer, string
+
+ This extracts version information for a package from a file, usually a C or
+ C++ header file. The version information must each be specified as a
+ ``#define`` of a numeric (hexadecimal or decimal) value and/or a string
+ value.
+
+ :param filename:
+ the name of the file to read.
+ :param description:
+ a descriptive name of the package used in error messages.
+ :param numdefine:
+ the optional name of the ``#define`` of the version as a number. If it
+ is ``None`` then the numeric version is ignored.
+ :param strdefine:
+ the optional name of the ``#define`` of the version as a string. If it
+ is ``None`` then the string version is ignored.
+ :return:
+ a tuple of the numeric and string versions. :func:`sipconfig.error()`
+ is called if either were required but could not be found.
+
+
+.. function:: version_to_sip_tag(version, tags, description) -> string
+
+ This converts a version number to a SIP version tag. SIP uses the
+ :directive:`%Timeline` directive to define the chronology of the different
+ versions of the C/C++ library being wrapped. Typically it is not necessary
+ to define a version tag for every version of the library, but only for
+ those versions that affect the library's API as SIP sees it.
+
+ :param version:
+ the numeric version number of the C/C++ library being wrapped. If it
+ is negative then the latest version is assumed. (This is typically
+ useful if a snapshot is indicated by a negative version number.)
+ :param tags:
+ the dictionary of SIP version tags keyed by the corresponding C/C++
+ library version number. The tag used is the one with the smallest key
+ (i.e. earliest version) that is greater than *version*.
+ :param description:
+ a descriptive name of the C/C++ library used in error messages.
+ :return:
+ the SIP version tag. :func:`sipconfig.error()` is called if the C/C++
+ library version number did not correspond to a SIP version tag.
+
+
+.. function:: version_to_string(v) -> string
+
+ This converts a 3 part version number encoded as a hexadecimal value to a
+ string.
+
+ :param v:
+ the version number.
+ :return:
+ a string.
+
+
+.. class:: Configuration
+
+ This class encapsulates configuration values that can be accessed as
+ instance objects. A sub-class may provide a dictionary of additional
+ configuration values in its constructor the elements of which will have
+ precedence over the super-class's values.
+
+ The following configuration values are provided:
+
+ .. attribute:: default_bin_dir
+
+ The name of the directory where executables should be installed by
+ default.
+
+ .. attribute:: default_mod_dir
+
+ The name of the directory where SIP generated modules should be
+ installed by default.
+
+ .. attribute:: default_sip_dir
+
+ The name of the base directory where the ``.sip`` files for SIP
+ generated modules should be installed by default. A sub-directory with
+ the same name as the module should be created and its ``.sip`` files
+ should be installed in the sub-directory. The ``.sip`` files only need
+ to be installed if you might want to build other bindings based on
+ them.
+
+ .. attribute:: platform
+
+ The name of the platform/compiler for which the build system has been
+ configured for.
+
+ .. attribute:: py_conf_inc_dir
+
+ The name of the directory containing the ``pyconfig.h`` header file.
+
+ .. attribute:: py_inc_dir
+
+ The name of the directory containing the ``Python.h`` header file.
+
+ .. attribute:: py_lib_dir
+
+ The name of the directory containing the Python interpreter library.
+
+ .. attribute:: py_version
+
+ The Python version as a 3 part hexadecimal number (e.g. v2.3.3 is
+ represented as ``0x020303``).
+
+ .. attribute:: sip_bin
+
+ The full pathname of the SIP executable.
+
+ .. attribute:: sip_config_args
+
+ The command line passed to ``configure.py`` when SIP was configured.
+
+ .. attribute:: sip_inc_dir
+
+ The name of the directory containing the ``sip.h`` header file.
+
+ .. attribute:: sip_mod_dir
+
+ The name of the directory containing the SIP module.
+
+ .. attribute:: sip_version
+
+ The SIP version as a 3 part hexadecimal number (e.g. v4.0.0 is
+ represented as ``0x040000``).
+
+ .. attribute:: sip_version_str
+
+ The SIP version as a string. For development snapshots it will start
+ with ``snapshot-``.
+
+ .. attribute:: universal
+
+ The name of the MacOS/X SDK used when creating universal binaries.
+
+ .. attribute:: arch
+
+ The space separated MacOS/X architectures to build.
+
+ .. method:: __init__([sub_cfg=None])
+
+ :param sub_cfg:
+ an optional list of sub-class configurations. It should only be
+ used by the ``__init__()`` method of a sub-class to append its own
+ dictionary of configuration values before passing the list to its
+ super-class.
+
+ .. method:: build_macros() -> dict
+
+ Get the dictionary of platform specific build macros.
+
+ :return:
+ the macros dictionary.
+
+ .. method:: set_build_macros(macros)
+
+ Set the dictionary of platform specific build macros to be used when
+ generating Makefiles. Normally there is no need to change the default
+ macros.
+
+ :param macros:
+ the macros dictionary.
+
+
+.. class:: Makefile
+
+ This class encapsulates a Makefile. It is intended to be sub-classed to
+ generate Makefiles for particular purposes. It handles all platform and
+ compiler specific flags, but allows them to be adjusted to suit the
+ requirements of a particular module or program. These are defined using a
+ number of macros which can be accessed as instance attributes.
+
+ The following instance attributes are provided to help in fine tuning the
+ generated Makefile:
+
+ .. attribute:: chkdir
+
+ A string that will check for the existence of a directory.
+
+ .. attribute:: config
+
+ A reference to the *configuration* argument that was passed to
+ :meth:`Makefile.__init__`.
+
+ .. attribute:: console
+
+ A reference to the *console* argument that was passed to the
+ :meth:`Makefile.__init__`.
+
+ .. attribute:: copy
+
+ A string that will copy a file.
+
+ .. attribute:: extra_cflags
+
+ A list of additional flags passed to the C compiler.
+
+ .. attribute:: extra_cxxflags
+
+ A list of additional flags passed to the C++ compiler.
+
+ .. attribute:: extra_defines
+
+ A list of additional macro names passed to the C/C++ preprocessor.
+
+ .. attribute:: extra_include_dirs
+
+ A list of additional include directories passed to the C/C++
+ preprocessor.
+
+ .. attribute:: extra_lflags
+
+ A list of additional flags passed to the linker.
+
+ .. attribute:: extra_lib_dirs
+
+ A list of additional library directories passed to the linker.
+
+ .. attribute:: extra_libs
+
+ A list of additional libraries passed to the linker. The names of the
+ libraries must be in platform neutral form (i.e. without any platform
+ specific prefixes, version numbers or extensions).
+
+ .. attribute:: generator
+
+ A string that defines the platform specific style of Makefile. The
+ only supported values are ``UNIX``, ``MSVC``, ``MSVC.NET``, ``MINGW``
+ and ``BMAKE``.
+
+ .. attribute:: mkdir
+
+ A string that will create a directory.
+
+ .. attribute:: rm
+
+ A string that will remove a file.
+
+ .. method:: __init__(configuration[, console=0[, qt=0[, opengl=0[, python=0[, threaded=0[, warnings=None[, debug=0[, dir=None[, makefile="Makefile"[, installs=None[, universal=None[, arch=None]]]]]]]]]]]])
+
+ :param configuration:
+ the current configuration and is an instance of the
+ :class:`Configuration` class or a sub-class.
+ :param console:
+ is set if the target is a console (rather than GUI) target. This
+ only affects Windows and is ignored on other platforms.
+ :param qt:
+ is set if the target uses Qt. For Qt v4 a list of Qt libraries may
+ be specified and a simple non-zero value implies QtCore and QtGui.
+ :param opengl:
+ is set if the target uses OpenGL.
+ :param python:
+ is set if the target uses Python.h.
+ :param threaded:
+ is set if the target requires thread support. It is set
+ automatically if the target uses Qt and Qt has thread support
+ enabled.
+ :param warnings:
+ is set if compiler warning messages should be enabled. The default
+ of ``None`` means that warnings are enabled for SIP v4.x and
+ disabled for SIP v3.x.
+ :param debug:
+ is set if debugging symbols should be generated.
+ :param dir:
+ the name of the directory where build files are read from (if they
+ are not absolute file names) and Makefiles are written to. The
+ default of ``None`` means the current directory is used.
+ :param makefile:
+ the name of the generated Makefile.
+ :param installs:
+ the list of extra install targets. Each element is a two part
+ list, the first of which is the source and the second is the
+ destination. If the source is another list then it is a list of
+ source files and the destination is a directory.
+ :param universal:
+ the name of the SDK if universal binaries are to be created under
+ MacOS/X. If it is ``None`` then the value is taken from the
+ configuration.
+ :param arch:
+ the space separated MacOS/X architectures to build. If it is
+ ``None`` then the value is taken from the configuration.
+
+ .. method:: clean_build_file_objects(mfile, build)
+
+ This generates the Makefile commands that will remove any files
+ generated during the build of the default target.
+
+ :param mfile:
+ the Python file object of the Makefile.
+ :param build:
+ the dictionary created from parsing the build file.
+
+ .. method:: finalise()
+
+ This is called just before the Makefile is generated to ensure that it
+ is fully configured. It must be reimplemented by a sub-class.
+
+ .. method:: generate()
+
+ This generates the Makefile.
+
+ .. method:: generate_macros_and_rules(mfile)
+
+ This is the default implementation of the Makefile macros and rules
+ generation.
+
+ :param mfile:
+ the Python file object of the Makefile.
+
+ .. method:: generate_target_clean(mfile)
+
+ This is the default implementation of the Makefile clean target
+ generation.
+
+ :param mfile:
+ the Python file object of the Makefile.
+
+ .. method:: generate_target_default(mfile)
+
+ This is the default implementation of the Makefile default target
+ generation.
+
+ :param mfile:
+ the Python file object of the Makefile.
+
+ .. method:: generate_target_install(mfile)
+
+ This is the default implementation of the Makefile install target
+ generation.
+
+ :param mfile:
+ the Python file object of the Makefile.
+
+ .. method:: install_file(mfile, src, dst[, strip=0])
+
+ This generates the Makefile commands to install one or more files to a
+ directory.
+
+ :param mfile:
+ the Python file object of the Makefile.
+ :param src:
+ the name of a single file to install or a list of a number of files
+ to install.
+ :param dst:
+ the name of the destination directory.
+ :param strip:
+ is set if the files should be stripped of unneeded symbols after
+ having been installed.
+
+ .. method:: optional_list(name) -> list
+
+ This returns an optional Makefile macro as a list.
+
+ :param name:
+ the name of the macro.
+ :return:
+ the macro as a list.
+
+ .. method:: optional_string(name[, default=""])
+
+ This returns an optional Makefile macro as a string.
+
+ :param name:
+ the name of the macro.
+ :param default:
+ the optional default value of the macro.
+ :return:
+ the macro as a string.
+
+ .. method:: parse_build_file(filename) -> dict
+
+ This parses a build file (created with the :option:`-b <sip -b>` SIP
+ command line option) and converts it to a dictionary. It can also
+ validate an existing dictionary created through other means.
+
+ :param filename: is the name of the build file, or is a dictionary to
+ be validated. A valid dictionary will contain the name of the
+ target to build (excluding any platform specific extension) keyed
+ by ``target``; the names of all source files keyed by ``sources``;
+ and, optionally, the names of all header files keyed by
+ ``headers``.
+ :return:
+ a dictionary corresponding to the parsed build file.
+
+ .. method:: platform_lib(clib[, framework=0]) -> string
+
+ This converts a library name to a platform specific form.
+
+ :param clib:
+ the name of the library in cannonical form.
+ :param framework:
+ is set if the library is implemented as a MacOS framework.
+ :return:
+ the platform specific name.
+
+ .. method:: ready()
+
+ This is called to ensure that the Makefile is fully configured. It is
+ normally called automatically when needed.
+
+ .. method:: required_string(name) -> string
+
+ This returns a required Makefile macro as a string.
+
+ :param name:
+ the name of the macro.
+ :return:
+ the macro as a string. An exception is raised if the macro does
+ not exist or has an empty value.
+
+
+.. class:: ModuleMakefile
+
+ This class is derived from :class:`sipconfig.Makefile`.
+
+ This class encapsulates a Makefile to build a generic Python extension
+ module.
+
+ .. method:: __init__(self, configuration, build_file[, install_dir=None[, static=0[, console=0[, opengl=0[, threaded=0[, warnings=None[, debug=0[, dir=None[, makefile="Makefile"[, installs=None[, strip=1[, export_all=0[, universal=None[, arch=None]]]]]]]]]]]]]])
+
+ :param configuration:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param build_file:
+ the name of the build file. Build files are generated using the
+ :option:`-b <sip -b>` SIP command line option.
+ :param install_dir:
+ the name of the directory where the module will be optionally
+ installed.
+ :param static:
+ is set if the module should be built as a static library (see
+ :ref:`ref-builtin`).
+ :param console:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param qt:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param opengl:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param threaded:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param warnings:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param debug:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param dir:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param makefile:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param installs:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param strip:
+ is set if the module should be stripped of unneeded symbols after
+ installation. It is ignored if either *debug* or *static* is set,
+ or if the platform doesn't support it.
+ :param export_all:
+ is set if all of the module's symbols should be exported rather
+ than just the module's initialisation function. Exporting all
+ symbols increases the size of the module and slows down module load
+ times but may avoid problems with modules that use C++ exceptions.
+ All symbols are exported if either *debug* or *static* is set, or
+ if the platform doesn't support it.
+ :param universal:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param arch:
+ see :meth:`sipconfig.Makefile.__init__`.
+
+ .. method:: finalise()
+
+ This is a reimplementation of :meth:`sipconfig.Makefile.finalise`.
+
+ .. method:: generate_macros_and_rules(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_macros_and_rules`.
+
+ .. method:: generate_target_clean(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_target_clean`.
+
+ .. method:: generate_target_default(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_target_default`.
+
+ .. method:: generate_target_install(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_target_install`.
+
+ .. method:: module_as_lib(mname) -> string
+
+ This gets the name of a SIP v3.x module for when it is used as a
+ library to be linked against. An exception will be raised if it is
+ used with SIP v4.x modules.
+
+ :param mname:
+ the name of the module.
+ :return:
+ the corresponding library name.
+
+
+.. class:: ParentMakefile
+
+ This class is derived from :class:`sipconfig.Makefile`.
+
+ This class encapsulates a Makefile that sits above a number of other
+ Makefiles in sub-directories.
+
+ .. method:: __init__(self, configuration, subdirs[, dir=None[, makefile[="Makefile"[, installs=None]]]])
+
+ :param configuration:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param subdirs:
+ the sequence of sub-directories.
+ :param dir:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param makefile:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param installs:
+ see :meth:`sipconfig.Makefile.__init__`.
+
+ .. method:: generate_macros_and_rules(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_macros_and_rules`.
+
+ .. method:: generate_target_clean(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_target_clean`.
+
+ .. method:: generate_target_default(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_target_default`.
+
+ .. method:: generate_target_install(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_target_install`.
+
+.. class:: ProgramMakefile
+
+ This class is derived from :class:`sipconfig.Makefile`.
+
+ This class encapsulates a Makefile to build an executable program.
+
+ .. method:: __init__(configuration[, build_file=None[, install_dir=None[, console=0[, qt=0[, opengl=0[, python=0[, threaded=0[, warnings=None[, debug=0[, dir=None[, makefile="Makefile"[, installs=None[, universal=None[, arch=None]]]]]]]]]]]]]])
+
+ :param configuration:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param build_file:
+ the name of the optional build file. Build files are generated
+ using the :option:`-b <sip -b>` SIP command line option.
+ :param install_dir:
+ the name of the directory where the executable program will be
+ optionally installed.
+ :param console:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param qt:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param opengl:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param python:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param threaded:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param warnings:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param debug:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param dir:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param makefile:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param installs:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param universal:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param arch:
+ see :meth:`sipconfig.Makefile.__init__`.
+
+ .. method:: build_command(source) -> string, string
+
+ This creates a single command line that will create an executable
+ program from a single source file.
+
+ :param source:
+ the name of the source file.
+ :return:
+ a tuple of the name of the executable that will be created and the
+ command line.
+
+ .. method:: finalise()
+
+ This is a reimplementation of :meth:`sipconfig.Makefile.finalise`.
+
+ .. method:: generate_macros_and_rules(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_macros_and_rules`.
+
+ .. method:: generate_target_clean(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_target_clean`.
+
+ .. method:: generate_target_default(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_target_default`.
+
+ .. method:: generate_target_install(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_target_install`.
+
+
+.. class:: PythonModuleMakefile
+
+ This class is derived from :class:`sipconfig.Makefile`.
+
+ This class encapsulates a Makefile that installs a pure Python module.
+
+ .. method:: __init__(self, configuration, dstdir[, srcdir=None[, dir=None[, makefile="Makefile"[, installs=None]]]])
+
+ :param configuration:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param dstdir:
+ the name of the directory in which the module's Python code will be
+ installed.
+ :param srcdir:
+ the name of the directory (relative to *dir*) containing the
+ module's Python code. It defaults to the same directory.
+ :param dir:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param makefile:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param installs:
+ see :meth:`sipconfig.Makefile.__init__`.
+
+ .. method:: generate_macros_and_rules(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_macros_and_rules`.
+
+ .. method:: generate_target_install(mfile)
+
+ This is a reimplementation of
+ :meth:`sipconfig.Makefile.generate_target_install`.
+
+
+.. class:: SIPModuleMakefile
+
+ This class is derived from :class:`sipconfig.ModuleMakefile`.
+
+ This class encapsulates a Makefile to build a SIP generated Python
+ extension module.
+
+ .. method:: __init__(self, configuration, build_file[, install_dir=None[, static=0[, console=0[, opengl=0[, threaded=0[, warnings=None[, debug=0[, dir=None[, makefile="Makefile"[, installs=None[, strip=1[, export_all=0[, universal=None[, arch=None[, prot_is_public=0]]]]]]]]]]]]]]])
+
+ :param configuration:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param build_file:
+ see :meth:`sipconfig.ModuleMakefile.__init__`.
+ :param install_dir:
+ see :meth:`sipconfig.ModuleMakefile.__init__`.
+ :param static:
+ see :meth:`sipconfig.ModuleMakefile.__init__`.
+ :param console:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param qt:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param opengl:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param threaded:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param warnings:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param debug:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param dir:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param makefile:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param installs:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param strip:
+ see :meth:`sipconfig.ModuleMakefile.__init__`.
+ :param export_all:
+ see :meth:`sipconfig.ModuleMakefile.__init__`.
+ :param universal:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param arch:
+ see :meth:`sipconfig.Makefile.__init__`.
+ :param prot_is_public:
+ is set if ``protected`` should be redefined as ``public`` when
+ compiling the generated module.
+
+ .. method:: finalise()
+
+ This is a reimplementation of :meth:`sipconfig.Makefile.finalise`.
diff --git a/sphinx/builtin.rst b/sphinx/builtin.rst
new file mode 100644
index 0000000..58c7019
--- /dev/null
+++ b/sphinx/builtin.rst
@@ -0,0 +1,50 @@
+.. _ref-builtin:
+
+Builtin Modules and Custom Interpreters
+=======================================
+
+Sometimes you want to create a custom Python interpreter with some modules
+built in to the interpreter itself rather than being dynamically loaded. To
+do this the module must be created as a static library and linked with a
+custom stub and the normal Python library.
+
+To build the SIP module as a static library you must pass the ``-k`` command
+line option to ``configure.py``. You should then build and install SIP as
+normal. (Note that, because the module is now a static library, you will not
+be able to import it.)
+
+To build a module you have created for your own library you must modify your
+own configuration script to pass a non-zero value as the ``static`` argument
+of the ``__init__()`` method of the :class:`sipconfig.ModuleMakefile` class (or
+any derived class you have created). Normally you would make this configurable
+using a command line option in the same way that SIP's ``configure.py`` handles
+it.
+
+The next stage is to create a custom stub and a Makefile. The SIP distribution
+contains a directory called ``custom`` which contains example stubs and a
+Python script that will create a correct Makefile. Note that, if your copy of
+SIP was part of a standard Linux distribution, the ``custom`` directory may
+not be installed on your system.
+
+The ``custom`` directory contains the following files. They are provided as
+examples - each needs to be modified according to your particular
+requirements.
+
+ - ``mkcustom.py`` is a Python script that will create a Makefile which is
+ then used to build the custom interpreter. Comments in the file describe
+ how it should be modified.
+
+ - ``custom.c`` is a stub for a custom interpreter on Linux/UNIX. It
+ should also be used for a custom console interpreter on Windows (i.e.
+ like ``python.exe``). Comments in the file describe how it should be
+ modified.
+
+ - ``customw.c`` is a stub for a custom GUI interpreter on Windows (i.e.
+ like ``pythonw.exe``). Comments in the file describe how it should be
+ modified.
+
+Note that this technique does not restrict how the interpreter can be used.
+For example, it still allows users to write their own applications that can
+import your builtin modules. If you want to prevent users from doing that,
+perhaps to protect a proprietary API, then take a look at the
+`VendorID <http://www.riverbankcomputing.com/software/vendorid/>`__ package.
diff --git a/sphinx/c_api.rst b/sphinx/c_api.rst
new file mode 100644
index 0000000..782056c
--- /dev/null
+++ b/sphinx/c_api.rst
@@ -0,0 +1,1721 @@
+.. _ref-c-api:
+
+C API for Handwritten Code
+==========================
+
+In this section we describe the API that can be used by handwritten code in
+specification files.
+
+
+.. cmacro:: SIP_API_MAJOR_NR
+
+ This is a C preprocessor symbol that defines the major number of the SIP
+ API. Its value is a number. There is no direct relationship between this
+ and the SIP version number.
+
+
+.. cmacro:: SIP_API_MINOR_NR
+
+ This is a C preprocessor symbol that defines the minor number of the SIP
+ API. Its value is a number. There is no direct relationship between this
+ and the SIP version number.
+
+
+.. cmacro:: SIP_BLOCK_THREADS
+
+ This is a C preprocessor macro that will make sure the Python Global
+ Interpreter Lock (GIL) is acquired. Python API calls must only be made
+ when the GIL has been acquired. There must be a corresponding
+ :cmacro:`SIP_UNBLOCK_THREADS` at the same lexical scope.
+
+
+.. cmacro:: SIP_NO_CONVERTORS
+
+ This is a flag used by various type convertors that suppresses the use of a
+ type's :directive:`%ConvertToTypeCode`.
+
+
+.. cmacro:: SIP_NOT_NONE
+
+ This is a flag used by various type convertors that causes the conversion
+ to fail if the Python object being converted is ``Py_None``.
+
+
+.. cmacro:: SIP_PROTECTED_IS_PUBLIC
+
+ .. versionadded:: 4.10
+
+ This is a C preprocessor macro that is set automatically by the build
+ system to specify that the generated code is being compiled with
+ ``protected`` redefined as ``public``. This allows handwritten code to
+ determine if the generated helper functions for accessing protected C++
+ functions are available (see :directive:`%MethodCode`).
+
+
+.. cmacro:: SIP_SSIZE_T
+
+ This is a C preprocessor macro that is defined as ``Py_ssize_t`` for Python
+ v2.5 and later, and as ``int`` for earlier versions of Python. It makes it
+ easier to write PEP 353 compliant handwritten code.
+
+
+.. cmacro:: SIP_UNBLOCK_THREADS
+
+ This is a C preprocessor macro that will restore the Python Global
+ Interpreter Lock (GIL) to the state it was prior to the corresponding
+ :cmacro:`SIP_BLOCK_THREADS`.
+
+
+.. cmacro:: SIP_VERSION
+
+ This is a C preprocessor symbol that defines the SIP version number
+ represented as a 3 part hexadecimal number (e.g. v4.0.0 is represented as
+ ``0x040000``).
+
+
+.. cmacro:: SIP_VERSION_STR
+
+ This is a C preprocessor symbol that defines the SIP version number
+ represented as a string. For development snapshots it will start with
+ ``snapshot-``.
+
+
+.. cfunction:: sipErrorState sipBadCallableArg(int arg_nr, PyObject *arg)
+
+ .. versionadded:: 4.10
+
+ This is called from :directive:`%MethodCode` to raise a Python exception
+ when an argument to a function, a C++ constructor or method is found to
+ have an unexpected type. This should be used when the
+ :directive:`%MethodCode` does additional type checking of the supplied
+ arguments.
+
+ :param arg_nr:
+ the number of the argument. Arguments are numbered from 0 but are
+ numbered from 1 in the detail of the exception.
+ :param arg:
+ the argument.
+ :return:
+ the value that should be assigned to ``sipError``.
+
+
+.. cfunction:: void sipBadCatcherResult(PyObject *method)
+
+ This raises a Python exception when the result of a Python reimplementation
+ of a C++ method doesn't have the expected type. It is normally called by
+ handwritten code specified with the :directive:`%VirtualCatcherCode`
+ directive.
+
+ :param method:
+ the Python method and would normally be the supplied ``sipMethod``.
+
+
+.. cfunction:: void sipBadLengthForSlice(SIP_SSIZE_T seqlen, SIP_SSIZE_T slicelen)
+
+ This raises a Python exception when the length of a slice object is
+ inappropriate for a sequence-like object. It is normally called by
+ handwritten code specified for :meth:`__setitem__` methods.
+
+ :param seqlen:
+ the length of the sequence.
+ :param slicelen:
+ the length of the slice.
+
+
+.. cfunction:: PyObject *sipBuildResult(int *iserr, const char *format, ...)
+
+ This creates a Python object based on a format string and associated
+ values in a similar way to the Python :cfunc:`Py_BuildValue()` function.
+
+ :param iserr:
+ if this is not ``NULL`` then the location it points to is set to a
+ non-zero value.
+ :param format:
+ the string of format characters.
+ :return:
+ If there was an error then ``NULL`` is returned and a Python exception
+ is raised.
+
+ If the format string begins and ends with parentheses then a tuple of
+ objects is created. If it contains more than one format character then
+ parentheses must be specified.
+
+ In the following description the first letter is the format character, the
+ entry in parentheses is the Python object type that the format character
+ will create, and the entry in brackets are the types of the C/C++ values
+ to be passed.
+
+ ``a`` (string) [char]
+ Convert a C/C++ ``char`` to a Python v2 or v3 string object.
+
+ ``b`` (boolean) [int]
+ Convert a C/C++ ``int`` to a Python boolean.
+
+ ``c`` (string/bytes) [char]
+ Convert a C/C++ ``char`` to a Python v2 string object or a Python v3
+ bytes object.
+
+ ``d`` (float) [double]
+ Convert a C/C++ ``double`` to a Python floating point number.
+
+ ``e`` (integer) [enum]
+ Convert an anonymous C/C++ ``enum`` to a Python integer.
+
+ ``f`` (float) [float]
+ Convert a C/C++ ``float`` to a Python floating point number.
+
+ ``g`` (string/bytes) [char \*, :cmacro:`SIP_SSIZE_T`]
+ Convert a C/C++ character array and its length to a Python v2 string
+ object or a Python v3 bytes object. If the array is ``NULL`` then the
+ length is ignored and the result is ``Py_None``.
+
+ ``h`` (integer) [short]
+ Convert a C/C++ ``short`` to a Python integer.
+
+ ``i`` (integer) [int]
+ Convert a C/C++ ``int`` to a Python integer.
+
+ ``l`` (long) [long]
+ Convert a C/C++ ``long`` to a Python integer.
+
+ ``m`` (long) [unsigned long]
+ Convert a C/C++ ``unsigned long`` to a Python long.
+
+ ``n`` (long) [long long]
+ Convert a C/C++ ``long long`` to a Python long.
+
+ ``o`` (long) [unsigned long long]
+ Convert a C/C++ ``unsigned long long`` to a Python long.
+
+ ``r`` (wrapped instance) [*type* \*, :cmacro:`SIP_SSIZE_T`, const :ctype:`sipTypeDef` \*]
+ Convert an array of C structures, C++ classes or mapped type instances
+ to a Python tuple. Note that copies of the array elements are made.
+
+ ``s`` (string/bytes) [char \*]
+ Convert a C/C++ ``'\0'`` terminated string to a Python v2 string object
+ or a Python v3 bytes object. If the string pointer is ``NULL`` then
+ the result is ``Py_None``.
+
+ ``t`` (long) [unsigned short]
+ Convert a C/C++ ``unsigned short`` to a Python long.
+
+ ``u`` (long) [unsigned int]
+ Convert a C/C++ ``unsigned int`` to a Python long.
+
+ ``w`` (unicode/string) [wchar_t]
+ Convert a C/C++ wide character to a Python v2 unicode object or a
+ Python v3 string object.
+
+ ``x`` (unicode/string) [wchar_t \*]
+ Convert a C/C++ ``L'\0'`` terminated wide character string to a Python
+ v2 unicode object or a Python v3 string object. If the string pointer
+ is ``NULL`` then the result is ``Py_None``.
+
+ ``A`` (string) [char \*]
+ Convert a C/C++ ``'\0'`` terminated string to a Python v2 or v3 string
+ object. If the string pointer is ``NULL`` then the result is
+ ``Py_None``.
+
+ ``B`` (wrapped instance) [*type* \*, :ctype:`sipWrapperType` \*, PyObject \*]
+ Convert a new C structure or a new C++ class instance to a Python class
+ instance object. Ownership of the structure or instance is determined
+ by the ``PyObject *`` argument. If it is ``NULL`` and the instance has
+ already been wrapped then the ownership is unchanged. If it is
+ ``NULL`` or ``Py_None`` then ownership will be with Python. Otherwise
+ ownership will be with C/C++ and the instance associated with the
+ ``PyObject *`` argument. The Python class is influenced by any
+ applicable :directive:`%ConvertToSubClassCode` code.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use ``N``.
+
+ ``C`` (wrapped instance) [*type* \*, :ctype:`sipWrapperType` \*, PyObject \*]
+ Convert a C structure or a C++ class instance to a Python class
+ instance object. If the structure or class instance has already been
+ wrapped then the result is a new reference to the existing class
+ instance object. Ownership of the structure or instance is determined
+ by the ``PyObject *`` argument. If it is ``NULL`` and the instance has
+ already been wrapped then the ownership is unchanged. If it is
+ ``NULL`` and the instance is newly wrapped then ownership will be with
+ C/C++. If it is ``Py_None`` then ownership is transferred to Python
+ via a call to :cfunc:`sipTransferBack()`. Otherwise ownership is
+ transferred to C/C++ and the instance associated with the
+ ``PyObject *`` argument via a call to :cfunc:`sipTransferTo()`. The
+ Python class is influenced by any applicable
+ :directive:`%ConvertToSubClassCode` code.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use ``D``.
+
+ ``D`` (wrapped instance) [*type* \*, const :ctype:`sipTypeDef` \*, PyObject \*]
+ Convert a C structure, C++ class or mapped type instance to a Python
+ object. If the instance has already been wrapped then the result is a
+ new reference to the existing object. Ownership of the instance is
+ determined by the ``PyObject *`` argument. If it is ``NULL`` and the
+ instance has already been wrapped then the ownership is unchanged. If
+ it is ``NULL`` and the instance is newly wrapped then ownership will be
+ with C/C++. If it is ``Py_None`` then ownership is transferred to
+ Python via a call to :cfunc:`sipTransferBack()`. Otherwise ownership
+ is transferred to C/C++ and the instance associated with the
+ ``PyObject *`` argument via a call to :cfunc:`sipTransferTo()`. The
+ Python class is influenced by any applicable
+ :directive:`%ConvertToSubClassCode` code.
+
+ ``E`` (wrapped enum) [enum, PyTypeObject \*]
+ Convert a named C/C++ ``enum`` to an instance of the corresponding
+ Python named enum type.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use ``F``.
+
+ ``F`` (wrapped enum) [enum, :ctype:`sipTypeDef` \*]
+ Convert a named C/C++ ``enum`` to an instance of the corresponding
+ Python named enum type.
+
+ ``G`` (unicode) [wchar_t \*, :cmacro:`SIP_SSIZE_T`]
+ Convert a C/C++ wide character array and its length to a Python unicode
+ object. If the array is ``NULL`` then the length is ignored and the
+ result is ``Py_None``.
+
+ ``N`` (wrapped instance) [*type* \*, :ctype:`sipTypeDef` \*, PyObject \*]
+ Convert a new C structure, C++ class or mapped type instance to a
+ Python object. Ownership of the instance is determined by the
+ ``PyObject *`` argument. If it is ``NULL`` and the instance has
+ already been wrapped then the ownership is unchanged. If it is
+ ``NULL`` or ``Py_None`` then ownership will be with Python. Otherwise
+ ownership will be with C/C++ and the instance associated with the
+ ``PyObject *`` argument. The Python class is influenced by any
+ applicable :directive:`%ConvertToSubClassCode` code.
+
+ ``R`` (object) [PyObject \*]
+ The result is value passed without any conversions. The reference
+ count is unaffected, i.e. a reference is taken.
+
+ ``S`` (object) [PyObject \*]
+ The result is value passed without any conversions. The reference
+ count is incremented.
+
+ ``V`` (sip.voidptr) [void \*]
+ Convert a C/C++ ``void *`` Python :class:`sip.voidptr` object.
+
+
+.. cfunction:: PyObject *sipCallMethod(int *iserr, PyObject *method, const char *format, ...)
+
+ This calls a Python method passing a tuple of arguments based on a format
+ string and associated values in a similar way to the Python
+ :cfunc:`PyObject_CallObject()` function.
+
+ :param iserr:
+ if this is not ``NULL`` then the location it points to is set to a
+ non-zero value if there was an error.
+ :param method:
+ the Python bound method to call.
+ :param format:
+ the string of format characters (see :cfunc:`sipBuildResult()`).
+ :return:
+ If there was an error then ``NULL`` is returned and a Python exception
+ is raised.
+
+ It is normally called by handwritten code specified with the
+ :directive:`%VirtualCatcherCode` directive with method being the supplied
+ ``sipMethod``.
+
+
+.. cfunction:: int sipCanConvertToEnum(PyObject *obj, const sipTypeDef *td)
+
+ This checks if a Python object can be converted to a named enum.
+
+ :param obj:
+ the Python object.
+ :param td:
+ the enum's :ref:`generated type structure <ref-type-structures>`.
+ :return:
+ a non-zero value if the object can be converted.
+
+
+.. cfunction:: int sipCanConvertToInstance(PyObject *obj, sipWrapperType *type, int flags)
+
+ This checks if a Python object can be converted to an instance of a C
+ structure or C++ class.
+
+ :param obj:
+ the Python object.
+ :param type:
+ the C/C++ type's :ref:`generated type object <ref-type-objects>`.
+ :param flags:
+ any combination of the :cmacro:`SIP_NOT_NONE` and
+ :cmacro:`SIP_NO_CONVERTORS` flags.
+ :return:
+ a non-zero value if the object can be converted.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipCanConvertToType()`.
+
+
+.. cfunction:: int sipCanConvertToMappedType(PyObject *obj, const sipMappedType *mt, int flags)
+
+ This checks if a Python object can be converted to an instance of a C
+ structure or C++ class which has been implemented as a mapped type.
+
+ :param obj:
+ the Python object.
+ :param mt:
+ the opaque structure returned by :cfunc:`sipFindMappedType()`.
+ :param flags:
+ this may be the :cmacro:`SIP_NOT_NONE` flag.
+ :return:
+ a non-zero value if the object can be converted.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipCanConvertToType()`.
+
+
+.. cfunction:: int sipCanConvertToType(PyObject *obj, const sipTypeDef *td, int flags)
+
+ This checks if a Python object can be converted to an instance of a C
+ structure, C++ class or mapped type.
+
+ :param obj:
+ the Python object.
+ :param td:
+ the C/C++ type's :ref:`generated type structure <ref-type-structures>`.
+ :param flags:
+ any combination of the :cmacro:`SIP_NOT_NONE` and
+ :cmacro:`SIP_NO_CONVERTORS` flags.
+ :return:
+ a non-zero value if the object can be converted.
+
+
+.. cfunction:: PyObject *sipClassName(PyObject *obj)
+
+ This gets the class name of a wrapped instance as a Python string. It
+ comes with a reference.
+
+ :param obj:
+ the wrapped instance.
+ :return:
+ the name of the instance's class.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use the
+ following::
+
+ PyString_FromString(obj->ob_type->tp_name)
+
+
+.. cfunction:: PyObject *sipConvertFromConstVoidPtr(const void *cpp)
+
+ This creates a :class:`sip.voidptr` object for a memory address. The
+ object will not be writeable and has no associated size.
+
+ :param cpp:
+ the memory address.
+ :return:
+ the :class:`sip.voidptr` object.
+
+
+.. cfunction:: PyObject *sipConvertFromConstVoidPtrAndSize(const void *cpp, SIP_SSIZE_T size)
+
+ This creates a :class:`sip.voidptr` object for a memory address. The
+ object will not be writeable and can be used as an immutable buffer object.
+
+ :param cpp:
+ the memory address.
+ :param size:
+ the size associated with the address.
+ :return:
+ the :class:`sip.voidptr` object.
+
+
+.. cfunction:: PyObject *sipConvertFromEnum(int eval, const sipTypeDef *td)
+
+ This converts a named C/C++ ``enum`` to an instance of the corresponding
+ generated Python type.
+
+ :param eval:
+ the enumerated value to convert.
+ :param td:
+ the enum's :ref:`generated type structure <ref-type-structures>`.
+ :return:
+ the Python object.
+
+
+.. cfunction:: PyObject *sipConvertFromInstance(void *cpp, sipWrapperType *type, PyObject *transferObj)
+
+ This converts a C structure or a C++ class instance to an instance of the
+ corresponding generated Python type.
+
+ :param cpp:
+ the C/C++ instance.
+ :param type:
+ the type's :ref:`generated type object <ref-type-objects>`.
+ :param transferObj:
+ this controls the ownership of the returned value.
+ :return:
+ the Python object.
+
+ If the C/C++ instance has already been wrapped then the result is a
+ new reference to the existing class instance object.
+
+ If *transferObj* is ``NULL`` and the instance has already been wrapped then
+ the ownership is unchanged.
+
+ If *transferObj* is ``NULL`` and the instance is newly wrapped then
+ ownership will be with C/C++.
+
+ If *transferObj* is ``Py_None`` then ownership is transferred to Python via
+ a call to :cfunc:`sipTransferBack()`.
+
+ Otherwise ownership is transferred to C/C++ and the instance associated
+ with *transferObj* via a call to :cfunc:`sipTransferTo()`.
+
+ The Python type is influenced by any applicable
+ :directive:`%ConvertToSubClassCode` code.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipConvertFromType()`.
+
+
+.. cfunction:: PyObject *sipConvertFromMappedType(void *cpp, const sipMappedType *mt, PyObject *transferObj)
+
+ This converts a C structure or a C++ class instance wrapped as a mapped
+ type to an instance of the corresponding generated Python type.
+
+ :param cpp:
+ the C/C++ instance.
+ :param mt:
+ the opaque structure returned by :cfunc:`sipFindMappedType()`.
+ :param transferObj:
+ this controls the ownership of the returned value.
+ :return:
+ the Python object.
+
+ If *transferObj* is ``NULL`` then the ownership is unchanged.
+
+ If *transferObj* is ``Py_None`` then ownership is transferred to Python
+ via a call to :cfunc:`sipTransferBack()`.
+
+ Otherwise ownership is transferred to C/C++ and the instance associated
+ with *transferObj* argument via a call to :cfunc:`sipTransferTo()`.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipConvertFromType()`.
+
+
+.. cfunction:: PyObject *sipConvertFromNamedEnum(int eval, PyTypeObject *type)
+
+ This converts a named C/C++ ``enum`` to an instance of the corresponding
+ generated Python type.
+
+ :param eval:
+ the enumerated value to convert.
+ :param type:
+ the enum's :ref:`generated type object <ref-type-objects>`.
+ :return:
+ the Python object.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipConvertFromEnum()`.
+
+
+.. cfunction:: PyObject *sipConvertFromNewInstance(void *cpp, sipWrapperType *type, PyObject *transferObj)
+
+ This converts a new C structure or a C++ class instance to an instance of
+ the corresponding generated Python type.
+
+ :param cpp:
+ the C/C++ instance.
+ :param type:
+ the type's :ref:`generated type object <ref-type-objects>`.
+ :param transferObj:
+ this controls the ownership of the returned value.
+ :return:
+ the Python object.
+
+ If *transferObj* is ``NULL`` or ``Py_None`` then ownership will be with
+ Python.
+
+ Otherwise ownership will be with C/C++ and the instance associated with
+ *transferObj*.
+
+ The Python type is influenced by any applicable
+ :directive:`%ConvertToSubClassCode` code.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipConvertFromNewType()`.
+
+
+.. cfunction:: PyObject *sipConvertFromNewType(void *cpp, const sipTypeDef *td, PyObject *transferObj)
+
+ This converts a new C structure or a C++ class instance to an instance of
+ the corresponding generated Python type.
+
+ :param cpp:
+ the C/C++ instance.
+ :param td:
+ the type's :ref:`generated type structure <ref-type-structures>`.
+ :param transferObj:
+ this controls the ownership of the returned value.
+ :return:
+ the Python object.
+
+ If *transferObj* is ``NULL`` or ``Py_None`` then ownership will be with
+ Python.
+
+ Otherwise ownership will be with C/C++ and the instance associated with
+ *transferObj*.
+
+ The Python type is influenced by any applicable
+ :directive:`%ConvertToSubClassCode` code.
+
+
+.. cfunction:: SIP_SSIZE_T sipConvertFromSequenceIndex(SIP_SSIZE_T idx, SIP_SSIZE_T len)
+
+ This converts a Python sequence index (i.e. where a negative value refers
+ to the offset from the end of the sequence) to a C/C++ array index. If the
+ index was out of range then a negative value is returned and a Python
+ exception raised.
+
+ :param idx:
+ the sequence index.
+ :param len:
+ the length of the sequence.
+ :return:
+ the unsigned array index.
+
+
+.. cfunction:: int sipConvertFromSliceObject(PyObject *slice, SIP_SSIZE_T length, SIP_SSIZE_T *start, SIP_SSIZE_T *stop, SIP_SSIZE_T *step, SIP_SSIZE_T *slicelength)
+
+ This is a thin wrapper around the Python :cfunc:`PySlice_GetIndicesEx()`
+ function provided to make it easier to write handwritten code that is
+ compatible with SIP v3.x and versions of Python earlier that v2.3.
+
+
+.. cfunction:: PyObject *sipConvertFromType(void *cpp, const sipTypeDef *td, PyObject *transferObj)
+
+ This converts a C structure or a C++ class instance to an instance of the
+ corresponding generated Python type.
+
+ :param cpp:
+ the C/C++ instance.
+ :param td:
+ the type's :ref:`generated type structure <ref-type-structures>`.
+ :param transferObj:
+ this controls the ownership of the returned value.
+ :return:
+ the Python object.
+
+ If the C/C++ instance has already been wrapped then the result is a new
+ reference to the existing object.
+
+ If *transferObj* is ``NULL`` and the instance has already been wrapped then
+ the ownership is unchanged.
+
+ If *transferObj* is ``NULL`` and the instance is newly wrapped then
+ ownership will be with C/C++.
+
+ If *transferObj* is ``Py_None`` then ownership is transferred to Python via
+ a call to :cfunc:`sipTransferBack()`.
+
+ Otherwise ownership is transferred to C/C++ and the instance associated
+ with *transferObj* via a call to :cfunc:`sipTransferTo()`.
+
+ The Python class is influenced by any applicable
+ :directive:`%ConvertToSubClassCode` code.
+
+
+.. cfunction:: PyObject *sipConvertFromVoidPtr(void *cpp)
+
+ This creates a :class:`sip.voidptr` object for a memory address. The
+ object will be writeable but has no associated size.
+
+ :param cpp:
+ the memory address.
+ :return:
+ the :class:`sip.voidptr` object.
+
+
+.. cfunction:: PyObject *sipConvertFromVoidPtrAndSize(void *cpp, SIP_SSIZE_T size)
+
+ This creates a :class:`sip.voidptr` object for a memory address. The
+ object will be writeable and can be used as a mutable buffer object.
+
+ :param cpp:
+ the memory address.
+ :param size:
+ the size associated with the address.
+ :return:
+ the :class:`sip.voidptr` object.
+
+
+.. cfunction:: void *sipConvertToInstance(PyObject *obj, sipWrapperType *type, PyObject *transferObj, int flags, int *state, int *iserr)
+
+ This converts a Python object to an instance of a C structure or C++ class
+ assuming that a previous call to :cfunc:`sipCanConvertToInstance()` has
+ been successful.
+
+ :param obj:
+ the Python object.
+ :param type:
+ the type's :ref:`generated type object <ref-type-objects>`.
+ :param transferObj:
+ this controls any ownership changes to *obj*.
+ :param flags:
+ any combination of the :cmacro:`SIP_NOT_NONE` and
+ :cmacro:`SIP_NO_CONVERTORS` flags.
+ :param state:
+ the state of the returned C/C++ instance is returned via this pointer.
+ :param iserr:
+ the error flag is passed and updated via this pointer.
+ :return:
+ the C/C++ instance.
+
+ If *transferObj* is ``NULL`` then the ownership is unchanged.
+
+ If *transferObj* is ``Py_None`` then ownership is transferred to Python via
+ a call to :cfunc:`sipTransferBack()`.
+
+ Otherwise ownership is transferred to C/C++ and *obj* associated with
+ *transferObj* via a call to :cfunc:`sipTransferTo()`.
+
+ If *state* is not ``NULL`` then the location it points to is set to
+ describe the state of the returned C/C++ instance and is the value returned
+ by any :directive:`%ConvertToTypeCode`. The calling code must then release
+ the value at some point to prevent a memory leak by calling
+ :cfunc:`sipReleaseInstance()`.
+
+ If there is an error then the location *iserr* points to is set to a
+ non-zero value. If it was initially a non-zero value then the conversion
+ isn't attempted in the first place. (This allows several calls to be made
+ that share the same error flag so that it only needs to be tested once
+ rather than after each call.)
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipConvertToType()`.
+
+
+.. cfunction:: void *sipConvertToMappedType(PyObject *obj, const sipMappedType *mt, PyObject *transferObj, int flags, int *state, int *iserr)
+
+ This converts a Python object to an instance of a C structure or C++
+ class that is implemented as a mapped type assuming that a previous call to
+ :cfunc:`sipCanConvertToMappedType()` has been successful.
+
+ :param obj:
+ the Python object.
+ :param mt:
+ the opaque structure returned by :cfunc:`sipFindMappedType()`.
+ :param transferObj:
+ this controls any ownership changes to *obj*.
+ :param flags:
+ this may be the :cmacro:`SIP_NOT_NONE` flag.
+ :param state:
+ the state of the returned C/C++ instance is returned via this pointer.
+ :param iserr:
+ the error flag is passed and updated via this pointer.
+ :return:
+ the C/C++ instance.
+
+ If *transferObj* is ``NULL`` then the ownership is unchanged.
+
+ If *transferObj* is ``Py_None`` then ownership is transferred to Python via
+ a call to :cfunc:`sipTransferBack()`.
+
+ Otherwise ownership is transferred to C/C++ and *obj* associated with
+ *transferObj* via a call to :cfunc:`sipTransferTo()`.
+
+ If *state* is not ``NULL`` then the location it points to is set to
+ describe the state of the returned C/C++ instance and is the value returned
+ by any :directive:`%ConvertToTypeCode`. The calling code must then release
+ the value at some point to prevent a memory leak by calling
+ :cfunc:`sipReleaseMappedType()`.
+
+ If there is an error then the location *iserr* points to is set to a
+ non-zero value. If it was initially a non-zero value then the conversion
+ isn't attempted in the first place. (This allows several calls to be made
+ that share the same error flag so that it only needs to be tested once
+ rather than after each call.)
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipConvertToType()`
+
+
+.. cfunction:: void *sipConvertToType(PyObject *obj, const sipTypeDef *td, PyObject *transferObj, int flags, int *state, int *iserr)
+
+ This converts a Python object to an instance of a C structure, C++ class or
+ mapped type assuming that a previous call to :cfunc:`sipCanConvertToType()`
+ has been successful.
+
+ :param obj:
+ the Python object.
+ :param td:
+ the type's :ref:`generated type structure <ref-type-structures>`.
+ :param transferObj:
+ this controls any ownership changes to *obj*.
+ :param flags:
+ any combination of the :cmacro:`SIP_NOT_NONE` and
+ :cmacro:`SIP_NO_CONVERTORS` flags.
+ :param state:
+ the state of the returned C/C++ instance is returned via this pointer.
+ :param iserr:
+ the error flag is passed and updated via this pointer.
+ :return:
+ the C/C++ instance.
+
+ If *transferObj* is ``NULL`` then the ownership is unchanged. If it is
+ ``Py_None`` then ownership is transferred to Python via a call to
+ :cfunc:`sipTransferBack()`.
+
+ Otherwise ownership is transferred to C/C++ and *obj* associated with
+ *transferObj* via a call to :cfunc:`sipTransferTo()`.
+
+ If *state* is not ``NULL`` then the location it points to is set to
+ describe the state of the returned C/C++ instance and is the value returned
+ by any :directive:`%ConvertToTypeCode`. The calling code must then release
+ the value at some point to prevent a memory leak by calling
+ :cfunc:`sipReleaseType()`.
+
+ If there is an error then the location *iserr* points to is set to a
+ non-zero value. If it was initially a non-zero value then the conversion
+ isn't attempted in the first place. (This allows several calls to be made
+ that share the same error flag so that it only needs to be tested once
+ rather than after each call.)
+
+
+.. cfunction:: void *sipConvertToVoidPtr(PyObject *obj)
+
+ This converts a Python object to a memory address.
+ :cfunc:`PyErr_Occurred()` must be used to determine if the conversion was
+ successful.
+
+ :param obj:
+ the Python object which may be ``Py_None``, a :class:`sip.voidptr` or a
+ :ctype:`PyCObject`.
+ :return:
+ the memory address.
+
+
+.. cfunction:: int sipExportSymbol(const char *name, void *sym)
+
+ Python does not allow extension modules to directly access symbols in
+ another extension module. This exports a symbol, referenced by a name,
+ that can subsequently be imported, using :cfunc:`sipImportSymbol()`, by
+ another module.
+
+ :param name:
+ the name of the symbol.
+ :param sym:
+ the value of the symbol.
+ :return:
+ 0 if there was no error. A negative value is returned if *name* is
+ already associated with a symbol or there was some other error.
+
+
+.. cfunction:: sipWrapperType *sipFindClass(const char *type)
+
+ This returns a pointer to the :ref:`generated type object
+ <ref-type-objects` corresponding to a C/C++ type.
+
+ :param type:
+ the C/C++ declaration of the type.
+ :return:
+ the generated type object. This will not change and may be saved in a
+ static cache. ``NULL`` is returned if the C/C++ type doesn't exist.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipFindType()`.
+
+
+.. cfunction:: const sipMappedType *sipFindMappedType(const char *type)
+
+ This returns a pointer to an opaque structure describing a mapped type.
+
+ :param type:
+ the C/C++ declaration of the type.
+ :return:
+ the opaque structure. This will not change and may be saved in a
+ static cache. ``NULL`` is returned if the C/C++ type doesn't exist.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipFindType()`.
+
+
+.. cfunction:: PyTypeObject *sipFindNamedEnum(const char *type)
+
+ This returns a pointer to the :ref:`generated Python type object
+ <ref-enum-type-objects>` corresponding to a named C/C++ enum.
+
+ :param type:
+ the C/C++ declaration of the enum.
+ :return:
+ the generated Python type object. This will not change and may be
+ saved in a static cache. ``NULL`` is returned if the C/C++ enum
+ doesn't exist.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipFindType()`.
+
+
+.. cfunction:: const sipTypeDef *sipFindType(const char *type)
+
+ This returns a pointer to the :ref:`generated type structure
+ <ref-type-structures>` corresponding to a C/C++ type.
+
+ :param type:
+ the C/C++ declaration of the type.
+ :return:
+ the generated type structure. This will not change and may be saved in
+ a static cache. ``NULL`` is returned if the C/C++ type doesn't exist.
+
+
+.. cfunction:: void *sipForceConvertToInstance(PyObject *obj, sipWrapperType *type, PyObject *transferObj, int flags, int *state, int *iserr)
+
+ This converts a Python object to an instance of a C structure or C++ class
+ by calling :cfunc:`sipCanConvertToInstance()` and, if it is successfull,
+ calling :cfunc:`sipConvertToInstance()`.
+
+ See :cfunc:`sipConvertToInstance()` for a full description of the
+ arguments.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipForceConvertToType()`.
+
+
+.. cfunction:: void *sipForceConvertToMappedType(PyObject *obj, const sipMappedType *mt, PyObject *transferObj, int flags, int *state, int *iserr)
+
+ This converts a Python object to an instance of a C structure or C++ class
+ which has been implemented as a mapped type by calling
+ :cfunc:`sipCanConvertToMappedType()` and, if it is successfull, calling
+ :cfunc:`sipConvertToMappedType()`.
+
+ See :cfunc:`sipConvertToMappedType()` for a full description of the
+ arguments.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipForceConvertToType()`.
+
+
+.. cfunction:: void *sipForceConvertToType(PyObject *obj, const sipTypeDef *td, PyObject *transferObj, int flags, int *state, int *iserr)
+
+ This converts a Python object to an instance of a C structure, C++ class or
+ mapped type by calling :cfunc:`sipCanConvertToType()` and, if it is
+ successfull, calling :cfunc:`sipConvertToType()`.
+
+ See :cfunc:`sipConvertToType()` for a full description of the arguments.
+
+
+.. cfunction:: void sipFree(void *mem)
+
+ This returns an area of memory allocated by :cfunc:`sipMalloc()` to the
+ heap.
+
+ :param mem:
+ the memory address.
+
+
+.. cfunction:: PyObject *sipGetPyObject(void *cppptr, const sipTypeDef *td)
+
+ This returns a borrowed reference to the Python object for a C structure or
+ C++ class instance.
+
+ :param cppptr:
+ the pointer to the C/C++ instance.
+ :param td:
+ the :ref:`generated type structure <ref-type-structures>` corresponding
+ to the C/C++ type.
+ :return:
+ the Python object or ``NULL`` (and no exception is raised) if the
+ C/C++ instance hasn't been wrapped.
+
+
+.. cfunction:: int sipGetState(PyObject *transferObj)
+
+ The :directive:`%ConvertToTypeCode` directive requires that the provided
+ code returns an ``int`` describing the state of the converted value. The
+ state usually depends on any transfers of ownership that have been
+ requested. This is a convenience function that returns the correct state
+ when the converted value is a temporary.
+
+ :param transferObj:
+ the object that describes the requested transfer of ownership.
+ :return:
+ the state of the converted value.
+
+
+.. cfunction:: PyObject *sipGetWrapper(void *cppptr, sipWrapperType *type)
+
+ This returns a borrowed reference to the wrapped instance object for a C
+ structure or C++ class instance.
+
+ :param cppptr:
+ the pointer to the C/C++ instance.
+ :param type:
+ the :ref:`generated type object <ref-type-objects>` corresponding to
+ the C/C++ type.
+ :return:
+ the Python object or ``NULL`` (and no exception is raised) if the
+ C/C++ instance hasn't been wrapped.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipGetPyObject()`.
+
+
+.. cfunction:: void *sipImportSymbol(const char *name)
+
+ Python does not allow extension modules to directly access symbols in
+ another extension module. This imports a symbol, referenced by a name,
+ that has previously been exported, using :cfunc:`sipExportSymbol()`, by
+ another module.
+
+ :param name:
+ the name of the symbol.
+ :return:
+ the value of the symbol. ``NULL`` is returned if there is no such
+ symbol.
+
+
+.. ctype:: sipIntTypeClassMap
+
+ This C structure is used with :cfunc:`sipMapIntToClass()` to define a
+ mapping between integer based RTTI and :ref:`generated type objects
+ <ref-type-objects>`. The structure elements are as follows.
+
+ .. cmember:: int typeInt
+
+ The integer RTTI.
+
+ .. cmember:: sipWrapperType **pyType.
+
+ A pointer to the corresponding generated type object.
+
+ .. note::
+ This is deprecated from SIP v4.8.
+
+
+.. cfunction:: int sipIsAPIEnabled(const char *name, int from, int to)
+
+ .. versionadded:: 4.9
+
+ This checks to see if the current version number of an API falls within a
+ given range. See :ref:`ref-incompat-apis` for more detail.
+
+ :param name:
+ the name of the API.
+ :param from:
+ the lower bound of the range. For the API to be enabled its version
+ number must be greater than or equal to *from*. If *from* is 0 then
+ this check isn't made.
+ :param to:
+ the upper bound of the range. For the API to be enabled its version
+ number must be less than *to*. If *to* is 0 then this check isn't
+ made.
+ :return:
+ a non-zero value if the API is enabled.
+
+
+.. cfunction:: unsigned long sipLong_AsUnsignedLong(PyObject *obj)
+
+ This function is a thin wrapper around :cfunc:`PyLong_AsUnsignedLong()`
+ that works around a bug in Python v2.3.x and earlier when converting
+ integer objects.
+
+
+.. cfunction:: void *sipMalloc(size_t nbytes)
+
+ This allocates an area of memory on the heap using the Python
+ :cfunc:`PyMem_Malloc()` function. The memory is freed by calling
+ :cfunc:`sipFree()`.
+
+ :param nbytes:
+ the number of bytes to allocate.
+ :return:
+ the memory address. If there was an error then ``NULL`` is returned
+ and a Python exception raised.
+
+
+.. cfunction:: sipWrapperType *sipMapIntToClass(int type, const sipIntTypeClassMap *map, int maplen)
+
+ This can be used in :directive:`%ConvertToSubClassCode` code as a
+ convenient way of converting integer based RTTI to the corresponding
+ :ref:`generated type object <ref-type-objects>`.
+
+ :param type:
+ the integer RTTI.
+ :param map:
+ the table of known RTTI and the corresponding type objects (see
+ :ctype:`sipIntTypeClassMap`). The entries in the table must be sorted
+ in ascending order of RTTI.
+ :param maplen:
+ the number of entries in the table.
+ :return:
+ the corresponding type object, or ``NULL`` if *type* wasn't in *map*.
+
+ .. note::
+ This is deprecated from SIP v4.8.
+
+
+.. cfunction:: sipWrapperType *sipMapStringToClass(char *type, const sipStringTypeClassMap *map, int maplen)
+
+ This can be used in :directive:`%ConvertToSubClassCode` code as a
+ convenient way of converting ``'\0'`` terminated string based RTTI to the
+ corresponding :ref:`generated type object <ref-type-objects>`.
+
+ :param type:
+ the string RTTI.
+ :param map:
+ the table of known RTTI and the corresponding type objects (see
+ :ctype:`sipStringTypeClassMap`). The entries in the table must be
+ sorted in ascending order of RTTI.
+ :param maplen:
+ the number of entries in the table.
+ :return:
+ the corresponding type object, or ``NULL`` if *type* wasn't in *map*.
+
+ .. note::
+ This is deprecated from SIP v4.8.
+
+
+.. cfunction:: int sipParseResult(int *iserr, PyObject *method, PyObject *result, const char *format, ...)
+
+ This converts a Python object (usually returned by a method) to C/C++ based
+ on a format string and associated values in a similar way to the Python
+ :cfunc:`PyArg_ParseTuple()` function.
+
+ :param iserr:
+ if this is not ``NULL`` then the location it points to is set to a
+ non-zero value if there was an error.
+ :param method:
+ the Python method that returned *result*.
+ :param result:
+ the Python object returned by *method*.
+ :param format:
+ the format string.
+ :return:
+ 0 if there was no error. Otherwise a negative value is returned, and
+ an exception raised.
+
+ This is normally called by handwritten code specified with the
+ :directive:`%VirtualCatcherCode` directive with *method* being the supplied
+ ``sipMethod`` and *result* being the value returned by
+ :cfunc:`sipCallMethod()`.
+
+ If *format* begins and ends with parentheses then *result* must be a Python
+ tuple and the rest of *format* is applied to the tuple contents.
+
+ In the following description the first letter is the format character, the
+ entry in parentheses is the Python object type that the format character
+ will convert, and the entry in brackets are the types of the C/C++ values
+ to be passed.
+
+ ``ae`` (object) [char \*]
+ Convert a Python string-like object of length 1 to a C/C++ ``char``
+ according to the encoding ``e``. ``e`` can either be ``A`` for ASCII,
+ ``L`` for Latin-1, or ``8`` for UTF-8. For Python v2 the object may be
+ either a string or a unicode object that can be encoded. For Python v3
+ the object may either be a bytes object or a string object that can be
+ encoded. An object that supports the buffer protocol may also be used.
+
+ ``b`` (integer) [bool \*]
+ Convert a Python integer to a C/C++ ``bool``.
+
+ ``c`` (string/bytes) [char \*]
+ Convert a Python v2 string object or a Python v3 bytes object of length
+ 1 to a C/C++ ``char``.
+
+ ``d`` (float) [double \*]
+ Convert a Python floating point number to a C/C++ ``double``.
+
+ ``e`` (integer) [enum \*]
+ Convert a Python integer to an anonymous C/C++ ``enum``.
+
+ ``f`` (float) [float \*]
+ Convert a Python floating point number to a C/C++ ``float``.
+
+ ``g`` (string/bytes) [const char \*\*, :cmacro:`SIP_SSIZE_T` \*]
+ Convert a Python v2 string object or a Python v3 bytes object to a
+ C/C++ character array and its length. If the Python object is
+ ``Py_None`` then the array and length are ``NULL`` and zero
+ respectively.
+
+ ``h`` (integer) [short \*]
+ Convert a Python integer to a C/C++ ``short``.
+
+ ``i`` (integer) [int \*]
+ Convert a Python integer to a C/C++ ``int``.
+
+ ``l`` (long) [long \*]
+ Convert a Python long to a C/C++ ``long``.
+
+ ``m`` (long) [unsigned long \*]
+ Convert a Python long to a C/C++ ``unsigned long``.
+
+ ``n`` (long) [long long \*]
+ Convert a Python long to a C/C++ ``long long``.
+
+ ``o`` (long) [unsigned long long \*]
+ Convert a Python long to a C/C++ ``unsigned long long``.
+
+ ``s`` (string/bytes) [const char \*\*]
+ Convert a Python v2 string object or a Python v3 bytes object to a
+ C/C++ ``'\0'`` terminated string. If the Python object is ``Py_None``
+ then the string is ``NULL``.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use ``B``.
+
+ ``t`` (long) [unsigned short \*]
+ Convert a Python long to a C/C++ ``unsigned short``.
+
+ ``u`` (long) [unsigned int \*]
+ Convert a Python long to a C/C++ ``unsigned int``.
+
+ ``w`` (unicode/string) [wchar_t \*]
+ Convert a Python v2 string or unicode object or a Python v3 string
+ object of length 1 to a C/C++ wide character.
+
+ ``x`` (unicode/string) [wchar_t \*\*]
+ Convert a Python v2 string or unicode object or a Python v3 string
+ object to a C/C++ ``L'\0'`` terminated wide character string. If the
+ Python object is ``Py_None`` then the string is ``NULL``.
+
+ ``Ae`` (object) [int, const char \*\*]
+ Convert a Python string-like object to a C/C++ ``'\0'`` terminated
+ string according to the encoding ``e``. ``e`` can either be ``A`` for
+ ASCII, ``L`` for Latin-1, or ``8`` for UTF-8. If the Python object is
+ ``Py_None`` then the string is ``NULL``. The integer uniquely
+ identifies the object in the context defined by the ``S`` format
+ character and allows an extra reference to the object to be kept to
+ ensure that the string remains valid. For Python v2 the object may be
+ either a string or a unicode object that can be encoded. For Python v3
+ the object may either be a bytes object or a string object that can be
+ encoded. An object that supports the buffer protocol may also be used.
+
+ ``B`` (string/bytes) [int, const char \*\*]
+ Convert a Python v2 string object or a Python v3 bytes object to a
+ C/C++ ``'\0'`` terminated string. If the Python object is ``Py_None``
+ then the string is ``NULL``. The integer uniquely identifies the
+ object in the context defined by the ``S`` format character and allows
+ an extra reference to the object to be kept to ensure that the string
+ remains valid.
+
+ ``Cf`` (wrapped class) [:ctype:`sipWrapperType` \*, int \*, void \*\*]
+ Convert a Python object to a C structure or a C++ class instance and
+ return its state as described in :cfunc:`sipConvertToInstance()`.
+ ``f`` is a combination of the following flags encoded as an ASCII
+ character by adding ``0`` to the combined value:
+
+ 0x01 disallows the conversion of ``Py_None`` to ``NULL``
+
+ 0x02 implements the :fanno:`Factory` and :fanno:`TransferBack`
+ annotations
+
+ 0x04 suppresses the return of the state of the returned C/C++
+ instance. Note that the ``int *`` used to return the state is
+ not passed if this flag is specified.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use ``Hf``.
+
+ ``Df`` (wrapped instance) [const :ctype:`sipTypeDef` \*, int \*, void \*\*]
+ Convert a Python object to a C structure, C++ class or mapped type
+ instance and return its state as described in
+ :cfunc:`sipConvertToType()`. ``f`` is a combination of the following
+ flags encoded as an ASCII character by adding ``0`` to the combined
+ value:
+
+ 0x01 disallows the conversion of ``Py_None`` to ``NULL``
+
+ 0x02 implements the :fanno:`Factory` and :fanno:`TransferBack`
+ annotations
+
+ 0x04 suppresses the return of the state of the returned C/C++
+ instance. Note that the ``int *`` used to return the state is
+ not passed if this flag is specified.
+
+ .. note::
+ This is deprecated from SIP v4.10.1. Instead you should use
+ ``Hf``.
+
+ ``E`` (wrapped enum) [PyTypeObject \*, enum \*]
+ Convert a Python named enum type to the corresponding C/C++ ``enum``.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use ``F``.
+
+ ``F`` (wrapped enum) [:ctype:`sipTypeDef` \*, enum \*]
+ Convert a Python named enum type to the corresponding C/C++ ``enum``.
+
+ ``G`` (unicode/string) [wchar_t \*\*, :cmacro:`SIP_SSIZE_T` \*]
+ Convert a Python v2 string or unicode object or a Python v3 string
+ object to a C/C++ wide character array and its length. If the Python
+ object is ``Py_None`` then the array and length are ``NULL`` and zero
+ respectively.
+
+ ``Hf`` (wrapped instance) [const :ctype:`sipTypeDef` \*, int \*, void \*\*]
+ Convert a Python object to a C structure, C++ class or mapped type
+ instance as described in :cfunc:`sipConvertToType()`. ``f`` is a
+ combination of the following flags encoded as an ASCII character by
+ adding ``0`` to the combined value:
+
+ 0x01 disallows the conversion of ``Py_None`` to ``NULL``
+
+ 0x02 implements the :fanno:`Factory` and :fanno:`TransferBack`
+ annotations
+
+ 0x04 returns a copy of the C/C++ instance.
+
+ ``N`` (object) [PyTypeObject \*, :PyObject \*\*]
+ A Python object is checked to see if it is a certain type and then
+ returned without any conversions. The reference count is incremented.
+ The Python object may be ``Py_None``.
+
+ ``O`` (object) [PyObject \*\*]
+ A Python object is returned without any conversions. The reference
+ count is incremented.
+
+ ``S`` [:ctype:`sipSimpleWrapper` \*]
+ This format character, if used, must be the first. It is used with
+ other format characters to define a context and doesn't itself convert
+ an argument.
+
+ ``T`` (object) [PyTypeObject \*, PyObject \*\*]
+ A Python object is checked to see if it is a certain type and then
+ returned without any conversions. The reference count is incremented.
+ The Python object may not be ``Py_None``.
+
+ ``V`` (:class:`sip.voidptr`) [void \*]
+ Convert a Python :class:`sip.voidptr` object to a C/C++ ``void *``.
+
+ ``Z`` (object) []
+ Check that a Python object is ``Py_None``. No value is returned.
+
+
+.. cfunction:: int sipRegisterAttributeGetter(const sipTypeDef *td, sipAttrGetterFunc getter)
+
+ This registers a handler that will called just before SIP needs to get an
+ attribute from a wrapped type's dictionary for the first time. The handler
+ must then populate the type's dictionary with any lazy attributes.
+
+ :param td:
+ the optional :ref:`generated type structure <ref-type-structures>` that
+ determines which types the handler will be called for.
+ :param getter:
+ the handler function.
+ :return:
+ 0 if there was no error, otherwise -1 is returned.
+
+ If *td* is not ``NULL`` then the handler will only be called for types with
+ that type or that are sub-classed from it. Otherwise the handler will be
+ called for all types.
+
+ A handler has the following signature.
+
+ int handler(const :ctype:`sipTypeDef` \*td, PyObject \*dict)
+
+ *td* is the generated type definition of the type whose dictionary is
+ to be populated.
+
+ *dict* is the dictionary to be populated.
+
+ 0 if there was no error, otherwise -1 is returned.
+
+ See the section :ref:`ref-lazy-type-attributes` for more details.
+
+
+.. cfunction:: int sipRegisterPyType(PyTypeObject *type)
+
+ This registers a Python type object that can be used as the meta-type or
+ super-type of a wrapped C++ type.
+
+ :param type:
+ the type object.
+ :return:
+ 0 if there was no error, otherwise -1 is returned.
+
+ See the section :ref:`ref-types-metatypes` for more details.
+
+
+.. cfunction:: void sipReleaseInstance(void *cpp, sipWrapperType *type, int state)
+
+ This destroys a wrapped C/C++ instance if it was a temporary instance. It
+ is called after a call to either :cfunc:`sipConvertToInstance()` or
+ :cfunc:`sipForceConvertToInstance()`.
+
+ :param cpp:
+ the C/C++ instance.
+ :param type:
+ the type's :ref:`generated type object <ref-type-objects>`.
+ :param state:
+ describes the state of the C/C++ instance.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipReleaseType()`.
+
+
+.. cfunction:: void sipReleaseMappedType(void *cpp, const sipMappedType *mt, int state)
+
+ This destroys a wrapped C/C++ mapped type if it was a temporary instance.
+ It is called after a call to either :cfunc:`sipConvertToMappedType()` or
+ :cfunc:`sipForceConvertToMappedType()`.
+
+ :param cpp:
+ the C/C++ instance.
+ :param mt:
+ the opaque structure returned by :cfunc:`sipFindMappedType()`.
+ :param state:
+ describes the state of the C/C++ instance.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use
+ :cfunc:`sipReleaseType()`.
+
+
+.. cfunction:: void sipReleaseType(void *cpp, const sipTypeDef *td, int state)
+
+ This destroys a wrapped C/C++ or mapped type instance if it was a temporary
+ instance. It is called after a call to either :cfunc:`sipConvertToType()`
+ or :cfunc:`sipForceConvertToType()`.
+
+ :param cpp:
+ the C/C++ instance.
+ :param td:
+ the type's :ref:`generated type structure <ref-type-structures>`.
+ :param state:
+ describes the state of the C/C++ instance.
+
+
+.. cfunction:: const char *sipResolveTypedef(const char *name)
+
+ This returns the value of a C/C++ typedef.
+
+ :param name:
+ the name of the typedef.
+ :return:
+ the value of the typedef or ``NULL`` if there was no such typedef.
+
+
+.. ctype:: sipSimpleWrapper
+
+ This is a C structure that represents a Python wrapped instance whose type
+ is :class:`sip.simplewrapper`. It is an extension of the ``PyObject``
+ structure and so may be safely cast to it.
+
+ .. cmember:: PyObject *user
+
+ This can be used for any purpose by handwritten code and will
+ automatically be garbage collected at the appropriate time.
+
+
+.. cvar:: PyTypeObject *sipSimpleWrapper_Type
+
+ This is the type of a :ctype:`sipSimpleWrapper` structure and is the C
+ implementation of :class:`sip.simplewrapper`. It may be safely cast to
+ :ctype:`sipWrapperType`.
+
+
+.. ctype:: sipStringTypeClassMap
+
+ This C structure is used with :cfunc:`sipMapStringToClass()` to define a
+ mapping between ``'\0'`` terminated string based RTTI and
+ :ref:`ref-type-objects`. The structure elements are as follows.
+
+ .. cmember:: char *typeString
+
+ The ``'\0'`` terminated string RTTI.
+
+ .. cmember:: sipWrapperType **pyType.
+
+ A pointer to the corresponding generated type object.
+
+ .. note::
+ This is deprecated from SIP v4.8.
+
+
+.. cfunction:: void sipTransferBack(PyObject *obj)
+
+ This transfers ownership of a Python wrapped instance to Python (see
+ :ref:`ref-object-ownership`).
+
+ :param obj:
+ the wrapped instance.
+
+ In addition, any association of the instance with regard to the cyclic
+ garbage collector with another instance is removed.
+
+
+.. cfunction:: void sipTransferBreak(PyObject *obj)
+
+ Any association of a Python wrapped instance with regard to the cyclic
+ garbage collector with another instance is removed. Ownership of the
+ instance should be with C++.
+
+ :param obj:
+ the wrapped instance.
+
+
+.. cfunction:: void sipTransferTo(PyObject *obj, PyObject *owner)
+
+ This transfers ownership of a Python wrapped instance to C++ (see
+ :ref:`ref-object-ownership`).
+
+ :param obj:
+ the wrapped instance.
+ :param owner:
+ an optional wrapped instance that *obj* becomes associated with with
+ regard to the cyclic garbage collector. If *owner* is ``NULL`` then no
+ such association is made. If *owner* is the same value as *obj* then
+ any reference cycles involving *obj* can never be detected or broken by
+ the cyclic garbage collector. Responsibility for calling the C++
+ instance's destructor is always transfered to C++.
+
+
+.. cfunction:: PyTypeObject *sipTypeAsPyTypeObject(sipTypeDef *td)
+
+ This returns a pointer to the Python type object that SIP creates for a
+ :ref:`generated type structure <ref-type-structures>`.
+
+ :param td:
+ the type structure.
+ :return:
+ the Python type object. If the type structure refers to a mapped type
+ then ``NULL`` will be returned.
+
+ If the type structure refers to a C structure or C++ class then the
+ Python type object may be safely cast to a :ctype:`sipWrapperType`.
+
+
+.. cfunction:: const sipTypeDef *sipTypeFromPyTypeObject(PyTypeObject *py_type)
+
+ This returns the :ref:`generated type structure <ref-type-structures>` for
+ a Python type object.
+
+ :param py_type:
+ the Python type object.
+ :return:
+ the type structure or ``NULL`` if the Python type object doesn't
+ correspond to a type structure.
+
+
+.. cfunction:: int sipTypeIsClass(sipTypeDef *td)
+
+ This checks if a :ref:`generated type structure <ref-type-structures>`
+ refers to a C structure or C++ class.
+
+ :param td:
+ the type structure.
+ :return:
+ a non-zero value if the type structure refers to a structure or class.
+
+
+.. cfunction:: int sipTypeIsEnum(sipTypeDef *td)
+
+ This checks if a :ref:`generated type structure <ref-type-structures>`
+ refers to a named enum.
+
+ :param td:
+ the type structure.
+ :return:
+ a non-zero value if the type structure refers to an enum.
+
+
+.. cfunction:: int sipTypeIsMapped(sipTypeDef *td)
+
+ This checks if a :ref:`generated type structure <ref-type-structures>`
+ refers to a mapped type.
+
+ :param td:
+ the type structure.
+ :return:
+ a non-zero value if the type structure refers to a mapped type.
+
+
+.. cfunction:: int sipTypeIsNamespace(sipTypeDef *td)
+
+ This checks if a :ref:`generated type structure <ref-type-structures>`
+ refers to a C++ namespace.
+
+ :param td:
+ the type structure.
+ :return:
+ a non-zero value if the type structure refers to a namespace.
+
+
+.. cfunction:: const char *sipTypeName(const sipTypeDef *td)
+
+ This returns the C/C++ name of a wrapped type.
+
+ :param td:
+ the type's :ref:`generated type structure <ref-type-structures>`.
+ :return:
+ the name of the C/C++ type.
+
+
+.. cfunction:: const sipTypeDef *sipTypeScope(const sipTypeDef *td)
+
+ This returns the :ref:`generated type structure <ref-type-structures>` of
+ the enclosing scope of another generated type structure.
+
+ :param td:
+ the type structure.
+ :return:
+ the type structure of the scope or ``NULL`` if the type has no scope.
+
+
+.. cvar:: PyTypeObject *sipVoidPtr_Type
+
+ This is the type of a ``PyObject`` structure that is used to wrap a
+ ``void *``.
+
+
+.. ctype:: sipWrapper
+
+ This is a C structure that represents a Python wrapped instance whose type
+ is :class:`sip.wrapper`. It is an extension of the
+ :ctype:`sipSimpleWrapper` and ``PyObject`` structures and so may be safely
+ cast to both.
+
+
+.. cfunction:: int sipWrapper_Check(PyObject *obj)
+
+ This checks if a Python object is a wrapped instance.
+
+ :param obj:
+ the Python object.
+ :return:
+ a non-zero value if the Python object is a wrapped instance.
+
+ .. note::
+ This is deprecated from SIP v4.8. Instead you should use the
+ following::
+
+ PyObject_TypeCheck(obj, sipWrapper_Type)
+
+
+.. cvar:: PyTypeObject *sipWrapper_Type
+
+ This is the type of a :ctype:`sipWrapper` structure and is the C
+ implementation of :class:`sip.wrapper`. It may be safely cast to
+ :ctype:`sipWrapperType`.
+
+
+.. ctype:: sipWrapperType
+
+ This is a C structure that represents a SIP generated type object. It is
+ an extension of the ``PyTypeObject`` structure (which is itself an
+ extension of the ``PyObject`` structure) and so may be safely cast to
+ ``PyTypeObject`` (and ``PyObject``).
+
+
+.. cvar:: PyTypeObject *sipWrapperType_Type
+
+ This is the type of a :ctype:`sipWrapperType` structure and is the C
+ implementation of :class:`sip.wrappertype`.
+
+
+.. _ref-type-structures:
+
+Generated Type Structures
+-------------------------
+
+SIP generates an opaque type structure for each C structure, C++ class, C++
+namespace, named enum or mapped type being wrapped. These are
+:ctype:`sipTypeDef` structures and are used extensively by the SIP API.
+
+The names of these structure are prefixed by ``sipType_``.
+
+For those structures that correspond to C structures, C++ classes, C++
+namespaces or named enums the remaining part of the name is the fully
+qualified name of the structure, class, namespace or enum name. Any ``::``
+scope separators are replaced by an underscore. For example, the type object
+for class ``Klass`` is ``sipType_Klass``.
+
+For those structure that correspond to mapped types the remaining part of the
+name is generated by SIP. The only way for handwritten code to obtain a
+pointer to a structure for a mapped type is to use :cfunc:`sipFindType()`.
+
+The type structures of all imported types are available to handwritten code.
+
+
+.. _ref-type-objects:
+
+Generated Type Objects
+----------------------
+
+SIP generates a :ctype:`sipWrapperType` type object for each C structure or
+C++ class being wrapped.
+
+These objects are named with the structure or class name prefixed by
+``sipClass_``. For example, the type object for class ``Klass`` is
+``sipClass_Klass``.
+
+.. note::
+ Using these names is deprecated from SIP v4.8. Instead use the
+ corresponding generated type structure (see :ref:`ref-type-structures`) and
+ :cfunc:`sipTypeAsPyTypeObject()`.
+
+
+.. _ref-enum-type-objects:
+
+Generated Named Enum Type Objects
+---------------------------------
+
+SIP generates a type object for each named enum being wrapped. These are
+PyTypeObject structures. (Anonymous enums are wrapped as Python integers.)
+
+These objects are named with the fully qualified enum name (i.e. including any
+enclosing scope) prefixed by ``sipEnum_``. For example, the type object for
+enum ``Enum`` defined in class ``Klass`` is ``sipEnum_Klass_Enum``.
+
+.. note::
+ Using these names is deprecated from SIP v4.8. Instead use the
+ corresponding generated type structure (see :ref:`ref-type-structures`) and
+ :cfunc:`sipTypeAsPyTypeObject()`.
+
+
+.. _ref-derived-classes:
+
+Generated Derived Classes
+-------------------------
+
+For most C++ classes being wrapped SIP generates a derived class with the same
+name prefixed by ``sip``. For example, the derived class for class ``Klass``
+is ``sipKlass``.
+
+If a C++ class doesn't have any virtual or protected methods in it or any of
+it's super-class hierarchy, or does not emit any Qt signals, then a derived
+class is not generated.
+
+Most of the time handwritten code should ignore the derived classes. The only
+exception is that handwritten constructor code specified using the
+:directive:`%MethodCode` directive should call the derived class's constructor
+(which has the same C++ signature) rather then the wrapped class's constructor.
+
+
+.. _ref-exception-objects:
+
+Generated Exception Objects
+---------------------------
+
+SIP generates a Python object for each exception defined with the
+:directive:`%Exception` directive.
+
+These objects are named with the fully qualified exception name (i.e. including
+any enclosing scope) prefixed by ``sipException_``. For example, the type
+object for enum ``Except`` defined in class ``Klass`` is
+``sipException_Klass_Except``.
+
+The objects of all imported exceptions are available to handwritten code.
diff --git a/sphinx/command_line.rst b/sphinx/command_line.rst
new file mode 100644
index 0000000..9c50cf4
--- /dev/null
+++ b/sphinx/command_line.rst
@@ -0,0 +1,137 @@
+.. _ref-command-line:
+
+The SIP Command Line
+====================
+
+The syntax of the SIP command line is::
+
+ sip [options] [specification]
+
+``specification`` is the name of the specification file for the module. If it
+is omitted then ``stdin`` is used.
+
+The full set of command line options is:
+
+.. program:: sip
+
+.. cmdoption:: -h
+
+ Display a help message.
+
+.. cmdoption:: -V
+
+ Display the SIP version number.
+
+.. cmdoption:: -a <FILE>
+
+ The name of the QScintilla API file to generate. This file contains a
+ description of the module API in a form that the QScintilla editor
+ component can use for auto-completion and call tips. (The file may also be
+ used by the SciTE editor but must be sorted first.) By default the file is
+ not generated.
+
+.. cmdoption:: -b <FILE>
+
+ The name of the build file to generate. This file contains the information
+ about the module needed by the :ref:`SIP build system <ref-build-system>`
+ to generate a platform and compiler specific Makefile for the module. By
+ default the file is not generated.
+
+.. cmdoption:: -c <DIR>
+
+ The name of the directory (which must exist) into which all of the
+ generated C or C++ code is placed. By default no code is generated.
+
+.. cmdoption:: -d <FILE>
+
+ The name of the documentation file to generate. Documentation is included
+ in specification files using the :directive:`%Doc` and
+ :directive:`%ExportedDoc` directives. By default the file is not
+ generated.
+
+.. cmdoption:: -e
+
+ Support for C++ exceptions is enabled. This causes all calls to C++ code
+ to be enclosed in ``try``/``catch`` blocks and C++ exceptions to be
+ converted to Python exceptions. By default exception support is disabled.
+
+.. cmdoption:: -g
+
+ The Python GIL is released before making any calls to the C/C++ library
+ being wrapped and reacquired afterwards. See :ref:`ref-gil` and the
+ :fanno:`ReleaseGIL` and :fanno:`HoldGIL` annotations.
+
+.. cmdoption:: -I <DIR>
+
+ The directory is added to the list of directories searched when looking for
+ a specification file given in an :directive:`%Include` or
+ :directive:`%Import` directive. This option may be given any number of
+ times.
+
+.. cmdoption:: -j <NUMBER>
+
+ The generated code is split into the given number of files. This makes it
+ easier to use the parallel build facility of most modern implementations of
+ ``make``. By default 1 file is generated for each C structure or C++
+ class.
+
+.. cmdoption:: -k
+
+ .. versionadded:: 4.10
+
+ All functions and methods will, by default, support passing parameters
+ using the Python keyword argument syntax.
+
+.. cmdoption:: -o
+
+ .. versionadded:: 4.10
+
+ Docstrings will be automatically generated that describe the signature of
+ all functions, methods and constructors.
+
+.. cmdoption:: -p <MODULE>
+
+ The name of the :directive:`%ConsolidatedModule` which will contain the
+ wrapper code for this component module.
+
+.. cmdoption:: -P
+
+ .. versionadded:: 4.10
+
+ By default SIP generates code to provide access to protected C++ functions
+ from Python. On some platforms (notably Linux, but not Windows) this code
+ can be avoided if the ``protected`` keyword is redefined as ``public``
+ during compilation. This can result in a significant reduction in the size
+ of a generated Python module. This option disables the generation of the
+ extra code.
+
+.. cmdoption:: -r
+
+ Debugging statements that trace the execution of the bindings are
+ automatically generated. By default the statements are not generated.
+
+.. cmdoption:: -s <SUFFIX>
+
+ The suffix to use for generated C or C++ source files. By default ``.c``
+ is used for C and ``.cpp`` for C++.
+
+.. cmdoption:: -t <TAG>
+
+ The SIP version tag (declared using a :directive:`%Timeline` directive) or
+ the SIP platform tag (declared using the :directive:`%Platforms` directive)
+ to generate code for. This option may be given any number of times so long
+ as the tags do not conflict.
+
+.. cmdoption:: -w
+
+ The display of warning messages is enabled. By default warning messages
+ are disabled.
+
+.. cmdoption:: -x <FEATURE>
+
+ The feature (declared using the :directive:`%Feature` directive) is
+ disabled.
+
+.. cmdoption:: -z <FILE>
+
+ The name of a file containing more command line options.
diff --git a/sphinx/conf.py b/sphinx/conf.py
new file mode 100644
index 0000000..43a3a1e
--- /dev/null
+++ b/sphinx/conf.py
@@ -0,0 +1,231 @@
+# -*- coding: utf-8 -*-
+#
+# SIP documentation build configuration file, created by
+# sphinx-quickstart on Sat May 30 14:28:55 2009.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.append(os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+#extensions = []
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'SIP'
+copyright = u'2010 Riverbank Computing Limited'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '4.10.5'
+# The full version, including alpha/beta/rc tags.
+release = '4.10.5'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+#unused_docs = []
+
+# List of directories, relative to source directory, that shouldn't be searched
+# for source files.
+#exclude_trees = []
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. Major themes that come with
+# Sphinx are currently 'default' and 'sphinxdoc'.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+html_title = "SIP 4.10.5 Reference Guide"
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_use_modindex = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+html_show_sourcelink = False
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = ''
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'SIPdoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+ ('index', 'SIP.tex', u'SIP Documentation',
+ u'Riverbank Computing Limited', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_use_modindex = True
+
+
+def setup(app):
+ """ Define roles specific to SIP. """
+
+ app.add_description_unit('argument-annotation', 'aanno',
+ indextemplate='single: %s (argument annotation)')
+
+ app.add_description_unit('class-annotation', 'canno',
+ indextemplate='single: %s (class annotation)')
+
+ app.add_description_unit('enum-annotation', 'eanno',
+ indextemplate='single: %s (enum annotation)')
+
+ app.add_description_unit('exception-annotation', 'xanno',
+ indextemplate='single: %s (exception annotation)')
+
+ app.add_description_unit('function-annotation', 'fanno',
+ indextemplate='single: %s (function annotation)')
+
+ app.add_description_unit('license-annotation', 'lanno',
+ indextemplate='single: %s (license annotation)')
+
+ app.add_description_unit('mapped-type-annotation', 'manno',
+ indextemplate='single: %s (mapped type annotation)')
+
+ app.add_description_unit('typedef-annotation', 'tanno',
+ indextemplate='single: %s (typedef annotation)')
+
+ app.add_description_unit('variable-annotation', 'vanno',
+ indextemplate='single: %s (variable annotation)')
+
+ app.add_description_unit('directive', 'directive',
+ indextemplate='single: %s (directive)')
+
+ app.add_description_unit('sip-type', 'stype',
+ indextemplate='single: %s (SIP type)')
diff --git a/sphinx/directives.rst b/sphinx/directives.rst
new file mode 100644
index 0000000..7e3a2e0
--- /dev/null
+++ b/sphinx/directives.rst
@@ -0,0 +1,2109 @@
+Directives
+==========
+
+In this section we describe each of the directives that can be used in
+specification files. All directives begin with ``%`` as the first
+non-whitespace character in a line.
+
+Some directives have arguments or contain blocks of code or documentation. In
+the following descriptions these are shown in *italics*. Optional arguments
+are enclosed in [*brackets*].
+
+Some directives are used to specify handwritten code. Handwritten code must
+not define names that start with the prefix ``sip``.
+
+
+.. directive:: %AccessCode
+
+.. parsed-literal::
+
+ %AccessCode
+ *code*
+ %End
+
+This directive is used immediately after the declaration of an instance of a
+wrapped class or structure, or a pointer to such an instance. You use it to
+provide handwritten code that overrides the default behaviour.
+
+For example::
+
+ class Klass;
+
+ Klass *klassInstance;
+ %AccessCode
+ // In this contrived example the C++ library we are wrapping defines
+ // klassInstance as Klass ** (which SIP doesn't support) so we
+ // explicitly dereference it.
+ if (klassInstance && *klassInstance)
+ return *klassInstance;
+
+ // This will get converted to None.
+ return 0;
+ %End
+
+
+.. directive:: %API
+
+.. versionadded:: 4.9
+
+.. parsed-literal::
+
+ %API *name* *version*
+
+This directive is used to define an API and set its default version number. A
+version number must be greater than or equal to 1.
+
+See :ref:`ref-incompat-apis` for more detail.
+
+For example::
+
+ %API PyQt4 1
+
+
+.. directive:: %BIGetBufferCode
+
+.. parsed-literal::
+
+ %BIGetBufferCode
+ *code*
+ %End
+
+This directive (along with :directive:`%BIReleaseBufferCode`) is used to
+specify code that implements the buffer interface of Python v3. If Python v2
+is being used then this is ignored.
+
+The following variables are made available to the handwritten code:
+
+Py_buffer \*sipBuffer
+ This is a pointer to the Python buffer structure that the handwritten code
+ must populate.
+
+*type* \*sipCpp
+ This is a pointer to the structure or class instance. Its *type* is a
+ pointer to the structure or class.
+
+int sipFlags
+ These are the flags that specify what elements of the ``sipBuffer``
+ structure must be populated.
+
+int sipRes
+ The handwritten code should set this to 0 if there was no error or -1 if
+ there was an error.
+
+PyObject \*sipSelf
+ This is the Python object that wraps the structure or class instance, i.e.
+ ``self``.
+
+
+.. directive:: %BIGetCharBufferCode
+
+.. parsed-literal::
+
+ %BIGetCharBufferCode
+ *code*
+ %End
+
+This directive (along with :directive:`%BIGetReadBufferCode`,
+:directive:`%BIGetSegCountCode` and :directive:`%BIGetWriteBufferCode`) is used
+to specify code that implements the buffer interface of Python v2. If Python
+v3 is being used then this is ignored.
+
+The following variables are made available to the handwritten code:
+
+*type* \*sipCpp
+ This is a pointer to the structure or class instance. Its *type* is a
+ pointer to the structure or class.
+
+void \*\*sipPtrPtr
+ This is the pointer used to return the address of the character buffer.
+
+:cmacro:`SIP_SSIZE_T` sipRes
+ The handwritten code should set this to the length of the character buffer
+ or -1 if there was an error.
+
+:cmacro:`SIP_SSIZE_T` sipSegment
+ This is the number of the segment of the character buffer.
+
+PyObject \*sipSelf
+ This is the Python object that wraps the structure or class instance, i.e.
+ ``self``.
+
+
+.. directive:: %BIGetReadBufferCode
+
+.. parsed-literal::
+
+ %BIGetReadBufferCode
+ *code*
+ %End
+
+This directive (along with :directive:`%BIGetCharBufferCode`,
+:directive:`%BIGetSegCountCode` and :directive:`%BIGetWriteBufferCode`) is used
+to specify code that implements the buffer interface of Python v2. If
+Python v3 is being used then this is ignored.
+
+The following variables are made available to the handwritten code:
+
+*type* \*sipCpp
+ This is a pointer to the structure or class instance. Its *type* is a
+ pointer to the structure or class.
+
+void \*\*sipPtrPtr
+ This is the pointer used to return the address of the read buffer.
+
+:cmacro:`SIP_SSIZE_T` sipRes
+ The handwritten code should set this to the length of the read buffer or
+ -1 if there was an error.
+
+:cmacro:`SIP_SSIZE_T` sipSegment
+ This is the number of the segment of the read buffer.
+
+PyObject \*sipSelf
+ This is the Python object that wraps the structure or class instance, i.e.
+ ``self``.
+
+
+.. directive:: %BIGetSegCountCode
+
+.. parsed-literal::
+
+ %BIGetSegCountCode
+ *code*
+ %End
+
+This directive (along with :directive:`%BIGetCharBufferCode`,
+:directive:`%BIGetReadBufferCode` and :directive:`%BIGetWriteBufferCode`) is
+used to specify code that implements the buffer interface of Python v2. If
+Python v3 is being used then this is ignored.
+
+The following variables are made available to the handwritten code:
+
+*type* \*sipCpp
+ This is a pointer to the structure or class instance. Its *type* is a
+ pointer to the structure or class.
+
+:cmacro:`SIP_SSIZE_T` \*sipLenPtr
+ This is the pointer used to return the total length in bytes of all
+ segments of the buffer.
+
+:cmacro:`SIP_SSIZE_T` sipRes
+ The handwritten code should set this to the number of segments that make
+ up the buffer.
+
+PyObject \*sipSelf
+ This is the Python object that wraps the structure or class instance, i.e.
+ ``self``.
+
+
+.. directive:: %BIGetWriteBufferCode
+
+.. parsed-literal::
+
+ %BIGetWriteBufferCode
+ *code*
+ %End
+
+This directive (along with :directive:`%BIGetCharBufferCode`,
+:directive:`%BIGetReadBufferCode` and :directive:`%BIGetSegCountCode` is used
+to specify code that implements the buffer interface of Python v2. If Python
+v3 is being used then this is ignored.
+
+The following variables are made available to the handwritten code:
+
+*type* \*sipCpp
+ This is a pointer to the structure or class instance. Its *type* is a
+ pointer to the structure or class.
+
+void \*\*sipPtrPtr
+ This is the pointer used to return the address of the write buffer.
+
+:cmacro:`SIP_SSIZE_T` sipRes
+ The handwritten code should set this to the length of the write buffer or
+ -1 if there was an error.
+
+:cmacro:`SIP_SSIZE_T` sipSegment
+ This is the number of the segment of the write buffer.
+
+PyObject \*sipSelf
+ This is the Python object that wraps the structure or class instance, i.e.
+ ``self``.
+
+
+.. directive:: %BIReleaseBufferCode
+
+.. parsed-literal::
+
+ %BIReleaseBufferCode
+ *code*
+ %End
+
+This directive (along with :directive:`%BIGetBufferCode`) is used to specify
+code that implements the buffer interface of Python v3. If Python v2 is being
+used then this is ignored.
+
+The following variables are made available to the handwritten code:
+
+Py_buffer \*sipBuffer
+ This is a pointer to the Python buffer structure.
+
+*type* \*sipCpp
+ This is a pointer to the structure or class instance. Its *type* is a
+ pointer to the structure or class.
+
+PyObject \*sipSelf
+ This is the Python object that wraps the structure or class instance, i.e.
+ ``self``.
+
+
+.. directive:: %CModule
+
+.. parsed-literal::
+
+ %CModule *name* [*version*]
+
+This directive is used to identify that the library being wrapped is a C
+library and to define the name of the module and it's optional version number.
+
+See the :directive:`%Module` directive for an explanation of the version
+number.
+
+For example::
+
+ %CModule dbus 1
+
+
+.. directive:: %CompositeModule
+
+.. parsed-literal::
+
+ %CompositeModule *name*
+
+A composite module is one that merges a number of related SIP generated
+modules. For example, a module that merges the modules ``a_mod``, ``b_mod``
+and ``c_mod`` is equivalent to the following pure Python module::
+
+ from a_mod import *
+ from b_mod import *
+ from c_mod import *
+
+Clearly the individual modules should not define module-level objects with the
+same name.
+
+This directive is used to specify the name of a composite module. Any
+subsequent :directive:`%CModule` or :directive:`%Module` directive is
+interpreted as defining a component module.
+
+For example::
+
+ %CompositeModule PyQt4.Qt
+ %Include QtCore/QtCoremod.sip
+ %Include QtGui/QtGuimod.sip
+
+The main purpose of a composite module is as a programmer convenience as they
+don't have to remember which which individual module an object is defined in.
+
+
+.. directive:: %ConsolidatedModule
+
+.. parsed-literal::
+
+ %ConsolidatedModule *name*
+
+A consolidated module is one that consolidates the wrapper code of a number of
+SIP generated modules (refered to as component modules in this context).
+
+This directive is used to specify the name of a consolidated module. Any
+subsequent :directive:`%CModule` or :directive:`%Module` directive is
+interpreted as defining a component module.
+
+For example::
+
+ %ConsolidatedModule PyQt4._qt
+ %Include QtCore/QtCoremod.sip
+ %Include QtGui/QtGuimod.sip
+
+A consolidated module is not intended to be explicitly imported by an
+application. Instead it is imported by its component modules when they
+themselves are imported.
+
+Normally the wrapper code is contained in the component module and is linked
+against the corresponding C or C++ library. The advantage of a consolidated
+module is that it allows all of the wrapped C or C++ libraries to be linked
+against a single module. If the linking is done statically then deployment of
+generated modules can be greatly simplified.
+
+It follows that a component module can be built in one of two ways, as a
+normal standalone module, or as a component of a consolidated module. When
+building as a component the ``-p`` command line option should be used to
+specify the name of the consolidated module.
+
+
+.. directive:: %ConvertFromTypeCode
+
+.. parsed-literal::
+
+ %ConvertFromTypeCode
+ *code*
+ %End
+
+This directive is used as part of the :directive:`%MappedType` directive to
+specify the handwritten code that converts an instance of a mapped type to a
+Python object.
+
+The following variables are made available to the handwritten code:
+
+*type* \*sipCpp
+ This is a pointer to the instance of the mapped type to be converted. It
+ will never be zero as the conversion from zero to ``Py_None`` is handled
+ before the handwritten code is called.
+
+PyObject \*sipTransferObj
+ This specifies any desired ownership changes to the returned object. If it
+ is ``NULL`` then the ownership should be left unchanged. If it is
+ ``Py_None`` then ownership should be transferred to Python. Otherwise
+ ownership should be transferred to C/C++ and the returned object associated
+ with *sipTransferObj*. The code can choose to interpret these changes in
+ any way. For example, if the code is converting a C++ container of wrapped
+ classes to a Python list it is likely that the ownership changes should be
+ made to each element of the list.
+
+The handwritten code must explicitly return a ``PyObject *``. If there was an
+error then a Python exception must be raised and ``NULL`` returned.
+
+The following example converts a ``QList<QWidget *>`` instance to a Python
+list of ``QWidget`` instances::
+
+ %ConvertFromTypeCode
+ PyObject *l;
+
+ // Create the Python list of the correct length.
+ if ((l = PyList_New(sipCpp->size())) == NULL)
+ return NULL;
+
+ // Go through each element in the C++ instance and convert it to a
+ // wrapped QWidget.
+ for (int i = 0; i < sipCpp->size(); ++i)
+ {
+ QWidget *w = sipCpp->at(i);
+ PyObject *wobj;
+
+ // Get the Python wrapper for the QWidget instance, creating a new
+ // one if necessary, and handle any ownership transfer.
+ if ((wobj = sipConvertFromType(w, sipType_QWidget, sipTransferObj)) == NULL)
+ {
+ // There was an error so garbage collect the Python list.
+ Py_DECREF(l);
+ return NULL;
+ }
+
+ // Add the wrapper to the list.
+ PyList_SET_ITEM(l, i, wobj);
+ }
+
+ // Return the Python list.
+ return l;
+ %End
+
+
+.. directive:: %ConvertToSubClassCode
+
+.. parsed-literal::
+
+ %ConvertToSubClassCode
+ *code*
+ %End
+
+When SIP needs to wrap a C++ class instance it first checks to make sure it
+hasn't already done so. If it has then it just returns a new reference to the
+corresponding Python object. Otherwise it creates a new Python object of the
+appropriate type. In C++ a function may be defined to return an instance of a
+certain class, but can often return a sub-class instead.
+
+This directive is used to specify handwritten code that exploits any available
+real-time type information (RTTI) to see if there is a more specific Python
+type that can be used when wrapping the C++ instance. The RTTI may be
+provided by the compiler or by the C++ instance itself.
+
+The directive is included in the specification of one of the classes that the
+handwritten code handles the type conversion for. It doesn't matter which
+one, but a sensible choice would be the one at the root of that class
+hierarchy in the module.
+
+Note that if a class hierarchy extends over a number of modules then this
+directive should be used in each of those modules to handle the part of the
+hierarchy defined in that module. SIP will ensure that the different pieces
+of code are called in the right order to determine the most specific Python
+type to use.
+
+The following variables are made available to the handwritten code:
+
+*type* \*sipCpp
+ This is a pointer to the C++ class instance.
+
+void \*\*sipCppRet
+ When the sub-class is derived from more than one super-class then it is
+ possible that the C++ address of the instance as the sub-class is
+ different to that of the super-class. If so, then this must be set to the
+ C++ address of the instance when cast (usually using ``static_cast``)
+ from the super-class to the sub-class.
+
+const sipTypeDef \*sipType
+ The handwritten code must set this to the SIP generated type structure
+ that corresponds to the class instance. (The type structure for class
+ ``Klass`` is ``sipType_Klass``.) If the RTTI of the class instance isn't
+ recognised then ``sipType`` must be set to ``NULL``. The code doesn't
+ have to recognise the exact class, only the most specific sub-class that
+ it can.
+
+sipWrapperType \*sipClass
+ The handwritten code must set this to the SIP generated Python type object
+ that corresponds to the class instance. (The type object for class
+ ``Klass`` is ``sipClass_Klass``.) If the RTTI of the class instance isn't
+ recognised then ``sipClass`` must be set to ``NULL``. The code doesn't
+ have to recognise the exact class, only the most specific sub-class that
+ it can.
+
+ This is deprecated from SIP v4.8. Instead you should use ``sipType``.
+
+The handwritten code must not explicitly return.
+
+The following example shows the sub-class conversion code for ``QEvent`` based
+class hierarchy in PyQt::
+
+ class QEvent
+ {
+ %ConvertToSubClassCode
+ // QEvent sub-classes provide a unique type ID.
+ switch (sipCpp->type())
+ {
+ case QEvent::Timer:
+ sipType = sipType_QTimerEvent;
+ break;
+
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ sipType = sipType_QKeyEvent;
+ break;
+
+ // Skip the remaining event types to keep the example short.
+
+ default:
+ // We don't recognise the type.
+ sipType = NULL;
+ }
+ %End
+
+ // The rest of the class specification.
+
+ };
+
+
+.. directive:: %ConvertToTypeCode
+
+.. parsed-literal::
+
+ %ConvertToTypeCode
+ *code*
+ %End
+
+This directive is used to specify the handwritten code that converts a Python
+object to a mapped type instance and to handle any ownership transfers. It is
+used as part of the :directive:`%MappedType` directive and as part of a class
+specification. The code is also called to determine if the Python object is of
+the correct type prior to conversion.
+
+When used as part of a class specification it can automatically convert
+additional types of Python object. For example, PyQt uses it in the
+specification of the ``QString`` class to allow Python string objects and
+unicode objects to be used wherever ``QString`` instances are expected.
+
+The following variables are made available to the handwritten code:
+
+int \*sipIsErr
+ If this is ``NULL`` then the code is being asked to check the type of the
+ Python object. The check must not have any side effects. Otherwise the
+ code is being asked to convert the Python object and a non-zero value
+ should be returned through this pointer if an error occurred during the
+ conversion.
+
+PyObject \*sipPy
+ This is the Python object to be converted.
+
+*type* \*\*sipCppPtr
+ This is a pointer through which the address of the mapped type instance (or
+ zero if appropriate) is returned. Its value is undefined if ``sipIsErr``
+ is ``NULL``.
+
+PyObject \*sipTransferObj
+ This specifies any desired ownership changes to *sipPy*. If it is ``NULL``
+ then the ownership should be left unchanged. If it is ``Py_None`` then
+ ownership should be transferred to Python. Otherwise ownership should be
+ transferred to C/C++ and *sipPy* associated with *sipTransferObj*. The
+ code can choose to interpret these changes in any way.
+
+The handwritten code must explicitly return an ``int`` the meaning of which
+depends on the value of ``sipIsErr``.
+
+If ``sipIsErr`` is ``NULL`` then a non-zero value is returned if the Python
+object has a type that can be converted to the mapped type. Otherwise zero is
+returned.
+
+If ``sipIsErr`` is not ``NULL`` then a combination of the following flags is
+returned.
+
+ - :cmacro:`SIP_TEMPORARY` is set to indicate that the returned instance
+ is a temporary and should be released to avoid a memory leak.
+
+ - :cmacro:`SIP_DERIVED_CLASS` is set to indicate that the type of the
+ returned instance is a derived class. See
+ :ref:`ref-derived-classes`.
+
+The following example converts a Python list of ``QPoint`` instances to a
+``QList<QPoint>`` instance::
+
+ %ConvertToTypeCode
+ // See if we are just being asked to check the type of the Python
+ // object.
+ if (!sipIsErr)
+ {
+ // Checking whether or not None has been passed instead of a list
+ // has already been done.
+ if (!PyList_Check(sipPy))
+ return 0;
+
+ // Check the type of each element. We specify SIP_NOT_NONE to
+ // disallow None because it is a list of QPoint, not of a pointer
+ // to a QPoint, so None isn't appropriate.
+ for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i)
+ if (!sipCanConvertToType(PyList_GET_ITEM(sipPy, i),
+ sipType_QPoint, SIP_NOT_NONE))
+ return 0;
+
+ // The type is valid.
+ return 1;
+ }
+
+ // Create the instance on the heap.
+ QList<QPoint> *ql = new QList<QPoint>;
+
+ for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i)
+ {
+ QPoint *qp;
+ int state;
+
+ // Get the address of the element's C++ instance. Note that, in
+ // this case, we don't apply any ownership changes to the list
+ // elements, only to the list itself.
+ qp = reinterpret_cast<QPoint *>(sipConvertToType(
+ PyList_GET_ITEM(sipPy, i),
+ sipType_QPoint, 0,
+ SIP_NOT_NONE,
+ &state, sipIsErr));
+
+ // Deal with any errors.
+ if (*sipIsErr)
+ {
+ sipReleaseType(qp, sipType_QPoint, state);
+
+ // Tidy up.
+ delete ql;
+
+ // There is no temporary instance.
+ return 0;
+ }
+
+ ql->append(*qp);
+
+ // A copy of the QPoint was appended to the list so we no longer
+ // need it. It may be a temporary instance that should be
+ // destroyed, or a wrapped instance that should not be destroyed.
+ // sipReleaseType() will do the right thing.
+ sipReleaseType(qp, sipType_QPoint, state);
+ }
+
+ // Return the instance.
+ *sipCppPtr = ql;
+
+ // The instance should be regarded as temporary (and be destroyed as
+ // soon as it has been used) unless it has been transferred from
+ // Python. sipGetState() is a convenience function that implements
+ // this common transfer behaviour.
+ return sipGetState(sipTransferObj);
+ %End
+
+When used in a class specification the handwritten code replaces the code that
+would normally be automatically generated. This means that the handwritten
+code must also handle instances of the class itself and not just the additional
+types that are being supported. This should be done by making calls to
+:cfunc:`sipCanConvertToType()` to check the object type and
+:cfunc:`sipConvertToType()` to convert the object. The
+:cmacro:`SIP_NO_CONVERTORS` flag *must* be passed to both these functions to
+prevent recursive calls to the handwritten code.
+
+
+.. directive:: %Copying
+
+.. parsed-literal::
+
+ %Copying
+ *text*
+ %End
+
+This directive is used to specify some arbitrary text that will be included at
+the start of all source files generated by SIP. It is normally used to
+include copyright and licensing terms.
+
+For example::
+
+ %Copying
+ Copyright (c) 2009 Riverbank Computing Limited
+ %End
+
+
+.. directive:: %DefaultEncoding
+
+.. parsed-literal::
+
+ %DefaultEncoding *string*
+
+This directive is used to specify the default encoding used for ``char``,
+``const char``, ``char *`` or ``const char *`` values. The encoding can be
+either ``"ASCII"``, ``"Latin-1"``, ``"UTF-8"`` or ``"None"``. An encoding of
+``"None"`` means that the value is unencoded. The default can be overridden
+for a particular value using the :aanno:`Encoding` annotation. If the
+directive is not specified then ``"None"`` is used.
+
+For example::
+
+ %DefaultEncoding "Latin-1"
+
+
+.. directive:: %DefaultMetatype
+
+.. parsed-literal::
+
+ %DefaultMetatype *dotted-name*
+
+This directive is used to specify the Python type that should be used as the
+meta-type for any C/C++ data type defined in the same module, and by importing
+modules, that doesn't have an explicit meta-type.
+
+If this is not specified then ``sip.wrappertype`` is used.
+
+You can also use the :canno:`Metatype` class annotation to specify the
+meta-type used by a particular C/C++ type.
+
+See the section :ref:`ref-types-metatypes` for more details.
+
+For example::
+
+ %DefaultMetatype PyQt4.QtCore.pyqtWrapperType
+
+
+.. directive:: %DefaultSupertype
+
+.. parsed-literal::
+
+ %DefaultSupertype *dotted-name*
+
+This directive is used to specify the Python type that should be used as the
+super-type for any C/C++ data type defined in the same module that doesn't have
+an explicit super-type.
+
+If this is not specified then ``sip.wrapper`` is used.
+
+You can also use the :canno:`Supertype` class annotation to specify the
+super-type used by a particular C/C++ type.
+
+See the section :ref:`ref-types-metatypes` for more details.
+
+For example::
+
+ %DefaultSupertype sip.simplewrapper
+
+
+.. directive:: %Doc
+
+.. parsed-literal::
+
+ %Doc
+ *text*
+ %End
+
+This directive is used to specify some arbitrary text that will be extracted
+by SIP when the ``-d`` command line option is used. The directive can be
+specified any number of times and SIP will concatenate all the separate pieces
+of text in the order that it sees them.
+
+Documentation that is specified using this directive is local to the module in
+which it appears. It is ignored by modules that :directive:`%Import` it. Use
+the :directive:`%ExportedDoc` directive for documentation that should be
+included by all modules that :directive:`%Import` this one.
+
+For example::
+
+ %Doc
+ <h1>An Example</h1>
+ <p>
+ This fragment of documentation is HTML and is local to the module in
+ which it is defined.
+ </p>
+ %End
+
+
+.. directive:: %Docstring
+
+.. parsed-literal::
+
+ %Docstring
+ *text*
+ %End
+
+.. versionadded:: 4.10
+
+This directive is used to specify explicit docstrings for classes, functions
+and methods.
+
+The docstring of a class is made up of the docstring specified for the class
+itself, with the docstrings specified for each contructor appended.
+
+The docstring of a function or method is made up of the concatenated docstrings
+specified for each of the overloads.
+
+Specifying an explicit docstring will prevent SIP from generating an automatic
+docstring that describes the Python signature of a function or method overload.
+This means that SIP will generate less informative exceptions (i.e. without a
+full signature) when it fails to match a set of arguments to any function or
+method overload.
+
+For example::
+
+ class Klass
+ {
+ %Docstring
+ This will be at the start of the class's docstring.
+ %End
+
+ public:
+ Klass();
+ %Docstring
+ This will be appended to the class's docstring.
+ %End
+ };
+
+
+.. directive:: %End
+
+This isn't a directive in itself, but is used to terminate a number of
+directives that allow a block of handwritten code or text to be specified.
+
+
+.. directive:: %Exception
+
+.. parsed-literal::
+
+ %Exception *name* [(*base-exception)]
+ {
+ [*header-code*]
+ *raise-code*
+ };
+
+This directive is used to define new Python exceptions, or to provide a stub
+for existing Python exceptions. It allows handwritten code to be provided
+that implements the translation between C++ exceptions and Python exceptions.
+The arguments to ``throw ()`` specifiers must either be names of classes or the
+names of Python exceptions defined by this directive.
+
+*name* is the name of the exception.
+
+*base-exception* is the optional base exception. This may be either one of
+the standard Python exceptions or one defined with a previous
+:directive:`%Exception` directive.
+
+*header-code* is the optional :directive:`%TypeHeaderCode` used to specify any
+external interface to the exception being defined.
+
+*raise-code* is the :directive:`%RaiseCode` used to specify the handwritten
+code that converts a reference to the C++ exception to the Python exception.
+
+For example::
+
+ %Exception std::exception(SIP_Exception) /PyName=StdException/
+ {
+ %TypeHeaderCode
+ #include <exception>
+ %End
+ %RaiseCode
+ const char *detail = sipExceptionRef.what();
+
+ SIP_BLOCK_THREADS
+ PyErr_SetString(sipException_std_exception, detail);
+ SIP_UNBLOCK_THREADS
+ %End
+ };
+
+In this example we map the standard C++ exception to a new Python exception.
+The new exception is called ``StdException`` and is derived from the standard
+Python exception ``Exception``.
+
+An exception may be annotated with :xanno:`Default` to specify that it should
+be caught by default if there is no ``throw`` clause.
+
+
+.. directive:: %ExportedDoc
+
+.. parsed-literal::
+
+ %ExportedDoc
+ *text*
+ %End
+
+This directive is used to specify some arbitrary text that will be extracted
+by SIP when the ``-d`` command line option is used. The directive can be
+specified any number of times and SIP will concatenate all the separate pieces
+of text in the order that it sees them.
+
+Documentation that is specified using this directive will also be included by
+modules that :directive:`%Import` it.
+
+For example::
+
+ %ExportedDoc
+ ==========
+ An Example
+ ==========
+
+ This fragment of documentation is reStructuredText and will appear in the
+ module in which it is defined and all modules that %Import it.
+ %End
+
+
+.. directive:: %ExportedHeaderCode
+
+.. parsed-literal::
+
+ %ExportedHeaderCode
+ *code*
+ %End
+
+This directive is used to specify handwritten code, typically the declarations
+of types, that is placed in a header file that is included by all generated
+code for all modules. It should not include function declarations because
+Python modules should not explicitly call functions in another Python module.
+
+See also :directive:`%ModuleCode` and :directive:`%ModuleHeaderCode`.
+
+
+.. directive:: %Feature
+
+.. parsed-literal::
+
+ %Feature *name*
+
+This directive is used to declare a feature. Features (along with
+:directive:`%Platforms` and :directive:`%Timeline`) are used by the
+:directive:`%If` directive to control whether or not parts of a specification
+are processed or ignored.
+
+Features are mutually independent of each other - any combination of features
+may be enabled or disable. By default all features are enabled. The SIP
+``-x`` command line option is used to disable a feature.
+
+If a feature is enabled then SIP will automatically generate a corresponding C
+preprocessor symbol for use by handwritten code. The symbol is the name of
+the feature prefixed by ``SIP_FEATURE_``.
+
+For example::
+
+ %Feature FOO_SUPPORT
+
+ %If (FOO_SUPPORT)
+ void foo();
+ %End
+
+
+.. directive:: %GCClearCode
+
+.. parsed-literal::
+
+ %GCClearCode
+ *code*
+ %End
+
+Python has a cyclic garbage collector which can identify and release unneeded
+objects even when their reference counts are not zero. If a wrapped C
+structure or C++ class keeps its own reference to a Python object then, if the
+garbage collector is to do its job, it needs to provide some handwritten code
+to traverse and potentially clear those embedded references.
+
+See the section *Supporting cyclic garbage collection* in `Embedding and
+Extending the Python Interpreter <http://www.python.org/dev/doc/devel/ext/>`__
+for the details.
+
+This directive is used to specify the code that clears any embedded references.
+(See :directive:`%GCTraverseCode` for specifying the code that traverses any
+embedded references.)
+
+The following variables are made available to the handwritten code:
+
+*type* \*sipCpp
+ This is a pointer to the structure or class instance. Its *type* is a
+ pointer to the structure or class.
+
+int sipRes
+ The handwritten code should set this to the result to be returned.
+
+The following simplified example is taken from PyQt. The ``QCustomEvent``
+class allows arbitary data to be attached to the event. In PyQt this data is
+always a Python object and so should be handled by the garbage collector::
+
+ %GCClearCode
+ PyObject *obj;
+
+ // Get the object.
+ obj = reinterpret_cast<PyObject *>(sipCpp->data());
+
+ // Clear the pointer.
+ sipCpp->setData(0);
+
+ // Clear the reference.
+ Py_XDECREF(obj);
+
+ // Report no error.
+ sipRes = 0;
+ %End
+
+
+.. directive:: %GCTraverseCode
+
+.. parsed-literal::
+
+ %GCTraverseCode
+ *code*
+ %End
+
+This directive is used to specify the code that traverses any embedded
+references for Python's cyclic garbage collector. (See
+:directive:`%GCClearCode` for a full explanation.)
+
+The following variables are made available to the handwritten code:
+
+*type* \*sipCpp
+ This is a pointer to the structure or class instance. Its *type* is a
+ pointer to the structure or class.
+
+visitproc sipVisit
+ This is the visit function provided by the garbage collector.
+
+void \*sipArg
+ This is the argument to the visit function provided by the garbage
+ collector.
+
+int sipRes
+ The handwritten code should set this to the result to be returned.
+
+The following simplified example is taken from PyQt's ``QCustomEvent`` class::
+
+ %GCTraverseCode
+ PyObject *obj;
+
+ // Get the object.
+ obj = reinterpret_cast<PyObject *>(sipCpp->data());
+
+ // Call the visit function if there was an object.
+ if (obj)
+ sipRes = sipVisit(obj, sipArg);
+ else
+ sipRes = 0;
+ %End
+
+
+.. directive:: %GetCode
+
+.. parsed-literal::
+
+ %GetCode
+ *code*
+ %End
+
+This directive is used after the declaration of a C++ class variable or C
+structure member to specify handwritten code to convert it to a Python object.
+It is usually used to handle types that SIP cannot deal with automatically.
+
+The following variables are made available to the handwritten code:
+
+*type* \*sipCpp
+ This is a pointer to the structure or class instance. Its *type* is a
+ pointer to the structure or class. It is not made available if the
+ variable being wrapped is a static class variable.
+
+PyObject \*sipPy
+ The handwritten code must set this to the Python representation of the
+ class variable or structure member. If there is an error then the code
+ must raise an exception and set this to ``NULL``.
+
+PyObject \*sipPyType
+ If the variable being wrapped is a static class variable then this is the
+ Python type object of the class from which the variable was referenced
+ (*not* the class in which it is defined). It may be safely cast to a
+ PyTypeObject \* or a sipWrapperType \*.
+
+For example::
+
+ struct Entity
+ {
+ /*
+ * In this contrived example the C library we are wrapping actually
+ * defines this as char buffer[100] which SIP cannot handle
+ * automatically.
+ */
+ char *buffer;
+ %GetCode
+ sipPy = PyString_FromStringAndSize(sipCpp->buffer, 100);
+ %End
+ %SetCode
+ char *ptr;
+ int length;
+
+ if (PyString_AsStringAndSize(sipPy, &ptr, &length) == -1)
+ sipErr = 1;
+ else if (length != 100)
+ {
+ /*
+ * Raise an exception because the length isn't exactly right.
+ */
+
+ PyErr_SetString(PyExc_ValueError, "an Entity.buffer must be exactly 100 bytes");
+ sipErr = 1;
+ }
+ else
+ memcpy(sipCpp->buffer, ptr, 100);
+ %End
+ }
+
+
+.. directive:: %If
+
+.. parsed-literal::
+
+ %If (*expression*)
+ *specification*
+ %End
+
+where
+
+.. parsed-literal::
+
+ *expression* ::= [*ored-qualifiers* | *range*]
+
+ *ored-qualifiers* ::= [*qualifier* | *qualifier* **||** *ored-qualifiers*]
+
+ *qualifier* ::= [**!**] [*feature* | *platform*]
+
+ *range* ::= [*version*] **-** [*version*]
+
+This directive is used in conjunction with features (see
+:directive:`%Feature`), platforms (see :directive:`%Platforms`) and versions
+(see :directive:`%Timeline`) to control whether or not parts of a specification
+are processed or not.
+
+A *range* of versions means all versions starting with the lower bound up to
+but excluding the upper bound. If the lower bound is omitted then it is
+interpreted as being before the earliest version. If the upper bound is
+omitted then it is interpreted as being after the latest version.
+
+For example::
+
+ %Feature SUPPORT_FOO
+ %Platforms {WIN32_PLATFORM POSIX_PLATFORM MACOS_PLATFORM}
+ %Timeline {V1_0 V1_1 V2_0 V3_0}
+
+ %If (!SUPPORT_FOO)
+ // Process this if the SUPPORT_FOO feature is disabled.
+ %End
+
+ %If (POSIX_PLATFORM || MACOS_PLATFORM)
+ // Process this if either the POSIX_PLATFORM or MACOS_PLATFORM
+ // platforms are enabled.
+ %End
+
+ %If (V1_0 - V2_0)
+ // Process this if either V1_0 or V1_1 is enabled.
+ %End
+
+ %If (V2_0 - )
+ // Process this if either V2_0 or V3_0 is enabled.
+ %End
+
+ %If ( - )
+ // Always process this.
+ %End
+
+Note that this directive is not implemented as a preprocessor. Only the
+following parts of a specification are affected by it:
+
+ - :directive:`%API`
+ - ``class``
+ - :directive:`%ConvertFromTypeCode`
+ - :directive:`%ConvertToSubClassCode`
+ - :directive:`%ConvertToTypeCode`
+ - ``enum``
+ - :directive:`%DefaultEncoding`
+ - :directive:`%DefaultMetatype`
+ - :directive:`%DefaultSupertype`
+ - :directive:`%ExportedHeaderCode`
+ - functions
+ - :directive:`%GCClearCode`
+ - :directive:`%GCTraverseCode`
+ - :directive:`%If`
+ - :directive:`%InitialisationCode`
+ - :directive:`%MappedType`
+ - :directive:`%MethodCode`
+ - :directive:`%ModuleCode`
+ - :directive:`%ModuleHeaderCode`
+ - ``namespace``
+ - :directive:`%PostInitialisationCode`
+ - :directive:`%PreInitialisationCode`
+ - ``struct``
+ - ``typedef``
+ - :directive:`%TypeCode`
+ - :directive:`%TypeHeaderCode`
+ - :directive:`%UnitCode`
+ - variables
+ - :directive:`%VirtualCatcherCode`
+
+Also note that the only way to specify the logical and of qualifiers is to use
+nested :directive:`%If` directives.
+
+
+.. directive:: %Import
+
+.. parsed-literal::
+
+ %Import *filename*
+
+This directive is used to import the specification of another module. This is
+needed if the current module makes use of any types defined in the imported
+module, e.g. as an argument to a function, or to sub-class.
+
+If *filename* cannot be opened then SIP prepends *filename* with the name of
+the directory containing the current specification file (i.e. the one
+containing the :directive:`%Import` directive) and tries again. If this also
+fails then SIP prepends *filename* with each of the directories, in turn,
+specified by the ``-I`` command line option.
+
+For example::
+
+ %Import qt/qtmod.sip
+
+
+.. directive:: %Include
+
+.. parsed-literal::
+
+ %Include *filename*
+
+This directive is used to include contents of another file as part of the
+specification of the current module. It is the equivalent of the C
+preprocessor's ``#include`` directive and is used to structure a large module
+specification into manageable pieces.
+
+:directive:`%Include` follows the same search process as :directive:`%Import`
+when trying to open *filename*.
+
+For example::
+
+ %Include qwidget.sip
+
+
+.. directive:: %InitialisationCode
+
+.. parsed-literal::
+
+ %InitialisationCode
+ *code*
+ %End
+
+This directive is used to specify handwritten code that is embedded in-line
+in the generated module initialisation code after the SIP module has been
+imported but before the module itself has been initialised.
+
+It is typically used to call :cfunc:`sipRegisterPyType()`.
+
+For example::
+
+ %InitialisationCode
+ // The code will be executed when the module is first imported, after
+ // the SIP module has been imported, but before other module-specific
+ // initialisation has been completed.
+ %End
+
+
+.. directive:: %License
+
+.. parsed-literal::
+
+ %License /*license-annotations*/
+
+This directive is used to specify the contents of an optional license
+dictionary. The license dictionary is called :data:`__license__` and is stored
+in the module dictionary. The elements of the dictionary are specified using
+the :lanno:`Licensee`, :lanno:`Signature`, :lanno:`Timestamp` and :lanno:`Type`
+annotations. Only the :lanno:`Type` annotation is compulsory.
+
+Note that this directive isn't an attempt to impose any licensing restrictions
+on a module. It is simply a method for easily embedding licensing information
+in a module so that it is accessible to Python scripts.
+
+For example::
+
+ %License /Type="GPL"/
+
+
+.. directive:: %MappedType
+
+.. parsed-literal::
+
+ template<*type-list*>
+ %MappedType *type*
+ {
+ [*header-code*]
+ [*convert-to-code*]
+ [*convert-from-code*]
+ };
+
+ %MappedType *type*
+ {
+ [*header-code*]
+ [*convert-to-code*]
+ [*convert-from-code*]
+ };
+
+This directive is used to define an automatic mapping between a C or C++ type
+and a Python type. It can be used as part of a template, or to map a specific
+type.
+
+When used as part of a template *type* cannot itself refer to a template. Any
+occurrences of any of the type names (but not any ``*`` or ``&``) in
+*type-list* will be replaced by the actual type names used when the template is
+instantiated. Template mapped types are instantiated automatically as required
+(unlike template classes which are only instantiated using ``typedef``).
+
+Any explicit mapped type will be used in preference to any template that maps
+the same type, ie. a template will not be automatically instantiated if there
+is an explicit mapped type.
+
+*header-code* is the :directive:`%TypeHeaderCode` used to specify the library
+interface to the type being mapped.
+
+*convert-to-code* is the :directive:`%ConvertToTypeCode` used to specify the
+handwritten code that converts a Python object to an instance of the mapped
+type.
+
+*convert-from-code* is the :directive:`%ConvertFromTypeCode` used to specify
+the handwritten code that converts an instance of the mapped type to a Python
+object.
+
+For example::
+
+ template<Type *>
+ %MappedType QList
+ {
+ %TypeHeaderCode
+ // Include the library interface to the type being mapped.
+ #include <qlist.h>
+ %End
+
+ %ConvertToTypeCode
+ // See if we are just being asked to check the type of the Python
+ // object.
+ if (sipIsErr == NULL)
+ {
+ // Check it is a list.
+ if (!PyList_Check(sipPy))
+ return 0;
+
+ // Now check each element of the list is of the type we expect.
+ // The template is for a pointer type so we don't disallow None.
+ for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i)
+ if (!sipCanConvertToType(PyList_GET_ITEM(sipPy, i),
+ sipType_Type, 0))
+ return 0;
+
+ return 1;
+ }
+
+ // Create the instance on the heap.
+ QList<Type *> *ql = new QList<Type *>;
+
+ for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i)
+ {
+ // Use the SIP API to convert the Python object to the
+ // corresponding C++ instance. Note that we apply any ownership
+ // transfer to the list itself, not the individual elements.
+ Type *t = reinterpret_cast<Type *>(sipConvertToType(
+ PyList_GET_ITEM(sipPy, i),
+ sipType_Type, 0, 0, 0,
+ sipIsErr));
+
+ if (*sipIsErr)
+ {
+ // Tidy up.
+ delete ql;
+
+ // There is nothing on the heap.
+ return 0;
+ }
+
+ // Add the pointer to the C++ instance.
+ ql->append(t);
+ }
+
+ // Return the instance on the heap.
+ *sipCppPtr = ql;
+
+ // Apply the normal transfer.
+ return sipGetState(sipTransferObj);
+ %End
+
+ %ConvertFromTypeCode
+ PyObject *l;
+
+ // Create the Python list of the correct length.
+ if ((l = PyList_New(sipCpp->size())) == NULL)
+ return NULL;
+
+ // Go through each element in the C++ instance and convert it to the
+ // corresponding Python object.
+ for (int i = 0; i < sipCpp->size(); ++i)
+ {
+ Type *t = sipCpp->at(i);
+ PyObject *tobj;
+
+ if ((tobj = sipConvertFromType(t, sipType_Type, sipTransferObj)) == NULL)
+ {
+ // There was an error so garbage collect the Python list.
+ Py_DECREF(l);
+ return NULL;
+ }
+
+ PyList_SET_ITEM(l, i, tobj);
+ }
+
+ // Return the Python list.
+ return l;
+ %End
+ }
+
+Using this we can use, for example, ``QList<QObject *>`` throughout the
+module's specification files (and in any module that imports this one). The
+generated code will automatically map this to and from a Python list of QObject
+instances when appropriate.
+
+
+.. directive:: %MethodCode
+
+.. parsed-literal::
+
+ %MethodCode
+ *code*
+ %End
+
+This directive is used as part of the specification of a global function, class
+method, operator, constructor or destructor to specify handwritten code that
+replaces the normally generated call to the function being wrapped. It is
+usually used to handle argument types and results that SIP cannot deal with
+automatically.
+
+Normally the specified code is embedded in-line after the function's arguments
+have been successfully converted from Python objects to their C or C++
+equivalents. In this case the specified code must not include any ``return``
+statements.
+
+However if the :fanno:`NoArgParser` annotation has been used then the specified
+code is also responsible for parsing the arguments. No other code is generated
+by SIP and the specified code must include a ``return`` statement.
+
+In the context of a destructor the specified code is embedded in-line in the
+Python type's deallocation function. Unlike other contexts it supplements
+rather than replaces the normally generated code, so it must not include code
+to return the C structure or C++ class instance to the heap. The code is only
+called if ownership of the structure or class is with Python.
+
+The specified code must also handle the Python Global Interpreter Lock (GIL).
+If compatibility with SIP v3.x is required then the GIL must be released
+immediately before the C++ call and reacquired immediately afterwards as shown
+in this example fragment::
+
+ Py_BEGIN_ALLOW_THREADS
+ sipCpp->foo();
+ Py_END_ALLOW_THREADS
+
+If compatibility with SIP v3.x is not required then this is optional but
+should be done if the C++ function might block the current thread or take a
+significant amount of time to execute. (See :ref:`ref-gil` and the
+:fanno:`ReleaseGIL` and :fanno:`HoldGIL` annotations.)
+
+If the :fanno:`NoArgParser` annotation has not been used then the following
+variables are made available to the handwritten code:
+
+*type* a0
+ There is a variable for each argument of the Python signature (excluding
+ any ``self`` argument) named ``a0``, ``a1``, etc. The *type* of the
+ variable is the same as the type defined in the specification with the
+ following exceptions:
+
+ - if the argument is only used to return a value (e.g. it is an ``int *``
+ without an :aanno:`In` annotation) then the type has one less level of
+ indirection (e.g. it will be an ``int``)
+ - if the argument is a structure or class (or a reference or a pointer to a
+ structure or class) then *type* will always be a pointer to the structure
+ or class.
+
+ Note that handwritten code for destructors never has any arguments.
+
+PyObject \*a0Wrapper
+ This variable is made available only if the :aanno:`GetWrapper` annotation
+ is specified for the corresponding argument. The variable is a pointer to
+ the Python object that wraps the argument.
+
+*type* \*sipCpp
+ If the directive is used in the context of a class constructor then this
+ must be set by the handwritten code to the constructed instance. If it is
+ set to ``0`` and no Python exception is raised then SIP will continue to
+ try other Python signatures.
+
+ If the directive is used in the context of a method (but not the standard
+ binary operator methods, e.g. :meth:`__add__`) or a destructor then this is
+ a pointer to the C structure or C++ class instance.
+
+ Its *type* is a pointer to the structure or class.
+
+ Standard binary operator methods follow the same convention as global
+ functions and instead define two arguments called ``a0`` and ``a1``.
+
+sipErrorState sipError
+ The handwritten code should set this to either ``sipErrorContinue`` or
+ ``sipErrorFail``, and raise an appropriate Python exception, if an error
+ is detected. Its initial value will be ``sipErrorNone``.
+
+ When ``sipErrorContinue`` is used, SIP will remember the exception as the
+ reason why the particular overloaded callable could not be invoked. It
+ will then continue to try the next overloaded callable. It is typically
+ used by code that needs to do additional type checking of the callable's
+ arguments.
+
+ When ``sipErrorFail1`` is used, SIP will report the exception immediately
+ and will not attempt to invoke other overloaded callables.
+
+ ``sipError`` is not provided for destructors.
+
+int sipIsErr
+ The handwritten code should set this to a non-zero value, and raise an
+ appropriate Python exception, if an error is detected. This is the
+ equivalent of setting ``sipError`` to ``sipErrorFail``. Its initial value
+ will be ``0``.
+
+ ``sipIsErr`` is not provided for destructors.
+
+*type* sipRes
+ The handwritten code should set this to the result to be returned. The
+ *type* of the variable is the same as the type defined in the Python
+ signature in the specification with the following exception:
+
+ - if the argument is a structure or class (or a reference or a pointer to a
+ structure or class) then *type* will always be a pointer to the structure
+ or class.
+
+ ``sipRes`` is not provided for inplace operators (e.g. ``+=`` or
+ :meth:`__imul__`) as their results are handled automatically, nor for class
+ constructors or destructors.
+
+PyObject \*sipSelf
+ If the directive is used in the context of a class constructor, destructor
+ or method then this is the Python object that wraps the structure or class
+ instance, i.e. ``self``.
+
+bool sipSelfWasArg
+ This is only made available for non-abstract, virtual methods. It is set
+ if ``self`` was explicitly passed as the first argument of the method
+ rather than being bound to the method. In other words, the call was::
+
+ Klass.foo(self, ...)
+
+ rather than::
+
+ self.foo(...)
+
+If the :fanno:`NoArgParser` annotation has been used then only the following
+variables are made available to the handwritten code:
+
+PyObject \*sipArgs
+ This is the tuple of arguments.
+
+PyObject \*sipKwds
+ This is the dictionary of keyword arguments.
+
+The following is a complete example::
+
+ class Klass
+ {
+ public:
+ virtual int foo(SIP_PYTUPLE);
+ %MethodCode
+ // The C++ API takes a 2 element array of integers but passing a
+ // two element tuple is more Pythonic.
+
+ int iarr[2];
+
+ if (PyArg_ParseTuple(a0, "ii", &iarr[0], &iarr[1]))
+ {
+ Py_BEGIN_ALLOW_THREADS
+ sipRes = sipSelfWasArg ? sipCpp->Klass::foo(iarr)
+ : sipCpp->foo(iarr);
+ Py_END_ALLOW_THREADS
+ }
+ else
+ {
+ // PyArg_ParseTuple() will have raised the exception.
+ sipIsErr = 1;
+ }
+ %End
+ };
+
+As the example is a virtual method [#]_, note the use of ``sipSelfWasArg`` to
+determine exactly which implementation of ``foo()`` to call.
+
+If a method is in the ``protected`` section of a C++ class then SIP generates
+helpers that provide access to method. However, these are not available if
+the Python module is being built with ``protected`` redefined as ``public``.
+
+The following pattern should be used to cover all possibilities::
+
+ #if defined(SIP_PROTECTED_IS_PUBLIC)
+ sipRes = sipSelfWasArg ? sipCpp->Klass::foo(iarr)
+ : sipCpp->foo(iarr);
+ #else
+ sipRes = sipCpp->sipProtectVirt_foo(sipSelfWasArg, iarr);
+ #endif
+
+If a method is in the ``protected`` section of a C++ class but is not virtual
+then the pattern should instead be::
+
+ #if defined(SIP_PROTECTED_IS_PUBLIC)
+ sipRes = sipCpp->foo(iarr);
+ #else
+ sipRes = sipCpp->sipProtect_foo(iarr);
+ #endif
+
+.. [#] See :directive:`%VirtualCatcherCode` for a description of how SIP
+ generated code handles the reimplementation of C++ virtual methods in
+ Python.
+
+
+.. directive:: %Module
+
+.. parsed-literal::
+
+ %Module *name* [*version*]
+
+This directive is used to identify that the library being wrapped is a C++
+library and to define the name of the module and it's optional version number.
+
+The name may contain periods to specify that the module is part of a Python
+package.
+
+The optional version number is useful if you (or others) might create other
+modules that build on this module, i.e. if another module might
+:directive:`%Import` this module. Under the covers, a module exports an API
+that is used by modules that :directive:`%Import` it and the API is given a
+version number. A module built on that module knows the version number of the
+API that it is expecting. If, when the modules are imported at run-time, the
+version numbers do not match then a Python exception is raised. The dependent
+module must then be re-built using the correct specification files for the base
+module.
+
+The version number should be incremented whenever a module is changed. Some
+changes don't affect the exported API, but it is good practice to change the
+version number anyway.
+
+For example::
+
+ %Module qt 5
+
+
+.. directive:: %ModuleCode
+
+.. parsed-literal::
+
+ %ModuleCode
+ *code*
+ %End
+
+This directive is used to specify handwritten code, typically the
+implementations of utility functions, that can be called by other handwritten
+code in the module.
+
+For example::
+
+ %ModuleCode
+ // Print an object on stderr for debugging purposes.
+ void dump_object(PyObject *o)
+ {
+ PyObject_Print(o, stderr, 0);
+ fprintf(stderr, "\n");
+ }
+ %End
+
+See also :directive:`%ExportedHeaderCode` and :directive:`%ModuleHeaderCode`.
+
+
+.. directive:: %ModuleHeaderCode
+
+.. parsed-literal::
+
+ %ModuleHeaderCode
+ *code*
+ %End
+
+This directive is used to specify handwritten code, typically the declarations
+of utility functions, that is placed in a header file that is included by all
+generated code for the same module.
+
+For example::
+
+ %ModuleHeaderCode
+ void dump_object(PyObject *o);
+ %End
+
+See also :directive:`%ExportedHeaderCode` and :directive:`%ModuleCode`.
+
+
+.. directive:: %OptionalInclude
+
+.. parsed-literal::
+
+ %OptionalInclude *filename*
+
+This directive is identical to the :directive:`%Include` directive except that
+SIP silently continues processing if *filename* could not be opened.
+
+For example::
+
+ %OptionalInclude license.sip
+
+
+.. directive:: %PickleCode
+
+.. parsed-literal::
+
+ %PickleCode
+ *code*
+ %End
+
+This directive is used to specify handwritten code to pickle a C structure or
+C++ class instance.
+
+The following variables are made available to the handwritten code:
+
+*type* \*sipCpp
+ This is a pointer to the structure or class instance. Its *type* is a
+ pointer to the structure or class.
+
+PyObject \*sipRes
+ The handwritten code must set this to a tuple of the arguments that will
+ be passed to the type's __init__() method when the structure or class
+ instance is unpickled. If there is an error then the code must raise an
+ exception and set this to ``NULL``.
+
+For example::
+
+ class Point
+ {
+ Point(int x, y);
+
+ int x() const;
+ int y() const;
+
+ %PickleCode
+ sipRes = Py_BuildValue("ii", sipCpp->x(), sipCpp->y());
+ %End
+ }
+
+Note that SIP works around the Python limitation that prevents nested types
+being pickled.
+
+Both named and unnamed enums can be pickled automatically without providing any
+handwritten code.
+
+
+.. directive:: %Platforms
+
+.. parsed-literal::
+
+ %Platforms {*name* *name* ...}
+
+This directive is used to declare a set of platforms. Platforms (along with
+:directive:`%Feature` and :directive:`%Timeline`) are used by the
+:directive:`%If` directive to control whether or not parts of a specification
+are processed or ignored.
+
+Platforms are mutually exclusive - only one platform can be enabled at a time.
+By default all platforms are disabled. The SIP ``-t`` command line option is
+used to enable a platform.
+
+For example::
+
+ %Platforms {WIN32_PLATFORM POSIX_PLATFORM MACOS_PLATFORM}
+
+ %If (WIN32_PLATFORM)
+ void undocumented();
+ %End
+
+ %If (POSIX_PLATFORM)
+ void documented();
+ %End
+
+
+.. directive:: %PostInitialisationCode
+
+.. parsed-literal::
+
+ %PostInitialisationCode
+ *code*
+ %End
+
+This directive is used to specify handwritten code that is embedded in-line
+at the very end of the generated module initialisation code.
+
+The following variables are made available to the handwritten code:
+
+PyObject \*sipModule
+ This is the module object returned by ``Py_InitModule()``.
+
+PyObject \*sipModuleDict
+ This is the module's dictionary object returned by ``Py_ModuleGetDict()``.
+
+For example::
+
+ %PostInitialisationCode
+ // The code will be executed when the module is first imported and
+ // after all other initialisation has been completed.
+ %End
+
+
+.. directive:: %PreInitialisationCode
+
+.. parsed-literal::
+
+ %PreInitialisationCode
+ *code*
+ %End
+
+This directive is used to specify handwritten code that is embedded in-line
+at the very start of the generated module initialisation code.
+
+For example::
+
+ %PreInitialisationCode
+ // The code will be executed when the module is first imported and
+ // before other initialisation has been completed.
+ %End
+
+
+.. directive:: %RaiseCode
+
+.. parsed-literal::
+
+ %RaiseCode
+ *code*
+ %End
+
+This directive is used as part of the definition of an exception using the
+:directive:`%Exception` directive to specify handwritten code that raises a
+Python exception when a C++ exception has been caught. The code is embedded
+in-line as the body of a C++ ``catch ()`` clause.
+
+The specified code must handle the Python Global Interpreter Lock (GIL) if
+necessary. The GIL must be acquired before any calls to the Python API and
+released after the last call as shown in this example fragment::
+
+ SIP_BLOCK_THREADS
+ PyErr_SetNone(PyErr_Exception);
+ SIP_UNBLOCK_THREADS
+
+Finally, the specified code must not include any ``return`` statements.
+
+The following variable is made available to the handwritten code:
+
+*type* &sipExceptionRef
+ This is a reference to the caught C++ exception. The *type* of the
+ reference is the same as the type defined in the ``throw ()`` specifier.
+
+See the :directive:`%Exception` directive for an example.
+
+
+.. directive:: %SetCode
+
+.. parsed-literal::
+
+ %SetCode
+ *code*
+ %End
+
+This directive is used after the declaration of a C++ class variable or C
+structure member to specify handwritten code to convert it from a Python
+object. It is usually used to handle types that SIP cannot deal with
+automatically.
+
+The following variables are made available to the handwritten code:
+
+*type* \*sipCpp
+ This is a pointer to the structure or class instance. Its *type* is a
+ pointer to the structure or class. It is not made available if the
+ variable being wrapped is a static class variable.
+
+int sipErr
+ If the conversion failed then the handwritten code should raise a Python
+ exception and set this to a non-zero value. Its initial value will be
+ automatically set to zero.
+
+PyObject \*sipPy
+ This is the Python object that the handwritten code should convert.
+
+PyObject \*sipPyType
+ If the variable being wrapped is a static class variable then this is the
+ Python type object of the class from which the variable was referenced
+ (*not* the class in which it is defined). It may be safely cast to a
+ PyTypeObject \* or a sipWrapperType \*.
+
+See the :directive:`%GetCode` directive for an example.
+
+
+.. directive:: %Timeline
+
+.. parsed-literal::
+
+ %Timeline {*name* *name* ...}
+
+This directive is used to declare a set of versions released over a period of
+time. Versions (along with :directive:`%Feature` and :directive:`%Platforms`)
+are used by the :directive:`%If` directive to control whether or not parts of a
+specification are processed or ignored.
+
+Versions are mutually exclusive - only one version can be enabled at a time.
+By default all versions are disabled. The SIP ``-t`` command line option is
+used to enable a version.
+
+For example::
+
+ %Timeline {V1_0 V1_1 V2_0 V3_0}
+
+ %If (V1_0 - V2_0)
+ void foo();
+ %End
+
+ %If (V2_0 -)
+ void foo(int = 0);
+ %End
+
+:directive:`%Timeline` can be used any number of times in a module to allow
+multiple libraries to be wrapped in the same module.
+
+
+.. directive:: %TypeCode
+
+.. parsed-literal::
+
+ %TypeCode
+ *code*
+ %End
+
+This directive is used as part of the specification of a C structure or a C++
+class to specify handwritten code, typically the implementations of utility
+functions, that can be called by other handwritten code in the structure or
+class.
+
+For example::
+
+ class Klass
+ {
+ %TypeCode
+ // Print an instance on stderr for debugging purposes.
+ static void dump_klass(const Klass *k)
+ {
+ fprintf(stderr,"Klass %s at %p\n", k->name(), k);
+ }
+ %End
+
+ // The rest of the class specification.
+
+ };
+
+Because the scope of the code is normally within the generated file that
+implements the type, any utility functions would normally be declared
+``static``. However a naming convention should still be adopted to prevent
+clashes of function names within a module in case the SIP ``-j`` command line
+option is used.
+
+
+.. directive:: %TypeHeaderCode
+
+.. parsed-literal::
+
+ %TypeHeaderCode
+ *code*
+ %End
+
+This directive is used to specify handwritten code that defines the interface
+to a C or C++ type being wrapped, either a structure, a class, or a template.
+It is used within a class definition or a :directive:`%MappedType` directive.
+
+Normally *code* will be a pre-processor ``#include`` statement.
+
+For example::
+
+ // Wrap the Klass class.
+ class Klass
+ {
+ %TypeHeaderCode
+ #include <klass.h>
+ %End
+
+ // The rest of the class specification.
+ };
+
+
+.. directive:: %UnitCode
+
+.. parsed-literal::
+
+ %UnitCode
+ *code*
+ %End
+
+This directive is used to specify handwritten code that it included at the very
+start of a generated compilation unit (ie. C or C++ source file). It is
+typically used to ``#include`` a C++ precompiled header file.
+
+
+.. directive:: %VirtualCatcherCode
+
+.. parsed-literal::
+
+ %VirtualCatcherCode
+ *code*
+ %End
+
+For most classes there are corresponding :ref:`generated derived classes
+<ref-derived-classes>` that contain reimplementations of the class's virtual
+methods. These methods (which SIP calls catchers) determine if there is a
+corresponding Python reimplementation and call it if so. If there is no Python
+reimplementation then the method in the original class is called instead.
+
+This directive is used to specify handwritten code that replaces the normally
+generated call to the Python reimplementation and the handling of any returned
+results. It is usually used to handle argument types and results that SIP
+cannot deal with automatically.
+
+This directive can also be used in the context of a class destructor to
+specify handwritten code that is embedded in-line in the internal derived
+class's destructor.
+
+In the context of a method the Python Global Interpreter Lock (GIL) is
+automatically acquired before the specified code is executed and automatically
+released afterwards.
+
+In the context of a destructor the specified code must handle the GIL. The
+GIL must be acquired before any calls to the Python API and released after the
+last call as shown in this example fragment::
+
+ SIP_BLOCK_THREADS
+ Py_DECREF(obj);
+ SIP_UNBLOCK_THREADS
+
+The following variables are made available to the handwritten code in the
+context of a method:
+
+*type* a0
+ There is a variable for each argument of the C++ signature named ``a0``,
+ ``a1``, etc. The *type* of the variable is the same as the type defined in
+ the specification.
+
+int a0Key
+ There is a variable for each argument of the C++ signature that has a type
+ where it is important to ensure that the corresponding Python object is not
+ garbage collected too soon. This only applies to output arguments that
+ return ``'\0'`` terminated strings. The variable would normally be passed
+ to :cfunc:`sipParseResult()` using either the ``A`` or ``B`` format
+ characters.
+
+int sipIsErr
+ The handwritten code should set this to a non-zero value, and raise an
+ appropriate Python exception, if an error is detected.
+
+PyObject \*sipMethod
+ This object is the Python reimplementation of the virtual C++ method. It
+ is normally passed to :cfunc:`sipCallMethod()`.
+
+*type* sipRes
+ The handwritten code should set this to the result to be returned. The
+ *type* of the variable is the same as the type defined in the C++ signature
+ in the specification.
+
+int sipResKey
+ This variable is only made available if the result has a type where it is
+ important to ensure that the corresponding Python object is not garbage
+ collected too soon. This only applies to ``'\0'`` terminated strings. The
+ variable would normally be passed to :cfunc:`sipParseResult()` using either
+ the ``A`` or ``B`` format characters.
+
+sipSimpleWrapper \*sipPySelf
+ This variable is only made available if either the ``a0Key`` or
+ ``sipResKey`` are made available. It defines the context within which keys
+ are unique. The variable would normally be passed to
+ :cfunc:`sipParseResult()` using the ``S`` format character.
+
+No variables are made available in the context of a destructor.
+
+For example::
+
+ class Klass
+ {
+ public:
+ virtual int foo(SIP_PYTUPLE) [int (int *)];
+ %MethodCode
+ // The C++ API takes a 2 element array of integers but passing a
+ // two element tuple is more Pythonic.
+
+ int iarr[2];
+
+ if (PyArg_ParseTuple(a0, "ii", &iarr[0], &iarr[1]))
+ {
+ Py_BEGIN_ALLOW_THREADS
+ sipRes = sipCpp->Klass::foo(iarr);
+ Py_END_ALLOW_THREADS
+ }
+ else
+ {
+ // PyArg_ParseTuple() will have raised the exception.
+ sipIsErr = 1;
+ }
+ %End
+ %VirtualCatcherCode
+ // Convert the 2 element array of integers to the two element
+ // tuple.
+
+ PyObject *result;
+
+ result = sipCallMethod(&sipIsErr, sipMethod, "ii", a0[0], a0[1]);
+
+ if (result != NULL)
+ {
+ // Convert the result to the C++ type.
+ sipParseResult(&sipIsErr, sipMethod, result, "i", &sipRes);
+
+ Py_DECREF(result);
+ }
+ %End
+ };
diff --git a/sphinx/distutils.rst b/sphinx/distutils.rst
new file mode 100644
index 0000000..21a6b36
--- /dev/null
+++ b/sphinx/distutils.rst
@@ -0,0 +1,41 @@
+.. _ref-distutils:
+
+Building Your Extension with distutils
+======================================
+
+To build the example in :ref:`ref-simple-c++-example` using distutils, it is
+sufficient to create a standard ``setup.py``, listing ``word.sip`` among the
+files to build, and hook-up SIP into distutils::
+
+ from distutils.core import setup, Extension
+ import sipdistutils
+
+ setup(
+ name = 'word',
+ versione = '1.0',
+ ext_modules=[
+ Extension("word", ["word.sip", "word.cpp"]),
+ ],
+
+ cmdclass = {'build_ext': sipdistutils.build_ext}
+ )
+
+As we can see, the above is a normal distutils setup script, with just a
+special line which is needed so that SIP can see and process ``word.sip``.
+Then, running ``setup.py build`` will build our extension module.
+
+If you want to use any of sip's command-line options described in
+:ref:`ref-command-line`, there is a new option available for the
+``build_ext`` command in distutils: ``--sip-opts``. So you can either invoke
+distutils as follows::
+
+ $ python setup.py build_ext --sip-opts="-e -g" build
+
+or you can leverage distutils' config file support by creating a ``setup.cfg``
+file in the supported system or local paths (eg: in the same directory of
+``setup.py``) with these contents::
+
+ [build_ext]
+ sip-opts = -e -g
+
+and then run ``setup.py build`` as usual.
diff --git a/sphinx/embedding.rst b/sphinx/embedding.rst
new file mode 100644
index 0000000..114e3e8
--- /dev/null
+++ b/sphinx/embedding.rst
@@ -0,0 +1,62 @@
+Using the C API when Embedding
+==============================
+
+The :ref:`C API <ref-c-api>` is intended to be called from handwritten code in
+SIP generated modules. However it is also often necessary to call it from C or
+C++ applications that embed the Python interpreter and need to pass C or C++
+instances between the application and the interpreter.
+
+The API is exported by the SIP module as a ``sipAPIDef`` data structure
+containing a set of function pointers. The data structure is defined in the
+SIP header file ``sip.h``. The data structure is wrapped as a Python
+``PyCObject`` object and is referenced by the name ``_C_API`` in the SIP
+module dictionary.
+
+Each member of the data structure is a pointer to one of the functions of the
+SIP API. The name of the member can be derived from the function name by
+replacing the ``sip`` prefix with ``api`` and converting each word in the
+name to lower case and preceding it with an underscore. For example:
+
+ ``sipExportSymbol`` becomes ``api_export_symbol``
+
+ ``sipWrapperCheck`` becomes ``api_wrapper_check``
+
+Note that the type objects that SIP generates for a wrapped module (see
+:ref:`ref-type-structures`, :ref:`ref-enum-type-objects` and
+:ref:`ref-exception-objects`) cannot be refered to directly and must be
+obtained using the :cfunc:`sipFindType()` function. Of course, the
+corresponding modules must already have been imported into the interpreter.
+
+The following code fragment shows how to get a pointer to the ``sipAPIDef``
+data structure::
+
+ #include <sip.h>
+
+ const sipAPIDef *get_sip_api()
+ {
+ PyObject *sip_module;
+ PyObject *sip_module_dict;
+ PyObject *c_api;
+
+ /* Import the SIP module. */
+ sip_module = PyImport_ImportModule("sip");
+
+ if (sip_module == NULL)
+ return NULL;
+
+ /* Get the module's dictionary. */
+ sip_module_dict = PyModule_GetDict(sip_module);
+
+ /* Get the "_C_API" attribute. */
+ c_api = PyDict_GetItemString(sip_module_dict, "_C_API");
+
+ if (c_api == NULL)
+ return NULL;
+
+ /* Sanity check that it is the right type. */
+ if (!PyCObject_Check(c_api))
+ return NULL;
+
+ /* Get the actual pointer from the object. */
+ return (const sipAPIDef *)PyCObject_AsVoidPtr(c_api);
+ }
diff --git a/sphinx/incompatibilities.rst b/sphinx/incompatibilities.rst
new file mode 100644
index 0000000..a006e4f
--- /dev/null
+++ b/sphinx/incompatibilities.rst
@@ -0,0 +1,198 @@
+Potential Incompatibilities with Earlier Versions
+=================================================
+
+This section describes incompatibilities introduced by particular versions of
+SIP. Normally these are the removal of previously deprecated features.
+
+
+SIP v4.10.1
+-----------
+
+Newly Deprecated Features
+*************************
+
+The following parts of the :ref:`C API <ref-c-api>` are now deprecated (but
+still supported).
+
+- The ``D`` format character of :cfunc:`sipParseResult()`.
+
+
+SIP v4.8
+--------
+
+__truediv__
+***********
+
+Prior to this version the :meth:`__div__` special method implicitly defined the
+:meth:`__truediv__` special method. From this version the :meth:`__truediv__`
+special method must be explicitly defined.
+
+
+sipWrapper user Member
+**********************
+
+Prior to this version the :ctype:`sipWrapper` structure had a member called
+:ctype:`user` which is available for handwritten code to use. From this
+version :ctype:`user` is a member of the :ctype:`sipSimpleWrapper` structure.
+
+:ctype:`sipWrapper` pointers can be safely cast to :ctype:`sipSimpleWrapper`
+pointers, so if your code does something like::
+
+ ((sipWrapper *)obj)->user = an_object_reference;
+
+then you just need to change it to::
+
+ ((sipSimpleWrapper *)obj)->user = an_object_reference;
+
+
+Removal of Previously Deprecated Features
+*****************************************
+
+The following parts of the :ref:`C API <ref-c-api>` have been removed.
+
+- The ``a``, ``A``, ``M``, ``N``, ``O``, ``P`` and ``T`` format characters
+ from :cfunc:`sipBuildResult()` and :cfunc:`sipCallMethod()`.
+
+- The ``a``, ``A``, ``L`` and ``M`` format characters from
+ :cfunc:`sipParseResult()`.
+
+- :cfunc:`sipConvertToCpp()`
+
+- :cfunc:`sipIsSubClassInstance()`
+
+- :cfunc:`sipTransfer()`
+
+- The :func:`transfer` function of the :mod:`sip` module.
+
+- The old-style generated type convertors.
+
+In addition the :option:`-a` command line option to :file:`configure.py` has
+been removed.
+
+
+Removal of PyQt-specific Features
+*********************************
+
+The following PyQt-specific support functions have been removed.
+
+- :cfunc:`sipConnectRx()`
+
+- :cfunc:`sipDisconnectRx()`
+
+- :cfunc:`sipEmitSlot()`
+
+- :cfunc:`sipGetSender()`
+
+
+Newly Deprecated Features
+*************************
+
+The following parts of the :ref:`C API <ref-c-api>` are now deprecated (but
+still supported).
+
+- The :ref:`ref-type-objects`.
+
+- The :ref:`ref-enum-type-objects`.
+
+- :cfunc:`sipConvertFromInstance()`
+
+- :cfunc:`sipConvertFromMappedType()`
+
+- :cfunc:`sipConvertFromNamedEnum()`
+
+- :cfunc:`sipConvertFromNewInstance()`
+
+- :cfunc:`sipCanConvertToInstance()`
+
+- :cfunc:`sipCanConvertToMappedType()`
+
+- :cfunc:`sipConvertToInstance()`
+
+- :cfunc:`sipConvertToMappedType()`
+
+- :cfunc:`sipForceConvertToInstance()`
+
+- :cfunc:`sipForceConvertToMappedType()`
+
+- :cfunc:`sipClassName()`
+
+- :cfunc:`sipFindClass()`
+
+- :cfunc:`sipFindNamedEnum()`
+
+- :cfunc:`sipFindMappedType()`
+
+- :cfunc:`sipGetWrapper()`
+
+- :cfunc:`sipReleaseInstance()`
+
+- :cfunc:`sipReleaseMappedType()`
+
+- :cfunc:`sipWrapper_Check()`
+
+- The ``B``, ``C`` and ``E`` format characters of :cfunc:`sipBuildResult()` and
+ :cfunc:`sipCallMethod()`.
+
+- The ``s``, ``C`` and ``E`` format characters of :cfunc:`sipParseResult()`.
+
+
+SIP v4.7.8
+----------
+
+Automatic int to Enum Conversions
+*********************************
+
+This version allows a Python ``int`` object to be passed whenever an enum is
+expected. This can mean that two signatures that were different with prior
+versions are now the same as far as Python is concerned.
+
+The :aanno:`Constrained` argument annotation can now be applied to an enum
+argument to revert to the earlier behaviour.
+
+
+SIP v4.7.3
+----------
+
+Complementary Comparison Operators
+**********************************
+
+Prior to this version SIP did not automatically generate missing complementary
+comparison operators. Typically this was worked around by adding them
+explicitly to the .sip files, even though they weren't implemented in C++ and
+relied on the C++ compiler calling the complementary operator that was
+implemented.
+
+A necessary change to the code generator meant that this not longer worked and
+so SIP was changed to automatically generate any missing complementary
+operators. If you have added such operators explicitly then you should remove
+them or make them dependent on the particular version of SIP.
+
+
+SIP v4.4
+--------
+
+%ConvertFromTypeCode and %ConvertToTypeCode
+*******************************************
+
+Handwritten :directive:`%ConvertFromTypeCode` and
+:directive:`%ConvertToTypeCode` now have the responsibility for implementing
+the :aanno:`Transfer` and :aanno:`TransferBack` annotations.
+
+
+SIP_BUILD
+*********
+
+The :cmacro:`SIP_BUILD` C preprocessor symbol has been removed.
+
+
+Newly Deprecated Features
+*************************
+
+The following parts of the :ref:`C API <ref-c-api>` are now deprecated (but
+still supported).
+
+- The old-style generated type convertors.
+
+- :cfunc:`sipConvertToCpp()`
+
+- :cfunc:`sipIsSubClassInstance()`
diff --git a/sphinx/index.rst b/sphinx/index.rst
new file mode 100644
index 0000000..ac9289c
--- /dev/null
+++ b/sphinx/index.rst
@@ -0,0 +1,20 @@
+SIP Reference Guide
+===================
+
+.. toctree::
+ :maxdepth: 2
+
+ introduction
+ incompatibilities
+ installation
+ using
+ command_line
+ specification_files
+ directives
+ annotations
+ c_api
+ embedding
+ python_api
+ build_system
+ distutils
+ builtin
diff --git a/sphinx/installation.rst b/sphinx/installation.rst
new file mode 100644
index 0000000..3f9f823
--- /dev/null
+++ b/sphinx/installation.rst
@@ -0,0 +1,169 @@
+Installation
+============
+
+Downloading
+-----------
+
+You can get the latest release of the SIP source code from
+http://www.riverbankcomputing.com/software/sip/download.
+
+SIP is also included with all of the major Linux distributions. However, it
+may be a version or two out of date.
+
+
+Configuring
+-----------
+
+After unpacking the source package (either a ``.tar.gz`` or a ``.zip`` file
+depending on your platform) you should then check for any ``README`` files
+that relate to your platform.
+
+Next you need to configure SIP by executing the ``configure.py`` script. For
+example::
+
+ python configure.py
+
+This assumes that the Python interpreter is on your path. Something like the
+following may be appropriate on Windows::
+
+ c:\python26\python configure.py
+
+If you have multiple versions of Python installed then make sure you use the
+interpreter for which you wish SIP to generate bindings for.
+
+The full set of command line options is:
+
+.. program:: configure.py
+
+.. cmdoption:: --version
+
+ Display the SIP version number.
+
+.. cmdoption:: -h, --help
+
+ Display a help message.
+
+.. cmdoption:: --arch <ARCH>
+
+ Binaries for the MacOS/X architecture ``<ARCH>`` will be built. This
+ option should be given once for each architecture to be built. Specifying
+ more than one architecture will cause a universal binary to be created.
+
+.. cmdoption:: -b <DIR>, --bindir <DIR>
+
+ The SIP code generator will be installed in the directory ``<DIR>``.
+
+.. cmdoption:: -d <DIR>, --destdir <DIR>
+
+ The SIP module will be installed in the directory ``<DIR>``.
+
+.. cmdoption:: -e <DIR>, --incdir <DIR>
+
+ The SIP header file will be installed in the directory ``<DIR>``.
+
+.. cmdoption:: -k, --static
+
+ The SIP module will be built as a static library. This is useful when
+ building the SIP module as a Python builtin (see :ref:`ref-builtin`).
+
+.. cmdoption:: -n, --universal
+
+ The SIP code generator and module will be built as universal binaries
+ under MacOS/X. If the :option:`--arch <configure.py --arch>` option has
+ not been specified then the universal binary will include the ``i386`` and
+ ``ppc`` architectures.
+
+.. cmdoption:: -p <PLATFORM>, --platform <PLATFORM>
+
+ Explicitly specify the platform/compiler to be used by the build system,
+ otherwise a platform specific default will be used. The
+ :option:`--show-platforms <configure.py --show-platforms>` option will
+ display all the supported platform/compilers.
+
+.. cmdoption:: -s <SDK>, --sdk <SDK>
+
+ If the :option:`--universal <configure.py -n>` option was given then this
+ specifies the name of the SDK directory. If a path is not given then it is
+ assumed to be a sub-directory of ``/Developer/SDKs``.
+
+.. cmdoption:: -u, --debug
+
+ The SIP module will be built with debugging symbols.
+
+.. cmdoption:: -v <DIR>, --sipdir <DIR>
+
+ By default ``.sip`` files will be installed in the directory ``<DIR>``.
+
+.. cmdoption:: --show-platforms
+
+ The list of all supported platform/compilers will be displayed.
+
+.. cmdoption:: --show-build-macros
+
+ The list of all available build macros will be displayed.
+
+The ``configure.py`` script takes many other options that allows the build
+system to be finely tuned. These are of the form ``name=value`` or
+``name+=value``. The :option:`--show-build-macros <configure.py
+--show-build-macros>` option will display each supported ``name``, although not
+all are applicable to all platforms.
+
+The ``name=value`` form means that ``value`` will replace the existing value of
+``name``.
+
+The ``name+=value`` form means that ``value`` will be appended to the existing
+value of ``name``.
+
+For example, the following will disable support for C++ exceptions (and so
+reduce the size of module binaries) when used with GCC::
+
+ python configure.py CXXFLAGS+=-fno-exceptions
+
+A pure Python module called ``sipconfig.py`` is generated by ``configure.py``.
+This defines each ``name`` and its corresponding ``value``. Looking at it will
+give you a good idea of how the build system uses the different options. It is
+covered in detail in :ref:`ref-build-system`.
+
+
+Configuring for MinGW
+*********************
+
+SIP, and the modules it generates, can be built with MinGW, the Windows port of
+GCC. You must use the :option:`--platform <configure.py -p>` command line
+option to specify the correct platform. For example::
+
+ c:\python26\python configure.py --platform win32-g++
+
+
+Configuring for the Borland C++ Compiler
+****************************************
+
+SIP, and the modules it generates, can be built with the free Borland C++
+compiler. You must use the :option:`--platform <configure.py -p>` command line
+option to specify the correct platform. For example::
+
+ c:\python26\python configure.py --platform win32-borland
+
+You must also make sure you have a Borland-compatible version of the Python
+library. If you are using the standard Python distribution (built using the
+Microsoft compiler) then you must convert the format of the Python library.
+For example::
+
+ coff2omf python26.lib python26_bcpp.lib
+
+
+Building
+--------
+
+The next step is to build SIP by running your platform's ``make`` command. For
+example::
+
+ make
+
+The final step is to install SIP by running the following command::
+
+ make install
+
+(Depending on your system you may require root or administrator privileges.)
+
+This will install the various SIP components.
diff --git a/sphinx/introduction.rst b/sphinx/introduction.rst
new file mode 100644
index 0000000..8515243
--- /dev/null
+++ b/sphinx/introduction.rst
@@ -0,0 +1,169 @@
+Introduction
+============
+
+This is the reference guide for SIP 4.10.5. SIP is a tool for
+automatically generating `Python <http://www.python.org>`__ bindings for C and
+C++ libraries. SIP was originally developed in 1998 for
+`PyQt <http://www.riverbankcomputing.com/software/pyqt>`__ - the Python
+bindings for the Qt GUI toolkit - but is suitable for generating bindings for
+any C or C++ library.
+
+This version of SIP generates bindings for Python v2.3 or later, including
+Python v3.
+
+There are many other similar tools available. One of the original such tools
+is `SWIG <http://www.swig.org>`__ and, in fact, SIP is so called because it
+started out as a small SWIG. Unlike SWIG, SIP is specifically designed for
+bringing together Python and C/C++ and goes to great lengths to make the
+integration as tight as possible.
+
+The homepage for SIP is http://www.riverbankcomputing.com/software/sip. Here
+you will always find the latest stable version and the latest version of this
+documentation.
+
+SIP can also be downloaded from the
+`Mercurial <http://mercurial.selenic.com/>`__ repository at
+http://www.riverbankcomputing.com/hg/sip.
+
+
+License
+-------
+
+SIP is licensed under similar terms as Python itself. SIP is also licensed
+under the GPL (both v2 and v3). It is your choice as to which license you
+use. If you choose the GPL then any bindings you create must be distributed
+under the terms of the GPL.
+
+
+Features
+--------
+
+SIP, and the bindings it produces, have the following features:
+
+- bindings are fast to load and minimise memory consumption especially when
+ only a small sub-set of a large library is being used
+
+- automatic conversion between standard Python and C/C++ data types
+
+- overloading of functions and methods with different argument signatures
+
+- support for Python's keyword argument syntax
+
+- support for both explicitly specified and automatically generated docstrings
+
+- access to a C++ class's protected methods
+
+- the ability to define a Python class that is a sub-class of a C++ class,
+ including abstract C++ classes
+
+- Python sub-classes can implement the :meth:`__dtor__` method which will be
+ called from the C++ class's virtual destructor
+
+- support for ordinary C++ functions, class methods, static class methods,
+ virtual class methods and abstract class methods
+
+- the ability to re-implement C++ virtual and abstract methods in Python
+
+- support for global and class variables
+
+- support for global and class operators
+
+- support for C++ namespaces
+
+- support for C++ templates
+
+- support for C++ exceptions and wrapping them as Python exceptions
+
+- the automatic generation of complementary rich comparison slots
+
+- support for deprecation warnings
+
+- the ability to define mappings between C++ classes and similar Python data
+ types that are automatically invoked
+
+- the ability to automatically exploit any available run time type information
+ to ensure that the class of a Python instance object matches the class of the
+ corresponding C++ instance
+
+- the ability to change the type and meta-type of the Python object used to
+ wrap a C/C++ data type
+
+- full support of the Python global interpreter lock, including the ability to
+ specify that a C++ function of method may block, therefore allowing the lock
+ to be released and other Python threads to run
+
+- support for consolidated modules where the generated wrapper code for a
+ number of related modules may be included in a single, possibly private,
+ module
+
+- support for the concept of ownership of a C++ instance (i.e. what part of the
+ code is responsible for calling the instance's destructor) and how the
+ ownership may change during the execution of an application
+
+- the ability to generate bindings for a C++ class library that itself is built
+ on another C++ class library which also has had bindings generated so that
+ the different bindings integrate and share code properly
+
+- a sophisticated versioning system that allows the full lifetime of a C++
+ class library, including any platform specific or optional features, to be
+ described in a single set of specification files
+
+- the ability to include documentation in the specification files which can be
+ extracted and subsequently processed by external tools
+
+- the ability to include copyright notices and licensing information in the
+ specification files that is automatically included in all generated source
+ code
+
+- a build system, written in Python, that you can extend to configure, compile
+ and install your own bindings without worrying about platform specific issues
+
+- support for building your extensions using distutils
+
+- SIP, and the bindings it produces, runs under UNIX, Linux, Windows and
+ MacOS/X
+
+
+SIP Components
+--------------
+
+SIP comprises a number of different components.
+
+- The SIP code generator (:program:`sip`). This processes :file:`.sip`
+ specification files and generates C or C++ bindings. It is covered in detail
+ in :ref:`ref-using`.
+
+- The SIP header file (:file:`sip.h`). This contains definitions and data
+ structures needed by the generated C and C++ code.
+
+- The SIP module (:file:`sip.so` or :file:`sip.pyd`). This is a Python
+ extension module that is imported automatically by SIP generated bindings and
+ provides them with some common utility functions. See also
+ :ref:`ref-python-api`.
+
+- The SIP build system (:file:`sipconfig.py`). This is a pure Python module
+ that is created when SIP is configured and encapsulates all the necessary
+ information about your system including relevant directory names, compiler
+ and linker flags, and version numbers. It also includes several Python
+ classes and functions which help you write configuration scripts for your own
+ bindings. It is covered in detail in :ref:`ref-build-system`.
+
+- The SIP distutils extension (:file:`sipdistutils.py`). This is a distutils
+ extension that can be used to build your extension modules using distutils
+ and is an alternative to writing configuration scripts with the SIP build
+ system. This can be as simple as adding your .sip files to the list of files
+ needed to build the extension module. It is covered in detail in
+ :ref:`ref-distutils`.
+
+
+Qt Support
+----------
+
+SIP has specific support for the creation of bindings based on Nokia's Qt
+toolkit.
+
+The SIP code generator understands the signal/slot type safe callback mechanism
+that Qt uses to connect objects together. This allows applications to define
+new Python signals, and allows any Python callable object to be used as a slot.
+
+SIP itself does not require Qt to be installed.
diff --git a/sphinx/python_api.rst b/sphinx/python_api.rst
new file mode 100644
index 0000000..fa90411
--- /dev/null
+++ b/sphinx/python_api.rst
@@ -0,0 +1,282 @@
+.. _ref-python-api:
+
+Python API for Applications
+===========================
+
+.. module:: sip
+
+The main purpose of the :mod:`sip` module is to provide functionality common to
+all SIP generated bindings. It is loaded automatically and most of the time
+you will completely ignore it. However, it does expose some functionality that
+can be used by applications.
+
+
+.. function:: cast(obj, type) -> object
+
+ This does the Python equivalent of casting a C++ instance to one of its
+ sub or super-class types.
+
+ :param obj:
+ the Python object.
+ :param type:
+ the type.
+ :return:
+ a new Python object is that wraps the same C++ instance as *obj*, but
+ has the type *type*.
+
+
+.. function:: delete(obj)
+
+ For C++ instances this calls the C++ destructor. For C structures it
+ returns the structure's memory to the heap.
+
+ :param obj:
+ the Python object.
+
+
+.. function:: dump(obj)
+
+ This displays various bits of useful information about the internal state
+ of the Python object that wraps a C++ instance or C structure.
+
+ :param obj:
+ the Python object.
+
+
+.. function:: getapi(name) -> version
+
+ .. versionadded:: 4.9
+
+ This returns the version number that has been set for an API. The version
+ number is either set explicitly by a call to :func:`sip.setapi` or
+ implicitly by importing the module that defines it.
+
+ :param name:
+ the name of the API.
+ :return:
+ The version number that has been set for the API. An exception will
+ be raised if the API is unknown.
+
+
+.. function:: isdeleted(obj) -> bool
+
+ This checks if the C++ instance or C structure has been deleted and
+ returned to the heap.
+
+ :param obj:
+ the Python object.
+ :return:
+ ``True`` if the C/C++ instance has been deleted.
+
+
+.. function:: ispyowned(obj) -> bool
+
+ This checks if the C++ instance or C structure is owned by Python.
+
+ :param obj:
+ the Python object.
+ :return:
+ ``True`` if the C/C++ instance is owned by Python.
+
+
+.. function:: setapi(name, version)
+
+ .. versionadded:: 4.9
+
+ This sets the version number of an API. An exception is raised if a
+ different version number has already been set, either explicitly by a
+ previous call, or implicitly by importing the module that defines it.
+
+ :param name:
+ the name of the API.
+ :param version:
+ The version number to set for the API. Version numbers must be
+ greater than or equal to 1.
+
+
+.. function:: setdeleted(obj)
+
+ This marks the C++ instance or C structure as having been deleted and
+ returned to the heap so that future references to it raise an exception
+ rather than cause a program crash. Normally SIP handles such things
+ automatically, but there may be circumstances where this isn't possible.
+
+ :param obj:
+ the Python object.
+
+
+.. function:: settracemask(mask)
+
+ If the bindings have been created with SIP's :option:`-r <sip -r>` command
+ line option then the generated code will include debugging statements that
+ trace the execution of the code. (It is particularly useful when trying to
+ understand the operation of a C++ library's virtual function calls.)
+
+ :param mask:
+ the mask that determines which debugging statements are enabled.
+
+ Debugging statements are generated at the following points:
+
+ - in a C++ virtual function (*mask* is ``0x0001``)
+ - in a C++ constructor (*mask* is ``0x0002``)
+ - in a C++ destructor (*mask* is ``0x0004``)
+ - in a Python type's __init__ method (*mask* is ``0x0008``)
+ - in a Python type's __del__ method (*mask* is ``0x0010``)
+ - in a Python type's ordinary method (*mask* is ``0x0020``).
+
+ By default the trace mask is zero and all debugging statements are
+ disabled.
+
+
+.. data:: SIP_VERSION
+
+ This is a Python integer object that represents the SIP version number as
+ a 3 part hexadecimal number (e.g. v4.0.0 is represented as ``0x040000``).
+ It was first implemented in SIP v4.2.
+
+
+.. data:: SIP_VERSION_STR
+
+ This is a Python string object that defines the SIP version number as
+ represented as a string. For development snapshots it will start with
+ ``snapshot-``. It was first implemented in SIP v4.3.
+
+
+.. function:: transferback(obj)
+
+ This function is a wrapper around :cfunc:`sipTransferBack()`.
+
+
+.. function:: transferto(obj, owner)
+
+ This function is a wrapper around :cfunc:`sipTransferTo()`.
+
+
+.. function:: unwrapinstance(obj) -> integer
+
+ This returns the address, as an integer, of a wrapped C/C++ structure or
+ class instance.
+
+ :param obj:
+ the Python object.
+ :return:
+ an integer that is the address of the C/C++ instance.
+
+
+.. class:: voidptr
+
+ This is the type object for the type SIP uses to represent a C/C++
+ ``void *``. It may have a size associated with the address in which case
+ the Python buffer protocol is supported. This means that the memory can
+ be treated as a mutable array of bytes when wrapped with the ``buffer()``
+ builtin. The type has the following methods.
+
+ .. method:: __init__(address[, size=-1[, writeable=True]])
+
+ :param address:
+ the address, either another :class:`sip.voidptr`, ``None``, a
+ Python Capsule, a Python CObject, or an integer.
+ :param size:
+ the optional associated size of the block of memory and is negative
+ if the size is not known.
+ :param writeable:
+ set if the memory is writeable. If it is not specified, and
+ *address* is a :class:`sip.voidptr` instance then its value will be
+ used.
+
+ .. method:: __int__() -> integer
+
+ This returns the address as an integer.
+
+ :return:
+ the integer address.
+
+ .. method:: __hex__() -> string
+
+ This returns the address as a hexadecimal string.
+
+ :return:
+ the hexadecimal string address.
+
+ .. method:: ascapsule() -> capsule
+
+ .. versionadded:: 4.10
+
+ This returns the address as an unnamed Python Capsule. This requires
+ Python v3.1 or later or Python v2.7 or later.
+
+ :return:
+ the Capsule.
+
+ .. method:: ascobject() -> cObject
+
+ This returns the address as a Python CObject. This is deprecated with
+ Python v3.1 or later.
+
+ :return:
+ the CObject.
+
+ .. method:: asstring([size=-1]) -> string/bytes
+
+ This returns a copy of the block of memory as a Python v2 string object
+ or a Python v3 bytes object.
+
+ :param size:
+ the number of bytes to copy. If it is negative then the size
+ associated with the address is used. If there is no associated
+ size then an exception is raised.
+ :return:
+ the string or bytes object.
+
+ .. method:: getsize() -> integer
+
+ This returns the size associated with the address.
+
+ :return:
+ the associated size which will be negative if there is none.
+
+ .. method:: setsize(size)
+
+ This sets the size associated with the address.
+
+ :param size:
+ the size to associate. If it is negative then no size is
+ associated.
+
+ .. method:: getwriteable() -> bool
+
+ This returns the writeable state of the memory.
+
+ :return:
+ ``True`` if the memory is writeable.
+
+ .. method:: setwriteable(writeable)
+
+ This sets the writeable state of the memory.
+
+ :param writeable:
+ the writeable state to set.
+
+
+.. function:: wrapinstance(addr, type) -> object
+
+ This wraps a C structure or C++ class instance in a Python object. If the
+ instance has already been wrapped then a new reference to the existing
+ object is returned.
+
+ :param addr:
+ the address of the instance as a number.
+ :param type:
+ the Python type of the instance.
+ :return:
+ the Python object that wraps the instance.
+
+
+.. class:: wrapper
+
+ This is the type object of the base type of all instances wrapped by SIP.
+
+
+.. class:: wrappertype
+
+ This is the type object of the metatype of the :class:`sip.wrapper` type.
diff --git a/sphinx/specification_files.rst b/sphinx/specification_files.rst
new file mode 100644
index 0000000..6ba3aba
--- /dev/null
+++ b/sphinx/specification_files.rst
@@ -0,0 +1,499 @@
+SIP Specification Files
+=======================
+
+A SIP specification consists of some C/C++ type and function declarations and
+some directives. The declarations may contain annotations which provide SIP
+with additional information that cannot be expressed in C/C++. SIP does not
+include a full C/C++ parser.
+
+It is important to understand that a SIP specification describes the Python
+API, i.e. the API available to the Python programmer when they ``import`` the
+generated module. It does not have to accurately represent the underlying
+C/C++ library. There is nothing wrong with omitting functions that make
+little sense in a Python context, or adding functions implemented with
+handwritten code that have no C/C++ equivalent. It is even possible (and
+sometimes necessary) to specify a different super-class hierarchy for a C++
+class. All that matters is that the generated code compiles properly.
+
+In most cases the Python API matches the C/C++ API. In some cases handwritten
+code (see :directive:`%MethodCode`) is used to map from one to the other
+without SIP having to know the details itself. However, there are a few cases
+where SIP generates a thin wrapper around a C++ method or constructor (see
+:ref:`ref-derived-classes`) and needs to know the exact C++ signature. To deal
+with these cases SIP allows two signatures to be specified. For example::
+
+ class Klass
+ {
+ public:
+ // The Python signature is a tuple, but the underlying C++ signature
+ // is a 2 element array.
+ Klass(SIP_PYTUPLE) [(int *)];
+ %MethodCode
+ int iarr[2];
+
+ if (PyArg_ParseTuple(a0, "ii", &iarr[0], &iarr[1]))
+ {
+ // Note that we use the SIP generated derived class
+ // constructor.
+ Py_BEGIN_ALLOW_THREADS
+ sipCpp = new sipKlass(iarr);
+ Py_END_ALLOW_THREADS
+ }
+ %End
+ };
+
+
+Syntax Definition
+-----------------
+
+The following is a semi-formal description of the syntax of a specification
+file.
+
+.. parsed-literal::
+
+ *specification* ::= {*module-statement*}
+
+ *module-statement* ::= [*module-directive* | *statement*]
+
+ *module-directive* ::= [
+ :directive:`%API` |
+ :directive:`%CModule` |
+ :directive:`%CompositeModule` |
+ :directive:`%ConsolidatedModule` |
+ :directive:`%Copying` |
+ :directive:`%DefaultEncoding` |
+ :directive:`%DefaultMetatype` |
+ :directive:`%DefaultSupertype` |
+ :directive:`%Doc` |
+ :directive:`%ExportedDoc` |
+ :directive:`%ExportedHeaderCode` |
+ :directive:`%Feature` |
+ :directive:`%Import` |
+ :directive:`%Include` |
+ :directive:`%InitialisationCode` |
+ :directive:`%License` |
+ :directive:`%MappedType` |
+ :directive:`%Module` |
+ :directive:`%ModuleCode` |
+ :directive:`%ModuleHeaderCode` |
+ :directive:`%OptionalInclude` |
+ :directive:`%Platforms` |
+ :directive:`%PreInitialisationCode` |
+ :directive:`%PostInitialisationCode` |
+ :directive:`%Timeline` |
+ :directive:`%UnitCode` |
+ *mapped-type-template*]
+
+ *statement* :: [*class-statement* | *function* | *variable*]
+
+ *class-statement* :: [
+ :directive:`%If` |
+ *class* |
+ *class-template* |
+ *enum* |
+ *namespace* |
+ *opaque-class* |
+ *operator* |
+ *struct* |
+ *typedef* |
+ *exception*]
+
+ *class* ::= **class** *name* [**:** *super-classes*] [*class-annotations*]
+ **{** {*class-line*} **};**
+
+ *super-classes* ::= *name* [**,** *super-classes*]
+
+ *class-line* ::= [
+ *class-statement* |
+ :directive:`%BIGetBufferCode` |
+ :directive:`%BIGetReadBufferCode` |
+ :directive:`%BIGetWriteBufferCode` |
+ :directive:`%BIGetSegCountCode` |
+ :directive:`%BIGetCharBufferCode` |
+ :directive:`%BIReleaseBufferCode` |
+ :directive:`%ConvertToSubClassCode` |
+ :directive:`%ConvertToTypeCode` |
+ :directive:`%Docstring` |
+ :directive:`%GCClearCode` |
+ :directive:`%GCTraverseCode` |
+ :directive:`%PickleCode` |
+ :directive:`%TypeCode` |
+ :directive:`%TypeHeaderCode` |
+ *constructor* |
+ *destructor* |
+ *method* |
+ *static-method* |
+ *virtual-method* |
+ *special-method* |
+ *operator* |
+ *virtual-operator* |
+ *class-variable* |
+ **public:** |
+ **public Q_SLOTS:** |
+ **public slots:** |
+ **protected:** |
+ **protected Q_SLOTS:** |
+ **protected slots:** |
+ **private:** |
+ **private Q_SLOTS:** |
+ **private slots:** |
+ **Q_SIGNALS:** |
+ **signals:**]
+
+ *constructor* ::= [**explicit**] *name* **(** [*argument-list*] **)**
+ [*exceptions*] [*function-annotations*]
+ [*c++-constructor-signature*] **;** [:directive:`%Docstring`]
+ [:directive:`%MethodCode`]
+
+ *c++-constructor-signature* ::= **[(** [*argument-list*] **)]**
+
+ *destructor* ::= [**virtual**] **~** *name* **()** [*exceptions*] [**= 0**]
+ [*function-annotations*] **;** [:directive:`%MethodCode`]
+ [:directive:`%VirtualCatcherCode`]
+
+ *method* ::= [**Q_SIGNAL**] [**Q_SLOT**] *type* *name* **(**
+ [*argument-list*] **)** [**const**] [*exceptions*] [**= 0**]
+ [*function-annotations*] [*c++-signature*] **;**
+ [:directive:`%Docstring`] [:directive:`%MethodCode`]
+
+ *c++-signature* ::= **[** *type* **(** [*argument-list*] **)]**
+
+ *static-method* ::= **static** *function*
+
+ *virtual-method* ::= [**Q_SIGNAL**] [**Q_SLOT**] **virtual** *type* *name*
+ **(** [*argument-list*] **)** [**const**] [*exceptions*] [**= 0**]
+ [*function-annotations*] [*c++-signature*] **;**
+ [:directive:`%MethodCode`] [:directive:`%VirtualCatcherCode`]
+
+ *special-method* ::= *type* *special-method-name*
+ **(** [*argument-list*] **)** [*function-annotations*] **;**
+ [:directive:`%MethodCode`]
+
+ *special-method-name* ::= [**__abs__** | **__add__** | **__and__** |
+ **__bool__** | **__call__** | **__cmp__** | **__contains__** |
+ **__delitem__** | **__div__** | **__eq__** | **__float__** |
+ **__floordiv__** | **__ge__** | **__getitem__** | **__gt__** |
+ **__hash__** | **__iadd__** | **__iand__** | **__idiv__** |
+ **__ifloordiv__** | **__ilshift__** | **__imod__** | **__imul__** |
+ **__index__** | **__int__** | **__invert__** | **__ior__** |
+ **__irshift__** | **__isub__** | **__iter__** | **__itruediv__** |
+ **__ixor__** | **__le__** | **__len__** | **__long__** |
+ **__lshift__** | **__lt__** | **__mod__** | **__mul__** |
+ **__ne__** | **__neg__** | **__next__** | **__nonzero__** |
+ **__or__** | **__pos__** | **__repr__** | **__rshift__** |
+ **__setitem__** | **__str__** | **__sub__** | **__truediv__** |
+ **__xor__**]
+
+ *operator* ::= *operator-type*
+ **(** [*argument-list*] **)** [**const**] [*exceptions*]
+ [*function-annotations*] **;** [:directive:`%MethodCode`]
+
+ *virtual-operator* ::= **virtual** *operator-type*
+ **(** [*argument-list*] **)** [**const**] [*exceptions*] [**= 0**]
+ [*function-annotations*] **;** [:directive:`%MethodCode`]
+ [:directive:`%VirtualCatcherCode`]
+
+ *operatator-type* ::= [ *operator-function* | *operator-cast* ]
+
+ *operator-function* ::= *type* **operator** *operator-name*
+
+ *operator-cast* ::= **operator** *type*
+
+ *operator-name* ::= [**+** | **-** | ***** | **/** | **%** | **&** |
+ **|** | **^** | **<<** | **>>** | **+=** | **-=** | ***=** |
+ **/=** | **%=** | **&=** | **|=** | **^=** | **<<=** | **>>=** |
+ **~** | **()** | **[]** | **<** | **<=** | **==** | **!=** |
+ **>** | **>>=** | **=**]
+
+ *class-variable* ::= [**static**] *variable*
+
+ *class-template* :: = **template** **<** *type-list* **>** *class*
+
+ *mapped-type-template* :: = **template** **<** *type-list* **>**
+ :directive:`%MappedType`
+
+ *enum* ::= **enum** [*name*] [*enum-annotations*] **{** {*enum-line*} **};**
+
+ *enum-line* ::= [:directive:`%If` | *name* [*enum-annotations*] **,**
+
+ *function* ::= *type* *name* **(** [*argument-list*] **)** [*exceptions*]
+ [*function-annotations*] **;** [:directive:`%Docstring`]
+ [:directive:`%MethodCode`]
+
+ *namespace* ::= **namespace** *name* **{** {*namespace-line*} **};**
+
+ *namespace-line* ::= [:directive:`%TypeHeaderCode` | *statement*]
+
+ *opaque-class* ::= **class** *scoped-name* **;**
+
+ *struct* ::= **struct** *name* **{** {*class-line*} **};**
+
+ *typedef* ::= **typedef** [*typed-name* | *function-pointer*]
+ *typedef-annotations* **;**
+
+ *variable*::= *typed-name* [*variable-annotations*] **;**
+ [:directive:`%AccessCode`] [:directive:`%GetCode`]
+ [:directive:`%SetCode`]
+
+ *exception* ::= :directive:`%Exception` *exception-name* [*exception-base*]
+ **{** [:directive:`%TypeHeaderCode`] :directive:`%RaiseCode` **};**
+
+ *exception-name* ::= *scoped-name*
+
+ *exception-base* ::= **(** [*exception-name* | *python-exception*] **)**
+
+ *python-exception* ::= [**SIP_Exception** | **SIP_StopIteration** |
+ **SIP_StandardError** | **SIP_ArithmeticError** |
+ **SIP_LookupError** | **SIP_AssertionError** |
+ **SIP_AttributeError** | **SIP_EOFError** |
+ **SIP_FloatingPointError** | **SIP_EnvironmentError** |
+ **SIP_IOError** | **SIP_OSError** | **SIP_ImportError** |
+ **SIP_IndexError** | **SIP_KeyError** | **SIP_KeyboardInterrupt** |
+ **SIP_MemoryError** | **SIP_NameError** | **SIP_OverflowError** |
+ **SIP_RuntimeError** | **SIP_NotImplementedError** |
+ **SIP_SyntaxError** | **SIP_IndentationError** | **SIP_TabError** |
+ **SIP_ReferenceError** | **SIP_SystemError** | **SIP_SystemExit** |
+ **SIP_TypeError** | **SIP_UnboundLocalError** |
+ **SIP_UnicodeError** | **SIP_UnicodeEncodeError** |
+ **SIP_UnicodeDecodeError** | **SIP_UnicodeTranslateError** |
+ **SIP_ValueError** | **SIP_ZeroDivisionError** |
+ **SIP_WindowsError** | **SIP_VMSError**]
+
+ *exceptions* ::= **throw (** [*exception-list*] **)**
+
+ *exception-list* ::= *scoped-name* [**,** *exception-list*]
+
+ *argument-list* ::= *argument* [**,** *argument-list*] [**,** **...**]
+
+ *argument* ::= [
+ *type* [*name*] [*argument-annotations*] [*default-value*] |
+ :stype:`SIP_ANYSLOT` [*default-value*] |
+ :stype:`SIP_QOBJECT` |
+ :stype:`SIP_RXOBJ_CON` |
+ :stype:`SIP_RXOBJ_DIS` |
+ :stype:`SIP_SIGNAL` [*default-value*] |
+ :stype:`SIP_SLOT` [*default-value*] |
+ :stype:`SIP_SLOT_CON` |
+ :stype:`SIP_SLOT_DIS`]
+
+ *default-value* ::= **=** *expression*
+
+ *expression* ::= [*value* | *value* *binary-operator* *expression*]
+
+ *value* ::= [*unary-operator*] *simple-value*
+
+ *simple-value* ::= [*scoped-name* | *function-call* | *real-value* |
+ *integer-value* | *boolean-value* | *string-value* |
+ *character-value*]
+
+ *typed-name*::= *type* *name*
+
+ *function-pointer*::= *type* **(*** *name* **)(** [*type-list*] **)**
+
+ *type-list* ::= *type* [**,** *type-list*]
+
+ *function-call* ::= *scoped-name* **(** [*value-list*] **)**
+
+ *value-list* ::= *value* [**,** *value-list*]
+
+ *real-value* ::= a floating point number
+
+ *integer-value* ::= a number
+
+ *boolean-value* ::= [**true** | **false**]
+
+ *string-value* ::= **"** {*character*} **"**
+
+ *character-value* ::= **'** *character* **'**
+
+ *unary-operator* ::= [**!** | **~** | **-** | **+**]
+
+ *binary-operator* ::= [**-** | **+** | ***** | **/** | **&** | **|**]
+
+ *argument-annotations* ::= see :ref:`ref-arg-annos`
+
+ *class-annotations* ::= see :ref:`ref-class-annos`
+
+ *enum-annotations* ::= see :ref:`ref-enum-annos`
+
+ *function-annotations* ::= see :ref:`ref-function-annos`
+
+ *typedef-annotations* ::= see :ref:`ref-typedef-annos`
+
+ *variable-annotations* ::= see :ref:`ref-variable-annos`
+
+ *type* ::= [**const**] *base-type* {*****} [**&**]
+
+ *type-list* ::= *type* [**,** *type-list*]
+
+ *base-type* ::= [*scoped-name* | *template* | **struct** *scoped-name* |
+ **char** | **signed char** | **unsigned char** | **wchar_t** |
+ **int** | **unsigned** | **unsigned int** |
+ **short** | **unsigned short** |
+ **long** | **unsigned long** |
+ **long long** | **unsigned long long** |
+ **float** | **double** |
+ **bool** |
+ **void** |
+ :stype:`SIP_PYCALLABLE` |
+ :stype:`SIP_PYDICT` |
+ :stype:`SIP_PYLIST` |
+ :stype:`SIP_PYOBJECT` |
+ :stype:`SIP_PYSLICE` |
+ :stype:`SIP_PYTUPLE` |
+ :stype:`SIP_PYTYPE`]
+
+ *scoped-name* ::= *name* [**::** *scoped-name*]
+
+ *template* ::= *scoped-name* **<** *type-list* **>**
+
+ *dotted-name* ::= *name* [**.** *dotted-name*]
+
+ *name* ::= _A-Za-z {_A-Za-z0-9}
+
+Here is a short list of differences between C++ and the subset supported by
+SIP that might trip you up.
+
+ - SIP does not support the use of ``[]`` in types. Use pointers instead.
+
+ - A global ``operator`` can only be defined if its first argument is a
+ class or a named enum that has been wrapped in the same module.
+
+ - Variables declared outside of a class are effectively read-only.
+
+ - A class's list of super-classes doesn't not include any access specifier
+ (e.g. ``public``).
+
+
+Variable Numbers of Arguments
+-----------------------------
+
+SIP supports the use of ``...`` as the last part of a function signature. Any
+remaining arguments are collected as a Python tuple.
+
+
+Additional SIP Types
+--------------------
+
+SIP supports a number of additional data types that can be used in Python
+signatures.
+
+
+.. sip-type:: SIP_ANYSLOT
+
+This is both a ``const char *`` and a ``PyObject *`` that is used as the type
+of the member instead of ``const char *`` in functions that implement the
+connection or disconnection of an explicitly generated signal to a slot.
+Handwritten code must be provided to interpret the conversion correctly.
+
+
+.. sip-type:: SIP_PYCALLABLE
+
+This is a ``PyObject *`` that is a Python callable object.
+
+
+.. sip-type:: SIP_PYDICT
+
+This is a ``PyObject *`` that is a Python dictionary object.
+
+
+.. sip-type:: SIP_PYLIST
+
+This is a ``PyObject *`` that is a Python list object.
+
+
+.. sip-type:: SIP_PYOBJECT
+
+This is a ``PyObject *`` of any Python type.
+
+
+.. sip-type:: SIP_PYSLICE
+
+This is a ``PyObject *`` that is a Python slice object.
+
+
+.. sip-type:: SIP_PYTUPLE
+
+This is a ``PyObject *`` that is a Python tuple object.
+
+
+.. sip-type:: SIP_PYTYPE
+
+This is a ``PyObject *`` that is a Python type object.
+
+
+.. sip-type:: SIP_QOBJECT
+
+This is a ``QObject *`` that is a C++ instance of a class derived from Qt's
+``QObject`` class.
+
+
+.. sip-type:: SIP_RXOBJ_CON
+
+This is a ``QObject *`` that is a C++ instance of a class derived from Qt's
+``QObject`` class. It is used as the type of the receiver instead of ``const
+QObject *`` in functions that implement a connection to a slot.
+
+
+.. sip-type:: SIP_RXOBJ_DIS
+
+This is a ``QObject *`` that is a C++ instance of a class derived from Qt's
+``QObject`` class. It is used as the type of the receiver instead of ``const
+QObject *`` in functions that implement a disconnection from a slot.
+
+
+.. sip-type:: SIP_SIGNAL
+
+This is a ``const char *`` that is used as the type of the signal instead of
+``const char *`` in functions that implement the connection or disconnection
+of an explicitly generated signal to a slot.
+
+
+.. sip-type:: SIP_SLOT
+
+This is a ``const char *`` that is used as the type of the member instead of
+``const char *`` in functions that implement the connection or disconnection
+of an explicitly generated signal to a slot.
+
+
+.. sip-type:: SIP_SLOT_CON
+
+This is a ``const char *`` that is used as the type of the member instead of
+``const char *`` in functions that implement the connection of an internally
+generated signal to a slot. The type includes a comma separated list of types
+that is the C++ signature of of the signal.
+
+To take an example, ``QAccel::connectItem()`` connects an internally generated
+signal to a slot. The signal is emitted when the keyboard accelerator is
+activated and it has a single integer argument that is the ID of the
+accelerator. The C++ signature is::
+
+ bool connectItem(int id, const QObject *receiver, const char *member);
+
+The corresponding SIP specification is::
+
+ bool connectItem(int, SIP_RXOBJ_CON, SIP_SLOT_CON(int));
+
+
+.. sip-type:: SIP_SLOT_DIS
+
+This is a ``const char *`` that is used as the type of the member instead of
+``const char *`` in functions that implement the disconnection of an
+internally generated signal to a slot. The type includes a comma separated
+list of types that is the C++ signature of of the signal.
+
+
+Classic Division and True Division
+----------------------------------
+
+SIP supports the ``__div__`` and ``__truediv__`` special methods (and the
+corresponding inplace versions) for both Python v2 and v3.
+
+For Python v2 the ``__div__`` method will be used for both classic and true
+division if a ``__truediv__`` method is not defined.
+
+For Python v3 the ``__div__`` method will be used for true division if a
+``__truediv__`` method is not defined.
+
+For all versions of Python, if both methods are defined then ``__div__``
+should be defined first.
diff --git a/sphinx/using.rst b/sphinx/using.rst
new file mode 100644
index 0000000..ff121ce
--- /dev/null
+++ b/sphinx/using.rst
@@ -0,0 +1,662 @@
+.. _ref-using:
+
+Using SIP
+=========
+
+Bindings are generated by the SIP code generator from a number of specification
+files, typically with a ``.sip`` extension. Specification files look very
+similar to C and C++ header files, but often with additional information (in
+the form of a *directive* or an *annotation*) and code so that the bindings
+generated can be finely tuned.
+
+
+.. _ref-simple-c++-example:
+
+A Simple C++ Example
+--------------------
+
+We start with a simple example. Let's say you have a (fictional) C++ library
+that implements a single class called ``Word``. The class has one constructor
+that takes a ``\0`` terminated character string as its single argument. The
+class has one method called ``reverse()`` which takes no arguments and returns
+a ``\0`` terminated character string. The interface to the class is defined in
+a header file called ``word.h`` which might look something like this::
+
+ // Define the interface to the word library.
+
+ class Word {
+ const char *the_word;
+
+ public:
+ Word(const char *w);
+
+ char *reverse() const;
+ };
+
+The corresponding SIP specification file would then look something like this::
+
+ // Define the SIP wrapper to the word library.
+
+ %Module word 0
+
+ class Word {
+
+ %TypeHeaderCode
+ #include <word.h>
+ %End
+
+ public:
+ Word(const char *w);
+
+ char *reverse() const;
+ };
+
+Obviously a SIP specification file looks very much like a C++ (or C) header
+file, but SIP does not include a full C++ parser. Let's look at the
+differences between the two files.
+
+ - The :directive:`%Module` directive has been added [#]_. This is used to
+ name the Python module that is being created and to give it a
+ *generation* number. In this example these are ``word`` and ``0``
+ respectively. The generation number is effectively the version number of
+ the module.
+
+ - The :directive:`%TypeHeaderCode` directive has been added. The text
+ between this and the following :directive:`%End` directive is included
+ literally in the code that SIP generates. Normally it is used, as in
+ this case, to ``#include`` the corresponding C++ (or C) header file [#]_.
+
+ - The declaration of the private variable ``this_word`` has been removed.
+ SIP does not support access to either private or protected instance
+ variables.
+
+If we want to we can now generate the C++ code in the current directory by
+running the following command::
+
+ sip -c . word.sip
+
+However, that still leaves us with the task of compiling the generated code and
+linking it against all the necessary libraries. It's much easier to use the
+:ref:`SIP build system <ref-build-system>` to do the whole thing.
+
+Using the SIP build system is simply a matter of writing a small Python script.
+In this simple example we will assume that the ``word`` library we are wrapping
+and it's header file are installed in standard system locations and will be
+found by the compiler and linker without having to specify any additional
+flags. In a more realistic example your Python script may take command line
+options, or search a set of directories to deal with different configurations
+and installations.
+
+This is the simplest script (conventionally called ``configure.py``)::
+
+ import os
+ import sipconfig
+
+ # The name of the SIP build file generated by SIP and used by the build
+ # system.
+ build_file = "word.sbf"
+
+ # Get the SIP configuration information.
+ config = sipconfig.Configuration()
+
+ # Run SIP to generate the code.
+ os.system(" ".join([config.sip_bin, "-c", ".", "-b", build_file, "word.sip"]))
+
+ # Create the Makefile.
+ makefile = sipconfig.SIPModuleMakefile(config, build_file)
+
+ # Add the library we are wrapping. The name doesn't include any platform
+ # specific prefixes or extensions (e.g. the "lib" prefix on UNIX, or the
+ # ".dll" extension on Windows).
+ makefile.extra_libs = ["word"]
+
+ # Generate the Makefile itself.
+ makefile.generate()
+
+Hopefully this script is self-documenting. The key parts are the
+``Configuration`` and ``SIPModuleMakefile`` classes. The build system contains
+other Makefile classes, for example to build programs or to call other
+Makefiles in sub-directories.
+
+After running the script (using the Python interpreter the extension module is
+being created for) the generated C++ code and ``Makefile`` will be in the
+current directory.
+
+To compile and install the extension module, just run the following
+commands [#]_::
+
+ make
+ make install
+
+That's all there is to it.
+
+See :ref:`ref-distutils` for an example of how to build this example using
+distutils.
+
+.. [#] All SIP directives start with a ``%`` as the first non-whitespace
+ character of a line.
+.. [#] SIP includes many code directives like this. They differ in where the
+ supplied code is placed by SIP in the generated code.
+.. [#] On Windows you might run ``nmake`` or ``mingw32-make`` instead.
+
+
+A Simple C Example
+------------------
+
+Let's now look at a very similar example of wrapping a fictional C library::
+
+ /* Define the interface to the word library. */
+
+ struct Word {
+ const char *the_word;
+ };
+
+ struct Word *create_word(const char *w);
+ char *reverse(struct Word *word);
+
+The corresponding SIP specification file would then look something like this::
+
+ /* Define the SIP wrapper to the word library. */
+
+ %CModule word 0
+
+ struct Word {
+
+ %TypeHeaderCode
+ #include <word.h>
+ %End
+
+ const char *the_word;
+ };
+
+ struct Word *create_word(const char *w) /Factory/;
+ char *reverse(struct Word *word);
+
+Again, let's look at the differences between the two files.
+
+ - The :directive:`%CModule` directive has been added. This has the same
+ syntax as the :directive:`%Module` directive used in the previous example
+ but tells SIP that the library being wrapped is implemented in C rather
+ than C++.
+
+ - The :directive:`%TypeHeaderCode` directive has been added.
+
+ - The :fanno:`Factory` annotation has been added to the ``create_word()``
+ function. This tells SIP that a newly created structure is being
+ returned and it is owned by Python.
+
+The ``configure.py`` build system script described in the previous example can
+be used for this example without change.
+
+
+A More Complex C++ Example
+--------------------------
+
+In this last example we will wrap a fictional C++ library that contains a class
+that is derived from a Qt class. This will demonstrate how SIP allows a class
+hierarchy to be split across multiple Python extension modules, and will
+introduce SIP's versioning system.
+
+The library contains a single C++ class called ``Hello`` which is derived from
+Qt's ``QLabel`` class. It behaves just like ``QLabel`` except that the text
+in the label is hard coded to be ``Hello World``. To make the example more
+interesting we'll also say that the library only supports Qt v4.2 and later,
+and also includes a function called ``setDefault()`` that is not implemented
+in the Windows version of the library.
+
+The ``hello.h`` header file looks something like this::
+
+ // Define the interface to the hello library.
+
+ #include <qlabel.h>
+ #include <qwidget.h>
+ #include <qstring.h>
+
+ class Hello : public QLabel {
+ // This is needed by the Qt Meta-Object Compiler.
+ Q_OBJECT
+
+ public:
+ Hello(QWidget *parent = 0);
+
+ private:
+ // Prevent instances from being copied.
+ Hello(const Hello &);
+ Hello &operator=(const Hello &);
+ };
+
+ #if !defined(Q_OS_WIN)
+ void setDefault(const QString &def);
+ #endif
+
+The corresponding SIP specification file would then look something like this::
+
+ // Define the SIP wrapper to the hello library.
+
+ %Module hello 0
+
+ %Import QtGui/QtGuimod.sip
+
+ %If (Qt_4_2_0 -)
+
+ class Hello : QLabel {
+
+ %TypeHeaderCode
+ #include <hello.h>
+ %End
+
+ public:
+ Hello(QWidget *parent /TransferThis/ = 0);
+
+ private:
+ Hello(const Hello &);
+ };
+
+ %If (!WS_WIN)
+ void setDefault(const QString &def);
+ %End
+
+ %End
+
+Again we look at the differences, but we'll skip those that we've looked at in
+previous examples.
+
+ - The :directive:`%Import` directive has been added to specify that we are
+ extending the class hierarchy defined in the file ``QtGui/QtGuimod.sip``.
+ This file is part of PyQt. The build system will take care of finding
+ the file's exact location.
+
+ - The :directive:`%If` directive has been added to specify that everything
+ [#]_ up to the matching :directive:`%End` directive only applies to Qt
+ v4.2 and later. ``Qt_4_2_0`` is a *tag* defined in ``QtCoremod.sip``
+ [#]_ using the :directive:`%Timeline` directive. :directive:`%Timeline`
+ is used to define a tag for each version of a library's API you are
+ wrapping allowing you to maintain all the different versions in a single
+ SIP specification. The build system provides support to ``configure.py``
+ scripts for working out the correct tags to use according to which
+ version of the library is actually installed.
+
+ - The ``public`` keyword used in defining the super-classes has been
+ removed. This is not supported by SIP.
+
+ - The :aanno:`TransferThis` annotation has been added to the constructor's
+ argument. It specifies that if the argument is not 0 (i.e. the ``Hello``
+ instance being constructed has a parent) then ownership of the instance
+ is transferred from Python to C++. It is needed because Qt maintains
+ objects (i.e. instances derived from the ``QObject`` class) in a
+ hierachy. When an object is destroyed all of its children are also
+ automatically destroyed. It is important, therefore, that the Python
+ garbage collector doesn't also try and destroy them. This is covered in
+ more detail in :ref:`ref-object-ownership`. SIP provides many other
+ annotations that can be applied to arguments, functions and classes.
+ Multiple annotations are separated by commas. Annotations may have
+ values.
+
+ - The ``=`` operator has been removed. This operator is not supported by
+ SIP.
+
+ - The :directive:`%If` directive has been added to specify that everything
+ up to the matching :directive:`%End` directive does not apply to Windows.
+ ``WS_WIN`` is another tag defined by PyQt, this time using the
+ :directive:`%Platforms` directive. Tags defined by the
+ :directive:`%Platforms` directive are mutually exclusive, i.e. only one
+ may be valid at a time [#]_.
+
+One question you might have at this point is why bother to define the private
+copy constructor when it can never be called from Python? The answer is to
+prevent the automatic generation of a public copy constructor.
+
+We now look at the ``configure.py`` script. This is a little different to the
+script in the previous examples for two related reasons.
+
+Firstly, PyQt includes a pure Python module called ``pyqtconfig`` that extends
+the SIP build system for modules, like our example, that build on top of PyQt.
+It deals with the details of which version of Qt is being used (i.e. it
+determines what the correct tags are) and where it is installed. This is
+called a module's configuration module.
+
+Secondly, we generate a configuration module (called ``helloconfig``) for our
+own ``hello`` module. There is no need to do this, but if there is a chance
+that somebody else might want to extend your C++ library then it would make
+life easier for them.
+
+Now we have two scripts. First the ``configure.py`` script::
+
+ import os
+ import sipconfig
+ from PyQt4 import pyqtconfig
+
+ # The name of the SIP build file generated by SIP and used by the build
+ # system.
+ build_file = "hello.sbf"
+
+ # Get the PyQt configuration information.
+ config = pyqtconfig.Configuration()
+
+ # Get the extra SIP flags needed by the imported PyQt modules. Note that
+ # this normally only includes those flags (-x and -t) that relate to SIP's
+ # versioning system.
+ pyqt_sip_flags = config.pyqt_sip_flags
+
+ # Run SIP to generate the code. Note that we tell SIP where to find the qt
+ # module's specification files using the -I flag.
+ os.system(" ".join([config.sip_bin, "-c", ".", "-b", build_file, "-I", config.pyqt_sip_dir, pyqt_sip_flags, "hello.sip"]))
+
+ # We are going to install the SIP specification file for this module and
+ # its configuration module.
+ installs = []
+
+ installs.append(["hello.sip", os.path.join(config.default_sip_dir, "hello")])
+
+ installs.append(["helloconfig.py", config.default_mod_dir])
+
+ # Create the Makefile. The QtGuiModuleMakefile class provided by the
+ # pyqtconfig module takes care of all the extra preprocessor, compiler and
+ # linker flags needed by the Qt library.
+ makefile = pyqtconfig.QtGuiModuleMakefile(
+ configuration=config,
+ build_file=build_file,
+ installs=installs
+ )
+
+ # Add the library we are wrapping. The name doesn't include any platform
+ # specific prefixes or extensions (e.g. the "lib" prefix on UNIX, or the
+ # ".dll" extension on Windows).
+ makefile.extra_libs = ["hello"]
+
+ # Generate the Makefile itself.
+ makefile.generate()
+
+ # Now we create the configuration module. This is done by merging a Python
+ # dictionary (whose values are normally determined dynamically) with a
+ # (static) template.
+ content = {
+ # Publish where the SIP specifications for this module will be
+ # installed.
+ "hello_sip_dir": config.default_sip_dir,
+
+ # Publish the set of SIP flags needed by this module. As these are the
+ # same flags needed by the qt module we could leave it out, but this
+ # allows us to change the flags at a later date without breaking
+ # scripts that import the configuration module.
+ "hello_sip_flags": pyqt_sip_flags
+ }
+
+ # This creates the helloconfig.py module from the helloconfig.py.in
+ # template and the dictionary.
+ sipconfig.create_config_module("helloconfig.py", "helloconfig.py.in", content)
+
+Next we have the ``helloconfig.py.in`` template script::
+
+ from PyQt4 import pyqtconfig
+
+ # These are installation specific values created when Hello was configured.
+ # The following line will be replaced when this template is used to create
+ # the final configuration module.
+ # @SIP_CONFIGURATION@
+
+ class Configuration(pyqtconfig.Configuration):
+ """The class that represents Hello configuration values.
+ """
+ def __init__(self, sub_cfg=None):
+ """Initialise an instance of the class.
+
+ sub_cfg is the list of sub-class configurations. It should be None
+ when called normally.
+ """
+ # This is all standard code to be copied verbatim except for the
+ # name of the module containing the super-class.
+ if sub_cfg:
+ cfg = sub_cfg
+ else:
+ cfg = []
+
+ cfg.append(_pkg_config)
+
+ pyqtconfig.Configuration.__init__(self, cfg)
+
+ class HelloModuleMakefile(pyqtconfig.QtGuiModuleMakefile):
+ """The Makefile class for modules that %Import hello.
+ """
+ def finalise(self):
+ """Finalise the macros.
+ """
+ # Make sure our C++ library is linked.
+ self.extra_libs.append("hello")
+
+ # Let the super-class do what it needs to.
+ pyqtconfig.QtGuiModuleMakefile.finalise(self)
+
+Again, we hope that the scripts are self documenting.
+
+.. [#] Some parts of a SIP specification aren't subject to version control.
+.. [#] Actually in ``versions.sip``. PyQt uses the :directive:`%Include`
+ directive to split the SIP specification for Qt across a large number of
+ separate ``.sip`` files.
+.. [#] Tags can also be defined by the :directive:`%Feature` directive. These
+ tags are not mutually exclusive, i.e. any number may be valid at a time.
+
+
+.. _ref-object-ownership:
+
+Ownership of Objects
+--------------------
+
+When a C++ instance is wrapped a corresponding Python object is created. The
+Python object behaves as you would expect in regard to garbage collection - it
+is garbage collected when its reference count reaches zero. What then happens
+to the corresponding C++ instance? The obvious answer might be that the
+instance's destructor is called. However the library API may say that when the
+instance is passed to a particular function, the library takes ownership of the
+instance, i.e. responsibility for calling the instance's destructor is
+transferred from the SIP generated module to the library.
+
+Ownership of an instance may also be associated with another instance. The
+implication being that the owned instance will automatically be destroyed if
+the owning instance is destroyed. SIP keeps track of these relationships to
+ensure that Python's cyclic garbage collector can detect and break any
+reference cycles between the owning and owned instances. The association is
+implemented as the owning instance taking a reference to the owned instance.
+
+The TransferThis, Transfer and TransferBack annotations are used to specify
+where, and it what direction, transfers of ownership happen. It is very
+important that these are specified correctly to avoid crashes (where both
+Python and C++ call the destructor) and memory leaks (where neither Python and
+C++ call the destructor).
+
+This applies equally to C structures where the structure is returned to the
+heap using the ``free()`` function.
+
+See also :cfunc:`sipTransferTo()`, :cfunc:`sipTransferBack()` and
+:cfunc:`sipTransferBreak()`.
+
+
+.. _ref-types-metatypes:
+
+Types and Meta-types
+--------------------
+
+Every Python object (with the exception of the :class:`object` object itself)
+has a meta-type and at least one super-type. By default an object's meta-type
+is the meta-type of its first super-type.
+
+SIP implements two super-types, :class:`sip.simplewrapper` and
+:class:`sip.wrapper`, and a meta-type, :class:`sip.wrappertype`.
+
+:class:`sip.simplewrapper` is the super-type of :class:`sip.wrapper`. The
+super-type of :class:`sip.simplewrapper` is :class:`object`.
+
+:class:`sip.wrappertype` is the meta-type of both :class:`sip.simplewrapper`
+and :class:`sip.wrapper`. The super-type of :class:`sip.wrappertype` is
+:class:`type`.
+
+:class:`sip.wrapper` supports the concept of object ownership described in
+:ref:`ref-object-ownership` and, by default, is the super-type of all the types
+that SIP generates.
+
+:class:`sip.simplewrapper` does not support the concept of object ownership but
+SIP generated types that are sub-classed from it have Python objects that take
+less memory.
+
+SIP allows a class's meta-type and super-type to be explicitly specified using
+the :canno:`Metatype` and :canno:`Supertype` class annotations.
+
+SIP also allows the default meta-type and super-type to be changed for a module
+using the :directive:`%DefaultMetatype` and :directive:`%DefaultSupertype`
+directives. Unlike the default super-type, the default meta-type is inherited
+by importing modules.
+
+If you want to use your own meta-type or super-type then they must be
+sub-classed from one of the SIP provided types. Your types must be registered
+using :cfunc:`sipRegisterPyType()`. This is normally done in code specified
+using the :directive:`%InitialisationCode` directive.
+
+As an example, PyQt4 uses :directive:`%DefaultMetatype` to specify a new
+meta-type that handles the interaction with Qt's own meta-type system. It also
+uses :directive:`%DefaultSupertype` to specify that the smaller
+:class:`sip.simplewrapper` super-type is normally used. Finally it uses
+:canno:`Supertype` as an annotation of the ``QObject`` class to override the
+default and use :class:`sip.wrapper` as the super-type so that the parent/child
+relationships of ``QObject`` instances are properly maintained.
+
+
+.. _ref-lazy-type-attributes:
+
+Lazy Type Attributes
+--------------------
+
+Instead of populating a wrapped type's dictionary with its attributes (or
+descriptors for those attributes) SIP only creates objects for those attributes
+when they are actually needed. This is done to reduce the memory footprint and
+start up time when used to wrap large libraries with hundreds of classes and
+tens of thousands of attributes.
+
+SIP allows you to extend the handling of lazy attributes to your own attribute
+types by allowing you to register an attribute getter handler (using
+:cfunc:`sipRegisterAttributeGetter()`). This will be called just before a
+type's dictionary is accessed for the first time.
+
+
+Support for Python's Buffer Interface
+-------------------------------------
+
+SIP supports Python's buffer interface in that whenever C/C++ requires a
+``char`` or ``char *`` type then any Python type that supports the buffer
+interface (including ordinary Python strings) can be used.
+
+If a buffer is made up of a number of segments then all but the first will be
+ignored.
+
+
+Support for Wide Characters
+---------------------------
+
+SIP v4.6 introduced support for wide characters (i.e. the ``wchar_t`` type).
+Python's C API includes support for converting between unicode objects and wide
+character strings and arrays. When converting from a unicode object to wide
+characters SIP creates the string or array on the heap (using memory allocated
+using :cfunc:`sipMalloc()`). This then raises the problem of how this memory
+is subsequently freed.
+
+The following describes how SIP handles this memory in the different situations
+where this is an issue.
+
+ - When a wide string or array is passed to a function or method then the
+ memory is freed (using :cfunc:`sipFree()`) after than function or method
+ returns.
+
+ - When a wide string or array is returned from a virtual method then SIP
+ does not free the memory until the next time the method is called.
+
+ - When an assignment is made to a wide string or array instance variable
+ then SIP does not first free the instance's current string or array.
+
+
+.. _ref-gil:
+
+The Python Global Interpreter Lock
+----------------------------------
+
+Python's Global Interpretor Lock (GIL) must be acquired before calls can be
+made to the Python API. It should also be released when a potentially
+blocking call to C/C++ library is made in order to allow other Python threads
+to be executed. In addition, some C/C++ libraries may implement their own
+locking strategies that conflict with the GIL causing application deadlocks.
+SIP provides ways of specifying when the GIL is released and acquired to
+ensure that locking problems can be avoided.
+
+SIP always ensures that the GIL is acquired before making calls to the Python
+API. By default SIP does not release the GIL when making calls to the C/C++
+library being wrapped. The :fanno:`ReleaseGIL` annotation can be used to
+override this behaviour when required.
+
+If SIP is given the :option:`-g <sip -g>` command line option then the default
+behaviour is changed and SIP releases the GIL every time is makes calls to the
+C/C++ library being wrapped. The :fanno:`HoldGIL` annotation can be used to
+override this behaviour when required.
+
+
+.. _ref-incompat-apis:
+
+Managing Incompatible APIs
+--------------------------
+
+.. versionadded:: 4.9
+
+Sometimes it is necessary to change the way something is wrapped in a way that
+introduces an incompatibility. For example a new feature of Python may
+suggest that something may be wrapped in a different way to exploit that
+feature.
+
+SIP's :directive:`%Feature` directive could be used to provide two different
+implementations. However this would mean that the choice between the two
+implementations would have to be made when building the generated module
+potentially causing all sorts of deployment problems. It may also require
+applications to work out which implementation was available and to change
+their behaviour accordingly.
+
+Instead SIP provides limited support for providing multiple implementations
+(of classes, mapped types and functions) that can be selected by an
+application at run-time. It is then up to the application developer how they
+want to manage the migration from the old API to the new, incompatible API.
+
+This support is implemented in three parts.
+
+Firstly the :directive:`%API` directive is used to define the name of an API
+and its default version number. The default version number is the one used if
+an application doesn't explicitly set the version number to use.
+
+Secondly the :canno:`API class <API>`, :manno:`mapped type <API>` or
+:fanno:`function <API>` annotation is applied accordingly to specify the API
+and range of version numbers that a particular class, mapped type or function
+implementation should be enabled for.
+
+Finally the application calls :func:`sip.setapi` to specify the version number
+of the API that should be enabled. This call must be made before any module
+that has multiple implementations is imported for the first time.
+
+Note this mechanism is not intended as a way or providing equally valid
+alternative APIs. For example::
+
+ %API MyAPI 1
+
+ class Foo
+ {
+ public:
+ void bar();
+ };
+
+ class Baz : Foo
+ {
+ public:
+ void bar() /API=MyAPI:2-/;
+ };
+
+If the following Python code is executed then an exception will be raised::
+
+ b = Baz()
+ b.bar()
+
+This is because when version 1 of the *MyAPI* API (the default) is enabled
+there is no *Baz.bar()* implementation and *Foo.bar()* will not be called
+instead as might be expected.