summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSlávek Banko <slavek.banko@axis.cz>2021-03-26 13:52:33 +0100
committerSlávek Banko <slavek.banko@axis.cz>2021-03-26 13:52:33 +0100
commit0f27805eedcc40ae34009aa31a4dc08cb949f867 (patch)
tree8b1c8995d7fdab97acde4bd7c63f96d378c34d02
parentbad411472a12b93f8bfca6b7ca52d89488a8d8ce (diff)
downloadextra-dependencies-0f27805eedcc40ae34009aa31a4dc08cb949f867.tar.gz
extra-dependencies-0f27805eedcc40ae34009aa31a4dc08cb949f867.zip
DEB pyrex: Added to repository.
Signed-off-by: Slávek Banko <slavek.banko@axis.cz>
-rw-r--r--debian/pyrex/pyrex-0.9.9/.hgtags8
-rw-r--r--debian/pyrex/pyrex-0.9.9/CHANGES.txt1871
-rw-r--r--debian/pyrex/pyrex-0.9.9/CHECKLIST.txt24
-rw-r--r--debian/pyrex/pyrex-0.9.9/Demos/Makefile15
-rw-r--r--debian/pyrex/pyrex-0.9.9/Demos/Makefile.nodistutils21
-rw-r--r--debian/pyrex/pyrex-0.9.9/Demos/Setup.py14
-rw-r--r--debian/pyrex/pyrex-0.9.9/Demos/callback/Makefile10
-rw-r--r--debian/pyrex/pyrex-0.9.9/Demos/callback/Makefile.nodistutils19
-rw-r--r--debian/pyrex/pyrex-0.9.9/Demos/callback/README.txt1
-rw-r--r--debian/pyrex/pyrex-0.9.9/Demos/callback/Setup.py11
-rw-r--r--debian/pyrex/pyrex-0.9.9/Demos/callback/cheese.pyx13
-rw-r--r--debian/pyrex/pyrex-0.9.9/Demos/callback/cheesefinder.c21
-rw-r--r--debian/pyrex/pyrex-0.9.9/Demos/callback/cheesefinder.h1
-rw-r--r--debian/pyrex/pyrex-0.9.9/Demos/callback/run_cheese.py7
l---------debian/pyrex/pyrex-0.9.9/Demos/embed/Makefile1
-rw-r--r--debian/pyrex/pyrex-0.9.9/Demos/embed/Makefile.msc35
-rw-r--r--debian/pyrex/pyrex-0.9.9/Demos/embed/Makefile.msc.static1
-rw-r--r--debian/pyrex/pyrex-0.9.9/Demos/embed/Makefile.unix30
-rw-r--r--debian/pyrex/pyrex-0.9.9/Demos/embed/README1
-rw-r--r--debian/pyrex/pyrex-0.9.9/Demos/embed/embedded.pyx5
-rw-r--r--debian/pyrex/pyrex-0.9.9/Demos/embed/main.c9
-rw-r--r--debian/pyrex/pyrex-0.9.9/Demos/numeric_demo.pyx39
-rw-r--r--debian/pyrex/pyrex-0.9.9/Demos/primes.pyx18
-rw-r--r--debian/pyrex/pyrex-0.9.9/Demos/pyprimes.py13
-rw-r--r--debian/pyrex/pyrex-0.9.9/Demos/run_numeric_demo.py5
-rw-r--r--debian/pyrex/pyrex-0.9.9/Demos/run_primes.py7
-rw-r--r--debian/pyrex/pyrex-0.9.9/Demos/run_spam.py8
-rw-r--r--debian/pyrex/pyrex-0.9.9/Demos/spam.pyx22
-rw-r--r--debian/pyrex/pyrex-0.9.9/Doc/About.html149
-rw-r--r--debian/pyrex/pyrex-0.9.9/Doc/FAQ.html75
-rw-r--r--debian/pyrex/pyrex-0.9.9/Doc/LanguageOverview.html17
-rw-r--r--debian/pyrex/pyrex-0.9.9/Doc/Manual/Limitations.html53
-rw-r--r--debian/pyrex/pyrex-0.9.9/Doc/Manual/basics.html1118
-rw-r--r--debian/pyrex/pyrex-0.9.9/Doc/Manual/extension_types.html1079
-rw-r--r--debian/pyrex/pyrex-0.9.9/Doc/Manual/external.html294
-rw-r--r--debian/pyrex/pyrex-0.9.9/Doc/Manual/sharing.html342
-rw-r--r--debian/pyrex/pyrex-0.9.9/Doc/Manual/source_files.html78
-rw-r--r--debian/pyrex/pyrex-0.9.9/Doc/Manual/special_methods.html1124
-rw-r--r--debian/pyrex/pyrex-0.9.9/Doc/Manual/using_with_c++.html7
-rw-r--r--debian/pyrex/pyrex-0.9.9/Doc/Release_Notes_0.9.9.html43
-rw-r--r--debian/pyrex/pyrex-0.9.9/Doc/index.html70
-rw-r--r--debian/pyrex/pyrex-0.9.9/Doc/primes.c1
-rw-r--r--debian/pyrex/pyrex-0.9.9/INSTALL.txt33
-rw-r--r--debian/pyrex/pyrex-0.9.9/LICENSE.txt173
-rw-r--r--debian/pyrex/pyrex-0.9.9/MANIFEST.in7
-rw-r--r--debian/pyrex/pyrex-0.9.9/Makefile15
-rw-r--r--debian/pyrex/pyrex-0.9.9/Obsolete/PyrexTypes.py.old829
-rw-r--r--debian/pyrex/pyrex-0.9.9/Obsolete/overview.html1485
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Builtin.py276
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/CmdLine.py94
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Code.py546
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/DebugFlags.py4
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Errors.py77
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/ExprNodes.py3954
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Filenames.py9
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Lexicon.picklebin0 -> 19254 bytes
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Lexicon.py145
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Main.py564
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/ModuleNode.py1678
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Naming.py69
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Nodes.py3249
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Options.py5
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Parsing.py2142
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/PyrexTypes.py974
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Scanning.py390
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Symtab.py1342
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/TypeSlots.py629
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Version.py1
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/__init__.py0
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Debugging.py20
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Distutils/__init__.py11
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Distutils/build_ext.py194
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Distutils/extension.py79
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/DistutilsOld/__init__.py22
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/DistutilsOld/build_ext.py63
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Mac/DarwinSystem.py85
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Mac/MacSystem.py135
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Mac/MacUtils.py34
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Mac/Makefile24
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Mac/TS_Misc_Suite.py64
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Mac/_Filemodule_patched.c3345
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Mac/__init__.py0
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Mac/macglue.h135
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Mac/setup.py12
-rwxr-xr-xdebian/pyrex/pyrex-0.9.9/Pyrex/Plex/Actions.py109
-rwxr-xr-xdebian/pyrex/pyrex-0.9.9/Pyrex/Plex/DFA.py156
-rwxr-xr-xdebian/pyrex/pyrex-0.9.9/Pyrex/Plex/Errors.py52
-rwxr-xr-xdebian/pyrex/pyrex-0.9.9/Pyrex/Plex/Lexicons.py192
-rwxr-xr-xdebian/pyrex/pyrex-0.9.9/Pyrex/Plex/Machines.py326
-rwxr-xr-xdebian/pyrex/pyrex-0.9.9/Pyrex/Plex/Regexps.py557
-rwxr-xr-xdebian/pyrex/pyrex-0.9.9/Pyrex/Plex/Scanners.py377
-rwxr-xr-xdebian/pyrex/pyrex-0.9.9/Pyrex/Plex/Timing.py22
-rwxr-xr-xdebian/pyrex/pyrex-0.9.9/Pyrex/Plex/Traditional.py154
-rwxr-xr-xdebian/pyrex/pyrex-0.9.9/Pyrex/Plex/Transitions.py253
-rwxr-xr-xdebian/pyrex/pyrex-0.9.9/Pyrex/Plex/__init__.py40
-rwxr-xr-xdebian/pyrex/pyrex-0.9.9/Pyrex/Plex/test_tm.py24
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Unix/LinuxSystem.py74
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Unix/__init__.py0
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/Utils.py55
-rw-r--r--debian/pyrex/pyrex-0.9.9/Pyrex/__init__.py0
-rw-r--r--debian/pyrex/pyrex-0.9.9/README.txt37
-rw-r--r--debian/pyrex/pyrex-0.9.9/ToDo.txt164
-rw-r--r--debian/pyrex/pyrex-0.9.9/Tools/pyrex-mode.el1
-rw-r--r--debian/pyrex/pyrex-0.9.9/Tools/pyrex.st1
-rw-r--r--debian/pyrex/pyrex-0.9.9/USAGE.txt69
-rwxr-xr-xdebian/pyrex/pyrex-0.9.9/bin/pyrexc8
-rwxr-xr-xdebian/pyrex/pyrex-0.9.9/bin/pyrexc2.58
-rwxr-xr-xdebian/pyrex/pyrex-0.9.9/bin/pyrexc2.68
-rwxr-xr-xdebian/pyrex/pyrex-0.9.9/bin/pyxcc15
-rwxr-xr-xdebian/pyrex/pyrex-0.9.9/bin/run_tests_2.57
-rwxr-xr-xdebian/pyrex/pyrex-0.9.9/bin/run_tests_2.67
-rwxr-xr-xdebian/pyrex/pyrex-0.9.9/bin/update_references49
-rw-r--r--debian/pyrex/pyrex-0.9.9/debian/changelog333
-rw-r--r--debian/pyrex/pyrex-0.9.9/debian/compat1
-rw-r--r--debian/pyrex/pyrex-0.9.9/debian/control35
-rw-r--r--debian/pyrex/pyrex-0.9.9/debian/copyright44
-rw-r--r--debian/pyrex/pyrex-0.9.9/debian/patches/baseexception.patch24
-rw-r--r--debian/pyrex/pyrex-0.9.9/debian/patches/series1
-rw-r--r--debian/pyrex/pyrex-0.9.9/debian/pyrex-mode.el15
-rw-r--r--debian/pyrex/pyrex-0.9.9/debian/pyrex-mode.emacsen-startup23
-rw-r--r--debian/pyrex/pyrex-0.9.9/debian/pyrex-mode.install1
-rw-r--r--debian/pyrex/pyrex-0.9.9/debian/pyrexc.143
-rw-r--r--debian/pyrex/pyrex-0.9.9/debian/python-pyrex.doc-base10
-rw-r--r--debian/pyrex/pyrex-0.9.9/debian/python-pyrex.docs5
-rw-r--r--debian/pyrex/pyrex-0.9.9/debian/pythonX.Y-pyrexc7
-rwxr-xr-xdebian/pyrex/pyrex-0.9.9/debian/rules93
-rw-r--r--debian/pyrex/pyrex-0.9.9/debian/source/format1
-rw-r--r--debian/pyrex/pyrex-0.9.9/debian/source/options3
-rw-r--r--debian/pyrex/pyrex-0.9.9/debian/watch2
-rw-r--r--debian/pyrex/pyrex-0.9.9/hgignore10
-rwxr-xr-xdebian/pyrex/pyrex-0.9.9/pyrexc.py6
-rw-r--r--debian/pyrex/pyrex-0.9.9/setup.py48
-rw-r--r--debian/pyrex/pyrex_0.9.9.orig.tar.gzbin0 -> 255272 bytes
133 files changed, 33063 insertions, 0 deletions
diff --git a/debian/pyrex/pyrex-0.9.9/.hgtags b/debian/pyrex/pyrex-0.9.9/.hgtags
new file mode 100644
index 00000000..f273732d
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/.hgtags
@@ -0,0 +1,8 @@
+588a14055d1691eb3d0a14d69be108c6110fcee7 0.9.8
+66ff407aae9ec4fba986bfdbc6686f1eb7016dce 0.9.8.2
+37554acbb702072bdefef51980be33c551e38895 0.9.8.3
+ac76d2c45aa1f7055b6101064eac30cfb648a350 0.9.8.4
+ac4da2723c96ef0ffc792d9a763638a62e103426 0.9.8.5
+f89737e75fc5ef7c007abb97dd0f2694c7ae071b 0.9.8.6
+67efcff42bd53148cfdbb0767c64e1c7a852f82f 0.9.9
+f11df44eb1bfa2f7ed609c7affc89461e8aa91f5 0.9.9
diff --git a/debian/pyrex/pyrex-0.9.9/CHANGES.txt b/debian/pyrex/pyrex-0.9.9/CHANGES.txt
new file mode 100644
index 00000000..be330a81
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/CHANGES.txt
@@ -0,0 +1,1871 @@
+0.9.9
+-----
+
+New features:
+
+ - C++ struct declarations, 'new' operator, and del for C++ delete.
+
+ - As well as the 'not None' modifier for extension type arguments, there
+ is now 'or None' to explicitly allow passing None. It is planned to make
+ 'not None' the default in a future version. For now, a warning is issued
+ (once per Pyrex run) if you do not specify one or the other.
+
+ - Extension types may have a 'nogc' option to suppress GC support.
+
+Modifications:
+
+ - Exceptions caught by an except clause are no longer put into the thread
+ state and cannot be retrieved using sys.exc_info(). To access the caught
+ exception, it must be bound to a name in the except clause. A third name
+ can be supplied to capture the traceback.
+
+ - PyString_InternFromString is now exposed under the name 'cintern' because
+ it is not a complete substitute for 'intern' (it can't handle strings
+ containing null bytes). [John Arbash Meinel]
+
+ - Disabled size check for cimported types because it was generating too
+ many false positives in the field.
+
+ - Added __fastcall calling convention. Also no longer assuming that an
+ unspecified calling convention is the same as __cdecl.
+
+ - Operations between signed and unsigned ints of the same size now have
+ an unsigned result.
+
+ - Py_ssize_t now ranked between long and long long.
+
+ - Declaration of __new__ in an extension type is now an error, in
+ preparation for introducing new semantics.
+
+ - Added size_t type, and made sizeof() return it.
+
+Bug fixes:
+
+ - When casting the result of a function call to a Python type, the
+ function could be called twice. [David Martinez]
+
+ - __Pyx_GetException was not taking account of the fact that the traceback
+ could be NULL.
+
+ - sizeof(module.typename) did not work. [Daniele Pianu]
+
+
+0.9.8.6
+-------
+
+Enhancements:
+
+ - Check for gil when calling a function declared 'execpt *' or 'except ?'.
+ Acquire gil when reporting unraisable exception.
+
+ - Added iter2() function for 2-argument form of iter().
+
+Bug fixes:
+
+ - Compiler crashed if base class of extension type was incompletely
+ defined.
+
+ - Compiler crash on misspelled method name in property declaration.
+ [Stefan Behnel]
+
+ - Fixed deprecation warnings in 2.6
+
+ - Always preserve explicit type casts for non-Python types.
+ [Alexander Belchenko]
+
+ - Added workaround for threading initialisation bug in Python 2.3.
+ [Lisandro Dalcin]
+
+ - Deleting dict item with integer key did not work. [Titus Brown]
+
+ - Header files for cimported modules included in wrong order.
+ [Stephane Drouard]
+
+ - Don't allow a member of a ctypedef struct to reference itself.
+ [Tim Wakeham]
+
+ - Compiler crash due to attribute reference in compile-time expression.
+ [Hoyt Koepke]
+
+ - Public extension type attribute with cname didn't work.
+ [Mark Ellis]
+
+ - Memory leak related to exporting C functions. [Lisandro Dalcin]
+
+ - Compiler crash on return outside function. [Kurt Smith]
+
+ - Scope problem with extension types declared in pxd. [KS Sreeram]
+
+ - Calling a builtin method of a subclass of a builtin class did not work.
+
+ - Builtin hash() function had wrong return type. [John Arbash Meinel]
+
+
+Modifications:
+
+ - Added 'tags' to .hgignore file. [Kirill Smelkov]
+
+ - Disallow overriding a builtin method in a subclass of a builtin class.
+
+
+0.9.8.5
+-------
+
+Bug fixes:
+
+ - Function export code was erroneously generated for 'extern' functions
+ declared in a .pxd file. [Sebastian Sable]
+
+ - The 'api' option was not recognised with 'ctypedef public class'.
+ [Lisandro Dalcin]
+
+ - MACOSX_DEPLOYMENT_TARGET is no longer set unless the undocumented -X
+ option is being used. Hopefully this will prevent complaints about it
+ from distutils. [Martin Field]
+
+ - Recognize MS_WINDOWS as well as WIN32. [Alexander Belchenko]
+
+ - Hexadecimal compile-time constants did not work. [Devan]
+
+Enhancements:
+
+ - Dependency files (.dep) are only created when compiling with timestamp
+ checking or recursion enabled.
+
+Deprecations:
+
+ - The features introducted in 0.9.8 and 0.9.8.1 for cross-forward-declaring
+ extension types between .pxd files turn out to be unnecessary, since
+ the circular import problems they are aimed at can be avoided using
+ ordinary forward delcarations in the .pxd files ahead of any cimports.
+
+
+0.9.8.4
+-------
+
+Bug fixes:
+
+ - Incorrect code generated for Python indexing with an unsigned int.
+ [Christopher Williams]
+
+
+0.9.8.3
+-------
+
+Bug fixes:
+
+ - Compiling multiple source files at once should work as advertised
+ now.
+
+ - Assignment of a nogil function to a non-nogil function pointer
+ is now allowed.
+
+ - Applying += or -= to a pointer and an integer did not work.
+ [Arc Riley]
+
+ - Compiling a .pyx file whose name is not a valid module name now
+ reports an error instead of generating invalid C code.
+ [Robert Bradshaw]
+
+ - Integer indexing optimisation now performed only for signed
+ index types, to avoid change of semantics with index values
+ greater than the maximum positive signed int value. [Robert
+ Bradshaw]
+
+ - Non-void function declared 'except *' could produce C compiler
+ warning about uninitialised variable. [Lisandro Dalcin]
+
+
+0.9.8.2
+-------
+
+Enhancements:
+
+ - A block of external functions can be declared nogil at once.
+
+ cdef extern from "somewhere.h" nogil:
+ ...
+
+Bug fixes:
+
+ - The nogil attribute was not being checked for a match when
+ comparing function signatures.
+
+ - Improved error message for C method signature mismatch between
+ a class and its base class.
+
+Bug workarounds:
+
+ - Multiple source files passed to Main.compile are being compiled
+ in separate contexts for the time being until I can sort out a
+ problem. You probably won't notice any difference except that
+ there will be no speed advantage over compiling them separately.
+
+
+0.9.8.1
+-------
+
+Enhancements:
+
+ - It is no longer necessary to specify the base class of an
+ extension type in a forward declaration. Also, if the class is
+ defined in a .pxd file, the base class only needs to be specified
+ in the .pxd file, not the .pyx file.
+ [Arc Riley]
+
+ - There's now an even easier way to forward-declare a struct, union
+ or extension type in another module:
+
+ from blarg cimport class Foo
+
+ This simultaneously cimports the name Foo and forward-declares
+ it as an extension type. As well as 'class', you can also use
+ 'struct' or 'union'.
+
+Modifications:
+
+ - Casting a non-Python pointer type to a Python type no longer
+ generates an incref, unless one is required for other reasons.
+ [Arc Riley]
+
+ - More checks added for gil-requiring operations performed without
+ holding the gil.
+
+
+0.9.8
+-----
+
+New features:
+
+ * Augmented assignment operators (+=, etc.) are now supported.
+
+ * Package directories
+
+ Modules in packages no longer need to have dotted names. Instead,
+ a Python-like package directory structure can be used, with
+ package dirs marked by containing an __init__.py or __init__.pyx.
+
+ Top-level package directories are found by searching the include
+ directories specified by -I options (analogous to PYTHONPATH).
+
+ * Dependency tracking
+
+ The Pyrex compiler records information about other source files cimported
+ or included, and can automatically compile all the modules a given module
+ depends on, with timestamp checking.
+
+ This is enabled by a -r (recursive) option to the compiler, e.g.
+
+ pyrexc -r mainmodule.pyx
+
+ There are also two other new command-line options:
+
+ -t Enable timestamp checking. This is implied with -r.
+
+ -f Overrides implied -t when using -r and forces all
+ dependent modules to be compiled regardless of timestamps.
+
+ * Nogil restrictions relaxed
+
+ C functions declared nogil can now have Python objects as arguments.
+ The argument names are read-only inside the function when this is done.
+
+ Among other things, this allows C methods to be declared nogil (this
+ couldn't be done before because 'self' is always an object argument).
+
+ * Circular cimports
+
+ There is now a way of forward-declaring a struct, union or extension type
+ into another module. This allows two .pxd files to define extension types
+ that refer to each other without running into circular import problems.
+ For example:
+
+ cimport blarg
+ cdef class blarg.Blarg # Forward declaration
+
+ cdef class Foo:
+ cdef blarg.Blarg blg
+
+
+0.9.7.2
+-------
+
+ Bug fixes:
+
+ - Another integer indexing problem fixed.
+
+
+0.9.7.1
+-------
+
+ Bug fixes:
+
+ - The optimisation for indexing using a C int failed when the
+ object being indexed was a mapping rather than a sequence.
+ [Arc Riley]
+
+ Modifications:
+
+ - Old integer for-loop syntax is no longer deprecated.
+
+
+0.9.7
+-----
+
+New features:
+
+ - Builtin constants and types are known, and are referenced directly
+ with no dictionary lookup.
+
+ - Direct calls are made to certain methods of lists and dicts when
+ their type is statically known.
+
+ - New builtin functions 'typecheck' and 'issubtype' added, providing
+ safer type checking than isinstance and issubclass (which can be
+ overridden).
+
+Enhancements:
+
+ - Redundant type test eliminated when assigning the result of an
+ extension type constructor call to a variable of the same type.
+
+ - No tp_traverse and tp_clear functions generated for types
+ without Python attributes.
+
+ - Safer code generated in tp_clear. [Stefan Behnel]
+
+ - Indexing with a C int type generates calls to PySequence_GetItem
+ and PySequence_SetItem.
+
+ - Integer for-loop syntax streamlined to 'for x < i < y'.
+
+ - Appropriate C code generated for compile-time expressions
+ evaluating to float nan, inf and -inf. [Stefan Behnel]
+
+Bug fixes:
+
+ - Value raised by assert statement now only evaluated if the
+ assertion fails. [Stefan Behnel]
+
+ - Comparing a value of an enum type with another value of a type
+ which is ctypedefed to the same enum type gave a spurious type
+ error. [Matt Hammond]
+
+ - Comparing an int with a float resulted in the float being cast
+ to an int before comparison. [Robin Becker]
+
+ - Compiler crashed on an invalid argument to a 'with nogil' statement.
+ [Stefan Behnel]
+
+ - Incorrect code generated for function with keyword only args
+ and no * or ** args. [Stefan Behnel]
+
+ - GC type with non-GC base type caused crash due to trying to call
+ non-existent base tp_traverse and tp_clear functions. [Stefan Behnel]
+
+ - Compile-time IF with no ELSE clause crashed compiler. [Kirk McDonald]
+
+ - Values in enum declaration were not being checked for appropriate type.
+ [Simon Burton]
+
+ - Improved the error message from attempting to declare a struct or
+ union member as a function. [Yong Sun]
+
+ - Referring to an undefined name in a compile-time constant crashed
+ the compiler. [Stefan Behnel]
+
+
+0.9.6.4
+-------
+
+Bug fixes:
+
+ - Errors in setup.py corrected.
+
+ - Incorrect error checking code generated for builtin functions
+ and type slots with return type Py_ssize_t. [Robert Bradshaw]
+
+ - A counted reference was not kept to the module, so if the entry
+ in sys.modules was replaced, the module was freed prematurely.
+ [Franck Pommerau]
+
+ - A cimport statement inside a function crashed the compiler.
+ [Robert Bradshaw]
+
+ - __Pyx_ImportModule routine wasn't protected from multiple
+ definition when including _api.h files. [Stefan Behnel]
+
+ - Temp variables holding exception values were not being set to
+ NULL after use in an except clause. [Robert Bradshaw]
+
+ - Protect __stdcall and __cdecl from redefinition. [Jim Kleckner]
+
+ - A temp var was not being set to NULL after api function import
+ code. [Stefan Behnel]
+
+ - __Pyx_ImportFunction was incorrectly decrefing a borrowed
+ reference. [Stefan Behnel]
+
+Enhancements:
+
+ - Functions declared with_gil and external functions declared nogil
+ are now allowed to have Python arguments and return types.
+
+
+0.9.6.3
+-------
+
+Enhancements:
+
+ - C API now only uses a single name in the module namespace
+ instead of one for each exported C function. [Stefan Behnel]
+
+ - Multiple declarations with the same visibility and api options
+ can now be grouped into a 'cdef' block.
+
+ - The 'api' keyword can now be used on extension types to cause
+ generation of an api.h file when there are no exported C functions.
+
+ - Added a getattr3() builtin for the three-argument form of getattr.
+
+Bug fixes:
+
+ - Setup.py no longer uses an import to get the version number
+ being installed, to avoid a problem with setuptools.
+
+ - If a struct or union was forward-declared, certain types of error
+ message misleadingly referenced the source location of the forward
+ declaration rather than the definition.
+
+ - Calling convention specifier was being emitted in function
+ prototypes but not the corresponding definitions. [Atsuo Ishimoto]
+
+ - Added support for the --force option to Pyrex.Distutils.
+ [Alexander Belchenko]
+
+ - Compile-time "==" operator did not work. [Simon King]
+
+ - Header files generated for public and api declarations now
+ only contain types declared as 'public', instead of all types
+ defined in the module. [Stefan Behnel]
+
+
+0.9.6.2
+-------
+
+Bug fixes:
+
+ - Corrected a problem with declaration ordering in generated C
+ code involving forward-declared struct, union or extension types.
+
+ - New distutils extension: Only compile .pyx if it is newer
+ than the corresponding .c file.
+
+
+0.9.6.1
+-------
+
+Bug fixes:
+
+ - Changed os.uname to platform.uname for portability.
+ [Alexander Belchenko]
+
+ - Fixed C compiler warning about incompatible types in 2.5.
+ [Alexander Belchenko]
+
+ - Also fixed a few other 2.5 problems.
+
+ - Fixed problem with the Extension class in the new Pyrex.Distutils
+ module.
+
+
+0.9.6
+-----
+
+New Features:
+
+ - Top-level C functions defined in one module can now be used in
+ another via cimport, and a C API can be produced to allow them
+ to be used from C code without linking to the extension module.
+ See "Interfacing with External C Code" and "Sharing Declarations
+ between Pyrex Modules" in the Language Overview. [Stefan Behnel]
+
+ - Facilities added for releasing the GIL around a section of code
+ and acquiring it on entry to a C function. See "Acquiring and
+ Releasing the GIL under "Interfacing with External C Code" in
+ the Language Overview. [Ulisses Furquim, Stefan Behnel]
+
+ - Some conditional compilation facilities have been added. See
+ "Conditional Compilation" under "Language Basics" in the
+ Language Overview. [Sam Rushing]
+
+Language Changes:
+
+ - The __new__ special method of extension types is being renamed
+ to "__cinit__". For now, you will get a warning whenever you
+ declare a __new__ method for an extension type, and it will
+ automatically be renamed to __cinit__ for you. In the next
+ release, the warning will become an error and no renaming will
+ occur. In some later release, the __new__ method may be
+ re-introduced with different semantics. It is recommended that
+ you begin updating your sources now to use __cinit__.
+
+ - A 'raise' statement with no arguments (i.e. to re-raise the
+ last exception caught) is now required to be lexically within
+ the 'except' clause which caught the exception. This change was
+ necessary to efficiently support preserving the exception if an
+ intervening call raises and catches a different exception.
+
+ - The following new reserved words have been added:
+
+ with, DEF, IF, ELIF, ELSE
+
+Enhancements:
+
+ - Calls to many of the builtin functions are now compiled as
+ direct calls to Python/C API routines.
+
+ - A C type explicitly declared as 'signed' is represented as
+ such in the generated code, to acommodate platforms where
+ 'char' is unsigned by default. [Francesc Altet]
+
+ - Python function can now have an argument of type "unsigned
+ char". [Alexander Belchenko]
+
+ - A new Pyrex.Distutils implementation has been added, which
+ exports an Extension type supporting the following options:
+
+ pyrex_include_dirs - list of dirs to search for Pyrex header files
+ pyrex_create_listing_file - bool - write errs to listing file
+ pyrex_cplus - bool - generate C++ code
+ pyrex_c_in_temp - bool - put generated C files in temp dir
+ pyrex_gen_pxi - bool - generate .pxi file for public declarations
+
+ [Contributed by Billie G. Allie]
+
+ - Assert statements can be compiled out by arranging for
+ PYREX_WITHOUT_ASSERTIONS to be #defined at C compilation time.
+ [Contributed by Stefan Behnel]
+
+ - Support for __index__ slot added to extension types.
+ [William Stein]
+
+ - Exception types now properly checked according to pre or post
+ 2.5 rules as appropriate.
+
+ - Py_ssize_t support added. [Stefan Behnel]
+
+ - Windows __stdcall and __cdecl qualifiers now supported.
+ [Suggested by Eric Devolder]
+
+ - Keyword-only argument support added. [Suggested by Stefan Behnel]
+
+ - An 'include' statement can now appear anywhere that another kind
+ of statement or declaration can appear, instead of being restricted
+ to the top level. [Caio Marcelo]
+
+ - Unnecessary PyErr_Occurred() call to check result of
+ PyString_AsString() no longer made.
+
+ - Complicated C types are displayed more readably in error messages.
+
+Modifications:
+
+ - A Python function argument declared as "char" or "unsigned
+ char" now expects a Python integer rather than a string of
+ length 1, for consistency with the way automatic conversions
+ are done elsewhere.
+
+ - Support for string and tuple exceptions dropped.
+
+Bug fixes:
+
+ - If an external ctypedef type was used as the type of an
+ argument to a Python function, a declaration was generated
+ using the underlying type rather than the typedef name.
+ [Francesc Altet]
+
+ - Some problems with int/enum and pointer/array compatibility
+ fixed. [Eric Huss, Stefan Behnel, Jiba]
+
+ - Eliminated C compiler warning when comparing an extension
+ type reference to None using 'is' or 'is not'
+
+ - Eliminated C compiler warnings about docstrings of C functions
+ and special methods being unused. [Francesc Altet]
+
+ - When compiling with -O, raising an exception in a C function
+ that couldn't propagate exceptions produced a compiler
+ warning about the return value possibly being uninitialised.
+
+ - Fixed warning about function declaration not being a prototype
+ caused by C method table initialisation code.
+
+ - Spurious initialisation was generated for unused local variable.
+ [Helmut Jarausch]
+
+ - Declaration of a non-extern C function without definition
+ was not detected. [Lenard Lindstrom]
+
+ - Applying ** directly to two C int types is now disallowed due
+ to ambiguity (it's not clear whether to use C pow() or convert
+ to Python ints). [Didier Deshommes]
+
+ - Traverse and clear code was being inadvertently generated for
+ the __weakref__ slot of a weakly-referenceable extension type.
+ [Peter Johnson]
+
+ - Statements other than def inside a property declaration were
+ crashing the compiler. [Sven Berkvens]
+
+ - Defining an extension type with different visibility from its
+ declaration in a .pxd file crashed the compiler.
+ [Alex Coventry]
+
+ - Instantiating an exception type whose base class __new__ method
+ raises an exception caused a segfault. [Gustavo Sverzut Barbieri]
+
+ - The 'import pkg.module as name' form of import statement did not
+ work correctly. [Dan]
+
+ - Fixed error-checking typo in __Pyx_GetStarArgs(). [Eric Huss]
+
+ - Trailing comma now allowed on argument list. [Jim Kleckner]
+
+ - Behaviour of reraise made to match Python more closely.
+ [Eric Huss]
+
+ - An empty C variable declaration crashed the compiler.
+
+ - Now includes math.h instead of generating own declaration
+ of pow(). [Leif Strand]
+
+ - Missing import of sys in LinuxSystem.py added. [Scott Jackson]
+
+ - Typecasts using a ctypedef type were not using the ctypedef
+ name. [Alexander Belchenko]
+
+ - Workaround added to setup.py for a problem with bdist_wininst.
+ [Alexander Belchenko]
+
+ - Subtle error in parsing empty function declarators corrected.
+
+ - Checks added for some type combinations that are illegal in C:
+ array of functions, function returning function or array, cast
+ to a function.
+
+
+0.9.5.1a
+--------
+
+Bug fixes:
+
+ - Package list now calculated dynamically in setup.py so that
+ it will work with or without the testing framework installed.
+
+
+0.9.5.1
+-------
+
+Bug fixes:
+
+ - Comparing two values of the same enum type incorrectly
+ produced an error. [Anders Gustafsson]
+
+ - Compiler crash caused by assigning a Python value to
+ a variable of an enum type. [Peter Johnson]
+
+ - Comparison between pointer and array incorrectly produced
+ a type mismatch error. [Helmut Jarausch]
+
+ - Unused local Python variable had spurious init/cleanup code
+ generated for it, causing C compilation errors. [Helmut Jarausch]
+
+ - Updated list of packages in setup.py.
+
+Modifications:
+
+ - NULL in Pyrex source now translated into NULL instead of 0
+ in C code, to allow for the possibility of calling something
+ not defined with a prototype in an external header. [Adapted Cat]
+
+
+0.9.5
+-----
+
+Enhancements:
+
+ - Exception return values may now be specified by arbitrary
+ constant expressions of appropriate type, not just literals.
+ [Stefan Behnel]
+
+ - Redundant type check now omitted when passing a literal None
+ to a function expecting an extension type. [Patch by Sam Rushing]
+
+ - New-style classes now allowed as exceptions for compatibility
+ with Python 2.5 (inheritance from BaseException not currently
+ checked). [Stefan Behnel]
+
+ - Sequence unpacking is now done using the iterator protocol
+ instead of indexing.
+
+ - Allocation of an empty tuple is avoided when making a
+ Python call with no arguments. [Stefan Behnel]
+
+ - Most warnings about unused variables and labels have been
+ eliminated.
+
+ - Support for running the test suite on Linux added but not
+ yet fully tested. [Based in part on patch by Eric Wald].
+
+ - Makefile included for compiling the patched Carbon File module
+ used by the MacOSX test code.
+
+Modifications:
+
+ - Type rules for enums tightened for compatibility with C++.
+
+ - Direct assignment from float to int disallowed to prevent
+ C++ compilation warnings.
+
+ - Hex literals left as hex in C code to avoid warnings from
+ the C compiler about decimal constants becoming unsigned.
+
+Bug fixes:
+
+ - Exception raised during argument conversion could cause crash
+ due to uninitialised local variables. [Konrad Hinsen]
+
+ - Assignment to a C attribute of an extension type from a
+ different type could generate C code with a pointer type
+ mismatch. [Atsuo Ishimoto]
+
+ - Backslash in a string literal before a non-special character
+ was not handled correctly. [Yuan Mang]
+
+ - Temporary vars used by del statement not being properly
+ released, sometimes leading to double decrefs. [Jiba]
+
+ - A return statement whose expression raises an exception
+ inside a try-except that catches the exception could cause
+ a crash. [Anders Gustafsson]
+
+ - Fixed type compatibility checking problem between pointers
+ and arrays. [Lenard Lindstrom]
+
+ - Circular imports between modules defining extension types
+ caused unresolvable import order conflicts. [Mike Wyatt]
+
+ - Cimporting multiple submodules from the same package caused
+ a redefined name error for the top level name. [Martin Albrecht]
+
+ - Incorrect reference counting when assigning to an element of an
+ array that is a C attribute of an extension type. [Igor Khavkine]
+
+ - Weak-referenceable extension types were not implemented
+ properly. [Chris Perkins, Peter Johnson]
+
+ - Crash if C variable declared readonly outside an extension
+ type definition. [Eric Huss]
+
+Doc updates:
+
+ - Expanded discussion of the need for type declarations to enable
+ access to attributes of extension types.
+
+ - Added a section "Source Files and Compilation" explaining the
+ rules for naming of source files of modules residing in packages,
+ and instructions for using the compiler and distutils extension.
+
+
+0.9.4.1
+-------
+
+Bug fixes:
+
+ - Fixed indentation problem in Pyrex.Distutils.build_ext.
+ [Oliver Grisel]
+
+
+0.9.4
+-----
+
+Improvements:
+
+ - All use of lvalue casts has been eliminated, for
+ compatibility with gcc4.
+
+ - PyMODINIT_FUNC now used to declare the module init function.
+
+ - Generated code should be compilable as either C or C++.
+ When compiling as C++, "extern C" is used where appropriate
+ to preserve linkage semantics.
+
+ - An extension type can be made weak-referenceable by
+ giving it a C attribute of type object called __weakref__.
+
+ - Source files opened in universal newlines mode.
+
+ - Support for public extension type C attributes of type
+ long long and unsigned long long added (but not tested).
+ [Sam Rushing]
+
+ - Distutils include directories now passed to Pyrex compiler.
+ [Konrad Hinsen]
+
+ - Integer constants with an "L" suffix are now allowed
+ and are converted to Python long integers. [Rainer Deyke]
+
+ - A broken .c file is no longer left behind if there are
+ compilation errors.
+
+ - Using the result of a Python indexing or attribute access
+ operation as a char * is no longer considered an error in
+ most cases, as the former behaviour proved to be more
+ annoying than helpful.
+
+Bug fixes:
+
+ - Fixed problems with conversion from Python integers to
+ C unsigned longs. Now use PyInt_AsUnsignedLongMask and
+ PyInt_AsUnsignedLongLongMask instead of the PyLong_*
+ functions (which only work on Python longs). [Wim Vree]
+
+ - C unsigned ints now converted to/from Python longs intead
+ of Python ints to avoid overflow problems. [Heiko Wundram]
+
+ - Correct PyArg_ParseTuple format characters now used for
+ unsigned types. [Jeff Bowden]
+
+ - Nonzero return value from a base class tp_traverse call
+ is handled.
+
+ - Taking sizeof an incomplete type caused a crash while
+ producing an error message. [Drew Perttula]
+
+ - If a module cimported itself, definitions of global variables
+ were generated twice. [Parzival Herzog]
+
+ - Distutils extension updated to handle changed signature of
+ swig_sources(). [David M. Cooke]
+
+ - Incorrect C code generated for a raw string containing a double
+ quote preceded by a backslash. [Thomas Drake]
+
+ - Declaration of public C function with an exception value written
+ to generated .pxi file without the except clause. [Robby Dermody]
+
+ - __delitem__ method of an extension type with no __setitem__
+ did not get called. [Richard Boulton]
+
+ - A spurious Py_INCREF was generated when a return statement
+ required a type test. [Jonathan Doda]
+
+ - Casting a value to a function pointer and then immediately
+ calling it generated a cast to a function instead of a cast
+ to a function pointer. [Simon Burton]
+
+ - Py_TPFLAGS_HAVE_GC was not being set on an extension type that
+ inherited from an external extension type that used GC but did
+ not itself have any PyObject* attributes.
+ [Michael Hordijk]
+
+ - A return statement inside a for statement leaked a reference
+ to the loop's iterator.
+ [Jürgen Kartnaller]
+
+ - Full module name now appears in __module__ attribute of classes
+ and extension types, provided a correct dotted name is used
+ for the .pyx file. [Giovanni Bajo]
+
+ - Public extension type with no C attributes produced an
+ invalid .pxi file. [Simon Burton]
+
+ - Using a dict constructor as the second operand of a boolean
+ expression crashed the Pyrex compiler.
+ [Stefan Behnel]
+
+ - A C declaration list ending with a comma resulted in invalid
+ C code being generated. [Alex Coventry]
+
+ - A raw string containing two consecutive backslashes produced
+ incorrect C code. [Helmut Jarausch]
+
+ - An error is reported if you attempt to declare a special
+ method of an extension type using 'cdef' instead of 'def'.
+ [Sam Rushing]
+
+0.9.3
+-----
+
+Enhancements:
+
+ - Types defined with a ctypedef in a 'cdef extern from' block
+ are now referred to by the typedef name in generated C code,
+ so it is no longer necessary to match the type in the C
+ header file exactly.
+
+ - Conversion to/from unsigned long now done with
+ PyLong_AsUnsignedLong and PyLong_FromUnsignedLong. [Dug Song]
+
+ - A struct, union or enum definition in a 'cdef extern from'
+ block may now be left empty (using 'pass'). This can be useful
+ if you need to declare a variable of that type, but don't need
+ to refer to any of its members.
+
+ - More flexible about ordering of qualifiers such as 'long' and
+ 'unsigned'. ["John (J5) Palmieri"]
+
+
+Bug fixes:
+
+ - Non-interned string literals used in a Python class
+ definition did not work. [Atsuo Ishimoto, Andreas Kostyrka]
+
+ - Return types of the buffer interface functions for extension
+ types have been corrected. [Dug Song]
+
+ - Added 'static' to declarations of string literals. [Phil Frost]
+
+ - Float literals are now copied directly to the C code as written,
+ to avoid problems with loss of precision. [Mario Pernici]
+
+ - Inheriting from an extension type with C methods defined in
+ another Pyrex module did not work. [Itamar Shtull-Trauring]
+
+0.9.2.1
+-------
+
+Bug fixes:
+
+ - Corrected an import statement setup.py, and made it
+ check for a unix platform in a more reliable way.
+
+0.9.2
+-----
+
+Enhancements:
+
+ - Names of Python global variables and attributes are now
+ interned, and PyObject_GetAttr/SetAttr are used instead
+ of PyObject_GetAttrString/SetAttrString. String literals
+ which resemble Python identifiers are also interned.
+
+ - String literals are now converted to Python objects only
+ once instead of every time they are used.
+
+ - NUL characters are now allowed in Python string literals.
+
+ - Added some missing error checking code to the beginning
+ of module init functions. It's unlikely the operations
+ involved would ever fail, but you never know.
+
+Bug fixes:
+
+ - Corrected some problems introduced by moving the Plex
+ package.
+
+0.9.1.1
+-------
+
+Bug fixes:
+
+ - Corrected a problem in the setup.py (pyrexc script incorrectly
+ named).
+
+ - Updated the distutils extension to match changes in the
+ Pyrex compiler calling interface.
+
+ - Doing 'make clean' in Demos/callback was removing a little too
+ much (that's why cheesefinder.c kept disappearing).
+
+0.9.1
+-----
+
+Enhancements:
+
+ - A C method can now call an inherited C method by the usual
+ Python technique. [Jiba]
+
+ - The __modname__ of a Python class is now set correctly. [Paul Prescod]
+
+ - A MANIFEST.in file has been added to the distribution to
+ facilitate building rpms. [contributed by Konrad Hinsen]
+
+Bug fixes:
+
+ - Conditional code now generated to allow for the renaming of LONG_LONG
+ to PY_LONG_LONG that occurred between Python 2.2 and 2.3.
+
+ - Header files referenced in cimported modules were not being included.
+ [Tom Popovich]
+
+ - References to C functions and variables in a cimported module were
+ not being recognised if made from within a local scope. [Tom Popovich]
+
+ - Spurious declarations in code generated for a "finally" block.
+ [Brandon Long]
+
+ - Attempting to return a value from a __contains__ method didn't work.
+ [Andreas Kostyrka]
+
+ - Incorrect code generated for an extension type with C methods
+ inheriting from a base type with no C methods. [Robin Becker]
+
+ - Failure to report an error if a C method was defined in the
+ implementation part of an extension type that was not declared
+ in the corresponding definition part. Documentation also updated
+ to explain that this is necessary. [Jiba]
+
+ - Made it an error to forward-declare an extension type with
+ a different base class specification from its subsequent
+ definition. [Jiba]
+
+ - C attributes of an extension type were not being propagated
+ through more than one level of inheritance. [Jiba]
+
+ - If a garbage collection occurred early enough in the __new__
+ method of an extension type with Python-valued C attributes,
+ a crash could occur in its tp_traverse function.
+ [reported by Jiba, fix suggested by Paul Prescod]
+
+ - An empty vtable struct is no longer generated for extension
+ types with no C methods. [Robin Becker]
+
+ - Memory was leaked in the sq_item function of an extension
+ type with a __getitem__ method. [Atsuo Ishimoto]
+
+ - Code generated to work around a bug in some versions of Python
+ 2.2 which fails to initialise the tp_free slot correctly in
+ some circumstances. [Matthias Baas]
+
+ - Compiler crash when defining an extension type with a base
+ class specified by a dotted name. [Alain Pointdexter]
+
+ - Referencing an extension type defined in a cimported module
+ at run time did not work correctly. [Alain Pointdexter]
+
+ - Incorrect object struct code generated for an extension type
+ whose base class was defined in a .pxd file. [Alain Pointdexter]
+
+ - Redeclaring a type that wasn't previously an extension type
+ as an extension type caused a compiler crash. [Scott Robinson]
+
+ - Incorrect code was generated for return statements in a
+ special method with no return value. [Gary Bishop]
+
+ - Single-line def statement did not work. [Francois Pinard]
+
+Modifications:
+
+ - Only the last pathname component of the .pyx file is reported in
+ backtraces now. [Bryan Weingarten]
+
+ - Documentation corrected to remove the erroneous statement that
+ extension classes can have a __del__ method. [Bryan Weingarten]
+
+ - Note added to documentation explaining that it is not possible
+ for an extension type's __new__ method to explicitly call the
+ inherited __new__ method.
+
+ - The version of Plex included with Pyrex is now installed
+ as a subpackage of the Pyrex package, rather than as a
+ top-level package, so as not to interfere with any other
+ version of Plex the user may have installed.
+
+0.9
+---
+
+New features:
+
+ - Extension types can have properties. See the new "Properties"
+ section in the "Extension Types" page.
+
+ - An extension type can inherit from a builtin type or another
+ extension type. See "Subclassing" in the "Extension Types" page.
+
+ - Extension types can have C methods, which can be overridden
+ in derived extension types. See "C Methods" in the "Extension Types"
+ page.
+
+Enhancements:
+
+ - Conversion is now performed between C long longs and Python
+ long integers without chopping to the size of a C long.
+ Also the Python PY_LONG_LONG type is now used for long longs
+ for greater portability.
+
+Bug fixes:
+
+ - Names were sometimes being generated that were insufficiently
+ unique in the presence of cimported declarations.
+
+ - Changed the way the included filename table is declared from
+ char *[] to char **, to stop MSVC from complaining about it
+ having an unknown size. [Alexander A Naanou]
+
+ - Second argument of assert statement was not being coerced
+ to a Python value. [Francois Pinard]
+
+ - Return statement without value wasn't accepted in some
+ extension type special methods when it should have been.
+ [Francois Pinard]
+
+ - Attempting to call a non-function C value crashed the
+ compiler. [John J Lee]
+
+ - Functions declared as "except *" were not returning exceptions.
+ [John J Lee]
+
+ - A syntax warning from Plex about assignment to None has
+ been eliminated. [Gordon Williams]
+
+ - Public function declaration with empty argument list was
+ producing (void) in .pxi file. [Michael P. Dubner]
+
+ - Incorrect error signalling code was being generated in the
+ __hash__ special method of an extension type.
+
+
+0.8.1
+-----
+
+Bug fixes:
+
+ - Names of structs, unions and enums in external header
+ files were getting mangled when they shouldn't have been.
+ [Norman Shelley]
+
+ - Modified distutils extension so that it will stop before
+ compiling the C file if the Pyrex compiler reports errors.
+ [John J Lee]
+
+
+0.8
+---
+
+New features:
+
+ - INCOMPATIBLE CHANGE: The type object of an external extension
+ type is now imported at run time using the Python import
+ mechanism. To make this possible, an 'extern' extension type
+ declaration must DECLARE THE MODULE from which the extension
+ type originates. See the new version of the "Extension Types"
+ documentation for details.
+
+ This change was made to eliminate the need for Pyrex to be
+ told the C name of the type object, or for the Pyrex module
+ to be linked against the object code providing the type object.
+
+ You will have to update any existing external extension type
+ declarations that you are using. I'm sorry about that, but it
+ was too hard to support both the old and new ways.
+
+ - Compile-time importing: A Pyrex module can now import declarations
+ from another Pyrex module using the new 'cimport' statement. See
+ the new section on "Sharing Declarations Between Pyrex Modules" in
+ the documentation.
+
+Minor improvements:
+
+ - An error is reported if you declare a struct, union or
+ extension type using 'cdef' in one place and 'ctypedef'
+ in another.
+
+ - Struct, union and extension types can only be forward-
+ declared using 'cdef', not 'ctypedef' (otherwise invalid
+ C code would be generated).
+
+ - The 'global' statement can be used at the module level to
+ declare that a name is a module-level name rather than a
+ builtin. This can be used to access module attributes such
+ as __name__ that would otherwise be assumed to be builtins.
+ [Pat Maupin]
+
+ - The 'assert' statement now accepts a second argument.
+ [Francois Pinard]
+
+Bug fixes:
+
+ - When using Python 2.3, "True" or "False" could sometimes
+ turn up in generated code instead of "1" or "0". [Adam Hixson]
+
+ - Function return value not always converted to or from a
+ Python object when it should have been.
+
+ - Certain kinds of error in a function call expression
+ could crash the compiler. ["Edward C. Jones"]
+
+ - Fixed memory leak in functions with * or ** args. [Alexander A Naanou]
+
+
+0.7.1
+-----
+
+Bug fixes:
+
+ - Calling a function declared as returning an extension
+ type could crash the compiler.
+
+ - A function call with type errors in the argument list
+ could crash the compiler.
+
+ - An 'else' clause on a for-from statement could crash
+ the compiler.
+
+ - Incorrect casting code was generated when a generic
+ object argument of a special method was declared as
+ being of an extension type. [Phillip J. Eby]
+
+ - A blank line that couldn't be interpreted wholly as
+ a valid indentation sequence caused a syntax error.
+ In particular, a formfeed character on an otherwise
+ blank line wasn't accepted. [Francois Pinard]
+
+ - Parallel assignments were incorrectly optimised.
+
+ - A bare tuple constructor with an extra comma at the
+ end of a line caused a syntax error.
+
+0.7
+---
+
+New features:
+
+ - Attributes of extension types can be exposed to Python
+ code, either read/write or read-only.
+
+ - Different internal and external names can be specified
+ for C entities.
+
+ - None is a compile-time constant, and more efficient code
+ is generated to reference it.
+
+ - Command line options for specifying directories to
+ search for include files.
+
+Enhancements:
+
+ - More efficient code is generated for access to Python
+ valued C attributes of extension types.
+
+ - Cosmetic code improvement: Less casting back and forth
+ between extension types and PyObject * when referencing
+ C members of the object struct.
+
+ - C arguments and variables declared as an extension type
+ can take the value None.
+
+ - Form feed characters are accepted as whitespace.
+
+ - Function names in tracebacks are qualified with
+ module name and class name.
+
+Bug fixes:
+
+ - A sufficiently complex expression in a boolean context
+ could cause code to be generated twice for the same
+ subexpression.
+
+ - Incorrect casting code was generated when passing an
+ extension type to a function expecting a generic Python
+ object.
+
+ - Executable statements are now disallowed inside a
+ cdef class block (previously they silently caused
+ crazy C code to be generated).
+
+ - Tracebacks should now report the correct filename for
+ functions defined in files included with the 'include'
+ statement.
+
+ - The documentation incorrectly claimed that an extension
+ type can't have a __del__ method. In fact, it can, and
+ it behaves as expected.
+
+
+0.6.1
+-----
+
+Bug fixes:
+
+ - Fixed broken distutils extension.
+
+
+
+0.6
+---
+
+New features:
+
+ - Command line options for reporting version number,
+ requesting a listing file and specifying the name of
+ the generated C file.
+
+ - An 'include' statement allows inclusion of declarations
+ from other Pyrex source files.
+
+ - If there are any public declarations, a Pyrex include
+ file is generated (as well as a .h file) containing
+ declarations for them.
+
+ - Extension types can be declared public, so their C
+ attributes are visible to other Pyrex and C code.
+
+ - Try-except statements can now have an 'else' clause.
+ [Francois Pinard]
+
+ - Multiple simple statements can be placed on one line
+ separated by semicolons.
+
+ - A suite consisting of a simple statement list can now
+ be placed on the same line after the colon in most
+ cases. [Francois Pinard]
+
+ - The automatic coercion of a C string to a C char has
+ been removed (it proved to be too error-prone).
+ Instead, there is a new form of literal for C
+ character constants: c'X'
+
+ - The __get__ special method (used by descriptor objects)
+ now allows for the possibility of the 2nd or 3rd
+ arguments being NULL. Also the __set__ method has been
+ split into two methods, __set__ and __delete__.
+ [Phillip J. Eby]
+
+Bug fixes:
+
+ - Values unpacked into a non-Python destination variable
+ were not being converted before assignment. [Gareth Watts]
+
+ - Hex constants greater than 0x7fffffff caused compiler
+ to crash. [Gareth Watts]
+
+ - Type slots are no longer statically initialised with
+ extern function pointers, to avoid problems with
+ some compilers. The hack in the distutils extension
+ to work around this by compiling as C++ has been
+ disabled. [Phillip J. Eby]
+
+ - Fixed several more instances of the error-reporting
+ routine being called with arguments in the wrong
+ order. Hoping I've *finally* got all of them now...
+
+ - Nested for-from loops used the same control variable.
+ [Sebastien de Menten]
+
+ - Fixed some other error message related bugs. [Francois Pinard]
+
+ - Assigning to slice didn't work. [Francois Pinard]
+
+ - Temp variables were being declared as extension
+ types and then being assigned PyObject *'s. All
+ Python temp vars are now declared as PyObject *.
+ [Francois Pinard]
+
+0.5
+---
+
+Bug fixes:
+
+ - Algorithm for allocating temp variables redesigned
+ to fix various errors concerning temp
+ variable re-use. [Mark Rowe]
+
+ - Memory leak occured sometimes when an implicit
+ type test was applied to the result of an
+ expression. [Christoph Wiedemann]
+
+ - __set__ method of extension types had wrong
+ signature. [Josh Littlefield]
+
+0.4.6
+-----
+
+Bug fixes:
+
+ - Indexing multi-dimensional C arrays didn't
+ work. [Gary Dietachmayer]
+
+
+0.4.5
+-----
+
+New features:
+
+ - There is now a 'public' declaration for
+ making Pyrex-defined variables and functions
+ available to external C code. A .h file is
+ also generated if there are any public
+ declarations.
+
+Enhancements:
+
+ - Defining __len__/__getitem__ methods in an
+ extension class fills sq_length/sq_item slots
+ as well as mp_length/mp_subscript. [Matthias Baas]
+
+ - The Distutils extension now allows .c files
+ to be incorporated along with .pyx files.
+ [Modification to Distutils extension contributed
+ by Darrell Gallion]
+
+Bug fixes:
+
+ - Float literals without a decimal point
+ work again now. [Mike Rovner, Peter Lepage]
+
+ - Compiler crashed if exception value didn't
+ match function return type. [Michael JasonSmith]
+
+ - The setup.py file should now install the
+ Lexicon.pickle file in the right place.
+ [Patch supplied by David M. Cooke]
+
+ - Compiler crashed when compiling a C function that
+ returned an extension type.
+ [David M. Cooke]
+
+ - Anonymous enum types did not have C code
+ suppressed inside an extern-from block. [Matthew Mueller]
+
+
+0.4.4
+-----
+
+Enhancements:
+
+ - Tracebacks now extend into Pyrex function
+ calls and show line numbers in the Pyrex
+ source file.
+
+ - Syntax for float literals made more lenient
+ (no longer requires digits both before and
+ after the point). [Peter Lepage]
+
+ - Method calls can be made on string literals
+ (e.g. ",".join(x)). [Pedro Rodriguez]
+
+Bug fixes:
+
+ - Incorrect refcount code generated when a
+ Python function needing argument type tests
+ had local Python variables. [Matthias Baas]
+
+ - 'self' parameter of __getitem__ method of
+ extension type had wrong implicit type. [Peter Lepage]
+
+ - Repaired breakage introduced by trying to
+ allow an empty parameter list to be written
+ as (void). No longer attempting to allow
+ this (too hard to parse correctly). [Peter Lepage]
+
+ - Found bug in Plex 1.1.2 which was the *real*
+ cause of the two-newlines-in-a-row problem.
+ Removed the Opt(Eol)+Str("\n") hacks in
+ the scanner which were working around this
+ before. [Pedro Rodriguez]
+
+ - __call__ special method of extension types
+ had wrong signature. [Peter Lepage]
+
+
+0.4.3
+-----
+
+New language features:
+
+ - For-from loop for iterating over integer
+ ranges, using pure C loop where possible.
+
+Enhancements:
+
+ - sizeof() can now be applied to types as
+ well as variables.
+
+ - Improved handling of forward-declared
+ extension types.
+
+Bug fixes:
+
+ - Two newlines in a row in a triple quoted
+ string caused a parse error on some
+ platforms. [Matthias Baas]
+
+ - Fixed problem with break and continue in
+ the else-clause of a loop.
+
+
+0.4.2
+-----
+
+New language features:
+
+ - C functions can be declared as having an
+ exception return value, which is checked
+ whenever the function is called. If an
+ exception is detected inside a C function
+ for which no exception value is declared,
+ a warning message is printed and the
+ exception is cleared.
+
+ - Cascaded assignments (i.e. a = b = c
+ are now supported.
+
+ - Anonymous enum declarations are allowed,
+ for when you just want to declare constants.
+
+ - The C types "long long" and "long double"
+ are now understood. Also, "int" is optional
+ after "short" or "long".
+
+Enhancements:
+
+ - A * argument in a function call can now be
+ any sequence, not just a tuple.
+
+ - A C char* or char[] will be turned into
+ a char by taking its first character if
+ used in a context where a char is required,
+ thus allowing a string literal to be used as
+ a char literal.
+
+ - C string * C int or vice versa is now
+ interpreted as Python string replication.
+
+ - Function arguments are checked for void or
+ incomplete type.
+
+Bug fixes:
+
+ - Non-external extension types show up in the
+ module dict once more (this got broken in
+ 0.4.1).
+
+ - A spurious decref has been removed from the
+ runtime support code for the "import" statement.
+ Hopefully this will prevent the crashes some
+ people have been experiencing when importing
+ builtin modules. [Mathew Yeates]
+
+0.4.1
+-----
+
+New language features:
+
+ - "ctypedef struct/union/enum/class" statements
+ added, for use in extern-from blocks when a
+ header file uses a ctypedef to declare a
+ tagless struct, union or enum type.
+
+ - "pass" allowed in an extern-from block.
+
+ - "cdef extern from *" for when you don't want
+ to specify an include file name.
+
+ - Argument names may be omitted in function
+ signatures when they're not needed.
+
+ - New reserved word NULL for the null C pointer.
+
+Compiler enhancements:
+
+ - Lexicon is now picked in binary format, so
+ startup should be much faster on slower
+ machines.
+
+ - If Pyrex decides to rebuild the lexicon and
+ then finds that it can't write a pickle file,
+ it now prints a warning and carries on
+ instead of crashing.
+
+ - Chat about hash codes and lexicon pickling
+ now turned off by default except when creating
+ a new lexicon (which ought never happen now
+ unless you change the scanner).
+
+Bug fixes:
+
+ - Modified the runtime support code for "import"
+ statements, hopefully fixing problem with using
+ a Pyrex module in conjunction with py2exe.
+
+ - DL_EXPORT now used in both the prototype and
+ definition of the module init function.
+
+ - Exception state is now saved and restored around
+ calls to an extension type __dealloc__ method,
+ to avoid screwing up if the object is deallocated
+ while an exception is being propagated.
+
+ - Making an attribute reference to a method of
+ an extension type caused a compiler crash.
+
+ - Doc string in new-style class definition
+ caused a run-time error.
+
+ - Insufficient parentheses were put around C type
+ casts.
+
+ - Constructors for extension types are now read-only
+ C global variables instead of entries in the
+ module dict. This change was needed to prevent
+ Numeric from blowing up due to touching its
+ typeobject before import_numeric() could be called.
+
+0.4
+---
+
+New features:
+
+ - "cdef extern from" statement allows inclusion
+ of C header files to be specified, solving
+ a number of problems including:
+ - Clashes between Pyrex and C declarations,
+ due to "const" and other reasons
+ - Windows-specific features required in
+ function declarations
+ - Helping deal with types such as "size_t"
+ - Helping deal with functions defined as
+ macros
+
+ - Access to internals of pre-existing extension
+ types is now possible by placing an extension
+ type declaration inside a "cdef extern from"
+ block.
+
+Bug fixes:
+
+ - Error not reported properly when passing
+ wrong number of args to certain special
+ methods of extension types. [Mitch Chapman]
+
+ - Compile-time crash when defining an extension
+ type with a __hash__ method.
+
+Minor enhancements:
+
+ - Hashing of the scanner source file made more
+ platform-independent, making spurious regeneration
+ of the pickle less likely.
+
+
+0.3.4
+-----
+
+Bug fixes:
+
+ - Runtime crash when using * or ** args in
+ a method of an extension type fixed. [Matthew Mueller]
+
+ - Compiler crash when using default argument
+ values in a method of a Python class. [Mike Rovner]
+
+Enhancements:
+
+ - Type slots filled with functions from outside
+ the extension module are now initialised dynamically,
+ which should eliminate at least some of the
+ "initialiser is not constant" problems experienced
+ on Windows. [Marek Baczek]
+
+ - On Windows, __declspec(dllexport) is now used for
+ the module init func declaration (or should be --
+ I haven't tested this). [Marek Baczek]
+
+ - The compiler shouldn't attempt to rewrite the
+ Lexicon.pickle file unless the source has been
+ changed (hashing is used now instead of comparing
+ timestamps). So there should be no problem any more
+ with installing Pyrex read-only.
+
+0.3.3
+-----
+
+Bug fixes:
+
+* A void * can be assigned from any other
+pointer type.
+* File names in error messages no longer
+quoted (this was apparently confusing some
+editors). [Matthew Mueller]
+
+* Reference to a struct member which is an
+array is coerced to a pointer. [Matthew Mueller]
+
+* Default argument values did not work
+in methods of an extension type. [Matthew Mueller]
+
+* Single or double quote characters in a
+triple-quoted string didn't work. [Matthew Mueller]
+
+* Using *args in a function definition
+sometimes caused a crash at runtime. [Matthew Mueller]
+
+* A hack is included which tries to make
+functions in Python.h which use 'const'
+accessible from Pyrex. But it doesn't
+work on all platforms. Thinking about a
+better solution.
+
+
+New features:
+
+* Comment containing Pyrex version number
+and date/time at top of generated C file. [Matthias Baas]
+
+
+0.3.2
+-----
+
+Bug fixes:
+
+* The & operator works again. [Matthias Baas]
+
+* The & operator had incorrect precedence.
+
+* "SystemError: 'finally' pops bad exception"
+under some circumstances when raising an
+exception. [Matthias Baas]
+
+* Calling a Python function sometimes leaked
+a reference.
+
+* Crash under some circumstances when casting
+a Python object reference to a C pointer type.
+[Michael JasonSmith]
+
+* Crash when redeclaring a function. [Matthias Baas]
+
+* Crash when using a string constant inside
+a Python class definition. [Mike Rovner]
+
+* 2-element slice indexing expressions. [Mike Rovner]
+
+* Crash when encountering mixed tabs and
+spaces. [Mike Rovner]
+
+New features:
+
+* A wider variety of constant expressions is
+now accepted for enum values, array
+dimensions, etc. [Mike Rovner]
+
+
+0.3.1
+-----
+
+New features:
+
+* More special methods for extension types:
+__delitem__, __delslice__, __getattr__,
+__setattr__, __delattr__
+
+* Module-level variable of a Python object type
+declared with 'cdef' is private to the module, and
+held in a C variable instead of the module dict.
+
+* External C functions with variable argument lists
+can be declared and called.
+
+* Pyrex-defined Python functions can have default
+argument values and * and ** arguments, and can be
+called with keyword arguments.
+
+* Pointer-to-function types can be declared.
+
+* Pyrex now supports a declaration syntax that
+C doesn't! Example:
+
+ cdef (int (*)()) foo() # function returning a function ptr
+
+* There is now a ctypedef statement.
+
+* Extension types can now be forward-declared.
+
+* All permutations of (non-Unicode) string literals
+and escape codes should work now.
+
+* Hex and octal integer literals.
+
+* Imaginary number literals.
+
+* Docstrings are now supported.
+
+Bug fixes:
+
+* Type tests are performed when using a Python object
+in a context requiring a particular extension type.
+
+* Module-level variable holding the type object
+of an extension type had incorrect type.
+
+0.3
+---
+
+New features:
+
+* Extension types! Yay!
+
+0.2.2
+-----
+
+Bug fixes:
+
+* Fixed error message generation again after a previous
+bug was accidentally re-indroduced.
+
+* Removed the declaration of isspace() from the code
+generated for print statement support (it's not needed
+and was conflicting with the system-supplied one on
+some platforms).
+
+0.2
+---
+
+New features:
+
+* Executable statements are now allowed at the
+top level of a module.
+
+* Python class definitions are now supported, with
+the following limitations:
+
+ - Class definitions are only allowed at the top
+ level of a module, not inside a control structure
+ or function or another class definition.
+
+ - Assigning a Pyrex-defined Python function to a
+ class attribute outside of the class definition
+ will not create a method (because it's not an
+ interpreted Python function and therefore
+ won't trigger the bound-method creation magic).
+
+ - The __metaclass__ mechanism and the creation of
+ new-style classes is not (yet) supported.
+
+* Casting between Python and non-Python types is
+better supported.
+
+Bug fixes:
+
+* Fixed bug preventing for-loops from working.
+
+
+0.1.1
+-----
+
+* I've discovered a flaw in my algorithm for releasing
+temp variables. Fixing this properly will require some
+extensive reworking; I've put in a hack in the meantime
+which should work at the cost of using more temp variables
+than are strictly necessary.
+
+* Fixed bug preventing access to builtin names from
+working. This should also have fixed the import
+statement, but I haven't tested it.
+
+* Fixed some errors in __Pyx_GetExcValue.
+
+* Fixed bug causing boolean expressions to malfunction
+sometimes.
diff --git a/debian/pyrex/pyrex-0.9.9/CHECKLIST.txt b/debian/pyrex/pyrex-0.9.9/CHECKLIST.txt
new file mode 100644
index 00000000..c35c0f77
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/CHECKLIST.txt
@@ -0,0 +1,24 @@
+Release Checklist
+=================
+
+* Update CHANGES.txt
+
+* Ensure all tests pass
+
+* cd Demos; make test
+
+* make test_setup
+
+* Check version number in Makefile
+
+* Update news in web page
+
+* Commit changes
+
+* Tag release
+
+* cd ..; make tar
+
+* make upload
+
+* make push
diff --git a/debian/pyrex/pyrex-0.9.9/Demos/Makefile b/debian/pyrex/pyrex-0.9.9/Demos/Makefile
new file mode 100644
index 00000000..e70687f4
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Demos/Makefile
@@ -0,0 +1,15 @@
+all:
+ python Setup.py build_ext --inplace
+
+test: all
+ python run_primes.py 20
+ python run_numeric_demo.py
+ python run_spam.py
+ cd callback; $(MAKE) test
+
+clean:
+ @echo Cleaning Demos
+ @rm -f *.c *.o *.so *~ core
+ @rm -rf build
+ @cd callback; $(MAKE) clean
+ @cd embed; $(MAKE) clean
diff --git a/debian/pyrex/pyrex-0.9.9/Demos/Makefile.nodistutils b/debian/pyrex/pyrex-0.9.9/Demos/Makefile.nodistutils
new file mode 100644
index 00000000..d648f849
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Demos/Makefile.nodistutils
@@ -0,0 +1,21 @@
+PYHOME = $(HOME)/pkg/python/version
+PYINCLUDE = \
+ -I$(PYHOME)/include/python2.2 \
+ -I$(PYHOME)/$(ARCH)/include/python2.2
+
+%.c: %.pyx
+ ../bin/pyrexc $<
+
+%.o: %.c
+ gcc -c -fPIC $(PYINCLUDE) $<
+
+%.so: %.o
+ gcc -shared $< -lm -o $@
+
+all: primes.so spam.so numeric_demo.so
+
+clean:
+ @echo Cleaning Demos
+ @rm -f *.c *.o *.so *~ core core.*
+ @cd callback; $(MAKE) clean
+ @cd embed; $(MAKE) clean
diff --git a/debian/pyrex/pyrex-0.9.9/Demos/Setup.py b/debian/pyrex/pyrex-0.9.9/Demos/Setup.py
new file mode 100644
index 00000000..e220d81b
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Demos/Setup.py
@@ -0,0 +1,14 @@
+from distutils.core import setup
+#from distutils.extension import Extension
+from Pyrex.Distutils.extension import Extension
+from Pyrex.Distutils import build_ext
+
+setup(
+ name = 'Demos',
+ ext_modules=[
+ Extension("primes", ["primes.pyx"]),
+ Extension("spam", ["spam.pyx"]),
+ Extension("numeric_demo", ["numeric_demo.pyx"]),
+ ],
+ cmdclass = {'build_ext': build_ext}
+)
diff --git a/debian/pyrex/pyrex-0.9.9/Demos/callback/Makefile b/debian/pyrex/pyrex-0.9.9/Demos/callback/Makefile
new file mode 100644
index 00000000..890bc808
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Demos/callback/Makefile
@@ -0,0 +1,10 @@
+all:
+ python Setup.py build_ext --inplace
+
+test: all
+ python run_cheese.py
+
+clean:
+ @echo Cleaning Demos/callback
+ @rm -f cheese.c *.o *.so *~ core
+ @rm -rf build
diff --git a/debian/pyrex/pyrex-0.9.9/Demos/callback/Makefile.nodistutils b/debian/pyrex/pyrex-0.9.9/Demos/callback/Makefile.nodistutils
new file mode 100644
index 00000000..012c1a86
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Demos/callback/Makefile.nodistutils
@@ -0,0 +1,19 @@
+PYHOME = $(HOME)/pkg/python/version
+PYINCLUDE = \
+ -I$(PYHOME)/include/python2.2 \
+ -I$(PYHOME)/$(ARCH)/include/python2.2
+
+%.c: %.pyx
+ ../../bin/pyrexc $<
+
+%.o: %.c
+ gcc -c -fPIC $(PYINCLUDE) $<
+
+%.so: %.o
+ gcc -shared $< -lm -o $@
+
+all: cheese.so
+
+clean:
+ @echo Cleaning Demos/callback
+ @rm -f *.c *.o *.so *~ core core.*
diff --git a/debian/pyrex/pyrex-0.9.9/Demos/callback/README.txt b/debian/pyrex/pyrex-0.9.9/Demos/callback/README.txt
new file mode 100644
index 00000000..fa3b871c
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Demos/callback/README.txt
@@ -0,0 +1 @@
+This example demonstrates how you can wrap a C API that has a callback interface, so that you can pass Python functions to it as callbacks. The files cheesefinder.h and cheesefinder.c represent the C library to be wrapped. The file cheese.pyx is the Pyrex module which wraps it. The file run_cheese.py demonstrates how to call the wrapper. \ No newline at end of file
diff --git a/debian/pyrex/pyrex-0.9.9/Demos/callback/Setup.py b/debian/pyrex/pyrex-0.9.9/Demos/callback/Setup.py
new file mode 100644
index 00000000..5e48206a
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Demos/callback/Setup.py
@@ -0,0 +1,11 @@
+from distutils.core import setup
+from distutils.extension import Extension
+from Pyrex.Distutils import build_ext
+
+setup(
+ name = 'callback',
+ ext_modules=[
+ Extension("cheese", ["cheese.pyx", "cheesefinder.c"]),
+ ],
+ cmdclass = {'build_ext': build_ext}
+)
diff --git a/debian/pyrex/pyrex-0.9.9/Demos/callback/cheese.pyx b/debian/pyrex/pyrex-0.9.9/Demos/callback/cheese.pyx
new file mode 100644
index 00000000..db0fc082
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Demos/callback/cheese.pyx
@@ -0,0 +1,13 @@
+#
+# Pyrex wrapper for the cheesefinder API
+#
+
+cdef extern from "cheesefinder.h":
+ ctypedef void (*cheesefunc)(char *name, void *user_data)
+ void find_cheeses(cheesefunc user_func, void *user_data)
+
+def find(f):
+ find_cheeses(callback, <void*>f)
+
+cdef void callback(char *name, void *f):
+ (<object>f)(name)
diff --git a/debian/pyrex/pyrex-0.9.9/Demos/callback/cheesefinder.c b/debian/pyrex/pyrex-0.9.9/Demos/callback/cheesefinder.c
new file mode 100644
index 00000000..ab41853b
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Demos/callback/cheesefinder.c
@@ -0,0 +1,21 @@
+/*
+ * An example of a C API that provides a callback mechanism.
+ */
+
+#include "cheesefinder.h"
+
+static char *cheeses[] = {
+ "cheddar",
+ "camembert",
+ "that runny one",
+ 0
+};
+
+void find_cheeses(cheesefunc user_func, void *user_data) {
+ char **p = cheeses;
+ while (*p) {
+ user_func(*p, user_data);
+ ++p;
+ }
+}
+
diff --git a/debian/pyrex/pyrex-0.9.9/Demos/callback/cheesefinder.h b/debian/pyrex/pyrex-0.9.9/Demos/callback/cheesefinder.h
new file mode 100644
index 00000000..3c31bdc0
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Demos/callback/cheesefinder.h
@@ -0,0 +1 @@
+typedef void (*cheesefunc)(char *name, void *user_data); void find_cheeses(cheesefunc user_func, void *user_data); \ No newline at end of file
diff --git a/debian/pyrex/pyrex-0.9.9/Demos/callback/run_cheese.py b/debian/pyrex/pyrex-0.9.9/Demos/callback/run_cheese.py
new file mode 100644
index 00000000..65fd431b
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Demos/callback/run_cheese.py
@@ -0,0 +1,7 @@
+import cheese
+
+def report_cheese(name):
+ print "Found cheese:", name
+
+cheese.find(report_cheese)
+
diff --git a/debian/pyrex/pyrex-0.9.9/Demos/embed/Makefile b/debian/pyrex/pyrex-0.9.9/Demos/embed/Makefile
new file mode 120000
index 00000000..a89ef208
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Demos/embed/Makefile
@@ -0,0 +1 @@
+Makefile.unix \ No newline at end of file
diff --git a/debian/pyrex/pyrex-0.9.9/Demos/embed/Makefile.msc b/debian/pyrex/pyrex-0.9.9/Demos/embed/Makefile.msc
new file mode 100644
index 00000000..37114c73
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Demos/embed/Makefile.msc
@@ -0,0 +1,35 @@
+# Makefile for Microsoft C Compiler, building a DLL
+PYVERSION = 2.2
+PYHOME = \Python$(PYVERSION:.=)
+PYINCLUDE = -I$(PYHOME)\include
+PYLIB = /LIBPATH:$(PYHOME)\libs
+
+CFLAGS = $(PYINCLUDE) /Ox /W3 /GX -nologo
+.SUFFIXES: .exe .dll .obj .c .cpp .pyx
+
+.pyx.c:
+ $(PYHOME)\Python.exe ../../pyrexc.py $<
+
+all: main.exe
+
+clean:
+ del /Q/F *.obj embedded.h embedded.c main.exe embedded.dll embedded.lib embedded.exp
+
+# When linking the DLL we must explicitly list all of the exports
+# There doesn't seem to be an easy way to get DL_EXPORT to have the correct definition
+# to do the export for us without breaking the importing of symbols from the core
+# python library.
+embedded.dll: embedded.obj
+ link /nologo /DLL /INCREMENTAL:NO $(PYLIB) $** /IMPLIB:$*.lib /DEF:<< /OUT:$*.dll
+EXPORTS initembedded
+EXPORTS spam
+<<
+
+main.exe: main.obj embedded.lib
+ link /nologo $** $(PYLIB) /OUT:main.exe
+
+embedded.h: embedded.c
+main.obj: embedded.h
+embedded.obj: embedded.c
+ $(CC) /MD $(CFLAGS) -c $**
+embedded.lib: embedded.dll
diff --git a/debian/pyrex/pyrex-0.9.9/Demos/embed/Makefile.msc.static b/debian/pyrex/pyrex-0.9.9/Demos/embed/Makefile.msc.static
new file mode 100644
index 00000000..14e1080c
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Demos/embed/Makefile.msc.static
@@ -0,0 +1 @@
+# Makefile for Microsoft compiler statically linking PYVERSION = 2.2 PYHOME = \Python$(PYVERSION:.=) PYINCLUDE = -I$(PYHOME)\include PYLIB = /LIBPATH:$(PYHOME)\libs python22.lib CFLAGS = $(PYINCLUDE) /Ox /W3 /GX -nologo .SUFFIXES: .exe .dll .obj .c .cpp .pyx .pyx.c: $(PYHOME)\Python.exe ../../pyrexc.py $< all: main.exe clean: -del /Q/F *.obj embedded.h embedded.c main.exe main.exe: main.obj embedded.obj link /nologo $** $(PYLIB) /OUT:main.exe embedded.h: embedded.c main.obj: embedded.h \ No newline at end of file
diff --git a/debian/pyrex/pyrex-0.9.9/Demos/embed/Makefile.unix b/debian/pyrex/pyrex-0.9.9/Demos/embed/Makefile.unix
new file mode 100644
index 00000000..c8c7dbeb
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Demos/embed/Makefile.unix
@@ -0,0 +1,30 @@
+PYVERSION = 2.2
+PYHOME = $(HOME)/pkg/python/$(PYVERSION)
+PYARCH = $(PYHOME)/$(ARCH)
+PYINCLUDE = \
+ -I$(PYHOME)/include/python$(PYVERSION) \
+ -I$(PYARCH)/include/python$(PYVERSION)
+PYLIB = -L$(PYARCH)/lib/python$(PYVERSION)/config \
+ -lpython$(PYVERSION) \
+ -ldl -lpthread -lutil -lm
+
+%.c: %.pyx
+ ../../bin/pyrexc $<
+
+%.o: %.c
+ gcc -c -fPIC $(PYINCLUDE) $<
+
+#%.so: %.o
+# gcc -shared $< -lm -o $@
+
+all: main
+
+main: main.o embedded.o
+ gcc main.o embedded.o $(PYLIB) -o main
+
+clean:
+ @echo Cleaning Demos/embed
+ @rm -f *~ *.o *.so core core.* embedded.h embedded.c main
+
+embedded.h: embedded.c
+main.o: embedded.h
diff --git a/debian/pyrex/pyrex-0.9.9/Demos/embed/README b/debian/pyrex/pyrex-0.9.9/Demos/embed/README
new file mode 100644
index 00000000..55283ac3
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Demos/embed/README
@@ -0,0 +1 @@
+This example demonstrates how Pyrex-generated code can be called directly from a main program written in C. In this example, the module's initialisation function (called "initembedded", since the module is called "embedded") is called explicitly. This is necessary because the module is not being imported using the normal Python import mechanism. The Windows makefiles were contributed by Duncan Booth <Duncan.Booth@SuttonCourtenay.org.uk>. \ No newline at end of file
diff --git a/debian/pyrex/pyrex-0.9.9/Demos/embed/embedded.pyx b/debian/pyrex/pyrex-0.9.9/Demos/embed/embedded.pyx
new file mode 100644
index 00000000..90d62f67
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Demos/embed/embedded.pyx
@@ -0,0 +1,5 @@
+cdef public void spam():
+ praise()
+
+def praise():
+ print "Spam, glorious spam!"
diff --git a/debian/pyrex/pyrex-0.9.9/Demos/embed/main.c b/debian/pyrex/pyrex-0.9.9/Demos/embed/main.c
new file mode 100644
index 00000000..3e089abc
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Demos/embed/main.c
@@ -0,0 +1,9 @@
+#include "Python.h"
+#include "embedded.h"
+
+int main(int argc, char *argv) {
+ Py_Initialize();
+ initembedded();
+ spam();
+ Py_Finalize();
+}
diff --git a/debian/pyrex/pyrex-0.9.9/Demos/numeric_demo.pyx b/debian/pyrex/pyrex-0.9.9/Demos/numeric_demo.pyx
new file mode 100644
index 00000000..3a20fd90
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Demos/numeric_demo.pyx
@@ -0,0 +1,39 @@
+#
+# This example demonstrates how to access the internals
+# of a Numeric array object.
+#
+
+cdef extern from "Numeric/arrayobject.h":
+
+ struct PyArray_Descr:
+ int type_num, elsize
+ char type
+
+ ctypedef class Numeric.ArrayType [object PyArrayObject]:
+ cdef char *data
+ cdef int nd
+ cdef int *dimensions, *strides
+ cdef object base
+ cdef PyArray_Descr *descr
+ cdef int flags
+
+def print_2d_array(ArrayType a):
+ print "Type:", chr(a.descr.type)
+ if chr(a.descr.type) <> "f":
+ raise TypeError("Float array required")
+ if a.nd <> 2:
+ raise ValueError("2 dimensional array required")
+ cdef int nrows, ncols
+ cdef float *elems, x
+ nrows = a.dimensions[0]
+ ncols = a.dimensions[1]
+ elems = <float *>a.data
+ hyphen = "-"
+ divider = ("+" + 10 * hyphen) * ncols + "+"
+ print divider
+ for row in range(nrows):
+ for col in range(ncols):
+ x = elems[row * ncols + col]
+ print "| %8f" % x,
+ print "|"
+ print divider
diff --git a/debian/pyrex/pyrex-0.9.9/Demos/primes.pyx b/debian/pyrex/pyrex-0.9.9/Demos/primes.pyx
new file mode 100644
index 00000000..dfbaae48
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Demos/primes.pyx
@@ -0,0 +1,18 @@
+def primes(int kmax):
+ cdef int n, k, i
+ cdef int p[1000]
+ result = []
+ if kmax > 1000:
+ kmax = 1000
+ k = 0
+ n = 2
+ while k < kmax:
+ i = 0
+ while i < k and n % p[i] <> 0:
+ i = i + 1
+ if i == k:
+ p[k] = n
+ k = k + 1
+ result.append(n)
+ n = n + 1
+ return result
diff --git a/debian/pyrex/pyrex-0.9.9/Demos/pyprimes.py b/debian/pyrex/pyrex-0.9.9/Demos/pyprimes.py
new file mode 100644
index 00000000..edcce852
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Demos/pyprimes.py
@@ -0,0 +1,13 @@
+def primes(kmax):
+ p = []
+ k = 0
+ n = 2
+ while k < kmax:
+ i = 0
+ while i < k and n % p[i] <> 0:
+ i = i + 1
+ if i == k:
+ p.append(n)
+ k = k + 1
+ n = n + 1
+ return p
diff --git a/debian/pyrex/pyrex-0.9.9/Demos/run_numeric_demo.py b/debian/pyrex/pyrex-0.9.9/Demos/run_numeric_demo.py
new file mode 100644
index 00000000..803442d5
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Demos/run_numeric_demo.py
@@ -0,0 +1,5 @@
+import Numeric
+import numeric_demo
+
+a = Numeric.array([[1.0, 3.5, 8.4], [2.3, 6.6, 4.1]], "f")
+numeric_demo.print_2d_array(a)
diff --git a/debian/pyrex/pyrex-0.9.9/Demos/run_primes.py b/debian/pyrex/pyrex-0.9.9/Demos/run_primes.py
new file mode 100644
index 00000000..487767d4
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Demos/run_primes.py
@@ -0,0 +1,7 @@
+import sys
+from primes import primes
+if len(sys.argv) >= 2:
+ n = int(sys.argv[1])
+else:
+ n = 1000
+print primes(n)
diff --git a/debian/pyrex/pyrex-0.9.9/Demos/run_spam.py b/debian/pyrex/pyrex-0.9.9/Demos/run_spam.py
new file mode 100644
index 00000000..e1c1e155
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Demos/run_spam.py
@@ -0,0 +1,8 @@
+from spam import Spam
+
+s = Spam()
+print "Created:", s
+s.set_amount(42)
+print "Amount =", s.get_amount()
+s.describe()
+s = None
diff --git a/debian/pyrex/pyrex-0.9.9/Demos/spam.pyx b/debian/pyrex/pyrex-0.9.9/Demos/spam.pyx
new file mode 100644
index 00000000..ab773378
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Demos/spam.pyx
@@ -0,0 +1,22 @@
+#
+# Example of an extension type.
+#
+
+cdef class Spam:
+
+ cdef int amount
+
+ def __cinit__(self):
+ self.amount = 0
+
+ def __dealloc__(self):
+ print self.amount, "tons of spam is history."
+
+ def get_amount(self):
+ return self.amount
+
+ def set_amount(self, new_amount):
+ self.amount = new_amount
+
+ def describe(self):
+ print self.amount, "tons of spam!"
diff --git a/debian/pyrex/pyrex-0.9.9/Doc/About.html b/debian/pyrex/pyrex-0.9.9/Doc/About.html
new file mode 100644
index 00000000..373625aa
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Doc/About.html
@@ -0,0 +1,149 @@
+<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en">
+<html><head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.51 (Macintosh; I; PPC) [Netscape]">
+ <title>About Pyrex</title></head>
+
+<body>
+
+<center>
+<h1>
+
+<hr width="100%">Pyrex</h1></center>
+
+<center><i><font size="+1">A language for writing Python extension modules</font></i>
+<hr width="100%"></center>
+
+<h2>
+What is Pyrex all about?</h2>
+Pyrex is a language specially designed for writing Python extension modules.
+It's designed to bridge the gap between the nice, high-level, easy-to-use
+world of Python and the messy, low-level world of C.
+<p>You may be wondering why anyone would want a special language for this.
+Python is really easy to extend using C or C++, isn't it? Why not just
+write your extension modules in one of those languages?
+</p><p>Well, if you've ever written an extension module for Python, you'll
+know that things are not as easy as all that. First of all, there is a
+fair bit of boilerplate code to write before you can even get off the ground.
+Then you're faced with the problem of converting between Python and C data
+types. For the basic types such as numbers and strings this is not too
+bad, but anything more elaborate and you're into picking Python objects
+apart using the Python/C API calls, which requires you to be meticulous
+about maintaining reference counts, checking for errors at every step and
+cleaning up properly if anything goes wrong. Any mistakes and you have
+a nasty crash that's very difficult to debug.
+</p><p>Various tools have been developed to ease some of the burdens of producing
+extension code, of which perhaps <a href="http://www.swig.org">SWIG</a>
+is the best known. SWIG takes a definition file consisting of a mixture
+of C code and specialised declarations, and produces an extension module.
+It writes all the boilerplate for you, and in many cases you can use it
+without knowing about the Python/C API. But you need to use API calls if
+any substantial restructuring of the data is required between Python and
+C.
+</p><p>What's more, SWIG gives you no help at all if you want to create a new
+built-in Python <i>type. </i>It will generate pure-Python classes which
+wrap (in a slightly unsafe manner) pointers to C data structures, but creation
+of true extension types is outside its scope.
+</p><p>Another notable attempt at making it easier to extend Python is <a href="http://pyinline.sourceforge.net/">PyInline</a>
+, inspired by a similar facility for Perl. PyInline lets you embed pieces
+of C code in the midst of a Python file, and automatically extracts them
+and compiles them into an extension. But it only converts the basic types
+automatically, and as with SWIG,&nbsp; it doesn't address the creation
+of new Python types.
+</p><p>Pyrex aims to go far beyond what any of these previous tools provides.
+Pyrex deals with the basic types just as easily as SWIG, but it also lets
+you write code to convert between arbitrary Python data structures and
+arbitrary C data structures, in a simple and natural way, without knowing
+<i>anything</i> about the Python/C API. That's right -- <i>nothing at all</i>!
+Nor do you have to worry about reference counting or error checking --
+it's all taken care of automatically, behind the scenes, just as it is
+in interpreted Python code. And what's more, Pyrex lets you define new
+<i>built-in</i> Python types just as easily as you can define new classes
+in Python.
+</p><p>Sound too good to be true? Read on and find out how it's done.
+</p><h2>
+The Basics of Pyrex</h2>
+The fundamental nature of Pyrex can be summed up as follows: <b>Pyrex is
+Python with C data types</b>.
+<p><i>Pyrex is Python:</i> Almost any piece of Python code is also valid
+Pyrex code. (There are a few limitations, but this approximation will serve
+for now.) The Pyrex compiler will convert it into C code which makes equivalent
+calls to the Python/C API. In this respect, Pyrex is similar to the former
+Python2C project (to which I would supply a reference except that it no
+longer seems to exist).
+</p><p><i>...with C data types.</i> But Pyrex is much more than that, because
+parameters and variables can be declared to have C data types. Code which
+manipulates Python values and C values can be freely intermixed, with conversions
+occurring automatically wherever possible. Reference count maintenance
+and error checking of Python operations is also automatic, and the full
+power of Python's exception handling facilities, including the try-except
+and try-finally statements, is available to you -- even in the midst of
+manipulating C data.
+</p><p>Here's a small example showing some of what can be done. It's a routine
+for finding prime numbers. You tell it how many primes you want, and it
+returns them as a Python list.
+</p><blockquote><b><tt><font size="+1">primes.pyx</font></tt></b></blockquote>
+
+<blockquote>
+<pre>&nbsp;1&nbsp; def primes(int kmax):<br>&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cdef int n, k, i<br>&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cdef int p[1000]<br>&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result = []<br>&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if kmax &gt; 1000:<br>&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kmax = 1000<br>&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; k = 0<br>&nbsp;8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n = 2<br>&nbsp;9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while k &lt; kmax:<br>10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i = 0<br>11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while i &lt; k and n % p[i] &lt;&gt; 0:<br>12&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i = i + 1<br>13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if i == k:<br>14&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p[k] = n<br>15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; k = k + 1<br>16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result.append(n)<br>17&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n = n + 1<br>18&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return result</pre>
+</blockquote>
+You'll see that it starts out just like a normal Python function definition,
+except that the parameter <b>kmax</b> is declared to be of type <b>int</b>
+. This means that the object passed will be converted to a C integer (or
+a TypeError will be raised if it can't be).
+<p>Lines 2 and 3 use the <b>cdef</b> statement to define some local C variables.
+Line 4 creates a Python list which will be used to return the result. You'll
+notice that this is done exactly the same way it would be in Python. Because
+the variable <b>result</b> hasn't been given a type, it is assumed to hold
+a Python object.
+</p><p>Lines 7-9 set up for a loop which will test candidate numbers for primeness
+until the required number of primes has been found. Lines 11-12, which
+try dividing a candidate by all the primes found so far, are of particular
+interest. Because no Python objects are referred to, the loop is translated
+entirely into C code, and thus runs very fast.
+</p><p>When a prime is found, lines 14-15 add it to the p array for fast access
+by the testing loop, and line 16 adds it to the result list. Again, you'll
+notice that line 16 looks very much like a Python statement, and in fact
+it is, with the twist that the C parameter <b>n</b> is automatically converted
+to a Python object before being passed to the <b>append</b> method. Finally,
+at line 18, a normal Python <b>return</b> statement returns the result
+list.
+</p><p>Compiling primes.pyx with the Pyrex compiler produces an extension module
+which we can try out in the interactive interpreter as follows:
+</p><blockquote>
+<pre>&gt;&gt;&gt; import primes<br>&gt;&gt;&gt; primes.primes(10)<br>[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]<br>&gt;&gt;&gt;</pre>
+</blockquote>
+See, it works! And if you're curious about how much work Pyrex has saved
+you, take a look at the <a href="primes.c">C code generated for this module</a>
+.
+<h2>
+Language Details</h2>
+For more about the Pyrex language, see the <a href="LanguageOverview.html">Language
+Overview</a> .
+<h2>
+Future Plans</h2>
+Pyrex is not finished. Substantial tasks remaining include:
+<ul>
+<li>
+Support for certain Python language features which are planned but not
+yet implemented. See the <a href="Manual/Limitations.html">Limitations</a>
+section of the <a href="LanguageOverview.html">Language Overview</a> for a current
+list.</li>
+</ul>
+
+<ul>
+<li>
+C++ support. This could be a very big can of worms - careful thought required
+before going there.</li>
+</ul>
+
+<ul>
+<li>
+Reading C/C++ header files directly would be very nice, but there are some
+severe problems that I will have to find solutions for first, such as what
+to do about preprocessor macros. My current thinking is to use a separate
+tool to convert .h files into Pyrex declarations, possibly with some manual
+intervention.</li>
+</ul>
+
+</body></html> \ No newline at end of file
diff --git a/debian/pyrex/pyrex-0.9.9/Doc/FAQ.html b/debian/pyrex/pyrex-0.9.9/Doc/FAQ.html
new file mode 100644
index 00000000..d55f3a6a
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Doc/FAQ.html
@@ -0,0 +1,75 @@
+<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
+<html><head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.51 (Macintosh; I; PPC) [Netscape]"><title>FAQ.html</title></head>
+<body>
+ <center> <h1> <hr width="100%">Pyrex FAQ
+<hr width="100%"></h1>
+ </center>
+ <h2> Contents</h2>
+ <ul>
+ <li> <b><a href="#CallCAPI">How do I call Python/C API routines?</a></b></li>
+ <li> <b><a href="#NullBytes">How do I convert a C string containing null
+ bytes to a Python string?</a></b></li>
+ <li> <b><a href="#NumericAccess">How do I access the data inside a Numeric
+ array object?</a></b></li>
+ <li><b><a href="#Rhubarb">Pyrex says my extension type object has no attribute
+'rhubarb', but I know it does. What gives?</a></b></li><li><a style="font-weight: bold;" href="#Quack">Python says my extension type has no method called 'quack', but I know it does. What gives?</a><br>
+ </li>
+
+ </ul>
+ <hr width="100%"> <h2> <a name="CallCAPI"></a>How do I call Python/C API routines?</h2>
+ Declare them as C functions inside a <tt>cdef extern from</tt> block.
+Use the type name <tt>object</tt> for any parameters and return types which
+are Python object references. Don't use the word <tt>const</tt> anywhere.
+Here is an example which defines and uses the <tt>PyString_FromStringAndSize</tt> routine:
+<blockquote><tt>cdef extern from "Python.h":</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp; object PyString_FromStringAndSize(char *, int)</tt> <p><tt>cdef char buf[42]</tt> <br>
+ <tt>my_string = PyString_FromStringAndSize(buf, 42)</tt></p>
+ </blockquote>
+ <h2> <a name="NullBytes"></a>How do I convert a C string containing null
+bytes to a Python string?</h2>
+ Put in a declaration for the <tt>PyString_FromStringAndSize</tt> API routine
+ and use that<tt>.</tt> See <a href="#CallCAPI">How do I call Python/C API
+ routines?</a> <h2> <a name="NumericAccess"></a>How do I access the data inside a Numeric
+ array object?</h2>
+ Use a <tt>cdef extern from</tt> block to include the Numeric header file
+ and declare the array object as an external extension type. The following
+ code illustrates how to do this:
+<blockquote><tt>cdef extern from "Numeric/arrayobject.h":</tt> <p><tt>&nbsp;&nbsp;&nbsp; struct PyArray_Descr:</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int type_num, elsize</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char type</tt> </p>
+ <p><tt>&nbsp;&nbsp;&nbsp; ctypedef class Numeric.ArrayType [object PyArrayObject]</tt><tt>:</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cdef char *data</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cdef int nd</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cdef int *dimensions,
+*strides</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cdef object base</tt>
+ <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cdef PyArray_Descr *descr</tt> <br>
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cdef int flags<br>
+ </tt></p>
+</blockquote>
+<p>For more information about external extension types, see the <a href="extension_types.html#ExternalExtTypes">"External Extension Types"</a>
+section of the <a href="extension_types.html">"Extension Types"</a> documentation
+page.<br>
+<tt> </tt> </p>
+ <h2><a name="Rhubarb"></a>Pyrex says my extension type object has no attribute
+'rhubarb', but I know it does. What gives?</h2>
+You're probably trying to access it through a reference which Pyrex thinks
+is a generic Python object. You need to tell Pyrex that it's a reference
+to your extension type by means of a declaration. For example,<br>
+<blockquote><tt>cdef class Vegetables:</tt><br>
+ <tt>&nbsp; &nbsp; cdef int rhubarb</tt><br>
+ <br>
+ <tt>...</tt><br>
+ <tt>cdef Vegetables veg</tt><br>
+ <tt>veg.rhubarb = 42</tt><br>
+</blockquote>
+Also see the <a href="Manual/extension_types.html#ExtTypeAttrs">"Attributes"</a>
+section of the <a href="Manual/extension_types.html">"Extension
+Types"</a> documentation page.<br>
+<h2><a name="Quack"></a>Python says my extension type has no method called 'quack', but I know it does. What gives?</h2>
+You may have declared the method using <span style="font-family: monospace;">cdef</span> instead of <span style="font-family: monospace;">def</span>. Only functions and methods declared with <span style="font-family: monospace;">def</span> are callable from Python code.<br><br>
+---
+</body></html> \ No newline at end of file
diff --git a/debian/pyrex/pyrex-0.9.9/Doc/LanguageOverview.html b/debian/pyrex/pyrex-0.9.9/Doc/LanguageOverview.html
new file mode 100644
index 00000000..17722e55
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Doc/LanguageOverview.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"><title>Pyrex Language Overview</title></head>
+<body>
+
+
+<h1>
+<hr width="100%">Overview of the Pyrex Language&nbsp;
+<hr width="100%"></h1>
+
+
+ This is a combined tutorial and reference manual that describes the extensions to the Python language
+ made by Pyrex.<h2> Contents</h2>
+
+
+
+<ul><li><a href="Manual/source_files.html">Source Files and Compilation</a> <span style="color: rgb(0, 153, 0);">(Section added in 0.9.5)</span><br>
+ </li><li><a href="Manual/basics.html">Language Basics</a></li><li> <a href="Manual/external.html">Interfacing with External C Code</a></li><li> <a href="Manual/extension_types.html">Extension Types</a></li><li><a href="Manual/special_methods.html">Special Methods of Extension Types</a></li><li> <a href="Manual/sharing.html">Sharing Declarations Between Pyrex Modules</a></li><li><a href="Manual/using_with_c++.html">Using Pyrex with C++</a></li><li> <a href="Manual/Limitations.html">Limitations</a></li></ul>---</body></html> \ No newline at end of file
diff --git a/debian/pyrex/pyrex-0.9.9/Doc/Manual/Limitations.html b/debian/pyrex/pyrex-0.9.9/Doc/Manual/Limitations.html
new file mode 100644
index 00000000..74131730
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Doc/Manual/Limitations.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"><title>Limitations</title></head>
+<body><h1><hr width="100%">
+<a name="Limitations"></a>Limitations <hr width="100%"></h1><h2> <a name="Unsupported"></a>Unsupported
+Python features</h2>
+Pyrex is not quite a full superset of Python. The following
+restrictions apply: <blockquote> <li> Function
+definitions (whether using <b>def</b> or <b>cdef</b>)
+cannot be nested within other function definitions.<br> </li>
+&nbsp; <li> Class definitions can only appear at the top
+level of a module, not inside a function.<br> </li>
+&nbsp; <li> The<tt> import *</tt> form of import
+is not allowed anywhere (other forms of the import statement are fine,
+though).<br> </li> &nbsp; <li> Generators
+cannot be defined in Pyrex.<br> <br> </li> <li>
+The <tt>globals()</tt> and <tt>locals()</tt>
+functions cannot be used.</li> </blockquote> The above
+restrictions will most likely remain, since removing them would be
+difficult and they're not really needed for Pyrex's intended
+applications. <p>There are also some temporary limitations,
+which may eventually be lifted, including: </p> <blockquote>
+<li> Class and function definitions cannot be placed inside
+control structures.<br> </li> &nbsp; <li> List comprehensions are not yet
+supported.<br> </li> &nbsp; <li> There is no
+support for Unicode.<br> </li> &nbsp; <li>
+Special methods of extension types cannot have functioning
+docstrings.<br> <br> </li> <li> The use of
+string literals as comments is not recommended at present, because they are not accepted in
+places where executable statements are not allowed.</li></blockquote><hr style="width: 100%; height: 2px;"><h2><a name="SemanticDifferences"></a>Semantic
+differences between Python and Pyrex</h2> <h3> Behaviour
+of class scopes</h3> In Python, referring to a method of a class
+inside the class definition, i.e. while the class is being defined,
+yields a plain function object, but in Pyrex it yields an unbound method<sup><font size="-2"><a href="#Footnote1">1</a></font></sup>.
+A consequence of this is that the
+usual idiom for using the classmethod and staticmethod functions, e.g. <blockquote>
+<pre>class Spam:</pre> <pre>&nbsp; def method(cls):<br>&nbsp;&nbsp;&nbsp; ...</pre><pre>&nbsp; method = classmethod(method)</pre>
+</blockquote>
+will not work in Pyrex. This can be worked around by defining the
+function <i>outside</i> the class, and then assigning the
+result of classmethod or staticmethod inside the class, i.e. <blockquote>
+<pre>def Spam_method(cls):<br>&nbsp; ...</pre> <pre>class Spam:</pre><pre>&nbsp; method = classmethod(Spam_method)</pre>
+</blockquote> <hr width="100%"><span style="font-weight: bold;">Footnotes</span><br><hr style="width: 100%; height: 2px;"><a name="Footnote1"></a>1.
+The reason for the different
+behaviour
+of class scopes is that Pyrex-defined Python functions are PyCFunction
+objects,
+not PyFunction objects, and are not recognised by the machinery that
+creates
+a bound or unbound method when a function is extracted from a class. To
+get
+around this, Pyrex wraps each method in an unbound method object itself
+before
+storing it in the class's dictionary.<br><br>--- </body></html> \ No newline at end of file
diff --git a/debian/pyrex/pyrex-0.9.9/Doc/Manual/basics.html b/debian/pyrex/pyrex-0.9.9/Doc/Manual/basics.html
new file mode 100644
index 00000000..132c2899
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Doc/Manual/basics.html
@@ -0,0 +1,1118 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html><head>
+<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"><title>Language Basics</title>
+
+</head>
+<body>
+<h1>
+<hr style="width: 100%; height: 2px;">Language
+Basics
+<hr width="100%"></h1>
+<ul id="mozToc">
+<!--mozToc h2 1 h3 2--><li><a href="#mozTocId641350">Python
+functions vs. C functions</a></li>
+<li><a href="#mozTocId972536">Python objects as
+parameters
+and return values</a></li>
+<li><a href="#mozTocId155104">C
+variable and type definitions</a>
+<ul>
+<li><a href="#mozTocId890190">Forward
+Declarations</a></li>
+<li><a href="#mozTocId522210">Grouping
+multiple C declarations</a></li>
+</ul>
+</li>
+<li><a href="#mozTocId763321">Automatic
+type conversions</a>
+<ul>
+<li><a href="#mozTocId440941">Caveats
+when using a Python string in a C context</a></li>
+</ul>
+</li>
+<li><a href="#mozTocId834148">Scope rules</a></li>
+<li><a href="#mozTocId954330">Statements and
+expressions</a>
+<ul>
+<li><a href="#mozTocId401576">Differences
+between C
+and Pyrex
+expressions</a></li>
+<li><a href="#mozTocId899067">Integer for-loops</a></li>
+<li><a href="#mozTocId457396">Catching
+exceptions and tracebacks</a></li>
+</ul>
+</li>
+<li><a href="#mozTocId482761">Error return values</a>
+<ul>
+<li><a href="#mozTocId622828">Checking
+return values of non-Pyrex functions</a></li>
+</ul>
+</li>
+<li><a href="#mozTocId494354">The include
+statement</a></li>
+<li><a href="#mozTocId849661">Keyword-only
+arguments</a></li>
+<li><a href="#mozTocId829237">Built-in Names</a>
+<ul>
+<li><a href="#mozTocId813519">Built-in
+Constants</a></li>
+<li><a href="#mozTocId593628">Built-in
+Functions</a></li>
+<li><a href="#mozTocId452377">Built-in Types</a></li>
+</ul>
+</li>
+<li><a href="#mozTocId42018">Conditional
+Compilation</a>
+<ul>
+<li><a href="#mozTocId379306">Compile-Time
+Definitions</a></li>
+<li><a href="#mozTocId997015">Conditional
+Statements</a></li>
+</ul>
+</li>
+</ul>
+This
+section describes the basic features of the Pyrex language. The
+facilities covered in this section allow you to create Python-callable
+functions that manipulate C data structures and convert between Python
+and C data types. Later sections will cover facilities for <a href="external.html">wrapping external C code</a>, <a href="extension_types.html">creating new Python types</a>
+and <a href="sharing.html">cooperation between Pyrex
+modules</a>.<br>
+<h2><a class="mozTocH2" name="mozTocId641350"></a>
+<a name="PyFuncsVsCFuncs"></a>Python
+functions vs. C functions</h2>
+There are two kinds of function
+definition in Pyrex:
+<p><b>Python functions</b> are
+defined using the <b>def</b> statement, as in Python. They
+take Python objects as parameters and return Python objects. </p>
+<p><b>C functions</b> are defined using the new <b>cdef</b>
+statement. They take either Python objects or C values as parameters,
+and can return either Python objects or C values. </p>
+<p>Within
+a Pyrex module, Python functions and C functions can call each other
+freely, but only Python functions can be called from outside the module
+by
+interpreted Python code. So, any functions that you want to "export"
+from your Pyrex module must be declared as Python functions using <span style="font-weight: bold;">def</span>. </p>
+<p>Parameters
+of either type of function can be declared to have C data types, using
+normal C declaration syntax. For example, </p>
+<blockquote>
+<pre>def spam(int i, char *s):<br>&nbsp;&nbsp;&nbsp; ...</pre>
+<pre>cdef int eggs(unsigned long l, float f):<br>&nbsp;&nbsp;&nbsp; ...</pre>
+</blockquote>
+When
+a parameter of a Python function is declared
+to have a C data type, it is passed in as a Python object and
+automatically converted to a C value, if possible. Automatic conversion
+is currently only possible for numeric types and string types;
+attempting to use any other type for the parameter of a Python function
+will result in a compile-time error.
+<p>C functions, on the
+other hand, can have parameters of any type, since they're passed in
+directly using a normal C function call. </p>
+<h2><a class="mozTocH2" name="mozTocId972536"></a>
+<a name="PyObjParams"></a>Python objects as
+parameters
+and return values</h2>
+If no type is specified for a parameter or
+return value, <i>it is assumed to be a Python object.</i>
+(Note that this is different from the C convention, where it would
+default to <tt>int</tt>.) For example, the following
+defines a C function that takes two Python objects as parameters and
+returns a Python object:
+<blockquote>
+<pre>cdef spamobjs(x, y):<br>&nbsp;&nbsp;&nbsp; ...</pre>
+</blockquote>
+Reference counting for these objects is performed
+automatically according to the standard Python/C API rules (i.e.
+borrowed references are taken as parameters and a new reference is
+returned).
+<p>The name <b>object</b> can also be
+used to explicitly declare something as a Python object. This can be
+useful if the name being declared would otherwise
+be taken as the name of a type, for example, </p>
+<blockquote>
+<pre>cdef ftang(object int):<br>&nbsp;&nbsp;&nbsp; ...</pre>
+</blockquote>
+declares
+a parameter called <tt>int</tt>
+which is a Python object. You can also use <b>object </b>as
+the explicit return type of a function, e.g.
+<blockquote>
+<pre>cdef object ftang(object int):<br>&nbsp;&nbsp;&nbsp; ...</pre>
+</blockquote>
+In the interests of clarity, it is probably a good
+idea to always be explicit about <b>object </b>parameters
+in C functions.
+<h2><a class="mozTocH2" name="mozTocId155104"></a><a name="CVarAndTypeDecls"></a>C
+variable and type definitions</h2>
+The <b>cdef</b>
+statement is also used to declare C variables, either
+local or module-level:
+<blockquote>
+<pre>cdef int i, j, k<br>cdef float f, g[42], *h</pre>
+</blockquote>
+and C struct, union or enum types:
+<blockquote>
+<pre>cdef struct Grail:<br>&nbsp;&nbsp;&nbsp; int age<br>&nbsp;&nbsp;&nbsp; float volume</pre>
+<pre>cdef union Food:<br>&nbsp;&nbsp;&nbsp; char *spam<br>&nbsp;&nbsp;&nbsp; float *eggs</pre>
+<pre>cdef enum CheeseType:<br>&nbsp;&nbsp;&nbsp; cheddar, edam,&nbsp;<br>&nbsp;&nbsp;&nbsp; camembert</pre>
+<pre>cdef enum CheeseState:<br>&nbsp;&nbsp;&nbsp; hard = 1<br>&nbsp;&nbsp;&nbsp; soft = 2<br>&nbsp;&nbsp;&nbsp; runny = 3</pre>
+</blockquote>
+There is currently no special syntax for defining a
+constant, but you
+can use an anonymous enum declaration for this purpose, for example,
+<blockquote><tt>cdef
+enum:</tt> <br>
+<tt>&nbsp;&nbsp;&nbsp;
+tons_of_spam = 3</tt></blockquote>
+Note that the words <span style="font-family: monospace;">struct</span>,
+<span style="font-family: monospace;">union</span>
+and <span style="font-family: monospace;">enum</span>
+are used
+only when <i>defining</i> a type, not when referring to
+it. For example, to declare a variable pointing to a Grail you would
+write
+<blockquote>
+<pre>cdef Grail *gp</pre>
+</blockquote>
+and <i>not</i>
+<blockquote>
+<pre>cdef struct Grail *gp <font color="#ed181e"># WRONG</font></pre>
+</blockquote>
+There is also a <b>ctypedef</b> statement for giving names
+to types, e.g.
+<blockquote>
+<pre>ctypedef unsigned long ULong</pre>
+<pre>ctypedef int *IntPtr<br></pre>
+</blockquote>
+<h3><a class="mozTocH2" name="mozTocId890190"></a>Forward
+Declarations</h3>
+If
+you have two struct or union types containing pointers that refer to
+each other, you will need to use a forward declaration for at least one
+of them. This is simply the header of a struct or union without the
+colon or body, for example,<br>
+<br>
+<div style="margin-left: 40px;"><span style="font-family: monospace;">cdef struct Sandwich</span><br style="font-family: monospace;">
+<br style="font-family: monospace;">
+<span style="font-family: monospace;">cdef struct Lunchbox:</span><br style="font-family: monospace;">
+<div style="margin-left: 40px;"><span style="font-family: monospace;">Sandwich *lunch</span><br style="font-family: monospace;">
+</div>
+<br style="font-family: monospace;">
+<span style="font-family: monospace;">cdef struct Sandwich:</span><br style="font-family: monospace;">
+<div style="margin-left: 40px;"><span style="font-family: monospace;">Lunchbox *container</span><br>
+</div>
+</div>
+<br>
+You
+can also forward-declare C functions, but there should be little need
+to do this. Pyrex processes all declarations in a module before
+analysing any executable statements, so calling a function defined
+further down in the source file is usually not a problem.
+<h3><a class="mozTocH2" name="mozTocId522210"></a><a name="Grouping_multiple_C_declarations"></a>Grouping
+multiple C declarations</h3>
+If you have a series of declarations that all begin with <span style="font-family: monospace;">cdef</span>, you can
+group them into a cdef block like this:<br>
+<pre style="margin-left: 40px;">cdef:<br><br> struct Spam:<br> int tons<br><br> int i<br> float f<br> Spam *p<br><br> void f(Spam *s):<br> print s.tons, "Tons of spam"<br> </pre>
+<h2><a class="mozTocH2" name="mozTocId763321"></a><a name="AutomaticTypeConversions"></a>Automatic
+type conversions</h2>
+In most situations, automatic conversions will be performed for the
+basic numeric and string types when a Python object is used in a
+context requiring a C value, or vice versa. The following table
+summarises the conversion possibilities.<br>
+<br>
+<table style="text-align: left; background-color: rgb(204, 255, 255); width: 10%; margin-left: 40px;" border="1" cellpadding="4" cellspacing="0">
+<tbody>
+<tr>
+<th style="vertical-align: top; width: 40%; white-space: nowrap; background-color: rgb(255, 204, 51);">C
+types<br>
+</th>
+<th style="vertical-align: top; width: 150px; white-space: nowrap; background-color: rgb(255, 204, 51);">From
+Python types<br>
+</th>
+<th style="vertical-align: top; width: 150px; white-space: nowrap; background-color: rgb(255, 204, 51);">To
+Python types<br>
+</th>
+</tr>
+<tr>
+<td colspan="1" rowspan="1" style="vertical-align: top; width: 40%; white-space: nowrap;">[unsigned]
+char<br>
+[unsigned] short<br>
+int, long</td>
+<td colspan="1" rowspan="1" style="vertical-align: top; width: 150px; white-space: nowrap;">int,
+long<br>
+</td>
+<td colspan="1" rowspan="1" style="vertical-align: top; width: 150px; white-space: nowrap;">int<br>
+</td>
+</tr>
+<tr>
+</tr>
+<tr>
+<td colspan="1" rowspan="1" style="vertical-align: top; width: 40%; white-space: nowrap;">unsigned
+int<br>
+unsigned long<br>
+[unsigned] long long<br>
+</td>
+<td colspan="1" rowspan="1" style="vertical-align: top; white-space: nowrap;">int, long<br>
+<br>
+</td>
+<td colspan="1" rowspan="1" style="vertical-align: top; white-space: nowrap;">long<br>
+<br>
+</td>
+</tr>
+<tr>
+</tr>
+<tr>
+<td style="vertical-align: top; width: 40%; white-space: nowrap;">float,
+double, long double<br>
+</td>
+<td style="vertical-align: top; width: 150px; white-space: nowrap;">int,
+long, float<br>
+</td>
+<td style="vertical-align: top; width: 150px; white-space: nowrap;">float<br>
+</td>
+</tr>
+<tr>
+<td style="vertical-align: top; width: 40%; white-space: nowrap;">char
+*<br>
+</td>
+<td style="vertical-align: top; width: 150px; white-space: nowrap;">str<span style="font-style: italic;"></span><br>
+</td>
+<td style="vertical-align: top; width: 150px; white-space: nowrap;">str<br>
+</td>
+</tr>
+</tbody>
+</table>
+<br>
+<h3><a class="mozTocH3" name="mozTocId440941"></a><a name="PyToCStringCaveats"></a>Caveats
+when using a Python string in a C context</h3>
+You need to be careful when using a Python string in a context
+expecting a <span style="font-family: monospace;">char *</span>.
+In this situation, a pointer to the contents of the Python string is
+used, which is only valid as long as the Python string exists. So you
+need to make sure that a reference to the original Python string is
+held for as long as the C string is needed. If you can't guarantee that
+the Python string will live long enough, you will need to copy the C
+string.<br>
+<br>
+Pyrex detects and prevents <span style="font-style: italic;">some</span>
+mistakes of
+this kind. For instance, if you attempt something like<br>
+<pre style="margin-left: 40px;">cdef char *s<br>s = pystring1 + pystring2</pre>
+then
+Pyrex will produce the error message "<span style="font-weight: bold;">Obtaining char * from temporary
+Python value</span>".
+The reason is that concatenating the two Python strings produces a new
+Python string object that is referenced only by a temporary internal
+variable that Pyrex generates. As soon as the statement has finished,
+the temporary variable will be decrefed and the Python string
+deallocated, leaving <span style="font-family: monospace;">s</span>
+dangling. Since this code could not possibly work, Pyrex refuses to
+compile it.<br>
+<br>
+The solution is to assign the result of the concatenation to
+a Python variable, and then obtain the char * from that, i.e.<br>
+<pre style="margin-left: 40px;">cdef char *s<br>p = pystring1 + pystring2<br>s = p<br></pre>
+It
+is then your responsibility to hold the reference <span style="font-family: monospace;">p</span> for as long
+as necessary.<br>
+<br>
+Keep in mind that the rules used to detect such errors are
+only
+heuristics. Sometimes Pyrex will complain unnecessarily, and sometimes
+it will fail to detect a problem that exists. Ultimately, you need to
+understand the issue and be careful what you do.
+<h2><a class="mozTocH2" name="mozTocId834148"></a><a name="ScopeRules"></a>Scope rules</h2>
+Pyrex
+determines whether a variable belongs to a local scope, the module
+scope, or the built-in scope <i>completely statically.</i>
+As with Python, assigning to a variable which is not otherwise declared
+implicitly declares it to be a Python variable residing in the scope
+where it is assigned. Unlike Python, however, a name which is referred
+to but not declared or assigned is assumed to reside in the <i>builtin
+scope, </i>not the module scope.
+Names added to the module dictionary at run time will not shadow such
+names.<br>
+<br>
+This can result in some odd things happening under rare circumstances,
+for example<br>
+<br>
+<div style="margin-left: 40px;"><tt>print __name__</tt></div>
+<p>In
+Pyrex, instead of printing the name of the current module, this prints
+the name of the builtins module. The reason is that because Pyrex
+hasn't seen a declaration of anything called <span style="font-family: monospace;">__name__</span> in the
+module, it's assumed to reside in the builtins. The solution is to use
+a <span style="font-weight: bold;">global</span>
+statement to declare <span style="font-family: monospace;">__name__</span>
+as a module-level name:</p>
+<p style="margin-left: 40px;"><tt>global
+__name__</tt><tt><br>
+print __name__</tt></p>
+Another
+consequence of these rules is that the module-level scope behaves the
+same way as a Python local scope if you refer to a variable before
+assigning to it. In particular, tricks such as the following will <i>not</i>
+work
+in Pyrex:<br>
+<blockquote>
+<pre>try:<br>&nbsp; x = True<br>except NameError:<br>&nbsp; True = 1<br></pre>
+</blockquote>
+because, due to the assignment in the last line, <span style="font-family: monospace;">True</span> will
+always be looked up in the module-level scope. You would have to do
+something like this instead:<br>
+<blockquote>
+<pre>import __builtin__<br>try:<br> True = __builtin__.True<br>except AttributeError:<br> True = 1<br></pre>
+</blockquote>
+<hr width="100%">
+<h2><a class="mozTocH2" name="mozTocId954330"></a><a name="StatsAndExprs"></a>Statements and
+expressions</h2>
+Control structures and expressions follow Python syntax for the most
+part. When applied to Python objects, they have the same semantics as
+in Python (unless otherwise noted). Most of the Python operators can
+also be applied to C values, with the obvious semantics.
+<p>If
+Python objects and C values are mixed in an expression, conversions are
+performed automatically between Python objects and C numeric or string
+types. </p>
+<p>Reference counts are maintained
+automatically for all Python objects, and
+all Python operations are automatically checked for errors, with
+appropriate action taken. </p>
+<h3><a class="mozTocH3" name="mozTocId401576"></a>
+<a name="ExprSyntaxDifferences"></a>Differences
+between C
+and Pyrex
+expressions</h3>
+There
+are some differences in syntax and semantics between C expressions and
+Pyrex expressions, particularly in the area of C constructs which have
+no direct equivalent in Python.<br>
+<ul>
+<li>An integer literal without an <span style="font-family: monospace; font-weight: bold;">L</span>
+suffix is treated as a C constant, and will be truncated to whatever
+size your C compiler thinks appropriate. With an <span style="font-family: monospace; font-weight: bold;">L</span>
+suffix, it will be converted to Python long integer (even if it would
+be small enough to fit into a C int).<br>
+<br>
+</li>
+<li>There is no <b><tt>-&gt;</tt></b>
+operator
+in Pyrex. Instead of <tt>p-&gt;x</tt>, use <tt>p.x</tt></li>
+&nbsp; <li> There is no <b><tt>*</tt></b>
+operator in Pyrex. Instead of <tt>*p</tt>, use <tt>p[0]</tt></li>
+&nbsp; <li> There is an <b><tt>&amp;</tt></b>
+operator, with the same semantics as in C.</li>
+&nbsp; <li>
+The null C pointer is called <b><tt>NULL</tt></b>,
+not 0 (and <tt>NULL</tt> is a reserved word).</li>
+&nbsp; <li> Character literals are written with a <b>c</b>
+prefix, for
+example:</li>
+<ul>
+<pre>c'X'</pre>
+</ul>
+<li>Type casts are written <b><tt>&lt;type&gt;value</tt></b>
+, for example:</li>
+<ul>
+<pre>cdef char *p, float *q<br>p = &lt;char*&gt;q</pre>
+</ul>
+<i><b>Warning</b>:
+Don't attempt to use a typecast to convert between
+Python and C data types -- it won't do the right thing. Leave Pyrex to
+perform the conversion automatically.</i>
+</ul>
+<h4>Operator Precedence</h4>
+Keep in mind that there are
+some differences
+in operator precedence between Python and C, and that Pyrex uses the
+Python precedences, not the C ones.
+<h3><a class="mozTocH3" name="mozTocId899067"></a>Integer
+for-loops</h3>
+You should be aware that a for-loop such as
+<blockquote><tt>for
+i in range(n):</tt> <br>
+<tt>&nbsp;&nbsp;&nbsp;
+...</tt></blockquote>
+won't be very fast, even if <tt>i</tt>
+and <tt>n</tt> are declared as
+C integers, because <tt>range</tt> is a Python function.
+For iterating over ranges of integers, Pyrex has another form of
+for-loop:
+<blockquote><tt>for 0 &lt;= i
+&lt; n:</tt> <br>
+<tt>&nbsp;&nbsp;&nbsp;
+...</tt></blockquote>
+Provided the loop variable and the lower
+and upper bounds are all C integers, this form of loop will be much
+faster, because Pyrex will translate it into pure C code.
+<p>Some
+things to note about the integer for-loop: </p>
+<ul>
+<li> The target expression (the middle one) must be a variable
+name.</li>
+<li>The direction of iteration is
+determined by the relations. If they are both from the set {<tt>&lt;</tt>,
+<tt>&lt;=</tt>} then it is upwards; if they are
+both
+from the set {<tt>&gt;</tt>, <tt>&gt;=</tt>}
+then it is
+downwards. (Any other combination is disallowed.)</li>
+</ul>
+Like other Python looping statements, <tt>break</tt> and <tt>continue</tt>
+may be used in the body, and the loop may have an <tt>else</tt>
+clause.
+<h3><a class="mozTocH3" name="mozTocId457396"></a>Catching
+exceptions and tracebacks</h3>
+For
+reasons of efficiency, there are some differences between Pyrex and
+Python concerning the way exceptions caught by a try-except statement
+are handled.<br>
+<ul>
+<li>Exceptions caught by an <span style="font-family: monospace;">except</span> clause <span style="font-style: italic;">cannot</span> be retrieved
+using <span style="font-family: monospace;">sys.exc_info()</span>.
+To access the caught exception, you must bind it to a name in the
+except clause.<br><br>Pyrex also allows an additional name to be provided for
+catching the traceback. For example,</li>
+</ul>
+<pre style="margin-left: 80px;">try:<br>&nbsp;&nbsp;&nbsp; start_engine()<br>except HovercraftError, e, tb:<br>&nbsp;&nbsp;&nbsp; print "Got an error:", e<br>&nbsp;&nbsp;&nbsp; traceback.print_tb(tb)</pre>
+<ul>
+<li>A <span style="font-family: monospace;">raise</span>
+statement with no arguments (to re-raise the last exception caught)
+must be lexically enclosed in the <span style="font-family: monospace;">except</span> clause
+which caught the exception. A raise statement in a Python function
+called from the except clause will <span style="font-style: italic;">not</span>
+work.</li>
+</ul>
+<pre style="margin-left: 80px;">try:<br> start_engine()<br>except HovercraftError, e:<br> print "Unable to start:", e<br> raise # the exception caught by the enclosing except clause</pre>
+<h2><a class="mozTocH2" name="mozTocId329136"></a>
+<hr width="100%"></h2>
+<h2><a class="mozTocH2" name="mozTocId482761"></a><a name="ExceptionValues"></a>Error return values</h2>
+If you don't do anything special, a function declared with <b>cdef</b>
+that does not return a Python object has no way of reporting Python
+exceptions to its caller. If an exception is detected in such a
+function, a warning message is printed and the exception is ignored.
+<p>If
+you want a C function that does not return a Python object to be able
+to propagate exceptions to its caller, you need to declare an <b>exception
+value</b> for it. Here is an example: </p>
+<blockquote><tt>cdef
+int spam() except -1:</tt> <br>
+<tt>&nbsp;&nbsp;&nbsp;
+...</tt></blockquote>
+With this declaration, whenever an
+exception occurs inside <tt>spam</tt>, it will immediately
+return with the value <tt>-1</tt>. Furthermore, whenever a
+call to <tt>spam</tt> returns <tt>-1</tt>, an
+exception will be assumed to have occurred and will be propagated.
+<p>When
+you declare an exception value for a function, you should never
+explicitly return that value. If all possible return values are legal
+and you can't
+reserve one entirely for signalling errors, you can use an alternative
+form
+of exception value declaration: </p>
+<blockquote><tt>cdef
+int spam() except? -1:</tt> <br>
+<tt>&nbsp;&nbsp;&nbsp;
+...</tt></blockquote>
+The "?" indicates that the value <tt>-1</tt>
+only indicates a <i>possible</i> error. In this case,
+Pyrex generates a call to <tt>PyErr_Occurred</tt> if the
+exception value is returned, to make sure it really is an error.
+<p>There
+is also a third form of exception value declaration: </p>
+<blockquote><tt>cdef
+int spam() except *:</tt> <br>
+<tt>&nbsp;&nbsp;&nbsp;
+...</tt></blockquote>
+This form causes Pyrex to generate a
+call to <tt>PyErr_Occurred</tt> after <i>every</i>
+call to <code>spam</code>, regardless of what value it
+returns. If you have a function returning <tt>void</tt>
+that needs to propagate errors, you will have to use this form, since
+there isn't any return value to test.
+<p>Some things to note: </p>
+<ul>
+<li>Exception values can only declared for functions
+returning an integer, enum, float or pointer type, and the value must
+be a constant expression. The only possible pointer exception value is <tt>NULL</tt>.
+Void functions can only use the <tt>except *</tt> form.</li>
+&nbsp; <li> The exception value specification is part of the
+signature
+of the function. If you're passing a pointer to a function as a
+parameter
+or assigning it to a variable, the declared type of the parameter or
+variable must have the same exception value specification (or lack
+thereof). Here
+is an example of a pointer-to-function declaration with an exception
+value:</li>
+<ul>
+<pre><tt>int (*grail)(int, char *) except -1</tt></pre>
+</ul>
+<li>You don't need to (and shouldn't) declare exception values
+for
+functions which return Python objects. Remember that a function with no
+declared return type implicitly returns a Python object.</li>
+</ul>
+<h3><a class="mozTocH3" name="mozTocId622828"></a>
+<a name="CheckingReturnValues"></a>Checking
+return values of non-Pyrex functions</h3>
+It's important to
+understand that the <tt>except</tt> clause does <i>not</i>
+cause an error to be <i>raised</i> when the specified
+value is returned. For
+example, you can't write something like
+<blockquote>
+<pre>cdef extern FILE *fopen(char *filename, char *mode) except NULL <font color="#ed181e"># WRONG!</font></pre>
+</blockquote>
+and expect an exception to be automatically raised if a call to fopen
+returns NULL. The except clause doesn't work that way; its only purpose
+is for <i>propagating</i> exceptions that have already
+been raised, either
+by a Pyrex function or a C function that calls Python/C API routines.
+To
+get an exception from a non-Python-aware function such as fopen, you
+will
+have to check the return value and raise it yourself, for example,
+<blockquote>
+<pre>cdef FILE *p<br>p = fopen("spam.txt", "r")<br>if p == NULL:<br>&nbsp;&nbsp;&nbsp; raise SpamError("Couldn't open the spam file")</pre>
+</blockquote>
+<h4>
+<hr width="100%"></h4>
+<h2><a class="mozTocH2" name="mozTocId494354"></a>
+<a name="IncludeStatement"></a>The <tt>include</tt>
+statement</h2>
+A&nbsp;Pyrex source file can include material from other files
+using the <b>include</b>
+statement, for example
+<blockquote>
+<pre>include "spamstuff.pxi"</pre>
+</blockquote>
+The contents of the named file are textually
+included at that point. The included file can contain any complete
+statements or declarations that are valid in the context where the
+include statement appears, including other <b>include</b>
+statements. The contents of the included file should begin at an
+indentation level of zero, and will be treated as though they were
+indented to the level of the include statement that is including the
+file.<br>
+<br>
+Note
+that there are other mechanisms available for splitting Pyrex code into
+separate parts that may be more appropriate in many cases. See<a href="sharing.html"> Sharing Declarations Between
+Pyrex Modules</a>.<br>
+<hr style="width: 100%; height: 2px;">
+<h2><a class="mozTocH2" name="mozTocId849661"></a><a name="KeywordOnlyArguments"></a>Keyword-only arguments</h2>
+<p>Python
+functions can have keyword-only arguments listed after the * parameter
+and before the ** paramter if any, e.g.</p>
+<pre style="margin-left: 40px;">def f(a, b, *args, c, d = 42, e, **kwds):<br> ...<br></pre>
+Here
+c, d and e cannot be passed as position arguments and must be passed as
+keyword arguments. Furthermore, c and e are required keyword arguments,
+since they do not have a default value.<br>
+<br>
+If the
+parameter name after the * is omitted, the function will not accept any
+extra positional arguments, e.g.<br>
+<br>
+<pre style="margin-left: 40px;">def g(a, b, *, c, d):<br> ...<br></pre>
+takes
+exactly two positional parameters and has two required keyword
+parameters.<br>
+<br>
+<hr style="width: 100%; height: 2px;">
+<h2><a class="mozTocH2" name="mozTocId829237"></a><a name="Built-in_Names"></a>Built-in Names</h2>
+Pyrex
+knows about many of the names in the builtin namespace, and treats them
+specially in the interests of generating efficient code.<br>
+<h3><a class="mozTocH3" name="mozTocId813519"></a><a name="Built-in_Constants"></a>Built-in Constants</h3>
+Pyrex
+knows the following built-in constant and type names, and references
+their values directly instead of using a dictionary lookup.<br>
+<br>
+<table style="background-color: rgb(204, 255, 255); width: 10px; margin-left: 40px;" border="1" cellpadding="5" cellspacing="0">
+<tbody>
+<tr>
+<td style="vertical-align: top; white-space: nowrap; text-align: left; background-color: rgb(255, 204, 0);">Type
+objects (type <span style="font-family: monospace;">type</span>)</td>
+<td colspan="2" rowspan="1" style="vertical-align: top; white-space: nowrap; text-align: left; background-color: rgb(255, 204, 0);">Exceptions
+(type <span style="font-family: monospace;">type</span>)</td>
+</tr>
+<tr>
+<td style="vertical-align: top; white-space: nowrap; text-align: left; height: 10px;">buffer<br>
+enumerate<br>
+file<br>
+float<br>
+int<br>
+long<br>
+open<br>
+property<br>
+str<br>
+tuple<br>
+xrange</td>
+<td colspan="1" rowspan="3" align="left" nowrap="nowrap" valign="top">Exception<br>
+StopIteration<br>
+StandardError<br>
+ArithmeticError<br>
+LookupError<br>
+AsssertionError<br>
+EOFError<br>
+FloatingPointError<br>
+EnvironmentError<br>
+IOError<br>
+OSError<br>
+ImportError<br>
+IndexError<br>
+KeyError<br>
+KeyboardInterrupt<br>
+MemoryError<br>
+NameError<br>
+OverflowError<br>
+RuntimeError<br>
+NotImplementedError<br>
+SyntaxError</td>
+<td colspan="1" rowspan="3" style="vertical-align: top; white-space: nowrap; text-align: left;">IndentationError<br>
+TabError<br>
+ReferenceError<br>
+SystemError<br>
+SystemExit<br>
+TypeError<br>
+UnboundLocalError<br>
+UnicodeError<br>
+UnicodeEncodeError<br>
+UnicodeDecodeError<br>
+UnicodeTranslateError<br>
+ValueError<br>
+ZeroDivisionError<br>
+Warning<br>
+UserWarning<br>
+DeprecationWarning<br>
+PendingDeprecationWarning<br>
+SyntaxWarning<br>
+OverflowWarning<br>
+RuntimeWarning<br>
+FutureWarning</td>
+</tr>
+<tr>
+<td style="vertical-align: top; white-space: nowrap; text-align: left; height: 10px; background-color: rgb(255, 204, 0);">Constants
+(type <span style="font-family: monospace;">object</span>)</td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">True<br>
+False<br>
+Ellipsis</td>
+</tr>
+<tr>
+</tr>
+<tr>
+</tr>
+<tr>
+</tr>
+<tr>
+</tr>
+<tr>
+</tr>
+<tr>
+</tr>
+<tr>
+</tr>
+<tr>
+</tr>
+<tr>
+</tr>
+<tr>
+</tr>
+<tr>
+</tr>
+<tr>
+</tr>
+</tbody>
+</table>
+<br>
+Note that although some of the above names refer to type objects, they
+are not Pyrex type names and therefore can't be used to declare the
+type of a variable. Only the names listed under Built-in Types below
+can be used as type names in declarations.<br>
+<h3><a class="mozTocH3" name="mozTocId593628"></a><a name="Built-in_Functions"></a>Built-in Functions</h3>
+Pyrex
+compiles calls to the following built-in functions into direct calls to
+the corresponding Python/C API routines, making them particularly fast.<br>
+<br>
+<table style="text-align: left; background-color: rgb(204, 255, 255); margin-left: 40px;" border="1" cellpadding="4" cellspacing="0">
+<tbody>
+<tr>
+<td style="font-weight: bold; background-color: rgb(255, 204, 51);">Function
+and arguments</td>
+<td style="font-weight: bold; background-color: rgb(255, 204, 51);">Return
+type</td>
+<td style="font-weight: bold; white-space: nowrap; background-color: rgb(255, 204, 51);">Python/C
+API Equivalent</td>
+</tr>
+<tr>
+<td>abs(obj)</td>
+<td>object</td>
+<td>PyNumber_Absolute</td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">bool(obj)
+&nbsp; <span style="font-style: italic;">(Note 3)</span></td>
+<td align="left" nowrap="nowrap" valign="top">int</td>
+<td align="left" nowrap="nowrap" valign="top">PyObject_IsTrue</td>
+</tr>
+<tr>
+<td>delattr(obj,&nbsp;name)</td>
+<td>int</td>
+<td>PyObject_DelAttr</td>
+</tr>
+<tr>
+<td>dir(obj)</td>
+<td>object</td>
+<td>PyObject_Dir</td>
+</tr>
+<tr>
+<td>divmod(x, y)</td>
+<td>object</td>
+<td>PyNumber_Divmod</td>
+</tr>
+<tr>
+<td style="white-space: nowrap;">getattr(obj,&nbsp;name)
+<span style="font-style: italic;">&nbsp; (Note 1</span>)<br>
+getattr3(obj, name, default)</td>
+<td>object</td>
+<td>PyObject_GetAttr</td>
+</tr>
+<tr>
+<td>hasattr(obj, name)</td>
+<td>int</td>
+<td>PyObject_HasAttr</td>
+</tr>
+<tr>
+<td>hash(obj)</td>
+<td>int</td>
+<td>PyObject_Hash</td>
+</tr>
+<tr>
+<td>cintern(char *)<span style="font-style: italic;">
+&nbsp; (Note 5)</span></td>
+<td>object</td>
+<td>PyString_InternFromString</td>
+</tr>
+<tr>
+<td>isinstance(obj, type)</td>
+<td>int</td>
+<td>PyObject_IsInstance</td>
+</tr>
+<tr>
+<td>issubclass(obj, type)</td>
+<td>int</td>
+<td>PyObject_IsSubclass</td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">issubtype(type,
+type) &nbsp; <span style="font-style: italic;">(Note 4</span>)</td>
+<td align="left" nowrap="nowrap" valign="top">int</td>
+<td align="left" nowrap="nowrap" valign="top">PyType_IsSubType</td>
+</tr>
+<tr>
+<td>iter(obj)</td>
+<td>object</td>
+<td>PyObject_GetIter</td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">iter2(obj,
+obj)</td>
+<td align="left" nowrap="nowrap" valign="top">object</td>
+<td align="left" nowrap="nowrap" valign="top">PyCallIter_New</td>
+</tr>
+<tr>
+<td>len(obj)</td>
+<td>Py_ssize_t</td>
+<td>PyObject_Length</td>
+</tr>
+<tr>
+<td style="width: 1px;">pow(x, y, z) <span style="font-style: italic;">&nbsp; (Note 2)</span></td>
+<td style="width: 1px;">object</td>
+<td style="width: 1px;">PyNumber_Power</td>
+</tr>
+<tr>
+<td>reload(obj)</td>
+<td>object</td>
+<td>PyImport_ReloadModule</td>
+</tr>
+<tr>
+<td>repr(obj)</td>
+<td>object</td>
+<td>PyObject_Repr</td>
+</tr>
+<tr>
+<td style="width: 200px;">setattr(obj,&nbsp;name)</td>
+<td style="width: 100px;">void</td>
+<td style="width: 150px;">PyObject_SetAttr</td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">typecheck(obj,
+type) &nbsp; <span style="font-style: italic;">(Note
+4)</span></td>
+<td align="left" nowrap="nowrap" valign="top">int</td>
+<td align="left" nowrap="nowrap" valign="top">PyObject_TypeCheck</td>
+</tr>
+</tbody>
+</table>
+<br>
+<div style="margin-left: 40px;"><span style="font-style: italic;">Note 1:</span> There are
+two different functions corresponding to the Python <span style="font-family: monospace;">getattr</span>
+depending on whether a third argument is used. In a non-call context,
+they both evaluate to the Python <span style="font-family: monospace;">getattr</span>
+function.<br>
+<br>
+<span style="font-style: italic;">Note 2:</span>
+Only the three-argument form of <span style="font-family: monospace;">pow()</span> is
+supported. Use the <span style="font-family: monospace;">**</span>
+operator otherwise.<br>
+<br>
+<span style="font-style: italic;">Note 3:</span> In
+a non-call context, the name <span style="font-family: monospace;">bool</span>
+refers to the Python built-in bool type.<br>
+<br>
+<span style="font-style: italic;">Note 4:</span> The
+functions <span style="font-family: monospace;">typecheck</span>
+and <span style="font-family: monospace;">issubtype</span>
+have no exact Python equivalent. They are included for fast, safe type
+checking of extension types. They are safer than using <span style="font-family: monospace;">isinstance</span> and <span style="font-family: monospace;">issubclass</span>
+for this purpose, because the behaviour of the latter functions can be
+overridden, so they don't necessarily reflect the true C types of the
+objects involved.<br>
+<br>
+<span style="font-style: italic;">Note 5:</span>
+This function is named <span style="font-family: monospace;">cintern</span>
+instead of <span style="font-family: monospace;">intern</span>
+because it takes a null-terminated C string rather than a Python
+string, and therefore cannot handle strings containing null bytes.<br>
+</div>
+<br>
+Only
+direct function calls using these names are optimised. If you do
+something else with one of these names that assumes it's a Python
+object, such as assign it to a Python variable, and later call it, the
+call will be made as a Python function call.
+<h3><a class="mozTocH3" name="mozTocId452377"></a><a name="BuiltinTypes"></a>Built-in Types</h3>
+Pyrex
+knows about the following builtin
+types:<br>
+<br>
+<div style="margin-left: 40px;"><span style="font-family: monospace;">dict</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">list</span><br>
+<span style="font-family: monospace;">object</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">slice</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">type</span><br>
+</div>
+<br>
+If you declare a variable as being of one of these types, then
+calls to the methods in the table below will be compiled to direct
+Python/C API calls,
+avoiding the overhead of a Python attribute lookup and function call.
+In the case of attributes, they will be accessed directly from the
+object's C struct.<br>
+<br>
+Referring to the types themselves is also
+slightly more efficient, because the relevant type object is accessed
+directly rather than via a global variable lookup.<br>
+<br>
+<table style="text-align: left; background-color: rgb(204, 255, 255); width: 665px; height: 330px;" border="1" cellpadding="4" cellspacing="0">
+<tbody>
+<tr>
+<td style="font-weight: bold; background-color: rgb(255, 204, 51);">Method
+or Attribute</td>
+<td style="font-weight: bold; background-color: rgb(255, 204, 51);">Return
+type</td>
+<td colspan="1" rowspan="1" style="font-weight: bold; white-space: nowrap; background-color: rgb(255, 204, 51);">Python/C
+API Equivalent</td>
+<td style="background-color: rgb(255, 204, 51); font-weight: bold;" align="left" nowrap="nowrap">Notes</td>
+</tr>
+<tr>
+<td colspan="4" rowspan="1" style="vertical-align: top; white-space: nowrap; text-align: left; background-color: rgb(51, 153, 153);"><span style="font-weight: bold;">Type </span><span style="font-family: monospace; font-weight: bold;">dict</span></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">clear()</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+<td align="left" nowrap="nowrap" valign="top">PyDict_Clear</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">copy()</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+<td align="left" nowrap="nowrap" valign="top">PyDict_Copy</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">items()</td>
+<td align="left" nowrap="nowrap" valign="top">object</td>
+<td align="left" nowrap="nowrap" valign="top">PyDict_Items</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">keys()</td>
+<td align="left" nowrap="nowrap" valign="top">object</td>
+<td align="left" nowrap="nowrap" valign="top">PyDict_Keys</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">values()</td>
+<td align="left" nowrap="nowrap" valign="top">object</td>
+<td align="left" nowrap="nowrap" valign="top">PyDict_Values</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">merge(obj,
+override)</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+<td align="left" nowrap="nowrap" valign="top">PyDict_Merge</td>
+<td align="left" nowrap="nowrap" valign="top">Merge
+items from a mapping</td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">update(obj)</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+<td align="left" nowrap="nowrap" valign="top">PyDict_Update</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">merge_pairs(obj,&nbsp;override)</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+<td align="left" nowrap="nowrap" valign="top">PyDict_MergeFromSeq2</td>
+<td align="left" nowrap="nowrap" valign="top">Merge
+(key, value) pairs from a sequence</td>
+</tr>
+<tr>
+<td colspan="4" rowspan="1" style="vertical-align: top; white-space: nowrap; text-align: left; background-color: rgb(51, 153, 153);"><span style="font-weight: bold;">Type </span><span style="font-family: monospace; font-weight: bold;">list</span></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">insert(int,
+obj)</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+<td align="left" nowrap="nowrap" valign="top">PyList_Insert</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">append(obj)</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+<td align="left" nowrap="nowrap" valign="top">PyList_Append</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">sort()</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+<td align="left" nowrap="nowrap" valign="top">PyList_Sort</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">reverse()</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+<td align="left" nowrap="nowrap" valign="top">PyList_Reverse</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">as_tuple()</td>
+<td align="left" nowrap="nowrap" valign="top">object</td>
+<td align="left" nowrap="nowrap" valign="top">PyList_AsTuple</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td colspan="4" rowspan="1" style="vertical-align: top; white-space: nowrap; text-align: left; background-color: rgb(51, 153, 153);"><span style="font-weight: bold;">Type <span style="font-family: monospace;">slice</span></span></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">indices()</td>
+<td align="left" nowrap="nowrap" valign="top">object</td>
+<td align="left" nowrap="nowrap" valign="top">PySlice_Indices</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">start</td>
+<td align="left" nowrap="nowrap" valign="top">object</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">stop</td>
+<td align="left" nowrap="nowrap" valign="top">object</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+<tr>
+<td align="left" nowrap="nowrap" valign="top">step</td>
+<td align="left" nowrap="nowrap" valign="top">object</td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+<td align="left" nowrap="nowrap" valign="top"></td>
+</tr>
+</tbody>
+</table>
+<br>
+Some
+of the above methods have no direct Python equivalent, but are there to
+provide access to routines that exist in the Python/C API.<br>
+<br>
+As an example, the following compiles into code containing no Python
+attribute lookups or function calls.<br>
+<br>
+<div style="margin-left: 40px;"><span style="font-family: monospace;">cdef list cheeses</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">cheeses = []</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">cheeses.append("camembert")</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">cheeses.append("cheddar")</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">cheeses.insert(1,
+"something runny")</span><br style="font-family: monospace;">
+</div>
+<br>
+<hr style="width: 100%; height: 2px;">
+<h2><a class="mozTocH2" name="mozTocId42018"></a><a name="Conditional_Compilation"></a>Conditional
+Compilation</h2>
+Some features are available for conditional compilation and
+compile-time constants within a Pyrex source file.<br>
+<h3><a class="mozTocH3" name="mozTocId379306"></a><a name="Compile-Time_Definitions"></a>Compile-Time
+Definitions</h3>
+A compile-time constant can be defined using the <span style="font-family: monospace; font-weight: bold;">DEF</span>
+statement:<br>
+<pre style="margin-left: 40px;">DEF FavouriteFood = "spam"<br>DEF ArraySize = 42<br>DEF OtherArraySize = 2 * ArraySize + 17</pre>
+The
+right-hand side of the DEF must be a valid compile-time expression.
+Such expressions are made up of literal values and names defined using
+DEF statements, combined using any of the Python expression syntax.<br>
+<br>
+The following compile-time names are predefined, corresponding to the
+values returned by <span style="font-weight: bold;">os.uname()</span>.<br>
+<pre style="margin-left: 40px;">UNAME_SYSNAME, UNAME_NODENAME, UNAME_RELEASE,<br>UNAME_VERSION, UNAME_MACHINE</pre>
+The following selection of builtin constants and functions are also
+available:<br>
+<pre style="margin-left: 40px;">None, True, False,<br>abs, bool, chr, cmp, complex, dict, divmod, enumerate,<br>float, hash, hex, int, len, list, long, map, max, min,<br>oct, ord, pow, range, reduce, repr, round, slice, str,<br>sum, tuple, xrange, zip</pre>
+A
+name defined using DEF can be used anywhere an identifier can appear,
+and it is replaced with its compile-time value as though it were
+written into the source at that point as a literal. For this to work,
+the compile-time expression must evaluate to a Python value of type <span style="font-weight: bold;">int</span>, <span style="font-weight: bold;">long</span>, <span style="font-weight: bold;">float </span>or <span style="font-weight: bold;">str</span>.<br>
+<pre style="margin-left: 40px;">cdef int a1[ArraySize]<br>cdef int a2[OtherArraySize]<br>print "I like", FavouriteFood</pre>
+<h3><a class="mozTocH3" name="mozTocId997015"></a><a name="Conditional_Statements"></a>Conditional
+Statements</h3>
+The <span style="font-family: monospace; font-weight: bold;">IF</span>
+statement can be used to conditionally include or exclude sections of
+code at compile time. It works in a similar way to the <span style="font-weight: bold;">#if</span> preprocessor
+directive in C.<br>
+<pre style="margin-left: 40px;">IF UNAME_SYSNAME == "Windows":<br> include "icky_definitions.pxi"<br>ELIF UNAME_SYSNAME == "Darwin":<br> include "nice_definitions.pxi"<br>ELIF UNAME_SYSNAME == "Linux":<br> include "penguin_definitions.pxi"<br>ELSE:<br> include "other_definitions.pxi"</pre>
+The
+ELIF and ELSE clauses are optional. An IF statement can appear anywhere
+that a normal statement or declaration can appear, and it can contain
+any statements or declarations that would be valid in that context,
+including DEF statements and other IF statements.<br>
+<br>
+The
+expressions in the IF and ELIF clauses must be valid compile-time
+expressions as for the DEF statement, although they can evaluate to any
+Python value, and the truth of the result is determined in the usual
+Python way.<br>
+<br>
+---
+</body></html> \ No newline at end of file
diff --git a/debian/pyrex/pyrex-0.9.9/Doc/Manual/extension_types.html b/debian/pyrex/pyrex-0.9.9/Doc/Manual/extension_types.html
new file mode 100644
index 00000000..3cd3dc42
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Doc/Manual/extension_types.html
@@ -0,0 +1,1079 @@
+<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
+<html><head>
+
+
+
+
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+
+
+
+
+ <meta name="GENERATOR" content="Mozilla/4.61 (Macintosh; I; PPC) [Netscape]">
+
+
+ <title>Extension Types</title></head>
+<body>
+
+
+
+<h1>
+<hr width="100%">Extension Types
+<hr width="100%"></h1>
+
+
+
+<h2> Contents</h2>
+
+
+
+<ul>
+
+
+ <li> <a href="#Introduction">Introduction</a></li>
+
+
+ <li> <a href="#ExtTypeAttrs">Attributes</a></li>
+ <li><a href="#TypeDeclarations">Type declarations</a></li>
+
+
+ <li> <a href="#NotNone">Extension types and None</a></li>
+
+
+ <li> <a href="special_methods.html">Special methods</a></li>
+
+
+ <li> <a href="#Properties">Properties</a></li>
+
+
+ <li><a href="#SubclassingExtTypes">Subclassing</a></li>
+
+
+ <li> <a href="#CMethods">C Methods</a></li><li><a href="#ForwardDeclaringExtTypes">Forward-declaring extension types</a></li>
+
+ <li><a href="#WeakRefs">Making extension types weak-referenceable</a><span style="color: rgb(255, 0, 0);"></span><br>
+
+
+ </li>
+
+
+
+ <li> <a href="#PublicAndExtern">Public and external extension types</a><font color="#2f8b20"><br>
+
+
+ </font></li>
+
+
+
+
+ <ul>
+
+
+ <li> <a href="#ExternalExtTypes">External extension types</a></li>
+
+
+ <li> <a href="#ImplicitImport">Implicit importing</a><font color="#2f8b20"><br>
+
+
+ </font></li>
+
+
+ <li> <a href="#TypeVsConstructor">Type names vs. constructor names</a></li>
+
+
+ <li> <a href="#PublicExtensionTypes">Public extension types</a></li>
+
+
+ <li> <a href="#NameSpecClause">Name specification clause</a></li>
+
+
+
+
+ </ul>
+
+
+
+</ul>
+
+
+
+<h2> <a name="Introduction"></a>Introduction</h2>
+
+
+ As well as creating normal user-defined classes with the Python <b>class</b>
+statement, Pyrex also lets you create new built-in Python types, known as
+<i>extension types</i>. <br><br><table style="text-align: left; background-color: rgb(255, 255, 0); width: 554px; margin-left: 40px;" border="0" cellpadding="5" cellspacing="0"><tbody><tr><td style="vertical-align: top; text-align: left;">WARNING: There are substantial differences in the way many of the
+special methods work in extension types compared to Python classes.
+Before attempting to define any __xxx__ methods, read the section on <a href="special_methods.html">Special Methods of Extension Types.</a></td></tr></tbody></table><br>You define an extension type using the <b>cdef class</b> statement. Here's an example:
+<blockquote><tt>cdef class Shrubbery:</tt>
+
+ <p><tt>&nbsp;&nbsp;&nbsp; cdef int width, height</tt> </p>
+
+
+
+
+ <p><tt>&nbsp;&nbsp;&nbsp; def __init__(self, w, h):</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.width = w</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.height = h</tt> </p>
+
+
+
+
+ <p><tt>&nbsp;&nbsp;&nbsp; def describe(self):</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "This shrubbery is",
+self.width, \</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+"by", self.height, "cubits."</tt></p>
+
+
+ </blockquote>
+
+
+ As you can see, a Pyrex extension type definition looks a lot like a Python
+ class definition. Within it, you use the <b>def</b> statement to define
+methods that can be called from Python code. You can even define many of
+the special methods such as <tt>__init__</tt> as you would in Python.
+<p>The main difference is that you can use the <b>cdef</b> statement to define
+attributes. The attributes may be Python objects (either generic or of a particular
+extension type), or they may be of any C data type. So you can use extension
+types to wrap arbitrary C data structures and provide a Python-like interface
+to them. </p>
+
+
+
+<h2> <a name="ExtTypeAttrs"></a>Attributes</h2>
+
+
+ Attributes of an extension type are stored directly in the object's C struct.
+ The set of attributes is fixed at compile time; you can't add attributes
+to an extension type instance at run time simply by assigning to them, as
+you could with a Python class instance. (You can subclass the extension type
+in Python and add attributes to instances of the subclass, however.)
+<p>There are two ways that attributes of an extension type can be accessed:
+ by Python attribute lookup, or by direct access to the C struct from Pyrex
+ code. Python code is only able to access attributes of an extension type
+by the first method, but Pyrex code can use either method. </p>
+
+
+
+<p>By default, extension type attributes are only accessible by direct access,
+not Python access, which means that they are not accessible from Python code.
+To make them accessible from Python code, you need to declare them as <tt>public</tt> or <tt>readonly</tt>. For example, </p>
+
+
+
+<blockquote><tt>cdef class Shrubbery:</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp; cdef public int width, height</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp; cdef readonly float depth</tt></blockquote>
+
+
+ makes the <tt>width</tt> and <tt>height</tt> attributes readable and writable
+ from Python code, and the <tt>depth</tt> attribute readable but not writable.
+
+<p>Note that you can only expose simple C types, such as ints, floats and
+ strings, for Python access. You can also expose Python-valued attributes,
+ although read-write exposure is only possible for generic Python attributes
+ (of type <tt>object</tt>). If the attribute is declared to be of an extension
+ type, it must be exposed <tt>readonly</tt>. </p>
+
+
+
+<p>Note also that the <tt>public</tt> and <tt>readonly</tt> options apply
+ only to <i>Python</i> access, not direct access. All the attributes of an
+extension type are always readable and writable by direct access.</p>
+
+<h2><a name="TypeDeclarations"></a>Type declarations </h2>
+
+
+
+<p>Before you can directly access the attributes of an extension type, the Pyrex compiler must know
+that you have an instance of that type, and not just a generic Python object.
+It knows this already in the case of the "self" parameter of the methods of
+that type, but in other cases you will have to use a type declaration.</p>
+
+<p>For example, in the following function,</p>
+
+<blockquote><tt>cdef widen_shrubbery(sh, extra_width): # </tt><span style="font-family: monospace;"><span style="color: rgb(255, 0, 0);">BAD</span></span><br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp; sh.width = sh.width + extra_width</tt></blockquote>
+
+<p> because the <span style="font-family: monospace;">sh</span> parameter hasn't been given a type, the <span style="font-family: monospace;">width</span>
+attribute will be accessed by a Python attribute lookup. If the
+attribute has been declared <span style="font-style: italic;">public</span> or <span style="font-style: italic;">readonly</span> then this will work, but
+it will be very inefficient. If the attribute is private, it will not work at all -- the
+code will compile, but an attribute error will be raised at run time.</p>
+
+<p>The solution is to declare sh as being of type <span style="font-family: monospace;">Shrubbery</span>, as follows:</p>
+
+
+
+<blockquote><tt>cdef widen_shrubbery(Shrubbery sh, extra_width):</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp; sh.width = sh.width + extra_width</tt></blockquote>
+
+Now the Pyrex compiler knows that <span style="font-family: monospace;">sh</span> has a C attribute called <span style="font-family: monospace;">width</span> and will generate code to access it directly and efficiently. The same consideration applies to local variables, for example,<br>
+
+<br>
+
+<div style="margin-left: 40px;"><code>cdef Shrubbery another_shrubbery(Shrubbery sh1):<br>
+
+&nbsp;&nbsp;&nbsp; cdef Shrubbery sh2<br>
+
+&nbsp;&nbsp;&nbsp; sh2 = Shrubbery()<br>
+
+&nbsp;&nbsp;&nbsp; sh2.width = sh1.width<br>
+
+&nbsp;&nbsp;&nbsp; sh2.height = sh1.height<br>
+
+&nbsp;&nbsp;&nbsp; return sh2</code></div>
+
+
+<h2> <a name="NotNone"></a>Extension types and None</h2>
+
+
+ When you declare a parameter or C variable as being of an extension type,
+ Pyrex will allow it to take on the value None as well as values of its declared
+type. This is analogous to the way a C pointer can take on the value NULL,
+and you need to exercise the same caution because of it. There is no problem
+as long as you are performing Python operations on it, because full dynamic
+type checking will be applied. However, when you access C attributes of an
+extension type (as in the <tt>widen_shrubbery</tt> function above), it's up
+to you to make sure the reference you're using is not None -- in the interests
+of efficiency, Pyrex does <i>not</i> check this.
+<p>You need to be particularly careful when exposing Python functions which
+ take extension types as arguments. If we wanted to make <tt>widen_shrubbery</tt>
+a Python function, for example, if we simply wrote </p>
+
+
+
+<blockquote><tt>def widen_shrubbery(Shrubbery sh, extra_width): # <font color="#ed181e">This is</font></tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp; sh.width = sh.width + extra_width&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+# <font color="#ed181e">dangerous!</font></tt></blockquote>
+
+
+ then users of our module could crash it by passing None for the <tt>sh</tt>
+parameter.
+<p>One way to fix this would be </p>
+
+
+
+<blockquote><tt>def widen_shrubbery(Shrubbery sh, extra_width):</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp; if sh is None:</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; raise TypeError</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp; sh.width = sh.width + extra_width</tt></blockquote>
+
+
+ but since this is anticipated to be such a frequent requirement, Pyrex
+provides a more convenient way. Parameters of a Python function declared
+as an extension type can have a <b><tt>not</tt></b> <b><tt>None</tt></b> clause:
+<blockquote><tt>def widen_shrubbery(Shrubbery sh not None, extra_width):</tt>
+ <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp; sh.width = sh.width + extra_width</tt></blockquote>
+
+
+ Now the function will automatically check that <tt>sh</tt> is not None
+along with checking that it has the right type.
+<p>Note, however that the <tt>not</tt> <tt>None</tt> clause can <i>only</i> be used
+ in Python functions (defined with <tt>def</tt>) and not C functions (defined
+ with <tt>cdef</tt>). If you need to check whether a parameter to a C function
+ is None, you will need to do it yourself. </p>
+
+
+
+<p>Some more things to note: </p>
+
+
+
+<ul>
+
+
+ <li> The <b>self</b> parameter of a method of an extension type is guaranteed
+ never to be None.</li>
+
+
+
+</ul>
+
+
+
+<ul>
+
+
+ <li> When comparing a value with None, keep in mind that, if <tt>x</tt> is a Python object, <tt>x</tt> <tt>is</tt> <tt>None</tt> and <tt>x is</tt> <tt>not</tt> <tt>None</tt> are very
+efficient because they translate directly to C pointer comparisons, whereas
+ <tt>x == None</tt> and <tt>x != None</tt>, or simply using <tt>x</tt> as a boolean value (as in <tt>if x: ...</tt>) will invoke Python operations
+and therefore be much slower.</li>
+
+
+
+</ul>
+
+
+
+<h2> <a name="ExtTypeSpecialMethods"></a>Special methods</h2>
+
+
+ Although the principles are similar, there are substantial differences
+between many of the <span style="font-family: monospace;">__xxx__</span> special methods of extension types and their
+Python counterparts. There is a <a href="special_methods.html">separate page</a> devoted to this subject, and you should read it carefully before attempting
+to use any special methods in your extension types.
+<h2> <a name="Properties"></a>Properties</h2>
+
+
+ There is a special syntax for defining <b>properties</b> in an extension
+ class:
+<blockquote><tt>cdef class Spam:</tt>
+
+ <p><tt>&nbsp;&nbsp;&nbsp; property cheese:</tt> </p>
+
+
+
+
+ <p><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "A doc string can go
+here."</tt> </p>
+
+
+
+
+ <p><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def __get__(self):</tt>
+ <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+# This is called when the property is read.</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+...</tt> </p>
+
+
+
+
+ <p><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def __set__(self, value):</tt>
+ <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+# This is called when the property is written.</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+...</tt> </p>
+
+
+
+
+ <p><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def __del__(self):</tt>
+ <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+# This is called when the property is deleted.</tt> <br>
+
+
+ &nbsp;</p>
+
+
+ </blockquote>
+
+
+ The <tt>__get__</tt>, <tt>__set__</tt> and <tt>__del__</tt> methods are
+all optional; if they are omitted, an exception will be raised when the corresponding
+operation is attempted.
+<p>Here's a complete example. It defines a property which adds to a list
+each time it is written to, returns the list when it is read, and empties
+the list when it is deleted. <br>
+
+
+ &nbsp; </p>
+
+
+
+<center>
+<table align="center" cellpadding="5">
+
+
+ <tbody>
+
+
+ <tr>
+
+
+ <td bgcolor="#ffaf18"><b><tt>cheesy.pyx</tt></b></td>
+
+
+ <td bgcolor="#5dbaca"><b>Test input</b></td>
+
+
+ </tr>
+
+
+ <tr>
+
+
+ <td rowspan="3" bgcolor="#ffaf18" valign="top"><tt>cdef class CheeseShop:</tt>
+
+
+ <p><tt>&nbsp; cdef object cheeses</tt> </p>
+
+
+
+
+ <p><tt>&nbsp; def __cinit__(self):</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp; self.cheeses = []</tt> </p>
+
+
+
+
+ <p><tt>&nbsp; property cheese:</tt> </p>
+
+
+
+
+ <p><tt>&nbsp;&nbsp;&nbsp; def __get__(self):</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "We don't have: %s" % self.cheeses</tt>
+ </p>
+
+
+
+
+ <p><tt>&nbsp;&nbsp;&nbsp; def __set__(self, value):</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.cheeses.append(value)</tt>
+ </p>
+
+
+
+
+ <p><tt>&nbsp;&nbsp;&nbsp; def __del__(self):</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; del self.cheeses[:]</tt></p>
+
+
+ </td>
+
+
+ <td bgcolor="#5dbaca" valign="top"><tt>from cheesy import CheeseShop</tt>
+
+
+ <p><tt>shop = CheeseShop()</tt> <br>
+
+
+ <tt>print shop.cheese</tt> </p>
+
+
+
+
+ <p><tt>shop.cheese = "camembert"</tt> <br>
+
+
+ <tt>print shop.cheese</tt> </p>
+
+
+
+
+ <p><tt>shop.cheese = "cheddar"</tt> <br>
+
+
+ <tt>print shop.cheese</tt> </p>
+
+
+
+
+ <p><tt>del shop.cheese</tt> <br>
+
+
+ <tt>print shop.cheese</tt></p>
+
+
+ </td>
+
+
+ </tr>
+
+
+ <tr>
+
+
+ <td bgcolor="#8cbc1c"><b>Test output</b></td>
+
+
+ </tr>
+
+
+ <tr>
+
+
+ <td bgcolor="#8cbc1c"><tt>We don't have: []</tt> <br>
+
+
+ <tt>We don't have: ['camembert']</tt> <br>
+
+
+ <tt>We don't have: ['camembert', 'cheddar']</tt> <br>
+
+
+ <tt>We don't have: []</tt></td>
+
+
+ </tr>
+
+
+
+
+ </tbody>
+</table>
+
+
+ </center>
+
+
+
+<h2> <a name="SubclassingExtTypes"></a>Subclassing</h2>
+
+
+ An extension type may inherit from a built-in type or another extension
+type:
+<blockquote><tt>cdef class Parrot:</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp; ...</tt><tt></tt>
+
+ <p><tt>cdef class Norwegian(Parrot):</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp; ...</tt></p>
+
+
+ </blockquote>
+
+
+
+<p><br>
+
+
+ A complete definition of the base type must be available to Pyrex, so if
+the base type is a built-in type, it must have been previously declared as
+an <b>extern</b> extension type. If the base type is defined in another Pyrex
+module, it must either be declared as an extern extension type or imported
+using the <b><a href="sharing.html">cimport</a></b> statement. </p>
+
+
+
+<p>An extension type can only have one base class (no multiple inheritance).
+ </p>
+
+
+
+<p>Pyrex extension types can also be subclassed in Python. A Python class
+ can inherit from multiple extension types provided that the usual Python
+rules for multiple inheritance are followed (i.e. the C layouts of all the
+base classes must be compatible).<br>
+
+
+ </p>
+
+
+
+<h2><a name="CMethods"></a>C methods</h2>
+
+
+ Extension types can have C methods as well as Python methods. Like C functions,
+C methods are declared using <tt>cdef</tt> instead of <tt>def</tt>. C methods
+are "virtual", and may be overridden in derived extension types.<br>
+
+
+ <br>
+
+
+
+<table align="center" cellpadding="5">
+
+
+ <tbody>
+
+
+ <tr>
+
+
+ <td bgcolor="#ffaf18" valign="top" width="50%"><b><tt>pets.pyx</tt></b><br>
+
+
+ </td>
+
+
+ <td bgcolor="#8cbc1c" valign="top" width="30%"><b>Output</b><br>
+
+
+ </td>
+
+
+ </tr>
+
+
+ <tr>
+
+
+ <td bgcolor="#ffaf18" valign="top" width="50%"><tt>cdef class Parrot:<br>
+
+
+ <br>
+
+
+ &nbsp; cdef void describe(self):<br>
+
+
+ &nbsp; &nbsp; print "This parrot is resting."<br>
+
+
+ <br>
+
+
+ cdef class Norwegian(Parrot):<br>
+
+
+ <br>
+
+
+ &nbsp; cdef void describe(self):<br>
+
+
+&nbsp; &nbsp; Parrot.describe(self)<br>
+
+
+ &nbsp; &nbsp; print "Lovely plumage!"<br>
+
+
+ <br>
+
+
+ <br>
+
+
+ cdef Parrot p1, p2<br>
+
+
+ p1 = Parrot()<br>
+
+
+ p2 = Norwegian()<br>
+
+
+print "p1:"<br>
+
+
+ p1.describe()<br>
+
+
+print "p2:"<br>
+
+
+ p2.describe()</tt> <br>
+
+
+ </td>
+
+
+ <td bgcolor="#8cbc1c" valign="top" width="30%"><tt>p1:<br>
+
+
+This parrot is resting.<br>
+
+
+p2:<br>
+
+
+ </tt><tt>This parrot is resting.<br>
+
+
+ </tt><tt> Lovely plumage!</tt><br>
+
+
+ </td>
+
+
+ </tr>
+
+
+
+
+ </tbody>
+</table>
+
+
+ <br>
+
+
+ The above example also illustrates that a C method can call an inherited
+C method using the usual Python technique, i.e.<br>
+
+
+<blockquote><tt>Parrot.describe(self)</tt><br>
+
+
+</blockquote>
+
+
+
+<h2><a name="ForwardDeclaringExtTypes"></a>Forward-declaring extension types</h2>
+
+
+ Extension types can be forward-declared, like struct and union types. This
+ will be necessary if you have two extension types that need to refer to
+each other, e.g.
+<blockquote><tt>cdef class Shrubbery # forward declaration</tt>
+
+ <p><tt>cdef class Shrubber:</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp; cdef Shrubbery work_in_progress</tt> </p>
+
+
+
+
+ <p><tt>cdef class Shrubbery:</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp; cdef Shrubber creator</tt></p>
+
+
+ </blockquote><h2><a name="WeakRefs"></a>Making extension types weak-referenceable</h2>
+
+By
+default, extension types do not support having weak references made to
+them. You can enable weak referencing by declaring a C attribute of
+type <span style="font-family: monospace;">object</span> called <span style="font-family: monospace; font-weight: bold;">__weakref__</span>. For example,<br>
+
+
+<br>
+
+
+<div style="margin-left: 40px;"><span style="font-family: monospace;">cdef class ExplodingAnimal:<br><br style="font-family: monospace;"></span>
+
+
+<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; """This animal will self-destruct when it is</span><br>
+
+
+<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; no longer strongly referenced."""</span><br>
+
+
+<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; </span><br style="font-family: monospace;">
+
+
+<span style="font-family: monospace;"></span><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; cdef object __weakref__</span><br>
+
+
+</div>
+
+
+<h2>Garbage Collection</h2>Normally, any extension type which has
+Python-valued attributes automatically participates in cyclic garbage
+collection. You can prevent this as follows:<br><pre style="margin-left: 40px;">cdef class Hovercraft [nogc]:<br><br> """This object will not participate in cyclic gc<br> even though it has a Python attribute."""<br><br> cdef object eels<br></pre>However,
+if there is a base type with Python attributes that participates in GC,
+any subclasses of it will also participate in GC regardless of their <span style="font-family: monospace;">nogc</span> options.
+
+
+<h2><a name="PublicAndExtern"></a>Public and external extension types</h2>
+
+
+
+ Extension types can be declared <b>extern</b> or <b>public</b>. An <a href="#ExternalExtTypes"><b>extern</b> extension type declaration</a> makes
+an extension type defined in external C code available to a Pyrex module.
+A <a href="#PublicExtensionTypes"><b>public</b> extension type declaration</a> makes an extension type defined in a Pyrex module available to external C
+code.
+<h3> <a name="ExternalExtTypes"></a>External extension types</h3>
+
+
+ An <b>extern</b> extension type allows you to gain access to the internals
+ of Python objects defined in the Python core or in a non-Pyrex extension
+module.
+<blockquote><b>NOTE:</b> In Pyrex versions before 0.8, <b>extern</b> extension
+ types were also used to reference extension types defined in another Pyrex
+ module. While you can still do that, Pyrex 0.8 and later provides a better
+ mechanism for this. See <a href="sharing.html">Sharing C Declarations Between
+ Pyrex Modules</a>.</blockquote>
+
+
+ Here is an example which will let you get at the C-level members of the
+built-in <i>complex</i> object.
+<blockquote><tt>cdef extern from "complexobject.h":</tt>
+
+ <p><tt>&nbsp;&nbsp;&nbsp; struct Py_complex:</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; double real</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; double imag</tt> </p>
+
+
+
+
+ <p><tt>&nbsp;&nbsp;&nbsp; ctypedef class __builtin__.complex [object PyComplexObject]:</tt>
+ <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cdef Py_complex cval</tt>
+ </p>
+
+
+
+
+ <p><tt># A function which uses the above type</tt> <br>
+
+
+ <tt>def spam(complex c):</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp; print "Real:", c.cval.real</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp; print "Imag:", c.cval.imag</tt></p>
+
+
+ </blockquote>
+
+
+ Some important things to note are:
+<ol>
+
+
+ <li> In this example, <b>ctypedef class</b> has been used. This is because,
+ in the Python header files, the <tt>PyComplexObject</tt> struct is declared
+ with<br>
+
+
+ <br>
+
+
+
+
+ <div style="margin-left: 40px;"><tt>ctypedef struct {</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp; ...</tt> <br>
+
+
+ <tt>} PyComplexObject;<br>
+
+
+ <br>
+
+
+ </tt></div>
+
+
+ </li>
+
+ <li>As well as the name of the extension type, the <i>module</i> in which
+its type object can be found is also specified. See the <a href="#ImplicitImport">implicit importing</a> section below.&nbsp; <br>
+
+
+ <br>
+
+
+ </li>
+
+
+ <li> When declaring an external extension type, you don't declare
+any methods. Declaration of methods is not required in order to call them,
+because the calls are Python method calls. Also, as with structs and unions,
+if your extension class declaration is inside a <i>cdef extern from</i> block,
+ you only need to declare those C members which you wish to access.</li>
+
+
+
+</ol>
+
+
+
+<h3> <a name="ImplicitImport"></a>Implicit importing</h3>
+
+
+
+<blockquote><font color="#ef1f1d">Backwards Incompatibility Note</font>:
+You will have to update any pre-0.8 Pyrex modules you have which use <b>extern</b>
+extension types. I apologise for this, but for complicated reasons it proved
+ to be too difficult to continue supporting the old way of doing these while
+ introducing the new features that I wanted.</blockquote>
+
+
+ Pyrex 0.8 and later requires you to include a module name in an extern
+extension class declaration, for example,
+<blockquote><tt>cdef extern class MyModule.Spam:</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp; ...</tt></blockquote>
+
+
+ The type object will be implicitly imported from the specified module and
+ bound to the corresponding name in this module. In other words, in this
+example an implicit
+<ol>
+
+
+
+
+ <pre>from <tt>MyModule</tt> import Spam</pre>
+
+
+
+</ol>
+
+
+ statement will be executed at module load time.
+<p>The module name can be a dotted name to refer to a module inside a package
+ hierarchy, for example, </p>
+
+
+
+<blockquote><tt>cdef extern class My.Nested.Package.Spam:</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp; ...</tt></blockquote>
+
+
+ You can also specify an alternative name under which to import the type
+using an <b>as</b> clause, for example,
+<ol>
+
+
+ <tt>cdef extern class My.Nested.Package.Spam as Yummy:</tt> <br>
+
+
+ <tt>&nbsp;&nbsp; ...</tt>
+</ol>
+
+
+ which corresponds to the implicit import statement
+<ol>
+
+
+
+
+ <pre>from <tt>My.Nested.Package</tt> import <tt>Spam</tt> as <tt>Yummy</tt></pre>
+
+
+
+</ol>
+
+
+
+<h3> <a name="TypeVsConstructor"></a>Type names vs. constructor names</h3>
+
+
+ Inside a Pyrex module, the name of an extension type serves two distinct
+ purposes. When used in an expression, it refers to a module-level global
+variable holding the type's constructor (i.e. its type-object). However,
+it can also be used as a C type name to declare variables, arguments and
+return values of that type.
+<p>When you declare </p>
+
+
+
+<blockquote><tt>cdef extern class MyModule.Spam:</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp; ...</tt></blockquote>
+
+
+ the name <tt>Spam</tt> serves both these roles. There may be other names
+ by which you can refer to the constructor, but only <tt>Spam</tt> can be
+used as a type name. For example, if you were to explicity <tt>import MyModule</tt>,
+ you could use<tt> MyModule.Spam()</tt> to create a Spam instance, but you
+ wouldn't be able to use <tt>MyModule.Spam</tt> as a type name.
+<p>When an <b>as</b> clause is used, the name specified in the <b>as</b>
+clause also takes over both roles. So if you declare </p>
+
+
+
+<blockquote><tt>cdef extern class MyModule.Spam as Yummy:</tt> <br>
+
+
+ <tt>&nbsp;&nbsp;&nbsp; ...</tt></blockquote>
+
+
+ then <tt>Yummy</tt> becomes both the type name and a name for the constructor.
+ Again, there are other ways that you could get hold of the constructor,
+but only <tt>Yummy</tt> is usable as a type name.
+<h3> <a name="PublicExtensionTypes"></a>Public extension types</h3>
+
+
+ An extension type can be declared <b>public</b>, in which case a <b>.h</b>
+file is generated containing declarations for its object struct and type
+object. By including the <b>.h</b> file in external C code that you write,
+that code can access the attributes of the extension type.
+<h3> <a name="NameSpecClause"></a>Name specification clause</h3>
+
+
+ The part of the class declaration in square brackets is a special feature
+ only available for <b>extern</b> or <b>public</b> extension types. The full
+form of this clause is
+<blockquote><tt>[object </tt><i>object_struct_name</i><tt>, type </tt><i>type_object_name</i><span style="font-family: monospace;"> ]</span></blockquote>
+
+
+ where <i>object_struct_name</i> is the name to assume for the type's C
+struct, and <i>type_object_name</i> is the name to assume for the type's
+statically declared type object. (The object and type clauses can be written
+in either order.)
+<p>If the extension type declaration is inside a <b>cdef extern from</b>
+block, the <b>object</b> clause is required, because Pyrex must be able to
+generate code that is compatible with the declarations in the header file.
+Otherwise, for <b>extern</b> extension types, the <b>object</b> clause is
+optional. </p>
+
+
+
+<p>For <b>public</b> extension types, the <b>object</b> and <b>type</b> clauses
+are both required, because Pyrex must be able to generate code that is compatible
+with external C code. </p>
+
+
+
+<p> </p>
+
+
+
+<hr width="100%"> <br>
+
+
+ Back to the <a href="overview.html">Language Overview</a> <br>
+
+
+ &nbsp; <br>
+
+
+ <br>
+
+
+</body></html> \ No newline at end of file
diff --git a/debian/pyrex/pyrex-0.9.9/Doc/Manual/external.html b/debian/pyrex/pyrex-0.9.9/Doc/Manual/external.html
new file mode 100644
index 00000000..38f19270
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Doc/Manual/external.html
@@ -0,0 +1,294 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"><title>Interfacing with External C Code</title></head>
+<body><h1><hr style="width: 100%; height: 2px;"><a name="InterfacingWithExternal"></a>Interfacing with
+External C Code <hr width="100%"></h1><ul><li>
+<a href="#ExternDecls">External declarations</a></li><ul><li>
+<a href="#ReferencingHeaders">Referencing C header files</a></li><li>
+<a href="#StructDeclStyles">Styles of struct/union/enum
+declaration</a></li><li> <a href="#AccessingAPI">Accessing
+Python/C API routines</a></li><li><a href="#SpecialTypes">Special Types</a><span style="color: rgb(255, 0, 0);"> <span style="color: rgb(255, 102, 0);">(New in 0.9.6)</span></span></li><li><a href="#CallingConventions">Windows Calling Conventions</a><span style="color: rgb(255, 0, 0);"> <span style="color: rgb(255, 102, 0);">(New in 0.9.6)</span></span></li><li>
+<a href="#CNameSpecs">Resolving naming conflicts - C name
+specifications</a></li></ul><li><a href="#Using_Pyrex_Declarations_from_C">Using Pyrex
+declarations from C</a></li><ul><li> <a href="#PublicDecls">Public declarations</a></li></ul><ul><li><a href="#C_API_Declarations">C API declarations</a><span style="color: rgb(255, 0, 0);"> <span style="color: rgb(255, 102, 0);">(New in 0.9.6)</span></span></li><li><a href="#Multiple_public_and_api_declarations">Multiple public and API declarations</a><span style="color: rgb(255, 0, 0);"> (New in 0.9.6.3)</span></li><li><a href="#Acquiring_and_Releasing_the_GIL">Acquiring and Releasing the GIL</a><span style="color: rgb(255, 0, 0);"> <span style="color: rgb(255, 102, 0);">(New in 0.9.6)</span></span></li></ul></ul>
+One of the main uses of Pyrex is wrapping existing libraries of C code.
+This is achieved by using <a href="#ExternDecls">external
+declarations</a> to declare the C functions and variables from
+the library that you want to use. <p>You can also use <a href="#PublicDecls">public declarations</a> to make C
+functions and variables defined in a Pyrex module available to external
+C code. The need for this is expected to be less frequent, but you
+might want to do it, for example, if you are embedding Python in
+another application as a scripting language. Just as a Pyrex module can
+be used as a bridge to
+allow Python code to call C code, it can also be used to allow C code
+to
+call Python code.</p><hr style="width: 100%; height: 2px;"> <h2> <a name="ExternDecls"></a>External
+declarations</h2> By default, C functions and variables declared
+at the module level are local to the module (i.e. they have the C <b>static</b>
+storage class). They can also be declared <b>extern</b> to
+specify that they are defined elsewhere, for example: <blockquote>
+<pre>cdef extern int spam_counter</pre> <pre>cdef extern void order_spam(int tons)</pre></blockquote>
+ <h3>
+<a name="ReferencingHeaders"></a>Referencing C
+header files</h3> When you use an extern definition on its own as
+in the examples above, Pyrex includes a declaration for it in the
+generated C file. This can cause problems if the declaration doesn't
+exactly match the declaration that will be seen by other C code. If
+you're wrapping an existing C library, for example, it's important that
+the generated C code is compiled with exactly the same declarations as
+the rest of the library. <p>To achieve this, you can tell Pyrex
+that the declarations are to be found in a C header file, like this: </p>
+<blockquote> <pre>cdef extern from "spam.h":</pre> <pre>&nbsp;&nbsp;&nbsp; int spam_counter</pre><pre>&nbsp;&nbsp;&nbsp; void order_spam(int tons)</pre>
+</blockquote> The <b>cdef extern from</b> clause
+does three things: <ol><li> It directs Pyrex to place a <b>#include</b>
+statement for the named header file in the generated C code.<br> </li>
+&nbsp; <li> It prevents Pyrex from generating any C code for
+the declarations found in the associated block.<br> </li>
+&nbsp; <li> It treats all declarations within the block as
+though they
+started with <b>cdef extern</b>.</li></ol>
+It's important to understand that Pyrex does <i>not</i>
+itself read the C header file, so you still need to provide Pyrex
+versions of any declarations from it that you use. However, the Pyrex
+declarations don't always have to
+exactly match the C ones, and in some cases they shouldn't or can't. In
+particular: <ol><li> Don't use <b>const</b>.
+Pyrex doesn't know anything about const,
+so just leave it out. Most of the time this shouldn't cause any
+problem,
+although on rare occasions you might have to use a cast.<sup><a href="#Footnote1"> 1</a></sup><br> </li>
+&nbsp; <li> Leave out any platform-specific extensions to C
+declarations such as <b>__declspec()</b>.<br> </li>
+&nbsp; <li> If the header file declares a big struct and you
+only want
+to use a few members, you only need to declare the members you're
+interested in. Leaving the rest out doesn't do any harm, because the C
+compiler will use the full definition from the header file.<br> <br>
+In some cases, you might not need <i>any</i> of the
+struct's members, in
+which case you can just put <tt>pass</tt> in the body of
+the struct declaration,
+e.g.<br> <br> <tt>&nbsp; &nbsp; cdef extern
+from "foo.h":<br> &nbsp; &nbsp; &nbsp; &nbsp;
+struct spam:<br> &nbsp; &nbsp; &nbsp; &nbsp;
+&nbsp; &nbsp; pass</tt><br> <br>
+Note that you can only do this inside a <b>cdef extern from</b>
+block; struct
+declarations anywhere else must be non-empty.<br> <br> </li><li>
+If the header file uses typedef names such as <b>size_t </b>to
+refer to platform-dependent flavours of numeric types, you will need a
+corresponding <b>ctypedef</b> statement, but you don't
+need to match the type exactly, just use something of the right general
+kind (int, float, etc). For example,</li><ol><pre>ctypedef int size_t</pre></ol>
+will work okay whatever the actual size of a size_t is (provided the
+header file defines it correctly). <br> &nbsp; <li>
+If the header file uses macros to define constants, translate them into
+a dummy <b>enum</b> declaration.<br> </li>
+&nbsp; <li> If the header file defines a function using a
+macro, declare it as though it were an ordinary function, with
+appropriate argument and
+result types.</li></ol> A few more tricks and tips: <ul><li>
+If you want to include a C header because it's needed by another
+header, but don't want to use any declarations from it, put <tt><font size="+1">pass</font></tt> in the extern-from
+block:</li></ul> <ul><ul><tt>cdef extern
+from "spam.h":</tt><br><tt>&nbsp;&nbsp;&nbsp;
+pass</tt></ul></ul> <ul><li> If you want
+to include some external declarations, but don't want to specify a
+header file (because it's included by some other header that you've
+already included) you can put <tt>*</tt> in place of the
+header file name:</li></ul> <blockquote> <blockquote><tt>cdef
+extern from *:</tt> <br> <tt>&nbsp;&nbsp;&nbsp;
+...</tt></blockquote> </blockquote> <h3> <a name="StructDeclStyles"></a>Styles of struct, union
+and enum declaration</h3> There are two main ways that structs,
+unions and enums can be declared in C header files: using a tag name,
+or using a typedef. There are also some variations based on various
+combinations of these. <p>It's important to make the Pyrex
+declarations match the style used in the
+header file, so that Pyrex can emit the right sort of references to the
+type
+in the code it generates. To make this possible, Pyrex provides two
+different
+syntaxes for declaring a struct, union or enum type. The style
+introduced
+above corresponds to the use of a tag name. To get the other style, you
+prefix
+the declaration with <b>ctypedef</b>, as illustrated
+below. </p> <p>The following table shows the various
+possible styles that can be found in a header file, and the
+corresponding Pyrex declaration that you should put in the <b>cdef
+exern from </b>block. Struct declarations are used as an
+example; the same applies equally to union and enum declarations. </p>
+<p>Note that in all the cases below, you refer to the type in
+Pyrex code simply
+as <tt><font size="+1">Foo</font></tt>,
+not <tt><font size="+1">struct Foo</font></tt>.
+ </p><table cellpadding="5"> <tbody>
+<tr bgcolor="#8cbc1c" valign="top"> <td bgcolor="#8cbc1c">&nbsp;</td> <td bgcolor="#ff9933" nowrap="nowrap"><b>C code</b></td>
+<td bgcolor="#66cccc" valign="top"><b>Possibilities
+for corresponding Pyrex code</b></td> <td bgcolor="#99cc33" valign="top"><b>Comments</b></td>
+</tr> <tr bgcolor="#8cbc1c" valign="top"> <td>1</td>
+<td bgcolor="#ff9900"><tt>struct Foo {</tt> <br>
+<tt>&nbsp; ...</tt> <br> <tt>};</tt></td>
+<td bgcolor="#66cccc"><tt>cdef struct Foo:</tt>
+<br> <tt>&nbsp; ...</tt></td> <td>Pyrex
+will refer to the type as <tt>struct Foo </tt>in the
+generated C code<tt>.</tt></td> </tr> <tr bgcolor="#8cbc1c" valign="top"> <td valign="top">2</td>
+<td bgcolor="#ff9900" nowrap="nowrap"><tt>typedef
+struct {</tt> <br> <tt>&nbsp; ...</tt> <br>
+<tt>} Foo;</tt></td> <td bgcolor="#66cccc" valign="top"><tt>ctypedef struct Foo:</tt> <br>
+<tt>&nbsp; ...</tt></td> <td valign="top">Pyrex
+will refer to the type simply as <tt>Foo</tt>
+in the generated C code.</td> </tr> <tr bgcolor="#8cbc1c" valign="top"> <td rowspan="2">3</td>
+<td rowspan="2" bgcolor="#ff9900" nowrap="nowrap"><tt>typedef
+struct
+foo {</tt> <br> <tt>&nbsp; ...</tt> <br>
+<tt>} Foo;</tt></td> <td bgcolor="#66cccc" nowrap="nowrap" valign="top"><tt>cdef struct
+foo:</tt> <br> <tt>&nbsp; ...</tt> <br>
+<tt>ctypedef foo Foo #optional</tt></td> <td rowspan="2" valign="top">If the C header uses both a
+tag and a typedef with <i>different</i> names, you can use
+either form of declaration in Pyrex (although if you need to forward
+reference the type, you'll have to use
+the first form).</td> </tr> <tr> <td bgcolor="#66cccc"><tt>ctypedef struct Foo:</tt> <br>
+<tt>&nbsp; ...</tt></td> </tr> <tr bgcolor="#8cbc1c" valign="top"> <td>4</td>
+<td bgcolor="#ff9900" nowrap="nowrap"><tt>typedef
+struct Foo {</tt> <br> <tt>&nbsp; ...</tt>
+<br> <tt>} Foo;</tt></td> <td bgcolor="#66cccc" valign="top"><tt>cdef struct
+Foo:</tt> <br> <tt>&nbsp; ...</tt></td>
+<td>If the header uses the <i>same</i> name for the
+tag and the typedef, you won't be able to include a <b>ctypedef</b>
+for it -- but then, it's not
+necessary.</td> </tr> </tbody> </table> <h3>
+<a name="AccessingAPI"></a>Accessing
+Python/C API routines</h3> One particular use of the <b>cdef
+extern from</b> statement is for gaining access to routines in
+the Python/C API. For example, <blockquote> <pre>cdef extern from "Python.h":</pre>
+<pre>&nbsp;&nbsp;&nbsp; object PyString_FromStringAndSize(char *s, Py_ssize_t len)</pre></blockquote>
+will allow you to create Python strings containing
+null bytes. <h3> <a name="SpecialTypes"></a>Special
+Types</h3><p>Pyrex predefines the name <span style="font-family: monospace;">Py_ssize_t</span>
+for use with Python/C API routines. To make your extensions compatible
+with 64-bit systems, you should always use this type where it is
+specified in the documentation of Python/C API routines.</p><h3><a name="CallingConventions"></a>Windows Calling
+Conventions</h3><p>The <span style="font-family: monospace;">__stdcall</span>, <span style="font-family: monospace;">__fastcall</span> and <span style="font-family: monospace;">__cdecl</span> calling
+convention specifiers can be used in Pyrex, with the same syntax as
+used by C compilers on Windows, for example,</p><pre style="margin-left: 40px;">cdef extern int __stdcall FrobnicateWindow(long handle)<br><br>cdef void (__stdcall *callback)(void *)<br></pre>If
+__stdcall is used, the function is only considered compatible with
+other __stdcall functions of the same signature.<br><br> <hr width="100%"> <h2> <a name="CNameSpecs"></a>Resolving
+naming conflicts - C name specifications</h2> Each Pyrex module
+has a single module-level namespace for both Python
+and C names. This can be inconvenient if you want to wrap some external
+C functions and provide the Python user with Python functions of the
+same
+names. <p>Pyrex 0.8 provides a couple of different ways of
+solving this problem. The best way, especially if you have many C
+functions to wrap, is probably to put the extern C function
+declarations into a different namespace using the facilities described
+in the section on <a href="sharing.html">sharing
+declarations between Pyrex modules</a>. </p> <p>The
+other way is to use a <b>c name specification</b> to give
+different Pyrex and C names to the C function. Suppose, for example,
+that you want to wrap an external function called <tt>eject_tomato</tt>.
+If you declare it as </p> <blockquote> <pre>cdef extern void c_eject_tomato "eject_tomato" (float speed)</pre>
+</blockquote> then its name inside the Pyrex module will be <tt>c_eject_tomato</tt>,
+whereas its name in C will be <tt>eject_tomato</tt>. You
+can then wrap it with <blockquote> <pre>def eject_tomato(speed):<br>&nbsp; c_eject_tomato(speed)</pre>
+</blockquote> so that users of your module can refer to it as <tt>eject_tomato</tt>.
+<p>Another use for this feature is referring to external names
+that happen to be Pyrex keywords. For example, if you want to call an
+external function called <tt>print</tt>, you can rename it
+to something else in your Pyrex module. </p> <p>As well
+as functions, C names can be specified for variables, structs, unions,
+enums, struct and union members, and enum values. For example, </p>
+<blockquote> <pre>cdef extern int one "ein", two "zwei"<br>cdef extern float three "drei"<br><br>cdef struct spam "SPAM":<br>&nbsp; int i "eye"</pre><tt>cdef
+enum surprise "inquisition":</tt> <br> <tt>&nbsp;
+first "alpha"</tt> <br> <tt>&nbsp; second
+"beta" = 3</tt></blockquote> <hr width="100%">
+<h2><a name="Using_Pyrex_Declarations_from_C"></a>Using
+Pyrex Declarations from C</h2>Pyrex
+provides two methods for making C declarations from a Pyrex module
+available for use by external C code &#8211; public declarations and C API
+declarations.<br><br><div style="margin-left: 40px;"><span style="font-weight: bold;">NOTE:</span> You do <span style="font-style: italic;">not</span> need to use
+either of these to make declarations from one Pyrex module available to
+another Pyrex module &#8211; you should use the <span style="font-weight: bold;">cimport</span> statement
+for that. <a href="sharing.html">Sharing Declarations
+Between Pyrex Modules</a>.</div><h3><a name="PublicDecls"></a>Public Declarations</h3>
+You can make C types, variables and functions defined in a Pyrex module
+accessible to C code that is linked with the module, by declaring them
+with the <b><tt>public</tt></b> keyword: <blockquote><tt>cdef
+public struct Bunny: # public type declaration<br>&nbsp;
+&nbsp; int vorpalness<br><br>cdef public int spam #
+public variable declaration</tt> <p><tt>cdef public
+void grail(Bunny *): # public function declaration</tt> <br>
+<tt>&nbsp;&nbsp;&nbsp; ...</tt></p> </blockquote>
+If there are any <tt>public</tt> declarations in a Pyrex
+module, a header file called <b><span style="font-style: italic;">modulename</span>.h</b>
+file is generated containing equivalent C declarations for inclusion in
+other C code.<br><br>Any
+C code wanting to make use of these declarations will need to be
+linked, either statically or dynamically, with the extension module.<br><br>If
+the Pyrex module resides within a package, then the name of the .h file
+consists of the full dotted name of the module, e.g. a module called <span style="font-weight: bold;">foo.spam</span> would have
+a header file called <span style="font-weight: bold;">foo.spam.h</span>.
+<h3><a name="C_API_Declarations"></a>C API
+Declarations</h3><p>The other way of making declarations available to C code is to declare them with the <span style="font-family: monospace; font-weight: bold;">api</span>
+keyword. You can use this keyword with C functions and extension types. A header file called "<span style="font-weight: bold;"><span style="font-style: italic;">modulename</span>_api.h</span>"
+is produced containing declarations of the functions and extension types, and a function
+called <span style="font-weight: bold;">import_<span style="font-style: italic;">modulename</span>()</span>.</p><p>C
+code wanting to use these functions or extension types needs to include the header and call
+the import_<span style="font-style: italic;">modulename</span>()
+function. The other functions can then be called and the extension types used as usual.</p><p>Any
+<span style="font-family: monospace;">public</span>
+C type or extension type declarations in the Pyrex module are also made available when you
+include <span style="font-style: italic;">modulename</span>_api.h.</p><table style="text-align: left; width: 100%;" border="0" cellpadding="5" cellspacing="2"><tbody><tr><td style="background-color: rgb(102, 204, 204);"><pre>delorean.pyx</pre></td><td style="background-color: rgb(255, 153, 0);"><pre>marty.c</pre></td></tr><tr><td style="vertical-align: top; background-color: rgb(102, 204, 204);"><pre>cdef public struct Vehicle:<br> int speed<br> float power<br><br>cdef api void activate(Vehicle *v):<br> if v.speed &gt;= 88 \<br> and v.power &gt;= 1.21:<br> print "Time travel achieved"</pre></td><td style="background-color: rgb(255, 153, 0);"><pre>#include "delorean_api.h"<br><br>Vehicle car;<br><br>int main(int argc, char *argv[]) {<br> import_delorean();<br> car.speed = atoi(argv[1]);<br> car.power = atof(argv[2]);&nbsp;<br> activate(&amp;car);<br>}</pre></td></tr></tbody></table><br>Note
+that any types defined in the Pyrex module that are used as argument or
+return types of the exported functions will need to be declared <span style="font-family: monospace;">public</span>,
+otherwise they won't be included in the generated header file, and you
+will get errors when you try to compile a C file that uses the header.<br><br>Using the <span style="font-family: monospace;">api</span> method does not require the C code using the declarations to be linked
+with the extension module in any way, as the Python import machinery is
+used to make the connection dynamically. However, only functions can be
+accessed this way, not variables.<br><br>You can use both <span style="font-family: monospace;">public</span> and <span style="font-family: monospace;">api</span> on the same
+function to make it available by both methods, e.g.<br><pre style="margin-left: 40px;">cdef public api void belt_and_braces():<br> ...<br></pre>However,
+note that you should include <span style="font-weight: bold;">either</span>
+<span style="font-style: italic;">modulename</span>.h
+<span style="font-weight: bold;">or</span> <span style="font-style: italic;">modulename</span>_api.h in
+a given C file, <span style="font-style: italic;">not</span>
+both, otherwise you may get conflicting dual definitions.<br><br>If
+the Pyrex module resides within a package, then:<br><ul><li>The
+name of the header file contains of the full dotted name of the module.</li><li>The
+name of the importing function contains the full name with dots
+replaced by double underscores.</li></ul>E.g. a module
+called <span style="font-weight: bold;">foo.spam</span>
+would have an API header file called <span style="font-weight: bold;">foo.spam_api.h</span> and
+an importing function called <span style="font-weight: bold;">import_foo__spam()</span>.<br><h3><a name="Multiple_public_and_api_declarations"></a>Multiple public and api declarations</h3>You can declare a whole group of items as <span style="font-style: italic;">public</span> and/or <span style="font-style: italic;">api</span> all at once by enclosing them in a cdef block, for example,<br><pre style="margin-left: 40px;">cdef public api:<br> void order_spam(int tons)<br> char *get_lunch(float tomato_size)<br></pre>This can be a useful thing to do in a <span style="font-family: monospace;">.pxd</span> file (see <a href="sharing.html">Sharing Declarations
+Between Pyrex Modules</a>) to make the module's public interface available by all three methods.<br><br><hr style="width: 100%; height: 2px;"><h2><a name="Acquiring_and_Releasing_the_GIL"></a>Acquiring and Releasing the GIL</h2>Pyrex
+provides facilities for releasing the Global Interpreter Lock (GIL)
+before calling C code, and for acquiring the GIL in functions that are
+to be called back from C code that is executed without the GIL.<br><h3>Releasing the GIL</h3>You can release the GIL around a section of code using the<span style="font-family: monospace; font-weight: bold;"> with nogil </span>statement:<br><pre style="margin-left: 40px;">with nogil:<br> &lt;code to be executed with the GIL released&gt;<br></pre>Code in the body of the statement <span style="font-style: italic;">must not manipulate Python objects</span>,
+and must
+not call anything that manipulates Python objects without first
+re-acquiring the GIL. Pyrex attempts to check that these restrictions
+are being followed as far as it can, but it may not catch all possible
+forms of violation<span style="font-weight: bold;"></span>.<br><br>Any external C functions called inside the block must be declared as <span style="font-family: monospace;">nogil</span> (<a href="#nogil">see below</a>).<br><br><span style="font-weight: bold;">Note</span>:
+It may be safe to do some things with Python objects under some
+circumstances. Provided steps are taken (such as adequate locking) to
+ensure that the objects involved cannot be deallocated by Python code
+running in another thread, it is probably safe to access non-Python C
+attributes of an extension type, and to pass references to Python
+objects to another function that is safe to call with the GIL released.<br><br>However, in the absence of such locking, it is not safe to do <span style="font-style: italic;">anything</span> with Python objects with the GIL released -- not even look at them.<br><h3>Acquiring the GIL</h3>A
+C function that is to be used as a callback from C code that is executed
+without the GIL needs to acquire the GIL before it can manipulate
+Python objects. This can be done by specifying<span style="font-family: monospace; font-weight: bold;"> with gil </span>in the function header:<br><pre style="margin-left: 40px;">cdef void my_callback(void *data) with gil:<br> ...<br></pre><h3><a name="nogil"></a>Declaring a function as callable without the GIL</h3>You can specify <span style="font-family: monospace; font-weight: bold;">nogil</span> in a C function header or function type to declare that it is safe to call without the GIL.<br><br><div style="margin-left: 40px;"><span style="font-family: monospace;">cdef extern int swizzle_the_knob() nogil</span><br></div><br>A block of external functions can be declared <span style="font-family: monospace;">nogil</span> at once.<br><br><div style="margin-left: 40px;"><span style="font-family: monospace;">cdef extern from "somewhere.h" nogil:</span><br style="font-family: monospace;"><div style="margin-left: 40px;"><span style="font-family: monospace;">...</span><br></div></div><br>Note that declaring a function <span style="font-family: monospace;">nogil</span> does <span style="font-style: italic;">not</span>
+cause the GIL to be released before calling the function. It simply
+allows the function to be called in situations where the GIL is not
+held.<br><br>You can also declare a function implemented in Pyrex as <span style="font-family: monospace;">nogil</span>.<br><pre style="margin-left: 40px;">cdef void my_gil_free_func(int spam) nogil:<br> ...</pre>Such a function cannot have any Python local variables, it cannot return a
+Python type, and the same restrictions apply to the body of the function as for a<span style="font-family: monospace;"> with nogil </span>block.<br><br>Declaring a function<span style="font-family: monospace;"> with gil </span>also implicitly makes its signature<span style="font-family: monospace;"> nogil</span>.<br><br>
+<hr style="width: 100%; height: 2px;"><span style="font-weight: bold;">Footnotes</span>
+<hr width="100%"><a name="Footnote1"></a>1.
+A problem with const
+could arise if you have something like <blockquote> <pre>cdef extern from "grail.h":<br>&nbsp; char *nun</pre>
+</blockquote> where grail.h actually contains <blockquote>
+<pre>extern const char *nun;</pre> </blockquote> and
+you do <blockquote> <pre>cdef void languissement(char *s):<br>&nbsp; #something that doesn't change s</pre>
+<pre>...</pre> <pre>languissement(nun)</pre> </blockquote>which
+will cause the C compiler to complain. You can work around it by
+casting away the constness: <blockquote> <pre>languissement(&lt;char *&gt;nun)&nbsp; <br></pre>
+</blockquote>---</body></html> \ No newline at end of file
diff --git a/debian/pyrex/pyrex-0.9.9/Doc/Manual/sharing.html b/debian/pyrex/pyrex-0.9.9/Doc/Manual/sharing.html
new file mode 100644
index 00000000..415bdfa1
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Doc/Manual/sharing.html
@@ -0,0 +1,342 @@
+<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
+<html><head>
+
+
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+
+
+ <meta name="GENERATOR" content="Mozilla/4.61 (Macintosh; I; PPC) [Netscape]">
+ <title>Sharing Declarations Between Pyrex Modules</title></head>
+<body>
+
+
+<h1>
+<hr width="100%">Sharing Declarations Between Pyrex Modules
+<hr width="100%"></h1>
+
+ This section describes a new set of facilities introduced in Pyrex 0.8
+for making C declarations, functions and extension types in one Pyrex module available
+for use in another Pyrex module. These facilities are closely modelled on
+the Python import mechanism, and can be thought of as a compile-time version
+of it.
+<h2><a class="mozTocH2" name="mozTocId699652"></a> Contents</h2><ul id="mozToc"><!--mozToc h2 1 h3 2--><li><a href="#mozTocId989010"> Definition and Implementation files</a><ul><li><a href="#mozTocId411233"> What a Definition File contains</a></li><li><a href="#mozTocId20347"> What an Implementation File contains</a></li></ul></li><li><a href="#mozTocId950993"> The <span style="font-family: monospace;">cimport</span> statement</a><ul><li><a href="#mozTocId559554"> Search paths for definition files</a></li><li><a href="#mozTocId478514"> Using <span style="font-family: monospace;">cimport</span> to resolve naming
+ conflicts</a></li></ul></li><li><a href="#mozTocId937218">Sharing C Functions</a></li><li><a href="#mozTocId825278">Sharing Extension Types</a></li><li><a href="#mozTocId144977">Circular cimports</a></li></ul>
+
+
+
+
+
+<h2><a class="mozTocH2" name="mozTocId989010"></a> <a name="DefAndImpFiles"></a>Definition and Implementation files</h2>
+
+ A Pyrex module can be split into two parts: a <i>definition file</i> with
+ a <tt>.pxd</tt> suffix, containing C declarations that are to be available
+ to other Pyrex modules, and an <i>implementation file</i> with a <tt>.pyx</tt>
+suffix, containing everything else. When a module wants to use something
+declared in another module's definition file, it imports it using the <a href="#CImportStatement"><b>cimport</b> statement</a>.
+<h3><a class="mozTocH3" name="mozTocId411233"></a> <a name="WhatDefFileContains"></a>What a Definition File contains</h3>
+
+ A definition file can contain:
+<ul>
+
+ <li> Any kind of C type declaration.</li>
+
+ <li> <b>extern</b> C function or variable declarations.</li><li>Declarations of C functions defined in the module.</li>
+
+ <li> The definition part of an extension type (<a href="#SharingExtensionTypes">see below</a>).</li>
+
+
+</ul>
+
+ It cannot contain any non-extern C variable declarations.
+<p>It cannot contain the implementations of any C or Python functions, or
+any Python class definitions, or any executable statements. </p>
+
+
+<blockquote>NOTE: You don't need to (and shouldn't) declare anything in a
+declaration file <b>public</b> in order to make it available to other Pyrex
+modules; its mere presence in a definition file does that. You only need a
+public declaration if you want to make something available to external C code.</blockquote>
+
+
+<h3><a class="mozTocH3" name="mozTocId20347"></a> <a name="WhatImpFileContains"></a>What an Implementation File contains</h3>
+
+ An implementation file can contain any kind of Pyrex statement, although
+ there are some restrictions on the implementation part of an extension type
+if the corresponding definition file also defines that type (see below).
+
+<h2><a class="mozTocH2" name="mozTocId950993"></a> <a name="CImportStatement"></a>The <tt>cimport</tt> statement</h2>
+
+ The <b>cimport</b> statement is used in a definition or implementation
+file to gain access to names declared in another definition file. Its syntax
+exactly parallels that of the normal Python import statement:
+<blockquote><tt>cimport </tt><i>module</i><tt> [, </tt><i>module</i><tt>...]</tt></blockquote>
+
+
+<blockquote><tt>from </tt><i>module</i><tt> cimport </tt><i>name</i><tt>
+[as </tt><i>name</i><tt>] [, </tt><i>name</i><tt> [as </tt><i>name</i><tt>]
+ ...]</tt></blockquote>
+
+ Here is an example. The file on the left is a definition file which exports
+ a C data type. The file on the right is an implementation file which imports
+ and uses it. <br>
+
+ &nbsp;
+<table cellpadding="5" cols="2" width="100%">
+
+ <tbody>
+
+ <tr>
+
+ <td bgcolor="#ffcc00" width="40%"><b><tt>dishes.pxd</tt></b></td>
+
+ <td bgcolor="#5dbaca"><b><tt>restaurant.pyx</tt></b></td>
+
+ </tr>
+
+ <tr align="left" valign="top">
+
+ <td bgcolor="#ffcc18" width="40%"><tt>cdef enum otherstuff:</tt> <br>
+
+ <tt>&nbsp;&nbsp;&nbsp; sausage, eggs, lettuce</tt>
+ <p><tt>cdef struct spamdish:</tt> <br>
+
+ <tt>&nbsp;&nbsp;&nbsp; int oz_of_spam</tt> <br>
+
+ <tt>&nbsp;&nbsp;&nbsp; otherstuff filler</tt></p>
+
+ </td>
+
+ <td bgcolor="#5dbaca"><tt>cimport dishes</tt> <br>
+
+ <tt>from dishes cimport spamdish</tt>
+ <p><tt>cdef void prepare(spamdish *d):</tt> <br>
+
+ <tt>&nbsp;&nbsp;&nbsp; d.oz_of_spam = 42</tt> <br>
+
+ <tt>&nbsp;&nbsp;&nbsp; d.filler = dishes.sausage</tt> </p>
+
+
+ <p><tt>def serve():</tt> <br>
+
+ <tt>&nbsp;&nbsp;&nbsp; cdef spamdish d</tt> <br>
+
+ <tt>&nbsp;&nbsp;&nbsp; prepare(&amp;d)</tt> <br>
+
+ <tt>&nbsp;&nbsp;&nbsp; print "%d oz spam, filler no. %d" % \</tt>
+ <br>
+
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (d.oz_of_spam,
+ d.filler)</tt></p>
+
+ </td>
+
+ </tr>
+
+
+ </tbody>
+</table>
+
+
+<p>It is important to understand that the <b>cimport</b> statement can <i>only</i>
+be used to import C data types, C functions and variables, and extension
+types. It cannot be used to import any Python objects, and (with one exception)
+it doesn't imply any Python import at run time. If you want to refer to any
+Python names from a module that you have cimported, you will have to include
+a regular <b>import</b> statement for it as well. </p>
+
+
+<p>The exception is that when you use <b>cimport</b> to import an extension
+ type, its type object is imported at run time and made available by the
+name under which you imported it. Using <b>cimport</b> to import extension
+types is covered in more detail <a href="#SharingExtensionTypes">below</a>.
+</p>
+
+
+<h3><a class="mozTocH3" name="mozTocId559554"></a> <a name="SearchPaths"></a>Search paths for definition files</h3>
+
+ When you <b>cimport</b> a module called <tt>modulename</tt>, the Pyrex
+compiler searches for a file called <tt>modulename.pxd</tt> along the search
+path for include files, as specified by <b>-I</b> command line options.
+<p>Also, whenever you compile a file <tt>modulename.pyx</tt>, the corresponding
+ definition file <tt>modulename.pxd</tt> is first searched for along the
+same path, and if found, it is processed before processing the <tt>.pyx</tt>
+file. </p>
+
+
+<h3><a class="mozTocH3" name="mozTocId478514"></a> <a name="ResolvingNamingConflicts"></a>Using cimport to resolve naming
+ conflicts</h3>
+
+ The cimport mechanism provides a clean and simple way to solve the problem
+ of wrapping external C functions with Python functions of the same name.
+All you need to do is put the extern C declarations into a .pxd file for
+an imaginary module, and cimport that module. You can then refer to the C
+functions by qualifying them with the name of the module. Here's an example:
+<br>
+
+ &nbsp;
+<table cellpadding="5" cols="2" width="100%">
+
+ <tbody>
+
+ <tr>
+
+ <td bgcolor="#ffcc00" width="50%"><b><tt>c_lunch.pxd</tt></b></td>
+
+ <td bgcolor="#5dbaca"><b><tt>lunch.pyx</tt></b></td>
+
+ </tr>
+
+ <tr align="left" valign="top">
+
+ <td bgcolor="#ffcc18" width="50%"><tt>cdef extern from "lunch.h":</tt>
+ <br>
+
+ <tt>&nbsp;&nbsp;&nbsp; void eject_tomato(float)</tt></td>
+
+ <td bgcolor="#5dbaca"><tt>cimport c_lunch</tt>
+ <p><tt>def eject_tomato(float speed):</tt> <br>
+
+ <tt>&nbsp;&nbsp;&nbsp; c_lunch.eject_tomato(speed)</tt></p>
+
+ </td>
+
+ </tr>
+
+
+ </tbody>
+</table>
+
+
+<p>You don't need any <tt>c_lunch.pyx</tt> file, because the only things
+defined in <tt>c_lunch.pxd</tt> are extern C entities. There won't be any
+actual <tt>c_lunch</tt> module at run time, but that doesn't matter; the <tt>c_lunch.pxd</tt> file has done its job of providing an additional namespace at compile time.</p><h2><a class="mozTocH2" name="mozTocId937218"></a><a name="Sharing_C_Functions"></a>Sharing C Functions</h2><p>C
+functions defined at the top level of a module can be made available
+via cimport by putting headers for them in the .pxd file, for example,</p><table style="text-align: left; width: 100%;" border="0" cellpadding="5" cellspacing="2"><tbody><tr><td style="font-weight: bold; background-color: rgb(255, 204, 0);"><pre>volume.pxd</pre></td><td style="font-weight: bold; background-color: rgb(93, 186, 202);"><pre>spammery.pyx</pre></td></tr><tr><td style="vertical-align: top; background-color: rgb(255, 204, 0);"><pre>cdef float cube(float)</pre></td><td style="background-color: rgb(93, 186, 202);" colspan="1" rowspan="3"><pre>from volume cimport cube<br><br>def menu(description, size):<br>&nbsp; &nbsp; print description, ":", cube(size), \<br> "cubic metres of spam"<br><br>menu("Entree", 1)<br>menu("Main course", 3)<br>menu("Dessert", 2)</pre></td></tr><tr style="font-weight: bold;"><td style="vertical-align: top; background-color: rgb(153, 204, 51); height: 1px;"><pre>volume.pyx</pre></td></tr><tr><td style="vertical-align: top; background-color: rgb(153, 204, 51);"><pre>cdef float cube(float x):<br>&nbsp; &nbsp; return x * x * x</pre></td></tr></tbody></table><br><h2><a class="mozTocH2" name="mozTocId825278"></a><a name="Sharing_Extension_Types"></a>Sharing Extension Types</h2>
+
+ An extension type can be made available via cimport by splitting its definition into two parts, one in
+a definition file and the other in the corresponding implementation file.
+<br>
+
+ <br>
+
+ The definition part of the extension type can only declare C attributes
+and C methods, not Python methods, and it must declare <i>all</i> of that
+type's C attributes and C methods.<br>
+
+ <br>
+
+ The implementation part must implement all of the C methods declared in
+the definition part, and may not add any further C attributes or methods. It may also
+define Python methods.
+<p>Here is an example of a module which defines and exports an extension
+type, and another module which uses it. <br>
+
+ &nbsp;
+<table cellpadding="5" cols="2" width="100%">
+
+ <tbody>
+
+ <tr>
+
+ <td bgcolor="#ffcc18" width="30%"><b><tt>Shrubbing.pxd</tt></b></td>
+
+ <td bgcolor="#5dbaca" width="50%"><b><tt>Shrubbing.pyx</tt></b></td>
+
+ </tr>
+
+ <tr align="left" valign="top">
+
+ <td bgcolor="#ffcc18" width="30%"><tt>cdef class Shrubbery:</tt> <br>
+
+ <tt>&nbsp;&nbsp;&nbsp; cdef int width</tt> <br>
+
+ <tt>&nbsp;&nbsp;&nbsp; cdef int length</tt></td>
+
+ <td bgcolor="#5dbaca" width="50%"><tt>cdef class Shrubbery:</tt> <br>
+
+ <tt>&nbsp;&nbsp;&nbsp; def __cinit__(self, int w, int l):</tt> <br>
+
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.width = w</tt>
+ <br>
+
+ <tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.length = l</tt>
+
+ <p><tt>def standard_shrubbery():</tt> <br>
+
+ <tt>&nbsp;&nbsp;&nbsp; return Shrubbery(3, 7)</tt></p>
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td colspan="2" bgcolor="#8cbc1c" width="30%"><b><tt>Landscaping.pyx</tt></b></td>
+
+ </tr>
+
+ <tr>
+
+ <td colspan="2" bgcolor="#99cc00" width="30%"><tt>cimport Shrubbing</tt>
+ <br>
+
+ <tt>import Shrubbing</tt>
+ <p><tt>cdef Shrubbing.Shrubbery sh</tt> <br>
+
+ <tt>sh = Shrubbing.standard_shrubbery()</tt> <br>
+
+ <tt>print "Shrubbery size is %d x %d" % (sh.width, sh.length)</tt>
+ <br>
+
+ &nbsp;</p>
+
+ </td>
+
+ </tr>
+
+
+ </tbody>
+</table>
+
+ </p>
+
+
+<p>Some things to note about this example: </p>
+
+
+<ul>
+
+ <li> There is a <tt>cdef</tt> <tt>class</tt> <tt>Shrubbery</tt> declaration in both Shrubbing.pxd
+ and Shrubbing.pyx. When the Shrubbing module is compiled, these two declarations
+ are combined into one.</li>
+
+
+ &nbsp; <li> In Landscaping.pyx, the <tt>cimport</tt> <tt>Shrubbing</tt> declaration
+allows us to refer to the Shrubbery type as <tt>Shrubbing.Shrubbery</tt>.
+But it doesn't bind the name <tt>Shrubbing</tt> in Landscaping's module namespace
+ at run time, so to access <tt>Shrubbing.standard_shrubbery</tt> we also
+need to <tt>import</tt> <tt>Shrubbing</tt>.</li>
+
+
+</ul>If you are exporting an extension type that has a base class, the
+base class must be declared in the definition part. Repeating the base
+class in the implementation part is not necessary, but if you do, it
+must match the base class in the definition part.<h2><a class="mozTocH2" name="mozTocId144977"></a><a name="CircularCImports"></a>Circular cimports</h2>If
+you have two structs, unions or extension types defined in different
+.pxd files, and they need to refer to each other, there is a potential
+for problems with circular imports. These problems can be avoided by
+placing forward declarations of all the structs, unions and extension
+types defined in the .pxd file <span style="font-style: italic;">before</span> the first <span style="font-family: monospace;">cimport</span> statement.<br><br>For example:<br><br><table style="text-align: left; margin-left: 40px;" border="1" cellpadding="5" cellspacing="2"><tbody><tr><td style="vertical-align: top; white-space: nowrap; text-align: left; background-color: rgb(255, 204, 24); font-family: monospace;">foo.pxd</td><td style="vertical-align: top; white-space: nowrap; text-align: left; background-color: rgb(255, 204, 24); font-family: monospace;">blarg.pxd</td></tr><tr><td style="vertical-align: top; white-space: nowrap; text-align: left; font-family: monospace; background-color: rgb(255, 204, 24);">cdef struct Spam<br><br>from blarg cimport Eggs<br><br>cdef struct Spam:<br>&nbsp;&nbsp;&nbsp;&nbsp;Eggs *eggs</td><td style="vertical-align: top; white-space: nowrap; text-align: left; background-color: rgb(255, 204, 24); font-family: monospace;">cdef struct Eggs<br><br>from foo cimport Spam<br><br>cdef struct Eggs:<br>&nbsp;&nbsp;&nbsp;&nbsp;Spam *spam</td></tr></tbody></table><br>If
+the forward declarations weren't present, a circular import problem
+would occur, analogous to that which arises in Python when two modules
+try to import names from each
+other. Placing the forward declarations before the <span style="font-family: monospace;">cimport</span> statements ensures that all type names are known to the Pyrex compiler sufficiently far in advance.<br><br>Note
+that any .pyx file is free to cimport anything it wants from any .pxd
+file without needing this precaution. It's only when two .pxd files
+import each other that circular
+import issues arise. <hr width="100%">Back to the <a href="overview.html">Language Overview</a>
+<br>
+
+ <br>
+
+</body></html> \ No newline at end of file
diff --git a/debian/pyrex/pyrex-0.9.9/Doc/Manual/source_files.html b/debian/pyrex/pyrex-0.9.9/Doc/Manual/source_files.html
new file mode 100644
index 00000000..0d47fdeb
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Doc/Manual/source_files.html
@@ -0,0 +1,78 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"><title>Source Files and Compilation</title></head>
+<body>
+<h1>
+<hr style="width: 100%; height: 2px;">
+Source
+Files and Compilation
+<hr style="width: 100%; height: 2px;">
+</h1><ul id="mozToc"><!--mozToc h2 1 h3 2--><li><a href="#mozTocId581403">File Names and Extensions</a></li><li><a href="#mozTocId146379">Modules in Packages</a></li><li><a href="#mozTocId431365">Building an Extension</a><ul><li><a href="#mozTocId233830">Command Line</a></li><li><a href="#mozTocId49372">Calling the Pyrex compiler from Python</a></li><li><a href="#mozTocId11953">Using the distutils extension</a></li></ul></li><li><a href="#mozTocId559484">Distributing Pyrex modules</a></li></ul><h2><a class="mozTocH2" name="mozTocId581403"></a>File Names and Extensions</h2>Pyrex
+source file names consist of the name of the module followed by a <span style="font-family: monospace;">.pyx</span> extension,
+for example a module called <span style="font-family: monospace;">primes</span>
+would have a source file named <span style="font-family: monospace;">primes.pyx</span>.<br><h2><a class="mozTocH2" name="mozTocId146379"></a>Modules in Packages</h2>If
+your module is destined to live in a package, the Pyrex compiler needs
+to know the fully-qualified name that the module will eventually have.<br><br>There are currently two ways to give it this information:<br><ol><li>Name the source file with the full dotted name of the module. For
+example, a module called <span style="font-family: monospace;">primes</span> to be installed in a package called <span style="font-family: monospace;">numbers</span> would
+have a source file called <span style="font-family: monospace;">numbers.primes.pyx</span>.<br><br></li><li>Place the source file in a <span style="font-style: italic;">package directory</span>. To Pyrex, a package directory is one that contains a file called either <span style="font-family: monospace;">__init__.py</span> or <span style="font-family: monospace;">__init__.pyx</span>. For example, a package called <span style="font-family: monospace;">numbers</span> containing a module called <span style="font-family: monospace;">primes</span> would have the source files laid out like this:</li></ol><div style="margin-left: 80px;"><span style="font-family: monospace;">numbers</span><br style="font-family: monospace;"><div style="margin-left: 40px;"><span style="font-family: monospace;">__init__.py</span><br style="font-family: monospace;"><span style="font-family: monospace;">primes.pyx</span><br></div></div><br>This will ensure that the __name__ properties of the module and any
+classes defined in it are set correctly. If you don't do this, you may
+find that pickling doesn't work, among other problems. It also ensures
+that the Pyrex compiler has the right idea about the layout of the
+module namespace, which can be important when accessing extension types
+defined in other modules.<br>
+<h2><a class="mozTocH2" name="mozTocId431365"></a>Building an Extension</h2>There are two steps involved in creating an extension module from Pyres sources:<br><ol><li>Use the Pyrex compiler to translate the .pyx file into a .c file.</li><li>Compile the .c file with a C compiler and link it with whatever libraries it needs, to produce an extension module.</li></ol>There
+are a variety of ways of accomplishing these steps, either separately
+or together. One way is to compile the Pyrex source manually from the
+command line
+with the Pyrex compiler, e.g.<br>
+<br><div style="margin-left: 40px;"><span style="font-family: monospace;">pyrexc -r primes.pyx</span><br>
+</div><br>
+This will compile <span style="font-family: monospace;">primes.pyx</span>
+and any other source files that it depends on, if any of them have
+changed since the last compilation, and produce a file called <span style="font-family: monospace;">primes.c</span>,
+which then needs to be compiled with the C compiler using whatever
+options are appropriate on your platform for generating an extension
+module.<br><br>You
+can perform the C compilation using distutils and a <span style="font-family: monospace;">setup.py</span> file, or with a conventional
+Makefile. There's a Makefile in the Demos directory (called <span style="font-family: monospace;">Makefile.nodistutils</span>)
+that shows how to do this for Linux.<br><br>Another approach is to put code at the beginning of your <span style="font-family: monospace;">setup.py</span> file to import the Pyrex compiler and call it from Python. You can then follow this with a normal call to <span style="font-family: monospace;">setup()</span> to compile the resulting .c files.<br>
+<br>You can also perform both steps at once in a <span style="font-family: monospace;">setup.py</span> file using the distutils
+extension provided with Pyrex. See the <span style="font-family: monospace;">Setup.py</span>
+file in the <span style="font-family: monospace;">Demos</span>
+directory for an example of how to use it. A disadvantage of this
+method is that you won't be able to take advantage of Pyrex's own
+dependency checking features to compile only the Pyrex sources which
+have changed.<br><h3><a class="mozTocH3" name="mozTocId233830"></a>Command Line</h3>You can run the Pyrex compiler from the command line using either the <span style="font-family: monospace;">pyrexc</span> shell command or the Python version of it, <span style="font-family: monospace;">pyrexc.py</span>.<br><br>The following command line options exist:<br><br><table style="text-align: left; margin-left: 40px;" border="1" cellpadding="2" cellspacing="2"><tbody><tr><td style="font-weight: bold;" align="left" nowrap="nowrap" valign="top">Short</td><td style="font-weight: bold;" align="left" nowrap="nowrap" valign="top">Long</td><td style="font-weight: bold;" align="left" nowrap="nowrap" valign="top">Description</td></tr><tr><td align="left" nowrap="nowrap" valign="top">-v</td><td align="left" nowrap="nowrap" valign="top">--version</td><td align="left" nowrap="nowrap" valign="top">Display the version number of the Pyrex compiler</td></tr><tr><td align="left" nowrap="nowrap" valign="top">-l</td><td align="left" nowrap="nowrap" valign="top">--create-listing</td><td align="left" nowrap="nowrap" valign="top">Produces a .lis file for each compiled .pyx file containing error messages</td></tr><tr><td align="left" nowrap="nowrap" valign="top">-I</td><td align="left" nowrap="nowrap" valign="top">--include-dir</td><td style="vertical-align: top; text-align: left; width: 200px;">Specifies
+a directory to be searched for included files and top-level package
+directories. Multiple -I options may be given, each specifying one
+directory.</td></tr><tr><td align="left" nowrap="nowrap" valign="top">-o</td><td align="left" nowrap="nowrap" valign="top">--output-file</td><td style="vertical-align: top; text-align: left; width: 200px;">Specifies name of generated C file. Only meaningful when a single .pyx file is being compiled.</td></tr><tr><td align="left" nowrap="nowrap" valign="top">-r</td><td align="left" nowrap="nowrap" valign="top">--recursive</td><td style="vertical-align: top; text-align: left; width: 200px;">Compile the given .pyx files, plus those of any modules it depends on directly or indirectly via <a href="sharing.html#CImportStatement">cimport</a> statements. The include path specified by -I options is used to find the .pyx files of dependent modules.</td></tr><tr><td align="left" nowrap="nowrap" valign="top">-t</td><td align="left" nowrap="nowrap" valign="top">--timestamps</td><td style="vertical-align: top; text-align: left; width: 200px;">Use
+modification times of files to decide whether to compile a .pyx file.
+This is the default when -r is used, unless -f is also used.</td></tr><tr><td align="left" nowrap="nowrap" valign="top">-f</td><td align="left" nowrap="nowrap" valign="top">--force</td><td style="vertical-align: top; text-align: left; width: 200px;">Compile all .pyx files regardless of modification times. This is the default when -r is not given.</td></tr><tr><td align="left" nowrap="nowrap" valign="top">-q</td><td align="left" nowrap="nowrap" valign="top">--quiet</td><td style="vertical-align: top; text-align: left; width: 200px;">When -r is given, don't display the names of source files being compiled.</td></tr></tbody></table><br><h3><a class="mozTocH3" name="mozTocId49372"></a>Calling the Pyrex compiler from Python</h3>The module <span style="font-family: monospace;">Pyrex.Compiler.Main</span> exports the following classes and functions to facilitate invoking the compiler from another Python program.<br><br><span style="font-family: monospace;">compile(</span><span style="font-style: italic;">source</span> [, <span style="font-style: italic;">options</span>] [, <span style="font-style: italic;">&nbsp;option</span>&nbsp; =&nbsp;<span style="font-style: italic;">value</span> ]...<span style="font-family: monospace;">)</span><br><br><div style="margin-left: 40px;">Compiles one or more Pyrex source files, which should be <span style="font-family: monospace;">.pyx</span> files. The <span style="font-style: italic;">source</span> argument may be either a single filename or a list of filenames.<br><br>Depending on the <span style="font-family: monospace;">recursive</span>&nbsp;option,
+it may compile just the specified source files, or the specified source
+files plus those of other modules that they depend on via <span style="font-style: italic;">cimport</span> statements. The options may be given either as keyword arguments or a <span style="font-family: monospace;">CompilationOptions</span> instance. If both are used, keyword arguments take precedence.<br><br>The return value depends on whether a list of sources was specifed and whether the <span style="font-family: monospace;">recursive</span> option is in effect. If a single source file is specified and the <span style="font-family: monospace;">recursive</span> option is false, the return value is a <span style="font-family: monospace;">CompilationResult</span> instance. Otherwise, the return value is a&nbsp;<span style="font-family: monospace;">CompilationResultSet</span><span style="font-family: monospace;"></span> containing a <span style="font-family: monospace;">CompilationResult</span>
+for each of the modules which were actually compiled (which may or may
+not include ones corresponding to the specified source files).<br><br>Note:
+If you have more than one source file to compile, it is more efficient
+to do so with a single call to compile rather than one call for each
+source file. This is because, if more than one source cimports the same
+.pxd file, the .pxd file&nbsp;is parsed only once instead of being
+parsed each time it is cimported.<br></div><br><span style="font-family: monospace;">compile_single(</span><span style="font-style: italic;">source_path</span> [, <span style="font-style: italic;">options</span>] [, <span style="font-style: italic;">&nbsp;option</span>&nbsp; =&nbsp;<span style="font-style: italic;">value</span> ]...<span style="font-family: monospace;">)</span><br><br><div style="margin-left: 40px;">Compiles just a single .pyx source file, specified as a string, with no dependency or timestamp checking (the <span style="font-family: monospace;">recursive</span> and <span style="font-family: monospace;">timestamps</span> options are ignored). Always returns a <span style="font-family: monospace;">CompilationResult</span>.</div><span style="font-family: monospace;"><br></span><span style="font-family: monospace;">compile_multiple(</span><span style="font-style: italic;">source_list</span> [, <span style="font-style: italic;">options</span>] [, <span style="font-style: italic;">&nbsp;option</span>&nbsp; =&nbsp;<span style="font-style: italic;">value</span> ]...<span style="font-family: monospace;">)</span><br><br><div style="margin-left: 40px;">Compiles
+a list of .pyx source files, with optional dependency and timestamp
+checking as for compile. Always takes a list of source pathnames, and
+always returns a <span style="font-family: monospace;">CompilationResultSet</span>.</div><span style="font-family: monospace;"><br>class CompilationOptions</span><br><br><div style="margin-left: 40px;">A collection of options to be passed to the <span style="font-family: monospace;">compile()</span> function. The following options may be specified as keyword arguments to either the <span style="font-family: monospace;">CompilationOptions</span> constructor or the <span style="font-family: monospace;">compile()</span> function.<br></div><div style="margin-left: 80px;"><dl><dt style="font-family: monospace;">show_version</dt><dd>Display the version number of the Pyrex compiler.<br></dd><dt style="font-family: monospace;">use_listing_file</dt><dd>Produce a .lis file for each .pyx file containing compilation errors.<br></dd><dt style="font-family: monospace;">include_path</dt><dd>A list of directories to search for included files and top-level package directories.<br></dd><dt style="font-family: monospace;">output_file</dt><dd>Use the given name for the generated .c file (only in non-recursive mode).<br></dd><dt style="font-family: monospace;">recursive</dt><dd>Compile the .pyx files of any cimported modules in addition to the one specified.<br></dd><dt style="font-family: monospace;">timestamps</dt><dd>Only
+compile modified sources as determined by file modification times. This
+may be true, false or None. If None, timestamps are used if and only if
+recursive mode is in effect.<br></dd><dt style="font-family: monospace;">quiet</dt><dd>Don't display names of sources being compiled in recursive mode.</dd></dl></div><span style="font-family: monospace;">class CompilationResult</span><br><br><div style="margin-left: 40px;">An object providing information about the result of compiling a .pyx file. It has the following attributes:<br></div><div style="margin-left: 80px;"><dl><dt style="font-family: monospace;">c_file</dt><dd>Pathname of the generated C source file.<br></dd><dt style="font-family: monospace;">h_file</dt><dd>Pathname of the generated C header file, if any.<br></dd><dt style="font-family: monospace;">api_file</dt><dd>Pathname of the generated C API header file, if any.<br></dd><dt style="font-family: monospace;">listing_file</dt><dd>Pathname of the generated error message file, if any.<br></dd><dt style="font-family: monospace;">num_errors</dt><dd>Number of compilation errors.</dd></dl></div><span style="font-family: monospace;">class CompilationResultSet</span><div style="margin-left: 40px;"></div><div style="margin-left: 40px;">This is a mapping object whose keys are the pathnames of .pyx files and whose values are the corresponding <span style="font-family: monospace;">CompilationResult</span> instances. It also has the following additional attributes:<br><dl style="margin-left: 40px;"><dt style="font-family: monospace;">num_errors</dt><dd>Total number of compilation errors.</dd></dl></div><h3><a class="mozTocH3" name="mozTocId11953"></a>Using the distutils extension</h3>The
+distutils extension provided with Pyrex allows you to pass .pyx files
+directly to the Extension constructor in your setup file.<br><br>To use it, you need to put the following at the top of your setup.py file:<br><br><div style="margin-left: 40px; font-family: monospace;">from Pyrex.Distutils.extension import Extension<br>from Pyrex.Distutils import build_ext<br></div><br>and you need to specify the Pyrex version of the build_ext command class in your setup() call:<br><br><div style="margin-left: 40px; font-family: monospace;">setup(<br>&nbsp;&nbsp;&nbsp; ...<br>&nbsp;&nbsp;&nbsp; cmdclass = {'build_ext': build_ext}<br>)<br></div><br>Using
+the distutils extension is not currently recommended, because it's
+unable to automatically find cimported modules or check the timestamps
+of .pxd files and included sources. It also makes it harder to turn off
+the use of Pyrex for people who are only installing your module and not
+modifying the sources.<br><h2><a class="mozTocH2" name="mozTocId559484"></a>Distributing Pyrex modules</h2>It
+is strongly recommended that you distribute the generated .c files as
+well as your Pyrex sources, so that users can install your module
+without needing to have Pyrex available.<br><br>It is also recommended that Pyrex compilation <span style="font-style: italic;">not</span>
+be enabled by default in the version you distribute. Even if the user
+has Pyrex installed, he probably doesn't want to use it just to install
+your module. Also, the version he has may not be the same one you used,
+and may not compile your sources correctly.<br><br>---<br></body></html> \ No newline at end of file
diff --git a/debian/pyrex/pyrex-0.9.9/Doc/Manual/special_methods.html b/debian/pyrex/pyrex-0.9.9/Doc/Manual/special_methods.html
new file mode 100644
index 00000000..087c51d7
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Doc/Manual/special_methods.html
@@ -0,0 +1,1124 @@
+<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
+<html><head>
+
+
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+
+
+ <meta name="GENERATOR" content="Mozilla/4.61 (Macintosh; I; PPC) [Netscape]">
+ <title>Special Methods of Extenstion Types</title></head>
+<body>
+
+
+<h1>
+<hr width="100%">Special Methods of Extension Types
+<hr width="100%"></h1>
+
+ This page describes the special methods currently supported by Pyrex extension
+ types. A complete list of all the special methods appears in the table at
+the bottom. Some of these methods behave differently from their Python counterparts
+or have no direct Python counterparts, and require special mention.
+<p><span style="font-weight: bold;">Note:</span><i> Everything said on this page applies only to </i><span style="font-weight: bold;">extension</span><i style="font-weight: bold;">
+</i><span style="font-weight: bold;">types</span><i>, defined with the </i><span style="font-weight: bold; font-family: monospace;">cdef</span> <span style="font-weight: bold; font-family: monospace;">class</span><i> statement. It doesn't apply
+to classes defined with the Python </i><span style="font-family: monospace;">class</span> <i>statement, where the normal
+ Python rules apply.</i> </p>
+
+
+<h2><small>Declaration</small></h2>
+Special methods of extension types must be declared with <span style="font-family: monospace; font-weight: bold;">def</span>, <span style="font-style: italic;">not</span> <span style="font-family: monospace;">cdef</span>.<br>
+
+<h2><font size="+1">Docstrings</font></h2>
+
+
+ Currently, docstrings are not fully supported in special methods of extension
+ types. You can place a docstring in the source to serve as a comment, but
+ it won't show up in the corresponding <span style="font-family: monospace;">__doc__</span> attribute at run time. (This
+ is a Python limitation -- there's nowhere in the PyTypeObject data structure
+ to put such docstrings.)
+<h2> <font size="+1">Initialisation methods: <tt>__cinit__</tt> and <tt>__init__</tt></font></h2>
+
+ There are two methods concerned with initialising the object<tt>.</tt>
+<p>The <b><tt>__cinit__</tt></b> method is where you should perform basic C-level
+initialisation of the object, including allocation of any C data structures
+that your object will own. You need to be careful what you do in the __cinit__
+method, because the object may not yet be a valid Python object when it is
+called. Therefore, you must not invoke any Python operations which might touch
+the object; in particular, do not try to call any of its methods. </p>
+
+
+<p>By the time your <tt>__cinit__</tt> method is called, memory has been allocated for the object
+and any C attributes it has have been initialised to 0 or null. (Any Python
+attributes have also been initialised to <tt>None</tt>, but you probably shouldn't
+rely on that.) Your <tt>__cinit__</tt> method is guaranteed to be called exactly
+once.<br>
+
+<br>
+
+If your extension type has a base type, the <tt>__cinit__</tt> method of the
+base type is automatically called <i>before</i> your <tt>__cinit__</tt> method
+is called; you cannot explicitly call the inherited <tt>__cinit__</tt> method.
+If you need to pass a modified argument list to the base type, you will have
+to do the relevant part of the initialisation in the <tt>__init__</tt> method
+instead (where the normal rules for calling inherited methods apply).<br>
+
+ </p>
+
+
+
+
+
+<p>Any initialisation which cannot safely be done in the <tt>__cinit__</tt>
+method should be done in the <b><tt>__init__</tt></b> method. By the time
+ <tt>__init__</tt> is called, the object is a fully valid Python object and
+all operations are safe. Under some circumstances it is possible for <tt>__init__</tt>
+to be called more than once or not to be called at all, so your other methods
+ should be designed to be robust in such situations. </p>
+
+
+<p>Any arguments passed to the constructor will be passed
+ to both the <tt>__cinit__</tt> method and the <tt>__init__</tt> method.
+If you anticipate subclassing your extension type in Python, you may find
+it useful to give the <tt>__cinit__</tt> method * and ** arguments so that
+it can accept and ignore extra arguments. Otherwise, any Python subclass
+which has an <tt>__init__</tt> with a different signature will have to override <tt>__new__</tt> as well as <tt>__init__</tt>, which the writer of a Python
+class wouldn't expect to have to do. </p>
+
+
+<h2> <font size="+1">Finalization method: <tt>__dealloc__</tt><tt></tt></font></h2>
+
+ The counterpart to the <tt>__cinit__</tt> method is the <b><tt>__dealloc__</tt></b>
+method, which should perform the inverse of the <tt>__cinit__</tt> method.
+Any C data structures that you allocated in your <tt>__cinit__</tt> method
+should be freed in your <tt>__dealloc__</tt> method.
+<p>You need to be careful what you do in a <tt>__dealloc__</tt> method. By
+the time your <tt>__dealloc__</tt> method is called, the object may already
+have been partially destroyed and may not be in a valid state as far as Python
+is concerned, so you should avoid invoking any Python operations which might
+touch the object. In particular, don't call any other methods of the object
+or do anything which might cause the object to be resurrected. It's best if
+you stick to just deallocating C data. </p>
+
+
+<p>You don't need to worry about deallocating Python attributes of your object,
+because that will be done for you by Pyrex after your <tt>__dealloc__</tt>
+method returns.<br>
+
+ <br>
+
+ <b>Note:</b> There is no <tt>__del__</tt> method for extension types.<br>
+
+ </p>
+
+
+<h2><font size="+1">Arithmetic methods</font></h2>
+
+ Arithmetic operator methods, such as <tt>__add__</tt>, behave differently
+ from their Python counterparts. There are no separate "reversed" versions
+ of these methods (<tt>__radd__</tt>, etc.) Instead, if the first operand
+cannot perform the operation, the <i>same</i> method of the second operand
+is called, with the operands in the <i>same order</i>.
+<p>This means that you can't rely on the first parameter of these methods
+ being "self", and you should test the types of <span style="font-weight: bold;">both</span> operands before deciding
+ what to do. If you can't handle the combination of types you've been given,
+ you should return <tt>NotImplemented</tt>. </p>
+
+
+<p>This also applies to the in-place arithmetic method <tt>__ipow__</tt>.
+ It doesn't apply to any of the <i>other</i> in-place methods (<tt>__iadd__</tt>,
+ etc.) which always take self as the first argument. </p><h2><font size="+1">Rich comparisons</font></h2>
+
+ There are no separate methods for the individual rich comparison operations
+ (<tt>__eq__</tt>, <tt>__le__</tt>, etc.) Instead there is a single method
+ <tt>__richcmp__</tt> which takes an integer indicating which operation is
+to be performed, as follows:
+<ul>
+
+
+ <ul>
+
+ &nbsp;
+ <table nosave="" border="0" cellpadding="5" cellspacing="0">
+
+ <tbody>
+
+ <tr nosave="">
+
+ <td nosave="" bgcolor="#ffcc33" width="30">
+ <div align="right">&lt;</div>
+
+ </td>
+
+ <td nosave="" bgcolor="#66ffff" width="30">0</td>
+
+ <td><br>
+
+ </td>
+
+ <td nosave="" bgcolor="#ffcc33" width="30">
+ <div align="right">==</div>
+
+ </td>
+
+ <td nosave="" bgcolor="#66ffff" width="30">2</td>
+
+ <td><br>
+
+ </td>
+
+ <td nosave="" bgcolor="#ffcc33" width="30">
+ <div align="right">&gt;</div>
+
+ </td>
+
+ <td nosave="" bgcolor="#66ffff" width="30">4</td>
+
+ </tr>
+
+ <tr nosave="">
+
+ <td nosave="" bgcolor="#ffcc33">
+ <div align="right">&lt;=</div>
+
+ </td>
+
+ <td nosave="" bgcolor="#66ffff">1</td>
+
+ <td><br>
+
+ </td>
+
+ <td nosave="" bgcolor="#ffcc33">
+ <div align="right">!=</div>
+
+ </td>
+
+ <td nosave="" bgcolor="#66ffff">3</td>
+
+ <td><br>
+
+ </td>
+
+ <td nosave="" bgcolor="#ffcc33">
+ <div align="right">&gt;=</div>
+
+ </td>
+
+ <td nosave="" bgcolor="#66ffff">5</td>
+
+ </tr>
+
+
+ </tbody>
+ </table>
+
+
+ </ul>
+
+
+</ul>
+
+
+<h2> <font size="+1">The __next__ method</font></h2>
+
+ Extension types wishing to implement the iterator interface should define
+ a method called <b><tt>__next__</tt></b>, <i>not</i> <tt>next</tt>. The Python
+ system will automatically supply a <tt>next</tt> method which calls your
+<span style="font-family: monospace;">__next__</span>. <b>Do NOT explicitly give your type a <tt>next</tt> method</b>,
+or bad things could happen.<br><h2><small>Type Testing in Special Methods <span style="color: rgb(255, 0, 0);">(New in 0.9.7)</span></small></h2>When testing the types of operands to your special methods, the obvious way might appear to be to use the <span style="font-family: monospace;">isinstance</span>
+function. However, this is not completely safe, because it's possible
+for a class to override what gets returned by isinstance tests on its
+instances. This is not a great problem in Python code, but in Pyrex it
+could be disastrous, as we are relying on knowing the C layout of the
+objects we're dealing with.<br><br>Pyrex provides an alternative function, <span style="font-family: monospace; font-weight: bold;">typecheck</span>,
+which corresponds to PyObject_TypeCheck in the Python/C API. This is
+safe to use, as it always tests the actual C type of the object.<br><br>Similarly, there is an <span style="font-family: monospace; font-weight: bold;">issubtype</span> function, corresponding to PyType_IsSubType, as a safe alternative to <span style="font-family: monospace;">issubclass</span>.<br><br>As an example, here's how you might write an __add__ method for an extension type called MyNumber:<br><br><div style="margin-left: 40px;"><span style="font-family: monospace;">def __add__(x, y):</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; if typecheck(x, MyNumber):</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; # we are the left operand<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if typecheck(y, MyNumber):<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; # add ourselves to another MyNumber and return result<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if typecheck(y, int):<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; # add ourselves to an int and return result<br style="font-family: monospace;"></span><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; elseif typecheck(y, MyNumber):<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; # we are the right operand<br style="font-family: monospace;"></span><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if typecheck(x, int):<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; # add an int to ourselves and return the result<br style="font-family: monospace;"></span><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; # Get here if unknown combination</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; return NotImplemented</span><br></div>
+<h2> <font size="+1">Special Method Table</font></h2>
+
+ This table lists all of the special methods together with their parameter
+ and return types. In the table below, a parameter name of <b>self</b> is used to indicate that the parameter has&nbsp;the type that the method
+ belongs to. Other parameters with no type specified in the table are generic Python objects.
+<p>You don't have to declare your method as taking these parameter types.
+ If you declare different types, conversions will be performed as necessary.
+ <br>
+
+ &nbsp;
+<table nosave="" bgcolor="#ccffff" border="1" cellpadding="5" cellspacing="0">
+
+ <tbody>
+
+ <tr nosave="" bgcolor="#ffcc33">
+
+ <td nosave=""><b>Name</b></td>
+
+ <td><b>Parameters</b></td>
+
+ <td><b>Return type</b></td>
+
+ <td><b>Description</b></td>
+
+ </tr>
+
+ <tr nosave="" bgcolor="#66ffff">
+
+ <td colspan="4" nosave=""><b>General</b></td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__cinit__</tt></td>
+
+ <td>self, ...</td>
+
+ <td>&nbsp;</td>
+
+ <td>Basic initialisation (no direct Python equivalent)</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__init__</tt></td>
+
+ <td>self, ...</td>
+
+ <td>&nbsp;</td>
+
+ <td>Further initialisation</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__dealloc__</tt></td>
+
+ <td>self</td>
+
+ <td>&nbsp;</td>
+
+ <td>Basic deallocation (no direct Python equivalent)</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__cmp__</tt></td>
+
+ <td>x, y</td>
+
+ <td>int</td>
+
+ <td>3-way comparison</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__richcmp__</tt></td>
+
+ <td>x, y, int op</td>
+
+ <td>object</td>
+
+ <td>Rich comparison (no direct Python equivalent)</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__str__</tt></td>
+
+ <td>self</td>
+
+ <td>object</td>
+
+ <td>str(self)</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__repr__</tt></td>
+
+ <td>self</td>
+
+ <td>object</td>
+
+ <td>repr(self)</td>
+
+ </tr>
+
+ <tr nosave="">
+
+ <td nosave=""><tt>__hash__</tt></td>
+
+ <td>self</td>
+
+ <td>int</td>
+
+ <td>Hash function</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__call__</tt></td>
+
+ <td>self, ...</td>
+
+ <td>object</td>
+
+ <td>self(...)</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__iter__</tt></td>
+
+ <td>self</td>
+
+ <td>object</td>
+
+ <td>Return iterator for sequence</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__getattr__</tt></td>
+
+ <td>self, name</td>
+
+ <td>object</td>
+
+ <td>Get attribute</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__setattr__</tt></td>
+
+ <td>self, name, val</td>
+
+ <td>&nbsp;</td>
+
+ <td>Set attribute</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__delattr__</tt></td>
+
+ <td>self, name</td>
+
+ <td>&nbsp;</td>
+
+ <td>Delete attribute</td>
+
+ </tr>
+
+ <tr nosave="" bgcolor="#66ffff">
+
+ <td colspan="4" nosave=""><b>Arithmetic operators</b></td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__add__</tt></td>
+
+ <td>x, y</td>
+
+ <td>object</td>
+
+ <td>binary + operator</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__sub__</tt></td>
+
+ <td>x, y</td>
+
+ <td>object</td>
+
+ <td>binary - operator</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__mul__</tt></td>
+
+ <td>x, y</td>
+
+ <td>object</td>
+
+ <td>* operator</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__div__</tt></td>
+
+ <td>x, y</td>
+
+ <td>object</td>
+
+ <td>/&nbsp; operator for old-style division</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__floordiv__</tt></td>
+
+ <td>x, y</td>
+
+ <td>object</td>
+
+ <td>//&nbsp; operator</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__truediv__</tt></td>
+
+ <td>x, y</td>
+
+ <td>object</td>
+
+ <td>/&nbsp; operator for new-style division</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__mod__</tt></td>
+
+ <td>x, y</td>
+
+ <td>object</td>
+
+ <td>% operator</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__divmod__</tt></td>
+
+ <td>x, y</td>
+
+ <td>object</td>
+
+ <td>combined div and mod</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__pow__</tt></td>
+
+ <td>x, y, z</td>
+
+ <td>object</td>
+
+ <td>** operator or pow(x, y, z)</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__neg__</tt></td>
+
+ <td>self</td>
+
+ <td>object</td>
+
+ <td>unary - operator</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__pos__</tt></td>
+
+ <td>self</td>
+
+ <td>object</td>
+
+ <td>unary + operator</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__abs__</tt></td>
+
+ <td>self</td>
+
+ <td>object</td>
+
+ <td>absolute value</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__nonzero__</tt></td>
+
+ <td>self</td>
+
+ <td>int</td>
+
+ <td>convert to boolean</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__invert__</tt></td>
+
+ <td>self</td>
+
+ <td>object</td>
+
+ <td>~ operator</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__lshift__</tt></td>
+
+ <td>x, y</td>
+
+ <td>object</td>
+
+ <td>&lt;&lt; operator</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__rshift__</tt></td>
+
+ <td>x, y</td>
+
+ <td>object</td>
+
+ <td>&gt;&gt; operator</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__and__</tt></td>
+
+ <td>x, y</td>
+
+ <td>object</td>
+
+ <td>&amp; operator</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__or__</tt></td>
+
+ <td>x, y</td>
+
+ <td>object</td>
+
+ <td>| operator</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__xor__</tt></td>
+
+ <td>x, y</td>
+
+ <td>object</td>
+
+ <td>^ operator</td>
+
+ </tr>
+
+ <tr nosave="" bgcolor="#66ffff">
+
+ <td colspan="4" nosave=""><b>Numeric conversions</b></td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__int__</tt></td>
+
+ <td>self</td>
+
+ <td>object</td>
+
+ <td>Convert to integer</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__long__</tt></td>
+
+ <td>self</td>
+
+ <td>object</td>
+
+ <td>Convert to long integer</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__float__</tt></td>
+
+ <td>self</td>
+
+ <td>object</td>
+
+ <td>Convert to float</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__oct__</tt></td>
+
+ <td>self</td>
+
+ <td>object</td>
+
+ <td>Convert to octal</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__hex__</tt></td>
+
+ <td>self</td>
+
+ <td>object</td>
+
+ <td>Convert to hexadecimal</td>
+
+ </tr>
+
+ <tr><td><span style="font-family: monospace;">__index__</span> (2.5+ only)</td><td>self</td><td>object</td><td>Convert to sequence index</td></tr><tr nosave="" bgcolor="#66ffff">
+
+ <td colspan="4" nosave=""><b>In-place arithmetic operators</b></td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__iadd__</tt></td>
+
+ <td>self, x</td>
+
+ <td>object</td>
+
+ <td>+= operator</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__isub__</tt></td>
+
+ <td>self, x</td>
+
+ <td>object</td>
+
+ <td>-= operator</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__imul__</tt></td>
+
+ <td>self, x</td>
+
+ <td>object</td>
+
+ <td>*= operator</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__idiv__</tt></td>
+
+ <td>self, x</td>
+
+ <td>object</td>
+
+ <td>/= operator for old-style division</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__ifloordiv__</tt></td>
+
+ <td>self, x</td>
+
+ <td>object</td>
+
+ <td>//= operator</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__itruediv__</tt></td>
+
+ <td>self, x</td>
+
+ <td>object</td>
+
+ <td>/= operator for new-style division</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__imod__</tt></td>
+
+ <td>self, x</td>
+
+ <td>object</td>
+
+ <td>%= operator</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__ipow__</tt></td>
+
+ <td>x, y, z</td>
+
+ <td>object</td>
+
+ <td>**= operator</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__ilshift__</tt></td>
+
+ <td>self, x</td>
+
+ <td>object</td>
+
+ <td>&lt;&lt;= operator</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__irshift__</tt></td>
+
+ <td>self, x</td>
+
+ <td>object</td>
+
+ <td>&gt;&gt;= operator</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__iand__</tt></td>
+
+ <td>self, x</td>
+
+ <td>object</td>
+
+ <td>&amp;= operator</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__ior__</tt></td>
+
+ <td>self, x</td>
+
+ <td>object</td>
+
+ <td>|= operator</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__ixor__</tt></td>
+
+ <td>self, x</td>
+
+ <td>object</td>
+
+ <td>^= operator</td>
+
+ </tr>
+
+ <tr nosave="" bgcolor="#66ffff">
+
+ <td colspan="4" nosave=""><b>Sequences and mappings</b></td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__len__</tt></td>
+
+ <td>self</td>
+
+ <td>int</td>
+
+ <td>len(self)</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__getitem__</tt></td>
+
+ <td>self, x</td>
+
+ <td>object</td>
+
+ <td>self[x]</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__setitem__</tt></td>
+
+ <td>self, x, y</td>
+
+ <td>&nbsp;</td>
+
+ <td>self[x] = y</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__delitem__</tt></td>
+
+ <td>self, x</td>
+
+ <td>&nbsp;</td>
+
+ <td>del self[x]</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__getslice__</tt></td>
+
+ <td>self, Py_ssize_t i,&nbsp;Py_ssize_t j</td>
+
+ <td>object</td>
+
+ <td>self[i:j]</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__setslice__</tt></td>
+
+ <td>self,&nbsp;Py_ssize_t i,&nbsp;Py_ssize_t j, x</td>
+
+ <td>&nbsp;</td>
+
+ <td>self[i:j] = x</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__delslice__</tt></td>
+
+ <td>self,&nbsp;Py_ssize_t i,&nbsp;Py_ssize_t j</td>
+
+ <td>&nbsp;</td>
+
+ <td>del self[i:j]</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__contains__</tt></td>
+
+ <td>self, x</td>
+
+ <td>int</td>
+
+ <td>x in self</td>
+
+ </tr>
+
+ <tr nosave="" bgcolor="#66ffff">
+
+ <td colspan="4" nosave=""><b>Iterators</b></td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__next__</tt></td>
+
+ <td>self</td>
+
+ <td>object</td>
+
+ <td>Get next item (called <tt>next</tt> in Python)</td>
+
+ </tr>
+
+ <tr nosave="" bgcolor="#66ffff">
+
+ <td colspan="4" nosave=""><b>Buffer interface</b>&nbsp; (no Python equivalents
+ - see note 1)</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__getreadbuffer__</tt></td>
+
+ <td>self, int i, void **p</td>
+
+ <td>&nbsp;</td>
+
+ <td>&nbsp;</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__getwritebuffer__</tt></td>
+
+ <td>self, int i, void **p</td>
+
+ <td>&nbsp;</td>
+
+ <td>&nbsp;</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__getsegcount__</tt></td>
+
+ <td>self, int *p</td>
+
+ <td>&nbsp;</td>
+
+ <td>&nbsp;</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__getcharbuffer__</tt></td>
+
+ <td>self, int i, char **p</td>
+
+ <td>&nbsp;</td>
+
+ <td>&nbsp;</td>
+
+ </tr>
+
+ <tr nosave="" bgcolor="#66ffff">
+
+ <td colspan="4" nosave=""><b>Descriptor objects</b>&nbsp; (see note 2)</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__get__</tt></td>
+
+ <td>self, instance, class</td>
+
+ <td>object</td>
+
+ <td>Get value of attribute</td>
+
+ </tr>
+
+ <tr>
+
+ <td><tt>__set__</tt></td>
+
+ <td>self, instance, value</td>
+
+ <td>&nbsp;</td>
+
+ <td>Set value of attribute</td>
+
+ </tr>
+
+ <tr>
+
+ <td style="font-family: monospace;">__delete__</td>
+
+ <td>self, instance</td>
+
+ <td>&nbsp;</td>
+
+ <td>Delete attribute</td>
+
+ </tr>
+
+
+ </tbody>
+</table>
+
+ </p>
+
+
+<p>Note 1: The buffer interface is intended for use by C code and is not
+directly accessible from Python. It is described in the <a href="http://www.python.org/doc/current/api/api.html">Python/C API Reference
+Manual</a> under sections <a href="http://www.python.org/doc/current/api/abstract-buffer.html">6.6</a>
+and <a href="http://www.python.org/doc/current/api/buffer-structs.html">10.6</a>.
+ </p>
+
+
+<p>Note 2: Descriptor objects are part of the support mechanism for new-style
+ Python classes. See the <a href="http://www.python.org/doc/2.2.1/whatsnew/sect-rellinks.html#SECTION000320000000000000000">discussion
+ of descriptors in the Python documentation</a>. See also <a href="http://www.python.org/peps/pep-0252.html">PEP 252, "Making Types Look
+More Like Classes"</a>, and <a href="http://www.python.org/peps/pep-0253.html">PEP 253, "Subtyping Built-In
+Types"</a>. </p>
+
+ <br>
+
+</body></html> \ No newline at end of file
diff --git a/debian/pyrex/pyrex-0.9.9/Doc/Manual/using_with_c++.html b/debian/pyrex/pyrex-0.9.9/Doc/Manual/using_with_c++.html
new file mode 100644
index 00000000..df95c8e7
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Doc/Manual/using_with_c++.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"><title>Using with C++</title></head><body><h1>Using Pyrex with C++</h1>This section describes some features of Pyrex that are designed to facilitate wrapping of libraries written in C++.<br><ul id="mozToc"><!--mozToc h2 1 h3 2--><li><a href="#mozTocId714434">Source Filenames</a></li><li><a href="#mozTocId758326">C++ Structs and&nbsp;Classes</a><ul><li><a href="#mozTocId52035">Inheritance</a></li><li><a href="#mozTocId470913">Instantiation</a></li><li><a href="#mozTocId84624">Disposal</a></li></ul></li><li><a href="#mozTocId214896">Overloaded Functions</a></li></ul><h2><a class="mozTocH2" name="mozTocId714434"></a>Source Filenames</h2>Pyrex source files that use C++ features should be named with an extension of "<span style="font-family: monospace;">.pyx+</span>". The corresponding generated C file will then have an extension of ".cpp", and should be compiled with a C++ compiler.<br><br>Note that this only applies to <span style="font-style: italic;">implementation</span> files, not definition files. Definition files should always have an extension of ".pxd", whether they use C++ features or not.<br><h2><a class="mozTocH2" name="mozTocId758326"></a>C++ Structs and&nbsp;Classes</h2>C++ structs and classes are declared using <span style="font-family: monospace;">cdef+ struct</span>, for example,<br><br><div style="margin-left: 40px;"><span style="font-family: monospace;">cdef extern from "somewhere.h":</span><br><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; cdef+ struct&nbsp;Shrubbery:</span><br><span style="font-family: monospace;">&nbsp; &nbsp; &nbsp; &nbsp; __init__()</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; __init__(float width)</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; __init__(float width, int price)</span><br><span style="font-family: monospace;">&nbsp; &nbsp; &nbsp; &nbsp; float width</span><br><span style="font-family: monospace;">&nbsp; &nbsp; &nbsp; &nbsp; int height</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; void plant_with_rhododendrons(int howmany)</span><br></div><br>Some important things to note:<br><ul><li>All <span style="font-family: monospace;">cdef+ struct</span> declarations must appear inside a <span style="font-family: monospace;">cdef extern from</span> block.</li><li>In Pyrex, <span style="font-family: monospace;">struct</span> is used regardless of whether the type is declared as a "struct" or a "class" in C++.</li><li>Constructors are declared using the name <span style="font-family: monospace;">__init__</span>. There can be multiple constructors with different signatures. If no constructor is declared, a single constructor with no arguments is assumed.</li><li>Destructors are not declared in Pyrex.</li><li>Member functions are declared without "virtual", whether they are virtual in C++ or not.</li></ul>A&nbsp;whole <span style="font-family: monospace;">extern from</span> block can also be declared using<span style="font-family: monospace;"> cdef+</span> if desired. This can be convenient when declaring a number of C++ types at once.<br><br><div style="margin-left: 40px;"><span style="font-family: monospace;">cdef+ extern from "shrubbing.h":</span><br><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;struct&nbsp;Shrubbery:</span><br><span style="font-family: monospace;">&nbsp; &nbsp; &nbsp; &nbsp; ...</span><br style="font-family: monospace;"></div><span style="font-family: monospace;"></span><br>The effect is the same as if <span style="font-family: monospace;">cdef+</span> had been used on all the contained struct declarations. Other declarations appearing in the block are treated as ordinary <span style="font-family: monospace;">cdef</span> declarations.<br><h3><a class="mozTocH3" name="mozTocId52035"></a>Inheritance</h3>A C++ struct may inherit from one or more base structs.<br><br><div style="margin-left: 40px;"><span style="font-family: monospace;">cdef+ extern from "shrubbing.h":</span><br><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;struct FancyShrubbery(Shrubbery):</span><br><span style="font-family: monospace;">&nbsp; &nbsp; &nbsp; &nbsp; ...</span><br></div><h3><a class="mozTocH3" name="mozTocId470913"></a>Instantiation</h3>C++ structs can be instantiated using the <span style="font-family: monospace;">new</span> operator, similarly to C++.<br><br><div style="margin-left: 40px;"><span style="font-family: monospace;">cdef&nbsp;Shrubbery *sh1, *sh2, *sh3</span><br><span style="font-family: monospace;">sh1 = new&nbsp;</span><span style="font-family: monospace;">Shrubbery()</span><br><span style="font-family: monospace;">sh2 = new&nbsp;</span><span style="font-family: monospace;">Shrubbery(3.2)</span><br><span style="font-family: monospace;">sh3 = new&nbsp;</span><span style="font-family: monospace;">Shrubbery(4.3, 800)</span><br><span style="font-family: monospace;"></span></div><br>Note that parentheses are required even if there are no arguments.<br><h3><a class="mozTocH3" name="mozTocId84624"></a>Disposal</h3>The <span style="font-family: monospace;">del</span> statement can be applied to a pointer to a C++ struct to deallocate it. This is equivalent to <span style="font-family: monospace;">delete</span> in C++.<br><br><div style="margin-left: 40px;"><span style="font-family: monospace;">cdef&nbsp;Shrubbery *big_sh</span><br><span style="font-family: monospace;">big_sh = new&nbsp;</span><span style="font-family: monospace;">Shrubbery(42.0)</span><br><span style="font-family: monospace;">display_in_garden_show(big_sh)</span><br style="font-family: monospace;"><span style="font-family: monospace;">del big_sh</span><br></div><h2><a class="mozTocH2" name="mozTocId214896"></a>Overloaded Functions</h2>Apart
+from the special case of C++ struct constructors, there is no special
+support for dealing with overloaded functions in C++. You will need to
+declare each version of the function with a different name in Pyrex and
+use C name specifications to map them all to the same C++ name. For
+example,<br><br><div style="margin-left: 40px;"><span style="font-family: monospace;">cdef extern from "shrubbing.h":</span><br style="font-family: monospace;"><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; void build_with_width "build_shrubbery" (float width)</span><br style="font-family: monospace;"><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; void build_with_petunias "build_shrubbery" (int number_of_petunias)</span><br></div><br></body></html> \ No newline at end of file
diff --git a/debian/pyrex/pyrex-0.9.9/Doc/Release_Notes_0.9.9.html b/debian/pyrex/pyrex-0.9.9/Doc/Release_Notes_0.9.9.html
new file mode 100644
index 00000000..6a85fc0c
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Doc/Release_Notes_0.9.9.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html><head><meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"><title>0.9.9 Release Notes</title></head><body><h1>Release Notes for Pyrex 0.9.9</h1><h2>C++ Features</h2>Some features for interfacing with C++ code have been introduced in this release. Structs declared with '<span style="font-family: monospace;">cdef+ struct</span>' may have constructors and member functions, there is a '<span style="font-family: monospace;">new</span>' operator for instantiating them, and they may be deallocated using the '<span style="font-family: monospace;">del</span>' operator. Details may be found in the <a href="LanguageOverview.html">Language Overview</a> under <a href="Manual/using_with_c++.html">Using Pyrex with C++</a>.<br><h2>Changes to Exception Semantics</h2>The
+behaviour surrounding exceptions caught using a try-except statement
+were previously an inconsistent mixture of Pyrex and Python semantics.
+Attempts to make the behaviour match Python more closely were requiring
+the generation of increasingly convoluted and inefficient code, so I
+decided to backtrack and return to something simpler.<br><br>Pyrex no
+longer places caught exceptions into the thread state. This ensures
+that exceptions and tracebacks do not leak out of the except clause
+that caught them, unless you do something to explicitly preserve them.<br><br>It also means that you <span style="font-style: italic;">cannot</span> retrieve an caught exception in Pyrex using <span style="font-family: monospace;">sys.exc_info()</span>. If you want to capture the exception, you need to bind it to a name in the <span style="font-family: monospace;">except</span> clause.<br><br>To capture the traceback, the syntax of the <span style="font-family: monospace;">except</span> clause has been extended to allow a third argument. For example,<br><pre style="margin-left: 40px;">try:<br> start_vehicle()<br>except HovercraftError, err, tb:<br> print "Can't start:", err<br> traceback.print_tb(tb)<br></pre>As previously, a <span style="font-family: monospace;">raise</span> statement with no arguments must be lexically enclosed in the <span style="font-family: monospace;">except</span>
+clause which caught the exception that you are trying to re-raise. In
+order to re-raise it from somewhere else, you will need to explicity
+communicate the exception and traceback to that place and use an
+ordinary <span style="font-family: monospace;">raise</span> statement.<br><h2>Planned Change to None-checking</h2>Currently,
+an argument to a Python function that is declared as an extension type
+will, by default, be allowed to receive the value None; to prevent
+this, you must qualify the argument declaration with '<span style="font-family: monospace;">not None</span>'.<br><br>This
+arrangement has proved to be error-prone, because it requires the
+programmer to be aware of the 'not None' feature and to remember to use
+it everywhere necessary. Failure to do so results in a Pyrex module
+that is prone to being crashed hard if it is passed a None value that
+it is not expecting.<br><br>To improve this situation, I am planning to make '<span style="font-family: monospace;">not None</span>' the default in a future release of Pyrex. In order to allow None as a legal argument value, it will be necessary to use an '<span style="font-family: monospace;">or None</span>' qualifier.<br><br>In release 0.9.9, the '<span style="font-family: monospace;">or None</span>'
+qualifier may be used, but it is optional. In preparation for the
+change of default, the Pyrex compiler will issue a warning (once per
+run) if it encounters an extension type argument that is not qualified
+with either 'or None' or 'not None'. For example, if <span style="font-family: monospace;">Spam</span> and <span style="font-family: monospace;">Eggs</span> are extension types and you have a function declared as<br><pre style="margin-left: 40px;">def frobulate(Spam s, Eggs e not None):<br> ...<br></pre>then in order to eliminate the warning, you will need to change it to<br><pre style="margin-left: 40px;">def frobulate(Spam s or None, Eggs e not None):<br> ...</pre>In a later release, when 'not None' has become the default, it will be possible to drop the 'not None' qualifiers.<br><h2>Non-GC Extension Types</h2>It
+is now possible to define and extension type with Python attributes
+that does not participate in cyclic garbage collection, using a new <span style="font-family: monospace;">nogc</span> option, for example:<br><pre style="margin-left: 40px;">cdef class Spam [nogc]:<br> """This class doesn't participate in GC even though<br> it has a Python attribute."""<br> object sausages</pre><h2>Other New Features</h2>Some other minor feature additions and modifications have been made.<br><ul><li><span style="font-family: monospace;">size_t </span>is now a built-in type and is the type returned by the <span style="font-family: monospace;">sizeof</span> operator. Also, the sizes of <span style="font-family: monospace;">size_t</span> and <span style="font-family: monospace;">Py_ssize_t</span> are now assumed to be somewhere between <span style="font-family: monospace;">long</span> and <span style="font-family: monospace;">long long</span>.<br><br></li><li>Operations
+between two int types of the same rank now return an
+unsigned result if either of the operands is unsigned; if the ranks
+differ, the result has the same type as the wider-ranked operand. I
+think this is the best
+approximation of the ANSI C rules that is possible without knowing the
+exact sizes of the types.<br><br><span style="font-family: monospace;"></span></li><li><span style="font-family: monospace;">PyString_InternFromString</span> is now exposed under the name <span style="font-family: monospace; font-weight: bold;">cintern</span><span style="font-weight: bold;"> </span>rather than <span style="font-family: monospace;">intern</span>, because it is not a complete replacement for the Python <span style="font-family: monospace;">intern</span> function (it can't handle strings containing null bytes).<br></li><li>The
+size check that was previously generated when importing an extension
+type has been disabled for the time being until I can think of
+something better. It was generating too many false positives, for
+example from different versions of numpy.<br><br></li><li>The <span style="font-family: monospace;">__fastcall</span> calling convention option is now supported. Also, Pyrex no longer assumes that <span style="font-family: monospace;">__cdecl</span>
+is the default calling convention. To be considered compatible, two
+function types must either be declared with the same calling
+convention, or both must leave it unspecified.<br><br></li><li>As I have been threatening for some time, using <span style="font-family: monospace;">__new__</span>
+as the name of the initialisation method of an extension type has
+become an error rather than just a warning. In some future release, <span style="font-family: monospace;">__new__</span> will re-emerge with more Python-like semantics.</li></ul><br></body></html> \ No newline at end of file
diff --git a/debian/pyrex/pyrex-0.9.9/Doc/index.html b/debian/pyrex/pyrex-0.9.9/Doc/index.html
new file mode 100644
index 00000000..e8246f5b
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Doc/index.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en">
+<html><head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.51 (Macintosh; I; PPC) [Netscape]">
+ <title>Pyrex - Front Page</title></head>
+
+<body>
+&nbsp;
+<table style="width: 100%;" cellpadding="10" cellspacing="0">
+<tbody><tr>
+<td bgcolor="#ff9218" valign="top"><font face="Arial,Helvetica"><font size="+4">Pyrex</font></font></td>
+
+<td style="width: 200px; vertical-align: top; text-align: right; background-color: rgb(93, 186, 202);"><font face="Arial,Helvetica"><font size="+1">A
+smooth blend of the finest Python&nbsp;</font></font>
+<br><font face="Arial,Helvetica"><font size="+1">with the unsurpassed power&nbsp;</font></font>
+<font face="Arial,Helvetica"><font size="+1">of raw C.</font></font></td>
+</tr>
+</tbody></table>
+
+<blockquote><font size="+1">Welcome to Pyrex, a language for writing Python
+extension modules. Pyrex makes creating an extension module&nbsp;almost as
+easy as creating a Python module.</font></blockquote>
+
+<h1>
+<font face="Arial,Helvetica"><font size="+2">Documentation</font></font></h1>
+
+<blockquote>
+<h2>
+<font face="Arial,Helvetica"><font size="+1"><a href="About.html">About Pyrex</a></font></font></h2>
+
+<blockquote><font size="+1">Read this to find out what Pyrex is all about
+and what it can do for you.</font></blockquote>
+
+<h2>
+<font face="Arial,Helvetica"><font size="+1"><a href="LanguageOverview.html">Language
+Overview</a></font></font></h2>
+
+<blockquote><font size="+1">A comined tutorial and reference manual describing of all the features of the Pyrex
+language.</font></blockquote>
+
+<h2>
+<font face="Arial,Helvetica"><font size="+1"><a href="FAQ.html">FAQ</a></font></font></h2>
+
+<blockquote><font size="+1">Want to know how to do something in Pyrex? Check
+here first<font face="Arial,Helvetica">.</font></font></blockquote>
+</blockquote>
+
+<h1>
+<font face="Arial,Helvetica"><font size="+2">Other Resources</font></font></h1>
+
+<blockquote>
+<h2>
+<font face="Arial,Helvetica"><font size="+1"><a href="http://www.cosc.canterbury.ac.nz/%7Egreg/python/Pyrex/mpj17-pyrex-guide/">Michael's
+Quick Guide to Pyrex</a></font></font></h2>
+
+<blockquote><font size="+1">This tutorial-style presentation will take you
+through the steps of creating some Pyrex modules to wrap existing C libraries.
+Contributed by <a href="mailto:mpj17@cosc.canterbury.ac.nz">Michael JasonSmith</a>.</font></blockquote>
+
+<h2>
+<font face="Arial,Helvetica"><font size="+1"><a href="mailto:greg.ewing@canterbury.ac.nz">Mail
+to the Author</a></font></font></h2>
+
+<blockquote><font size="+1">If you have a question that's not answered by
+anything here, you're not sure about something, or you have a bug to report
+or a suggestion to make, or anything at all to say about Pyrex, feel free
+to email me:<font face="Arial,Helvetica"> </font><tt><a href="mailto:greg.ewing@canterbury.ac.nz">greg.ewing@canterbury.ac.nz</a></tt></font></blockquote>
+</blockquote>
+
+</body></html> \ No newline at end of file
diff --git a/debian/pyrex/pyrex-0.9.9/Doc/primes.c b/debian/pyrex/pyrex-0.9.9/Doc/primes.c
new file mode 100644
index 00000000..9a88b84c
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Doc/primes.c
@@ -0,0 +1 @@
+#include "Python.h" static PyObject *__Pyx_UnpackItem(PyObject *, int); static int __Pyx_EndUnpack(PyObject *, int); static int __Pyx_PrintItem(PyObject *); static int __Pyx_PrintNewline(void); static void __Pyx_ReRaise(void); static void __Pyx_RaiseWithTraceback(PyObject *, PyObject *, PyObject *); static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); static PyObject *__Pyx_GetExcValue(void); static PyObject *__Pyx_GetName(PyObject *dict, char *name); static PyObject *__pyx_m; static PyObject *__pyx_d; static PyObject *__pyx_b; PyObject *__pyx_f_primes(PyObject *__pyx_self, PyObject *__pyx_args); /*proto*/ PyObject *__pyx_f_primes(PyObject *__pyx_self, PyObject *__pyx_args) { int __pyx_v_kmax; int __pyx_v_n; int __pyx_v_k; int __pyx_v_i; int (__pyx_v_p[1000]); PyObject *__pyx_v_result; PyObject *__pyx_r; PyObject *__pyx_1 = 0; int __pyx_2; int __pyx_3; int __pyx_4; PyObject *__pyx_5 = 0; PyObject *__pyx_6 = 0; if (!PyArg_ParseTuple(__pyx_args, "i", &__pyx_v_kmax)) return 0; __pyx_v_result = Py_None; Py_INCREF(__pyx_v_result); /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":2 */ /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":3 */ /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":4 */ __pyx_1 = PyList_New(0); if (!__pyx_1) goto __pyx_L1; Py_DECREF(__pyx_v_result); __pyx_v_result = __pyx_1; __pyx_1 = 0; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":5 */ __pyx_2 = (__pyx_v_kmax > 1000); if (__pyx_2) { /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":6 */ __pyx_v_kmax = 1000; goto __pyx_L2; } __pyx_L2:; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":7 */ __pyx_v_k = 0; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":8 */ __pyx_v_n = 2; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":9 */ while (1) { __pyx_L3:; __pyx_2 = (__pyx_v_k < __pyx_v_kmax); if (!__pyx_2) break; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":10 */ __pyx_v_i = 0; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":11 */ while (1) { __pyx_L5:; if (__pyx_3 = (__pyx_v_i < __pyx_v_k)) { __pyx_3 = ((__pyx_v_n % (__pyx_v_p[__pyx_v_i])) != 0); } if (!__pyx_3) break; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":12 */ __pyx_v_i = (__pyx_v_i + 1); } __pyx_L6:; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":13 */ __pyx_4 = (__pyx_v_i == __pyx_v_k); if (__pyx_4) { /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":14 */ (__pyx_v_p[__pyx_v_k]) = __pyx_v_n; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":15 */ __pyx_v_k = (__pyx_v_k + 1); /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":16 */ __pyx_1 = PyObject_GetAttrString(__pyx_v_result, "append"); if (!__pyx_1) goto __pyx_L1; __pyx_5 = PyInt_FromLong(__pyx_v_n); if (!__pyx_5) goto __pyx_L1; __pyx_6 = PyTuple_New(1); if (!__pyx_6) goto __pyx_L1; PyTuple_SET_ITEM(__pyx_6, 0, __pyx_5); __pyx_5 = 0; __pyx_5 = PyObject_CallObject(__pyx_1, __pyx_6); if (!__pyx_5) goto __pyx_L1; Py_DECREF(__pyx_6); __pyx_6 = 0; Py_DECREF(__pyx_5); __pyx_5 = 0; goto __pyx_L7; } __pyx_L7:; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":17 */ __pyx_v_n = (__pyx_v_n + 1); } __pyx_L4:; /* "ProjectsA:Python:Pyrex:Demos:primes.pyx":18 */ Py_INCREF(__pyx_v_result); __pyx_r = __pyx_v_result; goto __pyx_L0; __pyx_r = Py_None; Py_INCREF(__pyx_r); goto __pyx_L0; __pyx_L1:; Py_XDECREF(__pyx_1); Py_XDECREF(__pyx_5); Py_XDECREF(__pyx_6); __pyx_r = 0; __pyx_L0:; Py_DECREF(__pyx_v_result); return __pyx_r; } static struct PyMethodDef __pyx_methods[] = { {"primes", (PyCFunction)__pyx_f_primes, METH_VARARGS, 0}, {0, 0, 0, 0} }; void initprimes(void); /*proto*/ void initprimes(void) { __pyx_m = Py_InitModule4("primes", __pyx_methods, 0, 0, PYTHON_API_VERSION); __pyx_d = PyModule_GetDict(__pyx_m); __pyx_b = PyImport_AddModule("__builtin__"); PyDict_SetItemString(__pyx_d, "__builtins__", __pyx_b); } /* Runtime support code */ \ No newline at end of file
diff --git a/debian/pyrex/pyrex-0.9.9/INSTALL.txt b/debian/pyrex/pyrex-0.9.9/INSTALL.txt
new file mode 100644
index 00000000..a28d60c8
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/INSTALL.txt
@@ -0,0 +1,33 @@
+Pyrex - Installation Instructions
+=================================
+
+You have two installation options:
+
+(1) Run the setup.py script in this directory
+ as follows:
+
+ python setup.py install
+
+ This will install the Pyrex package
+ into your Python system.
+
+OR
+
+(2) If you prefer not to modify your Python
+ installation, arrange for the directory
+ containing this file (INSTALL.txt) to be in
+ your module search path.
+
+ For example, create a pyrex.pth file in your
+ Python installation's Lib/site-packages
+ directory and insert a line containing the
+ fully qualified path to the directory containing
+ this file.
+
+ On unix, also put the bin directory on your PATH.
+
+ On Win32 copy the pyrexc.py file to your Python
+ installation's Scripts directory, which should
+ already be on the PATH.
+
+See README.txt for pointers to other documentation.
diff --git a/debian/pyrex/pyrex-0.9.9/LICENSE.txt b/debian/pyrex/pyrex-0.9.9/LICENSE.txt
new file mode 100644
index 00000000..ca14331a
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/LICENSE.txt
@@ -0,0 +1,173 @@
+Apache License Version 2.0, January 2004
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction,
+and distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the
+copyright owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other
+entities that control, are controlled by, or are under common control
+with that entity. For the purposes of this definition, "control" means
+(i) the power, direct or indirect, to cause the direction or
+management of such entity, whether by contract or otherwise, or (ii)
+ownership of fifty percent (50%) or more of the outstanding shares, or
+(iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising
+permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications,
+including but not limited to software source code, documentation
+source, and configuration files.
+
+"Object" form shall mean any form resulting from mechanical
+transformation or translation of a Source form, including but not
+limited to compiled object code, generated documentation, and
+conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object
+form, made available under the License, as indicated by a copyright
+notice that is included in or attached to the work (an example is
+provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object
+form, that is based on (or derived from) the Work and for which the
+editorial revisions, annotations, elaborations, or other modifications
+represent, as a whole, an original work of authorship. For the
+purposes of this License, Derivative Works shall not include works
+that remain separable from, or merely link (or bind by name) to the
+interfaces of, the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the
+original version of the Work and any modifications or additions to
+that Work or Derivative Works thereof, that is intentionally submitted
+to Licensor for inclusion in the Work by the copyright owner or by an
+individual or Legal Entity authorized to submit on behalf of the
+copyright owner. For the purposes of this definition, "submitted"
+means any form of electronic, verbal, or written communication sent to
+the Licensor or its representatives, including but not limited to
+communication on electronic mailing lists, source code control
+systems, and issue tracking systems that are managed by, or on behalf
+of, the Licensor for the purpose of discussing and improving the Work,
+but excluding communication that is conspicuously marked or otherwise
+designated in writing by the copyright owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity
+on behalf of whom a Contribution has been received by Licensor and
+subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+this License, each Contributor hereby grants to You a perpetual,
+worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+copyright license to reproduce, prepare Derivative Works of, publicly
+display, publicly perform, sublicense, and distribute the Work and
+such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+this License, each Contributor hereby grants to You a perpetual,
+worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except
+as stated in this section) patent license to make, have made, use,
+offer to sell, sell, import, and otherwise transfer the Work, where
+such license applies only to those patent claims licensable by such
+Contributor that are necessarily infringed by their Contribution(s)
+alone or by combination of their Contribution(s) with the Work to
+which such Contribution(s) was submitted. If You institute patent
+litigation against any entity (including a cross-claim or counterclaim
+in a lawsuit) alleging that the Work or a Contribution incorporated
+within the Work constitutes direct or contributory patent
+infringement, then any patent licenses granted to You under this
+License for that Work shall terminate as of the date such litigation
+is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the Work
+or Derivative Works thereof in any medium, with or without
+modifications, and in Source or Object form, provided that You meet
+the following conditions:
+
+1. You must give any other recipients of the Work or Derivative Works
+a copy of this License; and
+
+2. You must cause any modified files to carry prominent notices
+stating that You changed the files; and
+
+3. You must retain, in the Source form of any Derivative Works that
+You distribute, all copyright, patent, trademark, and attribution
+notices from the Source form of the Work, excluding those notices that
+do not pertain to any part of the Derivative Works; and
+
+4. If the Work includes a "NOTICE" text file as part of its
+distribution, then any Derivative Works that You distribute must
+include a readable copy of the attribution notices contained within
+such NOTICE file, excluding those notices that do not pertain to any
+part of the Derivative Works, in at least one of the following places:
+within a NOTICE text file distributed as part of the Derivative Works;
+within the Source form or documentation, if provided along with the
+Derivative Works; or, within a display generated by the Derivative
+Works, if and wherever such third-party notices normally appear. The
+contents of the NOTICE file are for informational purposes only and do
+not modify the License. You may add Your own attribution notices
+within Derivative Works that You distribute, alongside or as an
+addendum to the NOTICE text from the Work, provided that such
+additional attribution notices cannot be construed as modifying the
+License.
+
+You may add Your own copyright statement to Your modifications and may
+provide additional or different license terms and conditions for use,
+reproduction, or distribution of Your modifications, or for any such
+Derivative Works as a whole, provided Your use, reproduction, and
+distribution of the Work otherwise complies with the conditions stated
+in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+any Contribution intentionally submitted for inclusion in the Work by
+You to the Licensor shall be under the terms and conditions of this
+License, without any additional terms or conditions. Notwithstanding
+the above, nothing herein shall supersede or modify the terms of any
+separate license agreement you may have executed with Licensor
+regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+names, trademarks, service marks, or product names of the Licensor,
+except as required for reasonable and customary use in describing the
+origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or agreed
+to in writing, Licensor provides the Work (and each Contributor
+provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+CONDITIONS OF ANY KIND, either express or implied, including, without
+limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT,
+MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely
+responsible for determining the appropriateness of using or
+redistributing the Work and assume any risks associated with Your
+exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+whether in tort (including negligence), contract, or otherwise, unless
+required by applicable law (such as deliberate and grossly negligent
+acts) or agreed to in writing, shall any Contributor be liable to You
+for damages, including any direct, indirect, special, incidental, or
+consequential damages of any character arising as a result of this
+License or out of the use or inability to use the Work (including but
+not limited to damages for loss of goodwill, work stoppage, computer
+failure or malfunction, or any and all other commercial damages or
+losses), even if such Contributor has been advised of the possibility
+of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+the Work or Derivative Works thereof, You may choose to offer, and
+charge a fee for, acceptance of support, warranty, indemnity, or other
+liability obligations and/or rights consistent with this License.
+However, in accepting such obligations, You may act only on Your own
+behalf and on Your sole responsibility, not on behalf of any other
+Contributor, and only if You agree to indemnify, defend, and hold each
+Contributor harmless for any liability incurred by, or claims asserted
+against, such Contributor by reason of your accepting any such
+warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
diff --git a/debian/pyrex/pyrex-0.9.9/MANIFEST.in b/debian/pyrex/pyrex-0.9.9/MANIFEST.in
new file mode 100644
index 00000000..7710f3e0
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/MANIFEST.in
@@ -0,0 +1,7 @@
+include MANIFEST.in README.txt INSTALL.txt CHANGES.txt ToDo.txt USAGE.txt
+include setup.py
+include bin/pyrexc
+include pyrexc.py
+include Pyrex/Compiler/Lexicon.pickle
+include Doc/*
+include Demos/*
diff --git a/debian/pyrex/pyrex-0.9.9/Makefile b/debian/pyrex/pyrex-0.9.9/Makefile
new file mode 100644
index 00000000..7042e68a
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Makefile
@@ -0,0 +1,15 @@
+VERSION = 0.9.9
+
+version:
+ @echo "Setting version to $(VERSION)"
+ @echo "version = '$(VERSION)'" > Pyrex/Compiler/Version.py
+
+clean:
+ @echo Cleaning Source
+ @rm -f *.pyc */*.pyc */*/*.pyc
+ @rm -f *~ */*~ */*/*~
+ @rm -f core */core
+ @(cd Demos; $(MAKE) clean)
+
+test_setup:
+ python setup.py --dry-run install
diff --git a/debian/pyrex/pyrex-0.9.9/Obsolete/PyrexTypes.py.old b/debian/pyrex/pyrex-0.9.9/Obsolete/PyrexTypes.py.old
new file mode 100644
index 00000000..ef581dd0
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Obsolete/PyrexTypes.py.old
@@ -0,0 +1,829 @@
+#
+# Pyrex - Types
+#
+
+import string
+import Naming
+
+class PyrexType:
+ #
+ # Base class for all Pyrex types.
+ #
+ # is_pyobject boolean Is a Python object type
+ # is_extension_type boolean Is a Python extension type
+ # is_numeric boolean Is a C numeric type
+ # is_int boolean Is a C integer type
+ # is_float boolean Is a C floating point type
+ # is_void boolean Is the C void type
+ # is_array boolean Is a C array type
+ # is_ptr boolean Is a C pointer type
+ # is_null_ptr boolean Is the type of NULL
+ # is_cfunction boolean Is a C function type
+ # is_struct_or_union boolean Is a C struct or union type
+ # is_enum boolean Is a C enum type
+ # is_string boolean Is a C char * type
+ # is_returncode boolean Is used only to signal exceptions
+ # is_error boolean Is the dummy error type
+ # has_attributes boolean Has C dot-selectable attributes
+ # default_value string Initial value
+ # parsetuple_format string Format char for PyArg_ParseTuple
+ # pymemberdef_typecode string Type code for PyMemberDef struct
+ #
+ # declaration_code(entity_code,
+ # for_display = 0, dll_linkage = None, pyrex = 0)
+ # Returns a code fragment for the declaration of an entity
+ # of this type, given a code fragment for the entity.
+ # * If for_display, this is for reading by a human in an error
+ # message; otherwise it must be valid C code.
+ # * If dll_linkage is not None, it must be 'DL_EXPORT' or
+ # 'DL_IMPORT', and will be added to the base type part of
+ # the declaration.
+ # * If pyrex = 1, this is for use in a 'cdef extern'
+ # statement of a Pyrex include file.
+ #
+ # assignable_from(src_type)
+ # Tests whether a variable of this type can be
+ # assigned a value of type src_type.
+ #
+ # same_as(other_type)
+ # Tests whether this type represents the same type
+ # as other_type.
+ #
+ # as_argument_type():
+ # Coerces array type into pointer type for use as
+ # a formal argument type.
+ #
+
+ is_pyobject = 0
+ is_extension_type = 0
+ is_numeric = 0
+ is_int = 0
+ is_float = 0
+ is_void = 0
+ is_array = 0
+ is_ptr = 0
+ is_null_ptr = 0
+ is_cfunction = 0
+ is_struct_or_union = 0
+ is_enum = 0
+ is_string = 0
+ is_returncode = 0
+ is_error = 0
+ has_attributes = 0
+ default_value = ""
+ parsetuple_format = ""
+ pymemberdef_typecode = None
+
+ def resolve(self):
+ # If a typedef, returns the base type.
+ return self
+
+ def literal_code(self, value):
+ # Returns a C code fragment representing a literal
+ # value of this type.
+ return str(value)
+
+ def __str__(self):
+ return string.strip(self.declaration_code("", for_display = 1))
+
+ def same_as(self, other_type, **kwds):
+ return self.same_as_resolved_type(other_type.resolve(), **kwds)
+
+ def same_as_resolved_type(self, other_type):
+ return self is other_type or other_type is error_type
+
+ def subtype_of(self, other_type):
+ return self.subtype_of_resolved_type(other_type.resolve())
+
+ def subtype_of_resolved_type(self, other_type):
+ return self.same_as(other_type)
+
+ def assignable_from(self, src_type):
+ return self.assignable_from_resolved_type(src_type.resolve())
+
+ def assignable_from_resolved_type(self, src_type):
+ return self.same_as(src_type)
+
+ def as_argument_type(self):
+ return self
+
+ def is_complete(self):
+ # A type is incomplete if it is an unsized array,
+ # a struct whose attributes are not defined, etc.
+ return 1
+
+ def cast_code(self, expr_code):
+ return "((%s)%s)" % (self.declaration_code(""), expr_code)
+
+
+class CTypedefType:
+ #
+ # Type defined with a ctypedef statement in a
+ # 'cdef extern from' block. Delegates most attribute
+ # lookups to the base type.
+ #
+
+ def __init__(self, cname, base_type):
+ self.typedef_cname = cname
+ self.typedef_base_type = base_type
+
+ def resolve(self):
+ return self.typedef_base_type.resolve()
+
+ def declaration_code(self, entity_code,
+ for_display = 0, dll_linkage = None, pyrex = 0):
+ return "%s %s" % (self.typedef_cname, entity_code)
+
+ def as_argument_type(self):
+ return self
+
+ def __str__(self):
+ return self.typedef_cname
+
+ def __getattr__(self, name):
+ return getattr(self.typedef_base_type, name)
+
+
+class PyObjectType(PyrexType):
+ #
+ # Base class for all Python object types (reference-counted).
+ #
+
+ is_pyobject = 1
+ default_value = "0"
+ parsetuple_format = "O"
+ pymemberdef_typecode = "T_OBJECT"
+
+ def __str__(self):
+ return "Python object"
+
+ def __repr__(self):
+ return "PyObjectType"
+
+ def assignable_from(self, src_type):
+ return 1 # Conversion will be attempted
+
+ def declaration_code(self, entity_code,
+ for_display = 0, dll_linkage = None, pyrex = 0):
+ if pyrex:
+ return "object %s" % entity_code
+ else:
+ return "%s *%s" % (public_decl("PyObject", dll_linkage), entity_code)
+
+
+class PyExtensionType(PyObjectType):
+ #
+ # A Python extension type.
+ #
+ # name string
+ # scope CClassScope Attribute namespace
+ # visibility string
+ # typedef_flag boolean
+ # base_type PyExtensionType or None
+ # module_name string or None Qualified name of defining module
+ # objstruct_cname string Name of PyObject struct
+ # typeobj_cname string or None C code fragment referring to type object
+ # typeptr_cname string or None Name of pointer to external type object
+ # vtabslot_cname string Name of C method table member
+ # vtabstruct_cname string Name of C method table struct
+ # vtabptr_cname string Name of pointer to C method table
+ # vtable_cname string Name of C method table definition
+
+ is_extension_type = 1
+ has_attributes = 1
+
+ def __init__(self, name, typedef_flag, base_type):
+ self.name = name
+ self.scope = None
+ self.typedef_flag = typedef_flag
+ self.base_type = base_type
+ self.module_name = None
+ self.objstruct_cname = None
+ self.typeobj_cname = None
+ self.typeptr_cname = None
+ self.vtabslot_cname = None
+ self.vtabstruct_cname = None
+ self.vtabptr_cname = None
+ self.vtable_cname = None
+
+ def set_scope(self, scope):
+ self.scope = scope
+ if scope:
+ scope.parent_type = self
+
+ def subtype_of_resolved_type(self, other_type):
+ if other_type.is_extension_type:
+ return self is other_type or (
+ self.base_type and self.base_type.subtype_of(other_type))
+ else:
+ return other_type is py_object_type
+
+ def typeobj_is_available(self):
+ # Do we have a pointer to the type object?
+ return self.typeptr_cname
+
+ def typeobj_is_imported(self):
+ # If we don't know the C name of the type object but we do
+ # know which module it's defined in, it will be imported.
+ return self.typeobj_cname is None and self.module_name is not None
+
+ def declaration_code(self, entity_code,
+ for_display = 0, dll_linkage = None, pyrex = 0):
+ if pyrex:
+ return "%s %s" % (self.name, entity_code)
+ else:
+ if self.typedef_flag:
+ base_format = "%s"
+ else:
+ base_format = "struct %s"
+ base = public_decl(base_format % self.objstruct_cname, dll_linkage)
+ return "%s *%s" % (base, entity_code)
+
+ def attributes_known(self):
+ return self.scope is not None
+
+ def __str__(self):
+ return self.name
+
+ def __repr__(self):
+ return "PyExtensionType(%s%s)" % (self.scope.class_name,
+ ("", ".typedef_flag=1")[self.typedef_flag])
+
+
+class CType(PyrexType):
+ #
+ # Base class for all C types (non-reference-counted).
+ #
+ # to_py_function string C function for converting to Python object
+ # from_py_function string C function for constructing from Python object
+ #
+
+ to_py_function = None
+ from_py_function = None
+
+
+#class CSimpleType(CType):
+# #
+# # Base class for all unstructured C types.
+# #
+# pass
+
+
+class CVoidType(CType):
+ is_void = 1
+
+ def __repr__(self):
+ return "<CVoidType>"
+
+ def declaration_code(self, entity_code,
+ for_display = 0, dll_linkage = None, pyrex = 0):
+ base = public_decl("void", dll_linkage)
+ return "%s %s" % (base, entity_code)
+
+ def is_complete(self):
+ return 0
+
+
+class CNumericType(CType):
+ #
+ # Base class for all C numeric types.
+ #
+ # rank integer Relative size
+ # signed boolean
+ #
+
+ is_numeric = 1
+ default_value = "0"
+
+ parsetuple_formats = ( # rank -> format
+ "?HIkK???", # unsigned
+ "chilLfd?", # signed
+ )
+
+ def __init__(self, rank, signed = 1, pymemberdef_typecode = None):
+ self.rank = rank
+ self.signed = signed
+ ptf = self.parsetuple_formats[signed][rank]
+ if ptf == '?':
+ ptf = None
+ self.parsetuple_format = ptf
+ self.pymemberdef_typecode = pymemberdef_typecode
+
+ def __repr__(self):
+ if self.signed:
+ u = ""
+ else:
+ u = "unsigned "
+ return "<CNumericType %s%s>" % (u, rank_to_type_name[self.rank])
+
+ def declaration_code(self, entity_code,
+ for_display = 0, dll_linkage = None, pyrex = 0):
+ if self.signed:
+ u = ""
+ else:
+ u = "unsigned "
+ base = public_decl(u + rank_to_type_name[self.rank], dll_linkage)
+ return "%s %s" % (base, entity_code)
+
+
+class CIntType(CNumericType):
+
+ is_int = 1
+ typedef_flag = 0
+ to_py_function = "PyInt_FromLong"
+ from_py_function = "PyInt_AsLong"
+
+ def __init__(self, rank, signed, pymemberdef_typecode = None, is_returncode = 0):
+ CNumericType.__init__(self, rank, signed, pymemberdef_typecode)
+ self.is_returncode = is_returncode
+
+ def assignable_from_resolved_type(self, src_type):
+ return src_type.is_int or src_type.is_enum or src_type is error_type
+
+
+class CUIntType(CIntType):
+
+ to_py_function = "PyLong_FromUnsignedLong"
+ from_py_function = "PyInt_AsUnsignedLongMask"
+
+
+class CULongType(CIntType):
+
+ to_py_function = "PyLong_FromUnsignedLong"
+ from_py_function = "PyInt_AsUnsignedLongMask"
+
+
+class CLongLongType(CIntType):
+
+ to_py_function = "PyLong_FromLongLong"
+ from_py_function = "PyInt_AsUnsignedLongLongMask"
+
+
+class CULongLongType(CIntType):
+
+ to_py_function = "PyLong_FromUnsignedLongLong"
+ from_py_function = "PyInt_AsUnsignedLongLongMask"
+
+
+class CFloatType(CNumericType):
+
+ is_float = 1
+ to_py_function = "PyFloat_FromDouble"
+ from_py_function = "PyFloat_AsDouble"
+
+ def __init__(self, rank, pymemberdef_typecode = None):
+ CNumericType.__init__(self, rank, 1, pymemberdef_typecode)
+
+ def assignable_from_resolved_type(self, src_type):
+ return src_type.is_numeric or src_type is error_type
+
+
+class CArrayType(CType):
+ # base_type CType Element type
+ # size integer or None Number of elements
+
+ is_array = 1
+
+ def __init__(self, base_type, size):
+ self.base_type = base_type
+ self.size = size
+ if base_type is c_char_type:
+ self.is_string = 1
+
+ def __repr__(self):
+ return "CArrayType(%s,%s)" % (self.size, repr(self.base_type))
+
+ def same_as_resolved_type(self, other_type):
+ return ((other_type.is_array and
+ self.base_type.same_as(other_type.base_type))
+ or other_type is error_type)
+
+ def assignable_from_resolved_type(self, src_type):
+ # Can't assign to a variable of an array type
+ return 0
+
+ def element_ptr_type(self):
+ return c_ptr_type(self.base_type)
+
+ def declaration_code(self, entity_code,
+ for_display = 0, dll_linkage = None, pyrex = 0):
+ if self.size is not None:
+ dimension_code = self.size
+ else:
+ dimension_code = ""
+ return self.base_type.declaration_code(
+ "(%s[%s])" % (entity_code, dimension_code),
+ for_display, dll_linkage, pyrex)
+
+ def as_argument_type(self):
+ return c_ptr_type(self.base_type)
+
+ def is_complete(self):
+ return self.size is not None
+
+
+class CPtrType(CType):
+ # base_type CType Referenced type
+
+ is_ptr = 1
+ default_value = 0
+
+ def __init__(self, base_type):
+ self.base_type = base_type
+
+ def __repr__(self):
+ return "CPtrType(%s)" % repr(self.base_type)
+
+ def same_as_resolved_type(self, other_type):
+ return ((other_type.is_ptr and
+ self.base_type.same_as(other_type.base_type))
+ or other_type is error_type)
+
+ def declaration_code(self, entity_code,
+ for_display = 0, dll_linkage = None, pyrex = 0):
+ #print "CPtrType.declaration_code: pointer to", self.base_type ###
+ return self.base_type.declaration_code(
+ "(*%s)" % entity_code,
+ for_display, dll_linkage, pyrex)
+
+ def assignable_from_resolved_type(self, other_type):
+ if other_type is error_type:
+ return 1
+ elif self.base_type.is_cfunction and other_type.is_cfunction:
+ return self.base_type.same_as(other_type)
+ elif other_type.is_array:
+ return self.base_type.same_as(other_type.base_type)
+ elif not other_type.is_ptr:
+ return 0
+ elif self.base_type.is_void:
+ return 1
+ elif other_type.is_null_ptr:
+ return 1
+ else:
+ return self.base_type.same_as(other_type.base_type)
+
+
+class CNullPtrType(CPtrType):
+
+ is_null_ptr = 1
+
+
+class CFuncType(CType):
+ # return_type CType
+ # args [CFuncTypeArg]
+ # has_varargs boolean
+ # exception_value string
+ # exception_check boolean True if PyErr_Occurred check needed
+
+ is_cfunction = 1
+
+ def __init__(self, return_type, args, has_varargs,
+ exception_value = None, exception_check = 0):
+ self.return_type = return_type
+ self.args = args
+ self.has_varargs = has_varargs
+ self.exception_value = exception_value
+ self.exception_check = exception_check
+
+ def __repr__(self):
+ arg_reprs = map(repr, self.args)
+ if self.has_varargs:
+ arg_reprs.append("...")
+ return "CFuncType(%s,[%s])" % (
+ repr(self.return_type),
+ string.join(arg_reprs, ","))
+
+ def same_c_signature_as(self, other_type, as_cmethod = 0):
+ return self.same_c_signature_as_resolved_type(
+ other_type.resolve(), as_cmethod)
+
+ def same_c_signature_as_resolved_type(self, other_type, as_cmethod):
+ if other_type is error_type:
+ return 1
+ if not other_type.is_cfunction:
+ return 0
+ nargs = len(self.args)
+ if nargs <> len(other_type.args):
+ return 0
+ # When comparing C method signatures, the first argument
+ # is exempt from compatibility checking (the proper check
+ # is performed elsewhere).
+ for i in range(as_cmethod, nargs):
+ if not self.args[i].type.same_as(
+ other_type.args[i].type):
+ return 0
+ if self.has_varargs <> other_type.has_varargs:
+ return 0
+ if not self.return_type.same_as(other_type.return_type):
+ return 0
+ return 1
+
+ def same_exception_signature_as(self, other_type):
+ return self.same_exception_signature_as_resolved_type(
+ other_type.resolve())
+
+ def same_exception_signature_as_resolved_type(self, other_type):
+ return self.exception_value == other_type.exception_value \
+ and self.exception_check == other_type.exception_check
+
+ def same_as_resolved_type(self, other_type, as_cmethod = 0):
+ return self.same_c_signature_as_resolved_type(other_type, as_cmethod) \
+ and self.same_exception_signature_as_resolved_type(other_type)
+
+ def declaration_code(self, entity_code,
+ for_display = 0, dll_linkage = None, pyrex = 0):
+ arg_decl_list = []
+ for arg in self.args:
+ arg_decl_list.append(
+ arg.type.declaration_code("", for_display, pyrex = pyrex))
+ if self.has_varargs:
+ arg_decl_list.append("...")
+ arg_decl_code = string.join(arg_decl_list, ",")
+ if not arg_decl_code and not pyrex:
+ arg_decl_code = "void"
+ exc_clause = ""
+ if pyrex or for_display:
+ if self.exception_value and self.exception_check:
+ exc_clause = " except? %s" % self.exception_value
+ elif self.exception_value:
+ exc_clause = " except %s" % self.exception_value
+ elif self.exception_check:
+ exc_clause = " except *"
+ return self.return_type.declaration_code(
+ "(%s(%s)%s)" % (entity_code, arg_decl_code, exc_clause),
+ for_display, dll_linkage, pyrex)
+
+
+class CFuncTypeArg:
+ # name string
+ # cname string
+ # type PyrexType
+ # pos source file position
+
+ def __init__(self, name, type, pos):
+ self.name = name
+ self.cname = Naming.var_prefix + name
+ self.type = type
+ self.pos = pos
+
+ def __repr__(self):
+ return "%s:%s" % (self.name, repr(self.type))
+
+ def declaration_code(self, for_display = 0):
+ return self.type.declaration_code(self.cname, for_display)
+
+
+class CStructOrUnionType(CType):
+ # name string
+ # cname string
+ # kind string "struct" or "union"
+ # scope StructOrUnionScope, or None if incomplete
+ # typedef_flag boolean
+
+ is_struct_or_union = 1
+ has_attributes = 1
+
+ def __init__(self, name, kind, scope, typedef_flag, cname):
+ self.name = name
+ self.cname = cname
+ self.kind = kind
+ self.scope = scope
+ self.typedef_flag = typedef_flag
+
+ def __repr__(self):
+ return "CStructOrUnionType(%s,%s%s)" % (self.name, self.cname,
+ ("", ",typedef_flag=1")[self.typedef_flag])
+
+ def declaration_code(self, entity_code,
+ for_display = 0, dll_linkage = None, pyrex = 0):
+ if pyrex:
+ return "%s %s" % (self.name, entity_code)
+ else:
+ if for_display:
+ base = self.name
+ elif self.typedef_flag:
+ base = self.cname
+ else:
+ base = "%s %s" % (self.kind, self.cname)
+ return "%s %s" % (public_decl(base, dll_linkage), entity_code)
+
+ def is_complete(self):
+ return self.scope is not None
+
+ def attributes_known(self):
+ return self.is_complete()
+
+
+class CEnumType(CType):
+ # name string
+ # cname string or None
+ # typedef_flag boolean
+
+ is_enum = 1
+ #signed = 1
+ #rank = 2
+ to_py_function = "PyInt_FromLong"
+ from_py_function = "PyInt_AsLong"
+
+ def __init__(self, name, cname, typedef_flag):
+ self.name = name
+ self.cname = cname
+ self.values = []
+ self.typedef_flag = typedef_flag
+
+ def __repr__(self):
+ return "CEnumType(%s,%s%s)" % (self.name, self.cname,
+ ("", ",typedef_flag=1")[self.typedef_flag])
+
+ def declaration_code(self, entity_code,
+ for_display = 0, dll_linkage = None, pyrex = 0):
+ if pyrex:
+ return "%s %s" % (self.cname, entity_code)
+ else:
+ if self.typedef_flag:
+ base = self.cname
+ else:
+ base = "enum %s" % self.cname
+ return "%s %s" % (public_decl(base, dll_linkage), entity_code)
+
+
+class CStringType:
+ # Mixin class for C string types.
+
+ is_string = 1
+
+ to_py_function = "PyString_FromString"
+ from_py_function = "PyString_AsString"
+
+ def literal_code(self, value):
+ return '"%s"' % value
+
+
+class CCharArrayType(CStringType, CArrayType):
+ # C 'char []' type.
+
+ parsetuple_format = "s"
+ pymemberdef_typecode = "T_STRING_INPLACE"
+
+ def __init__(self, size):
+ CArrayType.__init__(self, c_char_type, size)
+
+
+class CCharPtrType(CStringType, CPtrType):
+ # C 'char *' type.
+
+ parsetuple_format = "s"
+ pymemberdef_typecode = "T_STRING"
+
+ def __init__(self):
+ CPtrType.__init__(self, c_char_type)
+
+
+class ErrorType(PyrexType):
+ # Used to prevent propagation of error messages.
+
+ is_error = 1
+ exception_value = "0"
+ exception_check = 0
+ to_py_function = "dummy"
+ from_py_function = "dummy"
+
+ def declaration_code(self, entity_code,
+ for_display = 0, dll_linkage = None, pyrex = 0):
+ return "<error>"
+
+ def same_as_resolved_type(self, other_type):
+ return 1
+
+
+py_object_type = PyObjectType()
+
+c_void_type = CVoidType()
+c_void_ptr_type = CPtrType(c_void_type)
+c_void_ptr_ptr_type = CPtrType(c_void_ptr_type)
+
+c_char_type = CIntType(0, 1, "T_CHAR")
+c_short_type = CIntType(1, 1, "T_SHORT")
+c_int_type = CIntType(2, 1, "T_INT")
+c_long_type = CIntType(3, 1, "T_LONG")
+c_longlong_type = CLongLongType(4, 1, "T_LONGLONG")
+
+c_uchar_type = CIntType(0, 0, "T_UBYTE")
+c_ushort_type = CIntType(1, 0, "T_USHORT")
+c_uint_type = CUIntType(2, 0, "T_UINT")
+c_ulong_type = CULongType(3, 0, "T_ULONG")
+c_ulonglong_type = CULongLongType(4, 0, "T_ULONGLONG")
+
+c_float_type = CFloatType(5, "T_FLOAT")
+c_double_type = CFloatType(6, "T_DOUBLE")
+c_longdouble_type = CFloatType(7)
+
+c_null_ptr_type = CNullPtrType(c_void_type)
+c_char_array_type = CCharArrayType(None)
+c_char_ptr_type = CCharPtrType()
+c_char_ptr_ptr_type = CPtrType(c_char_ptr_type)
+c_int_ptr_type = CPtrType(c_int_type)
+
+c_returncode_type = CIntType(2, 1, "T_INT", is_returncode = 1)
+
+error_type = ErrorType()
+
+lowest_float_rank = 5
+
+rank_to_type_name = (
+ "char", # 0
+ "short", # 1
+ "int", # 2
+ "long", # 3
+ "PY_LONG_LONG", # 4
+ "float", # 5
+ "double", # 6
+ "long double", # 7
+)
+
+sign_and_rank_to_type = {
+ #(signed, rank)
+ (0, 0, ): c_uchar_type,
+ (0, 1): c_ushort_type,
+ (0, 2): c_uint_type,
+ (0, 3): c_ulong_type,
+ (0, 4): c_ulonglong_type,
+ (1, 0): c_char_type,
+ (1, 1): c_short_type,
+ (1, 2): c_int_type,
+ (1, 3): c_long_type,
+ (1, 4): c_longlong_type,
+ (1, 5): c_float_type,
+ (1, 6): c_double_type,
+ (1, 7): c_longdouble_type,
+}
+
+modifiers_and_name_to_type = {
+ #(signed, longness, name)
+ (0, 0, "char"): c_uchar_type,
+ (0, -1, "int"): c_ushort_type,
+ (0, 0, "int"): c_uint_type,
+ (0, 1, "int"): c_ulong_type,
+ (0, 2, "int"): c_ulonglong_type,
+ (1, 0, "void"): c_void_type,
+ (1, 0, "char"): c_char_type,
+ (1, -1, "int"): c_short_type,
+ (1, 0, "int"): c_int_type,
+ (1, 1, "int"): c_long_type,
+ (1, 2, "int"): c_longlong_type,
+ (1, 0, "float"): c_float_type,
+ (1, 0, "double"): c_double_type,
+ (1, 1, "double"): c_longdouble_type,
+ (1, 0, "object"): py_object_type,
+}
+
+def widest_numeric_type(type1, type2):
+ # Given two numeric types, return the narrowest type
+ # encompassing both of them.
+ signed = type1.signed
+ rank = max(type1.rank, type2.rank)
+ if rank >= lowest_float_rank:
+ signed = 1
+ return sign_and_rank_to_type[signed, rank]
+
+def simple_c_type(signed, longness, name):
+ # Find type descriptor for simple type given name and modifiers.
+ # Returns None if arguments don't make sense.
+ return modifiers_and_name_to_type.get((signed, longness, name))
+
+def c_array_type(base_type, size):
+ # Construct a C array type.
+ if base_type is c_char_type:
+ return CCharArrayType(size)
+ else:
+ return CArrayType(base_type, size)
+
+def c_ptr_type(base_type):
+ # Construct a C pointer type.
+ if base_type is c_char_type:
+ return c_char_ptr_type
+ else:
+ return CPtrType(base_type)
+
+def public_decl(base, dll_linkage):
+ if dll_linkage:
+ return "%s(%s)" % (dll_linkage, base)
+ else:
+ return base
+
+def same_type(type1, type2):
+ return type1.same_as(type2)
+
+def assignable_from(type1, type2):
+ return type1.assignable_from(type2)
+
+def typecast(to_type, from_type, expr_code):
+ # Return expr_code cast to a C type which can be
+ # assigned to to_type, assuming its existing C type
+ # is from_type.
+ if to_type is from_type or \
+ (not to_type.is_pyobject and assignable_from(to_type, from_type)):
+ return expr_code
+ else:
+ #print "typecast: to", to_type, "from", from_type ###
+ return to_type.cast_code(expr_code)
diff --git a/debian/pyrex/pyrex-0.9.9/Obsolete/overview.html b/debian/pyrex/pyrex-0.9.9/Obsolete/overview.html
new file mode 100644
index 00000000..f37a3e36
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Obsolete/overview.html
@@ -0,0 +1,1485 @@
+<!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"><meta name="GENERATOR" content="Mozilla/4.61 (Macintosh; I; PPC) [Netscape]"><title>Pyrex Language Overview</title></head>
+<body>
+
+
+<h1>
+<hr width="100%">Overview of the Pyrex Language&nbsp;
+<hr width="100%"></h1>
+
+
+ This document informally describes the extensions to the Python language
+ made by Pyrex. Some day there will be a reference manual covering everything
+ in more detail.&nbsp;<h2> Contents</h2>
+
+
+
+<ul>
+
+
+ <li><a href="#SourceFiles">Source Files and Compilation</a> <span style="color: rgb(0, 153, 0);">(Section added in 0.9.5)</span><br>
+ </li><li><a href="#Basics">Basics</a></li>
+
+
+
+ <ul>
+
+ <li> <a href="#PyFuncsVsCFuncs">Python functions vs. C functions</a></li>
+
+ <li> <a href="#PyObjParams">Python objects as parameters</a></li>
+
+ <li> <a href="#CVarAndTypeDecls">C variable and type definitions</a></li>
+ <li><a href="#AutomaticTypeConversions">Automatic type conversions</a></li>
+
+
+ <ul>
+
+ <li><a href="#PyToCStringCaveats">Caveats when using a Python string in a C context</a></li>
+
+
+ </ul>
+
+
+ <li> <a href="#ScopeRules">Scope rules</a></li>
+
+ <li> <a href="#StatsAndExprs">Statements and expressions</a></li>
+
+
+ <ul>
+
+ <li> <a href="#ExprSyntaxDifferences">Differences between C and Pyrex
+expressions<br>
+
+ </a></li>
+
+ <li> <a href="#ForFromLoop">Integer for-loops</a></li>
+
+
+ </ul>
+
+ <li> <a href="#ExceptionValues">Error return values</a></li>
+
+
+ <ul>
+
+ <li> <a href="#CheckingReturnValues">Checking return values of non-Pyrex
+ functions</a></li>
+
+
+ </ul>
+
+ <li> <a href="#IncludeStatement">The <tt>include</tt> statement</a></li><li><a href="#KeywordOnlyArguments">Keyword-only arguments</a><span style="color: rgb(255, 0, 0);"> (New in 0.9.6)</span></li>
+
+
+ </ul>
+
+ <li> <a href="#InterfacingWithExternal">Interfacing with External C Code</a></li>
+
+
+ <ul>
+
+ <li> <a href="#ExternDecls">External declarations</a></li>
+
+
+ <ul>
+
+ <li> <a href="#ReferencingHeaders">Referencing C header files</a></li>
+
+ <li> <a href="#StructDeclStyles">Styles of struct/union/enum declaration</a></li>
+
+ <li> <a href="#AccessingAPI">Accessing Python/C API routines</a></li><li><a href="#SpecialTypes">Special Types</a><span style="color: rgb(255, 0, 0);"> (New in 0.9.6)</span></li><li><a href="#CallingConventions">Windows Calling Conventions</a><span style="color: rgb(255, 0, 0);"> (New in 0.9.6)</span></li>
+
+ <li> <a href="#CNameSpecs">Resolving naming conflicts - C name specifications</a></li>
+
+
+ </ul><li><a href="#Using_Pyrex_Declarations_from_C">Using Pyrex declarations from C</a></li>
+
+ <ul><li> <a href="#PublicDecls">Public declarations</a></li></ul><ul><li><a href="#C_API_Declarations">C API declarations</a><span style="color: rgb(255, 0, 0);"> (New in 0.9.6)</span></li></ul>
+
+
+ </ul>
+
+ <li> <a href="extension_types.html">Extension Types</a></li>
+
+ <li> <a href="sharing.html">Sharing Declarations Between Pyrex Modules</a></li>
+
+ <li> <a href="#Limitations">Limitations</a></li>
+
+
+ <ul>
+
+ <li> <a href="#Unsupported">Unsupported Python features</a></li>
+
+ <li> <a href="#SemanticDifferences">Semantic differences between Python
+ and Pyrex</a></li>
+
+
+ </ul>
+
+
+</ul>
+
+
+
+<h2>
+<hr width="100%"></h2>
+<h2><a name="SourceFiles"></a>Source Files and Compilation<br>
+</h2>
+<hr style="width: 100%; height: 2px;"><br>
+Pyrex source file names consist of the name of the module followed by a <span style="font-family: monospace;">.pyx</span> extension, for example a module called <span style="font-family: monospace;">primes</span> would have a source file named <span style="font-family: monospace;">primes.pyx</span>.<br>
+
+<br>
+
+If your module is destined to live in a package, the source file name should include the <span style="font-style: italic;">full dotted name</span> that the module will eventually have. For example, a module called <span style="font-family: monospace;">primes</span> that will be installed in a package called <span style="font-family: monospace;">numbers</span> should have a source file called <span style="font-family: monospace;">numbers.primes.pyx</span>.
+This will ensure that the __name__ properties of the module and any
+classes defined in it are set correctly. If you don't do this, you may
+find that pickling doesn't work, among other problems. It also ensures
+that the Pyrex compiler has the right idea about the layout of the
+module namespace, which can be important when accessing extension types
+defined in other modules.<br>
+<br>
+Once you have written your .pyx file, there are a couple of ways of
+turning it into an extension module. One way is to compile it manually
+with the Pyrex compiler, e.g.<br>
+<br>
+<div style="margin-left: 40px;"><span style="font-family: monospace;">pyrexc primes.pyx</span><br>
+</div>
+<br>
+This will produce a file called <span style="font-family: monospace;">primes.c</span>,
+which then needs to be compiled with the C compiler using whatever
+options are appropriate on your platform for generating an extension
+module. There's a Makefile in the Demos directory (called <span style="font-family: monospace;">Makefile.nodistutils</span>) that shows how to do this for Linux.<br>
+<br>
+The other, and probably better, way is to use the distutils extension provided with Pyrex. See the <span style="font-family: monospace;">Setup.py</span>
+file in the Demos directory for an example of how to use it. This
+method has the advantage of being cross-platform -- the same setup file
+should work on any platform where distutils can compile an extension
+module.<br>
+<br>
+<hr style="width: 100%; height: 2px;">
+<h2><a name="Basics"></a>Language Basics
+<hr width="100%"></h2>
+This section describes the basic features of the Pyrex language. The facilities
+ covered in this section allow you to create Python-callable functions that
+ manipulate C data structures and convert between Python and C data types.
+ Later sections will cover facilities for <a href="#InterfacingWithExternal">wrapping external C code</a>, <a href="extension_types.html">creating new Python types</a> and <a href="sharing.html">cooperation between Pyrex modules</a>.<br>
+
+<h3> <a name="PyFuncsVsCFuncs"></a>Python functions vs. C functions</h3>
+
+
+ There are two kinds of function definition in Pyrex:
+<p><b>Python functions</b> are defined using the <b>def</b> statement, as
+ in Python. They take Python objects as parameters and return Python objects.
+ </p>
+
+
+
+<p><b>C functions</b> are defined using the new <b>cdef</b> statement. They
+ take either Python objects or C values as parameters, and can return either
+ Python objects or C values. </p>
+
+
+
+<p>Within a Pyrex module, Python functions and C functions can call each other
+freely, but only Python functions can be called from outside the module by
+interpreted Python code. So, any functions that you want to "export" from
+ your Pyrex module must be declared as Python functions using <span style="font-weight: bold;">def</span>. </p>
+
+
+
+<p>Parameters of either type of function can be declared to have C data types,
+ using normal C declaration syntax. For example, </p>
+
+
+
+<blockquote>
+ <pre>def spam(int i, char *s):<br>&nbsp;&nbsp;&nbsp; ...</pre>
+
+
+ <pre>cdef int eggs(unsigned long l, float f):<br>&nbsp;&nbsp;&nbsp; ...</pre>
+
+ </blockquote>
+
+
+ When a parameter of a Python function is declared to have a C data type,
+ it is passed in as a Python object and automatically converted to a C value,
+ if possible. Automatic conversion is currently only possible for numeric
+types and string types; attempting to use any other type for the parameter
+of a Python function will result in a compile-time error.
+<p>C functions, on the other hand, can have parameters of any type, since
+ they're passed in directly using a normal C function call. </p>
+
+
+
+<h3> <a name="PyObjParams"></a>Python objects as parameters and return values</h3>
+
+
+ If no type is specified for a parameter or return value, <i>it is assumed
+ to be a Python object.</i> (Note that this is different from the C convention,
+ where it would default to <tt>int</tt>.) For example, the following defines
+ a C function that takes two Python objects as parameters and returns a Python
+ object:
+<blockquote>
+ <pre>cdef spamobjs(x, y):<br>&nbsp;&nbsp;&nbsp; ...</pre>
+
+ </blockquote>
+
+
+ Reference counting for these objects is performed automatically according
+ to the standard Python/C API rules (i.e. borrowed references are taken as
+ parameters and a new reference is returned).
+<p>The name <b>object</b> can also be used to explicitly declare something
+ as a Python object. This can be useful if the name being declared would otherwise
+be taken as the name of a type, for example, </p>
+
+
+
+<blockquote>
+ <pre>cdef ftang(object int):<br>&nbsp;&nbsp;&nbsp; ...</pre>
+
+ </blockquote>
+
+
+ declares a parameter called <tt>int</tt> which is a Python object. You
+can also use <b>object </b>as the explicit return type of a function, e.g.
+
+<blockquote>
+ <pre>cdef object ftang(object int):<br>&nbsp;&nbsp;&nbsp; ...</pre>
+
+ </blockquote>
+
+
+ In the interests of clarity, it is probably a good idea to always be explicit
+ about <b>object </b>parameters in C functions.
+<h3> <a name="CVarAndTypeDecls"></a>C variable and type definitions</h3>
+
+
+ The <b>cdef</b> statement is also used to declare C variables, either
+local or module-level:
+<blockquote>
+ <pre>cdef int i, j, k<br>cdef float f, g[42], *h</pre>
+
+ </blockquote>
+
+
+ and C struct, union or enum types:
+<blockquote>
+ <pre>cdef struct Grail:<br>&nbsp;&nbsp;&nbsp; int age<br>&nbsp;&nbsp;&nbsp; float volume</pre>
+
+
+ <pre>cdef union Food:<br>&nbsp;&nbsp;&nbsp; char *spam<br>&nbsp;&nbsp;&nbsp; float *eggs</pre>
+
+
+ <pre>cdef enum CheeseType:<br>&nbsp;&nbsp;&nbsp; cheddar, edam,&nbsp;<br>&nbsp;&nbsp;&nbsp; camembert</pre>
+
+
+ <pre>cdef enum CheeseState:<br>&nbsp;&nbsp;&nbsp; hard = 1<br>&nbsp;&nbsp;&nbsp; soft = 2<br>&nbsp;&nbsp;&nbsp; runny = 3</pre>
+
+ </blockquote>
+
+
+ There is currently no special syntax for defining a constant, but you
+can use an anonymous enum declaration for this purpose, for example,
+<blockquote><tt>cdef enum:</tt> <br>
+
+ <tt>&nbsp;&nbsp;&nbsp; tons_of_spam = 3</tt></blockquote>
+
+
+ Note that the words <span style="font-family: monospace;">struct</span>, <span style="font-family: monospace;">union</span> and <span style="font-family: monospace;">enum</span> are used only when <i>defining</i> a type, not when referring to it. For example, to declare a variable pointing
+ to a Grail you would write
+<blockquote>
+ <pre>cdef Grail *gp</pre>
+
+ </blockquote>
+
+
+ and <i>not</i>
+<blockquote>
+ <pre>cdef struct Grail *gp <font color="#ed181e"># WRONG</font></pre>
+
+ </blockquote>
+
+
+ There is also a <b>ctypedef</b> statement for giving names to types, e.g.
+
+<blockquote>
+ <pre>ctypedef unsigned long ULong</pre>
+
+
+ <pre>ctypedef int *IntPtr<br></pre>
+</blockquote>
+
+
+<h3><a name="AutomaticTypeConversions"></a>Automatic type conversions</h3>
+
+
+In most situations, automatic conversions will be performed for the
+basic numeric and string types when a Python object is used in a
+context requiring a C value, or vice versa. The following table
+summarises the conversion possibilities.<br>
+
+
+<br>
+
+
+<table style="margin-left: auto; margin-right: auto; width: 10%; text-align: left;" border="1" cellpadding="4" cellspacing="0">
+
+
+ <tbody>
+
+ <tr>
+
+ <th style="vertical-align: top; width: 40%; white-space: nowrap;">C types<br>
+
+ </th>
+
+ <th style="vertical-align: top; width: 150px; white-space: nowrap;">From Python types<br>
+
+ </th>
+
+ <th style="vertical-align: top; width: 150px; white-space: nowrap;">To Python types<br>
+
+ </th>
+
+ </tr>
+
+ <tr>
+
+ <td colspan="1" rowspan="1" style="vertical-align: top; width: 40%; white-space: nowrap;">[unsigned] char<br>
+
+[unsigned] short<br>
+
+ int, long</td>
+
+ <td colspan="1" rowspan="1" style="vertical-align: top; width: 150px; white-space: nowrap;">int, long<br>
+
+ </td>
+
+ <td colspan="1" rowspan="1" style="vertical-align: top; width: 150px; white-space: nowrap;">int<br>
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ </tr>
+
+
+ <tr>
+
+ <td colspan="1" rowspan="1" style="vertical-align: top; width: 40%; white-space: nowrap;">unsigned int<br>
+
+unsigned long<br>
+
+ [unsigned] long long<br>
+
+
+ </td>
+
+ <td colspan="1" rowspan="1" style="vertical-align: top; white-space: nowrap;">int, long<br>
+
+ <br>
+
+
+ </td>
+
+ <td colspan="1" rowspan="1" style="vertical-align: top; white-space: nowrap;">long<br>
+
+ <br>
+
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+
+
+
+ </tr>
+
+ <tr>
+
+ <td style="vertical-align: top; width: 40%; white-space: nowrap;">float, double, long double<br>
+
+ </td>
+
+ <td style="vertical-align: top; width: 150px; white-space: nowrap;">int, long, float<br>
+
+ </td>
+
+ <td style="vertical-align: top; width: 150px; white-space: nowrap;">float<br>
+
+ </td>
+
+ </tr>
+
+ <tr>
+
+ <td style="vertical-align: top; width: 40%; white-space: nowrap;">char *<br>
+
+ </td>
+
+ <td style="vertical-align: top; width: 150px; white-space: nowrap;">str<span style="font-style: italic;"></span><br>
+
+ </td>
+
+ <td style="vertical-align: top; width: 150px; white-space: nowrap;">str<br>
+
+ </td>
+
+ </tr>
+
+
+ </tbody>
+</table>
+
+
+<br>
+
+
+<h4><a name="PyToCStringCaveats"></a>Caveats when using a Python string in a C context</h4>
+
+
+You need to be careful when using a Python string in a context expecting a <span style="font-family: monospace;">char *</span>.
+In this situation, a pointer to the contents of the Python string is
+used, which is only valid as long as the Python string exists. So you
+need to make sure that a reference to the original Python string is
+held for as long as the C string is needed. If you can't guarantee that
+the Python string will live long enough, you will need to copy the C
+string.<br>
+
+
+<br>
+
+
+Pyrex detects and prevents <span style="font-style: italic;">some</span> mistakes of this kind. For instance, if you attempt something like<br>
+
+
+<pre style="margin-left: 40px;">cdef char *s<br>s = pystring1 + pystring2</pre>
+
+
+then Pyrex will produce the error message "<span style="font-weight: bold;">Obtaining char * from temporary Python value</span>".
+The reason is that concatenating the two Python strings produces a new
+Python string object that is referenced only by a temporary internal
+variable that Pyrex generates. As soon as the statement has finished,
+the temporary variable will be decrefed and the Python string
+deallocated, leaving <span style="font-family: monospace;">s</span> dangling. Since this code could not possibly work, Pyrex refuses to compile it.<br>
+
+
+<br>
+
+
+The solution is to assign the result of the concatenation to a Python variable, and then obtain the char * from that, i.e.<br>
+
+
+<pre style="margin-left: 40px;">cdef char *s<br>p = pystring1 + pystring2<br>s = p<br></pre>
+
+
+It is then your responsibility to hold the reference <span style="font-family: monospace;">p</span> for as long as necessary.<br>
+
+
+<br>
+
+
+Keep in mind that the rules used to detect such errors are only
+heuristics. Sometimes Pyrex will complain unnecessarily, and sometimes
+it will fail to detect a problem that exists. Ultimately, you need to
+understand the issue and be careful what you do.
+
+
+
+
+<h3> <a name="ScopeRules"></a>Scope rules</h3>
+
+
+ Pyrex determines whether a variable belongs to a local scope, the module
+ scope, or the built-in scope <i>completely statically.</i> As with Python,
+ assigning to a variable which is not otherwise declared implicitly declares
+ it to be a Python variable residing in the scope where it is assigned. Unlike
+ Python, however, a name which is referred to but not declared or assigned
+ is assumed to reside in the <i>builtin scope, </i>not the module scope.
+Names added to the module dictionary at run time will not shadow such names.
+
+<p>You can use a <b>global</b> statement at the module level to explicitly
+ declare a name to be a module-level name when there would otherwise not be
+any indication of this, for example, </p>
+
+
+
+<blockquote><tt>global __name__</tt> <br>
+
+ <tt>print __name__</tt></blockquote>
+
+
+ Without the <b>global</b> statement, the above would print the name of
+the builtins module.<br>
+
+
+ <br>
+
+
+ Note: A consequence of these rules is that the module-level scope behaves
+ the same way as a Python local scope if you refer to a variable before assigning
+ to it. In particular, tricks such as the following will <i>not</i> work
+in Pyrex:<br>
+
+
+
+<blockquote>
+ <pre>try:<br>&nbsp; x = True<br>except NameError:<br>&nbsp; True = 1<br></pre>
+
+ </blockquote>
+
+
+ because, due to the assignment, the True will always be looked up in the
+ module-level scope. You would have to do something like this instead:<br>
+
+
+
+<blockquote>
+ <pre>import __builtin__<br>try:<br> True = __builtin__.True<br>except AttributeError:<br> True = 1<br></pre>
+
+ </blockquote>
+
+
+
+<hr width="100%">
+<h3> <a name="StatsAndExprs"></a>Statements and expressions</h3>
+
+
+ Control structures and expressions follow Python syntax for the most part.
+ When applied to Python objects, they have the same semantics as in Python
+ (unless otherwise noted). Most of the Python operators can also be applied
+ to C values, with the obvious semantics.
+<p>If Python objects and C values are mixed in an expression, conversions
+ are performed automatically between Python objects and C numeric or string
+ types. </p>
+
+
+
+<p>Reference counts are maintained automatically for all Python objects, and
+all Python operations are automatically checked for errors, with appropriate
+ action taken. </p>
+
+
+
+<h4> <a name="ExprSyntaxDifferences"></a>Differences between C and Pyrex
+expressions</h4>
+
+There
+are some differences in syntax and semantics between C expressions and
+Pyrex expressions, particularly in the area of C constructs which have
+no direct equivalent in Python.<br>
+
+
+<ul>
+
+ <li>An integer literal without an <span style="font-family: monospace; font-weight: bold;">L</span> suffix is treated as a C constant, and will be truncated to whatever size your C compiler thinks appropriate. With an <span style="font-family: monospace; font-weight: bold;">L</span> suffix, it will be converted to Python long integer (even if it would be small enough to fit into a C int).<br>
+
+ <br>
+
+ </li>
+
+ <li> There is no <b><tt>-&gt;</tt></b> operator in Pyrex. Instead of <tt>p-&gt;x</tt>,
+ use <tt>p.x</tt></li>
+
+
+ &nbsp; <li> There is no <b><tt>*</tt></b> operator in Pyrex. Instead of
+ <tt>*p</tt>, use <tt>p[0]</tt></li>
+
+
+ &nbsp; <li> There is an <b><tt>&amp;</tt></b> operator, with the same semantics
+ as in C.</li>
+
+
+ &nbsp; <li> The null C pointer is called <b><tt>NULL</tt></b>, not 0 (and
+ <tt>NULL</tt> is a reserved word).</li>
+
+
+ &nbsp; <li> Character literals are written with a <b>c</b> prefix, for
+example:</li>
+
+
+ <ul>
+
+
+ <pre>c'X'</pre>
+
+
+ </ul>
+
+ <li> Type casts are written <b><tt>&lt;type&gt;value</tt></b> , for example:</li>
+
+
+ <ul>
+
+
+ <pre>cdef char *p, float *q<br>p = &lt;char*&gt;q</pre>
+
+
+ </ul>
+
+ <i><b>Warning</b>: Don't attempt to use a typecast to convert between
+Python and C data types -- it won't do the right thing. Leave Pyrex to perform
+the conversion automatically.</i>
+</ul>
+
+
+
+<h4> <a name="ForFromLoop"></a>Integer for-loops</h4>
+
+
+ You should be aware that a for-loop such as
+<blockquote><tt>for i in range(n):</tt> <br>
+
+ <tt>&nbsp;&nbsp;&nbsp; ...</tt></blockquote>
+
+
+ won't be very fast, even if <tt>i</tt> and <tt>n</tt> are declared as
+C integers, because <tt>range</tt> is a Python function. For iterating over
+ranges of integers, Pyrex has another form of for-loop:
+<blockquote><tt>for i from 0 &lt;= i &lt; n:</tt> <br>
+
+ <tt>&nbsp;&nbsp;&nbsp; ...</tt></blockquote>
+
+
+ If the loop variable and the lower and upper bounds are all C integers,
+this form of loop will be much faster, because Pyrex will translate it into
+pure C code.
+<p>Some things to note about the <tt>for-from</tt> loop: </p>
+
+
+
+<ul>
+
+
+ <li> The target expression must be a variable name.</li>
+
+ <li> The name between the lower and upper bounds must be the same as
+the target name.</li>
+
+ <li> The direction of iteration is determined by the relations. If they
+ are both from the set {<tt>&lt;</tt>, <tt>&lt;=</tt>} then it is upwards;
+ if they are both from the set {<tt>&gt;</tt>, <tt>&gt;=</tt>} then it is
+downwards. (Any other combination is disallowed.)</li>
+
+
+</ul>
+
+
+ Like other Python looping statements, <tt>break</tt> and <tt>continue</tt> may be used in the body, and the loop may have an <tt>else</tt> clause.
+
+<h2>
+<hr width="100%"></h2>
+
+
+
+<h3> <a name="ExceptionValues"></a>Error return values</h3>
+
+
+ If you don't do anything special, a function declared with <b>cdef</b> that does not return a Python object has no way of reporting Python exceptions
+ to its caller. If an exception is detected in such a function, a warning
+message is printed and the exception is ignored.
+<p>If you want a C function that does not return a Python object to be able
+ to propagate exceptions to its caller, you need to declare an <b>exception
+ value</b> for it. Here is an example: </p>
+
+
+
+<blockquote><tt>cdef int spam() except -1:</tt> <br>
+
+ <tt>&nbsp;&nbsp;&nbsp; ...</tt></blockquote>
+
+
+ With this declaration, whenever an exception occurs inside <tt>spam</tt>,
+ it will immediately return with the value <tt>-1</tt>. Furthermore, whenever
+ a call to <tt>spam</tt> returns <tt>-1</tt>, an exception will be assumed
+ to have occurred and will be propagated.
+<p>When you declare an exception value for a function, you should never explicitly
+ return that value. If all possible return values are legal and you can't
+reserve one entirely for signalling errors, you can use an alternative form
+of exception value declaration: </p>
+
+
+
+<blockquote><tt>cdef int spam() except? -1:</tt> <br>
+
+ <tt>&nbsp;&nbsp;&nbsp; ...</tt></blockquote>
+
+
+ The "?" indicates that the value <tt>-1</tt> only indicates a <i>possible</i> error. In this case, Pyrex generates a call to <tt>PyErr_Occurred</tt> if the
+exception value is returned, to make sure it really is an error.
+<p>There is also a third form of exception value declaration: </p>
+
+
+
+<blockquote><tt>cdef int spam() except *:</tt> <br>
+
+ <tt>&nbsp;&nbsp;&nbsp; ...</tt></blockquote>
+
+
+ This form causes Pyrex to generate a call to <tt>PyErr_Occurred</tt> after
+ <i>every</i> call to <code>spam</code>, regardless of what value it returns. If you have
+ a function returning <tt>void</tt> that needs to propagate errors, you will
+ have to use this form, since there isn't any return value to test.
+<p>Some things to note: </p>
+
+
+
+<ul>
+
+
+ <li>Exception values can only declared for functions returning
+ an integer, enum, float or pointer type, and the value must be a constant expression. The only possible pointer
+ exception value is <tt>NULL</tt>. Void functions can only use the <tt>except
+ *</tt> form.</li>
+
+
+ &nbsp; <li> The exception value specification is part of the signature
+of the function. If you're passing a pointer to a function as a parameter
+or assigning it to a variable, the declared type of the parameter or variable
+ must have the same exception value specification (or lack thereof). Here
+is an example of a pointer-to-function declaration with an exception value:</li>
+
+
+ <ul>
+
+
+ <pre><tt>int (*grail)(int, char *) except -1</tt></pre>
+
+
+ </ul>
+
+ <li> You don't need to (and shouldn't) declare exception values for functions
+ which return Python objects. Remember that a function with no declared return
+ type implicitly returns a Python object.</li>
+
+
+</ul>
+
+
+
+<h4> <a name="CheckingReturnValues"></a>Checking return values of non-Pyrex
+ functions</h4>
+
+
+ It's important to understand that the <tt>except</tt> clause does <i>not</i> cause an error to be <i>raised</i> when the specified value is returned. For
+example, you can't write something like
+<blockquote>
+ <pre>cdef extern FILE *fopen(char *filename, char *mode) except NULL <font color="#ed181e"># WRONG!</font></pre>
+
+ </blockquote>
+
+
+ and expect an exception to be automatically raised if a call to fopen
+returns NULL. The except clause doesn't work that way; its only purpose
+is for <i>propagating</i> exceptions that have already been raised, either
+by a Pyrex function or a C function that calls Python/C API routines. To
+get an exception from a non-Python-aware function such as fopen, you will
+have to check the return value and raise it yourself, for example,
+<blockquote>
+ <pre>cdef FILE *p<br>p = fopen("spam.txt", "r")<br>if p == NULL:<br>&nbsp;&nbsp;&nbsp; raise SpamError("Couldn't open the spam file")</pre>
+
+ </blockquote>
+
+
+
+<h4>
+<hr width="100%"></h4>
+
+
+
+<h3> <a name="IncludeStatement"></a>The <tt>include</tt> statement</h3>
+
+
+ For convenience, a large Pyrex module can be split up into a number of
+files which are put together using the <b>include</b> statement, for example
+
+<blockquote>
+ <pre>include "spamstuff.pxi"</pre>
+
+ </blockquote>
+
+
+ The contents of the named file are textually included at that point. The
+ included file can contain any complete top-level Pyrex statements, including
+ other <b>include</b> statements. The <b>include</b> statement itself can
+only appear at the top level of a file.
+<p>The <b>include</b> statement can also be used in conjunction with <a href="#PublicDecls"><b>public</b> declarations</a> to make C functions and
+ variables defined in one Pyrex module accessible to another. However, note
+ that some of these uses have been superseded by the facilities described
+in <a href="sharing.html">Sharing Declarations Between Pyrex Modules</a>,
+and it is expected that use of the <b>include</b> statement for this purpose
+will be phased out altogether in future versions.</p><hr style="width: 100%; height: 2px;"><h3><a name="KeywordOnlyArguments"></a>Keyword-only arguments</h3><p>Python functions can have keyword-only arguments listed after the * parameter and before the ** paramter if any, e.g.</p><pre style="margin-left: 40px;">def f(a, b, *args, c, d = 42, e, **kwds):<br> ...<br></pre>Here
+c, d and e cannot be passed as position arguments and must be passed as
+keyword arguments. Furthermore, c and e are required keyword arguments,
+since they do not have a default value.<br><br>If the parameter name after the * is omitted, the function will not accept any extra positional arguments, e.g.<br><br><pre style="margin-left: 40px;">def g(a, b, *, c, d):<br> ...<br></pre>takes exactly two positional parameters and has two required keyword parameters.
+
+
+
+<h2>
+<hr width="100%"><a name="InterfacingWithExternal"></a>Interfacing with External
+ C Code
+<hr width="100%"></h2>
+
+
+ One of the main uses of Pyrex is wrapping existing libraries of C code.
+This is achieved by using <a href="#ExternDecls">external declarations</a> to declare the C functions and variables from the library that you want to
+ use.
+<p>You can also use <a href="#PublicDecls">public declarations</a> to make
+ C functions and variables defined in a Pyrex module available to external
+ C code. The need for this is expected to be less frequent, but you might
+want to do it, for example, if you are embedding Python in another application
+ as a scripting language. Just as a Pyrex module can be used as a bridge to
+allow Python code to call C code, it can also be used to allow C code to
+call Python code. </p>
+
+
+
+<h3> <a name="ExternDecls"></a>External declarations</h3>
+
+
+ By default, C functions and variables declared at the module level are
+local to the module (i.e. they have the C <b>static</b> storage class). They
+can also be declared <b>extern</b> to specify that they are defined elsewhere,
+ for example:
+<blockquote>
+ <pre>cdef extern int spam_counter</pre>
+
+
+ <pre>cdef extern void order_spam(int tons)</pre>
+
+ </blockquote>
+
+
+
+<blockquote> </blockquote>
+
+
+
+<h4> <a name="ReferencingHeaders"></a>Referencing C header files</h4>
+
+
+ When you use an extern definition on its own as in the examples above,
+Pyrex includes a declaration for it in the generated C file. This can cause
+problems if the declaration doesn't exactly match the declaration that will
+be seen by other C code. If you're wrapping an existing C library, for example,
+it's important that the generated C code is compiled with exactly the same
+declarations as the rest of the library.
+<p>To achieve this, you can tell Pyrex that the declarations are to be found
+ in a C header file, like this: </p>
+
+
+
+<blockquote>
+ <pre>cdef extern from "spam.h":</pre>
+
+
+ <pre>&nbsp;&nbsp;&nbsp; int spam_counter</pre>
+
+
+ <pre>&nbsp;&nbsp;&nbsp; void order_spam(int tons)</pre>
+
+ </blockquote>
+
+
+ The <b>cdef extern from</b> clause does three things:
+<ol>
+
+
+ <li> It directs Pyrex to place a <b>#include</b> statement for the named
+ header file in the generated C code.<br>
+
+ </li>
+
+ &nbsp; <li> It prevents Pyrex from generating any C code for the declarations
+ found in the associated block.<br>
+
+ </li>
+
+ &nbsp; <li> It treats all declarations within the block as though they
+started with <b>cdef extern</b>.</li>
+
+
+</ol>
+
+
+ It's important to understand that Pyrex does <i>not</i> itself read the
+C header file, so you still need to provide Pyrex versions of any declarations
+ from it that you use. However, the Pyrex declarations don't always have to
+exactly match the C ones, and in some cases they shouldn't or can't. In particular:
+
+<ol>
+
+
+ <li> Don't use <b>const</b>. Pyrex doesn't know anything about const,
+so just leave it out. Most of the time this shouldn't cause any problem,
+although on rare occasions you might have to use a cast.<sup><a href="#Footnote1"> 1</a></sup><br>
+
+ </li>
+
+ &nbsp; <li> Leave out any platform-specific extensions to C declarations
+ such as <b>__declspec()</b>.<br>
+
+ </li>
+
+ &nbsp; <li> If the header file declares a big struct and you only want
+to use a few members, you only need to declare the members you're interested
+in. Leaving the rest out doesn't do any harm, because the C compiler will
+use the full definition from the header file.<br>
+
+ <br>
+
+ In some cases, you might not need <i>any</i> of the struct's members, in
+which case you can just put <tt>pass</tt> in the body of the struct declaration,
+e.g.<br>
+
+ <br>
+
+ <tt>&nbsp; &nbsp; cdef extern from "foo.h":<br>
+
+ &nbsp; &nbsp; &nbsp; &nbsp; struct spam:<br>
+
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pass</tt><br>
+
+ <br>
+
+Note that you can only do this inside a <b>cdef extern from</b> block; struct
+declarations anywhere else must be non-empty.<br>
+
+ <br>
+
+ </li>
+
+ <li> If the header file uses typedef names such as <b>size_t </b>to refer
+to platform-dependent flavours of numeric types, you will need a corresponding
+ <b>ctypedef</b> statement, but you don't need to match the type exactly,
+ just use something of the right general kind (int, float, etc). For example,</li>
+
+
+ <ol>
+
+
+ <pre>ctypedef int size_t</pre>
+
+
+ </ol>
+
+ will work okay whatever the actual size of a size_t is (provided the header
+ file defines it correctly). <br>
+
+ &nbsp; <li> If the header file uses macros to define constants, translate
+ them into a dummy <b>enum</b> declaration.<br>
+
+ </li>
+
+ &nbsp; <li> If the header file defines a function using a macro, declare
+ it as though it were an ordinary function, with appropriate argument and
+result types.</li>
+
+
+</ol>
+
+
+ A few more tricks and tips:
+<ul>
+
+
+ <li> If you want to include a C header because it's needed by another
+header, but don't want to use any declarations from it, put <tt><font size="+1">pass</font></tt> in the extern-from block:</li>
+
+
+</ul>
+
+
+
+<ul>
+
+
+
+ <ul>
+
+ <tt>cdef extern from "spam.h":</tt> <br>
+
+ <tt>&nbsp;&nbsp;&nbsp; pass</tt>
+ </ul>
+
+
+</ul>
+
+
+
+<ul>
+
+
+ <li> If you want to include some external declarations, but don't want
+to specify a header file (because it's included by some other header that
+you've already included) you can put <tt>*</tt> in place of the header file
+name:</li>
+
+
+</ul>
+
+
+
+<blockquote>
+ <blockquote><tt>cdef extern from *:</tt> <br>
+
+ <tt>&nbsp;&nbsp;&nbsp; ...</tt></blockquote>
+
+ </blockquote>
+
+
+
+<h4> <a name="StructDeclStyles"></a>Styles of struct, union and enum declaration</h4>
+
+
+ There are two main ways that structs, unions and enums can be declared
+in C header files: using a tag name, or using a typedef. There are also some
+ variations based on various combinations of these.
+<p>It's important to make the Pyrex declarations match the style used in the
+header file, so that Pyrex can emit the right sort of references to the type
+in the code it generates. To make this possible, Pyrex provides two different
+syntaxes for declaring a struct, union or enum type. The style introduced
+above corresponds to the use of a tag name. To get the other style, you prefix
+the declaration with <b>ctypedef</b>, as illustrated below. </p>
+
+
+
+<p>The following table shows the various possible styles that can be found
+ in a header file, and the corresponding Pyrex declaration that you should
+ put in the <b>cdef exern from </b>block. Struct declarations are used as
+an example; the same applies equally to union and enum declarations. </p>
+
+
+
+<p>Note that in all the cases below, you refer to the type in Pyrex code simply
+as <tt><font size="+1">Foo</font></tt>, not <tt><font size="+1">struct Foo</font></tt>.
+ <br>
+
+ &nbsp;
+<table cellpadding="5">
+
+ <tbody>
+
+ <tr bgcolor="#8cbc1c" valign="top">
+
+ <td bgcolor="#8cbc1c">&nbsp;</td>
+
+ <td bgcolor="#ff9933" nowrap="nowrap"><b>C code</b></td>
+
+ <td bgcolor="#66cccc" valign="top"><b>Possibilities for corresponding
+Pyrex code</b></td>
+
+ <td bgcolor="#99cc33" valign="top"><b>Comments</b></td>
+
+ </tr>
+
+ <tr bgcolor="#8cbc1c" valign="top">
+
+ <td>1</td>
+
+ <td bgcolor="#ff9900"><tt>struct Foo {</tt> <br>
+
+ <tt>&nbsp; ...</tt> <br>
+
+ <tt>};</tt></td>
+
+ <td bgcolor="#66cccc"><tt>cdef struct Foo:</tt> <br>
+
+ <tt>&nbsp; ...</tt></td>
+
+ <td>Pyrex will refer to the type as <tt>struct Foo </tt>in the generated
+ C code<tt>.</tt></td>
+
+ </tr>
+
+ <tr bgcolor="#8cbc1c" valign="top">
+
+ <td valign="top">2</td>
+
+ <td bgcolor="#ff9900" nowrap="nowrap"><tt>typedef struct {</tt> <br>
+
+ <tt>&nbsp; ...</tt> <br>
+
+ <tt>} Foo;</tt></td>
+
+ <td bgcolor="#66cccc" valign="top"><tt>ctypedef struct Foo:</tt> <br>
+
+ <tt>&nbsp; ...</tt></td>
+
+ <td valign="top">Pyrex will refer to the type simply as <tt>Foo</tt>
+in the generated C code.</td>
+
+ </tr>
+
+ <tr bgcolor="#8cbc1c" valign="top">
+
+ <td rowspan="2">3</td>
+
+ <td rowspan="2" bgcolor="#ff9900" nowrap="nowrap"><tt>typedef struct
+foo {</tt> <br>
+
+ <tt>&nbsp; ...</tt> <br>
+
+ <tt>} Foo;</tt></td>
+
+ <td bgcolor="#66cccc" nowrap="nowrap" valign="top"><tt>cdef struct foo:</tt> <br>
+
+ <tt>&nbsp; ...</tt> <br>
+
+ <tt>ctypedef foo Foo #optional</tt></td>
+
+ <td rowspan="2" valign="top">If the C header uses both a tag and a typedef
+ with <i>different</i> names, you can use either form of declaration in Pyrex
+ (although if you need to forward reference the type, you'll have to use
+the first form).</td>
+
+ </tr>
+
+ <tr>
+
+ <td bgcolor="#66cccc"><tt>ctypedef struct Foo:</tt> <br>
+
+ <tt>&nbsp; ...</tt></td>
+
+ </tr>
+
+ <tr bgcolor="#8cbc1c" valign="top">
+
+ <td>4</td>
+
+ <td bgcolor="#ff9900" nowrap="nowrap"><tt>typedef struct Foo {</tt> <br>
+
+ <tt>&nbsp; ...</tt> <br>
+
+ <tt>} Foo;</tt></td>
+
+ <td bgcolor="#66cccc" valign="top"><tt>cdef struct Foo:</tt> <br>
+
+ <tt>&nbsp; ...</tt></td>
+
+ <td>If the header uses the <i>same</i> name for the tag and the typedef,
+ you won't be able to include a <b>ctypedef</b> for it -- but then, it's not
+necessary.</td>
+
+ </tr>
+
+
+ </tbody>
+</table>
+
+ </p>
+
+
+
+<h4> <a name="AccessingAPI"></a>Accessing Python/C API routines</h4>
+
+
+ One particular use of the <b>cdef extern from</b> statement is for gaining
+ access to routines in the Python/C API. For example,
+<blockquote>
+ <pre>cdef extern from "Python.h":</pre>
+
+
+ <pre>&nbsp;&nbsp;&nbsp; object PyString_FromStringAndSize(char *s, Py_ssize_t len)</pre>
+
+ </blockquote>
+
+
+ will allow you to create Python strings containing null bytes.
+<h4> <a name="SpecialTypes"></a>Special Types</h4><p>Pyrex predefines the name <span style="font-family: monospace;">Py_ssize_t</span>
+for use with Python/C API routines. To make your extensions compatible
+with 64-bit systems, you should always use this type where it is
+specified in the documentation of Python/C API routines.</p><h4><a name="CallingConventions"></a>Windows Calling Conventions</h4><p>The <span style="font-family: monospace;">__stdcall</span> and <span style="font-family: monospace;">__cdecl</span> calling convention specifiers can be used in Pyrex, with the same syntax as used by C compilers on Windows, for example,</p><pre style="margin-left: 40px;">cdef extern int __stdcall FrobnicateWindow(long handle)<br><br>cdef void (__stdcall *callback)(void *)<br></pre>If __stdcall is used, the function is only considered compatible with other __stdcall functions of the same signature.<br>
+
+
+
+<hr width="100%">
+<h3> <a name="CNameSpecs"></a>Resolving naming conflicts - C name specifications</h3>
+
+
+ Each Pyrex module has a single module-level namespace for both Python
+and C names. This can be inconvenient if you want to wrap some external
+C functions and provide the Python user with Python functions of the same
+names.
+<p>Pyrex 0.8 provides a couple of different ways of solving this problem.
+ The best way, especially if you have many C functions to wrap, is probably
+ to put the extern C function declarations into a different namespace using
+ the facilities described in the section on <a href="sharing.html">sharing
+ declarations between Pyrex modules</a>. </p>
+
+
+
+<p>The other way is to use a <b>c name specification</b> to give different
+ Pyrex and C names to the C function. Suppose, for example, that you want
+to wrap an external function called <tt>eject_tomato</tt>. If you declare
+it as </p>
+
+
+
+<blockquote>
+ <pre>cdef extern void c_eject_tomato "eject_tomato" (float speed)</pre>
+
+ </blockquote>
+
+
+ then its name inside the Pyrex module will be <tt>c_eject_tomato</tt>,
+whereas its name in C will be <tt>eject_tomato</tt>. You can then wrap it
+with
+<blockquote>
+ <pre>def eject_tomato(speed):<br>&nbsp; c_eject_tomato(speed)</pre>
+
+ </blockquote>
+
+
+ so that users of your module can refer to it as <tt>eject_tomato</tt>.
+
+<p>Another use for this feature is referring to external names that happen
+ to be Pyrex keywords. For example, if you want to call an external function
+ called <tt>print</tt>, you can rename it to something else in your Pyrex
+module. </p>
+
+
+
+<p>As well as functions, C names can be specified for variables, structs,
+ unions, enums, struct and union members, and enum values. For example, </p>
+
+
+
+<blockquote>
+ <pre>cdef extern int one "ein", two "zwei"<br>cdef extern float three "drei"<br><br>cdef struct spam "SPAM":<br>&nbsp; int i "eye"</pre>
+
+ <tt>cdef enum surprise "inquisition":</tt> <br>
+
+ <tt>&nbsp; first "alpha"</tt> <br>
+
+ <tt>&nbsp; second "beta" = 3</tt></blockquote>
+
+
+
+<hr width="100%">
+<h3><a name="Using_Pyrex_Declarations_from_C"></a>Using Pyrex Declarations from C</h3>Pyrex
+provides two methods for making C declarations from a Pyrex module
+available for use by external C code &#8211; public declarations and C API
+declarations.<br><br><div style="margin-left: 40px;"><span style="font-weight: bold;">NOTE:</span> You do <span style="font-style: italic;">not</span> need to use either of these to make declarations from one Pyrex module available to another Pyrex module &#8211; you should use the <span style="font-weight: bold;">cimport</span> statement for that. <a href="sharing.html">Sharing Declarations Between
+ Pyrex Modules</a>.</div><h4><a name="PublicDecls"></a>Public Declarations</h4>
+
+
+ You can make C types, variables and functions defined in a Pyrex module accessible
+ to C code that is linked with the module, by declaring them with the <b><tt>public</tt></b> keyword:
+<blockquote><tt>cdef public struct Bunny: # public type declaration<br>&nbsp; &nbsp; int vorpalness<br><br>cdef public int spam # public variable declaration</tt>
+ <p><tt>cdef public void grail(Bunny *): # public function declaration</tt> <br>
+
+ <tt>&nbsp;&nbsp;&nbsp; ...</tt></p>
+
+ </blockquote>
+
+
+ If there are any <tt>public</tt> declarations in a Pyrex module, a header file called <b><span style="font-style: italic;">modulename</span>.h</b> file is generated containing equivalent C declarations for inclusion in other
+ C code.<br><br>Any
+C code wanting to make use of these declarations will need to be
+linked, either statically or dynamically, with the extension module.<br><br>If
+the Pyrex module resides within a package, then the name of the .h file
+consists of the full dotted name of the module, e.g. a module called <span style="font-weight: bold;">foo.spam</span> would have a header file called <span style="font-weight: bold;">foo.spam.h</span>.
+<h4><a name="C_API_Declarations"></a>C API Declarations</h4><p>The other way of making functions available to C code is by declaring them with the <span style="font-family: monospace; font-weight: bold;">api</span> keyword. A header file called "<span style="font-weight: bold;"><span style="font-style: italic;">modulename</span>_api.h</span>" is produced containing declarations of the functions, and a function called <span style="font-weight: bold;">import_<span style="font-style: italic;">modulename</span>()</span>.</p><p>C code wanting to use the functions needs to include the header and call the import_<span style="font-style: italic;">modulename</span>() function. The other functions can then be called as usual.</p><p>Any <span style="font-family: monospace;">public</span> type declarations in the Pyrex module are also made available when you include <span style="font-style: italic;">modulename</span>_api.h.</p><table style="text-align: left; width: 100%;" border="0" cellpadding="5" cellspacing="2"><tbody><tr><td style="background-color: rgb(102, 204, 204);"><pre>delorean.pyx</pre></td><td style="background-color: rgb(255, 153, 0);"><pre>marty.c</pre></td></tr><tr><td style="vertical-align: top; background-color: rgb(102, 204, 204);"><pre>cdef public struct Vehicle:<br> int speed<br> float power<br><br>cdef api void activate(Vehicle *v):<br> if v.speed &gt;= 88 \<br> and v.power &gt;= 1.21:<br> print "Time travel achieved"</pre></td><td style="background-color: rgb(255, 153, 0);"><pre>#include "delorean_api.h"<br><br>Vehicle car;<br><br>int main(int argc, char *argv[]) {<br> import_delorean();<br> car.speed = atoi(argv[1]);<br> car.power = atof(argv[2]);&nbsp;<br> activate(&amp;car);<br>}</pre></td></tr></tbody></table><br>This
+method does not require the C code using the functions to be linked
+with the extension module in any way, as the Python import machinery is
+used to make the connection dynamically. However, only functions can be
+accessed this way, not variables.You can use both <span style="font-family: monospace;">public</span> and <span style="font-family: monospace;">api</span> on the same function to make it available by both methods, e.g.<br><pre style="margin-left: 40px;">cdef public api void belt_and_braces():<br> ...<br></pre>However, note that you should include <span style="font-weight: bold;">either</span> <span style="font-style: italic;">modulename</span>.h <span style="font-weight: bold;">or</span> <span style="font-style: italic;">modulename</span>_api.h in a given C file, <span style="font-style: italic;">not</span> both, otherwise you may get conflicting dual definitions.<br><br>If the Pyrex module resides within a package, then:<br><ul><li>The name of the header file contains of the full dotted name of the module.</li><li>The name of the importing function contains the full name with dots replaced by double underscores.</li></ul>E.g. a module called <span style="font-weight: bold;">foo.spam</span> would have an API header file called <span style="font-weight: bold;">foo.spam_api.h</span> and an importing function called <span style="font-weight: bold;">import_foo__spam()</span>.<h2>
+<hr width="100%">Extension Types
+<hr width="100%"></h2>
+
+
+ One of the most powerful features of Pyrex is the ability to easily create
+ new built-in Python types, called <b>extension types</b>. This is a major
+ topic in itself, so there is a&nbsp; <a href="extension_types.html">separate
+ page</a> devoted to it.
+<h2>
+<hr width="100%">Sharing Declarations Between Pyrex Modules
+<hr width="100%"></h2>
+
+
+ Pyrex 0.8 introduces a substantial new set of facilities allowing a Pyrex
+ module to easily import and use C declarations and extension types from another
+Pyrex module. You can now create a set of co-operating Pyrex modules just
+as easily as you can create a set of co-operating Python modules. There is
+a <a href="sharing.html">separate page</a> devoted to this topic.
+<h2>
+<hr width="100%"><a name="Limitations"></a>Limitations
+<hr width="100%"></h2>
+
+
+
+<h3> <a name="Unsupported"></a>Unsupported Python features</h3>
+
+
+ Pyrex is not quite a full superset of Python. The following restrictions
+ apply:
+<blockquote> <li> Function definitions (whether using <b>def</b> or <b>cdef</b>)
+ cannot be nested within other function definitions.<br>
+
+ </li>
+
+ &nbsp; <li> Class definitions can only appear at the top level of a module,
+ not inside a function.<br>
+
+ </li>
+
+ &nbsp; <li> The<tt> import *</tt> form of import is not allowed anywhere
+ (other forms of the import statement are fine, though).<br>
+
+ </li>
+
+ &nbsp; <li> Generators cannot be defined in Pyrex.<br>
+
+ <br>
+
+ </li>
+
+ <li> The <tt>globals()</tt> and <tt>locals()</tt> functions cannot be
+used.</li>
+
+ </blockquote>
+
+
+ The above restrictions will most likely remain, since removing them would
+ be difficult and they're not really needed for Pyrex's intended applications.
+
+<p>There are also some temporary limitations, which may eventually be lifted, including:
+ </p>
+
+
+
+<blockquote> <li> Class and function definitions cannot be placed inside
+control structures.<br>
+
+ </li>
+
+ &nbsp; <li> In-place arithmetic operators (+=, etc) are not yet supported.<br>
+
+ </li>
+
+ &nbsp; <li> List comprehensions are not yet supported.<br>
+
+ </li>
+
+ &nbsp; <li> There is no support for Unicode.<br>
+
+ </li>
+
+ &nbsp; <li> Special methods of extension types cannot have functioning
+docstrings.<br>
+
+ <br>
+
+ </li>
+
+ <li> The use of string literals as comments is not recommended at present,
+ because Pyrex doesn't optimize them away, and won't even accept them in
+places where executable statements are not allowed.</li>
+
+ </blockquote>
+
+
+<h3> <a name="SemanticDifferences"></a>Semantic differences between Python
+ and Pyrex</h3>
+
+
+
+<h4> Behaviour of class scopes</h4>
+
+
+ In Python, referring to a method of a class inside the class definition,
+ i.e. while the class is being defined, yields a plain function object, but
+ in Pyrex it yields an unbound method<sup><font size="-2"><a href="#Footnote2">2</a></font></sup>. A consequence of this is that the
+usual idiom for using the classmethod and staticmethod functions, e.g.
+<blockquote>
+ <pre>class Spam:</pre>
+
+
+ <pre>&nbsp; def method(cls):<br>&nbsp;&nbsp;&nbsp; ...</pre>
+
+
+ <pre>&nbsp; method = classmethod(method)</pre>
+
+ </blockquote>
+
+
+ will not work in Pyrex. This can be worked around by defining the function
+ <i>outside</i> the class, and then assigning the result of classmethod or
+ staticmethod inside the class, i.e.
+<blockquote>
+ <pre>def Spam_method(cls):<br>&nbsp; ...</pre>
+
+
+ <pre>class Spam:</pre>
+
+
+ <pre>&nbsp; method = classmethod(Spam_method)</pre>
+
+ </blockquote>
+
+
+
+<h1>
+<hr width="100%"><font size="+0">Footnotes</font>
+<hr width="100%"></h1>
+
+
+ <a name="Footnote1"></a>1. A problem with const could arise if you have
+something like
+<blockquote>
+ <pre>cdef extern from "grail.h":<br>&nbsp; char *nun</pre>
+
+ </blockquote>
+
+
+ where grail.h actually contains
+<blockquote>
+ <pre>extern const char *nun;</pre>
+
+ </blockquote>
+
+
+ and you do
+<blockquote>
+ <pre>cdef void languissement(char *s):<br>&nbsp; #something that doesn't change s</pre>
+
+
+ <pre>...</pre>
+
+
+ <pre>languissement(nun)</pre>
+
+ </blockquote>
+
+
+ which will cause the C compiler to complain. You can work around it by
+casting away the constness:
+<blockquote>
+ <pre>languissement(&lt;char *&gt;nun)</pre>
+
+ </blockquote>
+
+
+
+<hr width="100%"><a name="Footnote2"></a>2. The reason for the different behaviour
+of class scopes is that Pyrex-defined Python functions are PyCFunction objects,
+not PyFunction objects, and are not recognised by the machinery that creates
+a bound or unbound method when a function is extracted from a class. To get
+around this, Pyrex wraps each method in an unbound method object itself before
+storing it in the class's dictionary. <br>
+
+
+ &nbsp; <br>
+
+
+ <br>
+
+
+
+</body></html> \ No newline at end of file
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Builtin.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Builtin.py
new file mode 100644
index 00000000..62dbfbef
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Builtin.py
@@ -0,0 +1,276 @@
+#
+# Pyrex - Builtin Definitions
+#
+
+from Symtab import BuiltinScope
+from TypeSlots import Signature
+from PyrexTypes import py_type_type, c_size_t_type, c_py_ssize_t_type
+
+builtin_constant_table = [
+ # name, type/ctype, C API name
+ ("buffer", "t", "(&PyBuffer_Type)"),
+ ("enumerate", "t", "(&PyEnum_Type)"),
+ ("file", "t", "(&PyFile_Type)"),
+ ("float", "t", "(&PyFloat_Type)"),
+ ("int", "t", "(&PyInt_Type)"),
+ ("long", "t", "(&PyLong_Type)"),
+ ("open", "t", "(&PyFile_Type)"),
+ ("property", "t", "(&PyProperty_Type)"),
+ ("str", "t", "(&PyString_Type)"),
+ ("tuple", "t", "(&PyTuple_Type)"),
+ ("xrange", "t", "(&PyRange_Type)"),
+
+ ("True", "O", "Py_True"),
+ ("False", "O", "Py_False"),
+ ("Ellipsis", "O", "Py_Ellipsis"),
+
+ ("Exception", "t/O", "PyExc_Exception"),
+ ("StopIteration", "t/O", "PyExc_StopIteration"),
+ ("StandardError", "t/O", "PyExc_StandardError"),
+ ("ArithmeticError", "t/O", "PyExc_ArithmeticError"),
+ ("LookupError", "t/O", "PyExc_LookupError"),
+
+ ("AssertionError", "t/O", "PyExc_AssertionError"),
+ ("EOFError", "t/O", "PyExc_EOFError"),
+ ("FloatingPointError", "t/O", "PyExc_FloatingPointError"),
+ ("EnvironmentError", "t/O", "PyExc_EnvironmentError"),
+ ("IOError", "t/O", "PyExc_IOError"),
+ ("OSError", "t/O", "PyExc_OSError"),
+ ("ImportError", "t/O", "PyExc_ImportError"),
+ ("IndexError", "t/O", "PyExc_IndexError"),
+ ("KeyError", "t/O", "PyExc_KeyError"),
+ ("KeyboardInterrupt", "t/O", "PyExc_KeyboardInterrupt"),
+ ("MemoryError", "t/O", "PyExc_MemoryError"),
+ ("NameError", "t/O", "PyExc_NameError"),
+ ("OverflowError", "t/O", "PyExc_OverflowError"),
+ ("RuntimeError", "t/O", "PyExc_RuntimeError"),
+ ("NotImplementedError", "t/O", "PyExc_NotImplementedError"),
+ ("SyntaxError", "t/O", "PyExc_SyntaxError"),
+ ("IndentationError", "t/O", "PyExc_IndentationError"),
+ ("TabError", "t/O", "PyExc_TabError"),
+ ("ReferenceError", "t/O", "PyExc_ReferenceError"),
+ ("SystemError", "t/O", "PyExc_SystemError"),
+ ("SystemExit", "t/O", "PyExc_SystemExit"),
+ ("TypeError", "t/O", "PyExc_TypeError"),
+ ("UnboundLocalError", "t/O", "PyExc_UnboundLocalError"),
+ ("UnicodeError", "t/O", "PyExc_UnicodeError"),
+ ("UnicodeEncodeError", "t/O", "PyExc_UnicodeEncodeError"),
+ ("UnicodeDecodeError", "t/O", "PyExc_UnicodeDecodeError"),
+ ("UnicodeTranslateError", "t/O", "PyExc_UnicodeTranslateError"),
+ ("ValueError", "t/O", "PyExc_ValueError"),
+ ("ZeroDivisionError", "t/O", "PyExc_ZeroDivisionError"),
+ # Not including these by default because they are platform-specific
+ #("WindowsError", "t/O", "PyExc_WindowsError"),
+ #("VMSError", "t/O", "PyExc_VMSError"),
+
+ ("MemoryErrorInst", "t/O", "PyExc_MemoryErrorInst"),
+
+ ("Warning", "t/O", "PyExc_Warning"),
+ ("UserWarning", "t/O", "PyExc_UserWarning"),
+ ("DeprecationWarning", "t/O", "PyExc_DeprecationWarning"),
+ ("PendingDeprecationWarning", "t/O", "PyExc_PendingDeprecationWarning"),
+ ("SyntaxWarning", "t/O", "PyExc_SyntaxWarning"),
+ ("OverflowWarning", "t/O", "PyExc_OverflowWarning"),
+ ("RuntimeWarning", "t/O", "PyExc_RuntimeWarning"),
+ ("FutureWarning", "t/O", "PyExc_FutureWarning"),
+
+]
+
+builtin_function_table = [
+ # name, args, return, C API func, py equiv = "*"
+ ('abs', "O", "O", "PyNumber_Absolute"),
+ ('bool', "O", "i", "PyObject_IsTrue"),
+ #('chr', "", "", ""),
+ #('cmp', "", "", "", ""), # int PyObject_Cmp(PyObject *o1, PyObject *o2, int *result)
+ #('compile', "", "", ""), # PyObject* Py_CompileString( char *str, char *filename, int start)
+ ('delattr', "OO", "r", "PyObject_DelAttr"),
+ ('dir', "O", "O", "PyObject_Dir"),
+ ('divmod', "OO", "O", "PyNumber_Divmod"),
+ #('eval', "", "", ""),
+ #('execfile', "", "", ""),
+ #('filter', "", "", ""),
+ ('getattr', "OO", "O", "PyObject_GetAttr"),
+ ('getattr3', "OOO", "O", "__Pyx_GetAttr3", "getattr"),
+ ('hasattr', "OO", "i", "PyObject_HasAttr"),
+ ('hash', "O", "l", "PyObject_Hash"),
+ #('hex', "", "", ""),
+ #('id', "", "", ""),
+ #('input', "", "", ""),
+ ('cintern', "s", "O", "PyString_InternFromString"), # different name because doesn't handle null bytes
+ ('isinstance', "OO", "i", "PyObject_IsInstance"),
+ ('issubclass', "OO", "i", "PyObject_IsSubclass"),
+ ('iter', "O", "O", "PyObject_GetIter"),
+ ('iter2', "OO", "O", "PyCallIter_New"),
+ ('len', "O", "Z", "PyObject_Length"),
+ #('map', "", "", ""),
+ #('max', "", "", ""),
+ #('min', "", "", ""),
+ #('oct', "", "", ""),
+ # Not worth doing open, when second argument would become mandatory
+ #('open', "ss", "O", "PyFile_FromString"),
+ #('ord', "", "", ""),
+ ('pow', "OOO", "O", "PyNumber_Power"),
+ #('range', "", "", ""),
+ #('raw_input', "", "", ""),
+ #('reduce', "", "", ""),
+ ('reload', "O", "O", "PyImport_ReloadModule"),
+ ('repr', "O", "O", "PyObject_Repr"),
+ #('round', "", "", ""),
+ ('setattr', "OOO", "r", "PyObject_SetAttr"),
+ #('sum', "", "", ""),
+ #('unichr', "", "", ""),
+ #('unicode', "", "", ""),
+ #('vars', "", "", ""),
+ #('zip', "", "", ""),
+ ('typecheck', "Ot", "b", "PyObject_TypeCheck", False),
+ ('issubtype', "tt", "b", "PyType_IsSubtype", False),
+]
+
+dict_methods = [
+ # name, args, return, C API func
+ ("clear", "O", "v", "PyDict_Clear"),
+ ("copy", "O", "O", "PyDict_Copy"),
+ ("items", "O", "O", "PyDict_Items"),
+ ("keys", "O", "O", "PyDict_Keys"),
+ ("values", "O", "O", "PyDict_Values"),
+ ("merge", "OOi", "r", "PyDict_Merge"),
+ ("update", "OO", "r", "PyDict_Update"),
+ ("merge_pairs", "OOi", "r", "PyDict_MergeFromSeq2"),
+]
+
+list_methods = [
+ # name, args, return, C API func
+ ("insert", "OiO", "r", "PyList_Insert"),
+ ("append", "OO", "r", "PyList_Append"),
+ ("iappend", "OO", "i", "PyList_Append"),
+ ("sort", "O", "r", "PyList_Sort"),
+ ("reverse", "O", "r", "PyList_Reverse"),
+ ("as_tuple", "O", "O", "PyList_AsTuple"),
+]
+
+slice_methods = [
+ # name, args, return, C API func
+ ("indices", "O", "O", "PySlice_Indices"),
+]
+
+slice_members = [
+ # name, type
+ ("start", "O"),
+ ("stop", "O"),
+ ("step", "O"),
+]
+
+builtin_c_type_table = [
+ ("size_t", c_size_t_type),
+ ("Py_ssize_t", c_py_ssize_t_type),
+]
+
+builtin_type_table = [
+ # name, objstruct, typeobj, methods, members, flags
+# bool - function
+# buffer - constant
+# classmethod
+ ("dict", "PyDictObject", "PyDict_Type", dict_methods),
+# enumerate - constant
+# file - constant
+# float - constant
+# int - constant
+ ("list", "PyListObject", "PyList_Type", list_methods, [], ['is_sequence']),
+# long - constant
+# object
+# property - constant
+ ("slice", "PySliceObject", "PySlice_Type", slice_methods, slice_members),
+# staticmethod
+# super
+# str - constant
+# tuple - constant
+ ("type", "PyTypeObject", "PyType_Type", []),
+# xrange - constant
+]
+
+getattr3_utility_code = ["""
+static PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); /*proto*/
+""","""
+static PyObject *__Pyx_GetAttr3(PyObject *o, PyObject *n, PyObject *d) {
+ PyObject *r = PyObject_GetAttr(o, n);
+ if (!r) {
+ if (!PyErr_ExceptionMatches(PyExc_AttributeError))
+ goto bad;
+ PyErr_Clear();
+ r = d;
+ Py_INCREF(d);
+ }
+ return r;
+bad:
+ return 0;
+}
+"""]
+
+builtin_utility_code = {
+ 'getattr3': getattr3_utility_code,
+}
+
+builtin_scope = BuiltinScope()
+
+def type_and_ctype(typecode, c_typecode = None):
+ type = Signature.format_map[typecode]
+ if c_typecode:
+ ctype = Signature.format_map[c_typecode]
+ else:
+ ctype = None
+ return type, ctype
+
+def declare_builtin_constant(name, typecode, cname):
+ type, ctype = type_and_ctype(*typecode.split("/"))
+ builtin_scope.declare_builtin_constant(name, type, cname, ctype)
+
+def declare_builtin_func(name, args, ret, cname, py_equiv = "*"):
+ sig = Signature(args, ret)
+ type = sig.function_type()
+ utility = builtin_utility_code.get(name)
+ builtin_scope.declare_builtin_cfunction(name, type, cname, py_equiv, utility)
+
+def declare_builtin_method(self_type, name, args, ret, cname):
+ sig = Signature(args, ret)
+ meth_type = sig.function_type(self_type)
+ self_type.scope.declare_builtin_method(name, meth_type, cname)
+
+def declare_builtin_member(self_type, name, typecode, cname = None):
+ member_type = Signature.format_map[typecode]
+ self_type.scope.declare_builtin_var(name, member_type, cname)
+
+def declare_builtin_c_type(name, type):
+ builtin_scope.declare_builtin_c_type(name, type)
+
+def declare_builtin_type(name, objstruct, typeobj, methods, members = [],
+ flags = []):
+ entry = builtin_scope.declare_builtin_class(name, objstruct, typeobj)
+ type = entry.type
+ for desc in methods:
+ declare_builtin_method(type, *desc)
+ for desc in members:
+ declare_builtin_member(type, *desc)
+ for flag in flags:
+ setattr(type, flag, 1)
+
+def init_builtin_constants():
+ for desc in builtin_constant_table:
+ declare_builtin_constant(*desc)
+
+def init_builtin_funcs():
+ for desc in builtin_function_table:
+ declare_builtin_func(*desc)
+
+def init_builtin_types():
+ for desc in builtin_c_type_table:
+ declare_builtin_c_type(*desc)
+ for desc in builtin_type_table:
+ declare_builtin_type(*desc)
+ py_type_type.define(builtin_scope.find_type("type"))
+
+def init_builtins():
+ init_builtin_constants()
+ init_builtin_funcs()
+ init_builtin_types()
+
+init_builtins()
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/CmdLine.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/CmdLine.py
new file mode 100644
index 00000000..bf546d6e
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/CmdLine.py
@@ -0,0 +1,94 @@
+#
+# Pyrex - Command Line Parsing
+#
+
+import sys
+from Filenames import pyx_suffixes
+from Pyrex.Utils import has_suffix
+
+usage = """\
+Usage: pyrexc [options] sourcefile...
+Options:
+ -v, --version Display version number of pyrex compiler
+ -l, --create-listing Write error messages to a listing file
+ -I, --include-dir <directory> Search for include files in named directory
+ -o, --output-file <filename> Specify name of generated C file
+ -r, --recursive Recursively find and compile dependencies
+ -t, --timestamps Only compile newer source files (implied with -r)
+ -f, --force Compile all source files (overrides implied -t)
+ -q, --quiet Don't print module names in recursive mode
+The following experimental options are supported only on MacOSX:
+ -C, --compile Compile generated .c file to .o file
+ -X, --link Link .o file to produce extension module (implies -C)
+ -+, --cplus Use C++ compiler for compiling and linking
+ Additional .o files to link may be supplied when using -X."""
+
+def bad_usage():
+ print >>sys.stderr, usage
+ sys.exit(1)
+
+def parse_command_line(args):
+ from Pyrex.Compiler.Main import \
+ CompilationOptions, default_options
+
+ def pop_arg():
+ if args:
+ return args.pop(0)
+ else:
+ bad_usage()
+
+ def get_param(option):
+ tail = option[2:]
+ if tail:
+ return tail
+ else:
+ return pop_arg()
+
+ options = CompilationOptions(default_options)
+ sources = []
+ while args:
+ if args[0].startswith("-"):
+ option = pop_arg()
+ if option in ("-v", "--version"):
+ options.show_version = 1
+ elif option in ("-l", "--create-listing"):
+ options.use_listing_file = 1
+ elif option in ("-C", "--compile"):
+ options.c_only = 0
+ elif option in ("-X", "--link"):
+ options.c_only = 0
+ options.obj_only = 0
+ elif option in ("-+", "--cplus"):
+ options.cplus = 1
+ elif option.startswith("-I"):
+ options.include_path.append(get_param(option))
+ elif option == "--include-dir":
+ options.include_path.append(pop_arg())
+ elif option in ("-o", "--output-file"):
+ options.output_file = pop_arg()
+ elif option in ("-r", "--recursive"):
+ options.recursive = 1
+ elif option in ("-t", "--timestamps"):
+ options.timestamps = 1
+ elif option in ("-f", "--force"):
+ options.timestamps = 0
+ else:
+ bad_usage()
+ else:
+ arg = pop_arg()
+ if has_suffix(arg, pyx_suffixes):
+ sources.append(arg)
+ elif arg.endswith(".o"):
+ options.objects.append(arg)
+ else:
+ print >>sys.stderr, \
+ "pyrexc: %s: Unknown filename suffix" % arg
+ if options.objects and len(sources) > 1:
+ print >>sys.stderr, \
+ "pyrexc: Only one source file allowed together with .o files"
+ if options.use_listing_file and len(sources) > 1:
+ print >>sys.stderr, \
+ "pyrexc: Only one source file allowed when using -o"
+ sys.exit(1)
+ return options, sources
+
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Code.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Code.py
new file mode 100644
index 00000000..a47692bb
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Code.py
@@ -0,0 +1,546 @@
+##########################################################################
+#
+# Pyrex - Code output module
+#
+##########################################################################
+
+import os, re
+import Naming
+from Pyrex.Utils import open_new_file
+from PyrexTypes import py_object_type, c_char_array_type, typecast
+
+identifier_pattern = re.compile(r"[A-Za-z_][A-Za-z0-9_]*$")
+max_intern_length = 30
+
+class CCodeWriter:
+ # f file output file
+ # level int indentation level
+ # bol bool beginning of line?
+ # marker string comment to emit before next line
+
+ def __init__(self, f):
+ #self.f = open_new_file(outfile_name)
+ self.f = f
+ self.level = 0
+ self.bol = 1
+ self.marker = None
+
+ def putln(self, code = ""):
+ if self.marker and self.bol:
+ self.emit_marker()
+ if code:
+ self.put(code)
+ self.f.write("\n");
+ self.bol = 1
+
+ def emit_marker(self):
+ self.f.write("\n");
+ self.indent()
+ self.f.write("/* %s */\n" % self.marker)
+ self.marker = None
+
+ def put(self, code):
+ dl = code.count("{") - code.count("}")
+ if dl < 0:
+ self.level += dl
+ if self.bol:
+ self.indent()
+ self.f.write(code)
+ self.bol = 0
+ if dl > 0:
+ self.level += dl
+
+ def increase_indent(self):
+ self.level = self.level + 1
+
+ def decrease_indent(self):
+ self.level = self.level - 1
+
+ def begin_block(self):
+ self.putln("{")
+ self.increase_indent()
+
+ def end_block(self):
+ self.decrease_indent()
+ self.putln("}")
+
+ def indent(self):
+ self.f.write(" " * self.level)
+
+ def mark_pos(self, pos):
+ file, line, col = pos
+ self.marker = '"%s":%s' % (file, line)
+
+ def put_var_declarations(self, entries, static = 0, dll_linkage = None,
+ definition = True):
+ for entry in entries:
+ if not entry.in_cinclude:
+ self.put_var_declaration(entry, static, dll_linkage, definition)
+
+ def put_var_declaration(self, entry, static = 0, dll_linkage = None,
+ definition = True):
+ #print "Code.put_var_declaration:", entry.name, repr(entry.type) ###
+ visibility = entry.visibility
+ if visibility == 'private' and not definition:
+ #print "...private and not definition, skipping" ###
+ return
+ if not entry.used and visibility == "private":
+ #print "not used and private, skipping" ###
+ return
+ storage_class = ""
+ if visibility == 'extern':
+ storage_class = Naming.extern_c_macro
+ elif visibility == 'public':
+ if not definition:
+ storage_class = Naming.extern_c_macro
+ elif visibility == 'private':
+ if static:
+ storage_class = "static"
+ if storage_class:
+ self.put("%s " % storage_class)
+ if visibility <> 'public':
+ dll_linkage = None
+ self.put(entry.type.declaration_code(entry.cname,
+ dll_linkage = dll_linkage))
+ if entry.init is not None:
+ self.put(" = %s" % entry.type.literal_code(entry.init))
+ self.putln(";")
+
+ def entry_as_pyobject(self, entry):
+ type = entry.type
+ if (not entry.is_self_arg and not entry.type.is_complete()) \
+ or (entry.type.is_extension_type and entry.type.base_type):
+ return "(PyObject *)" + entry.cname
+ else:
+ return entry.cname
+
+ def as_pyobject(self, cname, type):
+ if type:
+ return typecast(py_object_type, type, cname)
+ else:
+ return cname
+
+ def put_incref(self, cname, type = None):
+ self.putln("Py_INCREF(%s);" % self.as_pyobject(cname, type))
+
+ def put_decref(self, cname, type = None):
+ self.putln("Py_DECREF(%s);" % self.as_pyobject(cname, type))
+
+ def put_var_incref(self, entry):
+ if entry.type.is_pyobject:
+ self.putln("Py_INCREF(%s);" % self.entry_as_pyobject(entry))
+
+ def put_decref_clear(self, cname, type = None):
+ self.putln("Py_DECREF(%s); %s = 0;" % (
+ self.as_pyobject(cname, type), cname)) # What was wrong with this?
+ #typecast(py_object_type, type, cname), cname))
+
+ def put_xdecref(self, cname, type):
+ self.putln("Py_XDECREF(%s);" % self.as_pyobject(cname, type))
+
+ def put_xdecref_clear(self, cname, type):
+ self.putln("Py_XDECREF(%s); %s = 0;" % (
+ self.as_pyobject(cname, type), cname))
+
+ def put_var_decref(self, entry):
+ if entry.type.is_pyobject:
+ self.putln("Py_DECREF(%s);" % self.entry_as_pyobject(entry))
+
+ def put_var_decref_clear(self, entry):
+ if entry.type.is_pyobject:
+ self.putln("Py_DECREF(%s); %s = 0;" % (
+ self.entry_as_pyobject(entry), entry.cname))
+
+ def put_var_xdecref(self, entry):
+ if entry.type.is_pyobject:
+ self.putln("Py_XDECREF(%s);" % self.entry_as_pyobject(entry))
+
+ def put_var_xdecref_clear(self, entry):
+ if entry.type.is_pyobject:
+ self.putln("Py_XDECREF(%s); %s = 0;" % (
+ self.entry_as_pyobject(entry), entry.cname))
+
+ def put_var_decrefs(self, entries, used_only = 0):
+ for entry in entries:
+ if not used_only or entry.used:
+ if entry.xdecref_cleanup:
+ self.put_var_xdecref(entry)
+ else:
+ self.put_var_decref(entry)
+
+ def put_var_xdecrefs(self, entries):
+ for entry in entries:
+ self.put_var_xdecref(entry)
+
+ def put_var_xdecrefs_clear(self, entries):
+ for entry in entries:
+ self.put_var_xdecref_clear(entry)
+
+ def put_init_to_py_none(self, cname, type):
+ py_none = typecast(type, py_object_type, "Py_None")
+ self.putln("%s = %s; Py_INCREF(Py_None);" % (cname, py_none))
+
+ def put_init_var_to_py_none(self, entry, template = "%s"):
+ code = template % entry.cname
+ self.put_init_to_py_none(code, entry.type)
+
+ def put_pymethoddef(self, entry, term):
+ if entry.doc:
+ doc_code = entry.doc_cname
+ else:
+ doc_code = 0
+ self.putln(
+ '{"%s", (PyCFunction)%s, METH_VARARGS|METH_KEYWORDS, %s}%s' % (
+ entry.name,
+ entry.func_cname,
+ doc_code,
+ term))
+
+ def put_h_guard(self, guard):
+ self.putln("#ifndef %s" % guard)
+ self.putln("#define %s" % guard)
+
+#--------------------------------------------------------------------------
+
+class MainCCodeWriter(CCodeWriter):
+ # Code writer for executable C code.
+ #
+ # global_state GlobalCodeState module-wide state
+ # return_label string function return point label
+ # error_label string error catch point label
+ # continue_label string loop continue point label
+ # break_label string loop break point label
+ # label_counter integer counter for naming labels
+ # in_try_finally boolean inside try of try...finally
+ # exc_vars (string * 3) exception vars for reraise, or None
+
+ in_try_finally = 0
+
+ def __init__(self, f, base = None):
+ CCodeWriter.__init__(self, f)
+ if base:
+ self.global_state = base.global_state
+ else:
+ self.global_state = GlobalCodeState()
+ self.label_counter = 1
+ self.error_label = None
+ self.exc_vars = None
+
+ def init_labels(self):
+ self.label_counter = 0
+ self.labels_used = {}
+ self.return_label = self.new_label()
+ self.new_error_label()
+ self.continue_label = None
+ self.break_label = None
+
+ def new_label(self):
+ n = self.label_counter
+ self.label_counter = n + 1
+ return "%s%d" % (Naming.label_prefix, n)
+
+ def new_error_label(self):
+ old_err_lbl = self.error_label
+ self.error_label = self.new_label()
+ return old_err_lbl
+
+ def get_loop_labels(self):
+ return (
+ self.continue_label,
+ self.break_label)
+
+ def set_loop_labels(self, labels):
+ (self.continue_label,
+ self.break_label) = labels
+
+ def new_loop_labels(self):
+ old_labels = self.get_loop_labels()
+ self.set_loop_labels(
+ (self.new_label(),
+ self.new_label()))
+ return old_labels
+
+ def get_all_labels(self):
+ return (
+ self.continue_label,
+ self.break_label,
+ self.return_label,
+ self.error_label)
+
+ def set_all_labels(self, labels):
+ (self.continue_label,
+ self.break_label,
+ self.return_label,
+ self.error_label) = labels
+
+ def all_new_labels(self):
+ old_labels = self.get_all_labels()
+ new_labels = []
+ for old_label in old_labels:
+ if old_label:
+ new_labels.append(self.new_label())
+ else:
+ new_labels.append(old_label)
+ self.set_all_labels(new_labels)
+ return old_labels
+
+ def use_label(self, lbl):
+ self.labels_used[lbl] = 1
+
+ def put_label(self, lbl):
+ if lbl in self.labels_used:
+ self.putln("%s:;" % lbl)
+
+ def put_goto(self, lbl):
+ self.use_label(lbl)
+ self.putln("goto %s;" % lbl)
+
+ def error_goto(self, pos):
+ lbl = self.error_label
+ self.use_label(lbl)
+ return "{%s; goto %s;}" % (
+ self.error_setup(pos),
+ lbl)
+
+ def error_setup(self, pos):
+ return "%s = %s[%s]; %s = %s" % (
+ Naming.filename_cname,
+ Naming.filetable_cname,
+ self.lookup_filename(pos[0]),
+ Naming.lineno_cname,
+ pos[1])
+
+ def lookup_filename(self, filename):
+ return self.global_state.lookup_filename(filename)
+
+ def use_utility_code(self, uc):
+ self.global_state.use_utility_code(uc)
+
+ def get_string_const(self, text):
+ # Get C name for a string constant, adding a new one
+ # if necessary.
+ return self.global_state.get_string_const(text).cname
+
+ def new_const(self, type):
+ # Get C name for a new precalculated value.
+ return self.global_state.new_const(type).cname
+
+ def get_py_string_const(self, text):
+ # Get C name for a Python string constant, adding a new one
+ # if necessary. If the string is name-like, it will be interned.
+ return self.global_state.get_py_string_const(text).cname
+
+ def intern(self, name):
+ return self.get_py_string_const(name)
+
+#--------------------------------------------------------------------------
+
+class StringConst:
+ # Info held by GlobalCodeState about a string constant.
+ #
+ # cname string
+ # text string
+ # py_const Const Corresponding Python string
+
+ py_const = None
+
+ def __init__(self, cname, text):
+ self.cname = cname
+ self.text = text
+
+#--------------------------------------------------------------------------
+
+class Const:
+ # Info held by GlobalCodeState about a precalculated value.
+ #
+ # cname string
+ # type PyrexType
+ # intern boolean for Python strings
+
+ intern = 0
+
+ def __init__(self, cname, type):
+ self.cname = cname
+ self.type = type
+
+#--------------------------------------------------------------------------
+
+class GlobalCodeState:
+ # State pertaining to code generation for a whole module.
+ #
+ # filename_table {string : int} for finding filename table indexes
+ # filename_list [string] filenames in filename table order
+ # utility_code {int : int} id to utility_list index
+ # utility_list list utility code used
+ # const_counter int for generating const names
+ # string_index {string : String} string constant index
+ # string_consts [StringConst] all string constants
+ # other_consts [Const] other precalculated values
+
+ def __init__(self):
+ self.filename_table = {}
+ self.filename_list = []
+ self.utility_code = {}
+ self.utility_list = []
+ self.const_counter = 1
+ self.string_index = {}
+ self.string_consts = []
+ self.other_consts = []
+
+ def lookup_filename(self, filename):
+ try:
+ index = self.filename_table[filename]
+ except KeyError:
+ index = len(self.filename_list)
+ self.filename_list.append(filename)
+ self.filename_table[filename] = index
+ return index
+
+ def generate_filename_table(self, code):
+ code.putln("")
+ code.putln("static char *%s[] = {" % Naming.filenames_cname)
+ if self.filename_list:
+ for filename in self.filename_list:
+ filename = os.path.basename(filename)
+ escaped_filename = filename.replace("\\", "\\\\").replace('"', r'\"')
+ code.putln('"%s",' %
+ escaped_filename)
+ else:
+ # Some C compilers don't like an empty array
+ code.putln("0")
+ code.putln("};")
+
+ def use_utility_code(self, uc):
+ i = id(uc)
+ if i not in self.utility_code:
+ self.utility_code[i] = len(self.utility_list)
+ self.utility_list.append(uc)
+
+ def generate_utility_functions(self, code):
+ code.putln("")
+ code.putln("/* Runtime support code */")
+ code.putln("")
+ code.putln("static void %s(void) {" % Naming.fileinit_cname)
+ code.putln("%s = %s;" %
+ (Naming.filetable_cname, Naming.filenames_cname))
+ code.putln("}")
+ for utility_code in self.utility_list:
+ code.h.put(utility_code[0])
+ code.put(utility_code[1])
+
+ def new_const_name(self):
+ # Create a new globally-unique name for a constant.
+ name = "%s%s" % (Naming.const_prefix, self.const_counter)
+ self.const_counter += 1
+ return name
+
+ def new_string_const(self, text):
+ # Add a new C string constant.
+ c = StringConst(self.new_const_name(), text)
+ self.string_consts.append(c)
+ self.string_index[text] = c
+ return c
+
+ def new_const(self, type, cname = None):
+ if not cname:
+ cname = self.new_const_name()
+ c = Const(cname, type)
+ self.other_consts.append(c)
+ return c
+
+ def new_py_const(self, cname = None, intern = 0):
+ # Add a new Python constant.
+ c = self.new_const(py_object_type, cname)
+ if intern:
+ c.intern = 1
+ return c
+
+ def get_string_const(self, text):
+ # Get a C string constant, adding a new one if necessary.
+ c = self.string_index.get(text)
+ if not c:
+ c = self.new_string_const(text)
+ return c
+
+ def get_py_string_const(self, text):
+ # Get a Python string constant, adding a new one if necessary.
+ # If the string is name-like, it will be interned.
+ s = self.get_string_const(text)
+ if not s.py_const:
+ intern = len(text) <= max_intern_length and identifier_pattern.match(text)
+ if intern:
+ cname = Naming.interned_prefix + text
+ else:
+ cname = s.cname + "p"
+ s.py_const = self.new_py_const(cname, intern)
+ return s.py_const
+
+ def generate_const_declarations(self, code):
+ self.generate_string_const_declarations(code)
+ self.generate_other_const_declarations(code)
+ self.generate_stringtab(code)
+
+ def generate_string_const_declarations(self, code):
+ code.putln("")
+ for c in self.string_consts:
+ code.putln('static char %s[] = "%s";' % (c.cname, c.text))
+
+ def generate_other_const_declarations(self, code):
+ interned = []
+ uninterned = []
+ for c in self.other_consts:
+ if c.intern:
+ interned.append(c)
+ else:
+ uninterned.append(c)
+ interned.sort(lambda c1, c2: cmp(c1.cname, c2.cname))
+ def put_consts(consts):
+ code.putln("")
+ for c in consts:
+ decl = c.type.declaration_code(c.cname)
+ code.putln("static %s;" % decl)
+ put_consts(interned)
+ put_consts(uninterned)
+
+ def generate_stringtab(self, code):
+ interned = []
+ uninterned = []
+ for s in self.string_consts:
+ p = s.py_const
+ if p:
+ if p.intern:
+ interned.append(s)
+ else:
+ uninterned.append(s)
+ interned.sort(lambda c1, c2: cmp(c1.py_const.cname, c2.py_const.cname))
+ def put_stringtab(consts, intern):
+ for c in consts:
+ cname = c.cname
+ code.putln("{&%s, %d, %s, sizeof(%s)}," % (
+ c.py_const.cname, intern, cname, cname))
+ code.putln("")
+ code.putln("static __Pyx_StringTabEntry %s[] = {" % Naming.stringtab_cname)
+ put_stringtab(interned, 1)
+ put_stringtab(uninterned, 0)
+ code.putln("{0, 0, 0, 0}")
+ code.putln("};")
+
+#--------------------------------------------------------------------------
+
+class PyrexCodeWriter:
+ # f file output file
+ # level int indentation level
+
+ def __init__(self, outfile_name):
+ self.f = open_new_file(outfile_name)
+ self.level = 0
+
+ def putln(self, code):
+ self.f.write("%s%s\n" % (" " * self.level, code))
+
+ def indent(self):
+ self.level += 1
+
+ def dedent(self):
+ self.level -= 1
+
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/DebugFlags.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/DebugFlags.py
new file mode 100644
index 00000000..e36e0bd2
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/DebugFlags.py
@@ -0,0 +1,4 @@
+debug_disposal_code = 0
+debug_temp_alloc = 0
+debug_coercion = 0
+
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Errors.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Errors.py
new file mode 100644
index 00000000..1eef3a33
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Errors.py
@@ -0,0 +1,77 @@
+#
+# Pyrex - Errors
+#
+
+import sys
+from Pyrex.Utils import open_new_file
+
+warnings_issued = {}
+
+class PyrexError(EnvironmentError):
+ pass
+
+
+class CompileError(PyrexError):
+
+ def __init__(self, position = None, message = ""):
+ self.position = position
+ if position:
+ pos_str = "%s:%d:%d: " % position
+ else:
+ pos_str = ""
+ PyrexError.__init__(self, pos_str + message)
+
+
+class InternalError(Exception):
+ # If this is ever raised, there is a bug in the compiler.
+
+ def __init__(self, message):
+ Exception.__init__(self, "Internal compiler error: %s"
+ % message)
+
+
+listing_file = None
+num_errors = 0
+echo_file = None
+
+def open_listing_file(path, echo_to_stderr = 1):
+ # Begin a new error listing. If path is None, no file
+ # is opened, the error counter is just reset.
+ global listing_file, num_errors, echo_file
+ if path is not None:
+ listing_file = open_new_file(path)
+ else:
+ listing_file = None
+ if echo_to_stderr:
+ echo_file = sys.stderr
+ else:
+ echo_file = None
+ num_errors = 0
+
+def close_listing_file():
+ global listing_file
+ if listing_file:
+ listing_file.close()
+ listing_file = None
+
+def report(position, message):
+ err = CompileError(position, message)
+ line = "%s\n" % err
+ if listing_file:
+ listing_file.write(line)
+ if echo_file:
+ echo_file.write(line)
+ return err
+
+def warning(position, message):
+ return report(position, "Warning: %s" % message)
+
+def one_time_warning(position, key, message):
+ if key not in warnings_issued:
+ warnings_issued[key] = 1
+ warning(position, message)
+
+def error(position, message):
+ global num_errors
+ num_errors = num_errors + 1
+ return report(position, message)
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/ExprNodes.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/ExprNodes.py
new file mode 100644
index 00000000..c2848286
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/ExprNodes.py
@@ -0,0 +1,3954 @@
+#
+# Pyrex - Parse tree nodes for expressions
+#
+
+import operator
+from string import join
+
+from Errors import error, InternalError
+import Naming
+from Nodes import Node
+import PyrexTypes
+from PyrexTypes import py_object_type, c_long_type, typecast, error_type, \
+ CPtrType, CFuncType, COverloadedFuncType
+import Symtab
+import Options
+
+from Pyrex.Debugging import print_call_chain
+from DebugFlags import debug_disposal_code, debug_temp_alloc, \
+ debug_coercion
+
+class ExprNode(Node):
+ # subexprs [string] Class var holding names of subexpr node attrs
+ # type PyrexType Type of the result
+ # result_code string Code fragment
+ # result_ctype string C type of result_code if different from type
+ # inplace_result string Temp var holding in-place operation result
+ # is_temp boolean Result is in a temporary variable
+ # is_sequence_constructor
+ # boolean Is a list or tuple constructor expression
+ # saved_subexpr_nodes
+ # [ExprNode or [ExprNode or None] or None]
+ # Cached result of subexpr_nodes()
+
+ result_ctype = None
+
+ # The Analyse Expressions phase for expressions is split
+ # into two sub-phases:
+ #
+ # Analyse Types
+ # Determines the result type of the expression based
+ # on the types of its sub-expressions, and inserts
+ # coercion nodes into the expression tree where needed.
+ # Marks nodes which will need to have temporary variables
+ # allocated.
+ #
+ # Allocate Temps
+ # Allocates temporary variables where needed, and fills
+ # in the result_code field of each node.
+ #
+ # ExprNode provides some convenience routines which
+ # perform both of the above phases. These should only
+ # be called from statement nodes, and only when no
+ # coercion nodes need to be added around the expression
+ # being analysed. If coercion is needed, the above two phases
+ # should be invoked separately.
+ #
+ # Framework code in ExprNode provides much of the common
+ # processing for the various phases. It makes use of the
+ # 'subexprs' class attribute of ExprNodes, which should
+ # contain a list of the names of attributes which can
+ # hold sub-nodes or sequences of sub-nodes.
+ #
+ # The framework makes use of a number of abstract methods.
+ # Their responsibilities are as follows.
+ #
+ # Declaration Analysis phase
+ #
+ # analyse_target_declaration
+ # Called during the Analyse Declarations phase to analyse
+ # the LHS of an assignment or argument of a del statement.
+ # Nodes which cannot be the LHS of an assignment need not
+ # implement it.
+ #
+ # Expression Analysis phase
+ #
+ # analyse_types
+ # - Call analyse_types on all sub-expressions.
+ # - Check operand types, and wrap coercion nodes around
+ # sub-expressions where needed.
+ # - Set the type of this node.
+ # - If a temporary variable will be required for the
+ # result, set the is_temp flag of this node.
+ #
+ # analyse_target_types
+ # Called during the Analyse Types phase to analyse
+ # the LHS of an assignment or argument of a del
+ # statement. Similar responsibilities to analyse_types.
+ #
+ # allocate_temps
+ # - Call allocate_temps for all sub-nodes.
+ # - Call allocate_temp for this node.
+ # - If a temporary was allocated, call release_temp on
+ # all sub-expressions.
+ #
+ # allocate_target_temps
+ # - Call allocate_temps on sub-nodes and allocate any other
+ # temps used during assignment.
+ # - Fill in result_code with a C lvalue if needed.
+ # - If a rhs node is supplied, call release_temp on it.
+ # - Call release_temp on sub-nodes and release any other
+ # temps used during assignment.
+ #
+ # #calculate_result_code
+ # # - Called during the Allocate Temps phase. Should return a
+ # # C code fragment evaluating to the result. This is only
+ # # called when the result is not a temporary.
+ #
+ # target_code
+ # Called by the default implementation of allocate_target_temps.
+ # Should return a C lvalue for assigning to the node. The default
+ # implementation calls calculate_result_code.
+ #
+ # check_const
+ # - Check that this node and its subnodes form a
+ # legal constant expression. If so, do nothing,
+ # otherwise call not_const.
+ #
+ # The default implementation of check_const
+ # assumes that the expression is not constant.
+ #
+ # check_const_addr
+ # - Same as check_const, except check that the
+ # expression is a C lvalue whose address is
+ # constant. Otherwise, call addr_not_const.
+ #
+ # The default implementation of calc_const_addr
+ # assumes that the expression is not a constant
+ # lvalue.
+ #
+ # Code Generation phase
+ #
+ # generate_evaluation_code
+ # 1. Call generate_evaluation_code for sub-expressions.
+ # 2. Generate any C statements necessary to calculate
+ # the result of this node from the results of its
+ # sub-expressions. If result is not in a temporary, record
+ # any information that will be needed by this node's
+ # implementation of calculate_result_code().
+ # 4. If result is in a temporary, call generate_disposal_code
+ # on all sub-expressions.
+ #
+ # A default implementation of generate_evaluation_code
+ # is provided which uses the folling abstract methods:
+ # generate_result_code (for no. 2)
+ #
+ # generate_assignment_code
+ # Called on the LHS of an assignment.
+ # - Call generate_evaluation_code for sub-expressions.
+ # - Generate code to perform the assignment.
+ # - If the assignment absorbed a reference, call
+ # generate_post_assignment_code on the RHS,
+ # otherwise call generate_disposal_code on it.
+ #
+ # generate_deletion_code
+ # Called on an argument of a del statement.
+ # - Call generate_evaluation_code for sub-expressions.
+ # - Generate code to perform the deletion.
+ # - Call generate_disposal_code on all sub-expressions.
+ #
+ # calculate_result_code
+ # Return a C code fragment representing the result of this node.
+ # This is only called if the result is not in a temporary.
+ #
+
+ is_sequence_constructor = 0
+ is_attribute = 0
+
+ saved_subexpr_nodes = None
+ is_temp = 0
+
+ def not_implemented(self, method_name):
+ print_call_chain(method_name, "not implemented") ###
+ raise InternalError(
+ "%s.%s not implemented" %
+ (self.__class__.__name__, method_name))
+
+ def is_lvalue(self):
+ return 0
+
+ def is_inplace_lvalue(self):
+ return 0
+
+ def is_ephemeral(self):
+ # An ephemeral node is one whose result is in
+ # a Python temporary and we suspect there are no
+ # other references to it. Certain operations are
+ # disallowed on such values, since they are
+ # likely to result in a dangling pointer.
+ return self.type.is_pyobject and self.is_temp
+
+ def subexpr_nodes(self):
+ # Extract a list of subexpression nodes based
+ # on the contents of the subexprs class attribute.
+ if self.saved_subexpr_nodes is None:
+ nodes = []
+ for name in self.subexprs:
+ item = getattr(self, name)
+ if item:
+ if isinstance(item, ExprNode):
+ nodes.append(item)
+ else:
+ nodes.extend(item)
+ self.saved_subexpr_nodes = nodes
+ return self.saved_subexpr_nodes
+
+ def result(self):
+ # Return a C code fragment for the result of this node.
+ if self.is_temp:
+ result_code = self.result_code
+ else:
+ result_code = self.calculate_result_code()
+ return result_code
+
+ def result_as(self, type = None):
+ # Return the result code cast to the specified C type.
+ return typecast(type, self.ctype(), self.result())
+
+ def py_result(self):
+ # Return the result code cast to PyObject *.
+ return self.result_as(py_object_type)
+
+ def ctype(self):
+ # Return the native C type of the result.
+ return self.result_ctype or self.type
+
+ def compile_time_value(self, denv):
+ # Return value of compile-time expression, or report error.
+ error(self.pos, "Invalid compile-time expression")
+
+ def compile_time_value_error(self, e):
+ error(self.pos, "Error in compile-time expression: %s: %s" % (
+ e.__class__.__name__, e))
+
+ # ------------- Declaration Analysis ----------------
+
+ def analyse_target_declaration(self, env):
+ error(self.pos, "Cannot assign to or delete this")
+
+ # ------------- Expression Analysis ----------------
+
+ def analyse_const_expression(self, env):
+ # Called during the analyse_declarations phase of a
+ # constant expression. Analyses the expression's type,
+ # checks whether it is a legal const expression,
+ # and determines its value.
+ self.analyse_types(env)
+ self.allocate_temps(env)
+ self.check_const()
+
+ def analyse_expressions(self, env):
+ # Convenience routine performing both the Type
+ # Analysis and Temp Allocation phases for a whole
+ # expression.
+ self.analyse_types(env)
+ self.allocate_temps(env)
+
+ def analyse_target_expression(self, env, rhs):
+ # Convenience routine performing both the Type
+ # Analysis and Temp Allocation phases for the LHS of
+ # an assignment.
+ self.analyse_target_types(env)
+ self.allocate_target_temps(env, rhs)
+
+ def analyse_boolean_expression(self, env):
+ # Analyse expression and coerce to a boolean.
+ self.analyse_types(env)
+ bool = self.coerce_to_boolean(env)
+ bool.allocate_temps(env)
+ return bool
+
+ def analyse_temp_boolean_expression(self, env):
+ # Analyse boolean expression and coerce result into
+ # a temporary. This is used when a branch is to be
+ # performed on the result and we won't have an
+ # opportunity to ensure disposal code is executed
+ # afterwards. By forcing the result into a temporary,
+ # we ensure that all disposal has been done by the
+ # time we get the result.
+ self.analyse_types(env)
+ bool = self.coerce_to_boolean(env)
+ temp_bool = bool.coerce_to_temp(env)
+ temp_bool.allocate_temps(env)
+ return temp_bool
+
+ # --------------- Type Analysis ------------------
+
+ def analyse_as_function(self, env):
+ # Analyse types for an expression that is to be called.
+ self.analyse_types(env)
+
+ def analyse_as_module(self, env):
+ # If this node can be interpreted as a reference to a
+ # cimported module, return its scope, else None.
+ return None
+
+ def analyse_as_extension_type(self, env):
+ # If this node can be interpreted as a reference to an
+ # extension type, return its type, else None.
+ return None
+
+ def analyse_as_cimported_attribute(self, env, *args, **kwds):
+ # If this node can be interpreted as a cimported name,
+ # finish type analysis and return true, else return false.
+ return 0
+
+ def analyse_types(self, env):
+ self.not_implemented("analyse_types")
+
+ def analyse_target_types(self, env):
+ self.analyse_types(env)
+
+ def analyse_inplace_types(self, env):
+ if self.is_inplace_lvalue():
+ self.analyse_types(env)
+ else:
+ error(self.pos, "Invalid target for in-place operation")
+ self.type = error_type
+
+ def gil_assignment_check(self, env):
+ if env.nogil and self.type.is_pyobject:
+ error(self.pos, "Assignment of Python object not allowed without gil")
+
+ def check_const(self):
+ self.not_const()
+
+ def not_const(self):
+ error(self.pos, "Not allowed in a constant expression")
+
+ def check_const_addr(self):
+ self.addr_not_const()
+
+ def addr_not_const(self):
+ error(self.pos, "Address is not constant")
+
+ def gil_check(self, env):
+ if env.nogil and self.type.is_pyobject:
+ self.gil_error()
+
+ # ----------------- Result Allocation -----------------
+
+ def result_in_temp(self):
+ # Return true if result is in a temporary owned by
+ # this node or one of its subexpressions. Overridden
+ # by certain nodes which can share the result of
+ # a subnode.
+ return self.is_temp
+
+ def allocate_target_temps(self, env, rhs, inplace = 0):
+ # Perform temp allocation for the LHS of an assignment.
+ if debug_temp_alloc:
+ print self, "Allocating target temps"
+ self.allocate_subexpr_temps(env)
+ #self.result_code = self.target_code()
+ if rhs:
+ rhs.release_temp(env)
+ self.release_subexpr_temps(env)
+
+ def allocate_inplace_target_temps(self, env, rhs):
+ if debug_temp_alloc:
+ print self, "Allocating inplace target temps"
+ self.allocate_subexpr_temps(env)
+ #self.result_code = self.target_code()
+ py_inplace = self.type.is_pyobject
+ if py_inplace:
+ self.allocate_temp(env)
+ self.inplace_result = env.allocate_temp(py_object_type)
+ self.release_temp(env)
+ rhs.release_temp(env)
+ if py_inplace:
+ env.release_temp(self.inplace_result)
+ self.release_subexpr_temps(env)
+
+ def allocate_temps(self, env, result = None):
+ # Allocate temporary variables for this node and
+ # all its sub-expressions. If a result is specified,
+ # this must be a temp node and the specified variable
+ # is used as the result instead of allocating a new
+ # one.
+ if debug_temp_alloc:
+ print self, "Allocating temps"
+ self.allocate_subexpr_temps(env)
+ self.allocate_temp(env, result)
+ if self.is_temp:
+ self.release_subexpr_temps(env)
+
+ def allocate_subexpr_temps(self, env):
+ # Allocate temporary variables for all sub-expressions
+ # of this node.
+ if debug_temp_alloc:
+ print self, "Allocating temps for:", self.subexprs
+ for node in self.subexpr_nodes():
+ if node:
+ if debug_temp_alloc:
+ print self, "Allocating temps for", node
+ node.allocate_temps(env)
+
+ def allocate_temp(self, env, result = None):
+ # If this node requires a temporary variable for its
+ # result, allocate one. If a result is specified,
+ # this must be a temp node and the specified variable
+ # is used as the result instead of allocating a new
+ # one.
+ if debug_temp_alloc:
+ print self, "Allocating temp"
+ if result:
+ if not self.is_temp:
+ raise InternalError("Result forced on non-temp node")
+ self.result_code = result
+ elif self.is_temp:
+ type = self.type
+ if not type.is_void:
+ if type.is_pyobject:
+ type = PyrexTypes.py_object_type
+ self.result_code = env.allocate_temp(type)
+ else:
+ self.result_code = None
+ if debug_temp_alloc:
+ print self, "Allocated result", self.result_code
+ #else:
+ # self.result_code = self.calculate_result_code()
+
+ def target_code(self):
+ # Return code fragment for use as LHS of a C assignment.
+ return self.calculate_result_code()
+
+ def calculate_result_code(self):
+ self.not_implemented("calculate_result_code")
+
+ def release_temp(self, env):
+ # If this node owns a temporary result, release it,
+ # otherwise release results of its sub-expressions.
+ if self.is_temp:
+ if debug_temp_alloc:
+ print self, "Releasing result", self.result_code
+ env.release_temp(self.result_code)
+ else:
+ self.release_subexpr_temps(env)
+
+ def release_subexpr_temps(self, env):
+ # Release the results of all sub-expressions of
+ # this node.
+ for node in self.subexpr_nodes():
+ if node:
+ node.release_temp(env)
+
+ # ---------------- Code Generation -----------------
+
+ def mark_vars_used(self):
+ for node in self.subexpr_nodes():
+ node.mark_vars_used()
+
+ def make_owned_reference(self, code):
+ # If result is a pyobject, make sure we own
+ # a reference to it.
+ if self.type.is_pyobject and not self.result_in_temp():
+ code.put_incref(self.py_result())
+
+ def generate_evaluation_code(self, code):
+ # Generate code to evaluate this node and
+ # its sub-expressions, and dispose of any
+ # temporary results of its sub-expressions.
+ self.generate_subexpr_evaluation_code(code)
+ self.generate_result_code(code)
+ if self.is_temp:
+ self.generate_subexpr_disposal_code(code)
+
+ def generate_subexpr_evaluation_code(self, code):
+ for node in self.subexpr_nodes():
+ node.generate_evaluation_code(code)
+
+ def generate_result_code(self, code):
+ self.not_implemented("generate_result_code")
+
+ inplace_functions = {
+ "+=": "PyNumber_InPlaceAdd",
+ "-=": "PyNumber_InPlaceSubtract",
+ "*=": "PyNumber_InPlaceMultiply",
+ "/=": "PyNumber_InPlaceDivide",
+ "%=": "PyNumber_InPlaceRemainder",
+ "**=": "PyNumber_InPlacePower",
+ "<<=": "PyNumber_InPlaceLshift",
+ ">>=": "PyNumber_InPlaceRshift",
+ "&=": "PyNumber_InPlaceAnd",
+ "^=": "PyNumber_InPlaceXor",
+ "|=": "PyNumber_InPlaceOr",
+ }
+
+ def generate_inplace_operation_code(self, operator, rhs, code):
+ args = (self.py_result(), rhs.py_result())
+ if operator == "**=":
+ arg_code = "%s, %s, Py_None" % args
+ else:
+ arg_code = "%s, %s" % args
+ code.putln("%s = %s(%s); if (!%s) %s" % (
+ self.inplace_result,
+ self.inplace_functions[operator],
+ arg_code,
+ self.inplace_result,
+ code.error_goto(self.pos)))
+ if self.is_temp:
+ code.put_decref_clear(self.py_result())
+ rhs.generate_disposal_code(code)
+ if self.type.is_extension_type:
+ code.putln(
+ "if (!__Pyx_TypeTest(%s, %s)) %s" % (
+ self.inplace_result,
+ self.type.typeptr_cname,
+ code.error_goto(self.pos)))
+
+ def generate_disposal_code(self, code):
+ # If necessary, generate code to dispose of
+ # temporary Python reference.
+ if self.is_temp:
+ if self.type.is_pyobject:
+ code.put_decref_clear(self.py_result(), self.ctype())
+ else:
+ self.generate_subexpr_disposal_code(code)
+
+ def generate_subexpr_disposal_code(self, code):
+ # Generate code to dispose of temporary results
+ # of all sub-expressions.
+ for node in self.subexpr_nodes():
+ node.generate_disposal_code(code)
+
+ def generate_post_assignment_code(self, code):
+ # Same as generate_disposal_code except that
+ # assignment will have absorbed a reference to
+ # the result if it is a Python object.
+ if self.is_temp:
+ if self.type.is_pyobject:
+ code.putln("%s = 0;" % self.result())
+ else:
+ self.generate_subexpr_disposal_code(code)
+
+ def generate_inplace_result_disposal_code(self, code):
+ code.put_decref_clear(self.inplace_result, py_object_type)
+
+ def generate_assignment_code(self, rhs, code):
+ # Stub method for nodes which are not legal as
+ # the LHS of an assignment. An error will have
+ # been reported earlier.
+ pass
+
+ def generate_deletion_code(self, code):
+ # Stub method for nodes that are not legal as
+ # the argument of a del statement. An error
+ # will have been reported earlier.
+ pass
+
+ # ----------------- Coercion ----------------------
+
+ def coerce_to(self, dst_type, env):
+ # Coerce the result so that it can be assigned to
+ # something of type dst_type. If processing is necessary,
+ # wraps this node in a coercion node and returns that.
+ # Otherwise, returns this node unchanged.
+ #
+ # This method is called during the analyse_expressions
+ # phase of the src_node's processing.
+ src = self
+ src_type = self.type
+ src_is_py_type = src_type.is_pyobject
+ dst_is_py_type = dst_type.is_pyobject
+
+ if dst_type.is_pyobject:
+ if not src.type.is_pyobject:
+ src = CoerceToPyTypeNode(src, env)
+ if not src.type.subtype_of(dst_type):
+ if not isinstance(src, NoneNode):
+ src = PyTypeTestNode(src, dst_type, env)
+ elif src.type.is_pyobject:
+ src = CoerceFromPyTypeNode(dst_type, src, env)
+ else: # neither src nor dst are py types
+ if not dst_type.assignable_from(src_type):
+ error(self.pos, "Cannot assign type '%s' to '%s'" %
+ (src.type, dst_type))
+ return src
+
+ def coerce_to_pyobject(self, env):
+ return self.coerce_to(PyrexTypes.py_object_type, env)
+
+ def coerce_to_boolean(self, env):
+ # Coerce result to something acceptable as
+ # a boolean value.
+ type = self.type
+ if type.is_pyobject or type.is_ptr or type.is_float:
+ return CoerceToBooleanNode(self, env)
+ else:
+ if not type.is_int and not type.is_error:
+ error(self.pos,
+ "Type '%s' not acceptable as a boolean" % type)
+ return self
+
+ def coerce_to_integer(self, env):
+ # If not already some C integer type, coerce to longint.
+ if self.type.is_int:
+ return self
+ else:
+ return self.coerce_to(PyrexTypes.c_long_type, env)
+
+ def coerce_to_temp(self, env):
+ # Ensure that the result is in a temporary.
+ if self.result_in_temp():
+ return self
+ else:
+ return CoerceToTempNode(self, env)
+
+ def coerce_to_simple(self, env):
+ # Ensure that the result is simple (see is_simple).
+ if self.is_simple():
+ return self
+ else:
+ return self.coerce_to_temp(env)
+
+ def is_simple(self):
+ # A node is simple if its result is something that can
+ # be referred to without performing any operations, e.g.
+ # a constant, local var, C global var, struct member
+ # reference, or temporary.
+ return self.result_in_temp()
+
+
+class AtomicExprNode(ExprNode):
+ # Abstract base class for expression nodes which have
+ # no sub-expressions.
+
+ subexprs = []
+
+
+class PyConstNode(AtomicExprNode):
+ # Abstract base class for constant Python values.
+
+ def is_simple(self):
+ return 1
+
+ def analyse_types(self, env):
+ self.type = py_object_type
+
+ def calculate_result_code(self):
+ return self.value
+
+ def generate_result_code(self, code):
+ pass
+
+
+class NoneNode(PyConstNode):
+ # The constant value None
+
+ value = "Py_None"
+
+ def compile_time_value(self, denv):
+ return None
+
+
+class EllipsisNode(PyConstNode):
+ # '...' in a subscript list.
+
+ value = "Py_Ellipsis"
+
+ def compile_time_value(self, denv):
+ return Ellipsis
+
+
+class ConstNode(AtomicExprNode):
+ # Abstract base type for literal constant nodes.
+ #
+ # value string C code fragment
+
+ is_literal = 1
+
+ def is_simple(self):
+ return 1
+
+ def analyse_types(self, env):
+ pass # Types are held in class variables
+
+ def check_const(self):
+ pass
+
+ def calculate_result_code(self):
+ return str(self.value)
+
+ def generate_result_code(self, code):
+ pass
+
+
+class NullNode(ConstNode):
+ type = PyrexTypes.c_null_ptr_type
+ value = "NULL"
+
+
+class CharNode(ConstNode):
+ type = PyrexTypes.c_char_type
+
+ def compile_time_value(self, denv):
+ return ord(self.value)
+
+ def calculate_result_code(self):
+ return "'%s'" % self.value
+
+
+class IntNode(ConstNode):
+ type = PyrexTypes.c_long_type
+
+ def compile_time_value(self, denv):
+ return int(self.value, 0)
+
+
+class FloatNode(ConstNode):
+ type = PyrexTypes.c_double_type
+
+ def compile_time_value(self, denv):
+ return float(self.value)
+
+ def calculate_result_code(self):
+ strval = str(self.value)
+ if strval == 'nan':
+ return "NAN"
+ elif strval == 'inf':
+ return "INFINITY"
+ elif strval == '-inf':
+ return "(-INFINITY)"
+ else:
+ return strval
+
+
+class StringNode(ConstNode):
+ # #entry Symtab.Entry
+
+ type = PyrexTypes.c_char_ptr_type
+
+ def compile_time_value(self, denv):
+ return eval('"%s"' % self.value)
+
+# def analyse_types(self, env):
+# self.entry = env.add_string_const(self.value)
+
+ def coerce_to(self, dst_type, env):
+ # Arrange for a Python version of the string to be pre-allocated
+ # when coercing to a Python type.
+ if dst_type.is_pyobject and not self.type.is_pyobject:
+ node = self.as_py_string_node(env)
+ else:
+ node = self
+ # We still need to perform normal coerce_to processing on the
+ # result, because we might be coercing to an extension type,
+ # in which case a type test node will be needed.
+ return ConstNode.coerce_to(node, dst_type, env)
+
+ def as_py_string_node(self, env):
+ # Return a new StringNode with the same value as this node
+ # but whose type is a Python type instead of a C type.
+ #entry = self.entry
+ #env.add_py_string(entry)
+ return StringNode(self.pos, type = py_object_type, value = self.value)
+
+ def generate_evaluation_code(self, code):
+ if self.type.is_pyobject:
+ self.result_code = code.get_py_string_const(self.value)
+ else:
+ self.result_code = code.get_string_const(self.value)
+
+ def calculate_result_code(self):
+ return self.result_code
+
+
+class LongNode(AtomicExprNode):
+ # Python long integer literal
+ #
+ # value string
+
+ def compile_time_value(self, denv):
+ return long(self.value)
+
+ gil_message = "Constructing Python long int"
+
+ def analyse_types(self, env):
+ self.type = py_object_type
+ self.gil_check(env)
+ self.is_temp = 1
+
+ def generate_evaluation_code(self, code):
+ result = self.result()
+ code.putln(
+ '%s = PyLong_FromString("%s", 0, 0); if (!%s) %s' % (
+ self.result(),
+ self.value,
+ self.result(),
+ code.error_goto(self.pos)))
+
+
+class ImagNode(AtomicExprNode):
+ # Imaginary number literal
+ #
+ # value float imaginary part
+
+ def compile_time_value(self, denv):
+ return complex(0.0, self.value)
+
+ gil_message = "Constructing complex number"
+
+ def analyse_types(self, env):
+ self.type = py_object_type
+ self.gil_check(env)
+ self.is_temp = 1
+
+ def generate_evaluation_code(self, code):
+ result = self.result()
+ code.putln(
+ "%s = PyComplex_FromDoubles(0.0, %s); if (!%s) %s" % (
+ self.result(),
+ self.value,
+ self.result(),
+ code.error_goto(self.pos)))
+
+
+class NameNode(AtomicExprNode):
+ # Reference to a local or global variable name.
+ #
+ # name string Python name of the variable
+ #
+ # entry Entry Symbol table entry
+ # type_entry Entry For extension type names, the original type entry
+ # interned_cname string
+
+ is_name = 1
+ entry = None
+ type_entry = None
+
+ def compile_time_value(self, denv):
+ try:
+ return denv.lookup(self.name)
+ except KeyError:
+ error(self.pos, "Compile-time name '%s' not defined" % self.name)
+
+ def coerce_to(self, dst_type, env):
+ # If coercing to a generic pyobject and this is a builtin
+ # C function with a Python equivalent, manufacture a NameNode
+ # referring to the Python builtin.
+ #print "NameNode.coerce_to:", self.name, dst_type ###
+ if dst_type is py_object_type:
+ entry = self.entry
+ if entry.is_cfunction:
+ var_entry = entry.as_variable
+ if var_entry:
+ node = NameNode(self.pos, name = self.name)
+ node.entry = var_entry
+ node.analyse_rvalue_entry(env)
+ return node
+ return AtomicExprNode.coerce_to(self, dst_type, env)
+
+ def analyse_as_module(self, env):
+ # Try to interpret this as a reference to a cimported module.
+ # Returns the module scope, or None.
+ entry = env.lookup(self.name)
+ if entry and entry.as_module:
+ return entry.as_module
+ return None
+
+ def analyse_as_extension_type(self, env):
+ # Try to interpret this as a reference to an extension type.
+ # Returns the extension type, or None.
+ entry = env.lookup(self.name)
+ if entry and entry.is_type and entry.type.is_extension_type:
+ return entry.type
+ else:
+ return None
+
+ def analyse_target_declaration(self, env):
+ self.entry = env.lookup_here(self.name)
+ if not self.entry:
+ self.entry = env.declare_var(self.name, py_object_type, self.pos)
+
+ def analyse_types(self, env):
+ self.lookup_entry(env)
+ self.analyse_rvalue_entry(env)
+
+ def lookup_entry(self, env):
+ self.entry = env.lookup(self.name)
+ if not self.entry:
+ self.entry = env.declare_builtin(self.name, self.pos)
+
+ def analyse_target_types(self, env):
+ self.analyse_entry(env)
+ self.finish_analysing_lvalue()
+
+ def analyse_inplace_types(self, env):
+ self.analyse_rvalue_entry(env)
+ self.finish_analysing_lvalue()
+
+ def finish_analysing_lvalue(self):
+ if self.entry.is_readonly:
+ error(self.pos, "Assignment to read-only name '%s'"
+ % self.name)
+ elif not self.is_lvalue():
+ error(self.pos, "Assignment to non-lvalue '%s'"
+ % self.name)
+ self.type = PyrexTypes.error_type
+ self.entry.used = 1
+
+ def analyse_as_function(self, env):
+ self.lookup_entry(env)
+ if self.entry.is_type:
+ self.analyse_constructor_entry(env)
+ else:
+ self.analyse_rvalue_entry(env)
+
+ def analyse_constructor_entry(self, env):
+ entry = self.entry
+ type = entry.type
+ if type.is_struct_or_union:
+ self.type = entry.type.cplus_constructor_type
+ elif type.is_pyobject:
+ self.analyse_rvalue_entry(env)
+ else:
+ error(self.pos, "Type '%s' not callable as a C++ constructor" % type)
+ self.type = error_type
+
+ def analyse_rvalue_entry(self, env):
+ #print "NameNode.analyse_rvalue_entry:", self.name ###
+ #print "Entry:", self.entry.__dict__ ###
+ self.analyse_entry(env)
+ entry = self.entry
+ if entry.is_declared_generic:
+ self.result_ctype = py_object_type
+ if entry.is_pyglobal or entry.is_builtin:
+ self.is_temp = 1
+ self.gil_check(env)
+
+ gil_message = "Accessing Python global or builtin"
+
+ def analyse_entry(self, env):
+ #print "NameNode.analyse_entry:", self.name ###
+ self.check_identifier_kind()
+ entry = self.entry
+ type = entry.type
+ ctype = entry.ctype
+ self.type = type
+ if ctype:
+ self.result_ctype = ctype
+ if entry.is_pyglobal or entry.is_builtin:
+ assert type.is_pyobject, "Python global or builtin not a Python object"
+ #self.interned_cname = env.intern(self.entry.name)
+
+ def check_identifier_kind(self):
+ # Check that this is an appropriate kind of name for use in an expression.
+ # Also finds the variable entry associated with an extension type.
+ entry = self.entry
+ if entry.is_type and entry.type.is_extension_type:
+ self.type_entry = entry
+ if not (entry.is_const or entry.is_variable
+ or entry.is_builtin or entry.is_cfunction):
+ if self.entry.as_variable:
+ self.entry = self.entry.as_variable
+ else:
+ error(self.pos,
+ "'%s' is not a constant, variable or function identifier" % self.name)
+
+ def is_simple(self):
+ # If it's not a C variable, it'll be in a temp.
+ return 1
+
+ def calculate_target_results(self, env):
+ pass
+
+ def check_const(self):
+ entry = self.entry
+ if not (entry.is_const or entry.is_cfunction):
+ self.not_const()
+
+ def check_const_addr(self):
+ entry = self.entry
+ if not (entry.is_cglobal or entry.is_cfunction):
+ self.addr_not_const()
+
+ def is_lvalue(self):
+ entry = self.entry
+ return entry.is_variable and \
+ not entry.type.is_array and \
+ not entry.is_readonly
+
+ def is_inplace_lvalue(self):
+ return self.is_lvalue()
+
+ def is_ephemeral(self):
+ # Name nodes are never ephemeral, even if the
+ # result is in a temporary.
+ return 0
+
+ def allocate_temp(self, env, result = None):
+ AtomicExprNode.allocate_temp(self, env, result)
+ entry = self.entry
+ if entry:
+ entry.used = 1
+
+ def calculate_result_code(self):
+ entry = self.entry
+ if not entry:
+ return "<error>" # There was an error earlier
+ return entry.cname
+
+ def generate_result_code(self, code):
+ assert hasattr(self, 'entry')
+ entry = self.entry
+ if entry is None:
+ return # There was an error earlier
+ if entry.utility_code:
+ code.use_utility_code(entry.utility_code)
+ if entry.is_pyglobal or entry.is_builtin:
+ if entry.is_builtin:
+ namespace = Naming.builtins_cname
+ else: # entry.is_pyglobal
+ namespace = entry.namespace_cname
+ result = self.result()
+ cname = code.intern(self.entry.name)
+ code.use_utility_code(get_name_interned_utility_code)
+ code.putln(
+ '%s = __Pyx_GetName(%s, %s); if (!%s) %s' % (
+ result,
+ namespace,
+ cname,
+ result,
+ code.error_goto(self.pos)))
+
+ def generate_setattr_code(self, value_code, code):
+ entry = self.entry
+ namespace = self.entry.namespace_cname
+ cname = code.intern(self.entry.name)
+ code.putln(
+ 'if (PyObject_SetAttr(%s, %s, %s) < 0) %s' % (
+ namespace,
+ cname,
+ value_code,
+ code.error_goto(self.pos)))
+
+ def generate_assignment_code(self, rhs, code):
+ #print "NameNode.generate_assignment_code:", self.name ###
+ entry = self.entry
+ if entry is None:
+ return # There was an error earlier
+ if entry.is_pyglobal:
+ self.generate_setattr_code(rhs.py_result(), code)
+ if debug_disposal_code:
+ print "NameNode.generate_assignment_code:"
+ print "...generating disposal code for", rhs
+ rhs.generate_disposal_code(code)
+ else:
+ if self.type.is_pyobject:
+ rhs.make_owned_reference(code)
+ code.put_decref(self.py_result())
+ code.putln('%s = %s;' % (self.result(), rhs.result_as(self.ctype())))
+ if debug_disposal_code:
+ print "NameNode.generate_assignment_code:"
+ print "...generating post-assignment code for", rhs
+ rhs.generate_post_assignment_code(code)
+
+ def generate_inplace_assignment_code(self, operator, rhs, code):
+ entry = self.entry
+ if entry is None:
+ return # There was an error earlier
+ if self.type.is_pyobject:
+ self.generate_result_code(code)
+ self.generate_inplace_operation_code(operator, rhs, code)
+ if entry.is_pyglobal:
+ self.generate_setattr_code(self.inplace_result, code)
+ self.generate_inplace_result_disposal_code(code)
+ else:
+ code.put_decref(self.py_result())
+ cast_inplace_result = typecast(self.ctype(), py_object_type, self.inplace_result)
+ code.putln('%s = %s;' % (self.result(), cast_inplace_result))
+ else:
+ code.putln("%s %s %s;" % (self.result(), operator, rhs.result()))
+ rhs.generate_disposal_code(code)
+
+ def generate_deletion_code(self, code):
+ if self.entry is None:
+ return # There was an error earlier
+ if not self.entry.is_pyglobal:
+ error(self.pos, "Deletion of local or C global name not supported")
+ return
+ cname = code.intern(self.entry.name)
+ code.putln(
+ 'if (PyObject_DelAttr(%s, %s) < 0) %s' % (
+ Naming.module_cname,
+ cname,
+ code.error_goto(self.pos)))
+
+ def mark_vars_used(self):
+ if self.entry:
+ self.entry.used = 1
+
+
+class BackquoteNode(ExprNode):
+ # `expr`
+ #
+ # arg ExprNode
+
+ subexprs = ['arg']
+
+ def analyse_types(self, env):
+ self.arg.analyse_types(env)
+ self.arg = self.arg.coerce_to_pyobject(env)
+ self.type = py_object_type
+ self.gil_check(env)
+ self.is_temp = 1
+
+ gil_message = "Backquote expression"
+
+ def generate_result_code(self, code):
+ result = self.result()
+ code.putln(
+ "%s = PyObject_Repr(%s); if (!%s) %s" % (
+ self.result(),
+ self.arg.py_result(),
+ self.result(),
+ code.error_goto(self.pos)))
+
+
+class ImportNode(ExprNode):
+ # Used as part of import statement implementation.
+ # Implements result =
+ # __import__(module_name, globals(), None, name_list)
+ #
+ # module_name StringNode dotted name of module
+ # name_list ListNode or None list of names to be imported
+
+ subexprs = ['module_name', 'name_list']
+
+ def analyse_types(self, env):
+ self.module_name.analyse_types(env)
+ self.module_name = self.module_name.coerce_to_pyobject(env)
+ if self.name_list:
+ self.name_list.analyse_types(env)
+ self.type = py_object_type
+ self.gil_check(env)
+ self.is_temp = 1
+# env.use_utility_code(import_utility_code)
+
+ gil_message = "Python import"
+
+ def generate_result_code(self, code):
+ if self.name_list:
+ name_list_code = self.name_list.py_result()
+ else:
+ name_list_code = "0"
+ code.use_utility_code(import_utility_code)
+ result = self.result()
+ code.putln(
+ "%s = __Pyx_Import(%s, %s); if (!%s) %s" % (
+ result,
+ self.module_name.py_result(),
+ name_list_code,
+ result,
+ code.error_goto(self.pos)))
+
+
+class IteratorNode(ExprNode):
+ # Used as part of for statement implementation.
+ # Implements result = iter(sequence)
+ #
+ # sequence ExprNode
+
+ subexprs = ['sequence']
+
+ def analyse_types(self, env):
+ self.sequence.analyse_types(env)
+ self.sequence = self.sequence.coerce_to_pyobject(env)
+ self.type = py_object_type
+ self.gil_check(env)
+ self.is_temp = 1
+
+ gil_message = "Iterating over Python object"
+
+ def generate_result_code(self, code):
+ result = self.result()
+ code.putln(
+ "%s = PyObject_GetIter(%s); if (!%s) %s" % (
+ result,
+ self.sequence.py_result(),
+ result,
+ code.error_goto(self.pos)))
+
+
+class NextNode(AtomicExprNode):
+ # Used as part of for statement implementation.
+ # Implements result = iterator.next()
+ # Created during analyse_types phase.
+ # The iterator is not owned by this node.
+ #
+ # iterator ExprNode
+
+ def __init__(self, iterator, env):
+ self.pos = iterator.pos
+ self.iterator = iterator
+ self.type = py_object_type
+ self.is_temp = 1
+
+ def generate_result_code(self, code):
+ result = self.result()
+ code.putln(
+ "%s = PyIter_Next(%s);" % (
+ result,
+ self.iterator.py_result()))
+ code.putln(
+ "if (!%s) {" %
+ result)
+ code.putln(
+ "if (PyErr_Occurred()) %s" %
+ code.error_goto(self.pos))
+ code.putln(
+ "break;")
+ code.putln(
+ "}")
+
+
+class ExcValueNode(AtomicExprNode):
+ # Node created during analyse_types phase
+ # of an ExceptClauseNode to fetch the current
+ # exception or traceback value.
+
+ def __init__(self, pos, env, var):
+ ExprNode.__init__(self, pos)
+ self.type = py_object_type
+ self.var = var
+
+ def calculate_result_code(self):
+ return self.var
+
+ def generate_result_code(self, code):
+ pass
+
+
+class TempNode(AtomicExprNode):
+ # Node created during analyse_types phase
+ # of some nodes to hold a temporary value.
+
+ def __init__(self, pos, type, env):
+ ExprNode.__init__(self, pos)
+ self.type = type
+ if type.is_pyobject:
+ self.result_ctype = py_object_type
+ self.is_temp = 1
+
+ def generate_result_code(self, code):
+ pass
+
+
+class PyTempNode(TempNode):
+ # TempNode holding a Python value.
+
+ def __init__(self, pos, env):
+ TempNode.__init__(self, pos, PyrexTypes.py_object_type, env)
+
+
+#-------------------------------------------------------------------
+#
+# Trailer nodes
+#
+#-------------------------------------------------------------------
+
+class IndexNode(ExprNode):
+ # Sequence indexing.
+ #
+ # base ExprNode
+ # index ExprNode
+
+ subexprs = ['base', 'index']
+
+ def compile_time_value(self, denv):
+ base = self.base.compile_time_value(denv)
+ index = self.index.compile_time_value(denv)
+ try:
+ return base[index]
+ except Exception, e:
+ self.compile_time_value_error(e)
+
+ def is_ephemeral(self):
+ return self.base.is_ephemeral()
+
+ def analyse_target_declaration(self, env):
+ pass
+
+ def analyse_types(self, env):
+ self.analyse_base_and_index_types(env, getting = 1)
+
+ def analyse_target_types(self, env):
+ self.analyse_base_and_index_types(env, setting = 1)
+
+ def analyse_inplace_types(self, env):
+ self.analyse_base_and_index_types(env, getting = 1, setting = 1)
+
+ def analyse_base_and_index_types(self, env, getting = 0, setting = 0):
+ self.base.analyse_types(env)
+ self.index.analyse_types(env)
+ btype = self.base.type
+ if btype.is_pyobject:
+ itype = self.index.type
+ if not (btype.is_sequence and itype.is_int and itype.signed):
+ self.index = self.index.coerce_to_pyobject(env)
+ self.type = py_object_type
+ self.gil_check(env)
+ self.is_temp = 1
+ else:
+ if self.base.type.is_ptr or self.base.type.is_array:
+ self.type = self.base.type.base_type
+ else:
+ error(self.pos,
+ "Attempting to index non-array type '%s'" %
+ self.base.type)
+ self.type = PyrexTypes.error_type
+ if self.index.type.is_pyobject:
+ self.index = self.index.coerce_to(
+ PyrexTypes.c_py_ssize_t_type, env)
+ if not self.index.type.is_int:
+ error(self.pos,
+ "Invalid index type '%s'" %
+ self.index.type)
+
+ gil_message = "Indexing Python object"
+
+ def check_const_addr(self):
+ self.base.check_const_addr()
+ self.index.check_const()
+
+ def is_lvalue(self):
+ return 1
+
+ def is_inplace_lvalue(self):
+ return 1
+
+ def calculate_result_code(self):
+ return "(%s[%s])" % (
+ self.base.result(), self.index.result())
+
+ def generate_result_code(self, code):
+ if self.type.is_pyobject:
+ itype = self.index.type
+ if itype.is_int and itype.signed:
+ code.use_utility_code(getitem_int_utility_code)
+ function = "__Pyx_GetItemInt"
+ index_code = self.index.result()
+ else:
+ function = "PyObject_GetItem"
+ index_code = self.index.py_result()
+ result = self.result()
+ code.putln(
+ "%s = %s(%s, %s); if (!%s) %s" % (
+ result,
+ function,
+ self.base.py_result(),
+ index_code,
+ result,
+ code.error_goto(self.pos)))
+
+ def generate_setitem_code(self, value_code, code):
+ itype = self.index.type
+ if itype.is_int and itype.signed:
+ code.use_utility_code(setitem_int_utility_code)
+ function = "__Pyx_SetItemInt"
+ index_code = self.index.result()
+ else:
+ function = "PyObject_SetItem"
+ index_code = self.index.py_result()
+ code.putln(
+ "if (%s(%s, %s, %s) < 0) %s" % (
+ function,
+ self.base.py_result(),
+ index_code,
+ value_code,
+ code.error_goto(self.pos)))
+
+ def generate_assignment_code(self, rhs, code):
+ self.generate_subexpr_evaluation_code(code)
+ if self.type.is_pyobject:
+ self.generate_setitem_code(rhs.py_result(), code)
+ else:
+ code.putln(
+ "%s = %s;" % (
+ self.result(), rhs.result()))
+ self.generate_subexpr_disposal_code(code)
+ rhs.generate_disposal_code(code)
+
+ def generate_inplace_assignment_code(self, operator, rhs, code):
+ self.generate_subexpr_evaluation_code(code)
+ if self.type.is_pyobject:
+ self.generate_result_code(code)
+ self.generate_inplace_operation_code(operator, rhs, code)
+ self.generate_setitem_code(self.inplace_result, code)
+ self.generate_inplace_result_disposal_code(code)
+ else:
+ code.putln("%s %s %s;" % (self.result(), operator, rhs.result()))
+ rhs.generate_disposal_code(code)
+ self.generate_subexpr_disposal_code(code)
+
+ def generate_deletion_code(self, code):
+ self.generate_subexpr_evaluation_code(code)
+ if self.base.type.is_sequence and self.index.type.is_int:
+ function = "PySequence_DelItem"
+ index_code = self.index.result()
+ else:
+ function = "PyObject_DelItem"
+ index_code = self.index.py_result()
+ code.putln(
+ "if (%s(%s, %s) < 0) %s" % (
+ function,
+ self.base.py_result(),
+ index_code,
+ code.error_goto(self.pos)))
+ #else:
+ # error(self.pos, "Cannot delete non-Python variable")
+ self.generate_subexpr_disposal_code(code)
+
+
+class SliceIndexNode(ExprNode):
+ # 2-element slice indexing
+ #
+ # base ExprNode
+ # start ExprNode or None
+ # stop ExprNode or None
+
+ subexprs = ['base', 'start', 'stop']
+
+ def is_inplace_lvalue(self):
+ return 1
+
+ def compile_time_value(self, denv):
+ base = self.base.compile_time_value(denv)
+ start = self.start.compile_time_value(denv)
+ stop = self.stop.compile_time_value(denv)
+ try:
+ return base[start:stop]
+ except Exception, e:
+ self.compile_time_value_error(e)
+
+ def analyse_target_declaration(self, env):
+ pass
+
+ def analyse_types(self, env):
+ self.base.analyse_types(env)
+ if self.start:
+ self.start.analyse_types(env)
+ if self.stop:
+ self.stop.analyse_types(env)
+ self.base = self.base.coerce_to_pyobject(env)
+ c_int = PyrexTypes.c_py_ssize_t_type
+ if self.start:
+ self.start = self.start.coerce_to(c_int, env)
+ if self.stop:
+ self.stop = self.stop.coerce_to(c_int, env)
+ self.type = py_object_type
+ self.gil_check(env)
+ self.is_temp = 1
+
+ gil_message = "Slicing Python object"
+
+ def generate_result_code(self, code):
+ result = self.result()
+ code.putln(
+ "%s = PySequence_GetSlice(%s, %s, %s); if (!%s) %s" % (
+ result,
+ self.base.py_result(),
+ self.start_code(),
+ self.stop_code(),
+ result,
+ code.error_goto(self.pos)))
+
+ def generate_setslice_code(self, value_code, code):
+ code.putln(
+ "if (PySequence_SetSlice(%s, %s, %s, %s) < 0) %s" % (
+ self.base.py_result(),
+ self.start_code(),
+ self.stop_code(),
+ value_code,
+ code.error_goto(self.pos)))
+
+ def generate_assignment_code(self, rhs, code):
+ self.generate_subexpr_evaluation_code(code)
+ self.generate_setslice_code(rhs.result(), code)
+ self.generate_subexpr_disposal_code(code)
+ rhs.generate_disposal_code(code)
+
+ def generate_inplace_assignment_code(self, operator, rhs, code):
+ self.generate_subexpr_evaluation_code(code)
+ self.generate_result_code(code)
+ self.generate_inplace_operation_code(operator, rhs, code)
+ self.generate_setslice_code(self.inplace_result, code)
+ self.generate_inplace_result_disposal_code(code)
+ self.generate_subexpr_disposal_code(code)
+
+ def generate_deletion_code(self, code):
+ self.generate_subexpr_evaluation_code(code)
+ code.putln(
+ "if (PySequence_DelSlice(%s, %s, %s) < 0) %s" % (
+ self.base.py_result(),
+ self.start_code(),
+ self.stop_code(),
+ code.error_goto(self.pos)))
+ self.generate_subexpr_disposal_code(code)
+
+ def start_code(self):
+ if self.start:
+ return self.start.result()
+ else:
+ return "0"
+
+ def stop_code(self):
+ if self.stop:
+ return self.stop.result()
+ else:
+ return "PY_SSIZE_T_MAX"
+
+# def calculate_result_code(self):
+# # self.result_code is not used, but this method must exist
+# return "<unused>"
+
+
+class SliceNode(ExprNode):
+ # start:stop:step in subscript list
+ #
+ # start ExprNode
+ # stop ExprNode
+ # step ExprNode
+
+ def compile_time_value(self, denv):
+ start = self.start.compile_time_value(denv)
+ stop = self.stop.compile_time_value(denv)
+ step = step.step.compile_time_value(denv)
+ try:
+ return slice(start, stop, step)
+ except Exception, e:
+ self.compile_time_value_error(e)
+
+ subexprs = ['start', 'stop', 'step']
+
+ def analyse_types(self, env):
+ self.start.analyse_types(env)
+ self.stop.analyse_types(env)
+ self.step.analyse_types(env)
+ self.start = self.start.coerce_to_pyobject(env)
+ self.stop = self.stop.coerce_to_pyobject(env)
+ self.step = self.step.coerce_to_pyobject(env)
+ self.type = py_object_type
+ self.gil_check(env)
+ self.is_temp = 1
+
+ gil_message = "Constructing Python slice object"
+
+ def generate_result_code(self, code):
+ result = self.result()
+ code.putln(
+ "%s = PySlice_New(%s, %s, %s); if (!%s) %s" % (
+ result,
+ self.start.py_result(),
+ self.stop.py_result(),
+ self.step.py_result(),
+ result,
+ code.error_goto(self.pos)))
+
+
+class CallNode(ExprNode):
+
+ def gil_check(self, env):
+ # Make sure we're not in a nogil environment
+ if env.nogil:
+ error(self.pos, "Calling gil-requiring function without gil")
+
+
+class SimpleCallNode(CallNode):
+ # Function call without keyword, * or ** args.
+ #
+ # function ExprNode
+ # args [ExprNode]
+ # arg_tuple ExprNode or None used internally
+ # self ExprNode or None used internally
+ # coerced_self ExprNode or None used internally
+ # function_type PyrexType used internally
+
+ subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
+
+ self = None
+ coerced_self = None
+ arg_tuple = None
+ is_new = False
+
+ cplus_argless_constr_type = CFuncType(None, [])
+
+ def compile_time_value(self, denv):
+ function = self.function.compile_time_value(denv)
+ args = [arg.compile_time_value(denv) for arg in self.args]
+ try:
+ return function(*args)
+ except Exception, e:
+ self.compile_time_value_error(e)
+
+ def analyse_types(self, env):
+ #print "SimpleCallNode.analyse_types:", self.pos ###
+ function = self.function
+ function.is_called = 1
+ function.analyse_as_function(env)
+ if function.is_name or function.is_attribute:
+ #print "SimpleCallNode.analyse_types:", self.pos, "is name or attribute" ###
+ func_entry = function.entry
+ if func_entry:
+ if func_entry.is_cmethod or func_entry.is_builtin_method:
+ # Take ownership of the object from which the attribute
+ # was obtained, because we need to pass it as 'self'.
+ #print "SimpleCallNode: Snarfing self argument" ###
+ self.self = function.obj
+ function.obj = CloneNode(self.self)
+ elif self.is_new:
+ if not (func_entry.is_type and func_entry.type.is_struct_or_union
+ and func_entry.type.scope.is_cplus):
+ error(self.pos, "'new' operator can only be used on a C++ struct type")
+ self.type = error_type
+ return
+ else:
+ #print "SimpleCallNode.analyse_types:", self.pos, "not name or attribute" ###
+ if self.is_new:
+ error(self.pos, "Invalid use of 'new' operator")
+ self.type = error_type
+ return
+ func_type = self.function.type
+ if func_type.is_ptr:
+ func_type = func_type.base_type
+ self.function_type = func_type
+ if func_type.is_pyobject:
+ #print "SimpleCallNode: Python call" ###
+ if self.args:
+ self.arg_tuple = TupleNode(self.pos, args = self.args)
+ self.arg_tuple.analyse_types(env)
+ else:
+ self.arg_tuple = None
+ self.args = None
+ if function.is_name and function.type_entry:
+ # We are calling an extension type constructor
+ self.type = function.type_entry.type
+ self.result_ctype = py_object_type
+ else:
+ self.type = py_object_type
+ self.gil_check(env)
+ self.is_temp = 1
+ else:
+ #print "SimpleCallNode: C call" ###
+ for arg in self.args:
+ arg.analyse_types(env)
+ if func_type.is_cfunction:
+ self.type = func_type.return_type
+ if self.is_new:
+ self.type = CPtrType(self.type)
+ if func_type.is_overloaded:
+ func_type = self.resolve_overloading()
+ if not func_type:
+ self.type = error_type
+ return
+ if self.self and func_type.args:
+ #print "SimpleCallNode: Inserting self into argument list" ###
+ # Coerce 'self' to the type expected by the method.
+ expected_type = func_type.args[0].type
+ self.coerced_self = CloneNode(self.self).coerce_to(
+ expected_type, env)
+ # Insert coerced 'self' argument into argument list.
+ self.args.insert(0, self.coerced_self)
+ self.analyse_c_function_call(env)
+
+ def resolve_overloading(self):
+ func_type = self.function_type
+ arg_types = [arg.type for arg in self.args]
+ signatures = func_type.signatures or [self.cplus_argless_constr_type]
+ for signature in signatures:
+ if signature.callable_with(arg_types):
+ signature.return_type = func_type.return_type
+ self.function_type = signature
+ return signature
+ def display_types(types):
+ return ", ".join([str(type) for type in types])
+ error(self.pos, "No matching signature found for argument types (%s)"
+ % display_types(arg_types))
+ if signatures:
+ error(self.pos, "Candidates are:")
+ for signature in signatures:
+ error(signature.pos, "(%s)" % display_types(signature.args))
+
+ def analyse_c_function_call(self, env):
+ func_type = self.function_type
+ # Check function type
+ if not func_type.is_cfunction:
+ if not func_type.is_error:
+ error(self.pos, "Calling non-function type '%s'" %
+ func_type)
+ self.type = PyrexTypes.error_type
+ return
+ # Check no. of args
+ expected_nargs = len(func_type.args)
+ actual_nargs = len(self.args)
+ if actual_nargs < expected_nargs \
+ or (not func_type.has_varargs and actual_nargs > expected_nargs):
+ expected_str = str(expected_nargs)
+ if func_type.has_varargs:
+ expected_str = "at least " + expected_str
+ error(self.pos,
+ "Call with wrong number of arguments (expected %s, got %s)"
+ % (expected_str, actual_nargs))
+ self.args = None
+ self.type = PyrexTypes.error_type
+ return
+ # Coerce arguments
+ for i in range(expected_nargs):
+ formal_type = func_type.args[i].type
+ self.args[i] = self.args[i].coerce_to(formal_type, env)
+ for i in range(expected_nargs, actual_nargs):
+ if self.args[i].type.is_pyobject:
+ error(self.args[i].pos,
+ "Python object cannot be passed as a varargs parameter")
+ # Calc result code fragment
+ #print "SimpleCallNode.analyse_c_function_call: self.type =", self.type ###
+ if self.type.is_pyobject \
+ or func_type.exception_value is not None \
+ or func_type.exception_check:
+ self.is_temp = 1
+ if self.type.is_pyobject:
+ self.result_ctype = py_object_type
+ # Check gil
+ if not func_type.nogil:
+ self.gil_check(env)
+ if func_type.exception_check and env.nogil:
+ self.gil_error("Calling 'except ?' or 'except *' function")
+
+ def calculate_result_code(self):
+ return self.c_call_code()
+
+ def c_call_code(self):
+ if self.type.is_error or self.args is None or not self.function_type.is_cfunction:
+ return "<error>"
+ func_type = self.function_type
+ formal_args = func_type.args
+ arg_list_code = []
+ for (formal_arg, actual_arg) in zip(formal_args, self.args):
+ arg_code = actual_arg.result_as(formal_arg.type)
+ arg_list_code.append(arg_code)
+ for actual_arg in self.args[len(formal_args):]:
+ arg_list_code.append(actual_arg.result())
+ result = "%s(%s)" % (self.function.result(),
+ join(arg_list_code, ","))
+ if self.is_new:
+ result = "new " + result
+ return result
+
+ def generate_result_code(self, code):
+ if self.type.is_error:
+ return
+ func_type = self.function_type
+ result = self.result()
+ if func_type.is_pyobject:
+ if self.arg_tuple:
+ arg_code = self.arg_tuple.py_result()
+ else:
+ arg_code = "0"
+ code.putln(
+ "%s = PyObject_CallObject(%s, %s); if (!%s) %s" % (
+ result,
+ self.function.py_result(),
+ arg_code,
+ result,
+ code.error_goto(self.pos)))
+ elif func_type.is_cfunction:
+ exc_checks = []
+ if self.type.is_pyobject:
+ exc_checks.append("!%s" % result)
+ else:
+ exc_val = func_type.exception_value
+ exc_check = func_type.exception_check
+ if exc_val is not None:
+ exc_checks.append("%s == %s" % (self.result(), exc_val))
+ if exc_check:
+ exc_checks.append("PyErr_Occurred()")
+ if self.is_temp or exc_checks:
+ rhs = self.c_call_code()
+ result = self.result()
+ if result:
+ lhs = "%s = " % result
+ if self.is_temp and self.type.is_pyobject:
+ #return_type = self.type # func_type.return_type
+ #print "SimpleCallNode.generate_result_code: casting", rhs, \
+ # "from", return_type, "to pyobject" ###
+ rhs = typecast(py_object_type, self.type, rhs)
+ else:
+ lhs = ""
+ code.putln(
+ "%s%s; if (%s) %s" % (
+ lhs,
+ rhs,
+ " && ".join(exc_checks),
+ code.error_goto(self.pos)))
+
+
+class GeneralCallNode(CallNode):
+ # General Python function call, including keyword,
+ # * and ** arguments.
+ #
+ # function ExprNode
+ # positional_args ExprNode Tuple of positional arguments
+ # keyword_args ExprNode or None Dict of keyword arguments
+ # starstar_arg ExprNode or None Dict of extra keyword args
+
+ subexprs = ['function', 'positional_args', 'keyword_args', 'starstar_arg']
+
+ def compile_time_value(self, denv):
+ function = self.function.compile_time_value(denv)
+ positional_args = self.positional_args.compile_time_value(denv)
+ keyword_args = self.keyword_args.compile_time_value(denv)
+ starstar_arg = self.starstar_arg.compile_time_value(denv)
+ try:
+ keyword_args.update(starstar_arg)
+ return function(*positional_args, **keyword_args)
+ except Exception, e:
+ self.compile_time_value_error(e)
+
+ def analyse_types(self, env):
+ function = self.function
+ function.analyse_types(env)
+ self.positional_args.analyse_types(env)
+ if self.keyword_args:
+ self.keyword_args.analyse_types(env)
+ if self.starstar_arg:
+ self.starstar_arg.analyse_types(env)
+ self.function = self.function.coerce_to_pyobject(env)
+ self.positional_args = \
+ self.positional_args.coerce_to_pyobject(env)
+ if self.starstar_arg:
+ self.starstar_arg = \
+ self.starstar_arg.coerce_to_pyobject(env)
+ if function.is_name and function.type_entry:
+ # We are calling an extension type constructor
+ self.type = function.type_entry.type
+ self.result_ctype = py_object_type
+ else:
+ self.type = py_object_type
+ self.gil_check(env)
+ self.is_temp = 1
+
+ def generate_result_code(self, code):
+ if self.keyword_args and self.starstar_arg:
+ code.putln(
+ "if (PyDict_Update(%s, %s) < 0) %s" % (
+ self.keyword_args.py_result(),
+ self.starstar_arg.py_result(),
+ code.error_goto(self.pos)))
+ keyword_code = self.keyword_args.py_result()
+ elif self.keyword_args:
+ keyword_code = self.keyword_args.py_result()
+ elif self.starstar_arg:
+ keyword_code = self.starstar_arg.py_result()
+ else:
+ keyword_code = None
+ if not keyword_code:
+ call_code = "PyObject_CallObject(%s, %s)" % (
+ self.function.py_result(),
+ self.positional_args.py_result())
+ else:
+ call_code = "PyEval_CallObjectWithKeywords(%s, %s, %s)" % (
+ self.function.py_result(),
+ self.positional_args.py_result(),
+ keyword_code)
+ result = self.result()
+ code.putln(
+ "%s = %s; if (!%s) %s" % (
+ result,
+ call_code,
+ result,
+ code.error_goto(self.pos)))
+
+
+class AsTupleNode(ExprNode):
+ # Convert argument to tuple. Used for normalising
+ # the * argument of a function call.
+ #
+ # arg ExprNode
+
+ subexprs = ['arg']
+
+ def compile_time_value(self, denv):
+ arg = self.arg.compile_time_value(denv)
+ try:
+ return tuple(arg)
+ except Exception, e:
+ self.compile_time_value_error(e)
+
+ def analyse_types(self, env):
+ self.arg.analyse_types(env)
+ self.arg = self.arg.coerce_to_pyobject(env)
+ self.type = py_object_type
+ self.gil_check(env)
+ self.is_temp = 1
+
+ gil_message = "Constructing Python tuple"
+
+ def generate_result_code(self, code):
+ result = self.result()
+ code.putln(
+ "%s = PySequence_Tuple(%s); if (!%s) %s" % (
+ result,
+ self.arg.py_result(),
+ result,
+ code.error_goto(self.pos)))
+
+
+class AttributeNode(ExprNode):
+ # obj.attribute
+ #
+ # obj ExprNode
+ # attribute string
+ #
+ # Used internally:
+ #
+ # is_py_attr boolean Is a Python getattr operation
+ # member string C name of struct member
+ # is_called boolean Function call is being done on result
+ # entry Entry Symbol table entry of attribute
+ # interned_attr_cname string C name of interned attribute name
+
+ is_attribute = 1
+ subexprs = ['obj']
+
+ type = PyrexTypes.error_type
+ result_code = "<error>"
+ entry = None
+ is_called = 0
+
+ def compile_time_value(self, denv):
+ attr = self.attribute
+ if attr.startswith("__") and attr.endswith("__"):
+ self.error("Invalid attribute name '%s' in compile-time expression"
+ % attr)
+ return None
+ obj = self.obj.compile_time_value(denv)
+ try:
+ return getattr(obj, attr)
+ except Exception, e:
+ self.compile_time_value_error(e)
+
+ def analyse_target_declaration(self, env):
+ pass
+
+ def analyse_target_types(self, env):
+ self.analyse_types(env, target = 1)
+
+ def analyse_as_function(self, env):
+ module_scope = self.obj.analyse_as_module(env)
+ if module_scope:
+ entry = module_scope.lookup_here(self.attribute)
+ if entry and entry.is_type:
+ self.mutate_into_name_node(entry)
+ self.analyse_constructor_entry(env)
+ return
+ self.analyse_types(env)
+
+ def analyse_types(self, env, target = 0):
+ if self.analyse_as_cimported_attribute(env, target):
+ return
+ if not target and self.analyse_as_unbound_cmethod(env):
+ return
+ self.analyse_as_ordinary_attribute(env, target)
+
+ def analyse_as_cimported_attribute(self, env, target = 0, allow_type = 0):
+ # Try to interpret this as a reference to an imported
+ # C const, type, var or function. If successful, mutates
+ # this node into a NameNode and returns 1, otherwise
+ # returns 0.
+ module_scope = self.obj.analyse_as_module(env)
+ if module_scope:
+ entry = module_scope.lookup_here(self.attribute)
+ if entry and (
+ entry.is_cglobal or entry.is_cfunction
+ or entry.is_type or entry.is_const):
+ self.mutate_into_name_node(entry)
+ if entry.is_type and allow_type:
+ pass
+ elif target:
+ self.analyse_target_types(env)
+ else:
+ self.analyse_rvalue_entry(env)
+ return 1
+ return 0
+
+ def analyse_as_unbound_cmethod(self, env):
+ # Try to interpret this as a reference to an unbound
+ # C method of an extension type. If successful, mutates
+ # this node into a NameNode and returns 1, otherwise
+ # returns 0.
+ type = self.obj.analyse_as_extension_type(env)
+ if type:
+ entry = type.scope.lookup_here(self.attribute)
+ if entry and entry.is_cmethod:
+ # Create a temporary entry describing the C method
+ # as an ordinary function.
+ ubcm_entry = Symtab.Entry(entry.name,
+ "%s->%s" % (type.vtabptr_cname, entry.cname),
+ entry.type)
+ ubcm_entry.is_cfunction = 1
+ ubcm_entry.func_cname = entry.func_cname
+ self.mutate_into_name_node(ubcm_entry)
+ self.analyse_rvalue_entry(env)
+ return 1
+ return 0
+
+ def analyse_as_extension_type(self, env):
+ # Try to interpret this as a reference to an extension type
+ # in a cimported module. Returns the extension type, or None.
+ module_scope = self.obj.analyse_as_module(env)
+ if module_scope:
+ entry = module_scope.lookup_here(self.attribute)
+ if entry and entry.is_type and entry.type.is_extension_type:
+ return entry.type
+ return None
+
+ def analyse_as_module(self, env):
+ # Try to interpret this as a reference to a cimported module
+ # in another cimported module. Returns the module scope, or None.
+ module_scope = self.obj.analyse_as_module(env)
+ if module_scope:
+ entry = module_scope.lookup_here(self.attribute)
+ if entry and entry.as_module:
+ return entry.as_module
+ return None
+
+ def mutate_into_name_node(self, entry):
+ # Turn this node into a NameNode with the given entry.
+ self.__class__ = NameNode
+ self.name = self.attribute
+ self.entry = entry
+ del self.obj
+ del self.attribute
+
+ def analyse_as_ordinary_attribute(self, env, target):
+ self.obj.analyse_types(env)
+ self.analyse_attribute(env)
+ if self.entry and self.entry.is_cmethod and not self.is_called:
+ error(self.pos, "C method can only be called")
+ if self.is_py_attr:
+ if not target:
+ self.is_temp = 1
+ self.result_ctype = py_object_type
+
+ def analyse_attribute(self, env):
+ # Look up attribute and set self.type and self.member.
+ self.is_py_attr = 0
+ self.member = self.attribute
+ if self.obj.type.is_string:
+ self.obj = self.obj.coerce_to_pyobject(env)
+ obj_type = self.obj.type
+ if obj_type.is_ptr:
+ obj_type = obj_type.base_type
+ self.op = "->"
+ elif obj_type.is_extension_type:
+ self.op = "->"
+ else:
+ self.op = "."
+ if obj_type.has_attributes:
+ entry = None
+ if obj_type.attributes_known():
+ entry = obj_type.scope.lookup_here(self.attribute)
+ else:
+ error(self.pos,
+ "Cannot select attribute of incomplete type '%s'"
+ % obj_type)
+ obj_type = PyrexTypes.error_type
+ self.entry = entry
+ if entry:
+ if obj_type.is_extension_type and entry.name == "__weakref__":
+ error(self.pos, "Illegal use of special attribute __weakref__")
+ if entry.is_variable or entry.is_cmethod:
+ self.type = entry.type
+ self.member = entry.cname
+ return
+ if entry.is_builtin_method and self.is_called:
+ # Mutate into NameNode referring to C function
+ #print "AttributeNode: Mutating builtin method into NameNode" ###
+ self.type = entry.type
+ self.__class__ = NameNode
+ return
+ else:
+ # If it's not a variable or C method, it must be a Python
+ # method of an extension type, so we treat it like a Python
+ # attribute.
+ pass
+ # If we get here, the base object is not a struct/union/extension
+ # type, or it is an extension type and the attribute is either not
+ # declared or is declared as a Python method. Treat it as a Python
+ # attribute reference.
+ if obj_type.is_pyobject:
+ self.type = py_object_type
+ self.is_py_attr = 1
+ #self.interned_attr_cname = env.intern(self.attribute)
+ self.gil_check(env)
+ else:
+ if not obj_type.is_error:
+ error(self.pos,
+ "Object of type '%s' has no attribute '%s'" %
+ (obj_type, self.attribute))
+
+ gil_message = "Accessing Python attribute"
+
+ def is_simple(self):
+ if self.obj:
+ return self.result_in_temp() or self.obj.is_simple()
+ else:
+ return NameNode.is_simple(self)
+
+ def is_lvalue(self):
+ if self.obj:
+ return 1
+ else:
+ return NameNode.is_lvalue(self)
+
+ def is_inplace_lvalue(self):
+ return self.is_lvalue()
+
+ def is_ephemeral(self):
+ if self.obj:
+ return self.obj.is_ephemeral()
+ else:
+ return NameNode.is_ephemeral(self)
+
+ def calculate_result_code(self):
+ obj = self.obj
+ obj_code = obj.result_as(obj.type)
+ if self.entry and self.entry.is_cmethod:
+ return "((struct %s *)%s%s%s)->%s" % (
+ obj.type.vtabstruct_cname, obj_code, self.op,
+ obj.type.vtabslot_cname, self.member)
+ else:
+ return "%s%s%s" % (obj_code, self.op, self.member)
+
+ def generate_result_code(self, code):
+ if self.is_py_attr:
+ result = self.result()
+ cname = code.intern(self.attribute)
+ code.putln(
+ '%s = PyObject_GetAttr(%s, %s); if (!%s) %s' % (
+ result,
+ self.obj.py_result(),
+ cname,
+ result,
+ code.error_goto(self.pos)))
+
+ def generate_setattr_code(self, value_code, code):
+ cname = code.intern(self.attribute)
+ code.putln(
+ 'if (PyObject_SetAttr(%s, %s, %s) < 0) %s' % (
+ self.obj.py_result(),
+ cname,
+ value_code,
+ code.error_goto(self.pos)))
+
+ def generate_assignment_code(self, rhs, code):
+ self.obj.generate_evaluation_code(code)
+ if self.is_py_attr:
+ self.generate_setattr_code(rhs.py_result(), code)
+ rhs.generate_disposal_code(code)
+ else:
+ select_code = self.result()
+ if self.type.is_pyobject:
+ rhs.make_owned_reference(code)
+ code.put_decref(select_code, self.ctype())
+ code.putln(
+ "%s = %s;" % (
+ select_code,
+ rhs.result_as(self.ctype())))
+ rhs.generate_post_assignment_code(code)
+ self.obj.generate_disposal_code(code)
+
+ def generate_inplace_assignment_code(self, operator, rhs, code):
+ self.obj.generate_evaluation_code(code)
+ select_code = self.result()
+ if self.type.is_pyobject:
+ self.generate_result_code(code)
+ self.generate_inplace_operation_code(operator, rhs, code)
+ if self.is_py_attr:
+ self.generate_setattr_code(self.inplace_result, code)
+ self.generate_inplace_result_disposal_code(code)
+ else:
+ code.put_decref(select_code, self.ctype())
+ cast_inplace_result = typecast(self.ctype(), py_object_type, self.inplace_result)
+ code.putln("%s = %s;" % (select_code, cast_inplace_result))
+ else:
+ code.putln("%s %s %s;" % (select_code, operator, rhs.result()))
+ rhs.generate_disposal_code(code)
+ self.obj.generate_disposal_code(code)
+
+ def generate_deletion_code(self, code):
+ self.obj.generate_evaluation_code(code)
+ if self.is_py_attr:
+ cname = code.intern(self.attribute)
+ code.putln(
+ 'if (PyObject_DelAttr(%s, %s) < 0) %s' % (
+ self.obj.py_result(),
+ cname,
+ code.error_goto(self.pos)))
+ else:
+ error(self.pos, "Cannot delete C attribute of extension type")
+ self.obj.generate_disposal_code(code)
+
+#-------------------------------------------------------------------
+#
+# Constructor nodes
+#
+#-------------------------------------------------------------------
+
+class SequenceNode(ExprNode):
+ # Base class for list and tuple constructor nodes.
+ # Contains common code for performing sequence unpacking.
+ #
+ # args [ExprNode]
+ # iterator ExprNode
+ # unpacked_items [ExprNode] or None
+ # coerced_unpacked_items [ExprNode] or None
+
+ subexprs = ['args']
+
+ is_sequence_constructor = 1
+ unpacked_items = None
+
+ def compile_time_value_list(self, denv):
+ return [arg.compile_time_value(denv) for arg in self.args]
+
+ def analyse_target_declaration(self, env):
+ for arg in self.args:
+ arg.analyse_target_declaration(env)
+
+ def analyse_types(self, env):
+ for i in range(len(self.args)):
+ arg = self.args[i]
+ arg.analyse_types(env)
+ self.args[i] = arg.coerce_to_pyobject(env)
+ self.type = py_object_type
+ self.gil_check(env)
+ self.is_temp = 1
+
+ def analyse_target_types(self, env):
+ self.iterator = PyTempNode(self.pos, env)
+ self.unpacked_items = []
+ self.coerced_unpacked_items = []
+ for arg in self.args:
+ arg.analyse_target_types(env)
+ unpacked_item = PyTempNode(self.pos, env)
+ coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env)
+ self.unpacked_items.append(unpacked_item)
+ self.coerced_unpacked_items.append(coerced_unpacked_item)
+ self.type = py_object_type
+# env.use_utility_code(unpacking_utility_code)
+
+ def allocate_target_temps(self, env, rhs):
+ self.iterator.allocate_temps(env)
+ if rhs:
+ rhs.release_temp(env)
+ for arg, node in zip(self.args, self.coerced_unpacked_items):
+ node.allocate_temps(env)
+ arg.allocate_target_temps(env, node)
+ #arg.release_target_temp(env)
+ #node.release_temp(env)
+ self.iterator.release_temp(env)
+
+# def release_target_temp(self, env):
+# #for arg in self.args:
+# # arg.release_target_temp(env)
+# #for node in self.coerced_unpacked_items:
+# # node.release_temp(env)
+# self.iterator.release_temp(env)
+
+ def generate_result_code(self, code):
+ self.generate_operation_code(code)
+
+ def generate_assignment_code(self, rhs, code):
+ iter_result = self.iterator.result()
+ code.putln(
+ "%s = PyObject_GetIter(%s); if (!%s) %s" % (
+ iter_result,
+ rhs.py_result(),
+ iter_result,
+ code.error_goto(self.pos)))
+ rhs.generate_disposal_code(code)
+ for i in range(len(self.args)):
+ item = self.unpacked_items[i]
+ code.use_utility_code(unpacking_utility_code)
+ unpack_code = "__Pyx_UnpackItem(%s)" % (
+ self.iterator.py_result())
+ item_result = item.result()
+ code.putln(
+ "%s = %s; if (!%s) %s" % (
+ item_result,
+ typecast(item.ctype(), py_object_type, unpack_code),
+ item_result,
+ code.error_goto(self.pos)))
+ value_node = self.coerced_unpacked_items[i]
+ value_node.generate_evaluation_code(code)
+ self.args[i].generate_assignment_code(value_node, code)
+ code.putln(
+ "if (__Pyx_EndUnpack(%s) < 0) %s" % (
+ self.iterator.py_result(),
+ code.error_goto(self.pos)))
+ if debug_disposal_code:
+ print "UnpackNode.generate_assignment_code:"
+ print "...generating disposal code for", rhs
+ self.iterator.generate_disposal_code(code)
+
+
+class TupleNode(SequenceNode):
+ # Tuple constructor.
+
+ gil_message = "Constructing Python tuple"
+
+ def compile_time_value(self, denv):
+ values = self.compile_time_value_list(denv)
+ try:
+ return tuple(values)
+ except Exception, e:
+ self.compile_time_value_error(e)
+
+ def generate_operation_code(self, code):
+ result = self.result()
+ code.putln(
+ "%s = PyTuple_New(%s); if (!%s) %s" % (
+ result,
+ len(self.args),
+ result,
+ code.error_goto(self.pos)))
+ for i in range(len(self.args)):
+ arg = self.args[i]
+ arg_result = arg.py_result()
+ # ??? Change this to use make_owned_reference?
+ if not arg.result_in_temp():
+ code.put_incref(arg_result)
+ code.putln(
+ "PyTuple_SET_ITEM(%s, %s, %s);" % (
+ result,
+ i,
+ arg_result))
+
+ def generate_subexpr_disposal_code(self, code):
+ # We call generate_post_assignment_code here instead
+ # of generate_disposal_code, because values were stored
+ # in the tuple using a reference-stealing operation.
+ for arg in self.args:
+ arg.generate_post_assignment_code(code)
+
+
+class ListNode(SequenceNode):
+ # List constructor.
+
+ gil_message = "Constructing Python list"
+
+ def compile_time_value(self, denv):
+ return self.compile_time_value_list(denv)
+
+ def generate_operation_code(self, code):
+ result = self.result()
+ code.putln("%s = PyList_New(%s); if (!%s) %s" %
+ (result,
+ len(self.args),
+ result,
+ code.error_goto(self.pos)))
+ for i in range(len(self.args)):
+ arg = self.args[i]
+ arg_result = arg.py_result()
+ #if not arg.is_temp:
+ if not arg.result_in_temp():
+ code.put_incref(arg_result)
+ code.putln("PyList_SET_ITEM(%s, %s, %s);" %
+ (result,
+ i,
+ arg_result))
+
+ def generate_subexpr_disposal_code(self, code):
+ # We call generate_post_assignment_code here instead
+ # of generate_disposal_code, because values were stored
+ # in the list using a reference-stealing operation.
+ for arg in self.args:
+ arg.generate_post_assignment_code(code)
+
+
+class DictNode(ExprNode):
+ # Dictionary constructor.
+ #
+ # key_value_pairs [(ExprNode, ExprNode)]
+
+ def compile_time_value(self, denv):
+ pairs = [(key.compile_time_value(denv), value.compile_time_value(denv))
+ for (key, value) in self.key_value_pairs]
+ try:
+ return dict(pairs)
+ except Exception, e:
+ self.compile_time_value_error(e)
+
+ def analyse_types(self, env):
+ new_pairs = []
+ for key, value in self.key_value_pairs:
+ key.analyse_types(env)
+ value.analyse_types(env)
+ key = key.coerce_to_pyobject(env)
+ value = value.coerce_to_pyobject(env)
+ new_pairs.append((key, value))
+ self.key_value_pairs = new_pairs
+ self.type = py_object_type
+ self.gil_check(env)
+ self.is_temp = 1
+
+ gil_message = "Constructing Python dict"
+
+ def allocate_temps(self, env, result = None):
+ # Custom method used here because key-value
+ # pairs are evaluated and used one at a time.
+ self.allocate_temp(env, result)
+ for key, value in self.key_value_pairs:
+ key.allocate_temps(env)
+ value.allocate_temps(env)
+ key.release_temp(env)
+ value.release_temp(env)
+
+ def generate_evaluation_code(self, code):
+ # Custom method used here because key-value
+ # pairs are evaluated and used one at a time.
+ result = self.result()
+ code.putln(
+ "%s = PyDict_New(); if (!%s) %s" % (
+ result,
+ result,
+ code.error_goto(self.pos)))
+ for key, value in self.key_value_pairs:
+ key.generate_evaluation_code(code)
+ value.generate_evaluation_code(code)
+ code.putln(
+ "if (PyDict_SetItem(%s, %s, %s) < 0) %s" % (
+ result,
+ key.py_result(),
+ value.py_result(),
+ code.error_goto(self.pos)))
+ key.generate_disposal_code(code)
+ value.generate_disposal_code(code)
+
+
+class ClassNode(ExprNode):
+ # Helper class used in the implementation of Python
+ # class definitions. Constructs a class object given
+ # a name, tuple of bases and class dictionary.
+ #
+ # name ExprNode Name of the class
+ # bases ExprNode Base class tuple
+ # dict ExprNode Class dict (not owned by this node)
+ # doc ExprNode or None Doc string
+ # module_name string Name of defining module
+
+ subexprs = ['name', 'bases', 'doc']
+
+ def analyse_types(self, env):
+ self.name.analyse_types(env)
+ self.name = self.name.coerce_to_pyobject(env)
+ self.bases.analyse_types(env)
+ if self.doc:
+ self.doc.analyse_types(env)
+ self.doc = self.doc.coerce_to_pyobject(env)
+ self.module_name = env.global_scope().qualified_name
+ self.type = py_object_type
+ self.gil_check(env)
+ self.is_temp = 1
+# env.use_utility_code(create_class_utility_code)
+
+ gil_message = "Constructing Python class"
+
+ def generate_result_code(self, code):
+ result = self.result()
+ if self.doc:
+ code.putln(
+ 'if (PyDict_SetItemString(%s, "__doc__", %s) < 0) %s' % (
+ self.dict.py_result(),
+ self.doc.py_result(),
+ code.error_goto(self.pos)))
+ code.use_utility_code(create_class_utility_code)
+ code.putln(
+ '%s = __Pyx_CreateClass(%s, %s, %s, "%s"); if (!%s) %s' % (
+ result,
+ self.bases.py_result(),
+ self.dict.py_result(),
+ self.name.py_result(),
+ self.module_name,
+ result,
+ code.error_goto(self.pos)))
+
+
+class UnboundMethodNode(ExprNode):
+ # Helper class used in the implementation of Python
+ # class definitions. Constructs an unbound method
+ # object from a class and a function.
+ #
+ # class_cname string C var holding the class object
+ # function ExprNode Function object
+
+ subexprs = ['function']
+
+ def analyse_types(self, env):
+ self.function.analyse_types(env)
+ self.type = py_object_type
+ self.gil_check(env)
+ self.is_temp = 1
+
+ gil_message = "Constructing an unbound method"
+
+ def generate_result_code(self, code):
+ result = self.result()
+ code.putln(
+ "%s = PyMethod_New(%s, 0, %s); if (!%s) %s" % (
+ result,
+ self.function.py_result(),
+ self.class_cname,
+ result,
+ code.error_goto(self.pos)))
+
+
+class PyCFunctionNode(AtomicExprNode):
+ # Helper class used in the implementation of Python
+ # class definitions. Constructs a PyCFunction object
+ # from a PyMethodDef struct.
+ #
+ # pymethdef_cname string PyMethodDef structure
+ # module_name string Name of defining module
+
+ def analyse_types(self, env):
+ self.type = py_object_type
+ self.module_name = env.global_scope().module_name
+ self.gil_check(env)
+ self.is_temp = 1
+
+ gil_message = "Constructing Python function"
+
+ def generate_result_code(self, code):
+ result = self.result()
+ code.putln(
+ "%s = PyCFunction_NewEx(&%s, 0, %s); if (!%s) %s" % (
+ result,
+ self.pymethdef_cname,
+ code.get_py_string_const(self.module_name),
+ result,
+ code.error_goto(self.pos)))
+
+#-------------------------------------------------------------------
+#
+# Unary operator nodes
+#
+#-------------------------------------------------------------------
+
+compile_time_unary_operators = {
+ 'not': operator.not_,
+ '~': operator.inv,
+ '-': operator.neg,
+ '+': operator.pos,
+}
+
+class UnopNode(ExprNode):
+ # operator string
+ # operand ExprNode
+ #
+ # Processing during analyse_expressions phase:
+ #
+ # analyse_c_operation
+ # Called when the operand is not a pyobject.
+ # - Check operand type and coerce if needed.
+ # - Determine result type and result code fragment.
+ # - Allocate temporary for result if needed.
+
+ subexprs = ['operand']
+
+ def compile_time_value(self, denv):
+ func = compile_time_unary_operators.get(self.operator)
+ if not func:
+ error(self.pos,
+ "Unary '%s' not supported in compile-time expression"
+ % self.operator)
+ operand = self.operand.compile_time_value(denv)
+ try:
+ return func(operand)
+ except Exception, e:
+ self.compile_time_value_error(e)
+
+ def analyse_types(self, env):
+ self.operand.analyse_types(env)
+ if self.is_py_operation():
+ self.coerce_operand_to_pyobject(env)
+ self.type = py_object_type
+ self.gil_check(env)
+ self.is_temp = 1
+ else:
+ self.analyse_c_operation(env)
+
+ def check_const(self):
+ self.operand.check_const()
+
+ def is_py_operation(self):
+ return self.operand.type.is_pyobject
+
+ def coerce_operand_to_pyobject(self, env):
+ self.operand = self.operand.coerce_to_pyobject(env)
+
+ def generate_result_code(self, code):
+ if self.operand.type.is_pyobject:
+ self.generate_py_operation_code(code)
+ else:
+ if self.is_temp:
+ self.generate_c_operation_code(code)
+
+ def generate_py_operation_code(self, code):
+ function = self.py_operation_function()
+ result = self.result()
+ code.putln(
+ "%s = %s(%s); if (!%s) %s" % (
+ result,
+ function,
+ self.operand.py_result(),
+ result,
+ code.error_goto(self.pos)))
+
+ def type_error(self):
+ if not self.operand.type.is_error:
+ error(self.pos, "Invalid operand type for '%s' (%s)" %
+ (self.operator, self.operand.type))
+ self.type = PyrexTypes.error_type
+
+
+class NotNode(ExprNode):
+ # 'not' operator
+ #
+ # operand ExprNode
+
+ def compile_time_value(self, denv):
+ operand = self.operand.compile_time_value(denv)
+ try:
+ return not operand
+ except Exception, e:
+ self.compile_time_value_error(e)
+
+ subexprs = ['operand']
+
+ def analyse_types(self, env):
+ self.operand.analyse_types(env)
+ self.operand = self.operand.coerce_to_boolean(env)
+ self.type = PyrexTypes.c_int_type
+
+ def calculate_result_code(self):
+ return "(!%s)" % self.operand.result()
+
+ def generate_result_code(self, code):
+ pass
+
+
+class UnaryPlusNode(UnopNode):
+ # unary '+' operator
+
+ operator = '+'
+
+ def analyse_c_operation(self, env):
+ self.type = self.operand.type
+
+ def py_operation_function(self):
+ return "PyNumber_Positive"
+
+ def calculate_result_code(self):
+ return self.operand.result()
+
+
+class UnaryMinusNode(UnopNode):
+ # unary '-' operator
+
+ operator = '-'
+
+ def analyse_c_operation(self, env):
+ if self.operand.type.is_numeric:
+ self.type = self.operand.type
+ else:
+ self.type_error()
+
+ def py_operation_function(self):
+ return "PyNumber_Negative"
+
+ def calculate_result_code(self):
+ return "(-%s)" % self.operand.result()
+
+
+class TildeNode(UnopNode):
+ # unary '~' operator
+
+ def analyse_c_operation(self, env):
+ if self.operand.type.is_int:
+ self.type = self.operand.type
+ else:
+ self.type_error()
+
+ def py_operation_function(self):
+ return "PyNumber_Invert"
+
+ def calculate_result_code(self):
+ return "(~%s)" % self.operand.result()
+
+
+class AmpersandNode(ExprNode):
+ # The C address-of operator.
+ #
+ # operand ExprNode
+
+ subexprs = ['operand']
+
+ def analyse_types(self, env):
+ self.operand.analyse_types(env)
+ argtype = self.operand.type
+ if not (argtype.is_cfunction or self.operand.is_lvalue()):
+ self.error("Taking address of non-lvalue")
+ return
+ if argtype.is_pyobject:
+ self.error("Cannot take address of Python variable")
+ return
+ self.type = PyrexTypes.c_ptr_type(argtype)
+
+ def check_const(self):
+ self.operand.check_const_addr()
+
+ def error(self, mess):
+ error(self.pos, mess)
+ self.type = PyrexTypes.error_type
+ self.result_code = "<error>"
+
+ def calculate_result_code(self):
+ return "(&%s)" % self.operand.result()
+
+ def generate_result_code(self, code):
+ pass
+
+
+unop_node_classes = {
+ "+": UnaryPlusNode,
+ "-": UnaryMinusNode,
+ "~": TildeNode,
+}
+
+def unop_node(pos, operator, operand):
+ # Construct unnop node of appropriate class for
+ # given operator.
+ return unop_node_classes[operator](pos,
+ operator = operator,
+ operand = operand)
+
+
+class TypecastNode(ExprNode):
+ # C type cast
+ #
+ # base_type CBaseTypeNode
+ # declarator CDeclaratorNode
+ # operand ExprNode
+
+ subexprs = ['operand']
+
+ def analyse_types(self, env):
+ base_type = self.base_type.analyse(env)
+ _, self.type = self.declarator.analyse(base_type, env)
+ if self.type.is_cfunction:
+ error(self.pos,
+ "Cannot cast to a function type")
+ self.type = PyrexTypes.error_type
+ self.operand.analyse_types(env)
+ to_py = self.type.is_pyobject
+ from_py = self.operand.type.is_pyobject
+ if from_py and not to_py and self.operand.is_ephemeral():
+ error(self.pos, "Casting temporary Python object to non-Python type")
+ # Must do the following, so that the result can be increfed without
+ # the operand getting evaluated twice.
+ if to_py and not from_py:
+ #self.result_ctype = py_object_type
+ #self.is_temp = 1
+ self.operand = self.operand.coerce_to_simple(env)
+
+ def check_const(self):
+ self.operand.check_const()
+
+ def calculate_result_code(self):
+ opnd = self.operand
+ result_code = self.type.cast_code(opnd.result())
+ return result_code
+
+ def result_as(self, type):
+ if not self.is_temp and type.is_pyobject and self.type.is_pyobject:
+ # Optimise away some unnecessary casting
+ return self.operand.result_as(type)
+ else:
+ return ExprNode.result_as(self, type)
+
+ def generate_result_code(self, code):
+ if self.is_temp:
+ code.putln(
+ "%s = %s;" % (
+ self.result(),
+ self.operand.py_result()))
+ code.put_incref(self.py_result())
+
+
+class SizeofNode(ExprNode):
+ # Base class for sizeof(x) expression nodes.
+ #
+ # sizeof_code string
+
+ subexprs = []
+
+ def check_const(self):
+ pass
+
+ def analyse_types(self, env):
+ self.analyse_argument(env)
+ self.type = PyrexTypes.c_size_t_type
+
+ def analyse_type_argument(self, arg_type):
+ if arg_type.is_pyobject:
+ error(self.pos, "Cannot take sizeof Python object")
+ elif arg_type.is_void:
+ error(self.pos, "Cannot take sizeof void")
+ elif not arg_type.is_complete():
+ error(self.pos, "Cannot take sizeof incomplete type '%s'" % arg_type)
+ arg_code = arg_type.declaration_code("")
+ self.sizeof_code = "(sizeof(%s))" % arg_code
+
+ def calculate_result_code(self):
+ return self.sizeof_code
+
+ def generate_result_code(self, code):
+ pass
+
+
+class SizeofTypeNode(SizeofNode):
+ # C sizeof function applied to a type
+ #
+ # base_type CBaseTypeNode
+ # declarator CDeclaratorNode
+
+ def analyse_argument(self, env):
+ base_type = self.base_type.analyse(env)
+ _, arg_type = self.declarator.analyse(base_type, env)
+ self.analyse_type_argument(arg_type)
+
+
+class SizeofVarNode(SizeofNode):
+ # C sizeof function applied to a variable or qualified name
+ # (which may actually refer to a type)
+ #
+ # operand ExprNode
+
+ #subexprs = ['operand']
+
+ def analyse_argument(self, env):
+ is_type = 0
+ operand = self.operand
+ if operand.analyse_as_cimported_attribute(env, allow_type = 1):
+ if operand.entry.is_type:
+ is_type = 1
+ self.analyse_type_argument(operand.entry.type)
+ else:
+ self.operand.analyse_types(env)
+ self.operand.mark_vars_used()
+ if not is_type:
+ self.sizeof_code = "(sizeof(%s))" % operand.result()
+
+
+#-------------------------------------------------------------------
+#
+# Binary operator nodes
+#
+#-------------------------------------------------------------------
+
+compile_time_binary_operators = {
+ '<': operator.lt,
+ '<=': operator.le,
+ '==': operator.eq,
+ '!=': operator.ne,
+ '>=': operator.ge,
+ '>': operator.gt,
+ 'is': operator.is_,
+ 'is_not': operator.is_not,
+ '+': operator.add,
+ '&': operator.and_,
+ '/': operator.div,
+ '//': operator.floordiv,
+ '<<': operator.lshift,
+ '%': operator.mod,
+ '*': operator.mul,
+ '|': operator.or_,
+ '**': operator.pow,
+ '>>': operator.rshift,
+ '-': operator.sub,
+ #'/': operator.truediv,
+ '^': operator.xor,
+ 'in': lambda x, y: x in y,
+ 'not_in': lambda x, y: x not in y,
+}
+
+def get_compile_time_binop(node):
+ func = compile_time_binary_operators.get(node.operator)
+ if not func:
+ error(node.pos,
+ "Binary '%s' not supported in compile-time expression"
+ % node.operator)
+ return func
+
+class BinopNode(ExprNode):
+ # operator string
+ # operand1 ExprNode
+ # operand2 ExprNode
+ #
+ # Processing during analyse_expressions phase:
+ #
+ # analyse_c_operation
+ # Called when neither operand is a pyobject.
+ # - Check operand types and coerce if needed.
+ # - Determine result type and result code fragment.
+ # - Allocate temporary for result if needed.
+
+ subexprs = ['operand1', 'operand2']
+
+ def compile_time_value(self, denv):
+ func = get_compile_time_binop(self)
+ operand1 = self.operand1.compile_time_value(denv)
+ operand2 = self.operand2.compile_time_value(denv)
+ try:
+ return func(operand1, operand2)
+ except Exception, e:
+ self.compile_time_value_error(e)
+
+ def analyse_types(self, env):
+ self.operand1.analyse_types(env)
+ self.operand2.analyse_types(env)
+ if self.is_py_operation():
+ self.coerce_operands_to_pyobjects(env)
+ self.type = py_object_type
+ self.gil_check(env)
+ self.is_temp = 1
+ else:
+ self.analyse_c_operation(env)
+
+ def is_py_operation(self):
+ return (self.operand1.type.is_pyobject
+ or self.operand2.type.is_pyobject)
+
+ def coerce_operands_to_pyobjects(self, env):
+ self.operand1 = self.operand1.coerce_to_pyobject(env)
+ self.operand2 = self.operand2.coerce_to_pyobject(env)
+
+ def check_const(self):
+ self.operand1.check_const()
+ self.operand2.check_const()
+
+ def generate_result_code(self, code):
+ #print "BinopNode.generate_result_code:", self.operand1, self.operand2 ###
+ if self.operand1.type.is_pyobject:
+ function = self.py_operation_function()
+ if function == "PyNumber_Power":
+ extra_args = ", Py_None"
+ else:
+ extra_args = ""
+ result = self.result()
+ code.putln(
+ "%s = %s(%s, %s%s); if (!%s) %s" % (
+ result,
+ function,
+ self.operand1.py_result(),
+ self.operand2.py_result(),
+ extra_args,
+ result,
+ code.error_goto(self.pos)))
+ else:
+ if self.is_temp:
+ self.generate_c_operation_code(code)
+
+ def type_error(self):
+ if not (self.operand1.type.is_error
+ or self.operand2.type.is_error):
+ error(self.pos, "Invalid operand types for '%s' (%s; %s)" %
+ (self.operator, self.operand1.type,
+ self.operand2.type))
+ self.type = PyrexTypes.error_type
+
+
+class NumBinopNode(BinopNode):
+ # Binary operation taking numeric arguments.
+
+ def analyse_c_operation(self, env):
+ type1 = self.operand1.type
+ type2 = self.operand2.type
+ if self.operator == "**" and type1.is_int and type2.is_int:
+ error(self.pos, "** with two C int types is ambiguous")
+ self.type = error_type
+ return
+ self.type = self.compute_c_result_type(type1, type2)
+ if not self.type:
+ self.type_error()
+
+ def compute_c_result_type(self, type1, type2):
+ if self.c_types_okay(type1, type2):
+ return PyrexTypes.widest_numeric_type(type1, type2)
+ else:
+ return None
+
+ def c_types_okay(self, type1, type2):
+ #print "NumBinopNode.c_types_okay:", type1, type2 ###
+ return (type1.is_numeric or type1.is_enum) \
+ and (type2.is_numeric or type2.is_enum)
+
+ def calculate_result_code(self):
+ return "(%s %s %s)" % (
+ self.operand1.result(),
+ self.operator,
+ self.operand2.result())
+
+ def py_operation_function(self):
+ return self.py_functions[self.operator]
+
+ py_functions = {
+ "|": "PyNumber_Or",
+ "^": "PyNumber_Xor",
+ "&": "PyNumber_And",
+ "<<": "PyNumber_Lshift",
+ ">>": "PyNumber_Rshift",
+ "+": "PyNumber_Add",
+ "-": "PyNumber_Subtract",
+ "*": "PyNumber_Multiply",
+ "/": "PyNumber_Divide",
+ "%": "PyNumber_Remainder",
+ "**": "PyNumber_Power"
+ }
+
+
+class IntBinopNode(NumBinopNode):
+ # Binary operation taking integer arguments.
+
+ def c_types_okay(self, type1, type2):
+ #print "IntBinopNode.c_types_okay:", type1, type2 ###
+ return (type1.is_int or type1.is_enum) \
+ and (type2.is_int or type2.is_enum)
+
+
+class AddNode(NumBinopNode):
+ # '+' operator.
+
+ def is_py_operation(self):
+ if self.operand1.type.is_string \
+ and self.operand2.type.is_string:
+ return 1
+ else:
+ return NumBinopNode.is_py_operation(self)
+
+ def compute_c_result_type(self, type1, type2):
+ #print "AddNode.compute_c_result_type:", type1, self.operator, type2 ###
+ if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
+ return type1
+ elif (type2.is_ptr or type2.is_array) and (type1.is_int or type1.is_enum):
+ return type2
+ else:
+ return NumBinopNode.compute_c_result_type(
+ self, type1, type2)
+
+
+class SubNode(NumBinopNode):
+ # '-' operator.
+
+ def compute_c_result_type(self, type1, type2):
+ if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
+ return type1
+ elif (type1.is_ptr or type1.is_array) and (type2.is_ptr or type2.is_array):
+ return PyrexTypes.c_int_type
+ else:
+ return NumBinopNode.compute_c_result_type(
+ self, type1, type2)
+
+
+class MulNode(NumBinopNode):
+ # '*' operator.
+
+ def is_py_operation(self):
+ type1 = self.operand1.type
+ type2 = self.operand2.type
+ if (type1.is_string and type2.is_int) \
+ or (type2.is_string and type1.is_int):
+ return 1
+ else:
+ return NumBinopNode.is_py_operation(self)
+
+
+class ModNode(IntBinopNode):
+ # '%' operator.
+
+ def is_py_operation(self):
+ return (self.operand1.type.is_string
+ or self.operand2.type.is_string
+ or IntBinopNode.is_py_operation(self))
+
+
+class PowNode(NumBinopNode):
+ # '**' operator.
+
+ def analyse_types(self, env):
+ env.pow_function_used = 1
+ NumBinopNode.analyse_types(self, env)
+
+ def compute_c_result_type(self, type1, type2):
+ if self.c_types_okay(type1, type2):
+ return PyrexTypes.c_double_type
+ else:
+ return None
+
+ def calculate_result_code(self):
+ return "pow(%s, %s)" % (
+ self.operand1.result(), self.operand2.result())
+
+
+class BoolBinopNode(ExprNode):
+ # Short-circuiting boolean operation.
+ #
+ # operator string
+ # operand1 ExprNode
+ # operand2 ExprNode
+ # temp_bool ExprNode used internally
+
+ temp_bool = None
+
+ subexprs = ['operand1', 'operand2', 'temp_bool']
+
+ def compile_time_value(self, denv):
+ if self.operator == 'and':
+ return self.operand1.compile_time_value(denv) \
+ and self.operand2.compile_time_value(denv)
+ else:
+ return self.operand1.compile_time_value(denv) \
+ or self.operand2.compile_time_value(denv)
+
+ def analyse_types(self, env):
+ self.operand1.analyse_types(env)
+ self.operand2.analyse_types(env)
+ if self.operand1.type.is_pyobject or \
+ self.operand2.type.is_pyobject:
+ self.operand1 = self.operand1.coerce_to_pyobject(env)
+ self.operand2 = self.operand2.coerce_to_pyobject(env)
+ self.temp_bool = TempNode(self.pos,
+ PyrexTypes.c_int_type, env)
+ self.type = py_object_type
+ self.gil_check(env)
+ else:
+ self.operand1 = self.operand1.coerce_to_boolean(env)
+ self.operand2 = self.operand2.coerce_to_boolean(env)
+ self.type = PyrexTypes.c_int_type
+ # For what we're about to do, it's vital that
+ # both operands be temp nodes.
+ self.operand1 = self.operand1.coerce_to_temp(env) #CTT
+ self.operand2 = self.operand2.coerce_to_temp(env)
+ self.is_temp = 1
+
+ gil_message = "Truth-testing Python object"
+
+ def allocate_temps(self, env, result_code = None):
+ # We don't need both operands at the same time, and
+ # one of the operands will also be our result. So we
+ # use an allocation strategy here which results in
+ # this node and both its operands sharing the same
+ # result variable. This allows us to avoid some
+ # assignments and increfs/decrefs that would otherwise
+ # be necessary.
+ self.allocate_temp(env, result_code)
+ self.operand1.allocate_temps(env, self.result_code)
+ if self.temp_bool:
+ self.temp_bool.allocate_temp(env)
+ self.temp_bool.release_temp(env)
+ self.operand2.allocate_temps(env, self.result_code)
+ # We haven't called release_temp on either operand,
+ # because although they are temp nodes, they don't own
+ # their result variable. And because they are temp
+ # nodes, any temps in their subnodes will have been
+ # released before their allocate_temps returned.
+ # Therefore, they contain no temp vars that need to
+ # be released.
+
+ def check_const(self):
+ self.operand1.check_const()
+ self.operand2.check_const()
+
+ def calculate_result_code(self):
+ return "(%s %s %s)" % (
+ self.operand1.result(),
+ self.py_to_c_op[self.operator],
+ self.operand2.result())
+
+ py_to_c_op = {'and': "&&", 'or': "||"}
+
+ def generate_evaluation_code(self, code):
+ self.operand1.generate_evaluation_code(code)
+ test_result = self.generate_operand1_test(code)
+ if self.operator == 'and':
+ sense = ""
+ else:
+ sense = "!"
+ code.putln(
+ "if (%s%s) {" % (
+ sense,
+ test_result))
+ self.operand1.generate_disposal_code(code)
+ self.operand2.generate_evaluation_code(code)
+ code.putln(
+ "}")
+
+ def generate_operand1_test(self, code):
+ # Generate code to test the truth of the first operand.
+ if self.type.is_pyobject:
+ test_result = self.temp_bool.result()
+ code.putln(
+ "%s = PyObject_IsTrue(%s); if (%s < 0) %s" % (
+ test_result,
+ self.operand1.py_result(),
+ test_result,
+ code.error_goto(self.pos)))
+ else:
+ test_result = self.operand1.result()
+ return test_result
+
+
+class CmpNode:
+ # Mixin class containing code common to PrimaryCmpNodes
+ # and CascadedCmpNodes.
+
+ def cascaded_compile_time_value(self, operand1, denv):
+ func = get_compile_time_binop(self)
+ operand2 = self.operand2.compile_time_value(denv)
+ try:
+ result = func(operand1, operand2)
+ except Exception, e:
+ self.compile_time_value_error(e)
+ result = None
+ if result:
+ cascade = self.cascade
+ if cascade:
+ result = result and cascade.compile_time_value(operand2, denv)
+ return result
+
+ def is_python_comparison(self):
+ return (self.has_python_operands()
+ or (self.cascade and self.cascade.is_python_comparison())
+ or self.operator in ('in', 'not_in'))
+
+ def check_types(self, env, operand1, op, operand2):
+ if not self.types_okay(operand1, op, operand2):
+ error(self.pos, "Invalid types for '%s' (%s, %s)" %
+ (self.operator, operand1.type, operand2.type))
+
+ def types_okay(self, operand1, op, operand2):
+ type1 = operand1.type
+ type2 = operand2.type
+ if type1.is_error or type2.is_error:
+ return 1
+ if type1.is_pyobject: # type2 will be, too
+ return 1
+ elif type1.is_ptr or type1.is_array:
+ return type1.is_null_ptr or type2.is_null_ptr \
+ or ((type2.is_ptr or type2.is_array)
+ and type1.base_type.same_as(type2.base_type))
+ elif ((type1.is_numeric and type2.is_numeric
+ or type1.is_enum and (type2.is_int or type1.same_as(type2))
+ or type1.is_int and type2.is_enum)
+ and op not in ('is', 'is_not')):
+ return 1
+ else:
+ return 0
+
+ def generate_operation_code(self, code, result,
+ operand1, op , operand2):
+ if op == 'in' or op == 'not_in':
+ code.putln(
+ "%s = PySequence_Contains(%s, %s); if (%s < 0) %s" % (
+ result,
+ operand2.py_result(),
+ operand1.py_result(),
+ result,
+ code.error_goto(self.pos)))
+ if op == 'not_in':
+ code.putln(
+ "%s = !%s;" % (
+ result, result))
+ elif (operand1.type.is_pyobject
+ and op not in ('is', 'is_not')):
+ code.putln(
+ "if (PyObject_Cmp(%s, %s, &%s) < 0) %s" % (
+ operand1.py_result(),
+ operand2.py_result(),
+ result,
+ code.error_goto(self.pos)))
+ code.putln(
+ "%s = %s %s 0;" % (
+ result, result, op))
+ else:
+ type1 = operand1.type
+ type2 = operand2.type
+ if (type1.is_extension_type or type2.is_extension_type) \
+ and not operand1.ctype().same_as(operand2.ctype()):
+ code1 = operand1.result_as(py_object_type)
+ code2 = operand2.result_as(py_object_type)
+ else:
+ code1 = operand1.result()
+ code2 = operand2.result()
+ code.putln("%s = %s %s %s;" % (
+ result,
+ code1,
+ self.c_operator(op),
+ code2))
+
+ def c_operator(self, op):
+ if op == 'is':
+ return "=="
+ elif op == 'is_not':
+ return "!="
+ else:
+ return op
+
+
+class PrimaryCmpNode(ExprNode, CmpNode):
+ # Non-cascaded comparison or first comparison of
+ # a cascaded sequence.
+ #
+ # operator string
+ # operand1 ExprNode
+ # operand2 ExprNode
+ # cascade CascadedCmpNode
+
+ # We don't use the subexprs mechanism, because
+ # things here are too complicated for it to handle.
+ # Instead, we override all the framework methods
+ # which use it.
+
+ cascade = None
+
+ def compile_time_value(self, denv):
+ operand1 = self.operand1.compile_time_value(denv)
+ return self.cascaded_compile_time_value(operand1, denv)
+
+ def analyse_types(self, env):
+ self.operand1.analyse_types(env)
+ self.operand2.analyse_types(env)
+ if self.cascade:
+ self.cascade.analyse_types(env, self.operand2)
+ self.is_pycmp = self.is_python_comparison()
+ if self.is_pycmp:
+ self.coerce_operands_to_pyobjects(env)
+ if self.cascade:
+ self.operand2 = self.operand2.coerce_to_simple(env)
+ self.cascade.coerce_cascaded_operands_to_temp(env)
+ self.check_operand_types(env)
+ self.type = PyrexTypes.c_int_type
+ if self.is_pycmp or self.cascade:
+ self.is_temp = 1
+
+ def check_operand_types(self, env):
+ self.check_types(env,
+ self.operand1, self.operator, self.operand2)
+ if self.cascade:
+ self.cascade.check_operand_types(env, self.operand2)
+
+ def has_python_operands(self):
+ return (self.operand1.type.is_pyobject
+ or self.operand2.type.is_pyobject)
+
+ def coerce_operands_to_pyobjects(self, env):
+ self.operand1 = self.operand1.coerce_to_pyobject(env)
+ self.operand2 = self.operand2.coerce_to_pyobject(env)
+ if self.cascade:
+ self.cascade.coerce_operands_to_pyobjects(env)
+
+ def allocate_subexpr_temps(self, env):
+ self.operand1.allocate_temps(env)
+ self.operand2.allocate_temps(env)
+ if self.cascade:
+ self.cascade.allocate_subexpr_temps(env)
+
+ def release_subexpr_temps(self, env):
+ self.operand1.release_temp(env)
+ self.operand2.release_temp(env)
+ if self.cascade:
+ self.cascade.release_subexpr_temps(env)
+
+ def check_const(self):
+ self.operand1.check_const()
+ self.operand2.check_const()
+ if self.cascade:
+ self.not_const()
+
+ def calculate_result_code(self):
+ return "(%s %s %s)" % (
+ self.operand1.result(),
+ self.c_operator(self.operator),
+ self.operand2.result())
+
+ def generate_evaluation_code(self, code):
+ self.operand1.generate_evaluation_code(code)
+ self.operand2.generate_evaluation_code(code)
+ if self.is_temp:
+ result = self.result()
+ self.generate_operation_code(code, result,
+ self.operand1, self.operator, self.operand2)
+ if self.cascade:
+ self.cascade.generate_evaluation_code(code,
+ result, self.operand2)
+ self.operand1.generate_disposal_code(code)
+ self.operand2.generate_disposal_code(code)
+
+ def generate_subexpr_disposal_code(self, code):
+ # If this is called, it is a non-cascaded cmp,
+ # so only need to dispose of the two main operands.
+ self.operand1.generate_disposal_code(code)
+ self.operand2.generate_disposal_code(code)
+
+
+class CascadedCmpNode(Node, CmpNode):
+ # A CascadedCmpNode is not a complete expression node. It
+ # hangs off the side of another comparison node, shares
+ # its left operand with that node, and shares its result
+ # with the PrimaryCmpNode at the head of the chain.
+ #
+ # operator string
+ # operand2 ExprNode
+ # cascade CascadedCmpNode
+
+ cascade = None
+
+ def analyse_types(self, env, operand1):
+ self.operand2.analyse_types(env)
+ if self.cascade:
+ self.cascade.analyse_types(env, self.operand2)
+
+ def check_operand_types(self, env, operand1):
+ self.check_types(env,
+ operand1, self.operator, self.operand2)
+ if self.cascade:
+ self.cascade.check_operand_types(env, self.operand2)
+
+ def has_python_operands(self):
+ return self.operand2.type.is_pyobject
+
+ def coerce_operands_to_pyobjects(self, env):
+ self.operand2 = self.operand2.coerce_to_pyobject(env)
+ if self.cascade:
+ self.cascade.coerce_operands_to_pyobjects(env)
+
+ def coerce_cascaded_operands_to_temp(self, env):
+ if self.cascade:
+ #self.operand2 = self.operand2.coerce_to_temp(env) #CTT
+ self.operand2 = self.operand2.coerce_to_simple(env)
+ self.cascade.coerce_cascaded_operands_to_temp(env)
+
+ def allocate_subexpr_temps(self, env):
+ self.operand2.allocate_temps(env)
+ if self.cascade:
+ self.cascade.allocate_subexpr_temps(env)
+
+ def release_subexpr_temps(self, env):
+ self.operand2.release_temp(env)
+ if self.cascade:
+ self.cascade.release_subexpr_temps(env)
+
+ def generate_evaluation_code(self, code, result, operand1):
+ code.putln("if (%s) {" % result)
+ self.operand2.generate_evaluation_code(code)
+ self.generate_operation_code(code, result,
+ operand1, self.operator, self.operand2)
+ if self.cascade:
+ self.cascade.generate_evaluation_code(
+ code, result, self.operand2)
+ # Cascaded cmp result is always temp
+ self.operand2.generate_disposal_code(code)
+ code.putln("}")
+
+
+binop_node_classes = {
+ "or": BoolBinopNode,
+ "and": BoolBinopNode,
+ "|": IntBinopNode,
+ "^": IntBinopNode,
+ "&": IntBinopNode,
+ "<<": IntBinopNode,
+ ">>": IntBinopNode,
+ "+": AddNode,
+ "-": SubNode,
+ "*": MulNode,
+ "/": NumBinopNode,
+ "%": ModNode,
+ "**": PowNode
+}
+
+def binop_node(pos, operator, operand1, operand2):
+ # Construct binop node of appropriate class for
+ # given operator.
+ return binop_node_classes[operator](pos,
+ operator = operator,
+ operand1 = operand1,
+ operand2 = operand2)
+
+#-------------------------------------------------------------------
+#
+# Coercion nodes
+#
+# Coercion nodes are special in that they are created during
+# the analyse_types phase of parse tree processing.
+# Their __init__ methods consequently incorporate some aspects
+# of that phase.
+#
+#-------------------------------------------------------------------
+
+class CoercionNode(ExprNode):
+ # Abstract base class for coercion nodes.
+ #
+ # arg ExprNode node being coerced
+
+ subexprs = ['arg']
+
+ def __init__(self, arg):
+ self.pos = arg.pos
+ self.arg = arg
+ if debug_coercion:
+ print self, "Coercing", self.arg
+
+
+class CastNode(CoercionNode):
+ # Wrap a node in a C type cast.
+
+ def __init__(self, arg, new_type):
+ CoercionNode.__init__(self, arg)
+ self.type = new_type
+
+ def calculate_result_code(self):
+ return self.arg.result_as(self.type)
+
+ def generate_result_code(self, code):
+ self.arg.generate_result_code(code)
+
+
+class PyTypeTestNode(CoercionNode):
+ # This node is used to check that a generic Python
+ # object is an instance of a particular extension type.
+ # This node borrows the result of its argument node.
+
+ def __init__(self, arg, dst_type, env):
+ # The arg is know to be a Python object, and
+ # the dst_type is known to be an extension type.
+ assert dst_type.is_extension_type, "PyTypeTest on non extension type"
+ CoercionNode.__init__(self, arg)
+ self.type = dst_type
+ self.result_ctype = arg.ctype()
+# env.use_utility_code(type_test_utility_code)
+ self.gil_check(env)
+
+ gil_message = "Python type test"
+
+ def result_in_temp(self):
+ return self.arg.result_in_temp()
+
+ def is_ephemeral(self):
+ return self.arg.is_ephemeral()
+
+ def calculate_result_code(self):
+ return self.arg.result()
+
+ def generate_result_code(self, code):
+ if self.type.typeobj_is_available():
+ code.use_utility_code(type_test_utility_code)
+ code.putln(
+ "if (!__Pyx_TypeTest(%s, %s)) %s" % (
+ self.arg.py_result(),
+ self.type.typeptr_cname,
+ code.error_goto(self.pos)))
+ else:
+ error(self.pos, "Cannot test type of extern C class "
+ "without type object name specification")
+
+ def generate_post_assignment_code(self, code):
+ self.arg.generate_post_assignment_code(code)
+
+
+class CoerceToPyTypeNode(CoercionNode):
+ # This node is used to convert a C data type
+ # to a Python object.
+
+ def __init__(self, arg, env):
+ CoercionNode.__init__(self, arg)
+ self.type = py_object_type
+ self.gil_check(env)
+ self.is_temp = 1
+ if not arg.type.to_py_function:
+ error(arg.pos,
+ "Cannot convert '%s' to Python object" % arg.type)
+
+ gil_message = "Converting to Python object"
+
+ def generate_result_code(self, code):
+ function = self.arg.type.to_py_function
+ result = self.result()
+ code.putln('%s = %s(%s); if (!%s) %s' % (
+ result,
+ function,
+ self.arg.result(),
+ result,
+ code.error_goto(self.pos)))
+
+
+class CoerceFromPyTypeNode(CoercionNode):
+ # This node is used to convert a Python object
+ # to a C data type.
+
+ def __init__(self, result_type, arg, env):
+ CoercionNode.__init__(self, arg)
+ self.type = result_type
+ self.is_temp = 1
+ if not result_type.from_py_function:
+ error(arg.pos,
+ "Cannot convert Python object to '%s'" % result_type)
+ if self.type.is_string and self.arg.is_ephemeral():
+ error(arg.pos,
+ "Obtaining char * from temporary Python value")
+
+ def generate_result_code(self, code):
+ function = self.type.from_py_function
+ operand = self.arg.py_result()
+ rhs = "%s(%s)" % (function, operand)
+ if self.type.is_enum:
+ rhs = typecast(self.type, c_long_type, rhs)
+ result = self.result()
+ if self.type.is_string:
+ err_code = "!%s" % result
+ else:
+ err_code = "PyErr_Occurred()"
+ code.putln('%s = %s; if (%s) %s' % (
+ result,
+ rhs,
+ err_code,
+ code.error_goto(self.pos)))
+
+
+class CoerceToBooleanNode(CoercionNode):
+ # This node is used when a result needs to be used
+ # in a boolean context.
+
+ def __init__(self, arg, env):
+ CoercionNode.__init__(self, arg)
+ self.type = PyrexTypes.c_int_type
+ if arg.type.is_pyobject:
+ if env.nogil:
+ self.gil_error()
+ self.is_temp = 1
+
+ gil_message = "Truth-testing Python object"
+
+ def check_const(self):
+ if self.is_temp:
+ self.not_const()
+ self.arg.check_const()
+
+ def calculate_result_code(self):
+ return "(%s != 0)" % self.arg.result()
+
+ def generate_result_code(self, code):
+ if self.arg.type.is_pyobject:
+ result = self.result()
+ code.putln(
+ "%s = PyObject_IsTrue(%s); if (%s < 0) %s" % (
+ result,
+ self.arg.py_result(),
+ result,
+ code.error_goto(self.pos)))
+
+
+class CoerceToTempNode(CoercionNode):
+ # This node is used to force the result of another node
+ # to be stored in a temporary. It is only used if the
+ # argument node's result is not already in a temporary.
+
+ def __init__(self, arg, env):
+ CoercionNode.__init__(self, arg)
+ self.type = self.arg.type
+ self.is_temp = 1
+ if self.type.is_pyobject:
+ self.gil_check(env)
+ self.result_ctype = py_object_type
+
+ gil_message = "Creating temporary Python reference"
+
+
+ def generate_result_code(self, code):
+ #self.arg.generate_evaluation_code(code) # Already done
+ # by generic generate_subexpr_evaluation_code!
+ code.putln("%s = %s;" % (
+ self.result(), self.arg.result_as(self.ctype())))
+ if self.type.is_pyobject:
+ code.put_incref(self.py_result())
+
+
+class CloneNode(CoercionNode):
+ # This node is employed when the result of another node needs
+ # to be used multiple times. The argument node's result must
+ # be in a temporary. This node "borrows" the result from the
+ # argument node, and does not generate any evaluation or
+ # disposal code for it. The original owner of the argument
+ # node is responsible for doing those things.
+
+ subexprs = [] # Arg is not considered a subexpr
+
+ def __init__(self, arg):
+ CoercionNode.__init__(self, arg)
+ self.type = arg.type
+ self.result_ctype = arg.result_ctype
+
+ def calculate_result_code(self):
+ return self.arg.result()
+
+ def generate_evaluation_code(self, code):
+ pass
+
+ def generate_result_code(self, code):
+ pass
+
+#------------------------------------------------------------------------------------
+#
+# Runtime support code
+#
+#------------------------------------------------------------------------------------
+
+get_name_utility_code = [
+"""
+static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/
+""","""
+static PyObject *__Pyx_GetName(PyObject *dict, char *name) {
+ PyObject *result;
+ result = PyObject_GetAttrString(dict, name);
+ if (!result)
+ PyErr_SetString(PyExc_NameError, name);
+ return result;
+}
+"""]
+
+get_name_interned_utility_code = [
+"""
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
+""","""
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
+ PyObject *result;
+ result = PyObject_GetAttr(dict, name);
+ if (!result)
+ PyErr_SetObject(PyExc_NameError, name);
+ return result;
+}
+"""]
+
+#------------------------------------------------------------------------------------
+
+import_utility_code = [
+"""
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
+""","""
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) {
+ PyObject *__import__ = 0;
+ PyObject *empty_list = 0;
+ PyObject *module = 0;
+ PyObject *global_dict = 0;
+ PyObject *empty_dict = 0;
+ PyObject *list;
+ __import__ = PyObject_GetAttrString(%(BUILTINS)s, "__import__");
+ if (!__import__)
+ goto bad;
+ if (from_list)
+ list = from_list;
+ else {
+ empty_list = PyList_New(0);
+ if (!empty_list)
+ goto bad;
+ list = empty_list;
+ }
+ global_dict = PyModule_GetDict(%(GLOBALS)s);
+ if (!global_dict)
+ goto bad;
+ empty_dict = PyDict_New();
+ if (!empty_dict)
+ goto bad;
+ module = PyObject_CallFunction(__import__, "OOOO",
+ name, global_dict, empty_dict, list);
+bad:
+ Py_XDECREF(empty_list);
+ Py_XDECREF(__import__);
+ Py_XDECREF(empty_dict);
+ return module;
+}
+""" % {
+ "BUILTINS": Naming.builtins_cname,
+ "GLOBALS": Naming.module_cname,
+}]
+
+#------------------------------------------------------------------------------------
+#
+#get_exception_utility_code = [
+#"""
+#static PyObject *__Pyx_GetExcValue(void); /*proto*/
+#""","""
+#static PyObject *__Pyx_GetExcValue(void) {
+# PyObject *type = 0, *value = 0, *tb = 0;
+# PyObject *result = 0;
+# PyThreadState *tstate = PyThreadState_Get();
+# PyErr_Fetch(&type, &value, &tb);
+# PyErr_NormalizeException(&type, &value, &tb);
+# if (PyErr_Occurred())
+# goto bad;
+# if (!value) {
+# value = Py_None;
+# Py_INCREF(value);
+# }
+# Py_XDECREF(tstate->exc_type);
+# Py_XDECREF(tstate->exc_value);
+# Py_XDECREF(tstate->exc_traceback);
+# tstate->exc_type = type;
+# tstate->exc_value = value;
+# tstate->exc_traceback = tb;
+# result = value;
+# Py_XINCREF(result);
+# type = 0;
+# value = 0;
+# tb = 0;
+#bad:
+# Py_XDECREF(type);
+# Py_XDECREF(value);
+# Py_XDECREF(tb);
+# return result;
+#}
+#"""]
+#
+#------------------------------------------------------------------------------------
+
+unpacking_utility_code = [
+"""
+static PyObject *__Pyx_UnpackItem(PyObject *); /*proto*/
+static int __Pyx_EndUnpack(PyObject *); /*proto*/
+""","""
+static void __Pyx_UnpackError(void) {
+ PyErr_SetString(PyExc_ValueError, "unpack sequence of wrong size");
+}
+
+static PyObject *__Pyx_UnpackItem(PyObject *iter) {
+ PyObject *item;
+ if (!(item = PyIter_Next(iter))) {
+ if (!PyErr_Occurred())
+ __Pyx_UnpackError();
+ }
+ return item;
+}
+
+static int __Pyx_EndUnpack(PyObject *iter) {
+ PyObject *item;
+ if ((item = PyIter_Next(iter))) {
+ Py_DECREF(item);
+ __Pyx_UnpackError();
+ return -1;
+ }
+ else if (!PyErr_Occurred())
+ return 0;
+ else
+ return -1;
+}
+"""]
+
+#------------------------------------------------------------------------------------
+
+type_test_utility_code = [
+"""
+static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
+""","""
+static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
+ if (!type) {
+ PyErr_Format(PyExc_SystemError, "Missing type object");
+ return 0;
+ }
+ if (obj == Py_None || PyObject_TypeCheck(obj, type))
+ return 1;
+ PyErr_Format(PyExc_TypeError, "Cannot convert %s to %s",
+ obj->ob_type->tp_name, type->tp_name);
+ return 0;
+}
+"""]
+
+#------------------------------------------------------------------------------------
+
+create_class_utility_code = [
+"""
+static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, char *modname); /*proto*/
+""","""
+static PyObject *__Pyx_CreateClass(
+ PyObject *bases, PyObject *dict, PyObject *name, char *modname)
+{
+ PyObject *py_modname;
+ PyObject *result = 0;
+
+ py_modname = PyString_FromString(modname);
+ if (!py_modname)
+ goto bad;
+ if (PyDict_SetItemString(dict, "__module__", py_modname) < 0)
+ goto bad;
+ result = PyClass_New(bases, dict, name);
+bad:
+ Py_XDECREF(py_modname);
+ return result;
+}
+"""]
+
+#------------------------------------------------------------------------------------
+
+getitem_int_utility_code = [
+"""
+static PyObject *__Pyx_GetItemInt(PyObject *o, Py_ssize_t i); /*proto*/
+""","""
+static PyObject *__Pyx_GetItemInt(PyObject *o, Py_ssize_t i) {
+ PyTypeObject *t = o->ob_type;
+ PyObject *r;
+ if (t->tp_as_sequence && t->tp_as_sequence->sq_item)
+ r = PySequence_GetItem(o, i);
+ else {
+ PyObject *j = PyInt_FromLong(i);
+ if (!j)
+ return 0;
+ r = PyObject_GetItem(o, j);
+ Py_DECREF(j);
+ }
+ return r;
+}
+"""]
+
+#------------------------------------------------------------------------------------
+
+setitem_int_utility_code = [
+"""
+static int __Pyx_SetItemInt(PyObject *o, Py_ssize_t i, PyObject *v); /*proto*/
+""","""
+static int __Pyx_SetItemInt(PyObject *o, Py_ssize_t i, PyObject *v) {
+ PyTypeObject *t = o->ob_type;
+ int r;
+ if (t->tp_as_sequence && t->tp_as_sequence->sq_item)
+ r = PySequence_SetItem(o, i, v);
+ else {
+ PyObject *j = PyInt_FromLong(i);
+ if (!j)
+ return -1;
+ r = PyObject_SetItem(o, j, v);
+ Py_DECREF(j);
+ }
+ return r;
+}
+"""]
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Filenames.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Filenames.py
new file mode 100644
index 00000000..09092e28
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Filenames.py
@@ -0,0 +1,9 @@
+#
+# Pyrex - Filename suffixes
+#
+
+cplus_suffix = ".cpp"
+pxd_suffixes = (".pxd",)
+pyx_suffixes = (".pyx", ".pyx+")
+package_init_files = ("__init__.py", "__init__.pyx", "__init__.pyx+")
+pyx_to_c_suffix = {".pyx": ".c", ".pyx+": cplus_suffix}
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Lexicon.pickle b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Lexicon.pickle
new file mode 100644
index 00000000..1631a72c
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Lexicon.pickle
Binary files differ
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Lexicon.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Lexicon.py
new file mode 100644
index 00000000..ca303c0d
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Lexicon.py
@@ -0,0 +1,145 @@
+#
+# Pyrex Scanner - Lexical Definitions
+#
+# Changing anything in this file will cause Lexicon.pickle
+# to be rebuilt next time pyrexc is run.
+#
+
+string_prefixes = "cCrR"
+
+def make_lexicon():
+ from Pyrex.Plex import \
+ Str, Any, AnyBut, AnyChar, Rep, Rep1, Opt, Bol, Eol, Eof, \
+ TEXT, IGNORE, State, Lexicon
+ from Scanning import Method
+
+ letter = Any("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_")
+ digit = Any("0123456789")
+ octdigit = Any("01234567")
+ hexdigit = Any("0123456789ABCDEFabcdef")
+ indentation = Bol + Rep(Any(" \t"))
+
+ decimal = Rep1(digit)
+ dot = Str(".")
+ exponent = Any("Ee") + Opt(Any("+-")) + decimal
+ decimal_fract = (decimal + dot + Opt(decimal)) | (dot + decimal)
+
+ name = letter + Rep(letter | digit)
+ intconst = decimal | (Str("0x") + Rep1(hexdigit))
+ longconst = intconst + Str("L")
+ fltconst = (decimal_fract + Opt(exponent)) | (decimal + exponent)
+ imagconst = (intconst | fltconst) + Any("jJ")
+
+# sq_string = (
+# Str("'") +
+# Rep(AnyBut("\\\n'") | (Str("\\") + AnyChar)) +
+# Str("'")
+# )
+#
+# dq_string = (
+# Str('"') +
+# Rep(AnyBut('\\\n"') | (Str("\\") + AnyChar)) +
+# Str('"')
+# )
+#
+# non_sq = AnyBut("'") | (Str('\\') + AnyChar)
+# tsq_string = (
+# Str("'''")
+# + Rep(non_sq | (Str("'") + non_sq) | (Str("''") + non_sq))
+# + Str("'''")
+# )
+#
+# non_dq = AnyBut('"') | (Str('\\') + AnyChar)
+# tdq_string = (
+# Str('"""')
+# + Rep(non_dq | (Str('"') + non_dq) | (Str('""') + non_dq))
+# + Str('"""')
+# )
+#
+# stringlit = Opt(Any(string_prefixes)) + (sq_string | dq_string | tsq_string| tdq_string)
+
+ beginstring = Opt(Any(string_prefixes)) + (Str("'") | Str('"') | Str("'''") | Str('"""'))
+ two_oct = octdigit + octdigit
+ three_oct = octdigit + octdigit + octdigit
+ two_hex = hexdigit + hexdigit
+ escapeseq = Str("\\") + (two_oct | three_oct | two_hex | AnyChar)
+
+ bra = Any("([{")
+ ket = Any(")]}")
+ punct = Any(":,;+-*/|&<>=.%`~^?")
+ diphthong = Str("==", "<>", "!=", "<=", ">=", "<<", ">>", "**",
+ "+=", "-=", "*=", "/=", "%=", "**=", "<<=", ">>=", "&=", "^=", "|=")
+ spaces = Rep1(Any(" \t\f"))
+ comment = Str("#") + Rep(AnyBut("\n"))
+ escaped_newline = Str("\\\n")
+ lineterm = Eol + Opt(Str("\n"))
+
+ return Lexicon([
+ (name, 'IDENT'),
+ (intconst, 'INT'),
+ (longconst, 'LONG'),
+ (fltconst, 'FLOAT'),
+ (imagconst, 'IMAG'),
+ (punct | diphthong, TEXT),
+
+ (bra, Method('open_bracket_action')),
+ (ket, Method('close_bracket_action')),
+ (lineterm, Method('newline_action')),
+
+ #(stringlit, 'STRING'),
+ (beginstring, Method('begin_string_action')),
+
+ (comment, IGNORE),
+ (spaces, IGNORE),
+ (escaped_newline, IGNORE),
+
+ State('INDENT', [
+ (Opt(spaces) + Opt(comment) + lineterm, IGNORE),
+ (indentation, Method('indentation_action')),
+ (Eof, Method('eof_action'))
+ ]),
+
+ State('SQ_STRING', [
+ (escapeseq, 'ESCAPE'),
+ (Rep1(AnyBut("'\"\n\\")), 'CHARS'),
+ (Str('"'), 'CHARS'),
+ (Str("\n"), Method('unclosed_string_action')),
+ (Str("'"), Method('end_string_action')),
+ (Eof, 'EOF')
+ ]),
+
+ State('DQ_STRING', [
+ (escapeseq, 'ESCAPE'),
+ (Rep1(AnyBut('"\n\\')), 'CHARS'),
+ (Str("'"), 'CHARS'),
+ (Str("\n"), Method('unclosed_string_action')),
+ (Str('"'), Method('end_string_action')),
+ (Eof, 'EOF')
+ ]),
+
+ State('TSQ_STRING', [
+ (escapeseq, 'ESCAPE'),
+ (Rep1(AnyBut("'\"\n\\")), 'CHARS'),
+ (Any("'\""), 'CHARS'),
+ (Str("\n"), 'NEWLINE'),
+ (Str("'''"), Method('end_string_action')),
+ (Eof, 'EOF')
+ ]),
+
+ State('TDQ_STRING', [
+ (escapeseq, 'ESCAPE'),
+ (Rep1(AnyBut('"\'\n\\')), 'CHARS'),
+ (Any("'\""), 'CHARS'),
+ (Str("\n"), 'NEWLINE'),
+ (Str('"""'), Method('end_string_action')),
+ (Eof, 'EOF')
+ ]),
+
+ (Eof, Method('eof_action'))
+ ],
+
+ # FIXME: Plex 1.9 needs different args here from Plex 1.1.4
+ #debug_flags = scanner_debug_flags,
+ #debug_file = scanner_dump_file
+ )
+
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Main.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Main.py
new file mode 100644
index 00000000..2769b771
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Main.py
@@ -0,0 +1,564 @@
+#
+# Pyrex Top Level
+#
+
+import os, re, sys
+if sys.version_info[:2] < (2, 3):
+ print >>sys.stderr, "Sorry, Pyrex requires Python 2.3 or later"
+ sys.exit(1)
+
+import os
+from time import time
+import Builtin
+import Code
+import Errors
+import Parsing
+import Version
+from Errors import PyrexError, CompileError, error
+from Scanning import PyrexScanner
+from Symtab import BuiltinScope, DefinitionScope, ImplementationScope
+from Pyrex.Utils import set, replace_suffix, modification_time, \
+ file_newer_than, castrate_file, map_suffix
+from Filenames import cplus_suffix, pxd_suffixes, pyx_suffixes, \
+ package_init_files, pyx_to_c_suffix
+
+verbose = 0
+debug_timestamps = 0
+
+module_name_pattern = re.compile(
+ r"[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$")
+
+class Context:
+ # This class encapsulates the context needed for compiling
+ # one or more Pyrex implementation files along with their
+ # associated and imported declaration files. It holds
+ # the root of the module import namespace and the list
+ # of directories to search for include files.
+ #
+ # modules {string : DefinitionScope}
+ # include_directories [string]
+
+ def __init__(self, include_directories):
+ self.modules = {"__builtin__" : Builtin.builtin_scope}
+ self.include_directories = include_directories
+
+ def find_module(self, module_name,
+ relative_to = None, pos = None, need_pxd = 1):
+ # Finds and returns the module scope corresponding to
+ # the given relative or absolute module name. If this
+ # is the first time the module has been requested, finds
+ # the corresponding .pxd file and process it.
+ # If relative_to is not None, it must be a module scope,
+ # and the module will first be searched for relative to
+ # that module, provided its name is not a dotted name.
+ debug_find_module = 0
+ if debug_find_module:
+ print "Context.find_module: module_name =", module_name, \
+ "relative_to =", relative_to, "pos =", pos, "need_pxd =", need_pxd
+ scope = None
+ pxd_pathname = None
+ if "." not in module_name and relative_to:
+ if debug_find_module:
+ print "...trying relative import"
+ scope = relative_to.lookup_submodule(module_name)
+ if not scope:
+ qualified_name = relative_to.qualify_name(module_name)
+ pxd_pathname = self.find_pxd_file(qualified_name, pos)
+ if pxd_pathname:
+ scope = relative_to.find_submodule(module_name)
+ if not scope:
+ if debug_find_module:
+ print "...trying absolute import"
+ scope = self
+ for name in module_name.split("."):
+ scope = scope.find_submodule(name)
+ if debug_find_module:
+ print "...scope =", scope
+ if not scope.pxd_file_loaded:
+ if debug_find_module:
+ print "...pxd not loaded"
+ scope.pxd_file_loaded = 1
+ if not pxd_pathname:
+ if debug_find_module:
+ print "...looking for pxd file"
+ pxd_pathname = self.find_pxd_file(module_name, pos)
+ if debug_find_module:
+ print "......found ", pxd_pathname
+ if not pxd_pathname and need_pxd:
+ error(pos, "Cannot find .pxd file for module '%s'" % module_name)
+ if pxd_pathname:
+ try:
+ if debug_find_module:
+ print "Context.find_module: Parsing", pxd_pathname
+ pxd_tree = self.parse(pxd_pathname, scope, pxd = 1)
+ pxd_tree.analyse_declarations(scope)
+ except CompileError:
+ pass
+ return scope
+
+ def find_pxd_file(self, qualified_name, pos):
+ # Search include path for the .pxd file corresponding to the
+ # given fully-qualified module name.
+ # Will find either a dotted filename or a file in a
+ # package directory. If a source file position is given,
+ # the directory containing the source file is searched first
+ # for a dotted filename, and its containing package root
+ # directory is searched first for a non-dotted filename.
+ return self.search_package_directories(qualified_name, pxd_suffixes, pos)
+
+ def find_pyx_file(self, qualified_name, pos):
+ # Search include path for the .pyx file corresponding to the
+ # given fully-qualified module name, as for find_pxd_file().
+ return self.search_package_directories(qualified_name, pyx_suffixes, pos)
+
+ def search_package_directories(self, qualified_name, suffixes, pos):
+ dotted_filenames = [qualified_name + suffix for suffix in suffixes]
+ if pos:
+ here = os.path.dirname(pos[0])
+ for dotted_filename in dotted_filenames:
+ path = os.path.join(here, dotted_filename)
+ if os.path.exists(path):
+ return path
+ dirs = self.include_directories
+ if pos:
+ here = self.find_root_package_dir(pos[0])
+ dirs = [here] + dirs
+ names = qualified_name.split(".")
+ package_names = names[:-1]
+ module_name = names[-1]
+ filenames = [module_name + suffix for suffix in suffixes]
+ for root in dirs:
+ for dotted_filename in dotted_filenames:
+ path = os.path.join(root, dotted_filename)
+ if os.path.exists(path):
+ return path
+ dir = self.descend_to_package_dir(root, package_names)
+ if dir:
+ for filename in filenames:
+ path = os.path.join(dir, filename)
+ if os.path.exists(path):
+ return path
+ for init_filename in package_init_files:
+ path = os.path.join(dir, module_name, init_filename)
+ if os.path.exists(path):
+ return path
+
+ def find_root_package_dir(self, file_path):
+ # Given the full pathname of a source file, find the directory
+ # containing the top-level package that it ultimately belongs to.
+ dir = os.path.dirname(file_path)
+ while 1:
+ if not self.is_package_dir(dir):
+ return dir
+ parent = os.path.dirname(dir)
+ if parent == dir:
+ return dir
+ dir = parent
+
+ def descend_to_package_dir(self, root_dir, package_names):
+ # Starting from the given root directory, look for a nested
+ # succession of package directories. Returns the full pathname
+ # of the innermost one, or None.
+ dir = root_dir
+ for name in package_names:
+ dir = os.path.join(dir, name)
+ if self.is_package_dir(dir):
+ return dir
+
+ def is_package_dir(self, dir_path):
+ # Return true if the given directory is a package directory.
+ for filename in package_init_files:
+ path = os.path.join(dir_path, filename)
+ if os.path.exists(path):
+ return 1
+
+ def find_include_file(self, filename, pos):
+ # Search list of include directories for filename.
+ # Reports an error and returns None if not found.
+ path = self.search_include_directories(filename, pos)
+ if not path:
+ error(pos, "'%s' not found" % filename)
+ return path
+
+ def search_include_directories(self, filename, pos):
+ # Search the list of include directories for the given
+ # file name. If a source file position is given, first
+ # searches the directory containing that file. Returns
+ # None if not found, but does not report an error.
+ dirs = self.include_directories
+ if pos:
+ here_dir = os.path.dirname(pos[0])
+ dirs = [here_dir] + dirs
+ for dir in dirs:
+ path = os.path.join(dir, filename)
+ if os.path.exists(path):
+ return path
+ return None
+
+ def lookup_submodule(self, name):
+ # Look up a top-level module. Returns None if not found.
+ return self.modules.get(name, None)
+
+ def find_submodule(self, name):
+ # Find a top-level module, creating a new one if needed.
+ scope = self.lookup_submodule(name)
+ if not scope:
+ scope = DefinitionScope(name,
+ parent_module = None, context = self)
+ self.modules[name] = scope
+ return scope
+
+ def parse(self, source_filename, scope, pxd):
+ # Parse the given source file and return a parse tree.
+ f = open(source_filename, "rU")
+ s = PyrexScanner(f, source_filename, scope = scope, context = self)
+ try:
+ tree = Parsing.p_module(s, pxd)
+ finally:
+ f.close()
+ if Errors.num_errors > 0:
+ raise CompileError
+ return tree
+
+ def extract_module_name(self, path):
+ # Find fully_qualified module name from the full pathname
+ # of a source file.
+ dir, filename = os.path.split(path)
+ module_name, _ = os.path.splitext(filename)
+ if "." not in module_name:
+ if module_name == "__init__":
+ dir, module_name = os.path.split(dir)
+ names = [module_name]
+ while self.is_package_dir(dir):
+ parent, package_name = os.path.split(dir)
+ if parent == dir:
+ break
+ names.insert(0, package_name)
+ dir = parent
+ module_name = ".".join(names)
+ if not module_name_pattern.match(module_name):
+ raise CompileError((path, 0, 0),
+ "'%s' is not a valid module name" % module_name)
+ return module_name
+
+ def dep_file_out_of_date(self, source_path):
+ dep_path = replace_suffix(source_path, ".dep")
+ if not os.path.exists(dep_path):
+ return 1
+ dep_time = modification_time(dep_path)
+ return file_newer_than(source_path, dep_time)
+
+ def c_file_out_of_date(self, source_path):
+ if debug_timestamps:
+ print "Checking whether", source_path, "is out of date"
+ c_path = map_suffix(source_path, pyx_to_c_suffix, ".c")
+ if not os.path.exists(c_path):
+ if debug_timestamps:
+ print "...yes, c file doesn't exist"
+ return 1
+ c_time = modification_time(c_path)
+ if file_newer_than(source_path, c_time):
+ if debug_timestamps:
+ print "...yes, newer than c file"
+ return 1
+ pos = [source_path]
+ module_name = self.extract_module_name(source_path)
+ pxd_path = self.find_pxd_file(module_name, pos)
+ if pxd_path and file_newer_than(pxd_path, c_time):
+ if debug_timestamps:
+ print "...yes, pxd file newer than c file"
+ return 1
+ dep_path = replace_suffix(source_path, ".dep")
+ if not os.path.exists(dep_path):
+ if debug_timestamps:
+ print "...yes, dep file does not exist"
+ return 1
+ for kind, name in self.read_dependency_file(source_path):
+ if kind == "cimport":
+ dep_path = self.find_pxd_file(name, pos)
+ elif kind == "include":
+ dep_path = self.search_include_directories(name, pos)
+ else:
+ continue
+ if dep_path and file_newer_than(dep_path, c_time):
+ if debug_timestamps:
+ print "...yes,", dep_path, "newer than c file"
+ return 1
+ if debug_timestamps:
+ print "...no"
+
+ def find_cimported_module_names(self, source_path):
+ for kind, name in self.read_dependency_file(source_path):
+ if kind == "cimport":
+ yield name
+
+ def read_dependency_file(self, source_path):
+ dep_path = replace_suffix(source_path, ".dep")
+ if os.path.exists(dep_path):
+ f = open(dep_path, "rU")
+ for line in f.readlines():
+ chunks = line.strip().split(" ", 1)
+ if len(chunks) == 2:
+ yield chunks
+ f.close()
+
+ def compile(self, source, options = None):
+ # Compile a Pyrex implementation file in this context
+ # and return a CompilationResult.
+ if not options:
+ options = default_options
+ result = CompilationResult()
+ cwd = os.getcwd()
+ source = os.path.join(cwd, source)
+ if options.use_listing_file:
+ result.listing_file = replace_suffix(source, ".lis")
+ Errors.open_listing_file(result.listing_file,
+ echo_to_stderr = options.errors_to_stderr)
+ else:
+ Errors.open_listing_file(None)
+ if options.output_file:
+ result.c_file = os.path.join(cwd, options.output_file)
+ else:
+ if options.cplus:
+ result.c_file = replace_suffix(source, cplus_suffix)
+ else:
+ result.c_file = map_suffix(source, pyx_to_c_suffix, ".c")
+ module_name = self.extract_module_name(source)
+ initial_pos = (source, 1, 0)
+ def_scope = self.find_module(module_name, pos = initial_pos, need_pxd = 0)
+ imp_scope = ImplementationScope(def_scope)
+ errors_occurred = False
+ try:
+ tree = self.parse(source, imp_scope, pxd = 0)
+ tree.process_implementation(imp_scope, options, result)
+ except CompileError:
+ errors_occurred = True
+ Errors.close_listing_file()
+ result.num_errors = Errors.num_errors
+ if result.num_errors > 0:
+ errors_occurred = True
+ if errors_occurred and result.c_file:
+ try:
+ st = os.stat(source)
+ castrate_file(result.c_file, st)
+ except EnvironmentError:
+ pass
+ result.c_file = None
+ if result.c_file and not options.c_only and c_compile:
+ result.object_file = c_compile(result.c_file,
+ verbose_flag = options.show_version,
+ cplus = options.cplus)
+ if not options.obj_only and c_link:
+ result.extension_file = c_link(result.object_file,
+ extra_objects = options.objects,
+ verbose_flag = options.show_version,
+ cplus = options.cplus)
+ return result
+
+#------------------------------------------------------------------------
+#
+# Main Python entry points
+#
+#------------------------------------------------------------------------
+
+class CompilationOptions:
+ """
+ Options to the Pyrex compiler:
+
+ show_version boolean Display version number
+ use_listing_file boolean Generate a .lis file
+ errors_to_stderr boolean Echo errors to stderr when using .lis
+ include_path [string] Directories to search for include files
+ output_file string Name of generated .c file
+ generate_pxi boolean Generate .pxi file for public declarations
+ recursive boolean Recursively find and compile dependencies
+ timestamps boolean Only compile changed source files. If None,
+ defaults to true when recursive is true.
+ verbose boolean Always print source names being compiled
+ quiet boolean Don't print source names in recursive mode
+
+ Following options are experimental and only used on MacOSX:
+
+ c_only boolean Stop after generating C file (default)
+ obj_only boolean Stop after compiling to .o file
+ objects [string] Extra .o files to link with
+ cplus boolean Compile as c++ code
+ """
+
+ def __init__(self, defaults = None, c_compile = 0, c_link = 0, **kw):
+ self.include_path = []
+ self.objects = []
+ if defaults:
+ if isinstance(defaults, CompilationOptions):
+ defaults = defaults.__dict__
+ else:
+ defaults = default_options
+ self.__dict__.update(defaults)
+ self.__dict__.update(kw)
+ if c_compile:
+ self.c_only = 0
+ if c_link:
+ self.obj_only = 0
+
+
+class CompilationResult:
+ """
+ Results from the Pyrex compiler:
+
+ c_file string or None The generated C source file
+ h_file string or None The generated C header file
+ i_file string or None The generated .pxi file
+ api_file string or None The generated C API .h file
+ listing_file string or None File of error messages
+ object_file string or None Result of compiling the C file
+ extension_file string or None Result of linking the object file
+ num_errors integer Number of compilation errors
+ """
+
+ def __init__(self):
+ self.c_file = None
+ self.h_file = None
+ self.i_file = None
+ self.api_file = None
+ self.listing_file = None
+ self.object_file = None
+ self.extension_file = None
+
+
+class CompilationResultSet(dict):
+ """
+ Results from compiling multiple Pyrex source files. A mapping
+ from source file paths to CompilationResult instances. Also
+ has the following attributes:
+
+ num_errors integer Total number of compilation errors
+ """
+
+ num_errors = 0
+
+ def add(self, source, result):
+ self[source] = result
+ self.num_errors += result.num_errors
+
+
+def compile_single(source, options):
+ """
+ compile_single(source, options)
+
+ Compile the given Pyrex implementation file and return a CompilationResult.
+ Always compiles a single file; does not perform timestamp checking or
+ recursion.
+ """
+ context = Context(options.include_path)
+ return context.compile(source, options)
+
+def compile_multiple(sources, options):
+ """
+ compile_multiple(sources, options)
+
+ Compiles the given sequence of Pyrex implementation files and returns
+ a CompilationResultSet. Performs timestamp checking and/or recursion
+ if these are specified in the options.
+ """
+ sources = [os.path.abspath(source) for source in sources]
+ processed = set()
+ results = CompilationResultSet()
+ context = Context(options.include_path)
+ recursive = options.recursive
+ timestamps = options.timestamps
+ if timestamps is None:
+ timestamps = recursive
+ verbose = options.verbose or ((recursive or timestamps) and not options.quiet)
+ for source in sources:
+ if source not in processed:
+ if not timestamps or context.c_file_out_of_date(source):
+ if verbose:
+ print >>sys.stderr, "Compiling", source
+ result = context.compile(source, options)
+ results.add(source, result)
+ processed.add(source)
+ if recursive:
+ for module_name in context.find_cimported_module_names(source):
+ path = context.find_pyx_file(module_name, [source])
+ if path:
+ sources.append(path)
+ else:
+ print >>sys.stderr, \
+ "Cannot find .pyx file for cimported module '%s'" % module_name
+ return results
+
+def compile(source, options = None, c_compile = 0, c_link = 0, **kwds):
+ """
+ compile(source [, options], [, <option> = <value>]...)
+
+ Compile one or more Pyrex implementation files, with optional timestamp
+ checking and recursing on dependecies. The source argument may be a string
+ or a sequence of strings. If it is a string and no recursion or timestamp
+ checking is requested, a CompilationResult is returned, otherwise a
+ CompilationResultSet is returned.
+ """
+ options = CompilationOptions(defaults = options, c_compile = c_compile,
+ c_link = c_link, **kwds)
+ if isinstance(source, basestring) and not options.timestamps \
+ and not options.recursive:
+ return compile_single(source, options)
+ else:
+ return compile_multiple(source, options)
+
+#------------------------------------------------------------------------
+#
+# Main command-line entry point
+#
+#------------------------------------------------------------------------
+
+def main(command_line = 0):
+ args = sys.argv[1:]
+ any_failures = 0
+ if command_line:
+ from CmdLine import parse_command_line
+ options, sources = parse_command_line(args)
+ else:
+ options = CompilationOptions(default_options)
+ sources = args
+ if options.show_version:
+ print >>sys.stderr, "Pyrex version %s" % Version.version
+ try:
+ result = compile(sources, options)
+ if result.num_errors > 0:
+ any_failures = 1
+ except EnvironmentError, e:
+ print >>sys.stderr, e
+ any_failures = 1
+ if any_failures:
+ sys.exit(1)
+
+#------------------------------------------------------------------------
+#
+# Set the default options depending on the platform
+#
+#------------------------------------------------------------------------
+
+default_options = dict(
+ show_version = 0,
+ use_listing_file = 0,
+ errors_to_stderr = 1,
+ c_only = 1,
+ obj_only = 1,
+ cplus = 0,
+ output_file = None,
+ generate_pxi = 0,
+ recursive = 0,
+ timestamps = None,
+ verbose = 0,
+ quiet = 0)
+
+if sys.platform == "mac":
+ from Pyrex.Mac.MacSystem import c_compile, c_link, CCompilerError
+ default_options['use_listing_file'] = 1
+elif sys.platform == "darwin":
+ from Pyrex.Mac.DarwinSystem import c_compile, c_link, CCompilerError
+else:
+ c_compile = None
+ c_link = None
+
+
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/ModuleNode.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/ModuleNode.py
new file mode 100644
index 00000000..9c2b0a31
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/ModuleNode.py
@@ -0,0 +1,1678 @@
+#
+# Pyrex - Module parse tree node
+#
+
+import os, time
+from cStringIO import StringIO
+from PyrexTypes import CPtrType, py_object_type, typecast
+from Pyrex.Utils import set
+
+# Following is set by Testing.py to suppress filename/date comments
+# in generated files, so as not to produce spurious changes in test
+# reference files.
+
+testing_mode = False
+
+
+import Code
+import Naming
+import Nodes
+import Options
+import PyrexTypes
+import TypeSlots
+import Version
+
+from Errors import error
+from PyrexTypes import py_object_type
+from Pyrex.Utils import open_new_file, replace_suffix
+
+class ModuleNode(Nodes.Node, Nodes.BlockNode):
+ # doc string or None
+ # body StatListNode
+ #
+ # referenced_modules [ModuleScope]
+ # module_temp_cname string
+
+ def analyse_declarations(self, env):
+ env.doc = self.doc
+ self.body.analyse_declarations(env)
+
+ def process_implementation(self, env, options, result):
+ self.analyse_declarations(env)
+ env.check_c_classes()
+ self.body.analyse_expressions(env)
+ env.return_type = PyrexTypes.c_void_type
+ self.referenced_modules = self.find_referenced_modules(env)
+ if self.has_imported_c_functions():
+ self.module_temp_cname = env.allocate_temp_pyobject()
+ env.release_temp(self.module_temp_cname)
+ if options.timestamps or options.recursive:
+ self.generate_dep_file(env, result)
+ self.generate_c_code(env, result)
+ self.generate_h_code(env, options, result)
+ self.generate_api_code(env, result)
+
+ def has_imported_c_functions(self):
+ for module in self.referenced_modules:
+ for entry in module.cfunc_entries:
+ if entry.defined_in_pxd:
+ return 1
+ return 0
+
+ def generate_dep_file(self, env, result):
+ modules = self.referenced_modules
+ includes = set(env.pyrex_include_files)
+ for module in modules:
+ for include in module.pyrex_include_files:
+ includes.add(include)
+ if len(modules) > 1 or includes:
+ include_list = list(includes)
+ include_list.sort()
+ dep_file = replace_suffix(result.c_file, ".dep")
+ f = open(dep_file, "w")
+ try:
+ for module in modules[:-1]:
+ f.write("cimport %s\n" % module.qualified_name)
+ for path in include_list:
+ f.write("include %s\n" % path)
+ finally:
+ f.close()
+
+ def generate_h_code(self, env, options, result):
+ def pub(entries): #, pxd = 0):
+ return [entry for entry in entries
+ if entry.visibility == 'public'] # or pxd and entry.defined_in_pxd]
+ denv = env.definition_scope
+ h_types = pub(denv.type_entries) + pub(env.type_entries)
+ h_vars = pub(denv.var_entries) + pub(env.var_entries)
+ h_funcs = pub(denv.cfunc_entries) + pub(env.cfunc_entries)
+ h_extension_types = pub(denv.c_class_entries) + pub(env.c_class_entries)
+ if h_types or h_vars or h_funcs or h_extension_types:
+ result.h_file = replace_suffix(result.c_file, ".h")
+ h_code = Code.CCodeWriter(open_new_file(result.h_file))
+ if options.generate_pxi:
+ result.i_file = replace_suffix(result.c_file, ".pxi")
+ i_code = Code.PyrexCodeWriter(result.i_file)
+ else:
+ i_code = None
+ guard = Naming.h_guard_prefix + env.qualified_name.replace(".", "__")
+ h_code.put_h_guard(guard)
+ self.generate_extern_c_macro_definition(h_code)
+ self.generate_type_header_code(h_types, h_code)
+ h_code.putln("")
+ h_code.putln("#ifndef %s" % Naming.api_guard_prefix + self.api_name(env))
+ if h_vars:
+ h_code.putln("")
+ for entry in h_vars:
+ self.generate_public_declaration(entry, h_code, i_code)
+ if h_funcs:
+ h_code.putln("")
+ for entry in h_funcs:
+ self.generate_public_declaration(entry, h_code, i_code)
+ if h_extension_types:
+ h_code.putln("")
+ for entry in h_extension_types:
+ self.generate_cclass_header_code(entry.type, h_code)
+ if i_code:
+ self.generate_cclass_include_code(entry.type, i_code)
+ h_code.putln("")
+ h_code.putln("#endif")
+ h_code.putln("")
+ h_code.putln("PyMODINIT_FUNC init%s(void);" % env.module_name)
+ h_code.putln("")
+ h_code.putln("#endif")
+
+ def generate_public_declaration(self, entry, h_code, i_code):
+ h_code.putln("%s %s;" % (
+ Naming.extern_c_macro,
+ entry.type.declaration_code(
+ entry.cname, dll_linkage = "DL_IMPORT")))
+ if i_code:
+ i_code.putln("cdef extern %s" %
+ entry.type.declaration_code(entry.cname, pyrex = 1))
+
+ def api_name(self, env):
+ return env.qualified_name.replace(".", "__")
+
+ def generate_api_code(self, env, result):
+ denv = env.definition_scope
+ api_funcs = []
+ public_extension_types = []
+ has_api_extension_types = 0
+ for entry in denv.cfunc_entries:
+ if entry.api:
+ api_funcs.append(entry)
+ for entry in env.cfunc_entries:
+ if entry.api:
+ api_funcs.append(entry)
+ for entry in denv.c_class_entries + env.c_class_entries:
+ if entry.visibility == 'public':
+ public_extension_types.append(entry)
+ if entry.api:
+ has_api_extension_types = 1
+ if api_funcs or has_api_extension_types:
+ result.api_file = replace_suffix(result.c_file, "_api.h")
+ h_code = Code.CCodeWriter(open_new_file(result.api_file))
+ name = self.api_name(env)
+ guard = Naming.api_guard_prefix + name
+ h_code.put_h_guard(guard)
+ h_code.putln('#include "Python.h"')
+ if result.h_file:
+ h_code.putln('#include "%s"' % os.path.basename(result.h_file))
+ for entry in public_extension_types:
+ type = entry.type
+ h_code.putln("")
+ h_code.putln("static PyTypeObject *%s;" % type.typeptr_cname)
+ h_code.putln("#define %s (*%s)" % (
+ type.typeobj_cname, type.typeptr_cname))
+ if api_funcs:
+ h_code.putln("")
+ for entry in api_funcs:
+ type = CPtrType(entry.type)
+ h_code.putln("static %s;" % type.declaration_code(entry.cname))
+ h_code.putln("")
+ h_code.put_h_guard(Naming.api_func_guard + "import_module")
+ h_code.put(import_module_utility_code[1])
+ h_code.putln("")
+ h_code.putln("#endif")
+ if api_funcs:
+ h_code.putln("")
+ h_code.put(function_import_utility_code[1])
+ if public_extension_types:
+ h_code.putln("")
+ h_code.put(type_import_utility_code[1])
+ h_code.putln("")
+ h_code.putln("static int import_%s(void) {" % name)
+ h_code.putln("PyObject *module = 0;")
+ h_code.putln('module = __Pyx_ImportModule("%s");' % env.qualified_name)
+ h_code.putln("if (!module) goto bad;")
+ for entry in api_funcs:
+ sig = entry.type.signature_string()
+ h_code.putln(
+ 'if (__Pyx_ImportFunction(module, "%s", (void**)&%s, "%s") < 0) goto bad;' % (
+ entry.name,
+ entry.cname,
+ sig))
+ h_code.putln("Py_DECREF(module); module = 0;")
+ for entry in public_extension_types:
+ self.generate_type_import_call(entry.type, h_code, "goto bad;")
+ h_code.putln("return 0;")
+ h_code.putln("bad:")
+ h_code.putln("Py_XDECREF(module);")
+ h_code.putln("return -1;")
+ h_code.putln("}")
+ h_code.putln("")
+ h_code.putln("#endif")
+
+ def generate_cclass_header_code(self, type, h_code):
+ h_code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
+ Naming.extern_c_macro,
+ type.typeobj_cname))
+ #self.generate_obj_struct_definition(type, h_code)
+
+ def generate_cclass_include_code(self, type, i_code):
+ i_code.putln("cdef extern class %s.%s:" % (
+ type.module_name, type.name))
+ i_code.indent()
+ var_entries = type.scope.var_entries
+ if var_entries:
+ for entry in var_entries:
+ i_code.putln("cdef %s" %
+ entry.type.declaration_code(entry.cname, pyrex = 1))
+ else:
+ i_code.putln("pass")
+ i_code.dedent()
+
+ def generate_c_code(self, env, result):
+ code = Code.MainCCodeWriter(StringIO())
+ code.h = Code.CCodeWriter(StringIO())
+ code.init_labels()
+
+ modules = self.referenced_modules
+ self.generate_module_preamble(env, modules, code.h)
+
+ code.putln("")
+ code.putln("/* Implementation of %s */" % env.qualified_name)
+ #self.generate_const_definitions(env, code)
+ #self.generate_interned_name_decls(env, code)
+ #self.generate_py_string_decls(env, code)
+ self.body.generate_function_definitions(env, code)
+ #self.generate_interned_name_table(env, code)
+ #self.generate_py_string_table(env, code)
+ self.generate_typeobj_definitions(env, code)
+ self.generate_method_table(env, code)
+ self.generate_filename_init_prototype(code)
+ self.generate_module_init_func(modules[:-1], env, code)
+ self.generate_filename_table(code)
+ self.generate_utility_functions(code)
+
+ denv = env.definition_scope
+ for module in modules:
+ code.h.putln("")
+ code.h.putln("/* Declarations from %s */" % module.qualified_name)
+ self.generate_declarations_for_module(module, code.h,
+ implementation = module is denv)
+
+ code.h.putln("")
+ code.h.putln("/* Declarations from implementation of %s */" %
+ env.qualified_name)
+ self.generate_declarations_for_module(env, code.h, implementation = 1)
+ code.global_state.generate_const_declarations(code.h)
+ #self.generate_interned_name_table(code.interned_strings, code.h)
+ #self.generate_py_string_table(code.py_strings, code.h)
+ self.generate_default_value_declarations(env, code.h)
+
+ f = open_new_file(result.c_file)
+ f.write(code.h.f.getvalue())
+ f.write("\n")
+ f.write(code.f.getvalue())
+ f.close()
+ result.c_file_generated = 1
+
+ def find_referenced_modules(self, env):
+ # Given the ImplementationScope, find the DefinitionScopes of all
+ # modules cimported, directly or indirectly. Includes this module's
+ # DefinitionScope as the last entry in the list.
+ denv = env.definition_scope
+ module_list = []
+ modules_seen = set()
+ def add_module(module):
+ if module not in modules_seen:
+ modules_seen.add(module)
+ add_modules(module.cimported_modules)
+ module_list.append(module)
+ def add_modules(modules):
+ for module in modules:
+ add_module(module)
+ modules_seen.add(denv)
+ add_modules(denv.cimported_modules)
+ add_modules(env.cimported_modules)
+ module_list.append(denv)
+ #self.print_referenced_modules(module_list) ###
+ return module_list
+
+ def print_referenced_modules(self, module_list):
+ print "find_referenced_modules: result =",
+ for m in module_list:
+ print m,
+ print
+
+ def generate_module_preamble(self, env, cimported_modules, code):
+ comment = "Generated by Pyrex"
+ if not testing_mode:
+ comment = "%s %s on %s" % (comment, Version.version, time.asctime())
+ code.putln('/* %s */' % comment)
+ code.putln('')
+ code.putln('#define PY_SSIZE_T_CLEAN')
+ for filename in env.python_include_files:
+ code.putln('#include "%s"' % filename)
+ code.putln("#ifndef PY_LONG_LONG")
+ code.putln(" #define PY_LONG_LONG LONG_LONG")
+ code.putln("#endif")
+ code.putln("#if PY_VERSION_HEX < 0x02050000")
+ code.putln(" typedef int Py_ssize_t;")
+ code.putln(" #define PY_SSIZE_T_MAX INT_MAX")
+ code.putln(" #define PY_SSIZE_T_MIN INT_MIN")
+ code.putln(" #define PyInt_FromSsize_t(z) PyInt_FromLong(z)")
+ code.putln(" #define PyInt_AsSsize_t(o) PyInt_AsLong(o)")
+ code.putln("#endif")
+ code.putln("#if !defined(WIN32) && !defined(MS_WINDOWS)")
+ code.putln(" #ifndef __stdcall")
+ code.putln(" #define __stdcall")
+ code.putln(" #endif")
+ code.putln(" #ifndef __cdecl")
+ code.putln(" #define __cdecl")
+ code.putln(" #endif")
+ code.putln("#endif")
+ self.generate_extern_c_macro_definition(code)
+ code.putln("#include <math.h>")
+ self.generate_includes(env, cimported_modules, code)
+ code.putln('')
+ code.put(Nodes.utility_function_predeclarations)
+ code.putln('')
+ code.putln('static PyObject *%s;' % env.module_cname)
+ code.putln('static PyObject *%s;' % Naming.builtins_cname)
+ code.putln('static int %s;' % Naming.lineno_cname)
+ code.putln('static char *%s;' % Naming.filename_cname)
+ code.putln('static char **%s;' % Naming.filetable_cname)
+ doc = None
+ doc1 = env.definition_scope.doc
+ doc2 = env.doc
+ if doc1 and doc2:
+ doc = "%s\\n%s" % (doc1, doc2)
+ else:
+ doc = doc1 or doc2
+ if doc:
+ code.putln('')
+ code.putln('static char %s[] = "%s";' % (env.doc_cname, doc))
+
+ def generate_extern_c_macro_definition(self, code):
+ name = Naming.extern_c_macro
+ code.putln("#ifdef __cplusplus")
+ code.putln('#define %s extern "C"' % name)
+ code.putln("#else")
+ code.putln("#define %s extern" % name)
+ code.putln("#endif")
+
+ def generate_includes(self, env, cimported_modules, code):
+ includes = []
+ for module in cimported_modules + [env]:
+ for filename in module.include_files:
+ if filename not in includes:
+ includes.append(filename)
+ for filename in includes:
+ code.putln('#include "%s"' % filename)
+
+ def generate_filename_table(self, code):
+ code.global_state.generate_filename_table(code)
+
+ def generate_declarations_for_module(self, env, code, implementation):
+ self.generate_type_predeclarations(env, code)
+ self.generate_type_definitions(env, code) #, implementation)
+ self.generate_global_declarations(env, code, implementation)
+ self.generate_cfunction_predeclarations(env, code, implementation)
+
+ def generate_type_predeclarations(self, env, code):
+ pass
+
+ def generate_type_header_code(self, type_entries, code):
+ # Generate definitions of structs/unions/enums/typedefs/objstructs.
+ #self.generate_gcc33_hack(env, code) # Is this still needed?
+ #for entry in env.type_entries:
+ for entry in type_entries:
+ if not entry.in_cinclude:
+ #print "generate_type_header_code:", entry.name, repr(entry.type) ###
+ type = entry.type
+ if type.is_typedef: # Must test this first!
+ self.generate_typedef(entry, code)
+ elif type.is_struct_or_union:
+ self.generate_struct_union_definition(entry, code)
+ elif type.is_enum:
+ self.generate_enum_definition(entry, code)
+ elif type.is_extension_type:
+ self.generate_obj_struct_definition(type, code)
+
+ def generate_type_definitions(self, env, code): #, implementation):
+ #print "generate_type_definitions:", env ###
+ type_entries = env.type_entries
+ self.generate_type_header_code(type_entries, code)
+ for entry in env.c_class_entries:
+ if not entry.in_cinclude:
+ self.generate_typeobject_predeclaration(entry, code)
+ self.generate_exttype_vtable_struct(entry, code)
+ self.generate_exttype_vtabptr_declaration(entry, code)
+
+ def generate_typedef(self, entry, code):
+ base_type = entry.type.typedef_base_type
+ code.putln("")
+ code.putln("typedef %s;" % base_type.declaration_code(entry.cname))
+
+ def sue_header_footer(self, type, kind, name):
+ if type.typedef_flag:
+ header = "typedef %s {" % kind
+ footer = "} %s;" % name
+ else:
+ header = "%s %s {" % (kind, name)
+ footer = "};"
+ return header, footer
+
+ def generate_struct_union_definition(self, entry, code):
+ type = entry.type
+ scope = type.scope
+ if scope:
+ header, footer = \
+ self.sue_header_footer(type, type.kind, type.cname)
+ code.putln("")
+ code.putln(header)
+ var_entries = scope.var_entries
+ if not var_entries and not scope.cfunc_entries:
+ error(entry.pos,
+ "Empty struct or union definition not allowed outside a"
+ " 'cdef extern from' block")
+ for attr in var_entries:
+ code.putln(
+ "%s;" %
+ attr.type.declaration_code(attr.cname))
+ code.putln(footer)
+
+ def generate_enum_definition(self, entry, code):
+ type = entry.type
+ name = entry.cname or entry.name or ""
+ header, footer = \
+ self.sue_header_footer(type, "enum", name)
+ code.putln("")
+ code.putln(header)
+ enum_values = entry.enum_values
+ if not enum_values:
+ error(entry.pos,
+ "Empty enum definition not allowed outside a"
+ " 'cdef extern from' block")
+ else:
+ last_entry = enum_values[-1]
+ for value_entry in enum_values:
+ if value_entry.value == value_entry.name:
+ value_code = value_entry.cname
+ else:
+ value_code = ("%s = %s" % (
+ value_entry.cname,
+ value_entry.value))
+ if value_entry is not last_entry:
+ value_code += ","
+ code.putln(value_code)
+ code.putln(footer)
+
+ def generate_typeobject_predeclaration(self, entry, code):
+ code.putln("")
+ name = entry.type.typeobj_cname
+ if name:
+ if entry.visibility == 'extern' and not entry.in_cinclude:
+ code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
+ Naming.extern_c_macro,
+ name))
+ elif entry.visibility == 'public':
+ #code.putln("DL_EXPORT(PyTypeObject) %s;" % name)
+ code.putln("%s DL_EXPORT(PyTypeObject) %s;" % (
+ Naming.extern_c_macro,
+ name))
+
+ def generate_exttype_vtable_struct(self, entry, code):
+ # Generate struct declaration for an extension type's vtable.
+ type = entry.type
+ scope = type.scope
+ if type.vtabstruct_cname:
+ code.putln("")
+ code.putln(
+ "struct %s {" %
+ type.vtabstruct_cname)
+ if type.base_type and type.base_type.vtabstruct_cname:
+ code.putln("struct %s %s;" % (
+ type.base_type.vtabstruct_cname,
+ Naming.obj_base_cname))
+ for method_entry in scope.cfunc_entries:
+ if not method_entry.is_inherited:
+ code.putln(
+ "%s;" % method_entry.type.declaration_code("(*%s)" % method_entry.name))
+ code.putln(
+ "};")
+
+ def generate_exttype_vtabptr_declaration(self, entry, code):
+ # Generate declaration of pointer to an extension type's vtable.
+ type = entry.type
+ if type.vtabptr_cname:
+ code.putln("static struct %s *%s;" % (
+ type.vtabstruct_cname,
+ type.vtabptr_cname))
+
+ def generate_obj_struct_definition(self, type, code):
+ # Generate object struct definition for an
+ # extension type.
+ if not type.scope:
+ return # Forward declared but never defined
+ header, footer = \
+ self.sue_header_footer(type, "struct", type.objstruct_cname)
+ code.putln("")
+ code.putln(header)
+ base_type = type.base_type
+ if base_type:
+ code.putln(
+ "%s%s %s;" % (
+ ("struct ", "")[base_type.typedef_flag],
+ base_type.objstruct_cname,
+ Naming.obj_base_cname))
+ else:
+ code.putln(
+ "PyObject_HEAD")
+ if type.vtabslot_cname and not (type.base_type and type.base_type.vtabslot_cname):
+ code.putln(
+ "struct %s *%s;" % (
+ type.vtabstruct_cname,
+ type.vtabslot_cname))
+ for attr in type.scope.var_entries:
+ code.putln(
+ "%s;" %
+ attr.type.declaration_code(attr.cname))
+ code.putln(footer)
+
+ def generate_global_declarations(self, env, code, implementation):
+ code.putln("")
+ for entry in env.c_class_entries:
+ if implementation or entry.defined_in_pxd:
+ code.putln("static PyTypeObject *%s = 0;" %
+ entry.type.typeptr_cname)
+ #code.putln("/* var_entries */") ###
+ code.put_var_declarations(env.var_entries, static = 1,
+ dll_linkage = "DL_EXPORT", definition = implementation)
+
+ def generate_default_value_declarations(self, env, code):
+ #code.putln("/* default_entries */") ###
+ code.putln("")
+ code.put_var_declarations(env.default_entries, static = 1)
+
+ def generate_cfunction_predeclarations(self, env, code, implementation):
+ for entry in env.cfunc_entries:
+ if not entry.in_cinclude:
+ # and (definition or entry.defined_in_pxd or
+ # entry.visibility == 'extern'):
+ if entry.visibility in ('public', 'extern'):
+ dll_linkage = "DL_EXPORT"
+ else:
+ dll_linkage = None
+ type = entry.type
+ if not implementation: #and entry.defined_in_pxd:
+ type = CPtrType(type)
+ header = type.declaration_code(entry.cname,
+ dll_linkage = dll_linkage)
+ if entry.visibility <> 'private':
+ storage_class = "%s " % Naming.extern_c_macro
+ else:
+ storage_class = "static "
+ code.putln("%s%s; /*proto*/" % (
+ storage_class,
+ header))
+
+ def generate_typeobj_definitions(self, env, code):
+ full_module_name = env.qualified_name
+ denv = env.definition_scope
+ for entry in denv.c_class_entries + env.c_class_entries:
+ #print "generate_typeobj_definitions:", entry.name
+ #print "...visibility =", entry.visibility
+ if entry.visibility <> 'extern':
+ type = entry.type
+ scope = type.scope
+ if scope: # could be None if there was an error
+ self.generate_exttype_vtable(scope, code)
+ self.generate_new_function(scope, code)
+ self.generate_dealloc_function(scope, code)
+ self.generate_traverse_function(scope, code)
+ self.generate_clear_function(scope, code)
+ if scope.defines_any(["__getitem__"]):
+ self.generate_getitem_int_function(scope, code)
+ if scope.defines_any(["__setitem__", "__delitem__"]):
+ self.generate_ass_subscript_function(scope, code)
+ if scope.defines_any(["__setslice__", "__delslice__"]):
+ self.generate_ass_slice_function(scope, code)
+ if scope.defines_any(["__getattr__"]):
+ self.generate_getattro_function(scope, code)
+ if scope.defines_any(["__setattr__", "__delattr__"]):
+ self.generate_setattro_function(scope, code)
+ if scope.defines_any(["__get__"]):
+ self.generate_descr_get_function(scope, code)
+ if scope.defines_any(["__set__", "__delete__"]):
+ self.generate_descr_set_function(scope, code)
+ self.generate_property_accessors(scope, code)
+ self.generate_method_table(scope, code)
+ self.generate_member_table(scope, code)
+ self.generate_getset_table(scope, code)
+ self.generate_typeobj_definition(full_module_name, entry, code)
+
+ def generate_exttype_vtable(self, scope, code):
+ # Generate the definition of an extension type's vtable.
+ type = scope.parent_type
+ if type.vtable_cname:
+ code.putln("static struct %s %s;" % (
+ type.vtabstruct_cname,
+ type.vtable_cname))
+
+ def generate_self_cast(self, scope, code):
+ type = scope.parent_type
+ code.putln(
+ "%s = (%s)o;" % (
+ type.declaration_code("p"),
+ type.declaration_code("")))
+
+ def generate_new_function(self, scope, code):
+ type = scope.parent_type
+ base_type = type.base_type
+ py_attrs = []
+ for entry in scope.var_entries:
+ if entry.type.is_pyobject:
+ py_attrs.append(entry)
+ need_self_cast = type.vtabslot_cname or py_attrs
+ code.putln("")
+ code.putln(
+ "static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k) {"
+ % scope.mangle_internal("tp_new"))
+ if need_self_cast:
+ code.putln(
+ "%s;"
+ % scope.parent_type.declaration_code("p"))
+ if base_type:
+ code.putln(
+ "PyObject *o = %s->tp_new(t, a, k);" %
+ base_type.typeptr_cname)
+ else:
+ code.putln(
+ "PyObject *o = (*t->tp_alloc)(t, 0);")
+ code.putln(
+ "if (!o) return 0;")
+ if need_self_cast:
+ code.putln(
+ "p = %s;"
+ % type.cast_code("o"))
+ #if need_self_cast:
+ # self.generate_self_cast(scope, code)
+ if type.vtabslot_cname:
+ code.putln("*(struct %s **)&p->%s = %s;" % (
+ type.vtabstruct_cname,
+ type.vtabslot_cname,
+ type.vtabptr_cname))
+ for entry in py_attrs:
+ if entry.name == "__weakref__":
+ code.putln("p->%s = 0;" % entry.cname)
+ else:
+ code.put_init_var_to_py_none(entry, "p->%s")
+ entry = scope.lookup_here("__new__")
+ if entry:
+ code.putln(
+ "if (%s(o, a, k) < 0) {" %
+ entry.func_cname)
+ code.put_decref_clear("o", py_object_type);
+ code.putln(
+ "}")
+ code.putln(
+ "return o;")
+ code.putln(
+ "}")
+
+ def generate_dealloc_function(self, scope, code):
+ base_type = scope.parent_type.base_type
+ code.putln("")
+ code.putln(
+ "static void %s(PyObject *o) {"
+ % scope.mangle_internal("tp_dealloc"))
+ #py_attrs = []
+ #for entry in scope.var_entries:
+ # if entry.type.is_pyobject and entry.name <> "__weakref__":
+ # py_attrs.append(entry)
+ py_attrs = scope.pyattr_entries
+ if py_attrs:
+ self.generate_self_cast(scope, code)
+ self.generate_usr_dealloc_call(scope, code)
+ if scope.lookup_here("__weakref__"):
+ code.putln("PyObject_ClearWeakRefs(o);")
+ for entry in py_attrs:
+ code.put_xdecref("p->%s" % entry.cname, entry.type)
+ if base_type:
+ code.putln(
+ "%s->tp_dealloc(o);" %
+ base_type.typeptr_cname)
+ else:
+ code.putln(
+ "(*o->ob_type->tp_free)(o);")
+ code.putln(
+ "}")
+
+ def generate_usr_dealloc_call(self, scope, code):
+ entry = scope.lookup_here("__dealloc__")
+ if entry:
+ code.putln(
+ "{")
+ code.putln(
+ "PyObject *etype, *eval, *etb;")
+ code.putln(
+ "PyErr_Fetch(&etype, &eval, &etb);")
+ code.putln(
+ "++o->ob_refcnt;")
+ code.putln(
+ "%s(o);" %
+ entry.func_cname)
+ code.putln(
+ "if (PyErr_Occurred()) PyErr_WriteUnraisable(o);")
+ code.putln(
+ "--o->ob_refcnt;")
+ code.putln(
+ "PyErr_Restore(etype, eval, etb);")
+ code.putln(
+ "}")
+
+ def generate_traverse_function(self, scope, code):
+ py_attrs = scope.pyattr_entries
+ if py_attrs:
+ base_type = scope.parent_type.base_type
+ code.putln("")
+ code.putln(
+ "static int %s(PyObject *o, visitproc v, void *a) {"
+ % scope.mangle_internal("tp_traverse"))
+ code.putln(
+ "int e;")
+ self.generate_self_cast(scope, code)
+ if base_type:
+ code.putln(
+ "traverseproc t;")
+ code.putln(
+ "if ((t = %s->tp_traverse)) {" %
+ base_type.typeptr_cname)
+ code.putln(
+ "e = t(o, v, a); if (e) return e;")
+ code.putln(
+ "}")
+ for entry in py_attrs:
+ var_code = "p->%s" % entry.cname
+ code.putln(
+ "if (%s) {"
+ % var_code)
+ if entry.type.is_extension_type:
+ var_code = "((PyObject*)%s)" % var_code
+ code.putln(
+ "e = (*v)(%s, a); if (e) return e;"
+ % var_code)
+ code.putln(
+ "}")
+ code.putln(
+ "return 0;")
+ code.putln(
+ "}")
+
+ def generate_clear_function(self, scope, code):
+ py_attrs = scope.pyattr_entries
+ if py_attrs:
+ base_type = scope.parent_type.base_type
+ code.putln("")
+ code.putln(
+ "static int %s(PyObject *o) {"
+ % scope.mangle_internal("tp_clear"))
+ self.generate_self_cast(scope, code)
+ code.putln(
+ "PyObject *t;")
+ if base_type:
+ code.putln(
+ "inquiry c;")
+ code.putln(
+ "if ((c = %s->tp_clear)) {" %
+ base_type.typeptr_cname)
+ code.putln(
+ "c(o);")
+ code.putln(
+ "}")
+ for entry in py_attrs:
+ name = "p->%s" % entry.cname
+ code.putln(
+ "t = %s; " %
+ typecast(py_object_type, entry.type, name))
+ code.put_init_var_to_py_none(entry, "p->%s")
+ #code.put_xdecref(name, entry.type)
+ code.putln(
+ "Py_XDECREF(t);")
+ code.putln(
+ "return 0;")
+ code.putln(
+ "}")
+
+ def generate_getitem_int_function(self, scope, code):
+ # This function is put into the sq_item slot when
+ # a __getitem__ method is present. It converts its
+ # argument to a Python integer and calls mp_subscript.
+ code.putln(
+ "static PyObject *%s(PyObject *o, Py_ssize_t i) {" %
+ scope.mangle_internal("sq_item"))
+ code.putln(
+ "PyObject *r;")
+ code.putln(
+ "PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;")
+ code.putln(
+ "r = o->ob_type->tp_as_mapping->mp_subscript(o, x);")
+ code.putln(
+ "Py_DECREF(x);")
+ code.putln(
+ "return r;")
+ code.putln(
+ "}")
+
+ def generate_ass_subscript_function(self, scope, code):
+ # Setting and deleting an item are both done through
+ # the ass_subscript method, so we dispatch to user's __setitem__
+ # or __delitem__, or raise an exception.
+ base_type = scope.parent_type.base_type
+ set_entry = scope.lookup_here("__setitem__")
+ del_entry = scope.lookup_here("__delitem__")
+ code.putln("")
+ code.putln(
+ "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
+ scope.mangle_internal("mp_ass_subscript"))
+ code.putln(
+ "if (v) {")
+ if set_entry:
+ code.putln(
+ "return %s(o, i, v);" %
+ set_entry.func_cname)
+ else:
+ self.generate_guarded_basetype_call(
+ base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
+ code.putln(
+ "PyErr_Format(PyExc_NotImplementedError,")
+ code.putln(
+ ' "Subscript assignment not supported by %s", o->ob_type->tp_name);')
+ code.putln(
+ "return -1;")
+ code.putln(
+ "}")
+ code.putln(
+ "else {")
+ if del_entry:
+ code.putln(
+ "return %s(o, i);" %
+ del_entry.func_cname)
+ else:
+ self.generate_guarded_basetype_call(
+ base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
+ code.putln(
+ "PyErr_Format(PyExc_NotImplementedError,")
+ code.putln(
+ ' "Subscript deletion not supported by %s", o->ob_type->tp_name);')
+ code.putln(
+ "return -1;")
+ code.putln(
+ "}")
+ code.putln(
+ "}")
+
+ def generate_guarded_basetype_call(
+ self, base_type, substructure, slot, args, code):
+ if base_type:
+ base_tpname = base_type.typeptr_cname
+ if substructure:
+ code.putln(
+ "if (%s->%s && %s->%s->%s)" % (
+ base_tpname, substructure, base_tpname, substructure, slot))
+ code.putln(
+ " return %s->%s->%s(%s);" % (
+ base_tpname, substructure, slot, args))
+ else:
+ code.putln(
+ "if (%s->%s)" % (
+ base_tpname, slot))
+ code.putln(
+ " return %s->%s(%s);" % (
+ base_tpname, slot, args))
+
+ def generate_ass_slice_function(self, scope, code):
+ # Setting and deleting a slice are both done through
+ # the ass_slice method, so we dispatch to user's __setslice__
+ # or __delslice__, or raise an exception.
+ base_type = scope.parent_type.base_type
+ set_entry = scope.lookup_here("__setslice__")
+ del_entry = scope.lookup_here("__delslice__")
+ code.putln("")
+ code.putln(
+ "static int %s(PyObject *o, Py_ssize_t i, Py_ssize_t j, PyObject *v) {" %
+ scope.mangle_internal("sq_ass_slice"))
+ code.putln(
+ "if (v) {")
+ if set_entry:
+ code.putln(
+ "return %s(o, i, j, v);" %
+ set_entry.func_cname)
+ else:
+ self.generate_guarded_basetype_call(
+ base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
+ code.putln(
+ "PyErr_Format(PyExc_NotImplementedError,")
+ code.putln(
+ ' "2-element slice assignment not supported by %s", o->ob_type->tp_name);')
+ code.putln(
+ "return -1;")
+ code.putln(
+ "}")
+ code.putln(
+ "else {")
+ if del_entry:
+ code.putln(
+ "return %s(o, i, j);" %
+ del_entry.func_cname)
+ else:
+ self.generate_guarded_basetype_call(
+ base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
+ code.putln(
+ "PyErr_Format(PyExc_NotImplementedError,")
+ code.putln(
+ ' "2-element slice deletion not supported by %s", o->ob_type->tp_name);')
+ code.putln(
+ "return -1;")
+ code.putln(
+ "}")
+ code.putln(
+ "}")
+
+ def generate_getattro_function(self, scope, code):
+ # First try to get the attribute using PyObject_GenericGetAttr.
+ # If that raises an AttributeError, call the user's __getattr__
+ # method.
+ entry = scope.lookup_here("__getattr__")
+ code.putln("")
+ code.putln(
+ "static PyObject *%s(PyObject *o, PyObject *n) {"
+ % scope.mangle_internal("tp_getattro"))
+ code.putln(
+ "PyObject *v = PyObject_GenericGetAttr(o, n);")
+ code.putln(
+ "if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {")
+ code.putln(
+ "PyErr_Clear();")
+ code.putln(
+ "v = %s(o, n);" %
+ entry.func_cname)
+ code.putln(
+ "}")
+ code.putln(
+ "return v;")
+ code.putln(
+ "}")
+
+ def generate_setattro_function(self, scope, code):
+ # Setting and deleting an attribute are both done through
+ # the setattro method, so we dispatch to user's __setattr__
+ # or __delattr__ or fall back on PyObject_GenericSetAttr.
+ base_type = scope.parent_type.base_type
+ set_entry = scope.lookup_here("__setattr__")
+ del_entry = scope.lookup_here("__delattr__")
+ code.putln("")
+ code.putln(
+ "static int %s(PyObject *o, PyObject *n, PyObject *v) {" %
+ scope.mangle_internal("tp_setattro"))
+ code.putln(
+ "if (v) {")
+ if set_entry:
+ code.putln(
+ "return %s(o, n, v);" %
+ set_entry.func_cname)
+ else:
+ self.generate_guarded_basetype_call(
+ base_type, None, "tp_setattro", "o, n, v", code)
+ code.putln(
+ "return PyObject_GenericSetAttr(o, n, v);")
+ code.putln(
+ "}")
+ code.putln(
+ "else {")
+ if del_entry:
+ code.putln(
+ "return %s(o, n);" %
+ del_entry.func_cname)
+ else:
+ self.generate_guarded_basetype_call(
+ base_type, None, "tp_setattro", "o, n, v", code)
+ code.putln(
+ "return PyObject_GenericSetAttr(o, n, 0);")
+ code.putln(
+ "}")
+ code.putln(
+ "}")
+
+ def generate_descr_get_function(self, scope, code):
+ # The __get__ function of a descriptor object can be
+ # called with NULL for the second or third arguments
+ # under some circumstances, so we replace them with
+ # None in that case.
+ user_get_entry = scope.lookup_here("__get__")
+ code.putln("")
+ code.putln(
+ "static PyObject *%s(PyObject *o, PyObject *i, PyObject *c) {" %
+ scope.mangle_internal("tp_descr_get"))
+ code.putln(
+ "PyObject *r = 0;")
+ code.putln(
+ "if (!i) i = Py_None;")
+ code.putln(
+ "if (!c) c = Py_None;")
+ #code.put_incref("i", py_object_type)
+ #code.put_incref("c", py_object_type)
+ code.putln(
+ "r = %s(o, i, c);" %
+ user_get_entry.func_cname)
+ #code.put_decref("i", py_object_type)
+ #code.put_decref("c", py_object_type)
+ code.putln(
+ "return r;")
+ code.putln(
+ "}")
+
+ def generate_descr_set_function(self, scope, code):
+ # Setting and deleting are both done through the __set__
+ # method of a descriptor, so we dispatch to user's __set__
+ # or __delete__ or raise an exception.
+ base_type = scope.parent_type.base_type
+ user_set_entry = scope.lookup_here("__set__")
+ user_del_entry = scope.lookup_here("__delete__")
+ code.putln("")
+ code.putln(
+ "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
+ scope.mangle_internal("tp_descr_set"))
+ code.putln(
+ "if (v) {")
+ if user_set_entry:
+ code.putln(
+ "return %s(o, i, v);" %
+ user_set_entry.func_cname)
+ else:
+ self.generate_guarded_basetype_call(
+ base_type, None, "tp_descr_set", "o, i, v", code)
+ code.putln(
+ 'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
+ code.putln(
+ "return -1;")
+ code.putln(
+ "}")
+ code.putln(
+ "else {")
+ if user_del_entry:
+ code.putln(
+ "return %s(o, i);" %
+ user_del_entry.func_cname)
+ else:
+ self.generate_guarded_basetype_call(
+ base_type, None, "tp_descr_set", "o, i, v", code)
+ code.putln(
+ 'PyErr_SetString(PyExc_NotImplementedError, "__delete__");')
+ code.putln(
+ "return -1;")
+ code.putln(
+ "}")
+ code.putln(
+ "}")
+
+ def generate_property_accessors(self, cclass_scope, code):
+ for entry in cclass_scope.property_entries:
+ property_scope = entry.scope
+ if property_scope.defines_any(["__get__"]):
+ self.generate_property_get_function(entry, code)
+ if property_scope.defines_any(["__set__", "__del__"]):
+ self.generate_property_set_function(entry, code)
+
+ def generate_property_get_function(self, property_entry, code):
+ property_scope = property_entry.scope
+ property_entry.getter_cname = property_scope.parent_scope.mangle(
+ Naming.prop_get_prefix, property_entry.name)
+ get_entry = property_scope.lookup_here("__get__")
+ code.putln("")
+ code.putln(
+ "static PyObject *%s(PyObject *o, void *x) {" %
+ property_entry.getter_cname)
+ code.putln(
+ "return %s(o);" %
+ get_entry.func_cname)
+ code.putln(
+ "}")
+
+ def generate_property_set_function(self, property_entry, code):
+ property_scope = property_entry.scope
+ property_entry.setter_cname = property_scope.parent_scope.mangle(
+ Naming.prop_set_prefix, property_entry.name)
+ set_entry = property_scope.lookup_here("__set__")
+ del_entry = property_scope.lookup_here("__del__")
+ code.putln("")
+ code.putln(
+ "static int %s(PyObject *o, PyObject *v, void *x) {" %
+ property_entry.setter_cname)
+ code.putln(
+ "if (v) {")
+ if set_entry:
+ code.putln(
+ "return %s(o, v);" %
+ set_entry.func_cname)
+ else:
+ code.putln(
+ 'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
+ code.putln(
+ "return -1;")
+ code.putln(
+ "}")
+ code.putln(
+ "else {")
+ if del_entry:
+ code.putln(
+ "return %s(o);" %
+ del_entry.func_cname)
+ else:
+ code.putln(
+ 'PyErr_SetString(PyExc_NotImplementedError, "__del__");')
+ code.putln(
+ "return -1;")
+ code.putln(
+ "}")
+ code.putln(
+ "}")
+
+ def generate_typeobj_definition(self, modname, entry, code):
+ type = entry.type
+ scope = type.scope
+ for suite in TypeSlots.substructures:
+ suite.generate_substructure(scope, code)
+ code.putln("")
+ if entry.visibility == 'public':
+ header = "DL_EXPORT(PyTypeObject) %s = {"
+ else:
+ header = "PyTypeObject %s = {"
+ code.putln(header % type.typeobj_cname)
+ code.putln(
+ "PyObject_HEAD_INIT(0)")
+ code.putln(
+ "0, /*ob_size*/")
+ code.putln(
+ '"%s.%s", /*tp_name*/' % (
+ modname, scope.class_name))
+ if type.typedef_flag:
+ objstruct = type.objstruct_cname
+ else:
+ #objstruct = "struct %s" % scope.parent_type.objstruct_cname
+ objstruct = "struct %s" % type.objstruct_cname
+ code.putln(
+ "sizeof(%s), /*tp_basicsize*/" %
+ objstruct)
+ code.putln(
+ "0, /*tp_itemsize*/")
+ for slot in TypeSlots.slot_table:
+ slot.generate(scope, code)
+ code.putln(
+ "};")
+
+ def generate_method_table(self, env, code):
+ code.putln("")
+ code.putln(
+ "static struct PyMethodDef %s[] = {" %
+ env.method_table_cname)
+ for entry in env.pyfunc_entries:
+ code.put_pymethoddef(entry, ",")
+ code.putln(
+ "{0, 0, 0, 0}")
+ code.putln(
+ "};")
+
+ def generate_member_table(self, env, code):
+ #print "ModuleNode.generate_member_table: scope =", env ###
+ if env.public_attr_entries:
+ code.putln("")
+ code.putln(
+ "static struct PyMemberDef %s[] = {" %
+ env.member_table_cname)
+ type = env.parent_type
+ if type.typedef_flag:
+ objstruct = type.objstruct_cname
+ else:
+ objstruct = "struct %s" % type.objstruct_cname
+ for entry in env.public_attr_entries:
+ type_code = entry.type.pymemberdef_typecode
+ if entry.visibility == 'readonly':
+ flags = "READONLY"
+ else:
+ flags = "0"
+ code.putln('{"%s", %s, %s, %s, 0},' % (
+ entry.name,
+ type_code,
+ "offsetof(%s, %s)" % (objstruct, entry.cname),
+ flags))
+ code.putln(
+ "{0, 0, 0, 0, 0}")
+ code.putln(
+ "};")
+
+ def generate_getset_table(self, env, code):
+ if env.property_entries:
+ code.putln("")
+ code.putln(
+ "static struct PyGetSetDef %s[] = {" %
+ env.getset_table_cname)
+ for entry in env.property_entries:
+ if entry.doc:
+ doc_code = code.get_string_const(entry.doc)
+ else:
+ doc_code = "0"
+ code.putln(
+ '{"%s", %s, %s, %s, 0},' % (
+ entry.name,
+ entry.getter_cname or "0",
+ entry.setter_cname or "0",
+ doc_code))
+ code.putln(
+ "{0, 0, 0, 0, 0}")
+ code.putln(
+ "};")
+
+ def generate_interned_name_table(self, interned_strings, code):
+ code.putln("")
+ code.putln(
+ "static PyObject **%s[] = {" % Naming.intern_tab_cname)
+ for s in interned_strings:
+ code.putln("&%s," % s.py_cname)
+ code.putln("0")
+ code.putln(
+ "};")
+
+ def generate_filename_init_prototype(self, code):
+ code.putln("");
+ code.putln("static void %s(void); /*proto*/" % Naming.fileinit_cname)
+
+ def generate_module_init_func(self, imported_modules, env, code):
+ denv = env.definition_scope
+ code.putln("")
+ header = "PyMODINIT_FUNC init%s(void)" % env.module_name
+ code.putln("%s; /*proto*/" % header)
+ code.putln("%s {" % header)
+ code.put_var_declarations(env.temp_entries)
+
+ if env.gil_used:
+ # Workaround for GIL/threading bug in 2.3
+ code.putln("#if PY_VERSION_HEX < 0x02040000 && defined(WITH_THREAD)")
+ code.putln(" PyEval_InitThreads();")
+ code.putln("#endif")
+
+ #code.putln("/*--- Libary function declarations ---*/")
+ env.generate_library_function_declarations(code)
+ self.generate_filename_init_call(code)
+
+ #code.putln("/*--- Module creation code ---*/")
+ self.generate_module_creation_code(env, code)
+
+ #code.putln("/*--- String init code ---*/")
+ self.generate_string_init_code(env, code)
+
+ #code.putln("/*--- Intern code ---*/")
+ #self.generate_intern_code(env, code)
+
+ #code.putln("/*--- Global init code ---*/")
+ self.generate_global_init_code(env, code)
+
+ #code.putln("/*--- Function export code ---*/")
+ self.generate_pxd_function_export_code(env, code)
+ self.generate_api_function_export_code(env, code)
+
+ #code.putln("/*--- Function import code ---*/")
+ for module in imported_modules:
+ self.generate_c_function_import_code_for_module(module, env, code)
+
+ #code.putln("/*--- Type init code ---*/")
+ self.generate_type_init_code(env, code)
+
+ #code.putln("/*--- Type import code ---*/")
+ for module in imported_modules:
+ self.generate_type_import_code_for_module(module, env, code)
+
+ #code.putln("/*--- Execution code ---*/")
+ self.body.generate_execution_code(code)
+ code.putln("return;")
+ code.put_label(code.error_label)
+ code.put_var_xdecrefs(env.temp_entries)
+ code.putln('__Pyx_AddTraceback("%s");' % (env.qualified_name))
+ code.use_utility_code(Nodes.traceback_utility_code)
+ code.putln('}')
+
+ def generate_filename_init_call(self, code):
+ code.putln("%s();" % Naming.fileinit_cname)
+
+ def generate_module_creation_code(self, env, code):
+ # Generate code to create the module object and
+ # install the builtins.
+ if env.doc:
+ doc = env.doc_cname
+ else:
+ doc = "0"
+ code.putln(
+ '%s = Py_InitModule4("%s", %s, %s, 0, PYTHON_API_VERSION);' % (
+ env.module_cname,
+ env.module_name,
+ env.method_table_cname,
+ doc))
+ code.putln(
+ "if (!%s) %s;" % (
+ env.module_cname,
+ code.error_goto(self.pos)));
+ code.putln(
+ "Py_INCREF(%s);" %
+ env.module_cname)
+ code.putln(
+ '%s = PyImport_AddModule("__builtin__");' %
+ Naming.builtins_cname)
+ code.putln(
+ "if (!%s) %s;" % (
+ Naming.builtins_cname,
+ code.error_goto(self.pos)));
+ code.putln(
+ 'if (PyObject_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % (
+ env.module_cname,
+ Naming.builtins_cname,
+ code.error_goto(self.pos)))
+
+ def generate_string_init_code(self, env, code):
+ code.use_utility_code(Nodes.init_string_tab_utility_code)
+ code.putln(
+ "if (__Pyx_InitStrings(%s) < 0) %s;" % (
+ Naming.stringtab_cname,
+ code.error_goto(self.pos)))
+
+ def generate_global_init_code(self, env, code):
+ # Generate code to initialise global PyObject *
+ # variables to None.
+ for entry in env.var_entries:
+ if entry.visibility <> 'extern':
+ if entry.type.is_pyobject:
+ code.put_init_var_to_py_none(entry)
+
+ def generate_pxd_function_export_code(self, env, code):
+ denv = env.definition_scope
+ for entry in denv.cfunc_entries:
+ if entry.visibility <> 'extern':
+ self.generate_c_function_export_code(env, entry, code)
+
+ def generate_api_function_export_code(self, env, code):
+ for entry in env.cfunc_entries:
+ if entry.api:
+ self.generate_c_function_export_code(env, entry, code)
+
+ def generate_c_function_export_code(self, env, entry, code):
+ code.use_utility_code(function_export_utility_code)
+ signature = entry.type.signature_string()
+ code.putln('if (__Pyx_ExportFunction("%s", (void*)%s, "%s") < 0) %s' % (
+ entry.name,
+ entry.cname,
+ signature,
+ code.error_goto(self.pos)))
+
+ def generate_type_import_code_for_module(self, module, env, code):
+ # Generate type import code for all exported extension types in
+ # an imported module.
+ #if module.c_class_entries:
+ #print "generate_type_import_code_for_module:", module ###
+ for entry in module.c_class_entries:
+ if entry.defined_in_pxd:
+ self.generate_type_import_code(env, entry.type, entry.pos, code)
+
+ def generate_c_function_import_code_for_module(self, module, env, code):
+ # Generate import code for all exported C functions in a cimported module.
+ entries = []
+ for entry in module.cfunc_entries:
+ if entry.defined_in_pxd:
+ entries.append(entry)
+ if entries:
+ code.use_utility_code(import_module_utility_code)
+ code.use_utility_code(function_import_utility_code)
+ temp = self.module_temp_cname
+ code.putln(
+ '%s = __Pyx_ImportModule("%s"); if (!%s) %s' % (
+ temp,
+ module.qualified_name,
+ temp,
+ code.error_goto(self.pos)))
+ for entry in entries:
+ code.putln(
+ 'if (__Pyx_ImportFunction(%s, "%s", (void**)&%s, "%s") < 0) %s' % (
+ temp,
+ entry.name,
+ entry.cname,
+ entry.type.signature_string(),
+ code.error_goto(self.pos)))
+ code.putln("Py_DECREF(%s); %s = 0;" % (temp, temp))
+
+ def generate_type_init_code(self, env, code):
+ # Generate type import code for extern extension types
+ # and type ready code for non-extern ones.
+ #print "generate_type_init_code:", env ###
+ denv = env.definition_scope
+ for entry in denv.c_class_entries + env.c_class_entries:
+ if entry.visibility == 'extern':
+ self.generate_type_import_code(env, entry.type, entry.pos, code)
+ else:
+ self.generate_base_type_import_code(env, entry, code)
+ self.generate_exttype_vtable_init_code(entry, code)
+ self.generate_type_ready_code(env, entry, code)
+ self.generate_typeptr_assignment_code(entry, code)
+
+ def generate_base_type_import_code(self, env, entry, code):
+ base_type = entry.type.base_type
+ if base_type and base_type.module_name <> env.qualified_name:
+ self.generate_type_import_code(env, base_type, self.pos, code)
+
+ def use_type_import_utility_code(self, code):
+ import ExprNodes
+ code.use_utility_code(type_import_utility_code)
+ code.use_utility_code(import_module_utility_code)
+
+ def generate_type_import_code(self, env, type, pos, code):
+ # If not already done, generate code to import the typeobject of an
+ # extension type defined in another module, and extract its C method
+ # table pointer if any.
+ #print "generate_type_import_code:", type ###
+ if not type.is_builtin and type not in env.types_imported:
+ if type.typedef_flag:
+ objstruct = type.objstruct_cname
+ else:
+ objstruct = "struct %s" % type.objstruct_cname
+ self.generate_type_import_call(type, code, code.error_goto(pos))
+ self.use_type_import_utility_code(code)
+ if type.vtabptr_cname:
+ code.putln(
+ "if (__Pyx_GetVtable(%s->tp_dict, &%s) < 0) %s" % (
+ type.typeptr_cname,
+ type.vtabptr_cname,
+ code.error_goto(pos)))
+ code.use_utility_code(Nodes.get_vtable_utility_code)
+ env.types_imported[type] = 1
+
+ def generate_type_import_call(self, type, code, error_code):
+ if type.typedef_flag:
+ objstruct = type.objstruct_cname
+ else:
+ objstruct = "struct %s" % type.objstruct_cname
+ code.putln('%s = __Pyx_ImportType("%s", "%s", sizeof(%s)); if (!%s) %s' % (
+ type.typeptr_cname,
+ type.module_name,
+ type.name,
+ objstruct,
+ type.typeptr_cname,
+ error_code))
+
+ def generate_type_ready_code(self, env, entry, code):
+ # Generate a call to PyType_Ready for an extension
+ # type defined in this module.
+ type = entry.type
+ typeobj_cname = type.typeobj_cname
+ scope = type.scope
+ if scope: # could be None if there was an error
+ if entry.visibility <> 'extern':
+ for slot in TypeSlots.slot_table:
+ slot.generate_dynamic_init_code(scope, code)
+ code.putln(
+ "if (PyType_Ready(&%s) < 0) %s" % (
+ typeobj_cname,
+ code.error_goto(entry.pos)))
+ if type.vtable_cname:
+ code.putln(
+ "if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % (
+ typeobj_cname,
+ type.vtabptr_cname,
+ code.error_goto(entry.pos)))
+ code.use_utility_code(Nodes.set_vtable_utility_code)
+ code.putln(
+ 'if (PyObject_SetAttrString(%s, "%s", (PyObject *)&%s) < 0) %s' % (
+ Naming.module_cname,
+ scope.class_name,
+ typeobj_cname,
+ code.error_goto(entry.pos)))
+ weakref_entry = scope.lookup_here("__weakref__")
+ if weakref_entry:
+ if weakref_entry.type is py_object_type:
+ tp_weaklistoffset = "%s.tp_weaklistoffset" % typeobj_cname
+ code.putln("if (%s == 0) %s = offsetof(struct %s, %s);" % (
+ tp_weaklistoffset,
+ tp_weaklistoffset,
+ type.objstruct_cname,
+ weakref_entry.cname))
+ else:
+ error(weakref_entry.pos, "__weakref__ slot must be of type 'object'")
+
+ def generate_exttype_vtable_init_code(self, entry, code):
+ # Generate code to initialise the C method table of an
+ # extension type.
+ type = entry.type
+ if type.vtable_cname:
+ code.putln(
+ "%s = &%s;" % (
+ type.vtabptr_cname,
+ type.vtable_cname))
+ if type.base_type and type.base_type.vtabptr_cname:
+ code.putln(
+ "%s.%s = *%s;" % (
+ type.vtable_cname,
+ Naming.obj_base_cname,
+ type.base_type.vtabptr_cname))
+ for meth_entry in type.scope.cfunc_entries:
+ if meth_entry.func_cname:
+ code.putln(
+ "*(void(**)(void))&%s.%s = (void(*)(void))%s;" % (
+ type.vtable_cname,
+ meth_entry.cname,
+ meth_entry.func_cname))
+
+ def generate_typeptr_assignment_code(self, entry, code):
+ # Generate code to initialise the typeptr of an extension
+ # type defined in this module to point to its type object.
+ type = entry.type
+ if type.typeobj_cname:
+ code.putln(
+ "%s = &%s;" % (
+ type.typeptr_cname, type.typeobj_cname))
+
+ def generate_utility_functions(self, code):
+ code.global_state.generate_utility_functions(code)
+
+#------------------------------------------------------------------------------------
+#
+# Runtime support code
+#
+#------------------------------------------------------------------------------------
+
+import_module_utility_code = [
+"""
+static PyObject *__Pyx_ImportModule(char *name); /*proto*/
+""","""
+#ifndef __PYX_HAVE_RT_ImportModule
+#define __PYX_HAVE_RT_ImportModule
+static PyObject *__Pyx_ImportModule(char *name) {
+ PyObject *py_name = 0;
+
+ py_name = PyString_FromString(name);
+ if (!py_name)
+ goto bad;
+ return PyImport_Import(py_name);
+bad:
+ Py_XDECREF(py_name);
+ return 0;
+}
+#endif
+"""]
+
+#------------------------------------------------------------------------------------
+
+type_import_utility_code = [
+"""
+static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, long size); /*proto*/
+""",r"""
+#ifndef __PYX_HAVE_RT_ImportType
+#define __PYX_HAVE_RT_ImportType
+static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name,
+ long size)
+{
+ PyObject *py_module = 0;
+ PyObject *result = 0;
+
+ py_module = __Pyx_ImportModule(module_name);
+ if (!py_module)
+ goto bad;
+ result = PyObject_GetAttrString(py_module, class_name);
+ if (!result)
+ goto bad;
+ if (!PyType_Check(result)) {
+ PyErr_Format(PyExc_TypeError,
+ "%s.%s is not a type object",
+ module_name, class_name);
+ goto bad;
+ }
+#ifdef __PYX_CHECK_IMPORTED_TYPES
+ if (((PyTypeObject *)result)->tp_basicsize != size) {
+ PyErr_Format(PyExc_ValueError,
+ "%s.%s does not appear to be the correct type object",
+ module_name, class_name);
+ goto bad;
+ }
+#endif
+ return (PyTypeObject *)result;
+bad:
+ Py_XDECREF(result);
+ return 0;
+}
+#endif
+"""]
+
+#------------------------------------------------------------------------------------
+
+function_export_utility_code = [
+"""
+static int __Pyx_ExportFunction(char *n, void *f, char *s); /*proto*/
+""",r"""
+static int __Pyx_ExportFunction(char *n, void *f, char *s) {
+ PyObject *d = 0;
+ PyObject *p = 0;
+ d = PyObject_GetAttrString(%(MODULE)s, "%(API)s");
+ if (!d) {
+ PyErr_Clear();
+ d = PyDict_New();
+ if (!d)
+ goto bad;
+ Py_INCREF(d);
+ if (PyModule_AddObject(%(MODULE)s, "%(API)s", d) < 0)
+ goto bad;
+ }
+ p = PyCObject_FromVoidPtrAndDesc(f, s, 0);
+ if (!p)
+ goto bad;
+ if (PyDict_SetItemString(d, n, p) < 0)
+ goto bad;
+ Py_DECREF(p);
+ Py_DECREF(d);
+ return 0;
+bad:
+ Py_XDECREF(p);
+ Py_XDECREF(d);
+ return -1;
+}
+""" % {'MODULE': Naming.module_cname, 'API': Naming.api_name}]
+
+#------------------------------------------------------------------------------------
+
+function_import_utility_code = [
+"""
+static int __Pyx_ImportFunction(PyObject *module, char *funcname, void **f, char *sig); /*proto*/
+""","""
+#ifndef __PYX_HAVE_RT_ImportFunction
+#define __PYX_HAVE_RT_ImportFunction
+static int __Pyx_ImportFunction(PyObject *module, char *funcname, void **f, char *sig) {
+ PyObject *d = 0;
+ PyObject *cobj = 0;
+ char *desc;
+
+ d = PyObject_GetAttrString(module, "%(API)s");
+ if (!d)
+ goto bad;
+ cobj = PyDict_GetItemString(d, funcname);
+ if (!cobj) {
+ PyErr_Format(PyExc_ImportError,
+ "%%s does not export expected C function %%s",
+ PyModule_GetName(module), funcname);
+ goto bad;
+ }
+ desc = (char *)PyCObject_GetDesc(cobj);
+ if (!desc)
+ goto bad;
+ if (strcmp(desc, sig) != 0) {
+ PyErr_Format(PyExc_TypeError,
+ "C function %%s.%%s has wrong signature (expected %%s, got %%s)",
+ PyModule_GetName(module), funcname, sig, desc);
+ goto bad;
+ }
+ *f = PyCObject_AsVoidPtr(cobj);
+ Py_DECREF(d);
+ return 0;
+bad:
+ Py_XDECREF(d);
+ return -1;
+}
+#endif
+""" % dict(API = Naming.api_name)]
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Naming.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Naming.py
new file mode 100644
index 00000000..61076a81
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Naming.py
@@ -0,0 +1,69 @@
+#
+# Pyrex - C naming conventions
+#
+#
+# Prefixes for generating C names.
+# Collected here to facilitate ensuring uniqueness.
+#
+
+pyrex_prefix = "__pyx_"
+
+arg_prefix = pyrex_prefix + "arg_"
+funcdoc_prefix = pyrex_prefix + "doc_"
+enum_prefix = pyrex_prefix + "e_"
+func_prefix = pyrex_prefix + "f_"
+gstab_prefix = pyrex_prefix + "getsets_"
+prop_get_prefix = pyrex_prefix + "getprop_"
+const_prefix = pyrex_prefix + "k"
+label_prefix = pyrex_prefix + "L"
+pymethdef_prefix = pyrex_prefix + "mdef_"
+methtab_prefix = pyrex_prefix + "methods_"
+memtab_prefix = pyrex_prefix + "members_"
+interned_prefix = pyrex_prefix + "n_"
+objstruct_prefix = pyrex_prefix + "obj_"
+typeptr_prefix = pyrex_prefix + "ptype_"
+prop_set_prefix = pyrex_prefix + "setprop_"
+type_prefix = pyrex_prefix + "t_"
+typeobj_prefix = pyrex_prefix + "type_"
+var_prefix = pyrex_prefix + "v_"
+vtable_prefix = pyrex_prefix + "vtable_"
+vtabptr_prefix = pyrex_prefix + "vtabptr_"
+vtabstruct_prefix = pyrex_prefix + "vtabstruct_"
+
+args_cname = pyrex_prefix + "args"
+kwdlist_cname = pyrex_prefix + "argnames"
+obj_base_cname = pyrex_prefix + "base"
+builtins_cname = pyrex_prefix + "b"
+moddict_cname = pyrex_prefix + "d"
+default_prefix = pyrex_prefix + "d"
+dummy_cname = pyrex_prefix + "dummy"
+filename_cname = pyrex_prefix + "filename"
+filetable_cname = pyrex_prefix + "f"
+filenames_cname = pyrex_prefix + "filenames"
+fileinit_cname = pyrex_prefix + "init_filenames"
+intern_tab_cname = pyrex_prefix + "intern_tab"
+kwds_cname = pyrex_prefix + "kwds"
+lineno_cname = pyrex_prefix + "lineno"
+module_cname = pyrex_prefix + "m"
+moddoc_cname = pyrex_prefix + "mdoc"
+methtable_cname = pyrex_prefix + "methods"
+retval_cname = pyrex_prefix + "r"
+reqd_kwds_cname = pyrex_prefix + "reqd_kwds"
+self_cname = pyrex_prefix + "self"
+stringtab_cname = pyrex_prefix + "string_tab"
+vtabslot_cname = pyrex_prefix + "vtab"
+
+extern_c_macro = pyrex_prefix.upper() + "EXTERN_C"
+
+exc_type_name = pyrex_prefix + "exc_type"
+exc_value_name = pyrex_prefix + "exc_value"
+exc_tb_name = pyrex_prefix + "exc_tb"
+exc_lineno_name = pyrex_prefix + "exc_lineno"
+
+exc_vars = (exc_type_name, exc_value_name, exc_tb_name)
+
+api_name = pyrex_prefix + "capi__"
+
+h_guard_prefix = "__PYX_HAVE__"
+api_guard_prefix = "__PYX_HAVE_API__"
+api_func_guard = "__PYX_HAVE_API_FUNC_"
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Nodes.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Nodes.py
new file mode 100644
index 00000000..fb974df0
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Nodes.py
@@ -0,0 +1,3249 @@
+#
+# Pyrex - Parse tree nodes
+#
+
+import string, sys
+
+import Code
+from Errors import error, one_time_warning, InternalError
+import Naming
+import PyrexTypes
+from PyrexTypes import py_object_type, c_int_type, error_type, \
+ CTypedefType, CFuncType
+from Symtab import ModuleScope, LocalScope, \
+ StructOrUnionScope, PyClassScope, CClassScope
+from Pyrex.Utils import open_new_file, replace_suffix
+import Options
+
+from DebugFlags import debug_disposal_code
+
+class Node:
+ # pos (string, int, int) Source file position
+ # is_name boolean Is a NameNode
+ # is_literal boolean Is a ConstNode
+
+ is_name = 0
+ is_literal = 0
+
+ def __init__(self, pos, **kw):
+ self.pos = pos
+ self.__dict__.update(kw)
+
+ gil_message = "Operation"
+
+ def gil_check(self, env):
+ if env.nogil:
+ self.gil_error()
+
+ def gil_error(self, message = None):
+ error(self.pos, "%s not allowed without gil" % (message or self.gil_message))
+
+ #
+ # There are 3 phases of parse tree processing, applied in order to
+ # all the statements in a given scope-block:
+ #
+ # (1) analyse_declarations
+ # Make symbol table entries for all declarations at the current
+ # level, both explicit (def, cdef, etc.) and implicit (assignment
+ # to an otherwise undeclared name).
+ #
+ # (2) analyse_expressions
+ # Determine the result types of expressions and fill in the
+ # 'type' attribute of each ExprNode. Insert coercion nodes into the
+ # tree where needed to convert to and from Python objects.
+ # Allocate temporary locals for intermediate results.
+ #
+ # (3) generate_code
+ # Emit C code for all declarations, statements and expressions.
+ # Recursively applies the 3 processing phases to the bodies of
+ # functions.
+ #
+
+ def analyse_declarations(self, env):
+ pass
+
+ def analyse_expressions(self, env):
+ raise InternalError("analyse_expressions not implemented for %s" % \
+ self.__class__.__name__)
+
+ def generate_code(self, code):
+ raise InternalError("generate_code not implemented for %s" % \
+ self.__class__.__name__)
+
+
+class BlockNode:
+ # Mixin class for nodes representing a declaration block.
+ pass
+
+# def generate_const_definitions(self, env, code):
+# if env.const_entries:
+# code.putln("")
+# for entry in env.const_entries:
+# if not entry.is_interned:
+# code.put_var_declaration(entry, static = 1)
+
+# def generate_interned_name_decls(self, env, code):
+# # Flush accumulated interned names from the global scope
+# # and generate declarations for them.
+# genv = env.global_scope()
+# intern_map = genv.intern_map
+# names = genv.interned_names
+# if names:
+# code.putln("")
+# for name in names:
+# code.putln(
+# "static PyObject *%s;" % intern_map[name])
+# del names[:]
+
+# def generate_py_string_decls(self, env, code):
+# entries = env.pystring_entries
+# if entries:
+# code.putln("")
+# for entry in entries:
+# code.putln(
+# "static PyObject *%s;" % entry.pystring_cname)
+
+
+class StatListNode(Node):
+ # stats a list of StatNode
+
+ def analyse_declarations(self, env):
+ #print "StatListNode.analyse_declarations" ###
+ for stat in self.stats:
+ stat.analyse_declarations(env)
+
+ def analyse_expressions(self, env):
+ #print "StatListNode.analyse_expressions" ###
+ for stat in self.stats:
+ stat.analyse_expressions(env)
+
+ def generate_function_definitions(self, env, code):
+ #print "StatListNode.generate_function_definitions" ###
+ for stat in self.stats:
+ stat.generate_function_definitions(env, code)
+
+ def generate_execution_code(self, code):
+ #print "StatListNode.generate_execution_code" ###
+ for stat in self.stats:
+ code.mark_pos(stat.pos)
+ stat.generate_execution_code(code)
+
+
+class StatNode(Node):
+ #
+ # Code generation for statements is split into the following subphases:
+ #
+ # (1) generate_function_definitions
+ # Emit C code for the definitions of any structs,
+ # unions, enums and functions defined in the current
+ # scope-block.
+ #
+ # (2) generate_execution_code
+ # Emit C code for executable statements.
+ #
+
+ def generate_function_definitions(self, env, code):
+ pass
+
+ def generate_execution_code(self, code):
+ raise InternalError("generate_execution_code not implemented for %s" % \
+ self.__class__.__name__)
+
+
+class CDefExternNode(StatNode):
+ # include_file string or None
+ # body StatNode
+
+ def analyse_declarations(self, env):
+ if self.include_file:
+ env.add_include_file(self.include_file)
+ old_cinclude_flag = env.in_cinclude
+ env.in_cinclude = 1
+ self.body.analyse_declarations(env)
+ env.in_cinclude = old_cinclude_flag
+
+ def analyse_expressions(self, env):
+ pass
+
+ def generate_execution_code(self, code):
+ pass
+
+
+class CDeclaratorNode(Node):
+ # Part of a C declaration.
+ #
+ # Processing during analyse_declarations phase:
+ #
+ # analyse
+ # Returns (name, type) pair where name is the
+ # CNameDeclaratorNode of the name being declared
+ # and type is the type it is being declared as.
+ #
+ # calling_convention string Calling convention of CFuncDeclaratorNode
+ # for which this is a base
+
+ calling_convention = ""
+
+
+class CNameDeclaratorNode(CDeclaratorNode):
+ # name string The Pyrex name being declared
+ # cname string or None C name, if specified
+
+ def analyse(self, base_type, env):
+ return self, base_type
+
+
+class CPtrDeclaratorNode(CDeclaratorNode):
+ # base CDeclaratorNode
+
+ def analyse(self, base_type, env):
+ if base_type.is_pyobject:
+ error(self.pos,
+ "Pointer base type cannot be a Python object")
+ ptr_type = PyrexTypes.c_ptr_type(base_type)
+ return self.base.analyse(ptr_type, env)
+
+
+class CArrayDeclaratorNode(CDeclaratorNode):
+ # base CDeclaratorNode
+ # dimension ExprNode
+
+ def analyse(self, base_type, env):
+ if self.dimension:
+ self.dimension.analyse_const_expression(env)
+ if not self.dimension.type.is_int:
+ error(self.dimension.pos, "Array dimension not integer")
+ size = self.dimension.result()
+ else:
+ size = None
+ if not base_type.is_complete():
+ error(self.pos,
+ "Array element type '%s' is incomplete" % base_type)
+ if base_type.is_pyobject:
+ error(self.pos,
+ "Array element cannot be a Python object")
+ if base_type.is_cfunction:
+ error(self.pos,
+ "Array element cannot be a function")
+ array_type = PyrexTypes.c_array_type(base_type, size)
+ return self.base.analyse(array_type, env)
+
+
+class CFuncDeclaratorNode(CDeclaratorNode):
+ # base CDeclaratorNode
+ # args [CArgDeclNode]
+ # has_varargs boolean
+ # exception_value ConstNode
+ # exception_check boolean True if PyErr_Occurred check needed
+ # nogil boolean Can be called without gil
+ # with_gil boolean Acquire gil around function body
+
+ def analyse(self, return_type, env):
+ func_type_args = []
+ for arg_node in self.args:
+ name_declarator, type = arg_node.analyse(env)
+ name = name_declarator.name
+ if name_declarator.cname:
+ error(self.pos,
+ "Function argument cannot have C name specification")
+ # Turn *[] argument into **
+ if type.is_array:
+ type = PyrexTypes.c_ptr_type(type.base_type)
+ # Catch attempted C-style func(void) decl
+ if type.is_void:
+ error(arg_node.pos, "Function argument cannot be void")
+ func_type_args.append(
+ PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
+ if arg_node.default:
+ error(arg_node.pos, "C function argument cannot have default value")
+ exc_val = None
+ exc_check = 0
+ if return_type.is_pyobject \
+ and (self.exception_value or self.exception_check):
+ error(self.pos,
+ "Exception clause not allowed for function returning Python object")
+ else:
+ if self.exception_value:
+ self.exception_value.analyse_const_expression(env)
+ exc_val = self.exception_value.result()
+ if not return_type.assignable_from(self.exception_value.type):
+ error(self.exception_value.pos,
+ "Exception value incompatible with function return type")
+ exc_check = self.exception_check
+ if return_type.is_array:
+ error(self.pos,
+ "Function cannot return an array")
+ if return_type.is_cfunction:
+ error(self.pos,
+ "Function cannot return a function")
+ func_type = PyrexTypes.CFuncType(
+ return_type, func_type_args, self.has_varargs,
+ exception_value = exc_val, exception_check = exc_check,
+ calling_convention = self.base.calling_convention,
+ nogil = self.nogil, with_gil = self.with_gil)
+ return self.base.analyse(func_type, env)
+
+
+class CArgDeclNode(Node):
+ # Item in a function declaration argument list.
+ #
+ # base_type CBaseTypeNode
+ # declarator CDeclaratorNode
+ # #not_none boolean Tagged with 'not None'
+ # allow_none tristate True == 'or None', False == 'not None', None = unspecified
+ # default ExprNode or None
+ # default_entry Symtab.Entry Entry for the variable holding the default value
+ # is_self_arg boolean Is the "self" arg of an extension type method
+ # is_kw_only boolean Is a keyword-only argument
+
+ is_self_arg = 0
+
+ def analyse(self, env):
+ #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
+ base_type = self.base_type.analyse(env)
+ return self.declarator.analyse(base_type, env)
+
+
+class CBaseTypeNode(Node):
+ # Abstract base class for C base type nodes.
+ #
+ # Processing during analyse_declarations phase:
+ #
+ # analyse
+ # Returns the type.
+
+ pass
+
+
+class CSimpleBaseTypeNode(CBaseTypeNode):
+ # name string
+ # module_path [string] Qualifying name components
+ # is_basic_c_type boolean
+ # signed boolean
+ # longness integer
+ # is_self_arg boolean Is self argument of C method
+
+ def analyse(self, env):
+ # Return type descriptor.
+ #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
+ type = None
+ if self.is_basic_c_type:
+ type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
+ if not type:
+ error(self.pos, "Unrecognised type modifier combination")
+ elif self.name == "object" and not self.module_path:
+ type = py_object_type
+ elif self.name is None:
+ if self.is_self_arg and env.is_c_class_scope:
+ #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
+ type = env.parent_type
+ else:
+ type = py_object_type
+ else:
+ scope = env.find_imported_module(self.module_path, self.pos)
+ if scope:
+ entry = scope.find(self.name, self.pos)
+ if entry and entry.is_type:
+ type = entry.type
+ else:
+ error(self.pos, "'%s' is not a type identifier" % self.name)
+ if type:
+ return type
+ else:
+ return PyrexTypes.error_type
+
+
+class CComplexBaseTypeNode(CBaseTypeNode):
+ # base_type CBaseTypeNode
+ # declarator CDeclaratorNode
+
+ def analyse(self, env):
+ base = self.base_type.analyse(env)
+ _, type = self.declarator.analyse(base, env)
+ return type
+
+
+class CVarDefNode(StatNode):
+ # C variable definition or forward/extern function declaration.
+ #
+ # visibility 'private' or 'public' or 'extern'
+ # base_type CBaseTypeNode
+ # declarators [CDeclaratorNode]
+ # in_pxd boolean
+ # api boolean
+
+ def analyse_declarations(self, env, dest_scope = None):
+ if not dest_scope:
+ dest_scope = env
+ base_type = self.base_type.analyse(env)
+ for declarator in self.declarators:
+ name_declarator, type = declarator.analyse(base_type, env)
+ if not type.is_complete():
+ if not (self.visibility == 'extern' and type.is_array):
+ error(declarator.pos,
+ "Variable type '%s' is incomplete" % type)
+ if self.visibility == 'extern' and type.is_pyobject:
+ error(declarator.pos,
+ "Python object cannot be declared extern")
+ name = name_declarator.name
+ cname = name_declarator.cname
+ if type.is_cfunction:
+ entry = dest_scope.declare_cfunction(name, type, declarator.pos,
+ cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
+ api = self.api)
+ else:
+ if self.in_pxd and self.visibility <> 'extern':
+ error(self.pos,
+ "Only 'extern' C variable declaration allowed in .pxd file")
+ dest_scope.declare_var(name, type, declarator.pos,
+ cname = cname, visibility = self.visibility, is_cdef = 1)
+
+ def analyse_expressions(self, env):
+ pass
+
+ def generate_execution_code(self, code):
+ pass
+
+
+class CStructOrUnionDefNode(StatNode):
+ # name string
+ # cname string or None
+ # module_path [string]
+ # kind "struct" or "union"
+ # typedef_flag boolean
+ # cplus_flag boolean
+ # visibility "public" or "private"
+ # in_pxd boolean
+ # attributes [CVarDefNode] or None
+ # entry Entry
+ # bases [([name, ...], name), ...]
+
+ def analyse_declarations(self, env):
+ scope = None
+ base_scopes = []
+ for base in self.bases:
+ base_entry = env.find_qualified_name(base, self.pos)
+ if base_entry:
+ if base_entry.is_type and base_entry.type.is_struct_or_union \
+ and base_entry.type.scope.is_cplus:
+ base_scopes.append(base_entry.type.scope)
+ else:
+ error(self.pos, "Base type '%s' is not a C++ struct" %
+ ".".join(base[0] + [base[1]]))
+ if self.attributes is not None:
+ scope = StructOrUnionScope(base_scopes = base_scopes, is_cplus = self.cplus_flag)
+ if self.module_path:
+ home_scope = env.find_imported_module(self.module_path, self.pos)
+ if not home_scope:
+ return
+ else:
+ home_scope = env
+ def declare():
+ self.entry = home_scope.declare_struct_or_union(
+ self.name, self.kind, scope, self.typedef_flag, self.pos,
+ self.cname, visibility = self.visibility)
+ if self.attributes is not None:
+ if self.in_pxd and not env.in_cinclude:
+ self.entry.defined_in_pxd = 1
+ if not self.typedef_flag:
+ declare()
+ if self.attributes is not None:
+ for attr in self.attributes:
+ attr.analyse_declarations(env, scope)
+ if self.typedef_flag:
+ declare()
+
+ def analyse_expressions(self, env):
+ pass
+
+ def generate_execution_code(self, code):
+ pass
+
+
+class CEnumDefNode(StatNode):
+ # name string or None
+ # cname string or None
+ # items [CEnumDefItemNode]
+ # typedef_flag boolean
+ # visibility "public" or "private"
+ # in_pxd boolean
+ # entry Entry
+
+ def analyse_declarations(self, env):
+ self.entry = env.declare_enum(self.name, self.pos,
+ cname = self.cname, typedef_flag = self.typedef_flag,
+ visibility = self.visibility)
+ if self.items is not None:
+ if self.in_pxd and not env.in_cinclude:
+ self.entry.defined_in_pxd = 1
+ for item in self.items:
+ item.analyse_declarations(env, self.entry)
+
+ def analyse_expressions(self, env):
+ pass
+
+ def generate_execution_code(self, code):
+ pass
+
+
+class CEnumDefItemNode(StatNode):
+ # name string
+ # cname string or None
+ # value ExprNode or None
+
+ def analyse_declarations(self, env, enum_entry):
+ value_node = self.value
+ if value_node:
+ value_node.analyse_const_expression(env)
+ type = value_node.type
+ if type.is_int or type.is_enum:
+ value = value_node.result()
+ else:
+ error(self.pos,
+ "Type '%s' is not a valid enum value" % type)
+ value = "<error>"
+ else:
+ value = self.name
+ entry = env.declare_const(self.name, enum_entry.type,
+ value, self.pos, cname = self.cname)
+ enum_entry.enum_values.append(entry)
+
+
+class CTypeDefNode(StatNode):
+ # base_type CBaseTypeNode
+ # declarator CDeclaratorNode
+ # visibility "public" or "private"
+ # in_pxd boolean
+
+ def analyse_declarations(self, env):
+ base = self.base_type.analyse(env)
+ name_declarator, type = self.declarator.analyse(base, env)
+ name = name_declarator.name
+ cname = name_declarator.cname
+ entry = env.declare_typedef(name, type, self.pos,
+ cname = cname, visibility = self.visibility)
+ if self.in_pxd and not env.in_cinclude:
+ entry.defined_in_pxd = 1
+
+ def analyse_expressions(self, env):
+ pass
+
+ def generate_execution_code(self, code):
+ pass
+
+
+class FuncDefNode(StatNode, BlockNode):
+ # Base class for function definition nodes.
+ #
+ # return_type PyrexType
+ # #filename string C name of filename string const
+ # entry Symtab.Entry
+
+ def analyse_expressions(self, env):
+ pass
+
+ def need_gil_acquisition(self, lenv):
+ return 0
+
+ def generate_function_definitions(self, env, code):
+ # Generate C code for header and body of function
+ genv = env.global_scope()
+ lenv = LocalScope(name = self.entry.name, outer_scope = genv)
+ lenv.return_type = self.return_type
+ type = self.entry.type
+ if type.is_cfunction:
+ lenv.nogil = type.nogil and not type.with_gil
+ code.init_labels()
+ self.declare_arguments(lenv)
+ self.body.analyse_declarations(lenv)
+ self.body.analyse_expressions(lenv)
+ # Code for nested function definitions would go here
+ # if we supported them, which we probably won't.
+ # ----- Function header
+ code.putln("")
+ self.generate_function_header(code,
+ with_pymethdef = env.is_py_class_scope)
+ # ----- Local variable declarations
+ self.generate_argument_declarations(lenv, code)
+ code.put_var_declarations(lenv.var_entries)
+ init = ""
+ if not self.return_type.is_void:
+ code.putln(
+ "%s%s;" %
+ (self.return_type.declaration_code(
+ Naming.retval_cname),
+ init))
+ code.put_var_declarations(lenv.temp_entries)
+ self.generate_keyword_list(code)
+ # ----- Extern library function declarations
+ lenv.generate_library_function_declarations(code)
+ # ----- GIL acquisition
+ acquire_gil = self.need_gil_acquisition(lenv)
+ if acquire_gil:
+ lenv.global_scope().gil_used = 1
+ code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
+ # ----- Fetch arguments
+ self.generate_argument_parsing_code(code)
+ self.generate_argument_increfs(lenv, code)
+ # ----- Initialise local variables
+ for entry in lenv.var_entries:
+ if entry.type.is_pyobject and entry.init_to_none and entry.used:
+ code.put_init_var_to_py_none(entry)
+ # ----- Check and convert arguments
+ self.generate_argument_conversion_code(code)
+ self.generate_argument_type_tests(code)
+ # ----- Function body
+ self.body.generate_execution_code(code)
+ # ----- Default return value
+ code.putln("")
+ if self.return_type.is_pyobject:
+ #if self.return_type.is_extension_type:
+ # lhs = "(PyObject *)%s" % Naming.retval_cname
+ #else:
+ lhs = Naming.retval_cname
+ code.put_init_to_py_none(lhs, self.return_type)
+ else:
+ val = self.return_type.default_value
+ if val:
+ code.putln("%s = %s;" % (Naming.retval_cname, val))
+ #code.putln("goto %s;" % code.return_label)
+ # ----- Error cleanup
+ if code.error_label in code.labels_used:
+ code.put_goto(code.return_label)
+ code.put_label(code.error_label)
+ code.put_var_xdecrefs(lenv.temp_entries)
+ default_retval = self.return_type.default_value
+ err_val = self.error_value()
+ exc_check = self.caller_will_check_exceptions()
+ if err_val or exc_check:
+ code.putln(
+ '__Pyx_AddTraceback("%s");' %
+ self.entry.qualified_name)
+ val = err_val or default_retval
+ if val:
+ code.putln(
+ "%s = %s;" % (
+ Naming.retval_cname,
+ val))
+ else:
+ code.use_utility_code(unraisable_exception_utility_code)
+ code.putln(
+ '__Pyx_WriteUnraisable("%s");' %
+ self.entry.qualified_name)
+ #if not self.return_type.is_void:
+ if default_retval:
+ code.putln(
+ "%s = %s;" % (
+ Naming.retval_cname,
+ default_retval))
+ #self.return_type.default_value))
+ # ----- Return cleanup
+ code.put_label(code.return_label)
+ code.put_var_decrefs(lenv.var_entries, used_only = 1)
+ #code.put_var_decrefs(lenv.arg_entries)
+ self.generate_argument_decrefs(lenv, code)
+ self.put_stararg_decrefs(code)
+ if acquire_gil:
+ code.putln("PyGILState_Release(_save);")
+ if not self.return_type.is_void:
+ code.putln("return %s;" % Naming.retval_cname)
+ code.putln("}")
+
+ def put_stararg_decrefs(self, code):
+ pass
+
+ def declare_argument(self, env, arg, readonly = 0):
+ if arg.type.is_void:
+ error(arg.pos, "Invalid use of 'void'")
+ elif not arg.type.is_complete() and not arg.type.is_array:
+ error(arg.pos,
+ "Argument type '%s' is incomplete" % arg.type)
+ return env.declare_arg(arg.name, arg.type, arg.pos,
+ readonly = readonly)
+
+ def generate_argument_increfs(self, env, code):
+ # Turn writable borrowed argument refs into owned refs.
+ # This is necessary, because if the argument is assigned to,
+ # it will be decrefed.
+ for entry in env.arg_entries:
+ if not entry.is_readonly:
+ code.put_var_incref(entry)
+
+ def generate_argument_decrefs(self, env, code):
+ for entry in env.arg_entries:
+ if not entry.is_readonly:
+ code.put_var_decref(entry)
+
+ def generate_execution_code(self, code):
+ pass
+
+
+class CFuncDefNode(FuncDefNode):
+ # C function definition.
+ #
+ # visibility 'private' or 'public' or 'extern'
+ # base_type CBaseTypeNode
+ # declarator CDeclaratorNode
+ # body StatListNode
+ # api boolean
+ #
+ # with_gil boolean Acquire GIL around body
+ # type CFuncType
+
+ def unqualified_name(self):
+ return self.entry.name
+
+ def analyse_declarations(self, env):
+ base_type = self.base_type.analyse(env)
+ name_declarator, type = self.declarator.analyse(base_type, env)
+ if not type.is_cfunction:
+ error(self.pos,
+ "Suite attached to non-function declaration")
+ # Remember the actual type according to the function header
+ # written here, because the type in the symbol table entry
+ # may be different if we're overriding a C method inherited
+ # from the base type of an extension type.
+ self.type = type
+ name = name_declarator.name
+ cname = name_declarator.cname
+ self.entry = env.declare_cfunction(
+ name, type, self.pos,
+ cname = cname, visibility = self.visibility,
+ defining = self.body is not None,
+ api = self.api)
+ self.return_type = type.return_type
+
+ def declare_arguments(self, env):
+ type = self.type
+ without_gil = type.nogil and not type.with_gil
+ for arg in type.args:
+ if not arg.name:
+ error(arg.pos, "Missing argument name")
+ self.declare_argument(env, arg,
+ readonly = without_gil and arg.type.is_pyobject)
+
+ def need_gil_acquisition(self, lenv):
+ type = self.type
+ with_gil = type.with_gil
+ if type.nogil and not with_gil:
+# for arg in type.args:
+# if arg.type.is_pyobject:
+# error(self.pos,
+# "Function with Python argument cannot be declared nogil")
+ if type.return_type.is_pyobject:
+ error(self.pos,
+ "Function with Python return type cannot be declared nogil")
+ for entry in lenv.var_entries + lenv.temp_entries:
+ #print "CFuncDefNode.need_gil_acquisition:", entry.name, entry.cname, "readonly =", entry.is_readonly ###
+ if entry.type.is_pyobject and not entry.is_readonly:
+ error(self.pos, "Function declared nogil has Python locals or temporaries")
+ return with_gil
+
+ def generate_function_header(self, code, with_pymethdef):
+ arg_decls = []
+ type = self.type
+ visibility = self.entry.visibility
+ for arg in type.args:
+ arg_decls.append(arg.declaration_code())
+ if type.has_varargs:
+ arg_decls.append("...")
+ if not arg_decls:
+ arg_decls = ["void"]
+ entity = type.function_header_code(self.entry.func_cname,
+ string.join(arg_decls, ","))
+ if visibility == 'public':
+ dll_linkage = "DL_EXPORT"
+ else:
+ dll_linkage = None
+ header = self.return_type.declaration_code(entity,
+ dll_linkage = dll_linkage)
+ if visibility <> 'private':
+ storage_class = "%s " % Naming.extern_c_macro
+ else:
+ storage_class = "static "
+ code.putln("%s%s {" % (
+ storage_class,
+ header))
+
+ def generate_argument_declarations(self, env, code):
+ # Arguments already declared in function header
+ pass
+
+ def generate_keyword_list(self, code):
+ pass
+
+ def generate_argument_parsing_code(self, code):
+ pass
+
+ def generate_argument_conversion_code(self, code):
+ pass
+
+ def generate_argument_type_tests(self, code):
+ pass
+
+ def error_value(self):
+ if self.return_type.is_pyobject:
+ return "0"
+ else:
+ #return None
+ return self.entry.type.exception_value
+
+ def caller_will_check_exceptions(self):
+ return self.entry.type.exception_check
+
+
+class PyArgDeclNode(Node):
+ # Argument which must be a Python object (used
+ # for * and ** arguments).
+ #
+ # name string
+ # entry Symtab.Entry
+
+ pass
+
+
+class DefNode(FuncDefNode):
+ # A Python function definition.
+ #
+ # name string the Python name of the function
+ # args [CArgDeclNode] formal arguments
+ # star_arg PyArgDeclNode or None * argument
+ # starstar_arg PyArgDeclNode or None ** argument
+ # doc string or None
+ # body StatListNode
+ #
+ # The following subnode is constructed internally
+ # when the def statement is inside a Python class definition.
+ #
+ # assmt AssignmentNode Function construction/assignment
+
+ assmt = None
+ num_kwonly_args = 0
+ reqd_kw_flags_cname = "0"
+ has_star_or_kwonly_args = 0
+
+ def __init__(self, pos, **kwds):
+ FuncDefNode.__init__(self, pos, **kwds)
+ n = 0
+ for arg in self.args:
+ if arg.kw_only:
+ n += 1
+ self.num_kwonly_args = n
+ if self.star_arg or self.starstar_arg or n > 0:
+ self.has_star_or_kwonly_args = 1
+
+ def analyse_declarations(self, env):
+ for arg in self.args:
+ base_type = arg.base_type.analyse(env)
+ name_declarator, type = \
+ arg.declarator.analyse(base_type, env)
+ arg.name = name_declarator.name
+ if name_declarator.cname:
+ error(self.pos,
+ "Python function argument cannot have C name specification")
+ arg.type = type.as_argument_type()
+ arg.hdr_type = None
+ arg.needs_conversion = 0
+ arg.needs_type_test = 0
+ arg.is_generic = 1
+ if arg.allow_none is not None and not arg.type.is_extension_type:
+ error(self.pos,
+ "Only extension type arguments can have 'or None' or 'not None'")
+ self.declare_pyfunction(env)
+ self.analyse_signature(env)
+ self.return_type = self.entry.signature.return_type()
+# if self.has_star_or_kwonly_args:
+# env.use_utility_code(get_starargs_utility_code)
+
+ def analyse_signature(self, env):
+ any_type_tests_needed = 0
+ sig = self.entry.signature
+ nfixed = sig.num_fixed_args()
+ for i in range(nfixed):
+ if i < len(self.args):
+ arg = self.args[i]
+ arg.is_generic = 0
+ if sig.is_self_arg(i):
+ arg.is_self_arg = 1
+ arg.hdr_type = arg.type = env.parent_type
+ arg.needs_conversion = 0
+ else:
+ arg.hdr_type = sig.fixed_arg_type(i)
+ if not arg.type.same_as(arg.hdr_type):
+ if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
+ arg.needs_type_test = 1
+ any_type_tests_needed = 1
+ else:
+ arg.needs_conversion = 1
+ if arg.needs_conversion:
+ arg.hdr_cname = Naming.arg_prefix + arg.name
+ else:
+ arg.hdr_cname = Naming.var_prefix + arg.name
+ else:
+ self.bad_signature()
+ return
+ if nfixed < len(self.args):
+ if not sig.has_generic_args:
+ self.bad_signature()
+ for arg in self.args:
+ if arg.is_generic and arg.type.is_extension_type:
+ arg.needs_type_test = 1
+ any_type_tests_needed = 1
+# if any_type_tests_needed:
+# env.use_utility_code(arg_type_test_utility_code)
+
+ def bad_signature(self):
+ sig = self.entry.signature
+ expected_str = "%d" % sig.num_fixed_args()
+ if sig.has_generic_args:
+ expected_str = expected_str + " or more"
+ name = self.name
+ if name.startswith("__") and name.endswith("__"):
+ desc = "Special method"
+ else:
+ desc = "Method"
+ error(self.pos,
+ "%s %s has wrong number of arguments "
+ "(%d declared, %s expected)" % (
+ desc, self.name, len(self.args), expected_str))
+
+ def declare_pyfunction(self, env):
+ #print "DefNode.declare_pyfunction:", self.name, "in", env ###
+ name = self.name
+ entry = env.declare_pyfunction(self.name, self.pos)
+ self.entry = entry
+ prefix = env.scope_prefix
+ entry.func_cname = \
+ Naming.func_prefix + prefix + name
+ entry.pymethdef_cname = \
+ Naming.pymethdef_prefix + prefix + name
+ if not entry.is_special:
+ entry.doc = self.doc
+ entry.doc_cname = \
+ Naming.funcdoc_prefix + prefix + name
+
+ def declare_arguments(self, env):
+ for arg in self.args:
+ if not arg.name:
+ error(arg.pos, "Missing argument name")
+ if arg.needs_conversion:
+ arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
+ if arg.type.is_pyobject:
+ arg.entry.init = "0"
+ arg.entry.init_to_none = 0
+ else:
+ arg.entry = self.declare_argument(env, arg)
+ arg.entry.used = 1
+ arg.entry.is_self_arg = arg.is_self_arg
+ if arg.hdr_type:
+ if arg.is_self_arg or \
+ (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
+ arg.entry.is_declared_generic = 1
+ self.declare_python_arg(env, self.star_arg)
+ self.declare_python_arg(env, self.starstar_arg)
+
+ def declare_python_arg(self, env, arg):
+ if arg:
+ entry = env.declare_var(arg.name,
+ PyrexTypes.py_object_type, arg.pos)
+ entry.used = 1
+ entry.init = "0"
+ entry.init_to_none = 0
+ entry.xdecref_cleanup = 1
+ arg.entry = entry
+
+ def analyse_expressions(self, env):
+ self.analyse_default_values(env)
+ if env.is_py_class_scope:
+ self.synthesize_assignment_node(env)
+
+ def analyse_default_values(self, env):
+ for arg in self.args:
+ if arg.default:
+ if arg.is_generic:
+ arg.default.analyse_types(env)
+ arg.default = arg.default.coerce_to(arg.type, env)
+ arg.default.allocate_temps(env)
+ arg.default_entry = env.add_default_value(arg.type)
+ arg.default_entry.used = 1
+ else:
+ error(arg.pos,
+ "This argument cannot have a default value")
+ arg.default = None
+
+ def synthesize_assignment_node(self, env):
+ import ExprNodes
+ self.assmt = SingleAssignmentNode(self.pos,
+ lhs = ExprNodes.NameNode(self.pos, name = self.name),
+ rhs = ExprNodes.UnboundMethodNode(self.pos,
+ class_cname = env.class_obj_cname,
+ function = ExprNodes.PyCFunctionNode(self.pos,
+ pymethdef_cname = self.entry.pymethdef_cname)))
+ self.assmt.analyse_declarations(env)
+ self.assmt.analyse_expressions(env)
+
+ def generate_function_header(self, code, with_pymethdef):
+ arg_code_list = []
+ sig = self.entry.signature
+ if sig.has_dummy_arg:
+ arg_code_list.append(
+ "PyObject *%s" % Naming.self_cname)
+ for arg in self.args:
+ if not arg.is_generic:
+ if arg.is_self_arg:
+ arg_code_list.append("PyObject *%s" % arg.hdr_cname)
+ else:
+ arg_code_list.append(
+ arg.hdr_type.declaration_code(arg.hdr_cname))
+ if sig.has_generic_args:
+ arg_code_list.append(
+ "PyObject *%s, PyObject *%s"
+ % (Naming.args_cname, Naming.kwds_cname))
+ arg_code = ", ".join(arg_code_list)
+ dc = self.return_type.declaration_code(self.entry.func_cname)
+ header = "static %s(%s)" % (dc, arg_code)
+ code.putln("%s; /*proto*/" % header)
+ if self.entry.doc:
+ code.putln(
+ 'static char %s[] = "%s";' % (
+ self.entry.doc_cname,
+ self.entry.doc))
+ if with_pymethdef:
+ code.put(
+ "static PyMethodDef %s = " %
+ self.entry.pymethdef_cname)
+ code.put_pymethoddef(self.entry, ";")
+ code.putln("%s {" % header)
+
+ def generate_argument_declarations(self, env, code):
+ for arg in self.args:
+ if arg.is_generic: # or arg.needs_conversion:
+ code.put_var_declaration(arg.entry)
+
+ def generate_keyword_list(self, code):
+ if self.entry.signature.has_generic_args:
+ reqd_kw_flags = []
+ has_reqd_kwds = False
+ code.put(
+ "static char *%s[] = {" %
+ Naming.kwdlist_cname)
+ for arg in self.args:
+ if arg.is_generic:
+ code.put(
+ '"%s",' %
+ arg.name)
+ if arg.kw_only and not arg.default:
+ has_reqd_kwds = 1
+ flag = "1"
+ else:
+ flag = "0"
+ reqd_kw_flags.append(flag)
+ code.putln(
+ "0};")
+ if has_reqd_kwds:
+ flags_name = Naming.reqd_kwds_cname
+ self.reqd_kw_flags_cname = flags_name
+ code.putln(
+ "static char %s[] = {%s};" % (
+ flags_name,
+ ",".join(reqd_kw_flags)))
+
+ def generate_argument_parsing_code(self, code):
+ # Generate PyArg_ParseTuple call for generic
+ # arguments, if any.
+ has_kwonly_args = self.num_kwonly_args > 0
+ has_star_or_kw_args = self.star_arg is not None \
+ or self.starstar_arg is not None or has_kwonly_args
+ if not self.entry.signature.has_generic_args:
+ if has_star_or_kw_args:
+ error(self.pos, "This method cannot have * or keyword arguments")
+ else:
+ arg_addrs = []
+ arg_formats = []
+ default_seen = 0
+ for arg in self.args:
+ arg_entry = arg.entry
+ if arg.is_generic:
+ if arg.default:
+ code.putln(
+ "%s = %s;" % (
+ arg_entry.cname,
+ arg.default_entry.cname))
+ if not default_seen:
+ arg_formats.append("|")
+ default_seen = 1
+ elif default_seen and not arg.kw_only:
+ error(arg.pos, "Non-default argument following default argument")
+ arg_addrs.append("&" + arg_entry.cname)
+ format = arg_entry.type.parsetuple_format
+ if format:
+ arg_formats.append(format)
+ else:
+ error(arg.pos,
+ "Cannot convert Python object argument to type '%s'"
+ % arg.type)
+ error_return_code = "return %s;" % self.error_value()
+ argformat = '"%s"' % string.join(arg_formats, "")
+ if has_star_or_kw_args:
+ self.generate_stararg_getting_code(code)
+ pt_arglist = [Naming.args_cname, Naming.kwds_cname, argformat,
+ Naming.kwdlist_cname] + arg_addrs
+ pt_argstring = string.join(pt_arglist, ", ")
+ code.put(
+ 'if (!PyArg_ParseTupleAndKeywords(%s)) ' %
+ pt_argstring)
+ if has_star_or_kw_args:
+ code.putln("{")
+ code.put_xdecref(Naming.args_cname, py_object_type)
+ code.put_xdecref(Naming.kwds_cname, py_object_type)
+ self.generate_arg_xdecref(self.star_arg, code)
+ self.generate_arg_xdecref(self.starstar_arg, code)
+ code.putln(error_return_code)
+ code.putln("}")
+ else:
+ code.putln(error_return_code)
+
+ def put_stararg_decrefs(self, code):
+ if self.has_star_or_kwonly_args:
+ code.put_xdecref(Naming.args_cname, py_object_type)
+ code.put_xdecref(Naming.kwds_cname, py_object_type)
+
+ def generate_arg_xdecref(self, arg, code):
+ if arg:
+ code.put_var_xdecref(arg.entry)
+
+ def arg_address(self, arg):
+ if arg:
+ return "&%s" % arg.entry.cname
+ else:
+ return 0
+
+ def generate_stararg_getting_code(self, code):
+ num_kwonly = self.num_kwonly_args
+ nargs = len(self.args) - num_kwonly - self.entry.signature.num_fixed_args()
+ star_arg_addr = self.arg_address(self.star_arg)
+ starstar_arg_addr = self.arg_address(self.starstar_arg)
+ code.use_utility_code(get_starargs_utility_code)
+ code.putln(
+ "if (__Pyx_GetStarArgs(&%s, &%s, %s, %s, %s, %s, %s) < 0) return %s;" % (
+ Naming.args_cname,
+ Naming.kwds_cname,
+ Naming.kwdlist_cname,
+ nargs,
+ star_arg_addr,
+ starstar_arg_addr,
+ self.reqd_kw_flags_cname,
+ self.error_value()))
+
+ def generate_argument_conversion_code(self, code):
+ # Generate code to convert arguments from
+ # signature type to declared type, if needed.
+ for arg in self.args:
+ if arg.needs_conversion:
+ self.generate_arg_conversion(arg, code)
+
+ def generate_arg_conversion(self, arg, code):
+ # Generate conversion code for one argument.
+ old_type = arg.hdr_type
+ new_type = arg.type
+ if old_type.is_pyobject:
+ self.generate_arg_conversion_from_pyobject(arg, code)
+ elif new_type.is_pyobject:
+ self.generate_arg_conversion_to_pyobject(arg, code)
+ else:
+ if new_type.assignable_from(old_type):
+ code.putln(
+ "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
+ else:
+ error(arg.pos,
+ "Cannot convert argument from '%s' to '%s'" %
+ (old_type, new_type))
+
+ def generate_arg_conversion_from_pyobject(self, arg, code):
+ new_type = arg.type
+ func = new_type.from_py_function
+ if func:
+ code.putln("%s = %s(%s); if (PyErr_Occurred()) %s" % (
+ arg.entry.cname,
+ func,
+ arg.hdr_cname,
+ code.error_goto(arg.pos)))
+ else:
+ error(arg.pos,
+ "Cannot convert Python object argument to type '%s'"
+ % new_type)
+
+ def generate_arg_conversion_to_pyobject(self, arg, code):
+ old_type = arg.hdr_type
+ func = old_type.to_py_function
+ if func:
+ code.putln("%s = %s(%s); if (!%s) %s" % (
+ arg.entry.cname,
+ func,
+ arg.hdr_cname,
+ arg.entry.cname,
+ code.error_goto(arg.pos)))
+ else:
+ error(arg.pos,
+ "Cannot convert argument of type '%s' to Python object"
+ % old_type)
+
+ def generate_argument_type_tests(self, code):
+ # Generate type tests for args whose signature
+ # type is PyObject * and whose declared type is
+ # a subtype thereof.
+ for arg in self.args:
+ if arg.needs_type_test:
+ self.generate_arg_type_test(arg, code)
+
+ def generate_arg_type_test(self, arg, code):
+ # Generate type test for one argument.
+ if arg.type.typeobj_is_available():
+ typeptr_cname = arg.type.typeptr_cname
+ arg_code = "((PyObject *)%s)" % arg.entry.cname
+ code.use_utility_code(arg_type_test_utility_code)
+ code.putln(
+ 'if (!__Pyx_ArgTypeTest(%s, %s, %d, "%s")) %s' % (
+ arg_code,
+ typeptr_cname,
+ #not arg.not_none,
+ arg.allow_none <> False,
+ arg.name,
+ code.error_goto(arg.pos)))
+ if arg.allow_none is None:
+ one_time_warning(arg.pos, 'or_none',
+ "'not None' will become the default in a future version of Pyrex. "
+ "Use 'or None' to allow passing None.")
+ else:
+ error(arg.pos, "Cannot test type of extern C class "
+ "without type object name specification")
+
+ def generate_execution_code(self, code):
+ # Evaluate and store argument default values
+ for arg in self.args:
+ default = arg.default
+ if default:
+ default.generate_evaluation_code(code)
+ default.make_owned_reference(code)
+ code.putln(
+ "%s = %s;" % (
+ arg.default_entry.cname,
+ default.result_as(arg.default_entry.type)))
+ default.generate_post_assignment_code(code)
+# if default.is_temp and default.type.is_pyobject:
+# code.putln(
+# "%s = 0;" %
+# default.result())
+ # For Python class methods, create and store function object
+ if self.assmt:
+ self.assmt.generate_execution_code(code)
+
+ def error_value(self):
+ return self.entry.signature.error_value
+
+ def caller_will_check_exceptions(self):
+ return 1
+
+
+class PyClassDefNode(StatNode, BlockNode):
+ # A Python class definition.
+ #
+ # name string Name of the class
+ # doc string or None
+ # body StatNode Attribute definition code
+ # entry Symtab.Entry
+ # scope PyClassScope
+ #
+ # The following subnodes are constructed internally:
+ #
+ # dict DictNode Class dictionary
+ # classobj ClassNode Class object
+ # target NameNode Variable to assign class object to
+
+ def __init__(self, pos, name, bases, doc, body):
+ StatNode.__init__(self, pos)
+ self.name = name
+ self.doc = doc
+ self.body = body
+ import ExprNodes
+ self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
+ if self.doc:
+ doc_node = ExprNodes.StringNode(pos, value = self.doc)
+ else:
+ doc_node = None
+ self.classobj = ExprNodes.ClassNode(pos,
+ name = ExprNodes.StringNode(pos, value = name),
+ bases = bases, dict = self.dict, doc = doc_node)
+ self.target = ExprNodes.NameNode(pos, name = name)
+
+ def analyse_declarations(self, env):
+ self.target.analyse_target_declaration(env)
+
+ def analyse_expressions(self, env):
+ self.dict.analyse_expressions(env)
+ self.classobj.analyse_expressions(env)
+ genv = env.global_scope()
+ cenv = PyClassScope(name = self.name, outer_scope = genv)
+ cenv.class_dict_cname = self.dict.result()
+ cenv.class_obj_cname = self.classobj.result()
+ self.scope = cenv
+ self.body.analyse_declarations(cenv)
+ self.body.analyse_expressions(cenv)
+ self.target.analyse_target_expression(env, self.classobj)
+ self.dict.release_temp(env)
+ #self.classobj.release_temp(env)
+ #self.target.release_target_temp(env)
+
+ def generate_function_definitions(self, env, code):
+ #self.generate_py_string_decls(self.scope, code)
+ self.body.generate_function_definitions(
+ self.scope, code)
+
+ def generate_execution_code(self, code):
+ self.dict.generate_evaluation_code(code)
+ self.classobj.generate_evaluation_code(code)
+ self.body.generate_execution_code(code)
+ self.target.generate_assignment_code(self.classobj, code)
+ self.dict.generate_disposal_code(code)
+
+
+class CClassDefNode(StatNode):
+ # An extension type definition.
+ #
+ # visibility 'private' or 'public' or 'extern'
+ # typedef_flag boolean
+ # api boolean
+ # module_name string or None For import of extern type objects
+ # class_name string Unqualified name of class
+ # as_name string or None Name to declare as in this scope
+ # base_class_module string or None Module containing the base class
+ # base_class_name string or None Name of the base class
+ # options CClassOptions:
+ # objstruct_name string or None Specified C name of object struct
+ # typeobj_name string or None Specified C name of type object
+ # no_gc boolean Suppress GC support
+ # in_pxd boolean Is in a .pxd file
+ # doc string or None
+ # body StatNode or None
+ # entry Symtab.Entry
+ # base_type PyExtensionType or None
+
+ entry = None
+
+ def analyse_declarations(self, env):
+ #print "CClassDefNode.analyse_declarations:", self.class_name
+ #print "...visibility =", self.visibility
+ #print "...module_name =", self.module_name
+ if env.in_cinclude and not self.options.objstruct_cname:
+ error(self.pos, "Object struct name specification required for "
+ "C class defined in 'extern from' block")
+ self.base_type = None
+ has_body = self.body is not None
+ if self.base_class_name:
+ if self.base_class_module:
+ base_class_scope = env.find_module(self.base_class_module, self.pos)
+ else:
+ base_class_scope = env
+ if base_class_scope:
+ base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
+ if base_class_entry:
+ if not base_class_entry.is_type:
+ error(self.pos, "'%s' is not a type name" % self.base_class_name)
+ elif not base_class_entry.type.is_extension_type:
+ error(self.pos, "'%s' is not an extension type" % self.base_class_name)
+ elif has_body and base_class_entry.visibility <> 'extern' and not base_class_entry.type.is_defined():
+ error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
+ else:
+ self.base_type = base_class_entry.type
+ if self.module_name and self.visibility <> 'extern':
+ module_path = self.module_name.split(".")
+ home_scope = env.find_imported_module(module_path, self.pos)
+ if not home_scope:
+ return
+ else:
+ home_scope = env
+ self.entry = home_scope.declare_c_class(
+ name = self.class_name,
+ pos = self.pos,
+ defining = has_body and self.in_pxd,
+ implementing = has_body and not self.in_pxd,
+ module_name = self.module_name,
+ base_type = self.base_type,
+ visibility = self.visibility,
+ typedef_flag = self.typedef_flag,
+ api = self.api,
+ options = self.options)
+ if home_scope is not env and self.visibility == 'extern':
+ env.add_imported_entry(self.class_name, self.entry, pos)
+ scope = self.entry.type.scope
+ if self.doc:
+ scope.doc = self.doc
+ if has_body:
+ self.body.analyse_declarations(scope)
+ if self.in_pxd:
+ scope.defined = 1
+ else:
+ scope.implemented = 1
+ env.allocate_vtable_names(self.entry)
+
+ def analyse_expressions(self, env):
+ if self.body:
+ self.body.analyse_expressions(env)
+
+ def generate_function_definitions(self, env, code):
+ if self.entry and self.body:
+# self.body.generate_function_definitions(
+# self.entry.type.scope, code)
+ self.body.generate_function_definitions(env, code)
+
+ def generate_execution_code(self, code):
+ # This is needed to generate evaluation code for
+ # default values of method arguments.
+ if self.body:
+ self.body.generate_execution_code(code)
+
+
+class PropertyNode(StatNode):
+ # Definition of a property in an extension type.
+ #
+ # name string
+ # doc string or None Doc string
+ # body StatListNode
+
+ def analyse_declarations(self, env):
+ #print "PropertyNode.analyse_declarations:", env ###
+ entry = env.declare_property(self.name, self.doc, self.pos)
+ if entry:
+ #if self.doc:
+ # doc_entry = env.get_string_const(self.doc)
+ # entry.doc_cname = doc_entry.cname
+ self.body.analyse_declarations(entry.scope)
+
+ def analyse_expressions(self, env):
+ self.body.analyse_expressions(env)
+
+ def generate_function_definitions(self, env, code):
+ self.body.generate_function_definitions(env, code)
+
+ def generate_execution_code(self, code):
+ pass
+
+
+class GlobalNode(StatNode):
+ # Global variable declaration.
+ #
+ # names [string]
+
+ def analyse_declarations(self, env):
+ for name in self.names:
+ env.declare_global(name, self.pos)
+
+ def analyse_expressions(self, env):
+ pass
+
+ def generate_execution_code(self, code):
+ pass
+
+
+class ExprStatNode(StatNode):
+ # Expression used as a statement.
+ #
+ # expr ExprNode
+
+ def analyse_expressions(self, env):
+ self.expr.analyse_expressions(env)
+ self.expr.release_temp(env)
+
+ def generate_execution_code(self, code):
+ self.expr.generate_evaluation_code(code)
+ if not self.expr.is_temp and self.expr.result():
+ code.putln("%s;" % self.expr.result())
+ self.expr.generate_disposal_code(code)
+
+
+class AssignmentNode(StatNode):
+ # Abstract base class for assignment nodes.
+ #
+ # The analyse_expressions and generate_execution_code
+ # phases of assignments are split into two sub-phases
+ # each, to enable all the right hand sides of a
+ # parallel assignment to be evaluated before assigning
+ # to any of the left hand sides.
+
+ def analyse_expressions(self, env):
+ self.analyse_types(env)
+ self.allocate_rhs_temps(env)
+ self.allocate_lhs_temps(env)
+
+ def generate_execution_code(self, code):
+ self.generate_rhs_evaluation_code(code)
+ self.generate_assignment_code(code)
+
+
+class SingleAssignmentNode(AssignmentNode):
+ # The simplest case:
+ #
+ # a = b
+ #
+ # lhs ExprNode Left hand side
+ # rhs ExprNode Right hand side
+
+ def analyse_declarations(self, env):
+ self.lhs.analyse_target_declaration(env)
+
+ def analyse_types(self, env, use_temp = 0):
+ self.rhs.analyse_types(env)
+ self.lhs.analyse_target_types(env)
+ self.lhs.gil_assignment_check(env)
+ self.rhs = self.rhs.coerce_to(self.lhs.type, env)
+ if use_temp:
+ self.rhs = self.rhs.coerce_to_temp(env)
+
+ def allocate_rhs_temps(self, env):
+ self.rhs.allocate_temps(env)
+
+ def allocate_lhs_temps(self, env):
+ self.lhs.allocate_target_temps(env, self.rhs)
+
+ def generate_rhs_evaluation_code(self, code):
+ self.rhs.generate_evaluation_code(code)
+
+ def generate_assignment_code(self, code):
+ self.lhs.generate_assignment_code(self.rhs, code)
+
+
+class AugmentedAssignmentNode(SingleAssignmentNode):
+ # An in-place operation:
+ #
+ # a op= b
+ #
+ # lhs ExprNode Left hand side
+ # operator string
+ # rhs ExprNode Right hand side
+
+ def analyse_types(self, env):
+ op = self.operator
+ self.rhs.analyse_types(env)
+ self.lhs.analyse_inplace_types(env)
+ type = self.lhs.type
+ if type.is_pyobject:
+ type = py_object_type
+ else:
+ if type.is_ptr and (op == '+=' or op == '-='):
+ type = c_int_type
+ elif op == "**=":
+ error(self.pos, "**= operator not supported for non-Python types")
+ return
+ self.rhs = self.rhs.coerce_to(type, env)
+
+ def allocate_lhs_temps(self, env):
+ self.lhs.allocate_inplace_target_temps(env, self.rhs)
+
+ def generate_assignment_code(self, code):
+ self.lhs.generate_inplace_assignment_code(self.operator, self.rhs, code)
+
+
+class CascadedAssignmentNode(AssignmentNode):
+ # An assignment with multiple left hand sides:
+ #
+ # a = b = c
+ #
+ # lhs_list [ExprNode] Left hand sides
+ # rhs ExprNode Right hand sides
+ #
+ # Used internally:
+ #
+ # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
+
+ def analyse_declarations(self, env):
+ for lhs in self.lhs_list:
+ lhs.analyse_target_declaration(env)
+
+ def analyse_types(self, env, use_temp = 0):
+ self.rhs.analyse_types(env)
+ if use_temp:
+ self.rhs = self.rhs.coerce_to_temp(env)
+ else:
+ self.rhs = self.rhs.coerce_to_simple(env)
+ from ExprNodes import CloneNode
+ self.coerced_rhs_list = []
+ for lhs in self.lhs_list:
+ lhs.analyse_target_types(env)
+ lhs.gil_assignment_check(env)
+ rhs = CloneNode(self.rhs)
+ rhs = rhs.coerce_to(lhs.type, env)
+ self.coerced_rhs_list.append(rhs)
+
+ def allocate_rhs_temps(self, env):
+ self.rhs.allocate_temps(env)
+
+ def allocate_lhs_temps(self, env):
+ for lhs, rhs in zip(self.lhs_list, self.coerced_rhs_list):
+ rhs.allocate_temps(env)
+ lhs.allocate_target_temps(env, rhs)
+ #lhs.release_target_temp(env)
+ #rhs.release_temp(env)
+ self.rhs.release_temp(env)
+
+ def generate_rhs_evaluation_code(self, code):
+ self.rhs.generate_evaluation_code(code)
+
+ def generate_assignment_code(self, code):
+ for i in range(len(self.lhs_list)):
+ lhs = self.lhs_list[i]
+ rhs = self.coerced_rhs_list[i]
+ rhs.generate_evaluation_code(code)
+ lhs.generate_assignment_code(rhs, code)
+ # Assignment has disposed of the cloned RHS
+ self.rhs.generate_disposal_code(code)
+
+class ParallelAssignmentNode(AssignmentNode):
+ # A combined packing/unpacking assignment:
+ #
+ # a, b, c = d, e, f
+ #
+ # This has been rearranged by the parser into
+ #
+ # a = d ; b = e ; c = f
+ #
+ # but we must evaluate all the right hand sides
+ # before assigning to any of the left hand sides.
+ #
+ # stats [AssignmentNode] The constituent assignments
+
+ def analyse_declarations(self, env):
+ for stat in self.stats:
+ stat.analyse_declarations(env)
+
+ def analyse_expressions(self, env):
+ for stat in self.stats:
+ stat.analyse_types(env, use_temp = 1)
+ stat.allocate_rhs_temps(env)
+ for stat in self.stats:
+ stat.allocate_lhs_temps(env)
+
+ def generate_execution_code(self, code):
+ for stat in self.stats:
+ stat.generate_rhs_evaluation_code(code)
+ for stat in self.stats:
+ stat.generate_assignment_code(code)
+
+
+class PrintStatNode(StatNode):
+ # print statement
+ #
+ # args [ExprNode]
+ # ends_with_comma boolean
+
+ def analyse_expressions(self, env):
+ for i in range(len(self.args)):
+ arg = self.args[i]
+ arg.analyse_types(env)
+ arg = arg.coerce_to_pyobject(env)
+ arg.allocate_temps(env)
+ arg.release_temp(env)
+ self.args[i] = arg
+# env.use_utility_code(printing_utility_code)
+ self.gil_check(env)
+
+ gil_message = "Python print statement"
+
+ def generate_execution_code(self, code):
+ for arg in self.args:
+ arg.generate_evaluation_code(code)
+ code.use_utility_code(printing_utility_code)
+ code.putln(
+ "if (__Pyx_PrintItem(%s) < 0) %s" % (
+ arg.py_result(),
+ code.error_goto(self.pos)))
+ arg.generate_disposal_code(code)
+ if not self.ends_with_comma:
+ code.use_utility_code(printing_utility_code)
+ code.putln(
+ "if (__Pyx_PrintNewline() < 0) %s" %
+ code.error_goto(self.pos))
+
+
+class DelStatNode(StatNode):
+ # del statement
+ #
+ # args [ExprNode]
+
+ def analyse_declarations(self, env):
+ for arg in self.args:
+ arg.analyse_target_declaration(env)
+
+ def analyse_expressions(self, env):
+ for arg in self.args:
+ arg.analyse_target_expression(env, None)
+ type = arg.type
+ if not (type.is_pyobject
+ or (type.is_ptr and type.base_type.is_struct_or_union
+ and type.base_type.scope.is_cplus)):
+ error(arg.pos, "'del' can only be applied to Python object or pointer to C++ type")
+ if type.is_pyobject:
+ self.gil_check(env)
+
+ gil_message = "Deleting Python object"
+
+ def generate_execution_code(self, code):
+ for arg in self.args:
+ if arg.type.is_pyobject:
+ arg.generate_deletion_code(code)
+ else:
+ arg.generate_evaluation_code(code)
+ code.putln("delete %s;" % arg.result())
+ arg.generate_disposal_code(code)
+
+
+class PassStatNode(StatNode):
+ # pass statement
+
+ def analyse_expressions(self, env):
+ pass
+
+ def generate_execution_code(self, code):
+ pass
+
+
+class BreakStatNode(StatNode):
+
+ def analyse_expressions(self, env):
+ pass
+
+ def generate_execution_code(self, code):
+ if not code.break_label:
+ error(self.pos, "break statement not inside loop")
+ else:
+ #code.putln(
+ # "goto %s;" %
+ # code.break_label)
+ code.put_goto(code.break_label)
+
+
+class ContinueStatNode(StatNode):
+
+ def analyse_expressions(self, env):
+ pass
+
+ def generate_execution_code(self, code):
+ if code.in_try_finally:
+ error(self.pos, "continue statement inside try of try...finally")
+ elif not code.continue_label:
+ error(self.pos, "continue statement not inside loop")
+ else:
+ #code.putln(
+ # "goto %s;" %
+ # code.continue_label)
+ code.put_goto(code.continue_label)
+
+
+class ReturnStatNode(StatNode):
+ # return statement
+ #
+ # value ExprNode or None
+ # return_type PyrexType
+ # temps_in_use [Entry] Temps in use at time of return
+
+ def analyse_expressions(self, env):
+ return_type = env.return_type
+ self.return_type = return_type
+ self.temps_in_use = env.temps_in_use()
+ if not return_type:
+ error(self.pos, "Return not inside a function body")
+ return
+ if self.value:
+ self.value.analyse_types(env)
+ if return_type.is_void or return_type.is_returncode:
+ error(self.value.pos,
+ "Return with value in void function")
+ else:
+ self.value = self.value.coerce_to(env.return_type, env)
+ self.value.allocate_temps(env)
+ self.value.release_temp(env)
+ else:
+ if (not return_type.is_void
+ and not return_type.is_pyobject
+ and not return_type.is_returncode):
+ error(self.pos, "Return value required")
+ if return_type.is_pyobject:
+ self.gil_check(env)
+
+ gil_message = "Returning Python object"
+
+ def generate_execution_code(self, code):
+ if not self.return_type:
+ # error reported earlier
+ return
+ if self.value:
+ self.value.generate_evaluation_code(code)
+ self.value.make_owned_reference(code)
+ code.putln(
+ "%s = %s;" % (
+ Naming.retval_cname,
+ self.value.result_as(self.return_type)))
+ self.value.generate_post_assignment_code(code)
+ else:
+ if self.return_type.is_pyobject:
+ code.put_init_to_py_none(Naming.retval_cname, self.return_type)
+ elif self.return_type.is_returncode:
+ code.putln(
+ "%s = %s;" % (
+ Naming.retval_cname,
+ self.return_type.default_value))
+ for entry in self.temps_in_use:
+ code.put_var_decref_clear(entry)
+ #code.putln(
+ # "goto %s;" %
+ # code.return_label)
+ code.put_goto(code.return_label)
+
+
+class RaiseStatNode(StatNode):
+ # raise statement
+ #
+ # exc_type ExprNode or None
+ # exc_value ExprNode or None
+ # exc_tb ExprNode or None
+
+ def analyse_expressions(self, env):
+ if self.exc_type:
+ self.exc_type.analyse_types(env)
+ self.exc_type = self.exc_type.coerce_to_pyobject(env)
+ self.exc_type.allocate_temps(env)
+ if self.exc_value:
+ self.exc_value.analyse_types(env)
+ self.exc_value = self.exc_value.coerce_to_pyobject(env)
+ self.exc_value.allocate_temps(env)
+ if self.exc_tb:
+ self.exc_tb.analyse_types(env)
+ self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
+ self.exc_tb.allocate_temps(env)
+ if self.exc_type:
+ self.exc_type.release_temp(env)
+ if self.exc_value:
+ self.exc_value.release_temp(env)
+ if self.exc_tb:
+ self.exc_tb.release_temp(env)
+ self.gil_check(env)
+
+ gil_message = "Raising exception"
+
+ def generate_execution_code(self, code):
+ if self.exc_type:
+ self.exc_type.generate_evaluation_code(code)
+ type_code = self.exc_type.py_result()
+ else:
+ type_code = 0
+ if self.exc_value:
+ self.exc_value.generate_evaluation_code(code)
+ value_code = self.exc_value.py_result()
+ else:
+ value_code = "0"
+ if self.exc_tb:
+ self.exc_tb.generate_evaluation_code(code)
+ tb_code = self.exc_tb.py_result()
+ else:
+ tb_code = "0"
+ code.use_utility_code(raise_utility_code)
+ code.putln(
+ "__Pyx_Raise(%s, %s, %s);" % (
+ type_code,
+ value_code,
+ tb_code))
+ if self.exc_type:
+ self.exc_type.generate_disposal_code(code)
+ if self.exc_value:
+ self.exc_value.generate_disposal_code(code)
+ if self.exc_tb:
+ self.exc_tb.generate_disposal_code(code)
+ code.putln(
+ code.error_goto(self.pos))
+
+
+class ReraiseStatNode(StatNode):
+
+ def analyse_expressions(self, env):
+ env.reraise_used = 1
+ self.gil_check(env)
+
+ gil_message = "Raising exception"
+
+ def generate_execution_code(self, code):
+ vars = code.exc_vars
+ if vars:
+ tvars = tuple(vars)
+ code.putln("PyErr_Restore(%s, %s, %s);" % tvars)
+ code.putln("%s = %s = %s = 0;" % tvars)
+ code.putln(code.error_goto(self.pos))
+ else:
+ error(self.pos, "Reraise not inside except clause")
+
+
+class AssertStatNode(StatNode):
+ # assert statement
+ #
+ # cond ExprNode
+ # value ExprNode or None
+
+ def analyse_expressions(self, env):
+ self.cond = self.cond.analyse_boolean_expression(env)
+ if self.value:
+ self.value.analyse_types(env)
+ self.value = self.value.coerce_to_pyobject(env)
+ self.value.allocate_temps(env)
+ self.cond.release_temp(env)
+ if self.value:
+ self.value.release_temp(env)
+ self.gil_check(env)
+
+ gil_message = "Raising exception"
+
+ def generate_execution_code(self, code):
+ code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
+ self.cond.generate_evaluation_code(code)
+ code.putln(
+ "if (!%s) {" %
+ self.cond.result())
+ if self.value:
+ self.value.generate_evaluation_code(code)
+ if self.value:
+ code.putln(
+ "PyErr_SetObject(PyExc_AssertionError, %s);" %
+ self.value.py_result())
+ else:
+ code.putln(
+ "PyErr_SetNone(PyExc_AssertionError);")
+ code.putln(
+ code.error_goto(self.pos))
+ code.putln(
+ "}")
+ self.cond.generate_disposal_code(code)
+ # Disposal code for value not needed because exception always raised
+ #if self.value:
+ # self.value.generate_disposal_code(code)
+ code.putln("#endif")
+
+class IfStatNode(StatNode):
+ # if statement
+ #
+ # if_clauses [IfClauseNode]
+ # else_clause StatNode or None
+
+ def analyse_declarations(self, env):
+ for if_clause in self.if_clauses:
+ if_clause.analyse_declarations(env)
+ if self.else_clause:
+ self.else_clause.analyse_declarations(env)
+
+ def analyse_expressions(self, env):
+ for if_clause in self.if_clauses:
+ if_clause.analyse_expressions(env)
+ if self.else_clause:
+ self.else_clause.analyse_expressions(env)
+
+ def generate_execution_code(self, code):
+ end_label = code.new_label()
+ for if_clause in self.if_clauses:
+ if_clause.generate_execution_code(code, end_label)
+ if self.else_clause:
+ code.putln("/*else*/ {")
+ self.else_clause.generate_execution_code(code)
+ code.putln("}")
+ code.put_label(end_label)
+
+
+class IfClauseNode(Node):
+ # if or elif clause in an if statement
+ #
+ # condition ExprNode
+ # body StatNode
+
+ def analyse_declarations(self, env):
+ self.condition.analyse_declarations(env)
+ self.body.analyse_declarations(env)
+
+ def analyse_expressions(self, env):
+ self.condition = \
+ self.condition.analyse_temp_boolean_expression(env)
+ self.condition.release_temp(env)
+ self.body.analyse_expressions(env)
+
+ def generate_execution_code(self, code, end_label):
+ self.condition.generate_evaluation_code(code)
+ code.putln(
+ "if (%s) {" %
+ self.condition.result())
+ self.body.generate_execution_code(code)
+ #code.putln(
+ # "goto %s;" %
+ # end_label)
+ code.put_goto(end_label)
+ code.putln("}")
+
+
+class WhileStatNode(StatNode):
+ # while statement
+ #
+ # condition ExprNode
+ # body StatNode
+ # else_clause StatNode
+
+ def analyse_declarations(self, env):
+ self.body.analyse_declarations(env)
+ if self.else_clause:
+ self.else_clause.analyse_declarations(env)
+
+ def analyse_expressions(self, env):
+ self.condition = \
+ self.condition.analyse_temp_boolean_expression(env)
+ self.condition.release_temp(env)
+ #env.recycle_pending_temps() # TEMPORARY
+ self.body.analyse_expressions(env)
+ if self.else_clause:
+ self.else_clause.analyse_expressions(env)
+
+ def generate_execution_code(self, code):
+ old_loop_labels = code.new_loop_labels()
+ code.putln(
+ "while (1) {")
+ self.condition.generate_evaluation_code(code)
+ code.putln(
+ "if (!%s) break;" %
+ self.condition.result())
+ self.body.generate_execution_code(code)
+ code.put_label(code.continue_label)
+ code.putln("}")
+ break_label = code.break_label
+ code.set_loop_labels(old_loop_labels)
+ if self.else_clause:
+ code.putln("/*else*/ {")
+ self.else_clause.generate_execution_code(code)
+ code.putln("}")
+ code.put_label(break_label)
+
+
+class ForInStatNode(StatNode):
+ # for statement
+ #
+ # target ExprNode
+ # iterator IteratorNode
+ # body StatNode
+ # else_clause StatNode
+ # item NextNode used internally
+
+ def analyse_declarations(self, env):
+ self.target.analyse_target_declaration(env)
+ self.body.analyse_declarations(env)
+ if self.else_clause:
+ self.else_clause.analyse_declarations(env)
+
+ def analyse_expressions(self, env):
+ import ExprNodes
+ self.iterator.analyse_expressions(env)
+ self.target.analyse_target_types(env)
+ self.item = ExprNodes.NextNode(self.iterator, env)
+ self.item = self.item.coerce_to(self.target.type, env)
+ self.item.allocate_temps(env)
+ self.target.allocate_target_temps(env, self.item)
+ #self.item.release_temp(env)
+ #self.target.release_target_temp(env)
+ self.body.analyse_expressions(env)
+ if self.else_clause:
+ self.else_clause.analyse_expressions(env)
+ self.iterator.release_temp(env)
+
+ def generate_execution_code(self, code):
+ old_loop_labels = code.new_loop_labels()
+ self.iterator.generate_evaluation_code(code)
+ code.putln(
+ "for (;;) {")
+ self.item.generate_evaluation_code(code)
+ self.target.generate_assignment_code(self.item, code)
+ self.body.generate_execution_code(code)
+ code.put_label(code.continue_label)
+ code.putln(
+ "}")
+ break_label = code.break_label
+ code.set_loop_labels(old_loop_labels)
+ if self.else_clause:
+ code.putln("/*else*/ {")
+ self.else_clause.generate_execution_code(code)
+ code.putln("}")
+ code.put_label(break_label)
+ self.iterator.generate_disposal_code(code)
+
+
+class IntegerForStatNode(StatNode):
+ # for expr rel name rel expr
+ #
+ # bound1 ExprNode
+ # relation1 string
+ # target NameNode
+ # relation2 string
+ # bound2 ExprNode
+ # body StatNode
+ # else_clause StatNode or None
+ #
+ # Used internally:
+ #
+ # is_py_target bool
+ # loopvar_name string
+ # py_loopvar_node PyTempNode or None
+
+ def analyse_declarations(self, env):
+ self.target.analyse_target_declaration(env)
+ self.body.analyse_declarations(env)
+ if self.else_clause:
+ self.else_clause.analyse_declarations(env)
+
+ def analyse_expressions(self, env):
+ import ExprNodes
+ self.target.analyse_target_types(env)
+ self.bound1.analyse_types(env)
+ self.bound2.analyse_types(env)
+ self.bound1 = self.bound1.coerce_to_integer(env)
+ self.bound2 = self.bound2.coerce_to_integer(env)
+ if not (self.bound2.is_name or self.bound2.is_literal):
+ self.bound2 = self.bound2.coerce_to_temp(env)
+ target_type = self.target.type
+ if not (target_type.is_pyobject or target_type.is_int):
+ error(self.target.pos,
+ "Integer for-loop variable must be of type int or Python object")
+ #if not (target_type.is_pyobject
+ # or target_type.assignable_from(PyrexTypes.c_int_type)):
+ # error(self.target.pos,
+ # "Cannot assign integer to variable of type '%s'" % target_type)
+ if target_type.is_int:
+ self.is_py_target = 0
+ self.loopvar_name = self.target.entry.cname
+ self.py_loopvar_node = None
+ else:
+ self.is_py_target = 1
+ c_loopvar_node = ExprNodes.TempNode(self.pos,
+ PyrexTypes.c_long_type, env)
+ c_loopvar_node.allocate_temps(env)
+ self.loopvar_name = c_loopvar_node.result()
+ self.py_loopvar_node = \
+ ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
+ self.bound1.allocate_temps(env)
+ self.bound2.allocate_temps(env)
+ if self.is_py_target:
+ self.py_loopvar_node.allocate_temps(env)
+ self.target.allocate_target_temps(env, self.py_loopvar_node)
+ #self.target.release_target_temp(env)
+ #self.py_loopvar_node.release_temp(env)
+ self.body.analyse_expressions(env)
+ if self.is_py_target:
+ c_loopvar_node.release_temp(env)
+ if self.else_clause:
+ self.else_clause.analyse_expressions(env)
+ self.bound1.release_temp(env)
+ self.bound2.release_temp(env)
+
+ def generate_execution_code(self, code):
+ old_loop_labels = code.new_loop_labels()
+ self.bound1.generate_evaluation_code(code)
+ self.bound2.generate_evaluation_code(code)
+ offset, incop = self.relation_table[self.relation1]
+ code.putln(
+ "for (%s = %s%s; %s %s %s; %s%s) {" % (
+ self.loopvar_name,
+ self.bound1.result(), offset,
+ self.loopvar_name, self.relation2, self.bound2.result(),
+ incop, self.loopvar_name))
+ if self.py_loopvar_node:
+ self.py_loopvar_node.generate_evaluation_code(code)
+ self.target.generate_assignment_code(self.py_loopvar_node, code)
+ self.body.generate_execution_code(code)
+ code.put_label(code.continue_label)
+ code.putln("}")
+ break_label = code.break_label
+ code.set_loop_labels(old_loop_labels)
+ if self.else_clause:
+ code.putln("/*else*/ {")
+ self.else_clause.generate_execution_code(code)
+ code.putln("}")
+ code.put_label(break_label)
+ self.bound1.generate_disposal_code(code)
+ self.bound2.generate_disposal_code(code)
+
+ relation_table = {
+ # {relop : (initial offset, increment op)}
+ '<=': ("", "++"),
+ '<' : ("+1", "++"),
+ '>=': ("", "--"),
+ '>' : ("-1", "--")
+ }
+
+
+class TryExceptStatNode(StatNode):
+ # try .. except statement
+ #
+ # body StatNode
+ # except_clauses [ExceptClauseNode]
+ # else_clause StatNode or None
+ # cleanup_list [Entry] temps to clean up on error
+
+ def analyse_declarations(self, env):
+ self.body.analyse_declarations(env)
+ for except_clause in self.except_clauses:
+ except_clause.analyse_declarations(env)
+ if self.else_clause:
+ self.else_clause.analyse_declarations(env)
+ self.gil_check(env)
+
+ def analyse_expressions(self, env):
+ self.body.analyse_expressions(env)
+ self.cleanup_list = env.free_temp_entries[:]
+ for except_clause in self.except_clauses:
+ except_clause.analyse_expressions(env)
+ if self.else_clause:
+ self.else_clause.analyse_expressions(env)
+ self.gil_check(env)
+
+ gil_message = "Try-except statement"
+
+ def generate_execution_code(self, code):
+ old_error_label = code.new_error_label()
+ our_error_label = code.error_label
+ end_label = code.new_label()
+ code.putln(
+ "/*try:*/ {")
+ self.body.generate_execution_code(code)
+ code.putln(
+ "}")
+ code.error_label = old_error_label
+ if self.else_clause:
+ code.putln(
+ "/*else:*/ {")
+ self.else_clause.generate_execution_code(code)
+ code.putln(
+ "}")
+ code.put_goto(end_label)
+ code.put_label(our_error_label)
+ code.put_var_xdecrefs_clear(self.cleanup_list)
+ default_clause_seen = 0
+ for except_clause in self.except_clauses:
+ if not except_clause.pattern:
+ default_clause_seen = 1
+ else:
+ if default_clause_seen:
+ error(except_clause.pos, "Default except clause not last")
+ except_clause.generate_handling_code(code, end_label)
+ if not default_clause_seen:
+ code.put_goto(code.error_label)
+ code.put_label(end_label)
+
+
+class ExceptClauseNode(Node):
+ # Part of try ... except statement.
+ #
+ # pattern ExprNode
+ # exc_target ExprNode or None
+ # tb_target ExprNode or None
+ # body StatNode
+ # match_flag string result of exception match
+ # exc_value ExcValueNode used internally
+ # tb_value ExcValueNode used internally
+ # function_name string qualified name of enclosing function
+ # exc_vars (string * 3) local exception variables
+ # reraise_used boolean body contains reraise statement
+
+ def analyse_declarations(self, env):
+ if self.exc_target:
+ self.exc_target.analyse_target_declaration(env)
+ if self.tb_target:
+ self.tb_target.analyse_target_declaration(env)
+ self.body.analyse_declarations(env)
+
+ def analyse_expressions(self, env):
+ genv = env.global_scope()
+ self.function_name = env.qualified_name
+ if self.pattern:
+ self.pattern.analyse_expressions(env)
+ self.pattern = self.pattern.coerce_to_pyobject(env)
+ self.match_flag = env.allocate_temp(PyrexTypes.c_int_type)
+ self.pattern.release_temp(env)
+ env.release_temp(self.match_flag)
+ self.exc_vars = [env.allocate_temp(py_object_type) for i in xrange(3)]
+ self.exc_value = self.analyse_target(env, self.exc_target, 1)
+ self.tb_value = self.analyse_target(env, self.tb_target, 2)
+ old_reraise_used = env.reraise_used
+ env.reraise_used = False
+ self.body.analyse_expressions(env)
+ self.reraise_used = env.reraise_used
+ env.reraise_used = old_reraise_used
+ for var in self.exc_vars:
+ env.release_temp(var)
+
+ def analyse_target(self, env, target, var_no):
+ if target:
+ import ExprNodes
+ value = ExprNodes.ExcValueNode(self.pos, env, self.exc_vars[var_no])
+ value.allocate_temps(env)
+ target.analyse_target_expression(env, value)
+ return value
+
+ def generate_handling_code(self, code, end_label):
+ code.mark_pos(self.pos)
+ if self.pattern:
+ self.pattern.generate_evaluation_code(code)
+ code.putln(
+ "%s = PyErr_ExceptionMatches(%s);" % (
+ self.match_flag,
+ self.pattern.py_result()))
+ self.pattern.generate_disposal_code(code)
+ code.putln(
+ "if (%s) {" %
+ self.match_flag)
+ else:
+ code.putln(
+ "/*except:*/ {")
+ any_bindings = self.exc_target or self.tb_target
+ exc_vars_used = any_bindings or self.reraise_used
+ if exc_vars_used:
+ if any_bindings:
+ code.putln(
+ '%s; __Pyx_AddTraceback("%s");' % (
+ code.error_setup(self.pos),
+ self.function_name))
+ exc_args = "&%s, &%s, &%s" % tuple(self.exc_vars)
+ code.putln("PyErr_Fetch(%s);" % exc_args)
+ if any_bindings:
+ code.use_utility_code(normalize_exception_utility_code)
+ code.putln("if (__Pyx_NormalizeException(%s) < 0) %s" % (exc_args,
+ code.error_goto(self.pos)))
+ if self.exc_target:
+ self.exc_value.generate_evaluation_code(code)
+ self.exc_target.generate_assignment_code(self.exc_value, code)
+ if self.tb_target:
+ self.tb_value.generate_evaluation_code(code)
+ self.tb_target.generate_assignment_code(self.tb_value, code)
+ old_exc_vars = code.exc_vars
+ code.exc_vars = self.exc_vars
+ self.body.generate_execution_code(code)
+ code.exc_vars = old_exc_vars
+ if exc_vars_used:
+ for var in self.exc_vars:
+ code.putln("Py_XDECREF(%s); %s = 0;" % (var, var))
+ code.put_goto(end_label)
+ code.putln(
+ "}")
+
+
+class TryFinallyStatNode(StatNode):
+ # try ... finally statement
+ #
+ # body StatNode
+ # finally_clause StatNode
+ #
+ # cleanup_list [Entry] temps to clean up on error
+ #
+ # The plan is that we funnel all continue, break
+ # return and error gotos into the beginning of the
+ # finally block, setting a variable to remember which
+ # one we're doing. At the end of the finally block, we
+ # switch on the variable to figure out where to go.
+ # In addition, if we're doing an error, we save the
+ # exception on entry to the finally block and restore
+ # it on exit.
+
+ preserve_exception = 1
+
+ disallow_continue_in_try_finally = 0
+ # There doesn't seem to be any point in disallowing
+ # continue in the try block, since we have no problem
+ # handling it.
+
+ def analyse_declarations(self, env):
+ self.body.analyse_declarations(env)
+ self.finally_clause.analyse_declarations(env)
+
+ def analyse_expressions(self, env):
+ self.body.analyse_expressions(env)
+ self.cleanup_list = env.free_temp_entries[:]
+ self.finally_clause.analyse_expressions(env)
+ self.gil_check(env)
+
+ gil_message = "Try-finally statement"
+
+ def generate_execution_code(self, code):
+ old_error_label = code.error_label
+ old_labels = code.all_new_labels()
+ new_labels = code.get_all_labels()
+ new_error_label = code.error_label
+ catch_label = code.new_label()
+ code.putln(
+ "/*try:*/ {")
+ if self.disallow_continue_in_try_finally:
+ was_in_try_finally = code.in_try_finally
+ code.in_try_finally = 1
+ self.body.generate_execution_code(code)
+ if self.disallow_continue_in_try_finally:
+ code.in_try_finally = was_in_try_finally
+ code.putln(
+ "}")
+ code.putln(
+ "/*finally:*/ {")
+ cases_used = []
+ error_label_used = 0
+ for i, new_label in enumerate(new_labels):
+ if new_label in code.labels_used:
+ cases_used.append(i)
+ if new_label == new_error_label:
+ error_label_used = 1
+ error_label_case = i
+ if cases_used:
+ code.putln(
+ "int __pyx_why;")
+ if error_label_used and self.preserve_exception:
+ code.putln(
+ "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
+ code.putln(
+ "int %s;" % Naming.exc_lineno_name)
+ code.use_label(catch_label)
+ code.putln(
+ "__pyx_why = 0; goto %s;" % catch_label)
+ for i in cases_used:
+ new_label = new_labels[i]
+ #if new_label and new_label <> "<try>":
+ if new_label == new_error_label and self.preserve_exception:
+ self.put_error_catcher(code,
+ new_error_label, i+1, catch_label)
+ else:
+ code.putln(
+ "%s: __pyx_why = %s; goto %s;" % (
+ new_label,
+ i+1,
+ catch_label))
+ code.put_label(catch_label)
+ code.set_all_labels(old_labels)
+ if error_label_used:
+ code.new_error_label()
+ finally_error_label = code.error_label
+ self.finally_clause.generate_execution_code(code)
+ if error_label_used:
+ if finally_error_label in code.labels_used and self.preserve_exception:
+ over_label = code.new_label()
+ code.put_goto(over_label);
+ code.put_label(finally_error_label)
+ code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
+ for var in Naming.exc_vars:
+ code.putln("Py_XDECREF(%s);" % var)
+ code.putln("}")
+ code.put_goto(old_error_label)
+ code.put_label(over_label)
+ code.error_label = old_error_label
+ if cases_used:
+ code.putln(
+ "switch (__pyx_why) {")
+ for i in cases_used:
+ old_label = old_labels[i]
+ if old_label == old_error_label and self.preserve_exception:
+ self.put_error_uncatcher(code, i+1, old_error_label)
+ else:
+ code.use_label(old_label)
+ code.putln(
+ "case %s: goto %s;" % (
+ i+1,
+ old_label))
+ code.putln(
+ "}")
+ code.putln(
+ "}")
+
+ def put_error_catcher(self, code, error_label, i, catch_label):
+ code.putln(
+ "%s: {" %
+ error_label)
+ code.putln(
+ "__pyx_why = %s;" %
+ i)
+ code.put_var_xdecrefs_clear(self.cleanup_list)
+ code.putln(
+ "PyErr_Fetch(&%s, &%s, &%s);" %
+ Naming.exc_vars)
+ code.putln(
+ "%s = %s;" % (
+ Naming.exc_lineno_name, Naming.lineno_cname))
+ #code.putln(
+ # "goto %s;" %
+ # catch_label)
+ code.put_goto(catch_label)
+ code.putln(
+ "}")
+
+ def put_error_uncatcher(self, code, i, error_label):
+ code.putln(
+ "case %s: {" %
+ i)
+ code.putln(
+ "PyErr_Restore(%s, %s, %s);" %
+ Naming.exc_vars)
+ code.putln(
+ "%s = %s;" % (
+ Naming.lineno_cname, Naming.exc_lineno_name))
+ for var in Naming.exc_vars:
+ code.putln(
+ "%s = 0;" %
+ var)
+ code.put_goto(error_label)
+ code.putln(
+ "}")
+
+
+class GILStatNode(TryFinallyStatNode):
+ # 'with gil' or 'with nogil' statement
+ #
+ # state string 'gil' or 'nogil'
+
+ preserve_exception = 0
+
+ def __init__(self, pos, state, body):
+ self.state = state
+ TryFinallyStatNode.__init__(self, pos,
+ body = body,
+ finally_clause = GILExitNode(pos, state = state))
+
+ def analyse_expressions(self, env):
+ env.global_scope().gil_used = 1
+ was_nogil = env.nogil
+ env.nogil = 1
+ TryFinallyStatNode.analyse_expressions(self, env)
+ env.nogil = was_nogil
+
+ def gil_check(self, env):
+ pass
+
+ def generate_execution_code(self, code):
+ code.putln("/*with %s:*/ {" % self.state)
+ if self.state == 'gil':
+ code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
+ else:
+ code.putln("PyThreadState *_save;")
+ code.putln("Py_UNBLOCK_THREADS")
+ TryFinallyStatNode.generate_execution_code(self, code)
+ code.putln("}")
+
+
+class GILExitNode(StatNode):
+ # Used as the 'finally' block in a GILStatNode
+ #
+ # state string 'gil' or 'nogil'
+
+ def analyse_expressions(self, env):
+ pass
+
+ def generate_execution_code(self, code):
+ if self.state == 'gil':
+ code.putln("PyGILState_Release();")
+ else:
+ code.putln("Py_BLOCK_THREADS")
+
+
+class CImportStatNode(StatNode):
+ # cimport statement
+ #
+ # module_name string Qualified name of module being imported
+ # as_name string or None Name specified in "as" clause, if any
+
+ def analyse_declarations(self, env):
+ module_scope = env.find_module(self.module_name, self.pos)
+ if "." in self.module_name:
+ names = self.module_name.split(".")
+ top_name = names[0]
+ top_module_scope = env.context.find_submodule(top_name)
+ module_scope = top_module_scope
+ for name in names[1:]:
+ submodule_scope = module_scope.find_submodule(name)
+ module_scope.declare_module(name, submodule_scope, self.pos)
+ if not self.as_name:
+ env.add_imported_module(submodule_scope)
+ module_scope = submodule_scope
+ if self.as_name:
+ env.declare_module(self.as_name, module_scope, self.pos)
+ env.add_imported_module(module_scope)
+ else:
+ env.declare_module(top_name, top_module_scope, self.pos)
+ env.add_imported_module(top_module_scope)
+ else:
+ name = self.as_name or self.module_name
+ env.declare_module(name, module_scope, self.pos)
+ env.add_imported_module(module_scope)
+
+ def analyse_expressions(self, env):
+ pass
+
+ def generate_execution_code(self, code):
+ pass
+
+
+class FromCImportStatNode(StatNode):
+ # from ... cimport statement
+ #
+ # module_name string Qualified name of module
+ # imported_names Parsing.ImportedName Names to be imported
+
+ def analyse_declarations(self, env):
+ module_scope = env.find_module(self.module_name, self.pos)
+ env.add_imported_module(module_scope)
+ for imp in self.imported_names:
+ kind = imp.kind
+ #entry = module_scope.find(imp.name, imp.pos)
+ entry = module_scope.lookup(imp.name)
+ if entry:
+ if kind and not self.declaration_matches(entry, kind):
+ entry.redeclared(pos)
+ else:
+ if kind == 'struct' or kind == 'union':
+ entry = module_scope.declare_struct_or_union(imp.name,
+ kind = kind, scope = None, typedef_flag = 0, pos = imp.pos)
+ elif kind == 'class':
+ entry = module_scope.declare_c_class(imp.name, pos = imp.pos,
+ module_name = self.module_name)
+ else:
+ error(imp.pos, "Name '%s' not declared in module '%s'"
+ % (imp.name, self.module_name))
+ if entry:
+ local_name = imp.as_name or imp.name
+ env.add_imported_entry(local_name, entry, imp.pos)
+
+ def declaration_matches(self, entry, kind):
+ if not entry.is_type:
+ return 0
+ type = entry.type
+ if kind == 'class':
+ if not type.is_extension_type:
+ return 0
+ else:
+ if not type.is_struct_or_union:
+ return 0
+ if kind <> type.kind:
+ return 0
+ return 1
+
+ def analyse_expressions(self, env):
+ pass
+
+ def generate_execution_code(self, code):
+ pass
+
+
+class FromImportStatNode(StatNode):
+ # from ... import statement
+ #
+ # module ImportNode
+ # items [(string, NameNode)]
+ # #interned_items [(string, NameNode)]
+ # item PyTempNode used internally
+
+ def analyse_declarations(self, env):
+ for _, target in self.items:
+ target.analyse_target_declaration(env)
+
+ def analyse_expressions(self, env):
+ import ExprNodes
+ self.module.analyse_expressions(env)
+ self.item = ExprNodes.PyTempNode(self.pos, env)
+ self.item.allocate_temp(env)
+ #self.interned_items = []
+ for name, target in self.items:
+ #self.interned_items.append((env.intern(name), target))
+ target.analyse_target_expression(env, None)
+ self.module.release_temp(env)
+ self.item.release_temp(env)
+
+ def generate_execution_code(self, code):
+ self.module.generate_evaluation_code(code)
+ #for cname, target in self.interned_items:
+ for name, target in self.items:
+ cname = code.intern(name)
+ code.putln(
+ '%s = PyObject_GetAttr(%s, %s); if (!%s) %s' % (
+ self.item.result(),
+ self.module.py_result(),
+ cname,
+ self.item.result(),
+ code.error_goto(self.pos)))
+ target.generate_assignment_code(self.item, code)
+ self.module.generate_disposal_code(code)
+
+#------------------------------------------------------------------------------------
+#
+# Runtime support code
+#
+#------------------------------------------------------------------------------------
+
+#utility_function_predeclarations = \
+#"""
+#typedef struct {PyObject **p; char *s;} __Pyx_InternTabEntry; /*proto*/
+#typedef struct {PyObject **p; char *s; long n;} __Pyx_StringTabEntry; /*proto*/
+#"""
+
+utility_function_predeclarations = \
+"""
+typedef struct {PyObject **p; int i; char *s; long n;} __Pyx_StringTabEntry; /*proto*/
+"""
+
+#get_name_predeclaration = \
+#"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
+
+#get_name_interned_predeclaration = \
+#"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
+
+#------------------------------------------------------------------------------------
+
+printing_utility_code = [
+"""
+static int __Pyx_PrintItem(PyObject *); /*proto*/
+static int __Pyx_PrintNewline(void); /*proto*/
+""",r"""
+static PyObject *__Pyx_GetStdout(void) {
+ PyObject *f = PySys_GetObject("stdout");
+ if (!f) {
+ PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
+ }
+ return f;
+}
+
+static int __Pyx_PrintItem(PyObject *v) {
+ PyObject *f;
+
+ if (!(f = __Pyx_GetStdout()))
+ return -1;
+ if (PyFile_SoftSpace(f, 1)) {
+ if (PyFile_WriteString(" ", f) < 0)
+ return -1;
+ }
+ if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
+ return -1;
+ if (PyString_Check(v)) {
+ char *s = PyString_AsString(v);
+ Py_ssize_t len = PyString_Size(v);
+ if (len > 0 &&
+ isspace(Py_CHARMASK(s[len-1])) &&
+ s[len-1] != ' ')
+ PyFile_SoftSpace(f, 0);
+ }
+ return 0;
+}
+
+static int __Pyx_PrintNewline(void) {
+ PyObject *f;
+
+ if (!(f = __Pyx_GetStdout()))
+ return -1;
+ if (PyFile_WriteString("\n", f) < 0)
+ return -1;
+ PyFile_SoftSpace(f, 0);
+ return 0;
+}
+"""]
+
+#------------------------------------------------------------------------------------
+
+# The following function is based on do_raise() from ceval.c.
+
+raise_utility_code = [
+"""
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
+""","""
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
+ if (value == Py_None)
+ value = NULL;
+ if (tb == Py_None)
+ tb = NULL;
+ Py_XINCREF(type);
+ Py_XINCREF(value);
+ Py_XINCREF(tb);
+ if (tb && !PyTraceBack_Check(tb)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: arg 3 must be a traceback or None");
+ goto raise_error;
+ }
+ #if PY_VERSION_HEX < 0x02050000
+ if (!PyClass_Check(type))
+ #else
+ if (!PyType_Check(type))
+ #endif
+ {
+ /* Raising an instance. The value should be a dummy. */
+ if (value) {
+ PyErr_SetString(PyExc_TypeError,
+ "instance exception may not have a separate value");
+ goto raise_error;
+ }
+ /* Normalize to raise <class>, <instance> */
+ value = type;
+ #if PY_VERSION_HEX < 0x02050000
+ if (PyInstance_Check(type)) {
+ type = (PyObject*) ((PyInstanceObject*)type)->in_class;
+ Py_INCREF(type);
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception must be an old-style class or instance");
+ goto raise_error;
+ }
+ #else
+ type = (PyObject*) type->ob_type;
+ Py_INCREF(type);
+ if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+ PyErr_SetString(PyExc_TypeError,
+ "raise: exception class must be a subclass of BaseException");
+ goto raise_error;
+ }
+ #endif
+ }
+ PyErr_Restore(type, value, tb);
+ return;
+raise_error:
+ Py_XDECREF(value);
+ Py_XDECREF(type);
+ Py_XDECREF(tb);
+ return;
+}
+"""]
+
+#------------------------------------------------------------------------------------
+
+#reraise_utility_code = [
+#"""
+#static void __Pyx_ReRaise(void); /*proto*/
+#""","""
+#static void __Pyx_ReRaise(void) {
+# PyThreadState *tstate = PyThreadState_Get();
+# PyObject *type = tstate->exc_type;
+# PyObject *value = tstate->exc_value;
+# PyObject *tb = tstate->exc_traceback;
+# Py_XINCREF(type);
+# Py_XINCREF(value);
+# Py_XINCREF(tb);
+# PyErr_Restore(type, value, tb);
+#}
+#"""]
+
+#------------------------------------------------------------------------------------
+
+arg_type_test_utility_code = [
+"""
+static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, char *name); /*proto*/
+""","""
+static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, char *name) {
+ if (!type) {
+ PyErr_Format(PyExc_SystemError, "Missing type object");
+ return 0;
+ }
+ if ((none_allowed && obj == Py_None) || PyObject_TypeCheck(obj, type))
+ return 1;
+ PyErr_Format(PyExc_TypeError,
+ "Argument '%s' has incorrect type (expected %s, got %s)",
+ name, type->tp_name, obj->ob_type->tp_name);
+ return 0;
+}
+"""]
+
+#------------------------------------------------------------------------------------
+#
+# __Pyx_GetStarArgs splits the args tuple and kwds dict into two parts
+# each, one part suitable for passing to PyArg_ParseTupleAndKeywords,
+# and the other containing any extra arguments. On success, replaces
+# the borrowed references *args and *kwds with references to a new
+# tuple and dict, and passes back new references in *args2 and *kwds2.
+# Does not touch any of its arguments on failure.
+#
+# Any of *kwds, args2 and kwds2 may be 0 (but not args or kwds). If
+# *kwds == 0, it is not changed. If kwds2 == 0 and *kwds != 0, a new
+# reference to the same dictionary is passed back in *kwds.
+#
+# If rqd_kwds is not 0, it is an array of booleans corresponding to the
+# names in kwd_list, indicating required keyword arguments. If any of
+# these are not present in kwds, an exception is raised.
+#
+
+get_starargs_utility_code = [
+"""
+static int __Pyx_GetStarArgs(PyObject **args, PyObject **kwds, char *kwd_list[], \
+ Py_ssize_t nargs, PyObject **args2, PyObject **kwds2, char rqd_kwds[]); /*proto*/
+""","""
+static int __Pyx_GetStarArgs(
+ PyObject **args,
+ PyObject **kwds,
+ char *kwd_list[],
+ Py_ssize_t nargs,
+ PyObject **args2,
+ PyObject **kwds2,
+ char rqd_kwds[])
+{
+ PyObject *x = 0, *args1 = 0, *kwds1 = 0;
+ int i;
+ char **p;
+
+ if (args2)
+ *args2 = 0;
+ if (kwds2)
+ *kwds2 = 0;
+
+ if (args2) {
+ args1 = PyTuple_GetSlice(*args, 0, nargs);
+ if (!args1)
+ goto bad;
+ *args2 = PyTuple_GetSlice(*args, nargs, PyTuple_GET_SIZE(*args));
+ if (!*args2)
+ goto bad;
+ }
+ else if (PyTuple_GET_SIZE(*args) > nargs) {
+ int m = nargs;
+ int n = PyTuple_GET_SIZE(*args);
+ PyErr_Format(PyExc_TypeError,
+ "function takes at most %d positional arguments (%d given)",
+ m, n);
+ goto bad;
+ }
+ else {
+ args1 = *args;
+ Py_INCREF(args1);
+ }
+
+ if (rqd_kwds && !*kwds)
+ for (i = 0, p = kwd_list; *p; i++, p++)
+ if (rqd_kwds[i])
+ goto missing_kwarg;
+
+ if (kwds2) {
+ if (*kwds) {
+ kwds1 = PyDict_New();
+ if (!kwds1)
+ goto bad;
+ *kwds2 = PyDict_Copy(*kwds);
+ if (!*kwds2)
+ goto bad;
+ for (i = 0, p = kwd_list; *p; i++, p++) {
+ x = PyDict_GetItemString(*kwds, *p);
+ if (x) {
+ if (PyDict_SetItemString(kwds1, *p, x) < 0)
+ goto bad;
+ if (PyDict_DelItemString(*kwds2, *p) < 0)
+ goto bad;
+ }
+ else if (rqd_kwds && rqd_kwds[i])
+ goto missing_kwarg;
+ }
+ }
+ else {
+ *kwds2 = PyDict_New();
+ if (!*kwds2)
+ goto bad;
+ }
+ }
+ else {
+ kwds1 = *kwds;
+ Py_XINCREF(kwds1);
+ if (rqd_kwds && *kwds)
+ for (i = 0, p = kwd_list; *p; i++, p++)
+ if (rqd_kwds[i] && !PyDict_GetItemString(*kwds, *p))
+ goto missing_kwarg;
+ }
+
+ *args = args1;
+ *kwds = kwds1;
+ return 0;
+missing_kwarg:
+ PyErr_Format(PyExc_TypeError,
+ "required keyword argument '%s' is missing", *p);
+bad:
+ Py_XDECREF(args1);
+ Py_XDECREF(kwds1);
+ if (args2) {
+ Py_XDECREF(*args2);
+ }
+ if (kwds2) {
+ Py_XDECREF(*kwds2);
+ }
+ return -1;
+}
+"""]
+
+#------------------------------------------------------------------------------------
+
+unraisable_exception_utility_code = [
+"""
+static void __Pyx_WriteUnraisable(char *name); /*proto*/
+""","""
+static void __Pyx_WriteUnraisable(char *name) {
+ PyObject *old_exc, *old_val, *old_tb;
+ PyObject *ctx;
+ PyGILState_STATE state = PyGILState_Ensure();
+ PyErr_Fetch(&old_exc, &old_val, &old_tb);
+ ctx = PyString_FromString(name);
+ PyErr_Restore(old_exc, old_val, old_tb);
+ if (!ctx)
+ ctx = Py_None;
+ PyErr_WriteUnraisable(ctx);
+ PyGILState_Release(state);
+}
+"""]
+
+#------------------------------------------------------------------------------------
+
+traceback_utility_code = [
+"""
+static void __Pyx_AddTraceback(char *funcname); /*proto*/
+""","""
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+
+static void __Pyx_AddTraceback(char *funcname) {
+ PyObject *py_srcfile = 0;
+ PyObject *py_funcname = 0;
+ PyObject *py_globals = 0;
+ PyObject *empty_tuple = 0;
+ PyObject *empty_string = 0;
+ PyCodeObject *py_code = 0;
+ PyFrameObject *py_frame = 0;
+
+ py_srcfile = PyString_FromString(%(FILENAME)s);
+ if (!py_srcfile) goto bad;
+ py_funcname = PyString_FromString(funcname);
+ if (!py_funcname) goto bad;
+ py_globals = PyModule_GetDict(%(GLOBALS)s);
+ if (!py_globals) goto bad;
+ empty_tuple = PyTuple_New(0);
+ if (!empty_tuple) goto bad;
+ empty_string = PyString_FromString("");
+ if (!empty_string) goto bad;
+ py_code = PyCode_New(
+ 0, /*int argcount,*/
+ 0, /*int nlocals,*/
+ 0, /*int stacksize,*/
+ 0, /*int flags,*/
+ empty_string, /*PyObject *code,*/
+ empty_tuple, /*PyObject *consts,*/
+ empty_tuple, /*PyObject *names,*/
+ empty_tuple, /*PyObject *varnames,*/
+ empty_tuple, /*PyObject *freevars,*/
+ empty_tuple, /*PyObject *cellvars,*/
+ py_srcfile, /*PyObject *filename,*/
+ py_funcname, /*PyObject *name,*/
+ %(LINENO)s, /*int firstlineno,*/
+ empty_string /*PyObject *lnotab*/
+ );
+ if (!py_code) goto bad;
+ py_frame = PyFrame_New(
+ PyThreadState_Get(), /*PyThreadState *tstate,*/
+ py_code, /*PyCodeObject *code,*/
+ py_globals, /*PyObject *globals,*/
+ 0 /*PyObject *locals*/
+ );
+ if (!py_frame) goto bad;
+ py_frame->f_lineno = %(LINENO)s;
+ PyTraceBack_Here(py_frame);
+bad:
+ Py_XDECREF(py_srcfile);
+ Py_XDECREF(py_funcname);
+ Py_XDECREF(empty_tuple);
+ Py_XDECREF(empty_string);
+ Py_XDECREF(py_code);
+ Py_XDECREF(py_frame);
+}
+""" % {
+ 'FILENAME': Naming.filename_cname,
+ 'LINENO': Naming.lineno_cname,
+ 'GLOBALS': Naming.module_cname
+}]
+
+#------------------------------------------------------------------------------------
+
+set_vtable_utility_code = [
+"""
+static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
+""","""
+static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
+ PyObject *pycobj = 0;
+ int result;
+
+ pycobj = PyCObject_FromVoidPtr(vtable, 0);
+ if (!pycobj)
+ goto bad;
+ if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
+ goto bad;
+ result = 0;
+ goto done;
+
+bad:
+ result = -1;
+done:
+ Py_XDECREF(pycobj);
+ return result;
+}
+"""]
+
+#------------------------------------------------------------------------------------
+
+get_vtable_utility_code = [
+"""
+static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
+""",r"""
+static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
+ int result;
+ PyObject *pycobj;
+
+ pycobj = PyMapping_GetItemString(dict, "__pyx_vtable__");
+ if (!pycobj)
+ goto bad;
+ *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
+ if (!*(void **)vtabptr)
+ goto bad;
+ result = 0;
+ goto done;
+
+bad:
+ result = -1;
+done:
+ Py_XDECREF(pycobj);
+ return result;
+}
+"""]
+
+#------------------------------------------------------------------------------------
+
+#init_intern_tab_utility_code = [
+#"""
+#static int __Pyx_InternStrings(__Pyx_InternTabEntry *t); /*proto*/
+#""","""
+#static int __Pyx_InternStrings(__Pyx_InternTabEntry *t) {
+# while (t->p) {
+# *t->p = PyString_InternFromString(t->s);
+# if (!*t->p)
+# return -1;
+# ++t;
+# }
+# return 0;
+#}
+#"""]
+
+#init_intern_tab_utility_code = [
+#"""
+#static int __Pyx_InternStrings(PyObject **t[]); /*proto*/
+#""","""
+#static int __Pyx_InternStrings(PyObject **t[]) {
+# while (*t) {
+# PyString_InternInPlace(*t);
+# if (!**t)
+# return -1;
+# ++t;
+# }
+# return 0;
+#}
+#"""]
+
+#------------------------------------------------------------------------------------
+
+init_string_tab_utility_code = [
+"""
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+""","""
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+ while (t->p) {
+ *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+ if (!*t->p)
+ return -1;
+ if (t->i)
+ PyString_InternInPlace(t->p);
+ ++t;
+ }
+ return 0;
+}
+"""]
+
+#------------------------------------------------------------------------------------
+
+#get_exception_utility_code = [
+#"""
+#static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
+#""","""
+#static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
+# PyThreadState *tstate = PyThreadState_Get();
+# PyObject *old_type, *old_value, *old_tb;
+# PyErr_Fetch(type, value, tb);
+# PyErr_NormalizeException(type, value, tb);
+# if (PyErr_Occurred())
+# goto bad;
+# if (!*tb) {
+# printf("no traceback\n");
+# *tb = Py_None;
+# Py_INCREF(*tb);
+# }
+##if 1
+# Py_INCREF(*type);
+# Py_INCREF(*value);
+# Py_INCREF(*tb);
+# old_type = tstate->exc_type;
+# old_value = tstate->exc_value;
+# old_tb = tstate->exc_traceback;
+# tstate->exc_type = *type;
+# tstate->exc_value = *value;
+# tstate->exc_traceback = *tb;
+# Py_XDECREF(old_type);
+# Py_XDECREF(old_value);
+# Py_XDECREF(old_tb);
+##endif
+# return 0;
+#bad:
+# Py_XDECREF(*type);
+# Py_XDECREF(*value);
+# Py_XDECREF(*tb);
+# return -1;
+#}
+#"""]
+
+#------------------------------------------------------------------------------------
+
+#get_exception_utility_code = [
+#"""
+#static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
+#""","""
+#static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
+# PyErr_Fetch(type, value, tb);
+# PyErr_NormalizeException(type, value, tb);
+# if (PyErr_Occurred())
+# goto bad;
+# if (!*tb) {
+# *tb = Py_None;
+# Py_INCREF(*tb);
+# }
+# return 0;
+#bad:
+# Py_XDECREF(*type);
+# Py_XDECREF(*value);
+# Py_XDECREF(*tb);
+# return -1;
+#}
+#"""]
+
+#------------------------------------------------------------------------------------
+
+normalize_exception_utility_code = [
+"""
+static int __Pyx_NormalizeException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
+""","""
+static int __Pyx_NormalizeException(PyObject **type, PyObject **value, PyObject **tb) {
+ PyErr_NormalizeException(type, value, tb);
+ if (PyErr_Occurred())
+ goto bad;
+ if (!*tb) {
+ *tb = Py_None;
+ Py_INCREF(*tb);
+ }
+ return 0;
+bad:
+ Py_XDECREF(*type);
+ Py_XDECREF(*value);
+ Py_XDECREF(*tb);
+ return -1;
+}
+"""]
+
+#------------------------------------------------------------------------------------
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Options.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Options.py
new file mode 100644
index 00000000..0754fa24
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Options.py
@@ -0,0 +1,5 @@
+#
+# Pyrex - Compilation-wide options
+#
+
+intern_names = 1 # Intern global variable and attribute names
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Parsing.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Parsing.py
new file mode 100644
index 00000000..b7b9e4b5
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Parsing.py
@@ -0,0 +1,2142 @@
+#
+# Pyrex Parser
+#
+
+import os, re
+from string import join, replace
+from types import ListType, TupleType
+from Scanning import PyrexScanner
+import Nodes
+import ExprNodes
+from ModuleNode import ModuleNode
+from Errors import warning, error, InternalError
+
+
+class Ctx(object):
+ # Parsing context
+ level = 'other'
+ visibility = 'private'
+ extern_from = False
+ cdef_flag = 0
+ cplus_flag = 0
+ typedef_flag = 0
+ api = 0
+ nogil = 0
+
+ def __init__(self, **kwds):
+ self.__dict__.update(kwds)
+
+ def __call__(self, **kwds):
+ ctx = Ctx()
+ d = ctx.__dict__
+ d.update(self.__dict__)
+ d.update(kwds)
+ return ctx
+
+ def cplus_check(self, pos):
+ #if self.visibility <> 'extern':
+ # error(pos, "C++ declarations must be 'extern'")
+ if self.cplus_flag and not self.extern_from:
+ error(pos, "C++ declarations must be in an 'extern from' block")
+
+
+def p_ident(s, message = "Expected an identifier"):
+ if s.sy == 'IDENT':
+ name = s.systring
+ s.next()
+ return name
+ else:
+ s.error(message)
+
+def p_ident_list(s):
+ names = []
+ while s.sy == 'IDENT':
+ names.append(s.systring)
+ s.next()
+ if s.sy <> ',':
+ break
+ s.next()
+ return names
+
+#------------------------------------------
+#
+# Expressions
+#
+#------------------------------------------
+
+def p_binop_expr(s, ops, p_sub_expr):
+ n1 = p_sub_expr(s)
+ while s.sy in ops:
+ op = s.sy
+ pos = s.position()
+ s.next()
+ n2 = p_sub_expr(s)
+ n1 = ExprNodes.binop_node(pos, op, n1, n2)
+ return n1
+
+#test: and_test ('or' and_test)* | lambdef
+
+def p_simple_expr(s):
+ return p_rassoc_binop_expr(s, ('or',), p_and_test)
+
+def p_rassoc_binop_expr(s, ops, p_subexpr):
+ n1 = p_subexpr(s)
+ if s.sy in ops:
+ pos = s.position()
+ op = s.sy
+ s.next()
+ n2 = p_rassoc_binop_expr(s, ops, p_subexpr)
+ n1 = ExprNodes.binop_node(pos, op, n1, n2)
+ return n1
+
+#and_test: not_test ('and' not_test)*
+
+def p_and_test(s):
+ #return p_binop_expr(s, ('and',), p_not_test)
+ return p_rassoc_binop_expr(s, ('and',), p_not_test)
+
+#not_test: 'not' not_test | comparison
+
+def p_not_test(s):
+ if s.sy == 'not':
+ pos = s.position()
+ s.next()
+ return ExprNodes.NotNode(pos, operand = p_not_test(s))
+ else:
+ return p_comparison(s)
+
+#comparison: expr (comp_op expr)*
+#comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
+
+def p_comparison(s):
+ n1 = p_bit_expr(s)
+ if s.sy in comparison_ops:
+ pos = s.position()
+ op = p_cmp_op(s)
+ n2 = p_bit_expr(s)
+ n1 = ExprNodes.PrimaryCmpNode(pos,
+ operator = op, operand1 = n1, operand2 = n2)
+ if s.sy in comparison_ops:
+ n1.cascade = p_cascaded_cmp(s)
+ return n1
+
+def p_cascaded_cmp(s):
+ pos = s.position()
+ op = p_cmp_op(s)
+ n2 = p_bit_expr(s)
+ result = ExprNodes.CascadedCmpNode(pos,
+ operator = op, operand2 = n2)
+ if s.sy in comparison_ops:
+ result.cascade = p_cascaded_cmp(s)
+ return result
+
+def p_cmp_op(s):
+ if s.sy == 'not':
+ s.next()
+ s.expect('in')
+ op = 'not_in'
+ elif s.sy == 'is':
+ s.next()
+ if s.sy == 'not':
+ s.next()
+ op = 'is_not'
+ else:
+ op = 'is'
+ else:
+ op = s.sy
+ s.next()
+ if op == '<>':
+ op = '!='
+ return op
+
+comparison_ops = (
+ '<', '>', '==', '>=', '<=', '<>', '!=',
+ 'in', 'is', 'not'
+)
+
+#expr: xor_expr ('|' xor_expr)*
+
+def p_bit_expr(s):
+ return p_binop_expr(s, ('|',), p_xor_expr)
+
+#xor_expr: and_expr ('^' and_expr)*
+
+def p_xor_expr(s):
+ return p_binop_expr(s, ('^',), p_and_expr)
+
+#and_expr: shift_expr ('&' shift_expr)*
+
+def p_and_expr(s):
+ return p_binop_expr(s, ('&',), p_shift_expr)
+
+#shift_expr: arith_expr (('<<'|'>>') arith_expr)*
+
+def p_shift_expr(s):
+ return p_binop_expr(s, ('<<', '>>'), p_arith_expr)
+
+#arith_expr: term (('+'|'-') term)*
+
+def p_arith_expr(s):
+ return p_binop_expr(s, ('+', '-'), p_term)
+
+#term: factor (('*'|'/'|'%') factor)*
+
+def p_term(s):
+ return p_binop_expr(s, ('*', '/', '%'), p_factor)
+
+#factor: ('+'|'-'|'~'|'&'|typecast|sizeof) factor | power
+
+def p_factor(s):
+ sy = s.sy
+ if sy in ('+', '-', '~'):
+ op = s.sy
+ pos = s.position()
+ s.next()
+ return ExprNodes.unop_node(pos, op, p_factor(s))
+ elif sy == '&':
+ pos = s.position()
+ s.next()
+ arg = p_factor(s)
+ return ExprNodes.AmpersandNode(pos, operand = arg)
+ elif sy == "<":
+ return p_typecast(s)
+ elif sy == 'IDENT' and s.systring == "sizeof":
+ return p_sizeof(s)
+ else:
+ return p_power(s)
+
+def p_typecast(s):
+ # s.sy == "<"
+ pos = s.position()
+ s.next()
+ base_type = p_c_base_type(s)
+ declarator = p_c_declarator(s, empty = 1)
+ s.expect(">")
+ operand = p_factor(s)
+ return ExprNodes.TypecastNode(pos,
+ base_type = base_type,
+ declarator = declarator,
+ operand = operand)
+
+def p_sizeof(s):
+ # s.sy == ident "sizeof"
+ pos = s.position()
+ s.next()
+ s.expect('(')
+ if looking_at_type(s):
+ base_type = p_c_base_type(s)
+ declarator = p_c_declarator(s, empty = 1)
+ node = ExprNodes.SizeofTypeNode(pos,
+ base_type = base_type, declarator = declarator)
+ else:
+ operand = p_simple_expr(s)
+ node = ExprNodes.SizeofVarNode(pos, operand = operand)
+ s.expect(')')
+ return node
+
+#power: atom trailer* ('**' factor)*
+
+def p_power(s):
+ n1 = p_primitive(s)
+ if s.sy == '**':
+ pos = s.position()
+ s.next()
+ n2 = p_factor(s)
+ n1 = ExprNodes.binop_node(pos, '**', n1, n2)
+ return n1
+
+def p_primitive(s):
+ n = p_atom(s)
+ while s.sy in ('(', '[', '.'):
+ n = p_trailer(s, n)
+ return n
+
+#trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
+
+def p_trailer(s, node1):
+ pos = s.position()
+ if s.sy == '(':
+ return p_call(s, node1)
+ elif s.sy == '[':
+ return p_index(s, node1)
+ else: # s.sy == '.'
+ s.next()
+ name = p_ident(s)
+ return ExprNodes.AttributeNode(pos,
+ obj = node1, attribute = name)
+
+# arglist: argument (',' argument)* [',']
+# argument: [test '='] test # Really [keyword '='] test
+
+def p_call(s, function):
+ # s.sy == '('
+ pos = s.position()
+ s.next()
+ positional_args = []
+ keyword_args = []
+ star_arg = None
+ starstar_arg = None
+ while s.sy not in ('*', '**', ')'):
+ arg = p_simple_expr(s)
+ if s.sy == '=':
+ s.next()
+ if not arg.is_name:
+ s.error("Expected an identifier before '='",
+ pos = arg.pos)
+ keyword = ExprNodes.StringNode(arg.pos,
+ value = arg.name)
+ arg = p_simple_expr(s)
+ keyword_args.append((keyword, arg))
+ else:
+ if keyword_args:
+ s.error("Non-keyword arg following keyword arg",
+ pos = arg.pos)
+ positional_args.append(arg)
+ if s.sy <> ',':
+ break
+ s.next()
+ if s.sy == '*':
+ s.next()
+ star_arg = p_simple_expr(s)
+ if s.sy == ',':
+ s.next()
+ if s.sy == '**':
+ s.next()
+ starstar_arg = p_simple_expr(s)
+ if s.sy == ',':
+ s.next()
+ s.expect(')')
+ if not (keyword_args or star_arg or starstar_arg):
+ return ExprNodes.SimpleCallNode(pos,
+ function = function,
+ args = positional_args)
+ else:
+ arg_tuple = None
+ keyword_dict = None
+ if positional_args or not star_arg:
+ arg_tuple = ExprNodes.TupleNode(pos,
+ args = positional_args)
+ if star_arg:
+ star_arg_tuple = ExprNodes.AsTupleNode(pos, arg = star_arg)
+ if arg_tuple:
+ arg_tuple = ExprNodes.binop_node(pos,
+ operator = '+', operand1 = arg_tuple,
+ operand2 = star_arg_tuple)
+ else:
+ arg_tuple = star_arg_tuple
+ if keyword_args:
+ keyword_dict = ExprNodes.DictNode(pos,
+ key_value_pairs = keyword_args)
+ return ExprNodes.GeneralCallNode(pos,
+ function = function,
+ positional_args = arg_tuple,
+ keyword_args = keyword_dict,
+ starstar_arg = starstar_arg)
+
+#lambdef: 'lambda' [varargslist] ':' test
+
+#subscriptlist: subscript (',' subscript)* [',']
+
+def p_index(s, base):
+ # s.sy == '['
+ pos = s.position()
+ s.next()
+ subscripts = p_subscript_list(s)
+ if len(subscripts) == 1 and len(subscripts[0]) == 2:
+ start, stop = subscripts[0]
+ result = ExprNodes.SliceIndexNode(pos,
+ base = base, start = start, stop = stop)
+ else:
+ indexes = make_slice_nodes(pos, subscripts)
+ if len(indexes) == 1:
+ index = indexes[0]
+ else:
+ index = ExprNodes.TupleNode(pos, args = indexes)
+ result = ExprNodes.IndexNode(pos,
+ base = base, index = index)
+ s.expect(']')
+ return result
+
+def p_subscript_list(s):
+ items = [p_subscript(s)]
+ while s.sy == ',':
+ s.next()
+ if s.sy == ']':
+ break
+ items.append(p_subscript(s))
+ return items
+
+#subscript: '.' '.' '.' | test | [test] ':' [test] [':' [test]]
+
+def p_subscript(s):
+ # Parse a subscript and return a list of
+ # 1, 2 or 3 ExprNodes, depending on how
+ # many slice elements were encountered.
+ pos = s.position()
+ if s.sy == '.':
+ expect_ellipsis(s)
+ return [ExprNodes.EllipsisNode(pos)]
+ else:
+ start = p_slice_element(s, (':',))
+ if s.sy <> ':':
+ return [start]
+ s.next()
+ stop = p_slice_element(s, (':', ',', ']'))
+ if s.sy <> ':':
+ return [start, stop]
+ s.next()
+ step = p_slice_element(s, (':', ',', ']'))
+ return [start, stop, step]
+
+def p_slice_element(s, follow_set):
+ # Simple expression which may be missing iff
+ # it is followed by something in follow_set.
+ if s.sy not in follow_set:
+ return p_simple_expr(s)
+ else:
+ return None
+
+def expect_ellipsis(s):
+ s.expect('.')
+ s.expect('.')
+ s.expect('.')
+
+def make_slice_nodes(pos, subscripts):
+ # Convert a list of subscripts as returned
+ # by p_subscript_list into a list of ExprNodes,
+ # creating SliceNodes for elements with 2 or
+ # more components.
+ result = []
+ for subscript in subscripts:
+ if len(subscript) == 1:
+ result.append(subscript[0])
+ else:
+ result.append(make_slice_node(pos, *subscript))
+ return result
+
+def make_slice_node(pos, start, stop = None, step = None):
+ if not start:
+ start = ExprNodes.NoneNode(pos)
+ if not stop:
+ stop = ExprNodes.NoneNode(pos)
+ if not step:
+ step = ExprNodes.NoneNode(pos)
+ return ExprNodes.SliceNode(pos,
+ start = start, stop = stop, step = step)
+
+#atom: '(' [testlist] ')' | '[' [listmaker] ']' | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING+
+
+def p_atom(s):
+ pos = s.position()
+ sy = s.sy
+ if sy == '(':
+ s.next()
+ if s.sy == ')':
+ result = ExprNodes.TupleNode(pos, args = [])
+ else:
+ result = p_expr(s)
+ s.expect(')')
+ return result
+ elif sy == '[':
+ return p_list_maker(s)
+ elif sy == '{':
+ return p_dict_maker(s)
+ elif sy == '`':
+ return p_backquote_expr(s)
+ elif sy == 'INT':
+ value = s.systring
+ s.next()
+ return ExprNodes.IntNode(pos, value = value)
+ elif sy == 'LONG':
+ value = s.systring
+ s.next()
+ return ExprNodes.LongNode(pos, value = value)
+ elif sy == 'FLOAT':
+ value = s.systring
+ s.next()
+ return ExprNodes.FloatNode(pos, value = value)
+ elif sy == 'IMAG':
+ value = s.systring[:-1]
+ s.next()
+ return ExprNodes.ImagNode(pos, value = value)
+ elif sy == 'STRING' or sy == 'BEGIN_STRING':
+ kind, value = p_cat_string_literal(s)
+ if kind == 'c':
+ return ExprNodes.CharNode(pos, value = value)
+ else:
+ return ExprNodes.StringNode(pos, value = value)
+ elif sy == 'IDENT':
+ name = s.systring
+ s.next()
+ if name == "None":
+ return ExprNodes.NoneNode(pos)
+ elif name == "new" and s.sy == 'IDENT':
+ return p_new_call(s)
+ else:
+ return p_name_atom(s, name)
+ elif sy == 'NULL':
+ s.next()
+ return ExprNodes.NullNode(pos)
+ else:
+ s.error("Expected an identifier or literal")
+
+def p_new_call(s):
+ node = p_primitive(s)
+ if isinstance(node, ExprNodes.SimpleCallNode):
+ node.is_new = 1
+ else:
+ error(s.position(), "'new' must be followed by a C++ constructor call")
+ return node
+
+def p_name(s):
+ if s.sy == 'IDENT':
+ pos = s.position()
+ name = s.systring
+ s.next()
+ return ExprNodes.NameNode(pos, name = name)
+ else:
+ s.error("Expected a variable name")
+
+def p_name_atom(s, name):
+ pos = s.position()
+ if not s.compile_time_expr:
+ try:
+ value = s.compile_time_env.lookup_here(name)
+ except KeyError:
+ pass
+ else:
+ rep = repr(value)
+ if isinstance(value, int):
+ return ExprNodes.IntNode(pos, value = rep)
+ elif isinstance(value, long):
+ return ExprNodes.LongNode(pos, value = rep)
+ elif isinstance(value, float):
+ return ExprNodes.FloatNode(pos, value = rep)
+ elif isinstance(value, str):
+ return ExprNodes.StringNode(pos, value = rep[1:-1])
+ else:
+ error(pos, "Invalid type for compile-time constant: %s"
+ % value.__class__.__name__)
+ return ExprNodes.NameNode(pos, name = name)
+
+def p_cat_string_literal(s):
+ # A sequence of one or more adjacent string literals.
+ # Returns (kind, value) where kind in ('', 'c', 'r')
+ kind, value = p_string_literal(s)
+ if kind <> 'c':
+ strings = [value]
+ while s.sy == 'STRING' or s.sy == 'BEGIN_STRING':
+ next_kind, next_value = p_string_literal(s)
+ if next_kind == 'c':
+ self.error(
+ "Cannot concatenate char literal with another string or char literal")
+ strings.append(next_value)
+ value = ''.join(strings)
+ return kind, value
+
+def p_opt_string_literal(s):
+ if s.sy == 'STRING' or s.sy == 'BEGIN_STRING':
+ return p_string_literal(s)
+ else:
+ return None
+
+def p_string_literal(s):
+ # A single string or char literal.
+ # Returns (kind, value) where kind in ('', 'c', 'r')
+ if s.sy == 'STRING':
+ value = unquote(s.systring)
+ s.next()
+ return value
+ # s.sy == 'BEGIN_STRING'
+ pos = s.position()
+ #is_raw = s.systring[:1].lower() == "r"
+ kind = s.systring[:1].lower()
+ if kind not in "cr":
+ kind = ''
+ chars = []
+ while 1:
+ s.next()
+ sy = s.sy
+ #print "p_string_literal: sy =", sy, repr(s.systring) ###
+ if sy == 'CHARS':
+ systr = s.systring
+ if len(systr) == 1 and systr in "'\"\n":
+ chars.append('\\')
+ chars.append(systr)
+ elif sy == 'ESCAPE':
+ systr = s.systring
+ if kind == 'r':
+ if systr == '\\\n':
+ chars.append(r'\\\n')
+ elif systr == r'\"':
+ chars.append(r'\\\"')
+ elif systr == r'\\':
+ chars.append(r'\\\\')
+ else:
+ chars.append('\\' + systr)
+ else:
+ c = systr[1]
+ if c in "'\"\\abfnrtv01234567":
+ chars.append(systr)
+ elif c == 'x':
+ chars.append('\\x0' + systr[2:])
+ elif c == '\n':
+ pass
+ else:
+ chars.append(r'\\' + systr[1:])
+ elif sy == 'NEWLINE':
+ chars.append(r'\n')
+ elif sy == 'END_STRING':
+ break
+ elif sy == 'EOF':
+ s.error("Unclosed string literal", pos = pos)
+ else:
+ s.error(
+ "Unexpected token %r:%r in string literal" %
+ (sy, s.systring))
+ s.next()
+ value = join(chars, '')
+ #print "p_string_literal: value =", repr(value) ###
+ return kind, value
+
+def unquote(s):
+ is_raw = 0
+ if s[:1].lower() == "r":
+ is_raw = 1
+ s = s[1:]
+ q = s[:3]
+ if q == '"""' or q == "'''":
+ s = s[3:-3]
+ else:
+ s = s[1:-1]
+ if is_raw:
+ s = s.replace('\\', '\\\\')
+ s = s.replace('\n', '\\\n')
+ else:
+ # Split into double quotes, newlines, escape sequences
+ # and spans of regular chars
+ l1 = re.split(r'((?:\\[0-7]{1,3})|(?:\\x[0-9A-Fa-f]{2})|(?:\\.)|(?:\\\n)|(?:\n)|")', s)
+ print "unquote: l1 =", l1 ###
+ l2 = []
+ for item in l1:
+ if item == '"' or item == '\n':
+ l2.append('\\' + item)
+ elif item == '\\\n':
+ pass
+ elif item[:1] == '\\':
+ if len(item) == 2:
+ if item[1] in '"\\abfnrtv':
+ l2.append(item)
+ else:
+ l2.append(item[1])
+ elif item[1:2] == 'x':
+ l2.append('\\x0' + item[2:])
+ else:
+ # octal escape
+ l2.append(item)
+ else:
+ l2.append(item)
+ s = "".join(l2)
+ return s
+
+def p_list_maker(s):
+ # s.sy == '['
+ pos = s.position()
+ s.next()
+ exprs = p_simple_expr_list(s)
+ s.expect(']')
+ return ExprNodes.ListNode(pos, args = exprs)
+
+#dictmaker: test ':' test (',' test ':' test)* [',']
+
+def p_dict_maker(s):
+ # s.sy == '{'
+ pos = s.position()
+ s.next()
+ items = []
+ while s.sy <> '}':
+ key = p_simple_expr(s)
+ s.expect(':')
+ value = p_simple_expr(s)
+ items.append((key, value))
+ if s.sy <> ',':
+ break
+ s.next()
+ s.expect('}')
+ return ExprNodes.DictNode(pos, key_value_pairs = items)
+
+def p_backquote_expr(s):
+ # s.sy == '`'
+ pos = s.position()
+ s.next()
+ arg = p_expr(s)
+ s.expect('`')
+ return ExprNodes.BackquoteNode(pos, arg = arg)
+
+#testlist: test (',' test)* [',']
+
+def p_simple_expr_list(s):
+ exprs = []
+ while s.sy not in expr_terminators:
+ exprs.append(p_simple_expr(s))
+ if s.sy <> ',':
+ break
+ s.next()
+ return exprs
+
+def p_expr(s):
+ pos = s.position()
+ expr = p_simple_expr(s)
+ if s.sy == ',':
+ s.next()
+ exprs = [expr] + p_simple_expr_list(s)
+ return ExprNodes.TupleNode(pos, args = exprs)
+ else:
+ return expr
+
+expr_terminators = (')', ']', '}', ':', '=', 'NEWLINE')
+
+#-------------------------------------------------------
+#
+# Statements
+#
+#-------------------------------------------------------
+
+def p_global_statement(s):
+ # assume s.sy == 'global'
+ pos = s.position()
+ s.next()
+ names = p_ident_list(s)
+ return Nodes.GlobalNode(pos, names = names)
+
+inplace_operators = ('+=', '-=', '*=', '/=', '%=', '**=',
+ '<<=', '>>=', '&=', '^=', '|=')
+
+def p_expression_or_assignment(s):
+ pos = s.position()
+ expr = p_expr(s)
+ if s.sy in inplace_operators:
+ return p_inplace_operation(s, expr)
+ elif s.sy <> '=':
+ if isinstance(expr, ExprNodes.StringNode):
+ return Nodes.PassStatNode(expr.pos)
+ else:
+ return Nodes.ExprStatNode(expr.pos, expr = expr)
+ else:
+ expr_list = [expr]
+ while s.sy == '=':
+ s.next()
+ expr_list.append(p_expr(s))
+ expr_list_list = []
+ flatten_parallel_assignments(expr_list, expr_list_list)
+ nodes = []
+ for expr_list in expr_list_list:
+ lhs_list = expr_list[:-1]
+ rhs = expr_list[-1]
+ if len(lhs_list) == 1:
+ node = Nodes.SingleAssignmentNode(rhs.pos,
+ lhs = lhs_list[0], rhs = rhs)
+ else:
+ node = Nodes.CascadedAssignmentNode(rhs.pos,
+ lhs_list = lhs_list, rhs = rhs)
+ nodes.append(node)
+ if len(nodes) == 1:
+ return nodes[0]
+ else:
+ return Nodes.ParallelAssignmentNode(nodes[0].pos, stats = nodes)
+
+def p_inplace_operation(s, lhs):
+ pos = s.position()
+ op = s.sy
+ s.next()
+ rhs = p_expr(s)
+ return Nodes.AugmentedAssignmentNode(pos, lhs = lhs, operator = op, rhs = rhs)
+
+def flatten_parallel_assignments(input, output):
+ # The input is a list of expression nodes, representing
+ # the LHSs and RHS of one (possibly cascaded) assignment
+ # statement. If they are all sequence constructors with
+ # the same number of arguments, rearranges them into a
+ # list of equivalent assignments between the individual
+ # elements. This transformation is applied recursively.
+ size = find_parallel_assignment_size(input)
+ if size >= 0:
+ for i in range(size):
+ new_exprs = [expr.args[i] for expr in input]
+ flatten_parallel_assignments(new_exprs, output)
+ else:
+ output.append(input)
+
+def find_parallel_assignment_size(input):
+ # The input is a list of expression nodes. If
+ # they are all sequence constructors with the same number
+ # of arguments, return that number, else return -1.
+ # Produces an error message if they are all sequence
+ # constructors but not all the same size.
+ for expr in input:
+ if not expr.is_sequence_constructor:
+ return -1
+ rhs = input[-1]
+ rhs_size = len(rhs.args)
+ for lhs in input[:-1]:
+ lhs_size = len(lhs.args)
+ if lhs_size <> rhs_size:
+ error(lhs.pos, "Unpacking sequence of wrong size (expected %d, got %d)"
+ % (lhs_size, rhs_size))
+ return -1
+ return rhs_size
+
+def p_print_statement(s):
+ # s.sy == 'print'
+ pos = s.position()
+ s.next()
+ if s.sy == '>>':
+ s.error("'print >>' not yet implemented")
+ args = []
+ ewc = 0
+ if s.sy not in ('NEWLINE', 'EOF'):
+ args.append(p_simple_expr(s))
+ while s.sy == ',':
+ s.next()
+ if s.sy in ('NEWLINE', 'EOF'):
+ ewc = 1
+ break
+ args.append(p_simple_expr(s))
+ return Nodes.PrintStatNode(pos,
+ args = args, ends_with_comma = ewc)
+
+def p_del_statement(s):
+ # s.sy == 'del'
+ pos = s.position()
+ s.next()
+ args = p_simple_expr_list(s)
+ return Nodes.DelStatNode(pos, args = args)
+
+def p_pass_statement(s, with_newline = 0):
+ pos = s.position()
+ s.expect('pass')
+ if with_newline:
+ s.expect_newline("Expected a newline")
+ return Nodes.PassStatNode(pos)
+
+def p_break_statement(s):
+ # s.sy == 'break'
+ pos = s.position()
+ s.next()
+ return Nodes.BreakStatNode(pos)
+
+def p_continue_statement(s):
+ # s.sy == 'continue'
+ pos = s.position()
+ s.next()
+ return Nodes.ContinueStatNode(pos)
+
+def p_return_statement(s):
+ # s.sy == 'return'
+ pos = s.position()
+ s.next()
+ if s.sy not in statement_terminators:
+ value = p_expr(s)
+ else:
+ value = None
+ return Nodes.ReturnStatNode(pos, value = value)
+
+def p_raise_statement(s):
+ # s.sy == 'raise'
+ pos = s.position()
+ s.next()
+ exc_type = None
+ exc_value = None
+ exc_tb = None
+ if s.sy not in statement_terminators:
+ exc_type = p_simple_expr(s)
+ if s.sy == ',':
+ s.next()
+ exc_value = p_simple_expr(s)
+ if s.sy == ',':
+ s.next()
+ exc_tb = p_simple_expr(s)
+ if exc_type or exc_value or exc_tb:
+ return Nodes.RaiseStatNode(pos,
+ exc_type = exc_type,
+ exc_value = exc_value,
+ exc_tb = exc_tb)
+ else:
+ return Nodes.ReraiseStatNode(pos)
+
+def p_import_statement(s):
+ # s.sy in ('import', 'cimport')
+ pos = s.position()
+ kind = s.sy
+ s.next()
+ items = [p_dotted_name(s, as_allowed = 1)]
+ while s.sy == ',':
+ s.next()
+ items.append(p_dotted_name(s, as_allowed = 1))
+ stats = []
+ for pos, target_name, dotted_name, as_name in items:
+ if kind == 'cimport':
+ stat = Nodes.CImportStatNode(pos,
+ module_name = dotted_name,
+ as_name = as_name)
+ else:
+ if as_name and "." in dotted_name:
+ name_list = ExprNodes.ListNode(pos, args = [
+ ExprNodes.StringNode(pos, value = "*")])
+ else:
+ name_list = None
+ stat = Nodes.SingleAssignmentNode(pos,
+ lhs = ExprNodes.NameNode(pos,
+ name = as_name or target_name),
+ rhs = ExprNodes.ImportNode(pos,
+ module_name = ExprNodes.StringNode(pos,
+ value = dotted_name),
+ name_list = name_list))
+ stats.append(stat)
+ return Nodes.StatListNode(pos, stats = stats)
+
+def p_from_import_statement(s, ctx):
+ # s.sy == 'from'
+ pos = s.position()
+ s.next()
+ (dotted_name_pos, _, dotted_name, _) = \
+ p_dotted_name(s, as_allowed = 0)
+ if s.sy in ('import', 'cimport'):
+ kind = s.sy
+ s.next()
+ else:
+ s.error("Expected 'import' or 'cimport'")
+ if kind == 'cimport' and ctx.level not in ('module', 'module_pxd'):
+ s.error("cimport statement not allowed in this context")
+ if s.sy == '*':
+ s.error("'import *' not supported")
+ is_cimport = kind == 'cimport'
+ imported_names = [p_imported_name(s, is_cimport)]
+ while s.sy == ',':
+ s.next()
+ imported_names.append(p_imported_name(s, is_cimport))
+ if kind == 'cimport':
+ for imp in imported_names:
+ local_name = imp.as_name or imp.name
+ s.add_type_name(local_name)
+ return Nodes.FromCImportStatNode(pos,
+ module_name = dotted_name,
+ imported_names = imported_names)
+ else:
+ imported_name_strings = []
+ items = []
+ for imp in imported_names:
+ imported_name_strings.append(
+ ExprNodes.StringNode(imp.pos, value = imp.name))
+ items.append(
+ (imp.name,
+ ExprNodes.NameNode(imp.pos,
+ name = imp.as_name or imp.name)))
+ import_list = ExprNodes.ListNode(
+ imported_names[0].pos, args = imported_name_strings)
+ return Nodes.FromImportStatNode(pos,
+ module = ExprNodes.ImportNode(dotted_name_pos,
+ module_name = ExprNodes.StringNode(dotted_name_pos,
+ value = dotted_name),
+ name_list = import_list),
+ items = items)
+
+class ImportedName(object):
+ # pos
+ # name
+ # as_name
+ # kind 'class', 'struct', 'union', None
+
+ def __init__(self, pos, name, as_name, kind):
+ self.pos = pos
+ self.name = name
+ self.as_name = as_name
+ self.kind = kind
+
+imported_name_kinds = ('class', 'struct', 'union')
+
+def p_imported_name(s, is_cimport):
+ pos = s.position()
+ kind = None
+ if is_cimport and s.systring in imported_name_kinds:
+ kind = s.systring
+ s.next()
+ name = p_ident(s)
+ as_name = p_as_name(s)
+ return ImportedName(pos, name, as_name, kind)
+
+def p_dotted_name(s, as_allowed):
+ pos = s.position()
+ target_name = p_ident(s)
+ as_name = None
+ names = [target_name]
+ while s.sy == '.':
+ s.next()
+ names.append(p_ident(s))
+ if as_allowed:
+ as_name = p_as_name(s)
+ return (pos, target_name, join(names, "."), as_name)
+
+def p_as_name(s):
+ if s.sy == 'IDENT' and s.systring == 'as':
+ s.next()
+ return p_ident(s)
+ else:
+ return None
+
+def p_assert_statement(s):
+ # s.sy == 'assert'
+ pos = s.position()
+ s.next()
+ cond = p_simple_expr(s)
+ if s.sy == ',':
+ s.next()
+ value = p_simple_expr(s)
+ else:
+ value = None
+ return Nodes.AssertStatNode(pos, cond = cond, value = value)
+
+statement_terminators = (';', 'NEWLINE', 'EOF')
+
+def p_if_statement(s):
+ # s.sy == 'if'
+ pos = s.position()
+ s.next()
+ if_clauses = [p_if_clause(s)]
+ while s.sy == 'elif':
+ s.next()
+ if_clauses.append(p_if_clause(s))
+ else_clause = p_else_clause(s)
+ return Nodes.IfStatNode(pos,
+ if_clauses = if_clauses, else_clause = else_clause)
+
+def p_if_clause(s):
+ pos = s.position()
+ test = p_simple_expr(s)
+ body = p_suite(s)
+ return Nodes.IfClauseNode(pos,
+ condition = test, body = body)
+
+def p_else_clause(s):
+ if s.sy == 'else':
+ s.next()
+ return p_suite(s)
+ else:
+ return None
+
+def p_while_statement(s):
+ # s.sy == 'while'
+ pos = s.position()
+ s.next()
+ test = p_simple_expr(s)
+ body = p_suite(s)
+ else_clause = p_else_clause(s)
+ return Nodes.WhileStatNode(pos,
+ condition = test, body = body,
+ else_clause = else_clause)
+
+def p_for_statement(s):
+ # s.sy == 'for'
+ pos = s.position()
+ s.next()
+ expr = p_for_expr(s)
+ if s.sy == 'in':
+ return p_standard_for_statement(s, expr)
+ elif s.sy in inequality_relations:
+ return p_integer_for_statement(s, expr)
+ elif s.sy == 'from':
+ #warning(pos, "Old-style integer for-loop is deprecated, use 'for x < i < y' instead")
+ return p_old_style_integer_for_statement(s, expr)
+ else:
+ s.error("Expected 'in' or an inequality relation")
+
+def p_standard_for_statement(s, target):
+ # s.sy == 'in'
+ s.next()
+ iterator = p_for_iterator(s)
+ body = p_suite(s)
+ else_clause = p_else_clause(s)
+ return Nodes.ForInStatNode(target.pos,
+ target = target,
+ iterator = iterator,
+ body = body,
+ else_clause = else_clause)
+
+def p_integer_for_statement(s, bound1):
+ rel1 = s.sy
+ s.next()
+ name_pos = s.position()
+ target = p_name(s)
+ rel2_pos = s.position()
+ rel2 = p_inequality_relation(s)
+ bound2 = p_bit_expr(s)
+ if rel1[0] <> rel2[0]:
+ error(rel2_pos,
+ "Relation directions in integer for-loop do not match")
+ body = p_suite(s)
+ else_clause = p_else_clause(s)
+ return Nodes.IntegerForStatNode(bound1.pos,
+ bound1 = bound1,
+ relation1 = rel1,
+ target = target,
+ relation2 = rel2,
+ bound2 = bound2,
+ body = body,
+ else_clause = else_clause)
+
+def p_old_style_integer_for_statement(s, target):
+ # s.sy == 'for'
+ s.next()
+ bound1 = p_bit_expr(s)
+ rel1 = p_inequality_relation(s)
+ name2_pos = s.position()
+ name2 = p_ident(s)
+ rel2_pos = s.position()
+ rel2 = p_inequality_relation(s)
+ bound2 = p_bit_expr(s)
+ if not target.is_name:
+ error(target.pos,
+ "Target of for-from statement must be a variable name")
+ elif name2 <> target.name:
+ error(name2_pos,
+ "Variable name in for-from range does not match target")
+ if rel1[0] <> rel2[0]:
+ error(rel2_pos,
+ "Relation directions in for-from do not match")
+ body = p_suite(s)
+ else_clause = p_else_clause(s)
+ return Nodes.IntegerForStatNode(bound1.pos,
+ bound1 = bound1,
+ relation1 = rel1,
+ target = target,
+ relation2 = rel2,
+ bound2 = bound2,
+ body = body,
+ else_clause = else_clause)
+
+def p_inequality_relation(s):
+ if s.sy in inequality_relations:
+ op = s.sy
+ s.next()
+ return op
+ else:
+ s.error("Expected one of '<', '<=', '>' '>='")
+
+inequality_relations = ('<', '<=', '>', '>=')
+
+def p_for_expr(s):
+ # Target of standard for-statement or first bound of integer for-statement
+ pos = s.position()
+ expr = p_bit_expr(s)
+ if s.sy == ',':
+ s.next()
+ exprs = [expr]
+ while s.sy <> 'in':
+ exprs.append(p_bit_expr(s))
+ if s.sy <> ',':
+ break
+ s.next()
+ return ExprNodes.TupleNode(pos, args = exprs)
+ else:
+ return expr
+
+def p_for_iterator(s):
+ pos = s.position()
+ expr = p_expr(s)
+ return ExprNodes.IteratorNode(pos, sequence = expr)
+
+def p_try_statement(s):
+ # s.sy == 'try'
+ pos = s.position()
+ s.next()
+ body = p_suite(s)
+ except_clauses = []
+ else_clause = None
+ if s.sy in ('except', 'else'):
+ while s.sy == 'except':
+ except_clauses.append(p_except_clause(s))
+ if s.sy == 'else':
+ s.next()
+ else_clause = p_suite(s)
+ return Nodes.TryExceptStatNode(pos,
+ body = body, except_clauses = except_clauses,
+ else_clause = else_clause)
+ elif s.sy == 'finally':
+ s.next()
+ finally_clause = p_suite(s)
+ return Nodes.TryFinallyStatNode(pos,
+ body = body, finally_clause = finally_clause)
+ else:
+ s.error("Expected 'except' or 'finally'")
+
+def p_except_clause(s):
+ # s.sy == 'except'
+ pos = s.position()
+ s.next()
+ exc_type = None
+ exc_value = None
+ tb_value = None
+ if s.sy <> ':':
+ exc_type = p_simple_expr(s)
+ if s.sy == ',':
+ s.next()
+ exc_value = p_simple_expr(s)
+ if s.sy == ',':
+ s.next()
+ tb_value = p_simple_expr(s)
+ body = p_suite(s)
+ return Nodes.ExceptClauseNode(pos,
+ pattern = exc_type, exc_target = exc_value, tb_target = tb_value, body = body)
+
+def p_include_statement(s, ctx):
+ pos = s.position()
+ s.next() # 'include'
+ _, include_file_name = p_string_literal(s)
+ s.expect_newline("Syntax error in include statement")
+ if s.compile_time_eval:
+ include_file_path = s.context.find_include_file(include_file_name, pos)
+ if include_file_path:
+ s.included_files.append(include_file_name)
+ f = open(include_file_path, "rU")
+ s2 = PyrexScanner(f, include_file_path, parent_scanner = s)
+ try:
+ tree = p_statement_list(s2, ctx)
+ finally:
+ f.close()
+ return tree
+ else:
+ return None
+ else:
+ return Nodes.PassStatNode(pos)
+
+def p_with_statement(s):
+ pos = s.position()
+ s.next() # 'with'
+# if s.sy == 'IDENT' and s.systring in ('gil', 'nogil'):
+ if s.sy == 'IDENT' and s.systring == 'nogil':
+ state = s.systring
+ s.next()
+ body = p_suite(s)
+ return Nodes.GILStatNode(pos, state = state, body = body)
+ else:
+ s.error("Only 'with nogil' implemented")
+
+def p_simple_statement(s, ctx):
+ if s.sy == 'global':
+ node = p_global_statement(s)
+ elif s.sy == 'print':
+ node = p_print_statement(s)
+ elif s.sy == 'del':
+ node = p_del_statement(s)
+ elif s.sy == 'break':
+ node = p_break_statement(s)
+ elif s.sy == 'continue':
+ node = p_continue_statement(s)
+ elif s.sy == 'return':
+ node = p_return_statement(s)
+ elif s.sy == 'raise':
+ node = p_raise_statement(s)
+ elif s.sy == 'cimport':
+ if ctx.level not in ('module', 'module_pxd'):
+ s.error("cimport statement not allowed in this context")
+ node = p_import_statement(s)
+ elif s.sy == 'import':
+ node = p_import_statement(s)
+ elif s.sy == 'from':
+ node = p_from_import_statement(s, ctx)
+ elif s.sy == 'assert':
+ node = p_assert_statement(s)
+ elif s.sy == 'pass':
+ node = p_pass_statement(s)
+ else:
+ node = p_expression_or_assignment(s)
+ return node
+
+def p_simple_statement_list(s, ctx):
+ # Parse a series of simple statements on one line
+ # separated by semicolons.
+ stat = p_simple_statement(s, ctx)
+ if s.sy == ';':
+ stats = [stat]
+ while s.sy == ';':
+ s.next()
+ if s.sy in ('NEWLINE', 'EOF'):
+ break
+ stats.append(p_simple_statement(s, ctx))
+ stat = Nodes.StatListNode(stats[0].pos, stats = stats)
+ s.expect_newline("Syntax error in simple statement list")
+ return stat
+
+def p_compile_time_expr(s):
+ old = s.compile_time_expr
+ s.compile_time_expr = 1
+ expr = p_expr(s)
+ s.compile_time_expr = old
+ return expr
+
+def p_DEF_statement(s):
+ pos = s.position()
+ denv = s.compile_time_env
+ s.next() # 'DEF'
+ name = p_ident(s)
+ s.expect('=')
+ expr = p_compile_time_expr(s)
+ value = expr.compile_time_value(denv)
+ #print "p_DEF_statement: %s = %r" % (name, value) ###
+ denv.declare(name, value)
+ s.expect_newline()
+ return Nodes.PassStatNode(pos)
+
+def p_IF_statement(s, ctx):
+ pos = s.position()
+ saved_eval = s.compile_time_eval
+ current_eval = saved_eval
+ denv = s.compile_time_env
+ result = None
+ while 1:
+ s.next() # 'IF' or 'ELIF'
+ expr = p_compile_time_expr(s)
+ s.compile_time_eval = current_eval and bool(expr.compile_time_value(denv))
+ body = p_suite(s, ctx)
+ if s.compile_time_eval:
+ result = body
+ current_eval = 0
+ if s.sy <> 'ELIF':
+ break
+ if s.sy == 'ELSE':
+ s.next()
+ s.compile_time_eval = current_eval
+ body = p_suite(s, ctx)
+ if current_eval:
+ result = body
+ if not result:
+ result = Nodes.PassStatNode(pos)
+ s.compile_time_eval = saved_eval
+ return result
+
+def p_statement(s, ctx):
+ pos = s.position()
+ cdef_flag = ctx.cdef_flag
+ if s.sy == 'ctypedef':
+ if ctx.level not in ('module', 'module_pxd'):
+ s.error("ctypedef statement not allowed here")
+ #if ctx.api:
+ # error(s.pos, "'api' not allowed with 'ctypedef'")
+ return p_ctypedef_statement(s, ctx)
+ elif s.sy == 'DEF':
+ return p_DEF_statement(s)
+ elif s.sy == 'IF':
+ return p_IF_statement(s, ctx)
+ else:
+ if s.sy == 'cdef':
+ cdef_flag = 1
+ s.next()
+ if s.sy == '+':
+ ctx = ctx(cplus_flag = 1)
+ s.next()
+ if cdef_flag:
+ if ctx.level not in ('module', 'module_pxd', 'function', 'c_class', 'c_class_pxd'):
+ s.error('cdef statement not allowed here')
+ return p_cdef_statement(s, ctx)
+ else:
+ if ctx.api:
+ error(s.pos, "'api' not allowed with this statement")
+ if s.sy == 'def':
+ if ctx.level not in ('module', 'class', 'c_class', 'property'):
+ s.error('def statement not allowed here')
+ return p_def_statement(s)
+ elif s.sy == 'class':
+ if ctx.level <> 'module':
+ s.error("class definition not allowed here")
+ return p_class_statement(s)
+ elif s.sy == 'include':
+ #if ctx.level not in ('module', 'module_pxd'):
+ # s.error("include statement not allowed here")
+ return p_include_statement(s, ctx)
+ elif ctx.level == 'c_class' and s.sy == 'IDENT' and s.systring == 'property':
+ return p_property_decl(s)
+ elif s.sy == 'pass' and ctx.level <> 'property':
+ return p_pass_statement(s, with_newline = 1)
+ else:
+ if ctx.level in ('c_class', 'c_class_pxd', 'property'):
+ s.error("Executable statement not allowed here")
+ if s.sy == 'if':
+ return p_if_statement(s)
+ elif s.sy == 'while':
+ return p_while_statement(s)
+ elif s.sy == 'for':
+ return p_for_statement(s)
+ elif s.sy == 'try':
+ return p_try_statement(s)
+ elif s.sy == 'with':
+ return p_with_statement(s)
+ else:
+ return p_simple_statement_list(s, ctx)
+
+def p_statement_list(s, ctx):
+ # Parse a series of statements separated by newlines.
+ pos = s.position()
+ stats = []
+ while s.sy not in ('DEDENT', 'EOF'):
+ stats.append(p_statement(s, ctx))
+ if len(stats) == 1:
+ return stats[0]
+ else:
+ return Nodes.StatListNode(pos, stats = stats)
+
+def p_suite(s, ctx = Ctx(), with_doc = 0, with_pseudo_doc = 0):
+ pos = s.position()
+ s.expect(':')
+ doc = None
+ stmts = []
+ if s.sy == 'NEWLINE':
+ s.next()
+ s.expect_indent()
+ if with_doc or with_pseudo_doc:
+ doc = p_doc_string(s)
+ body = p_statement_list(s, ctx)
+ s.expect_dedent()
+ else:
+ if ctx.api:
+ error(s.pos, "'api' not allowed with this statement")
+ if ctx.level in ('module', 'class', 'function', 'other'):
+ body = p_simple_statement_list(s, ctx)
+ else:
+ body = p_pass_statement(s)
+ s.expect_newline("Syntax error in declarations")
+ if with_doc:
+ return doc, body
+ else:
+ return body
+
+def p_c_base_type(s, self_flag = 0):
+ # If self_flag is true, this is the base type for the
+ # self argument of a C method of an extension type.
+ if s.sy == '(':
+ return p_c_complex_base_type(s)
+ else:
+ return p_c_simple_base_type(s, self_flag)
+
+def p_calling_convention(s):
+ if s.sy == 'IDENT' and s.systring in calling_convention_words:
+ result = s.systring
+ s.next()
+ return result
+ else:
+ return ""
+
+calling_convention_words = ("__stdcall", "__cdecl", "__fastcall")
+
+def p_c_complex_base_type(s):
+ # s.sy == '('
+ pos = s.position()
+ s.next()
+ base_type = p_c_base_type(s)
+ declarator = p_c_declarator(s, empty = 1)
+ s.expect(')')
+ return Nodes.CComplexBaseTypeNode(pos,
+ base_type = base_type, declarator = declarator)
+
+def p_c_simple_base_type(s, self_flag):
+ #print "p_c_simple_base_type: self_flag =", self_flag
+ is_basic = 0
+ signed = 1
+ longness = 0
+ module_path = []
+ pos = s.position()
+ if looking_at_base_type(s):
+ #print "p_c_simple_base_type: looking_at_base_type at", s.position()
+ is_basic = 1
+ signed, longness = p_sign_and_longness(s)
+ if s.sy == 'IDENT' and s.systring in basic_c_type_names:
+ name = s.systring
+ s.next()
+ else:
+ name = 'int'
+ elif s.looking_at_type_name() or looking_at_dotted_name(s):
+ #print "p_c_simple_base_type: looking_at_type_name at", s.position()
+ name = s.systring
+ s.next()
+ while s.sy == '.':
+ module_path.append(name)
+ s.next()
+ name = p_ident(s)
+ else:
+ #print "p_c_simple_base_type: not looking at type at", s.position()
+ name = None
+ return Nodes.CSimpleBaseTypeNode(pos,
+ name = name, module_path = module_path,
+ is_basic_c_type = is_basic, signed = signed,
+ longness = longness, is_self_arg = self_flag)
+
+def looking_at_type(s):
+ return looking_at_base_type(s) or s.looking_at_type_name()
+
+def looking_at_base_type(s):
+ #print "looking_at_base_type?", s.sy, s.systring, s.position()
+ return s.sy == 'IDENT' and s.systring in base_type_start_words
+
+def looking_at_dotted_name(s):
+ if s.sy == 'IDENT':
+ name = s.systring
+ s.next()
+ result = s.sy == '.'
+ s.put_back('IDENT', name)
+ return result
+ else:
+ return 0
+
+basic_c_type_names = ("void", "char", "int", "float", "double") #,
+ #"size_t", "Py_ssize_t")
+
+sign_and_longness_words = ("short", "long", "signed", "unsigned")
+
+base_type_start_words = \
+ basic_c_type_names + sign_and_longness_words
+
+def p_sign_and_longness(s):
+ signed = 1
+ longness = 0
+ while s.sy == 'IDENT' and s.systring in sign_and_longness_words:
+ if s.systring == 'unsigned':
+ signed = 0
+ elif s.systring == 'signed':
+ signed = 2
+ elif s.systring == 'short':
+ longness = -1
+ elif s.systring == 'long':
+ longness += 1
+ s.next()
+ return signed, longness
+
+def p_opt_cname(s):
+ literal = p_opt_string_literal(s)
+ if literal:
+ _, cname = literal
+ else:
+ cname = None
+ return cname
+
+def p_c_declarator(s, ctx = Ctx(), empty = 0, is_type = 0, cmethod_flag = 0, nonempty = 0,
+ calling_convention_allowed = 0):
+ # If empty is true, the declarator must be empty. If nonempty is true,
+ # the declarator must be nonempty. Otherwise we don't care.
+ # If cmethod_flag is true, then if this declarator declares
+ # a function, it's a C method of an extension type.
+ pos = s.position()
+ if s.sy == '(':
+ s.next()
+ if s.sy == ')' or looking_at_type(s):
+ base = Nodes.CNameDeclaratorNode(pos, name = "", cname = None)
+ result = p_c_func_declarator(s, pos, ctx, base, cmethod_flag)
+ else:
+ result = p_c_declarator(s, ctx, empty = empty, is_type = is_type,
+ cmethod_flag = cmethod_flag, nonempty = nonempty,
+ calling_convention_allowed = 1)
+ s.expect(')')
+ else:
+ result = p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag, nonempty)
+ if not calling_convention_allowed and result.calling_convention and s.sy <> '(':
+ error(s.position(), "%s on something that is not a function"
+ % result.calling_convention)
+ while s.sy in ('[', '('):
+ pos = s.position()
+ if s.sy == '[':
+ result = p_c_array_declarator(s, result)
+ else: # sy == '('
+ s.next()
+ result = p_c_func_declarator(s, pos, ctx, result, cmethod_flag)
+ cmethod_flag = 0
+ return result
+
+def p_c_array_declarator(s, base):
+ pos = s.position()
+ s.next() # '['
+ if s.sy <> ']':
+ dim = p_expr(s)
+ else:
+ dim = None
+ s.expect(']')
+ return Nodes.CArrayDeclaratorNode(pos, base = base, dimension = dim)
+
+def p_c_func_declarator(s, pos, ctx, base, cmethod_flag):
+ # Opening paren has already been skipped
+ args = p_c_arg_list(s, ctx, cmethod_flag = cmethod_flag,
+ nonempty_declarators = 0)
+ ellipsis = p_optional_ellipsis(s)
+ s.expect(')')
+ nogil = p_nogil(s)
+ exc_val, exc_check = p_exception_value_clause(s)
+ with_gil = p_with_gil(s)
+ return Nodes.CFuncDeclaratorNode(pos,
+ base = base, args = args, has_varargs = ellipsis,
+ exception_value = exc_val, exception_check = exc_check,
+ nogil = nogil or ctx.nogil or with_gil, with_gil = with_gil)
+
+def p_c_simple_declarator(s, ctx, empty, is_type, cmethod_flag, nonempty):
+ pos = s.position()
+ calling_convention = p_calling_convention(s)
+ if s.sy == '*':
+ s.next()
+ base = p_c_declarator(s, ctx, empty = empty, is_type = is_type,
+ cmethod_flag = cmethod_flag, nonempty = nonempty)
+ result = Nodes.CPtrDeclaratorNode(pos,
+ base = base)
+ elif s.sy == '**': # scanner returns this as a single token
+ s.next()
+ base = p_c_declarator(s, ctx, empty = empty, is_type = is_type,
+ cmethod_flag = cmethod_flag, nonempty = nonempty)
+ result = Nodes.CPtrDeclaratorNode(pos,
+ base = Nodes.CPtrDeclaratorNode(pos,
+ base = base))
+ else:
+ if s.sy == 'IDENT':
+ name = s.systring
+ if is_type:
+ s.add_type_name(name)
+ if empty:
+ error(s.position(), "Declarator should be empty")
+ s.next()
+ cname = p_opt_cname(s)
+ else:
+ if nonempty:
+ error(s.position(), "Empty declarator")
+ name = ""
+ cname = None
+ result = Nodes.CNameDeclaratorNode(pos,
+ name = name, cname = cname)
+ result.calling_convention = calling_convention
+ return result
+
+def p_nogil(s):
+ if s.sy == 'IDENT' and s.systring == 'nogil':
+ s.next()
+ return 1
+ else:
+ return 0
+
+def p_with_gil(s):
+ if s.sy == 'with':
+ s.next()
+ s.expect_keyword('gil')
+ return 1
+ else:
+ return 0
+
+def p_exception_value_clause(s):
+ exc_val = None
+ exc_check = 0
+ if s.sy == 'except':
+ s.next()
+ if s.sy == '*':
+ exc_check = 1
+ s.next()
+ else:
+ if s.sy == '?':
+ exc_check = 1
+ s.next()
+ exc_val = p_simple_expr(s)
+ return exc_val, exc_check
+
+c_arg_list_terminators = ('*', '**', '.', ')')
+
+def p_c_arg_list(s, ctx = Ctx(), in_pyfunc = 0, cmethod_flag = 0, nonempty_declarators = 0,
+ kw_only = 0):
+ # Comma-separated list of C argument declarations, possibly empty.
+ # May have a trailing comma.
+ args = []
+ is_self_arg = cmethod_flag
+ while s.sy not in c_arg_list_terminators:
+ args.append(p_c_arg_decl(s, ctx, in_pyfunc, is_self_arg,
+ nonempty = nonempty_declarators, kw_only = kw_only))
+ if s.sy <> ',':
+ break
+ s.next()
+ is_self_arg = 0
+ return args
+
+def p_optional_ellipsis(s):
+ if s.sy == '.':
+ expect_ellipsis(s)
+ return 1
+ else:
+ return 0
+
+def p_c_arg_decl(s, ctx, in_pyfunc, cmethod_flag = 0, nonempty = 0, kw_only = 0):
+ pos = s.position()
+ allow_none = None
+ #not_none = 0
+ default = None
+ base_type = p_c_base_type(s, cmethod_flag)
+ declarator = p_c_declarator(s, ctx, nonempty = nonempty)
+ if s.sy in ('or', 'not'):
+ or_not = s.sy
+ s.next()
+ if s.sy == 'IDENT' and s.systring == 'None':
+ s.next()
+ else:
+ s.error("Expected 'None'")
+ if not in_pyfunc:
+ error(pos, "'%s None' only allowed in Python functions" % or_not)
+ allow_none = or_not == 'or'
+ if s.sy == '=':
+ s.next()
+ default = p_simple_expr(s)
+ return Nodes.CArgDeclNode(pos,
+ base_type = base_type,
+ declarator = declarator,
+ allow_none = allow_none,
+ default = default,
+ kw_only = kw_only)
+
+def p_api(s):
+ if s.sy == 'IDENT' and s.systring == 'api':
+ s.next()
+ return 1
+ else:
+ return 0
+
+def p_cdef_statement(s, ctx):
+ ctx = ctx(cdef_flag = 1)
+ pos = s.position()
+ ctx.visibility = p_visibility(s, ctx.visibility)
+ ctx.api = ctx.api or p_api(s)
+ if ctx.api:
+ if ctx.visibility not in ('private', 'public'):
+ error(pos, "Cannot combine 'api' with '%s'" % visibility)
+ if ctx.visibility == 'extern' and s.sy == 'from':
+ return p_cdef_extern_block(s, pos, ctx)
+ if p_nogil(s):
+ ctx.nogil = 1
+ if s.sy == ':':
+ return p_cdef_block(s, ctx)
+ elif s.sy == 'class':
+ if ctx.level not in ('module', 'module_pxd'):
+ error(pos, "Extension type definition not allowed here")
+ #if api:
+ # error(pos, "'api' not allowed with extension class")
+ return p_c_class_definition(s, pos, ctx)
+ elif s.sy == 'IDENT' and s.systring in struct_union_or_enum:
+ if ctx.level not in ('module', 'module_pxd'):
+ error(pos, "C struct/union/enum definition not allowed here")
+ #if ctx.visibility == 'public':
+ # error(pos, "Public struct/union/enum definition not implemented")
+ #if ctx.api:
+ # error(pos, "'api' not allowed with '%s'" % s.systring)
+ if s.systring == "enum":
+ return p_c_enum_definition(s, pos, ctx)
+ else:
+ return p_c_struct_or_union_definition(s, pos, ctx)
+ elif s.sy == 'pass':
+ node = p_pass_statement(s)
+ s.expect_newline('Expected a newline')
+ return node
+ else:
+ return p_c_func_or_var_declaration(s, pos, ctx)
+
+def p_cdef_block(s, ctx):
+ return p_suite(s, ctx(cdef_flag = 1))
+
+def p_cdef_extern_block(s, pos, ctx):
+ include_file = None
+ s.expect('from')
+ if s.sy == '*':
+ s.next()
+ else:
+ _, include_file = p_string_literal(s)
+ ctx = ctx(cdef_flag = 1, visibility = 'extern', extern_from = True)
+ if p_nogil(s):
+ ctx.nogil = 1
+ body = p_suite(s, ctx)
+ return Nodes.CDefExternNode(pos,
+ include_file = include_file,
+ body = body)
+
+struct_union_or_enum = (
+ "struct", "union", "enum"
+)
+
+def p_c_enum_definition(s, pos, ctx):
+ # s.sy == ident 'enum'
+ s.next()
+ if s.sy == 'IDENT':
+ name = s.systring
+ s.next()
+ s.add_type_name(name)
+ cname = p_opt_cname(s)
+ else:
+ name = None
+ cname = None
+ items = None
+ s.expect(':')
+ items = []
+ if s.sy <> 'NEWLINE':
+ p_c_enum_line(s, items)
+ else:
+ s.next() # 'NEWLINE'
+ s.expect_indent()
+ while s.sy not in ('DEDENT', 'EOF'):
+ p_c_enum_line(s, items)
+ s.expect_dedent()
+ return Nodes.CEnumDefNode(pos, name = name, cname = cname, items = items,
+ typedef_flag = ctx.typedef_flag,
+ visibility = ctx.visibility,
+ in_pxd = ctx.level == 'module_pxd')
+
+def p_c_enum_line(s, items):
+ if s.sy <> 'pass':
+ p_c_enum_item(s, items)
+ while s.sy == ',':
+ s.next()
+ if s.sy in ('NEWLINE', 'EOF'):
+ break
+ p_c_enum_item(s, items)
+ else:
+ s.next()
+ s.expect_newline("Syntax error in enum item list")
+
+def p_c_enum_item(s, items):
+ pos = s.position()
+ name = p_ident(s)
+ cname = p_opt_cname(s)
+ value = None
+ if s.sy == '=':
+ s.next()
+ value = p_simple_expr(s)
+ items.append(Nodes.CEnumDefItemNode(pos,
+ name = name, cname = cname, value = value))
+
+def p_c_struct_or_union_definition(s, pos, ctx):
+ # s.sy == ident 'struct' or 'union'
+ ctx.cplus_check(pos)
+ kind = s.systring
+ s.next()
+ module_path, name = p_qualified_name(s)
+ bases = []
+ if s.sy == '(':
+ s.next()
+ while s.sy == 'IDENT':
+ bases.append(p_qualified_name(s))
+ if s.sy <> ',':
+ break
+ s.next()
+ s.expect(')')
+ if bases and not ctx.cplus_flag:
+ error(s, "Only C++ struct may have bases")
+ cname = p_opt_cname(s)
+ s.add_type_name(name)
+ attributes = None
+ if s.sy == ':':
+ s.next()
+ s.expect('NEWLINE')
+ s.expect_indent()
+ attributes = []
+ body_ctx = Ctx()
+ while s.sy <> 'DEDENT':
+ if s.sy <> 'pass':
+ attributes.append(p_c_func_or_var_declaration(s,
+ s.position(), body_ctx))
+ else:
+ s.next()
+ s.expect_newline("Expected a newline")
+ s.expect_dedent()
+ else:
+ s.expect_newline("Syntax error in struct or union definition")
+ return Nodes.CStructOrUnionDefNode(pos,
+ name = name, cname = cname, module_path = module_path,
+ kind = kind, attributes = attributes,
+ typedef_flag = ctx.typedef_flag,
+ visibility = ctx.visibility,
+ in_pxd = ctx.level == 'module_pxd',
+ cplus_flag = ctx.cplus_flag,
+ bases = bases)
+
+def p_visibility(s, prev_visibility):
+ pos = s.position()
+ visibility = prev_visibility
+ if s.sy == 'IDENT' and s.systring in ('extern', 'public', 'readonly'):
+ visibility = s.systring
+ if prev_visibility <> 'private' and visibility <> prev_visibility:
+ s.error("Conflicting visibility options '%s' and '%s'"
+ % (prev_visibility, visibility))
+ s.next()
+ return visibility
+
+def p_c_func_or_var_declaration(s, pos, ctx):
+ cmethod_flag = ctx.level in ('c_class', 'c_class_pxd')
+ base_type = p_c_base_type(s)
+ declarator = p_c_declarator(s, ctx, cmethod_flag = cmethod_flag, nonempty = 1)
+ if s.sy == ':':
+ if ctx.level not in ('module', 'c_class'):
+ s.error("C function definition not allowed here")
+ suite = p_suite(s, Ctx(level = 'function'), with_pseudo_doc = 1)
+ result = Nodes.CFuncDefNode(pos,
+ visibility = ctx.visibility,
+ base_type = base_type,
+ declarator = declarator,
+ body = suite,
+ api = ctx.api)
+ else:
+ #if api:
+ # error(pos, "'api' not allowed with variable declaration")
+ declarators = [declarator]
+ while s.sy == ',':
+ s.next()
+ if s.sy == 'NEWLINE':
+ break
+ declarator = p_c_declarator(s, ctx, cmethod_flag = cmethod_flag, nonempty = 1)
+ declarators.append(declarator)
+ s.expect_newline("Syntax error in C variable declaration")
+ result = Nodes.CVarDefNode(pos,
+ visibility = ctx.visibility,
+ base_type = base_type,
+ declarators = declarators,
+ in_pxd = ctx.level == 'module_pxd',
+ api = ctx.api)
+ return result
+
+def p_ctypedef_statement(s, ctx):
+ # s.sy == 'ctypedef'
+ pos = s.position()
+ s.next()
+ visibility = p_visibility(s, ctx.visibility)
+ api = p_api(s)
+ ctx = ctx(typedef_flag = 1, visibility = visibility)
+ if api:
+ ctx.api = 1
+ if s.sy == 'class':
+ return p_c_class_definition(s, pos, ctx)
+ elif s.sy == 'IDENT' and s.systring in ('struct', 'union', 'enum'):
+ if s.systring == 'enum':
+ return p_c_enum_definition(s, pos, ctx)
+ else:
+ return p_c_struct_or_union_definition(s, pos, ctx)
+ else:
+ base_type = p_c_base_type(s)
+ declarator = p_c_declarator(s, ctx, is_type = 1, nonempty = 1)
+ s.expect_newline("Syntax error in ctypedef statement")
+ return Nodes.CTypeDefNode(pos,
+ base_type = base_type, declarator = declarator,
+ visibility = ctx.visibility,
+ in_pxd = ctx.level == 'module_pxd')
+
+def p_def_statement(s):
+ # s.sy == 'def'
+ pos = s.position()
+ s.next()
+ name = p_ident(s)
+ #args = []
+ s.expect('(');
+ args = p_c_arg_list(s, in_pyfunc = 1, nonempty_declarators = 1)
+ star_arg = None
+ starstar_arg = None
+ if s.sy == '*':
+ s.next()
+ if s.sy == 'IDENT':
+ star_arg = p_py_arg_decl(s)
+ if s.sy == ',':
+ s.next()
+ args.extend(p_c_arg_list(s, in_pyfunc = 1,
+ nonempty_declarators = 1, kw_only = 1))
+ elif s.sy <>')':
+ s.error("Syntax error in Python function argument list")
+ if s.sy == '**':
+ s.next()
+ starstar_arg = p_py_arg_decl(s)
+ s.expect(')')
+ if p_nogil(s):
+ error(s.pos, "Python function cannot be declared nogil")
+ doc, body = p_suite(s, Ctx(level = 'function'), with_doc = 1)
+ return Nodes.DefNode(pos, name = name, args = args,
+ star_arg = star_arg, starstar_arg = starstar_arg,
+ doc = doc, body = body)
+
+def p_py_arg_decl(s):
+ pos = s.position()
+ name = p_ident(s)
+ return Nodes.PyArgDeclNode(pos, name = name)
+
+def p_class_statement(s):
+ # s.sy == 'class'
+ pos = s.position()
+ s.next()
+ class_name = p_ident(s)
+ if s.sy == '(':
+ s.next()
+ base_list = p_simple_expr_list(s)
+ s.expect(')')
+ else:
+ base_list = []
+ doc, body = p_suite(s, Ctx(level = 'class'), with_doc = 1)
+ return Nodes.PyClassDefNode(pos,
+ name = class_name,
+ bases = ExprNodes.TupleNode(pos, args = base_list),
+ doc = doc, body = body)
+
+def p_qualified_name(s):
+ path = []
+ name = p_ident(s)
+ while s.sy == '.':
+ s.next()
+ path.append(name)
+ name = p_ident(s)
+ return path, name
+
+class CClassOptions:
+
+ objstruct_cname = None
+ typeobj_cname = None
+ no_gc = 0
+
+
+def p_c_class_definition(s, pos, ctx):
+ # s.sy == 'class'
+ s.next()
+ module_path, class_name = p_qualified_name(s)
+ if module_path and s.sy == 'IDENT' and s.systring == 'as':
+ s.next()
+ as_name = p_ident(s)
+ else:
+ as_name = class_name
+ s.add_type_name(as_name)
+ options = CClassOptions()
+ base_class_module = None
+ base_class_name = None
+ if s.sy == '(':
+ s.next()
+ base_class_path, base_class_name = p_qualified_name(s)
+ if s.sy == ',':
+ s.error("C class may only have one base class")
+ s.expect(')')
+ base_class_module = ".".join(base_class_path)
+ if s.sy == '[':
+ p_c_class_options(s, ctx, options)
+ if s.sy == ':':
+ if ctx.level == 'module_pxd':
+ body_level = 'c_class_pxd'
+ else:
+ body_level = 'c_class'
+ doc, body = p_suite(s, Ctx(level = body_level), with_doc = 1)
+ else:
+ s.expect_newline("Syntax error in C class definition")
+ doc = None
+ body = None
+ if ctx.visibility == 'extern':
+ if not module_path:
+ error(pos, "Module name required for 'extern' C class")
+ if options.typeobj_cname:
+ error(pos, "Type object name specification not allowed for 'extern' C class")
+ elif ctx.visibility == 'public':
+ if not options.objstruct_cname:
+ error(pos, "Object struct name specification required for 'public' C class")
+ if not options.typeobj_cname:
+ error(pos, "Type object name specification required for 'public' C class")
+ else:
+ if ctx.api:
+ error(pos, "Only 'public' C class can be declared 'api'")
+ return Nodes.CClassDefNode(pos,
+ visibility = ctx.visibility,
+ typedef_flag = ctx.typedef_flag,
+ api = ctx.api,
+ module_name = ".".join(module_path),
+ class_name = class_name,
+ as_name = as_name,
+ base_class_module = base_class_module,
+ base_class_name = base_class_name,
+ options = options,
+ in_pxd = ctx.level == 'module_pxd',
+ doc = doc,
+ body = body)
+
+def p_c_class_options(s, ctx, options):
+ s.expect('[')
+ while 1:
+ if s.sy <> 'IDENT':
+ break
+ if s.systring == 'object':
+ if ctx.visibility not in ('public', 'extern'):
+ error(s.position(), "Object name option only allowed for 'public' or 'extern' C class")
+ s.next()
+ options.objstruct_cname = p_ident(s)
+ elif s.systring == 'type':
+ if ctx.visibility not in ('public', 'extern'):
+ error(s.position(), "Type name option only allowed for 'public' or 'extern' C class")
+ s.next()
+ options.typeobj_cname = p_ident(s)
+ elif s.systring == 'nogc':
+ s.next()
+ options.no_gc = 1
+ else:
+ s.error("Unrecognised C class option '%s'" % s.systring)
+ if s.sy <> ',':
+ break
+ s.next()
+ s.expect(']', "Expected a C class option")
+
+def p_property_decl(s):
+ pos = s.position()
+ s.next() # 'property'
+ name = p_ident(s)
+ doc, body = p_suite(s, Ctx(level = 'property'), with_doc = 1)
+ return Nodes.PropertyNode(pos, name = name, doc = doc, body = body)
+
+def p_doc_string(s):
+ if s.sy == 'STRING' or s.sy == 'BEGIN_STRING':
+ _, result = p_cat_string_literal(s)
+ if s.sy <> 'EOF':
+ s.expect_newline("Syntax error in doc string")
+ return result
+ else:
+ return None
+
+def p_module(s, pxd):
+ s.add_type_name("object")
+ pos = s.position()
+ doc = p_doc_string(s)
+ if pxd:
+ level = 'module_pxd'
+ else:
+ level = 'module'
+ body = p_statement_list(s, Ctx(level = level))
+ if s.sy <> 'EOF':
+ s.error("Syntax error in statement [%s,%s]" % (
+ repr(s.sy), repr(s.systring)))
+ return ModuleNode(pos, doc = doc, body = body)
+
+#----------------------------------------------
+#
+# Debugging
+#
+#----------------------------------------------
+
+def print_parse_tree(f, node, level, key = None):
+ ind = " " * level
+ if node:
+ f.write(ind)
+ if key:
+ f.write("%s: " % key)
+ t = type(node)
+ if t == TupleType:
+ f.write("(%s @ %s\n" % (node[0], node[1]))
+ for i in xrange(2, len(node)):
+ print_parse_tree(f, node[i], level+1)
+ f.write("%s)\n" % ind)
+ return
+ elif isinstance(node, Node):
+ try:
+ tag = node.tag
+ except AttributeError:
+ tag = node.__class__.__name__
+ f.write("%s @ %s\n" % (tag, node.pos))
+ for name, value in node.__dict__.items():
+ if name <> 'tag' and name <> 'pos':
+ print_parse_tree(f, value, level+1, name)
+ return
+ elif t == ListType:
+ f.write("[\n")
+ for i in xrange(len(node)):
+ print_parse_tree(f, node[i], level+1)
+ f.write("%s]\n" % ind)
+ return
+ f.write("%s%s\n" % (ind, node))
+
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/PyrexTypes.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/PyrexTypes.py
new file mode 100644
index 00000000..7d4f244a
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/PyrexTypes.py
@@ -0,0 +1,974 @@
+#
+# Pyrex - Types
+#
+
+import string
+import Naming
+
+class BaseType:
+ #
+ # Base class for all Pyrex types including pseudo-types.
+
+ def cast_code(self, expr_code):
+ return "((%s)%s)" % (self.declaration_code(""), expr_code)
+
+ def base_declaration_code(self, base_code, entity_code):
+ if entity_code:
+ return "%s %s" % (base_code, entity_code)
+ else:
+ return base_code
+
+
+class PyrexType(BaseType):
+ #
+ # Base class for all non-pseudo Pyrex types.
+ #
+ # is_pyobject boolean Is a Python object type
+ # is_extension_type boolean Is a Python extension type
+ # is_numeric boolean Is a C numeric type
+ # is_int boolean Is a C integer type
+ # is_float boolean Is a C floating point type
+ # is_void boolean Is the C void type
+ # is_array boolean Is a C array type
+ # is_ptr boolean Is a C pointer type
+ # is_null_ptr boolean Is the type of NULL
+ # is_cfunction boolean Is a C function type
+ # is_struct_or_union boolean Is a C struct or union type
+ # is_enum boolean Is a C enum type
+ # is_typedef boolean Is a typedef type
+ # is_string boolean Is a C char * type
+ # is_returncode boolean Is used only to signal exceptions
+ # is_sequence boolean Is a sequence type
+ # is_builtin boolean Is a built-in Python type
+ # is_error boolean Is the dummy error type
+ # has_attributes boolean Has C dot-selectable attributes
+ # default_value string Initial value
+ # parsetuple_format string Format char for PyArg_ParseTuple
+ # pymemberdef_typecode string Type code for PyMemberDef struct
+ #
+ # declaration_code(entity_code,
+ # for_display = 0, dll_linkage = None, pyrex = 0)
+ # Returns a code fragment for the declaration of an entity
+ # of this type, given a code fragment for the entity.
+ # * If for_display, this is for reading by a human in an error
+ # message; otherwise it must be valid C code.
+ # * If dll_linkage is not None, it must be 'DL_EXPORT' or
+ # 'DL_IMPORT', and will be added to the base type part of
+ # the declaration.
+ # * If pyrex = 1, this is for use in a 'cdef extern'
+ # statement of a Pyrex include file.
+ #
+ # assignable_from(src_type)
+ # Tests whether a variable of this type can be
+ # assigned a value of type src_type.
+ #
+ # same_as(other_type)
+ # Tests whether this type represents the same type
+ # as other_type.
+ #
+ # as_argument_type():
+ # Coerces array type into pointer type for use as
+ # a formal argument type.
+ #
+
+ is_pyobject = 0
+ is_extension_type = 0
+ is_numeric = 0
+ is_int = 0
+ is_float = 0
+ is_void = 0
+ is_array = 0
+ is_ptr = 0
+ is_null_ptr = 0
+ is_cfunction = 0
+ is_struct_or_union = 0
+ is_enum = 0
+ is_typedef = 0
+ is_string = 0
+ is_returncode = 0
+ is_sequence = 0
+ is_builtin = 0
+ is_error = 0
+ has_attributes = 0
+ default_value = ""
+ parsetuple_format = ""
+ pymemberdef_typecode = None
+
+ def resolve(self):
+ # If a typedef, returns the base type.
+ return self
+
+ def literal_code(self, value):
+ # Returns a C code fragment representing a literal
+ # value of this type.
+ return str(value)
+
+ def __str__(self):
+ return string.strip(self.declaration_code("", for_display = 1))
+
+ def same_as(self, other_type, **kwds):
+ return self.same_as_resolved_type(other_type.resolve(), **kwds)
+
+ def same_as_resolved_type(self, other_type):
+ return self is other_type or other_type is error_type
+
+ def subtype_of(self, other_type):
+ return self.subtype_of_resolved_type(other_type.resolve())
+
+ def subtype_of_resolved_type(self, other_type):
+ return self.same_as(other_type)
+
+ def assignable_from(self, src_type):
+ return self.assignable_from_resolved_type(src_type.resolve())
+
+ def assignable_from_resolved_type(self, src_type):
+ return self.same_as(src_type)
+
+ def as_argument_type(self):
+ return self
+
+ def is_complete(self):
+ # A type is incomplete if it is an unsized array,
+ # a struct whose attributes are not defined, etc.
+ return 1
+
+
+class TypeWrapper(BaseType):
+ # Base class for pseudo-types that delegate most
+ # attribute lookups to another type.
+ #
+ # delegate_type PyrexType
+
+ def __init__(self, base_type):
+ self.delegate_type = base_type
+
+ def __getattr__(self, name):
+ return getattr(self.delegate_type, name)
+
+ def define(self, base_type):
+ self.delegate_type = base_type
+
+ def resolve(self):
+ return self.delegate_type.resolve()
+
+
+class CTypedefType(TypeWrapper):
+ #
+ # Pseudo-type defined with a ctypedef statement in a
+ # 'cdef extern from' block. Delegates most attribute
+ # lookups to the base type. ANYTHING NOT DEFINED
+ # HERE IS DELEGATED!
+ #
+ # qualified_name string
+ # typedef_cname string
+ # typedef_base_type PyrexType
+
+ is_typedef = 1
+
+ def __init__(self, cname, base_type):
+ TypeWrapper.__init__(self, base_type)
+ self.typedef_cname = cname
+ self.typedef_base_type = base_type
+
+ def declaration_code(self, entity_code,
+ for_display = 0, dll_linkage = None, pyrex = 0):
+ name = self.declaration_name(for_display, pyrex)
+ return self.base_declaration_code(name, entity_code)
+
+ def declaration_name(self, for_display = 0, pyrex = 0):
+ if pyrex or for_display:
+ return self.qualified_name
+ else:
+ return self.typedef_cname
+
+ def as_argument_type(self):
+ return self
+
+ def __repr__(self):
+ return "<CTypedefType %s>" % self.typedef_cname
+
+ def __str__(self):
+ return self.declaration_name(for_display = 1)
+
+
+class PyObjectType(PyrexType):
+ #
+ # Base class for all Python object types (reference-counted).
+ #
+
+ is_pyobject = 1
+ default_value = "0"
+ parsetuple_format = "O"
+ pymemberdef_typecode = "T_OBJECT"
+
+ def __str__(self):
+ return "Python object"
+
+ def __repr__(self):
+ return "<PyObjectType>"
+
+ def assignable_from(self, src_type):
+ return 1 # Conversion will be attempted
+
+ def declaration_code(self, entity_code,
+ for_display = 0, dll_linkage = None, pyrex = 0):
+ if pyrex or for_display:
+ return self.base_declaration_code("object", entity_code)
+ else:
+ return "%s *%s" % (public_decl("PyObject", dll_linkage), entity_code)
+
+
+class PyExtensionType(PyObjectType):
+ #
+ # A Python extension type.
+ #
+ # name string
+ # scope CClassScope Attribute namespace
+ # visibility string
+ # typedef_flag boolean
+ # base_type PyExtensionType or None
+ # module_name string or None Qualified name of defining module
+ # objstruct_cname string Name of PyObject struct
+ # typeobj_cname string or None C code fragment referring to type object
+ # typeptr_cname string or None Name of pointer to external type object
+ # vtabslot_cname string Name of C method table member
+ # vtabstruct_cname string Name of C method table struct
+ # vtabptr_cname string Name of pointer to C method table
+ # vtable_cname string Name of C method table definition
+
+ is_extension_type = 1
+ has_attributes = 1
+
+ def __init__(self, name, typedef_flag, base_type):
+ self.name = name
+ self.scope = None
+ self.typedef_flag = typedef_flag
+ self.base_type = base_type
+ self.module_name = None
+ self.objstruct_cname = None
+ self.typeobj_cname = None
+ self.typeptr_cname = None
+ self.vtabslot_cname = None
+ self.vtabstruct_cname = None
+ self.vtabptr_cname = None
+ self.vtable_cname = None
+ if base_type and base_type.is_sequence:
+ self.is_sequence = 1
+
+ def set_scope(self, scope):
+ self.scope = scope
+ if scope:
+ scope.parent_type = self
+
+ def subtype_of_resolved_type(self, other_type):
+ if other_type.is_extension_type:
+ return self is other_type or (
+ self.base_type and self.base_type.subtype_of(other_type))
+ else:
+ return other_type is py_object_type
+
+ def typeobj_is_available(self):
+ # Do we have a pointer to the type object?
+ return self.typeptr_cname
+
+ def typeobj_is_imported(self):
+ # If we don't know the C name of the type object but we do
+ # know which module it's defined in, it will be imported.
+ return self.typeobj_cname is None and self.module_name is not None
+
+ def declaration_code(self, entity_code,
+ for_display = 0, dll_linkage = None, pyrex = 0):
+ if pyrex or for_display:
+ return self.base_declaration_code(self.name, entity_code)
+ else:
+ if self.typedef_flag:
+ base_format = "%s"
+ else:
+ base_format = "struct %s"
+ base = public_decl(base_format % self.objstruct_cname, dll_linkage)
+ return "%s *%s" % (base, entity_code)
+
+ def attributes_known(self):
+ return self.scope is not None
+
+ def is_defined(self):
+ scope = self.scope
+ return scope and (scope.defined or scope.implemented)
+
+ def __str__(self):
+ return self.name
+
+ def __repr__(self):
+ return "<PyExtensionType %s%s>" % (self.scope.class_name,
+ ("", " typedef")[self.typedef_flag])
+
+
+class CType(PyrexType):
+ #
+ # Base class for all C types (non-reference-counted).
+ #
+ # to_py_function string C function for converting to Python object
+ # from_py_function string C function for constructing from Python object
+ #
+
+ to_py_function = None
+ from_py_function = None
+
+
+class CVoidType(CType):
+ is_void = 1
+
+ def __repr__(self):
+ return "<CVoidType>"
+
+ def declaration_code(self, entity_code,
+ for_display = 0, dll_linkage = None, pyrex = 0):
+ base = public_decl("void", dll_linkage)
+ return self.base_declaration_code(base, entity_code)
+
+ def is_complete(self):
+ return 0
+
+
+class CNumericType(CType):
+ #
+ # Base class for all C numeric types.
+ #
+ # rank integer Relative size
+ # signed integer 0 = unsigned, 1 = unspecified, 2 = explicitly signed
+ # name string or None to construct from sign and rank
+ #
+
+ is_numeric = 1
+ default_value = "0"
+
+ parsetuple_formats = ( # rank -> format
+ "BHIk?K???", # unsigned
+ "bhil?Lfd?", # assumed signed
+ "bhil?Lfd?", # explicitly signed
+ )
+
+ sign_words = ("unsigned ", "", "signed ")
+
+ def __init__(self, rank, signed, name, pymemberdef_typecode = None):
+ self.rank = rank
+ self.signed = signed
+ self.name = name
+ ptf = self.parsetuple_formats[signed][rank]
+ if ptf == '?':
+ ptf = None
+ self.parsetuple_format = ptf
+ self.pymemberdef_typecode = pymemberdef_typecode
+
+ def sign_and_name(self):
+ return self.name
+
+ def __repr__(self):
+ return "<CNumericType %s>" % self.sign_and_name()
+
+ def declaration_code(self, entity_code,
+ for_display = 0, dll_linkage = None, pyrex = 0):
+ base = public_decl(self.sign_and_name(), dll_linkage)
+ return self.base_declaration_code(base, entity_code)
+
+
+class CIntType(CNumericType):
+
+ is_int = 1
+ typedef_flag = 0
+ to_py_function = "PyInt_FromLong"
+ from_py_function = "PyInt_AsLong"
+
+ def __init__(self, rank, signed, name, pymemberdef_typecode = None, is_returncode = 0):
+ CNumericType.__init__(self, rank, signed, name, pymemberdef_typecode)
+ self.is_returncode = is_returncode
+
+ def assignable_from_resolved_type(self, src_type):
+ return src_type.is_int or src_type.is_enum or src_type is error_type
+
+
+class CAnonEnumType(CIntType):
+
+ is_enum = 1
+
+
+class CUIntType(CIntType):
+
+ to_py_function = "PyLong_FromUnsignedLong"
+ from_py_function = "PyInt_AsUnsignedLongMask"
+
+
+class CULongType(CIntType):
+
+ to_py_function = "PyLong_FromUnsignedLong"
+ from_py_function = "PyInt_AsUnsignedLongMask"
+
+
+class CLongLongType(CIntType):
+
+ to_py_function = "PyLong_FromLongLong"
+ from_py_function = "PyInt_AsUnsignedLongLongMask"
+
+
+class CULongLongType(CIntType):
+
+ to_py_function = "PyLong_FromUnsignedLongLong"
+ from_py_function = "PyInt_AsUnsignedLongLongMask"
+
+
+class CPySSizeTType(CIntType):
+
+ to_py_function = "PyInt_FromSsize_t"
+ from_py_function = "PyInt_AsSsize_t"
+
+
+class CFloatType(CNumericType):
+
+ is_float = 1
+ to_py_function = "PyFloat_FromDouble"
+ from_py_function = "PyFloat_AsDouble"
+
+ def __init__(self, rank, name, pymemberdef_typecode = None):
+ CNumericType.__init__(self, rank, 1, name, pymemberdef_typecode)
+
+ def assignable_from_resolved_type(self, src_type):
+ return src_type.is_numeric or src_type is error_type
+
+
+class CArrayType(CType):
+ # base_type CType Element type
+ # size integer or None Number of elements
+
+ is_array = 1
+
+ def __init__(self, base_type, size):
+ self.base_type = base_type
+ self.size = size
+ if base_type is c_char_type:
+ self.is_string = 1
+
+ def __repr__(self):
+ return "<CArrayType %s %s>" % (self.size, repr(self.base_type))
+
+ def same_as_resolved_type(self, other_type):
+ return ((other_type.is_array and
+ self.base_type.same_as(other_type.base_type))
+ or other_type is error_type)
+
+ def assignable_from_resolved_type(self, src_type):
+ # Can't assign to a variable of an array type
+ return 0
+
+ def element_ptr_type(self):
+ return c_ptr_type(self.base_type)
+
+ def declaration_code(self, entity_code,
+ for_display = 0, dll_linkage = None, pyrex = 0):
+ if self.size is not None:
+ dimension_code = self.size
+ else:
+ dimension_code = ""
+ if entity_code.startswith("*"):
+ entity_code = "(%s)" % entity_code
+ return self.base_type.declaration_code(
+ "%s[%s]" % (entity_code, dimension_code),
+ for_display, dll_linkage, pyrex)
+
+ def as_argument_type(self):
+ return c_ptr_type(self.base_type)
+
+ def is_complete(self):
+ return self.size is not None
+
+
+class CPtrType(CType):
+ # base_type CType Referenced type
+
+ is_ptr = 1
+ default_value = "0"
+
+ def __init__(self, base_type):
+ self.base_type = base_type
+
+ def __repr__(self):
+ return "<CPtrType %s>" % repr(self.base_type)
+
+ def same_as_resolved_type(self, other_type):
+ return ((other_type.is_ptr and
+ self.base_type.same_as(other_type.base_type))
+ or other_type is error_type)
+
+ def declaration_code(self, entity_code,
+ for_display = 0, dll_linkage = None, pyrex = 0):
+ #print "CPtrType.declaration_code: pointer to", self.base_type ###
+ return self.base_type.declaration_code(
+ "*%s" % entity_code,
+ for_display, dll_linkage, pyrex)
+
+ def assignable_from_resolved_type(self, other_type):
+ if other_type is error_type:
+ return 1
+ if other_type.is_null_ptr:
+ return 1
+ if self.base_type.is_cfunction:
+ if other_type.is_ptr:
+ other_type = other_type.base_type.resolve()
+ if other_type.is_cfunction:
+ return self.base_type.pointer_assignable_from_resolved_type(other_type)
+ else:
+ return 0
+ if other_type.is_array or other_type.is_ptr:
+ return self.base_type.is_void or self.base_type.same_as(other_type.base_type)
+ return 0
+
+
+class CNullPtrType(CPtrType):
+
+ is_null_ptr = 1
+
+
+class CFuncType(CType):
+ # return_type CType
+ # args [CFuncTypeArg]
+ # has_varargs boolean
+ # exception_value string
+ # exception_check boolean True if PyErr_Occurred check needed
+ # calling_convention string Function calling convention
+ # nogil boolean Can be called without gil
+ # with_gil boolean Acquire gil around function body
+
+ is_cfunction = 1
+ is_overloaded = 0
+
+ def __init__(self, return_type, args, has_varargs = 0,
+ exception_value = None, exception_check = 0, calling_convention = "",
+ nogil = 0, with_gil = 0):
+ self.return_type = return_type
+ self.args = args
+ self.has_varargs = has_varargs
+ self.exception_value = exception_value
+ self.exception_check = exception_check
+ self.calling_convention = calling_convention
+ self.nogil = nogil
+ self.with_gil = with_gil
+
+ def __repr__(self):
+ arg_reprs = map(repr, self.args)
+ if self.has_varargs:
+ arg_reprs.append("...")
+ return "<CFuncType %s %s[%s]>" % (
+ repr(self.return_type),
+ self.calling_convention_prefix(),
+ string.join(arg_reprs, ","))
+
+ def callable_with(self, actual_arg_types):
+ formal_arg_types = self.args
+ nf = len(formal_arg_types)
+ na = len(actual_arg_types)
+ if not (nf == na or self.has_varargs and nf >= na):
+ return False
+ for formal_type, actual_type in zip(formal_arg_types, actual_arg_types):
+ if not formal_type.assignable_from(actual_type):
+ return False
+ return True
+
+ def calling_convention_prefix(self):
+ cc = self.calling_convention
+ if cc:
+ return cc + " "
+ else:
+ return ""
+
+ def same_c_signature_as(self, other_type, as_cmethod = 0):
+ return self.same_c_signature_as_resolved_type(
+ other_type.resolve(), as_cmethod)
+
+ def same_c_signature_as_resolved_type(self, other_type, as_cmethod = 0):
+ #print "CFuncType.same_c_signature_as_resolved_type:", \
+ # self, other_type, "as_cmethod =", as_cmethod ###
+ if other_type is error_type:
+ return 1
+ if not other_type.is_cfunction:
+ return 0
+ nargs = len(self.args)
+ if nargs <> len(other_type.args):
+ return 0
+ # When comparing C method signatures, the first argument
+ # is exempt from compatibility checking (the proper check
+ # is performed elsewhere).
+ for i in range(as_cmethod, nargs):
+ if not self.args[i].type.same_as(
+ other_type.args[i].type):
+ return 0
+ if self.has_varargs <> other_type.has_varargs:
+ return 0
+ if not self.return_type.same_as(other_type.return_type):
+ return 0
+ if not self.same_calling_convention_as(other_type):
+ return 0
+ return 1
+
+ def same_calling_convention_as(self, other):
+ return self.calling_convention == other.calling_convention
+
+ def same_exception_signature_as(self, other_type):
+ return self.same_exception_signature_as_resolved_type(
+ other_type.resolve())
+
+ def same_exception_signature_as_resolved_type(self, other_type):
+ return self.exception_value == other_type.exception_value \
+ and self.exception_check == other_type.exception_check
+
+ def same_as_resolved_type(self, other_type, as_cmethod = 0):
+ return self.same_c_signature_as_resolved_type(other_type, as_cmethod) \
+ and self.same_exception_signature_as_resolved_type(other_type) \
+ and self.nogil == other_type.nogil
+
+ def pointer_assignable_from_resolved_type(self, other_type):
+ return self.same_c_signature_as_resolved_type(other_type) \
+ and self.same_exception_signature_as_resolved_type(other_type) \
+ and not (self.nogil and not other_type.nogil)
+
+ def declaration_code(self, entity_code,
+ for_display = 0, dll_linkage = None, pyrex = 0):
+ arg_decl_list = []
+ for arg in self.args:
+ arg_decl_list.append(
+ arg.type.declaration_code("", for_display, pyrex = pyrex))
+ if self.has_varargs:
+ arg_decl_list.append("...")
+ arg_decl_code = string.join(arg_decl_list, ",")
+ if not arg_decl_code and not pyrex:
+ arg_decl_code = "void"
+ trailer = ""
+ if (pyrex or for_display) and not self.return_type.is_pyobject:
+ if self.exception_value and self.exception_check:
+ trailer = " except? %s" % self.exception_value
+ elif self.exception_value:
+ trailer = " except %s" % self.exception_value
+ elif self.exception_check:
+ trailer = " except *"
+ if self.nogil:
+ trailer += " nogil"
+ cc = self.calling_convention_prefix()
+ if (not entity_code and cc) or entity_code.startswith("*"):
+ entity_code = "(%s%s)" % (cc, entity_code)
+ cc = ""
+ return self.return_type.declaration_code(
+ "%s%s(%s)%s" % (cc, entity_code, arg_decl_code, trailer),
+ for_display, dll_linkage, pyrex)
+
+ def function_header_code(self, func_name, arg_code):
+ return "%s%s(%s)" % (self.calling_convention_prefix(),
+ func_name, arg_code)
+
+ def signature_string(self):
+ s = self.declaration_code("")
+ return s
+
+
+class COverloadedFuncType(CType):
+ # return_type CType
+ # signatures [CFuncType]
+
+ is_cfunction = 1
+ is_overloaded = 1
+
+ def __init__(self, return_type, signatures):
+ self.return_type = return_type
+ self.signatures = signatures
+
+ def __str__(self):
+ return "COverloadedFuncType(%s, [%s])" % (self.return_type,
+ ", ".join(map(str, self.signatures)))
+
+
+class CFuncTypeArg:
+ # name string
+ # cname string
+ # type PyrexType
+ # pos source file position
+
+ def __init__(self, name, type, pos):
+ self.name = name
+ self.cname = Naming.var_prefix + name
+ self.type = type
+ self.pos = pos
+
+ def __repr__(self):
+ return "%s:%s" % (self.name, repr(self.type))
+
+ def declaration_code(self, for_display = 0):
+ return self.type.declaration_code(self.cname, for_display)
+
+
+class CStructOrUnionType(CType):
+ # name string
+ # cname string
+ # kind string "struct" or "union"
+ # scope StructOrUnionScope, or None if incomplete
+ # typedef_flag boolean
+ # cplus_constructor_type COverloadedFuncType
+
+ is_struct_or_union = 1
+ has_attributes = 1
+
+ def __init__(self, name, kind, scope, typedef_flag, cname):
+ self.name = name
+ self.cname = cname
+ self.kind = kind
+ self.typedef_flag = typedef_flag
+ self.set_scope(scope)
+
+ def __repr__(self):
+ return "<CStructOrUnionType %s %s%s>" % (self.name, self.cname,
+ ("", " typedef")[self.typedef_flag])
+
+ def set_scope(self, scope):
+ self.scope = scope
+ if scope and scope.is_cplus:
+ self.cplus_constructor_type = COverloadedFuncType(self,
+ scope.cplus_constructors)
+
+ def declaration_code(self, entity_code,
+ for_display = 0, dll_linkage = None, pyrex = 0):
+ if pyrex:
+ return self.base_declaration_code(self.name, entity_code)
+ else:
+ if for_display:
+ base = self.name
+ elif self.typedef_flag:
+ base = self.cname
+ else:
+ base = "%s %s" % (self.kind, self.cname)
+ return self.base_declaration_code(public_decl(base, dll_linkage), entity_code)
+
+ def is_complete(self):
+ return self.scope is not None
+
+ def attributes_known(self):
+ return self.is_complete()
+
+
+class CEnumType(CType):
+ # name string
+ # cname string or None
+ # typedef_flag boolean
+
+ is_enum = 1
+ signed = 1
+ rank = -1 # Ranks below any integer type
+ to_py_function = "PyInt_FromLong"
+ from_py_function = "PyInt_AsLong"
+
+ def __init__(self, name, cname, typedef_flag):
+ self.name = name
+ self.cname = cname
+ self.values = []
+ self.typedef_flag = typedef_flag
+
+ def __str__(self):
+ return self.name
+
+ def __repr__(self):
+ return "<CEnumType %s %s%s>" % (self.name, self.cname,
+ ("", " typedef")[self.typedef_flag])
+
+ def declaration_code(self, entity_code,
+ for_display = 0, dll_linkage = None, pyrex = 0):
+ if pyrex:
+ return self.base_declaration_code(self.cname, entity_code)
+ else:
+ if self.typedef_flag:
+ base = self.cname
+ else:
+ base = "enum %s" % self.cname
+ return self.base_declaration_code(public_decl(base, dll_linkage), entity_code)
+
+
+class CStringType:
+ # Mixin class for C string types.
+
+ is_string = 1
+
+ to_py_function = "PyString_FromString"
+ from_py_function = "PyString_AsString"
+
+ def literal_code(self, value):
+ return '"%s"' % value
+
+
+class CCharArrayType(CStringType, CArrayType):
+ # C 'char []' type.
+
+ parsetuple_format = "s"
+ pymemberdef_typecode = "T_STRING_INPLACE"
+
+ def __init__(self, size):
+ CArrayType.__init__(self, c_char_type, size)
+
+
+class CCharPtrType(CStringType, CPtrType):
+ # C 'char *' type.
+
+ parsetuple_format = "s"
+ pymemberdef_typecode = "T_STRING"
+
+ def __init__(self):
+ CPtrType.__init__(self, c_char_type)
+
+
+class ErrorType(PyrexType):
+ # Used to prevent propagation of error messages.
+
+ is_error = 1
+ exception_value = "0"
+ exception_check = 0
+ to_py_function = "dummy"
+ from_py_function = "dummy"
+ parsetuple_format = "E"
+
+ def declaration_code(self, entity_code,
+ for_display = 0, dll_linkage = None, pyrex = 0):
+ return "<error>"
+
+ def same_as_resolved_type(self, other_type):
+ return 1
+
+
+py_object_type = PyObjectType()
+py_type_type = TypeWrapper(None) # Bootstrapping placeholder, filled later
+
+c_void_type = CVoidType()
+c_void_ptr_type = CPtrType(c_void_type)
+c_void_ptr_ptr_type = CPtrType(c_void_ptr_type)
+
+c_uchar_type = CIntType(0, 0, "unsigned char", "T_UBYTE")
+c_ushort_type = CIntType(1, 0, "unsigned short", "T_USHORT")
+c_uint_type = CUIntType(2, 0, "unsigned int", "T_UINT")
+c_ulong_type = CULongType(3, 0, "unsigned long", "T_ULONG")
+c_size_t_type = CPySSizeTType(4, 0, "size_t")
+c_ulonglong_type = CULongLongType(5, 0, "unsigned PY_LONG_LONG", "T_ULONGLONG")
+
+c_char_type = CIntType(0, 1, "char", "T_CHAR")
+c_short_type = CIntType(1, 1, "short", "T_SHORT")
+c_int_type = CIntType(2, 1, "int", "T_INT")
+c_long_type = CIntType(3, 1, "long", "T_LONG")
+c_longlong_type = CLongLongType(5, 1, "PY_LONG_LONG", "T_LONGLONG")
+
+c_schar_type = CIntType(0, 2, "signed char", "T_CHAR")
+c_sshort_type = CIntType(1, 2, "signed short", "T_SHORT")
+c_sint_type = CIntType(2, 2, "signed int", "T_INT")
+c_slong_type = CIntType(3, 2, "signed long", "T_LONG")
+c_py_ssize_t_type = CPySSizeTType(4, 2, "Py_ssize_t")
+c_slonglong_type = CLongLongType(5, 2, "signed PY_LONG_LONG", "T_LONGLONG")
+
+c_float_type = CFloatType(6, "float", "T_FLOAT")
+c_double_type = CFloatType(7, "double", "T_DOUBLE")
+c_longdouble_type = CFloatType(8, "long double")
+
+c_null_ptr_type = CNullPtrType(c_void_type)
+c_char_array_type = CCharArrayType(None)
+c_char_ptr_type = CCharPtrType()
+c_char_ptr_ptr_type = CPtrType(c_char_ptr_type)
+c_int_ptr_type = CPtrType(c_int_type)
+
+c_returncode_type = CIntType(2, 1, "int", "T_INT", is_returncode = 1)
+
+c_anon_enum_type = CAnonEnumType(-1, 1, "<enum>")
+
+error_type = ErrorType()
+
+# Signedness values
+UNSIGNED = 0
+NOSIGN = 1
+SIGNED = 2
+
+# Longness values
+SHORT = -1
+NOLEN = 0
+LONG = 1
+LONGLONG = 2
+
+modifiers_and_name_to_type = {
+ #(signedness, longness, name)
+ (UNSIGNED, NOLEN, "char"): c_uchar_type,
+ (UNSIGNED, SHORT, "int"): c_ushort_type,
+ (UNSIGNED, NOLEN, "int"): c_uint_type,
+ (UNSIGNED, LONG, "int"): c_ulong_type,
+ (UNSIGNED, LONGLONG, "int"): c_ulonglong_type,
+ (NOSIGN, NOLEN, "void"): c_void_type,
+ (NOSIGN, NOLEN, "char"): c_char_type,
+ (NOSIGN, SHORT, "int"): c_short_type,
+ (NOSIGN, NOLEN, "int"): c_int_type,
+ #(NOSIGN, NOLEN, "size_t"): c_size_t_type,
+ #(NOSIGN, NOLEN, "Py_ssize_t"): c_py_ssize_t_type,
+ (NOSIGN, LONG, "int"): c_long_type,
+ (NOSIGN, LONGLONG, "int"): c_longlong_type,
+ (NOSIGN, NOLEN, "float"): c_float_type,
+ (NOSIGN, NOLEN, "double"): c_double_type,
+ (NOSIGN, LONG, "double"): c_longdouble_type,
+ (NOSIGN, NOLEN, "object"): py_object_type,
+ (SIGNED, NOLEN, "char"): c_schar_type,
+ (SIGNED, SHORT, "int"): c_sshort_type,
+ (SIGNED, NOLEN, "int"): c_sint_type,
+ (SIGNED, LONG, "int"): c_slong_type,
+ (SIGNED, LONGLONG, "int"): c_slonglong_type,
+}
+
+def widest_numeric_type(type1, type2):
+ # Given two numeric types, return the narrowest type
+ # encompassing both of them.
+ if type1.is_enum and type2.is_enum:
+ widest_type = c_int_type
+ elif type1.rank < type2.rank:
+ widest_type = type2
+ elif type1.rank > type2.rank:
+ widest_type = type1
+ elif type1.signed < type2.signed:
+ widest_type = type1
+ else:
+ widest_type = type2
+ return widest_type
+
+def simple_c_type(signed, longness, name):
+ # Find type descriptor for simple type given name and modifiers.
+ # Returns None if arguments don't make sense.
+ return modifiers_and_name_to_type.get((signed, longness, name))
+
+def c_array_type(base_type, size):
+ # Construct a C array type.
+ if base_type is c_char_type:
+ return CCharArrayType(size)
+ else:
+ return CArrayType(base_type, size)
+
+def c_ptr_type(base_type):
+ # Construct a C pointer type.
+ if base_type is c_char_type:
+ return c_char_ptr_type
+ else:
+ return CPtrType(base_type)
+
+def public_decl(base, dll_linkage):
+ if dll_linkage:
+ return "%s(%s)" % (dll_linkage, base)
+ else:
+ return base
+
+def same_type(type1, type2):
+ return type1.same_as(type2)
+
+def assignable_from(type1, type2):
+ return type1.assignable_from(type2)
+
+def typecast(to_type, from_type, expr_code):
+ # Return expr_code cast to a C type which can be
+ # assigned to to_type, assuming its existing C type
+ # is from_type.
+ if to_type is from_type or \
+ same_type(to_type, from_type) or \
+ (not to_type.is_pyobject and assignable_from(to_type, from_type)):
+ return expr_code
+ else:
+ return to_type.cast_code(expr_code)
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Scanning.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Scanning.py
new file mode 100644
index 00000000..1fc92f99
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Scanning.py
@@ -0,0 +1,390 @@
+#
+# Pyrex Scanner
+#
+
+#import pickle
+import cPickle as pickle
+
+import os
+import platform
+import stat
+import sys
+from time import time
+
+from Pyrex import Plex
+from Pyrex.Plex import Scanner
+from Pyrex.Plex.Errors import UnrecognizedInput
+from Errors import CompileError, error
+from Lexicon import string_prefixes, make_lexicon
+
+plex_version = getattr(Plex, '_version', None)
+#print "Plex version:", plex_version ###
+
+debug_scanner = 0
+trace_scanner = 0
+scanner_debug_flags = 0
+scanner_dump_file = None
+binary_lexicon_pickle = 1
+notify_lexicon_unpickling = 0
+notify_lexicon_pickling = 1
+
+lexicon = None
+
+#-----------------------------------------------------------------
+
+def hash_source_file(path):
+ # Try to calculate a hash code for the given source file.
+ # Returns an empty string if the file cannot be accessed.
+ #print "Hashing", path ###
+ try:
+ from hashlib import md5
+ except ImportError:
+ from md5 import new as md5
+ try:
+ try:
+ f = open(path, "rU")
+ text = f.read()
+ except IOError, e:
+ print "Unable to hash scanner source file (%s)" % e
+ return ""
+ finally:
+ f.close()
+ # Normalise spaces/tabs. We don't know what sort of
+ # space-tab substitution the file may have been
+ # through, so we replace all spans of spaces and
+ # tabs by a single space.
+ import re
+ text = re.sub("[ \t]+", " ", text)
+ hash = md5(text).hexdigest()
+ return hash
+
+def open_pickled_lexicon(expected_hash):
+ # Try to open pickled lexicon file and verify that
+ # it matches the source file. Returns the opened
+ # file if successful, otherwise None. ???
+ f = None
+ result = None
+ if os.path.exists(lexicon_pickle):
+ try:
+ f = open(lexicon_pickle, "rb")
+ actual_hash = pickle.load(f)
+ if actual_hash == expected_hash:
+ result = f
+ f = None
+ else:
+ print "Lexicon hash mismatch:" ###
+ print " expected", expected_hash ###
+ print " got ", actual_hash ###
+ except IOError, e:
+ print "Warning: Unable to read pickled lexicon", lexicon_pickle
+ print e
+ if f:
+ f.close()
+ return result
+
+def try_to_unpickle_lexicon():
+ global lexicon, lexicon_pickle, lexicon_hash
+ dir = os.path.dirname(__file__)
+ source_file = os.path.join(dir, "Lexicon.py")
+ lexicon_hash = hash_source_file(source_file)
+ lexicon_pickle = os.path.join(dir, "Lexicon.pickle")
+ f = open_pickled_lexicon(expected_hash = lexicon_hash)
+ if f:
+ if notify_lexicon_unpickling:
+ t0 = time()
+ print "Unpickling lexicon..."
+ lexicon = pickle.load(f)
+ f.close()
+ if notify_lexicon_unpickling:
+ t1 = time()
+ print "Done (%.2f seconds)" % (t1 - t0)
+
+def create_new_lexicon():
+ global lexicon
+ t0 = time()
+ print "Creating lexicon..."
+ lexicon = make_lexicon()
+ t1 = time()
+ print "Done (%.2f seconds)" % (t1 - t0)
+
+def pickle_lexicon():
+ f = None
+ try:
+ f = open(lexicon_pickle, "wb")
+ except IOError:
+ print "Warning: Unable to save pickled lexicon in", lexicon_pickle
+ if f:
+ if notify_lexicon_pickling:
+ t0 = time()
+ print "Pickling lexicon..."
+ pickle.dump(lexicon_hash, f, binary_lexicon_pickle)
+ pickle.dump(lexicon, f, binary_lexicon_pickle)
+ f.close()
+ if notify_lexicon_pickling:
+ t1 = time()
+ print "Done (%.2f seconds)" % (t1 - t0)
+
+def get_lexicon():
+ global lexicon
+ if not lexicon and plex_version is None:
+ try_to_unpickle_lexicon()
+ if not lexicon:
+ create_new_lexicon()
+ if plex_version is None:
+ pickle_lexicon()
+ return lexicon
+
+#------------------------------------------------------------------
+
+reserved_words = [
+ "global", "include", "ctypedef", "cdef", "def", "class",
+ "print", "del", "pass", "break", "continue", "return",
+ "raise", "import", "exec", "try", "except", "finally",
+ "while", "if", "elif", "else", "for", "in", "assert",
+ "and", "or", "not", "is", "in", "lambda", "from",
+ "NULL", "cimport", "with", "DEF", "IF", "ELIF", "ELSE"
+]
+
+class Method:
+
+ def __init__(self, name):
+ self.name = name
+ self.__name__ = name # for Plex tracing
+
+ def __call__(self, stream, text):
+ return getattr(stream, self.name)(text)
+
+#------------------------------------------------------------------
+
+def build_resword_dict():
+ d = {}
+ for word in reserved_words:
+ d[word] = 1
+ return d
+
+#------------------------------------------------------------------
+
+class CompileTimeScope(object):
+
+ def __init__(self, outer = None):
+ self.entries = {}
+ self.outer = outer
+
+ def declare(self, name, value):
+ self.entries[name] = value
+
+ def lookup_here(self, name):
+ return self.entries[name]
+
+ def lookup(self, name):
+ try:
+ return self.lookup_here(name)
+ except KeyError:
+ outer = self.outer
+ if outer:
+ return outer.lookup(name)
+ else:
+ raise
+
+def initial_compile_time_env():
+ benv = CompileTimeScope()
+ names = ('UNAME_SYSNAME', 'UNAME_NODENAME', 'UNAME_RELEASE',
+ 'UNAME_VERSION', 'UNAME_MACHINE')
+ for name, value in zip(names, platform.uname()):
+ benv.declare(name, value)
+ import __builtin__
+ names = ('False', 'True',
+ 'abs', 'bool', 'chr', 'cmp', 'complex', 'dict', 'divmod', 'enumerate',
+ 'float', 'hash', 'hex', 'int', 'len', 'list', 'long', 'map', 'max', 'min',
+ 'oct', 'ord', 'pow', 'range', 'reduce', 'repr', 'round', 'slice', 'str',
+ 'sum', 'tuple', 'xrange', 'zip')
+ for name in names:
+ benv.declare(name, getattr(__builtin__, name))
+ denv = CompileTimeScope(benv)
+ return denv
+
+#------------------------------------------------------------------
+
+class PyrexScanner(Scanner):
+ # context Context Compilation context
+ # type_names set Identifiers to be treated as type names
+ # included_files [string] Files included with 'include' statement
+ # compile_time_env dict Environment for conditional compilation
+ # compile_time_eval boolean In a true conditional compilation context
+ # compile_time_expr boolean In a compile-time expression context
+
+ resword_dict = build_resword_dict()
+
+ def __init__(self, file, filename, parent_scanner = None,
+ scope = None, context = None):
+ Scanner.__init__(self, get_lexicon(), file, filename)
+ if parent_scanner:
+ self.context = parent_scanner.context
+ self.type_names = parent_scanner.type_names
+ self.included_files = parent_scanner.included_files
+ self.compile_time_env = parent_scanner.compile_time_env
+ self.compile_time_eval = parent_scanner.compile_time_eval
+ self.compile_time_expr = parent_scanner.compile_time_expr
+ else:
+ self.context = context
+ self.type_names = scope.type_names
+ self.included_files = scope.pyrex_include_files
+ self.compile_time_env = initial_compile_time_env()
+ self.compile_time_eval = 1
+ self.compile_time_expr = 0
+ self.trace = trace_scanner
+ self.indentation_stack = [0]
+ self.indentation_char = None
+ self.bracket_nesting_level = 0
+ self.begin('INDENT')
+ self.sy = ''
+ self.next()
+
+ def current_level(self):
+ return self.indentation_stack[-1]
+
+ def open_bracket_action(self, text):
+ self.bracket_nesting_level = self.bracket_nesting_level + 1
+ return text
+
+ def close_bracket_action(self, text):
+ self.bracket_nesting_level = self.bracket_nesting_level - 1
+ return text
+
+ def newline_action(self, text):
+ if self.bracket_nesting_level == 0:
+ self.begin('INDENT')
+ self.produce('NEWLINE', '')
+
+ string_states = {
+ "'": 'SQ_STRING',
+ '"': 'DQ_STRING',
+ "'''": 'TSQ_STRING',
+ '"""': 'TDQ_STRING'
+ }
+
+ def begin_string_action(self, text):
+ if text[:1] in string_prefixes:
+ text = text[1:]
+ self.begin(self.string_states[text])
+ self.produce('BEGIN_STRING')
+
+ def end_string_action(self, text):
+ self.begin('')
+ self.produce('END_STRING')
+
+ def unclosed_string_action(self, text):
+ self.end_string_action(text)
+ self.error("Unclosed string literal")
+
+ def indentation_action(self, text):
+ self.begin('')
+ # Indentation within brackets should be ignored.
+ #if self.bracket_nesting_level > 0:
+ # return
+ # Check that tabs and spaces are being used consistently.
+ if text:
+ c = text[0]
+ #print "Scanner.indentation_action: indent with", repr(c) ###
+ if self.indentation_char is None:
+ self.indentation_char = c
+ #print "Scanner.indentation_action: setting indent_char to", repr(c)
+ else:
+ if self.indentation_char <> c:
+ self.error("Mixed use of tabs and spaces")
+ if text.replace(c, "") <> "":
+ self.error("Mixed use of tabs and spaces")
+ # Figure out how many indents/dedents to do
+ current_level = self.current_level()
+ new_level = len(text)
+ #print "Changing indent level from", current_level, "to", new_level ###
+ if new_level == current_level:
+ return
+ elif new_level > current_level:
+ #print "...pushing level", new_level ###
+ self.indentation_stack.append(new_level)
+ self.produce('INDENT', '')
+ else:
+ while new_level < self.current_level():
+ #print "...popping level", self.indentation_stack[-1] ###
+ self.indentation_stack.pop()
+ self.produce('DEDENT', '')
+ #print "...current level now", self.current_level() ###
+ if new_level <> self.current_level():
+ self.error("Inconsistent indentation")
+
+ def eof_action(self, text):
+ while len(self.indentation_stack) > 1:
+ self.produce('DEDENT', '')
+ self.indentation_stack.pop()
+ self.produce('EOF', '')
+
+ def next(self):
+ try:
+ sy, systring = self.read()
+ except UnrecognizedInput:
+ self.error("Unrecognized character")
+ if sy == 'IDENT' and systring in self.resword_dict:
+ sy = systring
+ self.sy = sy
+ self.systring = systring
+ if debug_scanner:
+ _, line, col = self.position()
+ if not self.systring or self.sy == self.systring:
+ t = self.sy
+ else:
+ t = "%s %s" % (self.sy, self.systring)
+ print "--- %3d %2d %s" % (line, col, t)
+
+ def put_back(self, sy, systring):
+ self.unread(self.sy, self.systring)
+ self.sy = sy
+ self.systring = systring
+
+ def unread(self, token, value):
+ # This method should be added to Plex
+ self.queue.insert(0, (token, value))
+
+ def add_type_name(self, name):
+ self.type_names[name] = 1
+
+ def looking_at_type_name(self):
+ return self.sy == 'IDENT' and self.systring in self.type_names
+
+ def error(self, message, pos = None):
+ if pos is None:
+ pos = self.position()
+ if self.sy == 'INDENT':
+ error(pos, "Possible inconsistent indentation")
+ raise error(pos, message)
+
+ def expect(self, what, message = None):
+ if self.sy == what:
+ self.next()
+ else:
+ self.expected(what, message)
+
+ def expect_keyword(self, what, message = None):
+ if self.sy == 'IDENT' and self.systring == what:
+ self.next()
+ else:
+ self.expected(what, message)
+
+ def expected(self, what, message):
+ if message:
+ self.error(message)
+ else:
+ self.error("Expected '%s'" % what)
+
+ def expect_indent(self):
+ self.expect('INDENT',
+ "Expected an increase in indentation level")
+
+ def expect_dedent(self):
+ self.expect('DEDENT',
+ "Expected a decrease in indentation level")
+
+ def expect_newline(self, message = "Expected a newline"):
+ # Expect either a newline or end of file
+ if self.sy <> 'EOF':
+ self.expect('NEWLINE', message)
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Symtab.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Symtab.py
new file mode 100644
index 00000000..b56b8531
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Symtab.py
@@ -0,0 +1,1342 @@
+#
+# Pyrex - Symbol Table
+#
+
+from Errors import warning, error, InternalError
+import Options
+import Naming
+import PyrexTypes
+from PyrexTypes import \
+ py_object_type, py_type_type, \
+ c_int_type, c_char_array_type, \
+ CEnumType, CStructOrUnionType, PyExtensionType
+from TypeSlots import \
+ pyfunction_signature, pymethod_signature, \
+ get_special_method_signature, get_property_accessor_signature
+
+class Entry:
+ # A symbol table entry in a Scope or ModuleNamespace.
+ #
+ # name string Python name of entity
+ # cname string C name of entity
+ # type PyrexType Type of entity
+ # ctype PyrexType Declared C type, if different from Pyrex type
+ # doc string Doc string
+ # init string Initial value
+ # visibility 'private' or 'public' or 'extern'
+ # is_builtin boolean Is an entry in the Python builtins dict
+ # is_cglobal boolean Is a C global variable
+ # is_pyglobal boolean Is a Python module-level variable or
+ # class attribute during class construction
+ # is_variable boolean Is a variable
+ # is_cfunction boolean Is a C function
+ # is_cmethod boolean Is a C method of an extension type
+ # is_builtin_method boolean Is a method corresponding to a Python/C API func
+ # is_type boolean Is a type definition
+ # is_const boolean Is a constant
+ # is_property boolean Is a property of an extension type:
+ # #doc_cname string or None C const holding the docstring
+ # getter_cname string C func for getting property
+ # setter_cname string C func for setting or deleting property
+ # is_self_arg boolean Is the "self" arg of an exttype method
+ # is_readonly boolean Can't be assigned to
+ # func_cname string C func implementing Python func
+ # pos position Source position where declared
+ # namespace_cname string If is_pyglobal, the C variable
+ # holding its home namespace
+ # pymethdef_cname string PyMethodDef structure
+ # signature Signature Arg & return types for Python func
+ # init_to_none boolean True if initial value should be None
+ # as_variable Entry Alternative interpretation of extension
+ # type name or builtin C function as a variable
+ # xdecref_cleanup boolean Use Py_XDECREF for error cleanup
+ # in_cinclude boolean Suppress C declaration code
+ # enum_values [Entry] For enum types, list of values
+ # qualified_name string "modname.funcname" or "modname.classname"
+ # or "modname.classname.funcname"
+ # is_declared_generic boolean Is declared as PyObject * even though its
+ # type is an extension type
+ # as_module None Module scope, if a cimported module
+ # is_inherited boolean Is an inherited attribute of an extension type
+ # #interned_cname string C name of interned name string
+ # pystring_cname string C name of Python version of string literal
+ # #is_interned boolean For string const entries, value is interned
+ # used boolean
+ # is_special boolean Is a special method or property accessor
+ # of an extension type
+ # defined_in_pxd boolean Is defined in a .pxd file (not just declared)
+ # api boolean Generate C API for C class or function
+ # utility_code string Utility code needed when this entry is used
+
+ borrowed = 0
+ init = ""
+ visibility = 'private'
+ ctype = None
+ is_builtin = 0
+ is_cglobal = 0
+ is_pyglobal = 0
+ is_variable = 0
+ is_cfunction = 0
+ is_cmethod = 0
+ is_builtin_method = 0
+ is_type = 0
+ is_const = 0
+ is_property = 0
+ doc_cname = None
+ getter_cname = None
+ setter_cname = None
+ is_self_arg = 0
+ is_declared_generic = 0
+ is_readonly = 0
+ func_cname = None
+ doc = None
+ init_to_none = 0
+ as_variable = None
+ xdecref_cleanup = 0
+ in_cinclude = 0
+ as_module = None
+ is_inherited = 0
+ #interned_cname = None
+ pystring_cname = None
+ is_interned = 0
+ used = 0
+ is_special = 0
+ defined_in_pxd = 0
+ api = 0
+ utility_code = None
+
+ def __init__(self, name, cname, type, pos = None, init = None):
+ self.name = name
+ self.cname = cname
+ self.type = type
+ self.pos = pos
+ self.init = init
+
+ def redeclared(self, pos):
+ error(pos, "'%s' does not match previous declaration" % self.name)
+ error(self.pos, "Previous declaration is here")
+
+
+class Scope:
+ # name string Unqualified name
+ # outer_scope Scope or None Enclosing scope
+ # entries {string : Entry} Python name to entry, non-types
+ # const_entries [Entry] Constant entries
+ # type_entries [Entry] Struct/union/enum/typedef/exttype entries
+ # sue_entries [Entry] Struct/union/enum entries
+ # arg_entries [Entry] Function argument entries
+ # var_entries [Entry] User-defined variable entries
+ # pyfunc_entries [Entry] Python function entries
+ # cfunc_entries [Entry] C function entries
+ # c_class_entries [Entry] All extension type entries
+ # temp_entries [Entry] Temporary variable entries
+ # free_temp_entries [Entry] Temp variables currently unused
+ # temp_counter integer Counter for naming temp vars
+ # cname_to_entry {string : Entry} Temp cname to entry mapping
+ # pow_function_used boolean The C pow() function is used
+ # return_type PyrexType or None Return type of function owning scope
+ # is_py_class_scope boolean Is a Python class scope
+ # is_c_class_scope boolean Is an extension type scope
+ # scope_prefix string Disambiguator for C names
+ # in_cinclude boolean Suppress C declaration code
+ # qualified_name string "modname" or "modname.classname"
+ # #pystring_entries [Entry] String const entries newly used as
+ # # Python strings in this scope
+ # nogil boolean In a nogil section
+ # is_cplus boolean Is a C++ struct namespace
+ # reraise_used boolean Reraise statement encountered
+
+ is_py_class_scope = 0
+ is_c_class_scope = 0
+ scope_prefix = ""
+ in_cinclude = 0
+ nogil = 0
+ return_type = None
+ reraise_used = 0
+
+ def __init__(self, name, outer_scope, parent_scope):
+ # The outer_scope is the next scope in the lookup chain.
+ # The parent_scope is used to derive the qualified name of this scope.
+ self.name = name
+ self.outer_scope = outer_scope
+ self.parent_scope = parent_scope
+ mangled_name = "%d%s_" % (len(name), name)
+ qual_scope = self.qualifying_scope()
+ if qual_scope:
+ self.qualified_name = qual_scope.qualify_name(name)
+ self.scope_prefix = qual_scope.scope_prefix + mangled_name
+ else:
+ self.qualified_name = name
+ self.scope_prefix = mangled_name
+ self.entries = {}
+ self.const_entries = []
+ self.type_entries = []
+ self.sue_entries = []
+ self.arg_entries = []
+ self.var_entries = []
+ self.pyfunc_entries = []
+ self.cfunc_entries = []
+ self.c_class_entries = []
+ self.defined_c_classes = []
+ self.imported_c_classes = {}
+ self.temp_entries = []
+ self.free_temp_entries = []
+ self.temp_counter = 1
+ self.cname_to_entry = {}
+ self.pow_function_used = 0
+ #self.pystring_entries = []
+
+ def __str__(self):
+ return "<%s %s>" % (self.__class__.__name__, self.qualified_name)
+
+# def intern(self, name):
+# return self.global_scope().intern(name)
+
+ def qualifying_scope(self):
+ return self.parent_scope
+
+ def mangle(self, prefix, name = None):
+ if name:
+ return "%s%s%s" % (prefix, self.scope_prefix, name)
+ else:
+ return self.parent_scope.mangle(prefix, self.name)
+
+ def mangle_internal(self, name):
+ # Mangle an internal name so as not to clash with any
+ # user-defined name in this scope.
+ prefix = "%s%s_" % (Naming.pyrex_prefix, name)
+ return self.mangle(prefix)
+ #return self.parent_scope.mangle(prefix, self.name)
+
+ def global_scope(self):
+ # Return the module-level scope containing this scope.
+ return self.outer_scope.global_scope()
+
+ def declare(self, name, cname, type, pos):
+ # Create new entry, and add to dictionary if
+ # name is not None. Reports an error if already
+ # declared.
+ dict = self.entries
+ if name and dict.has_key(name):
+ error(pos, "'%s' already declared" % name)
+ entry = Entry(name, cname, type, pos = pos)
+ entry.in_cinclude = self.in_cinclude
+ if name:
+ entry.qualified_name = self.qualify_name(name)
+ dict[name] = entry
+ return entry
+
+ def qualify_name(self, name):
+ return "%s.%s" % (self.qualified_name, name)
+
+ def declare_const(self, name, type, value, pos, cname = None):
+ # Add an entry for a named constant.
+ if not cname:
+ if self.in_cinclude:
+ cname = name
+ else:
+ cname = self.mangle(Naming.enum_prefix, name)
+ entry = self.declare(name, cname, type, pos)
+ entry.is_const = 1
+ entry.value = value
+ return entry
+
+ def declare_type(self, name, type, pos,
+ cname = None, visibility = 'private', defining = 1):
+ # Add an entry for a type definition.
+ if not cname:
+ cname = name
+ entry = self.declare(name, cname, type, pos)
+ entry.visibility = visibility
+ entry.is_type = 1
+ if defining:
+ self.type_entries.append(entry)
+ return entry
+
+ def declare_typedef(self, name, base_type, pos, cname = None,
+ visibility = 'private'):
+ if not cname:
+ if self.in_cinclude or visibility == 'public':
+ cname = name
+ else:
+ cname = self.mangle(Naming.type_prefix, name)
+ type = PyrexTypes.CTypedefType(cname, base_type)
+ entry = self.declare_type(name, type, pos, cname, visibility)
+ type.qualified_name = entry.qualified_name
+ return entry
+
+ def declare_struct_or_union(self, name, kind, scope,
+ typedef_flag, pos, cname = None, visibility = 'private'):
+ # Add an entry for a struct or union definition.
+ if not cname:
+ if self.in_cinclude or visibility == 'public':
+ cname = name
+ else:
+ cname = self.mangle(Naming.type_prefix, name)
+ entry = self.lookup_here(name)
+ if not entry:
+ type = CStructOrUnionType(name, kind, scope, typedef_flag, cname)
+ entry = self.declare_type(name, type, pos, cname,
+ visibility = visibility, defining = scope is not None)
+ self.sue_entries.append(entry)
+ else:
+ if not (entry.is_type and entry.type.is_struct_or_union
+ and entry.type.kind == kind):
+ entry.redeclared(pos)
+ elif scope and entry.type.scope:
+ error(pos, "'%s' already defined" % name)
+ else:
+ self.check_previous_typedef_flag(entry, typedef_flag, pos)
+ self.check_previous_visibility(entry, visibility, pos)
+ if scope:
+ entry.pos = pos
+ entry.type.set_scope(scope)
+ self.type_entries.append(entry)
+ if not scope and not entry.type.scope:
+ self.check_for_illegal_incomplete_ctypedef(typedef_flag, pos)
+ return entry
+
+ def check_previous_typedef_flag(self, entry, typedef_flag, pos):
+ if typedef_flag <> entry.type.typedef_flag:
+ error(pos, "'%s' previously declared using '%s'" % (
+ entry.name, ("cdef", "ctypedef")[entry.type.typedef_flag]))
+
+ def check_previous_visibility(self, entry, visibility, pos):
+ if entry.visibility <> visibility:
+ error(pos, "'%s' previously declared as '%s'" % (
+ entry.name, entry.visibility))
+
+ def declare_enum(self, name, pos, cname, typedef_flag,
+ visibility = 'private'):
+ if name:
+ if not cname:
+ if self.in_cinclude or visibility == 'public':
+ cname = name
+ else:
+ cname = self.mangle(Naming.type_prefix, name)
+ type = CEnumType(name, cname, typedef_flag)
+ else:
+ type = PyrexTypes.c_anon_enum_type
+ entry = self.declare_type(name, type, pos, cname = cname,
+ visibility = visibility)
+ entry.enum_values = []
+ self.sue_entries.append(entry)
+ return entry
+
+ def declare_var(self, name, type, pos,
+ cname = None, visibility = 'private', is_cdef = 0):
+ # Add an entry for a variable.
+ if not cname:
+ if visibility <> 'private':
+ cname = name
+ else:
+ cname = self.mangle(Naming.var_prefix, name)
+ entry = self.declare(name, cname, type, pos)
+ entry.is_variable = 1
+ entry.visibility = visibility
+ return entry
+
+ def declare_builtin(self, name, pos):
+ return self.outer_scope.declare_builtin(name, pos)
+
+ def declare_pyfunction(self, name, pos):
+ # Add an entry for a Python function.
+ entry = self.declare_var(name, py_object_type, pos)
+ entry.signature = pyfunction_signature
+ self.pyfunc_entries.append(entry)
+ return entry
+
+ def register_pyfunction(self, entry):
+ self.pyfunc_entries.append(entry)
+
+ def declare_cfunction(self, name, type, pos,
+ cname = None, visibility = 'private', defining = 0, api = 0, in_pxd = 0):
+ # Add an entry for a C function.
+ entry = self.lookup_here(name)
+ if entry:
+ if visibility <> 'private' and visibility <> entry.visibility:
+ error(pos, "Function '%s' previously declared as '%s'" % (
+ name, entry.visibility))
+ if not entry.type.same_as(type):
+ error(pos, "Function signature does not match previous declaration")
+ else:
+ if not cname:
+ if api or visibility <> 'private':
+ cname = name
+ else:
+ cname = self.mangle(Naming.func_prefix, name)
+ entry = self.add_cfunction(name, type, pos, cname, visibility)
+ entry.func_cname = cname
+ if in_pxd and visibility <> 'extern':
+ entry.defined_in_pxd = 1
+ if api:
+ entry.api = 1
+ if not defining and not in_pxd and visibility <> 'extern':
+ error(pos, "Non-extern C function declared but not defined")
+ return entry
+
+ def add_cfunction(self, name, type, pos, cname, visibility = 'private'):
+ # Add a C function entry without giving it a func_cname.
+ entry = self.declare(name, cname, type, pos)
+ entry.is_cfunction = 1
+ entry.visibility = visibility
+ self.cfunc_entries.append(entry)
+ return entry
+
+ def attach_var_entry_to_c_class(self, entry):
+ # The name of an extension class has to serve as both a type name and a
+ # variable name holding the type object. It is represented in the symbol
+ # table by a type entry with a variable entry attached to it. For the
+ # variable entry, we use a read-only C global variable whose name is an
+ # expression that refers to the type object.
+ var_entry = Entry(name = entry.name,
+ #type = py_object_type,
+ type = py_type_type,
+ pos = entry.pos,
+ #cname = "((PyObject*)%s)" % entry.type.typeptr_cname
+ cname = entry.type.typeptr_cname)
+ var_entry.is_variable = 1
+ var_entry.is_cglobal = 1
+ var_entry.is_readonly = 1
+ entry.as_variable = var_entry
+
+ def find(self, name, pos):
+ # Look up name, report error if not found.
+ entry = self.lookup(name)
+ if entry:
+ return entry
+ else:
+ error(pos, "'%s' is not declared" % name)
+
+ def find_imported_module(self, path, pos):
+ # Look up qualified name, must be a module, report error if not found.
+ # Path is a list of names.
+ scope = self
+ for name in path:
+ entry = scope.find(name, pos)
+ if not entry:
+ return None
+ if entry.as_module:
+ scope = entry.as_module
+ else:
+ error(pos, "'%s' is not a cimported module" % scope.qualified_name)
+ return None
+ return scope
+
+ def find_qualified_name(self, module_and_name, pos):
+ # Look up qualified name, report error if not found.
+ # module_and_name = [path, name] where path is a list of names.
+ module_path, name = module_and_name
+ scope = self.find_imported_module(module_path, pos)
+ if scope:
+ entry = scope.lookup_here(name)
+ if not entry:
+ mess = "'%s' is not declared" % name
+ if module_path:
+ mess = "%s in module '%s'" % (mess, ".".join(module_path))
+ error(pos, mess)
+ return entry
+
+ def lookup(self, name):
+ # Look up name in this scope or an enclosing one.
+ # Return None if not found.
+ return (self.lookup_here(name)
+ or (self.outer_scope and self.outer_scope.lookup(name))
+ or None)
+
+ def lookup_here(self, name):
+ # Look up in this scope only, return None if not found.
+ return self.entries.get(name, None)
+
+ def lookup_target(self, name):
+ # Look up name in this scope only. Declare as Python
+ # variable if not found.
+ entry = self.lookup_here(name)
+ if not entry:
+ entry = self.declare_var(name, py_object_type, None)
+ return entry
+
+# def add_string_const(self, value):
+# # Add an entry for a string constant.
+# cname = self.new_const_cname()
+# entry = Entry("", cname, c_char_array_type, init = value)
+# entry.used = 1
+# self.const_entries.append(entry)
+# return entry
+
+# def get_string_const(self, value):
+# # Get entry for string constant. Returns an existing
+# # one if possible, otherwise creates a new one.
+# genv = self.global_scope()
+# entry = genv.string_to_entry.get(value)
+# if not entry:
+# entry = self.add_string_const(value)
+# genv.string_to_entry[value] = entry
+# return entry
+
+# def add_py_string(self, entry):
+# # If not already done, allocate a C name for a Python version of
+# # a string literal, and add it to the list of Python strings to
+# # be created at module init time. If the string resembles a
+# # Python identifier, it will be interned.
+# if not entry.pystring_cname:
+# value = entry.init
+# if identifier_pattern.match(value):
+# entry.pystring_cname = self.intern(value)
+# entry.is_interned = 1
+# else:
+# entry.pystring_cname = entry.cname + "p"
+# self.pystring_entries.append(entry)
+# self.global_scope().all_pystring_entries.append(entry)
+
+# def new_const_cname(self):
+# # Create a new globally-unique name for a constant.
+# return self.global_scope().new_const_cname()
+
+ def allocate_temp(self, type):
+ # Allocate a temporary variable of the given type from the
+ # free list if available, otherwise create a new one.
+ # Returns the cname of the variable.
+ for entry in self.free_temp_entries:
+ if entry.type == type:
+ self.free_temp_entries.remove(entry)
+ return entry.cname
+ n = self.temp_counter
+ self.temp_counter = n + 1
+ cname = "%s%d" % (Naming.pyrex_prefix, n)
+ entry = Entry("", cname, type)
+ entry.used = 1
+ if type.is_pyobject:
+ entry.init = "0"
+ self.cname_to_entry[entry.cname] = entry
+ self.temp_entries.append(entry)
+ return entry.cname
+
+ def allocate_temp_pyobject(self):
+ # Allocate a temporary PyObject variable.
+ return self.allocate_temp(py_object_type)
+
+ def release_temp(self, cname):
+ # Release a temporary variable for re-use.
+ if not cname: # can happen when type of an expr is void
+ return
+ entry = self.cname_to_entry[cname]
+ if entry in self.free_temp_entries:
+ raise InternalError("Temporary variable %s released more than once"
+ % cname)
+ self.free_temp_entries.append(entry)
+
+ def temps_in_use(self):
+ # Return a new list of temp entries currently in use.
+ return [entry for entry in self.temp_entries
+ if entry not in self.free_temp_entries]
+
+# def use_utility_code(self, new_code):
+# self.global_scope().use_utility_code(new_code)
+
+ def generate_library_function_declarations(self, code):
+ # Generate extern decls for C library funcs used.
+ #if self.pow_function_used:
+ # code.putln("%s double pow(double, double);" % Naming.extern_c_macro)
+ pass
+
+ def defines_any(self, names):
+ # Test whether any of the given names are
+ # defined in this scope.
+ for name in names:
+ if name in self.entries:
+ return 1
+ return 0
+
+
+class BuiltinScope(Scope):
+ # The builtin namespace.
+ #
+ # type_names {string : 1} Set of type names (used during parsing)
+
+ def __init__(self):
+ Scope.__init__(self, "__builtin__", None, None)
+ self.type_names = {}
+
+ def declare_builtin(self, name, pos):
+ entry = self.declare(name, name, py_object_type, pos)
+ entry.is_builtin = 1
+ return entry
+
+ def declare_builtin_constant(self, name, type, cname, ctype = None):
+ entry = self.declare(name, cname, type, None)
+ if ctype:
+ entry.ctype = ctype
+ entry.is_variable = 1
+ entry.is_cglobal = 1
+ entry.is_readonly = 1
+ return entry
+
+ def declare_builtin_c_type(self, name, type):
+ entry = self.declare_type(name, type, pos = None)
+ self.type_names[name] = 1
+ return entry
+
+ def declare_builtin_cfunction(self, name, type, cname, python_equiv = None,
+ utility_code = None):
+ # If python_equiv == "*", the Python equivalent has the same name
+ # as the entry, otherwise it has the name specified by python_equiv.
+ entry = self.declare_cfunction(name, type, None, cname)
+ entry.utility_code = utility_code
+ if python_equiv:
+ if python_equiv == "*":
+ python_equiv = name
+ var_entry = Entry(python_equiv, python_equiv, py_object_type)
+ var_entry.is_variable = 1
+ var_entry.is_builtin = 1
+ entry.as_variable = var_entry
+ return entry
+
+ def declare_builtin_class(self, name, objstruct_cname, typeobj_cname):
+ type = PyExtensionType(name, typedef_flag = 1, base_type = None)
+ type.module_name = "__builtin__"
+ type.typeptr_cname = "(&%s)" % typeobj_cname
+ type.objstruct_cname = objstruct_cname
+ type.is_builtin = 1
+ scope = CClassScope(name = name, outer_scope = self, visibility = "extern")
+ type.set_scope(scope)
+ entry = self.declare_type(name, type, pos = None, visibility = "extern",
+ defining = 0)
+ self.attach_var_entry_to_c_class(entry)
+ self.type_names[name] = 1
+ return entry
+
+ def find_type(self, name):
+ # Used internally during initialisation, always succeeds
+ entry = self.lookup_here(name)
+ return entry.type
+
+
+class ModuleScope(Scope):
+ # module_name string Python name of the module
+ # module_cname string C name of Python module object
+ # #module_dict_cname string C name of module dict object
+ # method_table_cname string C name of method table
+ # doc string Module doc string
+ # python_include_files [string] Standard Python headers to be included
+ # include_files [string] Other C headers to be included
+ # context Context
+ # pxd_file_loaded boolean Corresponding .pxd file has been processed
+ # cimported_modules [ModuleScope] Modules imported with cimport
+ # types_imported {PyrexType : 1} Set of types for which import code generated
+ # type_names {string : 1} Set of type names (used during parsing)
+ # pyrex_include_files [string] Pyrex sources included with 'include'
+ # gil_used boolean True if GIL is acquired/released anywhere
+
+ gil_used = 0
+
+ def __init__(self, name, parent_module, context):
+ outer_scope = context.find_submodule("__builtin__")
+ Scope.__init__(self, name, outer_scope, parent_module)
+ self.module_name = name
+ self.context = context
+ self.module_cname = Naming.module_cname
+ self.module_dict_cname = Naming.moddict_cname
+ self.method_table_cname = Naming.methtable_cname
+ self.doc = ""
+ self.python_include_files = ["Python.h", "structmember.h"]
+ self.include_files = []
+ self.type_names = self.outer_scope.type_names.copy()
+ self.pxd_file_loaded = 0
+ self.cimported_modules = []
+ self.types_imported = {}
+ self.pyrex_include_files = []
+
+# def qualifying_scope(self):
+# return self.parent_module
+
+ def global_scope(self):
+ return self
+
+ def declare_builtin(self, name, pos):
+ entry = Scope.declare_builtin(self, name, pos)
+ #entry.interned_cname = self.intern(name)
+ return entry
+
+# def intern(self, name):
+# intern_map = self.intern_map
+# cname = intern_map.get(name)
+# if not cname:
+# cname = Naming.interned_prefix + name
+# intern_map[name] = cname
+# self.interned_names.append(name)
+# return cname
+
+ def add_include_file(self, filename):
+ if filename not in self.python_include_files \
+ and filename not in self.include_files:
+ self.include_files.append(filename)
+
+ def add_imported_module(self, scope):
+ #print "add_imported_module:", scope, "to", self ###
+ if scope not in self.cimported_modules:
+ self.cimported_modules.append(scope)
+
+ def add_imported_entry(self, name, entry, pos):
+ if entry not in self.entries:
+ self.entries[name] = entry
+ else:
+ error(pos, "'%s' already declared" % name)
+
+ def declare_module(self, name, scope, pos):
+ # Declare a cimported module. This is represented as a
+ # Python module-level variable entry with a module
+ # scope attached to it. Reports an error and returns
+ # None if previously declared as something else.
+ entry = self.lookup_here(name)
+ if entry:
+ if entry.is_pyglobal and entry.as_module is scope:
+ return entry # Already declared as the same module
+ if not (entry.is_pyglobal and not entry.as_module):
+ #error(pos, "'%s' redeclared" % name)
+ entry.redeclared(pos)
+ return None
+ else:
+ entry = self.declare_var(name, py_object_type, pos)
+ #print "declare_module:", scope, "in", self ###
+ entry.as_module = scope
+ #self.cimported_modules.append(scope)
+ return entry
+
+ def declare_var(self, name, type, pos,
+ cname = None, visibility = 'private', is_cdef = 0):
+ # Add an entry for a global variable. If it is a Python
+ # object type, and not declared with cdef, it will live
+ # in the module dictionary, otherwise it will be a C
+ # global variable.
+ entry = Scope.declare_var(self, name, type, pos,
+ cname, visibility, is_cdef)
+ if not visibility in ('private', 'public', 'extern'):
+ error(pos, "Module-level variable cannot be declared %s" % visibility)
+ if not is_cdef:
+ if not (type.is_pyobject and not type.is_extension_type):
+ raise InternalError(
+ "Non-cdef global variable is not a generic Python object")
+ entry.is_pyglobal = 1
+ entry.namespace_cname = self.module_cname
+ #if Options.intern_names:
+ # entry.interned_cname = self.intern(name)
+ else:
+ entry.is_cglobal = 1
+ self.var_entries.append(entry)
+ return entry
+
+ def declare_global(self, name, pos):
+ entry = self.lookup_here(name)
+ if not entry:
+ self.declare_var(name, py_object_type, pos)
+
+ def add_default_value(self, type):
+ # Add an entry for holding a function argument
+ # default value.
+ cname = "%s%d" % (Naming.default_prefix, self.default_counter)
+ self.default_counter += 1
+ entry = Entry("", cname, type)
+ self.default_entries.append(entry)
+ return entry
+
+# def new_const_cname(self):
+# # Create a new globally-unique name for a constant.
+# n = self.const_counter
+# self.const_counter = n + 1
+# return "%s%d" % (Naming.const_prefix, n)
+
+# def use_utility_code(self, new_code):
+# # Add string to list of utility code to be included,
+# # if not already there (tested using 'is').
+# for old_code in self.utility_code_used:
+# if old_code is new_code:
+# return
+# self.utility_code_used.append(new_code)
+
+ def declare_c_class(self, name, pos, defining = 0, implementing = 0,
+ module_name = None, base_type = None, visibility = 'private',
+ typedef_flag = 0, api = 0, options = None):
+ #
+ # Look for previous declaration as a type
+ #
+ #print "declare_c_class:", name, "in", self ###
+ entry = self.lookup_here(name)
+ if entry:
+ type = entry.type
+ if not (entry.is_type and type.is_extension_type):
+ entry = None # Will cause redeclaration and produce an error
+ else:
+ scope = type.scope
+ defined = scope and scope.defined
+ definitive = defining or (implementing and not defined)
+ self.check_previous_typedef_flag(entry, typedef_flag, pos)
+ if base_type or definitive:
+ if type.base_type and base_type is not type.base_type:
+ error(pos, "Base type does not match previous declaration")
+ type.base_type = base_type
+ #
+ # Make a new entry if needed
+ #
+ if not entry:
+ type = PyExtensionType(name, typedef_flag, base_type)
+ if visibility == 'extern':
+ type.module_name = module_name
+ else:
+ type.module_name = self.qualified_name
+ type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name)
+ entry = self.declare_type(name, type, pos, visibility = visibility,
+ defining = 0)
+ if options and options.objstruct_cname:
+ type.objstruct_cname = options.objstruct_cname
+ elif not entry.in_cinclude:
+ type.objstruct_cname = self.mangle(Naming.objstruct_prefix, name)
+ else:
+ error(entry.pos,
+ "Object name required for 'public' or 'extern' C class")
+ self.attach_var_entry_to_c_class(entry)
+ self.c_class_entries.append(entry)
+ #
+ # Check for re-definition and create scope if needed
+ #
+ scope = type.scope
+ if not scope:
+ if defining or implementing:
+ scope = CClassScope(name = name, outer_scope = self,
+ visibility = visibility, no_gc = options.no_gc)
+ if base_type:
+ scope.declare_inherited_c_attributes(base_type.scope)
+ type.set_scope(scope)
+ self.type_entries.append(entry)
+ else:
+ self.check_for_illegal_incomplete_ctypedef(typedef_flag, pos)
+ else:
+ if defining and scope.defined:
+ error(pos, "C class '%s' already defined" % name)
+ elif implementing and scope.implemented:
+ error(pos, "C class '%s' already implemented" % name)
+ scope.outer_scope = self
+ #
+ # Fill in options, checking for compatibility with any previous declaration
+ #
+ if defining:
+ entry.defined_in_pxd = 1
+ if implementing: # So that filenames in runtime exceptions refer to
+ entry.pos = pos # the .pyx file and not the .pxd file
+ if visibility <> 'private' and entry.visibility <> visibility:
+ error(pos, "Class '%s' previously declared as '%s'"
+ % (name, entry.visibility))
+ if api:
+ entry.api = 1
+ if options:
+ if options.objstruct_cname:
+ if type.objstruct_cname and type.objstruct_cname <> options.objstruct_cname:
+ error(pos, "Object struct name differs from previous declaration")
+ type.objstruct_cname = options.objstruct_cname
+ if options.typeobj_cname:
+ if type.typeobj_cname and type.typeobj_cname <> options.typeobj_cname:
+ error(pos, "Type object name differs from previous declaration")
+ type.typeobj_cname = options.typeobj_cname
+ #
+ # Return new or existing entry
+ #
+ return entry
+
+ def check_for_illegal_incomplete_ctypedef(self, typedef_flag, pos):
+ if typedef_flag and not self.in_cinclude:
+ error(pos, "Forward-referenced type must use 'cdef', not 'ctypedef'")
+
+ def allocate_vtable_names(self, entry):
+ # If extension type has a vtable, allocate vtable struct and
+ # slot names for it.
+ type = entry.type
+ if type.base_type and type.base_type.vtabslot_cname:
+ #print "...allocating vtabslot_cname because base type has one" ###
+ type.vtabslot_cname = "%s.%s" % (
+ Naming.obj_base_cname, type.base_type.vtabslot_cname)
+ elif type.scope and type.scope.cfunc_entries:
+ #print "...allocating vtabslot_cname because there are C methods" ###
+ type.vtabslot_cname = Naming.vtabslot_cname
+ if type.vtabslot_cname:
+ #print "...allocating other vtable related cnames" ###
+ type.vtabstruct_cname = self.mangle(Naming.vtabstruct_prefix, entry.name)
+ type.vtabptr_cname = self.mangle(Naming.vtabptr_prefix, entry.name)
+
+ def check_c_classes(self):
+ # Performs post-analysis checking and finishing up of extension types
+ # being implemented in this module. This is called only for the main
+ # .pyx file scope and its associated .pxd scope, not for cimported .pxd
+ # scopes.
+ #
+ # Checks all extension types declared in this scope to
+ # make sure that:
+ #
+ # * The extension type is implemented
+ # * All required object and type names have been specified or generated
+ # * All non-inherited C methods are implemented
+ #
+ # Also allocates a name for the vtable if needed.
+ #
+ debug_check_c_classes = 0
+ if debug_check_c_classes:
+ print "Scope.check_c_classes: checking scope", self.qualified_name
+ for entry in self.c_class_entries:
+ if debug_check_c_classes:
+ print "...entry", entry.name, entry
+ print "......type =", entry.type
+ print "......visibility =", entry.visibility
+ type = entry.type
+ name = entry.name
+ visibility = entry.visibility
+ # Check defined
+ if not type.scope:
+ error(entry.pos, "C class '%s' is declared but not defined" % name)
+ # Generate typeobj_cname
+ if visibility <> 'extern' and not type.typeobj_cname:
+ type.typeobj_cname = self.mangle(Naming.typeobj_prefix, name)
+ ## Generate typeptr_cname
+ #type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name)
+ # Check C methods defined
+ if type.scope:
+ for method_entry in type.scope.cfunc_entries:
+ if not method_entry.is_inherited and not method_entry.func_cname:
+ error(method_entry.pos, "C method '%s' is declared but not defined" %
+ method_entry.name)
+ # Allocate vtable name if necessary
+ if type.vtabslot_cname:
+ #print "ModuleScope.check_c_classes: allocating vtable cname for", self ###
+ type.vtable_cname = self.mangle(Naming.vtable_prefix, entry.name)
+
+
+class DefinitionScope(ModuleScope):
+ # Scope for the definition part of a module (.pxd).
+ #
+ # parent_module Scope Parent in the import namespace
+ # module_entries {string : Entry} For cimport statements
+
+ def __init__(self, name, parent_module, context):
+ ModuleScope.__init__(self, name, parent_module, context)
+ self.parent_module = parent_module
+ self.module_entries = {}
+
+ def find_module(self, module_name, pos):
+ # Find a module in the import namespace, interpreting
+ # relative imports relative to this module's parent.
+ # Finds and parses the module's .pxd file if the module
+ # has not been referenced before.
+ return self.global_scope().context.find_module(
+ module_name, relative_to = self.parent_module, pos = pos)
+
+ def find_submodule(self, name):
+ # Find and return the definition scope for a submodule of this module,
+ # creating a new empty one if necessary. Doesn't parse .pxd.
+ scope = self.lookup_submodule(name)
+ if not scope:
+ scope = DefinitionScope(name,
+ parent_module = self, context = self.context)
+ self.module_entries[name] = scope
+ return scope
+
+ def lookup_submodule(self, name):
+ # Return scope for submodule of this module, or None.
+ return self.module_entries.get(name, None)
+
+
+class ImplementationScope(ModuleScope):
+ # This scope is used to keep the names declared only in the implementation
+ # part of a module from being seen by other modules that cimport this
+ # module. Also holds information that is only relevant for the
+ # implementation part. When declaring or looking up a name, this scope
+ # behaves as though it and its corresponding definition_scope were a single
+ # scope.
+ #
+ # definition_scope ModuleScope Scope holding definitions from corresponding .pxd
+ # doc_cname string C name of module doc string
+ # default_counter string Counter for naming default values
+ # #const_counter integer Counter for naming constants
+ # #utility_code_used [string] Utility code to be included
+ # default_entries [Entry] Function argument default entries
+ # #string_to_entry {string : Entry} Map string const to entry
+ # #intern_map {string : string} Mapping from Python names to interned strs
+ # #interned_names [string] Interned names pending generation of declarations
+ # #all_pystring_entries [Entry] Python string consts from all scopes
+
+ def __init__(self, def_scope):
+ ModuleScope.__init__(self, def_scope.name, def_scope.parent_scope,
+ def_scope.context)
+ self.definition_scope = def_scope
+ self.doc_cname = Naming.moddoc_cname
+ self.type_names = def_scope.type_names.copy()
+ self.default_counter = 1
+ #self.const_counter = 1
+ #self.utility_code_used = []
+ self.default_entries = []
+ #self.string_to_entry = {}
+ #self.intern_map = {}
+ #self.interned_names = []
+ #self.all_pystring_entries = []
+
+ def lookup_here(self, name):
+ entry = Scope.lookup_here(self, name)
+ if not entry:
+ entry = self.definition_scope.lookup_here(name)
+ return entry
+
+ def find_module(self, module_name, pos):
+ return self.definition_scope.find_module(module_name, pos)
+
+ def check_c_classes(self):
+ self.definition_scope.check_c_classes()
+ ModuleScope.check_c_classes(self)
+
+
+class LocalScope(Scope):
+
+ def __init__(self, name, outer_scope):
+ Scope.__init__(self, name, outer_scope, outer_scope)
+
+ def mangle(self, prefix, name):
+ return prefix + name
+
+ def declare_arg(self, name, type, pos, readonly = 0):
+ # Add an entry for an argument of a function.
+ #print "LocalScope.declare_arg:", name, "readonly =", readonly ###
+ cname = self.mangle(Naming.var_prefix, name)
+ entry = self.declare(name, cname, type, pos)
+ entry.is_variable = 1
+ entry.is_readonly = readonly
+ if type.is_pyobject:
+ entry.init = "0"
+ #entry.borrowed = 1 # Not using borrowed arg refs for now
+ self.arg_entries.append(entry)
+ return entry
+
+ def declare_var(self, name, type, pos,
+ cname = None, visibility = 'private', is_cdef = 0):
+ # Add an entry for a local variable.
+ if visibility in ('public', 'readonly'):
+ error(pos, "Local variable cannot be declared %s" % visibility)
+ entry = Scope.declare_var(self, name, type, pos,
+ cname, visibility, is_cdef)
+ entry.init_to_none = type.is_pyobject
+ self.var_entries.append(entry)
+ return entry
+
+ def declare_global(self, name, pos):
+ # Pull entry from global scope into local scope.
+ if self.lookup_here(name):
+ error(pos, "'%s' already declared")
+ else:
+ entry = self.global_scope().lookup_target(name)
+ self.entries[name] = entry
+
+
+class StructOrUnionScope(Scope):
+ # Namespace of a C struct or union.
+ #
+ # cplus_constructors [CFuncType] C++ constructor signatures
+
+ def __init__(self, is_cplus = False, base_scopes = []):
+ Scope.__init__(self, "?", None, None)
+ self.base_scopes = base_scopes
+ self.is_cplus = is_cplus
+ if is_cplus:
+ constructors = []
+ for base in base_scopes:
+ constructors.extend(base.cplus_constructors)
+ self.cplus_constructors = constructors
+
+ def lookup_here(self, name):
+ entry = Scope.lookup_here(self, name)
+ if not entry:
+ for base in self.base_scopes:
+ entry = base.lookup_here(name)
+ if entry:
+ break
+ return entry
+
+ def declare_var(self, name, type, pos,
+ cname = None, visibility = 'private', **kwds):
+ # Add an entry for an attribute.
+ if not cname:
+ cname = name
+ entry = self.declare(name, cname, type, pos)
+ entry.is_variable = 1
+ self.var_entries.append(entry)
+ if type.is_pyobject:
+ error(pos,
+ "C struct/union member cannot be a Python object")
+ if visibility <> 'private':
+ error(pos,
+ "C struct/union member cannot be declared %s" % visibility)
+ return entry
+
+ def declare_cfunction(self, name, type, pos, **kwds):
+ #print "StructOrUnionScope.declare_cfunction:", name ###
+ if not self.is_cplus:
+ error(pos, "C struct/union member cannot be a function")
+ # Define it anyway to suppress further errors
+ elif name == "__init__":
+ type.pos = pos
+ self.cplus_constructors.append(type)
+ return
+ #kwds['defining'] = 1
+ #Scope.declare_cfunction(self, name, type, pos, *args, **kwds)
+ self.declare_var(name, type, pos, **kwds)
+
+
+class ClassScope(Scope):
+ # Abstract base class for namespace of
+ # Python class or extension type.
+ #
+ # class_name string Pyrex name of the class
+ # scope_prefix string Additional prefix for names
+ # declared in the class
+ # doc string or None Doc string
+
+ def __init__(self, name, outer_scope):
+ Scope.__init__(self, name, outer_scope, outer_scope)
+ self.class_name = name
+ self.doc = None
+
+ def add_string_const(self, value):
+ return self.outer_scope.add_string_const(value)
+
+
+class PyClassScope(ClassScope):
+ # Namespace of a Python class.
+ #
+ # class_dict_cname string C variable holding class dict
+ # class_obj_cname string C variable holding class object
+
+ is_py_class_scope = 1
+
+ def declare_var(self, name, type, pos,
+ cname = None, visibility = 'private', is_cdef = 0):
+ # Add an entry for a class attribute.
+ entry = Scope.declare_var(self, name, type, pos,
+ cname, visibility, is_cdef)
+ entry.is_pyglobal = 1
+ entry.namespace_cname = self.class_obj_cname
+ #if Options.intern_names:
+ # entry.interned_cname = self.intern(name)
+ return entry
+
+ def allocate_temp(self, type):
+ return self.outer_scope.allocate_temp(type)
+
+ def release_temp(self, cname):
+ self.outer_scope.release_temp(cname)
+
+ #def recycle_pending_temps(self):
+ # self.outer_scope.recycle_pending_temps()
+
+ def add_default_value(self, type):
+ return self.outer_scope.add_default_value(type)
+
+
+class CClassScope(ClassScope):
+ # Namespace of an extension type.
+ #
+ # parent_type CClassType
+ # #typeobj_cname string or None
+ # #objstruct_cname string
+ # method_table_cname string
+ # member_table_cname string
+ # getset_table_cname string
+ # has_pyobject_attrs boolean Any PyObject attributes?
+ # pyattr_entries [Entry]
+ # public_attr_entries boolean public/readonly attrs
+ # property_entries [Entry]
+ # defined boolean Defined in .pxd file
+ # implemented boolean Defined in .pyx file
+ # inherited_var_entries [Entry] Adapted var entries from base class
+ # no_gc boolean No GC even if there are Python attributes
+
+ is_c_class_scope = 1
+
+ def __init__(self, name, outer_scope, visibility, no_gc = 0):
+ ClassScope.__init__(self, name, outer_scope)
+ if visibility <> 'extern':
+ self.method_table_cname = outer_scope.mangle(Naming.methtab_prefix, name)
+ self.member_table_cname = outer_scope.mangle(Naming.memtab_prefix, name)
+ self.getset_table_cname = outer_scope.mangle(Naming.gstab_prefix, name)
+ self.has_pyobject_attrs = 0
+ self.pyattr_entries = []
+ self.public_attr_entries = []
+ self.property_entries = []
+ self.inherited_var_entries = []
+ self.defined = 0
+ self.implemented = 0
+ self.no_gc = no_gc
+
+ def needs_gc(self):
+ # If the type or any of its base types have Python-valued
+ # C attributes, then it needs to participate in GC.
+ return self.has_pyobject_attrs or \
+ (self.parent_type.base_type and \
+ self.parent_type.base_type.scope.needs_gc())
+
+ def declare_builtin_var(self, name, type, cname):
+ entry = self.declare(name, cname or name, type, None)
+ entry.is_variable = 1
+ return entry
+
+ def declare_var(self, name, type, pos,
+ cname = None, visibility = 'private', is_cdef = 0):
+ # Add an entry for an attribute.
+ if self.defined:
+ error(pos,
+ "C attributes cannot be added in implementation part of"
+ " extension type")
+ if get_special_method_signature(name):
+ error(pos,
+ "The name '%s' is reserved for a special method."
+ % name)
+ if not cname:
+ cname = name
+ entry = self.declare(name, cname, type, pos)
+ entry.visibility = visibility
+ entry.is_variable = 1
+ self.var_entries.append(entry)
+ if type.is_pyobject and name <> "__weakref__":
+ self.has_pyobject_attrs = 1
+ self.pyattr_entries.append(entry)
+ if visibility not in ('private', 'public', 'readonly'):
+ error(pos,
+ "Attribute of extension type cannot be declared %s" % visibility)
+ if visibility in ('public', 'readonly'):
+ if type.pymemberdef_typecode:
+ self.public_attr_entries.append(entry)
+ if name == "__weakref__":
+ error(pos, "Special attribute __weakref__ cannot be exposed to Python")
+ else:
+ error(pos,
+ "C attribute of type '%s' cannot be accessed from Python" % type)
+ if visibility == 'public' and type.is_extension_type:
+ error(pos,
+ "Non-generic Python attribute cannot be exposed for writing from Python")
+ return entry
+
+ def declare_pyfunction(self, name, pos):
+ # Add an entry for a method.
+ if name == "__new__":
+ error(pos, "__new__ method of extension type will change semantics "
+ "in a future version of Pyrex. Use __cinit__ instead.")
+ name = "__cinit__"
+ entry = self.lookup_here(name)
+ if entry and entry.is_builtin_method:
+ self.overriding_builtin_method(name, pos)
+ else:
+ entry = self.declare(name, name, py_object_type, pos)
+ special_sig = get_special_method_signature(name)
+ if special_sig:
+ entry.is_special = 1
+ entry.signature = special_sig
+ # Special methods don't get put in the method table
+ else:
+ entry.signature = pymethod_signature
+ self.pyfunc_entries.append(entry)
+ return entry
+
+ def overriding_builtin_method(self, name, pos):
+ error(pos, "Cannot override builtin method '%s' of class '%s'" % (
+ name, self.parent_type.base_type.name))
+
+ def lookup_here(self, name):
+ if name == "__new__":
+ name = "__cinit__"
+ return ClassScope.lookup_here(self, name)
+
+ def declare_builtin_method(self, name, type, cname):
+ entry = ClassScope.add_cfunction(self, name, type, None, cname)
+ entry.is_builtin_method = 1
+ return entry
+
+ def declare_cfunction(self, name, type, pos,
+ cname = None, visibility = 'private', defining = 0, api = 0, in_pxd = 0):
+ if get_special_method_signature(name):
+ error(pos, "Special methods must be declared with 'def', not 'cdef'")
+ args = type.args
+ if not args:
+ error(pos, "C method has no self argument")
+ elif not args[0].type.same_as(self.parent_type):
+ error(pos, "Self argument of C method does not match parent type")
+ entry = self.lookup_here(name)
+ if entry:
+ if not entry.is_cfunction:
+ entry.redeclared(pos)
+ elif entry.is_builtin_method:
+ self.overriding_builtin_method(name, pos)
+ else:
+ if defining and entry.func_cname:
+ error(pos, "'%s' already defined" % name)
+ if not entry.type.same_as(type, as_cmethod = 1):
+ error(pos, "Signature does not match previous declaration")
+ error(entry.pos, "Previous declaration is here")
+ else:
+ if self.defined:
+ error(pos,
+ "C method '%s' not previously declared in definition part of"
+ " extension type" % name)
+ entry = self.add_cfunction(name, type, pos, cname or name, visibility)
+ if defining:
+ entry.func_cname = self.mangle(Naming.func_prefix, name)
+ return entry
+
+ def add_cfunction(self, name, type, pos, cname, visibility):
+ # Add a cfunction entry without giving it a func_cname.
+ entry = ClassScope.add_cfunction(self, name, type, pos, cname, visibility)
+ entry.is_cmethod = 1
+ return entry
+
+ def declare_property(self, name, doc, pos):
+ entry = self.declare(name, name, py_object_type, pos)
+ entry.is_property = 1
+ entry.doc = doc
+ entry.scope = PropertyScope(name,
+ outer_scope = self.global_scope(), parent_scope = self)
+ entry.scope.parent_type = self.parent_type
+ self.property_entries.append(entry)
+ return entry
+
+ def declare_inherited_c_attributes(self, base_scope):
+ # Declare entries for all the C attributes of an
+ # inherited type, with cnames modified appropriately
+ # to work with this type.
+ def adapt(cname):
+ return "%s.%s" % (Naming.obj_base_cname, base_entry.cname)
+ for base_entry in \
+ base_scope.inherited_var_entries + base_scope.var_entries:
+ entry = self.declare(base_entry.name, adapt(base_entry.cname),
+ base_entry.type, None)
+ entry.is_variable = 1
+ self.inherited_var_entries.append(entry)
+ for base_entry in base_scope.cfunc_entries:
+ cname = base_entry.cname
+ if base_entry.is_builtin_method:
+ self.entries[base_entry.name] = base_entry
+ else:
+ entry = self.add_cfunction(base_entry.name, base_entry.type,
+ base_entry.pos, adapt(base_entry.cname), base_entry.visibility)
+ entry.is_inherited = 1
+
+
+class PropertyScope(Scope):
+ # Scope holding the __get__, __set__ and __del__ methods for
+ # a property of an extension type.
+ #
+ # parent_type PyExtensionType The type to which the property belongs
+
+ def declare_pyfunction(self, name, pos):
+ # Add an entry for a method.
+ entry = self.declare(name, name, py_object_type, pos)
+ signature = get_property_accessor_signature(name)
+ if signature:
+ entry.is_special = 1
+ entry.signature = signature
+ else:
+ error(pos, "Only __get__, __set__ and __del__ methods allowed "
+ "in a property declaration")
+ entry.signature = pymethod_signature
+ return entry
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/TypeSlots.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/TypeSlots.py
new file mode 100644
index 00000000..9cb858e3
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/TypeSlots.py
@@ -0,0 +1,629 @@
+#
+# Pyrex - Tables describing slots in the type object
+# and associated know-how.
+#
+
+import Naming
+import PyrexTypes
+
+class Signature:
+ # Method slot signature descriptor.
+ #
+ # has_dummy_arg boolean
+ # has_generic_args boolean
+ # fixed_arg_format string
+ # ret_format string
+ # error_value string
+ #
+ # The formats are strings made up of the following
+ # characters:
+ #
+ # 'O' Python object
+ # 'T' Python object of the type of 'self'
+ # 't' Python type object
+ # 'v' void
+ # 'p' void *
+ # 'P' void **
+ # 'i' int
+ # 'I' int *
+ # 'l' long
+ # 'Z' Py_ssize_t
+ # 's' char *
+ # 'S' char **
+ # 'r' int used only to signal exception
+ # '-' dummy 'self' argument (not used)
+ # '*' rest of args passed as generic Python
+ # arg tuple and kw dict (must be last
+ # char in format string)
+
+ format_map = {
+ 'O': PyrexTypes.py_object_type,
+ 't': PyrexTypes.py_type_type,
+ 'v': PyrexTypes.c_void_type,
+ 'p': PyrexTypes.c_void_ptr_type,
+ 'P': PyrexTypes.c_void_ptr_ptr_type,
+ 'b': PyrexTypes.c_int_type, # boolean - no error value
+ 'i': PyrexTypes.c_int_type,
+ 'I': PyrexTypes.c_int_ptr_type,
+ 'l': PyrexTypes.c_long_type,
+ 'Z': PyrexTypes.c_py_ssize_t_type,
+ 's': PyrexTypes.c_char_ptr_type,
+ 'S': PyrexTypes.c_char_ptr_ptr_type,
+ 'r': PyrexTypes.c_returncode_type,
+ # 'T', '-' and '*' are handled otherwise
+ # and are not looked up in here
+ }
+
+ error_value_map = {
+ 'O': "0",
+ 't': "0",
+ 'i': "-1",
+ 'l': "-1",
+ 'r': "-1",
+ 'Z': "-1",
+ }
+
+ def __init__(self, arg_format, ret_format):
+ self.has_dummy_arg = 0
+ self.has_generic_args = 0
+ if arg_format[:1] == '-':
+ self.has_dummy_arg = 1
+ arg_format = arg_format[1:]
+ if arg_format[-1:] == '*':
+ self.has_generic_args = 1
+ arg_format = arg_format[:-1]
+ self.fixed_arg_format = arg_format
+ self.ret_format = ret_format
+ self.error_value = self.error_value_map.get(ret_format, None)
+
+ def num_fixed_args(self):
+ return len(self.fixed_arg_format)
+
+ def is_self_arg(self, i):
+ return self.fixed_arg_format[i] == 'T'
+
+ def fixed_arg_type(self, i):
+ return self.format_map[self.fixed_arg_format[i]]
+
+ def return_type(self):
+ return self.format_map[self.ret_format]
+
+ def exception_value(self):
+ return self.error_value_map.get(self.ret_format)
+
+ def function_type(self, self_type = None):
+ # Construct a C function type descriptor for this signature
+ args = []
+ #for i in xrange(self.num_fixed_args()):
+ # arg_type = self.fixed_arg_type(i)
+ for c in self.fixed_arg_format:
+ if c == "T":
+ assert self_type is not None
+ arg_type = self_type
+ else:
+ arg_type = self.format_map[c]
+ args.append(PyrexTypes.CFuncTypeArg("", arg_type, None))
+ ret_type = self.return_type()
+ exc_value = self.exception_value()
+ return PyrexTypes.CFuncType(ret_type, args, exception_value = exc_value)
+
+
+class SlotDescriptor:
+ # Abstract base class for type slot descriptors.
+ #
+ # slot_name string Member name of the slot in the type object
+ # is_initialised_dynamically Is initialised by code in the module init function
+ # flag Py_TPFLAGS_XXX value indicating presence of slot
+
+ def __init__(self, slot_name, dynamic = 0, flag = None):
+ self.slot_name = slot_name
+ self.is_initialised_dynamically = dynamic
+ self.flag = flag
+
+ def generate(self, scope, code):
+ if self.is_initialised_dynamically:
+ value = 0
+ else:
+ value = self.slot_code(scope)
+ flag = self.flag
+ if flag:
+ code.putln("#if Py_TPFLAGS_DEFAULT & %s" % flag)
+ code.putln("%s, /*%s*/" % (value, self.slot_name))
+ if flag:
+ code.putln("#endif")
+
+ # Some C implementations have trouble statically
+ # initialising a global with a pointer to an extern
+ # function, so we initialise some of the type slots
+ # in the module init function instead.
+
+ def generate_dynamic_init_code(self, scope, code):
+ if self.is_initialised_dynamically:
+ value = self.slot_code(scope)
+ if value <> "0":
+ code.putln("%s.%s = %s;" % (
+ scope.parent_type.typeobj_cname,
+ self.slot_name,
+ value
+ )
+ )
+
+
+class FixedSlot(SlotDescriptor):
+ # Descriptor for a type slot with a fixed value.
+ #
+ # value string
+
+ def __init__(self, slot_name, value):
+ SlotDescriptor.__init__(self, slot_name)
+ self.value = value
+
+ def slot_code(self, scope):
+ return self.value
+
+
+class EmptySlot(FixedSlot):
+ # Descriptor for a type slot whose value is always 0.
+
+ def __init__(self, slot_name):
+ FixedSlot.__init__(self, slot_name, "0")
+
+
+class GCDependentSlot(SlotDescriptor):
+ # Descriptor for a slot whose value depends on whether
+ # the type participates in GC.
+
+ def __init__(self, slot_name, no_gc_value, gc_value, dynamic = 0):
+ SlotDescriptor.__init__(self, slot_name, dynamic)
+ self.no_gc_value = no_gc_value
+ self.gc_value = gc_value
+
+ def slot_code(self, scope):
+ if scope.has_pyobject_attrs:
+ return self.gc_value
+ else:
+ return self.no_gc_value
+
+
+class MethodSlot(SlotDescriptor):
+ # Type slot descriptor for a user-definable method.
+ #
+ # signature Signature
+ # method_name string The __xxx__ name of the method
+ # default string or None Default value of the slot
+
+ def __init__(self, signature, slot_name, method_name, default = None, flag = None):
+ SlotDescriptor.__init__(self, slot_name, flag = flag)
+ self.signature = signature
+ self.slot_name = slot_name
+ self.method_name = method_name
+ self.default = default
+ method_name_to_slot[method_name] = self
+
+ def slot_code(self, scope):
+ entry = scope.lookup_here(self.method_name)
+ if entry:
+ return entry.func_cname
+ else:
+ return "0"
+
+
+class InternalMethodSlot(SlotDescriptor):
+ # Type slot descriptor for a method which is always
+ # synthesized by Pyrex.
+ #
+ # slot_name string Member name of the slot in the type object
+
+ def __init__(self, slot_name):
+ SlotDescriptor.__init__(self, slot_name)
+
+ def slot_code(self, scope):
+ return scope.mangle_internal(self.slot_name)
+
+
+class PyAttrDependentSlot(InternalMethodSlot):
+ # Type slot for a method that is synthesized only
+ # when the extension type has Python-valued attributes.
+
+ def slot_code(self, scope):
+ if scope.pyattr_entries:
+ return InternalMethodSlot.slot_code(self, scope)
+ else:
+ return "0"
+
+
+class SyntheticSlot(InternalMethodSlot):
+ # Type slot descriptor for a synthesized method which
+ # dispatches to one or more user-defined methods depending
+ # on its arguments. If none of the relevant methods are
+ # defined, the method will not be synthesized and an
+ # alternative default value will be placed in the type
+ # slot.
+
+ def __init__(self, slot_name, user_methods, default_value):
+ InternalMethodSlot.__init__(self, slot_name)
+ self.user_methods = user_methods
+ self.default_value = default_value
+
+ def slot_code(self, scope):
+ if scope.defines_any(self.user_methods):
+ return InternalMethodSlot.slot_code(self, scope)
+ else:
+ return self.default_value
+
+
+class TypeFlagsSlot(SlotDescriptor):
+ # Descriptor for the type flags slot.
+
+ def slot_code(self, scope):
+ value = "Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE"
+ if scope.pyattr_entries and not scope.no_gc:
+ value += "|Py_TPFLAGS_HAVE_GC"
+ return value
+
+
+class DocStringSlot(SlotDescriptor):
+ # Descriptor for the docstring slot.
+
+ def slot_code(self, scope):
+ if scope.doc is not None:
+ return '"%s"' % scope.doc
+ else:
+ return "0"
+
+
+class SuiteSlot(SlotDescriptor):
+ # Descriptor for a substructure of the type object.
+ #
+ # sub_slots [SlotDescriptor]
+
+ def __init__(self, sub_slots, slot_type, slot_name):
+ SlotDescriptor.__init__(self, slot_name)
+ self.sub_slots = sub_slots
+ self.slot_type = slot_type
+ substructures.append(self)
+
+ def substructure_cname(self, scope):
+ return "%s%s_%s" % (Naming.pyrex_prefix, self.slot_name, scope.class_name)
+
+ def slot_code(self, scope):
+ return "&%s" % self.substructure_cname(scope)
+
+ def generate_substructure(self, scope, code):
+ code.putln("")
+ code.putln(
+ "static %s %s = {" % (
+ self.slot_type,
+ self.substructure_cname(scope)))
+ for slot in self.sub_slots:
+ slot.generate(scope, code)
+ code.putln("};")
+
+substructures = [] # List of all SuiteSlot instances
+
+class MethodTableSlot(SlotDescriptor):
+ # Slot descriptor for the method table.
+
+ def slot_code(self, scope):
+ return scope.method_table_cname
+
+
+class MemberTableSlot(SlotDescriptor):
+ # Slot descriptor for the table of Python-accessible attributes.
+
+ def slot_code(self, scope):
+ if scope.public_attr_entries:
+ return scope.member_table_cname
+ else:
+ return "0"
+
+
+class GetSetSlot(SlotDescriptor):
+ # Slot descriptor for the table of attribute get & set methods.
+
+ def slot_code(self, scope):
+ if scope.property_entries:
+ return scope.getset_table_cname
+ else:
+ return "0"
+
+
+class BaseClassSlot(SlotDescriptor):
+ # Slot descriptor for the base class slot.
+
+ def __init__(self, name):
+ SlotDescriptor.__init__(self, name, dynamic = 1)
+
+ def generate_dynamic_init_code(self, scope, code):
+ base_type = scope.parent_type.base_type
+ if base_type:
+ code.putln("%s.%s = %s;" % (
+ scope.parent_type.typeobj_cname,
+ self.slot_name,
+ base_type.typeptr_cname))
+
+
+# The following dictionary maps __xxx__ method names to slot descriptors.
+
+method_name_to_slot = {}
+
+## The following slots are (or could be) initialised with an
+## extern function pointer.
+#
+#slots_initialised_from_extern = (
+# "tp_free",
+#)
+
+#------------------------------------------------------------------------------------------
+#
+# Utility functions for accessing slot table data structures
+#
+#------------------------------------------------------------------------------------------
+
+def get_special_method_signature(name):
+ # Given a method name, if it is a special method,
+ # return its signature, else return None.
+ slot = method_name_to_slot.get(name)
+ if slot:
+ return slot.signature
+ else:
+ return None
+
+def get_property_accessor_signature(name):
+ # Return signature of accessor for an extension type
+ # property, else None.
+ return property_accessor_signatures.get(name)
+
+#------------------------------------------------------------------------------------------
+#
+# Signatures for generic Python functions and methods.
+#
+#------------------------------------------------------------------------------------------
+
+pyfunction_signature = Signature("-*", "O")
+pymethod_signature = Signature("T*", "O")
+
+#------------------------------------------------------------------------------------------
+#
+# Signatures for the various kinds of function that
+# can appear in the type object and its substructures.
+#
+#------------------------------------------------------------------------------------------
+
+unaryfunc = Signature("T", "O") # typedef PyObject * (*unaryfunc)(PyObject *);
+binaryfunc = Signature("OO", "O") # typedef PyObject * (*binaryfunc)(PyObject *, PyObject *);
+ibinaryfunc = Signature("TO", "O") # typedef PyObject * (*binaryfunc)(PyObject *, PyObject *);
+ternaryfunc = Signature("OOO", "O") # typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *);
+iternaryfunc = Signature("TOO", "O") # typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *);
+callfunc = Signature("T*", "O") # typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *);
+inquiry = Signature("T", "i") # typedef int (*inquiry)(PyObject *);
+lenfunc = Signature("T", "Z") # typedef Py_ssize_t (*lenfunc)(PyObject *);
+ # typedef int (*coercion)(PyObject **, PyObject **);
+intargfunc = Signature("Ti", "O") # typedef PyObject *(*intargfunc)(PyObject *, int);
+ssizeargfunc = Signature("TZ", "O") # typedef PyObject *(*ssizeargfunc)(PyObject *, Py_ssize_t);
+intintargfunc = Signature("Tii", "O") # typedef PyObject *(*intintargfunc)(PyObject *, int, int);
+ssizessizeargfunc = Signature("TZZ", "O") # typedef PyObject *(*ssizessizeargfunc)(PyObject *, Py_ssize_t, Py_ssize_t);
+intobjargproc = Signature("TiO", 'r') # typedef int(*intobjargproc)(PyObject *, int, PyObject *);
+ssizeobjargproc = Signature("TZO", 'r') # typedef int(*ssizeobjargproc)(PyObject *, Py_ssize_t, PyObject *);
+intintobjargproc = Signature("TiiO", 'r') # typedef int(*intintobjargproc)(PyObject *, int, int, PyObject *);
+ssizessizeobjargproc = Signature("TZZO", 'r') # typedef int(*ssizessizeobjargproc)(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *);
+intintargproc = Signature("Tii", 'r')
+ssizessizeargproc = Signature("TZZ", 'r')
+objargfunc = Signature("TO", "O")
+objobjargproc = Signature("TOO", 'r') # typedef int (*objobjargproc)(PyObject *, PyObject *, PyObject *);
+getreadbufferproc = Signature("TiP", 'i') # typedef int (*getreadbufferproc)(PyObject *, int, void **);
+getwritebufferproc = Signature("TiP", 'i') # typedef int (*getwritebufferproc)(PyObject *, int, void **);
+getsegcountproc = Signature("TI", 'i') # typedef int (*getsegcountproc)(PyObject *, int *);
+getcharbufferproc = Signature("TiS", 'i') # typedef int (*getcharbufferproc)(PyObject *, int, const char **);
+readbufferproc = Signature("TZP", "Z") # typedef Py_ssize_t (*readbufferproc)(PyObject *, Py_ssize_t, void **);
+writebufferproc = Signature("TZP", "Z") # typedef Py_ssize_t (*writebufferproc)(PyObject *, Py_ssize_t, void **);
+segcountproc = Signature("TZ", "Z") # typedef Py_ssize_t (*segcountproc)(PyObject *, Py_ssize_t *);
+writebufferproc = Signature("TZS", "Z") # typedef Py_ssize_t (*charbufferproc)(PyObject *, Py_ssize_t, char **);
+objargproc = Signature("TO", 'r') # typedef int (*objobjproc)(PyObject *, PyObject *);
+ # typedef int (*visitproc)(PyObject *, void *);
+ # typedef int (*traverseproc)(PyObject *, visitproc, void *);
+
+destructor = Signature("T", "v") # typedef void (*destructor)(PyObject *);
+# printfunc = Signature("TFi", 'r') # typedef int (*printfunc)(PyObject *, FILE *, int);
+ # typedef PyObject *(*getattrfunc)(PyObject *, char *);
+getattrofunc = Signature("TO", "O") # typedef PyObject *(*getattrofunc)(PyObject *, PyObject *);
+ # typedef int (*setattrfunc)(PyObject *, char *, PyObject *);
+setattrofunc = Signature("TOO", 'r') # typedef int (*setattrofunc)(PyObject *, PyObject *, PyObject *);
+delattrofunc = Signature("TO", 'r')
+cmpfunc = Signature("TO", "i") # typedef int (*cmpfunc)(PyObject *, PyObject *);
+reprfunc = Signature("T", "O") # typedef PyObject *(*reprfunc)(PyObject *);
+hashfunc = Signature("T", "l") # typedef long (*hashfunc)(PyObject *);
+ # typedef PyObject *(*richcmpfunc) (PyObject *, PyObject *, int);
+richcmpfunc = Signature("OOi", "O") # typedef PyObject *(*richcmpfunc) (PyObject *, PyObject *, int);
+getiterfunc = Signature("T", "O") # typedef PyObject *(*getiterfunc) (PyObject *);
+iternextfunc = Signature("T", "O") # typedef PyObject *(*iternextfunc) (PyObject *);
+descrgetfunc = Signature("TOO", "O") # typedef PyObject *(*descrgetfunc) (PyObject *, PyObject *, PyObject *);
+descrsetfunc = Signature("TOO", 'r') # typedef int (*descrsetfunc) (PyObject *, PyObject *, PyObject *);
+descrdelfunc = Signature("TO", 'r')
+initproc = Signature("T*", 'r') # typedef int (*initproc)(PyObject *, PyObject *, PyObject *);
+ # typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *);
+ # typedef PyObject *(*allocfunc)(struct _typeobject *, int);
+
+#------------------------------------------------------------------------------------------
+#
+# Signatures for accessor methods of properties.
+#
+#------------------------------------------------------------------------------------------
+
+property_accessor_signatures = {
+ '__get__': Signature("T", "O"),
+ '__set__': Signature("TO", 'r'),
+ '__del__': Signature("T", 'r')
+}
+
+#------------------------------------------------------------------------------------------
+#
+# Descriptor tables for the slots of the various type object
+# substructures, in the order they appear in the structure.
+#
+#------------------------------------------------------------------------------------------
+
+PyNumberMethods = (
+ MethodSlot(binaryfunc, "nb_add", "__add__"),
+ MethodSlot(binaryfunc, "nb_subtract", "__sub__"),
+ MethodSlot(binaryfunc, "nb_multiply", "__mul__"),
+ MethodSlot(binaryfunc, "nb_divide", "__div__"),
+ MethodSlot(binaryfunc, "nb_remainder", "__mod__"),
+ MethodSlot(binaryfunc, "nb_divmod", "__divmod__"),
+ MethodSlot(ternaryfunc, "nb_power", "__pow__"),
+ MethodSlot(unaryfunc, "nb_negative", "__neg__"),
+ MethodSlot(unaryfunc, "nb_positive", "__pos__"),
+ MethodSlot(unaryfunc, "nb_absolute", "__abs__"),
+ MethodSlot(inquiry, "nb_nonzero", "__nonzero__"),
+ MethodSlot(unaryfunc, "nb_invert", "__invert__"),
+ MethodSlot(binaryfunc, "nb_lshift", "__lshift__"),
+ MethodSlot(binaryfunc, "nb_rshift", "__rshift__"),
+ MethodSlot(binaryfunc, "nb_and", "__and__"),
+ MethodSlot(binaryfunc, "nb_xor", "__xor__"),
+ MethodSlot(binaryfunc, "nb_or", "__or__"),
+ EmptySlot("nb_coerce"),
+ MethodSlot(unaryfunc, "nb_int", "__int__"),
+ MethodSlot(unaryfunc, "nb_long", "__long__"),
+ MethodSlot(unaryfunc, "nb_float", "__float__"),
+ MethodSlot(unaryfunc, "nb_oct", "__oct__"),
+ MethodSlot(unaryfunc, "nb_hex", "__hex__"),
+
+ # Added in release 2.0
+ MethodSlot(ibinaryfunc, "nb_inplace_add", "__iadd__"),
+ MethodSlot(ibinaryfunc, "nb_inplace_subtract", "__isub__"),
+ MethodSlot(ibinaryfunc, "nb_inplace_multiply", "__imul__"),
+ MethodSlot(ibinaryfunc, "nb_inplace_divide", "__idiv__"),
+ MethodSlot(ibinaryfunc, "nb_inplace_remainder", "__imod__"),
+ MethodSlot(ternaryfunc, "nb_inplace_power", "__ipow__"), # NOT iternaryfunc!!!
+ MethodSlot(ibinaryfunc, "nb_inplace_lshift", "__ilshift__"),
+ MethodSlot(ibinaryfunc, "nb_inplace_rshift", "__irshift__"),
+ MethodSlot(ibinaryfunc, "nb_inplace_and", "__iand__"),
+ MethodSlot(ibinaryfunc, "nb_inplace_xor", "__ixor__"),
+ MethodSlot(ibinaryfunc, "nb_inplace_or", "__ior__"),
+
+ # Added in release 2.2
+ # The following require the Py_TPFLAGS_HAVE_CLASS flag
+ MethodSlot(binaryfunc, "nb_floor_divide", "__floordiv__"),
+ MethodSlot(binaryfunc, "nb_true_divide", "__truediv__"),
+ MethodSlot(ibinaryfunc, "nb_inplace_floor_divide", "__ifloordiv__"),
+ MethodSlot(ibinaryfunc, "nb_inplace_true_divide", "__itruediv__"),
+ MethodSlot(unaryfunc, "nb_index", "__index__", flag = "Py_TPFLAGS_HAVE_INDEX")
+)
+
+PySequenceMethods = (
+ MethodSlot(lenfunc, "sq_length", "__len__"),
+ EmptySlot("sq_concat"), # nb_add used instead
+ EmptySlot("sq_repeat"), # nb_multiply used instead
+ SyntheticSlot("sq_item", ["__getitem__"], "0"), #EmptySlot("sq_item"), # mp_subscript used instead
+ MethodSlot(ssizessizeargfunc, "sq_slice", "__getslice__"),
+ EmptySlot("sq_ass_item"), # mp_ass_subscript used instead
+ SyntheticSlot("sq_ass_slice", ["__setslice__", "__delslice__"], "0"),
+ MethodSlot(cmpfunc, "sq_contains", "__contains__"),
+ EmptySlot("sq_inplace_concat"), # nb_inplace_add used instead
+ EmptySlot("sq_inplace_repeat"), # nb_inplace_multiply used instead
+)
+
+PyMappingMethods = (
+ MethodSlot(lenfunc, "mp_length", "__len__"),
+ MethodSlot(objargfunc, "mp_subscript", "__getitem__"),
+ SyntheticSlot("mp_ass_subscript", ["__setitem__", "__delitem__"], "0"),
+)
+
+PyBufferProcs = (
+ MethodSlot(getreadbufferproc, "bf_getreadbuffer", "__getreadbuffer__"),
+ MethodSlot(getwritebufferproc, "bf_getwritebuffer", "__getwritebuffer__"),
+ MethodSlot(getsegcountproc, "bf_getsegcount", "__getsegcount__"),
+ MethodSlot(getcharbufferproc, "bf_getcharbuffer", "__getcharbuffer__"),
+)
+
+#------------------------------------------------------------------------------------------
+#
+# The main slot table. This table contains descriptors for all the
+# top-level type slots, beginning with tp_dealloc, in the order they
+# appear in the type object.
+#
+#------------------------------------------------------------------------------------------
+
+slot_table = (
+ InternalMethodSlot("tp_dealloc"),
+ EmptySlot("tp_print"), #MethodSlot(printfunc, "tp_print", "__print__"),
+ EmptySlot("tp_getattr"),
+ EmptySlot("tp_setattr"),
+ MethodSlot(cmpfunc, "tp_compare", "__cmp__"),
+ MethodSlot(reprfunc, "tp_repr", "__repr__"),
+
+ SuiteSlot(PyNumberMethods, "PyNumberMethods", "tp_as_number"),
+ SuiteSlot(PySequenceMethods, "PySequenceMethods", "tp_as_sequence"),
+ SuiteSlot(PyMappingMethods, "PyMappingMethods", "tp_as_mapping"),
+
+ MethodSlot(hashfunc, "tp_hash", "__hash__"),
+ MethodSlot(callfunc, "tp_call", "__call__"),
+ MethodSlot(reprfunc, "tp_str", "__str__"),
+
+ SyntheticSlot("tp_getattro", ["__getattr__"], "0"), #"PyObject_GenericGetAttr"),
+ SyntheticSlot("tp_setattro", ["__setattr__", "__delattr__"], "0"), #"PyObject_GenericSetAttr"),
+
+ SuiteSlot(PyBufferProcs, "PyBufferProcs", "tp_as_buffer"),
+
+ TypeFlagsSlot("tp_flags"),
+ DocStringSlot("tp_doc"),
+
+ PyAttrDependentSlot("tp_traverse"),
+ PyAttrDependentSlot("tp_clear"),
+
+ # Later -- synthesize a method to split into separate ops?
+ MethodSlot(richcmpfunc, "tp_richcompare", "__richcmp__"),
+
+ EmptySlot("tp_weaklistoffset"),
+
+ MethodSlot(getiterfunc, "tp_iter", "__iter__"),
+ MethodSlot(iternextfunc, "tp_iternext", "__next__"),
+
+ MethodTableSlot("tp_methods"),
+ MemberTableSlot("tp_members"),
+ GetSetSlot("tp_getset"),
+
+ BaseClassSlot("tp_base"), #EmptySlot("tp_base"),
+ EmptySlot("tp_dict"),
+
+ SyntheticSlot("tp_descr_get", ["__get__"], "0"),
+ SyntheticSlot("tp_descr_set", ["__set__", "__delete__"], "0"),
+
+ EmptySlot("tp_dictoffset"),
+
+ MethodSlot(initproc, "tp_init", "__init__"),
+ EmptySlot("tp_alloc"), #FixedSlot("tp_alloc", "PyType_GenericAlloc"),
+ InternalMethodSlot("tp_new"),
+ # Some versions of Python 2.2 inherit the wrong value for tp_free when the
+ # type has GC but the base type doesn't, so we explicitly set it ourselves
+ # in that case.
+ GCDependentSlot("tp_free", "0", "_PyObject_GC_Del", dynamic = 1),
+
+ EmptySlot("tp_is_gc"),
+ EmptySlot("tp_bases"),
+ EmptySlot("tp_mro"),
+ EmptySlot("tp_cache"),
+ EmptySlot("tp_subclasses"),
+ EmptySlot("tp_weaklist"),
+)
+
+#------------------------------------------------------------------------------------------
+#
+# Descriptors for special methods which don't appear directly
+# in the type object or its substructures. These methods are
+# called from slot functions synthesized by Pyrex.
+#
+#------------------------------------------------------------------------------------------
+
+MethodSlot(initproc, "", "__cinit__")
+MethodSlot(destructor, "", "__dealloc__")
+MethodSlot(objobjargproc, "", "__setitem__")
+MethodSlot(objargproc, "", "__delitem__")
+MethodSlot(ssizessizeobjargproc, "", "__setslice__")
+MethodSlot(ssizessizeargproc, "", "__delslice__")
+MethodSlot(getattrofunc, "", "__getattr__")
+MethodSlot(setattrofunc, "", "__setattr__")
+MethodSlot(delattrofunc, "", "__delattr__")
+MethodSlot(descrgetfunc, "", "__get__")
+MethodSlot(descrsetfunc, "", "__set__")
+MethodSlot(descrdelfunc, "", "__delete__")
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Version.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Version.py
new file mode 100644
index 00000000..3f085698
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/Version.py
@@ -0,0 +1 @@
+version = '0.9.9'
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/__init__.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Compiler/__init__.py
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Debugging.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Debugging.py
new file mode 100644
index 00000000..1fbccd88
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Debugging.py
@@ -0,0 +1,20 @@
+###############################################
+#
+# Odds and ends for debugging
+#
+###############################################
+
+def print_call_chain(*args):
+ import sys
+ print " ".join(map(str, args))
+ f = sys._getframe(1)
+ while f:
+ name = f.f_code.co_name
+ s = f.f_locals.get('self', None)
+ if s:
+ c = getattr(s, "__class__", None)
+ if c:
+ name = "%s.%s" % (c.__name__, name)
+ print "Called from:", name, f.f_lineno
+ f = f.f_back
+ print "-" * 70
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Distutils/__init__.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Distutils/__init__.py
new file mode 100644
index 00000000..49493bf2
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Distutils/__init__.py
@@ -0,0 +1,11 @@
+# July 2002, Graham Fawcett
+#
+# this hack was inspired by the way Thomas Heller got py2exe
+# to appear as a distutil command
+#
+# we replace distutils.command.build_ext with our own version
+# and keep the old one under the module name _build_ext,
+# so that *our* build_ext can make use of it.
+
+from build_ext import build_ext
+from extension import Extension
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Distutils/build_ext.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Distutils/build_ext.py
new file mode 100644
index 00000000..43a4f721
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Distutils/build_ext.py
@@ -0,0 +1,194 @@
+"""Pyrex.Distutils.build_ext
+
+Implements a version of the Distutils 'build_ext' command, for
+building Pyrex extension modules."""
+
+# This module should be kept compatible with Python 2.1.
+
+__revision__ = "$Id:$"
+
+import sys, os, string, re
+from types import *
+from distutils.core import Command
+from distutils.errors import *
+from distutils.sysconfig import customize_compiler, get_python_version
+from distutils.dep_util import newer, newer_group
+from distutils import log
+from distutils.dir_util import mkpath
+try:
+ from Pyrex.Compiler.Main \
+ import CompilationOptions, \
+ default_options as pyrex_default_options, \
+ compile as pyrex_compile
+ from Pyrex.Compiler.Errors import PyrexError
+except ImportError:
+ PyrexError = None
+
+from distutils.command import build_ext as _build_ext
+
+extension_name_re = _build_ext.extension_name_re
+
+show_compilers = _build_ext.show_compilers
+
+class build_ext(_build_ext.build_ext):
+
+ description = "build C/C++ and Pyrex extensions (compile/link to build directory)"
+
+ sep_by = _build_ext.build_ext.sep_by
+ user_options = _build_ext.build_ext.user_options
+ boolean_options = _build_ext.build_ext.boolean_options
+ help_options = _build_ext.build_ext.help_options
+
+ # Add the pyrex specific data.
+ user_options.extend([
+ ('pyrex-cplus', None,
+ "generate C++ source files"),
+ ('pyrex-create-listing', None,
+ "write errors to a listing file"),
+ ('pyrex-include-dirs=', None,
+ "path to the Pyrex include files" + sep_by),
+ ('pyrex-c-in-temp', None,
+ "put generated C files in temp directory"),
+ ('pyrex-gen-pxi', None,
+ "generate .pxi file for public declarations"),
+ ])
+
+ boolean_options.extend([
+ 'pyrex-cplus', 'pyrex-create-listing', 'pyrex-c-in-temp'
+ ])
+
+ def initialize_options(self):
+ _build_ext.build_ext.initialize_options(self)
+ self.pyrex_cplus = 0
+ self.pyrex_create_listing = 0
+ self.pyrex_include_dirs = None
+ self.pyrex_c_in_temp = 0
+ self.pyrex_gen_pxi = 0
+
+ def finalize_options (self):
+ _build_ext.build_ext.finalize_options(self)
+ if self.pyrex_include_dirs is None:
+ self.pyrex_include_dirs = []
+ elif type(self.pyrex_include_dirs) is StringType:
+ self.pyrex_include_dirs = \
+ string.split(self.pyrex_include_dirs, os.pathsep)
+ # finalize_options ()
+
+ def build_extensions(self):
+ # First, sanity-check the 'extensions' list
+ self.check_extensions_list(self.extensions)
+ for ext in self.extensions:
+ ext.sources = self.pyrex_sources(ext.sources, ext)
+ self.build_extension(ext)
+
+ def pyrex_sources(self, sources, extension):
+
+ """
+ Walk the list of source files in 'sources', looking for Pyrex
+ source (.pyx) files. Run Pyrex on all that are found, and return
+ a modified 'sources' list with Pyrex source files replaced by the
+ generated C (or C++) files.
+ """
+
+ if PyrexError == None:
+ raise DistutilsPlatformError, \
+ ("Pyrex does not appear to be installed "
+ "on platform '%s'") % os.name
+
+ new_sources = []
+ pyrex_sources = []
+ pyrex_targets = {}
+
+ # Setup create_list and cplus from the extension options if
+ # Pyrex.Distutils.extension.Extension is used, otherwise just
+ # use what was parsed from the command-line or the configuration file.
+ # cplus will also be set to true is extension.language is equal to
+ # 'C++' or 'c++'.
+ #try:
+ # create_listing = self.pyrex_create_listing or \
+ # extension.pyrex_create_listing
+ # cplus = self.pyrex_cplus or \
+ # extension.pyrex_cplus or \
+ # (extension.language != None and \
+ # extension.language.lower() == 'c++')
+ #except AttributeError:
+ # create_listing = self.pyrex_create_listing
+ # cplus = self.pyrex_cplus or \
+ # (extension.language != None and \
+ # extension.language.lower() == 'c++')
+
+ create_listing = self.pyrex_create_listing or \
+ getattr(extension, 'pyrex_create_listing', 0)
+ cplus = self.pyrex_cplus or getattr(extension, 'pyrex_cplus', 0) or \
+ (extension.language and extension.language.lower() == 'c++')
+ pyrex_gen_pxi = self.pyrex_gen_pxi or getattr(extension, 'pyrex_gen_pxi', 0)
+
+ # Set up the include_path for the Pyres compiler:
+ # 1. Start with the command line option.
+ # 2. Add in any (unique) paths from the extension
+ # pyrex_include_dirs (if Pyrex.Distutils.extension is used).
+ # 3. Add in any (unique) paths from the extension include_dirs
+ includes = self.pyrex_include_dirs
+ try:
+ for i in extension.pyrex_include_dirs:
+ if not i in includes:
+ includes.append(i)
+ except AttributeError:
+ pass
+ for i in extension.include_dirs:
+ if not i in includes:
+ includes.append(i)
+
+ # Set the target_ext to '.c'. Pyrex will change this to '.cpp' if
+ # needed.
+ if cplus:
+ target_ext = '.cpp'
+ else:
+ target_ext = '.c'
+
+ # Decide whether to drop the generated C files into the temp dir
+ # or the source tree.
+
+ if not self.inplace and (self.pyrex_c_in_temp
+ or getattr(extension, 'pyrex_c_in_temp', 0)):
+ target_dir = os.path.join(self.build_temp, "pyrex")
+ else:
+ target_dir = ""
+
+ for source in sources:
+ (base, ext) = os.path.splitext(source)
+ if ext == ".pyx": # Pyrex source file
+ new_sources.append(os.path.join(target_dir, base + target_ext))
+ pyrex_sources.append(source)
+ pyrex_targets[source] = new_sources[-1]
+ else:
+ new_sources.append(source)
+
+ if not pyrex_sources:
+ return new_sources
+
+ for source in pyrex_sources:
+ target = pyrex_targets[source]
+# source_time = os.stat(source).st_mtime
+# try:
+# target_time = os.stat(target).st_mtime
+# newer = source_time > target_time
+# except EnvironmentError:
+# newer = 1
+# if newer:
+ if self.force or newer(source, target):
+ log.info("pyrexc %s --> %s", source, target)
+ self.mkpath(os.path.dirname(target))
+ options = CompilationOptions(pyrex_default_options,
+ use_listing_file = create_listing,
+ include_path = includes,
+ output_file = target,
+ cplus = cplus,
+ generate_pxi = pyrex_gen_pxi)
+ result = pyrex_compile(source, options=options)
+
+ return new_sources
+
+ # pyrex_sources ()
+
+# class build_ext
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Distutils/extension.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Distutils/extension.py
new file mode 100644
index 00000000..5c35557a
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Distutils/extension.py
@@ -0,0 +1,79 @@
+"""Pyrex.Distutils.extension
+
+Provides a modified Extension class, that understands hou to describe
+Pyrex extension modules in setup scripts."""
+
+__revision__ = "$Id:$"
+
+import os, string, sys
+from types import *
+import distutils.extension as _Extension
+
+try:
+ import warnings
+except ImportError:
+ warnings = None
+
+class Extension(_Extension.Extension):
+ _Extension.Extension.__doc__ + \
+ """pyrex_include_dirs : [string]
+ list of directories to search for Pyrex header files (.pxd) (in
+ Unix form for portability)
+ pyrex_create_listing_file : boolean
+ write pyrex error messages to a listing (.lis) file.
+ pyrex_cplus : boolean
+ use the C++ compiler for compiling and linking.
+ pyrex_c_in_temp : boolean
+ put generated C files in temp directory.
+ pyrex_gen_pxi : boolean
+ generate .pxi file for public declarations
+ """
+
+ # When adding arguments to this constructor, be sure to update
+ # user_options.extend in build_ext.py.
+ def __init__ (self, name, sources,
+ include_dirs = None,
+ define_macros = None,
+ undef_macros = None,
+ library_dirs = None,
+ libraries = None,
+ runtime_library_dirs = None,
+ extra_objects = None,
+ extra_compile_args = None,
+ extra_link_args = None,
+ export_symbols = None,
+ #swig_opts = None,
+ depends = None,
+ language = None,
+ pyrex_include_dirs = None,
+ pyrex_create_listing = 0,
+ pyrex_cplus = 0,
+ pyrex_c_in_temp = 0,
+ pyrex_gen_pxi = 0,
+ **kw):
+
+ _Extension.Extension.__init__(self, name, sources,
+ include_dirs = include_dirs,
+ define_macros = define_macros,
+ undef_macros = undef_macros,
+ library_dirs = library_dirs,
+ libraries = libraries,
+ runtime_library_dirs = runtime_library_dirs,
+ extra_objects = extra_objects,
+ extra_compile_args = extra_compile_args,
+ extra_link_args = extra_link_args,
+ export_symbols = export_symbols,
+ #swig_opts = swig_opts,
+ depends = depends,
+ language = language,
+ **kw)
+
+ self.pyrex_include_dirs = pyrex_include_dirs or []
+ self.pyrex_create_listing = pyrex_create_listing
+ self.pyrex_cplus = pyrex_cplus
+ self.pyrex_c_in_temp = pyrex_c_in_temp
+ self.pyrex_gen_pxi = pyrex_gen_pxi
+
+# class Extension
+
+read_setup_file = _Extension.read_setup_file
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/DistutilsOld/__init__.py b/debian/pyrex/pyrex-0.9.9/Pyrex/DistutilsOld/__init__.py
new file mode 100644
index 00000000..5033ac04
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/DistutilsOld/__init__.py
@@ -0,0 +1,22 @@
+# July 2002, Graham Fawcett
+
+#
+
+# this hack was inspired by the way Thomas Heller got py2exe
+
+# to appear as a distutil command
+
+#
+
+# we replace distutils.command.build_ext with our own version
+
+# and keep the old one under the module name _build_ext,
+
+# so that *our* build_ext can make use of it.
+
+
+
+from build_ext import build_ext
+
+
+
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/DistutilsOld/build_ext.py b/debian/pyrex/pyrex-0.9.9/Pyrex/DistutilsOld/build_ext.py
new file mode 100644
index 00000000..95c0a745
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/DistutilsOld/build_ext.py
@@ -0,0 +1,63 @@
+# Subclasses disutils.command.build_ext,
+# replacing it with a Pyrex version that compiles pyx->c
+# before calling the original build_ext command.
+# July 2002, Graham Fawcett
+# Modified by Darrell Gallion <dgallion1@yahoo.com>
+# to allow inclusion of .c files along with .pyx files.
+# Pyrex is (c) Greg Ewing.
+
+import distutils.command.build_ext
+#import Pyrex.Compiler.Main
+from Pyrex.Compiler.Main import CompilationOptions, default_options, compile
+from Pyrex.Compiler.Errors import PyrexError
+from distutils.dep_util import newer
+import os
+import sys
+
+def replace_suffix(path, new_suffix):
+ return os.path.splitext(path)[0] + new_suffix
+
+class build_ext (distutils.command.build_ext.build_ext):
+
+ description = "compile Pyrex scripts, then build C/C++ extensions (compile/link to build directory)"
+
+ def finalize_options (self):
+ distutils.command.build_ext.build_ext.finalize_options(self)
+
+ # The following hack should no longer be needed.
+ if 0:
+ # compiling with mingw32 gets an "initializer not a constant" error
+ # doesn't appear to happen with MSVC!
+ # so if we are compiling with mingw32,
+ # switch to C++ mode, to avoid the problem
+ if self.compiler == 'mingw32':
+ self.swig_cpp = 1
+
+ def swig_sources (self, sources, extension = None):
+ if not self.extensions:
+ return
+
+ # collect the names of the source (.pyx) files
+ pyx_sources = []
+ pyx_sources = [source for source in sources if source.endswith('.pyx')]
+ other_sources = [source for source in sources if not source.endswith('.pyx')]
+
+ #suffix = self.swig_cpp and '.cpp' or '.c'
+ suffix = '.c'
+ for pyx in pyx_sources:
+ # should I raise an exception if it doesn't exist?
+ if os.path.exists(pyx):
+ source = pyx
+ target = replace_suffix(source, suffix)
+ if newer(source, target) or self.force:
+ self.pyrex_compile(source)
+
+ return [replace_suffix(src, suffix) for src in pyx_sources] + other_sources
+
+ def pyrex_compile(self, source):
+ options = CompilationOptions(default_options,
+ include_path = self.include_dirs)
+ result = compile(source, options)
+ if result.num_errors <> 0:
+ sys.exit(1)
+
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/DarwinSystem.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/DarwinSystem.py
new file mode 100644
index 00000000..ebe5f03f
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/DarwinSystem.py
@@ -0,0 +1,85 @@
+#
+# Pyrex - Darwin system interface
+#
+
+verbose = 0
+gcc_pendantic = False
+gcc_no_long_long = True
+gcc_warnings_are_errors = True
+gcc_all_warnings = True
+gcc_optimize = False
+
+import os, sys
+from Pyrex.Utils import replace_suffix
+from Pyrex.Compiler.Errors import PyrexError
+
+version_string = "%s.%s" % sys.version_info[:2]
+
+py_include_dirs = [
+ "/Library/Frameworks/Python.framework/Versions/%s/Headers" % version_string
+]
+
+compilers = ["gcc", "g++"]
+compiler_options = \
+ "-g -c -fno-strict-aliasing -Wno-long-double -no-cpp-precomp " \
+ "-mno-fused-madd -fno-common -dynamic " \
+ .split()
+if gcc_pendantic:
+ compiler_options.append("-pedantic")
+if gcc_no_long_long:
+ compiler_options.append("-Wno-long-long")
+if gcc_warnings_are_errors:
+ compiler_options.append("-Werror")
+if gcc_all_warnings:
+ compiler_options.append("-Wall")
+ compiler_options.append("-Wno-unused-function")
+if gcc_optimize:
+ compiler_options.append("-O")
+
+linkers = ["gcc", "g++"]
+linker_options = \
+ "-Wl,-F.,-w -bundle -undefined dynamic_lookup" \
+ .split()
+#linker_options = \
+# "-Wl,-F.,-w -bundle -framework Python" \
+# .split()
+
+class CCompilerError(PyrexError):
+ pass
+
+def c_compile(c_file, verbose_flag = 0, cplus = 0, obj_suffix = ".o"):
+ # Compile the given C source file to produce
+ # an object file. Returns the pathname of the
+ # resulting file.
+ c_file = os.path.join(os.getcwd(), c_file)
+ o_file = replace_suffix(c_file, obj_suffix)
+ include_options = []
+ for dir in py_include_dirs:
+ include_options.append("-I%s" % dir)
+ compiler = compilers[bool(cplus)]
+ args = [compiler] + compiler_options + include_options + [c_file, "-o", o_file]
+ if verbose_flag or verbose:
+ print " ".join(args)
+ #print compiler, args ###
+ status = os.spawnvp(os.P_WAIT, compiler, args)
+ if status <> 0:
+ raise CCompilerError("C compiler returned status %s" % status)
+ return o_file
+
+def c_link(obj_file, verbose_flag = 0, extra_objects = [], cplus = 0):
+ return c_link_list([obj_file] + extra_objects, verbose_flag, cplus)
+
+def c_link_list(obj_files, verbose_flag = 0, cplus = 0):
+ # Link the given object files into a dynamically
+ # loadable extension file. Returns the pathname
+ # of the resulting file.
+ os.environ["MACOSX_DEPLOYMENT_TARGET"] = "10.3"
+ out_file = replace_suffix(obj_files[0], ".so")
+ linker = linkers[bool(cplus)]
+ args = [linker] + linker_options + obj_files + ["-o", out_file]
+ if verbose_flag or verbose:
+ print " ".join(args)
+ status = os.spawnvp(os.P_WAIT, linker, args)
+ if status <> 0:
+ raise CCompilerError("Linker returned status %s" % status)
+ return out_file
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/MacSystem.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/MacSystem.py
new file mode 100644
index 00000000..c29e0023
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/MacSystem.py
@@ -0,0 +1,135 @@
+#
+# Pyrex -- Mac system interface
+#
+
+import os, sys, string
+import aetools
+from aetools import TalkTo
+from StdSuites.Standard_Suite import Standard_Suite_Events as Standard_Suite
+from Pyrex.Utils import replace_suffix
+from Pyrex.Compiler.Errors import PyrexError
+
+c_compiler = "MWCPPC"
+c_optimizations = "off"
+#c_linker = "PPCLink"
+c_linker = "MWLinkPPC"
+shared_lib_suffix = ".slb"
+
+#py_home = "Python2.2:Home:"
+py_home = sys.exec_prefix
+
+py_include_dirs = (
+ py_home + "Include:",
+ py_home + "Mac:Include:"
+)
+
+pythoncore = py_home + "PythonCore"
+
+mwlibdir = "MPW:Interfaces&Libraries:Libraries:MWPPCLibraries:"
+
+libraries = (
+ #mwlibdir + "'MSL C.PPC.Lib'",
+ #mwlibdir + "'MSL RuntimePPC.Lib'",
+ mwlibdir + "'MSL ShLibRuntime.Lib'",
+ mwlibdir + "InterfaceLib",
+ #mwlibdir + "MathLib",
+ )
+
+class CCompilerError(PyrexError):
+ pass
+
+#---------------- ToolServer ---------------------------
+
+from TS_Misc_Suite import TS_Misc_Suite
+
+class ToolServer(Standard_Suite, TS_Misc_Suite, TalkTo):
+ pass
+
+def send_toolserver_command(cmd):
+ ts = ToolServer('MPSX', start = 1)
+ return ts.DoScript(cmd)
+
+def do_toolserver_command(command):
+ try:
+ result = send_toolserver_command(command)
+ except aetools.Error, e:
+ raise CCompilerError("Apple Event error: %s" % e)
+ errn, stat, stdout, stderr = result
+ if errn:
+ raise CCompilerError("ToolServer error: %s" % errn)
+ stdout = string.replace(stdout, "\r", "\n")
+ stderr = string.replace(stderr, "\r", "\n")
+ if stdout:
+ #print "<<< Begin ToolServer StdOut >>>"
+ sys.stderr.write(stdout)
+ #print "<<< End ToolServer StdOut >>>"
+ if stderr:
+ #print "<<< Begin ToolServer StdErr >>>"
+ sys.stderr.write(stderr)
+ #print "<<< End ToolServer StdErr >>>"
+ return stat
+
+#-------------------------------------------------------
+
+def c_compile(c_file):
+ # Compile the given C source file to produce
+ # an object file. Returns the pathname of the
+ # resulting file.
+ c_file = os.path.join(os.getcwd(), c_file)
+ #print "c_compile: c_file =", repr(c_file) ###
+ c_file_dir = os.path.dirname(c_file)
+ o_file = replace_suffix(c_file, ".o")
+ include_options = ["-i %s" % c_file_dir]
+ for dir in py_include_dirs:
+ include_options.append("-i %s" % dir)
+ command = "%s -opt %s -nomapcr -w off -r %s %s -o %s" % (
+ c_compiler,
+ c_optimizations,
+ string.join(include_options),
+ c_file,
+ o_file,
+ #e_file
+ )
+ #print "...command =", repr(command) ###
+ stat = do_toolserver_command(command)
+ if stat:
+ raise CCompilerError("C compiler returned status %s" % stat)
+ return o_file
+
+def c_link(obj_file):
+ return c_link_list([obj_file])
+
+def c_link_list(obj_files):
+ # Link the given object files into a dynamically
+ # loadable extension file. Returns the pathname
+ # of the resulting file.
+ out_file = replace_suffix(obj_files[0], shared_lib_suffix)
+ command = "%s -xm s -export all %s %s %s -o %s" % (
+ c_linker,
+ string.join(obj_files),
+ pythoncore,
+ string.join(libraries),
+ out_file)
+ stat = do_toolserver_command(command)
+ if stat:
+ raise CCompilerError("Linker returned status %s" % stat)
+ return out_file
+
+def test_c_compile(link = 0):
+ objs = []
+ for arg in sys.argv[1:]:
+ if arg.endswith(".c"):
+ try:
+ obj = c_compile(arg)
+ except PyrexError, e:
+ #print "Caught a PyrexError:" ###
+ #print repr(e) ###
+ print "%s.%s:" % (e.__class__.__module__,
+ e.__class__.__name__), e
+ sys.exit(1)
+ else:
+ obj = arg
+ objs.append(obj)
+ if link:
+ c_link_list(objs)
+
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/MacUtils.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/MacUtils.py
new file mode 100644
index 00000000..91201f45
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/MacUtils.py
@@ -0,0 +1,34 @@
+#
+# Pyrex -- Misc Mac-specific things
+#
+
+import os, MacOS, macfs
+
+def open_new_file(path):
+ # On the Mac, try to preserve Finder position
+ # of previously existing file.
+ fsspec = macfs.FSSpec(path)
+ try:
+ old_finfo = fsspec.GetFInfo()
+ except MacOS.Error, e:
+ #print "MacUtils.open_new_file:", e ###
+ old_finfo = None
+ try:
+ os.unlink(path)
+ except OSError:
+ pass
+ file = open(path, "w")
+ new_finfo = fsspec.GetFInfo()
+ if old_finfo:
+ #print "MacUtils.open_new_file:", path ###
+ #print "...old file info =", old_finfo.Creator, old_finfo.Type, old_finfo.Location ###
+ #print "...new file info =", new_finfo.Creator, new_finfo.Type, new_finfo.Location ###
+ new_finfo.Location = old_finfo.Location
+ new_finfo.Flags = old_finfo.Flags
+ # Make darn sure the type and creator are right. There seems
+ # to be a bug in MacPython 2.2 that screws them up sometimes.
+ new_finfo.Creator = "R*ch"
+ new_finfo.Type = "TEXT"
+ fsspec.SetFInfo(new_finfo)
+ return file
+
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/Makefile b/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/Makefile
new file mode 100644
index 00000000..bf47d83f
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/Makefile
@@ -0,0 +1,24 @@
+# Makefile for Darwin
+
+# Change this to your Python source location
+PYTHON := /Local/Build/Pythonic/python/2.6.1
+
+# Version 2.3:
+#DYNOPT := -framework Python
+# Version 2.4+:
+DYNOPT := -undefined dynamic_lookup
+
+INCLUDE := -I$(PYTHON) -I$(PYTHON)/Include -I$(PYTHON)/Mac/Include
+
+CCOPTS := -fno-strict-aliasing -Wno-long-double -no-cpp-precomp \
+ -mno-fused-madd -fno-common -dynamic
+
+LDOPTS := -Wl,-F.,-w -bundle $(DYNOPT) -framework Carbon
+
+all: _File.so
+
+_File.o: _Filemodule_patched.c
+ gcc -c $(INCLUDE) $(OPTS) $< -o $@
+
+_File.so: _File.o
+ gcc $(LDOPTS) $< -o $@
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/TS_Misc_Suite.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/TS_Misc_Suite.py
new file mode 100644
index 00000000..f1daa7d4
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/TS_Misc_Suite.py
@@ -0,0 +1,64 @@
+"""Suite Misc Suite: Suite that adds additional features to the Application.
+Level 1, version 1
+
+Generated from Macintosh HD:Desktop Folder:ToolServer 3.4.1:ToolServer
+AETE/AEUT resource version 1/0, language 0, script 0
+"""
+
+import aetools
+import MacOS
+
+_code = 'misc'
+
+class TS_Misc_Suite:
+
+ def DoScript(self, _object, _attributes={}, **_arguments):
+ """DoScript: Execute an MPW command, any command that could be executed from the command line can be sent as a script.
+ Required argument: The script to execute
+ Keyword argument _attributes: AppleEvent attribute dictionary
+ """
+ _code = 'misc'
+ _subcode = 'dosc'
+
+ if _arguments: raise TypeError, 'No optional args expected'
+ _arguments['----'] = _object
+
+
+ _reply, _arguments, _attributes = self.send(_code, _subcode,
+ _arguments, _attributes)
+ #if _arguments.has_key('errn'):
+ # raise aetools.Error, aetools.decodeerror(_arguments)
+ # XXXX Optionally decode result
+ #if _arguments.has_key('----'):
+ # return _arguments['----']
+ errn = 0
+ stat = 0
+ stdout = ""
+ stderr = ""
+ if _arguments.has_key('errn'):
+ errn = _arguments['errn']
+ if errn:
+ errn = aetools.decodeerror(_arguments)
+ if _arguments.has_key('stat'):
+ stat = _arguments['stat']
+ if _arguments.has_key('----'):
+ stdout = _arguments['----']
+ if _arguments.has_key('diag'):
+ stderr = _arguments['diag']
+ return (errn, stat, stdout, stderr)
+
+
+#
+# Indices of types declared in this module
+#
+_classdeclarations = {
+}
+
+_propdeclarations = {
+}
+
+_compdeclarations = {
+}
+
+_enumdeclarations = {
+}
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/_Filemodule_patched.c b/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/_Filemodule_patched.c
new file mode 100644
index 00000000..d5aaf2b4
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/_Filemodule_patched.c
@@ -0,0 +1,3345 @@
+/*
+ * This is a hacked version of _Filemodule.c from the Python 2.3
+ * distribution to support access to the finderInfo field of the
+ * FSCatalogInfo data structure.
+ */
+
+/* ========================== Module _File ========================== */
+
+#include "Python.h"
+
+
+
+#ifdef _WIN32
+#include "pywintoolbox.h"
+#else
+#include "macglue.h"
+#include "pymactoolbox.h"
+#endif
+
+/* Macro to test whether a weak-loaded CFM function exists */
+#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL ) {\
+ PyErr_SetString(PyExc_NotImplementedError, \
+ "Not available in this shared library/OS version"); \
+ return NULL; \
+ }} while(0)
+
+
+#ifdef WITHOUT_FRAMEWORKS
+#include <Files.h>
+#else
+#include <Carbon/Carbon.h>
+#endif
+
+#ifdef USE_TOOLBOX_OBJECT_GLUE
+extern int _PyMac_GetFSSpec(PyObject *v, FSSpec *spec);
+extern int _PyMac_GetFSRef(PyObject *v, FSRef *fsr);
+extern PyObject *_PyMac_BuildFSSpec(FSSpec *spec);
+extern PyObject *_PyMac_BuildFSRef(FSRef *spec);
+
+#define PyMac_GetFSSpec _PyMac_GetFSSpec
+#define PyMac_GetFSRef _PyMac_GetFSRef
+#define PyMac_BuildFSSpec _PyMac_BuildFSSpec
+#define PyMac_BuildFSRef _PyMac_BuildFSRef
+#else
+extern int PyMac_GetFSSpec(PyObject *v, FSSpec *spec);
+extern int PyMac_GetFSRef(PyObject *v, FSRef *fsr);
+extern PyObject *PyMac_BuildFSSpec(FSSpec *spec);
+extern PyObject *PyMac_BuildFSRef(FSRef *spec);
+#endif
+
+/* Forward declarations */
+static PyObject *FInfo_New(FInfo *itself);
+static PyObject *FSRef_New(FSRef *itself);
+static PyObject *FSSpec_New(FSSpec *itself);
+static PyObject *Alias_New(AliasHandle itself);
+static int FInfo_Convert(PyObject *v, FInfo *p_itself);
+#define FSRef_Convert PyMac_GetFSRef
+#define FSSpec_Convert PyMac_GetFSSpec
+static int Alias_Convert(PyObject *v, AliasHandle *p_itself);
+
+/*
+** UTCDateTime records
+*/
+static int
+UTCDateTime_Convert(PyObject *v, UTCDateTime *ptr)
+{
+ return PyArg_Parse(v, "(HlH)", &ptr->highSeconds, &ptr->lowSeconds, &ptr->fraction);
+}
+
+static PyObject *
+UTCDateTime_New(UTCDateTime *ptr)
+{
+ return Py_BuildValue("(HlH)", ptr->highSeconds, ptr->lowSeconds, ptr->fraction);
+}
+
+/*
+** Optional fsspec and fsref pointers. None will pass NULL
+*/
+static int
+myPyMac_GetOptFSSpecPtr(PyObject *v, FSSpec **spec)
+{
+ if (v == Py_None) {
+ *spec = NULL;
+ return 1;
+ }
+ return PyMac_GetFSSpec(v, *spec);
+}
+
+static int
+myPyMac_GetOptFSRefPtr(PyObject *v, FSRef **ref)
+{
+ if (v == Py_None) {
+ *ref = NULL;
+ return 1;
+ }
+ return PyMac_GetFSRef(v, *ref);
+}
+
+/*
+** Parse/generate objsect
+*/
+static PyObject *
+PyMac_BuildHFSUniStr255(HFSUniStr255 *itself)
+{
+
+ return Py_BuildValue("u#", itself->unicode, itself->length);
+}
+
+static PyObject *File_Error;
+
+static PyTypeObject FInfo_Type;
+
+#define FInfo_Check(x) ((x)->ob_type == &FInfo_Type || PyObject_TypeCheck((x), &FInfo_Type))
+
+typedef struct FInfoObject {
+ PyObject_HEAD
+ FInfo ob_itself;
+} FInfoObject;
+
+/* ------------------- Object type FSCatalogInfo -------------------- */
+
+static PyTypeObject FSCatalogInfo_Type;
+
+#define FSCatalogInfo_Check(x) ((x)->ob_type == &FSCatalogInfo_Type || PyObject_TypeCheck((x), &FSCatalogInfo_Type))
+
+typedef struct FSCatalogInfoObject {
+ PyObject_HEAD
+ FSCatalogInfo ob_itself;
+} FSCatalogInfoObject;
+
+static PyObject *FSCatalogInfo_New(FSCatalogInfo *itself)
+{
+ FSCatalogInfoObject *it;
+ if (itself == NULL) return Py_None;
+ it = PyObject_NEW(FSCatalogInfoObject, &FSCatalogInfo_Type);
+ if (it == NULL) return NULL;
+ it->ob_itself = *itself;
+ return (PyObject *)it;
+}
+static int FSCatalogInfo_Convert(PyObject *v, FSCatalogInfo *p_itself)
+{
+ if (!FSCatalogInfo_Check(v))
+ {
+ PyErr_SetString(PyExc_TypeError, "FSCatalogInfo required");
+ return 0;
+ }
+ *p_itself = ((FSCatalogInfoObject *)v)->ob_itself;
+ return 1;
+}
+
+static void FSCatalogInfo_dealloc(FSCatalogInfoObject *self)
+{
+ /* Cleanup of self->ob_itself goes here */
+ self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyMethodDef FSCatalogInfo_methods[] = {
+ {NULL, NULL, 0}
+};
+
+static PyObject *FSCatalogInfo_get_nodeFlags(FSCatalogInfoObject *self, void *closure)
+{
+ return Py_BuildValue("H", self->ob_itself.nodeFlags);
+}
+
+static int FSCatalogInfo_set_nodeFlags(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+ return PyArg_Parse(v, "H", &self->ob_itself.nodeFlags)-1;
+ return 0;
+}
+
+static PyObject *FSCatalogInfo_get_volume(FSCatalogInfoObject *self, void *closure)
+{
+ return Py_BuildValue("h", self->ob_itself.volume);
+}
+
+static int FSCatalogInfo_set_volume(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+ return PyArg_Parse(v, "h", &self->ob_itself.volume)-1;
+ return 0;
+}
+
+static PyObject *FSCatalogInfo_get_parentDirID(FSCatalogInfoObject *self, void *closure)
+{
+ return Py_BuildValue("l", self->ob_itself.parentDirID);
+}
+
+static int FSCatalogInfo_set_parentDirID(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+ return PyArg_Parse(v, "l", &self->ob_itself.parentDirID)-1;
+ return 0;
+}
+
+static PyObject *FSCatalogInfo_get_nodeID(FSCatalogInfoObject *self, void *closure)
+{
+ return Py_BuildValue("l", self->ob_itself.nodeID);
+}
+
+static int FSCatalogInfo_set_nodeID(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+ return PyArg_Parse(v, "l", &self->ob_itself.nodeID)-1;
+ return 0;
+}
+
+static PyObject *FSCatalogInfo_get_createDate(FSCatalogInfoObject *self, void *closure)
+{
+ return Py_BuildValue("O&", UTCDateTime_New, &self->ob_itself.createDate);
+}
+
+static int FSCatalogInfo_set_createDate(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+ return PyArg_Parse(v, "O&", UTCDateTime_Convert, &self->ob_itself.createDate)-1;
+ return 0;
+}
+
+static PyObject *FSCatalogInfo_get_contentModDate(FSCatalogInfoObject *self, void *closure)
+{
+ return Py_BuildValue("O&", UTCDateTime_New, &self->ob_itself.contentModDate);
+}
+
+static int FSCatalogInfo_set_contentModDate(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+ return PyArg_Parse(v, "O&", UTCDateTime_Convert, &self->ob_itself.contentModDate)-1;
+ return 0;
+}
+
+static PyObject *FSCatalogInfo_get_attributeModDate(FSCatalogInfoObject *self, void *closure)
+{
+ return Py_BuildValue("O&", UTCDateTime_New, &self->ob_itself.attributeModDate);
+}
+
+static int FSCatalogInfo_set_attributeModDate(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+ return PyArg_Parse(v, "O&", UTCDateTime_Convert, &self->ob_itself.attributeModDate)-1;
+ return 0;
+}
+
+static PyObject *FSCatalogInfo_get_accessDate(FSCatalogInfoObject *self, void *closure)
+{
+ return Py_BuildValue("O&", UTCDateTime_New, &self->ob_itself.accessDate);
+}
+
+static int FSCatalogInfo_set_accessDate(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+ return PyArg_Parse(v, "O&", UTCDateTime_Convert, &self->ob_itself.accessDate)-1;
+ return 0;
+}
+
+static PyObject *FSCatalogInfo_get_backupDate(FSCatalogInfoObject *self, void *closure)
+{
+ return Py_BuildValue("O&", UTCDateTime_New, &self->ob_itself.backupDate);
+}
+
+static int FSCatalogInfo_set_backupDate(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+ return PyArg_Parse(v, "O&", UTCDateTime_Convert, &self->ob_itself.backupDate)-1;
+ return 0;
+}
+
+static PyObject *FSCatalogInfo_get_permissions(FSCatalogInfoObject *self, void *closure)
+{
+ return Py_BuildValue("(llll)", self->ob_itself.permissions[0], self->ob_itself.permissions[1], self->ob_itself.permissions[2], self->ob_itself.permissions[3]);
+}
+
+static int FSCatalogInfo_set_permissions(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+ return PyArg_Parse(v, "(llll)", &self->ob_itself.permissions[0], &self->ob_itself.permissions[1], &self->ob_itself.permissions[2], &self->ob_itself.permissions[3])-1;
+ return 0;
+}
+
+static PyObject *FSCatalogInfo_get_valence(FSCatalogInfoObject *self, void *closure)
+{
+ return Py_BuildValue("l", self->ob_itself.valence);
+}
+
+static int FSCatalogInfo_set_valence(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+ return PyArg_Parse(v, "l", &self->ob_itself.valence)-1;
+ return 0;
+}
+
+static PyObject *FSCatalogInfo_get_dataLogicalSize(FSCatalogInfoObject *self, void *closure)
+{
+ return Py_BuildValue("l", self->ob_itself.dataLogicalSize);
+}
+
+static int FSCatalogInfo_set_dataLogicalSize(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+ return PyArg_Parse(v, "l", &self->ob_itself.dataLogicalSize)-1;
+ return 0;
+}
+
+static PyObject *FSCatalogInfo_get_dataPhysicalSize(FSCatalogInfoObject *self, void *closure)
+{
+ return Py_BuildValue("l", self->ob_itself.dataPhysicalSize);
+}
+
+static int FSCatalogInfo_set_dataPhysicalSize(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+ return PyArg_Parse(v, "l", &self->ob_itself.dataPhysicalSize)-1;
+ return 0;
+}
+
+static PyObject *FSCatalogInfo_get_rsrcLogicalSize(FSCatalogInfoObject *self, void *closure)
+{
+ return Py_BuildValue("l", self->ob_itself.rsrcLogicalSize);
+}
+
+static int FSCatalogInfo_set_rsrcLogicalSize(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+ return PyArg_Parse(v, "l", &self->ob_itself.rsrcLogicalSize)-1;
+ return 0;
+}
+
+static PyObject *FSCatalogInfo_get_rsrcPhysicalSize(FSCatalogInfoObject *self, void *closure)
+{
+ return Py_BuildValue("l", self->ob_itself.rsrcPhysicalSize);
+}
+
+static int FSCatalogInfo_set_rsrcPhysicalSize(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+ return PyArg_Parse(v, "l", &self->ob_itself.rsrcPhysicalSize)-1;
+ return 0;
+}
+
+static PyObject *FSCatalogInfo_get_sharingFlags(FSCatalogInfoObject *self, void *closure)
+{
+ return Py_BuildValue("l", self->ob_itself.sharingFlags);
+}
+
+static int FSCatalogInfo_set_sharingFlags(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+ return PyArg_Parse(v, "l", &self->ob_itself.sharingFlags)-1;
+ return 0;
+}
+
+static PyObject *FSCatalogInfo_get_userPrivileges(FSCatalogInfoObject *self, void *closure)
+{
+ return Py_BuildValue("b", self->ob_itself.userPrivileges);
+}
+
+static int FSCatalogInfo_set_userPrivileges(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+ return PyArg_Parse(v, "b", &self->ob_itself.userPrivileges)-1;
+ return 0;
+}
+
+static PyObject *FSCatalogInfo_get_finderInfo(FSCatalogInfoObject *self, void *closure)
+{
+ return FInfo_New((FInfo *)self->ob_itself.finderInfo);
+}
+
+static int FSCatalogInfo_set_finderInfo(FSCatalogInfoObject *self, PyObject *v, void *closure)
+{
+ if (!FInfo_Check(v)) {
+ PyErr_SetString(PyExc_TypeError, "Expected an FInfo object");
+ return -1;
+ }
+ *(FInfo *)self->ob_itself.finderInfo = ((FInfoObject *)v)->ob_itself;
+ return 0;
+}
+
+static PyGetSetDef FSCatalogInfo_getsetlist[] = {
+ {"nodeFlags", (getter)FSCatalogInfo_get_nodeFlags, (setter)FSCatalogInfo_set_nodeFlags, NULL},
+ {"volume", (getter)FSCatalogInfo_get_volume, (setter)FSCatalogInfo_set_volume, NULL},
+ {"parentDirID", (getter)FSCatalogInfo_get_parentDirID, (setter)FSCatalogInfo_set_parentDirID, NULL},
+ {"nodeID", (getter)FSCatalogInfo_get_nodeID, (setter)FSCatalogInfo_set_nodeID, NULL},
+ {"createDate", (getter)FSCatalogInfo_get_createDate, (setter)FSCatalogInfo_set_createDate, NULL},
+ {"contentModDate", (getter)FSCatalogInfo_get_contentModDate, (setter)FSCatalogInfo_set_contentModDate, NULL},
+ {"attributeModDate", (getter)FSCatalogInfo_get_attributeModDate, (setter)FSCatalogInfo_set_attributeModDate, NULL},
+ {"accessDate", (getter)FSCatalogInfo_get_accessDate, (setter)FSCatalogInfo_set_accessDate, NULL},
+ {"backupDate", (getter)FSCatalogInfo_get_backupDate, (setter)FSCatalogInfo_set_backupDate, NULL},
+ {"permissions", (getter)FSCatalogInfo_get_permissions, (setter)FSCatalogInfo_set_permissions, NULL},
+ {"valence", (getter)FSCatalogInfo_get_valence, (setter)FSCatalogInfo_set_valence, NULL},
+ {"dataLogicalSize", (getter)FSCatalogInfo_get_dataLogicalSize, (setter)FSCatalogInfo_set_dataLogicalSize, NULL},
+ {"dataPhysicalSize", (getter)FSCatalogInfo_get_dataPhysicalSize, (setter)FSCatalogInfo_set_dataPhysicalSize, NULL},
+ {"rsrcLogicalSize", (getter)FSCatalogInfo_get_rsrcLogicalSize, (setter)FSCatalogInfo_set_rsrcLogicalSize, NULL},
+ {"rsrcPhysicalSize", (getter)FSCatalogInfo_get_rsrcPhysicalSize, (setter)FSCatalogInfo_set_rsrcPhysicalSize, NULL},
+ {"sharingFlags", (getter)FSCatalogInfo_get_sharingFlags, (setter)FSCatalogInfo_set_sharingFlags, NULL},
+ {"userPrivileges", (getter)FSCatalogInfo_get_userPrivileges, (setter)FSCatalogInfo_set_userPrivileges, NULL},
+ {"finderInfo", (getter)FSCatalogInfo_get_finderInfo, (setter)FSCatalogInfo_set_finderInfo, NULL},
+ {NULL, NULL, NULL, NULL},
+};
+
+
+#define FSCatalogInfo_compare NULL
+
+#define FSCatalogInfo_repr NULL
+
+#define FSCatalogInfo_hash NULL
+static int FSCatalogInfo_tp_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ static char *kw[] = {
+ "nodeFlags",
+ "volume",
+ "parentDirID",
+ "nodeID",
+ "createDate",
+ "contentModDate",
+ "atributeModDate",
+ "accessDate",
+ "backupDate",
+ "valence",
+ "dataLogicalSize",
+ "dataPhysicalSize",
+ "rsrcLogicalSize",
+ "rsrcPhysicalSize",
+ "sharingFlags",
+ "userPrivileges"
+ , 0};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|HhllO&O&O&O&O&llllllb", kw, &((FSCatalogInfoObject *)self)->ob_itself.nodeFlags,
+ &((FSCatalogInfoObject *)self)->ob_itself.volume,
+ &((FSCatalogInfoObject *)self)->ob_itself.parentDirID,
+ &((FSCatalogInfoObject *)self)->ob_itself.nodeID,
+ UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.createDate,
+ UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.contentModDate,
+ UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.attributeModDate,
+ UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.accessDate,
+ UTCDateTime_Convert, &((FSCatalogInfoObject *)self)->ob_itself.backupDate,
+ &((FSCatalogInfoObject *)self)->ob_itself.valence,
+ &((FSCatalogInfoObject *)self)->ob_itself.dataLogicalSize,
+ &((FSCatalogInfoObject *)self)->ob_itself.dataPhysicalSize,
+ &((FSCatalogInfoObject *)self)->ob_itself.rsrcLogicalSize,
+ &((FSCatalogInfoObject *)self)->ob_itself.rsrcPhysicalSize,
+ &((FSCatalogInfoObject *)self)->ob_itself.sharingFlags,
+ &((FSCatalogInfoObject *)self)->ob_itself.userPrivileges))
+ {
+ return -1;
+ }
+ return 0;
+}
+
+#define FSCatalogInfo_tp_alloc PyType_GenericAlloc
+
+static PyObject *FSCatalogInfo_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *self;
+
+ if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
+ memset(&((FSCatalogInfoObject *)self)->ob_itself, 0, sizeof(FSCatalogInfo));
+ return self;
+}
+
+#define FSCatalogInfo_tp_free PyObject_Del
+
+
+static PyTypeObject FSCatalogInfo_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "Carbon.File.FSCatalogInfo", /*tp_name*/
+ sizeof(FSCatalogInfoObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor) FSCatalogInfo_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)0, /*tp_getattr*/
+ (setattrfunc)0, /*tp_setattr*/
+ (cmpfunc) FSCatalogInfo_compare, /*tp_compare*/
+ (reprfunc) FSCatalogInfo_repr, /*tp_repr*/
+ (PyNumberMethods *)0, /* tp_as_number */
+ (PySequenceMethods *)0, /* tp_as_sequence */
+ (PyMappingMethods *)0, /* tp_as_mapping */
+ (hashfunc) FSCatalogInfo_hash, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ PyObject_GenericGetAttr, /*tp_getattro*/
+ PyObject_GenericSetAttr, /*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*/
+ FSCatalogInfo_methods, /* tp_methods */
+ 0, /*tp_members*/
+ FSCatalogInfo_getsetlist, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ FSCatalogInfo_tp_init, /* tp_init */
+ FSCatalogInfo_tp_alloc, /* tp_alloc */
+ FSCatalogInfo_tp_new, /* tp_new */
+ FSCatalogInfo_tp_free, /* tp_free */
+};
+
+/* ----------------- End object type FSCatalogInfo ------------------ */
+
+
+/* ----------------------- Object type FInfo ------------------------ */
+
+static PyObject *FInfo_New(FInfo *itself)
+{
+ FInfoObject *it;
+ if (itself == NULL) return PyMac_Error(resNotFound);
+ it = PyObject_NEW(FInfoObject, &FInfo_Type);
+ if (it == NULL) return NULL;
+ it->ob_itself = *itself;
+ return (PyObject *)it;
+}
+static int FInfo_Convert(PyObject *v, FInfo *p_itself)
+{
+ if (!FInfo_Check(v))
+ {
+ PyErr_SetString(PyExc_TypeError, "FInfo required");
+ return 0;
+ }
+ *p_itself = ((FInfoObject *)v)->ob_itself;
+ return 1;
+}
+
+static void FInfo_dealloc(FInfoObject *self)
+{
+ /* Cleanup of self->ob_itself goes here */
+ self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyMethodDef FInfo_methods[] = {
+ {NULL, NULL, 0}
+};
+
+static PyObject *FInfo_get_Type(FInfoObject *self, void *closure)
+{
+ return Py_BuildValue("O&", PyMac_BuildOSType, self->ob_itself.fdType);
+}
+
+static int FInfo_set_Type(FInfoObject *self, PyObject *v, void *closure)
+{
+ return PyArg_Parse(v, "O&", PyMac_GetOSType, &self->ob_itself.fdType)-1;
+ return 0;
+}
+
+static PyObject *FInfo_get_Creator(FInfoObject *self, void *closure)
+{
+ return Py_BuildValue("O&", PyMac_BuildOSType, self->ob_itself.fdCreator);
+}
+
+static int FInfo_set_Creator(FInfoObject *self, PyObject *v, void *closure)
+{
+ return PyArg_Parse(v, "O&", PyMac_GetOSType, &self->ob_itself.fdCreator)-1;
+ return 0;
+}
+
+static PyObject *FInfo_get_Flags(FInfoObject *self, void *closure)
+{
+ return Py_BuildValue("H", self->ob_itself.fdFlags);
+}
+
+static int FInfo_set_Flags(FInfoObject *self, PyObject *v, void *closure)
+{
+ return PyArg_Parse(v, "H", &self->ob_itself.fdFlags)-1;
+ return 0;
+}
+
+static PyObject *FInfo_get_Location(FInfoObject *self, void *closure)
+{
+ return Py_BuildValue("O&", PyMac_BuildPoint, self->ob_itself.fdLocation);
+}
+
+static int FInfo_set_Location(FInfoObject *self, PyObject *v, void *closure)
+{
+ return PyArg_Parse(v, "O&", PyMac_GetPoint, &self->ob_itself.fdLocation)-1;
+ return 0;
+}
+
+static PyObject *FInfo_get_Fldr(FInfoObject *self, void *closure)
+{
+ return Py_BuildValue("h", self->ob_itself.fdFldr);
+}
+
+static int FInfo_set_Fldr(FInfoObject *self, PyObject *v, void *closure)
+{
+ return PyArg_Parse(v, "h", &self->ob_itself.fdFldr)-1;
+ return 0;
+}
+
+static PyGetSetDef FInfo_getsetlist[] = {
+ {"Type", (getter)FInfo_get_Type, (setter)FInfo_set_Type, "4-char file type"},
+ {"Creator", (getter)FInfo_get_Creator, (setter)FInfo_set_Creator, "4-char file creator"},
+ {"Flags", (getter)FInfo_get_Flags, (setter)FInfo_set_Flags, "Finder flag bits"},
+ {"Location", (getter)FInfo_get_Location, (setter)FInfo_set_Location, "(x, y) location of the file's icon in its parent finder window"},
+ {"Fldr", (getter)FInfo_get_Fldr, (setter)FInfo_set_Fldr, "Original folder, for 'put away'"},
+ {NULL, NULL, NULL, NULL},
+};
+
+
+#define FInfo_compare NULL
+
+#define FInfo_repr NULL
+
+#define FInfo_hash NULL
+static int FInfo_tp_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ FInfo *itself = NULL;
+ static char *kw[] = {"itself", 0};
+
+ if (PyArg_ParseTupleAndKeywords(args, kwds, "|O&", kw, FInfo_Convert, &itself))
+ {
+ if (itself) memcpy(&((FInfoObject *)self)->ob_itself, itself, sizeof(FInfo));
+ return 0;
+ }
+ return -1;
+}
+
+#define FInfo_tp_alloc PyType_GenericAlloc
+
+static PyObject *FInfo_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *self;
+
+ if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
+ memset(&((FInfoObject *)self)->ob_itself, 0, sizeof(FInfo));
+ return self;
+}
+
+#define FInfo_tp_free PyObject_Del
+
+
+static PyTypeObject FInfo_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "Carbon.File.FInfo", /*tp_name*/
+ sizeof(FInfoObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor) FInfo_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)0, /*tp_getattr*/
+ (setattrfunc)0, /*tp_setattr*/
+ (cmpfunc) FInfo_compare, /*tp_compare*/
+ (reprfunc) FInfo_repr, /*tp_repr*/
+ (PyNumberMethods *)0, /* tp_as_number */
+ (PySequenceMethods *)0, /* tp_as_sequence */
+ (PyMappingMethods *)0, /* tp_as_mapping */
+ (hashfunc) FInfo_hash, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ PyObject_GenericGetAttr, /*tp_getattro*/
+ PyObject_GenericSetAttr, /*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*/
+ FInfo_methods, /* tp_methods */
+ 0, /*tp_members*/
+ FInfo_getsetlist, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ FInfo_tp_init, /* tp_init */
+ FInfo_tp_alloc, /* tp_alloc */
+ FInfo_tp_new, /* tp_new */
+ FInfo_tp_free, /* tp_free */
+};
+
+/* --------------------- End object type FInfo ---------------------- */
+
+
+/* ----------------------- Object type Alias ------------------------ */
+
+static PyTypeObject Alias_Type;
+
+#define Alias_Check(x) ((x)->ob_type == &Alias_Type || PyObject_TypeCheck((x), &Alias_Type))
+
+typedef struct AliasObject {
+ PyObject_HEAD
+ AliasHandle ob_itself;
+ void (*ob_freeit)(AliasHandle ptr);
+} AliasObject;
+
+static PyObject *Alias_New(AliasHandle itself)
+{
+ AliasObject *it;
+ if (itself == NULL) return PyMac_Error(resNotFound);
+ it = PyObject_NEW(AliasObject, &Alias_Type);
+ if (it == NULL) return NULL;
+ it->ob_itself = itself;
+ it->ob_freeit = NULL;
+ return (PyObject *)it;
+}
+static int Alias_Convert(PyObject *v, AliasHandle *p_itself)
+{
+ if (!Alias_Check(v))
+ {
+ PyErr_SetString(PyExc_TypeError, "Alias required");
+ return 0;
+ }
+ *p_itself = ((AliasObject *)v)->ob_itself;
+ return 1;
+}
+
+static void Alias_dealloc(AliasObject *self)
+{
+ if (self->ob_freeit && self->ob_itself)
+ {
+ self->ob_freeit(self->ob_itself);
+ }
+ self->ob_itself = NULL;
+ self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *Alias_ResolveAlias(AliasObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ FSSpec fromFile__buf__;
+ FSSpec *fromFile = &fromFile__buf__;
+ FSSpec target;
+ Boolean wasChanged;
+ if (!PyArg_ParseTuple(_args, "O&",
+ myPyMac_GetOptFSSpecPtr, &fromFile))
+ return NULL;
+ _err = ResolveAlias(fromFile,
+ _self->ob_itself,
+ &target,
+ &wasChanged);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&b",
+ FSSpec_New, &target,
+ wasChanged);
+ return _res;
+}
+
+static PyObject *Alias_GetAliasInfo(AliasObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ AliasInfoType index;
+ Str63 theString;
+ if (!PyArg_ParseTuple(_args, "h",
+ &index))
+ return NULL;
+ _err = GetAliasInfo(_self->ob_itself,
+ index,
+ theString);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&",
+ PyMac_BuildStr255, theString);
+ return _res;
+}
+
+static PyObject *Alias_ResolveAliasWithMountFlags(AliasObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ FSSpec fromFile__buf__;
+ FSSpec *fromFile = &fromFile__buf__;
+ FSSpec target;
+ Boolean wasChanged;
+ unsigned long mountFlags;
+ if (!PyArg_ParseTuple(_args, "O&l",
+ myPyMac_GetOptFSSpecPtr, &fromFile,
+ &mountFlags))
+ return NULL;
+ _err = ResolveAliasWithMountFlags(fromFile,
+ _self->ob_itself,
+ &target,
+ &wasChanged,
+ mountFlags);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&b",
+ FSSpec_New, &target,
+ wasChanged);
+ return _res;
+}
+
+static PyObject *Alias_FollowFinderAlias(AliasObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ FSSpec fromFile__buf__;
+ FSSpec *fromFile = &fromFile__buf__;
+ Boolean logon;
+ FSSpec target;
+ Boolean wasChanged;
+ if (!PyArg_ParseTuple(_args, "O&b",
+ myPyMac_GetOptFSSpecPtr, &fromFile,
+ &logon))
+ return NULL;
+ _err = FollowFinderAlias(fromFile,
+ _self->ob_itself,
+ logon,
+ &target,
+ &wasChanged);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&b",
+ FSSpec_New, &target,
+ wasChanged);
+ return _res;
+}
+
+static PyObject *Alias_FSResolveAliasWithMountFlags(AliasObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ FSRef fromFile__buf__;
+ FSRef *fromFile = &fromFile__buf__;
+ FSRef target;
+ Boolean wasChanged;
+ unsigned long mountFlags;
+ if (!PyArg_ParseTuple(_args, "O&l",
+ myPyMac_GetOptFSRefPtr, &fromFile,
+ &mountFlags))
+ return NULL;
+ _err = FSResolveAliasWithMountFlags(fromFile,
+ _self->ob_itself,
+ &target,
+ &wasChanged,
+ mountFlags);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&b",
+ FSRef_New, &target,
+ wasChanged);
+ return _res;
+}
+
+static PyObject *Alias_FSResolveAlias(AliasObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ FSRef fromFile__buf__;
+ FSRef *fromFile = &fromFile__buf__;
+ FSRef target;
+ Boolean wasChanged;
+ if (!PyArg_ParseTuple(_args, "O&",
+ myPyMac_GetOptFSRefPtr, &fromFile))
+ return NULL;
+ _err = FSResolveAlias(fromFile,
+ _self->ob_itself,
+ &target,
+ &wasChanged);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&b",
+ FSRef_New, &target,
+ wasChanged);
+ return _res;
+}
+
+static PyObject *Alias_FSFollowFinderAlias(AliasObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ FSRef fromFile;
+ Boolean logon;
+ FSRef target;
+ Boolean wasChanged;
+ if (!PyArg_ParseTuple(_args, "b",
+ &logon))
+ return NULL;
+ _err = FSFollowFinderAlias(&fromFile,
+ _self->ob_itself,
+ logon,
+ &target,
+ &wasChanged);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&O&b",
+ FSRef_New, &fromFile,
+ FSRef_New, &target,
+ wasChanged);
+ return _res;
+}
+
+static PyMethodDef Alias_methods[] = {
+ {"ResolveAlias", (PyCFunction)Alias_ResolveAlias, 1,
+ PyDoc_STR("(FSSpec fromFile) -> (FSSpec target, Boolean wasChanged)")},
+ {"GetAliasInfo", (PyCFunction)Alias_GetAliasInfo, 1,
+ PyDoc_STR("(AliasInfoType index) -> (Str63 theString)")},
+ {"ResolveAliasWithMountFlags", (PyCFunction)Alias_ResolveAliasWithMountFlags, 1,
+ PyDoc_STR("(FSSpec fromFile, unsigned long mountFlags) -> (FSSpec target, Boolean wasChanged)")},
+ {"FollowFinderAlias", (PyCFunction)Alias_FollowFinderAlias, 1,
+ PyDoc_STR("(FSSpec fromFile, Boolean logon) -> (FSSpec target, Boolean wasChanged)")},
+ {"FSResolveAliasWithMountFlags", (PyCFunction)Alias_FSResolveAliasWithMountFlags, 1,
+ PyDoc_STR("(FSRef fromFile, unsigned long mountFlags) -> (FSRef target, Boolean wasChanged)")},
+ {"FSResolveAlias", (PyCFunction)Alias_FSResolveAlias, 1,
+ PyDoc_STR("(FSRef fromFile) -> (FSRef target, Boolean wasChanged)")},
+ {"FSFollowFinderAlias", (PyCFunction)Alias_FSFollowFinderAlias, 1,
+ PyDoc_STR("(Boolean logon) -> (FSRef fromFile, FSRef target, Boolean wasChanged)")},
+ {NULL, NULL, 0}
+};
+
+static PyObject *Alias_get_data(AliasObject *self, void *closure)
+{
+ int size;
+ PyObject *rv;
+
+ size = GetHandleSize((Handle)self->ob_itself);
+ HLock((Handle)self->ob_itself);
+ rv = PyString_FromStringAndSize(*(Handle)self->ob_itself, size);
+ HUnlock((Handle)self->ob_itself);
+ return rv;
+
+}
+
+#define Alias_set_data NULL
+
+static PyGetSetDef Alias_getsetlist[] = {
+ {"data", (getter)Alias_get_data, (setter)Alias_set_data, "Raw data of the alias object"},
+ {NULL, NULL, NULL, NULL},
+};
+
+
+#define Alias_compare NULL
+
+#define Alias_repr NULL
+
+#define Alias_hash NULL
+static int Alias_tp_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ AliasHandle itself = NULL;
+ char *rawdata = NULL;
+ int rawdatalen = 0;
+ Handle h;
+ static char *kw[] = {"itself", "rawdata", 0};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&s#", kw, Alias_Convert, &itself, &rawdata, &rawdatalen))
+ return -1;
+ if (itself && rawdata)
+ {
+ PyErr_SetString(PyExc_TypeError, "Only one of itself or rawdata may be specified");
+ return -1;
+ }
+ if (!itself && !rawdata)
+ {
+ PyErr_SetString(PyExc_TypeError, "One of itself or rawdata must be specified");
+ return -1;
+ }
+ if (rawdata)
+ {
+ if ((h = NewHandle(rawdatalen)) == NULL)
+ {
+ PyErr_NoMemory();
+ return -1;
+ }
+ HLock(h);
+ memcpy((char *)*h, rawdata, rawdatalen);
+ HUnlock(h);
+ ((AliasObject *)self)->ob_itself = (AliasHandle)h;
+ return 0;
+ }
+ ((AliasObject *)self)->ob_itself = itself;
+ return 0;
+}
+
+#define Alias_tp_alloc PyType_GenericAlloc
+
+static PyObject *Alias_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *self;
+
+ if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
+ ((AliasObject *)self)->ob_itself = NULL;
+ return self;
+}
+
+#define Alias_tp_free PyObject_Del
+
+
+static PyTypeObject Alias_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "Carbon.File.Alias", /*tp_name*/
+ sizeof(AliasObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor) Alias_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)0, /*tp_getattr*/
+ (setattrfunc)0, /*tp_setattr*/
+ (cmpfunc) Alias_compare, /*tp_compare*/
+ (reprfunc) Alias_repr, /*tp_repr*/
+ (PyNumberMethods *)0, /* tp_as_number */
+ (PySequenceMethods *)0, /* tp_as_sequence */
+ (PyMappingMethods *)0, /* tp_as_mapping */
+ (hashfunc) Alias_hash, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ PyObject_GenericGetAttr, /*tp_getattro*/
+ PyObject_GenericSetAttr, /*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*/
+ Alias_methods, /* tp_methods */
+ 0, /*tp_members*/
+ Alias_getsetlist, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ Alias_tp_init, /* tp_init */
+ Alias_tp_alloc, /* tp_alloc */
+ Alias_tp_new, /* tp_new */
+ Alias_tp_free, /* tp_free */
+};
+
+/* --------------------- End object type Alias ---------------------- */
+
+
+/* ----------------------- Object type FSSpec ----------------------- */
+
+static PyTypeObject FSSpec_Type;
+
+#define FSSpec_Check(x) ((x)->ob_type == &FSSpec_Type || PyObject_TypeCheck((x), &FSSpec_Type))
+
+typedef struct FSSpecObject {
+ PyObject_HEAD
+ FSSpec ob_itself;
+} FSSpecObject;
+
+static PyObject *FSSpec_New(FSSpec *itself)
+{
+ FSSpecObject *it;
+ if (itself == NULL) return PyMac_Error(resNotFound);
+ it = PyObject_NEW(FSSpecObject, &FSSpec_Type);
+ if (it == NULL) return NULL;
+ it->ob_itself = *itself;
+ return (PyObject *)it;
+}
+
+static void FSSpec_dealloc(FSSpecObject *self)
+{
+ /* Cleanup of self->ob_itself goes here */
+ self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *FSSpec_FSpOpenDF(FSSpecObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ SInt8 permission;
+ short refNum;
+ if (!PyArg_ParseTuple(_args, "b",
+ &permission))
+ return NULL;
+ _err = FSpOpenDF(&_self->ob_itself,
+ permission,
+ &refNum);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("h",
+ refNum);
+ return _res;
+}
+
+static PyObject *FSSpec_FSpOpenRF(FSSpecObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ SInt8 permission;
+ short refNum;
+ if (!PyArg_ParseTuple(_args, "b",
+ &permission))
+ return NULL;
+ _err = FSpOpenRF(&_self->ob_itself,
+ permission,
+ &refNum);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("h",
+ refNum);
+ return _res;
+}
+
+static PyObject *FSSpec_FSpCreate(FSSpecObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ OSType creator;
+ OSType fileType;
+ ScriptCode scriptTag;
+ if (!PyArg_ParseTuple(_args, "O&O&h",
+ PyMac_GetOSType, &creator,
+ PyMac_GetOSType, &fileType,
+ &scriptTag))
+ return NULL;
+ _err = FSpCreate(&_self->ob_itself,
+ creator,
+ fileType,
+ scriptTag);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *FSSpec_FSpDirCreate(FSSpecObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ ScriptCode scriptTag;
+ long createdDirID;
+ if (!PyArg_ParseTuple(_args, "h",
+ &scriptTag))
+ return NULL;
+ _err = FSpDirCreate(&_self->ob_itself,
+ scriptTag,
+ &createdDirID);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("l",
+ createdDirID);
+ return _res;
+}
+
+static PyObject *FSSpec_FSpDelete(FSSpecObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ if (!PyArg_ParseTuple(_args, ""))
+ return NULL;
+ _err = FSpDelete(&_self->ob_itself);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *FSSpec_FSpGetFInfo(FSSpecObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ FInfo fndrInfo;
+ if (!PyArg_ParseTuple(_args, ""))
+ return NULL;
+ _err = FSpGetFInfo(&_self->ob_itself,
+ &fndrInfo);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&",
+ FInfo_New, &fndrInfo);
+ return _res;
+}
+
+static PyObject *FSSpec_FSpSetFInfo(FSSpecObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ FInfo fndrInfo;
+ if (!PyArg_ParseTuple(_args, "O&",
+ FInfo_Convert, &fndrInfo))
+ return NULL;
+ _err = FSpSetFInfo(&_self->ob_itself,
+ &fndrInfo);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *FSSpec_FSpSetFLock(FSSpecObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ if (!PyArg_ParseTuple(_args, ""))
+ return NULL;
+ _err = FSpSetFLock(&_self->ob_itself);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *FSSpec_FSpRstFLock(FSSpecObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ if (!PyArg_ParseTuple(_args, ""))
+ return NULL;
+ _err = FSpRstFLock(&_self->ob_itself);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *FSSpec_FSpRename(FSSpecObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ Str255 newName;
+ if (!PyArg_ParseTuple(_args, "O&",
+ PyMac_GetStr255, newName))
+ return NULL;
+ _err = FSpRename(&_self->ob_itself,
+ newName);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *FSSpec_FSpCatMove(FSSpecObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ FSSpec dest;
+ if (!PyArg_ParseTuple(_args, "O&",
+ FSSpec_Convert, &dest))
+ return NULL;
+ _err = FSpCatMove(&_self->ob_itself,
+ &dest);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *FSSpec_FSpExchangeFiles(FSSpecObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ FSSpec dest;
+ if (!PyArg_ParseTuple(_args, "O&",
+ FSSpec_Convert, &dest))
+ return NULL;
+ _err = FSpExchangeFiles(&_self->ob_itself,
+ &dest);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *FSSpec_FSpMakeFSRef(FSSpecObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ FSRef newRef;
+ if (!PyArg_ParseTuple(_args, ""))
+ return NULL;
+ _err = FSpMakeFSRef(&_self->ob_itself,
+ &newRef);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&",
+ FSRef_New, &newRef);
+ return _res;
+}
+
+static PyObject *FSSpec_NewAliasMinimal(FSSpecObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ AliasHandle alias;
+ if (!PyArg_ParseTuple(_args, ""))
+ return NULL;
+ _err = NewAliasMinimal(&_self->ob_itself,
+ &alias);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&",
+ Alias_New, alias);
+ return _res;
+}
+
+static PyObject *FSSpec_IsAliasFile(FSSpecObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ Boolean aliasFileFlag;
+ Boolean folderFlag;
+ if (!PyArg_ParseTuple(_args, ""))
+ return NULL;
+ _err = IsAliasFile(&_self->ob_itself,
+ &aliasFileFlag,
+ &folderFlag);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("bb",
+ aliasFileFlag,
+ folderFlag);
+ return _res;
+}
+
+static PyObject *FSSpec_as_pathname(FSSpecObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+
+ char strbuf[1024];
+ OSErr err;
+
+ if (!PyArg_ParseTuple(_args, ""))
+ return NULL;
+ err = PyMac_GetFullPathname(&_self->ob_itself, strbuf, sizeof(strbuf));
+ if ( err ) {
+ PyMac_Error(err);
+ return NULL;
+ }
+ _res = PyString_FromString(strbuf);
+ return _res;
+
+}
+
+static PyObject *FSSpec_as_tuple(FSSpecObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+
+ if (!PyArg_ParseTuple(_args, ""))
+ return NULL;
+ _res = Py_BuildValue("(iis#)", _self->ob_itself.vRefNum, _self->ob_itself.parID,
+ &_self->ob_itself.name[1], _self->ob_itself.name[0]);
+ return _res;
+
+}
+
+static PyMethodDef FSSpec_methods[] = {
+ {"FSpOpenDF", (PyCFunction)FSSpec_FSpOpenDF, 1,
+ PyDoc_STR("(SInt8 permission) -> (short refNum)")},
+ {"FSpOpenRF", (PyCFunction)FSSpec_FSpOpenRF, 1,
+ PyDoc_STR("(SInt8 permission) -> (short refNum)")},
+ {"FSpCreate", (PyCFunction)FSSpec_FSpCreate, 1,
+ PyDoc_STR("(OSType creator, OSType fileType, ScriptCode scriptTag) -> None")},
+ {"FSpDirCreate", (PyCFunction)FSSpec_FSpDirCreate, 1,
+ PyDoc_STR("(ScriptCode scriptTag) -> (long createdDirID)")},
+ {"FSpDelete", (PyCFunction)FSSpec_FSpDelete, 1,
+ PyDoc_STR("() -> None")},
+ {"FSpGetFInfo", (PyCFunction)FSSpec_FSpGetFInfo, 1,
+ PyDoc_STR("() -> (FInfo fndrInfo)")},
+ {"FSpSetFInfo", (PyCFunction)FSSpec_FSpSetFInfo, 1,
+ PyDoc_STR("(FInfo fndrInfo) -> None")},
+ {"FSpSetFLock", (PyCFunction)FSSpec_FSpSetFLock, 1,
+ PyDoc_STR("() -> None")},
+ {"FSpRstFLock", (PyCFunction)FSSpec_FSpRstFLock, 1,
+ PyDoc_STR("() -> None")},
+ {"FSpRename", (PyCFunction)FSSpec_FSpRename, 1,
+ PyDoc_STR("(Str255 newName) -> None")},
+ {"FSpCatMove", (PyCFunction)FSSpec_FSpCatMove, 1,
+ PyDoc_STR("(FSSpec dest) -> None")},
+ {"FSpExchangeFiles", (PyCFunction)FSSpec_FSpExchangeFiles, 1,
+ PyDoc_STR("(FSSpec dest) -> None")},
+ {"FSpMakeFSRef", (PyCFunction)FSSpec_FSpMakeFSRef, 1,
+ PyDoc_STR("() -> (FSRef newRef)")},
+ {"NewAliasMinimal", (PyCFunction)FSSpec_NewAliasMinimal, 1,
+ PyDoc_STR("() -> (AliasHandle alias)")},
+ {"IsAliasFile", (PyCFunction)FSSpec_IsAliasFile, 1,
+ PyDoc_STR("() -> (Boolean aliasFileFlag, Boolean folderFlag)")},
+ {"as_pathname", (PyCFunction)FSSpec_as_pathname, 1,
+ PyDoc_STR("() -> string")},
+ {"as_tuple", (PyCFunction)FSSpec_as_tuple, 1,
+ PyDoc_STR("() -> (vRefNum, dirID, name)")},
+ {NULL, NULL, 0}
+};
+
+static PyObject *FSSpec_get_data(FSSpecObject *self, void *closure)
+{
+ return PyString_FromStringAndSize((char *)&self->ob_itself, sizeof(self->ob_itself));
+}
+
+#define FSSpec_set_data NULL
+
+static PyGetSetDef FSSpec_getsetlist[] = {
+ {"data", (getter)FSSpec_get_data, (setter)FSSpec_set_data, "Raw data of the FSSpec object"},
+ {NULL, NULL, NULL, NULL},
+};
+
+
+#define FSSpec_compare NULL
+
+static PyObject * FSSpec_repr(FSSpecObject *self)
+{
+ char buf[512];
+ PyOS_snprintf(buf, sizeof(buf), "%s((%d, %ld, '%.*s'))",
+ self->ob_type->tp_name,
+ self->ob_itself.vRefNum,
+ self->ob_itself.parID,
+ self->ob_itself.name[0], self->ob_itself.name+1);
+ return PyString_FromString(buf);
+}
+
+#define FSSpec_hash NULL
+static int FSSpec_tp_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ PyObject *v = NULL;
+ char *rawdata = NULL;
+ int rawdatalen = 0;
+ static char *kw[] = {"itself", "rawdata", 0};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Os#", kw, &v, &rawdata, &rawdatalen))
+ return -1;
+ if (v && rawdata)
+ {
+ PyErr_SetString(PyExc_TypeError, "Only one of itself or rawdata may be specified");
+ return -1;
+ }
+ if (!v && !rawdata)
+ {
+ PyErr_SetString(PyExc_TypeError, "One of itself or rawdata must be specified");
+ return -1;
+ }
+ if (rawdata)
+ {
+ if (rawdatalen != sizeof(FSSpec))
+ {
+ PyErr_SetString(PyExc_TypeError, "FSSpec rawdata incorrect size");
+ return -1;
+ }
+ memcpy(&((FSSpecObject *)self)->ob_itself, rawdata, rawdatalen);
+ return 0;
+ }
+ if (PyMac_GetFSSpec(v, &((FSSpecObject *)self)->ob_itself)) return 0;
+ return -1;
+}
+
+#define FSSpec_tp_alloc PyType_GenericAlloc
+
+static PyObject *FSSpec_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *self;
+
+ if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
+ memset(&((FSSpecObject *)self)->ob_itself, 0, sizeof(FSSpec));
+ return self;
+}
+
+#define FSSpec_tp_free PyObject_Del
+
+
+static PyTypeObject FSSpec_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "Carbon.File.FSSpec", /*tp_name*/
+ sizeof(FSSpecObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor) FSSpec_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)0, /*tp_getattr*/
+ (setattrfunc)0, /*tp_setattr*/
+ (cmpfunc) FSSpec_compare, /*tp_compare*/
+ (reprfunc) FSSpec_repr, /*tp_repr*/
+ (PyNumberMethods *)0, /* tp_as_number */
+ (PySequenceMethods *)0, /* tp_as_sequence */
+ (PyMappingMethods *)0, /* tp_as_mapping */
+ (hashfunc) FSSpec_hash, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ PyObject_GenericGetAttr, /*tp_getattro*/
+ PyObject_GenericSetAttr, /*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*/
+ FSSpec_methods, /* tp_methods */
+ 0, /*tp_members*/
+ FSSpec_getsetlist, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ FSSpec_tp_init, /* tp_init */
+ FSSpec_tp_alloc, /* tp_alloc */
+ FSSpec_tp_new, /* tp_new */
+ FSSpec_tp_free, /* tp_free */
+};
+
+/* --------------------- End object type FSSpec --------------------- */
+
+
+/* ----------------------- Object type FSRef ------------------------ */
+
+static PyTypeObject FSRef_Type;
+
+#define FSRef_Check(x) ((x)->ob_type == &FSRef_Type || PyObject_TypeCheck((x), &FSRef_Type))
+
+typedef struct FSRefObject {
+ PyObject_HEAD
+ FSRef ob_itself;
+} FSRefObject;
+
+static PyObject *FSRef_New(FSRef *itself)
+{
+ FSRefObject *it;
+ if (itself == NULL) return PyMac_Error(resNotFound);
+ it = PyObject_NEW(FSRefObject, &FSRef_Type);
+ if (it == NULL) return NULL;
+ it->ob_itself = *itself;
+ return (PyObject *)it;
+}
+
+static void FSRef_dealloc(FSRefObject *self)
+{
+ /* Cleanup of self->ob_itself goes here */
+ self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyObject *FSRef_FSMakeFSRefUnicode(FSRefObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ UniChar *nameLength__in__;
+ UniCharCount nameLength__len__;
+ int nameLength__in_len__;
+ TextEncoding textEncodingHint;
+ FSRef newRef;
+ if (!PyArg_ParseTuple(_args, "u#l",
+ &nameLength__in__, &nameLength__in_len__,
+ &textEncodingHint))
+ return NULL;
+ nameLength__len__ = nameLength__in_len__;
+ _err = FSMakeFSRefUnicode(&_self->ob_itself,
+ nameLength__len__, nameLength__in__,
+ textEncodingHint,
+ &newRef);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&",
+ FSRef_New, &newRef);
+ return _res;
+}
+
+static PyObject *FSRef_FSCompareFSRefs(FSRefObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ FSRef ref2;
+ if (!PyArg_ParseTuple(_args, "O&",
+ FSRef_Convert, &ref2))
+ return NULL;
+ _err = FSCompareFSRefs(&_self->ob_itself,
+ &ref2);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *FSRef_FSCreateFileUnicode(FSRefObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ UniChar *nameLength__in__;
+ UniCharCount nameLength__len__;
+ int nameLength__in_len__;
+ FSCatalogInfoBitmap whichInfo;
+ FSCatalogInfo catalogInfo;
+ FSRef newRef;
+ FSSpec newSpec;
+ if (!PyArg_ParseTuple(_args, "u#lO&",
+ &nameLength__in__, &nameLength__in_len__,
+ &whichInfo,
+ FSCatalogInfo_Convert, &catalogInfo))
+ return NULL;
+ nameLength__len__ = nameLength__in_len__;
+ _err = FSCreateFileUnicode(&_self->ob_itself,
+ nameLength__len__, nameLength__in__,
+ whichInfo,
+ &catalogInfo,
+ &newRef,
+ &newSpec);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&O&",
+ FSRef_New, &newRef,
+ FSSpec_New, &newSpec);
+ return _res;
+}
+
+static PyObject *FSRef_FSCreateDirectoryUnicode(FSRefObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ UniChar *nameLength__in__;
+ UniCharCount nameLength__len__;
+ int nameLength__in_len__;
+ FSCatalogInfoBitmap whichInfo;
+ FSCatalogInfo catalogInfo;
+ FSRef newRef;
+ FSSpec newSpec;
+ UInt32 newDirID;
+ if (!PyArg_ParseTuple(_args, "u#lO&",
+ &nameLength__in__, &nameLength__in_len__,
+ &whichInfo,
+ FSCatalogInfo_Convert, &catalogInfo))
+ return NULL;
+ nameLength__len__ = nameLength__in_len__;
+ _err = FSCreateDirectoryUnicode(&_self->ob_itself,
+ nameLength__len__, nameLength__in__,
+ whichInfo,
+ &catalogInfo,
+ &newRef,
+ &newSpec,
+ &newDirID);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&O&l",
+ FSRef_New, &newRef,
+ FSSpec_New, &newSpec,
+ newDirID);
+ return _res;
+}
+
+static PyObject *FSRef_FSDeleteObject(FSRefObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ if (!PyArg_ParseTuple(_args, ""))
+ return NULL;
+ _err = FSDeleteObject(&_self->ob_itself);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *FSRef_FSMoveObject(FSRefObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ FSRef destDirectory;
+ FSRef newRef;
+ if (!PyArg_ParseTuple(_args, "O&",
+ FSRef_Convert, &destDirectory))
+ return NULL;
+ _err = FSMoveObject(&_self->ob_itself,
+ &destDirectory,
+ &newRef);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&",
+ FSRef_New, &newRef);
+ return _res;
+}
+
+static PyObject *FSRef_FSExchangeObjects(FSRefObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ FSRef destRef;
+ if (!PyArg_ParseTuple(_args, "O&",
+ FSRef_Convert, &destRef))
+ return NULL;
+ _err = FSExchangeObjects(&_self->ob_itself,
+ &destRef);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *FSRef_FSRenameUnicode(FSRefObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ UniChar *nameLength__in__;
+ UniCharCount nameLength__len__;
+ int nameLength__in_len__;
+ TextEncoding textEncodingHint;
+ FSRef newRef;
+ if (!PyArg_ParseTuple(_args, "u#l",
+ &nameLength__in__, &nameLength__in_len__,
+ &textEncodingHint))
+ return NULL;
+ nameLength__len__ = nameLength__in_len__;
+ _err = FSRenameUnicode(&_self->ob_itself,
+ nameLength__len__, nameLength__in__,
+ textEncodingHint,
+ &newRef);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&",
+ FSRef_New, &newRef);
+ return _res;
+}
+
+static PyObject *FSRef_FSGetCatalogInfo(FSRefObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ FSCatalogInfoBitmap whichInfo;
+ FSCatalogInfo catalogInfo;
+ HFSUniStr255 outName;
+ FSSpec fsSpec;
+ FSRef parentRef;
+ if (!PyArg_ParseTuple(_args, "l",
+ &whichInfo))
+ return NULL;
+ _err = FSGetCatalogInfo(&_self->ob_itself,
+ whichInfo,
+ &catalogInfo,
+ &outName,
+ &fsSpec,
+ &parentRef);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&O&O&O&",
+ FSCatalogInfo_New, &catalogInfo,
+ PyMac_BuildHFSUniStr255, &outName,
+ FSSpec_New, &fsSpec,
+ FSRef_New, &parentRef);
+ return _res;
+}
+
+static PyObject *FSRef_FSSetCatalogInfo(FSRefObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ FSCatalogInfoBitmap whichInfo;
+ FSCatalogInfo catalogInfo;
+ if (!PyArg_ParseTuple(_args, "lO&",
+ &whichInfo,
+ FSCatalogInfo_Convert, &catalogInfo))
+ return NULL;
+ _err = FSSetCatalogInfo(&_self->ob_itself,
+ whichInfo,
+ &catalogInfo);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *FSRef_FSCreateFork(FSRefObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ UniChar *forkNameLength__in__;
+ UniCharCount forkNameLength__len__;
+ int forkNameLength__in_len__;
+ if (!PyArg_ParseTuple(_args, "u#",
+ &forkNameLength__in__, &forkNameLength__in_len__))
+ return NULL;
+ forkNameLength__len__ = forkNameLength__in_len__;
+ _err = FSCreateFork(&_self->ob_itself,
+ forkNameLength__len__, forkNameLength__in__);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *FSRef_FSDeleteFork(FSRefObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ UniChar *forkNameLength__in__;
+ UniCharCount forkNameLength__len__;
+ int forkNameLength__in_len__;
+ if (!PyArg_ParseTuple(_args, "u#",
+ &forkNameLength__in__, &forkNameLength__in_len__))
+ return NULL;
+ forkNameLength__len__ = forkNameLength__in_len__;
+ _err = FSDeleteFork(&_self->ob_itself,
+ forkNameLength__len__, forkNameLength__in__);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *FSRef_FSOpenFork(FSRefObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ UniChar *forkNameLength__in__;
+ UniCharCount forkNameLength__len__;
+ int forkNameLength__in_len__;
+ SInt8 permissions;
+ SInt16 forkRefNum;
+ if (!PyArg_ParseTuple(_args, "u#b",
+ &forkNameLength__in__, &forkNameLength__in_len__,
+ &permissions))
+ return NULL;
+ forkNameLength__len__ = forkNameLength__in_len__;
+ _err = FSOpenFork(&_self->ob_itself,
+ forkNameLength__len__, forkNameLength__in__,
+ permissions,
+ &forkRefNum);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("h",
+ forkRefNum);
+ return _res;
+}
+
+#if TARGET_API_MAC_OSX
+
+static PyObject *FSRef_FNNotify(FSRefObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSStatus _err;
+ FNMessage message;
+ OptionBits flags;
+ if (!PyArg_ParseTuple(_args, "ll",
+ &message,
+ &flags))
+ return NULL;
+ _err = FNNotify(&_self->ob_itself,
+ message,
+ flags);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+#endif
+
+static PyObject *FSRef_FSNewAliasMinimal(FSRefObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ AliasHandle inAlias;
+ if (!PyArg_ParseTuple(_args, ""))
+ return NULL;
+ _err = FSNewAliasMinimal(&_self->ob_itself,
+ &inAlias);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&",
+ Alias_New, inAlias);
+ return _res;
+}
+
+static PyObject *FSRef_FSIsAliasFile(FSRefObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ Boolean aliasFileFlag;
+ Boolean folderFlag;
+ if (!PyArg_ParseTuple(_args, ""))
+ return NULL;
+ _err = FSIsAliasFile(&_self->ob_itself,
+ &aliasFileFlag,
+ &folderFlag);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("bb",
+ aliasFileFlag,
+ folderFlag);
+ return _res;
+}
+
+static PyObject *FSRef_FSRefMakePath(FSRefObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+
+ OSStatus _err;
+#define MAXPATHNAME 1024
+ UInt8 path[MAXPATHNAME];
+ UInt32 maxPathSize = MAXPATHNAME;
+
+ if (!PyArg_ParseTuple(_args, ""))
+ return NULL;
+ _err = FSRefMakePath(&_self->ob_itself,
+ path,
+ maxPathSize);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("s", path);
+ return _res;
+
+}
+
+static PyObject *FSRef_as_pathname(FSRefObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+
+#if TARGET_API_MAC_OSX
+ if (!PyArg_ParseTuple(_args, ""))
+ return NULL;
+ _res = FSRef_FSRefMakePath(_self, _args);
+#else
+ char strbuf[1024];
+ OSErr err;
+ FSSpec fss;
+
+ if (!PyArg_ParseTuple(_args, ""))
+ return NULL;
+ if ( !PyMac_GetFSSpec((PyObject *)_self, &fss))
+ return NULL;
+ err = PyMac_GetFullPathname(&fss, strbuf, sizeof(strbuf));
+ if ( err ) {
+ PyMac_Error(err);
+ return NULL;
+ }
+ _res = PyString_FromString(strbuf);
+#endif
+ return _res;
+
+}
+
+static PyMethodDef FSRef_methods[] = {
+ {"FSMakeFSRefUnicode", (PyCFunction)FSRef_FSMakeFSRefUnicode, 1,
+ PyDoc_STR("(Buffer nameLength, TextEncoding textEncodingHint) -> (FSRef newRef)")},
+ {"FSCompareFSRefs", (PyCFunction)FSRef_FSCompareFSRefs, 1,
+ PyDoc_STR("(FSRef ref2) -> None")},
+ {"FSCreateFileUnicode", (PyCFunction)FSRef_FSCreateFileUnicode, 1,
+ PyDoc_STR("(Buffer nameLength, FSCatalogInfoBitmap whichInfo, FSCatalogInfo catalogInfo) -> (FSRef newRef, FSSpec newSpec)")},
+ {"FSCreateDirectoryUnicode", (PyCFunction)FSRef_FSCreateDirectoryUnicode, 1,
+ PyDoc_STR("(Buffer nameLength, FSCatalogInfoBitmap whichInfo, FSCatalogInfo catalogInfo) -> (FSRef newRef, FSSpec newSpec, UInt32 newDirID)")},
+ {"FSDeleteObject", (PyCFunction)FSRef_FSDeleteObject, 1,
+ PyDoc_STR("() -> None")},
+ {"FSMoveObject", (PyCFunction)FSRef_FSMoveObject, 1,
+ PyDoc_STR("(FSRef destDirectory) -> (FSRef newRef)")},
+ {"FSExchangeObjects", (PyCFunction)FSRef_FSExchangeObjects, 1,
+ PyDoc_STR("(FSRef destRef) -> None")},
+ {"FSRenameUnicode", (PyCFunction)FSRef_FSRenameUnicode, 1,
+ PyDoc_STR("(Buffer nameLength, TextEncoding textEncodingHint) -> (FSRef newRef)")},
+ {"FSGetCatalogInfo", (PyCFunction)FSRef_FSGetCatalogInfo, 1,
+ PyDoc_STR("(FSCatalogInfoBitmap whichInfo) -> (FSCatalogInfo catalogInfo, HFSUniStr255 outName, FSSpec fsSpec, FSRef parentRef)")},
+ {"FSSetCatalogInfo", (PyCFunction)FSRef_FSSetCatalogInfo, 1,
+ PyDoc_STR("(FSCatalogInfoBitmap whichInfo, FSCatalogInfo catalogInfo) -> None")},
+ {"FSCreateFork", (PyCFunction)FSRef_FSCreateFork, 1,
+ PyDoc_STR("(Buffer forkNameLength) -> None")},
+ {"FSDeleteFork", (PyCFunction)FSRef_FSDeleteFork, 1,
+ PyDoc_STR("(Buffer forkNameLength) -> None")},
+ {"FSOpenFork", (PyCFunction)FSRef_FSOpenFork, 1,
+ PyDoc_STR("(Buffer forkNameLength, SInt8 permissions) -> (SInt16 forkRefNum)")},
+
+#if TARGET_API_MAC_OSX
+ {"FNNotify", (PyCFunction)FSRef_FNNotify, 1,
+ PyDoc_STR("(FNMessage message, OptionBits flags) -> None")},
+#endif
+ {"FSNewAliasMinimal", (PyCFunction)FSRef_FSNewAliasMinimal, 1,
+ PyDoc_STR("() -> (AliasHandle inAlias)")},
+ {"FSIsAliasFile", (PyCFunction)FSRef_FSIsAliasFile, 1,
+ PyDoc_STR("() -> (Boolean aliasFileFlag, Boolean folderFlag)")},
+ {"FSRefMakePath", (PyCFunction)FSRef_FSRefMakePath, 1,
+ PyDoc_STR("() -> string")},
+ {"as_pathname", (PyCFunction)FSRef_as_pathname, 1,
+ PyDoc_STR("() -> string")},
+ {NULL, NULL, 0}
+};
+
+static PyObject *FSRef_get_data(FSRefObject *self, void *closure)
+{
+ return PyString_FromStringAndSize((char *)&self->ob_itself, sizeof(self->ob_itself));
+}
+
+#define FSRef_set_data NULL
+
+static PyGetSetDef FSRef_getsetlist[] = {
+ {"data", (getter)FSRef_get_data, (setter)FSRef_set_data, "Raw data of the FSRef object"},
+ {NULL, NULL, NULL, NULL},
+};
+
+
+#define FSRef_compare NULL
+
+#define FSRef_repr NULL
+
+#define FSRef_hash NULL
+static int FSRef_tp_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ PyObject *v = NULL;
+ char *rawdata = NULL;
+ int rawdatalen = 0;
+ static char *kw[] = {"itself", "rawdata", 0};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Os#", kw, &v, &rawdata, &rawdatalen))
+ return -1;
+ if (v && rawdata)
+ {
+ PyErr_SetString(PyExc_TypeError, "Only one of itself or rawdata may be specified");
+ return -1;
+ }
+ if (!v && !rawdata)
+ {
+ PyErr_SetString(PyExc_TypeError, "One of itself or rawdata must be specified");
+ return -1;
+ }
+ if (rawdata)
+ {
+ if (rawdatalen != sizeof(FSRef))
+ {
+ PyErr_SetString(PyExc_TypeError, "FSRef rawdata incorrect size");
+ return -1;
+ }
+ memcpy(&((FSRefObject *)self)->ob_itself, rawdata, rawdatalen);
+ return 0;
+ }
+ if (PyMac_GetFSRef(v, &((FSRefObject *)self)->ob_itself)) return 0;
+ return -1;
+}
+
+#define FSRef_tp_alloc PyType_GenericAlloc
+
+static PyObject *FSRef_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *self;
+
+ if ((self = type->tp_alloc(type, 0)) == NULL) return NULL;
+ memset(&((FSRefObject *)self)->ob_itself, 0, sizeof(FSRef));
+ return self;
+}
+
+#define FSRef_tp_free PyObject_Del
+
+
+static PyTypeObject FSRef_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "Carbon.File.FSRef", /*tp_name*/
+ sizeof(FSRefObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor) FSRef_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)0, /*tp_getattr*/
+ (setattrfunc)0, /*tp_setattr*/
+ (cmpfunc) FSRef_compare, /*tp_compare*/
+ (reprfunc) FSRef_repr, /*tp_repr*/
+ (PyNumberMethods *)0, /* tp_as_number */
+ (PySequenceMethods *)0, /* tp_as_sequence */
+ (PyMappingMethods *)0, /* tp_as_mapping */
+ (hashfunc) FSRef_hash, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ PyObject_GenericGetAttr, /*tp_getattro*/
+ PyObject_GenericSetAttr, /*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*/
+ FSRef_methods, /* tp_methods */
+ 0, /*tp_members*/
+ FSRef_getsetlist, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ FSRef_tp_init, /* tp_init */
+ FSRef_tp_alloc, /* tp_alloc */
+ FSRef_tp_new, /* tp_new */
+ FSRef_tp_free, /* tp_free */
+};
+
+/* --------------------- End object type FSRef ---------------------- */
+
+
+static PyObject *File_UnmountVol(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ Str63 volName;
+ short vRefNum;
+ if (!PyArg_ParseTuple(_args, "O&h",
+ PyMac_GetStr255, volName,
+ &vRefNum))
+ return NULL;
+ _err = UnmountVol(volName,
+ vRefNum);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *File_FlushVol(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ Str63 volName;
+ short vRefNum;
+ if (!PyArg_ParseTuple(_args, "O&h",
+ PyMac_GetStr255, volName,
+ &vRefNum))
+ return NULL;
+ _err = FlushVol(volName,
+ vRefNum);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *File_HSetVol(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ Str63 volName;
+ short vRefNum;
+ long dirID;
+ if (!PyArg_ParseTuple(_args, "O&hl",
+ PyMac_GetStr255, volName,
+ &vRefNum,
+ &dirID))
+ return NULL;
+ _err = HSetVol(volName,
+ vRefNum,
+ dirID);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *File_FSClose(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ short refNum;
+ if (!PyArg_ParseTuple(_args, "h",
+ &refNum))
+ return NULL;
+ _err = FSClose(refNum);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *File_Allocate(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ short refNum;
+ long count;
+ if (!PyArg_ParseTuple(_args, "h",
+ &refNum))
+ return NULL;
+ _err = Allocate(refNum,
+ &count);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("l",
+ count);
+ return _res;
+}
+
+static PyObject *File_GetEOF(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ short refNum;
+ long logEOF;
+ if (!PyArg_ParseTuple(_args, "h",
+ &refNum))
+ return NULL;
+ _err = GetEOF(refNum,
+ &logEOF);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("l",
+ logEOF);
+ return _res;
+}
+
+static PyObject *File_SetEOF(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ short refNum;
+ long logEOF;
+ if (!PyArg_ParseTuple(_args, "hl",
+ &refNum,
+ &logEOF))
+ return NULL;
+ _err = SetEOF(refNum,
+ logEOF);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *File_GetFPos(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ short refNum;
+ long filePos;
+ if (!PyArg_ParseTuple(_args, "h",
+ &refNum))
+ return NULL;
+ _err = GetFPos(refNum,
+ &filePos);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("l",
+ filePos);
+ return _res;
+}
+
+static PyObject *File_SetFPos(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ short refNum;
+ short posMode;
+ long posOff;
+ if (!PyArg_ParseTuple(_args, "hhl",
+ &refNum,
+ &posMode,
+ &posOff))
+ return NULL;
+ _err = SetFPos(refNum,
+ posMode,
+ posOff);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *File_GetVRefNum(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ short fileRefNum;
+ short vRefNum;
+ if (!PyArg_ParseTuple(_args, "h",
+ &fileRefNum))
+ return NULL;
+ _err = GetVRefNum(fileRefNum,
+ &vRefNum);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("h",
+ vRefNum);
+ return _res;
+}
+
+static PyObject *File_HGetVol(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ StringPtr volName;
+ short vRefNum;
+ long dirID;
+ if (!PyArg_ParseTuple(_args, "O&",
+ PyMac_GetStr255, &volName))
+ return NULL;
+ _err = HGetVol(volName,
+ &vRefNum,
+ &dirID);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("hl",
+ vRefNum,
+ dirID);
+ return _res;
+}
+
+static PyObject *File_HOpen(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ short vRefNum;
+ long dirID;
+ Str255 fileName;
+ SInt8 permission;
+ short refNum;
+ if (!PyArg_ParseTuple(_args, "hlO&b",
+ &vRefNum,
+ &dirID,
+ PyMac_GetStr255, fileName,
+ &permission))
+ return NULL;
+ _err = HOpen(vRefNum,
+ dirID,
+ fileName,
+ permission,
+ &refNum);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("h",
+ refNum);
+ return _res;
+}
+
+static PyObject *File_HOpenDF(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ short vRefNum;
+ long dirID;
+ Str255 fileName;
+ SInt8 permission;
+ short refNum;
+ if (!PyArg_ParseTuple(_args, "hlO&b",
+ &vRefNum,
+ &dirID,
+ PyMac_GetStr255, fileName,
+ &permission))
+ return NULL;
+ _err = HOpenDF(vRefNum,
+ dirID,
+ fileName,
+ permission,
+ &refNum);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("h",
+ refNum);
+ return _res;
+}
+
+static PyObject *File_HOpenRF(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ short vRefNum;
+ long dirID;
+ Str255 fileName;
+ SInt8 permission;
+ short refNum;
+ if (!PyArg_ParseTuple(_args, "hlO&b",
+ &vRefNum,
+ &dirID,
+ PyMac_GetStr255, fileName,
+ &permission))
+ return NULL;
+ _err = HOpenRF(vRefNum,
+ dirID,
+ fileName,
+ permission,
+ &refNum);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("h",
+ refNum);
+ return _res;
+}
+
+static PyObject *File_AllocContig(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ short refNum;
+ long count;
+ if (!PyArg_ParseTuple(_args, "h",
+ &refNum))
+ return NULL;
+ _err = AllocContig(refNum,
+ &count);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("l",
+ count);
+ return _res;
+}
+
+static PyObject *File_HCreate(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ short vRefNum;
+ long dirID;
+ Str255 fileName;
+ OSType creator;
+ OSType fileType;
+ if (!PyArg_ParseTuple(_args, "hlO&O&O&",
+ &vRefNum,
+ &dirID,
+ PyMac_GetStr255, fileName,
+ PyMac_GetOSType, &creator,
+ PyMac_GetOSType, &fileType))
+ return NULL;
+ _err = HCreate(vRefNum,
+ dirID,
+ fileName,
+ creator,
+ fileType);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *File_DirCreate(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ short vRefNum;
+ long parentDirID;
+ Str255 directoryName;
+ long createdDirID;
+ if (!PyArg_ParseTuple(_args, "hlO&",
+ &vRefNum,
+ &parentDirID,
+ PyMac_GetStr255, directoryName))
+ return NULL;
+ _err = DirCreate(vRefNum,
+ parentDirID,
+ directoryName,
+ &createdDirID);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("l",
+ createdDirID);
+ return _res;
+}
+
+static PyObject *File_HDelete(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ short vRefNum;
+ long dirID;
+ Str255 fileName;
+ if (!PyArg_ParseTuple(_args, "hlO&",
+ &vRefNum,
+ &dirID,
+ PyMac_GetStr255, fileName))
+ return NULL;
+ _err = HDelete(vRefNum,
+ dirID,
+ fileName);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *File_HGetFInfo(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ short vRefNum;
+ long dirID;
+ Str255 fileName;
+ FInfo fndrInfo;
+ if (!PyArg_ParseTuple(_args, "hlO&",
+ &vRefNum,
+ &dirID,
+ PyMac_GetStr255, fileName))
+ return NULL;
+ _err = HGetFInfo(vRefNum,
+ dirID,
+ fileName,
+ &fndrInfo);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&",
+ FInfo_New, &fndrInfo);
+ return _res;
+}
+
+static PyObject *File_HSetFInfo(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ short vRefNum;
+ long dirID;
+ Str255 fileName;
+ FInfo fndrInfo;
+ if (!PyArg_ParseTuple(_args, "hlO&O&",
+ &vRefNum,
+ &dirID,
+ PyMac_GetStr255, fileName,
+ FInfo_Convert, &fndrInfo))
+ return NULL;
+ _err = HSetFInfo(vRefNum,
+ dirID,
+ fileName,
+ &fndrInfo);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *File_HSetFLock(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ short vRefNum;
+ long dirID;
+ Str255 fileName;
+ if (!PyArg_ParseTuple(_args, "hlO&",
+ &vRefNum,
+ &dirID,
+ PyMac_GetStr255, fileName))
+ return NULL;
+ _err = HSetFLock(vRefNum,
+ dirID,
+ fileName);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *File_HRstFLock(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ short vRefNum;
+ long dirID;
+ Str255 fileName;
+ if (!PyArg_ParseTuple(_args, "hlO&",
+ &vRefNum,
+ &dirID,
+ PyMac_GetStr255, fileName))
+ return NULL;
+ _err = HRstFLock(vRefNum,
+ dirID,
+ fileName);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *File_HRename(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ short vRefNum;
+ long dirID;
+ Str255 oldName;
+ Str255 newName;
+ if (!PyArg_ParseTuple(_args, "hlO&O&",
+ &vRefNum,
+ &dirID,
+ PyMac_GetStr255, oldName,
+ PyMac_GetStr255, newName))
+ return NULL;
+ _err = HRename(vRefNum,
+ dirID,
+ oldName,
+ newName);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *File_CatMove(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ short vRefNum;
+ long dirID;
+ Str255 oldName;
+ long newDirID;
+ Str255 newName;
+ if (!PyArg_ParseTuple(_args, "hlO&lO&",
+ &vRefNum,
+ &dirID,
+ PyMac_GetStr255, oldName,
+ &newDirID,
+ PyMac_GetStr255, newName))
+ return NULL;
+ _err = CatMove(vRefNum,
+ dirID,
+ oldName,
+ newDirID,
+ newName);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *File_FSMakeFSSpec(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ short vRefNum;
+ long dirID;
+ Str255 fileName;
+ FSSpec spec;
+ if (!PyArg_ParseTuple(_args, "hlO&",
+ &vRefNum,
+ &dirID,
+ PyMac_GetStr255, fileName))
+ return NULL;
+ _err = FSMakeFSSpec(vRefNum,
+ dirID,
+ fileName,
+ &spec);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&",
+ FSSpec_New, &spec);
+ return _res;
+}
+
+static PyObject *File_FSGetForkPosition(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ SInt16 forkRefNum;
+ SInt64 position;
+ if (!PyArg_ParseTuple(_args, "h",
+ &forkRefNum))
+ return NULL;
+ _err = FSGetForkPosition(forkRefNum,
+ &position);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("L",
+ position);
+ return _res;
+}
+
+static PyObject *File_FSSetForkPosition(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ SInt16 forkRefNum;
+ UInt16 positionMode;
+ SInt64 positionOffset;
+ if (!PyArg_ParseTuple(_args, "hHL",
+ &forkRefNum,
+ &positionMode,
+ &positionOffset))
+ return NULL;
+ _err = FSSetForkPosition(forkRefNum,
+ positionMode,
+ positionOffset);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *File_FSGetForkSize(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ SInt16 forkRefNum;
+ SInt64 forkSize;
+ if (!PyArg_ParseTuple(_args, "h",
+ &forkRefNum))
+ return NULL;
+ _err = FSGetForkSize(forkRefNum,
+ &forkSize);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("L",
+ forkSize);
+ return _res;
+}
+
+static PyObject *File_FSSetForkSize(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ SInt16 forkRefNum;
+ UInt16 positionMode;
+ SInt64 positionOffset;
+ if (!PyArg_ParseTuple(_args, "hHL",
+ &forkRefNum,
+ &positionMode,
+ &positionOffset))
+ return NULL;
+ _err = FSSetForkSize(forkRefNum,
+ positionMode,
+ positionOffset);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *File_FSAllocateFork(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ SInt16 forkRefNum;
+ FSAllocationFlags flags;
+ UInt16 positionMode;
+ SInt64 positionOffset;
+ UInt64 requestCount;
+ UInt64 actualCount;
+ if (!PyArg_ParseTuple(_args, "hHHLL",
+ &forkRefNum,
+ &flags,
+ &positionMode,
+ &positionOffset,
+ &requestCount))
+ return NULL;
+ _err = FSAllocateFork(forkRefNum,
+ flags,
+ positionMode,
+ positionOffset,
+ requestCount,
+ &actualCount);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("L",
+ actualCount);
+ return _res;
+}
+
+static PyObject *File_FSFlushFork(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ SInt16 forkRefNum;
+ if (!PyArg_ParseTuple(_args, "h",
+ &forkRefNum))
+ return NULL;
+ _err = FSFlushFork(forkRefNum);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *File_FSCloseFork(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ SInt16 forkRefNum;
+ if (!PyArg_ParseTuple(_args, "h",
+ &forkRefNum))
+ return NULL;
+ _err = FSCloseFork(forkRefNum);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+
+static PyObject *File_FSGetDataForkName(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ HFSUniStr255 dataForkName;
+ if (!PyArg_ParseTuple(_args, ""))
+ return NULL;
+ _err = FSGetDataForkName(&dataForkName);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&",
+ PyMac_BuildHFSUniStr255, &dataForkName);
+ return _res;
+}
+
+static PyObject *File_FSGetResourceForkName(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ HFSUniStr255 resourceForkName;
+ if (!PyArg_ParseTuple(_args, ""))
+ return NULL;
+ _err = FSGetResourceForkName(&resourceForkName);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&",
+ PyMac_BuildHFSUniStr255, &resourceForkName);
+ return _res;
+}
+
+static PyObject *File_FSPathMakeRef(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSStatus _err;
+ UInt8 * path;
+ FSRef ref;
+ Boolean isDirectory;
+ if (!PyArg_ParseTuple(_args, "s",
+ &path))
+ return NULL;
+ _err = FSPathMakeRef(path,
+ &ref,
+ &isDirectory);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&b",
+ FSRef_New, &ref,
+ isDirectory);
+ return _res;
+}
+
+#if TARGET_API_MAC_OSX
+
+static PyObject *File_FNNotifyByPath(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSStatus _err;
+ UInt8 * path;
+ FNMessage message;
+ OptionBits flags;
+ if (!PyArg_ParseTuple(_args, "sll",
+ &path,
+ &message,
+ &flags))
+ return NULL;
+ _err = FNNotifyByPath(path,
+ message,
+ flags);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+#endif
+
+#if TARGET_API_MAC_OSX
+
+static PyObject *File_FNNotifyAll(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSStatus _err;
+ FNMessage message;
+ OptionBits flags;
+ if (!PyArg_ParseTuple(_args, "ll",
+ &message,
+ &flags))
+ return NULL;
+ _err = FNNotifyAll(message,
+ flags);
+ if (_err != noErr) return PyMac_Error(_err);
+ Py_INCREF(Py_None);
+ _res = Py_None;
+ return _res;
+}
+#endif
+
+static PyObject *File_NewAlias(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ FSSpec fromFile__buf__;
+ FSSpec *fromFile = &fromFile__buf__;
+ FSSpec target;
+ AliasHandle alias;
+ if (!PyArg_ParseTuple(_args, "O&O&",
+ myPyMac_GetOptFSSpecPtr, &fromFile,
+ FSSpec_Convert, &target))
+ return NULL;
+ _err = NewAlias(fromFile,
+ &target,
+ &alias);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&",
+ Alias_New, alias);
+ return _res;
+}
+
+static PyObject *File_NewAliasMinimalFromFullPath(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ char *fullPath__in__;
+ int fullPath__len__;
+ int fullPath__in_len__;
+ Str32 zoneName;
+ Str31 serverName;
+ AliasHandle alias;
+ if (!PyArg_ParseTuple(_args, "s#O&O&",
+ &fullPath__in__, &fullPath__in_len__,
+ PyMac_GetStr255, zoneName,
+ PyMac_GetStr255, serverName))
+ return NULL;
+ fullPath__len__ = fullPath__in_len__;
+ _err = NewAliasMinimalFromFullPath(fullPath__len__, fullPath__in__,
+ zoneName,
+ serverName,
+ &alias);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&",
+ Alias_New, alias);
+ return _res;
+}
+
+static PyObject *File_ResolveAliasFile(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ FSSpec theSpec;
+ Boolean resolveAliasChains;
+ Boolean targetIsFolder;
+ Boolean wasAliased;
+ if (!PyArg_ParseTuple(_args, "O&b",
+ FSSpec_Convert, &theSpec,
+ &resolveAliasChains))
+ return NULL;
+ _err = ResolveAliasFile(&theSpec,
+ resolveAliasChains,
+ &targetIsFolder,
+ &wasAliased);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&bb",
+ FSSpec_New, &theSpec,
+ targetIsFolder,
+ wasAliased);
+ return _res;
+}
+
+static PyObject *File_ResolveAliasFileWithMountFlags(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ FSSpec theSpec;
+ Boolean resolveAliasChains;
+ Boolean targetIsFolder;
+ Boolean wasAliased;
+ unsigned long mountFlags;
+ if (!PyArg_ParseTuple(_args, "O&bl",
+ FSSpec_Convert, &theSpec,
+ &resolveAliasChains,
+ &mountFlags))
+ return NULL;
+ _err = ResolveAliasFileWithMountFlags(&theSpec,
+ resolveAliasChains,
+ &targetIsFolder,
+ &wasAliased,
+ mountFlags);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&bb",
+ FSSpec_New, &theSpec,
+ targetIsFolder,
+ wasAliased);
+ return _res;
+}
+
+static PyObject *File_UpdateAlias(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ FSSpec fromFile__buf__;
+ FSSpec *fromFile = &fromFile__buf__;
+ FSSpec target;
+ AliasHandle alias;
+ Boolean wasChanged;
+ if (!PyArg_ParseTuple(_args, "O&O&O&",
+ myPyMac_GetOptFSSpecPtr, &fromFile,
+ FSSpec_Convert, &target,
+ Alias_Convert, &alias))
+ return NULL;
+ _err = UpdateAlias(fromFile,
+ &target,
+ alias,
+ &wasChanged);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("b",
+ wasChanged);
+ return _res;
+}
+
+static PyObject *File_ResolveAliasFileWithMountFlagsNoUI(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ FSSpec theSpec;
+ Boolean resolveAliasChains;
+ Boolean targetIsFolder;
+ Boolean wasAliased;
+ unsigned long mountFlags;
+ if (!PyArg_ParseTuple(_args, "O&bl",
+ FSSpec_Convert, &theSpec,
+ &resolveAliasChains,
+ &mountFlags))
+ return NULL;
+ _err = ResolveAliasFileWithMountFlagsNoUI(&theSpec,
+ resolveAliasChains,
+ &targetIsFolder,
+ &wasAliased,
+ mountFlags);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&bb",
+ FSSpec_New, &theSpec,
+ targetIsFolder,
+ wasAliased);
+ return _res;
+}
+
+static PyObject *File_FSNewAlias(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ FSRef fromFile__buf__;
+ FSRef *fromFile = &fromFile__buf__;
+ FSRef target;
+ AliasHandle inAlias;
+ if (!PyArg_ParseTuple(_args, "O&O&",
+ myPyMac_GetOptFSRefPtr, &fromFile,
+ FSRef_Convert, &target))
+ return NULL;
+ _err = FSNewAlias(fromFile,
+ &target,
+ &inAlias);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&",
+ Alias_New, inAlias);
+ return _res;
+}
+
+static PyObject *File_FSResolveAliasFileWithMountFlags(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ FSRef theRef;
+ Boolean resolveAliasChains;
+ Boolean targetIsFolder;
+ Boolean wasAliased;
+ unsigned long mountFlags;
+ if (!PyArg_ParseTuple(_args, "O&bl",
+ FSRef_Convert, &theRef,
+ &resolveAliasChains,
+ &mountFlags))
+ return NULL;
+ _err = FSResolveAliasFileWithMountFlags(&theRef,
+ resolveAliasChains,
+ &targetIsFolder,
+ &wasAliased,
+ mountFlags);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&bb",
+ FSRef_New, &theRef,
+ targetIsFolder,
+ wasAliased);
+ return _res;
+}
+
+static PyObject *File_FSResolveAliasFile(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ FSRef theRef;
+ Boolean resolveAliasChains;
+ Boolean targetIsFolder;
+ Boolean wasAliased;
+ if (!PyArg_ParseTuple(_args, "O&b",
+ FSRef_Convert, &theRef,
+ &resolveAliasChains))
+ return NULL;
+ _err = FSResolveAliasFile(&theRef,
+ resolveAliasChains,
+ &targetIsFolder,
+ &wasAliased);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("O&bb",
+ FSRef_New, &theRef,
+ targetIsFolder,
+ wasAliased);
+ return _res;
+}
+
+static PyObject *File_FSUpdateAlias(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+ OSErr _err;
+ FSRef fromFile__buf__;
+ FSRef *fromFile = &fromFile__buf__;
+ FSRef target;
+ AliasHandle alias;
+ Boolean wasChanged;
+ if (!PyArg_ParseTuple(_args, "O&O&O&",
+ myPyMac_GetOptFSRefPtr, &fromFile,
+ FSRef_Convert, &target,
+ Alias_Convert, &alias))
+ return NULL;
+ _err = FSUpdateAlias(fromFile,
+ &target,
+ alias,
+ &wasChanged);
+ if (_err != noErr) return PyMac_Error(_err);
+ _res = Py_BuildValue("b",
+ wasChanged);
+ return _res;
+}
+
+static PyObject *File_pathname(PyObject *_self, PyObject *_args)
+{
+ PyObject *_res = NULL;
+
+ PyObject *obj;
+
+ if (!PyArg_ParseTuple(_args, "O", &obj))
+ return NULL;
+ if (PyString_Check(obj)) {
+ Py_INCREF(obj);
+ return obj;
+ }
+ if (PyUnicode_Check(obj))
+ return PyUnicode_AsEncodedString(obj, "utf8", "strict");
+ _res = PyObject_CallMethod(obj, "as_pathname", NULL);
+ return _res;
+
+}
+
+static PyMethodDef File_methods[] = {
+ {"UnmountVol", (PyCFunction)File_UnmountVol, 1,
+ PyDoc_STR("(Str63 volName, short vRefNum) -> None")},
+ {"FlushVol", (PyCFunction)File_FlushVol, 1,
+ PyDoc_STR("(Str63 volName, short vRefNum) -> None")},
+ {"HSetVol", (PyCFunction)File_HSetVol, 1,
+ PyDoc_STR("(Str63 volName, short vRefNum, long dirID) -> None")},
+ {"FSClose", (PyCFunction)File_FSClose, 1,
+ PyDoc_STR("(short refNum) -> None")},
+ {"Allocate", (PyCFunction)File_Allocate, 1,
+ PyDoc_STR("(short refNum) -> (long count)")},
+ {"GetEOF", (PyCFunction)File_GetEOF, 1,
+ PyDoc_STR("(short refNum) -> (long logEOF)")},
+ {"SetEOF", (PyCFunction)File_SetEOF, 1,
+ PyDoc_STR("(short refNum, long logEOF) -> None")},
+ {"GetFPos", (PyCFunction)File_GetFPos, 1,
+ PyDoc_STR("(short refNum) -> (long filePos)")},
+ {"SetFPos", (PyCFunction)File_SetFPos, 1,
+ PyDoc_STR("(short refNum, short posMode, long posOff) -> None")},
+ {"GetVRefNum", (PyCFunction)File_GetVRefNum, 1,
+ PyDoc_STR("(short fileRefNum) -> (short vRefNum)")},
+ {"HGetVol", (PyCFunction)File_HGetVol, 1,
+ PyDoc_STR("(StringPtr volName) -> (short vRefNum, long dirID)")},
+ {"HOpen", (PyCFunction)File_HOpen, 1,
+ PyDoc_STR("(short vRefNum, long dirID, Str255 fileName, SInt8 permission) -> (short refNum)")},
+ {"HOpenDF", (PyCFunction)File_HOpenDF, 1,
+ PyDoc_STR("(short vRefNum, long dirID, Str255 fileName, SInt8 permission) -> (short refNum)")},
+ {"HOpenRF", (PyCFunction)File_HOpenRF, 1,
+ PyDoc_STR("(short vRefNum, long dirID, Str255 fileName, SInt8 permission) -> (short refNum)")},
+ {"AllocContig", (PyCFunction)File_AllocContig, 1,
+ PyDoc_STR("(short refNum) -> (long count)")},
+ {"HCreate", (PyCFunction)File_HCreate, 1,
+ PyDoc_STR("(short vRefNum, long dirID, Str255 fileName, OSType creator, OSType fileType) -> None")},
+ {"DirCreate", (PyCFunction)File_DirCreate, 1,
+ PyDoc_STR("(short vRefNum, long parentDirID, Str255 directoryName) -> (long createdDirID)")},
+ {"HDelete", (PyCFunction)File_HDelete, 1,
+ PyDoc_STR("(short vRefNum, long dirID, Str255 fileName) -> None")},
+ {"HGetFInfo", (PyCFunction)File_HGetFInfo, 1,
+ PyDoc_STR("(short vRefNum, long dirID, Str255 fileName) -> (FInfo fndrInfo)")},
+ {"HSetFInfo", (PyCFunction)File_HSetFInfo, 1,
+ PyDoc_STR("(short vRefNum, long dirID, Str255 fileName, FInfo fndrInfo) -> None")},
+ {"HSetFLock", (PyCFunction)File_HSetFLock, 1,
+ PyDoc_STR("(short vRefNum, long dirID, Str255 fileName) -> None")},
+ {"HRstFLock", (PyCFunction)File_HRstFLock, 1,
+ PyDoc_STR("(short vRefNum, long dirID, Str255 fileName) -> None")},
+ {"HRename", (PyCFunction)File_HRename, 1,
+ PyDoc_STR("(short vRefNum, long dirID, Str255 oldName, Str255 newName) -> None")},
+ {"CatMove", (PyCFunction)File_CatMove, 1,
+ PyDoc_STR("(short vRefNum, long dirID, Str255 oldName, long newDirID, Str255 newName) -> None")},
+ {"FSMakeFSSpec", (PyCFunction)File_FSMakeFSSpec, 1,
+ PyDoc_STR("(short vRefNum, long dirID, Str255 fileName) -> (FSSpec spec)")},
+ {"FSGetForkPosition", (PyCFunction)File_FSGetForkPosition, 1,
+ PyDoc_STR("(SInt16 forkRefNum) -> (SInt64 position)")},
+ {"FSSetForkPosition", (PyCFunction)File_FSSetForkPosition, 1,
+ PyDoc_STR("(SInt16 forkRefNum, UInt16 positionMode, SInt64 positionOffset) -> None")},
+ {"FSGetForkSize", (PyCFunction)File_FSGetForkSize, 1,
+ PyDoc_STR("(SInt16 forkRefNum) -> (SInt64 forkSize)")},
+ {"FSSetForkSize", (PyCFunction)File_FSSetForkSize, 1,
+ PyDoc_STR("(SInt16 forkRefNum, UInt16 positionMode, SInt64 positionOffset) -> None")},
+ {"FSAllocateFork", (PyCFunction)File_FSAllocateFork, 1,
+ PyDoc_STR("(SInt16 forkRefNum, FSAllocationFlags flags, UInt16 positionMode, SInt64 positionOffset, UInt64 requestCount) -> (UInt64 actualCount)")},
+ {"FSFlushFork", (PyCFunction)File_FSFlushFork, 1,
+ PyDoc_STR("(SInt16 forkRefNum) -> None")},
+ {"FSCloseFork", (PyCFunction)File_FSCloseFork, 1,
+ PyDoc_STR("(SInt16 forkRefNum) -> None")},
+ {"FSGetDataForkName", (PyCFunction)File_FSGetDataForkName, 1,
+ PyDoc_STR("() -> (HFSUniStr255 dataForkName)")},
+ {"FSGetResourceForkName", (PyCFunction)File_FSGetResourceForkName, 1,
+ PyDoc_STR("() -> (HFSUniStr255 resourceForkName)")},
+ {"FSPathMakeRef", (PyCFunction)File_FSPathMakeRef, 1,
+ PyDoc_STR("(UInt8 * path) -> (FSRef ref, Boolean isDirectory)")},
+
+#if TARGET_API_MAC_OSX
+ {"FNNotifyByPath", (PyCFunction)File_FNNotifyByPath, 1,
+ PyDoc_STR("(UInt8 * path, FNMessage message, OptionBits flags) -> None")},
+#endif
+
+#if TARGET_API_MAC_OSX
+ {"FNNotifyAll", (PyCFunction)File_FNNotifyAll, 1,
+ PyDoc_STR("(FNMessage message, OptionBits flags) -> None")},
+#endif
+ {"NewAlias", (PyCFunction)File_NewAlias, 1,
+ PyDoc_STR("(FSSpec fromFile, FSSpec target) -> (AliasHandle alias)")},
+ {"NewAliasMinimalFromFullPath", (PyCFunction)File_NewAliasMinimalFromFullPath, 1,
+ PyDoc_STR("(Buffer fullPath, Str32 zoneName, Str31 serverName) -> (AliasHandle alias)")},
+ {"ResolveAliasFile", (PyCFunction)File_ResolveAliasFile, 1,
+ PyDoc_STR("(FSSpec theSpec, Boolean resolveAliasChains) -> (FSSpec theSpec, Boolean targetIsFolder, Boolean wasAliased)")},
+ {"ResolveAliasFileWithMountFlags", (PyCFunction)File_ResolveAliasFileWithMountFlags, 1,
+ PyDoc_STR("(FSSpec theSpec, Boolean resolveAliasChains, unsigned long mountFlags) -> (FSSpec theSpec, Boolean targetIsFolder, Boolean wasAliased)")},
+ {"UpdateAlias", (PyCFunction)File_UpdateAlias, 1,
+ PyDoc_STR("(FSSpec fromFile, FSSpec target, AliasHandle alias) -> (Boolean wasChanged)")},
+ {"ResolveAliasFileWithMountFlagsNoUI", (PyCFunction)File_ResolveAliasFileWithMountFlagsNoUI, 1,
+ PyDoc_STR("(FSSpec theSpec, Boolean resolveAliasChains, unsigned long mountFlags) -> (FSSpec theSpec, Boolean targetIsFolder, Boolean wasAliased)")},
+ {"FSNewAlias", (PyCFunction)File_FSNewAlias, 1,
+ PyDoc_STR("(FSRef fromFile, FSRef target) -> (AliasHandle inAlias)")},
+ {"FSResolveAliasFileWithMountFlags", (PyCFunction)File_FSResolveAliasFileWithMountFlags, 1,
+ PyDoc_STR("(FSRef theRef, Boolean resolveAliasChains, unsigned long mountFlags) -> (FSRef theRef, Boolean targetIsFolder, Boolean wasAliased)")},
+ {"FSResolveAliasFile", (PyCFunction)File_FSResolveAliasFile, 1,
+ PyDoc_STR("(FSRef theRef, Boolean resolveAliasChains) -> (FSRef theRef, Boolean targetIsFolder, Boolean wasAliased)")},
+ {"FSUpdateAlias", (PyCFunction)File_FSUpdateAlias, 1,
+ PyDoc_STR("(FSRef fromFile, FSRef target, AliasHandle alias) -> (Boolean wasChanged)")},
+ {"pathname", (PyCFunction)File_pathname, 1,
+ PyDoc_STR("(str|unicode|FSSpec|FSref) -> pathname")},
+ {NULL, NULL, 0}
+};
+
+
+
+int
+PyMac_GetFSSpec(PyObject *v, FSSpec *spec)
+{
+ Str255 path;
+ short refnum;
+ long parid;
+ OSErr err;
+ FSRef fsr;
+
+ if (FSSpec_Check(v)) {
+ *spec = ((FSSpecObject *)v)->ob_itself;
+ return 1;
+ }
+
+ if (PyArg_Parse(v, "(hlO&)",
+ &refnum, &parid, PyMac_GetStr255, &path)) {
+ err = FSMakeFSSpec(refnum, parid, path, spec);
+ if ( err && err != fnfErr ) {
+ PyMac_Error(err);
+ return 0;
+ }
+ return 1;
+ }
+ PyErr_Clear();
+#if !TARGET_API_MAC_OSX
+ /* On OS9 we now try a pathname */
+ if ( PyString_Check(v) ) {
+ /* It's a pathname */
+ if( !PyArg_Parse(v, "O&", PyMac_GetStr255, &path) )
+ return 0;
+ refnum = 0; /* XXXX Should get CurWD here?? */
+ parid = 0;
+ err = FSMakeFSSpec(refnum, parid, path, spec);
+ if ( err && err != fnfErr ) {
+ PyMac_Error(err);
+ return 0;
+ }
+ return 1;
+ }
+ PyErr_Clear();
+#endif
+ /* Otherwise we try to go via an FSRef. On OSX we go all the way,
+ ** on OS9 we accept only a real FSRef object
+ */
+#if TARGET_API_MAC_OSX
+ if ( PyMac_GetFSRef(v, &fsr) ) {
+#else
+ if (FSRef_Check(v)) {
+ fsr = ((FSRefObject *)v)->ob_itself;
+#endif
+ err = FSGetCatalogInfo(&fsr, kFSCatInfoNone, NULL, NULL, spec, NULL);
+ if (err != noErr) {
+ PyMac_Error(err);
+ return 0;
+ }
+ return 1;
+ }
+#if !TARGET_API_MAC_OSX
+ PyErr_SetString(PyExc_TypeError, "FSSpec, FSRef, pathname or (refnum, parid, path) required");
+#endif
+ return 0;
+}
+
+int
+PyMac_GetFSRef(PyObject *v, FSRef *fsr)
+{
+ OSStatus err;
+ FSSpec fss;
+
+ if (FSRef_Check(v)) {
+ *fsr = ((FSRefObject *)v)->ob_itself;
+ return 1;
+ }
+
+#if TARGET_API_MAC_OSX
+ /* On OSX we now try a pathname */
+ if ( PyString_Check(v) || PyUnicode_Check(v)) {
+ char *path = NULL;
+ if (!PyArg_Parse(v, "et", Py_FileSystemDefaultEncoding, &path))
+ return 0;
+ if ( (err=FSPathMakeRef((unsigned char *)path, fsr, NULL)) ) {
+ PyMac_Error(err);
+ return 0;
+ }
+ return 1;
+ }
+ /* XXXX Should try unicode here too */
+#endif
+ /* Otherwise we try to go via an FSSpec */
+#if TARGET_API_MAC_OSX
+ if (FSSpec_Check(v)) {
+ fss = ((FSSpecObject *)v)->ob_itself;
+#else
+ if (PyMac_GetFSSpec(v, &fss)) {
+#endif
+ if ((err=FSpMakeFSRef(&fss, fsr)) == 0)
+ return 1;
+ PyMac_Error(err);
+ return 0;
+ }
+ PyErr_SetString(PyExc_TypeError, "FSRef, FSSpec or pathname required");
+ return 0;
+}
+
+extern PyObject *
+PyMac_BuildFSSpec(FSSpec *spec)
+{
+ return FSSpec_New(spec);
+}
+
+extern PyObject *
+PyMac_BuildFSRef(FSRef *spec)
+{
+ return FSRef_New(spec);
+}
+
+
+void init_File(void)
+{
+ PyObject *m;
+ PyObject *d;
+
+
+
+ PyMac_INIT_TOOLBOX_OBJECT_NEW(FSSpec *, PyMac_BuildFSSpec);
+ PyMac_INIT_TOOLBOX_OBJECT_NEW(FSRef *, PyMac_BuildFSRef);
+ PyMac_INIT_TOOLBOX_OBJECT_CONVERT(FSSpec, PyMac_GetFSSpec);
+ PyMac_INIT_TOOLBOX_OBJECT_CONVERT(FSRef, PyMac_GetFSRef);
+
+
+ m = Py_InitModule("_File", File_methods);
+ d = PyModule_GetDict(m);
+ File_Error = PyMac_GetOSErrException();
+ if (File_Error == NULL ||
+ PyDict_SetItemString(d, "Error", File_Error) != 0)
+ return;
+ FSCatalogInfo_Type.ob_type = &PyType_Type;
+ if (PyType_Ready(&FSCatalogInfo_Type) < 0) return;
+ Py_INCREF(&FSCatalogInfo_Type);
+ PyModule_AddObject(m, "FSCatalogInfo", (PyObject *)&FSCatalogInfo_Type);
+ /* Backward-compatible name */
+ Py_INCREF(&FSCatalogInfo_Type);
+ PyModule_AddObject(m, "FSCatalogInfoType", (PyObject *)&FSCatalogInfo_Type);
+ FInfo_Type.ob_type = &PyType_Type;
+ if (PyType_Ready(&FInfo_Type) < 0) return;
+ Py_INCREF(&FInfo_Type);
+ PyModule_AddObject(m, "FInfo", (PyObject *)&FInfo_Type);
+ /* Backward-compatible name */
+ Py_INCREF(&FInfo_Type);
+ PyModule_AddObject(m, "FInfoType", (PyObject *)&FInfo_Type);
+ Alias_Type.ob_type = &PyType_Type;
+ if (PyType_Ready(&Alias_Type) < 0) return;
+ Py_INCREF(&Alias_Type);
+ PyModule_AddObject(m, "Alias", (PyObject *)&Alias_Type);
+ /* Backward-compatible name */
+ Py_INCREF(&Alias_Type);
+ PyModule_AddObject(m, "AliasType", (PyObject *)&Alias_Type);
+ FSSpec_Type.ob_type = &PyType_Type;
+ if (PyType_Ready(&FSSpec_Type) < 0) return;
+ Py_INCREF(&FSSpec_Type);
+ PyModule_AddObject(m, "FSSpec", (PyObject *)&FSSpec_Type);
+ /* Backward-compatible name */
+ Py_INCREF(&FSSpec_Type);
+ PyModule_AddObject(m, "FSSpecType", (PyObject *)&FSSpec_Type);
+ FSRef_Type.ob_type = &PyType_Type;
+ if (PyType_Ready(&FSRef_Type) < 0) return;
+ Py_INCREF(&FSRef_Type);
+ PyModule_AddObject(m, "FSRef", (PyObject *)&FSRef_Type);
+ /* Backward-compatible name */
+ Py_INCREF(&FSRef_Type);
+ PyModule_AddObject(m, "FSRefType", (PyObject *)&FSRef_Type);
+}
+
+/* ======================== End module _File ======================== */
+
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/__init__.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/__init__.py
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/macglue.h b/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/macglue.h
new file mode 100644
index 00000000..f2b0bfbe
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/macglue.h
@@ -0,0 +1,135 @@
+/***********************************************************
+Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
+The Netherlands.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+#ifndef Py_MACGLUE_H
+#define Py_MACGLUE_H
+#ifdef WITHOUT_FRAMEWORKS
+#include <Types.h>
+#include <Files.h>
+#include <Events.h>
+#include <StandardFile.h>
+#else
+#include <Carbon/Carbon.h>
+#endif
+
+#include "pymactoolbox.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Scheduler parameters */
+typedef struct {
+ int check_interrupt; /* if true check for command-dot */
+ int process_events; /* if nonzero enable evt processing, this mask */
+ int besocial; /* Be social, give up CPU now and again */
+ double check_interval; /* how often to check */
+ double bg_yield; /* yield at most so long when in background */
+} PyMacSchedParams;
+
+unsigned char *Pstring(char *str); /* Convert c-string to pascal-string in static buffer */
+
+#ifdef USE_GUSI
+extern int PyMac_ConsoleIsDead; /* True when exiting */
+extern void PyMac_StopGUSISpin(void); /* Stop eventprocessing during exit() */
+#endif
+
+extern short PyMac_AppRefNum; /* RefNum of application rsrcfork (from macmain.c) */
+extern FSSpec PyMac_ApplicationFSSpec; /* Application location (from macargv.c) */
+extern char PyMac_ApplicationPath[]; /* Application location (from macargv.c) */
+extern OSErr PyMac_init_application_location(void); /* Init the above */
+extern int PyMac_GetArgv(char ***, int); /* Get argc, argv (from macargv.c) */
+
+extern PyObject *PyMac_OSErrException; /* Exception for OSErr */
+PyObject *PyMac_GetOSErrException(void); /* Initialize & return it */
+
+#if !TARGET_API_MAC_OSX
+void PyMac_GetSchedParams(PyMacSchedParams *); /* Get schedulers params */
+void PyMac_SetSchedParams(PyMacSchedParams *); /* Set schedulers params */
+int PyMac_DoYield(int, int); /* Yield cpu. First arg is maxtime, second ok to call python */
+#endif
+int PyMac_HandleEvent(EventRecord *); /* Handle one event, possibly in Python */
+void PyMac_HandleEventIntern(EventRecord *); /* Handle one event internal only */
+int PyMac_SetEventHandler(PyObject *); /* set python-coded event handler */
+
+#if !TARGET_API_MAC_OSX
+void PyMac_InitMenuBar(void); /* Setup menu bar as we want it */
+void PyMac_RestoreMenuBar(void); /* Restore menu bar for ease of exiting */
+void PyMac_RaiseConsoleWindow(); /* Bring console window to front, if it exists */
+#endif
+int PyMac_FindResourceModule(PyStringObject *, char *, char *); /* Test for 'PYC ' resource in a file */
+PyObject * PyMac_LoadResourceModule(char *, char *); /* Load 'PYC ' resource from file */
+int PyMac_FindCodeResourceModule(PyStringObject *, char *, char *); /* Test for 'PYD ' resource in a file */
+PyObject * PyMac_LoadCodeResourceModule(char *, char *); /* Load 'PYD ' resource from file */
+struct filedescr *PyMac_FindModuleExtension(char *, size_t *, char *); /* Look for module in single folder */
+
+void PyMac_InitApplet(void); /* Initialize and run an Applet */
+void PyMac_Initialize(void); /* Initialize function for embedding Python */
+
+#ifdef USE_GUSI2
+short PyMac_OpenPrefFile(void); /* From macgetpath.c, open and return preference file */
+#endif
+
+
+/* From macfiletype.c: */
+
+long PyMac_getfiletype(char *); /* Get file type */
+int PyMac_setfiletype(char *, long, long); /* Set file creator and type */
+
+/* from macmain.c: */
+void PyMac_Exit(int);
+void PyMac_InitApplication(void);
+void PyMac_OutputSeen(void);
+void PyMac_OutputNotSeen(void);
+int PyMac_GetDelayConsoleFlag(void);
+#ifdef USE_MAC_APPLET_SUPPORT
+void PyMac_InitApplet(void);
+#endif
+
+/* from macgetargv: */
+OSErr PyMac_init_process_location(void);
+char * strdup(const char *str);
+
+#ifdef USE_GUSI2
+/* from pyGUSISIOUX.cp */
+typedef long (*PyWriteHandler)(char *buffer, long n);
+typedef long (*PyReadHandler)(char *buffer, long n);
+
+/* Override routines that normally reads and writes to the
+** SIOUX console window. Intended for embedding applications
+** that want to forestall a Python console window ever showing up.
+*/
+void PyMac_SetConsoleHandler(PyReadHandler stdinH, PyWriteHandler stdoutH,
+ PyWriteHandler stderrH);
+
+/* Courtesy console handlers that drop all output and return
+** 0 on reads.
+*/
+long PyMac_DummyReadHandler(char *, long);
+long PyMac_DummyWriteHandler(char *, long);
+#endif /* USE_GUSI2 */
+
+#ifdef __cplusplus
+ }
+#endif
+#endif
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/setup.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/setup.py
new file mode 100644
index 00000000..f0da28ed
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Mac/setup.py
@@ -0,0 +1,12 @@
+#
+# Setup file for compiling _Filemodule_patched.c
+#
+
+from distutils.core import setup
+from distutils.extension import Extension
+
+setup(
+ ext_modules = [
+ Extension("_File", ["_Filemodule_patched.c"])
+ ]
+)
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Actions.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Actions.py
new file mode 100755
index 00000000..23253a90
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Actions.py
@@ -0,0 +1,109 @@
+#=======================================================================
+#
+# Python Lexical Analyser
+#
+# Actions for use in token specifications
+#
+#=======================================================================
+
+class Action:
+
+ def same_as(self, other):
+ return self is other
+
+
+class Return(Action):
+ """
+ Internal Plex action which causes |value| to
+ be returned as the value of the associated token
+ """
+
+ value = None
+
+ def __init__(self, value):
+ self.value = value
+
+ def perform(self, token_stream, text):
+ return self.value
+
+ def same_as(self, other):
+ return isinstance(other, Return) and self.value == other.value
+
+ def __repr__(self):
+ return "Return(%s)" % repr(self.value)
+
+
+class Call(Action):
+ """
+ Internal Plex action which causes a function to be called.
+ """
+
+ function = None
+
+ def __init__(self, function):
+ self.function = function
+
+ def perform(self, token_stream, text):
+ return self.function(token_stream, text)
+
+ def __repr__(self):
+ return "Call(%s)" % self.function.__name__
+
+ def same_as(self, other):
+ return isinstance(other, Call) and self.function is other.function
+
+
+class Begin(Action):
+ """
+ Begin(state_name) is a Plex action which causes the Scanner to
+ enter the state |state_name|. See the docstring of Plex.Lexicon
+ for more information.
+ """
+
+ state_name = None
+
+ def __init__(self, state_name):
+ self.state_name = state_name
+
+ def perform(self, token_stream, text):
+ token_stream.begin(self.state_name)
+
+ def __repr__(self):
+ return "Begin(%s)" % self.state_name
+
+ def same_as(self, other):
+ return isinstance(other, Begin) and self.state_name == other.state_name
+
+
+class Ignore(Action):
+ """
+ IGNORE is a Plex action which causes its associated token
+ to be ignored. See the docstring of Plex.Lexicon for more
+ information.
+ """
+ def perform(self, token_stream, text):
+ return None
+
+ def __repr__(self):
+ return "IGNORE"
+
+IGNORE = Ignore()
+IGNORE.__doc__ = Ignore.__doc__
+
+class Text(Action):
+ """
+ TEXT is a Plex action which causes the text of a token to
+ be returned as the value of the token. See the docstring of
+ Plex.Lexicon for more information.
+ """
+
+ def perform(self, token_stream, text):
+ return text
+
+ def __repr__(self):
+ return "TEXT"
+
+TEXT = Text()
+TEXT.__doc__ = Text.__doc__
+
+
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/DFA.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/DFA.py
new file mode 100755
index 00000000..2c0004b0
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/DFA.py
@@ -0,0 +1,156 @@
+#=======================================================================
+#
+# Python Lexical Analyser
+#
+# Converting NFA to DFA
+#
+#=======================================================================
+
+import Machines
+from Machines import LOWEST_PRIORITY
+from Transitions import TransitionMap
+
+def nfa_to_dfa(old_machine, debug = None):
+ """
+ Given a nondeterministic Machine, return a new equivalent
+ Machine which is deterministic.
+ """
+ # We build a new machine whose states correspond to sets of states
+ # in the old machine. Initially we add a new state corresponding to
+ # the epsilon-closure of each initial old state. Then we give transitions
+ # to each new state which are the union of all transitions out of any
+ # of the corresponding old states. The new state reached on a given
+ # character is the one corresponding to the set of states reachable
+ # on that character from any of the old states. As new combinations of
+ # old states are created, new states are added as needed until closure
+ # is reached.
+ new_machine = Machines.FastMachine()
+ state_map = StateMap(new_machine)
+ # Seed the process using the initial states of the old machine.
+ # Make the corresponding new states into initial states of the new
+ # machine with the same names.
+ for (key, old_state) in old_machine.initial_states.items():
+ new_state = state_map.old_to_new(epsilon_closure(old_state))
+ new_machine.make_initial_state(key, new_state)
+ # Tricky bit here: we add things to the end of this list while we're
+ # iterating over it. The iteration stops when closure is achieved.
+ for new_state in new_machine.states:
+ transitions = TransitionMap()
+ for old_state in state_map.new_to_old(new_state).keys():
+ for event, old_target_states in old_state.transitions.items():
+ if event and old_target_states:
+ transitions.add_set(event, set_epsilon_closure(old_target_states))
+ for event, old_states in transitions.items():
+ new_machine.add_transitions(new_state, event, state_map.old_to_new(old_states))
+ if debug:
+ debug.write("\n===== State Mapping =====\n")
+ state_map.dump(debug)
+ return new_machine
+
+def set_epsilon_closure(state_set):
+ """
+ Given a set of states, return the union of the epsilon
+ closures of its member states.
+ """
+ result = {}
+ for state1 in state_set.keys():
+ for state2 in epsilon_closure(state1).keys():
+ result[state2] = 1
+ return result
+
+def epsilon_closure(state):
+ """
+ Return the set of states reachable from the given state
+ by epsilon moves.
+ """
+ # Cache the result
+ result = state.epsilon_closure
+ if result is None:
+ result = {}
+ state.epsilon_closure = result
+ add_to_epsilon_closure(result, state)
+ return result
+
+def add_to_epsilon_closure(state_set, state):
+ """
+ Recursively add to |state_set| states reachable from the given state
+ by epsilon moves.
+ """
+ if not state_set.get(state, 0):
+ state_set[state] = 1
+ state_set_2 = state.transitions.get_epsilon()
+ if state_set_2:
+ for state2 in state_set_2.keys():
+ add_to_epsilon_closure(state_set, state2)
+
+class StateMap:
+ """
+ Helper class used by nfa_to_dfa() to map back and forth between
+ sets of states from the old machine and states of the new machine.
+ """
+ new_machine = None # Machine
+ old_to_new_dict = None # {(old_state,...) : new_state}
+ new_to_old_dict = None # {id(new_state) : old_state_set}
+
+ def __init__(self, new_machine):
+ self.new_machine = new_machine
+ self.old_to_new_dict = {}
+ self.new_to_old_dict= {}
+
+ def old_to_new(self, old_state_set):
+ """
+ Return the state of the new machine corresponding to the
+ set of old machine states represented by |state_set|. A new
+ state will be created if necessary. If any of the old states
+ are accepting states, the new state will be an accepting state
+ with the highest priority action from the old states.
+ """
+ key = self.make_key(old_state_set)
+ new_state = self.old_to_new_dict.get(key, None)
+ if not new_state:
+ action = self.highest_priority_action(old_state_set)
+ new_state = self.new_machine.new_state(action)
+ self.old_to_new_dict[key] = new_state
+ self.new_to_old_dict[id(new_state)] = old_state_set
+ #for old_state in old_state_set.keys():
+ #new_state.merge_actions(old_state)
+ return new_state
+
+ def highest_priority_action(self, state_set):
+ best_action = None
+ best_priority = LOWEST_PRIORITY
+ for state in state_set.keys():
+ priority = state.action_priority
+ if priority > best_priority:
+ best_action = state.action
+ best_priority = priority
+ return best_action
+
+# def old_to_new_set(self, old_state_set):
+# """
+# Return the new state corresponding to a set of old states as
+# a singleton set.
+# """
+# return {self.old_to_new(old_state_set):1}
+
+ def new_to_old(self, new_state):
+ """Given a new state, return a set of corresponding old states."""
+ return self.new_to_old_dict[id(new_state)]
+
+ def make_key(self, state_set):
+ """
+ Convert a set of states into a uniquified
+ sorted tuple suitable for use as a dictionary key.
+ """
+ lst = state_set.keys()
+ lst.sort()
+ return tuple(lst)
+
+ def dump(self, file):
+ from Transitions import state_set_str
+ for new_state in self.new_machine.states:
+ old_state_set = self.new_to_old_dict[id(new_state)]
+ file.write(" State %s <-- %s\n" % (
+ new_state['number'], state_set_str(old_state_set)))
+
+
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Errors.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Errors.py
new file mode 100755
index 00000000..ae033672
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Errors.py
@@ -0,0 +1,52 @@
+#=======================================================================
+#
+# Python Lexical Analyser
+#
+# Exception classes
+#
+#=======================================================================
+
+import exceptions
+
+class PlexError(exceptions.Exception):
+ message = ""
+
+class PlexTypeError(PlexError, TypeError):
+ pass
+
+class PlexValueError(PlexError, ValueError):
+ pass
+
+class InvalidRegex(PlexError):
+ pass
+
+class InvalidToken(PlexError):
+
+ def __init__(self, token_number, message):
+ PlexError.__init__(self, "Token number %d: %s" % (token_number, message))
+
+class InvalidScanner(PlexError):
+ pass
+
+class AmbiguousAction(PlexError):
+ message = "Two tokens with different actions can match the same string"
+
+ def __init__(self):
+ pass
+
+class UnrecognizedInput(PlexError):
+ scanner = None
+ position = None
+ state_name = None
+
+ def __init__(self, scanner, state_name):
+ self.scanner = scanner
+ self.position = scanner.position()
+ self.state_name = state_name
+
+ def __str__(self):
+ return ("'%s', line %d, char %d: Token not recognised in state %s"
+ % (self.position + (repr(self.state_name),)))
+
+
+
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Lexicons.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Lexicons.py
new file mode 100755
index 00000000..32b12c43
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Lexicons.py
@@ -0,0 +1,192 @@
+#=======================================================================
+#
+# Python Lexical Analyser
+#
+# Lexical Analyser Specification
+#
+#=======================================================================
+
+import types
+
+import Actions
+import DFA
+import Errors
+import Machines
+import Regexps
+
+# debug_flags for Lexicon constructor
+DUMP_NFA = 1
+DUMP_DFA = 2
+
+class State:
+ """
+ This class is used as part of a Plex.Lexicon specification to
+ introduce a user-defined state.
+
+ Constructor:
+
+ State(name, token_specifications)
+ """
+
+ name = None
+ tokens = None
+
+ def __init__(self, name, tokens):
+ self.name = name
+ self.tokens = tokens
+
+class Lexicon:
+ """
+ Lexicon(specification) builds a lexical analyser from the given
+ |specification|. The specification consists of a list of
+ specification items. Each specification item may be either:
+
+ 1) A token definition, which is a tuple:
+
+ (pattern, action)
+
+ The |pattern| is a regular axpression built using the
+ constructors defined in the Plex module.
+
+ The |action| is the action to be performed when this pattern
+ is recognised (see below).
+
+ 2) A state definition:
+
+ State(name, tokens)
+
+ where |name| is a character string naming the state,
+ and |tokens| is a list of token definitions as
+ above. The meaning and usage of states is described
+ below.
+
+ Actions
+ -------
+
+ The |action| in a token specication may be one of three things:
+
+ 1) A function, which is called as follows:
+
+ function(scanner, text)
+
+ where |scanner| is the relevant Scanner instance, and |text|
+ is the matched text. If the function returns anything
+ other than None, that value is returned as the value of the
+ token. If it returns None, scanning continues as if the IGNORE
+ action were specified (see below).
+
+ 2) One of the following special actions:
+
+ IGNORE means that the recognised characters will be treated as
+ white space and ignored. Scanning will continue until
+ the next non-ignored token is recognised before returning.
+
+ TEXT causes the scanned text itself to be returned as the
+ value of the token.
+
+ 3) Any other value, which is returned as the value of the token.
+
+ States
+ ------
+
+ At any given time, the scanner is in one of a number of states.
+ Associated with each state is a set of possible tokens. When scanning,
+ only tokens associated with the current state are recognised.
+
+ There is a default state, whose name is the empty string. Token
+ definitions which are not inside any State definition belong to
+ the default state.
+
+ The initial state of the scanner is the default state. The state can
+ be changed in one of two ways:
+
+ 1) Using Begin(state_name) as the action of a token.
+
+ 2) Calling the begin(state_name) method of the Scanner.
+
+ To change back to the default state, use '' as the state name.
+ """
+
+ machine = None # Machine
+ tables = None # StateTableMachine
+
+ def __init__(self, specifications, debug = None, debug_flags = 7, timings = None):
+ if type(specifications) <> types.ListType:
+ raise Errors.InvalidScanner("Scanner definition is not a list")
+ if timings:
+ from Timing import time
+ total_time = 0.0
+ time1 = time()
+ nfa = Machines.Machine()
+ default_initial_state = nfa.new_initial_state('')
+ token_number = 1
+ for spec in specifications:
+ if isinstance(spec, State):
+ user_initial_state = nfa.new_initial_state(spec.name)
+ for token in spec.tokens:
+ self.add_token_to_machine(
+ nfa, user_initial_state, token, token_number)
+ token_number = token_number + 1
+ elif type(spec) == types.TupleType:
+ self.add_token_to_machine(
+ nfa, default_initial_state, spec, token_number)
+ token_number = token_number + 1
+ else:
+ raise Errors.InvalidToken(
+ token_number,
+ "Expected a token definition (tuple) or State instance")
+ if timings:
+ time2 = time()
+ total_time = total_time + (time2 - time1)
+ time3 = time()
+ if debug and (debug_flags & 1):
+ debug.write("\n============= NFA ===========\n")
+ nfa.dump(debug)
+ dfa = DFA.nfa_to_dfa(nfa, debug = (debug_flags & 3) == 3 and debug)
+ if timings:
+ time4 = time()
+ total_time = total_time + (time4 - time3)
+ if debug and (debug_flags & 2):
+ debug.write("\n============= DFA ===========\n")
+ dfa.dump(debug)
+ if timings:
+ timings.write("Constructing NFA : %5.2f\n" % (time2 - time1))
+ timings.write("Converting to DFA: %5.2f\n" % (time4 - time3))
+ timings.write("TOTAL : %5.2f\n" % total_time)
+ self.machine = dfa
+
+ def add_token_to_machine(self, machine, initial_state, token_spec, token_number):
+ try:
+ (re, action_spec) = self.parse_token_definition(token_spec)
+ # Disabled this -- matching empty strings can be useful
+ #if re.nullable:
+ # raise Errors.InvalidToken(
+ # token_number, "Pattern can match 0 input symbols")
+ if isinstance(action_spec, Actions.Action):
+ action = action_spec
+ elif callable(action_spec):
+ action = Actions.Call(action_spec)
+ else:
+ action = Actions.Return(action_spec)
+ final_state = machine.new_state()
+ re.build_machine(machine, initial_state, final_state,
+ match_bol = 1, nocase = 0)
+ final_state.set_action(action, priority = -token_number)
+ except Errors.PlexError, e:
+ raise e.__class__("Token number %d: %s" % (token_number, e))
+
+ def parse_token_definition(self, token_spec):
+ if type(token_spec) <> types.TupleType:
+ raise Errors.InvalidToken("Token definition is not a tuple")
+ if len(token_spec) <> 2:
+ raise Errors.InvalidToken("Wrong number of items in token definition")
+ pattern, action = token_spec
+ if not isinstance(pattern, Regexps.RE):
+ raise Errors.InvalidToken("Pattern is not an RE instance")
+ return (pattern, action)
+
+ def get_initial_state(self, name):
+ return self.machine.get_initial_state(name)
+
+
+
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Machines.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Machines.py
new file mode 100755
index 00000000..fb9ba717
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Machines.py
@@ -0,0 +1,326 @@
+#=======================================================================
+#
+# Python Lexical Analyser
+#
+# Classes for building NFAs and DFAs
+#
+#=======================================================================
+
+import string
+import sys
+from sys import maxint
+from types import TupleType
+
+from Transitions import TransitionMap
+
+LOWEST_PRIORITY = -sys.maxint
+
+class Machine:
+ """A collection of Nodes representing an NFA or DFA."""
+ states = None # [Node]
+ next_state_number = 1
+ initial_states = None # {(name, bol): Node}
+
+ def __init__(self):
+ self.states = []
+ self.initial_states = {}
+
+ def __del__(self):
+ #print "Destroying", self ###
+ for state in self.states:
+ state.destroy()
+
+ def new_state(self):
+ """Add a new state to the machine and return it."""
+ s = Node()
+ n = self.next_state_number
+ self.next_state_number = n + 1
+ s.number = n
+ self.states.append(s)
+ return s
+
+ def new_initial_state(self, name):
+ state = self.new_state()
+ self.make_initial_state(name, state)
+ return state
+
+ def make_initial_state(self, name, state):
+ self.initial_states[name] = state
+
+ def get_initial_state(self, name):
+ return self.initial_states[name]
+
+ def dump(self, file):
+ file.write("Plex.Machine:\n")
+ if self.initial_states is not None:
+ file.write(" Initial states:\n")
+ for (name, state) in self.initial_states.items():
+ file.write(" '%s': %d\n" % (name, state.number))
+ for s in self.states:
+ s.dump(file)
+
+class Node:
+ """A state of an NFA or DFA."""
+ transitions = None # TransitionMap
+ action = None # Action
+ action_priority = None # integer
+ number = 0 # for debug output
+ epsilon_closure = None # used by nfa_to_dfa()
+
+ def __init__(self):
+ # Preinitialise the list of empty transitions, because
+ # the nfa-to-dfa algorithm needs it
+ #self.transitions = {'':[]}
+ self.transitions = TransitionMap()
+ self.action_priority = LOWEST_PRIORITY
+
+ def destroy(self):
+ #print "Destroying", self ###
+ self.transitions = None
+ self.action = None
+ self.epsilon_closure = None
+
+ def add_transition(self, event, new_state):
+ self.transitions.add(event, new_state)
+
+ def link_to(self, state):
+ """Add an epsilon-move from this state to another state."""
+ self.add_transition('', state)
+
+ def set_action(self, action, priority):
+ """Make this an accepting state with the given action. If
+ there is already an action, choose the action with highest
+ priority."""
+ if priority > self.action_priority:
+ self.action = action
+ self.action_priority = priority
+
+ def get_action(self):
+ return self.action
+
+ def get_action_priority(self):
+ return self.action_priority
+
+# def merge_actions(self, other_state):
+# """Merge actions of other state into this state according
+# to their priorities."""
+# action = other_state.get_action()
+# priority = other_state.get_action_priority()
+# self.set_action(action, priority)
+
+ def is_accepting(self):
+ return self.action is not None
+
+ def __str__(self):
+ return "State %d" % self.number
+
+ def dump(self, file):
+ import string
+ # Header
+ file.write(" State %d:\n" % self.number)
+ # Transitions
+# self.dump_transitions(file)
+ self.transitions.dump(file)
+ # Action
+ action = self.action
+ priority = self.action_priority
+ if action is not None:
+ file.write(" %s [priority %d]\n" % (action, priority))
+
+
+class FastMachine:
+ """
+ FastMachine is a deterministic machine represented in a way that
+ allows fast scanning.
+ """
+ initial_states = None # {state_name:state}
+ states = None # [state]
+ # where state = {event:state, 'else':state, 'action':Action}
+ next_number = 1 # for debugging
+
+ new_state_template = {
+ '':None, 'bol':None, 'eol':None, 'eof':None, 'else':None
+ }
+
+ def __init__(self, old_machine = None):
+ self.initial_states = initial_states = {}
+ self.states = []
+ if old_machine:
+ self.old_to_new = old_to_new = {}
+ for old_state in old_machine.states:
+ new_state = self.new_state()
+ old_to_new[old_state] = new_state
+ for name, old_state in old_machine.initial_states.items():
+ initial_states[name] = old_to_new[old_state]
+ for old_state in old_machine.states:
+ new_state = old_to_new[old_state]
+ for event, old_state_set in old_state.transitions.items():
+ if old_state_set:
+ new_state[event] = old_to_new[old_state_set.keys()[0]]
+ else:
+ new_state[event] = None
+ new_state['action'] = old_state.action
+
+ def __del__(self):
+ for state in self.states:
+ state.clear()
+
+ def new_state(self, action = None):
+ number = self.next_number
+ self.next_number = number + 1
+ result = self.new_state_template.copy()
+ result['number'] = number
+ result['action'] = action
+ self.states.append(result)
+ return result
+
+ def make_initial_state(self, name, state):
+ self.initial_states[name] = state
+
+ def add_transitions(self, state, event, new_state):
+ if type(event) == TupleType:
+ code0, code1 = event
+ if code0 == -maxint:
+ state['else'] = new_state
+ elif code1 <> maxint:
+ while code0 < code1:
+ state[chr(code0)] = new_state
+ code0 = code0 + 1
+ else:
+ state[event] = new_state
+
+ def get_initial_state(self, name):
+ return self.initial_states[name]
+
+ def dump(self, file):
+ file.write("Plex.FastMachine:\n")
+ file.write(" Initial states:\n")
+ for name, state in self.initial_states.items():
+ file.write(" %s: %s\n" % (repr(name), state['number']))
+ for state in self.states:
+ self.dump_state(state, file)
+
+ def dump_state(self, state, file):
+ import string
+ # Header
+ file.write(" State %d:\n" % state['number'])
+ # Transitions
+ self.dump_transitions(state, file)
+ # Action
+ action = state['action']
+ if action is not None:
+ file.write(" %s\n" % action)
+
+ def dump_transitions(self, state, file):
+ chars_leading_to_state = {}
+ special_to_state = {}
+ for (c, s) in state.items():
+ if len(c) == 1:
+ chars = chars_leading_to_state.get(id(s), None)
+ if chars is None:
+ chars = []
+ chars_leading_to_state[id(s)] = chars
+ chars.append(c)
+ elif len(c) <= 4:
+ special_to_state[c] = s
+ ranges_to_state = {}
+ for state in self.states:
+ char_list = chars_leading_to_state.get(id(state), None)
+ if char_list:
+ ranges = self.chars_to_ranges(char_list)
+ ranges_to_state[ranges] = state
+ ranges_list = ranges_to_state.keys()
+ ranges_list.sort()
+ for ranges in ranges_list:
+ key = self.ranges_to_string(ranges)
+ state = ranges_to_state[ranges]
+ file.write(" %s --> State %d\n" % (key, state['number']))
+ for key in ('bol', 'eol', 'eof', 'else'):
+ state = special_to_state.get(key, None)
+ if state:
+ file.write(" %s --> State %d\n" % (key, state['number']))
+
+ def chars_to_ranges(self, char_list):
+ char_list.sort()
+ i = 0
+ n = len(char_list)
+ result = []
+ while i < n:
+ c1 = ord(char_list[i])
+ c2 = c1
+ i = i + 1
+ while i < n and ord(char_list[i]) == c2 + 1:
+ i = i + 1
+ c2 = c2 + 1
+ result.append((chr(c1), chr(c2)))
+ return tuple(result)
+
+ def ranges_to_string(self, range_list):
+ return string.join(map(self.range_to_string, range_list), ",")
+
+ def range_to_string(self, (c1, c2)):
+ if c1 == c2:
+ return repr(c1)
+ else:
+ return "%s..%s" % (repr(c1), repr(c2))
+##
+## (Superseded by Machines.FastMachine)
+##
+## class StateTableMachine:
+## """
+## StateTableMachine is an alternative representation of a Machine
+## that can be run more efficiently.
+## """
+## initial_states = None # {state_name:state_index}
+## states = None # [([state] indexed by char code, Action)]
+
+## special_map = {'bol':256, 'eol':257, 'eof':258}
+
+## def __init__(self, m):
+## """
+## Initialise StateTableMachine from Machine |m|.
+## """
+## initial_states = self.initial_states = {}
+## states = self.states = [None]
+## old_to_new = {}
+## i = 1
+## for old_state in m.states:
+## new_state = ([0] * 259, old_state.get_action())
+## states.append(new_state)
+## old_to_new[old_state] = i # new_state
+## i = i + 1
+## for name, old_state in m.initial_states.items():
+## initial_states[name] = old_to_new[old_state]
+## for old_state in m.states:
+## new_state_index = old_to_new[old_state]
+## new_table = states[new_state_index][0]
+## transitions = old_state.transitions
+## for c, old_targets in transitions.items():
+## if old_targets:
+## old_target = old_targets[0]
+## new_target_index = old_to_new[old_target]
+## if len(c) == 1:
+## a = ord(c)
+## else:
+## a = self.special_map[c]
+## new_table[a] = states[new_target_index]
+
+## def dump(self, f):
+## f.write("Plex.StateTableMachine:\n")
+## f.write(" Initial states:\n")
+## for name, index in self.initial_states.items():
+## f.write(" %s: State %d\n" % (
+## repr(name), id(self.states[index])))
+## for i in xrange(1, len(self.states)):
+## table, action = self.states[i]
+## f.write(" State %d:" % i)
+## if action:
+## f.write("%s" % action)
+## f.write("\n")
+## f.write(" %s\n" % map(id,table))
+
+
+
+
+
+
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Regexps.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Regexps.py
new file mode 100755
index 00000000..6164d3bd
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Regexps.py
@@ -0,0 +1,557 @@
+#=======================================================================
+#
+# Python Lexical Analyser
+#
+# Regular Expressions
+#
+#=======================================================================
+
+import array
+import string
+import types
+from sys import maxint
+
+import Errors
+
+#
+# Constants
+#
+
+BOL = 'bol'
+EOL = 'eol'
+EOF = 'eof'
+
+nl_code = ord('\n')
+
+#
+# Helper functions
+#
+
+def chars_to_ranges(s):
+ """
+ Return a list of character codes consisting of pairs
+ [code1a, code1b, code2a, code2b,...] which cover all
+ the characters in |s|.
+ """
+ char_list = list(s)
+ char_list.sort()
+ i = 0
+ n = len(char_list)
+ result = []
+ while i < n:
+ code1 = ord(char_list[i])
+ code2 = code1 + 1
+ i = i + 1
+ while i < n and code2 >= ord(char_list[i]):
+ code2 = code2 + 1
+ i = i + 1
+ result.append(code1)
+ result.append(code2)
+ return result
+
+def uppercase_range(code1, code2):
+ """
+ If the range of characters from code1 to code2-1 includes any
+ lower case letters, return the corresponding upper case range.
+ """
+ code3 = max(code1, ord('a'))
+ code4 = min(code2, ord('z') + 1)
+ if code3 < code4:
+ d = ord('A') - ord('a')
+ return (code3 + d, code4 + d)
+ else:
+ return None
+
+def lowercase_range(code1, code2):
+ """
+ If the range of characters from code1 to code2-1 includes any
+ upper case letters, return the corresponding lower case range.
+ """
+ code3 = max(code1, ord('A'))
+ code4 = min(code2, ord('Z') + 1)
+ if code3 < code4:
+ d = ord('a') - ord('A')
+ return (code3 + d, code4 + d)
+ else:
+ return None
+
+def CodeRanges(code_list):
+ """
+ Given a list of codes as returned by chars_to_ranges, return
+ an RE which will match a character in any of the ranges.
+ """
+ re_list = []
+ for i in xrange(0, len(code_list), 2):
+ re_list.append(CodeRange(code_list[i], code_list[i + 1]))
+ return apply(Alt, tuple(re_list))
+
+def CodeRange(code1, code2):
+ """
+ CodeRange(code1, code2) is an RE which matches any character
+ with a code |c| in the range |code1| <= |c| < |code2|.
+ """
+ if code1 <= nl_code < code2:
+ return Alt(RawCodeRange(code1, nl_code),
+ RawNewline,
+ RawCodeRange(nl_code + 1, code2))
+ else:
+ return RawCodeRange(code1, code2)
+
+#
+# Abstract classes
+#
+
+class RE:
+ """RE is the base class for regular expression constructors.
+ The following operators are defined on REs:
+
+ re1 + re2 is an RE which matches |re1| followed by |re2|
+ re1 | re2 is an RE which matches either |re1| or |re2|
+ """
+
+ nullable = 1 # True if this RE can match 0 input symbols
+ match_nl = 1 # True if this RE can match a string ending with '\n'
+ str = None # Set to a string to override the class's __str__ result
+
+ def build_machine(self, machine, initial_state, final_state,
+ match_bol, nocase):
+ """
+ This method should add states to |machine| to implement this
+ RE, starting at |initial_state| and ending at |final_state|.
+ If |match_bol| is true, the RE must be able to match at the
+ beginning of a line. If nocase is true, upper and lower case
+ letters should be treated as equivalent.
+ """
+ raise exceptions.UnimplementedMethod("%s.build_machine not implemented" %
+ self.__class__.__name__)
+
+ def build_opt(self, m, initial_state, c):
+ """
+ Given a state |s| of machine |m|, return a new state
+ reachable from |s| on character |c| or epsilon.
+ """
+ s = m.new_state()
+ initial_state.link_to(s)
+ initial_state.add_transition(c, s)
+ return s
+
+ def __add__(self, other):
+ return Seq(self, other)
+
+ def __or__(self, other):
+ return Alt(self, other)
+
+ def __str__(self):
+ if self.str:
+ return self.str
+ else:
+ return self.calc_str()
+
+ def check_re(self, num, value):
+ if not isinstance(value, RE):
+ self.wrong_type(num, value, "Plex.RE instance")
+
+ def check_string(self, num, value):
+ if type(value) <> type(''):
+ self.wrong_type(num, value, "string")
+
+ def check_char(self, num, value):
+ self.check_string(num, value)
+ if len(value) <> 1:
+ raise Errors.PlexValueError("Invalid value for argument %d of Plex.%s."
+ "Expected a string of length 1, got: %s" % (
+ num, self.__class__.__name__, repr(value)))
+
+ def wrong_type(self, num, value, expected):
+ if type(value) == types.InstanceType:
+ got = "%s.%s instance" % (
+ value.__class__.__module__, value.__class__.__name__)
+ else:
+ got = type(value).__name__
+ raise Errors.PlexTypeError("Invalid type for argument %d of Plex.%s "
+ "(expected %s, got %s" % (
+ num, self.__class__.__name__, expected, got))
+
+#
+# Primitive RE constructors
+# -------------------------
+#
+# These are the basic REs from which all others are built.
+#
+
+## class Char(RE):
+## """
+## Char(c) is an RE which matches the character |c|.
+## """
+
+## nullable = 0
+
+## def __init__(self, char):
+## self.char = char
+## self.match_nl = char == '\n'
+
+## def build_machine(self, m, initial_state, final_state, match_bol, nocase):
+## c = self.char
+## if match_bol and c <> BOL:
+## s1 = self.build_opt(m, initial_state, BOL)
+## else:
+## s1 = initial_state
+## if c == '\n' or c == EOF:
+## s1 = self.build_opt(m, s1, EOL)
+## if len(c) == 1:
+## code = ord(self.char)
+## s1.add_transition((code, code+1), final_state)
+## if nocase and is_letter_code(code):
+## code2 = other_case_code(code)
+## s1.add_transition((code2, code2+1), final_state)
+## else:
+## s1.add_transition(c, final_state)
+
+## def calc_str(self):
+## return "Char(%s)" % repr(self.char)
+
+def Char(c):
+ """
+ Char(c) is an RE which matches the character |c|.
+ """
+ if len(c) == 1:
+ result = CodeRange(ord(c), ord(c) + 1)
+ else:
+ result = SpecialSymbol(c)
+ result.str = "Char(%s)" % repr(c)
+ return result
+
+class RawCodeRange(RE):
+ """
+ RawCodeRange(code1, code2) is a low-level RE which matches any character
+ with a code |c| in the range |code1| <= |c| < |code2|, where the range
+ does not include newline. For internal use only.
+ """
+ nullable = 0
+ match_nl = 0
+ range = None # (code, code)
+ uppercase_range = None # (code, code) or None
+ lowercase_range = None # (code, code) or None
+
+ def __init__(self, code1, code2):
+ self.range = (code1, code2)
+ self.uppercase_range = uppercase_range(code1, code2)
+ self.lowercase_range = lowercase_range(code1, code2)
+
+ def build_machine(self, m, initial_state, final_state, match_bol, nocase):
+ if match_bol:
+ initial_state = self.build_opt(m, initial_state, BOL)
+ initial_state.add_transition(self.range, final_state)
+ if nocase:
+ if self.uppercase_range:
+ initial_state.add_transition(self.uppercase_range, final_state)
+ if self.lowercase_range:
+ initial_state.add_transition(self.lowercase_range, final_state)
+
+ def calc_str(self):
+ return "CodeRange(%d,%d)" % (self.code1, self.code2)
+
+class _RawNewline(RE):
+ """
+ RawNewline is a low-level RE which matches a newline character.
+ For internal use only.
+ """
+ nullable = 0
+ match_nl = 1
+
+ def build_machine(self, m, initial_state, final_state, match_bol, nocase):
+ if match_bol:
+ initial_state = self.build_opt(m, initial_state, BOL)
+ s = self.build_opt(m, initial_state, EOL)
+ s.add_transition((nl_code, nl_code + 1), final_state)
+
+RawNewline = _RawNewline()
+
+
+class SpecialSymbol(RE):
+ """
+ SpecialSymbol(sym) is an RE which matches the special input
+ symbol |sym|, which is one of BOL, EOL or EOF.
+ """
+ nullable = 0
+ match_nl = 0
+ sym = None
+
+ def __init__(self, sym):
+ self.sym = sym
+
+ def build_machine(self, m, initial_state, final_state, match_bol, nocase):
+ # Sequences 'bol bol' and 'bol eof' are impossible, so only need
+ # to allow for bol if sym is eol
+ if match_bol and self.sym == EOL:
+ initial_state = self.build_opt(m, initial_state, BOL)
+ initial_state.add_transition(self.sym, final_state)
+
+
+class Seq(RE):
+ """Seq(re1, re2, re3...) is an RE which matches |re1| followed by
+ |re2| followed by |re3|..."""
+
+ def __init__(self, *re_list):
+ nullable = 1
+ for i in xrange(len(re_list)):
+ re = re_list[i]
+ self.check_re(i, re)
+ nullable = nullable and re.nullable
+ self.re_list = re_list
+ self.nullable = nullable
+ i = len(re_list)
+ match_nl = 0
+ while i:
+ i = i - 1
+ re = re_list[i]
+ if re.match_nl:
+ match_nl = 1
+ break
+ if not re.nullable:
+ break
+ self.match_nl = match_nl
+
+ def build_machine(self, m, initial_state, final_state, match_bol, nocase):
+ re_list = self.re_list
+ if len(re_list) == 0:
+ initial_state.link_to(final_state)
+ else:
+ s1 = initial_state
+ n = len(re_list)
+ for i in xrange(n):
+ if i < n - 1:
+ s2 = m.new_state()
+ else:
+ s2 = final_state
+ re = re_list[i]
+ re.build_machine(m, s1, s2, match_bol, nocase)
+ s1 = s2
+ match_bol = re.match_nl or (match_bol and re.nullable)
+
+ def calc_str(self):
+ return "Seq(%s)" % string.join(map(str, self.re_list), ",")
+
+
+class Alt(RE):
+ """Alt(re1, re2, re3...) is an RE which matches either |re1| or
+ |re2| or |re3|..."""
+
+ def __init__(self, *re_list):
+ self.re_list = re_list
+ nullable = 0
+ match_nl = 0
+ nullable_res = []
+ non_nullable_res = []
+ i = 1
+ for re in re_list:
+ self.check_re(i, re)
+ if re.nullable:
+ nullable_res.append(re)
+ nullable = 1
+ else:
+ non_nullable_res.append(re)
+ if re.match_nl:
+ match_nl = 1
+ i = i + 1
+ self.nullable_res = nullable_res
+ self.non_nullable_res = non_nullable_res
+ self.nullable = nullable
+ self.match_nl = match_nl
+
+ def build_machine(self, m, initial_state, final_state, match_bol, nocase):
+ for re in self.nullable_res:
+ re.build_machine(m, initial_state, final_state, match_bol, nocase)
+ if self.non_nullable_res:
+ if match_bol:
+ initial_state = self.build_opt(m, initial_state, BOL)
+ for re in self.non_nullable_res:
+ re.build_machine(m, initial_state, final_state, 0, nocase)
+
+ def calc_str(self):
+ return "Alt(%s)" % string.join(map(str, self.re_list), ",")
+
+
+class Rep1(RE):
+ """Rep1(re) is an RE which matches one or more repetitions of |re|."""
+
+ def __init__(self, re):
+ self.check_re(1, re)
+ self.re = re
+ self.nullable = re.nullable
+ self.match_nl = re.match_nl
+
+ def build_machine(self, m, initial_state, final_state, match_bol, nocase):
+ s1 = m.new_state()
+ s2 = m.new_state()
+ initial_state.link_to(s1)
+ self.re.build_machine(m, s1, s2, match_bol or self.re.match_nl, nocase)
+ s2.link_to(s1)
+ s2.link_to(final_state)
+
+ def calc_str(self):
+ return "Rep1(%s)" % self.re
+
+
+class SwitchCase(RE):
+ """
+ SwitchCase(re, nocase) is an RE which matches the same strings as RE,
+ but treating upper and lower case letters according to |nocase|. If
+ |nocase| is true, case is ignored, otherwise it is not.
+ """
+ re = None
+ nocase = None
+
+ def __init__(self, re, nocase):
+ self.re = re
+ self.nocase = nocase
+ self.nullable = re.nullable
+ self.match_nl = re.match_nl
+
+ def build_machine(self, m, initial_state, final_state, match_bol, nocase):
+ self.re.build_machine(m, initial_state, final_state, match_bol,
+ self.nocase)
+
+ def calc_str(self):
+ if self.nocase:
+ name = "NoCase"
+ else:
+ name = "Case"
+ return "%s(%s)" % (name, self.re)
+
+#
+# Composite RE constructors
+# -------------------------
+#
+# These REs are defined in terms of the primitive REs.
+#
+
+Empty = Seq()
+Empty.__doc__ = \
+ """
+ Empty is an RE which matches the empty string.
+ """
+Empty.str = "Empty"
+
+def Str1(s):
+ """
+ Str1(s) is an RE which matches the literal string |s|.
+ """
+ result = apply(Seq, tuple(map(Char, s)))
+ result.str = "Str(%s)" % repr(s)
+ return result
+
+def Str(*strs):
+ """
+ Str(s) is an RE which matches the literal string |s|.
+ Str(s1, s2, s3, ...) is an RE which matches any of |s1| or |s2| or |s3|...
+ """
+ if len(strs) == 1:
+ return Str1(strs[0])
+ else:
+ result = apply(Alt, tuple(map(Str1, strs)))
+ result.str = "Str(%s)" % string.join(map(repr, strs), ",")
+ return result
+
+def Any(s):
+ """
+ Any(s) is an RE which matches any character in the string |s|.
+ """
+ #result = apply(Alt, tuple(map(Char, s)))
+ result = CodeRanges(chars_to_ranges(s))
+ result.str = "Any(%s)" % repr(s)
+ return result
+
+def AnyBut(s):
+ """
+ AnyBut(s) is an RE which matches any character (including
+ newline) which is not in the string |s|.
+ """
+ ranges = chars_to_ranges(s)
+ ranges.insert(0, -maxint)
+ ranges.append(maxint)
+ result = CodeRanges(ranges)
+ result.str = "AnyBut(%s)" % repr(s)
+ return result
+
+AnyChar = AnyBut("")
+AnyChar.__doc__ = \
+ """
+ AnyChar is an RE which matches any single character (including a newline).
+ """
+AnyChar.str = "AnyChar"
+
+def Range(s1, s2 = None):
+ """
+ Range(c1, c2) is an RE which matches any single character in the range
+ |c1| to |c2| inclusive.
+ Range(s) where |s| is a string of even length is an RE which matches
+ any single character in the ranges |s[0]| to |s[1]|, |s[2]| to |s[3]|,...
+ """
+ if s2:
+ result = CodeRange(ord(s1), ord(s2) + 1)
+ result.str = "Range(%s,%s)" % (s1, s2)
+ else:
+ ranges = []
+ for i in range(0, len(s1), 2):
+ ranges.append(CodeRange(ord(s1[i]), ord(s1[i+1]) + 1))
+ result = apply(Alt, tuple(ranges))
+ result.str = "Range(%s)" % repr(s1)
+ return result
+
+def Opt(re):
+ """
+ Opt(re) is an RE which matches either |re| or the empty string.
+ """
+ result = Alt(re, Empty)
+ result.str = "Opt(%s)" % re
+ return result
+
+def Rep(re):
+ """
+ Rep(re) is an RE which matches zero or more repetitions of |re|.
+ """
+ result = Opt(Rep1(re))
+ result.str = "Rep(%s)" % re
+ return result
+
+def NoCase(re):
+ """
+ NoCase(re) is an RE which matches the same strings as RE, but treating
+ upper and lower case letters as equivalent.
+ """
+ return SwitchCase(re, nocase = 1)
+
+def Case(re):
+ """
+ Case(re) is an RE which matches the same strings as RE, but treating
+ upper and lower case letters as distinct, i.e. it cancels the effect
+ of any enclosing NoCase().
+ """
+ return SwitchCase(re, nocase = 0)
+
+#
+# RE Constants
+#
+
+Bol = Char(BOL)
+Bol.__doc__ = \
+ """
+ Bol is an RE which matches the beginning of a line.
+ """
+Bol.str = "Bol"
+
+Eol = Char(EOL)
+Eol.__doc__ = \
+ """
+ Eol is an RE which matches the end of a line.
+ """
+Eol.str = "Eol"
+
+Eof = Char(EOF)
+Eof.__doc__ = \
+ """
+ Eof is an RE which matches the end of the file.
+ """
+Eof.str = "Eof"
+
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Scanners.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Scanners.py
new file mode 100755
index 00000000..6278d88b
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Scanners.py
@@ -0,0 +1,377 @@
+#=======================================================================
+#
+# Python Lexical Analyser
+#
+#
+# Scanning an input stream
+#
+#=======================================================================
+
+import Errors
+from Regexps import BOL, EOL, EOF
+
+class Scanner:
+ """
+ A Scanner is used to read tokens from a stream of characters
+ using the token set specified by a Plex.Lexicon.
+
+ Constructor:
+
+ Scanner(lexicon, stream, name = '')
+
+ See the docstring of the __init__ method for details.
+
+ Methods:
+
+ See the docstrings of the individual methods for more
+ information.
+
+ read() --> (value, text)
+ Reads the next lexical token from the stream.
+
+ position() --> (name, line, col)
+ Returns the position of the last token read using the
+ read() method.
+
+ begin(state_name)
+ Causes scanner to change state.
+
+ produce(value [, text])
+ Causes return of a token value to the caller of the
+ Scanner.
+
+ """
+
+ lexicon = None # Lexicon
+ stream = None # file-like object
+ name = ''
+ buffer = ''
+ buf_start_pos = 0 # position in input of start of buffer
+ next_pos = 0 # position in input of next char to read
+ cur_pos = 0 # position in input of current char
+ cur_line = 1 # line number of current char
+ cur_line_start = 0 # position in input of start of current line
+ start_pos = 0 # position in input of start of token
+ start_line = 0 # line number of start of token
+ start_col = 0 # position in line of start of token
+ text = None # text of last token read
+ initial_state = None # Node
+ state_name = '' # Name of initial state
+ queue = None # list of tokens to be returned
+ trace = 0
+
+ def __init__(self, lexicon, stream, name = ''):
+ """
+ Scanner(lexicon, stream, name = '')
+
+ |lexicon| is a Plex.Lexicon instance specifying the lexical tokens
+ to be recognised.
+
+ |stream| can be a file object or anything which implements a
+ compatible read() method.
+
+ |name| is optional, and may be the name of the file being
+ scanned or any other identifying string.
+ """
+ self.lexicon = lexicon
+ self.stream = stream
+ self.name = name
+ self.queue = []
+ self.initial_state = None
+ self.begin('')
+ self.next_pos = 0
+ self.cur_pos = 0
+ self.cur_line_start = 0
+ self.cur_char = BOL
+ self.input_state = 1
+
+ def read(self):
+ """
+ Read the next lexical token from the stream and return a
+ tuple (value, text), where |value| is the value associated with
+ the token as specified by the Lexicon, and |text| is the actual
+ string read from the stream. Returns (None, '') on end of file.
+ """
+ queue = self.queue
+ while not queue:
+ self.text, action = self.scan_a_token()
+ if action is None:
+ self.produce(None)
+ self.eof()
+ else:
+ value = action.perform(self, self.text)
+ if value is not None:
+ self.produce(value)
+ result = queue[0]
+ del queue[0]
+ return result
+
+ def scan_a_token(self):
+ """
+ Read the next input sequence recognised by the machine
+ and return (text, action). Returns ('', None) on end of
+ file.
+ """
+ self.start_pos = self.cur_pos
+ self.start_line = self.cur_line
+ self.start_col = self.cur_pos - self.cur_line_start
+# if self.trace:
+# action = self.run_machine()
+# else:
+# action = self.run_machine_inlined()
+ action = self.run_machine_inlined()
+ if action:
+ if self.trace:
+ print "Scanner: read: Performing", action, "%d:%d" % (
+ self.start_pos, self.cur_pos)
+ base = self.buf_start_pos
+ text = self.buffer[self.start_pos - base : self.cur_pos - base]
+ return (text, action)
+ else:
+ if self.cur_pos == self.start_pos:
+ if self.cur_char == EOL:
+ self.next_char()
+ if not self.cur_char or self.cur_char == EOF:
+ return ('', None)
+ raise Errors.UnrecognizedInput(self, self.state_name)
+
+ def run_machine(self):
+ """
+ Run the machine until no more transitions are possible.
+ """
+ self.state = self.initial_state
+ self.backup_state = None
+ while self.transition():
+ pass
+ return self.back_up()
+
+ def run_machine_inlined(self):
+ """
+ Inlined version of run_machine for speed.
+ """
+ state = self.initial_state
+ cur_pos = self.cur_pos
+ cur_line = self.cur_line
+ cur_line_start = self.cur_line_start
+ cur_char = self.cur_char
+ input_state = self.input_state
+ next_pos = self.next_pos
+ buffer = self.buffer
+ buf_start_pos = self.buf_start_pos
+ buf_len = len(buffer)
+ backup_state = None
+ trace = self.trace
+ while 1:
+ if trace: #TRACE#
+ print "State %d, %d/%d:%s -->" % ( #TRACE#
+ state['number'], input_state, cur_pos, repr(cur_char)), #TRACE#
+ # Begin inlined self.save_for_backup()
+ #action = state.action #@slow
+ action = state['action'] #@fast
+ if action:
+ backup_state = (
+ action, cur_pos, cur_line, cur_line_start, cur_char, input_state, next_pos)
+ # End inlined self.save_for_backup()
+ c = cur_char
+ #new_state = state.new_state(c) #@slow
+ new_state = state.get(c, -1) #@fast
+ if new_state == -1: #@fast
+ new_state = c and state.get('else') #@fast
+ if new_state:
+ if trace: #TRACE#
+ print "State %d" % new_state['number'] #TRACE#
+ state = new_state
+ # Begin inlined: self.next_char()
+ if input_state == 1:
+ cur_pos = next_pos
+ # Begin inlined: c = self.read_char()
+ buf_index = next_pos - buf_start_pos
+ if buf_index < buf_len:
+ c = buffer[buf_index]
+ next_pos = next_pos + 1
+ else:
+ discard = self.start_pos - buf_start_pos
+ data = self.stream.read(0x1000)
+ buffer = self.buffer[discard:] + data
+ self.buffer = buffer
+ buf_start_pos = buf_start_pos + discard
+ self.buf_start_pos = buf_start_pos
+ buf_len = len(buffer)
+ buf_index = buf_index - discard
+ if data:
+ c = buffer[buf_index]
+ next_pos = next_pos + 1
+ else:
+ c = ''
+ # End inlined: c = self.read_char()
+ if c == '\n':
+ cur_char = EOL
+ input_state = 2
+ elif not c:
+ cur_char = EOL
+ input_state = 4
+ else:
+ cur_char = c
+ elif input_state == 2:
+ cur_char = '\n'
+ input_state = 3
+ elif input_state == 3:
+ cur_line = cur_line + 1
+ cur_line_start = cur_pos = next_pos
+ cur_char = BOL
+ input_state = 1
+ elif input_state == 4:
+ cur_char = EOF
+ input_state = 5
+ else: # input_state = 5
+ cur_char = ''
+ # End inlined self.next_char()
+ else: # not new_state
+ if trace: #TRACE#
+ print "blocked" #TRACE#
+ # Begin inlined: action = self.back_up()
+ if backup_state:
+ (action, cur_pos, cur_line, cur_line_start,
+ cur_char, input_state, next_pos) = backup_state
+ else:
+ action = None
+ break # while 1
+ # End inlined: action = self.back_up()
+ self.cur_pos = cur_pos
+ self.cur_line = cur_line
+ self.cur_line_start = cur_line_start
+ self.cur_char = cur_char
+ self.input_state = input_state
+ self.next_pos = next_pos
+ if trace: #TRACE#
+ if action: #TRACE#
+ print "Doing", action #TRACE#
+ return action
+
+# def transition(self):
+# self.save_for_backup()
+# c = self.cur_char
+# new_state = self.state.new_state(c)
+# if new_state:
+# if self.trace:
+# print "Scanner: read: State %d: %s --> State %d" % (
+# self.state.number, repr(c), new_state.number)
+# self.state = new_state
+# self.next_char()
+# return 1
+# else:
+# if self.trace:
+# print "Scanner: read: State %d: %s --> blocked" % (
+# self.state.number, repr(c))
+# return 0
+
+# def save_for_backup(self):
+# action = self.state.get_action()
+# if action:
+# if self.trace:
+# print "Scanner: read: Saving backup point at", self.cur_pos
+# self.backup_state = (
+# action, self.cur_pos, self.cur_line, self.cur_line_start,
+# self.cur_char, self.input_state, self.next_pos)
+
+# def back_up(self):
+# backup_state = self.backup_state
+# if backup_state:
+# (action, self.cur_pos, self.cur_line, self.cur_line_start,
+# self.cur_char, self.input_state, self.next_pos) = backup_state
+# if self.trace:
+# print "Scanner: read: Backing up to", self.cur_pos
+# return action
+# else:
+# return None
+
+ def next_char(self):
+ input_state = self.input_state
+ if self.trace:
+ print "Scanner: next:", " "*20, "[%d] %d" % (input_state, self.cur_pos),
+ if input_state == 1:
+ self.cur_pos = self.next_pos
+ c = self.read_char()
+ if c == '\n':
+ self.cur_char = EOL
+ self.input_state = 2
+ elif not c:
+ self.cur_char = EOL
+ self.input_state = 4
+ else:
+ self.cur_char = c
+ elif input_state == 2:
+ self.cur_char = '\n'
+ self.input_state = 3
+ elif input_state == 3:
+ self.cur_line = self.cur_line + 1
+ self.cur_line_start = self.cur_pos = self.next_pos
+ self.cur_char = BOL
+ self.input_state = 1
+ elif input_state == 4:
+ self.cur_char = EOF
+ self.input_state = 5
+ else: # input_state = 5
+ self.cur_char = ''
+ if self.trace:
+ print "--> [%d] %d %s" % (input_state, self.cur_pos, repr(self.cur_char))
+
+# def read_char(self):
+# """
+# Get the next input character, filling the buffer if necessary.
+# Returns '' at end of file.
+# """
+# next_pos = self.next_pos
+# buf_index = next_pos - self.buf_start_pos
+# if buf_index == len(self.buffer):
+# discard = self.start_pos - self.buf_start_pos
+# data = self.stream.read(0x1000)
+# self.buffer = self.buffer[discard:] + data
+# self.buf_start_pos = self.buf_start_pos + discard
+# buf_index = buf_index - discard
+# if not data:
+# return ''
+# c = self.buffer[buf_index]
+# self.next_pos = next_pos + 1
+# return c
+
+ def position(self):
+ """
+ Return a tuple (name, line, col) representing the location of
+ the last token read using the read() method. |name| is the
+ name that was provided to the Scanner constructor; |line|
+ is the line number in the stream (1-based); |col| is the
+ position within the line of the first character of the token
+ (0-based).
+ """
+ return (self.name, self.start_line, self.start_col)
+
+ def begin(self, state_name):
+ """Set the current state of the scanner to the named state."""
+ self.initial_state = (
+ self.lexicon.get_initial_state(state_name))
+ self.state_name = state_name
+
+ def produce(self, value, text = None):
+ """
+ Called from an action procedure, causes |value| to be returned
+ as the token value from read(). If |text| is supplied, it is
+ returned in place of the scanned text.
+
+ produce() can be called more than once during a single call to an action
+ procedure, in which case the tokens are queued up and returned one
+ at a time by subsequent calls to read(), until the queue is empty,
+ whereupon scanning resumes.
+ """
+ if text is None:
+ text = self.text
+ self.queue.append((value, text))
+
+ def eof(self):
+ """
+ Override this method if you want something to be done at
+ end of file.
+ """
+
+# For backward compatibility:
+setattr(Scanner, "yield", Scanner.produce)
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Timing.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Timing.py
new file mode 100755
index 00000000..f47c5c89
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Timing.py
@@ -0,0 +1,22 @@
+#
+# Get time in platform-dependent way
+#
+
+import os
+from sys import platform, exit, stderr
+
+if platform == 'mac':
+ import MacOS
+ def time():
+ return MacOS.GetTicks() / 60.0
+ timekind = "real"
+elif hasattr(os, 'times'):
+ def time():
+ t = os.times()
+ return t[0] + t[1]
+ timekind = "cpu"
+else:
+ stderr.write(
+ "Don't know how to get time on platform %s\n" % repr(platform))
+ exit(1)
+
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Traditional.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Traditional.py
new file mode 100755
index 00000000..b3148c1e
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Traditional.py
@@ -0,0 +1,154 @@
+#=======================================================================
+#
+# Python Lexical Analyser
+#
+# Traditional Regular Expression Syntax
+#
+#=======================================================================
+
+from Regexps import *
+from Errors import PlexError
+
+class RegexpSyntaxError(PlexError):
+ pass
+
+def re(s):
+ """
+ Convert traditional string representation of regular expression |s|
+ into Plex representation.
+ """
+ return REParser(s).parse_re()
+
+class REParser:
+
+ def __init__(self, s):
+ self.s = s
+ self.i = -1
+ self.end = 0
+ self.next()
+
+ def parse_re(self):
+ re = self.parse_alt()
+ if not self.end:
+ self.error("Unexpected %s" % repr(self.c))
+ return re
+
+ def parse_alt(self):
+ """Parse a set of alternative regexps."""
+ re = self.parse_seq()
+ if self.c == '|':
+ re_list = [re]
+ while self.c == '|':
+ self.next()
+ re_list.append(self.parse_seq())
+ re = apply(Alt, tuple(re_list))
+ return re
+
+ def parse_seq(self):
+ """Parse a sequence of regexps."""
+ re_list = []
+ while not self.end and not self.c in "|)":
+ re_list.append(self.parse_mod())
+ return apply(Seq, tuple(re_list))
+
+ def parse_mod(self):
+ """Parse a primitive regexp followed by *, +, ? modifiers."""
+ re = self.parse_prim()
+ while not self.end and self.c in "*+?":
+ if self.c == '*':
+ re = Rep(re)
+ elif self.c == '+':
+ re = Rep1(re)
+ else: # self.c == '?'
+ re = Opt(re)
+ self.next()
+ return re
+
+ def parse_prim(self):
+ """Parse a primitive regexp."""
+ c = self.get()
+ if c == '.':
+ re = AnyBut("\n")
+ elif c == '^':
+ re = Bol
+ elif c == '$':
+ re = Eol
+ elif c == '(':
+ re = self.parse_alt()
+ self.expect(')')
+ elif c == '[':
+ re = self.parse_charset()
+ self.expect(']')
+ else:
+ if c == '\\':
+ c = self.get()
+ re = Char(c)
+ return re
+
+ def parse_charset(self):
+ """Parse a charset. Does not include the surrounding []."""
+ char_list = []
+ invert = 0
+ if self.c == '^':
+ invert = 1
+ self.next()
+ if self.c == ']':
+ char_list.append(']')
+ self.next()
+ while not self.end and self.c <> ']':
+ c1 = self.get()
+ if self.c == '-' and self.lookahead(1) <> ']':
+ self.next()
+ c2 = self.get()
+ for a in xrange(ord(c1), ord(c2) + 1):
+ char_list.append(chr(a))
+ else:
+ char_list.append(c1)
+ chars = string.join(char_list, "")
+ if invert:
+ return AnyBut(chars)
+ else:
+ return Any(chars)
+
+ def next(self):
+ """Advance to the next char."""
+ s = self.s
+ i = self.i = self.i + 1
+ if i < len(s):
+ self.c = s[i]
+ else:
+ self.c = ''
+ self.end = 1
+
+ def get(self):
+ if self.end:
+ self.error("Premature end of string")
+ c = self.c
+ self.next()
+ return c
+
+ def lookahead(self, n):
+ """Look ahead n chars."""
+ j = self.i + n
+ if j < len(self.s):
+ return self.s[j]
+ else:
+ return ''
+
+ def expect(self, c):
+ """
+ Expect to find character |c| at current position.
+ Raises an exception otherwise.
+ """
+ if self.c == c:
+ self.next()
+ else:
+ self.error("Missing %s" % repr(c))
+
+ def error(self, mess):
+ """Raise exception to signal syntax error in regexp."""
+ raise RegexpSyntaxError("Syntax error in regexp %s at position %d: %s" % (
+ repr(self.s), self.i, mess))
+
+
+
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Transitions.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Transitions.py
new file mode 100755
index 00000000..c1edd5ef
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/Transitions.py
@@ -0,0 +1,253 @@
+#
+# Plex - Transition Maps
+#
+# This version represents state sets direcly as dicts
+# for speed.
+#
+
+from copy import copy
+import string
+from sys import maxint
+from types import TupleType
+
+class TransitionMap:
+ """
+ A TransitionMap maps an input event to a set of states.
+ An input event is one of: a range of character codes,
+ the empty string (representing an epsilon move), or one
+ of the special symbols BOL, EOL, EOF.
+
+ For characters, this implementation compactly represents
+ the map by means of a list:
+
+ [code_0, states_0, code_1, states_1, code_2, states_2,
+ ..., code_n-1, states_n-1, code_n]
+
+ where |code_i| is a character code, and |states_i| is a
+ set of states corresponding to characters with codes |c|
+ in the range |code_i| <= |c| <= |code_i+1|.
+
+ The following invariants hold:
+ n >= 1
+ code_0 == -maxint
+ code_n == maxint
+ code_i < code_i+1 for i in 0..n-1
+ states_0 == states_n-1
+
+ Mappings for the special events '', BOL, EOL, EOF are
+ kept separately in a dictionary.
+ """
+
+ map = None # The list of codes and states
+ special = None # Mapping for special events
+
+ def __init__(self, map = None, special = None):
+ if not map:
+ map = [-maxint, {}, maxint]
+ if not special:
+ special = {}
+ self.map = map
+ self.special = special
+ #self.check() ###
+
+ def add(self, event, new_state,
+ TupleType = TupleType):
+ """
+ Add transition to |new_state| on |event|.
+ """
+ if type(event) == TupleType:
+ code0, code1 = event
+ i = self.split(code0)
+ j = self.split(code1)
+ map = self.map
+ while i < j:
+ map[i + 1][new_state] = 1
+ i = i + 2
+ else:
+ self.get_special(event)[new_state] = 1
+
+ def add_set(self, event, new_set,
+ TupleType = TupleType):
+ """
+ Add transitions to the states in |new_set| on |event|.
+ """
+ if type(event) == TupleType:
+ code0, code1 = event
+ i = self.split(code0)
+ j = self.split(code1)
+ map = self.map
+ while i < j:
+ map[i + 1].update(new_set)
+ i = i + 2
+ else:
+ self.get_special(event).update(new_set)
+
+ def get_epsilon(self,
+ none = None):
+ """
+ Return the mapping for epsilon, or None.
+ """
+ return self.special.get('', none)
+
+ def items(self,
+ len = len):
+ """
+ Return the mapping as a list of ((code1, code2), state_set) and
+ (special_event, state_set) pairs.
+ """
+ result = []
+ map = self.map
+ else_set = map[1]
+ i = 0
+ n = len(map) - 1
+ code0 = map[0]
+ while i < n:
+ set = map[i + 1]
+ code1 = map[i + 2]
+ if set or else_set:
+ result.append(((code0, code1), set))
+ code0 = code1
+ i = i + 2
+ for event, set in self.special.items():
+ if set:
+ result.append((event, set))
+ return result
+
+ # ------------------- Private methods --------------------
+
+ def split(self, code,
+ len = len, maxint = maxint):
+ """
+ Search the list for the position of the split point for |code|,
+ inserting a new split point if necessary. Returns index |i| such
+ that |code| == |map[i]|.
+ """
+ # We use a funky variation on binary search.
+ map = self.map
+ hi = len(map) - 1
+ # Special case: code == map[-1]
+ if code == maxint:
+ return hi
+ # General case
+ lo = 0
+ # loop invariant: map[lo] <= code < map[hi] and hi - lo >= 2
+ while hi - lo >= 4:
+ # Find midpoint truncated to even index
+ mid = ((lo + hi) / 2) & ~1
+ if code < map[mid]:
+ hi = mid
+ else:
+ lo = mid
+ # map[lo] <= code < map[hi] and hi - lo == 2
+ if map[lo] == code:
+ return lo
+ else:
+ map[hi:hi] = [code, map[hi - 1].copy()]
+ #self.check() ###
+ return hi
+
+ def get_special(self, event):
+ """
+ Get state set for special event, adding a new entry if necessary.
+ """
+ special = self.special
+ set = special.get(event, None)
+ if not set:
+ set = {}
+ special[event] = set
+ return set
+
+ # --------------------- Conversion methods -----------------------
+
+ def __str__(self):
+ map_strs = []
+ map = self.map
+ n = len(map)
+ i = 0
+ while i < n:
+ code = map[i]
+ if code == -maxint:
+ code_str = "-inf"
+ elif code == maxint:
+ code_str = "inf"
+ else:
+ code_str = str(code)
+ map_strs.append(code_str)
+ i = i + 1
+ if i < n:
+ map_strs.append(state_set_str(map[i]))
+ i = i + 1
+ special_strs = {}
+ for event, set in self.special.items():
+ special_strs[event] = state_set_str(set)
+ return "[%s]+%s" % (
+ string.join(map_strs, ","),
+ special_strs
+ )
+
+ # --------------------- Debugging methods -----------------------
+
+ def check(self):
+ """Check data structure integrity."""
+ if not self.map[-3] < self.map[-1]:
+ print self
+ assert 0
+
+ def dump(self, file):
+ map = self.map
+ i = 0
+ n = len(map) - 1
+ while i < n:
+ self.dump_range(map[i], map[i + 2], map[i + 1], file)
+ i = i + 2
+ for event, set in self.special.items():
+ if set:
+ if not event:
+ event = 'empty'
+ self.dump_trans(event, set, file)
+
+ def dump_range(self, code0, code1, set, file):
+ if set:
+ if code0 == -maxint:
+ if code1 == maxint:
+ k = "any"
+ else:
+ k = "< %s" % self.dump_char(code1)
+ elif code1 == maxint:
+ k = "> %s" % self.dump_char(code0 - 1)
+ elif code0 == code1 - 1:
+ k = self.dump_char(code0)
+ else:
+ k = "%s..%s" % (self.dump_char(code0),
+ self.dump_char(code1 - 1))
+ self.dump_trans(k, set, file)
+
+ def dump_char(self, code):
+ if 0 <= code <= 255:
+ return repr(chr(code))
+ else:
+ return "chr(%d)" % code
+
+ def dump_trans(self, key, set, file):
+ file.write(" %s --> %s\n" % (key, self.dump_set(set)))
+
+ def dump_set(self, set):
+ return state_set_str(set)
+
+#
+# State set manipulation functions
+#
+
+#def merge_state_sets(set1, set2):
+# for state in set2.keys():
+# set1[state] = 1
+
+def state_set_str(set):
+ state_list = set.keys()
+ str_list = []
+ for state in state_list:
+ str_list.append("S%d" % state.number)
+ return "[%s]" % string.join(str_list, ",")
+
+
+
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/__init__.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/__init__.py
new file mode 100755
index 00000000..22b9bba3
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/__init__.py
@@ -0,0 +1,40 @@
+#=======================================================================
+#
+# Python Lexical Analyser
+#
+#=======================================================================
+
+"""
+The Plex module provides lexical analysers with similar capabilities
+to GNU Flex. The following classes and functions are exported;
+see the attached docstrings for more information.
+
+ Scanner For scanning a character stream under the
+ direction of a Lexicon.
+
+ Lexicon For constructing a lexical definition
+ to be used by a Scanner.
+
+ Str, Any, AnyBut, AnyChar, Seq, Alt, Opt, Rep, Rep1,
+ Bol, Eol, Eof, Empty
+
+ Regular expression constructors, for building pattern
+ definitions for a Lexicon.
+
+ State For defining scanner states when creating a
+ Lexicon.
+
+ TEXT, IGNORE, Begin
+
+ Actions for associating with patterns when
+ creating a Lexicon.
+"""
+
+from Actions import TEXT, IGNORE, Begin
+from Lexicons import Lexicon, State
+from Regexps import RE, Seq, Alt, Rep1, Empty, Str, Any, AnyBut, AnyChar, Range
+from Regexps import Opt, Rep, Bol, Eol, Eof, Case, NoCase
+from Scanners import Scanner
+
+
+
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/test_tm.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/test_tm.py
new file mode 100755
index 00000000..e08c9e68
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Plex/test_tm.py
@@ -0,0 +1,24 @@
+import sys
+sys.stderr = sys.stdout
+
+from TransitionMaps import TransitionMap
+
+m = TransitionMap()
+print m
+
+def add(c, s):
+ print
+ print "adding", repr(c), "-->", repr(s)
+ m.add_transition(c, s)
+ print m
+ print "keys:", m.keys()
+
+add('a','alpha')
+add('e', 'eta')
+add('f', 'foo')
+add('i', 'iota')
+add('i', 'imp')
+add('eol', 'elephant')
+
+
+
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Unix/LinuxSystem.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Unix/LinuxSystem.py
new file mode 100644
index 00000000..50a75146
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Unix/LinuxSystem.py
@@ -0,0 +1,74 @@
+#
+# Pyrex - Linux system interface
+#
+
+verbose = 0
+gcc_pendantic = True
+gcc_warnings_are_errors = True
+gcc_all_warnings = True
+
+import os, sys
+from Pyrex.Utils import replace_suffix
+from Pyrex.Compiler.Errors import PyrexError
+
+version = "%s.%s" % sys.version[:2]
+py_include_dirs = [
+ "%s/include/python%s" % (sys.prefix, version)
+]
+
+compilers = ["gcc", "g++"]
+compiler_options = \
+ "-g -c -fno-strict-aliasing -Wno-long-double -no-cpp-precomp " \
+ "-mno-fused-madd -fno-common -dynamic " \
+ .split()
+if gcc_pendantic:
+ compiler_options.extend(["-pedantic", "-Wno-long-long"])
+if gcc_warnings_are_errors:
+ compiler_options.append("-Werror")
+if gcc_all_warnings:
+ compiler_options.append("-Wall")
+ compiler_options.append("-Wno-unused-function")
+
+linkers = ["gcc", "g++"]
+linker_options = \
+ "-shared" \
+ .split()
+
+class CCompilerError(PyrexError):
+ pass
+
+def c_compile(c_file, verbose_flag = 0, cplus = 0, obj_suffix = ".o"):
+ # Compile the given C source file to produce
+ # an object file. Returns the pathname of the
+ # resulting file.
+ c_file = os.path.join(os.getcwd(), c_file)
+ o_file = replace_suffix(c_file, obj_suffix)
+ include_options = []
+ for dir in py_include_dirs:
+ include_options.append("-I%s" % dir)
+ compiler = compilers[bool(cplus)]
+ args = [compiler] + compiler_options + include_options + [c_file, "-o", o_file]
+ if verbose_flag or verbose:
+ print " ".join(args)
+ #print compiler, args ###
+ status = os.spawnvp(os.P_WAIT, compiler, args)
+ if status <> 0:
+ raise CCompilerError("C compiler returned status %s" % status)
+ return o_file
+
+def c_link(obj_file, verbose_flag = 0, extra_objects = [], cplus = 0):
+ return c_link_list([obj_file] + extra_objects, verbose_flag, cplus)
+
+def c_link_list(obj_files, verbose_flag = 0, cplus = 0):
+ # Link the given object files into a dynamically
+ # loadable extension file. Returns the pathname
+ # of the resulting file.
+ out_file = replace_suffix(obj_files[0], ".so")
+ linker = linkers[bool(cplus)]
+ args = [linker] + linker_options + obj_files + ["-o", out_file]
+ if verbose_flag or verbose:
+ print " ".join(args)
+ status = os.spawnvp(os.P_WAIT, linker, args)
+ if status <> 0:
+ raise CCompilerError("Linker returned status %s" % status)
+ return out_file
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Unix/__init__.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Unix/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Unix/__init__.py
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/Utils.py b/debian/pyrex/pyrex-0.9.9/Pyrex/Utils.py
new file mode 100644
index 00000000..7fa06460
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/Utils.py
@@ -0,0 +1,55 @@
+#
+# Pyrex -- Things that don't belong
+# anywhere else in particular
+#
+
+import os, sys
+try:
+ from __builtin__ import set
+except ImportError:
+ from sets import Set as set
+
+def has_suffix(path, suffixes):
+ for suffix in suffixes:
+ if path.endswith(suffix):
+ return True
+ return False
+
+def replace_suffix(path, newsuf):
+ base, _ = os.path.splitext(path)
+ return base + newsuf
+
+def map_suffix(path, mapping, default):
+ base, suffix = os.path.splitext(path)
+ return base + mapping.get(suffix, default)
+
+def open_new_file(path):
+ # Open and truncate existing file to
+ # preserve metadata on the Mac.
+ return open(path, "w+")
+
+def castrate_file(path, st):
+ # Remove junk contents from an output file after a
+ # failed compilation, but preserve metadata on Mac.
+ # Also sets access and modification times earlier
+ # than those specified by st (a stat struct).
+ try:
+ f = open(path, "r+")
+ except EnvironmentError:
+ pass
+ else:
+ f.seek(0, 0)
+ f.truncate()
+ f.write(
+ "#error Do not use this file, it is the result of a failed Pyrex compilation.\n")
+ f.close()
+ if st:
+ os.utime(path, (st.st_atime - 1, st.st_mtime - 1))
+
+def modification_time(path):
+ st = os.stat(path)
+ return st.st_mtime
+
+def file_newer_than(path, time):
+ ftime = modification_time(path)
+ return ftime > time
diff --git a/debian/pyrex/pyrex-0.9.9/Pyrex/__init__.py b/debian/pyrex/pyrex-0.9.9/Pyrex/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Pyrex/__init__.py
diff --git a/debian/pyrex/pyrex-0.9.9/README.txt b/debian/pyrex/pyrex-0.9.9/README.txt
new file mode 100644
index 00000000..deda8286
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/README.txt
@@ -0,0 +1,37 @@
+Welcome to Pyrex!
+=================
+
+This is a development version of Pyrex, a language
+for writing Python extension modules.
+
+For more info, see:
+
+ Doc/About.html for a description of the language
+ INSTALL.txt for installation instructions
+ USAGE.txt for usage instructions
+ Demos for usage examples
+
+Comments, suggestions, bug reports, etc. are
+welcome!
+
+License
+-------
+
+Pyrex is open source. You may use it, redistribute it, modify
+it and distribute modified versions without restriction.
+
+If you require a more formal license statement, you may use
+Pyrex under the terms of the Apache License Version 2.0, a copy
+of which is included in the file LICENSE.txt.
+
+Updates
+-------
+
+The latest version of Pyrex can be found here:
+
+http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/
+
+Gregory Ewing, Computer Science Dept,
+University of Canterbury,
+Christchurch, New Zealand
+greg.ewing@canterbury.ac.nz
diff --git a/debian/pyrex/pyrex-0.9.9/ToDo.txt b/debian/pyrex/pyrex-0.9.9/ToDo.txt
new file mode 100644
index 00000000..7e03c3f8
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/ToDo.txt
@@ -0,0 +1,164 @@
+Const types.
+
+Tuple/list construction: Evaluate & store items one at a time?
+
+Varargs argument traversal.
+
+Optimise abs() on integer or float.
+
+Optional semicolons after C declarations.
+
+Multiple C declarations on one line?
+
+Optimise return without value outside of try-finally.
+
+exec statement.
+
+Use iterator protocol for unpacking.
+
+In-place operators (+=, etc).
+
+Check for lack of return with value in non-void C functions?
+
+Make C structs callable as constructors.
+
+When calling user __dealloc__ func, save & restore exception.
+
+Complex number parsetuple format?
+
+Provide a way of declaring a C function as returning a
+borrowed Python reference.
+
+Provide a way of declaring a C function as stealing a
+Python reference.
+
+Provide a way of specifying whether a Python object obtained
+by casting a pointer should be treated as a new reference
+or not.
+
+Make sizeof() take types as well as variables.
+
+Allow "unsigned" to be used alone as a type name.
+
+Do something about installing proper version of pyrexc
+script according to platform in setup.py.
+
+Recognise #line directives?
+
+Catch floating point exceptions?
+
+Generate type test when casting from one Python type
+to another.
+
+Allow ranges of exception values.
+
+Support "complex double" and "complex float"?
+
+Allow module-level Python variables to be declared extern.
+
+Consider:
+>cdef extern from "foo.h":
+> int dosomething() except -1 raise MyException
+
+Properties for Python types?
+
+Find a way to make classmethod and staticmethod work better.
+
+Statically initialised C arrays & structs.
+
+Make docstrings of extension type special methods work.
+
+Treat result of getting C attribute of extension type as non-ephemeral.
+
+Teach it about common builtin types.
+
+Option for generating a main() function?
+
+Do something about external C functions declared as returning
+const * types?
+
+Use PyString_FromStringAndSize for string literals? (For efficiency
+and so that they can contain nulls.)
+
+What to do about __name__ etc. attributes of a module (they are
+currently assumed to be built-in names).
+
+Use PyDict_GetItem etc. on module & builtins dicts for speed.
+
+Intern all string literals used as Python strings?
+[Koshy <jkoshy@freebsd.org>]
+
+Disallow a filename which results in an illegal identifier when
+used as a module name.
+
+Provide an easy way of exposing a set of enum values as Python names.
+[John J Lee <jjl@pobox.com>]
+
+Prevent user from returning a value from special methods that
+return an error indicator only.
+
+Allow * in cimport? [John J Lee <jjl@pobox.com>]
+
+Make Python class construction work more like it does in Python.
+
+Give the right module name to Python classes.
+
+Command line switch for full pathnames in backtraces?
+
+Peephole optimisation? [Vladislav Bulatov <vrbulatov@list.ru>]
+
+Avoid PyArg_ParseTuple call when a function takes no positional args.
+
+Can a faster way of instantiating extension types be found?
+
+Use PySequence_GetItem instead of PyObject_GetItem when index
+is an integer.
+
+If a __getitem__ method is declared with an int index, use the
+sq_item slot instead of the mp_subscript slot.
+
+Provide some way of controlling the argument list passed to
+an extension type's base __new__ method?
+[Alain Pointdexter <alainpoint@yahoo.fr>]
+
+Implement a true __new__ for extension types.
+
+Way to provide constructors for extension types that are not
+available to Python and can accept C types directly?
+
+Support generators by turning them into extension types?
+
+List comprehensions.
+
+Variable declarations inside inner code blocks?
+
+Initial values when declaring variables?
+
+Support class methods in extension types using METH_CLASS flag.
+
+Disallow defaulting types to 'object' in C declarations?
+
+C globals with static initialisers.
+
+Find a way of providing C-only initialisers for extension types.
+
+Metaclasses for extension types?
+
+Make extension types use Py_TPFLAGS_HEAPTYPE so their __module__
+will get set dynamically?
+
+Track GIL state.
+
+Private fields of extension types in a separate struct.
+
+Private vtable entries in a separate struct.
+
+Specialised constructors for builtin types.
+
+Special-case integer indexing and slicing.
+
+Allow "extern api".
+
+Lockstep iteration syntax.
+
+True division? Future import?
diff --git a/debian/pyrex/pyrex-0.9.9/Tools/pyrex-mode.el b/debian/pyrex/pyrex-0.9.9/Tools/pyrex-mode.el
new file mode 100644
index 00000000..1493a9d8
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Tools/pyrex-mode.el
@@ -0,0 +1 @@
+;;;; `Pyrex' mode. (add-to-list 'auto-mode-alist '("\\.pyx\\'" . pyrex-mode)) (define-derived-mode pyrex-mode python-mode "Pyrex" (font-lock-add-keywords nil `((,(concat "\\<\\(NULL" "\\|c\\(def\\|har\\|typedef\\)" "\\|e\\(num\\|xtern\\)" "\\|float" "\\|in\\(clude\\|t\\)" "\\|object\\|public\\|struct\\|type\\|union\\|void" "\\)\\>") 1 font-lock-keyword-face t)))) \ No newline at end of file
diff --git a/debian/pyrex/pyrex-0.9.9/Tools/pyrex.st b/debian/pyrex/pyrex-0.9.9/Tools/pyrex.st
new file mode 100644
index 00000000..d4fe4ecf
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/Tools/pyrex.st
@@ -0,0 +1 @@
+/** * Name: pyrex * Description: Pyrex - a Language for Writing Python Extension Modules * Author: Markku Rossi <mtr@iki.fi> */ state pyrex extends python { /* Additional keywords. (build-re '( NULL as cdef char ctypedef double enum extern float include int long private public short signed sizeof struct union unsigned void )) */ /\b(NULL|as|c(def|har|typedef)|double|e(num|xtern)|float|in(clude|t)\ |long|p(rivate|ublic)|s(hort|i(gned|zeof)|truct)|un(ion|signed)|void)\b/ { keyword_face(true); language_print($0); keyword_face(false); } } /* Local variables: mode: c End: */ \ No newline at end of file
diff --git a/debian/pyrex/pyrex-0.9.9/USAGE.txt b/debian/pyrex/pyrex-0.9.9/USAGE.txt
new file mode 100644
index 00000000..3128cd01
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/USAGE.txt
@@ -0,0 +1,69 @@
+Pyrex - Usage Instructions
+==========================
+
+Building Pyrex extensions using distutils
+-----------------------------------------
+
+Pyrex comes with an experimental distutils extension for compiling
+Pyrex modules, contributed by Graham Fawcett of the University of
+Windsor (fawcett@uwindsor.ca).
+
+The Demos directory contains a setup.py file demonstrating its use. To
+compile the demos:
+
+(1) cd Demos
+
+(2) python setup.py build_ext --inplace
+
+ or
+
+ python setup.py build --build-lib=.
+
+(You may get a screed of warnings from the C compiler, but you can
+ignore these -- as long as there are no actual errors, things are
+probably okay.)
+
+Try out the extensions with:
+
+ python run_primes.py
+ python run_spam.py
+ python run_numeric_demo.py
+
+
+Building Pyrex extensions by hand
+---------------------------------
+
+You can also invoke the Pyrex compiler on its own to translate a .pyx
+file to a .c file. On Unix,
+
+ pyrexc filename.pyx
+
+On other platforms,
+
+ python pyrexc.py filename.pyx
+
+It's then up to you to compile and link the .c file using whatever
+procedure is appropriate for your platform. The file
+Makefile.nodistutils in the Demos directory shows how to do this for
+one particular Unix system.
+
+
+Command line options
+--------------------
+
+The pyrexc command supports the following options:
+
+ Short Long Argument Description
+ -----------------------------------------------------------------------------
+ -v --version Display version number of pyrex compiler
+ -l --create-listing Write error messages to a .lis file
+ -I --include-dir <directory> Search for include files in named
+ directory (may be repeated)
+ -o --output-file <filename> Specify name of generated C file (only
+ one source file allowed if this is used)
+
+Anything else is taken as the name of a Pyrex source file and compiled
+to a C source file. Multiple Pyrex source files can be specified
+(unless -o is used), in which case each source file is treated as the
+source of a distinct extension module and compiled separately to
+produce its own C file.
diff --git a/debian/pyrex/pyrex-0.9.9/bin/pyrexc b/debian/pyrex/pyrex-0.9.9/bin/pyrexc
new file mode 100755
index 00000000..b604d4d0
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/bin/pyrexc
@@ -0,0 +1,8 @@
+#!/usr/bin/env python
+
+#
+# Pyrex -- Main Program, Unix
+#
+
+from Pyrex.Compiler.Main import main
+main(command_line = 1)
diff --git a/debian/pyrex/pyrex-0.9.9/bin/pyrexc2.5 b/debian/pyrex/pyrex-0.9.9/bin/pyrexc2.5
new file mode 100755
index 00000000..766631c1
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/bin/pyrexc2.5
@@ -0,0 +1,8 @@
+#!/usr/bin/env python2.5
+
+#
+# Pyrex -- Main Program, Unix
+#
+
+from Pyrex.Compiler.Main import main
+main(command_line = 1)
diff --git a/debian/pyrex/pyrex-0.9.9/bin/pyrexc2.6 b/debian/pyrex/pyrex-0.9.9/bin/pyrexc2.6
new file mode 100755
index 00000000..4c34f547
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/bin/pyrexc2.6
@@ -0,0 +1,8 @@
+#!/usr/bin/env python2.6
+
+#
+# Pyrex -- Main Program, Unix
+#
+
+from Pyrex.Compiler.Main import main
+main(command_line = 1)
diff --git a/debian/pyrex/pyrex-0.9.9/bin/pyxcc b/debian/pyrex/pyrex-0.9.9/bin/pyxcc
new file mode 100755
index 00000000..d1f96df2
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/bin/pyxcc
@@ -0,0 +1,15 @@
+#!/bin/sh
+export MACOSX_DEPLOYMENT_TARGET=10.3
+ver=2.3
+if [ $1 == -p ]; then
+ ver=$2
+ shift 2
+fi
+base=$1
+gcc -g -c -fno-strict-aliasing -Wno-long-double -no-cpp-precomp \
+ -mno-fused-madd -fno-common -dynamic -Wno-long-long \
+ -Wno-unused-function \
+ -I/Library/Frameworks/Python.framework/Versions/$ver/Headers \
+ $base.c
+gcc -Wl,-F.,-w -bundle -undefined dynamic_lookup \
+ $base.o -o $base.so
diff --git a/debian/pyrex/pyrex-0.9.9/bin/run_tests_2.5 b/debian/pyrex/pyrex-0.9.9/bin/run_tests_2.5
new file mode 100755
index 00000000..f478aaa7
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/bin/run_tests_2.5
@@ -0,0 +1,7 @@
+#!/usr/bin/env python2.5
+#
+# runtests -- Run all the tests.
+#
+
+from Pyrex.Testing import Testing
+Testing.run_tests()
diff --git a/debian/pyrex/pyrex-0.9.9/bin/run_tests_2.6 b/debian/pyrex/pyrex-0.9.9/bin/run_tests_2.6
new file mode 100755
index 00000000..3cca59e7
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/bin/run_tests_2.6
@@ -0,0 +1,7 @@
+#!/usr/bin/env python2.6
+#
+# runtests -- Run all the tests.
+#
+
+from Pyrex.Testing import Testing
+Testing.run_tests()
diff --git a/debian/pyrex/pyrex-0.9.9/bin/update_references b/debian/pyrex/pyrex-0.9.9/bin/update_references
new file mode 100755
index 00000000..70277781
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/bin/update_references
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+#
+# Go through the Tests directory and its subdirectories
+# copying the latest versions of the test outputs into
+# the Reference directories.
+#
+
+import os, sys
+
+ignore_names = [".DS_Store", "Icon\r"]
+
+def copy_file(from_path, to_path):
+ # We copy the contents from one file to the other
+ # so as to preserve metadata on the Mac.
+ #print from_path, "-->", to_path
+ f = open(from_path)
+ g = open(to_path, "w+")
+ g.write(f.read())
+ f.close()
+ g.close()
+
+def update_references(out_dir, ref_dir):
+ for name in os.listdir(ref_dir):
+ if name not in ignore_names:
+ out_file = os.path.join(out_dir, name)
+ ref_file = os.path.join(ref_dir, name)
+ if os.path.isfile(out_file):
+ print "Updating", name
+ copy_file(out_file, ref_file)
+
+def update_references_in_dir(dir):
+ print "Updating references in", dir
+ for name in os.listdir(dir):
+ if name <> "Reference" and not name.startswith("("):
+ item_path = os.path.join(dir, name)
+ if os.path.isdir(item_path):
+ update_references_in_dir(item_path)
+ ref_dir = os.path.join(dir, "Reference")
+ if os.path.isdir(ref_dir):
+ update_references(dir, ref_dir)
+
+def main():
+ bin_dir = os.path.dirname(sys.argv[0])
+ source_dir = os.path.dirname(bin_dir)
+ tests_dir = os.path.join(source_dir, "Tests")
+ update_references_in_dir(tests_dir)
+
+if __name__ == "__main__":
+ main()
diff --git a/debian/pyrex/pyrex-0.9.9/debian/changelog b/debian/pyrex/pyrex-0.9.9/debian/changelog
new file mode 100644
index 00000000..9912bac4
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/debian/changelog
@@ -0,0 +1,333 @@
+pyrex (0.9.9-1~0debian11.0.0+0~a) bullseye; urgency=medium
+
+ * Temporarily added to the Trinity repository.
+ * Change python binary to python2 instead of python.
+ * Add python2-dev | python-all-dev as alternatives to python-dev dependency.
+
+ -- Slávek Banko <slavek.banko@axis.cz> Tue, 02 Mar 2021 15:37:49 +0100
+
+pyrex (0.9.9-1) unstable; urgency=medium
+
+ * New upstream release (closes: #582561, #610386)
+ * Bump debian/compat to 7
+ * Acknowledge NMU (Closes: #616980)
+ * debian/compat: bump from 5 to 9
+ * debian/patches: removed, integrated upstream
+ * debian/control: add X-Python-Version, remove dpatch, add dh-python
+ * debian/control: bump Standards-Version to 3.9.8, strip trailing space
+ * debian/rules: update (closes: #668804, #831938), strip trailing spaces
+ * debian/control: add python-dev to depends (closes: #648800)
+ * debian/patches/baseexception.patch: add patch from ubuntu, thanks to
+ Michael Vogt (closes: #604965)
+
+ -- Paul Brossier <piem@debian.org> Thu, 01 Sep 2016 12:04:51 +0200
+
+pyrex (0.9.8.5-2.1) unstable; urgency=low
+
+ * Non-maintainer upload.
+ * Convert to dh_python2. (Closes: #616980)
+
+ -- Andrea Colangelo <warp10@ubuntu.com> Fri, 28 Jun 2013 17:03:29 +0200
+
+pyrex (0.9.8.5-2) unstable; urgency=low
+
+ * Acknowledge NMU (closes: #519951)
+ * Adjust pyrex-mode depends for emacs22 (closes: #485766)
+ * Fix Vcs-* fields (closes: #536808)
+ * Bump Standards-Version to 3.8.3
+
+ -- Paul Brossier <piem@debian.org> Tue, 08 Dec 2009 01:11:36 +0100
+
+pyrex (0.9.8.5-1.1) unstable; urgency=low
+
+ * Non-maintainer upload.
+ * Prepare for the upcoming Python 2.6 transition; thanks to Evan Broder for
+ the report; Closes: #519951
+ - debian/control
+ + tight b-d on python-all-dev to '(>= 2.5.4-1~)'
+ - debian/rules
+ + include python.mk
+ + pass py_setup_install_args to setup.py install
+
+ -- Sandro Tosi <morph@debian.org> Wed, 25 Nov 2009 23:28:41 +0100
+
+pyrex (0.9.8.5-1) unstable; urgency=low
+
+ * New upstream release.
+ * Acknowledge non-maintainer upload (closes: #483035).
+ * Bump Standards-version to 3.8.1
+ * Add ${misc:Depends} for debhelper
+ * Complete debian/copyright
+
+ -- Paul Brossier <piem@debian.org> Thu, 19 Mar 2009 16:11:15 +0100
+
+pyrex (0.9.7.2-0.1) unstable; urgency=high
+
+ * NMU because maintainer is MIA.
+ * New upstream release fixing an integer indexing optimisation problem
+ (0.9.7.1 and 0.9.7.2 contain this fix only, so this is safe for
+ Lenny release) (Closes: #483035).
+
+ -- Marc Dequènes (Duck) <Duck@DuckCorp.org> Fri, 29 Aug 2008 03:00:52 +0200
+
+pyrex (0.9.7-1) unstable; urgency=low
+
+ * New upstream release.
+ * remove dh_python from debian/rules, add XB-Python-Version
+ (closes: #460253)
+ * remove auto-mode-alist from debian/pyrex-mode.el (ubuntu #73904)
+ * add provide to debian/pyrex-mode.el (ubuntu #73903)
+ * debian/control: added Homepage field
+ * debian/rules, debian/control: add dpatch
+ * debian/patches: add hash patch, thanks to Jakub Wilk (closes: #469735)
+ * debian/control: drop Suggests: python-numeric (closes: #478455)
+ * debian/python-pyrex.doc-base: switch to section Programming/Pyrex
+ * debian/control: added fields Vcs-Browser and Vcs-Hg
+ * debian/control: fix typo python -> Python
+
+ -- Paul Brossier <piem@debian.org> Sun, 11 May 2008 16:19:48 +0200
+
+pyrex (0.9.6.4-1) unstable; urgency=low
+
+ * New upstream release (closes:#406025)
+ * Move python-all-dev to Build-Depends since python gets called in
+ debian/rules:clean
+ * Delete empty usr/lib from python-pyrex
+ * Delete blank lines from debian/python-pyrex.doc-base
+ * Remove empty binary-arch target
+ * Bump Standards-Version to 3.7.3
+
+ -- Paul Brossier <piem@debian.org> Fri, 11 Jan 2008 11:50:29 +0100
+
+pyrex (0.9.5.1a-1) unstable; urgency=low
+
+ * New upstream release (closes: #411004)
+ * Provide only ${python:Provides} (closes: #399937)
+ * Drop Conflicts and Replaces against oldstable packages
+ * Bumpep Build-depends on debhelper to 5.0.37.2
+ * Added debian/pycompat, set to 2
+ * Moved DH_COMPAT=5 to debian/compat
+
+ -- Paul Brossier <piem@debian.org> Sat, 21 Apr 2007 15:16:07 +0200
+
+pyrex (0.9.4.1-2) unstable; urgency=low
+
+ * Correct pyrex-mode emacsen-startup script: load python-mode, not
+ python-mode. Add support for .pxi/.pxd extensions (thanks to Lukasz
+ Pankowski, closes: #375861). Avoid loading pyrex-mode when package has
+ been removed but not purged, do not touch load-path.
+ * Move dh_pycentral call right before dh_python.
+
+ -- Paul Brossier <piem@debian.org> Tue, 4 Jul 2006 15:44:27 +0200
+
+pyrex (0.9.4.1-1) unstable; urgency=low
+
+ * New upstream release
+ * Update to new Python policy (closes: #373505)
+
+ -- Paul Brossier <piem@debian.org> Wed, 14 Jun 2006 18:21:15 +0200
+
+pyrex (0.9.4-1) unstable; urgency=low
+
+ * New upstream release
+
+ -- Paul Brossier <piem@debian.org> Thu, 20 Apr 2006 15:54:27 +0200
+
+pyrex (0.9.3.1-2) unstable; urgency=low
+
+ * Add missing gcc 4.0 patch (closes: #343533)
+
+ -- Paul Brossier <piem@debian.org> Mon, 19 Dec 2005 09:01:29 +0000
+
+pyrex (0.9.3.1-1) unstable; urgency=low
+
+ * New upstream release, integrates some of the gcc-4.x changes:
+ - adopted changes in Pyrex/Compiler/Nodes.py
+ - changed casts from PyObject* to void* in Pyrex/Compiler/Code.py
+ - removed Demos/{callback,embed} and Tools as in upstream
+ (closes: #328871)
+ * Keep a copy of pyrex-mode.el to debian/
+ * Added missing emacscen-startup script for pyrex-mode (closes: #337054)
+
+ -- Paul Brossier <piem@debian.org> Sun, 11 Dec 2005 15:45:59 +0000
+
+pyrex (0.9.3-3) unstable; urgency=low
+
+ * Drop python2.2-pyrex
+ * Update copyright file
+ * Bump to new Standards-Version
+
+ -- Paul Brossier <piem@debian.org> Wed, 13 Jul 2005 17:48:17 +0100
+
+pyrex (0.9.3-2) unstable; urgency=low
+
+ * Added python2.4-pyrex (closes: #292257)
+ * Patch to get friendlier code for gcc 4.0 (closes: #298084)
+ Author is Jeremy Katz, sent to pyrex ML via John (J5) Palmieri
+ * Also add additional patch from Martijn Faassen
+ * Fix swig_sources function in Pyrex/Distutils for python2.4
+ * Correct the email in previous changelog entry 0.9.2.1-4
+ * Move pyrexc link to python-pyrex
+ * Remove Guenter from the uploaders (thanks for the uploads)
+
+ -- Paul Brossier <piem@debian.org> Tue, 21 Jun 2005 20:02:11 +0100
+
+pyrex (0.9.3-1) unstable; urgency=low
+
+ * New upstream release
+ * Created watch file and pyrex-mode package
+ * Removed long unsigned patch (fixed upstream)
+ * Removed DH_VERBOSE mode, debug and nostrip opts in rules
+
+ -- Paul Brossier <piem@altern.org> Thu, 12 Aug 2004 13:08:21 +0200
+
+pyrex (0.9.2.1-4) unstable; urgency=low
+
+ * Fixed python Build-Depends: for amd64 (closes: #255603)
+
+ -- Paul Brossier <piem@altern.org> Mon, 28 Jun 2004 12:01:14 +0100
+
+pyrex (0.9.2.1-3) unstable; urgency=low
+
+ * Fixed patch (closes: #251572, #255279)
+ * Fixed override disparity (now in section python)
+
+ -- Paul Brossier <piem@altern.org> Mon, 21 Jun 2004 11:31:58 +0100
+
+pyrex (0.9.2.1-2) unstable; urgency=low
+
+ * Really includes a patch for dbus now (closes: #251572)
+ * Bump debian-policy to 3.6.1.0
+
+ -- Paul Brossier <piem@altern.org> Wed, 16 Jun 2004 15:55:44 +0100
+
+pyrex (0.9.2.1-1) unstable; urgency=low
+
+ * New upstream release (closes: #252819)
+ * Fixes namespace collision (closes: #233596)
+ * Added lamont patch (closes: #249881)
+ * Clean *.pyc to allow recompile
+
+ -- Paul Brossier <piem@altern.org> Wed, 9 Jun 2004 12:16:04 +0100
+
+pyrex (0.9.0-4) unstable; urgency=low
+
+ * Fixed upstream archive (permissions set to -x, removed .DS_Store garbage).
+ * Added missing cheesfinder.c as found in 0.7.2 release (closes: #232655).
+ * Corrected Makefile* in Demos.
+ * Added Tools in doc (enscript and emacs style files)
+
+ -- Paul Brossier <piem@altern.org> Wed, 18 Feb 2004 03:13:59 +0000
+
+pyrex (0.9.0-3) unstable; urgency=low
+
+ * Fixed debian/rules clean (Gregor Hoffleit)
+
+ -- Paul Brossier <piem@altern.org> Fri, 30 Jan 2004 01:05:20 +0000
+
+pyrex (0.9.0-2) unstable; urgency=low
+
+ * chmod -x on Pyrex/Compiler/Lexicon.pickle and some other files
+ * fixed carriage return Changes.txt and ToDo.txt (s/\r/\r/g)
+
+ -- Paul Brossier <piem@altern.org> Sat, 10 Jan 2004 17:02:43 +0000
+
+pyrex (0.9.0-1) unstable; urgency=low
+
+ * New upstream release.
+
+ -- Paul Brossier <piem@altern.org> Sat, 15 Nov 2003 11:51:47 +0000
+
+pyrex (0.8.2-5) unstable; urgency=low
+
+ * Fixed Doc problem in python2.3-pyrex
+ * Added 2.2 2.3 diversions for /usr/bin/pyrexc
+
+ -- Paul Brossier <piem@altern.org> Mon, 22 Sep 2003 19:52:39 +0100
+
+pyrex (0.8.2-4) unstable; urgency=low
+
+ * Added virtual package python-pyrex
+ * Added compilation for python2.2
+ * Removed dirs file
+
+ -- Paul Brossier <piem@altern.org> Tue, 16 Sep 2003 02:46:40 +0100
+
+pyrex (0.8.2-3) unstable; urgency=low
+
+ * Fixed compilation warning at postinst in Plex/Transitions.py
+ * Header corrected to #!/urs/bin/python2.3 in pyrexc
+ * Fixed wrong placement of dh_python in debian/rules
+ * Removed Replaces: pyrex in control file
+ * Removed redundant Build-Depends-Indep on python
+ * Removed obsolete /usr/share/doc/pyrex in dirs
+
+ -- Paul Brossier <piem@altern.org> Tue, 16 Sep 2003 01:06:09 +0100
+
+pyrex (0.8.2-2) unstable; urgency=low
+
+ * Renamed binary from pyrex to python2.3-pyrex
+ * Added Replaces: pyrex
+ * Added missing changelog entries
+ * Added build dependancie to python2.3-dev
+ * Corrected dependancies to use dh_python
+ * Updated rules to use distutil and dh_python
+ * Removed old prerm to let dh_python handle it
+ * Specify manpage in debian/rules
+
+ -- Paul Brossier <piem@altern.org> Sat, 13 Sep 2003 11:39:51 +0100
+
+pyrex (0.8.2-1) unstable; urgency=low
+
+ * New upstream release
+ * Fixed broken distutils
+ * Removed obsolote README.Debian
+ * Updated maintainer
+
+ -- Paul Brossier <piem@altern.org> Wed, 3 Sep 2003 12:26:29 +0100
+
+pyrex (0.8.1-1) unstable; urgency=low
+
+ * New upstream release
+
+ -- Paul Brossier <piem@altern.org> Mon, 30 Jun 2003 17:05:37 +0100
+
+pyrex (0.7.2-1) unstable; urgency=low
+
+ * New upstream release
+ * Renamed my version of setup.py in the Demos directory to setup_all.py
+
+ -- Peter Harris <scav@blueyonder.co.uk> Thu, 24 Apr 2003 10:03:55 +0100
+
+pyrex (0.7-1) unstable; urgency=low
+
+ * New upstream release
+
+ -- Peter Harris <scav@blueyonder.co.uk> Thu, 10 Apr 2003 22:28:34 +0100
+
+pyrex (0.6.1-2) unstable; urgency=low
+
+ * Added Makefile.debian in Demos directory, uses python2.2 explicitly.
+
+ * Changed setup.py in demos directory to be an example of a setup.py that
+ builds all .pyx files in current directory.
+
+ -- Peter Harris <scav@blueyonder.co.uk> Wed, 9 Apr 2003 23:01:13 +0100
+
+pyrex (0.6.1-1) unstable; urgency=low
+
+ * New upstream release
+
+ -- Peter Harris <scav@blueyonder.co.uk> Fri, 4 Apr 2003 21:54:54 +0100
+
+pyrex (0.5-1) unstable; urgency=low
+
+ * 0.5-1
+ Upstream bug-fix release
+
+ * Initial Release.
+ Makefiles in Demos directory changed to refer explicitly to python2.2
+ where it is expected to be installed on Debian.
+
+ -- Peter Harris <scav@blueyonder.co.uk> Fri, 06 Dec 2002 16:30:00 +0000
+
diff --git a/debian/pyrex/pyrex-0.9.9/debian/compat b/debian/pyrex/pyrex-0.9.9/debian/compat
new file mode 100644
index 00000000..ec635144
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/debian/compat
@@ -0,0 +1 @@
+9
diff --git a/debian/pyrex/pyrex-0.9.9/debian/control b/debian/pyrex/pyrex-0.9.9/debian/control
new file mode 100644
index 00000000..f8d6cdd6
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/debian/control
@@ -0,0 +1,35 @@
+Source: pyrex
+Section: deps-r14/python
+Priority: optional
+Maintainer: Paul Brossier <piem@debian.org>
+Build-Depends: debhelper (>= 5.0.37.2),
+ python-all-dev (>= 2.6.6-3~),
+ dh-python
+Standards-Version: 3.9.8
+Homepage: http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/
+Vcs-Bzr: http://bzr.debian.org/users/piem/pyrex/
+Vcs-Browser: http://bzr.debian.org/loggerhead/users/piem/pyrex/
+X-Python-Version: 2.7
+
+Package: python-pyrex
+Architecture: all
+Depends: ${python:Depends}, ${misc:Depends}, python-dev | python2-dev | python-all-dev
+Provides: ${python:Provides}
+Recommends: python-all-dev
+Description: compile native-code modules for Python from Python-like syntax
+ Pyrex lets you write code that mixes Python and C data types any way you want,
+ and compiles it into a C extension for Python.
+ .
+ You can get very large speedups for tasks that don't need all the dynamic
+ features of Python, with very small differences in syntax and much less
+ hassle than writing your modules from scratch in C.
+
+Package: pyrex-mode
+Architecture: all
+Depends: python-mode | emacs22, ${misc:Depends}
+Description: emacs-lisp pyrex-mode for pyrex
+ Pyrex lets you write code that mixes Python and C data types any way you want,
+ and compiles it into a C extension for Python.
+ .
+ This Emacs mode is derived from the Python language mode, python-mode,
+ and provides syntax highlighting for Pyrex scripts.
diff --git a/debian/pyrex/pyrex-0.9.9/debian/copyright b/debian/pyrex/pyrex-0.9.9/debian/copyright
new file mode 100644
index 00000000..a83507e1
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/debian/copyright
@@ -0,0 +1,44 @@
+This package was first debianized by Peter Harris <scav@blueyonder.co.uk> on
+Tue, 26 Nov 2002 11:08:39 +0000.
+
+It is now maintained by Paul Brossier <piem@debian.org>
+
+This version was downloaded from
+ http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/
+
+Upstream Author: Greg Ewing <greg@cosc.canterbury.ac.nz>
+
+Copyright:
+
+ Copyright 2004-2009 greg@cosc.canterbury.ac.nz
+
+ Pyrex is free of restrictions. You can use, redistribute or modify it however
+ you want.
+
+ Greg Ewing, Computer Science Dept,
+ University of Canterbury,
+ Christchurch, New Zealand
+
+Except for the file Pyrex/Mac/macglue.h:
+
+Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
+The Netherlands.
+
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
diff --git a/debian/pyrex/pyrex-0.9.9/debian/patches/baseexception.patch b/debian/pyrex/pyrex-0.9.9/debian/patches/baseexception.patch
new file mode 100644
index 00000000..bdd78218
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/debian/patches/baseexception.patch
@@ -0,0 +1,24 @@
+--- pyrex-0.9.8.5~/Pyrex/Plex/Errors.py 2003-07-08 18:35:31.000000000 +1000
++++ pyrex-0.9.8.5/Pyrex/Plex/Errors.py 2009-05-24 00:53:54.000000000 +1000
+@@ -9,7 +9,7 @@
+ import exceptions
+
+ class PlexError(exceptions.Exception):
+- message = ""
++ pass
+
+ class PlexTypeError(PlexError, TypeError):
+ pass
+@@ -29,10 +29,10 @@
+ pass
+
+ class AmbiguousAction(PlexError):
+- message = "Two tokens with different actions can match the same string"
+
+ def __init__(self):
+- pass
++ PlexError.__init__(self, "Two tokens with different actions can match the same string")
++
+
+ class UnrecognizedInput(PlexError):
+ scanner = None
diff --git a/debian/pyrex/pyrex-0.9.9/debian/patches/series b/debian/pyrex/pyrex-0.9.9/debian/patches/series
new file mode 100644
index 00000000..966a41d0
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/debian/patches/series
@@ -0,0 +1 @@
+baseexception.patch
diff --git a/debian/pyrex/pyrex-0.9.9/debian/pyrex-mode.el b/debian/pyrex/pyrex-0.9.9/debian/pyrex-mode.el
new file mode 100644
index 00000000..8e7e7e52
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/debian/pyrex-mode.el
@@ -0,0 +1,15 @@
+;;;; `Pyrex' mode.
+
+(provide 'pyrex-mode)
+
+(define-derived-mode pyrex-mode python-mode "Pyrex"
+ (font-lock-add-keywords
+ nil
+ `((,(concat "\\<\\(NULL"
+ "\\|c\\(def\\|har\\|typedef\\)"
+ "\\|e\\(num\\|xtern\\)"
+ "\\|float"
+ "\\|in\\(clude\\|t\\)"
+ "\\|object\\|public\\|struct\\|type\\|union\\|void"
+ "\\)\\>")
+ 1 font-lock-keyword-face t))))
diff --git a/debian/pyrex/pyrex-0.9.9/debian/pyrex-mode.emacsen-startup b/debian/pyrex/pyrex-0.9.9/debian/pyrex-mode.emacsen-startup
new file mode 100644
index 00000000..6e99af87
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/debian/pyrex-mode.emacsen-startup
@@ -0,0 +1,23 @@
+;; -*-emacs-lisp-*-
+;;
+;; Emacs startup file, e.g. /etc/emacs/site-start.d/50pyrex-mode.el
+;; for the Debian pyrex-mode package
+;;
+;; The pyrex-mode package follows the Debian/GNU Linux 'emacsen' policy and
+;; byte-compiles its elisp files for each 'emacs flavor' (emacs19,
+;; xemacs19, emacs20, xemacs20...). The compiled code is then installed
+;; in a subdirectory of the respective site-lisp directory.
+
+;; If package-dir does not exist, the pyrex-mode package must have
+;; been removed but not purged, and we should skip the setup.
+(if (not (file-exists-p "/usr/share/emacs/site-lisp/pyrex-mode.el"))
+ (message "Package pyrex-mode removed but not purged. Skipping setup")
+
+;; Otherwise, autoload the pyrex-mode for the following extensions
+ (autoload 'pyrex-mode "pyrex-mode" "Pyrex editing mode." t)
+ (add-to-list 'auto-mode-alist '("\\.pyx$" . pyrex-mode))
+ (add-to-list 'auto-mode-alist '("\\.pxd$" . pyrex-mode))
+ (add-to-list 'auto-mode-alist '("\\.pxi$" . pyrex-mode))
+
+;; endif
+)
diff --git a/debian/pyrex/pyrex-0.9.9/debian/pyrex-mode.install b/debian/pyrex/pyrex-0.9.9/debian/pyrex-mode.install
new file mode 100644
index 00000000..8f517711
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/debian/pyrex-mode.install
@@ -0,0 +1 @@
+debian/pyrex-mode.el usr/share/emacs/site-lisp
diff --git a/debian/pyrex/pyrex-0.9.9/debian/pyrexc.1 b/debian/pyrex/pyrex-0.9.9/debian/pyrexc.1
new file mode 100644
index 00000000..e3d2bce2
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/debian/pyrexc.1
@@ -0,0 +1,43 @@
+.\" Hey, EMACS: -*- nroff -*-
+.\" First parameter, NAME, should be all caps
+.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
+.\" other parameters are allowed: see man(7), man(1)
+.TH PYREXC 1 "November 26, 2002"
+.\" Please adjust this date whenever revising the manpage.
+.\"
+.\" Some roff macros, for reference:
+.\" .nh disable hyphenation
+.\" .hy enable hyphenation
+.\" .ad l left justify
+.\" .ad b justify to both left and right margins
+.\" .nf disable filling
+.\" .fi enable filling
+.\" .br insert line break
+.\" .sp <n> insert n+1 empty lines
+.\" for manpage-specific macros, see man(7)
+.SH NAME
+pyrexc \- compile python-like .pyx file to C for use as python module
+.SH SYNOPSIS
+.B pyrexc
+.RI " files" ...
+.SH DESCRIPTION
+This manual page documents briefly the
+.B pyrexc
+command.
+This manual page was written for the Debian distribution
+because the original program does not have a manual page.
+.PP
+.\" TeX users may be more comfortable with the \fB<whatever>\fP and
+.\" \fI<whatever>\fP escape sequences to invode bold face and italics,
+.\" respectively.
+\fBpyrexc\fP is a python script that converts a .pyx file to C, so it can
+be compiled for use as a Python module.
+.PP
+You then need to compile the .c file along with the include files for
+Python, and link it into a shared library.
+.PP
+The HTML documentation explains this better, and the Demo examples show how
+to automate the compile and link stages more easily.
+.SH AUTHOR
+This manual page was written by Peter Harris <scav@blueyonder.co.uk>,
+for the Debian GNU/Linux system (but may be used by others).
diff --git a/debian/pyrex/pyrex-0.9.9/debian/python-pyrex.doc-base b/debian/pyrex/pyrex-0.9.9/debian/python-pyrex.doc-base
new file mode 100644
index 00000000..1108bd7e
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/debian/python-pyrex.doc-base
@@ -0,0 +1,10 @@
+Document: python-pyrex
+Title: Debian pyrex Manual
+Author: various
+Abstract: These HTML pages describes what pyrex is
+ and how it can be used.
+Section: Programming/Python
+
+Format: HTML
+Index: /usr/share/doc/python-pyrex/Doc/index.html
+Files: /usr/share/doc/python-pyrex/Doc/*.html
diff --git a/debian/pyrex/pyrex-0.9.9/debian/python-pyrex.docs b/debian/pyrex/pyrex-0.9.9/debian/python-pyrex.docs
new file mode 100644
index 00000000..2e07141f
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/debian/python-pyrex.docs
@@ -0,0 +1,5 @@
+README.txt
+ToDo.txt
+USAGE.txt
+Doc
+Demos
diff --git a/debian/pyrex/pyrex-0.9.9/debian/pythonX.Y-pyrexc b/debian/pyrex/pyrex-0.9.9/debian/pythonX.Y-pyrexc
new file mode 100644
index 00000000..3e03581c
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/debian/pythonX.Y-pyrexc
@@ -0,0 +1,7 @@
+#! /bin/sh
+if which python#VERS# > /dev/null; then
+ exec python#VERS# -c 'from Pyrex.Compiler.Main import main; main(command_line = 1)' $*
+else
+ echo python#VERS# not found
+ exit 1
+fi
diff --git a/debian/pyrex/pyrex-0.9.9/debian/rules b/debian/pyrex/pyrex-0.9.9/debian/rules
new file mode 100755
index 00000000..b1aa9787
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/debian/rules
@@ -0,0 +1,93 @@
+#!/usr/bin/make -f
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+include /usr/share/python/python.mk
+
+PYTHON := /usr/bin/python2
+PYVERS := $(shell pyversions -vr debian/control)
+PYVER := $(shell python -c 'import sys; print sys.version[:3]')
+PYREXC=pyrexc
+
+post-patches:
+ # make sure that python binary exists
+ # since the existing code is still dependent on python2
+ # and cdbs uses python as the default binary name
+ test -x /usr/bin/python || ln -s python2 /usr/bin/python
+
+configure: configure-stamp
+configure-stamp:
+ dh_testdir
+ # nothing to do
+ touch configure-stamp
+
+build-arch: build
+build-indep: build
+
+build: build-stamp
+build-stamp: configure-stamp
+ # make sure most files are not executable
+ find [DPTCs]* -type f -exec chmod -x {} \;
+ dh_testdir
+ # nothing to do
+ touch build-stamp
+
+clean: clean1st
+clean1st:
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp configure-stamp
+
+ $(PYTHON) setup.py clean --all ;\
+ # delete *.pyc generated by setup.py
+ find . -name '*.pyc' -exec rm -rf {} \;
+ rm -f build-stamp
+
+ dh_clean
+
+install: build
+ dh_testdir
+ dh_testroot
+ dh_prep
+ dh_installdirs
+
+ # fix executable file : headers, names
+ # $$file -> python$$version-$$file
+ $(PYTHON) setup.py install --root=$(CURDIR)/debian/python-pyrex --no-compile $(py_setup_install_args)
+ for python in $(PYVERS); do \
+ sed 's/#VERS#/'$$python'/g' debian/pythonX.Y-pyrexc > debian/python-pyrex/usr/bin/python$$python-pyrexc ; \
+ chmod 755 debian/python-pyrex/usr/bin/python$$python-pyrexc ; \
+ done
+ dh_install -p pyrex-mode
+
+binary-arch:
+
+binary-indep: build install
+ dh_testdir
+ dh_testroot
+ dh_installdebconf
+ dh_installchangelogs CHANGES.txt
+ dh_installdocs
+ dh_installemacsen
+ dh_installexamples
+ dh_installman debian/pyrexc.1
+ # default version link for binary and manpage
+ for python in $(PYVERS); \
+ do dh_link -ppython-pyrex \
+ usr/share/man/man1/$(PYREXC).1.gz \
+ usr/share/man/man1/python$$python-$(PYREXC).1.gz ;\
+ done
+ dh_strip
+ dh_compress
+ dh_fixperms
+ dh_python2
+ dh_installdeb
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+binary: binary-arch binary-indep
+
+.PHONY: build clean binary-indep binary-arch binary install configure clean1st
diff --git a/debian/pyrex/pyrex-0.9.9/debian/source/format b/debian/pyrex/pyrex-0.9.9/debian/source/format
new file mode 100644
index 00000000..163aaf8d
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/debian/pyrex/pyrex-0.9.9/debian/source/options b/debian/pyrex/pyrex-0.9.9/debian/source/options
new file mode 100644
index 00000000..d71748bb
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/debian/source/options
@@ -0,0 +1,3 @@
+# Use xz instead of gzip
+compression = "xz"
+compression-level = 9
diff --git a/debian/pyrex/pyrex-0.9.9/debian/watch b/debian/pyrex/pyrex-0.9.9/debian/watch
new file mode 100644
index 00000000..1c69e923
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/debian/watch
@@ -0,0 +1,2 @@
+version=2
+http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/ Pyrex-([0-9\.]*)\.tar\.gz
diff --git a/debian/pyrex/pyrex-0.9.9/hgignore b/debian/pyrex/pyrex-0.9.9/hgignore
new file mode 100644
index 00000000..b081da6a
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/hgignore
@@ -0,0 +1,10 @@
+glob:*.pyc
+glob:*.o
+glob:*.so
+glob:.DS_Store
+glob:*.pickle
+glob:*.dep
+glob:*.orig
+glob:*.new
+glob:*_copy.c
+tags
diff --git a/debian/pyrex/pyrex-0.9.9/pyrexc.py b/debian/pyrex/pyrex-0.9.9/pyrexc.py
new file mode 100755
index 00000000..f32cf153
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/pyrexc.py
@@ -0,0 +1,6 @@
+#
+# Pyrex -- Main Program, generic
+#
+
+from Pyrex.Compiler.Main import main
+main(command_line = 1)
diff --git a/debian/pyrex/pyrex-0.9.9/setup.py b/debian/pyrex/pyrex-0.9.9/setup.py
new file mode 100644
index 00000000..a6ea6945
--- /dev/null
+++ b/debian/pyrex/pyrex-0.9.9/setup.py
@@ -0,0 +1,48 @@
+#
+# Pyrex setup file
+#
+
+import distutils
+from distutils.core import setup
+from distutils.sysconfig import get_python_lib
+import os, sys
+execfile(distutils.util.convert_path('Pyrex/Compiler/Version.py'))
+
+compiler_dir = os.path.join(get_python_lib(prefix=''), 'Pyrex', 'Compiler')
+
+# Workaround for problem with distutils wininst
+if sys.platform == "win32" and 'bdist_wininst' in sys.argv:
+ compiler_dir = compiler_dir[len(sys.prefix)+1:]
+
+
+def packages():
+ result = []
+ def find_packages(dir, parent_names):
+ for name in os.listdir(dir):
+ subdir = os.path.join(dir, name)
+ if os.path.isdir(subdir) and os.path.exists(os.path.join(subdir, "__init__.py")):
+ pkg_names = parent_names + [name]
+ result.append(".".join(pkg_names))
+ find_packages(subdir, pkg_names)
+ source_dir = os.path.dirname(__file__) or os.curdir
+ find_packages(source_dir, [])
+ return result
+
+def scripts():
+ if os.name == "posix":
+ return ["bin/pyrexc"]
+ else:
+ return ["pyrexc.py"]
+
+setup(
+ name = 'Pyrex',
+ version = version,
+ url = 'http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/',
+ author = 'Greg Ewing',
+ author_email = 'greg.ewing@canterbury.ac.nz',
+ scripts = scripts(),
+ packages = packages(),
+ data_files=[
+ (compiler_dir, ['Pyrex/Compiler/Lexicon.pickle'])
+ ]
+)
diff --git a/debian/pyrex/pyrex_0.9.9.orig.tar.gz b/debian/pyrex/pyrex_0.9.9.orig.tar.gz
new file mode 100644
index 00000000..0d712a9c
--- /dev/null
+++ b/debian/pyrex/pyrex_0.9.9.orig.tar.gz
Binary files differ