sip-4.15.5/0000755000076500000240000000000012310606641012457 5ustar philstaff00000000000000sip-4.15.5/configure.py0000644000076500000240000004470112310606636015024 0ustar philstaff00000000000000# This script handles the SIP configuration and generates the Makefiles. # # Copyright (c) 2014 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 = 0x040f05 sip_version_str = "4.15.5" py_version = sys.hexversion >> 8 plat_py_site_dir = None plat_py_inc_dir = None plat_py_conf_inc_dir = None plat_py_lib_dir = None plat_sip_dir = None plat_bin_dir = None platform_specs = [] src_dir = os.path.dirname(os.path.abspath(__file__)) sip_module_base = None # Constants. DEFAULT_MACOSX_ARCH = 'i386 ppc' MACOSX_SDK_DIRS = ('/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs', '/Developer/SDKs') # Command line options. default_platform = None default_sipbindir = None default_sipmoddir = None default_sipincdir = None default_sipsipdir = None # The names of build macros extracted from the platform specific configuration # files. build_macro_names = [ "DEFINES", "CONFIG", "CC", "CFLAGS", "CFLAGS_RELEASE", "CFLAGS_DEBUG", "CFLAGS_CONSOLE", "CFLAGS_SHLIB", "CFLAGS_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_defaults(): """Set up the defaults for values that can be set on the command line. """ global default_platform, default_sipbindir, default_sipmoddir global default_sipincdir, default_sipsipdir # Set the platform specific default specification. platdefaults = { "aix": "aix-xlc", "bsd": "bsdi-g++", "cygwin": "cygwin-g++", "darwin": "macx-g++", "dgux": "dgux-g++", "freebsd": "freebsd-g++", "gnu": "hurd-g++", "hp-ux": "hpux-acc", "irix": "irix-cc", "linux": "linux-g++", "lynxos": "lynxos-g++", "netbsd": "netbsd-g++", "openbsd": "openbsd-g++", "openunix": "unixware-cc", "osf1": "tru64-cxx", "qnx": "qnx-g++", "reliantunix": "reliant-cds", "sco_sv": "sco-cc", "sinix": "reliant-cds", "sunos5": "solaris-cc", "ultrix": "ultrix-g++", "unix_sv": "unixware-g++", "unixware": "unixware-cc" } default_platform = "none" if sys.platform == "win32": if py_version >= 0x030300: default_platform = "win32-msvc2010" elif py_version >= 0x020600: default_platform = "win32-msvc2008" elif py_version >= 0x020400: default_platform = "win32-msvc.net" else: default_platform = "win32-msvc" else: for pd in list(platdefaults.keys()): if sys.platform[:len(pd)] == pd: default_platform = platdefaults[pd] break default_sipbindir = plat_bin_dir default_sipmoddir = plat_py_site_dir default_sipincdir = plat_py_inc_dir default_sipsipdir = plat_sip_dir def inform_user(): """Tell the user the option values that are going to be used. """ siputils.inform("The SIP code generator will be installed in %s." % opts.sipbindir) siputils.inform("The %s module will be installed in %s." % (sip_module_base, opts.sipmoddir)) siputils.inform("The sip.h header file will be installed in %s." % opts.sipincdir) siputils.inform("The default directory to install .sip files in is %s." % opts.sipsipdir) siputils.inform("The platform/compiler configuration is %s." % opts.platform) if opts.arch: siputils.inform("MacOS/X binaries will be created for %s." % (", ".join(opts.arch.split()))) if opts.universal: siputils.inform("MacOS/X universal binaries will be created using %s." % opts.universal) 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_conf_inc_dir global plat_bin_dir, plat_py_lib_dir, plat_sip_dir # We trust distutils for some stuff. plat_py_site_dir = sysconfig.get_python_lib(plat_specific=1) plat_py_inc_dir = sysconfig.get_python_inc() plat_py_conf_inc_dir = os.path.dirname(sysconfig.get_config_h_filename()) if sys.platform == "win32": plat_py_lib_dir = sys.prefix + "\\libs" plat_bin_dir = sys.exec_prefix plat_sip_dir = sys.prefix + "\\sip" else: lib_dir = sysconfig.get_python_lib(plat_specific=1, standard_lib=1) plat_py_lib_dir = lib_dir + "/config" plat_bin_dir = sys.exec_prefix + "/bin" plat_sip_dir = sys.prefix + "/share/sip" def 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": opts.platform, "sip_bin": os.path.join(opts.sipbindir, "sip"), "sip_inc_dir": opts.sipincdir, "sip_mod_dir": opts.sipmoddir, "default_bin_dir": plat_bin_dir, "default_mod_dir": plat_py_site_dir, "default_sip_dir": opts.sipsipdir, "py_version": py_version, "py_inc_dir": plat_py_inc_dir, "py_conf_inc_dir": plat_py_conf_inc_dir, "py_lib_dir": plat_py_lib_dir, "universal": opts.universal, "arch": opts.arch, "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) sipconfig.inform("Creating top level Makefile...") sipconfig.ParentMakefile( configuration=cfg, subdirs=["sipgen", "siplib"], installs=(["sipconfig.py", os.path.join(src_dir, "sipdistutils.py")], cfg.sip_mod_dir) ).generate() sipconfig.inform("Creating sip code generator Makefile...") sipconfig.ProgramMakefile( configuration=cfg, build_file=os.path.join(src_dir, "sipgen", "sipgen.sbf"), dir="sipgen", install_dir=os.path.dirname(cfg.sip_bin), console=1, warnings=0, universal=opts.universal, arch=opts.arch, deployment_target=opts.deployment_target ).generate() sipconfig.inform("Creating sip module Makefile...") makefile = sipconfig.ModuleMakefile( configuration=cfg, build_file=os.path.join(src_dir, "siplib", "siplib.sbf"), dir="siplib", install_dir=cfg.sip_mod_dir, installs=([os.path.join(src_dir, "siplib", "sip.h")], cfg.sip_inc_dir), console=1, warnings=0, static=opts.static, debug=opts.debug, universal=opts.universal, arch=opts.arch, deployment_target=opts.deployment_target ) makefile.generate() 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)) p = optparse.OptionParser(usage="python %prog [opts] [macro=value] " "[macro+=value]", version=sip_version_str) # Note: we don't use %default to be compatible with Python 2.3. p.add_option("-k", "--static", action="store_true", default=False, dest="static", help="build the SIP module as a static library") p.add_option("-p", "--platform", action="store", default=default_platform, type="string", metavar="PLATFORM", dest="platform", help="the platform/compiler configuration " "[default: %s]" % default_platform) p.add_option("-u", "--debug", action="store_true", default=False, help="build with debugging symbols") 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]") 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", default=default_sipbindir, type="string", metavar="DIR", dest="sipbindir", callback=store_abspath, help="where the SIP " "code generator will be installed [default: %s]" % default_sipbindir) g.add_option("-d", "--destdir", action="callback", default=default_sipmoddir, type="string", metavar="DIR", dest="sipmoddir", callback=store_abspath, help="where the SIP " "module will be installed [default: %s]" % default_sipmoddir) g.add_option("-e", "--incdir", action="callback", default=default_sipincdir, type="string", metavar="DIR", dest="sipincdir", callback=store_abspath, help="where the SIP " "header file will be installed [default: %s]" % default_sipincdir) g.add_option("-v", "--sipdir", action="callback", default=default_sipsipdir, type="string", metavar="DIR", dest="sipsipdir", callback=store_abspath, help="where .sip files " "are normally installed [default: %s]" % default_sipsipdir) p.add_option_group(g) return p def main(argv): """Create the configuration module module. argv is the list of command line arguments. """ siputils.inform("This is SIP %s for Python %s on %s." % (sip_version_str, sys.version.split()[0], sys.platform)) if py_version < 0x020300: siputils.error("This version of SIP requires Python v2.3 or later.") # Basic initialisation. set_platform_directories() # Build up the list of valid specs. for s in os.listdir(os.path.join(src_dir, "specs")): platform_specs.append(s) # 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 set_defaults() p = create_optparser(sdk_dir) opts, args = p.parse_args() # 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 = '' # Get the platform specific macros for building. macros = siputils.parse_build_macros( os.path.join(src_dir, "specs", opts.platform), build_macro_names, args) if macros is None: 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, opts.sipmoddir) opts.sipmoddir = 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.15.5/custom/0000755000076500000240000000000012125131242013763 5ustar philstaff00000000000000sip-4.15.5/custom/custom.c0000644000076500000240000000312611562553731015462 0ustar philstaff00000000000000/* * This file is the basis of a custom Python interpreter. Use it for Linux, * UNIX and Windows (console). You will also need to edit mkcustom.py. */ #include int main(int argc, char **argv) { /* * Declare the module initialisation function for each module you want * to be a builtin in the custom interpreter. The name of the function * will be the name of the module with "init" prepended. The modules * must be built as static libraries (using the -k flag to configure.py * for SIP and PyQt). */ /* The sip module will be builtin. */ extern void initsip(void); /* * Uncomment these (and in the structure below) to include the PyQt * modules as builtins. */ /* extern void initqt(void);*/ /* extern void initqtaxcontainer(void);*/ /* extern void initqtcanvas(void);*/ /* extern void initqtext(void);*/ /* extern void initqtgl(void);*/ /* extern void initqtnetwork(void);*/ /* extern void initqtsql(void);*/ /* extern void initqttable(void);*/ /* extern void initqtui(void);*/ /* extern void initqtxml(void);*/ /* * This structure specifies the names and initialisation functions of * the builtin modules. */ struct _inittab builtin_modules[] = { {"sip", initsip}, /* {"qt", initqt},*/ /* {"qtaxcontainer", initqtaxcontainer},*/ /* {"qtcanvas", initqtcanvas},*/ /* {"qtext", initqtext},*/ /* {"qtgl", initqtgl},*/ /* {"qtnetwork", initqtnetwork},*/ /* {"qtsql", initqtsql},*/ /* {"qttable", initqttable},*/ /* {"qtui", initqtui},*/ /* {"qtxml", initqtxml},*/ {NULL, NULL} }; PyImport_ExtendInittab(builtin_modules); return Py_Main(argc, argv); } sip-4.15.5/custom/customw.c0000644000076500000240000000332311562553731015650 0ustar philstaff00000000000000/* * This file is the basis of a custom Python interpreter. Use it for Windows * (non-console). You will also need to edit mkcustom.py. */ #define WIN32_LEAN_AND_MEAN #include #include int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { /* * Declare the module initialisation function for each module you want * to be a builtin in the custom interpreter. The name of the function * will be the name of the module with "init" prepended. The modules * must be built as static libraries (using the -k flag to configure.py * for SIP and PyQt). */ /* The sip module will be builtin. */ extern void initsip(void); /* * Uncomment these (and in the structure below) to include the PyQt * modules as builtins. */ /* extern void initqt(void);*/ /* extern void initqtaxcontainer(void);*/ /* extern void initqtcanvas(void);*/ /* extern void initqtext(void);*/ /* extern void initqtgl(void);*/ /* extern void initqtnetwork(void);*/ /* extern void initqtsql(void);*/ /* extern void initqttable(void);*/ /* extern void initqtui(void);*/ /* extern void initqtxml(void);*/ /* * This structure specifies the names and initialisation functions of * the builtin modules. */ struct _inittab builtin_modules[] = { {"sip", initsip}, /* {"qt", initqt},*/ /* {"qtaxcontainer", initqtaxcontainer},*/ /* {"qtcanvas", initqtcanvas},*/ /* {"qtext", initqtext},*/ /* {"qtgl", initqtgl},*/ /* {"qtnetwork", initqtnetwork},*/ /* {"qtsql", initqtsql},*/ /* {"qttable", initqttable},*/ /* {"qtui", initqtui},*/ /* {"qtxml", initqtxml},*/ {NULL, NULL} }; PyImport_ExtendInittab(builtin_modules); return Py_Main(__argc, __argv); } sip-4.15.5/custom/mkcustom.py0000644000076500000240000000516112125131242016202 0ustar philstaff00000000000000"""This Python script uses the SIP build system to create a Makefile for building a custom Python interpreter. The script doesn't take any command line flags - just edit it to suit your needs. You will also need to edit custom.c or customw.c. """ import sys import sipconfig # Get the SIP configuration. cfg = sipconfig.Configuration() # This is the name of the interpreter executable (excluding any platform # specific extension. InterpreterName = "custom" # Set this to True to create a non-console interpreter on Windows (ie. a custom # version of pythonw). Make sure you make changes to customw.c rather than # custom.c. It is ignored on other platforms. WindowsInterpreter = False # Set this to the list of the name of modules to be builtin to the custom # interpreter. The modules must also be added to custom.c and/or customw.c. Modules = ["sip"] #Modules = ["sip", "qt", "qtaxcontainer", "qtcanvas", "qtext", "qtgl", # "qtnetwork", "qtsql", "qttable", "qtui", "qtxml"] # Set this to the name of the directory containing the static modules. ModuleDirectory = cfg.default_mod_dir # Set this to the list of additional libraries to link with the custom # interpreter. ExtraLibraries = [] #ExtraLibraries = ["qassistantclient"] # Set this to the list of additional directory names to search for any # additional libraries. ExtraLibraryDirectories = [] # Set this to the name of the directory containing the Python library. PythonLibraryDirectory = cfg.py_lib_dir # Make platform specific modifications. if sys.platform.startswith("linux"): ExtraLibraries.append("util") # Create a dictionary describing the target and source files to be passed to # the SIP build system. build = {} if sys.platform == "win32" and WindowsInterpreter: build["target"] = InterpreterName + "w" build["sources"] = "customw.c" console = False else: build["target"] = InterpreterName build["sources"] = "custom.c" console = True # Assume Qt support is required if Qt support was enabled in the sip module. qt = (cfg.qt_version > 0) # Create the Makefile instance. mf = sipconfig.ProgramMakefile(cfg, build, python=True, console=console, qt=qt) # Modify the Makefile according to the values set above. mf.extra_lib_dirs.extend(ExtraLibraryDirectories) mf.extra_lib_dirs.append(ModuleDirectory) mf.extra_lib_dirs.append(PythonLibraryDirectory) mf.extra_libs.extend(Modules) if sys.platform == "win32": pylib = "python%u%u" else: pylib = "python%u.%u" mf.extra_libs.append(pylib % ((cfg.py_version >> 16), ((cfg.py_version >> 8) & 0xff))) mf.extra_libs.extend(ExtraLibraries) # Generate the Makefile itself. mf.generate() sip-4.15.5/doc/0000755000076500000240000000000012310606641013224 5ustar philstaff00000000000000sip-4.15.5/doc/html/0000755000076500000240000000000012310606653014173 5ustar philstaff00000000000000sip-4.15.5/doc/html/_sources/0000755000076500000240000000000012310606652016014 5ustar philstaff00000000000000sip-4.15.5/doc/html/_sources/annotations.txt0000644000076500000240000011437312274165576021141 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); .. argument-annotation:: DocType .. versionadded:: 4.10 This string annotation specifies the type of the argument as it will appear in any generated docstrings. It is usually used with arguments of type :stype:`SIP_PYOBJECT` to provide a more specific type. .. argument-annotation:: DocValue .. versionadded:: 4.10 This string annotation specifies the default value of the argument as it will appear in any generated docstrings. .. argument-annotation:: Encoding This string annotation specifies that the corresponding argument (which should be either ``char``, ``const char``, ``char *`` or ``const char *``) refers to an encoded character or ``'\0'`` terminated encoded string with the specified encoding. The encoding can be either ``"ASCII"``, ``"Latin-1"``, ``"UTF-8"`` or ``"None"``. An encoding of ``"None"`` means that the corresponding argument refers to an unencoded character or string. The default encoding is specified by the :directive:`%DefaultEncoding` directive. If the directive is not specified then ``None`` is used. Python v3 will use the ``bytes`` type to represent the argument if the encoding is ``"None"`` and the ``str`` type otherwise. Python v2 will use the ``str`` type to represent the argument if the encoding is ``"None"`` and the ``unicode`` type otherwise. .. argument-annotation:: GetWrapper This boolean annotation is only ever used in conjunction with handwritten code specified with the :directive:`%MethodCode` directive. It causes an extra variable to be generated for the corresponding argument which is a pointer to the Python object that wraps the argument. See the :directive:`%MethodCode` directive for more detail. .. argument-annotation:: In This boolean annotation is used to specify that the corresponding argument (which should be a pointer type) is used to pass a value to the function. For pointers to wrapped C structures or C++ class instances, ``char *`` and ``unsigned char *`` then this annotation is assumed unless the :aanno:`Out` annotation is specified. For pointers to other types then this annotation must be explicitly specified if required. The argument will be dereferenced to obtain the actual value. Both :aanno:`In` and :aanno:`Out` may be specified for the same argument. .. argument-annotation:: KeepReference This 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 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. .. _ref-class-annos: Class Annotations ----------------- .. class-annotation:: Abstract This boolean annotation is used to specify that the class has additional pure virtual methods that have not been specified and so it cannot be instantiated or sub-classed from Python. .. class-annotation:: AllowNone .. versionadded:: 4.8.2 Normally when a Python object is converted to a C/C++ instance ``None`` is handled automatically before the class's :directive:`%ConvertToTypeCode` is called. This boolean annotation specifies that the handling of ``None`` will be left to the :directive:`%ConvertToTypeCode`. The annotation is ignored if the class does not have any :directive:`%ConvertToTypeCode`. .. class-annotation:: API .. versionadded:: 4.9 This API range annotation is used to specify an API and corresponding range of version numbers that the class is enabled for. If a class or mapped type has different implementations enabled for different ranges of version numbers then those ranges must not overlap. 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:: 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:: 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:: 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 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` .. _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:: 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:: 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:: DocType .. versionadded:: 4.10 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:: 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:: NewThread This boolean annotation specifies that the function will create a new thread. .. function-annotation:: NoArgParser This boolean annotation is used with methods and global functions to specify that the supplied :directive:`%MethodCode` will handle the parsing of the arguments. .. function-annotation:: NoCopy .. versionadded:: 4.10.1 This boolean annotation is used with methods and global functions that return a ``const`` reference to a class. Normally, if the class defines a copy constructor then a copy of the returned reference is automatically created and wrapped. The copy will be owned by Python. If the annotation is specified then the copy is not made and the original reference is wrapped instead and will be owned by C++. .. function-annotation:: NoDerived This boolean annotation is only used with C++ constructors. In many cases SIP generates a derived class for each class being wrapped (see :ref:`ref-derived-classes`). This derived class contains constructors with the same C++ signatures as the class being wrapped. Sometimes you may want to define a Python constructor that has no corresponding C++ constructor. This annotation is used to suppress the generation of the constructor in the derived class. .. function-annotation:: NoKeywordArgs .. versionadded:: 4.10 .. 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:: 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:: 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 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` .. _ref-variable-annos: Variable Annotations -------------------- .. variable-annotation:: DocType .. versionadded:: 4.10 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:: 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` sip-4.15.5/doc/html/_sources/build_system.txt0000644000076500000240000007465112266235021021273 0ustar philstaff00000000000000.. _ref-build-system: The Build System ================ .. module:: sipconfig The purpose of the build system is to make it easy for you to write configuration scripts in Python for your own bindings. The build system takes care of the details of particular combinations of platform and compiler. It supports over 50 different platform/compiler combinations. The build system is implemented as a pure Python module called :mod:`sipconfig` that contains a number of classes and functions. Using this module you can write bespoke configuration scripts (e.g. PyQt's ``configure.py``) or use it with other Python based build systems (e.g. `Distutils `_ 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 PyQt but all three packages are maintained by different developers. To make this easier PyQt includes its own configuration module, ``pyqtconfig``, that contains additional classes intended to be used by the configuration scripts of bindings built on top of PyQt. The SIP build system includes facilities that do a lot of the work of creating these additional configuration modules. .. function:: create_config_module(module, template, content[, macros=None]) This creates a configuration module (e.g. ``pyqtconfig``) from a template file and a string. :param module: the name of the configuration module file to create. :param template: the name of the template file. :param content: a string which replaces every occurence of the pattern ``@SIP_CONFIGURATION@`` in the template file. The content string is usually created from a Python dictionary using :func:`sipconfig.create_content()`. *content* may also be a dictionary, in which case :func:`sipconfig.create_content()` is automatically called to convert it to a string. :param macros: an optional dictionary of platform specific build macros. It is only used if :func:`sipconfig.create_content()` is called automatically to convert a *content* dictionary to a string. .. function:: create_content(dict[, macros=None]) -> string This converts a Python dictionary to a string that can be parsed by the Python interpreter and converted back to an equivalent dictionary. It is typically used to generate the content string for :func:`sipconfig.create_config_module()`. :param dict: the Python dictionary to convert. :param macros: the optional dictionary of platform specific build macros. :return: the string representation of the dictionary. .. function:: create_wrapper(script, wrapper[, gui=0[, use_arch='']]) -> string This creates a platform dependent executable wrapper around a Python script. :param script: the full pathname of the script. :param wrapper: the full pathname of the wrapper to create, excluding any platform specific extension. :param gui: is non-zero if a GUI enabled version of the interpreter should be used on platforms that require it. :param use_arch: is the MacOS/X 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 snapshot is indicated by a negative version number.) :param tags: the dictionary of SIP version tags keyed by the corresponding C/C++ library version number. The tag used is the one with the smallest key (i.e. earliest version) that is greater than *version*. :param description: a descriptive name of the C/C++ library used in error messages. :return: the SIP version tag. :func:`sipconfig.error()` is called if the C/C++ library version number did not correspond to a SIP version tag. .. function:: version_to_string(v) -> string This converts a 3 part version number encoded as a hexadecimal value to a string. :param v: the version number. :return: a string. .. class:: Configuration This class encapsulates configuration values that can be accessed as instance objects. A sub-class may provide a dictionary of additional configuration values in its constructor the elements of which will have precedence over the super-class's values. The following configuration values are provided: .. attribute:: default_bin_dir The name of the directory where executables should be installed by default. .. attribute:: default_mod_dir The name of the directory where SIP generated modules should be installed by default. .. attribute:: default_sip_dir The name of the base directory where the ``.sip`` files for SIP generated modules should be installed by default. A sub-directory with the same name as the module should be created and its ``.sip`` files should be installed in the sub-directory. The ``.sip`` files only need to be installed if you might want to build other bindings based on them. .. attribute:: platform The name of the platform/compiler for which the build system has been configured for. .. attribute:: py_conf_inc_dir The name of the directory containing the ``pyconfig.h`` header file. .. attribute:: py_inc_dir The name of the directory containing the ``Python.h`` header file. .. attribute:: py_lib_dir The name of the directory containing the Python interpreter library. .. attribute:: py_version The Python version as a 3 part hexadecimal number (e.g. v2.3.3 is represented as ``0x020303``). .. attribute:: sip_bin The full pathname of the SIP executable. .. attribute:: sip_config_args The command line passed to ``configure.py`` when SIP was configured. .. attribute:: sip_inc_dir The name of the directory containing the ``sip.h`` header file. .. attribute:: sip_mod_dir The name of the directory containing the SIP module. .. attribute:: sip_version The SIP version as a 3 part hexadecimal number (e.g. v4.0.0 is represented as ``0x040000``). .. attribute:: sip_version_str The SIP version as a string. For development snapshots it will start with ``snapshot-``. .. attribute:: universal The name of the MacOS/X SDK used when creating universal binaries. .. attribute:: arch The space separated MacOS/X architectures to build. .. 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:: 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 (see :ref:`ref-builtin`). :param console: see :meth:`sipconfig.Makefile.__init__`. :param qt: see :meth:`sipconfig.Makefile.__init__`. :param opengl: see :meth:`sipconfig.Makefile.__init__`. :param threaded: see :meth:`sipconfig.Makefile.__init__`. :param warnings: see :meth:`sipconfig.Makefile.__init__`. :param debug: see :meth:`sipconfig.Makefile.__init__`. :param dir: see :meth:`sipconfig.Makefile.__init__`. :param makefile: see :meth:`sipconfig.Makefile.__init__`. :param installs: see :meth:`sipconfig.Makefile.__init__`. :param strip: is set if the module should be stripped of unneeded symbols after installation. It is ignored if either *debug* or *static* is set, or if the platform doesn't support it. :param export_all: is set if all of the module's symbols should be exported rather than just the module's initialisation function. Exporting all symbols increases the size of the module and slows down module load times but may avoid problems with modules that use C++ exceptions. All symbols are exported if either *debug* or *static* is set, or if the platform doesn't support it. :param universal: see :meth:`sipconfig.Makefile.__init__`. :param arch: see :meth:`sipconfig.Makefile.__init__`. :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.15.5/doc/html/_sources/builtin.txt0000644000076500000240000000467511673627050020245 0ustar philstaff00000000000000.. _ref-builtin: Builtin Modules and Custom Interpreters ======================================= Sometimes you want to create a custom Python interpreter with some modules built in to the interpreter itself rather than being dynamically loaded. To do this the module must be created as a static library and linked with a custom stub and the normal Python library. To build the SIP module as a static library you must pass the ``-k`` command line option to ``configure.py``. You should then build and install SIP as normal. (Note that, because the module is now a static library, you will not be able to import it.) To build a module you have created for your own library you must modify your own configuration script to pass a non-zero value as the ``static`` argument of the ``__init__()`` method of the :class:`sipconfig.ModuleMakefile` class (or any derived class you have created). Normally you would make this configurable using a command line option in the same way that SIP's ``configure.py`` handles it. The next stage is to create a custom stub and a Makefile. The SIP distribution contains a directory called ``custom`` which contains example stubs and a Python script that will create a correct Makefile. Note that, if your copy of SIP was part of a standard Linux distribution, the ``custom`` directory may not be installed on your system. The ``custom`` directory contains the following files. They are provided as examples - each needs to be modified according to your particular requirements. - ``mkcustom.py`` is a Python script that will create a Makefile which is then used to build the custom interpreter. Comments in the file describe how it should be modified. - ``custom.c`` is a stub for a custom interpreter on Linux/UNIX. It should also be used for a custom console interpreter on Windows (i.e. like ``python.exe``). Comments in the file describe how it should be modified. - ``customw.c`` is a stub for a custom GUI interpreter on Windows (i.e. like ``pythonw.exe``). Comments in the file describe how it should be modified. Note that this technique does not restrict how the interpreter can be used. For example, it still allows users to write their own applications that can import your builtin modules. If you want to prevent users from doing that, perhaps to protect a proprietary API, then take a look at the `VendorID `__ package. sip-4.15.5/doc/html/_sources/c_api.txt0000644000076500000240000021761012254035112017631 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_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_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_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. v4.0.0 is represented as ``0x040000``). .. c:macro:: SIP_VERSION_STR This is a C preprocessor symbol that defines the SIP version number represented as a string. For development snapshots it will start with ``snapshot-``. .. 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: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) 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: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 an instance of the corresponding generated Python type. :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. :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:: 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: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 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 C/C++ enum. :param type: the C/C++ declaration of the enum. :return: the generated Python type object. This will not change and may be saved in a static cache. ``NULL`` is returned if the C/C++ enum doesn't exist. .. 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:: 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:: 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:: 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:: unsigned long sipLong_AsUnsignedLong(PyObject *obj) This function is a thin wrapper around :c:func:`PyLong_AsUnsignedLong()` that works around a bug in Python v2.3.x and earlier when converting integer objects. .. 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: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:: 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 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: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. .. 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`. .. 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: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(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 named enum. :param td: the type structure. :return: a non-zero value if the type structure refers to an 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:: 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: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. .. 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``). .. c:var:: PyTypeObject *sipWrapperType_Type This is the type of a :c:type:`sipWrapperType` structure and is the C implementation of :class:`sip.wrappertype`. .. _ref-type-structures: Generated Type Structures ------------------------- SIP generates an opaque type structure for each C structure, C++ class, C++ namespace, named enum or mapped type being wrapped. These are :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 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.15.5/doc/html/_sources/command_line.txt0000644000076500000240000001174312125131242021200 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 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:: -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:: -e Support for C++ exceptions is enabled. This causes all calls to C++ code to be enclosed in ``try``/``catch`` blocks and C++ exceptions to be converted to Python exceptions. By default exception support is disabled. .. cmdoption:: -g The Python GIL is released before making any calls to the C/C++ library being wrapped and reacquired afterwards. See :ref:`ref-gil` and the :fanno:`ReleaseGIL` and :fanno:`HoldGIL` annotations. .. cmdoption:: -I 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 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:: -z The name of a file containing more command line options. sip-4.15.5/doc/html/_sources/directives.txt0000644000076500000240000023757112261240532020731 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 following variables are made available to the handwritten code: Py_buffer \*sipBuffer This is a pointer to the Python buffer structure that the handwritten code must populate. *type* \*sipCpp This is a pointer to the structure or class instance. Its *type* is a pointer to the structure or class. int sipFlags These are the flags that specify what elements of the ``sipBuffer`` structure must be populated. int sipRes The handwritten code should set this to 0 if there was no error or -1 if there was an error. PyObject \*sipSelf This is the Python object that wraps the structure or class instance, i.e. ``self``. .. directive:: %BIGetCharBufferCode .. parsed-literal:: %BIGetCharBufferCode *code* %End This directive (along with :directive:`%BIGetReadBufferCode`, :directive:`%BIGetSegCountCode` and :directive:`%BIGetWriteBufferCode`) is used to specify code that implements the buffer interface of Python v2. If Python v3 is being used then this is ignored. The following variables are made available to the handwritten code: *type* \*sipCpp This is a pointer to the structure or class instance. Its *type* is a pointer to the structure or class. void \*\*sipPtrPtr This is the pointer used to return the address of the character buffer. :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 following variables are made available to the handwritten code: Py_buffer \*sipBuffer This is a pointer to the Python buffer structure. *type* \*sipCpp This is a pointer to the structure or class instance. Its *type* is a pointer to the structure or class. PyObject \*sipSelf This is the Python object that wraps the structure or class instance, i.e. ``self``. .. directive:: %CModule .. 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 .. 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) 2014 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:: %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"]) *text* %End This directive is used to specify explicit docstrings for modules, classes, functions, methods 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. Specifying an explicit docstring will prevent SIP from generating an automatic docstring that describes the Python signature of a function or method overload. This means that SIP will generate less informative exceptions (i.e. without a full signature) when it fails to match a set of arguments to any function or method overload. .. versionadded:: 4.13 The format may either be ``"raw"`` or ``"deindented"``. If it is not specified then the value specified by any :directive:`%DefaultDocstringFormat` directive is used. If the format is ``"raw"`` then the docstring is used as it appears in the specification file. If the format is ``"deindented"`` then any leading spaces common to all non-blank lines of the docstring are removed. 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 }; .. 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:: %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 disable. 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 one 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:: %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]] [, 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. ``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. 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:: %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. By default all versions are disabled. The SIP :option:`-t ` command line option is used to enable a version. 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:: %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:: %VirtualCatcherCode .. parsed-literal:: %VirtualCatcherCode *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 Python reimplementation and the handling of any returned results. It is usually used to handle argument types and results that SIP cannot deal with automatically. This directive can also be used in the context of a class destructor to specify handwritten code that is embedded in-line in the internal derived class's destructor. In the context of a method the Python Global Interpreter Lock (GIL) is automatically acquired before the specified code is executed and automatically released afterwards. In the context of a destructor the specified code must handle the GIL. The GIL must be acquired before any calls to the Python API and released after the last call as shown in this example fragment:: SIP_BLOCK_THREADS Py_DECREF(obj); SIP_UNBLOCK_THREADS The following variables are made available to the handwritten code in the context of a method: *type* a0 There is a variable for each argument of the C++ signature named ``a0``, ``a1``, etc. 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 the result to be returned. The *type* of the variable is the same as the type defined in the C++ signature in the specification. int sipResKey This variable is only made available if the result has a type where it is important to ensure that the corresponding Python object is not garbage collected too soon. This only applies to ``'\0'`` terminated strings. The variable would normally be passed to :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.15.5/doc/html/_sources/distutils.txt0000644000076500000240000000270212163400134020573 0ustar philstaff00000000000000.. _ref-distutils: Building Your Extension with distutils ====================================== To build the example in :ref:`ref-simple-c++-example` using distutils, it is sufficient to create a standard ``setup.py``, listing ``word.sip`` among the files to build, and hook-up SIP into distutils:: from distutils.core import setup, Extension import sipdistutils setup( name = 'word', versione = '1.0', ext_modules=[ Extension("word", ["word.sip", "word.cpp"]), ], cmdclass = {'build_ext': sipdistutils.build_ext} ) As we can see, the above is a normal distutils setup script, with just a special line which is needed so that SIP can see and process ``word.sip``. Then, running ``setup.py build`` will build our extension module. If you want to use any of sip's command-line options described in :ref:`ref-command-line`, there is a new option available for the ``build_ext`` command in distutils: ``--sip-opts``. So you can either invoke distutils as follows:: $ python setup.py build_ext --sip-opts="-e -g" build or you can leverage distutils' config file support by creating a ``setup.cfg`` file in the supported system or local paths (eg: in the same directory of ``setup.py``) with these contents:: [build_ext] sip-opts = -e -g and then run ``setup.py build`` as usual. If ``sip-opts`` has not been specified then any ``swig_opts`` defined when creating the ``Extension`` will be used. sip-4.15.5/doc/html/_sources/embedding.txt0000644000076500000240000000520312125131242020463 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.15.5/doc/html/_sources/incompatibilities.txt0000644000076500000240000001451612227760566022310 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.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 :option:`-a` command line option to :file:`configure.py` has been removed. Removal of PyQt-specific Features ********************************* The following PyQt-specific support functions have been removed. - :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.15.5/doc/html/_sources/index.txt0000644000076500000240000000044411673627050017674 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 builtin sip-4.15.5/doc/html/_sources/installation.txt0000644000076500000240000001400212227760566021267 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 ``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:\python32\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:: -d , --destdir The 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 SIP module will be built as a static library. This is useful when building the SIP module as a Python builtin (see :ref:`ref-builtin`). .. cmdoption:: -n, --universal The SIP code generator and module will be built as universal binaries under MacOS/X. If the :option:`--arch ` option has not been specified then the universal binary will include the ``i386`` and ``ppc`` architectures. .. 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:: -u, --debug The 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 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 SIP module. The ``configure.py`` script takes many other options that allows the build system to be finely tuned. These are of the form ``name=value`` or ``name+=value``. The :option:`--show-build-macros ` option will display each supported ``name``, although not all are applicable to all platforms. The ``name=value`` form means that ``value`` will replace the existing value of ``name``. The ``name+=value`` form means that ``value`` will be appended to the existing value of ``name``. For example, the following will disable support for C++ exceptions (and so reduce the size of module binaries) when used with GCC:: python configure.py CXXFLAGS+=-fno-exceptions A pure Python module called ``sipconfig.py`` is generated by ``configure.py``. This defines each ``name`` and its corresponding ``value``. Looking at it will give you a good idea of how the build system uses the different options. It is covered in detail in :ref:`ref-build-system`. Configuring for MinGW ********************* SIP, and the modules it generates, can be built with MinGW, the Windows port of GCC. You must use the :option:`--platform ` command line option to specify the correct platform. For example:: c:\python32\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:\python32\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 python32.lib python32_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. sip-4.15.5/doc/html/_sources/introduction.txt0000644000076500000240000001565112310606636021310 0ustar philstaff00000000000000Introduction ============ This is the reference guide for SIP 4.15.5. 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 - the ability to include documentation in the specification files which can be extracted and subsequently processed by external tools - the ability to include copyright notices and licensing information in the specification files that is automatically included in all generated source code - a build system, written in Python, that you can extend to configure, compile and install your own bindings without worrying about platform specific issues - support for building your extensions using distutils - SIP, and the bindings it produces, runs under UNIX, Linux, Windows and MacOS/X SIP Components -------------- SIP comprises a number of different components. - The SIP code generator (:program:`sip`). This processes :file:`.sip` specification files and generates C or C++ bindings. It is covered in detail in :ref:`ref-using`. - The SIP header file (:file:`sip.h`). This contains definitions and data structures needed by the generated C and C++ code. - The SIP module (:file:`sip.so` or :file:`sip.pyd`). This is a Python extension module that is imported automatically by SIP generated bindings and provides them with some common utility functions. See also :ref:`ref-python-api`. - The SIP build system (:file:`sipconfig.py`). This is a pure Python module that is created when SIP is configured and encapsulates all the necessary information about your system including relevant directory names, compiler and linker flags, and version numbers. It also includes several Python classes and functions which help you write configuration scripts for your own bindings. It is covered in detail in :ref:`ref-build-system`. - The SIP distutils extension (:file:`sipdistutils.py`). This is a distutils extension that can be used to build your extension modules using distutils and is an alternative to writing configuration scripts with the SIP build system. This can be as simple as adding your .sip files to the list of files needed to build the extension module. It is covered in detail in :ref:`ref-distutils`. 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.15.5/doc/html/_sources/python_api.txt0000644000076500000240000002744112227760566020753 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. .. 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. :param type: the Python type object. :param enable: is ``True`` if auto-conversion should be enabled for the type. This is the default behaviour. :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:: 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 This is a Python integer object that represents the SIP version number as a 3 part hexadecimal number (e.g. v4.0.0 is represented as ``0x040000``). It was first implemented in SIP v4.2. .. data:: SIP_VERSION_STR This is a Python string object that defines the SIP version number as represented as a string. For development snapshots it will start with ``snapshot-``. It was first implemented in SIP v4.3. .. function:: transferback(obj) This function is a wrapper around :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:: 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.15.5/doc/html/_sources/specification_files.txt0000644000076500000240000004773412163400134022567 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:`%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:`%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**] [*exceptions*] [**= 0**] [*function-annotations*] [*c++-signature*] **;** [:directive:`%Docstring`] [:directive:`%MethodCode`] *c++-signature* ::= **[** *type* **(** [*argument-list*] **)]** *static-method* ::= **static** *function* *virtual-method* ::= [**Q_SIGNAL**] [**Q_SLOT**] **virtual** *type* *name* **(** [*argument-list*] **)** [**const**] [*exceptions*] [**= 0**] [*function-annotations*] [*c++-signature*] **;** [:directive:`%MethodCode`] [:directive:`%VirtualCatcherCode`] *special-method* ::= *type* *special-method-name* **(** [*argument-list*] **)** [*function-annotations*] **;** [:directive:`%MethodCode`] *special-method-name* ::= [**__abs__** | **__add__** | **__and__** | **__bool__** | **__call__** | **__cmp__** | **__contains__** | **__delattr__** | **__delitem__** | **__div__** | **__eq__** | **__float__** | **__floordiv__** | **__ge__** | **__getattr__** | **__getattribute__** | **__getitem__** | **__gt__** | **__hash__** | **__iadd__** | **__iand__** | **__idiv__** | **__ifloordiv__** | **__ilshift__** | **__imod__** | **__imul__** | **__index__** | **__int__** | **__invert__** | **__ior__** | **__irshift__** | **__isub__** | **__iter__** | **__itruediv__** | **__ixor__** | **__le__** | **__len__** | **__long__** | **__lshift__** | **__lt__** | **__mod__** | **__mul__** | **__ne__** | **__neg__** | **__next__** | **__nonzero__** | **__or__** | **__pos__** | **__repr__** | **__rshift__** | **__setattr__** | **__setitem__** | **__str__** | **__sub__** | **__truediv__** | **__xor__**] *operator* ::= *operator-type* **(** [*argument-list*] **)** [**const**] [*exceptions*] [*function-annotations*] **;** [:directive:`%MethodCode`] *virtual-operator* ::= **virtual** *operator-type* **(** [*argument-list*] **)** [**const**] [*exceptions*] [**= 0**] [*function-annotations*] **;** [:directive:`%MethodCode`] [:directive:`%VirtualCatcherCode`] *operatator-type* ::= [ *operator-function* | *operator-cast* ] *operator-function* ::= *type* **operator** *operator-name* *operator-cast* ::= **operator** *type* *operator-name* ::= [**+** | **-** | ***** | **/** | **%** | **&** | **|** | **^** | **<<** | **>>** | **+=** | **-=** | ***=** | **/=** | **%=** | **&=** | **|=** | **^=** | **<<=** | **>>=** | **~** | **()** | **[]** | **<** | **<=** | **==** | **!=** | **>** | **>>=** | **=**] *class-variable* ::= [**static**] *variable* *class-template* :: = **template** **<** *type-list* **>** *class* *mapped-type-template* :: = **template** **<** *type-list* **>** :directive:`%MappedType` *enum* ::= **enum** [*name*] [*enum-annotations*] **{** {*enum-line*} **};** *enum-line* ::= [:directive:`%If` | *name* [*enum-annotations*] **,** *function* ::= *type* *name* **(** [*argument-list*] **)** [*exceptions*] [*function-annotations*] **;** [:directive:`%Docstring`] [:directive:`%MethodCode`] *namespace* ::= **namespace** *name* [**{** {*namespace-line*} **}**] **;** *namespace-line* ::= [:directive:`%TypeHeaderCode` | *statement*] *opaque-class* ::= **class** *scoped-name* **;** *struct* ::= **struct** *name* **{** {*class-line*} **};** *typedef* ::= **typedef** [*typed-name* | *function-pointer*] *typedef-annotations* **;** *variable*::= *typed-name* [*variable-annotations*] **;** [:directive:`%AccessCode`] [:directive:`%GetCode`] [:directive:`%SetCode`] *exception* ::= :directive:`%Exception` *exception-name* [*exception-base*] **{** [:directive:`%TypeHeaderCode`] :directive:`%RaiseCode` **};** *exception-name* ::= *scoped-name* *exception-base* ::= **(** [*exception-name* | *python-exception*] **)** *python-exception* ::= [**SIP_Exception** | **SIP_StopIteration** | **SIP_StandardError** | **SIP_ArithmeticError** | **SIP_LookupError** | **SIP_AssertionError** | **SIP_AttributeError** | **SIP_EOFError** | **SIP_FloatingPointError** | **SIP_EnvironmentError** | **SIP_IOError** | **SIP_OSError** | **SIP_ImportError** | **SIP_IndexError** | **SIP_KeyError** | **SIP_KeyboardInterrupt** | **SIP_MemoryError** | **SIP_NameError** | **SIP_OverflowError** | **SIP_RuntimeError** | **SIP_NotImplementedError** | **SIP_SyntaxError** | **SIP_IndentationError** | **SIP_TabError** | **SIP_ReferenceError** | **SIP_SystemError** | **SIP_SystemExit** | **SIP_TypeError** | **SIP_UnboundLocalError** | **SIP_UnicodeError** | **SIP_UnicodeEncodeError** | **SIP_UnicodeDecodeError** | **SIP_UnicodeTranslateError** | **SIP_ValueError** | **SIP_ZeroDivisionError** | **SIP_WindowsError** | **SIP_VMSError**] *exceptions* ::= **throw (** [*exception-list*] **)** *exception-list* ::= *scoped-name* [**,** *exception-list*] *argument-list* ::= *argument* [**,** *argument-list*] [**,** **...**] *argument* ::= [ *type* [*name*] [*argument-annotations*] [*default-value*] | :stype:`SIP_ANYSLOT` [*default-value*] | :stype:`SIP_QOBJECT` | :stype:`SIP_RXOBJ_CON` | :stype:`SIP_RXOBJ_DIS` | :stype:`SIP_SIGNAL` [*default-value*] | :stype:`SIP_SLOT` [*default-value*] | :stype:`SIP_SLOT_CON` | :stype:`SIP_SLOT_DIS` | :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. - A class's list of super-classes doesn't not include any access specifier (e.g. ``public``). Variable Numbers of Arguments ----------------------------- SIP supports the use of ``...`` as the last part of a function signature. Any remaining arguments are collected as a Python tuple. Additional SIP Types -------------------- SIP supports a number of additional data types that can be used in Python signatures. .. sip-type:: SIP_ANYSLOT This is both a ``const char *`` and a ``PyObject *`` that is used as the type of the member instead of ``const char *`` in functions that implement the connection or disconnection of an explicitly generated signal to a slot. Handwritten code must be provided to interpret the conversion correctly. .. sip-type:: SIP_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 This is a ``QObject *`` that is a C++ instance of a class derived from Qt's ``QObject`` class. .. sip-type:: SIP_RXOBJ_CON This is a ``QObject *`` that is a C++ instance of a class derived from Qt's ``QObject`` class. It is used as the type of the receiver instead of ``const QObject *`` in functions that implement a connection to a slot. .. sip-type:: SIP_RXOBJ_DIS This is a ``QObject *`` that is a C++ instance of a class derived from Qt's ``QObject`` class. It is used as the type of the receiver instead of ``const QObject *`` in functions that implement a disconnection from a slot. .. sip-type:: SIP_SIGNAL This is a ``const char *`` that is used as the type of the signal instead of ``const char *`` in functions that implement the connection or disconnection of an explicitly generated signal to a slot. .. sip-type:: SIP_SLOT This is a ``const char *`` that is used as the type of the member instead of ``const char *`` in functions that implement the connection or disconnection of an explicitly generated signal to a slot. .. sip-type:: SIP_SLOT_CON This is a ``const char *`` that is used as the type of the member instead of ``const char *`` in functions that implement the connection of an internally generated signal to a slot. The type includes a comma separated list of types that is the C++ signature of of the signal. To take an example, ``QAccel::connectItem()`` connects an internally generated signal to a slot. The signal is emitted when the keyboard accelerator is activated and it has a single integer argument that is the ID of the accelerator. The C++ signature is:: bool connectItem(int id, const QObject *receiver, const char *member); The corresponding SIP specification is:: bool connectItem(int, SIP_RXOBJ_CON, SIP_SLOT_CON(int)); .. sip-type:: SIP_SLOT_DIS This is a ``const char *`` that is used as the type of the member instead of ``const char *`` in functions that implement the disconnection of an internally generated signal to a slot. The type includes a comma separated list of types that is the C++ signature of of the signal. .. 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.15.5/doc/html/_sources/using.txt0000644000076500000240000006424512125131242017705 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 PyQt. The build system will take care of finding the file's exact location. - The :directive:`%If` directive has been added to specify that everything [#]_ up to the matching :directive:`%End` directive only applies to Qt v4.2 and later. ``Qt_4_2_0`` is a *tag* defined in ``QtCoremod.sip`` [#]_ using the :directive:`%Timeline` directive. :directive:`%Timeline` is used to define a tag for each version of a library's API you are wrapping allowing you to maintain all the different versions in a single SIP specification. The build system provides support to ``configure.py`` scripts for working out the correct tags to use according to which version of the library is actually installed. - The :aanno:`TransferThis` annotation has been added to the constructor's argument. It specifies that if the argument is not 0 (i.e. the ``Hello`` instance being constructed has a parent) then ownership of the instance is transferred from Python to C++. It is needed because Qt maintains objects (i.e. instances derived from the ``QObject`` class) in a hierachy. When an object is destroyed all of its children are also automatically destroyed. It is important, therefore, that the Python garbage collector doesn't also try and destroy them. This is covered in more detail in :ref:`ref-object-ownership`. SIP provides many other annotations that can be applied to arguments, functions and classes. Multiple annotations are separated by commas. Annotations may have values. - The ``=`` operator has been removed. This operator is not supported by SIP. - The :directive:`%If` directive has been added to specify that everything up to the matching :directive:`%End` directive does not apply to Windows. ``WS_WIN`` is another tag defined by PyQt, this time using the :directive:`%Platforms` directive. Tags defined by the :directive:`%Platforms` directive are mutually exclusive, i.e. only one may be valid at a time [#]_. One question you might have at this point is why bother to define the private copy constructor when it can never be called from Python? The answer is to prevent the automatic generation of a public copy constructor. We now look at the ``configure.py`` script. This is a little different to the script in the previous examples for two related reasons. Firstly, PyQt includes a pure Python module called ``pyqtconfig`` that extends the SIP build system for modules, like our example, that build on top of PyQt. It deals with the details of which version of Qt is being used (i.e. it determines what the correct tags are) and where it is installed. This is called a module's configuration module. Secondly, we generate a configuration module (called ``helloconfig``) for our own ``hello`` module. There is no need to do this, but if there is a chance that somebody else might want to extend your C++ library then it would make life easier for them. Now we have two scripts. First the ``configure.py`` script:: import os import sipconfig from PyQt4 import pyqtconfig # The name of the SIP build file generated by SIP and used by the build # system. build_file = "hello.sbf" # Get the PyQt configuration information. config = pyqtconfig.Configuration() # Get the extra SIP flags needed by the imported PyQt modules. Note that # this normally only includes those flags (-x and -t) that relate to SIP's # versioning system. pyqt_sip_flags = config.pyqt_sip_flags # Run SIP to generate the code. Note that we tell SIP where to find the qt # module's specification files using the -I flag. os.system(" ".join([config.sip_bin, "-c", ".", "-b", build_file, "-I", config.pyqt_sip_dir, pyqt_sip_flags, "hello.sip"])) # We are going to install the SIP specification file for this module and # its configuration module. installs = [] installs.append(["hello.sip", os.path.join(config.default_sip_dir, "hello")]) installs.append(["helloconfig.py", config.default_mod_dir]) # Create the Makefile. The QtGuiModuleMakefile class provided by the # pyqtconfig module takes care of all the extra preprocessor, compiler and # linker flags needed by the Qt library. makefile = pyqtconfig.QtGuiModuleMakefile( configuration=config, build_file=build_file, installs=installs ) # Add the library we are wrapping. The name doesn't include any platform # specific prefixes or extensions (e.g. the "lib" prefix on UNIX, or the # ".dll" extension on Windows). makefile.extra_libs = ["hello"] # Generate the Makefile itself. makefile.generate() # Now we create the configuration module. This is done by merging a Python # dictionary (whose values are normally determined dynamically) with a # (static) template. content = { # Publish where the SIP specifications for this module will be # installed. "hello_sip_dir": config.default_sip_dir, # Publish the set of SIP flags needed by this module. As these are the # same flags needed by the qt module we could leave it out, but this # allows us to change the flags at a later date without breaking # scripts that import the configuration module. "hello_sip_flags": pyqt_sip_flags } # This creates the helloconfig.py module from the helloconfig.py.in # template and the dictionary. sipconfig.create_config_module("helloconfig.py", "helloconfig.py.in", content) Next we have the ``helloconfig.py.in`` template script:: from PyQt4 import pyqtconfig # These are installation specific values created when Hello was configured. # The following line will be replaced when this template is used to create # the final configuration module. # @SIP_CONFIGURATION@ class Configuration(pyqtconfig.Configuration): """The class that represents Hello configuration values. """ def __init__(self, sub_cfg=None): """Initialise an instance of the class. sub_cfg is the list of sub-class configurations. It should be None when called normally. """ # This is all standard code to be copied verbatim except for the # name of the module containing the super-class. if sub_cfg: cfg = sub_cfg else: cfg = [] cfg.append(_pkg_config) pyqtconfig.Configuration.__init__(self, cfg) class HelloModuleMakefile(pyqtconfig.QtGuiModuleMakefile): """The Makefile class for modules that %Import hello. """ def finalise(self): """Finalise the macros. """ # Make sure our C++ library is linked. self.extra_libs.append("hello") # Let the super-class do what it needs to. pyqtconfig.QtGuiModuleMakefile.finalise(self) Again, we hope that the scripts are self documenting. .. [#] Some parts of a SIP specification aren't subject to version control. .. [#] Actually in ``versions.sip``. PyQt uses the :directive:`%Include` directive to split the SIP specification for Qt across a large number of separate ``.sip`` files. .. [#] Tags can also be defined by the :directive:`%Feature` directive. These tags are not mutually exclusive, i.e. any number may be valid at a time. .. _ref-object-ownership: Ownership of Objects -------------------- When a C++ instance is wrapped a corresponding Python object is created. The Python object behaves as you would expect in regard to garbage collection - it is garbage collected when its reference count reaches zero. What then happens to the corresponding C++ instance? The obvious answer might be that the instance's destructor is called. However the library API may say that when the instance is passed to a particular function, the library takes ownership of the instance, i.e. responsibility for calling the instance's destructor is transferred from the SIP generated module to the library. Ownership of an instance may also be associated with another instance. The implication being that the owned instance will automatically be destroyed if the owning instance is destroyed. SIP keeps track of these relationships to ensure that Python's cyclic garbage collector can detect and break any reference cycles between the owning and owned instances. The association is implemented as the owning instance taking a reference to the owned instance. The TransferThis, Transfer and TransferBack annotations are used to specify where, and it what direction, transfers of ownership happen. It is very important that these are specified correctly to avoid crashes (where both Python and C++ call the destructor) and memory leaks (where neither Python and C++ call the destructor). This applies equally to C structures where the structure is returned to the heap using the ``free()`` function. See also :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. .. _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. 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 than function or method returns. - When a wide string or array is returned from a virtual method then SIP does not free the memory until the next time the method is called. - When an assignment is made to a wide string or array instance variable then SIP does not first free the instance's current string or array. .. _ref-gil: The Python Global Interpreter Lock ---------------------------------- Python's Global Interpretor Lock (GIL) must be acquired before calls can be made to the Python API. It should also be released when a potentially blocking call to C/C++ library is made in order to allow other Python threads to be executed. In addition, some C/C++ libraries may implement their own locking strategies that conflict with the GIL causing application deadlocks. SIP provides ways of specifying when the GIL is released and acquired to ensure that locking problems can be avoided. SIP always ensures that the GIL is acquired before making calls to the Python API. By default SIP does not release the GIL when making calls to the C/C++ library being wrapped. The :fanno:`ReleaseGIL` annotation can be used to override this behaviour when required. If SIP is given the :option:`-g ` 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 PyQt3 and PyQt4 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. sip-4.15.5/doc/html/_static/0000755000076500000240000000000012310606653015621 5ustar philstaff00000000000000sip-4.15.5/doc/html/_static/ajax-loader.gif0000644000076500000240000000124112307277337020506 0ustar philstaff00000000000000GIF89aU|NU|l!Created with ajaxload.info! ! NETSCAPE2.0,30Ikc:Nf E1º.`q-[9ݦ9 JkH! ,4N!  DqBQT`1 `LE[|ua C%$*! ,62#+AȐ̔V/cNIBap ̳ƨ+Y2d! ,3b%+2V_ ! 1DaFbR]=08,Ȥr9L! ,2r'+JdL &v`\bThYB)@<&,ȤR! ,3 9tڞ0!.BW1  sa50 m)J! ,2 ٜU]qp`a4AF0` @1Α! ,20IeBԜ) q10ʰPaVڥ ub[;sip-4.15.5/doc/html/_static/basic.css0000644000076500000240000002040412310606653017414 0ustar philstaff00000000000000/* * basic.css * ~~~~~~~~~ * * Sphinx stylesheet -- basic theme. * * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ /* -- main layout ----------------------------------------------------------- */ div.clearer { clear: both; } /* -- relbar ---------------------------------------------------------------- */ div.related { width: 100%; font-size: 90%; } div.related h3 { display: none; } div.related ul { margin: 0; padding: 0 0 0 10px; list-style: none; } div.related li { display: inline; } div.related li.right { float: right; margin-right: 5px; } /* -- sidebar --------------------------------------------------------------- */ div.sphinxsidebarwrapper { padding: 10px 5px 0 10px; } div.sphinxsidebar { float: left; width: 230px; margin-left: -100%; font-size: 90%; } div.sphinxsidebar ul { list-style: none; } div.sphinxsidebar ul ul, div.sphinxsidebar ul.want-points { margin-left: 20px; list-style: square; } div.sphinxsidebar ul ul { margin-top: 0; margin-bottom: 0; } div.sphinxsidebar form { margin-top: 10px; } div.sphinxsidebar input { border: 1px solid #98dbcc; font-family: sans-serif; font-size: 1em; } div.sphinxsidebar #searchbox input[type="text"] { width: 170px; } div.sphinxsidebar #searchbox input[type="submit"] { width: 30px; } img { border: 0; max-width: 100%; } /* -- search page ----------------------------------------------------------- */ ul.search { margin: 10px 0 0 20px; padding: 0; } ul.search li { padding: 5px 0 5px 20px; background-image: url(file.png); background-repeat: no-repeat; background-position: 0 7px; } ul.search li a { font-weight: bold; } ul.search li div.context { color: #888; margin: 2px 0 0 30px; text-align: left; } ul.keywordmatches li.goodmatch a { font-weight: bold; } /* -- index page ------------------------------------------------------------ */ table.contentstable { width: 90%; } table.contentstable p.biglink { line-height: 150%; } a.biglink { font-size: 1.3em; } span.linkdescr { font-style: italic; padding-top: 5px; font-size: 90%; } /* -- general index --------------------------------------------------------- */ table.indextable { width: 100%; } table.indextable td { text-align: left; vertical-align: top; } table.indextable dl, table.indextable dd { margin-top: 0; margin-bottom: 0; } table.indextable tr.pcap { height: 10px; } table.indextable tr.cap { margin-top: 10px; background-color: #f2f2f2; } img.toggler { margin-right: 3px; margin-top: 3px; cursor: pointer; } div.modindex-jumpbox { border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; margin: 1em 0 1em 0; padding: 0.4em; } div.genindex-jumpbox { border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; margin: 1em 0 1em 0; padding: 0.4em; } /* -- general body styles --------------------------------------------------- */ a.headerlink { visibility: hidden; } h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, h4:hover > a.headerlink, h5:hover > a.headerlink, h6:hover > a.headerlink, dt:hover > a.headerlink { visibility: visible; } div.body p.caption { text-align: inherit; } div.body td { text-align: left; } .field-list ul { padding-left: 1em; } .first { margin-top: 0 !important; } p.rubric { margin-top: 30px; font-weight: bold; } img.align-left, .figure.align-left, object.align-left { clear: left; float: left; margin-right: 1em; } img.align-right, .figure.align-right, object.align-right { clear: right; float: right; margin-left: 1em; } img.align-center, .figure.align-center, object.align-center { display: block; margin-left: auto; margin-right: auto; } .align-left { text-align: left; } .align-center { text-align: center; } .align-right { text-align: right; } /* -- sidebars -------------------------------------------------------------- */ div.sidebar { margin: 0 0 0.5em 1em; border: 1px solid #ddb; padding: 7px 7px 0 7px; background-color: #ffe; width: 40%; float: right; } p.sidebar-title { font-weight: bold; } /* -- topics ---------------------------------------------------------------- */ div.topic { border: 1px solid #ccc; padding: 7px 7px 0 7px; margin: 10px 0 10px 0; } p.topic-title { font-size: 1.1em; font-weight: bold; margin-top: 10px; } /* -- admonitions ----------------------------------------------------------- */ div.admonition { margin-top: 10px; margin-bottom: 10px; padding: 7px; } div.admonition dt { font-weight: bold; } div.admonition dl { margin-bottom: 0; } p.admonition-title { margin: 0px 10px 5px 0px; font-weight: bold; } div.body p.centered { text-align: center; margin-top: 25px; } /* -- tables ---------------------------------------------------------------- */ table.docutils { border: 0; border-collapse: collapse; } table.docutils td, table.docutils th { padding: 1px 8px 1px 5px; border-top: 0; border-left: 0; border-right: 0; border-bottom: 1px solid #aaa; } table.field-list td, table.field-list th { border: 0 !important; } table.footnote td, table.footnote th { border: 0 !important; } th { text-align: left; padding-right: 5px; } table.citation { border-left: solid 1px gray; margin-left: 1px; } table.citation td { border-bottom: none; } /* -- other body styles ----------------------------------------------------- */ ol.arabic { list-style: decimal; } ol.loweralpha { list-style: lower-alpha; } ol.upperalpha { list-style: upper-alpha; } ol.lowerroman { list-style: lower-roman; } ol.upperroman { list-style: upper-roman; } dl { margin-bottom: 15px; } dd p { margin-top: 0px; } dd ul, dd table { margin-bottom: 10px; } dd { margin-top: 3px; margin-bottom: 10px; margin-left: 30px; } dt:target, .highlighted { background-color: #fbe54e; } dl.glossary dt { font-weight: bold; font-size: 1.1em; } .field-list ul { margin: 0; padding-left: 1em; } .field-list p { margin: 0; } .optional { font-size: 1.3em; } .versionmodified { font-style: italic; } .system-message { background-color: #fda; padding: 5px; border: 3px solid red; } .footnote:target { background-color: #ffa; } .line-block { display: block; margin-top: 1em; margin-bottom: 1em; } .line-block .line-block { margin-top: 0; margin-bottom: 0; margin-left: 1.5em; } .guilabel, .menuselection { font-family: sans-serif; } .accelerator { text-decoration: underline; } .classifier { font-style: oblique; } abbr, acronym { border-bottom: dotted 1px; cursor: help; } /* -- code displays --------------------------------------------------------- */ pre { overflow: auto; overflow-y: hidden; /* fixes display issues on Chrome browsers */ } td.linenos pre { padding: 5px 0px; border: 0; background-color: transparent; color: #aaa; } table.highlighttable { margin-left: 0.5em; } table.highlighttable td { padding: 0 0.5em 0 0.5em; } tt.descname { background-color: transparent; font-weight: bold; font-size: 1.2em; } tt.descclassname { background-color: transparent; } tt.xref, a tt { background-color: transparent; font-weight: bold; } h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { background-color: transparent; } .viewcode-link { float: right; } .viewcode-back { float: right; font-family: sans-serif; } div.viewcode-block:target { margin: -1px -10px; padding: 0 10px; } /* -- math display ---------------------------------------------------------- */ img.math { vertical-align: middle; } div.body div.math p { text-align: center; } span.eqno { float: right; } /* -- printout stylesheet --------------------------------------------------- */ @media print { div.document, div.documentwrapper, div.bodywrapper { margin: 0 !important; width: 100%; } div.sphinxsidebar, div.related, div.footer, #top-link { display: none; } }sip-4.15.5/doc/html/_static/comment-bright.png0000644000076500000240000000665412307277337021272 0ustar philstaff00000000000000PNG  IHDRa OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-bKGD pHYs  tIME 6 B\<IDAT8˅Kh]es1mA`jh[-E(FEaA!bIȐ*BX"؁4)NURZ!Mhjssm؋^-\gg ]o|Ҭ[346>zd ]#8Oݺt{5uIXN!I=@Vf=v1}e>;fvnvxaHrʪJF`D¹WZ]S%S)WAb |0K=So7D~\~q-˟\aMZ,S'*} F`Nnz674U H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-bKGD pHYs  tIME!,IDAT8e_Hu?}s3y˕U2MvQ֊FE.łĊbE$DDZF5b@Q":2{n.s<_ y?mwV@tR`}Z _# _=_@ w^R%6gC-έ(K>| ${} H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-bKGD pHYs  tIME 1;VIDAT8ukU?sg4h`G1 RQܸp%Bn"bЍXJ .4V iZ##T;m!4bP~7r>ιbwc;m;oӍAΆ ζZ^/|s{;yR=9(rtVoG1w#_ө{*E&!(LVuoᲵ‘D PG4 :&~*ݳreu: S-,U^E&JY[P!RB ŖޞʖR@_ȐdBfNvHf"2T]R j'B1ddAak/DIJD D2H&L`&L $Ex,6|~_\P $MH`I=@Z||ttvgcЕWTZ'3rje"ܵx9W> mb|byfFRx{w%DZC$wdցHmWnta(M<~;9]C/_;Տ#}o`zSڷ_>:;x컓?yݩ|}~wam-/7=0S5RP"*֯ IENDB`sip-4.15.5/doc/html/_static/default.css0000644000076500000240000001015212125131242017745 0ustar philstaff00000000000000/* * The stylesheet (based on the Sphinx default). */ @import url("basic.css"); /* -- page layout ----------------------------------------------------------- */ body { font-family: 100% Verdana, Arial, Helvetica, sans-serif; font-size: 12px; background-color: white; color: black; margin: 0; padding: 0; } div.document { background-color: white; } div.documentwrapper { float: left; width: 100%; } div.bodywrapper { margin: 0 0 0 230px; } div.body { background-color: white; color: black; padding: 0 20px 30px 20px; } /* "footer" contains the copyright notice and the Sphinx link. */ div.footer { color: black; background-color: white; width: 100%; padding: 9px 0 9px 0; text-align: center; font-size: 75%; } div.footer a { color: black; text-decoration: underline; } /* "related" contains the title and the previous/next/modules/index links. */ div.related { background-color: white; line-height: 30px; color: black; } div.related a { color: #4186cb; } div.sphinxsidebar { } div.sphinxsidebar h3 { font-family: 'Trebuchet MS', sans-serif; color: black; font-size: 1.4em; font-weight: normal; margin: 0; padding: 0; } div.sphinxsidebar h3 a { color: black; } div.sphinxsidebar h4 { font-family: 'Trebuchet MS', sans-serif; color: black; font-size: 1.3em; font-weight: normal; margin: 5px 0 0 0; padding: 0; } div.sphinxsidebar p { color: black; } div.sphinxsidebar p.topless { margin: 5px 10px 10px 10px; } div.sphinxsidebar ul { margin: 10px; padding: 0; color: black; } div.sphinxsidebar a { color: #4186cb; } div.sphinxsidebar input { border: 1px solid #4186cb; font-family: sans-serif; font-size: 1em; } /* -- body styles ----------------------------------------------------------- */ a { color: #4186cb; text-decoration: none; } a:hover { text-decoration: underline; } div.body p, div.body dd, div.body li { text-align: justify; line-height: 130%; } div.body h1 { font-size: 180%; font-weight: bold; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 2px; color: white; background-color: #4186cb; padding: 5px; margin-top: 20px; -moz-border-radius: 5px; -webkit-border-radius: 5px; -khtml-border-radius: 5px; } div.body h2 { font-size: 140%; font-weight: normal; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 2px; color: white; background-color: #4186cb; padding: 5px; margin-top: 20px; -moz-border-radius: 5px; -webkit-border-radius: 5px; -khtml-border-radius: 5px; } h1 a, h2 a { color: white; text-decoration: none; } div.body h3 { font-size: 130%; font-weight: bold; color: black; } a.headerlink { color: white; font-size: 0.8em; padding: 0 4px 0 4px; text-decoration: none; } div.body p, div.body dd, div.body li { text-align: justify; line-height: 130%; } div.admonition p.admonition-title + p { display: inline; } div.admonition p { margin-bottom: 5px; } div.admonition pre { margin-bottom: 5px; } div.admonition ul, div.admonition ol { margin-bottom: 5px; } div.note { background-color: #eee; border: 1px solid #ccc; } div.seealso { background-color: #ffc; border: 1px solid #ff6; } div.topic { background-color: #eee; } div.warning { background-color: #ffe4e4; border: 1px solid #f66; } p.admonition-title { display: inline; } p.admonition-title:after { content: ":"; } pre { padding: 5px; /* * Note that this isn't our standard "sun" colour which doesn't contrast * too well with the pygments defaults. */ background-color: #fff4c0; color: black; line-height: 120%; border: 1px solid #ac9; border-left: none; border-right: none; } tt { background-color: #ecf0f3; padding: 0 1px 0 1px; font-size: 0.95em; } .warning tt { background: #efc2c2; } .note tt { background: #d6d6d6; } sip-4.15.5/doc/html/_static/doctools.js0000644000076500000240000001503012307277337020015 0ustar philstaff00000000000000/* * doctools.js * ~~~~~~~~~~~ * * Sphinx JavaScript utilities for all documentation. * * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ /** * select a different prefix for underscore */ $u = _.noConflict(); /** * make the code below compatible with browsers without * an installed firebug like debugger if (!window.console || !console.firebug) { var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"]; window.console = {}; for (var i = 0; i < names.length; ++i) window.console[names[i]] = function() {}; } */ /** * small helper function to urldecode strings */ jQuery.urldecode = function(x) { return decodeURIComponent(x).replace(/\+/g, ' '); }; /** * small helper function to urlencode strings */ jQuery.urlencode = encodeURIComponent; /** * This function returns the parsed url parameters of the * current request. Multiple values per key are supported, * it will always return arrays of strings for the value parts. */ jQuery.getQueryParameters = function(s) { if (typeof s == 'undefined') s = document.location.search; var parts = s.substr(s.indexOf('?') + 1).split('&'); var result = {}; for (var i = 0; i < parts.length; i++) { var tmp = parts[i].split('=', 2); var key = jQuery.urldecode(tmp[0]); var value = jQuery.urldecode(tmp[1]); if (key in result) result[key].push(value); else result[key] = [value]; } return result; }; /** * highlight a given string on a jquery object by wrapping it in * span elements with the given class name. */ jQuery.fn.highlightText = function(text, className) { function highlight(node) { if (node.nodeType == 3) { var val = node.nodeValue; var pos = val.toLowerCase().indexOf(text); if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { var span = document.createElement("span"); span.className = className; span.appendChild(document.createTextNode(val.substr(pos, text.length))); node.parentNode.insertBefore(span, node.parentNode.insertBefore( document.createTextNode(val.substr(pos + text.length)), node.nextSibling)); node.nodeValue = val.substr(0, pos); } } else if (!jQuery(node).is("button, select, textarea")) { jQuery.each(node.childNodes, function() { highlight(this); }); } } return this.each(function() { highlight(this); }); }; /** * Small JavaScript module for the documentation. */ var Documentation = { init : function() { this.fixFirefoxAnchorBug(); this.highlightSearchWords(); this.initIndexTable(); }, /** * i18n support */ TRANSLATIONS : {}, PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, LOCALE : 'unknown', // gettext and ngettext don't access this so that the functions // can safely bound to a different name (_ = Documentation.gettext) gettext : function(string) { var translated = Documentation.TRANSLATIONS[string]; if (typeof translated == 'undefined') return string; return (typeof translated == 'string') ? translated : translated[0]; }, ngettext : function(singular, plural, n) { var translated = Documentation.TRANSLATIONS[singular]; if (typeof translated == 'undefined') return (n == 1) ? singular : plural; return translated[Documentation.PLURALEXPR(n)]; }, addTranslations : function(catalog) { for (var key in catalog.messages) this.TRANSLATIONS[key] = catalog.messages[key]; this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); this.LOCALE = catalog.locale; }, /** * add context elements like header anchor links */ addContextElements : function() { $('div[id] > :header:first').each(function() { $('\u00B6'). attr('href', '#' + this.id). attr('title', _('Permalink to this headline')). appendTo(this); }); $('dt[id]').each(function() { $('\u00B6'). attr('href', '#' + this.id). attr('title', _('Permalink to this definition')). appendTo(this); }); }, /** * workaround a firefox stupidity */ fixFirefoxAnchorBug : function() { if (document.location.hash && $.browser.mozilla) window.setTimeout(function() { document.location.href += ''; }, 10); }, /** * highlight the search words provided in the url in the text */ highlightSearchWords : function() { var params = $.getQueryParameters(); var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; if (terms.length) { var body = $('div.body'); if (!body.length) { body = $('body'); } window.setTimeout(function() { $.each(terms, function() { body.highlightText(this.toLowerCase(), 'highlighted'); }); }, 10); $('') .appendTo($('#searchbox')); } }, /** * init the domain index toggle buttons */ initIndexTable : function() { var togglers = $('img.toggler').click(function() { var src = $(this).attr('src'); var idnum = $(this).attr('id').substr(7); $('tr.cg-' + idnum).toggle(); if (src.substr(-9) == 'minus.png') $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); else $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); }).css('display', ''); if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { togglers.click(); } }, /** * helper function to hide the search marks again */ hideSearchWords : function() { $('#searchbox .highlight-link').fadeOut(300); $('span.highlighted').removeClass('highlighted'); }, /** * make the url absolute */ makeURL : function(relativeURL) { return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; }, /** * get the current relative url */ getCurrentURL : function() { var path = document.location.pathname; var parts = path.split(/\//); $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { if (this == '..') parts.pop(); }); var url = parts.join('/'); return path.substring(url.lastIndexOf('/') + 1, path.length - 1); } }; // quick alias for translations _ = Documentation.gettext; $(document).ready(function() { Documentation.init(); }); sip-4.15.5/doc/html/_static/down-pressed.png0000644000076500000240000000056012307277337020753 0ustar philstaff00000000000000PNG  IHDRasRGBbKGDC pHYs B(xtIME -vF#IDAT8!OAJ, ++@I vbÿ@W7F HN#48646TMvv޼7Dsax1U q;< E-f)j%po4xF78G>)- EYm4%7YTk-Qa"NWAo-yeq,) Ypt\hqmszG]Nar߶s^l vh\2%0EeRvIENDB`sip-4.15.5/doc/html/_static/down.png0000644000076500000240000000055312307277337017312 0ustar philstaff00000000000000PNG  IHDRasRGBbKGDC pHYs B(xtIME"U{IDAT8ҡNCAJ, ++@4>/U^,~T&3M^^^PM6ٹs*RJa)eG*W<"F Fg78G>q OIp:sAj5GنyD^+yU:p_%G@D|aOs(yM,"msx:.b@D|`Vٟ۲иeKſ/G!IENDB`sip-4.15.5/doc/html/_static/file.png0000644000076500000240000000061012307277337017254 0ustar philstaff00000000000000PNG  IHDRabKGD pHYs  tIME  )TIDAT8˭J@Ir('[ "&xYZ X0!i|_@tD] #xjv YNaEi(əy@D&`6PZk$)5%"z.NA#Aba`Vs_3c,2mj [klvy|!Iմy;v "߮a?A7`c^nk?Bg}TЙD# "RD1yER*6MJ3K_Ut8F~IENDB`sip-4.15.5/doc/html/_static/jquery.js0000644000076500000240000026670512307277337017527 0ustar philstaff00000000000000/*! jQuery v1.8.3 jquery.com | jquery.org/license */ (function(e,t){function _(e){var t=M[e]={};return v.each(e.split(y),function(e,n){t[n]=!0}),t}function H(e,n,r){if(r===t&&e.nodeType===1){var i="data-"+n.replace(P,"-$1").toLowerCase();r=e.getAttribute(i);if(typeof r=="string"){try{r=r==="true"?!0:r==="false"?!1:r==="null"?null:+r+""===r?+r:D.test(r)?v.parseJSON(r):r}catch(s){}v.data(e,n,r)}else r=t}return r}function B(e){var t;for(t in e){if(t==="data"&&v.isEmptyObject(e[t]))continue;if(t!=="toJSON")return!1}return!0}function et(){return!1}function tt(){return!0}function ut(e){return!e||!e.parentNode||e.parentNode.nodeType===11}function at(e,t){do e=e[t];while(e&&e.nodeType!==1);return e}function ft(e,t,n){t=t||0;if(v.isFunction(t))return v.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return v.grep(e,function(e,r){return e===t===n});if(typeof t=="string"){var r=v.grep(e,function(e){return e.nodeType===1});if(it.test(t))return v.filter(t,r,!n);t=v.filter(t,r)}return v.grep(e,function(e,r){return v.inArray(e,t)>=0===n})}function lt(e){var t=ct.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function At(e,t){if(t.nodeType!==1||!v.hasData(e))return;var n,r,i,s=v._data(e),o=v._data(t,s),u=s.events;if(u){delete o.handle,o.events={};for(n in u)for(r=0,i=u[n].length;r").appendTo(i.body),n=t.css("display");t.remove();if(n==="none"||n===""){Pt=i.body.appendChild(Pt||v.extend(i.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Ht||!Pt.createElement)Ht=(Pt.contentWindow||Pt.contentDocument).document,Ht.write(""),Ht.close();t=Ht.body.appendChild(Ht.createElement(e)),n=Dt(t,"display"),i.body.removeChild(Pt)}return Wt[e]=n,n}function fn(e,t,n,r){var i;if(v.isArray(t))v.each(t,function(t,i){n||sn.test(e)?r(e,i):fn(e+"["+(typeof i=="object"?t:"")+"]",i,n,r)});else if(!n&&v.type(t)==="object")for(i in t)fn(e+"["+i+"]",t[i],n,r);else r(e,t)}function Cn(e){return function(t,n){typeof t!="string"&&(n=t,t="*");var r,i,s,o=t.toLowerCase().split(y),u=0,a=o.length;if(v.isFunction(n))for(;u)[^>]*$|#([\w\-]*)$)/,E=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,S=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,T=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,N=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,C=/^-ms-/,k=/-([\da-z])/gi,L=function(e,t){return(t+"").toUpperCase()},A=function(){i.addEventListener?(i.removeEventListener("DOMContentLoaded",A,!1),v.ready()):i.readyState==="complete"&&(i.detachEvent("onreadystatechange",A),v.ready())},O={};v.fn=v.prototype={constructor:v,init:function(e,n,r){var s,o,u,a;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if(typeof e=="string"){e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3?s=[null,e,null]:s=w.exec(e);if(s&&(s[1]||!n)){if(s[1])return n=n instanceof v?n[0]:n,a=n&&n.nodeType?n.ownerDocument||n:i,e=v.parseHTML(s[1],a,!0),E.test(s[1])&&v.isPlainObject(n)&&this.attr.call(e,n,!0),v.merge(this,e);o=i.getElementById(s[2]);if(o&&o.parentNode){if(o.id!==s[2])return r.find(e);this.length=1,this[0]=o}return this.context=i,this.selector=e,this}return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e)}return v.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),v.makeArray(e,this))},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return l.call(this)},get:function(e){return e==null?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e,t,n){var r=v.merge(this.constructor(),e);return r.prevObject=this,r.context=this.context,t==="find"?r.selector=this.selector+(this.selector?" ":"")+n:t&&(r.selector=this.selector+"."+t+"("+n+")"),r},each:function(e,t){return v.each(this,e,t)},ready:function(e){return v.ready.promise().done(e),this},eq:function(e){return e=+e,e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(l.apply(this,arguments),"slice",l.call(arguments).join(","))},map:function(e){return this.pushStack(v.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:[].sort,splice:[].splice},v.fn.init.prototype=v.fn,v.extend=v.fn.extend=function(){var e,n,r,i,s,o,u=arguments[0]||{},a=1,f=arguments.length,l=!1;typeof u=="boolean"&&(l=u,u=arguments[1]||{},a=2),typeof u!="object"&&!v.isFunction(u)&&(u={}),f===a&&(u=this,--a);for(;a0)return;r.resolveWith(i,[v]),v.fn.trigger&&v(i).trigger("ready").off("ready")},isFunction:function(e){return v.type(e)==="function"},isArray:Array.isArray||function(e){return v.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return e==null?String(e):O[h.call(e)]||"object"},isPlainObject:function(e){if(!e||v.type(e)!=="object"||e.nodeType||v.isWindow(e))return!1;try{if(e.constructor&&!p.call(e,"constructor")&&!p.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||p.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){var r;return!e||typeof e!="string"?null:(typeof t=="boolean"&&(n=t,t=0),t=t||i,(r=E.exec(e))?[t.createElement(r[1])]:(r=v.buildFragment([e],t,n?null:[]),v.merge([],(r.cacheable?v.clone(r.fragment):r.fragment).childNodes)))},parseJSON:function(t){if(!t||typeof t!="string")return null;t=v.trim(t);if(e.JSON&&e.JSON.parse)return e.JSON.parse(t);if(S.test(t.replace(T,"@").replace(N,"]").replace(x,"")))return(new Function("return "+t))();v.error("Invalid JSON: "+t)},parseXML:function(n){var r,i;if(!n||typeof n!="string")return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(s){r=t}return(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)&&v.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&g.test(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(C,"ms-").replace(k,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,n,r){var i,s=0,o=e.length,u=o===t||v.isFunction(e);if(r){if(u){for(i in e)if(n.apply(e[i],r)===!1)break}else for(;s0&&e[0]&&e[a-1]||a===0||v.isArray(e));if(f)for(;u-1)a.splice(n,1),i&&(n<=o&&o--,n<=u&&u--)}),this},has:function(e){return v.inArray(e,a)>-1},empty:function(){return a=[],this},disable:function(){return a=f=n=t,this},disabled:function(){return!a},lock:function(){return f=t,n||c.disable(),this},locked:function(){return!f},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],a&&(!r||f)&&(i?f.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},v.extend({Deferred:function(e){var t=[["resolve","done",v.Callbacks("once memory"),"resolved"],["reject","fail",v.Callbacks("once memory"),"rejected"],["notify","progress",v.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return v.Deferred(function(n){v.each(t,function(t,r){var s=r[0],o=e[t];i[r[1]](v.isFunction(o)?function(){var e=o.apply(this,arguments);e&&v.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===i?n:this,[e])}:n[s])}),e=null}).promise()},promise:function(e){return e!=null?v.extend(e,r):r}},i={};return r.pipe=r.then,v.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add,u&&o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock),i[s[0]]=o.fire,i[s[0]+"With"]=o.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=l.call(arguments),r=n.length,i=r!==1||e&&v.isFunction(e.promise)?r:0,s=i===1?e:v.Deferred(),o=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?l.call(arguments):r,n===u?s.notifyWith(t,n):--i||s.resolveWith(t,n)}},u,a,f;if(r>1){u=new Array(r),a=new Array(r),f=new Array(r);for(;t
a",n=p.getElementsByTagName("*"),r=p.getElementsByTagName("a")[0];if(!n||!r||!n.length)return{};s=i.createElement("select"),o=s.appendChild(i.createElement("option")),u=p.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:r.getAttribute("href")==="/a",opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:u.value==="on",optSelected:o.selected,getSetAttribute:p.className!=="t",enctype:!!i.createElement("form").enctype,html5Clone:i.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",boxModel:i.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},u.checked=!0,t.noCloneChecked=u.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!o.disabled;try{delete p.test}catch(d){t.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",h=function(){t.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick"),p.detachEvent("onclick",h)),u=i.createElement("input"),u.value="t",u.setAttribute("type","radio"),t.radioValue=u.value==="t",u.setAttribute("checked","checked"),u.setAttribute("name","t"),p.appendChild(u),a=i.createDocumentFragment(),a.appendChild(p.lastChild),t.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,t.appendChecked=u.checked,a.removeChild(u),a.appendChild(p);if(p.attachEvent)for(l in{submit:!0,change:!0,focusin:!0})f="on"+l,c=f in p,c||(p.setAttribute(f,"return;"),c=typeof p[f]=="function"),t[l+"Bubbles"]=c;return v(function(){var n,r,s,o,u="padding:0;margin:0;border:0;display:block;overflow:hidden;",a=i.getElementsByTagName("body")[0];if(!a)return;n=i.createElement("div"),n.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",a.insertBefore(n,a.firstChild),r=i.createElement("div"),n.appendChild(r),r.innerHTML="
t
",s=r.getElementsByTagName("td"),s[0].style.cssText="padding:0;margin:0;border:0;display:none",c=s[0].offsetHeight===0,s[0].style.display="",s[1].style.display="none",t.reliableHiddenOffsets=c&&s[0].offsetHeight===0,r.innerHTML="",r.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=r.offsetWidth===4,t.doesNotIncludeMarginInBodyOffset=a.offsetTop!==1,e.getComputedStyle&&(t.pixelPosition=(e.getComputedStyle(r,null)||{}).top!=="1%",t.boxSizingReliable=(e.getComputedStyle(r,null)||{width:"4px"}).width==="4px",o=i.createElement("div"),o.style.cssText=r.style.cssText=u,o.style.marginRight=o.style.width="0",r.style.width="1px",r.appendChild(o),t.reliableMarginRight=!parseFloat((e.getComputedStyle(o,null)||{}).marginRight)),typeof r.style.zoom!="undefined"&&(r.innerHTML="",r.style.cssText=u+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=r.offsetWidth===3,r.style.display="block",r.style.overflow="visible",r.innerHTML="
",r.firstChild.style.width="5px",t.shrinkWrapBlocks=r.offsetWidth!==3,n.style.zoom=1),a.removeChild(n),n=r=s=o=null}),a.removeChild(p),n=r=s=o=u=a=p=null,t}();var D=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;v.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(v.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?v.cache[e[v.expando]]:e[v.expando],!!e&&!B(e)},data:function(e,n,r,i){if(!v.acceptData(e))return;var s,o,u=v.expando,a=typeof n=="string",f=e.nodeType,l=f?v.cache:e,c=f?e[u]:e[u]&&u;if((!c||!l[c]||!i&&!l[c].data)&&a&&r===t)return;c||(f?e[u]=c=v.deletedIds.pop()||v.guid++:c=u),l[c]||(l[c]={},f||(l[c].toJSON=v.noop));if(typeof n=="object"||typeof n=="function")i?l[c]=v.extend(l[c],n):l[c].data=v.extend(l[c].data,n);return s=l[c],i||(s.data||(s.data={}),s=s.data),r!==t&&(s[v.camelCase(n)]=r),a?(o=s[n],o==null&&(o=s[v.camelCase(n)])):o=s,o},removeData:function(e,t,n){if(!v.acceptData(e))return;var r,i,s,o=e.nodeType,u=o?v.cache:e,a=o?e[v.expando]:v.expando;if(!u[a])return;if(t){r=n?u[a]:u[a].data;if(r){v.isArray(t)||(t in r?t=[t]:(t=v.camelCase(t),t in r?t=[t]:t=t.split(" ")));for(i=0,s=t.length;i1,null,!1))},removeData:function(e){return this.each(function(){v.removeData(this,e)})}}),v.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=v._data(e,t),n&&(!r||v.isArray(n)?r=v._data(e,t,v.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=v.queue(e,t),r=n.length,i=n.shift(),s=v._queueHooks(e,t),o=function(){v.dequeue(e,t)};i==="inprogress"&&(i=n.shift(),r--),i&&(t==="fx"&&n.unshift("inprogress"),delete s.stop,i.call(e,o,s)),!r&&s&&s.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return v._data(e,n)||v._data(e,n,{empty:v.Callbacks("once memory").add(function(){v.removeData(e,t+"queue",!0),v.removeData(e,n,!0)})})}}),v.fn.extend({queue:function(e,n){var r=2;return typeof e!="string"&&(n=e,e="fx",r--),arguments.length1)},removeAttr:function(e){return this.each(function(){v.removeAttr(this,e)})},prop:function(e,t){return v.access(this,v.prop,e,t,arguments.length>1)},removeProp:function(e){return e=v.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,s,o,u;if(v.isFunction(e))return this.each(function(t){v(this).addClass(e.call(this,t,this.className))});if(e&&typeof e=="string"){t=e.split(y);for(n=0,r=this.length;n=0)r=r.replace(" "+n[s]+" "," ");i.className=e?v.trim(r):""}}}return this},toggleClass:function(e,t){var n=typeof e,r=typeof t=="boolean";return v.isFunction(e)?this.each(function(n){v(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if(n==="string"){var i,s=0,o=v(this),u=t,a=e.split(y);while(i=a[s++])u=r?u:!o.hasClass(i),o[u?"addClass":"removeClass"](i)}else if(n==="undefined"||n==="boolean")this.className&&v._data(this,"__className__",this.className),this.className=this.className||e===!1?"":v._data(this,"__className__")||""})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n=0)return!0;return!1},val:function(e){var n,r,i,s=this[0];if(!arguments.length){if(s)return n=v.valHooks[s.type]||v.valHooks[s.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(s,"value"))!==t?r:(r=s.value,typeof r=="string"?r.replace(R,""):r==null?"":r);return}return i=v.isFunction(e),this.each(function(r){var s,o=v(this);if(this.nodeType!==1)return;i?s=e.call(this,r,o.val()):s=e,s==null?s="":typeof s=="number"?s+="":v.isArray(s)&&(s=v.map(s,function(e){return e==null?"":e+""})),n=v.valHooks[this.type]||v.valHooks[this.nodeName.toLowerCase()];if(!n||!("set"in n)||n.set(this,s,"value")===t)this.value=s})}}),v.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a=0}),n.length||(e.selectedIndex=-1),n}}},attrFn:{},attr:function(e,n,r,i){var s,o,u,a=e.nodeType;if(!e||a===3||a===8||a===2)return;if(i&&v.isFunction(v.fn[n]))return v(e)[n](r);if(typeof e.getAttribute=="undefined")return v.prop(e,n,r);u=a!==1||!v.isXMLDoc(e),u&&(n=n.toLowerCase(),o=v.attrHooks[n]||(X.test(n)?F:j));if(r!==t){if(r===null){v.removeAttr(e,n);return}return o&&"set"in o&&u&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r)}return o&&"get"in o&&u&&(s=o.get(e,n))!==null?s:(s=e.getAttribute(n),s===null?t:s)},removeAttr:function(e,t){var n,r,i,s,o=0;if(t&&e.nodeType===1){r=t.split(y);for(;o=0}})});var $=/^(?:textarea|input|select)$/i,J=/^([^\.]*|)(?:\.(.+)|)$/,K=/(?:^|\s)hover(\.\S+|)\b/,Q=/^key/,G=/^(?:mouse|contextmenu)|click/,Y=/^(?:focusinfocus|focusoutblur)$/,Z=function(e){return v.event.special.hover?e:e.replace(K,"mouseenter$1 mouseleave$1")};v.event={add:function(e,n,r,i,s){var o,u,a,f,l,c,h,p,d,m,g;if(e.nodeType===3||e.nodeType===8||!n||!r||!(o=v._data(e)))return;r.handler&&(d=r,r=d.handler,s=d.selector),r.guid||(r.guid=v.guid++),a=o.events,a||(o.events=a={}),u=o.handle,u||(o.handle=u=function(e){return typeof v=="undefined"||!!e&&v.event.triggered===e.type?t:v.event.dispatch.apply(u.elem,arguments)},u.elem=e),n=v.trim(Z(n)).split(" ");for(f=0;f=0&&(y=y.slice(0,-1),a=!0),y.indexOf(".")>=0&&(b=y.split("."),y=b.shift(),b.sort());if((!s||v.event.customEvent[y])&&!v.event.global[y])return;n=typeof n=="object"?n[v.expando]?n:new v.Event(y,n):new v.Event(y),n.type=y,n.isTrigger=!0,n.exclusive=a,n.namespace=b.join("."),n.namespace_re=n.namespace?new RegExp("(^|\\.)"+b.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,h=y.indexOf(":")<0?"on"+y:"";if(!s){u=v.cache;for(f in u)u[f].events&&u[f].events[y]&&v.event.trigger(n,r,u[f].handle.elem,!0);return}n.result=t,n.target||(n.target=s),r=r!=null?v.makeArray(r):[],r.unshift(n),p=v.event.special[y]||{};if(p.trigger&&p.trigger.apply(s,r)===!1)return;m=[[s,p.bindType||y]];if(!o&&!p.noBubble&&!v.isWindow(s)){g=p.delegateType||y,l=Y.test(g+y)?s:s.parentNode;for(c=s;l;l=l.parentNode)m.push([l,g]),c=l;c===(s.ownerDocument||i)&&m.push([c.defaultView||c.parentWindow||e,g])}for(f=0;f=0:v.find(h,this,null,[s]).length),u[h]&&f.push(c);f.length&&w.push({elem:s,matches:f})}d.length>m&&w.push({elem:this,matches:d.slice(m)});for(r=0;r0?this.on(t,null,e,n):this.trigger(t)},Q.test(t)&&(v.event.fixHooks[t]=v.event.keyHooks),G.test(t)&&(v.event.fixHooks[t]=v.event.mouseHooks)}),function(e,t){function nt(e,t,n,r){n=n||[],t=t||g;var i,s,a,f,l=t.nodeType;if(!e||typeof e!="string")return n;if(l!==1&&l!==9)return[];a=o(t);if(!a&&!r)if(i=R.exec(e))if(f=i[1]){if(l===9){s=t.getElementById(f);if(!s||!s.parentNode)return n;if(s.id===f)return n.push(s),n}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(f))&&u(t,s)&&s.id===f)return n.push(s),n}else{if(i[2])return S.apply(n,x.call(t.getElementsByTagName(e),0)),n;if((f=i[3])&&Z&&t.getElementsByClassName)return S.apply(n,x.call(t.getElementsByClassName(f),0)),n}return vt(e.replace(j,"$1"),t,n,r,a)}function rt(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function it(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function st(e){return N(function(t){return t=+t,N(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--)n[i=s[o]]&&(n[i]=!(r[i]=n[i]))})})}function ot(e,t,n){if(e===t)return n;var r=e.nextSibling;while(r){if(r===t)return-1;r=r.nextSibling}return 1}function ut(e,t){var n,r,s,o,u,a,f,l=L[d][e+" "];if(l)return t?0:l.slice(0);u=e,a=[],f=i.preFilter;while(u){if(!n||(r=F.exec(u)))r&&(u=u.slice(r[0].length)||u),a.push(s=[]);n=!1;if(r=I.exec(u))s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=r[0].replace(j," ");for(o in i.filter)(r=J[o].exec(u))&&(!f[o]||(r=f[o](r)))&&(s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=o,n.matches=r);if(!n)break}return t?u.length:u?nt.error(e):L(e,a).slice(0)}function at(e,t,r){var i=t.dir,s=r&&t.dir==="parentNode",o=w++;return t.first?function(t,n,r){while(t=t[i])if(s||t.nodeType===1)return e(t,n,r)}:function(t,r,u){if(!u){var a,f=b+" "+o+" ",l=f+n;while(t=t[i])if(s||t.nodeType===1){if((a=t[d])===l)return t.sizset;if(typeof a=="string"&&a.indexOf(f)===0){if(t.sizset)return t}else{t[d]=l;if(e(t,r,u))return t.sizset=!0,t;t.sizset=!1}}}else while(t=t[i])if(s||t.nodeType===1)if(e(t,r,u))return t}}function ft(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function lt(e,t,n,r,i){var s,o=[],u=0,a=e.length,f=t!=null;for(;u-1&&(s[f]=!(o[f]=c))}}else g=lt(g===o?g.splice(d,g.length):g),i?i(null,o,g,a):S.apply(o,g)})}function ht(e){var t,n,r,s=e.length,o=i.relative[e[0].type],u=o||i.relative[" "],a=o?1:0,f=at(function(e){return e===t},u,!0),l=at(function(e){return T.call(t,e)>-1},u,!0),h=[function(e,n,r){return!o&&(r||n!==c)||((t=n).nodeType?f(e,n,r):l(e,n,r))}];for(;a1&&ft(h),a>1&&e.slice(0,a-1).join("").replace(j,"$1"),n,a0,s=e.length>0,o=function(u,a,f,l,h){var p,d,v,m=[],y=0,w="0",x=u&&[],T=h!=null,N=c,C=u||s&&i.find.TAG("*",h&&a.parentNode||a),k=b+=N==null?1:Math.E;T&&(c=a!==g&&a,n=o.el);for(;(p=C[w])!=null;w++){if(s&&p){for(d=0;v=e[d];d++)if(v(p,a,f)){l.push(p);break}T&&(b=k,n=++o.el)}r&&((p=!v&&p)&&y--,u&&x.push(p))}y+=w;if(r&&w!==y){for(d=0;v=t[d];d++)v(x,m,a,f);if(u){if(y>0)while(w--)!x[w]&&!m[w]&&(m[w]=E.call(l));m=lt(m)}S.apply(l,m),T&&!u&&m.length>0&&y+t.length>1&&nt.uniqueSort(l)}return T&&(b=k,c=N),x};return o.el=0,r?N(o):o}function dt(e,t,n){var r=0,i=t.length;for(;r2&&(f=u[0]).type==="ID"&&t.nodeType===9&&!s&&i.relative[u[1].type]){t=i.find.ID(f.matches[0].replace($,""),t,s)[0];if(!t)return n;e=e.slice(u.shift().length)}for(o=J.POS.test(e)?-1:u.length-1;o>=0;o--){f=u[o];if(i.relative[l=f.type])break;if(c=i.find[l])if(r=c(f.matches[0].replace($,""),z.test(u[0].type)&&t.parentNode||t,s)){u.splice(o,1),e=r.length&&u.join("");if(!e)return S.apply(n,x.call(r,0)),n;break}}}return a(e,h)(r,t,s,n,z.test(e)),n}function mt(){}var n,r,i,s,o,u,a,f,l,c,h=!0,p="undefined",d=("sizcache"+Math.random()).replace(".",""),m=String,g=e.document,y=g.documentElement,b=0,w=0,E=[].pop,S=[].push,x=[].slice,T=[].indexOf||function(e){var t=0,n=this.length;for(;ti.cacheLength&&delete e[t.shift()],e[n+" "]=r},e)},k=C(),L=C(),A=C(),O="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",_=M.replace("w","w#"),D="([*^$|!~]?=)",P="\\["+O+"*("+M+")"+O+"*(?:"+D+O+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+_+")|)|)"+O+"*\\]",H=":("+M+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+P+")|[^:]|\\\\.)*|.*))\\)|)",B=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+O+"*((?:-\\d)?\\d*)"+O+"*\\)|)(?=[^-]|$)",j=new RegExp("^"+O+"+|((?:^|[^\\\\])(?:\\\\.)*)"+O+"+$","g"),F=new RegExp("^"+O+"*,"+O+"*"),I=new RegExp("^"+O+"*([\\x20\\t\\r\\n\\f>+~])"+O+"*"),q=new RegExp(H),R=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,U=/^:not/,z=/[\x20\t\r\n\f]*[+~]/,W=/:not\($/,X=/h\d/i,V=/input|select|textarea|button/i,$=/\\(?!\\)/g,J={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),NAME:new RegExp("^\\[name=['\"]?("+M+")['\"]?\\]"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+H),POS:new RegExp(B,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+O+"*(even|odd|(([+-]|)(\\d*)n|)"+O+"*(?:([+-]|)"+O+"*(\\d+)|))"+O+"*\\)|)","i"),needsContext:new RegExp("^"+O+"*[>+~]|"+B,"i")},K=function(e){var t=g.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}},Q=K(function(e){return e.appendChild(g.createComment("")),!e.getElementsByTagName("*").length}),G=K(function(e){return e.innerHTML="",e.firstChild&&typeof e.firstChild.getAttribute!==p&&e.firstChild.getAttribute("href")==="#"}),Y=K(function(e){e.innerHTML="";var t=typeof e.lastChild.getAttribute("multiple");return t!=="boolean"&&t!=="string"}),Z=K(function(e){return e.innerHTML="",!e.getElementsByClassName||!e.getElementsByClassName("e").length?!1:(e.lastChild.className="e",e.getElementsByClassName("e").length===2)}),et=K(function(e){e.id=d+0,e.innerHTML="
",y.insertBefore(e,y.firstChild);var t=g.getElementsByName&&g.getElementsByName(d).length===2+g.getElementsByName(d+0).length;return r=!g.getElementById(d),y.removeChild(e),t});try{x.call(y.childNodes,0)[0].nodeType}catch(tt){x=function(e){var t,n=[];for(;t=this[e];e++)n.push(t);return n}}nt.matches=function(e,t){return nt(e,null,null,t)},nt.matchesSelector=function(e,t){return nt(t,null,null,[e]).length>0},s=nt.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(i===1||i===9||i===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=s(e)}else if(i===3||i===4)return e.nodeValue}else for(;t=e[r];r++)n+=s(t);return n},o=nt.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":!1},u=nt.contains=y.contains?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!(r&&r.nodeType===1&&n.contains&&n.contains(r))}:y.compareDocumentPosition?function(e,t){return t&&!!(e.compareDocumentPosition(t)&16)}:function(e,t){while(t=t.parentNode)if(t===e)return!0;return!1},nt.attr=function(e,t){var n,r=o(e);return r||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):r||Y?e.getAttribute(t):(n=e.getAttributeNode(t),n?typeof e[t]=="boolean"?e[t]?t:null:n.specified?n.value:null:null)},i=nt.selectors={cacheLength:50,createPseudo:N,match:J,attrHandle:G?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},find:{ID:r?function(e,t,n){if(typeof t.getElementById!==p&&!n){var r=t.getElementById(e);return r&&r.parentNode?[r]:[]}}:function(e,n,r){if(typeof n.getElementById!==p&&!r){var i=n.getElementById(e);return i?i.id===e||typeof i.getAttributeNode!==p&&i.getAttributeNode("id").value===e?[i]:t:[]}},TAG:Q?function(e,t){if(typeof t.getElementsByTagName!==p)return t.getElementsByTagName(e)}:function(e,t){var n=t.getElementsByTagName(e);if(e==="*"){var r,i=[],s=0;for(;r=n[s];s++)r.nodeType===1&&i.push(r);return i}return n},NAME:et&&function(e,t){if(typeof t.getElementsByName!==p)return t.getElementsByName(name)},CLASS:Z&&function(e,t,n){if(typeof t.getElementsByClassName!==p&&!n)return t.getElementsByClassName(e)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace($,""),e[3]=(e[4]||e[5]||"").replace($,""),e[2]==="~="&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),e[1]==="nth"?(e[2]||nt.error(e[0]),e[3]=+(e[3]?e[4]+(e[5]||1):2*(e[2]==="even"||e[2]==="odd")),e[4]=+(e[6]+e[7]||e[2]==="odd")):e[2]&&nt.error(e[0]),e},PSEUDO:function(e){var t,n;if(J.CHILD.test(e[0]))return null;if(e[3])e[2]=e[3];else if(t=e[4])q.test(t)&&(n=ut(t,!0))&&(n=t.indexOf(")",t.length-n)-t.length)&&(t=t.slice(0,n),e[0]=e[0].slice(0,n)),e[2]=t;return e.slice(0,3)}},filter:{ID:r?function(e){return e=e.replace($,""),function(t){return t.getAttribute("id")===e}}:function(e){return e=e.replace($,""),function(t){var n=typeof t.getAttributeNode!==p&&t.getAttributeNode("id");return n&&n.value===e}},TAG:function(e){return e==="*"?function(){return!0}:(e=e.replace($,"").toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[d][e+" "];return t||(t=new RegExp("(^|"+O+")"+e+"("+O+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==p&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r,i){var s=nt.attr(r,e);return s==null?t==="!=":t?(s+="",t==="="?s===n:t==="!="?s!==n:t==="^="?n&&s.indexOf(n)===0:t==="*="?n&&s.indexOf(n)>-1:t==="$="?n&&s.substr(s.length-n.length)===n:t==="~="?(" "+s+" ").indexOf(n)>-1:t==="|="?s===n||s.substr(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r){return e==="nth"?function(e){var t,i,s=e.parentNode;if(n===1&&r===0)return!0;if(s){i=0;for(t=s.firstChild;t;t=t.nextSibling)if(t.nodeType===1){i++;if(e===t)break}}return i-=r,i===n||i%n===0&&i/n>=0}:function(t){var n=t;switch(e){case"only":case"first":while(n=n.previousSibling)if(n.nodeType===1)return!1;if(e==="first")return!0;n=t;case"last":while(n=n.nextSibling)if(n.nodeType===1)return!1;return!0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||nt.error("unsupported pseudo: "+e);return r[d]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?N(function(e,n){var i,s=r(e,t),o=s.length;while(o--)i=T.call(e,s[o]),e[i]=!(n[i]=s[o])}):function(e){return r(e,0,n)}):r}},pseudos:{not:N(function(e){var t=[],n=[],r=a(e.replace(j,"$1"));return r[d]?N(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--)if(s=o[u])e[u]=!(t[u]=s)}):function(e,i,s){return t[0]=e,r(t,null,s,n),!n.pop()}}),has:N(function(e){return function(t){return nt(e,t).length>0}}),contains:N(function(e){return function(t){return(t.textContent||t.innerText||s(t)).indexOf(e)>-1}}),enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!i.pseudos.empty(e)},empty:function(e){var t;e=e.firstChild;while(e){if(e.nodeName>"@"||(t=e.nodeType)===3||t===4)return!1;e=e.nextSibling}return!0},header:function(e){return X.test(e.nodeName)},text:function(e){var t,n;return e.nodeName.toLowerCase()==="input"&&(t=e.type)==="text"&&((n=e.getAttribute("type"))==null||n.toLowerCase()===t)},radio:rt("radio"),checkbox:rt("checkbox"),file:rt("file"),password:rt("password"),image:rt("image"),submit:it("submit"),reset:it("reset"),button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},input:function(e){return V.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},active:function(e){return e===e.ownerDocument.activeElement},first:st(function(){return[0]}),last:st(function(e,t){return[t-1]}),eq:st(function(e,t,n){return[n<0?n+t:n]}),even:st(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:st(function(e,t,n){for(var r=n<0?n+t:n;++r",e.querySelectorAll("[selected]").length||i.push("\\["+O+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),K(function(e){e.innerHTML="

",e.querySelectorAll("[test^='']").length&&i.push("[*^$]="+O+"*(?:\"\"|'')"),e.innerHTML="",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=new RegExp(i.join("|")),vt=function(e,r,s,o,u){if(!o&&!u&&!i.test(e)){var a,f,l=!0,c=d,h=r,p=r.nodeType===9&&e;if(r.nodeType===1&&r.nodeName.toLowerCase()!=="object"){a=ut(e),(l=r.getAttribute("id"))?c=l.replace(n,"\\$&"):r.setAttribute("id",c),c="[id='"+c+"'] ",f=a.length;while(f--)a[f]=c+a[f].join("");h=z.test(e)&&r.parentNode||r,p=a.join(",")}if(p)try{return S.apply(s,x.call(h.querySelectorAll(p),0)),s}catch(v){}finally{l||r.removeAttribute("id")}}return t(e,r,s,o,u)},u&&(K(function(t){e=u.call(t,"div");try{u.call(t,"[test!='']:sizzle"),s.push("!=",H)}catch(n){}}),s=new RegExp(s.join("|")),nt.matchesSelector=function(t,n){n=n.replace(r,"='$1']");if(!o(t)&&!s.test(n)&&!i.test(n))try{var a=u.call(t,n);if(a||e||t.document&&t.document.nodeType!==11)return a}catch(f){}return nt(n,null,null,[t]).length>0})}(),i.pseudos.nth=i.pseudos.eq,i.filters=mt.prototype=i.pseudos,i.setFilters=new mt,nt.attr=v.attr,v.find=nt,v.expr=nt.selectors,v.expr[":"]=v.expr.pseudos,v.unique=nt.uniqueSort,v.text=nt.getText,v.isXMLDoc=nt.isXML,v.contains=nt.contains}(e);var nt=/Until$/,rt=/^(?:parents|prev(?:Until|All))/,it=/^.[^:#\[\.,]*$/,st=v.expr.match.needsContext,ot={children:!0,contents:!0,next:!0,prev:!0};v.fn.extend({find:function(e){var t,n,r,i,s,o,u=this;if(typeof e!="string")return v(e).filter(function(){for(t=0,n=u.length;t0)for(i=r;i=0:v.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,s=[],o=st.test(e)||typeof e!="string"?v(e,t||this.context):0;for(;r-1:v.find.matchesSelector(n,e)){s.push(n);break}n=n.parentNode}}return s=s.length>1?v.unique(s):s,this.pushStack(s,"closest",e)},index:function(e){return e?typeof e=="string"?v.inArray(this[0],v(e)):v.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var n=typeof e=="string"?v(e,t):v.makeArray(e&&e.nodeType?[e]:e),r=v.merge(this.get(),n);return this.pushStack(ut(n[0])||ut(r[0])?r:v.unique(r))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}),v.fn.andSelf=v.fn.addBack,v.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return v.dir(e,"parentNode")},parentsUntil:function(e,t,n){return v.dir(e,"parentNode",n)},next:function(e){return at(e,"nextSibling")},prev:function(e){return at(e,"previousSibling")},nextAll:function(e){return v.dir(e,"nextSibling")},prevAll:function(e){return v.dir(e,"previousSibling")},nextUntil:function(e,t,n){return v.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return v.dir(e,"previousSibling",n)},siblings:function(e){return v.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return v.sibling(e.firstChild)},contents:function(e){return v.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:v.merge([],e.childNodes)}},function(e,t){v.fn[e]=function(n,r){var i=v.map(this,t,n);return nt.test(e)||(r=n),r&&typeof r=="string"&&(i=v.filter(r,i)),i=this.length>1&&!ot[e]?v.unique(i):i,this.length>1&&rt.test(e)&&(i=i.reverse()),this.pushStack(i,e,l.call(arguments).join(","))}}),v.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),t.length===1?v.find.matchesSelector(t[0],e)?[t[0]]:[]:v.find.matches(e,t)},dir:function(e,n,r){var i=[],s=e[n];while(s&&s.nodeType!==9&&(r===t||s.nodeType!==1||!v(s).is(r)))s.nodeType===1&&i.push(s),s=s[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)e.nodeType===1&&e!==t&&n.push(e);return n}});var ct="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ht=/ jQuery\d+="(?:null|\d+)"/g,pt=/^\s+/,dt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,vt=/<([\w:]+)/,mt=/]","i"),Et=/^(?:checkbox|radio)$/,St=/checked\s*(?:[^=]|=\s*.checked.)/i,xt=/\/(java|ecma)script/i,Tt=/^\s*\s*$/g,Nt={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},Ct=lt(i),kt=Ct.appendChild(i.createElement("div"));Nt.optgroup=Nt.option,Nt.tbody=Nt.tfoot=Nt.colgroup=Nt.caption=Nt.thead,Nt.th=Nt.td,v.support.htmlSerialize||(Nt._default=[1,"X
","
"]),v.fn.extend({text:function(e){return v.access(this,function(e){return e===t?v.text(this):this.empty().append((this[0]&&this[0].ownerDocument||i).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(v.isFunction(e))return this.each(function(t){v(this).wrapAll(e.call(this,t))});if(this[0]){var t=v(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&e.firstChild.nodeType===1)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return v.isFunction(e)?this.each(function(t){v(this).wrapInner(e.call(this,t))}):this.each(function(){var t=v(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=v.isFunction(e);return this.each(function(n){v(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){v.nodeName(this,"body")||v(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(e,this.firstChild)})},before:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(e,this),"before",this.selector)}},after:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(this,e),"after",this.selector)}},remove:function(e,t){var n,r=0;for(;(n=this[r])!=null;r++)if(!e||v.filter(e,[n]).length)!t&&n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),v.cleanData([n])),n.parentNode&&n.parentNode.removeChild(n);return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++){e.nodeType===1&&v.cleanData(e.getElementsByTagName("*"));while(e.firstChild)e.removeChild(e.firstChild)}return this},clone:function(e,t){return e=e==null?!1:e,t=t==null?e:t,this.map(function(){return v.clone(this,e,t)})},html:function(e){return v.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return n.nodeType===1?n.innerHTML.replace(ht,""):t;if(typeof e=="string"&&!yt.test(e)&&(v.support.htmlSerialize||!wt.test(e))&&(v.support.leadingWhitespace||!pt.test(e))&&!Nt[(vt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(dt,"<$1>");try{for(;r1&&typeof f=="string"&&St.test(f))return this.each(function(){v(this).domManip(e,n,r)});if(v.isFunction(f))return this.each(function(i){var s=v(this);e[0]=f.call(this,i,n?s.html():t),s.domManip(e,n,r)});if(this[0]){i=v.buildFragment(e,this,l),o=i.fragment,s=o.firstChild,o.childNodes.length===1&&(o=s);if(s){n=n&&v.nodeName(s,"tr");for(u=i.cacheable||c-1;a0?this.clone(!0):this).get(),v(o[i])[t](r),s=s.concat(r);return this.pushStack(s,e,o.selector)}}),v.extend({clone:function(e,t,n){var r,i,s,o;v.support.html5Clone||v.isXMLDoc(e)||!wt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(kt.innerHTML=e.outerHTML,kt.removeChild(o=kt.firstChild));if((!v.support.noCloneEvent||!v.support.noCloneChecked)&&(e.nodeType===1||e.nodeType===11)&&!v.isXMLDoc(e)){Ot(e,o),r=Mt(e),i=Mt(o);for(s=0;r[s];++s)i[s]&&Ot(r[s],i[s])}if(t){At(e,o);if(n){r=Mt(e),i=Mt(o);for(s=0;r[s];++s)At(r[s],i[s])}}return r=i=null,o},clean:function(e,t,n,r){var s,o,u,a,f,l,c,h,p,d,m,g,y=t===i&&Ct,b=[];if(!t||typeof t.createDocumentFragment=="undefined")t=i;for(s=0;(u=e[s])!=null;s++){typeof u=="number"&&(u+="");if(!u)continue;if(typeof u=="string")if(!gt.test(u))u=t.createTextNode(u);else{y=y||lt(t),c=t.createElement("div"),y.appendChild(c),u=u.replace(dt,"<$1>"),a=(vt.exec(u)||["",""])[1].toLowerCase(),f=Nt[a]||Nt._default,l=f[0],c.innerHTML=f[1]+u+f[2];while(l--)c=c.lastChild;if(!v.support.tbody){h=mt.test(u),p=a==="table"&&!h?c.firstChild&&c.firstChild.childNodes:f[1]===""&&!h?c.childNodes:[];for(o=p.length-1;o>=0;--o)v.nodeName(p[o],"tbody")&&!p[o].childNodes.length&&p[o].parentNode.removeChild(p[o])}!v.support.leadingWhitespace&&pt.test(u)&&c.insertBefore(t.createTextNode(pt.exec(u)[0]),c.firstChild),u=c.childNodes,c.parentNode.removeChild(c)}u.nodeType?b.push(u):v.merge(b,u)}c&&(u=c=y=null);if(!v.support.appendChecked)for(s=0;(u=b[s])!=null;s++)v.nodeName(u,"input")?_t(u):typeof u.getElementsByTagName!="undefined"&&v.grep(u.getElementsByTagName("input"),_t);if(n){m=function(e){if(!e.type||xt.test(e.type))return r?r.push(e.parentNode?e.parentNode.removeChild(e):e):n.appendChild(e)};for(s=0;(u=b[s])!=null;s++)if(!v.nodeName(u,"script")||!m(u))n.appendChild(u),typeof u.getElementsByTagName!="undefined"&&(g=v.grep(v.merge([],u.getElementsByTagName("script")),m),b.splice.apply(b,[s+1,0].concat(g)),s+=g.length)}return b},cleanData:function(e,t){var n,r,i,s,o=0,u=v.expando,a=v.cache,f=v.support.deleteExpando,l=v.event.special;for(;(i=e[o])!=null;o++)if(t||v.acceptData(i)){r=i[u],n=r&&a[r];if(n){if(n.events)for(s in n.events)l[s]?v.event.remove(i,s):v.removeEvent(i,s,n.handle);a[r]&&(delete a[r],f?delete i[u]:i.removeAttribute?i.removeAttribute(u):i[u]=null,v.deletedIds.push(r))}}}}),function(){var e,t;v.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e=v.uaMatch(o.userAgent),t={},e.browser&&(t[e.browser]=!0,t.version=e.version),t.chrome?t.webkit=!0:t.webkit&&(t.safari=!0),v.browser=t,v.sub=function(){function e(t,n){return new e.fn.init(t,n)}v.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function(r,i){return i&&i instanceof v&&!(i instanceof e)&&(i=e(i)),v.fn.init.call(this,r,i,t)},e.fn.init.prototype=e.fn;var t=e(i);return e}}();var Dt,Pt,Ht,Bt=/alpha\([^)]*\)/i,jt=/opacity=([^)]*)/,Ft=/^(top|right|bottom|left)$/,It=/^(none|table(?!-c[ea]).+)/,qt=/^margin/,Rt=new RegExp("^("+m+")(.*)$","i"),Ut=new RegExp("^("+m+")(?!px)[a-z%]+$","i"),zt=new RegExp("^([-+])=("+m+")","i"),Wt={BODY:"block"},Xt={position:"absolute",visibility:"hidden",display:"block"},Vt={letterSpacing:0,fontWeight:400},$t=["Top","Right","Bottom","Left"],Jt=["Webkit","O","Moz","ms"],Kt=v.fn.toggle;v.fn.extend({css:function(e,n){return v.access(this,function(e,n,r){return r!==t?v.style(e,n,r):v.css(e,n)},e,n,arguments.length>1)},show:function(){return Yt(this,!0)},hide:function(){return Yt(this)},toggle:function(e,t){var n=typeof e=="boolean";return v.isFunction(e)&&v.isFunction(t)?Kt.apply(this,arguments):this.each(function(){(n?e:Gt(this))?v(this).show():v(this).hide()})}}),v.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Dt(e,"opacity");return n===""?"1":n}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":v.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(!e||e.nodeType===3||e.nodeType===8||!e.style)return;var s,o,u,a=v.camelCase(n),f=e.style;n=v.cssProps[a]||(v.cssProps[a]=Qt(f,a)),u=v.cssHooks[n]||v.cssHooks[a];if(r===t)return u&&"get"in u&&(s=u.get(e,!1,i))!==t?s:f[n];o=typeof r,o==="string"&&(s=zt.exec(r))&&(r=(s[1]+1)*s[2]+parseFloat(v.css(e,n)),o="number");if(r==null||o==="number"&&isNaN(r))return;o==="number"&&!v.cssNumber[a]&&(r+="px");if(!u||!("set"in u)||(r=u.set(e,r,i))!==t)try{f[n]=r}catch(l){}},css:function(e,n,r,i){var s,o,u,a=v.camelCase(n);return n=v.cssProps[a]||(v.cssProps[a]=Qt(e.style,a)),u=v.cssHooks[n]||v.cssHooks[a],u&&"get"in u&&(s=u.get(e,!0,i)),s===t&&(s=Dt(e,n)),s==="normal"&&n in Vt&&(s=Vt[n]),r||i!==t?(o=parseFloat(s),r||v.isNumeric(o)?o||0:s):s},swap:function(e,t,n){var r,i,s={};for(i in t)s[i]=e.style[i],e.style[i]=t[i];r=n.call(e);for(i in t)e.style[i]=s[i];return r}}),e.getComputedStyle?Dt=function(t,n){var r,i,s,o,u=e.getComputedStyle(t,null),a=t.style;return u&&(r=u.getPropertyValue(n)||u[n],r===""&&!v.contains(t.ownerDocument,t)&&(r=v.style(t,n)),Ut.test(r)&&qt.test(n)&&(i=a.width,s=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=r,r=u.width,a.width=i,a.minWidth=s,a.maxWidth=o)),r}:i.documentElement.currentStyle&&(Dt=function(e,t){var n,r,i=e.currentStyle&&e.currentStyle[t],s=e.style;return i==null&&s&&s[t]&&(i=s[t]),Ut.test(i)&&!Ft.test(t)&&(n=s.left,r=e.runtimeStyle&&e.runtimeStyle.left,r&&(e.runtimeStyle.left=e.currentStyle.left),s.left=t==="fontSize"?"1em":i,i=s.pixelLeft+"px",s.left=n,r&&(e.runtimeStyle.left=r)),i===""?"auto":i}),v.each(["height","width"],function(e,t){v.cssHooks[t]={get:function(e,n,r){if(n)return e.offsetWidth===0&&It.test(Dt(e,"display"))?v.swap(e,Xt,function(){return tn(e,t,r)}):tn(e,t,r)},set:function(e,n,r){return Zt(e,n,r?en(e,t,r,v.support.boxSizing&&v.css(e,"boxSizing")==="border-box"):0)}}}),v.support.opacity||(v.cssHooks.opacity={get:function(e,t){return jt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=v.isNumeric(t)?"alpha(opacity="+t*100+")":"",s=r&&r.filter||n.filter||"";n.zoom=1;if(t>=1&&v.trim(s.replace(Bt,""))===""&&n.removeAttribute){n.removeAttribute("filter");if(r&&!r.filter)return}n.filter=Bt.test(s)?s.replace(Bt,i):s+" "+i}}),v(function(){v.support.reliableMarginRight||(v.cssHooks.marginRight={get:function(e,t){return v.swap(e,{display:"inline-block"},function(){if(t)return Dt(e,"marginRight")})}}),!v.support.pixelPosition&&v.fn.position&&v.each(["top","left"],function(e,t){v.cssHooks[t]={get:function(e,n){if(n){var r=Dt(e,t);return Ut.test(r)?v(e).position()[t]+"px":r}}}})}),v.expr&&v.expr.filters&&(v.expr.filters.hidden=function(e){return e.offsetWidth===0&&e.offsetHeight===0||!v.support.reliableHiddenOffsets&&(e.style&&e.style.display||Dt(e,"display"))==="none"},v.expr.filters.visible=function(e){return!v.expr.filters.hidden(e)}),v.each({margin:"",padding:"",border:"Width"},function(e,t){v.cssHooks[e+t]={expand:function(n){var r,i=typeof n=="string"?n.split(" "):[n],s={};for(r=0;r<4;r++)s[e+$t[r]+t]=i[r]||i[r-2]||i[0];return s}},qt.test(e)||(v.cssHooks[e+t].set=Zt)});var rn=/%20/g,sn=/\[\]$/,on=/\r?\n/g,un=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,an=/^(?:select|textarea)/i;v.fn.extend({serialize:function(){return v.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?v.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||an.test(this.nodeName)||un.test(this.type))}).map(function(e,t){var n=v(this).val();return n==null?null:v.isArray(n)?v.map(n,function(e,n){return{name:t.name,value:e.replace(on,"\r\n")}}):{name:t.name,value:n.replace(on,"\r\n")}}).get()}}),v.param=function(e,n){var r,i=[],s=function(e,t){t=v.isFunction(t)?t():t==null?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};n===t&&(n=v.ajaxSettings&&v.ajaxSettings.traditional);if(v.isArray(e)||e.jquery&&!v.isPlainObject(e))v.each(e,function(){s(this.name,this.value)});else for(r in e)fn(r,e[r],n,s);return i.join("&").replace(rn,"+")};var ln,cn,hn=/#.*$/,pn=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,dn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,vn=/^(?:GET|HEAD)$/,mn=/^\/\//,gn=/\?/,yn=/)<[^<]*)*<\/script>/gi,bn=/([?&])_=[^&]*/,wn=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,En=v.fn.load,Sn={},xn={},Tn=["*/"]+["*"];try{cn=s.href}catch(Nn){cn=i.createElement("a"),cn.href="",cn=cn.href}ln=wn.exec(cn.toLowerCase())||[],v.fn.load=function(e,n,r){if(typeof e!="string"&&En)return En.apply(this,arguments);if(!this.length)return this;var i,s,o,u=this,a=e.indexOf(" ");return a>=0&&(i=e.slice(a,e.length),e=e.slice(0,a)),v.isFunction(n)?(r=n,n=t):n&&typeof n=="object"&&(s="POST"),v.ajax({url:e,type:s,dataType:"html",data:n,complete:function(e,t){r&&u.each(r,o||[e.responseText,t,e])}}).done(function(e){o=arguments,u.html(i?v("
").append(e.replace(yn,"")).find(i):e)}),this},v.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){v.fn[t]=function(e){return this.on(t,e)}}),v.each(["get","post"],function(e,n){v[n]=function(e,r,i,s){return v.isFunction(r)&&(s=s||i,i=r,r=t),v.ajax({type:n,url:e,data:r,success:i,dataType:s})}}),v.extend({getScript:function(e,n){return v.get(e,t,n,"script")},getJSON:function(e,t,n){return v.get(e,t,n,"json")},ajaxSetup:function(e,t){return t?Ln(e,v.ajaxSettings):(t=e,e=v.ajaxSettings),Ln(e,t),e},ajaxSettings:{url:cn,isLocal:dn.test(ln[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Tn},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":v.parseJSON,"text xml":v.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:Cn(Sn),ajaxTransport:Cn(xn),ajax:function(e,n){function T(e,n,s,a){var l,y,b,w,S,T=n;if(E===2)return;E=2,u&&clearTimeout(u),o=t,i=a||"",x.readyState=e>0?4:0,s&&(w=An(c,x,s));if(e>=200&&e<300||e===304)c.ifModified&&(S=x.getResponseHeader("Last-Modified"),S&&(v.lastModified[r]=S),S=x.getResponseHeader("Etag"),S&&(v.etag[r]=S)),e===304?(T="notmodified",l=!0):(l=On(c,w),T=l.state,y=l.data,b=l.error,l=!b);else{b=T;if(!T||e)T="error",e<0&&(e=0)}x.status=e,x.statusText=(n||T)+"",l?d.resolveWith(h,[y,T,x]):d.rejectWith(h,[x,T,b]),x.statusCode(g),g=t,f&&p.trigger("ajax"+(l?"Success":"Error"),[x,c,l?y:b]),m.fireWith(h,[x,T]),f&&(p.trigger("ajaxComplete",[x,c]),--v.active||v.event.trigger("ajaxStop"))}typeof e=="object"&&(n=e,e=t),n=n||{};var r,i,s,o,u,a,f,l,c=v.ajaxSetup({},n),h=c.context||c,p=h!==c&&(h.nodeType||h instanceof v)?v(h):v.event,d=v.Deferred(),m=v.Callbacks("once memory"),g=c.statusCode||{},b={},w={},E=0,S="canceled",x={readyState:0,setRequestHeader:function(e,t){if(!E){var n=e.toLowerCase();e=w[n]=w[n]||e,b[e]=t}return this},getAllResponseHeaders:function(){return E===2?i:null},getResponseHeader:function(e){var n;if(E===2){if(!s){s={};while(n=pn.exec(i))s[n[1].toLowerCase()]=n[2]}n=s[e.toLowerCase()]}return n===t?null:n},overrideMimeType:function(e){return E||(c.mimeType=e),this},abort:function(e){return e=e||S,o&&o.abort(e),T(0,e),this}};d.promise(x),x.success=x.done,x.error=x.fail,x.complete=m.add,x.statusCode=function(e){if(e){var t;if(E<2)for(t in e)g[t]=[g[t],e[t]];else t=e[x.status],x.always(t)}return this},c.url=((e||c.url)+"").replace(hn,"").replace(mn,ln[1]+"//"),c.dataTypes=v.trim(c.dataType||"*").toLowerCase().split(y),c.crossDomain==null&&(a=wn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===ln[1]&&a[2]===ln[2]&&(a[3]||(a[1]==="http:"?80:443))==(ln[3]||(ln[1]==="http:"?80:443)))),c.data&&c.processData&&typeof c.data!="string"&&(c.data=v.param(c.data,c.traditional)),kn(Sn,c,n,x);if(E===2)return x;f=c.global,c.type=c.type.toUpperCase(),c.hasContent=!vn.test(c.type),f&&v.active++===0&&v.event.trigger("ajaxStart");if(!c.hasContent){c.data&&(c.url+=(gn.test(c.url)?"&":"?")+c.data,delete c.data),r=c.url;if(c.cache===!1){var N=v.now(),C=c.url.replace(bn,"$1_="+N);c.url=C+(C===c.url?(gn.test(c.url)?"&":"?")+"_="+N:"")}}(c.data&&c.hasContent&&c.contentType!==!1||n.contentType)&&x.setRequestHeader("Content-Type",c.contentType),c.ifModified&&(r=r||c.url,v.lastModified[r]&&x.setRequestHeader("If-Modified-Since",v.lastModified[r]),v.etag[r]&&x.setRequestHeader("If-None-Match",v.etag[r])),x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+Tn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)x.setRequestHeader(l,c.headers[l]);if(!c.beforeSend||c.beforeSend.call(h,x,c)!==!1&&E!==2){S="abort";for(l in{success:1,error:1,complete:1})x[l](c[l]);o=kn(xn,c,n,x);if(!o)T(-1,"No Transport");else{x.readyState=1,f&&p.trigger("ajaxSend",[x,c]),c.async&&c.timeout>0&&(u=setTimeout(function(){x.abort("timeout")},c.timeout));try{E=1,o.send(b,T)}catch(k){if(!(E<2))throw k;T(-1,k)}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var Mn=[],_n=/\?/,Dn=/(=)\?(?=&|$)|\?\?/,Pn=v.now();v.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Mn.pop()||v.expando+"_"+Pn++;return this[e]=!0,e}}),v.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,a=n.data,f=n.url,l=n.jsonp!==!1,c=l&&Dn.test(f),h=l&&!c&&typeof a=="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Dn.test(a);if(n.dataTypes[0]==="jsonp"||c||h)return s=n.jsonpCallback=v.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,o=e[s],c?n.url=f.replace(Dn,"$1"+s):h?n.data=a.replace(Dn,"$1"+s):l&&(n.url+=(_n.test(f)?"&":"?")+n.jsonp+"="+s),n.converters["script json"]=function(){return u||v.error(s+" was not called"),u[0]},n.dataTypes[0]="json",e[s]=function(){u=arguments},i.always(function(){e[s]=o,n[s]&&(n.jsonpCallback=r.jsonpCallback,Mn.push(s)),u&&v.isFunction(o)&&o(u[0]),u=o=t}),"script"}),v.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return v.globalEval(e),e}}}),v.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),v.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=i.head||i.getElementsByTagName("head")[0]||i.documentElement;return{send:function(s,o){n=i.createElement("script"),n.async="async",e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,i){if(i||!n.readyState||/loaded|complete/.test(n.readyState))n.onload=n.onreadystatechange=null,r&&n.parentNode&&r.removeChild(n),n=t,i||o(200,"success")},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(0,1)}}}});var Hn,Bn=e.ActiveXObject?function(){for(var e in Hn)Hn[e](0,1)}:!1,jn=0;v.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&Fn()||In()}:Fn,function(e){v.extend(v.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(v.ajaxSettings.xhr()),v.support.ajax&&v.ajaxTransport(function(n){if(!n.crossDomain||v.support.cors){var r;return{send:function(i,s){var o,u,a=n.xhr();n.username?a.open(n.type,n.url,n.async,n.username,n.password):a.open(n.type,n.url,n.async);if(n.xhrFields)for(u in n.xhrFields)a[u]=n.xhrFields[u];n.mimeType&&a.overrideMimeType&&a.overrideMimeType(n.mimeType),!n.crossDomain&&!i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest");try{for(u in i)a.setRequestHeader(u,i[u])}catch(f){}a.send(n.hasContent&&n.data||null),r=function(e,i){var u,f,l,c,h;try{if(r&&(i||a.readyState===4)){r=t,o&&(a.onreadystatechange=v.noop,Bn&&delete Hn[o]);if(i)a.readyState!==4&&a.abort();else{u=a.status,l=a.getAllResponseHeaders(),c={},h=a.responseXML,h&&h.documentElement&&(c.xml=h);try{c.text=a.responseText}catch(p){}try{f=a.statusText}catch(p){f=""}!u&&n.isLocal&&!n.crossDomain?u=c.text?200:404:u===1223&&(u=204)}}}catch(d){i||s(-1,d)}c&&s(u,f,c,l)},n.async?a.readyState===4?setTimeout(r,0):(o=++jn,Bn&&(Hn||(Hn={},v(e).unload(Bn)),Hn[o]=r),a.onreadystatechange=r):r()},abort:function(){r&&r(0,1)}}}});var qn,Rn,Un=/^(?:toggle|show|hide)$/,zn=new RegExp("^(?:([-+])=|)("+m+")([a-z%]*)$","i"),Wn=/queueHooks$/,Xn=[Gn],Vn={"*":[function(e,t){var n,r,i=this.createTween(e,t),s=zn.exec(t),o=i.cur(),u=+o||0,a=1,f=20;if(s){n=+s[2],r=s[3]||(v.cssNumber[e]?"":"px");if(r!=="px"&&u){u=v.css(i.elem,e,!0)||n||1;do a=a||".5",u/=a,v.style(i.elem,e,u+r);while(a!==(a=i.cur()/o)&&a!==1&&--f)}i.unit=r,i.start=u,i.end=s[1]?u+(s[1]+1)*n:n}return i}]};v.Animation=v.extend(Kn,{tweener:function(e,t){v.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;r-1,f={},l={},c,h;a?(l=i.position(),c=l.top,h=l.left):(c=parseFloat(o)||0,h=parseFloat(u)||0),v.isFunction(t)&&(t=t.call(e,n,s)),t.top!=null&&(f.top=t.top-s.top+c),t.left!=null&&(f.left=t.left-s.left+h),"using"in t?t.using.call(e,f):i.css(f)}},v.fn.extend({position:function(){if(!this[0])return;var e=this[0],t=this.offsetParent(),n=this.offset(),r=er.test(t[0].nodeName)?{top:0,left:0}:t.offset();return n.top-=parseFloat(v.css(e,"marginTop"))||0,n.left-=parseFloat(v.css(e,"marginLeft"))||0,r.top+=parseFloat(v.css(t[0],"borderTopWidth"))||0,r.left+=parseFloat(v.css(t[0],"borderLeftWidth"))||0,{top:n.top-r.top,left:n.left-r.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||i.body;while(e&&!er.test(e.nodeName)&&v.css(e,"position")==="static")e=e.offsetParent;return e||i.body})}}),v.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);v.fn[e]=function(i){return v.access(this,function(e,i,s){var o=tr(e);if(s===t)return o?n in o?o[n]:o.document.documentElement[i]:e[i];o?o.scrollTo(r?v(o).scrollLeft():s,r?s:v(o).scrollTop()):e[i]=s},e,i,arguments.length,null)}}),v.each({Height:"height",Width:"width"},function(e,n){v.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){v.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!="boolean"),u=r||(i===!0||s===!0?"margin":"border");return v.access(this,function(n,r,i){var s;return v.isWindow(n)?n.document.documentElement["client"+e]:n.nodeType===9?(s=n.documentElement,Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])):i===t?v.css(n,r,i,u):v.style(n,r,i,u)},n,o?i:t,o,null)}})}),e.jQuery=e.$=v,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return v})})(window);sip-4.15.5/doc/html/_static/logo.png0000644000076500000240000000761312125131242017265 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.15.5/doc/html/_static/logo_tn.ico0000644000076500000240000000217612125131242017753 0ustar philstaff00000000000000 h(  @ݱݱݱݱݱݱݱݱݱݱݱݱݱݱݱݱ|[|[|[|[|[|[|[|[|[|[|[|[|[|[|[|[Ʀťͱ˯PQ˯βݱstݱááܯܯݰTTݰݱIIݱݰeeݰ޲޲ε##δۭۭۭ~ۭ~ڪz|,,|ڪzsip-4.15.5/doc/html/_static/minus.png0000644000076500000240000000030712307277337017473 0ustar philstaff00000000000000PNG  IHDR &q pHYs  tIME <8tEXtComment̖RIDATcz(BpipPc |IENDB`sip-4.15.5/doc/html/_static/pygments.css0000644000076500000240000000753412310606653020212 0ustar philstaff00000000000000.highlight .hll { background-color: #ffffcc } .highlight { background: #eeffcc; } .highlight .c { color: #408090; font-style: italic } /* Comment */ .highlight .err { border: 1px solid #FF0000 } /* Error */ .highlight .k { color: #007020; font-weight: bold } /* Keyword */ .highlight .o { color: #666666 } /* Operator */ .highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ .highlight .cp { color: #007020 } /* Comment.Preproc */ .highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ .highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #A00000 } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #FF0000 } /* Generic.Error */ .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ .highlight .gi { color: #00A000 } /* Generic.Inserted */ .highlight .go { color: #333333 } /* Generic.Output */ .highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ .highlight .gt { color: #0044DD } /* Generic.Traceback */ .highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #007020 } /* Keyword.Pseudo */ .highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #902000 } /* Keyword.Type */ .highlight .m { color: #208050 } /* Literal.Number */ .highlight .s { color: #4070a0 } /* Literal.String */ .highlight .na { color: #4070a0 } /* Name.Attribute */ .highlight .nb { color: #007020 } /* Name.Builtin */ .highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ .highlight .no { color: #60add5 } /* Name.Constant */ .highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ .highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ .highlight .ne { color: #007020 } /* Name.Exception */ .highlight .nf { color: #06287e } /* Name.Function */ .highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ .highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ .highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #bb60d5 } /* Name.Variable */ .highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mf { color: #208050 } /* Literal.Number.Float */ .highlight .mh { color: #208050 } /* Literal.Number.Hex */ .highlight .mi { color: #208050 } /* Literal.Number.Integer */ .highlight .mo { color: #208050 } /* Literal.Number.Oct */ .highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ .highlight .sc { color: #4070a0 } /* Literal.String.Char */ .highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ .highlight .s2 { color: #4070a0 } /* Literal.String.Double */ .highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ .highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ .highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ .highlight .sx { color: #c65d09 } /* Literal.String.Other */ .highlight .sr { color: #235388 } /* Literal.String.Regex */ .highlight .s1 { color: #4070a0 } /* Literal.String.Single */ .highlight .ss { color: #517918 } /* Literal.String.Symbol */ .highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ .highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ .highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ .highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ .highlight .il { color: #208050 } /* Literal.Number.Integer.Long */sip-4.15.5/doc/html/_static/searchtools.js0000644000076500000240000004270212310606653020512 0ustar philstaff00000000000000/* * searchtools.js_t * ~~~~~~~~~~~~~~~~ * * Sphinx JavaScript utilties for the full-text search. * * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ /** * Porter Stemmer */ var Stemmer = function() { var step2list = { ational: 'ate', tional: 'tion', enci: 'ence', anci: 'ance', izer: 'ize', bli: 'ble', alli: 'al', entli: 'ent', eli: 'e', ousli: 'ous', ization: 'ize', ation: 'ate', ator: 'ate', alism: 'al', iveness: 'ive', fulness: 'ful', ousness: 'ous', aliti: 'al', iviti: 'ive', biliti: 'ble', logi: 'log' }; var step3list = { icate: 'ic', ative: '', alize: 'al', iciti: 'ic', ical: 'ic', ful: '', ness: '' }; var c = "[^aeiou]"; // consonant var v = "[aeiouy]"; // vowel var C = c + "[^aeiouy]*"; // consonant sequence var V = v + "[aeiou]*"; // vowel sequence var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 var s_v = "^(" + C + ")?" + v; // vowel in stem this.stemWord = function (w) { var stem; var suffix; var firstch; var origword = w; if (w.length < 3) return w; var re; var re2; var re3; var re4; firstch = w.substr(0,1); if (firstch == "y") w = firstch.toUpperCase() + w.substr(1); // Step 1a re = /^(.+?)(ss|i)es$/; re2 = /^(.+?)([^s])s$/; if (re.test(w)) w = w.replace(re,"$1$2"); else if (re2.test(w)) w = w.replace(re2,"$1$2"); // Step 1b re = /^(.+?)eed$/; re2 = /^(.+?)(ed|ing)$/; if (re.test(w)) { var fp = re.exec(w); re = new RegExp(mgr0); if (re.test(fp[1])) { re = /.$/; w = w.replace(re,""); } } else if (re2.test(w)) { var fp = re2.exec(w); stem = fp[1]; re2 = new RegExp(s_v); if (re2.test(stem)) { w = stem; re2 = /(at|bl|iz)$/; re3 = new RegExp("([^aeiouylsz])\\1$"); re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); if (re2.test(w)) w = w + "e"; else if (re3.test(w)) { re = /.$/; w = w.replace(re,""); } else if (re4.test(w)) w = w + "e"; } } // Step 1c re = /^(.+?)y$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; re = new RegExp(s_v); if (re.test(stem)) w = stem + "i"; } // Step 2 re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; suffix = fp[2]; re = new RegExp(mgr0); if (re.test(stem)) w = stem + step2list[suffix]; } // Step 3 re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; suffix = fp[2]; re = new RegExp(mgr0); if (re.test(stem)) w = stem + step3list[suffix]; } // Step 4 re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; re2 = /^(.+?)(s|t)(ion)$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; re = new RegExp(mgr1); if (re.test(stem)) w = stem; } else if (re2.test(w)) { var fp = re2.exec(w); stem = fp[1] + fp[2]; re2 = new RegExp(mgr1); if (re2.test(stem)) w = stem; } // Step 5 re = /^(.+?)e$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; re = new RegExp(mgr1); re2 = new RegExp(meq1); re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) w = stem; } re = /ll$/; re2 = new RegExp(mgr1); if (re.test(w) && re2.test(w)) { re = /.$/; w = w.replace(re,""); } // and turn initial Y back to y if (firstch == "y") w = firstch.toLowerCase() + w.substr(1); return w; } } /** * Simple result scoring code. */ var Scorer = { // Implement the following function to further tweak the score for each result // The function takes a result array [filename, title, anchor, descr, score] // and returns the new score. /* score: function(result) { return result[4]; }, */ // query matches the full name of an object objNameMatch: 11, // or matches in the last dotted part of the object name objPartialMatch: 6, // Additive scores depending on the priority of the object objPrio: {0: 15, // used to be importantResults 1: 5, // used to be objectResults 2: -5}, // used to be unimportantResults // Used when the priority is not in the mapping. objPrioDefault: 0, // query found in title title: 15, // query found in terms term: 5 }; /** * Search Module */ var Search = { _index : null, _queued_query : null, _pulse_status : -1, init : function() { var params = $.getQueryParameters(); if (params.q) { var query = params.q[0]; $('input[name="q"]')[0].value = query; this.performSearch(query); } }, loadIndex : function(url) { $.ajax({type: "GET", url: url, data: null, dataType: "script", cache: true, complete: function(jqxhr, textstatus) { if (textstatus != "success") { document.getElementById("searchindexloader").src = url; } }}); }, setIndex : function(index) { var q; this._index = index; if ((q = this._queued_query) !== null) { this._queued_query = null; Search.query(q); } }, hasIndex : function() { return this._index !== null; }, deferQuery : function(query) { this._queued_query = query; }, stopPulse : function() { this._pulse_status = 0; }, startPulse : function() { if (this._pulse_status >= 0) return; function pulse() { var i; Search._pulse_status = (Search._pulse_status + 1) % 4; var dotString = ''; for (i = 0; i < Search._pulse_status; i++) dotString += '.'; Search.dots.text(dotString); if (Search._pulse_status > -1) window.setTimeout(pulse, 500); } pulse(); }, /** * perform a search for something (or wait until index is loaded) */ performSearch : function(query) { // create the required interface elements this.out = $('#search-results'); this.title = $('

' + _('Searching') + '

').appendTo(this.out); this.dots = $('').appendTo(this.title); this.status = $('

').appendTo(this.out); this.output = $('
'); } // Prettify the comment rating. comment.pretty_rating = comment.rating + ' point' + (comment.rating == 1 ? '' : 's'); // Make a class (for displaying not yet moderated comments differently) comment.css_class = comment.displayed ? '' : ' moderate'; // Create a div for this comment. var context = $.extend({}, opts, comment); var div = $(renderTemplate(commentTemplate, context)); // If the user has voted on this comment, highlight the correct arrow. if (comment.vote) { var direction = (comment.vote == 1) ? 'u' : 'd'; div.find('#' + direction + 'v' + comment.id).hide(); div.find('#' + direction + 'u' + comment.id).show(); } if (opts.moderator || comment.text != '[deleted]') { div.find('a.reply').show(); if (comment.proposal_diff) div.find('#sp' + comment.id).show(); if (opts.moderator && !comment.displayed) div.find('#cm' + comment.id).show(); if (opts.moderator || (opts.username == comment.username)) div.find('#dc' + comment.id).show(); } return div; } /** * A simple template renderer. Placeholders such as <%id%> are replaced * by context['id'] with items being escaped. Placeholders such as <#id#> * are not escaped. */ function renderTemplate(template, context) { var esc = $(document.createElement('div')); function handle(ph, escape) { var cur = context; $.each(ph.split('.'), function() { cur = cur[this]; }); return escape ? esc.text(cur || "").html() : cur; } return template.replace(/<([%#])([\w\.]*)\1>/g, function() { return handle(arguments[2], arguments[1] == '%' ? true : false); }); } /** Flash an error message briefly. */ function showError(message) { $(document.createElement('div')).attr({'class': 'popup-error'}) .append($(document.createElement('div')) .attr({'class': 'error-message'}).text(message)) .appendTo('body') .fadeIn("slow") .delay(2000) .fadeOut("slow"); } /** Add a link the user uses to open the comments popup. */ $.fn.comment = function() { return this.each(function() { var id = $(this).attr('id').substring(1); var count = COMMENT_METADATA[id]; var title = count + ' comment' + (count == 1 ? '' : 's'); var image = count > 0 ? opts.commentBrightImage : opts.commentImage; var addcls = count == 0 ? ' nocomment' : ''; $(this) .append( $(document.createElement('a')).attr({ href: '#', 'class': 'sphinx-comment-open' + addcls, id: 'ao' + id }) .append($(document.createElement('img')).attr({ src: image, alt: 'comment', title: title })) .click(function(event) { event.preventDefault(); show($(this).attr('id').substring(2)); }) ) .append( $(document.createElement('a')).attr({ href: '#', 'class': 'sphinx-comment-close hidden', id: 'ah' + id }) .append($(document.createElement('img')).attr({ src: opts.closeCommentImage, alt: 'close', title: 'close' })) .click(function(event) { event.preventDefault(); hide($(this).attr('id').substring(2)); }) ); }); }; var opts = { processVoteURL: '/_process_vote', addCommentURL: '/_add_comment', getCommentsURL: '/_get_comments', acceptCommentURL: '/_accept_comment', deleteCommentURL: '/_delete_comment', commentImage: '/static/_static/comment.png', closeCommentImage: '/static/_static/comment-close.png', loadingImage: '/static/_static/ajax-loader.gif', commentBrightImage: '/static/_static/comment-bright.png', upArrow: '/static/_static/up.png', downArrow: '/static/_static/down.png', upArrowPressed: '/static/_static/up-pressed.png', downArrowPressed: '/static/_static/down-pressed.png', voting: false, moderator: false }; if (typeof COMMENT_OPTIONS != "undefined") { opts = jQuery.extend(opts, COMMENT_OPTIONS); } var popupTemplate = '\
\

\ Sort by:\ best rated\ newest\ oldest\

\
Comments
\
\ loading comments...
\
    \
    \

    Add a comment\ (markup):

    \
    \ reStructured text markup: *emph*, **strong**, \ ``code``, \ code blocks: :: and an indented block after blank line
    \
    \ \

    \ \ Propose a change ▹\ \ \ Propose a change ▿\ \

    \ \ \ \ \ \
    \
    '; var commentTemplate = '\
    \
    \
    \ \ \ \ \ \ \
    \
    \ \ \ \ \ \ \
    \
    \
    \

    \ <%username%>\ <%pretty_rating%>\ <%time.delta%>\

    \
    <#text#>
    \

    \ \ reply ▿\ proposal ▹\ proposal ▿\ \ \

    \
    \
    <#proposal_diff#>\
            
    \
      \
      \
      \
      \ '; var replyTemplate = '\
    • \
      \
      \ \ \ \ \ \ \
      \
    • '; $(document).ready(function() { init(); }); })(jQuery); $(document).ready(function() { // add comment anchors for all paragraphs that are commentable $('.sphinx-has-comment').comment(); // highlight search words in search results $("div.context").each(function() { var params = $.getQueryParameters(); var terms = (params.q) ? params.q[0].split(/\s+/) : []; var result = $(this); $.each(terms, function() { result.highlightText(this.toLowerCase(), 'highlighted'); }); }); // directly open comment window if requested var anchor = document.location.hash; if (anchor.substring(0, 9) == '#comment-') { $('#ao' + anchor.substring(9)).click(); document.location.hash = '#s' + anchor.substring(9); } }); sip-4.15.5/doc/html/annotations.html0000644000076500000240000025075712310606647017441 0ustar philstaff00000000000000 Annotations — SIP 4.15.5 Reference Guide

      Annotations

      In this section we describe each of the annotations that can be used in specification files.

      Annotations can either be argument annotations, class annotations, mapped type annotations, enum annotations, exception annotations, function annotations, typedef annotations or 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 %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/;
      

      Argument Annotations

      AllowNone

      This boolean annotation specifies that the value of the corresponding argument (which should be either SIP_PYBUFFER, SIP_PYCALLABLE, SIP_PYDICT, SIP_PYLIST, SIP_PYSLICE, SIP_PYTUPLE or SIP_PYTYPE) may be None.

      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 Encoding annotation with an encoding of "None".

      There must be a corresponding argument with the ArraySize annotation specified. The annotation may only be specified once in a list of arguments.

      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 Array annotation specified. The annotation may only be specified once in a list of arguments.

      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 %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);
      
      DocType

      New in version 4.10.

      This string annotation specifies the type of the argument as it will appear in any generated docstrings. It is usually used with arguments of type SIP_PYOBJECT to provide a more specific type.

      DocValue

      New in version 4.10.

      This string annotation specifies the default value of the argument as it will appear in any generated docstrings.

      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 %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.

      GetWrapper

      This boolean annotation is only ever used in conjunction with handwritten code specified with the %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 %MethodCode directive for more detail.

      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 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 In and Out may be specified for the same argument.

      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 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.

      NoCopy

      New in version 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++.

      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 In annotation is specified.

      Both In and Out may be specified for the same argument.

      PyInt

      New in version 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.

      ResultSize

      This boolean annotation is used with functions or methods that return a void * or const void *. It identifies an argument that defines the size of the block of memory whose address is being returned. This allows the sip.voidptr object that wraps the address to support the Python buffer protocol.

      SingleShot

      This boolean annotation is used only with arguments of type 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.

      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 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 Ownership of Objects for more detail.

      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 Ownership of Objects for more detail.

      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 Ownership of Objects for more detail.

      Class Annotations

      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.

      AllowNone

      New in version 4.8.2.

      Normally when a Python object is converted to a C/C++ instance None is handled automatically before the class’s %ConvertToTypeCode is called. This boolean annotation specifies that the handling of None will be left to the %ConvertToTypeCode. The annotation is ignored if the class does not have any %ConvertToTypeCode.

      API

      New in version 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 Managing Incompatible APIs for more detail.

      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 sipDelayedDtors() is called with the list of delayed instances. sipDelayedDtors() can then choose to call (or ignore) the destructors in any desired order.

      The sipDelayedDtors() function must be specified using the %ModuleCode directive.

      void sipDelayedDtors(const sipDelayedDtor *dd_list)
      Parameters:
      • dd_list – the linked list of delayed instances.
      sipDelayedDtor

      This structure describes a particular delayed destructor.

      const char* dd_name

      This is the name of the class excluding any package or module name.

      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 dd_isderived.

      int dd_isderived

      This is non-zero if the type of dd_ptr is actually the generated derived class. This allows the correct destructor to be called. See Generated Derived Classes.

      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.

      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.

      ExportDerived

      New in version 4.15.

      In many cases SIP generates a derived class for each class being wrapped (see Generated 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.

      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.

      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 Types and Meta-types for more details.

      Mixin

      New in version 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.
      NoDefaultCtors

      This boolean annotation is used to suppress the automatic generation of default constructors for the class.

      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.

      See also

      %AutoPyName

      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 Types and Meta-types for more details.

      VirtualErrorHandler

      New in version 4.14.

      This name annotation specifies the handler (defined by the %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 %Module directive is used.

      Mapped Type Annotations

      AllowNone

      Normally when a Python object is converted to a C/C++ instance None is handled automatically before the mapped type’s %ConvertToTypeCode is called. This boolean annotation specifies that the handling of None will be left to the %ConvertToTypeCode.

      API

      New in version 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 Managing Incompatible APIs for more detail.

      DocType

      New in version 4.10.

      This string annotation serves the same purpose as the DocType argument annotation when applied to the mapped type being defined.

      NoRelease

      This boolean annotation is used to specify that the mapped type does not support the sipReleaseType() function. Any %ConvertToTypeCode should not create temporary instances of the mapped type, i.e. it should not return SIP_TEMPORARY.

      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.

      See also

      %AutoPyName

      Enum Annotations

      NoScope

      New in version 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.

      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.

      See also

      %AutoPyName

      Exception Annotations

      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.

      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.

      See also

      %AutoPyName

      Function Annotations

      API

      New in version 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 Managing Incompatible APIs for more detail.

      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 %Feature directive) which must be enabled for the method to be generated.

      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 %InstanceCode.

      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.

      DocType

      New in version 4.10.

      This string annotation serves the same purpose as the DocType argument annotation when applied to the type of the value returned by the function.

      Encoding

      This string annotation serves the same purpose as the Encoding argument annotation when applied to the type of the value returned by the function.

      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 Ownership of Objects for more detail.

      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 The Python Global Interpreter Lock and the ReleaseGIL annotation.

      KeepReference

      New in version 4.12.2.

      This optional integer annotation serves the same purpose as the 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.

      KeywordArgs

      New in version 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 %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 since version 4.12: It can also be used as a boolean annotation which is the equivalent of specifiying a value of "All".

      __len__

      New in version 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.

      NewThread

      This boolean annotation specifies that the function will create a new thread.

      NoArgParser

      This boolean annotation is used with methods and global functions to specify that the supplied %MethodCode will handle the parsing of the arguments.

      NoCopy

      New in version 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++.

      NoDerived

      This boolean annotation is only used with C++ constructors. In many cases SIP generates a derived class for each class being wrapped (see Generated 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.

      NoKeywordArgs

      New in version 4.10.

      Deprecated since version 4.12: Use the 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 %Module directive, but you would still like certain functions to only support positional arguments.

      NoRaisesPyException

      New in version 4.13.1.

      This boolean annotation specifies that the function or constructor does not raise a Python exception to indicate that an error occurred.

      NoVirtualErrorHandler

      New in version 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 VirtualErrorHandler function annotation, the VirtualErrorHandler class annotation or the default_VirtualErrorHandler argument of the %Module directive is ignored.

      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 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 [], __getitem__(), __setitem__() or __delitem__() defined then it assumes that they should be sequence operators.

      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.

      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.

      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.

      See also

      %AutoPyName

      PyInt

      New in version 4.12.

      This boolean annotation serves the same purpose as the PyInt argument annotation when applied to the type of the value returned by the function.

      RaisesPyException

      New in version 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 %MethodCode directive is used.

      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 The Python Global Interpreter Lock and the HoldGIL annotation.

      Sequence

      New in version 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 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 [], __getitem__(), __setitem__() or __delitem__() defined then it assumes that they should be sequence operators.

      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 Ownership of Objects for more detail.

      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 Ownership of Objects for more detail.

      TransferThis

      This boolean annotation specifies that ownership of this is transferred from Python to C++.

      See Ownership of Objects for more detail.

      VirtualErrorHandler

      New in version 4.14.

      This name annotation specifies the handler (defined by the %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 VirtualErrorHandler is used.

      Typedef Annotations

      Capsule

      New in version 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 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 sip.voidptr is used instead and name based type checking is not performed.

      DocType

      New in version 4.10.

      This string annotation serves the same purpose as the DocType argument annotation when applied to the mapped type being defined.

      Encoding

      This string annotation serves the same purpose as the Encoding argument annotation when applied to the mapped type being defined.

      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.

      PyInt

      New in version 4.12.

      This boolean annotation serves the same purpose as the PyInt argument annotation when applied to the type being defined.

      PyName

      New in version 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.

      See also

      %AutoPyName

      Variable Annotations

      DocType

      New in version 4.10.

      This string annotation serves the same purpose as the DocType argument annotation when applied to the type of the variable being defined.

      Encoding

      This string annotation serves the same purpose as the Encoding argument annotation when applied to the type of the variable being defined.

      PyInt

      New in version 4.12.

      This boolean annotation serves the same purpose as the PyInt argument annotation when applied to the type of the variable being defined.

      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.

      See also

      %AutoPyName

      sip-4.15.5/doc/html/build_system.html0000644000076500000240000025734412310606650017600 0ustar philstaff00000000000000 The Build System — SIP 4.15.5 Reference Guide

      The Build System

      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 sipconfig that contains a number of classes and functions. Using this module you can write bespoke configuration scripts (e.g. PyQt’s configure.py) or use it with other Python based build systems (e.g. Distutils 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 PyQt but all three packages are maintained by different developers. To make this easier PyQt includes its own configuration module, pyqtconfig, that contains additional classes intended to be used by the configuration scripts of bindings built on top of PyQt. The SIP build system includes facilities that do a lot of the work of creating these additional configuration modules.

      sipconfig.create_config_module(module, template, content[, macros=None])

      This creates a configuration module (e.g. pyqtconfig) from a template file and a string.

      Parameters:
      • module – the name of the configuration module file to create.
      • template – the name of the template file.
      • 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 sipconfig.create_content(). content may also be a dictionary, in which case sipconfig.create_content() is automatically called to convert it to a string.
      • macros – an optional dictionary of platform specific build macros. It is only used if sipconfig.create_content() is called automatically to convert a content dictionary to a string.
      sipconfig.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 sipconfig.create_config_module().

      Parameters:
      • dict – the Python dictionary to convert.
      • macros – the optional dictionary of platform specific build macros.
      Returns:

      the string representation of the dictionary.

      sipconfig.create_wrapper(script, wrapper[, gui=0[, use_arch='']]) → string

      This creates a platform dependent executable wrapper around a Python script.

      Parameters:
      • script – the full pathname of the script.
      • wrapper – the full pathname of the wrapper to create, excluding any platform specific extension.
      • gui – is non-zero if a GUI enabled version of the interpreter should be used on platforms that require it.
      • 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.

      sipconfig.error(msg)

      This displays an error message on stderr and calls sys.exit(1).

      Parameters:msg – the text of the message and should not include any newline characters.
      sipconfig.format(msg[, leftmargin=0[, rightmargin=78]]) → string

      This formats a message by inserting newline characters at appropriate places.

      Parameters:
      • msg – the text of the message and should not include any newline characters.
      • leftmargin – the optional position of the left margin.
      • rightmargin – the optional position of the right margin.
      Returns:

      the formatted message.

      sipconfig.inform(msg)

      This displays an information message on stdout.

      Parameters:msg – the text of the message and should not include any newline characters.
      sipconfig.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.

      Parameters:
      • filename – the name of the file to parse.
      • names – the list of the macro names to extract from the file.
      • 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).
      • properties – the optional dictionary of property name and values that are used to resolve any expressions of the form $[name] in the file.
      Returns:

      the dictionary of parsed macros or None if any of the overrides were invalid.

      sipconfig.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.

      Parameters:
      • filename – the name of the file to read.
      • description – a descriptive name of the package used in error messages.
      • numdefine – the optional name of the #define of the version as a number. If it is None then the numeric version is ignored.
      • strdefine – the optional name of the #define of the version as a string. If it is None then the string version is ignored.
      Returns:

      a tuple of the numeric and string versions. sipconfig.error() is called if either were required but could not be found.

      sipconfig.version_to_sip_tag(version, tags, description) → string

      This converts a version number to a SIP version tag. SIP uses the %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.

      Parameters:
      • version – the numeric version number of the C/C++ library being wrapped. If it is negative then the latest version is assumed. (This is typically useful if a snapshot is indicated by a negative version number.)
      • 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.
      • description – a descriptive name of the C/C++ library used in error messages.
      Returns:

      the SIP version tag. sipconfig.error() is called if the C/C++ library version number did not correspond to a SIP version tag.

      sipconfig.version_to_string(v) → string

      This converts a 3 part version number encoded as a hexadecimal value to a string.

      Parameters:v – the version number.
      Returns:a string.
      class sipconfig.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:

      default_bin_dir

      The name of the directory where executables should be installed by default.

      default_mod_dir

      The name of the directory where SIP generated modules should be installed by default.

      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.

      platform

      The name of the platform/compiler for which the build system has been configured for.

      py_conf_inc_dir

      The name of the directory containing the pyconfig.h header file.

      py_inc_dir

      The name of the directory containing the Python.h header file.

      py_lib_dir

      The name of the directory containing the Python interpreter library.

      py_version

      The Python version as a 3 part hexadecimal number (e.g. v2.3.3 is represented as 0x020303).

      sip_bin

      The full pathname of the SIP executable.

      sip_config_args

      The command line passed to configure.py when SIP was configured.

      sip_inc_dir

      The name of the directory containing the sip.h header file.

      sip_mod_dir

      The name of the directory containing the SIP module.

      sip_version

      The SIP version as a 3 part hexadecimal number (e.g. v4.0.0 is represented as 0x040000).

      sip_version_str

      The SIP version as a string. For development snapshots it will start with snapshot-.

      universal

      The name of the MacOS/X SDK used when creating universal binaries.

      arch

      The space separated MacOS/X architectures to build.

      deployment_target

      The MacOS/X deployment target.

      __init__([sub_cfg=None])
      Parameters: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.
      build_macros() → dict

      Get the dictionary of platform specific build macros.

      Returns:the macros dictionary.
      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.

      Parameters:macros – the macros dictionary.
      class sipconfig.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:

      chkdir

      A string that will check for the existence of a directory.

      config

      A reference to the configuration argument that was passed to Makefile.__init__().

      console

      A reference to the console argument that was passed to the Makefile.__init__().

      copy

      A string that will copy a file.

      extra_cflags

      A list of additional flags passed to the C compiler.

      extra_cxxflags

      A list of additional flags passed to the C++ compiler.

      extra_defines

      A list of additional macro names passed to the C/C++ preprocessor.

      extra_include_dirs

      A list of additional include directories passed to the C/C++ preprocessor.

      extra_lflags

      A list of additional flags passed to the linker.

      extra_lib_dirs

      A list of additional library directories passed to the linker.

      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).

      generator

      A string that defines the platform specific style of Makefile. The only supported values are UNIX, MSVC, MSVC.NET, MINGW and BMAKE.

      mkdir

      A string that will create a directory.

      rm

      A string that will remove a file.

      __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]]]]]]]]]]]]])
      Parameters:
      • configuration – the current configuration and is an instance of the Configuration class or a sub-class.
      • console – is set if the target is a console (rather than GUI) target. This only affects Windows and is ignored on other platforms.
      • 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 uses Python.h.
      • threaded – is set if the target requires thread support. It is set automatically if the target uses Qt and Qt has thread support enabled.
      • 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.
      • debug – is set if debugging symbols should be generated.
      • 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.
      • makefile – the name of the generated Makefile.
      • 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.
      • 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.
      • arch – the space separated MacOS/X architectures to build. If it is None then the value is taken from the configuration.
      • deployment_target – the MacOS/X deployment target. If it is None then the value is taken from the configuration.
      clean_build_file_objects(mfile, build)

      This generates the Makefile commands that will remove any files generated during the build of the default target.

      Parameters:
      • mfile – the Python file object of the Makefile.
      • build – the dictionary created from parsing the build file.
      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.

      generate()

      This generates the Makefile.

      generate_macros_and_rules(mfile)

      This is the default implementation of the Makefile macros and rules generation.

      Parameters:mfile – the Python file object of the Makefile.
      generate_target_clean(mfile)

      This is the default implementation of the Makefile clean target generation.

      Parameters:mfile – the Python file object of the Makefile.
      generate_target_default(mfile)

      This is the default implementation of the Makefile default target generation.

      Parameters:mfile – the Python file object of the Makefile.
      generate_target_install(mfile)

      This is the default implementation of the Makefile install target generation.

      Parameters:mfile – the Python file object of the Makefile.
      install_file(mfile, src, dst[, strip=0])

      This generates the Makefile commands to install one or more files to a directory.

      Parameters:
      • mfile – the Python file object of the Makefile.
      • src – the name of a single file to install or a list of a number of files to install.
      • dst – the name of the destination directory.
      • strip – is set if the files should be stripped of unneeded symbols after having been installed.
      optional_list(name) → list

      This returns an optional Makefile macro as a list.

      Parameters:name – the name of the macro.
      Returns:the macro as a list.
      optional_string(name[, default=""])

      This returns an optional Makefile macro as a string.

      Parameters:
      • name – the name of the macro.
      • default – the optional default value of the macro.
      Returns:

      the macro as a string.

      parse_build_file(filename) → dict

      This parses a build file (created with the -b SIP command line option) and converts it to a dictionary. It can also validate an existing dictionary created through other means.

      Parameters: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.
      Returns:a dictionary corresponding to the parsed build file.
      platform_lib(clib[, framework=0]) → string

      This converts a library name to a platform specific form.

      Parameters:
      • clib – the name of the library in cannonical form.
      • framework – is set if the library is implemented as a MacOS framework.
      Returns:

      the platform specific name.

      ready()

      This is called to ensure that the Makefile is fully configured. It is normally called automatically when needed.

      required_string(name) → string

      This returns a required Makefile macro as a string.

      Parameters:name – the name of the macro.
      Returns:the macro as a string. An exception is raised if the macro does not exist or has an empty value.
      class sipconfig.ModuleMakefile

      This class is derived from sipconfig.Makefile.

      This class encapsulates a Makefile to build a generic Python extension module.

      __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]]]]]]]]]]]]]]])
      Parameters:
      finalise()

      This is a reimplementation of sipconfig.Makefile.finalise().

      generate_macros_and_rules(mfile)

      This is a reimplementation of sipconfig.Makefile.generate_macros_and_rules().

      generate_target_clean(mfile)

      This is a reimplementation of sipconfig.Makefile.generate_target_clean().

      generate_target_default(mfile)

      This is a reimplementation of sipconfig.Makefile.generate_target_default().

      generate_target_install(mfile)

      This is a reimplementation of sipconfig.Makefile.generate_target_install().

      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.

      Parameters:mname – the name of the module.
      Returns:the corresponding library name.
      class sipconfig.ParentMakefile

      This class is derived from sipconfig.Makefile.

      This class encapsulates a Makefile that sits above a number of other Makefiles in sub-directories.

      __init__(self, configuration, subdirs[, dir=None[, makefile[="Makefile"[, installs=None]]]])
      Parameters:
      generate_macros_and_rules(mfile)

      This is a reimplementation of sipconfig.Makefile.generate_macros_and_rules().

      generate_target_clean(mfile)

      This is a reimplementation of sipconfig.Makefile.generate_target_clean().

      generate_target_default(mfile)

      This is a reimplementation of sipconfig.Makefile.generate_target_default().

      generate_target_install(mfile)

      This is a reimplementation of sipconfig.Makefile.generate_target_install().

      class sipconfig.ProgramMakefile

      This class is derived from sipconfig.Makefile.

      This class encapsulates a Makefile to build an executable program.

      __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]]]]]]]]]]]]]]])
      Parameters:
      build_command(source) → string, string

      This creates a single command line that will create an executable program from a single source file.

      Parameters:source – the name of the source file.
      Returns:a tuple of the name of the executable that will be created and the command line.
      finalise()

      This is a reimplementation of sipconfig.Makefile.finalise().

      generate_macros_and_rules(mfile)

      This is a reimplementation of sipconfig.Makefile.generate_macros_and_rules().

      generate_target_clean(mfile)

      This is a reimplementation of sipconfig.Makefile.generate_target_clean().

      generate_target_default(mfile)

      This is a reimplementation of sipconfig.Makefile.generate_target_default().

      generate_target_install(mfile)

      This is a reimplementation of sipconfig.Makefile.generate_target_install().

      class sipconfig.PythonModuleMakefile

      This class is derived from sipconfig.Makefile.

      This class encapsulates a Makefile that installs a pure Python module.

      __init__(self, configuration, dstdir[, srcdir=None[, dir=None[, makefile="Makefile"[, installs=None]]]])
      Parameters:
      generate_macros_and_rules(mfile)

      This is a reimplementation of sipconfig.Makefile.generate_macros_and_rules().

      generate_target_install(mfile)

      This is a reimplementation of sipconfig.Makefile.generate_target_install().

      class sipconfig.SIPModuleMakefile

      This class is derived from sipconfig.ModuleMakefile.

      This class encapsulates a Makefile to build a SIP generated Python extension module.

      __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]]]]]]]]]]]]]]]])
      Parameters:
      finalise()

      This is a reimplementation of sipconfig.Makefile.finalise().

      Previous topic

      Python API for Applications

      Next topic

      Building Your Extension with distutils

      sip-4.15.5/doc/html/builtin.html0000644000076500000240000001635512310606650016536 0ustar philstaff00000000000000 Builtin Modules and Custom Interpreters — SIP 4.15.5 Reference Guide

      Builtin Modules and Custom Interpreters

      Sometimes you want to create a custom Python interpreter with some modules built in to the interpreter itself rather than being dynamically loaded. To do this the module must be created as a static library and linked with a custom stub and the normal Python library.

      To build the SIP module as a static library you must pass the -k command line option to configure.py. You should then build and install SIP as normal. (Note that, because the module is now a static library, you will not be able to import it.)

      To build a module you have created for your own library you must modify your own configuration script to pass a non-zero value as the static argument of the __init__() method of the sipconfig.ModuleMakefile class (or any derived class you have created). Normally you would make this configurable using a command line option in the same way that SIP’s configure.py handles it.

      The next stage is to create a custom stub and a Makefile. The SIP distribution contains a directory called custom which contains example stubs and a Python script that will create a correct Makefile. Note that, if your copy of SIP was part of a standard Linux distribution, the custom directory may not be installed on your system.

      The custom directory contains the following files. They are provided as examples - each needs to be modified according to your particular requirements.

      • mkcustom.py is a Python script that will create a Makefile which is then used to build the custom interpreter. Comments in the file describe how it should be modified.
      • custom.c is a stub for a custom interpreter on Linux/UNIX. It should also be used for a custom console interpreter on Windows (i.e. like python.exe). Comments in the file describe how it should be modified.
      • customw.c is a stub for a custom GUI interpreter on Windows (i.e. like pythonw.exe). Comments in the file describe how it should be modified.

      Note that this technique does not restrict how the interpreter can be used. For example, it still allows users to write their own applications that can import your builtin modules. If you want to prevent users from doing that, perhaps to protect a proprietary API, then take a look at the VendorID package.

      Previous topic

      Building Your Extension with distutils

      sip-4.15.5/doc/html/c_api.html0000644000076500000240000053760612310606651016153 0ustar philstaff00000000000000 C API for Handwritten Code — SIP 4.15.5 Reference Guide

      C API for Handwritten Code

      In this section we describe the API that can be used by handwritten code in specification files.

      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.

      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.

      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 SIP_UNBLOCK_THREADS at the same lexical scope.

      SIP_OWNS_MEMORY

      New in version 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.

      SIP_NO_CONVERTORS

      This is a flag used by various type convertors that suppresses the use of a type’s %ConvertToTypeCode.

      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.

      SIP_PROTECTED_IS_PUBLIC

      New in version 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 %MethodCode).

      SIP_READ_ONLY

      New in version 4.15.2.

      This is a flag used by various array constructors that species that the array is read-only.

      SIP_RELEASE_GIL(sip_gilstate_t sipGILState)

      New in version 4.14.4.

      This is called from the handwritten code specified with the 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.

      Parameters:
      • sipGILState – an opaque value provided to the handwritten code by SIP.
      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.

      SIP_SSIZE_T_FORMAT

      New in version 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.

      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 SIP_BLOCK_THREADS.

      SIP_USE_PYCAPSULE

      New in version 4.11.

      This is a C preprocessor symbol that is defined when PyCapsule objects are being used rather than the (now deprecated) PyCObject objects.

      SIP_VERSION

      This is a C preprocessor symbol that defines the SIP version number represented as a 3 part hexadecimal number (e.g. v4.0.0 is represented as 0x040000).

      SIP_VERSION_STR

      This is a C preprocessor symbol that defines the SIP version number represented as a string. For development snapshots it will start with snapshot-.

      sipErrorState sipBadCallableArg(int arg_nr, PyObject *arg)

      New in version 4.10.

      This is called from %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 %MethodCode does additional type checking of the supplied arguments.

      Parameters:
      • arg_nr – the number of the argument. Arguments are numbered from 0 but are numbered from 1 in the detail of the exception.
      • arg – the argument.
      Returns:

      the value that should be assigned to sipError.

      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 %VirtualCatcherCode directive.

      Parameters:
      • method – the Python method and would normally be the supplied sipMethod.
      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 __setitem__() methods.

      Parameters:
      • seqlen – the length of the sequence.
      • slicelen – the length of the slice.
      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 Py_BuildValue() function.

      Parameters:
      • iserr – if this is not NULL then the location it points to is set to a non-zero value.
      • format – the string of format characters.
      Returns:

      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 *, 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 *, SIP_SSIZE_T, const 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 *, sipWrapperType *, PyObject *]

      Deprecated since version 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 %ConvertToSubClassCode code.

      C (wrapped instance) [type *, sipWrapperType *, PyObject *]

      Deprecated since version 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 sipTransferBack(). Otherwise ownership is transferred to C/C++ and the instance associated with the PyObject * argument via a call to sipTransferTo(). The Python class is influenced by any applicable %ConvertToSubClassCode code.

      D (wrapped instance) [type *, const 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 sipTransferBack(). Otherwise ownership is transferred to C/C++ and the instance associated with the PyObject * argument via a call to sipTransferTo(). The Python class is influenced by any applicable %ConvertToSubClassCode code.
      E (wrapped enum) [enum, PyTypeObject *]

      Deprecated since version 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, sipTypeDef *]
      Convert a named C/C++ enum to an instance of the corresponding Python named enum type.
      G (unicode) [wchar_t *, 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]

      New in version 4.12.

      Convert a C/C++ char to a Python integer.

      M (long) [unsigned char]

      New in version 4.12.

      Convert a C/C++ unsigned char to a Python long.

      N (wrapped instance) [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 %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 sip.voidptr object.
      z (object) [const char *, void *]

      New in version 4.14.1.

      Convert a C/C++ void * to a Python named capsule object.

      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 PyObject_CallObject() function.

      Parameters:
      • iserr – if this is not NULL then the location it points to is set to a non-zero value if there was an error.
      • method – the Python bound method to call.
      • format – the string of format characters (see sipBuildResult()).
      Returns:

      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 %VirtualCatcherCode directive with method being the supplied sipMethod.

      int sipCanConvertToEnum(PyObject *obj, const sipTypeDef *td)

      This checks if a Python object can be converted to a named enum.

      Parameters:
      Returns:

      a non-zero value if the object can be converted.

      int sipCanConvertToInstance(PyObject *obj, sipWrapperType *type, int flags)

      Deprecated since version 4.8: Use sipCanConvertToType() instead.

      This checks if a Python object can be converted to an instance of a C structure or C++ class.

      Parameters:
      Returns:

      a non-zero value if the object can be converted.

      int sipCanConvertToMappedType(PyObject *obj, const sipMappedType *mt, int flags)

      Deprecated since version 4.8: Use 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.

      Parameters:
      Returns:

      a non-zero value if the object can be converted.

      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.

      Parameters:
      Returns:

      a non-zero value if the object can be converted.

      PyObject *sipClassName(PyObject *obj)

      Deprecated since version 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.

      Parameters:
      • obj – the wrapped instance.
      Returns:

      the name of the instance’s class.

      PyObject *sipConvertFromConstVoidPtr(const void *cpp)

      This creates a sip.voidptr object for a memory address. The object will not be writeable and has no associated size.

      Parameters:
      • cpp – the memory address.
      Returns:

      the sip.voidptr object.

      PyObject *sipConvertFromConstVoidPtrAndSize(const void *cpp, SIP_SSIZE_T size)

      This creates a sip.voidptr object for a memory address. The object will not be writeable and can be used as an immutable buffer object.

      Parameters:
      • cpp – the memory address.
      • size – the size associated with the address.
      Returns:

      the sip.voidptr object.

      PyObject *sipConvertFromEnum(int eval, const sipTypeDef *td)

      This converts a named C/C++ enum to an instance of the corresponding generated Python type.

      Parameters:
      Returns:

      the Python object.

      PyObject *sipConvertFromInstance(void *cpp, sipWrapperType *type, PyObject *transferObj)

      Deprecated since version 4.8: Use sipConvertFromType() instead.

      This converts a C structure or a C++ class instance to an instance of the corresponding generated Python type.

      Parameters:
      • cpp – the C/C++ instance.
      • type – the type’s generated type object.
      • transferObj – this controls the ownership of the returned value.
      Returns:

      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 sipTransferBack().

      Otherwise ownership is transferred to C/C++ and the instance associated with transferObj via a call to sipTransferTo().

      The Python type is influenced by any applicable %ConvertToSubClassCode code.

      PyObject *sipConvertFromMappedType(void *cpp, const sipMappedType *mt, PyObject *transferObj)

      Deprecated since version 4.8: Use 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.

      Parameters:
      • cpp – the C/C++ instance.
      • mt – the opaque structure returned by sipFindMappedType().
      • transferObj – this controls the ownership of the returned value.
      Returns:

      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 sipTransferBack().

      Otherwise ownership is transferred to C/C++ and the instance associated with transferObj argument via a call to sipTransferTo().

      PyObject *sipConvertFromNamedEnum(int eval, PyTypeObject *type)

      Deprecated since version 4.8: Use sipConvertFromEnum() instead.

      This converts a named C/C++ enum to an instance of the corresponding generated Python type.

      Parameters:
      Returns:

      the Python object.

      PyObject *sipConvertFromNewInstance(void *cpp, sipWrapperType *type, PyObject *transferObj)

      Deprecated since version 4.8: Use sipConvertFromNewType() instead.

      This converts a new C structure or a C++ class instance to an instance of the corresponding generated Python type.

      Parameters:
      • cpp – the C/C++ instance.
      • type – the type’s generated type object.
      • transferObj – this controls the ownership of the returned value.
      Returns:

      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 %ConvertToSubClassCode code.

      PyObject *sipConvertFromNewPyType(void *cpp, PyTypeObject *py_type, sipWrapper *owner, sipSimpleWrapper **selfp, const char *format, ...)

      New in version 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.

      Parameters:
      • cpp – the C/C++ instance.
      • 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.
      • owner – is the optional owner of the Python object.
      • 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.
      • format – the string of format characters (see sipBuildResult()).
      Returns:

      the Python object. If there was an error then NULL is returned and a Python exception is raised.

      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.

      Parameters:
      • cpp – the C/C++ instance.
      • td – the type’s generated type structure.
      • transferObj – this controls the ownership of the returned value.
      Returns:

      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 %ConvertToSubClassCode code.

      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.

      Parameters:
      • idx – the sequence index.
      • len – the length of the sequence.
      Returns:

      the unsigned array index.

      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 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.

      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.

      Parameters:
      • cpp – the C/C++ instance.
      • td – the type’s generated type structure.
      • transferObj – this controls the ownership of the returned value.
      Returns:

      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 sipTransferBack().

      Otherwise ownership is transferred to C/C++ and the instance associated with transferObj via a call to sipTransferTo().

      The Python class is influenced by any applicable %ConvertToSubClassCode code.

      PyObject *sipConvertFromVoidPtr(void *cpp)

      This creates a sip.voidptr object for a memory address. The object will be writeable but has no associated size.

      Parameters:
      • cpp – the memory address.
      Returns:

      the sip.voidptr object.

      PyObject *sipConvertFromVoidPtrAndSize(void *cpp, SIP_SSIZE_T size)

      This creates a sip.voidptr object for a memory address. The object will be writeable and can be used as a mutable buffer object.

      Parameters:
      • cpp – the memory address.
      • size – the size associated with the address.
      Returns:

      the sip.voidptr object.

      PyObject *sipConvertToArray(void *data, const char *format, SIP_SSIZE_T len, int flags)

      New in version 4.15.

      This converts a one dimensional array of fundamental types to a sip.array object.

      An array is very like a Python 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.

      sip.array objects are not supported by the sip code generator. They can only be created by handwritten code.

      Parameters:
      • data – the address of the start of the C/C++ array.
      • format – the format, as defined by the 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.
      • len – the number of elements in the array.
      • readonly – is non-zero if the array is read-only.
      • flags – any combination of the SIP_READ_ONLY and SIP_OWNS_MEMORY flags.
      Returns:

      the sip.array object.

      void *sipConvertToInstance(PyObject *obj, sipWrapperType *type, PyObject *transferObj, int flags, int *state, int *iserr)

      Deprecated since version 4.8: Use sipConvertToType() instead.

      This converts a Python object to an instance of a C structure or C++ class assuming that a previous call to sipCanConvertToInstance() has been successful.

      Parameters:
      • obj – the Python object.
      • type – the type’s generated type object.
      • transferObj – this controls any ownership changes to obj.
      • flags – any combination of the SIP_NOT_NONE and SIP_NO_CONVERTORS flags.
      • state – the state of the returned C/C++ instance is returned via this pointer.
      • iserr – the error flag is passed and updated via this pointer.
      Returns:

      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 sipTransferBack().

      Otherwise ownership is transferred to C/C++ and obj associated with transferObj via a call to 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 %ConvertToTypeCode. The calling code must then release the value at some point to prevent a memory leak by calling 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.)

      void *sipConvertToMappedType(PyObject *obj, const sipMappedType *mt, PyObject *transferObj, int flags, int *state, int *iserr)

      Deprecated since version 4.8: Use 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 sipCanConvertToMappedType() has been successful.

      Parameters:
      • obj – the Python object.
      • mt – the opaque structure returned by sipFindMappedType().
      • transferObj – this controls any ownership changes to obj.
      • flags – this may be the SIP_NOT_NONE flag.
      • state – the state of the returned C/C++ instance is returned via this pointer.
      • iserr – the error flag is passed and updated via this pointer.
      Returns:

      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 sipTransferBack().

      Otherwise ownership is transferred to C/C++ and obj associated with transferObj via a call to 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 %ConvertToTypeCode. The calling code must then release the value at some point to prevent a memory leak by calling 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.)

      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 sipCanConvertToType() has been successful.

      Parameters:
      • obj – the Python object.
      • td – the type’s generated type structure.
      • transferObj – this controls any ownership changes to obj.
      • flags – any combination of the SIP_NOT_NONE and SIP_NO_CONVERTORS flags.
      • state – the state of the returned C/C++ instance is returned via this pointer.
      • iserr – the error flag is passed and updated via this pointer.
      Returns:

      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 sipTransferBack().

      Otherwise ownership is transferred to C/C++ and obj associated with transferObj via a call to sipTransferTo().

      Note that obj can also be managed by the C/C++ instance itself, but this can only be achieved by using 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 %ConvertToTypeCode. The calling code must then release the value at some point to prevent a memory leak by calling 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.)

      PyObject *sipConvertToTypedArray(void *data, const sipTypeDef *td, const char *format, size_t stride, SIP_SSIZE_T len, int flags)

      New in version 4.15.

      This converts a one dimensional array of instances of a C structure, C++ class or mapped type to a sip.array object.

      An array is very like a Python 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.

      sip.array objects are not supported by the sip code generator. They can only be created by handwritten code.

      Parameters:
      • data – the address of the start of the C/C++ array.
      • td – an element’s type’s generated type structure.
      • format – the format, as defined by the struct module, of an array element.
      • stride – the size of an array element, including any padding.
      • len – the number of elements in the array.
      • flags – the optional SIP_READ_ONLY flag.
      Returns:

      the sip.array object.

      void *sipConvertToVoidPtr(PyObject *obj)

      This converts a Python object to a memory address. PyErr_Occurred() must be used to determine if the conversion was successful.

      Parameters:
      • obj – the Python object which may be Py_None, a sip.voidptr or a PyCObject.
      Returns:

      the memory address.

      int sipEnableAutoconversion(const sipTypeDef *td, int enable)

      New in version 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.

      Parameters:
      • td – the type’s generated type structure. This must refer to a class.
      • enable – is non-zero if auto-conversion should be enabled for the type. This is the default behaviour.
      Returns:

      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.

      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 sipImportSymbol(), by another module.

      Parameters:
      • name – the name of the symbol.
      • sym – the value of the symbol.
      Returns:

      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.

      sipWrapperType *sipFindClass(const char *type)

      Deprecated since version 4.8: Use sipFindType() instead.

      This returns a pointer to the generated type object corresponding to a C/C++ type.

      Parameters:
      • type – the C/C++ declaration of the type.
      Returns:

      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.

      const sipMappedType *sipFindMappedType(const char *type)

      Deprecated since version 4.8: Use sipFindType() instead.

      This returns a pointer to an opaque structure describing a mapped type.

      Parameters:
      • type – the C/C++ declaration of the type.
      Returns:

      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.

      PyTypeObject *sipFindNamedEnum(const char *type)

      Deprecated since version 4.8: Use sipFindType() instead.

      This returns a pointer to the generated Python type object corresponding to a named C/C++ enum.

      Parameters:
      • type – the C/C++ declaration of the enum.
      Returns:

      the generated Python type object. This will not change and may be saved in a static cache. NULL is returned if the C/C++ enum doesn’t exist.

      const sipTypeDef *sipFindType(const char *type)

      This returns a pointer to the generated type structure corresponding to a C/C++ type.

      Parameters:
      • type – the C/C++ declaration of the type.
      Returns:

      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.

      void *sipForceConvertToInstance(PyObject *obj, sipWrapperType *type, PyObject *transferObj, int flags, int *state, int *iserr)

      Deprecated since version 4.8: Use sipForceConvertToType() instead.

      This converts a Python object to an instance of a C structure or C++ class by calling sipCanConvertToInstance() and, if it is successfull, calling sipConvertToInstance().

      See sipConvertToInstance() for a full description of the arguments.

      void *sipForceConvertToMappedType(PyObject *obj, const sipMappedType *mt, PyObject *transferObj, int flags, int *state, int *iserr)

      Deprecated since version 4.8: Use 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 sipCanConvertToMappedType() and, if it is successfull, calling sipConvertToMappedType().

      See sipConvertToMappedType() for a full description of the arguments.

      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 sipCanConvertToType() and, if it is successfull, calling sipConvertToType().

      See sipConvertToType() for a full description of the arguments.

      void sipFree(void *mem)

      This returns an area of memory allocated by sipMalloc() to the heap.

      Parameters:
      • mem – the memory address.
      void *sipGetAddress(sipSimpleWrapper *obj)

      New in version 4.12.

      This returns the address of the C structure or C++ class instance wrapped by a Python object.

      Parameters:
      • obj – the Python object.
      Returns:

      the address of the C/C++ instance

      void *sipGetMixinAddress(sipSimpleWrapper *obj, const sipTypeDef *td)

      New in version 4.15.

      This returns the address of the C++ class instance that implements the mixin of a wrapped Python object.

      Parameters:
      Returns:

      the address of the C++ instance

      PyObject *sipGetPyObject(void *cppptr, const sipTypeDef *td)

      This returns a borrowed reference to the Python object for a C structure or C++ class instance.

      Parameters:
      Returns:

      the Python object or NULL (and no exception is raised) if the C/C++ instance hasn’t been wrapped.

      int sipGetState(PyObject *transferObj)

      The %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.

      Parameters:
      • transferObj – the object that describes the requested transfer of ownership.
      Returns:

      the state of the converted value.

      PyObject *sipGetWrapper(void *cppptr, sipWrapperType *type)

      Deprecated since version 4.8: Use sipGetPyObject() instead.

      This returns a borrowed reference to the wrapped instance object for a C structure or C++ class instance.

      Parameters:
      • cppptr – the pointer to the C/C++ instance.
      • type – the generated type object corresponding to the C/C++ type.
      Returns:

      the Python object or NULL (and no exception is raised) if the C/C++ instance hasn’t been wrapped.

      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 sipExportSymbol(), by another module.

      Parameters:
      • name – the name of the symbol.
      Returns:

      the value of the symbol. NULL is returned if there is no such symbol.

      sipIntTypeClassMap

      Deprecated since version 4.8.

      This C structure is used with sipMapIntToClass() to define a mapping between integer based RTTI and generated type objects. The structure elements are as follows.

      int typeInt

      The integer RTTI.

      sipWrapperType **pyType.

      A pointer to the corresponding generated type object.

      int sipIsAPIEnabled(const char *name, int from, int to)

      New in version 4.9.

      This checks to see if the current version number of an API falls within a given range. See Managing Incompatible APIs for more detail.

      Parameters:
      • name – the name of the API.
      • 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.
      • 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.
      Returns:

      a non-zero value if the API is enabled.

      unsigned long sipLong_AsUnsignedLong(PyObject *obj)

      This function is a thin wrapper around PyLong_AsUnsignedLong() that works around a bug in Python v2.3.x and earlier when converting integer objects.

      void *sipMalloc(size_t nbytes)

      This allocates an area of memory on the heap using the Python PyMem_Malloc() function. The memory is freed by calling sipFree().

      Parameters:
      • nbytes – the number of bytes to allocate.
      Returns:

      the memory address. If there was an error then NULL is returned and a Python exception raised.

      sipWrapperType *sipMapIntToClass(int type, const sipIntTypeClassMap *map, int maplen)

      Deprecated since version 4.8.

      This can be used in %ConvertToSubClassCode code as a convenient way of converting integer based RTTI to the corresponding generated type object.

      Parameters:
      • type – the integer RTTI.
      • map – the table of known RTTI and the corresponding type objects (see sipIntTypeClassMap). The entries in the table must be sorted in ascending order of RTTI.
      • maplen – the number of entries in the table.
      Returns:

      the corresponding type object, or NULL if type wasn’t in map.

      sipWrapperType *sipMapStringToClass(char *type, const sipStringTypeClassMap *map, int maplen)

      Deprecated since version 4.8.

      This can be used in %ConvertToSubClassCode code as a convenient way of converting '\0' terminated string based RTTI to the corresponding generated type object.

      Parameters:
      • type – the string RTTI.
      • map – the table of known RTTI and the corresponding type objects (see sipStringTypeClassMap). The entries in the table must be sorted in ascending order of RTTI.
      • maplen – the number of entries in the table.
      Returns:

      the corresponding type object, or NULL if type wasn’t in map.

      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 PyArg_ParseTuple() function.

      Parameters:
      • iserr – if this is not NULL then the location it points to is set to a non-zero value if there was an error.
      • method – the Python method that returned result.
      • result – the Python object returned by method.
      • format – the format string.
      Returns:

      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 %VirtualCatcherCode directive with method being the supplied sipMethod and result being the value returned by 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 **, 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 since version 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) [sipWrapperType *, int *, void **]

      Deprecated since version 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 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 Factory and 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 sipTypeDef *, int *, void **]

      Deprecated since version 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 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 Factory and 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 since version 4.8: Use F instead.

      Convert a Python named enum type to the corresponding C/C++ enum.

      F (wrapped enum) [sipTypeDef *, enum *]
      Convert a Python named enum type to the corresponding C/C++ enum.
      G (unicode/string) [wchar_t **, 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 sipTypeDef *, int *, void **]

      Convert a Python object to a C structure, C++ class or mapped type instance as described in 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 Factory and TransferBack
      annotations

      0x04 returns a copy of the C/C++ instance.

      L (integer) [signed char *]

      New in version 4.12.

      Convert a Python integer to a C/C++ signed char.

      M (long) [unsigned char *]

      New in version 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 [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 (sip.voidptr) [void **]
      Convert a Python sip.voidptr object to a C/C++ void *.
      z (object) [const char *, void **]

      New in version 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 **]

      New in version 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 **]

      New in version 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.

      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.

      Parameters:
      • td – the optional generated type structure that determines which types the handler will be called for.
      • getter – the handler function.
      Returns:

      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 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 Lazy Type Attributes for more details.

      int sipRegisterProxyResolver(const sipTypeDef *td, sipProxyResolverFunc resolver)

      New in version 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.

      Parameters:
      • td – the optional generated type structure that determines which type the resolver will be called for.
      • resolver – the resolver function.
      Returns:

      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.

      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.

      Parameters:
      • type – the type object.
      Returns:

      0 if there was no error, otherwise -1 is returned.

      See the section Types and Meta-types for more details.

      void sipReleaseInstance(void *cpp, sipWrapperType *type, int state)

      Deprecated since version 4.8: Use sipReleaseType() instead.

      This destroys a wrapped C/C++ instance if it was a temporary instance. It is called after a call to either sipConvertToInstance() or sipForceConvertToInstance().

      Parameters:
      • cpp – the C/C++ instance.
      • type – the type’s generated type object.
      • state – describes the state of the C/C++ instance.
      void sipReleaseMappedType(void *cpp, const sipMappedType *mt, int state)

      Deprecated since version 4.8: Use sipReleaseType() instead.

      This destroys a wrapped C/C++ mapped type if it was a temporary instance. It is called after a call to either sipConvertToMappedType() or sipForceConvertToMappedType().

      Parameters:
      • cpp – the C/C++ instance.
      • mt – the opaque structure returned by sipFindMappedType().
      • state – describes the state of the C/C++ instance.
      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 sipConvertToType() or sipForceConvertToType().

      Parameters:
      • cpp – the C/C++ instance.
      • td – the type’s generated type structure.
      • state – describes the state of the C/C++ instance.
      const char *sipResolveTypedef(const char *name)

      This returns the value of a C/C++ typedef.

      Parameters:
      • name – the name of the typedef.
      Returns:

      the value of the typedef or NULL if there was no such typedef.

      void sipSetDestroyOnExit(int destroy)

      New in version 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.

      Parameters:
      • destroy – non-zero if all C++ instances and C structures owned by Python should be destroyed when the interpreter exits. This is the default.
      sipSimpleWrapper

      This is a C structure that represents a Python wrapped instance whose type is sip.simplewrapper. It is an extension of the PyObject structure and so may be safely cast to it.

      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.

      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 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.

      PyObject *user

      This can be used for any purpose by handwritten code and will automatically be garbage collected at the appropriate time.

      PyTypeObject *sipSimpleWrapper_Type

      This is the type of a sipSimpleWrapper structure and is the C implementation of sip.simplewrapper. It may be safely cast to sipWrapperType.

      sipStringTypeClassMap

      Deprecated since version 4.8.

      This C structure is used with sipMapStringToClass() to define a mapping between '\0' terminated string based RTTI and Generated Type Objects. The structure elements are as follows.

      char *typeString

      The '\0' terminated string RTTI.

      sipWrapperType **pyType.

      A pointer to the corresponding generated type object.

      void sipTransferBack(PyObject *obj)

      This transfers ownership of a Python wrapped instance to Python (see Ownership of Objects).

      Parameters:
      • obj – the wrapped instance.

      In addition, any association of the instance with regard to the cyclic garbage collector with another instance is removed.

      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++.

      Parameters:
      • obj – the wrapped instance.

      Deprecated since version 4.14: Use the following instead:

      sipTransferTo(obj, NULL);
      void sipTransferTo(PyObject *obj, PyObject *owner)

      This transfers ownership of a Python wrapped instance to C++ (see Ownership of Objects).

      Parameters:
      • obj – the wrapped instance.
      • 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++.
      PyTypeObject *sipTypeAsPyTypeObject(sipTypeDef *td)

      This returns a pointer to the Python type object that SIP creates for a generated type structure.

      Parameters:
      • td – the type structure.
      Returns:

      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 sipWrapperType.

      const sipTypeDef *sipTypeFromPyTypeObject(PyTypeObject *py_type)

      This returns the generated type structure for a Python type object.

      Parameters:
      • py_type – the Python type object.
      Returns:

      the type structure or NULL if the Python type object doesn’t correspond to a type structure.

      int sipTypeIsClass(sipTypeDef *td)

      This checks if a generated type structure refers to a C structure or C++ class.

      Parameters:
      • td – the type structure.
      Returns:

      a non-zero value if the type structure refers to a structure or class.

      int sipTypeIsEnum(sipTypeDef *td)

      This checks if a generated type structure refers to a named enum.

      Parameters:
      • td – the type structure.
      Returns:

      a non-zero value if the type structure refers to an enum.

      int sipTypeIsMapped(sipTypeDef *td)

      This checks if a generated type structure refers to a mapped type.

      Parameters:
      • td – the type structure.
      Returns:

      a non-zero value if the type structure refers to a mapped type.

      int sipTypeIsNamespace(sipTypeDef *td)

      This checks if a generated type structure refers to a C++ namespace.

      Parameters:
      • td – the type structure.
      Returns:

      a non-zero value if the type structure refers to a namespace.

      const char *sipTypeName(const sipTypeDef *td)

      This returns the C/C++ name of a wrapped type.

      Parameters:
      Returns:

      the name of the C/C++ type.

      const sipTypeDef *sipTypeScope(const sipTypeDef *td)

      This returns the generated type structure of the enclosing scope of another generated type structure.

      Parameters:
      • td – the type structure.
      Returns:

      the type structure of the scope or NULL if the type has no scope.

      PyTypeObject *sipVoidPtr_Type

      This is the type of a PyObject structure that is used to wrap a void *.

      sipWrapper

      This is a C structure that represents a Python wrapped instance whose type is sip.wrapper. It is an extension of the sipSimpleWrapper and PyObject structures and so may be safely cast to both.

      int sipWrapper_Check(PyObject *obj)

      Deprecated since version 4.8: Use the following instead:

      PyObject_TypeCheck(obj, sipWrapper_Type)

      This checks if a Python object is a wrapped instance.

      Parameters:
      • obj – the Python object.
      Returns:

      a non-zero value if the Python object is a wrapped instance.

      PyTypeObject *sipWrapper_Type

      This is the type of a sipWrapper structure and is the C implementation of sip.wrapper. It may be safely cast to sipWrapperType.

      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).

      PyTypeObject *sipWrapperType_Type

      This is the type of a sipWrapperType structure and is the C implementation of sip.wrappertype.

      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 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 sipFindType().

      The type structures of all imported types are available to handwritten code.

      Generated Type Objects

      Deprecated since version 4.8: Use the corresponding generated type structure (see Generated Type Structures) and sipTypeAsPyTypeObject() instead.

      SIP generates a 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.

      Generated Named Enum Type Objects

      Deprecated since version 4.8: Use the corresponding generated type structure (see Generated Type Structures) and 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.

      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 %MethodCode directive should call the derived class’s constructor (which has the same C++ signature) rather then the wrapped class’s constructor.

      Generated Exception Objects

      SIP generates a Python object for each exception defined with the %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.15.5/doc/html/command_line.html0000644000076500000240000004130212310606651017504 0ustar philstaff00000000000000 The SIP Command Line — SIP 4.15.5 Reference Guide

      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:

      -h

      Display a help message.

      -V

      Display the SIP version number.

      -a <FILE>

      The name of the QScintilla API file to generate. This file contains a description of the module API in a form that the QScintilla editor component can use for auto-completion and call tips. (The file may also be used by the SciTE editor but must be sorted first.) By default the file is not generated.

      -b <FILE>

      The name of the build file to generate. This file contains the information about the module needed by the SIP build system to generate a platform and compiler specific Makefile for the module. By default the file is not generated.

      -c <DIR>

      The name of the directory (which must exist) into which all of the generated C or C++ code is placed. By default no code is generated.

      -d <FILE>

      Deprecated since version 4.12: Use the -X option instead.

      The name of the documentation file to generate. Documentation is included in specification files using the %Doc and %ExportedDoc directives. By default the file is not generated.

      -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.

      -g

      The Python GIL is released before making any calls to the C/C++ library being wrapped and reacquired afterwards. See The Python Global Interpreter Lock and the ReleaseGIL and HoldGIL annotations.

      -I <DIR>

      The directory is added to the list of directories searched when looking for a specification file given in an %Include or %Import directive. Directory separators must always be /. This option may be given any number of times.

      -j <NUMBER>

      The generated code is split into the given number of files. This makes it easier to use the parallel build facility of most modern implementations of make. By default 1 file is generated for each C structure or C++ class.

      -k

      New in version 4.10.

      Deprecated since version 4.12: Use the keyword_arguments="All" %Module directive argument instead.

      All functions and methods will, by default, support passing parameters using the Python keyword argument syntax.

      -o

      New in version 4.10.

      Docstrings will be automatically generated that describe the signature of all functions, methods and constructors.

      -p <MODULE>

      The name of the %ConsolidatedModule which will contain the wrapper code for this component module.

      -P

      New in version 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.

      -r

      Debugging statements that trace the execution of the bindings are automatically generated. By default the statements are not generated.

      -s <SUFFIX>

      The suffix to use for generated C or C++ source files. By default .c is used for C and .cpp for C++.

      -t <TAG>

      The SIP version tag (declared using a %Timeline directive) or the SIP platform tag (declared using the %Platforms directive) to generate code for. This option may be given any number of times so long as the tags do not conflict.

      -T

      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.

      -w

      The display of warning messages is enabled. By default warning messages are disabled.

      -x <FEATURE>

      The feature (declared using the %Feature directive) is disabled.

      -X <ID:FILE>

      New in version 4.12.

      The extract (defined with the %Extract directive) with the identifier ID is written to the file FILE.

      -z <FILE>

      The name of a file containing more command line options.

      Previous topic

      Using SIP

      Next topic

      SIP Specification Files

      sip-4.15.5/doc/html/directives.html0000644000076500000240000042014712310606651017230 0ustar philstaff00000000000000 Directives — SIP 4.15.5 Reference Guide

      Directives

      In this section we describe each of the directives that can be used in specification files. All directives begin with % as the first non-whitespace character in a line.

      Some directives have arguments or contain blocks of code or documentation. In the following descriptions these are shown in italics. Optional arguments are enclosed in [brackets].

      Some directives are used to specify handwritten code. Handwritten code must not define names that start with the prefix sip.

      Revised Directive Syntax

      New in version 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:

      %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:

      %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

      %AccessCode
      %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
      };
      

      See also

      %GetCode, %SetCode

      %API

      New in version 4.9.

      %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 Managing Incompatible APIs for more detail.

      For example:

      %API(name=PyQt4, version=1)
      
      %AutoPyName

      New in version 4.12.

      %AutoPyName(remove_leading = string)
      

      This is a sub-directive of the %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")
      }
      
      %BIGetBufferCode
      %BIGetBufferCode
          code
      %End
      

      This directive (along with %BIReleaseBufferCode) is used to specify code that implements the buffer interface of Python v3. If Python v2 is being used then this is ignored.

      The following variables are made available to the handwritten code:

      Py_buffer *sipBuffer
      This is a pointer to the Python buffer structure that the handwritten code must populate.
      type *sipCpp
      This is a pointer to the structure or class instance. Its type is a pointer to the structure or class.
      int sipFlags
      These are the flags that specify what elements of the sipBuffer structure must be populated.
      int sipRes
      The handwritten code should set this to 0 if there was no error or -1 if there was an error.
      PyObject *sipSelf
      This is the Python object that wraps the structure or class instance, i.e. self.
      %BIGetCharBufferCode
      %BIGetCharBufferCode
          code
      %End
      

      This directive (along with %BIGetReadBufferCode, %BIGetSegCountCode and %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.
      SIP_SSIZE_T sipRes
      The handwritten code should set this to the length of the character buffer or -1 if there was an error.
      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.
      %BIGetReadBufferCode
      %BIGetReadBufferCode
          code
      %End
      

      This directive (along with %BIGetCharBufferCode, %BIGetSegCountCode and %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.
      SIP_SSIZE_T sipRes
      The handwritten code should set this to the length of the read buffer or -1 if there was an error.
      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.
      %BIGetSegCountCode
      %BIGetSegCountCode
          code
      %End
      

      This directive (along with %BIGetCharBufferCode, %BIGetReadBufferCode and %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.
      SIP_SSIZE_T *sipLenPtr
      This is the pointer used to return the total length in bytes of all segments of the buffer.
      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.
      %BIGetWriteBufferCode
      %BIGetWriteBufferCode
          code
      %End
      

      This directive (along with %BIGetCharBufferCode, %BIGetReadBufferCode and %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.
      SIP_SSIZE_T sipRes
      The handwritten code should set this to the length of the write buffer or -1 if there was an error.
      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.
      %BIReleaseBufferCode
      %BIReleaseBufferCode
          code
      %End
      

      This directive (along with %BIGetBufferCode) is used to specify code that implements the buffer interface of Python v3. If Python v2 is being used then this is ignored.

      The following variables are made available to the handwritten code:

      Py_buffer *sipBuffer
      This is a pointer to the Python buffer structure.
      type *sipCpp
      This is a pointer to the structure or class instance. Its type is a pointer to the structure or class.
      PyObject *sipSelf
      This is the Python object that wraps the structure or class instance, i.e. self.
      %CModule

      Deprecated since version 4.12: Use the %Module directive with the language argument set to "C" instead.

      %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 %Module directive for an explanation of the version number.

      For example:

      %CModule dbus 1
      
      %CompositeModule
      %CompositeModule(name = dotted-name)
      {
          [%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 %Module directive is interpreted as defining a component module.

      The optional %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.

      %ConsolidatedModule
      %ConsolidatedModule(name = dotted-name)
      {
          [%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 %Module directive is interpreted as defining a component module.

      The optional %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.

      %ConvertFromTypeCode
      %ConvertFromTypeCode
          code
      %End
      

      This directive is used as part of the %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 sip.enableautoconversion() function, or from handwritten code by calling the 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<QWidget *> instance to a Python list of QWidget instances:

      %ConvertFromTypeCode
          PyObject *l;
      
          // Create the Python list of the correct length.
          if ((l = PyList_New(sipCpp->size())) == NULL)
              return NULL;
      
          // Go through each element in the C++ instance and convert it to a
          // wrapped QWidget.
          for (int i = 0; i < sipCpp->size(); ++i)
          {
              QWidget *w = sipCpp->at(i);
              PyObject *wobj;
      
              // Get the Python wrapper for the QWidget instance, creating a new
              // one if necessary, and handle any ownership transfer.
              if ((wobj = sipConvertFromType(w, sipType_QWidget, sipTransferObj)) == NULL)
              {
                  // There was an error so garbage collect the Python list.
                  Py_DECREF(l);
                  return NULL;
              }
      
              // Add the wrapper to the list.
              PyList_SET_ITEM(l, i, wobj);
          }
      
          // Return the Python list.
          return l;
      %End
      
      %ConvertToSubClassCode
      %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 since version 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.
      
      };
      
      %ConvertToTypeCode
      %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 %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.

      • SIP_TEMPORARY is set to indicate that the returned instance is a temporary and should be released to avoid a memory leak.
      • SIP_DERIVED_CLASS is set to indicate that the type of the returned instance is a derived class. See Generated Derived Classes.

      The following example converts a Python list of QPoint instances to a QList<QPoint> instance:

      %ConvertToTypeCode
          // See if we are just being asked to check the type of the Python
          // object.
          if (!sipIsErr)
          {
              // Checking whether or not None has been passed instead of a list
              // has already been done.
              if (!PyList_Check(sipPy))
                  return 0;
      
              // Check the type of each element.  We specify SIP_NOT_NONE to
              // disallow None because it is a list of QPoint, not of a pointer
              // to a QPoint, so None isn't appropriate.
              for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i)
                  if (!sipCanConvertToType(PyList_GET_ITEM(sipPy, i),
                                           sipType_QPoint, SIP_NOT_NONE))
                      return 0;
      
              // The type is valid.
              return 1;
          }
      
          // Create the instance on the heap.
          QList<QPoint> *ql = new QList<QPoint>;
      
          for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i)
          {
              QPoint *qp;
              int state;
      
              // Get the address of the element's C++ instance.  Note that, in
              // this case, we don't apply any ownership changes to the list
              // elements, only to the list itself.
              qp = reinterpret_cast<QPoint *>(sipConvertToType(
                                                      PyList_GET_ITEM(sipPy, i),
                                                      sipType_QPoint, 0,
                                                      SIP_NOT_NONE,
                                                      &state, sipIsErr));
      
              // Deal with any errors.
              if (*sipIsErr)
              {
                  sipReleaseType(qp, sipType_QPoint, state);
      
                  // Tidy up.
                  delete ql;
      
                  // There is no temporary instance.
                  return 0;
              }
      
              ql->append(*qp);
      
              // A copy of the QPoint was appended to the list so we no longer
              // need it.  It may be a temporary instance that should be
              // destroyed, or a wrapped instance that should not be destroyed.
              // sipReleaseType() will do the right thing.
              sipReleaseType(qp, sipType_QPoint, state);
          }
      
          // Return the instance.
          *sipCppPtr = ql;
      
          // The instance should be regarded as temporary (and be destroyed as
          // soon as it has been used) unless it has been transferred from
          // Python.  sipGetState() is a convenience function that implements
          // this common transfer behaviour.
          return sipGetState(sipTransferObj);
      %End
      

      When used in a class specification the handwritten code replaces the code that would normally be automatically generated. This means that the handwritten code must also handle instances of the class itself and not just the additional types that are being supported. This should be done by making calls to sipCanConvertToType() to check the object type and sipConvertToType() to convert the object. The SIP_NO_CONVERTORS flag must be passed to both these functions to prevent recursive calls to the handwritten code.

      %Copying
      %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) 2014 Riverbank Computing Limited
      %End
      
      %DefaultDocstringFormat

      New in version 4.13.

      %DefaultDocstringFormat(name = ["raw" | "deindented"])
      

      This directive is used to specify the default formatting of docstrings, i.e. when the %Docstring directive does not specify an explicit format.

      See the %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"
      
      %DefaultEncoding
      %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 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"
      
      %DefaultMetatype
      %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 Metatype class annotation to specify the meta-type used by a particular C/C++ type.

      See the section Types and Meta-types for more details.

      For example:

      %DefaultMetatype PyQt4.QtCore.pyqtWrapperType
      
      %DefaultSupertype
      %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 Supertype class annotation to specify the super-type used by a particular C/C++ type.

      See the section Types and Meta-types for more details.

      For example:

      %DefaultSupertype sip.simplewrapper
      
      %Doc

      Deprecated since version 4.12: Use the %Extract directive instead.

      %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 %Import it. Use the %ExportedDoc directive for documentation that should be included by all modules that %Import this one.

      For example:

      %Doc
      <h1>An Example</h1>
      <p>
      This fragment of documentation is HTML and is local to the module in
      which it is defined.
      </p>
      %End
      
      %Docstring

      New in version 4.10.

      %Docstring(format = ["raw" | "deindented"])
          text
      %End
      

      This directive is used to specify explicit docstrings for modules, classes, functions, methods 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.

      Specifying an explicit docstring will prevent SIP from generating an automatic docstring that describes the Python signature of a function or method overload. This means that SIP will generate less informative exceptions (i.e. without a full signature) when it fails to match a set of arguments to any function or method overload.

      New in version 4.13.

      The format may either be "raw" or "deindented". If it is not specified then the value specified by any %DefaultDocstringFormat directive is used.

      If the format is "raw" then the docstring is used as it appears in the specification file.

      If the format is "deindented" then any leading spaces common to all non-blank lines of the docstring are removed.

      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
      };
      
      %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.

      %Exception
      %Exception name [(base-exception)]
      {
          [%TypeHeaderCode]
          %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 %Exception directive.

      The optional %TypeHeaderCode sub-directive is used to specify any external interface to the exception being defined.

      The %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 <exception>
      %End
      %RaiseCode
          const char *detail = sipExceptionRef.what();
      
          SIP_BLOCK_THREADS
          PyErr_SetString(sipException_std_exception, detail);
          SIP_UNBLOCK_THREADS
      %End
      };
      

      In this example we map the standard C++ exception to a new Python exception. The new exception is called StdException and is derived from the standard Python exception Exception.

      An exception may be annotated with Default to specify that it should be caught by default if there is no throw clause.

      %ExportedDoc

      Deprecated since version 4.12: Use the %Extract directive instead.

      %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 %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
      
      %ExportedHeaderCode
      %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.

      %Extract

      New in version 4.12.

      %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 -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
      
      %Feature
      %Feature(name = name)
      

      This directive is used to declare a feature. Features (along with %Platforms and %Timeline) are used by the %If directive to control whether or not parts of a specification are processed or ignored.

      Features are mutually independent of each other - any combination of features may be enabled or disable. By default all features are enabled. The -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
      
      %FinalisationCode

      New in version 4.15.

      %FinalisationCode
          code
      %End
      

      This directive is used to specify handwritten code that is executed one 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.
      %GCClearCode
      %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 %GCTraverseCode for specifying the code that traverses any embedded references.)

      The following variables are made available to the handwritten code:

      type *sipCpp
      This is a pointer to the structure or class instance. Its type is a pointer to the structure or class.
      int sipRes
      The handwritten code should set this to the result to be returned.

      The following simplified example is taken from PyQt. The QCustomEvent class allows arbitary data to be attached to the event. In PyQt this data is always a Python object and so should be handled by the garbage collector:

      %GCClearCode
          PyObject *obj;
      
          // Get the object.
          obj = reinterpret_cast<PyObject *>(sipCpp->data());
      
          // Clear the pointer.
          sipCpp->setData(0);
      
          // Clear the reference.
          Py_XDECREF(obj);
      
          // Report no error.
          sipRes = 0;
      %End
      
      %GCTraverseCode
      %GCTraverseCode
          code
      %End
      

      This directive is used to specify the code that traverses any embedded references for Python’s cyclic garbage collector. (See %GCClearCode for a full explanation.)

      The following variables are made available to the handwritten code:

      type *sipCpp
      This is a pointer to the structure or class instance. Its type is a pointer to the structure or class.
      visitproc sipVisit
      This is the visit function provided by the garbage collector.
      void *sipArg
      This is the argument to the visit function provided by the garbage collector.
      int sipRes
      The handwritten code should set this to the result to be returned.

      The following simplified example is taken from PyQt’s QCustomEvent class:

      %GCTraverseCode
          PyObject *obj;
      
          // Get the object.
          obj = reinterpret_cast<PyObject *>(sipCpp->data());
      
          // Call the visit function if there was an object.
          if (obj)
              sipRes = sipVisit(obj, sipArg);
          else
              sipRes = 0;
      %End
      
      %GetCode
      %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
          };
      }
      

      See also

      %AccessCode, %SetCode

      %If
      %If (expression)
          specification
      %End
      

      where

      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 %Feature), platforms (see %Platforms) and versions (see %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 %If directives.

      %Import
      %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 %Import directive) and tries again. If this also fails then SIP prepends name with each of the directories, in turn, specified by the -I command line option.

      Directory separators must always be /.

      For example:

      %Import qt/qtmod.sip
      
      %Include
      %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.

      %Include follows the same search process as the %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
      
      %InitialisationCode
      %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 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
      
      %InstanceCode

      New in version 4.14.

      %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.
      %License
      %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 __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"
      
      %MappedType
      template<type-list>
      %MappedType type
      {
          [%TypeHeaderCode]
          [%ConvertToTypeCode]
          [%ConvertFromTypeCode]
      };
      
      %MappedType type
      {
          [%TypeHeaderCode]
          [%ConvertToTypeCode]
          [%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 %TypeHeaderCode sub-directive is used to specify the library interface to the type being mapped.

      The optional %ConvertToTypeCode sub-directive is used to specify the handwritten code that converts a Python object to an instance of the mapped type.

      The optional %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<Type *>
      %MappedType QList
      {
      %TypeHeaderCode
      // Include the library interface to the type being mapped.
      #include <qlist.h>
      %End
      
      %ConvertToTypeCode
          // See if we are just being asked to check the type of the Python
          // object.
          if (sipIsErr == NULL)
          {
              // Check it is a list.
              if (!PyList_Check(sipPy))
                  return 0;
      
              // Now check each element of the list is of the type we expect.
              // The template is for a pointer type so we don't disallow None.
              for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i)
                  if (!sipCanConvertToType(PyList_GET_ITEM(sipPy, i),
                                           sipType_Type, 0))
                      return 0;
      
              return 1;
          }
      
          // Create the instance on the heap.
          QList<Type *> *ql = new QList<Type *>;
      
          for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i)
          {
              // Use the SIP API to convert the Python object to the
              // corresponding C++ instance.  Note that we apply any ownership
              // transfer to the list itself, not the individual elements.
              Type *t = reinterpret_cast<Type *>(sipConvertToType(
                                                  PyList_GET_ITEM(sipPy, i),
                                                  sipType_Type, 0, 0, 0,
                                                  sipIsErr));
      
              if (*sipIsErr)
              {
                  // Tidy up.
                  delete ql;
      
                  // There is nothing on the heap.
                  return 0;
              }
      
              // Add the pointer to the C++ instance.
              ql->append(t);
          }
      
          // Return the instance on the heap.
          *sipCppPtr = ql;
      
          // Apply the normal transfer.
          return sipGetState(sipTransferObj);
      %End
      
      %ConvertFromTypeCode
          PyObject *l;
      
          // Create the Python list of the correct length.
          if ((l = PyList_New(sipCpp->size())) == NULL)
              return NULL;
      
          // Go through each element in the C++ instance and convert it to the
          // corresponding Python object.
          for (int i = 0; i < sipCpp->size(); ++i)
          {
              Type *t = sipCpp->at(i);
              PyObject *tobj;
      
              if ((tobj = sipConvertFromType(t, sipType_Type, sipTransferObj)) == NULL)
              {
                  // There was an error so garbage collect the Python list.
                  Py_DECREF(l);
                  return NULL;
              }
      
              PyList_SET_ITEM(l, i, tobj);
          }
      
          // Return the Python list.
          return l;
      %End
      };
      

      Using this we can use, for example, QList<QObject *> throughout the module’s specification files (and in any module that imports this one). The generated code will automatically map this to and from a Python list of QObject instances when appropriate.

      %MethodCode
      %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 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 The Python Global Interpreter Lock and the ReleaseGIL and HoldGIL annotations.)

      If the 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 %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 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 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 %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. __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 __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 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 [1], 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
      
      [1]See %VirtualCatcherCode for a description of how SIP generated code handles the reimplementation of C++ virtual methods in Python.
      %Module
      %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]]
              [, version = integer])
      {
          [%AutoPyName]
          [%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 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 %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 KeywordArgs annotation for an explaination of the possible values and their effect. If it is not specified then the value implied by the (deprecated) -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 %MethodCode or %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 GetWrapper argument annotation is used.

      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 %Import this module. Under the covers, a module exports an API that is used by modules that %Import it and the API is given a version number. A module built on that module knows the version number of the API that it is expecting. If, when the modules are imported at run-time, the version numbers do not match then a Python exception is raised. The dependent module must then be re-built using the correct specification files for the base module.

      The optional %AutoPyName sub-directive is used to specify a rule for automatically providing Python names.

      The optional %Docstring sub-directive is used to specify the module’s docstring.

      For example:

      %Module(name=PyQt4.QtCore, version=5)
      
      %ModuleCode
      %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
      
      %ModuleHeaderCode
      %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
      
      %OptionalInclude
      %OptionalInclude filename
      

      Deprecated since version 4.12: Use the %Include directive with the optional argument set to True instead.

      This directive is identical to the %Include directive except that SIP silently continues processing if filename could not be opened.

      For example:

      %OptionalInclude license.sip
      
      %PickleCode
      %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.

      %Platforms
      %Platforms {name name ...}
      

      This directive is used to declare a set of platforms. Platforms (along with %Feature and %Timeline) are used by the %If directive to control whether or not parts of a specification are processed or ignored.

      Platforms are mutually exclusive - only one platform can be enabled at a time. By default all platforms are disabled. The SIP -t command line option is used to enable a platform.

      New in version 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
      
      %PostInitialisationCode
      %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
      
      %PreInitialisationCode
      %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
      
      %Property

      New in version 4.12.

      %Property(name = name, get = name [, set = name])
      {
          [%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 %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)
      };
      
      %RaiseCode
      %RaiseCode
          code
      %End
      

      This directive is used as part of the definition of an exception using the %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 %Exception directive for an example.

      %SetCode
      %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 *.

      See also

      %AccessCode, %GetCode

      %Timeline
      %Timeline {name name ...}
      

      This directive is used to declare a set of versions released over a period of time. Versions (along with %Feature and %Platforms) are used by the %If directive to control whether or not parts of a specification are processed or ignored.

      Versions are mutually exclusive - only one version can be enabled at a time. By default all versions are disabled. The SIP -t command line option is used to enable a version.

      The %Timeline directive can be used any number of times in a module to allow multiple libraries to be wrapped in the same module.

      New in version 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.

      New in version 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
      
      %TypeCode
      %TypeCode
          code
      %End
      

      This directive is used as part of the specification of a C structure, a C++ class or a %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.

      %TypeHeaderCode
      %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 %MappedType directive.

      Normally code will be a pre-processor #include statement.

      For example:

      // Wrap the Klass class.
      class Klass
      {
      %TypeHeaderCode
      #include <klass.h>
      %End
      
          // The rest of the class specification.
      };
      
      %UnitCode
      %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.

      %UnitPostIncludeCode

      New in version 4.11.

      %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).

      %VirtualCatcherCode
      %VirtualCatcherCode
          code
      %End
      

      For most classes there are corresponding 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 Python reimplementation and the handling of any returned results. It is usually used to handle argument types and results that SIP cannot deal with automatically.

      This directive can also be used in the context of a class destructor to specify handwritten code that is embedded in-line in the internal derived class’s destructor.

      In the context of a method the Python Global Interpreter Lock (GIL) is automatically acquired before the specified code is executed and automatically released afterwards.

      In the context of a destructor the specified code must handle the GIL. The GIL must be acquired before any calls to the Python API and released after the last call as shown in this example fragment:

      SIP_BLOCK_THREADS
      Py_DECREF(obj);
      SIP_UNBLOCK_THREADS
      

      The following variables are made available to the handwritten code in the context of a method:

      type a0
      There is a variable for each argument of the C++ signature named a0, a1, etc. If use_argument_names has been set in the %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 sipParseResult() using either the A or B format characters.

      If use_argument_names has been set in the %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 sipCallMethod().
      type sipRes
      The handwritten code should set this to the result to be returned. The type of the variable is the same as the type defined in the C++ signature in the specification.
      int sipResKey
      This variable is only made available if the result has a type where it is important to ensure that the corresponding Python object is not garbage collected too soon. This only applies to '\0' terminated strings. The variable would normally be passed to 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 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
      };
      
      %VirtualErrorHandler

      New in version 4.14.

      %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 SIP_RELEASE_GIL(). It must not call 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 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
      

      Table Of Contents

      Previous topic

      SIP Specification Files

      Next topic

      Annotations

      sip-4.15.5/doc/html/distutils.html0000644000076500000240000002000512310606651017100 0ustar philstaff00000000000000 Building Your Extension with distutils — SIP 4.15.5 Reference Guide

      Building Your Extension with distutils

      To build the example in A 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 The SIP 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.

      Previous topic

      The Build System

      Next topic

      Builtin Modules and Custom Interpreters

      sip-4.15.5/doc/html/embedding.html0000644000076500000240000002027712310606651017005 0ustar philstaff00000000000000 Using the C API when Embedding — SIP 4.15.5 Reference Guide

      Using the C API when Embedding

      The 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 Generated Type Structures, Generated Named Enum Type Objects and Generated Exception Objects) cannot be refered to directly and must be obtained using the sipFindType() function. Of course, the corresponding modules must already have been imported into the interpreter.

      The following code fragment shows how to get a pointer to the sipAPIDef data structure:

      #include <sip.h>
      
      const sipAPIDef *get_sip_api()
      {
      #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 SIP_USE_PYCAPSULE means that code will run under all versions of Python.

      Previous topic

      C API for Handwritten Code

      Next topic

      Python API for Applications

      sip-4.15.5/doc/html/genindex.html0000644000076500000240000017351712310606652016677 0ustar philstaff00000000000000 Index — SIP 4.15.5 Reference Guide

      Index

      Symbols | _ | A | B | C | D | E | F | G | H | I | K | M | N | O | P | R | S | T | U | V | W

      Symbols

      %AccessCode (directive)
      %API (directive)
      %AutoPyName (directive)
      %BIGetBufferCode (directive)
      %BIGetCharBufferCode (directive)
      %BIGetReadBufferCode (directive)
      %BIGetSegCountCode (directive)
      %BIGetWriteBufferCode (directive)
      %BIReleaseBufferCode (directive)
      %CModule (directive)
      %CompositeModule (directive)
      %ConsolidatedModule (directive)
      %ConvertFromTypeCode (directive)
      %ConvertToSubClassCode (directive)
      %ConvertToTypeCode (directive)
      %Copying (directive)
      %DefaultDocstringFormat (directive)
      %DefaultEncoding (directive)
      %DefaultMetatype (directive)
      %DefaultSupertype (directive)
      %Doc (directive)
      %Docstring (directive)
      %End (directive)
      %Exception (directive)
      %ExportedDoc (directive)
      %ExportedHeaderCode (directive)
      %Extract (directive)
      %Feature (directive)
      %FinalisationCode (directive)
      %GCClearCode (directive)
      %GCTraverseCode (directive)
      %GetCode (directive)
      %If (directive)
      %Import (directive)
      %Include (directive)
      %InitialisationCode (directive)
      %InstanceCode (directive)
      %License (directive)
      %MappedType (directive)
      %MethodCode (directive)
      %Module (directive)
      %ModuleCode (directive)
      %ModuleHeaderCode (directive)
      %OptionalInclude (directive)
      %PickleCode (directive)
      %Platforms (directive)
      %PostInitialisationCode (directive)
      %PreInitialisationCode (directive)
      %Property (directive)
      %RaiseCode (directive)
      %SetCode (directive)
      %Timeline (directive)
      %TypeCode (directive)
      %TypeHeaderCode (directive)
      %UnitCode (directive)
      %UnitPostIncludeCode (directive)
      %VirtualCatcherCode (directive)
      %VirtualErrorHandler (directive)
      --arch <ARCH>
      configure.py command line option
      --deployment-target <VERSION>
      configure.py command line option
      --show-build-macros
      configure.py command line option
      --show-platforms
      configure.py command line option
      --sip-module <NAME>
      configure.py command line option
      --version
      configure.py command line option
      -a <FILE>
      sip command line option
      -b <DIR>, --bindir <DIR>
      configure.py command line option
      -b <FILE>
      sip command line option
      -c <DIR>
      sip command line option
      -d <DIR>, --destdir <DIR>
      configure.py command line option
      -d <FILE>
      sip command line option
      -e
      sip command line option
      -e <DIR>, --incdir <DIR>
      configure.py command line option
      -g
      sip command line option
      -h
      sip command line option
      -h, --help
      configure.py command line option
      -I <DIR>
      sip command line option
      -j <NUMBER>
      sip command line option
      -k
      sip command line option
      -k, --static
      configure.py command line option
      -n, --universal
      configure.py command line option
      -o
      sip command line option
      -P
      sip command line option
      -p <MODULE>
      sip command line option
      -p <PLATFORM>, --platform <PLATFORM>
      configure.py command line option
      -r
      sip command line option
      -s <SDK>, --sdk <SDK>
      configure.py command line option
      -s <SUFFIX>
      sip command line option
      -T
      sip command line option
      -t <TAG>
      sip command line option
      -u, --debug
      configure.py command line option
      -V
      sip command line option
      -v <DIR>, --sipdir <DIR>
      configure.py command line option
      -w
      sip command line option
      -x <FEATURE>
      sip command line option
      -X <ID:FILE>
      sip command line option
      -z <FILE>
      sip command line option

      _

      __getitem__() (sip.voidptr method)
      __hex__() (sip.voidptr method)
      __init__() (sip.voidptr method)
      (sipconfig.Configuration method)
      (sipconfig.Makefile method)
      (sipconfig.ModuleMakefile method)
      (sipconfig.ParentMakefile method)
      (sipconfig.ProgramMakefile method)
      (sipconfig.PythonModuleMakefile method)
      (sipconfig.SIPModuleMakefile method)
      __int__() (sip.voidptr method)
      __len__ (function annotation)
      __len__() (sip.voidptr method)
      __setitem__() (sip.voidptr method)

      A

      Abstract (class annotation)
      AllowNone (argument annotation)
      (class annotation)
      (mapped type annotation)
      API (class annotation)
      (function annotation)
      (mapped type annotation)
      arch (sipconfig.Configuration attribute)
      Array (argument annotation)
      ArraySize (argument annotation)
      ascapsule() (sip.voidptr method)
      ascobject() (sip.voidptr method)
      asstring() (sip.voidptr method)
      AutoGen (function annotation)

      B

      build_command() (sipconfig.ProgramMakefile method)
      build_macros() (sipconfig.Configuration method)

      C

      Capsule (typedef annotation)
      cast() (in module sip)
      chkdir (sipconfig.Makefile attribute)
      clean_build_file_objects() (sipconfig.Makefile method)
      config (sipconfig.Makefile attribute)
      Configuration (class in sipconfig)
      configure.py command line option
      --arch <ARCH>
      --deployment-target <VERSION>
      --show-build-macros
      --show-platforms
      --sip-module <NAME>
      --version
      -b <DIR>, --bindir <DIR>
      -d <DIR>, --destdir <DIR>
      -e <DIR>, --incdir <DIR>
      -h, --help
      -k, --static
      -n, --universal
      -p <PLATFORM>, --platform <PLATFORM>
      -s <SDK>, --sdk <SDK>
      -u, --debug
      -v <DIR>, --sipdir <DIR>
      console (sipconfig.Makefile attribute)
      Constrained (argument annotation)
      copy (sipconfig.Makefile attribute)
      create_config_module() (in module sipconfig)
      create_content() (in module sipconfig)
      create_wrapper() (in module sipconfig)

      D

      Default (exception annotation)
      (function annotation)
      default_bin_dir (sipconfig.Configuration attribute)
      default_mod_dir (sipconfig.Configuration attribute)
      default_sip_dir (sipconfig.Configuration attribute)
      DelayDtor (class annotation)
      delete() (in module sip)
      deployment_target (sipconfig.Configuration attribute)
      Deprecated (class annotation)
      (function annotation)
      DocType (argument annotation)
      (function annotation)
      (mapped type annotation)
      (typedef annotation)
      (variable annotation)
      DocValue (argument annotation)
      dump() (in module sip)

      E

      enableautoconversion() (in module sip)
      Encoding (argument annotation)
      (function annotation)
      (typedef annotation)
      (variable annotation)
      environment variable
      MACOSX_DEPLOYMENT_TARGET
      error() (in module sipconfig)
      ExportDerived (class annotation)
      External (class annotation)
      extra_cflags (sipconfig.Makefile attribute)
      extra_cxxflags (sipconfig.Makefile attribute)
      extra_defines (sipconfig.Makefile attribute)
      extra_include_dirs (sipconfig.Makefile attribute)
      extra_lflags (sipconfig.Makefile attribute)
      extra_lib_dirs (sipconfig.Makefile attribute)
      extra_libs (sipconfig.Makefile attribute)

      F

      Factory (function annotation)
      finalise() (sipconfig.Makefile method)
      (sipconfig.ModuleMakefile method)
      (sipconfig.ProgramMakefile method)
      (sipconfig.SIPModuleMakefile method)
      format() (in module sipconfig)

      G

      generate() (sipconfig.Makefile method)
      generate_macros_and_rules() (sipconfig.Makefile method)
      (sipconfig.ModuleMakefile method)
      (sipconfig.ParentMakefile method)
      (sipconfig.ProgramMakefile method)
      (sipconfig.PythonModuleMakefile method)
      generate_target_clean() (sipconfig.Makefile method)
      (sipconfig.ModuleMakefile method)
      (sipconfig.ParentMakefile method)
      (sipconfig.ProgramMakefile method)
      generate_target_default() (sipconfig.Makefile method)
      (sipconfig.ModuleMakefile method)
      (sipconfig.ParentMakefile method)
      (sipconfig.ProgramMakefile method)
      generate_target_install() (sipconfig.Makefile method)
      (sipconfig.ModuleMakefile method)
      (sipconfig.ParentMakefile method)
      (sipconfig.ProgramMakefile method)
      (sipconfig.PythonModuleMakefile method)
      generator (sipconfig.Makefile attribute)
      getapi() (in module sip)
      getsize() (sip.voidptr method)
      GetWrapper (argument annotation)
      getwriteable() (sip.voidptr method)

      H

      HoldGIL (function annotation)

      I

      In (argument annotation)
      inform() (in module sipconfig)
      install_file() (sipconfig.Makefile method)
      isdeleted() (in module sip)
      ispycreated() (in module sip)
      ispyowned() (in module sip)

      K

      KeepReference (argument annotation)
      (function annotation)
      KeywordArgs (function annotation)

      M

      MACOSX_DEPLOYMENT_TARGET
      Makefile (class in sipconfig)
      Metatype (class annotation)
      Mixin (class annotation)
      mkdir (sipconfig.Makefile attribute)
      module_as_lib() (sipconfig.ModuleMakefile method)
      ModuleMakefile (class in sipconfig)

      N

      NewThread (function annotation)
      NoArgParser (function annotation)
      NoCopy (argument annotation)
      (function annotation)
      NoDefaultCtors (class annotation)
      NoDerived (function annotation)
      NoKeywordArgs (function annotation)
      NoRaisesPyException (function annotation)
      NoRelease (mapped type annotation)
      NoScope (enum annotation)
      NoTypeName (typedef annotation)
      NoVirtualErrorHandler (function annotation)
      Numeric (function annotation)

      O

      optional_list() (sipconfig.Makefile method)
      optional_string() (sipconfig.Makefile method)
      Out (argument annotation)

      P

      ParentMakefile (class in sipconfig)
      parse_build_file() (sipconfig.Makefile method)
      parse_build_macros() (in module sipconfig)
      platform (sipconfig.Configuration attribute)
      platform_lib() (sipconfig.Makefile method)
      PostHook (function annotation)
      PreHook (function annotation)
      ProgramMakefile (class in sipconfig)
      py_conf_inc_dir (sipconfig.Configuration attribute)
      py_inc_dir (sipconfig.Configuration attribute)
      py_lib_dir (sipconfig.Configuration attribute)
      py_version (sipconfig.Configuration attribute)
      PyInt (argument annotation)
      (function annotation)
      (typedef annotation)
      (variable annotation)
      PyName (class annotation)
      (enum annotation)
      (exception annotation)
      (function annotation)
      (mapped type annotation)
      (typedef annotation)
      (variable annotation)
      PythonModuleMakefile (class in sipconfig)

      R

      RaisesPyException (function annotation)
      read_version() (in module sipconfig)
      ready() (sipconfig.Makefile method)
      ReleaseGIL (function annotation)
      required_string() (sipconfig.Makefile method)
      ResultSize (argument annotation)
      rm (sipconfig.Makefile attribute)

      S

      Sequence (function annotation)
      set_build_macros() (sipconfig.Configuration method)
      setapi() (in module sip)
      setdeleted() (in module sip)
      setdestroyonexit() (in module sip)
      setsize() (sip.voidptr method)
      settracemask() (in module sip)
      setwriteable() (sip.voidptr method)
      simplewrapper (class in sip)
      SingleShot (argument annotation)
      sip (module)
      sip command line option
      -I <DIR>
      -P
      -T
      -V
      -X <ID:FILE>
      -a <FILE>
      -b <FILE>
      -c <DIR>
      -d <FILE>
      -e
      -g
      -h
      -j <NUMBER>
      -k
      -o
      -p <MODULE>
      -r
      -s <SUFFIX>
      -t <TAG>
      -w
      -x <FEATURE>
      -z <FILE>
      SIP_ANYSLOT (SIP type)
      SIP_API_MAJOR_NR (C macro)
      SIP_API_MINOR_NR (C macro)
      sip_bin (sipconfig.Configuration attribute)
      SIP_BLOCK_THREADS (C macro)
      sip_config_args (sipconfig.Configuration attribute)
      sip_inc_dir (sipconfig.Configuration attribute)
      sip_mod_dir (sipconfig.Configuration attribute)
      SIP_NO_CONVERTORS (C macro)
      SIP_NOT_NONE (C macro)
      SIP_OWNS_MEMORY (C macro)
      SIP_PROTECTED_IS_PUBLIC (C macro)
      SIP_PYBUFFER (SIP type)
      SIP_PYCALLABLE (SIP type)
      SIP_PYDICT (SIP type)
      SIP_PYLIST (SIP type)
      SIP_PYOBJECT (SIP type)
      SIP_PYSLICE (SIP type)
      SIP_PYTUPLE (SIP type)
      SIP_PYTYPE (SIP type)
      SIP_QOBJECT (SIP type)
      SIP_READ_ONLY (C macro)
      SIP_RELEASE_GIL (C function)
      SIP_RXOBJ_CON (SIP type)
      SIP_RXOBJ_DIS (SIP type)
      SIP_SIGNAL (SIP type)
      SIP_SLOT (SIP type)
      SIP_SLOT_CON (SIP type)
      SIP_SLOT_DIS (SIP type)
      SIP_SSIZE_T (C macro)
      (SIP type)
      SIP_SSIZE_T_FORMAT (C macro)
      SIP_UNBLOCK_THREADS (C macro)
      SIP_USE_PYCAPSULE (C macro)
      SIP_VERSION (C macro)
      (in module sip)
      sip_version (sipconfig.Configuration attribute)
      SIP_VERSION_STR (C macro)
      (in module sip)
      sip_version_str (sipconfig.Configuration attribute)
      sipBadCallableArg (C function)
      sipBadCatcherResult (C function)
      sipBadLengthForSlice (C function)
      sipBuildResult (C function)
      sipCallMethod (C function)
      sipCanConvertToEnum (C function)
      sipCanConvertToInstance (C function)
      sipCanConvertToMappedType (C function)
      sipCanConvertToType (C function)
      sipClassName (C function)
      sipconfig (module)
      sipConvertFromConstVoidPtr (C function)
      sipConvertFromConstVoidPtrAndSize (C function)
      sipConvertFromEnum (C function)
      sipConvertFromInstance (C function)
      sipConvertFromMappedType (C function)
      sipConvertFromNamedEnum (C function)
      sipConvertFromNewInstance (C function)
      sipConvertFromNewPyType (C function)
      sipConvertFromNewType (C function)
      sipConvertFromSequenceIndex (C function)
      sipConvertFromSliceObject (C function)
      sipConvertFromType (C function)
      sipConvertFromVoidPtr (C function)
      sipConvertFromVoidPtrAndSize (C function)
      sipConvertToArray (C function)
      sipConvertToInstance (C function)
      sipConvertToMappedType (C function)
      sipConvertToType (C function)
      sipConvertToTypedArray (C function)
      sipConvertToVoidPtr (C function)
      sipDelayedDtor (C type)
      sipDelayedDtor.dd_isderived (C member)
      sipDelayedDtor.dd_name (C member)
      sipDelayedDtor.dd_next (C member)
      sipDelayedDtor.dd_ptr (C member)
      sipDelayedDtors (C function)
      sipEnableAutoconversion (C function)
      sipExportSymbol (C function)
      sipFindClass (C function)
      sipFindMappedType (C function)
      sipFindNamedEnum (C function)
      sipFindType (C function)
      sipForceConvertToInstance (C function)
      sipForceConvertToMappedType (C function)
      sipForceConvertToType (C function)
      sipFree (C function)
      sipGetAddress (C function)
      sipGetMixinAddress (C function)
      sipGetPyObject (C function)
      sipGetState (C function)
      sipGetWrapper (C function)
      sipImportSymbol (C function)
      sipIntTypeClassMap (C type)
      sipIntTypeClassMap.pyType. (C member)
      sipIntTypeClassMap.typeInt (C member)
      sipIsAPIEnabled (C function)
      sipLong_AsUnsignedLong (C function)
      sipMalloc (C function)
      sipMapIntToClass (C function)
      sipMapStringToClass (C function)
      SIPModuleMakefile (class in sipconfig)
      sipParseResult (C function)
      sipRegisterAttributeGetter (C function)
      sipRegisterProxyResolver (C function)
      sipRegisterPyType (C function)
      sipReleaseInstance (C function)
      sipReleaseMappedType (C function)
      sipReleaseType (C function)
      sipResolveTypedef (C function)
      sipSetDestroyOnExit (C function)
      sipSimpleWrapper (C type)
      sipSimpleWrapper.access_func (C member)
      sipSimpleWrapper.data (C member)
      sipSimpleWrapper.user (C member)
      sipSimpleWrapper_Type (C variable)
      sipStringTypeClassMap (C type)
      sipStringTypeClassMap.pyType. (C member)
      sipStringTypeClassMap.typeString (C member)
      sipTransferBack (C function)
      sipTransferBreak (C function)
      sipTransferTo (C function)
      sipTypeAsPyTypeObject (C function)
      sipTypeFromPyTypeObject (C function)
      sipTypeIsClass (C function)
      sipTypeIsEnum (C function)
      sipTypeIsMapped (C function)
      sipTypeIsNamespace (C function)
      sipTypeName (C function)
      sipTypeScope (C function)
      sipVoidPtr_Type (C variable)
      sipWrapper (C type)
      sipWrapper_Check (C function)
      sipWrapper_Type (C variable)
      sipWrapperType (C type)
      sipWrapperType_Type (C variable)
      Supertype (class annotation)

      T

      Transfer (argument annotation)
      (function annotation)
      TransferBack (argument annotation)
      (function annotation)
      transferback() (in module sip)
      TransferThis (argument annotation)
      (function annotation)
      transferto() (in module sip)

      U

      universal (sipconfig.Configuration attribute)
      unwrapinstance() (in module sip)

      V

      version_to_sip_tag() (in module sipconfig)
      version_to_string() (in module sipconfig)
      VirtualErrorHandler (class annotation)
      (function annotation)
      voidptr (class in sip)

      W

      wrapinstance() (in module sip)
      wrapper (class in sip)
      wrappertype (class in sip)
      sip-4.15.5/doc/html/incompatibilities.html0000644000076500000240000006077412310606652020606 0ustar philstaff00000000000000 Potential Incompatibilities with Earlier Versions — SIP 4.15.5 Reference Guide

      Potential Incompatibilities with Earlier Versions

      This section describes incompatibilities introduced by particular versions of SIP. Normally these are the removal of previously deprecated features.

      SIP v4.14.4

      Prior to this version, the handwritten code defined by the %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 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 %If directive. Starting with this version all directives are affected by the %If directive.

      SIP v4.10.1

      Newly Deprecated Features

      The following parts of the C API are now deprecated (but still supported).

      SIP v4.8

      __truediv__

      Prior to this version the __div__() special method implicitly defined the __truediv__() special method. From this version the __truediv__() special method must be explicitly defined.

      sipWrapper user Member

      Prior to this version the sipWrapper structure had a member called user which is available for handwritten code to use. From this version user is a member of the sipSimpleWrapper structure.

      sipWrapper pointers can be safely cast to 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 C API have been removed.

      • The a, A, M, N, O, P and T format characters from sipBuildResult() and sipCallMethod().
      • The a, A, L and M format characters from sipParseResult().
      • sipConvertToCpp()
      • sipIsSubClassInstance()
      • sipTransfer()
      • The transfer() function of the sip module.
      • The old-style generated type convertors.

      In addition the -a command line option to configure.py has been removed.

      Removal of PyQt-specific Features

      The following PyQt-specific support functions have been removed.

      • sipConnectRx()
      • sipDisconnectRx()
      • sipEmitSlot()
      • sipGetSender()

      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 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 %ConvertFromTypeCode and %ConvertToTypeCode now have the responsibility for implementing the Transfer and TransferBack annotations.

      SIP_BUILD

      The SIP_BUILD C preprocessor symbol has been removed.

      Newly Deprecated Features

      The following parts of the C API are now deprecated (but still supported).

      • The old-style generated type convertors.
      • sipConvertToCpp()
      • sipIsSubClassInstance()
      sip-4.15.5/doc/html/index.html0000644000076500000240000002621512310606652016175 0ustar philstaff00000000000000 SIP Reference Guide — SIP 4.15.5 Reference Guide sip-4.15.5/doc/html/installation.html0000644000076500000240000004751712310606652017577 0ustar philstaff00000000000000 Installation — SIP 4.15.5 Reference Guide

      Installation

      Downloading

      You can get the latest release of the SIP source code from http://www.riverbankcomputing.com/software/sip/download.

      SIP is also included with all of the major Linux distributions. However, it may be a version or two out of date.

      Configuring

      After unpacking the source package (either a .tar.gz or a .zip file depending on your platform) you should then check for any README files that relate to your platform.

      Next you need to configure SIP by executing the configure.py script. For example:

      python configure.py
      

      This assumes that the Python interpreter is on your path. Something like the following may be appropriate on Windows:

      c:\python32\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:

      --version

      Display the SIP version number.

      -h, --help

      Display a help message.

      --arch <ARCH>

      Binaries for the MacOS/X architecture <ARCH> will be built. This option should be given once for each architecture to be built. Specifying more than one architecture will cause a universal binary to be created.

      -b <DIR>, --bindir <DIR>

      The SIP code generator will be installed in the directory <DIR>.

      -d <DIR>, --destdir <DIR>

      The SIP module will be installed in the directory <DIR>.

      --deployment-target <VERSION>

      New in version 4.12.1.

      Each generated Makefile will set the MACOSX_DEPLOYMENT_TARGET environment variable to <VERSION>. In order to work around bugs in some versions of Python, this should be used instead of setting the environment variable in the shell.

      -e <DIR>, --incdir <DIR>

      The SIP header file will be installed in the directory <DIR>.

      -k, --static

      The SIP module will be built as a static library. This is useful when building the SIP module as a Python builtin (see Builtin Modules and Custom Interpreters).

      -n, --universal

      The SIP code generator and module will be built as universal binaries under MacOS/X. If the --arch option has not been specified then the universal binary will include the i386 and ppc architectures.

      -p <PLATFORM>, --platform <PLATFORM>

      Explicitly specify the platform/compiler to be used by the build system, otherwise a platform specific default will be used. The --show-platforms option will display all the supported platform/compilers.

      -s <SDK>, --sdk <SDK>

      If the --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.

      -u, --debug

      The SIP module will be built with debugging symbols.

      -v <DIR>, --sipdir <DIR>

      By default .sip files will be installed in the directory <DIR>.

      --show-platforms

      The list of all supported platform/compilers will be displayed.

      --show-build-macros

      The list of all available build macros will be displayed.

      --sip-module <NAME>

      The SIP module will be created with the name <NAME> rather than the default sip. <NAME> may be of the form package.sub-package.module. See Building a Private Copy of the sip Module for how to use this to create a private copy of the SIP module.

      The configure.py script takes many other options that allows the build system to be finely tuned. These are of the form name=value or name+=value. The --show-build-macros option will display each supported name, although not all are applicable to all platforms.

      The name=value form means that value will replace the existing value of name.

      The name+=value form means that value will be appended to the existing value of name.

      For example, the following will disable support for C++ exceptions (and so reduce the size of module binaries) when used with GCC:

      python configure.py CXXFLAGS+=-fno-exceptions
      

      A pure Python module called sipconfig.py is generated by configure.py. This defines each name and its corresponding value. Looking at it will give you a good idea of how the build system uses the different options. It is covered in detail in The 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 --platform command line option to specify the correct platform. For example:

      c:\python32\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 --platform command line option to specify the correct platform. For example:

      c:\python32\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 python32.lib python32_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.

      Table Of Contents

      Previous topic

      Potential Incompatibilities with Earlier Versions

      Next topic

      Using SIP

      sip-4.15.5/doc/html/introduction.html0000644000076500000240000003324412310606652017607 0ustar philstaff00000000000000 Introduction — SIP 4.15.5 Reference Guide

      Introduction

      This is the reference guide for SIP 4.15.5. 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 __dtor__() method which will be called from the C++ class’s virtual destructor
      • support for ordinary C++ functions, class methods, static class methods, virtual class methods and abstract class methods
      • the ability to re-implement C++ virtual and abstract methods in Python
      • support for global and class variables
      • support for global and class operators
      • support for C++ namespaces
      • support for C++ templates
      • support for C++ exceptions and wrapping them as Python exceptions
      • the automatic generation of complementary rich comparison slots
      • support for deprecation warnings
      • the ability to define mappings between C++ classes and similar Python data types that are automatically invoked
      • the ability to automatically exploit any available run time type information to ensure that the class of a Python instance object matches the class of the corresponding C++ instance
      • the ability to change the type and meta-type of the Python object used to wrap a C/C++ data type
      • full support of the Python global interpreter lock, including the ability to specify that a C++ function of method may block, therefore allowing the lock to be released and other Python threads to run
      • support for consolidated modules where the generated wrapper code for a number of related modules may be included in a single, possibly private, module
      • support for the concept of ownership of a C++ instance (i.e. what part of the code is responsible for calling the instance’s destructor) and how the ownership may change during the execution of an application
      • the ability to generate bindings for a C++ class library that itself is built on another C++ class library which also has had bindings generated so that the different bindings integrate and share code properly
      • a sophisticated versioning system that allows the full lifetime of a C++ class library, including any platform specific or optional features, to be described in a single set of specification files
      • the ability to include documentation in the specification files which can be extracted and subsequently processed by external tools
      • the ability to include copyright notices and licensing information in the specification files that is automatically included in all generated source code
      • a build system, written in Python, that you can extend to configure, compile and install your own bindings without worrying about platform specific issues
      • support for building your extensions using distutils
      • SIP, and the bindings it produces, runs under UNIX, Linux, Windows and MacOS/X

      SIP Components

      SIP comprises a number of different components.

      • The SIP code generator (sip). This processes .sip specification files and generates C or C++ bindings. It is covered in detail in Using SIP.
      • The SIP header file (sip.h). This contains definitions and data structures needed by the generated C and C++ code.
      • The SIP module (sip.so or 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 Python API for Applications.
      • The SIP build system (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 The Build System.
      • The SIP distutils extension (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 Building Your Extension with 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.

      Table Of Contents

      Previous topic

      SIP Reference Guide

      Next topic

      Potential Incompatibilities with Earlier Versions

      sip-4.15.5/doc/html/objects.inv0000644000076500000240000000757512310606653016360 0ustar philstaff00000000000000# Sphinx inventory version 2 # Project: SIP # Version: 4.15.5 # The remainder of this file is compressed using zlib. xڵ]K6ϯjdM`&=8m[$nacpIwя/ ?qH9>,wQD}r()mڈd0Mr|I˒B8-%2'QsS%?C9ykVOLJNP- otPX.l+pHIZ#<'IgAY`+Cu7znN&In D0uk)MJTbF1.USOIY$X4@cUu1Mj}_>Vd4pø` Q/yu:M1r 3ZqkǞP =Ees=R2}lҖ?譗M_{ M):߽@OtXL374=&od8/3 p %O\b؇5X.X1B- ~H_:"h>'{.bM2,jg\DW.Wׇq'(QJ7)B|#iuEO  Oz8:Zu30y%8:+2Y֯_g=\S<b= e0-~"pάݦGD+Ϝs>Юk{IgG>ɞg*?|q# &h/9yeۗk.Pj&?R }g&Fn15y/`(}$AD KNae? 'xI=3|=r.T% LItTyRCrK>CKs V~'$zs; -L-e ЅŚy(xb2Dcos,3n+:/X̧)`_#NR :t$PRu߷GQ/4Z'2\sS[E2OCmA)ҩ!jc&8^E'ӄ UӜL@GOPÖqN~|oO*RGb  CrtsMȹsLӨAh#9lH#?AG!Tq`3Z)Z1˸e*$!P08I}~sJdÕ zS@*w;MBhV}XLlntl+p.l,w@䜊Pbq}5&KcʹddӂbwH{b&'~{J  B#vbgגšTjj,Rϛ(TPE34ˀҽ]L^ce0ꩶAYҕ %O v_II ~[j\/\hr%:jtaG ~V#ݲkNr XǪ $3jyU33< j(FdV$: LPQ0v3X" Nxͩ53y]x,f0Ey R5( E^$V%LD2[=lGRk:.wyj0JZvu@/^MrG/6gCg6.~&6ϓm>kPSI(]]qF'ֹ}ϳ<]H|'%pPVaBP\b6nq),*TV3;tz&.+핪lLZs~DbS}{+hY9$Vu^Vݫ68܂+87iks+$:$M1 ڧzs8CqNe(dA{hk!Ԗ9>T҆2U鄃I|M[z:)*-"'u[_6%F[3)B )&*RNBs\.s_'\`mבJ^@zbo7=րKX^u>zWfa}\='suaLf֥5 ܊K"Ĩ$Jh {N!GnsX0!dfQDX]("9lu#>ɕ28vjO+ϪHZ=hW$-Ri lf㮫Xr ~r4ν)V氪O@kPa_ ~O؄C oǐ:vk'I2hvŹT]yGս\tKΡQ}$,SKgj!bQ9#ĸ]fj aƴk7K&1a~S2t-+s΍oyL-WqtdYV>$V޷>٥ f lmfFKP qWl`'>3<2\h]֙~\f Xߪsip-4.15.5/doc/html/py-modindex.html0000644000076500000240000000750312310606653017323 0ustar philstaff00000000000000 Python Module Index — SIP 4.15.5 Reference Guide

      Python Module Index

      s
       
      s
      sip
      sipconfig
      sip-4.15.5/doc/html/python_api.html0000644000076500000240000010514612310606652017241 0ustar philstaff00000000000000 Python API for Applications — SIP 4.15.5 Reference Guide

      Python API for Applications

      The main purpose of the 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.

      sip.cast(obj, type) → object

      This does the Python equivalent of casting a C++ instance to one of its sub or super-class types.

      Parameters:
      • obj – the Python object.
      • type – the type.
      Returns:

      a new Python object is that wraps the same C++ instance as obj, but has the type type.

      sip.delete(obj)

      For C++ instances this calls the C++ destructor. For C structures it returns the structure’s memory to the heap.

      Parameters:obj – the Python object.
      sip.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.

      Parameters:obj – the Python object.
      sip.enableautoconversion(type, enable) → bool

      New in version 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.

      Parameters:
      • type – the Python type object.
      • enable – is True if auto-conversion should be enabled for the type. This is the default behaviour.
      Returns:

      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.

      sip.getapi(name) → version

      New in version 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 sip.setapi() or implicitly by importing the module that defines it.

      Parameters:name – the name of the API.
      Returns:The version number that has been set for the API. An exception will be raised if the API is unknown.
      sip.isdeleted(obj) → bool

      This checks if the C++ instance or C structure has been deleted and returned to the heap.

      Parameters:obj – the Python object.
      Returns:True if the C/C++ instance has been deleted.
      sip.ispycreated(obj) → bool

      New in version 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.

      Parameters:obj – the Python object.
      Returns:True if the C/C++ instance was created by Python.
      sip.ispyowned(obj) → bool

      This checks if the C++ instance or C structure is owned by Python.

      Parameters:obj – the Python object.
      Returns:True if the C/C++ instance is owned by Python.
      sip.setapi(name, version)

      New in version 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.

      Parameters:
      • name – the name of the API.
      • version – The version number to set for the API. Version numbers must be greater than or equal to 1.
      sip.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.

      Parameters:obj – the Python object.
      sip.setdestroyonexit(destroy)

      New in version 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.

      Parameters:destroyTrue if all C++ instances and C structures owned by Python should be destroyed when the interpreter exits. This is the default.
      sip.settracemask(mask)

      If the bindings have been created with SIP’s -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.)

      Parameters: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 sip.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 sip.wrapper type but do not support the concept of object ownership.

      sip.SIP_VERSION

      This is a Python integer object that represents the SIP version number as a 3 part hexadecimal number (e.g. v4.0.0 is represented as 0x040000). It was first implemented in SIP v4.2.

      sip.SIP_VERSION_STR

      This is a Python string object that defines the SIP version number as represented as a string. For development snapshots it will start with snapshot-. It was first implemented in SIP v4.3.

      sip.transferback(obj)

      This function is a wrapper around sipTransferBack().

      sip.transferto(obj, owner)

      This function is a wrapper around sipTransferTo().

      sip.unwrapinstance(obj) → integer

      This returns the address, as an integer, of a wrapped C/C++ structure or class instance.

      Parameters:obj – the Python object.
      Returns:an integer that is the address of the C/C++ instance.
      class sip.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.

      __init__(address[, size=-1[, writeable=True]])
      Parameters:
      • address – the address, either another sip.voidptr, None, a Python Capsule, a Python CObject, an object that implements the buffer protocol or an integer.
      • size – the optional associated size of the block of memory and is negative if the size is not known.
      • writeable – set if the memory is writeable. If it is not specified, and address is a sip.voidptr instance then its value will be used.
      __int__() → integer

      This returns the address as an integer.

      Returns:the integer address.
      __getitem__(idx) → item

      New in version 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.

      Parameters:idx – is the index which may either be an integer, an object that implements __index__() or a slice object.
      Returns: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 voidptr object defining the subset of the memory corresponding to the slice.
      __hex__() → string

      This returns the address as a hexadecimal string.

      Returns:the hexadecimal string address.
      __len__() → integer

      New in version 4.12.

      This returns the size associated with the address.

      Returns:the associated size. An exception will be raised if there is none.
      __setitem__(idx, item)

      New in version 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.

      Parameters:
      • idx – is the index which may either be an integer, an object that implements __index__() or a slice object.
      • 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.
      ascapsule() → capsule

      New in version 4.10.

      This returns the address as an unnamed Python Capsule. This requires Python v3.1 or later or Python v2.7 or later.

      Returns:the Capsule.
      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.

      Returns:the CObject.
      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.

      Parameters: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.
      Returns:the string or bytes object.
      getsize() → integer

      This returns the size associated with the address.

      Returns:the associated size which will be negative if there is none.
      setsize(size)

      This sets the size associated with the address.

      Parameters:size – the size to associate. If it is negative then no size is associated.
      getwriteable() → bool

      This returns the writeable state of the memory.

      Returns:True if the memory is writeable.
      setwriteable(writeable)

      This sets the writeable state of the memory.

      Parameters:writeable – the writeable state to set.
      sip.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.

      Parameters:
      • addr – the address of the instance as a number.
      • type – the Python type of the instance.
      Returns:

      the Python object that wraps the instance.

      class sip.wrapper

      This is the type object of the default base type of all instances wrapped by SIP. The Supertype class annotation can be used to specify a different base type for a class.

      class sip.wrappertype

      This is the type object of the metatype of the sip.wrapper type.

      Previous topic

      Using the C API when Embedding

      Next topic

      The Build System

      sip-4.15.5/doc/html/search.html0000644000076500000240000000706312310606653016334 0ustar philstaff00000000000000 Search — SIP 4.15.5 Reference Guide

      Search

      Please activate JavaScript to enable the search functionality.

      From here you can search these documents. Enter your search words into the box below and click "search". Note that the search function will automatically search for all of the words. Pages containing fewer words won't appear in the result list.

      sip-4.15.5/doc/html/searchindex.js0000644000076500000240000013100412310606653017025 0ustar philstaff00000000000000Search.setIndex({envversion:42,terms:{sipcanconverttoinst:[9,4],sip_release_gil:[9,10,4],sipconvertfromtyp:[10,4],four:10,secondli:13,prefix:[0,13,10,11,4],mkcustom:7,whose:[13,8,4],accur:12,"const":[4,10,11,12,13,8],cmdclass:3,pylist_set_item:10,concret:10,under:[0,2,4,5,10,11],qlabel:13,everi:[0,13,10],ascapsul:14,"void":[4,14,10,12,13,8],capul:8,digia:5,appar:10,"__nonzero__":12,sipconverttotypedarrai:4,sip_pydict:[12,8],initialis:[0,13,10,4],sipconvertfromvoidptrands:4,capsul:[8,14,4],speci:4,direct:[0,6,8,4],consequ:12,second:[0,10,4],b_mod:10,module_as_lib:0,even:[4,9,10,12,13,14],neg:[0,14,4],qpoint:10,setdestroyonexit:14,"new":[2,3,4,5,6,8,10,12,13,14],net:0,ever:8,sipdisconnectrx:9,getsiz:14,q_os_win:13,abov:[0,8,3],unguardedpoint:4,mem:4,never:[13,10,8,4],here:[5,12],debugg:8,path:[2,3,4,9,10,13],interpret:[0,8],incdir:[13,2],adopt:[5,10],create_cont:0,create_word:13,sip_derived_class:10,default_sip_dir:[0,13],unix:[0,5,7,13],pythonmodulemakefil:0,total:10,unit:10,describ:[3,4,5,6,7,9,10,12,13,8],would:[13,7,10,8,4],sipregisterattributegett:[13,4],call:[0,2,4,5,6,7,8,9,10,11,12,13,14],until:[13,8],autogen:8,successful:4,relat:[5,10,2,13],notic:5,warn:[0,5,6,8],"__iter__":12,hold:4,unpack:2,must:[0,2,4,5,6,7,8,9,10,11,12,13,14],join:13,exportderiv:8,restor:[14,4],arbitari:10,setup:3,work:[0,2,4,9,10,13,8],sipbadcallablearg:4,root:[10,2],unnam:[10,14],overrid:[0,13,10],give:2,indic:[0,10,8],timer:10,want:[0,3,7,10,13,8],sip_module_dict:11,slicelen:4,unsign:[12,8,4],end:[12,13,10,4],quot:8,ordinari:[5,13,10,14,8],how:[2,5,7,10,11,13],answer:13,place:[0,4,6,10,12,13,8],coff2omf:2,config:[0,13,3],bindir:2,updat:[10,14,4],after:[0,2,4,10,13,8],sipwrapp:4,"_pkg_config":13,py_buff:10,befor:[0,4,6,10,13,8],wrong:12,nokeywordarg:8,arch:[0,2],parallel:6,demonstr:13,attempt:[10,4],opaqu:[12,10,4],c_mod:10,exclud:[0,10,8],receiv:12,maintain:[0,13],environ:2,finalis:[0,13],exclus:[13,10],get_sip_api:11,order:[2,4,5,8,9,10,12,13,14],origin:[5,10,8],composit:10,over:[0,13,10,4],becaus:[5,13,9,10,7],privileg:2,affect:[0,9,10],pyerr_setstr:10,delaydtor:8,easier:[0,13,6,4],this_word:13,thei:[0,4,6,7,9,10,12,13,8],fragment:[10,11],safe:[5,9,10,4],sip_read_onli:4,"break":[13,10],singleshot:8,choic:[5,13,10],bigetreadbuffercod:[12,10],unpickl:10,each:[0,2,4,6,7,10,11,13,8],debug:[0,6,10,2,14],bigetsegcountcod:[12,10],side:10,mean:[0,2,4,8,9,10,11,13,14],v1_0:10,v1_1:10,sipcanconverttomappedtyp:[9,4],sipemitslot:9,collector:[13,10,8,4],unbound:8,sip_nameerror:12,goe:5,newli:[8,4],pycobject:[11,4],content:[0,2,3,4,6,10,12,13],pyqtconfig:[0,13],allownon:8,build_fil:[0,13],situat:13,free:[13,2],standard:[2,3,5,7,10,13],"__setitem__":[12,8,14,4],voidptr:[8,14,4],precompil:10,foo_support:10,extra_cflag:0,traceback:10,v3_0:10,isn:[10,14,4],setwrit:14,selfp:4,rang:[13,10,8,4],siperr:10,mkdir:0,independ:[13,10],restrict:[7,10,8],hook:3,unlik:[5,13,10],mingw:0,messag:[0,5,6,2],wasn:4,sip_keyerror:12,iserr:4,top:[0,13],sometim:[12,13,7,8],fiction:13,mercuri:5,too:10,consol:[0,7],defaultdocstringformat:10,namespac:[5,1,4],tool:5,lower:[10,8,11,4],sipcanconverttotyp:[10,4],read_vers:0,reinterpret_cast:10,target:[0,2],keyword:[5,10,6,8],provid:[0,4,5,6,7,8,9,10,12,13,14],sipexceptionref:10,matter:[12,13,10],wchar_t:[12,13,4],sip_lookuperror:12,modern:6,raw:10,increment:4,incompat:[10,8,4],sipwrappertyp:[10,4],remove_lead:10,pydict_getitemstr:11,simplifi:10,though:[9,10,14,4],sipself:10,object:[0,8],deleg:8,lexic:4,letter:4,don:10,doc:[10,6],doe:[0,4,5,7,8,9,10,12,13,14],declar:[4,6,10,12,13,8],unchang:[10,4],dot:[12,10,8],"__str__":12,syntax:[6,8],qstring:[13,10],identifi:[10,6,8,4],siperror:[10,4],involv:4,absolut:0,pystring_fromstr:4,acquir:[13,10,4],explain:10,configur:[0,1,9,7],dd_name:8,qwidget:[13,10,8],"__call__":12,stop:4,next:[10,7,2,8,13],report:10,novirtualerrorhandl:[10,8],bar:[13,10],emb:11,baz:13,pyerr_print:[10,8],sipclass:10,pyexc_valueerror:10,set_build_macro:0,result:[10,6,8,4],respons:[5,13,9,10,4],fail:[10,4],best:8,subject:[13,10],sip_unicodetranslateerror:12,hopefulli:13,simplest:13,sip_zerodivisionerror:12,clean_build_file_object:0,handwritten:8,accord:[13,7,4],extend:[5,13,10],sip_overflowerror:12,extens:[0,4],lazi:[1,4],preprocessor:[0,13,9,10,4],rtti:[10,4],protect:[0,4,5,6,7,10,12,13,14],expos:14,fault:[14,4],howev:[2,8,10,11,12,13,14],set_count:10,against:[0,13,10],sipfindclass:[9,4],logic:10,fno:2,com:[5,2],create_wrapp:0,seqlen:4,getwrit:14,setapi:[13,14],qlist:10,three:[0,13],been:[0,2,3,4,8,9,10,11,12,13,14],much:13,siptypeismap:4,interest:13,q_signal:12,"__len__":[12,14,8],sipconvertfrominst:[9,4],life:13,suppress:[8,14,4],child:13,"catch":[10,6],riverbankcomput:[5,2],wobj:10,qtcoremod:[13,10],ident:10,visitproc:10,properti:[0,10],weren:9,"__ge__":12,have:[0,2,4,5,7,8,9,10,11,12,13,14],sip_slot_con:12,tabl:4,toolkit:5,sever:[0,5,9,4],sipselfwasarg:10,docvalu:8,perform:8,suggest:13,make:[0,2,4,5,6,7,9,10,12,13,8],export_al:0,bigetbuffercod:[12,10],complex:1,split:[13,6],sipgetsend:9,complet:[10,6,14,13],sip_api_major_nr:4,"__idiv__":12,rais:[0,4,8,9,10,13,14],ownership:[1,4,5,14,10,8],qaccel:12,tune:[0,13,2],redefin:[0,10,6,4],kept:[8,4],siptypeisclass:4,inherit:[13,10],sip_importerror:12,wherebi:4,thi:[0,2,4,5,6,7,8,9,10,12,13,14],win32_platform:10,programm:[12,10],everyth:13,left:[0,10,8],sip_keyboardinterrupt:12,protocol:[12,8,14,4],just:[0,3,4,9,10,12,13],memoryview:[14,4],gctraversecod:[12,10],languag:[13,10],previous:4,characterist:8,easi:0,had:[5,9],sip_eoferror:12,qtguimod:[13,10],siptypeaspytypeobject:4,els:[13,10,11],save:[10,4],opt:3,applic:[1,2,4,5,7,10,11,8],specif:[0,10,6,8,4],arbitrari:[9,10],specifii:8,sip_syntaxerror:12,cxxflag:2,underli:[12,8,4],www:[5,2],pymem_malloc:4,old:[5,13,9,10],deal:[12,13,10],sip_indentationerror:12,sipgetpyobject:4,indirect:10,successfulli:[10,8],cooper:10,deploy:[0,10,2,13],buffer:[1,4,14,10,12,8],simplewrapp:[13,10,14,4],foo:[13,10,8],dd_next:8,"__ne__":12,sensibl:10,repositori:5,sipenum_:4,"super":[0,4,8,10,12,13,14],"__long__":12,customw:7,pyarg_parsetupl:[12,10,4],py_modulegetdict:10,obj:[9,10,14,4],chronolog:0,unfortun:[14,4],"__mul__":12,produc:5,ppc:2,py_decref:10,regist:[13,4],"__dtor__":5,encod:[0,10,8,4],bound:[10,8,4],down:0,right:[0,10,11],"__and__":12,sipcanconverttoenum:4,often:[13,10,8,11],accordingli:13,suffici:3,segment:[13,10],support:[0,1,2,3,4,6,9,10,8],avail:[2,3,4,5,9,10,12,13],reli:9,extra_cxxflag:0,siptransf:9,siptype_qpoint:10,gil:[4,6,9,10,13,8],qtcore:[0,10],"__isub__":12,form:[0,6,2,13],some:[2,4,5,6,8,7,10,12,13,14],taken:[0,10,4],heap:[13,8,10,14,4],"true":[1,10,14,8],arrays:8,intern:[12,10,14,8],tell:13,sip_except:[12,10],minor:4,raisespyexcept:[10,8],hierachi:[13,9],sip_unicodeerror:12,unrel:10,emit:[12,8,4],featur:[0,10,6,8],initialisationcod:[12,13,10],classic:1,sipforceconverttoinst:[9,4],"abstract":[5,10,8],exist:[0,2,4,6,10,14],trip:12,bmake:0,readonli:4,py_lib_dir:0,when:[0,3,4,6,10,8],test:[10,4],asstr:14,intend:[0,13,10,8,11],sipenum_klass_enum:4,"__iand__":12,sipsimplewrapp:[9,10,4],longer:[9,10,4],pseudo:8,sip_pyslic:[12,8],ignor:[0,4,8,9,10,13,14],sipcppptr:10,time:[0,4,5,6,8,10,13,14],ptr:10,leftmargin:0,sip_attributeerror:12,concept:[5,13,14],skip:[13,10],global:[1,4,5,6,9,10,12,8],signific:[10,6,8],supplement:10,raisecod:[12,10],"__rshift__":12,depend:[0,2,4,8,9,10,14],sipimportsymbol:4,decim:0,riverbank:10,cobject:14,sip_mod_dir:0,sourc:[0,5,6,2,10],string:[0,4,8,10,12,13,14],extra_lib_dir:0,convertfromtypecod:10,"__bool__":12,word:[13,10,11,3,8],exact:[12,13,10,8,4],administr:2,level:[10,8],did:[0,9],gui:[0,5,7],pylist_new:10,"0x0001":14,item:[10,14],sipstringtypeclassmap:4,dir:[0,6,2],prevent:[13,7,10,8,4],core:3,sipvoidptr_typ:4,sign:[12,8,4],minimis:5,port:2,appear:[10,8],gcclearcod:[12,10],current:[0,13,10,8,4],qscintilla:6,sipdelayeddtor:8,iarr:[12,10],deriv:[0,7,8],gener:[0,8],explicitli:[2,5,8,9,10,12,13,14],address:[8,10,14,4],"__hex__":14,sip_runtimeerror:12,along:10,behav:[13,14],convertor:[9,4],extra:[0,13,6,8,4],modul:[0,8],prefer:10,pyobject_typecheck:4,sip_slot_di:12,instal:[0,1,7],sipregisterpytyp:[13,10,4],moduleheadercod:[12,10],memori:[4,5,14,10,13,8],univers:[0,2],visit:10,sipfindnamedenum:[9,4],siptypenam:4,msg:0,scope:[12,10,8,4],siptype_qtimerev:10,sip_pytupl:[12,10,8],scite:6,pyqwt:0,claus:[10,8],templat:[0,5,10,12,13,8],prepar:1,excepton:9,uniqu:[10,4],descriptor:13,can:[0,2,3,4,5,6,7,8,9,10,11,12,13,14],purpos:[0,8,10,14,4],problemat:10,sipptrptr:10,isdelet:14,occur:[0,10,8],alwai:[4,5,6,10,13,8],multipl:[10,2,8,13],"__license__":10,sipmalloc:[13,4],sip_protected_is_publ:[10,4],write:[0,4,5,7,10,13],pure:[0,2,5,10,13,8],sip_memoryerror:12,"__next__":12,sipsetdestroyonexit:4,sipmodulemakefil:[0,13],mixin:[9,10,8,4],mai:[0,2,4,5,6,7,8,9,10,12,13,14],underscor:[10,11,4],data:[4,5,10,11,12,14],sipcallmethod:[9,10,4],sip_qobject:12,stdin:6,explicit:[12,10,8],inform:[0,5,6,10,12,13,14],"switch":10,preced:[0,8,11],combin:[0,10,4],callabl:[5,12,9,10],converttosubclasscod:[12,10,4],wrapinst:14,size_t:4,still:[13,9,10,7,8],pointer:[4,9,10,11,12,8],dynam:[13,7,4],entiti:10,conjunct:[10,8],disconnect:12,platform:[0,2,5,6,10,12,13],window:[0,2,5,6,7,13],main:[10,14,8],non:[0,4,7,10,13,8],"float":[12,8,4],siplenptr:10,contriv:10,initi:[10,4],qcustomev:10,now:[13,9,10,7,4],nor:10,introduct:1,pykd:0,term:[5,10],name:[0,8],realist:13,transferback:[13,9,14,8,4],sipgetaddress:4,revers:13,revert:9,separ:[0,4,6,10,12,13,8],sipsimplewrapper_typ:4,argumentless:10,sip_pycal:[12,8],compil:[0,4,6,9,10,8],sip_vers:[0,14,4],sip_standarderror:12,replac:[0,2,4,10,11,13],individu:[0,10],sip_4_13:10,continu:10,wrap:[0,4,5,6,8,10,11,12,13,14],sipconvertfromsliceobject:4,happen:[13,10,14,4],py_ssize_t:[12,4],shown:10,sipforceconverttomappedtyp:[9,4],space:[0,10],"0x0010":14,bespok:0,correct:[2,4,7,10,13,8],earlier:4,migrat:13,"byte":[8,10,14,4],unpredict:[8,14,4],care:[0,13],sip_4_12:10,setdefault:13,sipconverttovoidptr:4,thing:[13,10,14],pyslice_getindicesex:4,imposs:13,first:[0,4,5,6,10,12,13,14],oper:[10,8],reimplement:[0,9,10,8,4],directli:[11,4],onc:[2,8,4],arrai:[12,13,10,8,4],sipiserr:10,oppos:4,dump_object:10,open:10,sip_configur:[0,13],size:[0,2,4,6,8,10,14],given:[2,4,6,10,13,14],silent:10,convent:10,sippi:10,caught:[10,8],convention:13,conveni:[10,4],sipseg:10,especi:5,pyqt3:13,"public":[0,4,6,10,12,13],copi:[0,1,2,4,8,7,10,12,14],specifi:[0,2,3,4,5,6,8,10,12,13,14],pyqt4:[13,10,8],enclos:[10,9,6,4],than:[0,2,4,8,7,10,13,14],virtualcatchercod:[12,10,4],serv:8,wide:[1,4],deindent:10,py_vers:0,were:[0,9,6],posit:[0,10,8],pre:10,sai:[12,13],"__getattribute__":12,ani:[0,2,3,4,5,6,7,8,9,10,12,13,14],doctyp:8,techniqu:7,sipconvertfromsequenceindex:4,note:[4,7,10,11,12,13,8],take:[0,2,7,10,12,13,8],noth:[12,10],begin:[10,4],sure:[12,10,2,13,4],trace:[6,14],normal:[0,3,4,7,8,9,10,13,14],multipli:8,sipforceconverttotyp:4,pair:[0,8],homepag:5,later:[4,5,10,11,12,13,14],picklecod:[12,10],show:[10,2,8,11],"0x020303":0,"__irshift__":12,slot:[5,12,8],sipgetst:[10,4],onli:[0,4,5,10,12,13,8],slow:0,noscop:8,activ:12,state:[10,14,4],api_export_symbol:11,dict:[0,4],variou:[2,14,4],get:[0,2,4,10,11,13,8],cannon:0,soon:10,cannot:[12,10,8,11],requir:[0,2,4,5,8,7,10,13,14],mybool:8,borrow:4,pynam:[10,8],hellomodulemakefil:13,where:[0,4,5,10,12,13,14],pytyp:4,keyboard:12,prehook:8,sipcpp:[12,10],concern:9,arg_nr:4,detect:[13,10,4],sippytyp:10,accesscod:[12,10],enumer:4,label:13,between:[4,5,10,11,12,13,8],"import":[0,3,4,5,6,7,10,11,12,13,14],across:13,sipwrappercheck:11,parent:13,fundament:4,inflex:10,cycl:[13,4],setcod:[12,10],come:4,"0x0020":14,programmakefil:0,inconsist:10,sipresolvetypedef:4,mani:[5,13,2,8],among:3,acceler:12,undocu:10,period:10,exploit:[5,13,10],colon:8,sipconvertfromconstvoidptr:4,build_command:0,default_bin_dir:0,endif:[13,10,11],mark:14,siparg:10,sip_pybuff:[12,8],derefer:10,thousand:13,ascobject:14,sip_indexerror:12,"__eq__":12,those:[0,4,14,10,13,8],"case":[0,8,10,11,12,13,14],defaultmetatyp:[12,13,10],py_typ:4,"__mod__":12,my_except:10,sip_arithmeticerror:12,cast:[12,9,10,14,4],invok:[0,5,10,3],invoc:8,sipreleasetyp:[10,8,4],margin:0,advantag:[10,8],stdout:0,support_foo:10,them:[0,5,9,10,13],worri:5,myapi:13,ascii:[10,8,4],concatan:8,"__init__":[0,13,7,10,14],develop:[0,2,4,5,13,14],"__delattr__":12,same:[0,3,4,7,8,9,10,12,13,14],check:[0,2,4,8,10,11,14],ispyown:14,binari:[0,10,2,12],html:10,pad:4,document:[5,10,6,13],metatyp:[13,10,14,8],nest:[12,10],sipgilst:[9,10,4],sipmethod:[10,4],footprint:13,appropri:[0,10,2,8,4],macro:[0,13,2,4],without:[0,4,5,9,10,12,13,8],sipmappedtyp:4,dereferenc:8,"__int__":[12,14],sipregisterproxyresolv:4,execut:[0,2,4,5,6,8,9,10,13,14],tip:6,rest:[10,4],releasegil:[10,6,8,13],siptransferobj:10,unitpostincludecod:10,tobj:10,struct:[12,13,10,4],littl:[12,13],real:[12,10],around:[0,2,4,8,9,10,12,13,14],read:[0,12,10,4],swig:5,world:13,part:[0,4,5,7,8,9,10,12,13,14],sip_ssize_t:[12,10,4],saniti:11,whitespac:[13,10],integ:[0,4,14,10,12,8],either:[0,2,3,4,8,10,13,14],output:10,manag:[5,1,10,8,4],wrappertyp:[13,10,14,4],pyconfig:0,ascend:4,slice:[12,14,4],definit:[5,1,10,8,4],siperrorfail:10,sip_assertionerror:12,exit:[0,8,14,4],notabl:6,freed:[13,8,4],mname:0,garbag:[13,8,10,14,4],cppptr:4,fulli:[0,4],immut:4,appli:[13,9,10,8,4],"throw":[12,9,10,8,4],src:0,methodcod:[12,10,8,4],a_modul:12,sip_stopiter:12,sipprotectvirt_foo:10,processor:10,slash:8,strip:0,pyobject_callobject:4,your:[0,7],macos_platform:10,generate_target_default:0,fast:5,mingw32:13,area:4,aren:13,hex:8,modulemakefil:[0,7],start:[0,4,5,8,9,10,13,14],compliant:4,interfac:[1,10,14],prot_is_publ:0,lot:0,timelin:[0,10,6,12,13],"__invert__":12,tupl:[0,12,10,8,4],py_end_allow_thread:[12,10],nmake:13,rightmargin:0,"default":[0,2,4,6,8,10,12,13,14],pylist_get_s:10,"__le__":12,embed:10,deadlock:13,holdgil:[10,6,8,13],expect:[4,9,10,12,13,8],creat:[0,2,3,4,5,8,7,10,12,13,14],certain:[10,8,4],a0kei:10,file:[0,1,2,3,4,5,6,7,9,10,11,8],sip_taberror:12,again:[13,10,8,4],readi:0,q_object:13,reduct:6,field:8,wai:[13,7,10,14,4],writabl:14,pathnam:0,you:[0,2,3,5,7,8,9,10,12,13,14],architectur:[0,2],noderiv:8,sequenc:[0,8,4],symbol:[0,10,9,2,4],docstr:[5,10,6,12,8],track:13,reduc:[13,2],directori:[0,2,3,5,6,7,10,13],descript:[0,10,6,12,4],stdexcept:10,py_initmodul:10,potenti:10,cpp:[6,3,4],dst:0,represent:[0,10],all:[0,2,4,5,6,8,9,10,11,12,13,14],unencod:[10,8],abil:[0,5],sipconvertfrommappedtyp:[9,4],follow:[0,2,3,4,5,7,8,9,10,11,12,13,14],children:13,sipconvertfromnewpytyp:4,"__cmp__":12,program:[0,13,14],sip_ioerror:12,sip_feature_:10,dd_isderiv:8,setdelet:14,introduc:[13,9,10],sipvisit:10,liter:13,fals:[12,9,10,14],util:[5,10],mechan:[5,13,4],fall:4,veri:[13,10,4],sipcppret:10,swig_opt:3,sipunus:10,list:[0,6,8],posthook:8,siptypescop:4,adjust:0,hello_sip_flag:13,stderr:[0,10],small:[5,13],py_begin_allow_thread:[12,10],py_inc_dir:0,platform_lib:0,ten:13,interpretor:13,pyobject:[12,10,11,4],python32_bcpp:2,keeprefer:8,zero:[0,4,8,7,10,13,14],design:[5,8],pass:[0,4,6,7,9,10,11,13,8],what:[5,13,10],sub:[0,2,4,5,8,10,13,14],sipconverttoinst:[9,4],section:[9,10,8,4],abl:[7,10,8],overload:[5,10],delet:[10,14],version:[0,3,4,6,10,11,8],method:[0,4,5,6,7,8,9,10,12,13,14],hasn:[10,4],full:[0,2,4,5,6,10,12,13],themselv:10,sipfindmappedtyp:[9,4],sophist:5,behaviour:[13,9,10,14,4],sip_vmserror:12,modifi:[0,7,4],valu:[0,2,4,9,8,7,10,12,13,14],search:[10,9,6,13],helloconfig:13,"__xor__":12,prior:[9,10,4],amount:[10,8],via:[10,8,4],transit:5,deprec:[10,6,8,4],inappropri:4,sipbadlengthforslic:4,select:13,hexadecim:[0,14,4],etc:10,sip_sign:12,two:[0,2,9,10,12,13],qt_4_2_0:13,sip_oserror:12,more:[0,1,2,4,6,10,8],desir:[10,8],sip_block_thread:[10,4],c_api:11,hundr:13,ital:10,flag:[0,5,10,13,4],bireleasebuffercod:[12,10],particular:[0,6,7,9,10,13,8],known:[14,4],destin:0,cach:4,none:[0,13,10,14,8],sipprotect_foo:10,remain:[12,10,6,4],pylist_check:10,v2_0:10,def:13,factori:[13,8,4],share:[5,4],accept:8,sipreleaseinst:[9,4],cours:11,newlin:0,rather:[0,2,4,8,7,10,13,14],anoth:[0,4,5,8,10,12,13,14],siperrorcontinu:10,divis:1,sipinttypeclassmap:4,simpl:[0,1,12,3,5],resourc:4,referenc:[10,11,4],api_wrapper_check:11,sip_windowserror:12,compulsori:[10,8],reflect:12,sipconfig:[0,5,7,2,13],generate_target_instal:0,associ:[13,8,10,14,4],circumst:[10,14,4],"short":[12,10,8,4],qtgui:[0,13,10],required_str:0,sip_ssize_t_format:4,assign:[13,4],caus:[2,4,6,14,13,8],callback:5,pyerr_fetch:10,help:[0,5,6,2],a_mod:10,held:[9,10],i386:2,through:[0,10],hierarchi:[12,13,10,4],paramet:[0,8,6,14,4],use_argument_nam:10,style:[0,9],scon:0,might:[0,12,10,8,13],good:2,"return":[0,4,8,10,11,13,14],timestamp:[10,6],exportedheadercod:[12,10],framework:0,somebodi:13,converttotypecod:[10,8,4],"0x0008":14,easili:10,achiev:[12,13,4],alreadi:[4,14,10,11,13,8],compris:5,found:[0,13,4],unicod:[13,10,8,4],"0x0004":14,inplac:[12,10],"0x0002":14,hard:13,idea:2,connect:[5,12,8],notypenam:8,event:[9,10],setsiz:14,publish:13,print:10,occurr:10,siptype_klass:[10,4],qualifi:[10,4],proxi:4,effect:[12,10],reason:[13,10],base:[0,4,5,8,10,12,14],sbf:13,ask:10,earliest:[0,10],basi:10,pylist_get_item:10,thread:[0,5,9,10,13,8],pycobject_check:11,omit:[12,10,6,8],perhap:7,lifetim:5,interact:13,siptypeisnamespac:4,major:[2,4],default_mod_dir:[0,13],obviou:[12,13],upper:[10,8,4],number:[0,1,2,4,5,6,8,10,14],extern:[5,10,8],done:[13,9,10,8],construct:[13,10],blank:10,stabl:5,miss:9,build_ext:3,"__float__":12,gpl:[5,10],differ:[0,2,5,8,9,10,12,13,14],script:[0,2,3,5,7,10,13],guardedpoint:4,least:13,mfile:0,default_virtualerrorhandl:[10,8],"__ixor__":12,store:10,statement:[12,10,6,14],relationship:[13,4],sipenableautoconvers:[10,4],siptransferbreak:[13,4],getter:[13,10,4],pars:[0,12,10,8],std:10,version_to_sip_tag:0,cyclic:[13,10,8,4],remov:[0,10,8,4],sip_api_minor_nr:4,str:8,consumpt:5,chkdir:0,comput:[10,8],create_config_modul:[0,13],tp_name:[8,4],packag:[0,2,7,10,13,8],"null":[10,11,4],option:[0,2,3,4,5,6,7,8,9,10,13,14],sipkwd:10,"0x040000":[0,14,4],built:[0,2,5,7,10,13],equival:[0,12,10,14,8],self:[0,13,10,8],ext_modul:3,also:[0,2,4,5,6,7,10,11,12,13,8],brace:10,distribut:[5,7,2],exec:8,klassinst:10,previou:[13,8,10,14,4],defaultencod:[12,10,8],most:[12,10,6,14,4],finalisationcod:10,maco:[0,5,2],addr:14,clear:[10,8],cover:[5,10,2,13],destruct:[14,4],dimension:4,transferobj:4,supertyp:[13,10,14,8],extra_lflag:0,latest:[0,5,10,2],microsoft:2,getcod:[12,10],xcode:2,particularli:14,sip_rxobj_con:[12,8],unitcod:[12,10],fine:[0,13,2],find:[5,13,8],copyright:[5,10],keyreleas:10,unus:10,express:[0,12,10],py_non:[10,4],pyint:8,mappedtyp:[12,10],setdata:10,"_c_api":11,catcher:10,whenev:[13,9,8],common:[5,10,14],sip_unboundlocalerror:12,noreleas:8,set:[0,2,4,5,6,8,10,11,13,14],dump:14,mutabl:4,extra_include_dir:0,sipr:10,arg:[10,4],"__imod__":12,pythonw:7,call_exec:8,python32:2,keypress:10,siptypeisenum:4,smallest:0,subdir:0,sip_:10,altern:[5,12,8,14,13],signatur:[4,5,6,9,10,12,8],latin:[10,8,4],sipconverttoarrai:4,disallow:[10,4],popul:[13,10,4],both:[0,4,5,10,12,13,8],last:[12,13,10,8],license:10,operat:12,context:[12,10,8,4],let:13,deployment_target:0,whole:[13,10],load:[0,5,7,14],sip_4_13_2:10,sipclass_klass:[10,4],simpli:[13,10],point:[4,14,10,12,13,8],instanti:[12,10,8],header:[0,2,5,6,10,11,13],linux:[5,6,7,2],throughout:10,compositemodul:[12,10],static_cast:10,empti:[0,10],destructor:[4,5,8,10,12,13,14],ws_win:13,extra_defin:0,strategi:13,sipconvertfromnamedenum:[9,4],convert:[0,2,4,6,8,10,11,13,14],sipreskei:10,understand:[5,12,14],"__lshift__":12,nodefaultctor:8,look:[6,7,2,8,13],sipreleasemappedtyp:[9,4],"while":12,behavior:12,error:[0,9,10,8,4],"__hash__":12,anonym:4,sip_pylist:[12,8],sip_slot:12,readm:2,itself:[4,5,7,10,12,13],pytypeobject:[10,4],pyqt_sip_flag:13,sipmapstringtoclass:4,instancecod:[12,10,8],conflict:[13,6],"__repr__":12,sym:4,moment:4,temporari:[10,8,4],user:[7,4],"__add__":[12,10],wherev:10,chang:[0,4,5,9,10,13,8],travers:10,task:13,lib:[13,2],older:10,entri:[8,4],parenthes:[10,4],pickl:10,sipflag:10,"__neg__":12,sip_rxobj_di:12,explan:10,getapi:14,dump_klass:10,siperrornon:10,restructuredtext:10,optionalinclud:[12,10],subsequ:[5,13,10,4],sip_pytyp:[12,8],format:[0,2,4,9,10,8],"__gt__":12,bit:14,pystring_fromstringands:10,formal:12,semi:12,signal:[5,12,8,4],resolv:[0,4],collect:[4,14,10,12,13,8],"boolean":[12,8,4],maplen:4,sipgetmixinaddress:4,version_to_str:0,myobject:9,nbyte:4,sip_floatingpointerror:12,creation:5,sip_timeline_:10,back:[0,8],siptype_qwidget:10,all_raise_py_except:10,transferthi:[13,8],pep:4,larg:[5,13,10],recognis:10,pystring_asstringands:10,run:[2,3,5,10,11,13],siptransferto:[13,14,4],reach:13,step:[2,4],impos:10,sipconverttomappedtyp:[9,4],idx:[14,4],autopynam:[10,8],block:[5,6,14,10,13,8],primarili:8,within:[8,10,14,4],ellipsi:8,hex_:8,ensur:[0,4,5,10,13,8],settracemask:14,question:13,"long":[12,6,8,4],custom:0,handler:[13,10,8,4],includ:[0,2,4,5,6,8,10,11,12,13,14],suit:0,forward:8,properli:[5,12,13,4],sipmoduledict:10,siptype_qkeyev:10,link:[0,13,7,10,8],translat:10,keyword_argu:[10,6,8],line:[0,7,8],sdk:[0,2],getwrapp:[10,8],concaten:10,utf:[10,8,4],consist:12,bigetcharbuffercod:[12,10],py_buildvalu:[10,4],similar:[5,13,8,4],install_fil:0,constant:6,newthread:8,dd_list:8,sip_unicodeencodeerror:12,parser:[12,13,8],doesn:[0,12,10,13,4],repres:[0,4,14,12,13,8],"char":[12,13,10,8,4],sipdir:2,call_super_init:10,sipmodul:10,invalid:[0,4],keywordarg:[10,8],bracket:[10,4],librari:[0,2,4,5,6,7,10,12,13,14],clean:0,eval:4,access_func:4,unaffect:4,far:9,hello:[12,13],sip_referenceerror:12,install_dir:0,code:[0,8],sipconvertfromenum:4,results:8,qtguimodulemakefil:13,overlap:8,the_word:13,privat:[5,1,2,12,8],sens:12,generate_target_clean:0,sip_valueerror:12,sip_no_convertor:[10,4],typeheadercod:[12,13,10],sipconnectrx:9,implicitli:[9,14,8],relev:5,tri:[10,8],complic:10,sipbuildresult:[9,4],"try":[10,6,14,13],refer:[0,10,8,11,4],pyerr_except:10,sub_cfg:[0,13],sipdistutil:[5,3],impli:[0,10,8],smaller:[13,14],cfg:[13,3],contructor:10,download:1,append:[0,10,2,13],compat:[0,2,4,10,13,8],index:[14,4],defaultsupertyp:[12,13,10],access:[0,4,5,6,10,12,13],sipexception_:4,get_count:10,consolid:[5,10],parse_build_macro:0,len:4,bodi:10,ispycr:14,becom:[11,4],sinc:[10,6,8,4],great:5,convers:[10,8,4],broken:4,pycobject_asvoidptr:11,typic:[0,13,9,10,4],chanc:13,siptype_typ:10,sip_not_non:[10,4],app:2,api:[0,7,8],encapsul:[0,5],sipexception_klass_except:4,from:[0,2,3,4,5,6,7,9,10,11,12,13,8],zip:2,doubl:[12,8,4],qobject:[12,13,9,10],implic:13,few:12,virtualerrorhandl:[9,10,8,4],pyimport_importmodul:11,sip_unblock_thread:[10,4],sort:[13,6,4],rich:5,greatli:10,augment:0,bigetwritebuffercod:[12,10],obvious:13,thin:[12,4],assum:[0,2,4,9,13,8],fprintf:10,control:[13,10,4],sipgetwrapp:[9,4],tar:2,process:[5,10,3],lock:[1,4,5,6,9,10,8],tag:[0,13,6],proprietari:7,msvc:0,delai:8,gcc:2,sip:[0,7,8,4],sit:0,pyqt:[0,10],enableautoconvers:[10,14],"__pos__":12,instead:[2,4,6,8,10,12,13,14],sip_use_pycapsul:[11,4],preinitialisationcod:[12,10],overridden:10,pymodule_getdict:11,sipproxyresolverfunc:4,alloc:[13,4],bind:[0,2,5,6,13,14],correspond:[0,2,4,5,8,10,11,12,13,14],releaseguard:4,element:[0,12,10,8,4],issu:[5,13,8],siperrorst:[10,4],allow:[0,2,4,5,7,8,9,10,12,13,14],siptypefrompytypeobject:4,typecod:[12,10],siptransferback:[13,14,4],comma:[12,13,8],py_conf_inc_dir:0,sipconvertfromnewinst:[9,4],destroi:[13,8,10,14,4],srcdir:0,therefor:[5,12,10,8,13],sipfre:[13,4],crash:[13,14],greater:[0,8,10,14,4],"__getitem__":[12,14,8],python:[0,1,2,3,4,5,6,7,9,10,11,8],auto:[6,14,4],generate_macros_and_rul:0,qmake:0,"__delitem__":[12,8],postinitialisationcod:[12,10],anyth:8,editor:6,modulecod:[12,10,8],subset:[12,14],macosx:2,meta:[5,1,10,8,4],"static":[0,2,4,5,7,10,12,13,8],sipklass:[12,4],our:[13,3],special:[12,9,3],out:[5,13,2,8,4],influenc:4,stub:[7,10],suitabl:5,rel:[0,10],merg:[13,10],vendorid:7,q_slot:12,standalon:10,qtmod:10,dictionari:[0,4,10,11,12,13],releas:[2,4,5,6,9,10,13,8],afterward:[10,6,8],indent:10,could:[0,12,10,13],opengl:0,pycapsule_import:11,keep:[13,10],sipconvertfromnewtyp:4,stride:4,length:[5,10,4],outsid:12,optional_list:0,softwar:[5,2],suffix:6,date:[13,2],overwrit:13,owner:[14,4],parse_build_fil:0,facil:[0,6],typestr:4,transferto:14,dd_ptr:8,unknown:14,licens:[1,10],perfectli:8,sipparseresult:[9,10,4],wrapper:[0,4,5,6,8,10,12,13,14],attach:10,termin:[13,10,8,4],"final":[10,2,13],sipclass_:4,shell:2,"__del__":14,sip_systemexit:12,exactli:10,cmodul:10,qevent:10,sip_gilstate_t:[10,4],bother:13,see:[0,2,3,4,5,6,9,10,11,12,13,8],structur:8,charact:[0,1,4,9,10,12,8],nocopi:8,slicelength:4,sipapidef:11,linker:[0,5,13],clearli:10,clib:0,sip_inc_dir:0,pyqt_sip_dir:13,need:[0,2,3,4,5,6,7,9,10,11,12,13,8],turn:10,tidi:10,verbatim:13,sip_typeerror:12,"0x04":4,"__or__":12,"0x01":4,"0x02":4,builtin:[0,8],"_qt":10,which:[0,2,3,4,5,6,7,8,9,10,12,13,14],singl:[0,5,10,12,13,14],regard:[13,10,8,4],unless:[10,8],clash:[10,8],sipissubclassinst:9,who:12,pyd:5,why:[13,10],siptype_:4,request:[10,4],snapshot:[0,14,4],determin:[13,8,10,14,4],siptyp:10,constrain:[9,8],someth:[13,9,2],fact:5,extra_lib:[0,13],a0wrapp:10,text:[0,13,10],bring:5,sip_unicodedecodeerror:12,dbu:10,anywai:8,setter:10,locat:[13,4],sip_platform_:10,sip_config_arg:0,should:[0,2,4,9,8,7,10,12,13,14],local:[10,3],hope:13,meant:[9,8],move:12,memcpi:10,increas:0,extract:[0,5,10,6,12],enabl:[0,4,6,8,10,13,14],sipconverttotyp:[10,4],approach:5,possibl:[5,12,10,14,8],integr:[5,8],contain:[0,4,5,6,8,7,10,11,12,13,14],pylong_asunsignedlong:4,attribut:[0,1,4,9,10,11,12],sipexportsymbol:[11,4],sipwrappertype_typ:4,pyobject_print:10,correctli:[12,13],pattern:[0,10],dll:13,numer:[0,8],written:[0,5,10,6],neither:13,kei:[0,13,10,8],"__ifloordiv__":12,job:10,strdefin:0,"__ilshift__":12,addit:[0,1,4,9,10,8],consolidatedmodul:[12,10,6],use_arch:0,equal:[13,8,10,14,4],"__ior__":12,instanc:[0,4,5,8,10,11,12,13,14],comment:7,hyphen:8,py_xdecref:10,respect:4,siplong_asunsignedlong:4,my_handl:10,compon:[10,1,6,2],immedi:[10,8],"__itruediv__":12,ob_typ:4,togeth:5,sipbuff:10,multi:10,bye:12,dstdir:0,"__iadd__":12,defin:[0,2,3,4,5,6,8,9,10,11,12,13,14],typeint:4,"__floordiv__":12,"__sub__":12,noargpars:[10,8],helper:[10,4],reacquir:[10,6,8],sip_version_str:[0,14,4],sipattrgetterfunc:4,sip_temporari:[10,8],unneed:[0,10],situ:4,member:[10,8,11],handl:[0,8,7,10,13,14],sip_environmenterror:12,difficult:13,sipaccessfunc:4,http:[5,2],sipmapinttoclass:4,sipwrapper_typ:4,dealloc:[10,4],distutil:0,sipisapien:4,firstli:13,connectitem:12,well:[13,8],"__div__":[12,9],exampl:[0,1,2,3,4,7,9,10,11,12,8],command:[0,7,8],choos:[5,10,8,4],undefin:10,usual:[0,10,8,3,4],unari:12,less:[13,10,8,4],obtain:[8,11,4],optional_str:0,"__lt__":12,prepend:10,tight:5,makefil:[0,6,7,2,13],sip_anyslot:12,add:[13,10],valid:[0,13,9,10,4],match:[5,12,10,8,13],sip_bin:[0,13],noraisespyexcept:8,piec:10,siptypedef:[10,4],know:[12,10],sip_owns_memori:4,recurs:10,insert:0,pyerr_occur:4,like:[2,4,9,8,7,10,13,14],success:4,pycapsul:[11,4],build_macro:0,necessari:[0,5,9,10,11,12,13],suppli:[13,8,4],destdir:2,"export":[0,10,8,11,4],sippyself:[10,4],win32:2,"__setattr__":12,an_object_refer:9,lead:10,"__contains__":12,leak:[13,10,8,4],avoid:[0,10,6,8,13],numdefin:0,"__getattr__":12,leav:13,hello_sip_dir:13,sipconvertfromconstvoidptrands:4,usag:12,although:2,offset:4,stage:7,about:[5,6,14],actual:[13,10,8,11,4],"__imul__":[12,10],macosx_deployment_target:2,sipconverttocpp:9,constructor:[0,4,6,8,10,12,13,14],discard:8,disabl:[0,2,4,6,10,14],own:[0,4,5,8,7,10,13,14],sipwrapper_check:[9,4],automat:[0,10,6,8,4],pyqtwrappertyp:10,"__abs__":12,leverag:3,transfer:[13,9,10,8,4],sip_notimplementederror:12,sipconvertfromvoidptr:4,sip_modul:11,unexpect:4,sip_systemerror:12,b_modul:12,neutral:0,sipfindtyp:[11,4],bug:[2,4],count:[13,10,4],made:[13,10,8,4],parentmakefil:0,whether:[10,14,4],wish:2,writeabl:[14,4],displai:[0,6,2,14],limit:[13,10],otherwis:[10,2,8,4],problem:[0,13,10,8],"int":[10,8,4],mask:14,dure:[0,5,10,6],sipbadcatcherresult:4,filenam:[0,10],posix_platform:10,implement:[0,4,5,6,8,9,10,12,13,14],probabl:13,sipexception_std_except:10,mutual:[13,10],sip_pyobject:[12,8],detail:[0,2,4,5,10,12,13,8],virtual:[4,5,8,9,10,12,13,14],other:[0,2,4,5,8,10,11,12,13,14],bool:[12,8,10,14,4],futur:14,rememb:10,unwrapinst:14,repeat:8,pyerr_setnon:10,exporteddoc:[10,6],singleton:8,rule:[0,10],klass:[12,10,4],"__index__":[12,14],sipclassnam:[9,4]},objtypes:{"0":"std:option","1":"std:directive","2":"std:function-annotation","3":"std:argument-annotation","4":"std:class-annotation","5":"std:variable-annotation","6":"std:sip-type","7":"std:exception-annotation","8":"std:typedef-annotation","9":"std:mapped-type-annotation","10":"std:enum-annotation","11":"c:function","12":"c:macro","13":"c:type","14":"c:member","15":"c:var","16":"py:module","17":"py:method","18":"py:function","19":"py:attribute","20":"py:class","21":"py:data"},objnames:{"0":["std","option","option"],"1":["std","directive","directive"],"2":["std","function-annotation","function-annotation"],"3":["std","argument-annotation","argument-annotation"],"4":["std","class-annotation","class-annotation"],"5":["std","variable-annotation","variable-annotation"],"6":["std","sip-type","sip-type"],"7":["std","exception-annotation","exception-annotation"],"8":["std","typedef-annotation","typedef-annotation"],"9":["std","mapped-type-annotation","mapped-type-annotation"],"10":["std","enum-annotation","enum-annotation"],"11":["c","function","C function"],"12":["c","macro","C macro"],"13":["c","type","C type"],"14":["c","member","C member"],"15":["c","var","C variable"],"16":["py","module","Python module"],"17":["py","method","Python method"],"18":["py","function","Python function"],"19":["py","attribute","Python attribute"],"20":["py","class","Python class"],"21":["py","data","Python data"]},filenames:["build_system","index","installation","distutils","c_api","introduction","command_line","builtin","annotations","incompatibilities","directives","embedding","specification_files","using","python_api"],titles:["The Build System","SIP Reference Guide","Installation","Building Your Extension with distutils","C API for Handwritten Code","Introduction","The SIP Command Line","Builtin Modules and Custom Interpreters","Annotations","Potential Incompatibilities with Earlier Versions","Directives","Using the C API when Embedding","SIP Specification Files","Using SIP","Python API for Applications"],objects:{"":{sipGetState:[4,11,1,"c.sipGetState"],"%API":[10,1,1,"-"],NoVirtualErrorHandler:[8,2,1,"-"],PyName:[8,7,1,"-"],sipTransferTo:[4,11,1,"c.sipTransferTo"],SIP_NOT_NONE:[4,12,1,"c.SIP_NOT_NONE"],"-I":[6,0,1,"cmdoption-sip-I"],PreHook:[8,2,1,"-"],SIP_VERSION:[4,12,1,"c.SIP_VERSION"],"-T":[6,0,1,"cmdoption-sip-T"],"%MethodCode":[10,1,1,"-"],"-V":[6,0,1,"cmdoption-sip-V"],"-P":[6,0,1,"cmdoption-sip-P"],"--bindir":[2,0,1,"cmdoption-configure.py--bindir"],"%AutoPyName":[10,1,1,"-"],sipConvertFromConstVoidPtrAndSize:[4,11,1,"c.sipConvertFromConstVoidPtrAndSize"],"-X":[6,0,1,"cmdoption-sip-X"],SingleShot:[8,3,1,"-"],sipSimpleWrapper:[4,13,1,"c.sipSimpleWrapper"],"-e":[2,0,1,"cmdoption-configure.py-e"],"-d":[6,0,1,"cmdoption-sip-d"],"-g":[6,0,1,"cmdoption-sip-g"],"-a":[6,0,1,"cmdoption-sip-a"],"-c":[6,0,1,"cmdoption-sip-c"],"-b":[2,0,1,"cmdoption-configure.py-b"],TransferBack:[8,2,1,"-"],sipConvertFromConstVoidPtr:[4,11,1,"c.sipConvertFromConstVoidPtr"],"-o":[6,0,1,"cmdoption-sip-o"],"-n":[2,0,1,"cmdoption-configure.py-n"],sipConvertFromEnum:[4,11,1,"c.sipConvertFromEnum"],"-h":[2,0,1,"cmdoption-configure.py-h"],"-k":[2,0,1,"cmdoption-configure.py-k"],"-j":[6,0,1,"cmdoption-sip-j"],"-u":[2,0,1,"cmdoption-configure.py-u"],"-t":[6,0,1,"cmdoption-sip-t"],"-w":[6,0,1,"cmdoption-sip-w"],"-v":[2,0,1,"cmdoption-configure.py-v"],"-p":[6,0,1,"cmdoption-sip-p"],"-s":[2,0,1,"cmdoption-configure.py-s"],"-r":[6,0,1,"cmdoption-sip-r"],"-x":[6,0,1,"cmdoption-sip-x"],"%TypeHeaderCode":[10,1,1,"-"],"-z":[6,0,1,"cmdoption-sip-z"],"%Exception":[10,1,1,"-"],"%BIGetReadBufferCode":[10,1,1,"-"],VirtualErrorHandler:[8,2,1,"-"],SIP_SLOT_CON:[12,6,1,"-"],"%DefaultDocstringFormat":[10,1,1,"-"],"%PostInitialisationCode":[10,1,1,"-"],sipReleaseType:[4,11,1,"c.sipReleaseType"],sipCanConvertToEnum:[4,11,1,"c.sipCanConvertToEnum"],"%ModuleCode":[10,1,1,"-"],sipSetDestroyOnExit:[4,11,1,"c.sipSetDestroyOnExit"],sipConvertToInstance:[4,11,1,"c.sipConvertToInstance"],SIP_RELEASE_GIL:[4,11,1,"c.SIP_RELEASE_GIL"],ExportDerived:[8,4,1,"-"],"--show-build-macros":[2,0,1,"cmdoption-configure.py--show-build-macros"],"%CModule":[10,1,1,"-"],"%Import":[10,1,1,"-"],SIP_SLOT_DIS:[12,6,1,"-"],Encoding:[8,5,1,"-"],SIP_QOBJECT:[12,6,1,"-"],"--sdk":[2,0,1,"cmdoption-configure.py--sdk"],"%ExportedDoc":[10,1,1,"-"],Numeric:[8,2,1,"-"],"%AccessCode":[10,1,1,"-"],SIP_ANYSLOT:[12,6,1,"-"],API:[8,4,1,"-"],sipMapIntToClass:[4,11,1,"c.sipMapIntToClass"],Supertype:[8,4,1,"-"],PyInt:[8,5,1,"-"],sipFindType:[4,11,1,"c.sipFindType"],"%BIReleaseBufferCode":[10,1,1,"-"],NoArgParser:[8,2,1,"-"],"%BIGetCharBufferCode":[10,1,1,"-"],"%Docstring":[10,1,1,"-"],sipBadCatcherResult:[4,11,1,"c.sipBadCatcherResult"],"__len__":[8,2,1,"-"],"%DefaultMetatype":[10,1,1,"-"],"%GCTraverseCode":[10,1,1,"-"],"--sip-module":[2,0,1,"cmdoption-configure.py--sip-module"],SIP_PYDICT:[12,6,1,"-"],sipTypeIsEnum:[4,11,1,"c.sipTypeIsEnum"],"%Timeline":[10,1,1,"-"],sipSimpleWrapper_Type:[4,15,1,"c.sipSimpleWrapper_Type"],sipConvertFromSliceObject:[4,11,1,"c.sipConvertFromSliceObject"],DelayDtor:[8,4,1,"-"],"%InstanceCode":[10,1,1,"-"],"%VirtualCatcherCode":[10,1,1,"-"],sipForceConvertToMappedType:[4,11,1,"c.sipForceConvertToMappedType"],sipTypeIsNamespace:[4,11,1,"c.sipTypeIsNamespace"],sipConvertToVoidPtr:[4,11,1,"c.sipConvertToVoidPtr"],"%License":[10,1,1,"-"],NoDefaultCtors:[8,4,1,"-"],"%Doc":[10,1,1,"-"],sipCanConvertToInstance:[4,11,1,"c.sipCanConvertToInstance"],GetWrapper:[8,3,1,"-"],External:[8,4,1,"-"],sipForceConvertToType:[4,11,1,"c.sipForceConvertToType"],sipRegisterProxyResolver:[4,11,1,"c.sipRegisterProxyResolver"],sipExportSymbol:[4,11,1,"c.sipExportSymbol"],sipConvertFromType:[4,11,1,"c.sipConvertFromType"],NewThread:[8,2,1,"-"],KeywordArgs:[8,2,1,"-"],NoCopy:[8,3,1,"-"],SIP_API_MAJOR_NR:[4,12,1,"c.SIP_API_MAJOR_NR"],"%UnitCode":[10,1,1,"-"],"%PickleCode":[10,1,1,"-"],sipBadLengthForSlice:[4,11,1,"c.sipBadLengthForSlice"],sipConvertToMappedType:[4,11,1,"c.sipConvertToMappedType"],sipTypeAsPyTypeObject:[4,11,1,"c.sipTypeAsPyTypeObject"],"%If":[10,1,1,"-"],sipLong_AsUnsignedLong:[4,11,1,"c.sipLong_AsUnsignedLong"],sipGetMixinAddress:[4,11,1,"c.sipGetMixinAddress"],sipIsAPIEnabled:[4,11,1,"c.sipIsAPIEnabled"],SIP_API_MINOR_NR:[4,12,1,"c.SIP_API_MINOR_NR"],"%VirtualErrorHandler":[10,1,1,"-"],"%DefaultEncoding":[10,1,1,"-"],SIP_PYLIST:[12,6,1,"-"],"%Extract":[10,1,1,"-"],"%CompositeModule":[10,1,1,"-"],SIP_RXOBJ_DIS:[12,6,1,"-"],sipConvertFromVoidPtrAndSize:[4,11,1,"c.sipConvertFromVoidPtrAndSize"],SIP_NO_CONVERTORS:[4,12,1,"c.SIP_NO_CONVERTORS"],sipFindClass:[4,11,1,"c.sipFindClass"],SIP_PYBUFFER:[12,6,1,"-"],NoScope:[8,10,1,"-"],SIP_PROTECTED_IS_PUBLIC:[4,12,1,"c.SIP_PROTECTED_IS_PUBLIC"],sipconfig:[0,16,0,"-"],sipEnableAutoconversion:[4,11,1,"c.sipEnableAutoconversion"],sipReleaseMappedType:[4,11,1,"c.sipReleaseMappedType"],"%TypeCode":[10,1,1,"-"],AllowNone:[8,3,1,"-"],SIP_READ_ONLY:[4,12,1,"c.SIP_READ_ONLY"],"%Module":[10,1,1,"-"],"--sipdir":[2,0,1,"cmdoption-configure.py--sipdir"],sip:[14,16,0,"-"],"%ConvertToTypeCode":[10,1,1,"-"],AutoGen:[8,2,1,"-"],SIP_PYOBJECT:[12,6,1,"-"],SIP_PYCALLABLE:[12,6,1,"-"],"%ExportedHeaderCode":[10,1,1,"-"],sipVoidPtr_Type:[4,15,1,"c.sipVoidPtr_Type"],sipFree:[4,11,1,"c.sipFree"],"%End":[10,1,1,"-"],sipRegisterAttributeGetter:[4,11,1,"c.sipRegisterAttributeGetter"],sipConvertToType:[4,11,1,"c.sipConvertToType"],"%BIGetWriteBufferCode":[10,1,1,"-"],"--universal":[2,0,1,"cmdoption-configure.py--universal"],sipForceConvertToInstance:[4,11,1,"c.sipForceConvertToInstance"],sipConvertFromNewType:[4,11,1,"c.sipConvertFromNewType"],sipTypeFromPyTypeObject:[4,11,1,"c.sipTypeFromPyTypeObject"],SIP_SIGNAL:[12,6,1,"-"],"--show-platforms":[2,0,1,"cmdoption-configure.py--show-platforms"],"%BIGetSegCountCode":[10,1,1,"-"],RaisesPyException:[8,2,1,"-"],KeepReference:[8,2,1,"-"],"%GetCode":[10,1,1,"-"],sipConvertFromSequenceIndex:[4,11,1,"c.sipConvertFromSequenceIndex"],SIP_VERSION_STR:[4,12,1,"c.SIP_VERSION_STR"],sipConvertToTypedArray:[4,11,1,"c.sipConvertToTypedArray"],Capsule:[8,8,1,"-"],sipTypeIsMapped:[4,11,1,"c.sipTypeIsMapped"],sipWrapperType:[4,13,1,"c.sipWrapperType"],SIP_PYTUPLE:[12,6,1,"-"],sipIntTypeClassMap:[4,13,1,"c.sipIntTypeClassMap"],NoRelease:[8,9,1,"-"],"--deployment-target":[2,0,1,"cmdoption-configure.py--deployment-target"],sipWrapper_Check:[4,11,1,"c.sipWrapper_Check"],HoldGIL:[8,2,1,"-"],sipClassName:[4,11,1,"c.sipClassName"],sipConvertFromInstance:[4,11,1,"c.sipConvertFromInstance"],sipWrapperType_Type:[4,15,1,"c.sipWrapperType_Type"],Default:[8,2,1,"-"],Deprecated:[8,2,1,"-"],sipTransferBack:[4,11,1,"c.sipTransferBack"],sipMalloc:[4,11,1,"c.sipMalloc"],Factory:[8,2,1,"-"],sipConvertFromMappedType:[4,11,1,"c.sipConvertFromMappedType"],sipWrapper_Type:[4,15,1,"c.sipWrapper_Type"],"%GCClearCode":[10,1,1,"-"],"%UnitPostIncludeCode":[10,1,1,"-"],"--arch":[2,0,1,"cmdoption-configure.py--arch"],"--platform":[2,0,1,"cmdoption-configure.py--platform"],"%Include":[10,1,1,"-"],"%DefaultSupertype":[10,1,1,"-"],"%Platforms":[10,1,1,"-"],SIP_SLOT:[12,6,1,"-"],"%ModuleHeaderCode":[10,1,1,"-"],sipCallMethod:[4,11,1,"c.sipCallMethod"],"%Copying":[10,1,1,"-"],PostHook:[8,2,1,"-"],sipGetPyObject:[4,11,1,"c.sipGetPyObject"],SIP_PYTYPE:[12,6,1,"-"],NoDerived:[8,2,1,"-"],NoTypeName:[8,8,1,"-"],"--incdir":[2,0,1,"cmdoption-configure.py--incdir"],SIP_UNBLOCK_THREADS:[4,12,1,"c.SIP_UNBLOCK_THREADS"],sipGetAddress:[4,11,1,"c.sipGetAddress"],"%RaiseCode":[10,1,1,"-"],Constrained:[8,3,1,"-"],sipReleaseInstance:[4,11,1,"c.sipReleaseInstance"],"--help":[2,0,1,"cmdoption-configure.py--help"],Out:[8,3,1,"-"],sipCanConvertToType:[4,11,1,"c.sipCanConvertToType"],"%FinalisationCode":[10,1,1,"-"],Transfer:[8,3,1,"-"],sipWrapper:[4,13,1,"c.sipWrapper"],SIP_SSIZE_T_FORMAT:[4,12,1,"c.SIP_SSIZE_T_FORMAT"],NoRaisesPyException:[8,2,1,"-"],SIP_PYSLICE:[12,6,1,"-"],sipBuildResult:[4,11,1,"c.sipBuildResult"],sipDelayedDtor:[8,13,1,"c.sipDelayedDtor"],sipTransferBreak:[4,11,1,"c.sipTransferBreak"],ReleaseGIL:[8,2,1,"-"],sipFindMappedType:[4,11,1,"c.sipFindMappedType"],Metatype:[8,4,1,"-"],sipTypeScope:[4,11,1,"c.sipTypeScope"],sipImportSymbol:[4,11,1,"c.sipImportSymbol"],SIP_OWNS_MEMORY:[4,12,1,"c.SIP_OWNS_MEMORY"],"%BIGetBufferCode":[10,1,1,"-"],Abstract:[8,4,1,"-"],"%OptionalInclude":[10,1,1,"-"],DocType:[8,9,1,"-"],sipDelayedDtors:[8,11,1,"c.sipDelayedDtors"],sipConvertToArray:[4,11,1,"c.sipConvertToArray"],"%Property":[10,1,1,"-"],"--debug":[2,0,1,"cmdoption-configure.py--debug"],TransferThis:[8,3,1,"-"],Mixin:[8,4,1,"-"],sipConvertFromNewInstance:[4,11,1,"c.sipConvertFromNewInstance"],sipResolveTypedef:[4,11,1,"c.sipResolveTypedef"],sipConvertFromNamedEnum:[4,11,1,"c.sipConvertFromNamedEnum"],SIP_BLOCK_THREADS:[4,12,1,"c.SIP_BLOCK_THREADS"],"%SetCode":[10,1,1,"-"],sipGetWrapper:[4,11,1,"c.sipGetWrapper"],DocValue:[8,3,1,"-"],sipBadCallableArg:[4,11,1,"c.sipBadCallableArg"],"--version":[2,0,1,"cmdoption-configure.py--version"],sipFindNamedEnum:[4,11,1,"c.sipFindNamedEnum"],ArraySize:[8,3,1,"-"],"%MappedType":[10,1,1,"-"],NoKeywordArgs:[8,2,1,"-"],Array:[8,3,1,"-"],sipCanConvertToMappedType:[4,11,1,"c.sipCanConvertToMappedType"],"%ConsolidatedModule":[10,1,1,"-"],"%ConvertFromTypeCode":[10,1,1,"-"],sipTypeIsClass:[4,11,1,"c.sipTypeIsClass"],Sequence:[8,2,1,"-"],sipStringTypeClassMap:[4,13,1,"c.sipStringTypeClassMap"],"%InitialisationCode":[10,1,1,"-"],sipParseResult:[4,11,1,"c.sipParseResult"],sipTypeName:[4,11,1,"c.sipTypeName"],sipConvertFromNewPyType:[4,11,1,"c.sipConvertFromNewPyType"],ResultSize:[8,3,1,"-"],sipRegisterPyType:[4,11,1,"c.sipRegisterPyType"],sipMapStringToClass:[4,11,1,"c.sipMapStringToClass"],"%PreInitialisationCode":[10,1,1,"-"],"--destdir":[2,0,1,"cmdoption-configure.py--destdir"],In:[8,3,1,"-"],SIP_RXOBJ_CON:[12,6,1,"-"],"%Feature":[10,1,1,"-"],"%ConvertToSubClassCode":[10,1,1,"-"],SIP_SSIZE_T:[4,12,1,"c.SIP_SSIZE_T"],"--static":[2,0,1,"cmdoption-configure.py--static"],SIP_USE_PYCAPSULE:[4,12,1,"c.SIP_USE_PYCAPSULE"],sipConvertFromVoidPtr:[4,11,1,"c.sipConvertFromVoidPtr"]},"sipStringTypeClassMap.pyType":{"":[4,14,1,"c.sipStringTypeClassMap.pyType."]},sip:{dump:[14,18,1,""],getapi:[14,18,1,""],SIP_VERSION:[14,21,1,""],setapi:[14,18,1,""],settracemask:[14,18,1,""],unwrapinstance:[14,18,1,""],transferto:[14,18,1,""],simplewrapper:[14,20,1,""],SIP_VERSION_STR:[14,21,1,""],wrapper:[14,20,1,""],setdestroyonexit:[14,18,1,""],isdeleted:[14,18,1,""],setdeleted:[14,18,1,""],wrappertype:[14,20,1,""],voidptr:[14,20,1,""],ispycreated:[14,18,1,""],transferback:[14,18,1,""],ispyowned:[14,18,1,""],cast:[14,18,1,""],enableautoconversion:[14,18,1,""],wrapinstance:[14,18,1,""],"delete":[14,18,1,""]},"sipconfig.Configuration":{py_lib_dir:[0,19,1,""],py_version:[0,19,1,""],default_mod_dir:[0,19,1,""],default_bin_dir:[0,19,1,""],platform:[0,19,1,""],universal:[0,19,1,""],sip_version:[0,19,1,""],sip_config_args:[0,19,1,""],default_sip_dir:[0,19,1,""],sip_mod_dir:[0,19,1,""],build_macros:[0,17,1,""],py_inc_dir:[0,19,1,""],sip_inc_dir:[0,19,1,""],py_conf_inc_dir:[0,19,1,""],deployment_target:[0,19,1,""],set_build_macros:[0,17,1,""],arch:[0,19,1,""],sip_version_str:[0,19,1,""],"__init__":[0,17,1,""],sip_bin:[0,19,1,""]},"sipconfig.ProgramMakefile":{generate_target_default:[0,17,1,""],build_command:[0,17,1,""],generate_macros_and_rules:[0,17,1,""],generate_target_clean:[0,17,1,""],generate_target_install:[0,17,1,""],finalise:[0,17,1,""],"__init__":[0,17,1,""]},"sip.voidptr":{"__int__":[14,17,1,""],getwriteable:[14,17,1,""],setwriteable:[14,17,1,""],"__getitem__":[14,17,1,""],ascobject:[14,17,1,""],ascapsule:[14,17,1,""],getsize:[14,17,1,""],"__setitem__":[14,17,1,""],"__len__":[14,17,1,""],"__hex__":[14,17,1,""],asstring:[14,17,1,""],setsize:[14,17,1,""],"__init__":[14,17,1,""]},"sipIntTypeClassMap.pyType":{"":[4,14,1,"c.sipIntTypeClassMap.pyType."]},sipconfig:{create_config_module:[0,18,1,""],ModuleMakefile:[0,20,1,""],Configuration:[0,20,1,""],create_wrapper:[0,18,1,""],version_to_sip_tag:[0,18,1,""],format:[0,18,1,""],parse_build_macros:[0,18,1,""],create_content:[0,18,1,""],ParentMakefile:[0,20,1,""],error:[0,18,1,""],Makefile:[0,20,1,""],inform:[0,18,1,""],read_version:[0,18,1,""],version_to_string:[0,18,1,""],ProgramMakefile:[0,20,1,""],SIPModuleMakefile:[0,20,1,""],PythonModuleMakefile:[0,20,1,""]},"sipconfig.ParentMakefile":{generate_target_clean:[0,17,1,""],generate_target_install:[0,17,1,""],generate_target_default:[0,17,1,""],generate_macros_and_rules:[0,17,1,""],"__init__":[0,17,1,""]},sipIntTypeClassMap:{typeInt:[4,14,1,"c.sipIntTypeClassMap.typeInt"]},"sipconfig.ModuleMakefile":{generate_target_default:[0,17,1,""],generate_macros_and_rules:[0,17,1,""],generate_target_clean:[0,17,1,""],module_as_lib:[0,17,1,""],generate_target_install:[0,17,1,""],finalise:[0,17,1,""],"__init__":[0,17,1,""]},"sipconfig.Makefile":{chkdir:[0,19,1,""],platform_lib:[0,17,1,""],install_file:[0,17,1,""],ready:[0,17,1,""],extra_libs:[0,19,1,""],"__init__":[0,17,1,""],generate_target_default:[0,17,1,""],console:[0,19,1,""],generator:[0,19,1,""],extra_include_dirs:[0,19,1,""],clean_build_file_objects:[0,17,1,""],mkdir:[0,19,1,""],extra_cflags:[0,19,1,""],rm:[0,19,1,""],extra_lib_dirs:[0,19,1,""],config:[0,19,1,""],finalise:[0,17,1,""],required_string:[0,17,1,""],extra_cxxflags:[0,19,1,""],extra_lflags:[0,19,1,""],parse_build_file:[0,17,1,""],generate_target_clean:[0,17,1,""],copy:[0,19,1,""],generate_target_install:[0,17,1,""],generate:[0,17,1,""],optional_string:[0,17,1,""],optional_list:[0,17,1,""],generate_macros_and_rules:[0,17,1,""],extra_defines:[0,19,1,""]},"sipconfig.SIPModuleMakefile":{finalise:[0,17,1,""],"__init__":[0,17,1,""]},"sipconfig.PythonModuleMakefile":{generate_target_install:[0,17,1,""],generate_macros_and_rules:[0,17,1,""],"__init__":[0,17,1,""]},sipDelayedDtor:{dd_ptr:[8,14,1,"c.sipDelayedDtor.dd_ptr"],dd_name:[8,14,1,"c.sipDelayedDtor.dd_name"],dd_isderived:[8,14,1,"c.sipDelayedDtor.dd_isderived"],dd_next:[8,14,1,"c.sipDelayedDtor.dd_next"]},sipStringTypeClassMap:{typeString:[4,14,1,"c.sipStringTypeClassMap.typeString"]},sipSimpleWrapper:{access_func:[4,14,1,"c.sipSimpleWrapper.access_func"],data:[4,14,1,"c.sipSimpleWrapper.data"],user:[4,14,1,"c.sipSimpleWrapper.user"]}},titleterms:{code:4,global:13,handwritten:4,syntax:[12,10],previous:9,divis:12,typedef:8,configur:2,except:[8,4],sip_build:9,applic:14,python:[13,14],convertfromtypecod:9,converttotypecod:9,introduct:5,name:4,specif:[12,9],list:10,mingw:2,attribut:13,remov:9,compil:2,direct:10,"__truediv__":9,meta:13,download:2,variabl:[12,8],borland:2,newli:9,definit:12,version:9,refer:1,earlier:9,deriv:4,gener:4,"enum":[9,8,4],privat:13,extens:3,lazi:13,complementari:9,interpret:[13,7],addit:12,comparison:9,convers:9,manag:13,licens:5,oper:9,modul:[13,7],number:12,automat:9,deprec:9,api:[13,14,11,4],instal:2,guid:1,your:3,support:[5,13],system:0,custom:7,compon:5,interfac:13,type:[12,13,8,4],more:13,"function":8,namespac:12,copi:13,line:6,"true":12,wide:13,prepar:5,annot:8,structur:4,charact:13,embed:11,featur:[5,9],classic:12,"int":9,lock:13,argument:[12,8],file:12,revis:10,incompat:[13,9],sip:[1,5,6,9,12,13],when:11,pyqt:9,member:9,builtin:7,complex:13,build:[0,13,2,3],simpl:13,map:8,buffer:13,object:[13,4],sipwrapp:9,user:9,ownership:13,distutil:3,"class":[8,4],exampl:13,command:6,potenti:9}})sip-4.15.5/doc/html/specification_files.html0000644000076500000240000014421312310606652021067 0ustar philstaff00000000000000 SIP Specification Files — SIP 4.15.5 Reference Guide

      SIP Specification Files

      A SIP specification consists of some C/C++ type and function declarations and some directives. The declarations may contain annotations which provide SIP with additional information that cannot be expressed in C/C++. SIP does not include a full C/C++ parser.

      It is important to understand that a SIP specification describes the Python API, i.e. the API available to the Python programmer when they import the generated module. It does not have to accurately represent the underlying C/C++ library. There is nothing wrong with omitting functions that make little sense in a Python context, or adding functions implemented with handwritten code that have no C/C++ equivalent. It is even possible (and sometimes necessary) to specify a different super-class hierarchy for a C++ class. All that matters is that the generated code compiles properly.

      In most cases the Python API matches the C/C++ API. In some cases handwritten code (see %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 Generated 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.

      specification ::= {module-statement}
      
      module-statement ::= [module-directive | statement]
      
      module-directive ::= [
              %API |
              %CompositeModule |
              %ConsolidatedModule |
              %Copying |
              %DefaultEncoding |
              %DefaultMetatype |
              %DefaultSupertype |
              %ExportedHeaderCode |
              %Extract |
              %Feature |
              %Import |
              %Include |
              %InitialisationCode |
              %License |
              %MappedType |
              %Module |
              %ModuleCode |
              %ModuleHeaderCode |
              %OptionalInclude |
              %Platforms |
              %PreInitialisationCode |
              %PostInitialisationCode |
              %Timeline |
              %UnitCode |
              mapped-type-template]
      
      statement :: [class-statement | function | variable]
      
      class-statement :: [
              %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 |
              %BIGetBufferCode |
              %BIGetReadBufferCode |
              %BIGetWriteBufferCode |
              %BIGetSegCountCode |
              %BIGetCharBufferCode |
              %BIReleaseBufferCode |
              %ConvertToSubClassCode |
              %ConvertToTypeCode |
              %Docstring |
              %GCClearCode |
              %GCTraverseCode |
              %InstanceCode |
              %PickleCode |
              %TypeCode |
              %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] ; [%Docstring]
              [%MethodCode]
      
      c++-constructor-signature ::= [( [argument-list] )]
      
      destructor ::= [virtual] ~ name () [exceptions] [= 0]
              [function-annotations] ; [%MethodCode]
              [%VirtualCatcherCode]
      
      method ::= [Q_SIGNAL] [Q_SLOT] type name (
              [argument-list] ) [const] [exceptions] [= 0]
              [function-annotations] [c++-signature] ;
              [%Docstring] [%MethodCode]
      
      c++-signature ::= [ type ( [argument-list] )]
      
      static-method ::= static function
      
      virtual-method ::= [Q_SIGNAL] [Q_SLOT] virtual type name
              ( [argument-list] ) [const] [exceptions] [= 0]
              [function-annotations] [c++-signature] ;
              [%MethodCode] [%VirtualCatcherCode]
      
      special-method ::= type special-method-name
              ( [argument-list] ) [function-annotations] ;
              [%MethodCode]
      
      special-method-name ::= [__abs__ | __add__ | __and__ |
              __bool__ | __call__ | __cmp__ | __contains__ |
              __delattr__ | __delitem__ | __div__ | __eq__ |
              __float__ | __floordiv__ | __ge__ | __getattr__ |
              __getattribute__ | __getitem__ | __gt__ |
              __hash__ | __iadd__ | __iand__ | __idiv__ |
              __ifloordiv__ | __ilshift__ | __imod__ | __imul__ |
              __index__ | __int__ | __invert__ | __ior__ |
              __irshift__ | __isub__ | __iter__ | __itruediv__ |
              __ixor__ | __le__ | __len__ | __long__ |
              __lshift__ | __lt__ | __mod__ | __mul__ |
              __ne__ | __neg__ | __next__ | __nonzero__ |
              __or__ | __pos__ | __repr__ | __rshift__ |
              __setattr__ | __setitem__ | __str__ | __sub__ |
              __truediv__ | __xor__]
      
      operator ::= operator-type
              ( [argument-list] ) [const] [exceptions]
              [function-annotations] ; [%MethodCode]
      
      virtual-operator ::= virtual operator-type
              ( [argument-list] ) [const] [exceptions] [= 0]
              [function-annotations] ; [%MethodCode]
              [%VirtualCatcherCode]
      
      operatator-type ::= [ operator-function | operator-cast ]
      
      operator-function ::= type operator operator-name
      
      operator-cast ::= operator type
      
      operator-name ::= [+ | - | * | / | % | & |
              | | ^ | << | >> | += | -= | *= |
              /= | %= | &= | |= | ^= | <<= | >>= |
              ~ | () | [] | < | <= | == | != |
              > | >>= | =]
      
      class-variable ::= [static] variable
      
      class-template :: = template < type-list > class
      
      mapped-type-template :: = template < type-list >
              %MappedType
      
      enum ::= enum [name] [enum-annotations] { {enum-line} };
      
      enum-line ::= [%If | name [enum-annotations] ,
      
      function ::= type name ( [argument-list] ) [exceptions]
              [function-annotations] ; [%Docstring]
              [%MethodCode]
      
      namespace ::= namespace name [{ {namespace-line} }] ;
      
      namespace-line ::= [%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] ;
              [%AccessCode] [%GetCode]
              [%SetCode]
      
      exception ::= %Exception exception-name [exception-base]
              { [%TypeHeaderCode] %RaiseCode };
      
      exception-name ::= scoped-name
      
      exception-base ::= ( [exception-name | python-exception] )
      
      python-exception ::= [SIP_Exception | SIP_StopIteration |
              SIP_StandardError | SIP_ArithmeticError |
              SIP_LookupError | SIP_AssertionError |
              SIP_AttributeError | SIP_EOFError |
              SIP_FloatingPointError | SIP_EnvironmentError |
              SIP_IOError | SIP_OSError | SIP_ImportError |
              SIP_IndexError | SIP_KeyError | SIP_KeyboardInterrupt |
              SIP_MemoryError | SIP_NameError | SIP_OverflowError |
              SIP_RuntimeError | SIP_NotImplementedError |
              SIP_SyntaxError | SIP_IndentationError | SIP_TabError |
              SIP_ReferenceError | SIP_SystemError | SIP_SystemExit |
              SIP_TypeError | SIP_UnboundLocalError |
              SIP_UnicodeError | SIP_UnicodeEncodeError |
              SIP_UnicodeDecodeError | SIP_UnicodeTranslateError |
              SIP_ValueError | SIP_ZeroDivisionError |
              SIP_WindowsError | SIP_VMSError]
      
      exceptions ::= throw ( [exception-list] )
      
      exception-list ::= scoped-name [, exception-list]
      
      argument-list ::= argument [, argument-list] [, ...]
      
      argument ::= [
              type [name] [argument-annotations] [default-value] |
              SIP_ANYSLOT [default-value] |
              SIP_QOBJECT |
              SIP_RXOBJ_CON |
              SIP_RXOBJ_DIS |
              SIP_SIGNAL [default-value] |
              SIP_SLOT [default-value] |
              SIP_SLOT_CON |
              SIP_SLOT_DIS |
              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 Argument Annotations
      
      class-annotations ::= see Class Annotations
      
      enum-annotations ::= see Enum Annotations
      
      function-annotations ::= see Function Annotations
      
      typedef-annotations ::= see Typedef Annotations
      
      variable-annotations ::= see Variable Annotations
      
      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 |
              SIP_PYBUFFER |
              SIP_PYCALLABLE |
              SIP_PYDICT |
              SIP_PYLIST |
              SIP_PYOBJECT |
              SIP_PYSLICE |
              SIP_PYTUPLE |
              SIP_PYTYPE]
      
      scoped-name ::= name [:: scoped-name]
      
      template ::= scoped-name < type-list >
      
      dotted-name ::= name [. dotted-name]
      
      name ::= _A-Za-z {_A-Za-z0-9}
      

      Here is a short list of differences between C++ and the subset supported by SIP that might trip you up.

      • SIP does not support the use of [] in types. Use pointers instead.
      • A global operator can only be defined if its first argument is a class or a named enum that has been wrapped in the same module.
      • Variables declared outside of a class are effectively read-only.
      • A class’s list of super-classes doesn’t not include any access specifier (e.g. public).

      Variable Numbers of Arguments

      SIP supports the use of ... as the last part of a function signature. Any remaining arguments are collected as a Python tuple.

      Additional SIP Types

      SIP supports a number of additional data types that can be used in Python signatures.

      SIP_ANYSLOT

      This is both a const char * and a PyObject * that is used as the type of the member instead of const char * in functions that implement the connection or disconnection of an explicitly generated signal to a slot. Handwritten code must be provided to interpret the conversion correctly.

      SIP_PYBUFFER

      This is a PyObject * that implements the Python buffer protocol.

      SIP_PYCALLABLE

      This is a PyObject * that is a Python callable object.

      SIP_PYDICT

      This is a PyObject * that is a Python dictionary object.

      SIP_PYLIST

      This is a PyObject * that is a Python list object.

      SIP_PYOBJECT

      This is a PyObject * of any Python type. The type PyObject * can also be used.

      SIP_PYSLICE

      This is a PyObject * that is a Python slice object.

      SIP_PYTUPLE

      This is a PyObject * that is a Python tuple object.

      SIP_PYTYPE

      This is a PyObject * that is a Python type object.

      SIP_QOBJECT

      This is a QObject * that is a C++ instance of a class derived from Qt’s QObject class.

      SIP_RXOBJ_CON

      This is a QObject * that is a C++ instance of a class derived from Qt’s QObject class. It is used as the type of the receiver instead of const QObject * in functions that implement a connection to a slot.

      SIP_RXOBJ_DIS

      This is a QObject * that is a C++ instance of a class derived from Qt’s QObject class. It is used as the type of the receiver instead of const QObject * in functions that implement a disconnection from a slot.

      SIP_SIGNAL

      This is a const char * that is used as the type of the signal instead of const char * in functions that implement the connection or disconnection of an explicitly generated signal to a slot.

      SIP_SLOT

      This is a const char * that is used as the type of the member instead of const char * in functions that implement the connection or disconnection of an explicitly generated signal to a slot.

      SIP_SLOT_CON

      This is a const char * that is used as the type of the member instead of const char * in functions that implement the connection of an internally generated signal to a slot. The type includes a comma separated list of types that is the C++ signature of of the signal.

      To take an example, QAccel::connectItem() connects an internally generated signal to a slot. The signal is emitted when the keyboard accelerator is activated and it has a single integer argument that is the ID of the accelerator. The C++ signature is:

      bool connectItem(int id, const QObject *receiver, const char *member);
      

      The corresponding SIP specification is:

      bool connectItem(int, SIP_RXOBJ_CON, SIP_SLOT_CON(int));
      
      SIP_SLOT_DIS

      This is a const char * that is used as the type of the member instead of const char * in functions that implement the disconnection of an internally generated signal to a slot. The type includes a comma separated list of types that is the C++ signature of of the signal.

      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 %Import directive so that it is at the end of the file.

      Table Of Contents

      Previous topic

      The SIP Command Line

      Next topic

      Directives

      sip-4.15.5/doc/html/using.html0000644000076500000240000015760612310606652016224 0ustar philstaff00000000000000 Using SIP — SIP 4.15.5 Reference Guide

      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.

      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 <word.h>
      %End
      
      public:
          Word(const char *w);
      
          char *reverse() const;
      };
      

      Obviously a SIP specification file looks very much like a C++ (or C) header file, but SIP does not include a full C++ parser. Let’s look at the differences between the two files.

      • The %Module directive has been added [1]. This is used to name the Python module that is being created, word in this example.
      • The %TypeHeaderCode directive has been added. The text between this and the following %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 [2].
      • 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 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 [3]:

      make
      make install
      

      That’s all there is to it.

      See Building Your Extension with distutils for an example of how to build this example using distutils.

      [1]All SIP directives start with a % as the first non-whitespace character of a line.
      [2]SIP includes many code directives like this. They differ in where the supplied code is placed by SIP in the generated code.
      [3]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 <word.h>
      %End
      
          const char *the_word;
      };
      
      struct Word *create_word(const char *w) /Factory/;
      char *reverse(struct Word *word);
      

      Again, let’s look at the differences between the two files.

      • The %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 %TypeHeaderCode directive has been added.
      • The Factory annotation has been added to the create_word() function. This tells SIP that a newly created structure is being returned and it is owned by Python.

      The configure.py build system script described in the previous example can be used for this example without change.

      A More Complex C++ Example

      In this last example we will wrap a fictional C++ library that contains a class that is derived from a Qt class. This will demonstrate how SIP allows a class hierarchy to be split across multiple Python extension modules, and will introduce SIP’s versioning system.

      The library contains a single C++ class called Hello which is derived from Qt’s QLabel class. It behaves just like QLabel except that the text in the label is hard coded to be Hello World. To make the example more interesting we’ll also say that the library only supports Qt v4.2 and later, and also includes a function called setDefault() that is not implemented in the Windows version of the library.

      The hello.h header file looks something like this:

      // Define the interface to the hello library.
      
      #include <qlabel.h>
      #include <qwidget.h>
      #include <qstring.h>
      
      class Hello : public QLabel {
          // This is needed by the Qt Meta-Object Compiler.
          Q_OBJECT
      
      public:
          Hello(QWidget *parent = 0);
      
      private:
          // Prevent instances from being copied.
          Hello(const Hello &);
          Hello &operator=(const Hello &);
      };
      
      #if !defined(Q_OS_WIN)
      void setDefault(const QString &def);
      #endif
      

      The corresponding SIP specification file would then look something like this:

      // Define the SIP wrapper to the hello library.
      
      %Module hello
      
      %Import QtGui/QtGuimod.sip
      
      %If (Qt_4_2_0 -)
      
      class Hello : public QLabel {
      
      %TypeHeaderCode
      #include <hello.h>
      %End
      
      public:
          Hello(QWidget *parent /TransferThis/ = 0);
      
      private:
          Hello(const Hello &);
      };
      
      %If (!WS_WIN)
      void setDefault(const QString &def);
      %End
      
      %End
      

      Again we look at the differences, but we’ll skip those that we’ve looked at in previous examples.

      • The %Import directive has been added to specify that we are extending the class hierarchy defined in the file QtGui/QtGuimod.sip. This file is part of PyQt. The build system will take care of finding the file’s exact location.
      • The %If directive has been added to specify that everything [4] up to the matching %End directive only applies to Qt v4.2 and later. Qt_4_2_0 is a tag defined in QtCoremod.sip [5] using the %Timeline 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 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 Ownership of Objects. 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 %If directive has been added to specify that everything up to the matching %End directive does not apply to Windows. WS_WIN is another tag defined by PyQt, this time using the %Platforms directive. Tags defined by the %Platforms directive are mutually exclusive, i.e. only one may be valid at a time [6].

      One question you might have at this point is why bother to define the private copy constructor when it can never be called from Python? The answer is to prevent the automatic generation of a public copy constructor.

      We now look at the configure.py script. This is a little different to the script in the previous examples for two related reasons.

      Firstly, PyQt includes a pure Python module called pyqtconfig that extends the SIP build system for modules, like our example, that build on top of PyQt. It deals with the details of which version of Qt is being used (i.e. it determines what the correct tags are) and where it is installed. This is called a module’s configuration module.

      Secondly, we generate a configuration module (called helloconfig) for our own hello module. There is no need to do this, but if there is a chance that somebody else might want to extend your C++ library then it would make life easier for them.

      Now we have two scripts. First the configure.py script:

      import os
      import sipconfig
      from PyQt4 import pyqtconfig
      
      # The name of the SIP build file generated by SIP and used by the build
      # system.
      build_file = "hello.sbf"
      
      # Get the PyQt configuration information.
      config = pyqtconfig.Configuration()
      
      # Get the extra SIP flags needed by the imported PyQt modules.  Note that
      # this normally only includes those flags (-x and -t) that relate to SIP's
      # versioning system.
      pyqt_sip_flags = config.pyqt_sip_flags
      
      # Run SIP to generate the code.  Note that we tell SIP where to find the qt
      # module's specification files using the -I flag.
      os.system(" ".join([config.sip_bin, "-c", ".", "-b", build_file, "-I", config.pyqt_sip_dir, pyqt_sip_flags, "hello.sip"]))
      
      # We are going to install the SIP specification file for this module and
      # its configuration module.
      installs = []
      
      installs.append(["hello.sip", os.path.join(config.default_sip_dir, "hello")])
      
      installs.append(["helloconfig.py", config.default_mod_dir])
      
      # Create the Makefile.  The QtGuiModuleMakefile class provided by the
      # pyqtconfig module takes care of all the extra preprocessor, compiler and
      # linker flags needed by the Qt library.
      makefile = pyqtconfig.QtGuiModuleMakefile(
          configuration=config,
          build_file=build_file,
          installs=installs
      )
      
      # Add the library we are wrapping.  The name doesn't include any platform
      # specific prefixes or extensions (e.g. the "lib" prefix on UNIX, or the
      # ".dll" extension on Windows).
      makefile.extra_libs = ["hello"]
      
      # Generate the Makefile itself.
      makefile.generate()
      
      # Now we create the configuration module.  This is done by merging a Python
      # dictionary (whose values are normally determined dynamically) with a
      # (static) template.
      content = {
          # Publish where the SIP specifications for this module will be
          # installed.
          "hello_sip_dir":    config.default_sip_dir,
      
          # Publish the set of SIP flags needed by this module.  As these are the
          # same flags needed by the qt module we could leave it out, but this
          # allows us to change the flags at a later date without breaking
          # scripts that import the configuration module.
          "hello_sip_flags":  pyqt_sip_flags
      }
      
      # This creates the helloconfig.py module from the helloconfig.py.in
      # template and the dictionary.
      sipconfig.create_config_module("helloconfig.py", "helloconfig.py.in", content)
      

      Next we have the helloconfig.py.in template script:

      from PyQt4 import pyqtconfig
      
      # These are installation specific values created when Hello was configured.
      # The following line will be replaced when this template is used to create
      # the final configuration module.
      # @SIP_CONFIGURATION@
      
      class Configuration(pyqtconfig.Configuration):
          """The class that represents Hello configuration values.
          """
          def __init__(self, sub_cfg=None):
              """Initialise an instance of the class.
      
              sub_cfg is the list of sub-class configurations.  It should be None
              when called normally.
              """
              # This is all standard code to be copied verbatim except for the
              # name of the module containing the super-class.
              if sub_cfg:
                  cfg = sub_cfg
              else:
                  cfg = []
      
              cfg.append(_pkg_config)
      
              pyqtconfig.Configuration.__init__(self, cfg)
      
      class HelloModuleMakefile(pyqtconfig.QtGuiModuleMakefile):
          """The Makefile class for modules that %Import hello.
          """
          def finalise(self):
              """Finalise the macros.
              """
              # Make sure our C++ library is linked.
              self.extra_libs.append("hello")
      
              # Let the super-class do what it needs to.
              pyqtconfig.QtGuiModuleMakefile.finalise(self)
      

      Again, we hope that the scripts are self documenting.

      [4]Some parts of a SIP specification aren’t subject to version control.
      [5]Actually in versions.sip. PyQt uses the %Include directive to split the SIP specification for Qt across a large number of separate .sip files.
      [6]Tags can also be defined by the %Feature directive. These tags are not mutually exclusive, i.e. any number may be valid at a time.

      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 sipTransferTo(), sipTransferBack() and sipTransferBreak().

      Types and Meta-types

      Every Python object (with the exception of the 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, sip.simplewrapper and sip.wrapper, and a meta-type, sip.wrappertype.

      sip.simplewrapper is the super-type of sip.wrapper. The super-type of sip.simplewrapper is object.

      sip.wrappertype is the meta-type of both sip.simplewrapper and sip.wrapper. The super-type of sip.wrappertype is type.

      sip.wrapper supports the concept of object ownership described in Ownership of Objects and, by default, is the super-type of all the types that SIP generates.

      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 Metatype and Supertype class annotations.

      SIP also allows the default meta-type and super-type to be changed for a module using the %DefaultMetatype and %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 sipRegisterPyType(). This is normally done in code specified using the %InitialisationCode directive.

      As an example, PyQt4 uses %DefaultMetatype to specify a new meta-type that handles the interaction with Qt’s own meta-type system. It also uses %DefaultSupertype to specify that the smaller sip.simplewrapper super-type is normally used. Finally it uses Supertype as an annotation of the QObject class to override the default and use sip.wrapper as the super-type so that the parent/child relationships of QObject instances are properly maintained.

      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 sipRegisterAttributeGetter()). This will be called just before a type’s dictionary is accessed for the first time.

      Support for Python’s Buffer Interface

      SIP supports Python’s buffer interface in that whenever C/C++ requires a char or char * type then any Python type that supports the buffer interface (including ordinary Python strings) can be used.

      If a buffer is made up of a number of segments then all but the first will be ignored.

      Support for Wide Characters

      SIP v4.6 introduced support for wide characters (i.e. the wchar_t type). Python’s C API includes support for converting between unicode objects and wide character strings and arrays. When converting from a unicode object to wide characters SIP creates the string or array on the heap (using memory allocated using 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 sipFree()) after than function or method returns.
      • When a wide string or array is returned from a virtual method then SIP does not free the memory until the next time the method is called.
      • When an assignment is made to a wide string or array instance variable then SIP does not first free the instance’s current string or array.

      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 ReleaseGIL annotation can be used to override this behaviour when required.

      If SIP is given the -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 HoldGIL annotation can be used to override this behaviour when required.

      Managing Incompatible APIs

      New in version 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 %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 %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 API class, mapped type or 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 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.

      Building a Private Copy of the sip Module

      New in version 4.12.

      The sip module is intended to be be used by all the SIP generated modules of a particular Python installation. For example PyQt3 and PyQt4 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 --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 --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.

      sip-4.15.5/LICENSE0000644000076500000240000000513512261240331013463 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) 2014 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.15.5/LICENSE-GPL20000644000076500000240000004336111712024255014175 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.15.5/LICENSE-GPL30000644000076500000240000010474111712024255014176 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.15.5/NEWS0000644000076500000240000006054612310606510013164 0ustar philstaff00000000000000v4.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.15.5/README0000644000076500000240000000223311712024255013337 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``, and the Mercurial Python bindings are installed. If you want to create the HTML documentation then Sphinx must also be installed. To prepare run the following:: python build.py prepare Note that ``build.py`` is a Python v2 script. Now you can follow the normal installation instructions. The ``build.py`` script has other useful commands, use the ``--help`` option to see the details. sip-4.15.5/sipdistutils.py0000644000076500000240000001363112163400134015570 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.15.5/sipgen/0000755000076500000240000000000012310606636013750 5ustar philstaff00000000000000sip-4.15.5/sipgen/export.c0000644000076500000240000006547412261240661015452 0ustar philstaff00000000000000/* * The XML and API file generator module for SIP. * * Copyright (c) 2014 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 void exportDefaultValue(argDef *ad, int in_str, FILE *fp); static const char *pyType(sipSpec *pt, argDef *ad, int sec, classDef **scope); /* * Generate the API file. */ void generateAPI(sipSpec *pt, moduleDef *mod, const char *apiFile) { overDef *od; classDef *cd; FILE *fp; /* Generate the file. */ if ((fp = fopen(apiFile, "w")) == NULL) fatal("Unable to create file \"%s\"\n", apiFile); apiEnums(pt, mod, NULL, fp); apiVars(pt, mod, NULL, fp); for (od = mod->overs; od != NULL; od = od->next) { if (od->common->module != mod) continue; if (od->common->slot != no_slot) continue; if (apiOverload(pt, mod, NULL, od, FALSE, fp)) apiOverload(pt, mod, NULL, od, TRUE, fp); } for (cd = pt->classes; cd != NULL; cd = cd->next) { ctorDef *ct; if (cd->iff->module != mod) continue; if (isExternal(cd)) continue; apiEnums(pt, mod, cd, fp); apiVars(pt, mod, cd, fp); for (ct = cd->ctors; ct != NULL; ct = ct->next) { if (isPrivateCtor(ct)) continue; if (apiCtor(pt, mod, cd, ct, FALSE, fp)) apiCtor(pt, mod, cd, ct, TRUE, fp); } for (od = cd->overs; od != NULL; od = od->next) { if (isPrivate(od)) continue; if (od->common->slot != no_slot) continue; if (apiOverload(pt, mod, cd, od, FALSE, fp)) apiOverload(pt, mod, cd, od, TRUE, fp); } } fclose(fp); } /* * Generate an API ctor. */ static int apiCtor(sipSpec *pt, moduleDef *mod, classDef *scope, ctorDef *ct, int sec, FILE *fp) { int need_sec = FALSE, need_comma, a; /* Do the callable type form. */ fprintf(fp, "%s.", mod->name); prScopedPythonName(fp, scope->ecd, scope->pyname->text); fprintf(fp, "?%d(", CLASS_ID); need_comma = FALSE; for (a = 0; a < ct->pysig.nrArgs; ++a) { argDef *ad = &ct->pysig.args[a]; need_comma = apiArgument(pt, ad, FALSE, need_comma, sec, TRUE, TRUE, FALSE, fp); if (ad->atype == rxcon_type || ad->atype == rxdis_type) need_sec = TRUE; } fprintf(fp, ")\n"); /* Do the call __init__ form. */ fprintf(fp, "%s.", mod->name); prScopedPythonName(fp, scope->ecd, scope->pyname->text); fprintf(fp, ".__init__?%d(self", CLASS_ID); for (a = 0; a < ct->pysig.nrArgs; ++a) apiArgument(pt, &ct->pysig.args[a], FALSE, TRUE, sec, TRUE, TRUE, FALSE, fp); fprintf(fp, ")\n"); return need_sec; } /* * Generate the APIs for all the enums in a scope. */ static void apiEnums(sipSpec *pt, moduleDef *mod, classDef *scope, FILE *fp) { enumDef *ed; for (ed = pt->enums; ed != NULL; ed = ed->next) { enumMemberDef *emd; if (ed->module != mod) continue; if (ed->ecd != scope) continue; if (ed->pyname != NULL) { fprintf(fp, "%s.", mod->name); prScopedPythonName(fp, ed->ecd, ed->pyname->text); fprintf(fp, "?%d\n", ENUM_ID); } for (emd = ed->members; emd != NULL; emd = emd->next) { fprintf(fp, "%s.", mod->name); prScopedPythonName(fp, ed->ecd, emd->pyname->text); fprintf(fp, "?%d\n", ENUM_ID); } } } /* * Generate the APIs for all the variables in a scope. */ static void apiVars(sipSpec *pt, moduleDef *mod, classDef *scope, FILE *fp) { varDef *vd; for (vd = pt->vars; vd != NULL; vd = vd->next) { if (vd->module != mod) continue; if (vd->ecd != scope) continue; fprintf(fp, "%s.", mod->name); prScopedPythonName(fp, vd->ecd, vd->pyname->text); fprintf(fp, "?%d\n", VARIABLE_ID); } } /* * Generate a single API overload. */ static int apiOverload(sipSpec *pt, moduleDef *mod, classDef *scope, overDef *od, int sec, FILE *fp) { int need_sec; fprintf(fp, "%s.", mod->name); prScopedPythonName(fp, scope, od->common->pyname->text); fprintf(fp, "?%d", METHOD_ID); need_sec = prPythonSignature(pt, fp, &od->pysig, sec, TRUE, TRUE, FALSE, FALSE); fprintf(fp, "\n"); return need_sec; } /* * Generate the API for an argument. */ static int apiArgument(sipSpec *pt, argDef *ad, int out, int need_comma, int sec, int names, int defaults, int in_str, FILE *fp) { const char *tname; classDef *tscope; if (isArraySize(ad)) return need_comma; if (sec && (ad->atype == slotcon_type || ad->atype == slotdis_type)) return need_comma; if ((tname = pyType(pt, ad, sec, &tscope)) == NULL) return need_comma; if (need_comma) fprintf(fp, ", "); prScopedPythonName(fp, tscope, tname); /* * Handle the default value is required, but ignore it if it is an output * only argument. */ if (defaults && ad->defval && !out) { if (names && ad->name != NULL) fprintf(fp, " %s", ad->name->text); fprintf(fp, "="); prcode(fp, "%M"); exportDefaultValue(ad, in_str, fp); prcode(fp, "%M"); } return TRUE; } /* * Generate the XML export file. */ void generateXML(sipSpec *pt, moduleDef *mod, const char *xmlFile) { FILE *fp; classDef *cd; memberDef *md; if ((fp = fopen(xmlFile, "w")) == NULL) fatal("Unable to create file \"%s\"\n", xmlFile); fprintf(fp, "\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; } 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"); xmlEnums(pt, mod, cd, indent, fp); xmlVars(pt, mod, cd, indent, fp); for (ct = cd->ctors; ct != NULL; ct = ct->next) { if (isPrivateCtor(ct)) continue; if (xmlCtor(pt, cd, ct, FALSE, indent, fp)) xmlCtor(pt, cd, ct, TRUE, indent, fp); } for (md = cd->members; md != NULL; md = md->next) xmlFunction(pt, cd, md, cd->overs, indent, fp); xmlIndent(--indent, fp); fprintf(fp, "\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 (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=\"%M"); exportDefaultValue(ad, FALSE, fp); prcode(fp, "%M\""); } fprintf(fp, "/>\n"); } /* * Generate the XML for a type. */ static void xmlType(sipSpec *pt, argDef *ad, int sec, FILE *fp) { const char *type_type = NULL, *type_name; classDef *type_scope; fprintf(fp, " typename=\""); switch (ad->atype) { case class_type: type_type = (isOpaque(ad->u.cd) ? "opaque" : "class"); break; case enum_type: if (ad->u.ed->pyname != NULL) type_type = "enum"; break; case rxcon_type: case rxdis_type: if (!sec) type_type = "class"; break; case qobject_type: type_type = "class"; break; case slotcon_type: case slotdis_type: { int a; prcode(fp, "SLOT("); for (a = 0; a < ad->u.sa->nrArgs; ++a) { if (a > 0) prcode(fp, ", "); prcode(fp, "%M%B%M", &ad->u.sa->args[a]); } prcode(fp, ")"); } break; case mapped_type: type_type = "mappedtype"; break; } if ((type_name = pyType(pt, ad, sec, &type_scope)) != NULL) prScopedPythonName(fp, type_scope, type_name); fprintf(fp, "\""); if (type_type != NULL) fprintf(fp, " typetype=\"%s\"", type_type); if (ad->name != NULL) fprintf(fp, " name=\"%s\"", ad->name->text); } /* * Generate the indentation for a line. */ static void xmlIndent(int indent, FILE *fp) { while (indent-- > 0) fprintf(fp, " "); } /* * Export the default value of an argument. */ static void exportDefaultValue(argDef *ad, int in_str, FILE *fp) { /* Use any explicitly provided documentation. */ if (ad->docval != NULL) { prcode(fp, "%s", ad->docval); return; } /* Translate some special cases. */ if (ad->defval->next == NULL && ad->defval->vtype == numeric_value) { if (ad->nrderefs > 0 && ad->defval->u.vnum == 0) { prcode(fp, "None"); return; } if (ad->atype == bool_type || ad->atype == cbool_type) { prcode(fp, ad->defval->u.vnum ? "True" : "False"); return; } } generateExpression(ad->defval, in_str, fp); } /* * Get the Python representation of a type. */ static const char *pyType(sipSpec *pt, argDef *ad, int sec, classDef **scope) { const char *type_name; *scope = NULL; /* Use any explicit documented type. */ if (ad->doctype != NULL) return ad->doctype; /* For classes and mapped types we need the default implementation. */ if (ad->atype == class_type || ad->atype == mapped_type) { classDef *def_cd = NULL; mappedTypeDef *def_mtd = NULL; ifaceFileDef *iff; if (ad->atype == class_type) { iff = ad->u.cd->iff; if (iff->api_range == NULL) { /* There is only one implementation. */ def_cd = ad->u.cd; iff = NULL; } } else { iff = ad->u.mtd->iff; if (iff->api_range == NULL) { /* There is only one implementation. */ def_mtd = ad->u.mtd; iff = NULL; } } if (iff != NULL) { int def_api; /* Find the default implementation. */ def_api = findAPI(pt, iff->api_range->api_name->text)->from; for (iff = iff->first_alt; iff != NULL; iff = iff->next_alt) { apiVersionRangeDef *avd = iff->api_range; if (avd->from > 0 && avd->from > def_api) continue; if (avd->to > 0 && avd->to <= def_api) continue; /* It's within range. */ break; } /* Find the corresponding class or mapped type. */ for (def_cd = pt->classes; def_cd != NULL; def_cd = def_cd->next) if (def_cd->iff == iff) break; if (def_cd == NULL) for (def_mtd = pt->mappedtypes; def_mtd != NULL; def_mtd = def_mtd->next) if (def_mtd->iff == iff) break; } /* Now handle the correct implementation. */ if (def_cd != NULL) { *scope = def_cd->ecd; type_name = def_cd->pyname->text; } else { /* * Give a hint that /DocType/ should be used, or there is no * default implementation. */ type_name = "unknown-type"; if (def_mtd != NULL) { if (def_mtd->doctype != NULL) type_name = def_mtd->doctype; else if (def_mtd->pyname != NULL) type_name = def_mtd->pyname->text; } } return type_name; } switch (ad->atype) { case 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: case string_type: case sstring_type: case wstring_type: case ascii_string_type: case latin1_string_type: case utf8_string_type: type_name = "str"; break; case 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: 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 scoped Python name. */ void prScopedPythonName(FILE *fp, classDef *scope, const char *pyname) { if (scope != NULL) { prScopedPythonName(fp, scope->ecd, NULL); fprintf(fp, "%s.", scope->pyname->text); } if (pyname != NULL) fprintf(fp, "%s", pyname); } /* * Generate a Python signature. */ int prPythonSignature(sipSpec *pt, FILE *fp, signatureDef *sd, int sec, int names, int defaults, int in_str, int is_signal) { int need_sec = FALSE, need_comma = FALSE, is_res, nr_out, a; 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.15.5/sipgen/extracts.c0000644000076500000240000000546412261240664015762 0ustar philstaff00000000000000/* * The extracts generator for SIP. * * Copyright (c) 2014 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.15.5/sipgen/gencode.c0000644000076500000240000130474712302133530015525 0ustar philstaff00000000000000/* * The code generator module for SIP. * * Copyright (c) 2014 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 "sip.h" /* Return the base (ie. C/C++) name of a super-type or meta-type. */ #define smtypeName(sm) (strrchr((sm)->name->text, '.') + 1) /* Return TRUE if a wrapped variable can be set. */ #define canSetVariable(vd) ((vd)->type.nrderefs != 0 || !isConstArg(&(vd)->type)) /* Control what generateCalledArgs() actually generates. */ typedef enum { Declaration, Definition } funcArgType; /* An entry in the sorted array of methods. */ typedef struct { memberDef *md; /* The method. */ } sortedMethTab; static int currentLineNr; /* Current output line number. */ static const char *currentFileName; /* Current output file name. */ static int previousLineNr; /* Previous output line number. */ static const char *previousFileName; /* Previous output file name. */ static int exceptions; /* Set if exceptions are enabled. */ static int tracing; /* Set if tracing is enabled. */ static int generating_c; /* Set if generating C. */ static int release_gil; /* Set if always releasing the GIL. */ static const char *prcode_last = NULL; /* The last prcode format string. */ static int prcode_xml = FALSE; /* Set if prcode is XML aware. */ static int docstrings; /* Set if generating docstrings. */ static void generateDocumentation(sipSpec *pt, const char *docFile); static void generateBuildFile(sipSpec *pt, const char *buildFile, const char *srcSuffix, const char *consModule); static void generateBuildFileSources(sipSpec *pt, moduleDef *mod, const char *srcSuffix, FILE *fp); static void generateInternalAPIHeader(sipSpec *pt, moduleDef *mod, const char *codeDir, stringList *needed_qualifiers, stringList *xsl, int timestamp); static void generateCpp(sipSpec *pt, moduleDef *mod, const char *codeDir, const char *srcSuffix, int parts, stringList *needed_qualifiers, stringList *xsl, int timestamp); static void generateCompositeCpp(sipSpec *pt, const char *codeDir, int timestamp); static void generateConsolidatedCpp(sipSpec *pt, const char *codeDir, const char *srcSuffix, int timestamp); static void generateComponentCpp(sipSpec *pt, const char *codeDir, const char *consModule, int timestamp); 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 *, ifaceFileDef *, int, const char *, const char *, FILE *, int); static void generateMappedTypeCpp(mappedTypeDef *mtd, sipSpec *pt, FILE *fp); static void generateImportedMappedTypeAPI(mappedTypeDef *mtd, sipSpec *pt, moduleDef *mod, FILE *fp); static void generateMappedTypeAPI(sipSpec *pt, mappedTypeDef *mtd, FILE *fp); static void generateClassCpp(classDef *cd, sipSpec *pt, FILE *fp); static void generateImportedClassAPI(classDef *cd, sipSpec *pt, moduleDef *mod, FILE *fp); static void generateClassAPI(classDef *cd, sipSpec *pt, FILE *fp); static void generateClassFunctions(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp); static void generateShadowCode(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp); static void generateFunction(sipSpec *, memberDef *, overDef *, classDef *, classDef *, moduleDef *, FILE *); static void generateFunctionBody(overDef *, classDef *, mappedTypeDef *, classDef *, int deref, moduleDef *, FILE *); static void generateTypeDefinition(sipSpec *pt, classDef *cd, FILE *fp); static void generateTypeInit(classDef *, moduleDef *, FILE *); static void generateCppCodeBlock(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, int, FILE *); static void generateVariable(moduleDef *, ifaceFileDef *, argDef *, int, FILE *); static void generateNamedValueType(ifaceFileDef *, argDef *, char *, FILE *); static void generateBaseType(ifaceFileDef *, argDef *, int, FILE *); static void generateNamedBaseType(ifaceFileDef *, argDef *, const char *, int, FILE *); static void generateTupleBuilder(moduleDef *, signatureDef *, FILE *); static void generatePyQt3Emitters(moduleDef *mod, classDef *cd, FILE *fp); static void generatePyQt3Emitter(moduleDef *, classDef *, visibleList *, FILE *); static void generatePyQt5Emitters(moduleDef *mod, 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(sipSpec *pt, moduleDef *mod, classDef *cd, int virtNr, virtOverDef *vod, FILE *fp); static void generateVirtHandlerCall(sipSpec *pt, 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 *, FILE *); 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, int timestamp); static FILE *createFile(moduleDef *mod, const char *fname, const char *description, int timestamp); static void closeFile(FILE *); static void prScopedName(FILE *fp, scopedNameDef *snd, char *sep); static void prTypeName(FILE *fp, argDef *ad); static void prScopedClassName(FILE *fp, ifaceFileDef *scope, classDef *cd); static int 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, memberDef *md, int membernr, int optional_args, FILE *fp); static void generateTypesTable(sipSpec *pt, moduleDef *mod, FILE *fp); static int py2OnlySlot(slotType st); static int py2_5LaterSlot(slotType st); static int keepPyReference(argDef *ad); static int isDuplicateProtected(classDef *cd, overDef *target); static char getEncoding(argType atype); static void generateTypeDefName(ifaceFileDef *iff, FILE *fp); static void generateTypeDefLink(sipSpec *pt, ifaceFileDef *iff, FILE *fp); static int overloadHasDocstring(sipSpec *pt, overDef *od, memberDef *md); static int hasDocstring(sipSpec *pt, overDef *od, memberDef *md, ifaceFileDef *scope); static void generateDocstring(sipSpec *pt, overDef *overs, memberDef *md, const char *scope_name, classDef *scope_scope, FILE *fp); static int overloadHasClassDocstring(sipSpec *pt, ctorDef *ct); static int hasClassDocstring(sipSpec *pt, classDef *cd); static void generateClassDocstring(sipSpec *pt, classDef *cd, FILE *fp); static int isDefaultAPI(sipSpec *pt, apiVersionRangeDef *avd); static void generateExplicitDocstring(codeBlockList *cbl, FILE *fp); static int copyConstRefArg(argDef *ad); static void generatePreprocLine(int linenr, const char *fname, FILE *fp); static virtErrorHandler *getVirtErrorHandler(sipSpec *pt, overDef *od, classDef *cd, moduleDef *mod); static int hasOptionalArgs(overDef *od); /* * 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 timestamp) { 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, timestamp); 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, timestamp); generateConsolidatedCpp(pt, codeDir, srcSuffix, timestamp); } else if (consModule != NULL) generateComponentCpp(pt, codeDir, consModule, timestamp); else generateCpp(pt, pt->module, codeDir, srcSuffix, parts, needed_qualifiers, xsl, timestamp); } /* 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, FALSE); 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, FALSE); prcode(fp, "target = %s\nsources =", mname); if (isComposite(pt->module)) prcode(fp, " sip%scmodule.c", mname); else if (isConsolidated(pt->module)) { moduleDef *mod; for (mod = pt->modules; mod != NULL; mod = mod->next) if (mod->container == pt->module) generateBuildFileSources(pt, mod, srcSuffix, fp); prcode(fp, " sip%scmodule%s", mname, srcSuffix); } else if (consModule == NULL) generateBuildFileSources(pt, pt->module, srcSuffix, fp); else prcode(fp, " sip%scmodule.c", mname); if (isConsolidated(pt->module)) { moduleDef *mod; prcode(fp, "\nheaders ="); for (mod = pt->modules; mod != NULL; mod = mod->next) if (mod->container == pt->module) prcode(fp, " sipAPI%s.h", mod->name); } else if (!isComposite(pt->module) && consModule == NULL) prcode(fp, "\nheaders = sipAPI%s.h", mname); prcode(fp, "\n"); closeFile(fp); } /* * Generate the list of source files for a module. */ static void generateBuildFileSources(sipSpec *pt, moduleDef *mod, const char *srcSuffix, FILE *fp) { const char *mname = mod->name; if (mod->parts) { int p; for (p = 0; p < mod->parts; ++p) prcode(fp, " sip%spart%d%s", mname, p, srcSuffix); } else { ifaceFileDef *iff; prcode(fp, " sip%scmodule%s", mname, srcSuffix); for (iff = pt->ifacefiles; iff != NULL; iff = iff->next) { if (iff->module != mod) continue; if (iff->type == exception_iface) continue; if (iff->api_range != NULL) prcode(fp, " sip%s%F_%d%s", mname, iff->fqcname, iff->api_range->index, srcSuffix); else prcode(fp, " sip%s%F%s", mname, iff->fqcname, srcSuffix); } } } /* * Generate an expression in C++. */ void generateExpression(valueDef *vd, int in_str, FILE *fp) { while (vd != NULL) { if (vd->cast != NULL) prcode(fp, "(%S)", vd->cast); if (vd->vunop != '\0') prcode(fp,"%c",vd->vunop); switch (vd->vtype) { case qchar_value: prcode(fp,"'%c'",vd->u.vqchar); break; case string_value: { const char *quote = (in_str ? "\\\"" : "\""); prcode(fp,"%s%s%s", quote, vd->u.vstr, quote); } break; case numeric_value: prcode(fp,"%l",vd->u.vnum); break; case real_value: prcode(fp,"%g",vd->u.vreal); break; case scoped_value: if (prcode_xml) prScopedName(fp, vd->u.vscp, "."); else prcode(fp, "%S", vd->u.vscp); break; case fcall_value: generateSimpleFunctionCall(vd->u.fcd,fp); break; } if (vd->vbinop != '\0') prcode(fp,"%c",vd->vbinop); vd = vd->next; } } /* * Generate the C++ internal module API header file. */ static void generateInternalAPIHeader(sipSpec *pt, moduleDef *mod, const char *codeDir, stringList *needed_qualifiers, stringList *xsl, int timestamp) { 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.", timestamp); /* Include files. */ prcode(fp, "\n" "#ifndef _%sAPI_H\n" "#define _%sAPI_H\n" "\n" "\n" "#include \n" , mname , mname); 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" ); 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); /* 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 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 sipCommonDtor sipAPI_%s->api_common_dtor\n" "#define sipConvertFromSequenceIndex sipAPI_%s->api_convert_from_sequence_index\n" "#define sipConvertFromVoidPtr sipAPI_%s->api_convert_from_void_ptr\n" "#define sipConvertToVoidPtr sipAPI_%s->api_convert_to_void_ptr\n" "#define sipAddException sipAPI_%s->api_add_exception\n" "#define sipNoFunction sipAPI_%s->api_no_function\n" "#define sipNoMethod sipAPI_%s->api_no_method\n" "#define sipAbstractMethod sipAPI_%s->api_abstract_method\n" "#define sipBadClass sipAPI_%s->api_bad_class\n" "#define sipBadCatcherResult sipAPI_%s->api_bad_catcher_result\n" "#define sipBadCallableArg sipAPI_%s->api_bad_callable_arg\n" "#define sipBadOperatorArg sipAPI_%s->api_bad_operator_arg\n" "#define sipTrace sipAPI_%s->api_trace\n" "#define sipTransferBack sipAPI_%s->api_transfer_back\n" "#define sipTransferTo sipAPI_%s->api_transfer_to\n" "#define sipTransferBreak sipAPI_%s->api_transfer_break\n" "#define sipSimpleWrapper_Type sipAPI_%s->api_simplewrapper_type\n" "#define sipWrapper_Type sipAPI_%s->api_wrapper_type\n" "#define sipWrapperType_Type sipAPI_%s->api_wrappertype_type\n" "#define sipVoidPtr_Type sipAPI_%s->api_voidptr_type\n" "#define sipGetPyObject sipAPI_%s->api_get_pyobject\n" "#define 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 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 sipLong_AsUnsignedLong sipAPI_%s->api_long_as_unsigned_long\n" "#define sipExportSymbol sipAPI_%s->api_export_symbol\n" "#define sipImportSymbol sipAPI_%s->api_import_symbol\n" "#define sipFindType sipAPI_%s->api_find_type\n" "#define sipFindNamedEnum sipAPI_%s->api_find_named_enum\n" "#define sipBytes_AsChar sipAPI_%s->api_bytes_as_char\n" "#define sipBytes_AsString sipAPI_%s->api_bytes_as_string\n" "#define sipString_AsASCIIChar sipAPI_%s->api_string_as_ascii_char\n" "#define sipString_AsASCIIString sipAPI_%s->api_string_as_ascii_string\n" "#define sipString_AsLatin1Char sipAPI_%s->api_string_as_latin1_char\n" "#define sipString_AsLatin1String sipAPI_%s->api_string_as_latin1_string\n" "#define sipString_AsUTF8Char sipAPI_%s->api_string_as_utf8_char\n" "#define sipString_AsUTF8String sipAPI_%s->api_string_as_utf8_string\n" "#define sipUnicode_AsWChar sipAPI_%s->api_unicode_as_wchar\n" "#define sipUnicode_AsWString sipAPI_%s->api_unicode_as_wstring\n" "#define sipConvertFromConstVoidPtr sipAPI_%s->api_convert_from_const_void_ptr\n" "#define sipConvertFromVoidPtrAndSize sipAPI_%s->api_convert_from_void_ptr_and_size\n" "#define sipConvertFromConstVoidPtrAndSize sipAPI_%s->api_convert_from_const_void_ptr_and_size\n" "#define sipInvokeSlot sipAPI_%s->api_invoke_slot\n" "#define sipSaveSlot sipAPI_%s->api_save_slot\n" "#define sipClearAnySlotReference sipAPI_%s->api_clear_any_slot_reference\n" "#define sipVisitSlot sipAPI_%s->api_visit_slot\n" "#define sipWrappedTypeName(wt) ((wt)->type->td_cname)\n" "#define sipDeprecated sipAPI_%s->api_deprecated\n" "#define sipKeepReference sipAPI_%s->api_keep_reference\n" "#define 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 sipInitMixin sipAPI_%s->api_init_mixin\n" "#define sipExportModule sipAPI_%s->api_export_module\n" "#define sipInitModule sipAPI_%s->api_init_module\n" "\n" "/* These are deprecated. */\n" "#define sipMapStringToClass sipAPI_%s->api_map_string_to_class\n" "#define sipMapIntToClass sipAPI_%s->api_map_int_to_class\n" "#define sipFindClass sipAPI_%s->api_find_class\n" "#define sipFindMappedType sipAPI_%s->api_find_mapped_type\n" "#define sipConvertToArray sipAPI_%s->api_convert_to_array\n" "#define sipConvertToTypedArray sipAPI_%s->api_convert_to_typed_array\n" "#define sipWrapper_Check(w) PyObject_TypeCheck((w), sipAPI_%s->api_wrapper_type)\n" "#define sipGetWrapper(p, wt) sipGetPyObject((p), (wt)->type)\n" "#define sipReleaseInstance(p, wt, s) sipReleaseType((p), (wt)->type, (s))\n" "#define sipReleaseMappedType sipReleaseType\n" "#define sipCanConvertToInstance(o, wt, f) sipCanConvertToType((o), (wt)->type, (f))\n" "#define sipCanConvertToMappedType sipCanConvertToType\n" "#define sipConvertToInstance(o, wt, t, f, s, e) sipConvertToType((o), (wt)->type, (t), (f), (s), (e))\n" "#define sipConvertToMappedType sipConvertToType\n" "#define sipForceConvertToInstance(o, wt, t, f, s, e) sipForceConvertToType((o), (wt)->type, (t), (f), (s), (e))\n" "#define sipForceConvertToMappedType sipForceConvertToType\n" "#define sipConvertFromInstance(p, wt, t) sipConvertFromType((p), (wt)->type, (t))\n" "#define sipConvertFromMappedType sipConvertFromType\n" "#define sipConvertFromNamedEnum(v, pt) sipConvertFromEnum((v), ((sipEnumTypeObject *)(pt))->type)\n" "#define sipConvertFromNewInstance(p, wt, t) sipConvertFromNewType((p), (wt)->type, (t))\n" ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname ,mname); /* The name strings. */ prcode(fp, "\n" "/* The strings used by this module. */\n" "extern const char sipStrings_%s[];\n" , pt->module->name); /* The unscoped enum macros. */ generateEnumMacros(pt, mod, NULL, NULL, fp); generateModuleAPI(pt, mod, fp); prcode(fp, "\n" "/* The SIP API, this module's API and the APIs of any imported modules. */\n" "extern const sipAPIDef *sipAPI_%s;\n" "extern sipExportedModuleDef sipModuleAPI_%s;\n" , mname , mname, mname); for (mld = mod->allimports; mld != NULL; mld = mld->next) { generateImportedModuleAPI(pt, mod, mld->module, fp); prcode(fp, "extern const sipExportedModuleDef *sipModuleAPI_%s_%s;\n" , mname, mld->module->name); } if (pluginPyQt4(pt) || 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); } /* * 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 timestamp) { 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.", timestamp); prcode(fp, "\n" "#include \n" "\n" "\n" "static void sip_import_component_module(PyObject *d, const char *name)\n" "{\n" "#if PY_VERSION_HEX >= 0x02050000\n" " PyObject *mod = PyImport_ImportModule(name);\n" "#else\n" " PyObject *mod = PyImport_ImportModule((char *)name);\n" "#endif\n" "\n" " /*\n" " * Note that we don't complain if the module can't be imported. This\n" " * is a favour to Linux distro packagers who like to split PyQt into\n" " * different sub-packages.\n" " */\n" " if (mod)\n" " {\n" " PyDict_Merge(d, PyModule_GetDict(mod), 0);\n" " Py_DECREF(mod);\n" " }\n" "}\n" ); 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, int timestamp) { 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.", timestamp); 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, int timestamp) { char *cppfile; FILE *fp; cppfile = concat(codeDir, "/sip", pt->module->name, "cmodule.c", NULL); fp = createCompilationUnit(pt->module, cppfile, "Component module code.", timestamp); 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 timestamp) { char *cppfile; const char *mname = mod->name; int nrSccs = 0, files_in_part, max_per_part, this_part, mod_nr, enum_idx; int is_inst_class, is_inst_voidp, is_inst_char, is_inst_string; int is_inst_int, is_inst_long, is_inst_ulong, is_inst_longlong; int is_inst_ulonglong, is_inst_double, nr_enummembers, is_api_versions; int is_versioned_functions; int hasexternal = FALSE, slot_extenders = FALSE, ctor_extenders = FALSE; FILE *fp; moduleListDef *mld; classDef *cd; memberDef *md; enumDef *ed; ifaceFileDef *iff; virtHandlerDef *vhd; 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.", timestamp); 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 (mod->qobjclass >= 0) prcode(fp, "\n" "#define sipQtCreateUniversalSignal 0\n" "#define sipQtFindUniversalSignal 0\n" "#define sipQtEmitSignal 0\n" "#define sipQtConnectPySignal 0\n" "#define sipQtDisconnectPySignal 0\n" ); /* Define the names. */ if (mod->container == NULL) generateNameCache(pt, fp); /* Generate the C++ code blocks. */ generateCppCodeBlock(mod->cppcode, fp); /* Generate any virtual handlers. */ for (vhd = mod->virthandlers; vhd != NULL; vhd = vhd->next) if (!isDuplicateVH(vhd)) 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 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 (py2OnlySlot(md->slot) || py2_5LaterSlot(md->slot)) prcode(fp, "#endif\n" ); break; } } for (cd = mod->proxies; cd != NULL; cd = cd->next) for (md = cd->members; md != NULL; md = md->next) { if (py2OnlySlot(md->slot)) prcode(fp, "#if PY_MAJOR_VERSION < 3\n" ); else if (py2_5LaterSlot(md->slot)) prcode(fp, "#if PY_VERSION_HEX >= 0x02050000\n" ); prcode(fp, " {(void *)slot_%L_%s, %s, ", cd->iff, md->pyname->text, slotName(md->slot)); generateEncodedType(mod, cd, 0, fp); prcode(fp, "},\n" ); if (py2OnlySlot(md->slot) || py2_5LaterSlot(md->slot)) prcode(fp, "#endif\n" ); } prcode(fp, " {NULL, (sipPySlotType)0, {0, 0, 0}}\n" "};\n" ); } /* Generate the global access functions. */ generateAccessFunctions(pt, mod, NULL, fp); /* Generate any sub-class convertors. */ nrSccs = generateSubClassConvertors(pt, mod, fp); /* Generate the external classes table if needed. */ for (cd = pt->classes; cd != NULL; cd = cd->next) { if (!isExternal(cd)) continue; if (cd->iff->module != mod) continue; if (!hasexternal) { prcode(fp, "\n" "\n" "/* This defines each external type declared in this module, */\n" "static sipExternalTypeDef externalTypesTable[] = {\n" ); hasexternal = TRUE; } prcode(fp, " {%d, \"", cd->iff->ifacenr); prScopedName(fp, classFQCName(cd), "."); prcode(fp,"\"},\n" ); } if (hasexternal) prcode(fp, " {-1, NULL}\n" "};\n" ); /* Generate any enum slot tables. */ for (ed = pt->enums; ed != NULL; ed = ed->next) { memberDef *slot; if (ed->module != mod || ed->fqcname == NULL) continue; if (ed->slots == NULL) continue; for (slot = ed->slots; slot != NULL; slot = slot->next) generateSlot(mod, NULL, ed, slot, fp); prcode(fp, "\n" "static sipPySlotDef slots_%C[] = {\n" , ed->fqcname); for (slot = ed->slots; slot != NULL; slot = slot->next) { const char *stype; if ((stype = slotName(slot->slot)) != NULL) { if (py2OnlySlot(slot->slot)) prcode(fp, "#if PY_MAJOR_VERSION < 3\n" ); else if (py2_5LaterSlot(slot->slot)) prcode(fp, "#if PY_VERSION_HEX >= 0x02050000\n" ); prcode(fp, " {(void *)slot_%C_%s, %s},\n" , ed->fqcname, slot->pyname->text, stype); if (py2OnlySlot(slot->slot) || py2_5LaterSlot(slot->slot)) prcode(fp, "#endif\n" ); } } prcode(fp, " {0, (sipPySlotType)0}\n" "};\n" "\n" ); } /* Generate the enum type structures. */ enum_idx = 0; for (ed = pt->enums; ed != NULL; ed = ed->next) { int type_nr = -1; apiVersionRangeDef *avr = NULL; if (ed->module != mod || ed->fqcname == NULL) continue; if (ed->ecd != NULL) { if (isTemplateClass(ed->ecd)) continue; type_nr = ed->ecd->iff->first_alt->ifacenr; avr = ed->ecd->iff->api_range; } else if (ed->emtd != NULL) { type_nr = ed->emtd->iff->first_alt->ifacenr; avr = ed->emtd->iff->api_range; } if (enum_idx == 0) { prcode(fp, "static sipEnumTypeDef enumTypes[] = {\n" ); } ed->enum_idx = enum_idx++; prcode(fp, " {{%P, ", avr); if (ed->next_alt != NULL) prcode(fp, "&enumTypes[%d].etd_base", ed->next_alt->enum_idx); else prcode(fp, "0"); prcode(fp, ", 0, SIP_TYPE_ENUM, %n, {0}}, %n, %d, ", ed->cname, ed->pyname, type_nr); if (ed->slots != NULL) prcode(fp, "slots_%C", ed->fqcname); else prcode(fp, "NULL"); prcode(fp, "},\n" ); } if (enum_idx != 0) prcode(fp, "};\n" ); nr_enummembers = generateEnumMemberTable(pt, mod, NULL, NULL, fp); /* Generate the types table. */ if (mod->nrtypes > 0) generateTypesTable(pt, mod, fp); if (mod->nrtypedefs > 0) { typedefDef *td; prcode(fp, "\n" "\n" "/*\n" " * These define each typedef in this module.\n" " */\n" "static sipTypedefDef typedefsTable[] = {\n" ); for (td = pt->typedefs; td != NULL; td = td->next) { if (td->module != mod) continue; prcode(fp, " {\"%S\", \"", td->fqname); /* The default behaviour isn't right in a couple of cases. */ if (td->type.atype == longlong_type) prcode(fp, "long long"); else if (td->type.atype == ulonglong_type) prcode(fp, "unsigned long long"); else generateBaseType(NULL, &td->type, FALSE, fp); prcode(fp, "\"},\n" ); } prcode(fp, "};\n" ); } if (mod->nrvirthandlers > 0) { prcode(fp, "\n" "\n" "/*\n" " * This defines the virtual handlers that this module implements and can be\n" " * used by other modules.\n" " */\n" "static sipVirtHandlerFunc virtHandlersTable[] = {\n" ); for (vhd = mod->virthandlers; vhd != NULL; vhd = vhd->next) if (!isDuplicateVH(vhd)) prcode(fp, " (sipVirtHandlerFunc)sipVH_%s_%d,\n" , mname, vhd->virthandlernr); prcode(fp, "};\n" ); } if (mod->nrvirterrorhandlers > 0) { 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 sipVirtErrorHandlerFunc virtErrorHandlersTable[] = {\n" ); for (veh = pt->errorhandlers; veh != NULL; veh = veh->next) if (veh->mod == mod) prcode(fp, " sipVEH_%s_%s,\n" , mname, veh->name); prcode(fp, "};\n" ); } if (mod->allimports != NULL) { prcode(fp, "\n" "\n" "/* This defines the modules that this module needs to import. */\n" "static sipImportedModuleDef importsTable[] = {\n" ); for (mld = mod->allimports; mld != NULL; mld = mld->next) prcode(fp, " {\"%s\", %d, NULL},\n" , mld->module->fullname->text, mld->module->version); prcode(fp, " {NULL, -1, NULL}\n" "};\n" ); } if (nrSccs > 0) { prcode(fp, "\n" "\n" "/* This defines the class sub-convertors that this module defines. */\n" "static sipSubClassConvertorDef convertorsTable[] = {\n" ); for (cd = pt->classes; cd != NULL; cd = cd->next) { if (cd->iff->module != mod) continue; if (cd->convtosubcode == NULL) continue; prcode(fp, " {sipSubClass_%C, ",classFQCName(cd)); generateEncodedType(mod, cd->subbase, 0, fp); prcode(fp,", NULL},\n"); } prcode(fp, " {NULL, {0, 0, 0}, NULL}\n" "};\n" ); } /* Generate any license information. */ if (mod->license != NULL) { licenseDef *ld = mod->license; prcode(fp, "\n" "\n" "/* Define the module's license. */\n" "static sipLicenseDef module_license = {\n" ); prcode(fp, " \"%s\",\n" , ld->type); if (ld->licensee != NULL) prcode(fp, " \"%s\",\n" , ld->licensee); else prcode(fp, " NULL,\n" ); if (ld->timestamp != NULL) prcode(fp, " \"%s\",\n" , ld->timestamp); else prcode(fp, " NULL,\n" ); if (ld->sig != NULL) prcode(fp, " \"%s\"\n" , ld->sig); else prcode(fp, " NULL\n" ); prcode(fp, "};\n" ); } /* Generate each instance table. */ is_inst_class = generateClasses(pt, mod, NULL, fp); is_inst_voidp = generateVoidPointers(pt, mod, NULL, fp); is_inst_char = generateChars(pt, mod, NULL, fp); is_inst_string = generateStrings(pt, mod, NULL, fp); is_inst_int = generateInts(pt, mod, NULL, fp); is_inst_long = generateLongs(pt, mod, NULL, fp); is_inst_ulong = generateUnsignedLongs(pt, mod, NULL, fp); is_inst_longlong = generateLongLongs(pt, mod, NULL, fp); is_inst_ulonglong = generateUnsignedLongLongs(pt, mod, NULL, fp); is_inst_double = generateDoubles(pt, mod, NULL, fp); /* Generate any exceptions table. */ if (mod->nrexceptions > 0) prcode(fp, "\n" "\n" "static PyObject *exceptionsTable[%d];\n" , mod->nrexceptions); /* Generate any API versions table. */ if (mod->api_ranges != NULL || mod->api_versions != NULL) { apiVersionRangeDef *avr; is_api_versions = TRUE; prcode(fp, "\n" "\n" "/* This defines the API versions and ranges in use. */\n" "static int apiVersions[] = {"); for (avr = mod->api_ranges; avr != NULL; avr = avr->next) prcode(fp, "%n, %d, %d, ", avr->api_name, avr->from, avr->to); for (avr = mod->api_versions; avr != NULL; avr = avr->next) prcode(fp, "%n, %d, -1, ", avr->api_name, avr->from); prcode(fp, "-1};\n" ); } else is_api_versions = FALSE; /* Generate any versioned global functions. */ is_versioned_functions = FALSE; for (md = mod->othfuncs; md != NULL; md = md->next) if (md->slot == no_slot) { overDef *od; int has_docstring; if (notVersioned(md)) continue; if (!is_versioned_functions) { prcode(fp, "\n" "\n" "/* This defines the global functions where all overloads are versioned. */\n" "static sipVersionedFunctionDef versionedFunctions[] = {\n" ); is_versioned_functions = TRUE; } has_docstring = FALSE; if (md->docstring != NULL || (docstrings && hasDocstring(pt, mod->overs, md, NULL))) has_docstring = TRUE; /* * Every overload has an entry to capture all the version ranges. */ for (od = mod->overs; od != NULL; od = od->next) { if (od->common != md) continue; prcode(fp, " {%n, ", md->pyname); if (noArgParser(md) || 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 (mod->qobjclass >= 0) prcode(fp, "\n" "\n" "/* This defines the Qt support API. */\n" "\n" "static sipQtAPI qtAPI = {\n" " &typesTable[%d],\n" " sipQtCreateUniversalSignal,\n" " sipQtFindUniversalSignal,\n" " sipQtCreateUniversalSlot,\n" " sipQtDestroyUniversalSlot,\n" " sipQtFindSlot,\n" " sipQtConnect,\n" " sipQtDisconnect,\n" " sipQtSameSignalSlotName,\n" " sipQtFindSipslot,\n" " sipQtEmitSignal,\n" " sipQtConnectPySignal,\n" " sipQtDisconnectPySignal\n" "};\n" , mod->qobjclass); prcode(fp, "\n" "\n" "/* This defines this module. */\n" "sipExportedModuleDef sipModuleAPI_%s = {\n" " 0,\n" " SIP_API_MINOR_NR,\n" " %n,\n" " 0,\n" " %d,\n" " sipStrings_%s,\n" " %s,\n" " %s,\n" " %d,\n" " %s,\n" " %s,\n" " %d,\n" " %s,\n" " %d,\n" " %s,\n" " %s,\n" " %s,\n" " %s,\n" " {%s, %s, %s, %s, %s, %s, %s, %s, %s, %s},\n" " %s,\n" " %s,\n" " %s,\n" " %s,\n" " %s,\n" " NULL,\n" " %s,\n" " %s\n" "};\n" , mname , mod->fullname , mod->version , pt->module->name , mod->allimports != NULL ? "importsTable" : "NULL" , mod->qobjclass >= 0 ? "&qtAPI" : "NULL" , mod->nrtypes , mod->nrtypes > 0 ? "typesTable" : "NULL" , hasexternal ? "externalTypesTable" : "NULL" , nr_enummembers , nr_enummembers > 0 ? "enummembers" : "NULL" , mod->nrtypedefs , mod->nrtypedefs > 0 ? "typedefsTable" : "NULL" , mod->nrvirthandlers > 0 ? "virtHandlersTable" : "NULL" , mod->nrvirterrorhandlers > 0 ? "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" , mod->nrexceptions > 0 ? "exceptionsTable" : "NULL" , slot_extenders ? "slotExtenders" : "NULL" , ctor_extenders ? "initExtenders" : "NULL" , hasDelayedDtors(mod) ? "sipDelayedDtors" : "NULL" , is_api_versions ? "apiVersions" : "NULL" , is_versioned_functions ? "versionedFunctions" : "NULL"); 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); for (mld = mod->allimports; mld != NULL; mld = mld->next) prcode(fp, "const sipExportedModuleDef *sipModuleAPI_%s_%s;\n" , mname, mld->module->name); 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" ); for (md = mod->othfuncs; md != NULL; md = md->next) if (md->slot == no_slot) { int has_docstring; if (!notVersioned(md)) continue; has_docstring = FALSE; if (md->docstring != NULL || (docstrings && hasDocstring(pt, mod->overs, md, NULL))) has_docstring = TRUE; prcode(fp, " {SIP_MLNAME_CAST(%N), ", md->pyname); if (noArgParser(md) || 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, ", SIP_MLDOC_CAST(doc_%s)},\n" , md->pyname->text); else prcode(fp, ", NULL},\n" ); } prcode(fp, " {0, 0, 0, 0}\n" " };\n" ); generateModDefinition(mod, "sip_methods", fp); prcode(fp, "\n" " PyObject *sipModule, *sipModuleDict;\n" ); generateSipImportVariables(fp); /* Generate any pre-initialisation code. */ generateCppCodeBlock(mod->preinitcode, fp); prcode(fp, " /* Initialise the module and get it's dictionary. */\n" "#if PY_MAJOR_VERSION >= 3\n" " sipModule = PyModule_Create(&sip_module_def);\n" "#elif PY_VERSION_HEX >= 0x02050000\n" ); 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); mod_nr = 0; for (mld = mod->allimports; mld != NULL; mld = mld->next) { if (mod_nr == 0) prcode(fp, "\n" " /* Get the APIs of the modules that this one is dependent on. */\n" ); prcode(fp, " sipModuleAPI_%s_%s = sipModuleAPI_%s.em_imports[%d].im_module;\n" , mname, mld->module->name, mname, mod_nr); ++mod_nr; } generateTypesInline(pt, mod, fp); /* Create any exceptions. */ for (xd = pt->exceptions; xd != NULL; xd = xd->next) { if (xd->iff->module != mod) continue; if (xd->iff->type != exception_iface) continue; if (xd->exceptionnr < 0) continue; prcode(fp, "\n" " if ((exceptionsTable[%d] = PyErr_NewException(\n" "#if PY_MAJOR_VERSION >= 3\n" " \"%s.%s\",\n" "#else\n" " const_cast(\"%s.%s\"),\n" "#endif\n" " " , xd->exceptionnr , xd->iff->module->name, xd->pyname , xd->iff->module->name, xd->pyname); if (xd->bibase != NULL) prcode(fp, "PyExc_%s", xd->bibase); else if (xd->base->iff->module == mod) prcode(fp, "exceptionsTable[%d]", xd->base->exceptionnr); else prcode(fp, "sipException_%C", xd->base->iff->fqcname); prcode(fp, ",NULL)) == NULL || PyDict_SetItemString(sipModuleDict,\"%s\",exceptionsTable[%d]) < 0)\n" " {\n" " SIP_MODULE_DISCARD(sipModule);\n" " SIP_MODULE_RETURN(0);\n" " }\n" , xd->pyname, xd->exceptionnr); } /* Generate any post-initialisation code. */ generateCppCodeBlock(mod->postinitcode, fp); prcode(fp, "\n" " SIP_MODULE_RETURN(sipModule);\n" "}\n" ); /* Generate the interface source files. */ for (iff = pt->ifacefiles; iff != NULL; iff = iff->next) if (iff->module == mod && iff->type != exception_iface) { 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.", timestamp); prcode(fp, "\n" "#include \"sipAPI%s.h\"\n" , mname); need_postinc = TRUE; } else { need_postinc = FALSE; } generateIfaceCpp(pt, iff, need_postinc, codeDir, srcSuffix, (parts ? fp : NULL), timestamp); } 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, timestamp); } /* * Generate the types table for a module. */ static void generateTypesTable(sipSpec *pt, moduleDef *mod, FILE *fp) { int i; argDef *ad; const char *type_suffix; type_suffix = (pluginPyQt5(pt) || pluginPyQt4(pt) || pluginPyQt3(pt)) ? ".super" : ""; prcode(fp, "\n" "\n" "/*\n" " * This defines each type in this module.\n" " */\n" "static sipTypeDef *typesTable[] = {\n" ); for (ad = mod->types, i = 0; i < mod->nrtypes; ++i, ++ad) { switch (ad->atype) { case class_type: if (isExternal(ad->u.cd)) prcode(fp, " 0,\n" ); else prcode(fp, " &sipTypeDef_%s_%L%s.ctd_base,\n" , mod->name, ad->u.cd->iff, type_suffix); break; case mapped_type: prcode(fp, " &sipTypeDef_%s_%L.mtd_base,\n" , mod->name, ad->u.mtd->iff); break; case enum_type: prcode(fp, " &enumTypes[%d].etd_base,\n" , ad->u.ed->enum_idx); break; } } prcode(fp, "};\n" ); } /* * Generate the code to import the sip module and get its API. */ static void generateSipImport(moduleDef *mod, FILE *fp) { /* * 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->type : 0);\n" "}\n" ); else prcode(fp, "\n" " return sipType;\n" "}\n" ); ++nrSccs; } return nrSccs; } /* * Generate the structure representing an encoded type. */ static void generateEncodedType(moduleDef *mod, classDef *cd, int last, FILE *fp) { moduleDef *cmod = cd->iff->module; prcode(fp, "{%u, ", cd->iff->first_alt->ifacenr); if (cmod == mod) prcode(fp, "255"); else { int mod_nr = 0; moduleListDef *mld; for (mld = mod->allimports; mld != NULL; mld = mld->next) { if (mld->module == cmod) { prcode(fp, "%u", mod_nr); break; } ++mod_nr; } } prcode(fp, ", %u}", last); } /* * Generate an ordinary function. */ static void generateOrdinaryFunction(sipSpec *pt, moduleDef *mod, classDef *c_scope, mappedTypeDef *mt_scope, memberDef *md, FILE *fp) { overDef *od; int need_intro, has_auto_docstring; ifaceFileDef *scope; classDef *scope_scope; const char *scope_name, *kw_fw_decl, *kw_decl; if (mt_scope != NULL) { scope = mt_scope->iff; scope_name = mt_scope->pyname->text; scope_scope = NULL; od = mt_scope->overs; } else if (c_scope != NULL) { scope = c_scope->iff; scope_name = c_scope->pyname->text; scope_scope = NULL; od = c_scope->overs; } else { scope = NULL; scope_name = NULL; scope_scope = NULL; od = mod->overs; } prcode(fp, "\n" "\n" ); /* Generate the docstrings. */ has_auto_docstring = FALSE; if (md->docstring != NULL || (docstrings && hasDocstring(pt, od, md, scope))) { if (scope != NULL) prcode(fp, "PyDoc_STRVAR(doc_%L_%s, ", scope, md->pyname->text); else prcode(fp, "PyDoc_STRVAR(doc_%s, " , md->pyname->text); if (md->docstring != NULL) { generateExplicitDocstring(md->docstring, fp); } else { generateDocstring(pt, od, md, scope_name, scope_scope, fp); has_auto_docstring = TRUE; } prcode(fp, ");\n" "\n" ); } if (noArgParser(md) || 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; if (ed->module != mod) continue; if (cd != NULL) { if (ed->ecd != cd || (isProtectedEnum(ed) && !hasShadow(cd))) continue; } else if (mtd != NULL) { if (ed->emtd != mtd) continue; } else if (ed->ecd != NULL || ed->emtd != NULL || ed->fqcname == NULL) { continue; } for (emd = ed->members; emd != NULL; emd = emd->next) ++nr_members; } if (nr_members == 0) return 0; /* Create a table so they can be sorted. */ etab = sipCalloc(nr_members, sizeof (enumMemberDef *)); et = etab; for (ed = pt->enums; ed != NULL; ed = ed->next) { enumMemberDef *emd; if (ed->module != mod) continue; if (cd != NULL) { if (ed->ecd != cd) continue; } else if (mtd != NULL) { if (ed->emtd != mtd) continue; } else if (ed->ecd != NULL || ed->emtd != NULL || ed->fqcname == NULL) { continue; } for (emd = ed->members; emd != NULL; emd = emd->next) *et++ = emd; } qsort(etab, nr_members, sizeof (enumMemberDef *), compareEnumMembers); /* Now generate the table. */ if (cd == NULL && mtd == NULL) { prcode(fp, "\n" "/* These are the enum members of all global enums. */\n" "static sipEnumMemberDef enummembers[] = {\n" ); } else { ifaceFileDef *iff = (cd != NULL ? cd->iff : mtd->iff); prcode(fp, "\n" "static sipEnumMemberDef enummembers_%L[] = {\n" , iff); } for (i = 0; i < nr_members; ++i) { enumMemberDef *emd; emd = etab[i]; prcode(fp, " {%N, ", emd->pyname); if (!isNoScope(emd->ed)) { if (cd != NULL) { if (isProtectedEnum(emd->ed)) prcode(fp, "sip%C::", classFQCName(cd)); else if (isProtectedClass(cd)) prcode(fp, "%U::", cd); else prcode(fp, "%S::", classFQCName(cd)); } else if (mtd != NULL) { prcode(fp, "%S::", mtd->iff->fqcname); } } prcode(fp, "%s, %d},\n", emd->cname, emd->ed->first_alt->enumnr); } prcode(fp, "};\n" ); return nr_members; } /* * The qsort helper to compare two enumMemberDef structures based on the name * of the enum member. */ static int compareEnumMembers(const void *m1,const void *m2) { return strcmp((*(enumMemberDef **)m1)->pyname->text, (*(enumMemberDef **)m2)->pyname->text); } /* * Generate the access functions for the variables. */ static void generateAccessFunctions(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp) { varDef *vd; for (vd = pt->vars; vd != NULL; vd = vd->next) { if (vd->accessfunc == NULL) continue; if (vd->ecd != cd || vd->module != mod) continue; prcode(fp, "\n" "\n" "/* Access function. */\n" ); if (!generating_c) prcode(fp, "extern \"C\" {static void *access_%C();}\n" , vd->fqcname); prcode(fp, "static void *access_%C()\n" "{\n" , vd->fqcname); generateCppCodeBlock(vd->accessfunc, fp); prcode(fp, "}\n" ); } } /* * Generate the inline code to add a set of generated type instances to a * dictionary. */ static void generateTypesInline(sipSpec *pt, moduleDef *mod, FILE *fp) { int noIntro; varDef *vd; noIntro = TRUE; for (vd = pt->vars; vd != NULL; vd = vd->next) { if (vd->module != mod) continue; if (vd->type.atype != class_type && vd->type.atype != mapped_type && vd->type.atype != enum_type) continue; if (needsHandler(vd)) continue; /* Skip classes that don't need inline code. */ if (generating_c || vd->accessfunc != NULL || vd->type.nrderefs != 0) continue; if (noIntro) { prcode(fp, "\n" " /*\n" " * Define the class, mapped type and enum instances that have to be\n" " * added inline.\n" " */\n" ); noIntro = FALSE; } prcode(fp, " sipAddTypeInstance("); if (vd->ecd == NULL) prcode(fp, "sipModuleDict"); else prcode(fp, "(PyObject *)sipTypeAsPyTypeObject(sipType_%C)", classFQCName(vd->ecd)); prcode(fp, ",%N,", vd->pyname); if (isConstArg(&vd->type)) prcode(fp, "const_cast<%b *>(&%S)", &vd->type, vd->fqcname); else prcode(fp, "&%S", vd->fqcname); if (vd->type.atype == class_type) prcode(fp, ",sipType_%C);\n" , classFQCName(vd->type.u.cd)); else if (vd->type.atype == enum_type) prcode(fp, ",sipType_%C);\n" , vd->type.u.ed->fqcname); else prcode(fp, ",sipType_%T);\n" , &vd->type); } } /* * Generate the code to add a set of class instances to a dictionary. Return * TRUE if there was at least one. */ static int generateClasses(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp) { int noIntro; varDef *vd; noIntro = TRUE; for (vd = pt->vars; vd != NULL; vd = vd->next) { if (vd->ecd != cd || vd->module != mod) continue; if (vd->type.atype != class_type && (vd->type.atype != enum_type || vd->type.u.ed->fqcname == NULL)) continue; if (needsHandler(vd)) continue; /* * Skip ordinary C++ class instances which need to be done with inline * code rather than through a static table. This is because C++ does * not guarantee the order in which the table and the instance will be * created. So far this has only been seen to be a problem when * statically linking SIP generated modules on Windows. */ if (!generating_c && vd->accessfunc == NULL && vd->type.nrderefs == 0) continue; if (noIntro) { if (cd != NULL) prcode(fp, "\n" "\n" "/* Define the class and enum instances to be added to this type dictionary. */\n" "static sipTypeInstanceDef typeInstances_%C[] = {\n" , classFQCName(cd)); else prcode(fp, "\n" "\n" "/* Define the class and enum instances to be added to this module dictionary. */\n" "static sipTypeInstanceDef typeInstances[] = {\n" ); noIntro = FALSE; } prcode(fp, " {%N, ", vd->pyname); if (vd->type.atype == class_type) { scopedNameDef *vcname = classFQCName(vd->type.u.cd); if (vd->accessfunc != NULL) { prcode(fp, "(void *)access_%C, &sipType_%C, SIP_ACCFUNC|SIP_NOT_IN_MAP", vd->fqcname, vcname); } else if (vd->type.nrderefs != 0) { prcode(fp, "&%S, &sipType_%C, SIP_INDIRECT", vd->fqcname, vcname); } else if (isConstArg(&vd->type)) { prcode(fp, "const_cast<%b *>(&%S), &sipType_%C, 0", &vd->type, vd->fqcname, vcname); } else { prcode(fp, "&%S, &sipType_%C, 0", vd->fqcname, vcname); } } else { prcode(fp, "&%S, &sipType_%C, 0", vd->fqcname, vd->type.u.ed->fqcname); } prcode(fp, "},\n" ); } if (!noIntro) prcode(fp, " {0, 0, 0, 0}\n" "};\n" ); return !noIntro; } /* * Generate the code to add a set of void pointers to a dictionary. Return * TRUE if there was at least one. */ static int generateVoidPointers(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp) { int noIntro; varDef *vd; noIntro = TRUE; for (vd = pt->vars; vd != NULL; vd = vd->next) { if (vd->ecd != cd || vd->module != mod) continue; if (vd->type.atype != void_type && vd->type.atype != struct_type) continue; if (needsHandler(vd)) continue; if (noIntro) { if (cd != NULL) prcode(fp, "\n" "\n" "/* Define the void pointers to be added to this type dictionary. */\n" "static sipVoidPtrInstanceDef voidPtrInstances_%C[] = {\n" , classFQCName(cd)); else prcode(fp, "\n" "\n" "/* Define the void pointers to be added to this module dictionary. */\n" "static sipVoidPtrInstanceDef voidPtrInstances[] = {\n" ); noIntro = FALSE; } if (isConstArg(&vd->type)) prcode(fp, " {%N, const_cast<%b *>(%S)},\n" , vd->pyname, &vd->type, vd->fqcname); else prcode(fp, " {%N, %S},\n" , vd->pyname, vd->fqcname); } if (!noIntro) prcode(fp, " {0, 0}\n" "};\n" ); return !noIntro; } /* * Generate the code to add a set of characters to a dictionary. Return TRUE * if there was at least one. */ static int generateChars(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp) { int noIntro; varDef *vd; noIntro = TRUE; for (vd = pt->vars; vd != NULL; vd = vd->next) { argType vtype = vd->type.atype; if (vd->ecd != cd || vd->module != mod) continue; if (!((vtype == ascii_string_type || vtype == latin1_string_type || vtype == utf8_string_type || vtype == sstring_type || vtype == ustring_type || vtype == string_type || vtype == wstring_type) && vd->type.nrderefs == 0)) continue; if (needsHandler(vd)) continue; if (noIntro) { if (cd != NULL) prcode(fp, "\n" "\n" "/* Define the chars to be added to this type dictionary. */\n" "static sipCharInstanceDef charInstances_%C[] = {\n" , classFQCName(cd)); else prcode(fp, "\n" "\n" "/* Define the chars to be added to this module dictionary. */\n" "static sipCharInstanceDef charInstances[] = {\n" ); noIntro = FALSE; } prcode(fp, " {%N, %S, '%c'},\n" , vd->pyname, vd->fqcname, getEncoding(vtype)); } if (!noIntro) prcode(fp, " {0, 0, 0}\n" "};\n" ); return !noIntro; } /* * Generate the code to add a set of strings to a dictionary. Return TRUE if * there is at least one. */ static int generateStrings(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp) { int noIntro; varDef *vd; noIntro = TRUE; for (vd = pt->vars; vd != NULL; vd = vd->next) { argType vtype = vd->type.atype; if (vd->ecd != cd || vd->module != mod) continue; if (!((vtype == ascii_string_type || vtype == latin1_string_type || vtype == utf8_string_type || vtype == sstring_type || vtype == ustring_type || vtype == string_type || vtype == wstring_type) && vd->type.nrderefs != 0)) continue; if (needsHandler(vd)) continue; if (noIntro) { if (cd != NULL) prcode(fp, "\n" "\n" "/* Define the strings to be added to this type dictionary. */\n" "static sipStringInstanceDef stringInstances_%C[] = {\n" , classFQCName(cd)); else prcode(fp, "\n" "\n" "/* Define the strings to be added to this module dictionary. */\n" "static sipStringInstanceDef stringInstances[] = {\n" ); noIntro = FALSE; } prcode(fp, " {%N, %S, '%c'},\n" , vd->pyname, vd->fqcname, getEncoding(vtype)); } if (!noIntro) prcode(fp, " {0, 0, 0}\n" "};\n" ); return !noIntro; } /* * Generate the code to add a set of ints to a dictionary. Return TRUE if * there was at least one. */ static int generateInts(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp) { int noIntro; varDef *vd; enumDef *ed; noIntro = TRUE; for (vd = pt->vars; vd != NULL; vd = vd->next) { argType vtype = vd->type.atype; if (vd->ecd != cd || vd->module != mod) continue; if (!(vtype == enum_type || vtype == byte_type || vtype == sbyte_type || vtype == ubyte_type || vtype == ushort_type || vtype == short_type || vtype == uint_type || vtype == cint_type || vtype == int_type || vtype == bool_type || vtype == cbool_type)) continue; if (needsHandler(vd)) continue; /* Named enums are handled elsewhere. */ if (vtype == enum_type && vd->type.u.ed->fqcname != NULL) continue; if (noIntro) { ints_intro(cd, fp); noIntro = FALSE; } prcode(fp, " {%N, %S},\n" , vd->pyname, vd->fqcname); } /* Now do global anonymous enums. */ if (cd == NULL) for (ed = pt->enums; ed != NULL; ed = ed->next) { enumMemberDef *em; if (ed->ecd != cd || ed->module != mod) continue; if (ed->fqcname != NULL) continue; for (em = ed->members; em != NULL; em = em->next) { if (noIntro) { ints_intro(cd, fp); noIntro = FALSE; } prcode(fp, " {%N, %s},\n" , em->pyname, em->cname); } } if (!noIntro) prcode(fp, " {0, 0}\n" "};\n" ); return !noIntro; } /* * Generate the intro for a table of int instances. */ static void ints_intro(classDef *cd, FILE *fp) { if (cd != NULL) prcode(fp, "\n" "\n" "/* Define the ints to be added to this type dictionary. */\n" "static sipIntInstanceDef intInstances_%C[] = {\n" ,classFQCName(cd)); else prcode(fp, "\n" "\n" "/* Define the ints to be added to this module dictionary. */\n" "static sipIntInstanceDef intInstances[] = {\n" ); } /* * Generate the code to add a set of longs to a dictionary. Return TRUE if * there was at least one. */ static int generateLongs(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp) { return generateVariableType(pt, mod, cd, long_type, "long", "Long", "long", fp); } /* * Generate the code to add a set of unsigned longs to a dictionary. Return * TRUE if there was at least one. */ static int generateUnsignedLongs(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp) { return generateVariableType(pt, mod, cd, ulong_type, "unsigned long", "UnsignedLong", "unsignedLong", fp); } /* * Generate the code to add a set of long longs to a dictionary. Return TRUE * if there was at least one. */ static int generateLongLongs(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp) { return generateVariableType(pt, mod, cd, longlong_type, "long long", "LongLong", "longLong", fp); } /* * Generate the code to add a set of unsigned long longs to a dictionary. * Return TRUE if there was at least one. */ static int generateUnsignedLongLongs(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp) { return generateVariableType(pt, mod, cd, ulonglong_type, "unsigned long long", "UnsignedLongLong", "unsignedLongLong", fp); } /* * Generate the code to add a set of a particular type to a dictionary. Return * TRUE if there was at least one. */ static int generateVariableType(sipSpec *pt, moduleDef *mod, classDef *cd, argType atype, const char *eng, const char *s1, const char *s2, FILE *fp) { int noIntro; varDef *vd; noIntro = TRUE; for (vd = pt->vars; vd != NULL; vd = vd->next) { argType vtype = vd->type.atype; if (vd->ecd != cd || vd->module != mod) continue; if (vtype != atype) continue; if (needsHandler(vd)) continue; if (noIntro) { if (cd != NULL) prcode(fp, "\n" "\n" "/* Define the %ss to be added to this type dictionary. */\n" "static sip%sInstanceDef %sInstances_%C[] = {\n" , eng , s1, s2, classFQCName(cd)); else prcode(fp, "\n" "\n" "/* Define the %ss to be added to this module dictionary. */\n" "static sip%sInstanceDef %sInstances[] = {\n" , eng , s1, s2); noIntro = FALSE; } prcode(fp, " {%N, %S},\n" , vd->pyname, vd->fqcname); } if (!noIntro) prcode(fp, " {0, 0}\n" "};\n" ); return !noIntro; } /* * Generate the code to add a set of doubles to a dictionary. Return TRUE if * there was at least one. */ static int generateDoubles(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp) { int noIntro; varDef *vd; noIntro = TRUE; for (vd = pt->vars; vd != NULL; vd = vd->next) { argType vtype = vd->type.atype; if (vd->ecd != cd || vd->module != mod) continue; if (!(vtype == float_type || vtype == cfloat_type || vtype == double_type || vtype == cdouble_type)) continue; if (needsHandler(vd)) continue; if (noIntro) { if (cd != NULL) prcode(fp, "\n" "\n" "/* Define the doubles to be added to this type dictionary. */\n" "static sipDoubleInstanceDef doubleInstances_%C[] = {\n" , classFQCName(cd)); else prcode(fp, "\n" "\n" "/* Define the doubles to be added to this module dictionary. */\n" "static sipDoubleInstanceDef doubleInstances[] = {\n" ); noIntro = FALSE; } prcode(fp, " {%N, %S},\n" , vd->pyname, vd->fqcname); } if (!noIntro) prcode(fp, " {0, 0}\n" "};\n" ); return !noIntro; } /* * Generate the C/C++ code for an interface. */ static void generateIfaceCpp(sipSpec *pt, ifaceFileDef *iff, int need_postinc, const char *codeDir, const char *srcSuffix, FILE *master, int timestamp) { char *cppfile; const char *cmname = iff->module->name; classDef *cd; mappedTypeDef *mtd; FILE *fp; if (master == NULL) { cppfile = createIfaceFileName(codeDir,iff,srcSuffix); fp = createCompilationUnit(iff->module, cppfile, "Interface wrapper code.", timestamp); prcode(fp, "\n" "#include \"sipAPI%s.h\"\n" , cmname); need_postinc = TRUE; } else fp = master; 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 (cd->iff == iff && !isExternal(cd)) { classDef *pcd; generateClassCpp(cd, pt, fp); /* Generate any enclosed protected classes. */ for (pcd = pt->classes; pcd != NULL; pcd = pcd->next) if (isProtectedClass(pcd) && pcd->ecd == cd) generateClassCpp(pcd, pt, fp); } } for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next) if (mtd->iff == iff) generateMappedTypeCpp(mtd, pt, fp); if (master == NULL) { closeFile(fp); free(cppfile); } } /* * Return a filename for an interface C++ or header file on the heap. */ static char *createIfaceFileName(const char *codeDir, ifaceFileDef *iff, const char *suffix) { char *fn; scopedNameDef *snd; fn = concat(codeDir,"/sip",iff->module->name,NULL); for (snd = iff->fqcname; snd != NULL; snd = snd->next) append(&fn,snd->name); if (iff->api_range != NULL) { char buf[50]; sprintf(buf, "_%d", iff->api_range->index); append(&fn, buf); } append(&fn,suffix); return fn; } /* * Generate the C++ code for a mapped type version. */ static void generateMappedTypeCpp(mappedTypeDef *mtd, sipSpec *pt, FILE *fp) { int need_xfer, nr_methods, nr_enums; memberDef *md; generateCppCodeBlock(mtd->typecode, fp); if (!noRelease(mtd)) { /* Generate the assignment helper. */ prcode(fp, "\n" "\n" ); if (!generating_c) prcode(fp, "extern \"C\" {static void assign_%L(void *, SIP_SSIZE_T, const void *);}\n" , mtd->iff); prcode(fp, "static void assign_%L(void *sipDst, SIP_SSIZE_T sipDstIdx, const void *sipSrc)\n" "{\n" , mtd->iff); if (generating_c) prcode(fp, " ((%b *)sipDst)[sipDstIdx] = *((const %b *)sipSrc);\n" , &mtd->type, &mtd->type); else prcode(fp, " reinterpret_cast<%b *>(sipDst)[sipDstIdx] = *reinterpret_cast(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(pt, mtd->iff, fp); prcode(fp, ",\n" " 0,\n" " %sSIP_TYPE_MAPPED,\n" " %n,\n" " {0}\n" " },\n" " {\n" , (handlesNone(mtd) ? "SIP_TYPE_ALLOW_NONE|" : "") , mtd->cname); if (nr_enums == 0) prcode(fp, " -1,\n" ); else prcode(fp, " %n,\n" , mtd->pyname); prcode(fp, " {0, 0, 1},\n" ); if (nr_methods == 0) prcode(fp, " 0, 0,\n" ); else prcode(fp, " %d, methods_%L,\n" , nr_methods, mtd->iff); if (nr_enums == 0) prcode(fp, " 0, 0,\n" ); else prcode(fp, " %d, enummembers_%L,\n" , nr_enums, mtd->iff); prcode(fp, " 0, 0,\n" " {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}\n" " },\n" ); if (noRelease(mtd)) prcode(fp, " 0,\n" " 0,\n" " 0,\n" " 0,\n" ); else prcode(fp, " assign_%L,\n" " array_%L,\n" " copy_%L,\n" " release_%L,\n" , mtd->iff , mtd->iff , mtd->iff , mtd->iff); prcode(fp, " convertTo_%L,\n" " convertFrom_%L\n" , mtd->iff , mtd->iff); prcode(fp, "};\n" ); } /* * Generate the name of the type structure for a class or mapped type. */ static void generateTypeDefName(ifaceFileDef *iff, FILE *fp) { prcode(fp, "sipTypeDef_%s_%L", iff->module->name, iff); } /* * Generate the link to a type structure implementing an alternate API. */ static void generateTypeDefLink(sipSpec *pt, ifaceFileDef *iff, FILE *fp) { if (iff->next_alt != NULL) { prcode(fp, "&"); generateTypeDefName(iff->next_alt, fp); if (iff->next_alt->type == mappedtype_iface) prcode(fp, ".mtd_base"); else if (pluginPyQt3(pt) || pluginPyQt4(pt) || pluginPyQt5(pt)) prcode(fp, ".super.ctd_base"); else prcode(fp, ".ctd_base"); } else prcode(fp, "0"); } /* * Generate the C++ code for a class. */ static void generateClassCpp(classDef *cd, sipSpec *pt, FILE *fp) { moduleDef *mod = cd->iff->module; /* Generate any local class code. */ generateCppCodeBlock(cd->cppcode, fp); generateClassFunctions(pt, mod, cd, fp); generateAccessFunctions(pt, mod, cd, fp); if (cd->iff->type != namespace_iface) { generateConvertToDefinitions(NULL,cd,fp); /* 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, fp); } /* * Return a sorted array of relevant functions for a namespace. */ static sortedMethTab *createFunctionTable(memberDef *members, int *nrp) { int nr; sortedMethTab *mtab, *mt; memberDef *md; /* First we need to count the number of applicable functions. */ nr = 0; for (md = members; md != NULL; md = md->next) ++nr; if ((*nrp = nr) == 0) return NULL; /* Create the table of methods. */ mtab = sipCalloc(nr, sizeof (sortedMethTab)); /* Initialise the table. */ mt = mtab; for (md = members; md != NULL; md = md->next) { mt->md = md; ++mt; } /* Finally, sort the table. */ qsort(mtab,nr,sizeof (sortedMethTab),compareMethTab); return mtab; } /* * Return a sorted array of relevant methods (either lazy or non-lazy) for a * class. */ static sortedMethTab *createMethodTable(classDef *cd, int *nrp) { int nr; visibleList *vl; sortedMethTab *mtab, *mt; /* * First we need to count the number of applicable methods. Only provide * an entry point if there is at least one overload that is defined in this * class and is a non-abstract function or slot. We allow private (even * though we don't actually generate code) because we need to intercept the * name before it reaches a more public version further up the class * hierarchy. We add the ctor and any variable handlers as special * entries. */ nr = 0; for (vl = cd->visible; vl != NULL; vl = vl->next) { overDef *od; if (vl->m->slot != no_slot) continue; for (od = vl->cd->overs; od != NULL; od = od->next) { /* * Skip protected methods if we don't have the means to handle * them. */ if (isProtected(od) && !hasShadow(cd)) continue; if (skipOverload(od,vl->m,cd,vl->cd,TRUE)) continue; ++nr; break; } } if ((*nrp = nr) == 0) return NULL; /* Create the table of methods. */ mtab = sipCalloc(nr, sizeof (sortedMethTab)); /* Initialise the table. */ mt = mtab; for (vl = cd->visible; vl != NULL; vl = vl->next) { int need_method; overDef *od; if (vl->m->slot != no_slot) continue; need_method = FALSE; for (od = vl->cd->overs; od != NULL; od = od->next) { /* * Skip protected methods if we don't have the means to handle * them. */ if (isProtected(od) && !hasShadow(cd)) continue; if (!skipOverload(od,vl->m,cd,vl->cd,TRUE)) need_method = TRUE; } if (need_method) { mt->md = vl->m; ++mt; } } /* Finally sort the table. */ qsort(mtab,nr,sizeof (sortedMethTab),compareMethTab); return mtab; } /* * The qsort helper to compare two sortedMethTab structures based on the Python * name of the method. */ static int compareMethTab(const void *m1,const void *m2) { return strcmp(((sortedMethTab *)m1)->md->pyname->text, ((sortedMethTab *)m2)->md->pyname->text); } /* * Generate the sorted table of static methods for a mapped type and return * the number of entries. */ static int generateMappedTypeMethodTable(sipSpec *pt, mappedTypeDef *mtd, FILE *fp) { int nr; sortedMethTab *mtab; mtab = createFunctionTable(mtd->members, &nr); if (mtab != NULL) { prMethodTable(pt, mtab, nr, mtd->iff, mtd->overs, fp); free(mtab); } return nr; } /* * Generate the sorted table of methods for a class and return the number of * entries. */ static int generateClassMethodTable(sipSpec *pt, classDef *cd, FILE *fp) { int nr; sortedMethTab *mtab; mtab = (cd->iff->type == namespace_iface) ? createFunctionTable(cd->members, &nr) : createMethodTable(cd, &nr); if (mtab != NULL) { prMethodTable(pt, mtab, nr, cd->iff, cd->overs, fp); free(mtab); } return nr; } /* * Generate a method table for a class or mapped type. */ static void prMethodTable(sipSpec *pt, sortedMethTab *mtable, int nr, ifaceFileDef *iff, overDef *overs, FILE *fp) { int i; prcode(fp, "\n" "\n" "static PyMethodDef methods_%L[] = {\n" , iff); for (i = 0; i < nr; ++i) { memberDef *md = mtable[i].md; const char *cast, *flags; int has_docstring; if (noArgParser(md) || useKeywordArgs(md)) { cast = "(PyCFunction)"; flags = "|METH_KEYWORDS"; } else { cast = ""; flags = ""; } /* Save the index in the table. */ md->membernr = i; has_docstring = FALSE; if (md->docstring != NULL || (docstrings && hasDocstring(pt, overs, md, iff))) has_docstring = TRUE; prcode(fp, " {SIP_MLNAME_CAST(%N), %smeth_%L_%s, METH_VARARGS%s, ", md->pyname, cast, iff, md->pyname->text, flags); if (has_docstring) prcode(fp, "SIP_MLDOC_CAST(doc_%L_%s)", iff, md->pyname->text); else prcode(fp, "NULL"); prcode(fp, "}%s\n" , ((i + 1) < nr) ? "," : ""); } prcode(fp, "};\n" ); } /* * Generate the "to type" convertor definitions. */ static void generateConvertToDefinitions(mappedTypeDef *mtd,classDef *cd, FILE *fp) { 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, keepRef; 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)); keepRef = (atype == class_type && vd->type.nrderefs == 0 && !isConstArg(&vd->type)); second_arg = (generating_c || keepRef) ? "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 || keepRef) { 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 (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(", (keepRef ? "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 (keepRef) { prcode(fp, " sipKeepReference(sipPy, -1, sipPySelf);\n" "\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) { prcode(fp, " return sipConvertFromEnum(sipVal, sipType_%C);\n" , 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; } prcode(fp, "}\n" ); } /* * Generate a variable setter. */ static void generateVariableSetter(ifaceFileDef *scope, varDef *vd, FILE *fp) { argType atype = vd->type.atype; const char *first_arg, *last_arg; char *deref; int might_be_temp, keep, need_py, need_cpp; keep = keepPyReference(&vd->type); if (generating_c || !isStaticVar(vd)) first_arg = "sipSelf"; else first_arg = ""; if (generating_c || (!isStaticVar(vd) && keep)) last_arg = "sipPySelf"; else last_arg = ""; 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, " "); 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 = "*"; prcode(fp, "\n" " if (sipIsErr)\n" " return -1;\n" "\n" ); } else { prcode(fp, "\n" " if (PyErr_Occurred() != NULL)\n" " return -1;\n" "\n" ); } if (atype == pyobject_type || atype == pytuple_type || atype == pylist_type || atype == pydict_type || atype == pycallable_type || atype == pyslice_type || atype == pytype_type || atype == pybuffer_type) { prcode(fp, " Py_XDECREF("); generateVarMember(vd, fp); prcode(fp, ");\n" " Py_INCREF(sipVal);\n" "\n" ); } prcode(fp, " "); generateVarMember(vd, fp); prcode(fp, " = %ssipVal;\n" , deref); /* Note that wchar_t * leaks here. */ if (might_be_temp) prcode(fp, "\n" " sipReleaseType(sipVal, sipType_%C, sipValState);\n" , classFQCName(vd->type.u.cd)); else if (vd->type.atype == mapped_type && vd->type.nrderefs == 0 && !noRelease(vd->type.u.mtd)) prcode(fp, "\n" " sipReleaseType(sipVal, sipType_%T, sipValState);\n" , &vd->type); /* Generate the code to keep the object alive while we use its data. */ if (keep) { if (isStaticVar(vd)) { prcode(fp, "\n" " static PyObject *sipKeep = 0;\n" "\n" " Py_XDECREF(sipKeep);\n" " sipKeep = sipPy;\n" " Py_INCREF(sipKeep);\n" ); } else { vd->type.key = scope->module->next_key--; prcode(fp, "\n" " sipKeepReference(sipPySelf, %d, sipPy);\n" , vd->type.key); } } prcode(fp, "\n" " return 0;\n" "}\n" ); } /* * Generate the member variable of a class. */ static void generateVarMember(varDef *vd, FILE *fp) { if (isStaticVar(vd)) prcode(fp, "%S::", classFQCName(vd->ecd)); else prcode(fp, "sipCpp->"); prcode(fp, "%s", scopedNameTail(vd->fqcname)); } /* * Generate the declaration of a variable that is initialised from a Python * object. Return TRUE if the value might be a temporary on the heap. */ static int generateObjToCppConversion(argDef *ad,FILE *fp) { int might_be_temp = FALSE; char *rhs = NULL; prcode(fp, " sipVal = "); switch (ad->atype) { case mapped_type: { const char *tail; if (generating_c) { prcode(fp, "(%b *)", ad); tail = ""; } else { prcode(fp, "reinterpret_cast<%b *>(", ad); tail = ")"; } /* Note that we don't support /Transfer/ but could do. */ prcode(fp, "sipForceConvertToType(sipPy,sipType_%T,NULL,%s,%s,&sipIsErr)", ad, (ad->nrderefs ? "0" : "SIP_NOT_NONE"), (ad->nrderefs ? "NULL" : "&sipValState")); prcode(fp, "%s;\n" , tail); } break; case class_type: { const char *tail; if (ad->nrderefs == 0 && ad->u.cd->convtocode != NULL) might_be_temp = TRUE; if (generating_c) { prcode(fp, "(%b *)", ad); tail = ""; } else { prcode(fp, "reinterpret_cast<%b *>(", ad); tail = ")"; } /* * Note that we don't support /Transfer/ but could do. We could * also support /Constrained/ (so long as we also supported it for * all types). */ prcode(fp, "sipForceConvertToType(sipPy,sipType_%C,NULL,%s,%s,&sipIsErr)", classFQCName(ad->u.cd), (ad->nrderefs ? "0" : "SIP_NOT_NONE"), (might_be_temp ? "&sipValState" : "NULL")); prcode(fp, "%s;\n" , tail); } break; case enum_type: prcode(fp, "(%E)SIPLong_AsLong(sipPy);\n" , ad->u.ed); break; case sstring_type: if (ad->nrderefs == 0) rhs = "(signed char)sipBytes_AsChar(sipPy)"; else if (isConstArg(ad)) rhs = "(const signed char *)sipBytes_AsString(sipPy)"; else rhs = "(signed char *)sipBytes_AsString(sipPy)"; break; case ustring_type: if (ad->nrderefs == 0) rhs = "(unsigned char)sipBytes_AsChar(sipPy)"; else if (isConstArg(ad)) rhs = "(const unsigned char *)sipBytes_AsString(sipPy)"; else rhs = "(unsigned char *)sipBytes_AsString(sipPy)"; break; case ascii_string_type: if (ad->nrderefs == 0) rhs = "sipString_AsASCIIChar(sipPy)"; else if (isConstArg(ad)) rhs = "sipString_AsASCIIString(&sipPy)"; else rhs = "(char *)sipString_AsASCIIString(&sipPy)"; break; case latin1_string_type: if (ad->nrderefs == 0) rhs = "sipString_AsLatin1Char(sipPy)"; else if (isConstArg(ad)) rhs = "sipString_AsLatin1String(&sipPy)"; else rhs = "(char *)sipString_AsLatin1String(&sipPy)"; break; case utf8_string_type: if (ad->nrderefs == 0) rhs = "sipString_AsUTF8Char(sipPy)"; else if (isConstArg(ad)) rhs = "sipString_AsUTF8String(&sipPy)"; else rhs = "(char *)sipString_AsUTF8String(&sipPy)"; break; case string_type: if (ad->nrderefs == 0) rhs = "sipBytes_AsChar(sipPy)"; else if (isConstArg(ad)) rhs = "sipBytes_AsString(sipPy)"; else rhs = "(const *)sipBytes_AsString(sipPy)"; break; case wstring_type: if (ad->nrderefs == 0) rhs = "sipUnicode_AsWChar(sipPy)"; else rhs = "sipUnicode_AsWString(sipPy)"; break; case float_type: case cfloat_type: rhs = "(float)PyFloat_AsDouble(sipPy)"; break; case double_type: case cdouble_type: rhs = "PyFloat_AsDouble(sipPy)"; break; case bool_type: case cbool_type: rhs = "(bool)SIPLong_AsLong(sipPy)"; break; case byte_type: rhs = "(char)SIPLong_AsLong(sipPy)"; break; case sbyte_type: rhs = "(signed char)SIPLong_AsLong(sipPy)"; break; case ubyte_type: rhs = "(unsigned char)sipLong_AsUnsignedLong(sipPy)"; break; case ushort_type: rhs = "(unsigned short)sipLong_AsUnsignedLong(sipPy)"; break; case short_type: rhs = "(short)SIPLong_AsLong(sipPy)"; break; case uint_type: rhs = "(uint)sipLong_AsUnsignedLong(sipPy)"; break; case int_type: case cint_type: rhs = "(int)SIPLong_AsLong(sipPy)"; break; case ulong_type: rhs = "sipLong_AsUnsignedLong(sipPy)"; break; case long_type: rhs = "PyLong_AsLong(sipPy)"; break; case ulonglong_type: rhs = "PyLong_AsUnsignedLongLongMask(sipPy)"; break; case longlong_type: rhs = "PyLong_AsLongLong(sipPy)"; break; case struct_type: prcode(fp, "(struct %S *)sipConvertToVoidPtr(sipPy);\n" , ad->u.sname); break; case void_type: rhs = "sipConvertToVoidPtr(sipPy)"; break; case 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; } 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); } /* * 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); } /* * Returns TRUE if the given method is an inplace sequence slot. */ static int isInplaceSequenceSlot(memberDef *md) { slotType st = md->slot; return (st == iconcat_slot || st == irepeat_slot); } /* * Returns TRUE if the given method is a number slot. */ int isNumberSlot(memberDef *md) { slotType st = md->slot; return (st == add_slot || st == sub_slot || st == mul_slot || st == div_slot || st == mod_slot || st == floordiv_slot || st == truediv_slot || st == and_slot || st == or_slot || st == xor_slot || st == lshift_slot || st == rshift_slot); } /* * Returns TRUE if the given method is a rich compare slot. */ int isRichCompareSlot(memberDef *md) { slotType st = md->slot; return (st == lt_slot || st == le_slot || st == eq_slot || st == ne_slot || st == gt_slot || st == ge_slot); } /* * Generate a Python slot handler for either a class, an enum or an extender. */ static void generateSlot(moduleDef *mod, classDef *cd, enumDef *ed, memberDef *md, FILE *fp) { char *arg_str, *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 (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" " return %s;\n" "\n" , fqcname, fqcname, fqcname , (md->slot == cmp_slot ? "-2" : (ret_int ? "-1" : "0"))); else prcode(fp, " %S sipCpp = static_cast<%S>(SIPLong_AsLong(sipSelf));\n" "\n" , fqcname, fqcname); } if (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 (py2OnlySlot(md->slot) || py2_5LaterSlot(md->slot)) prcode(fp, "#endif\n" ); } /* * Generate the member functions for a class. */ static void generateClassFunctions(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp) { visibleList *vl; memberDef *md; /* Any shadow code. */ if (hasShadow(cd)) { 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); if (cd->iff->type != namespace_iface && !generating_c) { classList *cl; int need_ptr, need_cast_ptr, need_state; /* The cast function. */ prcode(fp, "\n" "\n" "/* Cast a pointer to a type somewhere in its superclass hierarchy. */\n" "extern \"C\" {static void *cast_%L(void *, const sipTypeDef *);}\n" "static void *cast_%L(void *ptr, const sipTypeDef *targetType)\n" "{\n" , cd->iff , cd->iff); if (cd->supers != NULL) prcode(fp, " void *res;\n" "\n" ); prcode(fp, " if (targetType == sipType_%C)\n" " return ptr;\n" ,classFQCName(cd)); for (cl = cd->supers; cl != NULL; cl = cl->next) { scopedNameDef *sname = cl->cd->iff->fqcname; prcode(fp, "\n" " if ((res = ((const sipClassTypeDef *)sipType_%C)->ctd_cast((%S *)(%S *)ptr,targetType)) != NULL)\n" " return res;\n" ,sname,sname,classFQCName(cd)); } prcode(fp, "\n" " return NULL;\n" "}\n" ); /* Generate the release function without compiler warnings. */ need_ptr = need_cast_ptr = need_state = FALSE; if (cd->dealloccode != NULL) need_ptr = need_cast_ptr = usedInCode(cd->dealloccode, "sipCpp"); if (canCreate(cd) || isPublicDtor(cd)) { if ((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 (!generating_c) prcode(fp, "extern \"C\" {static int getbuffer_%C(PyObject *, void *, Py_buffer *, int);}\n" , classFQCName(cd)); prcode(fp, "static int getbuffer_%C(PyObject *%s, void *%s, Py_buffer *sipBuffer, int %s)\n" "{\n" , classFQCName(cd), argName("sipSelf", cd->getbufcode), (generating_c || need_cpp ? "sipCppV" : ""), argName("sipFlags", cd->getbufcode)); if (need_cpp) { prcode(fp, " "); generateClassFromVoid(cd, "sipCpp", "sipCppV", fp); prcode(fp, ";\n" ); } prcode(fp, " int sipRes;\n" "\n" ); generateCppCodeBlock(cd->getbufcode, fp); prcode(fp, "\n" " return sipRes;\n" "}\n" "#endif\n" ); } if (cd->releasebufcode != NULL) { prcode(fp, "\n" "\n" "#if PY_MAJOR_VERSION >= 3\n" ); if (!generating_c) prcode(fp, "extern \"C\" {static void releasebuffer_%C(PyObject *, void *, Py_buffer *);}\n" , classFQCName(cd)); prcode(fp, "static void releasebuffer_%C(PyObject *%s, void *sipCppV, Py_buffer *)\n" "{\n" " ", classFQCName(cd) , argName("sipSelf", cd->releasebufcode)); generateClassFromVoid(cd, "sipCpp", "sipCppV", fp); prcode(fp, ";\n" "\n" ); generateCppCodeBlock(cd->releasebufcode, fp); prcode(fp, "}\n" "#endif\n" ); } if (cd->readbufcode != NULL) { prcode(fp, "\n" "\n" "#if PY_MAJOR_VERSION < 3\n" ); if (!generating_c) prcode(fp, "extern \"C\" {static SIP_SSIZE_T getreadbuffer_%C(PyObject *, void *, SIP_SSIZE_T, void **);}\n" , classFQCName(cd)); prcode(fp, "static SIP_SSIZE_T getreadbuffer_%C(PyObject *%s, void *sipCppV, SIP_SSIZE_T %s, void **%s)\n" "{\n" " ", classFQCName(cd) , argName("sipSelf", cd->readbufcode) , argName("sipSegment", cd->readbufcode) , argName("sipPtrPtr", cd->readbufcode)); generateClassFromVoid(cd, "sipCpp", "sipCppV", fp); prcode(fp, ";\n" " SIP_SSIZE_T sipRes;\n" "\n" ); generateCppCodeBlock(cd->readbufcode, fp); prcode(fp, "\n" " return sipRes;\n" "}\n" "#endif\n" ); } if (cd->writebufcode != NULL) { prcode(fp, "\n" "\n" "#if PY_MAJOR_VERSION < 3\n" ); if (!generating_c) prcode(fp, "extern \"C\" {static SIP_SSIZE_T getwritebuffer_%C(PyObject *, void *, SIP_SSIZE_T, void **);}\n" , classFQCName(cd)); prcode(fp, "static SIP_SSIZE_T getwritebuffer_%C(PyObject *%s, void *sipCppV, SIP_SSIZE_T %s, void **%s)\n" "{\n" " ", classFQCName(cd) , argName("sipSelf", cd->writebufcode) , argName("sipSegment", cd->writebufcode) , argName("sipPtrPtr", cd->writebufcode)); generateClassFromVoid(cd, "sipCpp", "sipCppV", fp); prcode(fp, ";\n" " SIP_SSIZE_T sipRes;\n" "\n" ); generateCppCodeBlock(cd->writebufcode, fp); prcode(fp, "\n" " return sipRes;\n" "}\n" "#endif\n" ); } if (cd->segcountcode != NULL) { prcode(fp, "\n" "\n" "#if PY_MAJOR_VERSION < 3\n" ); if (!generating_c) prcode(fp, "extern \"C\" {static SIP_SSIZE_T getsegcount_%C(PyObject *, void *, SIP_SSIZE_T *);}\n" , classFQCName(cd)); prcode(fp, "static SIP_SSIZE_T getsegcount_%C(PyObject *%s, void *sipCppV, SIP_SSIZE_T *%s)\n" "{\n" " ", classFQCName(cd) , argName("sipSelf", cd->segcountcode) , argName("sipLenPtr", cd->segcountcode)); generateClassFromVoid(cd, "sipCpp", "sipCppV", fp); prcode(fp, ";\n" " SIP_SSIZE_T sipRes;\n" "\n" ); generateCppCodeBlock(cd->segcountcode, fp); prcode(fp, "\n" " return sipRes;\n" "}\n" "#endif\n" ); } if (cd->charbufcode != NULL) { prcode(fp, "\n" "\n" "#if PY_MAJOR_VERSION < 3\n" ); if (!generating_c) prcode(fp, "extern \"C\" {static SIP_SSIZE_T getcharbuffer_%C(PyObject *, void *, SIP_SSIZE_T, void **);}\n" , classFQCName(cd)); prcode(fp, "static SIP_SSIZE_T getcharbuffer_%C(PyObject *%s, void *sipCppV, SIP_SSIZE_T %s, void **%s)\n" "{\n" " ", classFQCName(cd) , argName("sipSelf", cd->charbufcode) , argName("sipSegment", cd->charbufcode) , argName("sipPtrPtr", cd->charbufcode)); generateClassFromVoid(cd, "sipCpp", "sipCppV", fp); prcode(fp, ";\n" " SIP_SSIZE_T sipRes;\n" "\n" ); generateCppCodeBlock(cd->charbufcode, fp); prcode(fp, "\n" " return sipRes;\n" "}\n" "#endif\n" ); } /* The pickle function. */ if (cd->picklecode != NULL) { prcode(fp, "\n" "\n" ); if (!generating_c) prcode(fp, "extern \"C\" {static PyObject *pickle_%C(void *);}\n" , classFQCName(cd)); prcode(fp, "static PyObject *pickle_%C(void *sipCppV)\n" "{\n" " ", classFQCName(cd)); generateClassFromVoid(cd, "sipCpp", "sipCppV", fp); prcode(fp, ";\n" " PyObject *sipRes;\n" "\n" ); generateCppCodeBlock(cd->picklecode, fp); prcode(fp, "\n" " return sipRes;\n" "}\n" ); } /* 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)) { /* The assignment helper. */ prcode(fp, "\n" "\n" ); if (!generating_c) prcode(fp, "extern \"C\" {static void assign_%L(void *, SIP_SSIZE_T, const void *);}\n" , cd->iff); prcode(fp, "static void assign_%L(void *sipDst, SIP_SSIZE_T sipDstIdx, const void *sipSrc)\n" "{\n" , cd->iff); if (generating_c) prcode(fp, " ((struct %S *)sipDst)[sipDstIdx] = *((const struct %S *)sipSrc);\n" , classFQCName(cd), classFQCName(cd)); else prcode(fp, " reinterpret_cast<%S *>(sipDst)[sipDstIdx] = *reinterpret_cast(sipSrc);\n" , classFQCName(cd), classFQCName(cd)); prcode(fp, "}\n" ); /* The array allocation helper. */ prcode(fp, "\n" "\n" ); if (!generating_c) prcode(fp, "extern \"C\" {static void *array_%L(SIP_SSIZE_T);}\n" , cd->iff); prcode(fp, "static void *array_%L(SIP_SSIZE_T sipNrElem)\n" "{\n" , cd->iff); if (generating_c) prcode(fp, " return sipMalloc(sizeof (struct %S) * sipNrElem);\n" , classFQCName(cd)); else prcode(fp, " return new %S[sipNrElem];\n" , classFQCName(cd)); prcode(fp, "}\n" ); /* The copy helper. */ prcode(fp, "\n" "\n" ); if (!generating_c) prcode(fp, "extern \"C\" {static void *copy_%L(const void *, SIP_SSIZE_T);}\n" , cd->iff); prcode(fp, "static void *copy_%L(const void *sipSrc, SIP_SSIZE_T sipSrcIdx)\n" "{\n" , cd->iff); if (generating_c) prcode(fp, " struct %S *sipPtr = sipMalloc(sizeof (struct %S));\n" " *sipPtr = ((const struct %S *)sipSrc)[sipSrcIdx];\n" "\n" " return sipPtr;\n" , classFQCName(cd), classFQCName(cd) , classFQCName(cd)); else prcode(fp, " return new %S(reinterpret_cast(sipSrc)[sipSrcIdx]);\n" , classFQCName(cd), classFQCName(cd)); prcode(fp, "}\n" ); } /* The dealloc function. */ if (needDealloc(cd)) { prcode(fp, "\n" "\n" ); if (!generating_c) prcode(fp, "extern \"C\" {static void dealloc_%L(sipSimpleWrapper *);}\n" , cd->iff); prcode(fp, "static void dealloc_%L(sipSimpleWrapper *sipSelf)\n" "{\n" , cd->iff); if (tracing) prcode(fp, " sipTrace(SIP_TRACE_DEALLOCS,\"dealloc_%L()\\n\");\n" "\n" , cd->iff); /* Disable the virtual handlers. */ if (hasShadow(cd)) prcode(fp, " if (sipIsDerived(sipSelf))\n" " reinterpret_cast(sipGetAddress(sipSelf))->sipPySelf = NULL;\n" "\n" ,classFQCName(cd)); if (generating_c || isPublicDtor(cd) || (hasShadow(cd) && isProtectedDtor(cd))) { prcode(fp, " if (sipIsPyOwned(sipSelf))\n" " {\n" ); if (isDelayedDtor(cd)) { prcode(fp, " sipAddDelayedDtor(sipSelf);\n" ); } else if (generating_c) { 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) ? "sipSelf->flags" : "0")); } prcode(fp, " }\n" ); } prcode(fp, "}\n" ); } /* The type initialisation function. */ if (canCreate(cd)) generateTypeInit(cd, mod, fp); } /* * Generate the shadow (derived) class code. */ static void generateShadowCode(sipSpec *pt, moduleDef *mod, classDef *cd, FILE *fp) { int nrVirts, virtNr; virtOverDef *vod; ctorDef *ct; nrVirts = countVirtuals(cd); /* Generate the wrapper class constructors. */ for (ct = cd->ctors; ct != NULL; ct = ct->next) { ctorDef *dct; if (isPrivateCtor(ct)) continue; if (ct->cppsig == NULL) continue; /* Check we haven't already handled this C++ signature. */ for (dct = cd->ctors; dct != ct; dct = dct->next) if (dct->cppsig != NULL && sameSignature(dct->cppsig, ct->cppsig, TRUE)) break; if (dct != ct) continue; prcode(fp, "\n" "sip%C::sip%C(",classFQCName(cd),classFQCName(cd)); generateCalledArgs(mod, cd->iff, ct->cppsig, Definition, TRUE, fp); prcode(fp,")%X: %S(",ct->exceptions,classFQCName(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, TRUE, fp); prcode(fp,")%X (this=0x%%08x)\\n\",this);\n" "\n" ,ct->exceptions); } if (nrVirts > 0) prcode(fp, " memset(sipPyMethods, 0, sizeof (sipPyMethods));\n" ); prcode(fp, "}\n" ); } /* The destructor. */ if (!isPrivateDtor(cd)) { prcode(fp, "\n" "sip%C::~sip%C()%X\n" "{\n" ,classFQCName(cd),classFQCName(cd),cd->dtorexceptions); if (tracing) prcode(fp, " sipTrace(SIP_TRACE_DTORS,\"sip%C::~sip%C()%X (this=0x%%08x)\\n\",this);\n" "\n" ,classFQCName(cd),classFQCName(cd),cd->dtorexceptions); if (cd->dtorcode != NULL) generateCppCodeBlock(cd->dtorcode,fp); prcode(fp, " sipCommonDtor(sipPySelf);\n" "}\n" ); } /* The meta methods if required. */ if ((pluginPyQt4(pt) || 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, " return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : sip_%s_qt_metaobject(sipPySelf,sipType_%C);\n" , mod->name, 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->o; virtOverDef *dvod; if (isPrivate(od)) continue; /* * Check we haven't already handled this C++ signature. The same C++ * signature should only appear more than once for overloads that are * enabled for different APIs and that differ in their /In/ and/or * /Out/ annotations. */ for (dvod = cd->vmembers; dvod != vod; dvod = dvod->next) if (strcmp(dvod->o.cppname, od->cppname) == 0 && sameSignature(dvod->o.cppsig, od->cppsig, TRUE)) break; if (dvod == vod) generateVirtualCatcher(pt, mod, cd, virtNr++, vod, fp); } /* Generate the wrapper around each protected member function. */ generateProtectedDefinitions(mod, cd, fp); /* Generate the emitters if needed. */ if (pluginPyQt3(pt)) generatePyQt3Emitters(mod, cd, fp); } /* * Generate the PyQt3 emitter functions. */ static void generatePyQt3Emitters(moduleDef *mod, classDef *cd, FILE *fp) { int noIntro; visibleList *vl; for (vl = cd->visible; vl != NULL; vl = vl->next) { overDef *od; for (od = vl->cd->overs; od != NULL; od = od->next) if (od->common == vl->m && isSignal(od)) { generatePyQt3Emitter(mod, cd, vl, fp); break; } } /* Generate the table of signals to support fan-outs. */ noIntro = TRUE; for (vl = cd->visible; vl != NULL; vl = vl->next) { overDef *od; for (od = vl->cd->overs; od != NULL; od = od->next) if (od->common == vl->m && isSignal(od)) { if (noIntro) { setHasSigSlots(cd); prcode(fp, "\n" "static pyqt3QtSignal signals_%C[] = {\n" ,classFQCName(cd)); noIntro = FALSE; } prcode(fp, " {%N, %C_emit_%s},\n" ,vl->m->pyname,classFQCName(cd),vl->m->pyname->text); break; } } if (!noIntro) prcode(fp, " {NULL, NULL}\n" "};\n" ); } /* * Generate the protected enums for a class. */ static void generateProtectedEnums(sipSpec *pt,classDef *cd,FILE *fp) { enumDef *ed; for (ed = pt->enums; ed != NULL; ed = ed->next) { char *eol; mroDef *mro; enumMemberDef *emd; if (!isProtectedEnum(ed)) continue; /* See if the class defining the enum is in our class hierachy. */ for (mro = cd->mro; mro != NULL; mro = mro->next) if (mro->cd == ed->ecd) break; if (mro == NULL) continue; prcode(fp, "\n" " /* Expose this protected enum. */\n" " enum"); if (ed->fqcname != NULL) prcode(fp," sip%s",scopedNameTail(ed->fqcname)); prcode(fp," {"); eol = "\n"; for (emd = ed->members; emd != NULL; emd = emd->next) { prcode(fp,"%s" " %s = %S::%s",eol,emd->cname,classFQCName(ed->ecd),emd->cname); eol = ",\n"; } prcode(fp,"\n" " };\n" ); } } /* * Generate the catcher for a virtual function. */ static void generateVirtualCatcher(sipSpec *pt, moduleDef *mod, classDef *cd, int virtNr, virtOverDef *vod, FILE *fp) { overDef *od = &vod->o; argDef *res; apiVersionRangeDef *avr; normaliseArgs(od->cppsig); res = &od->cppsig->result; if (res->atype == void_type && res->nrderefs == 0) res = NULL; prcode(fp, "\n"); generateBaseType(cd->iff, &od->cppsig->result, TRUE, fp); prcode(fp," sip%C::%O(",classFQCName(cd),od); generateCalledArgs(mod, cd->iff, od->cppsig, Definition, TRUE, fp); prcode(fp,")%s%X\n" "{\n" ,(isConst(od) ? " const" : ""),od->exceptions); if (tracing) { prcode(fp, " sipTrace(SIP_TRACE_CATCHERS,\""); generateBaseType(cd->iff, &od->cppsig->result, TRUE, fp); prcode(fp," sip%C::%O(",classFQCName(cd),od); generateCalledArgs(NULL, cd->iff, od->cppsig, Declaration, TRUE, fp); prcode(fp,")%s%X (this=0x%%08x)\\n\",this);\n" "\n" ,(isConst(od) ? " const" : ""),od->exceptions); } restoreArgs(od->cppsig); prcode(fp, " sip_gilstate_t sipGILState;\n" " PyObject *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 (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(pt, 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(pt, mod, cd, versioned_vod, res, " ", fp); if (res == NULL) prcode(fp, " return;\n" ); prcode(fp, " }\n" ); /* Find the next overload. */ while ((versioned_vod = versioned_vod->next) != NULL) { if (strcmp(versioned_vod->o.cppname, od->cppname) == 0 && sameSignature(versioned_vod->o.cppsig, od->cppsig, TRUE)) { avr = versioned_vod->o.api_range; /* Check that it has an API specified. */ if (avr == NULL) { fatalScopedName(classFQCName(cd)); fatal("::"); prOverloadName(stderr, od); fatal(" has versioned and unversioned overloads\n"); } break; } } } while (versioned_vod != NULL); prcode(fp, "\n" ); /* 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(sipSpec *pt, moduleDef *mod, classDef *cd, virtOverDef *vod, argDef *res, const char *indent, FILE *fp) { overDef *od = &vod->o; virtHandlerDef *vhd = od->virthandler; virtErrorHandler *veh; signatureDef saved; argDef *ad; int a, args_keep = FALSE, result_keep = FALSE; veh = getVirtErrorHandler(pt, od, cd, mod); saved = *vhd->cppsig; fakeProtectedArgs(vhd->cppsig); if (vhd->module == mod) { prcode(fp, "%sextern ", indent); generateBaseType(cd->iff, &od->cppsig->result, FALSE, fp); prcode(fp, " sipVH_%s_%d(sip_gilstate_t, sipVirtErrorHandlerFunc, sipSimpleWrapper *, PyObject *", vhd->module->name, vhd->virthandlernr); } else { prcode(fp, "%stypedef ", indent); generateBaseType(cd->iff, &od->cppsig->result, FALSE, fp); prcode(fp, " (*sipVH_%s_%d)(sip_gilstate_t, sipVirtErrorHandlerFunc, sipSimpleWrapper *, PyObject *", vhd->module->name, vhd->virthandlernr); } if (vhd->cppsig->nrArgs > 0) { prcode(fp, ", "); generateCalledArgs(NULL, cd->iff, vhd->cppsig, Declaration, FALSE, fp); } *vhd->cppsig = saved; /* Add extra arguments for all the references we need to keep. */ if (res != NULL && keepPyReference(res)) { result_keep = TRUE; res->key = mod->next_key--; prcode(fp, ", int"); } for (ad = od->cppsig->args, a = 0; a < od->cppsig->nrArgs; ++a, ++ad) if (isOutArg(ad) && keepPyReference(ad)) { args_keep = TRUE; ad->key = mod->next_key--; prcode(fp, ", int"); } prcode(fp,");\n" ); if (veh != NULL && veh->mod == mod) prcode(fp, "%sextern void sipVEH_%s_%s(sipSimpleWrapper *, sip_gilstate_t);\n" , indent, mod->name, veh->name); prcode(fp, "\n" "%s", indent); if (!isNewThread(od) && res != NULL) prcode(fp, "return "); if (vhd->module == mod) prcode(fp, "sipVH_%s_%d", vhd->module->name,vhd->virthandlernr); else prcode(fp, "((sipVH_%s_%d)(sipModuleAPI_%s_%s->em_virthandlers[%d]))", vhd->module->name, vhd->virthandlernr, mod->name, vhd->module->name, vhd->virthandlernr); prcode(fp, "(sipGILState, "); if (veh == NULL) prcode(fp, "0"); else if (veh->mod == mod) prcode(fp, "sipVEH_%s_%s" , mod->name, veh->name); else prcode(fp, "sipModuleAPI_%s_%s->em_virterrorhandlers[%d]", 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); } /* * Get the virtual error handler for a function. */ static virtErrorHandler *getVirtErrorHandler(sipSpec *pt, overDef *od, classDef *cd, moduleDef *mod) { const char *name; virtErrorHandler *veh; /* 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 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); return veh; } /* * Generate a cast to zero. */ static void generateCastZero(argDef *ad,FILE *fp) { if (ad->atype == enum_type) prcode(fp,"(%E)",ad->u.ed); prcode(fp,"0"); } /* * Generate 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 PyQt3 emitter function for a signal. */ static void generatePyQt3Emitter(moduleDef *mod, classDef *cd, visibleList *vl, FILE *fp) { const char *pname = vl->m->pyname->text; overDef *od; prcode(fp, "\n" "int sip%C::sipEmit_%s(PyObject *sipArgs)\n" "{\n" " PyObject *sipParseErr = NULL;\n" ,classFQCName(cd),pname); for (od = vl->cd->overs; od != NULL; od = od->next) { int rgil = ((release_gil || isReleaseGIL(od)) && !isHoldGIL(od)); if (od->common != vl->m || !isSignal(od)) continue; /* * Generate the code that parses the args and emits the appropriate * overloaded signal. */ prcode(fp, "\n" " {\n" ); generateArgParser(mod, &od->pysig, cd, NULL, NULL, NULL, FALSE, fp); prcode(fp, " {\n" ); if (rgil) prcode(fp, " Py_BEGIN_ALLOW_THREADS\n" ); prcode(fp, " emit %s(" ,od->cppname); generateCallArgs(mod, od->cppsig, &od->pysig, fp); prcode(fp,");\n" ); if (rgil) prcode(fp, " Py_END_ALLOW_THREADS\n" ); deleteTemps(mod, &od->pysig, fp); prcode(fp, "\n" " return 0;\n" " }\n" " }\n" ); } prcode(fp, "\n" " sipNoMethod(sipParseErr, %N, %N, NULL);\n" "\n" " return -1;\n" "}\n" "\n" , cd->pyname, vl->m->pyname); if (!generating_c) prcode(fp, "extern \"C\" {static int %C_emit_%s(sipSimpleWrapper *, PyObject *);}\n" , classFQCName(cd), pname); prcode(fp, "static int %C_emit_%s(sipSimpleWrapper *sw,PyObject *sipArgs)\n" "{\n" " sip%C *ptr = reinterpret_cast(sipGetComplexCppPtr(sw));\n" "\n" " return (ptr ? ptr->sipEmit_%s(sipArgs) : -1);\n" "}\n" ,classFQCName(cd),pname ,classFQCName(cd),classFQCName(cd) ,pname); } /* * Generate the declarations of the protected wrapper functions for a class. */ static void generateProtectedDeclarations(classDef *cd,FILE *fp) { int noIntro; visibleList *vl; noIntro = TRUE; for (vl = cd->visible; vl != NULL; vl = vl->next) { overDef *od; if (vl->m->slot != no_slot) continue; for (od = vl->cd->overs; od != NULL; od = od->next) { if (od->common != vl->m || !isProtected(od)) continue; /* * Check we haven't already handled this signature (eg. if we have * specified the same method with different Python names. */ if (isDuplicateProtected(cd, od)) continue; if (noIntro) { prcode(fp, "\n" " /*\n" " * There is a public method for every protected method visible from\n" " * this class.\n" " */\n" ); noIntro = FALSE; } prcode(fp, " "); if (isStatic(od)) prcode(fp,"static "); generateBaseType(cd->iff, &od->cppsig->result, TRUE, fp); if (!isStatic(od) && !isAbstract(od) && (isVirtual(od) || isVirtualReimp(od))) { prcode(fp, " sipProtectVirt_%s(bool", od->cppname); if (od->cppsig->nrArgs > 0) prcode(fp, ","); } else prcode(fp, " sipProtect_%s(", od->cppname); generateCalledArgs(NULL, cd->iff, od->cppsig, Declaration, TRUE, fp); prcode(fp,")%s;\n" ,(isConst(od) ? " const" : "")); } } } /* * Generate the definitions of the protected wrapper functions for a class. */ static void generateProtectedDefinitions(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, 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, TRUE, fp); prcode(fp,")%s\n" "{\n" ,(isConst(od) ? " const" : "")); parens = 1; res = &od->cppsig->result; if (res->atype == void_type && res->nrderefs == 0) prcode(fp, " "); else { prcode(fp, " return "); if (res->atype == class_type && isProtectedClass(res->u.cd)) { prcode(fp,"static_cast<%U *>(",res->u.cd); ++parens; } else if (res->atype == enum_type && isProtectedEnum(res->u.ed)) /* * One or two older compilers can't handle a static_cast * here so we revert to a C-style cast. */ prcode(fp,"(%E)",res->u.ed); } if (!isAbstract(od)) { if (isVirtual(od) || isVirtualReimp(od)) { prcode(fp, "(sipSelfWasArg ? %S::%s(", classFQCName(vl->cd), mname); generateProtectedCallArgs(mod, od->cppsig, fp); prcode(fp, ") : "); ++parens; } else prcode(fp, "%S::", classFQCName(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, FALSE, fp); prcode(fp," sipVH_%s_%d(sip_gilstate_t sipGILState, sipVirtErrorHandlerFunc sipErrorHandler, sipSimpleWrapper *sipPySelf, PyObject *sipMethod" , vhd->module->name, vhd->virthandlernr); if (vhd->cppsig->nrArgs > 0) { prcode(fp,", "); generateCalledArgs(mod, NULL, vhd->cppsig, Definition, FALSE, 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, FALSE, fp); prcode(fp," %ssipRes",(res_isref ? "*" : "")); if ((res->atype == class_type || res->atype == mapped_type) && res->nrderefs == 0) { if (res->atype == class_type) { ctorDef *ct = res->u.cd->defctor; if (ct != NULL && isPublicCtor(ct) && ct->cppsig != NULL && ct->cppsig->nrArgs > 0 && ct->cppsig->args[0].defval == NULL) generateCallDefaultCtor(ct,fp); } } else { /* * We initialise the result to try and suppress a compiler warning. */ prcode(fp," = "); generateCastZero(res,fp); } prcode(fp,";\n" ); if (res->atype == wstring_type && res->nrderefs == 1) prcode(fp, "\n" " if (sipRes)\n" " {\n" " // Return any previous result to the heap.\n" " sipFree(%s);\n" " sipRes = 0;\n" " }\n" "\n" , (isConstArg(res) ? "const_cast(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. */ prcode(fp, " PyObject *sipResObj = sipCallMethod(0, sipMethod, "); saved = *vhd->pysig; fakeProtectedArgs(vhd->pysig); generateTupleBuilder(mod, vhd->pysig, fp); *vhd->pysig = saved; prcode(fp, ");\n" "\n" " %ssipParseResultEx(sipGILState, sipErrorHandler, sipPySelf, sipMethod, sipResObj, \"", (res_isref ? "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) { prcode(fp, "\n" " if (sipRc < 0)\n" ); 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; } 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: 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) ? "$" : "!"); } /* 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; prcode(fp,"\""); for (a = 0; a < sd->nrArgs; ++a) { char *fmt = ""; argDef *ad = &sd->args[a]; if (!isInArg(ad)) continue; switch (ad->atype) { case ascii_string_type: if (ad->nrderefs == 0 || (ad->nrderefs == 1 && isOutArg(ad))) fmt = "aA"; else fmt = "AA"; break; case latin1_string_type: if (ad->nrderefs == 0 || (ad->nrderefs == 1 && isOutArg(ad))) fmt = "aL"; else fmt = "AL"; break; case utf8_string_type: if (ad->nrderefs == 0 || (ad->nrderefs == 1 && isOutArg(ad))) fmt = "a8"; else fmt = "A8"; break; case sstring_type: case ustring_type: case string_type: if (ad->nrderefs == 0 || (ad->nrderefs == 1 && isOutArg(ad))) fmt = "c"; else if (isArray(ad)) fmt = "g"; else fmt = "s"; break; case wstring_type: if (ad->nrderefs == 0 || (ad->nrderefs == 1 && isOutArg(ad))) fmt = "w"; else if (isArray(ad)) fmt = "G"; else fmt = "x"; break; case bool_type: case cbool_type: fmt = "b"; break; case enum_type: fmt = (ad->u.ed->fqcname != NULL) ? "F" : "e"; break; case cint_type: fmt = "i"; break; case uint_type: if (isArraySize(ad)) arraylenarg = a; else fmt = "u"; break; case int_type: if (isArraySize(ad)) arraylenarg = a; else fmt = "i"; break; case 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; } prcode(fp,fmt); } prcode(fp,"\""); for (a = 0; a < sd->nrArgs; ++a) { int derefs; argDef *ad = &sd->args[a]; if (!isInArg(ad)) continue; derefs = ad->nrderefs; switch (ad->atype) { case ascii_string_type: case latin1_string_type: case utf8_string_type: case sstring_type: case ustring_type: case string_type: case wstring_type: if (!(ad->nrderefs == 0 || (ad->nrderefs == 1 && isOutArg(ad)))) --derefs; break; case mapped_type: case fake_void_type: case class_type: if (ad->nrderefs > 0) --derefs; break; case struct_type: case void_type: --derefs; break; } if (ad->atype == mapped_type || ad->atype == class_type || ad->atype == rxcon_type || ad->atype == rxdis_type || ad->atype == qobject_type || ad->atype == fake_void_type) { int copy = copyConstRefArg(ad); prcode(fp,","); if (copy) { prcode(fp,"new %b(",ad); } else { if (isConstArg(ad)) prcode(fp,"const_cast<%b *>(",ad); if (ad->nrderefs == 0) prcode(fp,"&"); else while (derefs-- != 0) prcode(fp,"*"); } prcode(fp, "%a", 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) { classDef *cd; mappedTypeDef *mtd; exceptionDef *xd; for (cd = pt->classes; cd != NULL; cd = cd->next) if (cd->iff->module == mod) generateClassAPI(cd, pt, fp); for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next) if (mtd->iff->module == mod) generateMappedTypeAPI(pt, mtd, fp); for (xd = pt->exceptions; xd != NULL; xd = xd->next) if (xd->iff->module == mod && xd->exceptionnr >= 0) prcode(fp, "\n" "#define sipException_%C sipModuleAPI_%s.em_exceptions[%d]\n" , xd->iff->fqcname, mod->name, xd->exceptionnr); } /* * Generate the API details for an imported module. */ static void generateImportedModuleAPI(sipSpec *pt, moduleDef *mod, moduleDef *immod, FILE *fp) { classDef *cd; mappedTypeDef *mtd; exceptionDef *xd; for (cd = pt->classes; cd != NULL; cd = cd->next) if (cd->iff->module == immod && !isExternal(cd)) generateImportedClassAPI(cd, pt, mod, fp); for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next) if (mtd->iff->module == immod) generateImportedMappedTypeAPI(mtd, pt, mod, fp); for (xd = pt->exceptions; xd != NULL; xd = xd->next) if (xd->iff->module == immod && xd->exceptionnr >= 0) prcode(fp, "\n" "#define sipException_%C sipModuleAPI_%s_%s->em_exceptions[%d]\n" , xd->iff->fqcname, mod->name, xd->iff->module->name, xd->exceptionnr); } /* * Generate the API details for an imported mapped type. */ static void generateImportedMappedTypeAPI(mappedTypeDef *mtd, sipSpec *pt, moduleDef *mod, FILE *fp) { /* Ignore alternate API implementations. */ if (mtd->iff->first_alt == mtd->iff) { const char *mname = mod->name; const char *imname = mtd->iff->module->name; argDef type; memset(&type, 0, sizeof (argDef)); type.atype = mapped_type; type.u.mtd = mtd; prcode(fp, "\n" "#define sipType_%T sipModuleAPI_%s_%s->em_types[%d]\n" , &type, mname, imname, mtd->iff->ifacenr); } generateEnumMacros(pt, mod, NULL, mtd, fp); } /* * Generate the API details for a mapped type. */ static void generateMappedTypeAPI(sipSpec *pt, mappedTypeDef *mtd, FILE *fp) { argDef type; memset(&type, 0, sizeof (argDef)); type.atype = mapped_type; type.u.mtd = mtd; if (mtd->iff->first_alt == mtd->iff) prcode(fp, "\n" "#define sipType_%T sipModuleAPI_%s.em_types[%d]\n" , &type, mtd->iff->module->name, mtd->iff->ifacenr); prcode(fp, "\n" "extern sipMappedTypeDef sipTypeDef_%s_%L;\n" , mtd->iff->module->name, mtd->iff); generateEnumMacros(pt, mtd->iff->module, NULL, mtd, fp); } /* * Generate the API details for an imported class. */ static void generateImportedClassAPI(classDef *cd, sipSpec *pt, moduleDef *mod, FILE *fp) { prcode(fp, "\n" ); /* Ignore alternate API implementations. */ if (cd->iff->first_alt == cd->iff) { const char *mname = mod->name; const char *imname = cd->iff->module->name; if (cd->iff->type == namespace_iface) prcode(fp, "#if !defined(sipType_%L)\n" , cd->iff); prcode(fp, "#define sipType_%C sipModuleAPI_%s_%s->em_types[%d]\n" "#define sipClass_%C sipModuleAPI_%s_%s->em_types[%d]->u.td_wrapper_type\n" , classFQCName(cd), mname, imname, cd->iff->ifacenr , classFQCName(cd), mname, imname, cd->iff->ifacenr); if (cd->iff->type == namespace_iface) prcode(fp, "#endif\n" ); } generateEnumMacros(pt, mod, cd, NULL, fp); } /* * Generate the C++ API for a class. */ static void generateClassAPI(classDef *cd, sipSpec *pt, FILE *fp) { const char *mname = cd->iff->module->name; prcode(fp, "\n" ); if (cd->real == NULL && cd->iff->first_alt == cd->iff) prcode(fp, "#define sipType_%C sipModuleAPI_%s.em_types[%d]\n" "#define sipClass_%C sipModuleAPI_%s.em_types[%d]->u.td_wrapper_type\n" , classFQCName(cd), mname, cd->iff->ifacenr , classFQCName(cd), mname, cd->iff->ifacenr); generateEnumMacros(pt, cd->iff->module, cd, NULL, fp); if (!isExternal(cd)) { const char *type_prefix; if (pluginPyQt5(pt)) type_prefix = "pyqt5"; else if (pluginPyQt4(pt)) type_prefix = "pyqt4"; else if (pluginPyQt3(pt)) type_prefix = "pyqt3"; else type_prefix = "sip"; prcode(fp, "\n" "extern %sClassTypeDef sipTypeDef_%s_%L;\n" , type_prefix, mname, cd->iff); 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; int noIntro = TRUE; for (ed = pt->enums; ed != NULL; ed = ed->next) { if (ed->fqcname == NULL) continue; if (ed->first_alt != ed) continue; if (cd != NULL) { if (ed->ecd != cd) continue; } else if (mtd != NULL) { if (ed->emtd != mtd) continue; } else if (ed->ecd != NULL || ed->emtd != NULL) { continue; } if (noIntro) { prcode(fp, "\n" ); noIntro = FALSE; } if (mod == ed->module) prcode(fp, "#define sipType_%C sipModuleAPI_%s.em_types[%d]\n" "#define sipEnum_%C sipModuleAPI_%s.em_types[%d]->u.td_py_type\n" , ed->fqcname, mod->name, ed->enumnr , ed->fqcname, mod->name, ed->enumnr); else prcode(fp, "#define sipType_%C sipModuleAPI_%s_%s->em_types[%d]\n" "#define sipEnum_%C sipModuleAPI_%s_%s->em_types[%d]->u.td_py_type\n" , ed->fqcname, mod->name, ed->module->name, ed->enumnr , ed->fqcname, mod->name, ed->module->name, ed->enumnr); } } /* * Generate the shadow class declaration. */ static void generateShadowClassDeclaration(sipSpec *pt,classDef *cd,FILE *fp) { int noIntro, nrVirts; ctorDef *ct; virtOverDef *vod; classDef *pcd; prcode(fp, "\n" "\n" "class sip%C : public %S\n" "{\n" "public:\n" ,classFQCName(cd),classFQCName(cd)); /* Define a shadow class for any protected classes we have. */ for (pcd = pt->classes; pcd != NULL; pcd = pcd->next) { mroDef *mro; if (!isProtectedClass(pcd)) continue; /* See if the class defining the class is in our class hierachy. */ for (mro = cd->mro; mro != NULL; mro = mro->next) if (mro->cd == pcd->ecd) break; if (mro == NULL) continue; prcode(fp, " class sip%s : public %s {\n" " public:\n" , classBaseName(pcd), classBaseName(pcd)); generateProtectedEnums(pt, pcd, fp); prcode(fp, " };\n" "\n" ); } /* The constructor declarations. */ for (ct = cd->ctors; ct != NULL; ct = ct->next) { ctorDef *dct; if (isPrivateCtor(ct)) continue; if (ct->cppsig == NULL) continue; /* Check we haven't already handled this C++ signature. */ for (dct = cd->ctors; dct != ct; dct = dct->next) if (dct->cppsig != NULL && sameSignature(dct->cppsig, ct->cppsig, TRUE)) break; if (dct != ct) continue; prcode(fp, " sip%C(",classFQCName(cd)); generateCalledArgs(NULL, cd->iff, ct->cppsig, Declaration, TRUE, fp); prcode(fp,")%X;\n" ,ct->exceptions); } /* The destructor. */ if (!isPrivateDtor(cd)) prcode(fp, " %s~sip%C()%X;\n" ,(cd->vmembers != NULL ? "virtual " : ""),classFQCName(cd),cd->dtorexceptions); /* The metacall methods if required. */ if ((pluginPyQt4(pt) || 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 public wrapper around each signal emitter. */ if (pluginPyQt3(pt)) { visibleList *vl; noIntro = TRUE; for (vl = cd->visible; vl != NULL; vl = vl->next) { overDef *od; if (vl->m->slot != no_slot) continue; for (od = vl->cd->overs; od != NULL; od = od->next) { if (od->common != vl->m || !isSignal(od)) continue; if (noIntro) { prcode(fp, "\n" " /*\n" " * There is a public method for every Qt signal that can be emitted\n" " * by this object. This function is called by Python to emit the\n" " * signal.\n" " */\n" ); noIntro = FALSE; } prcode(fp, " int sipEmit_%s(PyObject *);\n" ,vl->m->pyname->text); break; } } } /* The catcher around each virtual function in the hierarchy. */ noIntro = TRUE; for (vod = cd->vmembers; vod != NULL; vod = vod->next) { overDef *od = &vod->o; virtOverDef *dvod; if (isPrivate(od)) continue; /* Check we haven't already handled this C++ signature. */ for (dvod = cd->vmembers; dvod != vod; dvod = dvod->next) if (strcmp(dvod->o.cppname,od->cppname) == 0 && sameSignature(dvod->o.cppsig,od->cppsig,TRUE)) break; if (dvod != vod) continue; if (noIntro) { prcode(fp, "\n" " /*\n" " * There is a protected method for every virtual method visible from\n" " * this class.\n" " */\n" "protected:\n" ); noIntro = FALSE; } prcode(fp, " "); prOverloadDecl(fp, cd->iff, od, FALSE); prcode(fp, ";\n"); } prcode(fp, "\n" "public:\n" " sipSimpleWrapper *sipPySelf;\n" ); /* The private declarations. */ prcode(fp, "\n" "private:\n" " sip%C(const sip%C &);\n" " sip%C &operator = (const sip%C &);\n" ,classFQCName(cd),classFQCName(cd) ,classFQCName(cd),classFQCName(cd)); if ((nrVirts = countVirtuals(cd)) > 0) prcode(fp, "\n" " char sipPyMethods[%d];\n" ,nrVirts); prcode(fp, "};\n" ); } /* * Generate the C++ declaration for an overload. */ void prOverloadDecl(FILE *fp, ifaceFileDef *scope, overDef *od, int defval) { int a; normaliseArgs(od->cppsig); generateBaseType(scope, &od->cppsig->result, TRUE, fp); prcode(fp, " %O(", od); for (a = 0; a < od->cppsig->nrArgs; ++a) { argDef *ad = &od->cppsig->args[a]; if (a > 0) prcode(fp, ","); generateBaseType(scope, ad, TRUE, fp); if (defval && ad->defval != NULL) { prcode(fp, " = "); generateExpression(ad->defval, FALSE, fp); } } prcode(fp, ")%s%X", (isConst(od) ? " const" : ""), od->exceptions); restoreArgs(od->cppsig); } /* * Generate typed arguments for a declaration or a definition. */ static void generateCalledArgs(moduleDef *mod, ifaceFileDef *scope, signatureDef *sd, funcArgType ftype, int use_typename, 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, use_typename, 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)) ind = "&"; break; case mapped_type: case class_type: if (ad->nrderefs == 2) ind = "&"; else if (ad->nrderefs == 0) ind = "*"; break; case struct_type: case void_type: if (ad->nrderefs == 2) ind = "&"; break; default: if (ad->nrderefs == 1) ind = "&"; } if (ind != NULL) prcode(fp, ind); /* * See if we need to cast a Python void * to the correct C/C++ pointer * type. */ if (py_sd != sd) { py_ad = &py_sd->args[a]; if ((py_ad->atype != void_type && 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 (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, fp); } /* * Generate a C++ type. */ static void generateBaseType(ifaceFileDef *scope, argDef *ad, int use_typename, FILE *fp) { generateNamedBaseType(scope, ad, "", use_typename, fp); } /* * Generate a C++ type and name. */ static void generateNamedBaseType(ifaceFileDef *scope, argDef *ad, const char *name, int use_typename, FILE *fp) { typedefDef *td = ad->original_type; int nr_derefs = ad->nrderefs; int is_reference = isReference(ad); int i; if (use_typename && td != NULL && !noTypeName(td) && !isArraySize(ad)) { if (isConstArg(ad) && !isConstArg(&td->type)) prcode(fp, "const "); nr_derefs -= td->type.nrderefs; if (isReference(&td->type)) is_reference = FALSE; prcode(fp, "%S", td->fqname); } else { /* * A function type is handled differently because of the position of * the name. */ if (ad->atype == function_type) { signatureDef *sig = ad->u.sa; generateBaseType(scope, &sig->result, TRUE, fp); prcode(fp," ("); for (i = 0; i < nr_derefs; ++i) prcode(fp, "*"); prcode(fp, "%s)(",name); generateCalledArgs(NULL, scope, sig, Declaration, use_typename, 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: 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, ad->u.snd, "."); } else { if (generating_c) fprintf(fp, "struct "); prScopedName(fp, ad->u.snd, "::"); } break; case rxcon_type: case rxdis_type: nr_derefs = 1; prcode(fp, "QObject"); break; case mapped_type: generateBaseType(scope, &ad->u.mtd->type, TRUE, fp); break; case class_type: prcode(fp, "%V", scope, ad->u.cd); break; case template_type: { static const char tail[] = ">"; int a; templateDef *td = ad->u.td; prcode(fp, "%S%s", td->fqname, (prcode_xml ? "<" : "<")); for (a = 0; a < td->types.nrArgs; ++a) { if (a > 0) prcode(fp, ","); generateBaseType(scope, &td->types.args[a], TRUE, fp); } if (prcode_last == tail) prcode(fp, " "); prcode(fp, (prcode_xml ? ">" : tail)); break; } case enum_type: prcode(fp, "%E", ad->u.ed); break; case pyobject_type: case pytuple_type: case pylist_type: case pydict_type: case pycallable_type: case pyslice_type: case pytype_type: case pybuffer_type: case qobject_type: case ellipsis_type: prcode(fp, "PyObject *"); break; } } for (i = 0; i < nr_derefs; ++i) { prcode(fp, " *"); if (ad->derefs[i]) prcode(fp, " const"); } if (is_reference) prcode(fp, (prcode_xml ? "&" : "&")); if (*name != '\0') { if (nr_derefs == 0) prcode(fp, " "); prcode(fp, name); } } /* * Generate the definition of an argument variable and any supporting * variables. */ static void generateVariable(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) 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; } } } /* * 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,FILE *fp) { int i; prcode(fp, "%B(", &fcd->type); for (i = 0; i < fcd->nrArgs; ++i) { if (i > 0) prcode(fp,","); generateExpression(fcd->args[i], FALSE, fp); } prcode(fp,")"); } /* * Generate the type structure that contains all the information needed by the * meta-type. A sub-set of this is used to extend namespaces. */ static void generateTypeDefinition(sipSpec *pt, classDef *cd, FILE *fp) { const char *mname, *sep, *type_prefix; int is_slots, is_signals, nr_methods, nr_enums, nr_vars, embedded; int is_inst_class, is_inst_voidp, is_inst_char, is_inst_string; int is_inst_int, is_inst_long, is_inst_ulong, is_inst_longlong; int is_inst_ulonglong, is_inst_double, has_docstring; memberDef *md; moduleDef *mod; propertyDef *pd; mod = cd->iff->module; mname = mod->name; if (cd->supers != NULL) { classList *cl; prcode(fp, "\n" "\n" "/* Define this type's super-types. */\n" "static sipEncodedTypeDef supers_%C[] = {", classFQCName(cd)); for (cl = cd->supers; cl != NULL; cl = cl->next) { if (cl != cd->supers) prcode(fp, ", "); generateEncodedType(mod, cl->cd, (cl->next == NULL), fp); } prcode(fp,"};\n" ); } /* Generate the slots table. */ is_slots = FALSE; for (md = cd->members; md != NULL; md = md->next) { const char *stype; if (md->slot == no_slot) continue; if (!is_slots) { prcode(fp, "\n" "\n" "/* Define this type's Python slots. */\n" "static sipPySlotDef slots_%L[] = {\n" , cd->iff); is_slots = TRUE; } if ((stype = slotName(md->slot)) != NULL) { if (py2OnlySlot(md->slot)) prcode(fp, "#if PY_MAJOR_VERSION < 3\n" ); else if (py2_5LaterSlot(md->slot)) prcode(fp, "#if PY_VERSION_HEX >= 0x02050000\n" ); prcode(fp, " {(void *)slot_%L_%s, %s},\n" , cd->iff, md->pyname->text, stype); if (py2OnlySlot(md->slot) || py2_5LaterSlot(md->slot)) prcode(fp, "#endif\n" ); } } if (is_slots) prcode(fp, " {0, (sipPySlotType)0}\n" "};\n" ); /* Generate the attributes tables. */ nr_methods = generateClassMethodTable(pt, cd, fp); nr_enums = generateEnumMemberTable(pt, mod, cd, NULL, fp); /* Generate the PyQt4/5 signals table. */ is_signals = FALSE; if ((pluginPyQt4(pt) || pluginPyQt5(pt)) && isQObjectSubClass(cd)) { const char *pyqt_prefix = (pluginPyQt5(pt) ? "pyqt5" : "pyqt4"); /* 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(mod, 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, md, 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, md, -1, FALSE, fp); } cppsig->nrArgs = nr_args; } } } if (is_signals) prcode(fp, " {0, 0, 0, 0}\n" "};\n" ); } /* 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); generateExplicitDocstring(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. */ has_docstring = FALSE; if (cd->docstring != NULL || (docstrings && hasClassDocstring(pt, cd))) { prcode(fp, "\n" "PyDoc_STRVAR(doc_%L, ", cd->iff); if (cd->docstring != NULL) generateExplicitDocstring(cd->docstring, fp); else generateClassDocstring(pt, cd, fp); prcode(fp, ");\n" ); has_docstring = TRUE; } if (pluginPyQt5(pt)) { type_prefix = "pyqt5"; embedded = TRUE; } else if (pluginPyQt4(pt)) { type_prefix = "pyqt4"; embedded = TRUE; } else if (pluginPyQt3(pt)) { type_prefix = "pyqt3"; embedded = TRUE; } else { type_prefix = "sip"; embedded = FALSE; } prcode(fp, "\n" "\n" "%sClassTypeDef ", type_prefix); generateTypeDefName(cd->iff, fp); prcode(fp, " = {\n" "%s" " {\n" " %P,\n" " " , (embedded ? "{\n" : "") , cd->iff->api_range); generateTypeDefLink(pt, cd->iff, fp); prcode(fp, ",\n" " 0,\n" " "); sep = ""; if (isAbstractClass(cd)) { prcode(fp, "%sSIP_TYPE_ABSTRACT", sep); sep = "|"; } if (cd->subbase != NULL) { prcode(fp, "%sSIP_TYPE_SCC", sep); sep = "|"; } if (classHandlesNone(cd)) { prcode(fp, "%sSIP_TYPE_ALLOW_NONE", sep); sep = "|"; } if (hasNonlazyMethod(cd)) { prcode(fp, "%sSIP_TYPE_NONLAZY", sep); sep = "|"; } if (isCallSuperInitYes(mod)) { prcode(fp, "%sSIP_TYPE_SUPER_INIT", sep); sep = "|"; } if (cd->iff->type == namespace_iface) { prcode(fp, "%sSIP_TYPE_NAMESPACE", sep); sep = "|"; } else { prcode(fp, "%sSIP_TYPE_CLASS", sep); sep = "|"; } if (*sep == '\0') prcode(fp, "0"); prcode(fp, ",\n"); prcode(fp, " %n,\n" " {0}\n" " },\n" " {\n" , cd->iff->name); if (cd->real == NULL) prcode(fp, " %n,\n" , cd->pyname); else prcode(fp, " -1,\n" ); prcode(fp, " "); if (cd->real != NULL) generateEncodedType(mod, cd->real, 0, fp); else if (cd->ecd != NULL) generateEncodedType(mod, cd->ecd, 0, fp); else prcode(fp, "{0, 0, 1}"); prcode(fp, ",\n" ); if (nr_methods == 0) prcode(fp, " 0, 0,\n" ); else prcode(fp, " %d, methods_%L,\n" , nr_methods, cd->iff); if (nr_enums == 0) prcode(fp, " 0, 0,\n" ); else prcode(fp, " %d, enummembers_%L,\n" , nr_enums, cd->iff); if (nr_vars == 0) prcode(fp, " 0, 0,\n" ); else prcode(fp, " %d, variables_%L,\n" , nr_vars, cd->iff); prcode(fp, " {"); if (is_inst_class) prcode(fp, "typeInstances_%C, ", classFQCName(cd)); else prcode(fp, "0, "); if (is_inst_voidp) prcode(fp, "voidPtrInstances_%C, ", classFQCName(cd)); else prcode(fp, "0, "); if (is_inst_char) prcode(fp, "charInstances_%C, ", classFQCName(cd)); else prcode(fp, "0, "); if (is_inst_string) prcode(fp, "stringInstances_%C, ", classFQCName(cd)); else prcode(fp, "0, "); if (is_inst_int) prcode(fp, "intInstances_%C, ", classFQCName(cd)); else prcode(fp, "0, "); if (is_inst_long) prcode(fp, "longInstances_%C, ", classFQCName(cd)); else prcode(fp, "0, "); if (is_inst_ulong) prcode(fp, "unsignedLongInstances_%C, ", classFQCName(cd)); else prcode(fp, "0, "); if (is_inst_longlong) prcode(fp, "longLongInstances_%C, ", classFQCName(cd)); else prcode(fp,"0, "); if (is_inst_ulonglong) prcode(fp, "unsignedLongLongInstances_%C, ", classFQCName(cd)); else prcode(fp, "0, "); if (is_inst_double) prcode(fp, "doubleInstances_%C", classFQCName(cd)); else prcode(fp, "0"); prcode(fp,"},\n" " },\n" ); if (has_docstring) prcode(fp, " doc_%L,\n" , cd->iff); else prcode(fp, " 0,\n" ); if (cd->metatype != NULL) prcode(fp, " %n,\n" , cd->metatype); else prcode(fp, " -1,\n" ); if (cd->supertype != NULL) prcode(fp, " %n,\n" , cd->supertype); else prcode(fp, " -1,\n" ); if (cd->supers != NULL) prcode(fp, " supers_%C,\n" , classFQCName(cd)); else prcode(fp, " 0,\n" ); if (is_slots) prcode(fp, " slots_%L,\n" , cd->iff); else prcode(fp, " 0,\n" ); if (canCreate(cd)) prcode(fp, " init_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" " 0,\n" ); else prcode(fp, " release_%L,\n" " cast_%L,\n" , cd->iff , cd->iff); if (cd->iff->type == namespace_iface) { prcode(fp, " 0,\n" ); } else { if (cd->convtocode != NULL) prcode(fp, " convertTo_%L,\n" , cd->iff); else prcode(fp, " 0,\n" ); } 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" ); if (embedded) prcode(fp, "},\n" ); if (pluginPyQt3(pt)) { if (hasSigSlots(cd)) prcode(fp, " signals_%C\n" , classFQCName(cd)); else prcode(fp, " 0\n" ); } if (pluginPyQt4(pt) || pluginPyQt5(pt)) { if (isQObjectSubClass(cd) && !noPyQtQMetaObject(cd)) prcode(fp, " &%U::staticMetaObject,\n" , cd); else prcode(fp, " 0,\n" ); prcode(fp, " %u,\n" , cd->pyqt_flags); if (pluginPyQt5(pt)) { 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" ); } else { if (is_signals) prcode(fp, " signals_%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(moduleDef *mod, classDef *cd, FILE *fp) { 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" " %C *sipCpp = reinterpret_cast<%C *>(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, memberDef *md, 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, fp); } prcode(fp,")\", "); if (docstrings) { if (md->docstring != NULL) { generateExplicitDocstring(md->docstring, fp); } else { fprintf(fp, "\"\\1"); prScopedPythonName(fp, cd->ecd, cd->pyname->text); fprintf(fp, ".%s", md->pyname->text); prPythonSignature(pt, fp, &sig->pysig, FALSE, FALSE, FALSE, FALSE, TRUE); fprintf(fp, "\""); } 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; 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->o)) ++nrvirts; return nrvirts; } /* * Generate the try block for a call. */ static void generateTry(throwArgs *ta,FILE *fp) { /* * Generate the block if there was no throw specifier, or a non-empty * throw specifier. */ if (exceptions && (ta == NULL || ta->nrArgs > 0)) prcode(fp, " try\n" " {\n" ); } /* * Generate the catch blocks for a call. */ static void generateCatch(throwArgs *ta, signatureDef *sd, moduleDef *mod, FILE *fp, 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 (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. */ has_auto_docstring = FALSE; if (md->docstring != NULL || (docstrings && hasDocstring(pt, overs, md, cd->iff))) { prcode(fp, "PyDoc_STRVAR(doc_%L_%s, " , cd->iff, pname); if (md->docstring != NULL) { generateExplicitDocstring(md->docstring, fp); } else { generateDocstring(pt, overs, md, cd->pyname->text, cd->ecd, fp); has_auto_docstring = TRUE; } prcode(fp, ");\n" "\n" ); } if (!generating_c) prcode(fp, "extern \"C\" {static PyObject *meth_%L_%s(PyObject *, PyObject *%s);}\n" , cd->iff, pname, (noArgParser(md) || 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 || sipIsDerived((sipSimpleWrapper *)sipSelf));\n" ); } if (need_orig_self) { /* * This is similar to the above but for abstract methods. We * allow the (potential) recursion because it means that the * concrete implementation can be put in a mixin and it will * all work. */ prcode(fp, " PyObject *sipOrigSelf = sipSelf;\n" ); } } for (od = overs; od != NULL; od = od->next) { /* If we are handling one variant then we must handle them all. */ if (skipOverload(od, md, cd, ocd, FALSE)) continue; if (isPrivate(od)) continue; if (noArgParser(md)) { generateCppCodeBlock(od->methodcode, fp); break; } generateFunctionBody(od, cd, NULL, ocd, TRUE, mod, fp); } if (!noArgParser(md)) { prcode(fp, "\n" " /* Raise an exception if the arguments couldn't be parsed. */\n" " sipNoMethod(%s, %N, %N, ", (need_args ? "sipParseErr" : "NULL"), cd->pyname, md->pyname); if (has_auto_docstring) prcode(fp, "doc_%L_%s", cd->iff, pname); else prcode(fp, "NULL"); prcode(fp, ");\n" "\n" " return NULL;\n" ); } prcode(fp, "}\n" ); } } /* * Generate the function calls for a particular overload. */ static void generateFunctionBody(overDef *od, classDef *c_scope, mappedTypeDef *mt_scope, classDef *ocd, int deref, moduleDef *mod, FILE *fp) { int needSecCall; signatureDef saved; ifaceFileDef *o_scope; apiVersionRangeDef *avr; if (mt_scope != NULL) o_scope = mt_scope->iff; else if (ocd != NULL) o_scope = ocd->iff; else o_scope = NULL; if (o_scope != NULL) avr = od->api_range; else avr = NULL; if (avr != NULL) prcode(fp, "\n" " if (sipIsAPIEnabled(%N, %d, %d))\n" " {\n" , avr->api_name, avr->from, avr->to); else prcode(fp, "\n" " {\n" ); /* In case we have to fiddle with it. */ saved = od->pysig; if (isNumberSlot(od->common)) { /* * Number slots must have two arguments because we parse them slightly * differently. */ if (od->pysig.nrArgs == 1) { od->pysig.nrArgs = 2; od->pysig.args[1] = od->pysig.args[0]; /* Insert self in the right place. */ od->pysig.args[0].atype = class_type; od->pysig.args[0].name = NULL; od->pysig.args[0].argflags = ARG_IS_REF|ARG_IN; od->pysig.args[0].nrderefs = 0; od->pysig.args[0].defval = NULL; od->pysig.args[0].original_type = NULL; od->pysig.args[0].u.cd = ocd; } generateArgParser(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) { prcode(fp, " %s sipConvertFromEnum(%s,sipType_%C);\n" , prefix, vname, 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; } } /* * Return the owner of a method result. */ static const char *resultOwner(overDef *od) { if (isResultTransferredBack(od)) return "Py_None"; if (isResultTransferred(od)) return "sipSelf"; return "NULL"; } /* * Return the format string used by sipBuildResult() for a particular type. */ static const char *getBuildResultFormat(argDef *ad) { switch (ad->atype) { case fake_void_type: case mapped_type: case class_type: if (needNewInstance(ad)) return "N"; return "D"; case bool_type: case cbool_type: return "b"; case ascii_string_type: return (ad->nrderefs > (isOutArg(ad) ? 1 : 0)) ? "AA" : "aA"; case latin1_string_type: return (ad->nrderefs > (isOutArg(ad) ? 1 : 0)) ? "AL" : "aL"; case utf8_string_type: return (ad->nrderefs > (isOutArg(ad) ? 1 : 0)) ? "A8" : "a8"; case sstring_type: case ustring_type: case string_type: return (ad->nrderefs > (isOutArg(ad) ? 1 : 0)) ? "s" : "c"; case wstring_type: return (ad->nrderefs > (isOutArg(ad) ? 1 : 0)) ? "x" : "w"; case enum_type: return (ad->u.ed->fqcname != NULL) ? "F" : "e"; case 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"; } /* We should never get here. */ return ""; } /* * Return TRUE if an argument (or result) should be copied because it is a * const reference to a type. */ static int copyConstRefArg(argDef *ad) { if (!noCopy(ad) && (ad->atype == class_type || ad->atype == mapped_type) && ad->nrderefs == 0) { /* Make a copy if it is not a reference or it is a const reference. */ if (!isReference(ad) || isConstArg(ad)) { /* If it is a class then we must be able to copy it. */ if (ad->atype != class_type || !(cannotCopy(ad->u.cd) || isAbstractClass(ad->u.cd))) { return TRUE; } } } return FALSE; } /* * Generate a function call. */ static void generateFunctionCall(classDef *c_scope, mappedTypeDef *mt_scope, ifaceFileDef *o_scope, overDef *od, int deref, moduleDef *mod, FILE *fp) { int needsNew, error_flag, old_error_flag, newline, is_result, result_size, a, deltemps, 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); /* See if sipRes is needed. */ is_result = (!isInplaceNumberSlot(od->common) && !isInplaceSequenceSlot(od->common) && (res->atype != void_type || res->nrderefs != 0)); newline = FALSE; if (is_result) { prcode(fp, " "); generateNamedValueType(scope, res, "sipRes", fp); /* * The typical %MethodCode usually causes a compiler warning, so we * initialise the result in that case to try and suppress it. */ if (od->methodcode != NULL) { prcode(fp," = "); generateCastZero(res,fp); } prcode(fp,";\n" ); newline = TRUE; } result_size = -1; deltemps = TRUE; 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; } 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: 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: 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; } 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 (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; 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; } 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 (ad->nrderefs == 0 || (isOutArg(ad) && ad->nrderefs == 1)) fmt = "aA"; else fmt = "AA"; break; case latin1_string_type: if (ad->nrderefs == 0 || (isOutArg(ad) && ad->nrderefs == 1)) fmt = "aL"; else fmt = "AL"; break; case utf8_string_type: if (ad->nrderefs == 0 || (isOutArg(ad) && ad->nrderefs == 1)) fmt = "a8"; else fmt = "A8"; break; case sstring_type: case ustring_type: case string_type: if (ad->nrderefs == 0 || (isOutArg(ad) && ad->nrderefs == 1)) fmt = "c"; else if (isArray(ad)) fmt = "k"; else fmt = "s"; break; case wstring_type: if (ad->nrderefs == 0 || (isOutArg(ad) && ad->nrderefs == 1)) fmt = "w"; else if (isArray(ad)) fmt = "K"; else fmt = "x"; break; case enum_type: if (ad->u.ed->fqcname == NULL) fmt = "e"; else if (isConstrained(ad)) fmt = "XE"; else fmt = "E"; break; case bool_type: fmt = "b"; break; case cbool_type: fmt = "Xb"; break; case int_type: if (!isArraySize(ad)) fmt = "i"; break; case uint_type: if (!isArraySize(ad)) fmt = "u"; break; case cint_type: fmt = "Xi"; break; case 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; } /* * 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, TRUE, 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, TRUE, 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) 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, int timestamp) { FILE *fp = createFile(mod, fname, description, timestamp); 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, int timestamp) { FILE *fp; /* Create the file. */ if ((fp = fopen(fname, "w")) == NULL) fatal("Unable to create file \"%s\"\n",fname); /* The "stack" doesn't have to be very deep. */ previousLineNr = currentLineNr; currentLineNr = 1; previousFileName = currentFileName; currentFileName = fname; if (description != NULL) { int needComment; codeBlockList *cbl; /* Write the header. */ prcode(fp, "/*\n" " * %s\n" " *\n" " * Generated by SIP %s" , description , sipVersion); if (timestamp) { time_t now = time(NULL); prcode(fp, " on %s", ctime(&now)); } else { prcode(fp, "\n" ); } if (mod->copying != NULL) prcode(fp, " *\n" ); needComment = TRUE; 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," * "); } prcode(fp,"%c",*cp); if (*cp == '\n') needComment = TRUE; } } prcode(fp, " */\n" ); } return fp; } /* * Close a file and report any errors. */ static void closeFile(FILE *fp) { if (ferror(fp)) fatal("Error writing to \"%s\"\n",currentFileName); if (fclose(fp)) fatal("Error closing \"%s\"\n",currentFileName); currentLineNr = previousLineNr; currentFileName = previousFileName; } /* * Print formatted code. */ void prcode(FILE *fp, const char *fmt, ...) { char ch; va_list ap; prcode_last = fmt; va_start(ap,fmt); while ((ch = *fmt++) != '\0') if (ch == '%') { ch = *fmt++; switch (ch) { case 'c': { char c = (char)va_arg(ap,int); if (c == '\n') ++currentLineNr; fputc(c,fp); break; } case 's': { const char *cp = va_arg(ap,const char *); while (*cp != '\0') { if (*cp == '\n') ++currentLineNr; fputc(*cp,fp); ++cp; } break; } case 'l': fprintf(fp,"%ld",va_arg(ap,long)); break; case 'u': fprintf(fp,"%u",va_arg(ap,unsigned)); break; case 'd': fprintf(fp,"%d",va_arg(ap,int)); break; case 'g': fprintf(fp,"%g",va_arg(ap,double)); break; case 'x': fprintf(fp,"0x%08x",va_arg(ap,unsigned)); break; case '\0': fputc('%',fp); --fmt; break; case '\n': fputc('\n',fp); ++currentLineNr; break; case 'b': { argDef *ad, orig; ad = va_arg(ap,argDef *); orig = *ad; resetIsConstArg(ad); resetIsReference(ad); ad->nrderefs = 0; generateBaseType(NULL, ad, TRUE, fp); *ad = orig; break; } case 'M': prcode_xml = !prcode_xml; break; case 'A': { ifaceFileDef *scope = va_arg(ap, ifaceFileDef *); argDef *ad = va_arg(ap, argDef *); generateBaseType(scope, ad, TRUE, fp); break; } case '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 'B': generateBaseType(NULL, va_arg(ap,argDef *),TRUE, fp); break; case 'T': prTypeName(fp, va_arg(ap,argDef *)); break; case 'I': { int indent = va_arg(ap,int); while (indent-- > 0) fputc('\t',fp); break; } case 'N': { nameDef *nd = va_arg(ap,nameDef *); prCachedName(fp, nd, "sipName_"); break; } case 'n': { nameDef *nd = va_arg(ap,nameDef *); prCachedName(fp, nd, "sipNameNr_"); break; } case 'E': { enumDef *ed = va_arg(ap,enumDef *); if (ed->fqcname == NULL || isProtectedEnum(ed)) fprintf(fp,"int"); else prScopedName(fp,ed->fqcname,"::"); break; } case 'F': prScopedName(fp,va_arg(ap,scopedNameDef *),""); break; case 'C': prScopedName(fp,va_arg(ap,scopedNameDef *),"_"); break; case 'L': { ifaceFileDef *iff = va_arg(ap, ifaceFileDef *); prScopedName(fp, iff->fqcname, "_"); if (iff->api_range != NULL) fprintf(fp, "_%d", iff->api_range->index); break; } case 'P': { apiVersionRangeDef *avr = va_arg(ap, apiVersionRangeDef *); fprintf(fp, "%d", (avr != NULL ? avr->index : -1)); break; } case 'S': prScopedName(fp, va_arg(ap, scopedNameDef *), "::"); break; case 'U': { classDef *cd = va_arg(ap, classDef *); if (generating_c) fprintf(fp,"struct "); prScopedClassName(fp, cd->iff, cd); break; } case 'V': { ifaceFileDef *scope = va_arg(ap, ifaceFileDef *); classDef *cd = va_arg(ap, classDef *); if (generating_c) fprintf(fp,"struct "); prScopedClassName(fp, scope, cd); break; } case 'O': prOverloadName(fp, va_arg(ap, overDef *)); break; case 'X': generateThrowSpecifier(va_arg(ap,throwArgs *),fp); break; default: fputc(ch,fp); } } else if (ch == '\n') { fputc('\n',fp); ++currentLineNr; } else fputc(ch,fp); va_end(ap); } /* * Generate the symbolic name of a cached name. */ static void prCachedName(FILE *fp, nameDef *nd, const char *prefix) { prcode(fp, "%s", prefix); /* * If the name seems to be a template then just use the offset to ensure * that it is unique. */ if (strchr(nd->text, '<') != NULL) prcode(fp, "%d", nd->offset); else { const char *cp; /* Handle C++ and Python scopes. */ for (cp = nd->text; *cp != '\0'; ++cp) { char ch = *cp; if (ch == ':' || ch == '.') ch = '_'; prcode(fp, "%c", ch); } } } /* * Generate the C++ name of an overloaded function. */ void prOverloadName(FILE *fp, overDef *od) { char *pt1, *pt2; pt1 = "operator"; switch (od->common->slot) { case add_slot: pt2 = "+"; break; case sub_slot: pt2 = "-"; break; case mul_slot: pt2 = "*"; break; case div_slot: case truediv_slot: pt2 = "/"; break; case mod_slot: pt2 = "%"; break; case and_slot: pt2 = "&"; break; case or_slot: pt2 = "|"; break; case xor_slot: pt2 = "^"; break; case lshift_slot: pt2 = "<<"; break; case rshift_slot: pt2 = ">>"; break; case iadd_slot: pt2 = "+="; break; case isub_slot: pt2 = "-="; break; case imul_slot: pt2 = "*="; break; case idiv_slot: case itruediv_slot: pt2 = "/="; break; case imod_slot: pt2 = "%="; break; case iand_slot: pt2 = "&="; break; case ior_slot: pt2 = "|="; break; case ixor_slot: pt2 = "^="; break; case ilshift_slot: pt2 = "<<="; break; case irshift_slot: pt2 = ">>="; break; case invert_slot: pt2 = "~"; break; case call_slot: pt2 = "()"; break; case getitem_slot: pt2 = "[]"; break; case lt_slot: pt2 = "<"; break; case le_slot: pt2 = "<="; break; case eq_slot: pt2 = "=="; break; case ne_slot: pt2 = "!="; break; case gt_slot: pt2 = ">"; break; case ge_slot: pt2 = ">="; break; default: pt1 = ""; pt2 = od->cppname; } fprintf(fp, "%s%s", pt1, pt2); } /* * Generate a scoped name with the given separator string. */ static void prScopedName(FILE *fp,scopedNameDef *snd,char *sep) { while (snd != NULL) { fprintf(fp,"%s",snd->name); if ((snd = snd->next) != NULL) fprintf(fp,"%s",sep); } } /* * Generate a scoped class name. */ static void prScopedClassName(FILE *fp, ifaceFileDef *scope, classDef *cd) { /* Protected classes have to be explicitly scoped. */ if (isProtectedClass(cd)) { /* This should never happen. */ if (scope == NULL) scope = cd->iff; prcode(fp, "sip%C::sip%s", scope->fqcname, classBaseName(cd)); } else { scopedNameDef *snd = classFQCName(cd); while (snd != NULL) { fprintf(fp,"%s",snd->name); if ((snd = snd->next) != NULL) fprintf(fp, "::"); } } } /* * Generate a type name to be used as part of an identifier name. */ static void prTypeName(FILE *fp, argDef *ad) { scopedNameDef *snd; switch (ad->atype) { case struct_type: snd = ad->u.sname; break; case defined_type: snd = ad->u.snd; break; case enum_type: snd = ad->u.ed->fqcname; break; case mapped_type: snd = ad->u.mtd->iff->fqcname; break; case class_type: snd = classFQCName(ad->u.cd); break; default: /* This should never happen. */ snd = NULL; } if (snd != NULL) prcode(fp, "%C", snd); } /* * Return TRUE if handwritten code uses the error flag. */ static int needErrorFlag(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(argType atype) { char encoding; switch (atype) { case ascii_string_type: encoding = 'A'; break; case latin1_string_type: encoding = 'L'; break; case utf8_string_type: encoding = '8'; break; default: encoding = 'N'; } return encoding; } /* * Return TRUE if a docstring can be automatically generated for a function * overload. */ static int overloadHasDocstring(sipSpec *pt, overDef *od, memberDef *md) { if (isPrivate(od) || isSignal(od)) return FALSE; if (od->common != md) return FALSE; /* If it is versioned then make sure it is the default API. */ return isDefaultAPI(pt, od->api_range); } /* * Return TRUE if a docstring can be automatically generated for a function. */ static int hasDocstring(sipSpec *pt, overDef *overs, memberDef *md, ifaceFileDef *scope) { overDef *od; if (noArgParser(md)) return FALSE; if (scope != NULL && !isDefaultAPI(pt, scope->api_range)) return FALSE; for (od = overs; od != NULL; od = od->next) if (overloadHasDocstring(pt, od, md)) return TRUE; return FALSE; } /* * Generate the docstring for a function or method. */ static void generateDocstring(sipSpec *pt, overDef *overs, memberDef *md, const char *scope_name, classDef *scope_scope, FILE *fp) { const char *sep = NULL; overDef *od; for (od = overs; od != NULL; od = od->next) { int need_sec; if (!overloadHasDocstring(pt, od, md)) continue; if (sep == NULL) { prcode(fp, "\""); sep = "\\n\"\n \""; } else { prcode(fp, "%s", sep); } prScopedPythonName(fp, scope_scope, scope_name); if (scope_name != NULL) prcode(fp, "."); prcode(fp, "%s", md->pyname->text); need_sec = prPythonSignature(pt, fp, &od->pysig, FALSE, TRUE, TRUE, TRUE, FALSE); if (need_sec) { prcode(fp, "%s", sep); prScopedPythonName(fp, scope_scope, scope_name); if (scope_name != NULL) prcode(fp, "."); prcode(fp, "%s", md->pyname->text); prPythonSignature(pt, fp, &od->pysig, TRUE, TRUE, TRUE, TRUE, FALSE); } } if (sep != NULL) prcode(fp, "\""); } /* * Return TRUE if a docstring can be automatically generated for a class * overload. */ static int overloadHasClassDocstring(sipSpec *pt, ctorDef *ct) { if (isPrivateCtor(ct)) return FALSE; /* If it is versioned then make sure it is the default API. */ return isDefaultAPI(pt, ct->api_range); } /* * Return TRUE if a docstring can be automatically generated for a class. */ static int hasClassDocstring(sipSpec *pt, classDef *cd) { ctorDef *ct; if (!canCreate(cd)) return FALSE; if (!isDefaultAPI(pt, cd->iff->api_range)) return FALSE; for (ct = cd->ctors; ct != NULL; ct = ct->next) if (overloadHasClassDocstring(pt, ct)) return TRUE; return FALSE; } /* * Generate the docstring for a class. */ static void generateClassDocstring(sipSpec *pt, classDef *cd, FILE *fp) { const char *sep = NULL; ctorDef *ct; for (ct = cd->ctors; ct != NULL; ct = ct->next) { int need_sec; if (!overloadHasClassDocstring(pt, ct)) continue; if (sep == NULL) { fprintf(fp, "\"\\1"); sep = "\\n\"\n \""; } else { fprintf(fp, "%s", sep); } prScopedPythonName(fp, cd->ecd, cd->pyname->text); need_sec = prPythonSignature(pt, fp, &ct->pysig, FALSE, TRUE, TRUE, TRUE, FALSE); ++currentLineNr; if (need_sec) { fprintf(fp, "%s", sep); prScopedPythonName(fp, cd->ecd, cd->pyname->text); prPythonSignature(pt, fp, &ct->pysig, TRUE, TRUE, TRUE, TRUE, FALSE); ++currentLineNr; } } if (sep != NULL) fprintf(fp, "\""); } /* * Returns TRUE if the given API version corresponds to the default. */ static int isDefaultAPI(sipSpec *pt, apiVersionRangeDef *avd) { int def_api; /* Handle the trivial case. */ if (avd == NULL) return TRUE; def_api = findAPI(pt, avd->api_name->text)->from; if (avd->from > 0 && avd->from > def_api) return FALSE; if (avd->to > 0 && avd->to <= def_api) return FALSE; return TRUE; } /* * Generate an explicit docstring. */ static void generateExplicitDocstring(codeBlockList *cbl, FILE *fp) { const char *sep = NULL; while (cbl != NULL) { const char *cp; if (sep == NULL) { prcode(fp, "\""); sep = "\\n\"\n \""; } else { prcode(fp, "%s", sep); } for (cp = cbl->block->frag; *cp != '\0'; ++cp) { if (*cp == '\n') { /* Ignore if this is the last character of the fragment. */ if (cp[1] != '\0') prcode(fp, "%s", sep); } else { if (*cp == '\\' || *cp == '\"') prcode(fp, "\\"); prcode(fp, "%c", *cp); } } cbl = cbl->next; } if (sep != NULL) prcode(fp, "\""); } /* * 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); generateExplicitDocstring(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 " : "")); } sip-4.15.5/sipgen/heap.c0000644000076500000240000000417512261240674015041 0ustar philstaff00000000000000/* * Wrappers around standard functions that use the heap. * * Copyright (c) 2014 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.15.5/sipgen/lexer.c0000644000076500000240000041267312310606636015250 0ustar philstaff00000000000000#line 2 "/Users/phil/hg/sip/sip-4.15.5/sipgen/lexer.c" #line 4 "/Users/phil/hg/sip/sip-4.15.5/sipgen/lexer.c" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #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 159 #define YY_END_OF_BUFFER 160 /* 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[1158] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 158, 101, 104, 158, 158, 158, 158, 158, 106, 106, 158, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 158, 101, 158, 157, 156, 157, 157, 116, 114, 116, 103, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 101, 158, 102, 101, 158, 0, 111, 0, 112, 0, 106, 0, 110, 107, 110, 113, 105, 107, 0, 107, 106, 0, 60, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 109, 109, 109, 109, 109, 109, 109, 82, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 0, 0, 0, 0, 0, 0, 107, 79, 110, 107, 105, 107, 0, 107, 108, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 40, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 109, 109, 109, 109, 109, 81, 109, 109, 109, 109, 109, 109, 109, 90, 109, 109, 109, 109, 109, 0, 0, 107, 53, 109, 109, 109, 38, 36, 109, 109, 109, 46, 109, 109, 109, 41, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 51, 109, 109, 109, 44, 109, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 10, 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, 155, 109, 99, 109, 109, 109, 109, 109, 109, 109, 86, 109, 109, 109, 109, 109, 93, 109, 109, 11, 109, 109, 109, 109, 109, 109, 109, 25, 49, 109, 109, 52, 42, 109, 109, 109, 109, 109, 39, 109, 109, 33, 109, 109, 109, 57, 109, 109, 109, 109, 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, 100, 109, 109, 109, 109, 109, 109, 109, 109, 88, 109, 109, 109, 109, 109, 109, 35, 109, 109, 109, 109, 109, 109, 109, 43, 109, 109, 109, 109, 109, 27, 109, 47, 50, 26, 109, 109, 109, 109, 109, 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, 109, 109, 109, 80, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 34, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 29, 109, 30, 109, 54, 109, 45, 37, 0, 0, 0, 0, 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, 0, 0, 19, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 98, 32, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 71, 109, 58, 109, 56, 109, 59, 48, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 117, 0, 0, 0, 0, 122, 13, 0, 0, 0, 152, 16, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 0, 109, 109, 109, 109, 84, 85, 87, 109, 109, 109, 109, 31, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 55, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 24, 132, 0, 129, 0, 0, 0, 109, 109, 109, 109, 109, 91, 92, 109, 109, 109, 109, 65, 64, 109, 109, 109, 68, 109, 109, 70, 109, 109, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 147, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 146, 0, 0, 0, 0, 109, 109, 109, 109, 109, 109, 72, 109, 109, 109, 67, 63, 78, 109, 109, 109, 109, 77, 151, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 133, 131, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 109, 109, 109, 109, 109, 109, 69, 109, 62, 109, 109, 75, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 149, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 109, 109, 109, 109, 109, 109, 73, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 109, 109, 109, 109, 109, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 0, 109, 109, 109, 109, 89, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 0, 0, 0, 0, 0, 124, 0, 0, 0, 109, 96, 109, 109, 109, 137, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 7, 8, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 109, 109, 109, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 128, 0, 123, 0, 0, 0, 0, 0, 109, 109, 83, 109, 0, 0, 141, 0, 0, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 0, 109, 109, 94, 0, 0, 0, 0, 5, 0, 0, 0, 121, 126, 0, 0, 0, 134, 0, 109, 109, 142, 139, 0, 138, 118, 0, 0, 0, 0, 130, 154, 109, 109, 140, 0, 0, 0, 0, 109, 109, 120, 0, 0, 125, 95, 109, 6, 127, 109, 109, 109, 109, 97, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 5, 1, 1, 6, 1, 7, 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, 1, 1, 1, 44, 1, 45, 46, 47, 48, 49, 50, 51, 52, 53, 28, 54, 55, 56, 57, 58, 59, 28, 60, 61, 62, 63, 64, 65, 66, 67, 28, 1, 68, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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[69] = { 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, 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[1166] = { 0, 0, 67, 2703, 68, 69, 72, 74, 74, 2697, 79, 2704, 2707, 2707, 2707, 81, 85, 78, 86, 93, 126, 2637, 2685, 92, 102, 133, 139, 96, 144, 147, 154, 158, 166, 170, 173, 181, 194, 203, 212, 217, 220, 223, 2633, 111, 262, 2707, 2707, 124, 2678, 2707, 2707, 2685, 2707, 230, 233, 254, 290, 238, 294, 298, 302, 305, 308, 311, 314, 318, 350, 357, 324, 365, 167, 2676, 2707, 195, 2675, 115, 2707, 197, 2707, 62, 2630, 176, 370, 378, 198, 2707, 0, 410, 404, 2707, 2707, 0, 2707, 374, 384, 417, 422, 425, 428, 431, 434, 437, 444, 449, 454, 457, 465, 468, 472, 475, 480, 483, 489, 492, 498, 504, 507, 518, 522, 527, 532, 538, 541, 545, 2707, 247, 0, 313, 2669, 65, 190, 203, 210, 113, 284, 2641, 346, 2634, 507, 2647, 2642, 174, 2633, 2636, 327, 2666, 2630, 2707, 556, 559, 562, 568, 575, 578, 587, 590, 593, 596, 600, 606, 614, 617, 621, 627, 630, 638, 642, 654, 645, 349, 2664, 2619, 366, 2662, 205, 657, 207, 671, 440, 0, 675, 74, 449, 0, 697, 701, 704, 657, 707, 719, 722, 725, 728, 731, 737, 740, 743, 746, 750, 756, 760, 763, 775, 778, 782, 788, 791, 794, 797, 800, 805, 814, 808, 819, 822, 828, 2657, 2635, 2619, 139, 2622, 589, 2629, 2631, 2629, 637, 2631, 2618, 338, 2612, 2707, 2614, 776, 2625, 155, 2609, 2622, 2607, 2621, 344, 2606, 464, 2613, 2603, 2608, 2604, 2609, 2601, 2612, 831, 834, 852, 855, 862, 865, 872, 875, 881, 885, 888, 891, 899, 902, 905, 910, 913, 916, 929, 933, 2611, 937, 943, 956, 962, 965, 969, 976, 986, 994, 997, 1001, 1004, 1007, 1012, 1015, 1018, 1021, 1024, 1027, 1030, 1033, 1036, 1039, 1050, 1053, 1061, 1077, 1080, 1083, 1087, 1090, 1100, 1103, 1106, 2707, 2609, 2599, 2607, 2606, 2606, 2594, 347, 2585, 2606, 2589, 2707, 2600, 2590, 2587, 2584, 2600, 2589, 2583, 2622, 2583, 2585, 2577, 2576, 2588, 2587, 2576, 2582, 2570, 2579, 2577, 2568, 2578, 2566, 117, 2568, 2565, 2605, 2575, 2574, 2560, 2559, 2707, 1109, 1112, 1115, 1124, 1130, 1134, 1137, 1140, 1143, 1147, 1157, 1160, 1164, 1168, 1171, 1174, 1178, 1184, 2707, 1193, 1197, 1213, 1217, 1226, 1229, 1235, 1238, 1241, 1253, 1260, 1263, 1266, 1269, 1272, 1275, 1278, 1282, 1285, 1291, 1296, 1299, 1302, 1305, 1308, 1318, 1326, 1329, 1338, 1343, 2559, 2586, 2556, 2562, 2553, 2557, 2556, 2564, 2559, 2548, 2548, 2550, 2548, 2562, 2543, 2550, 2555, 2558, 2544, 2541, 2537, 2546, 2553, 2540, 2546, 2546, 2536, 2538, 2534, 2536, 2540, 2536, 2562, 2530, 2519, 2536, 2535, 2525, 2527, 517, 256, 2518, 1346, 1349, 1352, 1356, 1359, 1364, 1367, 1376, 1379, 1383, 1386, 1389, 1392, 1395, 1402, 1405, 1413, 1416, 1427, 1419, 1453, 1456, 1459, 1462, 1465, 1469, 1480, 1483, 1486, 1489, 1492, 1495, 1498, 1501, 1504, 1507, 1514, 1517, 1520, 1524, 2519, 2512, 1504, 2529, 2522, 2515, 2520, 2514, 2516, 2517, 2511, 2508, 2507, 2521, 2507, 2513, 2520, 2500, 2515, 2500, 2513, 2515, 2502, 2497, 2504, 2508, 2507, 2505, 2496, 2503, 2493, 2493, 2492, 2495, 2485, 2484, 2501, 2472, 2466, 2460, 2468, 2458, 2457, 2469, 1534, 1540, 1545, 1548, 1558, 1564, 1567, 1576, 1570, 1579, 1582, 1585, 1588, 1596, 1599, 1605, 1610, 1616, 1625, 1640, 1643, 1646, 1651, 1619, 1655, 1659, 1664, 1667, 1670, 1673, 1682, 1685, 1690, 1693, 1699, 1702, 1705, 1709, 1712, 2493, 2481, 2447, 2457, 2458, 2457, 2445, 2459, 2453, 2448, 2446, 2436, 2446, 2434, 2442, 2441, 2444, 2430, 2442, 2429, 2429, 2438, 2437, 2707, 2436, 2429, 2430, 2413, 2406, 2415, 2431, 541, 2396, 2420, 2364, 2707, 2370, 2353, 2362, 2350, 2352, 2336, 2327, 2332, 2327, 2300, 2282, 2286, 1715, 1721, 1724, 1731, 1737, 1742, 1745, 1748, 1751, 1757, 1760, 1765, 1769, 1775, 1783, 1780, 1802, 1805, 1812, 1816, 1819, 1822, 1831, 1834, 1844, 1837, 1851, 1854, 1857, 1862, 1865, 1870, 1873, 2278, 2278, 2272, 2275, 2269, 2262, 2230, 2207, 2707, 2205, 2215, 320, 2707, 1867, 2204, 2198, 2207, 2707, 2707, 2205, 2228, 2181, 2707, 2707, 2168, 2164, 2707, 2156, 2123, 2131, 2129, 2133, 2121, 2116, 2113, 2099, 2107, 2100, 2074, 2085, 2707, 2083, 2081, 2063, 2061, 2037, 557, 1878, 1881, 1886, 1895, 1898, 1902, 1905, 1908, 1919, 1922, 1929, 1925, 1932, 1935, 1938, 1941, 1947, 1957, 1960, 1963, 1974, 1977, 1981, 1986, 1989, 1992, 1999, 2004, 2050, 2037, 2038, 2027, 2031, 2058, 2014, 2026, 2020, 2023, 2006, 2006, 2005, 1993, 2000, 1972, 1963, 1951, 611, 1945, 1925, 1921, 1905, 1945, 2707, 1904, 1914, 1908, 1884, 1902, 1878, 1863, 1870, 1860, 1847, 2707, 1853, 2707, 2707, 1852, 2707, 1870, 1835, 1812, 2007, 2010, 2014, 2017, 2020, 2025, 2028, 2031, 2034, 2040, 2043, 2046, 2060, 2069, 2072, 2078, 2083, 2089, 2092, 2095, 2102, 2105, 2108, 1811, 1810, 1805, 1821, 1819, 1779, 1778, 1802, 1790, 1750, 1752, 385, 1761, 1760, 1740, 1742, 2707, 2707, 1741, 1749, 1737, 1737, 1735, 1722, 1708, 1703, 1698, 1697, 1693, 1683, 1682, 2707, 1685, 1654, 1688, 2707, 1640, 1635, 1629, 1628, 2111, 2115, 2123, 2126, 2130, 2134, 2137, 2140, 2143, 2151, 2154, 2159, 2167, 2172, 2180, 2183, 2186, 2189, 2707, 2707, 1610, 1598, 1587, 1586, 1628, 1581, 1585, 1591, 1579, 1563, 1553, 1544, 1546, 1540, 1525, 1526, 1523, 1509, 1516, 1543, 1493, 1502, 2707, 2707, 2707, 1500, 1498, 2707, 1488, 1489, 1432, 1469, 1440, 1439, 1426, 2195, 2198, 2203, 2206, 2211, 2214, 2217, 2220, 2223, 2226, 2230, 2233, 2240, 1442, 1411, 1407, 1396, 1389, 1400, 1397, 1395, 1405, 1388, 1363, 1358, 1362, 1323, 1324, 2707, 1334, 1317, 2707, 1296, 1295, 1298, 1285, 1281, 1282, 1272, 1279, 1268, 1269, 1271, 1246, 2246, 2258, 2261, 2265, 2268, 2272, 2275, 2279, 2282, 1243, 1250, 1243, 1207, 1218, 1213, 1199, 1230, 1190, 1236, 1197, 1185, 1183, 1168, 1171, 1172, 1199, 1170, 1158, 2707, 1194, 1149, 1143, 1157, 1152, 1151, 1131, 1140, 1142, 2286, 2289, 2292, 2295, 2298, 2305, 2314, 1117, 1115, 1113, 1120, 1089, 1085, 1078, 1073, 1071, 1055, 1089, 1054, 1048, 1028, 1018, 1023, 1023, 1031, 1021, 1018, 1023, 1025, 1006, 2707, 1009, 1009, 994, 978, 2317, 2320, 2326, 2333, 2338, 2341, 973, 952, 941, 938, 946, 932, 942, 937, 935, 935, 914, 914, 913, 914, 902, 936, 906, 2707, 930, 891, 889, 874, 882, 2707, 884, 911, 863, 2344, 2347, 2351, 2354, 2357, 2707, 889, 888, 858, 831, 870, 2707, 819, 860, 811, 823, 811, 2707, 2707, 811, 801, 806, 794, 802, 2707, 796, 757, 773, 724, 733, 2362, 2365, 2375, 2380, 721, 720, 717, 745, 703, 692, 688, 668, 679, 700, 2707, 674, 2707, 660, 2707, 646, 645, 642, 647, 41, 2383, 2386, 2389, 2392, 64, 96, 2707, 133, 150, 173, 190, 257, 2707, 232, 256, 264, 287, 345, 332, 425, 426, 2395, 2405, 2408, 441, 449, 466, 474, 2707, 477, 490, 523, 2707, 2707, 564, 537, 547, 2707, 555, 2414, 2418, 2707, 2707, 567, 2707, 2707, 573, 568, 579, 613, 2707, 2707, 2421, 2425, 2707, 615, 629, 627, 629, 2431, 2435, 2707, 626, 643, 2707, 2442, 2446, 2707, 2707, 2452, 2456, 2459, 2462, 2469, 2707, 2522, 2526, 2530, 2534, 2536, 2538, 2542, 689 } ; static yyconst flex_int16_t yy_def[1166] = { 0, 1157, 1, 1158, 1158, 1159, 1159, 1, 7, 1, 1, 1157, 1157, 1157, 1157, 1160, 1161, 1157, 1162, 1157, 1157, 20, 1157, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1157, 44, 1157, 1157, 44, 1160, 1157, 1161, 1157, 1157, 20, 1162, 1162, 1162, 1162, 1157, 1164, 1157, 1157, 1157, 1157, 1165, 1157, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1157, 1157, 44, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1157, 44, 1157, 1157, 44, 1157, 1157, 1162, 1162, 1162, 1164, 1157, 1157, 1157, 1165, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1157, 1162, 1162, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1157, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1163, 1163, 1163, 1163, 1163, 1163, 1163, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1163, 1163, 1163, 1163, 1163, 1163, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1163, 1163, 1163, 1163, 1163, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1163, 1163, 1163, 1163, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1163, 1163, 1163, 1163, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1163, 1163, 1163, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1163, 1163, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1163, 1163, 1157, 1157, 1157, 1157, 1157, 1163, 1163, 1157, 1157, 1157, 1157, 1163, 1163, 1157, 1157, 1163, 1163, 1163, 1163, 1163, 0, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157 } ; static yyconst flex_int16_t yy_nxt[2776] = { 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, 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, 175, 175, 51, 71, 73, 51, 52, 76, 74, 76, 72, 78, 182, 182, 79, 78, 80, 80, 220, 1103, 53, 81, 82, 81, 83, 83, 85, 81, 84, 81, 86, 81, 84, 81, 54, 1107, 125, 81, 84, 81, 126, 76, 55, 76, 56, 57, 221, 58, 59, 144, 60, 61, 62, 145, 63, 64, 228, 65, 66, 67, 68, 69, 87, 94, 80, 80, 429, 1108, 81, 84, 81, 88, 89, 430, 81, 84, 81, 97, 90, 81, 84, 81, 81, 84, 81, 229, 307, 90, 96, 81, 84, 81, 169, 81, 84, 81, 170, 308, 88, 89, 95, 81, 84, 81, 90, 81, 84, 81, 81, 84, 81, 81, 90, 81, 1109, 91, 81, 84, 81, 98, 172, 1110, 99, 78, 173, 100, 104, 78, 101, 81, 84, 81, 329, 81, 102, 81, 105, 330, 81, 84, 81, 108, 81, 103, 81, 1111, 106, 81, 84, 81, 244, 107, 81, 84, 81, 81, 84, 81, 81, 84, 81, 1112, 222, 109, 245, 81, 84, 81, 81, 84, 81, 223, 125, 81, 84, 81, 126, 110, 112, 113, 111, 114, 226, 224, 116, 269, 227, 117, 115, 81, 84, 81, 225, 123, 225, 118, 121, 120, 148, 519, 1113, 122, 119, 127, 128, 129, 130, 131, 132, 133, 152, 134, 520, 1114, 135, 136, 149, 137, 138, 101, 139, 140, 141, 142, 143, 81, 84, 81, 1115, 81, 84, 81, 150, 81, 84, 81, 1116, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 144, 81, 84, 81, 145, 230, 151, 81, 84, 81, 104, 231, 232, 98, 727, 1117, 99, 216, 154, 100, 105, 155, 169, 153, 157, 156, 170, 159, 728, 321, 106, 217, 158, 81, 84, 81, 1118, 107, 162, 172, 81, 84, 81, 173, 160, 161, 322, 218, 81, 84, 81, 1119, 120, 81, 176, 81, 167, 81, 84, 81, 335, 81, 234, 81, 83, 83, 235, 81, 84, 81, 163, 177, 178, 112, 164, 236, 114, 116, 336, 402, 117, 165, 403, 115, 184, 168, 181, 181, 118, 121, 182, 182, 853, 854, 122, 166, 180, 180, 177, 178, 81, 84, 81, 88, 89, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 185, 81, 186, 81, 84, 81, 88, 89, 81, 84, 81, 182, 182, 81, 84, 81, 81, 84, 81, 89, 188, 1120, 1121, 189, 81, 84, 81, 81, 84, 81, 187, 81, 84, 81, 81, 84, 81, 1124, 190, 81, 84, 81, 81, 84, 81, 1125, 89, 191, 81, 84, 81, 81, 84, 81, 192, 193, 194, 81, 84, 81, 338, 1126, 195, 81, 84, 81, 81, 84, 81, 339, 1127, 199, 197, 1128, 196, 198, 202, 81, 84, 81, 200, 81, 84, 81, 517, 201, 81, 84, 81, 518, 204, 81, 84, 81, 203, 1129, 206, 81, 84, 81, 81, 84, 81, 205, 81, 84, 81, 238, 672, 239, 208, 207, 240, 673, 241, 81, 84, 81, 81, 84, 81, 81, 84, 81, 759, 209, 760, 81, 84, 81, 1130, 1131, 210, 211, 81, 84, 81, 81, 84, 81, 212, 214, 1132, 1133, 215, 213, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 249, 81, 84, 81, 1134, 1137, 251, 81, 84, 81, 1138, 250, 252, 1139, 253, 81, 84, 81, 81, 84, 81, 802, 81, 84, 81, 803, 1140, 254, 81, 84, 81, 81, 84, 81, 310, 311, 258, 312, 255, 81, 84, 81, 257, 81, 84, 81, 81, 84, 81, 256, 1141, 259, 199, 1144, 261, 81, 84, 81, 81, 84, 81, 175, 175, 1145, 1146, 260, 262, 1147, 88, 89, 264, 181, 270, 316, 81, 271, 271, 1150, 263, 180, 180, 1151, 183, 265, 1102, 317, 88, 89, 318, 1101, 266, 1100, 267, 1099, 268, 88, 89, 1098, 81, 84, 81, 276, 81, 84, 81, 81, 84, 81, 81, 84, 81, 1097, 1096, 88, 89, 272, 273, 1095, 1094, 274, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 1093, 1092, 275, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 1091, 81, 84, 81, 1090, 1089, 277, 81, 84, 81, 280, 81, 84, 81, 81, 84, 81, 1088, 1087, 278, 1082, 1081, 279, 281, 284, 282, 81, 84, 81, 81, 84, 81, 1080, 81, 84, 81, 285, 283, 286, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 1079, 287, 81, 84, 81, 81, 84, 81, 325, 288, 289, 81, 84, 81, 326, 290, 81, 84, 81, 81, 84, 81, 327, 291, 292, 81, 84, 81, 81, 84, 81, 81, 84, 81, 1078, 293, 1077, 1076, 294, 298, 1075, 296, 295, 297, 1074, 1073, 300, 1072, 299, 81, 84, 81, 81, 84, 81, 302, 1071, 1070, 303, 81, 84, 81, 81, 84, 81, 1069, 301, 1068, 348, 81, 84, 81, 81, 84, 81, 1067, 1066, 347, 81, 84, 81, 349, 81, 84, 81, 81, 84, 81, 81, 84, 81, 1065, 351, 1064, 1063, 350, 81, 84, 81, 81, 84, 81, 81, 84, 81, 1058, 352, 81, 84, 81, 81, 84, 81, 81, 84, 81, 1057, 354, 1056, 355, 1055, 1054, 356, 1053, 1052, 353, 81, 84, 81, 357, 81, 84, 81, 358, 81, 1051, 81, 271, 271, 1050, 81, 1049, 81, 271, 271, 359, 1048, 361, 1047, 1046, 362, 178, 360, 81, 84, 81, 1045, 1044, 363, 81, 84, 81, 81, 84, 81, 1043, 81, 84, 81, 1042, 1041, 366, 368, 81, 84, 81, 1040, 1039, 178, 364, 1038, 1037, 367, 81, 84, 81, 1036, 369, 370, 371, 372, 81, 84, 81, 81, 84, 81, 1035, 81, 84, 81, 81, 84, 81, 81, 84, 81, 1034, 1028, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 1027, 373, 375, 1026, 1025, 374, 376, 377, 81, 84, 81, 81, 84, 81, 1024, 380, 1023, 1022, 381, 81, 84, 81, 1021, 378, 1020, 382, 1019, 1018, 379, 1017, 385, 1016, 383, 1015, 386, 81, 84, 81, 81, 84, 81, 81, 84, 81, 384, 81, 84, 81, 81, 84, 81, 1014, 388, 1013, 389, 1012, 1011, 387, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 1010, 1009, 390, 1008, 1007, 392, 81, 84, 81, 1006, 1005, 393, 81, 84, 81, 391, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 438, 81, 84, 81, 1004, 394, 1003, 1002, 395, 995, 440, 81, 84, 81, 81, 84, 81, 439, 81, 84, 81, 442, 81, 84, 81, 81, 84, 81, 81, 84, 81, 994, 81, 84, 81, 441, 993, 443, 81, 84, 81, 992, 445, 991, 990, 444, 989, 81, 84, 81, 379, 81, 84, 81, 988, 449, 987, 446, 986, 386, 985, 984, 447, 983, 392, 451, 453, 81, 84, 81, 448, 81, 84, 81, 450, 982, 454, 981, 980, 452, 81, 84, 81, 81, 84, 81, 455, 979, 978, 81, 84, 81, 81, 84, 81, 81, 84, 81, 977, 976, 457, 456, 975, 459, 974, 973, 460, 81, 84, 81, 972, 971, 458, 461, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 970, 81, 84, 81, 81, 84, 81, 969, 968, 462, 81, 84, 81, 960, 463, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 959, 958, 467, 957, 956, 464, 468, 81, 84, 81, 955, 465, 954, 953, 466, 81, 84, 81, 81, 84, 81, 470, 952, 469, 951, 950, 471, 81, 84, 81, 473, 949, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 472, 81, 84, 81, 81, 84, 81, 948, 474, 81, 84, 81, 81, 84, 81, 947, 476, 946, 945, 475, 477, 81, 84, 81, 81, 84, 81, 522, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 944, 524, 527, 523, 81, 84, 81, 81, 84, 81, 943, 525, 942, 535, 526, 81, 84, 81, 81, 84, 81, 81, 84, 81, 941, 530, 529, 528, 545, 81, 84, 81, 940, 939, 469, 938, 538, 539, 540, 536, 937, 531, 936, 935, 532, 533, 541, 934, 537, 542, 534, 933, 932, 543, 544, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 547, 81, 84, 81, 922, 546, 921, 920, 549, 919, 918, 548, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 550, 563, 564, 551, 81, 84, 81, 81, 84, 81, 81, 84, 81, 553, 81, 84, 81, 565, 566, 552, 917, 916, 567, 915, 81, 84, 81, 914, 913, 554, 81, 84, 81, 912, 555, 81, 84, 81, 81, 84, 81, 911, 557, 910, 558, 909, 908, 556, 81, 84, 81, 907, 906, 559, 81, 84, 81, 81, 84, 81, 81, 84, 81, 905, 560, 609, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 610, 904, 903, 612, 611, 81, 84, 81, 81, 84, 81, 616, 613, 614, 81, 84, 81, 902, 615, 81, 84, 81, 621, 901, 618, 81, 84, 81, 81, 84, 81, 624, 900, 619, 81, 84, 81, 899, 622, 617, 898, 897, 620, 631, 896, 623, 895, 894, 625, 81, 84, 81, 81, 84, 81, 81, 84, 81, 893, 627, 81, 84, 81, 626, 81, 84, 81, 892, 81, 84, 81, 632, 628, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 878, 629, 633, 877, 876, 630, 81, 84, 81, 81, 84, 81, 875, 634, 81, 84, 81, 81, 84, 81, 874, 873, 635, 81, 84, 81, 81, 84, 81, 81, 84, 81, 637, 81, 84, 81, 81, 84, 81, 81, 84, 81, 872, 871, 636, 81, 84, 81, 81, 84, 81, 639, 870, 869, 638, 81, 84, 81, 868, 867, 640, 81, 84, 81, 866, 641, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 865, 864, 691, 81, 84, 81, 81, 84, 81, 692, 689, 81, 84, 81, 690, 81, 84, 81, 863, 862, 693, 81, 84, 81, 861, 694, 81, 84, 81, 81, 84, 81, 860, 859, 695, 858, 857, 696, 701, 700, 702, 856, 855, 703, 852, 697, 851, 698, 81, 84, 81, 81, 84, 81, 850, 849, 704, 699, 81, 84, 81, 848, 81, 84, 81, 81, 84, 81, 81, 84, 81, 847, 846, 706, 845, 705, 707, 81, 84, 81, 81, 84, 81, 81, 84, 81, 708, 710, 844, 709, 81, 84, 81, 843, 842, 711, 712, 81, 84, 81, 81, 84, 81, 81, 84, 81, 823, 714, 81, 84, 81, 81, 84, 81, 822, 713, 81, 84, 81, 81, 84, 81, 729, 730, 81, 84, 81, 81, 84, 81, 821, 731, 81, 84, 81, 820, 819, 732, 818, 817, 715, 81, 84, 81, 81, 84, 81, 716, 81, 84, 81, 81, 84, 81, 81, 84, 81, 816, 815, 763, 814, 761, 813, 812, 762, 81, 84, 81, 81, 84, 81, 81, 84, 81, 764, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 811, 765, 770, 81, 84, 81, 810, 809, 769, 808, 807, 771, 766, 81, 84, 81, 81, 84, 81, 81, 84, 81, 772, 774, 775, 767, 806, 805, 773, 768, 81, 84, 81, 81, 84, 81, 776, 81, 84, 81, 777, 778, 81, 84, 81, 81, 84, 81, 81, 84, 81, 804, 801, 781, 782, 81, 84, 81, 800, 780, 81, 84, 81, 81, 84, 81, 81, 84, 81, 779, 81, 84, 81, 81, 84, 81, 81, 84, 81, 799, 783, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 798, 797, 824, 81, 84, 81, 81, 84, 81, 81, 84, 81, 832, 831, 796, 795, 828, 794, 826, 793, 792, 825, 830, 81, 84, 81, 791, 790, 827, 789, 788, 829, 81, 84, 81, 81, 84, 81, 787, 786, 833, 81, 84, 81, 785, 834, 81, 84, 81, 784, 758, 835, 81, 84, 81, 81, 84, 81, 81, 84, 81, 757, 756, 837, 838, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 836, 81, 84, 81, 755, 840, 754, 753, 839, 81, 84, 81, 81, 84, 81, 752, 81, 84, 81, 841, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 751, 880, 750, 749, 886, 81, 84, 81, 81, 84, 81, 748, 879, 81, 84, 81, 747, 885, 746, 882, 883, 81, 84, 81, 745, 881, 81, 84, 81, 744, 887, 743, 742, 884, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 888, 741, 889, 81, 84, 81, 81, 84, 81, 740, 890, 81, 84, 81, 81, 84, 81, 739, 891, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 738, 81, 84, 81, 81, 84, 81, 737, 929, 736, 924, 81, 84, 81, 735, 734, 930, 81, 84, 81, 733, 923, 726, 927, 925, 931, 725, 724, 926, 81, 84, 81, 81, 84, 81, 928, 81, 84, 81, 81, 84, 81, 723, 81, 84, 81, 81, 84, 81, 961, 81, 84, 81, 81, 84, 81, 967, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 722, 721, 962, 966, 81, 84, 81, 720, 964, 719, 718, 963, 965, 81, 84, 81, 81, 84, 81, 81, 84, 81, 996, 717, 998, 81, 84, 81, 688, 997, 687, 999, 81, 84, 81, 686, 1000, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 1001, 81, 84, 81, 81, 84, 81, 81, 84, 81, 685, 1060, 81, 84, 81, 81, 84, 81, 684, 1031, 1030, 1029, 683, 682, 1033, 81, 84, 81, 1032, 1059, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 81, 84, 81, 681, 1083, 680, 1062, 679, 678, 1061, 81, 84, 81, 81, 84, 81, 677, 676, 1084, 81, 84, 81, 1086, 81, 84, 81, 81, 84, 81, 1085, 81, 84, 81, 675, 674, 1104, 81, 84, 81, 1105, 81, 84, 81, 1143, 671, 670, 1106, 81, 84, 81, 1122, 81, 84, 81, 669, 668, 1123, 81, 84, 81, 1135, 81, 84, 81, 81, 84, 81, 81, 84, 81, 667, 1136, 1142, 1149, 81, 84, 81, 666, 665, 664, 663, 1148, 662, 661, 660, 659, 658, 657, 656, 655, 654, 653, 652, 1153, 651, 650, 1152, 649, 648, 647, 646, 1155, 645, 644, 1154, 643, 642, 608, 607, 606, 605, 604, 603, 602, 601, 1156, 45, 45, 45, 45, 49, 49, 49, 49, 75, 75, 75, 75, 77, 77, 77, 77, 84, 84, 93, 93, 179, 600, 179, 179, 599, 598, 597, 596, 595, 594, 593, 592, 591, 590, 589, 588, 587, 586, 585, 584, 583, 582, 581, 580, 579, 578, 577, 576, 575, 574, 573, 572, 571, 570, 569, 568, 562, 561, 521, 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, 488, 487, 486, 485, 484, 483, 482, 481, 480, 479, 478, 437, 436, 435, 434, 433, 432, 431, 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, 401, 400, 399, 398, 397, 396, 365, 346, 345, 344, 343, 342, 341, 340, 337, 334, 333, 332, 331, 328, 324, 323, 320, 319, 315, 314, 313, 309, 306, 305, 304, 174, 225, 171, 248, 146, 247, 246, 243, 242, 237, 233, 219, 1157, 174, 171, 147, 146, 124, 92, 1157, 1157, 72, 46, 11, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157 } ; static yyconst flex_int16_t yy_chk[2776] = { 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, 2, 4, 4, 5, 2, 4, 6, 8, 79, 79, 5, 8, 10, 6, 7, 15, 10, 15, 10, 16, 181, 181, 17, 16, 17, 17, 129, 1082, 7, 18, 18, 18, 18, 18, 19, 23, 23, 23, 19, 27, 27, 27, 7, 1087, 43, 24, 24, 24, 43, 75, 7, 75, 7, 7, 129, 7, 7, 47, 7, 7, 7, 47, 7, 7, 133, 7, 7, 7, 7, 7, 20, 24, 20, 20, 338, 1088, 25, 25, 25, 20, 20, 338, 26, 26, 26, 27, 20, 28, 28, 28, 29, 29, 29, 133, 219, 20, 26, 30, 30, 30, 70, 31, 31, 31, 70, 219, 20, 20, 25, 32, 32, 32, 20, 33, 33, 33, 34, 34, 34, 81, 20, 81, 1090, 20, 35, 35, 35, 28, 73, 1091, 28, 77, 73, 28, 31, 77, 29, 36, 36, 36, 234, 84, 30, 84, 31, 234, 37, 37, 37, 34, 176, 30, 176, 1092, 32, 38, 38, 38, 141, 33, 39, 39, 39, 40, 40, 40, 41, 41, 41, 1093, 130, 35, 141, 53, 53, 53, 54, 54, 54, 130, 125, 57, 57, 57, 125, 36, 37, 37, 36, 37, 132, 131, 38, 174, 132, 38, 37, 55, 55, 55, 131, 41, 174, 38, 40, 39, 53, 436, 1094, 40, 38, 44, 44, 44, 44, 44, 44, 44, 57, 44, 436, 1096, 44, 44, 54, 44, 44, 57, 44, 44, 44, 44, 44, 56, 56, 56, 1097, 58, 58, 58, 55, 59, 59, 59, 1098, 60, 60, 60, 61, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, 64, 144, 65, 65, 65, 144, 134, 56, 68, 68, 68, 58, 134, 134, 56, 653, 1099, 56, 127, 59, 56, 58, 60, 169, 58, 62, 61, 169, 63, 653, 228, 60, 127, 62, 66, 66, 66, 1100, 62, 65, 172, 67, 67, 67, 172, 64, 64, 228, 127, 69, 69, 69, 1101, 68, 82, 82, 82, 68, 93, 93, 93, 239, 83, 136, 83, 83, 83, 136, 94, 94, 94, 66, 83, 83, 66, 66, 136, 66, 67, 239, 311, 67, 67, 311, 66, 94, 69, 88, 88, 67, 69, 88, 88, 795, 795, 69, 67, 87, 87, 83, 83, 95, 95, 95, 87, 87, 96, 96, 96, 97, 97, 97, 98, 98, 98, 99, 99, 99, 100, 100, 100, 101, 101, 101, 178, 95, 178, 96, 102, 102, 102, 87, 87, 103, 103, 103, 182, 182, 104, 104, 104, 105, 105, 105, 182, 98, 1102, 1103, 99, 106, 106, 106, 107, 107, 107, 97, 108, 108, 108, 109, 109, 109, 1107, 100, 110, 110, 110, 111, 111, 111, 1108, 182, 101, 112, 112, 112, 113, 113, 113, 102, 103, 104, 114, 114, 114, 241, 1109, 105, 115, 115, 115, 116, 116, 116, 241, 1110, 109, 107, 1112, 106, 108, 111, 117, 117, 117, 110, 118, 118, 118, 435, 110, 119, 119, 119, 435, 113, 120, 120, 120, 112, 1113, 115, 121, 121, 121, 122, 122, 122, 114, 123, 123, 123, 138, 592, 138, 116, 115, 138, 592, 138, 148, 148, 148, 149, 149, 149, 150, 150, 150, 688, 117, 688, 151, 151, 151, 1114, 1117, 118, 119, 152, 152, 152, 153, 153, 153, 120, 122, 1118, 1119, 123, 121, 154, 154, 154, 155, 155, 155, 156, 156, 156, 157, 157, 157, 148, 158, 158, 158, 1121, 1126, 150, 159, 159, 159, 1129, 149, 151, 1130, 152, 160, 160, 160, 161, 161, 161, 735, 162, 162, 162, 735, 1131, 153, 163, 163, 163, 164, 164, 164, 221, 221, 158, 221, 154, 165, 165, 165, 157, 166, 166, 166, 168, 168, 168, 156, 1132, 159, 160, 1138, 161, 167, 167, 167, 187, 187, 187, 175, 175, 1139, 1140, 160, 162, 1141, 175, 175, 164, 177, 177, 225, 177, 177, 177, 1145, 163, 180, 180, 1146, 1165, 165, 1081, 225, 180, 180, 225, 1080, 166, 1079, 167, 1078, 168, 175, 175, 1076, 184, 184, 184, 187, 185, 185, 185, 186, 186, 186, 188, 188, 188, 1074, 1072, 180, 180, 184, 185, 1071, 1070, 185, 189, 189, 189, 190, 190, 190, 191, 191, 191, 192, 192, 192, 193, 193, 193, 1069, 1068, 186, 194, 194, 194, 195, 195, 195, 196, 196, 196, 197, 197, 197, 1067, 198, 198, 198, 1066, 1065, 188, 199, 199, 199, 191, 200, 200, 200, 201, 201, 201, 1064, 1063, 189, 1058, 1057, 190, 192, 195, 193, 202, 202, 202, 203, 203, 203, 1056, 204, 204, 204, 197, 194, 198, 205, 205, 205, 206, 206, 206, 207, 207, 207, 208, 208, 208, 209, 209, 209, 1055, 199, 210, 210, 210, 212, 212, 212, 232, 200, 201, 211, 211, 211, 232, 202, 213, 213, 213, 214, 214, 214, 232, 203, 204, 215, 215, 215, 249, 249, 249, 250, 250, 250, 1054, 205, 1052, 1051, 206, 210, 1050, 208, 207, 209, 1049, 1048, 212, 1045, 211, 251, 251, 251, 252, 252, 252, 214, 1044, 1043, 215, 253, 253, 253, 254, 254, 254, 1042, 213, 1041, 250, 255, 255, 255, 256, 256, 256, 1039, 1038, 249, 257, 257, 257, 251, 258, 258, 258, 259, 259, 259, 260, 260, 260, 1037, 253, 1036, 1035, 252, 261, 261, 261, 262, 262, 262, 263, 263, 263, 1028, 254, 264, 264, 264, 265, 265, 265, 266, 266, 266, 1027, 257, 1026, 258, 1024, 1023, 259, 1022, 1021, 256, 267, 267, 267, 260, 268, 268, 268, 261, 270, 1020, 270, 270, 270, 1018, 271, 1017, 271, 271, 271, 262, 1016, 265, 1015, 1014, 266, 271, 264, 272, 272, 272, 1013, 1012, 267, 273, 273, 273, 274, 274, 274, 1011, 275, 275, 275, 1010, 1009, 273, 275, 276, 276, 276, 1008, 1007, 271, 268, 1006, 1005, 274, 277, 277, 277, 1004, 275, 275, 275, 275, 278, 278, 278, 279, 279, 279, 1003, 280, 280, 280, 281, 281, 281, 282, 282, 282, 1002, 995, 283, 283, 283, 284, 284, 284, 285, 285, 285, 286, 286, 286, 287, 287, 287, 288, 288, 288, 289, 289, 289, 290, 290, 290, 291, 291, 291, 292, 292, 292, 994, 278, 280, 993, 992, 279, 282, 283, 293, 293, 293, 294, 294, 294, 990, 287, 989, 988, 288, 295, 295, 295, 987, 284, 986, 289, 985, 984, 286, 983, 292, 982, 290, 981, 292, 296, 296, 296, 297, 297, 297, 298, 298, 298, 291, 299, 299, 299, 300, 300, 300, 980, 294, 979, 295, 978, 977, 293, 301, 301, 301, 302, 302, 302, 303, 303, 303, 347, 347, 347, 348, 348, 348, 349, 349, 349, 976, 975, 296, 974, 973, 299, 350, 350, 350, 972, 971, 300, 351, 351, 351, 297, 352, 352, 352, 353, 353, 353, 354, 354, 354, 355, 355, 355, 347, 356, 356, 356, 970, 301, 969, 968, 303, 960, 350, 357, 357, 357, 358, 358, 358, 349, 359, 359, 359, 352, 360, 360, 360, 361, 361, 361, 362, 362, 362, 959, 363, 363, 363, 351, 958, 353, 364, 364, 364, 957, 355, 956, 955, 354, 954, 366, 366, 366, 356, 367, 367, 367, 953, 360, 952, 357, 950, 360, 949, 948, 358, 947, 362, 363, 366, 368, 368, 368, 359, 369, 369, 369, 361, 946, 367, 945, 944, 364, 370, 370, 370, 371, 371, 371, 368, 943, 942, 372, 372, 372, 373, 373, 373, 374, 374, 374, 941, 940, 370, 369, 939, 372, 938, 937, 372, 375, 375, 375, 936, 935, 371, 372, 376, 376, 376, 377, 377, 377, 378, 378, 378, 379, 379, 379, 380, 380, 380, 381, 381, 381, 382, 382, 382, 934, 383, 383, 383, 384, 384, 384, 933, 932, 375, 385, 385, 385, 922, 376, 386, 386, 386, 387, 387, 387, 388, 388, 388, 389, 389, 389, 390, 390, 390, 921, 920, 382, 919, 918, 379, 383, 391, 391, 391, 917, 380, 916, 915, 381, 392, 392, 392, 393, 393, 393, 386, 914, 385, 913, 912, 388, 394, 394, 394, 390, 911, 395, 395, 395, 438, 438, 438, 439, 439, 439, 440, 440, 440, 389, 441, 441, 441, 442, 442, 442, 909, 392, 443, 443, 443, 444, 444, 444, 908, 394, 906, 905, 393, 395, 445, 445, 445, 446, 446, 446, 439, 447, 447, 447, 448, 448, 448, 449, 449, 449, 450, 450, 450, 451, 451, 451, 904, 441, 444, 440, 452, 452, 452, 453, 453, 453, 903, 442, 902, 453, 443, 454, 454, 454, 455, 455, 455, 457, 457, 457, 901, 448, 446, 445, 457, 456, 456, 456, 900, 899, 449, 898, 456, 456, 456, 454, 897, 449, 896, 895, 450, 451, 456, 894, 455, 456, 452, 893, 892, 456, 456, 458, 458, 458, 459, 459, 459, 460, 460, 460, 461, 461, 461, 462, 462, 462, 459, 463, 463, 463, 878, 458, 877, 876, 461, 875, 874, 460, 464, 464, 464, 465, 465, 465, 466, 466, 466, 467, 467, 467, 468, 468, 468, 469, 469, 469, 470, 470, 470, 471, 471, 471, 472, 472, 472, 473, 473, 473, 463, 480, 480, 464, 474, 474, 474, 475, 475, 475, 476, 476, 476, 466, 477, 477, 477, 480, 480, 465, 873, 872, 480, 870, 522, 522, 522, 869, 865, 467, 523, 523, 523, 864, 469, 524, 524, 524, 525, 525, 525, 863, 474, 862, 475, 861, 860, 473, 526, 526, 526, 859, 858, 476, 527, 527, 527, 528, 528, 528, 530, 530, 530, 857, 477, 522, 529, 529, 529, 531, 531, 531, 532, 532, 532, 533, 533, 533, 534, 534, 534, 523, 856, 855, 526, 524, 535, 535, 535, 536, 536, 536, 530, 527, 528, 537, 537, 537, 854, 529, 538, 538, 538, 535, 853, 532, 539, 539, 539, 545, 545, 545, 539, 852, 533, 540, 540, 540, 851, 537, 531, 850, 849, 534, 545, 848, 538, 847, 846, 540, 541, 541, 541, 542, 542, 542, 543, 543, 543, 845, 542, 544, 544, 544, 541, 546, 546, 546, 844, 547, 547, 547, 546, 543, 548, 548, 548, 549, 549, 549, 550, 550, 550, 551, 551, 551, 823, 544, 547, 822, 821, 544, 552, 552, 552, 553, 553, 553, 820, 548, 554, 554, 554, 555, 555, 555, 818, 817, 549, 556, 556, 556, 557, 557, 557, 558, 558, 558, 551, 559, 559, 559, 560, 560, 560, 609, 609, 609, 816, 814, 550, 610, 610, 610, 611, 611, 611, 554, 813, 812, 552, 612, 612, 612, 811, 810, 556, 613, 613, 613, 809, 558, 614, 614, 614, 615, 615, 615, 616, 616, 616, 617, 617, 617, 808, 807, 611, 618, 618, 618, 619, 619, 619, 612, 609, 620, 620, 620, 610, 621, 621, 621, 806, 805, 613, 622, 622, 622, 804, 614, 624, 624, 624, 623, 623, 623, 803, 802, 615, 799, 798, 616, 622, 621, 623, 797, 796, 624, 794, 617, 793, 618, 625, 625, 625, 626, 626, 626, 792, 791, 625, 619, 627, 627, 627, 790, 628, 628, 628, 629, 629, 629, 630, 630, 630, 789, 788, 627, 787, 626, 628, 631, 631, 631, 632, 632, 632, 634, 634, 634, 629, 631, 786, 630, 633, 633, 633, 785, 784, 632, 633, 635, 635, 635, 636, 636, 636, 637, 637, 637, 760, 635, 638, 638, 638, 639, 639, 639, 759, 634, 640, 640, 640, 641, 641, 641, 655, 655, 689, 689, 689, 690, 690, 690, 758, 655, 691, 691, 691, 756, 753, 655, 751, 750, 637, 692, 692, 692, 693, 693, 693, 639, 694, 694, 694, 695, 695, 695, 696, 696, 696, 749, 748, 691, 747, 689, 746, 745, 690, 697, 697, 697, 698, 698, 698, 700, 700, 700, 692, 699, 699, 699, 701, 701, 701, 702, 702, 702, 703, 703, 703, 704, 704, 704, 744, 696, 702, 705, 705, 705, 743, 742, 701, 740, 739, 703, 697, 706, 706, 706, 707, 707, 707, 708, 708, 708, 704, 706, 707, 698, 738, 737, 705, 699, 709, 709, 709, 710, 710, 710, 708, 711, 711, 711, 709, 710, 712, 712, 712, 713, 713, 713, 714, 714, 714, 736, 734, 713, 713, 715, 715, 715, 733, 712, 716, 716, 716, 761, 761, 761, 762, 762, 762, 711, 763, 763, 763, 764, 764, 764, 765, 765, 765, 732, 714, 766, 766, 766, 767, 767, 767, 768, 768, 768, 769, 769, 769, 731, 730, 761, 770, 770, 770, 771, 771, 771, 772, 772, 772, 771, 770, 729, 728, 765, 727, 763, 726, 725, 762, 769, 773, 773, 773, 724, 723, 764, 722, 721, 768, 774, 774, 774, 775, 775, 775, 720, 719, 774, 776, 776, 776, 718, 775, 777, 777, 777, 717, 687, 776, 778, 778, 778, 779, 779, 779, 780, 780, 780, 686, 685, 779, 779, 781, 781, 781, 782, 782, 782, 783, 783, 783, 824, 824, 824, 778, 825, 825, 825, 684, 782, 683, 681, 781, 826, 826, 826, 827, 827, 827, 680, 828, 828, 828, 783, 829, 829, 829, 830, 830, 830, 831, 831, 831, 832, 832, 832, 679, 825, 678, 677, 832, 833, 833, 833, 834, 834, 834, 676, 824, 835, 835, 835, 675, 831, 674, 827, 828, 836, 836, 836, 673, 826, 837, 837, 837, 672, 833, 671, 670, 829, 838, 838, 838, 839, 839, 839, 840, 840, 840, 841, 841, 841, 837, 669, 838, 879, 879, 879, 880, 880, 880, 667, 839, 881, 881, 881, 882, 882, 882, 666, 840, 883, 883, 883, 884, 884, 884, 885, 885, 885, 886, 886, 886, 887, 887, 887, 888, 888, 888, 663, 889, 889, 889, 890, 890, 890, 662, 886, 661, 880, 891, 891, 891, 658, 657, 888, 923, 923, 923, 656, 879, 652, 883, 881, 889, 651, 649, 882, 924, 924, 924, 925, 925, 925, 884, 926, 926, 926, 927, 927, 927, 648, 928, 928, 928, 929, 929, 929, 923, 930, 930, 930, 931, 931, 931, 929, 961, 961, 961, 962, 962, 962, 963, 963, 963, 964, 964, 964, 965, 965, 965, 647, 646, 924, 928, 966, 966, 966, 645, 926, 644, 643, 925, 927, 967, 967, 967, 996, 996, 996, 997, 997, 997, 961, 642, 963, 998, 998, 998, 608, 962, 607, 964, 999, 999, 999, 606, 965, 1000, 1000, 1000, 1001, 1001, 1001, 1029, 1029, 1029, 1030, 1030, 1030, 966, 1031, 1031, 1031, 1032, 1032, 1032, 1033, 1033, 1033, 605, 1031, 1059, 1059, 1059, 1060, 1060, 1060, 604, 998, 997, 996, 603, 602, 1001, 1061, 1061, 1061, 999, 1029, 1062, 1062, 1062, 1083, 1083, 1083, 1084, 1084, 1084, 1085, 1085, 1085, 1086, 1086, 1086, 1104, 1104, 1104, 601, 1059, 600, 1033, 599, 598, 1032, 1105, 1105, 1105, 1106, 1106, 1106, 597, 595, 1060, 1122, 1122, 1122, 1062, 1123, 1123, 1123, 1135, 1135, 1135, 1061, 1136, 1136, 1136, 594, 593, 1083, 1142, 1142, 1142, 1084, 1143, 1143, 1143, 1136, 591, 590, 1086, 1148, 1148, 1148, 1104, 1149, 1149, 1149, 589, 588, 1105, 1152, 1152, 1152, 1122, 1153, 1153, 1153, 1154, 1154, 1154, 1155, 1155, 1155, 587, 1123, 1135, 1143, 1156, 1156, 1156, 586, 585, 583, 582, 1142, 581, 580, 579, 578, 577, 576, 575, 574, 573, 572, 571, 1152, 570, 569, 1149, 568, 567, 566, 565, 1154, 564, 563, 1153, 562, 561, 521, 520, 519, 518, 517, 516, 515, 514, 1155, 1158, 1158, 1158, 1158, 1159, 1159, 1159, 1159, 1160, 1160, 1160, 1160, 1161, 1161, 1161, 1161, 1162, 1162, 1163, 1163, 1164, 513, 1164, 1164, 512, 511, 510, 509, 508, 507, 506, 505, 504, 503, 502, 501, 500, 499, 498, 497, 496, 495, 494, 493, 492, 491, 490, 489, 488, 487, 486, 485, 484, 483, 482, 481, 479, 478, 437, 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, 403, 402, 401, 400, 399, 398, 397, 396, 345, 344, 343, 342, 341, 340, 339, 337, 336, 335, 334, 333, 332, 331, 330, 329, 328, 327, 326, 325, 324, 323, 322, 321, 320, 319, 318, 317, 316, 314, 313, 312, 310, 309, 308, 307, 306, 305, 269, 248, 247, 246, 245, 244, 243, 242, 240, 238, 237, 236, 235, 233, 231, 229, 227, 226, 224, 223, 222, 220, 218, 217, 216, 173, 171, 170, 146, 145, 143, 142, 140, 139, 137, 135, 128, 80, 74, 71, 51, 48, 42, 22, 21, 11, 9, 3, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157 } ; 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 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" /* * The SIP lexer. * * Copyright (c) 2014 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 "/Users/phil/hg/sip/sip-4.15.5/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 #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 1502 "/Users/phil/hg/sip/sip-4.15.5/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 64 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" #line 1704 "/Users/phil/hg/sip/sip-4.15.5/sipgen/lexer.c" if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_current_state += YY_AT_BOL(); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 1158 ) 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] != 2707 ); 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 66 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_API;} YY_BREAK case 2: YY_RULE_SETUP #line 67 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_AUTOPYNAME;} YY_BREAK case 3: YY_RULE_SETUP #line 68 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_CMODULE;} YY_BREAK case 4: YY_RULE_SETUP #line 69 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_COMPOMODULE;} YY_BREAK case 5: YY_RULE_SETUP #line 70 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_CONSMODULE;} YY_BREAK case 6: YY_RULE_SETUP #line 71 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_DEFDOCSTRING;} YY_BREAK case 7: YY_RULE_SETUP #line 72 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_DEFENCODING;} YY_BREAK case 8: YY_RULE_SETUP #line 73 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_DEFMETATYPE;} YY_BREAK case 9: YY_RULE_SETUP #line 74 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_DEFSUPERTYPE;} YY_BREAK case 10: YY_RULE_SETUP #line 75 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_END;} YY_BREAK case 11: YY_RULE_SETUP #line 76 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {BEGIN INITIAL; return TK_END;} YY_BREAK case 12: YY_RULE_SETUP #line 77 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_EXCEPTION;} YY_BREAK case 13: YY_RULE_SETUP #line 78 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_FEATURE;} YY_BREAK case 14: YY_RULE_SETUP #line 79 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_IF;} YY_BREAK case 15: YY_RULE_SETUP #line 80 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_IMPORT;} YY_BREAK case 16: YY_RULE_SETUP #line 81 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_INCLUDE;} YY_BREAK case 17: YY_RULE_SETUP #line 82 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_LICENSE;} YY_BREAK case 18: YY_RULE_SETUP #line 83 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_MAPPEDTYPE;} YY_BREAK case 19: YY_RULE_SETUP #line 84 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_MODULE;} YY_BREAK case 20: YY_RULE_SETUP #line 85 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_OPTINCLUDE;} YY_BREAK case 21: YY_RULE_SETUP #line 86 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_PLATFORMS;} YY_BREAK case 22: YY_RULE_SETUP #line 87 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_PLUGIN;} YY_BREAK case 23: YY_RULE_SETUP #line 88 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {BEGIN directive_start; return TK_PROPERTY;} YY_BREAK case 24: YY_RULE_SETUP #line 89 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_TIMELINE;} YY_BREAK case 25: YY_RULE_SETUP #line 91 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_CLASS;} YY_BREAK case 26: YY_RULE_SETUP #line 92 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_STRUCT;} YY_BREAK case 27: YY_RULE_SETUP #line 93 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_PUBLIC;} YY_BREAK case 28: YY_RULE_SETUP #line 94 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_PROTECTED;} YY_BREAK case 29: YY_RULE_SETUP #line 95 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_PRIVATE;} YY_BREAK case 30: YY_RULE_SETUP #line 96 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_SIGNALS;} YY_BREAK case 31: YY_RULE_SETUP #line 97 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_SIGNALS;} YY_BREAK case 32: YY_RULE_SETUP #line 98 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_SIGNAL_METHOD;} YY_BREAK case 33: YY_RULE_SETUP #line 99 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_SLOTS;} YY_BREAK case 34: YY_RULE_SETUP #line 100 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_SLOTS;} YY_BREAK case 35: YY_RULE_SETUP #line 101 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_SLOT_METHOD;} YY_BREAK case 36: YY_RULE_SETUP #line 102 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_CHAR;} YY_BREAK case 37: YY_RULE_SETUP #line 103 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_WCHAR_T;} YY_BREAK case 38: YY_RULE_SETUP #line 104 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_BOOL;} YY_BREAK case 39: YY_RULE_SETUP #line 105 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_SHORT;} YY_BREAK case 40: YY_RULE_SETUP #line 106 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_INT;} YY_BREAK case 41: YY_RULE_SETUP #line 107 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_LONG;} YY_BREAK case 42: YY_RULE_SETUP #line 108 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_FLOAT;} YY_BREAK case 43: YY_RULE_SETUP #line 109 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_DOUBLE;} YY_BREAK case 44: YY_RULE_SETUP #line 110 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_VOID;} YY_BREAK case 45: YY_RULE_SETUP #line 111 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_VIRTUAL;} YY_BREAK case 46: YY_RULE_SETUP #line 112 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_ENUM;} YY_BREAK case 47: YY_RULE_SETUP #line 113 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_SIGNED;} YY_BREAK case 48: YY_RULE_SETUP #line 114 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_UNSIGNED;} YY_BREAK case 49: YY_RULE_SETUP #line 115 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_CONST;} YY_BREAK case 50: YY_RULE_SETUP #line 116 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_STATIC;} YY_BREAK case 51: YY_RULE_SETUP #line 117 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_TRUE_VALUE;} YY_BREAK case 52: YY_RULE_SETUP #line 118 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_FALSE_VALUE;} YY_BREAK case 53: YY_RULE_SETUP #line 119 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_NULL_VALUE;} YY_BREAK case 54: YY_RULE_SETUP #line 120 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_TYPEDEF;} YY_BREAK case 55: YY_RULE_SETUP #line 121 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_NAMESPACE;} YY_BREAK case 56: YY_RULE_SETUP #line 122 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_OPERATOR;} YY_BREAK case 57: YY_RULE_SETUP #line 123 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_THROW;} YY_BREAK case 58: YY_RULE_SETUP #line 124 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_EXPLICIT;} YY_BREAK case 59: YY_RULE_SETUP #line 125 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_TEMPLATE;} YY_BREAK case 60: YY_RULE_SETUP #line 126 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_SCOPE;} YY_BREAK case 61: YY_RULE_SETUP #line 127 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_LOGICAL_OR;} YY_BREAK case 62: YY_RULE_SETUP #line 128 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_PYOBJECT;} YY_BREAK case 63: YY_RULE_SETUP #line 129 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_PYTUPLE;} YY_BREAK case 64: YY_RULE_SETUP #line 130 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_PYLIST;} YY_BREAK case 65: YY_RULE_SETUP #line 131 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_PYDICT;} YY_BREAK case 66: YY_RULE_SETUP #line 132 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_PYCALLABLE;} YY_BREAK case 67: YY_RULE_SETUP #line 133 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_PYSLICE;} YY_BREAK case 68: YY_RULE_SETUP #line 134 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_PYTYPE;} YY_BREAK case 69: YY_RULE_SETUP #line 135 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_PYBUFFER;} YY_BREAK case 70: YY_RULE_SETUP #line 136 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_SIPSIGNAL;} YY_BREAK case 71: YY_RULE_SETUP #line 137 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_SIPSLOT;} YY_BREAK case 72: YY_RULE_SETUP #line 138 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_SIPANYSLOT;} YY_BREAK case 73: YY_RULE_SETUP #line 139 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_SIPRXCON;} YY_BREAK case 74: YY_RULE_SETUP #line 140 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_SIPRXDIS;} YY_BREAK case 75: YY_RULE_SETUP #line 141 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_SIPSLOTCON;} YY_BREAK case 76: YY_RULE_SETUP #line 142 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_SIPSLOTDIS;} YY_BREAK case 77: YY_RULE_SETUP #line 143 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_SIPSSIZET;} YY_BREAK case 78: YY_RULE_SETUP #line 144 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_QOBJECT;} YY_BREAK case 79: YY_RULE_SETUP #line 145 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_ELLIPSIS;} YY_BREAK case 80: YY_RULE_SETUP #line 147 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_FORMAT;} YY_BREAK case 81: YY_RULE_SETUP #line 148 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_GET;} YY_BREAK case 82: YY_RULE_SETUP #line 149 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_ID;} YY_BREAK case 83: YY_RULE_SETUP #line 150 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_KWARGS;} YY_BREAK case 84: YY_RULE_SETUP #line 151 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_LANGUAGE;} YY_BREAK case 85: YY_RULE_SETUP #line 152 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_LICENSEE;} YY_BREAK case 86: YY_RULE_SETUP #line 153 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_NAME;} YY_BREAK case 87: YY_RULE_SETUP #line 154 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_OPTIONAL;} YY_BREAK case 88: YY_RULE_SETUP #line 155 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_ORDER;} YY_BREAK case 89: YY_RULE_SETUP #line 156 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_REMOVELEADING;} YY_BREAK case 90: YY_RULE_SETUP #line 157 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_SET;} YY_BREAK case 91: YY_RULE_SETUP #line 158 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_SIGNATURE;} YY_BREAK case 92: YY_RULE_SETUP #line 159 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_TIMESTAMP;} YY_BREAK case 93: YY_RULE_SETUP #line 160 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_TYPE;} YY_BREAK case 94: YY_RULE_SETUP #line 161 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_USEARGNAMES;} YY_BREAK case 95: YY_RULE_SETUP #line 162 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_ALLRAISEPYEXC;} YY_BREAK case 96: YY_RULE_SETUP #line 163 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_CALLSUPERINIT;} YY_BREAK case 97: YY_RULE_SETUP #line 164 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_DEFERRORHANDLER;} YY_BREAK case 98: YY_RULE_SETUP #line 165 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_VERSION;} YY_BREAK case 99: YY_RULE_SETUP #line 167 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_TRUE_VALUE;} YY_BREAK case 100: YY_RULE_SETUP #line 168 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" {return TK_FALSE_VALUE;} YY_BREAK case 101: YY_RULE_SETUP #line 171 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* Ignore whitespace. */ ; } YY_BREAK case 102: YY_RULE_SETUP #line 176 "/Users/phil/hg/sip/sip-4.15.5/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 103: YY_RULE_SETUP #line 188 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* Maintain the parenthesis depth. */ --parenDepth; BEGIN INITIAL; return ')'; } YY_BREAK case 104: /* rule 104 can match eol */ YY_RULE_SETUP #line 197 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* Maintain the line number. */ ++inputFileStack[currentFile].sloc.linenr; if (codeIdx == 0 && parenDepth == 0) { BEGIN code; } } YY_BREAK case 105: YY_RULE_SETUP #line 207 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* Ignore C++ style comments. */ ; } YY_BREAK case 106: YY_RULE_SETUP #line 213 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* A signed decimal number. */ yylval.number = strtol(yytext,NULL,0); return TK_NUMBER_VALUE; } YY_BREAK case 107: YY_RULE_SETUP #line 220 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* A floating point number. */ yylval.real = strtod(yytext,NULL); return TK_REAL_VALUE; } YY_BREAK case 108: YY_RULE_SETUP #line 227 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* An unsigned hexadecimal number. */ yylval.number = strtol(yytext,NULL,16); return TK_NUMBER_VALUE; } YY_BREAK case 109: YY_RULE_SETUP #line 234 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* An identifier name. */ yylval.text = sipStrdup(yytext); return TK_NAME_VALUE; } YY_BREAK case 110: YY_RULE_SETUP #line 241 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* A relative pathname. */ yylval.text = sipStrdup(yytext); return TK_PATH_VALUE; } YY_BREAK case 111: /* rule 111 can match eol */ YY_RULE_SETUP #line 248 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* A double-quoted string. */ char *dp, *sp; /* Copy the string without the quotes. */ yylval.text = sipMalloc(strlen(yytext) + 1); dp = yylval.text; sp = yytext; while (*sp != '\0') { if (*sp != '"') *dp++ = *sp; ++sp; } *dp = '\0'; return TK_STRING_VALUE; } YY_BREAK case 112: /* rule 112 can match eol */ YY_RULE_SETUP #line 273 "/Users/phil/hg/sip/sip-4.15.5/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 113: YY_RULE_SETUP #line 284 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* Ignore C-style comments. */ yy_push_state(ccomment); } YY_BREAK case 114: /* rule 114 can match eol */ YY_RULE_SETUP #line 288 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { ++inputFileStack[currentFile].sloc.linenr; } YY_BREAK case 115: YY_RULE_SETUP #line 291 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { yy_pop_state(); } YY_BREAK case 116: YY_RULE_SETUP #line 294 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { ; } YY_BREAK case 117: YY_RULE_SETUP #line 299 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The software license. */ codeIdx = 0; return TK_COPYING; } YY_BREAK case 118: YY_RULE_SETUP #line 305 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a from-type code block. */ codeIdx = 0; return TK_FROMTYPE; } YY_BREAK case 119: YY_RULE_SETUP #line 311 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a to-type code block. */ codeIdx = 0; return TK_TOTYPE; } YY_BREAK case 120: YY_RULE_SETUP #line 317 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a to-sub-class code block. */ codeIdx = 0; return TK_TOSUBCLASS; } YY_BREAK case 121: YY_RULE_SETUP #line 323 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of an exported header code block. */ codeIdx = 0; return TK_EXPHEADERCODE; } YY_BREAK case 122: YY_RULE_SETUP #line 329 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of part of an extract. */ codeIdx = 0; BEGIN directive_start; return TK_EXTRACT; } YY_BREAK case 123: YY_RULE_SETUP #line 338 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a module header code block. */ codeIdx = 0; return TK_MODHEADERCODE; } YY_BREAK case 124: YY_RULE_SETUP #line 344 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a type header code block. */ codeIdx = 0; return TK_TYPEHEADERCODE; } YY_BREAK case 125: YY_RULE_SETUP #line 350 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a pre-initialisation code block. */ codeIdx = 0; return TK_PREINITCODE; } YY_BREAK case 126: YY_RULE_SETUP #line 356 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of an initialisation code block. */ codeIdx = 0; return TK_INITCODE; } YY_BREAK case 127: YY_RULE_SETUP #line 362 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a post-initialisation code block. */ codeIdx = 0; return TK_POSTINITCODE; } YY_BREAK case 128: YY_RULE_SETUP #line 368 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a class finalisation code block. */ codeIdx = 0; return TK_FINALCODE; } YY_BREAK case 129: YY_RULE_SETUP #line 374 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a unit code block. */ codeIdx = 0; return TK_UNITCODE; } YY_BREAK case 130: YY_RULE_SETUP #line 380 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a unit post-include code block. */ codeIdx = 0; return TK_UNITPOSTINCLUDECODE; } YY_BREAK case 131: YY_RULE_SETUP #line 386 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a module code block. */ codeIdx = 0; return TK_MODCODE; } YY_BREAK case 132: YY_RULE_SETUP #line 392 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a type code block. */ codeIdx = 0; return TK_TYPECODE; } YY_BREAK case 133: YY_RULE_SETUP #line 398 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a C++ method code block. */ codeIdx = 0; return TK_METHODCODE; } YY_BREAK case 134: YY_RULE_SETUP #line 404 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a C++ virtual code block. */ codeIdx = 0; return TK_VIRTUALCATCHERCODE; } YY_BREAK case 135: YY_RULE_SETUP #line 410 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a traverse code block. */ codeIdx = 0; return TK_TRAVERSECODE; } YY_BREAK case 136: YY_RULE_SETUP #line 416 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a clear code block. */ codeIdx = 0; return TK_CLEARCODE; } YY_BREAK case 137: YY_RULE_SETUP #line 422 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a get buffer code block. */ codeIdx = 0; return TK_GETBUFFERCODE; } YY_BREAK case 138: YY_RULE_SETUP #line 428 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a release buffer code block. */ codeIdx = 0; return TK_RELEASEBUFFERCODE; } YY_BREAK case 139: YY_RULE_SETUP #line 434 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a read buffer code block. */ codeIdx = 0; return TK_READBUFFERCODE; } YY_BREAK case 140: YY_RULE_SETUP #line 440 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a write buffer code block. */ codeIdx = 0; return TK_WRITEBUFFERCODE; } YY_BREAK case 141: YY_RULE_SETUP #line 446 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a segment count code block. */ codeIdx = 0; return TK_SEGCOUNTCODE; } YY_BREAK case 142: YY_RULE_SETUP #line 452 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a char buffer code block. */ codeIdx = 0; return TK_CHARBUFFERCODE; } YY_BREAK case 143: YY_RULE_SETUP #line 458 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a create instance code block. */ codeIdx = 0; return TK_INSTANCECODE; } YY_BREAK case 144: YY_RULE_SETUP #line 464 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a pickle code block. */ codeIdx = 0; return TK_PICKLECODE; } YY_BREAK case 145: YY_RULE_SETUP #line 470 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a pre-Python code block. */ deprecated("%PrePythonCode is deprecated"); codeIdx = 0; return TK_PREPYCODE; } YY_BREAK case 146: YY_RULE_SETUP #line 478 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a raise Python exception code block. */ codeIdx = 0; return TK_RAISECODE; } YY_BREAK case 147: YY_RULE_SETUP #line 484 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a docstring block. */ codeIdx = 0; return TK_DOCSTRING; } YY_BREAK case 148: YY_RULE_SETUP #line 490 "/Users/phil/hg/sip/sip-4.15.5/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 149: YY_RULE_SETUP #line 498 "/Users/phil/hg/sip/sip-4.15.5/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 150: YY_RULE_SETUP #line 506 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a Makefile code block. */ deprecated("%Makefile is deprecated"); codeIdx = 0; return TK_MAKEFILE; } YY_BREAK case 151: YY_RULE_SETUP #line 514 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of an access code block. */ codeIdx = 0; return TK_ACCESSCODE; } YY_BREAK case 152: YY_RULE_SETUP #line 520 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a get code block. */ codeIdx = 0; return TK_GETCODE; } YY_BREAK case 153: YY_RULE_SETUP #line 526 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of a set code block. */ codeIdx = 0; return TK_SETCODE; } YY_BREAK case 154: YY_RULE_SETUP #line 532 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The start of part of a virtual error handler. */ codeIdx = 0; BEGIN directive_start; return TK_VIRTERRORHANDLER; } YY_BREAK case 155: YY_RULE_SETUP #line 541 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* The end of a code block. */ BEGIN INITIAL; codeIdx = -1; return TK_END; } YY_BREAK case 156: /* rule 156 can match eol */ YY_RULE_SETUP #line 548 "/Users/phil/hg/sip/sip-4.15.5/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 157: YY_RULE_SETUP #line 567 "/Users/phil/hg/sip/sip-4.15.5/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 158: YY_RULE_SETUP #line 575 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" { /* Anything else is returned as is. */ return yytext[0]; } YY_BREAK case 159: YY_RULE_SETUP #line 580 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/lexer.l" ECHO; YY_BREAK #line 2875 "/Users/phil/hg/sip/sip-4.15.5/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 >= 1158 ) 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 >= 1158 ) 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 == 1157); 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 580 "/Users/phil/hg/sip/sip-4.15.5/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.15.5/sipgen/main.c0000644000076500000240000003243712261240700015040 0ustar philstaff00000000000000/* * The main module for SIP. * * Copyright (c) 2014 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 void help(void); static void version(void); static void usage(void); static char parseopt(int,char **,char *,char **,int *,char **); static int parseInt(char *,char); int main(int argc, char **argv) { char *filename, *docFile, *codeDir, *srcSuffix, *flagFile, *consModule; char arg, *optarg, *buildFile, *apiFile, *xmlFile; int optnr, exceptions, tracing, releaseGIL, parts, protHack, docs; int timestamp; KwArgs kwArgs; FILE *file; sipSpec spec; stringList *versions, *xfeatures, *extracts; /* Initialise. */ sipVersion = SIP_VERSION_STR; includeDirList = NULL; versions = NULL; xfeatures = NULL; buildFile = NULL; codeDir = NULL; docFile = NULL; srcSuffix = NULL; flagFile = NULL; apiFile = NULL; xmlFile = NULL; consModule = NULL; extracts = NULL; exceptions = FALSE; tracing = FALSE; releaseGIL = FALSE; parts = 0; kwArgs = NoKwArgs; protHack = FALSE; docs = FALSE; timestamp = TRUE; /* Parse the command line. */ optnr = 1; while ((arg = parseopt(argc, argv, "hVa:b:ec:d:gI:j:km:op:Prs:t:Twx:X:z:", &flagFile, &optnr, &optarg)) != '\0') switch (arg) { case 'o': /* Generate docstrings. */ docs = TRUE; break; case 'p': /* The name of the consolidated module. */ consModule = optarg; break; case 'P': /* Enable the protected/public hack. */ protHack = TRUE; break; case 'a': /* Where to generate the API file. */ apiFile = optarg; break; case 'm': /* Where to generate the XML file. */ xmlFile = optarg; break; case 'b': /* Generate a build file. */ buildFile = optarg; break; case 'e': /* Enable exceptions. */ exceptions = TRUE; break; case 'g': /* Always release the GIL. */ releaseGIL = TRUE; break; case 'j': /* Generate the code in this number of parts. */ parts = parseInt(optarg,'j'); break; case 'z': /* Read a file for the next flags. */ if (flagFile != NULL) fatal("The -z flag cannot be specified in an argument file\n"); flagFile = optarg; break; case 'c': /* Where to generate the code. */ codeDir = optarg; break; case 'd': /* Where to generate the documentation. */ docFile = optarg; break; case 't': /* Which platform or version to generate code for. */ appendString(&versions,optarg); break; case 'T': /* Disable the timestamp in the header of generated files. */ 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 '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"); /* Parse the input file. */ parse(&spec, file, filename, versions, xfeatures, kwArgs, protHack); /* Verify and transform the parse tree. */ transform(&spec); /* Generate code. */ generateCode(&spec, codeDir, buildFile, docFile, srcSuffix, exceptions, tracing, releaseGIL, parts, versions, xfeatures, consModule, docs, timestamp); /* 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); /* All done. */ return 0; } /* * Parse the next command line argument - similar to UNIX getopts(). Allow a * flag to specify that a file contains further arguments. */ static char parseopt(int argc, char **argv, char *opts, char **flags, int *optnrp, char **optargp) { char arg, *op, *fname; int optnr; static FILE *fp = NULL; /* Deal with any file first. */ fname = *flags; if (fname != NULL && fp == NULL && (fp = fopen(fname,"r")) == NULL) fatal("Unable to open %s\n",fname); if (fp != NULL) { char buf[200], *cp, *fname; int ch; fname = *flags; cp = buf; while ((ch = fgetc(fp)) != EOF) { /* Skip leading whitespace. */ if (cp == buf && isspace(ch)) continue; if (ch == '\n') break; if (cp == &buf[sizeof (buf) - 1]) fatal("A flag in %s is too long\n",fname); *cp++ = (char)ch; } *cp = '\0'; if (ch == EOF) { fclose(fp); fp = NULL; *flags = NULL; } /* * Get the option character and any optional argument from the * line. */ if (buf[0] != '\0') { if (buf[0] != '-' || buf[1] == '\0') fatal("An non-flag was given in %s\n",fname); arg = buf[1]; /* Find any optional argument. */ for (cp = &buf[2]; *cp != '\0'; ++cp) if (!isspace(*cp)) break; if (*cp == '\0') cp = NULL; else cp = sipStrdup(cp); *optargp = cp; if ((op = strchr(opts,arg)) == NULL) fatal("An invalid flag was given in %s\n",fname); if (op[1] == ':' && cp == NULL) fatal("Missing flag argument in %s\n",fname); if (op[1] != ':' && cp != NULL) fatal("Unexpected flag argument in %s\n",fname); return arg; } } /* Check there is an argument and it is a switch. */ optnr = *optnrp; if (optnr >= argc || argv[optnr] == NULL || argv[optnr][0] != '-') return '\0'; /* Check it is a valid switch. */ arg = argv[optnr][1]; if (arg == '\0' || (op = strchr(opts,arg)) == NULL) usage(); /* Check for the switch parameter, if any. */ if (op[1] == ':') { if (argv[optnr][2] != '\0') { *optargp = &argv[optnr][2]; ++optnr; } else if (optnr + 1 >= argc || argv[optnr + 1] == NULL) usage(); else { *optargp = argv[optnr + 1]; optnr += 2; } } else if (argv[optnr][2] != '\0') usage(); else { *optargp = NULL; ++optnr; } *optnrp = optnr; return arg; } /* * Parse an integer option. */ static int parseInt(char *arg, char opt) { char *endptr; int val; val = strtol(arg, &endptr, 10); if (*arg == '\0' || *endptr != '\0') fatal("Invalid integer argument for -%c flag\n", opt); return val; } /* * Append a string to a list of them. */ void appendString(stringList **headp, const char *s) { stringList *sl; /* Create the new entry. */ sl = sipMalloc(sizeof (stringList)); sl -> s = s; sl -> next = NULL; /* Append it to the list. */ while (*headp != NULL) headp = &(*headp) -> next; *headp = sl; } /* * Display a warning message. */ void warning(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) start = TRUE; } /* * Display all or part of a one line error message describing a fatal error. * If the message is complete (it has a newline) then the program exits. */ void fatal(char *fmt,...) { static int start = TRUE; va_list ap; if (start) { fprintf(stderr,"%s: ",sipPackage); start = FALSE; } va_start(ap,fmt); vfprintf(stderr,fmt,ap); va_end(ap); if (strchr(fmt,'\n') != NULL) exit(1); } /* * Display the SIP version number on stdout and exit with zero exit status. */ static void version(void) { printf("%s\n",sipVersion); exit(0); } /* * Display the help message on stdout and exit with zero exit status. */ static void help(void) { printf( "Usage:\n" " %s [-h] [-V] [-a file] [-b file] [-c dir] [-d file] [-e] [-g] [-I dir] [-j #] [-k] [-m file] [-o] [-p module] [-P] [-r] [-s suffix] [-t tag] [-T] [-w] [-x feature] [-X id:file] [-z file] [file]\n" "where:\n" " -h display this help message\n" " -V display the %s version number\n" " -a file the name of the QScintilla API file [default not generated]\n" " -b file the name of the build file [default none generated]\n" " -c dir the name of the code directory [default not generated]\n" " -d file the name of the documentation file (deprecated) [default not generated]\n" " -e enable support for exceptions [default disabled]\n" " -g always release and reacquire the GIL [default only when specified]\n" " -I dir look in this directory when including files\n" " -j # split the generated code into # files [default 1 per class]\n" " -k support keyword arguments in functions and methods\n" " -m file the name of the XML export file [default not generated]\n" " -o enable the automatic generation of docstrings [default disabled]\n" " -p module the name of the consolidated module that this is a component of\n" " -P enable the protected/public hack\n" " -r generate code with tracing enabled [default disabled]\n" " -s suffix the suffix to use for C or C++ source files [default \".c\" or \".cpp\"]\n" " -t tag the version/platform to generate code for\n" " -T disable the timestamp in the header of generated files\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" " -z file the name of a file containing more command line flags\n" " file the name of the specification file [default stdin]\n" , sipPackage, sipPackage); exit(0); } /* * Display the usage message. */ static void usage(void) { fatal("Usage: %s [-h] [-V] [-a file] [-b file] [-c dir] [-d file] [-e] [-g] [-I dir] [-j #] [-k] [-m file] [-o] [-p module] [-P] [-r] [-s suffix] [-t tag] [-T] [-w] [-x feature] [-X id:file] [-z file] [file]\n", sipPackage); } sip-4.15.5/sipgen/metasrc/0000755000076500000240000000000012306074075015407 5ustar philstaff00000000000000sip-4.15.5/sipgen/metasrc/lexer.l0000644000076500000240000004743012261240746016713 0ustar philstaff00000000000000/* * The SIP lexer. * * Copyright (c) 2014 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 #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_DEFDOCSTRING;} ^[ \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]*%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;} :: {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;} 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; } \"[^"\n]*["\n] { /* A double-quoted string. */ char *dp, *sp; /* Copy the string without the quotes. */ yylval.text = sipMalloc(strlen(yytext) + 1); dp = yylval.text; sp = yytext; while (*sp != '\0') { if (*sp != '"') *dp++ = *sp; ++sp; } *dp = '\0'; return TK_STRING_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]*%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]*%Docstring { /* The start of a docstring block. */ codeIdx = 0; 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.15.5/sipgen/metasrc/parser.y0000644000076500000240000071433412302135557017110 0ustar philstaff00000000000000/* * The SIP parser. * * Copyright (c) 2014 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 stringList *neededQualifiers; /* The list of required qualifiers. */ static stringList *excludedQualifiers; /* The list of excluded qualifiers. */ static moduleDef *currentModule; /* The current module being parsed. */ static mappedTypeDef *currentMappedType; /* The current mapped type. */ static enumDef *currentEnum; /* The current enum being parsed. */ static int sectionFlags; /* The current section flags. */ static int currentOverIsVirt; /* Set if the overload is virtual. */ static int currentCtorIsExplicit; /* Set if the ctor is explicit. */ static int currentIsStatic; /* Set if the current is static. */ static int currentIsSignal; /* Set if the current is Q_SIGNAL. */ static int currentIsSlot; /* Set if the current is Q_SLOT. */ static int currentIsTemplate; /* Set if the current is a template. */ static char *previousFile; /* The file just parsed. */ static parserContext currentContext; /* The current context. */ static int skipStackPtr; /* The skip stack pointer. */ static int skipStack[MAX_NESTED_IF]; /* Stack of skip flags. */ static classDef *scopeStack[MAX_NESTED_SCOPE]; /* The scope stack. */ static int sectFlagsStack[MAX_NESTED_SCOPE]; /* The section flags stack. */ static int currentScopeIdx; /* The scope stack index. */ static int currentTimelineOrder; /* The current timeline order. */ static classList *currentSupers; /* The current super-class list. */ static 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); static classDef *findClassWithInterface(sipSpec *pt, ifaceFileDef *iff); static classDef *newClass(sipSpec *pt, ifaceFileType iftype, apiVersionRangeDef *api_range, scopedNameDef *snd, const char *virt_error_handler); static void finishClass(sipSpec *, moduleDef *, classDef *, optFlags *); static exceptionDef *findException(sipSpec *pt, scopedNameDef *fqname, int new); static mappedTypeDef *newMappedType(sipSpec *,argDef *, optFlags *); static enumDef *newEnum(sipSpec *pt, moduleDef *mod, mappedTypeDef *mt_scope, char *name, optFlags *of, int flags); static void instantiateClassTemplate(sipSpec *pt, moduleDef *mod, classDef *scope, scopedNameDef *fqname, classTmplDef *tcd, templateDef *td, const char *pyname); static void newTypedef(sipSpec *, moduleDef *, char *, argDef *, optFlags *); 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, codeBlock *); static void newFunction(sipSpec *, moduleDef *, classDef *, mappedTypeDef *, int, int, int, int, int, char *, signatureDef *, int, int, optFlags *, codeBlock *, codeBlock *, throwArgs *, signatureDef *, codeBlock *); static optFlag *findOptFlag(optFlags *flgs, const char *name); static optFlag *getOptFlag(optFlags *flgs, const char *name, flagType ft); static memberDef *findFunction(sipSpec *, moduleDef *, classDef *, mappedTypeDef *, const char *, int, int, int); static void checkAttributes(sipSpec *, moduleDef *, classDef *, mappedTypeDef *, const char *, int); static void newModule(FILE *fp, 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, const char *, qualType); static qualDef *allocQualifier(moduleDef *, int, int, const char *, qualType); static void newImport(const char *filename); static int timePeriod(const char *lname, const char *uname); static int platOrFeature(char *,int); static int notSkipping(void); static void getHooks(optFlags *,char **,char **); static int getTransfer(optFlags *optflgs); static int getReleaseGIL(optFlags *optflgs); static int getHoldGIL(optFlags *optflgs); static int getDeprecated(optFlags *optflgs); static int getAllowNone(optFlags *optflgs); static const char *getVirtErrorHandler(optFlags *optflgs); static const char *getDocType(optFlags *optflgs); static const char *getDocValue(optFlags *optflgs); static void templateSignature(signatureDef *sd, int result, classTmplDef *tcd, templateDef *td, classDef *ncd); static void templateType(argDef *ad, classTmplDef *tcd, templateDef *td, classDef *ncd); static int search_back(const char *end, const char *start, const char *target); static char *type2string(argDef *ad); static char *scopedNameToString(scopedNameDef *name); static void addUsedFromCode(sipSpec *pt, ifaceFileList **used, const char *sname); static int sameName(scopedNameDef *snd, const char *sname); static int stringFind(stringList *sl, const char *s); static void setModuleName(sipSpec *pt, moduleDef *mod, const char *fullname); static int foundInScope(scopedNameDef *fq_name, scopedNameDef *rel_name); static void defineClass(scopedNameDef *snd, classList *supers, optFlags *of); static classDef *completeClass(scopedNameDef *snd, optFlags *of, int has_def); static memberDef *instantiateTemplateMethods(memberDef *tmd, moduleDef *mod); static void instantiateTemplateEnums(sipSpec *pt, classTmplDef *tcd, templateDef *td, classDef *cd, ifaceFileList **used, scopedNameDef *type_names, scopedNameDef *type_values); static void instantiateTemplateVars(sipSpec *pt, classTmplDef *tcd, templateDef *td, classDef *cd, ifaceFileList **used, scopedNameDef *type_names, scopedNameDef *type_values); static void instantiateTemplateTypedefs(sipSpec *pt, classTmplDef *tcd, templateDef *td, classDef *cd); 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 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, codeBlock *docstring); static moduleDef *configureModule(sipSpec *pt, moduleDef *module, const char *filename, const char *name, int version, int c_module, KwArgs kwargs, int use_arg_names, int call_super_init, int all_raise_py_exc, const char *def_error_handler, codeBlock *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); %} %union { char qchar; char *text; long number; double real; argDef memArg; signatureDef signature; signatureDef *optsignature; throwArgs *throwlist; codeBlock *codeb; valueDef value; valueDef *valp; optFlags optflags; optFlag flag; scopedNameDef *scpvalp; fcallDef fcall; int boolean; exceptionDef exceptionbase; classDef *klass; apiCfg api; autoPyNameCfg autopyname; compModuleCfg compmodule; consModuleCfg consmodule; defDocstringCfg defdocstring; defEncodingCfg defencoding; defMetatypeCfg defmetatype; defSupertypeCfg defsupertype; 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_DEFDOCSTRING %token TK_DEFENCODING %token TK_PLUGIN %token TK_VIRTERRORHANDLER %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_METHODCODE %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_ELLIPSIS %token TK_DEFMETATYPE %token TK_DEFSUPERTYPE %token TK_PROPERTY %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_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 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 typecode %type codeblock %type codelines %type virtualcatchercode %type methodcode %type instancecode %type raisecode %type docstring %type optdocstring %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 optcast %type exprlist %type qualifiers %type oredqualifiers %type optclassbody %type bool_value %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 defdocstring_args %type defdocstring_arg_list %type defdocstring_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 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 | defdocstring | defencoding | defmetatype | defsupertype | exphdrcode | modhdrcode | modcode | preinitcode | initcode | postinitcode | unitcode | unitpostinccode | prepycode | 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); } } ; defdocstring: TK_DEFDOCSTRING defdocstring_args { if (notSkipping()) currentModule->defdocstring = convertFormat($2.name); } ; defdocstring_args: TK_STRING_VALUE { resetLexerState(); $$.name = $1; } | '(' defdocstring_arg_list ')' { $$ = $2; } ; defdocstring_arg_list: defdocstring_arg | defdocstring_arg_list ',' defdocstring_arg { $$ = $1; switch ($3.token) { case TK_NAME: $$.name = $3.name; break; } } ; defdocstring_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. */ 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 = currentModule->nrvirterrorhandlers++; 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; if (xd->bibase != NULL || xd->base != NULL) xd->exceptionnr = currentModule->nrexceptions++; } } ; baseexception: { $$.bibase = NULL; $$.base = NULL; } | '(' scopedname ')' { exceptionDef *xd; $$.bibase = NULL; $$.base = NULL; /* See if it is a defined exception. */ for (xd = currentSpec->exceptions; xd != NULL; xd = xd->next) if (compareScopedNames(xd->iff->fqcname, $2) == 0) { $$.base = xd; break; } if (xd == NULL && $2->next == NULL && strncmp($2->name, "SIP_", 4) == 0) { /* See if it is a builtin exception. */ static char *builtins[] = { "Exception", "StopIteration", "StandardError", "ArithmeticError", "LookupError", "AssertionError", "AttributeError", "EOFError", "FloatingPointError", "EnvironmentError", "IOError", "OSError", "ImportError", "IndexError", "KeyError", "KeyboardInterrupt", "MemoryError", "NameError", "OverflowError", "RuntimeError", "NotImplementedError", "SyntaxError", "IndentationError", "TabError", "ReferenceError", "SystemError", "SystemExit", "TypeError", "UnboundLocalError", "UnicodeError", "UnicodeEncodeError", "UnicodeDecodeError", "UnicodeTranslateError", "ValueError", "ZeroDivisionError", "WindowsError", "VMSError", NULL }; char **cp; for (cp = builtins; *cp != NULL; ++cp) if (strcmp($2->name + 4, *cp) == 0) { $$.bibase = *cp; break; } } if ($$.bibase == NULL && $$.base == NULL) yyerror("Unknown exception base type"); } ; 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", 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", 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"); /* 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 methodcode { if (notSkipping()) { applyTypeFlags(currentModule, &$2, &$9); $5.result = $2; newFunction(currentSpec, currentModule, NULL, currentMappedType, 0, TRUE, FALSE, FALSE, FALSE, $3, &$5, $7, FALSE, &$9, $13, NULL, $8, $10, $12); } } ; namespace: TK_NAMESPACE TK_NAME_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); 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,$1,platform_qualifier); } ; feature: TK_FEATURE feature_args { if (notSkipping()) newQualifier(currentModule, -1, -1, $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++, $1, time_qualifier); } ; ifstart: TK_IF '(' qualifiers ')' { if (skipStackPtr >= MAX_NESTED_IF) yyerror("Internal error: increase the value of MAX_NESTED_IF"); /* Nested %Ifs are implicit logical ands. */ if (skipStackPtr > 0) $3 = ($3 && skipStack[skipStackPtr - 1]); skipStack[skipStackPtr++] = $3; } ; oredqualifiers: TK_NAME_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 (skipStackPtr-- <= 0) yyerror("Too many %End directives"); } ; 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; } ; consmodule: TK_CONSMODULE consmodule_args consmodule_body { 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); appendCodeBlock(¤tModule->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); appendCodeBlock(¤tModule->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.version, $2.c_module, $2.kwargs, $2.use_arg_names, $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, $3, TRUE, defaultKwArgs, 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; $$.all_raise_py_exc = FALSE; $$.call_super_init = -1; $$.def_error_handler = NULL; $$.version = $3; } | '(' 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_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; case TK_VERSION: $$.version = $3.version; break; } } ; module_arg: TK_KWARGS '=' TK_STRING_VALUE { $$.token = TK_KWARGS; $$.c_module = FALSE; $$.kwargs = convertKwArgs($3); $$.name = NULL; $$.use_arg_names = FALSE; $$.all_raise_py_exc = FALSE; $$.call_super_init = -1; $$.def_error_handler = NULL; $$.version = -1; } | 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; $$.all_raise_py_exc = FALSE; $$.call_super_init = -1; $$.def_error_handler = NULL; $$.version = -1; } | TK_NAME '=' dottedname { $$.token = TK_NAME; $$.c_module = FALSE; $$.kwargs = defaultKwArgs; $$.name = $3; $$.use_arg_names = FALSE; $$.all_raise_py_exc = FALSE; $$.call_super_init = -1; $$.def_error_handler = NULL; $$.version = -1; } | TK_USEARGNAMES '=' bool_value { $$.token = TK_USEARGNAMES; $$.c_module = FALSE; $$.kwargs = defaultKwArgs; $$.name = NULL; $$.use_arg_names = $3; $$.all_raise_py_exc = FALSE; $$.call_super_init = -1; $$.def_error_handler = NULL; $$.version = -1; } | TK_ALLRAISEPYEXC '=' bool_value { $$.token = TK_ALLRAISEPYEXC; $$.c_module = FALSE; $$.kwargs = defaultKwArgs; $$.name = NULL; $$.use_arg_names = FALSE; $$.all_raise_py_exc = $3; $$.call_super_init = -1; $$.def_error_handler = NULL; $$.version = -1; } | TK_CALLSUPERINIT '=' bool_value { $$.token = TK_CALLSUPERINIT; $$.c_module = FALSE; $$.kwargs = defaultKwArgs; $$.name = NULL; $$.use_arg_names = FALSE; $$.all_raise_py_exc = FALSE; $$.call_super_init = $3; $$.def_error_handler = NULL; $$.version = -1; } | TK_DEFERRORHANDLER '=' TK_NAME_VALUE { $$.token = TK_DEFERRORHANDLER; $$.c_module = FALSE; $$.kwargs = defaultKwArgs; $$.name = NULL; $$.use_arg_names = FALSE; $$.all_raise_py_exc = FALSE; $$.call_super_init = -1; $$.def_error_handler = $3; $$.version = -1; } | TK_VERSION '=' TK_NUMBER_VALUE { if ($3 < 0) yyerror("%Module 'version' argument cannot be negative"); $$.token = TK_VERSION; $$.c_module = FALSE; $$.kwargs = defaultKwArgs; $$.name = NULL; $$.use_arg_names = FALSE; $$.all_raise_py_exc = FALSE; $$.call_super_init = -1; $$.def_error_handler = NULL; $$.version = $3; } ; 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. */ } ; 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 { $$ = $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 = $$->frag; *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. */ dp = cp = $$->frag; 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->defdocstring; } | TK_STRING_VALUE { resetLexerState(); $$.format = convertFormat($1); } | '(' 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; } } ; docstring_arg: TK_FORMAT '=' TK_STRING_VALUE { $$.token = TK_FORMAT; $$.format = convertFormat($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 optname optflags { if (notSkipping()) { const char *annos[] = { "NoScope", "PyName", NULL }; checkAnnos(&$3, annos); if (sectionFlags != 0 && (sectionFlags & ~(SECT_IS_PUBLIC | SECT_IS_PROT)) != 0) yyerror("Class enums must be in the public or protected sections"); currentEnum = newEnum(currentSpec, currentModule, currentMappedType, $2, &$3, sectionFlags); } } '{' optenumbody '}' ';' ; optfilename: { $$ = NULL; } | TK_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[] = { "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 -> ed = currentEnum; emd -> next = NULL; checkAttributes(currentSpec, currentModule, emd->ed->ecd, emd->ed->emtd, emd->pyname->text, FALSE); /* Append to preserve the order. */ for (tail = ¤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: scopepart | scopedname 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 ';' { if (notSkipping()) { const char *annos[] = { "Capsule", "DocType", "Encoding", "NoTypeName", "PyInt", "PyName", NULL }; checkAnnos(&$4, annos); applyTypeFlags(currentModule, &$2, &$4); newTypedef(currentSpec, currentModule, $3, &$2, &$4); } } | TK_TYPEDEF cpptype '(' '*' TK_NAME_VALUE ')' '(' cpptypelist ')' optflags ';' { if (notSkipping()) { const char *annos[] = { "DocType", "Encoding", "NoTypeName", "PyInt", "PyName", 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); } } ; 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", "Metatype", "Mixin", "NoDefaultCtors", "PyName", "PyQtFlags", "PyQtInterface", "PyQtNoQMetaObject", "Supertype", "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", "Metatype", "Mixin", "NoDefaultCtors", "PyName", "PyQtFlags", "PyQtInterface", "PyQtNoQMetaObject", "Supertype", "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"); /* * 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); 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 | exception | typedef | enum | property | docstring { if (notSkipping()) appendCodeBlock(¤tScope()->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); } } | 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 ';' 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); appendCodeBlock(&cd->dtorcode, $11); cd -> dtorexceptions = $6; /* * Note that we don't apply the protected/public hack to dtors * as it (I think) may change the behaviour of the wrapped API. */ cd->classflags |= sectionFlags; if ($7) { if (!$1) yyerror("Abstract destructor must be virtual"); setIsAbstractClass(cd); } /* * The class has a shadow if we have a virtual dtor or some * dtor code. */ if ($1 || $11 != NULL) { if (currentSpec -> genc) yyerror("Virtual destructor or %VirtualCatcherCode not allowed in a C module"); setHasShadow(cd); } if (getReleaseGIL(&$8)) setIsReleaseGILDtor(cd); else if (getHoldGIL(&$8)) setIsHoldGILDtor(cd); } } ; ctor: TK_EXPLICIT {currentCtorIsExplicit = TRUE;} simplector | simplector ; simplector: TK_NAME_VALUE '(' arglist ')' optexceptions optflags optctorsig ';' optdocstring methodcode { /* Note that we allow ctors in C modules. */ if (notSkipping()) { const char *annos[] = { "API", "Default", "Deprecated", "HoldGIL", "KeywordArgs", "NoDerived", "NoRaisesPyException", "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, $10, $5, $7, currentCtorIsExplicit, $9); } 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 optexceptions optabstract optflags optsig ';' optdocstring methodcode virtualcatchercode { if (notSkipping()) { applyTypeFlags(currentModule, &$1, &$9); $4.result = $1; newFunction(currentSpec, currentModule, currentScope(), NULL, sectionFlags, currentIsStatic, currentIsSignal, currentIsSlot, currentOverIsVirt, $2, &$4, $6, $8, &$9, $13, $14, $7, $10, $12); } currentIsStatic = FALSE; currentIsSignal = FALSE; currentIsSlot = FALSE; currentOverIsVirt = FALSE; } | cpptype TK_OPERATOR '=' '(' cpptype ')' ';' { /* * It looks like an assignment operator (though we don't bother to * check the types) so make sure it is private. */ if (notSkipping()) { classDef *cd = currentScope(); if (cd == NULL || !(sectionFlags & SECT_IS_PRIVATE)) yyerror("Assignment operators may only be defined as private"); setCannotAssign(cd); } currentIsStatic = FALSE; currentIsSignal = FALSE; currentIsSlot = FALSE; currentOverIsVirt = FALSE; } | cpptype TK_OPERATOR operatorname '(' arglist ')' optconst optexceptions optabstract optflags optsig ';' methodcode virtualcatchercode { if (notSkipping()) { classDef *cd = currentScope(); /* * If the scope is a namespace then make sure the operator is * handled as a global. */ if (cd != NULL && cd->iff->type == namespace_iface) cd = NULL; applyTypeFlags(currentModule, &$1, &$10); /* Handle the unary '+' and '-' operators. */ if ((cd != NULL && $5.nrArgs == 0) || (cd == NULL && $5.nrArgs == 1)) { if (strcmp($3, "__add__") == 0) $3 = "__pos__"; else if (strcmp($3, "__sub__") == 0) $3 = "__neg__"; } $5.result = $1; newFunction(currentSpec, currentModule, cd, NULL, sectionFlags, currentIsStatic, currentIsSignal, currentIsSlot, currentOverIsVirt, $3, &$5, $7, $9, &$10, $13, $14, $8, $11, NULL); } currentIsStatic = FALSE; currentIsSignal = FALSE; currentIsSlot = FALSE; currentOverIsVirt = FALSE; } | TK_OPERATOR cpptype '(' arglist ')' optconst optexceptions optabstract optflags optsig ';' methodcode virtualcatchercode { if (notSkipping()) { char *sname; classDef *scope = currentScope(); if (scope == NULL || $4.nrArgs != 0) yyerror("Operator casts must be specified in a class and have no arguments"); applyTypeFlags(currentModule, &$2, &$9); switch ($2.atype) { case defined_type: sname = NULL; break; case bool_type: case cbool_type: case 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, sectionFlags, currentIsStatic, currentIsSignal, currentIsSlot, currentOverIsVirt, sname, &$4, $6, $8, &$9, $12, $13, $7, $10, NULL); } else { argList *al; /* Check it doesn't already exist. */ for (al = scope->casts; al != NULL; al = al->next) if (compareScopedNames($2.u.snd, al->arg.u.snd) == 0) yyerror("This operator cast has already been specified in this class"); al = sipMalloc(sizeof (argList)); al->arg = $2; al->next = scope->casts; scope->casts = al; } } currentIsStatic = FALSE; currentIsSignal = FALSE; currentIsSlot = FALSE; currentOverIsVirt = FALSE; } ; operatorname: '+' {$$ = "__add__";} | '-' {$$ = "__sub__";} | '*' {$$ = "__mul__";} | '/' {$$ = "__div__";} | '%' {$$ = "__mod__";} | '&' {$$ = "__and__";} | '|' {$$ = "__or__";} | '^' {$$ = "__xor__";} | '<' '<' {$$ = "__lshift__";} | '>' '>' {$$ = "__rshift__";} | '+' '=' {$$ = "__iadd__";} | '-' '=' {$$ = "__isub__";} | '*' '=' {$$ = "__imul__";} | '/' '=' {$$ = "__idiv__";} | '%' '=' {$$ = "__imod__";} | '&' '=' {$$ = "__iand__";} | '|' '=' {$$ = "__ior__";} | '^' '=' {$$ = "__ixor__";} | '<' '<' '=' {$$ = "__ilshift__";} | '>' '>' '=' {$$ = "__irshift__";} | '~' {$$ = "__invert__";} | '(' ')' {$$ = "__call__";} | '[' ']' {$$ = "__getitem__";} | '<' {$$ = "__lt__";} | '<' '=' {$$ = "__le__";} | '=' '=' {$$ = "__eq__";} | '!' '=' {$$ = "__ne__";} | '>' {$$ = "__gt__";} | '>' '=' {$$ = "__ge__";} ; optconst: { $$ = FALSE; } | TK_CONST { $$ = TRUE; } ; optabstract: { $$ = 0; } | '=' TK_NUMBER_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; } ; methodcode: { $$ = NULL; } | TK_METHODCODE codeblock { $$ = $2; } ; virtualcatchercode: { $$ = NULL; } | TK_VIRTUALCATCHERCODE codeblock { $$ = $2; } ; arglist: rawarglist { int a, nrrxcon, nrrxdis, nrslotcon, nrslotdis, nrarray, nrarraysize; nrrxcon = nrrxdis = nrslotcon = nrslotdis = nrarray = nrarraysize = 0; for (a = 0; a < $1.nrArgs; ++a) { argDef *ad = &$1.args[a]; switch (ad -> atype) { case rxcon_type: ++nrrxcon; break; case rxdis_type: ++nrrxdis; break; case slotcon_type: ++nrslotcon; break; case slotdis_type: ++nrslotdis; break; } if (isArray(ad)) ++nrarray; if (isArraySize(ad)) ++nrarraysize; } if (nrrxcon != nrslotcon || nrrxcon > 1) yyerror("SIP_RXOBJ_CON and SIP_SLOT_CON must both be given and at most once"); if (nrrxdis != nrslotdis || nrrxdis > 1) yyerror("SIP_RXOBJ_DIS and SIP_SLOT_DIS must both be given and at most once"); if (nrarray != nrarraysize || nrarray > 1) yyerror("/Array/ and /ArraySize/ must both be given and at most once"); $$ = $1; } ; rawarglist: { /* No arguments. */ $$.nrArgs = 0; } | argvalue { /* The single or first argument. */ $$.args[0] = $1; $$.nrArgs = 1; } | rawarglist ',' argvalue { /* Check that it wasn't ...(,arg...). */ if ($1.nrArgs == 0) yyerror("First argument of the list is missing"); /* Check there is nothing after an ellipsis. */ if ($1.args[$1.nrArgs - 1].atype == ellipsis_type) yyerror("An ellipsis must be at the end of the argument list"); /* * If this argument has no default value, then the * previous one mustn't either. */ if ($3.defval == NULL && $1.args[$1.nrArgs - 1].defval != NULL) yyerror("Compulsory argument given after optional argument"); /* Check there is room. */ if ($1.nrArgs == MAX_NR_ARGS) yyerror("Internal error - increase the value of MAX_NR_ARGS"); $$ = $1; $$.args[$$.nrArgs] = $3; $$.nrArgs++; } ; argvalue: TK_SIPSIGNAL optname optflags optassign { 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 { 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 { 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 }; 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 { 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 { 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 { 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 { 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", "PyInt", "PyName", 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 a sub-directive"); } if ($7 != NULL) { if ($4.get_code != NULL) yyerror("%GetCode already defined"); $4.get_code = $7; deprecated("%GetCode should be used a sub-directive"); } if ($8 != NULL) { if ($4.set_code != NULL) yyerror("%SetCode already defined"); $4.set_code = $8; deprecated("%SetCode should be used 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 { int i; $$ = $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", "DocType", "DocValue", "Encoding", "GetWrapper", "In", "KeepReference", "NoCopy", "Out", "PyInt", "ResultSize", "Transfer", "TransferBack", "TransferThis", NULL }; checkAnnos(&$3, annos); $$ = $1; $$.name = cacheName(currentSpec, $2); handleKeepReference(&$3, &$$, currentModule); if (getAllowNone(&$3)) $$.argflags |= ARG_ALLOW_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; } } applyTypeFlags(currentModule, &$$, &$3); $$.docval = getDocValue(&$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, stringList *tsl, stringList *xfl, KwArgs kwArgs, int protHack) { classTmplDef *tcd; /* Initialise the spec. */ memset(spec, 0, sizeof (sipSpec)); spec->genc = -1; currentSpec = spec; neededQualifiers = tsl; excludedQualifiers = xfl; currentModule = NULL; currentMappedType = NULL; currentOverIsVirt = FALSE; currentCtorIsExplicit = FALSE; currentIsStatic = FALSE; currentIsSignal = FALSE; currentIsSlot = FALSE; currentIsTemplate = FALSE; previousFile = NULL; skipStackPtr = 0; currentScopeIdx = 0; sectionFlags = 0; 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->version = -1; newmod->defdocstring = raw; newmod->encoding = no_type; newmod->qobjclass = -1; newmod->nrvirthandlers = -1; /* -1 is reserved for variable getters. */ newmod->next_key = -2; /* * 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 = skipStackPtr; pc.prevmod = prevmod; if (setInputFile(fp, &pc, optional)) currentContext = pc; } /* * Find an interface file, or create a new one. */ ifaceFileDef *findIfaceFile(sipSpec *pt, moduleDef *mod, scopedNameDef *fqname, ifaceFileType iftype, apiVersionRangeDef *api_range, argDef *ad) { ifaceFileDef *iff, *first_alt = NULL; /* See if the name is already used. */ for (iff = pt->ifacefiles; iff != NULL; iff = iff->next) { if (compareScopedNames(iff->fqcname, fqname) != 0) continue; /* * If they are both versioned then assume the user knows what they are * doing. */ if (iff->api_range != NULL && api_range != NULL && iff->module == mod) { /* Remember the first of the alternate APIs. */ if ((first_alt = iff->first_alt) == NULL) first_alt = iff; break; } /* * They must be the same type except that we allow a class if we want * an exception. This is because we allow classes to be used before * they are defined. */ if (iff->type != iftype) if (iftype != exception_iface || iff->type != class_iface) yyerror("A class, exception, namespace or mapped type has already been defined with the same name"); /* Ignore an external class declared in another module. */ if (iftype == class_iface && iff->module != mod) { classDef *cd; for (cd = pt->classes; cd != NULL; cd = cd->next) if (cd->iff == iff) break; if (cd != NULL && iff->module != NULL && isExternal(cd)) continue; } /* * If this is a mapped type with the same name defined in a different * module, then check that this type isn't the same as any of the * mapped types defined in that module. */ if (iftype == mappedtype_iface && iff->module != mod) { mappedTypeDef *mtd; /* * This is a bit of a cheat. With consolidated modules it's * possible to have two implementations of a mapped type in * different branches of the module hierarchy. We assume that, if * there really are multiple implementations in the same branch, * then it will be picked up in a non-consolidated build. */ if (isConsolidated(pt->module)) continue; for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next) { if (mtd->iff != iff) continue; if (ad->atype != template_type || mtd->type.atype != template_type || sameBaseType(ad, &mtd->type)) yyerror("Mapped type has already been defined in another module"); } /* * If we got here then we have a mapped type based on an existing * template, but with unique parameters. We don't want to use * interface files from other modules, so skip this one. */ continue; } /* Ignore a namespace defined in another module. */ if (iftype == namespace_iface && iff->module != mod) continue; return iff; } iff = sipMalloc(sizeof (ifaceFileDef)); iff->name = cacheName(pt, scopedNameToString(fqname)); iff->api_range = api_range; if (first_alt != NULL) { iff->first_alt = first_alt; iff->next_alt = first_alt->next_alt; first_alt->next_alt = iff; } else { /* This is the first alternate so point to itself. */ iff->first_alt = iff; } iff->type = iftype; iff->ifacenr = -1; iff->fqcname = fqname; iff->module = NULL; iff->hdrcode = NULL; iff->used = NULL; iff->next = pt->ifacefiles; pt->ifacefiles = iff; return iff; } /* * Find a class definition in a parse tree. */ static classDef *findClass(sipSpec *pt, ifaceFileType iftype, apiVersionRangeDef *api_range, scopedNameDef *fqname) { return findClassWithInterface(pt, findIfaceFile(pt, currentModule, fqname, iftype, api_range, NULL)); } /* * Find a class definition given an existing interface file. */ static classDef *findClassWithInterface(sipSpec *pt, ifaceFileDef *iff) { classDef *cd; for (cd = pt -> classes; cd != NULL; cd = cd -> next) if (cd -> iff == iff) return cd; /* Create a new one. */ cd = sipMalloc(sizeof (classDef)); cd->iff = iff; cd->pyname = cacheName(pt, classBaseName(cd)); cd->next = pt->classes; pt->classes = cd; return cd; } /* * Add an interface file to an interface file list if it isn't already there. */ void addToUsedList(ifaceFileList **ifflp, ifaceFileDef *iff) { /* Make sure we don't try to add an interface file to its own list. */ if (&iff->used != ifflp) { ifaceFileList *iffl; while ((iffl = *ifflp) != NULL) { /* Don't bother if it is already there. */ if (iffl->iff == iff) return; ifflp = &iffl -> next; } iffl = sipMalloc(sizeof (ifaceFileList)); iffl->iff = iff; iffl->next = NULL; *ifflp = iffl; } } /* * Find an undefined (or create a new) exception definition in a parse tree. */ static exceptionDef *findException(sipSpec *pt, scopedNameDef *fqname, int new) { exceptionDef *xd, **tail; ifaceFileDef *iff; classDef *cd; iff = findIfaceFile(pt, currentModule, fqname, exception_iface, NULL, NULL); /* See if it is an existing one. */ for (xd = pt->exceptions; xd != NULL; xd = xd->next) if (xd->iff == iff) return xd; /* * If it is an exception interface file then we have never seen this name * before. We require that exceptions are defined before being used, but * don't make the same requirement of classes (for reasons of backwards * compatibility). Therefore the name must be reinterpreted as a (as yet * undefined) class. */ if (new) { if (iff->type == exception_iface) cd = NULL; else yyerror("There is already a class with the same name or the exception has been used before being defined"); } else { if (iff->type == exception_iface) iff->type = class_iface; cd = findClassWithInterface(pt, iff); } /* Create a new one. */ xd = sipMalloc(sizeof (exceptionDef)); xd->exceptionnr = -1; xd->iff = iff; xd->pyname = NULL; xd->cd = cd; xd->bibase = NULL; xd->base = NULL; xd->raisecode = NULL; xd->next = NULL; /* Append it to the list. */ for (tail = &pt->exceptions; *tail != NULL; tail = &(*tail)->next) ; *tail = xd; return xd; } /* * Find an undefined (or create a new) class definition in a parse tree. */ static classDef *newClass(sipSpec *pt, ifaceFileType iftype, apiVersionRangeDef *api_range, scopedNameDef *fqname, const char *virt_error_handler) { 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) setHasShadow(scope); } /* Header code from outer scopes is also included. */ hdrcode = scope->iff->hdrcode; } else hdrcode = NULL; if (pt -> genc) { /* C structs are always global types. */ while (fqname -> next != NULL) fqname = fqname -> next; scope = NULL; } cd = findClass(pt, iftype, api_range, fqname); /* Check it hasn't already been defined. */ if (iftype != namespace_iface && cd->iff->module != NULL) yyerror("The struct/class has already been defined"); /* Complete the initialisation. */ cd->classflags |= flags; cd->ecd = scope; cd->iff->module = currentModule; cd->virt_error_handler = virt_error_handler; 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; 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); 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, "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; } 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; } } } if (inMainModule()) { setIsUsedName(cd->iff->name); setIsUsedName(cd->pyname); } } /* * Return the encoded name of a template (ie. including its argument types) as * a scoped name. */ scopedNameDef *encodedTemplateName(templateDef *td) { int a; scopedNameDef *snd; snd = copyScopedName(td->fqname); for (a = 0; a < td->types.nrArgs; ++a) { char buf[50]; int flgs; scopedNameDef *arg_snd; argDef *ad = &td->types.args[a]; flgs = 0; if (isConstArg(ad)) flgs += 1; if (isReference(ad)) flgs += 2; /* We use numbers so they don't conflict with names. */ sprintf(buf, "%02d%d%d", ad->atype, flgs, ad->nrderefs); switch (ad->atype) { case defined_type: arg_snd = copyScopedName(ad->u.snd); break; case template_type: arg_snd = encodedTemplateName(ad->u.td); break; case struct_type: arg_snd = copyScopedName(ad->u.sname); break; default: arg_snd = NULL; } /* * Replace the first element of the argument name with a copy with the * encoding prepended. */ if (arg_snd != NULL) arg_snd->name = concat(buf, arg_snd->name, NULL); else arg_snd = text2scopePart(sipStrdup(buf)); appendScopedName(&snd, arg_snd); } return snd; } /* * Create a new mapped type. */ static mappedTypeDef *newMappedType(sipSpec *pt, argDef *ad, optFlags *of) { mappedTypeDef *mtd; scopedNameDef *snd; ifaceFileDef *iff; const char *cname; /* Check that the type is one we want to map. */ switch (ad->atype) { case defined_type: snd = ad->u.snd; cname = scopedNameTail(snd); break; case template_type: snd = encodedTemplateName(ad->u.td); cname = NULL; break; case struct_type: snd = ad->u.sname; cname = scopedNameTail(snd); break; default: yyerror("Invalid type for %MappedType"); } iff = findIfaceFile(pt, currentModule, snd, mappedtype_iface, getAPIRange(of), ad); /* Check it hasn't already been defined. */ for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next) if (mtd->iff == iff) { /* * We allow types based on the same template but with different * arguments. */ if (ad->atype != template_type || sameBaseType(ad, &mtd->type)) yyerror("Mapped type has already been defined in this module"); } /* The module may not have been set yet. */ iff->module = currentModule; /* Create a new mapped type. */ mtd = allocMappedType(pt, ad); if (cname != NULL) mtd->pyname = cacheName(pt, getPythonName(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)); return mtd; } /* * Create a new enum. */ static enumDef *newEnum(sipSpec *pt, moduleDef *mod, mappedTypeDef *mt_scope, char *name, optFlags *of, int flags) { enumDef *ed, *first_alt, *next_alt; classDef *c_scope; ifaceFileDef *scope; if (mt_scope != NULL) { scope = mt_scope->iff; c_scope = NULL; } else { if ((c_scope = currentScope()) != NULL) scope = c_scope->iff; else scope = NULL; } ed = sipMalloc(sizeof (enumDef)); /* Assume the enum isn't versioned. */ first_alt = ed; next_alt = NULL; if (name != NULL) { ed->pyname = cacheName(pt, getPythonName(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) { setHasShadow(c_scope); } } ed->enumflags = flags; ed->enumnr = -1; ed->ecd = c_scope; ed->emtd = mt_scope; ed->first_alt = first_alt; ed->next_alt = next_alt; ed->module = mod; ed->members = NULL; ed->slots = NULL; ed->overs = NULL; ed->next = pt -> enums; pt->enums = ed; if (getOptFlag(of, "NoScope", bool_flag) != NULL) setIsNoScope(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; } /* * Convert a scoped name to a string on the heap. */ static char *scopedNameToString(scopedNameDef *name) { static const char scope_string[] = "::"; size_t len; scopedNameDef *snd; char *s, *dp; /* Work out the length of buffer needed. */ len = 0; for (snd = name; snd != NULL; snd = snd->next) { len += strlen(snd->name); if (snd->next != NULL) { /* Ignore the encoded part of template names. */ if (isdigit(snd->next->name[0])) break; len += strlen(scope_string); } } /* Allocate and populate the buffer. */ dp = s = sipMalloc(len + 1); for (snd = name; snd != NULL; snd = snd->next) { strcpy(dp, snd->name); dp += strlen(snd->name); if (snd->next != NULL) { /* Ignore the encoded part of template names. */ if (isdigit(snd->next->name[0])) break; strcpy(dp, scope_string); dp += strlen(scope_string); } } return s; } /* * Instantiate a class template. */ static void instantiateClassTemplate(sipSpec *pt, moduleDef *mod, classDef *scope, scopedNameDef *fqname, classTmplDef *tcd, templateDef *td, const char *pyname) { 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; resetIsTemplateClass(cd); cd->pyname = cacheName(pt, pyname); cd->td = td; /* Handle the interface file. */ cd->iff = findIfaceFile(pt, mod, fqname, class_iface, (scope != NULL ? scope->iff->api_range : NULL), NULL); cd->iff->module = mod; 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) addToUsedList(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 the super-classes. */ for (cl = cd->supers; cl != NULL; cl = cl->next) { const char *name; int a; /* Ignore defined or scoped classes. */ if (cl->cd->iff->module != NULL || cl->cd->iff->fqcname->next != NULL) continue; name = cl->cd->iff->fqcname->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]; classDef *icd; if (tad->atype == defined_type) icd = findClass(pt, class_iface, NULL, tad->u.snd); else if (tad->atype == class_type) icd = tad->u.cd; else fatal("Template argument %s must expand to a class\n", name); /* * Don't complain about the template argument being undefined. */ setTemplateArg(cl->cd); 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); /* Handle the ctors. */ cd->ctors = NULL; cttail = &cd->ctors; for (oct = tcd->cd->ctors; oct != NULL; oct = oct->next) { ctorDef *nct = sipMalloc(sizeof (ctorDef)); /* Start with a shallow copy. */ *nct = *oct; templateSignature(&nct->pysig, FALSE, tcd, td, cd); if (oct->cppsig == NULL) nct->cppsig = NULL; else if (oct->cppsig == &oct->pysig) nct->cppsig = &nct->pysig; else { nct->cppsig = sipMalloc(sizeof (signatureDef)); *nct->cppsig = *oct->cppsig; templateSignature(nct->cppsig, FALSE, tcd, td, cd); } nct->methodcode = templateCode(pt, used, nct->methodcode, type_names, type_values); nct->next = NULL; *cttail = nct; cttail = &nct->next; /* Handle the default ctor. */ if (tcd->cd->defctor == oct) cd->defctor = nct; } cd->dealloccode = templateCode(pt, used, cd->dealloccode, type_names, type_values); cd->dtorcode = templateCode(pt, used, cd->dtorcode, type_names, type_values); /* Handle the methods. */ cd->members = instantiateTemplateMethods(tcd->cd->members, mod); cd->overs = instantiateTemplateOverloads(pt, tcd->cd->overs, tcd->cd->members, cd->members, tcd, td, cd, used, type_names, type_values); cd->cppcode = templateCode(pt, used, cd->cppcode, type_names, type_values); cd->iff->hdrcode = templateCode(pt, used, cd->iff->hdrcode, type_names, type_values); cd->convtosubcode = templateCode(pt, used, cd->convtosubcode, type_names, type_values); cd->convtocode = templateCode(pt, used, cd->convtocode, type_names, type_values); cd->travcode = templateCode(pt, used, cd->travcode, type_names, type_values); cd->clearcode = templateCode(pt, used, cd->clearcode, type_names, type_values); cd->getbufcode = templateCode(pt, used, cd->getbufcode, type_names, type_values); cd->releasebufcode = templateCode(pt, used, cd->releasebufcode, type_names, type_values); cd->readbufcode = templateCode(pt, used, cd->readbufcode, type_names, type_values); cd->writebufcode = templateCode(pt, used, cd->writebufcode, type_names, type_values); cd->segcountcode = templateCode(pt, used, cd->segcountcode, type_names, type_values); cd->charbufcode = templateCode(pt, used, cd->charbufcode, type_names, type_values); cd->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->next = pt->classes; pt->classes = cd; tcd->sig.nrArgs--; freeScopedName(type_names); freeScopedName(type_values); } /* * Instantiate the methods of a template class. */ static memberDef *instantiateTemplateMethods(memberDef *tmd, moduleDef *mod) { memberDef *md, *methods, **mdtail; methods = NULL; mdtail = &methods; for (md = tmd; md != NULL; md = md->next) { memberDef *nmd = sipMalloc(sizeof (memberDef)); /* Start with a shallow copy. */ *nmd = *md; nmd->module = mod; if (inMainModule()) setIsUsedName(nmd->pyname); nmd->next = NULL; *mdtail = nmd; mdtail = &nmd->next; } return methods; } /* * Instantiate the overloads of a template class. */ static overDef *instantiateTemplateOverloads(sipSpec *pt, overDef *tod, memberDef *tmethods, memberDef *methods, classTmplDef *tcd, templateDef *td, classDef *cd, ifaceFileList **used, scopedNameDef *type_names, scopedNameDef *type_values) { overDef *od, *overloads, **odtail; overloads = NULL; odtail = &overloads; for (od = tod; od != NULL; od = od->next) { overDef *nod = sipMalloc(sizeof (overDef)); memberDef *nmd, *omd; /* Start with a shallow copy. */ *nod = *od; for (nmd = methods, omd = tmethods; omd != NULL; omd = omd->next, nmd = nmd->next) if (omd == od->common) { nod->common = nmd; break; } templateSignature(&nod->pysig, TRUE, tcd, td, cd); if (od->cppsig == &od->pysig) nod->cppsig = &nod->pysig; else { nod->cppsig = sipMalloc(sizeof (signatureDef)); *nod->cppsig = *od->cppsig; templateSignature(nod->cppsig, TRUE, tcd, td, cd); } nod->methodcode = templateCode(pt, used, nod->methodcode, type_names, type_values); /* Handle any virtual handler. */ if (od->virthandler != NULL) { moduleDef *mod = cd->iff->module; nod->virthandler = sipMalloc(sizeof (virtHandlerDef)); /* Start with a shallow copy. */ *nod->virthandler = *od->virthandler; nod->virthandler->pysig = &nod->pysig; nod->virthandler->cppsig = nod->cppsig; nod->virthandler->module = mod; nod->virthandler->virtcode = templateCode(pt, used, nod->virthandler->virtcode, type_names, type_values); nod->virthandler->next = mod->virthandlers; mod->virthandlers = nod->virthandler; } nod->next = NULL; *odtail = nod; odtail = &nod->next; } return overloads; } /* * Instantiate the enums of a template class. */ static void instantiateTemplateEnums(sipSpec *pt, classTmplDef *tcd, templateDef *td, classDef *cd, ifaceFileList **used, scopedNameDef *type_names, scopedNameDef *type_values) { enumDef *ted; moduleDef *mod = cd->iff->module; for (ted = pt->enums; ted != NULL; ted = ted->next) if (ted->ecd == tcd->cd) { enumDef *ed; enumMemberDef *temd; ed = sipMalloc(sizeof (enumDef)); /* Start with a shallow copy. */ *ed = *ted; if (ed->fqcname != NULL) { ed->fqcname = text2scopedName(cd->iff, scopedNameTail(ed->fqcname)); ed->cname = cacheName(pt, scopedNameToString(ed->fqcname)); } if (inMainModule()) { if (ed->pyname != NULL) setIsUsedName(ed->pyname); if (ed->cname != NULL) setIsUsedName(ed->cname); } ed->ecd = cd; ed->first_alt = ed; ed->module = mod; ed->members = NULL; for (temd = ted->members; temd != NULL; temd = temd->next) { enumMemberDef *emd; emd = sipMalloc(sizeof (enumMemberDef)); /* Start with a shallow copy. */ *emd = *temd; emd->ed = ed; emd->next = ed->members; ed->members = emd; } ed->slots = instantiateTemplateMethods(ted->slots, mod); ed->overs = instantiateTemplateOverloads(pt, ted->overs, ted->slots, ed->slots, tcd, td, cd, used, type_names, type_values); ed->next = pt->enums; pt->enums = ed; } } /* * Instantiate the variables of a template class. */ static void instantiateTemplateVars(sipSpec *pt, classTmplDef *tcd, templateDef *td, classDef *cd, ifaceFileList **used, scopedNameDef *type_names, scopedNameDef *type_values) { varDef *tvd; for (tvd = pt->vars; tvd != NULL; tvd = tvd->next) if (tvd->ecd == tcd->cd) { varDef *vd; vd = sipMalloc(sizeof (varDef)); /* Start with a shallow copy. */ *vd = *tvd; if (inMainModule()) setIsUsedName(vd->pyname); vd->fqcname = text2scopedName(cd->iff, scopedNameTail(vd->fqcname)); vd->ecd = cd; vd->module = cd->iff->module; templateType(&vd->type, tcd, td, cd); vd->accessfunc = templateCode(pt, used, vd->accessfunc, type_names, type_values); vd->getcode = templateCode(pt, used, vd->getcode, type_names, type_values); vd->setcode = templateCode(pt, used, vd->setcode, type_names, type_values); addVariable(pt, vd); } } /* * Instantiate the typedefs of a template class. */ static void instantiateTemplateTypedefs(sipSpec *pt, classTmplDef *tcd, templateDef *td, classDef *cd) { 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); addTypedef(pt, new_tdd); } } /* * Replace any template arguments in a signature. */ static void templateSignature(signatureDef *sd, int result, classTmplDef *tcd, templateDef *td, classDef *ncd) { int a; if (result) templateType(&sd->result, tcd, td, ncd); for (a = 0; a < sd->nrArgs; ++a) templateType(&sd->args[a], tcd, td, ncd); } /* * Replace any template arguments in a type. */ static void templateType(argDef *ad, classTmplDef *tcd, templateDef *td, classDef *ncd) { int a; char *name; /* Descend into any sub-templates. */ if (ad->atype == template_type) { templateDef *new_td = sipMalloc(sizeof (templateDef)); /* Make a deep copy of the template definition. */ *new_td = *ad->u.td; ad->u.td = new_td; templateSignature(&ad->u.td->types, FALSE, tcd, td, ncd); return; } /* Ignore if it isn't an unscoped name. */ if (ad->atype != defined_type || ad->u.snd->next != NULL) return; name = ad->u.snd->name; for (a = 0; a < tcd->sig.nrArgs - 1; ++a) if (strcmp(name, scopedNameTail(tcd->sig.args[a].u.snd)) == 0) { argDef *tad = &td->types.args[a]; ad->atype = tad->atype; /* We take the constrained flag from the real type. */ resetIsConstrained(ad); if (isConstrained(tad)) setIsConstrained(ad); ad->u = tad->u; return; } /* Handle the class name itself. */ if (strcmp(name, scopedNameTail(classFQCName(tcd->cd))) == 0) { ad->atype = class_type; ad->u.cd = ncd; ad->original_type = NULL; } } /* * Replace any template arguments in a literal code block. */ 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; /* * 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)) { addToUsedList(used, iff); return; } } for (ed = pt->enums; ed != NULL; ed = ed->next) { if (ed->ecd == NULL) continue; if (sameName(ed->fqcname, sname)) { addToUsedList(used, ed->ecd->iff); return; } } } /* * Compare a scoped name with its string equivalent. */ static int sameName(scopedNameDef *snd, const char *sname) { while (snd != NULL && *sname != '\0') { const char *sp = snd->name; while (*sp != '\0' && *sname != ':' && *sname != '\0') if (*sp++ != *sname++) return FALSE; if (*sp != '\0' || (*sname != ':' && *sname != '\0')) return FALSE; snd = snd->next; if (*sname == ':') sname += 2; } return (snd == NULL && *sname == '\0'); } /* * Compare a (possibly) relative scoped name with a fully qualified scoped name * while taking the current scope into account. */ static int foundInScope(scopedNameDef *fq_name, scopedNameDef *rel_name) { classDef *scope; for (scope = currentScope(); scope != NULL; scope = scope->ecd) { scopedNameDef *snd; int found; snd = copyScopedName(classFQCName(scope)); appendScopedName(&snd, copyScopedName(rel_name)); found = (compareScopedNames(fq_name, snd) == 0); freeScopedName(snd); if (found) return TRUE; } return compareScopedNames(fq_name, rel_name) == 0; } /* * Create a new typedef. */ static void newTypedef(sipSpec *pt, moduleDef *mod, char *name, argDef *type, optFlags *optflgs) { typedefDef *td; scopedNameDef *fqname; classDef *scope; scope = currentScope(); fqname = text2scopedName((scope != NULL ? scope->iff : NULL), name); /* See if we are instantiating a template class. */ if (type->atype == template_type) { classTmplDef *tcd; templateDef *td = type->u.td; for (tcd = pt->classtemplates; tcd != NULL; tcd = tcd->next) if (foundInScope(tcd->cd->iff->fqcname, td->fqname) && sameTemplateSignature(&tcd->sig, &td->types, FALSE)) { instantiateClassTemplate(pt, mod, scope, fqname, tcd, td, getPythonName(mod, optflgs, name)); /* All done. */ return; } } td = sipMalloc(sizeof (typedefDef)); td->tdflags = 0; td->fqname = fqname; td->ecd = scope; td->module = mod; 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 (getOptFlag(optflgs, "NoTypeName", bool_flag) != NULL) 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 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) { 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->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); 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, codeBlock *docstring) { ctorDef *ct, **ctp; classDef *cd = currentScope(); /* Check the name of the constructor. */ if (strcmp(classBaseName(cd), name) != 0) yyerror("Constructor doesn't have the same name as its class"); if (docstring != NULL) appendCodeBlock(&cd->docstring, docstring); /* Add to the list of constructors. */ ct = sipMalloc(sizeof (ctorDef)); if (sectFlags & SECT_IS_PROT && makeProtPublic) { sectFlags &= ~SECT_IS_PROT; sectFlags |= SECT_IS_PUBLIC; } /* Allow the signature to be used like an function signature. */ memset(&args->result, 0, sizeof (argDef)); args->result.atype = void_type; ct->ctorflags = sectFlags; ct->api_range = getAPIRange(optflgs); ct->pysig = *args; ct->cppsig = (cppsig != NULL ? cppsig : &ct->pysig); ct->exceptions = exceptions; appendCodeBlock(&ct->methodcode, methodcode); if (!isPrivateCtor(ct)) setCanCreate(cd); if (isProtectedCtor(ct)) setHasShadow(cd); if (explicit) setIsExplicitCtor(ct); getHooks(optflgs, &ct->prehook, &ct->posthook); if (getReleaseGIL(optflgs)) setIsReleaseGILCtor(ct); else if (getHoldGIL(optflgs)) setIsHoldGILCtor(ct); if (getTransfer(optflgs)) setIsResultTransferredCtor(ct); if (getDeprecated(optflgs)) setIsDeprecatedCtor(ct); if (!isPrivateCtor(ct)) 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, mappedTypeDef *mt_scope, int sflags, int isstatic, int issignal, int isslot, int isvirt, char *name, signatureDef *sig, int isconst, int isabstract, optFlags *optflgs, codeBlock *methodcode, codeBlock *vcode, throwArgs *exceptions, signatureDef *cppsig, codeBlock *docstring) { static const char *annos[] = { "__len__", "API", "AutoGen", "Deprecated", "DocType", "Encoding", "Factory", "HoldGIL", "KeywordArgs", "KeepReference", "NewThread", "NoArgParser", "NoCopy", "NoRaisesPyException", "NoVirtualErrorHandler", "Numeric", "PostHook", "PreHook", "PyInt", "PyName", "PyQtSignalHack", "RaisesPyException", "ReleaseGIL", "Sequence", "VirtualErrorHandler", "Transfer", "TransferBack", "TransferThis", NULL }; const char *pyname, *virt_error_handler; int factory, xferback, no_arg_parser, no_virt_error_handler; overDef *od, **odp, **headp; optFlag *of; virtHandlerDef *vhd; 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__", 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); } 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)) setHasShadow(c_scope); if ((isSlot(od) || isSignal(od)) && !isPrivate(od)) { if (isSignal(od)) setHasShadow(c_scope); pt->sigslots = TRUE; } if (isSignal(od) && (methodcode != NULL || vcode != NULL)) yyerror("Cannot provide code for signals"); if (isstatic) { if (isSignal(od)) yyerror("Static functions cannot be signals"); if (isvirt) yyerror("Static functions cannot be virtual"); setIsStatic(od); } if (isconst) setIsConst(od); if (isabstract) { if (sflags == 0) yyerror("Non-class function specified as abstract"); setIsAbstract(od); } if ((of = 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 (isSignal(od) && pluginPyQt3(pt)) yyerror("Virtual signals aren't supported"); setIsVirtual(od); setHasShadow(c_scope); vhd = sipMalloc(sizeof (virtHandlerDef)); vhd->virthandlernr = -1; vhd->vhflags = 0; vhd->pysig = &od->pysig; vhd->cppsig = (cppsig != NULL ? cppsig : &od->pysig); appendCodeBlock(&vhd->virtcode, vcode); if (factory || xferback) setIsTransferVH(vhd); 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; } /* * Only add it to the module's virtual handlers if we are not in a * class template. */ if (!currentIsTemplate) { vhd->module = mod; vhd->next = mod->virthandlers; mod->virthandlers = vhd; } } else { if (vcode != NULL) yyerror("%VirtualCatcherCode provided for non-virtual function"); if (virt_error_handler != NULL) yyerror("/VirtualErrorHandler/ provided for non-virtual function"); if (no_virt_error_handler) yyerror("/NoVirtualErrorHandler/ provided for non-virtual function"); vhd = NULL; } od->cppname = name; od->pysig = *sig; od->cppsig = (cppsig != NULL ? cppsig : &od->pysig); od->exceptions = exceptions; appendCodeBlock(&od->methodcode, methodcode); od->virthandler = vhd; 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"); } if (getOptFlag(optflgs, "NoCopy", bool_flag) != NULL) setNoCopy(&od->pysig.result); handleKeepReference(optflgs, &od->pysig.result, mod); pyname = getPythonName(mod, optflgs, name); od->common = findFunction(pt, mod, c_scope, mt_scope, pyname, (methodcode != NULL), sig->nrArgs, no_arg_parser); if (isProtected(od)) setHasProtected(od->common); if (strcmp(pyname, "__delattr__") == 0) setIsDelattr(od); if (docstring != NULL) appendCodeBlock(&od->common->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); } } } } /* See if we want to auto-generate a __len__() method. */ 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; len->common = findFunction(pt, mod, c_scope, mt_scope, len->cppname, TRUE, 0, FALSE); if ((len->methodcode = od->methodcode) == NULL) { char *buf = sipStrdup(" sipRes = (SIP_SSIZE_T)sipCpp->"); codeBlock *code; append(&buf, od->cppname); append(&buf, "();\n"); code = sipMalloc(sizeof (codeBlock)); code->frag = buf; code->filename = "Auto-generated"; code->linenr = 1; appendCodeBlock(&len->methodcode, code); } len->next = NULL; od->next = len; } else { od->next = NULL; } /* Append to the list. */ for (odp = headp; *odp != NULL; odp = &(*odp)->next) ; *odp = od; } /* * Return the Python name based on the C/C++ name and any /PyName/ annotation. */ static const char *getPythonName(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, 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}, {NULL} }; memberDef *md, **flist; struct slot_map *sm; slotType st; /* Get the slot type. */ st = no_slot; for (sm = slot_table; sm->name != NULL; ++sm) if (strcmp(sm->name, pname) == 0) { if (sm->needs_hwcode && !hwcode) yyerror("This Python slot requires %MethodCode"); if (sm->nrargs >= 0) { if (mt_scope == NULL && c_scope == NULL) { /* Global operators need one extra argument. */ if (sm -> nrargs + 1 != nrargs) yyerror("Incorrect number of arguments to global operator"); } else if (sm->nrargs != nrargs) yyerror("Incorrect number of arguments to Python slot"); } st = sm->type; break; } /* Check there is no name clash. */ checkAttributes(pt, mod, c_scope, mt_scope, pname, TRUE); /* See if it already exists. */ if (mt_scope != NULL) flist = &mt_scope->members; else if (c_scope != NULL) flist = &c_scope->members; else flist = &mod->othfuncs; /* __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->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; /* Check the enums. */ for (ed = pt->enums; ed != NULL; ed = ed->next) { enumMemberDef *emd; if (ed->pyname == NULL) continue; if (py_c_scope != NULL) { if (ed->ecd != py_c_scope) continue; } else if (py_mt_scope != NULL) { if (ed->emtd != py_mt_scope) continue; } else if (ed->ecd != NULL || ed->emtd != NULL) { continue; } if (strcmp(ed->pyname->text, attr) == 0) yyerror("There is already an enum in scope with the same Python name"); for (emd = ed->members; emd != NULL; emd = emd->next) if (strcmp(emd->pyname->text, attr) == 0) yyerror("There is already an enum member in scope with the same Python name"); } /* * Only check the members if this attribute isn't a member because we * can handle members with the same name in the same scope. */ if (!isfunc) { memberDef *md, *membs; overDef *overs; if (py_mt_scope != NULL) { membs = py_mt_scope->members; overs = py_mt_scope->overs; } else if (py_c_scope != NULL) { membs = py_c_scope->members; overs = py_c_scope->overs; } else { membs = mod->othfuncs; overs = mod->overs; } for (md = membs; md != NULL; md = md->next) { overDef *od; if (strcmp(md->pyname->text, attr) != 0) continue; /* Check for a conflict with all overloads. */ for (od = overs; od != NULL; od = od->next) { if (od->common != md) continue; yyerror("There is already a function in scope with the same Python name"); } } } /* If the scope was a mapped type then that's all we have to check. */ if (py_mt_scope != NULL) return; /* Check the variables. */ for (vd = pt->vars; vd != NULL; vd = vd->next) { if (vd->ecd != py_c_scope) continue; if (strcmp(vd->pyname->text,attr) == 0) yyerror("There is already a variable in scope with the same Python name"); } /* Check the classes. */ for (cd = pt->classes; cd != NULL; cd = cd->next) { if (cd->ecd != py_c_scope || cd->pyname == NULL) continue; if (strcmp(cd->pyname->text, attr) == 0 && !isExternal(cd)) yyerror("There is already a class or namespace in scope with the same Python name"); } /* Check the exceptions. */ if (py_c_scope == NULL) { exceptionDef *xd; for (xd = pt->exceptions; xd != NULL; xd = xd->next) if (xd->pyname != NULL && strcmp(xd->pyname, attr) == 0) yyerror("There is already an exception with the same Python name"); } /* 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 (skipStackPtr > currentContext.ifdepth) fatal("Too many %%If statements in %s\n", previousFile); if (skipStackPtr < currentContext.ifdepth) fatal("Too many %%End statements in %s\n", previousFile); } /* * Handle the end of a fully parsed a module. */ static void handleEOM() { moduleDef *from; /* Check it has been named. */ if (currentModule->name == NULL) fatal("No %%Module has been specified for module defined in %s\n", previousFile); from = currentContext.prevmod; if (from != NULL) { 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, 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) : NULL); appendScopedName(&snd, name); return snd; } /* * Return a pointer to the tail part of a scoped name. */ char *scopedNameTail(scopedNameDef *snd) { if (snd == NULL) return NULL; while (snd -> next != NULL) snd = snd -> next; return snd -> name; } /* * Push the given scope onto the scope stack. */ static void pushScope(classDef *scope) { if (currentScopeIdx >= MAX_NESTED_SCOPE) fatal("Internal error: increase the value of MAX_NESTED_SCOPE\n"); scopeStack[currentScopeIdx] = scope; sectFlagsStack[currentScopeIdx] = sectionFlags; ++currentScopeIdx; } /* * Pop the scope stack. */ static void popScope(void) { if (currentScopeIdx > 0) sectionFlags = sectFlagsStack[--currentScopeIdx]; } /* * Return non-zero if the current input should be parsed rather than be * skipped. */ static int notSkipping() { return (skipStackPtr == 0 ? TRUE : skipStack[skipStackPtr - 1]); } /* * Return the value of an expression involving a time period. */ static int timePeriod(const char *lname, const char *uname) { int this, line; qualDef *qd, *lower, *upper; moduleDef *mod; if (lname == NULL) lower = NULL; else if ((lower = findQualifier(lname)) == NULL || lower->qtype != time_qualifier) yyerror("Lower bound is not a time version"); if (uname == NULL) upper = NULL; else if ((upper = findQualifier(uname)) == NULL || upper->qtype != time_qualifier) yyerror("Upper bound is not a time version"); /* Sanity checks on the bounds. */ if (lower == NULL && upper == NULL) yyerror("Lower and upper bounds cannot both be omitted"); if (lower != NULL && upper != NULL) { if (lower->module != upper->module || lower->line != upper->line) yyerror("Lower and upper bounds are from different timelines"); if (lower == upper) yyerror("Lower and upper bounds must be different"); if (lower->order > upper->order) yyerror("Later version specified as lower bound"); } /* Go through each slot in the relevant timeline. */ if (lower != NULL) { mod = lower->module; line = lower->line; } else { mod = upper->module; line = upper->line; } /* Handle the SIP version number pseudo-timeline. */ if (line < 0) { if (lower != NULL && lower->order > SIP_VERSION) return FALSE; if (upper != NULL && upper->order <= SIP_VERSION) return FALSE; return TRUE; } this = FALSE; for (qd = mod->qualifiers; qd != NULL; qd = qd->next) { if (qd->qtype != time_qualifier || qd->line != line) continue; if (lower != NULL && qd->order < lower->order) continue; if (upper != NULL && qd->order >= upper->order) continue; /* * This is within the required range so if it is also needed then the * expression is true. */ if (selectedQualifier(neededQualifiers, qd)) { this = TRUE; break; } } return this; } /* * Return the value of an expression involving a single platform or feature. */ static int platOrFeature(char *name,int optnot) { int this; qualDef *qd; if ((qd = findQualifier(name)) == NULL || qd -> qtype == time_qualifier) yyerror("No such platform or feature"); /* Assume this sub-expression is false. */ this = FALSE; if (qd -> qtype == feature_qualifier) { if (!excludedFeature(excludedQualifiers,qd)) this = TRUE; } else if (selectedQualifier(neededQualifiers, qd)) this = TRUE; if (optnot) this = !this; return this; } /* * Return TRUE if the given qualifier is excluded. */ int excludedFeature(stringList *xsl,qualDef *qd) { while (xsl != NULL) { if (strcmp(qd -> name,xsl -> s) == 0) return TRUE; xsl = xsl -> next; } return FALSE; } /* * Return TRUE if the given qualifier is needed. */ 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 TRUE; return FALSE; } /* * Return the current scope. currentScope() is only valid if notSkipping() * returns non-zero. */ static classDef *currentScope(void) { return (currentScopeIdx > 0 ? scopeStack[currentScopeIdx - 1] : NULL); } /* * Create a new qualifier. */ static void newQualifier(moduleDef *mod, int line, int order, const char *name, qualType qt) { /* Check it doesn't already exist. */ if (findQualifier(name) != NULL) yyerror("Version is already defined"); allocQualifier(mod, line, order, name, qt); } /* * Allocate a new qualifier. */ static qualDef *allocQualifier(moduleDef *mod, int line, int order, 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->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 /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; return of->fvalue.sval; } /* * Get the /DocValue/ option flag. */ static const char *getDocValue(optFlags *optflgs) { optFlag *of = getOptFlag(optflgs, "DocValue", string_flag); if (of == NULL) return NULL; return of->fvalue.sval; } /* * Return TRUE if the PyQt3 plugin was specified. */ int pluginPyQt3(sipSpec *pt) { return stringFind(pt->plugins, "PyQt3"); } /* * Return TRUE if the PyQt4 plugin was specified. */ int pluginPyQt4(sipSpec *pt) { return stringFind(pt->plugins, "PyQt4"); } /* * Return TRUE if 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, *c_scope = currentScope(); cd = newClass(currentSpec, class_iface, getAPIRange(of), scopeScopedName((c_scope != NULL ? c_scope->iff : NULL), snd), getVirtErrorHandler(of)); cd->supers = supers; pushScope(cd); } /* * Complete the definition of a class. */ static classDef *completeClass(scopedNameDef *snd, optFlags *of, int has_def) { classDef *cd = currentScope(); /* See if the class was defined or just declared. */ if (has_def) { if (snd->next != NULL) yyerror("A scoped name cannot be given in a class/struct definition"); } else if (cd->supers != NULL) yyerror("Class/struct has super-classes but no definition"); else setIsOpaque(cd); finishClass(currentSpec, currentModule, cd, of); popScope(); /* * Check that external classes have only been declared at the global scope. */ if (isExternal(cd) && currentScope() != NULL) yyerror("External classes/structs can only be declared in the global scope"); return cd; } /* * Add a variable to the list so that the list remains sorted. */ static void addVariable(sipSpec *pt, varDef *vd) { varDef **at = &pt->vars; while (*at != NULL) { if (strcmp(vd->pyname->text, (*at)->pyname->text) < 0) break; at = &(*at)->next; } vd->next = *at; *at = vd; } /* * Update a type according to optional flags. */ static void applyTypeFlags(moduleDef *mod, argDef *ad, optFlags *flags) { ad->doctype = getDocType(flags); if (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 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, codeBlock *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; appendCodeBlock(&pd->docstring, docstring); 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 version, int c_module, KwArgs kwargs, int use_arg_names, int call_super_init, int all_raise_py_exc, const char *def_error_handler, codeBlock *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->version = version; appendCodeBlock(&module->docstring, docstring); if (all_raise_py_exc) setAllRaisePyException(module); if (use_arg_names) setUseArgNames(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) deprecated("Annotation is invalid"); } } } /* * 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); } /* * 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]; } } sip-4.15.5/sipgen/metasrc/README0000644000076500000240000000072712260016054016265 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.15.5/sipgen/parser.c0000644000076500000240000142075512310606636015426 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_DEFDOCSTRING = 260, TK_DEFENCODING = 261, TK_PLUGIN = 262, TK_VIRTERRORHANDLER = 263, TK_DOCSTRING = 264, TK_DOC = 265, TK_EXPORTEDDOC = 266, TK_EXTRACT = 267, TK_MAKEFILE = 268, TK_ACCESSCODE = 269, TK_GETCODE = 270, TK_SETCODE = 271, TK_PREINITCODE = 272, TK_INITCODE = 273, TK_POSTINITCODE = 274, TK_FINALCODE = 275, TK_UNITCODE = 276, TK_UNITPOSTINCLUDECODE = 277, TK_MODCODE = 278, TK_TYPECODE = 279, TK_PREPYCODE = 280, TK_COPYING = 281, TK_MAPPEDTYPE = 282, TK_CODELINE = 283, TK_IF = 284, TK_END = 285, TK_NAME_VALUE = 286, TK_PATH_VALUE = 287, TK_STRING_VALUE = 288, TK_VIRTUALCATCHERCODE = 289, TK_TRAVERSECODE = 290, TK_CLEARCODE = 291, TK_GETBUFFERCODE = 292, TK_RELEASEBUFFERCODE = 293, TK_READBUFFERCODE = 294, TK_WRITEBUFFERCODE = 295, TK_SEGCOUNTCODE = 296, TK_CHARBUFFERCODE = 297, TK_PICKLECODE = 298, TK_METHODCODE = 299, TK_INSTANCECODE = 300, TK_FROMTYPE = 301, TK_TOTYPE = 302, TK_TOSUBCLASS = 303, TK_INCLUDE = 304, TK_OPTINCLUDE = 305, TK_IMPORT = 306, TK_EXPHEADERCODE = 307, TK_MODHEADERCODE = 308, TK_TYPEHEADERCODE = 309, TK_MODULE = 310, TK_CMODULE = 311, TK_CONSMODULE = 312, TK_COMPOMODULE = 313, TK_CLASS = 314, TK_STRUCT = 315, TK_PUBLIC = 316, TK_PROTECTED = 317, TK_PRIVATE = 318, TK_SIGNALS = 319, TK_SIGNAL_METHOD = 320, TK_SLOTS = 321, TK_SLOT_METHOD = 322, TK_BOOL = 323, TK_SHORT = 324, TK_INT = 325, TK_LONG = 326, TK_FLOAT = 327, TK_DOUBLE = 328, TK_CHAR = 329, TK_WCHAR_T = 330, TK_VOID = 331, TK_PYOBJECT = 332, TK_PYTUPLE = 333, TK_PYLIST = 334, TK_PYDICT = 335, TK_PYCALLABLE = 336, TK_PYSLICE = 337, TK_PYTYPE = 338, TK_PYBUFFER = 339, TK_VIRTUAL = 340, TK_ENUM = 341, TK_SIGNED = 342, TK_UNSIGNED = 343, TK_SCOPE = 344, TK_LOGICAL_OR = 345, TK_CONST = 346, TK_STATIC = 347, TK_SIPSIGNAL = 348, TK_SIPSLOT = 349, TK_SIPANYSLOT = 350, TK_SIPRXCON = 351, TK_SIPRXDIS = 352, TK_SIPSLOTCON = 353, TK_SIPSLOTDIS = 354, TK_SIPSSIZET = 355, TK_NUMBER_VALUE = 356, TK_REAL_VALUE = 357, TK_TYPEDEF = 358, TK_NAMESPACE = 359, TK_TIMELINE = 360, TK_PLATFORMS = 361, TK_FEATURE = 362, TK_LICENSE = 363, TK_QCHAR_VALUE = 364, TK_TRUE_VALUE = 365, TK_FALSE_VALUE = 366, TK_NULL_VALUE = 367, TK_OPERATOR = 368, TK_THROW = 369, TK_QOBJECT = 370, TK_EXCEPTION = 371, TK_RAISECODE = 372, TK_VIRTERRORCODE = 373, TK_EXPLICIT = 374, TK_TEMPLATE = 375, TK_ELLIPSIS = 376, TK_DEFMETATYPE = 377, TK_DEFSUPERTYPE = 378, TK_PROPERTY = 379, TK_FORMAT = 380, TK_GET = 381, TK_ID = 382, TK_KWARGS = 383, TK_LANGUAGE = 384, TK_LICENSEE = 385, TK_NAME = 386, TK_OPTIONAL = 387, TK_ORDER = 388, TK_REMOVELEADING = 389, TK_SET = 390, TK_SIGNATURE = 391, TK_TIMESTAMP = 392, TK_TYPE = 393, TK_USEARGNAMES = 394, TK_ALLRAISEPYEXC = 395, TK_CALLSUPERINIT = 396, TK_DEFERRORHANDLER = 397, TK_VERSION = 398 }; #endif /* Tokens. */ #define TK_API 258 #define TK_AUTOPYNAME 259 #define TK_DEFDOCSTRING 260 #define TK_DEFENCODING 261 #define TK_PLUGIN 262 #define TK_VIRTERRORHANDLER 263 #define TK_DOCSTRING 264 #define TK_DOC 265 #define TK_EXPORTEDDOC 266 #define TK_EXTRACT 267 #define TK_MAKEFILE 268 #define TK_ACCESSCODE 269 #define TK_GETCODE 270 #define TK_SETCODE 271 #define TK_PREINITCODE 272 #define TK_INITCODE 273 #define TK_POSTINITCODE 274 #define TK_FINALCODE 275 #define TK_UNITCODE 276 #define TK_UNITPOSTINCLUDECODE 277 #define TK_MODCODE 278 #define TK_TYPECODE 279 #define TK_PREPYCODE 280 #define TK_COPYING 281 #define TK_MAPPEDTYPE 282 #define TK_CODELINE 283 #define TK_IF 284 #define TK_END 285 #define TK_NAME_VALUE 286 #define TK_PATH_VALUE 287 #define TK_STRING_VALUE 288 #define TK_VIRTUALCATCHERCODE 289 #define TK_TRAVERSECODE 290 #define TK_CLEARCODE 291 #define TK_GETBUFFERCODE 292 #define TK_RELEASEBUFFERCODE 293 #define TK_READBUFFERCODE 294 #define TK_WRITEBUFFERCODE 295 #define TK_SEGCOUNTCODE 296 #define TK_CHARBUFFERCODE 297 #define TK_PICKLECODE 298 #define TK_METHODCODE 299 #define TK_INSTANCECODE 300 #define TK_FROMTYPE 301 #define TK_TOTYPE 302 #define TK_TOSUBCLASS 303 #define TK_INCLUDE 304 #define TK_OPTINCLUDE 305 #define TK_IMPORT 306 #define TK_EXPHEADERCODE 307 #define TK_MODHEADERCODE 308 #define TK_TYPEHEADERCODE 309 #define TK_MODULE 310 #define TK_CMODULE 311 #define TK_CONSMODULE 312 #define TK_COMPOMODULE 313 #define TK_CLASS 314 #define TK_STRUCT 315 #define TK_PUBLIC 316 #define TK_PROTECTED 317 #define TK_PRIVATE 318 #define TK_SIGNALS 319 #define TK_SIGNAL_METHOD 320 #define TK_SLOTS 321 #define TK_SLOT_METHOD 322 #define TK_BOOL 323 #define TK_SHORT 324 #define TK_INT 325 #define TK_LONG 326 #define TK_FLOAT 327 #define TK_DOUBLE 328 #define TK_CHAR 329 #define TK_WCHAR_T 330 #define TK_VOID 331 #define TK_PYOBJECT 332 #define TK_PYTUPLE 333 #define TK_PYLIST 334 #define TK_PYDICT 335 #define TK_PYCALLABLE 336 #define TK_PYSLICE 337 #define TK_PYTYPE 338 #define TK_PYBUFFER 339 #define TK_VIRTUAL 340 #define TK_ENUM 341 #define TK_SIGNED 342 #define TK_UNSIGNED 343 #define TK_SCOPE 344 #define TK_LOGICAL_OR 345 #define TK_CONST 346 #define TK_STATIC 347 #define TK_SIPSIGNAL 348 #define TK_SIPSLOT 349 #define TK_SIPANYSLOT 350 #define TK_SIPRXCON 351 #define TK_SIPRXDIS 352 #define TK_SIPSLOTCON 353 #define TK_SIPSLOTDIS 354 #define TK_SIPSSIZET 355 #define TK_NUMBER_VALUE 356 #define TK_REAL_VALUE 357 #define TK_TYPEDEF 358 #define TK_NAMESPACE 359 #define TK_TIMELINE 360 #define TK_PLATFORMS 361 #define TK_FEATURE 362 #define TK_LICENSE 363 #define TK_QCHAR_VALUE 364 #define TK_TRUE_VALUE 365 #define TK_FALSE_VALUE 366 #define TK_NULL_VALUE 367 #define TK_OPERATOR 368 #define TK_THROW 369 #define TK_QOBJECT 370 #define TK_EXCEPTION 371 #define TK_RAISECODE 372 #define TK_VIRTERRORCODE 373 #define TK_EXPLICIT 374 #define TK_TEMPLATE 375 #define TK_ELLIPSIS 376 #define TK_DEFMETATYPE 377 #define TK_DEFSUPERTYPE 378 #define TK_PROPERTY 379 #define TK_FORMAT 380 #define TK_GET 381 #define TK_ID 382 #define TK_KWARGS 383 #define TK_LANGUAGE 384 #define TK_LICENSEE 385 #define TK_NAME 386 #define TK_OPTIONAL 387 #define TK_ORDER 388 #define TK_REMOVELEADING 389 #define TK_SET 390 #define TK_SIGNATURE 391 #define TK_TIMESTAMP 392 #define TK_TYPE 393 #define TK_USEARGNAMES 394 #define TK_ALLRAISEPYEXC 395 #define TK_CALLSUPERINIT 396 #define TK_DEFERRORHANDLER 397 #define TK_VERSION 398 /* Copy the first part of user declarations. */ #line 19 "/Users/phil/hg/sip/sip-4.15.5/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 stringList *neededQualifiers; /* The list of required qualifiers. */ static stringList *excludedQualifiers; /* The list of excluded qualifiers. */ static moduleDef *currentModule; /* The current module being parsed. */ static mappedTypeDef *currentMappedType; /* The current mapped type. */ static enumDef *currentEnum; /* The current enum being parsed. */ static int sectionFlags; /* The current section flags. */ static int currentOverIsVirt; /* Set if the overload is virtual. */ static int currentCtorIsExplicit; /* Set if the ctor is explicit. */ static int currentIsStatic; /* Set if the current is static. */ static int currentIsSignal; /* Set if the current is Q_SIGNAL. */ static int currentIsSlot; /* Set if the current is Q_SLOT. */ static int currentIsTemplate; /* Set if the current is a template. */ static char *previousFile; /* The file just parsed. */ static parserContext currentContext; /* The current context. */ static int skipStackPtr; /* The skip stack pointer. */ static int skipStack[MAX_NESTED_IF]; /* Stack of skip flags. */ static classDef *scopeStack[MAX_NESTED_SCOPE]; /* The scope stack. */ static int sectFlagsStack[MAX_NESTED_SCOPE]; /* The section flags stack. */ static int currentScopeIdx; /* The scope stack index. */ static int currentTimelineOrder; /* The current timeline order. */ static classList *currentSupers; /* The current super-class list. */ static 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); static classDef *findClassWithInterface(sipSpec *pt, ifaceFileDef *iff); static classDef *newClass(sipSpec *pt, ifaceFileType iftype, apiVersionRangeDef *api_range, scopedNameDef *snd, const char *virt_error_handler); static void finishClass(sipSpec *, moduleDef *, classDef *, optFlags *); static exceptionDef *findException(sipSpec *pt, scopedNameDef *fqname, int new); static mappedTypeDef *newMappedType(sipSpec *,argDef *, optFlags *); static enumDef *newEnum(sipSpec *pt, moduleDef *mod, mappedTypeDef *mt_scope, char *name, optFlags *of, int flags); static void instantiateClassTemplate(sipSpec *pt, moduleDef *mod, classDef *scope, scopedNameDef *fqname, classTmplDef *tcd, templateDef *td, const char *pyname); static void newTypedef(sipSpec *, moduleDef *, char *, argDef *, optFlags *); 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, codeBlock *); static void newFunction(sipSpec *, moduleDef *, classDef *, mappedTypeDef *, int, int, int, int, int, char *, signatureDef *, int, int, optFlags *, codeBlock *, codeBlock *, throwArgs *, signatureDef *, codeBlock *); static optFlag *findOptFlag(optFlags *flgs, const char *name); static optFlag *getOptFlag(optFlags *flgs, const char *name, flagType ft); static memberDef *findFunction(sipSpec *, moduleDef *, classDef *, mappedTypeDef *, const char *, int, int, int); static void checkAttributes(sipSpec *, moduleDef *, classDef *, mappedTypeDef *, const char *, int); static void newModule(FILE *fp, 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, const char *, qualType); static qualDef *allocQualifier(moduleDef *, int, int, const char *, qualType); static void newImport(const char *filename); static int timePeriod(const char *lname, const char *uname); static int platOrFeature(char *,int); static int notSkipping(void); static void getHooks(optFlags *,char **,char **); static int getTransfer(optFlags *optflgs); static int getReleaseGIL(optFlags *optflgs); static int getHoldGIL(optFlags *optflgs); static int getDeprecated(optFlags *optflgs); static int getAllowNone(optFlags *optflgs); static const char *getVirtErrorHandler(optFlags *optflgs); static const char *getDocType(optFlags *optflgs); static const char *getDocValue(optFlags *optflgs); static void templateSignature(signatureDef *sd, int result, classTmplDef *tcd, templateDef *td, classDef *ncd); static void templateType(argDef *ad, classTmplDef *tcd, templateDef *td, classDef *ncd); static int search_back(const char *end, const char *start, const char *target); static char *type2string(argDef *ad); static char *scopedNameToString(scopedNameDef *name); static void addUsedFromCode(sipSpec *pt, ifaceFileList **used, const char *sname); static int sameName(scopedNameDef *snd, const char *sname); static int stringFind(stringList *sl, const char *s); static void setModuleName(sipSpec *pt, moduleDef *mod, const char *fullname); static int foundInScope(scopedNameDef *fq_name, scopedNameDef *rel_name); static void defineClass(scopedNameDef *snd, classList *supers, optFlags *of); static classDef *completeClass(scopedNameDef *snd, optFlags *of, int has_def); static memberDef *instantiateTemplateMethods(memberDef *tmd, moduleDef *mod); static void instantiateTemplateEnums(sipSpec *pt, classTmplDef *tcd, templateDef *td, classDef *cd, ifaceFileList **used, scopedNameDef *type_names, scopedNameDef *type_values); static void instantiateTemplateVars(sipSpec *pt, classTmplDef *tcd, templateDef *td, classDef *cd, ifaceFileList **used, scopedNameDef *type_names, scopedNameDef *type_values); static void instantiateTemplateTypedefs(sipSpec *pt, classTmplDef *tcd, templateDef *td, classDef *cd); 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 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, codeBlock *docstring); static moduleDef *configureModule(sipSpec *pt, moduleDef *module, const char *filename, const char *name, int version, int c_module, KwArgs kwargs, int use_arg_names, int call_super_init, int all_raise_py_exc, const char *def_error_handler, codeBlock *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); /* 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 179 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { char qchar; char *text; long number; double real; argDef memArg; signatureDef signature; signatureDef *optsignature; throwArgs *throwlist; codeBlock *codeb; valueDef value; valueDef *valp; optFlags optflags; optFlag flag; scopedNameDef *scpvalp; fcallDef fcall; int boolean; exceptionDef exceptionbase; classDef *klass; apiCfg api; autoPyNameCfg autopyname; compModuleCfg compmodule; consModuleCfg consmodule; defDocstringCfg defdocstring; defEncodingCfg defencoding; defMetatypeCfg defmetatype; defSupertypeCfg defsupertype; 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 584 "/Users/phil/hg/sip/sip-4.15.5/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 597 "/Users/phil/hg/sip/sip-4.15.5/sipgen/parser.c" #ifdef short # undef short #endif #ifdef YYTYPE_UINT8 typedef YYTYPE_UINT8 yytype_uint8; #else typedef unsigned char yytype_uint8; #endif #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; #elif (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) typedef signed char yytype_int8; #else typedef short int yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else typedef unsigned short int yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else typedef short int yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include /* 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 1582 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 166 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 237 /* YYNRULES -- Number of rules. */ #define YYNRULES 558 /* YYNRULES -- Number of states. */ #define YYNSTATES 974 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 398 #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, 151, 2, 2, 2, 164, 156, 2, 144, 145, 154, 153, 146, 152, 2, 155, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 161, 150, 159, 147, 160, 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, 162, 2, 163, 165, 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, 148, 157, 149, 158, 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 }; #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, 107, 109, 113, 115, 119, 123, 126, 128, 132, 134, 138, 142, 145, 147, 151, 153, 157, 161, 165, 167, 171, 173, 177, 181, 184, 187, 191, 193, 197, 201, 205, 211, 212, 216, 221, 223, 226, 228, 230, 232, 234, 237, 238, 244, 245, 252, 257, 259, 262, 264, 266, 268, 270, 273, 276, 278, 280, 282, 296, 297, 303, 304, 308, 310, 313, 314, 320, 322, 325, 327, 330, 332, 336, 338, 342, 346, 347, 353, 355, 358, 360, 365, 367, 370, 374, 379, 381, 385, 387, 391, 392, 394, 398, 400, 404, 408, 412, 416, 420, 423, 425, 429, 431, 435, 439, 442, 444, 448, 450, 454, 458, 462, 464, 468, 470, 474, 478, 479, 484, 486, 489, 491, 493, 495, 499, 501, 505, 507, 511, 515, 516, 521, 523, 526, 528, 530, 532, 536, 540, 541, 545, 549, 551, 555, 559, 563, 567, 571, 575, 579, 583, 587, 588, 593, 595, 598, 600, 602, 604, 606, 608, 610, 611, 613, 616, 618, 622, 624, 628, 632, 636, 639, 642, 644, 648, 650, 654, 658, 659, 662, 663, 666, 667, 670, 673, 676, 679, 682, 685, 688, 691, 694, 697, 700, 703, 706, 709, 712, 715, 718, 721, 724, 727, 730, 733, 736, 739, 742, 745, 748, 752, 754, 758, 762, 766, 767, 769, 773, 775, 779, 783, 784, 786, 790, 792, 796, 798, 802, 806, 810, 815, 818, 820, 823, 824, 833, 834, 836, 837, 839, 840, 842, 844, 847, 849, 851, 856, 857, 859, 860, 863, 864, 867, 869, 873, 875, 877, 879, 881, 883, 885, 886, 888, 890, 892, 894, 896, 898, 902, 903, 907, 909, 913, 915, 917, 919, 921, 926, 928, 930, 932, 934, 936, 938, 939, 941, 945, 951, 963, 964, 965, 974, 975, 979, 984, 985, 986, 995, 996, 999, 1001, 1005, 1008, 1009, 1011, 1013, 1015, 1016, 1020, 1022, 1025, 1027, 1029, 1031, 1033, 1035, 1037, 1039, 1041, 1043, 1045, 1047, 1049, 1051, 1053, 1055, 1057, 1059, 1061, 1063, 1065, 1067, 1069, 1071, 1073, 1075, 1077, 1080, 1083, 1086, 1090, 1094, 1098, 1101, 1105, 1109, 1111, 1115, 1119, 1123, 1127, 1128, 1133, 1135, 1138, 1140, 1142, 1144, 1146, 1148, 1149, 1151, 1163, 1164, 1168, 1170, 1181, 1182, 1183, 1190, 1191, 1192, 1200, 1201, 1203, 1218, 1226, 1241, 1255, 1257, 1259, 1261, 1263, 1265, 1267, 1269, 1271, 1274, 1277, 1280, 1283, 1286, 1289, 1292, 1295, 1298, 1301, 1305, 1309, 1311, 1314, 1317, 1319, 1322, 1325, 1328, 1330, 1333, 1334, 1336, 1337, 1340, 1341, 1345, 1347, 1351, 1353, 1357, 1359, 1365, 1367, 1369, 1370, 1373, 1374, 1377, 1379, 1380, 1382, 1386, 1391, 1396, 1401, 1405, 1409, 1416, 1423, 1427, 1430, 1431, 1435, 1436, 1440, 1442, 1443, 1447, 1449, 1451, 1453, 1454, 1458, 1460, 1469, 1470, 1474, 1476, 1479, 1481, 1483, 1486, 1489, 1492, 1497, 1501, 1505, 1506, 1508, 1509, 1513, 1516, 1518, 1523, 1526, 1529, 1531, 1533, 1536, 1538, 1540, 1543, 1546, 1550, 1552, 1554, 1556, 1559, 1562, 1564, 1566, 1568, 1570, 1572, 1574, 1576, 1578, 1580, 1582, 1584, 1586, 1588, 1590, 1594, 1595, 1600, 1601, 1603 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int16 yyrhs[] = { 167, 0, -1, 168, -1, 167, 168, -1, -1, 169, 170, -1, 252, -1, 238, -1, 245, -1, 180, -1, 274, -1, 262, -1, 266, -1, 267, -1, 188, -1, 218, -1, 210, -1, 214, -1, 226, -1, 172, -1, 176, -1, 230, -1, 234, -1, 275, -1, 276, -1, 289, -1, 291, -1, 292, -1, 293, -1, 294, -1, 295, -1, 296, -1, 297, -1, 298, -1, 308, -1, 312, -1, 198, -1, 200, -1, 184, -1, 171, -1, 222, -1, 225, -1, 206, -1, 336, -1, 342, -1, 339, -1, 192, -1, 335, -1, 315, -1, 370, -1, 391, -1, 277, -1, 5, 173, -1, 33, -1, 144, 174, 145, -1, 175, -1, 174, 146, 175, -1, 131, 147, 33, -1, 6, 177, -1, 33, -1, 144, 178, 145, -1, 179, -1, 178, 146, 179, -1, 131, 147, 33, -1, 7, 181, -1, 31, -1, 144, 182, 145, -1, 183, -1, 182, 146, 183, -1, 131, 147, 31, -1, 8, 185, 313, -1, 31, -1, 144, 186, 145, -1, 187, -1, 186, 146, 187, -1, 131, 147, 31, -1, 3, 189, -1, 31, 101, -1, 144, 190, 145, -1, 191, -1, 190, 146, 191, -1, 131, 147, 359, -1, 143, 147, 101, -1, 116, 330, 193, 374, 194, -1, -1, 144, 330, 145, -1, 148, 195, 149, 150, -1, 196, -1, 195, 196, -1, 222, -1, 225, -1, 197, -1, 277, -1, 117, 313, -1, -1, 27, 399, 374, 199, 202, -1, -1, 341, 27, 399, 374, 201, 202, -1, 148, 203, 149, 150, -1, 204, -1, 203, 204, -1, 222, -1, 225, -1, 277, -1, 290, -1, 46, 313, -1, 47, 313, -1, 286, -1, 315, -1, 205, -1, 92, 395, 31, 144, 380, 145, 372, 401, 374, 367, 150, 307, 378, -1, -1, 104, 31, 207, 208, 150, -1, -1, 148, 209, 149, -1, 171, -1, 209, 171, -1, -1, 106, 211, 148, 212, 149, -1, 213, -1, 212, 213, -1, 31, -1, 107, 215, -1, 31, -1, 144, 216, 145, -1, 217, -1, 216, 146, 217, -1, 131, 147, 359, -1, -1, 105, 219, 148, 220, 149, -1, 221, -1, 220, 221, -1, 31, -1, 29, 144, 224, 145, -1, 31, -1, 151, 31, -1, 223, 90, 31, -1, 223, 90, 151, 31, -1, 223, -1, 318, 152, 318, -1, 30, -1, 108, 227, 374, -1, -1, 33, -1, 144, 228, 145, -1, 229, -1, 228, 146, 229, -1, 138, 147, 33, -1, 130, 147, 33, -1, 136, 147, 33, -1, 137, 147, 33, -1, 122, 231, -1, 260, -1, 144, 232, 145, -1, 233, -1, 232, 146, 233, -1, 131, 147, 260, -1, 123, 235, -1, 260, -1, 144, 236, 145, -1, 237, -1, 236, 146, 237, -1, 131, 147, 260, -1, 57, 239, 242, -1, 260, -1, 144, 240, 145, -1, 241, -1, 240, 146, 241, -1, 131, 147, 260, -1, -1, 148, 243, 149, 150, -1, 244, -1, 243, 244, -1, 222, -1, 225, -1, 303, -1, 58, 246, 249, -1, 260, -1, 144, 247, 145, -1, 248, -1, 247, 146, 248, -1, 131, 147, 260, -1, -1, 148, 250, 149, 150, -1, 251, -1, 250, 251, -1, 222, -1, 225, -1, 303, -1, 55, 253, 257, -1, 56, 260, 261, -1, -1, 260, 254, 261, -1, 144, 255, 145, -1, 256, -1, 255, 146, 256, -1, 128, 147, 33, -1, 129, 147, 33, -1, 131, 147, 260, -1, 139, 147, 332, -1, 140, 147, 332, -1, 141, 147, 332, -1, 142, 147, 31, -1, 143, 147, 101, -1, -1, 148, 258, 149, 150, -1, 259, -1, 258, 259, -1, 222, -1, 225, -1, 299, -1, 303, -1, 31, -1, 32, -1, -1, 101, -1, 49, 263, -1, 32, -1, 144, 264, 145, -1, 265, -1, 264, 146, 265, -1, 131, 147, 32, -1, 132, 147, 332, -1, 50, 32, -1, 51, 268, -1, 32, -1, 144, 269, 145, -1, 270, -1, 269, 146, 270, -1, 131, 147, 32, -1, -1, 14, 313, -1, -1, 15, 313, -1, -1, 16, 313, -1, 26, 313, -1, 52, 313, -1, 53, 313, -1, 54, 313, -1, 35, 313, -1, 36, 313, -1, 37, 313, -1, 38, 313, -1, 39, 313, -1, 40, 313, -1, 41, 313, -1, 42, 313, -1, 45, 313, -1, 43, 313, -1, 20, 313, -1, 23, 313, -1, 24, 313, -1, 17, 313, -1, 18, 313, -1, 19, 313, -1, 21, 313, -1, 22, 313, -1, 25, 313, -1, 10, 313, -1, 11, 313, -1, 4, 300, -1, 144, 301, 145, -1, 302, -1, 301, 146, 302, -1, 134, 147, 33, -1, 9, 304, 313, -1, -1, 33, -1, 144, 305, 145, -1, 306, -1, 305, 146, 306, -1, 125, 147, 33, -1, -1, 303, -1, 12, 309, 313, -1, 31, -1, 144, 310, 145, -1, 311, -1, 310, 146, 311, -1, 127, 147, 31, -1, 133, 147, 101, -1, 13, 32, 317, 313, -1, 314, 30, -1, 28, -1, 314, 28, -1, -1, 86, 318, 374, 316, 148, 319, 149, 150, -1, -1, 32, -1, -1, 31, -1, -1, 320, -1, 321, -1, 320, 321, -1, 222, -1, 225, -1, 31, 323, 374, 322, -1, -1, 146, -1, -1, 147, 328, -1, -1, 147, 325, -1, 328, -1, 325, 326, 328, -1, 152, -1, 153, -1, 154, -1, 155, -1, 156, -1, 157, -1, -1, 151, -1, 158, -1, 152, -1, 153, -1, 154, -1, 156, -1, 329, 327, 333, -1, -1, 144, 330, 145, -1, 331, -1, 330, 89, 331, -1, 31, -1, 110, -1, 111, -1, 330, -1, 399, 144, 334, 145, -1, 102, -1, 101, -1, 332, -1, 112, -1, 33, -1, 109, -1, -1, 325, -1, 334, 146, 325, -1, 103, 395, 31, 374, 150, -1, 103, 395, 144, 154, 31, 145, 144, 400, 145, 374, 150, -1, -1, -1, 60, 330, 337, 345, 374, 338, 349, 150, -1, -1, 341, 340, 342, -1, 120, 159, 400, 160, -1, -1, -1, 59, 330, 343, 345, 374, 344, 349, 150, -1, -1, 161, 346, -1, 347, -1, 346, 146, 347, -1, 348, 330, -1, -1, 61, -1, 62, -1, 63, -1, -1, 148, 350, 149, -1, 351, -1, 350, 351, -1, 222, -1, 225, -1, 206, -1, 336, -1, 342, -1, 192, -1, 335, -1, 315, -1, 352, -1, 303, -1, 290, -1, 277, -1, 278, -1, 279, -1, 280, -1, 281, -1, 282, -1, 283, -1, 284, -1, 285, -1, 286, -1, 287, -1, 288, -1, 362, -1, 361, -1, 383, -1, 48, 313, -1, 47, 313, -1, 46, 313, -1, 61, 360, 161, -1, 62, 360, 161, -1, 63, 360, 161, -1, 64, 161, -1, 124, 353, 356, -1, 144, 354, 145, -1, 355, -1, 354, 146, 355, -1, 126, 147, 31, -1, 131, 147, 359, -1, 135, 147, 31, -1, -1, 148, 357, 149, 150, -1, 358, -1, 357, 358, -1, 222, -1, 225, -1, 303, -1, 31, -1, 33, -1, -1, 66, -1, 369, 158, 31, 144, 145, 401, 373, 374, 150, 378, 379, -1, -1, 119, 363, 364, -1, 364, -1, 31, 144, 380, 145, 401, 374, 365, 150, 307, 378, -1, -1, -1, 162, 366, 144, 380, 145, 163, -1, -1, -1, 162, 368, 395, 144, 380, 145, 163, -1, -1, 85, -1, 395, 31, 144, 380, 145, 372, 401, 373, 374, 367, 150, 307, 378, 379, -1, 395, 113, 147, 144, 395, 145, 150, -1, 395, 113, 371, 144, 380, 145, 372, 401, 373, 374, 367, 150, 378, 379, -1, 113, 395, 144, 380, 145, 372, 401, 373, 374, 367, 150, 378, 379, -1, 153, -1, 152, -1, 154, -1, 155, -1, 164, -1, 156, -1, 157, -1, 165, -1, 159, 159, -1, 160, 160, -1, 153, 147, -1, 152, 147, -1, 154, 147, -1, 155, 147, -1, 164, 147, -1, 156, 147, -1, 157, 147, -1, 165, 147, -1, 159, 159, 147, -1, 160, 160, 147, -1, 158, -1, 144, 145, -1, 162, 163, -1, 159, -1, 159, 147, -1, 147, 147, -1, 151, 147, -1, 160, -1, 160, 147, -1, -1, 91, -1, -1, 147, 101, -1, -1, 155, 375, 155, -1, 376, -1, 375, 146, 376, -1, 31, -1, 31, 147, 377, -1, 260, -1, 31, 161, 261, 152, 261, -1, 33, -1, 101, -1, -1, 44, 313, -1, -1, 34, 313, -1, 381, -1, -1, 382, -1, 381, 146, 382, -1, 93, 318, 374, 324, -1, 94, 318, 374, 324, -1, 95, 318, 374, 324, -1, 96, 318, 374, -1, 97, 318, 374, -1, 98, 144, 380, 145, 318, 374, -1, 99, 144, 380, 145, 318, 374, -1, 115, 318, 374, -1, 396, 324, -1, -1, 65, 384, 386, -1, -1, 67, 385, 386, -1, 386, -1, -1, 92, 387, 388, -1, 388, -1, 389, -1, 391, -1, -1, 85, 390, 370, -1, 370, -1, 395, 31, 374, 392, 150, 271, 272, 273, -1, -1, 148, 393, 149, -1, 394, -1, 393, 394, -1, 222, -1, 225, -1, 14, 313, -1, 15, 313, -1, 16, 313, -1, 91, 399, 398, 397, -1, 399, 398, 397, -1, 395, 318, 374, -1, -1, 156, -1, -1, 398, 154, 91, -1, 398, 154, -1, 330, -1, 330, 159, 400, 160, -1, 60, 330, -1, 88, 69, -1, 69, -1, 88, -1, 88, 70, -1, 70, -1, 71, -1, 88, 71, -1, 71, 71, -1, 88, 71, 71, -1, 72, -1, 73, -1, 68, -1, 87, 74, -1, 88, 74, -1, 74, -1, 75, -1, 76, -1, 77, -1, 78, -1, 79, -1, 80, -1, 81, -1, 82, -1, 83, -1, 84, -1, 100, -1, 121, -1, 395, -1, 400, 146, 395, -1, -1, 114, 144, 402, 145, -1, -1, 330, -1, 402, 146, 330, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { 0, 527, 527, 528, 531, 531, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 610, 616, 621, 626, 627, 637, 644, 653, 658, 663, 664, 674, 681, 689, 694, 699, 700, 710, 717, 746, 751, 756, 757, 767, 774, 800, 808, 813, 814, 825, 831, 839, 889, 893, 967, 972, 973, 984, 987, 990, 1004, 1020, 1025, 1025, 1044, 1044, 1105, 1119, 1120, 1123, 1124, 1125, 1129, 1133, 1142, 1151, 1160, 1161, 1164, 1178, 1178, 1215, 1216, 1219, 1220, 1223, 1223, 1252, 1253, 1256, 1261, 1268, 1273, 1278, 1279, 1289, 1296, 1296, 1322, 1323, 1326, 1332, 1345, 1348, 1351, 1354, 1359, 1360, 1365, 1371, 1408, 1416, 1422, 1427, 1428, 1441, 1449, 1457, 1465, 1475, 1486, 1491, 1496, 1497, 1507, 1514, 1525, 1530, 1535, 1536, 1546, 1553, 1571, 1576, 1581, 1582, 1592, 1599, 1603, 1608, 1609, 1619, 1622, 1625, 1639, 1657, 1662, 1667, 1668, 1678, 1685, 1689, 1694, 1695, 1705, 1708, 1711, 1725, 1736, 1746, 1746, 1759, 1764, 1765, 1782, 1794, 1812, 1824, 1836, 1848, 1860, 1872, 1889, 1893, 1898, 1899, 1909, 1912, 1915, 1918, 1932, 1933, 1949, 1952, 1955, 1964, 1970, 1975, 1976, 1987, 1993, 2001, 2009, 2015, 2020, 2025, 2026, 2036, 2043, 2046, 2051, 2054, 2059, 2062, 2067, 2073, 2079, 2085, 2090, 2095, 2100, 2105, 2110, 2115, 2120, 2125, 2130, 2135, 2140, 2145, 2151, 2156, 2162, 2168, 2174, 2180, 2186, 2191, 2197, 2203, 2209, 2214, 2215, 2225, 2232, 2312, 2315, 2320, 2325, 2326, 2336, 2343, 2346, 2349, 2358, 2364, 2369, 2370, 2381, 2387, 2398, 2403, 2406, 2407, 2417, 2417, 2437, 2440, 2445, 2448, 2453, 2454, 2457, 2458, 2461, 2462, 2463, 2499, 2500, 2503, 2504, 2507, 2510, 2515, 2516, 2534, 2537, 2540, 2543, 2546, 2549, 2554, 2557, 2560, 2563, 2566, 2569, 2572, 2577, 2592, 2595, 2600, 2601, 2609, 2614, 2617, 2622, 2631, 2641, 2645, 2649, 2653, 2657, 2661, 2667, 2672, 2678, 2696, 2715, 2751, 2757, 2751, 2794, 2794, 2820, 2825, 2831, 2825, 2865, 2866, 2869, 2870, 2873, 2917, 2920, 2923, 2926, 2931, 2934, 2939, 2940, 2943, 2944, 2945, 2946, 2947, 2948, 2949, 2950, 2951, 2952, 2956, 2960, 2964, 2975, 2986, 2997, 3008, 3019, 3030, 3041, 3052, 3063, 3074, 3085, 3086, 3087, 3088, 3099, 3110, 3121, 3128, 3135, 3142, 3151, 3164, 3169, 3170, 3182, 3189, 3196, 3205, 3209, 3214, 3215, 3225, 3228, 3231, 3245, 3246, 3249, 3252, 3257, 3319, 3319, 3320, 3323, 3368, 3371, 3371, 3382, 3385, 3385, 3397, 3400, 3405, 3423, 3443, 3479, 3560, 3561, 3562, 3563, 3564, 3565, 3566, 3567, 3568, 3569, 3570, 3571, 3572, 3573, 3574, 3575, 3576, 3577, 3578, 3579, 3580, 3581, 3582, 3583, 3584, 3585, 3586, 3587, 3588, 3591, 3594, 3599, 3602, 3610, 3613, 3619, 3623, 3635, 3639, 3645, 3649, 3672, 3676, 3682, 3685, 3690, 3693, 3698, 3746, 3751, 3757, 3784, 3795, 3806, 3817, 3835, 3845, 3861, 3877, 3885, 3892, 3892, 3893, 3893, 3894, 3898, 3898, 3899, 3903, 3904, 3908, 3908, 3909, 3912, 3964, 3970, 3975, 3976, 3988, 3991, 3994, 4009, 4024, 4041, 4048, 4062, 4153, 4156, 4164, 4167, 4170, 4175, 4183, 4194, 4209, 4213, 4217, 4221, 4225, 4229, 4233, 4237, 4241, 4245, 4249, 4253, 4257, 4261, 4265, 4269, 4273, 4277, 4281, 4285, 4289, 4293, 4297, 4301, 4305, 4309, 4313, 4319, 4325, 4341, 4344, 4352, 4358, 4365 }; #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_DEFDOCSTRING", "TK_DEFENCODING", "TK_PLUGIN", "TK_VIRTERRORHANDLER", "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_METHODCODE", "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_ELLIPSIS", "TK_DEFMETATYPE", "TK_DEFSUPERTYPE", "TK_PROPERTY", "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_ALLRAISEPYEXC", "TK_CALLSUPERINIT", "TK_DEFERRORHANDLER", "TK_VERSION", "'('", "')'", "','", "'='", "'{'", "'}'", "';'", "'!'", "'-'", "'+'", "'*'", "'/'", "'&'", "'|'", "'~'", "'<'", "'>'", "':'", "'['", "']'", "'%'", "'^'", "$accept", "specification", "statement", "@1", "modstatement", "nsstatement", "defdocstring", "defdocstring_args", "defdocstring_arg_list", "defdocstring_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", "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", "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", "@7", "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", "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", "@8", "optfilename", "optname", "optenumbody", "enumbody", "enumline", "optcomma", "optenumassign", "optassign", "expr", "binop", "optunop", "value", "optcast", "scopedname", "scopepart", "bool_value", "simplevalue", "exprlist", "typedef", "struct", "@9", "@10", "classtmpl", "@11", "template", "class", "@12", "@13", "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", "@14", "simplector", "optctorsig", "@15", "optsig", "@16", "optvirtual", "function", "operatorname", "optconst", "optabstract", "optflags", "flaglist", "flag", "flagvalue", "methodcode", "virtualcatchercode", "arglist", "rawarglist", "argvalue", "varmember", "@17", "@18", "simple_varmem", "@19", "varmem", "member", "@20", "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, 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, 166, 167, 167, 169, 168, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 172, 173, 173, 174, 174, 175, 176, 177, 177, 178, 178, 179, 180, 181, 181, 182, 182, 183, 184, 185, 185, 186, 186, 187, 188, 189, 189, 190, 190, 191, 191, 192, 193, 193, 194, 195, 195, 196, 196, 196, 196, 197, 199, 198, 201, 200, 202, 203, 203, 204, 204, 204, 204, 204, 204, 204, 204, 204, 205, 207, 206, 208, 208, 209, 209, 211, 210, 212, 212, 213, 214, 215, 215, 216, 216, 217, 219, 218, 220, 220, 221, 222, 223, 223, 223, 223, 224, 224, 225, 226, 227, 227, 227, 228, 228, 229, 229, 229, 229, 230, 231, 231, 232, 232, 233, 234, 235, 235, 236, 236, 237, 238, 239, 239, 240, 240, 241, 242, 242, 243, 243, 244, 244, 244, 245, 246, 246, 247, 247, 248, 249, 249, 250, 250, 251, 251, 251, 252, 252, 254, 253, 253, 255, 255, 256, 256, 256, 256, 256, 256, 256, 256, 257, 257, 258, 258, 259, 259, 259, 259, 260, 260, 261, 261, 262, 263, 263, 264, 264, 265, 265, 266, 267, 268, 268, 269, 269, 270, 271, 271, 272, 272, 273, 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, 301, 302, 303, 304, 304, 304, 305, 305, 306, 307, 307, 308, 309, 309, 310, 310, 311, 311, 312, 313, 314, 314, 316, 315, 317, 317, 318, 318, 319, 319, 320, 320, 321, 321, 321, 322, 322, 323, 323, 324, 324, 325, 325, 326, 326, 326, 326, 326, 326, 327, 327, 327, 327, 327, 327, 327, 328, 329, 329, 330, 330, 331, 332, 332, 333, 333, 333, 333, 333, 333, 333, 333, 334, 334, 334, 335, 335, 337, 338, 336, 340, 339, 341, 343, 344, 342, 345, 345, 346, 346, 347, 348, 348, 348, 348, 349, 349, 350, 350, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 352, 353, 354, 354, 355, 355, 355, 356, 356, 357, 357, 358, 358, 358, 359, 359, 360, 360, 361, 363, 362, 362, 364, 365, 366, 365, 367, 368, 367, 369, 369, 370, 370, 370, 370, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 372, 372, 373, 373, 374, 374, 375, 375, 376, 376, 377, 377, 377, 377, 378, 378, 379, 379, 380, 381, 381, 381, 382, 382, 382, 382, 382, 382, 382, 382, 382, 384, 383, 385, 383, 383, 387, 386, 386, 388, 388, 390, 389, 389, 391, 392, 392, 393, 393, 394, 394, 394, 394, 394, 395, 395, 396, 397, 397, 398, 398, 398, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 400, 400, 401, 401, 402, 402, 402 }; /* 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, 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, 13, 0, 5, 0, 3, 1, 2, 0, 5, 1, 2, 1, 2, 1, 3, 1, 3, 3, 0, 5, 1, 2, 1, 4, 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, 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, 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, 3, 1, 3, 3, 3, 0, 1, 3, 1, 3, 3, 0, 1, 3, 1, 3, 1, 3, 3, 3, 4, 2, 1, 2, 0, 8, 0, 1, 0, 1, 0, 1, 1, 2, 1, 1, 4, 0, 1, 0, 2, 0, 2, 1, 3, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 3, 0, 3, 1, 3, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 0, 1, 3, 5, 11, 0, 0, 8, 0, 3, 4, 0, 0, 8, 0, 2, 1, 3, 2, 0, 1, 1, 1, 0, 3, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 11, 0, 3, 1, 10, 0, 0, 6, 0, 0, 7, 0, 1, 14, 7, 14, 13, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 1, 2, 2, 1, 2, 2, 2, 1, 2, 0, 1, 0, 2, 0, 3, 1, 3, 1, 3, 1, 5, 1, 1, 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, 140, 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 536, 526, 529, 530, 534, 535, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 290, 0, 527, 0, 550, 0, 0, 128, 117, 0, 142, 0, 0, 0, 551, 0, 0, 5, 39, 19, 20, 9, 38, 14, 46, 36, 37, 42, 16, 17, 15, 40, 41, 18, 21, 22, 7, 8, 6, 11, 12, 13, 10, 23, 24, 51, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 48, 522, 323, 47, 43, 45, 344, 44, 49, 50, 0, 519, 0, 0, 76, 53, 0, 52, 59, 0, 58, 65, 0, 64, 71, 0, 0, 284, 259, 0, 260, 276, 0, 0, 288, 253, 254, 255, 256, 257, 251, 258, 236, 0, 464, 290, 217, 0, 216, 223, 225, 0, 224, 237, 238, 239, 212, 213, 0, 204, 191, 214, 0, 169, 164, 0, 182, 177, 347, 341, 532, 291, 464, 537, 525, 528, 531, 538, 519, 0, 111, 0, 0, 123, 0, 122, 143, 0, 464, 0, 84, 0, 0, 151, 152, 0, 157, 158, 0, 0, 0, 0, 464, 0, 517, 77, 0, 0, 0, 79, 0, 0, 55, 0, 0, 61, 0, 0, 67, 0, 0, 73, 70, 285, 283, 0, 0, 0, 278, 275, 289, 0, 524, 0, 94, 134, 0, 138, 0, 0, 0, 0, 0, 219, 0, 0, 227, 0, 0, 0, 0, 0, 0, 0, 0, 0, 194, 0, 189, 214, 215, 190, 0, 0, 166, 0, 163, 0, 0, 179, 0, 176, 350, 350, 286, 533, 517, 464, 0, 113, 0, 0, 0, 0, 125, 0, 0, 0, 0, 0, 145, 141, 479, 0, 464, 552, 0, 0, 0, 154, 0, 0, 160, 324, 0, 464, 345, 479, 505, 0, 0, 0, 432, 431, 433, 434, 436, 437, 451, 454, 458, 0, 435, 438, 0, 521, 518, 515, 0, 0, 78, 0, 0, 54, 0, 0, 60, 0, 0, 66, 0, 0, 72, 0, 0, 0, 277, 0, 282, 468, 0, 466, 0, 135, 0, 133, 290, 0, 0, 218, 0, 0, 226, 0, 0, 0, 0, 0, 0, 0, 0, 0, 193, 0, 0, 267, 208, 209, 0, 206, 210, 211, 192, 0, 165, 0, 173, 174, 0, 171, 175, 0, 178, 0, 186, 187, 0, 184, 188, 355, 464, 464, 0, 514, 0, 0, 0, 0, 132, 0, 130, 121, 0, 119, 0, 124, 0, 0, 0, 0, 0, 144, 0, 290, 290, 290, 290, 290, 0, 0, 290, 0, 478, 480, 290, 303, 0, 0, 0, 346, 0, 153, 0, 0, 159, 0, 523, 96, 0, 0, 0, 452, 0, 456, 457, 442, 441, 443, 444, 446, 447, 455, 439, 459, 440, 453, 445, 448, 479, 520, 410, 411, 81, 82, 80, 57, 56, 63, 62, 69, 68, 75, 74, 280, 281, 279, 0, 0, 465, 0, 95, 136, 0, 139, 221, 326, 327, 222, 220, 229, 228, 196, 197, 198, 199, 200, 201, 202, 203, 195, 0, 261, 268, 0, 0, 0, 207, 168, 167, 0, 172, 181, 180, 0, 185, 356, 357, 358, 351, 352, 0, 348, 342, 292, 339, 0, 115, 0, 344, 112, 129, 131, 118, 120, 127, 126, 148, 149, 150, 147, 146, 464, 464, 464, 464, 464, 479, 479, 464, 460, 0, 464, 321, 490, 85, 0, 83, 553, 156, 155, 162, 161, 0, 460, 0, 0, 0, 509, 510, 0, 507, 230, 0, 449, 450, 0, 212, 472, 473, 470, 469, 467, 0, 0, 0, 0, 0, 0, 99, 109, 101, 102, 103, 107, 104, 108, 137, 0, 0, 263, 0, 0, 270, 266, 205, 170, 183, 355, 354, 359, 359, 301, 296, 297, 0, 293, 294, 0, 114, 116, 303, 303, 303, 485, 486, 0, 0, 489, 461, 554, 481, 516, 0, 304, 305, 313, 0, 0, 87, 91, 89, 90, 92, 97, 554, 511, 512, 513, 506, 508, 0, 232, 0, 460, 214, 252, 248, 105, 106, 0, 0, 100, 0, 262, 0, 0, 269, 0, 353, 425, 0, 0, 321, 464, 0, 295, 0, 482, 483, 484, 290, 290, 0, 462, 0, 307, 308, 309, 310, 311, 312, 321, 314, 316, 317, 318, 319, 315, 0, 93, 0, 88, 462, 231, 0, 234, 428, 554, 0, 0, 98, 265, 264, 272, 271, 0, 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 412, 412, 412, 0, 491, 493, 501, 496, 415, 0, 368, 365, 363, 364, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 373, 372, 370, 369, 366, 367, 425, 361, 371, 387, 386, 417, 0, 503, 388, 495, 498, 499, 500, 349, 343, 302, 299, 287, 0, 464, 464, 556, 0, 464, 322, 306, 334, 331, 330, 335, 333, 328, 332, 320, 0, 86, 464, 233, 0, 504, 462, 214, 479, 250, 479, 240, 241, 242, 243, 244, 245, 246, 247, 249, 391, 390, 389, 413, 0, 0, 0, 395, 0, 0, 0, 0, 0, 0, 403, 360, 362, 0, 300, 298, 464, 487, 488, 557, 0, 463, 422, 321, 422, 235, 464, 471, 0, 0, 392, 393, 394, 501, 492, 494, 502, 0, 497, 0, 416, 0, 0, 0, 0, 398, 0, 396, 0, 0, 555, 0, 423, 0, 337, 0, 0, 422, 460, 554, 0, 0, 0, 0, 397, 0, 407, 408, 409, 0, 405, 0, 340, 558, 0, 474, 329, 321, 273, 0, 554, 464, 400, 401, 402, 399, 0, 406, 554, 0, 0, 476, 338, 274, 474, 474, 464, 419, 404, 462, 479, 475, 0, 430, 476, 476, 422, 420, 0, 464, 0, 477, 427, 429, 0, 0, 273, 0, 0, 273, 479, 474, 474, 424, 474, 0, 418, 476, 110, 0, 414, 421 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { -1, 1, 2, 3, 73, 74, 75, 130, 224, 225, 76, 133, 227, 228, 77, 136, 230, 231, 78, 139, 233, 234, 79, 127, 221, 222, 80, 307, 579, 660, 661, 662, 81, 365, 82, 585, 503, 610, 611, 612, 83, 292, 420, 550, 84, 195, 425, 426, 85, 198, 296, 297, 86, 194, 422, 423, 87, 250, 251, 88, 89, 201, 302, 303, 90, 206, 311, 312, 91, 209, 314, 315, 92, 176, 276, 277, 279, 401, 402, 93, 179, 281, 282, 284, 409, 410, 94, 172, 272, 268, 269, 271, 391, 392, 173, 274, 95, 161, 255, 256, 96, 97, 165, 258, 259, 674, 728, 823, 98, 99, 100, 101, 767, 768, 769, 770, 771, 772, 773, 774, 616, 776, 777, 102, 617, 103, 104, 105, 106, 107, 108, 109, 110, 393, 524, 621, 622, 935, 527, 624, 625, 936, 111, 146, 240, 241, 112, 141, 142, 113, 415, 244, 185, 637, 638, 639, 857, 696, 576, 656, 714, 721, 657, 658, 114, 115, 510, 817, 897, 116, 117, 286, 633, 118, 214, 551, 120, 285, 632, 413, 541, 542, 543, 693, 784, 785, 786, 852, 886, 887, 889, 911, 912, 485, 842, 787, 788, 850, 789, 950, 957, 895, 916, 790, 791, 337, 652, 807, 247, 363, 364, 603, 933, 945, 444, 445, 446, 792, 846, 847, 793, 849, 794, 795, 848, 796, 463, 592, 593, 447, 448, 340, 217, 124, 309, 706, 862 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -775 static const yytype_int16 yypact[] = { -775, 106, -775, 1013, -775, -775, 62, 35, 68, 67, 73, 129, 129, 74, 150, 129, 129, 129, 129, 129, 129, 129, 129, 543, 89, -775, -775, 40, 207, 53, 129, 129, 129, 55, 107, 57, 59, 224, 224, -775, -775, -775, 201, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, 269, 210, 253, 543, -775, 402, 286, -775, -775, 77, 81, 402, 224, 147, -775, 65, 71, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, 78, -775, -775, -775, -775, 292, -775, -775, -775, 82, -775, 227, 16, -775, -775, 200, -775, -775, 226, -775, -775, 236, -775, -775, 238, 129, -775, -775, 283, -775, -775, -4, 129, 323, -775, -775, -775, -775, -775, -775, -775, -775, 224, 205, 29, -775, 161, -775, -775, -775, 276, -775, -775, -775, -775, -775, -775, 148, 267, -775, 324, 297, 284, -775, 314, 294, -775, 351, 51, -775, -775, 205, -775, -775, -775, 393, -775, -775, 80, -775, 321, 339, -775, 357, -775, -775, 196, 205, 347, 96, 402, 361, -775, -775, 364, -775, -775, 224, 402, 543, 437, -23, 194, 93, -775, 350, 352, 242, -775, 353, 247, -775, 354, 254, -775, 356, 257, -775, 358, 260, -775, -775, -775, -775, 359, 360, 264, -775, -775, -775, 129, 351, 467, -775, 362, 477, 419, 365, 366, 369, 372, 268, -775, 374, 273, -775, 377, 378, 380, 381, 382, 383, 384, 385, 275, -775, 256, -775, 324, -775, -775, 386, 278, -775, 141, -775, 387, 281, -775, 141, -775, 376, 376, -775, -775, 93, 205, 388, 391, 481, 509, 394, 285, -775, 396, 397, 398, 399, 289, -775, -775, 1238, 224, 205, -775, 76, 400, 291, -775, 403, 293, -775, -775, 85, 205, -775, 1238, 401, 406, 115, 405, 407, 408, 409, 410, 411, 412, -775, 91, 101, 390, 414, 415, 420, 472, -775, -775, 250, 464, -775, 16, 533, -775, 200, 534, -775, 226, 540, -775, 236, 542, -775, 238, 547, 478, -775, -4, -775, 433, -24, -775, 434, -775, 30, -775, 269, 549, 229, -775, 161, 551, -775, 276, 552, 554, 107, 229, 229, 229, 553, 487, -775, 148, 445, 86, -775, -775, 45, -775, -775, -775, -775, 107, -775, 297, -775, -775, 34, -775, -775, 107, -775, 314, -775, -775, 47, -775, -775, 274, 205, 205, 442, -775, 441, 561, 1184, 447, -775, 24, -775, -775, 38, -775, 250, -775, 357, 565, 566, 567, 568, -775, 196, 269, 269, 269, 269, 269, 458, 460, 269, 461, 459, -775, 269, 462, 21, 480, 402, -775, 107, -775, 361, 107, -775, 364, -775, -775, 463, 280, 482, -775, 402, -775, -775, -775, -775, -775, -775, -775, -775, -775, 488, -775, 491, -775, -775, -775, 1238, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, 145, 467, -775, 228, -775, -775, 579, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, 507, -775, -775, 519, 129, 495, -775, -775, -775, 496, -775, -775, -775, 498, -775, -775, -775, -775, 503, -775, 224, -775, -775, 348, -775, 506, -775, 715, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, 205, 205, 205, 205, 205, 1238, 1238, 205, 562, 1238, 205, 508, -775, -775, 139, -775, -775, -775, -775, -775, -775, 434, 562, 129, 129, 129, -775, -775, 37, -775, 640, 510, -775, -775, 512, 497, -775, -775, -775, -775, -775, 129, 129, 129, 129, 402, 70, -775, -775, -775, -775, -775, -775, -775, -775, -775, 513, 302, -775, 520, 305, -775, -775, -775, -775, -775, 274, 351, 511, 511, 521, -775, -775, 517, 348, -775, 525, -775, -775, 462, 462, 462, -775, -775, 526, 527, -775, -775, 556, -775, -775, 224, 219, -775, 212, 129, 41, -775, -775, -775, -775, -775, -775, 556, -775, -775, -775, -775, -775, 129, 658, 524, 562, 324, -775, -775, -775, -775, 644, 528, -775, 643, -775, 507, 646, -775, 519, -775, 1118, 530, 531, 508, 205, 532, -775, 402, -775, -775, -775, 269, 269, 539, 537, 44, -775, -775, -775, -775, -775, -775, 508, -775, -775, -775, -775, -775, -775, 1297, -775, 535, -775, 537, -775, 129, 661, -775, 556, 541, 545, -775, -775, -775, -775, -775, 129, 548, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 620, 620, 620, 538, -775, -775, 529, -775, -775, 550, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, 888, -775, -775, -775, -775, -775, 544, -775, -775, -775, -775, -775, -775, -775, -775, -775, 555, -775, 307, 205, 205, 224, 590, 205, -775, -775, -775, -775, -775, -775, -775, -8, -775, -775, 559, -775, 205, -775, 129, -775, 537, 324, 1238, -775, 1238, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, 546, 557, 558, -775, 1351, 1351, 1461, 1406, 665, 190, 560, -775, -775, 673, -775, -775, 205, -775, -775, 351, 309, -775, 563, 237, 563, -775, 205, -775, 564, 569, -775, -775, -775, -775, -775, -775, -775, 95, -775, 548, -775, 570, 573, 574, 311, -775, 141, -775, 572, 577, -775, 224, -775, 591, 219, 313, 592, 563, 562, 556, 578, 674, 250, 675, -775, 190, -775, -775, -775, 49, -775, 595, -775, 351, 402, 666, -775, 508, 702, 593, 556, 205, -775, -775, -775, -775, 597, -775, 556, 580, 129, 678, 219, -775, 666, 666, 205, 586, -775, 537, 1238, -775, 129, -775, 678, 678, 563, -775, 599, 205, 605, -775, -775, -775, 601, 608, 702, 604, 594, 702, 1238, 666, 666, -775, 666, 610, -775, 678, -775, 596, -775, -775 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { -775, -775, 712, -775, -775, -362, -775, -775, -775, 413, -775, -775, -775, 373, -775, -775, -775, 417, -775, -775, -775, 416, -775, -775, -775, 418, -630, -775, -775, -775, 98, -775, -775, -775, -775, -775, 171, -775, 151, -775, -619, -775, -775, -775, -775, -775, -775, 338, -775, -775, -775, 335, -775, -775, -775, 343, -249, -775, -775, -248, -775, -775, -775, 331, -775, -775, -775, 312, -775, -775, -775, 315, -775, -775, -775, 379, -775, -775, 370, -775, -775, -775, 421, -775, -775, 367, -775, -775, -775, -775, 392, -775, -775, 389, 12, -255, -775, -775, -775, 427, -775, -775, -775, -775, 428, -775, -775, -775, -775, -775, -775, -469, -775, -775, -775, -775, -775, -775, -775, -775, -612, -775, -775, -775, -580, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, -775, 118, -246, -775, -775, 117, -691, -775, -775, -775, 448, -775, -12, -775, -466, -775, -775, -135, -775, -775, 173, -775, -775, -259, -719, -775, -775, -479, -775, -26, 598, -341, -775, -775, -564, -557, -775, -775, -775, -775, 809, -198, -775, -775, 536, -775, 183, -775, 181, -775, 32, -775, -775, -775, -90, -775, -775, -91, -400, -293, -775, -775, -775, -29, -775, -775, -774, -775, -775, 10, -775, -558, -675, -170, -775, 325, -775, -695, -718, -306, -775, 251, -775, -775, -775, -380, -775, -20, -775, -775, 22, -775, -775, 231, -2, -775, 571, 635, -21, -186, -623, -775 }; /* 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 -525 static const yytype_int16 yytable[] = { 143, 123, 157, 148, 149, 150, 151, 152, 153, 154, 155, 181, 182, 121, 461, 287, 319, 395, 166, 167, 168, 389, 390, 252, 394, 122, 317, 557, 667, 399, 400, 304, 403, 615, 407, 408, 618, 411, 191, 517, 518, 519, 203, 388, 725, 321, 174, 177, 180, 387, 820, 587, 588, 589, 388, 421, 388, 549, 388, 192, 248, 504, 762, 24, 25, 202, 24, 25, 128, 424, 24, 25, 159, 763, 24, 25, 24, 25, 24, 25, 775, 211, -524, 207, 210, 163, 169, 170, 169, 170, 169, 170, 898, 125, 605, 32, 169, 170, 134, 24, 25, 131, 169, 170, 137, 144, 4, 824, 196, 665, 211, 290, 778, 215, 199, 606, 607, 608, 730, 525, 417, 320, 500, 238, 32, 921, 902, 235, 781, 239, 245, 501, 246, 211, 242, 782, -522, 450, 169, 170, 211, 615, 389, 390, 618, 394, 896, 219, 460, 868, 388, 212, 399, 400, 762, 403, 56, 140, 659, 220, 407, 408, 609, 411, -524, 763, 577, 211, 24, 25, 24, 25, 775, 553, 956, 598, 599, 170, 600, 129, 249, 505, 147, 532, 160, 211, 671, 555, 642, 808, 723, 665, 318, 32, 528, 216, 536, 164, 928, 171, 934, 175, 308, 178, 778, -524, 126, -524, 216, 205, 308, 135, 132, 590, 591, 208, 799, 138, 145, 683, 781, 197, 451, 766, 291, 200, 780, 782, 954, 955, 526, 451, 361, 158, 506, 809, 452, 212, 474, 162, 306, 946, 947, 544, 545, 459, 601, 338, 476, 339, 475, 972, 605, 613, 614, 26, 659, 24, 25, 465, 387, 477, 466, 648, 649, 388, 951, 963, 968, 969, 966, 970, 183, 606, 607, 608, 260, 261, 923, 262, 449, 483, 32, 484, 186, 24, 25, 263, 264, 265, 266, 267, 253, 254, 587, 588, 589, 635, 636, 938, 184, 564, 565, 566, 567, 568, 204, 941, 571, 24, 25, 236, 574, 237, 56, 766, 883, 193, 780, 213, 609, 884, 187, 188, 189, 885, 298, 190, 218, 663, 664, 223, 299, 300, 301, 538, 539, 540, 322, 508, 509, 323, 922, 590, 591, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 243, 334, 226, 335, 336, 246, 613, 614, 715, 716, 717, 718, 229, 719, 232, 720, 708, 709, 710, 711, 712, 713, 24, 25, 634, 816, 655, -336, -336, 700, 701, 702, 343, 344, 635, 636, 516, 346, 347, 643, 644, 645, 646, 647, 349, 350, 650, 352, 353, 654, 355, 356, 257, 530, 359, 360, 663, 664, 372, 373, 270, 534, 123, 375, 376, 385, 386, 731, 397, 398, 273, 405, 406, 275, 121, 428, 429, 278, 26, 434, 435, 454, 455, 457, 458, 211, 122, 283, 764, 765, 280, 779, 686, 687, 580, 689, 690, 858, 451, 892, 893, 906, 907, 918, 919, 843, 844, 156, 595, 288, 581, 876, 877, 583, 293, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 294, 295, 57, 58, 305, 310, 59, 783, 313, 37, 341, 362, 342, 345, 348, 60, 351, 925, 354, 357, 358, 366, 367, 368, 602, 421, 802, -291, 626, 370, 631, 369, 371, 870, 374, 871, 70, 377, 378, 800, 379, 380, 381, 382, 383, 384, 396, 404, 764, 765, 412, 779, 419, 424, 427, 418, 430, 431, 432, 433, 453, 123, 462, 456, 464, 467, 478, 468, 469, 470, 471, 472, 473, 121, 479, 480, 482, 481, 486, 488, 490, 803, 804, 869, 492, 122, 494, 26, 668, 669, 670, 496, 497, 499, 507, 502, 512, 520, 514, 783, 515, 521, 523, 546, 547, 548, 678, 679, 680, 681, 552, 559, 560, 561, 562, 569, 156, 570, 573, 572, 682, 586, 575, 619, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 578, 707, 57, 58, 594, 859, 860, 596, 952, 864, 597, 908, 909, 620, 910, 60, 623, 627, 628, 722, 629, 630, 866, 640, 655, 651, 673, 675, 967, 676, 677, 692, 685, 726, 908, 909, 70, 910, 697, 688, 695, 699, 705, 703, 704, 727, 729, 732, 734, 822, 733, 736, 797, 798, 801, 805, 806, 819, 841, -426, 891, 826, 123, 863, 828, 825, 851, 815, 881, 308, 899, 845, 818, 856, 855, 865, 890, 924, 926, 872, 888, 900, 932, 388, 944, 5, 901, 821, 913, 903, 873, 874, 904, 905, 320, 491, 942, 894, 827, 914, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 930, 917, 920, 937, 24, 25, 26, 940, 949, 958, 960, 961, 962, 939, 964, 971, 666, 965, 724, 973, 489, 684, 487, 556, 558, 554, 563, 582, 948, 32, 493, 533, 495, 584, 37, 38, 537, 531, 522, 861, 529, 959, 123, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 511, 56, 57, 58, 513, 735, 59, 737, 498, 316, 867, 698, 119, 691, 694, 60, 854, 927, 61, 62, 929, 882, 414, 672, 653, 604, 289, 535, 67, 880, 0, 68, 0, 0, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, 123, 123, 879, 123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 878, 0, 416, 0, 0, 0, 641, 0, 0, 915, 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, 388, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 738, 0, 0, 0, 605, 0, 931, 0, 0, 24, 25, 739, 943, 0, 0, 740, 741, 742, 743, 744, 745, 746, 747, 748, 953, 606, 749, 750, 751, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 37, 38, 752, 753, 754, 755, 756, 0, 757, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 758, 56, 57, 58, 0, 0, 59, 759, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 61, 62, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 68, 0, 0, 760, 0, 70, 0, 0, 761, 0, 0, 0, 6, 0, 7, 8, 9, 10, 0, 11, 12, 13, 14, 0, 0, 0, 15, 16, 17, 0, 18, 19, 20, 853, 21, 22, 23, 0, 24, 25, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 0, 0, 0, 0, 0, 0, 0, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 0, 56, 57, 58, 0, 0, 59, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 61, 62, 63, 64, 65, 66, 0, 0, 0, 0, 67, 388, 0, 68, 0, 0, 0, 69, 70, 71, 72, 0, 738, 0, 0, 0, 605, 0, 0, 0, 0, 24, 25, 739, 0, 0, 0, 740, 741, 742, 743, 744, 745, 746, 747, 748, 0, 606, 749, 750, 751, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 37, 38, 752, 753, 754, 755, 756, 0, 757, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 758, 56, 57, 58, 0, 0, 59, 759, 0, 0, 24, 25, 26, 0, 0, 60, 0, 0, 61, 62, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 68, 0, 0, 760, 32, 70, 0, 0, 761, 37, 38, 0, 0, 0, 0, 0, 0, 0, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 26, 56, 57, 58, 0, 0, 59, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 61, 62, 0, 0, 0, 0, 0, 0, 0, 0, 67, 156, 0, 68, 0, 0, 0, 69, 70, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 0, 0, 57, 58, 0, 26, 59, 810, 436, 437, 438, 439, 440, 441, 442, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 156, 0, 70, 0, 0, 0, 0, 0, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 26, 0, 57, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 811, 812, 0, 0, 0, 0, 0, 0, 813, 508, 509, 814, 0, 156, 0, 0, 0, 0, 0, 0, 70, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 875, 26, 57, 58, 0, 0, 59, 759, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 156, 0, 0, 0, 0, 0, 70, 0, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 875, 26, 57, 58, 0, 0, 59, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 156, 0, 0, 0, 0, 0, 70, 0, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 0, 0, 57, 58, 0, 0, 59, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 0, 0, 0, 0, 70 }; static const yytype_int16 yycheck[] = { 12, 3, 23, 15, 16, 17, 18, 19, 20, 21, 22, 37, 38, 3, 320, 185, 214, 272, 30, 31, 32, 270, 270, 158, 270, 3, 212, 427, 586, 278, 278, 201, 278, 502, 283, 283, 502, 283, 59, 380, 381, 382, 68, 9, 667, 215, 34, 35, 36, 4, 725, 14, 15, 16, 9, 31, 9, 419, 9, 61, 31, 31, 692, 29, 30, 67, 29, 30, 33, 31, 29, 30, 32, 692, 29, 30, 29, 30, 29, 30, 692, 89, 31, 71, 72, 32, 31, 32, 31, 32, 31, 32, 866, 31, 24, 54, 31, 32, 31, 29, 30, 33, 31, 32, 31, 31, 0, 730, 31, 578, 89, 31, 692, 31, 33, 45, 46, 47, 676, 33, 290, 144, 146, 127, 54, 899, 31, 139, 692, 133, 156, 155, 155, 89, 146, 692, 144, 307, 31, 32, 89, 610, 391, 391, 610, 391, 865, 131, 318, 824, 9, 159, 401, 401, 784, 401, 86, 28, 117, 143, 409, 409, 92, 409, 113, 784, 145, 89, 29, 30, 29, 30, 784, 149, 948, 481, 31, 32, 33, 144, 151, 151, 32, 149, 144, 89, 149, 149, 550, 145, 149, 660, 213, 54, 149, 113, 149, 144, 149, 144, 919, 144, 204, 144, 784, 154, 144, 156, 113, 144, 212, 144, 144, 462, 462, 144, 695, 144, 144, 149, 784, 144, 146, 692, 144, 144, 692, 784, 946, 947, 144, 146, 244, 144, 369, 714, 160, 159, 147, 32, 144, 936, 937, 413, 414, 160, 101, 154, 147, 156, 159, 969, 24, 502, 502, 31, 117, 29, 30, 144, 4, 160, 147, 569, 570, 9, 941, 958, 963, 964, 961, 966, 71, 45, 46, 47, 128, 129, 901, 131, 306, 31, 54, 33, 74, 29, 30, 139, 140, 141, 142, 143, 131, 132, 14, 15, 16, 546, 546, 922, 31, 436, 437, 438, 439, 440, 159, 930, 443, 29, 30, 28, 447, 30, 86, 784, 126, 31, 784, 27, 92, 131, 69, 70, 71, 135, 130, 74, 101, 578, 578, 131, 136, 137, 138, 61, 62, 63, 144, 110, 111, 147, 900, 592, 592, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 32, 162, 131, 164, 165, 155, 610, 610, 151, 152, 153, 154, 131, 156, 131, 158, 152, 153, 154, 155, 156, 157, 29, 30, 31, 721, 144, 145, 146, 643, 644, 645, 145, 146, 638, 638, 379, 145, 146, 564, 565, 566, 567, 568, 145, 146, 571, 145, 146, 574, 145, 146, 131, 396, 145, 146, 660, 660, 145, 146, 148, 404, 419, 145, 146, 145, 146, 677, 145, 146, 101, 145, 146, 131, 419, 145, 146, 148, 31, 145, 146, 145, 146, 145, 146, 89, 419, 148, 692, 692, 131, 692, 145, 146, 451, 145, 146, 145, 146, 145, 146, 145, 146, 145, 146, 753, 754, 60, 465, 71, 453, 846, 847, 456, 148, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 148, 131, 87, 88, 144, 131, 91, 692, 131, 59, 147, 31, 147, 147, 147, 100, 147, 904, 147, 147, 147, 31, 90, 145, 499, 31, 699, 152, 527, 147, 543, 152, 147, 826, 147, 828, 121, 147, 147, 696, 147, 147, 147, 147, 147, 147, 147, 147, 784, 784, 161, 784, 148, 31, 147, 154, 147, 147, 147, 147, 147, 550, 148, 147, 145, 147, 163, 147, 147, 147, 147, 147, 147, 550, 147, 147, 91, 144, 101, 33, 33, 703, 704, 825, 31, 550, 31, 31, 587, 588, 589, 31, 101, 147, 32, 148, 32, 31, 33, 784, 33, 101, 144, 148, 150, 31, 605, 606, 607, 608, 150, 33, 33, 33, 33, 144, 60, 144, 146, 145, 609, 145, 147, 31, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 148, 655, 87, 88, 150, 803, 804, 147, 942, 807, 147, 888, 888, 134, 888, 100, 125, 150, 150, 659, 150, 146, 820, 145, 144, 91, 14, 145, 962, 145, 161, 148, 147, 673, 911, 911, 121, 911, 149, 147, 147, 144, 114, 145, 145, 15, 150, 31, 33, 16, 150, 33, 150, 150, 150, 144, 147, 150, 66, 158, 858, 144, 692, 101, 144, 152, 144, 721, 31, 699, 868, 161, 721, 146, 158, 144, 31, 31, 31, 161, 148, 145, 44, 9, 34, 1, 145, 727, 144, 147, 161, 161, 147, 147, 144, 350, 144, 162, 738, 150, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 145, 150, 150, 150, 29, 30, 31, 150, 162, 150, 145, 150, 144, 923, 150, 145, 585, 163, 660, 163, 347, 610, 344, 425, 429, 422, 435, 455, 938, 54, 353, 401, 356, 458, 59, 60, 409, 398, 386, 805, 391, 951, 784, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 373, 86, 87, 88, 376, 687, 91, 690, 360, 211, 822, 638, 3, 630, 633, 100, 784, 907, 103, 104, 911, 850, 286, 592, 573, 500, 191, 406, 113, 849, -1, 116, -1, -1, -1, 120, 121, -1, -1, -1, -1, -1, -1, -1, 846, 847, 848, 849, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 848, -1, 289, -1, -1, -1, 149, -1, -1, 893, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20, -1, -1, -1, 24, -1, 916, -1, -1, 29, 30, 31, 932, -1, -1, 35, 36, 37, 38, 39, 40, 41, 42, 43, 944, 45, 46, 47, 48, -1, -1, -1, -1, -1, 54, -1, -1, -1, -1, 59, 60, 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, 91, 92, -1, -1, -1, -1, -1, -1, -1, 100, -1, -1, 103, 104, -1, -1, -1, -1, -1, -1, -1, -1, 113, -1, -1, 116, -1, -1, 119, -1, 121, -1, -1, 124, -1, -1, -1, 3, -1, 5, 6, 7, 8, -1, 10, 11, 12, 13, -1, -1, -1, 17, 18, 19, -1, 21, 22, 23, 149, 25, 26, 27, -1, 29, 30, 31, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, -1, -1, -1, -1, -1, -1, -1, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, -1, 86, 87, 88, -1, -1, 91, -1, -1, -1, -1, -1, -1, -1, -1, 100, -1, -1, 103, 104, 105, 106, 107, 108, -1, -1, -1, -1, 113, 9, -1, 116, -1, -1, -1, 120, 121, 122, 123, -1, 20, -1, -1, -1, 24, -1, -1, -1, -1, 29, 30, 31, -1, -1, -1, 35, 36, 37, 38, 39, 40, 41, 42, 43, -1, 45, 46, 47, 48, -1, -1, -1, -1, -1, 54, -1, -1, -1, -1, 59, 60, 61, 62, 63, 64, 65, -1, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, -1, -1, 91, 92, -1, -1, 29, 30, 31, -1, -1, 100, -1, -1, 103, 104, -1, -1, -1, -1, -1, -1, -1, -1, 113, -1, -1, 116, -1, -1, 119, 54, 121, -1, -1, 124, 59, 60, -1, -1, -1, -1, -1, -1, -1, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 31, 86, 87, 88, -1, -1, 91, -1, -1, -1, -1, -1, -1, -1, -1, 100, -1, -1, 103, 104, -1, -1, -1, -1, -1, -1, -1, -1, 113, 60, -1, 116, -1, -1, -1, 120, 121, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, -1, -1, 87, 88, -1, 31, 91, 33, 93, 94, 95, 96, 97, 98, 99, 100, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 115, -1, -1, -1, 60, -1, 121, -1, -1, -1, -1, -1, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 31, -1, 87, 88, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 100, 101, 102, -1, -1, -1, -1, -1, -1, 109, 110, 111, 112, -1, 60, -1, -1, -1, -1, -1, -1, 121, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 31, 87, 88, -1, -1, 91, 92, -1, -1, -1, -1, -1, -1, -1, 100, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 113, -1, 60, -1, -1, -1, -1, -1, 121, -1, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 31, 87, 88, -1, -1, 91, -1, -1, -1, -1, -1, -1, -1, -1, 100, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 113, -1, 60, -1, -1, -1, -1, -1, 121, -1, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, -1, -1, 87, 88, -1, -1, 91, -1, -1, -1, -1, -1, -1, -1, -1, 100, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 113, -1, -1, -1, -1, -1, -1, -1, 121 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint16 yystos[] = { 0, 167, 168, 169, 0, 168, 3, 5, 6, 7, 8, 10, 11, 12, 13, 17, 18, 19, 21, 22, 23, 25, 26, 27, 29, 30, 31, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 86, 87, 88, 91, 100, 103, 104, 105, 106, 107, 108, 113, 116, 120, 121, 122, 123, 170, 171, 172, 176, 180, 184, 188, 192, 198, 200, 206, 210, 214, 218, 222, 225, 226, 230, 234, 238, 245, 252, 262, 266, 267, 274, 275, 276, 277, 289, 291, 292, 293, 294, 295, 296, 297, 298, 308, 312, 315, 330, 331, 335, 336, 339, 341, 342, 370, 391, 395, 399, 31, 144, 189, 33, 144, 173, 33, 144, 177, 31, 144, 181, 31, 144, 185, 28, 313, 314, 313, 31, 144, 309, 32, 313, 313, 313, 313, 313, 313, 313, 313, 60, 399, 144, 32, 144, 263, 32, 32, 144, 268, 313, 313, 313, 31, 32, 144, 253, 260, 260, 144, 239, 260, 144, 246, 260, 330, 330, 71, 31, 318, 74, 69, 70, 71, 74, 399, 395, 31, 219, 211, 31, 144, 215, 33, 144, 227, 395, 330, 159, 144, 231, 260, 144, 235, 260, 89, 159, 27, 340, 31, 113, 398, 101, 131, 143, 190, 191, 131, 174, 175, 131, 178, 179, 131, 182, 183, 131, 186, 187, 313, 28, 30, 127, 133, 310, 311, 313, 32, 317, 330, 155, 374, 31, 151, 223, 224, 318, 131, 132, 264, 265, 131, 269, 270, 128, 129, 131, 139, 140, 141, 142, 143, 255, 256, 148, 257, 254, 101, 261, 131, 240, 241, 148, 242, 131, 247, 248, 148, 249, 343, 337, 374, 71, 398, 31, 144, 207, 148, 148, 131, 216, 217, 130, 136, 137, 138, 228, 229, 374, 144, 144, 193, 395, 400, 131, 232, 233, 131, 236, 237, 331, 400, 399, 342, 144, 374, 144, 147, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 162, 164, 165, 371, 154, 156, 397, 147, 147, 145, 146, 147, 145, 146, 147, 145, 146, 147, 145, 146, 147, 145, 146, 147, 147, 145, 146, 313, 31, 375, 376, 199, 31, 90, 145, 152, 147, 147, 145, 146, 147, 145, 146, 147, 147, 147, 147, 147, 147, 147, 147, 145, 146, 4, 9, 222, 225, 258, 259, 299, 303, 261, 147, 145, 146, 222, 225, 243, 244, 303, 147, 145, 146, 222, 225, 250, 251, 303, 161, 345, 345, 316, 397, 374, 154, 148, 208, 31, 220, 221, 31, 212, 213, 147, 145, 146, 147, 147, 147, 147, 145, 146, 93, 94, 95, 96, 97, 98, 99, 115, 380, 381, 382, 395, 396, 330, 374, 146, 160, 147, 145, 146, 147, 145, 146, 160, 374, 380, 148, 392, 145, 144, 147, 147, 147, 147, 147, 147, 147, 147, 147, 159, 147, 160, 163, 147, 147, 144, 91, 31, 33, 359, 101, 191, 33, 175, 33, 179, 31, 183, 31, 187, 31, 101, 311, 147, 146, 155, 148, 202, 31, 151, 318, 32, 110, 111, 332, 265, 32, 270, 33, 33, 260, 332, 332, 332, 31, 101, 256, 144, 300, 33, 144, 304, 149, 259, 260, 241, 149, 244, 260, 248, 149, 251, 61, 62, 63, 346, 347, 348, 374, 374, 148, 150, 31, 171, 209, 341, 150, 149, 221, 149, 213, 359, 217, 33, 33, 33, 33, 229, 318, 318, 318, 318, 318, 144, 144, 318, 145, 146, 318, 147, 324, 145, 148, 194, 395, 260, 233, 260, 237, 201, 145, 14, 15, 16, 222, 225, 393, 394, 150, 395, 147, 147, 380, 31, 33, 101, 260, 377, 376, 24, 45, 46, 47, 92, 203, 204, 205, 222, 225, 277, 286, 290, 315, 31, 134, 301, 302, 125, 305, 306, 313, 150, 150, 150, 146, 330, 344, 338, 31, 222, 225, 319, 320, 321, 145, 149, 171, 374, 374, 374, 374, 374, 380, 380, 374, 91, 372, 382, 374, 144, 325, 328, 329, 117, 195, 196, 197, 222, 225, 277, 202, 372, 313, 313, 313, 149, 394, 14, 271, 145, 145, 161, 313, 313, 313, 313, 395, 149, 204, 147, 145, 146, 147, 145, 146, 347, 148, 349, 349, 147, 323, 149, 321, 144, 324, 324, 324, 145, 145, 114, 401, 330, 152, 153, 154, 155, 156, 157, 326, 151, 152, 153, 154, 156, 158, 327, 313, 149, 196, 401, 313, 15, 272, 150, 372, 261, 31, 150, 33, 302, 33, 306, 20, 31, 35, 36, 37, 38, 39, 40, 41, 42, 43, 46, 47, 48, 61, 62, 63, 64, 65, 67, 85, 92, 119, 124, 192, 206, 222, 225, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 290, 303, 315, 335, 336, 342, 350, 351, 352, 361, 362, 364, 369, 370, 383, 386, 388, 389, 391, 150, 150, 328, 374, 150, 400, 318, 318, 144, 147, 373, 145, 328, 33, 101, 102, 109, 112, 330, 332, 333, 399, 150, 373, 313, 16, 273, 401, 152, 144, 313, 144, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 66, 360, 360, 360, 161, 384, 385, 390, 387, 363, 144, 353, 149, 351, 158, 146, 322, 145, 374, 374, 330, 402, 101, 374, 144, 374, 313, 373, 261, 380, 380, 161, 161, 161, 85, 386, 386, 370, 395, 388, 31, 364, 126, 131, 135, 354, 355, 148, 356, 31, 374, 145, 146, 162, 367, 325, 334, 367, 374, 145, 145, 31, 147, 147, 147, 145, 146, 222, 225, 303, 357, 358, 144, 150, 330, 368, 150, 145, 146, 150, 367, 372, 401, 31, 359, 31, 355, 149, 358, 145, 395, 44, 378, 325, 303, 307, 150, 401, 374, 150, 401, 144, 313, 34, 379, 378, 378, 374, 162, 365, 373, 380, 313, 379, 379, 367, 366, 150, 374, 145, 150, 144, 307, 150, 163, 307, 380, 378, 378, 378, 145, 379, 163 }; #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 531 "/Users/phil/hg/sip/sip-4.15.5/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 51: #line 597 "/Users/phil/hg/sip/sip-4.15.5/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 52: #line 610 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) currentModule->defdocstring = convertFormat((yyvsp[(2) - (2)].defdocstring).name); } break; case 53: #line 616 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.defdocstring).name = (yyvsp[(1) - (1)].text); } break; case 54: #line 621 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.defdocstring) = (yyvsp[(2) - (3)].defdocstring); } break; case 56: #line 627 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.defdocstring) = (yyvsp[(1) - (3)].defdocstring); switch ((yyvsp[(3) - (3)].defdocstring).token) { case TK_NAME: (yyval.defdocstring).name = (yyvsp[(3) - (3)].defdocstring).name; break; } } break; case 57: #line 637 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.defdocstring).token = TK_NAME; (yyval.defdocstring).name = (yyvsp[(3) - (3)].text); } break; case 58: #line 644 "/Users/phil/hg/sip/sip-4.15.5/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 59: #line 653 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.defencoding).name = (yyvsp[(1) - (1)].text); } break; case 60: #line 658 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.defencoding) = (yyvsp[(2) - (3)].defencoding); } break; case 62: #line 664 "/Users/phil/hg/sip/sip-4.15.5/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 63: #line 674 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.defencoding).token = TK_NAME; (yyval.defencoding).name = (yyvsp[(3) - (3)].text); } break; case 64: #line 681 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { /* Note that %Plugin is internal in SIP v4. */ if (notSkipping()) appendString(¤tSpec->plugins, (yyvsp[(2) - (2)].plugin).name); } break; case 65: #line 689 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.plugin).name = (yyvsp[(1) - (1)].text); } break; case 66: #line 694 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.plugin) = (yyvsp[(2) - (3)].plugin); } break; case 68: #line 700 "/Users/phil/hg/sip/sip-4.15.5/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 69: #line 710 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.plugin).token = TK_NAME; (yyval.plugin).name = (yyvsp[(3) - (3)].text); } break; case 70: #line 717 "/Users/phil/hg/sip/sip-4.15.5/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 = currentModule->nrvirterrorhandlers++; veh->next = NULL; *tailp = veh; } } break; case 71: #line 746 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.veh).name = (yyvsp[(1) - (1)].text); } break; case 72: #line 751 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.veh) = (yyvsp[(2) - (3)].veh); } break; case 74: #line 757 "/Users/phil/hg/sip/sip-4.15.5/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 75: #line 767 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.veh).token = TK_NAME; (yyval.veh).name = (yyvsp[(3) - (3)].text); } break; case 76: #line 774 "/Users/phil/hg/sip/sip-4.15.5/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 77: #line 800 "/Users/phil/hg/sip/sip-4.15.5/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 78: #line 808 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.api) = (yyvsp[(2) - (3)].api); } break; case 80: #line 814 "/Users/phil/hg/sip/sip-4.15.5/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 81: #line 825 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.api).token = TK_NAME; (yyval.api).name = (yyvsp[(3) - (3)].text); (yyval.api).version = 0; } break; case 82: #line 831 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.api).token = TK_VERSION; (yyval.api).name = NULL; (yyval.api).version = (yyvsp[(3) - (3)].number); } break; case 83: #line 839 "/Users/phil/hg/sip/sip-4.15.5/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; if (xd->bibase != NULL || xd->base != NULL) xd->exceptionnr = currentModule->nrexceptions++; } } break; case 84: #line 889 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.exceptionbase).bibase = NULL; (yyval.exceptionbase).base = NULL; } break; case 85: #line 893 "/Users/phil/hg/sip/sip-4.15.5/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[] = { "Exception", "StopIteration", "StandardError", "ArithmeticError", "LookupError", "AssertionError", "AttributeError", "EOFError", "FloatingPointError", "EnvironmentError", "IOError", "OSError", "ImportError", "IndexError", "KeyError", "KeyboardInterrupt", "MemoryError", "NameError", "OverflowError", "RuntimeError", "NotImplementedError", "SyntaxError", "IndentationError", "TabError", "ReferenceError", "SystemError", "SystemExit", "TypeError", "UnboundLocalError", "UnicodeError", "UnicodeEncodeError", "UnicodeDecodeError", "UnicodeTranslateError", "ValueError", "ZeroDivisionError", "WindowsError", "VMSError", NULL }; char **cp; for (cp = builtins; *cp != NULL; ++cp) if (strcmp((yyvsp[(2) - (3)].scpvalp)->name + 4, *cp) == 0) { (yyval.exceptionbase).bibase = *cp; break; } } if ((yyval.exceptionbase).bibase == NULL && (yyval.exceptionbase).base == NULL) yyerror("Unknown exception base type"); } break; case 86: #line 967 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.exception) = (yyvsp[(2) - (4)].exception); } break; case 88: #line 973 "/Users/phil/hg/sip/sip-4.15.5/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 89: #line 984 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.exception).token = TK_IF; } break; case 90: #line 987 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.exception).token = TK_END; } break; case 91: #line 990 "/Users/phil/hg/sip/sip-4.15.5/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 92: #line 1004 "/Users/phil/hg/sip/sip-4.15.5/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 93: #line 1020 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 94: #line 1025 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) { static const char *annos[] = { "AllowNone", "API", "DocType", "NoRelease", "PyName", NULL }; checkAnnos(&(yyvsp[(3) - (3)].optflags), annos); currentMappedType = newMappedType(currentSpec, &(yyvsp[(2) - (3)].memArg), &(yyvsp[(3) - (3)].optflags)); } } break; case 96: #line 1044 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) { static const char *annos[] = { "AllowNone", "DocType", "NoRelease", 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"); /* 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 98: #line 1105 "/Users/phil/hg/sip/sip-4.15.5/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 103: #line 1125 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tMappedType->iff->hdrcode, (yyvsp[(1) - (1)].codeb)); } break; case 104: #line 1129 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tMappedType->typecode, (yyvsp[(1) - (1)].codeb)); } break; case 105: #line 1133 "/Users/phil/hg/sip/sip-4.15.5/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 106: #line 1142 "/Users/phil/hg/sip/sip-4.15.5/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 107: #line 1151 "/Users/phil/hg/sip/sip-4.15.5/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 110: #line 1164 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) { applyTypeFlags(currentModule, &(yyvsp[(2) - (13)].memArg), &(yyvsp[(9) - (13)].optflags)); (yyvsp[(5) - (13)].signature).result = (yyvsp[(2) - (13)].memArg); newFunction(currentSpec, currentModule, NULL, currentMappedType, 0, TRUE, FALSE, FALSE, FALSE, (yyvsp[(3) - (13)].text), &(yyvsp[(5) - (13)].signature), (yyvsp[(7) - (13)].number), FALSE, &(yyvsp[(9) - (13)].optflags), (yyvsp[(13) - (13)].codeb), NULL, (yyvsp[(8) - (13)].throwlist), (yyvsp[(10) - (13)].optsignature), (yyvsp[(12) - (13)].codeb)); } } break; case 111: #line 1178 "/Users/phil/hg/sip/sip-4.15.5/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); pushScope(ns); sectionFlags = 0; } } break; case 112: #line 1199 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) { if (inMainModule()) { classDef *ns = currentScope(); setIsUsedName(ns->iff->name); setIsUsedName(ns->pyname); } popScope(); } } break; case 117: #line 1223 "/Users/phil/hg/sip/sip-4.15.5/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 118: #line 1233 "/Users/phil/hg/sip/sip-4.15.5/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 121: #line 1256 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { newQualifier(currentModule,-1,-1,(yyvsp[(1) - (1)].text),platform_qualifier); } break; case 122: #line 1261 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) newQualifier(currentModule, -1, -1, (yyvsp[(2) - (2)].feature).name, feature_qualifier); } break; case 123: #line 1268 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.feature).name = (yyvsp[(1) - (1)].text); } break; case 124: #line 1273 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.feature) = (yyvsp[(2) - (3)].feature); } break; case 126: #line 1279 "/Users/phil/hg/sip/sip-4.15.5/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 127: #line 1289 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.feature).token = TK_NAME; (yyval.feature).name = (yyvsp[(3) - (3)].text); } break; case 128: #line 1296 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { currentTimelineOrder = 0; } break; case 129: #line 1299 "/Users/phil/hg/sip/sip-4.15.5/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 132: #line 1326 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { newQualifier(currentModule, currentModule->nrtimelines, currentTimelineOrder++, (yyvsp[(1) - (1)].text), time_qualifier); } break; case 133: #line 1332 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (skipStackPtr >= MAX_NESTED_IF) yyerror("Internal error: increase the value of MAX_NESTED_IF"); /* Nested %Ifs are implicit logical ands. */ if (skipStackPtr > 0) (yyvsp[(3) - (4)].boolean) = ((yyvsp[(3) - (4)].boolean) && skipStack[skipStackPtr - 1]); skipStack[skipStackPtr++] = (yyvsp[(3) - (4)].boolean); } break; case 134: #line 1345 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.boolean) = platOrFeature((yyvsp[(1) - (1)].text),FALSE); } break; case 135: #line 1348 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.boolean) = platOrFeature((yyvsp[(2) - (2)].text),TRUE); } break; case 136: #line 1351 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.boolean) = (platOrFeature((yyvsp[(3) - (3)].text),FALSE) || (yyvsp[(1) - (3)].boolean)); } break; case 137: #line 1354 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.boolean) = (platOrFeature((yyvsp[(4) - (4)].text),TRUE) || (yyvsp[(1) - (4)].boolean)); } break; case 139: #line 1360 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.boolean) = timePeriod((yyvsp[(1) - (3)].text), (yyvsp[(3) - (3)].text)); } break; case 140: #line 1365 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (skipStackPtr-- <= 0) yyerror("Too many %End directives"); } break; case 141: #line 1371 "/Users/phil/hg/sip/sip-4.15.5/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 142: #line 1408 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.license).type = NULL; (yyval.license).licensee = NULL; (yyval.license).signature = NULL; (yyval.license).timestamp = NULL; } break; case 143: #line 1416 "/Users/phil/hg/sip/sip-4.15.5/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 144: #line 1422 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.license) = (yyvsp[(2) - (3)].license); } break; case 146: #line 1428 "/Users/phil/hg/sip/sip-4.15.5/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 147: #line 1441 "/Users/phil/hg/sip/sip-4.15.5/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 148: #line 1449 "/Users/phil/hg/sip/sip-4.15.5/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 149: #line 1457 "/Users/phil/hg/sip/sip-4.15.5/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 150: #line 1465 "/Users/phil/hg/sip/sip-4.15.5/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 151: #line 1475 "/Users/phil/hg/sip/sip-4.15.5/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 152: #line 1486 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.defmetatype).name = (yyvsp[(1) - (1)].text); } break; case 153: #line 1491 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.defmetatype) = (yyvsp[(2) - (3)].defmetatype); } break; case 155: #line 1497 "/Users/phil/hg/sip/sip-4.15.5/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 156: #line 1507 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.defmetatype).token = TK_NAME; (yyval.defmetatype).name = (yyvsp[(3) - (3)].text); } break; case 157: #line 1514 "/Users/phil/hg/sip/sip-4.15.5/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 158: #line 1525 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.defsupertype).name = (yyvsp[(1) - (1)].text); } break; case 159: #line 1530 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.defsupertype) = (yyvsp[(2) - (3)].defsupertype); } break; case 161: #line 1536 "/Users/phil/hg/sip/sip-4.15.5/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 162: #line 1546 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.defsupertype).token = TK_NAME; (yyval.defsupertype).name = (yyvsp[(3) - (3)].text); } break; case 163: #line 1553 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { 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); appendCodeBlock(¤tModule->docstring, (yyvsp[(3) - (3)].consmodule).docstring); setIsConsolidated(currentModule); } } break; case 164: #line 1571 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.consmodule).name = (yyvsp[(1) - (1)].text); } break; case 165: #line 1576 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.consmodule) = (yyvsp[(2) - (3)].consmodule); } break; case 167: #line 1582 "/Users/phil/hg/sip/sip-4.15.5/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 168: #line 1592 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.consmodule).token = TK_NAME; (yyval.consmodule).name = (yyvsp[(3) - (3)].text); } break; case 169: #line 1599 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.consmodule).token = 0; (yyval.consmodule).docstring = NULL; } break; case 170: #line 1603 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.consmodule) = (yyvsp[(2) - (4)].consmodule); } break; case 172: #line 1609 "/Users/phil/hg/sip/sip-4.15.5/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 173: #line 1619 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.consmodule).token = TK_IF; } break; case 174: #line 1622 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.consmodule).token = TK_END; } break; case 175: #line 1625 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) { (yyval.consmodule).token = TK_DOCSTRING; (yyval.consmodule).docstring = (yyvsp[(1) - (1)].codeb); } else { (yyval.consmodule).token = 0; (yyval.consmodule).docstring = NULL; } } break; case 176: #line 1639 "/Users/phil/hg/sip/sip-4.15.5/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); appendCodeBlock(¤tModule->docstring, (yyvsp[(3) - (3)].compmodule).docstring); setIsComposite(currentModule); } } break; case 177: #line 1657 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.compmodule).name = (yyvsp[(1) - (1)].text); } break; case 178: #line 1662 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.compmodule) = (yyvsp[(2) - (3)].compmodule); } break; case 180: #line 1668 "/Users/phil/hg/sip/sip-4.15.5/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 181: #line 1678 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.compmodule).token = TK_NAME; (yyval.compmodule).name = (yyvsp[(3) - (3)].text); } break; case 182: #line 1685 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.compmodule).token = 0; (yyval.compmodule).docstring = NULL; } break; case 183: #line 1689 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.compmodule) = (yyvsp[(2) - (4)].compmodule); } break; case 185: #line 1695 "/Users/phil/hg/sip/sip-4.15.5/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 186: #line 1705 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.compmodule).token = TK_IF; } break; case 187: #line 1708 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.compmodule).token = TK_END; } break; case 188: #line 1711 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) { (yyval.compmodule).token = TK_DOCSTRING; (yyval.compmodule).docstring = (yyvsp[(1) - (1)].codeb); } else { (yyval.compmodule).token = 0; (yyval.compmodule).docstring = NULL; } } break; case 189: #line 1725 "/Users/phil/hg/sip/sip-4.15.5/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).version, (yyvsp[(2) - (3)].module).c_module, (yyvsp[(2) - (3)].module).kwargs, (yyvsp[(2) - (3)].module).use_arg_names, (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 190: #line 1736 "/Users/phil/hg/sip/sip-4.15.5/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), (yyvsp[(3) - (3)].number), TRUE, defaultKwArgs, FALSE, -1, FALSE, NULL, NULL); } break; case 191: #line 1746 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {resetLexerState();} break; case 192: #line 1746 "/Users/phil/hg/sip/sip-4.15.5/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).all_raise_py_exc = FALSE; (yyval.module).call_super_init = -1; (yyval.module).def_error_handler = NULL; (yyval.module).version = (yyvsp[(3) - (3)].number); } break; case 193: #line 1759 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.module) = (yyvsp[(2) - (3)].module); } break; case 195: #line 1765 "/Users/phil/hg/sip/sip-4.15.5/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_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; case TK_VERSION: (yyval.module).version = (yyvsp[(3) - (3)].module).version; break; } } break; case 196: #line 1782 "/Users/phil/hg/sip/sip-4.15.5/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).all_raise_py_exc = FALSE; (yyval.module).call_super_init = -1; (yyval.module).def_error_handler = NULL; (yyval.module).version = -1; } break; case 197: #line 1794 "/Users/phil/hg/sip/sip-4.15.5/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).all_raise_py_exc = FALSE; (yyval.module).call_super_init = -1; (yyval.module).def_error_handler = NULL; (yyval.module).version = -1; } break; case 198: #line 1812 "/Users/phil/hg/sip/sip-4.15.5/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).all_raise_py_exc = FALSE; (yyval.module).call_super_init = -1; (yyval.module).def_error_handler = NULL; (yyval.module).version = -1; } break; case 199: #line 1824 "/Users/phil/hg/sip/sip-4.15.5/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).all_raise_py_exc = FALSE; (yyval.module).call_super_init = -1; (yyval.module).def_error_handler = NULL; (yyval.module).version = -1; } break; case 200: #line 1836 "/Users/phil/hg/sip/sip-4.15.5/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).all_raise_py_exc = (yyvsp[(3) - (3)].boolean); (yyval.module).call_super_init = -1; (yyval.module).def_error_handler = NULL; (yyval.module).version = -1; } break; case 201: #line 1848 "/Users/phil/hg/sip/sip-4.15.5/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).all_raise_py_exc = FALSE; (yyval.module).call_super_init = (yyvsp[(3) - (3)].boolean); (yyval.module).def_error_handler = NULL; (yyval.module).version = -1; } break; case 202: #line 1860 "/Users/phil/hg/sip/sip-4.15.5/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).all_raise_py_exc = FALSE; (yyval.module).call_super_init = -1; (yyval.module).def_error_handler = (yyvsp[(3) - (3)].text); (yyval.module).version = -1; } break; case 203: #line 1872 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { 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).all_raise_py_exc = FALSE; (yyval.module).call_super_init = -1; (yyval.module).def_error_handler = NULL; (yyval.module).version = (yyvsp[(3) - (3)].number); } break; case 204: #line 1889 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.module).token = 0; (yyval.module).docstring = NULL; } break; case 205: #line 1893 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.module) = (yyvsp[(2) - (4)].module); } break; case 207: #line 1899 "/Users/phil/hg/sip/sip-4.15.5/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 208: #line 1909 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.module).token = TK_IF; } break; case 209: #line 1912 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.module).token = TK_END; } break; case 210: #line 1915 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.module).token = TK_AUTOPYNAME; } break; case 211: #line 1918 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) { (yyval.module).token = TK_DOCSTRING; (yyval.module).docstring = (yyvsp[(1) - (1)].codeb); } else { (yyval.module).token = 0; (yyval.module).docstring = NULL; } } break; case 213: #line 1933 "/Users/phil/hg/sip/sip-4.15.5/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 214: #line 1949 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.number) = -1; } break; case 216: #line 1955 "/Users/phil/hg/sip/sip-4.15.5/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 217: #line 1964 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.include).name = (yyvsp[(1) - (1)].text); (yyval.include).optional = FALSE; } break; case 218: #line 1970 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.include) = (yyvsp[(2) - (3)].include); } break; case 220: #line 1976 "/Users/phil/hg/sip/sip-4.15.5/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 221: #line 1987 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.include).token = TK_NAME; (yyval.include).name = (yyvsp[(3) - (3)].text); (yyval.include).optional = FALSE; } break; case 222: #line 1993 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.include).token = TK_OPTIONAL; (yyval.include).name = NULL; (yyval.include).optional = (yyvsp[(3) - (3)].boolean); } break; case 223: #line 2001 "/Users/phil/hg/sip/sip-4.15.5/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 224: #line 2009 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) newImport((yyvsp[(2) - (2)].import).name); } break; case 225: #line 2015 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.import).name = (yyvsp[(1) - (1)].text); } break; case 226: #line 2020 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.import) = (yyvsp[(2) - (3)].import); } break; case 228: #line 2026 "/Users/phil/hg/sip/sip-4.15.5/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 229: #line 2036 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.import).token = TK_NAME; (yyval.import).name = (yyvsp[(3) - (3)].text); } break; case 230: #line 2043 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = NULL; } break; case 231: #line 2046 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 232: #line 2051 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = NULL; } break; case 233: #line 2054 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 234: #line 2059 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = NULL; } break; case 235: #line 2062 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 236: #line 2067 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tModule->copying, (yyvsp[(2) - (2)].codeb)); } break; case 237: #line 2073 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tSpec->exphdrcode, (yyvsp[(2) - (2)].codeb)); } break; case 238: #line 2079 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tModule->hdrcode, (yyvsp[(2) - (2)].codeb)); } break; case 239: #line 2085 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 240: #line 2090 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 241: #line 2095 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 242: #line 2100 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 243: #line 2105 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 244: #line 2110 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 245: #line 2115 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 246: #line 2120 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 247: #line 2125 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 248: #line 2130 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 249: #line 2135 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 250: #line 2140 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 251: #line 2145 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tModule->cppcode, (yyvsp[(2) - (2)].codeb)); } break; case 252: #line 2151 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 253: #line 2156 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tModule->preinitcode, (yyvsp[(2) - (2)].codeb)); } break; case 254: #line 2162 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tModule->initcode, (yyvsp[(2) - (2)].codeb)); } break; case 255: #line 2168 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tModule->postinitcode, (yyvsp[(2) - (2)].codeb)); } break; case 256: #line 2174 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tModule->unitcode, (yyvsp[(2) - (2)].codeb)); } break; case 257: #line 2180 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tModule->unitpostinccode, (yyvsp[(2) - (2)].codeb)); } break; case 258: #line 2186 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { /* Deprecated. */ } break; case 259: #line 2191 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping() && inMainModule()) appendCodeBlock(¤tSpec->docs, (yyvsp[(2) - (2)].codeb)); } break; case 260: #line 2197 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tSpec->docs, (yyvsp[(2) - (2)].codeb)); } break; case 261: #line 2203 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) addAutoPyName(currentModule, (yyvsp[(2) - (2)].autopyname).remove_leading); } break; case 262: #line 2209 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.autopyname) = (yyvsp[(2) - (3)].autopyname); } break; case 264: #line 2215 "/Users/phil/hg/sip/sip-4.15.5/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 265: #line 2225 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.autopyname).token = TK_REMOVELEADING; (yyval.autopyname).remove_leading = (yyvsp[(3) - (3)].text); } break; case 266: #line 2232 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = (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.codeb)->frag; *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. */ dp = cp = (yyval.codeb)->frag; 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 267: #line 2312 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.docstring).format = currentModule->defdocstring; } break; case 268: #line 2315 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.docstring).format = convertFormat((yyvsp[(1) - (1)].text)); } break; case 269: #line 2320 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.docstring) = (yyvsp[(2) - (3)].docstring); } break; case 271: #line 2326 "/Users/phil/hg/sip/sip-4.15.5/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; } } break; case 272: #line 2336 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.docstring).token = TK_FORMAT; (yyval.docstring).format = convertFormat((yyvsp[(3) - (3)].text)); } break; case 273: #line 2343 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = NULL; } break; case 275: #line 2349 "/Users/phil/hg/sip/sip-4.15.5/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 276: #line 2358 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { resetLexerState(); (yyval.extract).id = (yyvsp[(1) - (1)].text); (yyval.extract).order = -1; } break; case 277: #line 2364 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.extract) = (yyvsp[(2) - (3)].extract); } break; case 279: #line 2370 "/Users/phil/hg/sip/sip-4.15.5/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 280: #line 2381 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.extract).token = TK_ID; (yyval.extract).id = (yyvsp[(3) - (3)].text); (yyval.extract).order = -1; } break; case 281: #line 2387 "/Users/phil/hg/sip/sip-4.15.5/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 282: #line 2398 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { /* Deprecated. */ } break; case 285: #line 2407 "/Users/phil/hg/sip/sip-4.15.5/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 286: #line 2417 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) { const char *annos[] = { "NoScope", "PyName", NULL }; checkAnnos(&(yyvsp[(3) - (3)].optflags), annos); if (sectionFlags != 0 && (sectionFlags & ~(SECT_IS_PUBLIC | SECT_IS_PROT)) != 0) yyerror("Class enums must be in the public or protected sections"); currentEnum = newEnum(currentSpec, currentModule, currentMappedType, (yyvsp[(2) - (3)].text), &(yyvsp[(3) - (3)].optflags), sectionFlags); } } break; case 288: #line 2437 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.text) = NULL; } break; case 289: #line 2440 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.text) = (yyvsp[(1) - (1)].text); } break; case 290: #line 2445 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.text) = NULL; } break; case 291: #line 2448 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.text) = (yyvsp[(1) - (1)].text); } break; case 298: #line 2463 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) { const char *annos[] = { "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 -> ed = currentEnum; emd -> next = NULL; checkAttributes(currentSpec, currentModule, emd->ed->ecd, emd->ed->emtd, emd->pyname->text, FALSE); /* Append to preserve the order. */ for (tail = ¤tEnum->members; *tail != NULL; tail = &(*tail)->next) ; *tail = emd; if (inMainModule()) setIsUsedName(emd -> pyname); } } break; case 303: #line 2507 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.valp) = NULL; } break; case 304: #line 2510 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.valp) = (yyvsp[(2) - (2)].valp); } break; case 306: #line 2516 "/Users/phil/hg/sip/sip-4.15.5/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 307: #line 2534 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.qchar) = '-'; } break; case 308: #line 2537 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.qchar) = '+'; } break; case 309: #line 2540 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.qchar) = '*'; } break; case 310: #line 2543 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.qchar) = '/'; } break; case 311: #line 2546 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.qchar) = '&'; } break; case 312: #line 2549 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.qchar) = '|'; } break; case 313: #line 2554 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.qchar) = '\0'; } break; case 314: #line 2557 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.qchar) = '!'; } break; case 315: #line 2560 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.qchar) = '~'; } break; case 316: #line 2563 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.qchar) = '-'; } break; case 317: #line 2566 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.qchar) = '+'; } break; case 318: #line 2569 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.qchar) = '*'; } break; case 319: #line 2572 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.qchar) = '&'; } break; case 320: #line 2577 "/Users/phil/hg/sip/sip-4.15.5/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 321: #line 2592 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.scpvalp) = NULL; } break; case 322: #line 2595 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.scpvalp) = (yyvsp[(2) - (3)].scpvalp); } break; case 324: #line 2601 "/Users/phil/hg/sip/sip-4.15.5/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 325: #line 2609 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.scpvalp) = text2scopePart((yyvsp[(1) - (1)].text)); } break; case 326: #line 2614 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.boolean) = TRUE; } break; case 327: #line 2617 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.boolean) = FALSE; } break; case 328: #line 2622 "/Users/phil/hg/sip/sip-4.15.5/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 329: #line 2631 "/Users/phil/hg/sip/sip-4.15.5/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 330: #line 2641 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.value).vtype = real_value; (yyval.value).u.vreal = (yyvsp[(1) - (1)].real); } break; case 331: #line 2645 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.value).vtype = numeric_value; (yyval.value).u.vnum = (yyvsp[(1) - (1)].number); } break; case 332: #line 2649 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.value).vtype = numeric_value; (yyval.value).u.vnum = (yyvsp[(1) - (1)].boolean); } break; case 333: #line 2653 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.value).vtype = numeric_value; (yyval.value).u.vnum = 0; } break; case 334: #line 2657 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.value).vtype = string_value; (yyval.value).u.vstr = (yyvsp[(1) - (1)].text); } break; case 335: #line 2661 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.value).vtype = qchar_value; (yyval.value).u.vqchar = (yyvsp[(1) - (1)].qchar); } break; case 336: #line 2667 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { /* No values. */ (yyval.fcall).nrArgs = 0; } break; case 337: #line 2672 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { /* The single or first expression. */ (yyval.fcall).args[0] = (yyvsp[(1) - (1)].valp); (yyval.fcall).nrArgs = 1; } break; case 338: #line 2678 "/Users/phil/hg/sip/sip-4.15.5/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 339: #line 2696 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) { const char *annos[] = { "Capsule", "DocType", "Encoding", "NoTypeName", "PyInt", "PyName", NULL }; checkAnnos(&(yyvsp[(4) - (5)].optflags), annos); applyTypeFlags(currentModule, &(yyvsp[(2) - (5)].memArg), &(yyvsp[(4) - (5)].optflags)); newTypedef(currentSpec, currentModule, (yyvsp[(3) - (5)].text), &(yyvsp[(2) - (5)].memArg), &(yyvsp[(4) - (5)].optflags)); } } break; case 340: #line 2715 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) { const char *annos[] = { "DocType", "Encoding", "NoTypeName", "PyInt", "PyName", NULL }; signatureDef *sig; argDef ftype; checkAnnos(&(yyvsp[(10) - (11)].optflags), annos); applyTypeFlags(currentModule, &(yyvsp[(2) - (11)].memArg), &(yyvsp[(10) - (11)].optflags)); memset(&ftype, 0, sizeof (argDef)); /* Create the full signature on the heap. */ sig = sipMalloc(sizeof (signatureDef)); *sig = (yyvsp[(8) - (11)].signature); sig->result = (yyvsp[(2) - (11)].memArg); /* Create the full type. */ ftype.atype = function_type; ftype.nrderefs = 1; ftype.u.sa = sig; newTypedef(currentSpec, currentModule, (yyvsp[(5) - (11)].text), &ftype, &(yyvsp[(10) - (11)].optflags)); } } break; case 341: #line 2751 "/Users/phil/hg/sip/sip-4.15.5/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 342: #line 2757 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) { const char *annos[] = { "Abstract", "AllowNone", "API", "DelayDtor", "Deprecated", "ExportDerived", "External", "Metatype", "Mixin", "NoDefaultCtors", "PyName", "PyQtFlags", "PyQtInterface", "PyQtNoQMetaObject", "Supertype", "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 343: #line 2788 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) completeClass((yyvsp[(2) - (8)].scpvalp), &(yyvsp[(5) - (8)].optflags), (yyvsp[(7) - (8)].boolean)); } break; case 344: #line 2794 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {currentIsTemplate = TRUE;} break; case 345: #line 2794 "/Users/phil/hg/sip/sip-4.15.5/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 346: #line 2820 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.signature) = (yyvsp[(3) - (4)].signature); } break; case 347: #line 2825 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (currentSpec->genc) yyerror("Class definition not allowed in a C module"); if (notSkipping()) currentSupers = NULL; } break; case 348: #line 2831 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) { const char *annos[] = { "Abstract", "AllowNone", "API", "DelayDtor", "Deprecated", "ExportDerived", "External", "Metatype", "Mixin", "NoDefaultCtors", "PyName", "PyQtFlags", "PyQtInterface", "PyQtNoQMetaObject", "Supertype", "VirtualErrorHandler", NULL }; checkAnnos(&(yyvsp[(5) - (5)].optflags), annos); defineClass((yyvsp[(2) - (5)].scpvalp), currentSupers, &(yyvsp[(5) - (5)].optflags)); sectionFlags = SECT_IS_PRIVATE; } } break; case 349: #line 2859 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) (yyval.klass) = completeClass((yyvsp[(2) - (8)].scpvalp), &(yyvsp[(5) - (8)].optflags), (yyvsp[(7) - (8)].boolean)); } break; case 354: #line 2873 "/Users/phil/hg/sip/sip-4.15.5/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"); /* * 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); appendToClassList(¤tSupers, super); } } break; case 355: #line 2917 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.token) = TK_PUBLIC; } break; case 356: #line 2920 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.token) = TK_PUBLIC; } break; case 357: #line 2923 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.token) = TK_PROTECTED; } break; case 358: #line 2926 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.token) = TK_PRIVATE; } break; case 359: #line 2931 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.boolean) = FALSE; } break; case 360: #line 2934 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.boolean) = TRUE; } break; case 372: #line 2952 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tScope()->docstring, (yyvsp[(1) - (1)].codeb)); } break; case 373: #line 2956 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tScope()->cppcode, (yyvsp[(1) - (1)].codeb)); } break; case 374: #line 2960 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) appendCodeBlock(¤tScope()->iff->hdrcode, (yyvsp[(1) - (1)].codeb)); } break; case 375: #line 2964 "/Users/phil/hg/sip/sip-4.15.5/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 376: #line 2975 "/Users/phil/hg/sip/sip-4.15.5/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 377: #line 2986 "/Users/phil/hg/sip/sip-4.15.5/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 378: #line 2997 "/Users/phil/hg/sip/sip-4.15.5/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 379: #line 3008 "/Users/phil/hg/sip/sip-4.15.5/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 380: #line 3019 "/Users/phil/hg/sip/sip-4.15.5/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 381: #line 3030 "/Users/phil/hg/sip/sip-4.15.5/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 382: #line 3041 "/Users/phil/hg/sip/sip-4.15.5/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 383: #line 3052 "/Users/phil/hg/sip/sip-4.15.5/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 384: #line 3063 "/Users/phil/hg/sip/sip-4.15.5/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 385: #line 3074 "/Users/phil/hg/sip/sip-4.15.5/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 389: #line 3088 "/Users/phil/hg/sip/sip-4.15.5/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 390: #line 3099 "/Users/phil/hg/sip/sip-4.15.5/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 391: #line 3110 "/Users/phil/hg/sip/sip-4.15.5/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 392: #line 3121 "/Users/phil/hg/sip/sip-4.15.5/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 393: #line 3128 "/Users/phil/hg/sip/sip-4.15.5/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 394: #line 3135 "/Users/phil/hg/sip/sip-4.15.5/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 395: #line 3142 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (currentSpec -> genc) yyerror("signals section not allowed in a C module"); if (notSkipping()) sectionFlags = SECT_IS_SIGNAL; } break; case 396: #line 3151 "/Users/phil/hg/sip/sip-4.15.5/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 397: #line 3164 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.property) = (yyvsp[(2) - (3)].property); } break; case 399: #line 3170 "/Users/phil/hg/sip/sip-4.15.5/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 400: #line 3182 "/Users/phil/hg/sip/sip-4.15.5/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 401: #line 3189 "/Users/phil/hg/sip/sip-4.15.5/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 402: #line 3196 "/Users/phil/hg/sip/sip-4.15.5/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 403: #line 3205 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.property).token = 0; (yyval.property).docstring = NULL; } break; case 404: #line 3209 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.property) = (yyvsp[(2) - (4)].property); } break; case 406: #line 3215 "/Users/phil/hg/sip/sip-4.15.5/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 407: #line 3225 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.property).token = TK_IF; } break; case 408: #line 3228 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.property).token = TK_END; } break; case 409: #line 3231 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) { (yyval.property).token = TK_DOCSTRING; (yyval.property).docstring = (yyvsp[(1) - (1)].codeb); } else { (yyval.property).token = 0; (yyval.property).docstring = NULL; } } break; case 412: #line 3249 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.number) = 0; } break; case 413: #line 3252 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.number) = SECT_IS_SLOT; } break; case 414: #line 3257 "/Users/phil/hg/sip/sip-4.15.5/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) - (11)].optflags), annos); if (strcmp(classBaseName(cd),(yyvsp[(3) - (11)].text)) != 0) yyerror("Destructor doesn't have the same name as its class"); if (isDtor(cd)) yyerror("Destructor has already been defined"); if (currentSpec -> genc && (yyvsp[(10) - (11)].codeb) == NULL) yyerror("Destructor in C modules must include %MethodCode"); appendCodeBlock(&cd->dealloccode, (yyvsp[(10) - (11)].codeb)); appendCodeBlock(&cd->dtorcode, (yyvsp[(11) - (11)].codeb)); cd -> dtorexceptions = (yyvsp[(6) - (11)].throwlist); /* * Note that we don't apply the protected/public hack to dtors * as it (I think) may change the behaviour of the wrapped API. */ cd->classflags |= sectionFlags; if ((yyvsp[(7) - (11)].number)) { if (!(yyvsp[(1) - (11)].number)) yyerror("Abstract destructor must be virtual"); setIsAbstractClass(cd); } /* * The class has a shadow if we have a virtual dtor or some * dtor code. */ if ((yyvsp[(1) - (11)].number) || (yyvsp[(11) - (11)].codeb) != NULL) { if (currentSpec -> genc) yyerror("Virtual destructor or %VirtualCatcherCode not allowed in a C module"); setHasShadow(cd); } if (getReleaseGIL(&(yyvsp[(8) - (11)].optflags))) setIsReleaseGILDtor(cd); else if (getHoldGIL(&(yyvsp[(8) - (11)].optflags))) setIsHoldGILDtor(cd); } } break; case 415: #line 3319 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {currentCtorIsExplicit = TRUE;} break; case 418: #line 3323 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { /* Note that we allow ctors in C modules. */ if (notSkipping()) { const char *annos[] = { "API", "Default", "Deprecated", "HoldGIL", "KeywordArgs", "NoDerived", "NoRaisesPyException", "PostHook", "PreHook", "RaisesPyException", "ReleaseGIL", "Transfer", NULL }; checkAnnos(&(yyvsp[(6) - (10)].optflags), annos); if (currentSpec -> genc) { if ((yyvsp[(10) - (10)].codeb) == NULL && (yyvsp[(3) - (10)].signature).nrArgs != 0) yyerror("Constructors with arguments in C modules must include %MethodCode"); if (currentCtorIsExplicit) yyerror("Explicit constructors not allowed in a C module"); } if ((sectionFlags & (SECT_IS_PUBLIC | SECT_IS_PROT | SECT_IS_PRIVATE)) == 0) yyerror("Constructor must be in the public, private or protected sections"); newCtor(currentModule, (yyvsp[(1) - (10)].text), sectionFlags, &(yyvsp[(3) - (10)].signature), &(yyvsp[(6) - (10)].optflags), (yyvsp[(10) - (10)].codeb), (yyvsp[(5) - (10)].throwlist), (yyvsp[(7) - (10)].optsignature), currentCtorIsExplicit, (yyvsp[(9) - (10)].codeb)); } free((yyvsp[(1) - (10)].text)); currentCtorIsExplicit = FALSE; } break; case 419: #line 3368 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.optsignature) = NULL; } break; case 420: #line 3371 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { parsingCSignature = TRUE; } break; case 421: #line 3373 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.optsignature) = sipMalloc(sizeof (signatureDef)); *(yyval.optsignature) = (yyvsp[(4) - (6)].signature); parsingCSignature = FALSE; } break; case 422: #line 3382 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.optsignature) = NULL; } break; case 423: #line 3385 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { parsingCSignature = TRUE; } break; case 424: #line 3387 "/Users/phil/hg/sip/sip-4.15.5/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 425: #line 3397 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.number) = FALSE; } break; case 426: #line 3400 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.number) = TRUE; } break; case 427: #line 3405 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) { applyTypeFlags(currentModule, &(yyvsp[(1) - (14)].memArg), &(yyvsp[(9) - (14)].optflags)); (yyvsp[(4) - (14)].signature).result = (yyvsp[(1) - (14)].memArg); newFunction(currentSpec, currentModule, currentScope(), NULL, sectionFlags, currentIsStatic, currentIsSignal, currentIsSlot, currentOverIsVirt, (yyvsp[(2) - (14)].text), &(yyvsp[(4) - (14)].signature), (yyvsp[(6) - (14)].number), (yyvsp[(8) - (14)].number), &(yyvsp[(9) - (14)].optflags), (yyvsp[(13) - (14)].codeb), (yyvsp[(14) - (14)].codeb), (yyvsp[(7) - (14)].throwlist), (yyvsp[(10) - (14)].optsignature), (yyvsp[(12) - (14)].codeb)); } currentIsStatic = FALSE; currentIsSignal = FALSE; currentIsSlot = FALSE; currentOverIsVirt = FALSE; } break; case 428: #line 3423 "/Users/phil/hg/sip/sip-4.15.5/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 429: #line 3443 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) { classDef *cd = currentScope(); /* * If the scope is a namespace then make sure the operator is * handled as a global. */ if (cd != NULL && cd->iff->type == namespace_iface) cd = NULL; applyTypeFlags(currentModule, &(yyvsp[(1) - (14)].memArg), &(yyvsp[(10) - (14)].optflags)); /* Handle the unary '+' and '-' operators. */ if ((cd != NULL && (yyvsp[(5) - (14)].signature).nrArgs == 0) || (cd == NULL && (yyvsp[(5) - (14)].signature).nrArgs == 1)) { if (strcmp((yyvsp[(3) - (14)].text), "__add__") == 0) (yyvsp[(3) - (14)].text) = "__pos__"; else if (strcmp((yyvsp[(3) - (14)].text), "__sub__") == 0) (yyvsp[(3) - (14)].text) = "__neg__"; } (yyvsp[(5) - (14)].signature).result = (yyvsp[(1) - (14)].memArg); newFunction(currentSpec, currentModule, cd, NULL, sectionFlags, currentIsStatic, currentIsSignal, currentIsSlot, currentOverIsVirt, (yyvsp[(3) - (14)].text), &(yyvsp[(5) - (14)].signature), (yyvsp[(7) - (14)].number), (yyvsp[(9) - (14)].number), &(yyvsp[(10) - (14)].optflags), (yyvsp[(13) - (14)].codeb), (yyvsp[(14) - (14)].codeb), (yyvsp[(8) - (14)].throwlist), (yyvsp[(11) - (14)].optsignature), NULL); } currentIsStatic = FALSE; currentIsSignal = FALSE; currentIsSlot = FALSE; currentOverIsVirt = FALSE; } break; case 430: #line 3479 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) { char *sname; classDef *scope = currentScope(); if (scope == NULL || (yyvsp[(4) - (13)].signature).nrArgs != 0) yyerror("Operator casts must be specified in a class and have no arguments"); applyTypeFlags(currentModule, &(yyvsp[(2) - (13)].memArg), &(yyvsp[(9) - (13)].optflags)); switch ((yyvsp[(2) - (13)].memArg).atype) { case defined_type: sname = NULL; break; case bool_type: case cbool_type: case 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) - (13)].signature).result = (yyvsp[(2) - (13)].memArg); newFunction(currentSpec, currentModule, scope, NULL, sectionFlags, currentIsStatic, currentIsSignal, currentIsSlot, currentOverIsVirt, sname, &(yyvsp[(4) - (13)].signature), (yyvsp[(6) - (13)].number), (yyvsp[(8) - (13)].number), &(yyvsp[(9) - (13)].optflags), (yyvsp[(12) - (13)].codeb), (yyvsp[(13) - (13)].codeb), (yyvsp[(7) - (13)].throwlist), (yyvsp[(10) - (13)].optsignature), NULL); } else { argList *al; /* Check it doesn't already exist. */ for (al = scope->casts; al != NULL; al = al->next) if (compareScopedNames((yyvsp[(2) - (13)].memArg).u.snd, al->arg.u.snd) == 0) yyerror("This operator cast has already been specified in this class"); al = sipMalloc(sizeof (argList)); al->arg = (yyvsp[(2) - (13)].memArg); al->next = scope->casts; scope->casts = al; } } currentIsStatic = FALSE; currentIsSignal = FALSE; currentIsSlot = FALSE; currentOverIsVirt = FALSE; } break; case 431: #line 3560 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__add__";} break; case 432: #line 3561 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__sub__";} break; case 433: #line 3562 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__mul__";} break; case 434: #line 3563 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__div__";} break; case 435: #line 3564 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__mod__";} break; case 436: #line 3565 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__and__";} break; case 437: #line 3566 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__or__";} break; case 438: #line 3567 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__xor__";} break; case 439: #line 3568 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__lshift__";} break; case 440: #line 3569 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__rshift__";} break; case 441: #line 3570 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__iadd__";} break; case 442: #line 3571 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__isub__";} break; case 443: #line 3572 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__imul__";} break; case 444: #line 3573 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__idiv__";} break; case 445: #line 3574 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__imod__";} break; case 446: #line 3575 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__iand__";} break; case 447: #line 3576 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__ior__";} break; case 448: #line 3577 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__ixor__";} break; case 449: #line 3578 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__ilshift__";} break; case 450: #line 3579 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__irshift__";} break; case 451: #line 3580 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__invert__";} break; case 452: #line 3581 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__call__";} break; case 453: #line 3582 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__getitem__";} break; case 454: #line 3583 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__lt__";} break; case 455: #line 3584 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__le__";} break; case 456: #line 3585 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__eq__";} break; case 457: #line 3586 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__ne__";} break; case 458: #line 3587 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__gt__";} break; case 459: #line 3588 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {(yyval.text) = "__ge__";} break; case 460: #line 3591 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.number) = FALSE; } break; case 461: #line 3594 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.number) = TRUE; } break; case 462: #line 3599 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.number) = 0; } break; case 463: #line 3602 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if ((yyvsp[(2) - (2)].number) != 0) yyerror("Abstract virtual function '= 0' expected"); (yyval.number) = TRUE; } break; case 464: #line 3610 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.optflags).nrFlags = 0; } break; case 465: #line 3613 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.optflags) = (yyvsp[(2) - (3)].optflags); } break; case 466: #line 3619 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.optflags).flags[0] = (yyvsp[(1) - (1)].flag); (yyval.optflags).nrFlags = 1; } break; case 467: #line 3623 "/Users/phil/hg/sip/sip-4.15.5/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 468: #line 3635 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.flag).ftype = bool_flag; (yyval.flag).fname = (yyvsp[(1) - (1)].text); } break; case 469: #line 3639 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.flag) = (yyvsp[(3) - (3)].flag); (yyval.flag).fname = (yyvsp[(1) - (3)].text); } break; case 470: #line 3645 "/Users/phil/hg/sip/sip-4.15.5/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 471: #line 3649 "/Users/phil/hg/sip/sip-4.15.5/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 472: #line 3672 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.flag).ftype = string_flag; (yyval.flag).fvalue.sval = convertFeaturedString((yyvsp[(1) - (1)].text)); } break; case 473: #line 3676 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.flag).ftype = integer_flag; (yyval.flag).fvalue.ival = (yyvsp[(1) - (1)].number); } break; case 474: #line 3682 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = NULL; } break; case 475: #line 3685 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 476: #line 3690 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = NULL; } break; case 477: #line 3693 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.codeb) = (yyvsp[(2) - (2)].codeb); } break; case 478: #line 3698 "/Users/phil/hg/sip/sip-4.15.5/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; } 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 479: #line 3746 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { /* No arguments. */ (yyval.signature).nrArgs = 0; } break; case 480: #line 3751 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { /* The single or first argument. */ (yyval.signature).args[0] = (yyvsp[(1) - (1)].memArg); (yyval.signature).nrArgs = 1; } break; case 481: #line 3757 "/Users/phil/hg/sip/sip-4.15.5/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"); /* Check there is nothing after an ellipsis. */ if ((yyvsp[(1) - (3)].signature).args[(yyvsp[(1) - (3)].signature).nrArgs - 1].atype == ellipsis_type) yyerror("An ellipsis must be at the end of the argument list"); /* * If this argument has no default value, then the * previous one mustn't either. */ if ((yyvsp[(3) - (3)].memArg).defval == NULL && (yyvsp[(1) - (3)].signature).args[(yyvsp[(1) - (3)].signature).nrArgs - 1].defval != NULL) yyerror("Compulsory argument given after optional argument"); /* Check there is room. */ if ((yyvsp[(1) - (3)].signature).nrArgs == MAX_NR_ARGS) yyerror("Internal error - increase the value of MAX_NR_ARGS"); (yyval.signature) = (yyvsp[(1) - (3)].signature); (yyval.signature).args[(yyval.signature).nrArgs] = (yyvsp[(3) - (3)].memArg); (yyval.signature).nrArgs++; } break; case 482: #line 3784 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { 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 483: #line 3795 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { 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 484: #line 3806 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { 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 485: #line 3817 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { const char *annos[] = { "SingleShot", NULL }; 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 486: #line 3835 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { 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 487: #line 3845 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { 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 488: #line 3861 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { 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 489: #line 3877 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { 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 490: #line 3885 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.memArg) = (yyvsp[(1) - (2)].memArg); (yyval.memArg).defval = (yyvsp[(2) - (2)].valp); } break; case 491: #line 3892 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {currentIsSignal = TRUE;} break; case 493: #line 3893 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {currentIsSlot = TRUE;} break; case 496: #line 3898 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {currentIsStatic = TRUE;} break; case 501: #line 3908 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" {currentOverIsVirt = TRUE;} break; case 504: #line 3912 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (notSkipping()) { const char *annos[] = { "DocType", "Encoding", "PyInt", "PyName", 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 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 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 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 505: #line 3964 "/Users/phil/hg/sip/sip-4.15.5/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 506: #line 3970 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.variable) = (yyvsp[(2) - (3)].variable); } break; case 508: #line 3976 "/Users/phil/hg/sip/sip-4.15.5/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 509: #line 3988 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.variable).token = TK_IF; } break; case 510: #line 3991 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.variable).token = TK_END; } break; case 511: #line 3994 "/Users/phil/hg/sip/sip-4.15.5/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 512: #line 4009 "/Users/phil/hg/sip/sip-4.15.5/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 513: #line 4024 "/Users/phil/hg/sip/sip-4.15.5/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 514: #line 4041 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { int i; (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 515: #line 4048 "/Users/phil/hg/sip/sip-4.15.5/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 516: #line 4062 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { const char *annos[] = { "AllowNone", "Array", "ArraySize", "Constrained", "DocType", "DocValue", "Encoding", "GetWrapper", "In", "KeepReference", "NoCopy", "Out", "PyInt", "ResultSize", "Transfer", "TransferBack", "TransferThis", 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 (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; } } applyTypeFlags(currentModule, &(yyval.memArg), &(yyvsp[(3) - (3)].optflags)); (yyval.memArg).docval = getDocValue(&(yyvsp[(3) - (3)].optflags)); } break; case 517: #line 4153 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.number) = 0; } break; case 518: #line 4156 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (currentSpec -> genc) yyerror("References not allowed in a C module"); (yyval.number) = ARG_IS_REF; } break; case 519: #line 4164 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.memArg).nrderefs = 0; } break; case 520: #line 4167 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { add_new_deref(&(yyval.memArg), &(yyvsp[(1) - (3)].memArg), TRUE); } break; case 521: #line 4170 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { add_new_deref(&(yyval.memArg), &(yyvsp[(1) - (2)].memArg), FALSE); } break; case 522: #line 4175 "/Users/phil/hg/sip/sip-4.15.5/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 523: #line 4183 "/Users/phil/hg/sip/sip-4.15.5/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 524: #line 4194 "/Users/phil/hg/sip/sip-4.15.5/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 525: #line 4209 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = ushort_type; } break; case 526: #line 4213 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = short_type; } break; case 527: #line 4217 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = uint_type; } break; case 528: #line 4221 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = uint_type; } break; case 529: #line 4225 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = int_type; } break; case 530: #line 4229 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = long_type; } break; case 531: #line 4233 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = ulong_type; } break; case 532: #line 4237 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = longlong_type; } break; case 533: #line 4241 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = ulonglong_type; } break; case 534: #line 4245 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = float_type; } break; case 535: #line 4249 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = double_type; } break; case 536: #line 4253 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = bool_type; } break; case 537: #line 4257 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = sstring_type; } break; case 538: #line 4261 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = ustring_type; } break; case 539: #line 4265 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = string_type; } break; case 540: #line 4269 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = wstring_type; } break; case 541: #line 4273 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = void_type; } break; case 542: #line 4277 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = pyobject_type; } break; case 543: #line 4281 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = pytuple_type; } break; case 544: #line 4285 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = pylist_type; } break; case 545: #line 4289 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = pydict_type; } break; case 546: #line 4293 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = pycallable_type; } break; case 547: #line 4297 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = pyslice_type; } break; case 548: #line 4301 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = pytype_type; } break; case 549: #line 4305 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = pybuffer_type; } break; case 550: #line 4309 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = ssize_type; } break; case 551: #line 4313 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { memset(&(yyval.memArg), 0, sizeof (argDef)); (yyval.memArg).atype = ellipsis_type; } break; case 552: #line 4319 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { /* The single or first type. */ (yyval.signature).args[0] = (yyvsp[(1) - (1)].memArg); (yyval.signature).nrArgs = 1; } break; case 553: #line 4325 "/Users/phil/hg/sip/sip-4.15.5/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 554: #line 4341 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { (yyval.throwlist) = NULL; } break; case 555: #line 4344 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { if (currentSpec->genc) yyerror("Exceptions not allowed in a C module"); (yyval.throwlist) = (yyvsp[(3) - (4)].throwlist); } break; case 556: #line 4352 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { /* Empty list so use a blank. */ (yyval.throwlist) = sipMalloc(sizeof (throwArgs)); (yyval.throwlist) -> nrArgs = 0; } break; case 557: #line 4358 "/Users/phil/hg/sip/sip-4.15.5/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 558: #line 4365 "/Users/phil/hg/sip/sip-4.15.5/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 7898 "/Users/phil/hg/sip/sip-4.15.5/sipgen/parser.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if ! YYERROR_VERBOSE yyerror (YY_("syntax error")); #else { YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) { YYSIZE_T yyalloc = 2 * yysize; if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) yyalloc = YYSTACK_ALLOC_MAXIMUM; if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = (char *) YYSTACK_ALLOC (yyalloc); if (yymsg) yymsg_alloc = yyalloc; else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; } } if (0 < yysize && yysize <= yymsg_alloc) { (void) yysyntax_error (yymsg, yystate, yychar); yyerror (yymsg); } else { yyerror (YY_("syntax error")); if (yysize != 0) goto yyexhaustedlab; } } #endif } if (yyerrstatus == 3) { /* If just tried and failed to reuse 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 4381 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" /* * Parse the specification. */ void parse(sipSpec *spec, FILE *fp, char *filename, stringList *tsl, stringList *xfl, KwArgs kwArgs, int protHack) { classTmplDef *tcd; /* Initialise the spec. */ memset(spec, 0, sizeof (sipSpec)); spec->genc = -1; currentSpec = spec; neededQualifiers = tsl; excludedQualifiers = xfl; currentModule = NULL; currentMappedType = NULL; currentOverIsVirt = FALSE; currentCtorIsExplicit = FALSE; currentIsStatic = FALSE; currentIsSignal = FALSE; currentIsSlot = FALSE; currentIsTemplate = FALSE; previousFile = NULL; skipStackPtr = 0; currentScopeIdx = 0; sectionFlags = 0; 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->version = -1; newmod->defdocstring = raw; newmod->encoding = no_type; newmod->qobjclass = -1; newmod->nrvirthandlers = -1; /* -1 is reserved for variable getters. */ newmod->next_key = -2; /* * 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 = skipStackPtr; pc.prevmod = prevmod; if (setInputFile(fp, &pc, optional)) currentContext = pc; } /* * Find an interface file, or create a new one. */ ifaceFileDef *findIfaceFile(sipSpec *pt, moduleDef *mod, scopedNameDef *fqname, ifaceFileType iftype, apiVersionRangeDef *api_range, argDef *ad) { ifaceFileDef *iff, *first_alt = NULL; /* See if the name is already used. */ for (iff = pt->ifacefiles; iff != NULL; iff = iff->next) { if (compareScopedNames(iff->fqcname, fqname) != 0) continue; /* * If they are both versioned then assume the user knows what they are * doing. */ if (iff->api_range != NULL && api_range != NULL && iff->module == mod) { /* Remember the first of the alternate APIs. */ if ((first_alt = iff->first_alt) == NULL) first_alt = iff; break; } /* * They must be the same type except that we allow a class if we want * an exception. This is because we allow classes to be used before * they are defined. */ if (iff->type != iftype) if (iftype != exception_iface || iff->type != class_iface) yyerror("A class, exception, namespace or mapped type has already been defined with the same name"); /* Ignore an external class declared in another module. */ if (iftype == class_iface && iff->module != mod) { classDef *cd; for (cd = pt->classes; cd != NULL; cd = cd->next) if (cd->iff == iff) break; if (cd != NULL && iff->module != NULL && isExternal(cd)) continue; } /* * If this is a mapped type with the same name defined in a different * module, then check that this type isn't the same as any of the * mapped types defined in that module. */ if (iftype == mappedtype_iface && iff->module != mod) { mappedTypeDef *mtd; /* * This is a bit of a cheat. With consolidated modules it's * possible to have two implementations of a mapped type in * different branches of the module hierarchy. We assume that, if * there really are multiple implementations in the same branch, * then it will be picked up in a non-consolidated build. */ if (isConsolidated(pt->module)) continue; for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next) { if (mtd->iff != iff) continue; if (ad->atype != template_type || mtd->type.atype != template_type || sameBaseType(ad, &mtd->type)) yyerror("Mapped type has already been defined in another module"); } /* * If we got here then we have a mapped type based on an existing * template, but with unique parameters. We don't want to use * interface files from other modules, so skip this one. */ continue; } /* Ignore a namespace defined in another module. */ if (iftype == namespace_iface && iff->module != mod) continue; return iff; } iff = sipMalloc(sizeof (ifaceFileDef)); iff->name = cacheName(pt, scopedNameToString(fqname)); iff->api_range = api_range; if (first_alt != NULL) { iff->first_alt = first_alt; iff->next_alt = first_alt->next_alt; first_alt->next_alt = iff; } else { /* This is the first alternate so point to itself. */ iff->first_alt = iff; } iff->type = iftype; iff->ifacenr = -1; iff->fqcname = fqname; iff->module = NULL; iff->hdrcode = NULL; iff->used = NULL; iff->next = pt->ifacefiles; pt->ifacefiles = iff; return iff; } /* * Find a class definition in a parse tree. */ static classDef *findClass(sipSpec *pt, ifaceFileType iftype, apiVersionRangeDef *api_range, scopedNameDef *fqname) { return findClassWithInterface(pt, findIfaceFile(pt, currentModule, fqname, iftype, api_range, NULL)); } /* * Find a class definition given an existing interface file. */ static classDef *findClassWithInterface(sipSpec *pt, ifaceFileDef *iff) { classDef *cd; for (cd = pt -> classes; cd != NULL; cd = cd -> next) if (cd -> iff == iff) return cd; /* Create a new one. */ cd = sipMalloc(sizeof (classDef)); cd->iff = iff; cd->pyname = cacheName(pt, classBaseName(cd)); cd->next = pt->classes; pt->classes = cd; return cd; } /* * Add an interface file to an interface file list if it isn't already there. */ void addToUsedList(ifaceFileList **ifflp, ifaceFileDef *iff) { /* Make sure we don't try to add an interface file to its own list. */ if (&iff->used != ifflp) { ifaceFileList *iffl; while ((iffl = *ifflp) != NULL) { /* Don't bother if it is already there. */ if (iffl->iff == iff) return; ifflp = &iffl -> next; } iffl = sipMalloc(sizeof (ifaceFileList)); iffl->iff = iff; iffl->next = NULL; *ifflp = iffl; } } /* * Find an undefined (or create a new) exception definition in a parse tree. */ static exceptionDef *findException(sipSpec *pt, scopedNameDef *fqname, int new) { exceptionDef *xd, **tail; ifaceFileDef *iff; classDef *cd; iff = findIfaceFile(pt, currentModule, fqname, exception_iface, NULL, NULL); /* See if it is an existing one. */ for (xd = pt->exceptions; xd != NULL; xd = xd->next) if (xd->iff == iff) return xd; /* * If it is an exception interface file then we have never seen this name * before. We require that exceptions are defined before being used, but * don't make the same requirement of classes (for reasons of backwards * compatibility). Therefore the name must be reinterpreted as a (as yet * undefined) class. */ if (new) { if (iff->type == exception_iface) cd = NULL; else yyerror("There is already a class with the same name or the exception has been used before being defined"); } else { if (iff->type == exception_iface) iff->type = class_iface; cd = findClassWithInterface(pt, iff); } /* Create a new one. */ xd = sipMalloc(sizeof (exceptionDef)); xd->exceptionnr = -1; xd->iff = iff; xd->pyname = NULL; xd->cd = cd; xd->bibase = NULL; xd->base = NULL; xd->raisecode = NULL; xd->next = NULL; /* Append it to the list. */ for (tail = &pt->exceptions; *tail != NULL; tail = &(*tail)->next) ; *tail = xd; return xd; } /* * Find an undefined (or create a new) class definition in a parse tree. */ static classDef *newClass(sipSpec *pt, ifaceFileType iftype, apiVersionRangeDef *api_range, scopedNameDef *fqname, const char *virt_error_handler) { 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) setHasShadow(scope); } /* Header code from outer scopes is also included. */ hdrcode = scope->iff->hdrcode; } else hdrcode = NULL; if (pt -> genc) { /* C structs are always global types. */ while (fqname -> next != NULL) fqname = fqname -> next; scope = NULL; } cd = findClass(pt, iftype, api_range, fqname); /* Check it hasn't already been defined. */ if (iftype != namespace_iface && cd->iff->module != NULL) yyerror("The struct/class has already been defined"); /* Complete the initialisation. */ cd->classflags |= flags; cd->ecd = scope; cd->iff->module = currentModule; cd->virt_error_handler = virt_error_handler; 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; 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); 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, "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; } 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; } } } if (inMainModule()) { setIsUsedName(cd->iff->name); setIsUsedName(cd->pyname); } } /* * Return the encoded name of a template (ie. including its argument types) as * a scoped name. */ scopedNameDef *encodedTemplateName(templateDef *td) { int a; scopedNameDef *snd; snd = copyScopedName(td->fqname); for (a = 0; a < td->types.nrArgs; ++a) { char buf[50]; int flgs; scopedNameDef *arg_snd; argDef *ad = &td->types.args[a]; flgs = 0; if (isConstArg(ad)) flgs += 1; if (isReference(ad)) flgs += 2; /* We use numbers so they don't conflict with names. */ sprintf(buf, "%02d%d%d", ad->atype, flgs, ad->nrderefs); switch (ad->atype) { case defined_type: arg_snd = copyScopedName(ad->u.snd); break; case template_type: arg_snd = encodedTemplateName(ad->u.td); break; case struct_type: arg_snd = copyScopedName(ad->u.sname); break; default: arg_snd = NULL; } /* * Replace the first element of the argument name with a copy with the * encoding prepended. */ if (arg_snd != NULL) arg_snd->name = concat(buf, arg_snd->name, NULL); else arg_snd = text2scopePart(sipStrdup(buf)); appendScopedName(&snd, arg_snd); } return snd; } /* * Create a new mapped type. */ static mappedTypeDef *newMappedType(sipSpec *pt, argDef *ad, optFlags *of) { mappedTypeDef *mtd; scopedNameDef *snd; ifaceFileDef *iff; const char *cname; /* Check that the type is one we want to map. */ switch (ad->atype) { case defined_type: snd = ad->u.snd; cname = scopedNameTail(snd); break; case template_type: snd = encodedTemplateName(ad->u.td); cname = NULL; break; case struct_type: snd = ad->u.sname; cname = scopedNameTail(snd); break; default: yyerror("Invalid type for %MappedType"); } iff = findIfaceFile(pt, currentModule, snd, mappedtype_iface, getAPIRange(of), ad); /* Check it hasn't already been defined. */ for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next) if (mtd->iff == iff) { /* * We allow types based on the same template but with different * arguments. */ if (ad->atype != template_type || sameBaseType(ad, &mtd->type)) yyerror("Mapped type has already been defined in this module"); } /* The module may not have been set yet. */ iff->module = currentModule; /* Create a new mapped type. */ mtd = allocMappedType(pt, ad); if (cname != NULL) mtd->pyname = cacheName(pt, getPythonName(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)); return mtd; } /* * Create a new enum. */ static enumDef *newEnum(sipSpec *pt, moduleDef *mod, mappedTypeDef *mt_scope, char *name, optFlags *of, int flags) { enumDef *ed, *first_alt, *next_alt; classDef *c_scope; ifaceFileDef *scope; if (mt_scope != NULL) { scope = mt_scope->iff; c_scope = NULL; } else { if ((c_scope = currentScope()) != NULL) scope = c_scope->iff; else scope = NULL; } ed = sipMalloc(sizeof (enumDef)); /* Assume the enum isn't versioned. */ first_alt = ed; next_alt = NULL; if (name != NULL) { ed->pyname = cacheName(pt, getPythonName(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) { setHasShadow(c_scope); } } ed->enumflags = flags; ed->enumnr = -1; ed->ecd = c_scope; ed->emtd = mt_scope; ed->first_alt = first_alt; ed->next_alt = next_alt; ed->module = mod; ed->members = NULL; ed->slots = NULL; ed->overs = NULL; ed->next = pt -> enums; pt->enums = ed; if (getOptFlag(of, "NoScope", bool_flag) != NULL) setIsNoScope(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; } /* * Convert a scoped name to a string on the heap. */ static char *scopedNameToString(scopedNameDef *name) { static const char scope_string[] = "::"; size_t len; scopedNameDef *snd; char *s, *dp; /* Work out the length of buffer needed. */ len = 0; for (snd = name; snd != NULL; snd = snd->next) { len += strlen(snd->name); if (snd->next != NULL) { /* Ignore the encoded part of template names. */ if (isdigit(snd->next->name[0])) break; len += strlen(scope_string); } } /* Allocate and populate the buffer. */ dp = s = sipMalloc(len + 1); for (snd = name; snd != NULL; snd = snd->next) { strcpy(dp, snd->name); dp += strlen(snd->name); if (snd->next != NULL) { /* Ignore the encoded part of template names. */ if (isdigit(snd->next->name[0])) break; strcpy(dp, scope_string); dp += strlen(scope_string); } } return s; } /* * Instantiate a class template. */ static void instantiateClassTemplate(sipSpec *pt, moduleDef *mod, classDef *scope, scopedNameDef *fqname, classTmplDef *tcd, templateDef *td, const char *pyname) { 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; resetIsTemplateClass(cd); cd->pyname = cacheName(pt, pyname); cd->td = td; /* Handle the interface file. */ cd->iff = findIfaceFile(pt, mod, fqname, class_iface, (scope != NULL ? scope->iff->api_range : NULL), NULL); cd->iff->module = mod; 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) addToUsedList(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 the super-classes. */ for (cl = cd->supers; cl != NULL; cl = cl->next) { const char *name; int a; /* Ignore defined or scoped classes. */ if (cl->cd->iff->module != NULL || cl->cd->iff->fqcname->next != NULL) continue; name = cl->cd->iff->fqcname->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]; classDef *icd; if (tad->atype == defined_type) icd = findClass(pt, class_iface, NULL, tad->u.snd); else if (tad->atype == class_type) icd = tad->u.cd; else fatal("Template argument %s must expand to a class\n", name); /* * Don't complain about the template argument being undefined. */ setTemplateArg(cl->cd); 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); /* Handle the ctors. */ cd->ctors = NULL; cttail = &cd->ctors; for (oct = tcd->cd->ctors; oct != NULL; oct = oct->next) { ctorDef *nct = sipMalloc(sizeof (ctorDef)); /* Start with a shallow copy. */ *nct = *oct; templateSignature(&nct->pysig, FALSE, tcd, td, cd); if (oct->cppsig == NULL) nct->cppsig = NULL; else if (oct->cppsig == &oct->pysig) nct->cppsig = &nct->pysig; else { nct->cppsig = sipMalloc(sizeof (signatureDef)); *nct->cppsig = *oct->cppsig; templateSignature(nct->cppsig, FALSE, tcd, td, cd); } nct->methodcode = templateCode(pt, used, nct->methodcode, type_names, type_values); nct->next = NULL; *cttail = nct; cttail = &nct->next; /* Handle the default ctor. */ if (tcd->cd->defctor == oct) cd->defctor = nct; } cd->dealloccode = templateCode(pt, used, cd->dealloccode, type_names, type_values); cd->dtorcode = templateCode(pt, used, cd->dtorcode, type_names, type_values); /* Handle the methods. */ cd->members = instantiateTemplateMethods(tcd->cd->members, mod); cd->overs = instantiateTemplateOverloads(pt, tcd->cd->overs, tcd->cd->members, cd->members, tcd, td, cd, used, type_names, type_values); cd->cppcode = templateCode(pt, used, cd->cppcode, type_names, type_values); cd->iff->hdrcode = templateCode(pt, used, cd->iff->hdrcode, type_names, type_values); cd->convtosubcode = templateCode(pt, used, cd->convtosubcode, type_names, type_values); cd->convtocode = templateCode(pt, used, cd->convtocode, type_names, type_values); cd->travcode = templateCode(pt, used, cd->travcode, type_names, type_values); cd->clearcode = templateCode(pt, used, cd->clearcode, type_names, type_values); cd->getbufcode = templateCode(pt, used, cd->getbufcode, type_names, type_values); cd->releasebufcode = templateCode(pt, used, cd->releasebufcode, type_names, type_values); cd->readbufcode = templateCode(pt, used, cd->readbufcode, type_names, type_values); cd->writebufcode = templateCode(pt, used, cd->writebufcode, type_names, type_values); cd->segcountcode = templateCode(pt, used, cd->segcountcode, type_names, type_values); cd->charbufcode = templateCode(pt, used, cd->charbufcode, type_names, type_values); cd->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->next = pt->classes; pt->classes = cd; tcd->sig.nrArgs--; freeScopedName(type_names); freeScopedName(type_values); } /* * Instantiate the methods of a template class. */ static memberDef *instantiateTemplateMethods(memberDef *tmd, moduleDef *mod) { memberDef *md, *methods, **mdtail; methods = NULL; mdtail = &methods; for (md = tmd; md != NULL; md = md->next) { memberDef *nmd = sipMalloc(sizeof (memberDef)); /* Start with a shallow copy. */ *nmd = *md; nmd->module = mod; if (inMainModule()) setIsUsedName(nmd->pyname); nmd->next = NULL; *mdtail = nmd; mdtail = &nmd->next; } return methods; } /* * Instantiate the overloads of a template class. */ static overDef *instantiateTemplateOverloads(sipSpec *pt, overDef *tod, memberDef *tmethods, memberDef *methods, classTmplDef *tcd, templateDef *td, classDef *cd, ifaceFileList **used, scopedNameDef *type_names, scopedNameDef *type_values) { overDef *od, *overloads, **odtail; overloads = NULL; odtail = &overloads; for (od = tod; od != NULL; od = od->next) { overDef *nod = sipMalloc(sizeof (overDef)); memberDef *nmd, *omd; /* Start with a shallow copy. */ *nod = *od; for (nmd = methods, omd = tmethods; omd != NULL; omd = omd->next, nmd = nmd->next) if (omd == od->common) { nod->common = nmd; break; } templateSignature(&nod->pysig, TRUE, tcd, td, cd); if (od->cppsig == &od->pysig) nod->cppsig = &nod->pysig; else { nod->cppsig = sipMalloc(sizeof (signatureDef)); *nod->cppsig = *od->cppsig; templateSignature(nod->cppsig, TRUE, tcd, td, cd); } nod->methodcode = templateCode(pt, used, nod->methodcode, type_names, type_values); /* Handle any virtual handler. */ if (od->virthandler != NULL) { moduleDef *mod = cd->iff->module; nod->virthandler = sipMalloc(sizeof (virtHandlerDef)); /* Start with a shallow copy. */ *nod->virthandler = *od->virthandler; nod->virthandler->pysig = &nod->pysig; nod->virthandler->cppsig = nod->cppsig; nod->virthandler->module = mod; nod->virthandler->virtcode = templateCode(pt, used, nod->virthandler->virtcode, type_names, type_values); nod->virthandler->next = mod->virthandlers; mod->virthandlers = nod->virthandler; } nod->next = NULL; *odtail = nod; odtail = &nod->next; } return overloads; } /* * Instantiate the enums of a template class. */ static void instantiateTemplateEnums(sipSpec *pt, classTmplDef *tcd, templateDef *td, classDef *cd, ifaceFileList **used, scopedNameDef *type_names, scopedNameDef *type_values) { enumDef *ted; moduleDef *mod = cd->iff->module; for (ted = pt->enums; ted != NULL; ted = ted->next) if (ted->ecd == tcd->cd) { enumDef *ed; enumMemberDef *temd; ed = sipMalloc(sizeof (enumDef)); /* Start with a shallow copy. */ *ed = *ted; if (ed->fqcname != NULL) { ed->fqcname = text2scopedName(cd->iff, scopedNameTail(ed->fqcname)); ed->cname = cacheName(pt, scopedNameToString(ed->fqcname)); } if (inMainModule()) { if (ed->pyname != NULL) setIsUsedName(ed->pyname); if (ed->cname != NULL) setIsUsedName(ed->cname); } ed->ecd = cd; ed->first_alt = ed; ed->module = mod; ed->members = NULL; for (temd = ted->members; temd != NULL; temd = temd->next) { enumMemberDef *emd; emd = sipMalloc(sizeof (enumMemberDef)); /* Start with a shallow copy. */ *emd = *temd; emd->ed = ed; emd->next = ed->members; ed->members = emd; } ed->slots = instantiateTemplateMethods(ted->slots, mod); ed->overs = instantiateTemplateOverloads(pt, ted->overs, ted->slots, ed->slots, tcd, td, cd, used, type_names, type_values); ed->next = pt->enums; pt->enums = ed; } } /* * Instantiate the variables of a template class. */ static void instantiateTemplateVars(sipSpec *pt, classTmplDef *tcd, templateDef *td, classDef *cd, ifaceFileList **used, scopedNameDef *type_names, scopedNameDef *type_values) { varDef *tvd; for (tvd = pt->vars; tvd != NULL; tvd = tvd->next) if (tvd->ecd == tcd->cd) { varDef *vd; vd = sipMalloc(sizeof (varDef)); /* Start with a shallow copy. */ *vd = *tvd; if (inMainModule()) setIsUsedName(vd->pyname); vd->fqcname = text2scopedName(cd->iff, scopedNameTail(vd->fqcname)); vd->ecd = cd; vd->module = cd->iff->module; templateType(&vd->type, tcd, td, cd); vd->accessfunc = templateCode(pt, used, vd->accessfunc, type_names, type_values); vd->getcode = templateCode(pt, used, vd->getcode, type_names, type_values); vd->setcode = templateCode(pt, used, vd->setcode, type_names, type_values); addVariable(pt, vd); } } /* * Instantiate the typedefs of a template class. */ static void instantiateTemplateTypedefs(sipSpec *pt, classTmplDef *tcd, templateDef *td, classDef *cd) { 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); addTypedef(pt, new_tdd); } } /* * Replace any template arguments in a signature. */ static void templateSignature(signatureDef *sd, int result, classTmplDef *tcd, templateDef *td, classDef *ncd) { int a; if (result) templateType(&sd->result, tcd, td, ncd); for (a = 0; a < sd->nrArgs; ++a) templateType(&sd->args[a], tcd, td, ncd); } /* * Replace any template arguments in a type. */ static void templateType(argDef *ad, classTmplDef *tcd, templateDef *td, classDef *ncd) { int a; char *name; /* Descend into any sub-templates. */ if (ad->atype == template_type) { templateDef *new_td = sipMalloc(sizeof (templateDef)); /* Make a deep copy of the template definition. */ *new_td = *ad->u.td; ad->u.td = new_td; templateSignature(&ad->u.td->types, FALSE, tcd, td, ncd); return; } /* Ignore if it isn't an unscoped name. */ if (ad->atype != defined_type || ad->u.snd->next != NULL) return; name = ad->u.snd->name; for (a = 0; a < tcd->sig.nrArgs - 1; ++a) if (strcmp(name, scopedNameTail(tcd->sig.args[a].u.snd)) == 0) { argDef *tad = &td->types.args[a]; ad->atype = tad->atype; /* We take the constrained flag from the real type. */ resetIsConstrained(ad); if (isConstrained(tad)) setIsConstrained(ad); ad->u = tad->u; return; } /* Handle the class name itself. */ if (strcmp(name, scopedNameTail(classFQCName(tcd->cd))) == 0) { ad->atype = class_type; ad->u.cd = ncd; ad->original_type = NULL; } } /* * Replace any template arguments in a literal code block. */ 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; /* * 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)) { addToUsedList(used, iff); return; } } for (ed = pt->enums; ed != NULL; ed = ed->next) { if (ed->ecd == NULL) continue; if (sameName(ed->fqcname, sname)) { addToUsedList(used, ed->ecd->iff); return; } } } /* * Compare a scoped name with its string equivalent. */ static int sameName(scopedNameDef *snd, const char *sname) { while (snd != NULL && *sname != '\0') { const char *sp = snd->name; while (*sp != '\0' && *sname != ':' && *sname != '\0') if (*sp++ != *sname++) return FALSE; if (*sp != '\0' || (*sname != ':' && *sname != '\0')) return FALSE; snd = snd->next; if (*sname == ':') sname += 2; } return (snd == NULL && *sname == '\0'); } /* * Compare a (possibly) relative scoped name with a fully qualified scoped name * while taking the current scope into account. */ static int foundInScope(scopedNameDef *fq_name, scopedNameDef *rel_name) { classDef *scope; for (scope = currentScope(); scope != NULL; scope = scope->ecd) { scopedNameDef *snd; int found; snd = copyScopedName(classFQCName(scope)); appendScopedName(&snd, copyScopedName(rel_name)); found = (compareScopedNames(fq_name, snd) == 0); freeScopedName(snd); if (found) return TRUE; } return compareScopedNames(fq_name, rel_name) == 0; } /* * Create a new typedef. */ static void newTypedef(sipSpec *pt, moduleDef *mod, char *name, argDef *type, optFlags *optflgs) { typedefDef *td; scopedNameDef *fqname; classDef *scope; scope = currentScope(); fqname = text2scopedName((scope != NULL ? scope->iff : NULL), name); /* See if we are instantiating a template class. */ if (type->atype == template_type) { classTmplDef *tcd; templateDef *td = type->u.td; for (tcd = pt->classtemplates; tcd != NULL; tcd = tcd->next) if (foundInScope(tcd->cd->iff->fqcname, td->fqname) && sameTemplateSignature(&tcd->sig, &td->types, FALSE)) { instantiateClassTemplate(pt, mod, scope, fqname, tcd, td, getPythonName(mod, optflgs, name)); /* All done. */ return; } } td = sipMalloc(sizeof (typedefDef)); td->tdflags = 0; td->fqname = fqname; td->ecd = scope; td->module = mod; 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 (getOptFlag(optflgs, "NoTypeName", bool_flag) != NULL) 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 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) { 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->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); 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, codeBlock *docstring) { ctorDef *ct, **ctp; classDef *cd = currentScope(); /* Check the name of the constructor. */ if (strcmp(classBaseName(cd), name) != 0) yyerror("Constructor doesn't have the same name as its class"); if (docstring != NULL) appendCodeBlock(&cd->docstring, docstring); /* Add to the list of constructors. */ ct = sipMalloc(sizeof (ctorDef)); if (sectFlags & SECT_IS_PROT && makeProtPublic) { sectFlags &= ~SECT_IS_PROT; sectFlags |= SECT_IS_PUBLIC; } /* Allow the signature to be used like an function signature. */ memset(&args->result, 0, sizeof (argDef)); args->result.atype = void_type; ct->ctorflags = sectFlags; ct->api_range = getAPIRange(optflgs); ct->pysig = *args; ct->cppsig = (cppsig != NULL ? cppsig : &ct->pysig); ct->exceptions = exceptions; appendCodeBlock(&ct->methodcode, methodcode); if (!isPrivateCtor(ct)) setCanCreate(cd); if (isProtectedCtor(ct)) setHasShadow(cd); if (explicit) setIsExplicitCtor(ct); getHooks(optflgs, &ct->prehook, &ct->posthook); if (getReleaseGIL(optflgs)) setIsReleaseGILCtor(ct); else if (getHoldGIL(optflgs)) setIsHoldGILCtor(ct); if (getTransfer(optflgs)) setIsResultTransferredCtor(ct); if (getDeprecated(optflgs)) setIsDeprecatedCtor(ct); if (!isPrivateCtor(ct)) 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, mappedTypeDef *mt_scope, int sflags, int isstatic, int issignal, int isslot, int isvirt, char *name, signatureDef *sig, int isconst, int isabstract, optFlags *optflgs, codeBlock *methodcode, codeBlock *vcode, throwArgs *exceptions, signatureDef *cppsig, codeBlock *docstring) { static const char *annos[] = { "__len__", "API", "AutoGen", "Deprecated", "DocType", "Encoding", "Factory", "HoldGIL", "KeywordArgs", "KeepReference", "NewThread", "NoArgParser", "NoCopy", "NoRaisesPyException", "NoVirtualErrorHandler", "Numeric", "PostHook", "PreHook", "PyInt", "PyName", "PyQtSignalHack", "RaisesPyException", "ReleaseGIL", "Sequence", "VirtualErrorHandler", "Transfer", "TransferBack", "TransferThis", NULL }; const char *pyname, *virt_error_handler; int factory, xferback, no_arg_parser, no_virt_error_handler; overDef *od, **odp, **headp; optFlag *of; virtHandlerDef *vhd; 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__", 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); } 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)) setHasShadow(c_scope); if ((isSlot(od) || isSignal(od)) && !isPrivate(od)) { if (isSignal(od)) setHasShadow(c_scope); pt->sigslots = TRUE; } if (isSignal(od) && (methodcode != NULL || vcode != NULL)) yyerror("Cannot provide code for signals"); if (isstatic) { if (isSignal(od)) yyerror("Static functions cannot be signals"); if (isvirt) yyerror("Static functions cannot be virtual"); setIsStatic(od); } if (isconst) setIsConst(od); if (isabstract) { if (sflags == 0) yyerror("Non-class function specified as abstract"); setIsAbstract(od); } if ((of = 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 (isSignal(od) && pluginPyQt3(pt)) yyerror("Virtual signals aren't supported"); setIsVirtual(od); setHasShadow(c_scope); vhd = sipMalloc(sizeof (virtHandlerDef)); vhd->virthandlernr = -1; vhd->vhflags = 0; vhd->pysig = &od->pysig; vhd->cppsig = (cppsig != NULL ? cppsig : &od->pysig); appendCodeBlock(&vhd->virtcode, vcode); if (factory || xferback) setIsTransferVH(vhd); 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; } /* * Only add it to the module's virtual handlers if we are not in a * class template. */ if (!currentIsTemplate) { vhd->module = mod; vhd->next = mod->virthandlers; mod->virthandlers = vhd; } } else { if (vcode != NULL) yyerror("%VirtualCatcherCode provided for non-virtual function"); if (virt_error_handler != NULL) yyerror("/VirtualErrorHandler/ provided for non-virtual function"); if (no_virt_error_handler) yyerror("/NoVirtualErrorHandler/ provided for non-virtual function"); vhd = NULL; } od->cppname = name; od->pysig = *sig; od->cppsig = (cppsig != NULL ? cppsig : &od->pysig); od->exceptions = exceptions; appendCodeBlock(&od->methodcode, methodcode); od->virthandler = vhd; 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"); } if (getOptFlag(optflgs, "NoCopy", bool_flag) != NULL) setNoCopy(&od->pysig.result); handleKeepReference(optflgs, &od->pysig.result, mod); pyname = getPythonName(mod, optflgs, name); od->common = findFunction(pt, mod, c_scope, mt_scope, pyname, (methodcode != NULL), sig->nrArgs, no_arg_parser); if (isProtected(od)) setHasProtected(od->common); if (strcmp(pyname, "__delattr__") == 0) setIsDelattr(od); if (docstring != NULL) appendCodeBlock(&od->common->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); } } } } /* See if we want to auto-generate a __len__() method. */ 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; len->common = findFunction(pt, mod, c_scope, mt_scope, len->cppname, TRUE, 0, FALSE); if ((len->methodcode = od->methodcode) == NULL) { char *buf = sipStrdup(" sipRes = (SIP_SSIZE_T)sipCpp->"); codeBlock *code; append(&buf, od->cppname); append(&buf, "();\n"); code = sipMalloc(sizeof (codeBlock)); code->frag = buf; code->filename = "Auto-generated"; code->linenr = 1; appendCodeBlock(&len->methodcode, code); } len->next = NULL; od->next = len; } else { od->next = NULL; } /* Append to the list. */ for (odp = headp; *odp != NULL; odp = &(*odp)->next) ; *odp = od; } /* * Return the Python name based on the C/C++ name and any /PyName/ annotation. */ static const char *getPythonName(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, 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}, {NULL} }; memberDef *md, **flist; struct slot_map *sm; slotType st; /* Get the slot type. */ st = no_slot; for (sm = slot_table; sm->name != NULL; ++sm) if (strcmp(sm->name, pname) == 0) { if (sm->needs_hwcode && !hwcode) yyerror("This Python slot requires %MethodCode"); if (sm->nrargs >= 0) { if (mt_scope == NULL && c_scope == NULL) { /* Global operators need one extra argument. */ if (sm -> nrargs + 1 != nrargs) yyerror("Incorrect number of arguments to global operator"); } else if (sm->nrargs != nrargs) yyerror("Incorrect number of arguments to Python slot"); } st = sm->type; break; } /* Check there is no name clash. */ checkAttributes(pt, mod, c_scope, mt_scope, pname, TRUE); /* See if it already exists. */ if (mt_scope != NULL) flist = &mt_scope->members; else if (c_scope != NULL) flist = &c_scope->members; else flist = &mod->othfuncs; /* __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->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; /* Check the enums. */ for (ed = pt->enums; ed != NULL; ed = ed->next) { enumMemberDef *emd; if (ed->pyname == NULL) continue; if (py_c_scope != NULL) { if (ed->ecd != py_c_scope) continue; } else if (py_mt_scope != NULL) { if (ed->emtd != py_mt_scope) continue; } else if (ed->ecd != NULL || ed->emtd != NULL) { continue; } if (strcmp(ed->pyname->text, attr) == 0) yyerror("There is already an enum in scope with the same Python name"); for (emd = ed->members; emd != NULL; emd = emd->next) if (strcmp(emd->pyname->text, attr) == 0) yyerror("There is already an enum member in scope with the same Python name"); } /* * Only check the members if this attribute isn't a member because we * can handle members with the same name in the same scope. */ if (!isfunc) { memberDef *md, *membs; overDef *overs; if (py_mt_scope != NULL) { membs = py_mt_scope->members; overs = py_mt_scope->overs; } else if (py_c_scope != NULL) { membs = py_c_scope->members; overs = py_c_scope->overs; } else { membs = mod->othfuncs; overs = mod->overs; } for (md = membs; md != NULL; md = md->next) { overDef *od; if (strcmp(md->pyname->text, attr) != 0) continue; /* Check for a conflict with all overloads. */ for (od = overs; od != NULL; od = od->next) { if (od->common != md) continue; yyerror("There is already a function in scope with the same Python name"); } } } /* If the scope was a mapped type then that's all we have to check. */ if (py_mt_scope != NULL) return; /* Check the variables. */ for (vd = pt->vars; vd != NULL; vd = vd->next) { if (vd->ecd != py_c_scope) continue; if (strcmp(vd->pyname->text,attr) == 0) yyerror("There is already a variable in scope with the same Python name"); } /* Check the classes. */ for (cd = pt->classes; cd != NULL; cd = cd->next) { if (cd->ecd != py_c_scope || cd->pyname == NULL) continue; if (strcmp(cd->pyname->text, attr) == 0 && !isExternal(cd)) yyerror("There is already a class or namespace in scope with the same Python name"); } /* Check the exceptions. */ if (py_c_scope == NULL) { exceptionDef *xd; for (xd = pt->exceptions; xd != NULL; xd = xd->next) if (xd->pyname != NULL && strcmp(xd->pyname, attr) == 0) yyerror("There is already an exception with the same Python name"); } /* 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 (skipStackPtr > currentContext.ifdepth) fatal("Too many %%If statements in %s\n", previousFile); if (skipStackPtr < currentContext.ifdepth) fatal("Too many %%End statements in %s\n", previousFile); } /* * Handle the end of a fully parsed a module. */ static void handleEOM() { moduleDef *from; /* Check it has been named. */ if (currentModule->name == NULL) fatal("No %%Module has been specified for module defined in %s\n", previousFile); from = currentContext.prevmod; if (from != NULL) { 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, 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) : NULL); appendScopedName(&snd, name); return snd; } /* * Return a pointer to the tail part of a scoped name. */ char *scopedNameTail(scopedNameDef *snd) { if (snd == NULL) return NULL; while (snd -> next != NULL) snd = snd -> next; return snd -> name; } /* * Push the given scope onto the scope stack. */ static void pushScope(classDef *scope) { if (currentScopeIdx >= MAX_NESTED_SCOPE) fatal("Internal error: increase the value of MAX_NESTED_SCOPE\n"); scopeStack[currentScopeIdx] = scope; sectFlagsStack[currentScopeIdx] = sectionFlags; ++currentScopeIdx; } /* * Pop the scope stack. */ static void popScope(void) { if (currentScopeIdx > 0) sectionFlags = sectFlagsStack[--currentScopeIdx]; } /* * Return non-zero if the current input should be parsed rather than be * skipped. */ static int notSkipping() { return (skipStackPtr == 0 ? TRUE : skipStack[skipStackPtr - 1]); } /* * Return the value of an expression involving a time period. */ static int timePeriod(const char *lname, const char *uname) { int this, line; qualDef *qd, *lower, *upper; moduleDef *mod; if (lname == NULL) lower = NULL; else if ((lower = findQualifier(lname)) == NULL || lower->qtype != time_qualifier) yyerror("Lower bound is not a time version"); if (uname == NULL) upper = NULL; else if ((upper = findQualifier(uname)) == NULL || upper->qtype != time_qualifier) yyerror("Upper bound is not a time version"); /* Sanity checks on the bounds. */ if (lower == NULL && upper == NULL) yyerror("Lower and upper bounds cannot both be omitted"); if (lower != NULL && upper != NULL) { if (lower->module != upper->module || lower->line != upper->line) yyerror("Lower and upper bounds are from different timelines"); if (lower == upper) yyerror("Lower and upper bounds must be different"); if (lower->order > upper->order) yyerror("Later version specified as lower bound"); } /* Go through each slot in the relevant timeline. */ if (lower != NULL) { mod = lower->module; line = lower->line; } else { mod = upper->module; line = upper->line; } /* Handle the SIP version number pseudo-timeline. */ if (line < 0) { if (lower != NULL && lower->order > SIP_VERSION) return FALSE; if (upper != NULL && upper->order <= SIP_VERSION) return FALSE; return TRUE; } this = FALSE; for (qd = mod->qualifiers; qd != NULL; qd = qd->next) { if (qd->qtype != time_qualifier || qd->line != line) continue; if (lower != NULL && qd->order < lower->order) continue; if (upper != NULL && qd->order >= upper->order) continue; /* * This is within the required range so if it is also needed then the * expression is true. */ if (selectedQualifier(neededQualifiers, qd)) { this = TRUE; break; } } return this; } /* * Return the value of an expression involving a single platform or feature. */ static int platOrFeature(char *name,int optnot) { int this; qualDef *qd; if ((qd = findQualifier(name)) == NULL || qd -> qtype == time_qualifier) yyerror("No such platform or feature"); /* Assume this sub-expression is false. */ this = FALSE; if (qd -> qtype == feature_qualifier) { if (!excludedFeature(excludedQualifiers,qd)) this = TRUE; } else if (selectedQualifier(neededQualifiers, qd)) this = TRUE; if (optnot) this = !this; return this; } /* * Return TRUE if the given qualifier is excluded. */ int excludedFeature(stringList *xsl,qualDef *qd) { while (xsl != NULL) { if (strcmp(qd -> name,xsl -> s) == 0) return TRUE; xsl = xsl -> next; } return FALSE; } /* * Return TRUE if the given qualifier is needed. */ 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 TRUE; return FALSE; } /* * Return the current scope. currentScope() is only valid if notSkipping() * returns non-zero. */ static classDef *currentScope(void) { return (currentScopeIdx > 0 ? scopeStack[currentScopeIdx - 1] : NULL); } /* * Create a new qualifier. */ static void newQualifier(moduleDef *mod, int line, int order, const char *name, qualType qt) { /* Check it doesn't already exist. */ if (findQualifier(name) != NULL) yyerror("Version is already defined"); allocQualifier(mod, line, order, name, qt); } /* * Allocate a new qualifier. */ static qualDef *allocQualifier(moduleDef *mod, int line, int order, 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->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 /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; return of->fvalue.sval; } /* * Get the /DocValue/ option flag. */ static const char *getDocValue(optFlags *optflgs) { optFlag *of = getOptFlag(optflgs, "DocValue", string_flag); if (of == NULL) return NULL; return of->fvalue.sval; } /* * Return TRUE if the PyQt3 plugin was specified. */ int pluginPyQt3(sipSpec *pt) { return stringFind(pt->plugins, "PyQt3"); } /* * Return TRUE if the PyQt4 plugin was specified. */ int pluginPyQt4(sipSpec *pt) { return stringFind(pt->plugins, "PyQt4"); } /* * Return TRUE if 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, *c_scope = currentScope(); cd = newClass(currentSpec, class_iface, getAPIRange(of), scopeScopedName((c_scope != NULL ? c_scope->iff : NULL), snd), getVirtErrorHandler(of)); cd->supers = supers; pushScope(cd); } /* * Complete the definition of a class. */ static classDef *completeClass(scopedNameDef *snd, optFlags *of, int has_def) { classDef *cd = currentScope(); /* See if the class was defined or just declared. */ if (has_def) { if (snd->next != NULL) yyerror("A scoped name cannot be given in a class/struct definition"); } else if (cd->supers != NULL) yyerror("Class/struct has super-classes but no definition"); else setIsOpaque(cd); finishClass(currentSpec, currentModule, cd, of); popScope(); /* * Check that external classes have only been declared at the global scope. */ if (isExternal(cd) && currentScope() != NULL) yyerror("External classes/structs can only be declared in the global scope"); return cd; } /* * Add a variable to the list so that the list remains sorted. */ static void addVariable(sipSpec *pt, varDef *vd) { varDef **at = &pt->vars; while (*at != NULL) { if (strcmp(vd->pyname->text, (*at)->pyname->text) < 0) break; at = &(*at)->next; } vd->next = *at; *at = vd; } /* * Update a type according to optional flags. */ static void applyTypeFlags(moduleDef *mod, argDef *ad, optFlags *flags) { ad->doctype = getDocType(flags); if (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 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, codeBlock *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; appendCodeBlock(&pd->docstring, docstring); 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 version, int c_module, KwArgs kwargs, int use_arg_names, int call_super_init, int all_raise_py_exc, const char *def_error_handler, codeBlock *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->version = version; appendCodeBlock(&module->docstring, docstring); if (all_raise_py_exc) setAllRaisePyException(module); if (use_arg_names) setUseArgNames(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) deprecated("Annotation is invalid"); } } } /* * 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); } /* * 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]; } } sip-4.15.5/sipgen/parser.h0000644000076500000240000002407412310606636015424 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_DEFDOCSTRING = 260, TK_DEFENCODING = 261, TK_PLUGIN = 262, TK_VIRTERRORHANDLER = 263, TK_DOCSTRING = 264, TK_DOC = 265, TK_EXPORTEDDOC = 266, TK_EXTRACT = 267, TK_MAKEFILE = 268, TK_ACCESSCODE = 269, TK_GETCODE = 270, TK_SETCODE = 271, TK_PREINITCODE = 272, TK_INITCODE = 273, TK_POSTINITCODE = 274, TK_FINALCODE = 275, TK_UNITCODE = 276, TK_UNITPOSTINCLUDECODE = 277, TK_MODCODE = 278, TK_TYPECODE = 279, TK_PREPYCODE = 280, TK_COPYING = 281, TK_MAPPEDTYPE = 282, TK_CODELINE = 283, TK_IF = 284, TK_END = 285, TK_NAME_VALUE = 286, TK_PATH_VALUE = 287, TK_STRING_VALUE = 288, TK_VIRTUALCATCHERCODE = 289, TK_TRAVERSECODE = 290, TK_CLEARCODE = 291, TK_GETBUFFERCODE = 292, TK_RELEASEBUFFERCODE = 293, TK_READBUFFERCODE = 294, TK_WRITEBUFFERCODE = 295, TK_SEGCOUNTCODE = 296, TK_CHARBUFFERCODE = 297, TK_PICKLECODE = 298, TK_METHODCODE = 299, TK_INSTANCECODE = 300, TK_FROMTYPE = 301, TK_TOTYPE = 302, TK_TOSUBCLASS = 303, TK_INCLUDE = 304, TK_OPTINCLUDE = 305, TK_IMPORT = 306, TK_EXPHEADERCODE = 307, TK_MODHEADERCODE = 308, TK_TYPEHEADERCODE = 309, TK_MODULE = 310, TK_CMODULE = 311, TK_CONSMODULE = 312, TK_COMPOMODULE = 313, TK_CLASS = 314, TK_STRUCT = 315, TK_PUBLIC = 316, TK_PROTECTED = 317, TK_PRIVATE = 318, TK_SIGNALS = 319, TK_SIGNAL_METHOD = 320, TK_SLOTS = 321, TK_SLOT_METHOD = 322, TK_BOOL = 323, TK_SHORT = 324, TK_INT = 325, TK_LONG = 326, TK_FLOAT = 327, TK_DOUBLE = 328, TK_CHAR = 329, TK_WCHAR_T = 330, TK_VOID = 331, TK_PYOBJECT = 332, TK_PYTUPLE = 333, TK_PYLIST = 334, TK_PYDICT = 335, TK_PYCALLABLE = 336, TK_PYSLICE = 337, TK_PYTYPE = 338, TK_PYBUFFER = 339, TK_VIRTUAL = 340, TK_ENUM = 341, TK_SIGNED = 342, TK_UNSIGNED = 343, TK_SCOPE = 344, TK_LOGICAL_OR = 345, TK_CONST = 346, TK_STATIC = 347, TK_SIPSIGNAL = 348, TK_SIPSLOT = 349, TK_SIPANYSLOT = 350, TK_SIPRXCON = 351, TK_SIPRXDIS = 352, TK_SIPSLOTCON = 353, TK_SIPSLOTDIS = 354, TK_SIPSSIZET = 355, TK_NUMBER_VALUE = 356, TK_REAL_VALUE = 357, TK_TYPEDEF = 358, TK_NAMESPACE = 359, TK_TIMELINE = 360, TK_PLATFORMS = 361, TK_FEATURE = 362, TK_LICENSE = 363, TK_QCHAR_VALUE = 364, TK_TRUE_VALUE = 365, TK_FALSE_VALUE = 366, TK_NULL_VALUE = 367, TK_OPERATOR = 368, TK_THROW = 369, TK_QOBJECT = 370, TK_EXCEPTION = 371, TK_RAISECODE = 372, TK_VIRTERRORCODE = 373, TK_EXPLICIT = 374, TK_TEMPLATE = 375, TK_ELLIPSIS = 376, TK_DEFMETATYPE = 377, TK_DEFSUPERTYPE = 378, TK_PROPERTY = 379, TK_FORMAT = 380, TK_GET = 381, TK_ID = 382, TK_KWARGS = 383, TK_LANGUAGE = 384, TK_LICENSEE = 385, TK_NAME = 386, TK_OPTIONAL = 387, TK_ORDER = 388, TK_REMOVELEADING = 389, TK_SET = 390, TK_SIGNATURE = 391, TK_TIMESTAMP = 392, TK_TYPE = 393, TK_USEARGNAMES = 394, TK_ALLRAISEPYEXC = 395, TK_CALLSUPERINIT = 396, TK_DEFERRORHANDLER = 397, TK_VERSION = 398 }; #endif /* Tokens. */ #define TK_API 258 #define TK_AUTOPYNAME 259 #define TK_DEFDOCSTRING 260 #define TK_DEFENCODING 261 #define TK_PLUGIN 262 #define TK_VIRTERRORHANDLER 263 #define TK_DOCSTRING 264 #define TK_DOC 265 #define TK_EXPORTEDDOC 266 #define TK_EXTRACT 267 #define TK_MAKEFILE 268 #define TK_ACCESSCODE 269 #define TK_GETCODE 270 #define TK_SETCODE 271 #define TK_PREINITCODE 272 #define TK_INITCODE 273 #define TK_POSTINITCODE 274 #define TK_FINALCODE 275 #define TK_UNITCODE 276 #define TK_UNITPOSTINCLUDECODE 277 #define TK_MODCODE 278 #define TK_TYPECODE 279 #define TK_PREPYCODE 280 #define TK_COPYING 281 #define TK_MAPPEDTYPE 282 #define TK_CODELINE 283 #define TK_IF 284 #define TK_END 285 #define TK_NAME_VALUE 286 #define TK_PATH_VALUE 287 #define TK_STRING_VALUE 288 #define TK_VIRTUALCATCHERCODE 289 #define TK_TRAVERSECODE 290 #define TK_CLEARCODE 291 #define TK_GETBUFFERCODE 292 #define TK_RELEASEBUFFERCODE 293 #define TK_READBUFFERCODE 294 #define TK_WRITEBUFFERCODE 295 #define TK_SEGCOUNTCODE 296 #define TK_CHARBUFFERCODE 297 #define TK_PICKLECODE 298 #define TK_METHODCODE 299 #define TK_INSTANCECODE 300 #define TK_FROMTYPE 301 #define TK_TOTYPE 302 #define TK_TOSUBCLASS 303 #define TK_INCLUDE 304 #define TK_OPTINCLUDE 305 #define TK_IMPORT 306 #define TK_EXPHEADERCODE 307 #define TK_MODHEADERCODE 308 #define TK_TYPEHEADERCODE 309 #define TK_MODULE 310 #define TK_CMODULE 311 #define TK_CONSMODULE 312 #define TK_COMPOMODULE 313 #define TK_CLASS 314 #define TK_STRUCT 315 #define TK_PUBLIC 316 #define TK_PROTECTED 317 #define TK_PRIVATE 318 #define TK_SIGNALS 319 #define TK_SIGNAL_METHOD 320 #define TK_SLOTS 321 #define TK_SLOT_METHOD 322 #define TK_BOOL 323 #define TK_SHORT 324 #define TK_INT 325 #define TK_LONG 326 #define TK_FLOAT 327 #define TK_DOUBLE 328 #define TK_CHAR 329 #define TK_WCHAR_T 330 #define TK_VOID 331 #define TK_PYOBJECT 332 #define TK_PYTUPLE 333 #define TK_PYLIST 334 #define TK_PYDICT 335 #define TK_PYCALLABLE 336 #define TK_PYSLICE 337 #define TK_PYTYPE 338 #define TK_PYBUFFER 339 #define TK_VIRTUAL 340 #define TK_ENUM 341 #define TK_SIGNED 342 #define TK_UNSIGNED 343 #define TK_SCOPE 344 #define TK_LOGICAL_OR 345 #define TK_CONST 346 #define TK_STATIC 347 #define TK_SIPSIGNAL 348 #define TK_SIPSLOT 349 #define TK_SIPANYSLOT 350 #define TK_SIPRXCON 351 #define TK_SIPRXDIS 352 #define TK_SIPSLOTCON 353 #define TK_SIPSLOTDIS 354 #define TK_SIPSSIZET 355 #define TK_NUMBER_VALUE 356 #define TK_REAL_VALUE 357 #define TK_TYPEDEF 358 #define TK_NAMESPACE 359 #define TK_TIMELINE 360 #define TK_PLATFORMS 361 #define TK_FEATURE 362 #define TK_LICENSE 363 #define TK_QCHAR_VALUE 364 #define TK_TRUE_VALUE 365 #define TK_FALSE_VALUE 366 #define TK_NULL_VALUE 367 #define TK_OPERATOR 368 #define TK_THROW 369 #define TK_QOBJECT 370 #define TK_EXCEPTION 371 #define TK_RAISECODE 372 #define TK_VIRTERRORCODE 373 #define TK_EXPLICIT 374 #define TK_TEMPLATE 375 #define TK_ELLIPSIS 376 #define TK_DEFMETATYPE 377 #define TK_DEFSUPERTYPE 378 #define TK_PROPERTY 379 #define TK_FORMAT 380 #define TK_GET 381 #define TK_ID 382 #define TK_KWARGS 383 #define TK_LANGUAGE 384 #define TK_LICENSEE 385 #define TK_NAME 386 #define TK_OPTIONAL 387 #define TK_ORDER 388 #define TK_REMOVELEADING 389 #define TK_SET 390 #define TK_SIGNATURE 391 #define TK_TIMESTAMP 392 #define TK_TYPE 393 #define TK_USEARGNAMES 394 #define TK_ALLRAISEPYEXC 395 #define TK_CALLSUPERINIT 396 #define TK_DEFERRORHANDLER 397 #define TK_VERSION 398 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE #line 179 "/Users/phil/hg/sip/sip-4.15.5/sipgen/metasrc/parser.y" { char qchar; char *text; long number; double real; argDef memArg; signatureDef signature; signatureDef *optsignature; throwArgs *throwlist; codeBlock *codeb; valueDef value; valueDef *valp; optFlags optflags; optFlag flag; scopedNameDef *scpvalp; fcallDef fcall; int boolean; exceptionDef exceptionbase; classDef *klass; apiCfg api; autoPyNameCfg autopyname; compModuleCfg compmodule; consModuleCfg consmodule; defDocstringCfg defdocstring; defEncodingCfg defencoding; defMetatypeCfg defmetatype; defSupertypeCfg defsupertype; 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 377 "/Users/phil/hg/sip/sip-4.15.5/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.15.5/sipgen/sip.h0000644000076500000240000016755212310606636014734 0ustar philstaff00000000000000/* * The main header file for SIP. * * Copyright (c) 2014 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 0x040f05 #define SIP_VERSION_STR "4.15.5" #ifdef TRUE #undef TRUE #endif #ifdef FALSE #undef FALSE #endif #define TRUE 1 #define FALSE 0 #define DEFAULT_OFILE_EXT ".o" /* Default object file extension. */ #define MAX_NR_ARGS 20 /* Max. nr. args. to a function or template. */ #define MAX_NR_DEREFS 5 /* Max. nr. type derefences. */ /* For convenience. */ #define classBaseName(cd) scopedNameTail((cd)->iff->fqcname) #define classFQCName(cd) ((cd)->iff->fqcname) /* Handle module flags. */ #define MOD_HAS_DELAYED_DTORS 0x0001 /* It has a class with a delayed dtor. */ #define MOD_IS_CONSOLIDATED 0x0002 /* It is a consolidated module. */ #define MOD_IS_COMPOSITE 0x0004 /* It is a composite module. */ #define MOD_IS_TRANSFORMED 0x0008 /* It's types have been transformed. */ #define MOD_USE_ARG_NAMES 0x0010 /* Use real argument names. */ #define MOD_ALL_RAISE_PY_EXC 0x0020 /* All callable raise a Python exception. */ #define MOD_SUPER_INIT_NO 0x0040 /* Don't call super().__init__(). */ #define MOD_SUPER_INIT_YES 0x0080 /* Call super().__init__(). */ #define MOD_SUPER_INIT_UNDEF 0x0000 /* Calling super().__init__() is undefined. */ #define MOD_SUPER_INIT_MASK 0x00c0 /* The mask for the above flags. */ #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 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) /* 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 isTemplateArg(cd) ((cd)->classflags2 & CLASS2_TMPL_ARG) #define setTemplateArg(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) /* 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 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) /* 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 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) /* Handle variable flags. */ #define VAR_IS_STATIC 0x01 /* It is a static variable. */ #define VAR_NEEDS_HANDLER 0x02 /* It the variable needs a handler. */ #define isStaticVar(v) ((v)->varflags & VAR_IS_STATIC) #define setIsStaticVar(v) ((v)->varflags |= VAR_IS_STATIC) #define needsHandler(v) ((v)->varflags & VAR_NEEDS_HANDLER) #define setNeedsHandler(v) ((v)->varflags |= VAR_NEEDS_HANDLER) /* Handle argument flags. */ #define ARG_IS_REF 0x0001 /* It is a reference. */ #define ARG_IS_CONST 0x0002 /* It is a const. */ #define ARG_XFERRED 0x0004 /* Ownership is transferred. */ #define ARG_THIS_XFERRED 0x0008 /* Ownership of this is transferred. */ #define ARG_XFERRED_BACK 0x0010 /* Ownership is transferred back. */ #define ARG_ARRAY 0x0020 /* Used as an array. */ #define ARG_ARRAY_SIZE 0x0040 /* Used as an array size. */ #define ARG_ALLOW_NONE 0x0080 /* Allow None as a value. */ #define ARG_GET_WRAPPER 0x0100 /* Get the wrapper object. */ #define ARG_IN 0x0200 /* It passes an argument. */ #define ARG_OUT 0x0400 /* It returns a result. */ #define ARG_CONSTRAINED 0x0800 /* Suppress type conversion. */ #define ARG_SINGLE_SHOT 0x1000 /* The slot is only ever fired once. */ #define ARG_RESULT_SIZE 0x2000 /* It defines the result size. */ #define ARG_KEEP_REF 0x4000 /* Keep a reference. */ #define ARG_NO_COPY 0x8000 /* Disable copying of const references. */ #define isReference(a) ((a)->argflags & ARG_IS_REF) #define setIsReference(a) ((a)->argflags |= ARG_IS_REF) #define resetIsReference(a) ((a)->argflags &= ~ARG_IS_REF) #define isConstArg(a) ((a)->argflags & ARG_IS_CONST) #define setIsConstArg(a) ((a)->argflags |= ARG_IS_CONST) #define resetIsConstArg(a) ((a)->argflags &= ~ARG_IS_CONST) #define isTransferred(a) ((a)->argflags & ARG_XFERRED) #define setIsTransferred(a) ((a)->argflags |= ARG_XFERRED) #define isThisTransferred(a) ((a)->argflags & ARG_THIS_XFERRED) #define setIsThisTransferred(a) ((a)->argflags |= ARG_THIS_XFERRED) #define isTransferredBack(a) ((a)->argflags & ARG_XFERRED_BACK) #define setIsTransferredBack(a) ((a)->argflags |= ARG_XFERRED_BACK) #define isArray(a) ((a)->argflags & ARG_ARRAY) #define setArray(a) ((a)->argflags |= ARG_ARRAY) #define isArraySize(a) ((a)->argflags & ARG_ARRAY_SIZE) #define setArraySize(a) ((a)->argflags |= ARG_ARRAY_SIZE) #define isAllowNone(a) ((a)->argflags & ARG_ALLOW_NONE) #define setAllowNone(a) ((a)->argflags |= ARG_ALLOW_NONE) #define isGetWrapper(a) ((a)->argflags & ARG_GET_WRAPPER) #define setGetWrapper(a) ((a)->argflags |= ARG_GET_WRAPPER) #define isInArg(a) ((a)->argflags & ARG_IN) #define setIsInArg(a) ((a)->argflags |= ARG_IN) #define isOutArg(a) ((a)->argflags & ARG_OUT) #define setIsOutArg(a) ((a)->argflags |= ARG_OUT) #define isConstrained(a) ((a)->argflags & ARG_CONSTRAINED) #define setIsConstrained(a) ((a)->argflags |= ARG_CONSTRAINED) #define resetIsConstrained(a) ((a)->argflags &= ~ARG_CONSTRAINED) #define isSingleShot(a) ((a)->argflags & ARG_SINGLE_SHOT) #define isResultSize(a) ((a)->argflags & ARG_RESULT_SIZE) #define setResultSize(a) ((a)->argflags |= ARG_RESULT_SIZE) #define keepReference(a) ((a)->argflags & ARG_KEEP_REF) #define setKeepReference(a) ((a)->argflags |= ARG_KEEP_REF) #define noCopy(a) ((a)->argflags & ARG_NO_COPY) #define setNoCopy(a) ((a)->argflags |= ARG_NO_COPY) /* Handle name flags. */ #define NAME_IS_USED 0x01 /* It is used in the main module. */ #define NAME_IS_SUBSTR 0x02 /* It is a substring of another. */ #define isUsedName(n) ((n)->nameflags & NAME_IS_USED) #define setIsUsedName(n) ((n)->nameflags |= NAME_IS_USED) #define resetIsUsedName(n) ((n)->nameflags &= ~NAME_IS_USED) #define isSubstring(n) ((n)->nameflags & NAME_IS_SUBSTR) #define setIsSubstring(n) ((n)->nameflags |= NAME_IS_SUBSTR) /* Handle virtual handler flags. */ #define VH_IS_DUPLICATE 0x01 /* It is a duplicate. */ #define VH_TRANSFERS 0x02 /* It transfers ownership of the result. */ #define isDuplicateVH(vh) ((vh)->vhflags & VH_IS_DUPLICATE) #define setIsDuplicateVH(vh) ((vh)->vhflags |= VH_IS_DUPLICATE) #define resetIsDuplicateVH(vh) ((vh)->vhflags &= ~VH_IS_DUPLICATE) #define isTransferVH(vh) ((vh)->vhflags & VH_TRANSFERS) #define setIsTransferVH(vh) ((vh)->vhflags |= VH_TRANSFERS) /* Handle mapped type flags. */ #define MT_NO_RELEASE 0x01 /* Do not generate a release function. */ #define MT_ALLOW_NONE 0x02 /* The mapped type will handle None. */ #define noRelease(mt) ((mt)->mtflags & MT_NO_RELEASE) #define setNoRelease(mt) ((mt)->mtflags |= MT_NO_RELEASE) #define handlesNone(mt) ((mt)->mtflags & MT_ALLOW_NONE) #define setHandlesNone(mt) ((mt)->mtflags |= MT_ALLOW_NONE) /* Handle typedef flags. */ #define TD_NO_TYPE_NAME 0x01 /* Do not use the typedef name. */ #define noTypeName(td) ((td)->tdflags & TD_NO_TYPE_NAME) #define setNoTypeName(td) ((td)->tdflags |= TD_NO_TYPE_NAME) /* Warning categories. */ typedef enum { ParserWarning, DeprecationWarning } Warning; /* Docstring formatting. */ typedef enum { raw, deindented } Format; /* 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. */ 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; /* 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. */ struct _qualDef *next; /* Next in the list. */ } qualDef; /* A scoped name. */ typedef struct _scopedNameDef { char *name; /* The name. */ struct _scopedNameDef *next; /* Next in the scope list. */ } scopedNameDef; /* A name. */ typedef struct _nameDef { int nameflags; /* The name flags. */ const char *text; /* The text of the name. */ size_t len; /* The length of the name. */ size_t offset; /* The offset in the string pool. */ struct _nameDef *next; /* Next in the list. */ } nameDef; /* A literal code block. */ typedef struct _codeBlock { char *frag; /* The code itself. */ const char *filename; /* The original file. */ int linenr; /* The line in the file. */ } 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. */ 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. */ 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. */ const char *docval; /* The documented value. */ int key; /* The optional /KeepReference/ key. */ struct _typedefDef *original_type; /* The original type if typedef'd. */ union { struct _signatureDef *sa; /* If it is a function. */ struct _templateDef *td; /* If it is a template. */ struct _scopedNameDef *snd; /* If it is a defined type. */ struct _classDef *cd; /* If it is a class. */ struct _enumDef *ed; /* If it is an enum. */ struct _scopedNameDef *sname; /* If it is a struct. */ struct _mappedTypeDef *mtd; /* If it is a mapped type. */ 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 module definition. */ typedef struct _moduleDef { nameDef *fullname; /* The full module name. */ const char *name; /* The module base name. */ int version; /* The module version. */ apiVersionRangeDef *api_versions; /* The defined APIs. */ apiVersionRangeDef *api_ranges; /* The list of API version ranges. */ int modflags; /* The module flags. */ KwArgs kwargs; /* The styleof keyword argument support. */ int qobjclass; /* QObject class, -1 if none. */ struct _memberDef *othfuncs; /* List of other functions. */ struct _overDef *overs; /* Global overloads. */ Format defdocstring; /* The default docstring format. */ 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 *docstring; /* The docstring. */ 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 *types; /* The array of numbered types. */ int nrtypes; /* The number of numbered types. */ int nrtimelines; /* The nr. of timelines. */ int nrexceptions; /* The nr. of exceptions. */ int nrtypedefs; /* The nr. of typedefs. */ int nrvirthandlers; /* The nr. of virtual handlers. */ int nrvirterrorhandlers; /* The nr. of virtual error handlers. */ int next_key; /* The next key to allocate. */ struct _virtHandlerDef *virthandlers; /* The virtual handlers. */ licenseDef *license; /* The software license. */ struct _classDef *proxies; /* The list of proxy classes. */ struct _moduleDef *container; /* The container module, if any. */ struct _ifaceFileList *used; /* Interface files used. */ struct _moduleListDef *allimports; /* The list of all imports. */ struct _moduleListDef *imports; /* The list of direct imports. */ struct _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. */ 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. */ struct _ifaceFileList *used; /* Interface files used. */ struct _ifaceFileDef *next; /* Next in the list. */ } ifaceFileDef; /* An entry in a linked interface file list. */ typedef struct _ifaceFileList { ifaceFileDef *iff; /* The interface file itself. */ struct _ifaceFileList *next; /* Next in the list. */ } ifaceFileList; /* A mapped type. */ typedef struct _mappedTypeDef { int mtflags; /* The mapped type flags. */ argDef type; /* The type being mapped. */ nameDef *pyname; /* The Python name. */ nameDef *cname; /* The C/C++ name. */ const char *doctype; /* The documented type. */ ifaceFileDef *iff; /* The interface file. */ struct _memberDef *members; /* The static member functions. */ struct _overDef *overs; /* The static overloads. */ codeBlockList *instancecode; /* Create instance code. */ codeBlockList *typecode; /* Type code. */ codeBlockList *convfromcode; /* Convert from C++ code. */ codeBlockList *convtocode; /* Convert to C++ code. */ struct _mappedTypeDef *next; /* Next in the list. */ } mappedTypeDef; /* A function signature. */ typedef struct _signatureDef { argDef result; /* The result. */ int nrArgs; /* The number of arguments. */ argDef args[MAX_NR_ARGS]; /* The arguments. */ } signatureDef; /* A list of function signatures. */ typedef struct _signatureList { struct _signatureDef *sd; /* The signature. */ struct _signatureList *next; /* Next in the list. */ } signatureList; /* A template type. */ typedef struct _templateDef { scopedNameDef *fqname; /* The name. */ signatureDef types; /* The types. */ } templateDef; /* A list of virtual handlers. */ typedef struct _virtHandlerDef { int virthandlernr; /* The nr. of the virtual handler. */ int vhflags; /* The virtual handler flags. */ signatureDef *pysig; /* The Python signature. */ signatureDef *cppsig; /* The C++ signature. */ struct _moduleDef *module; /* The defining module. */ codeBlockList *virtcode; /* Virtual handler code. */ struct _virtHandlerDef *next; /* Next in the list. */ } virtHandlerDef; /* A typedef definition. */ typedef struct _typedefDef { int tdflags; /* The typedef flags. */ scopedNameDef *fqname; /* The fully qualified name. */ struct _classDef *ecd; /* The enclosing class. */ moduleDef *module; /* The owning module. */ argDef type; /* The actual type. */ struct _typedefDef *next; /* Next in the list. */ } typedefDef; /* A variable definition. */ typedef struct _varDef { nameDef *pyname; /* The variable Python name. */ scopedNameDef *fqcname; /* The fully qualified C/C++ name. */ struct _classDef *ecd; /* The enclosing class. */ moduleDef *module; /* The owning module. */ int varflags; /* The variable flags. */ argDef type; /* The actual type. */ codeBlockList *accessfunc; /* The access function. */ codeBlockList *getcode; /* The get code. */ codeBlockList *setcode; /* The set code. */ struct _varDef *next; /* Next in the list. */ } varDef; /* A property definition. */ typedef struct _propertyDef { nameDef *name; /* The property name. */ const char *get; /* The name of the getter method. */ const char *set; /* The name of the setter method. */ codeBlockList *docstring; /* The docstring. */ 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. */ int overflags; /* The overload flags. */ 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. */ virtHandlerDef *virthandler; /* The virtual handler. */ char *prehook; /* The pre-hook name. */ char *posthook; /* The post-hook name. */ const char *virt_error_handler; /* The virtual error handler. */ struct _overDef *next; /* Next in the list. */ } overDef; /* An overloaded constructor definition. */ typedef struct _ctorDef { int ctorflags; /* The ctor flags. */ 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. */ char *prehook; /* The pre-hook name. */ char *posthook; /* The post-hook name. */ struct _ctorDef *next; /* Next in the list. */ } ctorDef; /* An enumerated type member definition. */ typedef struct _enumMemberDef { nameDef *pyname; /* The Python name. */ char *cname; /* The C/C++ name. */ struct _enumDef *ed; /* The enclosing enum. */ struct _enumMemberDef *next; /* Next in the list. */ } enumMemberDef; /* An enumerated type definition. */ typedef struct _enumDef { int enumflags; /* The enum flags. */ nameDef *pyname; /* The Python name (may be NULL). */ scopedNameDef *fqcname; /* The C/C++ name (may be NULL). */ nameDef *cname; /* The C/C++ name (may be NULL). */ struct _enumDef *first_alt; /* The first alternate API. */ struct _enumDef *next_alt; /* The next alternate API. */ int enumnr; /* The enum number. */ int enum_idx; /* The enum index within the module. */ struct _classDef *ecd; /* The enclosing class, if any. */ struct _mappedTypeDef *emtd; /* The enclosing mapped type, if any. */ moduleDef *module; /* The owning module. */ enumMemberDef *members; /* The list of members. */ struct _memberDef *slots; /* The list of slots. */ struct _overDef *overs; /* The list of slot overloads. */ struct _enumDef *next; /* Next in the list. */ } enumDef; /* An member function definition. */ typedef struct _memberDef { nameDef *pyname; /* The Python name. */ int memberflags; /* The member flags. */ int membernr; /* The index in the method table. */ slotType slot; /* The slot type. */ moduleDef *module; /* The owning module. */ codeBlockList *docstring; /* The overloads docstrings. */ struct _memberDef *next; /* Next in the list. */ } memberDef; /* A list of visible member functions. */ typedef struct _visibleList { memberDef *m; /* The member definition. */ struct _classDef *cd; /* The class. */ struct _visibleList *next; /* Next in the list. */ } visibleList; /* An entry in a linked class list. */ typedef struct _classList { struct _classDef *cd; /* The class itself. */ struct _classList *next; /* Next in the list. */ } classList; /* A virtual overload definition. */ typedef struct _virtOverDef { overDef o; /* The overload. */ struct _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 { 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. */ 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 *docstring; /* Class and ctor docstrings. */ 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. */ propertyDef *properties; /* The properties. */ const char *virt_error_handler; /* The virtual error handler. */ 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. */ virtErrorHandler *errorhandlers; /* The list of virtual error handlers. */ codeBlockList *exphdrcode; /* Exported header code. */ codeBlockList *docs; /* Documentation. */ int sigslots; /* Set if signals or slots are used. */ int genc; /* Set if we are generating C code. */ struct _stringList *plugins; /* The list of plugins. */ 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 *, stringList *, stringList *, KwArgs, int); void parserEOF(const char *,parserContext *); void transform(sipSpec *); 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 generateExpression(valueDef *vd, int in_str, FILE *fp); void warning(Warning w, const char *fmt, ...); void deprecated(const char *msg); void fatal(char *,...); void fatalScopedName(scopedNameDef *); 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 addToUsedList(ifaceFileList **, ifaceFileDef *); 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 prOverloadName(FILE *fp, overDef *od); void prOverloadDecl(FILE *fp, ifaceFileDef *scope, overDef *od, int defval); void prScopedPythonName(FILE *fp, classDef *scope, const char *pyname); int prPythonSignature(sipSpec *pt, FILE *fp, signatureDef *sd, int sec, int names, int defaults, int in_str, int is_signal); void searchTypedefs(sipSpec *pt, scopedNameDef *snd, argDef *ad); int 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 pluginPyQt3(sipSpec *pt); int pluginPyQt4(sipSpec *pt); int pluginPyQt5(sipSpec *pt); void yywarning(char *); 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); /* 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; codeBlock *docstring; } compModuleCfg; /* %ConsolidatedModule */ typedef struct _consModuleCfg { int token; const char *name; codeBlock *docstring; } consModuleCfg; /* %DefaultDocstringFormat */ typedef struct _defDocstringCfg { int token; const char *name; } defDocstringCfg; /* %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; } 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; /* %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 all_raise_py_exc; int call_super_init; const char *def_error_handler; int version; codeBlock *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; codeBlock *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.15.5/sipgen/sipgen.sbf0000644000076500000240000000141112261240717015725 0ustar philstaff00000000000000# This is the build file for the code generator. # # Copyright (c) 2014 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 heap.c parser.c lexer.c headers = sip.h parser.h sip-4.15.5/sipgen/transform.c0000644000076500000240000030134512261240724016132 0ustar philstaff00000000000000/* * The parse tree transformation module for SIP. * * Copyright (c) 2014 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 sameOverload(overDef *od1, overDef *od2); static int sameVirtualHandler(virtHandlerDef *vhd1,virtHandlerDef *vhd2); static int isSubClass(classDef *cc,classDef *pc); static void setAllImports(moduleDef *mod); static void addUniqueModule(moduleDef *mod, moduleDef *imp); static void ensureInput(classDef *,overDef *,argDef *); static void defaultInput(argDef *); static void defaultOutput(argDef *ad); static void createSortedNumberedTypesTable(sipSpec *pt, moduleDef *mod); static int compareTypes(const void *t1, const void *t2); static void addAutoOverload(sipSpec *,classDef *,overDef *); static void ifaceFileIsUsed(ifaceFileList **used, argDef *ad); static void ifaceFilesAreUsedByOverload(ifaceFileList **used, overDef *od); static void ifaceFilesAreUsedBySignature(ifaceFileList **used, signatureDef *sd); static void scopeDefaultValue(sipSpec *,classDef *,argDef *); static void setHierarchy(sipSpec *,classDef *,classDef *,classList **); static void transformModules(sipSpec *pt, moduleDef *mod); static void transformCtors(sipSpec *,classDef *); static void transformCasts(sipSpec *,classDef *); static void addDefaultCopyCtor(classDef *); static void transformScopeOverloads(sipSpec *pt, classDef *c_scope, mappedTypeDef *mt_scope, overDef *overs); static void transformVariableList(sipSpec *pt, moduleDef *mod); static void transformMappedTypes(sipSpec *pt, moduleDef *mod); static void getVisibleMembers(sipSpec *,classDef *); static void getVirtuals(sipSpec *pt,classDef *cd); static void getClassVirtuals(classDef *,classDef *); static void transformTypedefs(sipSpec *pt, moduleDef *mod); static void resolveMappedTypeTypes(sipSpec *,mappedTypeDef *); static void resolveCtorTypes(sipSpec *,classDef *,ctorDef *); static void resolveFuncTypes(sipSpec *pt, moduleDef *mod, classDef *c_scope, mappedTypeDef *mt_scope, overDef *od); static void resolvePySigTypes(sipSpec *,moduleDef *,classDef *,overDef *,signatureDef *,int); static void resolveVariableType(sipSpec *,varDef *); static void fatalNoDefinedType(scopedNameDef *); static void resolveType(sipSpec *,moduleDef *,classDef *,argDef *,int); static void searchClassScope(sipSpec *,classDef *,scopedNameDef *,argDef *); static void searchMappedTypes(sipSpec *,moduleDef *,scopedNameDef *,argDef *); static void searchEnums(sipSpec *,scopedNameDef *,argDef *); static void searchClasses(sipSpec *,moduleDef *mod,scopedNameDef *,argDef *); static void appendToMRO(mroDef *,mroDef ***,classDef *); static void moveMainModuleCastsSlots(sipSpec *pt, moduleDef *mod); static void moveClassCasts(sipSpec *pt, moduleDef *mod, classDef *cd); static void moveGlobalSlot(sipSpec *pt, moduleDef *mod, memberDef *gmd); static classDef *findAltClassImplementation(sipSpec *pt, mappedTypeDef *mtd); static void filterMainModuleVirtualHandlers(moduleDef *mod); static void filterModuleVirtualHandlers(moduleDef *mod); static ifaceFileDef *getIfaceFile(argDef *ad); static mappedTypeDef *instantiateMappedTypeTemplate(sipSpec *pt, moduleDef *mod, mappedTypeTmplDef *mtt, argDef *type); static classDef *getProxy(moduleDef *mod, classDef *cd); static int generatingCodeForModule(sipSpec *pt, moduleDef *mod); static void checkAssignmentHelper(sipSpec *pt, classDef *cd); static void addComplementarySlots(sipSpec *pt, classDef *cd); static void addComplementarySlot(sipSpec *pt, classDef *cd, memberDef *md, slotType cslot, const char *cslot_name); static void resolveInstantiatedClassTemplate(sipSpec *pt, argDef *type); static void setStringPoolOffsets(sipSpec *pt); static const char *templateString(const char *src, scopedNameDef *names, scopedNameDef *values); static mappedTypeDef *copyTemplateType(mappedTypeDef *mtd, argDef *ad); static void checkProperties(classDef *cd); /* * Transform the parse tree. */ void transform(sipSpec *pt) { moduleDef *mod; classDef *cd, *rev, **tail; classList *newl; overDef *od; /* * The class list has the main module's classes at the front and the ones * from the module at the most nested %Import at the end. This affects * some of the following algorithms. We have to have consistency whenever * a module is used. To achieve this we reverse the order of the classes. */ rev = NULL; cd = pt -> classes; while (cd != NULL) { classDef *next; /* * 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, mod); } else { transformModules(pt, pt->modules); } /* Handle default ctors now that the argument types are resolved. */ if (!pt->genc) for (cd = pt->classes; cd != NULL; cd = cd->next) if (!noDefaultCtors(cd) && !isOpaque(cd) && cd->iff->type != namespace_iface) addDefaultCopyCtor(cd); /* Create the array of numbered types sorted by type name. */ for (mod = pt->modules; mod != NULL; mod = mod->next) createSortedNumberedTypesTable(pt, mod); /* Add any automatically generated methods. */ for (cd = pt -> classes; cd != NULL; cd = cd -> next) for (od = cd -> overs; od != NULL; od = od -> next) if (isAutoGen(od)) addAutoOverload(pt,cd,od); /* * Move casts and slots around to their correct classes (if in the same * module) or create proxies for them (if cross-module). */ if (!pt->genc) for (mod = pt->modules; mod != NULL; mod = mod->next) if (generatingCodeForModule(pt, mod)) moveMainModuleCastsSlots(pt, mod); /* Automatically generate missing complementary slots. */ if (!pt->genc) { for (cd = pt->classes; cd != NULL; cd = cd->next) addComplementarySlots(pt, cd); for (mod = pt->modules; mod != NULL; mod = mod->next) if (generatingCodeForModule(pt, mod)) for (cd = mod->proxies; cd != NULL; cd = cd->next) addComplementarySlots(pt, cd); } /* Generate the different class views. */ for (cd = pt->classes; cd != NULL; cd = cd->next) if (cd->iff->type == class_iface) { /* Get the list of visible member functions. */ getVisibleMembers(pt, cd); /* Get the virtual members. */ if (hasShadow(cd)) getVirtuals(pt, cd); } else if (cd->iff->type == namespace_iface) for (od = cd->overs; od != NULL; od = od->next) ifaceFilesAreUsedByOverload(&cd->iff->used, od); /* * Filter the virtuals of all component modules (if consolidated) or the * main module (if not). */ for (mod = pt->modules; mod != NULL; mod = mod->next) { if (generatingCodeForModule(pt, mod)) { filterMainModuleVirtualHandlers(mod); for (od = mod->overs; od != NULL; od = od->next) ifaceFilesAreUsedByOverload(&mod->used, od); } /* Update proxies with some information from the real classes. */ for (cd = mod->proxies; cd != NULL; cd = cd->next) cd->iff->ifacenr = cd->real->iff->ifacenr; } /* Additional class specific checks. */ for (cd = pt->classes; cd != NULL; cd = cd->next) { checkAssignmentHelper(pt, cd); checkProperties(cd); } setStringPoolOffsets(pt); } /* * Transform a module and the modules it imports. */ static void transformModules(sipSpec *pt, moduleDef *mod) { classDef *cd; moduleListDef *mld; /* Handle the trivial case. */ if (isTransformed(mod)) return; /* * The modules on which this one depends must be done first because they * might generate new template-based types and they must be defined in the * right module. */ for (mld = mod->imports; mld != NULL; mld = mld->next) transformModules(pt, mld->module); /* Transform typedefs, variables and global functions. */ transformTypedefs(pt, mod); transformVariableList(pt, mod); transformScopeOverloads(pt, NULL, NULL, mod->overs); /* Transform class ctors, functions and casts. */ for (cd = pt->classes; cd != NULL; cd = cd->next) { if (cd->iff->module == mod) { transformCtors(pt, cd); if (!pt->genc) { transformScopeOverloads(pt, cd, NULL, cd->overs); transformCasts(pt, cd); } } } /* Transform mapped types based on templates. */ transformMappedTypes(pt, mod); setIsTransformed(mod); } /* * Set the offset into the string pool for every used name. */ static void setStringPoolOffsets(sipSpec *pt) { nameDef *nd; size_t offset = 0; for (nd = pt->namecache; nd != NULL; nd = nd->next) { size_t len; nameDef *prev; if (!isUsedName(nd)) continue; /* See if the tail of a previous used name could be used instead. */ len = nd->len; for (prev = pt->namecache; prev->len > len; prev = prev->next) { size_t pos; if (!isUsedName(prev) || isSubstring(prev)) continue; pos = prev->len - len; if (memcmp(&prev->text[pos], nd->text, len) == 0) { setIsSubstring(nd); nd->offset = prev->offset + pos; break; } } if (!isSubstring(nd)) { nd->offset = offset; offset += len + 1; } } } /* * Add any missing complementary slots to a class. This emulates the C++ * behaviour of automatically interpreting (for example) >= as !<. */ static void addComplementarySlots(sipSpec *pt, classDef *cd) { memberDef *md; for (md = cd->members; md != NULL; md = md->next) switch (md->slot) { case lt_slot: addComplementarySlot(pt, cd, md, ge_slot, "__ge__"); break; case le_slot: addComplementarySlot(pt, cd, md, gt_slot, "__gt__"); break; case gt_slot: addComplementarySlot(pt, cd, md, le_slot, "__le__"); break; case ge_slot: addComplementarySlot(pt, cd, md, lt_slot, "__lt__"); break; case eq_slot: addComplementarySlot(pt, cd, md, ne_slot, "__ne__"); break; case ne_slot: addComplementarySlot(pt, cd, md, eq_slot, "__eq__"); break; } } /* * Add a complementary slot if it is missing. */ static void addComplementarySlot(sipSpec *pt, classDef *cd, memberDef *md, slotType cslot, const char *cslot_name) { overDef *od1; memberDef *md2 = NULL; for (od1 = cd->overs; od1 != NULL; od1 = od1->next) { overDef *od2; if (od1->common != md || isComplementary(od1) || od1->methodcode != NULL) continue; /* Try and find an existing complementary slot. */ for (od2 = cd->overs; od2 != NULL; od2 = od2->next) if (od2->common->slot == cslot && sameSignature(&od1->pysig, &od2->pysig, TRUE)) break; /* * If there is an explicit complementary slot then there is nothing to * do. */ if (od2 != NULL) continue; /* Create a new member if needed. */ if (md2 == NULL) { for (md2 = cd->members; md2 != NULL; md2 = md2->next) if (md2->slot == cslot) break; if (md2 == NULL) { md2 = sipMalloc(sizeof (memberDef)); md2->pyname = cacheName(pt, cslot_name); md2->memberflags = md->memberflags; md2->slot = cslot; md2->module = md->module; md2->next = cd->members; cd->members = md2; if (isUsedName(md->pyname)) setIsUsedName(md2->pyname); } } /* Create the complementary slot. */ od2 = sipMalloc(sizeof (overDef)); *od2 = *od1; resetIsVirtual(od2); setIsComplementary(od2); od2->common = md2; od2->next = cd->overs; cd->overs = od2; } } /* * See if a class supports an assignment helper. */ static void checkAssignmentHelper(sipSpec *pt, classDef *cd) { int pub_def_ctor, pub_copy_ctor; ctorDef *ct; /* * We register types with Qt if the class is not abstract, doesn't have a * private assignment operator, has a public default ctor, a public copy * ctor and a public dtor. */ if (isAbstractClass(cd)) return; if (cannotAssign(cd)) return; if (!isPublicDtor(cd)) return; pub_def_ctor = pub_copy_ctor = FALSE; for (ct = cd->ctors; ct != NULL; ct = ct->next) { if (ct->cppsig == NULL || !isPublicCtor(ct)) continue; if (ct->cppsig->nrArgs == 0 || ct->cppsig->args[0].defval != NULL) { /* * The ctor either has no arguments or all arguments have defaults. */ pub_def_ctor = TRUE; } else if (ct->cppsig->nrArgs == 1) { argDef *ad = &ct->cppsig->args[0]; classDef *arg_cd; if (ad->atype == class_type) arg_cd = ad->u.cd; else if (ad->atype == mapped_type) arg_cd = findAltClassImplementation(pt, ad->u.mtd); else arg_cd = NULL; if (arg_cd == cd && isReference(ad) && isConstArg(ad) && ad->nrderefs == 0 && ad->defval == NULL) pub_copy_ctor = TRUE; } } if (pub_def_ctor && pub_copy_ctor) { setAssignmentHelper(cd); addToUsedList(&cd->iff->module->used, cd->iff); } } /* * Set the list of all imports for a module. The list is ordered so that a * module appears before any module that imports it. */ static void setAllImports(moduleDef *mod) { moduleListDef *mld; /* * Handle the trivial case where there are no imports, or the list has * already been done. */ if (mod->imports == NULL || mod->allimports != NULL) return; /* Make sure all the direct imports are done first. */ for (mld = mod->imports; mld != NULL; mld = mld->next) setAllImports(mld->module); /* * Now build the list from our direct imports lists but ignoring * duplicates. */ for (mld = mod->imports; mld != NULL; mld = mld->next) { moduleListDef *amld; for (amld = mld->module->allimports; amld != NULL; amld = amld->next) addUniqueModule(mod, amld->module); addUniqueModule(mod, mld->module); } } /* * Append a module to the list of all imported modules if it isn't already * there. */ static void addUniqueModule(moduleDef *mod, moduleDef *imp) { moduleListDef **tail; for (tail = &mod->allimports; *tail != NULL; tail = &(*tail)->next) if ((*tail)->module == imp) return; *tail = sipMalloc(sizeof (moduleListDef)); (*tail)->module = imp; (*tail)->next = NULL; } /* * Move the casts and slots to the correct place for a main module (ie. one we * are generating code for). */ static void moveMainModuleCastsSlots(sipSpec *pt, moduleDef *mod) { classDef *cd; memberDef *md; for (cd = pt->classes; cd != NULL; cd = cd->next) if (cd->iff->module == mod) moveClassCasts(pt, mod, cd); for (md = mod->othfuncs; md != NULL; md = md->next) if (md->slot != no_slot && md->module == mod) moveGlobalSlot(pt, mod, md); } /* * Move any class casts to its correct class, or publish as a ctor extender. */ static void moveClassCasts(sipSpec *pt, moduleDef *mod, classDef *cd) { argList *al; for (al = cd->casts; al != NULL; al = al->next) { classDef *dcd = al->arg.u.cd; ctorDef *ct, **ctp; argDef *ad; if (al->arg.atype == class_type) dcd = al->arg.u.cd; else /* Previous error checking means this will always work. */ dcd = findAltClassImplementation(pt, al->arg.u.mtd); /* 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); dcd = getProxy(mod, dcd); } ifaceFileIsUsed(&dcd->iff->used, ad); ct->pysig.nrArgs = 1; /* Append it to the list. */ for (ctp = &dcd->ctors; *ctp != NULL; ctp = &(*ctp)->next) if (sameSignature(&(*ctp)->pysig, &ct->pysig, FALSE)) { fatal("operator "); fatalScopedName(classFQCName(dcd)); fatal("::"); fatalScopedName(classFQCName(dcd)); fatal("("); fatalScopedName(classFQCName(cd)); fatal(") already defined\n"); } *ctp = ct; } } /* * If possible, move a global slot to its correct class. */ static void moveGlobalSlot(sipSpec *pt, moduleDef *mod, memberDef *gmd) { overDef **odp = &mod->overs, *od; while ((od = *odp) != NULL) { int second; argDef *arg0, *arg1; memberDef *md, **mdhead; overDef **odhead; moduleDef *mod; nameDef *nd; if (od->common != gmd) { odp = &od->next; continue; } /* * We know that the slot has the right number of arguments, but the * first or second one needs to be a class or enum defined in the same * module. Otherwise we leave it as it is and publish it as a slot * extender. */ arg0 = &od->pysig.args[0]; arg1 = &od->pysig.args[1]; mdhead = NULL; second = FALSE; nd = NULL; if (arg0->atype == class_type) { mdhead = &arg0->u.cd->members; odhead = &arg0->u.cd->overs; mod = arg0->u.cd->iff->module; } else if (arg0->atype == mapped_type) { classDef *cd = findAltClassImplementation(pt, arg0->u.mtd); if (cd != NULL) { mdhead = &cd->members; odhead = &cd->overs; mod = cd->iff->module; } } else if (arg0->atype == enum_type) { mdhead = &arg0->u.ed->slots; odhead = &arg0->u.ed->overs; mod = arg0->u.ed->module; nd = arg0->u.ed->pyname; } else if (arg1->atype == class_type) { mdhead = &arg1->u.cd->members; odhead = &arg1->u.cd->overs; mod = arg1->u.cd->iff->module; second = TRUE; } else if (arg1->atype == mapped_type) { classDef *cd = findAltClassImplementation(pt, arg1->u.mtd); if (cd != NULL) { mdhead = &cd->members; odhead = &cd->overs; mod = cd->iff->module; second = TRUE; } } else if (arg1->atype == enum_type) { mdhead = &arg1->u.ed->slots; odhead = &arg1->u.ed->overs; mod = arg1->u.ed->module; nd = arg1->u.ed->pyname; second = TRUE; } if (mdhead == NULL) { fatal("%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) { fatal("%s:%d: The first argument 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) { fatal("%s:%d: The first argument 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->next = pcd->members; pcd->members = pmd; } /* Add the proxy overload. */ pod = sipMalloc(sizeof (overDef)); *pod = *od; pod->common = pmd; pod->next = pcd->overs; pcd->overs = pod; /* Remove the first argument. */ pod->pysig.args[0] = pod->pysig.args[1]; pod->pysig.nrArgs = 1; /* Remove from the list. */ *odp = od->next; } else odp = &od->next; continue; } /* Remove from the list. */ *odp = od->next; /* The only time we need the name of an enum is when it has slots. */ if (nd != NULL) setIsUsedName(nd); /* See if there is already a member or create a new one. */ for (md = *mdhead; md != NULL; md = md->next) if (md->slot == gmd->slot) break; if (md == NULL) { md = sipMalloc(sizeof (memberDef)); *md = *gmd; md->module = mod; md->next = *mdhead; *mdhead = md; } /* Move the overload to the end of the destination list. */ setIsPublic(od); setIsGlobal(od); od->common = md; od->next = NULL; while (*odhead != NULL) odhead = &(*odhead)->next; *odhead = od; /* * Remove the first argument of 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; } /* * Filter the virtual handlers for a main module (ie. one we are generating * code for. */ static void filterMainModuleVirtualHandlers(moduleDef *mod) { moduleListDef *mld; virtHandlerDef *vhd; /* * Remove redundant virtual handlers. It's important that earlier, ie. * those at the deepest level of %Import, are done first. */ for (mld = mod->allimports; mld != NULL; mld = mld->next) filterModuleVirtualHandlers(mld->module); filterModuleVirtualHandlers(mod); /* * Make sure we have the interface files for all types from other modules * that are used in virtual handlers implemented in this module. */ for (vhd = mod->virthandlers; vhd != NULL; vhd = vhd->next) if (!isDuplicateVH(vhd)) ifaceFilesAreUsedBySignature(&mod->used, vhd->cppsig); } /* * Go through the virtual handlers filtering those that can duplicate earlier * ones. Make sure each virtual is numbered within its module, and according * to their position in the list (ignoring duplicates). */ static void filterModuleVirtualHandlers(moduleDef *mod) { virtHandlerDef *vhd; /* See if it has already been done for this module. */ if (mod->nrvirthandlers >= 0) return; mod->nrvirthandlers = 0; for (vhd = mod->virthandlers; vhd != NULL; vhd = vhd->next) { virtHandlerDef *best, *best_thismod, *hd; best = best_thismod = NULL; /* * If this has handwritten code then we will want to use it. * Otherwise, look for a handler in earlier modules. */ if (vhd->virtcode == NULL) { moduleListDef *mld; for (mld = mod->allimports; mld != NULL && mld->module != mod; mld = mld->next) { for (hd = mld->module->virthandlers; hd != NULL; hd = hd->next) if (sameVirtualHandler(vhd, hd)) { best = hd; break; } /* * No need to check later modules as this will either be the * right one, or a duplicate of the right one. */ if (best != NULL) break; } } /* * Find the best candidate in this module in case we want to give it * our handwritten code. */ for (hd = mod->virthandlers; hd != vhd; hd = hd->next) if (sameVirtualHandler(vhd, hd)) { best_thismod = hd; break; } /* * We don't use this one if it doesn't have virtual code and there is * an alternative, or if it does have virtual code and there is already * an alternative in the same module which doesn't have virtual code. */ if ((vhd->virtcode == NULL && (best != NULL || best_thismod != NULL)) || (vhd->virtcode != NULL && best_thismod != NULL && best_thismod->virtcode == NULL)) { virtHandlerDef *saved; /* * If the alternative is in the same module and we have virtual * code then give it to the alternative. Note that there is a bug * here. If there are three handlers, the first without code and * the second and third with code then which code is transfered to * the first is down to luck. We should really only transfer code * to methods that are known to be re-implementations - just having * the same signature isn't enough. */ if (best_thismod != NULL) { if (best_thismod->virtcode == NULL && vhd->virtcode != NULL) { best_thismod->virtcode = vhd->virtcode; resetIsDuplicateVH(best_thismod); } best = best_thismod; } /* Use the better one in place of this one. */ saved = vhd->next; *vhd = *best; setIsDuplicateVH(vhd); vhd->next = saved; } else vhd->virthandlernr = mod->nrvirthandlers++; } } /* * Add an overload that is automatically generated (typically by Qt's moc). */ static void addAutoOverload(sipSpec *pt,classDef *autocd,overDef *autood) { classDef *cd; /* Find every class that has this one in its hierarchy. */ for (cd = pt -> classes; cd != NULL; cd = cd -> next) { mroDef *mro; if (cd == autocd) continue; for (mro = cd -> mro; mro != NULL; mro = mro -> next) if (mro -> cd == autocd) { memberDef *md; overDef *od; /* Another overload may already exist. */ for (md = cd -> members; md != NULL; md = md -> next) if (md -> pyname == autood -> common -> pyname) break; if (md == NULL) { md = sipMalloc(sizeof (memberDef)); md -> pyname = autood -> common -> pyname; md -> memberflags = autood -> common -> memberflags; md -> slot = autood -> common -> slot; md -> module = cd -> iff -> module; md -> next = cd -> members; cd -> members = md; } od = sipMalloc(sizeof (overDef)); *od = *autood; od -> common = md; od -> next = cd -> overs; cd -> overs = od; resetIsAutoGen(od); if (generatingCodeForModule(pt, cd->iff->module)) setIsUsedName(md -> pyname); break; } } } /* * Set the complete hierarchy for a class. */ static void setHierarchy(sipSpec *pt, classDef *base, classDef *cd, classList **head) { mroDef **tailp = &cd->mro; /* See if it has already been done. */ if (cd->mro != NULL) return; if (cd->ecd != NULL) { setHierarchy(pt, base, cd->ecd, head); if (isDeprecatedClass(cd->ecd)) setIsDeprecatedClass(cd); } if (cd->iff->type == class_iface) { classList *cl; /* The first thing is itself. */ appendToMRO(cd->mro, &tailp, cd); if (cd->convtosubcode != NULL) cd->subbase = cd; /* Now do it's superclasses. */ setHierBeingSet(cd->mro); for (cl = cd->supers; cl != NULL; cl = cl->next) { mroDef *mro; if (cl->cd->mro != NULL && hierBeingSet(cl->cd->mro)) { fatal("Recursive class hierarchy detected: "); fatalScopedName(classFQCName(cd)); fatal(" and "); fatalScopedName(classFQCName(cl->cd)); fatal("\n"); } /* Make sure the super-class's hierarchy has been done. */ setHierarchy(pt, base, cl->cd, head); /* Append the super-classes hierarchy. */ for (mro = cl->cd->mro; mro != NULL; mro = mro->next) { appendToMRO(cd->mro, &tailp, mro->cd); if (isDeprecatedClass(mro->cd)) setIsDeprecatedClass(cd); /* * If the super-class is a QObject sub-class then this one is * as well. */ if (isQObjectSubClass(mro->cd)) setIsQObjectSubClass(cd); /* * If the super-class can't be assigned to then this one * cannot either. */ if (cannotAssign(mro->cd)) setCannotAssign(cd); /* * If the super-class has a shadow then this one should have * one as well. */ if (hasShadow(mro->cd)) setHasShadow(cd); /* * Ensure that the sub-class base class is the furthest up the * hierarchy. */ if (mro->cd->subbase != NULL) cd->subbase = mro->cd->subbase; } } resetHierBeingSet(cd->mro); /* * If the class doesn't have an explicit meta-type then inherit from * the module's default. */ if (cd->metatype == NULL && cd->supers == NULL) cd->metatype = cd->iff->module->defmetatype; if (cd->metatype != NULL && generatingCodeForModule(pt, cd->iff->module)) setIsUsedName(cd->metatype); /* * If the class doesn't have an explicit super-type then inherit from * the module's default. */ if (cd->supertype == NULL && cd->supers == NULL) cd->supertype = cd->iff->module->defsupertype; if (cd->supertype != NULL && strcmp(cd->supertype->text, "sip.wrapper") == 0) cd->supertype = NULL; if (cd->supertype != NULL && generatingCodeForModule(pt, cd->iff->module)) setIsUsedName(cd->supertype); } /* * Make sure that the module in which a sub-class convertor will be created * knows about the base class. */ if (cd->subbase != NULL) addToUsedList(&cd->iff->module->used, cd->subbase->iff); /* * We can't have a shadow if the specification is incomplete, there is * a private dtor, there are no none-private ctors or there are private * abstract methods. */ if (isIncomplete(cd) || isPrivateDtor(cd) || !canCreate(cd)) resetHasShadow(cd); else { overDef *od; /* * Note that we should be able to provide better support for * abstract private methods than we do at the moment. */ for (od = cd->overs; od != NULL; od = od->next) if (isAbstract(od) && isPrivate(od)) { resetHasShadow(cd); /* * It also means we cannot create an instance * from Python. */ resetCanCreate(cd); break; } } /* Add it to the new list. */ appendToClassList(head,cd); } /* * Append a class definition to an mro list */ static void appendToMRO(mroDef *head,mroDef ***tailp,classDef *cd) { mroDef *mro, *new; new = sipMalloc(sizeof (mroDef)); new -> cd = cd; new -> mroflags = 0; new -> next = NULL; /* See if it is a duplicate. */ for (mro = head; mro != NULL; mro = mro -> next) if (mro -> cd == cd) { setIsDuplicateSuper(new); if (!isDuplicateSuper(mro)) setHasDuplicateSuper(mro); break; } /* Append to the list and update the tail pointer. */ **tailp = new; *tailp = &new -> next; } /* * Get the base types for all typedefs of a module. */ static void transformTypedefs(sipSpec *pt, moduleDef *mod) { typedefDef *td; for (td = pt->typedefs; td != NULL; td = td->next) if (td->module == mod) 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, moduleDef *mod) { mappedTypeDef *mt; for (mt = pt->mappedtypes; mt != NULL; mt = mt->next) { if (mt->iff->module == mod) { if (mt->type.atype == template_type) resolveMappedTypeTypes(pt, mt); else transformScopeOverloads(pt, NULL, mt, mt->overs); } } } /* * Transform the data types for a list of ctors. */ static void transformCtors(sipSpec *pt, classDef *cd) { ctorDef *ct; for (ct = cd->ctors; ct != NULL; ct = ct->next) { ctorDef *prev; resolveCtorTypes(pt, cd, ct); /* * Now check that the Python signature doesn't conflict with an * earlier one. 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); /* Append it to the list. */ for (tailp = &cd->ctors; *tailp != NULL; tailp = &(*tailp)->next) ; *tailp = copyct; } /* * Transform the data types for a list of overloads. */ static void transformScopeOverloads(sipSpec *pt, classDef *c_scope, mappedTypeDef *mt_scope, overDef *overs) { overDef *od; for (od = overs; od != NULL; od = od->next) { overDef *prev; resolveFuncTypes(pt, od->common->module, c_scope, mt_scope, od); /* * Now check that the Python signature doesn't conflict with an earlier * one. If there is %MethodCode then assume that it will handle any * potential conflicts. */ if (od->methodcode == NULL) { 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; fatal("%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); fatal("::"); } fatal("%s() has overloaded functions with the same Python signature\n", od->common->pyname->text); } } } if (c_scope != NULL && isDeprecatedClass(c_scope)) setIsDeprecated(od); } } /* * Transform the data types for the variables of a module. */ static void transformVariableList(sipSpec *pt, moduleDef *mod) { varDef *vd; for (vd = pt->vars; vd != NULL; vd = vd->next) if (vd->module == mod) if (vd->ecd == NULL || !isTemplateClass(vd->ecd)) resolveVariableType(pt, vd); } /* * Set the list of visible member functions for a class. */ static void getVisibleMembers(sipSpec *pt, classDef *cd) { mroDef *mro; cd->visible = NULL; for (mro = cd->mro; mro != NULL; mro = mro->next) { memberDef *md; classDef *mrocd; if (isDuplicateSuper(mro)) continue; mrocd = mro->cd; for (md = mrocd->members; md != NULL; md = md->next) { visibleList *vl; /* * See if it is already in the list. This has the desired side * effect of eliminating any functions that have an implementation * closer to this class in the hierarchy. This is the only reason * to define private functions. */ for (vl = cd->visible; vl != NULL; vl = vl->next) if (vl->m->pyname == md->pyname) break; /* See if it is a new member function. */ if (vl == NULL) { overDef *od; vl = sipMalloc(sizeof (visibleList)); vl->m = md; vl->cd = mrocd; vl->next = cd->visible; cd->visible = vl; for (od = mrocd->overs; od != NULL; od = od->next) if (od->common == md) { if (isAbstract(od)) setIsAbstractClass(cd); ifaceFilesAreUsedByOverload(&cd->iff->used, od); /* See if we need the name. */ if (!generatingCodeForModule(pt, cd->iff->module)) continue; if (isProtected(od) || (isSignal(od) && pluginPyQt3(pt))) setIsUsedName(md->pyname); /* Make we have any API name. */ if (od->api_range != NULL) setIsUsedName(od->api_range->api_name); } } } } } /* * Get all the virtuals for a particular class. */ static void getVirtuals(sipSpec *pt, classDef *cd) { mroDef *mro; virtOverDef *vod; for (mro = cd->mro; mro != NULL; mro = mro->next) { if (isDuplicateSuper(mro)) continue; getClassVirtuals(cd, mro->cd); } /* * Identify any re-implementations of virtuals. We have to do this for all * classes, not just those in the module we are generating code for. */ for (vod = cd->vmembers; vod != NULL; vod = vod->next) { overDef *od; for (od = cd->overs; od != NULL; od = od->next) { if (isVirtual(od)) continue; if (strcmp(vod->o.cppname, od->cppname) == 0 && sameOverload(&vod->o, od)) { setIsVirtualReimp(od); break; } } /* * If this class is defined in the main module make sure we get the API * files for all the visible virtuals. */ if (generatingCodeForModule(pt, cd->iff->module)) { /* Make sure we get the name. */ setIsUsedName(vod->o.common->pyname); } } } /* * Update the list of visible virtual functions for a base class from a class * in its MRO. */ static void getClassVirtuals(classDef *base, classDef *cd) { overDef *od; for (od = cd->overs; od != NULL; od = od->next) { mroDef *mro; int is_nearer; overDef *reimp; if (!isVirtual(od) || isPrivate(od)) continue; /* * See if there is an implementation nearer in the class hierarchy with * the same name that will hide it. */ is_nearer = FALSE; reimp = NULL; for (mro = base->mro; mro->cd != cd; mro = mro->next) { overDef *nod; if (isDuplicateSuper(mro)) continue; /* * Ignore classes that are on a different branch of the class * hierarchy. */ if (!isSubClass(mro->cd, cd)) continue; for (nod = mro->cd->overs; nod != NULL; nod = nod->next) { if (strcmp(nod->cppname, od->cppname) == 0) { is_nearer = TRUE; /* * Re-implementations explicitly marked as virtual will * already have been handled. */ if (!isVirtual(nod) && sameSignature(nod->cppsig, od->cppsig, TRUE) && isConst(nod) == isConst(od) && !isAbstract(nod)) reimp = nod; break; } } if (is_nearer) break; } if (!is_nearer || reimp != NULL) { virtOverDef *vod; vod = sipMalloc(sizeof (virtOverDef)); vod->o = *od; vod->next = base->vmembers; base->vmembers = vod; /* * If there was a reimplementation then we use its protection and * abstract flags. */ if (reimp != NULL) { vod->o.overflags &= ~(SECT_MASK | OVER_IS_ABSTRACT); vod->o.overflags |= (SECT_MASK | OVER_IS_ABSTRACT) & reimp->overflags; } } } } /* * Return TRUE is a class is derived from another. */ static int isSubClass(classDef *cc,classDef *pc) { mroDef *mro; /* * In other words, does the parent class appear in the child class's * MRO list. */ for (mro = cc -> mro; mro != NULL; mro = mro -> next) if (mro -> cd == pc) return TRUE; return FALSE; } /* * Resolve the types of a mapped type based on a template. */ static void resolveMappedTypeTypes(sipSpec *pt, mappedTypeDef *mt) { int a; signatureDef *sd = &mt->type.u.td->types; for (a = 0; a < sd->nrArgs; ++a) { argDef *ad = &sd->args[a]; /* Leave templates as they are. */ if (ad->atype != template_type) 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); } /* * Resolve the types of a ctor. */ static void resolveCtorTypes(sipSpec *pt,classDef *scope,ctorDef *ct) { int a; /* Handle any C++ signature. */ if (ct->cppsig != NULL && ct->cppsig != &ct->pysig) for (a = 0; a < ct -> cppsig -> nrArgs; ++a) 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) && (ct -> cppsig == &ct -> pysig || ct -> methodcode == NULL)) { fatalScopedName(classFQCName(scope)); fatal(" unsupported ctor argument type - provide %%MethodCode and a C++ signature\n"); } ifaceFileIsUsed(&scope->iff->used, ad); scopeDefaultValue(pt, scope, ad); } } /* * Resolve the types of a function. */ static void resolveFuncTypes(sipSpec *pt, moduleDef *mod, classDef *c_scope, mappedTypeDef *mt_scope, overDef *od) { argDef *res; /* Handle any C++ signature. */ if (od->cppsig != &od->pysig) { int a; 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->virthandler->virtcode == NULL) { fatal("%s:%d: ", od->sloc.name, od->sloc.linenr); if (c_scope != NULL) { fatalScopedName(classFQCName(c_scope)); fatal("::"); } 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) { fatal("%s:%d: ", od->sloc.name, od->sloc.linenr); if (scope != NULL) { fatalScopedName(classFQCName(scope)); fatal("::"); } 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) { fatal("%s:%d: ", od->sloc.name, od->sloc.linenr); if (scope != NULL) { fatalScopedName(classFQCName(scope)); fatal("::"); } fatal("%s() unsupported function return type - provide %%MethodCode and a %s signature\n", od->cppname, (pt->genc ? "C" : "C++")); } } } for (a = 0; a < pysig -> nrArgs; ++a) { argDef *ad = &pysig -> args[a]; 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)) { fatal("%s:%d: ", od->sloc.name, od->sloc.linenr); if (scope != NULL) { fatalScopedName(classFQCName(scope)); fatal("::"); } fatal("%s() unsupported signal argument type\n", od->cppname); } } else if (!supportedType(scope, od, ad, TRUE)) { int need_meth, need_virt; need_meth = (od->cppsig == &od->pysig || od->methodcode == NULL); need_virt = (isVirtual(od) && od->virthandler->virtcode == NULL); if (need_meth || need_virt) { if (od->sloc.name != NULL) fatal("%s:%d: ", od->sloc.name, od->sloc.linenr); if (scope != NULL) { fatalScopedName(classFQCName(scope)); fatal("::"); } if (need_meth) fatal("%s() unsupported function argument type - provide %%MethodCode and a %s signature\n", od->cppname, (pt->genc ? "C" : "C++")); fatal("%s() unsupported function argument type - provide %%MethodCode, %%VirtualCatcherCode and a C++ signature\n", od->cppname); } } 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; } if (bad && (vd->getcode == NULL || vd->setcode == NULL)) { fatalScopedName(vd->fqcname); fatal(" has an unsupported type - provide %%GetCode and %%SetCode\n"); } if (vtype->atype != class_type && vd->accessfunc != NULL) { fatalScopedName(vd->fqcname); fatal(" has %%AccessCode but isn't a class instance\n"); } if (vd->ecd != NULL) ifaceFileIsUsed(&vd->ecd->iff->used, vtype); else ifaceFileIsUsed(&vd->module->used, vtype); /* Scoped variables need a handler unless they have %AccessCode. */ if (vd->ecd != NULL && vd->accessfunc == NULL) { setNeedsHandler(vd); setHasVarHandlers(vd->ecd); } } /* * See if a type is supported by the generated code. */ static int supportedType(classDef *cd,overDef *od,argDef *ad,int outputs) { switch (ad -> atype) { case anyslot_type: /* * This must be an input, and must also have handwritten code. */ ensureInput(cd,od,ad); return FALSE; case signal_type: case slot_type: case rxcon_type: case rxdis_type: case slotcon_type: case slotdis_type: case qobject_type: case ellipsis_type: /* These can only appear in argument lists without * or &. */ ensureInput(cd,od,ad); return TRUE; case ascii_string_type: case latin1_string_type: case utf8_string_type: case sstring_type: case ustring_type: case string_type: case wstring_type: if (isReference(ad)) { if (outputs && ad -> nrderefs <= 1) { defaultOutput(ad); return TRUE; } } else if (ad -> nrderefs == 0) { ensureInput(cd,od,ad); return TRUE; } else if (ad -> nrderefs == 1) { if (outputs) defaultInput(ad); else ensureInput(cd,od,ad); return TRUE; } else if (ad -> nrderefs == 2 && outputs) { defaultOutput(ad); return TRUE; } break; case cfloat_type: case float_type: case cdouble_type: case double_type: case enum_type: case bool_type: case cbool_type: case 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; } /* Unsupported if we got this far. */ return FALSE; } /* * Ensure the direction of an argument is an input. */ static void ensureInput(classDef *cd,overDef *od,argDef *ad) { if (isOutArg(ad)) { if (cd != NULL) { fatalScopedName(classFQCName(cd)); fatal("::"); } if (od != NULL) fatal("%s",od -> cppname); fatal("() invalid argument type for /Out/\n"); } setIsInArg(ad); } /* * Default the direction of an argument to an input. */ static void defaultInput(argDef *ad) { if (!isInArg(ad) && !isOutArg(ad)) setIsInArg(ad); } /* * Default the direction of an argument to an output unless the argument is * const. */ static void defaultOutput(argDef *ad) { if (!isOutArg(ad) && !isInArg(ad)) { if (isConstArg(ad)) setIsInArg(ad); else setIsOutArg(ad); } } /* * Put a scoped name to stderr. */ void fatalScopedName(scopedNameDef *snd) { while (snd != NULL) { fatal("%s",snd -> name); snd = snd -> next; if (snd != NULL) fatal("::"); } } /* * Compare two overloads and return TRUE if they are the same. */ static int sameOverload(overDef *od1, overDef *od2) { /* They must both be enabled for the same API. */ if (od1->api_range != od2->api_range) return FALSE; /* They must both be const, or both not. */ if (isConst(od1) != isConst(od2)) return FALSE; return sameSignature(&od1->pysig, &od2->pysig, TRUE); } /* * Compare two virtual handlers and return TRUE if they are the same. */ static int sameVirtualHandler(virtHandlerDef *vhd1,virtHandlerDef *vhd2) { int a; if (isTransferVH(vhd1) != isTransferVH(vhd2)) return FALSE; if (!sameArgType(&vhd1->pysig->result, &vhd2->pysig->result, TRUE)) return FALSE; if (!sameSignature(vhd1->pysig, vhd2->pysig, TRUE)) return FALSE; /* Take into account the argument directions in the Python signatures. */ for (a = 0; a < vhd1->pysig->nrArgs; ++a) { int dir1 = (vhd1->pysig->args[a].argflags & (ARG_IN | ARG_OUT)); int dir2 = (vhd2->pysig->args[a].argflags & (ARG_IN | ARG_OUT)); if (dir1 != dir2) return FALSE; } if (vhd1->pysig == vhd1->cppsig && vhd2->pysig == vhd2->cppsig) return TRUE; if (!sameArgType(&vhd1->cppsig->result, &vhd2->cppsig->result, TRUE)) return FALSE; return sameSignature(vhd1->cppsig, vhd2->cppsig, TRUE); } /* * Compare two signatures and return TRUE if they are the same. */ int sameSignature(signatureDef *sd1,signatureDef *sd2,int strict) { int a; if (strict) { /* The number of arguments must be the same. */ if (sd1 -> nrArgs != sd2 -> nrArgs) return FALSE; } else { int na1, na2; /* We only count the compulsory arguments. */ na1 = 0; for (a = 0; a < sd1 -> nrArgs; ++a) { if (sd1 -> args[a].defval != NULL) break; ++na1; } na2 = 0; for (a = 0; a < sd2 -> nrArgs; ++a) { if (sd2 -> args[a].defval != NULL) break; ++na2; } if (na1 != na2) return FALSE; } /* The arguments must be the same. */ for (a = 0; a < sd1 -> nrArgs; ++a) { if (!strict && sd1 -> args[a].defval != NULL) break; if (!sameArgType(&sd1 -> args[a],&sd2 -> args[a],strict)) return FALSE; } /* Must be the same if we've got this far. */ return TRUE; } #define pyAsString(t) ((t) == ustring_type || (t) == sstring_type || \ (t) == string_type || (t) == ascii_string_type || \ (t) == latin1_string_type || (t) == utf8_string_type) #define pyAsFloat(t) ((t) == cfloat_type || (t) == float_type || \ (t) == cdouble_type || (t) == double_type) #define pyAsInt(t) ((t) == bool_type || (t) == ssize_type || \ (t) == 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(a1->u.snd, a2->u.cd->iff->fqcname) == 0; if (a1->atype == mapped_type && a2->atype == defined_type) return compareScopedNames(a1->u.mtd->iff->fqcname, a2->u.snd) == 0; if (a1->atype == defined_type && a2->atype == mapped_type) return compareScopedNames(a1->u.snd, a2->u.mtd->iff->fqcname) == 0; 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(a1->u.snd, a2->u.ed->fqcname) == 0; return FALSE; } switch (a1->atype) { case class_type: if (a1->u.cd != a2->u.cd) return FALSE; break; case enum_type: if (a1->u.ed != a2->u.ed) return FALSE; break; case slotcon_type: case slotdis_type: if (!sameSignature(a1->u.sa, a2->u.sa, TRUE)) return FALSE; break; case template_type: { int a; templateDef *td1, *td2; td1 = a1->u.td; td2 = a2->u.td; if (compareScopedNames(td1->fqname, td2->fqname) != 0 || td1->types.nrArgs != td2->types.nrArgs) return FALSE; for (a = 0; a < td1->types.nrArgs; ++a) { 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; } /* Must be the same if we've got this far. */ return TRUE; } /* * See if two Python signatures are the same as far as Python is concerned. */ static int samePythonSignature(signatureDef *sd1, signatureDef *sd2) { int a1, a2; a1 = a2 = -1; for (;;) { a1 = nextSignificantArg(sd1, a1); a2 = nextSignificantArg(sd2, a2); if (a1 < 0 || a2 < 0) break; if (!sameArgType(&sd1->args[a1], &sd2->args[a2], FALSE)) return FALSE; } return (a1 < 0 && a2 < 0); } /* * Return the next significant argument from a Python signature (ie. one that * is not optional or an output only argument. Return -1 if there isn't one. */ static int nextSignificantArg(signatureDef *sd, int a) { while (++a < sd->nrArgs) { if (sd->args[a].defval != NULL) break; if (isInArg(&sd->args[a])) return a; } return -1; } /* * The equivalent of strcmp() for scoped names. */ int compareScopedNames(scopedNameDef *snd1, scopedNameDef *snd2) { while (snd1 != NULL && snd2 != NULL) { int res = strcmp(snd1->name, snd2->name); if (res != 0) return res; snd1 = snd1->next; snd2 = snd2->next; } if (snd1 == NULL) return (snd2 == NULL ? 0 : -1); return 1; } /* * Add an explicit scope to the default value of an argument if possible. */ static void scopeDefaultValue(sipSpec *pt,classDef *cd,argDef *ad) { valueDef *vd, **tailp, *newvd; /* * We do a quick check to see if we need to do anything. This means * we can limit the times we need to copy the default value. It needs * to be copied because it will be shared by class versions that have * been created on the fly and it may need to be scoped differently for * each of those versions. */ for (vd = ad -> defval; vd != NULL; vd = vd -> next) if (vd -> vtype == scoped_value && vd -> u.vscp -> next == NULL) break; if (vd == NULL) return; /* * It's not certain that we will do anything, but we assume we will and * start copying. */ newvd = NULL; tailp = &newvd; for (vd = ad -> defval; vd != NULL; vd = vd -> next) { mroDef *mro; scopedNameDef *origname; valueDef *new; /* Make the copy. */ new = sipMalloc(sizeof (valueDef)); *new = *vd; *tailp = new; tailp = &new -> next; /* * Skip this part of the expression if it isn't a named value * or it already has a scope. */ if (vd -> vtype != scoped_value || vd -> u.vscp -> next != NULL) continue; /* * Search the class hierarchy for an enum value with the same * name. If we don't find one, leave it as it is (the compiler * will find out if this is a problem). */ origname = vd -> u.vscp; for (mro = cd -> mro; mro != NULL; mro = mro -> next) { enumDef *ed; if (isDuplicateSuper(mro)) continue; for (ed = pt -> enums; ed != NULL; ed = ed -> next) { enumMemberDef *emd; if (ed -> ecd != mro -> cd) continue; for (emd = ed -> members; emd != NULL; emd = emd -> next) if (strcmp(emd -> cname,origname -> name) == 0) { scopedNameDef *snd; /* * Take the scope from the * class that the enum was * defined in. */ snd = copyScopedName(mro -> cd -> iff -> fqcname); appendScopedName(&snd,origname); new -> u.vscp = snd; /* Nothing more to do. */ break; } if (emd != NULL) break; } if (ed != NULL) break; } } ad -> defval = newvd; } /* * 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; if (c_scope != NULL) searchClassScope(pt, c_scope, snd,type); if (type->atype == no_type) searchMappedTypes(pt, mod, snd, type); if (type->atype == no_type) searchTypedefs(pt, snd, type); if (type->atype == no_type) searchEnums(pt, snd, type); if (type->atype == no_type) searchClasses(pt, mod, snd, type); if (type->atype == no_type) { 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(type->u.td->fqname, mtt->mt->type.u.td->fqname) == 0 && sameTemplateSignature(&mtt->mt->type.u.td->types, &type->u.td->types, TRUE)) { type->u.mtd = instantiateMappedTypeTemplate(pt, mod, mtt, type); type->atype = mapped_type; break; } } } } /* * If the type corresponds to a previously instantiated class template then * replace it with the class that was created. */ static void resolveInstantiatedClassTemplate(sipSpec *pt, argDef *type) { int a; classDef *cd; templateDef *td; signatureDef *sd; if (type->atype != template_type) return; td = type->u.td; sd = &td->types; for (a = 0; a < sd->nrArgs; ++a) resolveInstantiatedClassTemplate(pt, &sd->args[a]); for (cd = pt->classes; cd != NULL; cd = cd->next) if (cd->td != NULL && compareScopedNames(cd->td->fqname, td->fqname) == 0 && sameSignature(&cd->td->types, sd, TRUE)) { type->atype = class_type; type->u.cd = cd; break; } } /* * Instantiate a mapped type template and return it. */ static mappedTypeDef *instantiateMappedTypeTemplate(sipSpec *pt, moduleDef *mod, mappedTypeTmplDef *mtt, argDef *type) { scopedNameDef *type_names, *type_values; mappedTypeDef *mtd; type_names = type_values = NULL; appendTypeStrings(type->u.td->fqname, &mtt->mt->type.u.td->types, &type->u.td->types, &mtt->sig, &type_names, &type_values); mtd = allocMappedType(pt, type); if (generatingCodeForModule(pt, mod)) setIsUsedName(mtd->cname); mtd->iff = findIfaceFile(pt, mod, encodedTemplateName(type->u.td), mappedtype_iface, NULL, type); mtd->iff->module = mod; mtd->mtflags = mtt->mt->mtflags; mtd->doctype = templateString(mtt->mt->doctype, type_names, type_values); 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. */ static const char *templateString(const char *src, scopedNameDef *names, scopedNameDef *values) { char *dst; /* Handle the trivial case. */ if (src == NULL) return NULL; dst = sipStrdup(src); while (names != NULL && values != NULL) { char *cp, *vname = values->name; size_t name_len, value_len; name_len = strlen(names->name); value_len = strlen(vname); /* Translate any C++ scoping to Python. */ while ((cp = strstr(vname, "::")) != NULL) { char *new_vname = sipMalloc(value_len); size_t pos = cp - vname; memcpy(new_vname, vname, pos); new_vname[pos] = '.'; strcpy(new_vname + pos + 1, cp + 2); if (vname != values->name) free(vname); vname = new_vname; --value_len; } while ((cp = strstr(dst, names->name)) != NULL) { char *new_dst = sipMalloc(strlen(dst) - name_len + value_len + 1); memcpy(new_dst, dst, cp - dst); memcpy(new_dst + (cp - dst), vname, value_len); strcpy(new_dst + (cp - dst) + value_len, cp + name_len); free(dst); dst = new_dst; } if (vname != values->name) free(vname); names = names->next; values = values->next; } return dst; } /* * Search for a name in a scope and return the corresponding type. */ static void searchClassScope(sipSpec *pt, classDef *c_scope, scopedNameDef *snd, argDef *ad) { scopedNameDef *tmpsnd = NULL; mroDef *mro; for (mro = c_scope->mro; mro != NULL; mro = mro->next) { if (isDuplicateSuper(mro)) continue; /* Append the name to the scope and see if it exists. */ tmpsnd = copyScopedName(classFQCName(mro->cd)); appendScopedName(&tmpsnd, copyScopedName(snd)); searchMappedTypes(pt, mro->cd->iff->module, tmpsnd, ad); if (ad->atype != no_type) break; searchTypedefs(pt, tmpsnd, ad); if (ad->atype != no_type) break; searchEnums(pt, tmpsnd, ad); if (ad->atype != no_type) break; searchClasses(pt, mro->cd->iff->module, tmpsnd, ad); if (ad->atype != no_type) break; freeScopedName(tmpsnd); tmpsnd = NULL; } if (tmpsnd != NULL) freeScopedName(tmpsnd); } /* * Search the mapped types for a name and return the type. */ static void searchMappedTypes(sipSpec *pt, moduleDef *context, scopedNameDef *snd, argDef *ad) { mappedTypeDef *mtd; scopedNameDef *oname; /* Patch back to defined types so we can use sameBaseType(). */ if (snd != NULL) { oname = ad->u.snd; ad->u.snd = snd; ad->atype = defined_type; } for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next) if (sameBaseType(ad, &mtd->type)) { /* * If we a building a consolidated module and this mapped type is * defined in a different module then see if that other module is * in a different branch of the module hierarchy. */ if (isConsolidated(pt->module) && context != mtd->iff->module) { moduleListDef *mld; for (mld = context->allimports; mld != NULL; mld = mld->next) if (mld->module == mtd->iff->module) break; /* If it's in a different branch then we ignore it. */ if (mld == NULL) continue; } mtd = copyTemplateType(mtd, ad); /* Copy the type. */ ad->atype = mapped_type; ad->u.mtd = mtd; return; } /* Restore because we didn't find anything. */ if (snd != NULL) { ad->u.snd = oname; ad->atype = no_type; } } /* * 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; for (a = 0; a < src->nrArgs; ++a) { typedefDef *tdd = src->args[a].original_type; if (tdd != NULL) { /* * Create the copy now that we know it is needed and if it hasn't * already been done. */ if (mtd_copy == mtd) { mtd_copy = sipMalloc(sizeof (mappedTypeDef)); *mtd_copy = *mtd; dst = &mtd_copy->type.u.td->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->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; break; } } } /* * Print an error message describing an undefined type to stderr and terminate. */ static void fatalNoDefinedType(scopedNameDef *snd) { fatalScopedName(snd); fatal(" is undefined\n"); } /* * Make sure all interface files for a signature are used. */ static void ifaceFilesAreUsedBySignature(ifaceFileList **used, signatureDef *sd) { int a; ifaceFileIsUsed(used, &sd->result); for (a = 0; a < sd->nrArgs; ++a) ifaceFileIsUsed(used, &sd->args[a]); } /* * Make sure all interface files for a function are used. */ static void ifaceFilesAreUsedByOverload(ifaceFileList **used, overDef *od) { throwArgs *ta; ifaceFilesAreUsedBySignature(used, &od->pysig); if (od->cppsig != &od->pysig) ifaceFilesAreUsedBySignature(used, od->cppsig); if ((ta = od->exceptions) != NULL) { int a; for (a = 0; a < ta->nrArgs; ++a) addToUsedList(used, ta->args[a]->iff); } } /* * If a type has an interface file then add it to the the given list of used * interface files so that the header file is #included in the generated code. */ static void ifaceFileIsUsed(ifaceFileList **used, argDef *ad) { ifaceFileDef *iff; if ((iff = getIfaceFile(ad)) != NULL) { addToUsedList(used, iff); /* * For mapped type templates we also need the template arguments. * These will be in the mapped type's used list (which itself will be * empty for non-template mapped types). */ if (ad->atype == mapped_type) { ifaceFileList *iffl = iff->used; for (iffl = iff->used; iffl != NULL; iffl = iffl->next) addToUsedList(used, iffl->iff); } } } /* * Return the interface file for a type, or NULL if it doesn't have one. */ static ifaceFileDef *getIfaceFile(argDef *ad) { ifaceFileDef *iff; switch (ad->atype) { case class_type: iff = ad->u.cd->iff; break; case mapped_type: iff = ad->u.mtd->iff; break; case enum_type: if (ad->u.ed->fqcname != NULL) { if (ad->u.ed->ecd != NULL) { iff = ad->u.ed->ecd->iff; break; } if (ad->u.ed->emtd != NULL) { iff = ad->u.ed->emtd->iff; break; } } /* Drop through. */ default: iff = NULL; } return iff; } /* * Create the sorted array of numbered types for a module. */ static void createSortedNumberedTypesTable(sipSpec *pt, moduleDef *mod) { classDef *cd; mappedTypeDef *mtd; enumDef *ed; argDef *ad; int i; /* Count the how many types there are. */ mod->nrtypes = 0; for (cd = pt->classes; cd != NULL; cd = cd->next) { if (cd->iff->module != mod) continue; if (cd->iff->first_alt != cd->iff) continue; mod->nrtypes++; } for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next) { if (mtd->iff->module != mod) continue; if (mtd->iff->first_alt != mtd->iff) continue; mod->nrtypes++; } for (ed = pt->enums; ed != NULL; ed = ed->next) { if (ed->module != mod) continue; if (ed->fqcname == NULL) continue; if (ed->ecd != NULL && isTemplateClass(ed->ecd)) continue; if (ed->first_alt != ed) continue; mod->nrtypes++; } if (mod->nrtypes == 0) return; /* Allocate and populate the table. */ ad = mod->types = sipCalloc(mod->nrtypes, sizeof (argDef)); for (cd = pt->classes; cd != NULL; cd = cd->next) { if (cd->iff->module != mod) continue; if (cd->iff->first_alt != cd->iff) continue; ad->atype = class_type; ad->u.cd = cd; ad->name = cd->iff->name; ++ad; } for (mtd = pt->mappedtypes; mtd != NULL; mtd = mtd->next) { if (mtd->iff->module != mod) continue; if (mtd->iff->first_alt != mtd->iff) continue; ad->atype = mapped_type; ad->u.mtd = mtd; ad->name = mtd->cname; ++ad; } for (ed = pt->enums; ed != NULL; ed = ed->next) { if (ed->module != mod) continue; if (ed->fqcname == NULL) continue; if (ed->ecd != NULL && isTemplateClass(ed->ecd)) continue; if (ed->first_alt != ed) continue; ad->atype = enum_type; ad->u.ed = ed; ad->name = ed->cname; ++ad; } /* Sort the table and assign type numbers. */ qsort(mod->types, mod->nrtypes, sizeof (argDef), compareTypes); for (ad = mod->types, i = 0; i < mod->nrtypes; ++i, ++ad) { switch (ad->atype) { case class_type: ad->u.cd->iff->ifacenr = i; /* If we find a class called QObject, assume it's Qt. */ if (strcmp(ad->name->text, "QObject") == 0) mod->qobjclass = i; break; case mapped_type: ad->u.mtd->iff->ifacenr = i; break; case enum_type: ad->u.ed->enumnr = i; break; } } } /* * The qsort helper to compare two generated type names. */ static int compareTypes(const void *t1, const void *t2) { return strcmp(((argDef *)t1)->name->text, ((argDef *)t2)->name->text); } /* * Return TRUE if we are generating code for a module, ie. we are a component * of a consolidated module, or the main module where there is no consolidated * module. */ static int generatingCodeForModule(sipSpec *pt, moduleDef *mod) { if (isConsolidated(pt->module)) return (pt->module == mod->container); return (pt->module == mod); } /* * 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.15.5/siplib/0000755000076500000240000000000012310606636013745 5ustar philstaff00000000000000sip-4.15.5/siplib/apiversions.c0000644000076500000240000001600212261241062016443 0ustar philstaff00000000000000/* * The implementation of the supprt for setting API versions. * * Copyright (c) 2014 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" #include "sipint.h" /* * The structure that defines the version number of an API. */ typedef struct _apiVersionDef { /* The name of the API. */ const char *api_name; /* * The version number of the API. This will either be set explicitly via * a call to sip.setapi() or implicitly by an imported module. */ int version_nr; /* The next in the list of APIs. */ struct _apiVersionDef *next; } apiVersionDef; /* * The list of API versions. */ static apiVersionDef *api_versions = NULL; /* * Forward declarations. */ static int add_api(const char *api, int version_nr); static apiVersionDef *find_api(const char *api); /* * See if a range of versions of a particular API is enabled. */ int sip_api_is_api_enabled(const char *name, int from, int to) { const apiVersionDef *avd; if ((avd = find_api(name)) == NULL) return FALSE; if (from > 0 && avd->version_nr < from) return FALSE; if (to > 0 && avd->version_nr >= to) return FALSE; return TRUE; } /* * Initialise the the API for a module and return a negative value on error. */ int sipInitAPI(sipExportedModuleDef *em, PyObject *mod_dict) { int *apis, i; sipVersionedFunctionDef *vf; sipTypeDef **tdp; /* See if the module defines any APIs. */ if ((apis = em->em_versions) != NULL) { while (apis[0] >= 0) { /* * See if it is an API definition rather than a range * definition. */ if (apis[2] < 0) { const char *api_name; const apiVersionDef *avd; api_name = sipNameFromPool(em, apis[0]); /* Use the default version if not already set explicitly. */ if ((avd = find_api(api_name)) == NULL) if (add_api(api_name, apis[1]) < 0) return -1; } apis += 3; } } /* Add any versioned global functions to the module dictionary. */ if ((vf = em->em_versioned_functions) != NULL) { while (vf->vf_name >= 0) { if (sipIsRangeEnabled(em, vf->vf_api_range)) { const char *func_name = sipNameFromPool(em, vf->vf_name); PyMethodDef *pmd; PyObject *py_func; if ((pmd = sip_api_malloc(sizeof (PyMethodDef))) == NULL) return -1; pmd->ml_name = SIP_MLNAME_CAST(func_name); pmd->ml_meth = vf->vf_function; pmd->ml_flags = vf->vf_flags; pmd->ml_doc = vf->vf_docstring; if ((py_func = PyCFunction_New(pmd, NULL)) == NULL) return -1; if (PyDict_SetItemString(mod_dict, func_name, py_func) < 0) { Py_DECREF(py_func); return -1; } Py_DECREF(py_func); } ++vf; } } /* Update the types table according to any version information. */ for (tdp = em->em_types, i = 0; i < em->em_nrtypes; ++i, ++tdp) { sipTypeDef *td; if ((td = *tdp) != NULL && td->td_version >= 0) { do { if (sipIsRangeEnabled(em, td->td_version)) { /* Update the type with the enabled version. */ *tdp = td; break; } } while ((td = td->td_next_version) != NULL); /* * If there is no enabled version then stub the disabled version * so that we don't lose the name from the (sorted) types table. */ if (td == NULL) sipTypeSetStub(*tdp); } } return 0; } /* * Get the version number for an API. */ PyObject *sipGetAPI(PyObject *self, PyObject *args) { const char *api; const apiVersionDef *avd; if (!PyArg_ParseTuple(args, "s:getapi", &api)) return NULL; if ((avd = find_api(api)) == NULL) { PyErr_Format(PyExc_ValueError, "unknown API '%s'", api); return NULL; } #if PY_MAJOR_VERSION >= 3 return PyLong_FromLong(avd->version_nr); #else return PyInt_FromLong(avd->version_nr); #endif } /* * Set the version number for an API. */ PyObject *sipSetAPI(PyObject *self, PyObject *args) { const char *api; int version_nr; const apiVersionDef *avd; if (!PyArg_ParseTuple(args, "si:setapi", &api, &version_nr)) return NULL; if (version_nr < 1) { PyErr_Format(PyExc_ValueError, "API version numbers must be greater or equal to 1, not %d", version_nr); return NULL; } if ((avd = find_api(api)) == NULL) { char *api_copy; /* Make a deep copy of the name. */ if ((api_copy = sip_api_malloc(strlen(api) + 1)) == NULL) return NULL; strcpy(api_copy, api); if (add_api(api_copy, version_nr) < 0) return NULL; } else if (avd->version_nr != version_nr) { PyErr_Format(PyExc_ValueError, "API '%s' has already been set to version %d", api, avd->version_nr); return NULL; } Py_INCREF(Py_None); return Py_None; } /* * Add a new API to the global list returning a negative value on error. */ static int add_api(const char *api, int version_nr) { apiVersionDef *avd; if ((avd = sip_api_malloc(sizeof (apiVersionDef))) == NULL) return -1; avd->api_name = api; avd->version_nr = version_nr; avd->next = api_versions; api_versions = avd; return 0; } /* * Return the definition for the given API, or NULL if there was none. */ static apiVersionDef *find_api(const char *api) { apiVersionDef *avd; for (avd = api_versions; avd != NULL; avd = avd->next) if (strcmp(avd->api_name, api) == 0) break; return avd; } /* * Return TRUE if a range defined by a range index is enabled. */ int sipIsRangeEnabled(sipExportedModuleDef *em, int range_index) { int *range = &em->em_versions[range_index * 3]; const char *api_name = sipNameFromPool(em, range[0]); return sip_api_is_api_enabled(api_name, range[1], range[2]); } sip-4.15.5/siplib/array.c0000644000076500000240000005012712261241066015231 0ustar philstaff00000000000000/* * This file implements the API for the array type. * * Copyright (c) 2014 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" #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 sipArray_slice, /* sq_slice */ sipArray_ass_item, /* sq_ass_item */ sipArray_ass_slice, /* sq_ass_slice */ #endif }; #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) #if PY_MAJOR_VERSION >= 3 view->format = array->format; #else view->format = (char *)array->format; #endif 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 */ 0, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved (Python v3), tp_compare (Python v2) */ 0, /* tp_repr */ 0, /* tp_as_number */ &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 */ }; /* * 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 = SIPLong_AsLong(value); data = &static_data.s_char_t; break; case 'B': static_data.u_char_t = sip_api_long_as_unsigned_long(value); data = &static_data.u_char_t; break; case 'h': static_data.s_short_t = SIPLong_AsLong(value); data = &static_data.s_short_t; break; case 'H': static_data.u_short_t = sip_api_long_as_unsigned_long(value); data = &static_data.u_short_t; break; case 'i': static_data.s_int_t = SIPLong_AsLong(value); data = &static_data.s_int_t; break; case 'I': static_data.u_int_t = sip_api_long_as_unsigned_long(value); data = &static_data.u_int_t; break; case 'f': static_data.float_t = 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.15.5/siplib/array.h0000644000076500000240000000213712261241072015231 0ustar philstaff00000000000000/* * This file defines the API for the array type. * * Copyright (c) 2014 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 "sip.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.15.5/siplib/bool.cpp0000644000076500000240000000151212261241075015400 0ustar philstaff00000000000000// This contains all the C++ code that is needed by the sip module. // // Copyright (c) 2014 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.15.5/siplib/descriptors.c0000644000076500000240000002762012261241102016445 0ustar philstaff00000000000000/* * The implementation of the different descriptors. * * Copyright (c) 2014 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 "sip.h" #include "sipint.h" /***************************************************************************** * A method descriptor. We don't use the similar Python descriptor because it * doesn't support a method having static and non-static overloads, 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 */ }; /* * 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; 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 */ }; /* 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.15.5/siplib/libsip.a0000644000076500000240000044625012274666060015412 0ustar philstaff00000000000000! #1/20 1391684661 501 20 100644 1500 ` __.SYMDEF SORTED (- y']r`````& 4 :IC  Z ?o m(-(-  (  >E  Sf(_PyInit_sip_sipGetGeneratedClassType_sipQtSupport_sipSaveMethod_sipSimpleWrapper_Type_sip_api_common_dtor_sip_api_convert_from_type_sip_api_force_convert_to_type_sip_api_free_sip_api_get_address_sip_api_get_cpp_ptr_sip_api_long_as_unsigned_long_sip_api_malloc_sipGetAPI_sipInitAPI_sipIsRangeEnabled_sipSetAPI_sip_api_is_api_enabled_sipMethodDescr_Copy_sipMethodDescr_New_sipMethodDescr_Type_sipVariableDescr_Copy_sipVariableDescr_New_sipVariableDescr_Type_sipGetRx_sip_api_connect_rx_sip_api_convert_rx_sip_api_disconnect_rx_sip_api_free_sipslot_sip_api_invoke_slot_sip_api_same_slot_sip_api_save_slot_sipGetPending_sipIsPending_sipWrapInstance_sip_api_end_thread_sipOMAddObject_sipOMFinalise_sipOMFindObject_sipOMInit_sipOMRemoveObject_sipVoidPtr_Type_sip_api_convert_from_const_void_ptr_sip_api_convert_from_const_void_ptr_and_size_sip_api_convert_from_void_ptr_sip_api_convert_from_void_ptr_and_size_sip_api_convert_to_void_ptr_sipArray_Type_sip_api_convert_to_array_sip_api_convert_to_typed_array_sipSetBool` #1/12 1391684655 501 20 100644 107660 ` siplib.o    __text__TEXT'P__common__DATA __data__DATA0( к6C__cstring__TEXTX__bss__DATA __const__DATA X8i__const__TEXT __compact_unwind__LD8`;__eh_frame__TEXTx8 hA8oD5 P$$<UHAWAVATSL=L=H=E1jHHSH@HH HHHHH=H=H=L=H=H=H=H=IMLIH5LHH5LHH=2H)H=H5E11HHH5LHAH u HCHP0EH=uH=HHE11HHHHt!H5LHH u HCHP0H=HHt!H5LHH u HCHP0H5HLH5HLH5HLH5HLH=u3H=H=HH@HH=11IMt{H=HHtXH5HIMt2LL10HtHu HHHQ0Iu IGLP0H u HCHP0Iu IFLP0ME1I $u ID$LP0L[A\A^A_]UHAWAVSHHHHMLLMHH0E1HELxE1H]I9Lt,HLLuLHtZHEH0H}Ht3HMH0Hq HMDA HAA H1ILH[A^A_]HH8H5E1UHAWAVSPHHHMHH01ۅHuHFL01F tE1 HFHtHIHuL~LxWH}HGH H9tH5HH}tHEP P W LLHHHH[A^A_]UHAVSHHHHMHH01Hu1HEH0H=0H}HGHt HGH=H0HE@ L5HHIEH=0H=HE@ IEH0HH]H{H9tH5tDH]HshH=HsXH=H=Hs`H=HsPHHH[A^]UHSHHHHMLEHH01ۅtYHEH0Gu,H0t"ux2HHEHHPHH8H50HH[]UHHHHHMHH01t2H}HGHt HHOHHHDHH]UHHHHHMHH01t HEH HHEHH]UHHHHHMHH01t!HEH HHEHH]UHSPHHHMHH01teH]H{HH9tH5H]tHH]c HCHtH߾HCHCHHH[]UHHHHH0t HH1]UHHHHUHH0tEHH1H]UHHHHHMHH0tH}HH1H]UHAVSHHL5HMLEHHL01ۅtIHuH;5tH~L9t H5t/Hu HE1H}HHHH[A^]HH8HEH@HPH50UHHHHUH LEHH0tHEH0H}11H]UHSPHHHMHH01ۅtH}11Ht HHHH[]UHAWAVAUATSHHHUHMLLMHH01ۅttH}HtfDh8E~>L`@1L}M4MtAFGuIFIc~(Hx Lt=HD9|1L}HH8H5L0HH[A\A]A^A_]I~ HuHUHAWAVAUATSHHHUHMLEHH01ۅtyH}HtkDh8E~CL`@1L}M4Mt$AFGuIFIc~(Hx Lt=HD9|1L}HH8H5L0HH[A\A]A^A_]I~ Hu10HUHSPHHtHH HHH1ɉH[]UHSPHHHHt7HHtHHGHHHuHHHHHH=HH[]UHSPHHuHH[]UH]UH]UHAWAVATSH IM7HH'AH}HuHUEH}HuLL1HHtTH1H10IH u HCHP0MtI $u ID$LP0Ht}HUHuH}H=LIGHtLIGIGAG t%AG Iu4IGLP0(IHH9tH5tLDH [A\A^A_]UHHGhHtDH9xPuHOXHHPHGXHtHO`HH`HG`HtHOXHHXHGhWGXHt]HG]`0UHHGHt]HG]UHAWAVSPIIIGHtLHI_HLxXMtUIGH0H Ht HLHHu.IFIcN(HH HH8IGHPH501HH[A^A_]UH1Hu@#N HHHEH H9HNHQH0]UHAWAVAUATSPLMMAIHIA9LHDt&LHLDMLMH[A\A]A^A_]HH8IFHPCuHCHcKHH H50$LcC(HCHcH H@ HIH50MtAHE1H[A\A]A^A_]UHNH;=tt$H111] u7-H(HttHv HH9t ]UHAWAVAUATSPMMIHHHEE1A}PH;u t]tHuHLLAkL(MttCHHHEHt%MtAHL;%t0L+HE!AEHuHLLAMtE>HEH[A\A]A^A_]UHAWAVAUATSPIIILmMtCHH[HtL9;uLSILmLHtLLIL=IAGtHuLILmH=LLIMtI$&Iw HE1L1A@IMt#MtLL;5t LMLH[A\A]A^A_]UHGu H'HO H1HHt H9 HRuH0]UHAWAVAUATSH(HuE1H>HHH}H_ HELMt{I<$ttIID$Lh HLtLHEHH0H Ht It$HHEH}AT$IMtMw HLtI<$Md$uHEHHe#HEHMHLLL*L}LH([A\A]A^A_]IUHHHH=HH]UHSPHHtLH{HH9tH5t,C t%C H uHCHP0HK H[]UHAWAVSPIHHH{L=L9tH5Mt4L;5t9I~L9tH5C tS%]C t*%4C uoHH{#C C RHHC C H u9BHHC C IFPHt HCXIFPHX`I^PLshH;t H[A^A_]HCHH[A^A_]`0UHHFHHFHG]UHHNҁt HI(HRHLHI@H]UHSPHHHHH[]`0UHAWAVATSIIIAD$ ID$H0ID$Ht LID$HtxHuSHHtGLC1ځLt IP(H[HTHR@HHu HtHHtHLLхuRI|$8Ht LAׅu>I|$(Ht LAׅu*I|$0Ht LAׅuI|$@Ht LAׅu1[A\A^A_]UHAWAVSPIE1AG IGH0IGHt LIGHtqHuSHHtGLC1ځLt IP(H[HTHR@HHu HtHHtHAI8IG8Ht HuHGP0I(IG(Ht HuHGP0I0IG0Ht HuHGP0I@IG@Ht HuHGP0DH[A^A_]UHAWAVAUATSHXHUHIMoI0HEHEH}HuHUHEHtHMHaHEHEHMLELMLHHUHEHEHUHMHQ1H; HAPHt IGXHAPLx`LyPIOhIHEIGẺAO tH IOH IOH}HtMI8L}LeAIH}HGMmMLHHUHMMMAUHEHt1MIG ALeuH=LID$xtlLHt_HEHUH;U@HHu1@HEHuLЅHEHtH}HHHu HGP0HEHEH=tLH}tELt9HUHuLH}HHHuHGP0PHEAD$tLH5LH;t4HUH5LHAH}HHH}HHtkH8U1HUHHt 19HIHEAHBHcR(HP 1ʀUIHE1HtqHtQHEH}HuHUHMHH8HUH50H}HHHu"HGP0H}HHHuHGP0E1DHX[A\A]A^A_]UHAVSIHI9t HI9u#IVHH8H501[A^]I0HxCu)HcK(HCHcP H@ HHHH8H5,u3HcK(HCHcP H@ HHHH8H50z0u'Ht=CtI0L9p u HPtLHH8H5L1[A^]HcK(HCHcP H@ HHHH8H5vHcK(HCHcP H@ HHHH8H5JUHSPH_ HHHHt#H9H@u1tKH9HGH7u1HHtHHHAH H[]UHHHH]UHAWAVAUATSPIM#Mw A@t MoMoMAGu Iw(LL-LHs(HLH8HuHH[Ht*H3Ht LtLLSxpAdž@LAEuRIHtFIOҁt HI(HRHLHI@HHu!H}LBHEDhE9|HEȃxHELh I E1IcEIcMHy H$HUHRHR@H Hy H50IMIuH}LAIu IGLP0EIAHED;py1HEȃx(|HELx0EA?u?IIƻMMIIE1Mu)L}1E1E1LHuHUII LIMu HM1MMHy(HMHuHHHHHu1 H=LLLIE10IIu IFLP0MtI $u ID$LP0MtIu IGLP0HuL}H L}u HCHP0MtCIwH}LAIMu IELP0ExI0MM1HE;H(H8[A\A]A^A_]UHAWAVATSIILHAHt!I4$LHAH u HCHP0D[A\A^A_]UHHt 11]HH]UHH~ H50]UHHH1HH]UHu1]]gUHtu HGH 1uHG]UHAWAVSPHHHuYHHtKLwD;ADɁLt IV(H IHTHJ@H1HH!HMAL}LHHA@HtHLiMXMH}ILIMHAH0II8L}Ht6LHHt&HtI $-ID$LP0I~~wE1OlIHtLHHt HCH;u I1M;~|;H;u2I $u ID$LP0HEЋ8HH([A\A]A^A_]1I $u ID$LP0HLut1VH{t HGHH{H([A\A]A^A_]UHAWAVAUATSHIIIt/)0)@)P)`)p)m)u)}L(L HL-IEHEHHEHEHEE0ELHHHt&HUHLHtLH1IMtAE1HtH u HCHP0IEH;EuLH[A\A]A^A_]UHAWAVAUATSHHIL}ILeHN)1>(D}HEHM9 1z HEH HcHIcH(wKIGHȃAHIcH(wGIGHȃADIcOHIGHȃAOIGHHIOHc8IGHHIO8IcH(IGHȃAIcH)IWHAH<(IW@AHcHIcH)IWHAH<(IW@AHcHIcH)IWHAH<(IW@AHcHIcH)IWHA(xHcIOArIcH)qIWHA(iHcIOAcIcH)pIWAAH< (hHcIGAbIcH)fIWHAH<( IW@AHcHIcH(AIGHȃA;IcH(6IGHȃA0IcH(.IGHȃA(IcH((IGHȃA"IcH(-IGHȃA'IcH('IGHȃA!IcH)$IWAAH< (HcIGAIcH(IGHȃAIcH(IGHȃAIcH(IGHȃA IcH( IGHȃAIcH)IWHAHHU(IW@AHcHIcH(IGHȃAIcH(IGHȃAIcH(IGHȃAIcH)IWHAH4(HcIOAIGHHIOIGHHIOH8HIOHQIWH9IOHQIWH9IOHQIWH9IGHHIOIOHAIGHH0IGHHIOIOHAIGHHx H50%IGHHIOH8IGHHIOHH0IOHQIWH9IGHHIOL0IGHHIOL0IIGHHIOH8IGHHIOEH}־}IGHHIOHc8dIGHHIOEH}׾'IGHHIOH8IGHHIOHH0IGHHIOH8IGHHIOH8IGHHIOH8IGHHIOH8IOHQIWH HMIGHHIOH8Htu}IGHHIOEH}о"IGHHIOHHt;HHH5IGHHIOH0IOHAIGH9HuL5I1IOHQIWH (wIWpA7HcH IGHPIWH0IOHQIWH (wIWpA7HcH IGHPIWH04IOHQIWH1(wIOPAHcH IGHHIOHLLI1MtwMt L;5u LL1LWHHKAGtHuLI1Mt L;5tLIw HH}HDAH[A\A]A^A_]UHFuHHuuHHt]]]UHSPHHHtH=H0HtHH0H1H=0 H[]UHAWAVAUATSHIMcO MO urGHH8T$4$H5 A0ADH[A\A]A^A_]LMMo(MI}HAHL5tM6MIc^ I^ IuHuANEMDyMuI}IHu)A9tHH8H5HLE0LL5MLet5Ic^ I^ HLI~0t I0M6MuLIGAHHIL=E1H=HHH8IUH50HH8H5L0AdHH8H5LH0A;UHHGH;uDHGHt;HHH; u.HWHt%H H9HH@HBHPH50]HH8H50]UHHHHH:H5HH0]UHAWAVSHHIt,)@)P)`)p)e)m)u)}L8L0H(H L=IHEHHEHEHEE0E;(u=H߾)HtLxuFH)غH1Ʌx$HcH1Ht@H1HuHUHHHH8H5H01Hu MtAIH;MuH[A^A_]UHHH?H!HxH9|HH8H50H]UHAVSIHH{HGH H9tH5HH{tIv H9t  [A^]UHt]]UHH;=H]UHAVSHHt))P)`)p)])e)m)u)}LHL@L5IHEH HEHEHEE0E LEHH1Ht yIH;Mu H[A^]UHSHt))P)`)p)])e)m)u)}LHL@H8H0HHHEH HEHEHEE0E=tHH8HUHH;Eu H[]UHSPHHt4H{HH9tH5tC t%C H tH[]HH[]HCHH[]`0UHAWAVSPIIHu*HtL8LpH HHH1ۉH[A^A_]UHAVSIH H1HtH;LHKuHC[A^]UHAWAVSPIHL5H1Ht'HHcS8Hs@LMHtHH[A^A_]UHSPHH{HH9t4H5u$H{HH9tH51tH0H[]UHGuHcO,1HxEHGH@@H7W,1u*HOҁt HI(HRHLHI@H]UHAWAVATSIE1HHt7L=HcS`H~HshLMHu HHuLpL[A\A^A_]UHAVSIHHtHK HLpH HHH1ɉ[A^]UHAVSHFHPwH=0HAHt'HH8HAH u HCHP0D[A^]UH=]UHH1HtQuHA ]UHHt Ht1]UHH1Ht AuHA ]UHH}HcH}LHt H@H1H]UHHcLHt H@H1]UHHHH H; uHxH HHHHt]HG]`0UHHHO H; uHH;=tH]1]UHAWAVAUATSH(HuIL}EA8k1IG@L$MKI|$?AD$@u$u&A|$(xLLHU M|$u"H]A4$x~LurI\$,A|$(M|$AL$,ɁLt IW(H IHTHJ@HH8HHHH8uL!IO@HyM|$IcD$,HLux IO@HHPҁLt Iw(HRHtHV@H HHH8H@uAPM~oM}XI E1L5IcIM@HHx AWL0HHIwH}HH u HCHP0IAE;eP|LmAE8M~<1IO@H4Ht&FGu HF HH`AG8H9|IH}iMMIH=uH=HH3H=uH=HH H=uH=HHH=uH=HHH=uH=HHMIMI<$HAHH0H5LHAH u HCHP0EI|$Ht>HHH5LHAH u HCHP0EI|$Ht>HHH5LHAH u HCHP0EsI|$Ht>HHXH5LHAH u HCHP0E+LHHIu IFLP0H5H}HAH Mu HCHP0EEHHHEL9HEH@HH HEЋHHxyMHELhMtHEȋX8~HELp@E1OHt HuHGP0t.I4I>Ht HuHGP0HIH1 HIH1I $u ID$LP0HHH;EuH[A\A]A^A_]UHHHHH:H5HH0]UHHH H9H5H0]UH1]UHSPHHtEH5HHt1HHt$HHHtH1HtHtH[]HHHH[]a0UHSPHHuH=HH H9HH[]UHAWAVSPHIAIw HH1AHI HHtH u HCHP0DH[A^A_]UHAWAVATSIIIHH{HH9tH5tHHLLLE1[A\A^A_]UHwt uHHFu,HHHNHIHWHRH5H0]u HHHNHHLAHOHIH5H0]UHAWAVAUATSHLEIHAH}L-MmMtvL;mtMMtI>tIE9fuHHt*AFH%(H IHLHI@H9uLHuAVH;uI>MvuHHH[A\A]A^A_]UHAWAVATSIAG IGL0IGHtLIMwMthHHHtWC819}HS@L9$HIu Ht1L0IL$IcT$(HQ HPAO HHHHH[A\A^A_]UHSPHHux]"HH8HCHPH500H[]UHSPHHuxHE"HH8HCHPH501H[]UHHHuxEE0H]UHAVSHIIH;t%HHUHHIHtH]+HC1uHPHH8H50HH[A^]UHHHuxEE0H]UHAVSHIIH;t%HHUHHIHtH]+HC1uHPHH8H50HH[A^]UHHHuxEE0H]UHAVSHIIH;t%HHUHHIHtH]+HC1uHPHH8H50HH[A^]UHSPHHuxE"HH8HCHPH501H[]UHSPHHuxHE"HH8HCHPH501H[]UHSHxHHHHHUH}HtHt)HdI0$HdH Hd0HH8HuH H;MuHx[]UHAWAVATSIAHHtZLc(MuIMtLLc(IcHHt8MLD5LHLH uHCH[A\A^A_]`0MtI[A\A^A_]UHAWAVSHMƄt,)@)P)`)p)e)m)u)}L=IHEMt I$HtHuHH8H51WHHEHEHEE0E0HEH$MMuuI>1Ht HuHGP0IH;EuH[A^A_]UHSH8HtrH}HuHUH}Ht HuHGP0H}Ht HuHGP0E HuH}u6H}Ht HuHGP0H;Ht HuHGP0HHHH8[]UHAWAVAUATSHMHIIt/)0)@)P)`)p)m)u)}HHHEAMtUHHEHEHEE0E0ID$@HLtHLEHLLAIu IFLP0H u HCHP0E틝y!MtID$@HtILAHHH;EuDH[A\A]A^A_]UHHHtHN@HtHH]]UHAWAVAUATSH8IHUHuIM~ ID$H0Lh H=u!H=HHYLLH]t$LLLHuHH"HEHEHH5LHHHHLc@I$IFIc~Hx IMLLHAH u HCHP0EoHEIHuHUHMLmID$HHuH}HGH51ҹAH}H5H}uH5HEuH"L HLHEHIL$HHuHH}HHHuHGP0xaIHuHULIu IFLP0H]LLLHuHH"H uHCH Iu IFLP0H}Ht HuHGP0H8[A\A]A^A_]UHAVSHFHcvHp HE1Ht+HCHtH߾ILsH u HCHP0L[A^]UHAWAVAUATSHMIHHIt/)0)@)P)`)p)m)u)}L(HHHEHHEHEHEE0E(LHHE1HtXHUHLE1Ht2MDELHHHIMtM}H u HCHP0HHH;EuLH[A\A]A^A_]UHAVSIHHtHLpH HHH1ɉ[A^]UHAWAVAUATSHHMIHUHuH}Au1IH(HHIG HC IGHCIGHCIIOHKHHH1IMt:IGI>LI $HI $x"Hu4ID$L[A\A^A_]`0HHu ID$LP0A[A\A^A_]UHSP1HH{Ht HuHGP0HH[]UHAWAVAUATSHxMLEHHHHEHIHtH@E1FIHMLuA}1uIHCtHHHHXHLmIFHEIINHMHEHEHD$Ll$HEH$HuHULHMLELmME1IFHEIINHMHEuH}HEH$HHMMLMAI?Ht HuHGP0Et/I6I?Ht HuHGP0HIHE1HIHE1H u HCHP0HHH;EuDHx[A\A]A^A_]UHAWAVAUATSHLxMH0H`IHEHEHAHX1H]MtLHH} IH`LkBt!CuHcH(wVHGHȃTpuWHcH)s&HOPH H (wFHw@HcHCHOHQHWH H #HGHHHOHI;1LI6HWHrHwL:(wHGHpI1LLpMHxDž<ʈ'E1L(DžHELuIDHDLL@AE<|uAEIDž<IńLPD舅;EHEIcH;X}H0LtAGEME1'uADH`+HcHxHHt"HpHIH]IH(AD$HMtMAGLAAYYH 'JcHH} LP)sdA(wa]<tfHcH(HGHȃ)A(HGHG(wHGM H=+LHcH(HGHȃHcH(HGHȃHcH(HGHȃ)H(ZHcH)HOPH4(HcH(HGHȃHcH(HGHȃHcH(HGHȃHcAMIŃH)HwPH4( @ HcH)HWAH4 (HcHGHcH(HGHȃHcH(HGHȃHcH)HWAH4 (HcHG( HcH(HGHȃHcH( HGHȃHcH)?HWAH4 (8HcHG3HcH)JHGJH(CHcHO>HcAMIŃEy(% HOH (rmHcH(WHGHȃRHcH(yHGHȃtHcH(HGHȃ{HcH(HGHȃHcH(HGHȃHcH)HWAH4 (HcHGHcH(HGHȃHcH(HGHȃHcH(HGHȃHcH(HGHȃHcH)HWHHHh(@HcH(HGHȃHcH(HGHȃHcH(HGHȃHcH(HGHȃHcH(5HGHȃ0HcH(9HGHȃ4HcH)HHWHH4(AHcHO<HGHHHOMJL8L[HGHG(wHGML HGHHHOMINHHcH9YHHGHHHOMHL;5INHHH9HGHHHOMtHL0DHDLZHGHGIMDLHGHHHOH0HGML HGHHHOMHiHGHHHOMINRHAN 299HGHHHOMHL;5LHWHrHwH2HGHHHOH0HGHHHOMEHLHGHHHOM L8L HGHHHOML8LHHgAHGHHHOH0HGHHHOMHL;5+HGIHGHHHOMHLHGHHHOMZINAN H9HHHaHGHHHOH0HGHHHOMHI~H9tsfdHGHHHOHHOHQHWMHHHINLuL;5{L3s(HwHHGHHHOMDL8LHHLHGHHHOMH0LHGHHHOMHLhHChHGHHHOMHLhHZhfHGHHHOMQL8L(HGHHHOH0HGHHHOMHLHGHHHOML8LBHGHHHOML8LHGHHHOML8LHGHHHOML8LHOHQHWH HhHGHHHOMIH0LHGHHHOM$L8LHHfAHGHHHOML8LHHSAHGHHHOML8LHHIHGHHHOMxH0L HGHHHOMVH0LCHGHHHOH0HOHAHGHL;5u H MLIHnL;HGy(kfHOHQHWH (idHG(wHGMtxLIE1MxFM9}`LLHHt.HHhAH u HCHP0IEuELuILPLP1;WL@}AN H9VHHBI L0HwHFHGMtwHHHcHIFH;L;5H]HGʃu (w20+HGM/Hq I~H9HGM L~I~H;=tH5XAFI~H;=tH5(AZFIFLtIcH;X}dEH0HxhIw H0HXH{H9t CIH`DžL1CH(H;Hu H}HEE1L}LmHpHuLLHEHHHxtZ11E~'HxH4Ht H}tHD9|ۉD9t%H`HcHXH)HcH9nsH}MuIHEL0MtHUHuL-EH@PEIGIcO(HH HMDžL;WUEH} DHH(H;HELuL}LeHpLLLHEHHtfHxt911E~'HxH4Ht H}tHD9|ۉD9uHEE.HpHHMH~wE EHEHEHHuH}uDH}Ht HuHGP0HH8Ht HuHGP0HHHH1H[A\A]A^A_]E{22222222222222222222222222222222A_}2%C2w32202222222`u2 ?]{23 'EcB6UHAWAVAUATSHL@HMHXLH}MaAH}BtH}Cu)HM(wECHcH(wCHGHȃApuoH}HcH(HGHȃHAHMHGHHHOHHMHHcH)s(HWHH4(w%HcHO#MHGHHHOH0HOHAHGH}HH}jHGHHHOHHMHHcH)s HWHH4(wHcHOHGHHHOH0HOHAHGH}HH}HEH LHXH@HPHpHE|MA$ W0 |u A\$IIMHcH;P}MHXLL9E1H}uM*ȉM+LHcH@H4Ht H}IÃxw_pH]jfM/`H  HcH(MyH]HcH)HSH H4(HS@HcHquiHcH)0HSH H4(xHS@HcHrk8(%HKHQHSH1rHcH)HSH L4(HS@HcH}gHcH)HSH H4(HS@HcHHKHQHSL9(wHKPHcH HCHHHKM5LEH}L1HKHQHSH1OHC8auHc H(oHCHȃ j(wH]H]HCHKHQHSL9(wHKPHcH HCHHHKMLIEH}LE1IHMHKHQHSL1HKHQHSH Hh(wHKPHcH HCHHHKMHH`ELLMIAFu(LmII&HKHQHSH1LmIILuHLILeE1M~{ILH}LIEMLHu1ҹE1LMII $u ID$LP0}Le[LLLAII9IL|HhL H`L8LeVHKHQHSL1(wHKPHcH HCHHHKMLH}L1AIE HCHHHKMeMH0AE8tLuLLA|uL|EVHc H)GHSAL< (@HcHC ;)gH (^HSHcHVHc EEIAH)XHCQH4(SH{I HcHMHc H(fHCHȃ aHcH)HSH H4(HS@HcH(HcH)HSH H4(HS@HcHHCɉMHCHHHKL8HCHHHKMeM L0AE8LLLHCHCHHHKMXHLFHCHPHSH0HSHBHCML2AfAHE^HCHHHKMeMXL0AEШ^YI PIBLLP0I;HKHQHSH1HKHQHSL1(HKPHcHHCMeA}E(HKPHcHHKHQHSH1HKHQHSL1(HKPHcHLLAHEuLLHHLHEEHHEI!HEHHIDEA(HCDID HcHIMHCHHHKMt[LIH}LDHCHHHKMHLHCHHHKMtLH}L1IMhAH{HGHCAHHpDAuA(wH{AAIcHE1HCHxH{LMELLLMIE}EHHpHLcHPL)HEHtcL;P}&HXJLHPH1HH2HHHuHuHcH(wHNHу HNHQHVH HEEHĨ[A\A]A^A_]f7UUHG t]HH8H51]UH1H;=tHOu ]UHAWAVAUATSPEIHHuIAEuI} H50QL5MvMtM9.uHAVHLHt H1Iu HH1EHAHt!LHuHAH u HCHP0DH[A\A]A^A_]UHAWAVSPHGH0HAHcY(HX LpL=H=LLHA0H[A^A_]UHAWAVSPHIH=uH=HAHtELHHAHt,H5HLHAH u HCHP0DH[A^A_]UHAWAVAUATSHIIIEIMwIMtwLHHtVL4$I(H LLMIHt"I $u ID$LP0H u;HCHP0/H u HCHP0I $u ID$LP0IGEEH[A\A]A^A_]UHAWAVAUATSHHHUIHEI}IMIHHME1BDMvtLHH6EMLmE1IC ɁH}Ht HW(H IHTHJ@HHHUAHC HLJDIE9|LmHIcHx'Hy HMHH0 HMHHrIcHxHEHx Hu @HCH@HEH}H"HEH]AEMtaEl$0E~WI\$8E1L5I6Ht4H;IuLuLHMLDh0IH AE9|HEH$MI}(LHUHMLELuMHHtjIHtHI@tH5Hx*H}HuHGP0IuUIFLP0ILmL"H u HCHP0Iu IFLP0H]H u HCHP0IEEEHH[A\A]A^A_]UHAWAVAUATSPHuIHHt2AH3Ht$DCHSHCHLH yHELpMtOAI>tCI~HHI6LHAH u HCHP0IEyHELhMIAI}tuAEL8tLu1Au 1HH!IuLHAH u HCHP0IEyHELhMIAI}AE8t Lu&I]HHH14I})AuI]HHH1 I}HHbIuLHAH u HCHP0IE]/HELh MtQAI}tDIc}HHIuLHAH u HCHP0IEyHELh(MtQAI}tDI}HHIuLHAH u HCHP0IEysHELh0MtQAI}tDI}HHDIuLHAH u HCHP0IEyHELh8MtQAI}tDI}HHIuLHAH u HCHP0IEyHELh@MtNAI}tAI}HHIuLHAH u HCHP0IEy\HELhHMtLAI}t?AEHHt/IuLHAH u HCHP0IEyE1DH[A\A]A^A_]UHHHu!H50H1HtHHH]UHAWAVSPIHHHtL;ILHuHH8H5L0E1LH[A^A_]UHAWAVSPIH=uH=HE1Ht;HE1Ht+IVH5HxIH u HCHP0LH[A^A_]UHAWAVAUATSHLMMHMHUIHKuDHUɁHt Hr(H IHtHN@HtCHFuHGhHt$H@@FuHG`Ht HǀH>Hvu]UHAWAVATSL%M$$Mt2AD$8~IL$@1H4HtFGu H^ H;_t7H9|HHHOHQH5H01[A\A^A_]HFL@Lcv(Lp 1HAHtHHt(IT$H5H=LI0[A\A^A_]IcT$ IT$ HH8H5L0qUHSPHHHKHHރu1x HC HH[]UHH6]UH9 19L]UHH6]UHHHtHPHcHHJ *LI@H1HcHxHIP@HH9uHH@7H@ tH t@*wDH@Ls1t@8tŹL]UHSPH0H1Ht4HH0HHX HHp0HtHHH[]UHHHbHH\VH5:HcHH HHxHH HH HHHHHHHHHH~HrHfHZHpNHBH6H*HHH HH(H0HH8HHXHhH`HHHPHyH HiHH HRHIH@HOX:HOx4H+H"HHHHHHH]*=IUamy !-9EQ]irUHAWAVSPIIH"HLLH[A^A_]UHAWAVSPIHHE1Ht'L#LHIH u HCHP0LH[A^A_]UHAWAVATSIHIM$IMt'Mt9HL0HAHt7HH8AHLHAAH u HCHP0D[A\A^A_]UHAWAVATSHIIH$IMtHt-H=LH0HH8A1LHAHtLHAAH u HCHP0D[A\A^A_]UHAVSIHw HcH %4HHt HL[A^]HH[A^]UHAVSLwI~HH9tH5I0HHtHHt9YHIuHHt\LB1ƉLt IP(H<HTHR@HHHtHHt 9_Hu1Ht1!I0HH0H1Ht 9YHIHu[A^]UHSPHHHHH[]`0UHAWAVAUATSPIIIHHttHxHtmIGHtLHI_HtLHEL-HHHuPHHt'H H9H uHxL9t LAԅu,H}uI_PH[XHtL9tHLAԅu1H[A\A]A^A_]UHAWAVATSHIAH=t_AG!tXIGHtLHI_Ht7HELeHHLPHHtHH}uIPHuDH[A\A^A_]UHAVSIHH0xHHHL[A^]1[A^]UHAWAVSPIIHH0x#HHHLLH[A^A_]H[A^A_]UHAWAVSPHH(AxRH0Ht HX E1=LE1Mt.IHH9tH5tI0H0DH[A^A_]UHAVSH0H1HHHH0L5AFuzIHt HH8HEHHItHHItHHIHtHIPHtH(H[A^]UHAWAVATSAIHC uHHCL0HCHt H߾HCHtM$HHLD[A\A^A_]A[A\A^A_]UHAWAVSPIHC uEHCL0HCHt H߾HCHtIHHLH[A^A_]H[A^A_]PD88pDHcastdeletedumpenableautoconversiongetapiisdeletedispycreatedispyownedsetapisetdeletedsetdestroyonexitsettracemasktransferbacktransfertowrapinstanceunwrapinstance_unpickle_type_unpickle_enumsipsip._C_API_C_API__init__SIP_VERSION4.15.5-snapshot-e6e10c9f08b5SIP_VERSION_STRwrappertypesimplewrapperwrappervoidptrcould not convert '%s' to '%s'%s cannot be converted to a C/C++ %s in this context%s cannot be converted to %s.%s in this contextsip.simplewrapperO!i:enableautoconversion%s is not a wrapped class that supports optional auto-conversion_sip_exitatexitregisterthe %s type cannot be instantiated or sub-classed%s.%s represents a mapped type and cannot be instantiated%s.%s represents a C++ namespace and cannot be instantiated%s.%s cannot be instantiated or sub-classed%s.%s represents a C++ abstract class and cannot be instantiated(i)__getattribute____getattr____enter____exit__'%S' is an unknown keyword argument.%s%s%s() is a private method%U: %U%s%s%s(): %Uarguments did not match any overloaded call:%s%s%s(): %s %U: %U overload %zd: %Ufirst argument of unbound method must have type '%s'not enough argumentstoo many arguments%S keyword argument name is not a string'%U' is not a valid keyword argument'%U' has already been given as a positional argumentargument '%s' has unexpected type '%s'unknown reasonargument %d has unexpected type '%s'__dict____dict__ must be set to a dictionary, not a '%s'wrapped C/C++ object of type %s has been deletedsuper-class __init__() of type %s was never calledUsO:_unpickle_enumunable to find to find enum: %sunable to find to find module: %UUsO!:_unpickle_typeunable to find to find type: %s__dtor__buildObject(): invalid format character '%c'%s.%s() is abstract and must be overriddeni:setdestroyonexitKO!:wrapinstanceO!:unwrapinstanceO!:setdeletedO!:ispyownedO!:ispycreatedO!:isdeletedO!:deleteO!O!:castargument 1 of cast() must be an instance of a sub or super-type of argument 2O!:transferbackO!O:transfertotransferto() argument 2 must be sip.wrapper, not %sO!:dump Reference count: %ld Address of wrapped object: %p Created by: %s PythonC/C++ To be destroyed by: %s Parent wrapperNext sibling wrapperPrevious sibling wrapperFirst child wrapper %s: NULLI:settracemask__sipParseResult(): invalid format string "%s"aAHDCsipParseResult(): invalid format character '%c'bytes or UTF-8 string of length 1 expectedbytes or Latin-1 string of length 1 expectedbytes or ASCII string of length 1 expectedkeyword arguments are not supportedno access to protected functions or signals for objects not created from Python%s() is deprecated%s constructor is deprecated%s.%s() is deprecatedstring expected, not %sstring of length 1 expected, not %sbytes or UTF-8 string expected not '%s'bytes or Latin-1 string expected not '%s'bytes or ASCII string expected not '%s'bytes expected not '%s'bytes of length 1 expected not '%s'cannot concatenate '%s' and '%s' objects**=unknownunsupported operand type(s) for %s: '%s' and '%s'builtinscannot convert Python object to an instance of %s%s.%s() is abstract and cannot be called as an unbound method_pickle_enum__license__LicenseeTypeTimestampSignature_pickle_type%%PickleCode for type %s.%s did not return a tupleO(OsN)attempt to pickle unknown type '%s'__module__%s is not a registered type__reduce__O(Osi)sequence index out of rangesipBuildResult(): invalid format string "%s"attempt to assign sequence of size %zd to slice of size %zdinvalid argument to sipBadCatcherResult()invalid result type from %s.%U()the sip module implements API v%d.0 to v%d.%d but the %s module requires API v%d.%dthe %s module failed to register with the sip modulethe %s module is version %d but the %s module requires version %dthe sip module has already registered a module called %sthe %s and %s modules both wrap the QObject classpyqt_kw_handlersip.enumtype(nO)sip.wrappersip.wrappertype&'()*+ aazQ!`gUVr 3> A H !y O R X X =  "   _ H[aaMXhXXA,XA^aa2)G f7aXn!NX X#T $7$R$j${$%$za%8R%8%Xn&}X()b!J*3}*n!*!+ ,0X8.XR// Xl:XW;:;[; X >nz>)>>a?9@a!{@@@!\ABgzBVaB7!CWa^C[CaD` zDG!D]!E *E$NEkEE9E*E5"F+MFX-NNXP)P#Q *QoQKQhaLRZ R4SXS TGTE>U)gUv!U)Vv!|V)Vv!WD_WEW8X XaY_Z3X[&[X^V!^1X`C!J`3Xq!nrXskssa!sa!5ta!tU!t9$uXuXa vS!]v @w3swX(yX X*ʝ(XĞUaaXyX8FX~<aa{aNXO3 4Fz  AXt2aUao  G!!Ӳ)XԳ p>!Vaa!Qp fazRx ,hAC G$LAC I$tAC F$bQAC G$AC E$gAC $7UAC $<dVAC $dAC B$3AC $AAC $'HAC $GAC G$,OAC $TRAC B,|"AC M,AC M$p=AC B$AC B$, "AC B$T AC $| AC ,_AC K$[AC $+AC $$AC F$LMAC ,tAC J$uhAC ,AC J,lAC J$,C AAC ,T\ AC M$A!AC $6!aAC B$o!AC F$_"AC $$L"2AC $LV")AC B,tW"AC G$F#7AC F,U$AC M$(nAC C$$d)AC B$L)AC ,t)NAC J,*AC M,t-TAC G$-AC $,-AC $T-AC $|r-AC $[-%AC $X-zAC F$-8AC $ -8AC ,D -AC J,t ~.}AC M$ 0AC $ 1bAC C$ 13AC B$ 1nAC C$D +2AC C,l 2AC G, 20AC M, 4AC P, 5/ AC M,, @AC J$\ A:AC $ A[AC B, A AC M$ CnAC $ C)AC $, C>AC L$T E9AC $| "EaAC C$ [EAC $ DEAC $ 7EAC J$ EAC H$D SFgAC B$l FVAC F$ F7AC C$ FWAC F$ F[AC B$ 1GaAC ,4jG`AC G$dGGAC C$G]AC C$G AC $G$AC $GAC $,GAC $TG9AC $|G*AC $G5AC $G+AC ,GAC M$$OAC H,LPAC P$|Q)AC $Q#AC $Q AC $QoAC B$RKAC B$D$RhAC F,ldRZAC G$RAC ,RAC M,SAC G$$TGAC B$L1TEAC B$tNT)AC $OTvAC G$T)AC $TvAC G$T)AC $<TvAC G$d;UDAC B$WUEAC B$tUAC E,UAC G$ 4VAC L$4WAC E,\W3AC P$X&AC ,XAC M$ [VAC C, N[1AC P$<O\CAC C,dj\3AC M$mAC G,6nAC J$nkAC E$naAC C$<oaAC C$dUoaAC C$oUAC G$o9AC E,oAC J$ *pXAC F$4ZpSAC C,\pAC G$8q3AC B,CqAC M,rAC P, AC P$D*AC $l(AC ,AC J$UAC F$AC F,AC M,DAC M,tHFAC J$^<AC $raAC F${AC F,NAC M$LOAC ,tCAC G$FAC B$2 AC $AC $ AC $DAC $lYXAC B$tAC $2AC F$UAC F, AC G,<LAC G$lGAC C$צAC C$)AC B,AC J,DAC K$D>AC C$lƨVAC F$AC F$PAC C,pAC G$1fAC F2G-WVĵ=d-_S=Դ=ɴ}-=}-S"-E-/((mn-|=f(_=#(o-==P-ݲm- -۱=ñM-gv-WW-O`=F-9N%M-ΰW-ư`=-M-CM-+v-M-LKJIͬHG-zoaJ=Ы--\-U-+R-!Ec=-Dƪ6-R-Cb=AVyM-bX-J;---lM-d@NK-A@:-5A+@mR-?a=-ʧ>->HN-1f-N-Ԧx-N-vu-3N-w-եN-t-wN-\t-N-@---Ϥ-Ĥ--VN-;A-4-&--N--v--=-;-4-- ١-<-:--r<-Ѡ- ;--՟:-t=m8XF-B8;-69,8m-7p-N--rYh-5g,-%-ӝMY-5a=6--_d-ܛ-p- ---ٙMp-h--- -L-d-s--x-ҒJ- -6-ώ=!---L-1M-K-Ō-|L--p--~g=ugMS-Ng=EgM-c--̊-M?Mc-҉--<T-4D-M--T--WT-Os-T-s--r-q-fs-Ap---p-T-e-gT-Ze-5--T-p-MC-E-u-MCT-;s-p-,-C-M-4-M"u-p-|C-|(m{J-zP-yO-$y-y=x=x=x-Ox-w-w=ow{-IwD-w{-vn-vE-v3v:-wvo-Av-2vP-u-uP-u{-{u-eu:-=uMu--t-tY-t2ytc=Qt/-Ct-'tY-"t1tc=s/-s-sY-s0sc=s/-s-Gs-r{-r-r:-rM_=^-0^w-^v-]L-]M-]-]-|]-w]=h]-c]=J]-8]%]H-\L-\-\-x\xn\-c\\\xB\w-0\v-\-\%[-[&[%m[U-[-k[=d[j-][U-[-Z=NZ=Z!-YQ-Y-lY-7YY-2Y(Yc=Y=XM-XMoXt-[XK-4X-XZ-X]=X-WWW-WW=WR-W~Wd=mW-RWR-KW9Wd=)W- WR-WVc=V -V-VMV-lVR-eV[Vc=3V -$V-VMU -UR-U Uc=U -U-{UMKU-1UR-*UUc=U-TR-TTc=T-oT:-DTVS=SP-SMSP-YSV0SR-%SSc=SRRR-RRc=RR-{R-vRjRHRj-"RX-R-RQi-Qj-QX-Q^=QQ-QQQi-tQ-eQJ-UQ-HQJ-@Q4Qk-&Q-QR-QQc=PR-PPc=P-P=P={P==P-O-{O-GO=N-N-N=M-MVLM-LWLG-LM-L[zL-PLM-ELZ2L-LM-KXK-KM-KYK-KK-sK[lK-gK]K[mMKZFK-AK7KZm'KY K-KKYmKXJ-JJXmJWJ-JJWmJ-J-'JN- J-I]I- I=H(H-H-HH-|HM-RHHH->H7HH-HG-G-GG-Gz=GmG-F-F-jF-=FM0FMF=EME-EE-EpE-SE-/E-$E?DX-Dc=D-DDDD:-WD-:D.DVC-CCC-zCnCGC-/CCCVB-BBBB:-B-fB"-9B-4B(BB-A-A=ABA=XA-/A-@=@M@#-^@-F@->@2@ @R-@?_=?-?R-??b=?-z?-f?-B?-?=>R->>d=v>R-n>d>c=]>R-U>?>c=->hM>~M=R-==a==R-==a==R-==a==m=t=-=q=h=V^=VD=-=-<V<R-<<a=<-<V~<m-=<R-&<<a=;-;-;;-;=;-;;{-D;--;;M ;i-:=:#-:M:h-:gA9R-:909b=8#-8-8-8-7.-7E-6=6-6-~6@-H6x-/6u-6w-5t-5A-5>-~5-Z5-4-4@4-4f-N/-/[-.-.-.-.=4.}-.j--U--R---`=-hM-~M_-j-?-M)-M-I-,C-,I-,}-,-G,i-5,+R-++b=+-+V+l-+? +m+-**-*R-**c=]*K-F*- *-)-))-))-})r)-j)N)A)6)-0)))-#))(D-(X-(c=z(-g(2(-(- ('-''-'-'-}'v'm'-h'R'R-B'8'c='-'&-&-&& &-%-%-% D%-1%=#%(mf$y-N$-D$.$='$B-#N-#-|#N-#-"="-"="-"-k"-Q"-!N-!-!!t-`!-J!-$! -R -7  --=tjijR:-={-jc=c===]-QR-J@c=~c=}-R-|c=+OR-Hz:c=3L-O-y-xnw-cV=MOv-G+tu-tm~s-c-[rq\M-7==0n-(m-"-m"-P"--M-"--sZ-N---QV jE-H-M-~-sei-J=.h-gE-H-Mv6-6M-MjR-cfDR-=ec= d-c-R-a=bzaMR-F`4c=!-7j-/"-#--V-j-U-T-c_-U^F]-<\)Q-i- s- {- S- |- V -  [ Zw Yl Xa WL {- V    :- - R- T b=m -, P- <- S - R- Q b= -] P-N <-= =. O y- 6- <- + M .- <-  Ks R-l IV c=@ =9 H- -  M <-  G = E- <-  Dn =g BZ <-I A1 =& <- ? >="--<-+{<eM[=?<-.+':M=<-+8M=<-r+k6RR-K4Ac=1M'=3-<-2=&-0&-/&-.&--l-gSL-/,(-!+* )-(-'&-<-+%e=^#-A"-4-,  !-<-+ Y-c=j-X56-- -<-+A-*-"m-B--(--mN-=N-N-~+wpN-haKN-@1-,N- t-- -  mN- yE-o h QmJCJ-;4-J-%---=-=--=-=-~wpeR:-@-8+&-!= \- U T8 S0 R v P QOpu`FtBs6rphmX{HpknoPl8j(lXi(R NLhJgFfCeh@`dH=@c(; ba9`7_5^]h1`\H$@[( ZYHq@p8o0n )('$#"   xph`XPH@80]( 6y,x3ph4`XPH@80U( 8HE:k2.xph0`dXcPH@_80( +`@ `@ `@ `@ `@ `@ `@ `@ `@     ` @       ` @       ` @       ` @       ` @   `@ `@ `@ `@ `@ `@ `@ `@ `@ @U8 k|    +6 = FR%o.7@IR b l vaHW;z ;$-6?HQZ"d7nPx?X`r  $o->> LrVh a o>x^ N]y    + -6? Y0 e@ rH P X `  ,8. Q6?H Xl,} A*fG !j$7{$M$` l%wR%%( n&[  8 HP^#ir$7$R$ ()?"S F(1:C1LVU^gpyJ*}*DR/l:d m;*4/> NXBoyq >[z>>?*4@Q{@g@z@J`\ABzB C  ^C@CTDmzDDE*ENEkE"E<PEmzE"FMF4  "-EPya8oy(-NswN(yPP%/QL^*Qq~{Qx DQLRR6?@JATL^4SuSTsTt>Uss2gURuoyUsV|V5tV1`;WUta<k_W$u$W8XX j Y& ]v3 _ZL [h [| p   ^ ^ `! !!nr&!q>!H! vc!?m!w!!@w!ʝ!!Ğ!! !!~!""&" E"O" d"n"3{"y"r"?"A"""o""###"#Ӳ6#ԳH#]#pv####Q##0 $X$]$d!$i)$~1$9$A$I$Q$Y$b$k$t$}$$$'$-$$$$$$$$$2%%% "% x,% 5% B% R% 8k% `y% % % % % (% P% x% % & "& 4& PQ& x^& Hs& & & @& & & ' ' H6' S' q' ' @' p' ' ' ( "( H0( xD( b( z( ( ( @( h( ( ( ) ) @8) hV) t) ) ) ) @) p) ) * * -* PL* xm* * * * * @* h+ (+ C+ ]+ w+ 0+ X+ + + , (, (H, Pd, x, , , , , @- h)- @- W- s- - @- h- - . ". ?. 8Y. hv. . . . . 8/ `6/ V/ x/ / / (/ P/ 0 0 70 V0 (m0 X0 0 0 0 0 01 `(1 D1 a1 |1 1 (1 P1 1 1 2 2 ((2 X72 F2 [2 t2 2 82 `2 2 2 2 2 @ 3 h3 43 B3 R3  c3 @ }3 h 3 3 3 3  3 0 3 X 4 4 34 H4  U4 0 l4 X 4 4 4 4  4 0 5 X !5 4  j# X [ p<Pz    p+  2 V    p  @ g  S C  0 AyA\  1{~" 4`  F #  w    1 D _1u \`h7 k c3 Q n   f$m.!     o r SBM ]En#8c U ) AM -cJMA   x  O '         }   ._PyInit_sip_PyEval_InitThreads_PyType_Type_PyType_Ready_sipSimpleWrapper_Type_sip_api_malloc_sipMethodDescr_Type_sipVariableDescr_Type_sipVoidPtr_Type_sipArray_Type_PyModule_Create2_PyModule_GetDict_PyDict_GetItemString_PyCapsule_New_PyDict_SetItemString_PyUnicode_FromString_PyTuple_New_PyLong_FromLong_Py_AtExit_sipOMInit_sipQtSupport_PyThreadState_Get_PyCFunction_NewEx_PyImport_ImportModule_PyObject_GetAttrString_PyObject_CallFunctionObjArgs_PyArg_ParseTuple_PyType_IsSubtype_sip_api_get_cpp_ptr_sipWrapInstance_PyExc_TypeError_PyErr_SetString__Py_NoneStruct_printf__Py_FalseStruct__Py_TrueStruct_PyErr_Format_sip_api_convert_from_type_PyLong_FromVoidPtr_PyTuple_Type_strcmp_PyExc_SystemError_PyObject_CallObject_PyMem_Free_sipOMFinalise_PyMem_Malloc_PyErr_NoMemory_sip_api_free_sip_api_long_as_unsigned_long_PyLong_AsUnsignedLongMask_sip_api_common_dtor_PyGILState_Ensure_PyErr_Fetch_PyErr_Occurred_PyErr_Print_PyGILState_Release_PyErr_Restore_sipOMRemoveObject_sip_api_get_address_PyExc_RuntimeError_sip_api_force_convert_to_type_sipOMFindObject_sipSaveMethod_sipGetGeneratedClassType_PyBaseObject_Type_sipGetPending_sipOMAddObject_PyDict_Size_PyDict_Next_sipIsPending_PyType_Modified_PyObject_CallFunction_sipVariableDescr_New_PyProperty_Type_sipMethodDescr_New_sipQObjectType_PyObject_GetAttr_PyObject_Call_PyUnicode_FromFormat_PyUnicode_AppendAndDel_PyErr_SetObject_PyCapsule_GetPointer_strchr_PyUnicode_FromStringAndSize_PyDict_New_PyObject_GC_UnTrack_PyImport_Import_PyUnicode_Compare_PyDict_GetItem_PyCallable_Check_PyWrapperDescr_Type_PyMethod_Type_PyFunction_Type_PyExc_NotImplementedError_PyMethod_New___stack_chk_guard_strlen_PyEval_CallObjectWithKeywords___stack_chk_fail_PyFloat_FromDouble_sip_api_convert_from_void_ptr_PyBool_FromLong_PyBytes_FromStringAndSize_PyLong_FromUnsignedLong_PyLong_FromLongLong_PyLong_FromUnsignedLongLong_PyBytes_FromString_wcslen_PyUnicode_FromWideChar___stdoutp_PyObject_Print_putchar_PyExc_ValueError_PyExc_IndexError___stderrp_vfprintf_bsearch_sipInitAPI_sipIsRangeEnabled_PyLong_Type_PyTuple_Pack_PyDict_SetItem_PyDictProxy_New_PyImport_GetModuleDict_PyExc_Exception_PyErr_Clear__Py_NotImplementedStruct_PyUnicode_AsASCIIString_PyUnicode_AsLatin1String_PyUnicode_AsUTF8String_PyOS_snprintf_PyExc_DeprecationWarning_PyErr_WarnEx_PyObject_SetAttr_PyDict_Contains_PyUnicode_Tailmatch_PyObject_IsInstance_sipMethodDescr_Copy_sipVariableDescr_Copy_sip_api_convert_to_void_ptr_PyLong_AsLong_sipSetBool_PyFloat_AsDouble_PyLong_AsLongLong_PyLong_AsUnsignedLongLongMask_memchr_PyObject_AsCharBuffer_PyUnicode_AsWideChar_PyList_New_PyList_Append_PySequence_Size_PySequence_GetItem_PyBool_Type_PyFloat_Type_PyUnicode_CompareWithASCIIString_sip_api_convert_rx_sipGetRx_PyObject_CheckReadBuffer_Py_BuildValue_PyDescr_NewMethod_PyUnicode_DecodeLatin1_PyUnicode_DecodeASCII_PyLong_FromSsize_t_PyErr_SetNone_sipGetAPI_sipSetAPI_sip_api_connect_rx_sip_api_disconnect_rx_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_is_api_enabled_sip_api_free_sipslot_sip_api_same_slot_sip_api_invoke_slot_sip_api_save_slot_sip_api_end_thread_sip_api_convert_to_typed_array_sip_api_convert_to_array_PyInit_sip.eh_sip_api_malloc.eh_sip_api_free.eh_sip_api_long_as_unsigned_long.eh_sip_api_common_dtor.eh_sip_api_get_address.eh_sip_api_get_cpp_ptr.eh_sip_api_force_convert_to_type.eh_sip_api_convert_from_type.eh_sipSaveMethod.eh_sipGetGeneratedClassType.eh_sipWrapperType_Type_sipRegisteredPyTypes_sipWrapper_Type_sipEnumType_Type_PyInit_sip.module_defL_.str16_type_unpicklerL_.str17_enum_unpickler_sip_apiL_.str19L_.str20_init_nameL_.str21_empty_tupleL_.str22L_.str23L_.str24L_.str25L_.str26L_.str27L_.str28_sipInterpreter_finalise_cppPyMap_register_exit_notifier.mdL_.str36L_.str37_castL_.str87L_.str88_callDtorL_.str86_checkPointer_removeFromParent_release_dumpWrapperL_.str92_print_objectL_.str93L_.str94L_.str96L_.str97L_.str95L_.str98L_.str99L_.str100L_.str101L_.str102_enableAutoconversionL_.str33_sip_api_enable_autoconversionL_.str34_isDeletedL_.str85_isPyCreatedL_.str84_isPyOwnedL_.str83_setDeletedL_.str82_setDestroyOnExitL_.str79_destroy_on_exit_setTraceMaskL_.str106_traceMask_transferBackL_.str89_sip_api_transfer_back_transferToL_.str90_sip_api_transfer_toL_.str91_wrapInstanceL_.str80_unwrapInstanceL_.str81_unpickle_typeL_.str73_getModuleL_.str74_unpickle_enumL_.str70L_.str71_sip_api_register_py_type_moduleList_licenseName_licenseeName_typeName_timestampName_signatureNameL_.str75_sip_api_is_py_methodL_.str76_sip_api_call_methodL_.str29L_.str68L_.str69_sip_api_can_convert_to_type_sip_api_convert_to_typeL_.str30L_.str31_proxyResolvers_get_from_convertor_convertSubClass_sipDisabledAutoconversions_sip_api_get_pyobject_sipSimpleWrapper_dealloc_forgetObject_sipSimpleWrapper_clear_sipSimpleWrapper_traverse_sipSimpleWrapper_init_explicit_access_func_indirect_access_func_find_finalisation_kw_handler_isQObject_next_in_mro_super_init_unused_backdoor_sip_api_no_methodL_.str48_sipSimpleWrapper_newL_.str38_add_all_lazy_attrsL_.str40L_.str39L_.str41L_.str42_sip_exit_add_lazy_container_attrs_sipAttrGetters_isNonlazyMethod.lazy_addMethodL_.str43_create_function_sip_api_convert_from_enum_sip_api_no_functionL_.str49_detail_FromFailure_signature_FromDocstringL_.str51L_.str50L_.str53L_.str54L_.str55L_.str56L_.str52L_.str57L_.str58L_.str59L_.str61L_.str62L_.str65L_.str60L_.str64L_.str63_sipSimpleWrapper_get_dict_sipSimpleWrapper_set_dictL_.str67L_.str72L_.str78_buildObject_sip_api_convert_from_new_typeL_.str77L_.str103L_.str104_sip_api_export_moduleL_.str153L_.str155_got_kw_handlerL_.str158_sip_api_import_symbolL_.str154L_.str156L_.str157_sip_api_bad_catcher_resultL_.str152L_.str151_sip_api_bad_length_for_sliceL_.str150_sip_api_build_resultL_.str149_sip_api_convert_from_sequence_indexL_.str148_sip_api_can_convert_to_enum_sip_api_release_type_sip_api_get_state_sip_api_parse_result_parseResult_sip_api_trace_sip_api_transfer_break_sip_api_export_symbol_sipSymbolList_sip_api_find_type_compareTypeDef_module_searched_sip_api_type_from_py_type_object_sip_api_type_scope_sip_api_resolve_typedef_compareTypedefName_sip_api_register_attribute_getter_sip_api_bad_callable_arg_sip_api_set_destroy_on_exit_sip_api_find_named_enum_sip_api_find_mapped_type_sip_api_find_class_sip_api_map_int_to_class_compareIntMapEntry_sip_api_map_string_to_class_compareStringMapEntry_sip_api_clear_any_slot_reference_sip_api_visit_slot_sip_api_init_module_createMappedType_getScopeDict_createEnumType.bases_createTypeDict_currentType_fix_slots_sip_api_init_module.md_setReduce_createClassType_addInstancesL_.str135L_.str136L_.str137L_.str138L_.str139_sip_api_parse_args_parseKwdArgs_sip_api_parse_pair_parsePass1_parsePass2_sip_api_abstract_methodL_.str133_sip_api_bad_classL_.str132_sip_api_get_complex_cpp_ptr_getComplexCppPtr_sip_api_call_hookL_.str131_sip_api_raise_unknown_exception_sip_api_raise_unknown_exception.mobjL_.str129_sip_api_raise_type_exception_sip_api_add_type_instance_addSingleTypeInstance_sip_api_bad_operator_argL_.str127L_.str126L_.str128L_.str130_sip_api_pyslot_extend_sip_api_add_delayed_dtor_sip_api_bytes_as_char_parseBytes_AsCharL_.str125_sip_api_bytes_as_string_parseBytes_AsStringL_.str124_sip_api_string_as_ascii_char_parseString_AsASCIIChar_sip_api_string_as_ascii_string_parseString_AsEncodedStringL_.str123_sip_api_string_as_latin1_char_parseString_AsLatin1Char_sip_api_string_as_latin1_stringL_.str122_sip_api_string_as_utf8_char_parseString_AsUTF8Char_sip_api_string_as_utf8_stringL_.str121_sip_api_unicode_as_wchar_parseWCharL_.str120_sip_api_unicode_as_wstring_parseWCharStringL_.str119_sip_api_deprecatedL_.str118L_.str116L_.str117_sip_api_keep_reference_sip_api_parse_kwd_argsL_.str114_sip_api_add_exception_add_failure_sip_api_parse_result_ex_sip_api_call_error_handler_sip_api_init_mixin_sip_api_init_mixin.double_usL_.str107_sip_api_get_mixin_address_sip_api_convert_from_new_pytype_sip_api_register_proxy_resolverL_.str109L_.str110_parseWCharArray_parseBytes_AsCharArrayL_.str108_parseString_AsEncodedCharL_.str113L_.str112L_.str111_failure_dtor_check_encoded_stringL_.str115_pickle_enumL_.str147_setReduce.rstrL_.str146_getDefaultBases_createContainerType_findPyType_createClassType.md_getDefaultBases.default_basesL_.str145_createTypeDict.mstrL_.str144_pickle_typeL_.str143L_.str142L_.str141_sipEnumType_alloc_addTypeSlots_slot_richcompare_slot_mp_ass_subscript_slot_sq_ass_item_slot_call_slot_sq_item_findSlotL_.str160_sipWrapper_dealloc_sipWrapper_clear_sipWrapper_traverse_sipWrapperType_getattro_sipWrapperType_setattro_sipWrapperType_init_sipWrapperType_alloc_sipSimpleWrapper_getbuffer_sipSimpleWrapper_releasebuffer_PyInit_sip.methodsL_.strL_.str1L_.str2L_.str3L_.str4L_.str5L_.str6L_.str7L_.str8L_.str9L_.str10L_.str11L_.str12L_.str13L_.str14L_.str15L_.str18L_.str32_sipSimpleWrapper_getsetL_.str66L_.str35L_.str44L_.str45L_.str46L_.str47L_.str134L_.str140L_.str159L_.str161L_.str162EH_frame0_cast.eh_callDtor.eh_dumpWrapper.eh_enableAutoconversion.eh_isDeleted.eh_isPyCreated.eh_isPyOwned.eh_setDeleted.eh_setDestroyOnExit.eh_setTraceMask.eh_transferBack.eh_transferTo.eh_wrapInstance.eh_unwrapInstance.eh_unpickle_type.eh_unpickle_enum.eh_sip_api_register_py_type.eh_finalise.eh_removeFromParent.eh_checkPointer.eh_sip_api_can_convert_to_type.eh_sip_api_convert_to_type.eh_get_from_convertor.eh_convertSubClass.eh_sip_api_get_pyobject.eh_sip_api_transfer_back.eh_sip_api_transfer_to.eh_sipSimpleWrapper_dealloc.eh_sipSimpleWrapper_traverse.eh_sipSimpleWrapper_clear.eh_sipSimpleWrapper_init.eh_sipSimpleWrapper_new.eh_sip_api_enable_autoconversion.eh_sip_exit.eh_add_all_lazy_attrs.eh_add_lazy_container_attrs.eh_addMethod.eh_create_function.eh_sip_api_convert_from_enum.eh_sip_api_no_function.eh_explicit_access_func.eh_indirect_access_func.eh_find_finalisation.eh_isQObject.eh_next_in_mro.eh_super_init.eh_sip_api_no_method.eh_detail_FromFailure.eh_signature_FromDocstring.eh_sipSimpleWrapper_get_dict.eh_sipSimpleWrapper_set_dict.eh_forgetObject.eh_getModule.eh_sip_api_is_py_method.eh_sip_api_call_method.eh_buildObject.eh_sip_api_convert_from_new_type.eh_release.eh_print_object.eh_sip_api_export_module.eh_sip_api_bad_catcher_result.eh_sip_api_bad_length_for_slice.eh_sip_api_build_result.eh_sip_api_convert_from_sequence_index.eh_sip_api_can_convert_to_enum.eh_sip_api_release_type.eh_sip_api_get_state.eh_sip_api_parse_result.eh_sip_api_trace.eh_sip_api_transfer_break.eh_sip_api_export_symbol.eh_sip_api_import_symbol.eh_sip_api_find_type.eh_sip_api_type_from_py_type_object.eh_sip_api_type_scope.eh_sip_api_resolve_typedef.eh_sip_api_register_attribute_getter.eh_sip_api_bad_callable_arg.eh_sip_api_set_destroy_on_exit.eh_sip_api_find_named_enum.eh_sip_api_find_mapped_type.eh_sip_api_find_class.eh_sip_api_map_int_to_class.eh_sip_api_map_string_to_class.eh_sip_api_clear_any_slot_reference.eh_sip_api_visit_slot.eh_sip_api_init_module.eh_sip_api_parse_args.eh_sip_api_parse_pair.eh_sip_api_abstract_method.eh_sip_api_bad_class.eh_sip_api_get_complex_cpp_ptr.eh_sip_api_call_hook.eh_sip_api_raise_unknown_exception.eh_sip_api_raise_type_exception.eh_sip_api_add_type_instance.eh_sip_api_bad_operator_arg.eh_sip_api_pyslot_extend.eh_sip_api_add_delayed_dtor.eh_sip_api_bytes_as_char.eh_sip_api_bytes_as_string.eh_sip_api_string_as_ascii_char.eh_sip_api_string_as_ascii_string.eh_sip_api_string_as_latin1_char.eh_sip_api_string_as_latin1_string.eh_sip_api_string_as_utf8_char.eh_sip_api_string_as_utf8_string.eh_sip_api_unicode_as_wchar.eh_sip_api_unicode_as_wstring.eh_sip_api_deprecated.eh_sip_api_keep_reference.eh_sip_api_parse_kwd_args.eh_sip_api_add_exception.eh_sip_api_parse_result_ex.eh_sip_api_call_error_handler.eh_sip_api_init_mixin.eh_sip_api_get_mixin_address.eh_sip_api_convert_from_new_pytype.eh_sip_api_register_proxy_resolver.eh_parseResult.eh_parseBytes_AsCharArray.eh_parseWCharArray.eh_parseBytes_AsChar.eh_parseString_AsASCIIChar.eh_parseString_AsLatin1Char.eh_parseString_AsUTF8Char.eh_parseWChar.eh_parseBytes_AsString.eh_parseWCharString.eh_parseString_AsEncodedString.eh_parseString_AsEncodedChar.eh_add_failure.eh_failure_dtor.eh_parseKwdArgs.eh_parsePass1.eh_parsePass2.eh_getComplexCppPtr.eh_check_encoded_string.eh_addSingleTypeInstance.eh_pickle_enum.eh_setReduce.eh_createMappedType.eh_createClassType.eh_addInstances.eh_getDefaultBases.eh_findPyType.eh_createTypeDict.eh_createContainerType.eh_fix_slots.eh_pickle_type.eh_getScopeDict.eh_compareStringMapEntry.eh_compareIntMapEntry.eh_compareTypedefName.eh_compareTypeDef.eh_sipEnumType_alloc.eh_addTypeSlots.eh_slot_call.eh_slot_sq_item.eh_slot_mp_ass_subscript.eh_slot_sq_ass_item.eh_slot_richcompare.eh_findSlot.eh_sipWrapper_dealloc.eh_sipWrapper_traverse.eh_sipWrapper_clear.eh_sipWrapperType_getattro.eh_sipWrapperType_setattro.eh_sipWrapperType_init.eh_sipWrapperType_alloc.eh_sipSimpleWrapper_getbuffer.eh_sipSimpleWrapper_releasebuffer.eh #1/20 1391684655 501 20 100644 3516 ` apiversions.o@ `__text__TEXT}` &__cstring__TEXT}__bss__DATA__compact_unwind__LDh0 __eh_frame__TEXT hX   P  UHAWAVAUATSPAAIH E1HHt/H;LHKuE~D9{|E~D9s}ADH[A\A]A^A_]UHAWAVAUATSHHuH}LMAx|L-AA~y\LcHELx LHHHtH;Lt1A^HL8XH HHHAF I yHELMAI(AHELh HAkNHcɋTtHctnHt H; u6HCHK H@HcHP HNHH8H50/Hs(Ht HHHsHHtI1ɉ[A^]sip.methoddescriptorsip.variabledescriptor'%s' object attribute '%s' is read-only'%s' object attribute '%s' is an instance attribute @0@99Sp(A/4!<9u(@aaEaD! !zRx $9AC B$DAC $lAC $(AC $AAC B$/AC B$ 4AC C$49AC B$\AC $(AC $@AC F$AC F$TEAC F$$qDAC C$LAC C--y)-a'-Z P(=0,M*-%*-%p'-i _(=# - -*- *- &-)-,MO+-G  H@X0`@ `@ ~9*Sp<u1Ie {0 H p   ( E` b    x 38 L `@dP K( 9'u_PyUnicode_FromFormat__Py_NoneStruct_PyObject_GetAttr_PyCFunction_NewEx_sipMethodDescr_New_sipMethodDescr_Type_PyType_GenericAlloc_sipMethodDescr_Copy_PyExc_AttributeError_PyErr_Format_sipVariableDescr_New_sipVariableDescr_Type_sipVariableDescr_Copy_sip_api_get_cpp_ptr_sipMethodDescr_New.eh_sipMethodDescr_Copy.eh_sipVariableDescr_New.eh_sipVariableDescr_Copy.eh_sipMethodDescr_dealloc_sipMethodDescr_reprL_.str4_sipMethodDescr_traverse_sipMethodDescr_clear_sipMethodDescr_descr_get_sipVariableDescr_dealloc_sipVariableDescr_traverse_sipVariableDescr_clear_sipVariableDescr_descr_get_get_instance_address_sipVariableDescr_descr_setL_.str2L_.str3L_.strL_.str1EH_frame0_sipMethodDescr_dealloc.eh_sipMethodDescr_repr.eh_sipMethodDescr_traverse.eh_sipMethodDescr_clear.eh_sipMethodDescr_descr_get.eh_sipVariableDescr_dealloc.eh_sipVariableDescr_traverse.eh_sipVariableDescr_clear.eh_sipVariableDescr_descr_get.eh_sipVariableDescr_descr_set.eh_get_instance_address.eh #1/12 1391684656 501 20 100644 6604 ` qtlib.o   __text__TEXT M__cstring__TEXT  __compact_unwind__LD @ h __eh_frame__TEXT 0 h6 P UHAWAVAUATSH8III6Ht3>t.I~HHLPPE1L=II~ H;=t#1Ht0LE1HHIIFHH;I^HM6MHHEHEIHLHH-HCH;HH8H5L0H HCHP0L=IHIuHHCHP0HHIHHHEuIvI~HHu HEHH]IE1HL1LIMt{IHEH}HuHGP0H}Ht HuHGP0I9t/MtIMu IELP0H}Ht HuHGP0I $8ID$L(IHEH}HuHUHH0H}HMHH}I~CI9u HEHEI;Ht HuHGP0H}Ht HuHGP0H}Ht HuHGP0IVHL1IMIu IFLP0H}L1IMM"HH8H5L0E1H}HHtoI9t-MtIMu IELP0H}Ht HuHGP0LHUHuH}MtIMu IELP0H}Ht`Hu[HGP0RH}I9tNHt HuHGP0H}Ht HuHGP0H}Ht HuHGP0LHu1L Hu1H}HuHGP0H}Ht HuHGP0E1HHuHGP0LH8[A\A]A^A_]UHAVSIHHt9H;1H?HHHP@0ɅtL9s~IFH;tH;t+L9s\1H{uSHK0I;NuHCI;FH;1Ht3?u.HKIF1@ uIV0H9uH0H[A^]UHAWAVAUATSPMHIIHtR<wJIHH0L1Htf;2u^H H HIHtKHLH[A\A]A^A_]HHLh(HLLHMLH[A\A]A^A_]HHH[A\A]A^A_]UHAWAVSPMHIHtA<wMIHH0HH1Ht[;2uSHLH[A^A_]HHL1MHHLHME1PHtMt AO!HH[A^A_]UHAWAVSPIHL=IHHHHtHLHu IHH1HtHLH[A^A_]H[A^A_]UHAWAVAUATSH(DEIIIA}2HMHH0L1HLmHuHIMtpLELLLHME1HtRH HHMHuLHDES0HcH&HHLLLPX1ۅx HHHH([A\A]A^A_]UHAWAVAUATSHIIHIH]Ѐ;2HH0LI1MLELHLLIMtqL%M$IHHtHuLIM$H]HMLHLAP8I$LP Hc,HHLHLLP`HHHH[A\A]A^A_]UHAVSHH;Ht H *Ls HC H;uH{HHHuHGP0LH;HtHt[A^]HG[A^]`0UHAWAVATSIIIID$ MteLHxHHHLI$A?1u)H߾(HtI$LID$ Mt$I$IFH;H;IF@ M~MIH;=tH5tcIFHHHxHI $Ht|I<$HHM|$LH1IL$ QI$BIMt$HHID$ 1'I|$LI|$ID$ 1ID$[A\A^A_]UHSP1HHuHH[]Invalid slot %sPXP!Xa~^aXXd!   $zRx ,PAC M$LAC C,tAC J$AC F$^AC F,AC M,$xAC M$T9dAC C,|uAC G$$AC B - &- - ,-h )=> -1 4- 1- 5- $- -= -M M !M -r 2-[ 4-D 1-; 5-)M.-'=)=y+=p-*+=-0-*=)=+=-_+=S -2-0- *=+=I+=5+=.- 0-*=/-+=i+=V0-K*= 3-M!M|+=---=-#->-2=+---^ --(=(=-=M"-(Mj%-Y)MF(=++= `@ b i~t    b   @ 3p 8 8Ph + L q)KY}D$4lf|F^ZV>_sip_api_invoke_slot_sipQtSupport__Py_NoneStruct__Py_TrueStruct_PyWeakref_GetObject_PyObject_GetAttrString_PyCFunction_Type_PyExc_NameError_PyErr_Format_PyMethod_New_PyEval_CallObjectWithKeywords_PyErr_Clear_PyErr_Fetch_PyExc_TypeError_PyErr_GivenExceptionMatches_PyTuple_GetSlice_PyErr_Restore_sip_api_same_slot_PyMethod_Type_strcmp_sipGetRx_sipQObjectType_sip_api_get_cpp_ptr_sip_api_get_address_sip_api_convert_rx_sip_api_connect_rx_PyBool_FromLong_sip_api_disconnect_rx__Py_FalseStruct_sip_api_free_sipslot_sip_api_free_sip_api_save_slot_strlen_sip_api_malloc_strcpy_strchr_sipSimpleWrapper_Type_PyType_IsSubtype_sipSaveMethod_PyWeakref_NewRef_sip_api_invoke_slot.eh_sip_api_same_slot.eh_sipGetRx.eh_sip_api_convert_rx.eh_sip_api_connect_rx.eh_sip_api_disconnect_rx.eh_sip_api_free_sipslot.eh_sip_api_save_slot.ehL_.str_newSignal_getWeakRefEH_frame0_newSignal.eh_getWeakRef.eh#1/20 1391684656 501 20 100644 2172 ` threads.o ph__text__TEXTx __bss__DATAh__compact_unwind__LD__eh_frame__TEXT h(< P UHAWAVSPIIHHHHHDȸtHHHAIAA1HH[A^A_]UHSP11Ht Hx؉H[]UHAWAVAUATSH(EIHUIHHteHLq1HLDtSIFHEIINHMHEIMnE~LHu1HMINHMHUIVI HHH([A\A]A^A_]UHSP1HtHH[]UHAWAVSPAHE1H Hɸt1HH9tKHHDHI HuEt9Hu!(Ht%H HH HHH@IILH[A^A_]VaV(~X"-OazRx $`VAC F$D(AC B,lAC M$-AC B$AC F-j]-K -2-) - =--a--`@ Oh'@V~N"bu/>_sipGetPending_sipIsPending_sipWrapInstance_PyObject_Call__Py_NoneStruct_sip_api_end_thread_PyGILState_Ensure_PyGILState_Release_PyThread_get_thread_ident_sip_api_malloc_sipGetPending.eh_sipIsPending.eh_sipWrapInstance.eh_sip_api_end_thread.eh_currentThreadDef_threadsEH_frame0_currentThreadDef.eh #1/12 1391684656 501 20 100644 4396 ` objmap.o   __text__TEXT __const__TEXT__compact_unwind__LD` __eh_frame__TEXT  h0   P UHSPHHC HC HC HC H[]UHAVSHHHIMt LHL[A^]UHH ]UHAWAVSPIHXHtBMv C!ItL{I?t"LHtIL9tLu H[HHuE1LH[A^A_]UHLOLG H1IHIIH1HHHIH9t0Ht+HILHH1IHHHIH9tHuHIL]UHAWAVSPHIHCHt H1IL{LLHHCH0LLHIH[A^A_]UHAWAVAUATSPIIIIIHtCAF @u2IGH_HG u G HHuII~HMw:I?t IMIEM'IEHIEMwIFHM}LHH9vH[A\A]A^A_]IEAMLHH9sAtAEHcH HDk L{Lc H1IM>MfEnADHX[A\A]A^A_]HCHHt9H8t3HuE1H1xÃ}L}LeH}DHIHvHH8H5E1iUHH]UHAWAVSPAIHHt6H= H5HH1HtHYLyDq H HHH[A^A_]UHH1]UH]UH1]UHH11]UHAVSHHHEHH LEHHH0E1t"HuHy HsHuHxH{ILH[A^]HH8H5UHH]UHAVSIHHHt1I^HH[A^]UHHc ]UHAVSIHHHt1A^ HH[A^]UHAIIJHxIRAz DHL]HH8H5]UHHGHyHH8H5H]UHAWAVSH(HIIvHxrHHHQ`Ht>Ht4H H1HII1HH; t8HQHH8H50HH8H51lHUHMLELMH1ۅxNH}u8AV I~H}HuH-MxLIvLLHHH8HH([A^A_]UHAWAVATSHpIHIA IwHHHHQ`Ht~HttL%I4$HHEHuHHEHyIGHEI9GHEHH8H5H; tƞwH5Hc4H1 H$1H]UHAWAVAUATSPDLEIIIIH= H5H1Ht9LpLhL` Lx(HMHH0X8tH@@HMHtHHH@HHH[A\A]A^A_]UHHHtH$ HHH]UH1HDG8t#AtHH8H5uH~HHOHHO0HNADF LFHNLO(LNHF(tH H~(F$1HDHN0LELF8HFHHF@]UHHG0]UHAWAVSH(HIHHHQ`Ht?Ht5H H1HHHE1HH; t$HQHH8H50E1Iv0HUHMLELMHE1xoH}uYIFIvHx(H}HxIN(IV EN8IF@LEH$AI-HxHIv0HLIHH8LH([A^A_]UHAWAVAUATSH(IHIAG8t!HH8H5AHHHQ`HHHH3HHEHuAH2HEHyIG0HEI9G0IwHELML1ҹE1xH; t'HQHH8H50AIw0HUHMLELMHAH}u[LeH5LI_tI;]uIu I HtfHCHcSHP H;H5HH8IG 1ۃawIBHLGIG awDBHH/H HcHLdHH HcHHIM9e0uyIO(IU(H9\HH8H5-LILHIu HHHH8H5LL5LZLfLHH1HHDAHt_HEIO(H}HIHHE11HHHHH8H50DH([A\A]A^A_]IEHtHUfCbb&b]wH QHcHH>]>]Iu>]]Z]H>]Hc>]}}}sip.arrayObject is not writable.cannot index a sip.array object using '%s'charunsigned charshortunsigned shortintunsigned intfloatdoublecan only assign another array of %s to the slicethe array being assigned must have length %zdthe array being assigned must have stride %zuindex out of boundssip.array object is read-onlyHX2,^ ,aFXlzRx $8AC ,DAC J$t,AC $AC $ AC $,AC I,AC M$D|AC /3-&3-1-1-4-4-3-4-+- -==-(-/=<-)-}2-sl2-bV0-LD0-4*/=?-?- /=  s2-J  ?-'-*-.= @-7-"o9-H(-A7/=*:M>-)-5--=y+-tj/=4*-,.= --9-(-/=|:Md)-R5-G-=+-,=Q;=H-6-"8-"z-7;=h`XP`@ lx^^vlF u  G 3;CL U]emvT}     @ h  ! < + , Z2I }2zK`:Au_sip_api_convert_to_array__Py_NoneStruct_sipArray_Type_PyObject_Malloc_PyObject_Init_sip_api_convert_to_typed_array_PyExc_BufferError_PyErr_SetString_PyExc_IndexError_PyNumber_AsSsize_t_PyErr_Occurred_PySlice_Type_PyExc_TypeError_PyErr_Format_PySlice_GetIndicesEx_PyExc_NotImplementedError_PyErr_SetNone_sip_api_force_convert_to_type_PyObject_IsInstance_strcmp_PyErr_Clear_sip_api_long_as_unsigned_long_PyLong_AsLong_PyFloat_AsDouble_memmove_sip_api_convert_from_type_PyLong_FromUnsignedLong_PyLong_FromLong_PyFloat_FromDouble_sip_api_convert_to_array.eh_sip_api_convert_to_typed_array.eh_make_array_sipArray_getbufferL_.str1_sipArray_length_sipArray_subscriptL_.str2_sipArray_item_sipArray_ass_subscriptL_.str16L_.str15L_.str6L_.str3L_.str10L_.str14_get_value.static_dataL_.str4L_.str8L_.str11L_.str13L_.str9L_.str5L_.str7L_.str12L_.str_sipArray_SequenceMethods_sipArray_MappingMethods_sipArray_BufferProcsEH_frame0_make_array.eh_sipArray_getbuffer.eh_sipArray_length.eh_sipArray_subscript.eh_sipArray_ass_subscript.eh_sipArray_item.eh#1/12 1391684656 501 20 100644 668 ` bool.o 8pp__text__TEXT __compact_unwind__LD 0__eh_frame__TEXT0@ h8h( PUH] zRx $ AC 0 H_sipSetBool_sipSetBool.ehEH_frame0sip-4.15.5/siplib/objmap.c0000644000076500000240000003242012261241112015347 0ustar philstaff00000000000000/* * This module implements a hash table class for mapping C/C++ addresses to the * corresponding wrapped Python object. * * Copyright (c) 2014 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 "sip.h" #include "sipint.h" #define hash_1(k,s) (((unsigned long)(k)) % (s)) #define hash_2(k,s) ((s) - 2 - (hash_1((k),(s)) % ((s) - 2))) /* Prime numbers to use as hash table sizes. */ static unsigned long hash_primes[] = { 521, 1031, 2053, 4099, 8209, 16411, 32771, 65537, 131101, 262147, 524309, 1048583, 2097169, 4194319, 8388617, 16777259, 33554467, 67108879, 134217757, 268435459, 536870923, 1073741827, 2147483659U,0 }; static sipHashEntry *newHashTable(unsigned long); static sipHashEntry *findHashEntry(sipObjectMap *,void *); static void 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))->type; 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->flags = (val->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->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. */ sipSetNotInMap(sw); sip_api_common_dtor(sw); } sw = next; } } val->next = he->first; he->first = val; return; } /* See if the bucket was unused or stale. */ if (he->key == NULL) { he->key = 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))->type; 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.15.5/siplib/qtlib.c0000644000076500000240000004356012261241117015226 0ustar philstaff00000000000000/* * The SIP library code that implements the interface to the optional module * supplied Qt support. * * Copyright (c) 2014 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" #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. */ PyObject *sip_api_invoke_slot(const sipSlot *slot, PyObject *sigargs) { PyObject *sa, *oxtype, *oxvalue, *oxtb, *sfunc, *sref; assert(sipQtSupport); /* Keep some compilers quiet. */ oxtype = oxvalue = oxtb = NULL; /* Fan out Qt signals. (Only PyQt3 will do this.) */ if (slot->name != NULL && slot->name[0] != '\0') { assert(sipQtSupport->qt_emit_signal); if (sipQtSupport->qt_emit_signal(slot->pyobj, slot->name, sigargs) < 0) return NULL; Py_INCREF(Py_None); return Py_None; } /* Get the object to call, resolving any weak references. */ if (slot->weakSlot == Py_True) { /* * The slot is guaranteed to be Ok because it has an extra reference or * is None. */ sref = slot->pyobj; Py_INCREF(sref); } else if (slot -> weakSlot == NULL) sref = NULL; else if ((sref = PyWeakref_GetObject(slot -> weakSlot)) == NULL) return NULL; else Py_INCREF(sref); if (sref == Py_None) { /* * If the real object has gone then we pretend everything is Ok. This * mimics the Qt behaviour of not caring if a receiving object has been * deleted. */ Py_DECREF(sref); Py_INCREF(Py_None); return Py_None; } if (slot -> pyobj == NULL) { PyObject *self = (sref != NULL ? sref : slot->meth.mself); /* * We used to check that any wrapped C++ object still existed and just * returning None if it didn't. This caused inconsistent behaviour * when the slot was a method connected to its object's destroyed() * signal. */ #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 will get this far. */ assert(sipQtSupport->qt_connect_py_signal); if (sipQtSupport->qt_connect_py_signal(txObj, sig, rxObj, slot) < 0) return NULL; Py_INCREF(Py_True); return Py_True; } /* * Disconnect a signal to a signal or a Qt slot. */ PyObject *sip_api_disconnect_rx(PyObject *txObj,const char *sig, PyObject *rxObj,const char *slot) { 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 will get this far. */ assert(sipQtSupport->qt_disconnect_py_signal); sipQtSupport->qt_disconnect_py_signal(txObj, sig, rxObj, slot); Py_INCREF(Py_True); return Py_True; } /* * Free the resources of a slot. */ void sip_api_free_sipslot(sipSlot *slot) { 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.15.5/siplib/sip.h.in0000644000076500000240000015357512310606636015336 0ustar philstaff00000000000000/* * The SIP module interface. * * Copyright (c) 2014 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 0x040f05 #define SIP_VERSION_STR "4.15.5" /* * Define the current API version number. SIP must handle modules with the * same major number and with the same or earlier minor number. Whenever data * structure elements are added they must be appended and the minor number * incremented. Whenever data structure elements are removed or the order * changed then the major number must be incremented and the minor number set * to 0. * * History: * * 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 sip_api_assign_instance(). * Added sip_api_assign_mapped_type(). * Added the td_assign and td_qt fields to the sipTypeDef structure. * Added the mt_assign field to the sipMappedType structure. * * 3.6 Added the 'g' format character to sip_api_parse_args(). * * 3.5 Added the td_pickle field to the sipTypeDef structure. * Added sip_api_transfer_break(). * * 3.4 Added qt_find_connection() to the Qt support API. * Added sip_api_string_as_char(), sip_api_unicode_as_wchar(), * sip_api_unicode_as_wstring(), sip_api_find_class(), * sip_api_find_named_enum() and sip_api_parse_signature(). * Added the 'A', 'w' and 'x' format characters to sip_api_parse_args(), * sip_api_parse_result(), sip_api_build_result() and * sip_api_call_method(). * * 3.3 Added sip_api_register_int_types(). * * 3.2 Added sip_api_export_symbol() and sip_api_import_symbol(). * * 3.1 Added sip_api_add_mapped_type_instance(). * * 3.0 Moved the Qt support out of the sip module and into PyQt. This is * such a dramatic change that there is no point in attempting to maintain * backwards compatibility. * * 2.0 Added the td_flags field to the sipTypeDef structure. * Added the first_child, sibling_next, sibling_prev and parent fields to * the sipWrapper structure. * Added the td_traverse and td_clear fields to the sipTypeDef structure. * Added the em_api_minor field to the sipExportedModuleDef structure. * Added sip_api_bad_operator_arg(). * Added sip_api_wrapper_check(). * * 1.1 Added support for __pos__ and __abs__. * * 1.0 Removed all deprecated parts of the API. * Removed the td_proxy field from the sipTypeDef structure. * Removed the create proxy function from the 'q' and 'y' format * characters to sip_api_parse_args(). * Removed sip_api_emit_to_slot(). * Reworked the enum related structures. * * 0.2 Added the 'H' format character to sip_api_parse_args(). * * 0.1 Added sip_api_add_class_instance(). * Added the 't' format character to sip_api_parse_args(). * Deprecated the 'J' and 'K' format characters to sip_api_parse_result(). * * 0.0 Original version. */ #define SIP_API_MAJOR_NR 11 #define SIP_API_MINOR_NR 0 /* 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_FromLong PyLong_FromLong #define SIPLong_AsLong PyLong_AsLong #define SIPBytes_Check PyBytes_Check #define SIPBytes_FromString PyBytes_FromString #define SIPBytes_FromStringAndSize PyBytes_FromStringAndSize #define SIPBytes_AS_STRING PyBytes_AS_STRING #define SIPBytes_GET_SIZE PyBytes_GET_SIZE #if PY_MINOR_VERSION >= 1 #define SIP_USE_PYCAPSULE #endif #if PY_MINOR_VERSION < 2 #define SIP_SUPPORT_PYCOBJECT #endif #else #define SIPLong_FromLong PyInt_FromLong #define SIPLong_AsLong PyInt_AsLong #define SIPBytes_Check PyString_Check #define SIPBytes_FromString PyString_FromString #define SIPBytes_FromStringAndSize PyString_FromStringAndSize #define SIPBytes_AS_STRING PyString_AS_STRING #define SIPBytes_GET_SIZE PyString_GET_SIZE #if PY_MINOR_VERSION >= 7 #define SIP_USE_PYCAPSULE #endif #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 /* * Some convenient function pointers. */ /* * 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; struct _sipSimpleWrapper; struct _sipTypeDef; typedef void *(*sipInitFunc)(struct _sipSimpleWrapper *, PyObject *, PyObject *, PyObject **, PyObject **, PyObject **); typedef int (*sipFinalFunc)(PyObject *, void *, PyObject *, PyObject **); typedef void *(*sipAccessFunc)(struct _sipSimpleWrapper *, AccessFuncOp); typedef int (*sipTraverseFunc)(void *, visitproc, void *); typedef int (*sipClearFunc)(void *); #if PY_MAJOR_VERSION >= 3 typedef int (*sipGetBufferFunc)(PyObject *, void *, Py_buffer *, int); typedef void (*sipReleaseBufferFunc)(PyObject *, void *, Py_buffer *); #else typedef SIP_SSIZE_T (*sipBufferFunc)(PyObject *, void *, SIP_SSIZE_T, void **); typedef SIP_SSIZE_T (*sipSegCountFunc)(PyObject *, void *, SIP_SSIZE_T *); #endif typedef void (*sipDeallocFunc)(struct _sipSimpleWrapper *); typedef void *(*sipCastFunc)(void *, const struct _sipTypeDef *); typedef const struct _sipTypeDef *(*sipSubClassConvertFunc)(void **); typedef int (*sipConvertToFunc)(PyObject *, void **, int *, PyObject *); typedef PyObject *(*sipConvertFromFunc)(void *, PyObject *); typedef void (*sipVirtErrorHandlerFunc)(struct _sipSimpleWrapper *, sip_gilstate_t); typedef int (*sipVirtHandlerFunc)(sip_gilstate_t, sipVirtErrorHandlerFunc, struct _sipSimpleWrapper *, PyObject *, ...); typedef void (*sipAssignFunc)(void *, SIP_SSIZE_T, const void *); typedef void *(*sipArrayFunc)(SIP_SSIZE_T); typedef void *(*sipCopyFunc)(const void *, SIP_SSIZE_T); typedef void (*sipReleaseFunc)(void *, int); typedef PyObject *(*sipPickleFunc)(void *); typedef int (*sipAttrGetterFunc)(const struct _sipTypeDef *, PyObject *); typedef PyObject *(*sipVariableGetterFunc)(void *, PyObject *, PyObject *); typedef int (*sipVariableSetterFunc)(void *, PyObject *, PyObject *); typedef void *(*sipProxyResolverFunc)(void *); /* * The meta-type of a wrapper type. */ typedef struct _sipWrapperType { /* * The super-metatype. This must be first in the structure so that it can * be cast to a PyTypeObject *. */ PyHeapTypeObject super; /* The generated type structure. */ struct _sipTypeDef *type; /* The list of init extenders. */ struct _sipInitExtenderDef *iextend; /* Set if the type's dictionary contains all lazy attributes. */ int dict_complete; } sipWrapperType; /* * The type of a simple C/C++ wrapper object. */ typedef struct _sipSimpleWrapper { PyObject_HEAD /* * 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. */ int flags; /* The optional dictionary of extra references keyed by argument number. */ PyObject *extra_refs; /* For the user to use. */ PyObject *user; /* The instance dictionary. */ PyObject *dict; /* The main instance if this is a mixin. */ PyObject *mixin_main; /* Next object at this address. */ struct _sipSimpleWrapper *next; } sipSimpleWrapper; /* * The type of a C/C++ wrapper object that supports parent/child relationships. */ typedef struct _sipWrapper { /* The super-type. */ sipSimpleWrapper super; /* First child object. */ struct _sipWrapper *first_child; /* Next sibling. */ struct _sipWrapper *sibling_next; /* Previous sibling. */ struct _sipWrapper *sibling_prev; /* Owning object. */ struct _sipWrapper *parent; } sipWrapper; /* * The meta-type of an enum type. (This is exposed only to support the * deprecated sipConvertFromNamedEnum() macro.) */ typedef struct _sipEnumTypeObject { /* * The super-metatype. This must be first in the structure so that it can * be cast to a PyTypeObject *. */ PyHeapTypeObject super; /* The generated type structure. */ struct _sipTypeDef *type; } sipEnumTypeObject; /* * The information describing an encoded type ID. */ typedef struct _sipEncodedTypeDef { /* The type number. */ unsigned sc_type:16; /* The module number (255 for this one). */ unsigned sc_module:8; /* A context specific flag. */ unsigned sc_flag:1; } sipEncodedTypeDef; /* * The information describing an enum member. */ typedef struct _sipEnumMemberDef { /* The member name. */ const char *em_name; /* The member value. */ int em_val; /* The member enum, -ve if anonymous. */ int em_enum; } sipEnumMemberDef; /* * The information describing static instances. */ typedef struct _sipInstancesDef { /* The types. */ struct _sipTypeInstanceDef *id_type; /* The void *. */ struct _sipVoidPtrInstanceDef *id_voidp; /* The chars. */ struct _sipCharInstanceDef *id_char; /* The strings. */ struct _sipStringInstanceDef *id_string; /* The ints. */ struct _sipIntInstanceDef *id_int; /* The longs. */ struct _sipLongInstanceDef *id_long; /* The unsigned longs. */ struct _sipUnsignedLongInstanceDef *id_ulong; /* The long longs. */ struct _sipLongLongInstanceDef *id_llong; /* The unsigned long longs. */ struct _sipUnsignedLongLongInstanceDef *id_ullong; /* The doubles. */ struct _sipDoubleInstanceDef *id_double; } sipInstancesDef; /* * The information describing a type initialiser extender. */ typedef struct _sipInitExtenderDef { /* The API version range index. */ int ie_api_range; /* The extender function. */ sipInitFunc ie_extender; /* The class being extended. */ sipEncodedTypeDef ie_class; /* The next extender for this class. */ struct _sipInitExtenderDef *ie_next; } sipInitExtenderDef; /* * The information describing a sub-class convertor. */ typedef struct _sipSubClassConvertorDef { /* The convertor. */ sipSubClassConvertFunc scc_convertor; /* The encoded base type. */ sipEncodedTypeDef scc_base; /* The base type. */ struct _sipTypeDef *scc_basetype; } sipSubClassConvertorDef; /* * The different error states of handwritten code. */ typedef enum { sipErrorNone, /* There is no error. */ sipErrorFail, /* The error is a failure. */ sipErrorContinue /* It may not apply if a later operation succeeds. */ } sipErrorState; /* * The different Python slot types. */ typedef enum { str_slot, /* __str__ */ int_slot, /* __int__ */ #if PY_MAJOR_VERSION < 3 long_slot, /* __long__ */ #endif float_slot, /* __float__ */ len_slot, /* __len__ */ contains_slot, /* __contains__ */ add_slot, /* __add__ for number */ concat_slot, /* __add__ for sequence types */ sub_slot, /* __sub__ */ mul_slot, /* __mul__ for number types */ repeat_slot, /* __mul__ for sequence types */ div_slot, /* __div__ */ mod_slot, /* __mod__ */ floordiv_slot, /* __floordiv__ */ truediv_slot, /* __truediv__ */ and_slot, /* __and__ */ or_slot, /* __or__ */ xor_slot, /* __xor__ */ lshift_slot, /* __lshift__ */ rshift_slot, /* __rshift__ */ iadd_slot, /* __iadd__ for number types */ iconcat_slot, /* __iadd__ for sequence types */ isub_slot, /* __isub__ */ imul_slot, /* __imul__ for number types */ irepeat_slot, /* __imul__ for sequence types */ idiv_slot, /* __idiv__ */ imod_slot, /* __imod__ */ ifloordiv_slot, /* __ifloordiv__ */ itruediv_slot, /* __itruediv__ */ iand_slot, /* __iand__ */ ior_slot, /* __ior__ */ ixor_slot, /* __ixor__ */ ilshift_slot, /* __ilshift__ */ irshift_slot, /* __irshift__ */ invert_slot, /* __invert__ */ call_slot, /* __call__ */ getitem_slot, /* __getitem__ */ setitem_slot, /* __setitem__ */ delitem_slot, /* __delitem__ */ lt_slot, /* __lt__ */ le_slot, /* __le__ */ eq_slot, /* __eq__ */ ne_slot, /* __ne__ */ gt_slot, /* __gt__ */ ge_slot, /* __ge__ */ #if PY_MAJOR_VERSION < 3 cmp_slot, /* __cmp__ */ #endif bool_slot, /* __bool__, __nonzero__ */ neg_slot, /* __neg__ */ repr_slot, /* __repr__ */ hash_slot, /* __hash__ */ pos_slot, /* __pos__ */ abs_slot, /* __abs__ */ #if PY_VERSION_HEX >= 0x02050000 index_slot, /* __index__ */ #endif iter_slot, /* __iter__ */ next_slot, /* __next__ */ setattr_slot, /* __setattr__, __delattr__ */ } 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. */ typedef struct _sipTypeDef { /* The version range index, -1 if the type isn't versioned. */ int td_version; /* The next version of this type. */ struct _sipTypeDef *td_next_version; /* The module, 0 if the type hasn't been initialised. */ struct _sipExportedModuleDef *td_module; /* Type flags, see the sipType*() macros. */ int td_flags; /* The C/C++ name of the type. */ int td_cname; /* * The Python type object. This needs to be a union until we remove the * deprecated sipClass_* macros. */ union { PyTypeObject *td_py_type; sipWrapperType *td_wrapper_type; } u; } sipTypeDef; /* * The information describing a container (ie. a class, namespace or a mapped * type). */ typedef struct _sipContainerDef { /* * The Python name of the type, -1 if this is a namespace extender (in the * context of a class) or doesn't require a namespace (in the context of a * mapped type). */ int cod_name; /* * The scoping type or the namespace this is extending if it is a namespace * extender. */ sipEncodedTypeDef cod_scope; /* The number of lazy methods. */ int cod_nrmethods; /* The table of lazy methods. */ PyMethodDef *cod_methods; /* The number of lazy enum members. */ int cod_nrenummembers; /* The table of lazy enum members. */ sipEnumMemberDef *cod_enummembers; /* The number of variables. */ int cod_nrvariables; /* The table of variables. */ sipVariableDef *cod_variables; /* The static instances. */ sipInstancesDef cod_instances; } sipContainerDef; /* * The information describing a C++ class (or C struct) or a C++ namespace. */ typedef struct _sipClassTypeDef { /* The base type information. */ sipTypeDef ctd_base; /* The container information. */ sipContainerDef ctd_container; /* The docstring. */ const char *ctd_docstring; /* * The meta-type name, -1 to use the meta-type of the first super-type * (normally sipWrapperType). */ int ctd_metatype; /* The super-type name, -1 to use sipWrapper. */ int ctd_supertype; /* The super-types. */ sipEncodedTypeDef *ctd_supers; /* The table of Python slots. */ sipPySlotDef *ctd_pyslots; /* The initialisation function. */ sipInitFunc ctd_init; /* The traverse function. */ sipTraverseFunc ctd_traverse; /* The clear function. */ sipClearFunc ctd_clear; #if PY_MAJOR_VERSION >= 3 /* The get buffer function. */ sipGetBufferFunc ctd_getbuffer; /* The release buffer function. */ sipReleaseBufferFunc ctd_releasebuffer; #else /* The read buffer function. */ sipBufferFunc ctd_readbuffer; /* The write buffer function. */ sipBufferFunc ctd_writebuffer; /* The segment count function. */ sipSegCountFunc ctd_segcount; /* The char buffer function. */ sipBufferFunc ctd_charbuffer; #endif /* The deallocation function. */ sipDeallocFunc ctd_dealloc; /* The optional assignment function. */ sipAssignFunc ctd_assign; /* The optional array allocation function. */ sipArrayFunc ctd_array; /* The optional copy function. */ sipCopyFunc ctd_copy; /* The release function, 0 if a C 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; /* * The information describing an imported module. */ typedef struct _sipImportedModuleDef { /* The module name. */ const char *im_name; /* The required version. */ int im_version; /* The imported module. */ struct _sipExportedModuleDef *im_module; } sipImportedModuleDef; /* * The main client module structure. */ typedef struct _sipExportedModuleDef { /* The next in the list. */ struct _sipExportedModuleDef *em_next; /* The SIP API minor version number. */ unsigned em_api_minor; /* The module name. */ int em_name; /* The module name as an object. */ PyObject *em_nameobj; /* The module version. */ int em_version; /* The string pool. */ const char *em_strings; /* The imported modules. */ sipImportedModuleDef *em_imports; /* The optional Qt support API. */ struct _sipQtAPI *em_qt_api; /* The number of types. */ int em_nrtypes; /* The table of types. */ sipTypeDef **em_types; /* The table of external types. */ sipExternalTypeDef *em_external; /* The number of members in global enums. */ int em_nrenummembers; /* The table of members in global enums. */ sipEnumMemberDef *em_enummembers; /* The number of typedefs. */ int em_nrtypedefs; /* The table of typedefs. */ sipTypedefDef *em_typedefs; /* The table of virtual handlers. */ sipVirtHandlerFunc *em_virthandlers; /* The table of virtual error handlers. */ sipVirtErrorHandlerFunc *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. */ typedef struct _sipStringInstanceDef { /* The string name. */ const char *si_name; /* The string value. */ const char *si_val; /* The encoding used, either 'A', 'L', '8' or 'N'. */ char si_encoding; } sipStringInstanceDef; /* * The information describing an int instance to be added to a dictionary. */ typedef struct _sipIntInstanceDef { /* The int name. */ const char *ii_name; /* The int value. */ int ii_val; } sipIntInstanceDef; /* * The information describing a long instance to be added to a dictionary. */ typedef struct _sipLongInstanceDef { /* The long name. */ const char *li_name; /* The long value. */ long li_val; } sipLongInstanceDef; /* * The information describing an unsigned long instance to be added to a * dictionary. */ typedef struct _sipUnsignedLongInstanceDef { /* The unsigned long name. */ const char *uli_name; /* The unsigned long value. */ unsigned long uli_val; } sipUnsignedLongInstanceDef; /* * The information describing a long long instance to be added to a dictionary. */ typedef struct _sipLongLongInstanceDef { /* The long long name. */ const char *lli_name; /* The long long value. */ #if defined(HAVE_LONG_LONG) PY_LONG_LONG lli_val; #else long lli_val; #endif } sipLongLongInstanceDef; /* * The information describing an unsigned long long instance to be added to a * dictionary. */ typedef struct _sipUnsignedLongLongInstanceDef { /* The unsigned long long name. */ const char *ulli_name; /* The unsigned long long value. */ #if defined(HAVE_LONG_LONG) unsigned PY_LONG_LONG ulli_val; #else unsigned long ulli_val; #endif } sipUnsignedLongLongInstanceDef; /* * The information describing a double instance to be added to a dictionary. */ typedef struct _sipDoubleInstanceDef { /* The double name. */ const char *di_name; /* The double value. */ double di_val; } sipDoubleInstanceDef; /* * The information describing a class or enum instance to be added to a * dictionary. */ typedef struct _sipTypeInstanceDef { /* The type instance name. */ const char *ti_name; /* The actual instance. */ void *ti_ptr; /* A pointer to the generated type. */ struct _sipTypeDef **ti_type; /* The wrapping flags. */ int ti_flags; } sipTypeInstanceDef; /* * Define a mapping between a wrapped type identified by a string and the * corresponding Python type. This is deprecated. */ typedef struct _sipStringTypeClassMap { /* The type as a string. */ const char *typeString; /* A pointer to the Python type. */ struct _sipWrapperType **pyType; } sipStringTypeClassMap; /* * Define a mapping between a wrapped type identified by an integer and the * corresponding Python type. This is deprecated. */ typedef struct _sipIntTypeClassMap { /* The type as an integer. */ int typeInt; /* A pointer to the Python type. */ struct _sipWrapperType **pyType; } sipIntTypeClassMap; /* * A Python method's component parts. This allows us to re-create the method * without changing the reference counts of the components. */ typedef struct _sipPyMethod { /* The function. */ PyObject *mfunc; /* Self if it is a bound method. */ PyObject *mself; #if PY_MAJOR_VERSION < 3 /* The class. */ PyObject *mclass; #endif } sipPyMethod; /* * A slot (in the Qt, rather than Python, sense). */ typedef struct _sipSlot { /* Name if a Qt or Python signal. */ char *name; /* Signal or Qt slot object. */ PyObject *pyobj; /* Python slot method, pyobj is NULL. */ sipPyMethod meth; /* A weak reference to the slot, Py_True if pyobj has an extra reference. */ PyObject *weakSlot; } sipSlot; /* * The API exported by the SIP module, ie. pointers to all the data and * functions that can be used by generated code. */ typedef struct _sipAPIDef { /* * This must be the first entry and it's signature must not change so that * version number mismatches can be detected and reported. */ int (*api_export_module)(sipExportedModuleDef *client, unsigned api_major, unsigned api_minor, void *unused); /* * The following are part of the public API. */ PyTypeObject *api_simplewrapper_type; PyTypeObject *api_wrapper_type; PyTypeObject *api_wrappertype_type; PyTypeObject *api_voidptr_type; void (*api_bad_catcher_result)(PyObject *method); void (*api_bad_length_for_slice)(SIP_SSIZE_T seqlen, SIP_SSIZE_T slicelen); PyObject *(*api_build_result)(int *isErr, const char *fmt, ...); PyObject *(*api_call_method)(int *isErr, PyObject *method, const char *fmt, ...); PyObject *(*api_connect_rx)(PyObject *txObj, const char *sig, PyObject *rxObj, const char *slot, int type); SIP_SSIZE_T (*api_convert_from_sequence_index)(SIP_SSIZE_T idx, SIP_SSIZE_T len); int (*api_can_convert_to_type)(PyObject *pyObj, const sipTypeDef *td, int flags); void *(*api_convert_to_type)(PyObject *pyObj, const sipTypeDef *td, PyObject *transferObj, int flags, int *statep, int *iserrp); void *(*api_force_convert_to_type)(PyObject *pyObj, const sipTypeDef *td, PyObject *transferObj, int flags, int *statep, int *iserrp); int (*api_can_convert_to_enum)(PyObject *pyObj, const sipTypeDef *td); void (*api_release_type)(void *cpp, const sipTypeDef *td, int state); PyObject *(*api_convert_from_type)(void *cpp, const sipTypeDef *td, PyObject *transferObj); PyObject *(*api_convert_from_new_type)(void *cpp, const sipTypeDef *td, PyObject *transferObj); PyObject *(*api_convert_from_enum)(int eval, const sipTypeDef *td); int (*api_get_state)(PyObject *transferObj); PyObject *(*api_disconnect_rx)(PyObject *txObj, const char *sig, PyObject *rxObj, const char *slot); void (*api_free)(void *mem); PyObject *(*api_get_pyobject)(void *cppPtr, const sipTypeDef *td); void *(*api_malloc)(size_t nbytes); int (*api_parse_result)(int *isErr, PyObject *method, PyObject *res, const char *fmt, ...); void (*api_trace)(unsigned mask, const char *fmt, ...); void (*api_transfer_back)(PyObject *self); void (*api_transfer_to)(PyObject *self, PyObject *owner); void (*api_transfer_break)(PyObject *self); unsigned long (*api_long_as_unsigned_long)(PyObject *o); PyObject *(*api_convert_from_void_ptr)(void *val); PyObject *(*api_convert_from_const_void_ptr)(const void *val); PyObject *(*api_convert_from_void_ptr_and_size)(void *val, SIP_SSIZE_T size); PyObject *(*api_convert_from_const_void_ptr_and_size)(const void *val, SIP_SSIZE_T size); void *(*api_convert_to_void_ptr)(PyObject *obj); int (*api_export_symbol)(const char *name, void *sym); void *(*api_import_symbol)(const char *name); const sipTypeDef *(*api_find_type)(const char *type); int (*api_register_py_type)(PyTypeObject *type); const sipTypeDef *(*api_type_from_py_type_object)(PyTypeObject *py_type); const sipTypeDef *(*api_type_scope)(const sipTypeDef *td); const char *(*api_resolve_typedef)(const char *name); int (*api_register_attribute_getter)(const sipTypeDef *td, sipAttrGetterFunc getter); int (*api_is_api_enabled)(const char *name, int from, int to); sipErrorState (*api_bad_callable_arg)(int arg_nr, PyObject *arg); void *(*api_get_address)(struct _sipSimpleWrapper *w); void (*api_set_destroy_on_exit)(int); int (*api_enable_autoconversion)(const sipTypeDef *td, int enable); /* * The following are deprecated parts of the public API. */ PyTypeObject *(*api_find_named_enum)(const char *type); const sipMappedType *(*api_find_mapped_type)(const char *type); sipWrapperType *(*api_find_class)(const char *type); sipWrapperType *(*api_map_int_to_class)(int typeInt, const sipIntTypeClassMap *map, int maplen); sipWrapperType *(*api_map_string_to_class)(const char *typeString, const sipStringTypeClassMap *map, int maplen); /* * The following may be used by Qt support code but no other handwritten * code. */ void (*api_free_sipslot)(sipSlot *slot); int (*api_same_slot)(const sipSlot *sp, PyObject *rxObj, const char *slot); void *(*api_convert_rx)(sipWrapper *txSelf, const char *sigargs, PyObject *rxObj, const char *slot, const char **memberp, int flags); PyObject *(*api_invoke_slot)(const sipSlot *slot, PyObject *sigargs); int (*api_save_slot)(sipSlot *sp, PyObject *rxObj, const char *slot); void (*api_clear_any_slot_reference)(sipSlot *slot); int (*api_visit_slot)(sipSlot *slot, visitproc visit, void *arg); /* * The following are not part of the public API. */ int (*api_init_module)(sipExportedModuleDef *client, PyObject *mod_dict); int (*api_parse_args)(PyObject **parseErrp, PyObject *sipArgs, const char *fmt, ...); int (*api_parse_pair)(PyObject **parseErrp, PyObject *arg0, PyObject *arg1, const char *fmt, ...); void (*api_common_dtor)(sipSimpleWrapper *sipSelf); void (*api_no_function)(PyObject *parseErr, const char *func, const char *doc); void (*api_no_method)(PyObject *parseErr, const char *scope, const char *method, const char *doc); void (*api_abstract_method)(const char *classname, const char *method); void (*api_bad_class)(const char *classname); void *(*api_get_cpp_ptr)(sipSimpleWrapper *w, const sipTypeDef *td); void *(*api_get_complex_cpp_ptr)(sipSimpleWrapper *w); PyObject *(*api_is_py_method)(sip_gilstate_t *gil, char *pymc, sipSimpleWrapper *sipSelf, const char *cname, const char *mname); void (*api_call_hook)(const char *hookname); void (*api_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); /* * The following are part of the public API. */ 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); } 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(). */ #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 these * share the same "namespace" as the flags below. */ #define SIP_TEMPORARY 0x0001 /* A temporary instance. */ #define SIP_DERIVED_CLASS 0x0002 /* The instance is derived. */ /* * These flags are specific to the Qt support API. */ #define SIP_SINGLE_SHOT 0x01 /* The connection is single shot. */ /* * Useful macros, not part of the public API. */ #define SIP_PY_OWNED 0x0004 /* If owned by Python. */ #define SIP_INDIRECT 0x0008 /* If there is a level of indirection. */ #define SIP_ACCFUNC 0x0010 /* If there is an access function. */ #define SIP_NOT_IN_MAP 0x0020 /* If Python object is not in the map. */ #define SIP_SHARE_MAP 0x0040 /* If the map slot might be occupied. */ #define SIP_CPP_HAS_REF 0x0080 /* If C/C++ has a reference. */ #define SIP_POSSIBLE_PROXY 0x0100 /* If there might be a proxy slot. */ #define SIP_ALIAS 0x0200 /* If it is an alias. */ #define SIP_CREATED 0x0400 /* If the C/C++ object has been created. */ #define sipIsPyOwned(w) ((w)->flags & SIP_PY_OWNED) #define sipSetPyOwned(w) ((w)->flags |= SIP_PY_OWNED) #define sipResetPyOwned(w) ((w)->flags &= ~SIP_PY_OWNED) #define sipIsDerived(w) ((w)->flags & SIP_DERIVED_CLASS) #define sipIsIndirect(w) ((w)->flags & SIP_INDIRECT) #define sipIsAccessFunc(w) ((w)->flags & SIP_ACCFUNC) #define sipNotInMap(w) ((w)->flags & SIP_NOT_IN_MAP) #define sipSetNotInMap(w) ((w)->flags |= SIP_NOT_IN_MAP) #define sipCppHasRef(w) ((w)->flags & SIP_CPP_HAS_REF) #define sipSetCppHasRef(w) ((w)->flags |= SIP_CPP_HAS_REF) #define sipResetCppHasRef(w) ((w)->flags &= ~SIP_CPP_HAS_REF) #define sipPossibleProxy(w) ((w)->flags & SIP_POSSIBLE_PROXY) #define sipSetPossibleProxy(w) ((w)->flags |= SIP_POSSIBLE_PROXY) #define sipIsAlias(w) ((w)->flags & SIP_ALIAS) #define sipWasCreated(w) ((w)->flags & SIP_CREATED) #define SIP_TYPE_TYPE_MASK 0x0007 /* The type type mask. */ #define SIP_TYPE_CLASS 0x0000 /* If the type is a C++ class. */ #define SIP_TYPE_NAMESPACE 0x0001 /* If the type is a C++ namespace. */ #define SIP_TYPE_MAPPED 0x0002 /* If the type is a mapped type. */ #define SIP_TYPE_ENUM 0x0003 /* If the type is a named enum. */ #define SIP_TYPE_ABSTRACT 0x0008 /* If the type is abstract. */ #define SIP_TYPE_SCC 0x0010 /* If the type is subject to sub-class convertors. */ #define SIP_TYPE_ALLOW_NONE 0x0020 /* If the type can handle None. */ #define SIP_TYPE_STUB 0x0040 /* If the type is a stub. */ #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. */ /* * The following are part of the public API. */ #define sipTypeIsClass(td) (((td)->td_flags & SIP_TYPE_TYPE_MASK) == SIP_TYPE_CLASS) #define sipTypeIsNamespace(td) (((td)->td_flags & SIP_TYPE_TYPE_MASK) == SIP_TYPE_NAMESPACE) #define sipTypeIsMapped(td) (((td)->td_flags & SIP_TYPE_TYPE_MASK) == SIP_TYPE_MAPPED) #define sipTypeIsEnum(td) (((td)->td_flags & SIP_TYPE_TYPE_MASK) == SIP_TYPE_ENUM) #define sipTypeAsPyTypeObject(td) ((td)->u.td_py_type) #define sipTypeName(td) sipNameFromPool((td)->td_module, (td)->td_cname) #define sipIsExactWrappedType(wt) (sipTypeAsPyTypeObject((wt)->type) == (PyTypeObject *)(wt)) #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) /* * Get various names from the string pool for various data types. */ #define sipNameFromPool(em, mr) (&((em)->em_strings)[(mr)]) #define sipNameOfModule(em) sipNameFromPool((em), (em)->em_name) #define sipPyNameOfContainer(cod, td) sipNameFromPool((td)->td_module, (cod)->cod_name) #define sipPyNameOfEnum(etd) sipNameFromPool((etd)->etd_base.td_module, (etd)->etd_name) /* * The following are PyQt3-specific extensions. In SIP v5 they will be pushed * out to a plugin supplied by PyQt3. */ /* * Maps the name of a Qt signal to a wrapper function to emit it. */ typedef int (*pyqt3EmitFunc)(sipSimpleWrapper *, PyObject *); typedef struct _pyqt3QtSignal { /* The signal name. */ const char *st_name; /* The emitter function. */ pyqt3EmitFunc st_emitfunc; } pyqt3QtSignal; /* * This is the PyQt3-specific extension to the generated class type structure. */ typedef struct _pyqt3ClassTypeDef { /* * The super-type structure. This must be first in the structure so that * it can be cast to sipClassTypeDef *. */ sipClassTypeDef super; /* The emit table for Qt signals. */ pyqt3QtSignal *qt3_emit; } pyqt3ClassTypeDef; /* * The following are PyQt4-specific extensions. In SIP v5 they will be pushed * out to a plugin supplied by PyQt4. */ /* * The description of a Qt signal for PyQt4. */ typedef struct _pyqt4QtSignal { /* The C++ name and signature of the signal. */ const char *signature; /* The optional docstring. */ const char *docstring; /* * If the signal is an overload of regular methods then this points to the * code that implements those methods. */ PyMethodDef *non_signals; /* * 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 _pyqt4ClassTypeDef { /* * The super-type structure. This must be first in the structure so that * it can be cast to sipClassTypeDef *. */ sipClassTypeDef super; /* A pointer to the QObject sub-class's staticMetaObject class variable. */ const void *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; } pyqt4ClassTypeDef; /* * 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 _pyqt5ClassTypeDef { /* * The super-type structure. This must be first in the structure so that * it can be cast to sipClassTypeDef *. */ sipClassTypeDef super; /* A pointer to the QObject sub-class's staticMetaObject class variable. */ const void *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; } pyqt5ClassTypeDef; #ifdef __cplusplus } #endif #endif sip-4.15.5/siplib/sipint.h0000644000076500000240000001223512261241130015414 0ustar philstaff00000000000000/* * This file defines the SIP library internal interfaces. * * Copyright (c) 2014 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 #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); 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_common_dtor(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); unsigned long sip_api_long_as_unsigned_long(PyObject *o); int sip_api_same_slot(const sipSlot *sp, PyObject *rxObj, const char *slot); PyObject *sip_api_invoke_slot(const sipSlot *slot, PyObject *sigargs); void *sip_api_convert_rx(sipWrapper *txSelf, const char *sigargs, PyObject *rxObj, const char *slot, const char **memberp, int flags); int sip_api_save_slot(sipSlot *sp, PyObject *rxObj, const char *slot); /* * These are not part of the SIP API but are used within the SIP module. */ 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.15.5/siplib/siplib.c.in0000644000076500000240000115342612310312545016005 0ustar philstaff00000000000000/* * SIP library code. * * Copyright (c) 2014 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 "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_reserved (Python v3), tp_compare (Python v2) */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ sipWrapperType_getattro, /* tp_getattro */ sipWrapperType_setattro, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)sipWrapperType_init, /* tp_init */ sipWrapperType_alloc, /* tp_alloc */ 0, /* tp_new */ 0, /* tp_free */ }; /* * The Python type that is the super-type for all C++ wrapper types that * support parent/child relationships. */ static int sipWrapper_clear(sipWrapper *self); static void sipWrapper_dealloc(sipWrapper *self); static int sipWrapper_traverse(sipWrapper *self, visitproc visit, void *arg); static sipWrapperType sipWrapper_Type = { #if !defined(STACKLESS) { #endif { PyVarObject_HEAD_INIT(&sipWrapperType_Type, 0) "sip.wrapper", /* tp_name */ sizeof (sipWrapper), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)sipWrapper_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved (Python v3), tp_compare (Python v2) */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ (traverseproc)sipWrapper_traverse, /* tp_traverse */ (inquiry)sipWrapper_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ 0, /* tp_free */ }, #if !defined(STACKLESS) }, #endif 0, 0 }; static void sip_api_bad_catcher_result(PyObject *method); static void sip_api_bad_length_for_slice(SIP_SSIZE_T seqlen, SIP_SSIZE_T slicelen); static PyObject *sip_api_build_result(int *isErr, const char *fmt, ...); static PyObject *sip_api_call_method(int *isErr, PyObject *method, const char *fmt, ...); static SIP_SSIZE_T sip_api_convert_from_sequence_index(SIP_SSIZE_T idx, SIP_SSIZE_T len); static int sip_api_can_convert_to_type(PyObject *pyObj, const sipTypeDef *td, int flags); static void *sip_api_convert_to_type(PyObject *pyObj, const sipTypeDef *td, PyObject *transferObj, int flags, int *statep, int *iserrp); static int sip_api_can_convert_to_enum(PyObject *pyObj, const sipTypeDef *td); static void sip_api_release_type(void *cpp, const sipTypeDef *td, int state); static PyObject *sip_api_convert_from_new_type(void *cpp, const sipTypeDef *td, PyObject *transferObj); static 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 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); /* * The data structure that represents the SIP API. */ static const sipAPIDef sip_api = { /* This must be first. */ sip_api_export_module, /* * The following are part of the public API. */ (PyTypeObject *)&sipSimpleWrapper_Type, (PyTypeObject *)&sipWrapper_Type, &sipWrapperType_Type, &sipVoidPtr_Type, sip_api_bad_catcher_result, sip_api_bad_length_for_slice, sip_api_build_result, sip_api_call_method, sip_api_connect_rx, sip_api_convert_from_sequence_index, sip_api_can_convert_to_type, sip_api_convert_to_type, sip_api_force_convert_to_type, sip_api_can_convert_to_enum, sip_api_release_type, sip_api_convert_from_type, sip_api_convert_from_new_type, sip_api_convert_from_enum, sip_api_get_state, sip_api_disconnect_rx, sip_api_free, sip_api_get_pyobject, sip_api_malloc, sip_api_parse_result, sip_api_trace, sip_api_transfer_back, sip_api_transfer_to, sip_api_transfer_break, sip_api_long_as_unsigned_long, sip_api_convert_from_void_ptr, sip_api_convert_from_const_void_ptr, sip_api_convert_from_void_ptr_and_size, sip_api_convert_from_const_void_ptr_and_size, sip_api_convert_to_void_ptr, sip_api_export_symbol, sip_api_import_symbol, sip_api_find_type, sip_api_register_py_type, sip_api_type_from_py_type_object, sip_api_type_scope, sip_api_resolve_typedef, sip_api_register_attribute_getter, sip_api_is_api_enabled, sip_api_bad_callable_arg, sip_api_get_address, sip_api_set_destroy_on_exit, sip_api_enable_autoconversion, /* * The following are deprecated parts of the public API. */ sip_api_find_named_enum, sip_api_find_mapped_type, sip_api_find_class, sip_api_map_int_to_class, sip_api_map_string_to_class, /* * The following may be used by Qt support code but by no other handwritten * code. */ sip_api_free_sipslot, sip_api_same_slot, sip_api_convert_rx, sip_api_invoke_slot, sip_api_save_slot, sip_api_clear_any_slot_reference, sip_api_visit_slot, /* * The following are not part of the public API. */ sip_api_init_module, sip_api_parse_args, sip_api_parse_pair, sip_api_common_dtor, sip_api_no_function, sip_api_no_method, sip_api_abstract_method, sip_api_bad_class, sip_api_get_cpp_ptr, sip_api_get_complex_cpp_ptr, sip_api_is_py_method, sip_api_call_hook, sip_api_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, /* * The following are part of the public API. */ 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, }; #define AUTO_DOCSTRING '\1' /* Marks an auto class docstring. */ /* * These are the format flags supported by argument parsers. */ #define FMT_AP_DEREF 0x01 /* The pointer will be dereferenced. */ #define FMT_AP_TRANSFER 0x02 /* Implement /Transfer/. */ #define FMT_AP_TRANSFER_BACK 0x04 /* Implement /TransferBack/. */ #define FMT_AP_NO_CONVERTORS 0x08 /* Suppress any convertors. */ #define FMT_AP_TRANSFER_THIS 0x10 /* Support for /TransferThis/. */ /* * These are the format flags supported by result parsers. Deprecated values * have a _DEPR suffix. */ #define FMT_RP_DEREF 0x01 /* The pointer will be dereferenced. */ #define FMT_RP_FACTORY 0x02 /* /Factory/ or /TransferBack/. */ #define FMT_RP_MAKE_COPY 0x04 /* Return a copy of the value. */ #define FMT_RP_NO_STATE_DEPR 0x04 /* Don't return the C/C++ state. */ /* * The different reasons for failing to parse an overload. These include * internal (i.e. non-user) errors. */ typedef enum { Ok, Unbound, TooFew, TooMany, UnknownKeyword, Duplicate, WrongType, Raised, KeywordNotString, Exception } sipParseFailureReason; /* * The description of a failure to parse an overload because of a user error. */ typedef struct _sipParseFailure { sipParseFailureReason reason; /* The reason for the failure. */ const char *detail_str; /* The detail if a string. */ PyObject *detail_obj; /* The detail if a Python object. */ int arg_nr; /* The wrong positional argument. */ const char *arg_name; /* The wrong keyword argument. */ } sipParseFailure; /* * An entry in a linked list of name/symbol pairs. */ typedef struct _sipSymbol { const char *name; /* The name. */ void *symbol; /* The symbol. */ struct _sipSymbol *next; /* The next in the list. */ } sipSymbol; /* * An entry in a linked list of Python objects. */ typedef struct _sipPyObject { PyObject *object; /* The Python object. */ struct _sipPyObject *next; /* The next in the list. */ } sipPyObject; /* * An entry in the linked list of attribute getters. */ typedef struct _sipAttrGetter { PyTypeObject *type; /* The Python type being handled. */ sipAttrGetterFunc getter; /* The getter. */ struct _sipAttrGetter *next; /* The next in the list. */ } sipAttrGetter; /* * 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; /***************************************************************************** * The structures to support a Python type to hold a named enum. *****************************************************************************/ static PyObject *sipEnumType_alloc(PyTypeObject *self, SIP_SSIZE_T nitems); /* * The type data structure. We inherit everything from the standard Python * metatype and the size of the type object created is increased to accomodate * the extra information we associate with a named enum type. */ static PyTypeObject sipEnumType_Type = { PyVarObject_HEAD_INIT(NULL, 0) "sip.enumtype", /* tp_name */ sizeof (sipEnumTypeObject), /* tp_basicsize */ 0, /* tp_itemsize */ 0, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved (Python v3), tp_compare (Python v2) */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ sipEnumType_alloc, /* tp_alloc */ 0, /* tp_new */ 0, /* tp_free */ }; /* * 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 void addClassSlots(sipWrapperType *wt, const sipClassTypeDef *ctd); static void addTypeSlots(PyHeapTypeObject *heap_to, sipPySlotDef *slots); static void *findSlot(PyObject *self, sipPySlotType st); static void *findSlotInType(sipPySlotDef *psd, sipPySlotType st); static int objobjargprocSlot(PyObject *self, PyObject *arg1, PyObject *arg2, sipPySlotType st); static int ssizeobjargprocSlot(PyObject *self, SIP_SSIZE_T arg1, PyObject *arg2, sipPySlotType st); static PyObject *buildObject(PyObject *tup, const char *fmt, va_list va); static int parseKwdArgs(PyObject **parseErrp, PyObject *sipArgs, PyObject *sipKwdArgs, const char **kwdlist, PyObject **unused, const char *fmt, va_list va_orig); static int parsePass1(PyObject **parseErrp, sipSimpleWrapper **selfp, int *selfargp, PyObject *sipArgs, PyObject *sipKwdArgs, const char **kwdlist, PyObject **unused, const char *fmt, va_list va); static int parsePass2(sipSimpleWrapper *self, int selfarg, PyObject *sipArgs, PyObject *sipKwdArgs, const char **kwdlist, const char *fmt, va_list va); static 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 PyObject *createEnumMember(sipTypeDef *td, sipEnumMemberDef *enm); static int compareTypedefName(const void *key, const void *el); static int checkPointer(void *ptr, sipSimpleWrapper *sw); static void *cast_cpp_ptr(void *ptr, PyTypeObject *src_type, const sipTypeDef *dst_type); static void finalise(void); static PyObject *getDefaultBases(void); static PyObject *getScopeDict(sipTypeDef *td, PyObject *mod_dict, sipExportedModuleDef *client); static PyObject *createContainerType(sipContainerDef *cod, sipTypeDef *td, PyObject *bases, PyObject *metatype, PyObject *mod_dict, 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 *); static PyObject *unpickle_type(PyObject *, PyObject *args); static PyObject *pickle_enum(PyObject *obj, PyObject *); static PyObject *unpickle_enum(PyObject *, PyObject *args); static int setReduce(PyTypeObject *type, PyMethodDef *pickler); static int createEnumType(sipExportedModuleDef *client, sipEnumTypeDef *etd, PyObject *mod_dict); static PyObject *createTypeDict(sipExportedModuleDef *em); static sipExportedModuleDef *getTypeModule(const sipEncodedTypeDef *enc, sipExportedModuleDef *em); static sipTypeDef *getGeneratedType(const sipEncodedTypeDef *enc, sipExportedModuleDef *em); static const sipTypeDef *convertSubClass(const sipTypeDef *td, void **cppPtr); static 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 *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 *obj, PyObject *ignore); 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 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); /* * 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[] = { {"cast", cast, METH_VARARGS, NULL}, {"delete", callDtor, METH_VARARGS, NULL}, {"dump", dumpWrapper, METH_VARARGS, NULL}, {"enableautoconversion", enableAutoconversion, 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 > 11 #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 intialise sip module"); mod_dict = PyModule_GetDict(mod); /* Get a reference to the pickle helpers. */ type_unpickler = PyDict_GetItemString(mod_dict, "_unpickle_type"); enum_unpickler = PyDict_GetItemString(mod_dict, "_unpickle_enum"); if (type_unpickler == NULL || enum_unpickler == NULL) { SIP_MODULE_DISCARD(mod); SIP_FATAL(SIP_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 are notified when starting to exit. */ register_exit_notifier(); SIP_MODULE_RETURN(mod); } /* * Display a printf() style message to stderr according to the current trace * mask. */ static void sip_api_trace(unsigned mask, const char *fmt, ...) { va_list ap; va_start(ap,fmt); if (mask & traceMask) vfprintf(stderr, fmt, ap); va_end(ap); } /* * Set the trace mask. */ static PyObject *setTraceMask(PyObject *self, PyObject *args) { unsigned new_mask; if (PyArg_ParseTuple(args, "I:settracemask", &new_mask)) { traceMask = new_mask; Py_INCREF(Py_None); return Py_None; } return NULL; } /* * Dump various bits of potentially useful information to stdout. */ static PyObject *dumpWrapper(PyObject *self, PyObject *args) { sipSimpleWrapper *sw; if (PyArg_ParseTuple(args, "O!:dump", &sipSimpleWrapper_Type, &sw)) { print_object(NULL, (PyObject *)sw); #if PY_VERSION_HEX >= 0x02050000 printf(" Reference count: %" PY_FORMAT_SIZE_T "d\n", Py_REFCNT(sw)); #else printf(" Reference count: %d\n", Py_REFCNT(sw)); #endif printf(" Address of wrapped object: %p\n", 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; 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; if (PyArg_ParseTuple(args, "O!:transferback", &sipWrapper_Type, &w)) { sip_api_transfer_back(w); Py_INCREF(Py_None); return Py_None; } return NULL; } /* * Cast an instance to one of it's sub or super-classes by returning a new * Python object with the superclass type wrapping the same C++ instance. */ static PyObject *cast(PyObject *self, PyObject *args) { sipSimpleWrapper *sw; sipWrapperType *wt; const sipTypeDef *td; void *addr; PyTypeObject *ft, *tt; if (!PyArg_ParseTuple(args, "O!O!:cast", &sipSimpleWrapper_Type, &sw, &sipWrapperType_Type, &wt)) return NULL; ft = Py_TYPE(sw); tt = (PyTypeObject *)wt; if (ft == tt || PyType_IsSubtype(tt, ft)) td = NULL; else if (PyType_IsSubtype(ft, tt)) td = wt->type; else { PyErr_SetString(PyExc_TypeError, "argument 1 of 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->type, NULL, (sw->flags | SIP_NOT_IN_MAP) & ~SIP_PY_OWNED); } /* * Call an instance's dtor. */ static PyObject *callDtor(PyObject *self, PyObject *args) { sipSimpleWrapper *sw; void *addr; const sipClassTypeDef *ctd; if (!PyArg_ParseTuple(args, "O!:delete", &sipSimpleWrapper_Type, &sw)) return NULL; addr = getPtrTypeDef(sw, &ctd); if (checkPointer(addr, sw) < 0) return NULL; if (PyObject_TypeCheck((PyObject *)sw, (PyTypeObject *)&sipWrapper_Type)) { /* * Transfer ownership to C++ so we don't try to release it again when * the Python object is garbage collected. */ removeFromParent((sipWrapper *)sw); sipResetPyOwned(sw); } release(addr, (const sipTypeDef *)ctd, sw->flags); Py_INCREF(Py_None); return Py_None; } /* * Check if an instance still exists without raising an exception. */ static PyObject *isDeleted(PyObject *self, PyObject *args) { sipSimpleWrapper *sw; PyObject *res; if (!PyArg_ParseTuple(args, "O!:isdeleted", &sipSimpleWrapper_Type, &sw)) return NULL; res = (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; 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; if (!PyArg_ParseTuple(args, "O!:ispyowned", &sipSimpleWrapper_Type, &sw)) return NULL; res = (sipIsPyOwned(sw) ? Py_True : Py_False); Py_INCREF(res); return res; } /* * Mark an instance as having been deleted. */ static PyObject *setDeleted(PyObject *self, PyObject *args) { sipSimpleWrapper *sw; if (!PyArg_ParseTuple(args, "O!:setdeleted", &sipSimpleWrapper_Type, &sw)) return NULL; if (PyObject_TypeCheck((PyObject *)sw, (PyTypeObject *)&sipWrapper_Type)) { /* * Transfer ownership to C++ so we don't try to release it when the * Python object is garbage collected. */ removeFromParent((sipWrapper *)sw); sipResetPyOwned(sw); } clear_access_func(sw); Py_INCREF(Py_None); return Py_None; } /* * Unwrap an instance. */ static PyObject *unwrapInstance(PyObject *self, PyObject *args) { sipSimpleWrapper *sw; if (PyArg_ParseTuple(args, "O!:unwrapinstance", &sipSimpleWrapper_Type, &sw)) { void *addr; /* * We just get the pointer but don't try and cast it (which isn't * needed and wouldn't work with the way casts are currently * implemented if we are unwrapping something derived from a wrapped * class). */ if ((addr = sip_api_get_cpp_ptr(sw, NULL)) == NULL) return NULL; return PyLong_FromVoidPtr(addr); } return NULL; } /* * Wrap an instance. */ static PyObject *wrapInstance(PyObject *self, PyObject *args) { unsigned PY_LONG_LONG addr; sipWrapperType *wt; if (PyArg_ParseTuple(args, "KO!:wrapinstance", &addr, &sipWrapperType_Type, &wt)) return sip_api_convert_from_type((void *)addr, wt->type, NULL); return NULL; } /* * Set the destroy on exit flag from Python code. */ static PyObject *setDestroyOnExit(PyObject *self, PyObject *args) { 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); /* Check that we can support it. */ if (api_major != SIP_API_MAJOR_NR || api_minor > SIP_API_MINOR_NR) { #if SIP_API_MINOR_NR > 0 PyErr_Format(PyExc_RuntimeError, "the sip module implements API v%d.0 to v%d.%d but the %s module requires API v%d.%d", SIP_API_MAJOR_NR, SIP_API_MAJOR_NR, SIP_API_MINOR_NR, full_name, api_major, api_minor); #else PyErr_Format(PyExc_RuntimeError, "the sip module implements API v%d.0 but the %s module requires API v%d.%d", SIP_API_MAJOR_NR, full_name, api_major, api_minor); #endif return -1; } /* Import any required modules. */ if (client->em_imports != NULL) { sipImportedModuleDef *im = client->em_imports; while (im->im_name != NULL) { PyObject *mod; if ((mod = PyImport_ImportModule(im->im_name)) == NULL) return -1; for (em = moduleList; em != NULL; em = em->em_next) if (strcmp(sipNameOfModule(em), im->im_name) == 0) break; if (em == NULL) { PyErr_Format(PyExc_RuntimeError, "the %s module failed to register with the sip module", im->im_name); return -1; } /* Check the versions are compatible. */ if (im->im_version >= 0 || em->em_version >= 0) if (im->im_version != em->em_version) { PyErr_Format(PyExc_RuntimeError, "the %s module is version %d but the %s module requires version %d", sipNameOfModule(em), em->em_version, full_name, im->im_version); return -1; } /* Save the imported module. */ im->im_module = em; ++im; } } for (em = moduleList; em != NULL; em = em->em_next) { /* SIP clients must have unique names. */ if (strcmp(sipNameOfModule(em), full_name) == 0) { PyErr_Format(PyExc_RuntimeError, "the sip module has already registered a module called %s", full_name); return -1; } /* Only one module can claim to wrap QObject. */ if (em->em_qt_api != NULL && client->em_qt_api != NULL) { PyErr_Format(PyExc_RuntimeError, "the %s and %s modules both wrap the QObject class", full_name, sipNameOfModule(em)); return -1; } } /* Convert the module name to an object. */ #if PY_MAJOR_VERSION >= 3 client->em_nameobj = PyUnicode_FromString(full_name); #else client->em_nameobj = PyString_FromString(full_name); #endif if (client->em_nameobj == NULL) return -1; /* Add it to the list of client modules. */ client->em_next = moduleList; moduleList = client; /* 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)) { sipEnumTypeDef *etd = (sipEnumTypeDef *)td; if (td->td_version < 0 || sipIsRangeEnabled(client, td->td_version)) if (createEnumType(client, etd, mod_dict) < 0) return -1; /* * Register the enum pickler for scoped enums (unscoped, ie. those * not nested, don't need special treatment). */ if (etd->etd_scope >= 0) { static PyMethodDef md = { "_pickle_enum", pickle_enum, METH_NOARGS, NULL }; if (setReduce(sipTypeAsPyTypeObject(td), &md) < 0) return -1; } } else if (sipTypeIsMapped(td)) { sipMappedTypeDef *mtd = (sipMappedTypeDef *)td; /* If there is a name then we need a namespace. */ if (mtd->mtd_container.cod_name >= 0) { if (createMappedType(client, mtd, mod_dict) < 0) return -1; } else { td->td_module = client; } } else { sipClassTypeDef *ctd = (sipClassTypeDef *)td; /* See if this is a namespace extender. */ if (ctd->ctd_container.cod_name < 0) { sipTypeDef *real_nspace; sipClassTypeDef **last; ctd->ctd_base.td_module = client; real_nspace = getGeneratedType(&ctd->ctd_container.cod_scope, client); /* Append this type to the real one. */ last = &((sipClassTypeDef *)real_nspace)->ctd_nsextender; while (*last != NULL) last = &(*last)->ctd_nsextender; *last = ctd; /* * Save the real namespace type so that it is the correct scope * for any enums or classes defined in this module. */ client->em_types[i] = real_nspace; } else if (createClassType(client, ctd, mod_dict) < 0) return -1; } } /* Set any Qt support API. */ if (client->em_qt_api != NULL) { sipQtSupport = client->em_qt_api; sipQObjectType = *sipQtSupport->qt_qobject; } /* Append any initialiser extenders to the relevant classes. */ if (client->em_initextend != NULL) { sipInitExtenderDef *ie = client->em_initextend; while (ie->ie_extender != NULL) { sipTypeDef *td = getGeneratedType(&ie->ie_class, client); int enabled; if (ie->ie_api_range < 0) enabled = TRUE; else enabled = sipIsRangeEnabled(td->td_module, ie->ie_api_range); if (enabled) { sipWrapperType *wt = (sipWrapperType *)sipTypeAsPyTypeObject(td); ie->ie_next = wt->iextend; wt->iextend = ie; } ++ie; } } /* Set the base class object for any sub-class convertors. */ if (client->em_convertors != NULL) { sipSubClassConvertorDef *scc = client->em_convertors; while (scc->scc_convertor != NULL) { scc->scc_basetype = getGeneratedType(&scc->scc_base, client); ++scc; } } /* Create the module's enum members. */ for (emd = client->em_enummembers, i = 0; i < client->em_nrenummembers; ++i, ++emd) { PyObject *mo; if ((mo = sip_api_convert_from_enum(emd->em_val, client->em_types[emd->em_enum])) == NULL) return -1; if (PyDict_SetItemString(mod_dict, emd->em_name, mo) < 0) return -1; Py_DECREF(mo); } /* * Add any class static instances. We need to do this once all types are * fully formed because of potential interdependencies. */ for (i = 0; i < client->em_nrtypes; ++i) { sipTypeDef *td = client->em_types[i]; if (td != NULL && !sipTypeIsStub(td) && sipTypeIsClass(td)) if (addInstances((sipTypeAsPyTypeObject(td))->tp_dict, &((sipClassTypeDef *)td)->ctd_container.cod_instances) < 0) return -1; } /* Add any global static instances. */ if (addInstances(mod_dict, &client->em_instances) < 0) return -1; /* Add any license. */ if (client->em_license != NULL && addLicense(mod_dict, client->em_license) < 0) return -1; /* See if the new module satisfies any outstanding external types. */ for (em = moduleList; em != NULL; em = em->em_next) { sipExternalTypeDef *etd; if (em == client || em->em_external == NULL) continue; for (etd = em->em_external; etd->et_nr >= 0; ++etd) { if (etd->et_name == NULL) continue; for (i = 0; i < client->em_nrtypes; ++i) { sipTypeDef *td = client->em_types[i]; if (td != NULL && !sipTypeIsStub(td) && sipTypeIsClass(td)) { const char *pyname = sipPyNameOfContainer( &((sipClassTypeDef *)td)->ctd_container, td); if (strcmp(etd->et_name, pyname) == 0) { em->em_types[etd->et_nr] = td; etd->et_name = NULL; break; } } } } } return 0; } /* * Called by the interpreter to do any final clearing up, just in case the * interpreter will re-start. */ static void finalise(void) { sipExportedModuleDef *em; /* * Mark the Python API as unavailable. 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 the Python re-implementation of a C++ virtual. */ static PyObject *sip_api_call_method(int *isErr, PyObject *method, const char *fmt, ...) { PyObject *args, *res; va_list va; va_start(va,fmt); if ((args = PyTuple_New(strlen(fmt))) != NULL && buildObject(args,fmt,va) != NULL) res = PyEval_CallObject(method,args); else { res = NULL; if (isErr != NULL) *isErr = TRUE; } Py_XDECREF(args); va_end(va); return res; } /* * Build a result object based on a format string. */ static PyObject *sip_api_build_result(int *isErr, const char *fmt, ...) { PyObject *res = NULL; int badfmt, tupsz; va_list va; va_start(va,fmt); /* Basic validation of the format string. */ badfmt = FALSE; if (*fmt == '(') { char *ep; if ((ep = strchr(fmt,')')) == NULL || ep[1] != '\0') badfmt = TRUE; else tupsz = ep - fmt - 1; } else if (strlen(fmt) == 1) tupsz = -1; else badfmt = TRUE; if (badfmt) PyErr_Format(PyExc_SystemError,"sipBuildResult(): invalid format string \"%s\"",fmt); else if (tupsz < 0 || (res = PyTuple_New(tupsz)) != NULL) res = buildObject(res,fmt,va); va_end(va); if (res == NULL && isErr != NULL) *isErr = TRUE; return res; } /* * Get the values off the stack and put them into an object. */ static PyObject *buildObject(PyObject *obj, const char *fmt, va_list va) { char ch, termch; int i; /* * The format string has already been checked that it is properly formed if * it is enclosed in parenthesis. */ if (*fmt == '(') { termch = ')'; ++fmt; } else termch = '\0'; i = 0; while ((ch = *fmt++) != termch) { PyObject *el; switch (ch) { case 'g': { char *s; SIP_SSIZE_T l; s = va_arg(va, char *); l = va_arg(va, SIP_SSIZE_T); if (s != NULL) { el = SIPBytes_FromStringAndSize(s, l); } else { Py_INCREF(Py_None); el = Py_None; } } break; case 'G': #if defined(HAVE_WCHAR_H) { wchar_t *s; SIP_SSIZE_T l; s = va_arg(va, wchar_t *); l = va_arg(va, SIP_SSIZE_T); if (s != NULL) el = PyUnicode_FromWideChar(s, l); else { Py_INCREF(Py_None); el = Py_None; } } #else raiseNoWChar(); el = NULL; #endif break; case 'b': el = PyBool_FromLong(va_arg(va,int)); break; case 'c': { char c = va_arg(va, int); el = SIPBytes_FromStringAndSize(&c, 1); } break; case 'a': { char c = va_arg(va, int); #if PY_MAJOR_VERSION >= 3 el = PyUnicode_FromStringAndSize(&c, 1); #else el = PyString_FromStringAndSize(&c, 1); #endif } break; case 'w': #if defined(HAVE_WCHAR_H) { wchar_t c = va_arg(va, int); el = PyUnicode_FromWideChar(&c, 1); } #else raiseNoWChar(); el = NULL; #endif break; case 'E': { /* This is deprecated. */ int ev = va_arg(va, int); PyTypeObject *et = va_arg(va, PyTypeObject *); el = sip_api_convert_from_enum(ev, ((const sipEnumTypeObject *)et)->type); } break; case 'F': { int ev = va_arg(va, int); const sipTypeDef *td = va_arg(va, const sipTypeDef *); el = sip_api_convert_from_enum(ev, td); } break; case 'd': case 'f': el = PyFloat_FromDouble(va_arg(va, double)); break; case 'e': case 'h': case 'i': 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->type, xfer); } break; case 'N': { void *p = va_arg(va, void *); const sipTypeDef *td = va_arg(va, const sipTypeDef *); PyObject *xfer = va_arg(va, PyObject *); el = sip_api_convert_from_new_type(p, td, xfer); } break; case 'C': { /* This is deprecated. */ void *p = va_arg(va,void *); sipWrapperType *wt = va_arg(va, sipWrapperType *); PyObject *xfer = va_arg(va, PyObject *); el = sip_api_convert_from_type(p, wt->type, xfer); } break; case 'D': { void *p = va_arg(va, void *); const sipTypeDef *td = va_arg(va, const sipTypeDef *); PyObject *xfer = va_arg(va, PyObject *); el = sip_api_convert_from_type(p, td, xfer); } break; case 'r': { void *p = va_arg(va, void *); SIP_SSIZE_T l = va_arg(va, SIP_SSIZE_T); const sipTypeDef *td = va_arg(va, const sipTypeDef *); el = convertToSequence(p, l, td); } break; case 'R': el = va_arg(va,PyObject *); break; case 'S': el = va_arg(va,PyObject *); Py_INCREF(el); break; case 'V': el = sip_api_convert_from_void_ptr(va_arg(va, void *)); break; 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 = SIPLong_AsLong(arg); if (PyErr_Occurred()) 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 *); if (sip_api_can_convert_to_enum(arg, ((sipEnumTypeObject *)et)->type)) { if (p != NULL) *p = SIPLong_AsLong(arg); } else { invalid = TRUE; } } break; case 'F': { sipTypeDef *td = va_arg(va, sipTypeDef *); int *p = va_arg(va, int *); if (sip_api_can_convert_to_enum(arg, td)) { if (p != NULL) *p = SIPLong_AsLong(arg); } else { invalid = TRUE; } } break; case 'f': { float *p = va_arg(va, float *); float v = 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 = SIPLong_AsLong(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_long(arg); if (PyErr_Occurred()) invalid = TRUE; else if (p != NULL) *p = v; } break; case 'h': { short *p = va_arg(va, short *); short v = SIPLong_AsLong(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_long(arg); if (PyErr_Occurred()) invalid = TRUE; else if (p != NULL) *p = v; } break; case 'e': case 'i': { int *p = va_arg(va, int *); int v = SIPLong_AsLong(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_long(arg); if (PyErr_Occurred()) invalid = TRUE; else if (p != NULL) *p = v; } break; case 'l': { long *p = va_arg(va, long *); long v = PyLong_AsLong(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 = PyLong_AsLongLong(arg); #else long *p = va_arg(va, long *); long v = PyLong_AsLong(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 = PyLong_AsUnsignedLongLongMask(arg); #else unsigned long *p = va_arg(va, unsigned long *); unsigned long v = PyLong_AsUnsignedLongMask(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->type, (flags & FMT_RP_FACTORY ? arg : NULL), (flags & FMT_RP_DEREF ? SIP_NOT_NONE : 0), state, &iserr); if (iserr) invalid = TRUE; } } break; case 'D': { /* This is deprecated. */ if (*fmt == '\0') { invalid = TRUE; } else { int flags = *fmt++ - '0'; int iserr = FALSE; const sipTypeDef *td; void **cpp; int *state; td = va_arg(va, const sipTypeDef *); if (flags & FMT_RP_NO_STATE_DEPR) state = NULL; else state = va_arg(va, int *); cpp = va_arg(va, void **); *cpp = sip_api_force_convert_to_type(arg, td, (flags & FMT_RP_FACTORY ? arg : NULL), (flags & FMT_RP_DEREF ? SIP_NOT_NONE : 0), state, &iserr); if (iserr) invalid = TRUE; } } break; case 'H': { if (*fmt == '\0') { invalid = TRUE; } else { int flags = *fmt++ - '0'; int iserr = FALSE, state; const sipTypeDef *td; void *cpp, *val; td = va_arg(va, const sipTypeDef *); cpp = va_arg(va, void **); val = sip_api_force_convert_to_type(arg, td, (flags & FMT_RP_FACTORY ? arg : NULL), (flags & FMT_RP_DEREF ? SIP_NOT_NONE : 0), &state, &iserr); if (iserr) { invalid = TRUE; } else if (flags & FMT_RP_MAKE_COPY) { sipAssignFunc assign_helper; if (sipTypeIsMapped(td)) assign_helper = ((const sipMappedTypeDef *)td)->mtd_assign; else assign_helper = ((const sipClassTypeDef *)td)->ctd_assign; assert(assign_helper != NULL); 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); #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; } /* * A thin wrapper around PyLong_AsUnsignedLong() that works around a bug in * Python versions prior to v2.4 where an integer (or a named enum) causes an * error. */ unsigned long sip_api_long_as_unsigned_long(PyObject *o) { #if PY_VERSION_HEX < 0x02040000 if (o != NULL && !PyLong_Check(o) && PyInt_Check(o)) { long v = PyInt_AsLong(o); /* * Strictly speaking this should be changed to be consistent with the * use of PyLong_AsUnsignedLongMask(). However as it's such an old * version of Python we choose to leave it as it is. */ if (v < 0) { PyErr_SetString(PyExc_OverflowError, "can't convert negative value to unsigned long"); return (unsigned long)-1; } return v; } #endif /* * Note that we now ignore any overflow so that (for example) a negative * integer will be converted to an unsigned as C/C++ would do. We don't * bother to check for overflow when converting to small C/C++ types (short * etc.) so at least this is consistent. */ return PyLong_AsUnsignedLongMask(o); } /* * Parse the arguments to a C/C++ function without any side effects. */ static int sip_api_parse_args(PyObject **parseErrp, PyObject *sipArgs, const char *fmt, ...) { int ok; va_list va; va_start(va, fmt); ok = parseKwdArgs(parseErrp, sipArgs, NULL, NULL, NULL, fmt, va); va_end(va); return ok; } /* * Parse the positional and/or keyword arguments to a C/C++ function without * any side effects. */ static int sip_api_parse_kwd_args(PyObject **parseErrp, PyObject *sipArgs, PyObject *sipKwdArgs, const char **kwdlist, PyObject **unused, const char *fmt, ...) { int ok; va_list va; if (unused != NULL) { /* * Initialise the return of any unused keyword arguments. This is * used by any ctor overload. */ *unused = NULL; } else if (sipKwdArgs != NULL && kwdlist == NULL) { PyErr_SetString(PyExc_TypeError, "keyword arguments are not supported"); return FALSE; } 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. */ while (failure.reason == Ok) { char ch; PyObject *arg; PyErr_Clear(); /* See if the following arguments are optional. */ if ((ch = *fmt++) == '|') { compulsory = FALSE; ch = *fmt++; } /* See if we don't expect anything else. */ if (ch == '\0') { if (argnr < nr_pos_args) { /* There are still positional arguments. */ failure.reason = TooMany; } else if (nr_kwd_args_used != nr_kwd_args) { /* * Take a shortcut if no keyword arguments were used and we are * interested in them. */ if (nr_kwd_args_used == 0 && unused != NULL) { Py_INCREF(sipKwdArgs); *unused = sipKwdArgs; } else { PyObject *key, *value, *unused_dict = NULL; SIP_SSIZE_T pos = 0; /* * Go through the keyword arguments to find any that were * duplicates of positional arguments. For the remaining * ones remember the unused ones if we are interested. */ while (PyDict_Next(sipKwdArgs, &pos, &key, &value)) { int a; #if PY_MAJOR_VERSION >= 3 if (!PyUnicode_Check(key)) #else if (!PyString_Check(key)) #endif { failure.reason = KeywordNotString; failure.detail_obj = key; Py_INCREF(key); break; } if (kwdlist != NULL) { /* Get the argument's index if it is one. */ for (a = 0; a < nr_args; ++a) { const char *name = kwdlist[a]; if (name == NULL) continue; #if PY_MAJOR_VERSION >= 3 if (PyUnicode_CompareWithASCIIString(key, name) == 0) #else if (strcmp(PyString_AS_STRING(key), name) == 0) #endif break; } } else { a = nr_args; } if (a == nr_args) { /* * The name doesn't correspond to a keyword * argument. */ if (unused == NULL) { /* * It may correspond to a keyword argument of a * different overload. */ failure.reason = UnknownKeyword; failure.detail_obj = key; Py_INCREF(key); break; } /* * Add it to the dictionary of unused arguments * creating it if necessary. Note that if the * unused arguments are actually used by a later * overload then the parse will incorrectly * succeed. This should be picked up (perhaps with * a misleading exception) so long as the code that * handles the unused arguments checks that it can * handle them all. */ if (unused_dict == NULL && (*unused = unused_dict = PyDict_New()) == NULL) { failure.reason = Raised; break; } if (PyDict_SetItem(unused_dict, key, value) < 0) { failure.reason = Raised; break; } } else if (a < nr_pos_args - *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 (sipKwdArgs != NULL && 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 = SIPLong_AsLong(arg); if (PyErr_Occurred()) { failure.reason = WrongType; failure.detail_obj = arg; Py_INCREF(arg); } else { sipSetBool(p, v); } } break; } case 'E': { /* Named enum or integer. */ sipTypeDef *td = va_arg(va, sipTypeDef *); va_arg(va, int *); if (arg != NULL && !sip_api_can_convert_to_enum(arg, td)) { failure.reason = WrongType; failure.detail_obj = arg; Py_INCREF(arg); } } break; case 'e': case 'i': { /* Integer or anonymous enum. */ int *p = va_arg(va, int *); if (arg != NULL) { int v = SIPLong_AsLong(arg); if (PyErr_Occurred()) { failure.reason = WrongType; failure.detail_obj = arg; Py_INCREF(arg); } else { *p = v; } } break; } case 'u': { /* Unsigned integer. */ unsigned *p = va_arg(va, unsigned *); if (arg != NULL) { unsigned v = sip_api_long_as_unsigned_long(arg); if (PyErr_Occurred()) { failure.reason = WrongType; failure.detail_obj = arg; Py_INCREF(arg); } else { *p = v; } } break; } case 'L': { /* Signed char. */ signed char *p = va_arg(va, signed char *); if (arg != NULL) { signed char v = SIPLong_AsLong(arg); if (PyErr_Occurred()) { failure.reason = WrongType; failure.detail_obj = arg; Py_INCREF(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_long(arg); if (PyErr_Occurred()) { failure.reason = WrongType; failure.detail_obj = arg; Py_INCREF(arg); } else { *p = v; } } break; } case 'h': { /* Short integer. */ short *p = va_arg(va, short *); if (arg != NULL) { short v = SIPLong_AsLong(arg); if (PyErr_Occurred()) { failure.reason = WrongType; failure.detail_obj = arg; Py_INCREF(arg); } else { *p = v; } } break; } case 't': { /* Unsigned short integer. */ unsigned short *p = va_arg(va, unsigned short *); if (arg != NULL) { unsigned short v = sip_api_long_as_unsigned_long(arg); if (PyErr_Occurred()) { failure.reason = WrongType; failure.detail_obj = arg; Py_INCREF(arg); } else { *p = v; } } break; } case 'l': { /* Long integer. */ long *p = va_arg(va, long *); if (arg != NULL) { long v = PyLong_AsLong(arg); if (PyErr_Occurred()) { failure.reason = WrongType; failure.detail_obj = arg; Py_INCREF(arg); } else { *p = v; } } break; } case 'm': { /* Unsigned long integer. */ unsigned long *p = va_arg(va, unsigned long *); if (arg != NULL) { unsigned long v = sip_api_long_as_unsigned_long(arg); if (PyErr_Occurred()) { failure.reason = WrongType; failure.detail_obj = arg; Py_INCREF(arg); } else { *p = v; } } break; } case 'n': { /* Long long integer. */ #if defined(HAVE_LONG_LONG) PY_LONG_LONG *p = va_arg(va, PY_LONG_LONG *); #else long *p = va_arg(va, long *); #endif if (arg != NULL) { #if defined(HAVE_LONG_LONG) PY_LONG_LONG v = PyLong_AsLongLong(arg); #else long v = PyLong_AsLong(arg); #endif if (PyErr_Occurred()) { failure.reason = WrongType; failure.detail_obj = arg; Py_INCREF(arg); } else { *p = v; } } break; } case 'o': { /* Unsigned long long integer. */ #if defined(HAVE_LONG_LONG) unsigned PY_LONG_LONG *p = va_arg(va, unsigned PY_LONG_LONG *); #else unsigned long *p = va_arg(va, unsigned long *); #endif if (arg != NULL) { #if defined(HAVE_LONG_LONG) unsigned PY_LONG_LONG v = PyLong_AsUnsignedLongLongMask(arg); #else unsigned long v = PyLong_AsUnsignedLongMask(arg); #endif if (PyErr_Occurred()) { failure.reason = WrongType; failure.detail_obj = arg; Py_INCREF(arg); } else { *p = v; } } break; } case 'f': { /* Float. */ float *p = va_arg(va, float *); if (arg != NULL) { double v = PyFloat_AsDouble(arg); if (PyErr_Occurred()) { failure.reason = WrongType; failure.detail_obj = arg; Py_INCREF(arg); } else { *p = (float)v; } } break; } case 'X': { /* Constrained types. */ char sub_fmt = *fmt++; if (sub_fmt == 'E') { /* Named enum. */ sipTypeDef *td = va_arg(va, sipTypeDef *); va_arg(va, int *); if (arg != NULL && !PyObject_TypeCheck(arg, sipTypeAsPyTypeObject(td))) { failure.reason = WrongType; failure.detail_obj = arg; Py_INCREF(arg); } } else { void *p = va_arg(va, void *); if (arg != NULL) { switch (sub_fmt) { case 'b': { /* Boolean. */ if (PyBool_Check(arg)) { sipSetBool(p, (arg == Py_True)); } else { failure.reason = WrongType; failure.detail_obj = arg; Py_INCREF(arg); } break; } case 'd': { /* Double float. */ if (PyFloat_Check(arg)) { *(double *)p = PyFloat_AS_DOUBLE(arg); } else { failure.reason = WrongType; failure.detail_obj = arg; Py_INCREF(arg); } break; } case 'f': { /* Float. */ if (PyFloat_Check(arg)) { *(float *)p = (float)PyFloat_AS_DOUBLE(arg); } else { failure.reason = WrongType; failure.detail_obj = arg; Py_INCREF(arg); } break; } case 'i': { /* Integer. */ #if PY_MAJOR_VERSION >= 3 if (PyLong_Check(arg)) { *(int *)p = PyLong_AS_LONG(arg); } #else if (PyInt_Check(arg)) { *(int *)p = PyInt_AS_LONG(arg); } #endif else { failure.reason = WrongType; failure.detail_obj = arg; Py_INCREF(arg); } break; } } } } break; } case 'd': { /* Double float. */ double *p = va_arg(va,double *); if (arg != NULL) { double v = PyFloat_AsDouble(arg); if (PyErr_Occurred()) { failure.reason = WrongType; failure.detail_obj = arg; Py_INCREF(arg); } else { *p = v; } } break; } case 'v': { /* Void pointer. */ void **p = va_arg(va, void **); if (arg != NULL) { void *v = sip_api_convert_to_void_ptr(arg); if (PyErr_Occurred()) { failure.reason = WrongType; failure.detail_obj = arg; Py_INCREF(arg); } else { *p = v; } } break; } 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 && ch == 'W') { /* An ellipsis matches everything and ends the parse. */ break; } } /* Handle parse failures appropriately. */ if (failure.reason == Ok) return TRUE; if (failure.reason != Raised) { add_failure(parseErrp, &failure); } if (failure.reason == Raised) { Py_XDECREF(failure.detail_obj); /* * The error isn't a user error so don't bother with the detail of the * overload. */ Py_XDECREF(*parseErrp); *parseErrp = Py_None; Py_INCREF(Py_None); } return FALSE; } /* * Second pass of the argument parse, converting the remaining ones that might * have side effects. Return TRUE if there was no error. */ static int parsePass2(sipSimpleWrapper *self, int selfarg, PyObject *sipArgs, PyObject *sipKwdArgs, const char **kwdlist, const char *fmt, va_list va) { int a, ok; SIP_SSIZE_T nr_pos_args; /* Handle the converions of "self" first. */ switch (*fmt++) { case 'B': { /* * The address of a C++ instance when calling one of its public * methods. */ const sipTypeDef *td; void **p; *va_arg(va, PyObject **) = (PyObject *)self; td = va_arg(va, const sipTypeDef *); p = va_arg(va, void **); if ((*p = sip_api_get_cpp_ptr(self, td)) == NULL) return FALSE; break; } case 'p': { /* * The address of a C++ instance when calling one of its protected * methods. */ const sipTypeDef *td; void **p; *va_arg(va, PyObject **) = (PyObject *)self; td = va_arg(va, const sipTypeDef *); p = va_arg(va, void **); if ((*p = getComplexCppPtr(self, td)) == NULL) return FALSE; break; } case 'C': va_arg(va, PyObject *); break; default: --fmt; } ok = TRUE; nr_pos_args = PyTuple_GET_SIZE(sipArgs); for (a = (selfarg ? 1 : 0); *fmt != '\0' && *fmt != 'W' && ok; ++a) { char ch; PyObject *arg; /* Skip the optional character. */ if ((ch = *fmt++) == '|') ch = *fmt++; /* Get the next argument. */ arg = NULL; if (a < nr_pos_args) { arg = PyTuple_GET_ITEM(sipArgs, a); } else if (sipKwdArgs != NULL) { const char *name = kwdlist[a - 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. */ va_arg(va, void *); if (*fmt++ == 'E') { /* Named enum. */ int *p = va_arg(va, int *); if (arg != NULL) *p = SIPLong_AsLong(arg); } break; } case 'E': { /* Named enum. */ int *p; va_arg(va, sipTypeDef *); p = va_arg(va, int *); if (arg != NULL) *p = SIPLong_AsLong(arg); break; } case 'A': { /* String from a Python string or None. */ PyObject **keep = va_arg(va, PyObject **); const char **p = va_arg(va, const char **); char sub_fmt = *fmt++; if (arg != NULL) { PyObject *s; switch (sub_fmt) { case 'A': s = parseString_AsASCIIString(arg, p); break; case 'L': s = parseString_AsLatin1String(arg, p); break; case '8': s = parseString_AsUTF8String(arg, p); break; } if (s == NULL) 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': va_arg(va, void *); /* Drop through. */ default: va_arg(va, void *); } } /* Handle any ellipsis argument. */ if (*fmt == 'W') { PyObject *al; int da = 0; /* Create a tuple for any remaining arguments. */ if ((al = PyTuple_New(nr_pos_args - a)) == NULL) return FALSE; while (a < nr_pos_args) { PyObject *arg = PyTuple_GET_ITEM(sipArgs, a); /* Add the remaining argument to the tuple. */ Py_INCREF(arg); PyTuple_SET_ITEM(al, da, arg); ++a; ++da; } /* Return the tuple. */ *va_arg(va, PyObject **) = al; } return TRUE; } /* * Return TRUE if an object is a QObject. */ static int isQObject(PyObject *obj) { return (sipQtSupport != NULL && PyObject_TypeCheck(obj, sipTypeAsPyTypeObject(sipQObjectType))); } /* * See if a Python object is a sequence of a particular type. */ static int canConvertFromSequence(PyObject *seq, const sipTypeDef *td) { SIP_SSIZE_T i, size = PySequence_Size(seq); if (size < 0) return FALSE; for (i = 0; i < size; ++i) { int ok; PyObject *val_obj; if ((val_obj = PySequence_GetItem(seq, i)) == NULL) return FALSE; ok = sip_api_can_convert_to_type(val_obj, td, SIP_NO_CONVERTORS|SIP_NOT_NONE); Py_DECREF(val_obj); if (!ok) return FALSE; } return TRUE; } /* * Convert a Python sequence to an array that has already "passed" * canConvertFromSequence(). Return TRUE if the conversion was successful. */ static int convertFromSequence(PyObject *seq, const sipTypeDef *td, void **array, SIP_SSIZE_T *nr_elem) { int iserr = 0; SIP_SSIZE_T i, size = PySequence_Size(seq); sipArrayFunc array_helper; sipAssignFunc assign_helper; void *array_mem; /* Get the type's helpers. */ if (sipTypeIsMapped(td)) { array_helper = ((const sipMappedTypeDef *)td)->mtd_array; assign_helper = ((const sipMappedTypeDef *)td)->mtd_assign; } else { array_helper = ((const sipClassTypeDef *)td)->ctd_array; assign_helper = ((const sipClassTypeDef *)td)->ctd_assign; } assert(array_helper != NULL); assert(assign_helper != NULL); /* * Create the memory for the array of values. Note that this will leak if * there is an error. */ array_mem = array_helper(size); for (i = 0; i < size; ++i) { PyObject *val_obj; void *val; if ((val_obj = PySequence_GetItem(seq, i)) == NULL) return FALSE; val = sip_api_convert_to_type(val_obj, td, NULL, SIP_NO_CONVERTORS|SIP_NOT_NONE, NULL, &iserr); Py_DECREF(val_obj); if (iserr) return FALSE; assign_helper(array_mem, i, val); } *array = array_mem; *nr_elem = size; return TRUE; } /* * Convert an array of a type to a Python sequence. */ static PyObject *convertToSequence(void *array, SIP_SSIZE_T nr_elem, const sipTypeDef *td) { SIP_SSIZE_T i; PyObject *seq; sipCopyFunc copy_helper; /* Get the type's copy helper. */ if (sipTypeIsMapped(td)) copy_helper = ((const sipMappedTypeDef *)td)->mtd_copy; else copy_helper = ((const sipClassTypeDef *)td)->ctd_copy; assert(copy_helper != NULL); if ((seq = PyTuple_New(nr_elem)) == NULL) return NULL; for (i = 0; i < nr_elem; ++i) { void *el = copy_helper(array, i); PyObject *el_obj = sip_api_convert_from_new_type(el, td, NULL); if (el_obj == NULL) { release(el, td, 0); Py_DECREF(seq); } PyTuple_SET_ITEM(seq, i, el_obj); } return seq; } /* * Carry out actions common to all dtors. */ void sip_api_common_dtor(sipSimpleWrapper *sipSelf) { if (sipSelf != NULL && sipInterpreter != NULL) { PyObject *xtype, *xvalue, *xtb; SIP_BLOCK_THREADS /* We may be tidying up after an exception so preserve it. */ PyErr_Fetch(&xtype, &xvalue, &xtb); callPyDtor(sipSelf); PyErr_Restore(xtype, xvalue, xtb); 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 classes of a type that has no explicit * super-type. */ static PyObject *getDefaultBases(void) { static PyObject *default_bases = NULL; /* Only do this once. */ if (default_bases == NULL) { #if PY_VERSION_HEX >= 0x02040000 default_bases = PyTuple_Pack(1, (PyObject *)&sipWrapper_Type); #else default_bases = Py_BuildValue("(O)", &sipWrapper_Type); #endif if (default_bases == NULL) return NULL; } Py_INCREF(default_bases); return default_bases; } /* * Return the dictionary of a type. */ static PyObject *getScopeDict(sipTypeDef *td, PyObject *mod_dict, sipExportedModuleDef *client) { /* * Initialise the scoping type if necessary. It will always be in the * same module if it needs doing. */ if (sipTypeIsMapped(td)) { if (createMappedType(client, (sipMappedTypeDef *)td, mod_dict) < 0) return NULL; /* Check that the mapped type can act as a container. */ assert(sipTypeAsPyTypeObject(td) != NULL); } else { if (createClassType(client, (sipClassTypeDef *)td, mod_dict) < 0) return NULL; } return (sipTypeAsPyTypeObject(td))->tp_dict; } /* * Create a container type and return a borrowed reference to it. */ static PyObject *createContainerType(sipContainerDef *cod, sipTypeDef *td, PyObject *bases, PyObject *metatype, PyObject *mod_dict, 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 = getDefaultBases(); } else { PyObject *supertype; const char *supertype_name = sipNameFromPool(client, ctd->ctd_supertype); if ((supertype = findPyType(supertype_name)) == NULL) goto reterr; #if PY_VERSION_HEX >= 0x02040000 bases = PyTuple_Pack(1, supertype); #else bases = Py_BuildValue("(O)", supertype); #endif } if (bases == NULL) goto reterr; } else { int 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 = getDefaultBases()) == 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 *ignore, PyObject *args) { PyObject *mname_obj, *init_args; const char *tname; sipExportedModuleDef *em; int i; if (!PyArg_ParseTuple(args, #if PY_MAJOR_VERSION >= 3 "UsO!:_unpickle_type", #else "SsO!:_unpickle_type", #endif &mname_obj, &tname, &PyTuple_Type, &init_args)) return NULL; /* Get the module definition. */ if ((em = getModule(mname_obj)) == NULL) return NULL; /* Find the class type object. */ for (i = 0; i < em->em_nrtypes; ++i) { sipTypeDef *td = em->em_types[i]; if (td != NULL && !sipTypeIsStub(td) && sipTypeIsClass(td)) { const char *pyname = sipPyNameOfContainer( &((sipClassTypeDef *)td)->ctd_container, td); if (strcmp(pyname, tname) == 0) return PyObject_CallObject((PyObject *)sipTypeAsPyTypeObject(td), init_args); } } PyErr_Format(PyExc_SystemError, "unable to find to find type: %s", tname); return NULL; } /* * The type pickler. */ static PyObject *pickle_type(PyObject *obj, PyObject *ignore) { sipExportedModuleDef *em; /* Find the type definition and defining module. */ for (em = moduleList; em != NULL; em = em->em_next) { int i; for (i = 0; i < em->em_nrtypes; ++i) { sipTypeDef *td = em->em_types[i]; if (td != NULL && !sipTypeIsStub(td) && sipTypeIsClass(td)) if (sipTypeAsPyTypeObject(td) == Py_TYPE(obj)) { PyObject *init_args; sipClassTypeDef *ctd = (sipClassTypeDef *)td; const char *pyname = sipPyNameOfContainer(&ctd->ctd_container, td); /* * Ask the handwritten pickle code for the tuple of * arguments that will recreate the object. */ init_args = ctd->ctd_pickle(sip_api_get_cpp_ptr((sipSimpleWrapper *)obj, NULL)); if (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 *ignore, PyObject *args) { PyObject *mname_obj, *evalue_obj; const char *ename; sipExportedModuleDef *em; int i; if (!PyArg_ParseTuple(args, #if PY_MAJOR_VERSION >= 3 "UsO:_unpickle_enum", #else "SsO:_unpickle_enum", #endif &mname_obj, &ename, &evalue_obj)) return NULL; /* Get the module definition. */ if ((em = getModule(mname_obj)) == NULL) return NULL; /* Find the enum type object. */ for (i = 0; i < em->em_nrtypes; ++i) { sipTypeDef *td = em->em_types[i]; if (td != NULL && !sipTypeIsStub(td) && sipTypeIsEnum(td)) if (strcmp(sipPyNameOfEnum((sipEnumTypeDef *)td), ename) == 0) return PyObject_CallFunctionObjArgs((PyObject *)sipTypeAsPyTypeObject(td), evalue_obj, NULL); } PyErr_Format(PyExc_SystemError, "unable to find to find enum: %s", ename); return NULL; } /* * The enum pickler. */ static PyObject *pickle_enum(PyObject *obj, PyObject *ignore) { sipTypeDef *td = ((sipEnumTypeObject *)Py_TYPE(obj))->type; return Py_BuildValue("O(Osi)", enum_unpickler, td->td_module->em_nameobj, sipPyNameOfEnum((sipEnumTypeDef *)td), #if PY_MAJOR_VERSION >= 3 (int)PyLong_AS_LONG(obj) #else (int)PyInt_AS_LONG(obj) #endif ); } /* * Set the __reduce__method for a type. */ static int setReduce(PyTypeObject *type, PyMethodDef *pickler) { static PyObject *rstr = NULL; PyObject *descr; int rc; if (objectify("__reduce__", &rstr) < 0) return -1; /* Create the method descripter. */ if ((descr = PyDescr_NewMethod(type, pickler)) == NULL) return -1; /* * Save the method. Note that we don't use PyObject_SetAttr() as we want * to bypass any lazy attribute loading (which may not be safe yet). */ rc = PyType_Type.tp_setattro((PyObject *)type, rstr, descr); Py_DECREF(descr); return rc; } /* * Create an enum type object. */ static int createEnumType(sipExportedModuleDef *client, sipEnumTypeDef *etd, PyObject *mod_dict) { static PyObject *bases = NULL; PyObject *name, *type_dict, *args, *dict; PyTypeObject *py_type; etd->etd_base.td_module = client; /* Get the dictionary into which the type will be placed. */ if (etd->etd_scope < 0) dict = mod_dict; else if ((dict = getScopeDict(client->em_types[etd->etd_scope], mod_dict, client)) == NULL) goto reterr; /* Create the base type tuple if it hasn't already been done. */ if (bases == NULL) { #if PY_MAJOR_VERSION >= 3 bases = PyTuple_Pack(1, (PyObject *)&PyLong_Type); #elif PY_VERSION_HEX >= 0x02040000 bases = PyTuple_Pack(1, (PyObject *)&PyInt_Type); #else bases = Py_BuildValue("(O)", &PyInt_Type); #endif if (bases == NULL) goto reterr; } /* Create an object corresponding to the type name. */ #if PY_MAJOR_VERSION >= 3 name = PyUnicode_FromString(sipPyNameOfEnum(etd)); #else name = PyString_FromString(sipPyNameOfEnum(etd)); #endif if (name == NULL) goto reterr; /* Create the type dictionary. */ if ((type_dict = createTypeDict(client)) == NULL) goto relname; /* 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) goto relname; /* Pass the type via the back door. */ assert(currentType == NULL); currentType = &etd->etd_base; py_type = (PyTypeObject *)PyObject_Call((PyObject *)&sipEnumType_Type, args, NULL); currentType = NULL; Py_DECREF(args); if (py_type == NULL) goto relname; /* Add the type to the "parent" dictionary. */ if (PyDict_SetItem(dict, name, (PyObject *)py_type) < 0) { Py_DECREF((PyObject *)py_type); goto relname; } if (etd->etd_pyslots != NULL) fix_slots((PyTypeObject *)py_type, etd->etd_pyslots); /* We can now release our remaining references. */ Py_DECREF(name); return 0; /* Unwind after an error. */ relname: Py_DECREF(name); reterr: etd->etd_base.td_module = client; return -1; } /* * Create a type dictionary for dynamic type being created in 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__", 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 enum members. */ enm = cod->cod_enummembers; for (i = 0; i < cod->cod_nrenummembers; ++i) { int rc; PyObject *val; if ((val = createEnumMember(td, enm)) == NULL) return -1; rc = PyDict_SetItemString(dict, enm->em_name, val); Py_DECREF(val); if (rc < 0) return -1; ++enm; } /* Do the variables. */ vd = cod->cod_variables; for (i = 0; i < cod->cod_nrvariables; ++i) { int rc; PyObject *descr; if (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->dict_complete) return 0; dict = ((PyTypeObject *)wt)->tp_dict; if (sipTypeIsMapped(td)) { if (add_lazy_container_attrs(td, &((sipMappedTypeDef *)td)->mtd_container, dict) < 0) return -1; } else { sipClassTypeDef *nsx; /* Search the possible linked list of namespace extenders. */ for (nsx = (sipClassTypeDef *)td; nsx != NULL; nsx = nsx->ctd_nsextender) if (add_lazy_container_attrs((sipTypeDef *)nsx, &nsx->ctd_container, dict) < 0) return -1; } /* * Get any lazy attributes from registered getters. This must be done last * to allow any existing attributes to be replaced. */ for (ag = sipAttrGetters; ag != NULL; ag = ag->next) if (ag->type == NULL || PyType_IsSubtype((PyTypeObject *)wt, ag->type)) if (ag->getter(td, dict) < 0) return -1; wt->dict_complete = TRUE; #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)->type; if (PyObject_TypeCheck((PyObject *)py_type, &sipEnumType_Type)) return ((sipEnumTypeObject *)py_type)->type; return NULL; } /* * Return the generated type structure corresponding to the scope of the given * type. */ static const sipTypeDef *sip_api_type_scope(const sipTypeDef *td) { if (sipTypeIsEnum(td)) { const sipEnumTypeDef *etd = (const sipEnumTypeDef *)td; if (etd->etd_scope >= 0) return td->td_module->em_types[etd->etd_scope]; } else { const sipContainerDef *cod; if (sipTypeIsMapped(td)) cod = &((const sipMappedTypeDef *)td)->mtd_container; else cod = &((const sipClassTypeDef *)td)->ctd_container; if (!cod->cod_scope.sc_flag) return getGeneratedType(&cod->cod_scope, td->td_module); } return NULL; } /* * Return TRUE if an object can be converted to a named enum. */ static int sip_api_can_convert_to_enum(PyObject *obj, const sipTypeDef *td) { assert(sipTypeIsEnum(td)); /* If the object is an enum then it must be the right enum. */ if (PyObject_TypeCheck((PyObject *)Py_TYPE(obj), &sipEnumType_Type)) return (PyObject_TypeCheck(obj, sipTypeAsPyTypeObject(td))); #if PY_MAJOR_VERSION >= 3 return PyLong_Check(obj); #else return PyInt_Check(obj); #endif } /* * Create a Python object for an enum member. */ static PyObject *createEnumMember(sipTypeDef *td, sipEnumMemberDef *enm) { if (enm->em_enum < 0) #if PY_MAJOR_VERSION >= 3 return PyLong_FromLong(enm->em_val); #else return PyInt_FromLong(enm->em_val); #endif return sip_api_convert_from_enum(enm->em_val, td->td_module->em_types[enm->em_enum]); } /* * Create a Python object for a member of a named enum. */ static PyObject *sip_api_convert_from_enum(int eval, const sipTypeDef *td) { assert(sipTypeIsEnum(td)); return PyObject_CallFunction((PyObject *)sipTypeAsPyTypeObject(td), "(i)", eval); } /* * Register a getter for unknown attributes. */ static int sip_api_register_attribute_getter(const sipTypeDef *td, sipAttrGetterFunc getter) { sipAttrGetter *ag = sip_api_malloc(sizeof (sipAttrGetter)); if (ag == NULL) return -1; ag->type = sipTypeAsPyTypeObject(td); ag->getter = getter; ag->next = sipAttrGetters; sipAttrGetters = ag; return 0; } /* * 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. This won't show which overload we were parsing but it * doesn't really matter as it is a fundamental problem rather than a * user error. */ assert(parseErr == Py_None); } Py_XDECREF(parseErr); } /* * Return a string/unicode object extracted from a particular line of a * docstring. */ static PyObject *signature_FromDocstring(const char *doc, SIP_SSIZE_T line) { const char *eol; SIP_SSIZE_T size = 0; /* * Find the start of the line. If there is a non-default versioned * overload that has been enabled then it won't have an entry in the * docstring. This means that the returned signature may be incorrect. */ while (line-- > 0) { const char *next = strchr(doc, '\n'); if (next == NULL) break; doc = next + 1; } /* Find the last closing parenthesis. */ for (eol = doc; *eol != '\n' && *eol != '\0'; ++eol) if (*eol == ')') size = eol - doc + 1; #if PY_MAJOR_VERSION >= 3 return PyUnicode_FromStringAndSize(doc, size); #else return PyString_FromStringAndSize(doc, size); #endif } /* * Return a string/unicode object that describes the given failure. */ static PyObject *detail_FromFailure(PyObject *failure_obj) { sipParseFailure *failure; PyObject *detail; #if defined(SIP_USE_PYCAPSULE) failure = (sipParseFailure *)PyCapsule_GetPointer(failure_obj, NULL); #else failure = (sipParseFailure *)PyCObject_AsVoidPtr(failure_obj); #endif switch (failure->reason) { case Unbound: #if PY_MAJOR_VERSION >= 3 detail = PyUnicode_FromFormat( "first argument of unbound method must have type '%s'", failure->detail_str); #else detail = PyString_FromFormat( "first argument of unbound method must have type '%s'", failure->detail_str); #endif break; case TooFew: #if PY_MAJOR_VERSION >= 3 detail = PyUnicode_FromString("not enough arguments"); #else detail = PyString_FromString("not enough arguments"); #endif break; case TooMany: #if PY_MAJOR_VERSION >= 3 detail = PyUnicode_FromString("too many arguments"); #else detail = PyString_FromString("too many arguments"); #endif break; case KeywordNotString: #if PY_MAJOR_VERSION >= 3 detail = PyUnicode_FromFormat( "%S keyword argument name is not a string", failure->detail_obj); #else { PyObject *str = PyObject_Str(failure->detail_obj); if (str != NULL) { detail = PyString_FromFormat( "%s keyword argument name is not a string", PyString_AsString(str)); Py_DECREF(str); } else { detail = NULL; } } #endif break; case UnknownKeyword: #if PY_MAJOR_VERSION >= 3 detail = PyUnicode_FromFormat("'%U' is not a valid keyword argument", failure->detail_obj); #else detail = PyString_FromFormat("'%s' is not a valid keyword argument", PyString_AS_STRING(failure->detail_obj)); #endif break; case Duplicate: #if PY_MAJOR_VERSION >= 3 detail = PyUnicode_FromFormat( "'%U' has already been given as a positional argument", failure->detail_obj); #else detail = PyString_FromFormat( "'%s' has already been given as a positional argument", PyString_AS_STRING(failure->detail_obj)); #endif break; case WrongType: if (failure->arg_nr >= 0) { detail = bad_type_str(failure->arg_nr, failure->detail_obj); } else { #if PY_MAJOR_VERSION >= 3 detail = PyUnicode_FromFormat( "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 return type. */ static void sip_api_bad_catcher_result(PyObject *method) { PyObject *mname; /* * This is part of the public API so we make no assumptions about the * method object. */ if (!PyMethod_Check(method) || PyMethod_GET_FUNCTION(method) == NULL || !PyFunction_Check(PyMethod_GET_FUNCTION(method)) || PyMethod_GET_SELF(method) == NULL) { PyErr_Format(PyExc_TypeError, "invalid argument to sipBadCatcherResult()"); return; } mname = ((PyFunctionObject *)PyMethod_GET_FUNCTION(method))->func_name; #if PY_MAJOR_VERSION >= 3 PyErr_Format(PyExc_TypeError, "invalid result type from %s.%U()", Py_TYPE(PyMethod_GET_SELF(method))->tp_name, mname); #else PyErr_Format(PyExc_TypeError, "invalid result type from %s.%s()", Py_TYPE(PyMethod_GET_SELF(method))->tp_name, PyString_AsString(mname)); #endif } /* * Transfer ownership of a class instance to Python from C/C++. */ static void sip_api_transfer_back(PyObject *self) { if (self != NULL && PyObject_TypeCheck(self, (PyTypeObject *)&sipWrapper_Type)) { sipSimpleWrapper *sw = (sipSimpleWrapper *)self; if (sipCppHasRef(sw)) { sipResetCppHasRef(sw); Py_DECREF(sw); } else removeFromParent((sipWrapper *)sw); sipSetPyOwned(sw); } } /* * Break the association of a C++ owned Python object with any parent. 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; 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)) { 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))->type) < 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; case ReleaseGuard: addr = NULL; break; } return addr; } /* * Get the C/C++ pointer for a complex object. Note that not casting the C++ * pointer is a bug. However this is only ever called by PyQt3 signal emitter * code and PyQt doesn't contain anything that multiply inherits from QObject. */ static void *sip_api_get_complex_cpp_ptr(sipSimpleWrapper *sw) { return getComplexCppPtr(sw, NULL); } /* * Get the C/C++ pointer for a complex object and optionally cast it to the * required type. */ static void *getComplexCppPtr(sipSimpleWrapper *sw, const sipTypeDef *td) { if (!sipIsDerived(sw)) { PyErr_SetString(PyExc_RuntimeError, "no access to protected functions or signals for objects not created from Python"); return NULL; } return sip_api_get_cpp_ptr(sw, td); } /* * Get the C/C++ pointer from a wrapper and optionally cast it to the required * type. */ void *sip_api_get_cpp_ptr(sipSimpleWrapper *sw, const sipTypeDef *td) { void *ptr = sip_api_get_address(sw); if (checkPointer(ptr, sw) < 0) return NULL; if (td != NULL) { ptr = cast_cpp_ptr(ptr, Py_TYPE(sw), td); if (ptr == NULL) PyErr_Format(PyExc_TypeError, "could not convert '%s' to '%s'", Py_TYPE(sw)->tp_name, sipPyNameOfContainer(&((const sipClassTypeDef *)td)->ctd_container, td)); } return ptr; } /* * Cast a C/C++ pointer from a source type to a destination type. */ static void *cast_cpp_ptr(void *ptr, PyTypeObject *src_type, const sipTypeDef *dst_type) { sipCastFunc cast = ((const sipClassTypeDef *)((sipWrapperType *)src_type)->type)->ctd_cast; /* C structures don't have cast functions. */ if (cast != NULL) ptr = (*cast)(ptr, dst_type); return ptr; } /* * Check that a pointer is non-NULL. */ static int checkPointer(void *ptr, 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); } } /* * Check to see if a Python object can be converted to a type. */ static int sip_api_can_convert_to_type(PyObject *pyObj, const sipTypeDef *td, int flags) { int ok; assert(sipTypeIsClass(td) || sipTypeIsMapped(td)); /* None is handled outside the type checkers. */ if (pyObj == Py_None) { /* If the type explicitly handles None then ignore the flags. */ if (sipTypeAllowNone(td)) ok = TRUE; else ok = ((flags & SIP_NOT_NONE) == 0); } else { sipConvertToFunc cto; if (sipTypeIsClass(td)) { cto = ((const sipClassTypeDef *)td)->ctd_cto; if (cto == NULL || (flags & SIP_NO_CONVERTORS) != 0) ok = PyObject_TypeCheck(pyObj, sipTypeAsPyTypeObject(td)); else ok = cto(pyObj, NULL, NULL, NULL); } else { cto = ((const sipMappedTypeDef *)td)->mtd_cto; ok = cto(pyObj, NULL, NULL, NULL); } } return ok; } /* * Convert a Python object to a C/C++ pointer, assuming a previous call to * sip_api_can_convert_to_type() has been successful. Allow ownership to be * transferred and any type convertors to be disabled. */ static void *sip_api_convert_to_type(PyObject *pyObj, const sipTypeDef *td, PyObject *transferObj, int flags, int *statep, int *iserrp) { void *cpp = NULL; int state = 0; assert(sipTypeIsClass(td) || sipTypeIsMapped(td)); /* Don't convert if there has already been an error. */ if (!*iserrp) { /* Do the conversion. */ if (pyObj == Py_None && !sipTypeAllowNone(td)) cpp = NULL; else { sipConvertToFunc cto; if (sipTypeIsClass(td)) { cto = ((const sipClassTypeDef *)td)->ctd_cto; if (cto == NULL || (flags & SIP_NO_CONVERTORS) != 0) { if ((cpp = sip_api_get_cpp_ptr((sipSimpleWrapper *)pyObj, td)) == NULL) *iserrp = TRUE; else if (transferObj != NULL) { if (transferObj == Py_None) sip_api_transfer_back(pyObj); else sip_api_transfer_to(pyObj, transferObj); } } else { state = cto(pyObj, &cpp, iserrp, transferObj); } } else { cto = ((const sipMappedTypeDef *)td)->mtd_cto; state = cto(pyObj, &cpp, iserrp, transferObj); } } } if (statep != NULL) *statep = state; return cpp; } /* * Convert a Python object to a C/C++ pointer and raise an exception if it * can't be done. */ 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); /* Apply any sub-class convertor. */ if (sipTypeHasSCC(td)) td = convertSubClass(td, &cpp); /* See if we have already wrapped it. */ if ((py = sip_api_get_pyobject(cpp, td)) != NULL) Py_INCREF(py); else if ((py = 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 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_CallObject(hook, NULL); Py_XDECREF(res); } /* * Call any sub-class convertors for a given type returning a pointer to the * sub-type object, and possibly modifying the C++ address (in the case of * multiple inheritence). */ static const sipTypeDef *convertSubClass(const sipTypeDef *td, void **cppPtr) { /* 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 = sipTypeAsPyTypeObject(scc->scc_basetype); /* * The base type is the "root" class that may have a number of * convertors each handling a "branch" of the derived tree of * classes. The "root" normally implements the base function that * provides the RTTI used by the convertors and is re-implemented * by derived classes. We therefore see if the target type is a * sub-class of the root, ie. see if the convertor might be able to * convert the target type to something more specific. */ if (PyType_IsSubtype(py_type, base_type)) { void *ptr; const sipTypeDef *sub_td; ptr = cast_cpp_ptr(*cppPtr, py_type, scc->scc_basetype); 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 module of an encoded type. */ static sipExportedModuleDef *getTypeModule(const sipEncodedTypeDef *enc, sipExportedModuleDef *em) { if (enc->sc_module != 255) em = em->em_imports[enc->sc_module].im_module; return em; } /* * Return the generated type structure of an encoded type. */ static sipTypeDef *getGeneratedType(const sipEncodedTypeDef *enc, sipExportedModuleDef *em) { return getTypeModule(enc, em)->em_types[enc->sc_type]; } /* * 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)) { sipClassTypeDef *ctd; ctd = (sipClassTypeDef *)((sipWrapperType *)(py_type))->type; if (ctd->ctd_pyslots != NULL) slot = findSlotInType(ctd->ctd_pyslots, st); else slot = NULL; if (slot == NULL) { sipEncodedTypeDef *sup; /* Search any super-types. */ if ((sup = ctd->ctd_supers) != NULL) do { const sipClassTypeDef *sup_ctd = sipGetGeneratedClassType( sup, ctd); if (sup_ctd->ctd_pyslots != NULL) slot = findSlotInType(sup_ctd->ctd_pyslots, st); } while (slot == NULL && !sup++->sc_flag); } } else { sipEnumTypeDef *etd; /* If it is not a wrapper then it must be an enum. */ assert(PyObject_TypeCheck((PyObject *)py_type, &sipEnumType_Type)); etd = (sipEnumTypeDef *)((sipEnumTypeObject *)(py_type))->type; assert(etd->etd_pyslots != NULL); slot = findSlotInType(etd->etd_pyslots, st); } return slot; } /* * Find a particular slot function in a particular type. */ static void *findSlotInType(sipPySlotDef *psd, sipPySlotType st) { while (psd->psd_func != NULL) { if (psd->psd_type == st) return psd->psd_func; ++psd; } return NULL; } /* * Return the C/C++ address and the generated class structure for a wrapper. */ static void *getPtrTypeDef(sipSimpleWrapper *self, const sipClassTypeDef **ctd) { *ctd = (const sipClassTypeDef *)((sipWrapperType *)Py_TYPE(self))->type; return (sipNotInMap(self) ? NULL : 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)->type = 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->type == NULL) { PyTypeObject *base = ((PyTypeObject *)self)->tp_base; /* * We allow the class to use this as a meta-type without being derived * from a class that uses it. This allows mixin classes that need * their own meta-type to work so long as their meta-type is derived * from this meta-type. This condition is indicated by the pointer to * the generated type structure being NULL. */ if (base != NULL && PyObject_TypeCheck((PyObject *)base, (PyTypeObject *)&sipWrapperType_Type)) self->type = ((sipWrapperType *)base)->type; } else { /* * We must be a generated type so remember the type object in the * generated type structure. */ assert(self->type->u.td_py_type == NULL); self->type->u.td_py_type = (PyTypeObject *)self; } return 0; } /* * The metatype getattro slot. */ static PyObject *sipWrapperType_getattro(PyObject *self, PyObject *name) { if (add_all_lazy_attrs(((sipWrapperType *)self)->type) < 0) return NULL; return PyType_Type.tp_getattro(self, name); } /* * The metatype setattro slot. */ static int sipWrapperType_setattro(PyObject *self, PyObject *name, PyObject *value) { if (add_all_lazy_attrs(((sipWrapperType *)self)->type) < 0) return -1; return PyType_Type.tp_setattro(self, name, value); } /* * The instance new slot. */ static PyObject *sipSimpleWrapper_new(sipWrapperType *wt, PyObject *args, PyObject *kwds) { sipTypeDef *td = wt->type; sipContainerDef *cod; /* Check the base types are not being used directly. */ if (wt == &sipSimpleWrapper_Type || wt == &sipWrapper_Type) { PyErr_Format(PyExc_TypeError, "the %s type cannot be instantiated or sub-classed", ((PyTypeObject *)wt)->tp_name); return NULL; } if (add_all_lazy_attrs(wt->type) < 0) return NULL; if (sipTypeIsMapped(td)) cod = &((sipMappedTypeDef *)td)->mtd_container; else cod = &((sipClassTypeDef *)td)->ctd_container; /* See if it is a mapped type. */ if (sipTypeIsMapped(td)) { PyErr_Format(PyExc_TypeError, "%s.%s represents a mapped type and cannot be instantiated", sipNameOfModule(td->td_module), sipPyNameOfContainer(cod, td)); return NULL; } /* See if it is a namespace. */ if (sipTypeIsNamespace(td)) { PyErr_Format(PyExc_TypeError, "%s.%s represents a C++ namespace and cannot be instantiated", sipNameOfModule(td->td_module), sipPyNameOfContainer(cod, td)); return NULL; } /* * See if the object is being created explicitly rather than being wrapped. */ if (!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(cod, td)); return NULL; } /* See if it is an abstract type. */ if (sipTypeIsAbstract(td) && sipIsExactWrappedType(wt) && ((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(cod, 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->type; sipClassTypeDef *ctd = (sipClassTypeDef *)td; PyObject *unused = NULL; sipFinalFunc final_func; /* Check for an existing C++ instance waiting to be wrapped. */ if (sipGetPending(&sipNew, &owner, &sipFlags) < 0) return -1; if (sipNew == NULL) { PyObject *parseErr = NULL; /* Call the C++ ctor. */ owner = NULL; sipNew = ctd->ctd_init(self, args, kwds, &unused, (PyObject **)&owner, &parseErr); if (sipNew != NULL) { sipFlags = SIP_DERIVED_CLASS; } else if (parseErr == NULL) { /* * The C++ ctor must have raised an exception which has been * translated to a Python exception. */ return -1; } else { sipInitExtenderDef *ie = wt->iextend; /* * 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->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) return 0; /* Call any finalisation code. */ if ((final_func = find_finalisation(ctd)) != 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) 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 i, rc; SIP_SSIZE_T pos; PyObject *unused, *mixin, *mixin_name, *key, *value; PyTypeObject *self_wt = sipTypeAsPyTypeObject(((sipWrapperType *)Py_TYPE(self))->type); PyTypeObject *wt = sipTypeAsPyTypeObject(&ctd->ctd_base); PyMethodDef *pmd; #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; rc = 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) { int i; PyObject *mro, *next; 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 { sipTypeDef *sup_td = getGeneratedType(sup, ctd->ctd_base.td_module); sipFinalFunc func; if ((func = find_finalisation((sipClassTypeDef *)sup_td)) != 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 = (sipClassTypeDef *)getGeneratedType(sup, ctd->ctd_base.td_module); while (sup_ctd->ctd_clear == NULL && !sup++->sc_flag); } if (sup_ctd->ctd_clear != NULL) vret = sup_ctd->ctd_clear(ptr); } /* Remove the instance dictionary. */ tmp = self->dict; self->dict = NULL; Py_XDECREF(tmp); /* Remove any extra references dictionary. */ tmp = self->extra_refs; self->extra_refs = NULL; Py_XDECREF(tmp); /* Remove any user object. */ tmp = self->user; self->user = NULL; Py_XDECREF(tmp); /* 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; 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; 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(PyObject *self, void *closure) { sipSimpleWrapper *sw = (sipSimpleWrapper *)self; /* Create the dictionary if needed. */ if (sw->dict == NULL) { sw->dict = PyDict_New(); if (sw->dict == NULL) return NULL; } Py_INCREF(sw->dict); return sw->dict; } /* * The __dict__ setter. */ static int sipSimpleWrapper_set_dict(PyObject *self, PyObject *value, void *closure) { sipSimpleWrapper *sw = (sipSimpleWrapper *)self; /* Check that any new value really is a dictionary. */ if (value != NULL && !PyDict_Check(value)) { PyErr_Format(PyExc_TypeError, "__dict__ must be set to a dictionary, not a '%s'", Py_TYPE(value)->tp_name); return -1; } Py_XDECREF(sw->dict); Py_XINCREF(value); sw->dict = value; return 0; } /* * The table of getters and setters. */ static PyGetSetDef sipSimpleWrapper_getset[] = { {(char *)"__dict__", sipSimpleWrapper_get_dict, sipSimpleWrapper_set_dict, NULL, NULL}, {NULL, NULL, NULL, NULL, NULL} }; /* * The type data structure. Note that we pretend to be a mapping object and a * sequence object at the same time. Python will choose one over another, * depending on the context, but we implement as much as we can and don't make * assumptions about which Python will choose. */ sipWrapperType sipSimpleWrapper_Type = { #if !defined(STACKLESS) { #endif { PyVarObject_HEAD_INIT(&sipWrapperType_Type, 0) "sip.simplewrapper", /* tp_name */ sizeof (sipSimpleWrapper), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)sipSimpleWrapper_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved (Python v3), tp_compare (Python v2) */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 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 */ }, #if !defined(STACKLESS) }, #endif 0, 0 }; /* * The wrapper clear slot. */ static int sipWrapper_clear(sipWrapper *self) { int vret; sipSimpleWrapper *sw = (sipSimpleWrapper *)self; vret = sipSimpleWrapper_clear(sw); /* Remove any slots connected via a proxy. */ if (sipQtSupport != NULL && sipPossibleProxy(sw)) { void *tx = 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. */ if (sipQtSupport != NULL && sipQtSupport->qt_find_sipslot) { 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) { /* Add the buffer interface. */ #if PY_MAJOR_VERSION >= 3 if (ctd->ctd_getbuffer != NULL) wt->super.as_buffer.bf_getbuffer = (getbufferproc)sipSimpleWrapper_getbuffer; if (ctd->ctd_releasebuffer != NULL) wt->super.as_buffer.bf_releasebuffer = (releasebufferproc)sipSimpleWrapper_releasebuffer; #else if (ctd->ctd_readbuffer != NULL) #if PY_VERSION_HEX >= 0x02050000 wt->super.as_buffer.bf_getreadbuffer = (readbufferproc)sipSimpleWrapper_getreadbuffer; #else wt->super.as_buffer.bf_getreadbuffer = (getreadbufferproc)sipSimpleWrapper_getreadbuffer; #endif if (ctd->ctd_writebuffer != NULL) #if PY_VERSION_HEX >= 0x02050000 wt->super.as_buffer.bf_getwritebuffer = (writebufferproc)sipSimpleWrapper_getwritebuffer; #else wt->super.as_buffer.bf_getwritebuffer = (getwritebufferproc)sipSimpleWrapper_getwritebuffer; #endif if (ctd->ctd_segcount != NULL) #if PY_VERSION_HEX >= 0x02050000 wt->super.as_buffer.bf_getsegcount = (segcountproc)sipSimpleWrapper_getsegcount; #else wt->super.as_buffer.bf_getsegcount = (getsegcountproc)sipSimpleWrapper_getsegcount; #endif if (ctd->ctd_charbuffer != NULL) #if PY_VERSION_HEX >= 0x02050000 wt->super.as_buffer.bf_getcharbuffer = (charbufferproc)sipSimpleWrapper_getcharbuffer; #else wt->super.as_buffer.bf_getcharbuffer = (getcharbufferproc)sipSimpleWrapper_getcharbuffer; #endif #endif /* Add the slots for this type. */ if (ctd->ctd_pyslots != NULL) addTypeSlots(&wt->super, ctd->ctd_pyslots); } /* * Add the slot handler for each slot present in the type. */ static void addTypeSlots(PyHeapTypeObject *heap_to, sipPySlotDef *slots) { PyTypeObject *to; PyNumberMethods *nb; PySequenceMethods *sq; PyMappingMethods *mp; void *f; to = (PyTypeObject *)heap_to; nb = &heap_to->as_number; sq = &heap_to->as_sequence; mp = &heap_to->as_mapping; while ((f = slots->psd_func) != NULL) switch (slots++->psd_type) { case str_slot: to->tp_str = (reprfunc)f; break; case int_slot: if (nb != NULL) nb->nb_int = (unaryfunc)f; break; #if PY_MAJOR_VERSION < 3 case long_slot: if (nb != NULL) nb->nb_long = (unaryfunc)f; break; #endif case float_slot: if (nb != NULL) nb->nb_float = (unaryfunc)f; break; case len_slot: if (mp != NULL) #if PY_VERSION_HEX >= 0x02050000 mp->mp_length = (lenfunc)f; #else mp->mp_length = (inquiry)f; #endif if (sq != NULL) #if PY_VERSION_HEX >= 0x02050000 sq->sq_length = (lenfunc)f; #else sq->sq_length = (inquiry)f; #endif break; case contains_slot: if (sq != NULL) sq->sq_contains = (objobjproc)f; break; case add_slot: if (nb != NULL) nb->nb_add = (binaryfunc)f; break; case concat_slot: if (sq != NULL) sq->sq_concat = (binaryfunc)f; break; case sub_slot: if (nb != NULL) nb->nb_subtract = (binaryfunc)f; break; case mul_slot: if (nb != NULL) nb->nb_multiply = (binaryfunc)f; break; case repeat_slot: if (sq != NULL) #if PY_VERSION_HEX >= 0x02050000 sq->sq_repeat = (ssizeargfunc)f; #else sq->sq_repeat = (intargfunc)f; #endif break; case div_slot: if (nb != NULL) { nb->nb_true_divide = (binaryfunc)f; #if PY_MAJOR_VERSION < 3 nb->nb_divide = (binaryfunc)f; #endif } break; case mod_slot: if (nb != NULL) nb->nb_remainder = (binaryfunc)f; break; case floordiv_slot: if (nb != NULL) nb->nb_floor_divide = (binaryfunc)f; break; case truediv_slot: if (nb != NULL) nb->nb_true_divide = (binaryfunc)f; break; case and_slot: if (nb != NULL) nb->nb_and = (binaryfunc)f; break; case or_slot: if (nb != NULL) nb->nb_or = (binaryfunc)f; break; case xor_slot: if (nb != NULL) nb->nb_xor = (binaryfunc)f; break; case lshift_slot: if (nb != NULL) nb->nb_lshift = (binaryfunc)f; break; case rshift_slot: if (nb != NULL) nb->nb_rshift = (binaryfunc)f; break; case iadd_slot: if (nb != NULL) nb->nb_inplace_add = (binaryfunc)f; break; case iconcat_slot: if (sq != NULL) sq->sq_inplace_concat = (binaryfunc)f; break; case isub_slot: if (nb != NULL) nb->nb_inplace_subtract = (binaryfunc)f; break; case imul_slot: if (nb != NULL) nb->nb_inplace_multiply = (binaryfunc)f; break; case irepeat_slot: if (sq != NULL) #if PY_VERSION_HEX >= 0x02050000 sq->sq_inplace_repeat = (ssizeargfunc)f; #else sq->sq_inplace_repeat = (intargfunc)f; #endif break; case idiv_slot: if (nb != NULL) { nb->nb_inplace_true_divide = (binaryfunc)f; #if PY_MAJOR_VERSION < 3 nb->nb_inplace_divide = (binaryfunc)f; #endif } break; case imod_slot: if (nb != NULL) nb->nb_inplace_remainder = (binaryfunc)f; break; case ifloordiv_slot: if (nb != NULL) nb->nb_inplace_floor_divide = (binaryfunc)f; break; case itruediv_slot: if (nb != NULL) nb->nb_inplace_true_divide = (binaryfunc)f; break; case iand_slot: if (nb != NULL) nb->nb_inplace_and = (binaryfunc)f; break; case ior_slot: if (nb != NULL) nb->nb_inplace_or = (binaryfunc)f; break; case ixor_slot: if (nb != NULL) nb->nb_inplace_xor = (binaryfunc)f; break; case ilshift_slot: if (nb != NULL) nb->nb_inplace_lshift = (binaryfunc)f; break; case irshift_slot: if (nb != NULL) nb->nb_inplace_rshift = (binaryfunc)f; break; case invert_slot: if (nb != NULL) nb->nb_invert = (unaryfunc)f; break; case call_slot: to->tp_call = slot_call; break; case getitem_slot: if (mp != NULL) mp->mp_subscript = (binaryfunc)f; if (sq != NULL) sq->sq_item = slot_sq_item; break; case setitem_slot: case delitem_slot: if (mp != NULL) mp->mp_ass_subscript = slot_mp_ass_subscript; if (sq != NULL) sq->sq_ass_item = slot_sq_ass_item; break; case lt_slot: case le_slot: case eq_slot: case ne_slot: case gt_slot: case ge_slot: to->tp_richcompare = slot_richcompare; break; #if PY_MAJOR_VERSION < 3 case cmp_slot: to->tp_compare = (cmpfunc)f; break; #endif case bool_slot: if (nb != NULL) #if PY_MAJOR_VERSION >= 3 nb->nb_bool = (inquiry)f; #else nb->nb_nonzero = (inquiry)f; #endif break; case neg_slot: if (nb != NULL) nb->nb_negative = (unaryfunc)f; break; case repr_slot: to->tp_repr = (reprfunc)f; break; case hash_slot: to->tp_hash = (hashfunc)f; break; case pos_slot: if (nb != NULL) nb->nb_positive = (unaryfunc)f; break; case abs_slot: if (nb != NULL) nb->nb_absolute = (unaryfunc)f; break; #if PY_VERSION_HEX >= 0x02050000 case index_slot: if (nb != NULL) nb->nb_index = (unaryfunc)f; break; #endif case iter_slot: to->tp_iter = (getiterfunc)f; break; case next_slot: to->tp_iternext = (iternextfunc)f; break; case setattr_slot: to->tp_setattro = (setattrofunc)f; break; } } /* * Remove the object from the map and call the C/C++ dtor if we own the * instance. */ static void forgetObject(sipSimpleWrapper *sw) { /* * This is needed because we release the GIL when calling a C++ dtor. * Without it the cyclic garbage collector can be invoked from another * thread resulting in a crash. */ PyObject_GC_UnTrack((PyObject *)sw); /* * 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 * is only called externally by PyQt3. */ static int sip_api_visit_slot(sipSlot *slot, visitproc visit, void *arg) { /* See if the slot has an extra reference. */ if (slot->weakSlot == Py_True && slot->pyobj != Py_None) return visit(slot->pyobj, arg); return 0; } /* * Clear a slot if it has an extra reference to keep it alive. This is only * called externally by PyQt3. */ static void sip_api_clear_any_slot_reference(sipSlot *slot) { if (slot->weakSlot == Py_True) { PyObject *xref = slot->pyobj; /* * Replace the slot with None. We don't use NULL as this has another * meaning. */ Py_INCREF(Py_None); slot->pyobj = Py_None; Py_DECREF(xref); } } /* * Convert a Python object to a character and raise an exception if there was * an error. */ static char sip_api_bytes_as_char(PyObject *obj) { char ch; if (parseBytes_AsChar(obj, &ch) < 0) { PyErr_Format(PyExc_TypeError, #if PY_MAJOR_VERSION >= 3 "bytes of length 1 expected not '%s'", #else "string of length 1 expected not '%s'", #endif Py_TYPE(obj)->tp_name); return '\0'; } return ch; } /* * Convert a Python object to a string and raise an exception if there was * an error. */ static const char *sip_api_bytes_as_string(PyObject *obj) { const char *a; if (parseBytes_AsString(obj, &a) < 0) { PyErr_Format(PyExc_TypeError, #if PY_MAJOR_VERSION >= 3 "bytes expected not '%s'", #else "string expected not '%s'", #endif Py_TYPE(obj)->tp_name); return NULL; } return a; } /* * Convert a Python ASCII string object to a character and raise an exception * if there was an error. */ static char sip_api_string_as_ascii_char(PyObject *obj) { char ch; if (parseString_AsASCIIChar(obj, &ch) < 0) 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 *obj, PyObject *ignore) { /* 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, *atexit_module, *register_func, *res; if ((notifier = PyCFunction_New(&md, NULL)) == NULL) return; if ((atexit_module = PyImport_ImportModule("atexit")) == NULL) { Py_DECREF(notifier); return; } if ((register_func = PyObject_GetAttrString(atexit_module, "register")) == NULL) { Py_DECREF(atexit_module); Py_DECREF(notifier); return; } res = PyObject_CallFunctionObjArgs(register_func, notifier, NULL); Py_XDECREF(res); Py_DECREF(register_func); Py_DECREF(atexit_module); 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; if (PyArg_ParseTuple(args, "O!i:enableautoconversion", &sipWrapperType_Type, &wt, &enable)) { sipTypeDef *td = wt->type; 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; for (pr = proxyResolvers; pr != NULL; pr = pr->next) if (pr->td == td) proxy = pr->resolver(proxy); return proxy; } sip-4.15.5/siplib/siplib.sbf.in0000644000076500000240000000146612261241140016325 0ustar philstaff00000000000000# This is the build file for the extension module. # # Copyright (c) 2014 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 bool.cpp headers = sip.h sipint.h array.h sip-4.15.5/siplib/threads.c0000644000076500000240000001127712261241146015547 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) 2014 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 "sip.h" #include "sipint.h" /* * The data associated with pending request to wrap an object. */ typedef struct _pendingDef { void *cpp; /* The C/C++ object ot be wrapped. */ sipWrapper *owner; /* The owner of the object. */ int flags; /* The flags. */ } pendingDef; #ifdef WITH_THREAD #include /* * 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.15.5/siplib/voidptr.c0000644000076500000240000006022312261241151015573 0ustar philstaff00000000000000/* * SIP library code. * * Copyright (c) 2014 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" #include "sipint.h" /* The object data structure. */ typedef struct { PyObject_HEAD void *voidptr; SIP_SSIZE_T size; int rw; } sipVoidPtrObject; /* The structure used to hold the results of a voidptr conversion. */ struct vp_values { void *voidptr; SIP_SSIZE_T size; int rw; }; static 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); #if defined(SIP_USE_PYCAPSULE) /* * Implement ascapsule() for the type. */ static PyObject *sipVoidPtr_ascapsule(sipVoidPtrObject *v, PyObject *arg) { return PyCapsule_New(v->voidptr, NULL, NULL); } #endif #if defined(SIP_SUPPORT_PYCOBJECT) /* * Implement ascobject() for the type. */ static PyObject *sipVoidPtr_ascobject(sipVoidPtrObject *v, PyObject *arg) { return PyCObject_FromVoidPtr(v->voidptr, NULL); } #endif /* * Implement asstring() for the type. */ static PyObject *sipVoidPtr_asstring(sipVoidPtrObject *v, PyObject *args, PyObject *kw) { static char *kwlist[] = {"size", NULL}; SIP_SSIZE_T size = -1; if (!PyArg_ParseTupleAndKeywords(args, kw, #if PY_VERSION_HEX >= 0x02050000 "|n:asstring", #else "|i:asstring", #endif kwlist, &size)) return NULL; /* Use the current size if one wasn't explicitly given. */ if (size < 0) size = v->size; if (size < 0) { PyErr_SetString(PyExc_ValueError, "a size must be given or the sip.voidptr object must have a size"); return NULL; } return SIPBytes_FromStringAndSize(v->voidptr, size); } /* * Implement getsize() for the type. */ static PyObject *sipVoidPtr_getsize(sipVoidPtrObject *v, PyObject *arg) { #if PY_MAJOR_VERSION >= 3 return PyLong_FromSsize_t(v->size); #elif PY_VERSION_HEX >= 0x02050000 return PyInt_FromSsize_t(v->size); #else return PyInt_FromLong(v->size); #endif } /* * Implement setsize() for the type. */ static PyObject *sipVoidPtr_setsize(sipVoidPtrObject *v, PyObject *arg) { SIP_SSIZE_T size; #if PY_MAJOR_VERSION >= 3 size = PyLong_AsSsize_t(arg); #elif PY_VERSION_HEX >= 0x02050000 size = PyInt_AsSsize_t(arg); #else size = (int)PyInt_AsLong(arg); #endif if (PyErr_Occurred()) return NULL; v->size = size; Py_INCREF(Py_None); return Py_None; } /* * Implement getwriteable() for the type. */ static PyObject *sipVoidPtr_getwriteable(sipVoidPtrObject *v, PyObject *arg) { return PyBool_FromLong(v->rw); } /* * Implement setwriteable() for the type. */ static PyObject *sipVoidPtr_setwriteable(sipVoidPtrObject *v, PyObject *arg) { int rw; rw = (int)SIPLong_AsLong(arg); if (PyErr_Occurred()) return NULL; v->rw = rw; Py_INCREF(Py_None); return Py_None; } /* The methods data structure. */ static PyMethodDef sipVoidPtr_Methods[] = { #if defined(SIP_USE_PYCAPSULE) {"ascapsule", (PyCFunction)sipVoidPtr_ascapsule, METH_NOARGS, NULL}, #endif #if defined(SIP_SUPPORT_PYCOBJECT) {"ascobject", (PyCFunction)sipVoidPtr_ascobject, METH_NOARGS, NULL}, #endif {"asstring", (PyCFunction)sipVoidPtr_asstring, METH_KEYWORDS, NULL}, {"getsize", (PyCFunction)sipVoidPtr_getsize, METH_NOARGS, NULL}, {"setsize", (PyCFunction)sipVoidPtr_setsize, METH_O, NULL}, {"getwriteable", (PyCFunction)sipVoidPtr_getwriteable, METH_NOARGS, NULL}, {"setwriteable", (PyCFunction)sipVoidPtr_setwriteable, METH_O, NULL}, {NULL} }; /* * 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 */ 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 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 }; /* * 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 sipVoidPtr_slice, /* sq_slice */ sipVoidPtr_ass_item, /* sq_ass_item */ sipVoidPtr_ass_slice, /* sq_ass_slice */ #endif }; #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 */ }; /* * 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 PY_VERSION_HEX >= 0x03010000 PyErr_SetString(PyExc_TypeError, "a single integer, CObject, None, buffer protocol implementor or another sip.voidptr object is required"); #else PyErr_SetString(PyExc_TypeError, "a single integer, Capsule, CObject, None, buffer protocol implementor or another sip.voidptr object is required"); #endif return 0; } } vp->voidptr = ptr; vp->size = size; vp->rw = rw; return 1; } sip-4.15.5/siputils.py0000644000076500000240000026125512301625407014721 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) 2014 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.path.curdir # Assume we are building in the source tree. self._src_dir = self.dir if universal is None: self._universal = configuration.universal else: self._universal = universal if arch is None: self._arch = configuration.arch else: self._arch = arch 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 = [] # 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"))) if self._src_dir != self.dir: mfile.write("VPATH = %s\n\n" % self._src_dir) # These probably don't matter. if self.generator == "MINGW": mfile.write(".SUFFIXES: .cpp .cxx .cc .C .c\n\n") elif self.generator == "UNIX": mfile.write(".SUFFIXES: .c .o .cpp .cc .cxx .C\n\n") else: mfile.write(".SUFFIXES: .c .cpp .cc .cxx .C\n\n") if self.generator in ("MSVC", "MSVC.NET", "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 %s\n" % (cpp, mf)) 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 %s\n" % (cpp, mf)) 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(v): """Convert a 3 part version number encoded as a hexadecimal value to a string. """ return "%u.%u.%u" % (((v >> 16) & 0xff), ((v >> 8) & 0xff), (v & 0xff)) def read_version(filename, description, numdefine=None, strdefine=None): """Read the version information for a package from a file. The information is specified as #defines of a numeric (hexadecimal or decimal) value and/or a string value. filename is the name of the file. description is the descriptive name of the package. numdefine is the name of the #define of the numeric version. It is ignored if it is None. strdefine is the name of the #define of the string version. It is ignored if it is None. Returns a tuple of the version as a number and as a string. """ need_num = numdefine is not None need_str = strdefine is not None vers = None versstr = None f = open(filename) l = f.readline() while l and (need_num or need_str): wl = l.split() if len(wl) >= 3 and wl[0] == "#define": if need_num and wl[1] == numdefine: v = wl[2] if v[0:2] == "0x": vers = int(v, 16) else: dec = int(v) maj = dec / 100 min = (dec % 100) / 10 bug = (dec % 10) vers = (maj << 16) + (min << 8) + bug need_num = 0 if need_str and wl[1] == strdefine: # Take account of embedded spaces. versstr = ' '.join(wl[2:])[1:-1] need_str = 0 l = f.readline() f.close() if need_num or need_str: error("The %s version number could not be determined by parsing %s." % (description, filename)) return (vers, versstr) def create_content(cdict, macros=None): """Convert a dictionary to a string (typically to use as the content to a call to create_config_module()). Dictionary values that are strings are quoted. Dictionary values that are lists are converted to quoted strings. dict is the dictionary. macros is the optional dictionary of platform specific build macros. """ content = "_pkg_config = {\n" keys = list(cdict.keys()) keys.sort() # Format it nicely. width = 0 for k in keys: klen = len(k) if width < klen: width = klen for k in keys: val = cdict[k] vtype = type(val) delim = None if val is None: val = "None" elif vtype == list: val = ' '.join(val) delim = "'" elif vtype == int: if k.find("version") >= 0: # Assume it's a hexadecimal version number. It doesn't matter # if it isn't, we are just trying to make it look pretty. val = "0x%06x" % val else: val = str(val) else: val = str(val) delim = "'" if delim: if "'" in val: delim = "'''" val = delim + val + delim content = content + " '" + k + "':" + (" " * (width - len(k) + 2)) + val.replace("\\", "\\\\") if k != keys[-1]: content = content + "," content = content + "\n" content = content + "}\n\n" # Format the optional macros. content = content + "_default_macros = " if macros: content = content + "{\n" names = list(macros.keys()) names.sort() width = 0 for c in names: clen = len(c) if width < clen: width = clen for c in names: if c == names[-1]: sep = "" else: sep = "," val = macros[c] if "'" in val: delim = "'''" else: delim = "'" k = "'" + c + "':" content = content + " %-*s %s%s%s%s\n" % (1 + width + 2, k, delim, val.replace("\\", "\\\\"), delim, sep) content = content + "}\n" else: content = content + "None\n" return content def create_config_module(module, template, content, macros=None): """Create a configuration module by replacing "@" followed by "SIP_CONFIGURATION" followed by "@" in a template file with a content string. module is the name of the module file. template is the name of the template file. content is the content string. If it is a dictionary it is first converted to a string using create_content(). macros is an optional dictionary of platform specific build macros. It is only used if create_content() is called to convert the content to a string. """ if type(content) == dict: content = create_content(content, macros) # Allow this file to used as a template. key = "@" + "SIP_CONFIGURATION" + "@" df = open(module, "w") sf = open(template, "r") line = sf.readline() while line: if line.find(key) >= 0: line = content df.write(line) line = sf.readline() 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 snapshot is indicated by a negative version number.) tags is the dictionary of tags keyed by version number. The tag used is the one with the smallest key (ie. earliest version) that is greater than the given version number. description is the descriptive name of the package used for error messages. Returns the corresponding tag. """ vl = list(tags.keys()) vl.sort() # For a snapshot use the latest tag. if version < 0: tag = tags[vl[-1]] else: for v in vl: if version < v: tag = tags[v] break else: error("Unsupported %s version: 0x%06x." % (description, version)) return tag def error(msg): """Display an error message and terminate. msg is the text of the error message. """ sys.stderr.write(format("Error: " + msg) + "\n") sys.exit(1) def inform(msg): """Display an information message. msg is the text of the error message. """ sys.stdout.write(format(msg) + "\n") def format(msg, leftmargin=0, rightmargin=78): """Format a message by inserting line breaks at appropriate places. msg is the text of the message. leftmargin is the position of the left margin. rightmargin is the position of the right margin. Return the formatted message. """ curs = leftmargin fmsg = " " * leftmargin for w in msg.split(): l = len(w) if curs != leftmargin and curs + l > rightmargin: fmsg = fmsg + "\n" + (" " * leftmargin) curs = leftmargin if curs > leftmargin: fmsg = fmsg + " " curs = curs + 1 fmsg = fmsg + w curs = curs + l return fmsg def parse_build_macros(filename, names, overrides=None, properties=None): """Parse a qmake compatible file of build system macros and convert it to a dictionary. A macro is a name/value pair. The dictionary is returned or None if any of the overrides was invalid. filename is the name of the file to parse. names is a list of the macro names to extract from the file. overrides is an optional list of macro names and values that modify those found in the file. They are of the form "name=value" (in which case the value replaces the value found in the file) or "name+=value" (in which case the value is appended to the value found in the file). properties is an optional dictionary of property name and values that are used to resolve any expressions of the form "$[name]" in the file. """ # Validate and convert the overrides to a dictionary. orides = {} if overrides is not None: for oride in overrides: prefix = "" name_end = oride.find("+=") if name_end >= 0: prefix = "+" val_start = name_end + 2 else: name_end = oride.find("=") if name_end >= 0: val_start = name_end + 1 else: return None name = oride[:name_end] if name not in names: return None orides[name] = prefix + oride[val_start:] # This class defines a file like object that handles the nested include() # directives in qmake files. class qmake_build_file_reader: def __init__(self, filename): self.filename = filename self.currentfile = None self.filestack = [] self.pathstack = [] self.cond_fname = None self._openfile(filename) def _openfile(self, filename): try: f = open(filename, 'r') except IOError: # If this file is conditional then don't raise an error. if self.cond_fname == filename: return error("Unable to open %s" % filename) if self.currentfile: self.filestack.append(self.currentfile) self.pathstack.append(self.path) self.currentfile = f self.path = os.path.dirname(filename) def readline(self): line = self.currentfile.readline() sline = line.strip() if self.cond_fname and sline == '}': # The current condition is closed. self.cond_fname = None line = self.currentfile.readline() elif sline.startswith('exists(') and sline.endswith('{'): # A new condition is opened so extract the filename. self.cond_fname = self._normalise(sline[:-1].strip()[7:-1].strip()) line = self.currentfile.readline() elif sline.startswith('include('): nextfile = self._normalise(sline[8:-1].strip()) self._openfile(nextfile) return self.readline() if not line: 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 line = line.strip() # Ignore comments. if line and line[0] != "#": assstart = line.find("+") if assstart > 0 and line[assstart + 1] == '=': adding = True assend = assstart + 1 else: adding = False assstart = line.find("=") assend = assstart if assstart > 0: lhs = line[:assstart].strip() rhs = line[assend + 1:].strip() # Remove the escapes for any quotes. rhs = rhs.replace(r'\"', '"').replace(r"\'", "'") if adding and rhs != "": orig_rhs = raw.get(lhs) if orig_rhs is not None: rhs = orig_rhs + " " + rhs raw[lhs] = _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.15.5/specs/0000755000076500000240000000000012125131242013566 5ustar philstaff00000000000000sip-4.15.5/specs/aix-g++0000644000076500000240000000363211562553731014667 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.15.5/specs/aix-g++-640000644000076500000240000000371311562553731015116 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.15.5/specs/aix-xlc0000644000076500000240000000366311562553731015105 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.15.5/specs/aix-xlc-640000644000076500000240000000406711562553731015333 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.15.5/specs/bsdi-g++0000644000076500000240000000374111562553731015030 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.15.5/specs/cygwin-g++0000644000076500000240000000414411562553731015405 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.15.5/specs/darwin-g++0000644000076500000240000000442311562553731015371 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.15.5/specs/dgux-g++0000644000076500000240000000342011562553731015050 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.15.5/specs/freebsd-g++0000644000076500000240000000402511562553731015515 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.15.5/specs/freebsd-g++340000644000076500000240000000410311562553731015661 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.15.5/specs/freebsd-g++400000644000076500000240000000410311562553731015656 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.15.5/specs/freebsd-icc0000644000076500000240000000656411562553731015711 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.15.5/specs/hpux-acc0000644000076500000240000000576511562553731015255 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.15.5/specs/hpux-acc-640000644000076500000240000000771411562553731015500 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.15.5/specs/hpux-acc-o640000644000076500000240000000755011562553731015655 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.15.5/specs/hpux-cc0000644000076500000240000000552611562553731015107 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.15.5/specs/hpux-g++0000644000076500000240000000427711562553731015100 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.15.5/specs/hpux-g++-640000644000076500000240000000434511562553731015323 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.15.5/specs/hpuxi-acc0000644000076500000240000000766111562553731015423 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.15.5/specs/hpuxi-acc-640000644000076500000240000000766111562553731015652 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.15.5/specs/hurd-g++0000644000076500000240000000352311562553731015047 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.15.5/specs/irix-cc0000644000076500000240000000707311562553731015075 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.15.5/specs/irix-cc-640000644000076500000240000000706411562553731015324 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.15.5/specs/irix-cc-o320000644000076500000240000000423611562553731015474 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.15.5/specs/irix-g++0000644000076500000240000000406411562553731015061 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.15.5/specs/irix-g++-640000644000076500000240000000411111562553731015301 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.15.5/specs/linux-arm-g++0000644000076500000240000000452711712024256016016 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.15.5/specs/linux-arm-thumb-g++0000644000076500000240000000456711712024256017137 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.15.5/specs/linux-armv6-g++0000644000076500000240000000454411712024256016271 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.15.5/specs/linux-cxx0000644000076500000240000000342511562553731015473 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.15.5/specs/linux-ecc-640000644000076500000240000000377011562553731015655 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.15.5/specs/linux-g++0000644000076500000240000000454511562553731015251 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.15.5/specs/linux-g++-320000644000076500000240000000455711562553731015476 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.15.5/specs/linux-g++-640000644000076500000240000000473111562553731015475 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.15.5/specs/linux-icc0000644000076500000240000000466011673627050015430 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.15.5/specs/linux-kcc0000644000076500000240000000474011562553731015432 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.15.5/specs/linux-kylix0000644000076500000240000000377211562553731016036 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.15.5/specs/linux-lsb0000644000076500000240000000456011562553731015452 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.15.5/specs/linux-pgcc0000644000076500000240000000374711562553731015614 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.15.5/specs/lynxos-g++0000644000076500000240000000404311562553731015437 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.15.5/specs/macx-g++0000644000076500000240000000557311665463150015043 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.15.5/specs/macx-mwerks0000644000076500000240000000136111562553731015767 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.15.5/specs/macx-pbuilder0000644000076500000240000000451211562553731016266 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.15.5/specs/macx-xlc0000644000076500000240000000517411562553731015253 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.15.5/specs/netbsd-g++0000644000076500000240000000410111562553731015355 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.15.5/specs/openbsd-g++0000644000076500000240000000405011562553731015533 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.15.5/specs/qnx-g++0000644000076500000240000000376411562553731014722 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.15.5/specs/reliant-cds0000644000076500000240000000404111562553731015734 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.15.5/specs/reliant-cds-640000644000076500000240000000406511562553731016171 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.15.5/specs/sco-cc0000644000076500000240000000353211562553731014702 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.15.5/specs/sco-g++0000644000076500000240000000335611562553731014675 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.15.5/specs/solaris-cc0000644000076500000240000000413511562553731015572 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.15.5/specs/solaris-cc-640000644000076500000240000000610511562553731016020 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.15.5/specs/solaris-g++0000644000076500000240000000453611562553731015566 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.15.5/specs/solaris-g++-640000644000076500000240000000645611562553731016020 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.15.5/specs/tru64-cxx0000644000076500000240000000360211562553731015315 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.15.5/specs/tru64-g++0000644000076500000240000000356311562553731015075 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.15.5/specs/unixware-cc0000644000076500000240000000376611562553731015771 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.15.5/specs/unixware-g++0000644000076500000240000000360111562553731015744 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.15.5/specs/win32-borland0000644000076500000240000000456711562553731016125 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.15.5/specs/win32-g++0000644000076500000240000000606611562553731015054 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.15.5/specs/win32-icc0000644000076500000240000000531511562553731015232 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.15.5/specs/win32-msvc0000644000076500000240000000526611562553731015451 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.15.5/specs/win32-msvc.net0000644000076500000240000000535711562553731016237 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.15.5/specs/win32-msvc20050000644000076500000240000000574611673627050015762 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.15.5/specs/win32-msvc20080000644000076500000240000000751412125131242015742 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.15.5/specs/win32-msvc20100000644000076500000240000000751412125131242015733 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 QT_LARGEFILE_SUPPORT 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 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 = .vcxproj VCSOLUTION_EXTENSION = .sln VCPROJ_KEYWORD = Qt4VSv1.0 load(qt_config) sip-4.15.5/specs/win32-watcom0000644000076500000240000000315311562553731015764 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.15.5/sphinx/0000755000076500000240000000000012310606636013774 5ustar philstaff00000000000000sip-4.15.5/sphinx/annotations.rst0000644000076500000240000011437312274165576017110 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); .. argument-annotation:: DocType .. versionadded:: 4.10 This string annotation specifies the type of the argument as it will appear in any generated docstrings. It is usually used with arguments of type :stype:`SIP_PYOBJECT` to provide a more specific type. .. argument-annotation:: DocValue .. versionadded:: 4.10 This string annotation specifies the default value of the argument as it will appear in any generated docstrings. .. argument-annotation:: Encoding This string annotation specifies that the corresponding argument (which should be either ``char``, ``const char``, ``char *`` or ``const char *``) refers to an encoded character or ``'\0'`` terminated encoded string with the specified encoding. The encoding can be either ``"ASCII"``, ``"Latin-1"``, ``"UTF-8"`` or ``"None"``. An encoding of ``"None"`` means that the corresponding argument refers to an unencoded character or string. The default encoding is specified by the :directive:`%DefaultEncoding` directive. If the directive is not specified then ``None`` is used. Python v3 will use the ``bytes`` type to represent the argument if the encoding is ``"None"`` and the ``str`` type otherwise. Python v2 will use the ``str`` type to represent the argument if the encoding is ``"None"`` and the ``unicode`` type otherwise. .. argument-annotation:: GetWrapper This boolean annotation is only ever used in conjunction with handwritten code specified with the :directive:`%MethodCode` directive. It causes an extra variable to be generated for the corresponding argument which is a pointer to the Python object that wraps the argument. See the :directive:`%MethodCode` directive for more detail. .. argument-annotation:: In This boolean annotation is used to specify that the corresponding argument (which should be a pointer type) is used to pass a value to the function. For pointers to wrapped C structures or C++ class instances, ``char *`` and ``unsigned char *`` then this annotation is assumed unless the :aanno:`Out` annotation is specified. For pointers to other types then this annotation must be explicitly specified if required. The argument will be dereferenced to obtain the actual value. Both :aanno:`In` and :aanno:`Out` may be specified for the same argument. .. argument-annotation:: KeepReference This 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 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. .. _ref-class-annos: Class Annotations ----------------- .. class-annotation:: Abstract This boolean annotation is used to specify that the class has additional pure virtual methods that have not been specified and so it cannot be instantiated or sub-classed from Python. .. class-annotation:: AllowNone .. versionadded:: 4.8.2 Normally when a Python object is converted to a C/C++ instance ``None`` is handled automatically before the class's :directive:`%ConvertToTypeCode` is called. This boolean annotation specifies that the handling of ``None`` will be left to the :directive:`%ConvertToTypeCode`. The annotation is ignored if the class does not have any :directive:`%ConvertToTypeCode`. .. class-annotation:: API .. versionadded:: 4.9 This API range annotation is used to specify an API and corresponding range of version numbers that the class is enabled for. If a class or mapped type has different implementations enabled for different ranges of version numbers then those ranges must not overlap. 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:: 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:: 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:: 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 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` .. _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:: 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:: 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:: DocType .. versionadded:: 4.10 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:: 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:: NewThread This boolean annotation specifies that the function will create a new thread. .. function-annotation:: NoArgParser This boolean annotation is used with methods and global functions to specify that the supplied :directive:`%MethodCode` will handle the parsing of the arguments. .. function-annotation:: NoCopy .. versionadded:: 4.10.1 This boolean annotation is used with methods and global functions that return a ``const`` reference to a class. Normally, if the class defines a copy constructor then a copy of the returned reference is automatically created and wrapped. The copy will be owned by Python. If the annotation is specified then the copy is not made and the original reference is wrapped instead and will be owned by C++. .. function-annotation:: NoDerived This boolean annotation is only used with C++ constructors. In many cases SIP generates a derived class for each class being wrapped (see :ref:`ref-derived-classes`). This derived class contains constructors with the same C++ signatures as the class being wrapped. Sometimes you may want to define a Python constructor that has no corresponding C++ constructor. This annotation is used to suppress the generation of the constructor in the derived class. .. function-annotation:: NoKeywordArgs .. versionadded:: 4.10 .. 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:: 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:: 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 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` .. _ref-variable-annos: Variable Annotations -------------------- .. variable-annotation:: DocType .. versionadded:: 4.10 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:: 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` sip-4.15.5/sphinx/build_system.rst0000644000076500000240000007465112266235021017242 0ustar philstaff00000000000000.. _ref-build-system: The Build System ================ .. module:: sipconfig The purpose of the build system is to make it easy for you to write configuration scripts in Python for your own bindings. The build system takes care of the details of particular combinations of platform and compiler. It supports over 50 different platform/compiler combinations. The build system is implemented as a pure Python module called :mod:`sipconfig` that contains a number of classes and functions. Using this module you can write bespoke configuration scripts (e.g. PyQt's ``configure.py``) or use it with other Python based build systems (e.g. `Distutils `_ 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 PyQt but all three packages are maintained by different developers. To make this easier PyQt includes its own configuration module, ``pyqtconfig``, that contains additional classes intended to be used by the configuration scripts of bindings built on top of PyQt. The SIP build system includes facilities that do a lot of the work of creating these additional configuration modules. .. function:: create_config_module(module, template, content[, macros=None]) This creates a configuration module (e.g. ``pyqtconfig``) from a template file and a string. :param module: the name of the configuration module file to create. :param template: the name of the template file. :param content: a string which replaces every occurence of the pattern ``@SIP_CONFIGURATION@`` in the template file. The content string is usually created from a Python dictionary using :func:`sipconfig.create_content()`. *content* may also be a dictionary, in which case :func:`sipconfig.create_content()` is automatically called to convert it to a string. :param macros: an optional dictionary of platform specific build macros. It is only used if :func:`sipconfig.create_content()` is called automatically to convert a *content* dictionary to a string. .. function:: create_content(dict[, macros=None]) -> string This converts a Python dictionary to a string that can be parsed by the Python interpreter and converted back to an equivalent dictionary. It is typically used to generate the content string for :func:`sipconfig.create_config_module()`. :param dict: the Python dictionary to convert. :param macros: the optional dictionary of platform specific build macros. :return: the string representation of the dictionary. .. function:: create_wrapper(script, wrapper[, gui=0[, use_arch='']]) -> string This creates a platform dependent executable wrapper around a Python script. :param script: the full pathname of the script. :param wrapper: the full pathname of the wrapper to create, excluding any platform specific extension. :param gui: is non-zero if a GUI enabled version of the interpreter should be used on platforms that require it. :param use_arch: is the MacOS/X 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 snapshot is indicated by a negative version number.) :param tags: the dictionary of SIP version tags keyed by the corresponding C/C++ library version number. The tag used is the one with the smallest key (i.e. earliest version) that is greater than *version*. :param description: a descriptive name of the C/C++ library used in error messages. :return: the SIP version tag. :func:`sipconfig.error()` is called if the C/C++ library version number did not correspond to a SIP version tag. .. function:: version_to_string(v) -> string This converts a 3 part version number encoded as a hexadecimal value to a string. :param v: the version number. :return: a string. .. class:: Configuration This class encapsulates configuration values that can be accessed as instance objects. A sub-class may provide a dictionary of additional configuration values in its constructor the elements of which will have precedence over the super-class's values. The following configuration values are provided: .. attribute:: default_bin_dir The name of the directory where executables should be installed by default. .. attribute:: default_mod_dir The name of the directory where SIP generated modules should be installed by default. .. attribute:: default_sip_dir The name of the base directory where the ``.sip`` files for SIP generated modules should be installed by default. A sub-directory with the same name as the module should be created and its ``.sip`` files should be installed in the sub-directory. The ``.sip`` files only need to be installed if you might want to build other bindings based on them. .. attribute:: platform The name of the platform/compiler for which the build system has been configured for. .. attribute:: py_conf_inc_dir The name of the directory containing the ``pyconfig.h`` header file. .. attribute:: py_inc_dir The name of the directory containing the ``Python.h`` header file. .. attribute:: py_lib_dir The name of the directory containing the Python interpreter library. .. attribute:: py_version The Python version as a 3 part hexadecimal number (e.g. v2.3.3 is represented as ``0x020303``). .. attribute:: sip_bin The full pathname of the SIP executable. .. attribute:: sip_config_args The command line passed to ``configure.py`` when SIP was configured. .. attribute:: sip_inc_dir The name of the directory containing the ``sip.h`` header file. .. attribute:: sip_mod_dir The name of the directory containing the SIP module. .. attribute:: sip_version The SIP version as a 3 part hexadecimal number (e.g. v4.0.0 is represented as ``0x040000``). .. attribute:: sip_version_str The SIP version as a string. For development snapshots it will start with ``snapshot-``. .. attribute:: universal The name of the MacOS/X SDK used when creating universal binaries. .. attribute:: arch The space separated MacOS/X architectures to build. .. 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:: 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 (see :ref:`ref-builtin`). :param console: see :meth:`sipconfig.Makefile.__init__`. :param qt: see :meth:`sipconfig.Makefile.__init__`. :param opengl: see :meth:`sipconfig.Makefile.__init__`. :param threaded: see :meth:`sipconfig.Makefile.__init__`. :param warnings: see :meth:`sipconfig.Makefile.__init__`. :param debug: see :meth:`sipconfig.Makefile.__init__`. :param dir: see :meth:`sipconfig.Makefile.__init__`. :param makefile: see :meth:`sipconfig.Makefile.__init__`. :param installs: see :meth:`sipconfig.Makefile.__init__`. :param strip: is set if the module should be stripped of unneeded symbols after installation. It is ignored if either *debug* or *static* is set, or if the platform doesn't support it. :param export_all: is set if all of the module's symbols should be exported rather than just the module's initialisation function. Exporting all symbols increases the size of the module and slows down module load times but may avoid problems with modules that use C++ exceptions. All symbols are exported if either *debug* or *static* is set, or if the platform doesn't support it. :param universal: see :meth:`sipconfig.Makefile.__init__`. :param arch: see :meth:`sipconfig.Makefile.__init__`. :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.15.5/sphinx/builtin.rst0000644000076500000240000000467511673627050016214 0ustar philstaff00000000000000.. _ref-builtin: Builtin Modules and Custom Interpreters ======================================= Sometimes you want to create a custom Python interpreter with some modules built in to the interpreter itself rather than being dynamically loaded. To do this the module must be created as a static library and linked with a custom stub and the normal Python library. To build the SIP module as a static library you must pass the ``-k`` command line option to ``configure.py``. You should then build and install SIP as normal. (Note that, because the module is now a static library, you will not be able to import it.) To build a module you have created for your own library you must modify your own configuration script to pass a non-zero value as the ``static`` argument of the ``__init__()`` method of the :class:`sipconfig.ModuleMakefile` class (or any derived class you have created). Normally you would make this configurable using a command line option in the same way that SIP's ``configure.py`` handles it. The next stage is to create a custom stub and a Makefile. The SIP distribution contains a directory called ``custom`` which contains example stubs and a Python script that will create a correct Makefile. Note that, if your copy of SIP was part of a standard Linux distribution, the ``custom`` directory may not be installed on your system. The ``custom`` directory contains the following files. They are provided as examples - each needs to be modified according to your particular requirements. - ``mkcustom.py`` is a Python script that will create a Makefile which is then used to build the custom interpreter. Comments in the file describe how it should be modified. - ``custom.c`` is a stub for a custom interpreter on Linux/UNIX. It should also be used for a custom console interpreter on Windows (i.e. like ``python.exe``). Comments in the file describe how it should be modified. - ``customw.c`` is a stub for a custom GUI interpreter on Windows (i.e. like ``pythonw.exe``). Comments in the file describe how it should be modified. Note that this technique does not restrict how the interpreter can be used. For example, it still allows users to write their own applications that can import your builtin modules. If you want to prevent users from doing that, perhaps to protect a proprietary API, then take a look at the `VendorID `__ package. sip-4.15.5/sphinx/c_api.rst0000644000076500000240000021761012254035112015600 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_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_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_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. v4.0.0 is represented as ``0x040000``). .. c:macro:: SIP_VERSION_STR This is a C preprocessor symbol that defines the SIP version number represented as a string. For development snapshots it will start with ``snapshot-``. .. 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: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) 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: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 an instance of the corresponding generated Python type. :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. :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:: 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: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 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 C/C++ enum. :param type: the C/C++ declaration of the enum. :return: the generated Python type object. This will not change and may be saved in a static cache. ``NULL`` is returned if the C/C++ enum doesn't exist. .. 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:: 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:: 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:: 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:: unsigned long sipLong_AsUnsignedLong(PyObject *obj) This function is a thin wrapper around :c:func:`PyLong_AsUnsignedLong()` that works around a bug in Python v2.3.x and earlier when converting integer objects. .. 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: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:: 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 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: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. .. 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`. .. 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: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(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 named enum. :param td: the type structure. :return: a non-zero value if the type structure refers to an 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:: 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: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. .. 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``). .. c:var:: PyTypeObject *sipWrapperType_Type This is the type of a :c:type:`sipWrapperType` structure and is the C implementation of :class:`sip.wrappertype`. .. _ref-type-structures: Generated Type Structures ------------------------- SIP generates an opaque type structure for each C structure, C++ class, C++ namespace, named enum or mapped type being wrapped. These are :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 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.15.5/sphinx/command_line.rst0000644000076500000240000001174312125131242017147 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 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:: -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:: -e Support for C++ exceptions is enabled. This causes all calls to C++ code to be enclosed in ``try``/``catch`` blocks and C++ exceptions to be converted to Python exceptions. By default exception support is disabled. .. cmdoption:: -g The Python GIL is released before making any calls to the C/C++ library being wrapped and reacquired afterwards. See :ref:`ref-gil` and the :fanno:`ReleaseGIL` and :fanno:`HoldGIL` annotations. .. cmdoption:: -I 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 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:: -z The name of a file containing more command line options. sip-4.15.5/sphinx/conf.py0000644000076500000240000001665312310606636015306 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 sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.append(os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. #extensions = [] # Add any paths that contain templates here, relative to this directory. templates_path = ['templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8' # The master toctree document. master_doc = 'index' # General information about the project. project = u'SIP' copyright = u'2014 Riverbank Computing Limited' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = '4.15.5' # The full version, including alpha/beta/rc tags. release = '4.15.5' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of documents that shouldn't be included in the build. #unused_docs = [] # List of directories, relative to source directory, that shouldn't be searched # for source files. #exclude_trees = [] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. Major themes that come with # Sphinx are currently 'default' and 'sphinxdoc'. html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". html_title = "SIP 4.15.5 Reference Guide" # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. html_logo = 'static/logo.png' # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. html_favicon = 'logo_tn.ico' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_use_modindex = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. html_show_sourcelink = False # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = '' # Output file base name for HTML help builder. htmlhelp_basename = 'SIPdoc' # -- Options for LaTeX output -------------------------------------------------- # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). #latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('index', 'SIP.tex', u'SIP Documentation', u'Riverbank Computing Limited', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # Additional stuff for the LaTeX preamble. #latex_preamble = '' # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_use_modindex = True def setup(app): """ Define roles specific to SIP. """ app.add_description_unit('argument-annotation', 'aanno', indextemplate='single: %s (argument annotation)') app.add_description_unit('class-annotation', 'canno', indextemplate='single: %s (class annotation)') app.add_description_unit('enum-annotation', 'eanno', indextemplate='single: %s (enum annotation)') app.add_description_unit('exception-annotation', 'xanno', indextemplate='single: %s (exception annotation)') app.add_description_unit('function-annotation', 'fanno', indextemplate='single: %s (function annotation)') app.add_description_unit('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.15.5/sphinx/directives.rst0000644000076500000240000023757112261240532016700 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 following variables are made available to the handwritten code: Py_buffer \*sipBuffer This is a pointer to the Python buffer structure that the handwritten code must populate. *type* \*sipCpp This is a pointer to the structure or class instance. Its *type* is a pointer to the structure or class. int sipFlags These are the flags that specify what elements of the ``sipBuffer`` structure must be populated. int sipRes The handwritten code should set this to 0 if there was no error or -1 if there was an error. PyObject \*sipSelf This is the Python object that wraps the structure or class instance, i.e. ``self``. .. directive:: %BIGetCharBufferCode .. parsed-literal:: %BIGetCharBufferCode *code* %End This directive (along with :directive:`%BIGetReadBufferCode`, :directive:`%BIGetSegCountCode` and :directive:`%BIGetWriteBufferCode`) is used to specify code that implements the buffer interface of Python v2. If Python v3 is being used then this is ignored. The following variables are made available to the handwritten code: *type* \*sipCpp This is a pointer to the structure or class instance. Its *type* is a pointer to the structure or class. void \*\*sipPtrPtr This is the pointer used to return the address of the character buffer. :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 following variables are made available to the handwritten code: Py_buffer \*sipBuffer This is a pointer to the Python buffer structure. *type* \*sipCpp This is a pointer to the structure or class instance. Its *type* is a pointer to the structure or class. PyObject \*sipSelf This is the Python object that wraps the structure or class instance, i.e. ``self``. .. directive:: %CModule .. 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 .. 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) 2014 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:: %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"]) *text* %End This directive is used to specify explicit docstrings for modules, classes, functions, methods 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. Specifying an explicit docstring will prevent SIP from generating an automatic docstring that describes the Python signature of a function or method overload. This means that SIP will generate less informative exceptions (i.e. without a full signature) when it fails to match a set of arguments to any function or method overload. .. versionadded:: 4.13 The format may either be ``"raw"`` or ``"deindented"``. If it is not specified then the value specified by any :directive:`%DefaultDocstringFormat` directive is used. If the format is ``"raw"`` then the docstring is used as it appears in the specification file. If the format is ``"deindented"`` then any leading spaces common to all non-blank lines of the docstring are removed. 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 }; .. 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:: %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 disable. 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 one 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:: %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]] [, 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. ``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. 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:: %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. By default all versions are disabled. The SIP :option:`-t ` command line option is used to enable a version. 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:: %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:: %VirtualCatcherCode .. parsed-literal:: %VirtualCatcherCode *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 Python reimplementation and the handling of any returned results. It is usually used to handle argument types and results that SIP cannot deal with automatically. This directive can also be used in the context of a class destructor to specify handwritten code that is embedded in-line in the internal derived class's destructor. In the context of a method the Python Global Interpreter Lock (GIL) is automatically acquired before the specified code is executed and automatically released afterwards. In the context of a destructor the specified code must handle the GIL. The GIL must be acquired before any calls to the Python API and released after the last call as shown in this example fragment:: SIP_BLOCK_THREADS Py_DECREF(obj); SIP_UNBLOCK_THREADS The following variables are made available to the handwritten code in the context of a method: *type* a0 There is a variable for each argument of the C++ signature named ``a0``, ``a1``, etc. 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 the result to be returned. The *type* of the variable is the same as the type defined in the C++ signature in the specification. int sipResKey This variable is only made available if the result has a type where it is important to ensure that the corresponding Python object is not garbage collected too soon. This only applies to ``'\0'`` terminated strings. The variable would normally be passed to :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.15.5/sphinx/distutils.rst0000644000076500000240000000270212163400134016542 0ustar philstaff00000000000000.. _ref-distutils: Building Your Extension with distutils ====================================== To build the example in :ref:`ref-simple-c++-example` using distutils, it is sufficient to create a standard ``setup.py``, listing ``word.sip`` among the files to build, and hook-up SIP into distutils:: from distutils.core import setup, Extension import sipdistutils setup( name = 'word', versione = '1.0', ext_modules=[ Extension("word", ["word.sip", "word.cpp"]), ], cmdclass = {'build_ext': sipdistutils.build_ext} ) As we can see, the above is a normal distutils setup script, with just a special line which is needed so that SIP can see and process ``word.sip``. Then, running ``setup.py build`` will build our extension module. If you want to use any of sip's command-line options described in :ref:`ref-command-line`, there is a new option available for the ``build_ext`` command in distutils: ``--sip-opts``. So you can either invoke distutils as follows:: $ python setup.py build_ext --sip-opts="-e -g" build or you can leverage distutils' config file support by creating a ``setup.cfg`` file in the supported system or local paths (eg: in the same directory of ``setup.py``) with these contents:: [build_ext] sip-opts = -e -g and then run ``setup.py build`` as usual. If ``sip-opts`` has not been specified then any ``swig_opts`` defined when creating the ``Extension`` will be used. sip-4.15.5/sphinx/embedding.rst0000644000076500000240000000520312125131242016432 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.15.5/sphinx/incompatibilities.rst0000644000076500000240000001451612227760566020257 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.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 :option:`-a` command line option to :file:`configure.py` has been removed. Removal of PyQt-specific Features ********************************* The following PyQt-specific support functions have been removed. - :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.15.5/sphinx/index.rst0000644000076500000240000000044411673627050015643 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 builtin sip-4.15.5/sphinx/installation.rst0000644000076500000240000001400212227760566017236 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 ``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:\python32\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:: -d , --destdir The 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 SIP module will be built as a static library. This is useful when building the SIP module as a Python builtin (see :ref:`ref-builtin`). .. cmdoption:: -n, --universal The SIP code generator and module will be built as universal binaries under MacOS/X. If the :option:`--arch ` option has not been specified then the universal binary will include the ``i386`` and ``ppc`` architectures. .. 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:: -u, --debug The 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 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 SIP module. The ``configure.py`` script takes many other options that allows the build system to be finely tuned. These are of the form ``name=value`` or ``name+=value``. The :option:`--show-build-macros ` option will display each supported ``name``, although not all are applicable to all platforms. The ``name=value`` form means that ``value`` will replace the existing value of ``name``. The ``name+=value`` form means that ``value`` will be appended to the existing value of ``name``. For example, the following will disable support for C++ exceptions (and so reduce the size of module binaries) when used with GCC:: python configure.py CXXFLAGS+=-fno-exceptions A pure Python module called ``sipconfig.py`` is generated by ``configure.py``. This defines each ``name`` and its corresponding ``value``. Looking at it will give you a good idea of how the build system uses the different options. It is covered in detail in :ref:`ref-build-system`. Configuring for MinGW ********************* SIP, and the modules it generates, can be built with MinGW, the Windows port of GCC. You must use the :option:`--platform ` command line option to specify the correct platform. For example:: c:\python32\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:\python32\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 python32.lib python32_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. sip-4.15.5/sphinx/introduction.rst0000644000076500000240000001565112310606636017257 0ustar philstaff00000000000000Introduction ============ This is the reference guide for SIP 4.15.5. 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 - the ability to include documentation in the specification files which can be extracted and subsequently processed by external tools - the ability to include copyright notices and licensing information in the specification files that is automatically included in all generated source code - a build system, written in Python, that you can extend to configure, compile and install your own bindings without worrying about platform specific issues - support for building your extensions using distutils - SIP, and the bindings it produces, runs under UNIX, Linux, Windows and MacOS/X SIP Components -------------- SIP comprises a number of different components. - The SIP code generator (:program:`sip`). This processes :file:`.sip` specification files and generates C or C++ bindings. It is covered in detail in :ref:`ref-using`. - The SIP header file (:file:`sip.h`). This contains definitions and data structures needed by the generated C and C++ code. - The SIP module (:file:`sip.so` or :file:`sip.pyd`). This is a Python extension module that is imported automatically by SIP generated bindings and provides them with some common utility functions. See also :ref:`ref-python-api`. - The SIP build system (:file:`sipconfig.py`). This is a pure Python module that is created when SIP is configured and encapsulates all the necessary information about your system including relevant directory names, compiler and linker flags, and version numbers. It also includes several Python classes and functions which help you write configuration scripts for your own bindings. It is covered in detail in :ref:`ref-build-system`. - The SIP distutils extension (:file:`sipdistutils.py`). This is a distutils extension that can be used to build your extension modules using distutils and is an alternative to writing configuration scripts with the SIP build system. This can be as simple as adding your .sip files to the list of files needed to build the extension module. It is covered in detail in :ref:`ref-distutils`. 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.15.5/sphinx/python_api.rst0000644000076500000240000002744112227760566016722 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. .. 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. :param type: the Python type object. :param enable: is ``True`` if auto-conversion should be enabled for the type. This is the default behaviour. :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:: 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 This is a Python integer object that represents the SIP version number as a 3 part hexadecimal number (e.g. v4.0.0 is represented as ``0x040000``). It was first implemented in SIP v4.2. .. data:: SIP_VERSION_STR This is a Python string object that defines the SIP version number as represented as a string. For development snapshots it will start with ``snapshot-``. It was first implemented in SIP v4.3. .. function:: transferback(obj) This function is a wrapper around :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:: 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.15.5/sphinx/specification_files.rst0000644000076500000240000004773412163400134020536 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:`%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:`%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**] [*exceptions*] [**= 0**] [*function-annotations*] [*c++-signature*] **;** [:directive:`%Docstring`] [:directive:`%MethodCode`] *c++-signature* ::= **[** *type* **(** [*argument-list*] **)]** *static-method* ::= **static** *function* *virtual-method* ::= [**Q_SIGNAL**] [**Q_SLOT**] **virtual** *type* *name* **(** [*argument-list*] **)** [**const**] [*exceptions*] [**= 0**] [*function-annotations*] [*c++-signature*] **;** [:directive:`%MethodCode`] [:directive:`%VirtualCatcherCode`] *special-method* ::= *type* *special-method-name* **(** [*argument-list*] **)** [*function-annotations*] **;** [:directive:`%MethodCode`] *special-method-name* ::= [**__abs__** | **__add__** | **__and__** | **__bool__** | **__call__** | **__cmp__** | **__contains__** | **__delattr__** | **__delitem__** | **__div__** | **__eq__** | **__float__** | **__floordiv__** | **__ge__** | **__getattr__** | **__getattribute__** | **__getitem__** | **__gt__** | **__hash__** | **__iadd__** | **__iand__** | **__idiv__** | **__ifloordiv__** | **__ilshift__** | **__imod__** | **__imul__** | **__index__** | **__int__** | **__invert__** | **__ior__** | **__irshift__** | **__isub__** | **__iter__** | **__itruediv__** | **__ixor__** | **__le__** | **__len__** | **__long__** | **__lshift__** | **__lt__** | **__mod__** | **__mul__** | **__ne__** | **__neg__** | **__next__** | **__nonzero__** | **__or__** | **__pos__** | **__repr__** | **__rshift__** | **__setattr__** | **__setitem__** | **__str__** | **__sub__** | **__truediv__** | **__xor__**] *operator* ::= *operator-type* **(** [*argument-list*] **)** [**const**] [*exceptions*] [*function-annotations*] **;** [:directive:`%MethodCode`] *virtual-operator* ::= **virtual** *operator-type* **(** [*argument-list*] **)** [**const**] [*exceptions*] [**= 0**] [*function-annotations*] **;** [:directive:`%MethodCode`] [:directive:`%VirtualCatcherCode`] *operatator-type* ::= [ *operator-function* | *operator-cast* ] *operator-function* ::= *type* **operator** *operator-name* *operator-cast* ::= **operator** *type* *operator-name* ::= [**+** | **-** | ***** | **/** | **%** | **&** | **|** | **^** | **<<** | **>>** | **+=** | **-=** | ***=** | **/=** | **%=** | **&=** | **|=** | **^=** | **<<=** | **>>=** | **~** | **()** | **[]** | **<** | **<=** | **==** | **!=** | **>** | **>>=** | **=**] *class-variable* ::= [**static**] *variable* *class-template* :: = **template** **<** *type-list* **>** *class* *mapped-type-template* :: = **template** **<** *type-list* **>** :directive:`%MappedType` *enum* ::= **enum** [*name*] [*enum-annotations*] **{** {*enum-line*} **};** *enum-line* ::= [:directive:`%If` | *name* [*enum-annotations*] **,** *function* ::= *type* *name* **(** [*argument-list*] **)** [*exceptions*] [*function-annotations*] **;** [:directive:`%Docstring`] [:directive:`%MethodCode`] *namespace* ::= **namespace** *name* [**{** {*namespace-line*} **}**] **;** *namespace-line* ::= [:directive:`%TypeHeaderCode` | *statement*] *opaque-class* ::= **class** *scoped-name* **;** *struct* ::= **struct** *name* **{** {*class-line*} **};** *typedef* ::= **typedef** [*typed-name* | *function-pointer*] *typedef-annotations* **;** *variable*::= *typed-name* [*variable-annotations*] **;** [:directive:`%AccessCode`] [:directive:`%GetCode`] [:directive:`%SetCode`] *exception* ::= :directive:`%Exception` *exception-name* [*exception-base*] **{** [:directive:`%TypeHeaderCode`] :directive:`%RaiseCode` **};** *exception-name* ::= *scoped-name* *exception-base* ::= **(** [*exception-name* | *python-exception*] **)** *python-exception* ::= [**SIP_Exception** | **SIP_StopIteration** | **SIP_StandardError** | **SIP_ArithmeticError** | **SIP_LookupError** | **SIP_AssertionError** | **SIP_AttributeError** | **SIP_EOFError** | **SIP_FloatingPointError** | **SIP_EnvironmentError** | **SIP_IOError** | **SIP_OSError** | **SIP_ImportError** | **SIP_IndexError** | **SIP_KeyError** | **SIP_KeyboardInterrupt** | **SIP_MemoryError** | **SIP_NameError** | **SIP_OverflowError** | **SIP_RuntimeError** | **SIP_NotImplementedError** | **SIP_SyntaxError** | **SIP_IndentationError** | **SIP_TabError** | **SIP_ReferenceError** | **SIP_SystemError** | **SIP_SystemExit** | **SIP_TypeError** | **SIP_UnboundLocalError** | **SIP_UnicodeError** | **SIP_UnicodeEncodeError** | **SIP_UnicodeDecodeError** | **SIP_UnicodeTranslateError** | **SIP_ValueError** | **SIP_ZeroDivisionError** | **SIP_WindowsError** | **SIP_VMSError**] *exceptions* ::= **throw (** [*exception-list*] **)** *exception-list* ::= *scoped-name* [**,** *exception-list*] *argument-list* ::= *argument* [**,** *argument-list*] [**,** **...**] *argument* ::= [ *type* [*name*] [*argument-annotations*] [*default-value*] | :stype:`SIP_ANYSLOT` [*default-value*] | :stype:`SIP_QOBJECT` | :stype:`SIP_RXOBJ_CON` | :stype:`SIP_RXOBJ_DIS` | :stype:`SIP_SIGNAL` [*default-value*] | :stype:`SIP_SLOT` [*default-value*] | :stype:`SIP_SLOT_CON` | :stype:`SIP_SLOT_DIS` | :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. - A class's list of super-classes doesn't not include any access specifier (e.g. ``public``). Variable Numbers of Arguments ----------------------------- SIP supports the use of ``...`` as the last part of a function signature. Any remaining arguments are collected as a Python tuple. Additional SIP Types -------------------- SIP supports a number of additional data types that can be used in Python signatures. .. sip-type:: SIP_ANYSLOT This is both a ``const char *`` and a ``PyObject *`` that is used as the type of the member instead of ``const char *`` in functions that implement the connection or disconnection of an explicitly generated signal to a slot. Handwritten code must be provided to interpret the conversion correctly. .. sip-type:: SIP_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 This is a ``QObject *`` that is a C++ instance of a class derived from Qt's ``QObject`` class. .. sip-type:: SIP_RXOBJ_CON This is a ``QObject *`` that is a C++ instance of a class derived from Qt's ``QObject`` class. It is used as the type of the receiver instead of ``const QObject *`` in functions that implement a connection to a slot. .. sip-type:: SIP_RXOBJ_DIS This is a ``QObject *`` that is a C++ instance of a class derived from Qt's ``QObject`` class. It is used as the type of the receiver instead of ``const QObject *`` in functions that implement a disconnection from a slot. .. sip-type:: SIP_SIGNAL This is a ``const char *`` that is used as the type of the signal instead of ``const char *`` in functions that implement the connection or disconnection of an explicitly generated signal to a slot. .. sip-type:: SIP_SLOT This is a ``const char *`` that is used as the type of the member instead of ``const char *`` in functions that implement the connection or disconnection of an explicitly generated signal to a slot. .. sip-type:: SIP_SLOT_CON This is a ``const char *`` that is used as the type of the member instead of ``const char *`` in functions that implement the connection of an internally generated signal to a slot. The type includes a comma separated list of types that is the C++ signature of of the signal. To take an example, ``QAccel::connectItem()`` connects an internally generated signal to a slot. The signal is emitted when the keyboard accelerator is activated and it has a single integer argument that is the ID of the accelerator. The C++ signature is:: bool connectItem(int id, const QObject *receiver, const char *member); The corresponding SIP specification is:: bool connectItem(int, SIP_RXOBJ_CON, SIP_SLOT_CON(int)); .. sip-type:: SIP_SLOT_DIS This is a ``const char *`` that is used as the type of the member instead of ``const char *`` in functions that implement the disconnection of an internally generated signal to a slot. The type includes a comma separated list of types that is the C++ signature of of the signal. .. 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.15.5/sphinx/static/0000755000076500000240000000000012125131242015251 5ustar philstaff00000000000000sip-4.15.5/sphinx/static/default.css0000644000076500000240000001015212125131242017406 0ustar philstaff00000000000000/* * The stylesheet (based on the Sphinx default). */ @import url("basic.css"); /* -- page layout ----------------------------------------------------------- */ body { font-family: 100% Verdana, Arial, Helvetica, sans-serif; font-size: 12px; background-color: white; color: black; margin: 0; padding: 0; } div.document { background-color: white; } div.documentwrapper { float: left; width: 100%; } div.bodywrapper { margin: 0 0 0 230px; } div.body { background-color: white; color: black; padding: 0 20px 30px 20px; } /* "footer" contains the copyright notice and the Sphinx link. */ div.footer { color: black; background-color: white; width: 100%; padding: 9px 0 9px 0; text-align: center; font-size: 75%; } div.footer a { color: black; text-decoration: underline; } /* "related" contains the title and the previous/next/modules/index links. */ div.related { background-color: white; line-height: 30px; color: black; } div.related a { color: #4186cb; } div.sphinxsidebar { } div.sphinxsidebar h3 { font-family: 'Trebuchet MS', sans-serif; color: black; font-size: 1.4em; font-weight: normal; margin: 0; padding: 0; } div.sphinxsidebar h3 a { color: black; } div.sphinxsidebar h4 { font-family: 'Trebuchet MS', sans-serif; color: black; font-size: 1.3em; font-weight: normal; margin: 5px 0 0 0; padding: 0; } div.sphinxsidebar p { color: black; } div.sphinxsidebar p.topless { margin: 5px 10px 10px 10px; } div.sphinxsidebar ul { margin: 10px; padding: 0; color: black; } div.sphinxsidebar a { color: #4186cb; } div.sphinxsidebar input { border: 1px solid #4186cb; font-family: sans-serif; font-size: 1em; } /* -- body styles ----------------------------------------------------------- */ a { color: #4186cb; text-decoration: none; } a:hover { text-decoration: underline; } div.body p, div.body dd, div.body li { text-align: justify; line-height: 130%; } div.body h1 { font-size: 180%; font-weight: bold; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 2px; color: white; background-color: #4186cb; padding: 5px; margin-top: 20px; -moz-border-radius: 5px; -webkit-border-radius: 5px; -khtml-border-radius: 5px; } div.body h2 { font-size: 140%; font-weight: normal; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 2px; color: white; background-color: #4186cb; padding: 5px; margin-top: 20px; -moz-border-radius: 5px; -webkit-border-radius: 5px; -khtml-border-radius: 5px; } h1 a, h2 a { color: white; text-decoration: none; } div.body h3 { font-size: 130%; font-weight: bold; color: black; } a.headerlink { color: white; font-size: 0.8em; padding: 0 4px 0 4px; text-decoration: none; } div.body p, div.body dd, div.body li { text-align: justify; line-height: 130%; } div.admonition p.admonition-title + p { display: inline; } div.admonition p { margin-bottom: 5px; } div.admonition pre { margin-bottom: 5px; } div.admonition ul, div.admonition ol { margin-bottom: 5px; } div.note { background-color: #eee; border: 1px solid #ccc; } div.seealso { background-color: #ffc; border: 1px solid #ff6; } div.topic { background-color: #eee; } div.warning { background-color: #ffe4e4; border: 1px solid #f66; } p.admonition-title { display: inline; } p.admonition-title:after { content: ":"; } pre { padding: 5px; /* * Note that this isn't our standard "sun" colour which doesn't contrast * too well with the pygments defaults. */ background-color: #fff4c0; color: black; line-height: 120%; border: 1px solid #ac9; border-left: none; border-right: none; } tt { background-color: #ecf0f3; padding: 0 1px 0 1px; font-size: 0.95em; } .warning tt { background: #efc2c2; } .note tt { background: #d6d6d6; } sip-4.15.5/sphinx/static/logo.png0000644000076500000240000000761312125131242016726 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.15.5/sphinx/static/logo_tn.ico0000644000076500000240000000217612125131242017414 0ustar philstaff00000000000000 h(  @ݱݱݱݱݱݱݱݱݱݱݱݱݱݱݱݱ|[|[|[|[|[|[|[|[|[|[|[|[|[|[|[|[Ʀťͱ˯PQ˯βݱstݱááܯܯݰTTݰݱIIݱݰeeݰ޲޲ε##δۭۭۭ~ۭ~ڪz|,,|ڪzsip-4.15.5/sphinx/using.rst0000644000076500000240000006424512125131242015654 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 PyQt. The build system will take care of finding the file's exact location. - The :directive:`%If` directive has been added to specify that everything [#]_ up to the matching :directive:`%End` directive only applies to Qt v4.2 and later. ``Qt_4_2_0`` is a *tag* defined in ``QtCoremod.sip`` [#]_ using the :directive:`%Timeline` directive. :directive:`%Timeline` is used to define a tag for each version of a library's API you are wrapping allowing you to maintain all the different versions in a single SIP specification. The build system provides support to ``configure.py`` scripts for working out the correct tags to use according to which version of the library is actually installed. - The :aanno:`TransferThis` annotation has been added to the constructor's argument. It specifies that if the argument is not 0 (i.e. the ``Hello`` instance being constructed has a parent) then ownership of the instance is transferred from Python to C++. It is needed because Qt maintains objects (i.e. instances derived from the ``QObject`` class) in a hierachy. When an object is destroyed all of its children are also automatically destroyed. It is important, therefore, that the Python garbage collector doesn't also try and destroy them. This is covered in more detail in :ref:`ref-object-ownership`. SIP provides many other annotations that can be applied to arguments, functions and classes. Multiple annotations are separated by commas. Annotations may have values. - The ``=`` operator has been removed. This operator is not supported by SIP. - The :directive:`%If` directive has been added to specify that everything up to the matching :directive:`%End` directive does not apply to Windows. ``WS_WIN`` is another tag defined by PyQt, this time using the :directive:`%Platforms` directive. Tags defined by the :directive:`%Platforms` directive are mutually exclusive, i.e. only one may be valid at a time [#]_. One question you might have at this point is why bother to define the private copy constructor when it can never be called from Python? The answer is to prevent the automatic generation of a public copy constructor. We now look at the ``configure.py`` script. This is a little different to the script in the previous examples for two related reasons. Firstly, PyQt includes a pure Python module called ``pyqtconfig`` that extends the SIP build system for modules, like our example, that build on top of PyQt. It deals with the details of which version of Qt is being used (i.e. it determines what the correct tags are) and where it is installed. This is called a module's configuration module. Secondly, we generate a configuration module (called ``helloconfig``) for our own ``hello`` module. There is no need to do this, but if there is a chance that somebody else might want to extend your C++ library then it would make life easier for them. Now we have two scripts. First the ``configure.py`` script:: import os import sipconfig from PyQt4 import pyqtconfig # The name of the SIP build file generated by SIP and used by the build # system. build_file = "hello.sbf" # Get the PyQt configuration information. config = pyqtconfig.Configuration() # Get the extra SIP flags needed by the imported PyQt modules. Note that # this normally only includes those flags (-x and -t) that relate to SIP's # versioning system. pyqt_sip_flags = config.pyqt_sip_flags # Run SIP to generate the code. Note that we tell SIP where to find the qt # module's specification files using the -I flag. os.system(" ".join([config.sip_bin, "-c", ".", "-b", build_file, "-I", config.pyqt_sip_dir, pyqt_sip_flags, "hello.sip"])) # We are going to install the SIP specification file for this module and # its configuration module. installs = [] installs.append(["hello.sip", os.path.join(config.default_sip_dir, "hello")]) installs.append(["helloconfig.py", config.default_mod_dir]) # Create the Makefile. The QtGuiModuleMakefile class provided by the # pyqtconfig module takes care of all the extra preprocessor, compiler and # linker flags needed by the Qt library. makefile = pyqtconfig.QtGuiModuleMakefile( configuration=config, build_file=build_file, installs=installs ) # Add the library we are wrapping. The name doesn't include any platform # specific prefixes or extensions (e.g. the "lib" prefix on UNIX, or the # ".dll" extension on Windows). makefile.extra_libs = ["hello"] # Generate the Makefile itself. makefile.generate() # Now we create the configuration module. This is done by merging a Python # dictionary (whose values are normally determined dynamically) with a # (static) template. content = { # Publish where the SIP specifications for this module will be # installed. "hello_sip_dir": config.default_sip_dir, # Publish the set of SIP flags needed by this module. As these are the # same flags needed by the qt module we could leave it out, but this # allows us to change the flags at a later date without breaking # scripts that import the configuration module. "hello_sip_flags": pyqt_sip_flags } # This creates the helloconfig.py module from the helloconfig.py.in # template and the dictionary. sipconfig.create_config_module("helloconfig.py", "helloconfig.py.in", content) Next we have the ``helloconfig.py.in`` template script:: from PyQt4 import pyqtconfig # These are installation specific values created when Hello was configured. # The following line will be replaced when this template is used to create # the final configuration module. # @SIP_CONFIGURATION@ class Configuration(pyqtconfig.Configuration): """The class that represents Hello configuration values. """ def __init__(self, sub_cfg=None): """Initialise an instance of the class. sub_cfg is the list of sub-class configurations. It should be None when called normally. """ # This is all standard code to be copied verbatim except for the # name of the module containing the super-class. if sub_cfg: cfg = sub_cfg else: cfg = [] cfg.append(_pkg_config) pyqtconfig.Configuration.__init__(self, cfg) class HelloModuleMakefile(pyqtconfig.QtGuiModuleMakefile): """The Makefile class for modules that %Import hello. """ def finalise(self): """Finalise the macros. """ # Make sure our C++ library is linked. self.extra_libs.append("hello") # Let the super-class do what it needs to. pyqtconfig.QtGuiModuleMakefile.finalise(self) Again, we hope that the scripts are self documenting. .. [#] Some parts of a SIP specification aren't subject to version control. .. [#] Actually in ``versions.sip``. PyQt uses the :directive:`%Include` directive to split the SIP specification for Qt across a large number of separate ``.sip`` files. .. [#] Tags can also be defined by the :directive:`%Feature` directive. These tags are not mutually exclusive, i.e. any number may be valid at a time. .. _ref-object-ownership: Ownership of Objects -------------------- When a C++ instance is wrapped a corresponding Python object is created. The Python object behaves as you would expect in regard to garbage collection - it is garbage collected when its reference count reaches zero. What then happens to the corresponding C++ instance? The obvious answer might be that the instance's destructor is called. However the library API may say that when the instance is passed to a particular function, the library takes ownership of the instance, i.e. responsibility for calling the instance's destructor is transferred from the SIP generated module to the library. Ownership of an instance may also be associated with another instance. The implication being that the owned instance will automatically be destroyed if the owning instance is destroyed. SIP keeps track of these relationships to ensure that Python's cyclic garbage collector can detect and break any reference cycles between the owning and owned instances. The association is implemented as the owning instance taking a reference to the owned instance. The TransferThis, Transfer and TransferBack annotations are used to specify where, and it what direction, transfers of ownership happen. It is very important that these are specified correctly to avoid crashes (where both Python and C++ call the destructor) and memory leaks (where neither Python and C++ call the destructor). This applies equally to C structures where the structure is returned to the heap using the ``free()`` function. See also :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. .. _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. 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 than function or method returns. - When a wide string or array is returned from a virtual method then SIP does not free the memory until the next time the method is called. - When an assignment is made to a wide string or array instance variable then SIP does not first free the instance's current string or array. .. _ref-gil: The Python Global Interpreter Lock ---------------------------------- Python's Global Interpretor Lock (GIL) must be acquired before calls can be made to the Python API. It should also be released when a potentially blocking call to C/C++ library is made in order to allow other Python threads to be executed. In addition, some C/C++ libraries may implement their own locking strategies that conflict with the GIL causing application deadlocks. SIP provides ways of specifying when the GIL is released and acquired to ensure that locking problems can be avoided. SIP always ensures that the GIL is acquired before making calls to the Python API. By default SIP does not release the GIL when making calls to the C/C++ library being wrapped. The :fanno:`ReleaseGIL` annotation can be used to override this behaviour when required. If SIP is given the :option:`-g ` 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 PyQt3 and PyQt4 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.