sip-4.19.7/0000755000076500000240000000000013231604432012464 5ustar philstaff00000000000000sip-4.19.7/ChangeLog0000644000076500000240000103055213231604431014243 0ustar philstaff000000000000002018-01-23 Phil Thompson * NEWS: Released as v4.19.7. [7e9dbd15c866] [4.19.7] <4.19-maint> * NEWS: Updated the NEWS file. [3d0a9ebb536c] <4.19-maint> 2018-01-22 Phil Thompson * siplib/siplib.c.in: A significant update to a comment. [f947546822c3] <4.19-maint> 2018-01-16 Phil Thompson * sipgen/metasrc/lexer.l: Fixed the failed attempt to fix %Docstring argument parsing. [6054b3268f6f] <4.19-maint> 2018-01-15 Phil Thompson * sipgen/gencode.c, sipgen/metasrc/lexer.l, sipgen/metasrc/parser.y, sphinx/directives.rst: In the context of a class's docstring the signature argument refers to the concatanated ctor docstrings. [34ddf9638287] <4.19-maint> * sipgen/metasrc/parser.y, sphinx/directives.rst: Typedefs can now have docstrings. These are only used by those that instantiate class templates. [327ad560d853] <4.19-maint> 2018-01-14 Phil Thompson * sipgen/gencode.c: Fixed the generated of a default value that is a global unscoped enum. [8f9c478295d3] <4.19-maint> 2018-01-09 Phil Thompson * sipgen/gencode.c: Fixed a missing quote in the docstring support. [e37301b91a57] <4.19-maint> 2018-01-07 Phil Thompson * sipgen/gencode.c: Fixed the handling of signal docstrings. [5d4d28286e02] <4.19-maint> * sipgen/gencode.c: Fixed the docstring handling for private ctors and method. [8186b65687f1] <4.19-maint> * sipgen/gencode.c: Fixed the formats of class docstrings. [3af2dab08ed3] <4.19-maint> * sipgen/gencode.c: Fixed the formatting of function/method docstrings. [8e1829fdaf04] <4.19-maint> 2018-01-06 Phil Thompson * sipgen/gencode.c, sipgen/metasrc/lexer.l, sipgen/metasrc/parser.y, sipgen/sip.h.in, sphinx/directives.rst: Initial commit to support embeded signatures in explicit docstrings. [b3d42a546701] <4.19-maint> 2018-01-05 Phil Thompson * sphinx/conf.py.in, sphinx/riverbank/layout.html, sphinx/riverbank/static/logo.png, sphinx/riverbank/static/logo_tn.ico, sphinx/riverbank/static/riverbank.css, sphinx/riverbank/theme.conf, sphinx/static/classic.css, sphinx/static/logo.png, sphinx/static/logo_tn.ico: Switched to the revised Sphinx standards. [b68eecb348b9] <4.19-maint> 2017-12-30 Phil Thompson * sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in: Fixed the handling of wchar_t constants. [c0436cb89959] <4.19-maint> 2017-12-16 Phil Thompson * configure.py.in: Readability improvement. [6a635db426ea] <4.19-maint> * configure.py.in: Fixed the location to install the code generator in a Windows venv. [d0f37d83df6f] <4.19-maint> * configure.py.in: Fixed the location of the pythonMN.lib file on Windows when building in a venv. [a098e2be83c2] <4.19-maint> 2017-11-23 Phil Thompson * .hgtags: Added tag 4.19.6 for changeset 3f131525d4d5 [3f3a98f6a67a] <4.19-maint> * NEWS: Released as v4.19.6. [3f131525d4d5] [4.19.6] <4.19-maint> 2017-11-21 Phil Thompson * sphinx/annotations.rst: Updated the docs for /NewThread/. [30c7476904af] <4.19-maint> 2017-11-10 Phil Thompson * sipgen/gencode.c: Fixed the handling of the default value of unscoped enums when using old compilers. [dd017d3e1454] <4.19-maint> 2017-11-06 Phil Thompson * .hgtags: Added tag 4.19.5 for changeset a572b9daf87f [e0419013252c] <4.19-maint> * NEWS: Released as v4.19.5. [a572b9daf87f] [4.19.5] <4.19-maint> * siplib/sip.h.in.in, siplib/siplib.c.in: Fixed a regression in the conversion of enums which meant that an object with an __int__ method was accepted as a valid value. [273b01861a11] <4.19-maint> 2017-11-05 Phil Thompson * test/int_convertors/mk.sh, test/int_convertors/run_test.py, test/int_convertors/test.h, test/int_convertors/test.sip: Added the test for an overloaded function where the argument of each overload is a different named enum. [cac9082bdbd8] <4.19-maint> 2017-11-02 Phil Thompson * configure.py.in: Ensure that when building on macOS using qmake the sip module is a bundle. [f945942bc896] <4.19-maint> 2017-11-01 Phil Thompson * .hgtags: Added tag 4.19.4 for changeset ed56fb689db8 [c56a33a3ef0c] <4.19-maint> * NEWS: Released as v4.19.4. [ed56fb689db8] [4.19.4] <4.19-maint> 2017-10-09 Phil Thompson * siplib/siplib.c.in: Build fixes for Python v2. [5b2adad49340] <4.19-maint> 2017-09-18 Phil Thompson * sipgen/gencode.c: Fixed a regression that meant that namespaces were included in the types of arguments to signals. Probably only affects PyQtDataVisualization. [5c94d14871a3] <4.19-maint> 2017-09-05 Phil Thompson * sipgen/gencode.c: Appy a cast to const class pointers to static instances. [3db4b02ea152] <4.19-maint> * sphinx/incompatibilities.rst, sphinx/using.rst: Added a section on overflow checking to the documentation. [39409c0a5282] <4.19-maint> * sipgen/gencode.c: Make sure the default value of scoped enums is valid. [5024429c9126] <4.19-maint> 2017-09-04 Phil Thompson * siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/c_api.rst, test/int_convertors/run_test.py, test/int_convertors/test.h, test/int_convertors/test.sip: Deprecated sipCanConvertToEnum(). sipConvertToEnum() now has single- pass behaviour like the integer convertors. [2065bdd284cc] <4.19-maint> 2017-09-02 Phil Thompson * siplib/int_convertors.c, siplib/siplib.c.in: Improved the exception text when a virtual should return an enum or a bool. [7636b12a0789] <4.19-maint> * test/int_convertors/run_test.py, test/int_convertors/test.h, test/int_convertors/test.sip: Added the tests for converting names enums. [8b5be80fda82] <4.19-maint> * siplib/siplib.c.in: Fixed a regression where sipBadCatcherResult() is called without an exception. [894b51685d51] <4.19-maint> * test/int_convertors/run_test.py: Added the remaining bool tests. [1afb586f55db] <4.19-maint> * sipgen/gencode.c, siplib/int_convertors.c, siplib/sip.h.in.in, siplib/sipint.h, siplib/siplib.c.in, sphinx/c_api.rst, test/int_convertors/run_test.py, test/int_convertors/test.h, test/int_convertors/test.sip: Added sipConvertToBool() to the public API. Implemented the tests for invalid bool values. [3e8faabe48a1] <4.19-maint> * test/int_convertors/run_test.py, test/int_convertors/test.h, test/int_convertors/test.sip: Added the tests for converting char. [fb34c9009048] <4.19-maint> * test/int_convertors/run_test.py: Completed the unit tests for unsigned values. [cbb776ab54f9] <4.19-maint> 2017-09-01 Phil Thompson * test/int_convertors/run_test.py: Added the tests for valid values of unsigned types. [895e5218b2a2] <4.19-maint> * test/int_convertors/run_test.py, test/int_convertors/test.h, test/int_convertors/test.sip: Added tests for virtuals returning invalid values. Added the C++ and wrappers for the unsigned types tests. [b42f7afd33bc] <4.19-maint> * test/int_convertors/run_test.py: Fixed the tests for long and long long to account for the legacy behaviour of the convertors. [06c124a19f3c] <4.19-maint> * test/int_convertors/run_test.py, test/int_convertors/test.h, test/int_convertors/test.sip: Implemented the unit tests for int, long and long long integer conversions. [55a8a713a6fc] <4.19-maint> * test/int_convertors/mk.sh, test/int_convertors/run_test.py, test/int_convertors/test.h, test/int_convertors/test.sip: Added the unit tests for signed char and short integer convertors. [1109afd9d851] <4.19-maint> * siplib/siplib.c.in: The type of the exception raised when a Python re-implementation of a C++ virtual raises an exception is now the same as that original exception and not fixed to be TypeError. [61885f427681] <4.19-maint> 2017-08-31 Phil Thompson * sipgen/gencode.c, siplib/siplib.c.in: Fixed a regression in the generation of slots code. [9e09f205e404] <4.19-maint> 2017-08-30 Phil Thompson * sphinx/c_api.rst: Backed out the documentation change for sipConvertToEnum(). [fec7c90f35a2] <4.19-maint> * sipgen/gencode.c, siplib/siplib.c.in, sphinx/c_api.rst: Removed the last call to SIPLong_AsLong(). [b70f7ccc3069] <4.19-maint> * sipgen/gencode.c, siplib/int_convertors.c, siplib/sip.h.in.in, siplib/sipint.h, siplib/siplib.c.in, siplib/siplib.sbf.in, sphinx/c_api.rst: Added sipLong_AsSignedChar() ot the public API. The generated variable setters now use the new convertors. [85bfd5c33ae0] <4.19-maint> * siplib/siplib.c.in: Completed the sip module changes for overflow checking. [c8029d4cc754] <4.19-maint> 2017-08-23 Phil Thompson * siplib/siplib.c.in: Migration of more module code to the new convertors. [b035786f41e8] <4.19-maint> 2017-08-21 Phil Thompson * siplib/array.c, siplib/voidptr.c: The array and voidptr types now use the new convertors. [037839910d09] <4.19-maint> * siplib/int_convertors.c: Completed the implementation of the new integer convertors. [cae1cf5dfa79] <4.19-maint> 2017-08-20 Phil Thompson * sipgen/gencode.c, siplib/int_convertors.c, siplib/sip.h.in.in, siplib/sipint.h, siplib/siplib.c.in, sphinx/c_api.rst: Implemented the int convertor stubs and documented them. [3c4d82a590ac] <4.19-maint> * siplib/int_convertors.c, siplib/sipint.h, siplib/siplib.c.in: Refactored the support for int convertors. [2b1714de0e3f] <4.19-maint> 2017-08-19 Phil Thompson * sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/c_api.rst, sphinx/python_api.rst: Implemented sipEnableOverflowChecking() and sip.enableoverflowchecking() stubs. [56266006c18f] <4.19-maint> 2017-08-13 Phil Thompson * NEWS, sphinx/c_api.rst, sphinx/incompatibilities.rst: Updated the docs regarding support for scoped enums. [0cf1c85b12bd] <4.19-maint> * sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in: Completed the implementation of scoped enums. [d0b2e8967294] <4.19-maint> * siplib/siplib.c.in: Scoped enums are now created as Python enums. [ae7df49152e3] <4.19-maint> * siplib/siplib.c.in, sphinx/c_api.rst: More work on scoped enums. [9a196aece94e] <4.19-maint> 2017-08-12 Phil Thompson * sipgen/gencode.c, sipgen/metasrc/parser.y, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/c_api.rst: Created the stub of the scoped enums implementation. [674f800ed250] <4.19-maint> * sipgen/type_hints.c: Removed some unused variables. [90360e454f86] <4.19-maint> * sipgen/gencode.c, siplib/sip.h.in.in: Remove the const from the source object declaration in assignment helpers. [2b53ba180983] <4.19-maint> 2017-08-11 Phil Thompson * sipgen/metasrc/parser.y: Completed the parser support for scoped enums. [11b383822a47] <4.19-maint> * sipgen/metasrc/parser.y, sipgen/sip.h.in, sphinx/specification_files.rst: Added parser support for scoped enums. [f5b7d5bf0624] <4.19-maint> * sipgen/gencode.c: Use static_cast() when passing values to sipConvertFromEnum(). [091cfd53e597] <4.19-maint> 2017-08-08 Phil Thompson * sipgen/transform.c: Disallow (rather than ignore) invalid types in Python signatures if %MethodCode and a C/C++ signature is provided. [a975983c39c1] <4.19-maint> 2017-08-07 Phil Thompson * sipgen/gencode.c: Fixed a code generation bug in the handling of signals in scoped classes. [7c82958d6327] <4.19-maint> 2017-07-22 Phil Thompson * sipgen/sip.h.in, sipgen/transform.c: Fixes for the detection of recursive imports. [6a7ab03d4efa] <4.19-maint> 2017-07-14 Phil Thompson * sipgen/transform.c: Detect recursive imports as an error. [ba19c3f5fb29] <4.19-maint> 2017-07-03 Phil Thompson * .hgtags: Added tag 4.19.3 for changeset 14685a6e736e [2a9f342b7f39] <4.19-maint> * NEWS: Released as v4.19.3. [14685a6e736e] [4.19.3] <4.19-maint> 2017-07-02 Phil Thompson * sipgen/export.c, sipgen/type_hints.c: Fixes for hidden namespaces in generated XML. [489321fd2475] <4.19-maint> 2017-06-28 Phil Thompson * sphinx/specification_files.rst: Fixed an out of date statement in the docs. [21539b0e74c6] <4.19-maint> 2017-06-22 Phil Thompson * sipgen/metasrc/parser.y, sipgen/sip.h.in: Don't report template arguments of uninstantiated templates as undefined classes. [a69025738247] <4.19-maint> 2017-06-21 Phil Thompson * sipgen/metasrc/parser.y: Allow empty class bodies. [265b531cb6e4] <4.19-maint> * sipgen/gencode.c: Fixed a bug handling double quotes as the default value of a char argument. [d86c23976619] <4.19-maint> 2017-06-16 Phil Thompson * sipgen/main.c, sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/transform.c: Completed the implementation of non-strict parsing. [8b5e498d13dd] <4.19-maint> * sipgen/metasrc/parser.y, sipgen/sip.h.in: The relevant data structures now retain the platform information. [15b6c00166a7] <4.19-maint> * sipgen/gencode.c, sipgen/main.c, sipgen/metasrc/parser.y, sipgen/sip.h.in: Added the stub of non-strict parsing that saves (but otherwise ignores) the platform information. [b05b36a086c2] <4.19-maint> * sipgen/gencode.c, sipgen/metasrc/lexer.l: Improve the handling of string constants to properly support escape characters. [495a7635a52d] <4.19-maint> * sipgen/metasrc/parser.y: Make sure any expanded template ctor call is a deep copy. [141c98e741b6] <4.19-maint> 2017-06-15 Phil Thompson * sipgen/metasrc/parser.y: Expand template ctor calls when they are the default values of an argument. [5df8870c61a7] <4.19-maint> 2017-06-10 Phil Thompson * sipgen/gencode.c: Fixed a regression in the invocation of the dtor of shadow classes. [e833dc3f9a2f] <4.19-maint> 2017-06-06 Phil Thompson * .hgignore: Updated .hgignore for the changed build directory. [b2fb251d3500] <4.19-maint> 2017-05-27 Phil Thompson * siplib/siplib.c.in, sphinx/c_api.rst: Documented the event handler mechanism. [aee09bdf1206] <4.19-maint> * sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in: Implemented sipEventType and sipRegisterEventHandler(). [2a4bcf305afa] <4.19-maint> 2017-05-26 Phil Thompson * sipgen/gencode.c, siplib/objmap.c, siplib/sip.h.in.in, siplib/sipint.h, siplib/siplib.c.in, sphinx/c_api.rst: Renamed sipCommonDtor() to sipInstanceDestroyed() and added it to the public API. [e7d4e6661fa0] <4.19-maint> * sipgen/metasrc/parser.y: The parser will now accept class template definitions within a class. The generated code is untested. [ec57a6e03eb3] <4.19-maint> 2017-05-23 Phil Thompson * sipgen/type_hints.c: Added support for type hints for properties from Scott Maxwell. [c861fe0ef6ca] <4.19-maint> 2017-05-15 Phil Thompson * sipgen/gencode.c: Fixes for 'char *&' argument types. [684e23c995a3] <4.19-maint> 2017-05-05 Phil Thompson * siplib/siplib.c.in: Removed a duplicate call. [afe3d3efc82d] <4.19-maint> * sipgen/gencode.c: Don't try and initialise the result of a virtual when the type is a template. [cce4fe835faf] <4.19-maint> 2017-04-27 Phil Thompson * sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in: Added sipPrintObject() to the public C API. [10e10b1a2d68] <4.19-maint> 2017-04-24 Phil Thompson * sipgen/gencode.c, siplib/siplib.c.in: Fixed regressions in the handling of exceptions. [974a4d77314b] <4.19-maint> * sipgen/transform.c, sphinx/conf.py.in: Minor cosmetic fixes. [4ea35fd2187d] <4.19-maint> 2017-04-05 Phil Thompson * siplib/siplib.c.in: Effectively re-applied changeset dc06058c99dd. If there is a real problem here then we don't yet fully understand it. [95a493a417e8] <4.19-maint> 2017-04-02 Phil Thompson * sipgen/transform.c: Fix a regression so that a shadow class is not generated if there is a private dtor. [6b09a6d578e8] <4.19-maint> 2017-03-30 Phil Thompson * .hgtags: Added tag 4.19.2 for changeset 1df924860f57 [6209a625ac87] <4.19-maint> * NEWS: Released as v4.19.2. [1df924860f57] [4.19.2] <4.19-maint> 2017-03-23 Phil Thompson * siplib/siplib.c.in: Remove an unnecessary comment. [1f31effbc614] <4.19-maint> 2017-03-03 Phil Thompson * siplib/siplib.c.in: Fixed a crash when a user defined class uses sip.wrappertype as it's meta-type but is not derived from sip.simplewrapper. [f5bab1986fbb] <4.19-maint> 2017-02-15 Phil Thompson * .hgtags: Added tag 4.19.1 for changeset ee5ea590d186 [f45eb310f129] <4.19-maint> * NEWS: Released as v4.19.1. [ee5ea590d186] [4.19.1] <4.19-maint> 2017-02-13 Phil Thompson * sipgen/gencode.c: Fixed another regression in deprecated code. [556ca44cc535] <4.19-maint> * sipgen/gencode.c: Fixed some deprecated macros. [23a8ef68306d] <4.19-maint> 2017-02-08 Phil Thompson * siplib/siplib.c.in: Fixed a typo in the implementation of sipEnableGC(). [c15936fc6007] <4.19-maint> 2017-02-05 Phil Thompson * siplib/siplib.c.in: Fixed a doesn't-work-with-old-c-compilers bug. [5775566848d1] <4.19-maint> 2017-02-02 Phil Thompson * sipgen/transform.c: Fixed a regression in the generation of names of protected methods in classes imported from other modules. [948e06cb1921] <4.19-maint> 2017-02-01 Phil Thompson * sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/transform.c: Fixed a regression in determining when a shadow class should be generated. [71a8ee38b2c6] <4.19-maint> 2017-01-31 Phil Thompson * siplib/sip.h.in.in: Updated the ABI version number. [6b23496bd532] <4.19-maint> * sphinx/annotations.rst: Added a clarification to the /Abstract/ class annotation. [adb03184b044] <4.19-maint> * sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/c_api.rst: Added sipEnableGC() to the public API. [03b120e8fe2f] <4.19-maint> 2017-01-29 Phil Thompson * sipgen/metasrc/parser.y: Fixed a couple of missing types. [9737461081da] <4.19-maint> 2017-01-23 Phil Thompson * sipgen/gencode.c: More fixes for /NoTypeName/ applied to class templates. [8a45855e0d70] <4.19-maint> 2017-01-22 Phil Thompson * sipgen/gencode.c, sipgen/metasrc/parser.y, sipgen/sip.h.in: The /NoTypeName/ typedef annotation now affects classes instantiation from class templates. [30d9a5a61ed2] <4.19-maint> 2017-01-21 Phil Thompson * NEWS, sipgen/gencode.c, sipgen/metasrc/lexer.l, sipgen/metasrc/parser.y, sipgen/sip.h.in, sphinx/directives.rst: Added the %PreMethodCode implementation from Robin Dunn. [08d77fb135a2] <4.19-maint> * sipgen/metasrc/parser.y: Properly fix the template super-class regression. [3b674fc274d5] <4.19-maint> * sipgen/metasrc/parser.y: Backed out changeset b94757bc5637 It fixes the bug but breaks everything else. [f39e23bcd25b] <4.19-maint> * sipgen/metasrc/parser.y: Fixed a regression in the handling of template arguments specifying super-classes. [b94757bc5637] <4.19-maint> 2017-01-20 Phil Thompson * README, build.py: Fixed the build.py script so that it does a complete preparation. [85539feb92ea] <4.19-maint> 2017-01-19 Phil Thompson * siplib/siplib.c.in: Fixed sipGetBufferInfo(). [1de5c188f98d] <4.19-maint> 2017-01-10 Phil Thompson * sipgen/gencode.c, sipgen/main.c, sipgen/transform.c, siplib/siplib.c.in, sphinx/command_line.rst: Added the -D command line option so that the generated code is aware of Python debug builds. [2a21ceefdf2a] <4.19-maint> 2017-01-09 Phil Thompson * siplib/siplib.c.in: Hopefully a better implementation of changeset dc06058c99dd. [4c135d33a5cf] <4.19-maint> * siplib/siplib.c.in: Backed out changeset dc06058c99dd The change is too drastic. [d9e95528015e] <4.19-maint> 2017-01-07 Phil Thompson * sipgen/transform.c: Fixed a regression in the ordering of the generated types table for a module. [06237437b446] <4.19-maint> 2016-12-25 Phil Thompson * .hgtags: Added tag 4.19 for changeset 0a4ee5a5511f [245c1ac3c34e] * NEWS: Released as v4.19. [0a4ee5a5511f] [4.19] 2016-12-17 Phil Thompson * sipgen/transform.c: Fixed a problem importing the required types for protected methods without the public/protected hack. [ccf3d8f3cc59] 2016-12-14 Phil Thompson * siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/python_api.rst: Implemented sip.assign() to invoke the C++ assignment operator. [4324a0bc03a4] 2016-11-27 Phil Thompson * configure.py.in, sphinx/installation.rst: Added the --no-stubs and --stubsdir options to configure.py to be consistent with other configuration scripts. [70e0d9d09265] 2016-11-22 Phil Thompson * sipgen/transform.c: Fixed the incomplete tidy-up. [69aaa13a1883] 2016-11-21 Phil Thompson * sipgen/transform.c: Fix a warning message. [5d7b73925360] * sipgen/gencode.c, sipgen/sip.h.in, sipgen/transform.c: Reverted to pre-4.18 handling of the generated cast function. There are cases where a C++ derived class does not have the same address as its single base class. [8e9e02f1bea0] 2016-11-11 Phil Thompson * sipgen/metasrc/parser.y: Fixed a regression (related to scoped names) that meant that header code for template arguments wasn't being included. [04796a24e981] 2016-10-28 Phil Thompson * sipgen/gencode.c: iHandwritten code to be included in the sipAPI*.h file is now placed at the end so that it can make use of the generated macros and types. [ed446493da18] 2016-10-26 Phil Thompson * siplib/siplib.c.in: Fixed some compiler warnings when building for Python v2. [264793ee3fb0] 2016-10-25 Phil Thompson * sipgen/transform.c: Fixed a regression in the handling of abstratc classes. [ce1042e83d1a] * sipgen/gencode.c, sipgen/transform.c: More namespace related fixes. [73d456c2f5cc] 2016-10-18 Phil Thompson * sipgen/gencode.c, sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/transform.c, siplib/siplib.c.in: Implemented 'final' support. More fixes for the handling of scopes. [1d0d5c659b92] 2016-10-17 Phil Thompson * sipgen/metasrc/lexer.l, sipgen/metasrc/parser.y, sipgen/sip.h.in, sphinx/specification_files.rst: Added parser support for the 'final' keyword. [373d57302d56] 2016-10-16 Phil Thompson * sipgen/gencode.c, sipgen/metasrc/parser.y, sipgen/transform.c: Refactored the support for scopes so that types hav a leading '::'. [1f498dfe2888] 2016-10-09 Phil Thompson * sipgen/gencode.c, sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/transform.c: Fixed the generation of the scope of an operator moved from a namespace to a class. [f697ee13a3aa] 2016-10-06 Phil Thompson * sphinx/directives.rst: Documented the %HideNamespace directive. [b45a86055567] * sipgen/gencode.c, sipgen/metasrc/lexer.l, sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/transform.c: Implemented the %HideNamespace directive. [6b1f471385df] 2016-10-05 Phil Thompson * sipgen/gencode.c: Make sure the underlying types are generated in tuple builders. [0507dfae0588] * sipgen/gencode.c: Virtual handlers use typedef names like all the rest of the generated code. [c732f0460bc3] 2016-10-04 Phil Thompson * sipgen/transform.c: Refactored the name lookup code. [8bd669cf535f] 2016-09-29 Phil Thompson * sipgen/gencode.c: Variable getters/setters now only keep a hidden reference for C character strings. [6ec87337d5e2] * sipgen/gencode.c: Fixed a bad indentation in the generated code. [cb1d8e948a2b] 2016-09-25 Phil Thompson * sipgen/gencode.c, sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/transform.c, siplib/qtlib.c, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/using.rst: Removed anll code generator support for PyQt3. [a9cc0cc567aa] 2016-09-24 Phil Thompson * sipgen/transform.c: A class that sub-classes an abstract class and doesn't provide an implementation of an abstract method is itself abstract. [472469f1d7ad] * sipgen/gencode.c, sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/transform.c: Fixes for imported types that have multiple implementations. [dc02dc4430ec] * sipgen/transform.c, siplib/sip.h.in.in: Fixed the selection of a virtual handler. [d6c07e82a3d2] 2016-09-23 Phil Thompson * siplib/sip.h.in.in, siplib/sipint.h: Fixed some regressions when building with the limited API disabled. [8118a2156d11] * siplib/sip.h.in.in, siplib/sipint.h: Exposed some missing macros. [d12bb44a9d7d] * sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/c_api.rst: Added sipGetUserObject() and sipSetUserObject() to the public API. [e0352cc51b67] * sipgen/gencode.c, siplib/sip.h.in.in, siplib/sipint.h, siplib/siplib.c.in: Added sipIsOwnedByPython() and sipIsDerivedClass() to the private API to remove more binary dependencies. [17ed5300e0dc] * sipgen/metasrc/parser.y, siplib/objmap.c, siplib/sip.h.in.in, siplib/siplib.c.in: Fix some warnings. [d0dcc6cd73b9] * sipgen/gencode.c, siplib/sip.h.in.in: Refactored how the plugin-specific generated tables are handled. [a0fcb2bc14ca] 2016-09-22 Phil Thompson * sipgen/transform.c: Fixed the auto-generation of default copy ctors. [508f9dd396f9] * sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in: Implemented the sipCallProcedureMethod() optimisation. [948be90a3f5e] * sipgen/transform.c, siplib/sip.h.in.in: Class based exceptions should now have their type structure included. [64ac366b669f] * siplib/sip.h.in.in, siplib/siplib.c.in: Reorganised the C API structure. [a08c7533a799] * sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in: Completed the refactoring to eliminate binary dependencies. [fb3b72523947] * sipgen/gencode.c, sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/transform.c, siplib/sip.h.in.in, siplib/siplib.c.in: Refactored the implementation of exceptions to eliminate the binary dependencies. [aeb733f23126] * sipgen/gencode.c, sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/transform.c, siplib/sip.h.in.in, siplib/siplib.c.in: Refactored the handling of virtual error handlers to reduce binary dependencies. [b08f6f3325e8] 2016-09-21 Phil Thompson * sipgen/gencode.c, sipgen/sip.h.in, sipgen/transform.c: Genearte the needed types table at the right time. [26331d156a87] * sipgen/gencode.c, sipgen/sip.h.in, sipgen/transform.c: Refactoring of the code that inspects a class for its visible virtuals. [082c756c263d] 2016-09-20 Phil Thompson * sipgen/transform.c: Fixes for regressions using the type header files in the right place. [0b1a09bbde7a] * sipgen/gencode.c, sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/transform.c, siplib/sip.h.in.in: Initial refactoring of virtual handlers. [d454a9b02d26] 2016-09-19 Phil Thompson * sipgen/gencode.c, siplib/siplib.c.in: Generate the correct type names for template based types. [1f17d1688231] * sipgen/gencode.c, sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/transform.c, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/c_api.rst, sphinx/incompatibilities.rst: Refactored the handling of generated type structures so that they are only referenced by name by an importing module rather than by an index into a table. This reduces the binary dependencies between modules. [667720dbc42d] 2016-09-15 Phil Thompson * sipgen/gencode.c, sipgen/metasrc/parser.y, sipgen/sip.h.in, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/directives.rst: Removed the support for module version numbers. [685029cadb52] 2016-09-12 Phil Thompson * siplib/siplib.c.in: Fixed silly bugs in the previous change. [7df5236aa50f] * siplib/sip.h.in.in, siplib/siplib.c.in: Improved the implementation of sipGetBufferInfo(). [7a606d0daf37] 2016-09-09 Phil Thompson * sipgen/export.c, sipgen/type_hints.c: Fixed the type hint for unsigned const char *. [19f9b9eea667] * siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/c_api.rst: Updated sipGetBufferInfo() to optionally check the type. sipGetBufferInfo() only supports 1-dimensional arrays. [985d7877b3a1] 2016-09-08 Phil Thompson * siplib/siplib.c.in: Further fixes for invoking the new type handler. [ecdcfc0f0558] * siplib/objmap.c, siplib/sip.h.in.in, siplib/siplib.c.in: Fixes for the invocation of the new user type handler. [a95c68d37f6e] * siplib/siplib.c.in: Fixed the invocation of the new user type handler. [d484574b76e9] 2016-09-07 Phil Thompson * sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/c_api.rst: Added sipGetBufferInfo() and sipReleaseBufferInfo() to the public API. [c23d7cb8b06e] 2016-09-06 Phil Thompson * siplib/siplib.c.in, sphinx/c_api.rst: Documented the new Unicode-related functions. [c8408349d43c] 2016-09-05 Phil Thompson * sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in: Added sipUnicodeNew(), sipUnicodeWrite() and sipUnicodeData() to the public API. [e05849602bef] 2016-08-30 Phil Thompson * sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/c_api.rst: Added sipGetMethod(), sipFromMethod() and sipGetCFunction() ot the public API. [28f7daaa7542] * sipgen/gencode.c, sipgen/metasrc/parser.y, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/c_api.rst: Added sipCheckPluginForType() ot the public API. sipSetNewUserTypeHandler() now returns the old handler to allow chaining. [7e8e4447431b] 2016-08-29 Phil Thompson * siplib/descriptors.c, siplib/objmap.c, siplib/sip.h.in.in, siplib/siplib.c.in: Renamed some structure fields. [cb8478e5895d] * sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/c_api.rst: Added sipPyTypeDict() to the public API. [7f25c1fe8296] * sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/c_api.rst: Added sipGetFrame() to the public API. [a34c213208b2] * sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/c_api.rst: Added sipIsUserType() to the public API. [d2477eb9265e] * sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/c_api.rst: Added the data and time functions to the public API. [7739c16f94c9] 2016-08-28 Phil Thompson * sphinx/c_api.rst: Documented sipPyTypeName(). [c7098cf08c3a] * sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in: Added sipPyTypeName() to the public API. [319512a38c50] * siplib/sip.h.in.in: Fixed the new macros. [c361a6924e82] * siplib/sip.h.in.in: Implemented additional portablity macros for the limited API. [120e916e8608] * .hgignore, sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/c_api.rst, sphinx/using.rst: Implemented sipSetNewUserTypeFunc() sipSetTypeUserData() and sipGetTypeUserData(). [1f180cf4a42a] 2016-08-25 Phil Thompson * siplib/apiversions.c, siplib/array.c, siplib/array.h, siplib/descriptors.c, siplib/objmap.c, siplib/qtlib.c, siplib/sip.h.in.in, siplib/sipint.h, siplib/threads.c, siplib/voidptr.c, sphinx/c_api.rst, sphinx/directives.rst: Added the user field to the sipWrapperType structure as an alternative to defining a super-type of sipWrapperType (which isn't possible with the limited API). Bumped the major ABI version number. [5e9de8cde212] 2016-08-24 Phil Thompson * sipgen/gencode.c, sipgen/metasrc/lexer.l, sipgen/metasrc/parser.y, sipgen/sip.h.in, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/directives.rst: Added the use_limited_api argument to the %Module directive. Changed the API of %BIGetBufferCode when using the limited API. [10d7121c07e3] 2016-08-23 Phil Thompson * rbproduct.py: Merged the 4.18-maint branch into the trunk. [d92384aa5baf] * sipgen/gencode.c: Fixed the handling of global unsigned constants. [a45bec408ec2] <4.18-maint> * sphinx/conf.py.in: Fixed the copyright notice in the docs. [17475357a153] <4.18-maint> 2016-08-08 Phil Thompson * README, build.py: Removed the old internal build system leaving the minimum needed to build from hg without the new build system. [dbbced5689a8] <4.18-maint> 2016-07-25 Phil Thompson * .hgtags: Added tag 4.18.1 for changeset 81021a5690ce [8f5b6c8fe5f1] <4.18-maint> * NEWS: Released as v4.18.1. [81021a5690ce] [4.18.1] <4.18-maint> 2016-07-22 Phil Thompson * Roadmap.rst: Updated the Roadmap. [1226013f2516] <4.18-maint> * NEWS: Updated the NEWS file. [26a4fd92bf59] <4.18-maint> 2016-07-03 Phil Thompson * siplib/objmap.c: Fixed a problem with stale aliases for objects created by C/C++. [b493c6f3e015] <4.18-maint> 2016-06-21 Phil Thompson * rb-product, rbproduct.py: Replaced the product plugin with a product file. [a10b0caa91a8] <4.18-maint> 2016-06-20 Phil Thompson * rbproduct.py: Product plugin changes for rb-tools API changes. [86f51ad3ac30] <4.18-maint> * rbproduct.py: Debugged the product plugin. [67a81861273c] <4.18-maint> * rbproduct.py: Added support for a minimal build and release build types. [8cc794662db5] <4.18-maint> 2016-06-18 Phil Thompson * rbproduct.py: Tewaks to the product plugin. [b2fd658f11cf] <4.18-maint> 2016-06-15 Phil Thompson * rbproduct.py: Debugged the support for rb-release. [38cdb78872f4] <4.18-maint> 2016-06-13 Phil Thompson * rbproduct.py: Updated the product plugin to support rb-release. [ecb166af3ad3] <4.18-maint> 2016-06-10 Phil Thompson * sipgen/gencode.c: Fixed a regression in the handling of a cast with a diamond hierachy. [91206af66161] <4.18-maint> 2016-06-02 Phil Thompson * rbproduct.py: Implemented the different build types. [15184d86e394] <4.18-maint> * rbproduct.py: Updates to the product plugin. [23ca59449373] <4.18-maint> 2016-06-01 Phil Thompson * rbproduct.py: Updated the product plugin to simplify the class hierachy. [a977c7f870f7] <4.18-maint> * .hgignore, rbproduct.py: The product plugin will now do a default build. [8c433398f573] <4.18-maint> 2016-05-09 Phil Thompson * rbproduct.py: Updated the product plugin for the latest rbtools changes. [a4a0a84984dc] <4.18-maint> 2016-05-05 Phil Thompson * configure.py.in: Fixed a bug in out-of-source builds. [f9602fd24f17] <4.18-maint> 2016-04-22 Phil Thompson * METADATA.in: Updated the meta-data to say that 64-bit Linux wheels are available at PyPI. [5602445cb458] <4.18-maint> 2016-04-13 Phil Thompson * .hgtags: Added tag 4.18 for changeset b51768a1749e [1da474e6ccc1] * NEWS, sphinx/specification_files.rst: Released as v4.18. [b51768a1749e] [4.18] * METADATA.in, sipgen/export.c, sipgen/type_hints.c: Fixed the type hints for arrays. [02a712634ce1] 2016-04-09 Phil Thompson * METADATA.in: Updated the description in the meta-data. [d9eb656132f3] 2016-04-08 Phil Thompson * METADATA.in: Further tweak to METADATA.in. [9acfb4baa44c] * METADATA.in: Use v1.1 meta-data rather than v2.0. [8d9645471343] * METADATA.in: Fixed a typo. [4a9ee34e65c3] * METADATA.in, rbproduct.py: Added the METADATA.in file. [39106871989b] 2016-04-05 Phil Thompson * rbproduct.py: Updated the product plugin. [e42e999389f9] * rbproduct.py: Added the rbtools product plugin. [b9ba57967915] 2016-03-30 Phil Thompson * sphinx/incompatibilities.rst: Fixed a Sphinx warning message. [ae966103325c] * sipgen/main.c, sipgen/sip.h.in, sipgen/transform.c: Fixed the use of SIP_NORETURN. [b3a916e0bc78] 2016-03-25 Phil Thompson * sipgen/export.c: Fixed a regression in the exporting of the XML API files. [c7714bbbdae7] * build.py, sphinx/build_system.rst, sphinx/c_api.rst, sphinx/python_api.rst: Adopt the new standards for naming development versions. [72140f544ef1] * sphinx/annotations.rst: Fixed a bug in the documentation. [9e4ee12928cd] * .hgignore: Added the .hgignore file. [e1d2556ce4a2] 2016-03-04 Phil Thompson * sipgen/gencode.c: __long__ gets translated to __int__ for Python v3. [a4f8a7810cc3] 2016-03-01 Phil Thompson * sipgen/type_hints.c, sphinx/annotations.rst: Type hints are ignored if an argument is constrained. [f041cf891a29] * sipgen/type_hints.c: Implement the flattening of Unions in type hints. [ff5f0d0251e0] 2016-02-29 Phil Thompson * sipgen/sip.h.in, sipgen/type_hints.c: Reimplemented the type hint parser so it can handle recursive definitions properly. [506e30d92b51] 2016-02-27 Phil Thompson * sipgen/type_hints.c: Fixed type hints for enums in mapped types. [efb04ab24462] * sipgen/type_hints.c: Fixed type hints for the return values of functions. [b5c392c71f78] * sipgen/type_hints.c: Added Iterable to the list of known typing module objects. [a1d1a573a304] 2016-02-26 Phil Thompson * sipgen/sip.h.in, sipgen/type_hints.c: Fixed the handling of recursively defined type hints. [b5abe12b4968] 2016-02-25 Phil Thompson * sipgen/sip.h.in, sipgen/type_hints.c: The typing module is now imported as a whole rather than individual objects. [ac67b3f0bd95] 2016-02-24 Phil Thompson * sip.pyi: Fixed the Buffer type hint. [78a799aec114] * sipgen/type_hints.c: Don't generate type hints for the sequence concat and repeat slots (and the inplace versions). [a5ae3982ff5f] * sipgen/metasrc/parser.y, sphinx/directives.rst: Exported type hint code is no longer included in the module that defines it. [442b3ed07ae6] * sipgen/type_hints.c: Exclude external classes when looking up a class. [61fe4c76a394] * sipgen/transform.c, sipgen/type_hints.c: Fixed type hints and docstrings for const template arguments. [679c13adda6a] * sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/type_hints.c, sphinx/directives.rst: %TypeHintCode can now be used in a class. [053c7351dba2] 2016-02-19 Phil Thompson * sipgen/type_hints.c: Don't generate type hints for slots that can return Py_NotImplemented. Make sure callables generate a valid (but vague) type hint. [883918a8dc36] 2016-02-18 Phil Thompson * sip.pyi, sipgen/type_hints.c: Tweaks to the type hint support. [785978d8f7e3] 2016-02-16 Phil Thompson * sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/transform.c, sipgen/type_hints.c, sphinx/annotations.rst: Added the /TypeHint/, /TypeHintOut/ and /TypeHintValue/ class annotations. [4f5dc2c51d06] * sipgen/type_hints.c: Moved the old-style signal/slot type hints to PyQt4. [4689a40f7e7d] 2016-02-15 Phil Thompson * sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/transform.c, sphinx/annotations.rst: Implemented /TypeHintValue/ as a mapped type annotation. [2418e7f7760d] * build.py: Make sure sip.pyi is included in the source package. [1eabde271e53] 2016-02-11 Phil Thompson * sipgen/gencode.c, sipgen/metasrc/lexer.l, sipgen/metasrc/parser.y, sipgen/transform.c, siplib/siplib.c.in: Eliminate a few compiler warnings. [e864a0451a4a] 2016-02-10 Phil Thompson * sipgen/type_hints.c: More fixes for Optional handling. [365d31de81fd] * sipgen/type_hints.c: Use Optional properly. [ab7d66d1ea0d] 2016-02-09 Phil Thompson * sipgen/type_hints.c: PY_TYPE and PY_SLICE aren't actually needed. [9778770c65a5] 2016-02-08 Phil Thompson * sipgen/type_hints.c: Fixed the translation of Any to object in docstrings. [7571d96c1f79] * sipgen/export.c, sipgen/gencode.c, sipgen/sip.h.in, sipgen/type_hints.c: Docstrings now use a format based on type hints. [9de9b0470aa6] 2016-02-05 Phil Thompson * sipgen/transform.c: Don't complain about a lack of %SetCode when /NoSetter/ is specified. [cf4db5eb171a] * sipgen/metasrc/parser.y: Fixed some typos in error messages. [82a34911686f] * sipgen/metasrc/lexer.l, sipgen/metasrc/parser.y, sphinx/directives.rst: Renamed %ModuleTypeHintCode to %TypeHintCode. [73b214c14dde] * sipgen/type_hints.c, sphinx/annotations.rst: Documented the /NoTypeHint/ annotations. [26e59a86ca45] * sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/transform.c, sipgen/type_hints.c: Implemented the /NoTypeHint/ annotation. Fixed a bug to make sure type header code is included before enum slot code needs it. [1943d4866c73] * sipgen/metasrc/parser.y, sipgen/type_hints.c: More flexible handling of ellipsis when /NoArgParser/ is specified. [7097a0008042] * sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/type_hints.c: Protect against (possible) recursion when handling type hints for mapped types. [9402857f5eb6] * sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/transform.c, sipgen/type_hints.c: Fixed class /TypeHintIn/ when used with a template. [3a914d9789e0] 2016-02-04 Phil Thompson * sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/type_hints.c, sphinx/annotations.rst: Added /TypeHintIn/ as a class annotation. [92d3d32ebf64] 2016-02-03 Phil Thompson * sipgen/export.c, sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/transform.c, sipgen/type_hints.c: Completed the implementation of /TypeHintIn/ and /TypeHintOut/. [70e9172c61b7] * sipgen/export.c, sipgen/metasrc/parser.y, sipgen/sip.h.in: Implement /TypeHintValue/ as a synonym for /DocValue/ for the moment. [df8230d91f9f] * sipgen/metasrc/parser.y, sphinx/annotations.rst: Adde the stubs of the /TypeHintIn/, /TypeHintOut/ and /TypeHintValue/ annotations. [aeb5d848b98a] * sipgen/metasrc/parser.y, sphinx/annotations.rst: Deprecated /DocType/ and /DocValue/. [ec369060cd94] * sipgen/main.c, sipgen/metasrc/parser.y, sipgen/type_hints.c, sphinx/command_line.rst: Added the -f command line option to treat warnings as errors. [fc945a2d732f] 2016-02-02 Phil Thompson * sipgen/type_hints.c: Added Iterator and Mapping to the objecys imported from typing. [6d439bc77538] * sipgen/type_hints.c: Fixed references to mapped types imported from other modules. [b579781f2a2a] * sipgen/type_hints.c: Don't try and create type hints for global slots. [11562a825b7c] * sipgen/type_hints.c: Bug fix when looking up enums. [a4b89fac02d3] * sipgen/type_hints.c: Added PEP 484 support for composite modules. [99e626f4fd23] * sipgen/type_hints.c: Fixed PEP 484 support for all callables with a non-default API version. [b2f8e2fed83d] * sipgen/type_hints.c: Completed the PEP 484 support for mapped types. [b06408ae2397] * sipgen/export.c, sipgen/sip.h.in, sipgen/type_hints.c: More PEP 484 bug fixes. [3e4df4d97ba5] 2016-01-31 Phil Thompson * NEWS, sphinx/directives.rst, sphinx/specification_files.rst: Documented the %ExportedTypeHintCode and %ModuleTypeHintCode directives. [cc7f789360b8] * NEWS, sipgen/metasrc/lexer.l, sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/type_hints.c, sphinx/directives.rst: Added the %ExportedTypeHintCode and %ModuleTypeHintCode directives. [aef93197b065] * sipgen/metasrc/parser.y, sipgen/type_hints.c, sphinx/annotations.rst: Renamed /HintType/ to /TypeHint/. [70c8915f680a] 2016-01-30 Phil Thompson * sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/type_hints.c: More PEP 484 support. [ea6e7a7ae51f] 2016-01-29 Phil Thompson * sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/transform.c, sipgen/type_hints.c: More PEP 484 support. [aa1228396424] 2016-01-28 Phil Thompson * sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/transform.c, sipgen/type_hints.c: Added the stubs for parsing /HintType/ annotations. [7c0fac66f27c] * sipgen/gencode.c, sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/transform.c, sipgen/type_hints.c: Improved the lookup of QObject. [a2d8330df89d] 2016-01-27 Phil Thompson * sipgen/type_hints.c: More PEP 484 support. [336749ea71c5] * sipgen/type_hints.c, sphinx/annotations.rst: HintType will now fallback to DocType if the latter is specified. [4423da336fbb] * sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/transform.c, sipgen/type_hints.c, sphinx/annotations.rst: Added the /HintType/ annotation. [2985d2d641d4] * sipgen/type_hints.c: More PEP 484 support. [21e70ef4b15f] 2016-01-26 Phil Thompson * sipgen/sip.h.in, sipgen/type_hints.c: More PEP 484 support. [dd04be5e4e4f] * sipgen/export.c, sipgen/gencode.c, sipgen/sip.h.in, sipgen/type_hints.c: More support for PEP 484. [353fe29217fb] * siplib/siplib.c.in: Reverted the use of simplewrapper for mapped types. [14ba1e5b1e5b] * siplib/siplib.c.in: Namespaces and mapped types now default to simplewrapper as their super-type. [f7fd77d1cd4e] 2016-01-25 Phil Thompson * sipgen/export.c, sipgen/gencode.c, sipgen/main.c, sipgen/sip.h.in, sipgen/sipgen.sbf, sipgen/type_hints.c, sphinx/command_line.rst, sphinx/introduction.rst.in: Initial support for generating PEP484 type hints. [4191467f125a] * sip.pyi: Added None return types to the stub file. [314ef3cd76ed] 2016-01-24 Phil Thompson * configure.py.in: Hard-code the name of the stub file (rather than handle bespoke module names). [e1e4b29eb1a6] * configure.py.in, sip.pyi, sphinx/installation.rst: Added the sip.pyi type hints stub file. [30e58feee19f] 2016-01-22 Phil Thompson * sphinx/c_api.rst: Minor docs change. [dd03f114259c] 2016-01-17 Phil Thompson * sipgen/metasrc/parser.y, sphinx/specification_files.rst: Deprecated SIP_SLOT. [2b821ae5e9f1] * Roadmap.rst: Updated the roadmap. [495ebc034f99] * sphinx/annotations.rst: Deprecated the SingleShot annotation. [aa46307e00b4] * sipgen/metasrc/parser.y: Deprecated SIP_RXOBJ_CON and SIP_SLOT_CON. [affb0c5b465c] 2016-01-16 Phil Thompson * sipgen/metasrc/parser.y, sphinx/specification_files.rst: Deprecated SIP_SIGNAL. [865e00b6ffa0] 2016-01-15 Phil Thompson * sipgen/metasrc/parser.y, sphinx/specification_files.rst: Deprecated SIP_ANYSLOT. [8199aa8980e8] * sipgen/metasrc/parser.y, sphinx/specification_files.rst: Deprecated SIP_QOBJECT. [fb9c94746255] * sipgen/metasrc/parser.y, sphinx/specification_files.rst: Deprecated SIP_RXOBJ_DIS. [0f26db165557] * sipgen/metasrc/parser.y, sphinx/specification_files.rst: Deprecated SIP_SLOT_DIS. [051775601278] 2016-01-10 Phil Thompson * Merged the current maintenance branch. [b7bd085548b6] * sipgen/gencode.c, sipgen/transform.c: Fixes to the handling of fatal errors. [f35ebfa4c27f] <4.17-maint> * Merged the current maintenance branch with the default. [d244ec3a2dec] 2016-01-09 Phil Thompson * configure.py.in, sipgen/export.c, sipgen/gencode.c, sipgen/main.c, sipgen/metasrc/lexer.l, sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/transform.c, siplib/siplib.c.in: Fixed all compiler warnings. [9dbdf30558aa] <4.17-maint> * sipgen/metasrc/parser.y, sipgen/sip.h.in, siplib/siplib.c.in, sphinx/specification_files.rst: Some minor tidy-ups. [b4edb1990e23] <4.17-maint> * Merged the current maintenance branch with the default. [782cf5e8441e] 2015-12-20 Phil Thompson * sipgen/gencode.c: Another attempt and preventing accesses to SIP data structures after the interpreter has gone. [138eb1eded99] <4.17-maint> 2015-12-18 Phil Thompson * sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/c_api.rst: Added sipGetInterpreter() to the public API. Avoid the Python interpreter if it has gone when getting a QMetaObject. [61d8f0f6f5c0] <4.17-maint> 2015-12-12 Phil Thompson * siplib/siplib.c.in: Cleared a benign exception in the handling of mixins. [602884540b54] <4.17-maint> 2015-12-02 Phil Thompson * siplib/siplib.c.in: Fixed the previous fix. [17876e15c41d] <4.17-maint> 2015-11-25 Phil Thompson * siplib/siplib.c.in: Restrict the invocation of sub-class convertors to those that handle direct sub-classes. [57cbe5142d57] <4.17-maint> 2015-10-28 Phil Thompson * siplib/siplib.c.in: Invoking sub-class convertor code turns out to be quite expensive so check the object map first. Check the object map again if the convertor code needed to be invoked. This change is absolutely fundamental to the inner workings so may have some unexpected consequences. [77fde6c0ee2d] <4.17-maint> 2015-10-27 Phil Thompson * sipgen/gencode.c, sipgen/sip.h.in, sipgen/transform.c, siplib/siplib.c.in: Refactored the handling of casts so that cast functions are only generated for classes that multiply inherit somewhere in their class hierarchy. [14bfbaf7431a] <4.17-maint> 2015-10-24 Phil Thompson * .hgtags: Added tag 4.17 for changeset 0cbb680b4f69 [36d16e74cf7f] * NEWS: Released as v4.17. [0cbb680b4f69] [4.17] 2015-09-10 Phil Thompson * siplib/sip.h.in.in: Fix extensions that use Python v3.5 slots but are being built with an earlier version. [9102d6c3daf0] 2015-09-08 Phil Thompson * specs/win32-msvc2015: Tweak win32-msvc2015 to suppress a warning message. [74754ca3e59f] * configure.py.in, specs/win32-msvc2010, specs/win32-msvc2015: Added win32-msvc2015 to the build system. [fca4f2fcbb39] 2015-09-03 Phil Thompson * siplib/sip.h.in.in: Added a comment about adding new slot types and its effect on the ABI. [50af972e1652] 2015-09-02 Phil Thompson * sipgen/gencode.c, sipgen/metasrc/parser.y, sipgen/sip.h.in, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/specification_files.rst: Added support for PEP 492, ie. the __await__, __aiter__ and __anext__ special methods. [f5d07b919355] * sipgen/metasrc/parser.y, siplib/siplib.c.in: Add __aenter__ and __aexit__ and non-lazy methods. [979e23401d1d] * sipgen/metasrc/parser.y: Fixed a regression in the handling of the __len__ annotation. [cad3bdaecf3e] * sphinx/static/default.css: Merged the 4.16-main branch into the trunk. [b4f30681b90f] * sipgen/gencode.c, sipgen/metasrc/parser.y, sipgen/sip.h.in, siplib/sip.h.in.in, siplib/siplib.c.in, siplib/voidptr.c, sphinx/annotations.rst, sphinx/specification_files.rst: Implemented support for PEP465 (array infix operator) ie. the __matmul__ and __imatmul__ special methods and function annotations of the same name. [ff867feb8f90] <4.16-maint> * siplib/voidptr.c: Tweaked an exception message to follow the style adopted in Python v3.5. [e98693bf17d7] <4.16-maint> 2015-08-02 Phil Thompson * siplib/siplib.c.in: Fixed the error handling of sipCallMethod() when a re-implementation raises an exception. [27c61f660fba] <4.16-maint> 2015-07-17 Phil Thompson * .hgtags: Added tag 4.16.9 for changeset 87de938efba2 [90aaa31768c9] <4.16-maint> * NEWS: Released as v4.16.9. [87de938efba2] [4.16.9] <4.16-maint> * sipgen/export.c: Added the "virtual" attribute to the exported XML. [e37fcc2e29e2] <4.16-maint> 2015-07-10 Phil Thompson * siplib/siplib.c.in: Improved the detail of the text of the exception sipBadCatcherResult() raises. [4f7ad0a4e353] <4.16-maint> * siplib/siplib.c.in: Allow for an /External/ class being referenced when the module containing its implementation hasn't been imported. [1574043cc948] <4.16-maint> 2015-07-07 Phil Thompson * siplib/siplib.c.in: Fix a problem caused by PyQt4 wrapping the QApplication C++ instance as multiple Python objects. [42a056fbf006] <4.16-maint> 2015-06-30 Phil Thompson * siplib/siplib.c.in: Remove an object from the map whenever the pointer ot the C/C++ instance is cleared. [8dd533ab6ce9] <4.16-maint> 2015-06-20 Phil Thompson * sipgen/gencode.c: Fixed a missing reference in the previous fix. [1a2704282933] <4.16-maint> * sipgen/gencode.c: Fixed a regression in the handling of static non-pointer object variables. [dafbaadea76b] <4.16-maint> 2015-06-11 Phil Thompson * .hgtags: Added tag 4.16.8 for changeset f87e232098eb [95abaccb67d6] <4.16-maint> * NEWS: Released as v4.16.8. [f87e232098eb] [4.16.8] <4.16-maint> 2015-06-09 Phil Thompson * siplib/sip.h.in.in: Bump the internal API version number. [6069463e8937] <4.16-maint> * sipgen/gencode.c, sipgen/metasrc/parser.y, siplib/sip.h.in.in, siplib/siplib.c.in: Fixed the handling of non-pointer object variables so that they are only wrapped once and the Python object cached. [11a92ebd4840] <4.16-maint> 2015-06-08 Phil Thompson * sphinx/using.rst: Fixed a type in the docs. [7d0d2cede024] <4.16-maint> 2015-06-02 Phil Thompson * NEWS: Updated the NEWS file. [92c83f02758f] <4.16-maint> 2015-05-24 Phil Thompson * sipgen/metasrc/parser.y, sphinx/specification_files.rst: Added support for the current Python3 exceptions. [79afcf752c2a] <4.16-maint> 2015-05-08 Phil Thompson * siplib/siplib.c.in: Fixed bugs maintaining the deleted state of wrapped instances. [e5674f034e48] <4.16-maint> 2015-03-25 Phil Thompson * sipgen/metasrc/parser.y: Fixed a regression in v4.16.7 that affects methods with %MethodCode and the __len__ annotation. [765b6874363f] <4.16-maint> * .hgtags: Added tag 4.16.7 for changeset 9076f70a012c [dffe9ad569c9] <4.16-maint> * NEWS: Released as v4.16.7. [9076f70a012c] [4.16.7] <4.16-maint> * sphinx/static/classic.css, sphinx/static/default.css: Fixed the stylesheet. [af2e27024d33] <4.16-maint> 2015-03-21 Phil Thompson * sipgen/gencode.c: Fix the declaration of sipRes in the %VirtualCallCode support. [bd92aad3cf7d] <4.16-maint> 2015-03-19 Phil Thompson * sphinx/specification_files.rst: Added %VirtualCallCode to the BNF. [cf1ad8f7be68] <4.16-maint> * sphinx/directives.rst: Documented %VirtualCallCode. [752beb1cd641] <4.16-maint> * sipgen/gencode.c, sipgen/metasrc/lexer.l, sipgen/metasrc/parser.y, sipgen/sip.h.in: Renamed %InvokeCode to %VirtualCallCode and only use it in a generated virtual reimplementation. [82c8303a8041] <4.16-maint> * sipgen/gencode.c, sipgen/metasrc/lexer.l, sipgen/metasrc/parser.y, sipgen/sip.h.in: Implemented the %InvokeCode directive. [d85f3584b06f] <4.16-maint> * siplib/siplib.c.in: Fixed the handling of keyword argument when keywords can be used for all arguments. [2ae037bbfa23] <4.16-maint> * sphinx/directives.rst: Fixed a documentation typo. [fb4c980c92cc] <4.16-maint> * sipgen/gencode.c, sipgen/sip.h.in, sipgen/transform.c: Backed out changeset 9e11298be101 A more correct solution is required. [e212465fed26] <4.16-maint> 2015-03-16 Phil Thompson * sipgen/gencode.c, sipgen/sip.h.in, sipgen/transform.c: Reverted to the pre-v4.15 behavour when generating the scope of a call to a virtual implementation where the scope may be ambiguous. This may not be the right call, but at least the code compiles. [9e11298be101] <4.16-maint> 2015-03-11 Phil Thompson * sipgen/gencode.c, sipgen/transform.c: Fixed a bug where the original typedef of an argument of a mapped template type was being corrupted. [f652446e2462] <4.16-maint> * sphinx/conf.py.in: Updated for sphinx v1.3. [569a9695bc2f] <4.16-maint> * sipgen/sip.h.in: Fixed a regression in the handling of module flags. [3f8c05ac8e47] <4.16-maint> 2015-02-25 Phil Thompson * .hgtags: Added tag 4.16.6 for changeset 1c5f5c8c7416 [6c73a1f41add] <4.16-maint> * NEWS: Released v4.16.6. [1c5f5c8c7416] [4.16.6] <4.16-maint> * NEWS: Updated the NEWS file. [bf261aa4b322] <4.16-maint> 2015-02-23 Phil Thompson * sipgen/gencode.c: Added support for module-level PyObjects. [136913548818] <4.16-maint> 2015-02-14 Phil Thompson * configure.py.in: Installing into a virtual env should now work. [5e133f99d74e] <4.16-maint> * siplib/siplib.c.in: Fixed the handling of an empty dict of keyword arguments. [5f5542824235] <4.16-maint> 2015-02-09 Phil Thompson * sipgen/main.c, sphinx/command_line.rst: The -T command line option is now ignored and deprecated. Timestamps in generated files are always disabled. [9b1a195afe04] <4.16-maint> * sipgen/main.c, sphinx/command_line.rst: Added support for the '@file' format for passing additional command line options in a file. [6c270132db87] <4.16-maint> 2015-02-07 Phil Thompson * sipgen/main.c, sphinx/command_line.rst: Deprecated the -z option to the code generator. [b1dff38b9766] <4.16-maint> 2015-02-06 Phil Thompson * siplib/siplib.c.in: Fixed a couple of compiler warnings. [d653de687fd4] <4.16-maint> 2015-02-04 Phil Thompson * Merged the current 4.16-maint branch into the trunk. [f207b8886557] 2015-01-30 Phil Thompson * siplib/siplib.c.in: Fixed the lookup of slots. [56c254273cd8] <4.16-maint> 2015-01-05 Phil Thompson * sipgen/metasrc/parser.y: Fixed an invalid deprecation warning. [3c5425fa3c80] <4.16-maint> 2015-01-02 Phil Thompson * sipgen/gencode.c, sipgen/metasrc/parser.y, sipgen/sip.h.in, sphinx/annotations.rst: Added the /FileExtension/ class annotation. [51f7769fe32f] <4.16-maint> * LICENSE, Roadmap.rst, build.py, configure.py.in, sipgen/export.c, sipgen/extracts.c, sipgen/gencode.c, sipgen/heap.c, sipgen/main.c, sipgen/metasrc/lexer.l, sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/sipgen.sbf, sipgen/transform.c, siplib/apiversions.c, siplib/array.c, siplib/array.h, siplib/bool.cpp, siplib/descriptors.c, siplib/objmap.c, siplib/qtlib.c, siplib/sip.h.in.in, siplib/sipint.h, siplib/siplib.c.in, siplib/siplib.sbf.in, siplib/threads.c, siplib/voidptr.c, siputils.py, sphinx/conf.py.in, sphinx/directives.rst: Updated the copyright notices. [ccd0bdd9b21c] <4.16-maint> * siputils.py, sphinx/build_system.rst, sphinx/c_api.rst, sphinx/python_api.rst: Updated the docs in preparation for snapshots being called previews. [c42e02f71e27] <4.16-maint> 2014-12-31 Phil Thompson * sipgen/gencode.c: Fixed a code generation bug when a C/C++ argument was a pointer to a struct/class and the Python argument was a void*. [51b0b1f31cea] <4.16-maint> 2014-12-25 Phil Thompson * configure.py.in, siputils.py: Fixed the --target-py-version flag to configure.py. [0e9e078d2d18] <4.16-maint> 2014-12-24 Phil Thompson * .hgtags: Added tag 4.16.5 for changeset 9c27ed5e0d77 [6aa131ac48e8] <4.16-maint> * NEWS: Released as v4.16.5. [9c27ed5e0d77] [4.16.5] <4.16-maint> 2014-12-23 Phil Thompson * sipgen/gencode.c: Fixed SIP_SLOT_CON and SIP_SLOT_DIS so that they generate const char*. [7f4c922a779f] <4.16-maint> 2014-12-18 Phil Thompson * siplib/array.c, siplib/voidptr.c, sphinx/c_api.rst, sphinx/python_api.rst: Added sip.voidptr.asarray(). [d3b5a974ac69] <4.16-maint> 2014-12-07 Phil Thompson * siplib/voidptr.c: Updated a deprecated definition of method arguments. [529b8cd2ab89] <4.16-maint> 2014-11-29 Phil Thompson * siputils.py: Fixed a regression when adding the VPATH support for moc. [c2c285a80412] <4.16-maint> 2014-11-16 Phil Thompson * build.py: A source package now includes a full ChangeLog. [c005a6d2e53e] <4.16-maint> 2014-11-05 Phil Thompson * siputils.py: Build system fix so that generated Makefiles support VPATH with moc. [3f9301ccb08a] <4.16-maint> 2014-11-04 Phil Thompson * configure.py.in, siputils.py, sphinx/build_system.rst: Fixed bugs with out-of-tree builds. [4579c80da1be] <4.16-maint> * sphinx/build_system.rst, sphinx/distutils.rst: Updated the docs regarding the build system and SIP v5. [2828a3bb25af] <4.16-maint> * sphinx/c_api.rst: Updated the docs for sip.SIP_VERSION_STR. [04e7630e6a41] <4.16-maint> 2014-11-03 Phil Thompson * build.py: Removed the reference to MacHg in the internal build script. [b1668849c472] <4.16-maint> 2014-10-23 Phil Thompson * .hgtags: Added tag 4.16.4 for changeset c5d0da367a1e [cb045f5e074a] <4.16-maint> * NEWS: Released as v4.16.4. [c5d0da367a1e] [4.16.4] <4.16-maint> 2014-10-19 Phil Thompson * sipgen/gencode.c: Fixed a code generation bug related to encoded C string arguments to virtuals. [f230cfcebc36] <4.16-maint> 2014-10-15 Phil Thompson * siplib/descriptors.c: Minor fix for Python v2.5 and earlier. [3b7f6957ae4b] <4.16-maint> 2014-10-06 Phil Thompson * siplib/siplib.c.in: Reimplemented the __qualname__ support for enums so that it is always non_NULL (because Python accesses the value directly internally and doesn't go through the attribute interface). [c2cfa151229a] <4.16-maint> 2014-10-04 Phil Thompson * siplib/sip.h.in.in, sphinx/c_api.rst: Removed SIP_REACQUIRE_GIL as we no longer need it. [7e026c2613ec] <4.16-maint> * sipgen/transform.c: Fixed a recent regression in the de-duplication of virtual catchers. [65abadff114d] <4.16-maint> 2014-10-03 Phil Thompson * siplib/sip.h.in.in, sphinx/c_api.rst: Added SIP_REACQUIRE_GIL. [9ff042abc188] <4.16-maint> 2014-10-01 Phil Thompson * sipgen/gencode.c, sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/transform.c, sphinx/annotations.rst: Added the /AbortOnException/ function annotation. [835f4d6bcb99] <4.16-maint> * sipgen/gencode.c, sipgen/metasrc/parser.y, sipgen/transform.c, sphinx/annotations.rst: Added the /DisallowNone/ function annotation. [8b2f4c02e106] <4.16-maint> * sipgen/export.c, sipgen/gencode.c, sipgen/metasrc/parser.y, sipgen/sip.h.in, sphinx/annotations.rst: Implemented the /DisallowNone/ argument annotation. [d3a7fd6b1344] <4.16-maint> * sipgen/metasrc/parser.y, sipgen/transform.c, sphinx/annotations.rst, sphinx/c_api.rst: Added the AllowNone function annotation. [9d52162606b5] <4.16-maint> 2014-09-26 Phil Thompson * sipgen/transform.c: Virtual handlers with handwritten code can no longer be considered to be the same. [a4c712b72828] <4.16-maint> 2014-09-11 Phil Thompson * .hgtags: Added tag 4.16.3 for changeset 8ead57151bd1 [de0c3c076ab3] <4.16-maint> * NEWS: Released as v4.16.3. [8ead57151bd1] [4.16.3] <4.16-maint> 2014-09-04 Phil Thompson * NEWS: Updated the NEWS file. [b5de96615389] <4.16-maint> 2014-09-03 Phil Thompson * siplib/array.c, siplib/bool.cpp, siplib/siplib.c.in: Eliminated all compiler warnings when building on Windows with qmake. [1a321ad68223] <4.16-maint> 2014-09-02 Phil Thompson * siplib/siplib.c.in: Enums now support PEP 3155 fro Python v3.3 and later. [a3f8a9b56659] <4.16-maint> 2014-07-10 Phil Thompson * build.py, configure.py.in: Added fixes for QTBUG-39300. [53f490fe8f52] <4.16-maint> 2014-07-03 Phil Thompson * .hgtags: Added tag 4.16.2 for changeset 4eb546b2c208 [21412c346e75] <4.16-maint> * NEWS: Released as v4.16.2. [4eb546b2c208] [4.16.2] <4.16-maint> 2014-06-22 Phil Thompson * sipgen/gencode.c: Fixed a regression that introduced some "modern" C code. [449e2866018a] <4.16-maint> 2014-06-16 Phil Thompson * NEWS, sipgen/metasrc/parser.y, sphinx/directives.rst: Deprecated the %ConsolidatedModule directive as it won't be supported in SIP v5. [e4dc9d633742] <4.16-maint> 2014-06-15 Phil Thompson * sipgen/gencode.c: Fixed a bug with /Out/ class pointer arguments in virtual methods. [8abafd34bfab] <4.16-maint> * sipgen/gencode.c: Work around what looks like a Python2 bug in the handling of composite modules. [f113aea18630] <4.16-maint> 2014-06-09 Phil Thompson * .hgtags: Added tag 4.16.1 for changeset efd5e09a4024 [787e2ce426f7] <4.16-maint> * NEWS: Released as v4.16.1. [efd5e09a4024] [4.16.1] <4.16-maint> 2014-06-03 Phil Thompson * configure.py.in: Fixes for Python v2.6. [3974dcb54776] <4.16-maint> 2014-06-01 Phil Thompson * sipgen/gencode.c: Fixed a regression in the creating of the build file when generating individual source files. [d9229cce7220] <4.16-maint> 2014-05-26 Phil Thompson * .hgtags: Added tag 4.16 for changeset d3a907d2acd1 [2a310fa9719a] * NEWS: Released as v4.16. [d3a907d2acd1] [4.16] 2014-05-25 Phil Thompson * siplib/descriptors.c: Fixed a regression introduced when getting rid of warning messages. [9472e2f08313] 2014-05-23 Phil Thompson * configure.py.in: Fixed a regression in the handling of the --platform configure.py option. [1cc4bd967882] 2014-05-18 Phil Thompson * siplib/siplib.c.in: Eliminated a couple of (benign) warning messages. [f6acb8ed7b65] 2014-05-16 Phil Thompson * NEWS: Updated the NEWS file. [d3c64f5117e0] * sipgen/main.c, sipgen/metasrc/parser.y, sipgen/sip.h.in, sphinx/command_line.rst, sphinx/directives.rst, sphinx/incompatibilities.rst: Changed the handling of timelines so that the latest version is enabled if no known version is explicitly enabled. Added the -B option to sip to allow timeline backstops to be defined. [8a3fb94329aa] 2014-05-15 Phil Thompson * configure.py.in: Fixed a bug in the handling of configuration files. [61da788f455f] 2014-05-14 Phil Thompson * sipgen/gencode.c: Don't generate an interface file if it will be empty. [3f7d0afde4ce] * siplib/siplib.c.in: Ignore overflows when converting Python ints to C/C++. [8065fb1cb418] 2014-05-13 Phil Thompson * NEWS, sipgen/gencode.c, sipgen/metasrc/parser.y, sipgen/sip.h.in, sphinx/annotations.rst: Added the /NoSetter/ variable annotation. [422cc3b4ee5b] * sipgen/gencode.c: Fixed a code generation bug for variables with multi-const types. [dd6840986c03] 2014-05-12 Phil Thompson * siplib/array.c, siplib/descriptors.c, siplib/siplib.c.in, siplib/voidptr.c: Fixed building against Python v2.5 and earlier. [be46b0f3b785] * NEWS, configure.py.in, sphinx/installation.rst: Added the --no-tools option to configure.py. [fcc0fc5d24c4] 2014-05-11 Phil Thompson * sphinx/installation.rst: Some documentation fixes. [210151d0ba6a] * build.py, configurations/rpi_py3.cfg, sphinx/installation.rst: Removed the configurations directory. [4b482124587b] * siplib/apiversions.c, siplib/array.c, siplib/descriptors.c, siplib/siplib.c.in, siplib/voidptr.c: Eliminated most warning messages. Fixed a memory leak in the handling of sip.array. [63626dea7508] * configure.py.in, sphinx/installation.rst: Removed the unneeded support for continuation lines in configuration files. [95f40f9a8967] * NEWS, build.py, configurations/rpi_py3.cfg, configure.py.in, siputils.py, sphinx/installation.rst: Removed the --static-root option. Added the --configuration, --sysroot and --target-py-version options. Added the Raspberry Pi configuration file. [e57308c0ef92] 2014-05-05 Phil Thompson * NEWS, build.py, configure.py.in, sphinx/installation.rst: Added the --use-qmake option to configure.py so that it can be cross-compiled. [163331dc90b0] 2014-05-04 Phil Thompson * build.py, custom/custom.c, custom/customw.c, custom/mkcustom.py, sphinx/build_system.rst, sphinx/builtin.rst, sphinx/index.rst: Removed the (way out of date and superceded by pyqtdeploy) custom directory. [4e4a1cbe2f7e] * NEWS, configure.py.in, sphinx/installation.rst: Added the --static-root option to configure.py. [c90befbc77d2] 2014-04-26 Phil Thompson * siputils.py: Handle in-line comments in spec files. [044852da62d4] 2014-04-24 Phil Thompson * siplib/voidptr.c: Fixed the previous fix. (This is C not C++.) [a67e996e00d3] 2014-04-23 Phil Thompson * NEWS, siplib/voidptr.c: Implemented nb_bool for sip.voidptr. [7ca5aa6bde10] 2014-04-21 Phil Thompson * NEWS, siplib/qtlib.c, siplib/sipint.h: Reversed the sense of the argument to check for signal receivers. [e14829596147] * NEWS, sipgen/gencode.c, siplib/qtlib.c, siplib/sip.h.in.in, siplib/sipint.h, siplib/siplib.c.in: Added sipInvokeSlotEx() as support for the upcoming 'check_receiver' flag in PyQt's connect(). [d7ef32db3967] 2014-04-20 Phil Thompson * sipgen/lexer.l, sipgen/parser.y: Merged the v4.15 maintenance branch into the trunk. [8e55c9f2ba87] 2014-04-15 Phil Thompson * sphinx/conf.py.in: Fixed the missing logo thumbnail. [f53a9094e52e] <4.15-maint> 2014-04-08 Phil Thompson * siplib/siplib.c.in, sphinx/build_system.rst, sphinx/using.rst: Updated the docs so that pyqtconfig is only mentioned in the context of PyQt4. Fixed some typos. [efa359fde2a4] <4.15-maint> 2014-03-25 Phil Thompson * sipgen/gencode.c: Fixed the generation of Qt signal signatures so that they are correct for Qt5. [3f9633204687] <4.15-maint> 2014-03-21 Phil Thompson * sipgen/metasrc/parser.y, sipgen/sip.h.in: Fixed the handling of platforms and features that are disabled by other platforms or features. [0c1b13e45887] <4.15-maint> 2014-03-20 Phil Thompson * sipgen/gencode.c: Fixed the handling of enums for C++11. [85e544458789] <4.15-maint> 2014-03-14 Phil Thompson * .hgtags: Added tag 4.15.5 for changeset 13906834d910 [411bbc879ae6] <4.15-maint> * NEWS: Released as v4.15.5. [13906834d910] [4.15.5] <4.15-maint> 2014-03-13 Phil Thompson * siplib/siplib.c.in: Make sure an object doesn't already have a parent when adding it in __init__() (ie. avoid an infinite loop if __init__() is called twice for an object). [05c32deeaeed] <4.15-maint> 2014-03-05 Phil Thompson * NEWS: Updated the NEWS file. [8d7c37ddc55d] <4.15-maint> 2014-02-22 Phil Thompson * sipgen/gencode.c, siplib/sip.h.in.in: Added the PyQt signal hack #3. All versions of signals with optional arguments are now generated for PyQt4 when built against Qt5. [22c03a345d4e] <4.15-maint> 2014-02-21 Phil Thompson * siputils.py: Fixed the creation of wrapper scripts for Python v3.4 on OS/X. [93e30c84cbf9] <4.15-maint> 2014-02-20 Phil Thompson * sipgen/gencode.c, sipgen/metasrc/parser.y, sipgen/sip.h.in, siplib/sip.h.in.in: Support for the PyQt4 signal hacks when building against Qt5. [8bff7edb3c80] <4.15-maint> 2014-02-18 Phil Thompson * sipgen/gencode.c, siplib/sip.h.in.in: Implemented the PyQt5 signal emitters. [4fc63f9adb44] <4.15-maint> * sipgen/gencode.c, sipgen/metasrc/parser.y, sipgen/sip.h.in, siplib/sip.h.in.in, siplib/siplib.c.in: Bumped the internal API to v11.0. The PyQt4 and PyQt5 specific data structures are now completely separate in preparation for the signal changes needed by PyQt5. Renamed the PyQt4Flags and PyQt4NoQMetaObject annotations so that they are not PyQt4 specific. [b96a5e69adb6] <4.15-maint> 2014-02-09 Phil Thompson * sipgen/gencode.c: Fixed a name clash for a type in a module that has the same name as the module when building against Python v2. [d45411f2a001] <4.15-maint> 2014-02-06 Phil Thompson * siputils.py: Relax a test in the build system for PyQt v4.10.3 and earlier so that we don't have to synch releases. [e6e10c9f08b5] <4.15-maint> 2014-02-05 Phil Thompson * siplib/siplib.c.in: sip.wrapinstance() will now handle addresses >32 bits on Windows64. [5a95f257ccca] <4.15-maint> 2014-02-04 Phil Thompson * sipgen/gencode.c, sphinx/annotations.rst: Fixed the /KeepReference/ function annotation when applied to static functions. [2737c3074f4d] <4.15-maint> * siputils.py: Removed the requirement that Python must be built as a framework on OS/X. [fb6dbd80297b] <4.15-maint> 2014-01-22 Phil Thompson * sipgen/gencode.c, sipgen/metasrc/parser.y, sipgen/sip.h.in: Removed the unnecessary (and broken) support for __unicode__(). [0b19f77489ce] <4.15-maint> 2014-01-17 Phil Thompson * NEWS, siputils.py, sphinx/build_system.rst: The use_arch argument of sipconfig.create_wrapper() will now accept a space separated set of architectures. [6fe353128007] <4.15-maint> 2014-01-10 Phil Thompson * configure.py.in: Fixed a bug building on OSX when passing a value of LIBDIR to configure.py on the command line. [577bff05ca6d] <4.15-maint> 2014-01-07 Phil Thompson * .hgtags: Added tag 4.15.4 for changeset 4d629a0d7510 [79a5b5e82ca3] <4.15-maint> * NEWS: Released as v4.15.4. [4d629a0d7510] [4.15.4] <4.15-maint> 2014-01-02 Phil Thompson * LICENSE, Roadmap.rst, build.py, configure.py.in, sipgen/export.c, sipgen/extracts.c, sipgen/gencode.c, sipgen/heap.c, sipgen/main.c, sipgen/metasrc/lexer.l, sipgen/metasrc/parser.y, sipgen/sip.h.in, sipgen/sipgen.sbf, sipgen/transform.c, siplib/apiversions.c, siplib/array.c, siplib/array.h, siplib/bool.cpp, siplib/descriptors.c, siplib/objmap.c, siplib/qtlib.c, siplib/sip.h.in.in, siplib/sipint.h, siplib/siplib.c.in, siplib/siplib.sbf.in, siplib/threads.c, siplib/voidptr.c, siputils.py, sphinx/conf.py.in, sphinx/directives.rst: Updated the copyright notices. [b4a30e5b9970] <4.15-maint> 2013-12-29 Phil Thompson * siplib/siplib.c.in: Allow the pointers used to store the parsed results from Python reimplementations to be NULL. [7b83d16f7d28] <4.15-maint> * build.py, sipgen/lexer.l, sipgen/metasrc/README, sipgen/metasrc/lexer.l, sipgen/metasrc/parser.y, sipgen/parser.y: Moved the lexer and parser meta-source files to a separate directory to avoid problems with make accidentaly regenerating them. [c8d48c22ebf7] <4.15-maint> * build.py: Remove the __pycache__ directory when cleaning. [a0682feb1e94] <4.15-maint> 2013-12-17 Phil Thompson * NEWS, siplib/array.c, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/c_api.rst: Added SIP_SSIZE_T_FORMAT to the C API. [e74243fcc265] <4.15-maint> 2013-12-16 Phil Thompson * sipgen/gencode.c, sipgen/parser.y: Fixed the parsing of C++ types involving multiple const and pointers. [7a74623b6967] <4.15-maint> 2013-10-21 Phil Thompson * siplib/array.c, siplib/objmap.c, siplib/sipint.h, siplib/siplib.c.in, siplib/voidptr.c: Fixed all the compiler warning messages when building the sip module. [5e5fdf4cc35c] <4.15-maint> 2013-10-16 Phil Thompson * .hgtags: Added tag 4.15.3 for changeset a751e48db99a [dffbff1c0664] <4.15-maint> * NEWS: Released as v4.15.3. [a751e48db99a] [4.15.3] <4.15-maint> 2013-10-13 Phil Thompson * sipgen/transform.c: Fixed virtual re-implementations so that the number of generated Python methods slots is correct and that re-implementations explicitly marked as virtual are handled correctly. [aa7806ed2405] <4.15-maint> 2013-10-03 Phil Thompson * siplib/siplib.c.in: Fixed the format of an exception with Python v2. [5dc8c370157e] <4.15-maint> 2013-09-14 Phil Thompson * .hgtags: Added tag 4.15.2 for changeset f8fdf4d1eb87 [82b599f547b1] <4.15-maint> * NEWS: Released as v4.15.2. [f8fdf4d1eb87] [4.15.2] <4.15-maint> 2013-09-08 Phil Thompson * siplib/array.c, siplib/array.h, siplib/sip.h.in.in, sphinx/c_api.rst: sipConvertToArray() will now optionally take ownership of the array memory. Changed the signatures of sipConvertToArray() and sipConvertToTypedArray(), but in a source and binary compatible way. [908d49322dcf] <4.15-maint> * siplib/array.c, sphinx/c_api.rst: Added support for char, unsigned char, short, int, float and double as array types. [fc41755d6481] <4.15-maint> 2013-08-24 Phil Thompson * sipgen/transform.c: Further fixes for the handling of virtual methods. [14732b487dda] <4.15-maint> 2013-08-23 Phil Thompson * .hgtags: Added tag 4.15.1 for changeset 148b813a559c [5ef6f2e04687] <4.15-maint> * NEWS: Released as v4.15.1. [148b813a559c] [4.15.1] <4.15-maint> * sipgen/transform.c: Fixed a regression in the handling of hidden virtuals. [15657c502e42] <4.15-maint> 2013-08-21 Phil Thompson * .hgtags: Added tag 4.15 for changeset 2f84fb045098 [1f9737376184] * NEWS: Released as v4.15. [2f84fb045098] [4.15] 2013-08-18 Phil Thompson * sphinx/annotations.rst: Fixed a mistake in the documentation for /Factory/. [4c2fe2e7397e] * siplib/siplib.c.in: Fixed a C++ism that crept into the sip module code. [764f7fc80f1f] 2013-08-17 Phil Thompson * NEWS: Updated the NEWS file. [69897cf50dea] 2013-08-13 Phil Thompson * sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/c_api.rst: Added sipRegisterProxyResolver() to the public API. [66235bf9625f] 2013-08-07 Phil Thompson * sphinx/c_api.rst: Documented sipConvertToArray() and sipConvertToTypedArray(). [bf49a3ad5612] 2013-08-05 Phil Thompson * siplib/array.c, siplib/sipint.h, siplib/siplib.c.in: Fixed the array support. [e2d05fb54872] * sipgen/gencode.c, siplib/array.c, siplib/array.h, siplib/sip.h.in.in, siplib/siplib.c.in: Added sipConvertToArray(). [660fdd5cb10e] * sipgen/gencode.c: Eliminated unused arguments in the setters of constant variables. [e43b7d64c488] 2013-08-04 Phil Thompson * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h.in, sphinx/annotations.rst: Added the /NoScope/ enum annotation. [aa4646c186d2] * siplib/array.c, siplib/array.h, siplib/siplib.c.in: Properly initialise the sip.array type. [a7e4f6c62b8f] * siplib/array.c, siplib/array.h, siplib/sip.h.in.in, siplib/sipint.h, siplib/siplib.c.in: Completed the array implementation for wrapped types. [9e5b63022e19] 2013-08-03 Phil Thompson * sipgen/gencode.c, siplib/array.c, siplib/array.h, siplib/sip.h.in.in, siplib/siplib.c.in, siplib/siplib.sbf.in: Added the stub of the array support. [ffb87d2e0fc5] 2013-07-31 Phil Thompson * sphinx/c_api.rst: Documented sipConvertFromNewPyType(). [ba59d434b206] * siplib/sip.h.in.in, siplib/siplib.c.in: Changed the signature of sipConvertFromNewPyType() to handle ownership and hide the internals of generated derived classes. [5a9ba502593c] * sipgen/gencode.c: Fixed the PyQt5 generation of qt_metaobject() so that it supports QML. [2f18c4617542] 2013-07-30 Phil Thompson * sipgen/gencode.c, siplib/sip.h.in.in, siplib/sipint.h, siplib/siplib.c.in, siplib/threads.c: Added the (as yet undocumented) sipConvertFromNewPyType(). [5a65f5bad461] * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h.in, sphinx/annotations.rst: Added the /ExportDerived/ class annotation. [e3c78dfd30b8] 2013-07-26 Phil Thompson * siplib/siplib.c.in: Clear any exceptions before trying to parse a reimplementation result. [7bebd55f50b2] 2013-07-24 Phil Thompson * siplib/siplib.c.in: Fixed a mixin bug where C++ was using the mixin (rather than Python) wasn't being detected properly. [52d3b8035dca] 2013-07-23 Phil Thompson * siplib/siplib.c.in: Fixed a bug in the dereferencing of mixins. [fc3df3e99932] 2013-07-21 Phil Thompson * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h.in, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/c_api.rst: Implemented the PyQt5 plugin, including support for Qt interfaces. Added sipGetMixinAddress() to the public API. Python reimplementations of abstract mixins are now handled correctly. [972540270afa] 2013-07-19 Phil Thompson * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h.in, sipgen/transform.c: The parser now handles multiple consts in type declarations. [e7b6e4b5b1de] * sipgen/gencode.c: Properly implement /TransferBack/ even for return values that appear to be always new because the type may be a mapped collection type with elements that might not be new (e. QList). [9c073a101fb6] 2013-07-14 Phil Thompson * sipgen/lexer.l: Make sure that source locations are always valid (if not always absolutely correct). [e5a66c9174a6] 2013-07-13 Phil Thompson * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h.in: The parser can now handle expressions with casts. [54ec565cf24e] * sipgen/lexer.l: Added support for numbers having trailing lLuU. [88cc29113b02] 2013-07-11 Phil Thompson * sipgen/transform.c: Backed out changeset bd5b9927361b The problem is real (but currently not triggered), but the fix breaks PyQt. [3529b7c08228] 2013-07-10 Phil Thompson * sipgen/transform.c: Fixed a bug where a method with %VirtualCatcherCode was being used by a method without if they had the same signature. [bd5b9927361b] * configure.py.in: Invalidate the import caches before trying to import the newly created sipconfig.py. [1e3ae0d5e790] * sipgen/gencode.c: Fixed the mixin support when the generated class definition may be a sub-type. [aec935209f0d] 2013-07-07 Phil Thompson * sipgen/gencode.c, sipgen/sip.h.in, sipgen/transform.c: A virtual catcher now calls the super-class implementation by via the super-class rather than needing to know exactly where the nearest implementation is. [58987948b9fd] * NEWS, sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h.in, siplib/descriptors.c, siplib/sip.h.in.in, siplib/sipint.h, siplib/siplib.c.in, sphinx/annotations.rst: Implemented the /Mixin/ class annotation. [8b1702ce3226] 2013-07-01 Phil Thompson * NEWS, sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h.in, siplib/siplib.c.in, sphinx/directives.rst: Added the call_super_init argument to the %Module directive. Updated the documentation. [42950b118753] * siplib/sip.h.in.in, siplib/siplib.c.in: Support for cooperative multi-inheritance must now be explicitly enabled because it affects compatibility. Added a shortcut so that the cooperative multi-inheritance support is skipped when it isn't needed. [07984388686f] 2013-06-30 Phil Thompson * NEWS, siplib/siplib.c.in: Fixed the %Finalisation support so that QObject sub-classes work. [17fc8e27b7e9] * sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in: Completed the support for cooperative multi-inheritance. [ddd13ea38870] * siplib/sip.h.in.in, siplib/siplib.c.in: Changed the API of td_final to minimise the creation of new dicts. Fixed the calling of the super-class's __init__. [195f0d1ab91c] 2013-06-29 Phil Thompson * siplib/siplib.c.in: Instead of calling super() to implement the cooperative multi- inheritance, just call the __init__ of the next type in the MRO. [da9edad8f7b1] * siplib/sip.h.in.in, siplib/siplib.c.in: Wrapped classes now support cooperative multi-inheritance with non- sip classes. Implemented %FinalisationCode. [aaedcb26099e] * sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h.in, siplib/sip.h.in.in: Added the code generator support for %FinalisationCode. [e8b4b1ab730d] 2013-06-28 Phil Thompson * Merged the v4.14 maintenance branch. [97beee973f94] 2013-06-21 Phil Thompson * siplib/voidptr.c: Fixed a reference count bug when a sip.voidptr is created from a buffer object. [02bdf6cc32c1] <4.14-maint> 2013-06-16 Phil Thompson * .hgtags: Added tag 4.14.7 for changeset ee771b441704 [6e6cc6c60a36] <4.14-maint> * NEWS: Released as v4.14.7. [ee771b441704] [4.14.7] <4.14-maint> 2013-06-12 Phil Thompson * NEWS, build.py, sip.nsi.in, sphinx/installation.rst: Removed the Windows installer as we can't have co-existant PyQt4 and PyQt5 installers for other reasons. [74e1df1d9940] <4.14-maint> 2013-06-11 Phil Thompson * NEWS, sip.nsi.in, sphinx/installation.rst: Debugged the installer. [00678082f72e] <4.14-maint> * build.py, sip.nsi.in: Added the initial (not debugged) installer. [d22b19884c62] <4.14-maint> * sphinx/directives.rst: Fixed a broken reference to the Python documentation. [38ed755c797d] <4.14-maint> 2013-06-10 Phil Thompson * siplib/siplib.c.in: Fixed the last fix. [67258ffe885a] <4.14-maint> 2013-06-08 Phil Thompson * NEWS, sipgen/parser.y, sipgen/sip.h.in, siplib/siplib.c.in, sphinx/annotations.rst: Added the /Sequence/ function annotation. Added a work around for the Python bug whereby nb_inplace_add is wrongly copied to sq_inplace_concat if either are missing. [029828cabb4d] <4.14-maint> * NEWS, sipgen/export.c, sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h.in, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/c_api.rst, sphinx/directives.rst, sphinx/python_api.rst: Added support for classes to have %ConvertFromTypeCode. Added sipEnableAutoconversion() to the C API. Added sip.enableautoconversion() to the Python API. [4dbbc8c6c054] <4.14-maint> 2013-06-07 Phil Thompson * NEWS, sipgen/gencode.c, siplib/qtlib.c, siplib/sip.h.in.in, siplib/sipint.h, siplib/siplib.c.in, siplib/threads.c: Bumped the internal API to 10.0. Removed deprecated parts of the private API. Added the stub for the optional convert from class code. [50319794231a] <4.14-maint> 2013-06-02 Phil Thompson * siplib/qtlib.c, siplib/siplib.c.in: Add more checks to make sure that PyQt5 isn't accidentally using features that will be deprecated in SIP5. [c80745f8ee0b] <4.14-maint> 2013-06-01 Phil Thompson * siplib/qtlib.c: Added assertions for Qt support for all API functions that provide Qt support. [aa60efc50608] <4.14-maint> 2013-05-04 Phil Thompson * siplib/voidptr.c: Fixed a bug in converting an int to a voidptr. [dd473964ac33] <4.14-maint> 2013-05-01 Phil Thompson * NEWS, sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/c_api.rst: Added sipSetDestroyOnExit() to the public C API. [40660935c75b] <4.14-maint> 2013-04-25 Phil Thompson * sipgen/gencode.c: Fixed a code generation bug that affected QObject sub-classes with dtor %MethodCode and with the GIL not released by default (ie. PyQt5). [bd9eccac4407] <4.14-maint> 2013-04-21 Phil Thompson * .hgtags: Added tag 4.14.6 for changeset 32dcb22f994c [23da2e18916b] <4.14-maint> * NEWS, Roadmap.rst: Released as v4.14.6. [32dcb22f994c] [4.14.6] <4.14-maint> 2013-04-17 Phil Thompson * sipgen/parser.y, sphinx/annotations.rst: Documented that sub-classing from classes with different implementations is not supported. [1773f2100851] <4.14-maint> * sipgen/parser.y: Fixed a grammar bug in the parsing of %Module with no parenthesis. [2d5256eda850] <4.14-maint> 2013-04-09 Phil Thompson * siplib/siplib.c.in: Fixed a bug in the parsing of SIP_ANYSLOT arguments. [a9f7473ba9c7] <4.14-maint> 2013-04-06 Phil Thompson * sipgen/gencode.c: Removed some redundant code generated for a component module. [395bf9f00aa6] <4.14-maint> 2013-03-26 Phil Thompson * .hgtags: Added tag 4.14.5 for changeset e528e634d4db [6a2bda53d2c0] <4.14-maint> * NEWS: Released as v4.14.5. [e528e634d4db] [4.14.5] <4.14-maint> 2013-03-20 Phil Thompson * sipgen/gencode.c: Fixed a code generation bug when using /Array, Transfer/. [054f1676c300] <4.14-maint> 2013-03-06 Phil Thompson * siputils.py: Fixed a build system bug for QtWebKit on Linux against Qt v5. [c65a525a0a17] <4.14-maint> 2013-03-01 Phil Thompson * .hgtags: Added tag 4.14.4 for changeset 4c818299f57a [72b69b39a7a8] <4.14-maint> * NEWS: Released as v4.14.4. [4c818299f57a] [4.14.4] <4.14-maint> 2013-02-26 Phil Thompson * configure.py.in, sphinx/installation.rst: The --sdk flag to configure.py will now default to the directory used by current versions of Xcode. [312a27229b3f] <4.14-maint> 2013-02-20 Phil Thompson * sipgen/gencode.c, siplib/sipint.h, siplib/siplib.c.in, siplib/threads.c: The thread support now only creates TLS when it is actually needed. This makes sipStartThread() redundant and it is now deprecated. Failing to allocate TLS will now raise an exception. [34f6f0d52c1e] <4.14-maint> * NEWS, sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/c_api.rst, sphinx/directives.rst, sphinx/incompatibilities.rst: VirtualErrorHandler code is now called with the GIL and from the thread that raised the exception. This ensures that the details of the exception can be obtained. It also means that the default handler (ie. PyErr_Print()) can also get the details. VirtualErrorHandler code is now also provided sipGILState so that it can call SIP_RELEASE_GIL() prior to changing the execution path. [45a50c6d82fe] <4.14-maint> 2013-02-14 Phil Thompson * sphinx/introduction.rst.in: Documentation updates regarding SIP v5. [03f33e7fdfb1] <4.14-maint> 2013-02-04 Phil Thompson * NEWS, sipgen/gencode.c: Fixed the generation of an unnecessary variable for array arguments. [fb45cf6e775b] <4.14-maint> 2013-02-03 Phil Thompson * siputils.py: The problem of the moc pathname is more widespread. [bf2062f2318f] <4.14-maint> * siputils.py: Fix the build of QtWebKit on Windows. Workaround the foward slash characters in the moc pathname on Windows/Qt5. [13ee5a9fc8bd] <4.14-maint> 2013-02-02 Phil Thompson * siputils.py: Fixed the QAxContainer dependencies for Qt5. [793be65e22b9] <4.14-maint> * siputils.py: Fixed the renaming of QAxContainer for Qt5. [7e67f0559595] <4.14-maint> * siputils.py: Fixed the QAxContainer dependency for Qt5. [d33f9eaa4394] <4.14-maint> * siputils.py: Build system changes for Qt5 on Windows. [9abd1d0f5d3f] <4.14-maint> 2013-01-28 Phil Thompson * .hgtags: Added tag 4.14.3 for changeset 6e004d396299 [c9a29107c8ef] <4.14-maint> * NEWS: Released as v4.14.3. [6e004d396299] [4.14.3] <4.14-maint> 2013-01-18 Phil Thompson * siplib/siplib.c.in: When a Python object is garbage collected SIP no longer creates an additional reference to any child Python objects so that those children can now be handled by the garbage collector if appropriate. We used to keep the extra reference to make sure any additional attributes set in the child were preserved, however if the parent is being deleted then the C++ object it wraps must have been (or is about to be) destroyed, and therefore (if the parent/child relationships between the Python objects are correct) the child Python object is about to be deleted anyway. Before we relied on the C++ child telling us when to garbage collect the Python child via its virtual dtor - but this won't work if it was the C++ library (rather than the Python application) that created the child. [dc06058c99dd] <4.14-maint> 2013-01-17 Phil Thompson * siplib/siplib.c.in: Backed out changeset 4ec79ea69263 Realised that the (slight) change in behaviour could break legitimate use cases. [597c864debcc] <4.14-maint> * siplib/siplib.c.in: When a Python object is garbage collected its child Python objects are now garbage collected unless they have an instance dict. [4ec79ea69263] <4.14-maint> 2013-01-11 Phil Thompson * LICENSE, build.py, configure.py.in, sipgen/export.c, sipgen/extracts.c, sipgen/gencode.c, sipgen/heap.c, sipgen/lexer.l, sipgen/main.c, sipgen/parser.y, sipgen/sip.h.in, sipgen/sipgen.sbf, sipgen/transform.c, siplib/apiversions.c, siplib/bool.cpp, siplib/descriptors.c, siplib/objmap.c, siplib/qtlib.c, siplib/sip.h.in.in, siplib/sipint.h, siplib/siplib.c.in, siplib/siplib.sbf.in, siplib/threads.c, siplib/voidptr.c, siputils.py, sphinx/conf.py.in, sphinx/directives.rst: Updated the copyright notices. [ee3b1348996c] <4.14-maint> 2013-01-03 Phil Thompson * NEWS, sipgen/gencode.c, sphinx/annotations.rst: The /KeepReference/ argument annotation, when applied to factories, will now keep the reference with the object created by the factory. [0ad6099f31fa] <4.14-maint> 2013-01-02 Phil Thompson * siplib/voidptr.c: Properly implemented the support for passing objects that implement the buffer protocol where a voidptr is expected. [171bd8e1e037] <4.14-maint> * siputils.py: Changed the test for a Python framework build so that it works with pyvenv. [a612391f667c] <4.14-maint> 2012-12-29 Phil Thompson * siputils.py: Further build system fixes for Linux/Qt5. [04dec290a15e] <4.14-maint> * siputils.py: Fix the build system for the Linux specific naming conventions of the Qt5 libraries. [05cb90880c2b] <4.14-maint> 2012-12-18 Phil Thompson * siputils.py: Fixed the build system for QtTest in Qt5. [55188026fe6d] <4.14-maint> 2012-12-08 Phil Thompson * .hgtags: Added tag 4.14.2 for changeset e9180a8d374f [ed864cf2277f] <4.14-maint> * NEWS: Released as v4.14.2. [e9180a8d374f] [4.14.2] <4.14-maint> 2012-12-07 Phil Thompson * siputils.py: Fixed the build system for Qt v5-rc1. [44586b952072] <4.14-maint> 2012-11-14 Phil Thompson * siputils.py: The build system now knows that QtWebKit is QtWebKitWidgets in Qt5. [b8261071d302] <4.14-maint> 2012-11-11 Phil Thompson * NEWS, siplib/siplib.c.in, sphinx/python_api.rst: Added sip.setdestroyonexit(). [b063e90b6c20] <4.14-maint> * siplib/voidptr.c: Backed out to keep the behaviour the same as memoryview. [e8f21b0950c8] <4.14-maint> * siplib/voidptr.c: Backed out to keep the behaviour the same as memoryview. [26717fbefb61] <4.14-maint> 2012-11-10 Phil Thompson * sipgen/gencode.c: Patch from Matt Newell to fix /HoldGIL/ when exceptions are enabled. [669ecadaaae1] <4.14-maint> 2012-11-04 Phil Thompson * siplib/voidptr.c: A simple index of a sip.voidptr now returns an int rather than a string/bytes of length 1. [80ee79901dc9] <4.14-maint> * siplib/voidptr.c: Fixed simple index item assignment for voidptr. [3cb217678514] <4.14-maint> * siplib/voidptr.c: The new buffer interface was backported to v2.6.3. [47f4f489055e] <4.14-maint> * NEWS, siplib/voidptr.c, sphinx/python_api.rst: sip.voidptr() will now accept any object that implements the (old or new) buffer protocols. [cb7799eb557b] <4.14-maint> * sphinx/python_api.rst: Clarified the docs for __getitem__ and __setitem__ for sip.voidptr. [32fb8513b196] <4.14-maint> 2012-10-27 Phil Thompson * .hgtags: Added tag 4.14.1 for changeset d0431cee7920 [6b278a98323b] <4.14-maint> * NEWS: Released as v4.14.1. [d0431cee7920] [4.14.1] <4.14-maint> 2012-10-26 Phil Thompson * siplib/siplib.c.in: More buffer support fixes. [1fe9c59f0f06] <4.14-maint> * siplib/siplib.c.in: Both the old and new buffer protocols are now checked. [7227f121bac9] <4.14-maint> 2012-10-23 Phil Thompson * NEWS, sipgen/export.c, sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h.in, sipgen/transform.c, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/annotations.rst, sphinx/c_api.rst, sphinx/specification_files.rst: Added support for types that implement the buffer protocol. [4ec285852cba] <4.14-maint> * siplib/siplib.c.in: None may be provided whenever a capsule is expected. [b90e3475bdfc] <4.14-maint> 2012-10-17 Phil Thompson * sipgen/gencode.c, siplib/sip.h.in.in: Renamed the sipCapsule_* macros to be consistent with other similar ones. [1913168e0c8d] <4.14-maint> * sipgen/export.c: The type name of a capsule is now used in docstrings. [1c8ce8a61324] <4.14-maint> * sphinx/directives.rst: Fixed a documentation typo. [94362407c872] <4.14-maint> 2012-10-16 Phil Thompson * sipgen/gencode.c: Eliminated a C compiler warning message from the generated code. [e60f63cfe0d1] <4.14-maint> * NEWS, sipgen/parser.y, sipgen/sip.h.in: The C prototype foo(void) is now accepted. [54aca3c0b75e] <4.14-maint> * sipgen/lexer.l, sipgen/transform.c: Fixed a bug in the saving of line numbers for error messages when the error is on the last significant line. [7c77e368814f] <4.14-maint> * NEWS, sipdistutils.py, sphinx/distutils.rst: If no sip-opts are defined sipdistutils.py will now use any swig_opts passed to the Extension ctor. [6fcc431a81bf] <4.14-maint> 2012-10-15 Phil Thompson * NEWS, sipgen/export.c, sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h.in, sipgen/transform.c, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/annotations.rst, sphinx/c_api.rst: Increased the API version number to 9.1. Added the /Capsule/ typedef annotation. Added the 'z' format character to sipBuildResult(). Added the 'z' format character to sipParseResult(). [f4bc254f96d8] <4.14-maint> 2012-10-12 Phil Thompson * sipgen/gencode.c: Fixed regressions in the handling of types when generating code for C modules. [3eba5b9842f0] <4.14-maint> 2012-10-09 Phil Thompson * siputils.py: Explicity close files in siputils.py to avoid resource warning messages. [fdc332e116b2] <4.14-maint> 2012-10-07 Phil Thompson * sipgen/gencode.c, siplib/sip.h.in.in: Backed out the changes to the signal table generation (and revert the API version to 9.0) because they are no longer needed. [38235401ffbc] <4.14-maint> 2012-10-03 Phil Thompson * sipgen/gencode.c, siplib/sip.h.in.in: Renamed PYQT4_SIGNAL_EXPLICIT to PYQT4_SIGNAL_FIXED_ARGS. Renamed PYQT4_SIGNAL_MASK to PYQT4_SIGNAL_ARGS_MASK. [cfbd55297dcd] <4.14-maint> * sipgen/gencode.c, siplib/sip.h.in.in: Added the flags member to the pyqt4QtSignal structure so that PyQT can distinguish between explicitly defined signals and those added to support optional arguments. [81617aa9e051] <4.14-maint> 2012-10-01 Phil Thompson * sipgen/export.c, sipgen/gencode.c, sipgen/sip.h.in: Revised the previous change to keep the brackets unless the signal has no arguments. (PyQt relies on the format for some of its exceptions.) [dd884ddcb239] <4.14-maint> * sipgen/export.c, sipgen/gencode.c, sipgen/sip.h.in: Changed the docstrings for signals to use parenthesis rather than brackets as it is less confusing. [3f6128385aa2] <4.14-maint> 2012-09-29 Phil Thompson * .hgtags: Added tag 4.14 for changeset 90ea220ecc4b [76a18a32f759] * NEWS: Released as v4.14. [90ea220ecc4b] [4.14] 2012-09-28 Phil Thompson * NEWS: Updated the NEWS file. [214dd6433474] 2012-09-27 Phil Thompson * sphinx/directives.rst, sphinx/embedding.rst, sphinx/incompatibilities.rst, sphinx/python_api.rst, sphinx/using.rst: Got rid of all Sphinx warning messages. [cbf911605931] 2012-09-25 Phil Thompson * configure.py.in, specs/win32-msvc2008, specs/win32-msvc2010: Updated the win32-msvc2008 spec file. Taught the build system about MSVC 2010. [5d3c5164342a] 2012-09-24 Phil Thompson * configure.py.in, siputils.py: Taught the build system about Qt5's CXXFLAGS_APP macro. [4e2fddd95c07] * sphinx/annotations.rst: Another correction to the /Factory/ documentation. [f030580a19f6] 2012-09-21 Phil Thompson * sphinx/annotations.rst: Fixed the incorrect /Factory/ documentation. [3b76a41a1f4a] 2012-09-20 Phil Thompson * sipgen/gencode.c: Fixed the signature for generated virtual error handler functions. [caa74f25dff8] 2012-09-19 Phil Thompson * sipgen/parser.y: Fixed an initialisation bug in the parser by making it resiliant to future changes. [fd2e76ea8e16] 2012-09-18 Phil Thompson * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h.in: Fixed a few compiler warning messages. [a8aaecad7327] 2012-09-17 Phil Thompson * NEWS, sipgen/gencode.c, sipgen/main.c, sipgen/parser.y, sipgen/sip.h.in, sphinx/directives.rst: Added support for the SIP_PLATFORM_* and SIP_TIMELINE_* preprocessor symbols. [664ec65acb33] 2012-09-14 Phil Thompson * siputils.py: A build system fix for Qt v5-beta1. [6d704a7ab6c5] * siplib/sip.h.in.in: Removed the ANY SIP v3 compatibility macro as it causes problems with Qt v5. [40aeb5a8f98e] 2012-09-13 Phil Thompson * sipgen/parser.y, sipgen/transform.c: The AllowNone and NoRelease mapped type annotations can now be applied to mapped type templates. [3da91337f333] * sphinx/annotations.rst: Documented the PyName mapped type annotation. [b1a5b8cab2ab] * sipgen/lexer.l: Improved the parsing of floating point literals thanks to Andrea Griffini. [be35aa0bb4b5] 2012-09-01 Phil Thompson * sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/c_api.rst, sphinx/directives.rst: Added sipCallErrorHandler() to the private API. A virtual error handler is now called with the GIL released. The sipGILState variable is no longer passed to an error handler. [be42df79035d] 2012-08-31 Phil Thompson * NEWS, sphinx/annotations.rst, sphinx/directives.rst: Updated the docs regarding the latest virtual error changes. [86a4f33db172] * sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h.in, siplib/sip.h.in.in, siplib/siplib.c.in: Changed the virtual error handler support yet again so that error handlers are automatically exported to sub-classes and sub-modules. [118500886fa7] 2012-08-30 Phil Thompson * sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in: Completed the refactoring of virtual handlers to use sipParseResultEx(). [397b4ade7900] * sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in: Added sipParseResultEx() to the private API as a stub for future changes. [659fcb20bbc9] * specs/macx-xcode: Merged the 4.13 branch into the trunk. [96ef5f43f010] * NEWS, sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h.in, sipgen/transform.c, siplib/sip.h.in.in, sphinx/annotations.rst, sphinx/c_api.rst, sphinx/directives.rst: Replaced the virtual error support (again) with the %DefaultVirtualErrorHandler directive, the /NoVirtualErrorHandler/ and /VirtualErrorHandler/ function annotations, and the /VirtualErrorHandler/ class annotation. Added sip_gilstate_t and SIP_RELEASE_GIL() to the public API. The Sphinx docs now use C domains where appropriate. [71c0d64913bc] <4.13-maint> 2012-08-28 Phil Thompson * NEWS, sipgen/gencode.c, siplib/descriptors.c, siplib/sip.h.in.in, siplib/siplib.c.in: Bumped the API version number to 9.0. Removed the support for pre-9.0 variable structures. Changed the sipVariableGetterFunc signature to pass the Python object. [d8824768aa51] <4.13-maint> * sphinx/c_api.rst: Updated the documentation for sipConvertToType(). [32c2c73f4c27] <4.13-maint> 2012-08-27 Phil Thompson * NEWS, sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h.in, sipgen/transform.c, siplib/sip.h.in.in, sphinx/annotations.rst, sphinx/directives.rst: Changed the support for flagging errors in Python reimplementations of virtuals by adding the %VirtualErrorCode directive and removing SIPPyException. Also replaced the all_throw_cpp_exception %Module argument with all_use_VirtualErrorCode, and the /NoThrowsCppException/ and /ThrowsCppException/ function annotations with /NoUsesVirtualErrorCode/ and /UsesVirtualErrorCode/. [523c3bccb41b] <4.13-maint> 2012-08-26 Phil Thompson * sipgen/gencode.c, siplib/sip.h.in.in: Fixed the support for virtual handler exceptions so that memory isn't leaked and the GIL is released. [f644e914b292] <4.13-maint> * sipgen/transform.c: A simply tidy up after the previous change. [b3cd21a00d51] <4.13-maint> * sipgen/transform.c: Backed out changeset 1066 and did it properly. [368eaa1143bd] <4.13-maint> 2012-08-25 Phil Thompson * NEWS, sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h.in, sipgen/transform.c, siplib/sip.h.in.in, sphinx/annotations.rst, sphinx/directives.rst: Added the all_throw_cpp_exception argument to the %Module directive. Added the /ThrowCppException/ and /NoThrowCppException/ function annotations. [5f97352e818f] <4.13-maint> 2012-08-24 Phil Thompson * sipgen/transform.c: No longer require that the types of the arguments of a C/C++ signature are fully defined to SIP. [01e11dc52626] <4.13-maint> 2012-08-15 Phil Thompson * NEWS, siplib/siplib.c.in, sphinx/c_api.rst: sipTransferTo() now increments the reference count of an object if the owner is Py_None. Fixed a type checking bug in sip.transferto(). Deprecated sipTransferBreak(). [f59d135ae51c] <4.13-maint> 2012-08-10 Phil Thompson * sipgen/gencode.c: For Python v2.x unsigned short and unsigned byte are now converted to int rather than long objects (to be consistent with the signed versions). [897e085bdd97] <4.13-maint> * siplib/siplib.c.in: Make sure an exception is raised when converting to a character when a string longer than one character is passed. [28ea90cba3a9] <4.13-maint> 2012-07-22 Phil Thompson * sipdistutils.py: Applied a patch from Oliver Nagy to fix sipdistutils.py for Python v3. [5775580258b3] <4.13-maint> 2012-07-09 Phil Thompson * siplib/siplib.c.in: Fixed the use of a Python3 specific format character. [801ae4c35450] <4.13-maint> 2012-07-03 Phil Thompson * sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h.in, sphinx/annotations.rst, sphinx/directives.rst, sphinx/specification_files.rst: Implemented the %InstanceCode directive. [9b330b545c65] <4.13-maint> 2012-07-02 Phil Thompson * sipgen/gencode.c: Reformatted some comments. [fa8592b30bf5] <4.13-maint> * configure.py.in, sipgen/export.c, sipgen/extracts.c, sipgen/gencode.c, sipgen/heap.c, sipgen/lexer.l, sipgen/main.c, sipgen/sip.h.in, sipgen/sipgen.sbf, sipgen/transform.c, siplib/apiversions.c, siplib/bool.cpp, siplib/descriptors.c, siplib/objmap.c, siplib/qtlib.c, siplib/sipint.h, siplib/siplib.sbf.in, siplib/threads.c, siplib/voidptr.c, sphinx/conf.py.in, sphinx/directives.rst: Updated the dates on various copyright notices. [257d223f5d45] <4.13-maint> 2012-06-29 Phil Thompson * sphinx/c_api.rst: Fixed a documentation typo. [e1a825c52e33] <4.13-maint> 2012-06-20 Phil Thompson * .hgtags: Added tag 4.13.3 for changeset 589228145d51 [1cbf533ebe71] <4.13-maint> * NEWS: Released as v4.13.3. [589228145d51] [4.13.3] <4.13-maint> 2012-06-05 Phil Thompson * NEWS, siplib/siplib.c.in: Another fix for the handling of keyword arguments when used with unbound methods. [377e9e4763f5] <4.13-maint> 2012-06-04 Phil Thompson * siplib/siplib.c.in: Fixed the handling of keyword arguments when used with unbound methods. [cdd78f0c72b2] <4.13-maint> 2012-06-01 Phil Thompson * sipgen/gencode.c: Apply a cast to the argument to sipConvertFrom[Const]VoidPtr[AndSize]() when it was defined with a typedef. This makes it easier to use typedef as a way of hiding the complexities of a type that SIP doesn't handle. [c814c38523ff] <4.13-maint> 2012-05-25 Phil Thompson * NEWS, sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h.in, siplib/siplib.c.in, sphinx/annotations.rst, sphinx/directives.rst: The /NoRaisesPyExceptions/ and /RaisesPyExceptions/ function annotations can no be used with constructors. Updated the NEWS file. [482aa7e3f1ab] <4.13-maint> 2012-04-29 Phil Thompson * specs/macx-xcode: Removed the macx-xcode file at it isn't supported by the build system. [31ad477ff5ae] <4.13-maint> 2012-04-26 Phil Thompson * sipgen/parser.y: Removed the free() of a code block filename now that filenames are retained for error messages. [16ef20290565] <4.13-maint> * sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h.in, sipgen/transform.c: Error messages related to callables should now include the filename and line number of the callable in the .sip source file. [fa6c71904d78] <4.13-maint> 2012-04-18 Phil Thompson * sipgen/gencode.c: Fixed the support for keeping an extra reference to a containing class when refering to a member variable. [fbb9cdbad791] <4.13-maint> 2012-04-16 Phil Thompson * siplib/siplib.c.in: Eliminate a race condition in sip_api_is_py_method(). [871a7b44c8f0] <4.13-maint> 2012-04-14 Phil Thompson * siplib/sip.h.in.in, siplib/siplib.c.in: Improved the text of the exception raised when a wrapped C/C++ object doesn't exist. [dd2d72cac87f] <4.13-maint> 2012-04-09 Phil Thompson * siputils.py: Taught the build system about Qt5's QtGui module. [8d2739f3225f] <4.13-maint> 2012-04-02 Phil Thompson * sipgen/parser.y: Allow a string as well as an identifier for arguments to various name= settings so that name="name" can be used. [d5e6a1fa39f2] <4.13-maint> 2012-03-09 Phil Thompson * siplib/siplib.c.in: Updated the Unicode support for Python v3.3. [0870e512d8dd] <4.13-maint> 2012-03-04 Phil Thompson * sipgen/gencode.c, sipgen/parser.y, siplib/sip.h.in.in: Ensure a reference is kept to the containing object when getting an instance variable that is a non-const wrapped object. This should (safely) avoid a certain kind of application bug. [0dd3cb4eff0e] <4.13-maint> * siplib/qtlib.c: Effectively backed out change 769 because it causes inconsistent behaviour when a method is connected to its object's destroyed() method. [ca0fb2b4bd89] <4.13-maint> 2012-02-19 Phil Thompson * siplib/siplib.c.in: If a Python reimplementation is a descriptor then use the descriptor protocol to bind it (specifically added for Nuitka). [88844f85f705] <4.13-maint> 2012-02-10 Phil Thompson * .hgtags: Added tag 4.13.2 for changeset 4efeefee717e [389a142d1997] <4.13-maint> * NEWS: Updated the NEWS file. Released as v4.13.2. [4efeefee717e] [4.13.2] <4.13-maint> 2012-02-05 Phil Thompson * sipgen/parser.y: Fixed bad pointer bugs in the parsing of exceptions. [1058b2c18309] <4.13-maint> 2012-01-30 Phil Thompson * siplib/objmap.c: Handle aliases properly when discovering that an object has been deleted. [f51e159f6dff] <4.13-maint> 2011-12-22 Phil Thompson * .hgtags: Added tag 4.13.1 for changeset a782debccd42 [8a56d87be977] <4.13-maint> * NEWS: Released as v4.13.1. [a782debccd42] [4.13.1] <4.13-maint> 2011-12-20 Phil Thompson * sipgen/gencode.c: Fixed a bug in the generation of PyQt signal signatures that caused a "const" to be wrongly dropped. [39cf1d1d8167] <4.13-maint> 2011-12-19 Phil Thompson * siplib/siplib.c.in: Properly handle %PickleCode returning NULL. [29ec1c523114] <4.13-maint> 2011-12-17 Phil Thompson * NEWS, Roadmap.rst, sipgen/main.c: Deprecation warnings can no longer be suppressed. Updated the NEWS file. Updated the Roadmap. [358be4ede9fc] <4.13-maint> 2011-12-07 Phil Thompson * siplib/objmap.c: Completed the support for object aliases when garbage collecting an object. [7ab562ae0e39] <4.13-maint> * siplib/objmap.c, siplib/sip.h.in.in, siplib/sipint.h, siplib/siplib.c.in: When an object that uses multiple inheritance in its class hierachy is wrapped, all of its addresses when cast to the different super- classes are internally registered as aliases. This means that the original object will be found when given an address that is different as a result of a cast. (Note that the support for removing aliases when the object is garbage collected is not yet done.) [da88157d2f03] <4.13-maint> 2011-12-05 Phil Thompson * sipgen/gencode.c, sipgen/sip.h.in, sipgen/transform.c: Backed out 1013. It breaks when the method is overloaded in a super- class but only one overload is reimplemented in this class so the compiler doesn't see the other overload in the super-class so we must refer to it explicitly. [82af71f0adcb] <4.13-maint> * sipgen/gencode.c: Backed out 1014. [e50d347a15db] <4.13-maint> 2011-11-30 Phil Thompson * sipgen/parser.y: Fixed the generation of handlers for virtuals defined in templates. [98421b9cc511] <4.13-maint> * siputils.py: The build system now handles recursively defined macros. [5d7476cbb504] <4.13-maint> 2011-11-28 Phil Thompson * sipgen/gencode.c: sipSelf is now generated with the correct const qualifier. [3c46012c8562] <4.13-maint> * NEWS, sipgen/parser.y, sphinx/specification_files.rst: Protected and private super-classes can now be specified but are otherwise ignored. [f331e22716d9] <4.13-maint> * custom/mkcustom.py: Support for sys.platform being 'linux3'. [01a339a7f2e9] <4.13-maint> 2011-11-27 Phil Thompson * NEWS, sipgen/parser.y, sphinx/annotations.rst: Added the /PyName/ typedef annotation. [8c147224120a] <4.13-maint> 2011-11-23 Phil Thompson * siputils.py: Fixed the build system for building a debug version of PyQt on OS/X. [3b44dc2f0efd] <4.13-maint> * NEWS, sipgen/parser.y, sipgen/sip.h.in, sipgen/transform.c: Class templates now allow template arguments to be used as a super- class. [08e44ad74137] <4.13-maint> 2011-11-22 Phil Thompson * NEWS, sipgen/parser.y: Added support for 'public' preceding the name of a class in a super- class list. [7fbb8a754a81] <4.13-maint> * sipgen/parser.y, sphinx/annotations.rst, sphinx/directives.rst, sphinx/specification_files.rst, sphinx/using.rst: Updated the docs where the examples refered to deprecated syntax. [36208e0a6773] <4.13-maint> * NEWS, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h.in, sphinx/annotations.rst, sphinx/directives.rst: Added the all_raise_py_exception argument to the %Module directive. Added the /NoRaisesPyException/ function annotation. [bf725fdfd029] <4.13-maint> * sipgen/gencode.c: Fixed the previous change for classes contained in namespaces. [09411053ef1b] <4.13-maint> * sipgen/gencode.c, sipgen/sip.h.in, sipgen/transform.c: Virtual catchers will now call the most recent C++ implementation (if there is no Python reimplementation) even if it is unknown to SIP rather than the most recent implementation that SIP knows about. [8893e36b8ca3] <4.13-maint> 2011-11-21 Phil Thompson * sipgen/gencode.c: Updated some code generator comments. [fad4bdca5bbd] <4.13-maint> 2011-11-16 Phil Thompson * siputils.py: Make sure PyQt's internal static support libraries don't get added to rpath. [91848382e6fd] <4.13-maint> 2011-11-15 Phil Thompson * sipgen/parser.y: Added support for void template arguments. [1c699c672ed7] <4.13-maint> 2011-10-24 Phil Thompson * .hgtags: Added tag 4.13 for changeset 0869eb93c773 [3b2a3fb3fdda] * NEWS: Released as v4.13. [0869eb93c773] [4.13] * Merged the v4.12 maintenance branch into the trunk. [021e97baeeb0] * NEWS: Updated the NEWS file. [af334da384fd] <4.12-maint> 2011-10-13 Phil Thompson * sipgen/parser.y, sphinx/specification_files.rst: '*' and '&' are now accepted as unary operators in expressions used to define the values of default arguments. [4eba42cb2457] <4.12-maint> * sipgen/parser.y, sipgen/sip.h.in: Further fix for overloads with a variant that is protected and a variant that has optional arguments defined in a module that supports keyword arguments imported by a module that doesn't. [79951a333f30] <4.12-maint> 2011-10-10 Phil Thompson * sipgen/gencode.c, sphinx/annotations.rst: The /Transfer/ annotation can now be used with the /Array/ annotation to prevent the freeing of the temporary array of pointers. [3a009ee97d60] <4.12-maint> 2011-10-07 Phil Thompson * NEWS, siplib/siplib.c.in, sphinx/directives.rst: %ConvertToSubClassCode can now cause a restart of the conversion process using a different requested type. This enables the correct handling of PyQt's QLayoutItem. [fa212070a486] <4.12-maint> 2011-10-06 Phil Thompson * siplib/siplib.c.in: sipIsPyMethod() now allows for an object's type's tp_mro to be NULL. This can happen when the only instance of a dynamically created type is in the process of being garbage collected. [d66046441fa8] <4.12-maint> 2011-10-04 Phil Thompson * siplib/siplib.c.in: Commit backout. [6e11ad753de6] <4.12-maint> * sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in: Backed out changeset 0bcc2ce09ba0 This (and the following changeset) doesn't seem to make a difference. [2df67f4a3294] <4.12-maint> * siplib/siplib.c.in: Commit backout. [4a9b20624f88] <4.12-maint> * siplib/siplib.c.in: Backed out changeset de3fe63e5dec This (and the previous changeset) doesn't seem to make a difference. [78740eff2bf4] <4.12-maint> 2011-09-27 Phil Thompson * siplib/siplib.c.in: Add an atexit function that will disable all Python reimplementations of virtuals. [de6a700f5faa] <4.12-maint> 2011-09-26 Phil Thompson * NEWS, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h.in, sphinx/directives.rst: Added the %DefaultDocstringFormat directive. Added the format argument to the %Docstring directive. [dba052605539] <4.12-maint> 2011-09-24 Phil Thompson * siplib/siplib.c.in: Fixed the previous fix to sipIsPyMethod() so that it doesn't retain the GIL. [de3fe63e5dec] <4.12-maint> 2011-09-17 Phil Thompson * sipgen/gencode.c, siplib/sip.h.in.in, siplib/siplib.c.in: sipIsPyMethod() now acquires the GIL before checking if the Python object has been garbage collected. [0bcc2ce09ba0] <4.12-maint> * siplib/siplib.c.in: Fixed a typo in a comment. [c4ad84eeed37] <4.12-maint> * siplib/siplib.c.in: Added a missing Py_DECREF() on a (very rarely used) error handling path. [a99ab15f7b18] <4.12-maint> 2011-09-03 Phil Thompson * sipgen/gencode.c: Fixed a code generation bug where a module with keyword arguments disabled derives from a class imported from a module with them enabled. [1c3d2412e35a] <4.12-maint> 2011-08-26 Phil Thompson * sipgen/gencode.c: PyQt will now only delete a QObject if the QObject belongs to the current thread, otherwise it calls deleteLater(). [c2987628087f] <4.12-maint> 2011-08-02 Phil Thompson * .hgtags: Added tag 4.12.4 for changeset 7dff386f6d8c [49580889fa23] <4.12-maint> * NEWS: Released as v4.12.4. [7dff386f6d8c] [4.12.4] <4.12-maint> 2011-07-29 Phil Thompson * NEWS, siputils.py: Added support for Qt configured with -qtlibinfix based on a patch from Ian Scott. [d87cea364549] <4.12-maint> * NEWS, sipgen/gencode.c, siplib/siplib.c.in: Switched to using PyLong_AsUnsignedLongMask() and PyLong_AsUnsignedLongLongMask() instead of the non-mask versions so that overflow is ignored. [533e6a9e3e3a] <4.12-maint> 2011-07-10 Phil Thompson * sipgen/gencode.c: Make sure the %TypeHeaderCode of a /Default/ %Exception is included. [bbe43a0bad78] <4.12-maint> 2011-06-23 Phil Thompson * siplib/siplib.c.in: Fixed a regression introduced in the recent sipIsPyMethod() changes in the handling of special methods implemented by object (eg. __lt__). [f9f4b161c940] <4.12-maint> * siplib/siplib.c.in: Fixed some other warnings from more (undocumented) Python v3.2 changes. [df42f6bf92c8] <4.12-maint> * siplib/sip.h.in.in, siplib/voidptr.c: Fixed sipConvertFromSliceObject() for Python v3.2. [3d0336c32dfa] <4.12-maint> 2011-06-13 Phil Thompson * build.py: Fixed the build system for MacOS as the development platform. [fdd3cecee60d] <4.12-maint> 2011-05-22 Phil Thompson * .hgtags: Added tag 4.12.3 for changeset 50282bee0c60 [54c00a0e9c01] <4.12-maint> * NEWS: Released as v4.12.3. [50282bee0c60] [4.12.3] <4.12-maint> 2011-05-20 Phil Thompson * sipgen/gencode.c: Generated signal signatures no longer remove the reference '&' for non-const arguments. [274e38133e7a] <4.12-maint> * siplib/siplib.c.in: Fixed the calling of hooks for Python3. [192dfa04b3ac] <4.12-maint> 2011-05-15 Phil Thompson * siplib/siplib.c.in, sphinx/incompatibilities.rst: When searching for a Python reimplementation of a virtual C++ method, any object that is not a C++ method wrapper is assumed to be valid. Previously, if it wasn't a Python function or method then it would be ignored. This is a potential incompatibility, but any code that is affected is either buggy or badly written. [f95ee221598d] <4.12-maint> 2011-04-30 Phil Thompson * .hgtags: Added tag 4.12.2 for changeset dd8f52a95d04 [b99179c54a07] <4.12-maint> * NEWS: Released as v4.12.2. [dd8f52a95d04] [4.12.2] <4.12-maint> 2011-04-22 Phil Thompson * sipgen/gencode.c, sipgen/parser.y, sipgen/transform.c: Added support for global inplace numeric operators. [af33bd829af3] <4.12-maint> * sipdistutils.py: Updated the license and copyright information for sipdistutils.py. [94f4971497a9] <4.12-maint> 2011-04-18 Phil Thompson * sipgen/parser.y: Made sure thngs were initialised to 0 properly when parsing new- style directives for variables. [c3f5a8b89968] <4.12-maint> 2011-04-14 Phil Thompson * NEWS, sipgen/parser.y: Handwritten code in class templates no longer has types substituted in lines that appear to be C preprocessor directives. This prevents #include'd file names getting substituted. [e039b65daa03] <4.12-maint> 2011-04-08 Phil Thompson * siplib/siplib.c.in: Fixed a regression in the handling of keyword arguments. [f68e042c94f5] <4.12-maint> 2011-03-29 Phil Thompson * NEWS: Updated the news file. [ec9807971e08] <4.12-maint> 2011-03-27 Phil Thompson * sipgen/parser.y: The names of optional arguments to protected methods are generated no matter what module the method is defined in. [fe4c052830ff] <4.12-maint> * sipgen/gencode.c: Another fix for the bad protected enum fix. [d112d90bcbfd] <4.12-maint> * sipgen/parser.y: Fixed a bug where keyword argument names were being generated when being defined in a parent module. [3e11c4b7d541] <4.12-maint> 2011-03-26 Phil Thompson * sipgen/parser.y: Mapped type template arguments now include "const" if appropriate. [22c5009485a8] <4.12-maint> * sipgen/gencode.c: Fixed a regression that caused enums in namespaces to be ignored. [f9b89f2c1c7d] <4.12-maint> 2011-03-25 Phil Thompson * siplib/siplib.c.in: The keyword support now explicitly checks that keywords are provided. Python handles this for ordinary methods but not for __init__. [05718fa95834] <4.12-maint> 2011-03-22 Phil Thompson * sipgen/gencode.c: Code is no longer generated for protected enums of /Abstract/ classes. [d349bb35cdcc] <4.12-maint> 2011-03-18 Phil Thompson * sipgen/gencode.c: The /KeepReference/ function annotation now keeps a reference even if the result is already owned by Python. [ecb3e795382e] <4.12-maint> * sipgen/gencode.c, sipgen/parser.y, sipgen/transform.c, sphinx/annotations.rst: /KeepReference/ can now be used as a function annotation. [dc7effca2a82] <4.12-maint> * configure.py.in: A fix for when building outside the source directory. [942f1b8ac66b] <4.12-maint> 2011-03-03 Phil Thompson * sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h.in, sipgen/transform.c: The %TypeHeaderCode from a class template is now included in the generated code. [b5992208a757] <4.12-maint> 2011-02-24 Phil Thompson * sipgen/parser.y, sipgen/transform.c: typedefs in class templates are now handled correctly. [62e2faa4fb81] <4.12-maint> * sipgen/transform.c: When comparing mapped type templates the number of dereferences of the template arguments is now taken into account. [9cf3969984a5] <4.12-maint> 2011-02-22 Phil Thompson * sipgen/gencode.c: %Docstring applied to a Qt signal is no longer ignored. [0fae9a0aae28] <4.12-maint> 2011-02-21 Phil Thompson * sipgen/gencode.c: Fixed /KeepReference/ when used with ctors. [1a5475b48b7c] <4.12-maint> 2011-01-22 Phil Thompson * .hgtags: Added tag 4.12.1 for changeset 6a8117e8b16a [2ead36288f97] <4.12-maint> * NEWS, build.py: Released as v4.12.1. [6a8117e8b16a] [4.12.1] <4.12-maint> 2011-01-21 Phil Thompson * siplib/siplib.c.in: Tweaked an exception message to make it easier to mimic in handwritten code. [426308437843] <4.12-maint> * sipgen/transform.c: sip will now longer complain about callables with the same Python signature if either of them has %MethodCode as it assumes that the %MethodCode will resolve any potential conflicts. [9ed59e5c8070] <4.12-maint> 2011-01-15 Phil Thompson * build.py, sphinx/conf.py.in, sphinx/static/default.css, sphinx/static/logo.png, sphinx/static/logo_tn.ico: Added a new Sphinx stylesheet. [c0c94278423e] <4.12-maint> 2011-01-14 Phil Thompson * NEWS: Updated the NEWS file. [fa100876a783] <4.12-maint> 2011-01-07 Phil Thompson * LICENSE, build.py, configure.py.in, sipgen/export.c, sipgen/extracts.c, sipgen/gencode.c, sipgen/heap.c, sipgen/lexer.l, sipgen/main.c, sipgen/parser.y, sipgen/sip.h.in, sipgen/sipgen.sbf, sipgen/transform.c, siplib/apiversions.c, siplib/bool.cpp, siplib/descriptors.c, siplib/objmap.c, siplib/qtlib.c, siplib/sip.h.in.in, siplib/sipint.h, siplib/siplib.c.in, siplib/siplib.sbf.in, siplib/threads.c, siplib/voidptr.c, siputils.py, sphinx/conf.py.in, sphinx/directives.rst: Updated the copyright notices. [42e1cfe37140] <4.12-maint> * sphinx/directives.rst: Fixed a documentation typo. [e54f022f78f6] <4.12-maint> * NEWS, sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h.in, sphinx/annotations.rst: Added the /RaisesPyException/ function annotation. [649736ef0ab2] <4.12-maint> 2011-01-03 Phil Thompson * configure.py.in, siputils.py, sphinx/build_system.rst, sphinx/installation.rst: Added the --deployment-target option to configure.py which should be used to work around bugs in the latest versions of Python on MacOS/X. [18c8fe174f38] <4.12-maint> 2011-01-02 Phil Thompson * sipgen/gencode.c: Fixed a code generation bug in the %MethodCode error handling for zero argument slots. [4ed8b04e7e7a] <4.12-maint> 2010-12-31 Phil Thompson * sipgen/lexer.l, sipgen/parser.y, sphinx/specification_files.rst: Added SIP_SSIZE_T as a pre-defined type so it can be used in .sip files. [1871ed7f3c9b] <4.12-maint> * sipgen/parser.y, sphinx/specification_files.rst: PyObject * is now a synonym for SIP_PYOBJECT in .sip files. [56e378d55db0] <4.12-maint> * siplib/siplib.c.in, sphinx/python_api.rst: Added sip.ispycreated(). [e1efc2847290] <4.12-maint> 2010-12-28 Phil Thompson * NEWS, sipgen/parser.y, siplib/siplib.c.in, sphinx/specification_files.rst: Added support for the __getattribute__ and __getattr__ methods. [1da2e2e9fa1c] <4.12-maint> 2010-12-27 Phil Thompson * NEWS, sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h.in, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/specification_files.rst: Added support for __setattr__ and __delattr__ methods. [3f7a1f5bff74] <4.12-maint> * siplib/siplib.c.in: The lazy attributes of a type are added when the first instance of the type is created. This leaves the instance tp_getattro and tp_setattro slots available. [12a8fc4ee75a] <4.12-maint> 2010-12-24 Phil Thompson * NEWS: Fixed some errors in the NEWS file. [44a6a3833477] <4.12-maint> 2010-12-23 Phil Thompson * .hgtags: Added tag 4.12 for changeset 4a79f5996bd7 [111436ade941] * NEWS: Released as v4.12. [4a79f5996bd7] [4.12] * sipgen/gencode.c: A further fix for Python v2.4 and earlier. [5e655e94fc64] * sipgen/gencode.c: Fixed the code generated for a composite module an Python v2.4 and earlier. [00b0fadcf6fc] * siplib/voidptr.c: Add a couple of casts for MSVC2008. [68916b34ac59] 2010-12-20 Phil Thompson * sphinx/python_api.rst: Updated the documentation regarding the sip.simplewrapper type. [0f92caeb5770] * sipgen/parser.y, sipgen/transform.c: Fixed a bug looking up mapped types that are templates with enum arguments. [1212ca61ef1d] 2010-12-18 Phil Thompson * sipgen/transform.c: Fixed the inclusion of header files for init extenders. [171d8f4e9f3a] 2010-12-11 Phil Thompson * siplib/voidptr.c: sip.voidptr now uses PyLong_AsVoidPtr() for all versions of Python. [3d4ccc59c9c3] 2010-12-09 Phil Thompson * configure.py.in: Improved the configure.py error message when an invalid build macro is given. [631ded439583] * Roadmap.rst: Removed the section of the roadmap stating that SIP v5 will require types to be defined in advance of being used because (after thinking about it properly) in would be a complete pain for the user. [02eee09f591f] * sipgen/sip.h, sipgen/sip.h.in: Fixed an apparent hg problem with sipgen/sip.h[.in]. [1fd9ca0698a0] 2010-12-07 Phil Thompson * sipgen/lexer.l, sipgen/sip.h: Fixed the parsing of %Extract. [393564f2cfeb] * sipgen/gencode.c: Make sure backslashes in generated #line directives are escaped. [cc58da4653e7] * sipgen/parser.y, sipgen/sip.h: A deprecation warning is issues for any argument annotations in an explicit C/C++ signature. [8d0e2a1b1d1c] * sipgen/parser.y, sipgen/sip.h, sphinx/directives.rst: /AllowNone/ is a valid class annotation. [e94d52f996d7] 2010-12-06 Phil Thompson * sipgen/parser.y, sipgen/sip.h, sphinx/annotations.rst: Deprecation warning are now generated for any invalid annotation. Updated the docs so that annotations are mentioned in all the contexts that they can applied to. [a3715d0c74a5] * NEWS, build.py, sipgen/main.c, sipgen/main.c.in, sipgen/parser.y, sipgen/sip.h, sphinx/directives.rst: Added the automatic pseudo-%Timeline of SIP version numbers. [50fc306bfb6d] * NEWS, sphinx/annotations.rst: Documented /PyInt/ as a typedef annotation. [0d8a873e3d30] 2010-12-03 Phil Thompson * NEWS, siplib/sip.h.in.in, siplib/siplib.c.in, sphinx/c_api.rst: Added sipGetAddress() to the public API. [b202f0d04ba6] 2010-11-30 Phil Thompson * sipgen/main.c.in, sphinx/command_line.rst: Don't try and issue warnings until the -w flag has been parsed. [64e98b58216b] * NEWS, sipgen/gencode.c, sipgen/lexer.l, sipgen/main.c.in, sipgen/parser.y, sipgen/sip.h, sphinx/annotations.rst, sphinx/command_line.rst, sphinx/directives.rst: Added the 'keyword_arguments' argument to %Module. The /KeywordArgs/ annotation now takes a string value describing the level of keyword argument support. The previous behavior is deprecated. Deprecated the /NoKeywordArgs/ annotation. Deprecated the code generator's -k command line option. [2294802123f4] 2010-11-28 Phil Thompson * sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h: More generic parser fixes for directives that allow an argument without requiring parentheses. [1d6ba419952c] 2010-11-27 Phil Thompson * sipgen/parser.y, sphinx/directives.rst: Semi-colons are now not allowed after directives with no sub- directives but are now required after the closing brace after sub- directives. [1a300e9d7f80] * sipgen/parser.y: Tidy up some coding inconsistencies in the parser. [c86ace2573fd] * sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h: The (internal) %Plgin directive now uses the revised syntax. [86a793919cd1] * sipgen/lexer.l, sipgen/parser.y, sphinx/directives.rst: %Timeline now respects %If/%End. [d227e7ea1eac] * sipgen/parser.y, sphinx/directives.rst: %Platforms now respects %If/%End. [3c1e4cb9dd4c] * sipgen/parser.y, sphinx/directives.rst: %Doc and %ExportedDoc now respect %If/%End. [e3f95120f8c9] * sipgen/lexer.l, sipgen/parser.y, sphinx/directives.rst: %OptionalInclude is now deprecated. [fbfa68d0b559] * sipgen/parser.y, sphinx/directives.rst: The %MappedType sub-directives now respect %If/%End. [afb6cb9b21b9] * sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, sphinx/annotations.rst, sphinx/conf.py.in, sphinx/directives.rst: %License now uses the revised syntax. [ebeed9b2838e] * sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, sphinx/directives.rst: %Include now follows the new syntax and includes the functionality of %OptionalInclude. [b71dca41f194] * sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, sphinx/directives.rst: %Import now uses the revised syntax. [df828f381c63] * sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, sphinx/directives.rst: Changed the argument of %DefaultEncoding to 'name' to be consistent with other similar directives. [66c4f0e60cc5] 2010-11-26 Phil Thompson * sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, sphinx/directives.rst: %Feature now uses the revised syntax. [ca22b358ab05] * sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, sphinx/directives.rst, sphinx/specification_files.rst: %Exception now (sort of) follows the revised syntax. [b19d67575786] * sipgen/parser.y, sphinx/directives.rst: Reverted the change to make %Copying a sub-directive. [d59876780e53] * sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, sphinx/directives.rst: %DefaultEncoding now uses the revised syntax. [111024e5bcbd] 2010-11-25 Phil Thompson * sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, sphinx/directives.rst, sphinx/incompatibilities.rst, sphinx/specification_files.rst: Fixed some more generic parser issues. %Copying is now a sub- directive of each of the different module directives. All the module directives now support docstrings. [6244dcb1fcb9] * sipgen/parser.y, sipgen/sip.h, sphinx/directives.rst: %CompositeModule and %Consolidated module now conform to the revised syntax. [18da01aba948] * sipgen/parser.y, sipgen/sip.h, sphinx/directives.rst, sphinx/using.rst: %API now uses the revised directive syntax. [b7ba07998b37] 2010-11-23 Phil Thompson * sipgen/gencode.c: Generated #line directives now include the full path name of the file. [52ed45309f83] * siplib/siplib.c.in: Reverted the broken "fixes" passing sub-int values as varargs. [167ff79ec560] 2010-11-22 Phil Thompson * sipgen/parser.y, sipgen/sip.h, sphinx/directives.rst: The %Module and %Property sub-directives now respect %If/%End. %AccessCode, %GetCode and %SetCode are now new-style sub-directives. [7dfe49a56ec7] * Roadmap.rst: Added the v5 roadmap. [9ddab02f25a6] * sipgen/parser.y: /PyInt/ can now be applied to pointer types. [0a986be7f8e4] 2010-11-21 Phil Thompson * NEWS, sipgen/export.c, sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/siplib.c.in, sphinx/annotations.rst, sphinx/c_api.rst: Added /PyInt/ as an argument and function annotation. Added the L and M format characters to sipBuildResult(), sipCallMethod() and sipParseResult(). Fixed a bug in sipParseResult() in the handling of encoded strings. [372703eb4e88] * sipgen/gencode.c: Fixed a bug maintaining the current line number when generating docstrings. [2327d077f65a] 2010-11-20 Phil Thompson * sipgen/parser.y, sphinx/specification_files.rst: Added parser support for empty namespaces. Documented how namespaces are implemented and how to achieve the different behaviors. [9101c7412e89] * sphinx/annotations.rst, sphinx/command_line.rst, sphinx/directives.rst: Documented that -I, %Import and %Include all expect POSIX style directory separators. [7b0d6bc17f28] 2010-11-13 Phil Thompson * siplib/sip.h.in.in, siplib/siplib.c.in, siplib/voidptr.c: Eliminate compiler warnings when building the sip module. [93040d2c716c] * siplib/siplib.c.in, siplib/voidptr.c: Fixed some Python v3 and MSVC build bugs. [43cb06769dd6] 2010-11-12 Phil Thompson * NEWS: More updates to the NEWS file. [c38668e9dd93] * NEWS: Updated the NEWS file. [37a725e0b83a] * sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, siplib/siplib.c.in: Eliminated a couple of warning messages. [8d220ed77f02] * sipgen/parser.y: %Module and %Property sub-directives can now be individually enclosed in %If/%End. [637f2357b1e4] * sphinx/annotations.rst, sphinx/directives.rst: Documented the %AutoPyName directive. [e8106eb58553] * sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h: Added the %AutoPyName directive. [85d02c95ebf7] 2010-11-11 Phil Thompson * sipgen/gencode.c, sipgen/main.c.in, sipgen/sip.h, sphinx/command_line.rst: Added the -T command line flag to suppress the timestamp in the header of generated source files. [d84b9db1d89d] * sipgen/gencode.c: Fixed a bug where keyword strings where being generated for /Out/ arguments. [2a314426e67a] * sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, sphinx/directives.rst: Replaced the %RealArgNames directive with the use_argument_names argument to the %Module directive. [0eb004659e3d] * sipgen/parser.y, sphinx/directives.rst: The %Module directive now respects the %If directive. [9b99a6f7d295] * sphinx/directives.rst: Documented the revised %Module directive syntax. [0a7d4b89a2eb] * sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h: %Module now supports the revised directive syntax. Module docstrings are now supported. %CModule is deprecated. [2606deb743f2] 2010-11-09 Phil Thompson * sipgen/gencode.c: Fixed a bug in the generated of the variables table. [eac351f5cca7] * sipgen/gencode.c, sipgen/sip.h, sipgen/transform.c: Fixed a bug in the tidying up of temporary class instances in unary operators. [990299a02451] * sphinx/directives.rst: Documented the %Property directive. [455500391b43] * sipgen/parser.y, sphinx/directives.rst: Documented the revised directive syntax. Updated %Extract so that it follows the revised syntax completely. %Extract no longer uses a quoted string as an identifer. [7970e4fa94ef] * sipgen/gencode.c, sipgen/sip.h, sipgen/transform.c, siplib/sip.h.in.in, siplib/siplib.c.in: Completed the support for %Property. [dfd258dec260] * sipgen/gencode.c, sipgen/sip.h: The code generator now generates the property structure. [07134d471acd] * sipgen/gencode.c, siplib/descriptors.c, siplib/sip.h.in.in, siplib/siplib.c.in: Migrated the existing variable support to the new runtime structure. [c66412e816ab] 2010-11-08 Phil Thompson * sipgen/lexer.l: Fixed the parser so that C/C++ argument names don't get confused with directive argument names. [8bad8295e12f] 2010-11-07 Phil Thompson * sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c: Renamed getter to get and setter to set to be consistent with %GetCode and %SetCode. [eef0c18dd0df] * sipgen/parser.y, sipgen/transform.c: The %Property getters and setters are now validated. [caf6e4cee176] * sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h: Added parser support for %Property. [41f66dca2447] * sipgen/extracts.c, sipgen/lexer.l, sipgen/main.c.in, sipgen/parser.y, sipgen/sip.h, sipgen/sipgen.sbf, sphinx/command_line.rst, sphinx/directives.rst, sphinx/specification_files.rst: Added the %Extract directive and the corresponding -X command line option. [37a7149135a9] 2010-11-04 Phil Thompson * sipgen/lexer.l, sipgen/main.c.in, sipgen/parser.y, sipgen/sip.h, sphinx/c_api.rst, sphinx/command_line.rst, sphinx/directives.rst, sphinx/introduction.rst.in, sphinx/python_api.rst: Issue warning messages from the parser about deprecated syntax. Updated the documentation regarding deprecations. [3a45afc8d9eb] * siplib/voidptr.c: Fixed a bug in the new sip.voidptr code for Python v2.5 and earlier. [7ff903c5cb76] * sphinx/python_api.rst: Updated the sip.voidptr documentation to describe the memoryview- like support. [b49b90639831] * sipdistutils.py: sipdistutils.py now allows the output directory to be overriden in a derived class. [5a1f9d9fff30] 2010-11-02 Phil Thompson * siplib/voidptr.c: Fixed a silly typo in the sip.voidptr changes. [af2d7120dd7f] * siplib/voidptr.c: sip.voidptr now supports sub-script assignment for Python v2.4 and earlier. [14186a17d310] * siplib/voidptr.c: sip.voidptr now supports sub-script assignment for Python v2.5. [67ef521ce467] * siplib/voidptr.c: sip.voidptr now supports sub-script assignment (Python v2.6 and later only at the moment). [4ad087fd7e94] * siplib/voidptr.c: sip.voidptr can now be indexed like memoryview. [76620ebb872e] * siplib/voidptr.c: sip.voidptr now fully implements the new buffer protocol for Python v2 so that memoryview works. [f9dfbda5844f] * NEWS, build.py, configure.py.in, sipgen/gencode.c, siplib/sip.h.in, siplib/sip.h.in.in, siplib/siplib.c, siplib/siplib.c.in, siplib/siplib.sbf, siplib/siplib.sbf.in, sphinx/installation.rst, sphinx/using.rst: Added the --sip-module flag to configure.py to allow private copies of the module to be built. [8b8e93a159c6] 2010-10-25 Phil Thompson * sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, sphinx/directives.rst, sphinx/specification_files.rst: Added the %RealArgNames directive. [12acbffd0085] 2010-10-24 Phil Thompson * sipgen/lexer.l: All directives now start with the first non-whitespace character of a line. [c5a525178196] * .hgtags: Merged the v4.11 branch into the trunk. [a7689cef100b] 2010-10-22 Phil Thompson * NEWS: Released as v4.11.2. [13f57fe7e992] [4.11.2] <4.11-maint> * sipgen/gencode.c: Fixed the implementation of %MethodCode for dtors in C modules. [4f26704c5789] <4.11-maint> 2010-10-21 Phil Thompson * siplib/siplib.c: Make sure that lazy attributes have been added when searching for a Python reimplemention of a C++ method. [f45ff97a3c66] <4.11-maint> * siplib/sip.h.in: Properly set SIP_SUPPORT_PYCOBJECT in sip.h. [f1cf3fef8eb5] <4.11-maint> 2010-10-12 Phil Thompson * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, siplib/sip.h.in, siplib/siplib.c: __enter__ and __exit__ are now handled as non-lazy methods and are added to the type dictionary when the type is created (rather than when the first attribute of the first instance is accessed). This required by a change in behaviour introduced in Python v2.7 and v3.2. [5167b98767e2] <4.11-maint> 2010-10-11 Phil Thompson * NEWS: Updated the NEWS file. [ed3deec59b70] <4.11-maint> 2010-10-09 Phil Thompson * sipgen/gencode.c: /KeepReference/ now applies to global functions. [52e6a73fd81f] <4.11-maint> * siplib/siplib.c: Fixed a regression in the handling of global class pointers (eg. qApp in PyQt3). [08328092b36b] <4.11-maint> 2010-10-08 Phil Thompson * sipgen/gencode.c, siplib/siplib.c: /KeepReference/ can now be applied to static methods. [43c2359df596] <4.11-maint> 2010-10-03 Phil Thompson * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sphinx/directives.rst: %TypeCode can now be specified in a %MappedType directive. [8727e0eb0f5e] <4.11-maint> * sipgen/transform.c: Mapped types for templates no longer require the template arguments to be defined. [7ed0e265a218] <4.11-maint> 2010-10-01 Phil Thompson * siputils.py: Added support for the MSBUILD Makefile generator introduced in Qt v4.7 for the win32-msvc2010 target. [ff2494c0e443] <4.11-maint> 2010-09-30 Phil Thompson * sipgen/parser.y: A protected class enum will now trigger the generation of a shadow class. [18681651c2c7] <4.11-maint> 2010-09-27 Phil Thompson * sphinx/c_api.rst: A minor documentation fix. [f6df40935e99] <4.11-maint> 2010-09-24 Phil Thompson * configure.py.in: Fixed the rpaths problem properly (ie. didn't apply the fix to a generated file). [c93f5da3d4e4] <4.11-maint> * NEWS, siputils.py: Taught the build system about QtDeclarative. Updated the NEWS file. [2487fb909ee1] <4.11-maint> 2010-09-23 Phil Thompson * siputils.py: Fixed rpaths for Qt v4.7. [4d12df6526e5] <4.11-maint> 2010-09-14 Phil Thompson * siplib/sip.h.in: Ensured that uint is always defined. [b6508f053614] <4.11-maint> 2010-09-06 Phil Thompson * .hgtags: Added tag 4.11.1 for changeset fdf86b3115cd [3213dc5731bb] <4.11-maint> * NEWS: Released as v4.11.1. [fdf86b3115cd] [4.11.1] <4.11-maint> 2010-09-02 Phil Thompson * siplib/objmap.c: When deciding if an entry in the object map is valid the C/C++ address is first checked to see if it is still valid. This detects the case (if there is a guard in place) where a new C/C++ object has been created at the same address of one that has been destroyed (but whose Python wrapper is still around). HG commit message. Lines beginning with 'HG:' are removed. [13632c7f0f2c] <4.11-maint> 2010-08-31 Phil Thompson * .hgtags: Added tag 4.11 for changeset 80f7c6530416 [86286537601c] * NEWS: Released as v4.11. [80f7c6530416] [4.11] 2010-08-23 Phil Thompson * sipgen/gencode.c, siplib/objmap.c, siplib/sip.h.in, siplib/siplib.c, sphinx/c_api.rst: Objects with handwritten access functions are no longer placed in the object map as they don't have a usable key. Reworked the support for meta-type aupplied access functions so that the original address is still available (even if it is no longer valid) to be used to search the object map. [c38d259c1879] 2010-08-21 Phil Thompson * NEWS: Updated the NEWS file. [7cff86d70dc7] 2010-08-20 Phil Thompson * siplib/siplib.c: The parsing of encoded strings is now done with two passes so that encoding errors are now picked up in the second pass and raise an appropriate exception. [89ff42be167c] 2010-08-19 Phil Thompson * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sphinx/annotations.rst: The /KeepReference/ annotation now takes an optional integer key value. [efff0d2932e1] * sipgen/gencode.c, sipgen/parser.y, siplib/siplib.c: operator() and __call__() now support keyword arguments. [0daacc25c6ce] 2010-08-18 Phil Thompson * siplib/sip.h.in, siplib/siplib.c, sphinx/c_api.rst: Completed the access function implementation so that any resources created by access functions are released appropriately. [35cf486718d4] 2010-08-17 Phil Thompson * sipgen/gencode.c, siplib/sip.h.in, siplib/siplib.c, sphinx/c_api.rst: Removed sipRegisterObjectFinaliser() and assume that the equivalent functionality will be provided by a custom meta-class. [d028d0cecb7b] * sipgen/gencode.c, siplib/sip.h.in, siplib/siplib.c: Added sipRegisterObjectFinaliser() and related infrastructure. (Though it will probably be replaced by a meta-type based implementation.) [d525d84c9d61] * sipgen/gencode.c, siplib/objmap.c, siplib/qtlib.c, siplib/sip.h.in, siplib/sipint.h, siplib/siplib.c: All access to the C/C++ object now goes through sip_api_get_address(). Bumped the internal API version to 8.0 (because the size of sipSimpleWrapper has changed). [956c80d8e9fa] 2010-08-16 Phil Thompson * sipgen/parser.y: Make sure #line 0 is not generated as the Intel compiler doesn't like it. [d715222f1f65] * siplib/voidptr.c, sphinx/c_api.rst, sphinx/embedding.rst, sphinx/python_api.rst: Added support for Python v3.2. Exposed the SIP_USE_PYCAPSULE macro as part of the C API. [0e34dc4e0824] 2010-08-15 Phil Thompson * sipgen/gencode.c: Fixed a code generation bug affecting inplace operators. [6cddd9276220] 2010-08-05 Phil Thompson * siplib/siplib.c: Refactored the calls to assert() when creating types to catch any recursive calls. [052b642f04a8] 2010-08-03 Phil Thompson * sipgen/gencode.c: Make sure the %UnitPostIncludeCode is after all #includes. [d45e8042c7da] * NEWS, sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, sphinx/directives.rst: Added the %UnitPostIncludeCode directive. [058d680384e7] * NEWS, sipgen/export.c, sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, sphinx/directives.rst: Removed the %RemoveNamespace directive. [18fc68280d49] * sipgen/gencode.c: Removed 'const' and '&' from signal signatures so that Qt doesn't have to. [9e9795fa36a5] * sipgen/transform.c: Fixed a problem with the recent change regarding the original types of template based mapped types. [83019d3299ea] * sipgen/gencode.c, sipgen/parser.y: Generated code now uses 'uint' rather than 'unsigned'. This is because Qt's QMetaObject::normalizedType() converts the latter to the former. [0923d067541a] * sipgen/gencode.c: The generated typedefs table now always defines a type in terms of a base type and never another typedef type. [5ed328590fd1] * sipgen/transform.c: Template based mapped types now correctly keep a reference to the original types used when invoking the template. [691852c6b0b0] 2010-07-31 Phil Thompson * sipgen/transform.c: Const references are now assumed to be input arguments rather than output arguments. [d11b7adf095a] 2010-07-29 Phil Thompson * sipgen/parser.y: An improvement on the previous fix. [086a77b99464] * sipgen/parser.y: Fixed global operators that are declared in a namespace. [c46ac8f9b1e9] 2010-07-27 Phil Thompson * build.py: Switched to the new format of snapshot names. [4d30378c5622] * NEWS, sipgen/export.c, sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, sphinx/directives.rst: Implemented the %RemoveNamespace directive. [a2eb3fe46f43] * lib/LICENSE, lib/LICENSE-GPL2.txt, lib/LICENSE-GPL3.txt, lib/LICENSE.short, lib/README, lib/configure.py, lib/sipdistutils.py, lib/siputils.py, sipgen/main.c, siplib/sip.h, sphinx/Makefile, sphinx/conf.py, sphinx/introduction.rst: Merged v4.10.5 into the trunk. [4cce948441da] 2010-07-16 Phil Thompson * NEWS, siplib/sip.h.in, siplib/voidptr.c, sphinx/python_api.rst: Released as v4.10.5. Fixed the build regression against Python v3 introduced in SIP v4.10.4. Properly fixed the Python v2.7 workaround that SIP v4.10.4 was supposed to address. [834787fbcb72] [4.10.5] <4.10-maint> 2010-07-15 Phil Thompson * .hgtags: Added tag 4.10.4 for changeset 046c346a71fe [d0340fc3658c] <4.10-maint> * NEWS: Released as v4.10.4. [046c346a71fe] [4.10.4] <4.10-maint> 2010-07-13 Phil Thompson * NEWS, sipgen/gencode.c, siplib/siplib.c, siplib/voidptr.c: Use PyCapsule when available to work around an apparent bug in PyCObject in Python v2.7. [f5574a061fd0] <4.10-maint> 2010-07-12 Phil Thompson * .hgtags: Added tag 4.10.3 for changeset 2ec1a8f8560c [254b8071446e] <4.10-maint> * NEWS, README: Released as v4.10.3. [2ec1a8f8560c] [4.10.3] <4.10-maint> 2010-07-08 Phil Thompson * NEWS, sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, sphinx/annotations.rst: Added support for the __len__ annotation. [f760366cea3b] <4.10-maint> * sipgen/transform.c: Assignment helpers are now generated for classes that have a ctor where all arguments are optional. [3e647ed0f2a2] <4.10-maint> 2010-06-29 Phil Thompson * sipgen/gencode.c: Fixed the code generator for /NewThread/ methods so that it no longer assumes that such methods are abstract (though it still assumes they don't return a value) as QThread.run() no longer is. [710b71e6f0c6] <4.10-maint> * siputils.py: Fixed a regression introduced when fixing the += problem with spec. files. [94d177d8f426] <4.10-maint> 2010-06-11 Phil Thompson * sipgen/export.c, sipgen/gencode.c, sipgen/sip.h: Changed the generated docstrings for signals to use [] rather than () to surround the arguments. [1851f2d754e7] <4.10-maint> 2010-06-10 Phil Thompson * sipgen/gencode.c: Fixed a code generation bug where special methods that invoke sipNoMethod() were trying to tidy up sipParseErr rather than leaving it to sipNoMethod(). [90aad46480b2] <4.10-maint> 2010-06-08 Phil Thompson * sipgen/gencode.c: Fixed the previous fix to avoid compiler warning messages. [0a3f45fea555] <4.10-maint> * sipgen/gencode.c: Fixed a code generation bug caused by ctor handwritten code that sets the error flag and isn't handling unused keyword arguments. [d53889ad7abe] <4.10-maint> 2010-06-06 Phil Thompson * NEWS, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, sphinx/specification_files.rst: Added support for Q_SLOT and Q_SIGNAL. [cb323da88516] <4.10-maint> 2010-06-05 Phil Thompson * sipgen/lexer.l: Added support for Q_SIGNALS and Q_SLOTS as synonyms for signals and slots. [daf61465ef3c] <4.10-maint> * siputils.py: Fixed a build system regression introduced when not linking against X11 when building QtCore. [ee5415b91040] <4.10-maint> 2010-06-03 Phil Thompson * siputils.py: The build system now handles += in spec files properly. [f292793d6c99] <4.10-maint> 2010-05-28 Phil Thompson * configure.py.in, siputils.py: A build system fix for building a static version of QWebKit. [de0df36d3162] <4.10-maint> * sipgen/transform.c: Fixed a bug in the error message when reporting an unsupported signal argument type. [7adbf28d075e] <4.10-maint> 2010-05-07 Phil Thompson * sipgen/gencode.c: Fix a code generation bug where a protected ctor had a protected enum argument. [529660fb77a9] <4.10-maint> 2010-04-23 Phil Thompson * sipgen/main.c.in, siplib/qtlib.c: Invoking a slot is ignored if the underlying C++ object no longer exists. [7387fa17a780] <4.10-maint> 2010-04-16 Phil Thompson * .hgtags: Added tag 4.10.2 for changeset 44ac47d02467 [2a980c3f0e3a] <4.10-maint> * NEWS: Released as v4.10.2. [44ac47d02467] [4.10.2] <4.10-maint> 2010-04-06 Phil Thompson * sphinx/using.rst: Updated the PyQt example for PyQt4. [275fa5a54910] <4.10-maint> 2010-04-01 Phil Thompson * siplib/siplib.c: Fixed a regression in the new-style error handling of C++ ctors that raise exceptions. [ea295d6e9e9c] <4.10-maint> 2010-03-26 Phil Thompson * siputils.py: The X11 libraries will only be linked for modules that depend on the QtGui module. [9fe1eb5bf1ac] <4.10-maint> 2010-03-22 Phil Thompson * siplib/siplib.c: Fixed a bug in the pickle support under Python v3. [9c51fda2b963] <4.10-maint> 2010-03-17 Phil Thompson * .hgtags: Added tag 4.10.1 for changeset 812aad0bacea [6f759792341f] <4.10-maint> * NEWS, build.py: Fixed the generation of the change log after tagging a release. Updated the NEWS file. Released as v4.10.1. [812aad0bacea] [4.10.1] <4.10-maint> * siplib/siplib.c: Removed an unused variable left over from the previous commit. [0068b2608046] <4.10-maint> * siplib/siplib.c: Fixed the implementation of sip.cast(). [93bc3ab3fef5] <4.10-maint> 2010-03-02 Phil Thompson * NEWS: Updated the NEWS file. [752ab6580111] <4.10-maint> 2010-02-26 Phil Thompson * sipgen/gencode.c: Fixed a memory leak with the new error handling and most Python special methods. [637497440cb5] <4.10-maint> * sipgen/transform.c: Global operators, when moved to the correct class, are now appended to the list of any existing overloads to make sure the generated code is in the same order as the overloads in the .sip file. [5c0eb00cd19b] <4.10-maint> 2010-02-25 Phil Thompson * sipgen/export.c: Arguments in docstrings only have names if they are optional. [0f83f6c82600] <4.10-maint> 2010-02-20 Phil Thompson * sipgen/gencode.c, siplib/sip.h.in, siplib/siplib.c, sphinx/c_api.rst, sphinx/incompatibilities.rst: Fixed a bug in the handling of /Out/ arguments of virtuals where the type was a reference to a class by adding the 'H' format character to sipParseResult() (and deprecating the 'D' format character). [c723c4de2e22] <4.10-maint> 2010-02-18 Phil Thompson * sphinx/annotations.rst: Fixed a bug in the documentation of the NoCopy annotation. [cb2c1ea78ed5] <4.10-maint> 2010-02-07 Phil Thompson * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sphinx/annotations.rst: Python reimplementations of C++ virtuals will now be given a copy of any const references to classes so that they can keep a reference without needing to do their own explicit copy. The previous behaviour can be obtained using the new NoCopy annotation. The NoCopy annotation can also be applied to functions and methods to prevent the automatic copying of const references to classes that are returned. [724e4236428b] <4.10-maint> 2010-02-02 Phil Thompson * sipgen/export.c: Fixed the XML exporting of mapped type arguments. [b514b2f196b8] <4.10-maint> * siplib/sipint.h, siplib/siplib.c, siplib/siplib.sbf, siplib/voidptr.c: Moved the voidptr code to a separate file. Eliminated a few compilation warnings that have crept into the sip module. Refactored the sip module to eliminate the (wrong) forward declaration of the static type structures. [f07ec31fbdf9] <4.10-maint> * build.py: Fixed a bug in the release action of build.py. [bcdd91cbf139] <4.10-maint> 2010-01-31 Phil Thompson * sipgen/main.c.in: Added the -b command line argument to the sip usage text. [7ae3aa20dfc0] <4.10-maint> 2010-01-29 Phil Thompson * build.py: Refactored build.py so that it can be easily used as an imported module. [9170df0b1ea3] <4.10-maint> 2010-01-28 Phil Thompson * build.py: Fixed a regression in the release action of build.py. [e3611c1babe7] <4.10-maint> * build.py: Changed the format of the changelog to be closer to the Mercurial default. [f1d6ba993e7f] <4.10-maint> * build.py: Added the changelog action to build.py. [8189b0595d44] <4.10-maint> * build.py: build.py now generates a version number corresponding to the next release (as the old build system did). [d09c61626663] <4.10-maint> * build.py: build.py now doesn't care about the current working directory. Fixed the handling of branch names. [3402912a0176] <4.10-maint> 2010-01-27 Phil Thompson * README: Updated the README to document the need for flex, bison and Sphinx. [d785bd5471f8] <4.10-maint> * sphinx/introduction.rst.in: Updated the documentation to include the URL of the Mercurial repository. [0a7fc3830b27] <4.10-maint> * LICENSE, LICENSE-GPL2, LICENSE-GPL3, README, build.py, configure.py.in, lib/LICENSE, lib/LICENSE-GPL2.txt, lib/LICENSE- GPL3.txt, lib/LICENSE.short, lib/README, lib/configure.py, lib/sipdistutils.py, lib/siputils.py, sipdistutils.py, sipgen/export.c, sipgen/gencode.c, sipgen/heap.c, sipgen/lexer.l, sipgen/main.c, sipgen/main.c.in, sipgen/parser.y, sipgen/sip.h, sipgen/sipgen.sbf, sipgen/transform.c, siplib/apiversions.c, siplib/bool.cpp, siplib/descriptors.c, siplib/objmap.c, siplib/qtlib.c, siplib/sip.h, siplib/sip.h.in, siplib/sipint.h, siplib/siplib.c, siplib/siplib.sbf, siplib/threads.c, siputils.py, sphinx/Makefile, sphinx/conf.py, sphinx/conf.py.in, sphinx/introduction.rst, sphinx/introduction.rst.in: Refactored the build.py script so that it is a documented utility for allowing SIP to be built from a Mercurial repository or archive. Updated the directory structure accordingly. [3edc3f9c777f] <4.10-maint> 2010-01-27 phil * .hgtags: Import from SVN. [d6529eb1c096] 2010-01-14 phil * NEWS, lib/LICENSE.short: Released as v4.10. [d7aa01036415] [4.10] 2010-01-08 phil * lib/siputils.py, sipgen/gencode.c, sipgen/transform.c, siplib/siplib.c: Taught the build system about QtMultimedia. Removed some potential warning messages in virtual catchers with handwritten code. Fixed docstrings that might contain C++ rather than Python scoping. [d1214a2c892d] 2010-01-02 phil * siplib/siplib.c: Fixed a crash in the error handling when trying to call sip.wrapper or sip.wrappertype explicitly. [4f7c7b09a3e4] 2009-12-29 phil * siplib/apiversions.c: Fixed a memory corruption bug in the implementation of sip.setapi(). [11cc05a59770] 2009-12-28 phil * siplib/siplib.c: A fix for building against Stackless. [a3ce099e5002] 2009-12-27 phil * siplib/siplib.c: Fixed a regression in the parsing of constrained enums. [eacac49b64df] * siplib/siplib.c: Fixed a bug in the lookup of virtual reimplementations that may only be apparent when looking up Python special methods. [97c538d2e634] 2009-12-26 phil * siplib/siplib.c: Backed out the check for sub-classing from more than one wrapped type as it isn't sophisticated enough to handle mixins that share a meta-class. [34cf41855599] 2009-12-23 phil * siplib/siplib.c: Added a hack for va_copy() being missing in MSVC. [e3bd9f6c1a3a] 2009-12-22 phil * lib/siputils.py: Another attempt to fix creating script wrappers on MacOS to invokethe right version of Python. [39d66e33acfd] * sipgen/export.c, sipgen/gencode.c, sipgen/sip.h: Fixed a docstring bug handling default values that are literal strings. [a1fea3306f54] 2009-12-21 phil * siplib/siplib.c: Fixed a fundamental problem with the parsing of signatures that allow keyword arguments where the current position in the format string and the var_args was being lost. [afa78322cb2d] 2009-12-19 phil * sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Changed the signature of sipAddException(). Fixed a reference count bug in the handling of chained parse errors. [1e48cd06b448] 2009-12-17 phil * NEWS, sipgen/gencode.c, siplib/sip.h, siplib/siplib.c, sphinx/c_api.rst: Added sipBadCallableArg() to the C API. [4046e5d6ca66] 2009-12-15 phil * sipgen/parser.y: Fixed a NULL dereference when instantiating an unscoped class template. [908f41773044] 2009-12-14 phil * NEWS, sipgen/gencode.c, siplib/sip.h, siplib/siplib.c, sphinx/directives.rst: Added support for sipError to %MethodCode to allow code to distinguish between user errors and system errors. [8cb9ae04484a] 2009-12-12 phil * siplib/siplib.c: Raise an exception if the automatically generated cast function fails (though this, theoretcally, shouldn't happed). Explicitly test for attempting to inherit from more than one wrapped type. [ae6cee8faa67] 2009-12-11 phil * sipgen/gencode.c: Fixed the generation of a bad call to sipMalloc() when generating for a C library. [a174c9456eab] 2009-12-04 phil * sipgen/parser.y: Finally fixed %DefaultEncoding when set in an imported module. [d1eec2d99a95] 2009-12-03 phil * siplib/siplib.c: Fixed a problem where Python wasn't creating descriptors for any enum slots which meant that explicitly calling special methods failed to invoke those slots. [ca934a1f4132] 2009-12-02 phil * NEWS, sipgen/gencode.c, siplib/siplib.c, sphinx/python_api.rst: Use capsules for Python v3.1 and later. Added the sip.voidptr.ascapsule() method. [154f2c63c18d] 2009-11-23 phil * NEWS, sipgen/transform.c: Fixed a bug where assignment helpers may not be generated for classes that have an alternate mapped type implementation. [6734e82522ee] 2009-11-17 phil * siplib/siplib.c: Fixed a problem that meant that circular references in slots connected to objects owned by C++ weren't being detected. [b38add3f63d9] 2009-11-15 phil * sipgen/parser.y: Fixed a bug where %DefaultEncoding could be ignored if %Imports were being done in an inconvenient order. [ae075b6d08ea] * sphinx/command_line.rst, sphinx/distutils.rst: Added the documentation for the updated sipdistutils.py. [c5547730f27b] * lib/sipdistutils.py: An updated sipdistutils.py from Giovanni Bajo. [62a698e9f9bd] 2009-11-14 phil * sipgen/export.c, sipgen/gencode.c, sipgen/sip.h: Signal docstrings no longer include default values as they are implemented as separate overloads. [339a2114ec6d] * NEWS, sipgen/export.c, sipgen/gencode.c, sipgen/sip.h, siplib/sip.h: Docstrings are now generated for use by PyQt4 signals. [18bb2e74f269] 2009-11-11 phil * sipgen/gencode.c: The docstrings are now wrapped with PyDoc_STRVAR(). [ef3374625928] * sipgen/transform.c: The /DocType/ annotation is now properly supported for typedefs. [b3bbd7202a88] * sipgen/gencode.c: No docstrings are generated for any part of a class that isn't the default implementation. [9db19f2694a2] * sipgen/heap.c, sipgen/parser.y, sipgen/transform.c: Added support for /DocType/ to mapped type templates. [74a135153c66] 2009-11-10 phil * NEWS, sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, siplib/siplib.c, sphinx/directives.rst, sphinx/introduction.rst, sphinx/specification_files.rst: Added the %Docstring directive to specify explicit docstrings. [61b4453a9ff4] * sipgen/export.c, sipgen/gencode.c, sipgen/transform.c, siplib/siplib.c: More docstring fixes. Docstrings are not now generated for non- default implementations. [64779347846b] 2009-11-09 phil * NEWS, sipgen/gencode.c: A fix for the formatting of function calls in default values for XML and docstrings. [cfd41d5169d1] * sipgen/export.c, sipgen/parser.y, sipgen/sip.h, sphinx/annotations.rst: Added the /DocValue/ argument annotation. [63dbaa87cf17] * NEWS, sipgen/parser.y: String annotations can now have feature selectors embedded in them. [d8fccc02cc21] 2009-11-08 phil * NEWS, sipgen/export.c, sipgen/gencode.c, sipgen/parser.y: More docstring fixes. [98dc281a1a11] * sphinx/annotations.rst: Updated the docs as /DocType/ is also a function and variable annotation. [cad85d54df79] * sipgen/export.c: Docstrings now consider all C++ integer types to be "int". Docstrings now consider all C++ character types to be "str". [72ae0dd8d9dc] 2009-11-07 phil * sipgen/export.c, sipgen/gencode.c, sipgen/main.c, sipgen/parser.y, sipgen/sip.h, siplib/sip.h, sphinx/annotations.rst: Added the /DocType/ argument and mapped type annotation. More fixes for the docstring support. [99ebe42a8e10] * sipgen/export.c, sipgen/parser.y, sipgen/transform.c: Fixed a bug where a default copy ctor might be added when there aleady was one when the class had a alternative mapped type implementation. [0db8f014b7e7] 2009-11-06 phil * sipgen/export.c, sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c: Completed the basic support for automated docstrings (some tweaking still needed). [3d914379ef28] * sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Added stub docstring support for methods and classes. [b52d1ef306ae] 2009-11-05 phil * sipgen/gencode.c, sipgen/main.c, sipgen/sip.h, siplib/apiversions.c, siplib/sip.h, siplib/siplib.c, sphinx/command_line.rst, sphinx/introduction.rst: Added stubbed support for function docstrings. [91a545605044] 2009-11-04 phil * siplib/siplib.c: Fixed building on Python v2. [af23791238c1] * sipgen/gencode.c: Fixed a memory leak of class instances annotated with /Out/ when catching C++ exceptions. [7fe47a8dd71d] * siplib/siplib.c: Completed the basic extended (ie. without docstrings) error messages on overload parse failures. [fe018c83a8df] * siplib/siplib.c: More support for the extended errors when parsing signatures. [e837961dad1d] * sipgen/gencode.c, sipgen/parser.y, siplib/sip.h, siplib/siplib.c: Fixed a problem where an overload that didn't take keyword arguments wasn't raising an error if one was supplied and there where other overloads that did. [f405b7102d19] 2009-11-03 phil * siplib/siplib.c: Added the error detail for unbound methods. Ctor errors now don't include the module name (to match other errors). [b176dda5f1e9] * siplib/sip.h, siplib/siplib.c: Refactored the new error reporting so that it is much more lightweight in the common case of failure to parse an overload. [e801eb8ce7e6] * sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: The SIP API major version number has changed. Implemented the basics of the revised error messages (still missing the message detail though). [aa4e0e8fd705] 2009-11-02 phil * sphinx/directives.rst: Fixed a broken Sphinx directive. [fc0975814576] 2009-10-30 phil * NEWS, sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sphinx/annotations.rst, sphinx/directives.rst: Added the /Default/ exception annotation to specify an exception that will be caught if there is no throw clause. A 'catch (...)' block will now always be generated. [d65ec4986067] * siplib/siplib.c: Fixed a regression in the monkey patching of instances. [94348861afba] * sphinx/directives.rst: ...and another. [f90c80feb177] * sphinx/directives.rst: ...and another documentation typo. [c3a7ea01b1e5] * sphinx/directives.rst: Fixed a documentation typo. [80259f3cc2f5] * sipgen/gencode.c: Fixed a double delete bug with mapped types passed as references annotated with /Out/. [a788f308bbee] 2009-10-28 phil * NEWS, lib/configure.py, lib/siputils.py, sphinx/build_system.rst: Adde support for out-of-tree building. [837ce5451585] * lib/siputils.py, sipgen/gencode.c, sipgen/main.c, sipgen/parser.y, sipgen/sip.h, sphinx/build_system.rst, sphinx/c_api.rst, sphinx/command_line.rst, sphinx/directives.rst: Added support for building with "protected" redefined as "public" to reduce the size of generated modules. [6601a9a55993] 2009-10-26 phil * siplib/siplib.c: sipFindType() now handles references as well as pointers. [2228a1ad7d3f] * specs/linux-arm-g++, specs/linux-arm-thumb-g++, specs/linux- armv6-g++: Added the Linux ARM spec files from David Boddie's PyQt embedded patch set. [9285dfaea8a2] * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h: More keyword argument bug fixing. (PyQt now seems to work with it enabled.) [d2f15ccd7460] * sipgen/gencode.c: More keyword argument bug fixing. (PyQt now builds again.) [709ea5c81d46] 2009-10-25 phil * siplib/siplib.c: Bug fixing the keyword argument support. [9f8d9cc3f521] * sipgen/gencode.c, sipgen/main.c, sipgen/parser.y, sipgen/sip.h, siplib/sip.h, siplib/siplib.c, sphinx/annotations.rst, sphinx/command_line.rst, sphinx/introduction.rst: Added support for (optional) keyword arguments - untested. [04504a7b338b] 2009-10-24 phil * NEWS, sipgen/gencode.c, siplib/siplib.c: Merged v4.9.1 back into the trunk. [8e50e7601287] 2009-09-26 phil * NEWS: Released as v4.9. [4d26f5a2ec9c] [4.9] 2009-09-19 phil * lib/siputils.py: Fixed the dependency order of Qt libraries on Windows (which weems to only affect MinGW). [b3b353012242] 2009-09-16 phil * lib/configure.py: Fixed a configure.py command line parsing problem on OS/X. [26287bd85bfd] * lib/siputils.py, sphinx/build_system.rst: The default build system values of universal and arch are now taken from the configuration. [33fab9918a24] * NEWS, siplib/siplib.c, sphinx/python_api.rst: Added sip.ispyowned(). [ad556c1da3a4] 2009-09-15 phil * lib/siputils.py: A fix for the last fix. [de0e5576ac75] * lib/siputils.py: More fixes for Snow Leopard. [64601a49b403] 2009-09-14 phil * NEWS, sipgen/gencode.c, sipgen/parser.y, siplib/siplib.c, sphinx/annotations.rst: Allowed the /NoArgParser/ annotation to be used for class methods. [e5ec799a3f70] 2009-09-12 phil * sipgen/gencode.c: Fixed a problem when a function returns a class instance that SIP doesn't think can be copied. [bf71880486d0] * lib/configure.py, lib/siputils.py, sphinx/build_system.rst, sphinx/installation.rst: The --arch option now only implies a universal binary if it is specified more than once. [8c16580e8c21] * lib/configure.py, lib/siputils.py, sphinx/build_system.rst: Added support for specifying a MacOS architecture when creating a wrapper script. [8eeb8a1947b7] 2009-09-11 phil * lib/configure.py: The MacOS specific configure.py options are no longer enabled on other platforms. [2dd928167cd9] * lib/configure.py, sphinx/installation.rst: Removed the -a short form of --arch so that it will be the same as PyQt. [239f8861bc8e] * NEWS, lib/configure.py, lib/siputils.py, sphinx/build_system.rst, sphinx/installation.rst: Added the --arch flag to configure.py to allow the architectures to be included in a MacOS/X universal binary to be specified. [b74bcfcb34b0] * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c: Fixed a problem with the name of an API version in modules that sub- class from classes with versioned methods in a different module. [5b327c45a283] 2009-09-06 phil * siplib/siplib.c: Added the support for handling keyword arguments to QObject ctors. [562b8ecd5e55] 2009-09-04 phil * NEWS, sipgen/gencode.c, siplib/sip.h, siplib/siplib.c, sphinx/annotations.rst, sphinx/c_api.rst: Completed the support for /Array/ applied to classes and mapped types. [f32ceb5cb246] * sipgen/gencode.c, sipgen/sip.h, siplib/siplib.c: Added support for /Array/ for classes and mapped types for non- virtual functions. [24bcbdbd0393] 2009-09-03 phil * sipgen/gencode.c, sipgen/transform.c, siplib/sip.h: Added the extended assignment helper and the array allocation helper for the future support of /Array/ for classes and mapped types. [61cf6b3635ab] 2009-09-01 phil * NEWS, build.py, lib/LICENSE-GPL2.txt, lib/LICENSE-GPL3.txt, lib/LICENSE.short, sphinx/introduction.rst: Added the GPL as a licensing option. [1d372e99f512] * NEWS, sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, siplib/sip.h, siplib/siplib.c, sphinx/specification_files.rst: Added support for __iter__ and __next__. [d6cd069a434f] 2009-08-21 phil * sipgen/parser.y, sipgen/sip.h, sipgen/transform.c: Added a check for recursive class hierarchies. Fixed the error message about type2string() by making sure it handles structs. [7af2d9cb07f8] 2009-08-11 phil * siplib/siplib.c: Fixed sipIsPyMethod() to not use PyObject_GetAttr() so that reimplementations defined in mixins will be found. This was a regression introduced when attribute lookup was made less lazy when getting super() to work properly. [710a488b84b4] * siplib/siplib.c: Fixed the conversion of strings to wchar_t arrays as it was using calls that appeared in Python v2.6. [47cc56c95614] 2009-08-08 phil * siplib/siplib.c: sipFindType() will now find types given as a pointer. [b693f15869c8] 2009-08-06 phil * lib/sipdistutils.py: Fixed sipdistutils.py for Python v3. [4574e78f607f] 2009-08-05 phil * siplib/apiversions.c, siplib/sip.h, siplib/siplib.c: Fixes for looking up types when some times have no implementation for all API versions. [e77c51f40fe0] 2009-08-04 phil * sipgen/transform.c: No longer complain about methods having the same Python signature if they all are versioned. [076cbeaeb3ad] * sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Init extenders now respect API version numbers. [4efa4f7f246b] 2009-08-03 phil * sipgen/gencode.c, sipgen/transform.c: Virtual methods now support API versions. [8ec049505369] * sipgen/gencode.c, sipgen/parser.y, sphinx/annotations.rst: Added support for the /API/ annotation to all overloaded methods. [fae5b6dd29d0] * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, sphinx/annotations.rst: The /API/ annotation is now supported for ctors. [a24c25aede8d] 2009-08-02 phil * sipgen/gencode.c, sipgen/parser.y, siplib/siplib.c: Instantiated class templates now take their API from the scoping class. [39bf3e3fc6de] 2009-08-01 phil * sipgen/gencode.c, sipgen/transform.c: Operator casts and global slots now handle classes with alternate mapped type implementations. (In a limited way, but good enough for PyQt.) [c2ed8e5bbf11] 2009-07-29 phil * siplib/siplib.c: Fixed a crash with sipFindType() when the search happens to land on an unresolved external type. [ec4838cbf038] * siplib/siplib.c: Fixed the Python v3 buffer interface for sip.voidptr. [4f800839bd44] 2009-07-25 phil * sipgen/gencode.c, siplib/sip.h, siplib/siplib.c, sphinx/annotations.rst, sphinx/command_line.rst, sphinx/specification_files.rst: Fixed the '/' operator for Python v3 and future import for Python v2. [fe62bcd81fa3] 2009-07-18 phil * sipgen/transform.c, sphinx/python_api.rst: Fixed a typo in a couple of error messages. [c7eb3170f527] 2009-07-09 phil * siplib/siplib.c: Fixed the nb_index initialiser for sip.voidptr for Python v2.4 and earler. [672b898935b5] * siplib/siplib.c: Allow the meta-type to be used with with ordinary Python classes, not just SIP generated classes. [6f724709902c] 2009-07-08 phil * sipgen/gencode.c: Complete the support for mapped type static methods. [f1cf7ebed748] 2009-07-07 phil * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c: Safety commit of (mostly complete) support for static functions in mapped types. [58aa805c1867] * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sphinx/annotations.rst: Extended the use of /AllowNone/ to classes with %ConvertToType code. [102fc846396e] 2009-07-06 phil * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, siplib/sip.h, siplib/siplib.c, sphinx/annotations.rst: Added the /AllowNone/ mapped type annotation for mapped types that want to place a special interpretation on None. [d449e525c5e8] * sipgen/gencode.c: The generated virtual handler code is now the same for classes and for mapped types that might have an alternate class implementation. [60ce12a7d248] * sipgen/gencode.c, siplib/siplib.c: Make sure mapped types honour the /Constrained/ annotation. [0a8916fbe3b2] 2009-07-05 phil * siplib/apiversions.c, siplib/siplib.c: Debugged mapped types with namespaces. [1f55210a89de] * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, siplib/descriptors.c, siplib/sip.h, siplib/sipint.h, siplib/siplib.c: Safety checkin on the run-time support for mapped types with namespaces. [ec7ba808f36c] 2009-06-29 phil * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c: Finished the code generation support for enums in mapped types. (Runtime support still to do.) [552a2d4950a1] 2009-06-28 phil * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c: Safety commit of the support for mapped types containing enums. [d94e09ea5add] * sipgen/gencode.c, sipgen/parser.y, siplib/sip.h, siplib/siplib.c: Implemented the sipContainerDef in anticipation of mapped types supporting enums (for the moment, static methods and variables at a later date). Fixed a problem where API version ranges wheren't being reused. [28f8f2aa4bcf] * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/apiversions.c, siplib/sip.h, siplib/sipint.h, siplib/siplib.c: Fixed a problem with enums in a type with alternate APIs. [e320f9cb7d19] 2009-06-27 phil * lib/siputils.py: Added a workaround to the build system when using virtualenv on MacOS. [ff5b09d449d5] 2009-06-25 phil * sipgen/gencode.c, siplib/siplib.c, sphinx/c_api.rst: A Python string object can now be provided when a wide character (wchar_t) is expected. [5a629389629b] 2009-06-23 phil * sipgen/gencode.c, siplib/siplib.c: Some fixes for generated code for mapped types and classes not being as completely interchangeable as needed. (Still more to do.) [438a66e8e0a4] 2009-06-22 phil * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c: Bug fixes to the multi-API type support - PyQt4 now builds again. [795308460def] * siplib/apiversions.c, sphinx/annotations.rst: Completed the run-time support for multi-API types. [8888d5cd3feb] 2009-06-21 phil * sipgen/gencode.c: Completed the code generation changes for multi-API types. [439a95ba643e] * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c: More refactoring in preparation for multi-API support for types. [a9c3de1478d8] * sipgen/gencode.c: More changes to the multi-API support for types. [329493ac7802] 2009-06-20 phil * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c: Safety commit of latest changes for support of type API selection. [9443ed19b08b] 2009-06-19 phil * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c: Safety commit of parser changes to get at the API version of a class before it is defined. [c209ce56ea4d] 2009-06-18 phil * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, siplib/apiversions.c, siplib/sip.h, siplib/sipint.h, siplib/siplib.c, sphinx/annotations.rst: Implemented API selection for global functions. [db777d90f374] 2009-06-17 phil * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/apiversions.c, siplib/sip.h, sphinx/annotations.rst, sphinx/c_api.rst, sphinx/directives.rst, sphinx/using.rst: Completed the documentation for the API support. The %API directive can now be used any number of times in a module. Added the parser support for the API annotation. [9e63d5da36bd] * sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, siplib/apiversions.c, siplib/sip.h, siplib/sipint.h, siplib/siplib.c, sphinx/directives.rst, sphinx/specification_files.rst: Added support for the %API directive. [076c846bb8ca] 2009-06-16 phil * siplib/apiversions.c, siplib/sipint.h, siplib/siplib.c, sphinx/c_api.rst: Implemented sipIsAPIEnabled(). [ade852c2131a] * siplib/apiversions.c: ...and made sure it compiles. [3e8030fe1b76] * siplib/apiversions.c, siplib/sipint.h, siplib/siplib.c, siplib/siplib.sbf, sphinx/python_api.rst, sphinx/using.rst: Fixed the reference count of the sip module in the error path if its initialisation fails. Added the sip.getapi() and sip.setapi() functions. [43c34f1c289a] * NEWS, sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/sip.h, siplib/siplib.c, sphinx/specification_files.rst: Merged v4.8.1 into the trunk. [d1bd8aecab5a] 2009-06-05 phil * NEWS: Released as v4.8. [6e9fb584da32] [4.8] 2009-06-03 phil * build.py: More internal build system fixes. [4f34294143b0] * NEWS, build.py, siplib/descriptors.c, sphinx/Makefile: Fixed a Python v3 portability bug. Fixed the internal build system for Python v2.5. [144adbee9ea0] 2009-06-02 phil * build.py, doc/sipref.txt, sphinx/conf.py, sphinx/extensions/siproles.py: Switched to the Sphinx documentation. [16b6a4f285a6] * sphinx/build_system.rst, sphinx/builtin.rst, sphinx/distutils.rst, sphinx/python_api.rst, sphinx/using.rst: Completed the initial Sphinx docs. [d9202085c430] * sphinx/c_api.rst, sphinx/embedding.rst, sphinx/python_api.rst, sphinx/using.rst: More Sphinx docs. [f3c5b7d3dcd4] 2009-06-01 phil * sphinx/annotations.rst, sphinx/c_api.rst, sphinx/command_line.rst, sphinx/directives.rst, sphinx/extensions/siproles.py, sphinx/specification_files.rst, sphinx/using.rst: More Sphinx docs. [831112f389a5] * sipgen/transform.c: Fixed a bug where nested templates where having their types resolved (when they should have been left as templates) which then meant that they were being found and were being instantiated again (possibly in a different module). [79d8261912c8] * build.py: Fixed the build system after removing the TODO file. [93ea3b759b5f] 2009-05-31 phil * sphinx/annotations.rst, sphinx/builtin.rst, sphinx/c_api.rst, sphinx/conf.py, sphinx/directives.rst, sphinx/extensions/annotations.py, sphinx/extensions/siproles.py, sphinx/incompatibilities.rst, sphinx/installation.rst: More Sphinx docs. [d28f3153b2f8] * doc/sipref.txt, sphinx/annotations.rst, sphinx/c_api.rst, sphinx/conf.py, sphinx/extensions/annotations.py, sphinx/incompatibilities.rst, sphinx/using.rst: More Sphinx docs. [e4dcbba1bd9d] 2009-05-30 phil * sphinx/build_system.rst, sphinx/conf.py, sphinx/distutils.rst, sphinx/introduction.rst, sphinx/python_api.rst, sphinx/using.rst: Sphinx documentation changes. [62644d47ee77] * TODO, doc/sipref.txt, siplib/siplib.c, sphinx/Makefile, sphinx/annotations.rst, sphinx/build_system.rst, sphinx/builtin.rst, sphinx/c_api.rst, sphinx/command_line.rst, sphinx/conf.py, sphinx/directives.rst, sphinx/distutils.rst, sphinx/embedding.rst, sphinx/incompatibilities.rst, sphinx/index.rst, sphinx/installation.rst, sphinx/introduction.rst, sphinx/python_api.rst, sphinx/specification_files.rst, sphinx/using.rst: Initial commit of the Sphinx documentation. [432d95fdad2f] * sipgen/parser.y, sipgen/transform.c: Reverted the previous fix and fixed the real bug which was that %DefaultEncoding wasn't being inherited properly by modules. [9abeaff1148a] 2009-05-29 phil * sipgen/transform.c: Fixed a bug in comparing virtual handlers that had a char* result or argument and a default encoding was specified (ie. with Python v3). [3c92e9237373] * sipgen/gencode.c, sipgen/parser.y, siplib/descriptors.c, siplib/qtlib.c, siplib/sip.h, siplib/siplib.c: Eliminated more warning messages. [a61fb0a096f2] * sipgen/gencode.c, siplib/sip.h: Eliminated some compiler warning messages - particularly for Python v2.4. [374f079e7228] 2009-05-28 phil * sipgen/gencode.c: Removed a compiler warning for the generated calls to PyInit_Module() for Python v2.5 and v2.6. [dc93a8fa4a5b] 2009-05-27 phil * sipgen/gencode.c: The implicit copying of const& results is disabled for abstract classes. [705fc12e2144] 2009-05-26 phil * sipgen/gencode.c: Fixed the generated code for abstract operators. [c56cc92b0917] * siplib/siplib.c: Added the missing initialisation of the sipVariableDescr_Type type. [2c0779527ed3] 2009-05-25 phil * NEWS, doc/sipref.txt, sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, siplib/sip.h, siplib/siplib.c: __bool__ is now synonymous with __nonzero__. __truediv__ and __itruediv__ are now explicit. __div__ and __idiv__ are now Python v2 only. Added support for __floordiv__, __ifloordiv__ and __index__. [537579d9318e] * sipgen/parser.y: Hopefully fixed the regression with specific mapped types not properly superceding template mapped types that was affecting PyKDE3 and PyKDE4. [25a665370099] 2009-05-24 phil * siplib/descriptors.c, siplib/sipint.h: Added a repr() method to sip.methoddescriptor. [149f6c3f12a5] * sipgen/transform.c: Fixed a bug where the name of an automatically generated complementary slot wasn't being generated. [0f304e850331] * sipgen/export.c: Added support for images in the generated Scintilla API files from a patch from Detlev Offenbach. [83966cc9950a] 2009-04-30 phil * doc/sipref.txt, sipgen/transform.c, siplib/qtlib.c: %DefaultSupertype now only changes the default for the current module. (%DefaultMetatype still affects importing modules.) This should mean that modules that extend PyQt4 will continue to work without having to make super-type or meta-type changes. [5fc24c675796] 2009-04-24 phil * siplib/siplib.c: Fixed the lookup of generated slot functions in sub-types. Moved some assertions to more appropriate places when a generated slot function isn't found. [5b59bd703dff] 2009-04-20 phil * sipgen/gencode.c, sipgen/sip.h, sipgen/transform.c: Disabled the new implicit copying of const reference results where the class doesn't have a public copy ctor. [70cd90b1d5b9] 2009-04-18 phil * siplib/siplib.c: Fixed a problem handling __setitem__ when being used to support multi-dimensional mappings. [705be62a3cd0] 2009-04-09 phil * siplib/siplib.c: Print any exception raised by __dtor__. [0d56ac42feac] 2009-04-01 phil * sipgen/gencode.c, sipgen/sip.h, siplib/sip.h, siplib/siplib.c: Added support for PyQt4's support for signals that have overloaded methods. [c0ad968503e4] 2009-03-30 phil * sipgen/gencode.c: Fixed a compiler warning message if sipCpp isn't used by %BIGetBufferCode. [26269a7e86f4] * sipgen/gencode.c, siplib/siplib.c: Fixed the declaration of the module initialisation function when building static modules for Python v3. [6f48c809c90b] 2009-03-27 phil * siplib/siplib.c: Fixed a couple of missing calls to clear the error flag while parsing strings. [2275585e4c08] 2009-03-26 phil * NEWS, doc/sipref.txt, sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/sip.h, siplib/siplib.c: Replaced the new /Byte/ annotation with the even newer /Encoding/ annotation and %DefaultEncoding directive. [7c648d9cdd13] 2009-03-24 phil * sipgen/gencode.c: Changed the order in which PyQt4 signals are generated so that those with optional arguments appear with the most arguments first and least last. [4d0b9c852cf8] 2009-03-23 phil * doc/sipref.txt, sipgen/gencode.c: Backed out the removal of sipSelfWasArg and supporting code as it really is needed. However, changed how it was set so that super() should still work. [29d1813e4566] 2009-03-21 phil * sipgen/gencode.c: Fixed a bug in the code generated for protected methods with multiple Python names. [7aa8d62ddf7c] 2009-03-20 phil * siplib/siplib.c: Bytes and the buffer protocol are now also supported for non-byte char and char * (howver the buffer protocol support seems to be broken). [1c5b994cd2d6] * NEWS, doc/sipref.txt, sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/descriptors.c, siplib/sip.h, siplib/siplib.c: Many changes to the wrapping of strings for Python v3 so that char and char * (unless the /Byte/ annotation is specified) are handled as Unicode rather than bytes. Such strings must be able to be encoded as Latin-1. Related to the above, the generated code is much more careful than it used to be about keeping Python string objects alive while their data is being used. [49cf3c9e7b69] 2009-03-18 phil * sipgen/gencode.c: Fixed a long-standing bug in the handling of the /NoArgParser/ annotation that only came to light with Python v3. [2c44dd616d6d] * sipgen/gencode.c, sipgen/parser.y, sipgen/transform.c: More fixes for consolidated modules. Python v2 and v3 should now be working. [b966b1df2bb1] 2009-03-17 phil * sipgen/gencode.c, sipgen/transform.c: Some fixes for consolidated module support for both Python v2 and v3. [b17d4cdf4709] * lib/siputils.py: Tweaked the build system to make it easier for Makefile sub-classes to add commands to targets. [abe3ecd83256] 2009-03-16 phil * doc/sipref.txt, sipgen/gencode.c: Fixed a bug in generating Python v3 consolidated modules. [8fc22b7be6fd] * siplib/siplib.c: Fixed a typo that broke the build of the sip module for Python v2. [348b333af022] 2009-03-15 phil * siplib/sip.h: Tweaks to the Python portability macros. [c1f795ce8a5a] * siplib/sip.h: More Python portability macros. [b3d39099f350] 2009-03-14 phil * lib/configure.py: Fixed a Mac build regression handling the location of the SDK. [2c8cf43905e1] * siplib/sip.h: Added some more Python porting macros. [c046cc5bb268] * lib/siputils.py: Removed a remaining Python v2 specific call from the build system. [c1527c576e1d] * NEWS, sipgen/gencode.c, siplib/sip.h: The generated code now supports Python v3. [c60f38353478] * siplib/siplib.c: The sip module can now be imported by Python v3. [a8bd1e5a5a4b] 2009-03-13 phil * doc/sipref.txt, siplib/siplib.c: Ported the PyString_ calls in the sip module to Python v3. [337e7e627054] * sipgen/gencode.c: Updated the generated module initialisation code for Python v3 - but not for consolidated modules yet. [985c336dd059] * sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Moved to PyLong_* for Python v3. [a1d1a376920b] 2009-03-12 phil * lib/siputils.py, sipgen/gencode.c, siplib/objmap.c, siplib/qtlib.c, siplib/sip.h, siplib/siplib.c: More porting of the sip module. It now compiles but still calls Python v2 functions. [9f4570a090e1] * NEWS, doc/sipref.txt, sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, siplib/descriptors.c, siplib/sip.h, siplib/siplib.c: Partially ported the sip module to Python v3. Added the %BIGetBufferCode and %BIReleaseBufferCode directives to support the buffer interface of Python v3. [0631013fd5ae] 2009-03-11 phil * doc/sipref.txt, lib/configure.py, lib/siputils.py: configure.py now uses optparse. configure.py and the build system will now run under Python3. [89bbb0b49865] * siplib/siplib.c: Implemented __dict__ for sipsimplewrapper. [cf1c9edeb56a] * sipgen/gencode.c, siplib/sip.h: Added the SIP_PYMETHODDEF_CAST compatibility macro for Python v2.4 and earlier. [43e5b0afa42d] 2009-03-10 phil * sipgen/gencode.c: Changed the code generated for variable getters so that a copy is only returned if the variable is const. [22c2ae7bdc37] 2009-03-09 phil * sipgen/gencode.c: Changed the generation of the string pool to get around MSVC's limitation on the size of a string. [e15683c4034a] * NEWS: Updated the NEWS file. [262f29053a78] * sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Made sure all generated code doesn't break strict aliasing. [ae62345de148] * sipgen/gencode.c: SIP now automatically copies objects when they are returned as a const reference. [3d0c7011cb93] * doc/sipref.txt, sipgen/gencode.c, sipgen/sip.h, sipgen/transform.c: A further fix to the order in which modules have their types resolved. [d7ebeff5a7ce] 2009-03-06 phil * lib/siputils.py: Taught the build system about the QtScriptTools module. [6c0d66e4ef0b] * sipgen/transform.c: Fixed a bug where types were being resolved in outer modules before inner modules. This meant that template-based types created on the fly might be created in the wrong module. [cd2a99e505be] 2009-03-05 phil * lib/siputils.py: Taught the build system about the new dependency of QtXmlPatterns on QtNetwork. [50a9e41802c2] 2009-03-04 phil * siplib/siplib.c: Fixes for the updated method cache. [d82c3be07e1b] * sipgen/gencode.c, siplib/qtlib.c, siplib/sip.h, siplib/siplib.c: Greatly simplified the virtual reimplementation method cache now that attribute lookup has been cleaned up. [0cc40f47e6d5] 2009-03-03 phil * NEWS, doc/sipref.txt, sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, siplib/sip.h, siplib/siplib.c: Implemented the /KeepReference/ argument annotation. [c8e2e1961f50] 2009-02-27 phil * doc/sipref.txt, sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Added sipCanConvertToEnum() to the public API. [2748f0bbb0ab] 2009-02-26 phil * siplib/sipint.h, siplib/siplib.c: Removed the __dict__ getter as it is no longer needed. Changed the declaration of the descriptors as they don't need to be exported. [ddd2710b42fd] 2009-02-25 phil * NEWS, doc/sipref.txt, siplib/sip.h, siplib/siplib.c: Reverted to using type's and object's attribute getters and setters now that we populate the type dictionary of a generated type with all its lazy attributes in one go. Changed how an external attributer getter works now that it only needs to populate the type dictionary. [8a22253728be] * sipgen/gencode.c, siplib/siplib.c: Safety checking of the working (but still to be changed) attribute lookup code. [d7244d817b9f] * sipgen/gencode.c, siplib/descriptors.c, siplib/sip.h, siplib/siplib.c: Refactored the support for setting instance variables. [cc8a22386009] * sipgen/gencode.c, sipgen/parser.y, siplib/descriptors.c, siplib/sip.h, siplib/sipint.h, siplib/siplib.c: The refactored support for getting variables now works. [c3e7dc58b020] 2009-02-24 phil * sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Safety commit of refactored wrapping of class variables. [fa8ba6ef243b] 2009-02-23 phil * siplib/siplib.c: Fixed the problem with looking up external lazy attributes - wrapped variables are the only thing not working. [ab3e207d555b] * siplib/descriptors.c, siplib/sip.h, siplib/sipint.h, siplib/siplib.c, siplib/siplib.sbf: Safety commit of new attribute lookup code. Don't use this - it's broken. [2673bc2add5c] * siplib/siplib.c: Fixed a reference count leak when an external lazy attribute was a descriptor. [1047169d1ba8] * siplib/siplib.c: Fixed a crash when accessing a wrapped instance variable as a class variable. [e922b386c5aa] 2009-02-22 phil * siplib/siplib.c: Fixed a bug in the refactored attribute lookup. [ddad97af22ec] * doc/sipref.txt, sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Completed the support for the lazy attribute lookup hook. [1f7bc8f488a8] 2009-02-21 phil * sipgen/gencode.c, siplib/sip.h, siplib/sipint.h, siplib/siplib.c: Added initial support for registering lazy attribute getters. [9aae0eb78368] * sipgen/export.c, sipgen/gencode.c: The PyQt4 signal table is now generated. The XML export now marks the default signal. [dbf0c7f47b6b] 2009-02-20 phil * lib/LICENSE, sipgen/gencode.c, siplib/sip.h: Added the stub of signal table for PyQt4. [f53134503038] 2009-02-16 phil * siplib/sip.h, siplib/siplib.c: Removed some compiler warnings. [a3c24034045a] 2009-02-14 phil * sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: More signal/slot refactoring fixes. [e1c0b895f0d1] * sipgen/gencode.c, siplib/qtlib.c, siplib/sip.h: Debugged the signal/slot refactoring. [a4a47ea6fd1e] * doc/sipref.txt, sipgen/gencode.c, siplib/qtlib.c, siplib/sip.h, siplib/sipint.h, siplib/siplib.c: Safety commit of latest signal/slot refactoring. [751cebc544cc] 2009-02-13 phil * siplib/qtlib.c, siplib/siplib.c: Fixed a build problem with Python 2.4.x and earlier. [df846f30a329] * sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/siplib.c: PyQt3 signal support is now enabled with the %Plugin directive instead of %SIPOptions. Removed %SIPOptions. [d511ad00cc71] * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/sip.h, siplib/siplib.c: The generated typedefs table is now sorted. [abd1a7d60330] 2009-02-12 phil * siplib/siplib.c: An unconstrained enum can now be a sub-class of int. [60366594aa80] 2009-02-11 phil * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, siplib/sip.h: Renamed TypeFlags to PyQt4Flags. Renamed NoQMetaObject to PyQt4NoQMetaObject. Moved the type flags into the PyQt4-specific type structure. [259fceeadbbe] * sipgen/gencode.c, sipgen/sip.h, sipgen/transform.c: Removed the registration of wrapped types with the Qt meta-type system as it is no longer needed by PyQt4. [71f80e789732] 2009-02-07 phil * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/qtlib.c, siplib/sip.h, siplib/siplib.c: Removed sipAssignType() and moved the helpers to the PyQt4 plugin. [305f07cd3ce2] 2009-02-02 phil * sipgen/gencode.c, siplib/qtlib.c: The QObject.sender() support is now PyQt3 only again. [e732e65c15b5] 2009-02-01 phil * sipgen/gencode.c, siplib/siplib.c: Fixed a bug in the generation of the sipParseArgs() sub-format character for types. [fadc9f7074f1] * sipgen/gencode.c, siplib/qtlib.c, siplib/sip.h: Changed the QObject::sender() support for PyQt4. [9d6d9918bb1f] * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c: Debugged the merged types table. [cf4e643c28b5] 2009-01-31 phil * sipgen/gencode.c, sipgen/heap.c, sipgen/sip.h, sipgen/transform.c, siplib/sip.h, siplib/siplib.c: Safety commit of the merge of the class, mapped types and enum tables. [33a1dbf992df] 2009-01-30 phil * siplib/sip.h, siplib/siplib.c: Wrapped classes are now created as they are needed and not in the order they appear in the generated class table. Therefore the class, mapped type and enum tables can now be merged and ordered by the type name (and searched using a binary search). [4a72c9cee88f] 2009-01-29 phil * sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Moved the last of the type parsing to PyQt3. [b7d7695e3d8e] * sipgen/gencode.c, siplib/qtlib.c, siplib/sip.h, siplib/siplib.c: Moved the registering of int types to PyQt4. [e63f85d857bd] 2009-01-28 phil * doc/sipref.txt, sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Refactored the support for looking up typedefs. [42851fe9a2cb] * sipgen/gencode.c, siplib/qtlib.c, siplib/sip.h, siplib/sipint.h, siplib/siplib.c: Moved the type parsing support to PyQt3. [531e8244cfd3] 2009-01-27 phil * sipgen/gencode.c: Removed a remaining call to sipReleaseMappedType(). [2a9cbf86c86a] 2009-01-25 phil * sipgen/gencode.c: Fixed a too-few-arguments-to-a-print bug in the code generator. [1260503c2021] * siplib/siplib.c: Fixed compilation issues. [635ffd53597b] 2009-01-18 phil * sipgen/gencode.c, siplib/qtlib.c, siplib/sip.h, siplib/sipint.h: Replaced sipFindConnection() with sipFindSlot(). [30f0174c05f4] 2009-01-13 phil * sipgen/gencode.c, siplib/qtlib.c, siplib/sip.h, siplib/sipint.h, siplib/siplib.c: Replaced sipFreeSignature() with sipFreeSipslot(). [e5275f031458] 2009-01-12 phil * sipgen/gencode.c, siplib/qtlib.c, siplib/sip.h, siplib/sipint.h, siplib/siplib.c: Pushed the parsing of signatures into PyQt. [b2e616d5c92f] 2009-01-11 phil * sipgen/gencode.c, siplib/qtlib.c, siplib/sip.h, siplib/sipint.h, siplib/siplib.c: Replaced sipConvertRx() with sipConvertRxEx(). [cc0e4fe70f50] 2009-01-10 phil * sipgen/gencode.c: Removed the generation of an old Qt API entry. [30f044ed1723] 2009-01-09 phil * sipgen/gencode.c, siplib/qtlib.c, siplib/sip.h: Safety commit of partial refactoring of the Qt signal support. [429673b02dcd] 2009-01-04 phil * lib/LICENSE, lib/LICENSE.short, sipgen/gencode.c: Don't import the qt_register_type symbol if it isn't needed. Updated copyright notices. [f2dbc98f7144] 2008-12-30 phil * doc/sipref.txt, siplib/sip.h, siplib/siplib.c: sipTypeFromPyTypeObject() now takes a PyTypeObject* rather than a PyObject*. [077c2ad4451f] * doc/sipref.txt, sipgen/gencode.c, siplib/objmap.c, siplib/sip.h, siplib/sipint.h, siplib/siplib.c, siplib/threads.c: Added sipTypeName() and sipTypeScope() to the public SIP API. [701c6915d3e3] 2008-12-29 phil * doc/sipref.txt, sipgen/gencode.c, sipgen/parser.y, siplib/sip.h, siplib/sipint.h, siplib/siplib.c: Migrated sipEnum_* to sipType_*. [e0417099f5a9] 2008-12-27 phil * doc/sipref.txt, sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: sipType_* are now generated for enums. These are used internally but the SIP API has not yet been changed. [ca45e1d31af2] * sipgen/gencode.c, siplib/qtlib.c, siplib/sip.h, siplib/siplib.c: Broke out the generated type structures for mapped and class types to different structures with a common header. [ff4bec0abd37] 2008-12-26 phil * siplib/siplib.c: Wrapped enums now have their own meta-type. This is the hook that will allow the C++ name of an enum to be derived from the enum's Python type object. [ea550b12904c] 2008-12-24 phil * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, siplib/sip.h, siplib/siplib.c: Added sip_api_init_module() to make sure dependent modules can be fully initialised before they are needed. [fed394659169] * sipgen/gencode.c, siplib/sip.h: Removed the Qt meta-type id from the pyqt4TypeDef structure as we want to use it for mapped types as well but we would never know when it was safe to cast from a sipTypeDef pointer. [92c012de8c02] 2008-12-21 phil * sipgen/gencode.c: The PyQt4-specific extension to the generated type structure is now used for mapped types as well. [f49b6d447292] 2008-12-20 phil * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/sip.h, siplib/siplib.c: Changed the PyQt4-specifc handling of Qt meta-type registration. [d112840accfd] * sipgen/gencode.c, siplib/siplib.c: A generated type structure now has its Python type object set earlier so that sub-meta-types can use sipIsExactWrappedType(). Calls to QObject::metaObject() are no longer need to trigger the creation of the meta-object. [8d816e1f3008] * doc/sipref.txt, sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, siplib/sip.h: Added %Plugin and use it to support pyqt4TypeDef. [0f236470d582] 2008-12-19 phil * siplib/sip.h: Moved the qt_qobject member out of sipWrapperType and into PyQt where it belongs. [babe6a91d801] * sipgen/gencode.c, siplib/siplib.c: Completed the migration of sipClass_* to sipType_*. [e7c00163d819] * doc/sipref.txt: Documentation updates. All uses of sipClass_* are only by deprecated parts of the API. [cfa2b5ca880e] * doc/sipref.txt, sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Deprecated the 'B' and 'C' format characters to sipBuildResult() and sipCallMethod(). Added the new 'N' format character to sipBuildResult() and sipCallMethod(). [d685f1b18287] 2008-12-17 phil * doc/sipref.txt, sipgen/gencode.c, siplib/siplib.c: Deprecated the 'C' format character of sipParseResult() in favor of the existing 'D' character. [be1f044d9828] * doc/sipref.txt, sipgen/gencode.c, siplib/qtlib.c, siplib/sip.h, siplib/siplib.c: Migrated the sub-class convertor code to using sipType rather than sipClass. [a4424a9ac5a5] 2008-12-16 phil * sipgen/transform.c: Fixed a bug where names of mapped type templates where being generated for modules that didn't need them. [176171583343] 2008-12-14 phil * doc/sipref.txt, sipgen/gencode.c, siplib/qtlib.c, siplib/sip.h, siplib/sipint.h, siplib/siplib.c: Replaced the deprecated sipConvertFromInstance() and sipConvertFromNewInstance() with sipConvertFromType() and sipConvertFromNewType(). [6f6e06ceaace] * doc/sipref.txt, sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Replaced the deprecated sipForceConvertToInstance() and sipForceConvertToMappedType() with sipForceConvertToType(). [fc54ee3b5308] * doc/sipref.txt, sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Replaced the deprecated sipConvertToInstance() and sipConvertToMappedType() with sipConvertToType(). [8e66284398dd] * doc/sipref.txt, sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Replaced the deprecated sipCanConvertToInstance() and sipCanConvertToMappedType() by sipCanConvertToType(). [c1f1b170b263] 2008-12-13 phil * doc/sipref.txt, sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Replaced the deprecated sipReleaseInstance() and sipReleaseMappedType() with sipReleaseType(). [7ce45ed9ae89] * doc/sipref.txt, sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Replaced the deprecated sipGetWrapper() with sipGetPyObject(). [8cb295b72e62] * doc/sipref.txt, sipgen/gencode.c, siplib/objmap.c, siplib/qtlib.c, siplib/sip.h, siplib/sipint.h, siplib/siplib.c: More moves from sipClass_* to sipType_*. [4e7936a90f99] * sipgen/gencode.c, siplib/objmap.c, siplib/sip.h, siplib/sipint.h, siplib/siplib.c: More conversions from sipClass_* to sipType_*. [75eed80555d4] 2008-12-12 phil * sipgen/gencode.c, siplib/sip.h, siplib/sipint.h, siplib/siplib.c, siplib/threads.c: Merged the adding of type instances. [d2db3775a993] 2008-12-08 phil * lib/siputils.py, sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Started the port from sipClass_* to sipType_*. Added support for assert() to the build system. [231826fe6d04] * sipgen/gencode.c: Renamed sipMappedType_* to sipType_*. [8df5a86247e8] 2008-12-07 phil * sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Added sipType_* for wrapped types. sipClass_* is now defined in terms of sipType_*. [bb37272a3113] * doc/sipref.txt, sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Deprecated sipClassName(). [de0402f5112c] * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/sip.h, siplib/siplib.c: Mapped types are now described by the same sipTypeDef structure that describes wrapped types. [77ce210b751e] 2008-12-06 phil * doc/sipref.txt, siplib/sip.h, siplib/siplib.c: Moved the 'user' field from sip.wrapper to sip.simplewrapper because PyQt uses it for some non-QObject types. [0bb916ce4818] * doc/sipref.txt, sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/sip.h, siplib/siplib.c: Restored %DefaultMetatype and the /Metatype/ class annotation. This support is now complete. Documented the meta-type and super-type support. [15f1b60f808f] 2008-12-03 phil * doc/sipref.txt, sipgen/gencode.c, siplib/qtlib.c, siplib/sipint.h, siplib/siplib.c: Code generator changes to support sipSimpleWrapper. [ebd5b0b103ae] * siplib/qtlib.c, siplib/sip.h, siplib/sipint.h, siplib/siplib.c: The sip module now compiles again without any unexpected warnings. [6fb536d5333e] 2008-12-02 phil * siplib/objmap.c, siplib/qtlib.c, siplib/sip.h, siplib/sipint.h, siplib/siplib.c: Various compilation fixes. [ace8e0f95607] 2008-12-01 phil * sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Safety checkin of the support for the new sip.simplewrapper type. [3d87512e3a5c] * NEWS, doc/sipref.txt, siplib/siplib.c: Added support for %InitialisationCode. (Actually in the previous commit but I forgotto mention it.) The text of an attribute exception now mimics that produced by the Python interpreter. [70d0f5dc259b] 2008-11-30 phil * doc/sipref.txt, sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/sip.h, siplib/siplib.c: Refactored the super-type and meta-type support. Meta-types are now handled implicitly. [2676976c88bf] 2008-11-29 phil * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/siplib.c: Debugged the metatype support. [e7e9b5d303c3] 2008-11-27 phil * sipgen/gencode.c, siplib/siplib.c: The metatypes are now registered and readied. [5c4757c83b70] * sipgen/export.c, sipgen/gencode.c, sipgen/parser.y, sipgen/transform.c, siplib/siplib.c: Fixes for various regressions. [eea6dc713727] 2008-11-26 phil * sipgen/gencode.c: Use the string pool for calls to qRegisterMetaType(). [954bd63eb830] * sipgen/gencode.c, sipgen/transform.c, siplib/sip.h, siplib/siplib.c: Completed the code generator support for user defined metatypes. [6c09f41b9eec] 2008-11-24 phil * sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/sip.h: Added the parser support for %Metatype and %DefaultMetatype. [6af8f6a12eb5] 2008-11-23 phil * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c: The string pool now overlaps strings where possible. [4873718f6e82] * sipgen/export.c, sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, siplib/sip.h, siplib/siplib.c: Enum names now use the string pool. [b6414c99a03a] * sipgen/parser.y, siplib/sip.h, siplib/siplib.c: Fixed a regression in the handling of nested namespaces. [a49433be0291] * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/sip.h, siplib/siplib.c: Python and C++ type names now use the string pool. The string pool is currently broken for namespace extenders. [b08a2ca9d7fd] 2008-11-22 phil * doc/sipref.txt, sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/sip.h, siplib/siplib.c: The generated name cache is now a single (const) string. [0296eda5e61a] * doc/sipref.txt, lib/configure.py, lib/siputils.py, sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Removed all deprecated parts of the API and generated code. [0a00c20f5c5b] 2008-11-21 phil * lib/siputils.py: Use "-undefined dynamic_lookup" rather than linking against the Python framework on MacOS. [773c8920c04f] 2008-11-18 phil * doc/sipref.txt, sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Added sipWrapperType_Check() to the public API. [42d9ec7403f4] 2008-11-17 phil * NEWS, sipgen/gencode.c: Merged v4.7.9 into the trunk. [63aff4a6e0f0] 2008-11-08 phil * NEWS, TODO, build.py, doc/default.css, doc/sipref.txt, lib/LICENSE, lib/LICENSE.short, lib/README.HP-UX, lib/THANKS, lib/configure.py, lib/siputils.py, sipgen/export.c, sipgen/gencode.c, sipgen/heap.c, sipgen/lexer.l, sipgen/main.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/objmap.c, siplib/qtlib.c, siplib/sip.h, siplib/sipint.h, siplib/siplib.c, specs/linux-icc, specs/win32-msvc2005, specs/win32-msvc2008: Merged v4.7.8 into the trunk. [9cc6147a1067] 2007-07-30 phil * NEWS: Released as v4.7. [a458d43a6fbb] [4.7] 2007-07-28 phil * sipgen/gencode.c: Fixed a memory leak with mapped types with the /Out/ annotation. [5c156cb3b313] 2007-07-27 phil * siplib/qtlib.c: Fixed a bug preventing wrapped C++ slots from being disconnected. [43fc1981c30d] 2007-07-14 phil * siplib/qtlib.c, siplib/sip.h, siplib/sipint.h, siplib/siplib.c: Rather than only lambda functions being given an extra reference when used as a slot, anything other that a method or wrapped C function is given an extra reference. Specifically this means that partial functions can now be used as slots. [2562db168ce9] 2007-07-04 phil * sipgen/transform.c: Relaxed the restriction that /Out/ arguments couldn't be const. [546fba30aac6] 2007-06-25 phil * sipgen/gencode.c: Fixed a compiler warning message about an unused argument in generated code. [5713835ff863] * sipgen/parser.y: Fixed a bug in the previous fix so that it only applies to mapped types. [68a7fd2c1ea4] * sipgen/parser.y, sipgen/sip.h, sipgen/transform.c: Fixed a bug where template based types where overwriting the header code of any previously defined type based on the same interface file. [f41edc04b3cf] 2007-06-23 phil * NEWS, sipgen/gencode.c: Consolidated modules are now generated as either C or C++ (rather than always C) so that the name cache names are consistently mangled. [83c24c956277] 2007-06-22 phil * lib/siputils.py: Fixed a build system problem for PyQt on Windows against a static Qt. [3ff5f3d1e074] * sipgen/gencode.c: Fixed silly code generation typo. [3232af13c3f6] * lib/siputils.py: Changed the build system so that missing macros default to being empty rather than causing an error. (Qt v4.3.0 contains such a case.) [213c1dd11448] 2007-06-20 phil * doc/sipref.txt, sipgen/gencode.c, sipgen/lexer.l, sipgen/main.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/sip.h, siplib/siplib.c: Split the consolidated module concept into separate consolidated and composite module types, which significantly simplifies things. [eb0502b5bb27] 2007-06-19 phil * lib/siputils.py: Updated some comments in the build system. [f38ba63f0f97] * siplib/siplib.c: Fixed a bug in the sip module consolidated module support. Otherwise everything seems to work. [a9d7eeffdf81] * sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: More consolidated module refactoring. [9c629ca01a4a] 2007-06-18 phil * sipgen/export.c, sipgen/gencode.c, sipgen/main.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c: More consolidated module refactoring. PyQt4 with only QtCore enabled now compiles. [bec649674da2] 2007-06-16 phil * sipgen/gencode.c, sipgen/parser.y: More consolidated module support. [b7455f328486] 2007-06-12 phil * siplib/siplib.c: Hopefully fixed a bug in the handling of the 'C' and 'D' format characters in sipParseResult(). [c28fa1333976] * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c: More refactoring for consolidated module support. SIP no longer generates lots of .h files. Note that SIP is now less tolerant of missing #includes in %TypeHeaderCode and %ModuleHeaderCode. [ae2dec8da410] 2007-06-04 phil * sipgen/gencode.c: Removed the need to generate the shadow class definition in a header file and put it in the original class's C++ file instead. [30cd539612c7] 2007-06-03 phil * sipgen/export.c, sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c: More consolidated module refactoring. [9fbe5340767f] 2007-06-01 phil * sipgen/parser.y: Fixed a missing return in parser.y. [3f160ab4ae5b] 2007-05-28 phil * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c: A bit more consolidated module support. [f714935139bb] * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, siplib/sip.h, siplib/siplib.c: More work on consolidated modules. [bde47f2343cf] 2007-05-27 phil * sipgen/gencode.c, sipgen/sip.h, siplib/sip.h, siplib/siplib.c: The component stub modules (ie. those requested with the -p flag) are now generated. [21119384ab4f] * doc/sipref.txt, sipgen/gencode.c, sipgen/main.c, sipgen/sip.h: Added the stubs of the -n and -p command line options for the remaining consolidated module support. Documented the %ConsolidatedModule directive. [744cf0ed0857] 2007-05-24 phil * sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h: Completed the implementation of %ConsolidatedModule for the simple case (where the consolidated module populates itself from the component modules). [78406f2fdcb4] 2007-05-23 phil * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h: A bit more refactoring for the consolidated module support. [51a36ed46e45] * siplib/objmap.c, siplib/sip.h, siplib/sipint.h, siplib/siplib.c: When deciding if an instance is already wrapped, sip only considers if the candidate is a sub-class of the expected class. (Before it used to consider if the candidate was a super-class of the expected class as well. However this shouldn't be necessary as the candidates class should be correct if all the sub-class convertor code is working properly.) [014d6fb553a9] * sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, siplib/objmap.c: Added the start of the support for %ConsolidatedModule. [2cdafc7810be] 2007-05-20 phil * doc/sipref.txt, siplib/siplib.c: Added the dump() funtion to the sip module. [299d67a0fe51] 2007-05-13 phil * doc/sipref.txt, sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Added sipTransferBreak() for removing hidden references without changing owndership. [5d298052a2e5] * doc/sipref.txt, sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h: Added support for /Transfer/ as a function annotation. [ab6bd827b7a0] 2007-05-12 phil * lib/siputils.py: Added the build system hooks for PyQt's QtScript module. [6fdf6cb0ade1] * sipgen/parser.y: Fixed some parser problems related to versioning. [a4ffe24c61bd] 2007-05-11 phil * sipgen/parser.y: Relaxed the restriction that the arguments to mapped type templates had to be simple names and not basic types. [04d512a7ddee] * sipgen/gencode.c: Generated the sipClass_* for namespaces. [234dfbd619d5] 2007-05-07 phil * sipgen/gencode.c: More fixes to mapped type templates - should be Ok now. [3e7528f5ec18] 2007-05-04 phil * doc/sipref.txt: Fixed a couple of documentation bugs regarding exceptions. [21138bd0e4dd] 2007-05-03 phil * sipgen/transform.c: Fixed a bug where generated .h files for template argument types were being included in the mapped type rather than the mapped type's own .h file. [015e7bc362e3] 2007-04-28 phil * siplib/siplib.c: Removed the need for the copy_reg module. This marks the completion if the pickle support. [855e5b2a3bfc] * sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Pickling nested types now works. [d10779f3268e] * siplib/siplib.c: Minor refactoring of the pickle code prior to adding support for nested classes. [33badbfc5ee1] 2007-04-27 phil * doc/sipref.txt, siplib/siplib.c: Named enums that are nested within other types can now be pickled. (Note that the pickle format for classes will be changed in the next few days to allow nested classes to be pickled in the same way.) [ad31cd17972b] 2007-04-26 phil * siplib/siplib.c: More improvements to the pick code. [7387a6436f4f] * sipgen/gencode.c: Slight improvement to the generated pickle code. [250d4acde794] 2007-04-22 phil * NEWS, doc/sipref.txt, sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/sip.h, siplib/siplib.c: Added %PickleCode to allow wrapped objects to be pickled. [45059aeff1d0] * siplib/siplib.c: Module level enums can now be pickled. Removed the None implementations of __reduce__ and __reduce_ex__ and fixed the segfault that pickling was causing. [960a54bd61d7] 2007-04-10 phil * NEWS: Released as v4.6. [9d849b09a8d4] [4.6] 2007-04-07 phil * sipgen/export.c: Changed the API file generation to generate the __init__ form of a ctor as well as the callable type form. [316e430f8a37] 2007-04-02 phil * NEWS: Updated the NEWS file. [5c6477d8ee0d] * NEWS, doc/sipref.txt, lib/configure.py, lib/siputils.py: Added the -n flag to configure.py to build universal binaries on MacOS/X. [e892f0a63956] * siplib/siplib.c: Fixed a MinGW warning message. [79ac369e6efa] * siplib/siplib.c: Backed out the save and restore of the exception state in sipWrapper_dealloc() as it can get called when there is no current thread state (which results in a segfault). [f66e13ead83b] * NEWS: Updated the NEWS file. [c7488adf6abf] * siplib/siplib.c: Fixed a bug handling sub-class convertor code with multiple inheritance. [8ac3a23e1e3c] * doc/sipref.txt, sipgen/gencode.c: Virtuals that return a wchar_t * now keep then free the previous result to limit the possible memory leaks. [48b87ba8bc6a] 2007-04-01 phil * sipgen/gencode.c, sipgen/transform.c: Fixed a bug in the wchar_t support with const wchar_t * arguments. Fixed a bug in the wchar_t support with char and wchar_t being considered equivalent. [541c7556314d] 2007-03-26 phil * siplib/siplib.c: Fixed problem where lambda slots connected to QObject.destroyed() were cleared before the signal was emitted. [2ace696800c4] 2007-03-25 phil * doc/sipref.txt, sipgen/gencode.c: Completed the wchar_t support. [14c15deefc3b] 2007-03-24 phil * sipgen/export.c, sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/qtlib.c, siplib/sip.h, siplib/siplib.c: Added support for wchar_t - undocumented and certainly untested. [14559b49bd9d] 2007-03-10 phil * sipgen/gencode.c, siplib/siplib.c: No longer generate the forward declaration of an opaque class. It shouldn't be necessary and means that the class could be a C structure. [647d2f4b8561] 2007-03-02 phil * sipgen/lexer.l: SIP should now handle DOS format files on UNIX systems. [1935d8be814b] 2007-02-27 phil * doc/sipref.txt, sipgen/gencode.c, sipgen/main.c, sipgen/parser.y, sipgen/sip.h: Undeprecated the -g command line option. Added the /HoldGIL/ annotation. [fbf1aaec1094] 2007-02-25 phil * sipgen/transform.c, siplib/siplib.c: Fixed the previous fix related to signatures for the cases where the Python and C++ signatures have different numbers of arguments. [66f4866a1393] * doc/sipref.txt, siplib/siplib.c: Included Matt Newell's fix for making sure that a sub-class convertor returns the most specific type available. [7b9b628d5c50] 2007-02-24 phil * doc/sipref.txt, sipgen/transform.c: Fixed some documentation references to Py_ssize_t. sip now takes C++ as well as Python signatures into account when deciding what interface files a class need to include. [ac3ecfcc08d3] * doc/sipref.txt, siplib/qtlib.c: Leave it to the Qt support code to release the GIL when connecting signals. [8c907b07ad8f] 2007-02-20 phil * siplib/qtlib.c, siplib/sipint.h, siplib/siplib.c: An instance dictionary is not longer created automatically. Python will create it if and when it is needed. lambda slots are now cleaned up in the clear function rather than being left to the slot proxy dtor. [61eac95ed77e] * siplib/siplib.c: Fixed a bug in the implementation of /Transfer/ when the object was aleady owned by C++ but the owning object had been garbage collected. [4d64b0e0db86] 2007-02-18 phil * siplib/siplib.c: Fixed a bug in the clearing of reference cycles with lambda slots. Although the slot is visited, it is no longer cleared - that is left to the proxy dtor. [aac8236a8970] 2007-02-16 phil * lib/siputils.py, sipgen/gencode.c: Fixed a bug in the build system for QtDesigner on Windows. The Q_OBJECT support code now uses metaObject() rather than staticMetaObject because the latter is private in the ActiveQt classes. [4b8647dbb036] 2007-02-10 phil * doc/sipref.txt, sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/sip.h, siplib/siplib.c: Added support for /TypeFlags/. Added sipFindClass() and sipFindNamedEnum() to the public API. [530b7a1aa547] 2007-02-06 phil * sipgen/gencode.c, siplib/sip.h: More changes to the Q_OBJECT support. [b46c77268a1c] 2007-02-04 phil * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, siplib/sip.h: Renamed "Qt4MetaObject" to "Qt4Q_OBJECT". [9b8809b3f254] 2007-02-01 phil * sipgen/gencode.c: Changed the metaObject() hook so that it won't crash if the C++ instance has gone. [5241cd5c39d3] 2007-01-30 phil * sipgen/gencode.c: Changed the metaObject() hook again. [77da534919cb] * sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Changed the metaObject() hooks. [272f63959180] 2007-01-27 phil * sipgen/gencode.c: Changed the way the Qt support API is created so that new SIPs can build old PyQts. [15c8d8be611d] * NEWS, sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Added the hooks to allow PyQt to build a proper meta-object when a new Python class is defined. [c82c3d1b50aa] 2007-01-25 phil * lib/siputils.py, siplib/qtlib.c: Fixed a build system bug that affected non-MinGW Windows compilers when building static modules. Taught the build system about the QtDesigner module. [0029d3937d59] 2007-01-23 phil * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c: Reimplemented the support for qt_metacall() so that it is a bit cleaner and can't be called from Python. [c3701e916110] 2007-01-22 phil * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, siplib/qtlib.c, siplib/sip.h, siplib/sipint.h, siplib/siplib.c: Added support for the QtMetaClass option. Added sipParseSignature() to the private Qt API. (Both of the above are needed for David Boddie's support for Python widgets in Qt Designer.) [51250dc9185b] 2007-01-21 phil * sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Extended the cyclic garbage collector support for lambda slots so it works with SIGNALs as well as PYSIGNALs. Incremented the SIP API version number to 3.4. [fcf4f2b51bd7] * siplib/qtlib.c, siplib/sip.h, siplib/sipint.h, siplib/siplib.c: Fixed garbage collection support for lambda slots (at the moment only when the slot is connected to a PYSIGNAL). [8bf735cda5bf] 2007-01-16 phil * siplib/sip.h: Added #undef slots to sip.h for when embedding Python 2.3 in Qt applications. [33ab2adb9d0c] * sipgen/gencode.c: qRegisterMetaType() is now called for every candidate class at module initialisation rather than when the first instance is created from Python. [a31d12e3d9c2] 2007-01-15 phil * doc/sipref.txt, sipgen/gencode.c, siplib/siplib.c: Allowed /TransferThis/ to be specified more than once. [e8246e9dc928] * doc/sipref.txt, lib/LICENSE.short, siplib/threads.c: Updated the copyright notices. Fixed a reentrancy problem in wrapping objects obtained from C/C++ (thanks to Giovanni Bajo for the fix). [117d2c42c517] 2007-01-10 phil * siplib/sip.h, siplib/siplib.c: Added support for __truediv__ and __itruediv__ by making them synonyms for __div__ and __idiv__. [1c6e71aeb203] 2007-01-07 phil * sipgen/gencode.c, siplib/siplib.c: Hopefully fixed a bug in the generation of the typedefs table that wasn't using the full name of foreign modules. [a193602041a2] 2006-12-28 phil * siplib/sip.h: Fixed a bug in the sipResetCppHasRef() macro that breaks the /TransferBack/ annotation. [30e9fc168db0] 2006-12-20 phil * lib/siputils.py: Fixed a MacOS specific bug in create_wrapper() in the build system. [34641513890f] * lib/sipdistutils.py: Applied a patch to sipdistutils.py from Giovanni Bajo to allow .sip files to be used in the "depends" argument to setup(). [912613b39701] 2006-12-16 phil * NEWS, lib/siputils.py: Fixed a bug in the build system that meant that lines in the top level mkspec file were being ignored after the last include. [c2ee167686b7] 2006-12-09 phil * lib/siputils.py: Fixed a MacOS build problem caused by another change to Qt installs. [90c588f6fa54] * NEWS, build.py: Updated the NEWS file. Fixed the internal build system for later versions of docutils. [4bcf93b8836e] 2006-12-06 phil * NEWS, siplib/qtlib.c: "PyQt_PyObject" is now used instead of "PyObject *". lamda functions can now be used as slots. [33493621d63e] 2006-11-26 phil * siplib/sip.h, siplib/siplib.c: Fixed an incorrect assumption that if a Python wrapper of a C++ owned object was being garbage collected then its Python children (ie. things it owns) should also be garbage collected. It may be that the parent is a "temporary" object (eg. the argument of a reimplementation of a virtual) but the children are "permanent". The case in PyQt is the parent argument of QAbstractItemDelegate.createEditor(). [b981a814a1b2] 2006-11-25 phil * doc/sipref.txt, sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: PEP 353 fixes from Ulli. [d22c558be4b9] * siplib/qtlib.c, siplib/sip.h, siplib/siplib.c: Some "char *" to "const char *" fixes from Ulli. [208ba44fcddc] 2006-11-18 phil * sipgen/transform.c: Fixed a broken pointer bug in the API file generation. [b80f4ae42e97] 2006-11-17 phil * sipgen/export.c, sipgen/lexer.l: Fixed a misleading error message when instantiating templates. Fixed a bug generating global functions in API files. [6b6804bacc4f] 2006-11-11 phil * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c: Fixed a bug with virtual handlers when a module %Imports from two other (independent) modules. [56ca50343b62] 2006-11-04 phil * NEWS: Released as v4.5. [5982951360f3] [4.5] 2006-10-28 phil * lib/siputils.py: The build system now handles .prl files on MacOS. [25b8444de255] 2006-10-27 phil * NEWS, doc/sipref.txt, sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c: Changed NoDefaultCopyCtor to NoDefaultCtors. Updated the NEWS file. [57307ed6d154] 2006-10-22 phil * doc/sipref.txt, lib/siputils.py, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/qtlib.c: A fix for configuring QtAssistant in PyQt for Qt v4.2 on MacOS. Added the NoDefaultCopyCtor class annotation. [ed57b3a6fd1c] 2006-10-21 phil * doc/sipref.txt, siplib/siplib.c: Fixed a Python 2.4/2.5 change that was missed. Added sip.setdeleted(). [2db4a119d6c6] 2006-10-20 phil * doc/sipref.txt, lib/siputils.py, specs/hurd-g++, specs/solaris-cc: Platform portability fixes from Ulli. Fix for conditional includes in spec files from Ulli. Qt4 module include directories are now searched before the main Qt4 include directory. Handle the change in debug libraries in Qt v4.2. [3f72b2b88460] 2006-10-15 phil * sipgen/parser.y: Allow virtual signals if the NoEmitters option is set. [6657a8d15171] * sipgen/gencode.c, sipgen/sip.h, sipgen/transform.c: Fixed a bug where the first argument to a global comparison operator was mishandled if it was a pointer rather than a reference. [5c5c0d5f6b65] 2006-10-13 phil * siplib/siplib.c: Improved the previous fix for the incorrect ctor exception. [3d9f787fedf8] 2006-10-08 phil * lib/siputils.py, siplib/siplib.c: Fixed bug where handwritten traverse and clear code wasn't being called for derived classes. Fixed an incorrect Python exception raised when a C++ exception is thrown by a ctor. The build system now displayed an error if a non-framework build of Python is used on MacOS. Untested fix for building a static module with MinGW. [9c60ee47e4d5] 2006-10-07 phil * lib/siputils.py: Build system fixes for Qt v4.2.0 based on a patch from Matt Newell. [e7f12b65d105] 2006-09-30 phil * lib/siputils.py: Fixes for building QtTest on Windows. [a8b3716e682a] 2006-09-23 phil * lib/siputils.py, sipgen/parser.y: Taught the build system about QtTest. Fixed a bug in the handling of namespaces split across multiple header files. [89b8c6c6b8c6] * TODO, doc/sipref.txt, siplib/siplib.c: Added support for hooking into the C++ dtor from Python by implementing __dtor__() from a patch by Jean Jacques Lecler. [38da61ef1711] * NEWS, doc/sipref.txt, siplib/siplib.c: Added sip.delete() (based on a patch from Jean Jacques Lecler) and sip.isdeleted(). [8946500be6fa] * doc/sipref.txt, sipgen/export.c, sipgen/main.c, sipgen/sip.h: Removed the -n flag to sip now I think I've decided how to change code completion in QScintilla. [69cb56ba58f1] 2006-09-22 phil * sipgen/parser.y: Backed out the check that abstract methods are virtual - because they don't have to be. [1c753a1e011a] 2006-09-17 phil * doc/sipref.txt, sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c: Added support for pure virtual dtors. Fixed a bug where abstract operators weren't flagging the class as being abstract. [867e6aa1d499] 2006-09-03 phil * sipgen/gencode.c, siplib/siplib.c: Defeated a GCC v4 warning message on generated code. [be5889f172fb] 2006-08-17 phil * sipgen/gencode.c: Minor code generation formatting tidyups. [c4397d6c3aca] * siplib/sip.h, siplib/siplib.c, specs/linux-lsb: Added argument type checking to sipRegisterIntTypes(). [aa1a3cf373d0] 2006-08-16 phil * sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Added sipRegisterIntTypes() to the private Qt support API so that PyQt4 can implement Q_ENUMS and Q_FLAGS. [0909d2f2b376] 2006-08-05 phil * lib/siputils.py: Added support for QAxContainer in the build system. [5ddf72d045fb] 2006-07-19 phil * lib/configure.py, lib/siputils.py, specs/hurd-g++, specs/linux-pgcc, specs/solaris-cc, specs/solaris-cc-64, specs/solaris-g++, specs/solaris-g++-64, specs/win32-icc, specs/win32-msvc, specs/win32-msvc.net, specs/win32-msvc2005: Updated the spec files from Qt v4.1.4. Added (completely untested) support for embedding manifests for MSVC v8. [db5efb4cac5b] 2006-07-16 phil * doc/sipref.txt, siplib/sip.h, siplib/siplib.c: More Python v2.5 changes. [d54e5c462956] 2006-07-15 phil * siplib/objmap.c, siplib/sip.h, siplib/siplib.c: The sip module will now build against Python v2.5. (The 64 bit changes still need to be done.) [00cc5cf214cf] 2006-07-08 phil * lib/configure.py: Fixed the use of sys.lib in configure.py. [a10f12367272] 2006-07-06 phil * lib/configure.py: configure.py uses sys.lib if it is defined (for some 64 bit Linux distros). [0dbaacd9a231] 2006-07-04 phil * sipgen/gencode.c: Always call a dtor if there is one, even if we can't see how the instance could have been created. [47bb2a6a914a] 2006-07-01 phil * sipgen/export.c: Fixed default arguments and C++ scoped names in the new API file handling. [6909ffb3bb65] 2006-06-30 phil * NEWS, doc/sipref.txt, sipgen/export.c, sipgen/gencode.c, sipgen/genxml.c, sipgen/main.c, sipgen/sip.h, sipgen/sipgen.sbf: Added the -n command line option (possibly only temporarily). Changed the API generation so that it is more complete and uses Python types rather than C/C++ types. [1cd867db4c66] 2006-06-29 phil * lib/configure.py: Added sip_config_args to sipconfig.py. Added __hex__() to sip.voidptr. [d60d22ffda1c] * NEWS, doc/sipref.txt, lib/configure.py, siplib/siplib.c: [16c887e1169c] 2006-06-19 phil * lib/siputils.py, sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: More warning fixes from Ulli. [4ba06471ee46] 2006-06-17 phil * sipgen/gencode.c: Changed the explicit C linkage to retain the benefit of using static. [b2f02ca5a819] 2006-06-13 phil * sipgen/gencode.c, sipgen/parser.y: Signals and slots are now const char * rather than char *. [a43a225ba180] 2006-06-10 phil * doc/sipref.txt, sipgen/gencode.c, sipgen/parser.y, siplib/sip.h, siplib/siplib.c: Fixed the implementation of /TransferBack/ for virtuals. Changed all API arguments that take a format string from char * to const char * for Solaris. Used explicit C linkage for all generated function calls when genarting C++. (May need more work in this area.) [2d05ea691d29] 2006-06-06 phil * sipgen/genxml.c: Changed the XML handling of opaque classes. [86888971690a] 2006-06-05 phil * sipgen/genxml.c: Added support for opaque classes to the XML. [427fc4186f14] 2006-06-03 phil * sipgen/gencode.c: More XML generation changes. [b204d646b580] 2006-05-31 phil * sipgen/gencode.c, sipgen/genxml.c, sipgen/sip.h: More XML generation changes. [91acee878afd] 2006-05-30 phil * sipgen/gencode.c, sipgen/genxml.c, sipgen/parser.y, sipgen/sip.h: More XML generation changes. [7d79341cfc58] 2006-05-28 phil * sipgen/genxml.c: More XML generation changes. [a95f90a9f6d2] 2006-05-25 phil * sipgen/genxml.c, siplib/qtlib.c: Fixed bug disconnecting Python signals. [7a44ec54ef69] 2006-05-20 phil * sipgen/genxml.c: More XML generation changes. [7e8538e5e080] * sipgen/genxml.c, sipgen/transform.c: Backed out the change that treated "char" and "char *" as equivalent when comparing Python signatures. (The former is different to the latter if it appears first.) [f411eb8c010c] 2006-05-18 phil * sipgen/gencode.c, sipgen/genxml.c, sipgen/sip.h: More XML generation changes. [e42fe590a33c] 2006-05-16 phil * sipgen/gencode.c, sipgen/genxml.c, sipgen/sip.h, sipgen/transform.c: Tightened up on detecting clashing Python signatures involving strings and longs. Changes to the XML file generation. [180930e69638] 2006-05-13 phil * siplib/siplib.c: Removed some Python API calls made after the interpreter is known to have gone. [dc80be8d888f] * siplib/siplib.c: Fixed a sip module bug that meant that the Python API might be called after the interpreter had gone. [a9470b7f1479] * sipgen/gencode.c: Fixed code generation bug with abstract operators. [473bd3cea296] * NEWS, doc/sipref.txt, sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h: Added %UnitCode. [2f3ad3e3a582] 2006-05-11 phil * NEWS, doc/sipref.txt, sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Added sipExportSymbol() and sipImportSymbol(). Bumped the API version number to 3.2. [ee671f33f9a8] 2006-05-08 phil * sipgen/heap.c: Removed (hopefully) two new warning messages. [a347b1964dd2] 2006-05-07 phil * NEWS, doc/sipref.txt, sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h: Added support for %ExportedHeaderCode. [1fc6cbb5421c] * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c: Fixed bug in handling of virtuals with different Python and C++ signatures. [7c64bcb52e90] 2006-05-05 phil * NEWS, doc/sipref.txt, sipgen/gencode.c, sipgen/heap.c, sipgen/lexer.l, sipgen/main.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/qtlib.c, siplib/sip.h, siplib/siplib.c: Fixes for compiler warnings and a couple of minor bugs from Ulli. Deprecated %SIPNoEmitters and replaced it with %SIPOptions. Added the RegisterTypes option so that appropriate classes are registered with Qt automatically when needed - so PyQt4 doesn't need to implement qRegisterMetaType(). [b80581e367f3] * sipgen/gencode.c, sipgen/genxml.c, sipgen/sip.h: Fixed some compiler warnings. [5c4467450cbe] 2006-05-01 phil * sipgen/genxml.c, sipgen/transform.c: More work on the XML generation. [cb5eec12561a] 2006-04-30 phil * sipgen/gencode.c, sipgen/genxml.c, sipgen/main.c, sipgen/sip.h, sipgen/sipgen.sbf: Added the -m flag to generate the XML representation of the Pythonic API. [57d825e6a61f] 2006-04-28 phil * sipgen/gencode.c, siplib/qtlib.c, siplib/sip.h, siplib/siplib.c: Replaced long long with PY_LONG_LONG for MSVC 6. [19dc39dffac6] 2006-04-27 phil * lib/siputils.py, sipgen/parser.y: Fixed bug in handling multiple instances of the same namespace. The build system allows Apple's Python to be used if there is also a later python.org installation. MacOS modules are now bundles rather than dynamic libraries and can now be loaded by Pythons from python.org. Released as v4.4.3. [809972a88944] 2006-04-21 phil * sipgen/gencode.c: Fixed the previous const mapped type fix. [1a5385651af1] 2006-04-20 phil * lib/siputils.py, sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Fixed the GUI enabled interpreter in sipconfig.create_wrapper() for MacOS. Fixed static const mapped types. [def8fea45725] 2006-04-18 phil * doc/sipref.txt, lib/configure.py, lib/siputils.py: Fixed the build system for when sys.prefix != sys.exec_prefix. [83449c4ab4f2] 2006-04-16 phil * doc/sipref.txt, lib/siputils.py: Added the export_all argument to the ModuleMakefile constructor of the build system so that exports can be handled on a per module basis. This is needed to get around a (not properly understood) problem with modules that wrap C++ exceptions. [89709d0957bd] 2006-04-15 phil * lib/siputils.py, siplib/qtlib.c, specs/hurd-g++, specs/solaris-cc: The build system now complains if a property is used in a spec file when no properties have been defined. Removed Qt specific properties from the solaris-cc and hurd-g++ spec files. Fixed the disconnecting of short-circuited signals. [0c4ee0a3db80] 2006-04-08 phil * lib/siputils.py: Fixed the build system to better support frameworks on MacOS. [864b17931a7b] 2006-04-07 phil * doc/sipref.txt, siplib/sip.h, siplib/siplib.c: Made sure that all uses of sipMappedType * in the API are const. [0d3533b681e3] 2006-04-06 phil * lib/siputils.py: The sipconfig module now uses qt_data_dir (if set) to find the qmake spec files. [2f81428640de] 2006-04-05 phil * NEWS, TODO, sipgen/parser.y, sipgen/transform.c: Merged v4.4.1 into the trunk. SIP now properly detects duplicate Python signatures. [9c53b26de67b] 2006-04-02 phil * siplib/siplib.c: Fixed a regression in the handling of __dict__. [33a17c1ed42d] 2006-04-01 phil * siplib/sip.h, siplib/siplib.c: Make the sip module's support for long long and unsigned long long conditional on HAVE_LONG_LONG so that it will build with older compilers. [e655c6a8a748] 2006-03-29 phil * NEWS, sipgen/gencode.c: Removed extraneous brackets in generated code. [a64c7cdb2ee9] 2006-03-28 phil * sipgen/gencode.c: Fixed some C++ code wrongly appearing in C modules. [7e80756dae4d] 2006-03-25 phil * NEWS, sipgen/parser.y: Fixed a regression in the handling of namespaces. [7a22e2205ba9] 2006-03-24 phil * NEWS, doc/sipref.txt, sipgen/gencode.c: Documented sipModule and sipModuleDict as being available to %PostInitialisationCode. Released as v4.4. [8acdabcf6a08] [4.4] 2006-03-21 phil * doc/sipref.txt, lib/sipdistutils.py, siplib/sip.h, siplib/siplib.c: Applied patch for sipdistuils.py from Giovanni. Documented sipConvertFromNamedEnum(). Wrapped types now define __reduce_ex__ and __reduce__ attributes set to None so that pickle knows they can't be pickled. [94694c47891e] 2006-03-20 phil * siplib/siplib.c: Fixed the special handling of the __dict__ attribute so that it doesn't apply to Python sub-classes of wrapped classes. [6835562cf526] 2006-03-19 phil * doc/sipref.txt, sipgen/gencode.c, siplib/qtlib.c, siplib/sipint.h, siplib/siplib.c, siplib/threads.c: Documentation tweaks. Generate sipSelf for ctor %MethodCode now that it's existence is documented. Fixed a second place where slots with no underlying C++ instance might be invoked. [ba7b9c9371e1] 2006-03-17 phil * doc/sipref.txt, sipgen/gencode.c: Removed __unicode__ from the documentation. Fixed a bug with virtual methods that returned a reference to a type that had %ConvertToTypeCode. [6dc8ddba43ed] 2006-03-15 phil * sipgen/gencode.c, siplib/qtlib.c, siplib/sipint.h, siplib/siplib.c: Removal of a now redundant error message. Fixed a leaking weak reference object. Another attempt at fixing calling slots where the underlying C++ instance has disappeared. [8f7b10cbc372] 2006-03-14 phil * lib/siputils.py, sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c: More const void * fixes. Fixed bug with building debug modules using MinGW. Fixed feature where too many names were being generated from imported modules. SIP now handles nested imports properly and doesn't require all modules to be explcitly imported. [f7b3774f05bf] 2006-03-13 phil * build.py, doc/sipref.txt, lib/README.Fink, lib/siputils.py, sipgen/parser.y: Build system changes to support MacOS properly. Fixed crash when %TypeHeaderCode was used outside of a scope. [fc9cf357273b] 2006-03-12 phil * TODO, sipgen/gencode.c: Fixed calls to sipConvertFromVoidPtr() with a const argument. [1d20b7ddf5b7] 2006-03-11 phil * lib/siputils.py: Minor changes to sipconfig.py for PyQt4's pyqtconfig.py. [5c35ed3d0e90] * lib/siputils.py, sipgen/parser.y: Fixed handling of generating code for the version before the first %Timeline version. [3ffe3ddaa678] 2006-03-08 phil * siplib/qtlib.c: Fixed a bug in the handling of QVariant * and PyObject * signal arguments. [c04f60565120] 2006-03-06 phil * sipgen/gencode.c: Fixed a regression in handling of enums defined in an imported module. [305954bab24d] * sipgen/gencode.c: Fixed bug in handling the typedef void hack. [f5ec81faf924] 2006-03-05 phil * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, siplib/sip.h, siplib/siplib.c: Fixed bug with abstract classes with %ConvertToSubClassCode. Reimplemented namspaces split across modules so that there is a single namespace implemented in the original module. [e04e87b70f29] * sipgen/transform.c: Fixed missing #include for classes that aren't an immediate parent. [5f28954fe478] 2006-03-04 phil * sipgen/gencode.c: Fixed a regression in the wrappers around protected methods. [65fc03434a16] * siplib/qtlib.c: Suppressed the exception about the underlying object disappearing when calling a Python slot. This is because we don't automatically disconnect Python slots. [5a90239b615c] 2006-03-02 phil * NEWS, doc/sipref.txt, sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Added sipLong_AsUnsignedLong() to work around a bug in PyLong_AsUnsignedLong(). [ae6bdfc7d774] 2006-02-26 phil * sipgen/gencode.c: Fixed bug in handling class arguments with /Out/ specified. [a39d9d9a8d5a] * lib/siputils.py, sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y: Recognise NULL as a synonym for 0. Some build system changes for Cygwin. Fixed the deletion of temporary instances in catch clauses. [1b9e30dd13fb] * NEWS, doc/sipref.txt, sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/qtlib.c, siplib/sip.h: SIP now treats signed char as a type distinct from char. [01500c239ace] * sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/sip.h, siplib/siplib.c: Tore up the recent changes for handling cross module namespaces. A namespace is now defined in each module it is used. That makes things easier to implement and should be less confusing for the user. The API and data structures should now be stable. [02277356e12c] 2006-02-25 phil * sipgen/parser.y: Fixed bug in handling of variables introduced in the previous commit. [aadd2d0daa3e] * sipgen/gencode.c, sipgen/parser.y: Added support for variables defined in namespaces defined in other modules. [a1210912bb6c] * sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Completed the support for enums in namespaces originating in other modules. [590dbde2e463] 2006-02-21 phil * NEWS, doc/sipref.txt, sipgen/gencode.c, siplib/siplib.c: Added the 't' and 'u' format characters to sipParseArgs(), sipParseResult(), sipCallMethod() and sipBuildResult(). unsigned and unsigned short are now implemented as Python long objects instead of integer objects. [f8c047d7f8df] 2006-02-19 phil * sipgen/gencode.c, siplib/qtlib.c, siplib/sip.h: Implemented disconnects for universal signals. [6cd1a4dc4e73] 2006-02-18 phil * sipgen/gencode.c, siplib/qtlib.c, siplib/sip.h: Implemented support for signal arguments of type PyObject *. Implemented support for shortcircuited Python signals (ie. just the name without arguments) that will only work with other shortcircuited Python signals and Python slots - bit don't need to do any conversions between Python and C++. [6748c4088281] 2006-02-17 phil * doc/sipref.txt, sipgen/gencode.c: Fixed bug in the implementation of /TransferBack/ in virtual handlers. Fixed bug in methods with a void result and a single /Out/ argument that was a mapped type or class. [f6486c697de5] 2006-02-16 phil * doc/sipref.txt, sipgen/gencode.c: Fixed bug in generating code that called sipCallMethod(). Updated the documentation where it was still referring to the legacy type convertors. [acdd622dba74] * sipgen/gencode.c: Fixed bug in generated legacy mapped type convertor names. [8424561f0d54] 2006-02-15 phil * sipgen/gencode.c: Fixed bug that could easily result in deleting non-heap instances. [9ab37451f8f0] 2006-02-13 phil * doc/sipref.txt, lib/siputils.py: Fixes to PythonModuleMakefile. [684799b183d5] * NEWS, doc/sipref.txt, sipgen/gencode.c, siplib/qtlib.c, siplib/sip.h, siplib/sipint.h, siplib/siplib.c: Renamed the new sipCheckConvert functions to sipForceConvert functions. Added the 'B', 'C' and 'D' format character to sipBuildResult() and sipCallMethod(). Removed the 'L' format character from sipBuildResult() and sipCallMethod(). Added sipConvertFromInstance(), sipConvertFromNewInstance() and sipConvertFromMappedType(). [f6324b7c7ab1] 2006-02-12 phil * NEWS, TODO, doc/sipref.txt, sipgen/gencode.c, sipgen/parser.y, siplib/sip.h, siplib/siplib.c, siplib/threads.c: Overhauled how %ConvertToTypeCode should be written - detail below. (Still need to overhaul %ConvertFromTypeCode.) Added sipCanConvertToInstance(), sipConvertToInstance(), sipCheckConvertToInstance() and sipReleaseInstance(). Added sipCanConvertToMappedType(), sipConvertToMappedType(), sipCheckConvertToMappedType(), sipReleaseMappedType() and sipFindMappedType(). Changed the order of the arguments to sipConvertToCppTransfer(). Added the 'C' and 'D' format characters to sipParseResult(). Changed the meaning of the 'J' and 'M' format characters in sipParseArgs(). Removed the sipConvertTo_*() functions. Removed sipConvertToCppTransfer(). Took all of the None handling out of %ConvertToTypeCode. [7122e755a332] 2006-01-28 phil * sipgen/gencode.c, sipgen/sip.h, sipgen/transform.c: Fixed the support for __hash__. [f57b38d29839] 2006-01-26 phil * NEWS, doc/sipref.txt, sipgen/gencode.c, sipgen/lexer.l, sipgen/parser.y, sipgen/sip.h, siplib/qtlib.c, siplib/sip.h, siplib/sipint.h: Added %SIPNoEmitters to stop SIP generating signal emitters for a module and any module that imports it. Changed the signal/slot support so that Python signals can be implemented with proxies. [ebc0499b0e99] 2006-01-20 phil * sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Fixed a bug in sipTransferTo() that caused some objects to be garbage collected while ownership was being transferred. Check that abstract methods are only ever called as bound methods. [7f66705a98e7] 2006-01-19 phil * doc/sipref.txt, siplib/siplib.c: Updated the documentation for sipConnectRx(). The __dict__ attribute of a wrapper type now returns a regular dictionary rather than a proxy (because PyDict_Next() doesn't iterate over proxies). [b7b57265c54c] 2006-01-14 phil * siplib/siplib.c: Fixed the searching of signal types. [d24efdbe5952] 2006-01-11 phil * siplib/siplib.c: The previous fix wasn't quite so trivial. [a598de0cf451] * siplib/siplib.c: Added missing function prototype. [5d6320a5e0a1] 2006-01-10 phil * NEWS, doc/sipref.txt, lib/siputils.py, sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/sip.h, siplib/siplib.c: Fixed code generation bugs in new virtual handling code that was triggered by PyKDE. Build system changes for MinGW. Added support for constrained bools. Generate code to wrap static enum instances with inline code rather than through tables (as is done with class instances) for Windows. [48a76f76e9b8] 2006-01-09 phil * NEWS, doc/sipref.txt, sipgen/gencode.c, sipgen/parser.y: Changed the signatures of sipForceConvertTo_*() and sipConvertFrom_*() back to their SIP 4.3 versions, deprecated them, and introduced the Transfer variants. [422ea1e3fee9] * NEWS, doc/sipref.txt, lib/configure.py, lib/siputils.py: More build system changes for Windows. Added the platform macro to sipconfig.py. The default Windows platform Python 2.4 and later is now win32-msvc.net rather than win32-msvc. [e9d83bea0e38] 2006-01-08 phil * lib/configure.py, lib/siputils.py: Various build system changes needed by PyQt4 on Windows. [dcbf196c14bb] 2006-01-07 phil * lib/LICENSE.short, lib/configure.py, lib/sipdistutils.py, lib/siputils.py, specs/aix-g++, specs/aix-g++-64, specs/aix-xlc, specs/aix-xlc-64, specs/darwin-g++, specs/freebsd-g++, specs/freebsd-g++34, specs/freebsd-g++40, specs/freebsd-icc, specs /hpux-acc, specs/hpux-acc-64, specs/hpux-acc-o64, specs/hpux-g++, specs/hpux-g++-64, specs/hpuxi-acc, specs/hpuxi-acc-32, specs/hpuxi- acc-64, specs/hurd-g++, specs/irix-cc, specs/irix-cc-64, specs/irix-g++, specs/irix-g++-64, specs/linux-cxx, specs/linux- ecc-64, specs/linux-g++, specs/linux-g++-32, specs/linux-g++-64, specs/linux-icc, specs/linux-kcc, specs/linux-kylix, specs/linux- pgcc, specs/lynxos-g++, specs/macx-g++, specs/macx-mwerks, specs /macx-pbuilder, specs/macx-xcode, specs/macx-xlc, specs/netbsd-g++, specs/openbsd-g++, specs/qnx-g++, specs/sco-cc, specs/sco-g++, specs /solaris-cc, specs/solaris-cc-64, specs/solaris-g++, specs/solaris-g++-64, specs/tru64-cxx, specs/tru64-g++, specs /unixware-cc, specs/unixware-g++, specs/win32-borland, specs/win32-g++, specs/win32-icc, specs/win32-msvc, specs/win32-msvc.net, specs/win32-msvc2005: Updated the spec files from Qt v4.1. Added support for the $$() method of accessing environment variables in qmake spec files. sipdistutils.py fix from Giovanni. Changes to the build system for the slightly different macro names on Windows. [5030a64bab73] 2006-01-04 phil * NEWS, doc/sipref.txt, sipgen/gencode.c, sipgen/parser.y, sipgen/transform.c: Added support for the /NoDerived/ annotation. [496e87667614] 2006-01-03 phil * siplib/siplib.c: Fixed bug in handling of delayed dtors. [9ad8378e1bbd] 2006-01-02 phil * sipgen/transform.c: Fixed another bug with the new handling of virtual function calls (where re-implementations from another module weren't picked up). [b4a5f97c4acd] 2005-12-30 phil * sipgen/gencode.c, sipgen/sip.h, sipgen/transform.c: Fixed bugs with the new handling of virtuals that caused recursions. [e15093e5d260] 2005-12-29 phil * lib/siputils.py: Taught the build system about the QtAssistantClient library. [ef92ee748d4c] * sipgen/gencode.c: Fixed bugs related to global operators with an enum as the first argument. [2379d714c099] 2005-12-28 phil * NEWS, doc/sipref.txt, sipgen/gencode.c, siplib/sip.h, siplib/siplib.c: Added sipConvertToCppTransfer(). Changed the signatures for the type convertor functions. Added the 'L' format character to sipBuildResult() and sipCallMethod(). [2bf4d76eefe2] 2005-12-27 phil * NEWS, doc/sipref.txt, sipgen/gencode.c, sipgen/parser.y, sipgen/sip.h, sipgen/transform.c, siplib/sip.h, siplib/siplib.c: Added support for the /DelayDtor/ class annotation to control the order of dtor calls when the interpreter exits. Fixed bugs with cast operators. [5a03f38f92c7] 2005-12-26 phil * doc/sipref.txt, sipgen/gencode.c: Fixed a documentation bug. Slightly changed the declaration of the sipProtectVirt wrappers. [bc65dd63ac7d] 2005-12-24 phil * NEWS, doc/sipref.txt, sipgen/gencode.c: Class methods called as class.method(self, ...) is now equivalent to this->class::method(...). Class methods called as self.method(...) is now equivalent to this->method(...). Introduced sipSelfWasArg and the sipProtectVirt wrappers in order to support the above. [d49dc239a2d7] 2005-12-22 phil * siplib/qtlib.c, siplib/siplib.c: SIP no longer complains if a slot to be disconnected isn't actually connected (and hopes Qt will then behave appropriately). [7e93c92ec9b9] 2005-12-19 phil * sipgen/parser.y: Backed out the recent change that ignored abstract specifications if the methods wasn't virtual. [72f23df36c23] * doc/sipref.txt, lib/siputils.py: Various changes to the build system to better support Qt v4. [0a793291a2db] 2005-12-18 phil * NEWS, doc/sipref.txt, lib/siputils.py: Added the PythonModuleMakefile class and create_wrapper() function to the build system. [70cd55448b1c] 2005-12-15 phil * .repoman, NEWS, build.py, doc/sipref.txt, sipgen/main.c, siplib/qtlib.c, siplib/qtlib.cpp, siplib/sip.h: Internally renamed qtlib.cpp to qtlib.c. Small changes to the internal build system caused by the move to SVN. Removed SIP_BUILD from sip.h. [efe612146497] 2005-12-14 phil * .repoman, NEWS, TODO, build.py, custom/custom.c, custom/customw.c, custom/mkcustom.py, doc/default.css, doc/sipref.txt, lib/LICENSE, lib/LICENSE.short, lib/README, lib/README.Fink, lib/README.HP-UX, lib/THANKS, lib/configure.py, lib/sipdistutils.py, lib/siputils.py, sipgen/gencode.c, sipgen/heap.c, sipgen/lexer.l, sipgen/main.c, sipgen/parser.y, sipgen/sip.h, sipgen/sipgen.sbf, sipgen/transform.c, siplib/bool.cpp, siplib/objmap.c, siplib/qtlib.cpp, siplib/sip.h, siplib/sipint.h, siplib/siplib.c, siplib/siplib.sbf, siplib/threads.c, specs/aix-g++, specs/aix-g++-64, specs/aix-xlc, specs/aix-xlc-64, specs/bsdi-g++, specs/cygwin-g++, specs/darwin-g++, specs/dgux-g++, specs/freebsd-g++, specs/freebsd-g++34, specs/freebsd-icc, specs /hpux-acc, specs/hpux-acc-64, specs/hpux-acc-o64, specs/hpux-cc, specs/hpux-g++, specs/hpux-g++-64, specs/hpuxi-acc-32, specs/hpuxi- acc-64, specs/hurd-g++, specs/irix-cc, specs/irix-cc-64, specs/irix- cc-o32, specs/irix-g++, specs/linux-cxx, specs/linux-ecc-64, specs/linux-g++, specs/linux-g++-64, specs/linux-icc, specs/linux- kcc, specs/linux-kylix, specs/linux-pgcc, specs/lynxos-g++, specs/macx-g++, specs/macx-mwerks, specs/macx-pbuilder, specs/macx- xlc, specs/netbsd-g++, specs/openbsd-g++, specs/qnx-g++, specs /reliant-cds, specs/reliant-cds-64, specs/sco-cc, specs/sco-g++, specs/solaris-cc, specs/solaris-cc-64, specs/solaris-g++, specs/solaris-g++-64, specs/tru64-cxx, specs/tru64-g++, specs /unixware-cc, specs/unixware-g++, specs/win32-borland, specs/win32-g++, specs/win32-icc, specs/win32-msvc, specs/win32-msvc.net, specs/win32-msvc2005, specs/win32-watcom: Initial import of sip from CVS [1fd77e66a56d] sip-4.19.7/configure.py0000644000076500000240000007632413231604431015032 0ustar philstaff00000000000000# This script handles the SIP configuration and generates the Makefiles. # # Copyright (c) 2017 Riverbank Computing Limited # # 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 try: from importlib import invalidate_caches except ImportError: invalidate_caches = lambda: None import siputils # Initialise the globals. sip_version = 0x041307 sip_version_str = "4.19.7" py_version = sys.hexversion >> 8 py_platform = sys.platform plat_py_site_dir = None plat_py_inc_dir = None plat_py_venv_inc_dir = None plat_py_conf_inc_dir = None plat_py_lib_dir = None plat_sip_dir = None plat_bin_dir = None platform_specs = [] sip_bin_dir = '' sip_inc_dir = '' sip_module_dir = '' sip_sip_dir = '' pyi_dir = '' sysroot = '' src_dir = os.path.dirname(os.path.abspath(__file__)) sip_module_base = None build_platform = None # Constants. DEFAULT_MACOSX_ARCH = 'i386 ppc' MACOSX_SDK_DIRS = ('/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs', '/Developer/SDKs') # 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_APP", "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_APP", "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", "LFLAGS_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_build_platform(): """ Initialise the build platform. """ global build_platform # 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" } build_platform = "none" if py_platform == "win32": if py_version >= 0x030500: build_platform = "win32-msvc2015" elif py_version >= 0x030300: build_platform = "win32-msvc2010" elif py_version >= 0x020600: build_platform = "win32-msvc2008" elif py_version >= 0x020400: build_platform = "win32-msvc.net" else: build_platform = "win32-msvc" else: for pd in list(platdefaults.keys()): if py_platform[:len(pd)] == pd: build_platform = platdefaults[pd] break def inform_user(): """ Tell the user the option values that are going to be used. """ if not opts.no_tools: siputils.inform("The SIP code generator will be installed in %s." % sip_bin_dir) siputils.inform("The %s module will be installed in %s." % (sip_module_base, sip_module_dir)) if opts.pyi: siputils.inform("The sip.pyi stub file will be installed in %s." % pyi_dir) if opts.static: siputils.inform("The %s module will be built as a static library." % sip_module_base) siputils.inform("The sip.h header file will be installed in %s." % sip_inc_dir) siputils.inform("The default directory to install .sip files in is %s." % sip_sip_dir) if opts.use_qmake is None: siputils.inform("The platform/compiler configuration is %s." % build_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) if opts.deployment_target: siputils.inform("MacOS/X deployment target is %s." % opts.deployment_target) def set_platform_directories(): """ Initialise the global variables relating to platform-specific directories. """ global plat_py_site_dir, plat_py_inc_dir, plat_py_venv_inc_dir global plat_py_conf_inc_dir, 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_venv_inc_dir = sysconfig.get_python_inc(prefix=sys.prefix) plat_py_conf_inc_dir = os.path.dirname(sysconfig.get_config_h_filename()) if sys.platform == "win32": bin_dir = sys.exec_prefix try: # Python v3.3 and later. base_prefix = sys.base_prefix if sys.exec_prefix != sys.base_exec_prefix: bin_dir += '\\Scripts' except AttributeError: try: # virtualenv for Python v2. base_prefix = sys.real_prefix bin_dir += '\\Scripts' except AttributeError: # We can't detect the base prefix in Python v3 prior to v3.3. base_prefix = sys.prefix plat_py_lib_dir = base_prefix + "\\libs" plat_bin_dir = bin_dir 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 patch_files(): """Patch any files that need it.""" patched = ( ("siplib", "sip.h"), ("siplib", "siplib.c"), ("siplib", "siplib.sbf") ) # The siplib directory may not exist if we are building away from the # source directory. try: os.mkdir("siplib") except OSError: pass for f in patched: dst_fn = os.path.join(*f) src_fn = os.path.join(src_dir, dst_fn + ".in") siputils.inform("Creating %s..." % dst_fn) dst = open(dst_fn, "w") src = open(src_fn) for line in src: line = line.replace("@CFG_MODULE_NAME@", opts.sip_module) line = line.replace("@CFG_MODULE_BASENAME@", sip_module_base) dst.write(line) dst.close() src.close() 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": build_platform, "sip_bin": os.path.join(sip_bin_dir, "sip"), "sip_inc_dir": sip_inc_dir, "sip_mod_dir": sip_module_dir, "default_bin_dir": plat_bin_dir, "default_mod_dir": plat_py_site_dir, "default_sip_dir": sip_sip_dir, "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, "deployment_target": opts.deployment_target, "qt_framework": 0 } 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) invalidate_caches() import sipconfig cfg = sipconfig.Configuration() cfg.set_build_macros(macros) if opts.no_tools: subdirs = ["siplib"] installs = None else: subdirs = ["sipgen", "siplib"] installs = (["sipconfig.py", os.path.join(src_dir, "sipdistutils.py")], cfg.sip_mod_dir) if opts.use_qmake: sipconfig.inform("Creating top level .pro file...") pro = open("sip.pro", "w") pro.write("TEMPLATE = subdirs\n") pro.write("SUBDIRS = %s\n" % " ".join(subdirs)) if installs is not None: files, path = installs pro.write("\n") pro.write("build_system.files = %s\n" % " ".join(files)) pro.write("build_system.path = %s\n" % quote(path)) pro.write("INSTALLS += build_system\n") pro.close() else: sipconfig.inform("Creating top level Makefile...") sipconfig.ParentMakefile( configuration=cfg, subdirs=subdirs, installs=installs ).generate() if opts.use_qmake: sipconfig.inform("Creating sip code generator .pro file...") pro = open(os.path.join("sipgen", "sipgen.pro"), "w") pro.write("TEMPLATE = app\n") pro.write("TARGET = sip\n") pro.write("CONFIG -= qt app_bundle\n") pro.write("CONFIG += warn_on exceptions_off console %s\n" % ( ("debug" if opts.debug else "release"))) pro.write("\n") pro.write("# Work around QTBUG-39300.\n") pro.write("CONFIG -= android_install\n") pro.write("\n") pro.write("target.path = %s\n" % os.path.dirname(cfg.sip_bin)) pro.write("INSTALLS += target\n") c_sources = get_sources("sipgen", "*.c") pro.write("\n") pro.write("SOURCES = %s\n" % " ".join(c_sources)) headers = get_sources("sipgen", "*.h") pro.write("\n") pro.write("HEADERS = %s\n" % " ".join(headers)) pro.close() else: 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=1, universal=opts.universal, arch=opts.arch, deployment_target=opts.deployment_target ).generate() if opts.use_qmake: sipconfig.inform("Creating sip module .pro file...") pro = open(os.path.join("siplib", "siplib.pro"), "w") pro.write("TEMPLATE = lib\n") pro.write("TARGET = %s\n" % sip_module_base) pro.write("CONFIG -= qt\n") pro.write("CONFIG += warn_on exceptions_off %s %s\n" % ( ("staticlib" if opts.static else "plugin plugin_bundle"), ("debug" if opts.debug else "release"))) pro.write("\n") pro.write("# Work around QTBUG-39300.\n") pro.write("CONFIG -= android_install\n") pro.write("\n") pro.write("INCLUDEPATH += %s\n" % cfg.py_inc_dir) if cfg.py_conf_inc_dir != cfg.py_inc_dir: pro.write("INCLUDEPATH += %s\n" % cfg.py_conf_inc_dir) if not opts.static: # These only need to be correct for Windows. debug_suffix = "_d" if opts.debug else "" link_lib_dir = quote("-L" + cfg.py_lib_dir) pro.write(""" win32 { PY_MODULE = %s%s.pyd PY_MODULE_SRC = $(DESTDIR_TARGET) LIBS += %s } else { PY_MODULE = %s.so macx { PY_MODULE_SRC = $(TARGET).plugin/Contents/MacOS/$(TARGET) QMAKE_LFLAGS += "-undefined dynamic_lookup" } else { PY_MODULE_SRC = $(TARGET) } } QMAKE_POST_LINK = $(COPY_FILE) $(DESTDIR_TARGET) $$PY_MODULE target.CONFIG = no_check_exist target.files = $$PY_MODULE """ % (sip_module_base, debug_suffix, link_lib_dir, sip_module_base)) pro.write("\n") pro.write("target.path = %s\n" % cfg.sip_mod_dir) pro.write("INSTALLS += target\n") if opts.pyi: pro.write("\n") pro.write("sip_pyi.files = sip.pyi\n") pro.write("sip_pyi.path = %s\n" % pyi_dir) pro.write("INSTALLS += sip_pyi\n") pro.write("\n") pro.write("sip_h.files = sip.h\n") pro.write("sip_h.path = %s\n" % cfg.sip_inc_dir) pro.write("INSTALLS += sip_h\n") c_sources = get_sources("siplib", "*.c") cpp_sources = get_sources("siplib", "*.cpp") pro.write("\n") pro.write("SOURCES = %s\n" % " ".join(c_sources + cpp_sources)) headers = get_sources("siplib", "*.h") pro.write("\n") pro.write("HEADERS = %s\n" % " ".join(headers)) pro.close() else: sipconfig.inform("Creating sip module Makefile...") build_dir = os.getcwd() installs=[ ([os.path.join(build_dir, "siplib", "sip.h")], cfg.sip_inc_dir)] if opts.pyi: installs.append(([os.path.join(src_dir, 'sip.pyi')], pyi_dir)) makefile = sipconfig.ModuleMakefile( configuration=cfg, build_file=os.path.join(build_dir, "siplib", "siplib.sbf"), dir="siplib", install_dir=cfg.sip_mod_dir, installs=installs, console=1, warnings=1, static=opts.static, debug=opts.debug, universal=opts.universal, arch=opts.arch, deployment_target=opts.deployment_target ) if src_dir != build_dir: src_siplib_dir = os.path.join(src_dir, "siplib") makefile.extra_include_dirs.append(src_siplib_dir) makefile.extra_source_dirs.append(src_siplib_dir) makefile.generate() def get_sources(sources_dir, ext): """ Get the quoted files with the specified extension from a directory. """ return [quote(f) for f in glob.glob(os.path.join(src_dir, sources_dir, ext))] def quote(path): """ Return a path that is quoted if necessary. """ if " " in path: path = '"' + path + '"' return path # Look out for recursive definitions. _extrapolating = [] def _get_configuration_value(config, name, default=None): """ Get a configuration value while extrapolating. """ value = config.get(name) if value is None: if default is None: siputils.error("Configuration file references non-existent name '%s'." % name) return default parts = value.split('%(', 1) while len(parts) == 2: prefix, tail = parts parts = tail.split(')', 1) if len(parts) != 2: siputils.error("Configuration file contains unterminated extrapolated name '%s'." % tail) xtra_name, suffix = parts if xtra_name in _extrapolating: siputils.error("Configuration file contains a recursive reference to '%s'." % xtra_name) _extrapolating.append(xtra_name) xtra_value = _get_configuration_value(config, xtra_name) _extrapolating.pop() value = prefix + xtra_value + suffix parts = value.split('%(', 1) return value def update_from_configuration_file(config_file): """ Update a number of globals from values read from a configuration file. """ siputils.inform("Reading configuration from %s..." % config_file) config = {} # Read the file into the dict. cfg = open(config_file) line_nr = 0 for l in cfg: line_nr += 1 # Strip comments and blank lines. l = l.split('#')[0].strip() if l == '': continue parts = l.split('=', 1) if len(parts) == 2: name = parts[0].strip() value = parts[1].strip() else: name = value = '' if name == '' or value == '': siputils.error("%s:%d: Invalid line." % (config_file, line_nr)) config[name] = value last_name = name cfg.close() # Enforce the presets. version = siputils.version_to_string(py_version).split('.') config['py_major'] = version[0] config['py_minor'] = version[1] config['sysroot'] = sysroot # Override the relevant values. global py_platform, plat_py_conf_inc_dir, plat_py_inc_dir, plat_py_lib_dir global sip_bin_dir, sip_inc_dir, sip_module_dir, sip_sip_dir py_platform = _get_configuration_value(config, 'py_platform', py_platform) plat_py_inc_dir = _get_configuration_value(config, 'py_inc_dir', plat_py_inc_dir) plat_py_lib_dir = _get_configuration_value(config, 'py_pylib_dir', plat_py_lib_dir) # The pyconfig.h directory defaults to the Python.h directory. plat_py_conf_inc_dir = _get_configuration_value(config, 'py_conf_inc_dir', plat_py_inc_dir) sip_bin_dir = _get_configuration_value(config, 'sip_bin_dir', sip_bin_dir) sip_module_dir = _get_configuration_value(config, 'sip_module_dir', sip_module_dir) # Note that this defaults to any 'py_inc_dir' specified in the # configuration file. sip_inc_dir = _get_configuration_value(config, 'sip_inc_dir', plat_py_inc_dir) # Note that this is only used when creating sipconfig.py. sip_sip_dir = _get_configuration_value(config, 'sip_sip_dir', sip_sip_dir) def create_optparser(sdk_dir): """Create the parser for the command line. """ def store_abspath(option, opt_str, value, parser): setattr(parser.values, option.dest, os.path.abspath(value)) def store_abspath_dir(option, opt_str, value, parser): if not os.path.isdir(value): raise optparse.OptionValueError("'%s' is not a directory" % value) setattr(parser.values, option.dest, os.path.abspath(value)) def store_abspath_file(option, opt_str, value, parser): if not os.path.isfile(value): raise optparse.OptionValueError("'%s' is not a file" % value) setattr(parser.values, option.dest, os.path.abspath(value)) def store_version(option, opt_str, value, parser): version = siputils.version_from_string(value) if version is None: raise optparse.OptionValueError( "'%s' is not a valid version number" % value) setattr(parser.values, option.dest, version) 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", type="string", metavar="PLATFORM", dest="platform", help="the platform/compiler " "configuration [default: %s]" % build_platform) p.add_option("-u", "--debug", action="store_true", default=False, help="build with debugging symbols") p.add_option("--sip-module", action="store", default="sip", type="string", metavar="NAME", dest="sip_module", help="the package.module name " "of the sip module [default: sip]") p.add_option("--configuration", dest='config_file', type='string', action='callback', callback=store_abspath_file, metavar="FILE", help="FILE contains the target configuration") p.add_option("--target-py-version", dest='target_py_version', type='string', action='callback', callback=store_version, metavar="VERSION", help="the major.minor version of the target Python [default: " "%s]" % siputils.version_to_string(py_version, parts=2)) p.add_option("--sysroot", dest='sysroot', type='string', action='callback', callback=store_abspath_dir, metavar="DIR", help="DIR is the target system root directory") p.add_option("--no-tools", action="store_true", default=False, dest="no_tools", help="disable the building of the code generator " "and the installation of the build system [default: enabled]") p.add_option("--use-qmake", action="store_true", default=False, dest="use_qmake", help="generate qmake .pro files instead of " "Makefiles") if sys.platform == 'darwin': # Get the latest SDK to use as the default. sdks = glob.glob(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("--deployment-target", action="store", default='', metavar="VERSION", dest="deployment_target", help="set the value of the MACOSX_DEPLOYMENT_TARGET " "environment variable in generated Makefiles") 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", type="string", metavar="DIR", dest="sipbindir", callback=store_abspath, help="where the SIP code generator will be installed [default: " "%s]" % plat_bin_dir) g.add_option("-d", "--destdir", action="callback", type="string", metavar="DIR", dest="sipmoddir", callback=store_abspath, help="where the SIP module will be installed [default: " "%s]" % plat_py_site_dir) g.add_option("-e", "--incdir", action="callback", type="string", metavar="DIR", dest="sipincdir", callback=store_abspath, help="where the SIP header file will be installed [default: " "%s]" % plat_py_venv_inc_dir) g.add_option("-v", "--sipdir", action="callback", type="string", metavar="DIR", dest="sipsipdir", callback=store_abspath, help="where .sip files are normally installed [default: " "%s]" % plat_sip_dir) g.add_option("--no-stubs", "--no-pyi", action="store_false", default=True, dest="pyi", help="do not install the sip.pyi stub file") g.add_option("--stubsdir", "--pyidir", action="callback", type="string", metavar="DIR", dest="pyidir", callback=store_abspath, help="where the sip.pyi stub file will be installed [default: " "%s]" % plat_py_site_dir) 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)) global py_version, build_platform if py_version < 0x020300: siputils.error("This version of SIP requires Python v2.3 or later.") # Basic initialisation. set_platform_directories() set_build_platform() # Build up the list of valid specs. for s in os.listdir(os.path.join(src_dir, "specs")): platform_specs.append(s) # Determine the directory containing the default OS/X SDK. if sys.platform == 'darwin': for sdk_dir in MACOSX_SDK_DIRS: if os.path.isdir(sdk_dir): break else: sdk_dir = MACOSX_SDK_DIRS[0] else: sdk_dir = '' # Parse the command line. global opts p = create_optparser(sdk_dir) opts, args = p.parse_args() # Override defaults that affect subsequent configuration. if opts.target_py_version is not None: py_version = opts.target_py_version if opts.sysroot is not None: global sysroot sysroot = opts.sysroot # Make sure MacOS specific options get initialised. if sys.platform != 'darwin': opts.universal = '' opts.arch = [] opts.sdk = '' opts.deployment_target = '' # 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 = 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 = '' # Apply the overrides from any configuration file. global plat_bin_dir, plat_py_conf_inc_dir, plat_py_inc_dir global plat_py_lib_dir, plat_py_site_dir, plat_sip_dir global sip_bin_dir, sip_inc_dir, sip_module_dir, sip_sip_dir, pyi_dir # Set defaults. sip_bin_dir = plat_bin_dir sip_inc_dir = plat_py_venv_inc_dir sip_module_dir = plat_py_site_dir sip_sip_dir = plat_sip_dir if opts.config_file is not None: update_from_configuration_file(opts.config_file) elif sysroot != '': def apply_sysroot(d): if d.startswith(sys.prefix): d = sysroot + d[len(sys.prefix):] return d plat_bin_dir = apply_sysroot(plat_bin_dir) plat_py_conf_inc_dir = apply_sysroot(plat_py_conf_inc_dir) plat_py_inc_dir = apply_sysroot(plat_py_inc_dir) plat_py_lib_dir = apply_sysroot(plat_py_lib_dir) plat_py_site_dir = apply_sysroot(plat_py_site_dir) plat_sip_dir = apply_sysroot(plat_sip_dir) sip_bin_dir = apply_sysroot(sip_bin_dir) sip_inc_dir = apply_sysroot(sip_inc_dir) sip_module_dir = apply_sysroot(sip_module_dir) sip_sip_dir = apply_sysroot(sip_sip_dir) # Override from the command line. if opts.platform is not None: build_platform = opts.platform if opts.sipbindir is not None: sip_bin_dir = opts.sipbindir if opts.sipincdir is not None: sip_inc_dir = opts.sipincdir if opts.sipmoddir is not None: sip_module_dir = opts.sipmoddir if opts.sipsipdir is not None: sip_sip_dir = opts.sipsipdir if opts.pyidir is not None: pyi_dir = opts.pyidir else: pyi_dir = sip_module_dir # Get the platform specific macros for building. macros = siputils.parse_build_macros( os.path.join(src_dir, "specs", build_platform), build_macro_names, args) if macros is None: siputils.error("Unsupported macro name specified. Use the --show-build-macros flag to see a list of supported macros.") sys.exit(2) # Fix the name of the sip module. global sip_module_base module_path = opts.sip_module.split(".") sip_module_base = module_path[-1] if len(module_path) > 1: del module_path[-1] module_path.insert(0, sip_module_dir) sip_module_dir = os.path.join(*module_path) # Tell the user what's been found. inform_user() # Patch any files that need it. patch_files() # 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 sip-4.19.7/doc/0000755000076500000240000000000013231604432013231 5ustar philstaff00000000000000sip-4.19.7/LICENSE0000644000076500000240000000513513231604405013475 0ustar philstaff00000000000000RIVERBANK 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) 2015 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. sip-4.19.7/LICENSE-GPL20000644000076500000240000004336113231604405014202 0ustar philstaff00000000000000------------------------------------------------------------------------- GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. ------------------------------------------------------------------------- sip-4.19.7/LICENSE-GPL30000644000076500000240000010474113231604405014203 0ustar philstaff00000000000000------------------------------------------------------------------------- GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. 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. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 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 . 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: Copyright (C) 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 . 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 . ------------------------------------------------------------------------- sip-4.19.7/NEWS0000644000076500000240000007344513231604406013201 0ustar philstaff00000000000000v4.19.7 23rd January 2018 - The %Docstring directive can now include automatically generated signature descriptions using the "signature" option. - typedefs can now have %Docstring directives. - Bug fixes. v4.19.6 23rd November 2017 - Bug fixes. v4.19.5 6th November 2017 - Bug fixes. v4.19.4 1st November 2017 - Added support for C++11 scoped enums implemented as Python enums. - Added enableoverflowchecking() to the sip module. - Added sipEnableOverflowChecking() to the C API. - Added sipTypeIsScopedEnum() to the C API. - Added sipConvertToBool() to the C API. - Added sipConvertToEnum() to the C API. - Deprecated sipCanConvertToEnum() in the C API. - Added sipLong_AsChar(), sipLong_AsSignedChar() and sipLong_AsUnsignedChar() to the C API. - Added sipLong_AsShort() and sipLong_AsUnsignedShort() to the C API. - Added sipLong_AsInt() and sipLong_AsUnsignedInt() to the C API. - Added sipLong_AsLong() and sipLong_AsUnsignedLong() to the C API. - Added sipLong_AsLongLong() and sipLong_AsUnsignedLongLong() to the C API. - Bug fixes. v4.19.3 3rd July 2017 - Added support for type hints for properties. - Added sipEventType and sipRegisterEventHandler() to the C API. - Added sipInstanceDestroyed() to the C API. - Added sipPrintObject() to the C API. - Bug fixes. v4.19.2 30th March 2017 - Bug fixes. v4.19.1 15th February 2017 - Added the %PreMethodCode directive. - Added sipEnableGC() to the C API. - Added the -D command line option so that the generated code is aware of Python debug builds. - Bug fixes. v4.19 25th December 2016 - Added support for the 'final' keyword. - Added the 'use_limited_api' argument to the %Module directive. - Added the %HideNamespace directive. - Added the assign() function to the sip module. - Added sipCallProcedureMethod() to the C API. - Added sipCheckPluginForType() to the C API. - Added sipGetBufferInfo() and sipReleaseBufferInfo() to the C API. - Added sipGetCFunction() to the C API. - Added sipGetDate() and sipFromDate() to the C API. - Added sipGetDatetime() and sipFromDatetime() to the C API. - Added sipGetFrame() to the C API. - Added sipGetMethod() and sipFromMethod() to the C API. - Added sipGetTime() and sipFromTime() to the C API. - Added sipGetTypeUserData() and sipSetTypeUserData() to the C API. - Added sipGetUserObject() and sipSetUserObject() to the C API. - Added sipIsUserType() to the C API. - Added sipPyTypeDict() and sipPyTypeName() to the C API. - Added sipSetNewUserTypeHandler() to the C API. - Added sipUnicodeData(), sipUnicodeNew() and sipUnicodeWrite() to the C API. - Removed the support for module version numbers. - Removed all code generator support for PyQt3. - Bug fixes. v4.18.1 25th July 2016 - Bug fixes. v4.18 13th April 2016 - Added the /TypeHint/ argument, class, mapped type, function, typedef and variable annotations. - Added the /TypeHintIn/ and /TypeHintOut/ argument, class, mapped type and typedef annotations. - Added the /TypeHintValue/ argument, class and mapped type annotations. - Added the /NoTypeHint/ class, enum, function and variable annotations. - Added the %ExportedTypeHintCode and %TypeHintCode directives. - Added the -f command line option to treat warnings as errors. - Added the -y command line option to generated PEP 484 compatible type hint stub files. - Deprecated the /DocType/ and /DocValue/ annotations. - Bug fixes. v4.17 24th October 2015 - Added support for PEP 465 (__matmul__ and __imatmul__). - Added support for PEP 492 (__aenter__, __aexit__, __await__, __aiter__ and __anext__). - Added support for MSVC 2015 to the build system. - Bug fixes. v4.16.9 17th July 2015 - Bug fixes. v4.16.8 11th June 2015 - Added support for the current Python v3 exceptions. - Bug fixes. v4.16.7 25th March 2015 - Added the %VirtualCallCode directive. - Bug fixes. v4.16.6 25th February 2015 - Added the /FileExtension/ class annotation. - Installing into a virtual env should now work. - Timestamps are no longer included in generated code. The -T command line option is now ignored and deprecated. - The '@file' method of passing additional command line options is now supported. The -z command line option is now deprecated. - Bug fixes. v4.16.5 24th December 2014 - Added the asarray() method to sip.voidptr. - Bug fixes. v4.16.4 23rd October 2014 - Added the /AbortOnException/ function annotation. - Added the /DisallowNone/ function annotation. - Added the /DisallowNone/ argument annotation. - Bug fixes. v4.16.3 11th September 2014 - Enums now support __qualname__ for Python v3.3 and later. v4.16.2 3rd July 2014 - Deprecated the %ConsolidatedModule directive as it won't be supported in SIP v5. - Bug fixes. v4.16.1 9th June 2014 - Bug fixes. v4.16 26th May 2014 - Added the /NoSetter/ variable annotation. - Added the -B option to sip. - Changed the handling of timelines (introducing a potential incompatibility) so that later versions of wrapped libraries can be wrapped so long as they are compatible with known versions. - Added support for the 'no_receiver_check' argument to connect() in PyQt v4.11. - Added the --configuration option to configure.py. - Added the --sysroot option to configure.py. - Added the --target-py-version option to configure.py. - Added the --no-tools option to configure.py. - Added the --use-qmake option to configure.py. - Bug fixes. v4.15.5 14th March 2014 - The use_arch argument of sipconfig.create_wrapper() can now specify a space separated set of architectures. - Bug fixes. v4.15.4 8th January 2014 - Added SIP_SSIZE_T_FORMAT to the C API. - Bug fixes (specifically for PyQt5). v4.15.3 16th October 2013 - Bug fixes (specifically for PyQtChart). v4.15.2 14th September 2013 - sipConvertToArray() will now optionally take ownership of the array memory. - Added support for char, unsigned char, short, int, float and double as array types. - Bug fixes. v4.15.1 23rd August 2013 - Fixes a regression in the handling of hidden virtual methods. v4.15 21st August 2013 - Added the call_super_init argument to the %Module directive to specify that classes should support cooperative multi-inheritance. - Added the %FinalisationCode directive. - Added the /Mixin/ class annotation. - Added the /NoScope/ enum annotation. - Added sipConvertFromNewPyType() to the C API. - Added sipConvertToArray() and sipConvertToTypedArray() to the C API. - Added sipRegisterProxyResolver() to the C API. - Bug fixes. v4.14.7 16th June 2013 - The internal API version is increased to 10.0 requiring the regeneration of all modules. - Added the /Sequence/ function annotation. - %ConvertFromTypeCode can now be specified for classes. - Added sipEnableAutoconversion() to the C API. - Added sipSetDestroyOnExit() to the C API. - Bug fixes. v4.14.6 21st April 2013 - Bug fixes. v4.14.5 26th March 2013 - Bug fixes (specifically for QGIS). v4.14.4 1st March 2013 - The handwritten code provided to the %VirtualErrorHandler directive is now called with the GIL held and from the thread that raised the error. This is, potentially, an incompatible change. - Bug fixes. v4.14.3 28th January 2013 - The /KeepReference/ argument annotation, when applied to factories, will now keep the reference with the object created by the factory. - Any object that supports the buffer protocol can now be passed when a sip.voidptr is expected. - Bug fixes. v4.14.2 8th December 2012 - Added sip.setdestroyonexit(). - sip.voidptr() will now accept any object that implements the buffer protocol. - Bug fixes. v4.14.1 27th October 2012 - SIP_PYBUFFER can now be used to define objects that implement the Python buffer protocol. - Added /Capsule/ typedef annotation. - Added the 'z' format character to sipBuildResult(). - Added the 'z', '!' and '$' format characters to sipParseResult(). - The C prototype foo(void) is now accepted. - sipdistutils.py will now include swig_opts if no sip_opts have been defined. - Bug fixes. v4.14 29th September 2012 - The internal API version is increased to 9.0 requiring the regeneration of all modules. - Added the %InstanceCode directive. - Added the %VirtualErrorHandler directive. - Added the default_VirtualErrorHandler argument to the %Module directive. - Added the /VirtualErrorHandler/ class annotation. - Added the /NoVirtualErrorHandler/ and /VirtualErrorHandler/ function annotations. - The /AllowNone/ and /NoRelease/ mapped type annotations can now be used with mapped type templates. - SIP_PLATFORM_* and SIP_TIMELINE_* preprocessor symbols are generated corresponding to the '-t' arguments passed on the command line. - Deprecated sipTransferBreak(). - For Python v2.x unsigned short and unsigned char (when used as a byte) are now converted to int, rather than long, objects. - Added support for MSVC 2010 to the build system. v4.13.3 20th June 2012 - The /NoRaisesPyException/ and /RaisesPyException/ function annotations can now be applied to constructors. - Added support for the Python v3.3 handling of Unicode. v4.13.2 10th February 2012 - A bug fix release. v4.13.1 22nd December 2011 - Deprecation warnings can no longer be disabled. - Added the all_raise_py_exception argument to the %Module directive. - Added the /NoRaisesPyException/ function annotation. - Added the /PyName/ typedef annotation. - Class templates now allow super-classes to be defined as template arguments. - Added support for 'public' preceding the name of a class in a super-class list. - Added support for 'protected' and 'private' preceding the name of a class in a super-class list. Any such super-class will be ignored. v4.13 25th October 2011 - Added the %DefaultDocstringFormat directive. - Added the format argument to the %Docstring directive. - %ConvertToSubClassCode can now cause a restart of the conversion process using a different requested type. - '*' and '&' are now supported as unary operators in expressions used in the values of default arguments. - The /Transfer/ annotation can now be used with the /Array/ annotation to prevent the freeing of the temporary array of pointers. v4.12.4 2nd August 2011 - PyLong_AsUnsignedLongMask() and PyLong_AsUnsignedLongLongMask() are now used in preference to PyLong_AsUnsignedLong() and PyLong_AsUnsignedLongLong(). - The build system now supports Qt being built with the -qtlibinfix flag. v4.12.3 22nd May 2011 - A bug fix release. v4.12.2 30th April 2011 - /KeepReference/ is now supported as a function annotation. - Handwritten code in class templates no longer have the types substituted in lines that appear to contain C preprocessor directives. - Added support for global inplace numeric operators. v4.12.1 22nd January 2011 - Added support for the __getattribute__, __getattr__, __setattr__ and __delattr__ methods. - Added the /RaisesPyException/ function annotation. - Added SIP_SSIZE_T as a predefined type. - PyObject * can now be used as a synonym for SIP_PYOBJECT. - Added sip.ispycreated() to the sip module. - Added the --deployment-target flag to configure.py for MacOS/X. v4.12 23rd December 2010 - Implemented the revised directive syntax for %Module. - Deprecated %CModule, use %Module instead. - Added the keyword_arguments argument to %Module to specify the level of support for Python keyword arguments. - Deprecated the -k flag to sip, use the keyword_arguments argument to %Module instead. - Added an automatic pseudo-%Timeline to allow the SIP version number to be used in the %If directive. - Changed the behavior of the /KeywordArgs/ annotation to specify the level of support for Python keyword arguments. - Deprecated the /NoKeywordArgs/ annotation, use /KeywordArgs="None"/ instead. - Added the use_argument_names argument to %Module to provide the real names of arguments to handwritten code. - Module docstrings are now supported. - Added %AutoPyName to automatically provide Python names. - Added %Property to implement Python properties based on C/C++ getters and setters. - Added %Extract to allow arbitrary text to be embedded in specification files and subsequently extracted. - Deprecated %Doc and %ExportedDoc, use %Extract instead. - Added the -X flag to sip to extract text defined with %Extract. - Deprecated the -d flag to sip, use -X instead. - Added /PyInt/ as an argument, function and typedef annotation to force char types to be handled as Python integers rather than single character strings. - Added the L and M format characters to sipBuildResult(), sipCallMethod() and sipParseResult(). - Added sipGetAddress(). - Added the -T flag to sip to suppress the timestamp in the header comments of generated files. - sip.voidptr now behaves like a Python memoryview object and supports sub-script assignment. - Added the --sip-module flag to configure.py to allow the name and containing package of the sip module to be specified thereby allowing packages to include a local copy of the sip module. v4.11.2 22nd October 2010 - /KeepReference/ can now be applied to global functions and static methods. - %TypeCode can now be specified in a %MappedType directive. - Mapped types for templates no longer require the template arguments to be fully defined. - Build system changes required by PyQt v4.8 and Qt v4.7. v4.11.1 6th September 2010 - A bug fix release. v4.11 31st August 2010 - Added the %UnitPostIncludeCode directive. - /KeepReference/ will now accept a key to track when the same object is passed to more than one method. - operator() and __call__() can now accept keyword arguments. - Added support for Python v3.2. 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. sip-4.19.7/README0000644000076500000240000000162513231604406013351 0ustar philstaff00000000000000SIP - 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`` are installed. To prepare run the following:: python build.py prepare Now you can follow the normal installation instructions. sip-4.19.7/sip.pyi0000644000076500000240000000536113231604405014007 0ustar philstaff00000000000000# This file is the Python type hints stub file for the sip extension module. # # Copyright (c) 2016 Riverbank Computing Limited # # 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. from typing import overload, Sequence, Union # Constants. SIP_VERSION = ... # type: int SIP_VERSION_STR = ... # type: str # The bases for SIP generated types. class wrappertype: ... class simplewrapper: ... class wrapper(simplewrapper): ... # PEP 484 has no explicit support for the buffer protocol so we just name types # we know that implement it. Buffer = Union['array', 'voidptr', str, bytes, bytearray] # The array type. class array(Sequence): ... # The voidptr type. class voidptr: def __init__(addr: Union[int, Buffer], size: int = -1, writeable: bool = True) -> None: ... def __int__(self) -> int: ... @overload def __getitem__(self, i: int) -> bytes: ... @overload def __getitem__(self, s: slice) -> 'voidptr': ... def __hex__(self) -> str: ... def __len__(self) -> int: ... def __setitem__(self, i: Union[int, slice], v: Buffer) -> None: ... def asarray(self, size: int = -1) -> array: ... # Python doesn't expose the capsule type. #def ascapsule(self) -> capsule: ... def asstring(self, size: int = -1) -> bytes: ... def getsize(self) -> int: ... def getwriteable(self) -> bool: ... def setsize(self, size: int) -> None: ... def setwriteable(self, bool) -> None: ... # Remaining functions. def cast(obj: simplewrapper, type: wrappertype) -> simplewrapper: ... def delete(obj: simplewrapper) -> None: ... def dump(obj: simplewrapper) -> None: ... def enableautoconversion(type: wrappertype, enable: bool) -> bool: ... def getapi(name: str) -> int: ... def isdeleted(obj: simplewrapper) -> bool: ... def ispycreated(obj: simplewrapper) -> bool: ... def ispyowned(obj: simplewrapper) -> bool: ... def setapi(name: str, version: int) -> None: ... def setdeleted(obj: simplewrapper) -> None: ... def setdestroyonexit(destroy: bool) -> None: ... def settracemask(mask: int) -> None: ... def transferback(obj: wrapper) -> None: ... def transferto(obj: wrapper, owner: wrapper) -> None: ... def unwrapinstance(obj: simplewrapper) -> None: ... def wrapinstance(addr: int, type: wrappertype) -> simplewrapper: ... sip-4.19.7/sipdistutils.py0000644000076500000240000001363113231604405015602 0ustar philstaff00000000000000# Subclasses disutils.command.build_ext, replacing it with a SIP version that # compiles .sip -> .cpp before calling the original build_ext command. # Based on Pyrex.Distutils, written by Graham Fawcett and Darrel Gallion. # # Copyright (c) 2011 Develer Srl. # # 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 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 = "Compile 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 open(sbf).readlines(): key, value = L.split("=", 1) if key.strip() == "sources": out = [] for o in value.split(): out.append(os.path.join(self._sip_output_dir(), 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._sip_output_dir(), "sip.signature") def _sip_output_dir(self): return self.build_temp 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: # Command line sip_opts take precedence. if len(self.sip_opts) == 0: self.sip_opts.extend(extension.swig_opts) 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._sip_output_dir()): os.makedirs(self._sip_output_dir()) # 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._sip_output_dir(), 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._sip_output_dir(), "-b", sbf, "-I", self._sip_sipfiles_dir(), source]) sip-4.19.7/sipgen/0000755000076500000240000000000013231604431013750 5ustar philstaff00000000000000sip-4.19.7/sipgen/export.c0000644000076500000240000006452413231604406015452 0ustar philstaff00000000000000/* * The XML and API file generator module for SIP. * * Copyright (c) 2015 Riverbank Computing Limited * * 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 #include #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 const char *pyType(sipSpec *pt, argDef *ad, int sec, classDef **scope); static int exportPythonSignature(sipSpec *pt, FILE *fp, signatureDef *sd, int sec, int names, int defaults, int in_str, int is_signal); /* * 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 = exportPythonSignature(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, "="); prDefaultValue(ad, in_str, fp); } 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, "\n"); fprintf(fp, "\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, "\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, "ecd, cd->pyname->text); fprintf(fp, "\"/>\n"); return; } if (!isHiddenNamespace(cd)) { xmlIndent(indent++, fp); fprintf(fp, "ecd, cd->pyname->text); fprintf(fp, "\""); if (cd->picklecode != NULL) fprintf(fp, " pickle=\"1\""); if (cd->convtocode != NULL) fprintf(fp, " convert=\"1\""); if (cd->convfromcode != NULL) fprintf(fp, " convertfrom=\"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"); } 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); } xmlEnums(pt, mod, cd, indent, fp); xmlVars(pt, mod, cd, indent, fp); for (md = cd->members; md != NULL; md = md->next) xmlFunction(pt, cd, md, cd->overs, indent, fp); if (!isHiddenNamespace(cd)) { xmlIndent(--indent, fp); fprintf(fp, "\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, "ecd, ed->pyname->text); fprintf(fp, "\">\n"); for (emd = ed->members; emd != NULL; emd = emd->next) { xmlIndent(indent, fp); fprintf(fp, "ecd, emd->pyname->text); fprintf(fp, "\"/>\n"); } xmlIndent(--indent, fp); fprintf(fp, "\n"); } else { enumMemberDef *emd; for (emd = ed->members; emd != NULL; emd = emd->next) { xmlIndent(indent, fp); fprintf(fp, "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, "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, "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, "\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, "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, "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 (isVirtual(od)) { fprintf(fp, " virtual=\"1\""); } 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, "\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, "defval && (dir == NULL || strcmp(dir, "out") != 0)) { prcode(fp, " default=\""); prDefaultValue(ad, FALSE, fp); prcode(fp, "\""); } 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; /* Suppress a compiler warning. */ default: ; } 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, " "); } /* * 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 capsule_type: type_name = scopedNameTail(ad->u.cap); break; 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: /* Correct for Python v3. */ type_name = "bytes"; break; case string_type: case sstring_type: case wstring_type: case ascii_string_type: case latin1_string_type: case utf8_string_type: type_name = isArray(ad) ? "bytes" : "str"; break; case byte_type: case sbyte_type: case ubyte_type: 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: case ssize_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 pybuffer_type: type_name = "buffer"; 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 Python signature. */ static int exportPythonSignature(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; if (is_signal) { if (sd->nrArgs != 0) fprintf(fp, "["); } else { fprintf(fp, "("); } 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; } if (is_signal) { if (sd->nrArgs != 0) fprintf(fp, "]"); } else { fprintf(fp, ")"); } 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; } sip-4.19.7/sipgen/extracts.c0000644000076500000240000000546413231604405015763 0ustar philstaff00000000000000/* * The extracts generator for SIP. * * Copyright (c) 2015 Riverbank Computing Limited * * 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 #include #include "sip.h" /* * Generate the extracts. */ void generateExtracts(sipSpec *pt, const stringList *extracts) { while (extracts != NULL) { const char *cp, *id, *fname; size_t id_len; extractDef *ed; extractPartDef *epd; FILE *fp; /* Extract the id and file name. */ cp = strchr(extracts->s, ':'); if (cp == NULL || cp == extracts->s || cp[1] == '\0') fatal("An extract must be in the form 'id:file', not '%s'\n", extracts->s); id = extracts->s; id_len = cp - extracts->s; fname = &cp[1]; for (ed = pt->extracts; ed != NULL; ed = ed->next) if (strlen(ed->id) == id_len && strncmp(ed->id, id, id_len) == 0) break; if (ed == NULL) fatal("There is no extract defined with the identifier \"%.*s\"\n", id_len, id); if ((fp = fopen(fname, "w")) == NULL) fatal("Unable to create file '%s'\n", fname); for (epd = ed->parts; epd != NULL; epd = epd->next) fprintf(fp, "%s", epd->part->frag); fclose(fp); extracts = extracts->next; } } /* * Add a new part to a (possibly new) extract. */ void addExtractPart(sipSpec *pt, const char *id, int order, codeBlock *part) { extractDef *ed; extractPartDef *epd, **at; /* Find the extract if it exists. */ for (ed = pt->extracts; ed != NULL; ed = ed->next) if (strcmp(ed->id, id) == 0) break; /* Create the extract if it doesn't already exist. */ if (ed == NULL) { ed = sipMalloc(sizeof (extractDef)); ed->id = id; ed->parts = NULL; ed->next = pt->extracts; pt->extracts = ed; } /* Find the position where the new part should be inserted. */ for (at = &ed->parts; *at != NULL; at = &(*at)->next) if (order >= 0 && ((*at)->order < 0 || order < (*at)->order)) break; /* Create the new part. */ epd = sipMalloc(sizeof (extractPartDef)); epd->order = order; epd->part = part; epd->next = *at; *at = epd; } sip-4.19.7/sipgen/gencode.c0000644000076500000240000135704513231604406015541 0ustar philstaff00000000000000/* * The code generator module for SIP. * * Copyright (c) 2018 Riverbank Computing Limited * * 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 #include #include #include #include #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) (!noSetter(vd) && ((vd)->type.nrderefs != 0 || !isConstArg(&(vd)->type))) /* Return TRUE if a module implements Qt support. */ #define moduleSupportsQt(pt, mod) ((pt)->qobject_cd != NULL && (pt)->qobject_cd->iff->module == (mod)) /* Control what generateCalledArgs() actually generates. */ typedef enum { Declaration, Definition } funcArgType; /* Control how scopes should be stripped. */ typedef enum { StripNone, StripGlobal, StripNamespace } StripAction; /* 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 *needed_qualifiers, stringList *xsl, int py_debug); static void generateCpp(sipSpec *pt, moduleDef *mod, const char *codeDir, const char *srcSuffix, int parts, stringList *needed_qualifiers, stringList *xsl, int py_debug); static void generateCompositeCpp(sipSpec *pt, const char *codeDir, int py_debug); 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 generateModDocstring(moduleDef *mod, FILE *fp); static void generateIfaceCpp(sipSpec *, int, ifaceFileDef *, int, const char *, const char *, FILE *); static void generateMappedTypeCpp(mappedTypeDef *mtd, sipSpec *pt, FILE *fp); static void generateImportedMappedTypeAPI(mappedTypeDef *mtd, moduleDef *mod, FILE *fp); static void generateMappedTypeAPI(sipSpec *pt, mappedTypeDef *mtd, FILE *fp); static void generateClassCpp(classDef *cd, sipSpec *pt, int py_debug, FILE *fp); static void generateImportedClassAPI(classDef *cd, moduleDef *mod, FILE *fp); static void generateClassAPI(classDef *cd, sipSpec *pt, FILE *fp); static void generateClassFunctions(sipSpec *pt, moduleDef *mod, classDef *cd, int py_debug, 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 generatePyObjects(sipSpec *pt, moduleDef *mod, FILE *fp); static void generateTypeDefinition(sipSpec *pt, classDef *cd, int py_debug, FILE *fp); static void generateTypeInit(classDef *, moduleDef *, FILE *); static void generateCppCodeBlock(codeBlockList *cbl, FILE *fp); 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(moduleDef *mod, signatureDef *sd, FILE *fp); static void deleteTemps(moduleDef *mod, signatureDef *sd, FILE *fp); static void gc_ellipsis(signatureDef *sd, FILE *fp); static void generateCallArgs(moduleDef *, signatureDef *, signatureDef *, FILE *); static void generateCalledArgs(moduleDef *, ifaceFileDef *, signatureDef *, funcArgType, FILE *); static void generateVariable(moduleDef *, ifaceFileDef *, argDef *, int, FILE *); static void generateNamedValueType(ifaceFileDef *, argDef *, char *, FILE *); static void generateBaseType(ifaceFileDef *, argDef *, int, StripAction, FILE *); static void generateNamedBaseType(ifaceFileDef *, argDef *, const char *, int, StripAction, FILE *); static void generateTupleBuilder(moduleDef *, signatureDef *, FILE *); static void generatePyQt5Emitters(classDef *cd, FILE *fp); static void generateVirtualHandler(moduleDef *mod, virtHandlerDef *vhd, FILE *fp); static void generateDefaultInstanceReturn(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 generateProtectedEnums(sipSpec *, classDef *, FILE *); static void generateProtectedDeclarations(classDef *, FILE *); static void generateProtectedDefinitions(moduleDef *, classDef *, FILE *); static void generateProtectedCallArgs(moduleDef *mod, signatureDef *sd, FILE *fp); static void generateConstructorCall(classDef *, ctorDef *, int, int, moduleDef *, FILE *); static void generateHandleResult(moduleDef *, 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 *, int, FILE *); static int generateResultVar(ifaceFileDef *scope, overDef *od, argDef *res, const char *indent, FILE *fp); static void generateFunctionCall(classDef *c_scope, mappedTypeDef *mt_scope, ifaceFileDef *o_scope, overDef *od, int deref, moduleDef *mod, FILE *fp); static void generateCppFunctionCall(moduleDef *mod, ifaceFileDef *scope, ifaceFileDef *o_scope, overDef *od, FILE *fp); static void generateSlotArg(moduleDef *mod, signatureDef *sd, int argnr, FILE *fp); static void generateComparisonSlotCall(moduleDef *mod, ifaceFileDef *scope, overDef *od, const char *op, const char *cop, int deref, FILE *fp); static void generateBinarySlotCall(moduleDef *mod, ifaceFileDef *scope, overDef *od, const char *op, int deref, FILE *fp); static void generateNumberSlotCall(moduleDef *mod, 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(moduleDef *mod, 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, int rgil); static void generateCatchBlock(moduleDef *mod, exceptionDef *xd, signatureDef *sd, FILE *fp, int rgil); 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 void generateVoidPtrCast(argDef *ad, 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, StripAction strip); static int isMultiArgSlot(memberDef *md); static int isIntArgSlot(memberDef *md); static int isInplaceSequenceSlot(memberDef *md); static int needErrorFlag(codeBlockList *cbl); static int needOldErrorFlag(codeBlockList *cbl); 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(moduleDef *mod, 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, codeBlockList *cbl); static int usedInCode(codeBlockList *cbl, const char *str); static void generateDefaultValue(moduleDef *mod, 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, int membernr, int optional_args, FILE *fp); static void generateTypesTable(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(argDef *ad); static void generateTypeDefName(ifaceFileDef *iff, FILE *fp); static void generateTypeDefLink(ifaceFileDef *iff, FILE *fp); static int overloadHasAutoDocstring(sipSpec *pt, overDef *od); static int hasMemberDocstring(sipSpec *pt, overDef *overs, memberDef *md, ifaceFileDef *scope); static int generateMemberDocstring(sipSpec *pt, overDef *overs, memberDef *md, int is_method, FILE *fp); static void generateMemberAutoDocstring(sipSpec *pt, overDef *od, int is_method, FILE *fp); static int ctorHasAutoDocstring(sipSpec *pt, ctorDef *ct); static int hasClassDocstring(sipSpec *pt, classDef *cd); static void generateClassDocstring(sipSpec *pt, classDef *cd, FILE *fp); static void generateCtorAutoDocstring(sipSpec *pt, classDef *cd, ctorDef *ct, FILE *fp); static void generateDocstringText(docstringDef *docstring, FILE *fp); static int copyConstRefArg(argDef *ad); static void generatePreprocLine(int linenr, const char *fname, FILE *fp); static int hasOptionalArgs(overDef *od); static int emptyIfaceFile(sipSpec *pt, ifaceFileDef *iff); static void declareLimitedAPI(int py_debug, moduleDef *mod, FILE *fp); static int generatePluginSignalsTable(sipSpec *pt, classDef *cd, const char *pyqt_prefix, FILE *fp); static int generatePyQt5ClassPlugin(sipSpec *pt, classDef *cd, FILE *fp); static int generatePyQt4ClassPlugin(sipSpec *pt, classDef *cd, FILE *fp); static void generateGlobalFunctionTableEntries(sipSpec *pt, moduleDef *mod, memberDef *members, FILE *fp); static void prTemplateType(FILE *fp, ifaceFileDef *scope, templateDef *td, StripAction strip); static int isString(argDef *ad); static scopedNameDef *stripScope(scopedNameDef *snd, classDef *ecd, StripAction strip); static void prEnumMemberScope(enumMemberDef *emd, FILE *fp); /* * 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 *needed_qualifiers, stringList *xsl, const char *consModule, int docs, int py_debug) { 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, py_debug); 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, needed_qualifiers, xsl, py_debug); generateConsolidatedCpp(pt, codeDir, srcSuffix); } else if (consModule != NULL) generateComponentCpp(pt, codeDir, consModule); else generateCpp(pt, pt->module, codeDir, srcSuffix, parts, needed_qualifiers, xsl, py_debug); } /* 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; codeBlockList *cbl; fp = createFile(pt->module, docFile, NULL); for (cbl = pt->docs; cbl != NULL; cbl = cbl->next) fputs(cbl->block->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 (emptyIfaceFile(pt, iff)) 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->cast != NULL) prcode(fp, "(%S)", vd->cast); if (vd->vunop != '\0') prcode(fp,"%c",vd->vunop); switch (vd->vtype) { case qchar_value: if (vd->u.vqchar == '"' && in_str) prcode(fp, "'\\\"'"); else prcode(fp, "'%c'", vd->u.vqchar); break; case string_value: { const char *cp, *quote = (in_str ? "\\\"" : "\""); prcode(fp, "%s", quote); for (cp = vd->u.vstr; *cp != '\0'; ++cp) { char ch = *cp; int escape; if (strchr("\\\"", ch) != NULL) { escape = TRUE; } else if (ch == '\n') { escape = TRUE; ch = 'n'; } else if (ch == '\r') { escape = TRUE; ch = 'r'; } else if (ch == '\t') { escape = TRUE; ch = 't'; } else { escape = FALSE; } prcode(fp, "%s%c", (escape ? "\\" : ""), ch); } prcode(fp, "%s", 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, removeGlobalScope(vd->u.vscp), "."); else prcode(fp, "%S", vd->u.vscp); break; case fcall_value: generateSimpleFunctionCall(vd->u.fcd, in_str, 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 *needed_qualifiers, stringList *xsl, int py_debug) { 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" , mname , mname); declareLimitedAPI(py_debug, mod, fp); prcode(fp, "\n" "#include \n" ); if (pluginPyQt4(pt) || pluginPyQt5(pt)) prcode(fp, "\n" "#include \n" "#include \n" ); /* Define the qualifiers. */ noIntro = TRUE; for (imp = pt->modules; imp != NULL; imp = imp->next) { qualDef *qd; for (qd = imp->qualifiers; qd != NULL; qd = qd->next) { const char *qtype = NULL; switch (qd->qtype) { case time_qualifier: if (selectedQualifier(needed_qualifiers, qd)) qtype = "TIMELINE"; break; case platform_qualifier: if (selectedQualifier(needed_qualifiers, qd)) qtype = "PLATFORM"; break; case feature_qualifier: if (!excludedFeature(xsl, qd)) qtype = "FEATURE"; break; } if (qtype != NULL) { if (noIntro) { prcode(fp, "\n" "/* These are the qualifiers that are enabled. */\n" ); noIntro = FALSE; } prcode(fp, "#define SIP_%s_%s\n" , qtype, qd->name); } } } if (!noIntro) prcode(fp, "\n" ); /* 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 sipCallProcedureMethod sipAPI_%s->api_call_procedure_method\n" "#define sipCallErrorHandler sipAPI_%s->api_call_error_handler\n" "#define sipParseResultEx sipAPI_%s->api_parse_result_ex\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 sipInstanceDestroyed sipAPI_%s->api_instance_destroyed\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 sipGetAddress sipAPI_%s->api_get_address\n" "#define sipGetMixinAddress sipAPI_%s->api_get_mixin_address\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 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 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 sipConvertToEnum sipAPI_%s->api_convert_to_enum\n" "#define sipConvertToBool sipAPI_%s->api_convert_to_bool\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 sipConvertFromNewPyType sipAPI_%s->api_convert_from_new_pytype\n" "#define sipConvertFromEnum sipAPI_%s->api_convert_from_enum\n" "#define sipGetState sipAPI_%s->api_get_state\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 sipInvokeSlotEx sipAPI_%s->api_invoke_slot_ex\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)->wt_td->td_cname)\n" "#define sipDeprecated sipAPI_%s->api_deprecated\n" "#define sipGetReference sipAPI_%s->api_get_reference\n" "#define sipKeepReference sipAPI_%s->api_keep_reference\n" "#define sipRegisterProxyResolver sipAPI_%s->api_register_proxy_resolver\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 sipSetDestroyOnExit sipAPI_%s->api_set_destroy_on_exit\n" "#define sipEnableAutoconversion sipAPI_%s->api_enable_autoconversion\n" "#define sipEnableOverflowChecking sipAPI_%s->api_enable_overflow_checking\n" "#define sipInitMixin sipAPI_%s->api_init_mixin\n" "#define sipExportModule sipAPI_%s->api_export_module\n" "#define sipInitModule sipAPI_%s->api_init_module\n" "#define sipGetInterpreter sipAPI_%s->api_get_interpreter\n" "#define sipSetNewUserTypeHandler sipAPI_%s->api_set_new_user_type_handler\n" "#define sipSetTypeUserData sipAPI_%s->api_set_type_user_data\n" "#define sipGetTypeUserData sipAPI_%s->api_get_type_user_data\n" "#define sipPyTypeDict sipAPI_%s->api_py_type_dict\n" "#define sipPyTypeName sipAPI_%s->api_py_type_name\n" "#define sipGetCFunction sipAPI_%s->api_get_c_function\n" "#define sipGetMethod sipAPI_%s->api_get_method\n" "#define sipFromMethod sipAPI_%s->api_from_method\n" "#define sipGetDate sipAPI_%s->api_get_date\n" "#define sipFromDate sipAPI_%s->api_from_date\n" "#define sipGetDateTime sipAPI_%s->api_get_datetime\n" "#define sipFromDateTime sipAPI_%s->api_from_datetime\n" "#define sipGetTime sipAPI_%s->api_get_time\n" "#define sipFromTime sipAPI_%s->api_from_time\n" "#define sipIsUserType sipAPI_%s->api_is_user_type\n" "#define sipGetFrame sipAPI_%s->api_get_frame\n" "#define sipCheckPluginForType sipAPI_%s->api_check_plugin_for_type\n" "#define sipUnicodeNew sipAPI_%s->api_unicode_new\n" "#define sipUnicodeWrite sipAPI_%s->api_unicode_write\n" "#define sipUnicodeData sipAPI_%s->api_unicode_data\n" "#define sipGetBufferInfo sipAPI_%s->api_get_buffer_info\n" "#define sipReleaseBufferInfo sipAPI_%s->api_release_buffer_info\n" "#define sipIsOwnedByPython sipAPI_%s->api_is_owned_by_python\n" "#define sipIsDerivedClass sipAPI_%s->api_is_derived_class\n" "#define sipGetUserObject sipAPI_%s->api_get_user_object\n" "#define sipSetUserObject sipAPI_%s->api_set_user_object\n" "#define sipRegisterEventHandler sipAPI_%s->api_register_event_handler\n" "#define sipLong_AsChar sipAPI_%s->api_long_as_char\n" "#define sipLong_AsSignedChar sipAPI_%s->api_long_as_signed_char\n" "#define sipLong_AsUnsignedChar sipAPI_%s->api_long_as_unsigned_char\n" "#define sipLong_AsShort sipAPI_%s->api_long_as_short\n" "#define sipLong_AsUnsignedShort sipAPI_%s->api_long_as_unsigned_short\n" "#define sipLong_AsInt sipAPI_%s->api_long_as_int\n" "#define sipLong_AsUnsignedInt sipAPI_%s->api_long_as_unsigned_int\n" "#define sipLong_AsLong sipAPI_%s->api_long_as_long\n" "#define sipLong_AsUnsignedLong sipAPI_%s->api_long_as_unsigned_long\n" "#define sipLong_AsLongLong sipAPI_%s->api_long_as_long_long\n" "#define sipLong_AsUnsignedLongLong sipAPI_%s->api_long_as_unsigned_long_long\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 sipConvertToArray sipAPI_%s->api_convert_to_array\n" "#define sipConvertToTypedArray sipAPI_%s->api_convert_to_typed_array\n" "#define sipEnableGC sipAPI_%s->api_enable_gc\n" "#define sipPrintObject sipAPI_%s->api_print_object\n" "#define sipWrapper_Check(w) PyObject_TypeCheck((w), sipAPI_%s->api_wrapper_type)\n" "#define sipGetWrapper(p, wt) sipGetPyObject((p), (wt)->wt_td)\n" "#define sipReleaseInstance(p, wt, s) sipReleaseType((p), (wt)->wt_td, (s))\n" "#define sipReleaseMappedType sipReleaseType\n" "#define sipCanConvertToInstance(o, wt, f) sipCanConvertToType((o), (wt)->wt_td, (f))\n" "#define sipCanConvertToMappedType sipCanConvertToType\n" "#define sipConvertToInstance(o, wt, t, f, s, e) sipConvertToType((o), (wt)->wt_td, (t), (f), (s), (e))\n" "#define sipConvertToMappedType sipConvertToType\n" "#define sipForceConvertToInstance(o, wt, t, f, s, e) sipForceConvertToType((o), (wt)->wt_td, (t), (f), (s), (e))\n" "#define sipForceConvertToMappedType sipForceConvertToType\n" "#define sipConvertFromInstance(p, wt, t) sipConvertFromType((p), (wt)->wt_td, (t))\n" "#define sipConvertFromMappedType sipConvertFromType\n" "#define sipConvertFromNamedEnum(v, pt) sipConvertFromEnum((v), ((sipEnumTypeObject *)(pt))->type)\n" "#define sipConvertFromNewInstance(p, wt, t) sipConvertFromNewType((p), (wt)->wt_td, (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 ,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); 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); if (mod->nr_needed_types > 0) prcode(fp, "extern sipTypeDef *sipExportedTypes_%s[];\n" , mname); for (mld = mod->allimports; mld != NULL; mld = mld->next) { generateImportedModuleAPI(pt, mod, mld->module, fp); if (mld->module->nr_needed_types > 0) prcode(fp, "extern sipImportedTypeDef sipImportedTypes_%s_%s[];\n" , mname, mld->module->name); if (mld->module->nrvirterrorhandlers > 0) prcode(fp, "extern sipImportedVirtErrorHandlerDef sipImportedVirtErrorHandlers_%s_%s[];\n" , mname, mld->module->name); if (mld->module->nrexceptions > 0) prcode(fp, "extern sipImportedExceptionDef sipImportedExceptions_%s_%s[];\n" , mname, mld->module->name); } if (pluginPyQt4(pt) || pluginPyQt5(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" , mname , mname); if (pluginPyQt5(pt)) prcode(fp, "typedef bool (*sip_qt_metacast_func)(sipSimpleWrapper *, const sipTypeDef *, const char *, void **);\n" ); else prcode(fp, "typedef int (*sip_qt_metacast_func)(sipSimpleWrapper *, sipTypeDef *, const char *);\n" ); prcode(fp, "extern sip_qt_metacast_func sip_%s_qt_metacast;\n" , mname); } /* Handwritten code. */ generateCppCodeBlock(pt->exphdrcode, fp); generateCppCodeBlock(mod->hdrcode, fp); /* * Make sure any header code needed by the default exception is included. */ if (mod->defexception != NULL) generateCppCodeBlock(mod->defexception->iff->hdrcode, fp); /* * 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, int py_debug) { char *cppfile; const char *fullname = pt->module->fullname->text; moduleDef *mod; FILE *fp; cppfile = concat(codeDir, "/sip", pt->module->name, "cmodule.c", NULL); fp = createCompilationUnit(pt->module, cppfile, "Composite module code."); declareLimitedAPI(py_debug, NULL, fp); prcode(fp, "\n" "#include \n" "\n" "\n" "static void sip_import_component_module(PyObject *d, const char *name)\n" "{\n" " PyObject *mod;\n" "\n" " PyErr_Clear();\n" "\n" "#if PY_VERSION_HEX >= 0x02050000\n" " mod = PyImport_ImportModule(name);\n" "#else\n" " 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" ); generateModDocstring(pt->module, fp); 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" "#elif PY_VERSION_HEX >= 0x02050000\n" ); if (pt->module->docstring == NULL) prcode(fp, " sipModule = Py_InitModule(\"%s\", NULL);\n" "#else\n" " sipModule = Py_InitModule((char *)\"%s\", NULL);\n" , fullname , fullname); else prcode(fp, " sipModule = Py_InitModule3(\"%s\", NULL, doc_mod_%s);\n" "#else\n" " Py_InitModule3((char *)\"%s\", NULL, doc_mod_%s);\n" , fullname, pt->module->name , fullname, pt->module->name); prcode(fp, "#endif\n" "\n" " if (sipModule == NULL)\n" " SIP_MODULE_RETURN(NULL);\n" "\n" " sipModuleDict = PyModule_GetDict(sipModule);\n" "\n" ); 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; const char *fullname = pt->module->fullname->text; moduleDef *mod; FILE *fp; cppfile = concat(codeDir, "/sip", mname, "cmodule", srcSuffix, NULL); fp = createCompilationUnit(pt->module, cppfile, "Consolidated module code."); prcode(fp, "\n" "#include \n" "#include \n" "#include \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" ); generateModDocstring(pt->module, fp); 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" "#elif PY_VERSION_HEX >= 0x02050000\n" ); if (pt->module->docstring == NULL) prcode(fp, " Py_InitModule(\"%s\", sip_methods);\n" , fullname); else prcode(fp, " Py_InitModule3(\"%s\", sip_methods, doc_mod_%s);\n" , fullname, mname); prcode(fp, "#else\n" ); if (generating_c) { if (pt->module->docstring == NULL) prcode(fp, " Py_InitModule((char *)\"%s\", sip_methods);\n" , fullname); else prcode(fp, " Py_InitModule3((char *)\"%s\", sip_methods, doc_mod_%s);\n" , fullname, mname); } else { if (pt->module->docstring == NULL) prcode(fp, " Py_InitModule(const_cast(\"%s\"), sip_methods);\n" , fullname); else prcode(fp, " Py_InitModule3(const_cast(\"%s\"), sip_methods, doc_mod_%s);\n" , fullname, mname); } prcode(fp, "#endif\n" "}\n" ); 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 \n" ); generateModInitStart(pt->module, TRUE, 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 *needed_qualifiers, stringList *xsl, int py_debug) { char *cppfile; const char *mname = mod->name; int nrSccs = 0, files_in_part, max_per_part, this_part, 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; int hasvirterrorhandlers = FALSE; FILE *fp; moduleListDef *mld; classDef *cd; memberDef *md; enumDef *ed; ifaceFileDef *iff; virtHandlerDef *vhd; virtErrorHandler *veh; 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); generateCppCodeBlock(mod->unitpostinccode, 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 (moduleSupportsQt(pt, mod)) 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 handlers. */ for (vhd = pt->virthandlers; vhd != NULL; vhd = vhd->next) generateVirtualHandler(mod, vhd, fp); /* Generate any virtual error handlers. */ for (veh = pt->errorhandlers; veh != NULL; veh = veh->next) { if (veh->mod == mod) { prcode(fp, "\n" "\n" "void sipVEH_%s_%s(sipSimpleWrapper *%s, sip_gilstate_t%s)\n" "{\n" , mname, veh->name, (usedInCode(veh->code, "sipPySelf") ? "sipPySelf" : ""), (usedInCode(veh->code, "sipGILState") ? " sipGILState" : "")); generateCppCodeBlock(veh->code, fp); prcode(fp, "}\n" ); } } /* 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 the global functions for any hidden namespaces. */ for (cd = pt->classes; cd != NULL; cd = cd->next) { if (cd->iff->module == mod && isHiddenNamespace(cd)) { for (md = cd->members; md != NULL; md = md->next) { if (md->slot == no_slot) generateOrdinaryFunction(pt, mod, cd, NULL, md, fp); } } } /* 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_type_%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 (md->slot == long_slot) prcode(fp, "#else\n" " {(void *)slot_%s, %s, {0, 0, 0}},\n" , md->pyname->text, slotName(int_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 (md->slot == long_slot) { prcode(fp, "#else\n" " {(void *)slot_%L_%s, %s, ", cd->iff, md->pyname->text, slotName(int_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, removeGlobalScope(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 (slot->slot == long_slot) prcode(fp, "#else\n" " {(void *)slot_%C_%s, %s},\n" , ed->fqcname, slot->pyname->text, slotName(int_slot)); 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_%s, %n, {0}, 0}, %n, %d, ", (isScopedEnum(ed) ? "SCOPED_ENUM" : "ENUM"), 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->nr_needed_types > 0) generateTypesTable(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, " {\"%V\", \"", 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 generateBaseType(NULL, &td->type, FALSE, StripGlobal, fp); prcode(fp, "\"},\n" ); } prcode(fp, "};\n" ); } for (veh = pt->errorhandlers; veh != NULL; veh = veh->next) { if (veh->mod == mod) { if (!hasvirterrorhandlers) { hasvirterrorhandlers = TRUE; prcode(fp, "\n" "\n" "/*\n" " * This defines the virtual error handlers that this module implements and\n" " * can be used by other modules.\n" " */\n" "static sipVirtErrorHandlerDef virtErrorHandlersTable[] = {\n" ); } prcode(fp, " {\"%s\", sipVEH_%s_%s},\n" , veh->name, mname, veh->name); } } if (hasvirterrorhandlers) prcode(fp, " {NULL, NULL}\n" "};\n" ); if (mod->allimports != NULL) { for (mld = mod->allimports; mld != NULL; mld = mld->next) { int i; if (mld->module->nr_needed_types > 0) { prcode(fp, "\n" "\n" "/* This defines the types that this module needs to import from %s. */\n" "sipImportedTypeDef sipImportedTypes_%s_%s[] = {\n" , mld->module->name , mname, mld->module->name); for (i = 0; i < mld->module->nr_needed_types; ++i) { argDef *ad = &mld->module->needed_types[i]; if (ad->atype == mapped_type) prcode(fp, " {\"%s\"},\n" , ad->u.mtd->cname->text); else prcode(fp, " {\"%V\"},\n" , getFQCNameOfType(ad)); } prcode(fp, " {NULL}\n" "};\n" ); } if (mld->module->nrvirterrorhandlers > 0) { int i; prcode(fp, "\n" "\n" "/*\n" " * This defines the virtual error handlers that this module needs to import\n" " * from %s.\n" " */\n" "sipImportedVirtErrorHandlerDef sipImportedVirtErrorHandlers_%s_%s[] = {\n" , mld->module->name , mname, mld->module->name); /* * The handlers are unordered so search for each in turn. * There will probably be only one so speed isn't an issue. */ for (i = 0; i < mld->module->nrvirterrorhandlers; ++i) { virtErrorHandler *veh; for (veh = pt->errorhandlers; veh != NULL; veh = veh->next) { if (veh->mod == mld->module && veh->index == i) { prcode(fp, " {\"%s\"},\n" , veh->name); } } } prcode(fp, " {NULL}\n" "};\n" ); } if (mld->module->nrexceptions > 0) { int i; prcode(fp, "\n" "\n" "/*\n" " * This defines the exception objects that this module needs to import from\n" " * %s.\n" " */\n" "sipImportedExceptionDef sipImportedExceptions_%s_%s[] = {\n" , mld->module->name , mname, mld->module->name); /* * The exceptions are unordered so search for each in turn. * There will probably be very few so speed isn't an issue. */ for (i = 0; i < mld->module->nrexceptions; ++i) { exceptionDef *xd; for (xd = pt->exceptions; xd != NULL; xd = xd->next) { if (xd->iff->module == mld->module && xd->exceptionnr == i) { prcode(fp, " {\"%s\"},\n" , xd->pyname); } } } prcode(fp, " {NULL}\n" "};\n" ); } } 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\", ", mld->module->fullname->text); if (mld->module->nr_needed_types > 0) prcode(fp, "sipImportedTypes_%s_%s, ", mname, mld->module->name); else prcode(fp, "NULL, "); if (mld->module->nrvirterrorhandlers > 0) prcode(fp, "sipImportedVirtErrorHandlers_%s_%s, ", mname, mld->module->name); else prcode(fp, "NULL, "); if (mld->module->nrexceptions > 0) prcode(fp, "sipImportedExceptions_%s_%s", mname, mld->module->name); else prcode(fp, "NULL"); prcode(fp, "},\n" ); } prcode(fp, " {NULL, NULL, NULL, 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" "PyObject *sipExportedExceptions_%s[%d];\n" , mname, mod->nrexceptions + 1); /* 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 = hasMemberDocstring(pt, mod->overs, md, NULL); /* * 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) || useKeywordArgs(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 (moduleSupportsQt(pt, mod)) prcode(fp, "\n" "\n" "/* This defines the Qt support API. */\n" "\n" "static sipQtAPI qtAPI = {\n" " &sipExportedTypes_%s[%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" , mname, pt->qobject_cd->iff->ifacenr); prcode(fp, "\n" "\n" "/* This defines this module. */\n" "sipExportedModuleDef sipModuleAPI_%s = {\n" " 0,\n" " SIP_API_MINOR_NR,\n" " %n,\n" " 0,\n" " sipStrings_%s,\n" " %s,\n" " %s,\n" " %d,\n" , mname , mod->fullname , pt->module->name , mod->allimports != NULL ? "importsTable" : "NULL" , moduleSupportsQt(pt, mod) ? "&qtAPI" : "NULL" , mod->nr_needed_types); if (mod->nr_needed_types > 0) prcode(fp, " sipExportedTypes_%s,\n" , mname); else prcode(fp, " NULL,\n" ); prcode(fp, " %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" , hasexternal ? "externalTypesTable" : "NULL" , nr_enummembers , nr_enummembers > 0 ? "enummembers" : "NULL" , mod->nrtypedefs , mod->nrtypedefs > 0 ? "typedefsTable" : "NULL" , hasvirterrorhandlers ? "virtErrorHandlersTable" : "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"); if (mod->nrexceptions > 0) prcode(fp, " sipExportedExceptions_%s,\n" , mname); else prcode(fp, " NULL,\n" ); prcode(fp, " %s,\n" " %s,\n" " %s,\n" " NULL,\n" " %s,\n" " %s\n" "};\n" , slot_extenders ? "slotExtenders" : "NULL" , ctor_extenders ? "initExtenders" : "NULL" , hasDelayedDtors(mod) ? "sipDelayedDtors" : "NULL" , is_api_versions ? "apiVersions" : "NULL" , is_versioned_functions ? "versionedFunctions" : "NULL"); generateModDocstring(mod, fp); /* 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); if (pluginPyQt4(pt) || pluginPyQt5(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" ); generateGlobalFunctionTableEntries(pt, mod, mod->othfuncs, fp); /* Generate the global functions for any hidden namespaces. */ for (cd = pt->classes; cd != NULL; cd = cd->next) if (cd->iff->module == mod && isHiddenNamespace(cd)) generateGlobalFunctionTableEntries(pt, mod, cd->members, fp); 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" ); if (mod->docstring == NULL) prcode(fp, " sipModule = Py_InitModule(%N, sip_methods);\n" , mod->fullname); else prcode(fp, " sipModule = Py_InitModule3(%N, sip_methods, doc_mod_%s);\n" , mod->fullname, mname); prcode(fp, "#else\n" ); if (generating_c) { if (mod->docstring == NULL) prcode(fp, " sipModule = Py_InitModule((char *)%N, sip_methods);\n" , mod->fullname); else prcode(fp, " sipModule = Py_InitModule3((char *)%N, sip_methods, doc_mod_%s);\n" , mod->fullname, mname); } else { if (mod->docstring == NULL) prcode(fp, " sipModule = Py_InitModule(const_cast(%N), sip_methods);\n" , mod->fullname); else prcode(fp, " sipModule = Py_InitModule3(const_cast(%N), sip_methods, doc_mod_%s);\n" , mod->fullname, mname); } 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" " SIP_MODULE_DISCARD(sipModule);\n" " SIP_MODULE_RETURN(0);\n" " }\n" , mname); if (pluginPyQt4(pt) || pluginPyQt5(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" " if (!sip_%s_qt_metacast)\n" " Py_FatalError(\"Unable to import qtcore_qt_metacast\");\n" "\n" , mname , 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" " SIP_MODULE_DISCARD(sipModule);\n" " SIP_MODULE_RETURN(0);\n" " }\n" , mname); generateTypesInline(pt, mod, fp); generatePyObjects(pt, mod, fp); /* Create any exception objects. */ for (xd = pt->exceptions; xd != NULL; xd = xd->next) { if (xd->iff->module != mod) continue; if (xd->exceptionnr < 0) continue; prcode(fp, "\n" " if ((sipExportedExceptions_%s[%d] = PyErr_NewException(\n" "#if PY_MAJOR_VERSION >= 3\n" " \"%s.%s\",\n" "#else\n" " const_cast(\"%s.%s\"),\n" "#endif\n" " " , xd->iff->module->name, 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 prcode(fp, "sipException_%C", xd->base->iff->fqcname); prcode(fp, ",NULL)) == NULL || PyDict_SetItemString(sipModuleDict, \"%s\", sipExportedExceptions_%s[%d]) < 0)\n" " {\n" " SIP_MODULE_DISCARD(sipModule);\n" " SIP_MODULE_RETURN(0);\n" " }\n" , xd->pyname, xd->iff->module->name, xd->exceptionnr); } if (mod->nrexceptions > 0) prcode(fp, "\n" " sipExportedExceptions_%s[%d] = NULL;\n" , mname, mod->nrexceptions); /* Generate the interface source files. */ /* 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) { int need_postinc; 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); need_postinc = TRUE; } else { need_postinc = FALSE; } generateIfaceCpp(pt, py_debug, iff, need_postinc, codeDir, srcSuffix, ((parts && iff->file_extension == NULL) ? 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, needed_qualifiers, xsl, py_debug); } /* * Generate the types table for a module. */ static void generateTypesTable(moduleDef *mod, FILE *fp) { int i; argDef *ad; prcode(fp, "\n" "\n" "/*\n" " * This defines each type in this module.\n" " */\n" "sipTypeDef *sipExportedTypes_%s[] = {\n" , mod->name); for (ad = mod->needed_types, i = 0; i < mod->nr_needed_types; ++i, ++ad) { switch (ad->atype) { case class_type: if (isExternal(ad->u.cd)) prcode(fp, " 0,\n" ); else if (!isHiddenNamespace(ad->u.cd)) prcode(fp, " &sipTypeDef_%s_%L.ctd_base,\n" , mod->name, ad->u.cd->iff); 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; /* Supress a compiler warning. */ default: ; } } prcode(fp, "};\n" ); } /* * Generate the code to import the sip module and get its API. */ static void generateSipImport(moduleDef *mod, FILE *fp) { /* * Note that we don't use PyCapsule_Import() because it doesn't handle * package.module.attribute. */ prcode(fp, " /* Get the SIP module's API. */\n" "#if PY_VERSION_HEX >= 0x02050000\n" " sip_sipmod = PyImport_ImportModule(SIP_MODULE_NAME);\n" "#else\n" ); if (generating_c) prcode(fp, " sip_sipmod = PyImport_ImportModule((char *)SIP_MODULE_NAME);\n" ); else prcode(fp, " sip_sipmod = PyImport_ImportModule(const_cast(SIP_MODULE_NAME));\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" " Py_DECREF(sip_sipmod);\n" "\n" "#if defined(SIP_USE_PYCAPSULE)\n" " if (sip_capiobj == NULL || !PyCapsule_CheckExact(sip_capiobj))\n" "#else\n" " if (sip_capiobj == NULL || !PyCObject_Check(sip_capiobj))\n" "#endif\n" " {\n" " SIP_MODULE_DISCARD(sipModule);\n" " SIP_MODULE_RETURN(NULL);\n" " }\n" "\n" ); if (generating_c) prcode(fp, "#if defined(SIP_USE_PYCAPSULE)\n" " sipAPI_%s = (const sipAPIDef *)PyCapsule_GetPointer(sip_capiobj, SIP_MODULE_NAME \"._C_API\");\n" "#else\n" " sipAPI_%s = (const sipAPIDef *)PyCObject_AsVoidPtr(sip_capiobj);\n" "#endif\n" , mod->name , mod->name); else prcode(fp, "#if defined(SIP_USE_PYCAPSULE)\n" " sipAPI_%s = reinterpret_cast(PyCapsule_GetPointer(sip_capiobj, SIP_MODULE_NAME \"._C_API\"));\n" "#else\n" " sipAPI_%s = reinterpret_cast(PyCObject_AsVoidPtr(sip_capiobj));\n" "#endif\n" "\n" , mod->name , mod->name); prcode(fp, "#if defined(SIP_USE_PYCAPSULE)\n" " if (sipAPI_%s == NULL)\n" " {\n" " SIP_MODULE_DISCARD(sipModule);\n" " SIP_MODULE_RETURN(NULL);\n" " }\n" "#endif\n" "\n" , mod->name); } /* * Generate the variables needed by generateSipImport(). */ static void generateSipImportVariables(FILE *fp) { prcode(fp, " PyObject *sip_sipmod, *sip_capiobj;\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(%s)\n" "#else\n" "PyMODINIT_FUNC SIP_MODULE_ENTRY(%s)\n" "#endif\n" "{\n" , mod->name , mod->name , (gen_c ? "" : "extern \"C\" "), (gen_c ? "void" : "") , (gen_c ? "void" : "")); } /* * 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" , mod->fullname->text); if (mod->docstring == NULL) prcode(fp, " NULL,\n" ); else prcode(fp, " doc_mod_%s,\n" , mod->name); prcode(fp, " -1,\n" " %s,\n" " NULL,\n" " NULL,\n" " NULL,\n" " NULL\n" " };\n" "#endif\n" , 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->wt_td : 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; const char *kw_fw_decl, *kw_decl; if (mt_scope != NULL) { scope = mt_scope->iff; od = mt_scope->overs; } else if (c_scope != NULL) { scope = (isHiddenNamespace(c_scope) ? NULL : c_scope->iff); od = c_scope->overs; } else { scope = NULL; od = mod->overs; } prcode(fp, "\n" "\n" ); /* Generate the docstrings. */ if (hasMemberDocstring(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); has_auto_docstring = generateMemberDocstring(pt, od, md, FALSE, fp); prcode(fp, "\");\n" "\n" ); } else { has_auto_docstring = FALSE; } if (noArgParser(md) || useKeywordArgs(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; classDef *ps = pyScope(ed->ecd); if (ed->module != mod) continue; if (cd != NULL) { if (ps != cd || (isProtectedEnum(ed) && !hasShadow(cd))) continue; } else if (mtd != NULL) { if (ed->emtd != mtd) continue; } else if (ps != 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; classDef *ps = pyScope(ed->ecd); if (ed->module != mod) continue; if (cd != NULL) { if (ps != cd) continue; } else if (mtd != NULL) { if (ed->emtd != mtd) continue; } else if (ps != 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 (!generating_c) prcode(fp, "static_cast("); if (!isNoScope(emd->ed)) { if (isScopedEnum(emd->ed)) prcode(fp, "::%s", emd->ed->cname->text); else if (emd->ed->ecd != NULL) prEnumMemberScope(emd, fp); else if (mtd != NULL) prcode(fp, "%S", mtd->iff->fqcname); prcode(fp, "::"); } prcode(fp, "%s%s, %d},\n", emd->cname, (generating_c ? "" : ")"), 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 Python objects to a module * dictionary. Note that we should add these via a table (like int, etc) but * that will require a major API version change so this will do for now. */ static void generatePyObjects(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 != pyobject_type && vd->type.atype != pytuple_type && vd->type.atype != pylist_type && vd->type.atype != pydict_type && vd->type.atype != pycallable_type && vd->type.atype != pyslice_type && vd->type.atype != pytype_type && vd->type.atype != pybuffer_type) continue; if (needsHandler(vd)) continue; if (noIntro) { prcode(fp, "\n" " /* Define the Python objects wrapped as such. */\n" ); noIntro = FALSE; } prcode(fp, " PyDict_SetItemString(sipModuleDict, %N, %S);\n" , vd->pyname, vd->fqcname); } } /* * 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 (pyScope(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 (pyScope(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|SIP_NOT_IN_MAP", vd->fqcname, vcname); } else if (vd->type.nrderefs != 0) { /* This may be a bit heavy handed. */ if (isConstArg(&vd->type)) prcode(fp, "(void *)"); 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 (pyScope(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 (pyScope(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) && 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, (cd != NULL ? vd->fqcname : vd->fqcname->next), getEncoding(&vd->type)); } 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; const char *cast; char encoding; if (pyScope(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) && vd->type.nrderefs != 0) || vtype == wstring_type)) 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; } /* This is the hack for handling wchar_t and wchar_t*. */ encoding = getEncoding(&vd->type); if (encoding == 'w') cast = "(const char *)&"; else if (encoding == 'W') cast = "(const char *)"; else cast = ""; prcode(fp, " {%N, %s%S, '%c'},\n" , vd->pyname, cast, (cd != NULL ? vd->fqcname : vd->fqcname->next), encoding); } 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 (pyScope(vd->ecd) != cd || vd->module != mod) continue; if (!(vtype == enum_type || vtype == byte_type || vtype == sbyte_type || vtype == ubyte_type || vtype == ushort_type || vtype == short_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, (cd != NULL ? vd->fqcname : vd->fqcname->next)); } /* 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; /* * We treat unsigned as unsigned long as we don't (currently anyway) * generate a table for unsigned. */ if (vtype == uint_type && atype == ulong_type) vtype = ulong_type; if (pyScope(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, (cd != NULL ? vd->fqcname : vd->fqcname->next)); } 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 (pyScope(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, (cd != NULL ? vd->fqcname : vd->fqcname->next)); } if (!noIntro) prcode(fp, " {0, 0}\n" "};\n" ); return !noIntro; } /* * See if an interface file has any content. */ static int emptyIfaceFile(sipSpec *pt, ifaceFileDef *iff) { classDef *cd; mappedTypeDef *mtd; for (cd = pt->classes; cd != NULL; cd = cd->next) if (!isHiddenNamespace(cd) && !isProtectedClass(cd) && !isExternal(cd) && cd->iff == iff) return FALSE; for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next) if (mtd->iff == iff) return FALSE; return TRUE; } /* * Generate the C/C++ code for an interface. */ static void generateIfaceCpp(sipSpec *pt, int py_debug, ifaceFileDef *iff, int need_postinc, const char *codeDir, const char *srcSuffix, FILE *master) { char *cppfile; const char *cmname = iff->module->name; classDef *cd; mappedTypeDef *mtd; FILE *fp; /* * Check that there will be something in the file so that we don't get * warning messages from ranlib. */ if (emptyIfaceFile(pt, iff)) return; 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); need_postinc = TRUE; } else { fp = master; /* Suppress a compiler warning. */ cppfile = NULL; } prcode(fp, "\n" ); generateCppCodeBlock(iff->hdrcode, fp); generateUsedIncludes(iff->used, fp); if (need_postinc) generateCppCodeBlock(iff->module->unitpostinccode, 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 (isExternal(cd)) continue; if (cd->iff == iff) { classDef *pcd; generateClassCpp(cd, pt, py_debug, fp); /* Generate any enclosed protected classes. */ for (pcd = pt->classes; pcd != NULL; pcd = pcd->next) if (isProtectedClass(pcd) && pcd->ecd == cd) generateClassCpp(pcd, pt, py_debug, 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); } if (iff->file_extension != NULL) suffix = iff->file_extension; 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; generateCppCodeBlock(mtd->typecode, fp); if (!noRelease(mtd)) { /* * Generate the assignment helper. Note that the source pointer is not * const. This is to allow the source instance to be modified as a * consequence of the assignment, eg. if it is implementing some sort * of reference counting scheme. */ prcode(fp, "\n" "\n" ); if (!generating_c) prcode(fp, "extern \"C\" {static void assign_%L(void *, SIP_SSIZE_T, void *);}\n" , mtd->iff); prcode(fp, "static void assign_%L(void *sipDst, SIP_SSIZE_T sipDstIdx, void *sipSrc)\n" "{\n" , mtd->iff); if (generating_c) prcode(fp, " ((%b *)sipDst)[sipDstIdx] = *((%b *)sipSrc);\n" , &mtd->type, &mtd->type); else prcode(fp, " reinterpret_cast<%b *>(sipDst)[sipDstIdx] = *reinterpret_cast<%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(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(mtd->iff, fp); prcode(fp, ",\n" " 0,\n" " %sSIP_TYPE_MAPPED,\n" " %n, /* %s */\n" " {0},\n" " 0\n" " },\n" " {\n" , (handlesNone(mtd) ? "SIP_TYPE_ALLOW_NONE|" : "") , mtd->cname, mtd->cname->text); 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(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 prcode(fp, ".ctd_base"); } else prcode(fp, "0"); } /* * Generate the C++ code for a class. */ static void generateClassCpp(classDef *cd, sipSpec *pt, int py_debug, FILE *fp) { moduleDef *mod = cd->iff->module; /* Generate any local class code. */ generateCppCodeBlock(cd->cppcode, fp); generateClassFunctions(pt, mod, cd, py_debug, fp); generateAccessFunctions(pt, mod, cd, fp); if (cd->iff->type != namespace_iface) { generateConvertToDefinitions(NULL,cd,fp); /* Generate the optional from type convertor. */ if (cd->convfromcode != NULL) { int need_xfer; need_xfer = (generating_c || usedInCode(cd->convfromcode, "sipTransferObj")); prcode(fp, "\n" "\n" ); if (!generating_c) prcode(fp, "extern \"C\" {static PyObject *convertFrom_%L(void *, PyObject *);}\n" , cd->iff); prcode(fp, "static PyObject *convertFrom_%L(void *sipCppV, PyObject *%s)\n" "{\n" " ", cd->iff, (need_xfer ? "sipTransferObj" : "")); generateClassFromVoid(cd, "sipCpp", "sipCppV", fp); prcode(fp, ";\n" "\n" ); generateCppCodeBlock(cd->convfromcode, fp); prcode(fp, "}\n" ); } } /* The type definition structure. */ generateTypeDefinition(pt, cd, py_debug, 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; if (noArgParser(md) || useKeywordArgs(md)) { cast = "(PyCFunction)"; flags = "|METH_KEYWORDS"; } else { cast = ""; flags = ""; } /* Save the index in the table. */ md->membernr = i; prcode(fp, " {SIP_MLNAME_CAST(%N), %smeth_%L_%s, METH_VARARGS%s, ", md->pyname, cast, iff, md->pyname->text, flags); if (hasMemberDocstring(pt, overs, md, iff)) 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) { codeBlockList *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, *second_arg, *last_arg; int needsNew; if (keepPyReference(&vd->type)) vd->type.key = vd->module->next_key--; if (generating_c || !isStaticVar(vd)) first_arg = "sipSelf"; else first_arg = ""; last_arg = (generating_c || usedInCode(vd->getcode, "sipPyType")) ? "sipPyType" : ""; needsNew = ((atype == class_type || atype == mapped_type) && vd->type.nrderefs == 0 && isConstArg(&vd->type)); second_arg = (generating_c || (vd->type.key < 0 && !isStaticVar(vd))) ? "sipPySelf" : ""; prcode(fp, "\n" "\n" ); if (!generating_c) prcode(fp, "extern \"C\" {static PyObject *varget_%C(void *, PyObject *, PyObject *);}\n" , vd->fqcname); prcode(fp, "static PyObject *varget_%C(void *%s, PyObject *%s, PyObject *%s)\n" "{\n" , vd->fqcname, first_arg, second_arg, last_arg); if (vd->getcode != NULL) { prcode(fp, " PyObject *sipPy;\n" ); } else if (vd->type.key < 0) { if (isStaticVar(vd)) prcode(fp, " static PyObject *sipPy = NULL;\n" ); else prcode(fp, " PyObject *sipPy;\n" ); } if (vd->getcode == NULL) { prcode(fp, " "); generateNamedValueType(scope, &vd->type, "sipVal", fp); prcode(fp, ";\n" ); } if (!isStaticVar(vd)) { if (generating_c) prcode(fp, " struct %S *sipCpp = (struct %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; } if (vd->type.key < 0) { if (isStaticVar(vd)) { prcode(fp, " if (sipPy)\n" " {\n" " Py_INCREF(sipPy);\n" " return sipPy;\n" " }\n" "\n" ); } else { prcode(fp, " sipPy = sipGetReference(sipPySelf, %d);\n" " if (sipPy)\n" " return sipPy;\n" "\n" , vd->type.key); } } 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, " %s sipConvertFrom%sType(", (vd->type.key < 0 ? "sipPy =" : "return"), (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); if (vd->type.key < 0) { if (isStaticVar(vd)) prcode(fp, " Py_XINCREF(sipPy);\n" ); else prcode(fp, " sipKeepReference(sipPySelf, %d, sipPy);\n" , vd->type.key); prcode(fp, "\n" " return sipPy;\n" ); } } 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) { const char *cast_prefix, *cast_suffix; if (generating_c) { cast_prefix = cast_suffix = ""; } else { cast_prefix = "static_cast("; cast_suffix = ")"; } prcode(fp, " return sipConvertFromEnum(%ssipVal%s, sipType_%C);\n" , cast_prefix, cast_suffix, vd->type.u.ed->fqcname); break; } /* Drop through. */ case byte_type: case sbyte_type: 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 ubyte_type: case ushort_type: prcode(fp, "#if PY_MAJOR_VERSION >= 3\n" " return PyLong_FromUnsignedLong(sipVal);\n" "#else\n" " return PyInt_FromLong(sipVal);\n" "#endif\n" ); break; 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(", (isConstArg(&vd->type) ? "Const" : "")); generateVoidPtrCast(&vd->type, fp); prcode(fp, "sipVal);\n"); break; case capsule_type: prcode(fp, " return SIPCapsule_FromVoidPtr("); generateVoidPtrCast(&vd->type, fp); prcode(fp, "sipVal);\n"); break; case pyobject_type: case pytuple_type: case pylist_type: case pydict_type: case pycallable_type: case pyslice_type: case pytype_type: case pybuffer_type: prcode(fp, " Py_XINCREF(sipVal);\n" " return sipVal;\n" ); break; /* Supress a compiler warning. */ default: ; } 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, *error_test; char *deref; int might_be_temp, need_py, need_cpp; if (generating_c || !isStaticVar(vd)) first_arg = "sipSelf"; else first_arg = ""; if (generating_c || (!isStaticVar(vd) && vd->type.key < 0)) last_arg = "sipPySelf"; else last_arg = ""; need_py = (generating_c || vd->setcode == NULL || usedInCode(vd->setcode, "sipPy")); need_cpp = (generating_c || vd->setcode == NULL || usedInCode(vd->setcode, "sipCpp")); 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 *%s, PyObject *%s)\n" "{\n" , vd->fqcname, (need_cpp ? first_arg : ""), (need_py ? "sipPy" : ""), last_arg); if (vd->setcode == NULL) { prcode(fp, " "); if (atype == bool_type) prcode(fp, "int sipVal"); else generateNamedValueType(scope, &vd->type, "sipVal", fp); prcode(fp, ";\n" ); } if (!isStaticVar(vd) && need_cpp) { if (generating_c) prcode(fp, " struct %S *sipCpp = (struct %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 = "*"; error_test = "sipIsErr"; } else if (atype == bool_type) { error_test = "sipVal < 0"; } else { error_test = "PyErr_Occurred() != NULL"; } prcode(fp, "\n" " if (%s)\n" " return -1;\n" "\n" , error_test); if (atype == pyobject_type || atype == pytuple_type || atype == pylist_type || atype == pydict_type || atype == pycallable_type || atype == pyslice_type || atype == pytype_type || atype == pybuffer_type) { prcode(fp, " Py_XDECREF("); generateVarMember(vd, fp); prcode(fp, ");\n" " Py_INCREF(sipVal);\n" "\n" ); } prcode(fp, " "); generateVarMember(vd, fp); if (atype == bool_type) { if (generating_c) prcode(fp, " = (bool)%ssipVal;\n" , deref); else prcode(fp, " = static_cast(%ssipVal);\n" , deref); } else { 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 (vd->type.key < 0) { if (isStaticVar(vd)) { prcode(fp, "\n" " static PyObject *sipKeep = 0;\n" "\n" " Py_XDECREF(sipKeep);\n" " sipKeep = sipPy;\n" " Py_INCREF(sipKeep);\n" ); } else { 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)sipConvertToEnum(sipPy, sipType_%C);\n" , ad->u.ed, ad->u.ed->fqcname); 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 = "sipConvertToBool(sipPy)"; break; case byte_type: rhs = "sipLong_AsChar(sipPy)"; break; case sbyte_type: rhs = "sipLong_AsSignedChar(sipPy)"; break; case ubyte_type: rhs = "sipLong_AsUnsignedChar(sipPy)"; break; case ushort_type: rhs = "sipLong_AsUnsignedShort(sipPy)"; break; case short_type: rhs = "sipLong_AsShort(sipPy)"; break; case uint_type: rhs = "sipLong_AsUnsignedInt(sipPy)"; break; case int_type: case cint_type: rhs = "sipLong_AsInt(sipPy)"; break; case ulong_type: rhs = "sipLong_AsUnsignedLong(sipPy)"; break; case long_type: rhs = "sipLong_AsLong(sipPy)"; break; case ulonglong_type: rhs = "sipLong_AsUnsignedLongLong(sipPy)"; break; case longlong_type: rhs = "sipLong_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 capsule_type: prcode(fp, "SIPCapsule_AsVoidPtr(sipPy, \"%S\");\n" , ad->u.cap); break; case pyobject_type: case pytuple_type: case pylist_type: case pydict_type: case pycallable_type: case pyslice_type: case pytype_type: case pybuffer_type: rhs = "sipPy"; break; /* Supress a compiler warning. */ default: ; } 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. */ 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 || st == await_slot || st == aiter_slot || st == anext_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 || st == setattr_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. */ 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 || st == imatmul_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 || st == matmul_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, *decl_arg_str, *prefix, *ret_type; int ret_int, has_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 *"; } has_args = TRUE; if (isIntArgSlot(md)) { has_args = FALSE; arg_str = "PyObject *sipSelf,int a0"; decl_arg_str = "PyObject *,int"; } else if (md->slot == call_slot) { if (generating_c || useKeywordArgs(md) || noArgParser(md)) arg_str = "PyObject *sipSelf,PyObject *sipArgs,PyObject *sipKwds"; else arg_str = "PyObject *sipSelf,PyObject *sipArgs,PyObject *"; decl_arg_str = "PyObject *,PyObject *,PyObject *"; } else if (isMultiArgSlot(md)) { arg_str = "PyObject *sipSelf,PyObject *sipArgs"; decl_arg_str = "PyObject *,PyObject *"; } else if (isZeroArgSlot(md)) { has_args = FALSE; arg_str = "PyObject *sipSelf"; decl_arg_str = "PyObject *"; } else if (isNumberSlot(md)) { arg_str = "PyObject *sipArg0,PyObject *sipArg1"; decl_arg_str = "PyObject *,PyObject *"; } else if (md->slot == setattr_slot) { arg_str = "PyObject *sipSelf,PyObject *sipName,PyObject *sipValue"; decl_arg_str = "PyObject *,PyObject *,PyObject *"; } else { arg_str = "PyObject *sipSelf,PyObject *sipArg"; decl_arg_str = "PyObject *,PyObject *"; } prcode(fp, "\n" "\n" ); if (md->slot != long_slot) { 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, decl_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 (md->slot == call_slot && noArgParser(md)) { for (od = overs; od != NULL; od = od->next) if (od->common == md) generateCppCodeBlock(od->methodcode, fp); } else { 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" , fqcname, fqcname, fqcname); else prcode(fp, " %S sipCpp = static_cast<%S>(sipConvertToEnum(sipSelf, sipType_%C));\n" "\n" " if (PyErr_Occurred())\n" , fqcname, fqcname, fqcname); prcode(fp, " return %s;\n" "\n" , (md->slot == cmp_slot ? "-2" : (ret_int ? "-1" : "0"))); } if (has_args) 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 (has_args) { 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, ", pyname); if (md->slot == setattr_slot) prcode(fp, "(sipValue != NULL ? sipName___setattr__ : sipName___delattr__)"); else prcode(fp, "%N", md->pyname); prcode(fp, ", NULL);\n" "\n" " return %s;\n" ,ret_int ? "-1" : "0"); } } } else { prcode(fp, "\n" " return 0;\n" ); } } prcode(fp, "}\n" ); if (md->slot != long_slot) 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, int py_debug, FILE *fp) { visibleList *vl; memberDef *md; /* Any shadow code. */ if (hasShadow(cd)) { if (!isExportDerived(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) generateSlot(mod, cd, NULL, md, fp); /* * The cast function. Note that we used to try and work out if the cast * function was really needed (eg. only for multiple inheritance) but there * are subtle cases where, even for single inheritance, it is needed. We * take the conservative approach and generate it for all derived classes. */ if (cd->supers != NULL) { mroDef *mro; prcode(fp, "\n" "\n" "/* Cast a pointer to a type somewhere in its inheritance hierarchy. */\n" "extern \"C\" {static void *cast_%L(void *, const sipTypeDef *);}\n" "static void *cast_%L(void *sipCppV, const sipTypeDef *targetType)\n" "{\n" " " , cd->iff , cd->iff); generateClassFromVoid(cd, "sipCpp", "sipCppV", fp); prcode(fp, ";\n" "\n" ); /* Skip the the class itself. */ for (mro = cd->mro->next; mro != NULL; mro = mro->next) { if (!isDuplicateSuper(mro) && !hasDuplicateSuper(mro)) { prcode(fp, " if (targetType == sipType_%C)\n" " return static_cast<%U *>(sipCpp);\n" "\n" , classFQCName(mro->cd) , mro->cd); } } prcode(fp, " return sipCppV;\n" "}\n" ); } if (cd->iff->type != namespace_iface && !generating_c) { int need_ptr = FALSE, need_cast_ptr = FALSE, need_state = FALSE; /* Generate the release function without compiler warnings. */ if (cd->dealloccode != NULL) need_ptr = need_cast_ptr = usedInCode(cd->dealloccode, "sipCpp"); if (canCreate(cd) || isPublicDtor(cd)) { if ((pluginPyQt4(pt) || pluginPyQt5(pt)) && isQObjectSubClass(cd) && isPublicDtor(cd)) need_ptr = need_cast_ptr = TRUE; else 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 (need_cast_ptr) { prcode(fp, " "); generateClassFromVoid(cd, "sipCpp", "sipCppV", fp); prcode(fp, ";\n" "\n" ); } if (cd->dealloccode != NULL) { 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 ((pluginPyQt4(pt) || pluginPyQt5(pt)) && isQObjectSubClass(cd) && isPublicDtor(cd)) { /* * QObjects should only be deleted in the threads that they * belong to. */ prcode(fp, " if (QThread::currentThread() == sipCpp->thread())\n" " delete sipCpp;\n" " else\n" " sipCpp->deleteLater();\n" ); } else if (hasShadow(cd)) { prcode(fp, " if (sipState & SIP_DERIVED_CLASS)\n" " delete reinterpret_cast(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 (!py_debug && useLimitedAPI(mod)) { if (!generating_c) prcode(fp, "extern \"C\" {static int getbuffer_%C(PyObject *, void *, sipBufferDef *);}\n" , classFQCName(cd)); prcode(fp, "static int getbuffer_%C(PyObject *%s, void *%s, sipBufferDef *sipBuffer)\n" , classFQCName(cd), argName("sipSelf", cd->getbufcode), (generating_c || need_cpp ? "sipCppV" : "")); } else { 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" , classFQCName(cd), argName("sipSelf", cd->getbufcode), (generating_c || need_cpp ? "sipCppV" : ""), argName("sipFlags", cd->getbufcode)); } prcode(fp, "{\n" ); 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) { int need_cpp = usedInCode(cd->releasebufcode, "sipCpp"); prcode(fp, "\n" "\n" "#if PY_MAJOR_VERSION >= 3\n" ); if (!py_debug && useLimitedAPI(mod)) { if (!generating_c) prcode(fp, "extern \"C\" {static void releasebuffer_%C(PyObject *, void *);}\n" , classFQCName(cd)); prcode(fp, "static void releasebuffer_%C(PyObject *%s, void *%s)\n" "#else\n" , classFQCName(cd), argName("sipSelf", cd->releasebufcode), (generating_c || need_cpp ? "sipCppV" : "")); } else { 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 *%s, Py_buffer *%s)\n" , classFQCName(cd), argName("sipSelf", cd->releasebufcode), (generating_c || need_cpp ? "sipCppV" : ""), argName("sipBuffer", cd->releasebufcode)); } prcode(fp, "{\n" ); if (need_cpp) { prcode(fp, " "); generateClassFromVoid(cd, "sipCpp", "sipCppV", fp); prcode(fp, ";\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" ); } /* The finalisation function. */ if (cd->finalcode != NULL) { int need_cpp = usedInCode(cd->finalcode, "sipCpp"); prcode(fp, "\n" "\n" ); if (!generating_c) prcode(fp, "extern \"C\" {static int final_%C(PyObject *, void *, PyObject *, PyObject **);}\n" , classFQCName(cd)); prcode(fp, "static int final_%C(PyObject *%s, void *%s, PyObject *%s, PyObject **%s)\n" "{\n" , classFQCName(cd), (usedInCode(cd->finalcode, "sipSelf") ? "sipSelf" : ""), (need_cpp ? "sipCppV" : ""), (usedInCode(cd->finalcode, "sipKwds") ? "sipKwds" : ""), (usedInCode(cd->finalcode, "sipUnused") ? "sipUnused" : "")); if (need_cpp) { prcode(fp, " "); generateClassFromVoid(cd, "sipCpp", "sipCppV", fp); prcode(fp, ";\n" "\n" ); } generateCppCodeBlock(cd->finalcode, fp); prcode(fp, "}\n" ); } /* The mixin initialisation function. */ if (isMixin(cd)) { prcode(fp, "\n" "\n" ); if (!generating_c) prcode(fp, "extern \"C\" {static int mixin_%C(PyObject *, PyObject *, PyObject *);}\n" , classFQCName(cd)); prcode(fp, "static int mixin_%C(PyObject *sipSelf, PyObject *sipArgs, PyObject *sipKwds)\n" "{\n" " return sipInitMixin(sipSelf, sipArgs, sipKwds, (sipClassTypeDef *)&" , classFQCName(cd)); generateTypeDefName(cd->iff, fp); prcode(fp, ");\n" "}\n" ); } if (generating_c || assignmentHelper(cd)) { /* * Generate the assignment helper. Note that the source pointer is not * const. This is to allow the source instance to be modified as a * consequence of the assignment, eg. if it is implementing some sort * of reference counting scheme. */ prcode(fp, "\n" "\n" ); if (!generating_c) prcode(fp, "extern \"C\" {static void assign_%L(void *, SIP_SSIZE_T, void *);}\n" , cd->iff); prcode(fp, "static void assign_%L(void *sipDst, SIP_SSIZE_T sipDstIdx, void *sipSrc)\n" "{\n" , cd->iff); if (generating_c) prcode(fp, " ((struct %U *)sipDst)[sipDstIdx] = *((struct %U *)sipSrc);\n" , cd, cd); else prcode(fp, " reinterpret_cast<%U *>(sipDst)[sipDstIdx] = *reinterpret_cast<%U *>(sipSrc);\n" , cd, 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 (struct %U) * sipNrElem);\n" , cd); else prcode(fp, " return new %U[sipNrElem];\n" , 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, " struct %U *sipPtr = sipMalloc(sizeof (struct %U));\n" " *sipPtr = ((const struct %U *)sipSrc)[sipSrcIdx];\n" "\n" " return sipPtr;\n" , cd, cd , cd); else prcode(fp, " return new %U(reinterpret_cast(sipSrc)[sipSrcIdx]);\n" , cd, 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 (sipIsDerivedClass(sipSelf))\n" " reinterpret_cast(sipGetAddress(sipSelf))->sipPySelf = NULL;\n" "\n" ,classFQCName(cd)); if (generating_c || isPublicDtor(cd) || (hasShadow(cd) && isProtectedDtor(cd))) { prcode(fp, " if (sipIsOwnedByPython(sipSelf))\n" " {\n" ); if (isDelayedDtor(cd)) { prcode(fp, " sipAddDelayedDtor(sipSelf);\n" ); } else if (generating_c) { if (cd->dealloccode != NULL) generateCppCodeBlock(cd->dealloccode, fp); prcode(fp, " sipFree(sipGetAddress(sipSelf));\n" ); } else { prcode(fp, " release_%L(sipGetAddress(sipSelf), %s);\n" , cd->iff, (hasShadow(cd) ? "sipIsDerivedClass(sipSelf)" : "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(mod, cd->iff, ct->cppsig, Definition, fp); prcode(fp, ")%X: %U(", ct->exceptions, cd); generateProtectedCallArgs(mod, 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(NULL, cd->iff, ct->cppsig, Declaration, 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, " sipInstanceDestroyed(sipPySelf);\n" "}\n" ); } /* The meta methods if required. */ if ((pluginPyQt4(pt) || pluginPyQt5(pt)) && isQObjectSubClass(cd)) { if (!noPyQtQMetaObject(cd)) { prcode(fp, "\n" "const QMetaObject *sip%C::metaObject() const\n" "{\n" , classFQCName(cd)); if (pluginPyQt5(pt)) prcode(fp, " if (sipGetInterpreter())\n" " return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : sip_%s_qt_metaobject(sipPySelf,sipType_%C);\n" "\n" " return %S::metaObject();\n" , mod->name, classFQCName(cd) , classFQCName(cd)); else prcode(fp, " return sip_%s_qt_metaobject(sipPySelf,sipType_%C);\n" , mod->name, classFQCName(cd)); prcode(fp, "}\n" ); } 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" , classFQCName(cd) , classFQCName(cd) , mod->name, classFQCName(cd) , classFQCName(cd)); if (pluginPyQt5(pt)) prcode(fp, " void *sipCpp;\n" "\n" " return (sip_%s_qt_metacast(sipPySelf, sipType_%C, _clname, &sipCpp) ? sipCpp : %S::qt_metacast(_clname));\n" , mod->name, classFQCName(cd), classFQCName(cd)); else prcode(fp, " return (sip_%s_qt_metacast(sipPySelf, sipType_%C, _clname)) ? this : %S::qt_metacast(_clname);\n" , mod->name, classFQCName(cd), classFQCName(cd)); prcode(fp, "}\n" ); } /* Generate the virtual catchers. */ virtNr = 0; for (vod = cd->vmembers; vod != NULL; vod = vod->next) { overDef *od = vod->od; 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->od->cppname, od->cppname) == 0 && sameSignature(dvod->od->cppsig, od->cppsig, TRUE)) break; if (dvod == vod) generateVirtualCatcher(mod, cd, virtNr++, vod, fp); } /* Generate the wrapper around each protected member function. */ generateProtectedDefinitions(mod, cd, fp); } /* * 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->od; 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, StripNone, fp); prcode(fp," sip%C::%O(",classFQCName(cd),od); generateCalledArgs(mod, cd->iff, od->cppsig, Definition, 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, StripGlobal, fp); prcode(fp," sip%C::%O(",classFQCName(cd),od); generateCalledArgs(NULL, cd->iff, od->cppsig, Declaration, 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 *sipMeth;\n" "\n" " sipMeth = sipIsPyMethod(&sipGILState,"); if (isConst(od)) prcode(fp, "const_cast("); 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 (!sipMeth)\n" ); if (od->virtcallcode != NULL) { argDef *res = &od->cppsig->result; prcode(fp, " {\n"); if (res->atype != void_type || res->nrderefs != 0) { prcode(fp, " "); generateNamedBaseType(cd->iff, res, "sipRes", TRUE, StripNone, fp); prcode(fp, ";\n" ); } else { res = NULL; } prcode(fp, "\n" ); generateCppCodeBlock(od->virtcallcode, fp); prcode(fp, "\n" " return%s;\n" " }\n" , (res != NULL ? " sipRes" : "")); } else if (isAbstract(od)) { generateDefaultInstanceReturn(res, " ", fp); } else { int a; if (res == NULL) prcode(fp, " {\n" " "); else prcode(fp, " return "); prcode(fp, "%S::%O(", classFQCName(cd), od); for (a = 0; a < od->cppsig->nrArgs; ++a) { argDef *ad = &od->cppsig->args[a]; prcode(fp, "%s%a", (a == 0 ? "" : ","), mod, ad, a); } prcode(fp,");\n" ); if (res == NULL) { /* * Note that we should also generate this if the function returns a * value, but we are lazy and this is all that is needed by PyQt. */ if (isNewThread(od)) prcode(fp, " sipEndThread();\n" ); 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->od->cppname, od->cppname) == 0 && sameSignature(versioned_vod->od->cppsig, od->cppsig, TRUE)) { avr = versioned_vod->od->api_range; /* Check that it has an API specified. */ if (avr == NULL) { fatalScopedName(classFQCName(cd)); fprintf(stderr, "::"); prOverloadName(stderr, od); fatal(" has versioned and unversioned overloads\n"); } break; } } } while (versioned_vod != NULL); prcode(fp, "\n" ); /* Generate a default result in case no API is enabled. */ if (isAbstract(od)) generateDefaultInstanceReturn(res, "", fp); else { int a; prcode(fp, " %s%S::%O(", (res != NULL ? "return " : ""), classFQCName(cd), od); for (a = 0; a < od->cppsig->nrArgs; ++a) { argDef *ad = &od->cppsig->args[a]; prcode(fp, "%s%a", (a == 0 ? "" : ","), mod, ad, 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->od; virtHandlerDef *vhd = vod->virthandler; virtErrorHandler *veh; signatureDef saved; argDef *ad; int a, args_keep = FALSE, result_keep = FALSE; saved = *vhd->cppsig; fakeProtectedArgs(vhd->cppsig); prcode(fp, "%sextern ", indent); generateBaseType(cd->iff, &od->cppsig->result, TRUE, StripNone, fp); prcode(fp, " sipVH_%s_%d(sip_gilstate_t, sipVirtErrorHandlerFunc, sipSimpleWrapper *, PyObject *", mod->name, vhd->virthandlernr); if (vhd->cppsig->nrArgs > 0) { prcode(fp, ", "); generateCalledArgs(NULL, cd->iff, vhd->cppsig, Declaration, 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"); } prcode(fp,");\n" ); prcode(fp, "\n" "%s", indent); if (!isNewThread(od) && res != NULL) prcode(fp, "return "); prcode(fp, "sipVH_%s_%d(sipGILState, ", mod->name, vhd->virthandlernr); veh = vhd->veh; if (veh == NULL) prcode(fp, "0"); else if (veh->mod == mod) prcode(fp, "sipVEH_%s_%s" , mod->name, veh->name); else prcode(fp, "sipImportedVirtErrorHandlers_%s_%s[%d].iveh_handler", mod->name, veh->mod->name, veh->index); prcode(fp, ", sipPySelf, sipMeth"); for (ad = od->cppsig->args, a = 0; a < od->cppsig->nrArgs; ++a, ++ad) { if (ad->atype == class_type && isProtectedClass(ad->u.cd)) prcode(fp, ", %s%a", ((isReference(ad) || ad->nrderefs == 0) ? "&" : ""), mod, ad, a); else if (ad->atype == enum_type && isProtectedEnum(ad->u.ed)) prcode(fp, ", (%E)%a", ad->u.ed, mod, ad, a); else prcode(fp, ", %a", mod, ad, 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); prcode(fp,");\n" ); if (isNewThread(od)) prcode(fp, "\n" "%ssipEndThread();\n" , indent); } /* * Generate a cast to zero. */ static void generateCastZero(argDef *ad, FILE *fp) { if (ad->atype == enum_type) { enumDef *ed = ad->u.ed; if (ed->members != NULL) { if (isScopedEnum(ed)) prcode(fp, "%E", ed); else if (ed->ecd != NULL) prEnumMemberScope(ed->members, fp); prcode(fp, "::%s", ed->members->cname); return; } prcode(fp, "(%E)", ed); } prcode(fp, "0"); } /* * Generate a statement to return the default instance of a type typically on * error (ie. when there is nothing sensible to return). */ static void generateDefaultInstanceReturn(argDef *res, const char *indent, FILE *fp) { codeBlockList *instance_code; /* Handle the trivial case. */ if (res == NULL) { prcode(fp, "%s return;\n" , indent); return; } /* Handle any %InstanceCode. */ instance_code = NULL; if (res->nrderefs == 0) { if (res->atype == mapped_type) instance_code = res->u.mtd->instancecode; else if (res->atype == class_type) instance_code = res->u.cd->instancecode; } if (instance_code != NULL) { argDef res_noconstref; res_noconstref = *res; resetIsConstArg(&res_noconstref); resetIsReference(&res_noconstref); prcode(fp, "%s{\n" "%s static %B *sipCpp = 0;\n" "\n" "%s if (!sipCpp)\n" "%s {\n" , indent , indent, &res_noconstref , indent , indent); generateCppCodeBlock(instance_code, fp); prcode(fp, "%s }\n" "\n" "%s return *sipCpp;\n" "%s}\n" , indent , indent , indent); return; } prcode(fp, "%s return ", indent); 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 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, StripNone, 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(NULL, cd->iff, od->cppsig, Declaration, fp); prcode(fp,")%s;\n" ,(isConst(od) ? " const" : "")); } } } /* * Generate the definitions of the protected wrapper functions for a class. */ static void generateProtectedDefinitions(moduleDef *mod, 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, StripNone, 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(mod, cd->iff, od->cppsig, Definition, 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 ? %U::%s(", vl->cd, mname); generateProtectedCallArgs(mod, od->cppsig, fp); prcode(fp, ") : "); ++parens; } else { prcode(fp, "%U::", vl->cd); } } prcode(fp,"%s(",mname); generateProtectedCallArgs(mod, 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(moduleDef *mod, 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", mod, ad, a); } } /* * Generate the function that does most of the work to handle a particular * virtual function. */ static void generateVirtualHandler(moduleDef *mod, virtHandlerDef *vhd, FILE *fp) { int a, nrvals, res_isref; 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, TRUE, StripNone, fp); prcode(fp," sipVH_%s_%d(sip_gilstate_t sipGILState, sipVirtErrorHandlerFunc sipErrorHandler, sipSimpleWrapper *sipPySelf, PyObject *sipMethod" , mod->name, vhd->virthandlernr); if (vhd->cppsig->nrArgs > 0) { prcode(fp,", "); generateCalledArgs(mod, NULL, vhd->cppsig, Definition, fp); } *vhd->cppsig = saved; /* Declare the extra arguments for kept references. */ if (res != NULL && keepPyReference(res)) { 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)) prcode(fp, ", int %aKey", mod, ad, a); 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, TRUE, StripNone, fp); prcode(fp," %ssipRes",(res_isref ? "*" : "")); if ((res->atype == class_type || res->atype == mapped_type || res->atype == template_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(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); prcode(fp, "\n" " Py_DECREF(sipMethod);\n" ); if (error_flag || old_error_flag) prcode(fp, "\n" " if (%s)\n" " sipCallErrorHandler(sipErrorHandler, sipPySelf, sipGILState);\n" , (error_flag ? "sipError != sipErrorNone" : "sipIsErr")); prcode(fp, "\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. */ if (nrvals == 0) prcode(fp, " sipCallProcedureMethod(sipGILState, sipErrorHandler, sipPySelf, sipMethod, "); else prcode(fp, " PyObject *sipResObj = sipCallMethod(0, sipMethod, "); saved = *vhd->pysig; fakeProtectedArgs(vhd->pysig); generateTupleBuilder(mod, vhd->pysig, fp); *vhd->pysig = saved; if (nrvals == 0) { prcode(fp, ");\n" "}\n" ); return; } prcode(fp, ");\n" "\n" " %ssipParseResultEx(sipGILState, sipErrorHandler, sipPySelf, sipMethod, sipResObj, \"", ((res_isref || abortOnExceptionVH(vhd)) ? "int sipRc = " : "")); /* Build the format string. */ 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,"\""); /* Pass the destination pointers. */ if (res != NULL) { generateParseResultExtraArgs(NULL, res, -1, fp); prcode(fp, ", &sipRes"); } for (a = 0; a < vhd->pysig->nrArgs; ++a) { argDef *ad = &vhd->pysig->args[a]; if (isOutArg(ad)) { generateParseResultExtraArgs(mod, ad, a, fp); prcode(fp, ", %s%a", (isReference(ad) ? "&" : ""), mod, ad, a); } } prcode(fp, ");\n" ); if (res != NULL) { if (res_isref || abortOnExceptionVH(vhd)) { prcode(fp, "\n" " if (sipRc < 0)\n" ); if (abortOnExceptionVH(vhd)) prcode(fp, " abort();\n" ); else generateDefaultInstanceReturn(res, " ", fp); } prcode(fp, "\n" " return %ssipRes;\n" , (res_isref ? "*" : "")); } prcode(fp, "}\n" ); } /* * Generate the extra arguments needed by sipParseResultEx() for a particular * type. */ static void generateParseResultExtraArgs(moduleDef *mod, 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; case capsule_type: prcode(fp,", \"%S\"", ad->u.cap); break; default: if (keepPyReference(ad)) { if (argnr < 0) prcode(fp, ", sipResKey"); else prcode(fp, ", %aKey", mod, ad, argnr); } } } /* * Return the format characters used by sipParseResultEx() 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; } else if (ad->nrderefs == 1) { if (isOutArg(ad)) f |= 0x04; else if (isDisallowNone(ad)) f |= 0x01; } 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 byte_type: /* * Note that this assumes that char is signed. We should not make that * assumption. */ case sbyte_type: return "L"; case ubyte_type: return "M"; 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 capsule_type: return "z"; 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"); case pybuffer_type: return (isAllowNone(ad) ? "$" : "!"); /* Supress a compiler warning. */ default: ; } /* We should never get here. */ return " "; } /* * Generate the code to build a tuple of Python arguments. */ static void generateTupleBuilder(moduleDef *mod, signatureDef *sd,FILE *fp) { int a, arraylenarg; /* Suppress a compiler warning. */ arraylenarg = 0; 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: case latin1_string_type: case utf8_string_type: if (ad->nrderefs == 0 || (ad->nrderefs == 1 && isOutArg(ad))) fmt = "a"; else fmt = "A"; 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 byte_type: case sbyte_type: if (isArraySize(ad)) arraylenarg = a; else fmt = "L"; break; case ubyte_type: if (isArraySize(ad)) arraylenarg = a; else fmt = "M"; 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 capsule_type: fmt = "z"; 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: case pybuffer_type: fmt = "S"; break; /* Suppress a compiler warning. */ default: ; } 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; /* Supress a compiler warning. */ default: ; } 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<%D *>(", ad); if (ad->nrderefs == 0) prcode(fp,"&"); else while (derefs-- != 0) prcode(fp,"*"); } prcode(fp, "%a", mod, ad, a); if (copy || isConstArg(ad)) prcode(fp,")"); if (isArray(ad)) prcode(fp, ", (SIP_SSIZE_T)%a", mod, &sd->args[arraylenarg], 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 (ad->atype == capsule_type) { prcode(fp, ", \"%S\"", ad->u.cap); } else { if (!isArraySize(ad)) { prcode(fp, ", "); while (derefs-- != 0) prcode(fp, "*"); prcode(fp, "%a", mod, ad, a); } if (isArray(ad)) prcode(fp, ", (SIP_SSIZE_T)%a", mod, &sd->args[arraylenarg], 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) { int no_exceptions = TRUE; classDef *cd; mappedTypeDef *mtd; exceptionDef *xd; virtErrorHandler *veh; 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) { if (no_exceptions) { prcode(fp, "\n" "/* The exceptions defined in this module. */\n" "extern PyObject *sipExportedExceptions_%s[];\n" "\n" , mod->name); } prcode(fp, "#define sipException_%C sipExportedExceptions_%s[%d]\n" , xd->iff->fqcname, mod->name, xd->exceptionnr); } generateEnumMacros(pt, mod, NULL, NULL, fp); for (veh = pt->errorhandlers; veh != NULL; veh = veh->next) if (veh->mod == mod) prcode(fp, "\n" "void sipVEH_%s_%s(sipSimpleWrapper *, sip_gilstate_t);\n" , mod->name, veh->name); } /* * 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) { if (cd->iff->needed) generateImportedClassAPI(cd, mod, fp); generateEnumMacros(pt, mod, cd, NULL, fp); } for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next) if (mtd->iff->module == immod) { if (mtd->iff->needed) generateImportedMappedTypeAPI(mtd, mod, fp); generateEnumMacros(pt, mod, NULL, mtd, fp); } for (xd = pt->exceptions; xd != NULL; xd = xd->next) if (xd->iff->module == immod && xd->exceptionnr >= 0) prcode(fp, "\n" "#define sipException_%C sipImportedExceptions_%s_%s[%d].iexc_object\n" , xd->iff->fqcname, mod->name, xd->iff->module->name, xd->exceptionnr); generateEnumMacros(pt, mod, NULL, NULL, fp); } /* * Generate the API details for an imported mapped type. This will only be * called for the first API implementation. */ static void generateImportedMappedTypeAPI(mappedTypeDef *mtd, moduleDef *mod, FILE *fp) { 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 sipImportedTypes_%s_%s[%d].it_td\n" , &type, mname, imname, mtd->iff->ifacenr); } /* * 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 sipExportedTypes_%s[%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. This will only be called * for the first API implementation. */ static void generateImportedClassAPI(classDef *cd, moduleDef *mod, FILE *fp) { const char *mname = mod->name; const char *imname = cd->iff->module->name; prcode(fp, "\n" ); if (cd->iff->type == namespace_iface) prcode(fp, "#if !defined(sipType_%L)\n" , cd->iff); prcode(fp, "#define sipType_%C sipImportedTypes_%s_%s[%d].it_td\n" "#define sipClass_%C sipImportedTypes_%s_%s[%d].it_td->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" ); } /* * 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 && !isHiddenNamespace(cd)) prcode(fp, "#define sipType_%C sipExportedTypes_%s[%d]\n" "#define sipClass_%C sipExportedTypes_%s[%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) && !isHiddenNamespace(cd)) { prcode(fp, "\n" "extern sipClassTypeDef sipTypeDef_%s_%L;\n" , mname, cd->iff); if (isExportDerived(cd)) { generateCppCodeBlock(cd->iff->hdrcode, fp); generateShadowClassDeclaration(pt, cd, fp); } } } /* * Generate the sipEnum_* macros. */ static void generateEnumMacros(sipSpec *pt, moduleDef *mod, classDef *cd, mappedTypeDef *mtd, FILE *fp) { enumDef *ed; 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 (mod == ed->module) prcode(fp, "\n" "#define sipType_%C sipExportedTypes_%s[%d]\n" "#define sipEnum_%C sipExportedTypes_%s[%d]->u.td_py_type\n" , ed->fqcname, mod->name, ed->enumnr , ed->fqcname, mod->name, ed->enumnr); else if (needsEnum(ed)) prcode(fp, "\n" "#define sipType_%C sipImportedTypes_%s_%s[%d].it_td\n" "#define sipEnum_%C sipImportedTypes_%s_%s[%d].it_td->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 %U\n" "{\n" "public:\n" , classFQCName(cd), 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(NULL, cd->iff, ct->cppsig, Declaration, 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) || pluginPyQt5(pt)) && isQObjectSubClass(cd)) { prcode(fp, "\n" " int qt_metacall(QMetaObject::Call,int,void **);\n" " void *qt_metacast(const char *);\n" ); if (!noPyQtQMetaObject(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 catcher around each virtual function in the hierarchy. */ noIntro = TRUE; for (vod = cd->vmembers; vod != NULL; vod = vod->next) { overDef *od = vod->od; 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->od->cppname,od->cppname) == 0 && sameSignature(dvod->od->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, StripNone, 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, StripNone, 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(moduleDef *mod, ifaceFileDef *scope, signatureDef *sd, funcArgType ftype, FILE *fp) { const char *name; char buf[50]; int a; for (a = 0; a < sd->nrArgs; ++a) { argDef *ad = &sd->args[a]; if (a > 0) prcode(fp,","); name = buf; if (ftype == Definition) { if (mod != NULL && useArgNames(mod) && ad->name != NULL) name = ad->name->text; else sprintf(buf, "a%d", a); } else { buf[0] = '\0'; } generateNamedBaseType(scope, ad, name, TRUE, StripNone, fp); } } /* * Generate typed arguments for a call. */ static void generateCallArgs(moduleDef *mod, 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) && !isReference(ad)) 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 = "&"; } /* * 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 && py_ad->atype != capsule_type) || ad->atype == void_type || ad->atype == capsule_type || py_ad->nrderefs != ad->nrderefs) py_ad = NULL; } else py_ad = NULL; if (py_ad == NULL) { if (ind != NULL) prcode(fp, ind); if (isArraySize(ad)) prcode(fp, "(%b)", ad); prcode(fp, "%a", mod, ad, a); } else if (generating_c) prcode(fp, "(%b *)%a", ad, mod, ad, a); else prcode(fp, "reinterpret_cast<%b *>(%a)", ad, mod, 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, StripNone, fp); } /* * Generate a C++ type. */ static void generateBaseType(ifaceFileDef *scope, argDef *ad, int use_typename, StripAction strip, FILE *fp) { generateNamedBaseType(scope, ad, "", use_typename, strip, fp); } /* * Generate a C++ type and name. */ static void generateNamedBaseType(ifaceFileDef *scope, argDef *ad, const char *name, int use_typename, StripAction strip, FILE *fp) { typedefDef *td = ad->original_type; int nr_derefs = ad->nrderefs; int is_reference = isReference(ad); int i, space_before_name; 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", stripScope(td->fqname, NULL, strip)); } else { /* * A function type is handled differently because of the position of * the name. */ if (ad->atype == function_type) { signatureDef *sig = ad->u.sa; generateBaseType(scope, &sig->result, TRUE, strip, fp); prcode(fp," ("); for (i = 0; i < nr_derefs; ++i) prcode(fp, "*"); prcode(fp, "%s)(",name); generateCalledArgs(NULL, scope, sig, Declaration, fp); prcode(fp, ")"); return; } if (isConstArg(ad)) prcode(fp, "const "); switch (ad->atype) { case sbyte_type: case sstring_type: prcode(fp, "signed char"); break; case ubyte_type: 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 byte_type: 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: /* * Qt4 moc uses "uint" in signal signatures. We do all the time * and hope it is always defined. */ prcode(fp, "uint"); 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 capsule_type: nr_derefs = 1; /* Drop through. */ 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, removeGlobalScope(ad->u.snd), "."); } else { if (generating_c) fprintf(fp, "struct "); prScopedName(fp, stripScope(ad->u.snd, NULL, strip), "::"); } break; case rxcon_type: case rxdis_type: nr_derefs = 1; prcode(fp, "QObject"); break; case mapped_type: generateBaseType(scope, &ad->u.mtd->type, TRUE, strip, fp); break; case class_type: prScopedClassName(fp, scope, ad->u.cd, strip); break; case template_type: prTemplateType(fp, scope, ad->u.td, strip); break; case enum_type: { enumDef *ed = ad->u.ed; if (ed->fqcname == NULL || isProtectedEnum(ed)) fprintf(fp,"int"); else prScopedName(fp, stripScope(ed->fqcname, ed->ecd, strip), "::"); break; } case pyobject_type: case pytuple_type: case pylist_type: case pydict_type: case pycallable_type: case pyslice_type: case pytype_type: case pybuffer_type: case qobject_type: case ellipsis_type: prcode(fp, "PyObject *"); break; /* Supress a compiler warning. */ default: ; } } space_before_name = TRUE; for (i = 0; i < nr_derefs; ++i) { /* * Note that we don't put a space before the '*' so that Qt normalised * signal signatures are correct. Qt4 can cope with it but Qt5 can't. */ prcode(fp, "*"); space_before_name = FALSE; if (ad->derefs[i]) { prcode(fp, " const"); space_before_name = TRUE; } } if (is_reference) prcode(fp, (prcode_xml ? "&" : "&")); if (*name != '\0') { if (space_before_name) prcode(fp, " "); prcode(fp, name); } } /* * Generate the definition of an argument variable and any supporting * variables. */ static void generateVariable(moduleDef *mod, 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 %adef = ", scope, ad, mod, 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 && ad->atype != slotcon_type && ad->atype != slotdis_type) resetIsConstArg(ad); prcode(fp, " %A %a", scope, ad, mod, ad, argnr); if (atype == anyslot_type) prcode(fp, "Name"); *ad = orig; generateDefaultValue(mod, ad, argnr, fp); prcode(fp,";\n" ); /* Some types have supporting variables. */ if (isInArg(ad)) { if (isGetWrapper(ad)) prcode(fp, " PyObject *%aWrapper%s;\n" , mod, ad, argnr, (ad->defval != NULL ? " = 0" : "")); else if (keepReference(ad)) prcode(fp, " PyObject *%aKeep%s;\n" , mod, ad, argnr, (ad->defval != NULL ? " = 0" : "")); switch (atype) { case class_type: if (!isArray(ad) && ad->u.cd->convtocode != NULL && !isConstrained(ad)) prcode(fp, " int %aState = 0;\n" , mod, ad, argnr); break; case mapped_type: if (!noRelease(ad->u.mtd) && !isConstrained(ad)) prcode(fp, " int %aState = 0;\n" , mod, ad, argnr); break; case ascii_string_type: case latin1_string_type: case utf8_string_type: if (!keepReference(ad) && ad->nrderefs == 1) prcode(fp, " PyObject *%aKeep%s;\n" , mod, ad, argnr, (ad->defval != NULL ? " = 0" : "")); break; case anyslot_type: prcode(fp, " PyObject *%aCallable", mod, ad, argnr); generateDefaultValue(mod, ad, argnr, fp); prcode(fp, ";\n" ); break; /* Supress a compiler warning. */ default: ; } } } /* * Generate a default value. */ static void generateDefaultValue(moduleDef *mod, 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, "&%adef", mod, ad, argnr); else generateExpression(ad->defval, FALSE, fp); } } /* * Generate a simple function call. */ static void generateSimpleFunctionCall(fcallDef *fcd, int in_str, 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], in_str, 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, int py_debug, FILE *fp) { const char *sep; int is_slots, nr_methods, nr_enums, nr_vars, plugin; 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; propertyDef *pd; mod = cd->iff->module; 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 (md->slot == long_slot) prcode(fp, "#else\n" " {(void *)slot_%L_%s, %s},\n" , cd->iff, md->pyname->text, slotName(int_slot)); 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 property and 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 any docstrings. */ for (pd = cd->properties; pd != NULL; pd = pd->next) { ++nr_vars; if (pd->docstring != NULL) { prcode(fp, "\n" "PyDoc_STRVAR(doc_%L_%s, \"" , cd->iff, pd->name->text); generateDocstringText(pd->docstring, fp); prcode(fp, "\");\n" ); } } /* Generate the variables table. */ if (nr_vars > 0) prcode(fp, "\n" "sipVariableDef variables_%L[] = {\n" , cd->iff); for (pd = cd->properties; pd != NULL; pd = pd->next) { prcode(fp, " {PropertyVariable, %N, &methods_%L[%d], ", pd->name, cd->iff, findMethod(cd, pd->get)->membernr); if (pd->set != NULL) prcode(fp, "&methods_%L[%d], ", cd->iff, findMethod(cd, pd->set)->membernr); else prcode(fp, "NULL, "); /* We don't support a deleter yet. */ prcode(fp, "NULL, "); if (pd->docstring != NULL) prcode(fp, "doc_%L_%s", cd->iff, pd->name->text); else prcode(fp, "NULL"); prcode(fp, "},\n" ); } if (hasVarHandlers(cd)) { varDef *vd; for (vd = pt->vars; vd != NULL; vd = vd->next) if (vd->ecd == cd && needsHandler(vd)) { prcode(fp, " {%s, %N, (PyMethodDef *)varget_%C, ", (isStaticVar(vd) ? "ClassVariable" : "InstanceVariable"), vd->pyname, vd->fqcname); if (canSetVariable(vd)) prcode(fp, "(PyMethodDef *)varset_%C", vd->fqcname); else prcode(fp, "NULL"); prcode(fp, ", NULL, NULL},\n" ); } } if (nr_vars > 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. */ if (hasClassDocstring(pt, cd)) { prcode(fp, "\n" "PyDoc_STRVAR(doc_%L, \"", cd->iff); generateClassDocstring(pt, cd, fp); prcode(fp, "\");\n" ); has_docstring = TRUE; } else { has_docstring = FALSE; } /* Generate any plugin-specific data structures. */ if (pluginPyQt5(pt)) plugin = generatePyQt5ClassPlugin(pt, cd, fp); else if (pluginPyQt4(pt)) plugin = generatePyQt4ClassPlugin(pt, cd, fp); else plugin = FALSE; prcode(fp, "\n" "\n" "sipClassTypeDef "); generateTypeDefName(cd->iff, fp); prcode(fp, " = {\n" " {\n" " %P,\n" " " , cd->iff->api_range); generateTypeDefLink(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 (hasNonlazyMethod(cd)) { prcode(fp, "%sSIP_TYPE_NONLAZY", sep); sep = "|"; } if (isCallSuperInitYes(mod)) { prcode(fp, "%sSIP_TYPE_SUPER_INIT", sep); sep = "|"; } if (!py_debug && useLimitedAPI(mod)) { prcode(fp, "%sSIP_TYPE_LIMITED_API", 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" , cd->iff->name); if (plugin) prcode(fp, " &plugin_%L\n" , cd->iff); else prcode(fp, " 0\n" ); prcode(fp, " },\n" " {\n" ); 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 (pyScope(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_type_%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" ); else prcode(fp, " release_%L,\n" , cd->iff); if (cd->supers != NULL) prcode(fp, " cast_%L,\n" , cd->iff); else prcode(fp, " 0,\n" ); 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" ); } if (cd->iff->type == namespace_iface) { prcode(fp, " 0,\n" ); } else { if (cd->convfromcode != NULL) prcode(fp, " convertFrom_%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 (cd->finalcode != NULL) prcode(fp, " final_%C,\n" , classFQCName(cd)); else prcode(fp, " 0,\n" ); if (isMixin(cd)) prcode(fp, " mixin_%C\n" , classFQCName(cd)); else prcode(fp, " 0\n" ); prcode(fp, "};\n" ); } /* * See if an overload has optional arguments. */ static int hasOptionalArgs(overDef *od) { return (od->cppsig->nrArgs > 0 && od->cppsig->args[od->cppsig->nrArgs - 1].defval != NULL); } /* * Generate the PyQt5 emitters for a class. */ static void generatePyQt5Emitters(classDef *cd, FILE *fp) { moduleDef *mod = cd->iff->module; memberDef *md; for (md = cd->members; md != NULL; md = md->next) { int in_emitter = FALSE; overDef *od; for (od = cd->overs; od != NULL; od = od->next) { if (od->common != md || !isSignal(od) || !hasOptionalArgs(od)) continue; if (!in_emitter) { in_emitter = TRUE; prcode(fp, "\n" "\n" ); if (!generating_c) prcode(fp, "extern \"C\" {static int emit_%L_%s(void *, PyObject *);}\n" "\n" , cd->iff, od->cppname); prcode(fp, "static int emit_%L_%s(void *sipCppV, PyObject *sipArgs)\n" "{\n" " PyObject *sipParseErr = NULL;\n" " %V *sipCpp = reinterpret_cast<%V *>(sipCppV);\n" , cd->iff, od->cppname , classFQCName(cd), classFQCName(cd)); } /* * Generate the code that parses the args and emits the appropriate * overloaded signal. */ prcode(fp, "\n" " {\n" ); generateArgParser(mod, &od->pysig, cd, NULL, NULL, NULL, FALSE, fp); prcode(fp, " {\n" " Py_BEGIN_ALLOW_THREADS\n" " sipCpp->%s(" , od->cppname); generateCallArgs(mod, od->cppsig, &od->pysig, fp); prcode(fp, ");\n" " Py_END_ALLOW_THREADS\n" "\n" ); deleteTemps(mod, &od->pysig, fp); prcode(fp, "\n" " return 0;\n" " }\n" " }\n" ); } if (in_emitter) { prcode(fp, "\n" " sipNoMethod(sipParseErr, %N, %N, NULL);\n" "\n" " return -1;\n" "}\n" , cd->pyname, md->pyname); } } } /* * Generate an entry in the PyQt4 or PyQt5 signal table. */ static void generateSignalTableEntry(sipSpec *pt, classDef *cd, overDef *sig, int membernr, int optional_args, FILE *fp) { int a, pyqt5 = pluginPyQt5(pt); prcode(fp, " {\"%s(", sig->cppname); for (a = 0; a < sig->cppsig->nrArgs; ++a) { argDef arg = sig->cppsig->args[a]; if (a > 0) prcode(fp,","); /* Do some normalisation so that Qt doesn't have to. */ if (isConstArg(&arg) && isReference(&arg)) { resetIsConstArg(&arg); resetIsReference(&arg); } generateNamedBaseType(cd->iff, &arg, "", TRUE, StripNamespace, fp); } prcode(fp, ")\", "); if (docstrings) { prcode(fp, "\""); if (sig->docstring != NULL) { generateDocstringText(sig->docstring, fp); } else { fprintf(fp, "\\1"); dsOverload(pt, sig, TRUE, FALSE, fp); } fprintf(fp, "\", "); } else { prcode(fp, "0, "); } if (membernr >= 0) prcode(fp, "&methods_%L[%d], ", cd->iff, membernr); else prcode(fp, "0, "); if (pyqt5) { if (optional_args) prcode(fp, "emit_%L_%s", cd->iff, sig->cppname); else prcode(fp, "0"); } else { prcode(fp, "%d", sig->pyqt_signal_hack); } 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; case setattr_slot: sn = "setattr_slot"; break; case matmul_slot: sn = "matmul_slot"; break; case imatmul_slot: sn = "imatmul_slot"; break; case await_slot: sn = "await_slot"; break; case aiter_slot: sn = "aiter_slot"; break; case anext_slot: sn = "anext_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) { argDef *ad = &ct->pysig.args[a]; if (!isInArg(ad)) continue; if (keepReference(ad)) need_self = TRUE; if (isThisTransferred(ad)) need_owner = TRUE; } } } prcode(fp, "\n" "\n" ); if (!generating_c) prcode(fp, "extern \"C\" {static void *init_type_%L(sipSimpleWrapper *, PyObject *, PyObject *, PyObject **, PyObject **, PyObject **);}\n" , cd->iff); prcode(fp, "static void *init_type_%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_type_%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(mod, &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(mod, &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->od)) ++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, int rgil) { /* * 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(mod, ta->args[a], sd, fp, rgil); } else if (mod->defexception != NULL) { generateCatchBlock(mod, mod->defexception, sd, fp, rgil); } prcode(fp, " catch (...)\n" " {\n" ); if (rgil) prcode(fp, " Py_BLOCK_THREADS\n" "\n" ); deleteOuts(mod, sd, fp); deleteTemps(mod, sd, fp); prcode(fp, " sipRaiseUnknownException();\n" " return NULL;\n" " }\n" ); } } /* * Generate a single catch block. */ static void generateCatchBlock(moduleDef *mod, exceptionDef *xd, signatureDef *sd, FILE *fp, int rgil) { scopedNameDef *ename = xd->iff->fqcname; prcode(fp, " catch (%S &%s)\n" " {\n" ,ename,(xd->cd != NULL || usedInCode(xd->raisecode, "sipExceptionRef")) ? "sipExceptionRef" : ""); if (rgil) prcode(fp, "\n" " Py_BLOCK_THREADS\n" ); deleteOuts(mod, sd, fp); deleteTemps(mod, 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 (ct->premethodcode != NULL) { prcode(fp, "\n"); generateCppCodeBlock(ct->premethodcode,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 (struct %S));\n" ,classFQCName(cd)); else { int a; int rgil = ((release_gil || isReleaseGILCtor(ct)) && !isHoldGILCtor(ct)); if (raisesPyExceptionCtor(ct)) prcode(fp, " PyErr_Clear();\n" "\n" ); 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(mod, ct->cppsig, &ct->pysig, fp); prcode(fp,");\n" ); generateCatch(ct->exceptions, &ct->pysig, mod, fp, rgil); if (rgil) prcode(fp, " Py_END_ALLOW_THREADS\n" ); /* Handle any /KeepReference/ arguments. */ for (a = 0; a < ct->pysig.nrArgs; ++a) { argDef *ad = &ct->pysig.args[a]; if (!isInArg(ad)) continue; if (keepReference(ad)) { prcode(fp, "\n" " sipKeepReference((PyObject *)sipSelf, %d, %a%s);\n" , ad->key, mod, ad, a, (((ad->atype == ascii_string_type || ad->atype == latin1_string_type || ad->atype == utf8_string_type) && ad->nrderefs == 1) || !isGetWrapper(ad) ? "Keep" : "Wrapper")); } } /* * 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(mod, &ct->pysig, fp); prcode(fp, "\n" ); if (raisesPyExceptionCtor(ct)) { prcode(fp, " if (PyErr_Occurred())\n" " {\n" " delete sipCpp;\n" " return NULL;\n" " }\n" "\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; /* * 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 = 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 (need_method) { const char *pname = md->pyname->text; int has_auto_docstring; prcode(fp, "\n" "\n" ); /* Generate the docstrings. */ if (hasMemberDocstring(pt, overs, md, cd->iff)) { prcode(fp, "PyDoc_STRVAR(doc_%L_%s, \"" , cd->iff, pname); has_auto_docstring = generateMemberDocstring(pt, overs, md, TRUE, fp); prcode(fp, "\");\n" "\n" ); } else { has_auto_docstring = FALSE; } if (!generating_c) prcode(fp, "extern \"C\" {static PyObject *meth_%L_%s(PyObject *, PyObject *%s);}\n" , cd->iff, pname, (noArgParser(md) || useKeywordArgs(md) ? ", 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) || useKeywordArgs(md) ? ", 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++ sub-class 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. * * Note that we would like to rename 'sipSelfWasArg' to * 'sipExplicitScope' but it is part of the public API. */ prcode(fp, " bool sipSelfWasArg = (!sipSelf || sipIsDerivedClass((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(mod, &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(mod, &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(mod, &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(moduleDef *mod, overDef *od, int isNew, int result_size, char *prefix, FILE *fp) { const char *vname; char 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" : resultOwner(od))); /* * 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", mod, ad, 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]; if (useArgNames(mod) && ad->name != NULL) { vname = ad->name->text; } else { 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) { const char *cast_prefix, *cast_suffix; if (generating_c) { cast_prefix = cast_suffix = ""; } else { cast_prefix = "static_cast("; cast_suffix = ")"; } prcode(fp, " %s sipConvertFromEnum(%s%s%s, sipType_%C);\n" , prefix, cast_prefix, vname, cast_suffix, ad->u.ed->fqcname); break; } /* Drop through. */ case byte_type: case sbyte_type: 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 ubyte_type: case ushort_type: prcode(fp, "#if PY_MAJOR_VERSION >= 3\n" " %s PyLong_FromUnsignedLong(%s);\n" "#else\n" " %s PyInt_FromLong(%s);\n" "#endif\n" , prefix, vname , prefix, vname); break; 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: { prcode(fp, " %s sipConvertFrom%sVoidPtr", prefix, (isConstArg(ad) ? "Const" : "")); if (result_size < 0) { prcode(fp, "("); generateVoidPtrCast(ad, fp); prcode(fp, "%s", vname); } else { prcode(fp, "AndSize("); generateVoidPtrCast(ad, fp); prcode(fp, "%s,%a", vname, mod, &od->pysig.args[result_size], result_size); } prcode(fp, ");\n" ); } break; case capsule_type: prcode(fp, " %s SIPCapsule_FromVoidPtr(%s, \"%S\");\n" , prefix, vname, ad->u.cap); 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: case pybuffer_type: prcode(fp, " %s %s;\n" ,prefix,vname); break; /* Supress a compiler warning. */ default: ; } } /* * 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"; } /* * Check if an argument is a string rather than a char type. */ static int isString(argDef *ad) { int nrderefs = ad->nrderefs; if (isOutArg(ad) && !isReference(ad)) --nrderefs; return nrderefs > 0; } /* * 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: case latin1_string_type: case utf8_string_type: return isString(ad) ? "A" : "a"; case sstring_type: case ustring_type: case string_type: return isString(ad) ? "s" : "c"; case wstring_type: return isString(ad) ? "x" : "w"; case enum_type: return (ad->u.ed->fqcname != NULL) ? "F" : "e"; case byte_type: case sbyte_type: return "L"; case ubyte_type: return "M"; 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 capsule_type: return "z"; 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: case pybuffer_type: return "R"; /* Supress a compiler warning. */ default: ; } /* 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 variable to hold the result of a function call if one is needed. */ static int generateResultVar(ifaceFileDef *scope, overDef *od, argDef *res, const char *indent, FILE *fp) { int is_result; /* See if sipRes is needed. */ is_result = (!isInplaceNumberSlot(od->common) && !isInplaceSequenceSlot(od->common) && (res->atype != void_type || res->nrderefs != 0)); if (is_result) { prcode(fp, "%s", indent); 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" ); } return is_result; } /* * 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, post_process, static_factory; 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; } static_factory = ((scope == NULL || isStatic(od)) && isFactory(od)); 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); is_result = newline = generateResultVar(scope, od, res, " ", fp); result_size = -1; deltemps = TRUE; post_process = FALSE; /* See if we want to keep a reference to the result. */ if (keepReference(res)) post_process = TRUE; for (a = 0; a < od->pysig.nrArgs; ++a) { argDef *ad = &od->pysig.args[a]; if (isResultSize(ad)) result_size = a; if (static_factory && keepReference(ad)) post_process = TRUE; /* * 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 = FALSE; post_process = 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 = new %b();\n" , mod, ad, a, ad); newline = TRUE; } } if (post_process) { prcode(fp, " PyObject *sipResObj;\n" ); newline = TRUE; } if (od->premethodcode != NULL) { prcode(fp, "\n"); generateCppCodeBlock(od->premethodcode,fp); } 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)); int closing_paren = FALSE; 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 (raisesPyException(od)) prcode(fp, " PyErr_Clear();\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); closing_paren = TRUE; } } 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(mod, scope, o_scope, od, fp); break; case getitem_slot: prcode(fp, "(*sipCpp)["); generateSlotArg(mod, &od->pysig, 0, fp); prcode(fp,"]"); break; case call_slot: prcode(fp, "(*sipCpp)("); generateCallArgs(mod, 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(mod, od, "+", fp); break; case concat_slot: generateBinarySlotCall(mod, scope, od, "+", deref, fp); break; case sub_slot: generateNumberSlotCall(mod, od, "-", fp); break; case mul_slot: case matmul_slot: generateNumberSlotCall(mod, od, "*", fp); break; case repeat_slot: generateBinarySlotCall(mod, scope, od, "*", deref, fp); break; case div_slot: case truediv_slot: generateNumberSlotCall(mod, od, "/", fp); break; case mod_slot: generateNumberSlotCall(mod, od, "%", fp); break; case and_slot: generateNumberSlotCall(mod, od, "&", fp); break; case or_slot: generateNumberSlotCall(mod, od, "|", fp); break; case xor_slot: generateNumberSlotCall(mod, od, "^", fp); break; case lshift_slot: generateNumberSlotCall(mod, od, "<<", fp); break; case rshift_slot: generateNumberSlotCall(mod, od, ">>", fp); break; case iadd_slot: case iconcat_slot: generateBinarySlotCall(mod, scope, od, "+=", deref, fp); break; case isub_slot: generateBinarySlotCall(mod, scope, od, "-=", deref, fp); break; case imul_slot: case irepeat_slot: case imatmul_slot: generateBinarySlotCall(mod, scope, od, "*=", deref, fp); break; case idiv_slot: case itruediv_slot: generateBinarySlotCall(mod, scope, od, "/=", deref, fp); break; case imod_slot: generateBinarySlotCall(mod, scope, od, "%=", deref, fp); break; case iand_slot: generateBinarySlotCall(mod, scope, od, "&=", deref, fp); break; case ior_slot: generateBinarySlotCall(mod, scope, od, "|=", deref, fp); break; case ixor_slot: generateBinarySlotCall(mod, scope, od, "^=", deref, fp); break; case ilshift_slot: generateBinarySlotCall(mod, scope, od, "<<=", deref, fp); break; case irshift_slot: generateBinarySlotCall(mod, scope, od, ">>=", deref, fp); break; case invert_slot: prcode(fp, "~(*sipCpp)"); break; case lt_slot: generateComparisonSlotCall(mod, scope, od, "<", ">=", deref, fp); break; case le_slot: generateComparisonSlotCall(mod, scope, od, "<=", ">", deref, fp); break; case eq_slot: generateComparisonSlotCall(mod, scope, od, "==", "!=", deref, fp); break; case ne_slot: generateComparisonSlotCall(mod, scope, od, "!=", "==", deref, fp); break; case gt_slot: generateComparisonSlotCall(mod, scope, od, ">", "<=", deref, fp); break; case ge_slot: generateComparisonSlotCall(mod, 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(mod, scope, od, "<", deref, fp); prcode(fp,"\n" " sipRes = -1;\n" " else if "); generateBinarySlotCall(mod, scope, od, ">", deref, fp); prcode(fp,"\n" " sipRes = 1;\n" " else\n" " sipRes = 0"); break; /* Supress a compiler warning. */ default: ; } if (closing_paren) prcode(fp,")"); prcode(fp,";\n" ); generateCatch(od->exceptions, &od->pysig, mod, fp, rgil); 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 except for static factories. */ if (!static_factory && keepReference(ad)) { prcode(fp, "\n" " sipKeepReference(%s, %d, %a%s);\n" , (scope == NULL || isStatic(od) ? "NULL" : "sipSelf"), ad->key, mod, ad, 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(mod, &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 (raisesPyException(od)) { prcode(fp, " if (PyErr_Occurred())\n" " return %s;\n" "\n" , error_value); } else if (error_flag) { if (!isZeroArgSlot(od->common)) prcode(fp, " if (sipError == sipErrorFail)\n" " return %s;\n" "\n" , error_value); prcode(fp, " if (sipError == sipErrorNone)\n" " {\n" ); } 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(mod, od, needsNew, result_size, (post_process ? "sipResObj =" : "return"), fp); /* Delete the temporaries now if we haven't already done so. */ if (!deltemps) deleteTemps(mod, &od->pysig, fp); /* * Keep a reference to a pointer to a class if it isn't owned by * Python. */ if (keepReference(res)) prcode(fp, "\n" " sipKeepReference(%s, %d, sipResObj);\n" , (isStatic(od) ? "NULL" : "sipSelf"), res->key); /* * Keep a reference to any argument with the result if the function is * a static factory. */ if (static_factory) { for (a = 0; a < od->pysig.nrArgs; ++a) { argDef *ad = &od->pysig.args[a]; if (!isInArg(ad)) continue; if (keepReference(ad)) { prcode(fp, "\n" " sipKeepReference(sipResObj, %d, %a%s);\n" , ad->key, mod, ad, a, (((ad->atype == ascii_string_type || ad->atype == latin1_string_type || ad->atype == utf8_string_type) && ad->nrderefs == 1) || !isGetWrapper(ad) ? "Keep" : "Wrapper")); } } } if (post_process) prcode(fp, "\n" " return sipResObj;\n" ); } if (error_flag) { prcode(fp, " }\n" ); if (!isZeroArgSlot(od->common)) prcode(fp, "\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(moduleDef *mod, 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(mod, od->cppsig, &od->pysig, fp); prcode(fp, ") : sipCpp->%s(", mname); ++parens; } else prcode(fp, "sipCpp->%s(", mname); generateCallArgs(mod, od->cppsig, &od->pysig, fp); while (parens--) prcode(fp, ")"); } /* * Generate argument to a slot. */ static void generateSlotArg(moduleDef *mod, 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, "%s%a", (deref ? "*" : ""), mod, ad, argnr); } /* * Generate the call to a comparison slot method. */ static void generateComparisonSlotCall(moduleDef *mod, 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 it has been moved from a namespace then get the C++ scope. */ if (od->common->ns_scope != NULL) prcode(fp, "%S::", od->common->ns_scope->fqcname); if (deref) prcode(fp, "operator%s((*sipCpp), ", op); else prcode(fp, "operator%s(sipCpp, ", op); } generateSlotArg(mod, &od->pysig, 0, fp); prcode(fp, ")"); } /* * Generate the call to a binary (non-number) slot method. */ static void generateBinarySlotCall(moduleDef *mod, ifaceFileDef *scope, overDef *od, const char *op, int deref, FILE *fp) { generateComparisonSlotCall(mod, scope, od, op, "", deref, fp); } /* * Generate the call to a binary number slot method. */ static void generateNumberSlotCall(moduleDef *mod, overDef *od, char *op, FILE *fp) { prcode(fp, "("); generateSlotArg(mod, &od->pysig, 0, fp); prcode(fp, " %s ", op); generateSlotArg(mod, &od->pysig, 1, fp); prcode(fp, ")"); } /* * Generate the argument variables for a member function/constructor/operator. */ static int generateArgParser(moduleDef *mod, 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; argDef *arraylenarg_ad, *sigarg_ad, *slotconarg_ad, *slotdisarg_ad; /* Suppress compiler warnings. */ arraylenarg = slotconarg = slotdisarg = 0; arraylenarg_ad = sigarg_ad = slotconarg_ad = slotdisarg_ad = NULL; 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_ad = ad; sigarg = a; break; case rxcon_type: case rxdis_type: isQtSlot = TRUE; break; case slotcon_type: slotconarg_ad = ad; slotconarg = a; break; case slotdis_type: slotdisarg_ad = ad; slotdisarg = a; break; /* Supress a compiler warning. */ default: ; } if (isArraySize(ad)) { arraylenarg_ad = ad; arraylenarg = a; } generateVariable(mod, scope, ad, a, fp); if (isThisTransferred(ad)) need_owner = TRUE; } if (od != NULL && need_owner) prcode(fp, " sipWrapper *sipOwner = 0;\n" ); if (handle_self) { const char *const_str = (isConst(od) ? "const " : ""); if (isProtected(od) && hasShadow(c_scope)) prcode(fp, " %ssip%C *sipCpp;\n" , const_str, classFQCName(c_scope)); else prcode(fp, " %s%U *sipCpp;\n" , const_str, 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(&sipParseErr, sipArg0, sipArg1, \""); } else if (od != NULL && od->common->slot == setattr_slot) { /* * We don't even try to invoke the parser if there is a value and there * shouldn't be (or vice versa) so that the list of errors doesn't get * poluted with signatures that can never apply. */ prcode(fp, " if (sipValue %s NULL && sipParsePair(&sipParseErr, sipName, %s, \"", (isDelattr(od) ? "==" : "!="), (isDelattr(od) ? "NULL" : "sipValue")); } else if ((od != NULL && useKeywordArgs(od->common)) || ct != NULL) { KwArgs kwargs; int is_ka_list; /* * 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. */ if (od != NULL) kwargs = od->kwargs; else if (ct != NULL) kwargs = ct->kwargs; else kwargs = NoKwArgs; /* * The above test isn't good enough because when the flags were set in * the parser we couldn't know for sure if an argument was an output * pointer. Therefore we check here. The drawback is that we may * generate the name string for the argument but never use it, or we * might have an empty keyword name array or one that contains only * NULLs. */ is_ka_list = FALSE; if (kwargs != NoKwArgs) { int a; for (a = 0; a < sd->nrArgs; ++a) { argDef *ad = &sd->args[a]; if (isInArg(ad)) { if (!is_ka_list) { prcode(fp, " static const char *sipKwdList[] = {\n" ); is_ka_list = TRUE; } if (ad->name != NULL && (kwargs == AllKwArgs || ad->defval != NULL)) prcode(fp, " %N,\n" , ad->name); else prcode(fp, " NULL,\n" ); } } if (is_ka_list) prcode(fp, " };\n" "\n" ); } prcode(fp, " if (sipParseKwdArgs(%ssipParseErr, sipArgs, sipKwds, %s, %s, \"", (ct != NULL ? "" : "&"), (is_ka_list ? "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 (isString(ad)) fmt = "AA"; else fmt = "aA"; break; case latin1_string_type: if (isString(ad)) fmt = "AL"; else fmt = "aL"; break; case utf8_string_type: if (isString(ad)) fmt = "A8"; else fmt = "a8"; break; case sstring_type: case ustring_type: case string_type: if (isArray(ad)) fmt = "k"; else if (isString(ad)) fmt = "s"; else fmt = "c"; break; case wstring_type: if (isArray(ad)) fmt = "K"; else if (isString(ad)) fmt = "x"; else fmt = "w"; 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 byte_type: case sbyte_type: if (!isArraySize(ad)) fmt = "L"; break; case ubyte_type: if (!isArraySize(ad)) fmt = "M"; 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 capsule_type: fmt = "z"; 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 pybuffer_type: fmt = (isAllowNone(ad) ? "$" : "!"); break; case qobject_type: fmt = "R"; break; case ellipsis_type: fmt = "W"; break; /* Supress a compiler warning. */ default: ; } /* * 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, ", &%aWrapper", mod, ad, a); else if (keepReference(ad)) prcode(fp, ", &%aKeep", mod, ad, a); switch (ad->atype) { case mapped_type: prcode(fp, ", sipType_%T,&%a", ad, mod, ad, a); if (isArray(ad)) { prcode(fp, ", &%a", mod, arraylenarg_ad, arraylenarg); } else if (!isConstrained(ad)) { if (noRelease(ad->u.mtd)) prcode(fp, ",NULL"); else prcode(fp, ", &%aState", mod, ad, a); } break; case class_type: prcode(fp, ", sipType_%T, &%a", ad, mod, ad, a); if (isArray(ad)) { prcode(fp, ", &%a", mod, arraylenarg_ad, arraylenarg); } else { if (isThisTransferred(ad)) prcode(fp, ", %ssipOwner", (ct != NULL ? "" : "&")); if (ad->u.cd->convtocode != NULL && !isConstrained(ad)) prcode(fp, ", &%aState", mod, ad, a); } break; case ascii_string_type: if (!keepReference(ad) && ad->nrderefs == 1) prcode(fp, ", &%aKeep", mod, ad, a); prcode(fp, ", &%a", mod, ad, a); break; case latin1_string_type: if (!keepReference(ad) && ad->nrderefs == 1) prcode(fp, ", &%aKeep", mod, ad, a); prcode(fp, ", &%a", mod, ad, a); break; case utf8_string_type: if (!keepReference(ad) && ad->nrderefs == 1) prcode(fp, ", &%aKeep", mod, ad, a); prcode(fp, ", &%a", mod, ad, a); break; case rxcon_type: { if (sigarg > 0) prcode(fp, ", %a", mod, sigarg_ad, sigarg); else { prcode(fp,", \"("); generateCalledArgs(NULL, scope, slotconarg_ad->u.sa, Declaration, fp); prcode(fp,")\""); } prcode(fp, ", &%a, &%a", mod, ad, a, mod, slotconarg_ad, slotconarg); break; } case rxdis_type: { prcode(fp,", \"("); generateCalledArgs(NULL, scope, slotdisarg_ad->u.sa, Declaration, fp); prcode(fp, ")\", &%a, &%a", mod, ad, a, mod, slotdisarg_ad, slotdisarg); break; } case slotcon_type: case slotdis_type: if (!secCall) prcode(fp, ", &%a", mod, ad, a); break; case anyslot_type: prcode(fp, ", &%aName, &%aCallable", mod, ad, a, mod, ad, a); break; case pytuple_type: prcode(fp, ", &PyTuple_Type, &%a", mod, ad, a); break; case pylist_type: prcode(fp, ", &PyList_Type, &%a", mod, ad, a); break; case pydict_type: prcode(fp, ", &PyDict_Type, &%a", mod, ad, a); break; case pyslice_type: prcode(fp, ", &PySlice_Type, &%a", mod, ad, a); break; case pytype_type: prcode(fp, ", &PyType_Type, &%a", mod, ad, a); break; case enum_type: if (ad->u.ed->fqcname != NULL) prcode(fp, ", sipType_%C", ad->u.ed->fqcname); prcode(fp, ", &%a", mod, ad, a); break; case capsule_type: prcode(fp, ", \"%S\", &%a", ad->u.cap, mod, ad, a); break; default: if (!isArraySize(ad)) prcode(fp, ", &%a", mod, ad, a); if (isArray(ad)) prcode(fp, ", &%a", mod, arraylenarg_ad, 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 || isDisallowNone(ad)) 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) { codeBlockList *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(moduleDef *mod, 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;\n" , mod, ad, a); } } /* * Delete any temporary variables on the heap created by type convertors. */ static void deleteTemps(moduleDef *mod, 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 (!isTransferred(ad)) { if (generating_c) prcode(fp, " sipFree(%a);\n" , mod, ad, a); else prcode(fp, " delete[] %a;\n" , mod, ad, 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(%aKeep);\n" , (ad->defval != NULL ? "X" : ""), mod, ad, a); } else if (ad->atype == wstring_type && ad->nrderefs == 1) { if (generating_c || !isConstArg(ad)) prcode(fp, " sipFree(%a);\n" , mod, ad, a); else prcode(fp, " sipFree(const_cast(%a));\n" , mod, ad, a); } else if (hasConvertToCode(ad)) { if (ad->atype == mapped_type && noRelease(ad->u.mtd)) continue; if (generating_c || !isConstArg(ad)) prcode(fp, " sipReleaseType(%a,sipType_%T,%aState);\n" , mod, ad, a, ad, mod, ad, a); else prcode(fp, " sipReleaseType(const_cast<%b *>(%a),sipType_%T,%aState);\n" , ad, mod, ad, a, ad, mod, ad, a); } } } /* * Generate a list of C++ code blocks. */ static void generateCppCodeBlock(codeBlockList *cbl, FILE *fp) { int reset_line = FALSE; while (cbl != NULL) { codeBlock *cb = cbl->block; /* * Fragmented fragments (possibly created when applying template types) * don't have a filename. */ if (cb->filename != NULL) { generatePreprocLine(cb->linenr, cb->filename, fp); reset_line = TRUE; } prcode(fp, "%s", cb->frag); cbl = cbl->next; } if (reset_line) generatePreprocLine(currentLineNr + 1, currentFileName, fp); } /* * Generate a #line preprocessor directive. */ static void generatePreprocLine(int linenr, const char *fname, FILE *fp) { prcode(fp, "#line %d \"", linenr); while (*fname != '\0') { prcode(fp, "%c", *fname); if (*fname == '\\') prcode(fp, "\\"); ++fname; } prcode(fp, "\"\n" ); } /* * 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) { /* Write the header. */ prcode(fp, "/*\n" " * %s\n" " *\n" " * Generated by SIP %s\n" , description , sipVersion); prCopying(fp, mod, " *"); prcode(fp, " */\n" ); } return fp; } /* * Generate any copying (ie. licensing) text as a comment. */ void prCopying(FILE *fp, moduleDef *mod, const char *comment) { int needComment = TRUE; codeBlockList *cbl; if (mod->copying != NULL) prcode(fp, "%s\n", comment); for (cbl = mod->copying; cbl != NULL; cbl = cbl->next) { const char *cp; for (cp = cbl->block->frag; *cp != '\0'; ++cp) { if (needComment) { needComment = FALSE; prcode(fp, "%s ", comment); } prcode(fp, "%c", *cp); if (*cp == '\n') needComment = TRUE; } } } /* * 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 'a': { moduleDef *mod = va_arg(ap, moduleDef *); argDef *ad = va_arg(ap, argDef *); int argnr = va_arg(ap, int); if (useArgNames(mod) && ad->name != NULL) fprintf(fp, "%s", ad->name->text); else fprintf(fp, "a%d", argnr); break; } case 'A': { ifaceFileDef *scope = va_arg(ap, ifaceFileDef *); argDef *ad = va_arg(ap, argDef *); generateBaseType(scope, ad, TRUE, StripNone, fp); break; } case 'b': { argDef *ad, orig; ad = va_arg(ap,argDef *); orig = *ad; resetIsConstArg(ad); resetIsReference(ad); ad->nrderefs = 0; generateBaseType(NULL, ad, TRUE, StripNone, fp); *ad = orig; break; } case 'B': generateBaseType(NULL, va_arg(ap,argDef *), TRUE, StripNone, fp); break; case 'c': { char c = (char)va_arg(ap,int); if (c == '\n') ++currentLineNr; fputc(c,fp); break; } case 'C': prScopedName(fp, removeGlobalScope(va_arg(ap,scopedNameDef *)), "_"); break; case 'd': fprintf(fp,"%d",va_arg(ap,int)); break; case 'D': { /* * This is the same as 'b' but never uses a typedef's name. */ argDef *ad, orig; ad = va_arg(ap,argDef *); orig = *ad; resetIsConstArg(ad); resetIsReference(ad); ad->nrderefs = 0; generateBaseType(NULL, ad, FALSE, StripNone, fp); *ad = orig; 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, removeGlobalScope(va_arg(ap,scopedNameDef *)), ""); break; case 'g': fprintf(fp,"%g",va_arg(ap,double)); break; case 'I': { int indent = va_arg(ap,int); while (indent-- > 0) fputc('\t',fp); break; } case 'l': fprintf(fp,"%ld",va_arg(ap,long)); break; case 'L': { ifaceFileDef *iff = va_arg(ap, ifaceFileDef *); prScopedName(fp, removeGlobalScope(iff->fqcname), "_"); if (iff->api_range != NULL) fprintf(fp, "_%d", iff->api_range->index); break; } case 'M': prcode_xml = !prcode_xml; break; case 'n': { nameDef *nd = va_arg(ap,nameDef *); prCachedName(fp, nd, "sipNameNr_"); break; } case 'N': { nameDef *nd = va_arg(ap,nameDef *); prCachedName(fp, nd, "sipName_"); break; } case 'O': prOverloadName(fp, va_arg(ap, overDef *)); break; case 'P': { apiVersionRangeDef *avr = va_arg(ap, apiVersionRangeDef *); fprintf(fp, "%d", (avr != NULL ? avr->index : -1)); break; } case 's': { const char *cp = va_arg(ap,const char *); while (*cp != '\0') { if (*cp == '\n') ++currentLineNr; fputc(*cp,fp); ++cp; } break; } case 'S': prScopedName(fp, va_arg(ap, scopedNameDef *), "::"); break; case 'T': prTypeName(fp, va_arg(ap,argDef *)); break; case 'u': fprintf(fp,"%u",va_arg(ap,unsigned)); break; case 'U': { classDef *cd = va_arg(ap, classDef *); if (generating_c) fprintf(fp,"struct "); prScopedClassName(fp, cd->iff, cd, StripNone); break; } case 'V': prScopedName(fp, removeGlobalScope(va_arg(ap, scopedNameDef *)), "::"); break; case 'x': fprintf(fp,"0x%08x",va_arg(ap,unsigned)); break; case 'X': generateThrowSpecifier(va_arg(ap,throwArgs *),fp); break; case '\n': fputc('\n',fp); ++currentLineNr; break; case '\0': fputc('%',fp); --fmt; 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) { /* Precede an explicit global scope with a space to avoid '<::'. */ fprintf(fp, "%s", (snd->name[0] != '\0' ? snd->name : " ")); if ((snd = snd->next) != NULL) fprintf(fp, "%s", sep); } } /* * Generate a scoped class name. Protected classes have to be explicitly * scoped. */ static void prScopedClassName(FILE *fp, ifaceFileDef *scope, classDef *cd, StripAction strip) { if (useTemplateName(cd)) { prTemplateType(fp, scope, cd->td, strip); } else if (isProtectedClass(cd)) { /* This should never happen. */ if (scope == NULL) scope = cd->iff; prcode(fp, "sip%C::sip%s", scope->fqcname, classBaseName(cd)); } else { prScopedName(fp, stripScope(classFQCName(cd), cd->ecd, strip), "::"); } } /* * 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(codeBlockList *cbl) { return usedInCode(cbl, "sipError"); } /* * Return TRUE if handwritten code uses the deprecated error flag. */ static int needOldErrorFlag(codeBlockList *cbl) { return usedInCode(cbl, "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, codeBlockList *cbl) { 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(cbl, name)) return name; /* Don't use the name and avoid a compiler warning. */ return noname; } /* * Returns TRUE if a string is used in code. */ static int usedInCode(codeBlockList *cbl, const char *str) { while (cbl != NULL) { if (strstr(cbl->block->frag, str) != NULL) return TRUE; cbl = cbl->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, "struct %S *%s = (struct %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(argDef *ad) { char encoding; switch (ad->atype) { case ascii_string_type: encoding = 'A'; break; case latin1_string_type: encoding = 'L'; break; case utf8_string_type: encoding = '8'; break; case wstring_type: encoding = ((ad->nrderefs == 0) ? 'w' : 'W'); break; default: encoding = 'N'; } return encoding; } /* * Return TRUE if a docstring can be automatically generated for a function * overload. */ static int overloadHasAutoDocstring(sipSpec *pt, overDef *od) { if (!docstrings) return FALSE; /* If it is versioned then make sure it is the default API. */ return inDefaultAPI(pt, od->api_range); } /* * Return TRUE if a function/method has a docstring. */ static int hasMemberDocstring(sipSpec *pt, overDef *overs, memberDef *md, ifaceFileDef *scope) { int auto_docstring = FALSE; overDef *od; /* * Check for any explicit docstrings and remember if there were any that * could be automatically generated. */ for (od = overs; od != NULL; od = od->next) { if (od->common != md) continue; if (isPrivate(od) || isSignal(od)) continue; if (od->docstring != NULL) return TRUE; if (overloadHasAutoDocstring(pt, od)) auto_docstring = TRUE; } if (noArgParser(md)) return FALSE; if (scope != NULL && !inDefaultAPI(pt, scope->api_range)) return FALSE; return auto_docstring; } /* * Generate the docstring for all overloads of a function/method. Return TRUE * if the docstring was entirely automatically generated. */ static int generateMemberDocstring(sipSpec *pt, overDef *overs, memberDef *md, int is_method, FILE *fp) { int auto_docstring = TRUE; int is_first, all_auto, any_implied; static const char *newline = "\\n\"\n\""; overDef *od; /* See if all the docstrings are automatically generated. */ all_auto = TRUE; any_implied = FALSE; for (od = overs; od != NULL; od = od->next) { if (od->common != md) continue; if (isPrivate(od) || isSignal(od)) continue; if (od->docstring != NULL) { all_auto = FALSE; if (od->docstring->signature != discarded) any_implied = TRUE; } } /* Generate the docstring. */ is_first = TRUE; for (od = overs; od != NULL; od = od->next) { if (od->common != md) continue; if (isPrivate(od) || isSignal(od)) continue; if (!is_first) { prcode(fp, newline); /* * Insert a blank line if any explicit docstring wants to include a * signature. This maintains compatibility with previous versions. */ if (any_implied) prcode(fp, newline); } if (od->docstring != NULL) { if (od->docstring->signature == prepended) { generateMemberAutoDocstring(pt, od, is_method, fp); prcode(fp, newline); } generateDocstringText(od->docstring, fp); if (od->docstring->signature == appended) { prcode(fp, newline); generateMemberAutoDocstring(pt, od, is_method, fp); } auto_docstring = FALSE; } else if (all_auto || any_implied) { generateMemberAutoDocstring(pt, od, is_method, fp); } is_first = FALSE; } return auto_docstring; } /* * Generate the automatic docstring for a function/method. */ static void generateMemberAutoDocstring(sipSpec *pt, overDef *od, int is_method, FILE *fp) { if (overloadHasAutoDocstring(pt, od)) { dsOverload(pt, od, is_method, FALSE, fp); ++currentLineNr; if (hasImplicitOverloads(&od->pysig)) { prcode(fp, "\\n\"\n\""); dsOverload(pt, od, is_method, TRUE, fp); ++currentLineNr; } } } /* * Return TRUE if a docstring can be automatically generated for a ctor. */ static int ctorHasAutoDocstring(sipSpec *pt, ctorDef *ct) { if (!docstrings) return FALSE; /* If it is versioned then make sure it is the default API. */ return inDefaultAPI(pt, ct->api_range); } /* * Return TRUE if a class has a docstring. */ static int hasClassDocstring(sipSpec *pt, classDef *cd) { int auto_docstring = FALSE; ctorDef *ct; /* * Check for any explicit docstrings and remember if there were any that * could be automatically generated. */ if (cd->docstring != NULL) return TRUE; for (ct = cd->ctors; ct != NULL; ct = ct->next) { if (isPrivateCtor(ct)) continue; if (ct->docstring != NULL) return TRUE; if (ctorHasAutoDocstring(pt, ct)) auto_docstring = TRUE; } if (!canCreate(cd)) return FALSE; if (!inDefaultAPI(pt, cd->iff->api_range)) return FALSE; return auto_docstring; } /* * Generate the docstring for a class. */ static void generateClassDocstring(sipSpec *pt, classDef *cd, FILE *fp) { int is_first, all_auto, any_implied; static const char *newline = "\\n\"\n\""; ctorDef *ct; /* See if all the docstrings are automatically generated. */ all_auto = (cd->docstring == NULL); any_implied = FALSE; for (ct = cd->ctors; ct != NULL; ct = ct->next) { if (isPrivateCtor(ct)) continue; if (ct->docstring != NULL) { all_auto = FALSE; if (ct->docstring->signature != discarded) any_implied = TRUE; } } /* Generate the docstring. */ if (all_auto) prcode(fp, "\\1"); if (cd->docstring != NULL && cd->docstring->signature != prepended) { generateDocstringText(cd->docstring, fp); is_first = FALSE; } else { is_first = TRUE; } if (cd->docstring == NULL || cd->docstring->signature != discarded) { for (ct = cd->ctors; ct != NULL; ct = ct->next) { if (isPrivateCtor(ct)) continue; if (!is_first) { prcode(fp, newline); /* * Insert a blank line if any explicit docstring wants to * include a signature. This maintains compatibility with * previous versions. */ if (any_implied) prcode(fp, newline); } if (ct->docstring != NULL) { if (ct->docstring->signature == prepended) { generateCtorAutoDocstring(pt, cd, ct, fp); prcode(fp, newline); } generateDocstringText(ct->docstring, fp); if (ct->docstring->signature == appended) { prcode(fp, newline); generateCtorAutoDocstring(pt, cd, ct, fp); } } else if (all_auto || any_implied) { generateCtorAutoDocstring(pt, cd, ct, fp); } is_first = FALSE; } } if (cd->docstring != NULL && cd->docstring->signature == prepended) { if (!is_first) { prcode(fp, newline); prcode(fp, newline); } generateDocstringText(cd->docstring, fp); } } /* * Generate the automatic docstring for a ctor. */ static void generateCtorAutoDocstring(sipSpec *pt, classDef *cd, ctorDef *ct, FILE *fp) { if (ctorHasAutoDocstring(pt, ct)) { dsCtor(pt, cd, ct, FALSE, fp); ++currentLineNr; if (hasImplicitOverloads(&ct->pysig)) { prcode(fp, "\\n\"\n\""); dsCtor(pt, cd, ct, TRUE, fp); ++currentLineNr; } } } /* * Generate the text of a docstring. */ static void generateDocstringText(docstringDef *docstring, FILE *fp) { const char *cp; for (cp = docstring->text; *cp != '\0'; ++cp) { if (*cp == '\n') { /* Ignore if this is the last character. */ if (cp[1] != '\0') prcode(fp, "\\n\"\n\""); } else { if (*cp == '\\' || *cp == '\"') prcode(fp, "\\"); prcode(fp, "%c", *cp); } } } /* * Generate the definition of a module's optional docstring. */ static void generateModDocstring(moduleDef *mod, FILE *fp) { if (mod->docstring != NULL) { prcode(fp, "\n" "PyDoc_STRVAR(doc_mod_%s, \"", mod->name); generateDocstringText(mod->docstring, fp); prcode(fp, "\");\n" ); } } /* * Generate a void* cast for an argument if needed. */ static void generateVoidPtrCast(argDef *ad, FILE *fp) { /* * Generate a cast if the argument's type was a typedef. This allows us to * use typedef's to void* to hide something more complex that we don't * handle. */ if (ad->original_type != NULL) prcode(fp, "(%svoid *)", (isConstArg(ad) ? "const " : "")); } /* * Declare the use of the limited API. */ static void declareLimitedAPI(int py_debug, moduleDef *mod, FILE *fp) { if (!py_debug && (mod == NULL || useLimitedAPI(mod))) prcode(fp, "\n" "#if !defined(Py_LIMITED_API)\n" "#define Py_LIMITED_API\n" "#endif\n" ); } /* * Generate the PyQt4/5 signals table. */ static int generatePluginSignalsTable(sipSpec *pt, classDef *cd, const char *pyqt_prefix, FILE *fp) { int is_signals = FALSE; if (isQObjectSubClass(cd)) { memberDef *md; /* 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) { 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; if (pluginPyQt5(pt)) generatePyQt5Emitters(cd, fp); prcode(fp, "\n" "\n" "/* Define this type's signals. */\n" "static const %sQtSignal signals_%C[] = {\n" , pyqt_prefix, classFQCName(cd)); } /* * For PyQt4 optional arguments are handled as multiple * signals. We make sure the largest is first and the smallest * last which is what Qt does. When built against Qt5 we * enable a hack that supplies any missing optional arguments. * For PyQt5 we only include the version with all arguments and * provide an emitter function which handles the optional * arguments. */ generateSignalTableEntry(pt, cd, od, membernr, hasOptionalArgs(od), fp); membernr = -1; if (pluginPyQt4(pt)) { int a, nr_args; signatureDef *cppsig; cppsig = od->cppsig; nr_args = cppsig->nrArgs; for (a = nr_args - 1; a >= 0; --a) { if (cppsig->args[a].defval == NULL) break; cppsig->nrArgs = a; generateSignalTableEntry(pt, cd, od, -1, FALSE, fp); } cppsig->nrArgs = nr_args; } } } if (is_signals) prcode(fp, " {0, 0, 0, 0}\n" "};\n" ); } return is_signals; } /* * Generate any extended class definition data for PyQt5. Return TRUE if there * was something generated. */ static int generatePyQt5ClassPlugin(sipSpec *pt, classDef *cd, FILE *fp) { int is_signals = generatePluginSignalsTable(pt, cd, "pyqt5", fp); prcode(fp, "\n" "\n" "static pyqt5ClassPluginDef plugin_%L = {\n" , cd->iff); if (isQObjectSubClass(cd) && !noPyQtQMetaObject(cd)) prcode(fp, " &%U::staticMetaObject,\n" , cd); else prcode(fp, " 0,\n" ); prcode(fp, " %u,\n" , cd->pyqt_flags); if (is_signals) prcode(fp, " signals_%C,\n" , classFQCName(cd)); else prcode(fp, " 0,\n" ); if (cd->pyqt_interface != NULL) prcode(fp, " \"%s\"\n" , cd->pyqt_interface); else prcode(fp, " 0\n" ); prcode(fp, "};\n" ); return TRUE; } /* * Generate any extended class definition data for PyQt4. Return TRUE if there * was something generated. */ static int generatePyQt4ClassPlugin(sipSpec *pt, classDef *cd, FILE *fp) { int is_signals = generatePluginSignalsTable(pt, cd, "pyqt4", fp); prcode(fp, "\n" "\n" "static pyqt4ClassPluginDef plugin_%L = {\n" , cd->iff); if (isQObjectSubClass(cd) && !noPyQtQMetaObject(cd)) prcode(fp, " &%U::staticMetaObject,\n" , cd); else prcode(fp, " 0,\n" ); prcode(fp, " %u,\n" , cd->pyqt_flags); if (is_signals) prcode(fp, " signals_%C\n" , classFQCName(cd)); else prcode(fp, " 0\n" ); prcode(fp, "};\n" ); return TRUE; } /* * Generate the entries in a table of PyMethodDef for global functions. */ static void generateGlobalFunctionTableEntries(sipSpec *pt, moduleDef *mod, memberDef *members, FILE *fp) { memberDef *md; for (md = members; md != NULL; md = md->next) { if (md->slot == no_slot && notVersioned(md)) { prcode(fp, " {SIP_MLNAME_CAST(%N), ", md->pyname); if (noArgParser(md) || useKeywordArgs(md)) prcode(fp, "(PyCFunction)func_%s, METH_VARARGS|METH_KEYWORDS", md->pyname->text); else prcode(fp, "func_%s, METH_VARARGS", md->pyname->text); if (hasMemberDocstring(pt, mod->overs, md, NULL)) prcode(fp, ", SIP_MLDOC_CAST(doc_%s)},\n" , md->pyname->text); else prcode(fp, ", NULL},\n" ); } } } /* * Generate a template type. */ static void prTemplateType(FILE *fp, ifaceFileDef *scope, templateDef *td, StripAction strip) { static const char tail[] = ">"; int a; if (prcode_xml) strip = StripGlobal; prcode(fp, "%S%s", stripScope(td->fqname, NULL, strip), (prcode_xml ? "<" : "<")); for (a = 0; a < td->types.nrArgs; ++a) { if (a > 0) prcode(fp, ","); generateBaseType(scope, &td->types.args[a], TRUE, strip, fp); } if (prcode_last == tail) prcode(fp, " "); prcode(fp, (prcode_xml ? ">" : tail)); } /* * Strip the leading scopes from a scoped name as required. */ static scopedNameDef *stripScope(scopedNameDef *snd, classDef *ecd, StripAction strip) { if (strip != StripNone) { snd = removeGlobalScope(snd); if (strip == StripNamespace && ecd != NULL) { int i, nr_outers; /* Count the number of outer namespaces. */ nr_outers = 0; do { if (ecd->iff->type != namespace_iface) nr_outers = 0; else ++nr_outers; } while ((ecd = ecd->ecd) != NULL); /* Remove the names of any outer namespaces. */ for (i = 0; i < nr_outers; ++i) snd = snd->next; } } return snd; } /* * Generate the scope of a member of an unscoped enum. */ static void prEnumMemberScope(enumMemberDef *emd, FILE *fp) { classDef *ecd = emd->ed->ecd; if (isProtectedEnum(emd->ed)) prcode(fp, "sip%C", classFQCName(ecd)); else if (isProtectedClass(ecd)) prcode(fp, "%U", ecd); else prcode(fp, "%S", classFQCName(ecd)); } sip-4.19.7/sipgen/heap.c0000644000076500000240000000417513231604405015041 0ustar philstaff00000000000000/* * Wrappers around standard functions that use the heap. * * Copyright (c) 2015 Riverbank Computing Limited * * 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 #include #include #include #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"); } sip-4.19.7/sipgen/lexer.c0000644000076500000240000041604513231604431015245 0ustar philstaff00000000000000#line 2 "sip-4.19.7/sipgen/lexer.c" #line 4 "sip-4.19.7/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 #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . 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 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; typedef uint64_t flex_uint64_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; #endif /* ! C99 */ /* 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 /* ! 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 #define YY_BUF_SIZE 16384 #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 #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern yy_size_t 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_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. */ yy_size_t 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 yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ yy_size_t 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,yy_size_t 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 = (yy_size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 167 #define YY_END_OF_BUFFER 168 /* 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[1231] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168, 166, 105, 108, 166, 166, 166, 166, 166, 110, 110, 166, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 166, 105, 166, 165, 164, 165, 165, 120, 118, 120, 107, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 105, 166, 106, 105, 166, 0, 115, 0, 0, 116, 0, 110, 0, 114, 111, 114, 117, 109, 111, 0, 111, 110, 0, 63, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 119, 113, 113, 113, 113, 113, 113, 113, 85, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 0, 0, 0, 0, 0, 0, 111, 82, 114, 111, 109, 111, 0, 111, 112, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 42, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 113, 113, 113, 113, 113, 84, 113, 113, 113, 113, 113, 113, 113, 93, 113, 113, 113, 113, 113, 0, 0, 111, 55, 113, 113, 113, 40, 38, 113, 113, 113, 48, 113, 113, 113, 113, 43, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 53, 113, 113, 113, 46, 113, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 11, 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, 163, 113, 103, 113, 113, 113, 113, 113, 113, 113, 89, 113, 113, 113, 113, 113, 96, 113, 113, 12, 113, 113, 113, 113, 113, 113, 113, 27, 51, 113, 113, 54, 62, 44, 113, 113, 113, 113, 113, 41, 113, 113, 35, 113, 113, 113, 59, 113, 113, 113, 113, 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, 0, 0, 0, 0, 0, 104, 113, 113, 113, 113, 113, 113, 113, 113, 91, 113, 113, 113, 113, 113, 113, 113, 37, 113, 113, 113, 113, 113, 113, 113, 45, 113, 113, 113, 113, 113, 29, 113, 49, 52, 28, 113, 113, 113, 113, 113, 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, 0, 0, 0, 0, 0, 0, 0, 113, 113, 113, 83, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 36, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 31, 113, 32, 113, 56, 113, 47, 39, 0, 0, 0, 0, 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, 21, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 102, 34, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 74, 113, 60, 113, 58, 113, 61, 50, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 121, 0, 0, 0, 0, 126, 14, 0, 0, 0, 160, 0, 18, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 161, 0, 0, 0, 0, 0, 0, 0, 113, 113, 113, 113, 87, 88, 90, 113, 113, 113, 113, 113, 33, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 57, 30, 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, 158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 26, 136, 0, 0, 133, 0, 0, 0, 113, 113, 113, 113, 113, 94, 95, 113, 113, 113, 113, 113, 68, 67, 113, 113, 113, 71, 113, 113, 73, 113, 113, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 152, 0, 0, 0, 0, 0, 113, 113, 113, 113, 113, 113, 113, 75, 113, 113, 113, 70, 66, 81, 113, 113, 113, 113, 80, 159, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 137, 135, 0, 0, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 113, 113, 113, 113, 113, 113, 72, 113, 65, 113, 113, 78, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 157, 0, 0, 0, 142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 113, 113, 113, 113, 113, 113, 113, 76, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 149, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 113, 113, 113, 113, 113, 113, 113, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 138, 151, 0, 0, 0, 0, 0, 113, 113, 113, 113, 92, 113, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 141, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 113, 100, 113, 113, 113, 98, 143, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 139, 0, 0, 113, 113, 113, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 132, 0, 127, 0, 0, 0, 0, 0, 113, 113, 86, 113, 0, 0, 147, 0, 0, 0, 0, 0, 123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 113, 97, 0, 0, 0, 0, 5, 0, 0, 0, 0, 125, 0, 130, 0, 0, 0, 140, 0, 113, 113, 148, 145, 0, 144, 122, 0, 0, 0, 0, 0, 0, 134, 162, 113, 113, 146, 0, 0, 0, 153, 0, 0, 113, 113, 124, 0, 0, 0, 129, 99, 113, 6, 0, 131, 113, 0, 113, 0, 113, 7, 113, 101, 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, 8, 9, 10, 11, 1, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 1, 1, 1, 1, 1, 1, 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, 1, 44, 1, 1, 45, 1, 46, 47, 48, 49, 50, 51, 52, 53, 54, 28, 55, 56, 57, 58, 59, 60, 28, 61, 62, 63, 64, 65, 66, 67, 68, 28, 1, 69, 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[70] = { 0, 1, 1, 2, 1, 1, 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, 1, 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[1239] = { 0, 0, 68, 2823, 69, 70, 73, 75, 75, 2817, 80, 2824, 2827, 2827, 2827, 73, 82, 77, 87, 77, 128, 2756, 2805, 82, 94, 97, 102, 106, 134, 140, 146, 155, 149, 158, 162, 168, 184, 202, 207, 211, 217, 222, 2752, 143, 259, 2827, 2827, 171, 2798, 2827, 2827, 2805, 2827, 226, 229, 237, 287, 291, 298, 295, 302, 305, 310, 240, 313, 316, 322, 349, 325, 368, 183, 2796, 2827, 200, 2795, 120, 2827, 2813, 215, 2827, 89, 2748, 174, 249, 374, 191, 2827, 0, 378, 393, 2827, 2827, 0, 2827, 335, 401, 407, 419, 422, 425, 428, 432, 435, 441, 444, 447, 450, 453, 456, 463, 466, 470, 473, 479, 482, 488, 497, 501, 504, 516, 521, 524, 530, 536, 539, 545, 2827, 231, 0, 320, 2788, 153, 63, 133, 252, 224, 2759, 488, 2758, 514, 2751, 509, 2764, 2759, 178, 2750, 2753, 365, 2784, 2747, 2827, 562, 566, 569, 575, 582, 587, 590, 593, 596, 599, 602, 608, 622, 614, 625, 628, 631, 642, 646, 654, 657, 389, 2782, 2736, 405, 2780, 206, 658, 365, 678, 510, 0, 680, 140, 661, 0, 703, 707, 710, 713, 674, 725, 728, 731, 734, 737, 740, 746, 749, 752, 758, 761, 767, 770, 784, 787, 791, 795, 800, 803, 806, 809, 812, 817, 824, 827, 820, 836, 832, 2775, 2752, 2736, 296, 2739, 509, 2746, 2748, 2746, 569, 2748, 2735, 190, 2729, 2742, 2827, 2730, 344, 2741, 310, 2725, 2738, 2723, 2737, 33, 2722, 438, 2729, 2719, 2724, 2720, 2725, 2717, 2728, 842, 845, 848, 863, 874, 877, 884, 887, 893, 896, 899, 902, 909, 912, 915, 918, 923, 927, 930, 938, 2727, 946, 951, 956, 966, 969, 973, 980, 983, 991, 998, 1001, 1004, 1008, 1013, 1016, 1019, 1022, 1025, 1028, 1031, 1034, 1037, 1042, 1046, 1052, 1055, 1067, 1076, 1081, 1085, 1088, 1094, 1098, 1104, 1107, 2827, 2725, 2715, 2723, 2722, 2722, 2710, 361, 2701, 2722, 2705, 2827, 2716, 2706, 2703, 2700, 2716, 2705, 2699, 2739, 2708, 2698, 2700, 2692, 2691, 2703, 2702, 2691, 2697, 2685, 2694, 2692, 2683, 2693, 2681, 681, 2683, 2680, 2721, 2690, 2689, 2675, 2674, 2827, 1110, 1113, 1116, 1121, 1126, 1129, 1136, 1139, 1142, 1145, 1151, 1157, 1160, 1166, 1169, 1172, 1180, 1175, 2827, 1184, 1210, 1220, 1225, 1228, 1231, 1240, 1192, 1236, 1243, 1249, 1261, 1265, 1268, 1271, 1274, 1277, 1282, 1286, 1289, 1292, 1295, 1298, 1301, 1304, 1307, 1310, 1313, 1329, 1333, 1338, 2674, 2702, 2671, 2677, 2668, 2672, 2671, 2679, 2674, 2663, 2663, 2665, 2663, 2677, 2658, 2665, 2670, 2673, 2659, 2686, 2655, 2651, 2660, 2667, 2654, 2660, 2660, 2650, 2652, 2648, 2650, 2654, 2650, 2677, 2644, 2651, 2632, 2649, 2648, 2638, 2640, 566, 629, 2631, 1342, 1345, 1348, 1352, 1356, 1359, 1363, 1368, 1376, 1372, 1381, 1384, 1387, 1390, 1399, 1393, 1403, 1410, 1413, 1444, 1423, 1447, 1454, 1457, 1470, 1431, 1473, 1478, 1481, 1485, 1488, 1491, 1494, 1497, 1500, 1503, 1506, 1509, 1516, 1519, 1524, 2632, 2625, 1506, 2642, 2635, 2628, 2633, 2627, 2629, 2630, 2624, 2621, 2620, 2634, 2620, 2626, 2633, 2613, 2628, 2630, 2612, 2625, 2627, 2614, 2609, 2616, 2620, 2619, 2617, 2608, 2615, 2605, 2605, 2604, 2607, 2597, 2596, 2597, 2637, 2607, 2601, 2595, 362, 2594, 2593, 2605, 1531, 1535, 1540, 1545, 1549, 1558, 1564, 1567, 1570, 1576, 1579, 1582, 1588, 1592, 1595, 1604, 1607, 1614, 1617, 1625, 1634, 1642, 1645, 1650, 1653, 1656, 1659, 1664, 1669, 1672, 1681, 1684, 1690, 1693, 1696, 1701, 1704, 1707, 1710, 1713, 2630, 2618, 2584, 2594, 2596, 2595, 2583, 2597, 2592, 2587, 2586, 2576, 2586, 2574, 2582, 2581, 2584, 2570, 2582, 2569, 2569, 2579, 2578, 2570, 2827, 2576, 2569, 2576, 2573, 2566, 2584, 2600, 599, 2573, 2598, 2556, 2827, 2562, 2552, 2561, 2560, 2549, 2552, 2560, 2551, 2559, 2561, 2548, 2556, 2542, 2547, 1718, 1724, 1727, 1734, 1740, 1745, 1748, 1751, 1754, 1757, 1761, 1764, 1769, 1773, 1779, 1787, 1784, 1807, 1810, 1816, 1819, 1822, 1825, 1828, 1835, 1839, 1847, 1851, 1854, 1857, 1862, 1865, 1868, 1871, 2543, 2555, 2549, 2553, 2552, 2545, 2542, 2533, 2827, 2531, 2544, 624, 2827, 843, 2534, 2532, 2541, 2827, 2827, 2543, 2568, 2526, 2827, 2536, 2827, 2531, 2534, 2827, 2531, 2490, 2498, 2497, 2505, 2498, 2494, 2495, 2488, 2496, 2490, 2489, 2479, 2497, 2827, 2495, 2494, 2494, 2479, 2489, 2475, 678, 1874, 1877, 1881, 1884, 1887, 1890, 1896, 1899, 1903, 1909, 1919, 1922, 1925, 1928, 1931, 1934, 1938, 1943, 1952, 1958, 1969, 1974, 1977, 1980, 1987, 1990, 1993, 2000, 2005, 2488, 2479, 2484, 2473, 2484, 2511, 2467, 2479, 2478, 2480, 2464, 2465, 2464, 2464, 2471, 2456, 2467, 2460, 676, 2453, 2449, 2444, 2439, 2438, 2473, 2827, 2421, 2431, 2420, 2418, 2437, 2363, 2349, 2354, 2360, 2355, 2344, 2827, 2351, 2827, 2827, 2347, 2375, 2827, 2368, 2343, 2323, 2008, 2014, 2017, 2020, 2023, 2027, 2030, 2033, 2036, 2042, 2045, 2048, 2051, 2060, 2064, 2075, 2078, 2081, 2089, 2092, 2095, 2102, 2105, 2108, 2309, 2304, 2302, 2332, 2308, 2266, 2274, 2291, 2278, 2244, 2232, 230, 2235, 2226, 2208, 2208, 2827, 2827, 2207, 2215, 2192, 2204, 2208, 2175, 2157, 2166, 2152, 2159, 2158, 2141, 2141, 2130, 2137, 2827, 2139, 2114, 2149, 2147, 2827, 2095, 2096, 2083, 891, 2072, 2111, 2115, 2123, 2126, 2130, 2134, 2137, 2140, 2145, 2149, 2152, 2160, 2163, 2169, 2181, 2184, 2187, 2190, 2193, 2827, 2827, 2071, 2066, 2047, 2046, 2080, 2034, 2037, 2035, 2025, 2016, 2002, 2006, 1993, 2005, 1974, 1975, 1969, 1949, 1949, 1945, 1964, 1933, 1914, 1924, 2827, 2827, 2827, 1918, 1919, 2827, 1906, 1907, 1900, 1899, 1909, 1879, 1878, 1869, 1871, 1859, 2202, 2207, 2210, 2215, 2218, 2221, 2224, 2227, 2230, 2233, 2236, 2239, 2242, 2250, 1886, 1854, 1821, 1798, 1790, 1793, 1777, 1768, 1779, 1765, 1751, 1743, 1756, 1740, 1741, 2827, 1745, 1739, 1730, 2827, 1696, 1702, 1695, 1694, 1681, 1678, 1679, 1666, 1662, 1651, 1640, 1641, 1633, 1667, 1626, 1592, 2264, 2268, 2273, 2276, 2280, 2283, 2286, 2289, 2292, 2300, 1590, 1593, 1591, 1578, 1585, 1582, 1568, 1593, 1554, 1592, 1561, 1536, 1532, 1506, 1510, 1518, 1542, 1545, 1515, 1505, 1491, 2827, 1519, 1470, 1426, 1431, 1425, 1424, 1423, 2827, 1398, 1395, 1399, 1423, 2303, 2306, 2309, 2317, 2322, 2327, 2330, 2333, 1392, 1389, 1388, 1413, 1381, 1379, 1372, 1359, 1354, 1336, 1358, 1320, 1281, 1278, 1268, 1274, 1279, 1273, 1279, 2827, 1270, 1233, 1222, 1224, 1205, 2827, 2827, 1215, 1215, 1210, 1197, 1200, 2336, 2344, 2349, 2352, 2356, 2363, 2359, 1185, 1169, 1167, 1168, 1170, 1158, 1167, 1165, 1163, 1165, 1150, 1150, 1150, 1151, 1139, 1171, 1118, 1118, 2827, 1141, 1096, 1094, 1073, 1077, 2827, 1063, 1054, 1083, 77, 2366, 2369, 2374, 2379, 2386, 2403, 2827, 174, 206, 198, 198, 267, 2827, 249, 301, 270, 293, 306, 2827, 2827, 309, 391, 388, 422, 414, 439, 2827, 444, 447, 487, 2827, 466, 482, 2406, 2409, 2412, 2415, 495, 496, 521, 552, 531, 567, 587, 589, 602, 753, 2827, 626, 658, 2827, 630, 2827, 646, 652, 669, 680, 678, 2418, 2421, 2424, 2427, 707, 708, 2827, 708, 719, 727, 736, 766, 2827, 729, 740, 756, 768, 792, 793, 848, 823, 830, 832, 2432, 2435, 2438, 834, 842, 845, 852, 2827, 853, 858, 857, 881, 2827, 889, 2827, 928, 896, 907, 2827, 903, 2445, 2441, 2827, 2827, 922, 2827, 2827, 935, 931, 931, 948, 940, 970, 2827, 2827, 2448, 2454, 2827, 973, 978, 1006, 2827, 1021, 1021, 2459, 2463, 2827, 1010, 1012, 1026, 2827, 2471, 2474, 2827, 1014, 2827, 2478, 1022, 2484, 1035, 2491, 2827, 2498, 2501, 2827, 2559, 2563, 2567, 2571, 2573, 2575, 2579, 1082 } ; static yyconst flex_int16_t yy_def[1239] = { 0, 1230, 1, 1231, 1231, 1232, 1232, 1, 7, 1, 1, 1230, 1230, 1230, 1230, 1233, 1234, 1230, 1235, 1230, 1230, 20, 1230, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1230, 44, 1230, 1230, 44, 1233, 1230, 1233, 1234, 1230, 1230, 20, 1235, 1235, 1235, 1235, 1230, 1237, 1230, 1230, 1230, 1230, 1238, 1230, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1230, 1230, 44, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1230, 44, 1230, 1230, 44, 1230, 1230, 1235, 1235, 1235, 1237, 1230, 1230, 1230, 1238, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1230, 1235, 1235, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1230, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1236, 1236, 1236, 1236, 1236, 1236, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1236, 1236, 1236, 1236, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1236, 1236, 1236, 1236, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1236, 1236, 1236, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1236, 1236, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1236, 1236, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1236, 1236, 1230, 1230, 1230, 1230, 1230, 1236, 1236, 1230, 1230, 1230, 1236, 1230, 1236, 1230, 1236, 1230, 1236, 1236, 0, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230 } ; static yyconst flex_int16_t yy_nxt[2897] = { 0, 12, 13, 14, 13, 15, 12, 16, 12, 12, 12, 12, 17, 18, 19, 20, 21, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 23, 23, 25, 23, 26, 23, 23, 23, 23, 23, 23, 23, 12, 23, 23, 27, 28, 29, 30, 31, 23, 23, 32, 23, 33, 23, 34, 35, 36, 23, 37, 38, 39, 40, 41, 23, 23, 42, 43, 47, 46, 50, 44, 48, 50, 70, 76, 342, 51, 71, 73, 51, 52, 79, 74, 86, 72, 79, 80, 87, 81, 81, 82, 85, 82, 343, 53, 82, 83, 82, 84, 84, 178, 178, 82, 85, 82, 82, 85, 82, 54, 226, 82, 85, 82, 77, 82, 85, 82, 55, 227, 56, 57, 76, 58, 59, 97, 60, 61, 62, 95, 63, 64, 1117, 65, 66, 67, 68, 69, 88, 96, 81, 81, 127, 82, 85, 82, 128, 89, 90, 82, 85, 82, 185, 185, 91, 82, 85, 82, 82, 85, 82, 77, 98, 91, 82, 85, 82, 82, 85, 82, 147, 82, 85, 82, 148, 89, 90, 82, 85, 82, 224, 91, 172, 82, 99, 82, 173, 100, 228, 91, 101, 1122, 92, 82, 85, 82, 102, 229, 105, 175, 82, 103, 82, 176, 108, 110, 106, 327, 107, 225, 104, 82, 85, 82, 109, 79, 82, 85, 82, 79, 82, 85, 82, 1123, 328, 111, 82, 85, 82, 249, 127, 82, 85, 82, 128, 82, 85, 82, 82, 85, 82, 232, 112, 250, 1124, 113, 82, 85, 82, 82, 85, 82, 114, 115, 118, 116, 1125, 119, 82, 179, 82, 274, 117, 884, 885, 120, 122, 125, 123, 151, 229, 233, 121, 124, 129, 130, 131, 132, 133, 134, 135, 136, 137, 162, 1126, 138, 139, 152, 140, 141, 153, 142, 143, 144, 145, 146, 82, 85, 82, 230, 82, 85, 82, 231, 82, 85, 82, 82, 85, 82, 1127, 82, 85, 82, 82, 85, 82, 313, 1128, 82, 85, 82, 82, 85, 82, 82, 85, 82, 314, 1129, 154, 82, 85, 82, 82, 85, 82, 99, 155, 1130, 100, 105, 157, 101, 82, 85, 82, 102, 158, 106, 220, 107, 159, 160, 156, 1131, 1132, 108, 82, 85, 82, 161, 336, 165, 147, 221, 109, 337, 148, 166, 163, 164, 114, 167, 82, 116, 82, 82, 85, 82, 122, 222, 117, 82, 170, 82, 84, 84, 172, 332, 183, 183, 173, 180, 181, 333, 118, 89, 90, 119, 168, 184, 184, 334, 175, 185, 185, 120, 176, 621, 82, 85, 82, 622, 169, 171, 82, 85, 82, 123, 410, 180, 181, 411, 124, 89, 90, 187, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 188, 82, 85, 82, 82, 85, 82, 1133, 1134, 189, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 191, 1135, 1136, 192, 82, 85, 82, 82, 85, 82, 190, 82, 85, 82, 82, 85, 82, 345, 1137, 193, 82, 85, 82, 82, 85, 82, 346, 1138, 194, 82, 85, 82, 197, 196, 195, 1139, 1140, 198, 82, 85, 82, 199, 82, 85, 82, 82, 85, 82, 200, 203, 201, 82, 202, 82, 1141, 206, 204, 82, 85, 82, 1142, 205, 82, 85, 82, 82, 85, 82, 235, 208, 207, 82, 85, 82, 236, 237, 210, 82, 85, 82, 82, 85, 82, 1147, 1148, 209, 82, 85, 82, 239, 212, 211, 243, 240, 244, 316, 317, 245, 318, 246, 1149, 1150, 241, 82, 85, 82, 213, 82, 85, 82, 82, 85, 82, 215, 214, 530, 82, 85, 82, 1151, 531, 216, 218, 82, 85, 82, 217, 219, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 322, 254, 691, 82, 85, 82, 1152, 692, 256, 82, 85, 82, 323, 255, 257, 324, 258, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 1153, 749, 259, 532, 263, 1154, 1155, 260, 82, 85, 82, 262, 82, 85, 82, 750, 533, 266, 261, 264, 82, 85, 82, 82, 85, 82, 203, 178, 178, 1158, 185, 185, 1159, 1160, 89, 90, 267, 269, 90, 265, 82, 85, 82, 184, 275, 268, 82, 276, 276, 183, 183, 828, 784, 270, 785, 829, 89, 90, 272, 1161, 271, 438, 89, 90, 1162, 439, 90, 830, 440, 82, 85, 82, 273, 82, 85, 82, 82, 85, 82, 82, 85, 82, 1163, 1164, 89, 90, 277, 278, 1165, 282, 279, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 280, 1169, 1170, 82, 85, 82, 82, 85, 82, 82, 85, 82, 1171, 1172, 281, 82, 85, 82, 82, 85, 82, 1156, 1173, 285, 82, 85, 82, 82, 85, 82, 1174, 1175, 283, 1176, 1157, 284, 286, 289, 287, 1177, 290, 82, 85, 82, 82, 85, 82, 288, 82, 85, 82, 1178, 82, 85, 82, 291, 292, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 1179, 293, 82, 85, 82, 82, 85, 82, 294, 82, 85, 82, 82, 85, 82, 1180, 296, 82, 85, 82, 295, 82, 85, 82, 1181, 297, 298, 82, 85, 82, 82, 85, 82, 82, 85, 82, 299, 751, 752, 300, 304, 1182, 302, 301, 303, 1183, 753, 305, 82, 85, 82, 309, 754, 1184, 306, 1185, 307, 1188, 308, 82, 85, 82, 82, 85, 82, 1189, 356, 1190, 355, 82, 85, 82, 82, 85, 82, 1191, 1192, 354, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 1193, 1194, 357, 358, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 1195, 359, 82, 85, 82, 1196, 82, 85, 82, 82, 85, 82, 361, 362, 912, 1197, 363, 82, 85, 82, 360, 913, 1198, 364, 1199, 82, 365, 82, 276, 276, 82, 1200, 82, 276, 276, 82, 85, 82, 366, 1203, 368, 181, 370, 367, 369, 82, 85, 82, 82, 85, 82, 1204, 82, 85, 82, 1205, 1206, 373, 375, 82, 85, 82, 82, 85, 82, 1207, 1208, 371, 374, 181, 82, 85, 82, 376, 377, 378, 379, 82, 85, 82, 82, 85, 82, 82, 85, 82, 1209, 82, 85, 82, 1212, 1213, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 1214, 380, 82, 85, 82, 382, 82, 85, 82, 381, 383, 384, 82, 85, 82, 82, 85, 82, 1215, 1216, 385, 1219, 388, 1220, 1221, 389, 1223, 82, 85, 82, 386, 1225, 390, 1227, 186, 387, 82, 85, 82, 391, 393, 82, 85, 82, 394, 82, 85, 82, 82, 85, 82, 1116, 1115, 392, 82, 85, 82, 396, 82, 85, 82, 1114, 395, 397, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 1113, 398, 82, 85, 82, 1112, 400, 82, 85, 82, 82, 85, 82, 1111, 1110, 401, 399, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 448, 1109, 402, 82, 85, 82, 450, 1108, 403, 82, 85, 82, 82, 85, 82, 452, 1107, 449, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 451, 1106, 82, 85, 82, 453, 82, 85, 82, 1105, 455, 1104, 1103, 454, 82, 85, 82, 387, 1102, 1101, 456, 1100, 459, 1099, 1098, 464, 394, 1097, 457, 1096, 1095, 400, 82, 85, 82, 458, 461, 1094, 1093, 463, 1092, 460, 82, 85, 82, 1091, 462, 82, 85, 82, 82, 85, 82, 82, 85, 82, 1084, 465, 82, 85, 82, 466, 82, 85, 82, 82, 85, 82, 1083, 1082, 468, 82, 85, 82, 1081, 1080, 470, 467, 1079, 471, 1078, 1077, 469, 82, 85, 82, 472, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 1076, 473, 82, 85, 82, 474, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 1075, 1074, 478, 475, 1073, 1072, 479, 1071, 1070, 476, 1069, 1068, 477, 82, 85, 82, 481, 82, 85, 82, 480, 482, 82, 85, 82, 484, 82, 85, 82, 82, 85, 82, 82, 85, 82, 485, 82, 85, 82, 483, 82, 85, 82, 82, 85, 82, 1067, 82, 85, 82, 1066, 487, 82, 85, 82, 488, 82, 85, 82, 486, 82, 85, 82, 535, 1065, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 537, 540, 536, 82, 85, 82, 1064, 82, 85, 82, 1063, 538, 539, 549, 82, 85, 82, 82, 85, 82, 1062, 1061, 541, 543, 1060, 1059, 542, 82, 85, 82, 1058, 1057, 480, 1056, 559, 82, 85, 82, 550, 544, 1048, 1047, 545, 546, 548, 547, 1046, 551, 82, 85, 82, 82, 85, 82, 1045, 552, 553, 554, 82, 85, 82, 82, 85, 82, 1044, 555, 1043, 1042, 556, 1041, 561, 560, 557, 558, 82, 85, 82, 82, 85, 82, 1040, 562, 82, 85, 82, 82, 85, 82, 563, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 565, 577, 578, 564, 82, 85, 82, 82, 85, 82, 1039, 567, 82, 85, 82, 1038, 566, 579, 580, 82, 85, 82, 581, 82, 85, 82, 1037, 568, 82, 85, 82, 1036, 569, 82, 85, 82, 571, 82, 85, 82, 1035, 1034, 572, 1033, 1032, 570, 82, 85, 82, 1031, 1030, 573, 82, 85, 82, 82, 85, 82, 82, 85, 82, 626, 1029, 574, 82, 85, 82, 82, 85, 82, 82, 85, 82, 1028, 629, 627, 82, 85, 82, 628, 82, 85, 82, 82, 85, 82, 630, 1027, 1026, 632, 631, 633, 82, 85, 82, 82, 85, 82, 1025, 1024, 639, 635, 82, 85, 82, 82, 85, 82, 1023, 1022, 636, 642, 1021, 82, 85, 82, 634, 1020, 1019, 640, 1018, 637, 82, 85, 82, 1017, 638, 643, 641, 1008, 82, 85, 82, 82, 85, 82, 644, 645, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 646, 650, 82, 85, 82, 1007, 649, 82, 85, 82, 82, 85, 82, 1006, 647, 1005, 651, 1004, 648, 82, 85, 82, 82, 85, 82, 1003, 1002, 652, 82, 85, 82, 82, 85, 82, 82, 85, 82, 1001, 653, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 1000, 655, 82, 85, 82, 999, 998, 654, 82, 85, 82, 82, 85, 82, 997, 657, 996, 656, 82, 85, 82, 995, 994, 658, 82, 85, 82, 993, 659, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 712, 82, 85, 82, 82, 85, 82, 713, 710, 82, 85, 82, 711, 82, 85, 82, 992, 991, 714, 82, 85, 82, 990, 715, 82, 85, 82, 82, 85, 82, 989, 988, 716, 987, 986, 717, 723, 722, 724, 985, 984, 725, 719, 718, 983, 982, 721, 82, 85, 82, 82, 85, 82, 720, 981, 726, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 728, 980, 729, 727, 82, 85, 82, 732, 82, 85, 82, 979, 730, 978, 734, 731, 82, 85, 82, 733, 82, 85, 82, 82, 85, 82, 82, 85, 82, 977, 736, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 735, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 976, 975, 737, 82, 85, 82, 82, 85, 82, 738, 82, 85, 82, 964, 963, 788, 82, 85, 82, 786, 962, 961, 787, 960, 959, 789, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 790, 82, 85, 82, 791, 796, 82, 85, 82, 958, 957, 795, 956, 955, 797, 82, 85, 82, 954, 953, 792, 82, 85, 82, 952, 800, 798, 793, 951, 801, 950, 799, 82, 85, 82, 949, 794, 82, 85, 82, 82, 85, 82, 82, 85, 82, 948, 803, 804, 802, 82, 85, 82, 82, 85, 82, 82, 85, 82, 947, 946, 807, 808, 82, 85, 82, 945, 806, 82, 85, 82, 82, 85, 82, 944, 943, 805, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 809, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 942, 941, 854, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 863, 862, 940, 858, 939, 856, 82, 85, 82, 855, 82, 85, 82, 861, 938, 857, 937, 859, 864, 936, 860, 82, 85, 82, 82, 85, 82, 82, 85, 82, 935, 865, 934, 933, 866, 82, 85, 82, 82, 85, 82, 82, 85, 82, 932, 931, 868, 869, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 867, 82, 85, 82, 930, 871, 929, 914, 870, 82, 85, 82, 82, 85, 82, 911, 82, 85, 82, 872, 82, 85, 82, 82, 85, 82, 82, 85, 82, 910, 909, 82, 85, 82, 916, 82, 85, 82, 82, 85, 82, 908, 923, 907, 906, 915, 82, 85, 82, 82, 85, 82, 918, 919, 922, 82, 85, 82, 917, 905, 921, 904, 903, 924, 902, 901, 920, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 900, 899, 926, 898, 897, 925, 82, 85, 82, 896, 927, 82, 85, 82, 82, 85, 82, 895, 928, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 894, 893, 972, 892, 966, 82, 85, 82, 891, 890, 973, 889, 971, 965, 888, 969, 967, 887, 974, 82, 85, 82, 968, 82, 85, 82, 886, 970, 82, 85, 82, 82, 85, 82, 883, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 882, 881, 1009, 880, 1016, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 879, 878, 1010, 877, 1014, 82, 85, 82, 1015, 1012, 82, 85, 82, 1011, 1013, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 876, 875, 1049, 874, 1051, 82, 85, 82, 873, 1050, 82, 85, 82, 82, 85, 82, 1052, 82, 85, 82, 82, 85, 82, 1053, 82, 85, 82, 82, 85, 82, 82, 85, 82, 853, 1054, 82, 85, 82, 852, 1055, 82, 85, 82, 851, 850, 1119, 849, 82, 85, 82, 848, 847, 1085, 846, 1087, 845, 1086, 844, 1089, 1088, 843, 842, 1090, 1118, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 1120, 1121, 82, 85, 82, 82, 85, 82, 82, 85, 82, 82, 85, 82, 1143, 82, 85, 82, 82, 85, 82, 841, 840, 1146, 82, 85, 82, 839, 1144, 82, 85, 82, 1145, 82, 85, 82, 1166, 1211, 838, 837, 1167, 82, 85, 82, 82, 85, 82, 1168, 82, 85, 82, 836, 1187, 1186, 82, 85, 82, 1201, 835, 834, 1202, 82, 85, 82, 833, 1210, 832, 1218, 82, 85, 82, 82, 85, 82, 831, 1217, 827, 826, 825, 824, 823, 822, 821, 820, 819, 1224, 818, 817, 816, 815, 1222, 814, 813, 812, 811, 810, 783, 782, 1226, 1228, 781, 780, 779, 778, 777, 776, 775, 774, 773, 772, 771, 770, 769, 768, 767, 766, 765, 1229, 45, 45, 45, 45, 49, 49, 49, 49, 75, 75, 75, 75, 78, 78, 78, 78, 85, 85, 94, 94, 182, 764, 182, 182, 763, 762, 761, 760, 759, 758, 757, 756, 755, 748, 747, 746, 745, 744, 743, 742, 741, 740, 739, 709, 708, 707, 706, 705, 704, 703, 702, 701, 700, 699, 698, 697, 696, 695, 694, 693, 690, 689, 688, 687, 686, 685, 684, 683, 682, 681, 680, 679, 678, 677, 676, 675, 674, 673, 672, 671, 670, 669, 668, 667, 666, 665, 664, 663, 662, 661, 660, 625, 624, 623, 620, 619, 618, 617, 616, 615, 614, 613, 612, 611, 610, 609, 608, 607, 606, 605, 604, 603, 602, 601, 600, 599, 598, 597, 596, 595, 594, 593, 592, 591, 590, 589, 588, 587, 586, 585, 584, 583, 582, 576, 575, 534, 529, 528, 527, 526, 525, 524, 523, 522, 521, 520, 519, 518, 517, 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, 489, 447, 446, 445, 444, 443, 442, 441, 437, 436, 435, 434, 433, 432, 431, 430, 429, 428, 427, 426, 425, 424, 423, 422, 421, 420, 419, 418, 417, 416, 415, 414, 413, 412, 409, 408, 407, 406, 405, 404, 372, 353, 352, 351, 350, 349, 348, 347, 344, 341, 340, 339, 338, 335, 331, 330, 329, 326, 325, 321, 320, 319, 315, 312, 311, 310, 177, 229, 174, 253, 149, 252, 251, 248, 247, 242, 238, 234, 223, 1230, 1230, 177, 174, 150, 149, 126, 93, 1230, 1230, 72, 46, 11, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230 } ; static yyconst flex_int16_t yy_chk[2897] = { 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, 1, 1, 1, 1, 2, 4, 4, 5, 2, 4, 6, 8, 15, 244, 5, 8, 10, 6, 7, 16, 10, 19, 10, 16, 17, 19, 17, 17, 23, 23, 23, 244, 7, 18, 18, 18, 18, 18, 80, 80, 24, 24, 24, 25, 25, 25, 7, 132, 26, 26, 26, 15, 27, 27, 27, 7, 132, 7, 7, 75, 7, 7, 26, 7, 7, 7, 24, 7, 7, 1084, 7, 7, 7, 7, 7, 20, 25, 20, 20, 43, 28, 28, 28, 43, 20, 20, 29, 29, 29, 184, 184, 20, 30, 30, 30, 32, 32, 32, 75, 27, 20, 31, 31, 31, 33, 33, 33, 47, 34, 34, 34, 47, 20, 20, 35, 35, 35, 131, 20, 70, 82, 28, 82, 70, 28, 133, 20, 28, 1092, 20, 36, 36, 36, 29, 133, 31, 73, 85, 30, 85, 73, 32, 34, 31, 232, 31, 131, 30, 37, 37, 37, 33, 78, 38, 38, 38, 78, 39, 39, 39, 1093, 232, 35, 40, 40, 40, 144, 127, 41, 41, 41, 127, 53, 53, 53, 54, 54, 54, 135, 36, 144, 1094, 36, 55, 55, 55, 63, 63, 63, 37, 37, 38, 37, 1095, 38, 83, 83, 83, 177, 37, 821, 821, 38, 39, 41, 40, 53, 177, 135, 38, 40, 44, 44, 44, 44, 44, 44, 44, 44, 44, 63, 1096, 44, 44, 54, 44, 44, 55, 44, 44, 44, 44, 44, 56, 56, 56, 134, 57, 57, 57, 134, 59, 59, 59, 58, 58, 58, 1098, 60, 60, 60, 61, 61, 61, 223, 1099, 62, 62, 62, 64, 64, 64, 65, 65, 65, 223, 1100, 56, 66, 66, 66, 68, 68, 68, 56, 57, 1101, 56, 58, 59, 56, 94, 94, 94, 57, 60, 58, 129, 58, 61, 62, 58, 1102, 1105, 60, 67, 67, 67, 62, 239, 65, 147, 129, 62, 239, 147, 66, 64, 64, 66, 66, 179, 66, 179, 69, 69, 69, 68, 129, 66, 84, 68, 84, 84, 84, 172, 237, 88, 88, 172, 84, 84, 237, 67, 88, 88, 67, 67, 89, 89, 237, 175, 89, 89, 67, 175, 531, 95, 95, 95, 531, 67, 69, 96, 96, 96, 69, 317, 84, 84, 317, 69, 88, 88, 95, 97, 97, 97, 98, 98, 98, 99, 99, 99, 100, 100, 100, 96, 101, 101, 101, 102, 102, 102, 1106, 1107, 97, 103, 103, 103, 104, 104, 104, 105, 105, 105, 106, 106, 106, 107, 107, 107, 108, 108, 108, 99, 1108, 1109, 100, 109, 109, 109, 110, 110, 110, 98, 111, 111, 111, 112, 112, 112, 246, 1110, 101, 113, 113, 113, 114, 114, 114, 246, 1112, 102, 115, 115, 115, 105, 104, 103, 1113, 1114, 106, 116, 116, 116, 107, 117, 117, 117, 118, 118, 118, 108, 111, 109, 181, 110, 181, 1116, 113, 112, 119, 119, 119, 1117, 112, 120, 120, 120, 121, 121, 121, 137, 115, 114, 122, 122, 122, 137, 137, 117, 123, 123, 123, 124, 124, 124, 1122, 1123, 116, 125, 125, 125, 139, 118, 117, 141, 139, 141, 225, 225, 141, 225, 141, 1124, 1125, 139, 151, 151, 151, 119, 152, 152, 152, 153, 153, 153, 121, 120, 445, 154, 154, 154, 1126, 445, 122, 124, 155, 155, 155, 123, 125, 156, 156, 156, 157, 157, 157, 158, 158, 158, 159, 159, 159, 160, 160, 160, 161, 161, 161, 229, 151, 607, 162, 162, 162, 1127, 607, 153, 164, 164, 164, 229, 152, 154, 229, 155, 163, 163, 163, 165, 165, 165, 166, 166, 166, 167, 167, 167, 1128, 671, 156, 446, 161, 1129, 1130, 157, 168, 168, 168, 160, 169, 169, 169, 671, 446, 164, 159, 162, 170, 170, 170, 171, 171, 171, 163, 178, 178, 1133, 185, 185, 1134, 1136, 178, 178, 165, 167, 185, 163, 191, 191, 191, 180, 180, 166, 180, 180, 180, 183, 183, 757, 709, 168, 709, 757, 183, 183, 170, 1138, 169, 345, 178, 178, 1139, 345, 185, 757, 345, 187, 187, 187, 171, 188, 188, 188, 189, 189, 189, 190, 190, 190, 1140, 1141, 183, 183, 187, 188, 1142, 191, 188, 192, 192, 192, 193, 193, 193, 194, 194, 194, 195, 195, 195, 196, 196, 196, 197, 197, 197, 189, 1147, 1148, 198, 198, 198, 199, 199, 199, 200, 200, 200, 1150, 1151, 190, 201, 201, 201, 202, 202, 202, 1131, 1152, 194, 203, 203, 203, 204, 204, 204, 1153, 1154, 192, 1156, 1131, 193, 195, 198, 196, 1157, 199, 205, 205, 205, 206, 206, 206, 197, 207, 207, 207, 1158, 208, 208, 208, 201, 202, 209, 209, 209, 210, 210, 210, 211, 211, 211, 212, 212, 212, 213, 213, 213, 1159, 203, 214, 214, 214, 217, 217, 217, 204, 215, 215, 215, 216, 216, 216, 1160, 206, 219, 219, 219, 205, 218, 218, 218, 1161, 207, 208, 254, 254, 254, 255, 255, 255, 256, 256, 256, 209, 673, 673, 210, 214, 1162, 212, 211, 213, 1163, 673, 215, 257, 257, 257, 219, 673, 1164, 216, 1165, 217, 1169, 218, 258, 258, 258, 259, 259, 259, 1170, 256, 1171, 255, 260, 260, 260, 261, 261, 261, 1172, 1174, 254, 262, 262, 262, 263, 263, 263, 264, 264, 264, 265, 265, 265, 1175, 1176, 257, 258, 266, 266, 266, 267, 267, 267, 268, 268, 268, 269, 269, 269, 1177, 259, 270, 270, 270, 1179, 271, 271, 271, 272, 272, 272, 262, 263, 852, 1181, 264, 273, 273, 273, 261, 852, 1182, 265, 1183, 275, 266, 275, 275, 275, 276, 1185, 276, 276, 276, 277, 277, 277, 267, 1190, 270, 276, 272, 269, 271, 278, 278, 278, 279, 279, 279, 1193, 280, 280, 280, 1194, 1195, 278, 280, 281, 281, 281, 282, 282, 282, 1196, 1197, 273, 279, 276, 283, 283, 283, 280, 280, 280, 280, 284, 284, 284, 285, 285, 285, 286, 286, 286, 1198, 287, 287, 287, 1204, 1205, 288, 288, 288, 289, 289, 289, 290, 290, 290, 291, 291, 291, 292, 292, 292, 293, 293, 293, 294, 294, 294, 295, 295, 295, 296, 296, 296, 1206, 283, 297, 297, 297, 285, 298, 298, 298, 284, 287, 288, 299, 299, 299, 300, 300, 300, 1208, 1209, 289, 1213, 293, 1214, 1215, 294, 1220, 301, 301, 301, 290, 1223, 295, 1225, 1238, 292, 302, 302, 302, 296, 298, 303, 303, 303, 298, 304, 304, 304, 305, 305, 305, 1083, 1082, 297, 306, 306, 306, 300, 307, 307, 307, 1081, 299, 301, 308, 308, 308, 309, 309, 309, 354, 354, 354, 355, 355, 355, 356, 356, 356, 1079, 302, 357, 357, 357, 1078, 305, 358, 358, 358, 359, 359, 359, 1077, 1076, 306, 303, 360, 360, 360, 361, 361, 361, 362, 362, 362, 363, 363, 363, 354, 1075, 307, 364, 364, 364, 357, 1073, 309, 365, 365, 365, 366, 366, 366, 359, 1072, 356, 367, 367, 367, 368, 368, 368, 369, 369, 369, 371, 371, 371, 358, 1071, 370, 370, 370, 360, 373, 373, 373, 1070, 362, 1069, 1068, 361, 380, 380, 380, 363, 1067, 1066, 364, 1065, 367, 1064, 1063, 373, 367, 1062, 365, 1061, 1060, 369, 374, 374, 374, 366, 370, 1059, 1058, 371, 1057, 368, 375, 375, 375, 1056, 370, 376, 376, 376, 377, 377, 377, 378, 378, 378, 1048, 374, 381, 381, 381, 375, 379, 379, 379, 382, 382, 382, 1047, 1046, 377, 383, 383, 383, 1045, 1044, 379, 376, 1041, 379, 1040, 1039, 378, 384, 384, 384, 379, 385, 385, 385, 386, 386, 386, 387, 387, 387, 388, 388, 388, 389, 389, 389, 1038, 382, 390, 390, 390, 383, 391, 391, 391, 392, 392, 392, 393, 393, 393, 394, 394, 394, 395, 395, 395, 396, 396, 396, 397, 397, 397, 398, 398, 398, 399, 399, 399, 400, 400, 400, 1037, 1035, 390, 387, 1034, 1033, 391, 1032, 1031, 388, 1030, 1029, 389, 401, 401, 401, 394, 402, 402, 402, 393, 396, 403, 403, 403, 398, 448, 448, 448, 449, 449, 449, 450, 450, 450, 400, 451, 451, 451, 397, 452, 452, 452, 453, 453, 453, 1028, 454, 454, 454, 1027, 402, 455, 455, 455, 403, 457, 457, 457, 401, 456, 456, 456, 449, 1026, 458, 458, 458, 459, 459, 459, 460, 460, 460, 461, 461, 461, 463, 463, 463, 451, 454, 450, 462, 462, 462, 1025, 464, 464, 464, 1024, 452, 453, 464, 465, 465, 465, 466, 466, 466, 1023, 1022, 455, 458, 1021, 1020, 456, 468, 468, 468, 1019, 1018, 459, 1017, 468, 473, 473, 473, 465, 459, 1008, 1007, 460, 461, 463, 462, 1006, 466, 467, 467, 467, 469, 469, 469, 1005, 467, 467, 467, 470, 470, 470, 471, 471, 471, 1003, 467, 1002, 1001, 467, 1000, 470, 469, 467, 467, 472, 472, 472, 474, 474, 474, 999, 471, 475, 475, 475, 476, 476, 476, 472, 477, 477, 477, 478, 478, 478, 479, 479, 479, 480, 480, 480, 481, 481, 481, 482, 482, 482, 483, 483, 483, 484, 484, 484, 485, 485, 485, 475, 491, 491, 474, 486, 486, 486, 487, 487, 487, 998, 477, 488, 488, 488, 997, 476, 491, 491, 535, 535, 535, 491, 536, 536, 536, 995, 478, 537, 537, 537, 994, 480, 538, 538, 538, 485, 539, 539, 539, 993, 992, 486, 991, 990, 484, 540, 540, 540, 989, 988, 487, 541, 541, 541, 542, 542, 542, 543, 543, 543, 535, 987, 488, 544, 544, 544, 545, 545, 545, 546, 546, 546, 986, 539, 536, 547, 547, 547, 537, 548, 548, 548, 549, 549, 549, 540, 985, 984, 542, 541, 543, 550, 550, 550, 551, 551, 551, 983, 982, 549, 545, 552, 552, 552, 553, 553, 553, 981, 980, 546, 553, 979, 554, 554, 554, 544, 978, 977, 551, 976, 547, 555, 555, 555, 975, 548, 554, 552, 964, 556, 556, 556, 557, 557, 557, 555, 556, 558, 558, 558, 559, 559, 559, 560, 560, 560, 561, 561, 561, 557, 560, 562, 562, 562, 963, 559, 563, 563, 563, 564, 564, 564, 962, 558, 961, 561, 960, 558, 565, 565, 565, 566, 566, 566, 959, 958, 562, 567, 567, 567, 568, 568, 568, 569, 569, 569, 957, 563, 570, 570, 570, 571, 571, 571, 572, 572, 572, 573, 573, 573, 574, 574, 574, 956, 565, 626, 626, 626, 955, 954, 564, 627, 627, 627, 628, 628, 628, 953, 568, 952, 566, 629, 629, 629, 951, 950, 570, 630, 630, 630, 949, 572, 631, 631, 631, 632, 632, 632, 633, 633, 633, 634, 634, 634, 635, 635, 635, 628, 636, 636, 636, 637, 637, 637, 629, 626, 638, 638, 638, 627, 639, 639, 639, 947, 946, 630, 640, 640, 640, 945, 631, 642, 642, 642, 641, 641, 641, 943, 942, 632, 941, 940, 633, 640, 639, 641, 939, 938, 642, 635, 634, 937, 936, 637, 643, 643, 643, 644, 644, 644, 636, 935, 643, 645, 645, 645, 646, 646, 646, 647, 647, 647, 648, 648, 648, 649, 649, 649, 645, 934, 646, 644, 650, 650, 650, 649, 651, 651, 651, 933, 647, 932, 651, 648, 652, 652, 652, 650, 653, 653, 653, 654, 654, 654, 655, 655, 655, 931, 653, 656, 656, 656, 657, 657, 657, 658, 658, 658, 659, 659, 659, 710, 710, 710, 711, 711, 711, 652, 712, 712, 712, 713, 713, 713, 714, 714, 714, 715, 715, 715, 930, 929, 655, 716, 716, 716, 717, 717, 717, 657, 718, 718, 718, 914, 913, 712, 719, 719, 719, 710, 912, 911, 711, 910, 909, 713, 720, 720, 720, 721, 721, 721, 722, 722, 722, 723, 723, 723, 724, 724, 724, 725, 725, 725, 717, 726, 726, 726, 718, 724, 727, 727, 727, 908, 907, 723, 906, 905, 725, 728, 728, 728, 903, 902, 719, 729, 729, 729, 898, 728, 726, 720, 897, 729, 896, 727, 730, 730, 730, 895, 721, 731, 731, 731, 732, 732, 732, 733, 733, 733, 894, 731, 732, 730, 734, 734, 734, 735, 735, 735, 736, 736, 736, 893, 892, 735, 735, 737, 737, 737, 891, 734, 738, 738, 738, 786, 786, 786, 890, 889, 733, 787, 787, 787, 788, 788, 788, 789, 789, 789, 790, 790, 790, 736, 791, 791, 791, 792, 792, 792, 793, 793, 793, 794, 794, 794, 888, 887, 786, 795, 795, 795, 796, 796, 796, 797, 797, 797, 798, 798, 798, 797, 796, 886, 790, 885, 788, 799, 799, 799, 787, 800, 800, 800, 795, 884, 789, 883, 793, 800, 882, 794, 801, 801, 801, 802, 802, 802, 803, 803, 803, 881, 801, 880, 879, 802, 804, 804, 804, 805, 805, 805, 806, 806, 806, 878, 877, 805, 805, 807, 807, 807, 808, 808, 808, 809, 809, 809, 854, 854, 854, 804, 855, 855, 855, 876, 808, 875, 853, 807, 856, 856, 856, 857, 857, 857, 851, 858, 858, 858, 809, 859, 859, 859, 860, 860, 860, 861, 861, 861, 850, 849, 862, 862, 862, 855, 863, 863, 863, 864, 864, 864, 847, 863, 846, 845, 854, 865, 865, 865, 866, 866, 866, 857, 858, 862, 867, 867, 867, 856, 844, 860, 842, 841, 864, 840, 839, 859, 868, 868, 868, 869, 869, 869, 870, 870, 870, 871, 871, 871, 872, 872, 872, 838, 837, 869, 836, 835, 868, 915, 915, 915, 834, 870, 916, 916, 916, 917, 917, 917, 833, 871, 918, 918, 918, 919, 919, 919, 920, 920, 920, 921, 921, 921, 922, 922, 922, 923, 923, 923, 924, 924, 924, 925, 925, 925, 926, 926, 926, 927, 927, 927, 832, 831, 923, 830, 916, 928, 928, 928, 829, 828, 925, 825, 921, 915, 824, 919, 917, 823, 926, 965, 965, 965, 918, 966, 966, 966, 822, 920, 967, 967, 967, 968, 968, 968, 820, 969, 969, 969, 970, 970, 970, 971, 971, 971, 972, 972, 972, 973, 973, 973, 819, 818, 965, 817, 972, 974, 974, 974, 1009, 1009, 1009, 1010, 1010, 1010, 1011, 1011, 1011, 816, 815, 966, 814, 970, 1012, 1012, 1012, 971, 968, 1013, 1013, 1013, 967, 969, 1014, 1014, 1014, 1015, 1015, 1015, 1016, 1016, 1016, 1049, 1049, 1049, 813, 812, 1009, 811, 1011, 1050, 1050, 1050, 810, 1010, 1051, 1051, 1051, 1052, 1052, 1052, 1012, 1053, 1053, 1053, 1055, 1055, 1055, 1013, 1054, 1054, 1054, 1085, 1085, 1085, 1086, 1086, 1086, 785, 1014, 1087, 1087, 1087, 784, 1015, 1088, 1088, 1088, 783, 781, 1087, 780, 1089, 1089, 1089, 777, 775, 1049, 774, 1051, 773, 1050, 772, 1054, 1052, 771, 770, 1055, 1085, 1090, 1090, 1090, 1118, 1118, 1118, 1119, 1119, 1119, 1120, 1120, 1120, 1121, 1121, 1121, 1143, 1143, 1143, 1144, 1144, 1144, 1145, 1145, 1145, 1146, 1146, 1146, 1088, 1089, 1166, 1166, 1166, 1167, 1167, 1167, 1168, 1168, 1168, 1187, 1187, 1187, 1118, 1186, 1186, 1186, 1201, 1201, 1201, 769, 768, 1121, 1202, 1202, 1202, 767, 1119, 1210, 1210, 1210, 1120, 1211, 1211, 1211, 1143, 1202, 766, 765, 1144, 1217, 1217, 1217, 1218, 1218, 1218, 1146, 1222, 1222, 1222, 763, 1167, 1166, 1224, 1224, 1224, 1186, 762, 761, 1187, 1226, 1226, 1226, 760, 1201, 759, 1211, 1228, 1228, 1228, 1229, 1229, 1229, 758, 1210, 756, 755, 754, 753, 752, 751, 750, 749, 748, 1222, 747, 746, 745, 744, 1218, 743, 742, 741, 740, 739, 708, 707, 1224, 1226, 706, 705, 704, 703, 701, 700, 699, 698, 697, 696, 695, 694, 693, 692, 691, 690, 689, 1228, 1231, 1231, 1231, 1231, 1232, 1232, 1232, 1232, 1233, 1233, 1233, 1233, 1234, 1234, 1234, 1234, 1235, 1235, 1236, 1236, 1237, 688, 1237, 1237, 686, 685, 683, 681, 680, 679, 676, 675, 674, 670, 669, 667, 666, 665, 664, 663, 662, 661, 660, 625, 624, 623, 622, 621, 620, 619, 618, 617, 616, 615, 614, 613, 612, 610, 609, 608, 606, 605, 604, 603, 602, 601, 600, 598, 597, 596, 595, 594, 593, 592, 591, 590, 589, 588, 587, 586, 585, 584, 583, 582, 581, 580, 579, 578, 577, 576, 575, 534, 533, 532, 530, 529, 528, 527, 526, 525, 524, 523, 522, 521, 520, 519, 518, 517, 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, 490, 489, 447, 444, 443, 442, 441, 440, 439, 438, 437, 436, 435, 434, 433, 432, 431, 430, 429, 428, 427, 426, 425, 424, 423, 422, 421, 420, 419, 418, 417, 416, 415, 414, 413, 412, 411, 410, 409, 408, 407, 406, 405, 404, 352, 351, 350, 349, 348, 347, 346, 344, 343, 342, 341, 340, 339, 338, 337, 336, 335, 334, 333, 332, 331, 330, 329, 328, 327, 326, 325, 324, 323, 322, 320, 319, 318, 316, 315, 314, 313, 312, 311, 274, 253, 252, 251, 250, 249, 248, 247, 245, 243, 242, 241, 240, 238, 236, 234, 233, 231, 230, 228, 227, 226, 224, 222, 221, 220, 176, 174, 173, 149, 148, 146, 145, 143, 142, 140, 138, 136, 130, 81, 77, 74, 71, 51, 48, 42, 22, 21, 11, 9, 3, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230 } ; 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 "sip-4.19.7/sipgen/metasrc/lexer.l" /* * The SIP lexer. * * Copyright (c) 2018 Riverbank Computing Limited * * 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 "sip-4.19.7/sipgen/metasrc/lexer.l" #include #include #include #include #include "sip.h" #include "parser.h" #ifndef FLEX_SCANNER #error "Only flex is supported at the moment" #endif /* Windows doesn't have unistd.h so declare it here. */ extern int isatty(int); /* These are unused. */ static int input(void) SIP_UNUSED; static void yy_fatal_error(yyconst char *) SIP_UNUSED; static int yy_top_state(void) SIP_UNUSED; static void yyunput(int, char *) SIP_UNUSED; #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 { sourceLocation sloc; /* The source location. */ YY_BUFFER_STATE bs; /* The flex buffer state handle. */ 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 int parenDepth = 0; /* The current depth of (...). */ static FILE *openFile(const char *); static void fatallex(char *); #line 1564 "sip-4.19.7/sipgen/lexer.c" #define INITIAL 0 #define code 1 #define ccomment 2 #define directive 3 #define directive_start 4 #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 #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 ); yy_size_t 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 static int yy_start_stack_ptr = 0; static int yy_start_stack_depth = 0; static int *yy_start_stack = NULL; static void yy_push_state (int new_state ); static void yy_pop_state (void ); static int yy_top_state (void ); /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #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 fwrite( yytext, yyleng, 1, yyout ) #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 = '*'; \ yy_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 74 "sip-4.19.7/sipgen/metasrc/lexer.l" #line 1766 "sip-4.19.7/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 >= 1231 ) 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] != 2827 ); 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 76 "sip-4.19.7/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_API;} YY_BREAK case 2: YY_RULE_SETUP #line 77 "sip-4.19.7/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_AUTOPYNAME;} YY_BREAK case 3: YY_RULE_SETUP #line 78 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_CMODULE;} YY_BREAK case 4: YY_RULE_SETUP #line 79 "sip-4.19.7/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_COMPOMODULE;} YY_BREAK case 5: YY_RULE_SETUP #line 80 "sip-4.19.7/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_CONSMODULE;} YY_BREAK case 6: YY_RULE_SETUP #line 81 "sip-4.19.7/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_DEFDOCSTRFMT;} YY_BREAK case 7: YY_RULE_SETUP #line 82 "sip-4.19.7/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_DEFDOCSTRSIG;} YY_BREAK case 8: YY_RULE_SETUP #line 83 "sip-4.19.7/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_DEFENCODING;} YY_BREAK case 9: YY_RULE_SETUP #line 84 "sip-4.19.7/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_DEFMETATYPE;} YY_BREAK case 10: YY_RULE_SETUP #line 85 "sip-4.19.7/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_DEFSUPERTYPE;} YY_BREAK case 11: YY_RULE_SETUP #line 86 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_END;} YY_BREAK case 12: YY_RULE_SETUP #line 87 "sip-4.19.7/sipgen/metasrc/lexer.l" {BEGIN INITIAL; return TK_END;} YY_BREAK case 13: YY_RULE_SETUP #line 88 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_EXCEPTION;} YY_BREAK case 14: YY_RULE_SETUP #line 89 "sip-4.19.7/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_FEATURE;} YY_BREAK case 15: YY_RULE_SETUP #line 90 "sip-4.19.7/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_HIDE_NS;} YY_BREAK case 16: YY_RULE_SETUP #line 91 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_IF;} YY_BREAK case 17: YY_RULE_SETUP #line 92 "sip-4.19.7/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_IMPORT;} YY_BREAK case 18: YY_RULE_SETUP #line 93 "sip-4.19.7/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_INCLUDE;} YY_BREAK case 19: YY_RULE_SETUP #line 94 "sip-4.19.7/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_LICENSE;} YY_BREAK case 20: YY_RULE_SETUP #line 95 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_MAPPEDTYPE;} YY_BREAK case 21: YY_RULE_SETUP #line 96 "sip-4.19.7/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_MODULE;} YY_BREAK case 22: YY_RULE_SETUP #line 97 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_OPTINCLUDE;} YY_BREAK case 23: YY_RULE_SETUP #line 98 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_PLATFORMS;} YY_BREAK case 24: YY_RULE_SETUP #line 99 "sip-4.19.7/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_PLUGIN;} YY_BREAK case 25: YY_RULE_SETUP #line 100 "sip-4.19.7/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_PROPERTY;} YY_BREAK case 26: YY_RULE_SETUP #line 101 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_TIMELINE;} YY_BREAK case 27: YY_RULE_SETUP #line 103 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_CLASS;} YY_BREAK case 28: YY_RULE_SETUP #line 104 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_STRUCT;} YY_BREAK case 29: YY_RULE_SETUP #line 105 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_PUBLIC;} YY_BREAK case 30: YY_RULE_SETUP #line 106 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_PROTECTED;} YY_BREAK case 31: YY_RULE_SETUP #line 107 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_PRIVATE;} YY_BREAK case 32: YY_RULE_SETUP #line 108 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_SIGNALS;} YY_BREAK case 33: YY_RULE_SETUP #line 109 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_SIGNALS;} YY_BREAK case 34: YY_RULE_SETUP #line 110 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_SIGNAL_METHOD;} YY_BREAK case 35: YY_RULE_SETUP #line 111 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_SLOTS;} YY_BREAK case 36: YY_RULE_SETUP #line 112 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_SLOTS;} YY_BREAK case 37: YY_RULE_SETUP #line 113 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_SLOT_METHOD;} YY_BREAK case 38: YY_RULE_SETUP #line 114 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_CHAR;} YY_BREAK case 39: YY_RULE_SETUP #line 115 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_WCHAR_T;} YY_BREAK case 40: YY_RULE_SETUP #line 116 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_BOOL;} YY_BREAK case 41: YY_RULE_SETUP #line 117 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_SHORT;} YY_BREAK case 42: YY_RULE_SETUP #line 118 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_INT;} YY_BREAK case 43: YY_RULE_SETUP #line 119 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_LONG;} YY_BREAK case 44: YY_RULE_SETUP #line 120 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_FLOAT;} YY_BREAK case 45: YY_RULE_SETUP #line 121 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_DOUBLE;} YY_BREAK case 46: YY_RULE_SETUP #line 122 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_VOID;} YY_BREAK case 47: YY_RULE_SETUP #line 123 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_VIRTUAL;} YY_BREAK case 48: YY_RULE_SETUP #line 124 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_ENUM;} YY_BREAK case 49: YY_RULE_SETUP #line 125 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_SIGNED;} YY_BREAK case 50: YY_RULE_SETUP #line 126 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_UNSIGNED;} YY_BREAK case 51: YY_RULE_SETUP #line 127 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_CONST;} YY_BREAK case 52: YY_RULE_SETUP #line 128 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_STATIC;} YY_BREAK case 53: YY_RULE_SETUP #line 129 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_TRUE_VALUE;} YY_BREAK case 54: YY_RULE_SETUP #line 130 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_FALSE_VALUE;} YY_BREAK case 55: YY_RULE_SETUP #line 131 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_NULL_VALUE;} YY_BREAK case 56: YY_RULE_SETUP #line 132 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_TYPEDEF;} YY_BREAK case 57: YY_RULE_SETUP #line 133 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_NAMESPACE;} YY_BREAK case 58: YY_RULE_SETUP #line 134 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_OPERATOR;} YY_BREAK case 59: YY_RULE_SETUP #line 135 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_THROW;} YY_BREAK case 60: YY_RULE_SETUP #line 136 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_EXPLICIT;} YY_BREAK case 61: YY_RULE_SETUP #line 137 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_TEMPLATE;} YY_BREAK case 62: YY_RULE_SETUP #line 138 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_FINAL;} YY_BREAK case 63: YY_RULE_SETUP #line 139 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_SCOPE;} YY_BREAK case 64: YY_RULE_SETUP #line 140 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_LOGICAL_OR;} YY_BREAK case 65: YY_RULE_SETUP #line 141 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_PYOBJECT;} YY_BREAK case 66: YY_RULE_SETUP #line 142 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_PYTUPLE;} YY_BREAK case 67: YY_RULE_SETUP #line 143 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_PYLIST;} YY_BREAK case 68: YY_RULE_SETUP #line 144 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_PYDICT;} YY_BREAK case 69: YY_RULE_SETUP #line 145 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_PYCALLABLE;} YY_BREAK case 70: YY_RULE_SETUP #line 146 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_PYSLICE;} YY_BREAK case 71: YY_RULE_SETUP #line 147 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_PYTYPE;} YY_BREAK case 72: YY_RULE_SETUP #line 148 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_PYBUFFER;} YY_BREAK case 73: YY_RULE_SETUP #line 149 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_SIPSIGNAL;} YY_BREAK case 74: YY_RULE_SETUP #line 150 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_SIPSLOT;} YY_BREAK case 75: YY_RULE_SETUP #line 151 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_SIPANYSLOT;} YY_BREAK case 76: YY_RULE_SETUP #line 152 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_SIPRXCON;} YY_BREAK case 77: YY_RULE_SETUP #line 153 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_SIPRXDIS;} YY_BREAK case 78: YY_RULE_SETUP #line 154 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_SIPSLOTCON;} YY_BREAK case 79: YY_RULE_SETUP #line 155 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_SIPSLOTDIS;} YY_BREAK case 80: YY_RULE_SETUP #line 156 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_SIPSSIZET;} YY_BREAK case 81: YY_RULE_SETUP #line 157 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_QOBJECT;} YY_BREAK case 82: YY_RULE_SETUP #line 158 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_ELLIPSIS;} YY_BREAK case 83: YY_RULE_SETUP #line 160 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_FORMAT;} YY_BREAK case 84: YY_RULE_SETUP #line 161 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_GET;} YY_BREAK case 85: YY_RULE_SETUP #line 162 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_ID;} YY_BREAK case 86: YY_RULE_SETUP #line 163 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_KWARGS;} YY_BREAK case 87: YY_RULE_SETUP #line 164 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_LANGUAGE;} YY_BREAK case 88: YY_RULE_SETUP #line 165 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_LICENSEE;} YY_BREAK case 89: YY_RULE_SETUP #line 166 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_NAME;} YY_BREAK case 90: YY_RULE_SETUP #line 167 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_OPTIONAL;} YY_BREAK case 91: YY_RULE_SETUP #line 168 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_ORDER;} YY_BREAK case 92: YY_RULE_SETUP #line 169 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_REMOVELEADING;} YY_BREAK case 93: YY_RULE_SETUP #line 170 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_SET;} YY_BREAK case 94: YY_RULE_SETUP #line 171 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_SIGNATURE;} YY_BREAK case 95: YY_RULE_SETUP #line 172 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_TIMESTAMP;} YY_BREAK case 96: YY_RULE_SETUP #line 173 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_TYPE;} YY_BREAK case 97: YY_RULE_SETUP #line 174 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_USEARGNAMES;} YY_BREAK case 98: YY_RULE_SETUP #line 175 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_USELIMITEDAPI;} YY_BREAK case 99: YY_RULE_SETUP #line 176 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_ALLRAISEPYEXC;} YY_BREAK case 100: YY_RULE_SETUP #line 177 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_CALLSUPERINIT;} YY_BREAK case 101: YY_RULE_SETUP #line 178 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_DEFERRORHANDLER;} YY_BREAK case 102: YY_RULE_SETUP #line 179 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_VERSION;} YY_BREAK case 103: YY_RULE_SETUP #line 181 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_TRUE_VALUE;} YY_BREAK case 104: YY_RULE_SETUP #line 182 "sip-4.19.7/sipgen/metasrc/lexer.l" {return TK_FALSE_VALUE;} YY_BREAK case 105: YY_RULE_SETUP #line 185 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* Ignore whitespace. */ ; } YY_BREAK case 106: YY_RULE_SETUP #line 190 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* * Maintain the parenthesis depth so that we don't enter the 'code' state * until any arguments have been parsed. */ ++parenDepth; BEGIN directive; return '('; } YY_BREAK case 107: YY_RULE_SETUP #line 202 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* Maintain the parenthesis depth. */ --parenDepth; BEGIN INITIAL; return ')'; } YY_BREAK case 108: /* rule 108 can match eol */ YY_RULE_SETUP #line 211 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* Maintain the line number. */ ++inputFileStack[currentFile].sloc.linenr; if (codeIdx == 0 && parenDepth == 0) { BEGIN code; } } YY_BREAK case 109: YY_RULE_SETUP #line 221 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* Ignore C++ style comments. */ ; } YY_BREAK case 110: YY_RULE_SETUP #line 227 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* A signed decimal number. */ yylval.number = strtol(yytext,NULL,0); return TK_NUMBER_VALUE; } YY_BREAK case 111: YY_RULE_SETUP #line 234 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* A floating point number. */ yylval.real = strtod(yytext,NULL); return TK_REAL_VALUE; } YY_BREAK case 112: YY_RULE_SETUP #line 241 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* An unsigned hexadecimal number. */ yylval.number = strtol(yytext,NULL,16); return TK_NUMBER_VALUE; } YY_BREAK case 113: YY_RULE_SETUP #line 248 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* An identifier name. */ yylval.text = sipStrdup(yytext); return TK_NAME_VALUE; } YY_BREAK case 114: YY_RULE_SETUP #line 255 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* A relative pathname. */ yylval.text = sipStrdup(yytext); return TK_PATH_VALUE; } YY_BREAK case 115: /* rule 115 can match eol */ YY_RULE_SETUP #line 262 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* A double-quoted string. */ char ch, *dp, *sp; /* * Copy the string without the quotes and interpret any standard escape * characters. */ yylval.text = sipMalloc(strlen(yytext) - 2 + 1); dp = yylval.text; sp = yytext + 1; while ((ch = *sp++) != '"' && ch != '\0') { if (ch == '\\') { ch = *sp++; if (ch == 'n') ch = '\n'; else if (ch == 'r') ch = '\r'; else if (ch == 't') ch = '\t'; } *dp++ = ch; } *dp = '\0'; return TK_STRING_VALUE; } YY_BREAK case 116: /* rule 116 can match eol */ YY_RULE_SETUP #line 298 "sip-4.19.7/sipgen/metasrc/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_VALUE; } YY_BREAK case 117: YY_RULE_SETUP #line 309 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* Ignore C-style comments. */ yy_push_state(ccomment); } YY_BREAK case 118: /* rule 118 can match eol */ YY_RULE_SETUP #line 313 "sip-4.19.7/sipgen/metasrc/lexer.l" { ++inputFileStack[currentFile].sloc.linenr; } YY_BREAK case 119: YY_RULE_SETUP #line 316 "sip-4.19.7/sipgen/metasrc/lexer.l" { yy_pop_state(); } YY_BREAK case 120: YY_RULE_SETUP #line 319 "sip-4.19.7/sipgen/metasrc/lexer.l" { ; } YY_BREAK case 121: YY_RULE_SETUP #line 324 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The software license. */ codeIdx = 0; return TK_COPYING; } YY_BREAK case 122: YY_RULE_SETUP #line 330 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a from-type code block. */ codeIdx = 0; return TK_FROMTYPE; } YY_BREAK case 123: YY_RULE_SETUP #line 336 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a to-type code block. */ codeIdx = 0; return TK_TOTYPE; } YY_BREAK case 124: YY_RULE_SETUP #line 342 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a to-sub-class code block. */ codeIdx = 0; return TK_TOSUBCLASS; } YY_BREAK case 125: YY_RULE_SETUP #line 348 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of an exported header code block. */ codeIdx = 0; return TK_EXPHEADERCODE; } YY_BREAK case 126: YY_RULE_SETUP #line 354 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of part of an extract. */ codeIdx = 0; BEGIN directive_start; return TK_EXTRACT; } YY_BREAK case 127: YY_RULE_SETUP #line 363 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a module header code block. */ codeIdx = 0; return TK_MODHEADERCODE; } YY_BREAK case 128: YY_RULE_SETUP #line 369 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a type header code block. */ codeIdx = 0; return TK_TYPEHEADERCODE; } YY_BREAK case 129: YY_RULE_SETUP #line 375 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a pre-initialisation code block. */ codeIdx = 0; return TK_PREINITCODE; } YY_BREAK case 130: YY_RULE_SETUP #line 381 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of an initialisation code block. */ codeIdx = 0; return TK_INITCODE; } YY_BREAK case 131: YY_RULE_SETUP #line 387 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a post-initialisation code block. */ codeIdx = 0; return TK_POSTINITCODE; } YY_BREAK case 132: YY_RULE_SETUP #line 393 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a class finalisation code block. */ codeIdx = 0; return TK_FINALCODE; } YY_BREAK case 133: YY_RULE_SETUP #line 399 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a unit code block. */ codeIdx = 0; return TK_UNITCODE; } YY_BREAK case 134: YY_RULE_SETUP #line 405 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a unit post-include code block. */ codeIdx = 0; return TK_UNITPOSTINCLUDECODE; } YY_BREAK case 135: YY_RULE_SETUP #line 411 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a module code block. */ codeIdx = 0; return TK_MODCODE; } YY_BREAK case 136: YY_RULE_SETUP #line 417 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a type code block. */ codeIdx = 0; return TK_TYPECODE; } YY_BREAK case 137: YY_RULE_SETUP #line 423 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a C++ method code block. */ codeIdx = 0; return TK_METHODCODE; } YY_BREAK case 138: YY_RULE_SETUP #line 429 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a C++ code block to insert before the MethodCode. */ codeIdx = 0; return TK_PREMETHODCODE; } YY_BREAK case 139: YY_RULE_SETUP #line 435 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a C++ virtual call code block. */ codeIdx = 0; return TK_VIRTUALCALLCODE; } YY_BREAK case 140: YY_RULE_SETUP #line 441 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a C++ virtual code block. */ codeIdx = 0; return TK_VIRTUALCATCHERCODE; } YY_BREAK case 141: YY_RULE_SETUP #line 447 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a traverse code block. */ codeIdx = 0; return TK_TRAVERSECODE; } YY_BREAK case 142: YY_RULE_SETUP #line 453 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a clear code block. */ codeIdx = 0; return TK_CLEARCODE; } YY_BREAK case 143: YY_RULE_SETUP #line 459 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a get buffer code block. */ codeIdx = 0; return TK_GETBUFFERCODE; } YY_BREAK case 144: YY_RULE_SETUP #line 465 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a release buffer code block. */ codeIdx = 0; return TK_RELEASEBUFFERCODE; } YY_BREAK case 145: YY_RULE_SETUP #line 471 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a read buffer code block. */ codeIdx = 0; return TK_READBUFFERCODE; } YY_BREAK case 146: YY_RULE_SETUP #line 477 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a write buffer code block. */ codeIdx = 0; return TK_WRITEBUFFERCODE; } YY_BREAK case 147: YY_RULE_SETUP #line 483 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a segment count code block. */ codeIdx = 0; return TK_SEGCOUNTCODE; } YY_BREAK case 148: YY_RULE_SETUP #line 489 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a char buffer code block. */ codeIdx = 0; return TK_CHARBUFFERCODE; } YY_BREAK case 149: YY_RULE_SETUP #line 495 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a create instance code block. */ codeIdx = 0; return TK_INSTANCECODE; } YY_BREAK case 150: YY_RULE_SETUP #line 501 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a pickle code block. */ codeIdx = 0; return TK_PICKLECODE; } YY_BREAK case 151: YY_RULE_SETUP #line 507 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a pre-Python code block. */ deprecated("%PrePythonCode is deprecated"); codeIdx = 0; return TK_PREPYCODE; } YY_BREAK case 152: YY_RULE_SETUP #line 515 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a raise Python exception code block. */ codeIdx = 0; return TK_RAISECODE; } YY_BREAK case 153: YY_RULE_SETUP #line 521 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of an exported type hint code block. */ codeIdx = 0; return TK_EXPTYPEHINTCODE; } YY_BREAK case 154: YY_RULE_SETUP #line 527 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a type hint code block. */ codeIdx = 0; return TK_TYPEHINTCODE; } YY_BREAK case 155: YY_RULE_SETUP #line 533 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a docstring block. */ codeIdx = 0; BEGIN directive_start; return TK_DOCSTRING; } YY_BREAK case 156: YY_RULE_SETUP #line 542 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a documentation block. */ deprecated("%Doc is deprecated, use %Extract instead"); codeIdx = 0; return TK_DOC; } YY_BREAK case 157: YY_RULE_SETUP #line 550 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of an exported documentation block. */ deprecated("%ExportedDoc is deprecated, use %Extract instead"); codeIdx = 0; return TK_EXPORTEDDOC; } YY_BREAK case 158: YY_RULE_SETUP #line 558 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a Makefile code block. */ deprecated("%Makefile is deprecated"); codeIdx = 0; return TK_MAKEFILE; } YY_BREAK case 159: YY_RULE_SETUP #line 566 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of an access code block. */ codeIdx = 0; return TK_ACCESSCODE; } YY_BREAK case 160: YY_RULE_SETUP #line 572 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a get code block. */ codeIdx = 0; return TK_GETCODE; } YY_BREAK case 161: YY_RULE_SETUP #line 578 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of a set code block. */ codeIdx = 0; return TK_SETCODE; } YY_BREAK case 162: YY_RULE_SETUP #line 584 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The start of part of a virtual error handler. */ codeIdx = 0; BEGIN directive_start; return TK_VIRTERRORHANDLER; } YY_BREAK case 163: YY_RULE_SETUP #line 593 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* The end of a code block. */ BEGIN INITIAL; codeIdx = -1; return TK_END; } YY_BREAK case 164: /* rule 164 can match eol */ YY_RULE_SETUP #line 600 "sip-4.19.7/sipgen/metasrc/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->sloc.linenr++; yylval.codeb->filename = ifp->sloc.name; return TK_CODELINE; } YY_BREAK case 165: YY_RULE_SETUP #line 619 "sip-4.19.7/sipgen/metasrc/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 166: YY_RULE_SETUP #line 627 "sip-4.19.7/sipgen/metasrc/lexer.l" { /* Anything else is returned as is. */ return yytext[0]; } YY_BREAK case 167: YY_RULE_SETUP #line 632 "sip-4.19.7/sipgen/metasrc/lexer.l" ECHO; YY_BREAK #line 3007 "sip-4.19.7/sipgen/lexer.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(code): case YY_STATE_EOF(ccomment): case YY_STATE_EOF(directive): case YY_STATE_EOF(directive_start): 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 { yy_size_t 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 ) { yy_size_t 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), 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 >= 1231 ) 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 >= 1231 ) 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 == 1230); 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 yy_size_t 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 */ yy_size_t 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 0; 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) { yy_size_t 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 bytes the byte buffer to scan * @param 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, yy_size_t _yybytes_len ) { YY_BUFFER_STATE b; char *buf; yy_size_t n, 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; } static void yy_push_state (int new_state ) { if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) ) { yy_size_t new_size; (yy_start_stack_depth) += YY_START_STACK_INCR; new_size = (yy_start_stack_depth) * sizeof( int ); if ( ! (yy_start_stack) ) (yy_start_stack) = (int *) yyalloc(new_size ); else (yy_start_stack) = (int *) yyrealloc((void *) (yy_start_stack),new_size ); if ( ! (yy_start_stack) ) YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); } (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; BEGIN(new_state); } static void yy_pop_state (void) { if ( --(yy_start_stack_ptr) < 0 ) YY_FATAL_ERROR( "start-condition stack underflow" ); BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); } static int yy_top_state (void) { return (yy_start_stack)[(yy_start_stack_ptr) - 1]; } #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. * */ yy_size_t 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; (yy_start_stack_ptr) = 0; (yy_start_stack_depth) = 0; (yy_start_stack) = NULL; /* 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; /* Destroy the start condition stack. */ yyfree((yy_start_stack) ); (yy_start_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 632 "sip-4.19.7/sipgen/metasrc/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->sloc.name, &ifp->pc); /* * Tidy up this file. Note that we don't free the filename as it will * still be referenced for use in error messages. */ fclose(yyin); /* 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; } /* * Get the current source location. */ void getSourceLocation(sourceLocation *slp) { int cf; /* * Assume that we will already have gone past the newline but watch out in * case we have gone past the end of the file. */ if ((cf = currentFile) < 0) { /* This will be valid if we have been called. */ cf = 0; } slp->linenr = inputFileStack[cf].sloc.linenr - 1; slp->name = inputFileStack[cf].sloc.name; } /* * 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].sloc.linenr = 1; inputFileStack[currentFile].sloc.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].sloc.name, inputFileStack[currentFile].sloc.linenr, s); } /* * Handle warnings while parsing. */ void yywarning(char *s) { warning(ParserWarning, "%s:%d: %s\n", inputFileStack[currentFile].sloc.name, inputFileStack[currentFile].sloc.linenr, s); } /* * Handle deprecation warnings. */ void deprecated(const char *msg) { warning(DeprecationWarning, "%s:%d: %s\n", inputFileStack[currentFile].sloc.name, inputFileStack[currentFile].sloc.linenr, msg); } /* * Handle fatal lex errors. */ static void fatallex(char *s) { fatal("%s:%d: Lexical analyser error: %s\n", inputFileStack[currentFile].sloc.name, inputFileStack[currentFile].sloc.linenr, s); } /* * Reset the lexer state to INITIAL. This is used by directives that allow an * argument to be given without parentheses to get out of the 'directive_start' * state before an opening parenthesis is seen in another context. */ void resetLexerState() { BEGIN INITIAL; } sip-4.19.7/sipgen/main.c0000644000076500000240000003656313231604406015057 0ustar philstaff00000000000000/* * The main module for SIP. * * Copyright (c) 2017 Riverbank Computing Limited * * 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 #include #include #include #include #include "sip.h" #ifndef PACKAGE #define PACKAGE "sip" #endif /* Global variables - see sip.h for their meaning. */ char *sipVersion; stringList *includeDirList; static char *sipPackage = PACKAGE; static int warnings = FALSE; static int warnings_are_fatal = FALSE; SIP_NORETURN static void help(void); SIP_NORETURN static void version(void); SIP_NORETURN 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, *pyiFile; int optnr, exceptions, tracing, releaseGIL, parts, protHack, docs; int timestamp, was_flagFile, py_debug, strict; KwArgs kwArgs; FILE *file; sipSpec spec; stringList *versions, *backstops, *xfeatures, *extracts; /* Initialise. */ sipVersion = SIP_VERSION_STR; includeDirList = NULL; versions = NULL; backstops = NULL; xfeatures = NULL; buildFile = NULL; codeDir = NULL; docFile = NULL; srcSuffix = NULL; flagFile = NULL; was_flagFile = FALSE; apiFile = NULL; xmlFile = NULL; pyiFile = NULL; consModule = NULL; extracts = NULL; exceptions = FALSE; tracing = FALSE; releaseGIL = FALSE; parts = 0; kwArgs = NoKwArgs; protHack = FALSE; docs = FALSE; timestamp = TRUE; py_debug = FALSE; strict = TRUE; /* Parse the command line. */ optnr = 1; while ((arg = parseopt(argc, argv, "hVa:b:B:ec:d:DfgI:j:km:op:Prs:t:Twx:X:y: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 'y': /* Where to generate the .pyi file. */ pyiFile = optarg; break; case 'b': /* Generate a build file. */ buildFile = optarg; break; case 'B': /* Define a backstop. */ appendString(&backstops, 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; was_flagFile = TRUE; break; case 'c': /* Where to generate the code. */ codeDir = optarg; break; case 'd': /* Where to generate the documentation. */ docFile = optarg; break; case 'D': /* Generate code for a debug build of Python. */ py_debug = TRUE; break; case 't': /* Which platform or version to generate code for. */ appendString(&versions,optarg); break; case 'T': /* * Disable the timestamp in the header of generated files. It is * now ignored apart from triggering a deprecation warning. */ timestamp = FALSE; break; case 'x': /* Which features are disabled. */ appendString(&xfeatures,optarg); break; case 'X': /* Which extracts are to be created. */ appendString(&extracts, 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 'f': /* Warning messages are fatal. */ warnings_are_fatal = TRUE; break; case 'k': /* Allow keyword arguments in functions and methods. */ kwArgs = AllKwArgs; 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"; } /* Issue warnings after they (might) have been enabled. */ if (docFile != NULL) warning(DeprecationWarning, "the -d flag is deprecated\n"); if (kwArgs != NoKwArgs) warning(DeprecationWarning, "the -k flag is deprecated\n"); if (!timestamp) warning(DeprecationWarning, "the -T flag is ignored and deprecated\n"); if (was_flagFile) warning(DeprecationWarning, "the -z flag is deprecated\n"); /* Handle conflicting arguments. */ if (xmlFile != NULL) { if (codeDir != NULL || docFile != NULL || buildFile != NULL) fatal("The -m flag cannot be specified with either the -b, -c or -d flags\n"); strict = FALSE; } /* Parse the input file. */ parse(&spec, file, filename, strict, versions, backstops, xfeatures, kwArgs, protHack); /* Verify and transform the parse tree. */ transform(&spec, strict); /* Generate code. */ generateCode(&spec, codeDir, buildFile, docFile, srcSuffix, exceptions, tracing, releaseGIL, parts, versions, xfeatures, consModule, docs, py_debug); /* Generate any extracts. */ generateExtracts(&spec, extracts); /* Generate the API file. */ if (apiFile != NULL) generateAPI(&spec, spec.module, apiFile); /* Generate the XML export. */ if (xmlFile != NULL) generateXML(&spec, spec.module, xmlFile); /* Generate the .pyi file. */ if (pyiFile != NULL) generateTypeHints(&spec, spec.module, pyiFile); /* 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; optnr = *optnrp; /* Deal with any file first. */ fname = *flags; /* Support the sip5 method of passing arguments in a file. */ if (fname == NULL && optnr < argc && argv[optnr][0] == '@') { fname = *flags = &argv[optnr][1]; *optnrp = ++optnr; } 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. */ 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(Warning w, const char *fmt, ...) { static int start = TRUE; va_list ap; /* Don't allow deprecation warnings to be suppressed. */ if (!warnings && w != DeprecationWarning) return; if (start) { const char *wstr; switch (w) { case ParserWarning: wstr = "Parser warning"; break; case DeprecationWarning: wstr = "Deprecation warning"; break; } fprintf(stderr, "%s: %s: ", sipPackage, wstr); start = FALSE; } va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); if (strchr(fmt, '\n') != NULL) { if (warnings_are_fatal) exit(1); start = TRUE; } } /* * Display all or part of a one line error message describing a fatal error. */ void fatal(const char *fmt, ...) { va_list ap; fatalStart(); va_start(ap,fmt); vfprintf(stderr,fmt,ap); va_end(ap); exit(1); } /* * Make sure the start of a fatal message is handled. */ void fatalStart() { static int start = TRUE; if (start) { fprintf(stderr, "%s: ", sipPackage); start = FALSE; } } /* * 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] [-B tag] [-c dir] [-d file] [-D] [-e] [-f] [-g] [-I dir] [-j #] [-k] [-m file] [-o] [-p module] [-P] [-r] [-s suffix] [-t tag] [-T] [-w] [-x feature] [-X id:file] [-z file] [@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" " -B tag add tag to the list of timeline backstops\n" " -c dir the name of the code directory [default not generated]\n" " -d file the name of the documentation file (deprecated) [default not generated]\n" " -D generate code for a debug build of Python\n" " -e enable support for exceptions [default disabled]\n" " -f warnings are handled as errors\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" " -X id:file create the extracts for an id in a file\n" " -y file the name of the .pyi stub file [default not generated]\n" " -z file the name of a file containing more command line flags\n" " @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] [-B tag] [-c dir] " "[-d file] [-D] [-e] [-f] [-g] [-I dir] [-j #] [-k] [-m file] [-o] " "[-p module] [-P] [-r] [-s suffix] [-t tag] [-w] [-x feature] " "[-X id:file] [-y file] [-z file] [@file] [file]\n", sipPackage); } sip-4.19.7/sipgen/metasrc/0000755000076500000240000000000013231604406015410 5ustar philstaff00000000000000sip-4.19.7/sipgen/metasrc/lexer.l0000644000076500000240000005222413231604406016711 0ustar philstaff00000000000000/* * The SIP lexer. * * Copyright (c) 2018 Riverbank Computing Limited * * 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 #include #include #include #include "sip.h" #include "parser.h" #ifndef FLEX_SCANNER #error "Only flex is supported at the moment" #endif /* Windows doesn't have unistd.h so declare it here. */ extern int isatty(int); /* These are unused. */ static int input(void) SIP_UNUSED; static void yy_fatal_error(yyconst char *) SIP_UNUSED; static int yy_top_state(void) SIP_UNUSED; static void yyunput(int, char *) SIP_UNUSED; #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 { sourceLocation sloc; /* The source location. */ YY_BUFFER_STATE bs; /* The flex buffer state handle. */ 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 int parenDepth = 0; /* The current depth of (...). */ static FILE *openFile(const char *); static void fatallex(char *); %} %option stack %x code %x ccomment %s directive %s directive_start %% ^[ \t]*%API {BEGIN directive_start; return TK_API;} ^[ \t]*%AutoPyName {BEGIN directive_start; return TK_AUTOPYNAME;} ^[ \t]*%CModule {return TK_CMODULE;} ^[ \t]*%CompositeModule {BEGIN directive_start; return TK_COMPOMODULE;} ^[ \t]*%ConsolidatedModule {BEGIN directive_start; return TK_CONSMODULE;} ^[ \t]*%DefaultDocstringFormat {BEGIN directive_start; return TK_DEFDOCSTRFMT;} ^[ \t]*%DefaultDocstringSignature {BEGIN directive_start; return TK_DEFDOCSTRSIG;} ^[ \t]*%DefaultEncoding {BEGIN directive_start; return TK_DEFENCODING;} ^[ \t]*%DefaultMetatype {BEGIN directive_start; return TK_DEFMETATYPE;} ^[ \t]*%DefaultSupertype {BEGIN directive_start; return TK_DEFSUPERTYPE;} ^[ \t]*%End {return TK_END;} ^[ \t]*%End {BEGIN INITIAL; return TK_END;} ^[ \t]*%Exception {return TK_EXCEPTION;} ^[ \t]*%Feature {BEGIN directive_start; return TK_FEATURE;} ^[ \t]*%HideNamespace {BEGIN directive_start; return TK_HIDE_NS;} ^[ \t]*%If {return TK_IF;} ^[ \t]*%Import {BEGIN directive_start; return TK_IMPORT;} ^[ \t]*%Include {BEGIN directive_start; return TK_INCLUDE;} ^[ \t]*%License {BEGIN directive_start; return TK_LICENSE;} ^[ \t]*%MappedType {return TK_MAPPEDTYPE;} ^[ \t]*%Module {BEGIN directive_start; return TK_MODULE;} ^[ \t]*%OptionalInclude {return TK_OPTINCLUDE;} ^[ \t]*%Platforms {return TK_PLATFORMS;} ^[ \t]*%Plugin {BEGIN directive_start; return TK_PLUGIN;} ^[ \t]*%Property {BEGIN directive_start; return TK_PROPERTY;} ^[ \t]*%Timeline {return TK_TIMELINE;} 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_VALUE;} false {return TK_FALSE_VALUE;} NULL {return TK_NULL_VALUE;} typedef {return TK_TYPEDEF;} namespace {return TK_NAMESPACE;} operator {return TK_OPERATOR;} throw {return TK_THROW;} explicit {return TK_EXPLICIT;} template {return TK_TEMPLATE;} final {return TK_FINAL;} :: {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_PYBUFFER {return TK_PYBUFFER;} 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_SSIZE_T {return TK_SIPSSIZET;} SIP_QOBJECT {return TK_QOBJECT;} \.\.\. {return TK_ELLIPSIS;} format {return TK_FORMAT;} get {return TK_GET;} id {return TK_ID;} keyword_arguments {return TK_KWARGS;} language {return TK_LANGUAGE;} licensee {return TK_LICENSEE;} name {return TK_NAME;} optional {return TK_OPTIONAL;} order {return TK_ORDER;} remove_leading {return TK_REMOVELEADING;} set {return TK_SET;} signature {return TK_SIGNATURE;} timestamp {return TK_TIMESTAMP;} type {return TK_TYPE;} use_argument_names {return TK_USEARGNAMES;} use_limited_api {return TK_USELIMITEDAPI;} all_raise_py_exception {return TK_ALLRAISEPYEXC;} call_super_init {return TK_CALLSUPERINIT;} default_VirtualErrorHandler {return TK_DEFERRORHANDLER;} version {return TK_VERSION;} True {return TK_TRUE_VALUE;} False {return TK_FALSE_VALUE;} [ \t\r] { /* Ignore whitespace. */ ; } \( { /* * Maintain the parenthesis depth so that we don't enter the 'code' state * until any arguments have been parsed. */ ++parenDepth; BEGIN directive; return '('; } \) { /* Maintain the parenthesis depth. */ --parenDepth; BEGIN INITIAL; return ')'; } \n { /* Maintain the line number. */ ++inputFileStack[currentFile].sloc.linenr; if (codeIdx == 0 && parenDepth == 0) { BEGIN code; } } \/\/.* { /* Ignore C++ style comments. */ ; } -?[0-9]+[lLuU]? { /* A signed decimal number. */ yylval.number = strtol(yytext,NULL,0); return TK_NUMBER_VALUE; } -?([0-9]+(\.[0-9]*)?|\.[0-9]+)([eE][-+]?[0-9]+)?[fF]? { /* A floating point number. */ yylval.real = strtod(yytext,NULL); return TK_REAL_VALUE; } 0x[0-9a-fA-F]+ { /* An unsigned hexadecimal number. */ yylval.number = strtol(yytext,NULL,16); return TK_NUMBER_VALUE; } [_A-Za-z][_A-Za-z0-9]* { /* An identifier name. */ yylval.text = sipStrdup(yytext); return TK_NAME_VALUE; } [._A-Za-z][._/A-Za-z0-9\-]*[._A-Za-z0-9] { /* A relative pathname. */ yylval.text = sipStrdup(yytext); return TK_PATH_VALUE; } \"(\\.|[^\\"])*\" { /* A double-quoted string. */ char ch, *dp, *sp; /* * Copy the string without the quotes and interpret any standard escape * characters. */ yylval.text = sipMalloc(strlen(yytext) - 2 + 1); dp = yylval.text; sp = yytext + 1; while ((ch = *sp++) != '"' && ch != '\0') { if (ch == '\\') { ch = *sp++; if (ch == 'n') ch = '\n'; else if (ch == 'r') ch = '\r'; else if (ch == 't') ch = '\t'; } *dp++ = ch; } *dp = '\0'; return TK_STRING_VALUE; } \'[^'\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_VALUE; } \/\* { /* Ignore C-style comments. */ yy_push_state(ccomment); } \n { ++inputFileStack[currentFile].sloc.linenr; } \*\/ { yy_pop_state(); } . { ; } ^[ \t]*%Copying { /* The software license. */ codeIdx = 0; return TK_COPYING; } ^[ \t]*%ConvertFromTypeCode { /* The start of a from-type code block. */ codeIdx = 0; return TK_FROMTYPE; } ^[ \t]*%ConvertToTypeCode { /* The start of a to-type code block. */ codeIdx = 0; return TK_TOTYPE; } ^[ \t]*%ConvertToSubClassCode { /* The start of a to-sub-class code block. */ codeIdx = 0; return TK_TOSUBCLASS; } ^[ \t]*%ExportedHeaderCode { /* The start of an exported header code block. */ codeIdx = 0; return TK_EXPHEADERCODE; } ^[ \t]*%Extract { /* The start of part of an extract. */ codeIdx = 0; BEGIN directive_start; return TK_EXTRACT; } ^[ \t]*%ModuleHeaderCode { /* The start of a module header code block. */ codeIdx = 0; return TK_MODHEADERCODE; } ^[ \t]*%TypeHeaderCode { /* The start of a type header code block. */ codeIdx = 0; return TK_TYPEHEADERCODE; } ^[ \t]*%PreInitialisationCode { /* The start of a pre-initialisation code block. */ codeIdx = 0; return TK_PREINITCODE; } ^[ \t]*%InitialisationCode { /* The start of an initialisation code block. */ codeIdx = 0; return TK_INITCODE; } ^[ \t]*%PostInitialisationCode { /* The start of a post-initialisation code block. */ codeIdx = 0; return TK_POSTINITCODE; } ^[ \t]*%FinalisationCode { /* The start of a class finalisation code block. */ codeIdx = 0; return TK_FINALCODE; } ^[ \t]*%UnitCode { /* The start of a unit code block. */ codeIdx = 0; return TK_UNITCODE; } ^[ \t]*%UnitPostIncludeCode { /* The start of a unit post-include code block. */ codeIdx = 0; return TK_UNITPOSTINCLUDECODE; } ^[ \t]*%ModuleCode { /* The start of a module code block. */ codeIdx = 0; return TK_MODCODE; } ^[ \t]*%TypeCode { /* The start of a type code block. */ codeIdx = 0; return TK_TYPECODE; } ^[ \t]*%MethodCode { /* The start of a C++ method code block. */ codeIdx = 0; return TK_METHODCODE; } ^[ \t]*%PreMethodCode { /* The start of a C++ code block to insert before the MethodCode. */ codeIdx = 0; return TK_PREMETHODCODE; } ^[ \t]*%VirtualCallCode { /* The start of a C++ virtual call code block. */ codeIdx = 0; return TK_VIRTUALCALLCODE; } ^[ \t]*%VirtualCatcherCode { /* The start of a C++ virtual code block. */ codeIdx = 0; return TK_VIRTUALCATCHERCODE; } ^[ \t]*%GCTraverseCode { /* The start of a traverse code block. */ codeIdx = 0; return TK_TRAVERSECODE; } ^[ \t]*%GCClearCode { /* The start of a clear code block. */ codeIdx = 0; return TK_CLEARCODE; } ^[ \t]*%BIGetBufferCode { /* The start of a get buffer code block. */ codeIdx = 0; return TK_GETBUFFERCODE; } ^[ \t]*%BIReleaseBufferCode { /* The start of a release buffer code block. */ codeIdx = 0; return TK_RELEASEBUFFERCODE; } ^[ \t]*%BIGetReadBufferCode { /* The start of a read buffer code block. */ codeIdx = 0; return TK_READBUFFERCODE; } ^[ \t]*%BIGetWriteBufferCode { /* The start of a write buffer code block. */ codeIdx = 0; return TK_WRITEBUFFERCODE; } ^[ \t]*%BIGetSegCountCode { /* The start of a segment count code block. */ codeIdx = 0; return TK_SEGCOUNTCODE; } ^[ \t]*%BIGetCharBufferCode { /* The start of a char buffer code block. */ codeIdx = 0; return TK_CHARBUFFERCODE; } ^[ \t]*%InstanceCode { /* The start of a create instance code block. */ codeIdx = 0; return TK_INSTANCECODE; } ^[ \t]*%PickleCode { /* The start of a pickle code block. */ codeIdx = 0; return TK_PICKLECODE; } ^[ \t]*%PrePythonCode { /* The start of a pre-Python code block. */ deprecated("%PrePythonCode is deprecated"); codeIdx = 0; return TK_PREPYCODE; } ^[ \t]*%RaiseCode { /* The start of a raise Python exception code block. */ codeIdx = 0; return TK_RAISECODE; } ^[ \t]*%ExportedTypeHintCode { /* The start of an exported type hint code block. */ codeIdx = 0; return TK_EXPTYPEHINTCODE; } ^[ \t]*%TypeHintCode { /* The start of a type hint code block. */ codeIdx = 0; return TK_TYPEHINTCODE; } ^[ \t]*%Docstring { /* The start of a docstring block. */ codeIdx = 0; BEGIN directive_start; return TK_DOCSTRING; } ^[ \t]*%Doc { /* The start of a documentation block. */ deprecated("%Doc is deprecated, use %Extract instead"); codeIdx = 0; return TK_DOC; } ^[ \t]*%ExportedDoc { /* The start of an exported documentation block. */ deprecated("%ExportedDoc is deprecated, use %Extract instead"); codeIdx = 0; return TK_EXPORTEDDOC; } ^[ \t]*%Makefile { /* The start of a Makefile code block. */ deprecated("%Makefile is deprecated"); codeIdx = 0; return TK_MAKEFILE; } ^[ \t]*%AccessCode { /* The start of an access code block. */ codeIdx = 0; return TK_ACCESSCODE; } ^[ \t]*%GetCode { /* The start of a get code block. */ codeIdx = 0; return TK_GETCODE; } ^[ \t]*%SetCode { /* The start of a set code block. */ codeIdx = 0; return TK_SETCODE; } ^[ \t]*%VirtualErrorHandler { /* The start of part of a virtual error handler. */ codeIdx = 0; BEGIN directive_start; return TK_VIRTERRORHANDLER; } ^[ \t]*%End { /* The end of a code block. */ BEGIN INITIAL; codeIdx = -1; return TK_END; } \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->sloc.linenr++; yylval.codeb->filename = ifp->sloc.name; return TK_CODELINE; } . { /* 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->sloc.name, &ifp->pc); /* * Tidy up this file. Note that we don't free the filename as it will * still be referenced for use in error messages. */ fclose(yyin); /* 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; } /* * Get the current source location. */ void getSourceLocation(sourceLocation *slp) { int cf; /* * Assume that we will already have gone past the newline but watch out in * case we have gone past the end of the file. */ if ((cf = currentFile) < 0) { /* This will be valid if we have been called. */ cf = 0; } slp->linenr = inputFileStack[cf].sloc.linenr - 1; slp->name = inputFileStack[cf].sloc.name; } /* * 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].sloc.linenr = 1; inputFileStack[currentFile].sloc.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].sloc.name, inputFileStack[currentFile].sloc.linenr, s); } /* * Handle warnings while parsing. */ void yywarning(char *s) { warning(ParserWarning, "%s:%d: %s\n", inputFileStack[currentFile].sloc.name, inputFileStack[currentFile].sloc.linenr, s); } /* * Handle deprecation warnings. */ void deprecated(const char *msg) { warning(DeprecationWarning, "%s:%d: %s\n", inputFileStack[currentFile].sloc.name, inputFileStack[currentFile].sloc.linenr, msg); } /* * Handle fatal lex errors. */ static void fatallex(char *s) { fatal("%s:%d: Lexical analyser error: %s\n", inputFileStack[currentFile].sloc.name, inputFileStack[currentFile].sloc.linenr, s); } /* * Reset the lexer state to INITIAL. This is used by directives that allow an * argument to be given without parentheses to get out of the 'directive_start' * state before an opening parenthesis is seen in another context. */ void resetLexerState() { BEGIN INITIAL; } sip-4.19.7/sipgen/metasrc/parser.y0000644000076500000240000077201013231604406017105 0ustar philstaff00000000000000/* * The SIP parser. * * Copyright (c) 2018 Riverbank Computing Limited * * 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 #include #include #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 int strictParse; /* Set if the platform is enforced. */ static stringList *backstops; /* The list of backstops. */ 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 stackPtr; /* The 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 platformDef *currentPlatforms; /* The current platforms list. */ static platformDef *platformStack[MAX_NESTED_IF]; /* Stack of platforms. */ static KwArgs defaultKwArgs; /* The default keyword arguments support. */ static int makeProtPublic; /* Treat protected items as public. */ static int parsingCSignature; /* An explicit C/C++ signature is being parsed. */ static const char *getPythonName(moduleDef *mod, optFlags *optflgs, const char *cname); static classDef *findClass(sipSpec *pt, ifaceFileType iftype, apiVersionRangeDef *api_range, scopedNameDef *fqname, int tmpl_arg); static classDef *findClassWithInterface(sipSpec *pt, ifaceFileDef *iff, int tmpl_arg); static classDef *newClass(sipSpec *pt, ifaceFileType iftype, apiVersionRangeDef *api_range, scopedNameDef *snd, const char *virt_error_handler, typeHintDef *typehint_in, typeHintDef *typehint_out, const char *typehint_value); 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, int isscoped); static void instantiateClassTemplate(sipSpec *pt, moduleDef *mod, classDef *scope, scopedNameDef *fqname, classTmplDef *tcd, templateDef *td, const char *pyname, int use_template_name, docstringDef *docstring); static void newTypedef(sipSpec *, moduleDef *, char *, argDef *, optFlags *, docstringDef *); static void newVar(sipSpec *pt, moduleDef *mod, char *name, int isstatic, argDef *type, optFlags *of, codeBlock *acode, codeBlock *gcode, codeBlock *scode, int section); static void newCtor(moduleDef *, char *, int, signatureDef *, optFlags *, codeBlock *, throwArgs *, signatureDef *, int, docstringDef *, codeBlock *); static void newFunction(sipSpec *, moduleDef *, classDef *, ifaceFileDef *, mappedTypeDef *, int, int, int, int, int, char *, signatureDef *, int, int, optFlags *, codeBlock *, codeBlock *, codeBlock *, throwArgs *, signatureDef *, docstringDef *, int, codeBlock *); static optFlag *findOptFlag(optFlags *flgs, const char *name); static optFlag *getOptFlag(optFlags *flgs, const char *name, flagType ft); static memberDef *findFunction(sipSpec *, moduleDef *, classDef *, ifaceFileDef *, mappedTypeDef *, const char *, int, int, int); static void checkAttributes(sipSpec *, moduleDef *, classDef *, mappedTypeDef *, const char *, int); static void newModule(FILE *fp, const char *filename); static moduleDef *allocModule(); static void parseFile(FILE *fp, const char *name, moduleDef *prevmod, int optional); static void handleEOF(void); static void handleEOM(void); static qualDef *findQualifier(const char *name); static const char *getInt(const char *cp, int *ip); 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, int, const char *, qualType); static qualDef *allocQualifier(moduleDef *, int, int, int, const char *, qualType); static void newImport(const char *filename); static int timePeriod(const char *lname, const char *uname); static int platOrFeature(char *name, int optnot); static void addPlatform(qualDef *qd); 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 int getDisallowNone(optFlags *optflgs); static const char *getVirtErrorHandler(optFlags *optflgs); static const char *getDocType(optFlags *optflgs); static const char *getTypeHintValue(optFlags *optflgs); static void getTypeHints(optFlags *optflgs, typeHintDef **in, typeHintDef **out); static int getNoTypeHint(optFlags *optflgs); static void templateSignature(signatureDef *sd, int result, classTmplDef *tcd, templateDef *td, classDef *ncd, scopedNameDef *type_names, scopedNameDef *type_values); static void templateType(argDef *ad, classTmplDef *tcd, templateDef *td, classDef *ncd, scopedNameDef *type_names, scopedNameDef *type_values); 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 void instantiateTemplateTypedefs(sipSpec *pt, classTmplDef *tcd, templateDef *td, classDef *cd, 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 addTypedef(sipSpec *pt, typedefDef *tdd); static void addVariable(sipSpec *pt, varDef *vd); static void applyTypeFlags(moduleDef *mod, argDef *ad, optFlags *flags); static Format convertFormat(const char *format); static Signature convertSignature(const char *signature); 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 KwArgs keywordArgs(moduleDef *mod, optFlags *optflgs, signatureDef *sd, int need_name); static char *strip(char *s); static int isEnabledFeature(const char *name); static void addProperty(sipSpec *pt, moduleDef *mod, classDef *cd, const char *name, const char *get, const char *set, docstringDef *docstring); static moduleDef *configureModule(sipSpec *pt, moduleDef *module, const char *filename, const char *name, int c_module, KwArgs kwargs, int use_arg_names, int use_limited_api, int call_super_init, int all_raise_py_exc, const char *def_error_handler, docstringDef *docstring); static void addAutoPyName(moduleDef *mod, const char *remove_leading); static KwArgs convertKwArgs(const char *kwargs); static void checkAnnos(optFlags *annos, const char *valid[]); static void checkNoAnnos(optFlags *annos, const char *msg); static void appendCodeBlock(codeBlockList **headp, codeBlock *cb); static void handleKeepReference(optFlags *optflgs, argDef *ad, moduleDef *mod); static void mappedTypeAnnos(mappedTypeDef *mtd, optFlags *optflgs); static void add_new_deref(argDef *new, argDef *orig, int isconst); static void add_derefs(argDef *dst, argDef *src); static int isBackstop(qualDef *qd); static void checkEllipsis(signatureDef *sd); static scopedNameDef *fullyQualifiedName(scopedNameDef *snd); %} %union { char qchar; char *text; long number; double real; argDef memArg; signatureDef signature; signatureDef *optsignature; throwArgs *throwlist; codeBlock *codeb; docstringDef *docstr; valueDef value; valueDef *valp; optFlags optflags; optFlag flag; scopedNameDef *scpvalp; fcallDef fcall; int boolean; exceptionDef exceptionbase; classDef *klass; apiCfg api; autoPyNameCfg autopyname; compModuleCfg compmodule; consModuleCfg consmodule; defDocstringFmtCfg defdocstringfmt; defDocstringSigCfg defdocstringsig; defEncodingCfg defencoding; defMetatypeCfg defmetatype; defSupertypeCfg defsupertype; hiddenNsCfg hiddenns; exceptionCfg exception; docstringCfg docstring; extractCfg extract; featureCfg feature; licenseCfg license; importCfg import; includeCfg include; moduleCfg module; pluginCfg plugin; propertyCfg property; variableCfg variable; vehCfg veh; int token; } %token TK_API %token TK_AUTOPYNAME %token TK_DEFDOCSTRFMT %token TK_DEFDOCSTRSIG %token TK_DEFENCODING %token TK_PLUGIN %token TK_VIRTERRORHANDLER %token TK_EXPTYPEHINTCODE %token TK_TYPEHINTCODE %token TK_DOCSTRING %token TK_DOC %token TK_EXPORTEDDOC %token TK_EXTRACT %token TK_MAKEFILE %token TK_ACCESSCODE %token TK_GETCODE %token TK_SETCODE %token TK_PREINITCODE %token TK_INITCODE %token TK_POSTINITCODE %token TK_FINALCODE %token TK_UNITCODE %token TK_UNITPOSTINCLUDECODE %token TK_MODCODE %token TK_TYPECODE %token TK_PREPYCODE %token TK_COPYING %token TK_MAPPEDTYPE %token TK_CODELINE %token TK_IF %token TK_END %token TK_NAME_VALUE %token TK_PATH_VALUE %token TK_STRING_VALUE %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_VIRTUALCALLCODE %token TK_METHODCODE %token TK_PREMETHODCODE %token TK_INSTANCECODE %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_PYBUFFER %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 TK_SIPSSIZET %token TK_NUMBER_VALUE %token TK_REAL_VALUE %token TK_TYPEDEF %token TK_NAMESPACE %token TK_TIMELINE %token TK_PLATFORMS %token TK_FEATURE %token TK_LICENSE %token TK_QCHAR_VALUE %token TK_TRUE_VALUE %token TK_FALSE_VALUE %token TK_NULL_VALUE %token TK_OPERATOR %token TK_THROW %token TK_QOBJECT %token TK_EXCEPTION %token TK_RAISECODE %token TK_VIRTERRORCODE %token TK_EXPLICIT %token TK_TEMPLATE %token TK_FINAL %token TK_ELLIPSIS %token TK_DEFMETATYPE %token TK_DEFSUPERTYPE %token TK_PROPERTY %token TK_HIDE_NS %token TK_FORMAT %token TK_GET %token TK_ID %token TK_KWARGS %token TK_LANGUAGE %token TK_LICENSEE %token TK_NAME %token TK_OPTIONAL %token TK_ORDER %token TK_REMOVELEADING %token TK_SET %token TK_SIGNATURE %token TK_TIMESTAMP %token TK_TYPE %token TK_USEARGNAMES %token TK_USELIMITEDAPI %token TK_ALLRAISEPYEXC %token TK_CALLSUPERINIT %token TK_DEFERRORHANDLER %token TK_VERSION %type argvalue %type argtype %type cpptype %type basetype %type deref %type template %type arglist %type rawarglist %type cpptypelist %type optsig %type optctorsig %type optexceptions %type exceptionlist %type optslot %type optref %type optconst %type optfinal %type optvirtual %type optabstract %type optnumber %type simplevalue %type value %type expr %type optassign %type optaccesscode %type optgetcode %type optsetcode %type typehdrcode %type travcode %type clearcode %type getbufcode %type releasebufcode %type readbufcode %type writebufcode %type segcountcode %type charbufcode %type picklecode %type finalcode %type classtypehintcode %type typecode %type codeblock %type codelines %type virtualcatchercode %type virtualcallcode %type methodcode %type premethodcode %type instancecode %type raisecode %type optdocstring %type docstring %type operatorname %type optfilename %type optname %type dottedname %type name_or_string %type optflags %type flaglist %type flag %type flagvalue %type optunop %type binop %type scopepart %type scopedname %type scopednamehead %type optcast %type exprlist %type qualifiers %type oredqualifiers %type optclassbody %type bool_value %type optenumkey %type baseexception %type class %type class_access %type api_args %type api_arg_list %type api_arg %type autopyname_args %type autopyname_arg_list %type autopyname_arg %type compmodule_args %type compmodule_arg_list %type compmodule_arg %type compmodule_body %type compmodule_body_directives %type compmodule_body_directive %type consmodule_args %type consmodule_arg_list %type consmodule_arg %type consmodule_body %type consmodule_body_directives %type consmodule_body_directive %type defdocstringfmt_args %type defdocstringfmt_arg_list %type defdocstringfmt_arg %type defdocstringsig_args %type defdocstringsig_arg_list %type defdocstringsig_arg %type defencoding_args %type defencoding_arg_list %type defencoding_arg %type defmetatype_args %type defmetatype_arg_list %type defmetatype_arg %type defsupertype_args %type defsupertype_arg_list %type defsupertype_arg %type hiddenns_args %type hiddenns_arg_list %type hiddenns_arg %type exception_body %type exception_body_directives %type exception_body_directive %type docstring_args %type docstring_arg_list %type docstring_arg %type extract_args %type extract_arg_list %type extract_arg %type feature_args %type feature_arg_list %type feature_arg %type import_args %type import_arg_list %type import_arg %type include_args %type include_arg_list %type include_arg %type license_args %type license_arg_list %type license_arg %type module_args %type module_arg_list %type module_arg %type module_body %type module_body_directives %type module_body_directive %type plugin_args %type plugin_arg_list %type plugin_arg %type property_args %type property_arg_list %type property_arg %type property_body %type property_body_directives %type property_body_directive %type variable_body %type variable_body_directives %type variable_body_directive %type veh_args %type veh_arg_list %type veh_arg %% 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 | defdocstringfmt | defdocstringsig | defencoding | defmetatype | defsupertype | hiddenns | exphdrcode | modhdrcode | modcode | preinitcode | initcode | postinitcode | unitcode | unitpostinccode | prepycode | exptypehintcode | modtypehintcode | doc | exporteddoc | extract | makefile | mappedtype | mappedtypetmpl | virterrorhandler | 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); } } ; defdocstringfmt: TK_DEFDOCSTRFMT defdocstringfmt_args { if (notSkipping()) currentModule->defdocstringfmt = convertFormat($2.name); } ; defdocstringfmt_args: TK_STRING_VALUE { resetLexerState(); $$.name = $1; } | '(' defdocstringfmt_arg_list ')' { $$ = $2; } ; defdocstringfmt_arg_list: defdocstringfmt_arg | defdocstringfmt_arg_list ',' defdocstringfmt_arg { $$ = $1; switch ($3.token) { case TK_NAME: $$.name = $3.name; break; } } ; defdocstringfmt_arg: TK_NAME '=' TK_STRING_VALUE { $$.token = TK_NAME; $$.name = $3; } ; defdocstringsig: TK_DEFDOCSTRSIG defdocstringsig_args { if (notSkipping()) currentModule->defdocstringsig = convertSignature($2.name); } ; defdocstringsig_args: TK_STRING_VALUE { resetLexerState(); $$.name = $1; } | '(' defdocstringsig_arg_list ')' { $$ = $2; } ; defdocstringsig_arg_list: defdocstringsig_arg | defdocstringsig_arg_list ',' defdocstringsig_arg { $$ = $1; switch ($3.token) { case TK_NAME: $$.name = $3.name; break; } } ; defdocstringsig_arg: TK_NAME '=' TK_STRING_VALUE { $$.token = TK_NAME; $$.name = $3; } ; defencoding: TK_DEFENCODING defencoding_args { if (notSkipping()) { if ((currentModule->encoding = convertEncoding($2.name)) == no_type) yyerror("The %DefaultEncoding name must be one of \"ASCII\", \"Latin-1\", \"UTF-8\" or \"None\""); } } ; defencoding_args: TK_STRING_VALUE { resetLexerState(); $$.name = $1; } | '(' defencoding_arg_list ')' { $$ = $2; } ; defencoding_arg_list: defencoding_arg | defencoding_arg_list ',' defencoding_arg { $$ = $1; switch ($3.token) { case TK_NAME: $$.name = $3.name; break; } } ; defencoding_arg: TK_NAME '=' TK_STRING_VALUE { $$.token = TK_NAME; $$.name = $3; } ; plugin: TK_PLUGIN plugin_args { /* * Note that %Plugin is internal in SIP v4. The current thinking * is that it won't be needed for SIP v5. */ if (notSkipping()) appendString(¤tSpec->plugins, $2.name); } ; plugin_args: TK_NAME_VALUE { resetLexerState(); $$.name = $1; } | '(' plugin_arg_list ')' { $$ = $2; } ; plugin_arg_list: plugin_arg | plugin_arg_list ',' plugin_arg { $$ = $1; switch ($3.token) { case TK_NAME: $$.name = $3.name; break; } } ; plugin_arg: TK_NAME '=' TK_NAME_VALUE { $$.token = TK_NAME; $$.name = $3; } ; virterrorhandler: TK_VIRTERRORHANDLER veh_args codeblock { if ($2.name == NULL) yyerror("%VirtualErrorHandler must have a 'name' argument"); if (notSkipping()) { virtErrorHandler *veh, **tailp; /* Check there isn't already a handler with the same name. */ for (tailp = ¤tSpec->errorhandlers; (veh = *tailp) != NULL; tailp = &veh->next) if (strcmp(veh->name, $2.name) == 0) break; if (veh != NULL) yyerror("A virtual error handler with that name has already been defined"); veh = sipMalloc(sizeof (virtErrorHandler)); veh->name = $2.name; appendCodeBlock(&veh->code, $3); veh->mod = currentModule; veh->index = -1; veh->next = NULL; *tailp = veh; } } ; veh_args: TK_NAME_VALUE { resetLexerState(); $$.name = $1; } | '(' veh_arg_list ')' { $$ = $2; } ; veh_arg_list: veh_arg | veh_arg_list ',' veh_arg { $$ = $1; switch ($3.token) { case TK_NAME: $$.name = $3.name; break; } } ; veh_arg: TK_NAME '=' TK_NAME_VALUE { $$.token = TK_NAME; $$.name = $3; } ; api: TK_API api_args { if (notSkipping()) { apiVersionRangeDef *avd; if (findAPI(currentSpec, $2.name) != NULL) yyerror("The API name in the %API directive has already been defined"); if ($2.version < 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.name); avd->from = $2.version; avd->to = -1; avd->next = currentModule->api_versions; currentModule->api_versions = avd; if (inMainModule()) setIsUsedName(avd->api_name); } } ; api_args: TK_NAME_VALUE TK_NUMBER_VALUE { resetLexerState(); deprecated("%API name and version number should be specified using the 'name' and 'version' arguments"); $$.name = $1; $$.version = $2; } | '(' api_arg_list ')' { $$ = $2; } ; api_arg_list: api_arg | api_arg_list ',' api_arg { $$ = $1; switch ($3.token) { case TK_NAME: $$.name = $3.name; break; case TK_VERSION: $$.version = $3.version; break; } } ; api_arg: TK_NAME '=' name_or_string { $$.token = TK_NAME; $$.name = $3; $$.version = 0; } | TK_VERSION '=' TK_NUMBER_VALUE { $$.token = TK_VERSION; $$.name = NULL; $$.version = $3; } ; exception: TK_EXCEPTION scopedname baseexception optflags exception_body { if (notSkipping()) { static const char *annos[] = { "Default", "PyName", NULL }; exceptionDef *xd; const char *pyname; checkAnnos(&$4, annos); if (currentSpec->genc) yyerror("%Exception not allowed in a C module"); if ($5.raise_code == NULL) yyerror("%Exception must have a %RaiseCode sub-directive"); pyname = getPythonName(currentModule, &$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; appendCodeBlock(&xd->iff->hdrcode, $5.type_header_code); xd->pyname = pyname; xd->bibase = $3.bibase; xd->base = $3.base; appendCodeBlock(&xd->raisecode, $5.raise_code); if (getOptFlag(&$4, "Default", bool_flag) != NULL) currentModule->defexception = xd; } } ; 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[] = { "BaseException", "Exception", "StopIteration", "GeneratorExit", "ArithmeticError", "LookupError", "StandardError", /* Python v2. */ "AssertionError", "AttributeError", "BufferError", "EOFError", "FloatingPointError", "OSError", "ImportError", "IndexError", "KeyError", "KeyboardInterrupt", "MemoryError", "NameError", "OverflowError", "RuntimeError", "NotImplementedError", "SyntaxError", "IndentationError", "TabError", "ReferenceError", "SystemError", "SystemExit", "TypeError", "UnboundLocalError", "UnicodeError", "UnicodeEncodeError", "UnicodeDecodeError", "UnicodeTranslateError", "ValueError", "ZeroDivisionError", "EnvironmentError", /* Python v2. */ "IOError", /* Python v2. */ "WindowsError", /* Python v2. */ "VMSError", /* Python v2. */ "BlockingIOError", "BrokenPipeError", "ChildProcessError", "ConnectionError", "ConnectionAbortedError", "ConnectionRefusedError", "ConnectionResetError", "FileExistsError", "FileNotFoundError", "InterruptedError", "IsADirectoryError", "NotADirectoryError", "PermissionError", "ProcessLookupError", "TimeoutError", "Warning", "UserWarning", "DeprecationWarning", "PendingDeprecationWarning", "SyntaxWarning", "RuntimeWarning", "FutureWarning", "ImportWarning", "UnicodeWarning", "BytesWarning", "ResourceWarning", 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"); } ; exception_body: '{' exception_body_directives '}' ';' { $$ = $2; } ; exception_body_directives: exception_body_directive | exception_body_directives exception_body_directive { $$ = $1; switch ($2.token) { case TK_RAISECODE: $$.raise_code = $2.raise_code; break; case TK_TYPEHEADERCODE: $$.type_header_code = $2.type_header_code; break; } } ; exception_body_directive: ifstart { $$.token = TK_IF; } | ifend { $$.token = TK_END; } | raisecode { if (notSkipping()) { $$.token = TK_RAISECODE; $$.raise_code = $1; } else { $$.token = 0; $$.raise_code = NULL; } $$.type_header_code = NULL; } | typehdrcode { if (notSkipping()) { $$.token = TK_TYPEHEADERCODE; $$.type_header_code = $1; } else { $$.token = 0; $$.type_header_code = NULL; } $$.raise_code = NULL; } ; raisecode: TK_RAISECODE codeblock { $$ = $2; } ; mappedtype: TK_MAPPEDTYPE basetype optflags { if (notSkipping()) { static const char *annos[] = { "AllowNone", "API", "DocType", "NoRelease", "PyName", "TypeHint", "TypeHintIn", "TypeHintOut", "TypeHintValue", NULL }; checkAnnos(&$3, annos); currentMappedType = newMappedType(currentSpec, &$2, &$3); } } mtdefinition ; mappedtypetmpl: template TK_MAPPEDTYPE basetype optflags { if (notSkipping()) { static const char *annos[] = { "AllowNone", "DocType", "NoRelease", "TypeHint", "TypeHintIn", "TypeHintOut", "TypeHintValue", NULL }; int a; mappedTypeTmplDef *mtt; ifaceFileDef *iff; checkAnnos(&$4, annos); 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"); $3.u.td->fqname = fullyQualifiedName($3.u.td->fqname); /* 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); mappedTypeAnnos(mtt->mt, &$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: ifstart | ifend | typehdrcode { if (notSkipping()) appendCodeBlock(¤tMappedType->iff->hdrcode, $1); } | typecode { if (notSkipping()) appendCodeBlock(¤tMappedType->typecode, $1); } | TK_FROMTYPE codeblock { if (notSkipping()) { if (currentMappedType->convfromcode != NULL) yyerror("%MappedType has more than one %ConvertFromTypeCode directive"); appendCodeBlock(¤tMappedType->convfromcode, $2); } } | TK_TOTYPE codeblock { if (notSkipping()) { if (currentMappedType->convtocode != NULL) yyerror("%MappedType has more than one %ConvertToTypeCode directive"); appendCodeBlock(¤tMappedType->convtocode, $2); } } | instancecode { if (notSkipping()) { if (currentMappedType->instancecode != NULL) yyerror("%MappedType has more than one %InstanceCode directive"); appendCodeBlock(¤tMappedType->instancecode, $1); } } | enum | mtfunction ; mtfunction: TK_STATIC cpptype TK_NAME_VALUE '(' arglist ')' optconst optexceptions optflags optsig ';' optdocstring premethodcode methodcode { if (notSkipping()) { applyTypeFlags(currentModule, &$2, &$9); $5.result = $2; newFunction(currentSpec, currentModule, NULL, NULL, currentMappedType, 0, TRUE, FALSE, FALSE, FALSE, $3, &$5, $7, FALSE, &$9, $14, NULL, NULL, $8, $10, $12, FALSE, $13); } } ; namespace: TK_NAMESPACE TK_NAME_VALUE { 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), NULL, NULL, NULL, NULL); pushScope(ns); sectionFlags = 0; } } optnsbody ';' { if (notSkipping()) { if (inMainModule()) { classDef *ns = currentScope(); setIsUsedName(ns->iff->name); setIsUsedName(ns->pyname); } popScope(); } } ; optnsbody: | '{' nsbody '}' ; nsbody: nsstatement | nsbody nsstatement ; platforms: TK_PLATFORMS { if (notSkipping()) { 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 '}' { if (notSkipping()) { 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 && selectedQualifier(neededQualifiers, 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_VALUE { newQualifier(currentModule, -1, -1, notSkipping(), $1, platform_qualifier); } ; feature: TK_FEATURE feature_args { newQualifier(currentModule, -1, -1, notSkipping(), $2.name, feature_qualifier); } ; feature_args: TK_NAME_VALUE { resetLexerState(); $$.name = $1; } | '(' feature_arg_list ')' { $$ = $2; } ; feature_arg_list: feature_arg | feature_arg_list ',' feature_arg { $$ = $1; switch ($3.token) { case TK_NAME: $$.name = $3.name; break; } } ; feature_arg: TK_NAME '=' name_or_string { $$.token = TK_NAME; $$.name = $3; } ; timeline: TK_TIMELINE { currentTimelineOrder = 0; } '{' qualifierlist '}' { if (notSkipping()) { 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 && selectedQualifier(neededQualifiers, 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_VALUE { newQualifier(currentModule, currentModule->nrtimelines, currentTimelineOrder++, TRUE, $1, time_qualifier); } ; ifstart: TK_IF '(' { currentPlatforms = NULL; } qualifiers ')' { if (stackPtr >= MAX_NESTED_IF) yyerror("Internal error: increase the value of MAX_NESTED_IF"); /* Nested %Ifs are implicit logical ands. */ if (stackPtr > 0) $4 = ($4 && skipStack[stackPtr - 1]); skipStack[stackPtr] = $4; platformStack[stackPtr] = currentPlatforms; ++stackPtr; } ; oredqualifiers: TK_NAME_VALUE { $$ = platOrFeature($1, FALSE); } | '!' TK_NAME_VALUE { $$ = platOrFeature($2, TRUE); } | oredqualifiers TK_LOGICAL_OR TK_NAME_VALUE { $$ = (platOrFeature($3, FALSE) || $1); } | oredqualifiers TK_LOGICAL_OR '!' TK_NAME_VALUE { $$ = (platOrFeature($4, TRUE) || $1); } ; qualifiers: oredqualifiers | optname '-' optname { $$ = timePeriod($1, $3); } ; ifend: TK_END { if (stackPtr-- <= 0) yyerror("Too many %End directives"); currentPlatforms = (stackPtr == 0 ? NULL : platformStack[stackPtr - 1]); } ; license: TK_LICENSE license_args optflags { optFlag *of; if ($3.nrFlags != 0) deprecated("%License annotations are deprecated, use arguments instead"); if ($2.type == NULL) if ((of = getOptFlag(&$3, "Type", string_flag)) != NULL) $2.type = of->fvalue.sval; if ($2.licensee == NULL) if ((of = getOptFlag(&$3, "Licensee", string_flag)) != NULL) $2.licensee = of->fvalue.sval; if ($2.signature == NULL) if ((of = getOptFlag(&$3, "Signature", string_flag)) != NULL) $2.signature = of->fvalue.sval; if ($2.timestamp == NULL) if ((of = getOptFlag(&$3, "Timestamp", string_flag)) != NULL) $2.timestamp = of->fvalue.sval; if ($2.type == NULL) yyerror("%License must have a 'type' argument"); if (notSkipping()) { currentModule->license = sipMalloc(sizeof (licenseDef)); currentModule->license->type = $2.type; currentModule->license->licensee = $2.licensee; currentModule->license->sig = $2.signature; currentModule->license->timestamp = $2.timestamp; } } ; license_args: { resetLexerState(); $$.type = NULL; $$.licensee = NULL; $$.signature = NULL; $$.timestamp = NULL; } | TK_STRING_VALUE { $$.type = $1; $$.licensee = NULL; $$.signature = NULL; $$.timestamp = NULL; } | '(' license_arg_list ')' { $$ = $2; } ; license_arg_list: license_arg | license_arg_list ',' license_arg { $$ = $1; switch ($3.token) { case TK_TYPE: $$.type = $3.type; break; case TK_LICENSEE: $$.licensee = $3.licensee; break; case TK_SIGNATURE: $$.signature = $3.signature; break; case TK_TIMESTAMP: $$.timestamp = $3.timestamp; break; } } ; license_arg: TK_TYPE '=' TK_STRING_VALUE { $$.token = TK_NAME; $$.type = $3; $$.licensee = NULL; $$.signature = NULL; $$.timestamp = NULL; } | TK_LICENSEE '=' TK_STRING_VALUE { $$.token = TK_LICENSEE; $$.type = NULL; $$.licensee = $3; $$.signature = NULL; $$.timestamp = NULL; } | TK_SIGNATURE '=' TK_STRING_VALUE { $$.token = TK_SIGNATURE; $$.type = NULL; $$.licensee = NULL; $$.signature = $3; $$.timestamp = NULL; } | TK_TIMESTAMP '=' TK_STRING_VALUE { $$.token = TK_TIMESTAMP; $$.type = NULL; $$.licensee = NULL; $$.signature = NULL; $$.timestamp = $3; } ; defmetatype: TK_DEFMETATYPE defmetatype_args { if (notSkipping()) { if (currentModule->defmetatype != NULL) yyerror("%DefaultMetatype has already been defined for this module"); currentModule->defmetatype = cacheName(currentSpec, $2.name); } } ; defmetatype_args: dottedname { resetLexerState(); $$.name = $1; } | '(' defmetatype_arg_list ')' { $$ = $2; } ; defmetatype_arg_list: defmetatype_arg | defmetatype_arg_list ',' defmetatype_arg { $$ = $1; switch ($3.token) { case TK_NAME: $$.name = $3.name; break; } } ; defmetatype_arg: TK_NAME '=' dottedname { $$.token = TK_NAME; $$.name = $3; } ; defsupertype: TK_DEFSUPERTYPE defsupertype_args { if (notSkipping()) { if (currentModule->defsupertype != NULL) yyerror("%DefaultSupertype has already been defined for this module"); currentModule->defsupertype = cacheName(currentSpec, $2.name); } } ; defsupertype_args: dottedname { resetLexerState(); $$.name = $1; } | '(' defsupertype_arg_list ')' { $$ = $2; } ; defsupertype_arg_list: defsupertype_arg | defsupertype_arg_list ',' defsupertype_arg { $$ = $1; switch ($3.token) { case TK_NAME: $$.name = $3.name; break; } } ; defsupertype_arg: TK_NAME '=' dottedname { $$.token = TK_NAME; $$.name = $3; } ; hiddenns: TK_HIDE_NS hiddenns_args { if (notSkipping()) { classDef *ns; ns = newClass(currentSpec, namespace_iface, NULL, fullyQualifiedName($2.name), NULL, NULL, NULL, NULL); setHiddenNamespace(ns); } } ; hiddenns_args: scopedname { resetLexerState(); $$.name = $1; } | '(' hiddenns_arg_list ')' { $$ = $2; } ; hiddenns_arg_list: hiddenns_arg | hiddenns_arg_list ',' hiddenns_arg { $$ = $1; switch ($3.token) { case TK_NAME: $$.name = $3.name; break; } } ; hiddenns_arg: TK_NAME '=' scopedname { $$.token = TK_NAME; $$.name = $3; } ; consmodule: TK_CONSMODULE consmodule_args consmodule_body { deprecated("%ConsolidatedModule is deprecated and will not be supported by SIP v5"); if (notSkipping()) { /* 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.name); currentModule->docstring = $3.docstring; setIsConsolidated(currentModule); } } ; consmodule_args: dottedname { resetLexerState(); $$.name = $1; } | '(' consmodule_arg_list ')' { $$ = $2; } ; consmodule_arg_list: consmodule_arg | consmodule_arg_list ',' consmodule_arg { $$ = $1; switch ($3.token) { case TK_NAME: $$.name = $3.name; break; } } ; consmodule_arg: TK_NAME '=' dottedname { $$.token = TK_NAME; $$.name = $3; } ; consmodule_body: { $$.token = 0; $$.docstring = NULL; } | '{' consmodule_body_directives '}' ';' { $$ = $2; } ; consmodule_body_directives: consmodule_body_directive | consmodule_body_directives consmodule_body_directive { $$ = $1; switch ($2.token) { case TK_DOCSTRING: $$.docstring = $2.docstring; break; } } ; consmodule_body_directive: ifstart { $$.token = TK_IF; } | ifend { $$.token = TK_END; } | docstring { if (notSkipping()) { $$.token = TK_DOCSTRING; $$.docstring = $1; } else { $$.token = 0; $$.docstring = NULL; } } ; compmodule: TK_COMPOMODULE compmodule_args compmodule_body { if (notSkipping()) { /* 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 directive"); setModuleName(currentSpec, currentModule, $2.name); currentModule->docstring = $3.docstring; setIsComposite(currentModule); } } ; compmodule_args: dottedname { resetLexerState(); $$.name = $1; } | '(' compmodule_arg_list ')' { $$ = $2; } ; compmodule_arg_list: compmodule_arg | compmodule_arg_list ',' compmodule_arg { $$ = $1; switch ($3.token) { case TK_NAME: $$.name = $3.name; break; } } ; compmodule_arg: TK_NAME '=' dottedname { $$.token = TK_NAME; $$.name = $3; } ; compmodule_body: { $$.token = 0; $$.docstring = NULL; } | '{' compmodule_body_directives '}' ';' { $$ = $2; } ; compmodule_body_directives: compmodule_body_directive | compmodule_body_directives compmodule_body_directive { $$ = $1; switch ($2.token) { case TK_DOCSTRING: $$.docstring = $2.docstring; break; } } ; compmodule_body_directive: ifstart { $$.token = TK_IF; } | ifend { $$.token = TK_END; } | docstring { if (notSkipping()) { $$.token = TK_DOCSTRING; $$.docstring = $1; } else { $$.token = 0; $$.docstring = NULL; } } ; module: TK_MODULE module_args module_body { if ($2.name == NULL) yyerror("%Module must have a 'name' argument"); if (notSkipping()) currentModule = configureModule(currentSpec, currentModule, currentContext.filename, $2.name, $2.c_module, $2.kwargs, $2.use_arg_names, $2.use_limited_api, $2.call_super_init, $2.all_raise_py_exc, $2.def_error_handler, $3.docstring); } | TK_CMODULE dottedname optnumber { deprecated("%CModule is deprecated, use %Module and the 'language' argument instead"); if (notSkipping()) currentModule = configureModule(currentSpec, currentModule, currentContext.filename, $2, TRUE, defaultKwArgs, FALSE, FALSE, -1, FALSE, NULL, NULL); } ; module_args: dottedname {resetLexerState();} optnumber { if ($3 >= 0) deprecated("%Module version number should be specified using the 'version' argument"); $$.c_module = FALSE; $$.kwargs = defaultKwArgs; $$.name = $1; $$.use_arg_names = FALSE; $$.use_limited_api = FALSE; $$.all_raise_py_exc = FALSE; $$.call_super_init = -1; $$.def_error_handler = NULL; } | '(' module_arg_list ')' { $$ = $2; } ; module_arg_list: module_arg | module_arg_list ',' module_arg { $$ = $1; switch ($3.token) { case TK_KWARGS: $$.kwargs = $3.kwargs; break; case TK_LANGUAGE: $$.c_module = $3.c_module; break; case TK_NAME: $$.name = $3.name; break; case TK_USEARGNAMES: $$.use_arg_names = $3.use_arg_names; break; case TK_USELIMITEDAPI: $$.use_limited_api = $3.use_limited_api; break; case TK_ALLRAISEPYEXC: $$.all_raise_py_exc = $3.all_raise_py_exc; break; case TK_CALLSUPERINIT: $$.call_super_init = $3.call_super_init; break; case TK_DEFERRORHANDLER: $$.def_error_handler = $3.def_error_handler; break; } } ; module_arg: TK_KWARGS '=' TK_STRING_VALUE { $$.token = TK_KWARGS; $$.c_module = FALSE; $$.kwargs = convertKwArgs($3); $$.name = NULL; $$.use_arg_names = FALSE; $$.use_limited_api = FALSE; $$.all_raise_py_exc = FALSE; $$.call_super_init = -1; $$.def_error_handler = NULL; } | TK_LANGUAGE '=' TK_STRING_VALUE { $$.token = TK_LANGUAGE; if (strcmp($3, "C++") == 0) $$.c_module = FALSE; else if (strcmp($3, "C") == 0) $$.c_module = TRUE; else yyerror("%Module 'language' argument must be either \"C++\" or \"C\""); $$.kwargs = defaultKwArgs; $$.name = NULL; $$.use_arg_names = FALSE; $$.use_limited_api = FALSE; $$.all_raise_py_exc = FALSE; $$.call_super_init = -1; $$.def_error_handler = NULL; } | TK_NAME '=' dottedname { $$.token = TK_NAME; $$.c_module = FALSE; $$.kwargs = defaultKwArgs; $$.name = $3; $$.use_arg_names = FALSE; $$.use_limited_api = FALSE; $$.all_raise_py_exc = FALSE; $$.call_super_init = -1; $$.def_error_handler = NULL; } | TK_USEARGNAMES '=' bool_value { $$.token = TK_USEARGNAMES; $$.c_module = FALSE; $$.kwargs = defaultKwArgs; $$.name = NULL; $$.use_arg_names = $3; $$.use_limited_api = FALSE; $$.all_raise_py_exc = FALSE; $$.call_super_init = -1; $$.def_error_handler = NULL; } | TK_USELIMITEDAPI '=' bool_value { $$.token = TK_USELIMITEDAPI; $$.c_module = FALSE; $$.kwargs = defaultKwArgs; $$.name = NULL; $$.use_arg_names = FALSE; $$.use_limited_api = $3; $$.all_raise_py_exc = FALSE; $$.call_super_init = -1; $$.def_error_handler = NULL; } | TK_ALLRAISEPYEXC '=' bool_value { $$.token = TK_ALLRAISEPYEXC; $$.c_module = FALSE; $$.kwargs = defaultKwArgs; $$.name = NULL; $$.use_arg_names = FALSE; $$.use_limited_api = FALSE; $$.all_raise_py_exc = $3; $$.call_super_init = -1; $$.def_error_handler = NULL; } | TK_CALLSUPERINIT '=' bool_value { $$.token = TK_CALLSUPERINIT; $$.c_module = FALSE; $$.kwargs = defaultKwArgs; $$.name = NULL; $$.use_arg_names = FALSE; $$.use_limited_api = FALSE; $$.all_raise_py_exc = FALSE; $$.call_super_init = $3; $$.def_error_handler = NULL; } | TK_DEFERRORHANDLER '=' TK_NAME_VALUE { $$.token = TK_DEFERRORHANDLER; $$.c_module = FALSE; $$.kwargs = defaultKwArgs; $$.name = NULL; $$.use_arg_names = FALSE; $$.use_limited_api = FALSE; $$.all_raise_py_exc = FALSE; $$.call_super_init = -1; $$.def_error_handler = $3; } | TK_VERSION '=' TK_NUMBER_VALUE { deprecated("%Module version numbers are deprecated and ignored"); if ($3 < 0) yyerror("%Module 'version' argument cannot be negative"); $$.token = TK_VERSION; $$.c_module = FALSE; $$.kwargs = defaultKwArgs; $$.name = NULL; $$.use_arg_names = FALSE; $$.use_limited_api = FALSE; $$.all_raise_py_exc = FALSE; $$.call_super_init = -1; $$.def_error_handler = NULL; } ; module_body: { $$.token = 0; $$.docstring = NULL; } | '{' module_body_directives '}' ';' { $$ = $2; } ; module_body_directives: module_body_directive | module_body_directives module_body_directive { $$ = $1; switch ($2.token) { case TK_DOCSTRING: $$.docstring = $2.docstring; break; } } ; module_body_directive: ifstart { $$.token = TK_IF; } | ifend { $$.token = TK_END; } | autopyname { $$.token = TK_AUTOPYNAME; } | docstring { if (notSkipping()) { $$.token = TK_DOCSTRING; $$.docstring = $1; } else { $$.token = 0; $$.docstring = NULL; } } ; dottedname: TK_NAME_VALUE | TK_PATH_VALUE { /* * 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_VALUE ; include: TK_INCLUDE include_args { if ($2.name == NULL) yyerror("%Include must have a 'name' argument"); if (notSkipping()) parseFile(NULL, $2.name, NULL, $2.optional); } ; include_args: TK_PATH_VALUE { resetLexerState(); $$.name = $1; $$.optional = FALSE; } | '(' include_arg_list ')' { $$ = $2; } ; include_arg_list: include_arg | include_arg_list ',' include_arg { $$ = $1; switch ($3.token) { case TK_NAME: $$.name = $3.name; break; case TK_OPTIONAL: $$.optional = $3.optional; break; } } ; include_arg: TK_NAME '=' TK_PATH_VALUE { $$.token = TK_NAME; $$.name = $3; $$.optional = FALSE; } | TK_OPTIONAL '=' bool_value { $$.token = TK_OPTIONAL; $$.name = NULL; $$.optional = $3; } ; optinclude: TK_OPTINCLUDE TK_PATH_VALUE { deprecated("%OptionalInclude is deprecated, use %Include and the 'optional' argument instead"); if (notSkipping()) parseFile(NULL, $2, NULL, TRUE); } ; import: TK_IMPORT import_args { if (notSkipping()) newImport($2.name); } ; import_args: TK_PATH_VALUE { resetLexerState(); $$.name = $1; } | '(' import_arg_list ')' { $$ = $2; } ; import_arg_list: import_arg | import_arg_list ',' import_arg { $$ = $1; switch ($3.token) { case TK_NAME: $$.name = $3.name; break; } } ; import_arg: TK_NAME '=' TK_PATH_VALUE { $$.token = TK_NAME; $$.name = $3; } ; optaccesscode: { $$ = NULL; } | TK_ACCESSCODE codeblock { $$ = $2; } ; optgetcode: { $$ = NULL; } | TK_GETCODE codeblock { $$ = $2; } ; optsetcode: { $$ = NULL; } | TK_SETCODE codeblock { $$ = $2; } ; copying: TK_COPYING codeblock { if (notSkipping()) appendCodeBlock(¤tModule->copying, $2); } ; exphdrcode: TK_EXPHEADERCODE codeblock { if (notSkipping()) appendCodeBlock(¤tSpec->exphdrcode, $2); } ; modhdrcode: TK_MODHEADERCODE codeblock { if (notSkipping()) appendCodeBlock(¤tModule->hdrcode, $2); } ; typehdrcode: TK_TYPEHEADERCODE codeblock { $$ = $2; } ; 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; } ; instancecode: TK_INSTANCECODE codeblock { $$ = $2; } ; picklecode: TK_PICKLECODE codeblock { $$ = $2; } ; finalcode: TK_FINALCODE codeblock { $$ = $2; } ; modcode: TK_MODCODE codeblock { if (notSkipping()) appendCodeBlock(¤tModule->cppcode, $2); } ; typecode: TK_TYPECODE codeblock { $$ = $2; } ; preinitcode: TK_PREINITCODE codeblock { if (notSkipping()) appendCodeBlock(¤tModule->preinitcode, $2); } ; initcode: TK_INITCODE codeblock { if (notSkipping()) appendCodeBlock(¤tModule->initcode, $2); } ; postinitcode: TK_POSTINITCODE codeblock { if (notSkipping()) appendCodeBlock(¤tModule->postinitcode, $2); } ; unitcode: TK_UNITCODE codeblock { if (notSkipping()) appendCodeBlock(¤tModule->unitcode, $2); } ; unitpostinccode: TK_UNITPOSTINCLUDECODE codeblock { if (notSkipping()) appendCodeBlock(¤tModule->unitpostinccode, $2); } ; prepycode: TK_PREPYCODE codeblock { /* Deprecated. */ } ; exptypehintcode: TK_EXPTYPEHINTCODE codeblock { if (notSkipping() && !inMainModule()) appendCodeBlock(¤tSpec->exptypehintcode, $2); } ; modtypehintcode: TK_TYPEHINTCODE codeblock { if (notSkipping()) appendCodeBlock(¤tModule->typehintcode, $2); } ; classtypehintcode: TK_TYPEHINTCODE codeblock { $$ = $2; } ; doc: TK_DOC codeblock { if (notSkipping() && inMainModule()) appendCodeBlock(¤tSpec->docs, $2); } ; exporteddoc: TK_EXPORTEDDOC codeblock { if (notSkipping()) appendCodeBlock(¤tSpec->docs, $2); } ; autopyname: TK_AUTOPYNAME autopyname_args { if (notSkipping()) addAutoPyName(currentModule, $2.remove_leading); } ; autopyname_args: '(' autopyname_arg_list ')' { $$ = $2; } ; autopyname_arg_list: autopyname_arg | autopyname_arg_list ',' autopyname_arg { $$ = $1; switch ($3.token) { case TK_REMOVELEADING: $$.remove_leading = $3.remove_leading; break; } } ; autopyname_arg: TK_REMOVELEADING '=' TK_STRING_VALUE { $$.token = TK_REMOVELEADING; $$.remove_leading = $3; } ; docstring: TK_DOCSTRING docstring_args codeblock { $$ = sipMalloc(sizeof(docstringDef)); $$->signature = $2.signature; $$->text = $3->frag; free($3); /* Format the docstring. */ if ($2.format == deindented) { const char *cp; char *dp; int min_indent, indent, skipping; /* Find the common indent. */ min_indent = -1; indent = 0; skipping = FALSE; for (cp = $$->text; *cp != '\0'; ++cp) { if (skipping) { /* * We have handled the indent and are just looking for * the end of the line. */ if (*cp == '\n') skipping = FALSE; } else { if (*cp == ' ') { ++indent; } else if (*cp != '\n') { if (min_indent < 0 || min_indent > indent) min_indent = indent; /* Ignore the remaining characters of the line. */ skipping = TRUE; } } } /* In case the last line doesn't have a trailing newline. */ if (min_indent < 0 || min_indent > indent) min_indent = indent; /* * Go through the text again removing the common indentation. */ cp = dp = $$->text; while (*cp != '\0') { const char *start = cp; int non_blank = FALSE; /* Find the end of the line. */ while (*cp != '\n' && *cp != '\0') if (*cp++ != ' ') non_blank = TRUE; /* Find where we are copying from. */ if (non_blank) { start += min_indent; while (*start != '\n' && *start != '\0') *dp++ = *start++; } if (*cp == '\n') *dp++ = *cp++; } *dp = '\0'; } } ; docstring_args: { $$.format = currentModule->defdocstringfmt; $$.signature = currentModule->defdocstringsig; } | TK_STRING_VALUE { resetLexerState(); $$.format = convertFormat($1); $$.signature = currentModule->defdocstringsig; } | '(' docstring_arg_list ')' { $$ = $2; } ; docstring_arg_list: docstring_arg | docstring_arg_list ',' docstring_arg { $$ = $1; switch ($3.token) { case TK_FORMAT: $$.format = $3.format; break; case TK_SIGNATURE: $$.signature = $3.signature; break; } } ; docstring_arg: TK_FORMAT '=' TK_STRING_VALUE { $$.token = TK_FORMAT; $$.format = convertFormat($3); $$.signature = currentModule->defdocstringsig; } | TK_SIGNATURE '=' TK_STRING_VALUE { $$.token = TK_SIGNATURE; $$.format = currentModule->defdocstringfmt; $$.signature = convertSignature($3); } ; optdocstring: { $$ = NULL; } | docstring ; extract: TK_EXTRACT extract_args codeblock { if ($2.id == NULL) yyerror("%Extract must have an 'id' argument"); if (notSkipping()) addExtractPart(currentSpec, $2.id, $2.order, $3); } ; extract_args: TK_NAME_VALUE { resetLexerState(); $$.id = $1; $$.order = -1; } | '(' extract_arg_list ')' { $$ = $2; } ; extract_arg_list: extract_arg | extract_arg_list ',' extract_arg { $$ = $1; switch ($3.token) { case TK_ID: $$.id = $3.id; break; case TK_ORDER: $$.order = $3.order; break; } } ; extract_arg: TK_ID '=' TK_NAME_VALUE { $$.token = TK_ID; $$.id = $3; $$.order = -1; } | TK_ORDER '=' TK_NUMBER_VALUE { $$.token = TK_ORDER; if ($3 < 0) yyerror("The 'order' of an %Extract directive must not be negative"); $$.id = NULL; $$.order = $3; } ; makefile: TK_MAKEFILE TK_PATH_VALUE optfilename codeblock { /* Deprecated. */ } ; codeblock: codelines TK_END ; codelines: TK_CODELINE | codelines TK_CODELINE { $$ = $1; append(&$$->frag, $2->frag); free($2->frag); free($2); } ; enum: TK_ENUM optenumkey optname optflags { if (notSkipping()) { const char *annos[] = { "NoScope", "NoTypeHint", "PyName", NULL }; checkAnnos(&$4, annos); if (sectionFlags != 0 && (sectionFlags & ~(SECT_IS_PUBLIC | SECT_IS_PROT)) != 0) yyerror("Class enums must be in the public or protected sections"); if (currentSpec->genc && $2) yyerror("Scoped enums not allowed in a C module"); currentEnum = newEnum(currentSpec, currentModule, currentMappedType, $3, &$4, sectionFlags, $2); } } '{' optenumbody '}' ';' ; optenumkey: { $$ = FALSE; } | TK_CLASS { $$ = TRUE; } | TK_STRUCT { $$ = TRUE; } ; optfilename: { $$ = NULL; } | TK_PATH_VALUE { $$ = $1; } ; optname: { $$ = NULL; } | TK_NAME_VALUE { $$ = $1; } ; optenumbody: | enumbody ; enumbody: enumline | enumbody enumline ; enumline: ifstart | ifend | TK_NAME_VALUE optenumassign optflags optcomma { if (notSkipping()) { const char *annos[] = { "NoTypeHint", "PyName", NULL }; enumMemberDef *emd, **tail; checkAnnos(&$3, annos); /* Note that we don't use the assigned value. */ emd = sipMalloc(sizeof (enumMemberDef)); emd->pyname = cacheName(currentSpec, getPythonName(currentModule, &$3, $1)); emd->cname = $1; emd->no_typehint = getNoTypeHint(&$3); emd->ed = currentEnum; emd->platforms = currentPlatforms; emd->next = NULL; checkAttributes(currentSpec, currentModule, emd->ed->ecd, emd->ed->emtd, emd->pyname->text, FALSE); /* Append to preserve the order. */ for (tail = ¤tEnum->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: optcast optunop simplevalue { if ($2 != '\0' && $3.vtype == string_value) yyerror("Invalid unary operator for string"); /* Convert the value to a simple expression on the heap. */ $$ = sipMalloc(sizeof (valueDef)); *$$ = $3; $$->vunop = $2; $$->vbinop = '\0'; $$->cast = $1; $$->next = NULL; } ; optcast: { $$ = NULL; } | '(' scopedname ')' { $$ = $2; } ; scopedname: TK_SCOPE scopednamehead { if (currentSpec->genc) yyerror("Scoped names are not allowed in a C module"); $$ = scopeScopedName(NULL, $2); } | scopednamehead ; scopednamehead: scopepart | scopednamehead TK_SCOPE scopepart { if (currentSpec->genc) yyerror("Scoped names are not allowed in a C module"); appendScopedName(&$1, $3); } ; scopepart: TK_NAME_VALUE { $$ = text2scopePart($1); } ; bool_value: TK_TRUE_VALUE { $$ = TRUE; } | TK_FALSE_VALUE { $$ = FALSE; } ; 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_VALUE { $$.vtype = real_value; $$.u.vreal = $1; } | TK_NUMBER_VALUE { $$.vtype = numeric_value; $$.u.vnum = $1; } | bool_value { $$.vtype = numeric_value; $$.u.vnum = $1; } | TK_NULL_VALUE { $$.vtype = numeric_value; $$.u.vnum = 0; } | TK_STRING_VALUE { $$.vtype = string_value; $$.u.vstr = $1; } | TK_QCHAR_VALUE { $$.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("Internal error - increase the value of MAX_NR_ARGS"); $$ = $1; $$.args[$$.nrArgs] = $3; $$.nrArgs++; } ; typedef: TK_TYPEDEF cpptype TK_NAME_VALUE optflags ';' optdocstring { if (notSkipping()) { const char *annos[] = { "Capsule", "DocType", "Encoding", "NoTypeName", "PyInt", "PyName", "TypeHint", "TypeHintIn", "TypeHintOut", NULL }; checkAnnos(&$4, annos); applyTypeFlags(currentModule, &$2, &$4); newTypedef(currentSpec, currentModule, $3, &$2, &$4, $6); } } | TK_TYPEDEF cpptype '(' '*' TK_NAME_VALUE ')' '(' cpptypelist ')' optflags ';' optdocstring { if (notSkipping()) { const char *annos[] = { "DocType", "Encoding", "NoTypeName", "PyInt", "PyName", "TypeHint", "TypeHintIn", "TypeHintOut", NULL }; signatureDef *sig; argDef ftype; checkAnnos(&$10, annos); 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 = 1; ftype.u.sa = sig; newTypedef(currentSpec, currentModule, $5, &ftype, &$10, $12); } } ; 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()) { const char *annos[] = { "Abstract", "AllowNone", "API", "DelayDtor", "Deprecated", "ExportDerived", "External", "FileExtension", "Metatype", "Mixin", "NoDefaultCtors", "NoTypeHint", "PyName", "PyQtFlags", "PyQtInterface", "PyQtNoQMetaObject", "Supertype", "TypeHint", "TypeHintIn", "TypeHintOut", "TypeHintValue", "VirtualErrorHandler", NULL }; checkAnnos(&$5, annos); 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()) { const char *annos[] = { "Abstract", "AllowNone", "API", "DelayDtor", "Deprecated", "ExportDerived", "External", "FileExtension", "Metatype", "Mixin", "NoDefaultCtors", "PyName", "PyQtFlags", "PyQtInterface", "PyQtNoQMetaObject", "Supertype", "TypeHint", "TypeHintIn", "TypeHintOut", "TypeHintValue", "VirtualErrorHandler", NULL }; checkAnnos(&$5, annos); defineClass($2, currentSupers, &$5); sectionFlags = SECT_IS_PRIVATE; } } optclassbody ';' { if (notSkipping()) $$ = completeClass($2, &$5, $7); } ; superclasses: | ':' superlist ; superlist: superclass | superlist ',' superclass ; superclass: class_access scopedname { if (notSkipping() && $1 == TK_PUBLIC) { argDef ad; classDef *super; scopedNameDef *snd = $2; /* * 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"); /* * This is a bug because we should look in the local scope * rather than assume it is in the global scope. */ if (snd->name[0] != '\0') snd = scopeScopedName(NULL, snd); /* * Note that passing NULL as the API is a bug. Instead we * should pass the API of the sub-class being defined, * otherwise we cannot create sub-classes of versioned classes. */ super = findClass(currentSpec, class_iface, NULL, snd, currentIsTemplate); appendToClassList(¤tSupers, super); } } ; class_access: { $$ = TK_PUBLIC; } | TK_PUBLIC { $$ = TK_PUBLIC; } | TK_PROTECTED { $$ = TK_PROTECTED; } | TK_PRIVATE { $$ = TK_PRIVATE; } ; optclassbody: { $$ = FALSE; } | '{' classbody '}' { $$ = TRUE; } ; classbody: | classline | classbody classline ; classline: ifstart | ifend | namespace | struct | class | classtmpl | exception | typedef | enum | property | docstring { if (notSkipping()) { classDef *scope = currentScope(); if (scope->docstring != NULL) yyerror("%Docstring already given for class"); scope->docstring = $1; } } | typecode { if (notSkipping()) appendCodeBlock(¤tScope()->cppcode, $1); } | typehdrcode { if (notSkipping()) appendCodeBlock(¤tScope()->iff->hdrcode, $1); } | travcode { if (notSkipping()) { classDef *scope = currentScope(); if (scope->travcode != NULL) yyerror("%GCTraverseCode already given for class"); appendCodeBlock(&scope->travcode, $1); } } | clearcode { if (notSkipping()) { classDef *scope = currentScope(); if (scope->clearcode != NULL) yyerror("%GCClearCode already given for class"); appendCodeBlock(&scope->clearcode, $1); } } | getbufcode { if (notSkipping()) { classDef *scope = currentScope(); if (scope->getbufcode != NULL) yyerror("%BIGetBufferCode already given for class"); appendCodeBlock(&scope->getbufcode, $1); } } | releasebufcode { if (notSkipping()) { classDef *scope = currentScope(); if (scope->releasebufcode != NULL) yyerror("%BIReleaseBufferCode already given for class"); appendCodeBlock(&scope->releasebufcode, $1); } } | readbufcode { if (notSkipping()) { classDef *scope = currentScope(); if (scope->readbufcode != NULL) yyerror("%BIGetReadBufferCode already given for class"); appendCodeBlock(&scope->readbufcode, $1); } } | writebufcode { if (notSkipping()) { classDef *scope = currentScope(); if (scope->writebufcode != NULL) yyerror("%BIGetWriteBufferCode already given for class"); appendCodeBlock(&scope->writebufcode, $1); } } | segcountcode { if (notSkipping()) { classDef *scope = currentScope(); if (scope->segcountcode != NULL) yyerror("%BIGetSegCountCode already given for class"); appendCodeBlock(&scope->segcountcode, $1); } } | charbufcode { if (notSkipping()) { classDef *scope = currentScope(); if (scope->charbufcode != NULL) yyerror("%BIGetCharBufferCode already given for class"); appendCodeBlock(&scope->charbufcode, $1); } } | instancecode { if (notSkipping()) { classDef *scope = currentScope(); if (scope->instancecode != NULL) yyerror("%InstanceCode already given for class"); appendCodeBlock(&scope->instancecode, $1); } } | picklecode { if (notSkipping()) { classDef *scope = currentScope(); if (scope->picklecode != NULL) yyerror("%PickleCode already given for class"); appendCodeBlock(&scope->picklecode, $1); } } | finalcode { if (notSkipping()) { classDef *scope = currentScope(); if (scope->finalcode != NULL) yyerror("%FinalisationCode already given for class"); appendCodeBlock(&scope->finalcode, $1); } } | classtypehintcode { if (notSkipping()) { classDef *scope = currentScope(); if (scope->typehintcode != NULL) yyerror("%TypeHintCode already given for class"); appendCodeBlock(&scope->typehintcode, $1); } } | ctor | dtor | varmember | TK_TOSUBCLASS codeblock { if (notSkipping()) { classDef *scope = currentScope(); if (scope->convtosubcode != NULL) yyerror("Class has more than one %ConvertToSubClassCode directive"); appendCodeBlock(&scope->convtosubcode, $2); } } | TK_TOTYPE codeblock { if (notSkipping()) { classDef *scope = currentScope(); if (scope->convtocode != NULL) yyerror("Class has more than one %ConvertToTypeCode directive"); appendCodeBlock(&scope->convtocode, $2); } } | TK_FROMTYPE codeblock { if (notSkipping()) { classDef *scope = currentScope(); if (scope->convfromcode != NULL) yyerror("Class has more than one %ConvertFromTypeCode directive"); appendCodeBlock(&scope->convfromcode, $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; } ; property: TK_PROPERTY property_args property_body { if ($2.name == NULL) yyerror("A %Property directive must have a 'name' argument"); if ($2.get == NULL) yyerror("A %Property directive must have a 'get' argument"); if (notSkipping()) addProperty(currentSpec, currentModule, currentScope(), $2.name, $2.get, $2.set, $3.docstring); } ; property_args: '(' property_arg_list ')' { $$ = $2; } ; property_arg_list: property_arg | property_arg_list ',' property_arg { $$ = $1; switch ($3.token) { case TK_GET: $$.get = $3.get; break; case TK_NAME: $$.name = $3.name; break; case TK_SET: $$.set = $3.set; break; } } ; property_arg: TK_GET '=' TK_NAME_VALUE { $$.token = TK_GET; $$.get = $3; $$.name = NULL; $$.set = NULL; } | TK_NAME '=' name_or_string { $$.token = TK_NAME; $$.get = NULL; $$.name = $3; $$.set = NULL; } | TK_SET '=' TK_NAME_VALUE { $$.token = TK_SET; $$.get = NULL; $$.name = NULL; $$.set = $3; } ; property_body: { $$.token = 0; $$.docstring = NULL; } | '{' property_body_directives '}' ';' { $$ = $2; } ; property_body_directives: property_body_directive | property_body_directives property_body_directive { $$ = $1; switch ($2.token) { case TK_DOCSTRING: $$.docstring = $2.docstring; break; } } ; property_body_directive: ifstart { $$.token = TK_IF; } | ifend { $$.token = TK_END; } | docstring { if (notSkipping()) { $$.token = TK_DOCSTRING; $$.docstring = $1; } else { $$.token = 0; $$.docstring = NULL; } } ; name_or_string: TK_NAME_VALUE | TK_STRING_VALUE ; optslot: { $$ = 0; } | TK_SLOTS { $$ = SECT_IS_SLOT; } ; dtor: optvirtual '~' TK_NAME_VALUE '(' ')' optexceptions optabstract optflags ';' premethodcode methodcode virtualcatchercode { /* Note that we allow non-virtual dtors in C modules. */ if (notSkipping()) { const char *annos[] = { "HoldGIL", "ReleaseGIL", NULL }; classDef *cd = currentScope(); checkAnnos(&$8, annos); 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"); appendCodeBlock(&cd->dealloccode, $10); /* premethodcode */ appendCodeBlock(&cd->dealloccode, $11); /* methodcode */ appendCodeBlock(&cd->dtorcode, $12); 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"); setNeedsShadow(cd); } if (getReleaseGIL(&$8)) setIsReleaseGILDtor(cd); else if (getHoldGIL(&$8)) setIsHoldGILDtor(cd); } } ; ctor: TK_EXPLICIT {currentCtorIsExplicit = TRUE;} simplector | simplector ; simplector: TK_NAME_VALUE '(' arglist ')' optexceptions optflags optctorsig ';' optdocstring premethodcode methodcode { /* Note that we allow ctors in C modules. */ if (notSkipping()) { const char *annos[] = { "API", "Default", "Deprecated", "HoldGIL", "KeywordArgs", "NoDerived", "NoRaisesPyException", "NoTypeHint", "PostHook", "PreHook", "RaisesPyException", "ReleaseGIL", "Transfer", NULL }; checkAnnos(&$6, annos); 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(currentModule, $1, sectionFlags, &$3, &$6, $11, $5, $7, currentCtorIsExplicit, $9, $10); } free($1); currentCtorIsExplicit = FALSE; } ; optctorsig: { $$ = NULL; } | '[' { parsingCSignature = TRUE; } '(' arglist ')' ']' { $$ = sipMalloc(sizeof (signatureDef)); *$$ = $4; parsingCSignature = FALSE; } ; optsig: { $$ = NULL; } | '[' { parsingCSignature = TRUE; } cpptype '(' arglist ')' ']' { $$ = sipMalloc(sizeof (signatureDef)); *$$ = $5; $$->result = $3; parsingCSignature = FALSE; } ; optvirtual: { $$ = FALSE; } | TK_VIRTUAL { $$ = TRUE; } ; function: cpptype TK_NAME_VALUE '(' arglist ')' optconst optfinal optexceptions optabstract optflags optsig ';' optdocstring premethodcode methodcode virtualcatchercode virtualcallcode { if (notSkipping()) { applyTypeFlags(currentModule, &$1, &$10); $4.result = $1; newFunction(currentSpec, currentModule, currentScope(), NULL, NULL, sectionFlags, currentIsStatic, currentIsSignal, currentIsSlot, currentOverIsVirt, $2, &$4, $6, $9, &$10, $15, $16, $17, $8, $11, $13, $7, $14); } 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 optfinal optexceptions optabstract optflags optsig ';' premethodcode methodcode virtualcatchercode virtualcallcode { if (notSkipping()) { classDef *cd = currentScope(); ifaceFileDef *ns_scope; /* * If the scope is a namespace then make sure the operator is * handled as a global, but remember it's C++ scope.. */ if (cd != NULL && cd->iff->type == namespace_iface) { ns_scope = cd->iff; cd = NULL; } else { ns_scope = NULL; } applyTypeFlags(currentModule, &$1, &$11); /* 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, ns_scope, NULL, sectionFlags, currentIsStatic, currentIsSignal, currentIsSlot, currentOverIsVirt, $3, &$5, $7, $10, &$11, $15, $16, $17, $9, $12, NULL, $8, $14); } currentIsStatic = FALSE; currentIsSignal = FALSE; currentIsSlot = FALSE; currentOverIsVirt = FALSE; } | TK_OPERATOR cpptype '(' arglist ')' optconst optfinal optexceptions optabstract optflags optsig ';' premethodcode methodcode virtualcatchercode virtualcallcode { 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, &$10); switch ($2.atype) { case defined_type: sname = NULL; break; case bool_type: case cbool_type: case byte_type: case sbyte_type: case ubyte_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, NULL, sectionFlags, currentIsStatic, currentIsSignal, currentIsSlot, currentOverIsVirt, sname, &$4, $6, $9, &$10, $14, $15, $16, $8, $11, NULL, $7, $13); } 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; } ; optfinal: { $$ = FALSE; } | TK_FINAL { $$ = TRUE; } ; optabstract: { $$ = 0; } | '=' TK_NUMBER_VALUE { 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_VALUE { $$.ftype = bool_flag; $$.fname = $1; } | TK_NAME_VALUE '=' flagvalue { $$ = $3; $$.fname = $1; } ; flagvalue: dottedname { $$.ftype = (strchr($1, '.') != NULL) ? dotted_name_flag : name_flag; $$.fvalue.sval = $1; } | TK_NAME_VALUE ':' 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_VALUE { $$.ftype = string_flag; $$.fvalue.sval = convertFeaturedString($1); } | TK_NUMBER_VALUE { $$.ftype = integer_flag; $$.fvalue.ival = $1; } ; virtualcallcode: { $$ = NULL; } | TK_VIRTUALCALLCODE codeblock { $$ = $2; } ; methodcode: { $$ = NULL; } | TK_METHODCODE codeblock { $$ = $2; } ; premethodcode: { $$ = NULL; } | TK_PREMETHODCODE 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; /* Suppress a compiler warning. */ default: ; } 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"); /* * 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 { deprecated("SIP_SIGNAL is deprecated\n"); checkNoAnnos(&$3, "SIP_SIGNAL has no annotations"); $$.atype = signal_type; $$.argflags = ARG_IS_CONST; $$.nrderefs = 0; $$.name = cacheName(currentSpec, $2); $$.defval = $4; currentSpec -> sigslots = TRUE; } | TK_SIPSLOT optname optflags optassign { deprecated("SIP_SLOT is deprecated\n"); checkNoAnnos(&$3, "SIP_SLOT has no annotations"); $$.atype = slot_type; $$.argflags = ARG_IS_CONST; $$.nrderefs = 0; $$.name = cacheName(currentSpec, $2); $$.defval = $4; currentSpec -> sigslots = TRUE; } | TK_SIPANYSLOT optname optflags optassign { deprecated("SIP_ANYSLOT is deprecated\n"); checkNoAnnos(&$3, "SIP_ANYSLOT has no annotations"); $$.atype = anyslot_type; $$.argflags = ARG_IS_CONST; $$.nrderefs = 0; $$.name = cacheName(currentSpec, $2); $$.defval = $4; currentSpec -> sigslots = TRUE; } | TK_SIPRXCON optname optflags { const char *annos[] = { "SingleShot", NULL }; deprecated("SIP_RXOBJ_CON is deprecated\n"); checkAnnos(&$3, annos); $$.atype = rxcon_type; $$.argflags = 0; $$.nrderefs = 0; $$.name = cacheName(currentSpec, $2); if (getOptFlag(&$3, "SingleShot", bool_flag) != NULL) $$.argflags |= ARG_SINGLE_SHOT; currentSpec -> sigslots = TRUE; } | TK_SIPRXDIS optname optflags { deprecated("SIP_RXOBJ_DIS is deprecated\n"); checkNoAnnos(&$3, "SIP_RXOBJ_DIS has no annotations"); $$.atype = rxdis_type; $$.argflags = 0; $$.nrderefs = 0; $$.name = cacheName(currentSpec, $2); currentSpec -> sigslots = TRUE; } | TK_SIPSLOTCON '(' arglist ')' optname optflags { deprecated("SIP_SLOT_CON is deprecated\n"); checkNoAnnos(&$6, "SIP_SLOT_CON has no annotations"); $$.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 { deprecated("SIP_SLOT_DIS is deprecated\n"); checkNoAnnos(&$6, "SIP_SLOT_DIS has no annotations"); $$.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 { deprecated("SIP_QOBJECT is deprecated\n"); checkNoAnnos(&$3, "SIP_QOBJECT has no annotations"); $$.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_VALUE optflags variable_body ';' optaccesscode optgetcode optsetcode { if (notSkipping()) { const char *annos[] = { "DocType", "Encoding", "NoSetter", "NoTypeHint", "PyInt", "PyName", "TypeHint", NULL }; checkAnnos(&$3, annos); if ($6 != NULL) { if ($4.access_code != NULL) yyerror("%AccessCode already defined"); $4.access_code = $6; deprecated("%AccessCode should be used as a sub-directive"); } if ($7 != NULL) { if ($4.get_code != NULL) yyerror("%GetCode already defined"); $4.get_code = $7; deprecated("%GetCode should be used as a sub-directive"); } if ($8 != NULL) { if ($4.set_code != NULL) yyerror("%SetCode already defined"); $4.set_code = $8; deprecated("%SetCode should be used as a sub-directive"); } newVar(currentSpec, currentModule, $2, currentIsStatic, &$1, &$3, $4.access_code, $4.get_code, $4.set_code, sectionFlags); } currentIsStatic = FALSE; } ; variable_body: { $$.token = 0; $$.access_code = NULL; $$.get_code = NULL; $$.set_code = NULL; } | '{' variable_body_directives '}' { $$ = $2; } ; variable_body_directives: variable_body_directive | variable_body_directives variable_body_directive { $$ = $1; switch ($2.token) { case TK_ACCESSCODE: $$.access_code = $2.access_code; break; case TK_GETCODE: $$.get_code = $2.get_code; break; case TK_SETCODE: $$.set_code = $2.set_code; break; } } ; variable_body_directive: ifstart { $$.token = TK_IF; } | ifend { $$.token = TK_END; } | TK_ACCESSCODE codeblock { if (notSkipping()) { $$.token = TK_ACCESSCODE; $$.access_code = $2; } else { $$.token = 0; $$.access_code = NULL; } $$.get_code = NULL; $$.set_code = NULL; } | TK_GETCODE codeblock { if (notSkipping()) { $$.token = TK_GETCODE; $$.get_code = $2; } else { $$.token = 0; $$.get_code = NULL; } $$.access_code = NULL; $$.set_code = NULL; } | TK_SETCODE codeblock { if (notSkipping()) { $$.token = TK_SETCODE; $$.set_code = $2; } else { $$.token = 0; $$.set_code = NULL; } $$.access_code = NULL; $$.get_code = NULL; } ; cpptype: TK_CONST basetype deref optref { $$ = $2; add_derefs(&$$, &$3); $$.argflags |= ARG_IS_CONST | $4; } | basetype deref optref { $$ = $1; add_derefs(&$$, &$2); $$.argflags |= $3; /* PyObject * is a synonym for SIP_PYOBJECT. */ if ($1.atype == defined_type && strcmp($1.u.snd->name, "PyObject") == 0 && $1.u.snd->next == NULL && $2.nrderefs == 1 && $3 == 0) { $$.atype = pyobject_type; $$.nrderefs = 0; } } ; argtype: cpptype optname optflags { const char *annos[] = { "AllowNone", "Array", "ArraySize", "Constrained", "DisallowNone", "DocType", "DocValue", "Encoding", "GetWrapper", "In", "KeepReference", "NoCopy", "Out", "PyInt", "ResultSize", "Transfer", "TransferBack", "TransferThis", "TypeHint", "TypeHintIn", "TypeHintOut", "TypeHintValue", NULL }; checkAnnos(&$3, annos); $$ = $1; $$.name = cacheName(currentSpec, $2); handleKeepReference(&$3, &$$, currentModule); if (getAllowNone(&$3)) $$.argflags |= ARG_ALLOW_NONE; if (getDisallowNone(&$3)) $$.argflags |= ARG_DISALLOW_NONE; if (getOptFlag(&$3,"GetWrapper",bool_flag) != NULL) $$.argflags |= ARG_GET_WRAPPER; if (getOptFlag(&$3,"Array",bool_flag) != NULL) $$.argflags |= ARG_ARRAY; if (getOptFlag(&$3,"ArraySize",bool_flag) != NULL) $$.argflags |= ARG_ARRAY_SIZE; if (getTransfer(&$3)) $$.argflags |= ARG_XFERRED; if (getOptFlag(&$3,"TransferThis",bool_flag) != NULL) $$.argflags |= ARG_THIS_XFERRED; if (getOptFlag(&$3,"TransferBack",bool_flag) != NULL) $$.argflags |= ARG_XFERRED_BACK; if (getOptFlag(&$3,"In",bool_flag) != NULL) $$.argflags |= ARG_IN; if (getOptFlag(&$3,"Out",bool_flag) != NULL) $$.argflags |= ARG_OUT; if (getOptFlag(&$3, "ResultSize", bool_flag) != NULL) $$.argflags |= ARG_RESULT_SIZE; if (getOptFlag(&$3, "NoCopy", bool_flag) != NULL) $$.argflags |= ARG_NO_COPY; if (getOptFlag(&$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; /* Suppress a compiler warning. */ default: ; } } applyTypeFlags(currentModule, &$$, &$3); $$.typehint_value = getTypeHintValue(&$3); } ; optref: { $$ = 0; } | '&' { if (currentSpec -> genc) yyerror("References not allowed in a C module"); $$ = ARG_IS_REF; } ; deref: { $$.nrderefs = 0; } | deref '*' TK_CONST { add_new_deref(&$$, &$1, TRUE); } | deref '*' { add_new_deref(&$$, &$1, FALSE); } ; 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_PYBUFFER { memset(&$$, 0, sizeof (argDef)); $$.atype = pybuffer_type; } | TK_SIPSSIZET { memset(&$$, 0, sizeof (argDef)); $$.atype = ssize_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, int strict, stringList *tsl, stringList *bsl, stringList *xfl, KwArgs kwArgs, int protHack) { classTmplDef *tcd; /* Initialise the spec. */ memset(spec, 0, sizeof (sipSpec)); spec->genc = -1; currentSpec = spec; strictParse = strict; backstops = bsl; neededQualifiers = tsl; excludedQualifiers = xfl; currentModule = NULL; currentMappedType = NULL; currentOverIsVirt = FALSE; currentCtorIsExplicit = FALSE; currentIsStatic = FALSE; currentIsSignal = FALSE; currentIsSlot = FALSE; currentIsTemplate = FALSE; previousFile = NULL; stackPtr = 0; currentPlatforms = NULL; currentScopeIdx = 0; sectionFlags = 0; defaultKwArgs = kwArgs; 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(const 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, const 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->defdocstringfmt = raw; newmod->encoding = no_type; newmod->next_key = -1; /* * The consolidated module support needs these to be in order that they * appeared. */ for (tailp = ¤tSpec->modules; *tailp != NULL; tailp = &(*tailp)->next) ; *tailp = newmod; return newmod; } /* * Switch to parsing a new file. */ static void parseFile(FILE *fp, const char *name, moduleDef *prevmod, int optional) { parserContext pc; pc.filename = name; pc.ifdepth = stackPtr; 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; } /* * Note that we assume that the type (ie. class vs. mapped type vs. * exception) will be the same across all platforms. */ iff->platforms = currentPlatforms; iff->type = iftype; iff->ifacenr = -1; iff->fqcname = fqname; iff->module = NULL; iff->hdrcode = NULL; iff->used = NULL; iff->file_extension = 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, int tmpl_arg) { return findClassWithInterface(pt, findIfaceFile(pt, currentModule, fqname, iftype, api_range, NULL), tmpl_arg); } /* * Find a class definition given an existing interface file. */ static classDef *findClassWithInterface(sipSpec *pt, ifaceFileDef *iff, int tmpl_arg) { classDef *cd; for (cd = pt->classes; cd != NULL; cd = cd->next) if (cd->iff == iff) { if (isTemplateArg(cd) && !tmpl_arg) resetTemplateArg(cd); return cd; } /* Create a new one. */ cd = sipMalloc(sizeof (classDef)); if (tmpl_arg) setTemplateArg(cd); 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 appendToIfaceFileList(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, FALSE); } /* Create a new one. */ xd = sipMalloc(sizeof (exceptionDef)); xd->exceptionnr = -1; xd->needed = FALSE; 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, const char *virt_error_handler, typeHintDef *typehint_in, typeHintDef *typehint_out, const char *typehint_value) { int flags; classDef *cd, *scope; codeBlockList *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) setNeedsShadow(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, FALSE); /* 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; cd->virt_error_handler = virt_error_handler; cd->typehint_in = typehint_in; cd->typehint_out = typehint_out; cd->typehint_value = typehint_value; if (currentIsTemplate) setIsTemplateClass(cd); appendCodeBlockList(&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; if (inMainModule()) ns->iff->first_alt->needed = TRUE; 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(mod, of, classBaseName(cd)); cd->pyname = NULL; checkAttributes(pt, mod, cd->ecd, NULL, pyname, FALSE); cd->pyname = cacheName(pt, pyname); cd->no_typehint = getNoTypeHint(of); if ((flg = getOptFlag(of, "Metatype", dotted_name_flag)) != NULL) cd->metatype = cacheName(pt, flg->fvalue.sval); if ((flg = getOptFlag(of, "Supertype", dotted_name_flag)) != NULL) cd->supertype = cacheName(pt, flg->fvalue.sval); if (getOptFlag(of, "ExportDerived", bool_flag) != NULL) setExportDerived(cd); if (getOptFlag(of, "Mixin", bool_flag) != NULL) setMixin(cd); if ((flg = getOptFlag(of, "FileExtension", string_flag)) != NULL) cd->iff->file_extension = flg->fvalue.sval; if ((flg = getOptFlag(of, "PyQtFlags", integer_flag)) != NULL) cd->pyqt_flags = flg->fvalue.ival; if (getOptFlag(of, "PyQtNoQMetaObject", bool_flag) != NULL) setPyQtNoQMetaObject(cd); if ((flg = getOptFlag(of, "PyQtInterface", string_flag)) != NULL) cd->pyqt_interface = flg->fvalue.sval; if (isOpaque(cd)) { if (getOptFlag(of, "External", bool_flag) != NULL) setIsExternal(cd); } else { int seq_might, seq_not, default_to_sequence; memberDef *md; if (getOptFlag(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 (getOptFlag(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 (getOptFlag(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 the user has used the * /Sequence/ annotation or 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; /* Suppress a compiler warning. */ default: ; } default_to_sequence = (!seq_not && seq_might); for (md = cd->members; md != NULL; md = md->next) { /* Ignore if it is explicitly numeric. */ if (isNumeric(md)) continue; if (isSequence(md) || default_to_sequence) 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; /* Suppress a compiler warning. */ default: ; } } } 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 = fullyQualifiedName(ad->u.snd); cname = scopedNameTail(snd); break; case template_type: ad->u.td->fqname = fullyQualifiedName(ad->u.td->fqname); snd = encodedTemplateName(ad->u.td); cname = NULL; break; case struct_type: snd = ad->u.sname = fullyQualifiedName(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(currentModule, of, cname)); mappedTypeAnnos(mtd, 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, initialise 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)); /* Keep track of the original definition as it gets copied. */ mtd->real = mtd; return mtd; } /* * Create a new enum. */ static enumDef *newEnum(sipSpec *pt, moduleDef *mod, mappedTypeDef *mt_scope, char *name, optFlags *of, int flags, int isscoped) { 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(mod, 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) { if (makeProtPublic) { flags &= ~SECT_IS_PROT; flags |= SECT_IS_PUBLIC; } else if (c_scope != NULL) { setNeedsShadow(c_scope); } } ed->enumflags = flags; ed->no_typehint = getNoTypeHint(of); 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->platforms = currentPlatforms; ed->next = pt -> enums; pt->enums = ed; if (getOptFlag(of, "NoScope", bool_flag) != NULL) setIsNoScope(ed); if (isscoped) setIsScopedEnum(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); /* We do want const. */ if (isConstArg(sad)) { char *const_val = sipStrdup("const "); append(&const_val, val); free(val); val = const_val; } 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 ubyte_type: case ustring_type: s = "unsigned char"; break; case byte_type: case ascii_string_type: case latin1_string_type: case utf8_string_type: case string_type: s = "char"; break; case sbyte_type: 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 = "uint"; 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; case void_type: s = "void"; break; case capsule_type: s = "void *"; 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; } /* * Remove any explicit global scope. */ scopedNameDef *removeGlobalScope(scopedNameDef *snd) { return ((snd != NULL && snd->name[0] == '\0') ? snd->next : snd); } /* * 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; /* * We don't want the global scope (which probably should always be there, * but we check anyway). */ name = removeGlobalScope(name); /* 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, const char *pyname, int use_template_name, docstringDef *docstring) { scopedNameDef *type_names, *type_values; classDef *cd; ctorDef *oct, **cttail; argDef *ad; ifaceFileList *iffl, **used; classList *cl; 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; if (docstring != NULL) cd->docstring = docstring; resetIsTemplateClass(cd); cd->pyname = cacheName(pt, pyname); cd->td = td; if (use_template_name) setUseTemplateName(cd); /* Handle the interface file. */ cd->iff = findIfaceFile(pt, mod, fqname, class_iface, (scope != NULL ? scope->iff->api_range : NULL), NULL); cd->iff->module = mod; appendCodeBlockList(&cd->iff->hdrcode, tcd->cd->iff->hdrcode); /* 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) appendToIfaceFileList(used, iffl->iff); /* Include any scope header code. */ if (scope != NULL) appendCodeBlockList(&cd->iff->hdrcode, scope->iff->hdrcode); if (inMainModule()) { setIsUsedName(cd->iff->name); setIsUsedName(cd->pyname); } cd->ecd = currentScope(); /* Handle any type hints. */ if (cd->typehint_in != NULL) cd->typehint_in = newTypeHint( templateString(cd->typehint_in->raw_hint, type_names, type_values)); if (cd->typehint_out != NULL) cd->typehint_out = newTypeHint( templateString(cd->typehint_out->raw_hint, type_names, type_values)); /* Handle the super-classes. */ for (cl = cd->supers; cl != NULL; cl = cl->next) { int a; scopedNameDef *unscoped; unscoped = removeGlobalScope(cl->cd->iff->fqcname); /* Ignore defined or scoped classes. */ if (cl->cd->iff->module != NULL || unscoped->next != NULL) continue; for (a = 0; a < tcd->sig.nrArgs - 1; ++a) if (strcmp(unscoped->name, scopedNameTail(tcd->sig.args[a].u.snd)) == 0) { argDef *tad = &td->types.args[a]; classDef *icd; if (tad->atype == defined_type) icd = findClass(pt, class_iface, NULL, tad->u.snd, FALSE); else if (tad->atype == class_type) icd = tad->u.cd; else fatal("Template argument %s must expand to a class\n", unscoped->name); cl->cd = icd; } } /* 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 typedefs. */ instantiateTemplateTypedefs(pt, tcd, td, cd, 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, type_names, type_values); 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, type_names, type_values); } nct->methodcode = templateCode(pt, used, nct->methodcode, type_names, type_values); nct->premethodcode = templateCode(pt, used, nct->premethodcode, 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->instancecode = templateCode(pt, used, cd->instancecode, type_names, type_values); cd->picklecode = templateCode(pt, used, cd->picklecode, type_names, type_values); cd->finalcode = templateCode(pt, used, cd->finalcode, type_names, type_values); cd->typehintcode = templateCode(pt, used, cd->typehintcode, 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, type_names, type_values); 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, type_names, type_values); } nod->methodcode = templateCode(pt, used, nod->methodcode, type_names, type_values); nod->premethodcode = templateCode(pt, used, nod->premethodcode, type_names, type_values); nod->virtcallcode = templateCode(pt, used, nod->virtcallcode, type_names, type_values); nod->virtcode = templateCode(pt, used, nod->virtcode, type_names, type_values); 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, type_names, type_values); 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); } } /* * Instantiate the typedefs of a template class. */ static void instantiateTemplateTypedefs(sipSpec *pt, classTmplDef *tcd, templateDef *td, classDef *cd, scopedNameDef *type_names, scopedNameDef *type_values) { typedefDef *tdd; for (tdd = pt->typedefs; tdd != NULL; tdd = tdd->next) { typedefDef *new_tdd; if (tdd->ecd != tcd->cd) continue; new_tdd = sipMalloc(sizeof (typedefDef)); /* Start with a shallow copy. */ *new_tdd = *tdd; new_tdd->fqname = text2scopedName(cd->iff, scopedNameTail(new_tdd->fqname)); new_tdd->ecd = cd; new_tdd->module = cd->iff->module; templateType(&new_tdd->type, tcd, td, cd, type_names, type_values); addTypedef(pt, new_tdd); } } /* * Replace any template arguments in a signature. */ static void templateSignature(signatureDef *sd, int result, classTmplDef *tcd, templateDef *td, classDef *ncd, scopedNameDef *type_names, scopedNameDef *type_values) { int a; if (result) templateType(&sd->result, tcd, td, ncd, type_names, type_values); for (a = 0; a < sd->nrArgs; ++a) templateType(&sd->args[a], tcd, td, ncd, type_names, type_values); } /* * Replace any template arguments in a type. */ static void templateType(argDef *ad, classTmplDef *tcd, templateDef *td, classDef *ncd, scopedNameDef *type_names, scopedNameDef *type_values) { 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, type_names, type_values); return; } /* Handle any default value. */ if (ad->defval != NULL && ad->defval->vtype == fcall_value) { /* * We only handle the subset where the value is an function call, ie. a * template ctor. */ valueDef *vd = ad->defval; if (vd->vtype == fcall_value && vd->u.fcd->type.atype == defined_type) { valueDef *new_vd; fcallDef *fcd; scopedNameDef *snd, **tailp; fcd = sipMalloc(sizeof (fcallDef)); *fcd = *vd->u.fcd; tailp = &fcd->type.u.snd; for (snd = vd->u.fcd->type.u.snd; snd != NULL; snd = snd->next) { *tailp = text2scopePart( templateString(snd->name, type_names, type_values)); tailp = &(*tailp)->next; } new_vd = sipMalloc(sizeof (valueDef)); new_vd->vtype = fcall_value; new_vd->u.fcd = fcd; ad->defval = new_vd; } } /* Handle any type hints. */ if (ad->typehint_in != NULL) ad->typehint_in = newTypeHint( templateString(ad->typehint_in->raw_hint, type_names, type_values)); if (ad->typehint_out != NULL) ad->typehint_out = newTypeHint( templateString(ad->typehint_out->raw_hint, type_names, type_values)); /* 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. */ codeBlockList *templateCode(sipSpec *pt, ifaceFileList **used, codeBlockList *ocbl, scopedNameDef *names, scopedNameDef *values) { codeBlockList *ncbl = NULL; while (ocbl != NULL) { char *at = ocbl->block->frag; int start_of_line = TRUE; do { char *from = at, *first = NULL; codeBlock *cb; scopedNameDef *nam, *val, *nam_first, *val_first; /* Suppress a compiler warning. */ val_first = NULL; /* * Don't do any substitution in lines that appear to be * preprocessor directives. This prevents #include'd file names * being broken. */ if (start_of_line) { /* Strip leading whitespace. */ while (isspace(*from)) ++from; if (*from == '#') { /* Skip to the end of the line. */ do ++from; while (*from != '\n' && *from != '\0'); } else { start_of_line = FALSE; } } /* * 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(from, 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 == ocbl->block->frag) { cb->filename = ocbl->block->filename; cb->linenr = ocbl->block->linenr; } else cb->filename = NULL; appendCodeBlock(&ncbl, cb); /* 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 "_" * and remove any const. */ 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; if (strlen(sp) > 6 && strncmp(sp, "const ", 6) == 0) sp += 6; 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); if (*at == '\n') start_of_line = TRUE; } } while (at != NULL && *at != '\0'); ocbl = ocbl->next; } return ncbl; } /* * 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)) { appendToIfaceFileList(used, iff); return; } } for (ed = pt->enums; ed != NULL; ed = ed->next) { if (ed->ecd == NULL) continue; if (sameName(ed->fqcname, sname)) { appendToIfaceFileList(used, ed->ecd->iff); return; } } } /* * Compare a scoped name with its string equivalent. */ static int sameName(scopedNameDef *snd, const char *sname) { /* Handle any explicit scopes. */ if (sname[0] == ':' && sname[1] == ':') { if (snd->name[0] != '\0') return FALSE; sname += 2; } snd = removeGlobalScope(snd); 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, docstringDef *docstring) { int no_type_name; typedefDef *td; scopedNameDef *fqname; classDef *scope; scope = currentScope(); fqname = text2scopedName((scope != NULL ? scope->iff : NULL), name); no_type_name = (getOptFlag(optflgs, "NoTypeName", bool_flag) != NULL); /* 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, getPythonName(mod, optflgs, name), no_type_name, docstring); /* All done. */ return; } } td = sipMalloc(sizeof (typedefDef)); td->tdflags = 0; td->fqname = fqname; td->ecd = scope; td->module = mod; td->platforms = currentPlatforms; td->type = *type; if (getOptFlag(optflgs, "Capsule", bool_flag) != NULL) { /* Make sure the type is void *. */ if (type->atype != void_type || type->nrderefs != 1 || isConstArg(type) || isReference(type)) { fatalScopedName(fqname); fatal(" must be a void* if /Capsule/ is specified\n"); } td->type.atype = capsule_type; td->type.nrderefs = 0; td->type.u.cap = fqname; } if (no_type_name) setNoTypeName(td); addTypedef(pt, td); } /* * Add a typedef to the list so that the list remains sorted. */ static void addTypedef(sipSpec *pt, typedefDef *tdd) { typedefDef **tdp; /* * Check it doesn't already exist (with a strict parse) 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, tdd->fqname); if (res == 0 && strictParse) { fatalScopedName(tdd->fqname); fatal(" already defined\n"); } if (res >= 0) break; } tdd->next = *tdp; *tdp = tdd; tdd->module->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, int section) { varDef *var; classDef *escope = currentScope(); nameDef *nd; /* * For the moment we don't support capsule variables because it needs the * API major version increasing. */ if (type->atype == capsule_type) yyerror("Capsule variables not yet supported"); /* Check the section. */ if (section != 0) { if ((section & SECT_IS_PUBLIC) == 0) yyerror("Class variables must be in the public section"); if (!isstatic && acode != NULL) yyerror("%AccessCode cannot be specified for non-static class variables"); } if (isstatic && pt->genc) yyerror("Cannot have static members in a C structure"); if (gcode != NULL || scode != NULL) { if (acode != NULL) yyerror("Cannot mix %AccessCode and %GetCode or %SetCode"); if (escope == NULL) yyerror("Cannot specify %GetCode or %SetCode for global variables"); } applyTypeFlags(mod, type, of); nd = cacheName(pt, getPythonName(mod, 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->no_typehint = getNoTypeHint(of); var->platforms = currentPlatforms; var->type = *type; appendCodeBlock(&var->accessfunc, acode); appendCodeBlock(&var->getcode, gcode); appendCodeBlock(&var->setcode, scode); if (isstatic || (escope != NULL && escope->iff->type == namespace_iface)) setIsStaticVar(var); if (getOptFlag(of, "NoSetter", bool_flag) != NULL) setNoSetter(var); addVariable(pt, var); } /* * Create a new ctor. */ static void newCtor(moduleDef *mod, char *name, int sectFlags, signatureDef *args, optFlags *optflgs, codeBlock *methodcode, throwArgs *exceptions, signatureDef *cppsig, int explicit, docstringDef *docstring, codeBlock *premethodcode) { 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"); /* 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->docstring = docstring; ct->ctorflags = sectFlags; ct->no_typehint = getNoTypeHint(optflgs); ct->api_range = getAPIRange(optflgs); ct->pysig = *args; ct->cppsig = (cppsig != NULL ? cppsig : &ct->pysig); ct->exceptions = exceptions; ct->platforms = currentPlatforms; appendCodeBlock(&ct->methodcode, methodcode); appendCodeBlock(&ct->premethodcode, premethodcode); if (!isPrivateCtor(ct)) setCanCreate(cd); if (isProtectedCtor(ct)) setNeedsShadow(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)) ct->kwargs = keywordArgs(mod, optflgs, &ct->pysig, FALSE); if (methodcode == NULL && getOptFlag(optflgs, "NoRaisesPyException", bool_flag) == NULL) { if (allRaisePyException(mod) || getOptFlag(optflgs, "RaisesPyException", bool_flag) != NULL) setRaisesPyExceptionCtor(ct); } if (getOptFlag(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 (getOptFlag(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, ifaceFileDef *ns_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, codeBlock *virtcallcode, throwArgs *exceptions, signatureDef *cppsig, docstringDef *docstring, int isfinal, codeBlock *premethodcode) { static const char *annos[] = { "__len__", "__imatmul__", "__matmul__", "AbortOnException", "AllowNone", "API", "AutoGen", "Deprecated", "DisallowNone", "DocType", "Encoding", "Factory", "HoldGIL", "KeywordArgs", "KeepReference", "NewThread", "NoArgParser", "NoCopy", "NoRaisesPyException", "NoTypeHint", "NoVirtualErrorHandler", "Numeric", "PostHook", "PreHook", "PyInt", "PyName", "PyQtSignalHack", "RaisesPyException", "ReleaseGIL", "Sequence", "VirtualErrorHandler", "Transfer", "TransferBack", "TransferThis", "TypeHint", NULL }; const char *pyname, *virt_error_handler; int factory, xferback, no_arg_parser, no_virt_error_handler; overDef *od, **odp, **headp; optFlag *of; checkAnnos(optflgs, annos); /* 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"); /* Handle C void prototypes. */ if (sig->nrArgs == 1) { argDef *vad = &sig->args[0]; if (vad->atype == void_type && vad->nrderefs == 0) sig->nrArgs = 0; } } if (mt_scope != NULL) headp = &mt_scope->overs; else if (c_scope != NULL) headp = &c_scope->overs; else headp = &mod->overs; /* * See if the function has a non-lazy method. These are methods that * Python expects to see defined in the type before any instance of the * type is created. */ if (c_scope != NULL) { static const char *lazy[] = { "__getattribute__", "__getattr__", "__enter__", "__exit__", "__aenter__", "__aexit__", NULL }; const char **l; for (l = lazy; *l != NULL; ++l) if (strcmp(name, *l) == 0) { setHasNonlazyMethod(c_scope); break; } } /* See if it is a factory method. */ if (getOptFlag(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 = (getOptFlag(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)); getSourceLocation(&od->sloc); /* 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); } od->no_typehint = getNoTypeHint(optflgs); if (isSignal(od)) if ((of = getOptFlag(optflgs, "PyQtSignalHack", integer_flag)) != NULL) od->pyqt_signal_hack = of->fvalue.ival; if (factory) setIsFactory(od); if (xferback) setIsResultTransferredBack(od); if (getTransfer(optflgs)) setIsResultTransferred(od); if (getOptFlag(optflgs, "TransferThis", bool_flag) != NULL) setIsThisTransferredMeth(od); if (methodcode == NULL && getOptFlag(optflgs, "NoRaisesPyException", bool_flag) == NULL) { if (allRaisePyException(mod) || getOptFlag(optflgs, "RaisesPyException", bool_flag) != NULL) setRaisesPyException(od); } if (isProtected(od)) setNeedsShadow(c_scope); if ((isSlot(od) || isSignal(od)) && !isPrivate(od)) { if (isSignal(od)) setNeedsShadow(c_scope); pt->sigslots = TRUE; } if (isSignal(od) && (methodcode != NULL || vcode != NULL || virtcallcode != 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 (isfinal) setIsFinal(od); if (isabstract) { if (sflags == 0) yyerror("Non-class function specified as abstract"); setIsAbstract(od); } if ((of = getOptFlag(optflgs, "AutoGen", opt_name_flag)) != NULL) { if (of->fvalue.sval == NULL || isEnabledFeature(of->fvalue.sval)) setIsAutoGen(od); } virt_error_handler = getVirtErrorHandler(optflgs); no_virt_error_handler = (getOptFlag(optflgs, "NoVirtualErrorHandler", bool_flag) != NULL); if (isvirt) { if (!isfinal) { setIsVirtual(od); setNeedsShadow(c_scope); } if (getOptFlag(optflgs, "AbortOnException", bool_flag) != NULL) setAbortOnException(od); if (no_virt_error_handler) { if (virt_error_handler != NULL) yyerror("/VirtualErrorHandler/ and /NoVirtualErrorHandler/ provided"); setNoErrorHandler(od); } else { od->virt_error_handler = virt_error_handler; } } else { if (vcode != NULL) yyerror("%VirtualCatcherCode provided for non-virtual function"); if (virt_error_handler != NULL) yyerror("/VirtualErrorHandler/ provided for non-virtual function"); if (no_virt_error_handler) yyerror("/NoVirtualErrorHandler/ provided for non-virtual function"); } od->cppname = name; od->pysig = *sig; od->cppsig = (cppsig != NULL ? cppsig : &od->pysig); od->exceptions = exceptions; od->platforms = currentPlatforms; appendCodeBlock(&od->methodcode, methodcode); appendCodeBlock(&od->premethodcode, premethodcode); appendCodeBlock(&od->virtcallcode, virtcallcode); appendCodeBlock(&od->virtcode, vcode); no_arg_parser = (getOptFlag(optflgs, "NoArgParser", bool_flag) != NULL); if (no_arg_parser) { if (methodcode == NULL) yyerror("%MethodCode must be supplied if /NoArgParser/ is specified"); } else { /* * The argument parser requires that there is nothing after an * ellipsis. */ checkEllipsis(sig); } if (cppsig != NULL) checkEllipsis(cppsig); if (getOptFlag(optflgs, "NoCopy", bool_flag) != NULL) setNoCopy(&od->pysig.result); if (getAllowNone(optflgs)) setAllowNone(&od->pysig.result); if (getDisallowNone(optflgs)) setDisallowNone(&od->pysig.result); handleKeepReference(optflgs, &od->pysig.result, mod); pyname = getPythonName(mod, optflgs, name); od->common = findFunction(pt, mod, c_scope, ns_scope, mt_scope, pyname, (methodcode != NULL), sig->nrArgs, no_arg_parser); if (isProtected(od)) setHasProtected(od->common); if (strcmp(pyname, "__delattr__") == 0) setIsDelattr(od); od->docstring = docstring; od->api_range = getAPIRange(optflgs); if (od->api_range == NULL) setNotVersioned(od->common); if (getOptFlag(optflgs, "Numeric", bool_flag) != NULL) { if (isSequence(od->common)) yyerror("/Sequence/ has already been specified"); setIsNumeric(od->common); } if (getOptFlag(optflgs, "Sequence", bool_flag) != NULL) { if (isNumeric(od->common)) yyerror("/Numeric/ has already been specified"); setIsSequence(od->common); } /* Methods that run in new threads must be virtual. */ if (getOptFlag(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 || od->common->slot == call_slot)) { od->kwargs = keywordArgs(mod, optflgs, &od->pysig, hasProtected(od->common)); if (od->kwargs != NoKwArgs) setUseKeywordArgs(od->common); /* * If the overload is protected and defined in an imported module then * we need to make sure that any other overloads' keyword argument * names are marked as used. */ if (isProtected(od) && !inMainModule()) { overDef *kwod; for (kwod = c_scope->overs; kwod != NULL; kwod = kwod->next) if (kwod->common == od->common && kwod->kwargs != NoKwArgs) { int a; for (a = 0; a < kwod->pysig.nrArgs; ++a) { argDef *ad = &kwod->pysig.args[a]; if (kwod->kwargs == OptionalKwArgs && ad->defval == NULL) continue; if (ad->name != NULL) setIsUsedName(ad->name); } } } } od->next = NULL; /* See if we want to auto-generate some methods. */ if (getOptFlag(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; 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 = 1; appendCodeBlock(&len->methodcode, code); } len->common = findFunction(pt, mod, c_scope, ns_scope, mt_scope, len->cppname, TRUE, 0, FALSE); len->platforms = od->platforms; len->next = od->next; od->next = len; } if (getOptFlag(optflgs, "__matmul__", bool_flag) != NULL) { overDef *matmul; matmul = sipMalloc(sizeof (overDef)); matmul->cppname = "__matmul__"; matmul->overflags = SECT_IS_PUBLIC; matmul->pysig = od->pysig; matmul->cppsig = (cppsig != NULL ? cppsig : &matmul->pysig); matmul->methodcode = od->methodcode; matmul->common = findFunction(pt, mod, c_scope, ns_scope, mt_scope, matmul->cppname, (matmul->methodcode != NULL), matmul->pysig.nrArgs, FALSE); matmul->platforms = od->platforms; matmul->next = od->next; od->next = matmul; } if (getOptFlag(optflgs, "__imatmul__", bool_flag) != NULL) { overDef *imatmul; imatmul = sipMalloc(sizeof (overDef)); imatmul->cppname = "__imatmul__"; imatmul->overflags = SECT_IS_PUBLIC; imatmul->pysig = od->pysig; imatmul->cppsig = (cppsig != NULL ? cppsig : &imatmul->pysig); imatmul->methodcode = od->methodcode; imatmul->common = findFunction(pt, mod, c_scope, ns_scope, mt_scope, imatmul->cppname, (imatmul->methodcode != NULL), imatmul->pysig.nrArgs, FALSE); imatmul->platforms = od->platforms; imatmul->next = od->next; od->next = imatmul; } /* 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(moduleDef *mod, optFlags *optflgs, const char *cname) { const char *pname; optFlag *of; autoPyNameDef *apnd; /* Use the explicit name if given. */ if ((of = getOptFlag(optflgs, "PyName", name_flag)) != NULL) return of->fvalue.sval; /* Apply any automatic naming rules. */ pname = cname; for (apnd = mod->autopyname; apnd != NULL; apnd = apnd->next) { size_t len = strlen(apnd->remove_leading); if (strncmp(pname, apnd->remove_leading, len) == 0) pname += len; } 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, ifaceFileDef *ns_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}, {"__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}, {"__setattr__", setattr_slot, TRUE, 2}, {"__delattr__", delattr_slot, TRUE, 1}, {"__matmul__", matmul_slot, FALSE, 1}, {"__imatmul__", imatmul_slot, FALSE, 1}, {"__await__", await_slot, TRUE, 0}, {"__aiter__", aiter_slot, TRUE, 0}, {"__anext__", anext_slot, TRUE, 0}, {NULL, no_slot, FALSE, 0} }; 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; /* __delattr__ is implemented as __setattr__. */ if (st == delattr_slot) { if (inMainModule()) setIsUsedName(cacheName(pt, pname)); st = setattr_slot; pname = "__setattr__"; } 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->ns_scope = ns_scope; 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) && !isInplaceNumberSlot(md) && !isRichCompareSlot(md)) yyerror("Global operators must be either numeric or comparison operators"); return md; } /* * Search a set of flags for a particular one. */ static optFlag *findOptFlag(optFlags *flgs, const char *name) { int f; for (f = 0; f < flgs->nrFlags; ++f) { optFlag *of = &flgs->flags[f]; if (strcmp(of->fname, name) == 0) return of; } return NULL; } /* * Search a set of flags for a particular one and check its type. */ static optFlag *getOptFlag(optFlags *flgs, const char *name, flagType ft) { optFlag *of = findOptFlag(flgs, name); if (of != NULL) { /* 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; } } /* An optional integer can look like a boolean or an integer. */ if (ft == opt_integer_flag) { if (of->ftype == bool_flag) { of->ftype = opt_integer_flag; of->fvalue.ival = -1; } else if (of->ftype == integer_flag) { of->ftype = opt_integer_flag; } } if (ft != of->ftype) yyerror("Annotation has a value of the wrong type"); } return of; } /* * 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; /* We don't do any check for a non-strict parse. */ if (!strictParse) return; /* Check the enums. */ for (ed = pt->enums; ed != NULL; ed = ed->next) { 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"); if (!isScopedEnum(ed)) { enumMemberDef *emd; 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"); } /* Check the properties. */ if (py_c_scope != NULL) { propertyDef *pd; for (pd = py_c_scope->properties; pd != NULL; pd = pd->next) if (strcmp(pd->name->text, attr) == 0) yyerror("There is already a property with the same name"); } } /* * Append a code block to a list of them. */ static void appendCodeBlock(codeBlockList **headp, codeBlock *cb) { codeBlockList *cbl; /* Handle the trivial case. */ if (cb == NULL) return; /* Find the end of the list. */ while (*headp != NULL) { /* Ignore if the block is already in the list. */ if ((*headp)->block == cb) return; headp = &(*headp)->next; } cbl = sipMalloc(sizeof (codeBlockList)); cbl->block = cb; *headp = cbl; } /* * Append a code block list to an existing list. */ void appendCodeBlockList(codeBlockList **headp, codeBlockList *cbl) { while (cbl != NULL) { appendCodeBlock(headp, cbl->block); cbl = cbl->next; } } /* * 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 (stackPtr > currentContext.ifdepth) fatal("Too many %%If statements in %s\n", previousFile); if (stackPtr < 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) { if (from->encoding == no_type) from->encoding = currentModule->encoding; if (isCallSuperInitUndefined(from)) { if (isCallSuperInitYes(currentModule)) setCallSuperInitYes(from); else setCallSuperInitNo(from); } } /* 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; } /* Qualifiers corresponding to the SIP version are created on the fly. */ if (name[0] == 'S' && name[1] == 'I' && name[2] == 'P' && name[3] == '_') { const char *cp = &name[3]; int major, minor, patch; cp = getInt(cp, &major); cp = getInt(cp, &minor); cp = getInt(cp, &patch); if (*cp != '\0') yyerror("Unexpected character after SIP version number"); return allocQualifier(currentModule, -1, (major << 16) | (minor << 8) | patch, TRUE, name, time_qualifier); } return NULL; } /* * Get an integer from string. */ static const char *getInt(const char *cp, int *ip) { /* Handle the default value. */ *ip = 0; if (*cp == '\0') return cp; /* There must be a leading underscore. */ if (*cp++ != '_') yyerror("An underscore must separate the parts of a SIP version number"); while (isdigit(*cp)) { *ip *= 10; *ip += *cp - '0'; ++cp; } return cp; } /* * 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) : text2scopePart("")); 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 (stackPtr == 0 ? TRUE : skipStack[stackPtr - 1]); } /* * Return the value of an expression involving a time period. */ static int timePeriod(const char *lname, const char *uname) { int 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; } /* Handle the SIP version number pseudo-timeline. */ if (line < 0) { if (lower != NULL && SIP_VERSION < lower->order) return FALSE; if (upper != NULL && SIP_VERSION >= upper->order) return FALSE; return TRUE; } for (qd = mod->qualifiers; qd != NULL; qd = qd->next) { if (qd->qtype != time_qualifier || qd->line != line) continue; if (selectedQualifier(neededQualifiers, qd)) { if (lower != NULL && qd->order < lower->order) return FALSE; if (upper != NULL && qd->order >= upper->order) return FALSE; return TRUE; } } /* * If there is no upper bound then assume the expression is true unless * the lower bound is a backstop. */ if (upper == NULL) return !isBackstop(lower); /* * If the upper limit corresponds to a backstop then assume the expression * is true. */ return isBackstop(upper); } /* * See if a qualifier is a backstop. */ static int isBackstop(qualDef *qd) { stringList *sl; for (sl = backstops; sl != NULL; sl = sl->next) if (strcmp(qd->name, sl->s) == 0) return TRUE; return FALSE; } /* * 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 (!strictParse) { if (optnot) { moduleDef *mod; /* Add every platform except the one we have. */ for (mod = currentSpec->modules; mod != NULL; mod = mod->next) { qualDef *not_qd; for (not_qd = mod->qualifiers; not_qd != NULL; not_qd = not_qd->next) if (not_qd->qtype == platform_qualifier && strcmp(not_qd->name, qd->name) != 0) addPlatform(not_qd); } } else { addPlatform(qd); } /* * If it is a non-strict parse then this is always TRUE, ie. we * never skip because of the platform. */ return TRUE; } if (selectedQualifier(neededQualifiers, qd)) this = TRUE; } if (optnot) this = !this; return this; } /* * Add a platform to the current list of platforms if it is not already there. */ static void addPlatform(qualDef *qd) { platformDef *pd; for (pd = currentPlatforms; pd != NULL; pd = pd->next) if (pd->qualifier == qd) return; pd = sipMalloc(sizeof (platformDef)); pd->qualifier = qd; pd->next = currentPlatforms; currentPlatforms = pd; } /* * 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 !qd->default_enabled; } /* * Return TRUE if the given qualifier is needed. */ int selectedQualifier(stringList *needed_qualifiers, qualDef *qd) { stringList *sl; for (sl = needed_qualifiers; sl != NULL; sl = sl->next) if (strcmp(qd->name, sl->s) == 0) return qd->default_enabled; 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, int default_enabled, const char *name, qualType qt) { /* Check it doesn't already exist. */ if (findQualifier(name) != NULL) yyerror("Version is already defined"); allocQualifier(mod, line, order, default_enabled, name, qt); } /* * Allocate a new qualifier. */ static qualDef *allocQualifier(moduleDef *mod, int line, int order, int default_enabled, const char *name, qualType qt) { qualDef *qd; qd = sipMalloc(sizeof (qualDef)); qd->name = name; qd->qtype = qt; qd->module = mod; qd->line = line; qd->order = order; qd->default_enabled = default_enabled; qd->next = mod->qualifiers; mod->qualifiers = qd; return qd; } /* * Create a new imported module. */ static void newImport(const 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 = getOptFlag(optflgs,"PreHook",name_flag)) != NULL) *pre = of -> fvalue.sval; else *pre = NULL; if ((of = getOptFlag(optflgs,"PostHook",name_flag)) != NULL) *post = of -> fvalue.sval; else *post = NULL; } /* * Get the /Transfer/ option flag. */ static int getTransfer(optFlags *optflgs) { return (getOptFlag(optflgs, "Transfer", bool_flag) != NULL); } /* * Get the /ReleaseGIL/ option flag. */ static int getReleaseGIL(optFlags *optflgs) { return (getOptFlag(optflgs, "ReleaseGIL", bool_flag) != NULL); } /* * Get the /HoldGIL/ option flag. */ static int getHoldGIL(optFlags *optflgs) { return (getOptFlag(optflgs, "HoldGIL", bool_flag) != NULL); } /* * Get the /Deprecated/ option flag. */ static int getDeprecated(optFlags *optflgs) { return (getOptFlag(optflgs, "Deprecated", bool_flag) != NULL); } /* * Get the /AllowNone/ option flag. */ static int getAllowNone(optFlags *optflgs) { return (getOptFlag(optflgs, "AllowNone", bool_flag) != NULL); } /* * Get the /DisallowNone/ option flag. */ static int getDisallowNone(optFlags *optflgs) { return (getOptFlag(optflgs, "DisallowNone", bool_flag) != NULL); } /* * Get the /VirtualErrorHandler/ option flag. */ static const char *getVirtErrorHandler(optFlags *optflgs) { optFlag *of = getOptFlag(optflgs, "VirtualErrorHandler", name_flag); if (of == NULL) return NULL; return of->fvalue.sval; } /* * Get the /DocType/ option flag. */ static const char *getDocType(optFlags *optflgs) { optFlag *of = getOptFlag(optflgs, "DocType", string_flag); if (of == NULL) return NULL; deprecated("/DocType/ is deprecated\n"); return of->fvalue.sval; } /* * Get the /TypeHintValue/ option flag. */ static const char *getTypeHintValue(optFlags *optflgs) { optFlag *of = getOptFlag(optflgs, "TypeHintValue", string_flag); if (of != NULL) return of->fvalue.sval; if ((of = getOptFlag(optflgs, "DocValue", string_flag)) != NULL) { deprecated("/DocValue/ is deprecated\n"); return of->fvalue.sval; } return NULL; } /* * Get the /TypeHint/, /TypeHintIn/ and /TypeHintOut/ option flags. */ static void getTypeHints(optFlags *optflgs, typeHintDef **in, typeHintDef **out) { optFlag *of; typeHintDef *thd; if ((of = getOptFlag(optflgs, "TypeHint", string_flag)) != NULL) thd = newTypeHint(of->fvalue.sval); else thd = NULL; if ((of = getOptFlag(optflgs, "TypeHintIn", string_flag)) != NULL) { if (thd != NULL) yywarning("/TypeHintIn/ overrides /TypeHint/"); *in = newTypeHint(of->fvalue.sval); } else { *in = thd; } if ((of = getOptFlag(optflgs, "TypeHintOut", string_flag)) != NULL) { if (thd != NULL) yywarning("/TypeHintOut/ overrides /TypeHint/"); *out = newTypeHint(of->fvalue.sval); } else { *out = thd; } } /* * Get the /NoTypeHint/ option flag. */ static int getNoTypeHint(optFlags *optflgs) { return (getOptFlag(optflgs, "NoTypeHint", bool_flag) != NULL); } /* * Return TRUE if the PyQt4 plugin was specified. */ int pluginPyQt4(sipSpec *pt) { return stringFind(pt->plugins, "PyQt4"); } /* * Return TRUE if the PyQt5 plugin was specified. */ int pluginPyQt5(sipSpec *pt) { return stringFind(pt->plugins, "PyQt5"); } /* * 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; typeHintDef *in, *out; getTypeHints(of, &in, &out); cd = newClass(currentSpec, class_iface, getAPIRange(of), fullyQualifiedName(snd), getVirtErrorHandler(of), in, out, getTypeHintValue(of)); cd->supers = supers; pushScope(cd); } /* * Return a fully qualified scoped name. */ static scopedNameDef *fullyQualifiedName(scopedNameDef *snd) { classDef *scope = currentScope(); return scopeScopedName((scope != NULL ? scope->iff : NULL), snd); } /* * 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); getTypeHints(flags, &ad->typehint_in, &ad->typehint_out); if (getOptFlag(flags, "PyInt", bool_flag) != NULL) { if (ad->atype == string_type) ad->atype = byte_type; else if (ad->atype == sstring_type) ad->atype = sbyte_type; else if (ad->atype == ustring_type) ad->atype = ubyte_type; } if (ad->atype == string_type && !isArray(ad) && !isReference(ad)) { optFlag *of; if ((of = getOptFlag(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 keyword argument support converted from a string. */ static KwArgs convertKwArgs(const char *kwargs) { if (strcmp(kwargs, "None") == 0) return NoKwArgs; if (strcmp(kwargs, "All") == 0) return AllKwArgs; if (strcmp(kwargs, "Optional") == 0) return OptionalKwArgs; yyerror("The style of keyword argument support must be one of \"All\", \"Optional\" or \"None\""); } /* * Return the Format for a string. */ static Format convertFormat(const char *format) { if (strcmp(format, "raw") == 0) return raw; if (strcmp(format, "deindented") == 0) return deindented; yyerror("The docstring format must be either \"raw\" or \"deindented\""); } /* * Return the Signature for a string. */ static Signature convertSignature(const char *signature) { if (strcmp(signature, "discarded") == 0) return discarded; if (strcmp(signature, "prepended") == 0) return prepended; if (strcmp(signature, "appended") == 0) return appended; yyerror("The docstring signature must be either \"discarded\", \"prepended\" or \"appended\""); } /* * 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 = getOptFlag(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 the style of keyword argument support for a signature. */ static KwArgs keywordArgs(moduleDef *mod, optFlags *optflgs, signatureDef *sd, int need_name) { KwArgs kwargs; optFlag *ka_anno, *no_ka_anno; /* Get the default. */ kwargs = mod->kwargs; /* * Get the possible annotations allowing /KeywordArgs/ to have different * types of values. */ ka_anno = findOptFlag(optflgs, "KeywordArgs"); no_ka_anno = getOptFlag(optflgs, "NoKeywordArgs", bool_flag); if (no_ka_anno != NULL) { if (ka_anno != NULL) yyerror("/KeywordArgs/ and /NoKeywordArgs/ cannot both be specified"); deprecated("/NoKeywordArgs/ is deprecated, use /KeywordArgs=\"None\" instead"); kwargs = NoKwArgs; } else if (ka_anno != NULL) { /* A string value is the non-deprecated type. */ if (ka_anno->ftype == string_flag) { kwargs = convertKwArgs(ka_anno->fvalue.sval); } else { deprecated("/KeywordArgs/ is deprecated, use /KeywordArgs=\"All\" instead"); /* Get it again to check the type. */ ka_anno = getOptFlag(optflgs, "KeywordArgs", bool_flag); } } /* An ellipsis cannot be used with keyword arguments. */ if (sd->nrArgs > 0 && sd->args[sd->nrArgs - 1].atype == ellipsis_type) kwargs = NoKwArgs; if (kwargs != NoKwArgs) { 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) { argDef *ad = &sd->args[a]; if (kwargs == OptionalKwArgs && ad->defval == NULL) continue; if (ad->name != NULL) { if (need_name || inMainModule()) setIsUsedName(ad->name); is_name = TRUE; } } if (!is_name) kwargs = NoKwArgs; } return kwargs; } /* * 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); } /* * Add a property definition to a class. */ static void addProperty(sipSpec *pt, moduleDef *mod, classDef *cd, const char *name, const char *get, const char *set, docstringDef *docstring) { propertyDef *pd; checkAttributes(pt, mod, cd, NULL, name, FALSE); pd = sipMalloc(sizeof (propertyDef)); pd->name = cacheName(pt, name); pd->get = get; pd->set = set; pd->docstring = docstring; pd->platforms = currentPlatforms; pd->next = cd->properties; cd->properties = pd; if (inMainModule()) setIsUsedName(pd->name); } /* * Configure a module and return the (possibly new) current module. */ static moduleDef *configureModule(sipSpec *pt, moduleDef *module, const char *filename, const char *name, int c_module, KwArgs kwargs, int use_arg_names, int use_limited_api, int call_super_init, int all_raise_py_exc, const char *def_error_handler, docstringDef *docstring) { moduleDef *mod; /* Check the module hasn't already been defined. */ for (mod = pt->modules; mod != NULL; mod = mod->next) if (mod->fullname != NULL && strcmp(mod->fullname->text, name) == 0) yyerror("Module is already defined"); /* * If we are in a container module then create a component module and make * it current. */ if (isContainer(module) || module->container != NULL) { mod = allocModule(); mod->file = filename; mod->container = (isContainer(module) ? module : module->container); module = mod; } setModuleName(pt, module, name); module->kwargs = kwargs; module->virt_error_handler = def_error_handler; module->docstring = docstring; if (all_raise_py_exc) setAllRaisePyException(module); if (use_arg_names) setUseArgNames(module); if (use_limited_api) setUseLimitedAPI(module); if (call_super_init == 0) setCallSuperInitNo(module); else if (call_super_init > 0) setCallSuperInitYes(module); if (pt->genc < 0) pt->genc = c_module; else if (pt->genc != c_module) yyerror("Cannot mix C and C++ modules"); return module; } /* * Add a Python naming rule to a module. */ static void addAutoPyName(moduleDef *mod, const char *remove_leading) { autoPyNameDef *apnd, **apndp; for (apndp = &mod->autopyname; *apndp != NULL; apndp = &(*apndp)->next) ; apnd = sipMalloc(sizeof (autoPyNameDef)); apnd->remove_leading = remove_leading; apnd->next = *apndp; *apndp = apnd; } /* * Check that no invalid or unknown annotations are given. */ static void checkAnnos(optFlags *annos, const char *valid[]) { if (parsingCSignature && annos->nrFlags != 0) { deprecated("Annotations should not be used in explicit C/C++ signatures"); } else { int i; for (i = 0; i < annos->nrFlags; i++) { const char **name; for (name = valid; *name != NULL; ++name) if (strcmp(*name, annos->flags[i].fname) == 0) break; if (*name == NULL) yywarning("Annotation is unknown"); } } } /* * Check that no annotations were given. */ static void checkNoAnnos(optFlags *annos, const char *msg) { if (annos->nrFlags != 0) deprecated(msg); } /* * Handle any /KeepReference/ annotation for a type. */ static void handleKeepReference(optFlags *optflgs, argDef *ad, moduleDef *mod) { optFlag *of; if ((of = getOptFlag(optflgs, "KeepReference", opt_integer_flag)) != NULL) { setKeepReference(ad); if ((ad->key = of->fvalue.ival) < -1) yyerror("/KeepReference/ key cannot be negative"); /* If there was no explicit key then auto-allocate one. */ if (ad->key == -1) ad->key = mod->next_key--; } } /* * Configure the mapped type annotations that are also valid with mapped type * templates. */ static void mappedTypeAnnos(mappedTypeDef *mtd, optFlags *optflgs) { if (getOptFlag(optflgs, "NoRelease", bool_flag) != NULL) setNoRelease(mtd); if (getAllowNone(optflgs)) setHandlesNone(mtd); mtd->doctype = getDocType(optflgs); getTypeHints(optflgs, &mtd->typehint_in, &mtd->typehint_out); mtd->typehint_value = getTypeHintValue(optflgs); } /* * Initialise an argument with the derefences of another, plus a new one. */ static void add_new_deref(argDef *new, argDef *orig, int isconst) { if ((new->nrderefs = orig->nrderefs + 1) >= MAX_NR_DEREFS) yyerror("Internal error - increase the value of MAX_NR_DEREFS"); memcpy(&new->derefs[0], &orig->derefs[0], sizeof (new->derefs)); new->derefs[orig->nrderefs] = isconst; } /* * Add the dereferences from one type to another. */ static void add_derefs(argDef *dst, argDef *src) { int i; for (i = 0; i < src->nrderefs; ++i) { if (dst->nrderefs >= MAX_NR_DEREFS - 1) fatal("Internal error - increase the value of MAX_NR_DEREFS\n"); dst->derefs[dst->nrderefs++] = src->derefs[i]; } } /* * Check if a word is a Python keyword (or has been at any time). */ int isPyKeyword(const char *word) { static const char *kwds[] = { "False", "None", "True", "and", "as", "assert", "break", "class", "continue", "def", "del", "elif", "else", "except", "finally", "for", "from", "global", "if", "import", "in", "is", "lambda", "nonlocal", "not", "or", "pass", "raise", "return", "try", "while", "with'" "yield", /* Historical keywords. */ "exec", "print", NULL }; const char **kwd; for (kwd = kwds; *kwd != NULL; ++kwd) if (strcmp(*kwd, word) == 0) return TRUE; return FALSE; } /* * Check there is nothing after an ellipsis. */ static void checkEllipsis(signatureDef *sd) { int a; for (a = 0; a < sd->nrArgs; ++a) if (sd->args[a].atype == ellipsis_type && a < sd->nrArgs - 1) yyerror("An ellipsis must be at the end of the argument list if /NoArgParser/ is not specified"); } sip-4.19.7/sipgen/metasrc/README0000644000076500000240000000072713231604405016275 0ustar philstaff00000000000000This directory contains meta-source files for flex and bison. To support platforms that don't come with flex and bison installed we ship the generated .c files. We put them in a sub-directory to avoid problems with default Makefile rules accidentally recreating the .c files using the wrong tools. If you want to recreate the .c files then change to this directory and run the following commands: flex -o../lexer.c lexer.l bison -y -d -o ../parser.c parser.y sip-4.19.7/sipgen/parser.c0000644000076500000240000147342413231604431015427 0ustar philstaff00000000000000/* A Bison parser, made by GNU Bison 2.3. */ /* 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 2, 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* 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.3" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 0 /* Using locations. */ #define YYLSP_NEEDED 0 /* 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_AUTOPYNAME = 259, TK_DEFDOCSTRFMT = 260, TK_DEFDOCSTRSIG = 261, TK_DEFENCODING = 262, TK_PLUGIN = 263, TK_VIRTERRORHANDLER = 264, TK_EXPTYPEHINTCODE = 265, TK_TYPEHINTCODE = 266, TK_DOCSTRING = 267, TK_DOC = 268, TK_EXPORTEDDOC = 269, TK_EXTRACT = 270, TK_MAKEFILE = 271, TK_ACCESSCODE = 272, TK_GETCODE = 273, TK_SETCODE = 274, TK_PREINITCODE = 275, TK_INITCODE = 276, TK_POSTINITCODE = 277, TK_FINALCODE = 278, TK_UNITCODE = 279, TK_UNITPOSTINCLUDECODE = 280, TK_MODCODE = 281, TK_TYPECODE = 282, TK_PREPYCODE = 283, TK_COPYING = 284, TK_MAPPEDTYPE = 285, TK_CODELINE = 286, TK_IF = 287, TK_END = 288, TK_NAME_VALUE = 289, TK_PATH_VALUE = 290, TK_STRING_VALUE = 291, TK_VIRTUALCATCHERCODE = 292, TK_TRAVERSECODE = 293, TK_CLEARCODE = 294, TK_GETBUFFERCODE = 295, TK_RELEASEBUFFERCODE = 296, TK_READBUFFERCODE = 297, TK_WRITEBUFFERCODE = 298, TK_SEGCOUNTCODE = 299, TK_CHARBUFFERCODE = 300, TK_PICKLECODE = 301, TK_VIRTUALCALLCODE = 302, TK_METHODCODE = 303, TK_PREMETHODCODE = 304, TK_INSTANCECODE = 305, TK_FROMTYPE = 306, TK_TOTYPE = 307, TK_TOSUBCLASS = 308, TK_INCLUDE = 309, TK_OPTINCLUDE = 310, TK_IMPORT = 311, TK_EXPHEADERCODE = 312, TK_MODHEADERCODE = 313, TK_TYPEHEADERCODE = 314, TK_MODULE = 315, TK_CMODULE = 316, TK_CONSMODULE = 317, TK_COMPOMODULE = 318, TK_CLASS = 319, TK_STRUCT = 320, TK_PUBLIC = 321, TK_PROTECTED = 322, TK_PRIVATE = 323, TK_SIGNALS = 324, TK_SIGNAL_METHOD = 325, TK_SLOTS = 326, TK_SLOT_METHOD = 327, TK_BOOL = 328, TK_SHORT = 329, TK_INT = 330, TK_LONG = 331, TK_FLOAT = 332, TK_DOUBLE = 333, TK_CHAR = 334, TK_WCHAR_T = 335, TK_VOID = 336, TK_PYOBJECT = 337, TK_PYTUPLE = 338, TK_PYLIST = 339, TK_PYDICT = 340, TK_PYCALLABLE = 341, TK_PYSLICE = 342, TK_PYTYPE = 343, TK_PYBUFFER = 344, TK_VIRTUAL = 345, TK_ENUM = 346, TK_SIGNED = 347, TK_UNSIGNED = 348, TK_SCOPE = 349, TK_LOGICAL_OR = 350, TK_CONST = 351, TK_STATIC = 352, TK_SIPSIGNAL = 353, TK_SIPSLOT = 354, TK_SIPANYSLOT = 355, TK_SIPRXCON = 356, TK_SIPRXDIS = 357, TK_SIPSLOTCON = 358, TK_SIPSLOTDIS = 359, TK_SIPSSIZET = 360, TK_NUMBER_VALUE = 361, TK_REAL_VALUE = 362, TK_TYPEDEF = 363, TK_NAMESPACE = 364, TK_TIMELINE = 365, TK_PLATFORMS = 366, TK_FEATURE = 367, TK_LICENSE = 368, TK_QCHAR_VALUE = 369, TK_TRUE_VALUE = 370, TK_FALSE_VALUE = 371, TK_NULL_VALUE = 372, TK_OPERATOR = 373, TK_THROW = 374, TK_QOBJECT = 375, TK_EXCEPTION = 376, TK_RAISECODE = 377, TK_VIRTERRORCODE = 378, TK_EXPLICIT = 379, TK_TEMPLATE = 380, TK_FINAL = 381, TK_ELLIPSIS = 382, TK_DEFMETATYPE = 383, TK_DEFSUPERTYPE = 384, TK_PROPERTY = 385, TK_HIDE_NS = 386, TK_FORMAT = 387, TK_GET = 388, TK_ID = 389, TK_KWARGS = 390, TK_LANGUAGE = 391, TK_LICENSEE = 392, TK_NAME = 393, TK_OPTIONAL = 394, TK_ORDER = 395, TK_REMOVELEADING = 396, TK_SET = 397, TK_SIGNATURE = 398, TK_TIMESTAMP = 399, TK_TYPE = 400, TK_USEARGNAMES = 401, TK_USELIMITEDAPI = 402, TK_ALLRAISEPYEXC = 403, TK_CALLSUPERINIT = 404, TK_DEFERRORHANDLER = 405, TK_VERSION = 406 }; #endif /* Tokens. */ #define TK_API 258 #define TK_AUTOPYNAME 259 #define TK_DEFDOCSTRFMT 260 #define TK_DEFDOCSTRSIG 261 #define TK_DEFENCODING 262 #define TK_PLUGIN 263 #define TK_VIRTERRORHANDLER 264 #define TK_EXPTYPEHINTCODE 265 #define TK_TYPEHINTCODE 266 #define TK_DOCSTRING 267 #define TK_DOC 268 #define TK_EXPORTEDDOC 269 #define TK_EXTRACT 270 #define TK_MAKEFILE 271 #define TK_ACCESSCODE 272 #define TK_GETCODE 273 #define TK_SETCODE 274 #define TK_PREINITCODE 275 #define TK_INITCODE 276 #define TK_POSTINITCODE 277 #define TK_FINALCODE 278 #define TK_UNITCODE 279 #define TK_UNITPOSTINCLUDECODE 280 #define TK_MODCODE 281 #define TK_TYPECODE 282 #define TK_PREPYCODE 283 #define TK_COPYING 284 #define TK_MAPPEDTYPE 285 #define TK_CODELINE 286 #define TK_IF 287 #define TK_END 288 #define TK_NAME_VALUE 289 #define TK_PATH_VALUE 290 #define TK_STRING_VALUE 291 #define TK_VIRTUALCATCHERCODE 292 #define TK_TRAVERSECODE 293 #define TK_CLEARCODE 294 #define TK_GETBUFFERCODE 295 #define TK_RELEASEBUFFERCODE 296 #define TK_READBUFFERCODE 297 #define TK_WRITEBUFFERCODE 298 #define TK_SEGCOUNTCODE 299 #define TK_CHARBUFFERCODE 300 #define TK_PICKLECODE 301 #define TK_VIRTUALCALLCODE 302 #define TK_METHODCODE 303 #define TK_PREMETHODCODE 304 #define TK_INSTANCECODE 305 #define TK_FROMTYPE 306 #define TK_TOTYPE 307 #define TK_TOSUBCLASS 308 #define TK_INCLUDE 309 #define TK_OPTINCLUDE 310 #define TK_IMPORT 311 #define TK_EXPHEADERCODE 312 #define TK_MODHEADERCODE 313 #define TK_TYPEHEADERCODE 314 #define TK_MODULE 315 #define TK_CMODULE 316 #define TK_CONSMODULE 317 #define TK_COMPOMODULE 318 #define TK_CLASS 319 #define TK_STRUCT 320 #define TK_PUBLIC 321 #define TK_PROTECTED 322 #define TK_PRIVATE 323 #define TK_SIGNALS 324 #define TK_SIGNAL_METHOD 325 #define TK_SLOTS 326 #define TK_SLOT_METHOD 327 #define TK_BOOL 328 #define TK_SHORT 329 #define TK_INT 330 #define TK_LONG 331 #define TK_FLOAT 332 #define TK_DOUBLE 333 #define TK_CHAR 334 #define TK_WCHAR_T 335 #define TK_VOID 336 #define TK_PYOBJECT 337 #define TK_PYTUPLE 338 #define TK_PYLIST 339 #define TK_PYDICT 340 #define TK_PYCALLABLE 341 #define TK_PYSLICE 342 #define TK_PYTYPE 343 #define TK_PYBUFFER 344 #define TK_VIRTUAL 345 #define TK_ENUM 346 #define TK_SIGNED 347 #define TK_UNSIGNED 348 #define TK_SCOPE 349 #define TK_LOGICAL_OR 350 #define TK_CONST 351 #define TK_STATIC 352 #define TK_SIPSIGNAL 353 #define TK_SIPSLOT 354 #define TK_SIPANYSLOT 355 #define TK_SIPRXCON 356 #define TK_SIPRXDIS 357 #define TK_SIPSLOTCON 358 #define TK_SIPSLOTDIS 359 #define TK_SIPSSIZET 360 #define TK_NUMBER_VALUE 361 #define TK_REAL_VALUE 362 #define TK_TYPEDEF 363 #define TK_NAMESPACE 364 #define TK_TIMELINE 365 #define TK_PLATFORMS 366 #define TK_FEATURE 367 #define TK_LICENSE 368 #define TK_QCHAR_VALUE 369 #define TK_TRUE_VALUE 370 #define TK_FALSE_VALUE 371 #define TK_NULL_VALUE 372 #define TK_OPERATOR 373 #define TK_THROW 374 #define TK_QOBJECT 375 #define TK_EXCEPTION 376 #define TK_RAISECODE 377 #define TK_VIRTERRORCODE 378 #define TK_EXPLICIT 379 #define TK_TEMPLATE 380 #define TK_FINAL 381 #define TK_ELLIPSIS 382 #define TK_DEFMETATYPE 383 #define TK_DEFSUPERTYPE 384 #define TK_PROPERTY 385 #define TK_HIDE_NS 386 #define TK_FORMAT 387 #define TK_GET 388 #define TK_ID 389 #define TK_KWARGS 390 #define TK_LANGUAGE 391 #define TK_LICENSEE 392 #define TK_NAME 393 #define TK_OPTIONAL 394 #define TK_ORDER 395 #define TK_REMOVELEADING 396 #define TK_SET 397 #define TK_SIGNATURE 398 #define TK_TIMESTAMP 399 #define TK_TYPE 400 #define TK_USEARGNAMES 401 #define TK_USELIMITEDAPI 402 #define TK_ALLRAISEPYEXC 403 #define TK_CALLSUPERINIT 404 #define TK_DEFERRORHANDLER 405 #define TK_VERSION 406 /* Copy the first part of user declarations. */ #line 19 "sip-4.19.7/sipgen/metasrc/parser.y" #include #include #include #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 int strictParse; /* Set if the platform is enforced. */ static stringList *backstops; /* The list of backstops. */ 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 stackPtr; /* The 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 platformDef *currentPlatforms; /* The current platforms list. */ static platformDef *platformStack[MAX_NESTED_IF]; /* Stack of platforms. */ static KwArgs defaultKwArgs; /* The default keyword arguments support. */ static int makeProtPublic; /* Treat protected items as public. */ static int parsingCSignature; /* An explicit C/C++ signature is being parsed. */ static const char *getPythonName(moduleDef *mod, optFlags *optflgs, const char *cname); static classDef *findClass(sipSpec *pt, ifaceFileType iftype, apiVersionRangeDef *api_range, scopedNameDef *fqname, int tmpl_arg); static classDef *findClassWithInterface(sipSpec *pt, ifaceFileDef *iff, int tmpl_arg); static classDef *newClass(sipSpec *pt, ifaceFileType iftype, apiVersionRangeDef *api_range, scopedNameDef *snd, const char *virt_error_handler, typeHintDef *typehint_in, typeHintDef *typehint_out, const char *typehint_value); 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, int isscoped); static void instantiateClassTemplate(sipSpec *pt, moduleDef *mod, classDef *scope, scopedNameDef *fqname, classTmplDef *tcd, templateDef *td, const char *pyname, int use_template_name, docstringDef *docstring); static void newTypedef(sipSpec *, moduleDef *, char *, argDef *, optFlags *, docstringDef *); static void newVar(sipSpec *pt, moduleDef *mod, char *name, int isstatic, argDef *type, optFlags *of, codeBlock *acode, codeBlock *gcode, codeBlock *scode, int section); static void newCtor(moduleDef *, char *, int, signatureDef *, optFlags *, codeBlock *, throwArgs *, signatureDef *, int, docstringDef *, codeBlock *); static void newFunction(sipSpec *, moduleDef *, classDef *, ifaceFileDef *, mappedTypeDef *, int, int, int, int, int, char *, signatureDef *, int, int, optFlags *, codeBlock *, codeBlock *, codeBlock *, throwArgs *, signatureDef *, docstringDef *, int, codeBlock *); static optFlag *findOptFlag(optFlags *flgs, const char *name); static optFlag *getOptFlag(optFlags *flgs, const char *name, flagType ft); static memberDef *findFunction(sipSpec *, moduleDef *, classDef *, ifaceFileDef *, mappedTypeDef *, const char *, int, int, int); static void checkAttributes(sipSpec *, moduleDef *, classDef *, mappedTypeDef *, const char *, int); static void newModule(FILE *fp, const char *filename); static moduleDef *allocModule(); static void parseFile(FILE *fp, const char *name, moduleDef *prevmod, int optional); static void handleEOF(void); static void handleEOM(void); static qualDef *findQualifier(const char *name); static const char *getInt(const char *cp, int *ip); 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, int, const char *, qualType); static qualDef *allocQualifier(moduleDef *, int, int, int, const char *, qualType); static void newImport(const char *filename); static int timePeriod(const char *lname, const char *uname); static int platOrFeature(char *name, int optnot); static void addPlatform(qualDef *qd); 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 int getDisallowNone(optFlags *optflgs); static const char *getVirtErrorHandler(optFlags *optflgs); static const char *getDocType(optFlags *optflgs); static const char *getTypeHintValue(optFlags *optflgs); static void getTypeHints(optFlags *optflgs, typeHintDef **in, typeHintDef **out); static int getNoTypeHint(optFlags *optflgs); static void templateSignature(signatureDef *sd, int result, classTmplDef *tcd, templateDef *td, classDef *ncd, scopedNameDef *type_names, scopedNameDef *type_values); static void templateType(argDef *ad, classTmplDef *tcd, templateDef *td, classDef *ncd, scopedNameDef *type_names, scopedNameDef *type_values); 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 void instantiateTemplateTypedefs(sipSpec *pt, classTmplDef *tcd, templateDef *td, classDef *cd, 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 addTypedef(sipSpec *pt, typedefDef *tdd); static void addVariable(sipSpec *pt, varDef *vd); static void applyTypeFlags(moduleDef *mod, argDef *ad, optFlags *flags); static Format convertFormat(const char *format); static Signature convertSignature(const char *signature); 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 KwArgs keywordArgs(moduleDef *mod, optFlags *optflgs, signatureDef *sd, int need_name); static char *strip(char *s); static int isEnabledFeature(const char *name); static void addProperty(sipSpec *pt, moduleDef *mod, classDef *cd, const char *name, const char *get, const char *set, docstringDef *docstring); static moduleDef *configureModule(sipSpec *pt, moduleDef *module, const char *filename, const char *name, int c_module, KwArgs kwargs, int use_arg_names, int use_limited_api, int call_super_init, int all_raise_py_exc, const char *def_error_handler, docstringDef *docstring); static void addAutoPyName(moduleDef *mod, const char *remove_leading); static KwArgs convertKwArgs(const char *kwargs); static void checkAnnos(optFlags *annos, const char *valid[]); static void checkNoAnnos(optFlags *annos, const char *msg); static void appendCodeBlock(codeBlockList **headp, codeBlock *cb); static void handleKeepReference(optFlags *optflgs, argDef *ad, moduleDef *mod); static void mappedTypeAnnos(mappedTypeDef *mtd, optFlags *optflgs); static void add_new_deref(argDef *new, argDef *orig, int isconst); static void add_derefs(argDef *dst, argDef *src); static int isBackstop(qualDef *qd); static void checkEllipsis(signatureDef *sd); static scopedNameDef *fullyQualifiedName(scopedNameDef *snd); /* 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 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 203 "sip-4.19.7/sipgen/metasrc/parser.y" { char qchar; char *text; long number; double real; argDef memArg; signatureDef signature; signatureDef *optsignature; throwArgs *throwlist; codeBlock *codeb; docstringDef *docstr; valueDef value; valueDef *valp; optFlags optflags; optFlag flag; scopedNameDef *scpvalp; fcallDef fcall; int boolean; exceptionDef exceptionbase; classDef *klass; apiCfg api; autoPyNameCfg autopyname; compModuleCfg compmodule; consModuleCfg consmodule; defDocstringFmtCfg defdocstringfmt; defDocstringSigCfg defdocstringsig; defEncodingCfg defencoding; defMetatypeCfg defmetatype; defSupertypeCfg defsupertype; hiddenNsCfg hiddenns; exceptionCfg exception; docstringCfg docstring; extractCfg extract; featureCfg feature; licenseCfg license; importCfg import; includeCfg include; moduleCfg module; pluginCfg plugin; propertyCfg property; variableCfg variable; vehCfg veh; int token; } /* Line 193 of yacc.c. */ #line 627 "sip-4.19.7/sipgen/parser.c" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif /* Copy the second part of user declarations. */ /* Line 216 of yacc.c. */ #line 640 "sip-4.19.7/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 /* 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 defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* 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 i) #else static int YYID (i) int i; #endif { return i; } #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 /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* 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 /* 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 /* 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; YYSTYPE yyvs; }; /* 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) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack, Stack, yysize); \ Stack = &yyptr->Stack; \ 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 1611 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 174 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 254 /* YYNRULES -- Number of rules. */ #define YYNRULES 594 /* YYNRULES -- Number of states. */ #define YYNSTATES 1042 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 406 #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, 159, 2, 2, 2, 172, 164, 2, 152, 153, 162, 161, 154, 160, 2, 163, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 169, 158, 167, 155, 168, 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, 170, 2, 171, 173, 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, 156, 165, 157, 166, 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, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151 }; #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, 98, 100, 102, 104, 106, 108, 110, 112, 115, 117, 121, 123, 127, 131, 134, 136, 140, 142, 146, 150, 153, 155, 159, 161, 165, 169, 172, 174, 178, 180, 184, 188, 192, 194, 198, 200, 204, 208, 211, 214, 218, 220, 224, 228, 232, 238, 239, 243, 248, 250, 253, 255, 257, 259, 261, 264, 265, 271, 272, 279, 284, 286, 289, 291, 293, 295, 297, 300, 303, 305, 307, 309, 324, 325, 331, 332, 336, 338, 341, 342, 348, 350, 353, 355, 358, 360, 364, 366, 370, 374, 375, 381, 383, 386, 388, 389, 395, 397, 400, 404, 409, 411, 415, 417, 421, 422, 424, 428, 430, 434, 438, 442, 446, 450, 453, 455, 459, 461, 465, 469, 472, 474, 478, 480, 484, 488, 491, 493, 497, 499, 503, 507, 511, 513, 517, 519, 523, 527, 528, 533, 535, 538, 540, 542, 544, 548, 550, 554, 556, 560, 564, 565, 570, 572, 575, 577, 579, 581, 585, 589, 590, 594, 598, 600, 604, 608, 612, 616, 620, 624, 628, 632, 636, 640, 641, 646, 648, 651, 653, 655, 657, 659, 661, 663, 664, 666, 669, 671, 675, 677, 681, 685, 689, 692, 695, 697, 701, 703, 707, 711, 712, 715, 716, 719, 720, 723, 726, 729, 732, 735, 738, 741, 744, 747, 750, 753, 756, 759, 762, 765, 768, 771, 774, 777, 780, 783, 786, 789, 792, 795, 798, 801, 804, 807, 810, 814, 816, 820, 824, 828, 829, 831, 835, 837, 841, 845, 849, 850, 852, 856, 858, 862, 864, 868, 872, 876, 881, 884, 886, 889, 890, 900, 901, 903, 905, 906, 908, 909, 911, 912, 914, 916, 919, 921, 923, 928, 929, 931, 932, 935, 936, 939, 941, 945, 947, 949, 951, 953, 955, 957, 958, 960, 962, 964, 966, 968, 970, 974, 975, 979, 982, 984, 986, 990, 992, 994, 996, 998, 1003, 1005, 1007, 1009, 1011, 1013, 1015, 1016, 1018, 1022, 1029, 1042, 1043, 1044, 1053, 1054, 1058, 1063, 1064, 1065, 1074, 1075, 1078, 1080, 1084, 1087, 1088, 1090, 1092, 1094, 1095, 1099, 1100, 1102, 1105, 1107, 1109, 1111, 1113, 1115, 1117, 1119, 1121, 1123, 1125, 1127, 1129, 1131, 1133, 1135, 1137, 1139, 1141, 1143, 1145, 1147, 1149, 1151, 1153, 1155, 1157, 1159, 1161, 1164, 1167, 1170, 1174, 1178, 1182, 1185, 1189, 1193, 1195, 1199, 1203, 1207, 1211, 1212, 1217, 1219, 1222, 1224, 1226, 1228, 1230, 1232, 1233, 1235, 1248, 1249, 1253, 1255, 1267, 1268, 1269, 1276, 1277, 1278, 1286, 1287, 1289, 1307, 1315, 1333, 1350, 1352, 1354, 1356, 1358, 1360, 1362, 1364, 1366, 1369, 1372, 1375, 1378, 1381, 1384, 1387, 1390, 1393, 1396, 1400, 1404, 1406, 1409, 1412, 1414, 1417, 1420, 1423, 1425, 1428, 1429, 1431, 1432, 1434, 1435, 1438, 1439, 1443, 1445, 1449, 1451, 1455, 1457, 1463, 1465, 1467, 1468, 1471, 1472, 1475, 1476, 1479, 1480, 1483, 1485, 1486, 1488, 1492, 1497, 1502, 1507, 1511, 1515, 1522, 1529, 1533, 1536, 1537, 1541, 1542, 1546, 1548, 1549, 1553, 1555, 1557, 1559, 1560, 1564, 1566, 1575, 1576, 1580, 1582, 1585, 1587, 1589, 1592, 1595, 1598, 1603, 1607, 1611, 1612, 1614, 1615, 1619, 1622, 1624, 1629, 1632, 1635, 1637, 1639, 1642, 1644, 1646, 1649, 1652, 1656, 1658, 1660, 1662, 1665, 1668, 1670, 1672, 1674, 1676, 1678, 1680, 1682, 1684, 1686, 1688, 1690, 1692, 1694, 1696, 1700, 1701, 1706, 1707, 1709 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int16 yyrhs[] = { 175, 0, -1, 176, -1, 175, 176, -1, -1, 177, 178, -1, 269, -1, 255, -1, 262, -1, 192, -1, 291, -1, 279, -1, 283, -1, 284, -1, 200, -1, 230, -1, 222, -1, 226, -1, 239, -1, 180, -1, 184, -1, 188, -1, 243, -1, 247, -1, 251, -1, 292, -1, 293, -1, 306, -1, 308, -1, 309, -1, 310, -1, 311, -1, 312, -1, 313, -1, 314, -1, 315, -1, 317, -1, 318, -1, 328, -1, 332, -1, 210, -1, 212, -1, 196, -1, 179, -1, 234, -1, 238, -1, 218, -1, 358, -1, 364, -1, 361, -1, 204, -1, 357, -1, 335, -1, 392, -1, 416, -1, 294, -1, 5, 181, -1, 36, -1, 152, 182, 153, -1, 183, -1, 182, 154, 183, -1, 138, 155, 36, -1, 6, 185, -1, 36, -1, 152, 186, 153, -1, 187, -1, 186, 154, 187, -1, 138, 155, 36, -1, 7, 189, -1, 36, -1, 152, 190, 153, -1, 191, -1, 190, 154, 191, -1, 138, 155, 36, -1, 8, 193, -1, 34, -1, 152, 194, 153, -1, 195, -1, 194, 154, 195, -1, 138, 155, 34, -1, 9, 197, 333, -1, 34, -1, 152, 198, 153, -1, 199, -1, 198, 154, 199, -1, 138, 155, 34, -1, 3, 201, -1, 34, 106, -1, 152, 202, 153, -1, 203, -1, 202, 154, 203, -1, 138, 155, 381, -1, 151, 155, 106, -1, 121, 351, 205, 397, 206, -1, -1, 152, 351, 153, -1, 156, 207, 157, 158, -1, 208, -1, 207, 208, -1, 234, -1, 238, -1, 209, -1, 294, -1, 122, 333, -1, -1, 30, 424, 397, 211, 214, -1, -1, 363, 30, 424, 397, 213, 214, -1, 156, 215, 157, 158, -1, 216, -1, 215, 216, -1, 234, -1, 238, -1, 294, -1, 307, -1, 51, 333, -1, 52, 333, -1, 303, -1, 335, -1, 217, -1, 97, 420, 34, 152, 405, 153, 394, 426, 397, 389, 158, 327, 403, 402, -1, -1, 109, 34, 219, 220, 158, -1, -1, 156, 221, 157, -1, 179, -1, 221, 179, -1, -1, 111, 223, 156, 224, 157, -1, 225, -1, 224, 225, -1, 34, -1, 112, 227, -1, 34, -1, 152, 228, 153, -1, 229, -1, 228, 154, 229, -1, 138, 155, 381, -1, -1, 110, 231, 156, 232, 157, -1, 233, -1, 232, 233, -1, 34, -1, -1, 32, 152, 235, 237, 153, -1, 34, -1, 159, 34, -1, 236, 95, 34, -1, 236, 95, 159, 34, -1, 236, -1, 339, 160, 339, -1, 33, -1, 113, 240, 397, -1, -1, 36, -1, 152, 241, 153, -1, 242, -1, 241, 154, 242, -1, 145, 155, 36, -1, 137, 155, 36, -1, 143, 155, 36, -1, 144, 155, 36, -1, 128, 244, -1, 277, -1, 152, 245, 153, -1, 246, -1, 245, 154, 246, -1, 138, 155, 277, -1, 129, 248, -1, 277, -1, 152, 249, 153, -1, 250, -1, 249, 154, 250, -1, 138, 155, 277, -1, 131, 252, -1, 351, -1, 152, 253, 153, -1, 254, -1, 253, 154, 254, -1, 138, 155, 351, -1, 62, 256, 259, -1, 277, -1, 152, 257, 153, -1, 258, -1, 257, 154, 258, -1, 138, 155, 277, -1, -1, 156, 260, 157, 158, -1, 261, -1, 260, 261, -1, 234, -1, 238, -1, 323, -1, 63, 263, 266, -1, 277, -1, 152, 264, 153, -1, 265, -1, 264, 154, 265, -1, 138, 155, 277, -1, -1, 156, 267, 157, 158, -1, 268, -1, 267, 268, -1, 234, -1, 238, -1, 323, -1, 60, 270, 274, -1, 61, 277, 278, -1, -1, 277, 271, 278, -1, 152, 272, 153, -1, 273, -1, 272, 154, 273, -1, 135, 155, 36, -1, 136, 155, 36, -1, 138, 155, 277, -1, 146, 155, 354, -1, 147, 155, 354, -1, 148, 155, 354, -1, 149, 155, 354, -1, 150, 155, 34, -1, 151, 155, 106, -1, -1, 156, 275, 157, 158, -1, 276, -1, 275, 276, -1, 234, -1, 238, -1, 319, -1, 323, -1, 34, -1, 35, -1, -1, 106, -1, 54, 280, -1, 35, -1, 152, 281, 153, -1, 282, -1, 281, 154, 282, -1, 138, 155, 35, -1, 139, 155, 354, -1, 55, 35, -1, 56, 285, -1, 35, -1, 152, 286, 153, -1, 287, -1, 286, 154, 287, -1, 138, 155, 35, -1, -1, 17, 333, -1, -1, 18, 333, -1, -1, 19, 333, -1, 29, 333, -1, 57, 333, -1, 58, 333, -1, 59, 333, -1, 38, 333, -1, 39, 333, -1, 40, 333, -1, 41, 333, -1, 42, 333, -1, 43, 333, -1, 44, 333, -1, 45, 333, -1, 50, 333, -1, 46, 333, -1, 23, 333, -1, 26, 333, -1, 27, 333, -1, 20, 333, -1, 21, 333, -1, 22, 333, -1, 24, 333, -1, 25, 333, -1, 28, 333, -1, 10, 333, -1, 11, 333, -1, 11, 333, -1, 13, 333, -1, 14, 333, -1, 4, 320, -1, 152, 321, 153, -1, 322, -1, 321, 154, 322, -1, 141, 155, 36, -1, 12, 324, 333, -1, -1, 36, -1, 152, 325, 153, -1, 326, -1, 325, 154, 326, -1, 132, 155, 36, -1, 143, 155, 36, -1, -1, 323, -1, 15, 329, 333, -1, 34, -1, 152, 330, 153, -1, 331, -1, 330, 154, 331, -1, 134, 155, 34, -1, 140, 155, 106, -1, 16, 35, 338, 333, -1, 334, 33, -1, 31, -1, 334, 31, -1, -1, 91, 337, 339, 397, 336, 156, 340, 157, 158, -1, -1, 64, -1, 65, -1, -1, 35, -1, -1, 34, -1, -1, 341, -1, 342, -1, 341, 342, -1, 234, -1, 238, -1, 34, 344, 397, 343, -1, -1, 154, -1, -1, 155, 349, -1, -1, 155, 346, -1, 349, -1, 346, 347, 349, -1, 160, -1, 161, -1, 162, -1, 163, -1, 164, -1, 165, -1, -1, 159, -1, 166, -1, 160, -1, 161, -1, 162, -1, 164, -1, 350, 348, 355, -1, -1, 152, 351, 153, -1, 94, 352, -1, 352, -1, 353, -1, 352, 94, 353, -1, 34, -1, 115, -1, 116, -1, 351, -1, 424, 152, 356, 153, -1, 107, -1, 106, -1, 354, -1, 117, -1, 36, -1, 114, -1, -1, 346, -1, 356, 154, 346, -1, 108, 420, 34, 397, 158, 327, -1, 108, 420, 152, 162, 34, 153, 152, 425, 153, 397, 158, 327, -1, -1, -1, 65, 351, 359, 367, 397, 360, 371, 158, -1, -1, 363, 362, 364, -1, 125, 167, 425, 168, -1, -1, -1, 64, 351, 365, 367, 397, 366, 371, 158, -1, -1, 169, 368, -1, 369, -1, 368, 154, 369, -1, 370, 351, -1, -1, 66, -1, 67, -1, 68, -1, -1, 156, 372, 157, -1, -1, 373, -1, 372, 373, -1, 234, -1, 238, -1, 218, -1, 358, -1, 364, -1, 361, -1, 204, -1, 357, -1, 335, -1, 374, -1, 323, -1, 307, -1, 294, -1, 295, -1, 296, -1, 297, -1, 298, -1, 299, -1, 300, -1, 301, -1, 302, -1, 303, -1, 304, -1, 305, -1, 316, -1, 384, -1, 383, -1, 408, -1, 53, 333, -1, 52, 333, -1, 51, 333, -1, 66, 382, 169, -1, 67, 382, 169, -1, 68, 382, 169, -1, 69, 169, -1, 130, 375, 378, -1, 152, 376, 153, -1, 377, -1, 376, 154, 377, -1, 133, 155, 34, -1, 138, 155, 381, -1, 142, 155, 34, -1, -1, 156, 379, 157, 158, -1, 380, -1, 379, 380, -1, 234, -1, 238, -1, 323, -1, 34, -1, 36, -1, -1, 71, -1, 391, 166, 34, 152, 153, 426, 396, 397, 158, 403, 402, 404, -1, -1, 124, 385, 386, -1, 386, -1, 34, 152, 405, 153, 426, 397, 387, 158, 327, 403, 402, -1, -1, -1, 170, 388, 152, 405, 153, 171, -1, -1, -1, 170, 390, 420, 152, 405, 153, 171, -1, -1, 90, -1, 420, 34, 152, 405, 153, 394, 395, 426, 396, 397, 389, 158, 327, 403, 402, 404, 401, -1, 420, 118, 155, 152, 420, 153, 158, -1, 420, 118, 393, 152, 405, 153, 394, 395, 426, 396, 397, 389, 158, 403, 402, 404, 401, -1, 118, 420, 152, 405, 153, 394, 395, 426, 396, 397, 389, 158, 403, 402, 404, 401, -1, 161, -1, 160, -1, 162, -1, 163, -1, 172, -1, 164, -1, 165, -1, 173, -1, 167, 167, -1, 168, 168, -1, 161, 155, -1, 160, 155, -1, 162, 155, -1, 163, 155, -1, 172, 155, -1, 164, 155, -1, 165, 155, -1, 173, 155, -1, 167, 167, 155, -1, 168, 168, 155, -1, 166, -1, 152, 153, -1, 170, 171, -1, 167, -1, 167, 155, -1, 155, 155, -1, 159, 155, -1, 168, -1, 168, 155, -1, -1, 96, -1, -1, 126, -1, -1, 155, 106, -1, -1, 163, 398, 163, -1, 399, -1, 398, 154, 399, -1, 34, -1, 34, 155, 400, -1, 277, -1, 34, 169, 278, 160, 278, -1, 36, -1, 106, -1, -1, 47, 333, -1, -1, 48, 333, -1, -1, 49, 333, -1, -1, 37, 333, -1, 406, -1, -1, 407, -1, 406, 154, 407, -1, 98, 339, 397, 345, -1, 99, 339, 397, 345, -1, 100, 339, 397, 345, -1, 101, 339, 397, -1, 102, 339, 397, -1, 103, 152, 405, 153, 339, 397, -1, 104, 152, 405, 153, 339, 397, -1, 120, 339, 397, -1, 421, 345, -1, -1, 70, 409, 411, -1, -1, 72, 410, 411, -1, 411, -1, -1, 97, 412, 413, -1, 413, -1, 414, -1, 416, -1, -1, 90, 415, 392, -1, 392, -1, 420, 34, 397, 417, 158, 288, 289, 290, -1, -1, 156, 418, 157, -1, 419, -1, 418, 419, -1, 234, -1, 238, -1, 17, 333, -1, 18, 333, -1, 19, 333, -1, 96, 424, 423, 422, -1, 424, 423, 422, -1, 420, 339, 397, -1, -1, 164, -1, -1, 423, 162, 96, -1, 423, 162, -1, 351, -1, 351, 167, 425, 168, -1, 65, 351, -1, 93, 74, -1, 74, -1, 93, -1, 93, 75, -1, 75, -1, 76, -1, 93, 76, -1, 76, 76, -1, 93, 76, 76, -1, 77, -1, 78, -1, 73, -1, 92, 79, -1, 93, 79, -1, 79, -1, 80, -1, 81, -1, 82, -1, 83, -1, 84, -1, 85, -1, 86, -1, 87, -1, 88, -1, 89, -1, 105, -1, 127, -1, 420, -1, 425, 154, 420, -1, -1, 119, 152, 427, 153, -1, -1, 351, -1, 427, 154, 351, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { 0, 576, 576, 577, 580, 580, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 663, 669, 674, 679, 680, 690, 697, 703, 708, 713, 714, 724, 731, 740, 745, 750, 751, 761, 768, 779, 784, 789, 790, 800, 807, 836, 841, 846, 847, 857, 864, 890, 898, 903, 904, 915, 921, 929, 976, 980, 1087, 1092, 1093, 1104, 1107, 1110, 1124, 1140, 1145, 1145, 1168, 1168, 1235, 1249, 1250, 1253, 1254, 1255, 1259, 1263, 1272, 1281, 1290, 1291, 1294, 1309, 1309, 1346, 1347, 1350, 1351, 1354, 1354, 1383, 1384, 1387, 1393, 1399, 1404, 1409, 1410, 1420, 1427, 1427, 1453, 1454, 1457, 1463, 1463, 1482, 1485, 1488, 1491, 1496, 1497, 1502, 1510, 1547, 1555, 1561, 1566, 1567, 1580, 1588, 1596, 1604, 1614, 1625, 1630, 1635, 1636, 1646, 1653, 1664, 1669, 1674, 1675, 1685, 1692, 1704, 1709, 1714, 1715, 1725, 1732, 1752, 1757, 1762, 1763, 1773, 1780, 1784, 1789, 1790, 1800, 1803, 1806, 1820, 1838, 1843, 1848, 1849, 1859, 1866, 1870, 1875, 1876, 1886, 1889, 1892, 1906, 1917, 1927, 1927, 1940, 1945, 1946, 1963, 1975, 1993, 2005, 2017, 2029, 2041, 2053, 2065, 2084, 2088, 2093, 2094, 2104, 2107, 2110, 2113, 2127, 2128, 2144, 2147, 2150, 2159, 2165, 2170, 2171, 2182, 2188, 2196, 2204, 2210, 2215, 2220, 2221, 2231, 2238, 2241, 2246, 2249, 2254, 2257, 2262, 2268, 2274, 2280, 2285, 2290, 2295, 2300, 2305, 2310, 2315, 2320, 2325, 2330, 2335, 2340, 2346, 2351, 2357, 2363, 2369, 2375, 2381, 2386, 2392, 2398, 2403, 2409, 2415, 2421, 2426, 2427, 2437, 2444, 2528, 2532, 2538, 2543, 2544, 2555, 2561, 2569, 2572, 2575, 2584, 2590, 2595, 2596, 2607, 2613, 2624, 2629, 2632, 2633, 2643, 2643, 2667, 2670, 2673, 2678, 2681, 2686, 2689, 2694, 2695, 2698, 2699, 2702, 2703, 2704, 2743, 2744, 2747, 2748, 2751, 2754, 2759, 2760, 2778, 2781, 2784, 2787, 2790, 2793, 2798, 2801, 2804, 2807, 2810, 2813, 2816, 2821, 2836, 2839, 2844, 2850, 2853, 2854, 2862, 2867, 2870, 2875, 2884, 2894, 2898, 2902, 2906, 2910, 2914, 2920, 2925, 2931, 2949, 2971, 3010, 3016, 3010, 3059, 3059, 3085, 3090, 3096, 3090, 3135, 3136, 3139, 3140, 3143, 3195, 3198, 3201, 3204, 3209, 3212, 3217, 3218, 3219, 3222, 3223, 3224, 3225, 3226, 3227, 3228, 3229, 3230, 3231, 3232, 3243, 3247, 3251, 3262, 3273, 3284, 3295, 3306, 3317, 3328, 3339, 3350, 3361, 3372, 3383, 3384, 3385, 3386, 3397, 3408, 3419, 3426, 3433, 3440, 3449, 3462, 3467, 3468, 3480, 3487, 3494, 3503, 3507, 3512, 3513, 3523, 3526, 3529, 3543, 3544, 3547, 3550, 3555, 3619, 3619, 3620, 3623, 3669, 3672, 3672, 3683, 3686, 3686, 3698, 3701, 3706, 3724, 3744, 3788, 3869, 3870, 3871, 3872, 3873, 3874, 3875, 3876, 3877, 3878, 3879, 3880, 3881, 3882, 3883, 3884, 3885, 3886, 3887, 3888, 3889, 3890, 3891, 3892, 3893, 3894, 3895, 3896, 3897, 3900, 3903, 3908, 3911, 3916, 3919, 3927, 3930, 3936, 3940, 3952, 3956, 3962, 3966, 3989, 3993, 3999, 4002, 4007, 4010, 4015, 4018, 4023, 4026, 4031, 4083, 4088, 4094, 4117, 4129, 4141, 4153, 4172, 4183, 4200, 4217, 4226, 4233, 4233, 4234, 4234, 4235, 4239, 4239, 4240, 4244, 4245, 4249, 4249, 4250, 4253, 4308, 4314, 4319, 4320, 4332, 4335, 4338, 4353, 4368, 4385, 4390, 4404, 4507, 4510, 4518, 4521, 4524, 4529, 4537, 4548, 4563, 4567, 4571, 4575, 4579, 4583, 4587, 4591, 4595, 4599, 4603, 4607, 4611, 4615, 4619, 4623, 4627, 4631, 4635, 4639, 4643, 4647, 4651, 4655, 4659, 4663, 4667, 4673, 4679, 4695, 4698, 4706, 4712, 4719 }; #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_AUTOPYNAME", "TK_DEFDOCSTRFMT", "TK_DEFDOCSTRSIG", "TK_DEFENCODING", "TK_PLUGIN", "TK_VIRTERRORHANDLER", "TK_EXPTYPEHINTCODE", "TK_TYPEHINTCODE", "TK_DOCSTRING", "TK_DOC", "TK_EXPORTEDDOC", "TK_EXTRACT", "TK_MAKEFILE", "TK_ACCESSCODE", "TK_GETCODE", "TK_SETCODE", "TK_PREINITCODE", "TK_INITCODE", "TK_POSTINITCODE", "TK_FINALCODE", "TK_UNITCODE", "TK_UNITPOSTINCLUDECODE", "TK_MODCODE", "TK_TYPECODE", "TK_PREPYCODE", "TK_COPYING", "TK_MAPPEDTYPE", "TK_CODELINE", "TK_IF", "TK_END", "TK_NAME_VALUE", "TK_PATH_VALUE", "TK_STRING_VALUE", "TK_VIRTUALCATCHERCODE", "TK_TRAVERSECODE", "TK_CLEARCODE", "TK_GETBUFFERCODE", "TK_RELEASEBUFFERCODE", "TK_READBUFFERCODE", "TK_WRITEBUFFERCODE", "TK_SEGCOUNTCODE", "TK_CHARBUFFERCODE", "TK_PICKLECODE", "TK_VIRTUALCALLCODE", "TK_METHODCODE", "TK_PREMETHODCODE", "TK_INSTANCECODE", "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_PYBUFFER", "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_SIPSSIZET", "TK_NUMBER_VALUE", "TK_REAL_VALUE", "TK_TYPEDEF", "TK_NAMESPACE", "TK_TIMELINE", "TK_PLATFORMS", "TK_FEATURE", "TK_LICENSE", "TK_QCHAR_VALUE", "TK_TRUE_VALUE", "TK_FALSE_VALUE", "TK_NULL_VALUE", "TK_OPERATOR", "TK_THROW", "TK_QOBJECT", "TK_EXCEPTION", "TK_RAISECODE", "TK_VIRTERRORCODE", "TK_EXPLICIT", "TK_TEMPLATE", "TK_FINAL", "TK_ELLIPSIS", "TK_DEFMETATYPE", "TK_DEFSUPERTYPE", "TK_PROPERTY", "TK_HIDE_NS", "TK_FORMAT", "TK_GET", "TK_ID", "TK_KWARGS", "TK_LANGUAGE", "TK_LICENSEE", "TK_NAME", "TK_OPTIONAL", "TK_ORDER", "TK_REMOVELEADING", "TK_SET", "TK_SIGNATURE", "TK_TIMESTAMP", "TK_TYPE", "TK_USEARGNAMES", "TK_USELIMITEDAPI", "TK_ALLRAISEPYEXC", "TK_CALLSUPERINIT", "TK_DEFERRORHANDLER", "TK_VERSION", "'('", "')'", "','", "'='", "'{'", "'}'", "';'", "'!'", "'-'", "'+'", "'*'", "'/'", "'&'", "'|'", "'~'", "'<'", "'>'", "':'", "'['", "']'", "'%'", "'^'", "$accept", "specification", "statement", "@1", "modstatement", "nsstatement", "defdocstringfmt", "defdocstringfmt_args", "defdocstringfmt_arg_list", "defdocstringfmt_arg", "defdocstringsig", "defdocstringsig_args", "defdocstringsig_arg_list", "defdocstringsig_arg", "defencoding", "defencoding_args", "defencoding_arg_list", "defencoding_arg", "plugin", "plugin_args", "plugin_arg_list", "plugin_arg", "virterrorhandler", "veh_args", "veh_arg_list", "veh_arg", "api", "api_args", "api_arg_list", "api_arg", "exception", "baseexception", "exception_body", "exception_body_directives", "exception_body_directive", "raisecode", "mappedtype", "@2", "mappedtypetmpl", "@3", "mtdefinition", "mtbody", "mtline", "mtfunction", "namespace", "@4", "optnsbody", "nsbody", "platforms", "@5", "platformlist", "platform", "feature", "feature_args", "feature_arg_list", "feature_arg", "timeline", "@6", "qualifierlist", "qualifiername", "ifstart", "@7", "oredqualifiers", "qualifiers", "ifend", "license", "license_args", "license_arg_list", "license_arg", "defmetatype", "defmetatype_args", "defmetatype_arg_list", "defmetatype_arg", "defsupertype", "defsupertype_args", "defsupertype_arg_list", "defsupertype_arg", "hiddenns", "hiddenns_args", "hiddenns_arg_list", "hiddenns_arg", "consmodule", "consmodule_args", "consmodule_arg_list", "consmodule_arg", "consmodule_body", "consmodule_body_directives", "consmodule_body_directive", "compmodule", "compmodule_args", "compmodule_arg_list", "compmodule_arg", "compmodule_body", "compmodule_body_directives", "compmodule_body_directive", "module", "module_args", "@8", "module_arg_list", "module_arg", "module_body", "module_body_directives", "module_body_directive", "dottedname", "optnumber", "include", "include_args", "include_arg_list", "include_arg", "optinclude", "import", "import_args", "import_arg_list", "import_arg", "optaccesscode", "optgetcode", "optsetcode", "copying", "exphdrcode", "modhdrcode", "typehdrcode", "travcode", "clearcode", "getbufcode", "releasebufcode", "readbufcode", "writebufcode", "segcountcode", "charbufcode", "instancecode", "picklecode", "finalcode", "modcode", "typecode", "preinitcode", "initcode", "postinitcode", "unitcode", "unitpostinccode", "prepycode", "exptypehintcode", "modtypehintcode", "classtypehintcode", "doc", "exporteddoc", "autopyname", "autopyname_args", "autopyname_arg_list", "autopyname_arg", "docstring", "docstring_args", "docstring_arg_list", "docstring_arg", "optdocstring", "extract", "extract_args", "extract_arg_list", "extract_arg", "makefile", "codeblock", "codelines", "enum", "@9", "optenumkey", "optfilename", "optname", "optenumbody", "enumbody", "enumline", "optcomma", "optenumassign", "optassign", "expr", "binop", "optunop", "value", "optcast", "scopedname", "scopednamehead", "scopepart", "bool_value", "simplevalue", "exprlist", "typedef", "struct", "@10", "@11", "classtmpl", "@12", "template", "class", "@13", "@14", "superclasses", "superlist", "superclass", "class_access", "optclassbody", "classbody", "classline", "property", "property_args", "property_arg_list", "property_arg", "property_body", "property_body_directives", "property_body_directive", "name_or_string", "optslot", "dtor", "ctor", "@15", "simplector", "optctorsig", "@16", "optsig", "@17", "optvirtual", "function", "operatorname", "optconst", "optfinal", "optabstract", "optflags", "flaglist", "flag", "flagvalue", "virtualcallcode", "methodcode", "premethodcode", "virtualcatchercode", "arglist", "rawarglist", "argvalue", "varmember", "@18", "@19", "simple_varmem", "@20", "varmem", "member", "@21", "variable", "variable_body", "variable_body_directives", "variable_body_directive", "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, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 40, 41, 44, 61, 123, 125, 59, 33, 45, 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, 174, 175, 175, 177, 176, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 180, 181, 181, 182, 182, 183, 184, 185, 185, 186, 186, 187, 188, 189, 189, 190, 190, 191, 192, 193, 193, 194, 194, 195, 196, 197, 197, 198, 198, 199, 200, 201, 201, 202, 202, 203, 203, 204, 205, 205, 206, 207, 207, 208, 208, 208, 208, 209, 211, 210, 213, 212, 214, 215, 215, 216, 216, 216, 216, 216, 216, 216, 216, 216, 217, 219, 218, 220, 220, 221, 221, 223, 222, 224, 224, 225, 226, 227, 227, 228, 228, 229, 231, 230, 232, 232, 233, 235, 234, 236, 236, 236, 236, 237, 237, 238, 239, 240, 240, 240, 241, 241, 242, 242, 242, 242, 243, 244, 244, 245, 245, 246, 247, 248, 248, 249, 249, 250, 251, 252, 252, 253, 253, 254, 255, 256, 256, 257, 257, 258, 259, 259, 260, 260, 261, 261, 261, 262, 263, 263, 264, 264, 265, 266, 266, 267, 267, 268, 268, 268, 269, 269, 271, 270, 270, 272, 272, 273, 273, 273, 273, 273, 273, 273, 273, 273, 274, 274, 275, 275, 276, 276, 276, 276, 277, 277, 278, 278, 279, 280, 280, 281, 281, 282, 282, 283, 284, 285, 285, 286, 286, 287, 288, 288, 289, 289, 290, 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, 321, 322, 323, 324, 324, 324, 325, 325, 326, 326, 327, 327, 328, 329, 329, 330, 330, 331, 331, 332, 333, 334, 334, 336, 335, 337, 337, 337, 338, 338, 339, 339, 340, 340, 341, 341, 342, 342, 342, 343, 343, 344, 344, 345, 345, 346, 346, 347, 347, 347, 347, 347, 347, 348, 348, 348, 348, 348, 348, 348, 349, 350, 350, 351, 351, 352, 352, 353, 354, 354, 355, 355, 355, 355, 355, 355, 355, 355, 356, 356, 356, 357, 357, 359, 360, 358, 362, 361, 363, 365, 366, 364, 367, 367, 368, 368, 369, 370, 370, 370, 370, 371, 371, 372, 372, 372, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 374, 375, 376, 376, 377, 377, 377, 378, 378, 379, 379, 380, 380, 380, 381, 381, 382, 382, 383, 385, 384, 384, 386, 387, 388, 387, 389, 390, 389, 391, 391, 392, 392, 392, 392, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 394, 394, 395, 395, 396, 396, 397, 397, 398, 398, 399, 399, 400, 400, 400, 400, 401, 401, 402, 402, 403, 403, 404, 404, 405, 406, 406, 406, 407, 407, 407, 407, 407, 407, 407, 407, 407, 409, 408, 410, 408, 408, 412, 411, 411, 413, 413, 415, 414, 414, 416, 417, 417, 418, 418, 419, 419, 419, 419, 419, 420, 420, 421, 422, 422, 423, 423, 423, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, 425, 425, 426, 426, 427, 427, 427 }; /* 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, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 3, 1, 3, 3, 2, 1, 3, 1, 3, 3, 2, 1, 3, 1, 3, 3, 2, 1, 3, 1, 3, 3, 3, 1, 3, 1, 3, 3, 2, 2, 3, 1, 3, 3, 3, 5, 0, 3, 4, 1, 2, 1, 1, 1, 1, 2, 0, 5, 0, 6, 4, 1, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 14, 0, 5, 0, 3, 1, 2, 0, 5, 1, 2, 1, 2, 1, 3, 1, 3, 3, 0, 5, 1, 2, 1, 0, 5, 1, 2, 3, 4, 1, 3, 1, 3, 0, 1, 3, 1, 3, 3, 3, 3, 3, 2, 1, 3, 1, 3, 3, 2, 1, 3, 1, 3, 3, 2, 1, 3, 1, 3, 3, 3, 1, 3, 1, 3, 3, 0, 4, 1, 2, 1, 1, 1, 3, 1, 3, 1, 3, 3, 0, 4, 1, 2, 1, 1, 1, 3, 3, 0, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 4, 1, 2, 1, 1, 1, 1, 1, 1, 0, 1, 2, 1, 3, 1, 3, 3, 3, 2, 2, 1, 3, 1, 3, 3, 0, 2, 0, 2, 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, 3, 1, 3, 3, 3, 0, 1, 3, 1, 3, 3, 3, 0, 1, 3, 1, 3, 1, 3, 3, 3, 4, 2, 1, 2, 0, 9, 0, 1, 1, 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, 1, 1, 3, 0, 3, 2, 1, 1, 3, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 0, 1, 3, 6, 12, 0, 0, 8, 0, 3, 4, 0, 0, 8, 0, 2, 1, 3, 2, 0, 1, 1, 1, 0, 3, 0, 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, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 2, 3, 3, 1, 3, 3, 3, 3, 0, 4, 1, 2, 1, 1, 1, 1, 1, 0, 1, 12, 0, 3, 1, 11, 0, 0, 6, 0, 0, 7, 0, 1, 17, 7, 17, 16, 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, 1, 0, 2, 0, 3, 1, 3, 1, 3, 1, 5, 1, 1, 0, 2, 0, 2, 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, 8, 0, 3, 1, 2, 1, 1, 2, 2, 2, 4, 3, 3, 0, 1, 0, 3, 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, 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, 0, 0, 0, 0, 0, 0, 0, 151, 352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 572, 562, 565, 566, 570, 571, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 310, 0, 563, 0, 0, 586, 0, 0, 138, 127, 0, 153, 0, 0, 0, 587, 0, 0, 0, 5, 43, 19, 20, 21, 9, 42, 14, 50, 40, 41, 46, 16, 17, 15, 44, 45, 18, 22, 23, 24, 7, 8, 6, 11, 12, 13, 10, 25, 26, 55, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 52, 558, 349, 350, 51, 47, 49, 371, 48, 53, 54, 0, 555, 0, 0, 86, 57, 0, 56, 63, 0, 62, 69, 0, 68, 75, 0, 74, 81, 0, 0, 306, 277, 0, 278, 280, 281, 298, 0, 0, 313, 271, 272, 273, 274, 275, 269, 276, 254, 0, 496, 143, 235, 0, 234, 241, 243, 0, 242, 255, 256, 257, 230, 231, 0, 222, 208, 232, 0, 186, 181, 0, 199, 194, 374, 368, 568, 311, 312, 315, 573, 561, 564, 567, 574, 348, 555, 0, 121, 0, 0, 133, 0, 132, 154, 0, 496, 0, 94, 0, 0, 162, 163, 0, 168, 169, 0, 174, 175, 0, 0, 0, 0, 496, 0, 553, 87, 0, 0, 0, 89, 0, 0, 59, 0, 0, 65, 0, 0, 71, 0, 0, 77, 0, 0, 83, 80, 307, 305, 0, 0, 0, 300, 297, 314, 0, 560, 0, 104, 315, 0, 0, 0, 237, 0, 0, 245, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 211, 0, 206, 232, 233, 207, 0, 0, 183, 0, 180, 0, 0, 196, 0, 193, 377, 377, 316, 496, 569, 553, 496, 0, 123, 0, 0, 0, 0, 135, 0, 0, 0, 0, 0, 156, 152, 515, 0, 496, 588, 0, 0, 0, 165, 0, 0, 171, 0, 0, 177, 0, 351, 496, 372, 515, 541, 0, 0, 0, 462, 461, 463, 464, 466, 467, 481, 484, 488, 0, 465, 468, 0, 557, 554, 551, 0, 0, 88, 0, 0, 58, 0, 0, 64, 0, 0, 70, 0, 0, 76, 0, 0, 82, 0, 0, 0, 299, 0, 304, 500, 0, 498, 0, 145, 0, 149, 0, 0, 0, 0, 236, 0, 0, 244, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 0, 0, 288, 226, 227, 0, 224, 228, 229, 209, 0, 182, 0, 190, 191, 0, 188, 192, 0, 195, 0, 203, 204, 0, 201, 205, 382, 496, 496, 308, 550, 0, 0, 0, 0, 142, 0, 140, 131, 0, 129, 0, 134, 0, 0, 0, 0, 0, 155, 0, 315, 315, 315, 315, 315, 0, 0, 315, 0, 514, 516, 315, 328, 0, 0, 0, 373, 0, 164, 0, 0, 170, 0, 0, 176, 0, 559, 106, 0, 0, 0, 482, 0, 486, 487, 472, 471, 473, 474, 476, 477, 485, 469, 489, 470, 483, 475, 478, 515, 556, 440, 441, 91, 92, 90, 61, 60, 67, 66, 73, 72, 79, 78, 85, 84, 302, 303, 301, 0, 0, 497, 0, 105, 146, 0, 144, 315, 239, 353, 354, 240, 238, 247, 246, 213, 214, 215, 216, 217, 218, 219, 220, 221, 212, 0, 282, 289, 0, 0, 0, 225, 185, 184, 0, 189, 198, 197, 0, 202, 383, 384, 385, 378, 379, 0, 375, 369, 0, 295, 0, 125, 0, 371, 122, 139, 141, 128, 130, 137, 136, 159, 160, 161, 158, 157, 496, 496, 496, 496, 496, 515, 515, 496, 490, 0, 496, 346, 526, 95, 0, 93, 589, 167, 166, 173, 172, 179, 178, 0, 490, 0, 0, 0, 545, 546, 0, 543, 248, 0, 479, 480, 0, 230, 504, 505, 502, 501, 499, 0, 0, 0, 0, 0, 0, 109, 119, 111, 112, 113, 117, 114, 118, 147, 0, 150, 0, 0, 284, 0, 0, 0, 291, 287, 223, 187, 200, 382, 381, 386, 386, 317, 296, 366, 0, 124, 126, 328, 328, 328, 521, 522, 0, 0, 525, 491, 492, 517, 552, 0, 329, 330, 338, 0, 0, 97, 101, 99, 100, 102, 107, 492, 547, 548, 549, 542, 544, 0, 250, 0, 490, 232, 270, 266, 115, 116, 0, 0, 110, 148, 0, 283, 0, 0, 0, 290, 0, 380, 388, 0, 0, 326, 321, 322, 0, 318, 319, 0, 518, 519, 520, 315, 315, 493, 590, 0, 332, 333, 334, 335, 336, 337, 346, 339, 341, 342, 343, 344, 340, 0, 103, 0, 98, 590, 249, 0, 252, 458, 492, 0, 0, 108, 286, 285, 293, 294, 292, 0, 0, 352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 442, 442, 442, 0, 527, 529, 537, 532, 445, 0, 397, 393, 391, 392, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 402, 415, 401, 399, 398, 394, 396, 395, 455, 389, 400, 417, 416, 447, 0, 539, 418, 531, 534, 535, 536, 376, 370, 346, 496, 0, 320, 0, 496, 496, 0, 494, 347, 331, 361, 358, 357, 362, 360, 355, 359, 345, 0, 96, 494, 251, 0, 540, 590, 232, 515, 279, 268, 515, 258, 259, 260, 261, 262, 263, 264, 265, 267, 421, 420, 419, 443, 0, 0, 0, 425, 0, 0, 0, 0, 0, 0, 433, 387, 390, 0, 327, 324, 309, 496, 523, 524, 592, 0, 496, 346, 496, 253, 494, 503, 0, 0, 422, 423, 424, 537, 528, 530, 538, 0, 533, 0, 446, 0, 0, 0, 0, 428, 0, 426, 0, 325, 323, 0, 593, 0, 495, 452, 364, 0, 452, 496, 490, 590, 0, 0, 0, 0, 427, 0, 437, 438, 439, 0, 435, 0, 295, 591, 0, 453, 0, 356, 346, 0, 452, 590, 496, 430, 431, 432, 429, 0, 436, 590, 367, 594, 0, 510, 365, 295, 0, 496, 449, 434, 494, 0, 0, 508, 510, 510, 452, 450, 0, 496, 515, 511, 0, 512, 508, 508, 0, 0, 295, 0, 0, 509, 0, 506, 512, 512, 295, 515, 510, 510, 0, 513, 0, 460, 506, 506, 510, 0, 508, 508, 454, 507, 457, 459, 508, 0, 448, 512, 120, 451, 444 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { -1, 1, 2, 3, 78, 79, 80, 140, 244, 245, 81, 143, 247, 248, 82, 146, 250, 251, 83, 149, 253, 254, 84, 152, 256, 257, 85, 137, 241, 242, 86, 328, 615, 698, 699, 700, 87, 392, 88, 623, 537, 648, 649, 650, 89, 313, 449, 586, 90, 212, 454, 455, 91, 215, 317, 318, 92, 211, 451, 452, 93, 271, 395, 396, 94, 95, 218, 323, 324, 96, 223, 332, 333, 97, 226, 335, 336, 98, 229, 338, 339, 99, 191, 296, 297, 299, 430, 431, 100, 194, 301, 302, 304, 438, 439, 101, 187, 292, 288, 289, 291, 420, 421, 188, 294, 102, 176, 274, 275, 103, 104, 180, 277, 278, 712, 770, 869, 105, 106, 107, 108, 811, 812, 813, 814, 815, 816, 817, 818, 654, 820, 821, 109, 655, 110, 111, 112, 113, 114, 115, 116, 117, 823, 118, 119, 422, 560, 661, 662, 676, 563, 665, 666, 677, 120, 161, 263, 264, 121, 154, 155, 122, 582, 201, 267, 308, 738, 739, 740, 939, 846, 612, 694, 756, 763, 695, 696, 123, 124, 125, 545, 863, 946, 126, 127, 306, 674, 128, 234, 587, 130, 305, 673, 442, 577, 578, 579, 733, 830, 831, 832, 899, 933, 934, 936, 960, 961, 517, 889, 833, 834, 897, 835, 999, 1008, 967, 983, 836, 837, 361, 690, 748, 911, 270, 390, 391, 641, 1024, 1004, 994, 1014, 473, 474, 475, 838, 893, 894, 839, 896, 840, 841, 895, 842, 495, 630, 631, 476, 477, 364, 237, 134, 330, 853, 942 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -848 static const yytype_int16 yypact[] = { -848, 264, -848, 1011, -848, -848, 67, 30, 64, 89, 68, 70, 240, 240, 240, 240, 74, 246, 240, 240, 240, 240, 240, 240, 240, 240, 313, 143, -848, -848, 26, 284, 56, 240, 240, 240, 46, 272, 49, 59, 102, 102, -848, -848, -848, 216, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, 260, 242, 300, 305, 313, -848, 495, 339, -848, -848, 75, 92, 495, 102, 186, -848, 61, 63, 65, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, 210, 286, -848, -848, -848, -848, 332, -848, -848, -848, 84, -848, 279, -21, -848, -848, 270, -848, -848, 281, -848, -848, 289, -848, -848, 295, -848, -848, 297, 240, -848, -848, 176, -848, -848, -848, -848, 47, 240, 412, -848, -848, -848, -848, -848, -848, -848, -848, 102, 290, -848, -848, 190, -848, -848, -848, 320, -848, -848, -848, -848, -848, -848, 195, 306, -848, 361, 362, 355, -848, 378, 363, -848, -848, 22, -848, -848, -848, 440, -848, -848, -848, 442, -848, 286, -848, 86, -848, 364, 365, -848, 384, -848, -848, 212, 290, 371, 372, 495, 388, -848, -848, 389, -848, -848, 390, -848, -848, 495, 305, 313, 466, -29, 150, 139, -848, 379, 383, 181, -848, 385, 250, -848, 386, 268, -848, 387, 291, -848, 391, 296, -848, 392, 298, -848, -848, -848, -848, 393, 394, 301, -848, -848, -848, 240, -848, 497, -848, 2, 396, 398, 303, -848, 399, 311, -848, 400, 401, 403, 404, 406, 407, 408, 410, 430, 316, -848, 257, -848, 361, -848, -848, 435, 318, -848, 247, -848, 437, 323, -848, 247, -848, 370, 370, -848, 290, -848, 139, 290, 381, 377, 510, 511, 438, 325, -848, 439, 441, 444, 448, 328, -848, -848, 1253, 102, 290, -848, 8, 449, 330, -848, 450, 333, -848, 451, 336, -848, 9, -848, 290, -848, 1253, 411, 454, 141, 453, 455, 456, 461, 462, 463, 464, -848, 16, 95, 424, 465, 468, 445, 513, -848, -848, 347, 515, -848, -21, 588, -848, 270, 589, -848, 281, 590, -848, 289, 593, -848, 295, 594, -848, 297, 595, 528, -848, 47, -848, 480, 134, -848, 481, 476, 604, 544, 487, 482, 606, 376, -848, 190, 608, -848, 320, 609, 610, 272, 376, 376, 376, 376, 614, 538, -848, 195, 498, 93, -848, -848, 40, -848, -848, -848, -848, 272, -848, 362, -848, -848, 31, -848, -848, 272, -848, 378, -848, -848, 35, -848, -848, 358, 290, 290, -848, -848, 491, 617, 758, 494, -848, 28, -848, -848, 43, -848, 347, -848, 384, 618, 619, 620, 621, -848, 212, 440, 440, 440, 440, 440, 501, 506, 440, 507, 514, -848, 440, 512, 517, 509, 495, -848, 272, -848, 388, 272, -848, 389, 102, -848, 390, -848, -848, 519, 319, 516, -848, 495, -848, -848, -848, -848, -848, -848, -848, -848, -848, 518, -848, 520, -848, -848, -848, 1253, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, 97, 497, -848, 235, -848, -848, 21, -848, 440, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, 535, -848, -848, 114, 240, 521, -848, -848, -848, 522, -848, -848, -848, 523, -848, -848, -848, -848, 529, -848, 102, -848, -848, 526, 665, 532, -848, 1093, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, 290, 290, 290, 290, 290, 1253, 1253, 290, 592, 1253, 290, 534, -848, -848, 83, -848, -848, -848, -848, -848, -848, -848, -848, 481, 592, 240, 240, 240, -848, -848, 57, -848, 672, 537, -848, -848, 539, 524, -848, -848, -848, -848, -848, 240, 240, 240, 240, 495, 55, -848, -848, -848, -848, -848, -848, -848, -848, -848, 657, -848, 540, 340, -848, 542, 545, 342, -848, -848, -848, -848, -848, 358, -848, 543, 543, 397, -848, -848, 549, -848, -848, 512, 512, 512, -848, -848, 550, 551, -848, -848, 576, -848, -848, 102, 207, -848, 199, 240, 53, -848, -848, -848, -848, -848, -848, 576, -848, -848, -848, -848, -848, 240, 687, 548, 592, 361, -848, -848, -848, -848, 673, 552, -848, -848, 675, -848, 535, 676, 677, -848, 114, -848, 1192, 556, 557, 553, -848, -848, 559, 397, -848, 495, -848, -848, -848, 440, 440, -848, 598, 565, -848, -848, -848, -848, -848, -848, 534, -848, -848, -848, -848, -848, -848, 1314, -848, 562, -848, 598, -848, 240, 690, -848, 576, 561, 570, -848, -848, -848, -848, -848, -848, 240, 240, 571, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 654, 654, 654, 558, -848, -848, 563, -848, -848, 578, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, 877, -848, -848, -848, -848, -848, 567, -848, -848, -848, -848, -848, -848, -848, -848, 534, 290, 573, -848, 345, 290, 290, 582, 580, -848, -848, -848, -848, -848, -848, -848, -17, -848, -848, 585, -848, 580, -848, 240, -848, 598, 361, 1253, -848, -848, 1253, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, 569, 574, 575, -848, 1370, 1370, 1484, 1427, 694, 140, 583, -848, -848, 706, -848, 591, -848, 290, -848, -848, 102, 636, 290, 285, 290, -848, 580, -848, 596, 597, -848, -848, -848, -848, -848, -848, -848, 88, -848, 571, -848, 599, 600, 602, 348, -848, 247, -848, 607, -848, -848, 605, -848, 350, -848, 577, 207, 352, 577, 290, 592, 598, 612, 712, 347, 714, -848, 140, -848, -848, -848, 37, -848, 613, 665, -848, 102, -848, 625, -848, 534, 626, 577, 598, 290, -848, -848, -848, -848, 627, -848, 598, -848, -848, 495, 702, 207, 665, 629, 290, 623, -848, 580, 615, 240, 704, 702, 702, 577, -848, 630, 290, 1253, -848, 240, 721, 704, 704, 631, 642, 665, 637, 643, -848, 240, 713, 721, 721, 665, 1253, 702, 702, 628, -848, 240, -848, 713, 713, 702, 644, 704, 704, -848, -848, -848, -848, 704, 632, -848, 721, -848, -848, -848 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { -848, -848, 761, -848, -848, -397, -848, -848, -848, 427, -848, -848, -848, 426, -848, -848, -848, 425, -848, -848, -848, 428, -848, -848, -848, 382, -848, -848, -848, 402, -640, -848, -848, -848, 106, -848, -848, -848, -848, -848, 182, -848, 158, -848, -606, -848, -848, -848, -848, -848, -848, 353, -848, -848, -848, 351, -848, -848, -848, 359, -266, -848, -848, -848, -264, -848, -848, -848, 354, -848, -848, -848, 327, -848, -848, -848, 329, -848, -848, -848, 322, -848, -848, -848, 421, -848, -848, 395, -848, -848, -848, 380, -848, -848, 415, -848, -848, -848, -848, 405, -848, -848, 409, 3, -269, -848, -848, -848, 413, -848, -848, -848, -848, 417, -848, -848, -848, -848, -848, -848, -503, -848, -848, -848, -848, -848, -848, -848, -848, -605, -848, -848, -848, -583, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, -848, 98, -273, -848, -848, 96, -726, -848, -848, -848, 432, -848, -13, -848, -490, -848, -848, -848, -233, -848, -848, 117, -848, -848, -240, -799, -848, -848, -646, -848, -27, 765, 633, -351, -848, -848, -581, -579, -848, -848, -572, -848, 825, -215, -848, -848, 554, -848, 187, -848, 183, -848, 29, -848, -848, -848, -95, -848, -848, -98, -428, -290, -848, -848, -848, -33, -848, -848, -804, -848, -848, 12, -848, -595, -568, -812, -187, -848, 334, -848, -516, -731, -743, -847, -340, -848, 261, -848, -848, -848, -379, -848, -25, -848, -848, 15, -848, -848, 239, 0, -848, 564, 664, -10, -204, -732, -848 }; /* 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 -561 static const yytype_int16 yytable[] = { 156, 157, 158, 133, 493, 163, 164, 165, 166, 167, 168, 169, 170, 196, 197, 131, 172, 423, 132, 343, 181, 182, 183, 424, 418, 432, 419, 340, 593, 705, 440, 325, 428, 653, 429, 866, 393, 436, 397, 437, 189, 192, 195, 417, 416, 220, 656, 417, 345, 417, 230, 585, 417, 208, 913, 657, -560, 552, 553, 554, 555, 174, 450, 27, 28, 209, 138, 27, 28, 27, 28, 219, 27, 28, 625, 626, 627, 453, 224, 227, 184, 185, 643, 184, 185, 27, 28, 27, 28, 27, 28, 178, 806, 184, 185, 184, 185, 184, 185, 29, 141, 135, 147, 948, 150, 644, 645, 646, 159, 213, 855, 703, 35, 945, 35, 27, 28, 239, 235, 772, 311, 444, 951, 344, 446, 144, 807, 819, 216, 561, 240, 637, 185, 638, 269, -558, 29, 767, 915, 258, -560, 479, 35, 970, 268, 653, 59, 423, 265, 822, 231, 826, 647, 827, 418, 492, 419, 432, 656, 62, 828, 394, 480, 480, 428, 440, 429, 987, 1025, 1026, 985, 506, 436, 636, 437, 697, 481, 491, 175, 1000, 658, 261, 139, 507, -560, 589, -560, 262, 568, 680, 806, 1041, 572, 1007, 978, 703, 62, 564, 186, 903, 591, 190, 236, 639, 870, 697, 236, 259, 179, 260, 765, 193, 721, 222, 709, 225, 142, 228, 973, 136, 148, 329, 151, 342, 807, 819, 160, 214, 628, 810, 629, 329, 600, 601, 602, 603, 604, 981, 312, 607, 988, 145, 825, 610, 217, 562, 663, 822, 991, 826, 508, 827, 1005, 1006, 388, 580, 581, 664, 828, 417, 995, 416, 643, 509, 4, 686, 687, 27, 28, 417, 651, 153, 652, 930, 1015, 1016, 1029, 1030, 931, 27, 28, 162, 932, 1019, 1035, 644, 645, 646, 534, 27, 28, 1027, 198, 497, 35, 173, 498, 535, 1037, 1038, 478, 362, 346, 363, 1039, 347, 184, 185, 659, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 177, 358, 202, 359, 360, 199, 200, 59, 810, 272, 273, 279, 280, 647, 281, 367, 368, 625, 626, 627, 29, 825, 282, 283, 284, 285, 286, 287, 29, 701, 319, 702, 27, 28, 221, 972, 320, 321, 322, 757, 758, 759, 760, 233, 761, 628, 762, 629, 750, 751, 752, 753, 754, 755, 210, 203, 204, 205, 231, 171, 206, 232, 515, 651, 516, 652, 238, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 370, 371, 60, 61, 62, 243, 736, 551, 737, 862, 681, 682, 683, 684, 685, 64, 246, 688, 373, 374, 692, 574, 575, 576, 249, 566, 27, 28, 735, 701, 252, 702, 255, 570, 693, -363, -363, 74, 742, 743, 744, 376, 377, 773, 266, 133, 379, 380, 382, 383, 269, 386, 387, 400, 401, 276, 824, 131, 621, 290, 132, 403, 404, 808, 293, 809, 414, 415, 426, 427, 736, 307, 737, 434, 435, 457, 458, 616, 463, 464, 483, 484, 617, 486, 487, 619, 489, 490, 543, 544, 725, 726, 729, 730, 633, 906, 480, 295, 955, 956, 964, 965, 968, 969, 890, 891, 1033, 1034, 298, 850, 851, 923, 924, 300, 829, 309, 303, 314, 315, 316, 326, 327, 975, 331, 334, 337, 29, 40, 389, 917, 448, 365, 918, 640, 849, 366, 441, 369, 372, 375, 447, 450, 453, 378, 381, 384, 385, 667, 398, 672, 399, 402, 405, 406, 824, 407, 408, 171, 409, 410, 411, 808, 412, 809, 494, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 413, 133, 60, 61, 62, 425, 63, 433, 456, 459, 510, 460, 513, 131, 461, 64, 132, 916, 462, 482, 485, 488, 496, 499, 514, 500, 501, 706, 707, 708, 829, 502, 503, 504, 505, 511, 518, 74, 512, 520, 522, 524, 526, 528, 530, 716, 717, 718, 719, 531, 533, -316, 536, 538, 539, 540, 542, 541, 547, 557, 549, 550, 720, 556, 583, 559, 584, 588, 605, 595, 596, 597, 598, 606, 904, 608, 1011, 959, 907, 908, 614, 749, 611, 609, 957, 613, 958, 624, 634, 632, 635, 660, 417, 1028, 668, 669, 670, 675, 671, 764, 678, 693, 959, 689, 711, 713, 723, 714, 715, 957, 724, 958, 727, 768, 732, 728, 741, 747, 745, 746, 769, 771, 774, 845, 868, 775, 776, 778, 779, 843, 844, 847, 852, 854, 940, 865, 871, 872, 875, 944, 888, 947, 892, 928, -456, 898, 905, 133, 902, 909, 910, 861, 912, 919, 935, 937, 329, 943, 920, 921, 938, 974, 966, 976, 949, 950, 993, 1003, 864, 952, 953, 867, 954, 1013, 962, 1023, 971, 5, 963, 344, 529, 980, 1001, 873, 874, 519, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 984, 986, 990, 989, 996, 1009, 1017, 27, 28, 29, 998, 1018, 1020, 1021, 1036, 521, 1031, 523, 997, 525, 1040, 766, 704, 722, 592, 527, 594, 590, 618, 622, 1010, 546, 571, 620, 35, 599, 532, 558, 548, 40, 41, 777, 569, 780, 207, 129, 565, 133, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 567, 59, 60, 61, 62, 573, 63, 914, 848, 734, 731, 901, 443, 977, 979, 64, 929, 341, 65, 66, 642, 710, 691, 927, 310, 0, 445, 0, 71, 0, 0, 72, 0, 0, 941, 73, 0, 74, 0, 0, 781, 417, 0, 0, 0, 133, 133, 926, 133, 0, 0, 0, 782, 0, 0, 0, 643, 0, 0, 925, 0, 27, 28, 783, 0, 0, 0, 784, 785, 786, 787, 788, 789, 790, 791, 792, 0, 0, 0, 644, 793, 794, 795, 0, 0, 0, 0, 0, 35, 0, 982, 0, 0, 40, 41, 796, 797, 798, 799, 800, 0, 801, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 802, 59, 60, 61, 62, 0, 63, 803, 0, 0, 0, 0, 0, 1002, 0, 64, 992, 0, 65, 66, 0, 0, 0, 1012, 0, 0, 0, 0, 71, 0, 0, 72, 0, 1022, 804, 73, 0, 74, 0, 0, 805, 0, 0, 1032, 0, 0, 0, 6, 0, 7, 8, 9, 10, 11, 12, 13, 0, 14, 15, 16, 17, 0, 0, 0, 18, 19, 20, 900, 21, 22, 23, 0, 24, 25, 26, 0, 27, 28, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 0, 0, 0, 0, 0, 0, 0, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 0, 59, 60, 61, 62, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 65, 66, 67, 68, 69, 70, 27, 28, 29, 0, 71, 0, 0, 72, 0, 0, 0, 73, 0, 74, 75, 76, 0, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 40, 41, 0, 0, 0, 0, 0, 0, 0, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 0, 59, 60, 61, 62, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 65, 66, 781, 417, 0, 0, 0, 0, 0, 0, 71, 0, 0, 72, 782, 0, 0, 73, 643, 74, 0, 0, 0, 27, 28, 783, 0, 0, 0, 784, 785, 786, 787, 788, 789, 790, 791, 792, 0, 0, 0, 644, 793, 794, 795, 0, 0, 0, 0, 679, 35, 0, 0, 0, 0, 40, 41, 796, 797, 798, 799, 800, 0, 801, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 802, 59, 60, 61, 62, 29, 63, 803, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 65, 66, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 72, 0, 0, 804, 73, 171, 74, 0, 0, 805, 0, 0, 0, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 0, 0, 60, 61, 62, 29, 63, 856, 465, 466, 467, 468, 469, 470, 471, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 472, 0, 0, 0, 0, 0, 171, 74, 0, 0, 0, 0, 0, 0, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 29, 0, 60, 61, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 857, 858, 0, 0, 0, 0, 0, 0, 859, 543, 544, 860, 0, 0, 0, 171, 0, 0, 0, 0, 0, 74, 0, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 922, 29, 60, 61, 62, 0, 63, 803, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 171, 0, 0, 0, 0, 74, 0, 0, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 922, 29, 60, 61, 62, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 171, 0, 0, 0, 0, 74, 0, 0, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 0, 0, 60, 61, 62, 0, 63, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 0, 74 }; static const yytype_int16 yycheck[] = { 13, 14, 15, 3, 344, 18, 19, 20, 21, 22, 23, 24, 25, 40, 41, 3, 26, 290, 3, 234, 33, 34, 35, 292, 290, 298, 290, 231, 456, 624, 303, 218, 298, 536, 298, 767, 34, 303, 271, 303, 37, 38, 39, 12, 4, 72, 536, 12, 235, 12, 77, 448, 12, 63, 866, 34, 34, 408, 409, 410, 411, 35, 34, 32, 33, 65, 36, 32, 33, 32, 33, 71, 32, 33, 17, 18, 19, 34, 75, 76, 34, 35, 27, 34, 35, 32, 33, 32, 33, 32, 33, 35, 732, 34, 35, 34, 35, 34, 35, 34, 36, 34, 34, 915, 34, 50, 51, 52, 34, 34, 756, 614, 59, 912, 59, 32, 33, 138, 34, 714, 34, 308, 34, 152, 311, 36, 732, 732, 36, 36, 151, 34, 35, 36, 163, 152, 34, 705, 870, 152, 118, 328, 59, 947, 171, 648, 91, 420, 161, 732, 167, 732, 97, 732, 420, 342, 420, 430, 648, 94, 732, 159, 154, 154, 430, 438, 430, 971, 1015, 1016, 969, 155, 438, 513, 438, 122, 168, 168, 152, 991, 159, 134, 152, 167, 162, 157, 164, 140, 157, 586, 830, 1038, 157, 997, 157, 698, 94, 157, 152, 845, 157, 152, 118, 106, 772, 122, 118, 31, 152, 33, 157, 152, 157, 152, 157, 152, 152, 152, 950, 152, 152, 221, 152, 233, 830, 830, 152, 152, 494, 732, 494, 231, 465, 466, 467, 468, 469, 963, 152, 472, 972, 152, 732, 476, 152, 152, 132, 830, 980, 830, 155, 830, 995, 996, 267, 442, 443, 143, 830, 12, 986, 4, 27, 168, 0, 605, 606, 32, 33, 12, 536, 31, 536, 133, 1005, 1006, 1019, 1020, 138, 32, 33, 35, 142, 1009, 1027, 50, 51, 52, 154, 32, 33, 1017, 76, 152, 59, 152, 155, 163, 1029, 1030, 327, 162, 152, 164, 1035, 155, 34, 35, 541, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 35, 170, 79, 172, 173, 64, 65, 91, 830, 138, 139, 135, 136, 97, 138, 153, 154, 17, 18, 19, 34, 830, 146, 147, 148, 149, 150, 151, 34, 614, 137, 614, 32, 33, 167, 949, 143, 144, 145, 159, 160, 161, 162, 30, 164, 630, 166, 630, 160, 161, 162, 163, 164, 165, 34, 74, 75, 76, 167, 65, 79, 94, 34, 648, 36, 648, 106, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 153, 154, 92, 93, 94, 138, 675, 407, 675, 763, 600, 601, 602, 603, 604, 105, 138, 607, 153, 154, 610, 66, 67, 68, 138, 425, 32, 33, 34, 698, 138, 698, 138, 433, 152, 153, 154, 127, 681, 682, 683, 153, 154, 715, 35, 448, 153, 154, 153, 154, 163, 153, 154, 153, 154, 138, 732, 448, 488, 156, 448, 153, 154, 732, 106, 732, 153, 154, 153, 154, 739, 34, 739, 153, 154, 153, 154, 480, 153, 154, 153, 154, 482, 153, 154, 485, 153, 154, 115, 116, 153, 154, 153, 154, 497, 153, 154, 138, 153, 154, 153, 154, 153, 154, 797, 798, 1025, 1026, 156, 745, 746, 893, 894, 138, 732, 76, 156, 156, 156, 138, 152, 152, 953, 138, 138, 138, 34, 64, 34, 872, 156, 155, 875, 533, 741, 155, 169, 155, 155, 155, 162, 34, 34, 155, 155, 155, 155, 563, 155, 579, 155, 155, 155, 155, 830, 155, 155, 65, 155, 155, 155, 830, 155, 830, 156, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 155, 586, 92, 93, 94, 155, 96, 155, 155, 155, 171, 155, 152, 586, 155, 105, 586, 871, 155, 155, 155, 155, 153, 155, 96, 155, 155, 625, 626, 627, 830, 155, 155, 155, 155, 155, 106, 127, 155, 36, 36, 36, 34, 34, 34, 643, 644, 645, 646, 106, 155, 160, 156, 34, 95, 153, 35, 160, 35, 106, 36, 36, 647, 34, 158, 152, 34, 158, 152, 36, 36, 36, 36, 152, 846, 153, 1001, 935, 850, 851, 156, 693, 155, 154, 935, 153, 935, 153, 155, 158, 155, 141, 12, 1018, 158, 158, 158, 156, 154, 697, 153, 152, 960, 96, 17, 153, 34, 153, 169, 960, 155, 960, 155, 711, 156, 155, 152, 126, 153, 153, 18, 158, 34, 155, 19, 158, 36, 36, 36, 158, 158, 157, 119, 153, 906, 158, 160, 152, 152, 911, 71, 913, 169, 34, 166, 152, 158, 732, 166, 152, 155, 763, 152, 169, 156, 34, 741, 106, 169, 169, 154, 34, 170, 34, 153, 153, 49, 48, 763, 155, 155, 769, 155, 37, 152, 47, 948, 1, 158, 152, 383, 153, 152, 781, 782, 368, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 158, 158, 158, 973, 158, 158, 158, 32, 33, 34, 170, 152, 158, 153, 153, 371, 171, 374, 988, 377, 171, 698, 623, 648, 454, 380, 458, 451, 484, 490, 1000, 401, 435, 487, 59, 464, 387, 415, 404, 64, 65, 726, 430, 730, 62, 3, 420, 830, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 427, 91, 92, 93, 94, 438, 96, 868, 739, 674, 671, 830, 306, 956, 960, 105, 897, 232, 108, 109, 534, 630, 609, 896, 208, -1, 310, -1, 118, -1, -1, 121, -1, -1, 909, 125, -1, 127, -1, -1, 11, 12, -1, -1, -1, 893, 894, 895, 896, -1, -1, -1, 23, -1, -1, -1, 27, -1, -1, 895, -1, 32, 33, 34, -1, -1, -1, 38, 39, 40, 41, 42, 43, 44, 45, 46, -1, -1, -1, 50, 51, 52, 53, -1, -1, -1, -1, -1, 59, -1, 965, -1, -1, 64, 65, 66, 67, 68, 69, 70, -1, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, -1, 96, 97, -1, -1, -1, -1, -1, 993, -1, 105, 983, -1, 108, 109, -1, -1, -1, 1003, -1, -1, -1, -1, 118, -1, -1, 121, -1, 1013, 124, 125, -1, 127, -1, -1, 130, -1, -1, 1023, -1, -1, -1, 3, -1, 5, 6, 7, 8, 9, 10, 11, -1, 13, 14, 15, 16, -1, -1, -1, 20, 21, 22, 157, 24, 25, 26, -1, 28, 29, 30, -1, 32, 33, 34, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, -1, -1, -1, -1, -1, -1, -1, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, -1, 91, 92, 93, 94, -1, 96, -1, -1, -1, -1, -1, -1, -1, -1, 105, -1, -1, 108, 109, 110, 111, 112, 113, 32, 33, 34, -1, 118, -1, -1, 121, -1, -1, -1, 125, -1, 127, 128, 129, -1, 131, -1, -1, -1, -1, -1, -1, -1, -1, -1, 59, -1, -1, -1, -1, 64, 65, -1, -1, -1, -1, -1, -1, -1, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, -1, 91, 92, 93, 94, -1, 96, -1, -1, -1, -1, -1, -1, -1, -1, 105, -1, -1, 108, 109, 11, 12, -1, -1, -1, -1, -1, -1, 118, -1, -1, 121, 23, -1, -1, 125, 27, 127, -1, -1, -1, 32, 33, 34, -1, -1, -1, 38, 39, 40, 41, 42, 43, 44, 45, 46, -1, -1, -1, 50, 51, 52, 53, -1, -1, -1, -1, 157, 59, -1, -1, -1, -1, 64, 65, 66, 67, 68, 69, 70, -1, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 34, 96, 97, -1, -1, -1, -1, -1, -1, -1, 105, -1, -1, 108, 109, -1, -1, -1, -1, -1, -1, -1, -1, 118, -1, -1, 121, -1, -1, 124, 125, 65, 127, -1, -1, 130, -1, -1, -1, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, -1, -1, 92, 93, 94, 34, 96, 36, 98, 99, 100, 101, 102, 103, 104, 105, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 120, -1, -1, -1, -1, -1, 65, 127, -1, -1, -1, -1, -1, -1, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 34, -1, 92, 93, 94, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 105, 106, 107, -1, -1, -1, -1, -1, -1, 114, 115, 116, 117, -1, -1, -1, 65, -1, -1, -1, -1, -1, 127, -1, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 34, 92, 93, 94, -1, 96, 97, -1, -1, -1, -1, -1, -1, -1, 105, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 118, -1, -1, -1, 65, -1, -1, -1, -1, 127, -1, -1, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 34, 92, 93, 94, -1, 96, -1, -1, -1, -1, -1, -1, -1, -1, 105, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 118, -1, -1, -1, 65, -1, -1, -1, -1, 127, -1, -1, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, -1, -1, 92, 93, 94, -1, 96, -1, -1, -1, -1, -1, -1, -1, -1, 105, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 118, -1, -1, -1, -1, -1, -1, -1, -1, 127 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint16 yystos[] = { 0, 175, 176, 177, 0, 176, 3, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 20, 21, 22, 24, 25, 26, 28, 29, 30, 32, 33, 34, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 91, 92, 93, 94, 96, 105, 108, 109, 110, 111, 112, 113, 118, 121, 125, 127, 128, 129, 131, 178, 179, 180, 184, 188, 192, 196, 200, 204, 210, 212, 218, 222, 226, 230, 234, 238, 239, 243, 247, 251, 255, 262, 269, 279, 283, 284, 291, 292, 293, 294, 306, 308, 309, 310, 311, 312, 313, 314, 315, 317, 318, 328, 332, 335, 351, 352, 353, 357, 358, 361, 363, 364, 392, 416, 420, 424, 34, 152, 201, 36, 152, 181, 36, 152, 185, 36, 152, 189, 34, 152, 193, 34, 152, 197, 31, 333, 334, 333, 333, 333, 34, 152, 329, 35, 333, 333, 333, 333, 333, 333, 333, 333, 65, 424, 152, 35, 152, 280, 35, 35, 152, 285, 333, 333, 333, 34, 35, 152, 270, 277, 277, 152, 256, 277, 152, 263, 277, 351, 351, 76, 64, 65, 337, 79, 74, 75, 76, 79, 352, 424, 420, 34, 231, 223, 34, 152, 227, 36, 152, 240, 420, 351, 167, 152, 244, 277, 152, 248, 277, 152, 252, 351, 167, 94, 30, 362, 34, 118, 423, 106, 138, 151, 202, 203, 138, 182, 183, 138, 186, 187, 138, 190, 191, 138, 194, 195, 138, 198, 199, 333, 31, 33, 134, 140, 330, 331, 333, 35, 338, 351, 163, 397, 235, 138, 139, 281, 282, 138, 286, 287, 135, 136, 138, 146, 147, 148, 149, 150, 151, 272, 273, 156, 274, 271, 106, 278, 138, 257, 258, 156, 259, 138, 264, 265, 156, 266, 365, 359, 34, 339, 76, 423, 34, 152, 219, 156, 156, 138, 228, 229, 137, 143, 144, 145, 241, 242, 397, 152, 152, 205, 420, 425, 138, 245, 246, 138, 249, 250, 138, 253, 254, 425, 353, 424, 364, 152, 397, 152, 155, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 170, 172, 173, 393, 162, 164, 422, 155, 155, 153, 154, 155, 153, 154, 155, 153, 154, 155, 153, 154, 155, 153, 154, 155, 153, 154, 155, 155, 153, 154, 333, 34, 398, 399, 211, 34, 159, 236, 237, 339, 155, 155, 153, 154, 155, 153, 154, 155, 155, 155, 155, 155, 155, 155, 155, 155, 153, 154, 4, 12, 234, 238, 275, 276, 319, 323, 278, 155, 153, 154, 234, 238, 260, 261, 323, 155, 153, 154, 234, 238, 267, 268, 323, 169, 367, 367, 397, 422, 397, 162, 156, 220, 34, 232, 233, 34, 224, 225, 155, 153, 154, 155, 155, 155, 155, 153, 154, 98, 99, 100, 101, 102, 103, 104, 120, 405, 406, 407, 420, 421, 351, 397, 154, 168, 155, 153, 154, 155, 153, 154, 155, 153, 154, 168, 397, 405, 156, 417, 153, 152, 155, 155, 155, 155, 155, 155, 155, 155, 155, 167, 155, 168, 171, 155, 155, 152, 96, 34, 36, 381, 106, 203, 36, 183, 36, 187, 36, 191, 34, 195, 34, 199, 34, 106, 331, 155, 154, 163, 156, 214, 34, 95, 153, 160, 35, 115, 116, 354, 282, 35, 287, 36, 36, 277, 354, 354, 354, 354, 34, 106, 273, 152, 320, 36, 152, 324, 157, 276, 277, 258, 157, 261, 277, 265, 157, 268, 66, 67, 68, 368, 369, 370, 397, 397, 336, 158, 34, 179, 221, 363, 158, 157, 233, 157, 225, 381, 229, 36, 36, 36, 36, 242, 339, 339, 339, 339, 339, 152, 152, 339, 153, 154, 339, 155, 345, 153, 156, 206, 420, 277, 246, 277, 250, 351, 254, 213, 153, 17, 18, 19, 234, 238, 418, 419, 158, 420, 155, 155, 405, 34, 36, 106, 277, 400, 399, 27, 50, 51, 52, 97, 215, 216, 217, 234, 238, 294, 303, 307, 335, 34, 159, 339, 141, 321, 322, 132, 143, 325, 326, 333, 158, 158, 158, 154, 351, 366, 360, 156, 323, 327, 153, 157, 179, 397, 397, 397, 397, 397, 405, 405, 397, 96, 394, 407, 397, 152, 346, 349, 350, 122, 207, 208, 209, 234, 238, 294, 214, 394, 333, 333, 333, 157, 419, 17, 288, 153, 153, 169, 333, 333, 333, 333, 420, 157, 216, 34, 155, 153, 154, 155, 155, 153, 154, 369, 156, 371, 371, 34, 234, 238, 340, 341, 342, 152, 345, 345, 345, 153, 153, 126, 395, 351, 160, 161, 162, 163, 164, 165, 347, 159, 160, 161, 162, 164, 166, 348, 333, 157, 208, 395, 333, 18, 289, 158, 394, 278, 34, 158, 36, 322, 36, 36, 326, 11, 23, 34, 38, 39, 40, 41, 42, 43, 44, 45, 46, 51, 52, 53, 66, 67, 68, 69, 70, 72, 90, 97, 124, 130, 204, 218, 234, 238, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 307, 316, 323, 335, 357, 358, 361, 364, 372, 373, 374, 383, 384, 386, 391, 392, 408, 411, 413, 414, 416, 158, 158, 155, 344, 157, 342, 425, 339, 339, 119, 426, 153, 349, 36, 106, 107, 114, 117, 351, 354, 355, 424, 158, 426, 333, 19, 290, 395, 160, 152, 333, 333, 152, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, 71, 382, 382, 382, 169, 409, 410, 415, 412, 385, 152, 375, 157, 373, 166, 349, 397, 158, 153, 397, 397, 152, 155, 396, 152, 396, 333, 426, 278, 405, 405, 169, 169, 169, 90, 411, 411, 392, 420, 413, 34, 386, 133, 138, 142, 376, 377, 156, 378, 34, 154, 343, 397, 351, 427, 106, 397, 346, 356, 397, 396, 153, 153, 34, 155, 155, 155, 153, 154, 234, 238, 323, 379, 380, 152, 158, 153, 154, 170, 389, 153, 154, 389, 397, 394, 426, 34, 381, 34, 377, 157, 380, 153, 327, 351, 390, 158, 346, 158, 389, 426, 397, 158, 426, 420, 49, 403, 327, 158, 397, 170, 387, 396, 152, 333, 48, 402, 403, 403, 389, 388, 158, 397, 405, 333, 37, 404, 402, 402, 158, 152, 327, 158, 153, 333, 47, 401, 404, 404, 327, 405, 403, 403, 171, 333, 401, 401, 403, 153, 402, 402, 402, 171, 404 }; #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 defined YYLTYPE_IS_TRIVIAL && 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 /* 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 *bottom, yytype_int16 *top) #else static void yy_stack_print (bottom, top) yytype_int16 *bottom; yytype_int16 *top; #endif { YYFPRINTF (stderr, "Stack now"); for (; bottom <= top; ++bottom) YYFPRINTF (stderr, " %d", *bottom); 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++) { fprintf (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], &(yyvsp[(yyi + 1) - (yynrhs)]) ); fprintf (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 look-ahead symbol. */ int yychar; /* The semantic value of the look-ahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; /*----------. | yyparse. | `----------*/ #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; int yyn; int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* Look-ahead token as an internal (translated) token number. */ int yytoken = 0; #if YYERROR_VERBOSE /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYSIZE_T yymsg_alloc = sizeof yymsgbuf; #endif /* Three stacks and their tools: `yyss': related to states, `yyvs': related to semantic values, `yyls': related to locations. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ yytype_int16 yyssa[YYINITDEPTH]; yytype_int16 *yyss = yyssa; yytype_int16 *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) YYSIZE_T yystacksize = YYINITDEPTH; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; 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); YYSTACK_RELOCATE (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)); goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a look-ahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to look-ahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; /* Not known => get a look-ahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead 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; } if (yyn == YYFINAL) YYACCEPT; /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the look-ahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); /* Discard the shifted token unless it is eof. */ if (yychar != YYEOF) 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 580 "sip-4.19.7/sipgen/metasrc/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 55: #line 650 "sip-4.19.7/sipgen/metasrc/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 56: #line 663 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) currentModule->defdocstringfmt = convertFormat((yyvsp[(2) - (2)].defdocstringfmt).name); } break; case 57: #line 669 "sip-4.19.7/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.defdocstringfmt).name = (yyvsp[(1) - (1)].text); } break; case 58: #line 674 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.defdocstringfmt) = (yyvsp[(2) - (3)].defdocstringfmt); } break; case 60: #line 680 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.defdocstringfmt) = (yyvsp[(1) - (3)].defdocstringfmt); switch ((yyvsp[(3) - (3)].defdocstringfmt).token) { case TK_NAME: (yyval.defdocstringfmt).name = (yyvsp[(3) - (3)].defdocstringfmt).name; break; } } break; case 61: #line 690 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.defdocstringfmt).token = TK_NAME; (yyval.defdocstringfmt).name = (yyvsp[(3) - (3)].text); } break; case 62: #line 697 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) currentModule->defdocstringsig = convertSignature((yyvsp[(2) - (2)].defdocstringsig).name); } break; case 63: #line 703 "sip-4.19.7/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.defdocstringsig).name = (yyvsp[(1) - (1)].text); } break; case 64: #line 708 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.defdocstringsig) = (yyvsp[(2) - (3)].defdocstringsig); } break; case 66: #line 714 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.defdocstringsig) = (yyvsp[(1) - (3)].defdocstringsig); switch ((yyvsp[(3) - (3)].defdocstringsig).token) { case TK_NAME: (yyval.defdocstringsig).name = (yyvsp[(3) - (3)].defdocstringsig).name; break; } } break; case 67: #line 724 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.defdocstringsig).token = TK_NAME; (yyval.defdocstringsig).name = (yyvsp[(3) - (3)].text); } break; case 68: #line 731 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { if ((currentModule->encoding = convertEncoding((yyvsp[(2) - (2)].defencoding).name)) == no_type) yyerror("The %DefaultEncoding name must be one of \"ASCII\", \"Latin-1\", \"UTF-8\" or \"None\""); } } break; case 69: #line 740 "sip-4.19.7/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.defencoding).name = (yyvsp[(1) - (1)].text); } break; case 70: #line 745 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.defencoding) = (yyvsp[(2) - (3)].defencoding); } break; case 72: #line 751 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.defencoding) = (yyvsp[(1) - (3)].defencoding); switch ((yyvsp[(3) - (3)].defencoding).token) { case TK_NAME: (yyval.defencoding).name = (yyvsp[(3) - (3)].defencoding).name; break; } } break; case 73: #line 761 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.defencoding).token = TK_NAME; (yyval.defencoding).name = (yyvsp[(3) - (3)].text); } break; case 74: #line 768 "sip-4.19.7/sipgen/metasrc/parser.y" { /* * Note that %Plugin is internal in SIP v4. The current thinking * is that it won't be needed for SIP v5. */ if (notSkipping()) appendString(¤tSpec->plugins, (yyvsp[(2) - (2)].plugin).name); } break; case 75: #line 779 "sip-4.19.7/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.plugin).name = (yyvsp[(1) - (1)].text); } break; case 76: #line 784 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.plugin) = (yyvsp[(2) - (3)].plugin); } break; case 78: #line 790 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.plugin) = (yyvsp[(1) - (3)].plugin); switch ((yyvsp[(3) - (3)].plugin).token) { case TK_NAME: (yyval.plugin).name = (yyvsp[(3) - (3)].plugin).name; break; } } break; case 79: #line 800 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.plugin).token = TK_NAME; (yyval.plugin).name = (yyvsp[(3) - (3)].text); } break; case 80: #line 807 "sip-4.19.7/sipgen/metasrc/parser.y" { if ((yyvsp[(2) - (3)].veh).name == NULL) yyerror("%VirtualErrorHandler must have a 'name' argument"); if (notSkipping()) { virtErrorHandler *veh, **tailp; /* Check there isn't already a handler with the same name. */ for (tailp = ¤tSpec->errorhandlers; (veh = *tailp) != NULL; tailp = &veh->next) if (strcmp(veh->name, (yyvsp[(2) - (3)].veh).name) == 0) break; if (veh != NULL) yyerror("A virtual error handler with that name has already been defined"); veh = sipMalloc(sizeof (virtErrorHandler)); veh->name = (yyvsp[(2) - (3)].veh).name; appendCodeBlock(&veh->code, (yyvsp[(3) - (3)].codeb)); veh->mod = currentModule; veh->index = -1; veh->next = NULL; *tailp = veh; } } break; case 81: #line 836 "sip-4.19.7/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.veh).name = (yyvsp[(1) - (1)].text); } break; case 82: #line 841 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.veh) = (yyvsp[(2) - (3)].veh); } break; case 84: #line 847 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.veh) = (yyvsp[(1) - (3)].veh); switch ((yyvsp[(3) - (3)].veh).token) { case TK_NAME: (yyval.veh).name = (yyvsp[(3) - (3)].veh).name; break; } } break; case 85: #line 857 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.veh).token = TK_NAME; (yyval.veh).name = (yyvsp[(3) - (3)].text); } break; case 86: #line 864 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { apiVersionRangeDef *avd; if (findAPI(currentSpec, (yyvsp[(2) - (2)].api).name) != NULL) yyerror("The API name in the %API directive has already been defined"); if ((yyvsp[(2) - (2)].api).version < 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) - (2)].api).name); avd->from = (yyvsp[(2) - (2)].api).version; avd->to = -1; avd->next = currentModule->api_versions; currentModule->api_versions = avd; if (inMainModule()) setIsUsedName(avd->api_name); } } break; case 87: #line 890 "sip-4.19.7/sipgen/metasrc/parser.y" { resetLexerState(); deprecated("%API name and version number should be specified using the 'name' and 'version' arguments"); (yyval.api).name = (yyvsp[(1) - (2)].text); (yyval.api).version = (yyvsp[(2) - (2)].number); } break; case 88: #line 898 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.api) = (yyvsp[(2) - (3)].api); } break; case 90: #line 904 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.api) = (yyvsp[(1) - (3)].api); switch ((yyvsp[(3) - (3)].api).token) { case TK_NAME: (yyval.api).name = (yyvsp[(3) - (3)].api).name; break; case TK_VERSION: (yyval.api).version = (yyvsp[(3) - (3)].api).version; break; } } break; case 91: #line 915 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.api).token = TK_NAME; (yyval.api).name = (yyvsp[(3) - (3)].text); (yyval.api).version = 0; } break; case 92: #line 921 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.api).token = TK_VERSION; (yyval.api).name = NULL; (yyval.api).version = (yyvsp[(3) - (3)].number); } break; case 93: #line 929 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { static const char *annos[] = { "Default", "PyName", NULL }; exceptionDef *xd; const char *pyname; checkAnnos(&(yyvsp[(4) - (5)].optflags), annos); if (currentSpec->genc) yyerror("%Exception not allowed in a C module"); if ((yyvsp[(5) - (5)].exception).raise_code == NULL) yyerror("%Exception must have a %RaiseCode sub-directive"); pyname = getPythonName(currentModule, &(yyvsp[(4) - (5)].optflags), scopedNameTail((yyvsp[(2) - (5)].scpvalp))); checkAttributes(currentSpec, currentModule, NULL, NULL, pyname, FALSE); xd = findException(currentSpec, (yyvsp[(2) - (5)].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; appendCodeBlock(&xd->iff->hdrcode, (yyvsp[(5) - (5)].exception).type_header_code); xd->pyname = pyname; xd->bibase = (yyvsp[(3) - (5)].exceptionbase).bibase; xd->base = (yyvsp[(3) - (5)].exceptionbase).base; appendCodeBlock(&xd->raisecode, (yyvsp[(5) - (5)].exception).raise_code); if (getOptFlag(&(yyvsp[(4) - (5)].optflags), "Default", bool_flag) != NULL) currentModule->defexception = xd; } } break; case 94: #line 976 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.exceptionbase).bibase = NULL; (yyval.exceptionbase).base = NULL; } break; case 95: #line 980 "sip-4.19.7/sipgen/metasrc/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[] = { "BaseException", "Exception", "StopIteration", "GeneratorExit", "ArithmeticError", "LookupError", "StandardError", /* Python v2. */ "AssertionError", "AttributeError", "BufferError", "EOFError", "FloatingPointError", "OSError", "ImportError", "IndexError", "KeyError", "KeyboardInterrupt", "MemoryError", "NameError", "OverflowError", "RuntimeError", "NotImplementedError", "SyntaxError", "IndentationError", "TabError", "ReferenceError", "SystemError", "SystemExit", "TypeError", "UnboundLocalError", "UnicodeError", "UnicodeEncodeError", "UnicodeDecodeError", "UnicodeTranslateError", "ValueError", "ZeroDivisionError", "EnvironmentError", /* Python v2. */ "IOError", /* Python v2. */ "WindowsError", /* Python v2. */ "VMSError", /* Python v2. */ "BlockingIOError", "BrokenPipeError", "ChildProcessError", "ConnectionError", "ConnectionAbortedError", "ConnectionRefusedError", "ConnectionResetError", "FileExistsError", "FileNotFoundError", "InterruptedError", "IsADirectoryError", "NotADirectoryError", "PermissionError", "ProcessLookupError", "TimeoutError", "Warning", "UserWarning", "DeprecationWarning", "PendingDeprecationWarning", "SyntaxWarning", "RuntimeWarning", "FutureWarning", "ImportWarning", "UnicodeWarning", "BytesWarning", "ResourceWarning", 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 96: #line 1087 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.exception) = (yyvsp[(2) - (4)].exception); } break; case 98: #line 1093 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.exception) = (yyvsp[(1) - (2)].exception); switch ((yyvsp[(2) - (2)].exception).token) { case TK_RAISECODE: (yyval.exception).raise_code = (yyvsp[(2) - (2)].exception).raise_code; break; case TK_TYPEHEADERCODE: (yyval.exception).type_header_code = (yyvsp[(2) - (2)].exception).type_header_code; break; } } break; case 99: #line 1104 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.exception).token = TK_IF; } break; case 100: #line 1107 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.exception).token = TK_END; } break; case 101: #line 1110 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { (yyval.exception).token = TK_RAISECODE; (yyval.exception).raise_code = (yyvsp[(1) - (1)].codeb); } else { (yyval.exception).token = 0; (yyval.exception).raise_code = NULL; } (yyval.exception).type_header_code = NULL; } break; case 102: #line 1124 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { (yyval.exception).token = TK_TYPEHEADERCODE; (yyval.exception).type_header_code = (yyvsp[(1) - (1)].codeb); } else { (yyval.exception).token = 0; (yyval.exception).type_header_code = NULL; } (yyval.exception).raise_code = NULL; } break; case 103: #line 1140 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 104: #line 1145 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { static const char *annos[] = { "AllowNone", "API", "DocType", "NoRelease", "PyName", "TypeHint", "TypeHintIn", "TypeHintOut", "TypeHintValue", NULL }; checkAnnos(&(yyvsp[(3) - (3)].optflags), annos); currentMappedType = newMappedType(currentSpec, &(yyvsp[(2) - (3)].memArg), &(yyvsp[(3) - (3)].optflags)); } } break; case 106: #line 1168 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { static const char *annos[] = { "AllowNone", "DocType", "NoRelease", "TypeHint", "TypeHintIn", "TypeHintOut", "TypeHintValue", NULL }; int a; mappedTypeTmplDef *mtt; ifaceFileDef *iff; checkAnnos(&(yyvsp[(4) - (4)].optflags), annos); 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"); (yyvsp[(3) - (4)].memArg).u.td->fqname = fullyQualifiedName((yyvsp[(3) - (4)].memArg).u.td->fqname); /* 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)); mappedTypeAnnos(mtt->mt, &(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 108: #line 1235 "sip-4.19.7/sipgen/metasrc/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 113: #line 1255 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tMappedType->iff->hdrcode, (yyvsp[(1) - (1)].codeb)); } break; case 114: #line 1259 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tMappedType->typecode, (yyvsp[(1) - (1)].codeb)); } break; case 115: #line 1263 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { if (currentMappedType->convfromcode != NULL) yyerror("%MappedType has more than one %ConvertFromTypeCode directive"); appendCodeBlock(¤tMappedType->convfromcode, (yyvsp[(2) - (2)].codeb)); } } break; case 116: #line 1272 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { if (currentMappedType->convtocode != NULL) yyerror("%MappedType has more than one %ConvertToTypeCode directive"); appendCodeBlock(¤tMappedType->convtocode, (yyvsp[(2) - (2)].codeb)); } } break; case 117: #line 1281 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { if (currentMappedType->instancecode != NULL) yyerror("%MappedType has more than one %InstanceCode directive"); appendCodeBlock(¤tMappedType->instancecode, (yyvsp[(1) - (1)].codeb)); } } break; case 120: #line 1294 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { applyTypeFlags(currentModule, &(yyvsp[(2) - (14)].memArg), &(yyvsp[(9) - (14)].optflags)); (yyvsp[(5) - (14)].signature).result = (yyvsp[(2) - (14)].memArg); newFunction(currentSpec, currentModule, NULL, NULL, currentMappedType, 0, TRUE, FALSE, FALSE, FALSE, (yyvsp[(3) - (14)].text), &(yyvsp[(5) - (14)].signature), (yyvsp[(7) - (14)].number), FALSE, &(yyvsp[(9) - (14)].optflags), (yyvsp[(14) - (14)].codeb), NULL, NULL, (yyvsp[(8) - (14)].throwlist), (yyvsp[(10) - (14)].optsignature), (yyvsp[(12) - (14)].docstr), FALSE, (yyvsp[(13) - (14)].codeb)); } } break; case 121: #line 1309 "sip-4.19.7/sipgen/metasrc/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)), NULL, NULL, NULL, NULL); pushScope(ns); sectionFlags = 0; } } break; case 122: #line 1330 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { if (inMainModule()) { classDef *ns = currentScope(); setIsUsedName(ns->iff->name); setIsUsedName(ns->pyname); } popScope(); } } break; case 127: #line 1354 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { 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 128: #line 1364 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { 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 && selectedQualifier(neededQualifiers, qd)) ++nrneeded; if (nrneeded > 1) yyerror("No more than one of these %Platforms must be specified with the -t flag"); } } break; case 131: #line 1387 "sip-4.19.7/sipgen/metasrc/parser.y" { newQualifier(currentModule, -1, -1, notSkipping(), (yyvsp[(1) - (1)].text), platform_qualifier); } break; case 132: #line 1393 "sip-4.19.7/sipgen/metasrc/parser.y" { newQualifier(currentModule, -1, -1, notSkipping(), (yyvsp[(2) - (2)].feature).name, feature_qualifier); } break; case 133: #line 1399 "sip-4.19.7/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.feature).name = (yyvsp[(1) - (1)].text); } break; case 134: #line 1404 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.feature) = (yyvsp[(2) - (3)].feature); } break; case 136: #line 1410 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.feature) = (yyvsp[(1) - (3)].feature); switch ((yyvsp[(3) - (3)].feature).token) { case TK_NAME: (yyval.feature).name = (yyvsp[(3) - (3)].feature).name; break; } } break; case 137: #line 1420 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.feature).token = TK_NAME; (yyval.feature).name = (yyvsp[(3) - (3)].text); } break; case 138: #line 1427 "sip-4.19.7/sipgen/metasrc/parser.y" { currentTimelineOrder = 0; } break; case 139: #line 1430 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { 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 && selectedQualifier(neededQualifiers, qd)) ++nrneeded; if (nrneeded > 1) yyerror("At most one of this %Timeline must be specified with the -t flag"); currentModule->nrtimelines++; } } break; case 142: #line 1457 "sip-4.19.7/sipgen/metasrc/parser.y" { newQualifier(currentModule, currentModule->nrtimelines, currentTimelineOrder++, TRUE, (yyvsp[(1) - (1)].text), time_qualifier); } break; case 143: #line 1463 "sip-4.19.7/sipgen/metasrc/parser.y" { currentPlatforms = NULL; } break; case 144: #line 1465 "sip-4.19.7/sipgen/metasrc/parser.y" { if (stackPtr >= MAX_NESTED_IF) yyerror("Internal error: increase the value of MAX_NESTED_IF"); /* Nested %Ifs are implicit logical ands. */ if (stackPtr > 0) (yyvsp[(4) - (5)].boolean) = ((yyvsp[(4) - (5)].boolean) && skipStack[stackPtr - 1]); skipStack[stackPtr] = (yyvsp[(4) - (5)].boolean); platformStack[stackPtr] = currentPlatforms; ++stackPtr; } break; case 145: #line 1482 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.boolean) = platOrFeature((yyvsp[(1) - (1)].text), FALSE); } break; case 146: #line 1485 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.boolean) = platOrFeature((yyvsp[(2) - (2)].text), TRUE); } break; case 147: #line 1488 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.boolean) = (platOrFeature((yyvsp[(3) - (3)].text), FALSE) || (yyvsp[(1) - (3)].boolean)); } break; case 148: #line 1491 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.boolean) = (platOrFeature((yyvsp[(4) - (4)].text), TRUE) || (yyvsp[(1) - (4)].boolean)); } break; case 150: #line 1497 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.boolean) = timePeriod((yyvsp[(1) - (3)].text), (yyvsp[(3) - (3)].text)); } break; case 151: #line 1502 "sip-4.19.7/sipgen/metasrc/parser.y" { if (stackPtr-- <= 0) yyerror("Too many %End directives"); currentPlatforms = (stackPtr == 0 ? NULL : platformStack[stackPtr - 1]); } break; case 152: #line 1510 "sip-4.19.7/sipgen/metasrc/parser.y" { optFlag *of; if ((yyvsp[(3) - (3)].optflags).nrFlags != 0) deprecated("%License annotations are deprecated, use arguments instead"); if ((yyvsp[(2) - (3)].license).type == NULL) if ((of = getOptFlag(&(yyvsp[(3) - (3)].optflags), "Type", string_flag)) != NULL) (yyvsp[(2) - (3)].license).type = of->fvalue.sval; if ((yyvsp[(2) - (3)].license).licensee == NULL) if ((of = getOptFlag(&(yyvsp[(3) - (3)].optflags), "Licensee", string_flag)) != NULL) (yyvsp[(2) - (3)].license).licensee = of->fvalue.sval; if ((yyvsp[(2) - (3)].license).signature == NULL) if ((of = getOptFlag(&(yyvsp[(3) - (3)].optflags), "Signature", string_flag)) != NULL) (yyvsp[(2) - (3)].license).signature = of->fvalue.sval; if ((yyvsp[(2) - (3)].license).timestamp == NULL) if ((of = getOptFlag(&(yyvsp[(3) - (3)].optflags), "Timestamp", string_flag)) != NULL) (yyvsp[(2) - (3)].license).timestamp = of->fvalue.sval; if ((yyvsp[(2) - (3)].license).type == NULL) yyerror("%License must have a 'type' argument"); if (notSkipping()) { currentModule->license = sipMalloc(sizeof (licenseDef)); currentModule->license->type = (yyvsp[(2) - (3)].license).type; currentModule->license->licensee = (yyvsp[(2) - (3)].license).licensee; currentModule->license->sig = (yyvsp[(2) - (3)].license).signature; currentModule->license->timestamp = (yyvsp[(2) - (3)].license).timestamp; } } break; case 153: #line 1547 "sip-4.19.7/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.license).type = NULL; (yyval.license).licensee = NULL; (yyval.license).signature = NULL; (yyval.license).timestamp = NULL; } break; case 154: #line 1555 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.license).type = (yyvsp[(1) - (1)].text); (yyval.license).licensee = NULL; (yyval.license).signature = NULL; (yyval.license).timestamp = NULL; } break; case 155: #line 1561 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.license) = (yyvsp[(2) - (3)].license); } break; case 157: #line 1567 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.license) = (yyvsp[(1) - (3)].license); switch ((yyvsp[(3) - (3)].license).token) { case TK_TYPE: (yyval.license).type = (yyvsp[(3) - (3)].license).type; break; case TK_LICENSEE: (yyval.license).licensee = (yyvsp[(3) - (3)].license).licensee; break; case TK_SIGNATURE: (yyval.license).signature = (yyvsp[(3) - (3)].license).signature; break; case TK_TIMESTAMP: (yyval.license).timestamp = (yyvsp[(3) - (3)].license).timestamp; break; } } break; case 158: #line 1580 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.license).token = TK_NAME; (yyval.license).type = (yyvsp[(3) - (3)].text); (yyval.license).licensee = NULL; (yyval.license).signature = NULL; (yyval.license).timestamp = NULL; } break; case 159: #line 1588 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.license).token = TK_LICENSEE; (yyval.license).type = NULL; (yyval.license).licensee = (yyvsp[(3) - (3)].text); (yyval.license).signature = NULL; (yyval.license).timestamp = NULL; } break; case 160: #line 1596 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.license).token = TK_SIGNATURE; (yyval.license).type = NULL; (yyval.license).licensee = NULL; (yyval.license).signature = (yyvsp[(3) - (3)].text); (yyval.license).timestamp = NULL; } break; case 161: #line 1604 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.license).token = TK_TIMESTAMP; (yyval.license).type = NULL; (yyval.license).licensee = NULL; (yyval.license).signature = NULL; (yyval.license).timestamp = (yyvsp[(3) - (3)].text); } break; case 162: #line 1614 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { if (currentModule->defmetatype != NULL) yyerror("%DefaultMetatype has already been defined for this module"); currentModule->defmetatype = cacheName(currentSpec, (yyvsp[(2) - (2)].defmetatype).name); } } break; case 163: #line 1625 "sip-4.19.7/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.defmetatype).name = (yyvsp[(1) - (1)].text); } break; case 164: #line 1630 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.defmetatype) = (yyvsp[(2) - (3)].defmetatype); } break; case 166: #line 1636 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.defmetatype) = (yyvsp[(1) - (3)].defmetatype); switch ((yyvsp[(3) - (3)].defmetatype).token) { case TK_NAME: (yyval.defmetatype).name = (yyvsp[(3) - (3)].defmetatype).name; break; } } break; case 167: #line 1646 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.defmetatype).token = TK_NAME; (yyval.defmetatype).name = (yyvsp[(3) - (3)].text); } break; case 168: #line 1653 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { if (currentModule->defsupertype != NULL) yyerror("%DefaultSupertype has already been defined for this module"); currentModule->defsupertype = cacheName(currentSpec, (yyvsp[(2) - (2)].defsupertype).name); } } break; case 169: #line 1664 "sip-4.19.7/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.defsupertype).name = (yyvsp[(1) - (1)].text); } break; case 170: #line 1669 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.defsupertype) = (yyvsp[(2) - (3)].defsupertype); } break; case 172: #line 1675 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.defsupertype) = (yyvsp[(1) - (3)].defsupertype); switch ((yyvsp[(3) - (3)].defsupertype).token) { case TK_NAME: (yyval.defsupertype).name = (yyvsp[(3) - (3)].defsupertype).name; break; } } break; case 173: #line 1685 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.defsupertype).token = TK_NAME; (yyval.defsupertype).name = (yyvsp[(3) - (3)].text); } break; case 174: #line 1692 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { classDef *ns; ns = newClass(currentSpec, namespace_iface, NULL, fullyQualifiedName((yyvsp[(2) - (2)].hiddenns).name), NULL, NULL, NULL, NULL); setHiddenNamespace(ns); } } break; case 175: #line 1704 "sip-4.19.7/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.hiddenns).name = (yyvsp[(1) - (1)].scpvalp); } break; case 176: #line 1709 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.hiddenns) = (yyvsp[(2) - (3)].hiddenns); } break; case 178: #line 1715 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.hiddenns) = (yyvsp[(1) - (3)].hiddenns); switch ((yyvsp[(3) - (3)].hiddenns).token) { case TK_NAME: (yyval.hiddenns).name = (yyvsp[(3) - (3)].hiddenns).name; break; } } break; case 179: #line 1725 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.hiddenns).token = TK_NAME; (yyval.hiddenns).name = (yyvsp[(3) - (3)].scpvalp); } break; case 180: #line 1732 "sip-4.19.7/sipgen/metasrc/parser.y" { deprecated("%ConsolidatedModule is deprecated and will not be supported by SIP v5"); if (notSkipping()) { /* 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) - (3)].consmodule).name); currentModule->docstring = (yyvsp[(3) - (3)].consmodule).docstring; setIsConsolidated(currentModule); } } break; case 181: #line 1752 "sip-4.19.7/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.consmodule).name = (yyvsp[(1) - (1)].text); } break; case 182: #line 1757 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.consmodule) = (yyvsp[(2) - (3)].consmodule); } break; case 184: #line 1763 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.consmodule) = (yyvsp[(1) - (3)].consmodule); switch ((yyvsp[(3) - (3)].consmodule).token) { case TK_NAME: (yyval.consmodule).name = (yyvsp[(3) - (3)].consmodule).name; break; } } break; case 185: #line 1773 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.consmodule).token = TK_NAME; (yyval.consmodule).name = (yyvsp[(3) - (3)].text); } break; case 186: #line 1780 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.consmodule).token = 0; (yyval.consmodule).docstring = NULL; } break; case 187: #line 1784 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.consmodule) = (yyvsp[(2) - (4)].consmodule); } break; case 189: #line 1790 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.consmodule) = (yyvsp[(1) - (2)].consmodule); switch ((yyvsp[(2) - (2)].consmodule).token) { case TK_DOCSTRING: (yyval.consmodule).docstring = (yyvsp[(2) - (2)].consmodule).docstring; break; } } break; case 190: #line 1800 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.consmodule).token = TK_IF; } break; case 191: #line 1803 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.consmodule).token = TK_END; } break; case 192: #line 1806 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { (yyval.consmodule).token = TK_DOCSTRING; (yyval.consmodule).docstring = (yyvsp[(1) - (1)].docstr); } else { (yyval.consmodule).token = 0; (yyval.consmodule).docstring = NULL; } } break; case 193: #line 1820 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { /* 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 directive"); setModuleName(currentSpec, currentModule, (yyvsp[(2) - (3)].compmodule).name); currentModule->docstring = (yyvsp[(3) - (3)].compmodule).docstring; setIsComposite(currentModule); } } break; case 194: #line 1838 "sip-4.19.7/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.compmodule).name = (yyvsp[(1) - (1)].text); } break; case 195: #line 1843 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.compmodule) = (yyvsp[(2) - (3)].compmodule); } break; case 197: #line 1849 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.compmodule) = (yyvsp[(1) - (3)].compmodule); switch ((yyvsp[(3) - (3)].compmodule).token) { case TK_NAME: (yyval.compmodule).name = (yyvsp[(3) - (3)].compmodule).name; break; } } break; case 198: #line 1859 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.compmodule).token = TK_NAME; (yyval.compmodule).name = (yyvsp[(3) - (3)].text); } break; case 199: #line 1866 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.compmodule).token = 0; (yyval.compmodule).docstring = NULL; } break; case 200: #line 1870 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.compmodule) = (yyvsp[(2) - (4)].compmodule); } break; case 202: #line 1876 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.compmodule) = (yyvsp[(1) - (2)].compmodule); switch ((yyvsp[(2) - (2)].compmodule).token) { case TK_DOCSTRING: (yyval.compmodule).docstring = (yyvsp[(2) - (2)].compmodule).docstring; break; } } break; case 203: #line 1886 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.compmodule).token = TK_IF; } break; case 204: #line 1889 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.compmodule).token = TK_END; } break; case 205: #line 1892 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { (yyval.compmodule).token = TK_DOCSTRING; (yyval.compmodule).docstring = (yyvsp[(1) - (1)].docstr); } else { (yyval.compmodule).token = 0; (yyval.compmodule).docstring = NULL; } } break; case 206: #line 1906 "sip-4.19.7/sipgen/metasrc/parser.y" { if ((yyvsp[(2) - (3)].module).name == NULL) yyerror("%Module must have a 'name' argument"); if (notSkipping()) currentModule = configureModule(currentSpec, currentModule, currentContext.filename, (yyvsp[(2) - (3)].module).name, (yyvsp[(2) - (3)].module).c_module, (yyvsp[(2) - (3)].module).kwargs, (yyvsp[(2) - (3)].module).use_arg_names, (yyvsp[(2) - (3)].module).use_limited_api, (yyvsp[(2) - (3)].module).call_super_init, (yyvsp[(2) - (3)].module).all_raise_py_exc, (yyvsp[(2) - (3)].module).def_error_handler, (yyvsp[(3) - (3)].module).docstring); } break; case 207: #line 1917 "sip-4.19.7/sipgen/metasrc/parser.y" { deprecated("%CModule is deprecated, use %Module and the 'language' argument instead"); if (notSkipping()) currentModule = configureModule(currentSpec, currentModule, currentContext.filename, (yyvsp[(2) - (3)].text), TRUE, defaultKwArgs, FALSE, FALSE, -1, FALSE, NULL, NULL); } break; case 208: #line 1927 "sip-4.19.7/sipgen/metasrc/parser.y" {resetLexerState();} break; case 209: #line 1927 "sip-4.19.7/sipgen/metasrc/parser.y" { if ((yyvsp[(3) - (3)].number) >= 0) deprecated("%Module version number should be specified using the 'version' argument"); (yyval.module).c_module = FALSE; (yyval.module).kwargs = defaultKwArgs; (yyval.module).name = (yyvsp[(1) - (3)].text); (yyval.module).use_arg_names = FALSE; (yyval.module).use_limited_api = FALSE; (yyval.module).all_raise_py_exc = FALSE; (yyval.module).call_super_init = -1; (yyval.module).def_error_handler = NULL; } break; case 210: #line 1940 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.module) = (yyvsp[(2) - (3)].module); } break; case 212: #line 1946 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.module) = (yyvsp[(1) - (3)].module); switch ((yyvsp[(3) - (3)].module).token) { case TK_KWARGS: (yyval.module).kwargs = (yyvsp[(3) - (3)].module).kwargs; break; case TK_LANGUAGE: (yyval.module).c_module = (yyvsp[(3) - (3)].module).c_module; break; case TK_NAME: (yyval.module).name = (yyvsp[(3) - (3)].module).name; break; case TK_USEARGNAMES: (yyval.module).use_arg_names = (yyvsp[(3) - (3)].module).use_arg_names; break; case TK_USELIMITEDAPI: (yyval.module).use_limited_api = (yyvsp[(3) - (3)].module).use_limited_api; break; case TK_ALLRAISEPYEXC: (yyval.module).all_raise_py_exc = (yyvsp[(3) - (3)].module).all_raise_py_exc; break; case TK_CALLSUPERINIT: (yyval.module).call_super_init = (yyvsp[(3) - (3)].module).call_super_init; break; case TK_DEFERRORHANDLER: (yyval.module).def_error_handler = (yyvsp[(3) - (3)].module).def_error_handler; break; } } break; case 213: #line 1963 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.module).token = TK_KWARGS; (yyval.module).c_module = FALSE; (yyval.module).kwargs = convertKwArgs((yyvsp[(3) - (3)].text)); (yyval.module).name = NULL; (yyval.module).use_arg_names = FALSE; (yyval.module).use_limited_api = FALSE; (yyval.module).all_raise_py_exc = FALSE; (yyval.module).call_super_init = -1; (yyval.module).def_error_handler = NULL; } break; case 214: #line 1975 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.module).token = TK_LANGUAGE; if (strcmp((yyvsp[(3) - (3)].text), "C++") == 0) (yyval.module).c_module = FALSE; else if (strcmp((yyvsp[(3) - (3)].text), "C") == 0) (yyval.module).c_module = TRUE; else yyerror("%Module 'language' argument must be either \"C++\" or \"C\""); (yyval.module).kwargs = defaultKwArgs; (yyval.module).name = NULL; (yyval.module).use_arg_names = FALSE; (yyval.module).use_limited_api = FALSE; (yyval.module).all_raise_py_exc = FALSE; (yyval.module).call_super_init = -1; (yyval.module).def_error_handler = NULL; } break; case 215: #line 1993 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.module).token = TK_NAME; (yyval.module).c_module = FALSE; (yyval.module).kwargs = defaultKwArgs; (yyval.module).name = (yyvsp[(3) - (3)].text); (yyval.module).use_arg_names = FALSE; (yyval.module).use_limited_api = FALSE; (yyval.module).all_raise_py_exc = FALSE; (yyval.module).call_super_init = -1; (yyval.module).def_error_handler = NULL; } break; case 216: #line 2005 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.module).token = TK_USEARGNAMES; (yyval.module).c_module = FALSE; (yyval.module).kwargs = defaultKwArgs; (yyval.module).name = NULL; (yyval.module).use_arg_names = (yyvsp[(3) - (3)].boolean); (yyval.module).use_limited_api = FALSE; (yyval.module).all_raise_py_exc = FALSE; (yyval.module).call_super_init = -1; (yyval.module).def_error_handler = NULL; } break; case 217: #line 2017 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.module).token = TK_USELIMITEDAPI; (yyval.module).c_module = FALSE; (yyval.module).kwargs = defaultKwArgs; (yyval.module).name = NULL; (yyval.module).use_arg_names = FALSE; (yyval.module).use_limited_api = (yyvsp[(3) - (3)].boolean); (yyval.module).all_raise_py_exc = FALSE; (yyval.module).call_super_init = -1; (yyval.module).def_error_handler = NULL; } break; case 218: #line 2029 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.module).token = TK_ALLRAISEPYEXC; (yyval.module).c_module = FALSE; (yyval.module).kwargs = defaultKwArgs; (yyval.module).name = NULL; (yyval.module).use_arg_names = FALSE; (yyval.module).use_limited_api = FALSE; (yyval.module).all_raise_py_exc = (yyvsp[(3) - (3)].boolean); (yyval.module).call_super_init = -1; (yyval.module).def_error_handler = NULL; } break; case 219: #line 2041 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.module).token = TK_CALLSUPERINIT; (yyval.module).c_module = FALSE; (yyval.module).kwargs = defaultKwArgs; (yyval.module).name = NULL; (yyval.module).use_arg_names = FALSE; (yyval.module).use_limited_api = FALSE; (yyval.module).all_raise_py_exc = FALSE; (yyval.module).call_super_init = (yyvsp[(3) - (3)].boolean); (yyval.module).def_error_handler = NULL; } break; case 220: #line 2053 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.module).token = TK_DEFERRORHANDLER; (yyval.module).c_module = FALSE; (yyval.module).kwargs = defaultKwArgs; (yyval.module).name = NULL; (yyval.module).use_arg_names = FALSE; (yyval.module).use_limited_api = FALSE; (yyval.module).all_raise_py_exc = FALSE; (yyval.module).call_super_init = -1; (yyval.module).def_error_handler = (yyvsp[(3) - (3)].text); } break; case 221: #line 2065 "sip-4.19.7/sipgen/metasrc/parser.y" { deprecated("%Module version numbers are deprecated and ignored"); if ((yyvsp[(3) - (3)].number) < 0) yyerror("%Module 'version' argument cannot be negative"); (yyval.module).token = TK_VERSION; (yyval.module).c_module = FALSE; (yyval.module).kwargs = defaultKwArgs; (yyval.module).name = NULL; (yyval.module).use_arg_names = FALSE; (yyval.module).use_limited_api = FALSE; (yyval.module).all_raise_py_exc = FALSE; (yyval.module).call_super_init = -1; (yyval.module).def_error_handler = NULL; } break; case 222: #line 2084 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.module).token = 0; (yyval.module).docstring = NULL; } break; case 223: #line 2088 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.module) = (yyvsp[(2) - (4)].module); } break; case 225: #line 2094 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.module) = (yyvsp[(1) - (2)].module); switch ((yyvsp[(2) - (2)].module).token) { case TK_DOCSTRING: (yyval.module).docstring = (yyvsp[(2) - (2)].module).docstring; break; } } break; case 226: #line 2104 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.module).token = TK_IF; } break; case 227: #line 2107 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.module).token = TK_END; } break; case 228: #line 2110 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.module).token = TK_AUTOPYNAME; } break; case 229: #line 2113 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { (yyval.module).token = TK_DOCSTRING; (yyval.module).docstring = (yyvsp[(1) - (1)].docstr); } else { (yyval.module).token = 0; (yyval.module).docstring = NULL; } } break; case 231: #line 2128 "sip-4.19.7/sipgen/metasrc/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 232: #line 2144 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.number) = -1; } break; case 234: #line 2150 "sip-4.19.7/sipgen/metasrc/parser.y" { if ((yyvsp[(2) - (2)].include).name == NULL) yyerror("%Include must have a 'name' argument"); if (notSkipping()) parseFile(NULL, (yyvsp[(2) - (2)].include).name, NULL, (yyvsp[(2) - (2)].include).optional); } break; case 235: #line 2159 "sip-4.19.7/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.include).name = (yyvsp[(1) - (1)].text); (yyval.include).optional = FALSE; } break; case 236: #line 2165 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.include) = (yyvsp[(2) - (3)].include); } break; case 238: #line 2171 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.include) = (yyvsp[(1) - (3)].include); switch ((yyvsp[(3) - (3)].include).token) { case TK_NAME: (yyval.include).name = (yyvsp[(3) - (3)].include).name; break; case TK_OPTIONAL: (yyval.include).optional = (yyvsp[(3) - (3)].include).optional; break; } } break; case 239: #line 2182 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.include).token = TK_NAME; (yyval.include).name = (yyvsp[(3) - (3)].text); (yyval.include).optional = FALSE; } break; case 240: #line 2188 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.include).token = TK_OPTIONAL; (yyval.include).name = NULL; (yyval.include).optional = (yyvsp[(3) - (3)].boolean); } break; case 241: #line 2196 "sip-4.19.7/sipgen/metasrc/parser.y" { deprecated("%OptionalInclude is deprecated, use %Include and the 'optional' argument instead"); if (notSkipping()) parseFile(NULL, (yyvsp[(2) - (2)].text), NULL, TRUE); } break; case 242: #line 2204 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) newImport((yyvsp[(2) - (2)].import).name); } break; case 243: #line 2210 "sip-4.19.7/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.import).name = (yyvsp[(1) - (1)].text); } break; case 244: #line 2215 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.import) = (yyvsp[(2) - (3)].import); } break; case 246: #line 2221 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.import) = (yyvsp[(1) - (3)].import); switch ((yyvsp[(3) - (3)].import).token) { case TK_NAME: (yyval.import).name = (yyvsp[(3) - (3)].import).name; break; } } break; case 247: #line 2231 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.import).token = TK_NAME; (yyval.import).name = (yyvsp[(3) - (3)].text); } break; case 248: #line 2238 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = NULL; } break; case 249: #line 2241 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 250: #line 2246 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = NULL; } break; case 251: #line 2249 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 252: #line 2254 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = NULL; } break; case 253: #line 2257 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 254: #line 2262 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tModule->copying, (yyvsp[(2) - (2)].codeb)); } break; case 255: #line 2268 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tSpec->exphdrcode, (yyvsp[(2) - (2)].codeb)); } break; case 256: #line 2274 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tModule->hdrcode, (yyvsp[(2) - (2)].codeb)); } break; case 257: #line 2280 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 258: #line 2285 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 259: #line 2290 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 260: #line 2295 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 261: #line 2300 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 262: #line 2305 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 263: #line 2310 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 264: #line 2315 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 265: #line 2320 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 266: #line 2325 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 267: #line 2330 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 268: #line 2335 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 269: #line 2340 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tModule->cppcode, (yyvsp[(2) - (2)].codeb)); } break; case 270: #line 2346 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 271: #line 2351 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tModule->preinitcode, (yyvsp[(2) - (2)].codeb)); } break; case 272: #line 2357 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tModule->initcode, (yyvsp[(2) - (2)].codeb)); } break; case 273: #line 2363 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tModule->postinitcode, (yyvsp[(2) - (2)].codeb)); } break; case 274: #line 2369 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tModule->unitcode, (yyvsp[(2) - (2)].codeb)); } break; case 275: #line 2375 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tModule->unitpostinccode, (yyvsp[(2) - (2)].codeb)); } break; case 276: #line 2381 "sip-4.19.7/sipgen/metasrc/parser.y" { /* Deprecated. */ } break; case 277: #line 2386 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping() && !inMainModule()) appendCodeBlock(¤tSpec->exptypehintcode, (yyvsp[(2) - (2)].codeb)); } break; case 278: #line 2392 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tModule->typehintcode, (yyvsp[(2) - (2)].codeb)); } break; case 279: #line 2398 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 280: #line 2403 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping() && inMainModule()) appendCodeBlock(¤tSpec->docs, (yyvsp[(2) - (2)].codeb)); } break; case 281: #line 2409 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tSpec->docs, (yyvsp[(2) - (2)].codeb)); } break; case 282: #line 2415 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) addAutoPyName(currentModule, (yyvsp[(2) - (2)].autopyname).remove_leading); } break; case 283: #line 2421 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.autopyname) = (yyvsp[(2) - (3)].autopyname); } break; case 285: #line 2427 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.autopyname) = (yyvsp[(1) - (3)].autopyname); switch ((yyvsp[(3) - (3)].autopyname).token) { case TK_REMOVELEADING: (yyval.autopyname).remove_leading = (yyvsp[(3) - (3)].autopyname).remove_leading; break; } } break; case 286: #line 2437 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.autopyname).token = TK_REMOVELEADING; (yyval.autopyname).remove_leading = (yyvsp[(3) - (3)].text); } break; case 287: #line 2444 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.docstr) = sipMalloc(sizeof(docstringDef)); (yyval.docstr)->signature = (yyvsp[(2) - (3)].docstring).signature; (yyval.docstr)->text = (yyvsp[(3) - (3)].codeb)->frag; free((yyvsp[(3) - (3)].codeb)); /* Format the docstring. */ if ((yyvsp[(2) - (3)].docstring).format == deindented) { const char *cp; char *dp; int min_indent, indent, skipping; /* Find the common indent. */ min_indent = -1; indent = 0; skipping = FALSE; for (cp = (yyval.docstr)->text; *cp != '\0'; ++cp) { if (skipping) { /* * We have handled the indent and are just looking for * the end of the line. */ if (*cp == '\n') skipping = FALSE; } else { if (*cp == ' ') { ++indent; } else if (*cp != '\n') { if (min_indent < 0 || min_indent > indent) min_indent = indent; /* Ignore the remaining characters of the line. */ skipping = TRUE; } } } /* In case the last line doesn't have a trailing newline. */ if (min_indent < 0 || min_indent > indent) min_indent = indent; /* * Go through the text again removing the common indentation. */ cp = dp = (yyval.docstr)->text; while (*cp != '\0') { const char *start = cp; int non_blank = FALSE; /* Find the end of the line. */ while (*cp != '\n' && *cp != '\0') if (*cp++ != ' ') non_blank = TRUE; /* Find where we are copying from. */ if (non_blank) { start += min_indent; while (*start != '\n' && *start != '\0') *dp++ = *start++; } if (*cp == '\n') *dp++ = *cp++; } *dp = '\0'; } } break; case 288: #line 2528 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.docstring).format = currentModule->defdocstringfmt; (yyval.docstring).signature = currentModule->defdocstringsig; } break; case 289: #line 2532 "sip-4.19.7/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.docstring).format = convertFormat((yyvsp[(1) - (1)].text)); (yyval.docstring).signature = currentModule->defdocstringsig; } break; case 290: #line 2538 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.docstring) = (yyvsp[(2) - (3)].docstring); } break; case 292: #line 2544 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.docstring) = (yyvsp[(1) - (3)].docstring); switch ((yyvsp[(3) - (3)].docstring).token) { case TK_FORMAT: (yyval.docstring).format = (yyvsp[(3) - (3)].docstring).format; break; case TK_SIGNATURE: (yyval.docstring).signature = (yyvsp[(3) - (3)].docstring).signature; break; } } break; case 293: #line 2555 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.docstring).token = TK_FORMAT; (yyval.docstring).format = convertFormat((yyvsp[(3) - (3)].text)); (yyval.docstring).signature = currentModule->defdocstringsig; } break; case 294: #line 2561 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.docstring).token = TK_SIGNATURE; (yyval.docstring).format = currentModule->defdocstringfmt; (yyval.docstring).signature = convertSignature((yyvsp[(3) - (3)].text)); } break; case 295: #line 2569 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.docstr) = NULL; } break; case 297: #line 2575 "sip-4.19.7/sipgen/metasrc/parser.y" { if ((yyvsp[(2) - (3)].extract).id == NULL) yyerror("%Extract must have an 'id' argument"); if (notSkipping()) addExtractPart(currentSpec, (yyvsp[(2) - (3)].extract).id, (yyvsp[(2) - (3)].extract).order, (yyvsp[(3) - (3)].codeb)); } break; case 298: #line 2584 "sip-4.19.7/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.extract).id = (yyvsp[(1) - (1)].text); (yyval.extract).order = -1; } break; case 299: #line 2590 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.extract) = (yyvsp[(2) - (3)].extract); } break; case 301: #line 2596 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.extract) = (yyvsp[(1) - (3)].extract); switch ((yyvsp[(3) - (3)].extract).token) { case TK_ID: (yyval.extract).id = (yyvsp[(3) - (3)].extract).id; break; case TK_ORDER: (yyval.extract).order = (yyvsp[(3) - (3)].extract).order; break; } } break; case 302: #line 2607 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.extract).token = TK_ID; (yyval.extract).id = (yyvsp[(3) - (3)].text); (yyval.extract).order = -1; } break; case 303: #line 2613 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.extract).token = TK_ORDER; if ((yyvsp[(3) - (3)].number) < 0) yyerror("The 'order' of an %Extract directive must not be negative"); (yyval.extract).id = NULL; (yyval.extract).order = (yyvsp[(3) - (3)].number); } break; case 304: #line 2624 "sip-4.19.7/sipgen/metasrc/parser.y" { /* Deprecated. */ } break; case 307: #line 2633 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(1) - (2)].codeb); append(&(yyval.codeb)->frag, (yyvsp[(2) - (2)].codeb)->frag); free((yyvsp[(2) - (2)].codeb)->frag); free((yyvsp[(2) - (2)].codeb)); } break; case 308: #line 2643 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { const char *annos[] = { "NoScope", "NoTypeHint", "PyName", NULL }; checkAnnos(&(yyvsp[(4) - (4)].optflags), annos); if (sectionFlags != 0 && (sectionFlags & ~(SECT_IS_PUBLIC | SECT_IS_PROT)) != 0) yyerror("Class enums must be in the public or protected sections"); if (currentSpec->genc && (yyvsp[(2) - (4)].boolean)) yyerror("Scoped enums not allowed in a C module"); currentEnum = newEnum(currentSpec, currentModule, currentMappedType, (yyvsp[(3) - (4)].text), &(yyvsp[(4) - (4)].optflags), sectionFlags, (yyvsp[(2) - (4)].boolean)); } } break; case 310: #line 2667 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.boolean) = FALSE; } break; case 311: #line 2670 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.boolean) = TRUE; } break; case 312: #line 2673 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.boolean) = TRUE; } break; case 313: #line 2678 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.text) = NULL; } break; case 314: #line 2681 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.text) = (yyvsp[(1) - (1)].text); } break; case 315: #line 2686 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.text) = NULL; } break; case 316: #line 2689 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.text) = (yyvsp[(1) - (1)].text); } break; case 323: #line 2704 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { const char *annos[] = { "NoTypeHint", "PyName", NULL }; enumMemberDef *emd, **tail; checkAnnos(&(yyvsp[(3) - (4)].optflags), annos); /* Note that we don't use the assigned value. */ emd = sipMalloc(sizeof (enumMemberDef)); emd->pyname = cacheName(currentSpec, getPythonName(currentModule, &(yyvsp[(3) - (4)].optflags), (yyvsp[(1) - (4)].text))); emd->cname = (yyvsp[(1) - (4)].text); emd->no_typehint = getNoTypeHint(&(yyvsp[(3) - (4)].optflags)); emd->ed = currentEnum; emd->platforms = currentPlatforms; emd->next = NULL; checkAttributes(currentSpec, currentModule, emd->ed->ecd, emd->ed->emtd, emd->pyname->text, FALSE); /* Append to preserve the order. */ for (tail = ¤tEnum->members; *tail != NULL; tail = &(*tail)->next) ; *tail = emd; if (inMainModule()) setIsUsedName(emd->pyname); } } break; case 328: #line 2751 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.valp) = NULL; } break; case 329: #line 2754 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.valp) = (yyvsp[(2) - (2)].valp); } break; case 331: #line 2760 "sip-4.19.7/sipgen/metasrc/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 332: #line 2778 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.qchar) = '-'; } break; case 333: #line 2781 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.qchar) = '+'; } break; case 334: #line 2784 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.qchar) = '*'; } break; case 335: #line 2787 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.qchar) = '/'; } break; case 336: #line 2790 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.qchar) = '&'; } break; case 337: #line 2793 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.qchar) = '|'; } break; case 338: #line 2798 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.qchar) = '\0'; } break; case 339: #line 2801 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.qchar) = '!'; } break; case 340: #line 2804 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.qchar) = '~'; } break; case 341: #line 2807 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.qchar) = '-'; } break; case 342: #line 2810 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.qchar) = '+'; } break; case 343: #line 2813 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.qchar) = '*'; } break; case 344: #line 2816 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.qchar) = '&'; } break; case 345: #line 2821 "sip-4.19.7/sipgen/metasrc/parser.y" { if ((yyvsp[(2) - (3)].qchar) != '\0' && (yyvsp[(3) - (3)].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[(3) - (3)].value); (yyval.valp)->vunop = (yyvsp[(2) - (3)].qchar); (yyval.valp)->vbinop = '\0'; (yyval.valp)->cast = (yyvsp[(1) - (3)].scpvalp); (yyval.valp)->next = NULL; } break; case 346: #line 2836 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.scpvalp) = NULL; } break; case 347: #line 2839 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.scpvalp) = (yyvsp[(2) - (3)].scpvalp); } break; case 348: #line 2844 "sip-4.19.7/sipgen/metasrc/parser.y" { if (currentSpec->genc) yyerror("Scoped names are not allowed in a C module"); (yyval.scpvalp) = scopeScopedName(NULL, (yyvsp[(2) - (2)].scpvalp)); } break; case 351: #line 2854 "sip-4.19.7/sipgen/metasrc/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 352: #line 2862 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.scpvalp) = text2scopePart((yyvsp[(1) - (1)].text)); } break; case 353: #line 2867 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.boolean) = TRUE; } break; case 354: #line 2870 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.boolean) = FALSE; } break; case 355: #line 2875 "sip-4.19.7/sipgen/metasrc/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 356: #line 2884 "sip-4.19.7/sipgen/metasrc/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 357: #line 2894 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.value).vtype = real_value; (yyval.value).u.vreal = (yyvsp[(1) - (1)].real); } break; case 358: #line 2898 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.value).vtype = numeric_value; (yyval.value).u.vnum = (yyvsp[(1) - (1)].number); } break; case 359: #line 2902 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.value).vtype = numeric_value; (yyval.value).u.vnum = (yyvsp[(1) - (1)].boolean); } break; case 360: #line 2906 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.value).vtype = numeric_value; (yyval.value).u.vnum = 0; } break; case 361: #line 2910 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.value).vtype = string_value; (yyval.value).u.vstr = (yyvsp[(1) - (1)].text); } break; case 362: #line 2914 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.value).vtype = qchar_value; (yyval.value).u.vqchar = (yyvsp[(1) - (1)].qchar); } break; case 363: #line 2920 "sip-4.19.7/sipgen/metasrc/parser.y" { /* No values. */ (yyval.fcall).nrArgs = 0; } break; case 364: #line 2925 "sip-4.19.7/sipgen/metasrc/parser.y" { /* The single or first expression. */ (yyval.fcall).args[0] = (yyvsp[(1) - (1)].valp); (yyval.fcall).nrArgs = 1; } break; case 365: #line 2931 "sip-4.19.7/sipgen/metasrc/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("Internal error - increase the value of MAX_NR_ARGS"); (yyval.fcall) = (yyvsp[(1) - (3)].fcall); (yyval.fcall).args[(yyval.fcall).nrArgs] = (yyvsp[(3) - (3)].valp); (yyval.fcall).nrArgs++; } break; case 366: #line 2949 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { const char *annos[] = { "Capsule", "DocType", "Encoding", "NoTypeName", "PyInt", "PyName", "TypeHint", "TypeHintIn", "TypeHintOut", NULL }; checkAnnos(&(yyvsp[(4) - (6)].optflags), annos); applyTypeFlags(currentModule, &(yyvsp[(2) - (6)].memArg), &(yyvsp[(4) - (6)].optflags)); newTypedef(currentSpec, currentModule, (yyvsp[(3) - (6)].text), &(yyvsp[(2) - (6)].memArg), &(yyvsp[(4) - (6)].optflags), (yyvsp[(6) - (6)].docstr)); } } break; case 367: #line 2971 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { const char *annos[] = { "DocType", "Encoding", "NoTypeName", "PyInt", "PyName", "TypeHint", "TypeHintIn", "TypeHintOut", NULL }; signatureDef *sig; argDef ftype; checkAnnos(&(yyvsp[(10) - (12)].optflags), annos); applyTypeFlags(currentModule, &(yyvsp[(2) - (12)].memArg), &(yyvsp[(10) - (12)].optflags)); memset(&ftype, 0, sizeof (argDef)); /* Create the full signature on the heap. */ sig = sipMalloc(sizeof (signatureDef)); *sig = (yyvsp[(8) - (12)].signature); sig->result = (yyvsp[(2) - (12)].memArg); /* Create the full type. */ ftype.atype = function_type; ftype.nrderefs = 1; ftype.u.sa = sig; newTypedef(currentSpec, currentModule, (yyvsp[(5) - (12)].text), &ftype, &(yyvsp[(10) - (12)].optflags), (yyvsp[(12) - (12)].docstr)); } } break; case 368: #line 3010 "sip-4.19.7/sipgen/metasrc/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 369: #line 3016 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { const char *annos[] = { "Abstract", "AllowNone", "API", "DelayDtor", "Deprecated", "ExportDerived", "External", "FileExtension", "Metatype", "Mixin", "NoDefaultCtors", "NoTypeHint", "PyName", "PyQtFlags", "PyQtInterface", "PyQtNoQMetaObject", "Supertype", "TypeHint", "TypeHintIn", "TypeHintOut", "TypeHintValue", "VirtualErrorHandler", NULL }; checkAnnos(&(yyvsp[(5) - (5)].optflags), annos); 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 370: #line 3053 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) completeClass((yyvsp[(2) - (8)].scpvalp), &(yyvsp[(5) - (8)].optflags), (yyvsp[(7) - (8)].boolean)); } break; case 371: #line 3059 "sip-4.19.7/sipgen/metasrc/parser.y" {currentIsTemplate = TRUE;} break; case 372: #line 3059 "sip-4.19.7/sipgen/metasrc/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 373: #line 3085 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.signature) = (yyvsp[(3) - (4)].signature); } break; case 374: #line 3090 "sip-4.19.7/sipgen/metasrc/parser.y" { if (currentSpec->genc) yyerror("Class definition not allowed in a C module"); if (notSkipping()) currentSupers = NULL; } break; case 375: #line 3096 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { const char *annos[] = { "Abstract", "AllowNone", "API", "DelayDtor", "Deprecated", "ExportDerived", "External", "FileExtension", "Metatype", "Mixin", "NoDefaultCtors", "PyName", "PyQtFlags", "PyQtInterface", "PyQtNoQMetaObject", "Supertype", "TypeHint", "TypeHintIn", "TypeHintOut", "TypeHintValue", "VirtualErrorHandler", NULL }; checkAnnos(&(yyvsp[(5) - (5)].optflags), annos); defineClass((yyvsp[(2) - (5)].scpvalp), currentSupers, &(yyvsp[(5) - (5)].optflags)); sectionFlags = SECT_IS_PRIVATE; } } break; case 376: #line 3129 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) (yyval.klass) = completeClass((yyvsp[(2) - (8)].scpvalp), &(yyvsp[(5) - (8)].optflags), (yyvsp[(7) - (8)].boolean)); } break; case 381: #line 3143 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping() && (yyvsp[(1) - (2)].token) == TK_PUBLIC) { argDef ad; classDef *super; scopedNameDef *snd = (yyvsp[(2) - (2)].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"); /* * This is a bug because we should look in the local scope * rather than assume it is in the global scope. */ if (snd->name[0] != '\0') snd = scopeScopedName(NULL, snd); /* * Note that passing NULL as the API is a bug. Instead we * should pass the API of the sub-class being defined, * otherwise we cannot create sub-classes of versioned classes. */ super = findClass(currentSpec, class_iface, NULL, snd, currentIsTemplate); appendToClassList(¤tSupers, super); } } break; case 382: #line 3195 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.token) = TK_PUBLIC; } break; case 383: #line 3198 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.token) = TK_PUBLIC; } break; case 384: #line 3201 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.token) = TK_PROTECTED; } break; case 385: #line 3204 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.token) = TK_PRIVATE; } break; case 386: #line 3209 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.boolean) = FALSE; } break; case 387: #line 3212 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.boolean) = TRUE; } break; case 401: #line 3232 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { classDef *scope = currentScope(); if (scope->docstring != NULL) yyerror("%Docstring already given for class"); scope->docstring = (yyvsp[(1) - (1)].docstr); } } break; case 402: #line 3243 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tScope()->cppcode, (yyvsp[(1) - (1)].codeb)); } break; case 403: #line 3247 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tScope()->iff->hdrcode, (yyvsp[(1) - (1)].codeb)); } break; case 404: #line 3251 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { classDef *scope = currentScope(); if (scope->travcode != NULL) yyerror("%GCTraverseCode already given for class"); appendCodeBlock(&scope->travcode, (yyvsp[(1) - (1)].codeb)); } } break; case 405: #line 3262 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { classDef *scope = currentScope(); if (scope->clearcode != NULL) yyerror("%GCClearCode already given for class"); appendCodeBlock(&scope->clearcode, (yyvsp[(1) - (1)].codeb)); } } break; case 406: #line 3273 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { classDef *scope = currentScope(); if (scope->getbufcode != NULL) yyerror("%BIGetBufferCode already given for class"); appendCodeBlock(&scope->getbufcode, (yyvsp[(1) - (1)].codeb)); } } break; case 407: #line 3284 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { classDef *scope = currentScope(); if (scope->releasebufcode != NULL) yyerror("%BIReleaseBufferCode already given for class"); appendCodeBlock(&scope->releasebufcode, (yyvsp[(1) - (1)].codeb)); } } break; case 408: #line 3295 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { classDef *scope = currentScope(); if (scope->readbufcode != NULL) yyerror("%BIGetReadBufferCode already given for class"); appendCodeBlock(&scope->readbufcode, (yyvsp[(1) - (1)].codeb)); } } break; case 409: #line 3306 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { classDef *scope = currentScope(); if (scope->writebufcode != NULL) yyerror("%BIGetWriteBufferCode already given for class"); appendCodeBlock(&scope->writebufcode, (yyvsp[(1) - (1)].codeb)); } } break; case 410: #line 3317 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { classDef *scope = currentScope(); if (scope->segcountcode != NULL) yyerror("%BIGetSegCountCode already given for class"); appendCodeBlock(&scope->segcountcode, (yyvsp[(1) - (1)].codeb)); } } break; case 411: #line 3328 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { classDef *scope = currentScope(); if (scope->charbufcode != NULL) yyerror("%BIGetCharBufferCode already given for class"); appendCodeBlock(&scope->charbufcode, (yyvsp[(1) - (1)].codeb)); } } break; case 412: #line 3339 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { classDef *scope = currentScope(); if (scope->instancecode != NULL) yyerror("%InstanceCode already given for class"); appendCodeBlock(&scope->instancecode, (yyvsp[(1) - (1)].codeb)); } } break; case 413: #line 3350 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { classDef *scope = currentScope(); if (scope->picklecode != NULL) yyerror("%PickleCode already given for class"); appendCodeBlock(&scope->picklecode, (yyvsp[(1) - (1)].codeb)); } } break; case 414: #line 3361 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { classDef *scope = currentScope(); if (scope->finalcode != NULL) yyerror("%FinalisationCode already given for class"); appendCodeBlock(&scope->finalcode, (yyvsp[(1) - (1)].codeb)); } } break; case 415: #line 3372 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { classDef *scope = currentScope(); if (scope->typehintcode != NULL) yyerror("%TypeHintCode already given for class"); appendCodeBlock(&scope->typehintcode, (yyvsp[(1) - (1)].codeb)); } } break; case 419: #line 3386 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { classDef *scope = currentScope(); if (scope->convtosubcode != NULL) yyerror("Class has more than one %ConvertToSubClassCode directive"); appendCodeBlock(&scope->convtosubcode, (yyvsp[(2) - (2)].codeb)); } } break; case 420: #line 3397 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { classDef *scope = currentScope(); if (scope->convtocode != NULL) yyerror("Class has more than one %ConvertToTypeCode directive"); appendCodeBlock(&scope->convtocode, (yyvsp[(2) - (2)].codeb)); } } break; case 421: #line 3408 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { classDef *scope = currentScope(); if (scope->convfromcode != NULL) yyerror("Class has more than one %ConvertFromTypeCode directive"); appendCodeBlock(&scope->convfromcode, (yyvsp[(2) - (2)].codeb)); } } break; case 422: #line 3419 "sip-4.19.7/sipgen/metasrc/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 423: #line 3426 "sip-4.19.7/sipgen/metasrc/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 424: #line 3433 "sip-4.19.7/sipgen/metasrc/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 425: #line 3440 "sip-4.19.7/sipgen/metasrc/parser.y" { if (currentSpec -> genc) yyerror("signals section not allowed in a C module"); if (notSkipping()) sectionFlags = SECT_IS_SIGNAL; } break; case 426: #line 3449 "sip-4.19.7/sipgen/metasrc/parser.y" { if ((yyvsp[(2) - (3)].property).name == NULL) yyerror("A %Property directive must have a 'name' argument"); if ((yyvsp[(2) - (3)].property).get == NULL) yyerror("A %Property directive must have a 'get' argument"); if (notSkipping()) addProperty(currentSpec, currentModule, currentScope(), (yyvsp[(2) - (3)].property).name, (yyvsp[(2) - (3)].property).get, (yyvsp[(2) - (3)].property).set, (yyvsp[(3) - (3)].property).docstring); } break; case 427: #line 3462 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.property) = (yyvsp[(2) - (3)].property); } break; case 429: #line 3468 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.property) = (yyvsp[(1) - (3)].property); switch ((yyvsp[(3) - (3)].property).token) { case TK_GET: (yyval.property).get = (yyvsp[(3) - (3)].property).get; break; case TK_NAME: (yyval.property).name = (yyvsp[(3) - (3)].property).name; break; case TK_SET: (yyval.property).set = (yyvsp[(3) - (3)].property).set; break; } } break; case 430: #line 3480 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.property).token = TK_GET; (yyval.property).get = (yyvsp[(3) - (3)].text); (yyval.property).name = NULL; (yyval.property).set = NULL; } break; case 431: #line 3487 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.property).token = TK_NAME; (yyval.property).get = NULL; (yyval.property).name = (yyvsp[(3) - (3)].text); (yyval.property).set = NULL; } break; case 432: #line 3494 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.property).token = TK_SET; (yyval.property).get = NULL; (yyval.property).name = NULL; (yyval.property).set = (yyvsp[(3) - (3)].text); } break; case 433: #line 3503 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.property).token = 0; (yyval.property).docstring = NULL; } break; case 434: #line 3507 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.property) = (yyvsp[(2) - (4)].property); } break; case 436: #line 3513 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.property) = (yyvsp[(1) - (2)].property); switch ((yyvsp[(2) - (2)].property).token) { case TK_DOCSTRING: (yyval.property).docstring = (yyvsp[(2) - (2)].property).docstring; break; } } break; case 437: #line 3523 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.property).token = TK_IF; } break; case 438: #line 3526 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.property).token = TK_END; } break; case 439: #line 3529 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { (yyval.property).token = TK_DOCSTRING; (yyval.property).docstring = (yyvsp[(1) - (1)].docstr); } else { (yyval.property).token = 0; (yyval.property).docstring = NULL; } } break; case 442: #line 3547 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.number) = 0; } break; case 443: #line 3550 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.number) = SECT_IS_SLOT; } break; case 444: #line 3555 "sip-4.19.7/sipgen/metasrc/parser.y" { /* Note that we allow non-virtual dtors in C modules. */ if (notSkipping()) { const char *annos[] = { "HoldGIL", "ReleaseGIL", NULL }; classDef *cd = currentScope(); checkAnnos(&(yyvsp[(8) - (12)].optflags), annos); if (strcmp(classBaseName(cd),(yyvsp[(3) - (12)].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) - (12)].codeb) == NULL) yyerror("Destructor in C modules must include %MethodCode"); appendCodeBlock(&cd->dealloccode, (yyvsp[(10) - (12)].codeb)); /* premethodcode */ appendCodeBlock(&cd->dealloccode, (yyvsp[(11) - (12)].codeb)); /* methodcode */ appendCodeBlock(&cd->dtorcode, (yyvsp[(12) - (12)].codeb)); cd -> dtorexceptions = (yyvsp[(6) - (12)].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) - (12)].number)) { if (!(yyvsp[(1) - (12)].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) - (12)].number) || (yyvsp[(11) - (12)].codeb) != NULL) { if (currentSpec -> genc) yyerror("Virtual destructor or %VirtualCatcherCode not allowed in a C module"); setNeedsShadow(cd); } if (getReleaseGIL(&(yyvsp[(8) - (12)].optflags))) setIsReleaseGILDtor(cd); else if (getHoldGIL(&(yyvsp[(8) - (12)].optflags))) setIsHoldGILDtor(cd); } } break; case 445: #line 3619 "sip-4.19.7/sipgen/metasrc/parser.y" {currentCtorIsExplicit = TRUE;} break; case 448: #line 3623 "sip-4.19.7/sipgen/metasrc/parser.y" { /* Note that we allow ctors in C modules. */ if (notSkipping()) { const char *annos[] = { "API", "Default", "Deprecated", "HoldGIL", "KeywordArgs", "NoDerived", "NoRaisesPyException", "NoTypeHint", "PostHook", "PreHook", "RaisesPyException", "ReleaseGIL", "Transfer", NULL }; checkAnnos(&(yyvsp[(6) - (11)].optflags), annos); if (currentSpec -> genc) { if ((yyvsp[(10) - (11)].codeb) == NULL && (yyvsp[(3) - (11)].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(currentModule, (yyvsp[(1) - (11)].text), sectionFlags, &(yyvsp[(3) - (11)].signature), &(yyvsp[(6) - (11)].optflags), (yyvsp[(11) - (11)].codeb), (yyvsp[(5) - (11)].throwlist), (yyvsp[(7) - (11)].optsignature), currentCtorIsExplicit, (yyvsp[(9) - (11)].docstr), (yyvsp[(10) - (11)].codeb)); } free((yyvsp[(1) - (11)].text)); currentCtorIsExplicit = FALSE; } break; case 449: #line 3669 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.optsignature) = NULL; } break; case 450: #line 3672 "sip-4.19.7/sipgen/metasrc/parser.y" { parsingCSignature = TRUE; } break; case 451: #line 3674 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.optsignature) = sipMalloc(sizeof (signatureDef)); *(yyval.optsignature) = (yyvsp[(4) - (6)].signature); parsingCSignature = FALSE; } break; case 452: #line 3683 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.optsignature) = NULL; } break; case 453: #line 3686 "sip-4.19.7/sipgen/metasrc/parser.y" { parsingCSignature = TRUE; } break; case 454: #line 3688 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.optsignature) = sipMalloc(sizeof (signatureDef)); *(yyval.optsignature) = (yyvsp[(5) - (7)].signature); (yyval.optsignature)->result = (yyvsp[(3) - (7)].memArg); parsingCSignature = FALSE; } break; case 455: #line 3698 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.number) = FALSE; } break; case 456: #line 3701 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.number) = TRUE; } break; case 457: #line 3706 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { applyTypeFlags(currentModule, &(yyvsp[(1) - (17)].memArg), &(yyvsp[(10) - (17)].optflags)); (yyvsp[(4) - (17)].signature).result = (yyvsp[(1) - (17)].memArg); newFunction(currentSpec, currentModule, currentScope(), NULL, NULL, sectionFlags, currentIsStatic, currentIsSignal, currentIsSlot, currentOverIsVirt, (yyvsp[(2) - (17)].text), &(yyvsp[(4) - (17)].signature), (yyvsp[(6) - (17)].number), (yyvsp[(9) - (17)].number), &(yyvsp[(10) - (17)].optflags), (yyvsp[(15) - (17)].codeb), (yyvsp[(16) - (17)].codeb), (yyvsp[(17) - (17)].codeb), (yyvsp[(8) - (17)].throwlist), (yyvsp[(11) - (17)].optsignature), (yyvsp[(13) - (17)].docstr), (yyvsp[(7) - (17)].number), (yyvsp[(14) - (17)].codeb)); } currentIsStatic = FALSE; currentIsSignal = FALSE; currentIsSlot = FALSE; currentOverIsVirt = FALSE; } break; case 458: #line 3724 "sip-4.19.7/sipgen/metasrc/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 459: #line 3744 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { classDef *cd = currentScope(); ifaceFileDef *ns_scope; /* * If the scope is a namespace then make sure the operator is * handled as a global, but remember it's C++ scope.. */ if (cd != NULL && cd->iff->type == namespace_iface) { ns_scope = cd->iff; cd = NULL; } else { ns_scope = NULL; } applyTypeFlags(currentModule, &(yyvsp[(1) - (17)].memArg), &(yyvsp[(11) - (17)].optflags)); /* Handle the unary '+' and '-' operators. */ if ((cd != NULL && (yyvsp[(5) - (17)].signature).nrArgs == 0) || (cd == NULL && (yyvsp[(5) - (17)].signature).nrArgs == 1)) { if (strcmp((yyvsp[(3) - (17)].text), "__add__") == 0) (yyvsp[(3) - (17)].text) = "__pos__"; else if (strcmp((yyvsp[(3) - (17)].text), "__sub__") == 0) (yyvsp[(3) - (17)].text) = "__neg__"; } (yyvsp[(5) - (17)].signature).result = (yyvsp[(1) - (17)].memArg); newFunction(currentSpec, currentModule, cd, ns_scope, NULL, sectionFlags, currentIsStatic, currentIsSignal, currentIsSlot, currentOverIsVirt, (yyvsp[(3) - (17)].text), &(yyvsp[(5) - (17)].signature), (yyvsp[(7) - (17)].number), (yyvsp[(10) - (17)].number), &(yyvsp[(11) - (17)].optflags), (yyvsp[(15) - (17)].codeb), (yyvsp[(16) - (17)].codeb), (yyvsp[(17) - (17)].codeb), (yyvsp[(9) - (17)].throwlist), (yyvsp[(12) - (17)].optsignature), NULL, (yyvsp[(8) - (17)].number), (yyvsp[(14) - (17)].codeb)); } currentIsStatic = FALSE; currentIsSignal = FALSE; currentIsSlot = FALSE; currentOverIsVirt = FALSE; } break; case 460: #line 3788 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { char *sname; classDef *scope = currentScope(); if (scope == NULL || (yyvsp[(4) - (16)].signature).nrArgs != 0) yyerror("Operator casts must be specified in a class and have no arguments"); applyTypeFlags(currentModule, &(yyvsp[(2) - (16)].memArg), &(yyvsp[(10) - (16)].optflags)); switch ((yyvsp[(2) - (16)].memArg).atype) { case defined_type: sname = NULL; break; case bool_type: case cbool_type: case byte_type: case sbyte_type: case ubyte_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) - (16)].signature).result = (yyvsp[(2) - (16)].memArg); newFunction(currentSpec, currentModule, scope, NULL, NULL, sectionFlags, currentIsStatic, currentIsSignal, currentIsSlot, currentOverIsVirt, sname, &(yyvsp[(4) - (16)].signature), (yyvsp[(6) - (16)].number), (yyvsp[(9) - (16)].number), &(yyvsp[(10) - (16)].optflags), (yyvsp[(14) - (16)].codeb), (yyvsp[(15) - (16)].codeb), (yyvsp[(16) - (16)].codeb), (yyvsp[(8) - (16)].throwlist), (yyvsp[(11) - (16)].optsignature), NULL, (yyvsp[(7) - (16)].number), (yyvsp[(13) - (16)].codeb)); } else { argList *al; /* Check it doesn't already exist. */ for (al = scope->casts; al != NULL; al = al->next) if (compareScopedNames((yyvsp[(2) - (16)].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) - (16)].memArg); al->next = scope->casts; scope->casts = al; } } currentIsStatic = FALSE; currentIsSignal = FALSE; currentIsSlot = FALSE; currentOverIsVirt = FALSE; } break; case 461: #line 3869 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__add__";} break; case 462: #line 3870 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__sub__";} break; case 463: #line 3871 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__mul__";} break; case 464: #line 3872 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__div__";} break; case 465: #line 3873 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__mod__";} break; case 466: #line 3874 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__and__";} break; case 467: #line 3875 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__or__";} break; case 468: #line 3876 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__xor__";} break; case 469: #line 3877 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__lshift__";} break; case 470: #line 3878 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__rshift__";} break; case 471: #line 3879 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__iadd__";} break; case 472: #line 3880 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__isub__";} break; case 473: #line 3881 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__imul__";} break; case 474: #line 3882 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__idiv__";} break; case 475: #line 3883 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__imod__";} break; case 476: #line 3884 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__iand__";} break; case 477: #line 3885 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__ior__";} break; case 478: #line 3886 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__ixor__";} break; case 479: #line 3887 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__ilshift__";} break; case 480: #line 3888 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__irshift__";} break; case 481: #line 3889 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__invert__";} break; case 482: #line 3890 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__call__";} break; case 483: #line 3891 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__getitem__";} break; case 484: #line 3892 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__lt__";} break; case 485: #line 3893 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__le__";} break; case 486: #line 3894 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__eq__";} break; case 487: #line 3895 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__ne__";} break; case 488: #line 3896 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__gt__";} break; case 489: #line 3897 "sip-4.19.7/sipgen/metasrc/parser.y" {(yyval.text) = "__ge__";} break; case 490: #line 3900 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.number) = FALSE; } break; case 491: #line 3903 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.number) = TRUE; } break; case 492: #line 3908 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.number) = FALSE; } break; case 493: #line 3911 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.number) = TRUE; } break; case 494: #line 3916 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.number) = 0; } break; case 495: #line 3919 "sip-4.19.7/sipgen/metasrc/parser.y" { if ((yyvsp[(2) - (2)].number) != 0) yyerror("Abstract virtual function '= 0' expected"); (yyval.number) = TRUE; } break; case 496: #line 3927 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.optflags).nrFlags = 0; } break; case 497: #line 3930 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.optflags) = (yyvsp[(2) - (3)].optflags); } break; case 498: #line 3936 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.optflags).flags[0] = (yyvsp[(1) - (1)].flag); (yyval.optflags).nrFlags = 1; } break; case 499: #line 3940 "sip-4.19.7/sipgen/metasrc/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 500: #line 3952 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.flag).ftype = bool_flag; (yyval.flag).fname = (yyvsp[(1) - (1)].text); } break; case 501: #line 3956 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.flag) = (yyvsp[(3) - (3)].flag); (yyval.flag).fname = (yyvsp[(1) - (3)].text); } break; case 502: #line 3962 "sip-4.19.7/sipgen/metasrc/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 503: #line 3966 "sip-4.19.7/sipgen/metasrc/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 504: #line 3989 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.flag).ftype = string_flag; (yyval.flag).fvalue.sval = convertFeaturedString((yyvsp[(1) - (1)].text)); } break; case 505: #line 3993 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.flag).ftype = integer_flag; (yyval.flag).fvalue.ival = (yyvsp[(1) - (1)].number); } break; case 506: #line 3999 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = NULL; } break; case 507: #line 4002 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 508: #line 4007 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = NULL; } break; case 509: #line 4010 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 510: #line 4015 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = NULL; } break; case 511: #line 4018 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 512: #line 4023 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = NULL; } break; case 513: #line 4026 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 514: #line 4031 "sip-4.19.7/sipgen/metasrc/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; /* Suppress a compiler warning. */ default: ; } 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 515: #line 4083 "sip-4.19.7/sipgen/metasrc/parser.y" { /* No arguments. */ (yyval.signature).nrArgs = 0; } break; case 516: #line 4088 "sip-4.19.7/sipgen/metasrc/parser.y" { /* The single or first argument. */ (yyval.signature).args[0] = (yyvsp[(1) - (1)].memArg); (yyval.signature).nrArgs = 1; } break; case 517: #line 4094 "sip-4.19.7/sipgen/metasrc/parser.y" { /* Check that it wasn't ...(,arg...). */ if ((yyvsp[(1) - (3)].signature).nrArgs == 0) yyerror("First argument of the list is missing"); /* * 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 518: #line 4117 "sip-4.19.7/sipgen/metasrc/parser.y" { deprecated("SIP_SIGNAL is deprecated\n"); checkNoAnnos(&(yyvsp[(3) - (4)].optflags), "SIP_SIGNAL has no annotations"); (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 519: #line 4129 "sip-4.19.7/sipgen/metasrc/parser.y" { deprecated("SIP_SLOT is deprecated\n"); checkNoAnnos(&(yyvsp[(3) - (4)].optflags), "SIP_SLOT has no annotations"); (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 520: #line 4141 "sip-4.19.7/sipgen/metasrc/parser.y" { deprecated("SIP_ANYSLOT is deprecated\n"); checkNoAnnos(&(yyvsp[(3) - (4)].optflags), "SIP_ANYSLOT has no annotations"); (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 521: #line 4153 "sip-4.19.7/sipgen/metasrc/parser.y" { const char *annos[] = { "SingleShot", NULL }; deprecated("SIP_RXOBJ_CON is deprecated\n"); checkAnnos(&(yyvsp[(3) - (3)].optflags), annos); (yyval.memArg).atype = rxcon_type; (yyval.memArg).argflags = 0; (yyval.memArg).nrderefs = 0; (yyval.memArg).name = cacheName(currentSpec, (yyvsp[(2) - (3)].text)); if (getOptFlag(&(yyvsp[(3) - (3)].optflags), "SingleShot", bool_flag) != NULL) (yyval.memArg).argflags |= ARG_SINGLE_SHOT; currentSpec -> sigslots = TRUE; } break; case 522: #line 4172 "sip-4.19.7/sipgen/metasrc/parser.y" { deprecated("SIP_RXOBJ_DIS is deprecated\n"); checkNoAnnos(&(yyvsp[(3) - (3)].optflags), "SIP_RXOBJ_DIS has no annotations"); (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 523: #line 4183 "sip-4.19.7/sipgen/metasrc/parser.y" { deprecated("SIP_SLOT_CON is deprecated\n"); checkNoAnnos(&(yyvsp[(6) - (6)].optflags), "SIP_SLOT_CON has no annotations"); (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 524: #line 4200 "sip-4.19.7/sipgen/metasrc/parser.y" { deprecated("SIP_SLOT_DIS is deprecated\n"); checkNoAnnos(&(yyvsp[(6) - (6)].optflags), "SIP_SLOT_DIS has no annotations"); (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 525: #line 4217 "sip-4.19.7/sipgen/metasrc/parser.y" { deprecated("SIP_QOBJECT is deprecated\n"); checkNoAnnos(&(yyvsp[(3) - (3)].optflags), "SIP_QOBJECT has no annotations"); (yyval.memArg).atype = qobject_type; (yyval.memArg).argflags = 0; (yyval.memArg).nrderefs = 0; (yyval.memArg).name = cacheName(currentSpec, (yyvsp[(2) - (3)].text)); } break; case 526: #line 4226 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.memArg) = (yyvsp[(1) - (2)].memArg); (yyval.memArg).defval = (yyvsp[(2) - (2)].valp); } break; case 527: #line 4233 "sip-4.19.7/sipgen/metasrc/parser.y" {currentIsSignal = TRUE;} break; case 529: #line 4234 "sip-4.19.7/sipgen/metasrc/parser.y" {currentIsSlot = TRUE;} break; case 532: #line 4239 "sip-4.19.7/sipgen/metasrc/parser.y" {currentIsStatic = TRUE;} break; case 537: #line 4249 "sip-4.19.7/sipgen/metasrc/parser.y" {currentOverIsVirt = TRUE;} break; case 540: #line 4253 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { const char *annos[] = { "DocType", "Encoding", "NoSetter", "NoTypeHint", "PyInt", "PyName", "TypeHint", NULL }; checkAnnos(&(yyvsp[(3) - (8)].optflags), annos); if ((yyvsp[(6) - (8)].codeb) != NULL) { if ((yyvsp[(4) - (8)].variable).access_code != NULL) yyerror("%AccessCode already defined"); (yyvsp[(4) - (8)].variable).access_code = (yyvsp[(6) - (8)].codeb); deprecated("%AccessCode should be used as a sub-directive"); } if ((yyvsp[(7) - (8)].codeb) != NULL) { if ((yyvsp[(4) - (8)].variable).get_code != NULL) yyerror("%GetCode already defined"); (yyvsp[(4) - (8)].variable).get_code = (yyvsp[(7) - (8)].codeb); deprecated("%GetCode should be used as a sub-directive"); } if ((yyvsp[(8) - (8)].codeb) != NULL) { if ((yyvsp[(4) - (8)].variable).set_code != NULL) yyerror("%SetCode already defined"); (yyvsp[(4) - (8)].variable).set_code = (yyvsp[(8) - (8)].codeb); deprecated("%SetCode should be used as a sub-directive"); } newVar(currentSpec, currentModule, (yyvsp[(2) - (8)].text), currentIsStatic, &(yyvsp[(1) - (8)].memArg), &(yyvsp[(3) - (8)].optflags), (yyvsp[(4) - (8)].variable).access_code, (yyvsp[(4) - (8)].variable).get_code, (yyvsp[(4) - (8)].variable).set_code, sectionFlags); } currentIsStatic = FALSE; } break; case 541: #line 4308 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.variable).token = 0; (yyval.variable).access_code = NULL; (yyval.variable).get_code = NULL; (yyval.variable).set_code = NULL; } break; case 542: #line 4314 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.variable) = (yyvsp[(2) - (3)].variable); } break; case 544: #line 4320 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.variable) = (yyvsp[(1) - (2)].variable); switch ((yyvsp[(2) - (2)].variable).token) { case TK_ACCESSCODE: (yyval.variable).access_code = (yyvsp[(2) - (2)].variable).access_code; break; case TK_GETCODE: (yyval.variable).get_code = (yyvsp[(2) - (2)].variable).get_code; break; case TK_SETCODE: (yyval.variable).set_code = (yyvsp[(2) - (2)].variable).set_code; break; } } break; case 545: #line 4332 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.variable).token = TK_IF; } break; case 546: #line 4335 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.variable).token = TK_END; } break; case 547: #line 4338 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { (yyval.variable).token = TK_ACCESSCODE; (yyval.variable).access_code = (yyvsp[(2) - (2)].codeb); } else { (yyval.variable).token = 0; (yyval.variable).access_code = NULL; } (yyval.variable).get_code = NULL; (yyval.variable).set_code = NULL; } break; case 548: #line 4353 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { (yyval.variable).token = TK_GETCODE; (yyval.variable).get_code = (yyvsp[(2) - (2)].codeb); } else { (yyval.variable).token = 0; (yyval.variable).get_code = NULL; } (yyval.variable).access_code = NULL; (yyval.variable).set_code = NULL; } break; case 549: #line 4368 "sip-4.19.7/sipgen/metasrc/parser.y" { if (notSkipping()) { (yyval.variable).token = TK_SETCODE; (yyval.variable).set_code = (yyvsp[(2) - (2)].codeb); } else { (yyval.variable).token = 0; (yyval.variable).set_code = NULL; } (yyval.variable).access_code = NULL; (yyval.variable).get_code = NULL; } break; case 550: #line 4385 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.memArg) = (yyvsp[(2) - (4)].memArg); add_derefs(&(yyval.memArg), &(yyvsp[(3) - (4)].memArg)); (yyval.memArg).argflags |= ARG_IS_CONST | (yyvsp[(4) - (4)].number); } break; case 551: #line 4390 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.memArg) = (yyvsp[(1) - (3)].memArg); add_derefs(&(yyval.memArg), &(yyvsp[(2) - (3)].memArg)); (yyval.memArg).argflags |= (yyvsp[(3) - (3)].number); /* PyObject * is a synonym for SIP_PYOBJECT. */ if ((yyvsp[(1) - (3)].memArg).atype == defined_type && strcmp((yyvsp[(1) - (3)].memArg).u.snd->name, "PyObject") == 0 && (yyvsp[(1) - (3)].memArg).u.snd->next == NULL && (yyvsp[(2) - (3)].memArg).nrderefs == 1 && (yyvsp[(3) - (3)].number) == 0) { (yyval.memArg).atype = pyobject_type; (yyval.memArg).nrderefs = 0; } } break; case 552: #line 4404 "sip-4.19.7/sipgen/metasrc/parser.y" { const char *annos[] = { "AllowNone", "Array", "ArraySize", "Constrained", "DisallowNone", "DocType", "DocValue", "Encoding", "GetWrapper", "In", "KeepReference", "NoCopy", "Out", "PyInt", "ResultSize", "Transfer", "TransferBack", "TransferThis", "TypeHint", "TypeHintIn", "TypeHintOut", "TypeHintValue", NULL }; checkAnnos(&(yyvsp[(3) - (3)].optflags), annos); (yyval.memArg) = (yyvsp[(1) - (3)].memArg); (yyval.memArg).name = cacheName(currentSpec, (yyvsp[(2) - (3)].text)); handleKeepReference(&(yyvsp[(3) - (3)].optflags), &(yyval.memArg), currentModule); if (getAllowNone(&(yyvsp[(3) - (3)].optflags))) (yyval.memArg).argflags |= ARG_ALLOW_NONE; if (getDisallowNone(&(yyvsp[(3) - (3)].optflags))) (yyval.memArg).argflags |= ARG_DISALLOW_NONE; if (getOptFlag(&(yyvsp[(3) - (3)].optflags),"GetWrapper",bool_flag) != NULL) (yyval.memArg).argflags |= ARG_GET_WRAPPER; if (getOptFlag(&(yyvsp[(3) - (3)].optflags),"Array",bool_flag) != NULL) (yyval.memArg).argflags |= ARG_ARRAY; if (getOptFlag(&(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 (getOptFlag(&(yyvsp[(3) - (3)].optflags),"TransferThis",bool_flag) != NULL) (yyval.memArg).argflags |= ARG_THIS_XFERRED; if (getOptFlag(&(yyvsp[(3) - (3)].optflags),"TransferBack",bool_flag) != NULL) (yyval.memArg).argflags |= ARG_XFERRED_BACK; if (getOptFlag(&(yyvsp[(3) - (3)].optflags),"In",bool_flag) != NULL) (yyval.memArg).argflags |= ARG_IN; if (getOptFlag(&(yyvsp[(3) - (3)].optflags),"Out",bool_flag) != NULL) (yyval.memArg).argflags |= ARG_OUT; if (getOptFlag(&(yyvsp[(3) - (3)].optflags), "ResultSize", bool_flag) != NULL) (yyval.memArg).argflags |= ARG_RESULT_SIZE; if (getOptFlag(&(yyvsp[(3) - (3)].optflags), "NoCopy", bool_flag) != NULL) (yyval.memArg).argflags |= ARG_NO_COPY; if (getOptFlag(&(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; /* Suppress a compiler warning. */ default: ; } } applyTypeFlags(currentModule, &(yyval.memArg), &(yyvsp[(3) - (3)].optflags)); (yyval.memArg).typehint_value = getTypeHintValue(&(yyvsp[(3) - (3)].optflags)); } break; case 553: #line 4507 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.number) = 0; } break; case 554: #line 4510 "sip-4.19.7/sipgen/metasrc/parser.y" { if (currentSpec -> genc) yyerror("References not allowed in a C module"); (yyval.number) = ARG_IS_REF; } break; case 555: #line 4518 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.memArg).nrderefs = 0; } break; case 556: #line 4521 "sip-4.19.7/sipgen/metasrc/parser.y" { add_new_deref(&(yyval.memArg), &(yyvsp[(1) - (3)].memArg), TRUE); } break; case 557: #line 4524 "sip-4.19.7/sipgen/metasrc/parser.y" { add_new_deref(&(yyval.memArg), &(yyvsp[(1) - (2)].memArg), FALSE); } break; case 558: #line 4529 "sip-4.19.7/sipgen/metasrc/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 559: #line 4537 "sip-4.19.7/sipgen/metasrc/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 560: #line 4548 "sip-4.19.7/sipgen/metasrc/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 561: #line 4563 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = ushort_type; } break; case 562: #line 4567 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = short_type; } break; case 563: #line 4571 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = uint_type; } break; case 564: #line 4575 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = uint_type; } break; case 565: #line 4579 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = int_type; } break; case 566: #line 4583 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = long_type; } break; case 567: #line 4587 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = ulong_type; } break; case 568: #line 4591 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = longlong_type; } break; case 569: #line 4595 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = ulonglong_type; } break; case 570: #line 4599 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = float_type; } break; case 571: #line 4603 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = double_type; } break; case 572: #line 4607 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = bool_type; } break; case 573: #line 4611 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = sstring_type; } break; case 574: #line 4615 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = ustring_type; } break; case 575: #line 4619 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = string_type; } break; case 576: #line 4623 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = wstring_type; } break; case 577: #line 4627 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = void_type; } break; case 578: #line 4631 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = pyobject_type; } break; case 579: #line 4635 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = pytuple_type; } break; case 580: #line 4639 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = pylist_type; } break; case 581: #line 4643 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = pydict_type; } break; case 582: #line 4647 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = pycallable_type; } break; case 583: #line 4651 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = pyslice_type; } break; case 584: #line 4655 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = pytype_type; } break; case 585: #line 4659 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = pybuffer_type; } break; case 586: #line 4663 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = ssize_type; } break; case 587: #line 4667 "sip-4.19.7/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = ellipsis_type; } break; case 588: #line 4673 "sip-4.19.7/sipgen/metasrc/parser.y" { /* The single or first type. */ (yyval.signature).args[0] = (yyvsp[(1) - (1)].memArg); (yyval.signature).nrArgs = 1; } break; case 589: #line 4679 "sip-4.19.7/sipgen/metasrc/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 590: #line 4695 "sip-4.19.7/sipgen/metasrc/parser.y" { (yyval.throwlist) = NULL; } break; case 591: #line 4698 "sip-4.19.7/sipgen/metasrc/parser.y" { if (currentSpec->genc) yyerror("Exceptions not allowed in a C module"); (yyval.throwlist) = (yyvsp[(3) - (4)].throwlist); } break; case 592: #line 4706 "sip-4.19.7/sipgen/metasrc/parser.y" { /* Empty list so use a blank. */ (yyval.throwlist) = sipMalloc(sizeof (throwArgs)); (yyval.throwlist) -> nrArgs = 0; } break; case 593: #line 4712 "sip-4.19.7/sipgen/metasrc/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 594: #line 4719 "sip-4.19.7/sipgen/metasrc/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 1267 of yacc.c. */ #line 8382 "sip-4.19.7/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 look-ahead 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 look-ahead 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); } if (yyn == YYFINAL) YYACCEPT; *++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; #ifndef yyoverflow /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ yyexhaustedlab: yyerror (YY_("memory exhausted")); yyresult = 2; /* Fall through. */ #endif yyreturn: if (yychar != YYEOF && 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 4735 "sip-4.19.7/sipgen/metasrc/parser.y" /* * Parse the specification. */ void parse(sipSpec *spec, FILE *fp, char *filename, int strict, stringList *tsl, stringList *bsl, stringList *xfl, KwArgs kwArgs, int protHack) { classTmplDef *tcd; /* Initialise the spec. */ memset(spec, 0, sizeof (sipSpec)); spec->genc = -1; currentSpec = spec; strictParse = strict; backstops = bsl; neededQualifiers = tsl; excludedQualifiers = xfl; currentModule = NULL; currentMappedType = NULL; currentOverIsVirt = FALSE; currentCtorIsExplicit = FALSE; currentIsStatic = FALSE; currentIsSignal = FALSE; currentIsSlot = FALSE; currentIsTemplate = FALSE; previousFile = NULL; stackPtr = 0; currentPlatforms = NULL; currentScopeIdx = 0; sectionFlags = 0; defaultKwArgs = kwArgs; 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(const 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, const 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->defdocstringfmt = raw; newmod->encoding = no_type; newmod->next_key = -1; /* * The consolidated module support needs these to be in order that they * appeared. */ for (tailp = ¤tSpec->modules; *tailp != NULL; tailp = &(*tailp)->next) ; *tailp = newmod; return newmod; } /* * Switch to parsing a new file. */ static void parseFile(FILE *fp, const char *name, moduleDef *prevmod, int optional) { parserContext pc; pc.filename = name; pc.ifdepth = stackPtr; 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; } /* * Note that we assume that the type (ie. class vs. mapped type vs. * exception) will be the same across all platforms. */ iff->platforms = currentPlatforms; iff->type = iftype; iff->ifacenr = -1; iff->fqcname = fqname; iff->module = NULL; iff->hdrcode = NULL; iff->used = NULL; iff->file_extension = 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, int tmpl_arg) { return findClassWithInterface(pt, findIfaceFile(pt, currentModule, fqname, iftype, api_range, NULL), tmpl_arg); } /* * Find a class definition given an existing interface file. */ static classDef *findClassWithInterface(sipSpec *pt, ifaceFileDef *iff, int tmpl_arg) { classDef *cd; for (cd = pt->classes; cd != NULL; cd = cd->next) if (cd->iff == iff) { if (isTemplateArg(cd) && !tmpl_arg) resetTemplateArg(cd); return cd; } /* Create a new one. */ cd = sipMalloc(sizeof (classDef)); if (tmpl_arg) setTemplateArg(cd); 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 appendToIfaceFileList(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, FALSE); } /* Create a new one. */ xd = sipMalloc(sizeof (exceptionDef)); xd->exceptionnr = -1; xd->needed = FALSE; 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, const char *virt_error_handler, typeHintDef *typehint_in, typeHintDef *typehint_out, const char *typehint_value) { int flags; classDef *cd, *scope; codeBlockList *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) setNeedsShadow(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, FALSE); /* 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; cd->virt_error_handler = virt_error_handler; cd->typehint_in = typehint_in; cd->typehint_out = typehint_out; cd->typehint_value = typehint_value; if (currentIsTemplate) setIsTemplateClass(cd); appendCodeBlockList(&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; if (inMainModule()) ns->iff->first_alt->needed = TRUE; 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(mod, of, classBaseName(cd)); cd->pyname = NULL; checkAttributes(pt, mod, cd->ecd, NULL, pyname, FALSE); cd->pyname = cacheName(pt, pyname); cd->no_typehint = getNoTypeHint(of); if ((flg = getOptFlag(of, "Metatype", dotted_name_flag)) != NULL) cd->metatype = cacheName(pt, flg->fvalue.sval); if ((flg = getOptFlag(of, "Supertype", dotted_name_flag)) != NULL) cd->supertype = cacheName(pt, flg->fvalue.sval); if (getOptFlag(of, "ExportDerived", bool_flag) != NULL) setExportDerived(cd); if (getOptFlag(of, "Mixin", bool_flag) != NULL) setMixin(cd); if ((flg = getOptFlag(of, "FileExtension", string_flag)) != NULL) cd->iff->file_extension = flg->fvalue.sval; if ((flg = getOptFlag(of, "PyQtFlags", integer_flag)) != NULL) cd->pyqt_flags = flg->fvalue.ival; if (getOptFlag(of, "PyQtNoQMetaObject", bool_flag) != NULL) setPyQtNoQMetaObject(cd); if ((flg = getOptFlag(of, "PyQtInterface", string_flag)) != NULL) cd->pyqt_interface = flg->fvalue.sval; if (isOpaque(cd)) { if (getOptFlag(of, "External", bool_flag) != NULL) setIsExternal(cd); } else { int seq_might, seq_not, default_to_sequence; memberDef *md; if (getOptFlag(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 (getOptFlag(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 (getOptFlag(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 the user has used the * /Sequence/ annotation or 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; /* Suppress a compiler warning. */ default: ; } default_to_sequence = (!seq_not && seq_might); for (md = cd->members; md != NULL; md = md->next) { /* Ignore if it is explicitly numeric. */ if (isNumeric(md)) continue; if (isSequence(md) || default_to_sequence) 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; /* Suppress a compiler warning. */ default: ; } } } 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 = fullyQualifiedName(ad->u.snd); cname = scopedNameTail(snd); break; case template_type: ad->u.td->fqname = fullyQualifiedName(ad->u.td->fqname); snd = encodedTemplateName(ad->u.td); cname = NULL; break; case struct_type: snd = ad->u.sname = fullyQualifiedName(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(currentModule, of, cname)); mappedTypeAnnos(mtd, 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, initialise 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)); /* Keep track of the original definition as it gets copied. */ mtd->real = mtd; return mtd; } /* * Create a new enum. */ static enumDef *newEnum(sipSpec *pt, moduleDef *mod, mappedTypeDef *mt_scope, char *name, optFlags *of, int flags, int isscoped) { 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(mod, 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) { if (makeProtPublic) { flags &= ~SECT_IS_PROT; flags |= SECT_IS_PUBLIC; } else if (c_scope != NULL) { setNeedsShadow(c_scope); } } ed->enumflags = flags; ed->no_typehint = getNoTypeHint(of); 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->platforms = currentPlatforms; ed->next = pt -> enums; pt->enums = ed; if (getOptFlag(of, "NoScope", bool_flag) != NULL) setIsNoScope(ed); if (isscoped) setIsScopedEnum(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); /* We do want const. */ if (isConstArg(sad)) { char *const_val = sipStrdup("const "); append(&const_val, val); free(val); val = const_val; } 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 ubyte_type: case ustring_type: s = "unsigned char"; break; case byte_type: case ascii_string_type: case latin1_string_type: case utf8_string_type: case string_type: s = "char"; break; case sbyte_type: 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 = "uint"; 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; case void_type: s = "void"; break; case capsule_type: s = "void *"; 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; } /* * Remove any explicit global scope. */ scopedNameDef *removeGlobalScope(scopedNameDef *snd) { return ((snd != NULL && snd->name[0] == '\0') ? snd->next : snd); } /* * 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; /* * We don't want the global scope (which probably should always be there, * but we check anyway). */ name = removeGlobalScope(name); /* 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, const char *pyname, int use_template_name, docstringDef *docstring) { scopedNameDef *type_names, *type_values; classDef *cd; ctorDef *oct, **cttail; argDef *ad; ifaceFileList *iffl, **used; classList *cl; 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; if (docstring != NULL) cd->docstring = docstring; resetIsTemplateClass(cd); cd->pyname = cacheName(pt, pyname); cd->td = td; if (use_template_name) setUseTemplateName(cd); /* Handle the interface file. */ cd->iff = findIfaceFile(pt, mod, fqname, class_iface, (scope != NULL ? scope->iff->api_range : NULL), NULL); cd->iff->module = mod; appendCodeBlockList(&cd->iff->hdrcode, tcd->cd->iff->hdrcode); /* 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) appendToIfaceFileList(used, iffl->iff); /* Include any scope header code. */ if (scope != NULL) appendCodeBlockList(&cd->iff->hdrcode, scope->iff->hdrcode); if (inMainModule()) { setIsUsedName(cd->iff->name); setIsUsedName(cd->pyname); } cd->ecd = currentScope(); /* Handle any type hints. */ if (cd->typehint_in != NULL) cd->typehint_in = newTypeHint( templateString(cd->typehint_in->raw_hint, type_names, type_values)); if (cd->typehint_out != NULL) cd->typehint_out = newTypeHint( templateString(cd->typehint_out->raw_hint, type_names, type_values)); /* Handle the super-classes. */ for (cl = cd->supers; cl != NULL; cl = cl->next) { int a; scopedNameDef *unscoped; unscoped = removeGlobalScope(cl->cd->iff->fqcname); /* Ignore defined or scoped classes. */ if (cl->cd->iff->module != NULL || unscoped->next != NULL) continue; for (a = 0; a < tcd->sig.nrArgs - 1; ++a) if (strcmp(unscoped->name, scopedNameTail(tcd->sig.args[a].u.snd)) == 0) { argDef *tad = &td->types.args[a]; classDef *icd; if (tad->atype == defined_type) icd = findClass(pt, class_iface, NULL, tad->u.snd, FALSE); else if (tad->atype == class_type) icd = tad->u.cd; else fatal("Template argument %s must expand to a class\n", unscoped->name); cl->cd = icd; } } /* 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 typedefs. */ instantiateTemplateTypedefs(pt, tcd, td, cd, 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, type_names, type_values); 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, type_names, type_values); } nct->methodcode = templateCode(pt, used, nct->methodcode, type_names, type_values); nct->premethodcode = templateCode(pt, used, nct->premethodcode, 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->instancecode = templateCode(pt, used, cd->instancecode, type_names, type_values); cd->picklecode = templateCode(pt, used, cd->picklecode, type_names, type_values); cd->finalcode = templateCode(pt, used, cd->finalcode, type_names, type_values); cd->typehintcode = templateCode(pt, used, cd->typehintcode, 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, type_names, type_values); 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, type_names, type_values); } nod->methodcode = templateCode(pt, used, nod->methodcode, type_names, type_values); nod->premethodcode = templateCode(pt, used, nod->premethodcode, type_names, type_values); nod->virtcallcode = templateCode(pt, used, nod->virtcallcode, type_names, type_values); nod->virtcode = templateCode(pt, used, nod->virtcode, type_names, type_values); 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, type_names, type_values); 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); } } /* * Instantiate the typedefs of a template class. */ static void instantiateTemplateTypedefs(sipSpec *pt, classTmplDef *tcd, templateDef *td, classDef *cd, scopedNameDef *type_names, scopedNameDef *type_values) { typedefDef *tdd; for (tdd = pt->typedefs; tdd != NULL; tdd = tdd->next) { typedefDef *new_tdd; if (tdd->ecd != tcd->cd) continue; new_tdd = sipMalloc(sizeof (typedefDef)); /* Start with a shallow copy. */ *new_tdd = *tdd; new_tdd->fqname = text2scopedName(cd->iff, scopedNameTail(new_tdd->fqname)); new_tdd->ecd = cd; new_tdd->module = cd->iff->module; templateType(&new_tdd->type, tcd, td, cd, type_names, type_values); addTypedef(pt, new_tdd); } } /* * Replace any template arguments in a signature. */ static void templateSignature(signatureDef *sd, int result, classTmplDef *tcd, templateDef *td, classDef *ncd, scopedNameDef *type_names, scopedNameDef *type_values) { int a; if (result) templateType(&sd->result, tcd, td, ncd, type_names, type_values); for (a = 0; a < sd->nrArgs; ++a) templateType(&sd->args[a], tcd, td, ncd, type_names, type_values); } /* * Replace any template arguments in a type. */ static void templateType(argDef *ad, classTmplDef *tcd, templateDef *td, classDef *ncd, scopedNameDef *type_names, scopedNameDef *type_values) { 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, type_names, type_values); return; } /* Handle any default value. */ if (ad->defval != NULL && ad->defval->vtype == fcall_value) { /* * We only handle the subset where the value is an function call, ie. a * template ctor. */ valueDef *vd = ad->defval; if (vd->vtype == fcall_value && vd->u.fcd->type.atype == defined_type) { valueDef *new_vd; fcallDef *fcd; scopedNameDef *snd, **tailp; fcd = sipMalloc(sizeof (fcallDef)); *fcd = *vd->u.fcd; tailp = &fcd->type.u.snd; for (snd = vd->u.fcd->type.u.snd; snd != NULL; snd = snd->next) { *tailp = text2scopePart( templateString(snd->name, type_names, type_values)); tailp = &(*tailp)->next; } new_vd = sipMalloc(sizeof (valueDef)); new_vd->vtype = fcall_value; new_vd->u.fcd = fcd; ad->defval = new_vd; } } /* Handle any type hints. */ if (ad->typehint_in != NULL) ad->typehint_in = newTypeHint( templateString(ad->typehint_in->raw_hint, type_names, type_values)); if (ad->typehint_out != NULL) ad->typehint_out = newTypeHint( templateString(ad->typehint_out->raw_hint, type_names, type_values)); /* 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. */ codeBlockList *templateCode(sipSpec *pt, ifaceFileList **used, codeBlockList *ocbl, scopedNameDef *names, scopedNameDef *values) { codeBlockList *ncbl = NULL; while (ocbl != NULL) { char *at = ocbl->block->frag; int start_of_line = TRUE; do { char *from = at, *first = NULL; codeBlock *cb; scopedNameDef *nam, *val, *nam_first, *val_first; /* Suppress a compiler warning. */ val_first = NULL; /* * Don't do any substitution in lines that appear to be * preprocessor directives. This prevents #include'd file names * being broken. */ if (start_of_line) { /* Strip leading whitespace. */ while (isspace(*from)) ++from; if (*from == '#') { /* Skip to the end of the line. */ do ++from; while (*from != '\n' && *from != '\0'); } else { start_of_line = FALSE; } } /* * 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(from, 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 == ocbl->block->frag) { cb->filename = ocbl->block->filename; cb->linenr = ocbl->block->linenr; } else cb->filename = NULL; appendCodeBlock(&ncbl, cb); /* 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 "_" * and remove any const. */ 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; if (strlen(sp) > 6 && strncmp(sp, "const ", 6) == 0) sp += 6; 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); if (*at == '\n') start_of_line = TRUE; } } while (at != NULL && *at != '\0'); ocbl = ocbl->next; } return ncbl; } /* * 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)) { appendToIfaceFileList(used, iff); return; } } for (ed = pt->enums; ed != NULL; ed = ed->next) { if (ed->ecd == NULL) continue; if (sameName(ed->fqcname, sname)) { appendToIfaceFileList(used, ed->ecd->iff); return; } } } /* * Compare a scoped name with its string equivalent. */ static int sameName(scopedNameDef *snd, const char *sname) { /* Handle any explicit scopes. */ if (sname[0] == ':' && sname[1] == ':') { if (snd->name[0] != '\0') return FALSE; sname += 2; } snd = removeGlobalScope(snd); 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, docstringDef *docstring) { int no_type_name; typedefDef *td; scopedNameDef *fqname; classDef *scope; scope = currentScope(); fqname = text2scopedName((scope != NULL ? scope->iff : NULL), name); no_type_name = (getOptFlag(optflgs, "NoTypeName", bool_flag) != NULL); /* 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, getPythonName(mod, optflgs, name), no_type_name, docstring); /* All done. */ return; } } td = sipMalloc(sizeof (typedefDef)); td->tdflags = 0; td->fqname = fqname; td->ecd = scope; td->module = mod; td->platforms = currentPlatforms; td->type = *type; if (getOptFlag(optflgs, "Capsule", bool_flag) != NULL) { /* Make sure the type is void *. */ if (type->atype != void_type || type->nrderefs != 1 || isConstArg(type) || isReference(type)) { fatalScopedName(fqname); fatal(" must be a void* if /Capsule/ is specified\n"); } td->type.atype = capsule_type; td->type.nrderefs = 0; td->type.u.cap = fqname; } if (no_type_name) setNoTypeName(td); addTypedef(pt, td); } /* * Add a typedef to the list so that the list remains sorted. */ static void addTypedef(sipSpec *pt, typedefDef *tdd) { typedefDef **tdp; /* * Check it doesn't already exist (with a strict parse) 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, tdd->fqname); if (res == 0 && strictParse) { fatalScopedName(tdd->fqname); fatal(" already defined\n"); } if (res >= 0) break; } tdd->next = *tdp; *tdp = tdd; tdd->module->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, int section) { varDef *var; classDef *escope = currentScope(); nameDef *nd; /* * For the moment we don't support capsule variables because it needs the * API major version increasing. */ if (type->atype == capsule_type) yyerror("Capsule variables not yet supported"); /* Check the section. */ if (section != 0) { if ((section & SECT_IS_PUBLIC) == 0) yyerror("Class variables must be in the public section"); if (!isstatic && acode != NULL) yyerror("%AccessCode cannot be specified for non-static class variables"); } if (isstatic && pt->genc) yyerror("Cannot have static members in a C structure"); if (gcode != NULL || scode != NULL) { if (acode != NULL) yyerror("Cannot mix %AccessCode and %GetCode or %SetCode"); if (escope == NULL) yyerror("Cannot specify %GetCode or %SetCode for global variables"); } applyTypeFlags(mod, type, of); nd = cacheName(pt, getPythonName(mod, 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->no_typehint = getNoTypeHint(of); var->platforms = currentPlatforms; var->type = *type; appendCodeBlock(&var->accessfunc, acode); appendCodeBlock(&var->getcode, gcode); appendCodeBlock(&var->setcode, scode); if (isstatic || (escope != NULL && escope->iff->type == namespace_iface)) setIsStaticVar(var); if (getOptFlag(of, "NoSetter", bool_flag) != NULL) setNoSetter(var); addVariable(pt, var); } /* * Create a new ctor. */ static void newCtor(moduleDef *mod, char *name, int sectFlags, signatureDef *args, optFlags *optflgs, codeBlock *methodcode, throwArgs *exceptions, signatureDef *cppsig, int explicit, docstringDef *docstring, codeBlock *premethodcode) { 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"); /* 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->docstring = docstring; ct->ctorflags = sectFlags; ct->no_typehint = getNoTypeHint(optflgs); ct->api_range = getAPIRange(optflgs); ct->pysig = *args; ct->cppsig = (cppsig != NULL ? cppsig : &ct->pysig); ct->exceptions = exceptions; ct->platforms = currentPlatforms; appendCodeBlock(&ct->methodcode, methodcode); appendCodeBlock(&ct->premethodcode, premethodcode); if (!isPrivateCtor(ct)) setCanCreate(cd); if (isProtectedCtor(ct)) setNeedsShadow(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)) ct->kwargs = keywordArgs(mod, optflgs, &ct->pysig, FALSE); if (methodcode == NULL && getOptFlag(optflgs, "NoRaisesPyException", bool_flag) == NULL) { if (allRaisePyException(mod) || getOptFlag(optflgs, "RaisesPyException", bool_flag) != NULL) setRaisesPyExceptionCtor(ct); } if (getOptFlag(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 (getOptFlag(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, ifaceFileDef *ns_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, codeBlock *virtcallcode, throwArgs *exceptions, signatureDef *cppsig, docstringDef *docstring, int isfinal, codeBlock *premethodcode) { static const char *annos[] = { "__len__", "__imatmul__", "__matmul__", "AbortOnException", "AllowNone", "API", "AutoGen", "Deprecated", "DisallowNone", "DocType", "Encoding", "Factory", "HoldGIL", "KeywordArgs", "KeepReference", "NewThread", "NoArgParser", "NoCopy", "NoRaisesPyException", "NoTypeHint", "NoVirtualErrorHandler", "Numeric", "PostHook", "PreHook", "PyInt", "PyName", "PyQtSignalHack", "RaisesPyException", "ReleaseGIL", "Sequence", "VirtualErrorHandler", "Transfer", "TransferBack", "TransferThis", "TypeHint", NULL }; const char *pyname, *virt_error_handler; int factory, xferback, no_arg_parser, no_virt_error_handler; overDef *od, **odp, **headp; optFlag *of; checkAnnos(optflgs, annos); /* 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"); /* Handle C void prototypes. */ if (sig->nrArgs == 1) { argDef *vad = &sig->args[0]; if (vad->atype == void_type && vad->nrderefs == 0) sig->nrArgs = 0; } } if (mt_scope != NULL) headp = &mt_scope->overs; else if (c_scope != NULL) headp = &c_scope->overs; else headp = &mod->overs; /* * See if the function has a non-lazy method. These are methods that * Python expects to see defined in the type before any instance of the * type is created. */ if (c_scope != NULL) { static const char *lazy[] = { "__getattribute__", "__getattr__", "__enter__", "__exit__", "__aenter__", "__aexit__", NULL }; const char **l; for (l = lazy; *l != NULL; ++l) if (strcmp(name, *l) == 0) { setHasNonlazyMethod(c_scope); break; } } /* See if it is a factory method. */ if (getOptFlag(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 = (getOptFlag(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)); getSourceLocation(&od->sloc); /* 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); } od->no_typehint = getNoTypeHint(optflgs); if (isSignal(od)) if ((of = getOptFlag(optflgs, "PyQtSignalHack", integer_flag)) != NULL) od->pyqt_signal_hack = of->fvalue.ival; if (factory) setIsFactory(od); if (xferback) setIsResultTransferredBack(od); if (getTransfer(optflgs)) setIsResultTransferred(od); if (getOptFlag(optflgs, "TransferThis", bool_flag) != NULL) setIsThisTransferredMeth(od); if (methodcode == NULL && getOptFlag(optflgs, "NoRaisesPyException", bool_flag) == NULL) { if (allRaisePyException(mod) || getOptFlag(optflgs, "RaisesPyException", bool_flag) != NULL) setRaisesPyException(od); } if (isProtected(od)) setNeedsShadow(c_scope); if ((isSlot(od) || isSignal(od)) && !isPrivate(od)) { if (isSignal(od)) setNeedsShadow(c_scope); pt->sigslots = TRUE; } if (isSignal(od) && (methodcode != NULL || vcode != NULL || virtcallcode != 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 (isfinal) setIsFinal(od); if (isabstract) { if (sflags == 0) yyerror("Non-class function specified as abstract"); setIsAbstract(od); } if ((of = getOptFlag(optflgs, "AutoGen", opt_name_flag)) != NULL) { if (of->fvalue.sval == NULL || isEnabledFeature(of->fvalue.sval)) setIsAutoGen(od); } virt_error_handler = getVirtErrorHandler(optflgs); no_virt_error_handler = (getOptFlag(optflgs, "NoVirtualErrorHandler", bool_flag) != NULL); if (isvirt) { if (!isfinal) { setIsVirtual(od); setNeedsShadow(c_scope); } if (getOptFlag(optflgs, "AbortOnException", bool_flag) != NULL) setAbortOnException(od); if (no_virt_error_handler) { if (virt_error_handler != NULL) yyerror("/VirtualErrorHandler/ and /NoVirtualErrorHandler/ provided"); setNoErrorHandler(od); } else { od->virt_error_handler = virt_error_handler; } } else { if (vcode != NULL) yyerror("%VirtualCatcherCode provided for non-virtual function"); if (virt_error_handler != NULL) yyerror("/VirtualErrorHandler/ provided for non-virtual function"); if (no_virt_error_handler) yyerror("/NoVirtualErrorHandler/ provided for non-virtual function"); } od->cppname = name; od->pysig = *sig; od->cppsig = (cppsig != NULL ? cppsig : &od->pysig); od->exceptions = exceptions; od->platforms = currentPlatforms; appendCodeBlock(&od->methodcode, methodcode); appendCodeBlock(&od->premethodcode, premethodcode); appendCodeBlock(&od->virtcallcode, virtcallcode); appendCodeBlock(&od->virtcode, vcode); no_arg_parser = (getOptFlag(optflgs, "NoArgParser", bool_flag) != NULL); if (no_arg_parser) { if (methodcode == NULL) yyerror("%MethodCode must be supplied if /NoArgParser/ is specified"); } else { /* * The argument parser requires that there is nothing after an * ellipsis. */ checkEllipsis(sig); } if (cppsig != NULL) checkEllipsis(cppsig); if (getOptFlag(optflgs, "NoCopy", bool_flag) != NULL) setNoCopy(&od->pysig.result); if (getAllowNone(optflgs)) setAllowNone(&od->pysig.result); if (getDisallowNone(optflgs)) setDisallowNone(&od->pysig.result); handleKeepReference(optflgs, &od->pysig.result, mod); pyname = getPythonName(mod, optflgs, name); od->common = findFunction(pt, mod, c_scope, ns_scope, mt_scope, pyname, (methodcode != NULL), sig->nrArgs, no_arg_parser); if (isProtected(od)) setHasProtected(od->common); if (strcmp(pyname, "__delattr__") == 0) setIsDelattr(od); od->docstring = docstring; od->api_range = getAPIRange(optflgs); if (od->api_range == NULL) setNotVersioned(od->common); if (getOptFlag(optflgs, "Numeric", bool_flag) != NULL) { if (isSequence(od->common)) yyerror("/Sequence/ has already been specified"); setIsNumeric(od->common); } if (getOptFlag(optflgs, "Sequence", bool_flag) != NULL) { if (isNumeric(od->common)) yyerror("/Numeric/ has already been specified"); setIsSequence(od->common); } /* Methods that run in new threads must be virtual. */ if (getOptFlag(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 || od->common->slot == call_slot)) { od->kwargs = keywordArgs(mod, optflgs, &od->pysig, hasProtected(od->common)); if (od->kwargs != NoKwArgs) setUseKeywordArgs(od->common); /* * If the overload is protected and defined in an imported module then * we need to make sure that any other overloads' keyword argument * names are marked as used. */ if (isProtected(od) && !inMainModule()) { overDef *kwod; for (kwod = c_scope->overs; kwod != NULL; kwod = kwod->next) if (kwod->common == od->common && kwod->kwargs != NoKwArgs) { int a; for (a = 0; a < kwod->pysig.nrArgs; ++a) { argDef *ad = &kwod->pysig.args[a]; if (kwod->kwargs == OptionalKwArgs && ad->defval == NULL) continue; if (ad->name != NULL) setIsUsedName(ad->name); } } } } od->next = NULL; /* See if we want to auto-generate some methods. */ if (getOptFlag(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; 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 = 1; appendCodeBlock(&len->methodcode, code); } len->common = findFunction(pt, mod, c_scope, ns_scope, mt_scope, len->cppname, TRUE, 0, FALSE); len->platforms = od->platforms; len->next = od->next; od->next = len; } if (getOptFlag(optflgs, "__matmul__", bool_flag) != NULL) { overDef *matmul; matmul = sipMalloc(sizeof (overDef)); matmul->cppname = "__matmul__"; matmul->overflags = SECT_IS_PUBLIC; matmul->pysig = od->pysig; matmul->cppsig = (cppsig != NULL ? cppsig : &matmul->pysig); matmul->methodcode = od->methodcode; matmul->common = findFunction(pt, mod, c_scope, ns_scope, mt_scope, matmul->cppname, (matmul->methodcode != NULL), matmul->pysig.nrArgs, FALSE); matmul->platforms = od->platforms; matmul->next = od->next; od->next = matmul; } if (getOptFlag(optflgs, "__imatmul__", bool_flag) != NULL) { overDef *imatmul; imatmul = sipMalloc(sizeof (overDef)); imatmul->cppname = "__imatmul__"; imatmul->overflags = SECT_IS_PUBLIC; imatmul->pysig = od->pysig; imatmul->cppsig = (cppsig != NULL ? cppsig : &imatmul->pysig); imatmul->methodcode = od->methodcode; imatmul->common = findFunction(pt, mod, c_scope, ns_scope, mt_scope, imatmul->cppname, (imatmul->methodcode != NULL), imatmul->pysig.nrArgs, FALSE); imatmul->platforms = od->platforms; imatmul->next = od->next; od->next = imatmul; } /* 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(moduleDef *mod, optFlags *optflgs, const char *cname) { const char *pname; optFlag *of; autoPyNameDef *apnd; /* Use the explicit name if given. */ if ((of = getOptFlag(optflgs, "PyName", name_flag)) != NULL) return of->fvalue.sval; /* Apply any automatic naming rules. */ pname = cname; for (apnd = mod->autopyname; apnd != NULL; apnd = apnd->next) { size_t len = strlen(apnd->remove_leading); if (strncmp(pname, apnd->remove_leading, len) == 0) pname += len; } 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, ifaceFileDef *ns_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}, {"__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}, {"__setattr__", setattr_slot, TRUE, 2}, {"__delattr__", delattr_slot, TRUE, 1}, {"__matmul__", matmul_slot, FALSE, 1}, {"__imatmul__", imatmul_slot, FALSE, 1}, {"__await__", await_slot, TRUE, 0}, {"__aiter__", aiter_slot, TRUE, 0}, {"__anext__", anext_slot, TRUE, 0}, {NULL, no_slot, FALSE, 0} }; 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; /* __delattr__ is implemented as __setattr__. */ if (st == delattr_slot) { if (inMainModule()) setIsUsedName(cacheName(pt, pname)); st = setattr_slot; pname = "__setattr__"; } 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->ns_scope = ns_scope; 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) && !isInplaceNumberSlot(md) && !isRichCompareSlot(md)) yyerror("Global operators must be either numeric or comparison operators"); return md; } /* * Search a set of flags for a particular one. */ static optFlag *findOptFlag(optFlags *flgs, const char *name) { int f; for (f = 0; f < flgs->nrFlags; ++f) { optFlag *of = &flgs->flags[f]; if (strcmp(of->fname, name) == 0) return of; } return NULL; } /* * Search a set of flags for a particular one and check its type. */ static optFlag *getOptFlag(optFlags *flgs, const char *name, flagType ft) { optFlag *of = findOptFlag(flgs, name); if (of != NULL) { /* 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; } } /* An optional integer can look like a boolean or an integer. */ if (ft == opt_integer_flag) { if (of->ftype == bool_flag) { of->ftype = opt_integer_flag; of->fvalue.ival = -1; } else if (of->ftype == integer_flag) { of->ftype = opt_integer_flag; } } if (ft != of->ftype) yyerror("Annotation has a value of the wrong type"); } return of; } /* * 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; /* We don't do any check for a non-strict parse. */ if (!strictParse) return; /* Check the enums. */ for (ed = pt->enums; ed != NULL; ed = ed->next) { 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"); if (!isScopedEnum(ed)) { enumMemberDef *emd; 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"); } /* Check the properties. */ if (py_c_scope != NULL) { propertyDef *pd; for (pd = py_c_scope->properties; pd != NULL; pd = pd->next) if (strcmp(pd->name->text, attr) == 0) yyerror("There is already a property with the same name"); } } /* * Append a code block to a list of them. */ static void appendCodeBlock(codeBlockList **headp, codeBlock *cb) { codeBlockList *cbl; /* Handle the trivial case. */ if (cb == NULL) return; /* Find the end of the list. */ while (*headp != NULL) { /* Ignore if the block is already in the list. */ if ((*headp)->block == cb) return; headp = &(*headp)->next; } cbl = sipMalloc(sizeof (codeBlockList)); cbl->block = cb; *headp = cbl; } /* * Append a code block list to an existing list. */ void appendCodeBlockList(codeBlockList **headp, codeBlockList *cbl) { while (cbl != NULL) { appendCodeBlock(headp, cbl->block); cbl = cbl->next; } } /* * 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 (stackPtr > currentContext.ifdepth) fatal("Too many %%If statements in %s\n", previousFile); if (stackPtr < 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) { if (from->encoding == no_type) from->encoding = currentModule->encoding; if (isCallSuperInitUndefined(from)) { if (isCallSuperInitYes(currentModule)) setCallSuperInitYes(from); else setCallSuperInitNo(from); } } /* 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; } /* Qualifiers corresponding to the SIP version are created on the fly. */ if (name[0] == 'S' && name[1] == 'I' && name[2] == 'P' && name[3] == '_') { const char *cp = &name[3]; int major, minor, patch; cp = getInt(cp, &major); cp = getInt(cp, &minor); cp = getInt(cp, &patch); if (*cp != '\0') yyerror("Unexpected character after SIP version number"); return allocQualifier(currentModule, -1, (major << 16) | (minor << 8) | patch, TRUE, name, time_qualifier); } return NULL; } /* * Get an integer from string. */ static const char *getInt(const char *cp, int *ip) { /* Handle the default value. */ *ip = 0; if (*cp == '\0') return cp; /* There must be a leading underscore. */ if (*cp++ != '_') yyerror("An underscore must separate the parts of a SIP version number"); while (isdigit(*cp)) { *ip *= 10; *ip += *cp - '0'; ++cp; } return cp; } /* * 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) : text2scopePart("")); 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 (stackPtr == 0 ? TRUE : skipStack[stackPtr - 1]); } /* * Return the value of an expression involving a time period. */ static int timePeriod(const char *lname, const char *uname) { int 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; } /* Handle the SIP version number pseudo-timeline. */ if (line < 0) { if (lower != NULL && SIP_VERSION < lower->order) return FALSE; if (upper != NULL && SIP_VERSION >= upper->order) return FALSE; return TRUE; } for (qd = mod->qualifiers; qd != NULL; qd = qd->next) { if (qd->qtype != time_qualifier || qd->line != line) continue; if (selectedQualifier(neededQualifiers, qd)) { if (lower != NULL && qd->order < lower->order) return FALSE; if (upper != NULL && qd->order >= upper->order) return FALSE; return TRUE; } } /* * If there is no upper bound then assume the expression is true unless * the lower bound is a backstop. */ if (upper == NULL) return !isBackstop(lower); /* * If the upper limit corresponds to a backstop then assume the expression * is true. */ return isBackstop(upper); } /* * See if a qualifier is a backstop. */ static int isBackstop(qualDef *qd) { stringList *sl; for (sl = backstops; sl != NULL; sl = sl->next) if (strcmp(qd->name, sl->s) == 0) return TRUE; return FALSE; } /* * 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 (!strictParse) { if (optnot) { moduleDef *mod; /* Add every platform except the one we have. */ for (mod = currentSpec->modules; mod != NULL; mod = mod->next) { qualDef *not_qd; for (not_qd = mod->qualifiers; not_qd != NULL; not_qd = not_qd->next) if (not_qd->qtype == platform_qualifier && strcmp(not_qd->name, qd->name) != 0) addPlatform(not_qd); } } else { addPlatform(qd); } /* * If it is a non-strict parse then this is always TRUE, ie. we * never skip because of the platform. */ return TRUE; } if (selectedQualifier(neededQualifiers, qd)) this = TRUE; } if (optnot) this = !this; return this; } /* * Add a platform to the current list of platforms if it is not already there. */ static void addPlatform(qualDef *qd) { platformDef *pd; for (pd = currentPlatforms; pd != NULL; pd = pd->next) if (pd->qualifier == qd) return; pd = sipMalloc(sizeof (platformDef)); pd->qualifier = qd; pd->next = currentPlatforms; currentPlatforms = pd; } /* * 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 !qd->default_enabled; } /* * Return TRUE if the given qualifier is needed. */ int selectedQualifier(stringList *needed_qualifiers, qualDef *qd) { stringList *sl; for (sl = needed_qualifiers; sl != NULL; sl = sl->next) if (strcmp(qd->name, sl->s) == 0) return qd->default_enabled; 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, int default_enabled, const char *name, qualType qt) { /* Check it doesn't already exist. */ if (findQualifier(name) != NULL) yyerror("Version is already defined"); allocQualifier(mod, line, order, default_enabled, name, qt); } /* * Allocate a new qualifier. */ static qualDef *allocQualifier(moduleDef *mod, int line, int order, int default_enabled, const char *name, qualType qt) { qualDef *qd; qd = sipMalloc(sizeof (qualDef)); qd->name = name; qd->qtype = qt; qd->module = mod; qd->line = line; qd->order = order; qd->default_enabled = default_enabled; qd->next = mod->qualifiers; mod->qualifiers = qd; return qd; } /* * Create a new imported module. */ static void newImport(const 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 = getOptFlag(optflgs,"PreHook",name_flag)) != NULL) *pre = of -> fvalue.sval; else *pre = NULL; if ((of = getOptFlag(optflgs,"PostHook",name_flag)) != NULL) *post = of -> fvalue.sval; else *post = NULL; } /* * Get the /Transfer/ option flag. */ static int getTransfer(optFlags *optflgs) { return (getOptFlag(optflgs, "Transfer", bool_flag) != NULL); } /* * Get the /ReleaseGIL/ option flag. */ static int getReleaseGIL(optFlags *optflgs) { return (getOptFlag(optflgs, "ReleaseGIL", bool_flag) != NULL); } /* * Get the /HoldGIL/ option flag. */ static int getHoldGIL(optFlags *optflgs) { return (getOptFlag(optflgs, "HoldGIL", bool_flag) != NULL); } /* * Get the /Deprecated/ option flag. */ static int getDeprecated(optFlags *optflgs) { return (getOptFlag(optflgs, "Deprecated", bool_flag) != NULL); } /* * Get the /AllowNone/ option flag. */ static int getAllowNone(optFlags *optflgs) { return (getOptFlag(optflgs, "AllowNone", bool_flag) != NULL); } /* * Get the /DisallowNone/ option flag. */ static int getDisallowNone(optFlags *optflgs) { return (getOptFlag(optflgs, "DisallowNone", bool_flag) != NULL); } /* * Get the /VirtualErrorHandler/ option flag. */ static const char *getVirtErrorHandler(optFlags *optflgs) { optFlag *of = getOptFlag(optflgs, "VirtualErrorHandler", name_flag); if (of == NULL) return NULL; return of->fvalue.sval; } /* * Get the /DocType/ option flag. */ static const char *getDocType(optFlags *optflgs) { optFlag *of = getOptFlag(optflgs, "DocType", string_flag); if (of == NULL) return NULL; deprecated("/DocType/ is deprecated\n"); return of->fvalue.sval; } /* * Get the /TypeHintValue/ option flag. */ static const char *getTypeHintValue(optFlags *optflgs) { optFlag *of = getOptFlag(optflgs, "TypeHintValue", string_flag); if (of != NULL) return of->fvalue.sval; if ((of = getOptFlag(optflgs, "DocValue", string_flag)) != NULL) { deprecated("/DocValue/ is deprecated\n"); return of->fvalue.sval; } return NULL; } /* * Get the /TypeHint/, /TypeHintIn/ and /TypeHintOut/ option flags. */ static void getTypeHints(optFlags *optflgs, typeHintDef **in, typeHintDef **out) { optFlag *of; typeHintDef *thd; if ((of = getOptFlag(optflgs, "TypeHint", string_flag)) != NULL) thd = newTypeHint(of->fvalue.sval); else thd = NULL; if ((of = getOptFlag(optflgs, "TypeHintIn", string_flag)) != NULL) { if (thd != NULL) yywarning("/TypeHintIn/ overrides /TypeHint/"); *in = newTypeHint(of->fvalue.sval); } else { *in = thd; } if ((of = getOptFlag(optflgs, "TypeHintOut", string_flag)) != NULL) { if (thd != NULL) yywarning("/TypeHintOut/ overrides /TypeHint/"); *out = newTypeHint(of->fvalue.sval); } else { *out = thd; } } /* * Get the /NoTypeHint/ option flag. */ static int getNoTypeHint(optFlags *optflgs) { return (getOptFlag(optflgs, "NoTypeHint", bool_flag) != NULL); } /* * Return TRUE if the PyQt4 plugin was specified. */ int pluginPyQt4(sipSpec *pt) { return stringFind(pt->plugins, "PyQt4"); } /* * Return TRUE if the PyQt5 plugin was specified. */ int pluginPyQt5(sipSpec *pt) { return stringFind(pt->plugins, "PyQt5"); } /* * 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; typeHintDef *in, *out; getTypeHints(of, &in, &out); cd = newClass(currentSpec, class_iface, getAPIRange(of), fullyQualifiedName(snd), getVirtErrorHandler(of), in, out, getTypeHintValue(of)); cd->supers = supers; pushScope(cd); } /* * Return a fully qualified scoped name. */ static scopedNameDef *fullyQualifiedName(scopedNameDef *snd) { classDef *scope = currentScope(); return scopeScopedName((scope != NULL ? scope->iff : NULL), snd); } /* * 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); getTypeHints(flags, &ad->typehint_in, &ad->typehint_out); if (getOptFlag(flags, "PyInt", bool_flag) != NULL) { if (ad->atype == string_type) ad->atype = byte_type; else if (ad->atype == sstring_type) ad->atype = sbyte_type; else if (ad->atype == ustring_type) ad->atype = ubyte_type; } if (ad->atype == string_type && !isArray(ad) && !isReference(ad)) { optFlag *of; if ((of = getOptFlag(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 keyword argument support converted from a string. */ static KwArgs convertKwArgs(const char *kwargs) { if (strcmp(kwargs, "None") == 0) return NoKwArgs; if (strcmp(kwargs, "All") == 0) return AllKwArgs; if (strcmp(kwargs, "Optional") == 0) return OptionalKwArgs; yyerror("The style of keyword argument support must be one of \"All\", \"Optional\" or \"None\""); } /* * Return the Format for a string. */ static Format convertFormat(const char *format) { if (strcmp(format, "raw") == 0) return raw; if (strcmp(format, "deindented") == 0) return deindented; yyerror("The docstring format must be either \"raw\" or \"deindented\""); } /* * Return the Signature for a string. */ static Signature convertSignature(const char *signature) { if (strcmp(signature, "discarded") == 0) return discarded; if (strcmp(signature, "prepended") == 0) return prepended; if (strcmp(signature, "appended") == 0) return appended; yyerror("The docstring signature must be either \"discarded\", \"prepended\" or \"appended\""); } /* * 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 = getOptFlag(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 the style of keyword argument support for a signature. */ static KwArgs keywordArgs(moduleDef *mod, optFlags *optflgs, signatureDef *sd, int need_name) { KwArgs kwargs; optFlag *ka_anno, *no_ka_anno; /* Get the default. */ kwargs = mod->kwargs; /* * Get the possible annotations allowing /KeywordArgs/ to have different * types of values. */ ka_anno = findOptFlag(optflgs, "KeywordArgs"); no_ka_anno = getOptFlag(optflgs, "NoKeywordArgs", bool_flag); if (no_ka_anno != NULL) { if (ka_anno != NULL) yyerror("/KeywordArgs/ and /NoKeywordArgs/ cannot both be specified"); deprecated("/NoKeywordArgs/ is deprecated, use /KeywordArgs=\"None\" instead"); kwargs = NoKwArgs; } else if (ka_anno != NULL) { /* A string value is the non-deprecated type. */ if (ka_anno->ftype == string_flag) { kwargs = convertKwArgs(ka_anno->fvalue.sval); } else { deprecated("/KeywordArgs/ is deprecated, use /KeywordArgs=\"All\" instead"); /* Get it again to check the type. */ ka_anno = getOptFlag(optflgs, "KeywordArgs", bool_flag); } } /* An ellipsis cannot be used with keyword arguments. */ if (sd->nrArgs > 0 && sd->args[sd->nrArgs - 1].atype == ellipsis_type) kwargs = NoKwArgs; if (kwargs != NoKwArgs) { 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) { argDef *ad = &sd->args[a]; if (kwargs == OptionalKwArgs && ad->defval == NULL) continue; if (ad->name != NULL) { if (need_name || inMainModule()) setIsUsedName(ad->name); is_name = TRUE; } } if (!is_name) kwargs = NoKwArgs; } return kwargs; } /* * 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); } /* * Add a property definition to a class. */ static void addProperty(sipSpec *pt, moduleDef *mod, classDef *cd, const char *name, const char *get, const char *set, docstringDef *docstring) { propertyDef *pd; checkAttributes(pt, mod, cd, NULL, name, FALSE); pd = sipMalloc(sizeof (propertyDef)); pd->name = cacheName(pt, name); pd->get = get; pd->set = set; pd->docstring = docstring; pd->platforms = currentPlatforms; pd->next = cd->properties; cd->properties = pd; if (inMainModule()) setIsUsedName(pd->name); } /* * Configure a module and return the (possibly new) current module. */ static moduleDef *configureModule(sipSpec *pt, moduleDef *module, const char *filename, const char *name, int c_module, KwArgs kwargs, int use_arg_names, int use_limited_api, int call_super_init, int all_raise_py_exc, const char *def_error_handler, docstringDef *docstring) { moduleDef *mod; /* Check the module hasn't already been defined. */ for (mod = pt->modules; mod != NULL; mod = mod->next) if (mod->fullname != NULL && strcmp(mod->fullname->text, name) == 0) yyerror("Module is already defined"); /* * If we are in a container module then create a component module and make * it current. */ if (isContainer(module) || module->container != NULL) { mod = allocModule(); mod->file = filename; mod->container = (isContainer(module) ? module : module->container); module = mod; } setModuleName(pt, module, name); module->kwargs = kwargs; module->virt_error_handler = def_error_handler; module->docstring = docstring; if (all_raise_py_exc) setAllRaisePyException(module); if (use_arg_names) setUseArgNames(module); if (use_limited_api) setUseLimitedAPI(module); if (call_super_init == 0) setCallSuperInitNo(module); else if (call_super_init > 0) setCallSuperInitYes(module); if (pt->genc < 0) pt->genc = c_module; else if (pt->genc != c_module) yyerror("Cannot mix C and C++ modules"); return module; } /* * Add a Python naming rule to a module. */ static void addAutoPyName(moduleDef *mod, const char *remove_leading) { autoPyNameDef *apnd, **apndp; for (apndp = &mod->autopyname; *apndp != NULL; apndp = &(*apndp)->next) ; apnd = sipMalloc(sizeof (autoPyNameDef)); apnd->remove_leading = remove_leading; apnd->next = *apndp; *apndp = apnd; } /* * Check that no invalid or unknown annotations are given. */ static void checkAnnos(optFlags *annos, const char *valid[]) { if (parsingCSignature && annos->nrFlags != 0) { deprecated("Annotations should not be used in explicit C/C++ signatures"); } else { int i; for (i = 0; i < annos->nrFlags; i++) { const char **name; for (name = valid; *name != NULL; ++name) if (strcmp(*name, annos->flags[i].fname) == 0) break; if (*name == NULL) yywarning("Annotation is unknown"); } } } /* * Check that no annotations were given. */ static void checkNoAnnos(optFlags *annos, const char *msg) { if (annos->nrFlags != 0) deprecated(msg); } /* * Handle any /KeepReference/ annotation for a type. */ static void handleKeepReference(optFlags *optflgs, argDef *ad, moduleDef *mod) { optFlag *of; if ((of = getOptFlag(optflgs, "KeepReference", opt_integer_flag)) != NULL) { setKeepReference(ad); if ((ad->key = of->fvalue.ival) < -1) yyerror("/KeepReference/ key cannot be negative"); /* If there was no explicit key then auto-allocate one. */ if (ad->key == -1) ad->key = mod->next_key--; } } /* * Configure the mapped type annotations that are also valid with mapped type * templates. */ static void mappedTypeAnnos(mappedTypeDef *mtd, optFlags *optflgs) { if (getOptFlag(optflgs, "NoRelease", bool_flag) != NULL) setNoRelease(mtd); if (getAllowNone(optflgs)) setHandlesNone(mtd); mtd->doctype = getDocType(optflgs); getTypeHints(optflgs, &mtd->typehint_in, &mtd->typehint_out); mtd->typehint_value = getTypeHintValue(optflgs); } /* * Initialise an argument with the derefences of another, plus a new one. */ static void add_new_deref(argDef *new, argDef *orig, int isconst) { if ((new->nrderefs = orig->nrderefs + 1) >= MAX_NR_DEREFS) yyerror("Internal error - increase the value of MAX_NR_DEREFS"); memcpy(&new->derefs[0], &orig->derefs[0], sizeof (new->derefs)); new->derefs[orig->nrderefs] = isconst; } /* * Add the dereferences from one type to another. */ static void add_derefs(argDef *dst, argDef *src) { int i; for (i = 0; i < src->nrderefs; ++i) { if (dst->nrderefs >= MAX_NR_DEREFS - 1) fatal("Internal error - increase the value of MAX_NR_DEREFS\n"); dst->derefs[dst->nrderefs++] = src->derefs[i]; } } /* * Check if a word is a Python keyword (or has been at any time). */ int isPyKeyword(const char *word) { static const char *kwds[] = { "False", "None", "True", "and", "as", "assert", "break", "class", "continue", "def", "del", "elif", "else", "except", "finally", "for", "from", "global", "if", "import", "in", "is", "lambda", "nonlocal", "not", "or", "pass", "raise", "return", "try", "while", "with'" "yield", /* Historical keywords. */ "exec", "print", NULL }; const char **kwd; for (kwd = kwds; *kwd != NULL; ++kwd) if (strcmp(*kwd, word) == 0) return TRUE; return FALSE; } /* * Check there is nothing after an ellipsis. */ static void checkEllipsis(signatureDef *sd) { int a; for (a = 0; a < sd->nrArgs; ++a) if (sd->args[a].atype == ellipsis_type && a < sd->nrArgs - 1) yyerror("An ellipsis must be at the end of the argument list if /NoArgParser/ is not specified"); } sip-4.19.7/sipgen/parser.h0000644000076500000240000002507113231604431015422 0ustar philstaff00000000000000/* A Bison parser, made by GNU Bison 2.3. */ /* 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 2, 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* 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_AUTOPYNAME = 259, TK_DEFDOCSTRFMT = 260, TK_DEFDOCSTRSIG = 261, TK_DEFENCODING = 262, TK_PLUGIN = 263, TK_VIRTERRORHANDLER = 264, TK_EXPTYPEHINTCODE = 265, TK_TYPEHINTCODE = 266, TK_DOCSTRING = 267, TK_DOC = 268, TK_EXPORTEDDOC = 269, TK_EXTRACT = 270, TK_MAKEFILE = 271, TK_ACCESSCODE = 272, TK_GETCODE = 273, TK_SETCODE = 274, TK_PREINITCODE = 275, TK_INITCODE = 276, TK_POSTINITCODE = 277, TK_FINALCODE = 278, TK_UNITCODE = 279, TK_UNITPOSTINCLUDECODE = 280, TK_MODCODE = 281, TK_TYPECODE = 282, TK_PREPYCODE = 283, TK_COPYING = 284, TK_MAPPEDTYPE = 285, TK_CODELINE = 286, TK_IF = 287, TK_END = 288, TK_NAME_VALUE = 289, TK_PATH_VALUE = 290, TK_STRING_VALUE = 291, TK_VIRTUALCATCHERCODE = 292, TK_TRAVERSECODE = 293, TK_CLEARCODE = 294, TK_GETBUFFERCODE = 295, TK_RELEASEBUFFERCODE = 296, TK_READBUFFERCODE = 297, TK_WRITEBUFFERCODE = 298, TK_SEGCOUNTCODE = 299, TK_CHARBUFFERCODE = 300, TK_PICKLECODE = 301, TK_VIRTUALCALLCODE = 302, TK_METHODCODE = 303, TK_PREMETHODCODE = 304, TK_INSTANCECODE = 305, TK_FROMTYPE = 306, TK_TOTYPE = 307, TK_TOSUBCLASS = 308, TK_INCLUDE = 309, TK_OPTINCLUDE = 310, TK_IMPORT = 311, TK_EXPHEADERCODE = 312, TK_MODHEADERCODE = 313, TK_TYPEHEADERCODE = 314, TK_MODULE = 315, TK_CMODULE = 316, TK_CONSMODULE = 317, TK_COMPOMODULE = 318, TK_CLASS = 319, TK_STRUCT = 320, TK_PUBLIC = 321, TK_PROTECTED = 322, TK_PRIVATE = 323, TK_SIGNALS = 324, TK_SIGNAL_METHOD = 325, TK_SLOTS = 326, TK_SLOT_METHOD = 327, TK_BOOL = 328, TK_SHORT = 329, TK_INT = 330, TK_LONG = 331, TK_FLOAT = 332, TK_DOUBLE = 333, TK_CHAR = 334, TK_WCHAR_T = 335, TK_VOID = 336, TK_PYOBJECT = 337, TK_PYTUPLE = 338, TK_PYLIST = 339, TK_PYDICT = 340, TK_PYCALLABLE = 341, TK_PYSLICE = 342, TK_PYTYPE = 343, TK_PYBUFFER = 344, TK_VIRTUAL = 345, TK_ENUM = 346, TK_SIGNED = 347, TK_UNSIGNED = 348, TK_SCOPE = 349, TK_LOGICAL_OR = 350, TK_CONST = 351, TK_STATIC = 352, TK_SIPSIGNAL = 353, TK_SIPSLOT = 354, TK_SIPANYSLOT = 355, TK_SIPRXCON = 356, TK_SIPRXDIS = 357, TK_SIPSLOTCON = 358, TK_SIPSLOTDIS = 359, TK_SIPSSIZET = 360, TK_NUMBER_VALUE = 361, TK_REAL_VALUE = 362, TK_TYPEDEF = 363, TK_NAMESPACE = 364, TK_TIMELINE = 365, TK_PLATFORMS = 366, TK_FEATURE = 367, TK_LICENSE = 368, TK_QCHAR_VALUE = 369, TK_TRUE_VALUE = 370, TK_FALSE_VALUE = 371, TK_NULL_VALUE = 372, TK_OPERATOR = 373, TK_THROW = 374, TK_QOBJECT = 375, TK_EXCEPTION = 376, TK_RAISECODE = 377, TK_VIRTERRORCODE = 378, TK_EXPLICIT = 379, TK_TEMPLATE = 380, TK_FINAL = 381, TK_ELLIPSIS = 382, TK_DEFMETATYPE = 383, TK_DEFSUPERTYPE = 384, TK_PROPERTY = 385, TK_HIDE_NS = 386, TK_FORMAT = 387, TK_GET = 388, TK_ID = 389, TK_KWARGS = 390, TK_LANGUAGE = 391, TK_LICENSEE = 392, TK_NAME = 393, TK_OPTIONAL = 394, TK_ORDER = 395, TK_REMOVELEADING = 396, TK_SET = 397, TK_SIGNATURE = 398, TK_TIMESTAMP = 399, TK_TYPE = 400, TK_USEARGNAMES = 401, TK_USELIMITEDAPI = 402, TK_ALLRAISEPYEXC = 403, TK_CALLSUPERINIT = 404, TK_DEFERRORHANDLER = 405, TK_VERSION = 406 }; #endif /* Tokens. */ #define TK_API 258 #define TK_AUTOPYNAME 259 #define TK_DEFDOCSTRFMT 260 #define TK_DEFDOCSTRSIG 261 #define TK_DEFENCODING 262 #define TK_PLUGIN 263 #define TK_VIRTERRORHANDLER 264 #define TK_EXPTYPEHINTCODE 265 #define TK_TYPEHINTCODE 266 #define TK_DOCSTRING 267 #define TK_DOC 268 #define TK_EXPORTEDDOC 269 #define TK_EXTRACT 270 #define TK_MAKEFILE 271 #define TK_ACCESSCODE 272 #define TK_GETCODE 273 #define TK_SETCODE 274 #define TK_PREINITCODE 275 #define TK_INITCODE 276 #define TK_POSTINITCODE 277 #define TK_FINALCODE 278 #define TK_UNITCODE 279 #define TK_UNITPOSTINCLUDECODE 280 #define TK_MODCODE 281 #define TK_TYPECODE 282 #define TK_PREPYCODE 283 #define TK_COPYING 284 #define TK_MAPPEDTYPE 285 #define TK_CODELINE 286 #define TK_IF 287 #define TK_END 288 #define TK_NAME_VALUE 289 #define TK_PATH_VALUE 290 #define TK_STRING_VALUE 291 #define TK_VIRTUALCATCHERCODE 292 #define TK_TRAVERSECODE 293 #define TK_CLEARCODE 294 #define TK_GETBUFFERCODE 295 #define TK_RELEASEBUFFERCODE 296 #define TK_READBUFFERCODE 297 #define TK_WRITEBUFFERCODE 298 #define TK_SEGCOUNTCODE 299 #define TK_CHARBUFFERCODE 300 #define TK_PICKLECODE 301 #define TK_VIRTUALCALLCODE 302 #define TK_METHODCODE 303 #define TK_PREMETHODCODE 304 #define TK_INSTANCECODE 305 #define TK_FROMTYPE 306 #define TK_TOTYPE 307 #define TK_TOSUBCLASS 308 #define TK_INCLUDE 309 #define TK_OPTINCLUDE 310 #define TK_IMPORT 311 #define TK_EXPHEADERCODE 312 #define TK_MODHEADERCODE 313 #define TK_TYPEHEADERCODE 314 #define TK_MODULE 315 #define TK_CMODULE 316 #define TK_CONSMODULE 317 #define TK_COMPOMODULE 318 #define TK_CLASS 319 #define TK_STRUCT 320 #define TK_PUBLIC 321 #define TK_PROTECTED 322 #define TK_PRIVATE 323 #define TK_SIGNALS 324 #define TK_SIGNAL_METHOD 325 #define TK_SLOTS 326 #define TK_SLOT_METHOD 327 #define TK_BOOL 328 #define TK_SHORT 329 #define TK_INT 330 #define TK_LONG 331 #define TK_FLOAT 332 #define TK_DOUBLE 333 #define TK_CHAR 334 #define TK_WCHAR_T 335 #define TK_VOID 336 #define TK_PYOBJECT 337 #define TK_PYTUPLE 338 #define TK_PYLIST 339 #define TK_PYDICT 340 #define TK_PYCALLABLE 341 #define TK_PYSLICE 342 #define TK_PYTYPE 343 #define TK_PYBUFFER 344 #define TK_VIRTUAL 345 #define TK_ENUM 346 #define TK_SIGNED 347 #define TK_UNSIGNED 348 #define TK_SCOPE 349 #define TK_LOGICAL_OR 350 #define TK_CONST 351 #define TK_STATIC 352 #define TK_SIPSIGNAL 353 #define TK_SIPSLOT 354 #define TK_SIPANYSLOT 355 #define TK_SIPRXCON 356 #define TK_SIPRXDIS 357 #define TK_SIPSLOTCON 358 #define TK_SIPSLOTDIS 359 #define TK_SIPSSIZET 360 #define TK_NUMBER_VALUE 361 #define TK_REAL_VALUE 362 #define TK_TYPEDEF 363 #define TK_NAMESPACE 364 #define TK_TIMELINE 365 #define TK_PLATFORMS 366 #define TK_FEATURE 367 #define TK_LICENSE 368 #define TK_QCHAR_VALUE 369 #define TK_TRUE_VALUE 370 #define TK_FALSE_VALUE 371 #define TK_NULL_VALUE 372 #define TK_OPERATOR 373 #define TK_THROW 374 #define TK_QOBJECT 375 #define TK_EXCEPTION 376 #define TK_RAISECODE 377 #define TK_VIRTERRORCODE 378 #define TK_EXPLICIT 379 #define TK_TEMPLATE 380 #define TK_FINAL 381 #define TK_ELLIPSIS 382 #define TK_DEFMETATYPE 383 #define TK_DEFSUPERTYPE 384 #define TK_PROPERTY 385 #define TK_HIDE_NS 386 #define TK_FORMAT 387 #define TK_GET 388 #define TK_ID 389 #define TK_KWARGS 390 #define TK_LANGUAGE 391 #define TK_LICENSEE 392 #define TK_NAME 393 #define TK_OPTIONAL 394 #define TK_ORDER 395 #define TK_REMOVELEADING 396 #define TK_SET 397 #define TK_SIGNATURE 398 #define TK_TIMESTAMP 399 #define TK_TYPE 400 #define TK_USEARGNAMES 401 #define TK_USELIMITEDAPI 402 #define TK_ALLRAISEPYEXC 403 #define TK_CALLSUPERINIT 404 #define TK_DEFERRORHANDLER 405 #define TK_VERSION 406 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 203 "sip-4.19.7/sipgen/metasrc/parser.y" { char qchar; char *text; long number; double real; argDef memArg; signatureDef signature; signatureDef *optsignature; throwArgs *throwlist; codeBlock *codeb; docstringDef *docstr; valueDef value; valueDef *valp; optFlags optflags; optFlag flag; scopedNameDef *scpvalp; fcallDef fcall; int boolean; exceptionDef exceptionbase; classDef *klass; apiCfg api; autoPyNameCfg autopyname; compModuleCfg compmodule; consModuleCfg consmodule; defDocstringFmtCfg defdocstringfmt; defDocstringSigCfg defdocstringsig; defEncodingCfg defencoding; defMetatypeCfg defmetatype; defSupertypeCfg defsupertype; hiddenNsCfg hiddenns; exceptionCfg exception; docstringCfg docstring; extractCfg extract; featureCfg feature; licenseCfg license; importCfg import; includeCfg include; moduleCfg module; pluginCfg plugin; propertyCfg property; variableCfg variable; vehCfg veh; int token; } /* Line 1529 of yacc.c. */ #line 396 "sip-4.19.7/sipgen/parser.h" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif extern YYSTYPE yylval; sip-4.19.7/sipgen/sip.h0000644000076500000240000020753113231604431014724 0ustar philstaff00000000000000/* * The main header file for SIP. * * Copyright (c) 2018 Riverbank Computing Limited * * 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 #include /* * Define the SIP version number. */ #define SIP_VERSION 0x041307 #define SIP_VERSION_STR "4.19.7" #ifdef TRUE #undef TRUE #endif #ifdef FALSE #undef FALSE #endif #define TRUE 1 #define FALSE 0 /* Some convenient compiler extensions. */ #if defined(__GNUC__) #define SIP_NORETURN __attribute__((__noreturn__)) #define SIP_UNUSED __attribute__((__unused__)) #elif defined(_MSC_VER) #define SIP_NORETURN __declspec(noreturn) #endif #if !defined(SIP_NORETURN) #define SIP_NORETURN #endif #if !defined(SIP_UNUSED) #define SIP_UNUSED #endif #define DEFAULT_OFILE_EXT ".o" /* Default object file extension. */ #define MAX_NR_ARGS 20 /* Max. nr. args. to a function or template. */ #define MAX_NR_DEREFS 5 /* Max. nr. type derefences. */ /* For convenience. */ #define classBaseName(cd) scopedNameTail((cd)->iff->fqcname) #define classFQCName(cd) ((cd)->iff->fqcname) /* Return the Python scope corresponding to a C/C++ scope. */ #define pyScope(c) ((c) != NULL && isHiddenNamespace(c) ? NULL : (c)) /* 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 MOD_USE_ARG_NAMES 0x0010 /* Use real argument names. */ #define MOD_USE_LIMITED_API 0x0020 /* Use the limited API. */ #define MOD_ALL_RAISE_PY_EXC 0x0040 /* All callable raise a Python exception. */ #define MOD_SUPER_INIT_NO 0x0080 /* Don't call super().__init__(). */ #define MOD_SUPER_INIT_YES 0x0100 /* Call super().__init__(). */ #define MOD_SUPER_INIT_UNDEF 0x0000 /* Calling super().__init__() is undefined. */ #define MOD_SUPER_INIT_MASK 0x0180 /* The mask for the above flags. */ #define MOD_SETTING_IMPORTS 0x0200 /* Imports are being set. */ #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) #define setUseArgNames(m) ((m)->modflags |= MOD_USE_ARG_NAMES) #define useArgNames(m) ((m)->modflags & MOD_USE_ARG_NAMES) #define setUseLimitedAPI(m) ((m)->modflags |= MOD_USE_LIMITED_API) #define useLimitedAPI(m) ((m)->modflags & MOD_USE_LIMITED_API) #define setAllRaisePyException(m) ((m)->modflags |= MOD_ALL_RAISE_PY_EXC) #define allRaisePyException(m) ((m)->modflags & MOD_ALL_RAISE_PY_EXC) #define setCallSuperInitNo(m) ((m)->modflags = ((m)->modflags & ~MOD_SUPER_INIT_MASK) | MOD_SUPER_INIT_NO) #define setCallSuperInitYes(m) ((m)->modflags = ((m)->modflags & ~MOD_SUPER_INIT_MASK) | MOD_SUPER_INIT_YES) #define isCallSuperInitYes(m) (((m)->modflags & MOD_SUPER_INIT_MASK) == MOD_SUPER_INIT_YES) #define isCallSuperInitUndefined(m) (((m)->modflags & MOD_SUPER_INIT_MASK) == MOD_SUPER_INIT_UNDEF) #define settingImports(m) ((m)->modflags & MOD_SETTING_IMPORTS) #define setSettingImports(m) ((m)->modflags |= MOD_SETTING_IMPORTS) #define resetSettingImports(m) ((m)->modflags &= ~MOD_SETTING_IMPORTS) /* 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 CLASS_HAS_NONLAZY 0x80000000 /* The class has non-lazy methods. */ #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 noPyQtQMetaObject(cd) ((cd)->classflags & CLASS_NO_QMETAOBJECT) #define setPyQtNoQMetaObject(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 hasNonlazyMethod(cd) ((cd)->classflags & CLASS_HAS_NONLAZY) #define setHasNonlazyMethod(cd) ((cd)->classflags |= CLASS_HAS_NONLAZY) #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 the second group of class flags. */ #define CLASS2_TMPL_ARG 0x01 /* The class is a template argument. */ #define CLASS2_MIXIN 0x02 /* The class is a mixin. */ #define CLASS2_EXPORT_DERIVED 0x04 /* Export the derived class declaration. */ #define CLASS2_HIDDEN_NS 0x08 /* The namespace is hidden. */ #define CLASS2_USE_TMPL_NAME 0x10 /* Use the template name. */ #define CLASS2_NEEDS_SHADOW 0x20 /* The class needs a shadow class. */ #define isTemplateArg(cd) ((cd)->classflags2 & CLASS2_TMPL_ARG) #define setTemplateArg(cd) ((cd)->classflags2 |= CLASS2_TMPL_ARG) #define resetTemplateArg(cd) ((cd)->classflags2 &= ~CLASS2_TMPL_ARG) #define isMixin(cd) ((cd)->classflags2 & CLASS2_MIXIN) #define setMixin(cd) ((cd)->classflags2 |= CLASS2_MIXIN) #define isExportDerived(cd) ((cd)->classflags2 & CLASS2_EXPORT_DERIVED) #define setExportDerived(cd) ((cd)->classflags2 |= CLASS2_EXPORT_DERIVED) #define isHiddenNamespace(cd) ((cd)->classflags2 & CLASS2_HIDDEN_NS) #define setHiddenNamespace(cd) ((cd)->classflags2 |= CLASS2_HIDDEN_NS) #define useTemplateName(cd) ((cd)->classflags2 & CLASS2_USE_TMPL_NAME) #define setUseTemplateName(cd) ((cd)->classflags2 |= CLASS2_USE_TMPL_NAME) #define needsShadow(cd) ((cd)->classflags & CLASS2_NEEDS_SHADOW) #define setNeedsShadow(cd) ((cd)->classflags |= CLASS2_NEEDS_SHADOW) /* 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_RAISES_PY_EXC 0x00004000 /* It raises a Python exception. */ #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 raisesPyExceptionCtor(c) ((c)->ctorflags & CTOR_RAISES_PY_EXC) #define setRaisesPyExceptionCtor(c) ((c)->ctorflags |= CTOR_RAISES_PY_EXC) /* Handle member flags. */ #define MEMBR_NUMERIC 0x0001 /* It is a numeric slot. */ #define MEMBR_SEQUENCE 0x0002 /* It is a sequnce slot. */ #define MEMBR_NO_ARG_PARSER 0x0004 /* Don't generate an argument parser. */ #define MEMBR_NOT_VERSIONED 0x0008 /* There is an unversioned overload. */ #define MEMBR_KEYWORD_ARGS 0x0010 /* It allows keyword arguments. */ #define MEMBR_HAS_PROTECTED 0x0011 /* It has a protected overload. */ #define isNumeric(m) ((m)->memberflags & MEMBR_NUMERIC) #define setIsNumeric(m) ((m)->memberflags |= MEMBR_NUMERIC) #define isSequence(m) ((m)->memberflags & MEMBR_SEQUENCE) #define setIsSequence(m) ((m)->memberflags |= MEMBR_SEQUENCE) #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 useKeywordArgs(m) ((m)->memberflags & MEMBR_KEYWORD_ARGS) #define setUseKeywordArgs(m) ((m)->memberflags |= MEMBR_KEYWORD_ARGS) #define hasProtected(m) ((m)->memberflags & MEMBR_HAS_PROTECTED) #define setHasProtected(m) ((m)->memberflags |= MEMBR_HAS_PROTECTED) /* Handle enum flags. These are combined with the section flags. */ #define ENUM_WAS_PROT 0x00000100 /* It was defined as protected. */ #define ENUM_NO_SCOPE 0x00000200 /* Omit the member scopes. */ #define ENUM_NEEDS_ENUM 0x00000400 /* The module needs it. */ #define ENUM_SCOPED 0x00000800 /* A C++0x11 scoped enum. */ #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) #define isNoScope(e) ((e)->enumflags & ENUM_NO_SCOPE) #define setIsNoScope(e) ((e)->enumflags |= ENUM_NO_SCOPE) #define needsEnum(e) ((e)->enumflags & ENUM_NEEDS_ENUM) #define setNeedsEnum(e) ((e)->enumflags |= ENUM_NEEDS_ENUM) #define isScopedEnum(e) ((e)->enumflags & ENUM_SCOPED) #define setIsScopedEnum(e) ((e)->enumflags |= ENUM_SCOPED) /* 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_REALLY_PROT 0x02000000 /* It really is protected. */ #define OVER_IS_DELATTR 0x04000000 /* It is __delattr__. */ #define OVER_RAISES_PY_EXC 0x08000000 /* It raises a Python exception. */ #define OVER_NO_ERROR_HANDLER 0x10000000 /* It doesn't use a virtual error handler. */ #define OVER_ABORT_ON_EXC 0x20000000 /* It aborts on an exception. */ #define OVER_IS_FINAL 0x40000000 /* It is a final method. */ #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 isReallyProtected(o) ((o)->overflags & OVER_REALLY_PROT) #define setIsReallyProtected(o) ((o)->overflags |= OVER_REALLY_PROT) #define isDelattr(o) ((o)->overflags & OVER_IS_DELATTR) #define setIsDelattr(o) ((o)->overflags |= OVER_IS_DELATTR) #define raisesPyException(o) ((o)->overflags & OVER_RAISES_PY_EXC) #define setRaisesPyException(o) ((o)->overflags |= OVER_RAISES_PY_EXC) #define noErrorHandler(o) ((o)->overflags & OVER_NO_ERROR_HANDLER) #define setNoErrorHandler(o) ((o)->overflags |= OVER_NO_ERROR_HANDLER) #define abortOnException(o) ((o)->overflags & OVER_ABORT_ON_EXC) #define setAbortOnException(o) ((o)->overflags |= OVER_ABORT_ON_EXC) #define isFinal(o) ((o)->overflags & OVER_IS_FINAL) #define setIsFinal(o) ((o)->overflags |= OVER_IS_FINAL) /* Handle variable flags. */ #define VAR_IS_STATIC 0x01 /* It is a static variable. */ #define VAR_NEEDS_HANDLER 0x02 /* The variable needs a handler. */ #define VAR_NO_SETTER 0x04 /* The variable has no setter. */ #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) #define noSetter(v) ((v)->varflags & VAR_NO_SETTER) #define setNoSetter(v) ((v)->varflags |= VAR_NO_SETTER) /* Handle argument flags. */ #define ARG_IS_REF 0x00000001 /* It is a reference. */ #define ARG_IS_CONST 0x00000002 /* It is a const. */ #define ARG_XFERRED 0x00000004 /* Ownership is transferred. */ #define ARG_THIS_XFERRED 0x00000008 /* Ownership of this is transferred. */ #define ARG_XFERRED_BACK 0x00000010 /* Ownership is transferred back. */ #define ARG_ARRAY 0x00000020 /* Used as an array. */ #define ARG_ARRAY_SIZE 0x00000040 /* Used as an array size. */ #define ARG_ALLOW_NONE 0x00000080 /* Allow None as a value. */ #define ARG_GET_WRAPPER 0x00000100 /* Get the wrapper object. */ #define ARG_IN 0x00000200 /* It passes an argument. */ #define ARG_OUT 0x00000400 /* It returns a result. */ #define ARG_CONSTRAINED 0x00000800 /* Suppress type conversion. */ #define ARG_SINGLE_SHOT 0x00001000 /* The slot is only ever fired once. */ #define ARG_RESULT_SIZE 0x00002000 /* It defines the result size. */ #define ARG_KEEP_REF 0x00004000 /* Keep a reference. */ #define ARG_NO_COPY 0x00008000 /* Disable copying of const refs. */ #define ARG_DISALLOW_NONE 0x00010000 /* Disallow None as a value. */ #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) #define isDisallowNone(a) ((a)->argflags & ARG_DISALLOW_NONE) #define setDisallowNone(a) ((a)->argflags |= ARG_DISALLOW_NONE) /* 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_TRANSFERS 0x01 /* It transfers ownership of the result. */ #define VH_ABORT_ON_EXC 0x02 /* It aborts on an exception. */ #define isTransferVH(vh) ((vh)->vhflags & VH_TRANSFERS) #define setIsTransferVH(vh) ((vh)->vhflags |= VH_TRANSFERS) #define abortOnExceptionVH(vh) ((vh)->vhflags & VH_ABORT_ON_EXC) #define setAbortOnExceptionVH(vh) ((vh)->vhflags |= VH_ABORT_ON_EXC) /* 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) /* Warning categories. */ typedef enum { ParserWarning, DeprecationWarning } Warning; /* Docstring formatting. */ typedef enum { raw, deindented } Format; /* Docstring signature positioning. */ typedef enum { discarded, prepended, appended } Signature; /* Levels of keyword argument support. */ typedef enum { NoKwArgs = 0, AllKwArgs, OptionalKwArgs } KwArgs; /* Slot types. */ typedef enum { str_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, setattr_slot, delattr_slot, /* This is local to the parser. */ matmul_slot, imatmul_slot, await_slot, aiter_slot, anext_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, byte_type, sbyte_type, ubyte_type, capsule_type, pybuffer_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; /* Type hint parse status. */ typedef enum { needs_parsing, being_parsed, parsed } typeHintParseStatus; /* Type hint node type. */ typedef enum { typing_node, class_node, enum_node, brackets_node, other_node } typeHintNodeType; /* A location in a .sip source file. */ typedef struct { int linenr; /* The line number. */ const char *name; /* The filename. */ } sourceLocation; /* A software license. */ typedef struct { const char *type; /* The license type. */ const char *licensee; /* The licensee. */ const char *timestamp; /* The timestamp. */ const char *sig; /* The signature. */ } licenseDef; /* A version qualifier. */ typedef struct _qualDef { const 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. */ int default_enabled; /* Enabled by default. */ struct _qualDef *next; /* Next in the list. */ } qualDef; /* A platform. */ typedef struct _platformDef { struct _qualDef *qualifier; /* The platform qualifier. */ struct _platformDef *next; /* Next in the list. */ } platformDef; /* 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. */ } codeBlock; /* A list of literal code blocks. */ typedef struct _codeBlockList { codeBlock *block; /* The code block. */ struct _codeBlockList *next; /* The next in the list. */ } codeBlockList; /* 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. */ int needed; /* The module needs it. */ 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. */ codeBlockList *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. */ scopedNameDef *cast; /* Any cast. */ 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. */ struct _typeHintDef *typehint_in; /* The PEP 484 input type hint. */ struct _typeHintDef *typehint_out; /* The PEP 484 output type hint. */ const char *typehint_value; /* The type hint value. */ int argflags; /* The argument flags. */ int nrderefs; /* Nr. of dereferences. */ int derefs[MAX_NR_DEREFS]; /* The const for each dereference. */ valueDef *defval; /* The default 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. */ struct _scopedNameDef *cap; /* If it is a capsule. */ } 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 virtual error handler. */ typedef struct _virtErrorHandler { const char *name; /* The name of the handler. */ codeBlockList *code; /* The handler code. */ struct _moduleDef *mod; /* The defining module. */ int index; /* The index within the module. */ struct _virtErrorHandler *next; /* The next in the list. */ } virtErrorHandler; /* A parsed PEP 484 compliant type hint. */ typedef struct _typeHintDef { typeHintParseStatus status; /* The state of the type hint parse. */ char *raw_hint; /* The raw hint. */ struct _typeHintNodeDef *root; /* The root of parsed nodes. */ } typeHintDef; /* A node of a parsed type hint. */ typedef struct _typeHintNodeDef { typeHintNodeType type; /* The type of the node. */ union { const char *name; /* For typing objects and others. */ struct _classDef *cd; /* For class nodes. */ struct _enumDef *ed; /* For enum nodes. */ } u; struct _typeHintNodeDef *children; /* The list of children. */ struct _typeHintNodeDef *next; /* The next sibling. */ } typeHintNodeDef; /* An explicit docstring. */ typedef struct _docstringDef { Signature signature; /* How the signature should be positioned. */ char *text; /* The text of the docstring. */ } docstringDef; /* A module definition. */ typedef struct _moduleDef { nameDef *fullname; /* The full module name. */ const char *name; /* The module base name. */ docstringDef *docstring; /* The docstring. */ apiVersionRangeDef *api_versions; /* The defined APIs. */ apiVersionRangeDef *api_ranges; /* The list of API version ranges. */ int modflags; /* The module flags. */ KwArgs kwargs; /* The style of keyword argument support. */ struct _memberDef *othfuncs; /* List of other functions. */ struct _overDef *overs; /* Global overloads. */ Format defdocstringfmt; /* The default docstring format. */ Signature defdocstringsig; /* The default docstring signature. */ 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. */ codeBlockList *hdrcode; /* Header code. */ codeBlockList *cppcode; /* Global C++ code. */ codeBlockList *copying; /* Software license. */ codeBlockList *preinitcode; /* Pre-initialisation code. */ codeBlockList *initcode; /* Initialisation code. */ codeBlockList *postinitcode; /* Post-initialisation code. */ codeBlockList *unitcode; /* Compilation unit code. */ codeBlockList *unitpostinccode; /* Compilation unit post-include code. */ codeBlockList *typehintcode; /* Type hint code. */ const char *virt_error_handler; /* The virtual error handler. */ int parts; /* The number of parts generated. */ const char *file; /* The filename. */ qualDef *qualifiers; /* The list of qualifiers. */ argDef *needed_types; /* The array of needed types. */ int nr_needed_types; /* The number of needed types. */ int nrtimelines; /* The nr. of timelines. */ int nrexceptions; /* The nr. of exceptions. */ int nrtypedefs; /* The nr. of typedefs. */ int nrvirterrorhandlers; /* The nr. of virtual error handlers. */ int next_key; /* The next key to allocate. */ 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 _autoPyNameDef *autopyname; /* The Python naming rules. */ 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. */ int needed; /* The main module needs it. */ 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. */ codeBlockList *hdrcode; /* Header code. */ const char *file_extension; /* The optional file extension. */ struct _ifaceFileList *used; /* Interface files used. */ platformDef *platforms; /* The platforms. */ 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. */ typeHintDef *typehint_in; /* The PEP 484 input type hint. */ typeHintDef *typehint_out; /* The PEP 484 output type hint. */ const char *typehint_value; /* The type hint value. */ ifaceFileDef *iff; /* The interface file. */ struct _memberDef *members; /* The static member functions. */ struct _overDef *overs; /* The static overloads. */ codeBlockList *instancecode; /* Create instance code. */ codeBlockList *typecode; /* Type code. */ codeBlockList *convfromcode; /* Convert from C++ code. */ codeBlockList *convtocode; /* Convert to C++ code. */ struct _mappedTypeDef *real; /* The original definition. */ 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. */ codeBlockList *virtcode; /* Virtual handler code. */ virtErrorHandler *veh; /* The virtual error handler. */ 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. */ platformDef *platforms; /* The platforms. */ struct _typedefDef *next; /* Next in the list. */ } typedefDef; /* A variable definition. */ typedef struct _varDef { scopedNameDef *fqcname; /* The fully qualified C/C++ name. */ nameDef *pyname; /* The variable Python name. */ int no_typehint; /* The type hint will be suppressed. */ struct _classDef *ecd; /* The enclosing class. */ moduleDef *module; /* The owning module. */ int varflags; /* The variable flags. */ argDef type; /* The actual type. */ codeBlockList *accessfunc; /* The access function. */ codeBlockList *getcode; /* The get code. */ codeBlockList *setcode; /* The set code. */ platformDef *platforms; /* The platforms. */ struct _varDef *next; /* Next in the list. */ } varDef; /* A property definition. */ typedef struct _propertyDef { nameDef *name; /* The property name. */ docstringDef *docstring; /* The docstring. */ const char *get; /* The name of the getter method. */ const char *set; /* The name of the setter method. */ platformDef *platforms; /* The platforms. */ struct _propertyDef *next; /* Next in the list. */ } propertyDef; /* An overloaded member function definition. */ typedef struct _overDef { sourceLocation sloc; /* The source location. */ char *cppname; /* The C++ name. */ docstringDef *docstring; /* The docstring. */ int overflags; /* The overload flags. */ int no_typehint; /* The type hint will be suppressed. */ int pyqt_signal_hack; /* The PyQt signal hack. */ KwArgs kwargs; /* The keyword argument support. */ 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. */ codeBlockList *methodcode; /* Method code. */ codeBlockList *premethodcode; /* Code to insert before the method code. */ codeBlockList *virtcallcode; /* Virtual call code. */ codeBlockList *virtcode; /* Virtual handler code. */ char *prehook; /* The pre-hook name. */ char *posthook; /* The post-hook name. */ const char *virt_error_handler; /* The virtual error handler. */ platformDef *platforms; /* The platforms. */ struct _overDef *next; /* Next in the list. */ } overDef; /* An overloaded constructor definition. */ typedef struct _ctorDef { docstringDef *docstring; /* The docstring. */ int ctorflags; /* The ctor flags. */ int no_typehint; /* The type hint will be suppressed. */ KwArgs kwargs; /* The keyword argument support. */ 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. */ codeBlockList *methodcode; /* Method code. */ codeBlockList *premethodcode; /* Code to insert before the method code. */ char *prehook; /* The pre-hook name. */ char *posthook; /* The post-hook name. */ platformDef *platforms; /* The platforms. */ struct _ctorDef *next; /* Next in the list. */ } ctorDef; /* An enumerated type member definition. */ typedef struct _enumMemberDef { nameDef *pyname; /* The Python name. */ int no_typehint; /* The type hint will be suppressed. */ char *cname; /* The C/C++ name. */ struct _enumDef *ed; /* The enclosing enum. */ platformDef *platforms; /* The platforms. */ struct _enumMemberDef *next; /* Next in the list. */ } enumMemberDef; /* An enumerated type definition. */ typedef struct _enumDef { int enumflags; /* The enum flags. */ scopedNameDef *fqcname; /* The C/C++ name (may be NULL). */ nameDef *cname; /* The C/C++ name (may be NULL). */ nameDef *pyname; /* The Python name (may be NULL). */ int no_typehint; /* The type hint will be suppressed. */ 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. */ platformDef *platforms; /* The platforms. */ 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. */ struct _ifaceFileDef *ns_scope; /* The scope if it has been moved. */ 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 *od; /* The overload. */ virtHandlerDef *virthandler; /* The virtual handler. */ 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 { docstringDef *docstring; /* The class docstring. */ unsigned classflags; /* The class flags. */ unsigned classflags2; /* The class flags, part 2. */ int pyqt_flags; /* The PyQt specific flags. */ const char *pyqt_interface; /* The Qt interface name. */ nameDef *pyname; /* The Python name. */ int no_typehint; /* The type hint will be suppressed. */ 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. */ codeBlockList *dealloccode; /* Handwritten dealloc code. */ codeBlockList *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. */ codeBlockList *cppcode; /* Class C++ code. */ codeBlockList *convtosubcode; /* Convert to sub C++ code. */ struct _classDef *subbase; /* Sub-class base class. */ codeBlockList *instancecode; /* Create instance code. */ codeBlockList *convtocode; /* Convert to C++ code. */ codeBlockList *convfromcode; /* Convert from C++ code. */ codeBlockList *travcode; /* Traverse code. */ codeBlockList *clearcode; /* Clear code. */ codeBlockList *getbufcode; /* Get buffer code (Python v3). */ codeBlockList *releasebufcode; /* Release buffer code (Python v3). */ codeBlockList *readbufcode; /* Read buffer code (Python v2). */ codeBlockList *writebufcode; /* Write buffer code (Python v2). */ codeBlockList *segcountcode; /* Segment count code (Python v2). */ codeBlockList *charbufcode; /* Character buffer code (Python v2). */ codeBlockList *picklecode; /* Pickle code. */ codeBlockList *finalcode; /* Finalisation code. */ codeBlockList *typehintcode; /* Type hint code. */ propertyDef *properties; /* The properties. */ const char *virt_error_handler; /* The virtual error handler. */ typeHintDef *typehint_in; /* The PEP 484 input type hint. */ typeHintDef *typehint_out; /* The PEP 484 output type hint. */ const char *typehint_value; /* The type hint value. */ 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 extracts for an identifier. */ typedef struct _extractDef { const char *id; /* The identifier. */ struct _extractPartDef *parts; /* The ordered list of parts. */ struct _extractDef *next; /* The next in the list. */ } extractDef; /* Part of an extract for an identifier. */ typedef struct _extractPartDef { int order; /* The order of the part. */ codeBlock *part; /* The part itself. */ struct _extractPartDef *next; /* The next in the list. */ } extractPartDef; /* A rule for automatic Python naming. */ typedef struct _autoPyNameDef { const char *remove_leading; /* Leading string to remove. */ struct _autoPyNameDef *next; /* The next in the list. */ } autoPyNameDef; /* 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. */ int nrvirthandlers; /* The number of virtual handlers. */ virtHandlerDef *virthandlers; /* The virtual handlers. */ virtErrorHandler *errorhandlers; /* The list of virtual error handlers. */ codeBlockList *exphdrcode; /* Exported header code. */ codeBlockList *exptypehintcode; /* Exported type hint code. */ codeBlockList *docs; /* Documentation. */ classDef *qobject_cd; /* QObject class, NULL if none. */ 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. */ struct _extractDef *extracts; /* The list of extracts. */ } 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 *, int, stringList *, stringList *, stringList *, KwArgs, int); void parserEOF(const char *,parserContext *); void transform(sipSpec *, int); void generateCode(sipSpec *, char *, char *, char *, const char *, int, int, int, int, stringList *needed_qualifiers, stringList *, const char *, int, int); void generateExtracts(sipSpec *pt, const stringList *extracts); void addExtractPart(sipSpec *pt, const char *id, int order, codeBlock *part); void generateAPI(sipSpec *pt, moduleDef *mod, const char *apiFile); void generateXML(sipSpec *pt, moduleDef *mod, const char *xmlFile); void generateTypeHints(sipSpec *pt, moduleDef *mod, const char *pyiFile); void generateExpression(valueDef *vd, int in_str, FILE *fp); void warning(Warning w, const char *fmt, ...); void deprecated(const char *msg); SIP_NORETURN void fatal(const char *fmt,...); void fatalScopedName(scopedNameDef *); void fatalStart(); void getSourceLocation(sourceLocation *slp); int setInputFile(FILE *open_fp, parserContext *pc, int optional); void resetLexerState(); 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 appendToIfaceFileList(ifaceFileList **ifflp, ifaceFileDef *iff); int selectedQualifier(stringList *needed_qualifiers, qualDef *qd); 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 appendCodeBlockList(codeBlockList **headp, codeBlockList *cbl); void prcode(FILE *fp, const char *fmt, ...); void prCopying(FILE *fp, moduleDef *mod, const char *comment); void prOverloadName(FILE *fp, overDef *od); void prOverloadDecl(FILE *fp, ifaceFileDef *scope, overDef *od, int defval); void prDefaultValue(argDef *ad, int in_str, FILE *fp); void prScopedPythonName(FILE *fp, classDef *scope, const char *pyname); void searchTypedefs(sipSpec *pt, scopedNameDef *snd, argDef *ad); int isZeroArgSlot(memberDef *md); int isIntReturnSlot(memberDef *md); int isSSizeReturnSlot(memberDef *md); int isLongReturnSlot(memberDef *md); int isVoidReturnSlot(memberDef *md); int isNumberSlot(memberDef *md); int isInplaceNumberSlot(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); codeBlockList *templateCode(sipSpec *pt, ifaceFileList **used, codeBlockList *ocbl, scopedNameDef *names, scopedNameDef *values); ifaceFileDef *findIfaceFile(sipSpec *pt, moduleDef *mod, scopedNameDef *fqname, ifaceFileType iftype, apiVersionRangeDef *api_range, argDef *ad); int pluginPyQt4(sipSpec *pt); int pluginPyQt5(sipSpec *pt); SIP_NORETURN void yyerror(char *); void yywarning(char *); int yylex(); nameDef *cacheName(sipSpec *pt, const char *name); scopedNameDef *encodedTemplateName(templateDef *td); apiVersionRangeDef *findAPI(sipSpec *pt, const char *name); memberDef *findMethod(classDef *cd, const char *name); typeHintDef *newTypeHint(char *raw_hint); int isPyKeyword(const char *word); void getDefaultImplementation(sipSpec *pt, argType atype, classDef **cdp, mappedTypeDef **mtdp); char *templateString(const char *src, scopedNameDef *names, scopedNameDef *values); int inDefaultAPI(sipSpec *pt, apiVersionRangeDef *range); int hasImplicitOverloads(signatureDef *sd); void dsCtor(sipSpec *pt, classDef *cd, ctorDef *ct, int sec, FILE *fp); void dsOverload(sipSpec *pt, overDef *od, int is_method, int sec, FILE *fp); scopedNameDef *getFQCNameOfType(argDef *ad); scopedNameDef *removeGlobalScope(scopedNameDef *snd); /* 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, opt_integer_flag, api_range_flag } flagType; typedef struct { const 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; /* These represent the configuration of different directives. */ /* %API */ typedef struct _apiCfg { int token; const char *name; int version; } apiCfg; /* %AutoPyName */ typedef struct _autoPyNameCfg { int token; const char *remove_leading; } autoPyNameCfg; /* %CompositeModule */ typedef struct _compModuleCfg { int token; const char *name; docstringDef *docstring; } compModuleCfg; /* %ConsolidatedModule */ typedef struct _consModuleCfg { int token; const char *name; docstringDef *docstring; } consModuleCfg; /* %DefaultDocstringFormat */ typedef struct _defDocstringFmtCfg { int token; const char *name; } defDocstringFmtCfg; /* %DefaultDocstringSignature */ typedef struct _defDocstringSigCfg { int token; const char *name; } defDocstringSigCfg; /* %DefaultEncoding */ typedef struct _defEncodingCfg { int token; const char *name; } defEncodingCfg; /* %DefaultMetatype */ typedef struct _defMetatypeCfg { int token; const char *name; } defMetatypeCfg; /* %DefaultSupertype */ typedef struct _defSupertypeCfg { int token; const char *name; } defSupertypeCfg; /* %Docstring */ typedef struct _docstringCfg { int token; Format format; Signature signature; } docstringCfg; /* %Exception */ typedef struct _exceptionCfg { int token; codeBlock *type_header_code; codeBlock *raise_code; } exceptionCfg; /* %Extract */ typedef struct _extractCfg { int token; const char *id; int order; } extractCfg; /* %Feature */ typedef struct _featureCfg { int token; const char *name; } featureCfg; /* %HiddenNamespace */ typedef struct _hiddenNsCfg { int token; scopedNameDef *name; } hiddenNsCfg; /* %Import */ typedef struct _importCfg { int token; const char *name; } importCfg; /* %Include */ typedef struct _includeCfg { int token; const char *name; int optional; } includeCfg; /* %License */ typedef struct _licenseCfg { int token; const char *type; const char *licensee; const char *signature; const char *timestamp; } licenseCfg; /* %Module and its sub-directives. */ typedef struct _moduleCfg { int token; int c_module; KwArgs kwargs; const char *name; int use_arg_names; int use_limited_api; int all_raise_py_exc; int call_super_init; const char *def_error_handler; docstringDef *docstring; } moduleCfg; /* %Plugin */ typedef struct _pluginCfg { int token; const char *name; } pluginCfg; /* %Property */ typedef struct _propertyCfg { int token; const char *get; const char *name; const char *set; docstringDef *docstring; } propertyCfg; /* Variable sub-directives. */ typedef struct _variableCfg { int token; codeBlock *access_code; codeBlock *get_code; codeBlock *set_code; } variableCfg; /* %VirtualErrorHandler */ typedef struct _vehCfg { int token; const char *name; } vehCfg; #endif sip-4.19.7/sipgen/sipgen.sbf0000644000076500000240000000142613231604405015735 0ustar philstaff00000000000000# This is the build file for the code generator. # # Copyright (c) 2016 Riverbank Computing Limited # # 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 extracts.c export.c type_hints.c heap.c parser.c lexer.c headers = sip.h parser.h sip-4.19.7/sipgen/transform.c0000644000076500000240000031734613231604406016147 0ustar philstaff00000000000000/* * The parse tree transformation module for SIP. * * Copyright (c) 2017 Riverbank Computing Limited * * 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 #include #include #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 sameCppOverload(overDef *od1, overDef *od2); 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, int need_types); static void ifaceFilesAreUsedByOverload(ifaceFileList **used, overDef *od, int need_types); static void ifaceFilesAreUsedBySignature(ifaceFileList **used, signatureDef *sd, int need_types); static void scopeDefaultValue(sipSpec *,classDef *,argDef *); static void setHierarchy(sipSpec *,classDef *,classDef *,classList **); static void transformModules(sipSpec *pt, int strict, moduleDef *mod); static void transformCtors(sipSpec *,classDef *); static void transformCasts(sipSpec *,classDef *); static void addDefaultCopyCtor(classDef *); static void transformScopeOverloads(sipSpec *pt, int strict, classDef *c_scope, mappedTypeDef *mt_scope, overDef *overs); static void transformVariableList(sipSpec *pt, moduleDef *mod); static void transformMappedTypes(sipSpec *pt, int strict, moduleDef *mod); static void getVisiblePyMembers(sipSpec *pt, classDef *cd); static void getVirtuals(sipSpec *pt, classDef *cd); static void addVirtual(sipSpec *pt, overDef *od, classDef *cd); static virtErrorHandler *getVirtErrorHandler(sipSpec *pt, overDef *od, classDef *cd); static virtHandlerDef *getVirtualHandler(sipSpec *pt, overDef *od, classDef *cd); static int checkVirtualHandler(overDef *od, virtHandlerDef *vhd); 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, overDef *od); static void resolvePySigTypes(sipSpec *,moduleDef *,classDef *,overDef *,signatureDef *,int); static void resolveVariableType(sipSpec *,varDef *); SIP_NORETURN static void fatalNoDefinedType(scopedNameDef *); static void resolveType(sipSpec *,moduleDef *,classDef *,argDef *,int); static void setNeededType(argDef *ad); static void setNeededExceptions(sipSpec *pt, moduleDef *mod, throwArgs *exceptions); static void setNeedsException(exceptionDef *xd); static void searchClassScope(sipSpec *pt, classDef *c_scope, scopedNameDef *snd, argDef *ad); static void searchScope(sipSpec *pt, classDef *scope, scopedNameDef *snd, argDef *ad); static void nameLookup(sipSpec *pt, moduleDef *context, scopedNameDef *snd, argDef *ad); 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 ifaceFileDef *getIfaceFile(argDef *ad); static ifaceFileDef *getIfaceFileForEnum(enumDef *ed); 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 mappedTypeDef *copyTemplateType(mappedTypeDef *mtd, argDef *ad); static void checkProperties(classDef *cd); /* * Transform the parse tree. */ void transform(sipSpec *pt, int strict) { moduleDef *mod; classDef *cd, *rev, **tail; classList *newl; overDef *od; exceptionDef *xd; /* * 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; /* * Take the opportunity to strip any classes that are only template * arguments. */ while (isTemplateArg(cd)) if ((cd = cd->next) == NULL) break; if (cd == NULL) break; 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, strict, mod); } else { transformModules(pt, strict, 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); /* 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) { if (needsShadow(cd) && !isIncomplete(cd) && !isPrivateDtor(cd) && canCreate(cd)) setHasShadow(cd); /* Get the list of visible Python member functions. */ getVisiblePyMembers(pt, cd); /* Get the virtual members. */ if (needsShadow(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, FALSE); } for (mod = pt->modules; mod != NULL; mod = mod->next) { /* Create the array of numbered types sorted by type name. */ createSortedNumberedTypesTable(pt, mod); for (od = mod->overs; od != NULL; od = od->next) ifaceFilesAreUsedByOverload(&mod->used, od, FALSE); /* 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; } /* Additional class specific checks. */ for (cd = pt->classes; cd != NULL; cd = cd->next) { checkAssignmentHelper(pt, cd); checkProperties(cd); } /* Number the exceptions as they will be seen by the main module. */ for (xd = pt->exceptions; xd != NULL; xd = xd->next) { moduleDef *xd_mod; /* * Skip those that don't require a Python exception object to be * created. */ if (xd->iff->type != exception_iface) continue; if (xd->bibase == NULL && xd->base == NULL) continue; xd_mod = xd->iff->module; if (xd_mod == pt->module || xd->needed) xd->exceptionnr = xd_mod->nrexceptions++; } setStringPoolOffsets(pt); } /* * Transform a module and the modules it imports. */ static void transformModules(sipSpec *pt, int strict, 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, strict, mld->module); /* Transform typedefs, variables and global functions. */ transformTypedefs(pt, mod); transformVariableList(pt, mod); transformScopeOverloads(pt, strict, 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); /* Handle any dtor exceptions. */ setNeededExceptions(pt, mod, cd->dtorexceptions); if (!pt->genc) { transformScopeOverloads(pt, strict, cd, NULL, cd->overs); transformCasts(pt, cd); } } } /* Transform mapped types based on templates. */ transformMappedTypes(pt, strict, 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; /* Suppress a compiler warning. */ default: ; } } /* * 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); appendToIfaceFileList(&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; /* Check for recursive imports. */ if (settingImports(mod)) { fatalStart(); fatal("Module %s is imported recursively\n", mod->name); } setSettingImports(mod); /* 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); } resetSettingImports(mod); } /* * 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); /* 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; memcpy(ad->derefs, al->arg.derefs, sizeof (ad->derefs)); ad->defval = NULL; ad->u.cd = cd; /* * If the destination class is in a different module then use * a proxy. */ if (dcd->iff->module != mod) { ifaceFileIsUsed(&mod->used, ad, FALSE); dcd = getProxy(mod, dcd); ct->no_typehint = TRUE; } ifaceFileIsUsed(&dcd->iff->used, ad, FALSE); 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)) { fatalStart(); fprintf(stderr, "operator "); fatalScopedName(classFQCName(dcd)); fprintf(stderr, "::"); fatalScopedName(classFQCName(dcd)); fprintf(stderr, "("); 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; enumDef *ed; 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; ed = 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; ed = arg0->u.ed; } 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; ed = arg1->u.ed; second = TRUE; } if (mdhead == NULL) { fatalStart(); fprintf(stderr, "%s:%d: One of the arguments of ", od->sloc.name, od->sloc.linenr); 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) { fatalStart(); fprintf(stderr, "%s:%d: Argument 1 of ", od->sloc.name, od->sloc.linenr); prOverloadName(stderr, od); fatal(" must be a class or enum\n"); } if (mod != gmd->module && arg0->atype == enum_type) { fatalStart(); fprintf(stderr, "%s:%d: Argument 1 of ", od->sloc.name, od->sloc.linenr); 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->ns_scope = gmd->ns_scope; pmd->next = pcd->members; pcd->members = pmd; } /* Add the proxy overload. */ pod = sipMalloc(sizeof (overDef)); *pod = *od; pod->no_typehint = TRUE; 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; if (ed != NULL) { ifaceFileDef *enum_iff = getIfaceFileForEnum(ed); /* The slot code is generated at the module level. */ if (enum_iff != NULL) appendToIfaceFileList(&mod->used, enum_iff); setIsUsedName(ed->pyname); } /* 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 inplace numeric operators and * comparison operators. */ if (isInplaceNumberSlot(md) || isRichCompareSlot(md)) { /* Remember if the argument was a pointer. */ if (arg0->nrderefs > 0) setDontDerefSelf(od); *arg0 = *arg1; od->pysig.nrArgs = 1; } /* Remove the only argument of unary operators. */ if (isZeroArgSlot(md)) od->pysig.nrArgs = 0; } } /* * 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; } /* * 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) { /* 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; mroDef **tailp = &cd->mro; /* 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)) { fatalStart(); fprintf(stderr, "Recursive class hierarchy detected: "); fatalScopedName(classFQCName(cd)); fprintf(stderr, " 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 (generatingCodeForModule(pt, cd->iff->module)) mro->cd->iff->first_alt->needed = TRUE; 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 needs a shadow then this one should have * one as well. */ if (needsShadow(mro->cd)) setNeedsShadow(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) appendToIfaceFileList(&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 non-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) if (td->ecd == NULL || !isTemplateClass(td->ecd)) resolveType(pt, td->module, td->ecd, &td->type, FALSE); } /* * Transform the data types for mapped types based on a template. */ static void transformMappedTypes(sipSpec *pt, int strict, 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, strict, 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. If there is %MethodCode then assume that it will * handle any potential conflicts. */ if (ct->methodcode == NULL) { for (prev = cd->ctors; prev != ct; prev = prev->next) { if (prev->methodcode != NULL) continue; 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; resolveType(pt, cd->iff->module, cd, &al->arg, FALSE); 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 = ©ct->pysig; if (isDeprecatedClass(cd)) setIsDeprecatedCtor(copyct); if (!isAbstractClass(cd)) setCanCreate(cd); /* 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, int strict, 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, od); /* * Now check that the Python signature doesn't conflict with an earlier * one. If there is %MethodCode then assume that it will handle any * potential conflicts. */ if (od->methodcode == NULL && strict) { for (prev = overs; prev != od; prev = prev->next) { if (prev->common != od->common) continue; if (prev->methodcode != NULL) 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; fatalStart(); fprintf(stderr, "%s:%d: ", od->sloc.name, od->sloc.linenr); 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); fprintf(stderr, "::"); } fatal("%s() has overloaded functions with the same Python signature\n", od->common->pyname->text); } } } if (c_scope != NULL) { if (isDeprecatedClass(c_scope)) setIsDeprecated(od); if (isAbstract(od)) setIsAbstractClass(c_scope); } } } /* * 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 Python member functions for a class. */ static void getVisiblePyMembers(sipSpec *pt, classDef *cd) { mroDef *mro; cd->visible = NULL; for (mro = cd->mro; mro != NULL; mro = mro->next) { memberDef *md; classDef *mro_cd; if (isDuplicateSuper(mro)) continue; mro_cd = mro->cd; for (md = mro_cd->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 = mro_cd; vl->next = cd->visible; cd->visible = vl; for (od = mro_cd->overs; od != NULL; od = od->next) if (od->common == md) { int need_types = FALSE; /* * If the visible overload is abstract then it hasn't * had a concrete implementation so this class must * also be abstract. */ if (isAbstract(od)) setIsAbstractClass(cd); if (generatingCodeForModule(pt, cd->iff->module) && (cd == mro_cd || (isProtected(od) && hasShadow(cd)))) { need_types = TRUE; setIsUsedName(md->pyname); /* Make sure we have any API name. */ if (od->api_range != NULL) setIsUsedName(od->api_range->api_name); } ifaceFilesAreUsedByOverload(&cd->iff->used, od, need_types); } } } } } /* * Get all the virtuals for a particular class. */ static void getVirtuals(sipSpec *pt, classDef *cd) { classList *cl; overDef *od; /* * Copy the collected virtuals of each super-class updating from what we * find in this class. */ for (cl = cd->supers; cl != NULL; cl = cl->next) { virtOverDef *s_vod; for (s_vod = cl->cd->vmembers; s_vod != NULL; s_vod = s_vod->next) { int implicit = TRUE; for (od = cd->overs; od != NULL; od = od->next) { if (strcmp(s_vod->od->cppname, od->cppname) != 0) continue; implicit = FALSE; if (isFinal(od)) break; /* See if it re-implements rather than hides. */ if (sameCppOverload(s_vod->od, od)) { // What if is is private? setIsVirtual(od); setIsVirtualReimp(od); /* * Use the base implementation's virtual handler code if * there is any. We cannot just use it's virtual handler * because this re-implementation may have different * annotations which means the complete handler would be * different. In practice there is no reason why it * would be different (and maybe this should be detected as * an error) but if they are the same then the same handler * will eventually be chosen. */ if (od->virtcode == NULL) od->virtcode = s_vod->od->virtcode; /* * Use the base implementation's virtual error handler if * one isn't explicitly specified. */ if (od->virt_error_handler == NULL) od->virt_error_handler = s_vod->od->virt_error_handler; addVirtual(pt, od, cd); } } /* Add it if it wasn't explcitly mentioned in the class. */ if (implicit) addVirtual(pt, s_vod->od, cd); } } /* Handle any new virtuals. */ for (od = cd->overs; od != NULL; od = od->next) if (isVirtual(od) && !isVirtualReimp(od) && !isFinal(od)) addVirtual(pt, od, cd); } /* * Add an overload to the list of virtuals for a class. */ static void addVirtual(sipSpec *pt, overDef *od, classDef *cd) { virtHandlerDef *vhd; virtOverDef *vod; /* * If this class is defined in the main module then make sure the virtuals * have a handler. */ if (generatingCodeForModule(pt, cd->iff->module)) { vhd = getVirtualHandler(pt, od, cd); /* Make sure we get the name. */ setIsUsedName(od->common->pyname); /* * Make sure we have the interface files and type definitions for the * virtual handler. */ ifaceFilesAreUsedByOverload(&pt->module->used, od, TRUE); } else { vhd = NULL; } /* Add it to the class. */ vod = sipMalloc(sizeof (virtOverDef)); vod->od = od; vod->virthandler = vhd; vod->next = cd->vmembers; cd->vmembers = vod; } /* * Get the virtual error handler for a function. */ static virtErrorHandler *getVirtErrorHandler(sipSpec *pt, overDef *od, classDef *cd) { const char *name; virtErrorHandler *veh; moduleDef *mod = cd->iff->module; /* Handle the trivial case. */ if (noErrorHandler(od)) return NULL; /* Check the function itself. */ if ((name = od->virt_error_handler) == NULL) { mroDef *mro; /* Check the class hierarchy. */ for (mro = cd->mro; mro != NULL; mro = mro->next) if ((name = mro->cd->virt_error_handler) != NULL) break; if (name == NULL) { /* Check the class's module. */ if ((name = mod->virt_error_handler) == NULL) { moduleListDef *mld; /* Check the module hierarchy. */ for (mld = mod->allimports; mld != NULL; mld = mld->next) if ((name = mld->module->virt_error_handler) != NULL) break; } } } if (name == NULL) return NULL; /* Find the handler with the name. */ for (veh = pt->errorhandlers; veh != NULL; veh = veh->next) if (strcmp(veh->name, name) == 0) break; if (veh == NULL) fatal("Unknown virtual error handler \"%s\"\n", name); /* Assign it an index if we need to import the handler. */ if (mod != veh->mod && veh->index < 0) veh->index = veh->mod->nrvirterrorhandlers++; return veh; } /* * Get the virtual handler for an overload. */ static virtHandlerDef *getVirtualHandler(sipSpec *pt, overDef *od, classDef *cd) { virtHandlerDef *vhd; /* See if there is an existing handler that is suitable. */ for (vhd = pt->virthandlers; vhd != NULL; vhd = vhd->next) if (checkVirtualHandler(od, vhd)) return vhd; /* Create a new one. */ vhd = sipMalloc(sizeof (virtHandlerDef)); vhd->virthandlernr = pt->nrvirthandlers++; if (isFactory(od) || isResultTransferredBack(od)) setIsTransferVH(vhd); if (abortOnException(od)) setAbortOnExceptionVH(vhd); vhd->pysig = &od->pysig; vhd->cppsig = od->cppsig; vhd->virtcode = od->virtcode; vhd->veh = getVirtErrorHandler(pt, od, cd); vhd->next = pt->virthandlers; pt->virthandlers = vhd; return vhd; } /* * See if a virtual handler is appropriate for an overload. */ static int checkVirtualHandler(overDef *od, virtHandlerDef *vhd) { int a; if (od->virtcode != vhd->virtcode) return FALSE; /* * If the overload has an explicit error handler then it must be the same * as the candidate. */ if (od->virt_error_handler != NULL) { if (vhd->veh == NULL || strcmp(od->virt_error_handler, vhd->veh->name) != 0) return FALSE; } if ((isFactory(od) || isResultTransferredBack(od)) && !isTransferVH(vhd)) return FALSE; if (!abortOnException(od) != !abortOnExceptionVH(vhd)) return FALSE; if (!sameArgType(&od->pysig.result, &vhd->pysig->result, TRUE)) return FALSE; if (isAllowNone(&od->pysig.result) != isAllowNone(&vhd->pysig->result)) return FALSE; if (isDisallowNone(&od->pysig.result) != isDisallowNone(&vhd->pysig->result)) return FALSE; if (!sameSignature(&od->pysig, vhd->pysig, TRUE)) return FALSE; /* Take into account the argument directions in the Python signatures. */ for (a = 0; a < od->pysig.nrArgs; ++a) { int dir1 = (od->pysig.args[a].argflags & (ARG_IN | ARG_OUT)); int dir2 = (vhd->pysig->args[a].argflags & (ARG_IN | ARG_OUT)); if (dir1 != dir2) return FALSE; } if (&od->pysig == od->cppsig && vhd->pysig == vhd->cppsig) return TRUE; if (!sameArgType(&od->cppsig->result, &vhd->cppsig->result, TRUE)) return FALSE; return sameSignature(od->cppsig, vhd->cppsig, TRUE); } /* * 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) resolveType(pt, mt->iff->module, NULL, ad, TRUE); } /* Make sure that the signature result won't cause problems. */ sd->result.atype = no_type; ifaceFilesAreUsedBySignature(&mt->iff->used, sd, FALSE); } /* * Resolve the types of a ctor. */ static void resolveCtorTypes(sipSpec *pt,classDef *scope,ctorDef *ct) { int a; /* Handle any exceptions. */ setNeededExceptions(pt, scope->iff->module, ct->exceptions); /* Handle any C++ signature. */ if (ct->cppsig != NULL && ct->cppsig != &ct->pysig) for (a = 0; a < ct -> cppsig -> nrArgs; ++a) resolveType(pt, scope->iff->module, scope, &ct->cppsig->args[a], TRUE); /* Handle the Python signature. */ for (a = 0; a < ct -> pysig.nrArgs; ++a) { argDef *ad = &ct -> pysig.args[a]; resolveType(pt, scope->iff->module, scope, ad, FALSE); if (!supportedType(scope,NULL,ad,FALSE)) { fatalScopedName(classFQCName(scope)); fatal(" ctor argument %d has an unsupported type for a Python signature - provide a valid type, %%MethodCode and a C++ signature\n", a + 1); } ifaceFileIsUsed(&scope->iff->used, ad, FALSE); scopeDefaultValue(pt, scope, ad); } } /* * Resolve the types of a function. */ static void resolveFuncTypes(sipSpec *pt, moduleDef *mod, classDef *c_scope, overDef *od) { argDef *res; /* Handle any exceptions. */ setNeededExceptions(pt, mod, od->exceptions); /* Handle any C++ signature. */ if (od->cppsig != &od->pysig) { int a; argDef *res = &od->cppsig->result; resolveType(pt, mod, c_scope, res, TRUE); if ((res->atype != void_type || res->nrderefs != 0) && isVirtual(od) && !supportedType(c_scope, od, &od->cppsig->result, FALSE) && od->virtcode == NULL) { fatalStart(); fprintf(stderr, "%s:%d: ", od->sloc.name, od->sloc.linenr); if (c_scope != NULL) { fatalScopedName(classFQCName(c_scope)); fprintf(stderr, "::"); } fatal("%s() unsupported virtual function return type - provide %%VirtualCatcherCode\n", od->cppname); } for (a = 0; a < od->cppsig->nrArgs; ++a) resolveType(pt, mod, c_scope, &od->cppsig->args[a], TRUE); } /* 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:%d: %s slots must return SIP_SSIZE_T\n", od->sloc.name, od->sloc.linenr, 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:%d: %s slots must return int\n", od->sloc.name, od->sloc.linenr, 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:%d: %s slots must return void\n", od->sloc.name, od->sloc.linenr, 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:%d: %s slots must return long\n", od->sloc.name, od->sloc.linenr, 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) { fatalStart(); fprintf(stderr, "%s:%d: ", od->sloc.name, od->sloc.linenr); if (scope != NULL) { fatalScopedName(classFQCName(scope)); fprintf(stderr, "::"); } fatal("%s() signals must return void\n", od->cppname); } resolveType(pt, mod, scope, res, FALSE); /* Results must be simple. */ if (!supportedType(scope, od, res, FALSE)) { int need_meth; need_meth = (od->cppsig == &od->pysig || od->methodcode == NULL); if (need_meth) { fatalStart(); fprintf(stderr, "%s:%d: ", od->sloc.name, od->sloc.linenr); if (scope != NULL) { fatalScopedName(classFQCName(scope)); fprintf(stderr, "::"); } 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]; resolveType(pt, mod, scope, ad, FALSE); 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)) { fatalStart(); fprintf(stderr, "%s:%d: ", od->sloc.name, od->sloc.linenr); if (scope != NULL) { fatalScopedName(classFQCName(scope)); fprintf(stderr, "::"); } fatal("%s() argument %d has an unsupported type for a Python signature\n", od->cppname, a + 1); } } else if (!supportedType(scope, od, ad, TRUE)) { fatalStart(); if (od->sloc.name != NULL) fprintf(stderr, "%s:%d: ", od->sloc.name, od->sloc.linenr); if (scope != NULL) { fatalScopedName(classFQCName(scope)); fprintf(stderr, "::"); } if (isVirtual(od)) fatal("%s() argument %d has an unsupported type for a Python signature - provide a valid type, %%MethodCode, %%VirtualCatcherCode and a C++ signature\n", od->cppname, a + 1); fatal("%s() argument %d has an unsupported type for a Python signature - provide a valid type, %%MethodCode and a C++ signature\n", od->cppname, a + 1); } 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; resolveType(pt, vd->module, vd->ecd, vtype, FALSE); 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 byte_type: case sbyte_type: case ubyte_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: case pybuffer_type: case capsule_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; /* Suppress a compiler warning. */ default: ; } if (bad && (vd->getcode == NULL || (!noSetter(vd) && vd->setcode == NULL))) { fatalScopedName(vd->fqcname); fatal(" has an unsupported type - provide %%GetCode"); if (!noSetter(vd)) fatal(" and %%SetCode"); fatal("\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, FALSE); else ifaceFileIsUsed(&vd->module->used, vtype, FALSE); /* Scoped variables need a handler unless they have %AccessCode. */ if (pyScope(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 byte_type: case sbyte_type: case ubyte_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: case pybuffer_type: case capsule_type: if (isReference(ad)) { if (isConstArg(ad)) { ensureInput(cd, od, ad); return TRUE; } 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; /* Suppress a compiler warning. */ default: ; } /* 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)) { fatalStart(); if (cd != NULL) { fatalScopedName(classFQCName(cd)); fprintf(stderr, "::"); } if (od != NULL) fprintf(stderr, "%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) { fatalStart(); while (snd != NULL) { fprintf(stderr, "%s", snd->name); snd = snd -> next; if (snd != NULL) fprintf(stderr, "::"); } } /* * Compare two overloads and return TRUE if they are the same. */ static int sameCppOverload(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->cppsig, od2->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) == byte_type || (t) == sbyte_type || (t) == ubyte_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) == byte_type || (t) == sbyte_type || (t) == ubyte_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(a2->u.cd->iff->fqcname, a1->u.snd) == 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(a2->u.mtd->iff->fqcname, a1->u.snd) == 0; if (a1->atype == enum_type && a2->atype == defined_type) return compareScopedNames(a1->u.ed->fqcname, a2->u.snd) == 0; if (a1->atype == defined_type && a2->atype == enum_type) return compareScopedNames(a2->u.ed->fqcname, a1->u.snd) == 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) { argDef *td1ad = &td1->types.args[a]; argDef *td2ad = &td2->types.args[a]; if (td1ad->nrderefs != td2ad->nrderefs) return FALSE; if (!sameBaseType(td1ad, td2ad)) 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; /* Suppress a compiler warning. */ default: ; } /* 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) { /* Strip the global scope if the target doesn't specify it. */ if (snd2->name[0] != '\0') snd1 = removeGlobalScope(snd1); 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; } /* * Resolve a type if possible. */ static void resolveType(sipSpec *pt, moduleDef *mod, classDef *c_scope, argDef *type, int allow_defined) { /* Loop until we've got to a base type. */ while (type->atype == defined_type) { scopedNameDef *snd = type->u.snd; type->atype = no_type; /* * Search the local scopes unless what we are looking for has an * explicit global scope. */ if (snd->name[0] != '\0') { classDef *scope; for (scope = c_scope; scope != NULL; scope = scope->ecd) { if (scope->iff->type == class_iface) searchClassScope(pt, scope, snd, type); else searchScope(pt, scope, snd, type); if (type->atype != no_type) break; } if (type->atype != no_type) break; } nameLookup(pt, mod, snd, type); if (type->atype != no_type) break; if (allow_defined) { type->atype = defined_type; return; } 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) resolveType(pt, mod, c_scope, &type->u.sa->args[sa], FALSE); } /* 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(mtt->mt->type.u.td->fqname, 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 we are in the main module then mark any generated types as being * needed. */ if (generatingCodeForModule(pt, mod)) setNeededType(type); } /* * Specify that a generated type is needed. */ static void setNeededType(argDef *ad) { switch (ad->atype) { case class_type: ad->u.cd->iff->first_alt->needed = TRUE; break; case mapped_type: ad->u.mtd->real->iff->first_alt->needed = TRUE; break; case enum_type: setNeedsEnum(ad->u.ed->first_alt); break; default: ; } } /* * Specify that a set of thrown exceptions are needed. */ static void setNeededExceptions(sipSpec *pt, moduleDef *mod, throwArgs *exceptions) { if (generatingCodeForModule(pt, mod) && exceptions != NULL) { int i; for (i = 0; i < exceptions->nrArgs; ++i) setNeedsException(exceptions->args[i]); } } /* * Specify that an exception is needed. */ static void setNeedsException(exceptionDef *xd) { if (xd->cd != NULL) xd->cd->iff->first_alt->needed = TRUE; else xd->needed = TRUE; } /* * 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->mtflags = mtt->mt->mtflags; if (mtt->mt->doctype != NULL) mtd->doctype = templateString(mtt->mt->doctype, type_names, type_values); if (mtt->mt->typehint_in != NULL) mtd->typehint_in = newTypeHint( templateString(mtt->mt->typehint_in->raw_hint, type_names, type_values)); if (mtt->mt->typehint_out != NULL) mtd->typehint_out = newTypeHint( templateString(mtt->mt->typehint_out->raw_hint, type_names, type_values)); mtd->typehint_value = mtt->mt->typehint_value; appendCodeBlockList(&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); mtd = copyTemplateType(mtd, type); return mtd; } /* * Return a string based on an original with names replaced by corresponding * values. */ char *templateString(const char *src, scopedNameDef *names, scopedNameDef *values) { char *dst = sipStrdup(src); while (names != NULL && values != NULL) { char *cp, *vname = values->name; int vname_on_heap = FALSE; size_t name_len, value_len; /* Skip over any leading const. */ if (strstr(vname, "const ") == vname) vname += 6; 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; vname_on_heap = TRUE; --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_on_heap) free(vname); names = names->next; values = values->next; } return dst; } /* * Search for a name in a class scope and return the corresponding type. */ static void searchClassScope(sipSpec *pt, classDef *c_scope, scopedNameDef *snd, argDef *ad) { mroDef *mro; for (mro = c_scope->mro; mro != NULL; mro = mro->next) { if (isDuplicateSuper(mro)) continue; searchScope(pt, mro->cd, snd, ad); if (ad->atype != no_type) break; } } /* * Search for a name in a scope and return the corresponding type. */ static void searchScope(sipSpec *pt, classDef *scope, scopedNameDef *snd, argDef *ad) { scopedNameDef *tmpsnd; /* Append the name to the scope and see if it exists. */ tmpsnd = copyScopedName(classFQCName(scope)); appendScopedName(&tmpsnd, copyScopedName(snd)); nameLookup(pt, scope->iff->module, tmpsnd, ad); freeScopedName(tmpsnd); } /* * Look up a name and return the corresponding type. */ static void nameLookup(sipSpec *pt, moduleDef *context, scopedNameDef *snd, argDef *ad) { searchMappedTypes(pt, context, snd, ad); if (ad->atype != no_type) return; searchTypedefs(pt, snd, ad); if (ad->atype != no_type) return; searchEnums(pt, snd, ad); if (ad->atype != no_type) return; searchClasses(pt, context, snd, ad); } /* * 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; } else { /* Avoid a compiler warning. */ oname = NULL; } for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next) if (sameBaseType(&mtd->type, ad)) { /* * If we are 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; } mtd = copyTemplateType(mtd, ad); /* Copy the type. */ ad->atype = mapped_type; ad->u.mtd = mtd; /* * Copy the type hints if nothing was specified for this particular * context. */ if (ad->typehint_in == NULL) ad->typehint_in = mtd->typehint_in; if (ad->typehint_out == NULL) ad->typehint_out = mtd->typehint_out; if (ad->typehint_value == NULL) ad->typehint_value = mtd->typehint_value; return; } /* Restore because we didn't find anything. */ if (snd != NULL) { ad->u.snd = oname; ad->atype = no_type; } } /* * If a mapped type is based on a template then create a copy that keeps the * original types of the template arguments. */ static mappedTypeDef *copyTemplateType(mappedTypeDef *mtd, argDef *ad) { int a; signatureDef *src, *dst; mappedTypeDef *mtd_copy; /* There is no need to do anything for non-template types. */ if (mtd->type.atype != template_type) return mtd; /* Retain the original types if there are any. */ mtd_copy = mtd; src = &ad->u.td->types; dst = NULL; for (a = 0; a < src->nrArgs; ++a) { typedefDef *tdd = src->args[a].original_type; if (tdd != NULL) { /* * Create an appropriately deep copy now that we know it is needed * and if it hasn't already been done. */ if (dst == NULL) { templateDef *td_copy; mtd_copy = sipMalloc(sizeof (mappedTypeDef)); *mtd_copy = *mtd; td_copy = sipMalloc(sizeof (templateDef)); *td_copy = *mtd->type.u.td; mtd_copy->type.u.td = td_copy; dst = &td_copy->types; } dst->args[a].original_type = tdd; } } return mtd_copy; } /* * 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) { int i; /* Copy the type. */ ad->atype = td->type.atype; ad->argflags |= td->type.argflags; ad->doctype = td->type.doctype; ad->typehint_in = td->type.typehint_in; ad->typehint_out = td->type.typehint_out; ad->typehint_value = td->type.typehint_value; ad->u = td->type.u; for (i = 0; i < td->type.nrderefs; ++i) { if (ad->nrderefs >= MAX_NR_DEREFS - 1) fatal("Internal error - increase the value of MAX_NR_DEREFS\n"); ad->derefs[ad->nrderefs++] = td->type.derefs[i]; } 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; /* * Copy the type hints if nothing was specified for this particular * context. */ if (ad->typehint_in == NULL) ad->typehint_in = cd->typehint_in; if (ad->typehint_out == NULL) ad->typehint_out = cd->typehint_out; if (ad->typehint_value == NULL) ad->typehint_value = cd->typehint_value; 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 need_types) { int a; ifaceFileIsUsed(used, &sd->result, need_types); for (a = 0; a < sd->nrArgs; ++a) ifaceFileIsUsed(used, &sd->args[a], need_types); } /* * Make sure all interface files for a function are used. */ static void ifaceFilesAreUsedByOverload(ifaceFileList **used, overDef *od, int need_types) { throwArgs *ta; ifaceFilesAreUsedBySignature(used, &od->pysig, need_types); if (od->cppsig != &od->pysig) ifaceFilesAreUsedBySignature(used, od->cppsig, need_types); if ((ta = od->exceptions) != NULL) { int a; for (a = 0; a < ta->nrArgs; ++a) { exceptionDef *xd = ta->args[a]; appendToIfaceFileList(used, xd->iff); if (need_types) setNeedsException(xd); } } } /* * 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, int need_types) { ifaceFileDef *iff; if ((iff = getIfaceFile(ad)) != NULL) { appendToIfaceFileList(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) appendToIfaceFileList(used, iffl->iff); } } if (need_types) setNeededType(ad); } /* * Return the interface file for an enum, or NULL if it doesn't have one. */ static ifaceFileDef *getIfaceFileForEnum(enumDef *ed) { if (ed->fqcname != NULL) { if (ed->ecd != NULL) return ed->ecd->iff; if (ed->emtd != NULL) return ed->emtd->iff; } return NULL; } /* * 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: iff = getIfaceFileForEnum(ad->u.ed); break; default: iff = NULL; } return iff; } /* * Create the sorted array of numbered types for a module. For the main module * this will be every type defined in the module. For other modules this will * be every type needed by the main 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->nr_needed_types = 0; for (cd = pt->classes; cd != NULL; cd = cd->next) { if (cd->iff->module != mod) continue; if (cd->iff->first_alt != cd->iff) continue; if (generatingCodeForModule(pt, mod) || cd->iff->needed) if (!isHiddenNamespace(cd)) mod->nr_needed_types++; } for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next) { if (mtd->iff->module != mod) continue; if (mtd->iff->first_alt != mtd->iff) continue; if (generatingCodeForModule(pt, mod) || mtd->iff->needed) mod->nr_needed_types++; } 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; if (generatingCodeForModule(pt, mod) || needsEnum(ed)) mod->nr_needed_types++; } if (mod->nr_needed_types == 0) return; /* Allocate and populate the table. */ ad = mod->needed_types = sipCalloc(mod->nr_needed_types, 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; if (generatingCodeForModule(pt, mod) || cd->iff->needed) if (!isHiddenNamespace(cd)) { 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; if (generatingCodeForModule(pt, mod) || mtd->iff->needed) { 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; if (generatingCodeForModule(pt, mod) || needsEnum(ed)) { ad->atype = enum_type; ad->u.ed = ed; ad->name = ed->cname; ++ad; } } /* Sort the table and assign type numbers. */ qsort(mod->needed_types, mod->nr_needed_types, sizeof (argDef), compareTypes); for (ad = mod->needed_types, i = 0; i < mod->nr_needed_types; ++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) { if (pt->qobject_cd != NULL) fatal("QObject has been defined more than once\n"); pt->qobject_cd = ad->u.cd; } break; case mapped_type: ad->u.mtd->iff->ifacenr = i; break; case enum_type: ad->u.ed->enumnr = i; break; /* Suppress a compiler warning. */ default: ; } } } /* * The qsort helper to compare two generated C/C++ type names. */ static int compareTypes(const void *t1, const void *t2) { return strcmp(((argDef *)t1)->name->text, ((argDef *)t2)->name->text); } /* * Return the fully qualified C/C++ name for a generated type. */ scopedNameDef *getFQCNameOfType(argDef *ad) { scopedNameDef *snd; switch (ad->atype) { case class_type: snd = classFQCName(ad->u.cd); break; case mapped_type: snd = ad->u.mtd->iff->fqcname; break; case enum_type: snd = ad->u.ed->fqcname; break; default: /* Suppress a compiler warning. */ snd = NULL; } return snd; } /* * 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); } /* * Check that any properties are valid. */ static void checkProperties(classDef *cd) { propertyDef *pd; for (pd = cd->properties; pd != NULL; pd = pd->next) { if (findMethod(cd, pd->get) == NULL) fatal("Property %s.%s has no get method %s()\n", cd->pyname->text, pd->name->text, pd->get); if (pd->set != NULL && findMethod(cd, pd->set) == NULL) fatal("Property %s.%s has no set method %s()\n", cd->pyname->text, pd->name->text, pd->set); } } /* * Return the method of a class with a given name. */ memberDef *findMethod(classDef *cd, const char *name) { memberDef *md; for (md = cd->members; md != NULL; md = md->next) if (strcmp(md->pyname->text, name) == 0) break; return md; } sip-4.19.7/sipgen/type_hints.c0000644000076500000240000014177013231604406016316 0ustar philstaff00000000000000/* * The PEP 484 type hints generator for SIP. * * Copyright (c) 2017 Riverbank Computing Limited * * 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 #include #include "sip.h" /* Return a string referring to an object of any type. */ #define anyObject(pep484) ((pep484) ? "typing.Any" : "object") static void pyiCompositeModule(sipSpec *pt, moduleDef *comp_mod, FILE *fp); static void pyiModule(sipSpec *pt, moduleDef *mod, FILE *fp); static void pyiTypeHintCode(codeBlockList *thc, int indent, FILE *fp); static void pyiEnums(sipSpec *pt, moduleDef *mod, ifaceFileDef *scope, ifaceFileList *defined, int indent, FILE *fp); static void pyiVars(sipSpec *pt, moduleDef *mod, classDef *scope, ifaceFileList *defined, int indent, FILE *fp); static void pyiClass(sipSpec *pt, moduleDef *mod, classDef *cd, ifaceFileList **defined, int indent, FILE *fp); static void pyiMappedType(sipSpec *pt, moduleDef *mod, mappedTypeDef *mtd, ifaceFileList **defined, int indent, FILE *fp); static void pyiCtor(sipSpec *pt, moduleDef *mod, classDef *cd, ctorDef *ct, int overloaded, int sec, ifaceFileList *defined, int indent, FILE *fp); static void pyiCallable(sipSpec *pt, moduleDef *mod, memberDef *md, overDef *overloads, int is_method, ifaceFileList *defined, int indent, FILE *fp); static void pyiProperty(sipSpec *pt, moduleDef *mod, propertyDef *pd, int is_setter, memberDef *md, overDef *overloads, ifaceFileList *defined, int indent, FILE *fp); static void pyiOverload(sipSpec *pt, moduleDef *mod, overDef *od, int overloaded, int is_method, int sec, ifaceFileList *defined, int indent, int pep484, FILE *fp); static void pyiPythonSignature(sipSpec *pt, moduleDef *mod, signatureDef *sd, int need_self, int sec, ifaceFileList *defined, KwArgs kwargs, int pep484, FILE *fp); static int pyiArgument(sipSpec *pt, moduleDef *mod, argDef *ad, int arg_nr, int out, int need_comma, int sec, int names, int defaults, ifaceFileList *defined, KwArgs kwargs, int pep484, FILE *fp); static void pyiType(sipSpec *pt, moduleDef *mod, argDef *ad, int out, int sec, ifaceFileList *defined, int pep484, FILE *fp); static void pyiTypeHint(sipSpec *pt, typeHintDef *thd, moduleDef *mod, int out, ifaceFileList *defined, int pep484, FILE *fp); static void pyiTypeHintNode(typeHintNodeDef *node, moduleDef *mod, ifaceFileList *defined, int pep484, FILE *fp); static void prIndent(int indent, FILE *fp); static int separate(int first, int indent, FILE *fp); static void prClassRef(classDef *cd, moduleDef *mod, ifaceFileList *defined, int pep484, FILE *fp); static void prEnumRef(enumDef *ed, moduleDef *mod, ifaceFileList *defined, int pep484, FILE *fp); static void prScopedEnumName(FILE *fp, enumDef *ed); static int isDefined(ifaceFileDef *iff, classDef *cd, moduleDef *mod, ifaceFileList *defined); static int inIfaceFileList(ifaceFileDef *iff, ifaceFileList *defined); static void parseTypeHint(sipSpec *pt, typeHintDef *thd, int out); static int parseTypeHintNode(sipSpec *pt, int out, int top_level, char *start, char *end, typeHintNodeDef **thnp); static const char *typingModule(const char *name); static typeHintNodeDef *lookupType(sipSpec *pt, char *name, int out); static enumDef *lookupEnum(sipSpec *pt, const char *name, classDef *scope_cd, mappedTypeDef *scope_mtd); static mappedTypeDef *lookupMappedType(sipSpec *pt, const char *name); static classDef *lookupClass(sipSpec *pt, const char *name, classDef *scope_cd); static classDef *getClassImplementation(sipSpec *pt, classDef *cd); static mappedTypeDef *getMappedTypeImplementation(sipSpec *pt, mappedTypeDef *mtd); static void maybeAnyObject(const char *hint, int pep484, FILE *fp); static void strip_leading(char **startp, char *end); static void strip_trailing(char *start, char **endp); static typeHintNodeDef *flatten_unions(typeHintNodeDef *nodes); static typeHintNodeDef *copyTypeHintNode(sipSpec *pt, typeHintDef *thd, int out); /* * Generate the .pyi file. */ void generateTypeHints(sipSpec *pt, moduleDef *mod, const char *pyiFile) { FILE *fp; /* Generate the file. */ if ((fp = fopen(pyiFile, "w")) == NULL) fatal("Unable to create file \"%s\"\n", pyiFile); /* Write the header. */ fprintf(fp, "# The PEP 484 type hints stub file for the %s module.\n" "#\n" "# Generated by SIP %s\n" , mod->name , sipVersion); prCopying(fp, mod, "#"); fprintf(fp, "\n" "\n" ); if (isComposite(mod)) pyiCompositeModule(pt, mod, fp); else pyiModule(pt, mod, fp); fclose(fp); } /* * Generate the type hints for a composite module. */ static void pyiCompositeModule(sipSpec *pt, moduleDef *comp_mod, FILE *fp) { moduleDef *mod; for (mod = pt->modules; mod != NULL; mod = mod->next) if (mod->container == comp_mod) fprintf(fp, "from %s import *\n", mod->fullname->text); } /* * Generate the type hints for an ordinary module. */ static void pyiModule(sipSpec *pt, moduleDef *mod, FILE *fp) { char *cp; int first; memberDef *md; classDef *cd; mappedTypeDef *mtd; ifaceFileList *defined; moduleListDef *mld; /* * Generate the imports. Note that we assume the super-types are the * standard SIP ones. */ fprintf(fp, "import typing\n" "import sip\n" ); first = TRUE; for (mld = mod->imports; mld != NULL; mld = mld->next) { /* We lie about the indent because we only want one blank line. */ first = separate(first, 1, fp); if ((cp = strrchr(mld->module->fullname->text, '.')) == NULL) { fprintf(fp, "import %s\n", mld->module->name); } else { *cp = '\0'; fprintf(fp, "from %s import %s\n", mld->module->fullname->text, mld->module->name); *cp = '.'; } } /* * Generate any exported type hint code and any module-specific type hint * code. */ pyiTypeHintCode(pt->exptypehintcode, 0, fp); pyiTypeHintCode(mod->typehintcode, 0, fp); /* Generate the types - global enums must be first. */ pyiEnums(pt, mod, NULL, NULL, 0, fp); defined = NULL; for (cd = pt->classes; cd != NULL; cd = cd->next) { classDef *impl; if (cd->iff->module != mod) continue; if (isExternal(cd)) continue; impl = getClassImplementation(pt, cd); if (impl != NULL) { if (impl->no_typehint) continue; /* Only handle non-nested classes here. */ if (impl->ecd != NULL) continue; pyiClass(pt, mod, impl, &defined, 0, fp); } } for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next) { mappedTypeDef *impl; if (mtd->iff->module != mod) continue; impl = getMappedTypeImplementation(pt, mtd); if (impl != NULL && impl->pyname != NULL) pyiMappedType(pt, mod, impl, &defined, 0, fp); } pyiVars(pt, mod, NULL, defined, 0, fp); first = TRUE; for (md = mod->othfuncs; md != NULL; md = md->next) if (md->slot == no_slot) { first = separate(first, 0, fp); pyiCallable(pt, mod, md, mod->overs, FALSE, defined, 0, fp); } } /* * Generate handwritten type hint code. */ static void pyiTypeHintCode(codeBlockList *thc, int indent, FILE *fp) { while (thc != NULL) { int need_indent = TRUE; const char *cp; fprintf(fp, "\n"); for (cp = thc->block->frag; *cp != '\0'; ++cp) { if (need_indent) { need_indent = FALSE; prIndent(indent, fp); } fprintf(fp, "%c", *cp); if (*cp == '\n') need_indent = TRUE; } thc = thc->next; } } /* * Generate the type hints for a class. */ static void pyiClass(sipSpec *pt, moduleDef *mod, classDef *cd, ifaceFileList **defined, int indent, FILE *fp) { int first, no_body, nr_overloads; classDef *nested; ctorDef *ct; memberDef *md; propertyDef *pd; separate(TRUE, indent, fp); prIndent(indent, fp); fprintf(fp, "class %s(", cd->pyname->text); if (cd->supers != NULL) { classList *cl; for (cl = cd->supers; cl != NULL; cl = cl->next) { if (cl != cd->supers) fprintf(fp, ", "); prClassRef(cl->cd, mod, *defined, TRUE, fp); } } else if (cd->supertype != NULL) { fprintf(fp, "%s", cd->supertype->text); } else if (cd->iff->type == namespace_iface) { fprintf(fp, "sip.simplewrapper"); } else { fprintf(fp, "sip.wrapper"); } /* See if there is anything in the class body. */ nr_overloads = 0; for (ct = cd->ctors; ct != NULL; ct = ct->next) { if (isPrivateCtor(ct)) continue; if (ct->no_typehint) continue; if (!inDefaultAPI(pt, ct->api_range)) continue; ++nr_overloads; } no_body = (cd->typehintcode == NULL && nr_overloads == 0); if (no_body) { overDef *od; for (od = cd->overs; od != NULL; od = od->next) { if (isPrivate(od)) continue; if (od->no_typehint) continue; if (inDefaultAPI(pt, od->api_range)) { no_body = FALSE; break; } } } if (no_body) { enumDef *ed; for (ed = pt->enums; ed != NULL; ed = ed->next) { if (ed->no_typehint) continue; if (ed->ecd == cd) { no_body = FALSE; break; } } } if (no_body) { for (nested = pt->classes; nested != NULL; nested = nested->next) { if (nested->no_typehint) continue; if (nested->ecd == cd) { no_body = FALSE; break; } } } if (no_body) { varDef *vd; for (vd = pt->vars; vd != NULL; vd = vd->next) { if (vd->no_typehint) continue; if (vd->ecd == cd) { no_body = FALSE; break; } } } fprintf(fp, "):%s\n", (no_body ? " ..." : "")); ++indent; pyiTypeHintCode(cd->typehintcode, indent, fp); pyiEnums(pt, mod, cd->iff, *defined, indent, fp); /* Handle any nested classes. */ for (nested = pt->classes; nested != NULL; nested = nested->next) { classDef *impl = getClassImplementation(pt, nested); if (impl != NULL && impl->ecd == cd && !impl->no_typehint) pyiClass(pt, mod, impl, defined, indent, fp); } pyiVars(pt, mod, cd, *defined, indent, fp); first = TRUE; for (ct = cd->ctors; ct != NULL; ct = ct->next) { int implicit_overloads, overloaded; if (isPrivateCtor(ct)) continue; if (ct->no_typehint) continue; if (!inDefaultAPI(pt, ct->api_range)) continue; implicit_overloads = hasImplicitOverloads(&ct->pysig); overloaded = (implicit_overloads || nr_overloads > 1); first = separate(first, indent, fp); pyiCtor(pt, mod, NULL, ct, overloaded, FALSE, *defined, indent, fp); if (implicit_overloads) pyiCtor(pt, mod, NULL, ct, overloaded, TRUE, *defined, indent, fp); } first = TRUE; for (md = cd->members; md != NULL; md = md->next) { /* * Ignore slots which can return Py_NotImplemented as code may be * correctly handled elsewhere. We also have to include the sequence * slots because they can't be distinguished from the number slots of * the same name. */ if (isNumberSlot(md) || isInplaceNumberSlot(md) || isRichCompareSlot(md) || md->slot == concat_slot || md->slot == iconcat_slot || md->slot == repeat_slot || md->slot == irepeat_slot) continue; first = separate(first, indent, fp); pyiCallable(pt, mod, md, cd->overs, TRUE, *defined, indent, fp); } for (pd = cd->properties; pd != NULL; pd = pd->next) { first = separate(first, indent, fp); if (pd->get != NULL) { if ((md = findMethod(cd, pd->get)) != NULL) { pyiProperty(pt, mod, pd, FALSE, md, cd->overs, *defined, indent, fp); if (pd->set != NULL) { if ((md = findMethod(cd, pd->set)) != NULL) pyiProperty(pt, mod, pd, TRUE, md, cd->overs, *defined, indent, fp); } } } } /* * Keep track of what has been defined so that forward references are no * longer required. */ appendToIfaceFileList(defined, cd->iff); } /* * Generate the type hints for a mapped type. */ static void pyiMappedType(sipSpec *pt, moduleDef *mod, mappedTypeDef *mtd, ifaceFileList **defined, int indent, FILE *fp) { int first, no_body; memberDef *md; /* See if there is anything in the mapped type body. */ no_body = (mtd->members == NULL); if (no_body) { enumDef *ed; for (ed = pt->enums; ed != NULL; ed = ed->next) { if (ed->no_typehint) continue; if (ed->emtd == mtd) { no_body = FALSE; break; } } } if (!no_body) { separate(TRUE, indent, fp); prIndent(indent, fp); fprintf(fp, "class %s(sip.wrapper):\n", mtd->pyname->text); ++indent; pyiEnums(pt, mod, mtd->iff, *defined, indent, fp); first = TRUE; for (md = mtd->members; md != NULL; md = md->next) { first = separate(first, indent, fp); pyiCallable(pt, mod, md, mtd->overs, TRUE, *defined, indent, fp); } } /* * Keep track of what has been defined so that forward references are no * longer required. */ appendToIfaceFileList(defined, mtd->iff); } /* * Generate a ctor docstring. */ void dsCtor(sipSpec *pt, classDef *cd, ctorDef *ct, int sec, FILE *fp) { pyiCtor(pt, pt->module, cd, ct, FALSE, sec, NULL, 0, fp); } /* * Generate an ctor type hint. */ static void pyiCtor(sipSpec *pt, moduleDef *mod, classDef *cd, ctorDef *ct, int overloaded, int sec, ifaceFileList *defined, int indent, FILE *fp) { int a, need_comma; if (overloaded) { prIndent(indent, fp); fprintf(fp, "@typing.overload\n"); } prIndent(indent, fp); if (cd == NULL) { fprintf(fp, "def __init__(self"); need_comma = TRUE; } else { prScopedPythonName(fp, cd->ecd, cd->pyname->text); fprintf(fp, "("); need_comma = FALSE; } for (a = 0; a < ct->pysig.nrArgs; ++a) need_comma = pyiArgument(pt, mod, &ct->pysig.args[a], a, FALSE, need_comma, sec, TRUE, TRUE, defined, ct->kwargs, (cd == NULL), fp); fprintf(fp, (cd == NULL) ? ") -> None: ...\n" : ")"); } /* * Generate the APIs for all the enums in a scope. */ static void pyiEnums(sipSpec *pt, moduleDef *mod, ifaceFileDef *scope, ifaceFileList *defined, int indent, FILE *fp) { enumDef *ed; for (ed = pt->enums; ed != NULL; ed = ed->next) { enumMemberDef *emd; if (ed->module != mod) continue; if (ed->no_typehint) continue; if (scope != NULL) { if ((ed->ecd == NULL || ed->ecd->iff != scope) && (ed->emtd == NULL || ed->emtd->iff != scope)) continue; } else if (ed->ecd != NULL || ed->emtd != NULL) { continue; } separate(TRUE, indent, fp); if (ed->pyname != NULL) { prIndent(indent, fp); fprintf(fp, "class %s(int): ...\n", ed->pyname->text); } for (emd = ed->members; emd != NULL; emd = emd->next) { if (emd->no_typehint) continue; prIndent(indent, fp); fprintf(fp, "%s = ... # type: ", emd->pyname->text); if (ed->pyname != NULL) prEnumRef(ed, mod, defined, TRUE, fp); else fprintf(fp, "int"); fprintf(fp, "\n"); } } } /* * Generate the APIs for all the variables in a scope. */ static void pyiVars(sipSpec *pt, moduleDef *mod, classDef *scope, ifaceFileList *defined, int indent, FILE *fp) { int first = TRUE; varDef *vd; for (vd = pt->vars; vd != NULL; vd = vd->next) { if (vd->module != mod) continue; if (vd->ecd != scope) continue; if (vd->no_typehint) continue; first = separate(first, indent, fp); prIndent(indent, fp); fprintf(fp, "%s = ... # type: ", vd->pyname->text); pyiType(pt, mod, &vd->type, FALSE, FALSE, defined, TRUE, fp); fprintf(fp, "\n"); } } /* * Generate the type hints for a callable. */ static void pyiCallable(sipSpec *pt, moduleDef *mod, memberDef *md, overDef *overloads, int is_method, ifaceFileList *defined, int indent, FILE *fp) { int nr_overloads; overDef *od; /* Count the number of overloads. */ nr_overloads = 0; for (od = overloads; od != NULL; od = od->next) { if (isPrivate(od)) continue; if (od->common != md) continue; if (od->no_typehint) continue; if (!inDefaultAPI(pt, od->api_range)) continue; ++nr_overloads; } /* Handle each overload. */ for (od = overloads; od != NULL; od = od->next) { int implicit_overloads, overloaded; if (isPrivate(od)) continue; if (od->common != md) continue; if (od->no_typehint) continue; if (!inDefaultAPI(pt, od->api_range)) continue; implicit_overloads = hasImplicitOverloads(&od->pysig); overloaded = (implicit_overloads || nr_overloads > 1); pyiOverload(pt, mod, od, overloaded, is_method, FALSE, defined, indent, TRUE, fp); if (implicit_overloads) pyiOverload(pt, mod, od, overloaded, is_method, TRUE, defined, indent, TRUE, fp); } } /* * Generate the type hints for a property. */ static void pyiProperty(sipSpec *pt, moduleDef *mod, propertyDef *pd, int is_setter, memberDef *md, overDef *overloads, ifaceFileList *defined, int indent, FILE *fp) { overDef *od; /* Handle each overload. */ for (od = overloads; od != NULL; od = od->next) { if (isPrivate(od)) continue; if (od->common != md) continue; if (od->no_typehint) continue; prIndent(indent, fp); if (is_setter) fprintf(fp, "@%s.setter\n", pd->name->text); else fprintf(fp, "@property\n"); prIndent(indent, fp); fprintf(fp, "def %s", pd->name->text); pyiPythonSignature(pt, mod, &od->pysig, TRUE, FALSE, defined, od->kwargs, TRUE, fp); fprintf(fp, ": ...\n"); break; } } /* * Generate the docstring for a single API overload. */ void dsOverload(sipSpec *pt, overDef *od, int is_method, int sec, FILE *fp) { pyiOverload(pt, pt->module, od, FALSE, is_method, sec, NULL, 0, FALSE, fp); } /* * Generate the type hints for a single API overload. */ static void pyiOverload(sipSpec *pt, moduleDef *mod, overDef *od, int overloaded, int is_method, int sec, ifaceFileList *defined, int indent, int pep484, FILE *fp) { int need_self; if (overloaded) { prIndent(indent, fp); fprintf(fp, "@typing.overload\n"); } if (pep484 && is_method && isStatic(od)) { prIndent(indent, fp); fprintf(fp, "@staticmethod\n"); } prIndent(indent, fp); fprintf(fp, "%s%s", (pep484 ? "def " : ""), od->common->pyname->text); need_self = (is_method && !isStatic(od)); pyiPythonSignature(pt, mod, &od->pysig, need_self, sec, defined, od->kwargs, pep484, fp); if (pep484) fprintf(fp, ": ...\n"); } /* * Generate a Python argument. */ static int pyiArgument(sipSpec *pt, moduleDef *mod, argDef *ad, int arg_nr, int out, int need_comma, int sec, int names, int defaults, ifaceFileList *defined, KwArgs kwargs, int pep484, FILE *fp) { int optional, use_optional; if (isArraySize(ad)) return need_comma; if (sec && (ad->atype == slotcon_type || ad->atype == slotdis_type)) return need_comma; if (need_comma) fprintf(fp, ", "); optional = (defaults && ad->defval && !out); /* * We only show names for PEP 484 type hints and when they are part of the * API. */ if (names) names = (pep484 || kwargs == AllKwArgs || (kwargs == OptionalKwArgs && optional)); if (names && ad->atype != ellipsis_type) { if (ad->name != NULL) fprintf(fp, "%s%s: ", ad->name->text, (isPyKeyword(ad->name->text) ? "_" : "")); else fprintf(fp, "a%d: ", arg_nr); } use_optional = FALSE; if (optional && pep484) { /* Assume pointers can be None unless specified otherwise. */ if (isAllowNone(ad) || (!isDisallowNone(ad) && ad->nrderefs > 0)) { fprintf(fp, "typing.Optional["); use_optional = TRUE; } } pyiType(pt, mod, ad, out, sec, defined, pep484, fp); if (names && ad->atype == ellipsis_type) { if (ad->name != NULL) fprintf(fp, "%s%s", ad->name->text, (isPyKeyword(ad->name->text) ? "_" : "")); else fprintf(fp, "a%d", arg_nr); } if (optional) { if (use_optional) fprintf(fp, "]"); fprintf(fp, " = "); if (pep484) fprintf(fp, "..."); else prDefaultValue(ad, TRUE, fp); } return TRUE; } /* * Generate the default value of an argument. */ void prDefaultValue(argDef *ad, int in_str, FILE *fp) { /* Use any explicitly provided documentation. */ if (ad->typehint_value != NULL) { fprintf(fp, "%s", ad->typehint_value); return; } /* Translate some special cases. */ if (ad->defval->next == NULL && ad->defval->vtype == numeric_value) { if (ad->nrderefs > 0 && ad->defval->u.vnum == 0) { fprintf(fp, "None"); return; } if (ad->atype == bool_type || ad->atype == cbool_type) { fprintf(fp, ad->defval->u.vnum ? "True" : "False"); return; } } /* SIP v5 won't need this. */ prcode(fp, "%M"); generateExpression(ad->defval, in_str, fp); prcode(fp, "%M"); } /* * Generate the Python representation of a type. */ static void pyiType(sipSpec *pt, moduleDef *mod, argDef *ad, int out, int sec, ifaceFileList *defined, int pep484, FILE *fp) { const char *type_name; typeHintDef *thd; /* Use any explicit type hint unless the argument is constrained. */ thd = (out ? ad->typehint_out : (isConstrained(ad) ? NULL : ad->typehint_in)); if (thd != NULL) { pyiTypeHint(pt, thd, mod, out, defined, pep484, fp); return; } /* For classes and mapped types we need the default implementation. */ if (ad->atype == class_type || ad->atype == mapped_type) { classDef *cd = ad->u.cd; mappedTypeDef *mtd = ad->u.mtd; getDefaultImplementation(pt, ad->atype, &cd, &mtd); if (cd != NULL) { prClassRef(cd, mod, defined, pep484, fp); } else { /* * This should never happen as it should have been picked up when * generating code - but maybe we haven't been asked to generate * code. */ fprintf(fp, anyObject(pep484)); } return; } type_name = NULL; switch (ad->atype) { case enum_type: if (ad->u.ed->pyname != NULL) prEnumRef(ad->u.ed, mod, defined, pep484, fp); else type_name = "int"; break; case capsule_type: type_name = scopedNameTail(ad->u.cap); break; case struct_type: case void_type: type_name = "sip.voidptr"; break; case signal_type: type_name = "QT_SIGNAL"; break; case slot_type: type_name = "QT_SLOT_QT_SIGNAL"; break; case rxcon_type: case rxdis_type: if (sec) { type_name = (pep484 ? "typing.Callable[..., None]" : "Callable[..., None]"); } else { /* The class should always be found. */ if (pt->qobject_cd != NULL) prClassRef(pt->qobject_cd, mod, defined, pep484, fp); else type_name = anyObject(pep484); } break; case qobject_type: type_name = "QObject"; break; case ustring_type: /* Correct for Python v3. */ type_name = "bytes"; break; case string_type: case sstring_type: case wstring_type: case ascii_string_type: case latin1_string_type: case utf8_string_type: type_name = isArray(ad) ? "bytes" : "str"; break; case byte_type: case sbyte_type: case ubyte_type: 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: case ssize_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 = anyObject(pep484); break; case pytuple_type: type_name = (pep484 ? "typing.Tuple" : "Tuple"); break; case pylist_type: type_name = (pep484 ? "typing.List" : "List"); break; case pydict_type: type_name = (pep484 ? "typing.Dict" : "Dict"); break; case pycallable_type: type_name = (pep484 ? "typing.Callable[..., None]" : "Callable[..., None]"); break; case pyslice_type: type_name = "slice"; break; case pytype_type: type_name = "type"; break; case pybuffer_type: type_name = "sip.Buffer"; break; case ellipsis_type: type_name = "*"; break; case slotcon_type: case anyslot_type: type_name = "QT_SLOT"; break; default: type_name = anyObject(pep484); } if (type_name != NULL) fprintf(fp, "%s", type_name); } /* * Generate a scoped Python name. */ void prScopedPythonName(FILE *fp, classDef *scope, const char *pyname) { if (scope != NULL && !isHiddenNamespace(scope)) { prScopedPythonName(fp, scope->ecd, NULL); fprintf(fp, "%s.", scope->pyname->text); } if (pyname != NULL) fprintf(fp, "%s", pyname); } /* * Generate a Python signature. */ static void pyiPythonSignature(sipSpec *pt, moduleDef *mod, signatureDef *sd, int need_self, int sec, ifaceFileList *defined, KwArgs kwargs, int pep484, FILE *fp) { int void_return, need_comma, is_res, nr_out, a; if (need_self) { fprintf(fp, "(self"); need_comma = TRUE; } else { fprintf(fp, "("); need_comma = FALSE; } 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 = pyiArgument(pt, mod, ad, a, FALSE, need_comma, sec, TRUE, TRUE, defined, kwargs, pep484, fp); } fprintf(fp, ")"); /* An empty type hint specifies a void return. */ if (sd->result.typehint_out != NULL) void_return = (sd->result.typehint_out->raw_hint[0] == '\0'); else void_return = FALSE; is_res = !((sd->result.atype == void_type && sd->result.nrderefs == 0) || void_return); if (is_res || nr_out > 0) { fprintf(fp, " -> "); if ((is_res && nr_out > 0) || nr_out > 1) fprintf(fp, "%sTuple[", (pep484 ? "typing." : "")); if (is_res) need_comma = pyiArgument(pt, mod, &sd->result, -1, TRUE, FALSE, sec, FALSE, FALSE, defined, kwargs, pep484, 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 = pyiArgument(pt, mod, ad, -1, TRUE, need_comma, sec, FALSE, FALSE, defined, kwargs, pep484, fp); } if ((is_res && nr_out > 0) || nr_out > 1) fprintf(fp, "]"); } else if (pep484) { fprintf(fp, " -> None"); } } /* * Generate the required indentation. */ static void prIndent(int indent, FILE *fp) { while (indent--) fprintf(fp, " "); } /* * Generate a newline if not already done. */ static int separate(int first, int indent, FILE *fp) { if (first) fprintf(fp, (indent ? "\n" : "\n\n")); return FALSE; } /* * Generate a class reference, including its owning module if necessary and * handling forward references if necessary. */ static void prClassRef(classDef *cd, moduleDef *mod, ifaceFileList *defined, int pep484, FILE *fp) { if (pep484) { /* * We assume that an external class will be handled properly by some * handwritten type hint code. */ int is_defined = (isExternal(cd) || isDefined(cd->iff, cd->ecd, mod, defined)); if (!is_defined) fprintf(fp, "'"); if (cd->iff->module != mod) fprintf(fp, "%s.", cd->iff->module->name); prScopedPythonName(fp, cd->ecd, cd->pyname->text); if (!is_defined) fprintf(fp, "'"); } else { prScopedPythonName(fp, cd->ecd, cd->pyname->text); } } /* * Generate an enum reference, including its owning module if necessary and * handling forward references if necessary. */ static void prEnumRef(enumDef *ed, moduleDef *mod, ifaceFileList *defined, int pep484, FILE *fp) { if (pep484) { int is_defined; if (ed->ecd != NULL) { is_defined = isDefined(ed->ecd->iff, ed->ecd->ecd, mod, defined); } else if (ed->emtd != NULL) { is_defined = isDefined(ed->emtd->iff, NULL, mod, defined); } else { /* Global enums are defined early on. */ is_defined = TRUE; } if (!is_defined) fprintf(fp, "'"); if (ed->module != mod) fprintf(fp, "%s.", ed->module->name); prScopedEnumName(fp, ed); if (!is_defined) fprintf(fp, "'"); } else { prScopedEnumName(fp, ed); } } /* * Generate a scoped enum name. */ static void prScopedEnumName(FILE *fp, enumDef *ed) { if (ed->emtd != NULL) fprintf(fp, "%s.%s", ed->emtd->pyname->text, ed->pyname->text); else prScopedPythonName(fp, ed->ecd, ed->pyname->text); } /* * Check if a type has been defined. */ static int isDefined(ifaceFileDef *iff, classDef *scope, moduleDef *mod, ifaceFileList *defined) { /* A type in another module would have been imported. */ if (iff->module != mod) return TRUE; if (!inIfaceFileList(iff, defined)) return FALSE; /* Check all enclosing scopes have been defined as well. */ while (scope != NULL) { if (!inIfaceFileList(scope->iff, defined)) return FALSE; scope = scope->ecd; } return TRUE; } /* * Check if an interface file appears in a list of them. */ static int inIfaceFileList(ifaceFileDef *iff, ifaceFileList *defined) { while (defined != NULL) { if (defined->iff == iff) return TRUE; defined = defined->next; } return FALSE; } /* * See if a signature has implicit overloads. */ int hasImplicitOverloads(signatureDef *sd) { int a; for (a = 0; a < sd->nrArgs; ++a) { argDef *ad = &sd->args[a]; if (!isInArg(ad)) continue; if (ad->atype == rxcon_type || ad->atype == rxdis_type) return TRUE; } return FALSE; } /* * Create a new type hint for a raw string. */ typeHintDef *newTypeHint(char *raw_hint) { typeHintDef *thd = sipMalloc(sizeof (typeHintDef)); thd->status = needs_parsing; thd->raw_hint = raw_hint; return thd; } /* * Generate a type hint from a /TypeHint/ annotation. */ static void pyiTypeHint(sipSpec *pt, typeHintDef *thd, moduleDef *mod, int out, ifaceFileList *defined, int pep484, FILE *fp) { parseTypeHint(pt, thd, out); if (thd->root != NULL) pyiTypeHintNode(thd->root, mod, defined, pep484, fp); else maybeAnyObject(thd->raw_hint, pep484, fp); } /* * Generate a single node of a type hint. */ static void pyiTypeHintNode(typeHintNodeDef *node, moduleDef *mod, ifaceFileList *defined, int pep484, FILE *fp) { switch (node->type) { case typing_node: fprintf(fp, "%s%s", (pep484 ? "typing." : ""), node->u.name); if (node->children != NULL) { int need_comma = FALSE; typeHintNodeDef *thnd; fprintf(fp, "["); for (thnd = node->children; thnd != NULL; thnd = thnd->next) { if (need_comma) fprintf(fp, ", "); need_comma = TRUE; pyiTypeHintNode(thnd, mod, defined, pep484, fp); } fprintf(fp, "]"); } break; case class_node: prClassRef(node->u.cd, mod, defined, pep484, fp); break; case enum_node: prEnumRef(node->u.ed, mod, defined, pep484, fp); break; case brackets_node: fprintf(fp, "[]"); break; case other_node: maybeAnyObject(node->u.name, pep484, fp); break; } } /* * Parse a type hint and update its status accordingly. */ static void parseTypeHint(sipSpec *pt, typeHintDef *thd, int out) { if (thd->status == needs_parsing) { thd->status = being_parsed; parseTypeHintNode(pt, out, TRUE, thd->raw_hint, thd->raw_hint + strlen(thd->raw_hint), &thd->root); thd->status = parsed; } } /* * Recursively parse a type hint. Return FALSE if the parse failed. */ static int parseTypeHintNode(sipSpec *pt, int out, int top_level, char *start, char *end, typeHintNodeDef **thnp) { char *cp, *name_start, *name_end; int have_brackets = FALSE; typeHintNodeDef *node, *children = NULL; /* Assume there won't be a node. */ *thnp = NULL; /* Find the name and any opening and closing bracket. */ strip_leading(&start, end); name_start = start; strip_trailing(start, &end); name_end = end; for (cp = start; cp < end; ++cp) if (*cp == '[') { typeHintNodeDef **tail = &children; /* The last character must be a closing bracket. */ if (end[-1] != ']') return FALSE; /* Find the end of any name. */ name_end = cp; strip_trailing(name_start, &name_end); for (;;) { char *pp; int depth; /* Skip the opening bracket or comma. */ ++cp; /* Find the next comma, if any. */ depth = 0; for (pp = cp; pp < end; ++pp) if (*pp == '[') { ++depth; } else if (*pp == ']' && depth != 0) { --depth; } else if ((*pp == ',' || *pp == ']') && depth == 0) { typeHintNodeDef *child; /* Recursively parse this part. */ if (!parseTypeHintNode(pt, out, FALSE, cp, pp, &child)) return FALSE; if (child != NULL) { /* * Append the child to the list of children. There * might not be a child if we have detected a * recursive definition. */ *tail = child; tail = &child->next; } cp = pp; break; } if (pp == end) break; } have_brackets = TRUE; break; } /* We must have a name unless we have empty brackets. */ if (name_start == name_end) { if (top_level && have_brackets && children == NULL) return FALSE; /* Return the representation of empty brackets. */ node = sipMalloc(sizeof (typeHintNodeDef)); node->type = brackets_node; } else { char saved; const char *typing; /* Isolate the name. */ saved = *name_end; *name_end = '\0'; /* See if it is an object in the typing module. */ if ((typing = typingModule(name_start)) != NULL) { if (strcmp(typing, "Union") == 0) { /* * If there are no children assume it is because they have been * omitted. */ if (children == NULL) return TRUE; children = flatten_unions(children); } node = sipMalloc(sizeof (typeHintNodeDef)); node->type = typing_node; node->u.name = typing; node->children = children; } else { /* Search for the type. */ node = lookupType(pt, name_start, out); } *name_end = saved; /* Only objects from the typing module can have brackets. */ if (typing == NULL && have_brackets) return FALSE; } *thnp = node; return TRUE; } /* * Strip leading spaces from a string. */ static void strip_leading(char **startp, char *end) { char *start; start = *startp; while (start < end && start[0] == ' ') ++start; *startp = start; } /* * Strip trailing spaces from a string. */ static void strip_trailing(char *start, char **endp) { char *end; end = *endp; while (end > start && end[-1] == ' ') --end; *endp = end; } /* * Look up an object in the typing module. */ static const char *typingModule(const char *name) { static const char *typing[] = { "Any", "Callable", "Dict", "Iterable", "Iterator", "List", "Mapping", "NamedTuple", "Optional", "Sequence", "Set", "Tuple", "Union", NULL }; const char **np; for (np = typing; *np != NULL; ++np) if (strcmp(*np, name) == 0) return *np; return NULL; } /* * Flatten an unions in a list of nodes. */ static typeHintNodeDef *flatten_unions(typeHintNodeDef *nodes) { typeHintNodeDef *head, **tailp, *thnd; head = NULL; tailp = &head; for (thnd = nodes; thnd != NULL; thnd = thnd->next) { if (thnd->type == typing_node && strcmp(thnd->u.name, "Union") == 0) { typeHintNodeDef *child; for (child = thnd->children; child != NULL; child = child->next) { *tailp = child; tailp = &child->next; } } else { /* Move this one to the new list. */ *tailp = thnd; tailp = &thnd->next; } } *tailp = NULL; return head; } /* * Look up a qualified Python type and return the corresponding node (or NULL * if the type should be omitted because of a recursive definition). */ static typeHintNodeDef *lookupType(sipSpec *pt, char *name, int out) { char *sp, *ep; classDef *scope_cd; mappedTypeDef *scope_mtd; typeHintDef *thd; typeHintNodeDef *node; /* Start searching at the global level. */ scope_cd = NULL; scope_mtd = NULL; sp = name; ep = NULL; while (*sp != '\0') { enumDef *ed; /* Isolate the next part of the name. */ if ((ep = strchr(sp, '.')) != NULL) *ep = '\0'; /* See if it's an enum. */ if ((ed = lookupEnum(pt, sp, scope_cd, scope_mtd)) != NULL) { /* Make sure we have used the whole name. */ if (ep == NULL) { node = sipMalloc(sizeof (typeHintNodeDef)); node->type = enum_node; node->u.ed = ed; return node; } /* There is some left so the whole lookup has failed. */ break; } /* * If we have a mapped type scope then we must be looking for an enum, * which we have failed to find. */ if (scope_mtd != NULL) break; if (scope_cd == NULL) { mappedTypeDef *mtd; /* * We are looking at the global level, so see if it is a mapped * type. */ if ((mtd = lookupMappedType(pt, sp)) != NULL) { /* * If we have used the whole name then the lookup has * succeeded. */ if (ep == NULL) { thd = (out ? mtd->typehint_out : mtd->typehint_in); if (thd != NULL && thd->status != being_parsed) return copyTypeHintNode(pt, thd, out); /* * If we get here we have a recursively defined mapped type * so we simply omit it. */ return NULL; } /* Otherwise this is the scope for the next part. */ scope_mtd = mtd; } } if (scope_mtd == NULL) { classDef *cd; /* If we get here then it must be a class. */ if ((cd = lookupClass(pt, sp, scope_cd)) == NULL) break; /* If we have used the whole name then the lookup has succeeded. */ if (ep == NULL) { thd = (out ? cd->typehint_out : cd->typehint_in); if (thd != NULL && thd->status != being_parsed) return copyTypeHintNode(pt, thd, out); node = sipMalloc(sizeof (typeHintNodeDef)); node->type = class_node; node->u.cd = cd; return node; } /* Otherwise this is the scope for the next part. */ scope_cd = cd; } /* If we have run out of name then the lookup has failed. */ if (ep == NULL) break; /* Repair the name and go on to the next part. */ *ep++ = '.'; sp = ep; } /* Repair the name. */ if (ep != NULL) *ep = '.'; /* Nothing was found. */ node = sipMalloc(sizeof (typeHintNodeDef)); node->type = other_node; node->u.name = sipStrdup(name); return node; } /* * Copy the root node of a type hint. */ static typeHintNodeDef *copyTypeHintNode(sipSpec *pt, typeHintDef *thd, int out) { typeHintNodeDef *node; parseTypeHint(pt, thd, out); if (thd->root == NULL) return NULL; node = sipMalloc(sizeof (typeHintNodeDef)); *node = *thd->root; node->next = NULL; return node; } /* * Lookup an enum. */ static enumDef *lookupEnum(sipSpec *pt, const char *name, classDef *scope_cd, mappedTypeDef *scope_mtd) { enumDef *ed; for (ed = pt->enums; ed != NULL; ed = ed->next) if (ed->pyname != NULL && strcmp(ed->pyname->text, name) == 0 && ed->ecd == scope_cd && ed->emtd == scope_mtd) return ed; return NULL; } /* * Lookup a mapped type. */ static mappedTypeDef *lookupMappedType(sipSpec *pt, const char *name) { mappedTypeDef *mtd; for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next) if (mtd->pyname != NULL && strcmp(mtd->pyname->text, name) == 0) { mappedTypeDef *impl = getMappedTypeImplementation(pt, mtd); if (impl != NULL) return impl; } return NULL; } /* * Lookup a class. */ static classDef *lookupClass(sipSpec *pt, const char *name, classDef *scope_cd) { classDef *cd; for (cd = pt->classes; cd != NULL; cd = cd->next) if (strcmp(cd->pyname->text, name) == 0 && cd->ecd == scope_cd && !isExternal(cd)) { classDef *impl = getClassImplementation(pt, cd); if (impl != NULL) return impl; } return NULL; } /* * Get the implementation (if there is one) for a type for the default API * version. */ void getDefaultImplementation(sipSpec *pt, argType atype, classDef **cdp, mappedTypeDef **mtdp) { classDef *cd; mappedTypeDef *mtd; ifaceFileDef *iff; if (atype == class_type) { cd = *cdp; mtd = NULL; iff = cd->iff; } else { cd = NULL; mtd = *mtdp; iff = mtd->iff; } /* See if there is more than one implementation. */ if (iff->api_range != NULL) { int def_api; cd = NULL; mtd = NULL; /* 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. */ if (iff->type == class_iface) { for (cd = pt->classes; cd != NULL; cd = cd->next) if (cd->iff == iff) break; } else { for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next) if (mtd->iff == iff) break; } break; } } *cdp = cd; *mtdp = mtd; } /* * Return TRUE if a version range includes the default API. */ int inDefaultAPI(sipSpec *pt, apiVersionRangeDef *range) { int def_api; /* Handle the trivial case. */ if (range == NULL) return TRUE; /* Get the default API. */ def_api = findAPI(pt, range->api_name->text)->from; if (range->from > 0 && range->from > def_api) return FALSE; if (range->to > 0 && range->to <= def_api) return FALSE; return TRUE; } /* * Get the class implementation (if there is one) of the given class according * to the default version of any relevant API. */ static classDef *getClassImplementation(sipSpec *pt, classDef *cd) { mappedTypeDef *mtd; getDefaultImplementation(pt, class_type, &cd, &mtd); return cd; } /* * Get the mapped type implementation (if there is one) of the given mapped * type according to the default version of any relevant API. */ static mappedTypeDef *getMappedTypeImplementation(sipSpec *pt, mappedTypeDef *mtd) { classDef *cd; getDefaultImplementation(pt, mapped_type, &cd, &mtd); return mtd; } /* * Generate a hint taking into account that it may be any sort of object. */ static void maybeAnyObject(const char *hint, int pep484, FILE *fp) { fprintf(fp, "%s", (strcmp(hint, "Any") != 0 ? hint : anyObject(pep484))); } sip-4.19.7/siplib/0000755000076500000240000000000013231604431013745 5ustar philstaff00000000000000sip-4.19.7/siplib/apiversions.c0000644000076500000240000001602313231604405016456 0ustar philstaff00000000000000/* * The implementation of the supprt for setting API versions. * * Copyright (c) 2016 Riverbank Computing Limited * * 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 #include #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; (void)self; 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; (void)self; 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]); } sip-4.19.7/siplib/array.c0000644000076500000240000005150113231604406015233 0ustar philstaff00000000000000/* * This file implements the API for the array type. * * Copyright (c) 2016 Riverbank Computing Limited * * 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 #include #include #include "sipint.h" #include "array.h" /* The object data structure. */ typedef struct { PyObject_HEAD void *data; const sipTypeDef *td; const char *format; size_t stride; SIP_SSIZE_T len; int flags; PyObject *owner; } sipArrayObject; static int check_writable(sipArrayObject *array); static int check_index(sipArrayObject *array, SIP_SSIZE_T idx); static void *get_value(sipArrayObject *array, PyObject *value); static void *get_slice(sipArrayObject *array, PyObject *value, SIP_SSIZE_T len); #if PY_VERSION_HEX < 0x02050000 static void fix_bounds(int len, int *left, int *right); #endif #if PY_VERSION_HEX >= 0x02050000 static void bad_key(PyObject *key); #endif static void *element(sipArrayObject *array, SIP_SSIZE_T idx); static PyObject *make_array(void *data, const sipTypeDef *td, const char *format, size_t stride, SIP_SSIZE_T len, int flags, PyObject *owner); /* * Implement len() for the type. */ static SIP_SSIZE_T sipArray_length(PyObject *self) { return ((sipArrayObject *)self)->len; } /* * Implement sequence item sub-script for the type. */ static PyObject *sipArray_item(PyObject *self, SIP_SSIZE_T idx) { sipArrayObject *array = (sipArrayObject *)self; PyObject *py_item; void *data; if (check_index(array, idx) < 0) return NULL; data = element(array, idx); if (array->td != NULL) { py_item = sip_api_convert_from_type(data, array->td, NULL); } else { switch (*array->format) { case 'b': py_item = SIPLong_FromLong(*(char *)data); break; case 'B': py_item = PyLong_FromUnsignedLong(*(unsigned char *)data); break; case 'h': py_item = SIPLong_FromLong(*(short *)data); break; case 'H': py_item = PyLong_FromUnsignedLong(*(unsigned short *)data); break; case 'i': py_item = SIPLong_FromLong(*(int *)data); break; case 'I': py_item = PyLong_FromUnsignedLong(*(unsigned int *)data); break; case 'f': py_item = PyFloat_FromDouble(*(float *)data); break; case 'd': py_item = PyFloat_FromDouble(*(double *)data); break; default: py_item = NULL; } } return py_item; } #if PY_VERSION_HEX < 0x02050000 /* * Implement sequence slice sub-script for the type. */ static PyObject *sipArray_slice(PyObject *self, int left, int right) { sipArrayObject *array = (sipArrayObject *)self; fix_bounds(array->len, &left, &right); if (left == right) left = right = 0; return make_array(element(array, left), array->td, array->format, array->stride, right - left, (array->flags & ~SIP_OWNS_MEMORY), array->owner); } /* * Implement sequence assignment item sub-script for the type. */ static int sipArray_ass_item(PyObject *self, int idx, PyObject *value) { sipArrayObject *array = (sipArrayObject *)self; void *value_data; if (check_writable(array) < 0 || check_index(array, idx) < 0) return -1; if ((value_data = get_value(array, value)) == NULL) return -1; memmove(element(array, idx), value_data, array->stride); return 0; } /* * Implement sequence assignment slice sub-script for the type. */ static int sipArray_ass_slice(PyObject *self, int left, int right, PyObject *value) { sipArrayObject *array = (sipArrayObject *)self; void *value_data; if (check_writable(array) < 0) return -1; fix_bounds(array->len, &left, &right); if ((value_data = get_slice(array, value, right - left)) == NULL) return -1; memmove(element(array, left), value_data, (right - left) * array->stride); return 0; } #endif /* The sequence methods data structure. */ static PySequenceMethods sipArray_SequenceMethods = { sipArray_length, /* sq_length */ 0, /* sq_concat */ 0, /* sq_repeat */ sipArray_item, /* sq_item */ #if PY_VERSION_HEX >= 0x02050000 0, /* sq_slice */ 0, /* sq_ass_item */ 0, /* sq_ass_slice */ #else sipArray_slice, /* sq_slice */ sipArray_ass_item, /* sq_ass_item */ sipArray_ass_slice, /* sq_ass_slice */ #endif 0, /* sq_contains */ 0, /* sq_inplace_concat */ 0, /* sq_inplace_repeat */ }; #if PY_VERSION_HEX >= 0x02050000 /* * Implement mapping sub-script for the type. */ static PyObject *sipArray_subscript(PyObject *self, PyObject *key) { sipArrayObject *array = (sipArrayObject *)self; if (PyIndex_Check(key)) { Py_ssize_t idx = PyNumber_AsSsize_t(key, PyExc_IndexError); if (idx == -1 && PyErr_Occurred()) return NULL; if (idx < 0) idx += array->len; return sipArray_item(self, idx); } if (PySlice_Check(key)) { Py_ssize_t start, stop, step, slicelength; if (sipConvertFromSliceObject(key, array->len, &start, &stop, &step, &slicelength) < 0) return NULL; if (step != 1) { PyErr_SetNone(PyExc_NotImplementedError); return NULL; } return make_array(element(array->data, start), array->td, array->format, array->stride, slicelength, (array->flags & ~SIP_OWNS_MEMORY), array->owner); } bad_key(key); return NULL; } /* * Implement mapping assignment sub-script for the type. */ static int sipArray_ass_subscript(PyObject *self, PyObject *key, PyObject *value) { sipArrayObject *array = (sipArrayObject *)self; SIP_SSIZE_T start, len; void *value_data; if (check_writable(array) < 0) return -1; if (PyIndex_Check(key)) { start = PyNumber_AsSsize_t(key, PyExc_IndexError); if (start == -1 && PyErr_Occurred()) return -1; if (start < 0) start += array->len; if (check_index(array, start) < 0) return -1; if ((value_data = get_value(array, value)) == NULL) return -1; len = 1; } else if (PySlice_Check(key)) { Py_ssize_t stop, step; if (sipConvertFromSliceObject(key, array->len, &start, &stop, &step, &len) < 0) return -1; if (step != 1) { PyErr_SetNone(PyExc_NotImplementedError); return -1; } if ((value_data = get_slice(array, value, len)) == NULL) return -1; } else { bad_key(key); return -1; } memmove(element(array, start), value_data, len * array->stride); return 0; } /* The mapping methods data structure. */ static PyMappingMethods sipArray_MappingMethods = { sipArray_length, /* mp_length */ sipArray_subscript, /* mp_subscript */ sipArray_ass_subscript, /* mp_ass_subscript */ }; #endif #if PY_VERSION_HEX >= 0x02060300 /* * The buffer implementation for Python v2.6.3 and later. */ static int sipArray_getbuffer(PyObject *self, Py_buffer *view, int flags) { sipArrayObject *array = (sipArrayObject *)self; if (view == NULL) return 0; if (((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) && (array->flags & SIP_READ_ONLY)) { PyErr_SetString(PyExc_BufferError, "object is not writable."); return -1; } view->obj = self; Py_INCREF(self); view->buf = array->data; view->len = array->len; view->readonly = (array->flags & SIP_READ_ONLY); view->itemsize = array->stride; view->format = NULL; if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) view->format = (char *)array->format; view->ndim = 1; view->shape = NULL; if ((flags & PyBUF_ND) == PyBUF_ND) view->shape = &view->len; view->strides = NULL; if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) view->strides = &view->itemsize; view->suboffsets = NULL; view->internal = NULL; return 0; } #endif #if PY_MAJOR_VERSION < 3 /* * The read buffer implementation for Python v2. */ static SIP_SSIZE_T sipArray_getreadbuffer(PyObject *self, SIP_SSIZE_T seg, void **ptr) { sipArrayObject *array = (sipArrayObject *)self; if (seg != 0) { PyErr_SetString(PyExc_SystemError, "invalid buffer segment"); return -1; } *ptr = array->data; return array->len; } #endif #if PY_MAJOR_VERSION < 3 /* * The write buffer implementation for Python v2. */ static SIP_SSIZE_T sipArray_getwritebuffer(PyObject *self, SIP_SSIZE_T seg, void **ptr) { if (check_writable((sipArrayObject *)self) < 0) return -1; return sipArray_getreadbuffer(self, seg, ptr); } #endif #if PY_MAJOR_VERSION < 3 /* * The segment count implementation for Python v2. */ static SIP_SSIZE_T sipArray_getsegcount(PyObject *self, SIP_SSIZE_T *lenp) { SIP_SSIZE_T segs, len; len = ((sipArrayObject *)self)->len; segs = (len < 0 ? 0 : 1); if (lenp != NULL) *lenp = len; return segs; } #endif /* The buffer methods data structure. */ static PyBufferProcs sipArray_BufferProcs = { #if PY_MAJOR_VERSION >= 3 sipArray_getbuffer, /* bf_getbuffer */ 0 /* bf_releasebuffer */ #else sipArray_getreadbuffer, /* bf_getreadbuffer */ sipArray_getwritebuffer, /* bf_getwritebuffer */ sipArray_getsegcount, /* bf_getsegcount */ #if PY_VERSION_HEX >= 0x02050000 (charbufferproc)sipArray_getreadbuffer, /* bf_getcharbuffer */ #if PY_VERSION_HEX >= 0x02060300 sipArray_getbuffer, /* bf_getbuffer */ 0 /* bf_releasebuffer */ #endif #else (getcharbufferproc)sipArray_getreadbuffer /* bf_getcharbuffer */ #endif #endif }; /* The instance deallocation function. */ static void sipArray_dealloc(PyObject *self) { sipArrayObject *array = (sipArrayObject *)self; if (array->flags & SIP_OWNS_MEMORY) sip_api_free(array->data); else Py_XDECREF(array->owner); } /* The type data structure. */ PyTypeObject sipArray_Type = { PyVarObject_HEAD_INIT(NULL, 0) "sip.array", /* tp_name */ sizeof (sipArrayObject), /* tp_basicsize */ 0, /* tp_itemsize */ sipArray_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 */ &sipArray_SequenceMethods, /* tp_as_sequence */ #if PY_VERSION_HEX >= 0x02050000 &sipArray_MappingMethods, /* tp_as_mapping */ #else 0, /* tp_as_mapping */ #endif 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ &sipArray_BufferProcs, /* tp_as_buffer */ #if defined(Py_TPFLAGS_HAVE_NEWBUFFER) Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */ #else Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ #endif 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 */ 0, /* tp_alloc */ 0, /* tp_new */ 0, /* tp_free */ 0, /* tp_is_gc */ 0, /* tp_bases */ 0, /* tp_mro */ 0, /* tp_cache */ 0, /* tp_subclasses */ 0, /* tp_weaklist */ 0, /* tp_del */ #if PY_VERSION_HEX >= 0x02060000 0, /* tp_version_tag */ #endif #if PY_VERSION_HEX >= 0x03040000 0, /* tp_finalize */ #endif }; /* * Check that an array is writable. */ static int check_writable(sipArrayObject *array) { if (array->flags & SIP_READ_ONLY) { PyErr_SetString(PyExc_TypeError, "sip.array object is read-only"); return -1; } return 0; } /* * Check that an index is valid for an array. */ static int check_index(sipArrayObject *array, SIP_SSIZE_T idx) { if (idx >= 0 && idx < array->len) return 0; PyErr_SetString(PyExc_IndexError, "index out of bounds"); return -1; } #if PY_VERSION_HEX < 0x02050000 /* * Fix the bounds of a slice in the same way that the Python buffer object * does. */ static void fix_bounds(int len, int *left, int *right) { if (*left < 0) *left = 0; else if (*left > len) *left = len; if (*right < *left) *right = *left; else if (*right > len) *right = len; } #endif #if PY_VERSION_HEX >= 0x02050000 /* * Raise an exception about a bad sub-script key. */ static void bad_key(PyObject *key) { PyErr_Format(PyExc_TypeError, "cannot index a sip.array object using '%s'", Py_TYPE(key)->tp_name); } #endif /* * Get the address of an element of an array. */ static void *element(sipArrayObject *array, SIP_SSIZE_T idx) { return (unsigned char *)(array->data) + idx * array->stride; } /* * Get the address of a value that will be copied to an array. */ static void *get_value(sipArrayObject *array, PyObject *value) { static union { signed char s_char_t; unsigned char u_char_t; signed short s_short_t; unsigned short u_short_t; signed int s_int_t; unsigned int u_int_t; float float_t; double double_t; } static_data; void *data; if (array->td != NULL) { int iserr = FALSE; data = sip_api_force_convert_to_type(value, array->td, NULL, SIP_NOT_NONE|SIP_NO_CONVERTORS, NULL, &iserr); } else { PyErr_Clear(); switch (*array->format) { case 'b': static_data.s_char_t = sip_api_long_as_char(value); data = &static_data.s_char_t; break; case 'B': static_data.u_char_t = sip_api_long_as_unsigned_char(value); data = &static_data.u_char_t; break; case 'h': static_data.s_short_t = sip_api_long_as_short(value); data = &static_data.s_short_t; break; case 'H': static_data.u_short_t = sip_api_long_as_unsigned_short(value); data = &static_data.u_short_t; break; case 'i': static_data.s_int_t = sip_api_long_as_int(value); data = &static_data.s_int_t; break; case 'I': static_data.u_int_t = sip_api_long_as_unsigned_int(value); data = &static_data.u_int_t; break; case 'f': static_data.float_t = (float)PyFloat_AsDouble(value); data = &static_data.float_t; break; case 'd': static_data.double_t = PyFloat_AsDouble(value); data = &static_data.double_t; break; default: data = NULL; } if (PyErr_Occurred()) data = NULL; } return data; } /* * Get the address of an value that will be copied to an array slice. */ static void *get_slice(sipArrayObject *array, PyObject *value, SIP_SSIZE_T len) { sipArrayObject *other = (sipArrayObject *)value; if (!PyObject_IsInstance(value, (PyObject *)&sipArray_Type) || array->td != other->td || strcmp(array->format, other->format) != 0) { const char *type; if (array->td != NULL) { type = sipTypeName(array->td); } else { switch (*array->format) { case 'b': type = "char"; break; case 'B': type = "unsigned char"; break; case 'h': type = "short"; break; case 'H': type = "unsigned short"; break; case 'i': type = "int"; break; case 'I': type = "unsigned int"; break; case 'f': type = "float"; break; case 'd': type = "double"; break; default: type = ""; } } PyErr_Format(PyExc_TypeError, "can only assign another array of %s to the slice", type); return NULL; } if (other->len != len) { PyErr_Format(PyExc_TypeError, "the array being assigned must have length " SIP_SSIZE_T_FORMAT, len); return NULL; } if (other->stride == array->stride) { PyErr_Format(PyExc_TypeError, #if PY_VERSION_HEX >= 0x02050000 "the array being assigned must have stride %zu", array->stride); #else "the array being assigned must have stride %ld", (unsigned long)array->stride); #endif return NULL; } return other->data; } /* * Do the work of creating an array. */ static PyObject *make_array(void *data, const sipTypeDef *td, const char *format, size_t stride, SIP_SSIZE_T len, int flags, PyObject *owner) { sipArrayObject *array; if ((array = PyObject_NEW(sipArrayObject, &sipArray_Type)) == NULL) return NULL; array->data = data; array->td = td; array->format = format; array->stride = stride; array->len = len; array->flags = flags; if (flags & SIP_OWNS_MEMORY) { /* This is a borrowed reference to itself. */ array->owner = (PyObject *)array; } else { Py_XINCREF(owner); array->owner = owner; } return (PyObject *)array; } /* * Wrap an array of instances of a fundamental type. At the moment format must * be either "b" (char), "B" (unsigned char), "h" (short), "H" (unsigned * short), "i" (int), "I" (unsigned int), "f" (float) or "d" (double). */ PyObject *sip_api_convert_to_array(void *data, const char *format, SIP_SSIZE_T len, int flags) { size_t stride; if (data == NULL) { Py_INCREF(Py_None); return Py_None; } switch (*format) { case 'b': stride = sizeof (char); break; case 'B': stride = sizeof (unsigned char); break; case 'h': stride = sizeof (short); break; case 'H': stride = sizeof (unsigned short); break; case 'i': stride = sizeof (int); break; case 'I': stride = sizeof (unsigned int); break; case 'f': stride = sizeof (float); break; case 'd': stride = sizeof (double); break; default: stride = 0; } assert(stride > 0); assert(len >= 0); return make_array(data, NULL, format, stride, len, flags, NULL); } /* * Wrap an array of instances of a defined type. */ PyObject *sip_api_convert_to_typed_array(void *data, const sipTypeDef *td, const char *format, size_t stride, SIP_SSIZE_T len, int flags) { if (data == NULL) { Py_INCREF(Py_None); return Py_None; } assert(stride > 0); assert(len >= 0); return make_array(data, td, format, stride, len, flags, NULL); } sip-4.19.7/siplib/array.h0000644000076500000240000000214213231604405015234 0ustar philstaff00000000000000/* * This file defines the API for the array type. * * Copyright (c) 2016 Riverbank Computing Limited * * 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 _ARRAY_H #define _ARRAY_H #include #include "sipint.h" #ifdef __cplusplus extern "C" { #endif extern PyTypeObject sipArray_Type; PyObject *sip_api_convert_to_array(void *data, const char *format, SIP_SSIZE_T len, int flags); PyObject *sip_api_convert_to_typed_array(void *data, const sipTypeDef *td, const char *format, size_t stride, SIP_SSIZE_T len, int flags); #ifdef __cplusplus } #endif #endif sip-4.19.7/siplib/bool.cpp0000644000076500000240000000151413231604405015406 0ustar philstaff00000000000000// This contains all the C++ code that is needed by the sip module. // // Copyright (c) 2015 Riverbank Computing Limited // // 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(ptr) = !!val; } sip-4.19.7/siplib/descriptors.c0000644000076500000240000003245713231604405016466 0ustar philstaff00000000000000/* * The implementation of the different descriptors. * * Copyright (c) 2016 Riverbank Computing Limited * * 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 #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, and we * handle mixins via a delegate. *****************************************************************************/ /* Forward declarations of slots. */ static PyObject *sipMethodDescr_descr_get(PyObject *self, PyObject *obj, PyObject *type); static PyObject *sipMethodDescr_repr(PyObject *self); static int sipMethodDescr_traverse(PyObject *self, visitproc visit, void *arg); static int sipMethodDescr_clear(PyObject *self); static void sipMethodDescr_dealloc(PyObject *self); /* * The object data structure. */ typedef struct _sipMethodDescr { PyObject_HEAD /* The method definition. */ PyMethodDef *pmd; /* The mixin name, if any. */ PyObject *mixin_name; } sipMethodDescr; /* * The type data structure. */ PyTypeObject sipMethodDescr_Type = { PyVarObject_HEAD_INIT(NULL, 0) "sip.methoddescriptor", /* tp_name */ sizeof (sipMethodDescr), /* tp_basicsize */ 0, /* tp_itemsize */ sipMethodDescr_dealloc, /* 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|Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ sipMethodDescr_traverse,/* tp_traverse */ sipMethodDescr_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 */ sipMethodDescr_descr_get, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ 0, /* tp_free */ 0, /* tp_is_gc */ 0, /* tp_bases */ 0, /* tp_mro */ 0, /* tp_cache */ 0, /* tp_subclasses */ 0, /* tp_weaklist */ 0, /* tp_del */ #if PY_VERSION_HEX >= 0x02060000 0, /* tp_version_tag */ #endif #if PY_VERSION_HEX >= 0x03040000 0, /* tp_finalize */ #endif }; /* * 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; ((sipMethodDescr *)descr)->mixin_name = NULL; } return descr; } /* * Return a new method descriptor based on an existing one and a mixin name. */ PyObject *sipMethodDescr_Copy(PyObject *orig, PyObject *mixin_name) { PyObject *descr = PyType_GenericAlloc(&sipMethodDescr_Type, 0); if (descr != NULL) { ((sipMethodDescr *)descr)->pmd = ((sipMethodDescr *)orig)->pmd; ((sipMethodDescr *)descr)->mixin_name = mixin_name; Py_INCREF(mixin_name); } return descr; } /* * The descriptor's descriptor get slot. */ static PyObject *sipMethodDescr_descr_get(PyObject *self, PyObject *obj, PyObject *type) { sipMethodDescr *md = (sipMethodDescr *)self; (void)type; if (obj == Py_None) obj = NULL; else if (md->mixin_name != NULL) obj = PyObject_GetAttr(obj, md->mixin_name); 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 ("", md->pmd->ml_name); } /* * The descriptor's traverse slot. */ static int sipMethodDescr_traverse(PyObject *self, visitproc visit, void *arg) { if (((sipMethodDescr *)self)->mixin_name != NULL) { int vret = visit(((sipMethodDescr *)self)->mixin_name, arg); if (vret != 0) return vret; } return 0; } /* * The descriptor's clear slot. */ static int sipMethodDescr_clear(PyObject *self) { PyObject *tmp = ((sipMethodDescr *)self)->mixin_name; ((sipMethodDescr *)self)->mixin_name = NULL; Py_XDECREF(tmp); return 0; } /* * The descriptor's dealloc slot. */ static void sipMethodDescr_dealloc(PyObject *self) { sipMethodDescr_clear(self); Py_TYPE(self)->tp_free(self); } /***************************************************************************** * 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); static int sipVariableDescr_traverse(PyObject *self, visitproc visit, void *arg); static int sipVariableDescr_clear(PyObject *self); static void sipVariableDescr_dealloc(PyObject *self); /* * 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; /* The mixin name, if any. */ PyObject *mixin_name; } sipVariableDescr; /* * The type data structure. */ PyTypeObject sipVariableDescr_Type = { PyVarObject_HEAD_INIT(NULL, 0) "sip.variabledescriptor", /* tp_name */ sizeof (sipVariableDescr), /* tp_basicsize */ 0, /* tp_itemsize */ sipVariableDescr_dealloc, /* 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|Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ sipVariableDescr_traverse, /* tp_traverse */ sipVariableDescr_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 */ sipVariableDescr_descr_get, /* tp_descr_get */ sipVariableDescr_descr_set, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ 0, /* tp_free */ 0, /* tp_is_gc */ 0, /* tp_bases */ 0, /* tp_mro */ 0, /* tp_cache */ 0, /* tp_subclasses */ 0, /* tp_weaklist */ 0, /* tp_del */ #if PY_VERSION_HEX >= 0x02060000 0, /* tp_version_tag */ #endif #if PY_VERSION_HEX >= 0x03040000 0, /* tp_finalize */ #endif }; /* 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; ((sipVariableDescr *)descr)->mixin_name = NULL; } return descr; } /* * Return a new variable descriptor based on an existing one and a mixin name. */ PyObject *sipVariableDescr_Copy(PyObject *orig, PyObject *mixin_name) { PyObject *descr = PyType_GenericAlloc(&sipVariableDescr_Type, 0); if (descr != NULL) { ((sipVariableDescr *)descr)->vd = ((sipVariableDescr *)orig)->vd; ((sipVariableDescr *)descr)->td = ((sipVariableDescr *)orig)->td; ((sipVariableDescr *)descr)->cod = ((sipVariableDescr *)orig)->cod; ((sipVariableDescr *)descr)->mixin_name = mixin_name; Py_INCREF(mixin_name); } 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 ((sipVariableGetterFunc)vd->vd->vd_getter)(addr, obj, 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 ((sipVariableSetterFunc)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_type == ClassVariable) { 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; } if (vd->mixin_name != NULL) obj = PyObject_GetAttr(obj, vd->mixin_name); /* Get the C++ instance. */ if ((addr = sip_api_get_cpp_ptr((sipSimpleWrapper *)obj, vd->td)) == NULL) return -1; } *addrp = addr; return 0; } /* * The descriptor's traverse slot. */ static int sipVariableDescr_traverse(PyObject *self, visitproc visit, void *arg) { if (((sipVariableDescr *)self)->mixin_name != NULL) { int vret = visit(((sipVariableDescr *)self)->mixin_name, arg); if (vret != 0) return vret; } return 0; } /* * The descriptor's clear slot. */ static int sipVariableDescr_clear(PyObject *self) { PyObject *tmp = ((sipVariableDescr *)self)->mixin_name; ((sipVariableDescr *)self)->mixin_name = NULL; Py_XDECREF(tmp); return 0; } /* * The descriptor's dealloc slot. */ static void sipVariableDescr_dealloc(PyObject *self) { sipVariableDescr_clear(self); Py_TYPE(self)->tp_free(self); } sip-4.19.7/siplib/int_convertors.c0000644000076500000240000002101313231604406017166 0ustar philstaff00000000000000/* * The implementation of the Python object to C/C++ integer convertors. * * Copyright (c) 2017 Riverbank Computing Limited * * 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. */ /* * NOTES * * The legacy integer conversions (ie. without support for overflow checking) * are flawed and inconsistent. Large Python signed values were converted to * -1 whereas small values where truncated. When converting function arguments * all overlows were ignored, however when converting the results returned by * Python re-implementations then large Python values raised an exception * whereas small values were truncated. * * With the new integer conversions large Python signed values will always * raise an overflow exception (even if overflow checking is disabled). This * is because a truncated value is not available - it would have to be * computed. This may cause new exceptions to be raised but is justified in * that the value that was being used bore no relation to the original value. */ #include #include #include "sipint.h" /* Wrappers to deal with lack of long long support. */ #if defined(HAVE_LONG_LONG) #define SIPLong_AsLongLong PyLong_AsLongLong #define SIP_LONG_LONG PY_LONG_LONG #define SIP_LONG_LONG_FORMAT "%lld" #define SIP_UNSIGNED_LONG_LONG_FORMAT "%llu" #else #define SIPLong_AsLongLong PyLong_AsLong #define SIP_LONG_LONG long #define SIP_LONG_LONG_FORMAT "%ld" #define SIP_UNSIGNED_LONG_LONG_FORMAT "%lu" #endif static int overflow_checking = FALSE; /* Check for overflows. */ static SIP_LONG_LONG long_as_long_long(PyObject *o, SIP_LONG_LONG min, SIP_LONG_LONG max); static unsigned long long_as_unsigned_long(PyObject *o, unsigned long max); static void raise_signed_overflow(SIP_LONG_LONG min, SIP_LONG_LONG max); static void raise_unsigned_overflow(unsigned SIP_LONG_LONG max); /* * Enable or disable overflow checking (Python API). */ PyObject *sipEnableOverflowChecking(PyObject *self, PyObject *args) { int enable; (void)self; if (PyArg_ParseTuple(args, "i:enableoverflowchecking", &enable)) { PyObject *res; res = (sip_api_enable_overflow_checking(enable) ? Py_True : Py_False); Py_INCREF(res); return res; } return NULL; } /* * Enable or disable overflow checking (C API). */ int sip_api_enable_overflow_checking(int enable) { int was_enabled = overflow_checking; overflow_checking = enable; return was_enabled; } /* * Convert a Python object to a C++ bool (returned as an int). */ int sip_api_convert_to_bool(PyObject *o) { int was_enabled, v; /* Convert the object to an int while checking for overflow. */ was_enabled = sip_api_enable_overflow_checking(TRUE); v = sip_api_long_as_int(o); sip_api_enable_overflow_checking(was_enabled); if (PyErr_Occurred()) { if (PyErr_ExceptionMatches(PyExc_OverflowError)) { PyErr_Clear(); /* The value must have been non-zero. */ v = 1; } else { PyErr_Format(PyExc_TypeError, "a 'bool' is expected not '%s'", Py_TYPE(o)->tp_name); v = -1; } } else if (v != 0) { v = 1; } return v; } /* * Convert a Python object to a C char. */ char sip_api_long_as_char(PyObject *o) { return (char)long_as_long_long(o, CHAR_MIN, CHAR_MAX); } /* * Convert a Python object to a C signed char. */ signed char sip_api_long_as_signed_char(PyObject *o) { return (signed char)long_as_long_long(o, SCHAR_MIN, SCHAR_MAX); } /* * Convert a Python object to a C unsigned char. */ unsigned char sip_api_long_as_unsigned_char(PyObject *o) { return (unsigned char)long_as_unsigned_long(o, UCHAR_MAX); } /* * Convert a Python object to a C short. */ short sip_api_long_as_short(PyObject *o) { return (short)long_as_long_long(o, SHRT_MIN, SHRT_MAX); } /* * Convert a Python object to a C unsigned short. */ unsigned short sip_api_long_as_unsigned_short(PyObject *o) { return (unsigned short)long_as_unsigned_long(o, USHRT_MAX); } /* * Convert a Python object to a C int. */ int sip_api_long_as_int(PyObject *o) { return (int)long_as_long_long(o, INT_MIN, INT_MAX); } /* * Convert a Python object to a C unsigned int. */ unsigned sip_api_long_as_unsigned_int(PyObject *o) { return (unsigned)long_as_unsigned_long(o, UINT_MAX); } /* * Convert a Python object to a C long. */ long sip_api_long_as_long(PyObject *o) { return (long)long_as_long_long(o, LONG_MIN, LONG_MAX); } /* * Convert a Python object to a C unsigned long. */ unsigned long sip_api_long_as_unsigned_long(PyObject *o) { return long_as_unsigned_long(o, ULONG_MAX); } #if defined(HAVE_LONG_LONG) /* * Convert a Python object to a C long long. */ PY_LONG_LONG sip_api_long_as_long_long(PyObject *o) { return long_as_long_long(o, LLONG_MIN, LLONG_MAX); } /* * Convert a Python object to a C unsigned long long. */ unsigned PY_LONG_LONG sip_api_long_as_unsigned_long_long(PyObject *o) { unsigned PY_LONG_LONG value; PyErr_Clear(); if (overflow_checking) { value = PyLong_AsUnsignedLongLong(o); if (PyErr_Occurred()) { /* Provide a better exception message. */ if (PyErr_ExceptionMatches(PyExc_OverflowError)) raise_unsigned_overflow(ULLONG_MAX); } } else { /* * Note that this doesn't handle Python v2 int objects, but the old * convertors didn't either. */ value = PyLong_AsUnsignedLongLongMask(o); } return value; } #endif /* * Convert a Python object to a long long checking that the value is within a * range if overflow checking is enabled. */ static SIP_LONG_LONG long_as_long_long(PyObject *o, SIP_LONG_LONG min, SIP_LONG_LONG max) { SIP_LONG_LONG value; PyErr_Clear(); value = SIPLong_AsLongLong(o); if (PyErr_Occurred()) { /* Provide a better exception message. */ if (PyErr_ExceptionMatches(PyExc_OverflowError)) raise_signed_overflow(min, max); } else if (overflow_checking && (value < min || value > max)) { raise_signed_overflow(min, max); } return value; } /* * Convert a Python object to an unsigned long checking that the value is * within a range if overflow checking is enabled. */ static unsigned long long_as_unsigned_long(PyObject *o, unsigned long max) { unsigned long value; PyErr_Clear(); if (overflow_checking) { value = PyLong_AsUnsignedLong(o); if (PyErr_Occurred()) { /* Provide a better exception message. */ if (PyErr_ExceptionMatches(PyExc_OverflowError)) raise_unsigned_overflow(max); } else if (value > max) { raise_unsigned_overflow(max); } } else { #if PY_VERSION_HEX < 0x02040000 /* * Work around a bug in Python versions prior to v2.4 where an integer * (or a named enum) causes an error. */ if (!PyLong_Check(o) && PyInt_Check(o)) { long v = PyInt_AsLong(o); if (v < 0) { raise_unsigned_overflow(max); return (unsigned long)-1; } return v; } #endif value = PyLong_AsUnsignedLongMask(o); } return value; } /* * Raise an overflow exception if a signed value is out of range. */ static void raise_signed_overflow(SIP_LONG_LONG min, SIP_LONG_LONG max) { PyErr_Format(PyExc_OverflowError, "value must be in the range " SIP_LONG_LONG_FORMAT " to " SIP_LONG_LONG_FORMAT, min, max); } /* * Raise an overflow exception if an unsigned value is out of range. */ static void raise_unsigned_overflow(unsigned SIP_LONG_LONG max) { PyErr_Format(PyExc_OverflowError, "value must be in the range 0 to " SIP_UNSIGNED_LONG_LONG_FORMAT, max); } sip-4.19.7/siplib/objmap.c0000644000076500000240000003410613231604406015367 0ustar philstaff00000000000000/* * This module implements a hash table class for mapping C/C++ addresses to the * corresponding wrapped Python object. * * Copyright (c) 2017 Riverbank Computing Limited * * 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 #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 add_object(sipObjectMap *om, void *addr, sipSimpleWrapper *val); static void add_aliases(sipObjectMap *om, void *addr, sipSimpleWrapper *val, const sipClassTypeDef *base_ctd, const sipClassTypeDef *ctd); static int remove_object(sipObjectMap *om, void *addr, sipSimpleWrapper *val); static void remove_aliases(sipObjectMap *om, void *addr, sipSimpleWrapper *val, const sipClassTypeDef *base_ctd, const sipClassTypeDef *ctd); static void reorganiseMap(sipObjectMap *om); static void *getUnguardedPointer(sipSimpleWrapper *w); /* * 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) { sipSimpleWrapper *unaliased; unaliased = (sipIsAlias(sw) ? (sipSimpleWrapper *)sw->data : sw); /* * 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(unaliased) == 0) continue; /* Ignore it if the C/C++ address is no longer valid. */ if (sip_api_get_address(unaliased) == NULL) 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(unaliased, py_type)) return unaliased; } return NULL; } /* * Add a C/C++ address and the corresponding wrapped Python object to the map. */ void sipOMAddObject(sipObjectMap *om, sipSimpleWrapper *val) { void *addr = getUnguardedPointer(val); const sipClassTypeDef *base_ctd; /* Add the object. */ add_object(om, addr, val); /* Add any aliases. */ base_ctd = (const sipClassTypeDef *)((sipWrapperType *)Py_TYPE(val))->wt_td; add_aliases(om, addr, val, base_ctd, base_ctd); } /* * Add an alias for any address that is different when cast to a super-type. */ static void add_aliases(sipObjectMap *om, void *addr, sipSimpleWrapper *val, const sipClassTypeDef *base_ctd, const sipClassTypeDef *ctd) { const sipEncodedTypeDef *sup; /* See if there are any super-classes. */ if ((sup = ctd->ctd_supers) != NULL) { sipClassTypeDef *sup_ctd = sipGetGeneratedClassType(sup, ctd); /* Recurse up the hierachy for the first super-class. */ add_aliases(om, addr, val, base_ctd, sup_ctd); /* * We only check for aliases for subsequent super-classes because the * first one can never need one. */ while (!sup++->sc_flag) { void *sup_addr; sup_ctd = sipGetGeneratedClassType(sup, ctd); /* Recurse up the hierachy for the remaining super-classes. */ add_aliases(om, addr, val, base_ctd, sup_ctd); sup_addr = (*base_ctd->ctd_cast)(addr, (sipTypeDef *)sup_ctd); if (sup_addr != addr) { sipSimpleWrapper *alias; /* Note that we silently ignore errors. */ if ((alias = sip_api_malloc(sizeof (sipSimpleWrapper))) != NULL) { /* * An alias is basically a bit-wise copy of the Python * object but only to ensure the fields we are subverting * are in the right place. An alias should never be passed * to the Python API. */ *alias = *val; alias->sw_flags = (val->sw_flags & SIP_SHARE_MAP) | SIP_ALIAS; alias->data = val; alias->next = NULL; add_object(om, sup_addr, alias); } } } } } /* * Add a wrapper (which may be an alias) to the map. */ static void add_object(sipObjectMap *om, void *addr, sipSimpleWrapper *val) { sipHashEntry *he = findHashEntry(om, addr); /* * 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->sw_flags & SIP_SHARE_MAP)) { sipSimpleWrapper *sw = he->first; he->first = NULL; while (sw != NULL) { sipSimpleWrapper *next = sw->next; if (sipIsAlias(sw)) { sip_api_free(sw); } else { /* * We are removing it from the map here. However, note * that we first have to call the destructor before marking * it as not being in the map, as the destructor itself * might end up trying to remove the wrapper and its * aliases from the map. In that case, if the wrapper is * already marked as not in the map, the removal will just * return early, leaving any potential aliases as stale * entries in the map. If we later try to wrap a different * object at the same address, we end up retrieving the * stale alias entry from the object map, triggering a * use-after-free when accessing its C++ object. */ sip_api_instance_destroyed(sw); sipSetNotInMap(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 = addr; 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) { void *addr; const sipClassTypeDef *base_ctd; /* Handle the trivial case. */ if (sipNotInMap(val)) return 0; if ((addr = getUnguardedPointer(val)) == NULL) return 0; /* Remove any aliases. */ base_ctd = (const sipClassTypeDef *)((sipWrapperType *)Py_TYPE(val))->wt_td; remove_aliases(om, addr, val, base_ctd, base_ctd); /* Remove the object. */ return remove_object(om, addr, val); } /* * Remove an alias for any address that is different when cast to a super-type. */ static void remove_aliases(sipObjectMap *om, void *addr, sipSimpleWrapper *val, const sipClassTypeDef *base_ctd, const sipClassTypeDef *ctd) { const sipEncodedTypeDef *sup; /* See if there are any super-classes. */ if ((sup = ctd->ctd_supers) != NULL) { sipClassTypeDef *sup_ctd = sipGetGeneratedClassType(sup, ctd); /* Recurse up the hierachy for the first super-class. */ remove_aliases(om, addr, val, base_ctd, sup_ctd); /* * We only check for aliases for subsequent super-classes because the * first one can never need one. */ while (!sup++->sc_flag) { void *sup_addr; sup_ctd = sipGetGeneratedClassType(sup, ctd); /* Recurse up the hierachy for the remaining super-classes. */ remove_aliases(om, addr, val, base_ctd, sup_ctd); sup_addr = (*base_ctd->ctd_cast)(addr, (sipTypeDef *)sup_ctd); if (sup_addr != addr) remove_object(om, sup_addr, val); } } } /* * Remove a wrapper from the map. */ static int remove_object(sipObjectMap *om, void *addr, sipSimpleWrapper *val) { sipHashEntry *he = findHashEntry(om, addr); sipSimpleWrapper **swp; for (swp = &he->first; *swp != NULL; swp = &(*swp)->next) { sipSimpleWrapper *sw, *next; int do_remove; sw = *swp; next = sw->next; if (sipIsAlias(sw)) { if (sw->data == val) { sip_api_free(sw); do_remove = TRUE; } else { do_remove = FALSE; } } else { do_remove = (sw == val); } if (do_remove) { *swp = 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; } /* * Return the unguarded pointer to a C/C++ instance, ie. the pointer was valid * but may longer be. */ static void *getUnguardedPointer(sipSimpleWrapper *w) { return (w->access_func != NULL) ? w->access_func(w, UnguardedPointer) : w->data; } sip-4.19.7/siplib/qtlib.c0000644000076500000240000004452513231604405015237 0ustar philstaff00000000000000/* * The SIP library code that implements the interface to the optional module * supplied Qt support. * * Copyright (c) 2016 Riverbank Computing Limited * * 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 #include #include #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; assert(sipQtSupport->qt_create_universal_slot); 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. Don't check if * any receiver C++ object still exists. */ PyObject *sip_api_invoke_slot(const sipSlot *slot, PyObject *sigargs) { return sip_api_invoke_slot_ex(slot, sigargs, TRUE); } /* * Invoke a single slot (Qt or Python) and return the result. Optionally check * that any receiver C++ object still exist. */ PyObject *sip_api_invoke_slot_ex(const sipSlot *slot, PyObject *sigargs, int no_receiver_check) { PyObject *sa, *oxtype, *oxvalue, *oxtb, *sfunc, *sref; assert(sipQtSupport); /* Keep some compilers quiet. */ oxtype = oxvalue = oxtb = NULL; /* Fan out Qt signals. (Only PyQt3 would 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 (!no_receiver_check && PyObject_TypeCheck(self, (PyTypeObject *)&sipSimpleWrapper_Type) && sip_api_get_address((sipSimpleWrapper *)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) { assert(sipQtSupport); assert(sipQtSupport->qt_same_name); /* 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) { assert(sipQtSupport); assert(sipQtSupport->qt_find_slot); 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(sip_api_get_address(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) { assert(sipQtSupport); 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) { assert(sipQtSupport); assert(sipQtSupport->qt_connect); /* 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 would 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) { assert(sipQtSupport); assert(sipQtSupport->qt_disconnect); assert(sipQtSupport->qt_destroy_universal_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 would 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) { assert(sipQtSupport); 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) { assert(sipQtSupport); 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; } sip-4.19.7/siplib/sip.h.in0000644000076500000240000020233513231604431015323 0ustar philstaff00000000000000/* * The SIP module interface. * * Copyright (c) 2017 Riverbank Computing Limited * * 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 /* * There is a mis-feature somewhere with the Borland compiler. This works * around it. */ #if defined(__BORLANDC__) #include #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 0x041307 #define SIP_VERSION_STR "4.19.7" /* * Define the current API version number. SIP must handle modules with the * same major number and with the same or earlier minor number. Whenever * members are added to non-embedded data structures they must be appended and * the minor number incremented. Whenever data structure members are removed * or their offset changed then the major number must be incremented and the * minor number set * to 0. * * History: * * 12.3 Added SIP_TYPE_SCOPED_ENUM to the sipTypeDef flags. * Added sip_api_convert_to_enum() to the public API. * Added sip_api_convert_to_bool() to the public API. * Added sip_api_long_as_char(), sip_api_long_as_signed_char(), * sip_api_long_as_unsigned_char(), sip_api_long_as_short(), * sip_api_long_as_unsigned_short(), sip_api_long_as_int(), * sip_api_long_as_unsigned_int(), sip_api_long_as_long(), * sip_api_long_as_unsigned_long(), sip_api_long_as_long_long(), * sip_api_long_as_unsigned_long_long() to the public API. * Deprecated sip_api_can_convert_to_enum(). * * 12.2 Added sip_api_print_object() to the public API. * Renamed sip_api_common_dtor() to sip_api_instance_destroyed() and added * it to the public API. * Added sipEventType and sip_api_register_event_handler() to the public * API. * * 12.1 Added sip_api_enable_gc() to the public API. * * 12.0 Added SIP_TYPE_LIMITED_API to the sipTypeDef flags. * Added sip_api_py_type_dict() and sip_api_py_type_name() to the public * API. * Added sip_api_set_new_user_type_handler() to the public API. * Added sip_api_is_user_type() to the public API. * Added sip_api_set_type_user_data() and sip_api_get_type_user_data() to * the public API. * Added sip_api_set_user_object() and sip_api_get_user_object() to the * public API. * Added sip_api_get_method() and sip_api_from_method() to the public API. * Added sip_api_get_c_function() to the public API. * Added sip_api_get_date() and sip_api_from_date() to the public API. * Added sip_api_get_datetime() and sip_api_from_datetime() to the public * API. * Added sip_api_get_time() and sip_api_from_time() to the public API. * Added sip_api_get_frame() to the public API. * Added sip_api_check_plugin_for_type() to the public API. * Added sip_api_unicode_new(), sip_api_unicode_write() and * sip_api_unicode_data() to the public API. * Added sip_api_get_buffer_info() and sip_api_relese_buffer_info() to the * public API. * Added sip_api_call_procedure_method() to the public API. * Added sip_api_is_owned_by_python() to the private API. * Added sip_api_is_derived_class() to the private API. * Removed the im_version member from sipImportedModuleDef. * Removed the im_module member from sipImportedModuleDef. * Removed the em_version member from sipExportedModuleDef. * Removed the em_virthandlers member from sipExportedModuleDef. * Re-ordered the API functions. * * 11.3 Added sip_api_get_interpreter() to the public API. * * 11.2 Added sip_api_get_reference() to the private API. * * 11.1 Added sip_api_invoke_slot_ex(). * * 11.0 Added the pyqt5QtSignal and pyqt5ClassTypeDef structures. * Removed qt_interface from pyqt4ClassTypeDef. * Added hack to pyqt4QtSignal. * * 10.1 Added ctd_final to sipClassTypeDef. * Added ctd_init_mixin to sipClassTypeDef. * Added sip_api_get_mixin_address() to the public API. * Added sip_api_convert_from_new_pytype() to the public API. * Added sip_api_convert_to_array() to the public API. * Added sip_api_convert_to_typed_array() to the public API. * Added sip_api_register_proxy_resolver() to the public API. * Added sip_api_init_mixin() to the private API. * Added qt_interface to pyqt4ClassTypeDef. * * 10.0 Added sip_api_set_destroy_on_exit(). * Added sip_api_enable_autoconversion(). * Removed sip_api_call_error_handler_old(). * Removed sip_api_start_thread(). * * 9.2 Added sip_gilstate_t and SIP_RELEASE_GIL to the public API. * Renamed sip_api_call_error_handler() to * sip_api_call_error_handler_old(). * Added the new sip_api_call_error_handler() to the private API. * * 9.1 Added the capsule type. * Added the 'z' format character to sip_api_build_result(). * Added the 'z', '!' and '$' format characters to * sip_api_parse_result_ex(). * * 9.0 Changed the sipVariableGetterFunc signature. * Added sip_api_parse_result_ex() to the private API. * Added sip_api_call_error_handler() to the private API. * Added em_virterrorhandlers to sipExportedModuleDef. * Re-ordered the API functions. * * 8.1 Revised the sipVariableDef structure. * sip_api_get_address() is now part of the public API. * * 8.0 Changed the size of the sipSimpleWrapper structure. * Added sip_api_get_address(). * * 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 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 12 #define SIP_API_MINOR_NR 3 /* The name of the sip module. */ #define SIP_MODULE_NAME "@CFG_MODULE_NAME@" /* * Qt includes this typedef and its meta-object system explicitly converts * types to uint. If these correspond to signal arguments then that conversion * is exposed. Therefore SIP generates code that uses it. This definition is * for the cases that SIP is generating non-Qt related bindings with compilers * that don't include it themselves (i.e. MSVC). */ typedef unsigned int uint; /* Some Python compatibility stuff. */ #if PY_VERSION_HEX >= 0x02050000 #define SIP_SSIZE_T Py_ssize_t #define SIP_SSIZE_T_FORMAT "%zd" #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_SSIZE_T_FORMAT "%d" #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_Check PyLong_Check #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_AsString PyBytes_AsString #define SIPBytes_Size PyBytes_Size #define SIPBytes_AS_STRING PyBytes_AS_STRING #define SIPBytes_GET_SIZE PyBytes_GET_SIZE #if PY_MINOR_VERSION >= 1 #define SIP_USE_PYCAPSULE #endif #if PY_MINOR_VERSION < 2 #define SIP_SUPPORT_PYCOBJECT #endif #else #define SIPLong_Check PyInt_Check #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_AsString PyString_AsString #define SIPBytes_Size PyString_Size #define SIPBytes_AS_STRING PyString_AS_STRING #define SIPBytes_GET_SIZE PyString_GET_SIZE #if PY_MINOR_VERSION >= 7 #define SIP_USE_PYCAPSULE #endif #define SIP_SUPPORT_PYCOBJECT #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 #if defined(SIP_USE_PYCAPSULE) #define SIPCapsule_FromVoidPtr(p, n) PyCapsule_New((p), (n), NULL) #define SIPCapsule_AsVoidPtr(p, n) PyCapsule_GetPointer((p), (n)) #else #define SIPCapsule_FromVoidPtr(p, n) sipConvertFromVoidPtr((p)) #define SIPCapsule_AsVoidPtr(p, n) sipConvertToVoidPtr((p)) #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 /* * Forward declarations of types. */ struct _sipBufferDef; typedef struct _sipBufferDef sipBufferDef; struct _sipBufferInfoDef; typedef struct _sipBufferInfoDef sipBufferInfoDef; struct _sipCFunctionDef; typedef struct _sipCFunctionDef sipCFunctionDef; struct _sipDateDef; typedef struct _sipDateDef sipDateDef; struct _sipEnumTypeObject; typedef struct _sipEnumTypeObject sipEnumTypeObject; struct _sipMethodDef; typedef struct _sipMethodDef sipMethodDef; struct _sipSimpleWrapper; typedef struct _sipSimpleWrapper sipSimpleWrapper; struct _sipTimeDef; typedef struct _sipTimeDef sipTimeDef; struct _sipTypeDef; typedef struct _sipTypeDef sipTypeDef; struct _sipWrapperType; typedef struct _sipWrapperType sipWrapperType; struct _sipWrapper; typedef struct _sipWrapper sipWrapper; /* * The different events a handler can be registered for. */ typedef enum { sipEventWrappedInstance, /* After wrapping a C/C++ instance. */ sipEventCollectingWrapper, /* When garbage collecting a wrapper object. */ sipEventNrEvents } sipEventType; /* * The event handlers. */ typedef void (*sipWrappedInstanceEventHandler)(void *sipCpp); typedef void (*sipCollectingWrapperEventHandler)(sipSimpleWrapper *sipSelf); /* * The operation an access function is being asked to perform. */ typedef enum { UnguardedPointer, /* Return the unguarded pointer. */ GuardedPointer, /* Return the guarded pointer, ie. 0 if it has gone. */ ReleaseGuard /* Release the guard, if any. */ } AccessFuncOp; /* * Some convenient function pointers. */ typedef void *(*sipInitFunc)(sipSimpleWrapper *, PyObject *, PyObject *, PyObject **, PyObject **, PyObject **); typedef int (*sipFinalFunc)(PyObject *, void *, PyObject *, PyObject **); typedef void *(*sipAccessFunc)(sipSimpleWrapper *, AccessFuncOp); typedef int (*sipTraverseFunc)(void *, visitproc, void *); typedef int (*sipClearFunc)(void *); #if PY_MAJOR_VERSION >= 3 typedef int (*sipGetBufferFuncLimited)(PyObject *, void *, sipBufferDef *); typedef void (*sipReleaseBufferFuncLimited)(PyObject *, void *); #if !defined(Py_LIMITED_API) typedef int (*sipGetBufferFunc)(PyObject *, void *, Py_buffer *, int); typedef void (*sipReleaseBufferFunc)(PyObject *, void *, Py_buffer *); #endif #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 sipTypeDef *); typedef const sipTypeDef *(*sipSubClassConvertFunc)(void **); typedef int (*sipConvertToFunc)(PyObject *, void **, int *, PyObject *); typedef PyObject *(*sipConvertFromFunc)(void *, PyObject *); typedef void (*sipVirtErrorHandlerFunc)(sipSimpleWrapper *, sip_gilstate_t); typedef int (*sipVirtHandlerFunc)(sip_gilstate_t, sipVirtErrorHandlerFunc, sipSimpleWrapper *, PyObject *, ...); typedef void (*sipAssignFunc)(void *, SIP_SSIZE_T, 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 sipTypeDef *, PyObject *); typedef PyObject *(*sipVariableGetterFunc)(void *, PyObject *, PyObject *); typedef int (*sipVariableSetterFunc)(void *, PyObject *, PyObject *); typedef void *(*sipProxyResolverFunc)(void *); typedef int (*sipNewUserTypeFunc)(sipWrapperType *); #if !defined(Py_LIMITED_API) || PY_VERSION_HEX < 0x03020000 /* * The meta-type of a wrapper type. */ struct _sipWrapperType { /* * The super-metatype. This must be first in the structure so that it can * be cast to a PyTypeObject *. */ PyHeapTypeObject super; /* Set if the type is a user implemented Python sub-class. */ unsigned wt_user_type : 1; /* Set if the type's dictionary contains all lazy attributes. */ unsigned wt_dict_complete : 1; /* Unused and available for future use. */ unsigned wt_unused : 30; /* The generated type structure. */ sipTypeDef *wt_td; /* The list of init extenders. */ struct _sipInitExtenderDef *wt_iextend; /* The handler called whenever a new user type has been created. */ sipNewUserTypeFunc wt_new_user_type_handler; /* * For the user to use. Note that any data structure will leak if the * type is garbage collected. */ void *wt_user_data; }; /* * The type of a simple C/C++ wrapper object. */ struct _sipSimpleWrapper { PyObject_HEAD /* * The data, initially a pointer to the C/C++ object, as interpreted by the * access function. */ void *data; /* The optional access function. */ sipAccessFunc access_func; /* Object flags. */ unsigned sw_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; /* The main instance if this is a mixin. */ PyObject *mixin_main; /* Next object at this address. */ struct _sipSimpleWrapper *next; }; /* * The type of a C/C++ wrapper object that supports parent/child relationships. */ 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; }; /* * The meta-type of an enum type. (This is exposed only to support the * deprecated sipConvertFromNamedEnum() macro.) */ 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; }; #endif /* * 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 structure populated by %BIGetBufferCode when the limited API is enabled. */ struct _sipBufferDef { /* The address of the buffer. */ void *bd_buffer; /* The length of the buffer. */ SIP_SSIZE_T bd_length; /* Set if the buffer is read-only. */ int bd_readonly; }; /* * The structure describing a Python buffer. */ struct _sipBufferInfoDef { /* This is internal to sip. */ void *bi_internal; /* The address of the buffer. */ void *bi_buf; /* A reference to the object implementing the buffer interface. */ PyObject *bi_obj; /* The length of the buffer in bytes. */ SIP_SSIZE_T bi_len; /* The number of dimensions. */ int bi_ndim; /* The format of each element of the buffer. */ char *bi_format; }; /* * The structure describing a Python C function. */ struct _sipCFunctionDef { /* The C function. */ PyMethodDef *cf_function; /* The optional bound object. */ PyObject *cf_self; }; /* * The structure describing a Python method. */ struct _sipMethodDef { /* The function that implements the method. */ PyObject *pm_function; /* The bound object. */ PyObject *pm_self; #if PY_MAJOR_VERSION < 3 /* The class. */ PyObject *pm_class; #endif }; /* * The structure describing a Python date. */ struct _sipDateDef { /* The year. */ int pd_year; /* The month (1-12). */ int pd_month; /* The day (1-31). */ int pd_day; }; /* * The structure describing a Python time. */ struct _sipTimeDef { /* The hour (0-23). */ int pt_hour; /* The minute (0-59). */ int pt_minute; /* The second (0-59). */ int pt_second; /* The microsecond (0-999999). */ int pt_microsecond; }; /* * 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. New slots must be added to the end, * otherwise the major version of the internal ABI must be changed. */ 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__ */ setattr_slot, /* __setattr__, __delattr__ */ matmul_slot, /* __matmul__ (for Python v3.5 and later) */ imatmul_slot, /* __imatmul__ (for Python v3.5 and later) */ await_slot, /* __await__ (for Python v3.5 and later) */ aiter_slot, /* __aiter__ (for Python v3.5 and later) */ anext_slot, /* __anext__ (for Python v3.5 and later) */ } 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 or property. */ typedef enum { PropertyVariable, /* A property. */ InstanceVariable, /* An instance variable. */ ClassVariable /* A class (i.e. static) variable. */ } sipVariableType; typedef struct _sipVariableDef { /* The type of variable. */ sipVariableType vd_type; /* The name. */ const char *vd_name; /* * The getter. If this is a variable (rather than a property) then the * actual type is sipVariableGetterFunc. */ PyMethodDef *vd_getter; /* * The setter. If this is a variable (rather than a property) then the * actual type is sipVariableSetterFunc. It is NULL if the property cannot * be set or the variable is const. */ PyMethodDef *vd_setter; /* The property deleter. */ PyMethodDef *vd_deleter; /* The docstring. */ const char *vd_docstring; } sipVariableDef; /* * The information describing a type, either a C++ class (or C struct), a C++ * namespace, a mapped type or a named enum. */ 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; /* Any additional fixed data generated by a plugin. */ void *td_plugin_data; }; /* * 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. */ #if defined(Py_LIMITED_API) sipGetBufferFuncLimited ctd_getbuffer; #else sipGetBufferFunc ctd_getbuffer; #endif /* The release buffer function. */ #if defined(Py_LIMITED_API) sipReleaseBufferFuncLimited ctd_releasebuffer; #else sipReleaseBufferFunc ctd_releasebuffer; #endif #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 struct. */ sipReleaseFunc ctd_release; /* The cast function, 0 if a C struct. */ sipCastFunc ctd_cast; /* The optional convert to function. */ sipConvertToFunc ctd_cto; /* The optional convert from function. */ sipConvertFromFunc ctd_cfrom; /* The next namespace extender. */ struct _sipClassTypeDef *ctd_nsextender; /* The pickle function. */ sipPickleFunc ctd_pickle; /* The finalisation function. */ sipFinalFunc ctd_final; /* The mixin initialisation function. */ initproc ctd_init_mixin; } 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; /* * Defines a virtual error handler. */ typedef struct _sipVirtErrorHandlerDef { /* The name of the handler. */ const char *veh_name; /* The handler function. */ sipVirtErrorHandlerFunc veh_handler; } sipVirtErrorHandlerDef; /* * Defines a type imported from another module. */ typedef union _sipImportedTypeDef { /* The type name before the module is imported. */ const char *it_name; /* The type after the module is imported. */ sipTypeDef *it_td; } sipImportedTypeDef; /* * Defines a virtual error handler imported from another module. */ typedef union _sipImportedVirtErrorHandlerDef { /* The handler name before the module is imported. */ const char *iveh_name; /* The handler after the module is imported. */ sipVirtErrorHandlerFunc iveh_handler; } sipImportedVirtErrorHandlerDef; /* * Defines an exception imported from another module. */ typedef union _sipImportedExceptionDef { /* The exception name before the module is imported. */ const char *iexc_name; /* The exception object after the module is imported. */ PyObject *iexc_object; } sipImportedExceptionDef; /* * The information describing an imported module. */ typedef struct _sipImportedModuleDef { /* The module name. */ const char *im_name; /* The types imported from the module. */ sipImportedTypeDef *im_imported_types; /* The virtual error handlers imported from the module. */ sipImportedVirtErrorHandlerDef *im_imported_veh; /* The exceptions imported from the module. */ sipImportedExceptionDef *im_imported_exceptions; } 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 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 error handlers. */ sipVirtErrorHandlerDef *em_virterrorhandlers; /* 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. * This is also used as a hack to add (or fix) other types rather than add a * new table type and so requiring a new major version of the API. */ 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'. 'w' and 'W' are also * used to support the fix for wchar_t. */ 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, ...); void (*api_call_procedure_method)(sip_gilstate_t, sipVirtErrorHandlerFunc, sipSimpleWrapper *, PyObject *, const char *, ...); 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); /* * The following are deprecated parts of the public API. */ int (*api_can_convert_to_enum)(PyObject *pyObj, const sipTypeDef *td); /* * The following are part of the public API. */ 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); void *(*api_get_address)(struct _sipSimpleWrapper *w); void (*api_set_destroy_on_exit)(int); int (*api_enable_autoconversion)(const sipTypeDef *td, int enable); void *(*api_get_mixin_address)(struct _sipSimpleWrapper *w, const sipTypeDef *td); PyObject *(*api_convert_from_new_pytype)(void *cpp, PyTypeObject *py_type, sipWrapper *owner, sipSimpleWrapper **selfp, const char *fmt, ...); PyObject *(*api_convert_to_typed_array)(void *data, const sipTypeDef *td, const char *format, size_t stride, SIP_SSIZE_T len, int flags); PyObject *(*api_convert_to_array)(void *data, const char *format, SIP_SSIZE_T len, int flags); int (*api_register_proxy_resolver)(const sipTypeDef *td, sipProxyResolverFunc resolver); PyInterpreterState *(*api_get_interpreter)(); sipNewUserTypeFunc (*api_set_new_user_type_handler)(const sipTypeDef *, sipNewUserTypeFunc); void (*api_set_type_user_data)(sipWrapperType *, void *); void *(*api_get_type_user_data)(const sipWrapperType *); PyObject *(*api_py_type_dict)(const PyTypeObject *); const char *(*api_py_type_name)(const PyTypeObject *); int (*api_get_method)(PyObject *, sipMethodDef *); PyObject *(*api_from_method)(const sipMethodDef *); int (*api_get_c_function)(PyObject *, sipCFunctionDef *); int (*api_get_date)(PyObject *, sipDateDef *); PyObject *(*api_from_date)(const sipDateDef *); int (*api_get_datetime)(PyObject *, sipDateDef *, sipTimeDef *); PyObject *(*api_from_datetime)(const sipDateDef *, const sipTimeDef *); int (*api_get_time)(PyObject *, sipTimeDef *); PyObject *(*api_from_time)(const sipTimeDef *); int (*api_is_user_type)(const sipWrapperType *); struct _frame *(*api_get_frame)(int); int (*api_check_plugin_for_type)(const sipTypeDef *, const char *); PyObject *(*api_unicode_new)(SIP_SSIZE_T, unsigned, int *, void **); void (*api_unicode_write)(int, void *, int, unsigned); void *(*api_unicode_data)(PyObject *, int *, SIP_SSIZE_T *); int (*api_get_buffer_info)(PyObject *, sipBufferInfoDef *); void (*api_release_buffer_info)(sipBufferInfoDef *); PyObject *(*api_get_user_object)(const sipSimpleWrapper *); void (*api_set_user_object)(sipSimpleWrapper *, PyObject *); /* * 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, ...); /* * The following are part of the public API. */ void (*api_instance_destroyed)(sipSimpleWrapper *sipSelf); /* * The following are not part of the public API. */ 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_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); int (*api_parse_result_ex)(sip_gilstate_t, sipVirtErrorHandlerFunc, sipSimpleWrapper *, PyObject *method, PyObject *res, const char *fmt, ...); void (*api_call_error_handler)(sipVirtErrorHandlerFunc, sipSimpleWrapper *, sip_gilstate_t); int (*api_init_mixin)(PyObject *self, PyObject *args, PyObject *kwds, const sipClassTypeDef *ctd); PyObject *(*api_get_reference)(PyObject *self, int key); int (*api_is_owned_by_python)(sipSimpleWrapper *); int (*api_is_derived_class)(sipSimpleWrapper *); /* * 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); PyObject *(*api_invoke_slot_ex)(const sipSlot *slot, PyObject *sigargs, int check_receiver); 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 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 are part of the public API. */ int (*api_enable_gc)(int enable); void (*api_print_object)(PyObject *o); int (*api_register_event_handler)(sipEventType type, const sipTypeDef *td, void *handler); int (*api_convert_to_enum)(PyObject *obj, const sipTypeDef *td); int (*api_convert_to_bool)(PyObject *obj); int (*api_enable_overflow_checking)(int enable); char (*api_long_as_char)(PyObject *o); signed char (*api_long_as_signed_char)(PyObject *o); unsigned char (*api_long_as_unsigned_char)(PyObject *o); short (*api_long_as_short)(PyObject *o); unsigned short (*api_long_as_unsigned_short)(PyObject *o); int (*api_long_as_int)(PyObject *o); unsigned int (*api_long_as_unsigned_int)(PyObject *o); long (*api_long_as_long)(PyObject *o); #if defined(HAVE_LONG_LONG) PY_LONG_LONG (*api_long_as_long_long)(PyObject *o); unsigned PY_LONG_LONG (*api_long_as_unsigned_long_long)(PyObject *o); #else void *api_long_as_long_long; void *api_long_as_unsigned_long_long; #endif } 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 flags that can be passed to sipConvertToArray(). These are held * in sw_flags. */ #define SIP_READ_ONLY 0x01 /* The array is read-only. */ #define SIP_OWNS_MEMORY 0x02 /* The array owns its memory. */ /* * These are the state flags returned by %ConvertToTypeCode. Note that the * values share the same "flagspace" as the contents of sw_flags. */ #define SIP_TEMPORARY 0x01 /* A temporary instance. */ #define SIP_DERIVED_CLASS 0x02 /* 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. */ /* These are held in sw_flags. */ #define SIP_INDIRECT 0x0004 /* If there is a level of indirection. */ #define SIP_ACCFUNC 0x0008 /* If there is an access function. */ #define SIP_NOT_IN_MAP 0x0010 /* If Python object is not in the map. */ #if !defined(Py_LIMITED_API) || PY_VERSION_HEX < 0x03020000 #define SIP_PY_OWNED 0x0020 /* If owned by Python. */ #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 SIP_ALIAS 0x0200 /* If it is an alias. */ #define SIP_CREATED 0x0400 /* If the C/C++ object has been created. */ #define sipIsDerived(sw) ((sw)->sw_flags & SIP_DERIVED_CLASS) #define sipIsIndirect(sw) ((sw)->sw_flags & SIP_INDIRECT) #define sipIsAccessFunc(sw) ((sw)->sw_flags & SIP_ACCFUNC) #define sipNotInMap(sw) ((sw)->sw_flags & SIP_NOT_IN_MAP) #define sipSetNotInMap(sw) ((sw)->sw_flags |= SIP_NOT_IN_MAP) #define sipIsPyOwned(sw) ((sw)->sw_flags & SIP_PY_OWNED) #define sipSetPyOwned(sw) ((sw)->sw_flags |= SIP_PY_OWNED) #define sipResetPyOwned(sw) ((sw)->sw_flags &= ~SIP_PY_OWNED) #define sipCppHasRef(sw) ((sw)->sw_flags & SIP_CPP_HAS_REF) #define sipSetCppHasRef(sw) ((sw)->sw_flags |= SIP_CPP_HAS_REF) #define sipResetCppHasRef(sw) ((sw)->sw_flags &= ~SIP_CPP_HAS_REF) #define sipPossibleProxy(sw) ((sw)->sw_flags & SIP_POSSIBLE_PROXY) #define sipSetPossibleProxy(sw) ((sw)->sw_flags |= SIP_POSSIBLE_PROXY) #define sipIsAlias(sw) ((sw)->sw_flags & SIP_ALIAS) #define sipWasCreated(sw) ((sw)->sw_flags & SIP_CREATED) #endif #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_SCOPED_ENUM 0x0004 /* If the type is a scoped 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. */ #define SIP_TYPE_NONLAZY 0x0080 /* If the type has a non-lazy method. */ #define SIP_TYPE_SUPER_INIT 0x0100 /* If the instance's super init should be called. */ #define SIP_TYPE_LIMITED_API 0x0200 /* Use the limited API. If this is more generally required it may need to be moved to the module definition. */ /* * 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 sipTypeIsScopedEnum(td) (((td)->td_flags & SIP_TYPE_TYPE_MASK) == SIP_TYPE_SCOPED_ENUM) #define sipTypeAsPyTypeObject(td) ((td)->u.td_py_type) #define sipTypeName(td) sipNameFromPool((td)->td_module, (td)->td_cname) #define sipTypePluginData(td) ((td)->td_plugin_data) /* * Note that this was never actually documented as being part of the public * API. It is now deprecated. sipIsUserType() should be used instead. */ #define sipIsExactWrappedType(wt) (sipTypeAsPyTypeObject((wt)->wt_td) == (PyTypeObject *)(wt)) #if PY_VERSION_HEX >= 0x03020000 #define sipConvertFromSliceObject PySlice_GetIndicesEx #else #define sipConvertFromSliceObject(o, len, start, stop, step, slen) \ PySlice_GetIndicesEx((PySliceObject *)(o), (len), (start), (stop), \ (step), (slen)) #endif /* * 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) #define sipTypeHasNonlazyMethod(td) ((td)->td_flags & SIP_TYPE_NONLAZY) #define sipTypeCallSuperInit(td) ((td)->td_flags & SIP_TYPE_SUPER_INIT) #define sipTypeUseLimitedAPI(td) ((td)->td_flags & SIP_TYPE_LIMITED_API) /* * 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 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; /* * The hack to apply when built against Qt5: * * 0 - no hack * 1 - add an optional None * 2 - add an optional [] * 3 - add an optional False */ int hack; } pyqt4QtSignal; /* * This is the PyQt4-specific extension to the generated class type structure. */ typedef struct _pyqt4ClassPluginDef { /* A pointer to the QObject sub-class's staticMetaObject class variable. */ const void *static_metaobject; /* * A set of flags. At the moment only bit 0 is used to say if the type is * derived from QFlags. */ unsigned flags; /* * The table of signals emitted by the type. These are grouped by signal * name. */ const pyqt4QtSignal *qt_signals; } pyqt4ClassPluginDef; /* * The following are PyQt5-specific extensions. In SIP v5 they will be pushed * out to a plugin supplied by PyQt5. */ /* * The description of a Qt signal for PyQt5. */ typedef int (*pyqt5EmitFunc)(void *, PyObject *); typedef struct _pyqt5QtSignal { /* The normalised 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; /* * If the signal has optional arguments then this function will implement * emit() for the signal. */ pyqt5EmitFunc emitter; } pyqt5QtSignal; /* * This is the PyQt5-specific extension to the generated class type structure. */ typedef struct _pyqt5ClassPluginDef { /* A pointer to the QObject sub-class's staticMetaObject class variable. */ const void *static_metaobject; /* * A set of flags. At the moment only bit 0 is used to say if the type is * derived from QFlags. */ unsigned flags; /* * The table of signals emitted by the type. These are grouped by signal * name. */ const pyqt5QtSignal *qt_signals; /* The name of the interface that the class defines. */ const char *qt_interface; } pyqt5ClassPluginDef; #ifdef __cplusplus } #endif #endif sip-4.19.7/siplib/sipint.h0000644000076500000240000001404113231604406015426 0ustar philstaff00000000000000/* * This file defines the SIP library internal interfaces. * * Copyright (c) 2017 Riverbank Computing Limited * * 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 #include #include "sip.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); PyObject *sipMethodDescr_Copy(PyObject *orig, PyObject *mixin_name); extern PyTypeObject sipVariableDescr_Type; PyObject *sipVariableDescr_New(sipVariableDef *vd, const sipTypeDef *td, const sipContainerDef *cod); PyObject *sipVariableDescr_Copy(PyObject *orig, PyObject *mixin_name); /* * 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); /* * Support for int convertors. */ PyObject *sipEnableOverflowChecking(PyObject *self, PyObject *args); int sip_api_enable_overflow_checking(int enable); int sip_api_convert_to_bool(PyObject *o); char sip_api_long_as_char(PyObject *o); signed char sip_api_long_as_signed_char(PyObject *o); unsigned char sip_api_long_as_unsigned_char(PyObject *o); short sip_api_long_as_short(PyObject *o); unsigned short sip_api_long_as_unsigned_short(PyObject *o); int sip_api_long_as_int(PyObject *o); unsigned int sip_api_long_as_unsigned_int(PyObject *o); long sip_api_long_as_long(PyObject *o); unsigned long sip_api_long_as_unsigned_long(PyObject *o); #if defined(HAVE_LONG_LONG) PY_LONG_LONG sip_api_long_as_long_long(PyObject *o); unsigned PY_LONG_LONG sip_api_long_as_unsigned_long_long(PyObject *o); #endif 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_address(sipSimpleWrapper *w); 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_instance_destroyed(sipSimpleWrapper *sipSelf); void sip_api_end_thread(void); void *sip_api_force_convert_to_type(PyObject *pyObj, const sipTypeDef *td, PyObject *transferObj, int flags, int *statep, int *iserrp); 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); PyObject *sip_api_invoke_slot_ex(const sipSlot *slot, PyObject *sigargs, int no_receiver_check); 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. */ sipClassTypeDef *sipGetGeneratedClassType(const sipEncodedTypeDef *enc, const sipClassTypeDef *ctd); void sipSaveMethod(sipPyMethod *pm,PyObject *meth); int sipGetPending(void **pp, sipWrapper **op, int *fp); int sipIsPending(); PyObject *sipWrapInstance(void *cpp, PyTypeObject *py_type, PyObject *args, sipWrapper *owner, int flags); 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); #ifdef __cplusplus } #endif #endif sip-4.19.7/siplib/siplib.c.in0000644000076500000240000131372713231604406016020 0ustar philstaff00000000000000/* * SIP library code. * * Copyright (c) 2017 Riverbank Computing Limited * * 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 #include #include #include #include #include #include #include #include "sip.h" #include "sipint.h" #include "array.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_as_async (Python v3.5), 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 */ 0, /* tp_is_gc */ 0, /* tp_bases */ 0, /* tp_mro */ 0, /* tp_cache */ 0, /* tp_subclasses */ 0, /* tp_weaklist */ 0, /* tp_del */ 0, /* tp_version_tag */ #if PY_VERSION_HEX >= 0x03040000 0, /* tp_finalize */ #endif }; /* * 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_as_async (Python v3.5), 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 */ 0, /* tp_is_gc */ 0, /* tp_bases */ 0, /* tp_mro */ 0, /* tp_cache */ 0, /* tp_subclasses */ 0, /* tp_weaklist */ 0, /* tp_del */ #if PY_VERSION_HEX >= 0x02060000 0, /* tp_version_tag */ #endif #if PY_VERSION_HEX >= 0x03040000 0, /* tp_finalize */ #endif }, #if PY_VERSION_HEX >= 0x03050000 { 0, /* am_await */ 0, /* am_aiter */ 0, /* am_anext */ }, #endif { 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 0, /* nb_int */ 0, /* nb_reserved (Python v3), nb_long (Python v2) */ 0, /* nb_float */ #if PY_MAJOR_VERSION < 3 0, /* nb_oct */ 0, /* 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 */ #if PY_VERSION_HEX >= 0x02020000 0, /* nb_floor_divide */ 0, /* nb_true_divide */ 0, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ #endif #if PY_VERSION_HEX >= 0x02050000 0, /* nb_index */ #endif #if PY_VERSION_HEX >= 0x03050000 0, /* nb_matrix_multiply */ 0, /* nb_inplace_matrix_multiply */ #endif }, { 0, /* mp_length */ 0, /* mp_subscript */ 0, /* mp_ass_subscript */ }, { 0, /* sq_length */ 0, /* sq_concat */ 0, /* sq_repeat */ 0, /* sq_item */ 0, /* was_sq_slice */ 0, /* sq_ass_item */ 0, /* was_sq_ass_slice */ 0, /* sq_contains */ 0, /* sq_inplace_concat */ 0, /* sq_inplace_repeat */ }, { #if PY_MAJOR_VERSION >= 3 0, /* bf_getbuffer */ 0, /* bf_releasebuffer */ #else 0, /* bf_getreadbuffer */ 0, /* bf_getwritebuffer */ 0, /* bf_getsegcount */ 0, /* bf_getcharbuffer */ 0, /* bf_getbuffer */ 0, /* bf_releasebuffer */ #endif }, 0, /* ht_name */ 0, /* ht_slots */ #if PY_MAJOR_VERSION >= 3 0, /* ht_qualname */ 0, /* ht_cached_keys */ #endif #if !defined(STACKLESS) }, #endif 0, /* wt_user_type */ 0, /* wt_dict_complete */ 0, /* wt_unused */ 0, /* wt_td */ 0, /* wt_iextend */ 0, /* wt_new_user_type_handler */ 0, /* wt_user_data */ }; 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 void sip_api_call_procedure_method(sip_gilstate_t gil_state, sipVirtErrorHandlerFunc error_handler, sipSimpleWrapper *py_self, 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 int sip_api_can_convert_to_enum(PyObject *pyObj, const sipTypeDef *td); static int sip_api_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 PyObject *sip_api_convert_from_new_pytype(void *cpp, PyTypeObject *py_type, sipWrapper *owner, sipSimpleWrapper **selfp, const char *fmt, ...); 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_ex(sip_gilstate_t gil_state, sipVirtErrorHandlerFunc error_handler, sipSimpleWrapper *py_self, PyObject *method, PyObject *res, const char *fmt, ...); static int sip_api_parse_result(int *isErr, PyObject *method, PyObject *res, const char *fmt, ...); static void sip_api_call_error_handler(sipVirtErrorHandlerFunc error_handler, sipSimpleWrapper *py_self, sip_gilstate_t gil_state); 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 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 PyObject *sip_api_get_reference(PyObject *self, int key); static int sip_api_is_owned_by_python(sipSimpleWrapper *sw); static int sip_api_is_derived_class(sipSimpleWrapper *sw); static void sip_api_add_exception(sipErrorState es, PyObject **parseErrp); static void sip_api_set_destroy_on_exit(int value); static int sip_api_enable_autoconversion(const sipTypeDef *td, int enable); static int sip_api_init_mixin(PyObject *self, PyObject *args, PyObject *kwds, const sipClassTypeDef *ctd); static void *sip_api_get_mixin_address(sipSimpleWrapper *w, const sipTypeDef *td); static int sip_api_register_proxy_resolver(const sipTypeDef *td, sipProxyResolverFunc resolver); static PyInterpreterState *sip_api_get_interpreter(); static sipNewUserTypeFunc sip_api_set_new_user_type_handler( const sipTypeDef *td, sipNewUserTypeFunc handler); static void sip_api_set_type_user_data(sipWrapperType *wt, void *data); static void *sip_api_get_type_user_data(const sipWrapperType *wt); static PyObject *sip_api_py_type_dict(const PyTypeObject *py_type); static const char *sip_api_py_type_name(const PyTypeObject *py_type); static int sip_api_get_method(PyObject *obj, sipMethodDef *method); static PyObject *sip_api_from_method(const sipMethodDef *method); static int sip_api_get_c_function(PyObject *obj, sipCFunctionDef *c_function); static int sip_api_get_date(PyObject *obj, sipDateDef *date); static PyObject *sip_api_from_date(const sipDateDef *date); static int sip_api_get_datetime(PyObject *obj, sipDateDef *date, sipTimeDef *time); static PyObject *sip_api_from_datetime(const sipDateDef *date, const sipTimeDef *time); static int sip_api_get_time(PyObject *obj, sipTimeDef *time); static PyObject *sip_api_from_time(const sipTimeDef *time); static int sip_api_is_user_type(const sipWrapperType *wt); static struct _frame *sip_api_get_frame(int); static int sip_api_check_plugin_for_type(const sipTypeDef *td, const char *name); static PyObject *sip_api_unicode_new(SIP_SSIZE_T len, unsigned maxchar, int *kind, void **data); static void sip_api_unicode_write(int kind, void *data, int index, unsigned value); static void *sip_api_unicode_data(PyObject *obj, int *char_size, SIP_SSIZE_T *len); static int sip_api_get_buffer_info(PyObject *obj, sipBufferInfoDef *bi); static void sip_api_release_buffer_info(sipBufferInfoDef *bi); static PyObject *sip_api_get_user_object(const sipSimpleWrapper *sw); static void sip_api_set_user_object(sipSimpleWrapper *sw, PyObject *user); static int sip_api_enable_gc(int enable); static void sip_api_print_object(PyObject *o); static int sip_api_register_event_handler(sipEventType type, const sipTypeDef *td, void *handler); /* * 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_call_procedure_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, sip_api_get_address, sip_api_set_destroy_on_exit, sip_api_enable_autoconversion, sip_api_get_mixin_address, sip_api_convert_from_new_pytype, sip_api_convert_to_typed_array, sip_api_convert_to_array, sip_api_register_proxy_resolver, sip_api_get_interpreter, sip_api_set_new_user_type_handler, sip_api_set_type_user_data, sip_api_get_type_user_data, sip_api_py_type_dict, sip_api_py_type_name, sip_api_get_method, sip_api_from_method, sip_api_get_c_function, sip_api_get_date, sip_api_from_date, sip_api_get_datetime, sip_api_from_datetime, sip_api_get_time, sip_api_from_time, sip_api_is_user_type, sip_api_get_frame, sip_api_check_plugin_for_type, sip_api_unicode_new, sip_api_unicode_write, sip_api_unicode_data, sip_api_get_buffer_info, sip_api_release_buffer_info, sip_api_get_user_object, sip_api_set_user_object, /* * The following are not part of the public API. */ sip_api_init_module, sip_api_parse_args, sip_api_parse_pair, /* * The following are part of the public API. */ sip_api_instance_destroyed, /* * The following are not part of the public API. */ 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_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, sip_api_parse_result_ex, sip_api_call_error_handler, sip_api_init_mixin, sip_api_get_reference, sip_api_is_owned_by_python, sip_api_is_derived_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_invoke_slot_ex, sip_api_save_slot, sip_api_clear_any_slot_reference, sip_api_visit_slot, /* * 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 are part of the public API. */ sip_api_enable_gc, sip_api_print_object, sip_api_register_event_handler, sip_api_convert_to_enum, sip_api_convert_to_bool, sip_api_enable_overflow_checking, sip_api_long_as_char, sip_api_long_as_signed_char, sip_api_long_as_unsigned_char, sip_api_long_as_short, sip_api_long_as_unsigned_short, sip_api_long_as_int, sip_api_long_as_unsigned_int, sip_api_long_as_long, #if defined(HAVE_LONG_LONG) sip_api_long_as_long_long, sip_api_long_as_unsigned_long_long, #else 0, 0, #endif }; #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, Overflow } 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; /* * An entry in the linked list of proxy resolvers. */ typedef struct _sipProxyResolver { const sipTypeDef *td; /* The type the resolver handles. */ sipProxyResolverFunc resolver; /* The resolver. */ struct _sipProxyResolver *next; /* The next in the list. */ } sipProxyResolver; /* * An entry in the linked list of event handlers. */ typedef struct _sipEventHandler { const sipClassTypeDef *ctd; /* The type the handler handles. */ void *handler; /* The handler. */ struct _sipEventHandler *next; /* The next in the list. */ } sipEventHandler; /***************************************************************************** * 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_as_async (Python v3.5), 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 */ 0, /* tp_is_gc */ 0, /* tp_bases */ 0, /* tp_mro */ 0, /* tp_cache */ 0, /* tp_subclasses */ 0, /* tp_weaklist */ 0, /* tp_del */ 0, /* tp_version_tag */ #if PY_VERSION_HEX >= 0x03040000 0, /* tp_finalize */ #endif }; /* * Remove these in SIP v5. */ sipQtAPI *sipQtSupport = NULL; sipTypeDef *sipQObjectType; static int got_kw_handler = FALSE; static int (*kw_handler)(PyObject *, void *, PyObject *); /* * 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 **unused_backdoor = NULL; /* For passing dict of unused arguments. */ static PyObject *init_name = NULL; /* '__init__'. */ static PyObject *empty_tuple; /* The empty tuple. */ 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 sipProxyResolver *proxyResolvers = NULL; /* The list of proxy resolvers. */ static sipPyObject *sipRegisteredPyTypes = NULL; /* Registered Python types. */ static sipPyObject *sipDisabledAutoconversions = NULL; /* Python types whose auto-conversion is disabled. */ static PyInterpreterState *sipInterpreter = NULL; /* The interpreter. */ static int destroy_on_exit = TRUE; /* Destroy owned objects on exit. */ static sipEventHandler *event_handlers[sipEventNrEvents]; /* The event handler lists. */ static void addClassSlots(sipWrapperType *wt, const sipClassTypeDef *ctd); static void addTypeSlots(PyHeapTypeObject *heap_to, sipPySlotDef *slots); static void *findSlot(PyObject *self, sipPySlotType st); static void *findSlotInClass(const sipClassTypeDef *psd, sipPySlotType st); static void *findSlotInSlotList(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 int parseResult(PyObject *method, PyObject *res, sipSimpleWrapper *py_self, 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 int compareTypedefName(const void *key, const void *el); static int checkPointer(void *ptr, sipSimpleWrapper *sw); static void finalise(void); static PyObject *getDefaultBase(void); static PyObject *getDefaultSimpleBase(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, PyObject *type_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 *args); static PyObject *unpickle_type(PyObject *obj, PyObject *args); static PyObject *pickle_enum(PyObject *obj, PyObject *args); static PyObject *unpickle_enum(PyObject *obj, PyObject *args); static int setReduce(PyTypeObject *type, PyMethodDef *pickler); static int createEnum(sipExportedModuleDef *client, sipEnumTypeDef *etd, int enum_nr, PyObject *mod_dict); static PyObject *createUnscopedEnum(sipExportedModuleDef *client, sipEnumTypeDef *etd, PyObject *name); static PyObject *createScopedEnum(sipExportedModuleDef *client, sipEnumTypeDef *etd, int enum_nr, PyObject *name); static PyObject *createTypeDict(sipExportedModuleDef *em); static sipTypeDef *getGeneratedType(const sipEncodedTypeDef *enc, sipExportedModuleDef *em); static const sipTypeDef *convertSubClass(const sipTypeDef *td, void **cppPtr); static int convertPass(const sipTypeDef **tdp, 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 *assign(PyObject *self, PyObject *args); static PyObject *cast(PyObject *self, PyObject *args); static PyObject *callDtor(PyObject *self, PyObject *args); static PyObject *dumpWrapper(PyObject *self, PyObject *args); static PyObject *enableAutoconversion(PyObject *self, PyObject *args); static PyObject *isDeleted(PyObject *self, PyObject *args); static PyObject *isPyCreated(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 PyObject *setDestroyOnExit(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); static void *explicit_access_func(sipSimpleWrapper *sw, AccessFuncOp op); static void *indirect_access_func(sipSimpleWrapper *sw, AccessFuncOp op); static void clear_access_func(sipSimpleWrapper *sw); static int check_encoded_string(PyObject *obj); static int isNonlazyMethod(PyMethodDef *pmd); static int addMethod(PyObject *dict, PyMethodDef *pmd); static PyObject *create_property(sipVariableDef *vd); static PyObject *create_function(PyMethodDef *ml); static PyObject *sip_exit(PyObject *self, PyObject *args); static void register_exit_notifier(void); static sipConvertFromFunc get_from_convertor(const sipTypeDef *td); static sipPyObject **autoconversion_disabled(const sipTypeDef *td); static void fix_slots(PyTypeObject *py_type, sipPySlotDef *psd); static sipFinalFunc find_finalisation(sipClassTypeDef *ctd); static sipNewUserTypeFunc find_new_user_type_handler(sipWrapperType *wt); static PyObject *next_in_mro(PyObject *self, PyObject *after); static int super_init(PyObject *self, PyObject *args, PyObject *kwds, PyObject *type); static sipSimpleWrapper *deref_mixin(sipSimpleWrapper *w); static PyObject *wrap_simple_instance(void *cpp, const sipTypeDef *td, sipWrapper *owner, int flags); static void *resolve_proxy(const sipTypeDef *td, void *proxy); static void clear_wrapper(sipSimpleWrapper *sw); static PyObject *call_method(PyObject *method, const char *fmt, va_list va); static int importTypes(sipExportedModuleDef *client, sipImportedModuleDef *im, sipExportedModuleDef *em); static int importErrorHandlers(sipExportedModuleDef *client, sipImportedModuleDef *im, sipExportedModuleDef *em); static int importExceptions(sipExportedModuleDef *client, sipImportedModuleDef *im, sipExportedModuleDef *em); static int is_subtype(const sipClassTypeDef *ctd, const sipClassTypeDef *base_ctd); static PyObject *import_module_attr(const char *module, const char *attr); static const sipContainerDef *get_container(const sipTypeDef *td); #if PY_VERSION_HEX >= 0x03030000 static PyObject *get_qualname(const sipTypeDef *td, PyObject *name); #endif static int convert_to_enum(PyObject *obj, const sipTypeDef *td, int allow_int); static void handle_failed_int_conversion(sipParseFailure *pf, PyObject *arg); static void enum_expected(PyObject *obj, const sipTypeDef *td); static int long_as_nonoverflow_int(PyObject *val_obj); /* * The Python module initialisation function. */ #if PY_MAJOR_VERSION >= 3 #define SIP_MODULE_ENTRY PyInit_@CFG_MODULE_BASENAME@ #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 init@CFG_MODULE_BASENAME@ #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[] = { {"assign", assign, METH_VARARGS, NULL}, {"cast", cast, METH_VARARGS, NULL}, {"delete", callDtor, METH_VARARGS, NULL}, {"dump", dumpWrapper, METH_VARARGS, NULL}, {"enableautoconversion", enableAutoconversion, METH_VARARGS, NULL}, {"enableoverflowchecking", sipEnableOverflowChecking, METH_VARARGS, NULL}, {"getapi", sipGetAPI, METH_VARARGS, NULL}, {"isdeleted", isDeleted, METH_VARARGS, NULL}, {"ispycreated", isPyCreated, METH_VARARGS, NULL}, {"ispyowned", isPyOwned, METH_VARARGS, NULL}, {"setapi", sipSetAPI, METH_VARARGS, NULL}, {"setdeleted", setDeleted, METH_VARARGS, NULL}, {"setdestroyonexit", setDestroyOnExit, 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_MODULE_NAME, /* 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; /* * Remind ourselves to add support for capsule variables when we have * another reason to move to the next major version number. */ #if SIP_API_MAJOR_NR > 12 #error "Add support for capsule variables" #endif #ifdef WITH_THREAD PyEval_InitThreads(); #endif /* Initialise the types. */ sipWrapperType_Type.tp_base = &PyType_Type; if (PyType_Ready(&sipWrapperType_Type) < 0) SIP_FATAL(SIP_MODULE_NAME ": Failed to initialise sip.wrappertype type"); if (PyType_Ready((PyTypeObject *)&sipSimpleWrapper_Type) < 0) SIP_FATAL(SIP_MODULE_NAME ": Failed to initialise sip.simplewrapper type"); if (sip_api_register_py_type((PyTypeObject *)&sipSimpleWrapper_Type) < 0) SIP_FATAL(SIP_MODULE_NAME ": 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_MODULE_NAME ": Failed to initialise sip.wrapper type"); if (PyType_Ready(&sipMethodDescr_Type) < 0) SIP_FATAL(SIP_MODULE_NAME ": Failed to initialise sip.methoddescriptor type"); if (PyType_Ready(&sipVariableDescr_Type) < 0) SIP_FATAL(SIP_MODULE_NAME ": Failed to initialise sip.variabledescriptor type"); sipEnumType_Type.tp_base = &PyType_Type; if (PyType_Ready(&sipEnumType_Type) < 0) SIP_FATAL(SIP_MODULE_NAME ": Failed to initialise sip.enumtype type"); if (PyType_Ready(&sipVoidPtr_Type) < 0) SIP_FATAL(SIP_MODULE_NAME ": Failed to initialise sip.voidptr type"); if (PyType_Ready(&sipArray_Type) < 0) SIP_FATAL(SIP_MODULE_NAME ": Failed to initialise sip.array type"); #if PY_MAJOR_VERSION >= 3 mod = PyModule_Create(&module_def); #else mod = Py_InitModule(SIP_MODULE_NAME, methods); #endif if (mod == NULL) SIP_FATAL(SIP_MODULE_NAME ": Failed to initialise 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_MODULE_NAME ": Failed to get pickle helpers"); } /* Publish the SIP API. */ #if defined(SIP_USE_PYCAPSULE) obj = PyCapsule_New((void *)&sip_api, SIP_MODULE_NAME "._C_API", NULL); #else obj = PyCObject_FromVoidPtr((void *)&sip_api, NULL); #endif if (obj == NULL) { SIP_MODULE_DISCARD(mod); SIP_FATAL(SIP_MODULE_NAME ": 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_MODULE_NAME ": Failed to add _C_API object to module dictionary"); } /* These will always be needed. */ if (objectify("__init__", &init_name) < 0) { SIP_MODULE_DISCARD(mod); SIP_FATAL(SIP_MODULE_NAME ": Failed to objectify '__init__'"); } if ((empty_tuple = PyTuple_New(0)) == NULL) { SIP_MODULE_DISCARD(mod); SIP_FATAL(SIP_MODULE_NAME ": Failed to create empty tuple"); } /* 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; } /* Make sure we are notified when starting to exit. */ register_exit_notifier(); SIP_MODULE_RETURN(mod); } /* * Return the current interpreter, if there is one. */ static PyInterpreterState *sip_api_get_interpreter() { return sipInterpreter; } /* * 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; (void)self; 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; (void)self; 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", sip_api_get_address(sw)); printf(" Created by: %s\n", (sipIsDerived(sw) ? "Python" : "C/C++")); printf(" To be destroyed by: %s\n", (sipIsPyOwned(sw) ? "Python" : "C/C++")); 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; (void)self; if (PyArg_ParseTuple(args, "O!O:transferto", &sipWrapper_Type, &w, &owner)) { if (owner == Py_None) { /* * Note that the Python API is different to the C API when the * owner is 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; (void)self; if (PyArg_ParseTuple(args, "O!:transferback", &sipWrapper_Type, &w)) { sip_api_transfer_back(w); Py_INCREF(Py_None); return Py_None; } return NULL; } /* * Invoke the assignment operator for a C++ instance. */ static PyObject *assign(PyObject *self, PyObject *args) { sipSimpleWrapper *dst, *src; PyTypeObject *dst_type, *src_type; const sipTypeDef *td, *super_td; sipAssignFunc assign_helper; void *dst_addr, *src_addr; (void)self; if (!PyArg_ParseTuple(args, "O!O!:assign", &sipSimpleWrapper_Type, &dst, &sipSimpleWrapper_Type, &src)) return NULL; /* Get the assignment helper. */ dst_type = Py_TYPE(dst); td = ((sipWrapperType *)dst_type)->wt_td; if (sipTypeIsMapped(td)) assign_helper = ((const sipMappedTypeDef *)td)->mtd_assign; else assign_helper = ((const sipClassTypeDef *)td)->ctd_assign; if (assign_helper == NULL) { PyErr_SetString(PyExc_TypeError, "argument 1 of assign() does not support assignment"); return NULL; } /* Check the types are compatible. */ src_type = Py_TYPE(src); if (src_type == dst_type) { super_td = NULL; } else if (PyType_IsSubtype(src_type, dst_type)) { super_td = td; } else { PyErr_SetString(PyExc_TypeError, "type of argument 1 of assign() must be a super-type of type of argument 2"); return NULL; } /* Get the addresses. */ if ((dst_addr = sip_api_get_cpp_ptr(dst, NULL)) == NULL) return NULL; if ((src_addr = sip_api_get_cpp_ptr(src, super_td)) == NULL) return NULL; /* Do the assignment. */ assign_helper(dst_addr, 0, src_addr); Py_INCREF(Py_None); return Py_None; } /* * 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; (void)self; 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->wt_td; else { PyErr_SetString(PyExc_TypeError, "argument 1 of 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 wrap_simple_instance(addr, wt->wt_td, NULL, (sw->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; (void)self; if (!PyArg_ParseTuple(args, "O!:delete", &sipSimpleWrapper_Type, &sw)) return NULL; addr = getPtrTypeDef(sw, &ctd); if (checkPointer(addr, sw) < 0) return NULL; clear_wrapper(sw); release(addr, (const sipTypeDef *)ctd, sw->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; (void)self; if (!PyArg_ParseTuple(args, "O!:isdeleted", &sipSimpleWrapper_Type, &sw)) return NULL; res = (sip_api_get_address(sw) == NULL ? Py_True : Py_False); Py_INCREF(res); return res; } /* * Check if an instance was created by Python. */ static PyObject *isPyCreated(PyObject *self, PyObject *args) { sipSimpleWrapper *sw; PyObject *res; (void)self; if (!PyArg_ParseTuple(args, "O!:ispycreated", &sipSimpleWrapper_Type, &sw)) return NULL; /* sipIsDerived() is a misnomer. */ res = (sipIsDerived(sw) ? 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; (void)self; 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; (void)self; if (!PyArg_ParseTuple(args, "O!:setdeleted", &sipSimpleWrapper_Type, &sw)) return NULL; clear_wrapper(sw); Py_INCREF(Py_None); return Py_None; } /* * Unwrap an instance. */ static PyObject *unwrapInstance(PyObject *self, PyObject *args) { sipSimpleWrapper *sw; (void)self; 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 PY_LONG_LONG addr; sipWrapperType *wt; (void)self; if (PyArg_ParseTuple(args, "KO!:wrapinstance", &addr, &sipWrapperType_Type, &wt)) return sip_api_convert_from_type((void *)addr, wt->wt_td, NULL); return NULL; } /* * Set the destroy on exit flag from Python code. */ static PyObject *setDestroyOnExit(PyObject *self, PyObject *args) { (void)self; if (PyArg_ParseTuple(args, "i:setdestroyonexit", &destroy_on_exit)) { Py_INCREF(Py_None); return Py_None; } return NULL; } /* * Set the destroy on exit flag from C++ code. */ static void sip_api_set_destroy_on_exit(int value) { destroy_on_exit = value; } /* * 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); (void)unused; /* 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; } if (im->im_imported_types != NULL && importTypes(client, im, em) < 0) return -1; if (im->im_imported_veh != NULL && importErrorHandlers(client, im, em) < 0) return -1; if (im->im_imported_exceptions != NULL && importExceptions(client, im, em) < 0) return -1; ++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; /* Get any keyword handler. Remove this in SIP v5. */ if (!got_kw_handler) { kw_handler = sip_api_import_symbol("pyqt_kw_handler"); got_kw_handler = TRUE; } 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) || sipTypeIsScopedEnum(td)) { sipEnumTypeDef *etd = (sipEnumTypeDef *)td; if (td->td_version < 0 || sipIsRangeEnabled(client, td->td_version)) if (createEnum(client, etd, i, mod_dict) < 0) return -1; /* * Register the enum pickler for nested enums (non-nested enums * don't need special treatment). */ if (sipTypeIsEnum(td) && 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->wt_iextend; wt->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. This should already have been done, * but just in case... */ 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; } /* * Convert a new C/C++ instance to a Python instance of a specific Python type.. */ static PyObject *sip_api_convert_from_new_pytype(void *cpp, PyTypeObject *py_type, sipWrapper *owner, sipSimpleWrapper **selfp, 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 = sipWrapInstance(cpp, py_type, args, owner, (selfp != NULL ? SIP_DERIVED_CLASS : 0)); /* Initialise the rest of an instance of a derived class. */ if (selfp != NULL) *selfp = (sipSimpleWrapper *)res; } else { res = NULL; } Py_XDECREF(args); va_end(va); return res; } /* * Call a method and return the result. */ static PyObject *call_method(PyObject *method, const char *fmt, va_list va) { PyObject *args, *res; if ((args = PyTuple_New(strlen(fmt))) == NULL) return NULL; if (buildObject(args, fmt, va) != NULL) res = PyEval_CallObject(method, args); else res = NULL; Py_DECREF(args); return res; } /* * Call the Python re-implementation of a C++ virtual that does not return a * value and handle the result.. */ static void sip_api_call_procedure_method(sip_gilstate_t gil_state, sipVirtErrorHandlerFunc error_handler, sipSimpleWrapper *py_self, PyObject *method, const char *fmt, ...) { PyObject *res; va_list va; va_start(va, fmt); res = call_method(method, fmt, va); va_end(va); if (res != NULL) { Py_DECREF(res); if (res != Py_None) { sip_api_bad_catcher_result(method); res = NULL; } } Py_DECREF(method); if (res == NULL) sip_api_call_error_handler(error_handler, py_self, gil_state); SIP_RELEASE_GIL(gil_state); } /* * Call the Python re-implementation of a C++ virtual. */ static PyObject *sip_api_call_method(int *isErr, PyObject *method, const char *fmt, ...) { PyObject *res; va_list va; va_start(va, fmt); res = call_method(method, fmt, va); va_end(va); if (res == NULL && isErr != NULL) *isErr = TRUE; 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 = (int)(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': case 'L': #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': case 'M': 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->wt_td, 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->wt_td, 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; case 'z': { const char *name = va_arg(va, const char *); void *p = va_arg(va, void *); if (p == NULL) { el = Py_None; Py_INCREF(el); } else { #if defined(SIP_USE_PYCAPSULE) el = PyCapsule_New(p, name, NULL); #else el = sip_api_convert_from_void_ptr(p); #endif } } 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. As of v9.0 of the API this * is only ever called by handwritten code. */ static int sip_api_parse_result(int *isErr, PyObject *method, PyObject *res, const char *fmt, ...) { int rc; va_list va; va_start(va, fmt); rc = parseResult(method, res, NULL, fmt, va); va_end(va); if (isErr != NULL && rc < 0) *isErr = TRUE; return rc; } /* * Parse a result object based on a format string. */ static int sip_api_parse_result_ex(sip_gilstate_t gil_state, sipVirtErrorHandlerFunc error_handler, sipSimpleWrapper *py_self, PyObject *method, PyObject *res, const char *fmt, ...) { int rc; if (res != NULL) { va_list va; va_start(va, fmt); rc = parseResult(method, res, deref_mixin(py_self), fmt, va); va_end(va); Py_DECREF(res); } else { rc = -1; } Py_DECREF(method); if (rc < 0) sip_api_call_error_handler(error_handler, py_self, gil_state); SIP_RELEASE_GIL(gil_state); return rc; } /* * Call a virtual error handler. This is called with the GIL and from the * thread that raised the error. */ static void sip_api_call_error_handler(sipVirtErrorHandlerFunc error_handler, sipSimpleWrapper *py_self, sip_gilstate_t sipGILState) { if (error_handler != NULL) error_handler(deref_mixin(py_self), sipGILState); else PyErr_Print(); } /* * Do the main work of parsing a result object based on a format string. */ static int parseResult(PyObject *method, PyObject *res, sipSimpleWrapper *py_self, const char *fmt, va_list va) { int tupsz, rc = 0; /* We rely on PyErr_Occurred(). */ PyErr_Clear(); /* Get self if it is provided as an argument. */ if (*fmt == 'S') { py_self = va_arg(va, sipSimpleWrapper *); ++fmt; } /* Basic validation of the format string. */ if (*fmt == '(') { char ch; const char *cp = ++fmt; int sub_format = FALSE; tupsz = 0; while ((ch = *cp++) != ')') { if (ch == '\0') { PyErr_Format(PyExc_SystemError, "sipParseResult(): invalid format string \"%s\"", fmt - 1); rc = -1; break; } if (sub_format) { sub_format = FALSE; } else { ++tupsz; /* Some format characters have a sub-format. */ if (strchr("aAHDC", ch) != NULL) sub_format = TRUE; } } 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': { char *p = va_arg(va, void *); int v = sip_api_convert_to_bool(arg); if (v < 0) invalid = TRUE; else if (p != NULL) sipSetBool(p, 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 *p = va_arg(va, double *); double v = PyFloat_AsDouble(arg); if (PyErr_Occurred()) invalid = TRUE; else if (p != NULL) *p = v; } break; case 'E': { /* This is deprecated. */ PyTypeObject *et = va_arg(va, PyTypeObject *); int *p = va_arg(va, int *); int v = sip_api_convert_to_enum(arg, ((sipEnumTypeObject *)et)->type); if (PyErr_Occurred()) invalid = TRUE; else if (p != NULL) *p = v; } break; case 'F': { sipTypeDef *td = va_arg(va, sipTypeDef *); int *p = va_arg(va, int *); int v = sip_api_convert_to_enum(arg, td); if (PyErr_Occurred()) invalid = TRUE; else if (p != NULL) *p = v; } break; case 'f': { float *p = va_arg(va, float *); float v = (float)PyFloat_AsDouble(arg); if (PyErr_Occurred()) invalid = TRUE; else if (p != NULL) *p = v; } break; case 'L': { signed char *p = va_arg(va, signed char *); signed char v = sip_api_long_as_signed_char(arg); if (PyErr_Occurred()) invalid = TRUE; else if (p != NULL) *p = v; } break; case 'M': { unsigned char *p = va_arg(va, unsigned char *); unsigned char v = sip_api_long_as_unsigned_char(arg); if (PyErr_Occurred()) invalid = TRUE; else if (p != NULL) *p = v; } break; case 'h': { signed short *p = va_arg(va, signed short *); signed short v = sip_api_long_as_short(arg); if (PyErr_Occurred()) invalid = TRUE; else if (p != NULL) *p = v; } break; case 't': { unsigned short *p = va_arg(va, unsigned short *); unsigned short v = sip_api_long_as_unsigned_short(arg); if (PyErr_Occurred()) invalid = TRUE; else if (p != NULL) *p = v; } break; case 'e': { int *p = va_arg(va, int *); int v = long_as_nonoverflow_int(arg); if (PyErr_Occurred()) invalid = TRUE; else if (p != NULL) *p = v; } break; case 'i': { int *p = va_arg(va, int *); int v = sip_api_long_as_int(arg); if (PyErr_Occurred()) invalid = TRUE; else if (p != NULL) *p = v; } break; case 'u': { unsigned *p = va_arg(va, unsigned *); unsigned v = sip_api_long_as_unsigned_int(arg); if (PyErr_Occurred()) invalid = TRUE; else if (p != NULL) *p = v; } break; case 'l': { long *p = va_arg(va, long *); long v = sip_api_long_as_long(arg); if (PyErr_Occurred()) invalid = TRUE; else if (p != NULL) *p = v; } break; case 'm': { unsigned long *p = va_arg(va, unsigned long *); unsigned long v = sip_api_long_as_unsigned_long(arg); if (PyErr_Occurred()) invalid = TRUE; else if (p != NULL) *p = v; } break; case 'n': { #if defined(HAVE_LONG_LONG) PY_LONG_LONG *p = va_arg(va, PY_LONG_LONG *); PY_LONG_LONG v = sip_api_long_as_long_long(arg); #else long *p = va_arg(va, long *); long v = sip_api_long_as_long(arg); #endif if (PyErr_Occurred()) invalid = TRUE; else if (p != NULL) *p = v; } break; case 'o': { #if defined(HAVE_LONG_LONG) unsigned PY_LONG_LONG *p = va_arg(va, unsigned PY_LONG_LONG *); unsigned PY_LONG_LONG v = sip_api_long_as_unsigned_long_long(arg); #else unsigned long *p = va_arg(va, unsigned long *); unsigned long v = sip_api_long_as_unsigned_long(arg); #endif if (PyErr_Occurred()) invalid = TRUE; else if (p != NULL) *p = v; } 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 *)py_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 *)py_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->wt_td, (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); if (cpp != NULL) assign_helper(cpp, 0, val); sip_api_release_type(val, td, state); } else if (cpp != NULL) { *(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)) { if (p != NULL) { Py_INCREF(arg); *p = arg; } } else { invalid = TRUE; } } break; case 'O': { PyObject **p = va_arg(va, PyObject **); if (p != NULL) { Py_INCREF(arg); *p = arg; } } break; case 'T': { PyTypeObject *type = va_arg(va, PyTypeObject *); PyObject **p = va_arg(va, PyObject **); if (PyObject_TypeCheck(arg, type)) { if (p != NULL) { Py_INCREF(arg); *p = arg; } } else { invalid = TRUE; } } break; case 'V': { void *v = sip_api_convert_to_void_ptr(arg); void **p = va_arg(va, void **); if (PyErr_Occurred()) invalid = TRUE; else if (p != NULL) *p = v; } break; case 'z': { const char *name = va_arg(va, const char *); void **p = va_arg(va, void **); if (arg == Py_None) { if (p != NULL) *p = NULL; } else { #if defined(SIP_USE_CAPSULE) void *v = PyCapsule_GetPointer(arg, name); #else void *v = sip_api_convert_to_void_ptr(arg); (void)name; #endif if (PyErr_Occurred()) invalid = TRUE; else if (p != NULL) *p = v; } } break; case 'Z': if (arg != Py_None) invalid = TRUE; break; case '!': { PyObject **p = va_arg(va, PyObject **); #if PY_VERSION_HEX >= 0x03000000 if (PyObject_CheckBuffer(arg)) #elif PY_VERSION_HEX >= 0x02060300 if (PyObject_CheckBuffer(arg) || PyObject_CheckReadBuffer(arg)) #else if (PyObject_CheckReadBuffer(arg)) #endif { if (p != NULL) { Py_INCREF(arg); *p = arg; } } else { invalid = TRUE; } } break; case '$': { PyObject **p = va_arg(va, PyObject **); #if PY_VERSION_HEX >= 0x03000000 if (arg == Py_None || PyObject_CheckBuffer(arg)) #elif PY_VERSION_HEX >= 0x02060300 if (arg == Py_None || PyObject_CheckBuffer(arg) || PyObject_CheckReadBuffer(arg)) #else if (arg == Py_None || PyObject_CheckReadBuffer(arg)) #endif { if (p != NULL) { Py_INCREF(arg); *p = arg; } } else { 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; } } } return rc; } /* * 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; if (unused != NULL) { /* * Initialise the return of any unused keyword arguments. This is * used by any ctor overload. */ *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 one or 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(sipArg1 != NULL ? 2 : 1)) == 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); if (sipArg1 != NULL) { 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. We continue to parse if we get an * overflow because that is, strictly speaking, a second pass error. */ while (failure.reason == Ok || failure.reason == Overflow) { 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 - *selfargp) { /* * 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 (nr_kwd_args != 0 && kwdlist != NULL) { const char *name = kwdlist[argnr - *selfargp]; 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. */ va_arg(va, PyObject **); va_arg(va, const char **); fmt++; if (arg != NULL && check_encoded_string(arg) < 0) { failure.reason = WrongType; failure.detail_obj = arg; Py_INCREF(arg); } break; } case 'a': { /* Character from a Python string. */ va_arg(va, char *); fmt++; if (arg != NULL && check_encoded_string(arg) < 0) { failure.reason = WrongType; failure.detail_obj = arg; Py_INCREF(arg); } 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 '!': { /* Python object that implements the buffer protocol. */ PyObject **p = va_arg(va, PyObject **); if (arg != NULL) { #if PY_VERSION_HEX >= 0x03000000 if (PyObject_CheckBuffer(arg)) #elif PY_VERSION_HEX >= 0x02060300 if (PyObject_CheckBuffer(arg) || PyObject_CheckReadBuffer(arg)) #else if (PyObject_CheckReadBuffer(arg)) #endif { *p = arg; } else { failure.reason = WrongType; failure.detail_obj = arg; Py_INCREF(arg); } } break; } case '$': { /* * Python object that implements the buffer protocol or None. */ PyObject **p = va_arg(va, PyObject **); if (arg != NULL) { #if PY_VERSION_HEX >= 0x03000000 if (arg == Py_None || PyObject_CheckBuffer(arg)) #elif PY_VERSION_HEX >= 0x02060300 if (arg == Py_None || PyObject_CheckBuffer(arg) || PyObject_CheckReadBuffer(arg)) #else if (arg == Py_None || PyObject_CheckReadBuffer(arg)) #endif { *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 '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 = sip_api_convert_to_bool(arg); if (v < 0) { 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 *); int *p = va_arg(va, int *); if (arg != NULL) { int v = sip_api_convert_to_enum(arg, td); if (PyErr_Occurred()) handle_failed_int_conversion(&failure, arg); else *p = v; } } break; case 'e': { /* Anonymous enum. */ int *p = va_arg(va, int *); if (arg != NULL) { int v = long_as_nonoverflow_int(arg); if (PyErr_Occurred()) handle_failed_int_conversion(&failure, arg); else *p = v; } } break; case 'i': { /* Integer. */ int *p = va_arg(va, int *); if (arg != NULL) { int v = sip_api_long_as_int(arg); if (PyErr_Occurred()) handle_failed_int_conversion(&failure, 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_int(arg); if (PyErr_Occurred()) handle_failed_int_conversion(&failure, arg); else *p = v; } break; } case 'L': { /* Signed char. */ signed char *p = va_arg(va, signed char *); if (arg != NULL) { signed char v = sip_api_long_as_signed_char(arg); if (PyErr_Occurred()) handle_failed_int_conversion(&failure, arg); else *p = v; } break; } case 'M': { /* Unsigned char. */ unsigned char *p = va_arg(va, unsigned char *); if (arg != NULL) { unsigned char v = sip_api_long_as_unsigned_char(arg); if (PyErr_Occurred()) handle_failed_int_conversion(&failure, arg); else *p = v; } break; } case 'h': { /* Short integer. */ signed short *p = va_arg(va, signed short *); if (arg != NULL) { signed short v = sip_api_long_as_short(arg); if (PyErr_Occurred()) handle_failed_int_conversion(&failure, 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_short(arg); if (PyErr_Occurred()) handle_failed_int_conversion(&failure, arg); else *p = v; } break; } case 'l': { /* Long integer. */ long *p = va_arg(va, long *); if (arg != NULL) { long v = sip_api_long_as_long(arg); if (PyErr_Occurred()) handle_failed_int_conversion(&failure, 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()) handle_failed_int_conversion(&failure, 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 = sip_api_long_as_long_long(arg); #else long v = sip_api_long_as_long(arg); #endif if (PyErr_Occurred()) handle_failed_int_conversion(&failure, 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 = sip_api_long_as_unsigned_long_long(arg); #else unsigned long v = sip_api_long_as_unsigned_long(arg); #endif if (PyErr_Occurred()) handle_failed_int_conversion(&failure, 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 *); int *p = va_arg(va, int *); if (arg != NULL) { *p = convert_to_enum(arg, td, FALSE); if (PyErr_Occurred()) handle_failed_int_conversion(&failure, 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)) #else if (PyInt_Check(arg) || PyLong_Check(arg)) #endif { *(int *)p = sip_api_long_as_int(arg); if (PyErr_Occurred()) handle_failed_int_conversion(&failure, arg); } 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; } case 'z': { /* Void pointer as a capsule. */ const char *name = va_arg(va, const char *); void **p = va_arg(va, void **); if (arg == Py_None) { *p = NULL; } else if (arg != NULL) { #if defined(SIP_USE_PYCAPSULE) void *v = PyCapsule_GetPointer(arg, name); #else void *v = sip_api_convert_to_void_ptr(arg); #endif if (PyErr_Occurred()) { failure.reason = WrongType; failure.detail_obj = arg; Py_INCREF(arg); } else { *p = v; } } break; } } if ((failure.reason == Ok || failure.reason == Overflow) && ch == 'W') { /* An ellipsis matches everything and ends the parse. */ break; } } /* Handle parse failures appropriately. */ if (failure.reason == Ok) return TRUE; if (failure.reason == Overflow) { /* * We have successfully parsed the signature but one of the arguments * has been found to overflow. Raise an appropriate exception and * ensure we don't parse any subsequent overloads. */ #if PY_MAJOR_VERSION < 3 PyObject *exc_str_obj; const char *exc_str; if ((exc_str_obj = PyObject_Str(failure.detail_obj)) == NULL) exc_str = NULL; else exc_str = PyString_AsString(exc_str_obj); if (exc_str == NULL) exc_str = "invalid exception text"; #endif if (failure.arg_nr >= 0) { #if PY_MAJOR_VERSION >= 3 PyErr_Format(PyExc_OverflowError, "argument %d overflowed: %S", failure.arg_nr, failure.detail_obj); #else PyErr_Format(PyExc_OverflowError, "argument %s overflowed: %s", failure.arg_nr, exc_str); #endif } else { #if PY_MAJOR_VERSION >= 3 PyErr_Format(PyExc_OverflowError, "argument '%s' overflowed: %S", failure.arg_nr, failure.detail_obj); #else PyErr_Format(PyExc_OverflowError, "argument '%s' overflowed: %s", failure.arg_nr, exc_str); #endif } #if PY_MAJOR_VERSION < 3 Py_XDECREF(exc_str_obj); #endif /* The overflow exception has now been raised. */ failure.reason = Raised; } if (failure.reason != Raised) add_failure(parseErrp, &failure); if (failure.reason == Raised) { Py_XDECREF(failure.detail_obj); /* * Discard any previous errors and flag that the exception we want the * user to see has been raised. */ Py_XDECREF(*parseErrp); *parseErrp = Py_None; Py_INCREF(Py_None); } return FALSE; } /* * Called after a failed conversion of an integer. */ static void handle_failed_int_conversion(sipParseFailure *pf, PyObject *arg) { PyObject *xtype, *xvalue, *xtb; assert(pf->reason == Ok || pf->reason == Overflow); PyErr_Fetch(&xtype, &xvalue, &xtb); if (PyErr_GivenExceptionMatches(xtype, PyExc_OverflowError) && xvalue != NULL) { /* Remove any previous overflow exception. */ Py_XDECREF(pf->detail_obj); pf->reason = Overflow; pf->detail_obj = xvalue; Py_INCREF(xvalue); } else { pf->reason = WrongType; pf->detail_obj = arg; Py_INCREF(arg); } Py_XDECREF(xtype); Py_XDECREF(xvalue); Py_XDECREF(xtb); } /* * 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 - selfarg]; 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. */ if (*fmt++ == 'E') va_arg(va, void *); va_arg(va, void *); 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 = NULL; 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) return FALSE; *keep = s; } 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) return FALSE; } break; } /* * Every other argument is a pointer and only differ in how many there * are. */ case 'N': case 'T': case 'k': case 'K': case 'U': case 'E': 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_instance_destroyed(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); sipOMRemoveObject(&cppPyMap, sipSelf); /* This no longer points to anything useful. */ clear_access_func(sipSelf); /* * 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 } } /* * Clear any access function so that sip_api_get_address() will always return a * NULL pointer. */ static void clear_access_func(sipSimpleWrapper *sw) { if (sw->access_func != NULL) { sw->access_func(sw, ReleaseGuard); sw->access_func = NULL; } sw->data = NULL; } /* * 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 class of a type that has no explicit super-type. */ static PyObject *getDefaultBase(void) { static PyObject *default_base = NULL; /* Only do this once. */ if (default_base == NULL) { #if PY_VERSION_HEX >= 0x02040000 default_base = PyTuple_Pack(1, (PyObject *)&sipWrapper_Type); #else default_base = Py_BuildValue("(O)", &sipWrapper_Type); #endif if (default_base == NULL) return NULL; } Py_INCREF(default_base); return default_base; } /* * Return a tuple of the base class of a simple type that has no explicit * super-type. */ static PyObject *getDefaultSimpleBase(void) { static PyObject *default_simple_base = NULL; /* Only do this once. */ if (default_simple_base == NULL) { #if PY_VERSION_HEX >= 0x02040000 default_simple_base = PyTuple_Pack(1, (PyObject *)&sipSimpleWrapper_Type); #else default_simple_base = Py_BuildValue("(O)", &sipSimpleWrapper_Type); #endif if (default_simple_base == NULL) return NULL; } Py_INCREF(default_simple_base); return default_simple_base; } /* * 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, PyObject *type_dict, sipExportedModuleDef *client) { PyObject *py_type, *scope_dict, *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 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 reterr; /* Create the type by calling the metatype. */ #if PY_VERSION_HEX >= 0x02040000 args = PyTuple_Pack(3, name, bases, type_dict); #else args = Py_BuildValue("OOO", name, bases, type_dict); #endif if (args == NULL) goto relname; /* Pass the type via the back door. */ assert(currentType == NULL); currentType = td; py_type = PyObject_Call(metatype, args, NULL); currentType = NULL; if (py_type == 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); return py_type; /* Unwind on error. */ reltype: Py_DECREF(py_type); relargs: Py_DECREF(args); relname: Py_DECREF(name); reterr: return NULL; } /* * Create a single class type object. */ static int createClassType(sipExportedModuleDef *client, sipClassTypeDef *ctd, PyObject *mod_dict) { PyObject *bases, *metatype, *py_type, *type_dict; sipEncodedTypeDef *sup; int i; /* 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 = (sipTypeIsNamespace(&ctd->ctd_base) ? getDefaultSimpleBase() : getDefaultBase()); } 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 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)); /* Create the type dictionary and populate it with any non-lazy methods. */ if ((type_dict = createTypeDict(client)) == NULL) goto relbases; if (sipTypeHasNonlazyMethod(&ctd->ctd_base)) { PyMethodDef *pmd = ctd->ctd_container.cod_methods; for (i = 0; i < ctd->ctd_container.cod_nrmethods; ++i) { if (isNonlazyMethod(pmd) && addMethod(type_dict, pmd) < 0) goto reldict; ++pmd; } } if ((py_type = createContainerType(&ctd->ctd_container, (sipTypeDef *)ctd, bases, metatype, mod_dict, type_dict, client)) == NULL) goto reldict; if (ctd->ctd_pyslots != NULL) fix_slots((PyTypeObject *)py_type, ctd->ctd_pyslots); /* 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); Py_DECREF(type_dict); return 0; /* Unwind after an error. */ reltype: Py_DECREF(py_type); reldict: Py_DECREF(type_dict); 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, *type_dict; /* 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 = getDefaultBase()) == NULL) goto reterr; /* Create the type dictionary. */ if ((type_dict = createTypeDict(client)) == NULL) goto relbases; if (createContainerType(&mtd->mtd_container, (sipTypeDef *)mtd, bases, (PyObject *)&sipWrapperType_Type, mod_dict, type_dict, client) == NULL) goto reldict; /* We can now release our references. */ Py_DECREF(bases); Py_DECREF(type_dict); return 0; /* Unwind after an error. */ reldict: Py_DECREF(type_dict); 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 *obj, PyObject *args) { PyObject *mname_obj, *init_args; const char *tname; sipExportedModuleDef *em; int i; (void)obj; 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 *args) { sipExportedModuleDef *em; (void)args; /* 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 (init_args == NULL) return 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 *obj, PyObject *args) { PyObject *mname_obj, *evalue_obj; const char *ename; sipExportedModuleDef *em; int i; (void)obj; 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 *args) { sipTypeDef *td = ((sipEnumTypeObject *)Py_TYPE(obj))->type; (void)args; 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 object. */ static int createEnum(sipExportedModuleDef *client, sipEnumTypeDef *etd, int enum_nr, PyObject *mod_dict) { int rc; PyObject *name, *dict, *enum_obj; 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) return -1; /* 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) return -1; /* Create the enum. */ if (sipTypeIsEnum(&etd->etd_base)) enum_obj = createUnscopedEnum(client, etd, name); else enum_obj = createScopedEnum(client, etd, enum_nr, name); if (enum_obj == NULL) { Py_DECREF(name); return -1; } /* Add the enum to the "parent" dictionary. */ rc = PyDict_SetItem(dict, name, enum_obj); /* We can now release our remaining references. */ Py_DECREF(name); Py_DECREF(enum_obj); return rc; } /* * Create an unscoped enum. */ static PyObject *createUnscopedEnum(sipExportedModuleDef *client, sipEnumTypeDef *etd, PyObject *name) { static PyObject *bases = NULL; PyObject *type_dict, *args; sipEnumTypeObject *eto; /* 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) return NULL; } /* Create the type dictionary. */ if ((type_dict = createTypeDict(client)) == NULL) return NULL; /* Create the type by calling the metatype. */ #if PY_VERSION_HEX >= 0x02040000 args = PyTuple_Pack(3, name, bases, type_dict); #else args = Py_BuildValue("OOO", name, bases, type_dict); #endif Py_DECREF(type_dict); if (args == NULL) return NULL; /* Pass the type via the back door. */ assert(currentType == NULL); currentType = &etd->etd_base; eto = (sipEnumTypeObject *)PyObject_Call((PyObject *)&sipEnumType_Type, args, NULL); currentType = NULL; Py_DECREF(args); if (eto == NULL) return NULL; if (etd->etd_pyslots != NULL) fix_slots((PyTypeObject *)eto, etd->etd_pyslots); #if PY_VERSION_HEX >= 0x03030000 /* * If the enum has a scope then the default __qualname__ will be incorrect. */ if (etd->etd_scope >= 0) { /* Append the name of the enum to the scope's __qualname__. */ Py_CLEAR(eto->super.ht_qualname); eto->super.ht_qualname = get_qualname( client->em_types[etd->etd_scope], name); if (eto->super.ht_qualname == NULL) { Py_DECREF((PyObject *)eto); return NULL; } } #endif return (PyObject *)eto; } /* * Create a scoped enum. */ static PyObject *createScopedEnum(sipExportedModuleDef *client, sipEnumTypeDef *etd, int enum_nr, PyObject *name) { static PyObject *enum_type = NULL, *module_arg = NULL; #if PY_VERSION_HEX >= 0x03030000 static PyObject *qualname_arg = NULL; #endif int i, nr_members; sipEnumMemberDef *enm; PyObject *members, *enum_obj, *args, *kw_args; /* Get the enum type if we haven't done so already. */ if (enum_type == NULL) { if ((enum_type = import_module_attr("enum", "Enum")) == NULL) goto ret_err; } /* Create a dict of the members. */ if ((members = PyDict_New()) == NULL) goto ret_err; /* * Note that the current structures for defining scoped enums are not ideal * as we are re-using the ones used for unscoped enums (which are designed * to support lazy implementations). */ if (etd->etd_scope < 0) { nr_members = client->em_nrenummembers; enm = client->em_enummembers; } else { const sipContainerDef *cod = get_container(client->em_types[etd->etd_scope]); nr_members = cod->cod_nrenummembers; enm = cod->cod_enummembers; } for (i = 0; i < nr_members; ++i) { if (enm->em_enum == enum_nr) { int rc; PyObject *val; #if PY_MAJOR_VERSION >= 3 val = PyLong_FromLong(enm->em_val); #else val = PyInt_FromLong(enm->em_val); #endif if (val == NULL) goto rel_members; rc = PyDict_SetItemString(members, enm->em_name, val); Py_DECREF(val); if (rc < 0) goto rel_members; } ++enm; } #if PY_VERSION_HEX >= 0x02040000 args = PyTuple_Pack(2, name, members); #else args = Py_BuildValue("(OO)", name, members); #endif if (args == NULL) goto rel_members; if ((kw_args = PyDict_New()) == NULL) goto rel_args; if (objectify("module", &module_arg) < 0) goto rel_kw_args; if (PyDict_SetItem(kw_args, module_arg, client->em_nameobj) < 0) goto rel_kw_args; #if PY_VERSION_HEX >= 0x03030000 /* * If the enum has a scope then the default __qualname__ will be incorrect. */ if (etd->etd_scope >= 0) { int rc; PyObject *qualname; if (objectify("qualname", &qualname_arg) < 0) goto rel_kw_args; if ((qualname = get_qualname(client->em_types[etd->etd_scope], name)) == NULL) goto rel_kw_args; rc = PyDict_SetItem(kw_args, qualname_arg, qualname); Py_DECREF(qualname); if (rc < 0) goto rel_kw_args; } #endif if ((enum_obj = PyObject_Call(enum_type, args, kw_args)) == NULL) goto rel_kw_args; Py_DECREF(kw_args); Py_DECREF(args); Py_DECREF(members); /* Note that it isn't actually a PyTypeObject. */ etd->etd_base.u.td_py_type = (PyTypeObject *)enum_obj; return enum_obj; /* Unwind on errors. */ rel_kw_args: Py_DECREF(kw_args); rel_args: Py_DECREF(args); rel_members: Py_DECREF(members); ret_err: return NULL; } /* * Create a type dictionary for dynamic type being created in a module. */ static PyObject *createTypeDict(sipExportedModuleDef *em) { 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, em->em_nameobj) < 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; } /* * Return non-zero if a method is non-lazy, ie. it must be added to the type * when it is created. */ static int isNonlazyMethod(PyMethodDef *pmd) { static const char *lazy[] = { "__getattribute__", "__getattr__", "__enter__", "__exit__", #if PY_VERSION_HEX >= 0x03050000 "__aenter__", "__aexit__", #endif NULL }; const char **l; for (l = lazy; *l != NULL; ++l) if (strcmp(pmd->ml_name, *l) == 0) return TRUE; return FALSE; } /* * Add a method to a dictionary. */ static int addMethod(PyObject *dict, PyMethodDef *pmd) { int rc; PyObject *descr; if ((descr = sipMethodDescr_New(pmd)) == NULL) return -1; rc = PyDict_SetItemString(dict, pmd->ml_name, descr); Py_DECREF(descr); return rc; } /* * 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) { /* Non-lazy methods will already have been handled. */ if (!sipTypeHasNonlazyMethod(td) || !isNonlazyMethod(pmd)) { if (addMethod(dict, pmd) < 0) return -1; } ++pmd; } /* Do the unscoped enum members. */ enm = cod->cod_enummembers; for (i = 0; i < cod->cod_nrenummembers; ++i) { int rc; PyObject *val; if (enm->em_enum < 0) { /* It's an unnamed unscoped enum. */ #if PY_MAJOR_VERSION >= 3 val = PyLong_FromLong(enm->em_val); #else val = PyInt_FromLong(enm->em_val); #endif } else { sipTypeDef *etd = td->td_module->em_types[enm->em_enum]; if (sipTypeIsScopedEnum(etd)) continue; val = sip_api_convert_from_enum(enm->em_val, etd); } if (val == 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 (vd->vd_type == PropertyVariable) descr = create_property(vd); else descr = sipVariableDescr_New(vd, td, cod); if (descr == NULL) return -1; rc = PyDict_SetItemString(dict, vd->vd_name, descr); Py_DECREF(descr); if (rc < 0) return -1; ++vd; } return 0; } /* * Create a Python property object from the SIP generated structure. */ static PyObject *create_property(sipVariableDef *vd) { PyObject *descr, *fget, *fset, *fdel, *doc; descr = fget = fset = fdel = doc = NULL; if ((fget = create_function(vd->vd_getter)) == NULL) goto done; if ((fset = create_function(vd->vd_setter)) == NULL) goto done; if ((fdel = create_function(vd->vd_deleter)) == NULL) goto done; if (vd->vd_docstring == NULL) { doc = Py_None; Py_INCREF(doc); } #if PY_MAJOR_VERSION >= 3 else if ((doc = PyUnicode_FromString(vd->vd_docstring)) == NULL) #else else if ((doc = PyString_FromString(vd->vd_docstring)) == NULL) #endif { goto done; } descr = PyObject_CallFunctionObjArgs((PyObject *)&PyProperty_Type, fget, fset, fdel, doc, NULL); done: Py_XDECREF(fget); Py_XDECREF(fset); Py_XDECREF(fdel); Py_XDECREF(doc); return descr; } /* * Return a PyCFunction as an object or Py_None if there isn't one. */ static PyObject *create_function(PyMethodDef *ml) { if (ml != NULL) return PyCFunction_New(ml, NULL); Py_INCREF(Py_None); return Py_None; } /* * 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->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. */ /* TODO: Deprecate this mechanism in favour of an event handler. */ 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->wt_dict_complete = TRUE; #if PY_VERSION_HEX >= 0x02060000 PyType_Modified((PyTypeObject *)wt); #endif 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)->wt_td; 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) || sipTypeIsScopedEnum(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 } /* * Convert a Python object implementing a named enum to an integer value. */ static int sip_api_convert_to_enum(PyObject *obj, const sipTypeDef *td) { return convert_to_enum(obj, td, TRUE); } /* * Convert a Python object implementing a named enum (or, optionally, an int) * to an integer value. */ static int convert_to_enum(PyObject *obj, const sipTypeDef *td, int allow_int) { int val; assert(sipTypeIsEnum(td) || sipTypeIsScopedEnum(td)); if (sipTypeIsScopedEnum(td)) { static PyObject *value = NULL; PyObject *val_obj; if (PyObject_IsInstance(obj, (PyObject *)sipTypeAsPyTypeObject(td)) <= 0) { enum_expected(obj, td); return -1; } if (objectify("value", &value) < 0) return -1; if ((val_obj = PyObject_GetAttr(obj, value)) == NULL) return -1; /* This will never overflow. */ val = long_as_nonoverflow_int(val_obj); Py_DECREF(val_obj); } else { if (PyObject_TypeCheck((PyObject *)Py_TYPE(obj), &sipEnumType_Type)) { if (!PyObject_TypeCheck(obj, sipTypeAsPyTypeObject(td))) { enum_expected(obj, td); return -1; } /* This will never overflow. */ val = long_as_nonoverflow_int(obj); } else if (allow_int && SIPLong_Check(obj)) { val = long_as_nonoverflow_int(obj); } else { enum_expected(obj, td); return -1; } } return val; } /* * Raise an exception when failing to convert an enum because of its type. */ static void enum_expected(PyObject *obj, const sipTypeDef *td) { PyErr_Format(PyExc_TypeError, "a member of enum '%s' is expected not '%s'", sipPyNameOfEnum((sipEnumTypeDef *)td), Py_TYPE(obj)->tp_name); } /* Convert to a C/C++ int while checking for overflow. */ static int long_as_nonoverflow_int(PyObject *val_obj) { int old_overflow, val; old_overflow = sip_api_enable_overflow_checking(TRUE); val = sip_api_long_as_int(val_obj); sip_api_enable_overflow_checking(old_overflow); return val; } /* * 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) || sipTypeIsScopedEnum(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; } /* * Register a proxy resolver. */ static int sip_api_register_proxy_resolver(const sipTypeDef *td, sipProxyResolverFunc resolver) { sipProxyResolver *pr = sip_api_malloc(sizeof (sipProxyResolver)); if (pr == NULL) return -1; pr->td = td; pr->resolver = resolver; pr->next = proxyResolvers; proxyResolvers = pr; 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 " SIP_SSIZE_T_FORMAT ": %U", i + 1, detail); #else failure = PyString_FromFormat( "\n overload " SIP_SSIZE_T_FORMAT ": %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. */ 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( "argument '%s' has unexpected type '%s'", failure->arg_name, Py_TYPE(failure->detail_obj)->tp_name); #else detail = PyString_FromFormat( "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, "attempt to assign sequence of size " SIP_SSIZE_T_FORMAT " to slice of size " SIP_SSIZE_T_FORMAT, 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 result. */ static void sip_api_bad_catcher_result(PyObject *method) { PyObject *mname, *etype, *evalue, *etraceback; /* * Get the current exception object if there is one. Its string * representation will be used as the detail of a new exception. */ PyErr_Fetch(&etype, &evalue, &etraceback); PyErr_NormalizeException(&etype, &evalue, &etraceback); Py_XDECREF(etraceback); /* * 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 (evalue != NULL) { #if PY_MAJOR_VERSION >= 3 PyErr_Format(etype, "invalid result from %s.%U(), %S", Py_TYPE(PyMethod_GET_SELF(method))->tp_name, mname, evalue); #else PyObject *evalue_s = PyObject_Str(evalue); PyErr_Format(etype, "invalid result from %s.%s(), %s", Py_TYPE(PyMethod_GET_SELF(method))->tp_name, PyString_AsString(mname), PyString_AsString(evalue_s)); Py_XDECREF(evalue_s); #endif Py_DECREF(evalue); } else { #if PY_MAJOR_VERSION >= 3 PyErr_Format(PyExc_TypeError, "invalid result from %s.%U()", Py_TYPE(PyMethod_GET_SELF(method))->tp_name, mname); #else PyErr_Format(PyExc_TypeError, "invalid result from %s.%s()", Py_TYPE(PyMethod_GET_SELF(method))->tp_name, PyString_AsString(mname)); #endif } Py_XDECREF(etype); } /* * 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. This is * deprecated because it is the equivalent of sip_api_transfer_to(self, NULL). */ 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)) { sipSimpleWrapper *sw = (sipSimpleWrapper *)self; if (owner == NULL) { /* There is no owner. */ if (sipCppHasRef(sw)) { sipResetCppHasRef(sw); } else { Py_INCREF(sw); removeFromParent((sipWrapper *)sw); sipResetPyOwned(sw); } Py_DECREF(sw); } else if (owner == Py_None) { /* * The owner is a C++ instance and not a Python object (ie. there * is no parent) so there is an explicit extra reference to keep * this Python object alive. Note that there is no way to * specify this from a .sip file - it is useful when embedding in * C/C++ applications. */ if (!sipCppHasRef(sw)) { Py_INCREF(sw); removeFromParent((sipWrapper *)sw); sipResetPyOwned(sw); sipSetCppHasRef(sw); } } else if (PyObject_TypeCheck(owner, (PyTypeObject *)&sipWrapper_Type)) { /* * The owner is a Python object (ie. the C++ instance that the * Python object wraps). */ if (sipCppHasRef(sw)) { sipResetCppHasRef(sw); } else { Py_INCREF(sw); removeFromParent((sipWrapper *)sw); sipResetPyOwned(sw); } addToParent((sipWrapper *)sw, (sipWrapper *)owner); Py_DECREF(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", ×tampName) < 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; case 'w': /* The hack for wchar_t. */ #if defined(HAVE_WCHAR_H) w = PyUnicode_FromWideChar((const wchar_t *)si->si_val, 1); break; #else raiseNoWChar(); return -1; #endif case 'W': /* The hack for wchar_t*. */ #if defined(HAVE_WCHAR_H) w = PyUnicode_FromWideChar((const wchar_t *)si->si_val, wcslen((const wchar_t *)si->si_val)); break; #else raiseNoWChar(); return -1; #endif 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 (sipTypeIsEnum(td) || sipTypeIsScopedEnum(td)) { obj = sip_api_convert_from_enum(*(int *)cppPtr, td); } else { sipConvertFromFunc cfrom; cppPtr = resolve_proxy(td, cppPtr); cfrom = get_from_convertor(td); if (cfrom != NULL) obj = cfrom(cppPtr, NULL); else obj = wrap_simple_instance(cppPtr, td, NULL, initflags); } 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 GIL 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; #ifdef WITH_THREAD *gil = PyGILState_Ensure(); #endif /* * 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) sipSelf = deref_mixin(sipSelf); if (sipSelf == NULL) goto release_gil; /* * It's possible that the object's type's tp_mro is NULL. A possible * circumstance is when a type has been created dynamically and the only * reference to it is the single instance of the type which is in the * process of being garbage collected. */ cls = (PyObject *)Py_TYPE(sipSelf); mro = ((PyTypeObject *)cls)->tp_mro; if (mro == NULL) goto release_gil; /* Get any reimplementation. */ #if PY_MAJOR_VERSION >= 3 mname_obj = PyUnicode_FromString(mname); #else mname_obj = PyString_FromString(mname); #endif if (mname_obj == NULL) goto release_gil; /* * 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). However that means we must explicitly check that the class * hierarchy is fully initialised. */ if (add_all_lazy_attrs(((sipWrapperType *)Py_TYPE(sipSelf))->wt_td) < 0) { Py_DECREF(mname_obj); goto release_gil; } 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; } } assert(PyTuple_Check(mro)); reimp = NULL; for (i = 0; i < PyTuple_GET_SIZE(mro); ++i) { PyObject *cls_dict, *cls_attr; 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 /* * Check any possible reimplementation is not the wrapped C++ method or * a default special method implementation. */ if (cls_dict != NULL && (cls_attr = PyDict_GetItem(cls_dict, mname_obj)) != NULL && Py_TYPE(cls_attr) != &sipMethodDescr_Type && Py_TYPE(cls_attr) != &PyWrapperDescr_Type) { reimp = cls_attr; break; } } Py_DECREF(mname_obj); if (reimp != NULL) { /* * Emulate the behaviour of a descriptor to make sure we return a bound * 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 } } else if (PyFunction_Check(reimp)) { #if PY_MAJOR_VERSION >= 3 reimp = PyMethod_New(reimp, (PyObject *)sipSelf); #else reimp = PyMethod_New(reimp, (PyObject *)sipSelf, cls); #endif } else if (Py_TYPE(reimp)->tp_descr_get) { /* It is a descriptor, so assume it will do the right thing. */ reimp = Py_TYPE(reimp)->tp_descr_get(reimp, (PyObject *)sipSelf, cls); } else { /* * We don't know what it is so just return and assume that an * appropriate exception will be raised later on. */ Py_INCREF(reimp); } } else { /* 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; release_gil: #ifdef WITH_THREAD PyGILState_Release(*gil); #endif return NULL; } /* * 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); } /* * The default access function. */ void *sip_api_get_address(sipSimpleWrapper *w) { return (w->access_func != NULL) ? w->access_func(w, GuardedPointer) : w->data; } /* * The access function for handwritten access functions. */ static void *explicit_access_func(sipSimpleWrapper *sw, AccessFuncOp op) { typedef void *(*explicitAccessFunc)(void); if (op == ReleaseGuard) return NULL; return ((explicitAccessFunc)(sw->data))(); } /* * The access function for indirect access. */ static void *indirect_access_func(sipSimpleWrapper *sw, AccessFuncOp op) { void *addr; switch (op) { case UnguardedPointer: addr = sw->data; break; case GuardedPointer: addr = *((void **)sw->data); break; default: addr = NULL; } return addr; } /* * Get the C/C++ pointer for a complex object. Note that not casting the C++ * pointer is a bug. However this would only ever be 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 = sip_api_get_address(sw); if (checkPointer(ptr, sw) < 0) return NULL; if (td != NULL) { if (PyObject_TypeCheck((PyObject *)sw, sipTypeAsPyTypeObject(td))) { sipCastFunc cast = ((const sipClassTypeDef *)((sipWrapperType *)Py_TYPE(sw))->wt_td)->ctd_cast; /* Handle any multiple inheritance. */ if (cast != NULL) ptr = (*cast)(ptr, td); } else { ptr = NULL; } 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; } /* * Check that a pointer is non-NULL. */ static int checkPointer(void *ptr, sipSimpleWrapper *sw) { if (ptr == NULL) { PyErr_Format(PyExc_RuntimeError, (sipWasCreated(sw) ? "wrapped C/C++ object of type %s has been deleted" : "super-class __init__() of type %s was never called"), Py_TYPE(sw)->tp_name); 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. */ 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); } } /* * Get an object that has an extra reference. */ static PyObject *sip_api_get_reference(PyObject *self, int key) { PyObject *dict, *key_obj, *obj; /* Get the extra references dictionary if there is one. */ if ((dict = ((sipSimpleWrapper *)self)->extra_refs) == NULL) return NULL; #if PY_MAJOR_VERSION >= 3 key_obj = PyLong_FromLong(key); #else key_obj = PyInt_FromLong(key); #endif if (key_obj == NULL) return NULL; obj = PyDict_GetItem(dict, key_obj); Py_XINCREF(obj); return obj; } /* * Return TRUE if an object is owned by Python. Note that this isn't * implemented as a macro in sip.h because the position of the sw_flags field * is dependent on the version of Python. */ static int sip_api_is_owned_by_python(sipSimpleWrapper *sw) { return sipIsPyOwned(sw); } /* * Return TRUE if the type of a C++ instance is a derived class. Note that * this isn't implemented as a macro in sip.h because the position of the * sw_flags field is dependent on the version of Python. */ static int sip_api_is_derived_class(sipSimpleWrapper *sw) { return sipIsDerived(sw); } /* * Get the user defined object from a wrapped object. Note that this isn't * implemented as a macro in sip.h because the position of the user field is * dependent on the version of Python. */ static PyObject *sip_api_get_user_object(const sipSimpleWrapper *sw) { return sw->user; } /* * Set the user defined object in a wrapped object. Note that this isn't * implemented as a macro in sip.h because the position of the user field is * dependent on the version of Python. */ static void sip_api_set_user_object(sipSimpleWrapper *sw, PyObject *user) { sw->user = user; } /* * 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(td == NULL || sipTypeIsClass(td) || sipTypeIsMapped(td)); if (td == NULL) { /* * The type must be /External/ and the module that contains the * implementation hasn't been imported. */ ok = FALSE; } else 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. */ 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; sipConvertFromFunc cfrom; assert(sipTypeIsClass(td) || sipTypeIsMapped(td)); /* Handle None. */ if (cpp == NULL) { Py_INCREF(Py_None); return Py_None; } cpp = resolve_proxy(td, cpp); cfrom = get_from_convertor(td); if (cfrom != NULL) return cfrom(cpp, transferObj); /* * See if we have already wrapped it. Invoking sub-class code can be * expensive so we check the cache first, even though the sub-class code * might perform a down-cast. */ if ((py = sip_api_get_pyobject(cpp, td)) == NULL && sipTypeHasSCC(td)) { void *orig_cpp = cpp; const sipTypeDef *orig_td = td; /* Apply the sub-class convertor. */ td = convertSubClass(td, &cpp); /* * If the sub-class convertor has done something then check the cache * again using the modified values. */ if (cpp != orig_cpp || td != orig_td) py = sip_api_get_pyobject(cpp, td); } if (py != NULL) Py_INCREF(py); else if ((py = wrap_simple_instance(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; sipConvertFromFunc cfrom; /* Handle None. */ if (cpp == NULL) { Py_INCREF(Py_None); return Py_None; } cpp = resolve_proxy(td, cpp); cfrom = get_from_convertor(td); if (cfrom != NULL) { PyObject *res = 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 we are wrapping a * class. */ if (transferObj == NULL || transferObj == Py_None) release(cpp, td, 0); } return res; } /* 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 wrap_simple_instance(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 void *tdp = &module_searched->em_types[etd->et_nr]; if (tdp == 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 unscoped 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; #if PY_MAJOR_VERSION >= 3 /* Get the builtins module. */ if ((mod = PyDict_GetItemString(dictofmods, "builtins")) == NULL) return; #else /* Get the __builtin__ module. */ if ((mod = PyDict_GetItemString(dictofmods, "__builtin__")) == NULL) return; #endif /* 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_Call(hook, empty_tuple, 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) { /* Handle the trivial case. */ if (*cppPtr == NULL) return NULL; /* Try the conversions until told to stop. */ while (convertPass(&td, cppPtr)) ; return td; } /* * Do a single pass through the available convertors. */ static int convertPass(const sipTypeDef **tdp, void **cppPtr) { PyTypeObject *py_type = sipTypeAsPyTypeObject(*tdp); sipExportedModuleDef *em; /* * 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) { PyTypeObject *base_type, *tp; /* * 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. Note that * we only consider direct sub-classes so that (for example) a * QLayout is only handled by the QObject convertor and not by the * QLayoutItem convertor. */ base_type = sipTypeAsPyTypeObject(scc->scc_basetype); for (tp = py_type; tp != NULL; tp = tp->tp_base) if (tp == base_type) break; if (tp != NULL) { void *ptr = *cppPtr; const sipTypeDef *sub_td; if ((sub_td = (*scc->scc_convertor)(&ptr)) != NULL) { PyTypeObject *sub_type = sipTypeAsPyTypeObject(sub_td); /* * 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 (!PyType_IsSubtype(py_type, sub_type)) { *tdp = sub_td; *cppPtr = ptr; /* * Finally we allow the convertor to return a type that * is apparently unrelated to the current convertor. * This causes the whole process to be restarted with * the new values. The use case is PyQt's QLayoutItem. */ return !PyType_IsSubtype(sub_type, base_type); } } } ++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 FALSE; } /* * 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 = wrap_simple_instance(ptr, td, NULL, SIP_PY_OWNED); PyErr_SetObject((PyObject *)sipTypeAsPyTypeObject(td), self); Py_XDECREF(self); SIP_UNBLOCK_THREADS } /* * Return the generated type structure of an encoded type. */ static sipTypeDef *getGeneratedType(const sipEncodedTypeDef *enc, sipExportedModuleDef *em) { if (enc->sc_module == 255) return em->em_types[enc->sc_type]; return em->em_imports[enc->sc_module].im_imported_types[enc->sc_type].it_td; } /* * Return the generated class type structure of a class's super-class. */ sipClassTypeDef *sipGetGeneratedClassType(const sipEncodedTypeDef *enc, const sipClassTypeDef *ctd) { return (sipClassTypeDef *)getGeneratedType(enc, ctd->ctd_base.td_module); } /* * 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)) { const sipClassTypeDef *ctd; ctd = (sipClassTypeDef *)((sipWrapperType *)(py_type))->wt_td; slot = findSlotInClass(ctd, st); } 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 = findSlotInSlotList(etd->etd_pyslots, st); } return slot; } /* * Find a particular slot function in a class hierarchy. */ static void *findSlotInClass(const sipClassTypeDef *ctd, sipPySlotType st) { void *slot; if (ctd->ctd_pyslots != NULL) slot = findSlotInSlotList(ctd->ctd_pyslots, st); else slot = NULL; if (slot == NULL) { sipEncodedTypeDef *sup; /* Search any super-types. */ if ((sup = ctd->ctd_supers) != NULL) { do { const sipClassTypeDef *sup_ctd = sipGetGeneratedClassType( sup, ctd); slot = findSlotInClass(sup_ctd, st); } while (slot == NULL && !sup++->sc_flag); } } return slot; } /* * Find a particular slot function in a particular type. */ static void *findSlotInSlotList(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))->wt_td; return (sipNotInMap(self) ? NULL : sip_api_get_address(self)); } /* * 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) { assert(!sipTypeIsEnum(currentType)); ((sipWrapperType *)o)->wt_td = currentType; if (sipTypeIsClass(currentType)) { const sipClassTypeDef *ctd = (const sipClassTypeDef *)currentType; const char *docstring = ctd->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, ctd); /* Patch any mixin initialiser. */ if (ctd->ctd_init_mixin != NULL) ((PyTypeObject *)o)->tp_init = ctd->ctd_init_mixin; } } 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->wt_td == NULL) { PyTypeObject *base = ((PyTypeObject *)self)->tp_base; self->wt_user_type = TRUE; /* * 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)) { /* TODO: Deprecate this mechanism in favour of an event handler. */ sipNewUserTypeFunc new_user_type_handler; self->wt_td = ((sipWrapperType *)base)->wt_td; if (self->wt_td != NULL) { /* Call any new type handler. */ new_user_type_handler = find_new_user_type_handler( (sipWrapperType *)sipTypeAsPyTypeObject(self->wt_td)); if (new_user_type_handler != NULL) if (new_user_type_handler(self) < 0) return -1; } } } else { /* * We must be a generated type so remember the type object in the * generated type structure. */ assert(self->wt_td->u.td_py_type == NULL); self->wt_td->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)->wt_td) < 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)->wt_td) < 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) { sipTypeDef *td = wt->wt_td; (void)args; (void)kwds; /* 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 (add_all_lazy_attrs(td) < 0) 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(get_container(td), 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(get_container(td), td)); return NULL; } /* * See if the object is being created explicitly rather than being wrapped. */ if (!sipIsPending()) { /* * 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(get_container(td), td)); return NULL; } /* See if it is an abstract type. */ if (sipTypeIsAbstract(td) && !wt->wt_user_type && ((sipClassTypeDef *)td)->ctd_init_mixin == NULL) { PyErr_Format(PyExc_TypeError, "%s.%s represents a C++ abstract class and cannot be instantiated", sipNameOfModule(td->td_module), sipPyNameOfContainer(get_container(td), td)); return NULL; } } /* Call the standard super-type new. */ return PyBaseObject_Type.tp_new((PyTypeObject *)wt, empty_tuple, NULL); } /* * The instance init slot. */ static int sipSimpleWrapper_init(sipSimpleWrapper *self, PyObject *args, PyObject *kwds) { void *sipNew; int sipFlags, from_cpp = TRUE; sipWrapper *owner; sipWrapperType *wt = (sipWrapperType *)Py_TYPE(self); sipTypeDef *td = wt->wt_td; sipClassTypeDef *ctd = (sipClassTypeDef *)td; PyObject *unused = NULL; sipFinalFunc final_func = find_finalisation(ctd); /* Check for an existing C++ instance waiting to be wrapped. */ if (sipGetPending(&sipNew, &owner, &sipFlags) < 0) return -1; if (sipNew == NULL) { PyObject *parseErr = NULL, **unused_p = NULL; /* See if we are interested in any unused keyword arguments. */ if (sipTypeCallSuperInit(&ctd->ctd_base) || final_func != NULL || kw_handler != NULL) unused_p = &unused; /* 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->wt_iextend; /* * 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, (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; } /* The instance was created from Python. */ from_cpp = FALSE; } /* Handler any owner if the type supports the concept. */ if (PyObject_TypeCheck((PyObject *)self, (PyTypeObject *)&sipWrapper_Type)) { /* * The application may be doing something very unadvisable (like * calling __init__() for a second time), so make sure we don't already * have a parent. */ removeFromParent((sipWrapper *)self); if (owner != NULL) { assert(PyObject_TypeCheck((PyObject *)owner, (PyTypeObject *)&sipWrapper_Type)); addToParent((sipWrapper *)self, (sipWrapper *)owner); } } self->data = sipNew; self->sw_flags = sipFlags | SIP_CREATED; /* Set the access function. */ if (sipIsAccessFunc(self)) self->access_func = explicit_access_func; else if (sipIsIndirect(self)) self->access_func = indirect_access_func; else self->access_func = NULL; if (!sipNotInMap(self)) sipOMAddObject(&cppPyMap, self); /* If we are wrapping an instance returned from C/C++ then we are done. */ if (from_cpp) { /* * Invoke any event handlers for instances that are accessed directly. */ if (self->access_func == NULL) { sipEventHandler *eh; for (eh = event_handlers[sipEventWrappedInstance]; eh != NULL; eh = eh->next) { if (is_subtype(ctd, eh->ctd)) { sipWrappedInstanceEventHandler handler = (sipWrappedInstanceEventHandler)eh->handler; handler(sipNew); } } } return 0; } /* Call any finalisation code. */ if (final_func != NULL) { PyObject *new_unused = NULL, **new_unused_p; if (unused == NULL || unused != kwds) { /* * There are no unused arguments or we have already created a dict * containing the unused sub-set, so there is no need to create * another. */ new_unused_p = NULL; } else { /* * All of the keyword arguments are unused, so if some of them are * now going to be used then a new dict will be needed. */ new_unused_p = &new_unused; } if (final_func((PyObject *)self, sipNew, unused, new_unused_p) < 0) { Py_XDECREF(unused); return -1; } if (new_unused != NULL) { Py_DECREF(unused); unused = new_unused; } } /* Call the handler if we have one. Remove this in SIP v5. */ if (kw_handler != NULL && unused != NULL && isQObject((PyObject *)self)) { int rc = kw_handler((PyObject *)self, sipNew, unused); /* * A handler will always consume all unused keyword arguments (or raise * an exception) so discard the dict now. */ Py_DECREF(unused); if (rc < 0) return -1; unused = NULL; } /* See if we should call the equivalent of super().__init__(). */ if (sipTypeCallSuperInit(&ctd->ctd_base)) { PyObject *next; /* Find the next type in the MRO. */ next = next_in_mro((PyObject *)self, (PyObject *)&sipSimpleWrapper_Type); /* * If the next type in the MRO is object then take a shortcut by not * calling super().__init__() but emulating object.__init__() instead. * This will be the most common case and also allows us to generate a * better exception message if there are unused keyword arguments. The * disadvantage is that the exception message will be different if * there is a mixin. */ if (next != (PyObject *)&PyBaseObject_Type) { int rc = super_init((PyObject *)self, empty_tuple, unused, next); Py_XDECREF(unused); return rc; } } if (unused_backdoor != NULL) { /* * We are being called by a mixin's __init__ so save any unused * arguments for it to pass on to the main class's __init__. */ *unused_backdoor = unused; } else if (unused != NULL) { /* We shouldn't have any unused keyword arguments. */ if (PyDict_Size(unused) != 0) { PyObject *key, *value; SIP_SSIZE_T pos = 0; /* Just report one of the unused arguments. */ PyDict_Next(unused, &pos, &key, &value); #if PY_MAJOR_VERSION >= 3 PyErr_Format(PyExc_TypeError, "'%S' is an unknown keyword argument", key); #else { PyObject *key_s = PyObject_Str(key); if (key_s != NULL) { PyErr_Format(PyExc_TypeError, "'%s' is an unknown keyword argument", PyString_AsString(key_s)); Py_DECREF(key_s); } } #endif Py_DECREF(unused); return -1; } Py_DECREF(unused); } return 0; } /* * Get the C++ address of a mixin. */ static void *sip_api_get_mixin_address(sipSimpleWrapper *w, const sipTypeDef *td) { PyObject *mixin; void *cpp; if ((mixin = PyObject_GetAttrString((PyObject *)w, sipTypeName(td))) == NULL) { PyErr_Clear(); return NULL; } cpp = sip_api_get_address((sipSimpleWrapper *)mixin); Py_DECREF(mixin); return cpp; } /* * Initialise a mixin. */ static int sip_api_init_mixin(PyObject *self, PyObject *args, PyObject *kwds, const sipClassTypeDef *ctd) { int rc; SIP_SSIZE_T pos; PyObject *unused, *mixin, *mixin_name, *key, *value; PyTypeObject *self_wt = sipTypeAsPyTypeObject(((sipWrapperType *)Py_TYPE(self))->wt_td); PyTypeObject *wt = sipTypeAsPyTypeObject(&ctd->ctd_base); #if PY_MAJOR_VERSION >= 3 static PyObject *double_us = NULL; if (objectify("__", &double_us) < 0) return -1; #endif /* If we are not a mixin to another wrapped class then behave as normal. */ if (PyType_IsSubtype(self_wt, wt)) return super_init(self, args, kwds, next_in_mro(self, (PyObject *)wt)); /* * Create the mixin instance. Retain the positional arguments for the * super-class. Remember that, even though the mixin appears after the * main class in the MRO, it appears before sipWrapperType where the main * class's arguments are actually parsed. */ unused = NULL; unused_backdoor = &unused; mixin = PyObject_Call((PyObject *)wt, empty_tuple, kwds); unused_backdoor = NULL; if (mixin == NULL) goto gc_unused; /* Make sure the mixin can find the main instance. */ ((sipSimpleWrapper *)mixin)->mixin_main = self; Py_INCREF(self); #if PY_MAJOR_VERSION >= 3 mixin_name = PyUnicode_FromString(sipTypeName(&ctd->ctd_base)); #else mixin_name = PyString_FromString(sipTypeName(&ctd->ctd_base)); #endif if (mixin_name == NULL) { Py_DECREF(mixin); goto gc_unused; } rc = PyObject_SetAttr(self, mixin_name, mixin); Py_DECREF(mixin); if (rc < 0) goto gc_mixin_name; /* Add the mixin's useful attributes to the main class. */ pos = 0; while (PyDict_Next(wt->tp_dict, &pos, &key, &value)) { /* Don't replace existing values. */ if (PyDict_Contains(Py_TYPE(self)->tp_dict, key) != 0) continue; /* Skip values with names that start with double underscore. */ #if PY_MAJOR_VERSION >= 3 if (!PyUnicode_Check(key)) continue; /* * Despite what the docs say this returns a Py_ssize_t - although the * docs are probably right. */ rc = (int)PyUnicode_Tailmatch(key, double_us, 0, 2, -1); if (rc < 0) goto gc_mixin_name; if (rc > 0) continue; #else if (!PyString_Check(key)) continue; if (PyString_GET_SIZE(key) >= 2 && strncmp(PyString_AS_STRING(key), "__", 2) == 0) continue; #endif if (PyObject_IsInstance(value, (PyObject *)&sipMethodDescr_Type)) { if ((value = sipMethodDescr_Copy(value, mixin_name)) == NULL) goto gc_mixin_name; } else if (PyObject_IsInstance(value, (PyObject *)&sipVariableDescr_Type)) { if ((value = sipVariableDescr_Copy(value, mixin_name)) == NULL) goto gc_mixin_name; } else { Py_INCREF(value); } rc = PyDict_SetItem(Py_TYPE(self)->tp_dict, key, value); Py_DECREF(value); if (rc < 0) goto gc_mixin_name; } Py_DECREF(mixin_name); /* Call the super-class's __init__ with any remaining arguments. */ rc = super_init(self, args, unused, next_in_mro(self, (PyObject *)wt)); Py_XDECREF(unused); return rc; gc_mixin_name: Py_DECREF(mixin_name); gc_unused: Py_XDECREF(unused); return -1; } /* * Return the next in the MRO of an instance after a given type. */ static PyObject *next_in_mro(PyObject *self, PyObject *after) { SIP_SSIZE_T i; PyObject *mro; mro = Py_TYPE(self)->tp_mro; assert(PyTuple_Check(mro)); for (i = 0; i < PyTuple_GET_SIZE(mro); ++i) if (PyTuple_GET_ITEM(mro, i) == after) break; /* Assert that we have found ourself and that we are not the last. */ assert(i + 1 < PyTuple_GET_SIZE(mro)); return PyTuple_GET_ITEM(mro, i + 1); } /* * Call the equivalent of super()__init__() of an instance. */ static int super_init(PyObject *self, PyObject *args, PyObject *kwds, PyObject *type) { int i; PyObject *init, *init_args, *init_res; if ((init = PyObject_GetAttr(type, init_name)) == NULL) return -1; if ((init_args = PyTuple_New(1 + PyTuple_GET_SIZE(args))) == NULL) { Py_DECREF(init); return -1; } PyTuple_SET_ITEM(init_args, 0, self); Py_INCREF(self); for (i = 0; i < PyTuple_GET_SIZE(args); ++i) { PyObject *arg = PyTuple_GET_ITEM(args, i); PyTuple_SET_ITEM(init_args, 1 + i, arg); Py_INCREF(arg); } init_res = PyObject_Call(init, init_args, kwds); Py_DECREF(init_args); Py_DECREF(init); Py_XDECREF(init_res); return (init_res != NULL) ? 0 : -1; } /* * Find any finalisation function for a class, searching its super-classes if * necessary. */ static sipFinalFunc find_finalisation(sipClassTypeDef *ctd) { sipEncodedTypeDef *sup; if (ctd->ctd_final != NULL) return ctd->ctd_final; if ((sup = ctd->ctd_supers) != NULL) do { sipClassTypeDef *sup_ctd = sipGetGeneratedClassType(sup, ctd); sipFinalFunc func; if ((func = find_finalisation(sup_ctd)) != NULL) return func; } while (!sup++->sc_flag); return NULL; } /* * Find any new user type handler function for a class, searching its * super-classes if necessary. */ static sipNewUserTypeFunc find_new_user_type_handler(sipWrapperType *wt) { sipEncodedTypeDef *sup; sipClassTypeDef *ctd; if (wt->wt_new_user_type_handler != NULL) return wt->wt_new_user_type_handler; ctd = (sipClassTypeDef *)wt->wt_td; if ((sup = ctd->ctd_supers) != NULL) { do { sipTypeDef *sup_td = getGeneratedType(sup, ctd->ctd_base.td_module); sipNewUserTypeFunc func; wt = (sipWrapperType *)sipTypeAsPyTypeObject(sup_td); if ((func = find_new_user_type_handler(wt)) != NULL) return func; } while (!sup++->sc_flag); } return NULL; } /* * 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) { const sipEncodedTypeDef *sup; if ((sup = ctd->ctd_supers) != NULL) do sup_ctd = sipGetGeneratedClassType(sup, ctd); 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; if (self->mixin_main != NULL) if ((vret = visit(self->mixin_main, 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 = sipGetGeneratedClassType(sup, ctd); 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); /* Remove any mixin main. */ tmp = self->mixin_main; self->mixin_main = 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; if (sipTypeUseLimitedAPI(&ctd->ctd_base)) { sipGetBufferFuncLimited getbuffer = (sipGetBufferFuncLimited)ctd->ctd_getbuffer; sipBufferDef bd; /* * Ensure all fields have a default value. This means that extra * fields can be appended in the future that older handwritten code * doesn't know about. */ memset(&bd, 0, sizeof(sipBufferDef)); if (getbuffer((PyObject *)self, ptr, &bd) < 0) return -1; return PyBuffer_FillInfo(buf, (PyObject *)self, bd.bd_buffer, bd.bd_length, bd.bd_readonly, flags); } 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; if (sipTypeUseLimitedAPI(&ctd->ctd_base)) { sipReleaseBufferFuncLimited releasebuffer = (sipReleaseBufferFuncLimited)ctd->ctd_releasebuffer; releasebuffer((PyObject *)self, ptr); 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. */ static PyObject *slot_call(PyObject *self, PyObject *args, PyObject *kw) { PyObject *(*f)(PyObject *, PyObject *, PyObject *); f = (PyObject *(*)(PyObject *, PyObject *, PyObject *))findSlot(self, call_slot); assert(f != NULL); return f(self, args, kw); } /* * 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 __dict__ getter. */ static PyObject *sipSimpleWrapper_get_dict(sipSimpleWrapper *sw, void *closure) { (void)closure; /* 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(sipSimpleWrapper *sw, PyObject *value, void *closure) { (void)closure; /* 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__", (getter)sipSimpleWrapper_get_dict, (setter)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_as_async (Python v3.5), 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)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 */ 0, /* tp_is_gc */ 0, /* tp_bases */ 0, /* tp_mro */ 0, /* tp_cache */ 0, /* tp_subclasses */ 0, /* tp_weaklist */ 0, /* tp_del */ 0, /* tp_version_tag */ #if PY_VERSION_HEX >= 0x03040000 0, /* tp_finalize */ #endif }, #if PY_VERSION_HEX >= 0x03050000 { 0, /* am_await */ 0, /* am_aiter */ 0, /* am_anext */ }, #endif { 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 0, /* nb_int */ 0, /* nb_reserved (Python v3), nb_long (Python v2) */ 0, /* nb_float */ #if PY_MAJOR_VERSION < 3 0, /* nb_oct */ 0, /* 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 */ #if PY_VERSION_HEX >= 0x02020000 0, /* nb_floor_divide */ 0, /* nb_true_divide */ 0, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ #endif #if PY_VERSION_HEX >= 0x02050000 0, /* nb_index */ #endif #if PY_VERSION_HEX >= 0x03050000 0, /* nb_matrix_multiply */ 0, /* nb_inplace_matrix_multiply */ #endif }, { 0, /* mp_length */ 0, /* mp_subscript */ 0, /* mp_ass_subscript */ }, { 0, /* sq_length */ 0, /* sq_concat */ 0, /* sq_repeat */ 0, /* sq_item */ 0, /* was_sq_slice */ 0, /* sq_ass_item */ 0, /* was_sq_ass_slice */ 0, /* sq_contains */ 0, /* sq_inplace_concat */ 0, /* sq_inplace_repeat */ }, { #if PY_MAJOR_VERSION >= 3 0, /* bf_getbuffer */ 0, /* bf_releasebuffer */ #else 0, /* bf_getreadbuffer */ 0, /* bf_getwritebuffer */ 0, /* bf_getsegcount */ 0, /* bf_getcharbuffer */ 0, /* bf_getbuffer */ 0, /* bf_releasebuffer */ #endif }, 0, /* ht_name */ 0, /* ht_slots */ #if PY_MAJOR_VERSION >= 3 0, /* ht_qualname */ 0, /* ht_cached_keys */ #endif #if !defined(STACKLESS) }, #endif 0, /* wt_user_type */ 0, /* wt_dict_complete */ 0, /* wt_unused */ 0, /* wt_td */ 0, /* wt_iextend */ 0, /* wt_new_user_type_handler */ 0, /* wt_user_data */ }; /* * 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) && !sipNotInMap(sw)) { void *tx = sip_api_get_address(sw); if (tx != NULL) { sipSlot *slot; void *context = NULL; assert (sipQtSupport->qt_find_sipslot); 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) 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. The map check is a bit of a * hack to work around PyQt4 problems with qApp and a user created * instance. qt_find_sipslot() will return the same slot information for * both causing the gc module to trigger assert() failures. */ if (sipQtSupport != NULL && sipQtSupport->qt_find_sipslot && !sipNotInMap(sw)) { void *tx = sip_api_get_address(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, const sipClassTypeDef *ctd) { PyHeapTypeObject *heap_to = &wt->super; PyBufferProcs *bp = &heap_to->as_buffer; /* Add the buffer interface. */ #if PY_MAJOR_VERSION >= 3 if (ctd->ctd_getbuffer != NULL) bp->bf_getbuffer = (getbufferproc)sipSimpleWrapper_getbuffer; if (ctd->ctd_releasebuffer != NULL) bp->bf_releasebuffer = (releasebufferproc)sipSimpleWrapper_releasebuffer; #else if (ctd->ctd_readbuffer != NULL) #if PY_VERSION_HEX >= 0x02050000 bp->bf_getreadbuffer = (readbufferproc)sipSimpleWrapper_getreadbuffer; #else bp->bf_getreadbuffer = (getreadbufferproc)sipSimpleWrapper_getreadbuffer; #endif if (ctd->ctd_writebuffer != NULL) #if PY_VERSION_HEX >= 0x02050000 bp->bf_getwritebuffer = (writebufferproc)sipSimpleWrapper_getwritebuffer; #else bp->bf_getwritebuffer = (getwritebufferproc)sipSimpleWrapper_getwritebuffer; #endif if (ctd->ctd_segcount != NULL) #if PY_VERSION_HEX >= 0x02050000 bp->bf_getsegcount = (segcountproc)sipSimpleWrapper_getsegcount; #else bp->bf_getsegcount = (getsegcountproc)sipSimpleWrapper_getsegcount; #endif if (ctd->ctd_charbuffer != NULL) #if PY_VERSION_HEX >= 0x02050000 bp->bf_getcharbuffer = (charbufferproc)sipSimpleWrapper_getcharbuffer; #else bp->bf_getcharbuffer = (getcharbufferproc)sipSimpleWrapper_getcharbuffer; #endif #endif /* Add the slots for this type. */ if (ctd->ctd_pyslots != NULL) addTypeSlots(heap_to, 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; #if PY_VERSION_HEX >= 0x03050000 PyAsyncMethods *am; #endif void *f; to = &heap_to->ht_type; nb = &heap_to->as_number; sq = &heap_to->as_sequence; mp = &heap_to->as_mapping; #if PY_VERSION_HEX >= 0x03050000 am = &heap_to->as_async; #endif while ((f = slots->psd_func) != NULL) switch (slots++->psd_type) { case str_slot: to->tp_str = (reprfunc)f; break; case int_slot: nb->nb_int = (unaryfunc)f; break; #if PY_MAJOR_VERSION < 3 case long_slot: nb->nb_long = (unaryfunc)f; break; #endif case float_slot: nb->nb_float = (unaryfunc)f; break; case len_slot: #if PY_VERSION_HEX >= 0x02050000 mp->mp_length = (lenfunc)f; sq->sq_length = (lenfunc)f; #else mp->mp_length = (inquiry)f; sq->sq_length = (inquiry)f; #endif break; case contains_slot: sq->sq_contains = (objobjproc)f; break; case add_slot: nb->nb_add = (binaryfunc)f; break; case concat_slot: sq->sq_concat = (binaryfunc)f; break; case sub_slot: nb->nb_subtract = (binaryfunc)f; break; case mul_slot: nb->nb_multiply = (binaryfunc)f; break; case repeat_slot: #if PY_VERSION_HEX >= 0x02050000 sq->sq_repeat = (ssizeargfunc)f; #else sq->sq_repeat = (intargfunc)f; #endif break; case div_slot: nb->nb_true_divide = (binaryfunc)f; #if PY_MAJOR_VERSION < 3 nb->nb_divide = (binaryfunc)f; #endif break; case mod_slot: nb->nb_remainder = (binaryfunc)f; break; case floordiv_slot: nb->nb_floor_divide = (binaryfunc)f; break; case truediv_slot: nb->nb_true_divide = (binaryfunc)f; break; case and_slot: nb->nb_and = (binaryfunc)f; break; case or_slot: nb->nb_or = (binaryfunc)f; break; case xor_slot: nb->nb_xor = (binaryfunc)f; break; case lshift_slot: nb->nb_lshift = (binaryfunc)f; break; case rshift_slot: nb->nb_rshift = (binaryfunc)f; break; case iadd_slot: nb->nb_inplace_add = (binaryfunc)f; break; case iconcat_slot: sq->sq_inplace_concat = (binaryfunc)f; break; case isub_slot: nb->nb_inplace_subtract = (binaryfunc)f; break; case imul_slot: nb->nb_inplace_multiply = (binaryfunc)f; break; case irepeat_slot: #if PY_VERSION_HEX >= 0x02050000 sq->sq_inplace_repeat = (ssizeargfunc)f; #else sq->sq_inplace_repeat = (intargfunc)f; #endif break; case idiv_slot: nb->nb_inplace_true_divide = (binaryfunc)f; #if PY_MAJOR_VERSION < 3 nb->nb_inplace_divide = (binaryfunc)f; #endif break; case imod_slot: nb->nb_inplace_remainder = (binaryfunc)f; break; case ifloordiv_slot: nb->nb_inplace_floor_divide = (binaryfunc)f; break; case itruediv_slot: nb->nb_inplace_true_divide = (binaryfunc)f; break; case iand_slot: nb->nb_inplace_and = (binaryfunc)f; break; case ior_slot: nb->nb_inplace_or = (binaryfunc)f; break; case ixor_slot: nb->nb_inplace_xor = (binaryfunc)f; break; case ilshift_slot: nb->nb_inplace_lshift = (binaryfunc)f; break; case irshift_slot: nb->nb_inplace_rshift = (binaryfunc)f; break; case invert_slot: nb->nb_invert = (unaryfunc)f; break; case call_slot: to->tp_call = slot_call; break; case getitem_slot: mp->mp_subscript = (binaryfunc)f; sq->sq_item = slot_sq_item; break; case setitem_slot: case delitem_slot: mp->mp_ass_subscript = slot_mp_ass_subscript; 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 PY_MAJOR_VERSION >= 3 nb->nb_bool = (inquiry)f; #else nb->nb_nonzero = (inquiry)f; #endif break; case neg_slot: 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: nb->nb_positive = (unaryfunc)f; break; case abs_slot: nb->nb_absolute = (unaryfunc)f; break; #if PY_VERSION_HEX >= 0x02050000 case index_slot: 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; case setattr_slot: to->tp_setattro = (setattrofunc)f; break; #if PY_VERSION_HEX >= 0x03050000 case matmul_slot: nb->nb_matrix_multiply = (binaryfunc)f; break; case imatmul_slot: nb->nb_inplace_matrix_multiply = (binaryfunc)f; break; case await_slot: am->am_await = (unaryfunc)f; break; case aiter_slot: am->am_aiter = (unaryfunc)f; break; case anext_slot: am->am_anext = (unaryfunc)f; break; #endif /* Suppress a compiler warning. */ default: ; } } /* * Remove the object from the map and call the C/C++ dtor if we own the * instance. */ static void forgetObject(sipSimpleWrapper *sw) { sipEventHandler *eh; const sipClassTypeDef *ctd = (const sipClassTypeDef *)((sipWrapperType *)Py_TYPE(sw))->wt_td; /* Invoke any event handlers. */ for (eh = event_handlers[sipEventCollectingWrapper]; eh != NULL; eh = eh->next) { if (is_subtype(ctd, eh->ctd)) { sipCollectingWrapperEventHandler handler = (sipCollectingWrapperEventHandler)eh->handler; handler(sw); } } /* * This is needed because we might 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); /* * 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); if (sipInterpreter != NULL || destroy_on_exit) { const sipClassTypeDef *ctd; if (getPtrTypeDef(sw, &ctd) != NULL && ctd->ctd_dealloc != NULL) ctd->ctd_dealloc(sw); } clear_access_func(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 * would only be 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 would only * be 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) ch = '\0'; return ch; } /* * Parse an ASCII character and return it. */ static int parseString_AsASCIIChar(PyObject *obj, char *ap) { if (parseString_AsEncodedChar(PyUnicode_AsASCIIString(obj), obj, ap) < 0) { /* Use the exception set if it was an encoding error. */ #if PY_VERSION_HEX >= 0x03030000 if (!PyUnicode_Check(obj) || PyUnicode_GET_LENGTH(obj) != 1) #else if (!PyUnicode_Check(obj) || PyUnicode_GET_SIZE(obj) != 1) #endif PyErr_SetString(PyExc_TypeError, #if PY_MAJOR_VERSION >= 3 "bytes or ASCII string of length 1 expected"); #else "string or ASCII unicode of length 1 expected"); #endif return -1; } return 0; } /* * 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) ch = '\0'; return ch; } /* * Parse a Latin-1 character and return it via a pointer. */ static int parseString_AsLatin1Char(PyObject *obj, char *ap) { if (parseString_AsEncodedChar(PyUnicode_AsLatin1String(obj), obj, ap) < 0) { /* Use the exception set if it was an encoding error. */ #if PY_VERSION_HEX >= 0x03030000 if (!PyUnicode_Check(obj) || PyUnicode_GET_LENGTH(obj) != 1) #else if (!PyUnicode_Check(obj) || PyUnicode_GET_SIZE(obj) != 1) #endif PyErr_SetString(PyExc_TypeError, #if PY_MAJOR_VERSION >= 3 "bytes or Latin-1 string of length 1 expected"); #else "string or Latin-1 unicode of length 1 expected"); #endif return -1; } return 0; } /* * 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) ch = '\0'; return ch; } /* * Parse a UTF-8 character and return it. */ static int parseString_AsUTF8Char(PyObject *obj, char *ap) { if (parseString_AsEncodedChar(PyUnicode_AsUTF8String(obj), obj, ap) < 0) { /* Use the exception set if it was an encoding error. */ #if PY_VERSION_HEX >= 0x03030000 if (!PyUnicode_Check(obj) || PyUnicode_GET_LENGTH(obj) != 1) #else if (!PyUnicode_Check(obj) || PyUnicode_GET_SIZE(obj) != 1) #endif PyErr_SetString(PyExc_TypeError, #if PY_MAJOR_VERSION >= 3 "bytes or UTF-8 string of length 1 expected"); #else "string or UTF-8 unicode of length 1 expected"); #endif return -1; } return 0; } /* * 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; } if (ap != NULL) *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; } /* Don't try anything else if there was an encoding error. */ if (PyUnicode_Check(obj)) return NULL; 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) { const char *a; SIP_SSIZE_T asz; if (obj == Py_None) { a = NULL; asz = 0; } else if (SIPBytes_Check(obj)) { a = SIPBytes_AS_STRING(obj); asz = SIPBytes_GET_SIZE(obj); } else if (PyObject_AsCharBuffer(obj, &a, &asz) < 0) { return -1; } if (ap != NULL) *ap = a; if (aszp != NULL) *aszp = asz; 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; if (ap != NULL) *ap = *chp; return 0; } /* * Parse a character string and return it. */ static int parseBytes_AsString(PyObject *obj, const char **ap) { const char *a; SIP_SSIZE_T sz; if (parseBytes_AsCharArray(obj, &a, &sz) < 0) return -1; if (ap != NULL) *ap = a; return 0; } #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) { wchar_t *a; SIP_SSIZE_T asz; if (obj == Py_None) { a = NULL; asz = 0; } else if (PyUnicode_Check(obj)) { if (convertToWCharArray(obj, &a, &asz) < 0) return -1; } #if PY_MAJOR_VERSION < 3 else if (PyString_Check(obj)) { int rc; PyObject *uobj; if ((uobj = PyUnicode_FromObject(obj)) == NULL) return -1; rc = convertToWCharArray(uobj, &a, &asz); Py_DECREF(uobj); if (rc < 0) return -1; } #endif else { return -1; } if (ap != NULL) *ap = a; if (aszp != NULL) *aszp = asz; return 0; } /* * 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; #if PY_VERSION_HEX >= 0x03030000 ulen = PyUnicode_GET_LENGTH(obj); #else ulen = PyUnicode_GET_SIZE(obj); #endif if ((wc = sip_api_malloc(ulen * sizeof (wchar_t))) == NULL) return -1; #if PY_VERSION_HEX >= 0x03020000 ulen = PyUnicode_AsWideChar(obj, wc, ulen); #else ulen = PyUnicode_AsWideChar((PyUnicodeObject *)obj, wc, ulen); #endif 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) { wchar_t a; if (PyUnicode_Check(obj)) { if (convertToWChar(obj, &a) < 0) return -1; } #if PY_MAJOR_VERSION < 3 else if (PyString_Check(obj)) { int rc; PyObject *uobj; if ((uobj = PyUnicode_FromObject(obj)) == NULL) return -1; rc = convertToWChar(uobj, &a); Py_DECREF(uobj); if (rc < 0) return -1; } #endif else { return -1; } if (ap != NULL) *ap = a; return 0; } /* * Convert a Unicode object to a wide character and return it. */ static int convertToWChar(PyObject *obj, wchar_t *ap) { #if PY_VERSION_HEX >= 0x03030000 if (PyUnicode_GET_LENGTH(obj) != 1) #else if (PyUnicode_GET_SIZE(obj) != 1) #endif return -1; #if PY_VERSION_HEX >= 0x03020000 if (PyUnicode_AsWideChar(obj, ap, 1) != 1) #else if (PyUnicode_AsWideChar((PyUnicodeObject *)obj, ap, 1) != 1) #endif return -1; return 0; } /* * Parse a wide character string and return a copy on the heap. */ static int parseWCharString(PyObject *obj, wchar_t **ap) { wchar_t *a; if (obj == Py_None) { a = NULL; } else if (PyUnicode_Check(obj)) { if (convertToWCharString(obj, &a) < 0) return -1; } #if PY_MAJOR_VERSION < 3 else if (PyString_Check(obj)) { int rc; PyObject *uobj; if ((uobj = PyUnicode_FromObject(obj)) == NULL) return -1; rc = convertToWCharString(uobj, &a); Py_DECREF(uobj); if (rc < 0) return -1; } #endif else { return -1; } if (ap != NULL) *ap = a; return 0; } /* * 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; #if PY_VERSION_HEX >= 0x03030000 ulen = PyUnicode_GET_LENGTH(obj); #else ulen = PyUnicode_GET_SIZE(obj); #endif if ((wc = sip_api_malloc((ulen + 1) * sizeof (wchar_t))) == NULL) return -1; #if PY_VERSION_HEX >= 0x03020000 ulen = PyUnicode_AsWideChar(obj, wc, ulen); #else ulen = PyUnicode_AsWideChar((PyUnicodeObject *)obj, wc, ulen); #endif 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); assert(sipTypeIsEnum(currentType)); /* 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); return (PyObject *)py_type; } /* * Check if an object is of the right type to convert to an encoded string. */ static int check_encoded_string(PyObject *obj) { if (obj == Py_None) return 0; if (PyUnicode_Check(obj)) return 0; if (SIPBytes_Check(obj)) return 0; if (PyObject_CheckReadBuffer(obj)) return 0; return -1; } /* * This is called by the atexit module. */ static PyObject *sip_exit(PyObject *self, PyObject *args) { (void)self; (void)args; /* Disable all Python reimplementations of virtuals. */ sipInterpreter = NULL; Py_INCREF(Py_None); return Py_None; } /* * Register the exit notifier with the atexit module. */ static void register_exit_notifier(void) { static PyMethodDef md = { "_sip_exit", sip_exit, METH_NOARGS, NULL }; PyObject *notifier, *register_func, *res; if ((notifier = PyCFunction_New(&md, NULL)) == NULL) return; if ((register_func = import_module_attr("atexit", "register")) == NULL) { Py_DECREF(notifier); return; } res = PyObject_CallFunctionObjArgs(register_func, notifier, NULL); Py_XDECREF(res); Py_DECREF(register_func); Py_DECREF(notifier); } /* * Return the function that converts a C++ instance to a Python object. */ static sipConvertFromFunc get_from_convertor(const sipTypeDef *td) { if (sipTypeIsMapped(td)) return ((const sipMappedTypeDef *)td)->mtd_cfrom; assert(sipTypeIsClass(td)); if (autoconversion_disabled(td) != NULL) return NULL; return ((const sipClassTypeDef *)td)->ctd_cfrom; } /* * Enable or disable the auto-conversion. Returns the previous enabled state * or -1 on error. */ static int sip_api_enable_autoconversion(const sipTypeDef *td, int enable) { sipPyObject **pop; assert(sipTypeIsClass(td)); pop = autoconversion_disabled(td); /* See if there is anything to do. */ if (pop == NULL && enable) return TRUE; if (pop != NULL && !enable) return FALSE; if (pop != NULL) { /* Remove it from the list. */ sipPyObject *po = *pop; *pop = po->next; sip_api_free(po); } else { /* Add it to the list. */ if (addPyObjectToList(&sipDisabledAutoconversions, (PyObject *)sipTypeAsPyTypeObject(td)) < 0) return -1; } return !enable; } /* * Return a pointer to the entry in the list of disabled auto-conversions for a * type. */ static sipPyObject **autoconversion_disabled(const sipTypeDef *td) { PyObject *type = (PyObject *)sipTypeAsPyTypeObject(td); sipPyObject **pop; for (pop = &sipDisabledAutoconversions; *pop != NULL; pop = &(*pop)->next) if ((*pop)->object == type) return pop; return NULL; } /* * Enable or disable auto-conversion of a class that supports it. */ static PyObject *enableAutoconversion(PyObject *self, PyObject *args) { sipWrapperType *wt; int enable; (void)self; if (PyArg_ParseTuple(args, "O!i:enableautoconversion", &sipWrapperType_Type, &wt, &enable)) { sipTypeDef *td = wt->wt_td; int was_enabled; PyObject *res; if (!sipTypeIsClass(td) || ((sipClassTypeDef *)td)->ctd_cfrom == NULL) { PyErr_Format(PyExc_TypeError, "%s is not a wrapped class that supports optional auto-conversion", ((PyTypeObject *)wt)->tp_name); return NULL; } if ((was_enabled = sip_api_enable_autoconversion(td, enable)) < 0) return NULL; res = (was_enabled ? Py_True : Py_False); Py_INCREF(res); return res; } return NULL; } /* * Python copies the nb_inplace_add slot to the sq_inplace_concat slot and vice * versa if either are missing. This is a bug because they don't have the same * API. We therefore reverse this. */ static void fix_slots(PyTypeObject *py_type, sipPySlotDef *psd) { while (psd->psd_func != NULL) { if (psd->psd_type == iadd_slot && py_type->tp_as_sequence != NULL) py_type->tp_as_sequence->sq_inplace_concat = NULL; if (psd->psd_type == iconcat_slot && py_type->tp_as_number != NULL) py_type->tp_as_number->nb_inplace_add = NULL; ++psd; } } /* * Return the main instance for an object if it is a mixin. */ static sipSimpleWrapper *deref_mixin(sipSimpleWrapper *w) { return w->mixin_main != NULL ? (sipSimpleWrapper *)w->mixin_main : w; } /* * Convert a new C/C++ pointer to a Python instance. */ static PyObject *wrap_simple_instance(void *cpp, const sipTypeDef *td, sipWrapper *owner, int flags) { return sipWrapInstance(cpp, sipTypeAsPyTypeObject(td), empty_tuple, owner, flags); } /* * Resolve a proxy, if applicable. */ static void *resolve_proxy(const sipTypeDef *td, void *proxy) { sipProxyResolver *pr; /* TODO: Deprecate this mechanism in favour of an event handler. */ for (pr = proxyResolvers; pr != NULL; pr = pr->next) if (pr->td == td) proxy = pr->resolver(proxy); return proxy; } /* * Clear a simple wrapper. */ static void clear_wrapper(sipSimpleWrapper *sw) { if (PyObject_TypeCheck((PyObject *)sw, (PyTypeObject *)&sipWrapper_Type)) removeFromParent((sipWrapper *)sw); /* * Transfer ownership to C++ so we don't try to release it when the * Python object is garbage collected. */ sipResetPyOwned(sw); sipOMRemoveObject(&cppPyMap, sw); clear_access_func(sw); } /* * Set the handler to invoke when a new user Python sub-class is defined and * return the old handler. */ static sipNewUserTypeFunc sip_api_set_new_user_type_handler( const sipTypeDef *td, sipNewUserTypeFunc handler) { sipWrapperType *wt = (sipWrapperType *)sipTypeAsPyTypeObject(td); sipNewUserTypeFunc old_handler = wt->wt_new_user_type_handler;; wt->wt_new_user_type_handler = handler; return old_handler; } /* * Set the user-specific type data. */ static void sip_api_set_type_user_data(sipWrapperType *wt, void *data) { wt->wt_user_data = data; } /* * Get the user-specific type data. */ static void *sip_api_get_type_user_data(const sipWrapperType *wt) { return wt->wt_user_data; } /* * Get the dict of a Python type (on behalf of the limited API). */ static PyObject *sip_api_py_type_dict(const PyTypeObject *py_type) { return py_type->tp_dict; } /* * Get the name of a Python type (on behalf of the limited API). */ static const char *sip_api_py_type_name(const PyTypeObject *py_type) { return py_type->tp_name; } /* * Check an object is a method and return TRUE and its component parts if it * is. */ static int sip_api_get_method(PyObject *obj, sipMethodDef *method) { if (!PyMethod_Check(obj)) return FALSE; if (method != NULL) { method->pm_self = PyMethod_GET_SELF(obj); method->pm_function = PyMethod_GET_FUNCTION(obj); #if PY_MAJOR_VERSION < 3 method->pm_class = PyMethod_GET_CLASS(obj); #endif } return TRUE; } /* * Create a method from its component parts. */ static PyObject *sip_api_from_method(const sipMethodDef *method) { #if PY_MAJOR_VERSION < 3 return PyMethod_New(method->pm_function, method->pm_self, method->pm_class); #else return PyMethod_New(method->pm_function, method->pm_self); #endif } /* * Check an object is a C function and return TRUE and its component parts if * it is. */ static int sip_api_get_c_function(PyObject *obj, sipCFunctionDef *c_function) { if (!PyCFunction_Check(obj)) return FALSE; if (c_function != NULL) { c_function->cf_function = ((PyCFunctionObject *)obj)->m_ml; c_function->cf_self = PyCFunction_GET_SELF(obj); } return TRUE; } /* * Check an object is a date and return TRUE and its component parts if it is. */ static int sip_api_get_date(PyObject *obj, sipDateDef *date) { if (!PyDateTimeAPI) PyDateTime_IMPORT; if (!PyDate_Check(obj)) return FALSE; if (date != NULL) { date->pd_year = PyDateTime_GET_YEAR(obj); date->pd_month = PyDateTime_GET_MONTH(obj); date->pd_day = PyDateTime_GET_DAY(obj); } return TRUE; } /* * Create a date from its component parts. */ static PyObject *sip_api_from_date(const sipDateDef *date) { if (!PyDateTimeAPI) PyDateTime_IMPORT; return PyDate_FromDate(date->pd_year, date->pd_month, date->pd_day); } /* * Check an object is a datetime and return TRUE and its component parts if it * is. */ static int sip_api_get_datetime(PyObject *obj, sipDateDef *date, sipTimeDef *time) { if (!PyDateTimeAPI) PyDateTime_IMPORT; if (!PyDateTime_Check(obj)) return FALSE; if (date != NULL) { date->pd_year = PyDateTime_GET_YEAR(obj); date->pd_month = PyDateTime_GET_MONTH(obj); date->pd_day = PyDateTime_GET_DAY(obj); } if (time != NULL) { time->pt_hour = PyDateTime_DATE_GET_HOUR(obj); time->pt_minute = PyDateTime_DATE_GET_MINUTE(obj); time->pt_second = PyDateTime_DATE_GET_SECOND(obj); time->pt_microsecond = PyDateTime_DATE_GET_MICROSECOND(obj); } return TRUE; } /* * Create a datetime from its component parts. */ static PyObject *sip_api_from_datetime(const sipDateDef *date, const sipTimeDef *time) { if (!PyDateTimeAPI) PyDateTime_IMPORT; return PyDateTime_FromDateAndTime(date->pd_year, date->pd_month, date->pd_day, time->pt_hour, time->pt_minute, time->pt_second, time->pt_microsecond); } /* * Check an object is a time and return TRUE and its component parts if it is. */ static int sip_api_get_time(PyObject *obj, sipTimeDef *time) { if (!PyDateTimeAPI) PyDateTime_IMPORT; if (!PyTime_Check(obj)) return FALSE; if (time != NULL) { time->pt_hour = PyDateTime_TIME_GET_HOUR(obj); time->pt_minute = PyDateTime_TIME_GET_MINUTE(obj); time->pt_second = PyDateTime_TIME_GET_SECOND(obj); time->pt_microsecond = PyDateTime_TIME_GET_MICROSECOND(obj); } return TRUE; } /* * Create a time from its component parts. */ static PyObject *sip_api_from_time(const sipTimeDef *time) { if (!PyDateTimeAPI) PyDateTime_IMPORT; return PyTime_FromTime(time->pt_hour, time->pt_minute, time->pt_second, time->pt_microsecond); } /* * See if a type is user defined. */ static int sip_api_is_user_type(const sipWrapperType *wt) { return wt->wt_user_type; } /* * Return a frame from the execution stack. */ static struct _frame *sip_api_get_frame(int depth) { struct _frame *frame = PyEval_GetFrame(); while (frame != NULL && depth > 0) { frame = frame->f_back; --depth; } return frame; } /* * Check if a type was generated using the given plugin. Note that, although * this is part of the public API it is undocumented on purpose. */ static int sip_api_check_plugin_for_type(const sipTypeDef *td, const char *name) { /* * The current thinking on plugins is that SIP v5 will look for a plugin * with a name derived from the name as the current module in the same * directory as the .sip defining the module (ie. no %Plugin directive). A * module hierachy may have multiple plugins but they must co-operate. If * a plugin generates user data then it should include a void* (and a * run-time API) so that other plugins can extend it further. This * approach means that a plugin's user data structure can be opaque. */ sipExportedModuleDef *em = td->td_module; sipImportedModuleDef *im; if (strcmp(sipNameOfModule(em), name) == 0) return TRUE; if ((im = em->em_imports) == NULL) return FALSE; while (im->im_name != NULL) { if (strcmp(im->im_name, name) == 0) return TRUE; ++im; } return FALSE; } /* * Create a new Unicode object and return the character size and buffer. */ static PyObject *sip_api_unicode_new(SIP_SSIZE_T len, unsigned maxchar, int *kind, void **data) { #if PY_VERSION_HEX >= 0x03030000 PyObject *obj; if ((obj = PyUnicode_New(len, maxchar)) != NULL) { *kind = PyUnicode_KIND(obj); *data = PyUnicode_DATA(obj); } return obj; #else (void)len; (void)maxchar; (void)kind; (void)data; return NULL; #endif } /* * Update a new Unicode object with a new character. */ static void sip_api_unicode_write(int kind, void *data, int index, unsigned value) { #if PY_VERSION_HEX >= 0x03030000 PyUnicode_WRITE(kind, data, index, value); #else (void)kind; (void)data; (void)index; (void)value; #endif } /* * Get the address of the contents of a Unicode object, the character size and * the length. */ static void *sip_api_unicode_data(PyObject *obj, int *char_size, SIP_SSIZE_T *len) { #if PY_VERSION_HEX >= 0x03030000 void *data; /* Assume there will be an error. */ *char_size = -1; if (PyUnicode_READY(obj) < 0) return NULL; *len = PyUnicode_GET_LENGTH(obj); switch (PyUnicode_KIND(obj)) { case PyUnicode_1BYTE_KIND: *char_size = 1; data = PyUnicode_1BYTE_DATA(obj); break; case PyUnicode_2BYTE_KIND: *char_size = 2; data = PyUnicode_2BYTE_DATA(obj); break; case PyUnicode_4BYTE_KIND: *char_size = 4; data = PyUnicode_4BYTE_DATA(obj); break; default: data = NULL; } return data; #else (void)obj; (void)len; *char_size = -1; return NULL; #endif } /* * Get the buffer information supplied by an object that supports the buffer * protocol. */ static int sip_api_get_buffer_info(PyObject *obj, sipBufferInfoDef *bi) { #if PY_VERSION_HEX >= 0x02060300 int rc; Py_buffer *buffer; if (!PyObject_CheckBuffer(obj)) return 0; if (bi == NULL) return 1; if ((bi->bi_internal = sip_api_malloc(sizeof (Py_buffer))) == NULL) return -1; buffer = (Py_buffer *)bi->bi_internal; if (PyObject_GetBuffer(obj, buffer, PyBUF_FORMAT) < 0) return -1; if (buffer->ndim == 1) { bi->bi_buf = buffer->buf; bi->bi_obj = buffer->obj; bi->bi_len = buffer->len; bi->bi_format = buffer->format; rc = 1; } else { PyErr_SetString(PyExc_TypeError, "a 1-dimensional buffer is required"); PyBuffer_Release(buffer); rc = -1; } return rc; #else return -1; #endif } /* * Release the buffer information obtained from a previous call to * sipGetBufferInfo(). */ static void sip_api_release_buffer_info(sipBufferInfoDef *bi) { #if PY_VERSION_HEX >= 0x02060300 if (bi->bi_internal != NULL) { PyBuffer_Release((Py_buffer *)bi->bi_internal); sip_api_free(bi->bi_internal); bi->bi_internal = NULL; } #endif } /* * Import all the required types from an imported module. */ static int importTypes(sipExportedModuleDef *client, sipImportedModuleDef *im, sipExportedModuleDef *em) { const char *name; int i, e; /* * Look for each required type in turn. Both tables are sorted so a single * pass will find them all. */ for (i = e = 0; (name = im->im_imported_types[i].it_name) != NULL; ++i) { sipTypeDef *td = NULL; do { sipTypeDef *e_td; if (e >= em->em_nrtypes) { PyErr_Format(PyExc_RuntimeError, "%s cannot import type '%s' from %s", sipNameOfModule(client), name, sipNameOfModule(em)); return -1; } e_td = em->em_types[e++]; /* Ignore unresolved external types. */ if (e_td != NULL && strcmp(name, sipTypeName(e_td)) == 0) td = e_td; } while (td == NULL); im->im_imported_types[i].it_td = td; } return 0; } /* * Import all the required virtual error handlers from an imported module. */ static int importErrorHandlers(sipExportedModuleDef *client, sipImportedModuleDef *im, sipExportedModuleDef *em) { const char *name; int i; for (i = 0; (name = im->im_imported_veh[i].iveh_name) != NULL; ++i) { sipVirtErrorHandlerDef *veh = em->em_virterrorhandlers; sipVirtErrorHandlerFunc handler = NULL; if (veh != NULL) { while (veh->veh_name != NULL) { if (strcmp(veh->veh_name, name) == 0) { handler = veh->veh_handler; break; } ++veh; } } if (handler == NULL) { PyErr_Format(PyExc_RuntimeError, "%s cannot import virtual error handler '%s' from %s", sipNameOfModule(client), name, sipNameOfModule(em)); return -1; } im->im_imported_veh[i].iveh_handler = handler; } return 0; } /* * Import all the required exceptions from an imported module. */ static int importExceptions(sipExportedModuleDef *client, sipImportedModuleDef *im, sipExportedModuleDef *em) { const char *name; int i; for (i = 0; (name = im->im_imported_exceptions[i].iexc_name) != NULL; ++i) { PyObject **exc = em->em_exceptions; PyObject *exception = NULL; if (exc != NULL) { while (*exc != NULL) { if (strcmp(((PyTypeObject *)(*exc))->tp_name, name) == 0) { exception = *exc; break; } ++exc; } } if (exception == NULL) { PyErr_Format(PyExc_RuntimeError, "%s cannot import exception '%s' from %s", sipNameOfModule(client), name, sipNameOfModule(em)); return -1; } im->im_imported_exceptions[i].iexc_object = exception; } return 0; } /* * Enable or disable the garbage collector. Return the previous state or -1 if * there was an error. */ static int sip_api_enable_gc(int enable) { static PyObject *enable_func = NULL, *disable_func, *isenabled_func; PyObject *result; int was_enabled; /* * This may be -ve in the highly unusual event that a previous call failed. */ if (enable < 0) return -1; /* Get the functions if we haven't already got them. */ if (enable_func == NULL) { PyObject *gc_module; if ((gc_module = PyImport_ImportModule("gc")) == NULL) return -1; if ((enable_func = PyObject_GetAttrString(gc_module, "enable")) == NULL) { Py_DECREF(gc_module); return -1; } if ((disable_func = PyObject_GetAttrString(gc_module, "disable")) == NULL) { Py_DECREF(enable_func); Py_DECREF(gc_module); return -1; } if ((isenabled_func = PyObject_GetAttrString(gc_module, "isenabled")) == NULL) { Py_DECREF(disable_func); Py_DECREF(enable_func); Py_DECREF(gc_module); return -1; } Py_DECREF(gc_module); } /* Get the current state. */ if ((result = PyObject_Call(isenabled_func, empty_tuple, NULL)) == NULL) return -1; was_enabled = PyObject_IsTrue(result); Py_DECREF(result); if (was_enabled < 0) return -1; /* See if the state needs changing. */ if (!was_enabled != !enable) { /* Enable or disable as required. */ result = PyObject_Call((enable ? enable_func : disable_func), empty_tuple, NULL); Py_XDECREF(result); if (result != Py_None) return -1; } return was_enabled; } /* * A thin wrapper around PyObject_Print() usually used when debugging with the * limited API. */ static void sip_api_print_object(PyObject *o) { PyObject_Print(o, stdout, 0); } /* * Register a handler for a particular event. */ static int sip_api_register_event_handler(sipEventType type, const sipTypeDef *td, void *handler) { sipEventHandler *eh; assert(sipTypeIsClass(td)); if ((eh = sip_api_malloc(sizeof (sipEventHandler))) == NULL) return -1; eh->ctd = (const sipClassTypeDef *)td; eh->handler = handler; eh->next = event_handlers[(int)type]; event_handlers[(int)type] = eh; return 0; } /* * Returns TRUE if a generated class type is a sub-class of a base generated * class type. */ static int is_subtype(const sipClassTypeDef *ctd, const sipClassTypeDef *base_ctd) { const sipEncodedTypeDef *sup; /* Handle the trivial cases. */ if (ctd == base_ctd) return TRUE; if ((sup = ctd->ctd_supers) == NULL) return FALSE; /* Search the super-types. */ do { const sipClassTypeDef *sup_ctd = sipGetGeneratedClassType(sup, ctd); if (is_subtype(sup_ctd, base_ctd)) return TRUE; } while (!sup++->sc_flag); return FALSE; } /* * Return an attribute of an imported module. */ static PyObject *import_module_attr(const char *module, const char *attr) { PyObject *mod_obj, *attr_obj; if ((mod_obj = PyImport_ImportModule(module)) == NULL) return NULL; attr_obj = PyObject_GetAttrString(mod_obj, attr); Py_DECREF(mod_obj); return attr_obj; } /* * Get the container for a generated type. */ static const sipContainerDef *get_container(const sipTypeDef *td) { if (sipTypeIsMapped(td)) return &((const sipMappedTypeDef *)td)->mtd_container; return &((const sipClassTypeDef *)td)->ctd_container; } #if PY_VERSION_HEX >= 0x03030000 /* * Get the __qualname__ of an object based on its enclosing scope. */ static PyObject *get_qualname(const sipTypeDef *td, PyObject *name) { PyTypeObject *scope_type; /* Get the type that is the scope. */ scope_type = sipTypeAsPyTypeObject(td); return PyUnicode_FromFormat("%U.%U", ((PyHeapTypeObject *)scope_type)->ht_qualname, name); } #endif sip-4.19.7/siplib/siplib.sbf.in0000644000076500000240000000150713231604406016335 0ustar philstaff00000000000000# This is the build file for the extension module. # # Copyright (c) 2017 Riverbank Computing Limited # # 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 = @CFG_MODULE_BASENAME@ sources = siplib.c apiversions.c descriptors.c qtlib.c threads.c objmap.c voidptr.c array.c int_convertors.c bool.cpp headers = sip.h sipint.h array.h sip-4.19.7/siplib/threads.c0000644000076500000240000001125613231604406015552 0ustar philstaff00000000000000/* * 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) 2016 Riverbank Computing Limited * * 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 "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 /* * 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(int auto_alloc); #endif static pendingDef *get_pending(int auto_alloc); /* * Get the address etc. of any C/C++ object waiting to be wrapped. */ int sipGetPending(void **pp, sipWrapper **op, int *fp) { pendingDef *pd; if ((pd = get_pending(TRUE)) == NULL) return -1; *pp = pd->cpp; *op = pd->owner; *fp = pd->flags; /* Clear in case we execute Python code before finishing this wrapping. */ pd->cpp = NULL; return 0; } /* * Return TRUE if anything is pending. */ int sipIsPending() { pendingDef *pd; if ((pd = get_pending(FALSE)) == NULL) return FALSE; return (pd->cpp != NULL); } /* * Convert a new C/C++ pointer to a Python instance. */ PyObject *sipWrapInstance(void *cpp, PyTypeObject *py_type, PyObject *args, sipWrapper *owner, int flags) { pendingDef old_pending, *pd; PyObject *self; if (cpp == 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. */ if ((pd = get_pending(TRUE)) == NULL) return NULL; old_pending = *pd; pd->cpp = cpp; pd->owner = owner; pd->flags = flags; self = PyObject_Call((PyObject *)py_type, args, NULL); *pd = old_pending; return self; } /* * Handle the termination of a thread. */ void sip_api_end_thread(void) { #ifdef WITH_THREAD threadDef *thread; PyGILState_STATE gil = PyGILState_Ensure(); if ((thread = currentThreadDef(FALSE)) != NULL) thread->thr_ident = 0; PyGILState_Release(gil); #endif } /* * Return the pending data for the current thread, allocating it if necessary, * or NULL if there was an error. */ static pendingDef *get_pending(int auto_alloc) { #ifdef WITH_THREAD threadDef *thread; if ((thread = currentThreadDef(auto_alloc)) == NULL) return NULL; return &thread->pending; #else static pendingDef pending; return &pending; #endif } #ifdef WITH_THREAD /* * Return the thread data for the current thread, allocating it if necessary, * or NULL if there was an error. */ static threadDef *currentThreadDef(int auto_alloc) { threadDef *thread, *empty = NULL; long ident = PyThread_get_thread_ident(); /* See if we already know about the thread. */ for (thread = threads; thread != NULL; thread = thread->next) { if (thread->thr_ident == ident) return thread; if (thread->thr_ident == 0) empty = thread; } if (!auto_alloc) { /* This is not an error. */ return NULL; } if (empty != NULL) { /* Use an empty entry in the list. */ thread = empty; } else if ((thread = sip_api_malloc(sizeof (threadDef))) == NULL) { return NULL; } else { thread->next = threads; threads = thread; } thread->thr_ident = ident; thread->pending.cpp = NULL; return thread; } #endif sip-4.19.7/siplib/voidptr.c0000644000076500000240000006474413231604406015621 0ustar philstaff00000000000000/* * SIP library code. * * Copyright (c) 2016 Riverbank Computing Limited * * 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 #include #include #include "sipint.h" #include "array.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 int check_size(PyObject *self); static int check_rw(PyObject *self); static int check_index(PyObject *self, SIP_SSIZE_T idx); #if PY_VERSION_HEX < 0x02060300 static SIP_SSIZE_T get_value_data(PyObject *value, void **value_ptr); #endif #if PY_VERSION_HEX < 0x02050000 static void fix_bounds(int size, int *left, int *right); #endif #if PY_VERSION_HEX >= 0x02050000 static void bad_key(PyObject *key); #endif static int check_slice_size(SIP_SSIZE_T size, SIP_SSIZE_T value_size); static PyObject *make_voidptr(void *voidptr, SIP_SSIZE_T size, int rw); static int vp_convertor(PyObject *arg, struct vp_values *vp); static SIP_SSIZE_T get_size_from_arg(sipVoidPtrObject *v, SIP_SSIZE_T size); #if defined(SIP_USE_PYCAPSULE) /* * Implement ascapsule() for the type. */ static PyObject *sipVoidPtr_ascapsule(sipVoidPtrObject *v, PyObject *arg) { (void)arg; return PyCapsule_New(v->voidptr, NULL, NULL); } #endif #if defined(SIP_SUPPORT_PYCOBJECT) /* * Implement ascobject() for the type. */ static PyObject *sipVoidPtr_ascobject(sipVoidPtrObject *v, PyObject *arg) { (void)arg; return PyCObject_FromVoidPtr(v->voidptr, NULL); } #endif /* * Implement asarray() for the type. */ static PyObject *sipVoidPtr_asarray(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:asarray", #else "|i:asarray", #endif kwlist, &size)) return NULL; if ((size = get_size_from_arg(v, size)) < 0) return NULL; return sip_api_convert_to_array(v->voidptr, "B", size, (v->rw ? 0 : SIP_READ_ONLY)); } /* * 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; if ((size = get_size_from_arg(v, size)) < 0) return NULL; return SIPBytes_FromStringAndSize(v->voidptr, size); } /* * Implement getsize() for the type. */ static PyObject *sipVoidPtr_getsize(sipVoidPtrObject *v, PyObject *arg) { (void)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) { (void)arg; return PyBool_FromLong(v->rw); } /* * Implement setwriteable() for the type. */ static PyObject *sipVoidPtr_setwriteable(sipVoidPtrObject *v, PyObject *arg) { int rw; if ((rw = PyObject_IsTrue(arg)) < 0) return NULL; v->rw = rw; Py_INCREF(Py_None); return Py_None; } /* The methods data structure. */ static PyMethodDef sipVoidPtr_Methods[] = { {"asarray", (PyCFunction)sipVoidPtr_asarray, METH_VARARGS|METH_KEYWORDS, NULL}, #if defined(SIP_USE_PYCAPSULE) {"ascapsule", (PyCFunction)sipVoidPtr_ascapsule, METH_NOARGS, NULL}, #endif #if defined(SIP_SUPPORT_PYCOBJECT) {"ascobject", (PyCFunction)sipVoidPtr_ascobject, METH_NOARGS, NULL}, #endif {"asstring", (PyCFunction)sipVoidPtr_asstring, METH_VARARGS|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, NULL, 0, NULL} }; /* * Implement bool() for the type. */ static int sipVoidPtr_bool(PyObject *self) { return (((sipVoidPtrObject *)self)->voidptr != NULL); } /* * Implement int() for the type. */ static PyObject *sipVoidPtr_int(PyObject *self) { return PyLong_FromVoidPtr(((sipVoidPtrObject *)self)->voidptr); } #if PY_MAJOR_VERSION < 3 /* * Implement hex() for the type. */ static PyObject *sipVoidPtr_hex(PyObject *self) { char buf[2 + 16 + 1]; PyOS_snprintf(buf, sizeof (buf), "0x%.*lx", (int)(sizeof (void *) * 2), (unsigned long)((sipVoidPtrObject *)self)->voidptr); return PyString_FromString(buf); } #endif /* 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 */ sipVoidPtr_bool, /* 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 sipVoidPtr_int, /* nb_int */ 0, /* nb_reserved (Python v3), nb_long (Python v2) */ 0, /* nb_float */ #if PY_MAJOR_VERSION < 3 0, /* nb_oct */ 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 #if PY_VERSION_HEX >= 0x03050000 0, /* nb_matrix_multiply */ 0, /* nb_inplace_matrix_multiply */ #endif }; /* * Implement len() for the type. */ static SIP_SSIZE_T sipVoidPtr_length(PyObject *self) { if (check_size(self) < 0) return -1; return ((sipVoidPtrObject *)self)->size; } /* * Implement sequence item sub-script for the type. */ static PyObject *sipVoidPtr_item(PyObject *self, SIP_SSIZE_T idx) { if (check_size(self) < 0 || check_index(self, idx) < 0) return NULL; return SIPBytes_FromStringAndSize( (char *)((sipVoidPtrObject *)self)->voidptr + idx, 1); } #if PY_VERSION_HEX < 0x02050000 /* * Implement sequence slice sub-script for the type. */ static PyObject *sipVoidPtr_slice(PyObject *self, int left, int right) { sipVoidPtrObject *v; if (check_size(self) < 0) return NULL; v = (sipVoidPtrObject *)self; fix_bounds(v->size, &left, &right); if (left == right) left = right = 0; return make_voidptr((char *)(v->voidptr) + left, right - left, v->rw); } /* * Implement sequence assignment item sub-script for the type. */ static int sipVoidPtr_ass_item(PyObject *self, int idx, PyObject *value) { int value_size; void *value_ptr; if (check_rw(self) < 0 || check_size(self) < 0 || check_index(self, idx) < 0) return -1; if ((value_size = get_value_data(value, &value_ptr)) < 0) return -1; if (value_size != 1) { PyErr_SetString(PyExc_TypeError, "right operand must be a single byte"); return -1; } ((char *)((sipVoidPtrObject *)self)->voidptr)[idx] = *(char *)value_ptr; return 0; } /* * Implement sequence assignment slice sub-script for the type. */ static int sipVoidPtr_ass_slice(PyObject *self, int left, int right, PyObject *value) { sipVoidPtrObject *v; int value_size; void *value_ptr; if (check_rw(self) < 0 || check_size(self) < 0) return -1; if ((value_size = get_value_data(value, &value_ptr)) < 0) return -1; v = (sipVoidPtrObject *)self; fix_bounds(v->size, &left, &right); if (check_slice_size(right - left, value_size) < 0) return -1; memmove((char *)(v->voidptr) + left, value_ptr, right - left); return 0; } #endif /* The sequence methods data structure. */ static PySequenceMethods sipVoidPtr_SequenceMethods = { sipVoidPtr_length, /* sq_length */ 0, /* sq_concat */ 0, /* sq_repeat */ sipVoidPtr_item, /* sq_item */ #if PY_VERSION_HEX >= 0x02050000 0, /* sq_slice */ 0, /* sq_ass_item */ 0, /* sq_ass_slice */ #else sipVoidPtr_slice, /* sq_slice */ sipVoidPtr_ass_item, /* sq_ass_item */ sipVoidPtr_ass_slice, /* sq_ass_slice */ #endif 0, /* sq_contains */ 0, /* sq_inplace_concat */ 0, /* sq_inplace_repeat */ }; #if PY_VERSION_HEX >= 0x02050000 /* * Implement mapping sub-script for the type. */ static PyObject *sipVoidPtr_subscript(PyObject *self, PyObject *key) { sipVoidPtrObject *v; if (check_size(self) < 0) return NULL; v = (sipVoidPtrObject *)self; if (PyIndex_Check(key)) { Py_ssize_t idx = PyNumber_AsSsize_t(key, PyExc_IndexError); if (idx == -1 && PyErr_Occurred()) return NULL; if (idx < 0) idx += v->size; return sipVoidPtr_item(self, idx); } if (PySlice_Check(key)) { Py_ssize_t start, stop, step, slicelength; if (sipConvertFromSliceObject(key, v->size, &start, &stop, &step, &slicelength) < 0) return NULL; if (step != 1) { PyErr_SetNone(PyExc_NotImplementedError); return NULL; } return make_voidptr((char *)v->voidptr + start, slicelength, v->rw); } bad_key(key); return NULL; } /* * Implement mapping assignment sub-script for the type. */ static int sipVoidPtr_ass_subscript(PyObject *self, PyObject *key, PyObject *value) { sipVoidPtrObject *v; Py_ssize_t start, size; #if PY_VERSION_HEX >= 0x02060300 Py_buffer value_view; #else Py_ssize_t value_size; void *value_ptr; #endif if (check_rw(self) < 0 || check_size(self) < 0) return -1; v = (sipVoidPtrObject *)self; if (PyIndex_Check(key)) { start = PyNumber_AsSsize_t(key, PyExc_IndexError); if (start == -1 && PyErr_Occurred()) return -1; if (start < 0) start += v->size; if (check_index(self, start) < 0) return -1; size = 1; } else if (PySlice_Check(key)) { Py_ssize_t stop, step; if (sipConvertFromSliceObject(key, v->size, &start, &stop, &step, &size) < 0) return -1; if (step != 1) { PyErr_SetNone(PyExc_NotImplementedError); return -1; } } else { bad_key(key); return -1; } #if PY_VERSION_HEX >= 0x02060300 if (PyObject_GetBuffer(value, &value_view, PyBUF_CONTIG_RO) < 0) return -1; /* We could allow any item size... */ if (value_view.itemsize != 1) { PyErr_Format(PyExc_TypeError, "'%s' must have an item size of 1", Py_TYPE(value_view.obj)->tp_name); PyBuffer_Release(&value_view); return -1; } if (check_slice_size(size, value_view.len) < 0) { PyBuffer_Release(&value_view); return -1; } memmove((char *)v->voidptr + start, value_view.buf, size); PyBuffer_Release(&value_view); #else if ((value_size = get_value_data(value, &value_ptr)) < 0) return -1; if (check_slice_size(size, value_size) < 0) return -1; memmove((char *)v->voidptr + start, value_ptr, size); #endif return 0; } /* The mapping methods data structure. */ static PyMappingMethods sipVoidPtr_MappingMethods = { sipVoidPtr_length, /* mp_length */ sipVoidPtr_subscript, /* mp_subscript */ sipVoidPtr_ass_subscript, /* mp_ass_subscript */ }; #endif #if PY_VERSION_HEX >= 0x02060300 /* * The buffer implementation for Python v2.6.3 and later. */ static int sipVoidPtr_getbuffer(PyObject *self, Py_buffer *buf, int flags) { sipVoidPtrObject *v; if (check_size(self) < 0) return -1; 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_getreadbuffer(PyObject *self, SIP_SSIZE_T seg, void **ptr) { sipVoidPtrObject *v; if (seg != 0) { PyErr_SetString(PyExc_SystemError, "invalid buffer segment"); return -1; } if (check_size(self) < 0) return -1; v = (sipVoidPtrObject *)self; *ptr = v->voidptr; return v->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_getreadbuffer(self, seg, ptr); PyErr_SetString(PyExc_TypeError, "sip.voidptr object 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 /* The buffer methods data structure. */ static PyBufferProcs sipVoidPtr_BufferProcs = { #if PY_MAJOR_VERSION >= 3 sipVoidPtr_getbuffer, /* bf_getbuffer */ 0 /* bf_releasebuffer */ #else sipVoidPtr_getreadbuffer, /* bf_getreadbuffer */ sipVoidPtr_getwritebuffer, /* bf_getwritebuffer */ sipVoidPtr_getsegcount, /* bf_getsegcount */ #if PY_VERSION_HEX >= 0x02050000 (charbufferproc)sipVoidPtr_getreadbuffer, /* bf_getcharbuffer */ #if PY_VERSION_HEX >= 0x02060300 sipVoidPtr_getbuffer, /* bf_getbuffer */ 0 /* bf_releasebuffer */ #endif #else (getcharbufferproc)sipVoidPtr_getreadbuffer /* bf_getcharbuffer */ #endif #endif }; /* * 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; } /* 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 */ &sipVoidPtr_SequenceMethods, /* tp_as_sequence */ #if PY_VERSION_HEX >= 0x02050000 &sipVoidPtr_MappingMethods, /* tp_as_mapping */ #else 0, /* tp_as_mapping */ #endif 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ &sipVoidPtr_BufferProcs, /* tp_as_buffer */ #if defined(Py_TPFLAGS_HAVE_NEWBUFFER) Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */ #else Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ #endif 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 */ 0, /* tp_free */ 0, /* tp_is_gc */ 0, /* tp_bases */ 0, /* tp_mro */ 0, /* tp_cache */ 0, /* tp_subclasses */ 0, /* tp_weaklist */ 0, /* tp_del */ #if PY_VERSION_HEX >= 0x02060000 0, /* tp_version_tag */ #endif #if PY_VERSION_HEX >= 0x03040000 0, /* tp_finalize */ #endif }; /* * A convenience function to convert a C/C++ void pointer from a Python object. */ void *sip_api_convert_to_void_ptr(PyObject *obj) { struct vp_values vp; if (obj == NULL) { PyErr_SetString(PyExc_TypeError, "sip.voidptr is NULL"); return NULL; } if (vp_convertor(obj, &vp)) return vp.voidptr; return PyLong_AsVoidPtr(obj); } /* * 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); } /* * Check that a void pointer has an explicit size and raise an exception if it * hasn't. */ static int check_size(PyObject *self) { if (((sipVoidPtrObject *)self)->size >= 0) return 0; PyErr_SetString(PyExc_IndexError, "sip.voidptr object has an unknown size"); return -1; } /* * Check that a void pointer is writable. */ static int check_rw(PyObject *self) { if (((sipVoidPtrObject *)self)->rw) return 0; PyErr_SetString(PyExc_TypeError, "cannot modify a read-only sip.voidptr object"); return -1; } /* * Check that an index is valid for a void pointer. */ static int check_index(PyObject *self, SIP_SSIZE_T idx) { if (idx >= 0 && idx < ((sipVoidPtrObject *)self)->size) return 0; PyErr_SetString(PyExc_IndexError, "index out of bounds"); return -1; } #if PY_VERSION_HEX < 0x02060300 /* * Get the address and size of the data from a value that supports the buffer * interface. */ static SIP_SSIZE_T get_value_data(PyObject *value, void **value_ptr) { PyBufferProcs *bf = Py_TYPE(value)->tp_as_buffer; if (bf == NULL || bf->bf_getreadbuffer == NULL || bf->bf_getsegcount == NULL) { PyErr_Format(PyExc_TypeError, "'%s' does not support the buffer interface", Py_TYPE(value)->tp_name); return -1; } if ((*bf->bf_getsegcount)(value, NULL) != 1) { PyErr_SetString(PyExc_TypeError, "single-segment buffer object expected"); return -1; } return (*bf->bf_getreadbuffer)(value, 0, value_ptr); } #endif #if PY_VERSION_HEX < 0x02050000 /* * Fix the bounds of a slice in the same way that the Python buffer object * does. */ static void fix_bounds(int size, int *left, int *right) { if (*left < 0) *left = 0; else if (*left > size) *left = size; if (*right < *left) *right = *left; else if (*right > size) *right = size; } #endif #if PY_VERSION_HEX >= 0x02050000 /* * Raise an exception about a bad sub-script key. */ static void bad_key(PyObject *key) { PyErr_Format(PyExc_TypeError, "cannot index a sip.voidptr object using '%s'", Py_TYPE(key)->tp_name); } #endif /* * Check that the size of a value is the same as the size of the slice it is * replacing. */ static int check_slice_size(SIP_SSIZE_T size, SIP_SSIZE_T value_size) { if (value_size == size) return 0; PyErr_SetString(PyExc_ValueError, "cannot modify the size of a sip.voidptr object"); return -1; } /* * 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 #if defined(SIP_SUPPORT_PYCOBJECT) else if (PyCObject_Check(arg)) ptr = PyCObject_AsVoidPtr(arg); #endif else if (PyObject_TypeCheck(arg, &sipVoidPtr_Type)) { ptr = ((sipVoidPtrObject *)arg)->voidptr; size = ((sipVoidPtrObject *)arg)->size; rw = ((sipVoidPtrObject *)arg)->rw; } #if PY_VERSION_HEX >= 0x02060300 else if (PyObject_CheckBuffer(arg)) { Py_buffer view; if (PyObject_GetBuffer(arg, &view, PyBUF_SIMPLE) < 0) return 0; ptr = view.buf; size = view.len; rw = !view.readonly; PyBuffer_Release(&view); } #endif #if PY_VERSION_HEX < 0x03000000 else if (PyObject_AsReadBuffer(arg, (const void **)&ptr, &size) >= 0) { rw = (Py_TYPE(arg)->tp_as_buffer->bf_getwritebuffer != NULL); } #endif else { PyErr_Clear(); ptr = PyLong_AsVoidPtr(arg); if (PyErr_Occurred()) { #if defined(SIP_USE_PYCAPSULE) #if defined(SIP_SUPPORT_PYCOBJECT) PyErr_SetString(PyExc_TypeError, "a single integer, Capsule, CObject, None, bytes-like object or another sip.voidptr object is required"); #else PyErr_SetString(PyExc_TypeError, "a single integer, Capsule, None, bytes-like object or another sip.voidptr object is required"); #endif #else PyErr_SetString(PyExc_TypeError, "a single integer, CObject, None, bytes-like object or another sip.voidptr object is required"); #endif return 0; } } vp->voidptr = ptr; vp->size = size; vp->rw = rw; return 1; } /* * Get a size possibly supplied as an argument, otherwise get it from the * object. Raise an exception if there was no size specified. */ static SIP_SSIZE_T get_size_from_arg(sipVoidPtrObject *v, SIP_SSIZE_T size) { /* 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 object must have a size"); return size; } sip-4.19.7/siputils.py0000644000076500000240000026323013231604406014721 0ustar philstaff00000000000000# 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) 2015 Riverbank Computing Limited # # 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, deployment_target=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. deployment_target MacOS/X deployment target. 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 self._infix = "" # Make sure the destination directory is an absolute path. if dir: self.dir = os.path.abspath(dir) else: self.dir = os.getcwd() # 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 if deployment_target is None: self._deployment_target = configuration.deployment_target else: self._deployment_target = deployment_target 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 = [] self.extra_source_dirs = [] # 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) qt_version = self.config.qt_version else: win_shared = 1 win_exceptions = 0 win_rtti = 0 win_stl = 0 qt_version = 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: l_dir = os.path.dirname(l) # This is a hack to ignore PyQt's internal support libraries. if '/qpy/' in l_dir: continue # Ignore relative directories. This is really a hack to handle # SIP v3 inter-module linking. if l_dir in ("", ".", ".."): continue 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", "MSBUILD", "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", "MSBUILD", "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: # Get the name of the mkspecs directory. try: specd_base = self.config.qt_data_dir except AttributeError: specd_base = self.config.qt_dir mkspecs = os.path.join(specd_base, "mkspecs") if self.generator != "UNIX" and win_shared: defines.append("QT_DLL") if not self._debug: defines.append("QT_NO_DEBUG") if 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 == "QtDeclarative": defines.append("QT_DECLARATIVE_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") if qt_version >= 0x050000: if mod == "QtTest": defines.append("QT_GUI_LIB") if mod in ("QtSql", "QtTest"): defines.append("QT_WIDGETS_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 qt_version >= 0x040000: # Try and read QT_LIBINFIX from qconfig.pri. qconfig = os.path.join(mkspecs, "qconfig.pri") self._infix = self._extract_value(qconfig, "QT_LIBINFIX") # 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. qt5_depmap = { "QtDeclarative": ("QtXmlPatterns", "QtNetwork", "QtSql", "QtScript", "QtWidgets", "QtGui", "QtCore"), "QtGui": ("QtPrintSupport", "QtWidgets", "QtCore"), "QtHelp": ("QtNetwork", "QtSql", "QtWidgets", "QtGui", "QtCore"), "QtMultimedia": ("QtGui", "QtCore"), "QtNetwork": ("QtCore", ), "QtOpenGL": ("QtWidgets", "QtGui", "QtCore"), "QtScript": ("QtCore", ), "QtScriptTools": ("QtScript", "QtGui", "QtCore"), "QtSql": ("QtCore", ), "QtSvg": ("QtXml", "QtWidgets", "QtGui", "QtCore"), "QtTest": ("QtGui", "QtCore"), "QtWebKit": ("QtNetwork", "QtWebKitWidgets", "QtWidgets", "QtGui", "QtCore"), "QtXml": ("QtCore", ), "QtXmlPatterns": ("QtNetwork", "QtCore"), "QtDesigner": ("QtGui", "QtCore"), "QAxContainer": ("Qt5AxBase", "QtWidgets", "QtGui", "QtCore") } qt4_depmap = { "QtAssistant": ("QtNetwork", "QtGui", "QtCore"), "QtDeclarative": ("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") } if qt_version >= 0x050000: qt_depmap = qt5_depmap else: qt_depmap = qt4_depmap # 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 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._qt_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(qt_depmap.keys()): for qdep in qt_depmap[mod]: # Ignore the dependency if it is explicitly # linked. if qdep not in self._qt: libs.append(self.platform_lib(self._qt_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", "MSBUILD", "BMAKE") and win_shared: qt_lib = qt_lib + version_to_string(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. specd = os.path.join(mkspecs, "default") if not os.access(specd, os.F_OK): specd = os.path.join(mkspecs, self.config.platform) incdir.append(specd) qtincdir = self.optional_list("INCDIR_QT") if qtincdir: if qt_version >= 0x040000: for mod in self._qt: if mod == "QAxContainer": incdir.append(os.path.join(qtincdir[0], "ActiveQt")) elif self._is_framework(mod): idir = libdir_qt[0] if mod == "QtAssistant" and qt_version < 0x040202: mod = "QtAssistantClient" incdir.append(os.path.join(idir, mod + ".framework", "Headers")) if qt_version >= 0x050000: if mod == "QtGui": incdir.append(os.path.join(idir, "QtWidgets.framework", "Headers")) incdir.append(os.path.join(idir, "QtPrintSupport.framework", "Headers")) elif mod == "QtWebKit": incdir.append(os.path.join(idir, "QtWebKitWidgets.framework", "Headers")) else: idir = qtincdir[0] incdir.append(os.path.join(idir, mod)) if qt_version >= 0x050000: if mod == "QtGui": incdir.append(os.path.join(idir, "QtWidgets")) incdir.append(os.path.join(idir, "QtPrintSupport")) elif mod == "QtWebKit": incdir.append(os.path.join(idir, "QtWebKitWidgets")) # 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 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 _qt_module_to_lib(self, mname): """Return the name of the Qt library corresponding to a module. mname is the name of the module. """ qt_version = self.config.qt_version if mname == "QtAssistant": if qt_version >= 0x040202 and sys.platform == "darwin": lib = mname else: lib = "QtAssistantClient" else: lib = mname lib += self._infix if self._debug: if sys.platform == "win32": lib = lib + "d" elif sys.platform == "darwin": if not self._is_framework(mname): lib = lib + "_debug" elif qt_version < 0x040200: lib = lib + "_debug" qt5_rename = False if sys.platform == "win32" and "shared" in self.config.qt_winconfig.split(): if (mname in ("QtCore", "QtDeclarative", "QtDesigner", "QtGui", "QtHelp", "QtMultimedia", "QtNetwork", "QtOpenGL", "QtScript", "QtScriptTools", "QtSql", "QtSvg", "QtTest", "QtWebKit", "QtXml", "QtXmlPatterns", "phonon", "QAxContainer", "QtPrintSupport", "QtWebKitWidgets", "QtWidgets") or (qt_version >= 0x040200 and mname == "QtAssistant")): if mname == "QAxContainer": if qt_version >= 0x050000: lib = "Qt5" + lib[1:] elif qt_version >= 0x050000: qt5_rename = True else: lib = lib + "4" elif sys.platform.startswith("linux") and qt_version >= 0x050000: qt5_rename = True if qt5_rename: lib = "Qt5" + lib[2:] 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 == "": # This was renamed in Qt v4.7. prefix = self.optional_string("LFLAGS_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", "MSBUILD", "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. """ if self.generator in ("MSVC", "MSVC.NET", "MSBUILD", "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") libs = self._extract_value(prl_name, "QMAKE_PRL_LIBS").split() if self.config.qt_version >= 0x050000: xtra_libs = [] if clib in ("QtGui", "Qt5Gui"): xtra_libs.append("QtWidgets") xtra_libs.append("QtPrintSupport") elif clib in ("QtWebKit", "Qt5WebKit"): xtra_libs.append("QtWebKitWidgets") for xtra in xtra_libs: libs.extend( self.platform_lib( self._qt_module_to_lib(xtra), framework).split()) return libs def _extract_value(self, fname, vname): """Return the stripped value from a name=value line in a file. fname is the name of the file. vname is the name of the value. """ value = "" if os.access(fname, os.F_OK): try: f = open(fname, "r") except IOError: error("Unable to open \"%s\"" % fname) line = f.readline() while line: line = line.strip() if line and line[0] != "#": eq = line.find("=") if eq > 0 and line[:eq].strip() == vname: value = line[eq + 1:].strip() break line = f.readline() f.close() return value 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", "MSBUILD", "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. """ if self._deployment_target: mfile.write("export MACOSX_DEPLOYMENT_TARGET = %s\n" % self._deployment_target) 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", "MSBUILD"): 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"))) vpath = _UniqueList(self.extra_source_dirs) if self._src_dir != self.dir: vpath.append(self._src_dir) if vpath.as_list(): mfile.write("VPATH = %s\n\n" % " ".join(vpath.as_list())) # 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", "MSBUILD"): 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, deployment_target=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, deployment_target) 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": 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", "MSBUILD", "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 $<\n" % cpp) mfile.write("\n$(TARGET): $(OFILES)\n") if self.generator in ("MSVC", "MSVC.NET", "MSBUILD"): 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, deployment_target=None): """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, deployment_target) 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, deployment_target=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, deployment_target) 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")) # This is for Qt5. build.extend(self.optional_list("CXXFLAGS_APP")) # Borland requires all flags to precede all file names. if self.generator != "BMAKE": build.append(source) if self.generator in ("MSVC", "MSVC.NET", "MSBUILD"): 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", "MSBUILD"): 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 $<\n" % cpp) mfile.write("\n$(TARGET): $(OFILES)\n") if self.generator in ("MSVC", "MSVC.NET", "MSBUILD"): 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. """ # On Qt5 paths often includes forward slashes so convert them. if sys.platform == "win32": s = s.replace("/", "\\") if s.find(" ") >= 0: s = '"' + s + '"' return s def version_to_string(version, parts=3): """ Convert an n-part version number encoded as a hexadecimal value to a string. version is the version number. Returns the string. """ part_list = [str((version >> 16) & 0xff)] if parts > 1: part_list.append(str((version >> 8) & 0xff)) if parts > 2: part_list.append(str(version & 0xff)) return '.'.join(part_list) def version_from_string(version_str): """ Convert a version string of the form m.n or m.n.o to an encoded version number (or None if it was an invalid format). version_str is the version string. """ parts = version_str.split('.') if not isinstance(parts, list): return None if len(parts) == 2: parts.append('0') if len(parts) != 3: return None version = 0 for part in parts: try: v = int(part) except ValueError: return None version = (version << 8) + v return version 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() df.close() sf.close() 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 development preview 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 preview 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: self.currentfile.close() if 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 # Strip comments and surrounding whitespace. line = line.split('#', 1)[0].strip() if line: 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] = _expand_macro_value(raw, rhs, properties) 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.startswith(macro_prefix): 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] # 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 _expand_macro_value(macros, rhs, properties): """Expand the value of a macro based on ones seen so far.""" 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 == "]": # Assume a missing property expands to an empty string. if properties is None: value = "" else: value = properties.get(lhs, "") else: # We used to treat a missing value 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 = macros.get(lhs, "") rhs = rhs[:mstart] + value + rhs[mend:] estart = rhs.find("$$(") mstart = rhs.find("$$") return rhs 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 architectures to invoke python with. Several space separated architectures may be specified. 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. version = sys.version_info py_major = version[0] py_minor = version[1] if gui: # In Python v3.4 and later there is no pythonw. if (py_major == 3 and py_minor >= 4) or py_major >= 4: exe = "python" else: exe = "pythonw" else: exe = "python" exe = "%s%d.%d" % (exe, py_major, py_minor) if use_arch: # Note that this may not work with the "standard" interpreter but # should with the "pythonX.Y" version. arch_flags = ' '.join(["-%s" % a for a in use_arch.split()]) exe = "arch %s %s" % (arch_flags, 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 sip-4.19.7/specs/0000755000076500000240000000000013231604406013602 5ustar philstaff00000000000000sip-4.19.7/specs/aix-g++0000644000076500000240000000363213231604406014664 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/aix-g++-640000644000076500000240000000371313231604406015113 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/aix-xlc0000644000076500000240000000366313231604406015102 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/aix-xlc-640000644000076500000240000000406713231604406015330 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/bsdi-g++0000644000076500000240000000374113231604406015025 0ustar philstaff00000000000000# # $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 sip-4.19.7/specs/cygwin-g++0000644000076500000240000000414413231604406015402 0ustar philstaff00000000000000# # $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 sip-4.19.7/specs/darwin-g++0000644000076500000240000000442313231604406015366 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/dgux-g++0000644000076500000240000000342013231604406015045 0ustar philstaff00000000000000# # $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 sip-4.19.7/specs/freebsd-g++0000644000076500000240000000402513231604406015512 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/freebsd-g++340000644000076500000240000000410313231604406015656 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/freebsd-g++400000644000076500000240000000410313231604406015653 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/freebsd-icc0000644000076500000240000000656413231604406015706 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/hpux-acc0000644000076500000240000000576513231604406015252 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/hpux-acc-640000644000076500000240000000771413231604406015475 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/hpux-acc-o640000644000076500000240000000755013231604406015652 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/hpux-cc0000644000076500000240000000552613231604406015104 0ustar philstaff00000000000000# # $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 sip-4.19.7/specs/hpux-g++0000644000076500000240000000427713231604406015075 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/hpux-g++-640000644000076500000240000000434513231604406015320 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/hpuxi-acc0000644000076500000240000000766113231604406015420 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/hpuxi-acc-640000644000076500000240000000766113231604406015647 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/hurd-g++0000644000076500000240000000352313231604406015044 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/irix-cc0000644000076500000240000000707313231604406015072 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/irix-cc-640000644000076500000240000000706413231604406015321 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/irix-cc-o320000644000076500000240000000423613231604406015471 0ustar philstaff00000000000000# # $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 sip-4.19.7/specs/irix-g++0000644000076500000240000000406413231604406015056 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/irix-g++-640000644000076500000240000000411113231604406015276 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/linux-arm-g++0000644000076500000240000000452713231604406016023 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/linux-arm-thumb-g++0000644000076500000240000000456713231604406017144 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/linux-armv6-g++0000644000076500000240000000454413231604406016276 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/linux-cxx0000644000076500000240000000342513231604406015470 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/linux-ecc-640000644000076500000240000000377013231604406015652 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/linux-g++0000644000076500000240000000454513231604406015246 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/linux-g++-320000644000076500000240000000455713231604406015473 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/linux-g++-640000644000076500000240000000473113231604406015472 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/linux-icc0000644000076500000240000000466013231604406015426 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/linux-kcc0000644000076500000240000000474013231604406015427 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/linux-kylix0000644000076500000240000000377213231604406016033 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/linux-lsb0000644000076500000240000000456013231604406015447 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/linux-pgcc0000644000076500000240000000374713231604406015611 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/lynxos-g++0000644000076500000240000000404313231604406015434 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/macx-g++0000644000076500000240000000557313231604406015041 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/macx-mwerks0000644000076500000240000000136113231604406015764 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/macx-pbuilder0000644000076500000240000000451213231604406016263 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/macx-xlc0000644000076500000240000000517413231604406015250 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/netbsd-g++0000644000076500000240000000410113231604406015352 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/openbsd-g++0000644000076500000240000000405013231604406015530 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/qnx-g++0000644000076500000240000000376413231604406014717 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/reliant-cds0000644000076500000240000000404113231604406015731 0ustar philstaff00000000000000# # $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 sip-4.19.7/specs/reliant-cds-640000644000076500000240000000406513231604406016166 0ustar philstaff00000000000000# # $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 sip-4.19.7/specs/sco-cc0000644000076500000240000000353213231604406014677 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/sco-g++0000644000076500000240000000335613231604406014672 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/solaris-cc0000644000076500000240000000413513231604406015567 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/solaris-cc-640000644000076500000240000000610513231604406016015 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/solaris-g++0000644000076500000240000000453613231604406015563 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/solaris-g++-640000644000076500000240000000645613231604406016015 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/tru64-cxx0000644000076500000240000000360213231604406015312 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/tru64-g++0000644000076500000240000000356313231604406015072 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/unixware-cc0000644000076500000240000000376613231604406015766 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/unixware-g++0000644000076500000240000000360113231604406015741 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/win32-borland0000644000076500000240000000456713231604406016122 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/win32-g++0000644000076500000240000000606613231604406015051 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/win32-icc0000644000076500000240000000531513231604406015227 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/win32-msvc0000644000076500000240000000526613231604406015446 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/win32-msvc.net0000644000076500000240000000535713231604406016234 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/win32-msvc20050000644000076500000240000000574613231604406015760 0ustar philstaff00000000000000# # 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) sip-4.19.7/specs/win32-msvc20080000644000076500000240000000751413231604406015756 0ustar philstaff00000000000000# # qmake configuration for win32-msvc2008 # # Written for Microsoft Visual C++ 2008 # 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_RELEASE_WITH_DEBUGINFO += -O2 -MD -Zi QMAKE_CFLAGS_DEBUG = -Zi -MDd QMAKE_CFLAGS_YACC = QMAKE_CFLAGS_LTCG = -GL QMAKE_CFLAGS_MP = -MP 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_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC QMAKE_CXXFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG QMAKE_CXXFLAGS_MP = $$QMAKE_CFLAGS_MP 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 /DYNAMICBASE /NXCOMPAT QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO = /DEBUG /OPT:REF QMAKE_LFLAGS_DEBUG = /DEBUG QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS QMAKE_LFLAGS_EXE = \"/MANIFESTDEPENDENCY:type=\'win32\' name=\'Microsoft.Windows.Common-Controls\' version=\'6.0.0.0\' publicKeyToken=\'6595b64144ccf1df\' language=\'*\' processorArchitecture=\'*\'\" QMAKE_LFLAGS_DLL = /DLL QMAKE_LFLAGS_LTCG = /LTCG 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 = glu32.lib opengl32.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) sip-4.19.7/specs/win32-msvc20100000644000076500000240000000752013231604406015744 0ustar philstaff00000000000000# # qmake configuration for win32-msvc2010 # # Written for Microsoft Visual C++ 2010 # MAKEFILE_GENERATOR = MSBUILD 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 QMAKE_COMPILER_DEFINES += _MSC_VER=1600 _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_RELEASE_WITH_DEBUGINFO += -O2 -MD -Zi QMAKE_CFLAGS_DEBUG = -Zi -MDd QMAKE_CFLAGS_YACC = QMAKE_CFLAGS_LTCG = -GL QMAKE_CFLAGS_MP = -MP QMAKE_CXX = $$QMAKE_CC QMAKE_CXXFLAGS = $$QMAKE_CFLAGS QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON -w34100 -w34189 -w44996 QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC QMAKE_CXXFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG QMAKE_CXXFLAGS_MP = $$QMAKE_CFLAGS_MP 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 /DYNAMICBASE /NXCOMPAT QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO = /DEBUG /OPT:REF /INCREMENTAL:NO QMAKE_LFLAGS_DEBUG = /DEBUG QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS QMAKE_LFLAGS_EXE = \"/MANIFESTDEPENDENCY:type=\'win32\' name=\'Microsoft.Windows.Common-Controls\' version=\'6.0.0.0\' publicKeyToken=\'6595b64144ccf1df\' language=\'*\' processorArchitecture=\'*\'\" QMAKE_LFLAGS_DLL = /DLL QMAKE_LFLAGS_LTCG = /LTCG 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 = glu32.lib opengl32.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 = .vcxproj VCSOLUTION_EXTENSION = .sln VCPROJ_KEYWORD = Qt4VSv1.0 load(qt_config) sip-4.19.7/specs/win32-msvc20150000644000076500000240000001013013231604406015740 0ustar philstaff00000000000000# # qmake configuration for win32-msvc2015 # # Written for Microsoft Visual C++ 2015 # MAKEFILE_GENERATOR = MSBUILD 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 QMAKE_COMPILER_DEFINES += _MSC_VER=1900 _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_RELEASE_WITH_DEBUGINFO += -O2 -MD -Zi QMAKE_CFLAGS_DEBUG = -Zi -MDd QMAKE_CFLAGS_YACC = QMAKE_CFLAGS_LTCG = -GL QMAKE_CFLAGS_MP = -MP QMAKE_CXX = $$QMAKE_CC QMAKE_CXXFLAGS = $$QMAKE_CFLAGS QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON -w34100 -w34189 -w44996 QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC QMAKE_CXXFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG QMAKE_CXXFLAGS_MP = $$QMAKE_CFLAGS_MP 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 /DYNAMICBASE /NXCOMPAT QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO = /DEBUG /OPT:REF /INCREMENTAL:NO QMAKE_LFLAGS_DEBUG = /DEBUG QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS QMAKE_LFLAGS_EXE = \"/MANIFESTDEPENDENCY:type=\'win32\' name=\'Microsoft.Windows.Common-Controls\' version=\'6.0.0.0\' publicKeyToken=\'6595b64144ccf1df\' language=\'*\' processorArchitecture=\'*\'\" QMAKE_LFLAGS_DLL = /DLL QMAKE_LFLAGS_LTCG = /LTCG 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 = glu32.lib opengl32.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 = .vcxproj VCSOLUTION_EXTENSION = .sln VCPROJ_KEYWORD = Qt4VSv1.0 QMAKE_CFLAGS += -FS -Zc:strictStrings QMAKE_CFLAGS_WARN_ON += -w44456 -w44457 -w44458 QMAKE_CXXFLAGS += -FS -Zc:strictStrings QMAKE_CXXFLAGS_WARN_ON += -w44456 -w44457 -w44458 -wd4577 QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -D_HAS_EXCEPTIONS=0 load(qt_config) sip-4.19.7/specs/win32-watcom0000644000076500000240000000315313231604406015761 0ustar philstaff00000000000000# # $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 sip-4.19.7/sphinx/0000755000076500000240000000000013231604431013774 5ustar philstaff00000000000000sip-4.19.7/sphinx/annotations.rst0000644000076500000240000013655113231604406017100 0ustar philstaff00000000000000Annotations =========== In this section we describe each of the annotations that can be used in specification files. Annotations can either be :ref:`argument annotations `, :ref:`class annotations `, :ref:`mapped type annotations `, :ref:`enum annotations `, :ref:`exception annotations `, :ref:`function annotations `, :ref:`typedef annotations ` or :ref:`variable annotations ` 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. *integer* This type of annotation is an integer. In some cases the value is optional. *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/; .. _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_PYBUFFER`, :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); Any type hint for the argument will be ignored. .. argument-annotation:: DisallowNone .. versionadded:: 4.16.4 This boolean annotation specifies that the value of the corresponding argument (which should be a pointer to either a C++ class or a mapped type) must not be ``None``. .. argument-annotation:: DocType .. versionadded:: 4.10 .. deprecated:: 4.18 Use the :aanno:`TypeHint` annotation instead. 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 .. deprecated:: 4.18 Use the :aanno:`TypeHintValue` annotation instead. 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 optional integer 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. If the function is a method then the reference is kept by the instance, i.e. ``self``. Therefore the extra reference is released when the instance is garbage collected. If the function is a class method or an ordinary function and it is annotated using the :fanno:`Factory` annotation, then the reference is kept by the object created by the function. Therefore the extra reference is released when that object is garbage collected. Otherwise the reference is not kept by any specific object and will never be released. If a value is specified then it defines the argument's key. Arguments of different constructors or methods that have the same key are assumed to refer to the same value. .. 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:: PyInt .. versionadded:: 4.12 This boolean annotation is used with ``char``, ``signed char`` and ``unsigned char`` arguments to specify that they should be interpreted as integers rather than strings of one character. .. 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 :class:`sip.voidptr` object that wraps the address to support the Python buffer protocol. .. argument-annotation:: SingleShot .. deprecated:: 4.18 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. If the annotation is used with the :aanno:`Array` annotation then the array of pointers to the sequence of C structures or C++ class instances that is created on the heap is not automatically freed. 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. .. argument-annotation:: TypeHint .. versionadded:: 4.18 This string annotation specifies the type of the argument as it will appear in any generated docstrings and PEP 484 type hints. It is the equivalent of specifying :aanno:`TypeHintIn` and :aanno:`TypeHintOut` with the same value. It is usually used with arguments of type :stype:`SIP_PYOBJECT` to provide a more specific type. .. argument-annotation:: TypeHintIn .. versionadded:: 4.18 This string annotation specifies the type of the argument as it will appear in any generated docstrings and PEP 484 type hints when the argument is used to pass a value to a function (rather than being used to return a value from a function). It is usually used with arguments of type :stype:`SIP_PYOBJECT` to provide a more specific type. .. argument-annotation:: TypeHintOut .. versionadded:: 4.18 This string annotation specifies the type of the argument as it will appear in any generated docstrings and PEP 484 type hints when the argument is used to return a value from a function (rather than being used to pass a value to a function). It is usually used with arguments of type :stype:`SIP_PYOBJECT` to provide a more specific type. .. argument-annotation:: TypeHintValue .. versionadded:: 4.18 This string annotation specifies the default value of the argument as it will appear in any generated docstrings. .. _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. It should not be specified if all pure virtual methods have been specified. .. 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. Note that sub-classing from a class that has different implementations is not currently supported. 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 :c:func:`sipDelayedDtors()` is called with the list of delayed instances. :c:func:`sipDelayedDtors()` can then choose to call (or ignore) the destructors in any desired order. The :c:func:`sipDelayedDtors()` function must be specified using the :directive:`%ModuleCode` directive. .. c:function:: void sipDelayedDtors(const sipDelayedDtor *dd_list) :param dd_list: the linked list of delayed instances. .. c:type:: sipDelayedDtor This structure describes a particular delayed destructor. .. c:member:: const char* dd_name This is the name of the class excluding any package or module name. .. c:member:: 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 :c:member:`dd_isderived`. .. c:member:: int dd_isderived This is non-zero if the type of :c:member:`dd_ptr` is actually the generated derived class. This allows the correct destructor to be called. See :ref:`ref-derived-classes`. .. c:member:: 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:: FileExtension .. versionadded:: 4.16.6 This string annotation is used to specify the filename extension to be used for the file containing the generated code for this class. A separate file will be generated even if the :option:`-j ` command line option is specified. .. class-annotation:: ExportDerived .. versionadded:: 4.15 In many cases SIP generates a derived class for each class being wrapped (see :ref:`ref-derived-classes`). Normally this is used internally. This boolean annotation specifies that the declaration of the class is exported and able to be used by handwritten code. .. 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:: Mixin .. versionadded:: 4.15 This boolean annotation specifies that the class can be used as a mixin with other wrapped classes. Normally a Python application cannot define a new class that is derived from more than one wrapped class. In C++ this would create a new C++ class. This cannot be done from Python. At best a C++ instance of each of the wrapped classes can be created and wrapped as separate Python objects. However some C++ classes may function perfectly well with this restriction. Such classes are often intended to be used as mixins. If this annotation is specified then a separate instance of the class is created. The main instance automatically delegates to the instance of the mixin when required. A mixin class should have the following characteristics: - Any constructor arguments should be able to be specified using keyword arguments. - The class should not have any virtual methods. .. class-annotation:: NoDefaultCtors This boolean annotation is used to suppress the automatic generation of default constructors for the class. .. class-annotation:: NoTypeHint .. versionadded:: 4.18 This boolean annotation is used to suppress the generation of the PEP 484 type hint for the class and its contents. .. 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. .. seealso:: :directive:`%AutoPyName` .. 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. .. class-annotation:: TypeHint .. versionadded:: 4.18 This string annotation specifies the type of the class as it will appear in any generated docstrings and PEP 484 type hints. It is the equivalent of specifying :canno:`TypeHintIn` and :canno:`TypeHintOut` with the same value. .. class-annotation:: TypeHintIn .. versionadded:: 4.18 This string annotation specifies the type of the class as it will appear in any generated docstrings and PEP 484 type hints when an instance of the class is passed as an argument to a function (rather than being returned from a function). It is usually used with classes that implement :directive:`%ConvertToTypeCode` to allow additional types to be used whenever an instance of the class is expected. .. class-annotation:: TypeHintOut .. versionadded:: 4.18 This string annotation specifies the type of the class as it will appear in any generated docstrings and PEP 484 type hints when an instance of the class is returned from a function (rather than being used to pass a value to a function). .. class-annotation:: TypeHintValue .. versionadded:: 4.18 This string annotation specifies the default value of the class as it will appear in any generated docstrings. .. class-annotation:: VirtualErrorHandler .. versionadded:: 4.14 This name annotation specifies the handler (defined by the :directive:`%VirtualErrorHandler` directive) that is called when a Python re-implementation of any of the class's virtual C++ functions raises a Python exception. If not specified then the handler specified by the ``default_VirtualErrorHandler`` argument of the :directive:`%Module` directive is used. .. seealso:: :fanno:`NoVirtualErrorHandler`, :fanno:`VirtualErrorHandler`, :directive:`%VirtualErrorHandler` .. _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. It should not be used with mapped type templates. See :ref:`ref-incompat-apis` for more detail. .. mapped-type-annotation:: DocType .. versionadded:: 4.10 .. deprecated:: 4.18 Use the :manno:`TypeHint` annotation instead. This string annotation serves the same purpose as the :aanno:`DocType` argument annotation when applied to the mapped type being defined. .. mapped-type-annotation:: NoRelease This boolean annotation is used to specify that the mapped type does not support the :c:func:`sipReleaseType()` function. Any :directive:`%ConvertToTypeCode` should not create temporary instances of the mapped type, i.e. it should not return :c:macro:`SIP_TEMPORARY`. .. mapped-type-annotation:: PyName This name annotation specifies an alternative name for the mapped type being wrapped which is used when it is referred to from Python. The only time a Python type is created for a mapped type is when it is used as a scope for static methods or enums. It should not be used with mapped type templates. .. seealso:: :directive:`%AutoPyName` .. mapped-type-annotation:: TypeHint .. versionadded:: 4.18 This string annotation specifies the type of the mapped type as it will appear in any generated docstrings and PEP 484 type hints. It is the equivalent of specifying :manno:`TypeHintIn` and :manno:`TypeHintOut` with the same value. .. mapped-type-annotation:: TypeHintIn .. versionadded:: 4.18 This string annotation specifies the type of the mapped type as it will appear in any generated docstrings and PEP 484 type hints when it is passed to a function (rather than being returned from a function). .. mapped-type-annotation:: TypeHintOut .. versionadded:: 4.18 This string annotation specifies the type of the mapped type as it will appear in any generated docstrings and PEP 484 type hints when it is returned from a function (rather than being passed to a function). .. mapped-type-annotation:: TypeHintValue .. versionadded:: 4.18 This string annotation specifies the default value of the mapped type as it will appear in any generated docstrings. .. _ref-enum-annos: Enum Annotations ---------------- .. enum-annotation:: NoScope .. versionadded:: 4.15 This boolean annotation specifies the that scope of an enum's members should be omitted in the generated code. Normally this would mean that the generated code will not compile. However it is useful when defining pseudo-enums, for example, to wrap global values so that they are defined (in Python) within the scope of a class. .. enum-annotation:: NoTypeHint .. versionadded:: 4.18 This boolean annotation is used to suppress the generation of the PEP 484 type hint for the enum or enum member. .. 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. .. seealso:: :directive:`%AutoPyName` .. _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. .. seealso:: :directive:`%AutoPyName` .. _ref-function-annos: Function Annotations -------------------- .. function-annotation:: AbortOnException .. versionadded:: 4.16.4 This boolean annotation specifies that when a Python re-implementation of a virtual C++ function raises a Python exception then ``abort()`` is called after the error handler returns. .. function-annotation:: AllowNone .. versionadded:: 4.16.4 This boolean annotation is used to specify that the value returned by the function (which should be either :stype:`SIP_PYBUFFER`, :stype:`SIP_PYCALLABLE`, :stype:`SIP_PYDICT`, :stype:`SIP_PYLIST`, :stype:`SIP_PYSLICE`, :stype:`SIP_PYTUPLE` or :stype:`SIP_PYTYPE`) may be ``None``. .. 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. This annotation is ignored if the class defines :directive:`%InstanceCode`. .. 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:: DisallowNone .. versionadded:: 4.16.4 This boolean annotation is used to specify that the value returned by the function (which should be a pointer to either a C++ class or a mapped type) must not be ``None``. .. function-annotation:: DocType .. versionadded:: 4.10 .. deprecated:: 4.18 Use the :fanno:`TypeHint` annotation instead. This string annotation serves the same purpose as the :aanno:`DocType` argument annotation when applied to the type of the value returned by the function. .. function-annotation:: Encoding This string annotation serves the same purpose as the :aanno:`Encoding` argument annotation when applied to the type of the value returned by the function. .. 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:: __imatmul__ .. versionadded:: 4.17 This boolean annotation specifies that a ``__imatmul__()`` method should be automatically generated that will use the method being annotated to compute the value that the ``__imatmul__()`` method will return. .. function-annotation:: KeepReference .. versionadded:: 4.12.2 This optional integer annotation serves the same purpose as the :aanno:`KeepReference` argument annotation when applied to the type of the value returned by the function. If the function is a class method or an ordinary function then the reference is not kept by any other object and so the returned value will never be garbage collected. .. function-annotation:: KeywordArgs .. versionadded:: 4.10 This string annotation specifies the level of support the argument parser generated for this function will provide for passing the parameters using Python's keyword argument syntax. The value of the annotation can be either ``"None"`` meaning that keyword arguments are not supported, ``"All"`` meaning that all named arguments can be passed as keyword arguments, or ``"Optional"`` meaning that all named optional arguments (i.e. those with a default value) can be passed as keyword arguments. If the annotation is not used then the value specified by the ``keyword_arguments`` argument of the :directive:`%Module` directive is used. Keyword arguments cannot be used for functions that use an ellipsis to designate that the function has a variable number of arguments. .. deprecated:: 4.12 It can also be used as a boolean annotation which is the equivalent of specifiying a value of ``"All"``. .. 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:: __matmul__ .. versionadded:: 4.17 This boolean annotation specifies that a ``__matmul__()`` method should be automatically generated that will use the method being annotated to compute the value that the ``__matmul__()`` method will return. .. function-annotation:: NewThread This boolean annotation specifies that the function (which must be a virtual) will be executed in 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 .. deprecated:: 4.12 Use the :fanno:`KeywordArgs` annotation with a value of ``"None"``. 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 normal positional arguments. This annotation is useful when the default setting of allowing keyword arguments has been changed via the command line or the :directive:`%Module` directive, but you would still like certain functions to only support positional arguments. .. function-annotation:: NoRaisesPyException .. versionadded:: 4.13.1 This boolean annotation specifies that the function or constructor does not raise a Python exception to indicate that an error occurred. .. seealso:: :fanno:`RaisesPyException` .. function-annotation:: NoTypeHint .. versionadded:: 4.18 This boolean annotation is used to suppress the generation of the PEP 484 type hint for the function or constructor. .. function-annotation:: NoVirtualErrorHandler .. versionadded:: 4.14 This boolean annotation specifies that when a Python re-implementation of a virtual C++ function raises a Python exception then ``PyErr_Print()`` is always called. Any error handler specified by either the :fanno:`VirtualErrorHandler` function annotation, the :canno:`VirtualErrorHandler` class annotation or the ``default_VirtualErrorHandler`` argument of the :directive:`%Module` directive is ignored. .. seealso:: :fanno:`VirtualErrorHandler`, :canno:`VirtualErrorHandler`, :directive:`%VirtualErrorHandler` .. 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. Unless this or the :fanno:`Sequence` annotation is specified, 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. .. 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. .. seealso:: :directive:`%AutoPyName` .. function-annotation:: PyInt .. versionadded:: 4.12 This boolean annotation serves the same purpose as the :aanno:`PyInt` argument annotation when applied to the type of the value returned by the function. .. function-annotation:: RaisesPyException .. versionadded:: 4.12.1 This boolean annotation specifies that the function or constructor raises a Python exception to indicate that an error occurred. Any current exception is cleared before the function or constructor is called. It is ignored if the :directive:`%MethodCode` directive is used. .. seealso:: :fanno:`NoRaisesPyException` .. 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:: Sequence .. versionadded:: 4.14.7 This boolean annotation specifies that the operator should be interpreted as a sequence operator rather than a numeric operator. Python uses the ``+`` operator for adding numbers and concatanating sequences, and the ``*`` operator for multiplying numbers and repeating sequences. Unless this or the :fanno:`Numeric` annotation is specified, 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. .. 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. .. function-annotation:: TypeHint .. versionadded:: 4.18 This string annotation specifies the type of the value returned by the function as it will appear in any generated docstrings and PEP 484 type hints. It is usually used with results of type :stype:`SIP_PYOBJECT` to provide a more specific type. .. function-annotation:: VirtualErrorHandler .. versionadded:: 4.14 This name annotation specifies the handler (defined by the :directive:`%VirtualErrorHandler` directive) that is called when a Python re-implementation of the virtual C++ function raises a Python exception. If not specified then the handler specified by the class's :canno:`VirtualErrorHandler` is used. .. seealso:: :fanno:`NoVirtualErrorHandler`, :canno:`VirtualErrorHandler`, :directive:`%VirtualErrorHandler` .. _ref-typedef-annos: Typedef Annotations ------------------- .. typedef-annotation:: Capsule .. versionadded:: 4.14.1 This boolean annotation may only be used when the base type is ``void *`` and specifies that a Python capsule object is used to wrap the value rather than a :class:`sip.voidptr`. The advantage of using a capsule is that name based type checking is performed using the name of the type being defined. For versions of Python that do not support capules :class:`sip.voidptr` is used instead and name based type checking is not performed. .. typedef-annotation:: DocType .. versionadded:: 4.10 .. deprecated:: 4.18 Use the :tanno:`TypeHint` annotation instead. This string annotation serves the same purpose as the :aanno:`DocType` argument annotation when applied to the mapped type being defined. .. typedef-annotation:: Encoding This string annotation serves the same purpose as the :aanno:`Encoding` argument annotation when applied to the mapped type being defined. .. 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. .. typedef-annotation:: PyInt .. versionadded:: 4.12 This boolean annotation serves the same purpose as the :aanno:`PyInt` argument annotation when applied to the type being defined. .. typedef-annotation:: PyName .. versionadded:: 4.13.1 This name annotation only applies when the typedef is being used to create the wrapping for a class defined using a template and specifies an alternative name for the class 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. .. seealso:: :directive:`%AutoPyName` .. typedef-annotation:: TypeHint .. versionadded:: 4.18 This string annotation specifies the type as it will appear in any generated docstrings and PEP 484 type hints. It is the equivalent of specifying :tanno:`TypeHintIn` and :tanno:`TypeHintOut` with the same value. .. typedef-annotation:: TypeHintIn .. versionadded:: 4.18 This string annotation specifies the type as it will appear in any generated docstrings and PEP 484 type hints when it is passed to a function (rather than being returned from a function). It is usually used with arguments of type :stype:`SIP_PYOBJECT` to provide a more specific type. .. typedef-annotation:: TypeHintOut .. versionadded:: 4.18 This string annotation specifies the type as it will appear in any generated docstrings and PEP 484 type hints when it is returned from a function (rather than being passed to a function). It is usually used with arguments of type :stype:`SIP_PYOBJECT` to provide a more specific type. .. _ref-variable-annos: Variable Annotations -------------------- .. variable-annotation:: DocType .. versionadded:: 4.10 .. deprecated:: 4.18 Use the :vanno:`TypeHint` annotation instead. This string annotation serves the same purpose as the :aanno:`DocType` argument annotation when applied to the type of the variable being defined. .. variable-annotation:: Encoding This string annotation serves the same purpose as the :aanno:`Encoding` argument annotation when applied to the type of the variable being defined. .. variable-annotation:: NoSetter .. versionadded:: 4.16 This boolean annotation specifies that the variable will have no setter and will be read-only. Because SIP does not fully understand C/C++ types (particularly ``const`` arrays) it is sometimes necessary to explicitly annotate a variable as being read-only. .. variable-annotation:: NoTypeHint .. versionadded:: 4.18 This boolean annotation is used to suppress the generation of the PEP 484 type hint for the variable. .. variable-annotation:: PyInt .. versionadded:: 4.12 This boolean annotation serves the same purpose as the :aanno:`PyInt` argument annotation when applied to the type of the variable being defined. .. 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. .. seealso:: :directive:`%AutoPyName` .. variable-annotation:: TypeHint .. versionadded:: 4.18 This string annotation specifies the type of the variable as it will appear in any generated docstrings and PEP 484 type hints. It is usually used with arguments of type :stype:`SIP_PYOBJECT` to provide a more specific type. sip-4.19.7/sphinx/build_system.rst0000644000076500000240000007517213231604406017247 0ustar philstaff00000000000000.. _ref-build-system: The Build System ================ .. module:: sipconfig .. note:: This should not be used for new projects as it will not be supported by SIP v5. 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. PyQt4's ``configure.py``) or use it with other Python based build systems (e.g. `Distutils `_ and `SCons `_). An important feature of SIP is the ability to generate bindings that are built on top of existing bindings. For example, both `PyKDE `_ and `PyQwt `_ are built on top of PyQt4 but all three packages are maintained by different developers. To make this easier PyQt4 includes its own configuration module, ``pyqtconfig``, that contains additional classes intended to be used by the configuration scripts of bindings built on top of PyQt4. 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 architectures to invoke python with. Several space separated architectures may be specified. :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 development preview 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 versions it will contain either ``.dev`` or ``-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. .. attribute:: deployment_target The MacOS/X deployment target. .. 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:: extra_source_dirs A list of additional source directories passed to ``make``. .. 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[, deployment_target=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. :param deployment_target: the MacOS/X deployment target. 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 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[, deployment_target=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 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. :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__`. :param deployment_target: 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[,deployment_target=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 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__`. :param deployment_target: 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[, deployment_target=None]]]]]]]]]]]]]]]]) :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. :param deployment_target: see :meth:`sipconfig.Makefile.__init__`. .. method:: finalise() This is a reimplementation of :meth:`sipconfig.Makefile.finalise`. sip-4.19.7/sphinx/c_api.rst0000644000076500000240000027623113231604406015616 0ustar philstaff00000000000000.. _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. .. c:macro:: 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. .. c:macro:: 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. .. c:macro:: 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 :c:macro:`SIP_UNBLOCK_THREADS` at the same lexical scope. .. c:macro:: SIP_NO_CONVERTORS This is a flag used by various type convertors that suppresses the use of a type's :directive:`%ConvertToTypeCode`. .. c:macro:: 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``. .. c:macro:: SIP_OWNS_MEMORY .. versionadded:: 4.15.2 This is a flag used by various array constructors that species that the array owns the memory that holds the array's contents. .. c:macro:: SIP_PROTECTED_IS_PUBLIC .. versionadded:: 4.10 This is a C preprocessor symbol that is defined 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`). .. c:macro:: SIP_READ_ONLY .. versionadded:: 4.15.2 This is a flag used by various array constructors that species that the array is read-only. .. c:function:: SIP_RELEASE_GIL(sip_gilstate_t sipGILState) .. versionadded:: 4.14.4 This is called from the handwritten code specified with the :directive:`VirtualErrorHandler` in order to release the Python Global Interpreter Lock (GIL) prior to changing the execution path (e.g. by throwing a C++ exception). It should not be called under any other circumstances. :param sipGILState: an opaque value provided to the handwritten code by SIP. .. c:macro:: 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. .. c:macro:: SIP_SSIZE_T_FORMAT .. versionadded:: 4.15.4 This is a C preprocessor macro that is defined as ``%zd`` for Python v2.5 and later, and as ``%d`` for earlier versions of Python. It makes it easier to write PEP 353 compliant handwritten code. .. c:macro:: 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 :c:macro:`SIP_BLOCK_THREADS`. .. c:macro:: SIP_USE_PYCAPSULE .. versionadded:: 4.11 This is a C preprocessor symbol that is defined when ``PyCapsule`` objects are being used rather than the (now deprecated) ``PyCObject`` objects. .. c:macro:: SIP_VERSION This is a C preprocessor symbol that defines the SIP version number represented as a 3 part hexadecimal number (e.g. v5.0.0 is represented as ``0x050000``). .. c:macro:: SIP_VERSION_STR This is a C preprocessor symbol that defines the SIP version number represented as a string. For development versions it will contain either ``.dev`` or ``-snapshot-``. .. c:function:: 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``. .. c:function:: 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``. .. c:function:: 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. .. c:type:: sipBufferInfoDef .. versionadded:: 4.19 This C structure is used with :c:func:`sipGetBufferInfo()` and :c:func:`sipReleaseBufferInfo()` and encapsulates information provided by a Python object that implements the buffer protocol. The structure elements are as follows. .. c:member:: void \*bi_buf The address of the buffer. .. c:member:: PyObject \*bi_obj A reference to the object that implements the buffer protocol. .. c:member:: SIP_SSIZE_T bi_len The length of the buffer in bytes. .. c:member:: char \*bi_format The format of each element of the buffer. .. c:function:: 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 :c:func:`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 \*, :c:macro:`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* \*, :c:macro:`SIP_SSIZE_T`, const :c:type:`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* \*, :c:type:`sipWrapperType` \*, PyObject \*] .. deprecated:: 4.8 Use ``N`` instead. 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. ``C`` (wrapped instance) [*type* \*, :c:type:`sipWrapperType` \*, PyObject \*] .. deprecated:: 4.8 Use ``D`` instead. 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 :c:func:`sipTransferBack()`. Otherwise ownership is transferred to C/C++ and the instance associated with the ``PyObject *`` argument via a call to :c:func:`sipTransferTo()`. The Python class is influenced by any applicable :directive:`%ConvertToSubClassCode` code. ``D`` (wrapped instance) [*type* \*, const :c:type:`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 :c:func:`sipTransferBack()`. Otherwise ownership is transferred to C/C++ and the instance associated with the ``PyObject *`` argument via a call to :c:func:`sipTransferTo()`. The Python class is influenced by any applicable :directive:`%ConvertToSubClassCode` code. ``E`` (wrapped enum) [enum, PyTypeObject \*] .. deprecated:: 4.8 Use ``F`` instead. Convert a named C/C++ ``enum`` to an instance of the corresponding Python named enum type. ``F`` (wrapped enum) [enum, :c:type:`sipTypeDef` \*] Convert a named C/C++ ``enum`` to an instance of the corresponding Python named enum type. ``G`` (unicode) [wchar_t \*, :c:macro:`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``. ``L`` (integer) [char] .. versionadded:: 4.12 Convert a C/C++ ``char`` to a Python integer. ``M`` (long) [unsigned char] .. versionadded:: 4.12 Convert a C/C++ ``unsigned char`` to a Python long. ``N`` (wrapped instance) [*type* \*, :c:type:`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 *`` to a Python :class:`sip.voidptr` object. ``z`` (object) [const char \*, void \*] .. versionadded:: 4.14.1 Convert a C/C++ ``void *`` to a Python named capsule object. .. c:function:: 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 :c:func:`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 :c:func:`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``. .. c:function:: int sipCanConvertToEnum(PyObject *obj, const sipTypeDef *td) .. deprecated:: 4.19.4 Use :c:func:`sipConvertToEnum()` instead. 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 `. :return: a non-zero value if the object can be converted. .. c:function:: int sipCanConvertToInstance(PyObject *obj, sipWrapperType *type, int flags) .. deprecated:: 4.8 Use :c:func:`sipCanConvertToType()` instead. 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 `. :param flags: any combination of the :c:macro:`SIP_NOT_NONE` and :c:macro:`SIP_NO_CONVERTORS` flags. :return: a non-zero value if the object can be converted. .. c:function:: int sipCanConvertToMappedType(PyObject *obj, const sipMappedType *mt, int flags) .. deprecated:: 4.8 Use :c:func:`sipCanConvertToType()` instead. 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 :c:func:`sipFindMappedType()`. :param flags: this may be the :c:macro:`SIP_NOT_NONE` flag. :return: a non-zero value if the object can be converted. .. c:function:: 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 `. :param flags: any combination of the :c:macro:`SIP_NOT_NONE` and :c:macro:`SIP_NO_CONVERTORS` flags. :return: a non-zero value if the object can be converted. .. c:type:: sipCFunctionDef .. versionadded:: 4.19 This C structure is used with :c:func:`sipGetCFunction()` and encapsulates the components parts of a Python C function. The structure elements are as follows. .. c:member:: PyMethodDef \*cf_function The C function. .. c:member:: PyObject \*cf_self The optional bound object. .. c:function:: PyObject *sipClassName(PyObject *obj) .. deprecated:: 4.8 Use the following instead: PyString_FromString(obj->ob_type->tp_name) 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. .. c:function:: 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. .. c:function:: 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. .. c:function:: PyObject *sipConvertFromEnum(int eval, const sipTypeDef *td) This converts a named C/C++ ``enum`` to a Python object. If the enum is a C++11 scoped enum then the Python object is created using the :py:mod:`enum` module. Otherwise a SIP generated type is used that can itself be converted to an ``int``. :param eval: the enumerated value to convert. :param td: the enum's :ref:`generated type structure `. :return: the Python object. .. c:function:: PyObject *sipConvertFromInstance(void *cpp, sipWrapperType *type, PyObject *transferObj) .. deprecated:: 4.8 Use :c:func:`sipConvertFromType()` instead. 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 `. :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 :c:func:`sipTransferBack()`. Otherwise ownership is transferred to C/C++ and the instance associated with *transferObj* via a call to :c:func:`sipTransferTo()`. The Python type is influenced by any applicable :directive:`%ConvertToSubClassCode` code. .. c:function:: PyObject *sipConvertFromMappedType(void *cpp, const sipMappedType *mt, PyObject *transferObj) .. deprecated:: 4.8 Use :c:func:`sipConvertFromType()` instead. 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 :c:func:`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 :c:func:`sipTransferBack()`. Otherwise ownership is transferred to C/C++ and the instance associated with *transferObj* argument via a call to :c:func:`sipTransferTo()`. .. c:function:: PyObject *sipConvertFromNamedEnum(int eval, PyTypeObject *type) .. deprecated:: 4.8 Use :c:func:`sipConvertFromEnum()` instead. 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 `. :return: the Python object. .. c:function:: PyObject *sipConvertFromNewInstance(void *cpp, sipWrapperType *type, PyObject *transferObj) .. deprecated:: 4.8 Use :c:func:`sipConvertFromNewType()` instead. 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 `. :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. .. c:function:: PyObject *sipConvertFromNewPyType(void *cpp, PyTypeObject *py_type, sipWrapper *owner, sipSimpleWrapper **selfp, const char *format, ...) .. versionadded:: 4.15 This converts a new C structure or a C++ class instance to an instance of a corresponding Python type (as opposed to the corresponding generated Python type). This is useful when the C/C++ library provides some sort of mechanism whereby handwritten code has some control over the exact type of structure or class being created. Typically it would be used to create an instance of the generated derived class which would then allow Python re-implementations of C++ virtual methods to function properly. :param cpp: the C/C++ instance. :param py_type: the Python type object. This is called to create the Python object and is passed the arguments defined by the string of format characters. :param owner: is the optional owner of the Python object. :param selfp: is an optional pointer to the ``sipPySelf`` instance variable of the C/C++ instance if that instance's type is a generated derived class. Otherwise it should be ``NULL``. :param format: the string of format characters (see :c:func:`sipBuildResult()`). :return: the Python object. If there was an error then ``NULL`` is returned and a Python exception is raised. .. c:function:: 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 `. :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. .. c:function:: 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. .. c:function:: 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 :c:func:`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. .. c:function:: 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 `. :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 :c:func:`sipTransferBack()`. Otherwise ownership is transferred to C/C++ and the instance associated with *transferObj* via a call to :c:func:`sipTransferTo()`. The Python class is influenced by any applicable :directive:`%ConvertToSubClassCode` code. .. c:function:: 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. .. c:function:: 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. .. c:function:: PyObject *sipConvertToArray(void *data, const char *format, SIP_SSIZE_T len, int flags) .. versionadded:: 4.15 This converts a one dimensional array of fundamental types to a :class:`sip.array` object. An array is very like a Python :class:`memoryview` object. The underlying memory is not copied and may be modified in situ. Arrays support the buffer protocol and so can be passed to other modules, again without the underlying memory being copied. :class:`sip.array` objects are not supported by the :program:`sip` code generator. They can only be created by handwritten code or by :func:`sip.voidptr.asarray`. :param data: the address of the start of the C/C++ array. :param format: the format, as defined by the :mod:`struct` module, of an array element. At the moment only ``b`` (char), ``B`` (unsigned char), ``h`` (short), ``H`` (unsigned short), ``i`` (int), ``I`` (unsigned int), ``f`` (float) and ``d`` (double) are supported. :param len: the number of elements in the array. :param readonly: is non-zero if the array is read-only. :param flags: any combination of the :c:macro:`SIP_READ_ONLY` and :c:macro:`SIP_OWNS_MEMORY` flags. :return: the :class:`sip.array` object. .. c:function:: int sipConvertToBool(PyObject *obj) .. versionadded:: 4.19.4 This converts a Python object to an integer corresponding to a C++ ``bool``. :param obj: the Python object to convert. :return: the boolean value as an integer. ``1`` corresponds to ``true`` and ``0`` corresponds to ``false``. ``-1`` is returned, and an exception is raised, if there was an error. .. c:function:: int sipConvertToEnum(PyObject *obj, const sipTypeDef *td) .. versionadded:: 4.19.4 This converts a Python object to the value of a named C/C++ ``enum`` member. If the enum is a C++11 scoped enum then the Python object must be a member of the enum. Otherwise it may also be an ``int`` corresponding to the name of the member. :param obj: the Python object to convert. :param td: the enum's :ref:`generated type structure `. :return: the integer value. An exception is raised if there was an error. .. c:function:: void *sipConvertToInstance(PyObject *obj, sipWrapperType *type, PyObject *transferObj, int flags, int *state, int *iserr) .. deprecated:: 4.8 Use :c:func:`sipConvertToType()` instead. This converts a Python object to an instance of a C structure or C++ class assuming that a previous call to :c:func:`sipCanConvertToInstance()` has been successful. :param obj: the Python object. :param type: the type's :ref:`generated type object `. :param transferObj: this controls any ownership changes to *obj*. :param flags: any combination of the :c:macro:`SIP_NOT_NONE` and :c:macro:`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 :c:func:`sipTransferBack()`. Otherwise ownership is transferred to C/C++ and *obj* associated with *transferObj* via a call to :c:func:`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 :c:func:`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.) .. c:function:: void *sipConvertToMappedType(PyObject *obj, const sipMappedType *mt, PyObject *transferObj, int flags, int *state, int *iserr) .. deprecated:: 4.8 Use :c:func:`sipConvertToType()` instead. 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 :c:func:`sipCanConvertToMappedType()` has been successful. :param obj: the Python object. :param mt: the opaque structure returned by :c:func:`sipFindMappedType()`. :param transferObj: this controls any ownership changes to *obj*. :param flags: this may be the :c:macro:`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 :c:func:`sipTransferBack()`. Otherwise ownership is transferred to C/C++ and *obj* associated with *transferObj* via a call to :c:func:`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 :c:func:`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.) .. c:function:: 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 :c:func:`sipCanConvertToType()` has been successful. :param obj: the Python object. :param td: the type's :ref:`generated type structure `. :param transferObj: this controls any ownership changes to *obj*. :param flags: any combination of the :c:macro:`SIP_NOT_NONE` and :c:macro:`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 :c:func:`sipTransferBack()`. Otherwise ownership is transferred to C/C++ and *obj* associated with *transferObj* via a call to :c:func:`sipTransferTo()`. Note that *obj* can also be managed by the C/C++ instance itself, but this can only be achieved by using :c:func:`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 :c:func:`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.) .. c:function:: PyObject *sipConvertToTypedArray(void *data, const sipTypeDef *td, const char *format, size_t stride, SIP_SSIZE_T len, int flags) .. versionadded:: 4.15 This converts a one dimensional array of instances of a C structure, C++ class or mapped type to a :class:`sip.array` object. An array is very like a Python :class:`memoryview` object but it's elements correspond to C structures or C++ classes. The underlying memory is not copied and may be modified in situ. Arrays support the buffer protocol and so can be passed to other modules, again without the underlying memory being copied. :class:`sip.array` objects are not supported by the :program:`sip` code generator. They can only be created by handwritten code. :param data: the address of the start of the C/C++ array. :param td: an element's type's :ref:`generated type structure `. :param format: the format, as defined by the :mod:`struct` module, of an array element. :param stride: the size of an array element, including any padding. :param len: the number of elements in the array. :param flags: the optional :c:macro:`SIP_READ_ONLY` flag. :return: the :class:`sip.array` object. .. c:function:: void *sipConvertToVoidPtr(PyObject *obj) This converts a Python object to a memory address. :c:func:`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 :c:type:`PyCObject`. :return: the memory address. .. c:type:: sipDateDef .. versionadded:: 4.19 This C structure is used with :c:func:`sipGetDate()`, :c:func:`sipFromDate(), :c:func:`sipGetDateTime()` and :c:func:`sipFromDateTime()` and encapsulates the components parts of a Python date. The structure elements are as follows. .. c:member:: int pd_year The year. .. c:member:: int pd_month The month (1-12). .. c:member:: int pd_day The day (1-31). .. c:function:: int sipEnableAutoconversion(const sipTypeDef *td, int enable) .. versionadded:: 4.14.7 Instances of some classes may be automatically converted to other Python objects even though the class has been wrapped. This allows that behaviour to be suppressed so that an instances of the wrapped class is returned instead. :param td: the type's :ref:`generated type structure `. This must refer to a class. :param enable: is non-zero if auto-conversion should be enabled for the type. This is the default behaviour. :return: ``1`` or ``0`` depending on whether or not auto-conversion was previously enabled for the type. This allows the previous state to be restored later on. ``-1`` is returned, and a Python exception raised, if there was an error. .. c:function:: int sipEnableGC(int enable) .. versionadded:: 4.19.1 This enables or disables the Python garbarge collector. :param enable: is greater than ``0`` if the garbage collector should be enabled. :return: ``1`` or ``0`` depending on whether or not the garbage collector was previously enabled. This allows the previous state to be restored later on. ``-1`` is returned if there was an error. .. c:function:: int sipEnableOverflowChecking(int enable) .. versionadded:: 4.19.4 This enables or disables the checking for overflows when converting Python integer objects to C/C++ integer types. When it is enabled an exception is raised when the value of a Python integer object is too large to fit in the corresponding C/C++ type. By default it is disabled. :param enable: is greater than ``0`` if overflow checking should be enabled. :return: ``1`` or ``0`` depending on whether or not overflow chacking was previously enabled. This allows the previous state to be restored later on. .. c:function:: 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 :c:func:`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. .. c:function:: sipWrapperType *sipFindClass(const char *type) .. deprecated:: 4.8 Use :c:func:`sipFindType()` instead. This returns a pointer to the :ref:`generated type object ` 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. .. c:function:: const sipMappedType *sipFindMappedType(const char *type) .. deprecated:: 4.8 Use :c:func:`sipFindType()` instead. 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. .. c:function:: PyTypeObject *sipFindNamedEnum(const char *type) .. deprecated:: 4.8 Use :c:func:`sipFindType()` instead. This returns a pointer to the :ref:`generated Python type object ` corresponding to a named unscoped 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++ unscoped enum doesn't exist. .. c:function:: const sipTypeDef *sipFindType(const char *type) This returns a pointer to the :ref:`generated type structure ` 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. .. c:function:: void *sipForceConvertToInstance(PyObject *obj, sipWrapperType *type, PyObject *transferObj, int flags, int *state, int *iserr) .. deprecated:: 4.8 Use :c:func:`sipForceConvertToType()` instead. This converts a Python object to an instance of a C structure or C++ class by calling :c:func:`sipCanConvertToInstance()` and, if it is successfull, calling :c:func:`sipConvertToInstance()`. See :c:func:`sipConvertToInstance()` for a full description of the arguments. .. c:function:: void *sipForceConvertToMappedType(PyObject *obj, const sipMappedType *mt, PyObject *transferObj, int flags, int *state, int *iserr) .. deprecated:: 4.8 Use :c:func:`sipForceConvertToType()` instead. 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 :c:func:`sipCanConvertToMappedType()` and, if it is successfull, calling :c:func:`sipConvertToMappedType()`. See :c:func:`sipConvertToMappedType()` for a full description of the arguments. .. c:function:: 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 :c:func:`sipCanConvertToType()` and, if it is successfull, calling :c:func:`sipConvertToType()`. See :c:func:`sipConvertToType()` for a full description of the arguments. .. c:function:: void sipFree(void *mem) This returns an area of memory allocated by :c:func:`sipMalloc()` to the heap. :param mem: the memory address. .. c:function:: PyObject *sipFromDate(const sipDateDef *date) .. versionadded:: 4.19 This creates a Python date object from its component parts. :param date: the component parts of the date. :return: the Python date object. .. c:function:: PyObject *sipFromDateTime(const sipDateDef *date, const sipTimeDef *time) .. versionadded:: 4.19 This creates a Python datetime object from its component parts. :param date: the date related component parts of the datetime. :param time: the time related component parts of the datetime. :return: the Python datetime object. .. c:function:: PyObject *sipFromMethod(const sipMethodDef *method) .. versionadded:: 4.19 This creates a Python method object from its component parts. :param method: the component parts of the method. :return: the Python method object. .. c:function:: PyObject *sipFromTime(const sipTimeDef *time) .. versionadded:: 4.19 This creates a Python time object from its component parts. :param time: the component parts of the time. :return: the Python time object. .. c:function:: void *sipGetAddress(sipSimpleWrapper *obj) .. versionadded:: 4.12 This returns the address of the C structure or C++ class instance wrapped by a Python object. :param obj: the Python object. :return: the address of the C/C++ instance .. c:function:: int sipGetBufferInfo(PyObject *obj, sipBufferInfoDef *buffer_info) .. versionadded:: 4.19 This checks to see if an object implements the Python buffer protocol and, if so, optionally returns the buffer information. It is similar to :c:func:`PyObject_GetBuffer` and should be used instead of that when the limited Python API is enabled. Note that, at the moment, only 1-dimensional buffers are supported. :param obj: the Python object. :param buffer_info: if this is not ``NULL``, and the object implements the buffer protocol, then the buffer information is returned in this structure. There should be a corresponding call to :c:func:`sipReleaseBuffer`. :return: > 0 if the object supports the buffer protocol and the buffer information was returned (if requested). 0 if the object does not support the buffer protocol. < 0 (and a Python exception is raised) if the object supports the buffer protocol but there was an error returning the requested buffer information. .. c:function:: int sipGetCFunction(PyObject *obj, sipCFunctionDef *c_function) .. versionadded:: 4.19 This checks to see if an object is a Python C function object and, if so, optionally returns its component parts. :param obj: the Python object. :param c_function: if this is not ``NULL``, and the object is a C function object, then the component parts are returned in this structure. :return: a non-zero value if the object is a Python C function object. .. c:function:: int sipGetDate(PyObject *obj, sipDateDef *date) .. versionadded:: 4.19 This checks to see if an object is a Python date object and, if so, optionally returns its component parts. :param obj: the Python object. :param date: if this is not ``NULL``, and the object is a date object, then the component parts are returned in this structure. :return: a non-zero value if the object is a Python date object. .. c:function:: int sipGetDateTime(PyObject *obj, sipDateDef *date, sipTimeDef *time) .. versionadded:: 4.19 This checks to see if an object is a Python datetime object and, if so, optionally returns its component parts. :param obj: the Python object. :param date: if this is not ``NULL``, and the object is a datetime object, then the date related component parts are returned in this structure. :param time: if this is not ``NULL``, and the object is a datetime object, then the time related component parts are returned in this structure. :return: a non-zero value if the object is a Python datetime object. .. c:function:: struct _frame sipGetFrame(int depth) .. versionadded:: 4.19 This retrieves a frame object from the current execution stack. :param depth: the depth of frame to retrieve where 0 is the current frame, 1 is the previous frame etc. :return: the opaque frame or NULL if there wasn't one at the given depth. .. c:function:: void sipInstanceDestroyed(sipSimpleWrapper *obj) .. versionadded:: 4.19.3 This should be called by handwritten code if it is able to detect that a wrapped C++ instance has been destroyed from C++. It should not be called if SIP is able to detect this itself, i.e. when the instance was created from Python and the class has a virtual destructor. :param obj: the Python object that wraps the destroyed instance. .. c:function:: PyInterpreterState *sipGetInterpreter() .. versionadded:: 4.17.1 This returns the address of the Python interpreter. If it is ``NULL`` then calls to the Python interpreter library must not be made. :return: the address of the Python interpreter .. c:function:: int sipGetMethod(PyObject *obj, sipMethodDef *method) .. versionadded:: 4.19 This checks to see if an object is a Python method object and, if so, optionally returns its component parts. :param obj: the Python object. :param method: if this is not ``NULL``, and the object is a method object, then the component parts are returned in this structure. :return: a non-zero value if the object is a Python method object. .. c:function:: void *sipGetMixinAddress(sipSimpleWrapper *obj, const sipTypeDef *td) .. versionadded:: 4.15 This returns the address of the C++ class instance that implements the mixin of a wrapped Python object. :param obj: the Python object. :param td: the :ref:`generated type structure ` corresponding to the C++ type of the mixin. :return: the address of the C++ instance .. c:function:: 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 ` 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. .. c:function:: 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. .. c:function:: int sipGetTime(PyObject *obj, sipTimeDef *time) .. versionadded:: 4.19 This checks to see if an object is a Python time object and, if so, optionally returns its component parts. :param obj: the Python object. :param time: if this is not ``NULL``, and the object is a time object, then the component parts are returned in this structure. :return: a non-zero value if the object is a Python time object. .. c:function:: void *sipGetTypeUserData(const sipWrapperType *type) .. versionadded:: 4.19 Each generated type corresponding to a wrapped C/C++ type, or a user sub-class of such a type, contains a pointer for the use of handwritten code. This returns the value of that pointer. :param type: the type object. :return: the type-specific pointer. .. c:function:: PyObject *sipGetUserObject(const sipSimpleWrapper *obj) .. versionadded:: 4.19 Each wrapped object can contain a reference to a single Python object that can be used for any purpose by handwritten code and will automatically be garbage collected at the appropriate time. This returns that object. :param obj: the wrapped object. :return: the user object. .. c:function:: PyObject *sipGetWrapper(void *cppptr, sipWrapperType *type) .. deprecated:: 4.8 Use :c:func:`sipGetPyObject()` instead. 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 ` 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. .. c:function:: 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 :c:func:`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. .. c:type:: sipIntTypeClassMap .. deprecated:: 4.8 This C structure is used with :c:func:`sipMapIntToClass()` to define a mapping between integer based RTTI and :ref:`generated type objects `. The structure elements are as follows. .. c:member:: int typeInt The integer RTTI. .. c:member:: sipWrapperType **pyType. A pointer to the corresponding generated type object. .. c:function:: 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. .. c:function:: int sipIsUserType(const sipWrapperType *type) .. versionadded:: 4.19 This checks if a type corresponds to a wrapped C/C++ type or a user sub-class of such a type. :param type: the type object. :return: a non-zero value if the type is a user defined type. .. c:function:: char sipLong_AsChar(PyObject *obj) .. versionadded:: 4.19.4 This converts a Python object to a C/C++ char. If the value is too large then an exception is raised if overflow checking is enabled. :param obj: the Python object. :return: the converted C/C++ value. .. c:function:: signed char sipLong_AsSignedChar(PyObject *obj) .. versionadded:: 4.19.4 This converts a Python object to a C/C++ signed char. If the value is too large then an exception is raised if overflow checking is enabled. :param obj: the Python object. :return: the converted C/C++ value. .. c:function:: unsigned char sipLong_AsUnsignedChar(PyObject *obj) .. versionadded:: 4.19.4 This converts a Python object to a C/C++ unsigned char. If the value is too large then an exception is raised if overflow checking is enabled. :param obj: the Python object. :return: the converted C/C++ value. .. c:function:: short sipLong_AsShort(PyObject *obj) .. versionadded:: 4.19.4 This converts a Python object to a C/C++ short. If the value is too large then an exception is raised if overflow checking is enabled. :param obj: the Python object. :return: the converted C/C++ value. .. c:function:: unsigned short sipLong_AsUnsignedShort(PyObject *obj) .. versionadded:: 4.19.4 This converts a Python object to a C/C++ unsigned short. If the value is too large then an exception is raised if overflow checking is enabled. :param obj: the Python object. :return: the converted C/C++ value. .. c:function:: int sipLong_AsInt(PyObject *obj) .. versionadded:: 4.19.4 This converts a Python object to a C/C++ int. If the value is too large then an exception is raised if overflow checking is enabled. :param obj: the Python object. :return: the converted C/C++ value. .. c:function:: unsigned int sipLong_AsUnsignedInt(PyObject *obj) .. versionadded:: 4.19.4 This converts a Python object to a C/C++ unsigned int. If the value is too large then an exception is raised if overflow checking is enabled. :param obj: the Python object. :return: the converted C/C++ value. .. c:function:: long sipLong_AsLong(PyObject *obj) .. versionadded:: 4.19.4 This converts a Python object to a C/C++ long. If the value is too large then an exception is raised if overflow checking is enabled. :param obj: the Python object. :return: the converted C/C++ value. .. c:function:: unsigned long sipLong_AsUnsignedLong(PyObject *obj) .. versionadded:: 4.19.4 This converts a Python object to a C/C++ unsigned long. If the value is too large then an exception is raised if overflow checking is enabled. :param obj: the Python object. :return: the converted C/C++ value. .. c:function:: PY_LONG_LONG sipLong_AsLongLong(PyObject *obj) .. versionadded:: 4.19.4 This converts a Python object to a C/C++ long long. If the value is too large then an exception is raised if overflow checking is enabled. It is not available if ``Python.h`` does not define ``HAVE_LONG_LONG``. :param obj: the Python object. :return: the converted C/C++ value. .. c:function:: unsigned PY_LONG_LONG sipLong_AsUnsignedLongLong(PyObject *obj) .. versionadded:: 4.19.4 This converts a Python object to a C/C++ unsigned long long. If the value is too large then an exception is raised if overflow checking is enabled. It is not available if ``Python.h`` does not define ``HAVE_LONG_LONG``. :param obj: the Python object. :return: the converted C/C++ value. .. c:function:: void *sipMalloc(size_t nbytes) This allocates an area of memory on the heap using the Python :c:func:`PyMem_Malloc()` function. The memory is freed by calling :c:func:`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. .. c:function:: sipWrapperType *sipMapIntToClass(int type, const sipIntTypeClassMap *map, int maplen) .. deprecated:: 4.8 This can be used in :directive:`%ConvertToSubClassCode` code as a convenient way of converting integer based RTTI to the corresponding :ref:`generated type object `. :param type: the integer RTTI. :param map: the table of known RTTI and the corresponding type objects (see :c:type:`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*. .. c:function:: sipWrapperType *sipMapStringToClass(char *type, const sipStringTypeClassMap *map, int maplen) .. deprecated:: 4.8 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 `. :param type: the string RTTI. :param map: the table of known RTTI and the corresponding type objects (see :c:type:`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*. .. c:type:: sipMethodDef .. versionadded:: 4.19 This C structure is used with :c:func:`sipGetMethod()` and :c:func:`sipFromMethod()` and encapsulates the components parts of a Python method. The structure elements are as follows. .. c:member:: PyObject *pm_function The function that implements the method. .. c:member:: PyObject *pm_self The bound object. .. c:member:: PyObject *pm_class The class. (Python v2 only.) .. c:function:: sipNewUserTypeFunc sipSetNewUserTypeHandler(const sipTypeDef *td, sipNewUserTypeFunc handler) .. versionadded:: 4.19 The allows a function to be specified that is called whenever a user defined sub-class of a C/C++ type is created (i.e. one implemented in Python). It is normalled called from a module's :directive:`%PostInitialisationCode`. It is provided as an alternative to providing a meta-type when the limited Python API is enabled. :param td: the :ref:`generated type object ` corresponding to the C/C++ type. :param handler: the function that is called whenever a user defined sub-class of the type is created. The function takes a single argument which is the :c:type:`sipWrapperType` of the user defined class. It returns an :c:type:`int` which is 0 if there was no error. A Python exception is raised and -1 returned if there was an error. :return: the previously installed handler. This allows handlers to be chained. .. c:function:: 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 :c:func:`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 :c:func:`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 \*\*, :c:macro:`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 \*\*] .. deprecated:: 4.8 Use ``B`` instead. 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``. ``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) [:c:type:`sipWrapperType` \*, int \*, void \*\*] .. deprecated:: 4.8 Use ``Hf`` instead. Convert a Python object to a C structure or a C++ class instance and return its state as described in :c:func:`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. ``Df`` (wrapped instance) [const :c:type:`sipTypeDef` \*, int \*, void \*\*] .. deprecated:: 4.10.1 Use ``Hf`` instead. Convert a Python object to a C structure, C++ class or mapped type instance and return its state as described in :c:func:`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. ``E`` (wrapped enum) [PyTypeObject \*, enum \*] .. deprecated:: 4.8 Use ``F`` instead. Convert a Python named enum type to the corresponding C/C++ ``enum``. ``F`` (wrapped enum) [:c:type:`sipTypeDef` \*, enum \*] Convert a Python named enum type to the corresponding C/C++ ``enum``. ``G`` (unicode/string) [wchar_t \*\*, :c:macro:`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 :c:type:`sipTypeDef` \*, int \*, void \*\*] Convert a Python object to a C structure, C++ class or mapped type instance as described in :c:func:`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. ``L`` (integer) [signed char \*] .. versionadded:: 4.12 Convert a Python integer to a C/C++ ``signed char``. ``M`` (long) [unsigned char \*] .. versionadded:: 4.12 Convert a Python long to a C/C++ ``unsigned char``. ``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`` [:c:type:`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) [const char \*, void \*\*] .. versionadded:: 4.14.1 Convert a Python named capsule object to a C/C++ ``void *``. ``Z`` (object) [] Check that a Python object is ``Py_None``. No value is returned. ``!`` (object) [PyObject \*\*] .. versionadded:: 4.14.1 A Python object is checked to see if it implements the buffer protocol and then returned without any conversions. The reference count is incremented. The Python object may not be ``Py_None``. ``$`` (object) [PyObject \*\*] .. versionadded:: 4.14.1 A Python object is checked to see if it implements the buffer protocol and then returned without any conversions. The reference count is incremented. The Python object may be ``Py_None``. .. c:function:: PyObject *sipPyTypeDict(const PyTypeObject *py_type) .. versionadded:: 4.19 This provides access to a Python type object's ``tp_dict`` field and is typically used when the limited Python API is enabled. :param py_type: the type object. :return: the value of the type object's ``tp_dict`` field. .. c:function:: const char *sipPyTypeName(const PyTypeObject *py_type) .. versionadded:: 4.19 This provides access to a Python type object's ``tp_name`` field and is typically used when the limited Python API is enabled. :param py_type: the type object. :return: the value of the type object's ``tp_name`` field. .. c:function:: 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 ` 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 :c:type:`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 is returned if there was no error, otherwise -1 is returned. See the section :ref:`ref-lazy-type-attributes` for more details. .. c:function:: int sipRegisterProxyResolver(const sipTypeDef *td, sipProxyResolverFunc resolver) .. versionadded:: 4.15 This registers a resolver that will called just before SIP wraps a C/C++ pointer in a Python object. The resolver may choose to replace the C/C++ pointer with the address of another object. Typically this is used to replace a proxy by the object that is being proxied for. :param td: the optional :ref:`generated type structure ` that determines which type the resolver will be called for. :param resolver: the resolver function. :return: 0 if there was no error, otherwise -1 is returned. A resolver has the following signature. void \*resolver(void \*proxy) *proxy* is C/C++ pointer that is being wrapped. The C/C++ pointer that will actually be wrapped is returned. .. c:function:: 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. .. c:function:: void sipReleaseBufferInfo(sipBufferInfoDef *buffer_info) .. versionadded:: 4.19 This releases the buffer information related to a Python object that implements the buffer protocol that was created with a corresponding call to :c:func:`sipGetBufferInfo`. It is similar to :c:func:`PyBuffer_Release` and should be used instead of that when the limited Python API is enabled. :param buffer_info: the buffer information to release. .. c:function:: void sipReleaseInstance(void *cpp, sipWrapperType *type, int state) .. deprecated:: 4.8 Use :c:func:`sipReleaseType()` instead. This destroys a wrapped C/C++ instance if it was a temporary instance. It is called after a call to either :c:func:`sipConvertToInstance()` or :c:func:`sipForceConvertToInstance()`. :param cpp: the C/C++ instance. :param type: the type's :ref:`generated type object `. :param state: describes the state of the C/C++ instance. .. c:function:: void sipReleaseMappedType(void *cpp, const sipMappedType *mt, int state) .. deprecated:: 4.8 Use :c:func:`sipReleaseType()` instead. This destroys a wrapped C/C++ mapped type if it was a temporary instance. It is called after a call to either :c:func:`sipConvertToMappedType()` or :c:func:`sipForceConvertToMappedType()`. :param cpp: the C/C++ instance. :param mt: the opaque structure returned by :c:func:`sipFindMappedType()`. :param state: describes the state of the C/C++ instance. .. c:function:: 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 :c:func:`sipConvertToType()` or :c:func:`sipForceConvertToType()`. :param cpp: the C/C++ instance. :param td: the type's :ref:`generated type structure `. :param state: describes the state of the C/C++ instance. .. c:function:: 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. .. c:function:: void sipSetDestroyOnExit(int destroy) .. versionadded:: 4.14.7 When the Python interpreter exits it garbage collects those objects that it can. This means that any corresponding C++ instances and C structures owned by Python are destroyed. Unfortunately this happens in an unpredictable order and so can cause memory faults within the wrapped library. Calling this function with a value of zero disables the automatic destruction of C++ instances and C structures. :param destroy: non-zero if all C++ instances and C structures owned by Python should be destroyed when the interpreter exits. This is the default. .. c:function:: void sipSetTypeUserData(sipWrapperType *type, void *data) .. versionadded:: 4.19 Each generated type corresponding to a wrapped C/C++ type, or a user sub-class of such a type, contains a pointer for the use of handwritten code. This sets the value of that pointer. :param type: the type object. :param data: the type-specific pointer. .. c:function:: void sipSetUserObject(sipSimpleWrapper *obj, PyObject *user) .. versionadded:: 4.19 Each wrapped object can contain a reference to a single Python object that can be used for any purpose by handwritten code and will automatically be garbage collected at the appropriate time. This sets that object. :param obj: the wrapped object. :param user: the user object. .. c:type:: 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. When the limited Python API is enabled and Python v3.2 or later is being used then it is only available as an opaque (i.e. incomplete) type and the following members are not available. .. c:member:: void *data This is initialised to the address of the C/C++ instance. If an access function is subsequently provided then it may be used for any purpose by the access function. .. c:member:: sipAccessFunc access_func This is the address of an optional access function that is called, with a pointer to this structure as its first argument. If its second argument is ``UnguardedPointer`` then it returns the address of the C/C++ instance, even if it is known that its value is no longer valid. If the second argument is ``GuardedPointer`` then it returns the address of the C++ instance or ``0`` if it is known to be invalid. If the second argument is ``ReleaseGuard`` then the structure is being deallocated and any dynamic resources used by the access function should be released. If there is no access function then the :c:member:`sipSimpleWrapper.data` is used as the address of the C/C++ instance. Typically a custom meta-type is used to set an access method after the Python object has been created. .. c:member:: PyObject *user This can be used for any purpose by handwritten code and will automatically be garbage collected at the appropriate time. .. c:var:: PyTypeObject *sipSimpleWrapper_Type This is the type of a :c:type:`sipSimpleWrapper` structure and is the C implementation of :class:`sip.simplewrapper`. It may be safely cast to :c:type:`sipWrapperType`. When the limited Python API is enabled and Python v3.2 or later is being used then it is only available as an opaque (i.e. incomplete) type. .. c:type:: sipStringTypeClassMap .. deprecated:: 4.8 This C structure is used with :c:func:`sipMapStringToClass()` to define a mapping between ``'\0'`` terminated string based RTTI and :ref:`ref-type-objects`. The structure elements are as follows. .. c:member:: char *typeString The ``'\0'`` terminated string RTTI. .. c:member:: sipWrapperType **pyType. A pointer to the corresponding generated type object. .. c:type:: sipTimeDef .. versionadded:: 4.19 This C structure is used with :c:func:`sipGetTime()`, :c:func:`sipFromTime(), :c:func:`sipGetDateTime()` and :c:func:`sipFromDateTime()` and encapsulates the components parts of a Python time. The structure elements are as follows. .. c:member:: int pt_hour The hour (0-23). .. c:member:: int pt_minute The minute (0-59). .. c:member:: int pt_second The second (0-59). .. c:member:: int pt_microsecond The microsecond (0-999999). .. c:function:: 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. .. c:function:: 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. .. deprecated:: 4.14 Use the following instead: sipTransferTo(obj, NULL); .. c:function:: 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 ``Py_None`` then *obj* is given an extra reference which is removed when the C++ instance's destructor is called. 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++. .. c:function:: PyTypeObject *sipTypeAsPyTypeObject(const sipTypeDef *td) This returns a pointer to the Python type object that SIP creates for a :ref:`generated type structure `. :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 :c:type:`sipWrapperType`. .. c:function:: const sipTypeDef *sipTypeFromPyTypeObject(PyTypeObject *py_type) This returns the :ref:`generated type structure ` 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. .. c:function:: int sipTypeIsClass(sipTypeDef *td) This checks if a :ref:`generated type structure ` 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. .. c:function:: int sipTypeIsEnum(sipTypeDef *td) This checks if a :ref:`generated type structure ` refers to a C-style named enum. :param td: the type structure. :return: a non-zero value if the type structure refers to a C-style named enum. .. c:function:: int sipTypeIsMapped(sipTypeDef *td) This checks if a :ref:`generated type structure ` refers to a mapped type. :param td: the type structure. :return: a non-zero value if the type structure refers to a mapped type. .. c:function:: int sipTypeIsNamespace(sipTypeDef *td) This checks if a :ref:`generated type structure ` refers to a C++ namespace. :param td: the type structure. :return: a non-zero value if the type structure refers to a namespace. .. c:function:: int sipTypeIsScopedEnum(sipTypeDef *td) .. versionadded:: 4.19.4 This checks if a :ref:`generated type structure ` refers to a C++11 scoped enum. :param td: the type structure. :return: a non-zero value if the type structure refers to a C++11 scoped enum. .. c:function:: 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 `. :return: the name of the C/C++ type. .. c:function:: const sipTypeDef *sipTypeScope(const sipTypeDef *td) This returns the :ref:`generated type structure ` 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. .. c:function:: void *sipUnicodeData(PyObject *obj, int *char_size, SIP_SSIZE_T *len) .. versionadded:: 4.19 This returns information about the contents of a Python unicode object. This is only supported for Python v3.3 and later. :param obj: the unicode object. :param char_size: a pointer which will be updated with the number of bytes (either 1, 2 or 4) used to store a character. If there was an error then this will be a negative value. :param len: a pointer which will be updated with the number of characters (not bytes) in the unicode object. :return: the address of the buffer where the characters are stored. It will be undefined if the returned character size is a negative value. .. c:function:: PyObject *sipUnicodeNew(SIP_SSIZE_T len, unsigned maxchar, int *kind, void **data) .. versionadded:: 4.19 This creates a Python unicode object that will hold a set number of characters, each character being of a certain size. This is only supported for Python v3.3 and later. :param len: the number of characters. :param maxchar: the largest code point that will be placed in the object. :param kind: a pointer which will be updated with a value that represents the number of bytes (either 1, 2 or 4) used to store a character. :param data: a pointer which will be updated with the address of the buffer where the characters will be stored. :return: the unicode object or ``NULL`` if there was an error. .. c:function:: void sipUnicodeWrite(int kind, void *data, int index, unsigned value) .. versionadded:: 4.19 This updates the buffer of a Python unicode object with a character at a particular position. This is only supported for Python v3.3 and later. :param kind: the value that represents the number of bytes (either 1, 2 or 4) used to store a character. :param data: the address of the buffer where the characters are stored. :param index: the character (not byte) index of the character to be updated. :param value: the value of the new character. .. c:var:: PyTypeObject *sipVoidPtr_Type This is the type of a ``PyObject`` structure that is used to wrap a ``void *``. .. c:type:: sipWrapper This is a C structure that represents a Python wrapped instance whose type is :class:`sip.wrapper`. It is an extension of the :c:type:`sipSimpleWrapper` and ``PyObject`` structures and so may be safely cast to both. When the limited Python API is enabled and Python v3.2 or later is being used then it is only available as an opaque (i.e. incomplete) type. .. c:function:: int sipWrapper_Check(PyObject *obj) .. deprecated:: 4.8 Use the following instead: PyObject_TypeCheck(obj, sipWrapper_Type) 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. .. c:var:: PyTypeObject *sipWrapper_Type This is the type of a :c:type:`sipWrapper` structure and is the C implementation of :class:`sip.wrapper`. It may be safely cast to :c:type:`sipWrapperType`. .. c:type:: 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``). When the limited Python API is enabled and Python v3.2 or later is being used then it is only available as an opaque (i.e. incomplete) type. .. c:var:: PyTypeObject *sipWrapperType_Type This is the type of a :c:type:`sipWrapperType` structure and is the C implementation of :class:`sip.wrappertype`. Event Handlers -------------- .. versionadded:: 4.19.3 The :mod:`sip` module will trigger a number of events. Handwritten code can supply handlers for these events to allow it to perform additional actions. Each event has a type, described by the :cpp:enum:`sipEventType` enum. An event handler is registered using :c:func:`sipRegisterEventHandler()`. The signature of an event handler is specific to the event type. .. cpp:enum:: sipEventType This is the enum that defines the different event types. .. :cpp:enumerator:: sipEventWrappedInstance This event is triggered whenever a C/C++ instance that is created by C/C++ (and not by Python) is wrapped. The handler is passed a ``void *`` which is the address of the C/C++ instance. .. :cpp:enumerator:: sipEventCollectingWrapper This event is triggered whenever a Python wrapper object is being garbage collected. The handler is passed a pointer to the :c:type:`sipSimpleWrapper` object that is the Python wrapper object being garbage collected. .. c:function:: int sipRegisterEventHandler(sipEventType type, const sipTypeDef *td, void *handler) This registers an event handler which will be called whenever an event is triggered. :param type: the event type for which the handler is registered. :param td: the generated type structure - the handler will only be invoked for Python object corresponding to this type or a sub-type. :param handler: the handler that is called when the event is triggered. :return: 0 if there was no error, otherwise -1 is returned (and a Python exception is raised). .. _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 :c:type:`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 :c:func:`sipFindType()`. The type structures of all imported types explicitly used by a module are available to handwritten code. .. _ref-type-objects: Generated Type Objects ---------------------- .. deprecated:: 4.8 Use the corresponding generated type structure (see :ref:`ref-type-structures`) and :c:func:`sipTypeAsPyTypeObject()` instead. SIP generates a :c:type:`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``. .. _ref-enum-type-objects: Generated Named Enum Type Objects --------------------------------- .. deprecated:: 4.8 Use the corresponding generated type structure (see :ref:`ref-type-structures`) and :c:func:`sipTypeAsPyTypeObject()` instead. 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``. .. _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. sip-4.19.7/sphinx/command_line.rst0000644000076500000240000001374413231604406017166 0ustar philstaff00000000000000.. _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 .. deprecated:: 4.18 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 The name of the build file to generate. This file contains the information about the module needed by the :ref:`SIP build system ` to generate a platform and compiler specific Makefile for the module. By default the file is not generated. .. cmdoption:: -B .. versionadded:: 4.16 The tag is added to the list of *backstops*. The option may be given more than once if multiple timelines have been defined. See the :directive:`%Timeline` directive for more details. .. cmdoption:: -c 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 .. deprecated:: 4.12 Use the :option:`-X ` option instead. 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:: -D .. versionadded:: 4.19.1 Code is generated for a debug build of Python. .. 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:: -f .. versionadded:: 4.18 Warnings are handled as if they were errors and the program terminates. .. 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 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. Directory separators must always be ``/``. This option may be given any number of times. .. cmdoption:: -j 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 .. deprecated:: 4.12 Use the ``keyword_arguments="All"`` :directive:`%Module` directive argument instead. 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 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 The suffix to use for generated C or C++ source files. By default ``.c`` is used for C and ``.cpp`` for C++. .. cmdoption:: -t 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:: -T .. deprecated:: 4.16.6 This option is now ignored and timestamps are always disabled. By default the generated C and C++ source and header files include a timestamp specifying when they were generated. This option disables the timestamp so that the contents of the generated files remain constant for a particular version of SIP. .. cmdoption:: -w The display of warning messages is enabled. By default warning messages are disabled. .. cmdoption:: -x The feature (declared using the :directive:`%Feature` directive) is disabled. .. cmdoption:: -X .. versionadded:: 4.12 The extract (defined with the :directive:`%Extract` directive) with the identifier ``ID`` is written to the file ``FILE``. .. cmdoption:: -y .. versionadded:: 4.18 The name of the Python type hints stub file to generate. This file contains a description of the module API that is compliant with PEP 484. By default the file is not generated. .. cmdoption:: -z .. deprecated:: 4.16.6 Use the ``@`` style instead. The name of a file containing more command line options. Command line options can also be placed in a file and passed on the command line using the ``@`` prefix. sip-4.19.7/sphinx/conf.py0000644000076500000240000001111413231604431015271 0ustar philstaff00000000000000# -*- 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 datetime import os import sys # 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 = 'SIP' copyright = '{0} Riverbank Computing Limited'.format( datetime.date.today().year) # 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.19.7' # The full version, including alpha/beta/rc tags. release = '4.19.7' # 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 patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['html'] # 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. html_theme = 'riverbank' # 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 # " v documentation". html_title = "%s v%s Reference Guide" % (project, release) # Output file base name for HTML help builder. htmlhelp_basename = 'SIPdoc' # -- Project-specific extensions ----------------------------------------------- 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('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)') sip-4.19.7/sphinx/directives.rst0000644000076500000240000025330313231604406016677 0ustar philstaff00000000000000Directives ========== 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``. Revised Directive Syntax ------------------------ .. versionadded:: 4.12 The directive syntax used in older versions has some problems: - it is inconsistent in places - it can be problematic to parse - it is inflexible. SIP v4.12 introduced a revised directive syntax that addresses these problems and deprecates the old syntax. Support for the old syntax will be removed in SIP v5. The revised syntax is: .. parsed-literal:: %Directive(arg = value, ...) { %Sub-directive ... }; A directive may have a number of arguments enclosed in parentheses followed by a number of sub-directives enclosed in braces. Individual arguments and sub-directives may be optional. Arguments may be specified in any order. If no arguments are specified then the parentheses can be omitted. If a directive has only one compulsory argument then its value may be specified after the directive name and instead of the parentheses. Sub-directives may be specified in any order. If no sub-directives are specified then the braces can be omitted. If a directive is used to specify handwritten code then it may not have sub-directives. In this case the syntax is: .. parsed-literal:: %Directive(arg = value, ...) *code* %End Ordinary C/C++ statements may also have sub-directives. These will also be enclosed in braces. The documentation for each directive describes the revised syntax. The older syntax should be used if compatibility with versions of SIP prior to v4.12 is required. List of Directives ------------------ .. directive:: %AccessCode .. parsed-literal:: %AccessCode *code* %End This sub-directive is used in 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 }; .. seealso:: :directive:`%GetCode`, :directive:`%SetCode` .. directive:: %API .. versionadded:: 4.9 .. parsed-literal:: %API(name = *name*, version = *integer*) 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(name=PyQt4, version=1) .. directive:: %AutoPyName .. versionadded:: 4.12 .. parsed-literal:: %AutoPyName(remove_leading = *string*) This is a sub-directive of the :directive:`%Module` directive used to specify a rule for automatically providing Python names for classes, enums, functions, methods, variables and exceptions. The directive may be specified any number of times and each rule will be applied in turn. Rules will not be applied if an item has been given an explicit Python name. ``remove_leading`` is a string that will be removed from the beginning of any C++ or C name. For example:: %Module PyQt4.QtCore { %AutoPyName(remove_leading="Q") } .. 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 variables that are made available to the handwritten code depend on whether or not the limited Python API is enabled or not. The following variables are made available: sipBufferDef \*sipBuffer When the use of the limited API is enabled, this is a pointer to a structure that should be populated by the code. The ``bd_buffer`` field should be set to the address of the buffer. The ``bd_length`` field should be set to the length of the buffer. The ``bd_readonly`` field should be set to a non-zero value if the buffer is read-only. Py_buffer \*sipBuffer When the use of the limited Python API is disabled, this is a pointer to the Python buffer structure that should be populated by the code. *type* \*sipCpp This is a pointer to the structure or class instance. Its *type* is a pointer to the structure or class. int sipFlags When the use of the limited Python API is disabled, 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. :c:macro:`SIP_SSIZE_T` sipRes The handwritten code should set this to the length of the character buffer or -1 if there was an error. :c:macro:`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. :c:macro:`SIP_SSIZE_T` sipRes The handwritten code should set this to the length of the read buffer or -1 if there was an error. :c:macro:`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. :c:macro:`SIP_SSIZE_T` \*sipLenPtr This is the pointer used to return the total length in bytes of all segments of the buffer. :c:macro:`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. :c:macro:`SIP_SSIZE_T` sipRes The handwritten code should set this to the length of the write buffer or -1 if there was an error. :c:macro:`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 variables that are made available to the handwritten code depend on whether or not the limited Python API is enabled or not. The following variables are made available: Py_buffer \*sipBuffer When the use of the limited Python API is disabled, 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 .. deprecated:: 4.12 Use the :directive:`%Module` directive with the ``language`` argument set to ``"C"`` instead. .. 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 = *dotted-name*) { [:directive:`%Docstring`] }; 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:`%Module` directive is interpreted as defining a component module. The optional :directive:`%Docstring` sub-directive is used to specify the module's docstring. 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 individual module an object is defined in. .. directive:: %ConsolidatedModule .. deprecated:: 4.16.2 This will not be supported in SIP v5. .. parsed-literal:: %ConsolidatedModule(name = *dotted-name*) { [:directive:`%Docstring`] }; 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:`%Module` directive is interpreted as defining a component module. The optional :directive:`%Docstring` sub-directive is used to specify the module's docstring. 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 (when it is required) or of a class specification (when it is optional) to specify the handwritten code that converts an instance of a C/C++ type to a Python object. If used as part of a class specification then instances of the class will be automatically converted to the Python object, even though the class itself has been wrapped. This behaviour can be changed on a temporary basis from an application by calling the :func:`sip.enableautoconversion` function, or from handwritten code by calling the :c:func:`sipEnableAutoconversion` function. The following variables are made available to the handwritten code: *type* \*sipCpp This is a pointer to the C/C++ instance 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`` 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. The code may also set the value to a type that is apparently unrelated to the requested type. If this happens then the whole conversion process is started again using the new type as the requested type. This is typically used to deal with classes that have more than one super-class that are subject to this conversion process. It allows the code for one super-class to switch to the code for another (more appropriate) super-class. sipWrapperType \*sipClass .. deprecated:: 4.8 Use ``sipType`` instead. 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. 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. - :c:macro:`SIP_TEMPORARY` is set to indicate that the returned instance is a temporary and should be released to avoid a memory leak. - :c:macro:`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`` 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 *ql = new QList; 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(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 :c:func:`sipCanConvertToType()` to check the object type and :c:func:`sipConvertToType()` to convert the object. The :c:macro:`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) 2015 Riverbank Computing Limited %End .. directive:: %DefaultDocstringFormat .. versionadded:: 4.13 .. parsed-literal:: %DefaultDocstringFormat(name = ["raw" | "deindented"]) This directive is used to specify the default formatting of docstrings, i.e. when the :directive:`%Docstring` directive does not specify an explicit format. See the :directive:`%Docstring` directive for an explanation of the different formats. If the directive is not specified then the default format used is ``"raw"``. For example:: %DefaultDocstringFormat "deindented" .. directive:: %DefaultDocstringSignature .. versionadded:: 4.19.7 .. parsed-literal:: %DefaultDocstringSignature(name = ["discarded" | "prepended" | "appended"]) This directive is used to specify the default positioning of signatures in docstrings, i.e. when the :directive:`%Docstring` directive is used but does not specify an explicit positioning. See the :directive:`%Docstring` directive for an explanation of the different ways signatures are positioned. If the directive is not specified then the default positioning is ``"discarded"``. For example:: %DefaultDocstringSignature "prepended" .. directive:: %DefaultEncoding .. parsed-literal:: %DefaultEncoding(name = ["ASCII" | "Latin-1" | "UTF-8" | "None"]) This directive is used to specify the default encoding used for ``char``, ``const char``, ``char *`` or ``const char *`` values. 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 the default encoding of the last imported module is used, if any. For example:: %DefaultEncoding "Latin-1" .. directive:: %DefaultMetatype .. parsed-literal:: %DefaultMetatype(name = *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(name = *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 .. deprecated:: 4.12 Use the :directive:`%Extract` directive instead. .. 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

An Example

This fragment of documentation is HTML and is local to the module in which it is defined.

%End .. directive:: %Docstring .. versionadded:: 4.10 .. parsed-literal:: %Docstring(format = ["raw" | "deindented"], signature = ["discarded" | "prepended" | "appended"]) *text* %End This directive is used to specify explicit docstrings for modules, classes, functions, methods, typedefs and properties. 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. .. note:: Specifying an explicit docstring will mean 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. .. versionadded:: 4.13 ``format`` may either be ``"raw"`` or ``"deindented"``. If it is not specified then the value specified by any :directive:`%DefaultDocstringFormat` directive is used. If ``format`` is ``"raw"`` then the docstring is used as it appears in the specification file. If ``format`` is ``"deindented"`` then any leading spaces common to all non-blank lines of the docstring are removed. .. versionadded:: 4.19.7 ``signature`` may either be ``"discarded"``, ``"prepended"`` or ``"appended"``. It is ignored unless applied to the docstring of a class, function or method. If it is not specified then the value specified by any :directive:`%DefaultDocstringSignature` directive is used. If ``signature`` is ``"discarded"`` then the automatically generated function or method signature is discarded. In the context of a class's docstring then this refers to all of the constructors' docstrings. If ``signature`` is ``"prepended"`` then the automatically generated function or method signature is placed before the docstring. In the context of a class's docstring then this refers to all of the constructors' docstrings. If ``signature`` is ``"appended"`` then the automatically generated function or method signature is placed after the docstring. In the context of a class's docstring then this refers to all of the constructors' docstrings. For example:: class Klass { %Docstring This will be at the start of the class's docstring. %End public: Klass(); %Docstring deindented This will be appended to the class's docstring and will not be indented. This will be indented by four spaces. %End }; .. seealso:: :directive:`%DefaultDocstringFormat`, :directive:`%DefaultDocstringSignature` .. 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*)] { [:directive:`%TypeHeaderCode`] :directive:`%RaiseCode` }; 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. The optional :directive:`%TypeHeaderCode` sub-directive is used to specify any external interface to the exception being defined. The :directive:`%RaiseCode` sub-directive is 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 %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 .. deprecated:: 4.12 Use the :directive:`%Extract` directive instead. .. 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. .. seealso:: :directive:`%ModuleCode`, :directive:`%ModuleHeaderCode` .. directive:: %ExportedTypeHintCode .. versionadded:: 4.18 .. parsed-literal:: %ExportedTypeHintCode *code* %End This directive is used to specify handwritten code, typically the declarations of types, that is placed in the PEP 484 type hint stub file for any module that imports it. Note that it is not included in the stub file for the module itself. .. seealso:: :directive:`%TypeHintCode` .. directive:: %Extract .. versionadded:: 4.12 .. parsed-literal:: %Extract(id = *name* [, order = *integer*]) *text* %End This directive is used to specify part of an extract. An extract is a collection of arbitrary text specified as one or more parts each having the same ``id``. SIP places no interpretation on an identifier, or on the contents of the extract. Extracts may be used for any purpose, e.g. documentation, tests etc. The part's optional ``order`` determines its position relative to the extract's other parts. If the order is not specified then the part is appended to the extract. An extract is written to a file using the :option:`-X ` command line option. For example:: %Extract example This will be the last line because there is no explicit order. %End %Extract(id=example, order=20) This will be the second line. %End %Extract(id=example, order=10) This will be the first line. %End .. directive:: %Feature .. parsed-literal:: %Feature(name = *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 disabled. By default all features are enabled. The :option:`-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:: %FinalisationCode .. versionadded:: 4.15 .. parsed-literal:: %FinalisationCode *code* %End This directive is used to specify handwritten code that is executed once the instance of a wrapped class has been created. The handwritten code is passed a dictionary of any remaining keyword arguments. It must explicitly return an integer result which should be ``0`` if there was no error. If an error occurred then ``-1`` should be returned and a Python exception raised. The following variables are made available to the handwritten code: PyObject \*sipSelf This is the Python object that wraps the structure or class instance, i.e. ``self``. *type* \*sipCpp This is a pointer to the structure or class instance. Its *type* is a pointer to the structure or class. PyObject \*sipKwds This is an optional dictionary of unused keyword arguments. It may be ``NULL`` or refer to an empty dictionary. If the handwritten code handles any of the arguments then, if ``sipUnused`` is ``NULL``, those arguments must be removed from the dictionary. If ``sipUnused`` is not ``NULL`` then the ``sipKwds`` dictionary must not be updated. Instead a new dictionary must be created that contains any remaining unused keyword arguments and the address of the new dictionary returned via ``sipUnused``. This rather complicated API ensures that new dictionaries are created only when necessary. PyObject \*\*sipUnused This is an optional pointer to where the handwritten code should save the address of any new dictionary of unused keyword arguments that it creates. If it is ``NULL`` then the handwritten code is allowed to update the ``sipKwds`` dictionary. .. 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 the Python documentation 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(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(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 sub-directive is used in 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 }; } .. seealso:: :directive:`%AccessCode`, :directive:`%SetCode` .. directive:: %HideNamespace .. versionadded:: 4.19 .. parsed-literal:: %HideNamespace(name = *name*) This directive is used to specify that a C++ namespace, which would normally be wrapped as a Python class, is not wrapped. The contents of the namespace are still wrapped but are placed in the module dictionary. This is usually used when a library being wrapped uses a single namespace that includes everything in the library. In Python the module itself performs the same function as the namespace and so the namespace would just add an unneccessary extra level of indirection. .. 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 (SIP_4_13 - ) // SIP v4.13 and later will process this. %End %If ( - ) // Always process this. %End 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(name = *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 ``name`` cannot be opened then SIP prepends ``name`` 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 ``name`` with each of the directories, in turn, specified by the :option:`-I ` command line option. Directory separators must always be ``/``. For example:: %Import qt/qtmod.sip .. directive:: %Include .. parsed-literal:: %Include(name = *filename* [, optional = [True | False]]) 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 the :directive:`%Import` directive when trying to open ``name``. if ``optional`` is set then SIP will silently continue processing if the file could not be opened. Directory separators must always be ``/``. 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 :c:func:`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:: %InstanceCode .. versionadded:: 4.14 .. parsed-literal:: %InstanceCode *code* %End There are a number of circumstances where SIP needs to create an instance of a C++ class but may not be able to do so. For example the C++ class may be abstract or may not have an argumentless public constructor. This directive is used in the definition of a class or mapped type to specify handwritten code to create an instance of the C++ class. For example, if the C++ class is abstract, then the handwritten code may return an instance of a concrete sub-class. The following variable is made available to the handwritten code: *type* \*sipCpp This must be set by the handwritten code to the address of an instance of the C++ class. It doesn't matter if the instance is on the heap or not as it will never be explicitly destroyed. .. directive:: %License .. parsed-literal:: %License(type = *string* [, licensee = *string*] [, signature = *string*] [, timestamp = *string*]) 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. ``type`` is the type of the license and its value in the license dictionary is accessed using the ``"Type"`` key. No restrictions are placed on the value. ``licensee`` is the optional name of the licensee and its value in the license dictionary is accessed using the ``"Licensee"`` key. No restrictions are placed on the value. ``signature`` is the license's optional signature and its value in the license dictionary is accessed using the ``"Signature"`` key. No restrictions are placed on the value. ``timestamp`` is the license's optional timestamp and its value in the license dictionary is accessed using the ``"Timestamp"`` key. No restrictions are placed on the value. 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 "GPL" .. directive:: %MappedType .. parsed-literal:: template<*type-list*> %MappedType *type* { [:directive:`%TypeHeaderCode`] [:directive:`%ConvertToTypeCode`] [:directive:`%ConvertFromTypeCode`] }; %MappedType *type* { [:directive:`%TypeHeaderCode`] [:directive:`%ConvertToTypeCode`] [:directive:`%ConvertFromTypeCode`] }; 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. The optional :directive:`%TypeHeaderCode` sub-directive is used to specify the library interface to the type being mapped. The optional :directive:`%ConvertToTypeCode` sub-directive is used to specify the handwritten code that converts a Python object to an instance of the mapped type. The optional :directive:`%ConvertFromTypeCode` sub-directive is used to specify the handwritten code that converts an instance of the mapped type to a Python object. For example:: template %MappedType QList { %TypeHeaderCode // Include the library interface to the type being mapped. #include %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 *ql = new QList; 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(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`` 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. If ``use_argument_names`` has been set in the :directive:`%Module` directive then the name of the argument is the real name. 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. If ``use_argument_names`` has been set in the :directive:`%Module` directive then the name of the variable is the real name of the argument with ``Wrapper`` appended. *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 ``sipErrorFail`` 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 = *dotted-name* [, all_raise_py_exception = [True | False]] [, call_super_init = [True | False]] [, default_VirtualErrorHandler = *name*] [, keyword_arguments = ["None" | "All" | "Optional"]] [, language = *string*] [, use_argument_names = [True | False]] [, use_limited_api = [True | False]] [, version = *integer*]) { [:directive:`%AutoPyName`] [:directive:`%Docstring`] }; This directive is used to specify the name of a module and a number of other attributes. ``name`` may contain periods to specify that the module is part of a Python package. ``all_raise_py_exception`` specifies that all constructors, functions and methods defined in the module raise a Python exception to indicate that an error occurred. It is the equivalent of using the :fanno:`RaisesPyException` function annotation on every constructor, function and method. ``call_super_init`` specifies that the ``__init__()`` method of a wrapped class should automatically call it's super-class's ``__init__()`` method passing a dictionary of any unused keyword arguments. In other words, wrapped classes support cooperative multi-inheritance. This means that sub-classes, and any mixin classes, should always use call ``super().__init__()`` and not call any super-class's ``__init__()`` method explicitly. ``default_VirtualErrorHandler`` specifies the handler (defined by the :directive:`%VirtualErrorHandler` directive) that is called when a Python re-implementation of any virtual C++ function raises a Python exception. If no handler is specified for a virtual C++ function then ``PyErr_Print()`` is called. ``keyword_arguments`` specifies the default level of support for Python keyword arguments. See the :fanno:`KeywordArgs` annotation for an explaination of the possible values and their effect. If it is not specified then the value implied by the (deprecated) :option:`-k ` command line option is used. ``language`` specifies the implementation language of the library being wrapped. Its value is either ``"C++"`` (the default) or ``"C"``. When providing handwritten code as part of either the :directive:`%MethodCode` or :directive:`%VirtualCatcherCode` directives the names of the arguments of the function or method are based on the number of the argument, i.e. the first argument is named ``a0``, the second ``a1`` and so on. ``use_argument_names`` is set to specify that the real name of the argument, if any, should be used instead. It also affects the name of the variable created when the :aanno:`GetWrapper` argument annotation is used. ``use_limited_api`` specifies that the generated code will only use the limited Python API defined in PEP 384. It also ensures that the C preprocessor symbol ``Py_LIMITED_API`` is defined before the ``Python.h`` header file is included. Python extensions built in this way are independent of the version of Python being used. It is ignored for Python v2. ``version`` is an optional version number that 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. This is deprecated and ignored in SIP v4.19. The optional :directive:`%AutoPyName` sub-directive is used to specify a rule for automatically providing Python names. The optional :directive:`%Docstring` sub-directive is used to specify the module's docstring. For example:: %Module(name=PyQt4.QtCore, version=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 .. seealso:: :directive:`%ExportedHeaderCode`, :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 .. seealso:: :directive:`%ExportedHeaderCode`, :directive:`%ModuleCode` .. directive:: %OptionalInclude .. parsed-literal:: %OptionalInclude *filename* .. deprecated:: 4.12 Use the :directive:`%Include` directive with the ``optional`` argument set to ``True`` instead. 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 :option:`-t ` command line option is used to enable a platform. .. versionadded:: 4.14 If a platform is enabled then SIP will automatically generate a corresponding C preprocessor symbol for use by handwritten code. The symbol is the name of the platform prefixed by ``SIP_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:: %Property .. versionadded:: 4.12 .. parsed-literal:: %Property(name = *name*, get = *name* [, set = *name*]) { [:directive:`%Docstring`] }; This directive is used to define a Python property. ``name`` is the name of the property. ``get`` is the Python name of the getter method and must refer to a method in the same class. ``set`` is the Python name of the optional setter method and must refer to a method in the same class. The optional :directive:`%Docstring` sub-directive is used to specify the property's docstring. For example:: class Klass { public: int get_count() const; void set_count(); %Property(name=count, get=get_count, set=set_count) }; .. directive:: %PreMethodCode .. versionadded:: 4.19.1 .. parsed-literal:: %PreMethodCode *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 is inserted before the default code for calling the wrapped function, or before the :directive:`%MethodCode` directive if it is also given. .. 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 sub-directive is used in 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 \*. .. seealso:: :directive:`%AccessCode`, :directive:`%GetCode` .. 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. The SIP :option:`-t ` command line option is used to enable a version. If a timeline does not have a version explicitly enabled then the latest version will be enabled automatically. The :option:`-B ` command line option may be used to define a *backstop* for a timeline. Instead of automatically enabling the latest version, the version immediately preceeding the backstop is enabled instead. The :directive:`%Timeline` directive can be used any number of times in a module to allow multiple libraries to be wrapped in the same module. .. versionadded:: 4.12 SIP automatically defines a timeline containing all versions of SIP since v4.12. The name of the version is ``SIP_`` followed by the individual parts of the version number separated by an underscore. SIP v4.12 is therefore ``SIP_4_12`` and SIP v4.13.2 is ``SIP_4_13_2``. .. versionadded:: 4.14 If a particular version is enabled then SIP will automatically generate a corresponding C preprocessor symbol for use by handwritten code. The symbol is the name of the version prefixed by ``SIP_TIMELINE_``. 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 %If (- SIP_4_13) void bar(); %End .. directive:: %TypeCode .. parsed-literal:: %TypeCode *code* %End This directive is used as part of the specification of a C structure, a C++ class or a :directive:`%MappedType` directive 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 %End // The rest of the class specification. }; .. directive:: %TypeHintCode .. versionadded:: 4.18 .. parsed-literal:: %TypeHintCode *code* %End This directive is used, in the context of a module or an individual class, to specify handwritten code, typically the import of additional modules, that is placed in the PEP 484 type hint stub file for the module or class. .. seealso:: :directive:`%ExportedTypeHintCode` .. directive:: %UnitCode .. parsed-literal:: %UnitCode *code* %End This directive is used to specify handwritten code that is 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:: %UnitPostIncludeCode .. versionadded:: 4.11 .. parsed-literal:: %UnitPostIncludeCode *code* %End This directive is used to specify handwritten code that is included following the ``#include`` of all header files in a generated compilation unit (ie. C or C++ source file). .. directive:: %VirtualCallCode .. versionadded:: 4.16.7 .. parsed-literal:: %VirtualCallCode *code* %End For most classes there are corresponding :ref:`generated 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 original class method if there is no Python reimplementation. 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. If ``use_argument_names`` has been set in the :directive:`%Module` directive then the name of the argument is the real name. The *type* of the variable is the same as the type defined in the specification. *type* sipRes The handwritten code should set this to any result to be returned. The *type* of the variable is the same as the type defined in the C++ signature in the specification. .. directive:: %VirtualCatcherCode .. parsed-literal:: %VirtualCatcherCode *code* %End This directive is used to specify handwritten code that replaces the normally generated call to the Python reimplementation of a virtual method 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. If ``use_argument_names`` has been set in the :directive:`%Module` directive then the name of the argument is the real name. 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 :c:func:`sipParseResult()` using either the ``A`` or ``B`` format characters. If ``use_argument_names`` has been set in the :directive:`%Module` directive then the name of the variable is the real name of the argument with ``Key`` appended. 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 :c:func:`sipCallMethod()`. *type* sipRes The handwritten code should set this to any 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 :c:func:`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 :c:func:`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 }; .. directive:: %VirtualErrorHandler .. versionadded:: 4.14 .. parsed-literal:: %VirtualErrorHandler(name = *name*) *code* %End This directive is used to define the handwritten code that implements a handler that is called when a Python re-implementation of a virtual C++ function raises a Python exception. If a virtual C++ function does not have a handler the ``PyErr_Print()`` function is called. The handler is called after all tidying up has been completed, with the Python Global Interpreter Lock (GIL) held and from the thread that raised the exception. If the handler wants to change the execution path by, for example, throwing a C++ exception, it must first release the GIL by calling :c:func:`SIP_RELEASE_GIL`. It must not call :c:func:`SIP_RELEASE_GIL` if the execution path is not changed. The following variables are made available to the handwritten code: sipSimpleWrapper \*sipPySelf This is the class instance containing the Python reimplementation. sip_gilstate_t sipGILState This is an opaque value that must be passed to :c:func:`SIP_RELEASE_GIL` in order to release the GIL prior to changing the execution path. For example:: %VirtualErrorHandler my_handler PyObject *exception, *value, *traceback; PyErr_Fetch(&exception, &value, &traceback); SIP_RELEASE_GIL(sipGILState); throw my_exception(sipPySelf, exception, value, traceback); %End .. seealso:: :fanno:`NoVirtualErrorHandler`, :fanno:`VirtualErrorHandler`, :canno:`VirtualErrorHandler` sip-4.19.7/sphinx/distutils.rst0000644000076500000240000000304613231604406016557 0ustar philstaff00000000000000.. _ref-distutils: Building Your Extension with distutils ====================================== .. note:: This should not be used for new projects as it will not be supported by SIP v5. 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. If ``sip-opts`` has not been specified then any ``swig_opts`` defined when creating the ``Extension`` will be used. sip-4.19.7/sphinx/embedding.rst0000644000076500000240000000520313231604406016446 0ustar philstaff00000000000000Using the C API when Embedding ============================== The :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``. When using Python v2.7, or Python v3.1 or later the data structure is wrapped as a Python ``PyCapsule`` object. When using other versions of Python the data structure is wrapped as a Python ``PyCObject`` object. It 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 :c:func:`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 const sipAPIDef *get_sip_api() { #if defined(SIP_USE_PYCAPSULE) return (const sipAPIDef *)PyCapsule_Import("sip._C_API", 0); #else 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); #endif } The use of :c:macro:`SIP_USE_PYCAPSULE` means that code will run under all versions of Python. sip-4.19.7/sphinx/incompatibilities.rst0000644000076500000240000002154713231604406020251 0ustar philstaff00000000000000Potential 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.19.4 ----------- Converting to C/C++ Enums ************************* Prior to this version only traditional C/C++ enums were supported. They are implemented with a SIP-generated type that allows integers to be used whenever enum members are expected. Obtaining the integer value of an enum member could be done using the standard Python function :c:func:`PyLong_AsLong()` and therefore no specific conversion function was provided by the SIP API. Starting with this version, C++11 scoped enums are also supported and are implemented using Python's :py:mod:`enum` module. The integer values of members of these enums cannot be obtained using :c:func:`PyLong_AsLong()` and so :c:func:`sipConvertToEnum()` has been added to the SIP API. This function should be used for converting all types of enum. SIP v4.19 --------- Deprecation of Module Version Number ************************************ Prior to this version, the :directive:`%Module` directive allowed a version number to be specified for a module. This was then checked against the version numbers (if specified) of any other modules that imported it. This was intended to detect when binary incompatible modules where being used. Starting with this version the version number is deprecated and is simply ignored. Other internal changes have eliminated the need for this feature. Generated Type Structures for Imported Types ******************************************** As described in :ref:`ref-type-structures` SIP generates a *type structure* for each C structure, C++ class and namespace, mapped type and named enum. Prior to this version every type structure in a module was automatically available to any handwritten code in any module that imported it. Starting with this version only those type structures needed by the generated code are automatically available to handwritten code possibly resulting in compiler errors. Handwritten code should be changed to call :c:func:`sipFindType()` to obtain a pointer to the required type structure. SIP v4.16 --------- Prior to this version, if no valid version tag was specified using the :option:`-t ` command line option to :program:`sip` then all versions of the corresponding timeline were considered disabled. Starting with this version SIP assumes that the latest version is enabled if no valid version tag was specified. Exactly what is meant by the latest version can be changed by using the :option:`-B ` command line option to define a *backstop* for a timeline. See the :directive:`%Timeline` directive for more details. SIP v4.14.4 ----------- Prior to this version, the handwritten code defined by the :directive:`%VirtualErrorHandler` directive was called without the Python Global Interpreter Lock (GIL) being held and from an arbitrary thread. Starting with this version the code is called with the GIL being held and from the thread that raised the error. In addition the code is provided a value called ``sipGILState`` that may be passed to :c:func:`SIP_RELEASE_GIL` in order to release the GIL. This must be done if the code changes the execution path (e.g. by throwing a C++ exception). SIP v4.12.3 ----------- Prior to this version, when SIP searches a class hierachy to see if there is a Python reimplementation of a virtual C++ method, it ignored any objects that were not Python functions or methods. Starting with this version such an object is not ignored and will be called. If it is not callable then a Python exception will be raised. For example, the following code will now raise an excepton because the ``Mixin.event`` attribute will now be called as it is assumed to be a valid reimplementation of ``QObject.event()``:: class Mixin: event = False class MyObject(QObject, Mixin): pass SIP v4.12 --------- Prior to this version several directives ignored any enclosing :directive:`%If` directive. Starting with this version all directives are affected by the :directive:`%If` directive. SIP v4.10.1 ----------- Newly Deprecated Features ************************* The following parts of the :ref:`C API ` are now deprecated (but still supported). - The ``D`` format character of :c:func:`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 :c:type:`sipWrapper` structure had a member called :c:type:`user` which is available for handwritten code to use. From this version :c:type:`user` is a member of the :c:type:`sipSimpleWrapper` structure. :c:type:`sipWrapper` pointers can be safely cast to :c:type:`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 ` have been removed. - The ``a``, ``A``, ``M``, ``N``, ``O``, ``P`` and ``T`` format characters from :c:func:`sipBuildResult()` and :c:func:`sipCallMethod()`. - The ``a``, ``A``, ``L`` and ``M`` format characters from :c:func:`sipParseResult()`. - :c:func:`sipConvertToCpp()` - :c:func:`sipIsSubClassInstance()` - :c:func:`sipTransfer()` - The :func:`transfer` function of the :mod:`sip` module. - The old-style generated type convertors. In addition the ``-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. - :c:func:`sipConnectRx()` - :c:func:`sipDisconnectRx()` - :c:func:`sipEmitSlot()` - :c:func:`sipGetSender()` Newly Deprecated Features ************************* The following parts of the :ref:`C API ` are now deprecated (but still supported). - The :ref:`ref-type-objects`. - The :ref:`ref-enum-type-objects`. - :c:func:`sipConvertFromInstance()` - :c:func:`sipConvertFromMappedType()` - :c:func:`sipConvertFromNamedEnum()` - :c:func:`sipConvertFromNewInstance()` - :c:func:`sipCanConvertToInstance()` - :c:func:`sipCanConvertToMappedType()` - :c:func:`sipConvertToInstance()` - :c:func:`sipConvertToMappedType()` - :c:func:`sipForceConvertToInstance()` - :c:func:`sipForceConvertToMappedType()` - :c:func:`sipClassName()` - :c:func:`sipFindClass()` - :c:func:`sipFindNamedEnum()` - :c:func:`sipFindMappedType()` - :c:func:`sipGetWrapper()` - :c:func:`sipReleaseInstance()` - :c:func:`sipReleaseMappedType()` - :c:func:`sipWrapper_Check()` - The ``B``, ``C`` and ``E`` format characters of :c:func:`sipBuildResult()` and :c:func:`sipCallMethod()`. - The ``s``, ``C`` and ``E`` format characters of :c:func:`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 :c:macro:`SIP_BUILD` C preprocessor symbol has been removed. Newly Deprecated Features ************************* The following parts of the :ref:`C API ` are now deprecated (but still supported). - The old-style generated type convertors. - :c:func:`sipConvertToCpp()` - :c:func:`sipIsSubClassInstance()` sip-4.19.7/sphinx/index.rst0000644000076500000240000000043013231604406015634 0ustar philstaff00000000000000SIP Reference Guide =================== .. toctree:: :maxdepth: 2 introduction incompatibilities installation using command_line specification_files directives annotations c_api embedding python_api build_system distutils sip-4.19.7/sphinx/installation.rst0000644000076500000240000002570313231604406017240 0ustar philstaff00000000000000Installation ============ 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 :program:`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:\python35\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 Binaries for the MacOS/X architecture ```` 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 , --bindir The SIP code generator will be installed in the directory ````. .. cmdoption:: --configuration .. versionadded:: 4.16 ```` contains the configuration of the SIP build to be used instead of dynamically introspecting the system and is typically used when cross-compiling. See :ref:`ref-configuration-files`. .. cmdoption:: -d , --destdir The :mod:`sip` module will be installed in the directory ````. .. cmdoption:: --deployment-target .. versionadded:: 4.12.1 Each generated Makefile will set the :envvar:`MACOSX_DEPLOYMENT_TARGET` environment variable to ````. In order to work around bugs in some versions of Python, this should be used instead of setting the environment variable in the shell. .. cmdoption:: -e , --incdir The SIP header file will be installed in the directory ````. .. cmdoption:: -k, --static The :mod:`sip` module will be built as a static library. This is useful when building the :mod:`sip` module as a Python builtin. .. cmdoption:: -n, --universal The SIP code generator and module will be built as universal binaries under MacOS/X. If the :option:`--arch ` option has not been specified then the universal binary will include the ``i386`` and ``ppc`` architectures. .. cmdoption:: --no-stubs .. versionadded:: 4.19 This disables the installation of the ``sip.pyi`` type hints stub file. .. cmdoption:: --no-tools .. versionadded:: 4.16 The SIP code generator and :mod:`sipconfig` module will not be installed. .. cmdoption:: -p , --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 ` option will display all the supported platform/compilers. .. cmdoption:: -s , --sdk If the :option:`--universal ` 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 ``/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs`` or ``/Developer/SDKs``. .. cmdoption:: --stubsdir .. versionadded:: 4.19 ```` is the name of the directory where the ``sip.pyi`` type hints stub file is installed. By default this is the directory where the :mod:`sip` module is installed. .. cmdoption:: -u, --debug The :mod:`sip` module will be built with debugging symbols. .. cmdoption:: -v , --sipdir By default ``.sip`` files will be installed in the directory ````. .. 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. .. cmdoption:: --sip-module The :mod:`sip` module will be created with the name ```` rather than the default ``sip``. ```` may be of the form ``package.sub-package.module``. See :ref:`ref-private-sip` for how to use this to create a private copy of the :mod:`sip` module. .. cmdoption:: --sysroot .. versionadded:: 4.16 ```` is the name of an optional directory that replaces ``sys.prefix`` in the names of other directories (specifically those specifying where the various SIP components will be installed and where the Python include directories can be found). It is typically used when cross-compiling or when building a static version of SIP. See :ref:`ref-configuration-files`. .. cmdoption:: --target-py-version .. versionadded:: 4.16 ```` is the major and minor version (e.g. ``3.4``) of the version of Python being targetted. By default the version of Python being used to run the :program:`configure.py` script is used. It is typically used when cross-compiling. See :ref:`ref-configuration-files`. .. cmdoption:: --use-qmake .. versionadded:: 4.16 Normally the :program:`configure.py` script uses SIP's own build system to create the Makefiles for the code generator and module. This option causes project files (``.pro`` files) used by Qt's :program:`qmake` program to be generated instead. :program:`qmake` should then be run to generate the Makefiles. This is particularly useful when cross-compiling. The :program:`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 ` 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 :program:`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 ` command line option to specify the correct platform. For example:: c:\python35\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 ` command line option to specify the correct platform. For example:: c:\python35\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 python35.lib python35_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. .. _ref-configuration-files: Configuring with Configuration Files ------------------------------------ The :program:`configure.py` script normally introspects the Python installation of the interpreter running it in order to determine the names of the various files and directories it needs. This is fine for a native build of SIP but isn't appropriate when cross-compiling. In this case it is possible to supply a configuration file, specified using the :option:`--configuration ` option, which contains definitions of all the required values. The format of a configuration file is as follows: - a configuration item is a single line containing a name/value pair separated by ``=`` - a value may include another value by embedding the name of that value surrounded by ``%(`` and ``)`` - comments begin with ``#`` and continue to the end of the line - blank lines are ignored. :program:`configure.py` provides the following preset values for a configuration: ``py_major`` is the major version number of the target Python installation. ``py_minor`` is the minor version number of the target Python installation. ``sysroot`` is the name of the system root directory. This is specified with the :option:`--sysroot ` option. The following is an example configuration file:: # The target Python installation. py_platform = linux py_inc_dir = %(sysroot)/usr/include/python%(py_major)%(py_minor) # Where SIP will be installed. sip_bin_dir = %(sysroot)/usr/bin sip_module_dir = %(sysroot)/usr/lib/python%(py_major)/dist-packages The following values can be specified in the configuration file: ``py_platform`` is the target Python platform. ``py_inc_dir`` is the target Python include directory containing the ``Python.h`` file. ``py_conf_inc_dir`` is the target Python include directory containing the ``pyconfig.h`` file. If this isn't specified then it defaults to the value of ``py_inc_dir``. ``py_pylib_dir`` is the target Python library directory. ``sip_bin_dir`` is the name of the target directory where the SIP code generator will be installed. It can be overridden by the :option:`--bindir ` option. ``sip_inc_dir`` is the name of the target directory where the ``sip.h`` file will be installed. If this isn't specified then it defaults to the value of ``py_inc_dir``. It can be overridden by the :option:`--incdir ` option. ``sip_module_dir`` is the target directory where the :mod:`sip` module will be installed. It can be overridden by the :option:`--destdir ` option. ``sip_sip_dir`` is the name of the target directory where generated ``.sip`` files will be installed by default. It is only used when creating the :mod:`sipconfig` module. It can be overridden by the :option:`--sipdir ` option. sip-4.19.7/sphinx/introduction.rst0000644000076500000240000001600013231604431017244 0ustar philstaff00000000000000Introduction ============ This is the reference guide for SIP 4.19.7. SIP is a tool for automatically generating `Python `__ bindings for C and C++ libraries. SIP was originally developed in 1998 for `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 `__ 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 `__ 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 - support for the automatic generation of PEP 484 type hint stub 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, MacOS/X, Android and iOS. 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`. Preparing for SIP v5 -------------------- The syntax of a SIP specification file will change in SIP v5. The command line options to the SIP code generator will also change. In order to help users manage the transition the following approach will be adopted. - Where possible, all incompatible changes will be first implemented in SIP v4. - When an incompatible change is implemented, the old syntax will be deprecated (with a warning message) but will be supported for the lifetime of v4. Qt Support ---------- SIP has specific support for the creation of bindings based on Digia'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. sip-4.19.7/sphinx/python_api.rst0000644000076500000240000003326013231604406016706 0ustar philstaff00000000000000.. _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. .. class:: array .. versionadded:: 4.15 This is the type object for the type SIP uses to represent an array of a limited number of C/C++ types. Typically the memory is not owned by Python so that it is not freed when the object is garbage collected. A :class:`sip.array` object can be created from a :class:`sip.voidptr` object by calling :func:`sip.voidptr.asarray`. This allows the underlying memory (interpreted as a sequence of unsigned bytes) to be processed much more quickly. .. function:: assign(obj, other) .. versionadded:: 4.19 This does the Python equivalent of invoking the assignment operator of a C++ instance (i.e. ``*obj = other``). :param obj: the Python object being assigned to. :param other: the Python object being assigned. .. 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:: enableautoconversion(type, enable) -> bool .. versionadded:: 4.14.7 Instances of some classes may be automatically converted to other Python objects even though the class has been wrapped. This allows that behaviour to be suppressed so that an instances of the wrapped class is returned instead. By default it is enabled. :param type: the Python type object. :param enable: is ``True`` if auto-conversion should be enabled for the type. :return: ``True`` or ``False`` depending on whether or not auto-conversion was previously enabled for the type. This allows the previous state to be restored later on. .. function:: enableoverflowchecking(enable) -> bool .. versionadded:: 4.19.4 This enables or disables the checking for overflows when converting Python integer objects to C/C++ integer types. When it is enabled an exception is raised when the value of a Python integer object is too large to fit in the corresponding C/C++ type. By default it is disabled. :param enable: is ``True`` if overflow checking should be enabled. :return: ``True`` or ``False`` depending on whether or not overflow checking was previously enabled. This allows the previous state to be restored later on. .. 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:: ispycreated(obj) -> bool .. versionadded:: 4.12.1 This checks if the C++ instance or C structure was created by Python. If it was then it is possible to call a C++ instance's protected methods. :param obj: the Python object. :return: ``True`` if the C/C++ instance was created by Python. .. 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:: setdestroyonexit(destroy) .. versionadded:: 4.14.2 When the Python interpreter exits it garbage collects those objects that it can. This means that any corresponding C++ instances and C structures owned by Python are destroyed. Unfortunately this happens in an unpredictable order and so can cause memory faults within the wrapped library. Calling this function with a value of ``False`` disables the automatic destruction of C++ instances and C structures. :param destroy: ``True`` if all C++ instances and C structures owned by Python should be destroyed when the interpreter exits. This is the default. .. function:: settracemask(mask) If the bindings have been created with SIP's :option:`-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. .. class:: simplewrapper This is an alternative type object than can be used as the base type of an instance wrapped by SIP. Objects using this are smaller than those that use the default :class:`sip.wrapper` type but do not support the concept of object ownership. .. data:: SIP_VERSION .. versionadded:: 4.2 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``). .. data:: SIP_VERSION_STR .. versionadded:: 4.3 This is a Python string object that defines the SIP version number as represented as a string. For development versions it will contain either ``.dev`` or ``-snapshot-``. .. function:: transferback(obj) This function is a wrapper around :c:func:`sipTransferBack()`. .. function:: transferto(obj, owner) This function is a wrapper around :c:func:`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 interface is supported. 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, an object that implements the buffer protocol 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:: __getitem__(idx) -> item .. versionadded:: 4.12 This returns the item at a given index. An exception will be raised if the address does not have an associated size. In this way it behaves like a Python ``memoryview`` object. :param idx: is the index which may either be an integer, an object that implements ``__index__()`` or a slice object. :return: the item. If the index is an integer then the item will be a Python v2 string object or a Python v3 bytes object containing the single byte at that index. If the index is a slice object then the item will be a new :class:`voidptr` object defining the subset of the memory corresponding to the slice. .. method:: __hex__() -> string This returns the address as a hexadecimal string. :return: the hexadecimal string address. .. method:: __len__() -> integer .. versionadded:: 4.12 This returns the size associated with the address. :return: the associated size. An exception will be raised if there is none. .. method:: __setitem__(idx, item) .. versionadded:: 4.12 This updates the memory at a given index. An exception will be raised if the address does not have an associated size or is not writable. In this way it behaves like a Python ``memoryview`` object. :param idx: is the index which may either be an integer, an object that implements ``__index__()`` or a slice object. :param item: is the data that will update the memory defined by the index. It must implement the buffer interface and be the same size as the data that is being updated. .. method:: asarray([size=-1]) -> :class:`sip.array` .. versionadded:: 4.16.5 This returned the block of memory as a :class:`sip.array` object. The memory is *not* copied. :param size: the size of the array. 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 :class:`sip.array` object. .. 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 and is not supported with Python v3.2 and 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 default base type of all instances wrapped by SIP. The :canno:`Supertype` class annotation can be used to specify a different base type for a class. .. class:: wrappertype This is the type object of the metatype of the :class:`sip.wrapper` type. sip-4.19.7/sphinx/riverbank/0000755000076500000240000000000013231604406015761 5ustar philstaff00000000000000sip-4.19.7/sphinx/riverbank/layout.html0000644000076500000240000000020013231604406020154 0ustar philstaff00000000000000{% extends "classic/layout.html" %} {% set favicon = "logo_tn.png" %} {% set logo = "logo.png" %} {% set show_source = False %} sip-4.19.7/sphinx/riverbank/static/0000755000076500000240000000000013231604406017250 5ustar philstaff00000000000000sip-4.19.7/sphinx/riverbank/static/logo.png0000644000076500000240000000761313231604406020725 0ustar philstaff00000000000000PNG  IHDRdd pHYs!3=IDATx]ipTǵ}FѾ" ŏ0Kq1Ky y&.1qHB])W/6P! FrA hcHIYn~h3 fWw7}>N$:VhkKѮ75r, tg į VUuMpAAxȒ!y3 EOt=c1ʌX<15Fu+MW_a3?Y?96ez8^ ܭy, |h y O9mM=lV)P|zp `d .}\#J I2/iu!|1lY@Q|G:x7o଄gTaLINшc @)H.Ҷ.?'K&w&7~M\T7Z(tA2=Ӊѽ+]@" Iy$?TM]KU.O)#K~wէJ%)%p=XG9N=47Tmo|\?=#<,vѼ4B8g.̋!×̟|J/$Cxa:+^iey:\rr bq qTIY^o &Ko Y_.ɥ$Tˆj`*䝅J֒I*kvѽd}x<,GGo{aϑKrH9uȲ]N4\CDz{w?Vޝ8?@ˇ-4VQ@Hm񴸜$ZcKbWeE,y!m?vl"%hNWi)̰2zF,IqԸwr%vyɒ#&FR;zX`?qTQul 8V9>ZM'n6B6=.7xN5 cGd4bq5rbb򉡐,!&ES7%$^ N<'$EHBJQi~E8̐yP &(5FOdlXm !-tIkO{P@DGRv2G3ӑcu 2 NO5"A]RA#tj=IzeVs T h`k C(fd@SD,N/Lƛx!y E8h)Y,1Ċ+T(πЈPCdsv'w%+=NM.g4HQLCYe!}^~xPAZˮdpjvd1X}^̒iϫ-tAW:rFt{I9 k4_&([*` B jtէof%h&%{U^8Mp肉Rκ?PN-z$)@ ~LZ83+v'.wtzJ9 dh3Im1{3W|;^8#8,V-H!Cd?-3ⶃM rg"5R;Muךq| YYj6t&2A_aE6Wvl"GG<#wO#Z=1WC5w Taxm&1E<DZ ~x92i#5s $\fC>0Z=lD uwӣ[Eub*YÆ]PڎudQ7,FlMxɨu?1R Ky&|bd}YL75oM]bjM]9Yх3%N0YJ(8=[cIePC $'yl{j"U6g1``HjjCa&6ߡZH9zyq{$CM|QVa r,`O6|ROP-@1bZ..,#6ܟ9%UGZ?oٓ#-FYӦ/״4S3]IqYJ9mU.Ω?ofnG?䡆~gcY3L6(ebHij[|khrG 5;0??Oo鐰iӾ3FhOJ=4YWMzzyOdUPn #qyz$igy=io25MzzMeU,_ b~2h {tlp"v ϐ ~P-;k/KXOMTR5Z&ĩL7]hla娮59fhW?<1Ջ׶:6U\*Ҍw òԮ@Pk뗦]&aAZiP)IDfu^OI狲|6B;Y85tax a:v`ZUqOD yz6o侴);`~O|V#aV-8ۼQMWbNS3o%~ޭ'_,gRHU=(}Ta ?=n|B]MEBӾd_CJ\Q:%-/w$iޛhj` 8c}a9(%A $(g@964x$}4;N{1'+zcq 뾡VSοY xgyF#+ zVYA` 0NV/eĘ##+ m*IENDB`sip-4.19.7/sphinx/riverbank/static/logo_tn.ico0000644000076500000240000000217613231604406021413 0ustar philstaff00000000000000 h(  @ݱݱݱݱݱݱݱݱݱݱݱݱݱݱݱݱ|[|[|[|[|[|[|[|[|[|[|[|[|[|[|[|[Ʀťͱ˯PQ˯βݱstݱááܯܯݰTTݰݱIIݱݰeeݰ޲޲ε##δۭۭۭ~ۭ~ڪz|,,|ڪzsip-4.19.7/sphinx/riverbank/static/riverbank.css0000644000076500000240000000045213231604406021746 0ustar philstaff00000000000000@import url("classic.css"); div.body h1, div.body h2 { border-radius: 10px; margin-right: 0px; } h1 a:visited, h2 a:visited { color: white; text-decoration: none; } .classtable { width: 100%; } th.field-name { background: none; } th.head { background: lightgray; } sip-4.19.7/sphinx/riverbank/theme.conf0000644000076500000240000000066313231604406017737 0ustar philstaff00000000000000[theme] inherit = classic stylesheet = riverbank.css [options] footerbgcolor = white footertextcolor = black sidebarbgcolor = white sidebartextcolor = black sidebarlinkcolor = #4186cb relbarbgcolor = white relbartextcolor = black relbarlinkcolor = #4186cb headbgcolor = #4186cb headtextcolor = white headlinkcolor = #4186cb linkcolor = #4186cb visitedlinkcolor = #4186cb bodyfont = Copperplate / Copperplate Gothic Light, sans-serif sip-4.19.7/sphinx/specification_files.rst0000644000076500000240000005253113231604406020540 0ustar philstaff00000000000000SIP 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:`%CompositeModule` | :directive:`%ConsolidatedModule` | :directive:`%Copying` | :directive:`%DefaultEncoding` | :directive:`%DefaultMetatype` | :directive:`%DefaultSupertype` | :directive:`%ExportedHeaderCode` | :directive:`%ExportedTypeHintCode` | :directive:`%Extract` | :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:`%TypeHintCode` | :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* ::= [**public** | **protected** | **private**] *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:`%InstanceCode` | :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**] [**final**] [*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**] [**final**] [*exceptions*] [**= 0**] [*function-annotations*] [*c++-signature*] **;** [:directive:`%MethodCode`] [:directive:`%VirtualCatcherCode`] [:directive:`%VirtualCallCode`] *special-method* ::= *type* *special-method-name* **(** [*argument-list*] **)** [*function-annotations*] **;** [:directive:`%MethodCode`] *special-method-name* ::= [**__abs__** | **__add__** | **__and__** | **__aiter__** | **__anext__** | **__await__** | **__bool__** | **__call__** | **__cmp__** | **__contains__** | **__delattr__** | **__delitem__** | **__div__** | **__eq__** | **__float__** | **__floordiv__** | **__ge__** | **__getattr__** | **__getattribute__** | **__getitem__** | **__gt__** | **__hash__** | **__iadd__** | **__iand__** | **__idiv__** | **__ifloordiv__** | **__ilshift__** | **__imatmul__** | **__imod__** | **__imul__** | **__index__** | **__int__** | **__invert__** | **__ior__** | **__irshift__** | **__isub__** | **__iter__** | **__itruediv__** | **__ixor__** | **__le__** | **__len__** | **__long__** | **__lshift__** | **__lt__** | **__matmul** | **__mod__** | **__mul__** | **__ne__** | **__neg__** | **__next__** | **__nonzero__** | **__or__** | **__pos__** | **__repr__** | **__rshift__** | **__setattr__** | **__setitem__** | **__str__** | **__sub__** | **__truediv__** | **__xor__**] *operator* ::= *operator-type* **(** [*argument-list*] **)** [**const**] [**final**] [*exceptions*] [*function-annotations*] **;** [:directive:`%MethodCode`] *virtual-operator* ::= **virtual** *operator-type* **(** [*argument-list*] **)** [**const**] [**final**] [*exceptions*] [**= 0**] [*function-annotations*] **;** [:directive:`%MethodCode`] [:directive:`%VirtualCatcherCode`] [:directive:`%VirtualCallCode`] *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** [*enum-key*] [*name*] [*enum-annotations*] **{** {*enum-line*} **};** *enum-key* ::= [**class** | **struct**] *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_ArithmeticError** | **SIP_AssertionError** | **SIP_AttributeError** | **SIP_BaseException** | **SIP_BlockingIOError** | **SIP_BrokenPipeError** | **SIP_BufferError** | **SIP_ChildProcessError** | **SIP_ConnectionAbortedError** | **SIP_ConnectionError** | **SIP_ConnectionRefusedError** | **SIP_ConnectionResetError** | **SIP_EnvironmentError** | **SIP_EOFError** | **SIP_Exception** | **SIP_FileExistsError** | **SIP_FileNotFoundError** | **SIP_FloatingPointError** | **SIP_GeneratorExit** | **SIP_ImportError** | **SIP_IndentationError** | **SIP_IndexError** | **SIP_InterruptedError** | **SIP_IOError** | **SIP_IsADirectoryError** | **SIP_KeyboardInterrupt** | **SIP_KeyError** | **SIP_LookupError** | **SIP_MemoryError** | **SIP_NameError** | **SIP_NotADirectoryError** | **SIP_NotImplementedError** | **SIP_OSError** | **SIP_OverflowError** | **SIP_PermissionError** | **SIP_ProcessLookupError** | **SIP_ReferenceError** | **SIP_RuntimeError** | **SIP_StandardError** | **SIP_StopIteration** | **SIP_SyntaxError** | **SIP_SystemError** | **SIP_SystemExit** | **SIP_TabError** | **SIP_TimeoutError** | **SIP_TypeError** | **SIP_UnboundLocalError** | **SIP_UnicodeDecodeError** | **SIP_UnicodeEncodeError** | **SIP_UnicodeError** | **SIP_UnicodeTranslateError** | **SIP_ValueError** | **SIP_VMSError** | **SIP_WindowsError** | **SIP_ZeroDivisionError** | **SIP_Warning** | **SIP_BytesWarning** | **SIP_DeprecationWarning** | **SIP_FutureWarning** | **SIP_ImportWarning** | **SIP_PendingDeprecationWarning** | **SIP_ResourceWarning** | **SIP_RuntimeWarning** | **SIP_SyntaxWarning** | **SIP_UnicodeWarning** | **SIP_UserWarning**] *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` | :stype:`SIP_SSIZE_T`] *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** | **PyObject** | :stype:`SIP_PYBUFFER` | :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. 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 .. deprecated:: 4.18 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_PYBUFFER This is a ``PyObject *`` that implements the Python buffer protocol. .. 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. The type ``PyObject *`` can also be used. .. 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 .. deprecated:: 4.18 This is a ``QObject *`` that is a C++ instance of a class derived from Qt's ``QObject`` class. .. sip-type:: SIP_RXOBJ_CON .. deprecated:: 4.18 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 .. deprecated:: 4.18 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 .. deprecated:: 4.18 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 .. deprecated:: 4.18 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 .. deprecated:: 4.18 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 .. deprecated:: 4.18 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. .. sip-type:: SIP_SSIZE_T This is a ``Py_ssize_t`` in Python v2.5 and later and ``int`` in earlier versions of Python. 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. Namespaces ---------- SIP implements C++ namespaces as a Python class which cannot be instantiated. The contents of the namespace, including nested namespaces, are implemented as attributes of the class. The namespace class is created in the module that SIP is parsing when it first sees the namespace defined. If a function (for example) is defined in a namespace that is first defined in another module then the function is added to the namespace class in that other module. Say that we have a file ``a.sip`` that defines a module ``a_module`` as follows:: %Module a_module namespace N { void hello(); }; We also have a file ``b.sip`` that defines a module ``b_module`` as follows:: %Module b_module %Import a.sip namespace N { void bye(); }; When SIP parses ``b.sip`` it first sees the ``N`` namespace defined in module ``a_module``. Therefore it places the ``bye()`` function in the ``N`` Python class in the ``a_module``. It does not create an ``N`` Python class in the ``b_module``. Consequently the following code will call the ``bye()`` function:: import a_module import b_module a_module.N.bye() While this reflects the C++ usage it may not be obvious to the Python programmer who might expect to call the ``bye()`` function using:: import b_module b_module.N.bye() In order to achieve this behavior make sure that the ``N`` namespace is first defined in the ``b_module``. The following version of ``b.sip`` does this:: %Module b_module namespace N; %Import a.sip namespace N { void bye(); }; Alternatively you could just move the :directive:`%Import` directive so that it is at the end of the file. sip-4.19.7/sphinx/using.rst0000644000076500000240000006546713231604406015677 0ustar philstaff00000000000000.. _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 class Word { %TypeHeaderCode #include %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, ``word`` in this example. - 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 ` 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. */ %Module(name=word, language="C") struct Word { %TypeHeaderCode #include %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:`%Module` directive specifies that the library being wrapped is implemented in C rather than C++. Because we are now supplying an optional argument to the directive we must also specify the module name as an argument. - 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 #include #include 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 %Import QtGui/QtGuimod.sip %If (Qt_4_2_0 -) class Hello : public QLabel { %TypeHeaderCode #include %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 PyQt4. 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 :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 PyQt4, 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, PyQt4 includes a pure Python module called ``pyqtconfig`` that extends the SIP build system for modules, like our example, that build on top of PyQt4. 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 PyQt4 configuration information. config = pyqtconfig.Configuration() # Get the extra SIP flags needed by the imported PyQt4 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``. PyQt4 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 :c:func:`sipTransferTo()`, :c:func:`sipTransferBack()` and :c:func:`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 :c:func:`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. .. note:: It is not possible to define new super-types or meta-types if the limited Python API is enabled. .. _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 :c:func:`sipRegisterAttributeGetter()`). This will be called just before a type's dictionary is accessed for the first time. Overflow Checking ----------------- By default SIP does not check for overflow when converting Python number objects to C/C++ types. Overflowed values are undefined - it cannot be assumed that upper bits are simply discarded. SIP v4.19.4 allowed overflow checking to be enabled and disabled by the wrapper author (using :c:func`sipEnableOverflowChecking()`) or by the application developer (using :py:func`sip.enableoverflowchecking()`). It is recommended that wrapper authors should always enable overflow checking by default. 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 :c:func:`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 :c:func:`sipFree()`) after that 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 ` 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 `, :manno:`mapped type ` or :fanno:`function ` 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(name=MyAPI, version=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. .. _ref-private-sip: Building a Private Copy of the ``sip`` Module --------------------------------------------- .. versionadded:: 4.12 The ``sip`` module is intended to be be used by all the SIP generated modules of a particular Python installation. For example PyQt4 and PyQt5 are completely independent of each other but will use the same ``sip`` module. However, this means that all the generated modules must be built against a compatible version of SIP. If you do not have complete control over the Python installation then this may be difficult or even impossible to achieve. To get around this problem you can build a private copy of the ``sip`` module that has a different name and/or is placed in a different Python package. To do this you use the :option:`--sip-module ` option to specify the name (optionally including a package name) of your private copy. As well as building the private copy of the module, the version of the ``sip.h`` header file will also be specific to the private copy. You will probably also want to use the :option:`--incdir ` option to specify the directory where the header file will be installed to avoid overwriting a copy of the default version that might already be installed. When building your generated modules you must ensure that they ``#include`` the private copy of ``sip.h`` instead of any default version.