diff -Nru cython-0.10.3/bin/cython.bat cython-0.11.2/bin/cython.bat --- cython-0.10.3/bin/cython.bat 1970-01-01 01:00:00.000000000 +0100 +++ cython-0.11.2/bin/cython.bat 2009-05-20 16:37:46.000000000 +0100 @@ -0,0 +1,6 @@ +@REM Start cython from windows commandline as "cython", not "cython.py". +@REM This is especially useful for windows power shell, as no extra window +@REM is used. + +@echo OFF +python -c "from Cython.Compiler.Main import main; main(command_line = 1)" %* diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/CHANGES_pyrex.txt /tmp/bvXOgNtCTr/cython-0.11.2/CHANGES_pyrex.txt --- cython-0.10.3/CHANGES_pyrex.txt 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/CHANGES_pyrex.txt 1970-01-01 01:00:00.000000000 +0100 @@ -1,1179 +0,0 @@ -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. C++ functions still cannot - be called yet. - - - 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 http://www.iro.umontreal.ca/~pinard] - - - Return statement without value wasn't accepted in some - extension type special methods when it should have been. - [Francois Pinard http://www.iro.umontreal.ca/~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@daimlerchrysler.com] - - - __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@club-internet.fr] - -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@club-internet.fr] - - - __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. - [fawcett@uwindsor.ca] - -0.3.3 ------ - -Bug fixes: - -* A void * can be assigned from any other -pointer type. -[piers@cs.su.oz.au] - -* File names in error messages no longer -quoted (this was apparently confusing some -editors). -[donut@azstarnet.com] - -* Reference to a struct member which is an -array is coerced to a pointer. -[donut@azstarnet.com] - -* Default argument values did not work -in methods of an extension type. -[donut@azstarnet.com] - -* Single or double quote characters in a -triple-quoted string didn't work. -[donut@azstarnet.com] - -* Using *args in a function definition -sometimes caused a crash at runtime. -[donut@azstarnet.com] - -* 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. -[baas@ira.uka.de] - - -0.3.2 ------ - -Bug fixes: - -* The & operator works again. -[matthias.oberlaender@daimlerchrysler.com] -[baas@ira.uka.de] - -* The & operator had incorrect precedence. - -* "SystemError: 'finally' pops bad exception" -under some circumstances when raising an -exception. [baas@ira.uka.de] - -* Calling a Python function sometimes leaked -a reference. - -* Crash under some circumstances when casting -a Python object reference to a C pointer type. -[mpj17@cosc.canterbury.ac.nz] - -* Crash when redeclaring a function. -[baas@ira.uka.de] - -* Crash when using a string constant inside -a Python class definition. -[mike@bindkey.com] - -* 2-element slice indexing expressions. -[mike@bindkey.com] - -* Crash when encountering mixed tabs and -spaces. -[mike@bindkey.com] - -New features: - -* A wider variety of constant expressions is -now accepted for enum values, array -dimensions, etc. -[mike@bindkey.com] - - -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 -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/Annotate.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/Annotate.py --- cython-0.10.3/Cython/Compiler/Annotate.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/Annotate.py 2009-05-20 16:37:46.000000000 +0100 @@ -170,7 +170,7 @@ return raw_string -class AnnotationItem: +class AnnotationItem(object): def __init__(self, style, text, tag="", size=0): self.style = style diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/AutoDocTransforms.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/AutoDocTransforms.py --- cython-0.10.3/Cython/Compiler/AutoDocTransforms.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/AutoDocTransforms.py 2009-05-20 16:37:46.000000000 +0100 @@ -13,6 +13,7 @@ super(EmbedSignature, self).__init__(context) self.denv = None # XXX self.class_name = None + self.class_node = None def _fmt_arg_defv(self, arg): if not arg.default: @@ -20,7 +21,7 @@ try: denv = self.denv # XXX ctval = arg.default.compile_time_value(self.denv) - return '%s' % ctval + return '%r' % ctval except Exception: try: return arg.default.name # XXX @@ -40,11 +41,13 @@ def _fmt_arglist(self, args, npargs=0, pargs=None, - nkargs=0, kargs=None): + nkargs=0, kargs=None, + hide_self=False): arglist = [] for arg in args: - arg_doc = self._fmt_arg(arg) - arglist.append(arg_doc) + if not hide_self or not arg.entry.is_self_arg: + arg_doc = self._fmt_arg(arg) + arglist.append(arg_doc) if pargs: arglist.insert(npargs, '*%s' % pargs.name) elif nkargs: @@ -62,10 +65,11 @@ def _fmt_signature(self, cls_name, func_name, args, npargs=0, pargs=None, nkargs=0, kargs=None, - return_type=None): + return_type=None, hide_self=False): arglist = self._fmt_arglist(args, npargs, pargs, - nkargs, kargs) + nkargs, kargs, + hide_self=hide_self) arglist_doc = ', '.join(arglist) func_doc = '%s(%s)' % (func_name, arglist_doc) if cls_name: @@ -91,6 +95,8 @@ def visit_ClassDefNode(self, node): oldname = self.class_name + oldclass = self.class_node + self.class_node = node try: # PyClassDefNode self.class_name = node.name @@ -99,32 +105,67 @@ self.class_name = node.class_name self.visitchildren(node) self.class_name = oldname + self.class_node = oldclass return node - def visit_FuncDefNode(self, node): + def visit_DefNode(self, node): if not self.current_directives['embedsignature']: return node - signature = None - if type(node) is DefNode: # def FOO(...): - if not node.entry.is_special: - nkargs = getattr(node, 'num_kwonly_args', 0) - npargs = len(node.args) - nkargs - signature = self._fmt_signature( - self.class_name, node.name, node.args, - npargs, node.star_arg, - nkargs, node.starstar_arg, - return_type=None) - elif type(node) is CFuncDefNode: - if node.overridable: # cpdef FOO(...): - signature = self._fmt_signature( - self.class_name, node.declarator.base.name, - node.declarator.args, - return_type=node.return_type) - else: # should not fall here ... - assert False + is_constructor = False + hide_self = False + if node.entry.is_special: + is_constructor = self.class_node and node.name == '__init__' + if not is_constructor: + return node + class_name, func_name = None, self.class_name + hide_self = True + else: + class_name, func_name = self.class_name, node.name + + nkargs = getattr(node, 'num_kwonly_args', 0) + npargs = len(node.args) - nkargs + signature = self._fmt_signature( + class_name, func_name, node.args, + npargs, node.star_arg, + nkargs, node.starstar_arg, + return_type=None, hide_self=hide_self) + if signature: + if is_constructor: + doc_holder = self.class_node.entry.type.scope + else: + doc_holder = node.entry + + if doc_holder.doc is not None: + old_doc = doc_holder.doc + elif not is_constructor and getattr(node, 'py_func', None) is not None: + old_doc = node.py_func.entry.doc + else: + old_doc = None + new_doc = self._embed_signature(signature, old_doc) + doc_holder.doc = EncodedString(new_doc) + if not is_constructor and getattr(node, 'py_func', None) is not None: + node.py_func.entry.doc = EncodedString(new_doc) + return node + + def visit_CFuncDefNode(self, node): + if not self.current_directives['embedsignature']: + return node + if not node.overridable: # not cpdef FOO(...): + return node + + signature = self._fmt_signature( + self.class_name, node.declarator.base.name, + node.declarator.args, + return_type=node.return_type) if signature: - new_doc = self._embed_signature(signature, node.entry.doc) + if node.entry.doc is not None: + old_doc = node.entry.doc + elif getattr(node, 'py_func', None) is not None: + old_doc = node.py_func.entry.doc + else: + old_doc = None + new_doc = self._embed_signature(signature, old_doc) node.entry.doc = EncodedString(new_doc) if hasattr(node, 'py_func') and node.py_func is not None: node.py_func.entry.doc = EncodedString(new_doc) diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/Buffer.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/Buffer.py --- cython-0.10.3/Cython/Compiler/Buffer.py 2008-12-17 08:56:17.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/Buffer.py 2009-05-20 16:37:46.000000000 +0100 @@ -15,12 +15,6 @@ import textwrap -# Code cleanup ideas: -# - One could be more smart about casting in some places -# - Start using CCodeWriters to generate utility functions -# - Create a struct type per ndim rather than keeping loose local vars - - def dedent(text, reindent=0): text = textwrap.dedent(text) if reindent > 0: @@ -240,29 +234,32 @@ def put_acquire_arg_buffer(entry, code, pos): code.globalstate.use_utility_code(acquire_utility_code) buffer_aux = entry.buffer_aux - getbuffer_cname = get_getbuffer_code(entry.type.dtype, code) + getbuffer = get_getbuffer_call(code, entry.cname, buffer_aux, entry.type) # Acquire any new buffer - code.putln(code.error_goto_if("%s((PyObject*)%s, &%s, %s, %d, %d) == -1" % ( - getbuffer_cname, - entry.cname, - entry.buffer_aux.buffer_info_var.cname, - get_flags(buffer_aux, entry.type), - entry.type.ndim, - int(entry.type.cast)), pos)) + code.putln("{") + code.putln("__Pyx_BufFmt_StackElem __pyx_stack[%d];" % entry.type.dtype.struct_nesting_depth()) + code.putln(code.error_goto_if("%s == -1" % getbuffer, pos)) + code.putln("}") # An exception raised in arg parsing cannot be catched, so no # need to care about the buffer then. put_unpack_buffer_aux_into_scope(buffer_aux, entry.type.mode, code) -#def put_release_buffer_normal(entry, code): -# code.putln("if (%s != Py_None) PyObject_ReleaseBuffer(%s, &%s);" % ( -# entry.cname, -# entry.cname, -# entry.buffer_aux.buffer_info_var.cname)) - def get_release_buffer_code(entry): return "__Pyx_SafeReleaseBuffer(&%s)" % entry.buffer_aux.buffer_info_var.cname +def get_getbuffer_call(code, obj_cname, buffer_aux, buffer_type): + ndim = buffer_type.ndim + cast = int(buffer_type.cast) + flags = get_flags(buffer_aux, buffer_type) + bufstruct = buffer_aux.buffer_info_var.cname + + dtype_typeinfo = get_type_information_cname(code, buffer_type.dtype) + + return ("__Pyx_GetBufferAndValidate(&%(bufstruct)s, " + "(PyObject*)%(obj_cname)s, &%(dtype_typeinfo)s, %(flags)s, %(ndim)d, " + "%(cast)d, __pyx_stack)" % locals()) + def put_assign_to_buffer(lhs_cname, rhs_cname, buffer_aux, buffer_type, is_initialized, pos, code): """ @@ -283,40 +280,36 @@ bufstruct = buffer_aux.buffer_info_var.cname flags = get_flags(buffer_aux, buffer_type) - getbuffer = "%s((PyObject*)%%s, &%s, %s, %d, %d)" % (get_getbuffer_code(buffer_type.dtype, code), - # note: object is filled in later (%%s) - bufstruct, - flags, - buffer_type.ndim, - int(buffer_type.cast)) + code.putln("{") # Set up necesarry stack for getbuffer + code.putln("__Pyx_BufFmt_StackElem __pyx_stack[%d];" % buffer_type.dtype.struct_nesting_depth()) + + getbuffer = get_getbuffer_call(code, "%s", buffer_aux, buffer_type) # fill in object below if is_initialized: # Release any existing buffer code.putln('__Pyx_SafeReleaseBuffer(&%s);' % bufstruct) # Acquire - retcode_cname = code.funcstate.allocate_temp(PyrexTypes.c_int_type) + retcode_cname = code.funcstate.allocate_temp(PyrexTypes.c_int_type, manage_ref=False) code.putln("%s = %s;" % (retcode_cname, getbuffer % rhs_cname)) - code.putln('if (%s) ' % (code.unlikely("%s < 0" % retcode_cname))) + code.putln('if (%s) {' % (code.unlikely("%s < 0" % retcode_cname))) # If acquisition failed, attempt to reacquire the old buffer # before raising the exception. A failure of reacquisition # will cause the reacquisition exception to be reported, one # can consider working around this later. - code.begin_block() - type, value, tb = [code.funcstate.allocate_temp(PyrexTypes.py_object_type) + type, value, tb = [code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=False) for i in range(3)] code.putln('PyErr_Fetch(&%s, &%s, &%s);' % (type, value, tb)) - code.put('if (%s) ' % code.unlikely("%s == -1" % (getbuffer % lhs_cname))) - code.begin_block() - code.putln('Py_XDECREF(%s); Py_XDECREF(%s); Py_XDECREF(%s);' % (type, value, tb)) + code.putln('if (%s) {' % code.unlikely("%s == -1" % (getbuffer % lhs_cname))) + code.putln('Py_XDECREF(%s); Py_XDECREF(%s); Py_XDECREF(%s);' % (type, value, tb)) # Do not refnanny these! code.globalstate.use_utility_code(raise_buffer_fallback_code) code.putln('__Pyx_RaiseBufferFallbackError();') code.putln('} else {') code.putln('PyErr_Restore(%s, %s, %s);' % (type, value, tb)) for t in (type, value, tb): code.funcstate.release_temp(t) - code.end_block() + code.putln('}') + code.putln('}') # Unpack indices - code.end_block() put_unpack_buffer_aux_into_scope(buffer_aux, buffer_type.mode, code) code.putln(code.error_goto_if_neg(retcode_cname, pos)) code.funcstate.release_temp(retcode_cname) @@ -325,7 +318,7 @@ # In this case, auxiliary vars should be set up right in initialization to a zero-buffer, # so it suffices to set the buf field to NULL. code.putln('if (%s) {' % code.unlikely("%s == -1" % (getbuffer % rhs_cname))) - code.putln('%s = %s; Py_INCREF(Py_None); %s.buf = NULL;' % + code.putln('%s = %s; __Pyx_INCREF(Py_None); %s.buf = NULL;' % (lhs_cname, PyrexTypes.typecast(buffer_type, PyrexTypes.py_object_type, "Py_None"), bufstruct)) @@ -335,8 +328,9 @@ put_unpack_buffer_aux_into_scope(buffer_aux, buffer_type.mode, code) code.putln('}') + code.putln("}") # Release stack -def put_buffer_lookup_code(entry, index_signeds, index_cnames, options, pos, code): +def put_buffer_lookup_code(entry, index_signeds, index_cnames, directives, pos, code): """ Generates code to process indices and calculate an offset into a buffer. Returns a C string which gives a pointer which can be @@ -351,14 +345,14 @@ """ bufaux = entry.buffer_aux bufstruct = bufaux.buffer_info_var.cname - negative_indices = entry.type.negative_indices + negative_indices = directives['wraparound'] and entry.type.negative_indices - if options['boundscheck']: + if directives['boundscheck']: # Check bounds and fix negative indices. # We allocate a temporary which is initialized to -1, meaning OK (!). # If an error occurs, the temp is set to the dimension index the # error is occuring at. - tmp_cname = code.funcstate.allocate_temp(PyrexTypes.c_int_type) + tmp_cname = code.funcstate.allocate_temp(PyrexTypes.c_int_type, manage_ref=False) code.putln("%s = -1;" % tmp_cname) for dim, (signed, cname, shape) in enumerate(zip(index_signeds, index_cnames, bufaux.shapevars)): @@ -377,11 +371,10 @@ code.unlikely("%s >= %s" % (cname, shape.cname)), tmp_cname, dim)) code.globalstate.use_utility_code(raise_indexerror_code) - code.put("if (%s) " % code.unlikely("%s != -1" % tmp_cname)) - code.begin_block() + code.putln("if (%s) {" % code.unlikely("%s != -1" % tmp_cname)) code.putln('__Pyx_RaiseBufferIndexError(%s);' % tmp_cname) code.putln(code.error_goto(pos)) - code.end_block() + code.putln('}') code.funcstate.release_temp(tmp_cname) elif negative_indices: # Only fix negative indices. @@ -420,7 +413,11 @@ params.append(s.cname) # Make sure the utility code is available - code.globalstate.use_code_from(funcgen, name=funcname, nd=nd) + if funcname not in code.globalstate.utility_codes: + code.globalstate.utility_codes.add(funcname) + protocode = code.globalstate['utility_code_proto'] + defcode = code.globalstate['utility_code_def'] + funcgen(protocode, defcode, name=funcname, nd=nd) ptr_type = entry.type.buffer_ptr_type ptrcode = "%s(%s, %s.buf, %s)" % (funcname, @@ -492,216 +489,6 @@ offset = " + ".join(["i%d * s%d" % (i, i) for i in range(1, nd)]) proto.putln("#define %s(type, buf, %s) ((type)((char*)buf + %s) + i%d)" % (name, args, offset, 0)) -# -# Utils for creating type string checkers -# -def mangle_dtype_name(dtype): - # Use prefixes to seperate user defined types from builtins - # (consider "typedef float unsigned_int") - if dtype.is_pyobject: - return "object" - elif dtype.is_ptr: - return "ptr" - else: - if dtype.is_typedef or dtype.is_struct_or_union: - prefix = "nn_" - else: - prefix = "" - return prefix + dtype.declaration_code("").replace(" ", "_") - -def get_typestringchecker(code, dtype): - """ - Returns the name of a typestring checker with the given type; emitting - it to code if needed. - """ - name = "__Pyx_CheckTypestring_%s" % mangle_dtype_name(dtype) - code.globalstate.use_code_from(create_typestringchecker, - name, - dtype=dtype) - return name - -def create_typestringchecker(protocode, defcode, name, dtype): - - def put_assert(cond, msg): - defcode.putln("if (!(%s)) {" % cond) - defcode.putln('PyErr_Format(PyExc_ValueError, "Buffer dtype mismatch (%s)", __Pyx_DescribeTokenInFormatString(ts));' % msg) - defcode.putln("return NULL;") - defcode.putln("}") - - if dtype.is_error: return - simple = dtype.is_simple_buffer_dtype() - complex_possible = dtype.is_struct_or_union and dtype.can_be_complex() - # Cannot add utility code recursively... - if not simple: - dtype_t = dtype.declaration_code("") - protocode.globalstate.use_utility_code(parse_typestring_repeat_code) - fields = dtype.scope.var_entries - - # divide fields into blocks of equal type (for repeat count) - field_blocks = [] # of (n, type, checkerfunc) - n = 0 - prevtype = None - for f in fields: - if n and f.type != prevtype: - field_blocks.append((n, prevtype, get_typestringchecker(protocode, prevtype))) - n = 0 - prevtype = f.type - n += 1 - field_blocks.append((n, f.type, get_typestringchecker(protocode, f.type))) - - protocode.putln("static const char* %s(const char* ts); /*proto*/" % name) - defcode.putln("static const char* %s(const char* ts) {" % name) - if simple: - defcode.putln("int ok;") - defcode.putln("ts = __Pyx_ConsumeWhitespace(ts); if (!ts) return NULL;") - defcode.putln("if (*ts == '1') ++ts;") - if dtype.is_pyobject: - defcode.putln("ok = (*ts == 'O');") - else: - # Cannot trust declared size; but rely on int vs float and - # signed/unsigned to be correctly declared. Use a switch statement - # on all possible format codes to validate that the size is ok. - # (Note that many codes may map to same size, e.g. 'i' and 'l' - # may both be four bytes). - ctype = dtype.declaration_code("") - defcode.putln("switch (*ts) {") - if dtype.is_int: - types = [ - ('b', 'char'), ('h', 'short'), ('i', 'int'), - ('l', 'long'), ('q', 'long long') - ] - elif dtype.is_float: - types = [('f', 'float'), ('d', 'double'), ('g', 'long double')] - else: - assert False - if dtype.signed == 0: - for char, against in types: - defcode.putln("case '%s': ok = (sizeof(%s) == sizeof(unsigned %s) && (%s)-1 > 0); break;" % - (char.upper(), ctype, against, ctype)) - else: - for char, against in types: - defcode.putln("case '%s': ok = (sizeof(%s) == sizeof(%s) && (%s)-1 < 0); break;" % - (char, ctype, against, ctype)) - defcode.putln("default: ok = 0;") - defcode.putln("}") - put_assert("ok", "expected %s, got %%s" % dtype) - defcode.putln("++ts;") - elif complex_possible: - # Could be a struct representing a complex number, so allow - # for parsing a "Zf" spec. - real_t, imag_t = [x.type for x in fields] - defcode.putln("ts = __Pyx_ConsumeWhitespace(ts); if (!ts) return NULL;") - defcode.putln("if (*ts == '1') ++ts;") - defcode.putln("if (*ts == 'Z') {") - if len(field_blocks) == 2: - # Different float type, sizeof check needed - defcode.putln("if (sizeof(%s) != sizeof(%s)) {" % ( - real_t.declaration_code(""), - imag_t.declaration_code(""))) - defcode.putln('PyErr_SetString(PyExc_ValueError, "Cannot store complex number in \'%s\' as \'%s\' differs from \'%s\' in size.");' % ( - dtype, real_t, imag_t)) - defcode.putln("return NULL;") - defcode.putln("}") - check_real, check_imag = [x[2] for x in field_blocks] - else: - assert len(field_blocks) == 1 - check_real = check_imag = field_blocks[0][2] - defcode.putln("ts = %s(ts + 1); if (!ts) return NULL;" % check_real) - defcode.putln("} else {") - defcode.putln("ts = %s(ts); if (!ts) return NULL;" % check_real) - defcode.putln("ts = __Pyx_ConsumeWhitespace(ts); if (!ts) return NULL;") - defcode.putln("ts = %s(ts); if (!ts) return NULL;" % check_imag) - defcode.putln("}") - else: - defcode.putln("int n, count;") - defcode.putln("ts = __Pyx_ConsumeWhitespace(ts); if (!ts) return NULL;") - - next_types = [x[1] for x in field_blocks[1:]] + ["end"] - for (n, type, checker), next_type in zip(field_blocks, next_types): - if n == 1: - defcode.putln("if (*ts == '1') ++ts;") - else: - defcode.putln("n = %d;" % n); - defcode.putln("do {") - defcode.putln("ts = __Pyx_ParseTypestringRepeat(ts, &count); n -= count;") - put_assert("n >= 0", "expected %s, got %%s" % next_type) - - simple = type.is_simple_buffer_dtype() - if not simple: - put_assert("*ts == 'T' && *(ts+1) == '{'", "expected %s, got %%s" % type) - defcode.putln("ts += 2;") - defcode.putln("ts = %s(ts); if (!ts) return NULL;" % checker) - if not simple: - put_assert("*ts == '}'", "expected end of %s struct, got %%s" % type) - defcode.putln("++ts;") - - if n > 1: - defcode.putln("} while (n > 0);"); - defcode.putln("ts = __Pyx_ConsumeWhitespace(ts); if (!ts) return NULL;") - - defcode.putln("return ts;") - defcode.putln("}") - -def get_getbuffer_code(dtype, code): - """ - Generate a utility function for getting a buffer for the given dtype. - The function will: - - Call PyObject_GetBuffer - - Check that ndim matched the expected value - - Check that the format string is right - - Set suboffsets to all -1 if it is returned as NULL. - """ - - name = "__Pyx_GetBuffer_%s" % mangle_dtype_name(dtype) - if not code.globalstate.has_code(name): - code.globalstate.use_utility_code(acquire_utility_code) - typestringchecker = get_typestringchecker(code, dtype) - dtype_name = str(dtype) - dtype_cname = dtype.declaration_code("") - utilcode = UtilityCode(proto = dedent(""" - static int %s(PyObject* obj, Py_buffer* buf, int flags, int nd, int cast); /*proto*/ - """) % name, impl = dedent(""" - static int %(name)s(PyObject* obj, Py_buffer* buf, int flags, int nd, int cast) { - const char* ts; - if (obj == Py_None) { - __Pyx_ZeroBuffer(buf); - return 0; - } - buf->buf = NULL; - if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail; - if (buf->ndim != nd) { - __Pyx_BufferNdimError(buf, nd); - goto fail; - } - if (!cast) { - ts = buf->format; - ts = __Pyx_ConsumeWhitespace(ts); - if (!ts) goto fail; - ts = %(typestringchecker)s(ts); - if (!ts) goto fail; - ts = __Pyx_ConsumeWhitespace(ts); - if (!ts) goto fail; - if (*ts != 0) { - PyErr_Format(PyExc_ValueError, - "Buffer dtype mismatch (expected end, got %%s)", - __Pyx_DescribeTokenInFormatString(ts)); - goto fail; - } - } else { - if (buf->itemsize != sizeof(%(dtype_cname)s)) { - PyErr_SetString(PyExc_ValueError, - "Attempted cast of buffer to datatype of different size."); - goto fail; - } - } - if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones; - return 0; - fail:; - __Pyx_ZeroBuffer(buf); - return -1; - }""") % locals()) - code.globalstate.use_utility_code(utilcode, name) - return name def use_py2_buffer_functions(env): # Emulation of PyObject_GetBuffer and PyBuffer_Release for Python 2. @@ -782,9 +569,92 @@ #endif """), impl = code), codename) -# -# Static utility code -# + +def mangle_dtype_name(dtype): + # Use prefixes to seperate user defined types from builtins + # (consider "typedef float unsigned_int") + if dtype.is_pyobject: + return "object" + elif dtype.is_ptr: + return "ptr" + else: + if dtype.is_typedef or dtype.is_struct_or_union: + prefix = "nn_" + else: + prefix = "" + return prefix + dtype.declaration_code("").replace(" ", "_") + +def get_type_information_cname(code, dtype, maxdepth=None): + # Output the run-time type information (__Pyx_TypeInfo) for given dtype, + # and return the name of the type info struct. + # + # Structs with two floats of the same size are encoded as complex numbers. + # One can seperate between complex numbers declared as struct or with native + # encoding by inspecting to see if the fields field of the type is + # filled in. + namesuffix = mangle_dtype_name(dtype) + name = "__Pyx_TypeInfo_%s" % namesuffix + structinfo_name = "__Pyx_StructFields_%s" % namesuffix + + if dtype.is_error: return "" + + # It's critical that walking the type info doesn't use more stack + # depth than dtype.struct_nesting_depth() returns, so use an assertion for this + if maxdepth is None: maxdepth = dtype.struct_nesting_depth() + if maxdepth <= 0: + assert False + + if name not in code.globalstate.utility_codes: + code.globalstate.utility_codes.add(name) + typecode = code.globalstate['typeinfo'] + + complex_possible = dtype.is_struct_or_union and dtype.can_be_complex() + + declcode = dtype.declaration_code("") + if dtype.is_simple_buffer_dtype(): + structinfo_name = "NULL" + elif dtype.is_struct: + fields = dtype.scope.var_entries + # Must pre-call all used types in order not to recurse utility code + # writing. + assert len(fields) > 0 + types = [get_type_information_cname(code, f.type, maxdepth - 1) + for f in fields] + typecode.putln("static __Pyx_StructField %s[] = {" % structinfo_name, safe=True) + for f, typeinfo in zip(fields, types): + typecode.putln(' {&%s, "%s", offsetof(%s, %s)},' % + (typeinfo, f.name, dtype.declaration_code(""), f.cname), safe=True) + typecode.putln(' {NULL, NULL, 0}', safe=True) + typecode.putln("};", safe=True) + else: + assert False + + rep = str(dtype) + if dtype.is_int: + if dtype.signed == 0: + typegroup = 'U' + else: + typegroup = 'I' + elif complex_possible or dtype.is_complex: + typegroup = 'C' + elif dtype.is_float: + typegroup = 'R' + elif dtype.is_struct: + typegroup = 'S' + elif dtype.is_pyobject: + typegroup = 'O' + else: + print dtype + assert False + + typecode.putln(('static __Pyx_TypeInfo %s = { "%s", %s, sizeof(%s), \'%s\' };' + ) % (name, + rep, + structinfo_name, + declcode, + typegroup, + ), safe=True) + return name # Utility function to set the right exception @@ -801,122 +671,503 @@ """) +parse_typestring_repeat_code = UtilityCode( +proto = """ +""", +impl = """ +""") + +raise_buffer_fallback_code = UtilityCode( +proto = """ +static void __Pyx_RaiseBufferFallbackError(void); /*proto*/ +""", +impl = """ +static void __Pyx_RaiseBufferFallbackError(void) { + PyErr_Format(PyExc_ValueError, + "Buffer acquisition failed on assignment; and then reacquiring the old buffer failed too!"); +} + +""") + + + +# +# Buffer format string checking # # Buffer type checking. Utility code for checking that acquired # buffers match our assumptions. We only need to check ndim and # the format string; the access mode/flags is checked by the # exporter. # -acquire_utility_code = UtilityCode( -proto = """\ +# The alignment code is copied from _struct.c in Python. +acquire_utility_code = UtilityCode(proto=""" +/* Run-time type information about structs used with buffers */ +struct __Pyx_StructField_; + +typedef struct { + const char* name; /* for error messages only */ + struct __Pyx_StructField_* fields; + size_t size; /* sizeof(type) */ + char typegroup; /* _R_eal, _C_omplex, Signed _I_nt, _U_nsigned int, _S_truct, _P_ointer, _O_bject */ +} __Pyx_TypeInfo; + +typedef struct __Pyx_StructField_ { + __Pyx_TypeInfo* type; + const char* name; + size_t offset; +} __Pyx_StructField; + +typedef struct { + __Pyx_StructField* field; + size_t parent_offset; +} __Pyx_BufFmt_StackElem; + + static INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info); -static INLINE void __Pyx_ZeroBuffer(Py_buffer* buf); /*proto*/ -static INLINE const char* __Pyx_ConsumeWhitespace(const char* ts); /*proto*/ -static void __Pyx_BufferNdimError(Py_buffer* buffer, int expected_ndim); /*proto*/ -static const char* __Pyx_DescribeTokenInFormatString(const char* ts); /*proto*/ -""", -impl = """ -static INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) { - if (info->buf == NULL) return; - if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL; - __Pyx_ReleaseBuffer(info); +static int __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack); +""", impl=""" +static INLINE int __Pyx_IsLittleEndian(void) { + unsigned int n = 1; + return *(unsigned char*)(&n) != 0; } -static INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) { - buf->buf = NULL; - buf->obj = NULL; - buf->strides = __Pyx_zeros; - buf->shape = __Pyx_zeros; - buf->suboffsets = __Pyx_minusones; +typedef struct { + __Pyx_StructField root; + __Pyx_BufFmt_StackElem* head; + size_t fmt_offset; + int new_count, enc_count; + int is_complex; + char enc_type; + char packmode; +} __Pyx_BufFmt_Context; + +static void __Pyx_BufFmt_Init(__Pyx_BufFmt_Context* ctx, + __Pyx_BufFmt_StackElem* stack, + __Pyx_TypeInfo* type) { + stack[0].field = &ctx->root; + stack[0].parent_offset = 0; + ctx->root.type = type; + ctx->root.name = "buffer dtype"; + ctx->root.offset = 0; + ctx->head = stack; + ctx->head->field = &ctx->root; + ctx->fmt_offset = 0; + ctx->head->parent_offset = 0; + ctx->packmode = '@'; + ctx->new_count = 1; + ctx->enc_count = 0; + ctx->enc_type = 0; + ctx->is_complex = 0; + while (type->typegroup == 'S') { + ++ctx->head; + ctx->head->field = type->fields; + ctx->head->parent_offset = 0; + type = type->fields->type; + } } -static INLINE const char* __Pyx_ConsumeWhitespace(const char* ts) { - while (1) { - switch (*ts) { - case '@': - case 10: - case 13: - case ' ': - ++ts; - break; - case '=': - case '<': - case '>': - case '!': - PyErr_SetString(PyExc_ValueError, "Buffer acquisition error: Only native byte order, size and alignment supported."); - return NULL; - default: - return ts; +static int __Pyx_BufFmt_ParseNumber(const char** ts) { + int count; + const char* t = *ts; + if (*t < '0' || *t > '9') { + return -1; + } else { + count = *t++ - '0'; + while (*t >= '0' && *t < '9') { + count *= 10; + count += *t++ - '0'; + } } - } + *ts = t; + return count; } -static void __Pyx_BufferNdimError(Py_buffer* buffer, int expected_ndim) { - PyErr_Format(PyExc_ValueError, - "Buffer has wrong number of dimensions (expected %d, got %d)", - expected_ndim, buffer->ndim); +static void __Pyx_BufFmt_RaiseUnexpectedChar(char ch) { + char msg[] = {ch, 0}; + PyErr_Format(PyExc_ValueError, "Unexpected format string character: '%s'", msg); } -static const char* __Pyx_DescribeTokenInFormatString(const char* ts) { - switch (*ts) { - case 'b': return "char"; - case 'B': return "unsigned char"; - case 'h': return "short"; - case 'H': return "unsigned short"; - case 'i': return "int"; - case 'I': return "unsigned int"; - case 'l': return "long"; - case 'L': return "unsigned long"; - case 'q': return "long long"; - case 'Q': return "unsigned long long"; - case 'f': return "float"; - case 'd': return "double"; - case 'g': return "long double"; - case 'Z': switch (*(ts+1)) { - case 'f': return "complex float"; - case 'd': return "complex double"; - case 'g': return "complex long double"; - default: return "unparseable format string"; - } +static const char* __Pyx_BufFmt_DescribeTypeChar(char ch, int is_complex) { + switch (ch) { + case 'b': return "'char'"; + case 'B': return "'unsigned char'"; + case 'h': return "'short'"; + case 'H': return "'unsigned short'"; + case 'i': return "'int'"; + case 'I': return "'unsigned int'"; + case 'l': return "'long'"; + case 'L': return "'unsigned long'"; + case 'q': return "'long long'"; + case 'Q': return "'unsigned long long'"; + case 'f': return (is_complex ? "'complex float'" : "'float'"); + case 'd': return (is_complex ? "'complex double'" : "'double'"); + case 'g': return (is_complex ? "'complex long double'" : "'long double'"); case 'T': return "a struct"; case 'O': return "Python object"; case 'P': return "a pointer"; + case 0: return "end"; default: return "unparseable format string"; } } -""") +static size_t __Pyx_BufFmt_TypeCharToStandardSize(char ch, int is_complex) { + switch (ch) { + case '?': case 'c': case 'b': case 'B': return 1; + case 'h': case 'H': return 2; + case 'i': case 'I': case 'l': case 'L': return 4; + case 'q': case 'Q': return 8; + case 'f': return (is_complex ? 8 : 4); + case 'd': return (is_complex ? 16 : 8); + case 'g': { + PyErr_SetString(PyExc_ValueError, "Python does not define a standard format string size for long double ('g').."); + return 0; + } + case 'O': case 'P': return sizeof(void*); + default: + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } +} +static size_t __Pyx_BufFmt_TypeCharToNativeSize(char ch, int is_complex) { + switch (ch) { + case 'c': case 'b': case 'B': return 1; + case 'h': case 'H': return sizeof(short); + case 'i': case 'I': return sizeof(int); + case 'l': case 'L': return sizeof(long); + #ifdef HAVE_LONG_LONG + case 'q': case 'Q': return sizeof(PY_LONG_LONG); + #endif + case 'f': return sizeof(float) * (is_complex ? 2 : 1); + case 'd': return sizeof(double) * (is_complex ? 2 : 1); + case 'g': return sizeof(long double) * (is_complex ? 2 : 1); + case 'O': case 'P': return sizeof(void*); + default: { + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } + } +} -parse_typestring_repeat_code = UtilityCode( -proto = """ -static INLINE const char* __Pyx_ParseTypestringRepeat(const char* ts, int* out_count); /*proto*/ -""", -impl = """ -static INLINE const char* __Pyx_ParseTypestringRepeat(const char* ts, int* out_count) { - int count; - if (*ts < '0' || *ts > '9') { - count = 1; +typedef struct { char c; short x; } __Pyx_st_short; +typedef struct { char c; int x; } __Pyx_st_int; +typedef struct { char c; long x; } __Pyx_st_long; +typedef struct { char c; float x; } __Pyx_st_float; +typedef struct { char c; double x; } __Pyx_st_double; +typedef struct { char c; long double x; } __Pyx_st_longdouble; +typedef struct { char c; void *x; } __Pyx_st_void_p; +#ifdef HAVE_LONG_LONG +typedef struct { char c; PY_LONG_LONG x; } __Pyx_s_long_long; +#endif + +static size_t __Pyx_BufFmt_TypeCharToAlignment(char ch, int is_complex) { + switch (ch) { + case '?': case 'c': case 'b': case 'B': return 1; + case 'h': case 'H': return sizeof(__Pyx_st_short) - sizeof(short); + case 'i': case 'I': return sizeof(__Pyx_st_int) - sizeof(int); + case 'l': case 'L': return sizeof(__Pyx_st_long) - sizeof(long); +#ifdef HAVE_LONG_LONG + case 'q': case 'Q': return sizeof(__Pyx_s_long_long) - sizeof(PY_LONG_LONG); +#endif + case 'f': return sizeof(__Pyx_st_float) - sizeof(float); + case 'd': return sizeof(__Pyx_st_double) - sizeof(double); + case 'g': return sizeof(__Pyx_st_longdouble) - sizeof(long double); + case 'P': case 'O': return sizeof(__Pyx_st_void_p) - sizeof(void*); + default: + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } +} + +static size_t __Pyx_BufFmt_TypeCharToGroup(char ch, int is_complex) { + switch (ch) { + case 'c': case 'b': case 'h': case 'i': case 'l': case 'q': return 'I'; + case 'B': case 'H': case 'I': case 'L': case 'Q': return 'U'; + case 'f': case 'd': case 'g': return (is_complex ? 'C' : 'R'); + case 'O': return 'O'; + case 'P': return 'P'; + default: { + __Pyx_BufFmt_RaiseUnexpectedChar(ch); + return 0; + } + } +} + +static void __Pyx_BufFmt_RaiseExpected(__Pyx_BufFmt_Context* ctx) { + if (ctx->head == NULL || ctx->head->field == &ctx->root) { + const char* expected; + const char* quote; + if (ctx->head == NULL) { + expected = "end"; + quote = ""; } else { - count = *ts++ - '0'; - while (*ts >= '0' && *ts < '9') { - count *= 10; - count += *ts++ - '0'; + expected = ctx->head->field->type->name; + quote = "'"; + } + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch, expected %s%s%s but got %s", + quote, expected, quote, + __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex)); + } else { + __Pyx_StructField* field = ctx->head->field; + __Pyx_StructField* parent = (ctx->head - 1)->field; + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch, expected '%s' but got %s in '%s.%s'", + field->type->name, __Pyx_BufFmt_DescribeTypeChar(ctx->enc_type, ctx->is_complex), + parent->type->name, field->name); + } +} + +static int __Pyx_BufFmt_ProcessTypeChunk(__Pyx_BufFmt_Context* ctx) { + char group; + size_t size, offset; + if (ctx->enc_type == 0) return 0; + group = __Pyx_BufFmt_TypeCharToGroup(ctx->enc_type, ctx->is_complex); + do { + __Pyx_StructField* field = ctx->head->field; + __Pyx_TypeInfo* type = field->type; + + if (ctx->packmode == '@' || ctx->packmode == '^') { + size = __Pyx_BufFmt_TypeCharToNativeSize(ctx->enc_type, ctx->is_complex); + } else { + size = __Pyx_BufFmt_TypeCharToStandardSize(ctx->enc_type, ctx->is_complex); + } + if (ctx->packmode == '@') { + int align_at = __Pyx_BufFmt_TypeCharToAlignment(ctx->enc_type, ctx->is_complex); + int align_mod_offset; + if (align_at == 0) return -1; + align_mod_offset = ctx->fmt_offset % align_at; + if (align_mod_offset > 0) ctx->fmt_offset += align_at - align_mod_offset; + } + + if (type->size != size || type->typegroup != group) { + if (type->typegroup == 'C' && type->fields != NULL) { + /* special case -- treat as struct rather than complex number */ + size_t parent_offset = ctx->head->parent_offset + field->offset; + ++ctx->head; + ctx->head->field = type->fields; + ctx->head->parent_offset = parent_offset; + continue; + } + + __Pyx_BufFmt_RaiseExpected(ctx); + return -1; + } + + offset = ctx->head->parent_offset + field->offset; + if (ctx->fmt_offset != offset) { + PyErr_Format(PyExc_ValueError, + "Buffer dtype mismatch; next field is at offset %"PY_FORMAT_SIZE_T"d " + "but %"PY_FORMAT_SIZE_T"d expected", ctx->fmt_offset, offset); + return -1; + } + + ctx->fmt_offset += size; + + --ctx->enc_count; /* Consume from buffer string */ + + /* Done checking, move to next field, pushing or popping struct stack if needed */ + while (1) { + if (field == &ctx->root) { + ctx->head = NULL; + if (ctx->enc_count != 0) { + __Pyx_BufFmt_RaiseExpected(ctx); + return -1; } + break; /* breaks both loops as ctx->enc_count == 0 */ + } + ctx->head->field = ++field; + if (field->type == NULL) { + --ctx->head; + field = ctx->head->field; + continue; + } else if (field->type->typegroup == 'S') { + size_t parent_offset = ctx->head->parent_offset + field->offset; + if (field->type->fields->type == NULL) continue; /* empty struct */ + field = field->type->fields; + ++ctx->head; + ctx->head->field = field; + ctx->head->parent_offset = parent_offset; + break; + } else { + break; + } } - *out_count = count; - return ts; + } while (ctx->enc_count); + ctx->enc_type = 0; + ctx->is_complex = 0; + return 0; } -""") -raise_buffer_fallback_code = UtilityCode( -proto = """ -static void __Pyx_RaiseBufferFallbackError(void); /*proto*/ -""", -impl = """ -static void __Pyx_RaiseBufferFallbackError(void) { - PyErr_Format(PyExc_ValueError, - "Buffer acquisition failed on assignment; and then reacquiring the old buffer failed too!"); +static int __Pyx_BufFmt_FirstPack(__Pyx_BufFmt_Context* ctx) { + if (ctx->enc_type != 0 || ctx->packmode != '@') { + PyErr_SetString(PyExc_ValueError, "Buffer packing mode currently only allowed at beginning of format string (this is a defect)"); + return -1; + } + return 0; +} + +static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const char* ts) { + int got_Z = 0; + while (1) { + switch(*ts) { + case 0: + if (ctx->enc_type != 0 && ctx->head == NULL) { + __Pyx_BufFmt_RaiseExpected(ctx); + return NULL; + } + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + if (ctx->head != NULL) { + __Pyx_BufFmt_RaiseExpected(ctx); + return NULL; + } + return ts; + case ' ': + case 10: + case 13: + ++ts; + break; + case '<': + if (!__Pyx_IsLittleEndian()) { + PyErr_SetString(PyExc_ValueError, "Little-endian buffer not supported on big-endian compiler"); + return NULL; + } + if (__Pyx_BufFmt_FirstPack(ctx) == -1) return NULL; + ctx->packmode = '='; + ++ts; + break; + case '>': + case '!': + if (__Pyx_IsLittleEndian()) { + PyErr_SetString(PyExc_ValueError, "Big-endian buffer not supported on little-endian compiler"); + return NULL; + } + if (__Pyx_BufFmt_FirstPack(ctx) == -1) return NULL; + ctx->packmode = '='; + ++ts; + break; + case '=': + case '@': + case '^': + if (__Pyx_BufFmt_FirstPack(ctx) == -1) return NULL; + ctx->packmode = *ts++; + break; + case 'T': /* substruct */ + { + int i; + const char* ts_after_sub; + int struct_count = ctx->new_count; + ctx->new_count = 1; + ++ts; + if (*ts != '{') { + PyErr_SetString(PyExc_ValueError, "Buffer acquisition: Expected '{' after 'T'"); + return NULL; + } + ++ts; + ts_after_sub = ts; + for (i = 0; i != struct_count; ++i) { + ts_after_sub = __Pyx_BufFmt_CheckString(ctx, ts); + if (!ts_after_sub) return NULL; + } + ts = ts_after_sub; + } + break; + case '}': /* end of substruct; either repeat or move on */ + ++ts; + return ts; + case 'x': + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->fmt_offset += ctx->new_count; + ctx->new_count = 1; + ctx->enc_count = 0; + ctx->enc_type = 0; + ++ts; + break; + case 'Z': + got_Z = 1; + ++ts; + if (*ts != 'f' && *ts != 'd' && *ts != 'g') { + __Pyx_BufFmt_RaiseUnexpectedChar('Z'); + return NULL; + } /* fall through */ + case 'c': case 'b': case 'B': case 'h': case 'H': case 'i': case 'I': + case 'l': case 'L': case 'q': case 'Q': + case 'f': case 'd': case 'g': + case 'O': + if (ctx->enc_type == *ts && got_Z == ctx->is_complex) { + /* Continue pooling same type */ + ctx->enc_count += ctx->new_count; + } else { + /* New type */ + if (__Pyx_BufFmt_ProcessTypeChunk(ctx) == -1) return NULL; + ctx->enc_count = ctx->new_count; + ctx->enc_type = *ts; + ctx->is_complex = got_Z; + } + ++ts; + ctx->new_count = 1; + got_Z = 0; + break; + default: + { + ctx->new_count = __Pyx_BufFmt_ParseNumber(&ts); + if (ctx->new_count == -1) { /* First char was not a digit */ + char msg[2] = { *ts, 0 }; + PyErr_Format(PyExc_ValueError, + "Does not understand character buffer dtype format string ('%s')", msg); + return NULL; + } + } + + } + } +} + +static INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) { + buf->buf = NULL; + buf->obj = NULL; + buf->strides = __Pyx_zeros; + buf->shape = __Pyx_zeros; + buf->suboffsets = __Pyx_minusones; } +static int __Pyx_GetBufferAndValidate(Py_buffer* buf, PyObject* obj, __Pyx_TypeInfo* dtype, int flags, int nd, int cast, __Pyx_BufFmt_StackElem* stack) { + if (obj == Py_None) { + __Pyx_ZeroBuffer(buf); + return 0; + } + buf->buf = NULL; + if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail; + if (buf->ndim != nd) { + PyErr_Format(PyExc_ValueError, + "Buffer has wrong number of dimensions (expected %d, got %d)", + nd, buf->ndim); + goto fail; + } + if (!cast) { + __Pyx_BufFmt_Context ctx; + __Pyx_BufFmt_Init(&ctx, stack, dtype); + if (!__Pyx_BufFmt_CheckString(&ctx, buf->format)) goto fail; + } + if ((unsigned)buf->itemsize != dtype->size) { + PyErr_Format(PyExc_ValueError, + "Item size of buffer (%"PY_FORMAT_SIZE_T"d byte%s) does not match size of '%s' (%"PY_FORMAT_SIZE_T"d byte%s)", + buf->itemsize, (buf->itemsize > 1) ? "s" : "", + dtype->name, + dtype->size, (dtype->size > 1) ? "s" : ""); + goto fail; + } + if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones; + return 0; +fail:; + __Pyx_ZeroBuffer(buf); + return -1; +} + +static INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) { + if (info->buf == NULL) return; + if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL; + __Pyx_ReleaseBuffer(info); +} """) + diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/Builtin.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/Builtin.py --- cython-0.10.3/Cython/Compiler/Builtin.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/Builtin.py 2009-05-20 16:37:46.000000000 +0100 @@ -6,16 +6,18 @@ from Cython.Utils import UtilityCode from TypeSlots import Signature import PyrexTypes +import Naming builtin_function_table = [ # name, args, return, C API func, py equiv = "*" ('abs', "O", "O", "PyNumber_Absolute"), #('chr', "", "", ""), #('cmp', "", "", "", ""), # int PyObject_Cmp(PyObject *o1, PyObject *o2, int *result) - #('compile', "", "", ""), # PyObject* Py_CompileString( char *str, char *filename, int start) + #('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"), + ('exec', "OOO", "O", "__Pyx_PyRun"), #('eval', "", "", ""), #('execfile', "", "", ""), #('filter', "", "", ""), @@ -48,6 +50,7 @@ #('round', "", "", ""), ('setattr', "OOO", "r", "PyObject_SetAttr"), #('sum', "", "", ""), + ('type', "O", "O", "PyObject_Type"), #('unichr', "", "", ""), #('unicode', "", "", ""), #('vars', "", "", ""), @@ -89,7 +92,10 @@ ("int", "PyInt_Type", []), ("long", "PyLong_Type", []), ("float", "PyFloat_Type", []), - ("complex", "PyComplex_Type", []), + +# Until we have a way to access attributes of a type, +# we don't want to make this one builtin. +# ("complex", "PyComplex_Type", []), ("bytes", "PyBytes_Type", []), ("str", "PyString_Type", []), @@ -98,13 +104,14 @@ ("tuple", "PyTuple_Type", []), ("list", "PyList_Type", [("append", "OO", "i", "PyList_Append"), - ("insert", "OiO", "i", "PyList_Insert"), - ("sort", "O", "i", "PyList_Sort"), + ("insert", "OZO", "i", "PyList_Insert"), +# ("sort", "O", "i", "PyList_Sort"), # has optional arguments ("reverse","O", "i", "PyList_Reverse")]), ("dict", "PyDict_Type", [("items", "O", "O", "PyDict_Items"), ("keys", "O", "O", "PyDict_Keys"), - ("values","O", "O", "PyDict_Values")]), + ("values","O", "O", "PyDict_Values"), + ("copy", "O", "O", "PyDict_Copy")]), ("slice", "PySlice_Type", []), ("file", "PyFile_Type", []), @@ -154,6 +161,57 @@ } """) +pyexec_utility_code = UtilityCode( +proto = """ +static PyObject* __Pyx_PyRun(PyObject*, PyObject*, PyObject*); +""", +impl = """ +static PyObject* __Pyx_PyRun(PyObject* o, PyObject* globals, PyObject* locals) { + PyObject* result; + PyObject* s = 0; + char *code = 0; + + if (!locals && !globals) { + globals = PyModule_GetDict(%s);""" % Naming.module_cname + """ + if (!globals) + goto bad; + locals = globals; + } else if (!locals) { + locals = globals; + } else if (!globals) { + globals = locals; + } + + if (PyUnicode_Check(o)) { + s = PyUnicode_AsUTF8String(o); + if (!s) goto bad; + o = s; + #if PY_MAJOR_VERSION >= 3 + } else if (!PyBytes_Check(o)) { + #else + } else if (!PyString_Check(o)) { + #endif + /* FIXME: support file objects and code objects */ + PyErr_SetString(PyExc_TypeError, + "exec currently requires a string as code input."); + goto bad; + } + + #if PY_MAJOR_VERSION >= 3 + code = PyBytes_AS_STRING(o); + #else + code = PyString_AS_STRING(o); + #endif + result = PyRun_String(code, Py_file_input, globals, locals); + + Py_XDECREF(s); + return result; +bad: + Py_XDECREF(s); + return 0; +} +""") + intern_utility_code = UtilityCode( proto = """ #if PY_MAJOR_VERSION >= 3 @@ -190,22 +248,22 @@ PySequence_Contains((anyset), (key)) #define PySet_Pop(set) \\ - PyObject_CallMethod(set, "pop", NULL) + PyObject_CallMethod(set, (char *)"pop", NULL) static INLINE int PySet_Clear(PyObject *set) { - PyObject *ret = PyObject_CallMethod(set, "clear", NULL); + PyObject *ret = PyObject_CallMethod(set, (char *)"clear", NULL); if (!ret) return -1; Py_DECREF(ret); return 0; } static INLINE int PySet_Discard(PyObject *set, PyObject *key) { - PyObject *ret = PyObject_CallMethod(set, "discard", "O", key); + PyObject *ret = PyObject_CallMethod(set, (char *)"discard", (char *)"O", key); if (!ret) return -1; Py_DECREF(ret); return 0; } static INLINE int PySet_Add(PyObject *set, PyObject *key) { - PyObject *ret = PyObject_CallMethod(set, "add", "O", key); + PyObject *ret = PyObject_CallMethod(set, (char *)"add", (char *)"O", key); if (!ret) return -1; Py_DECREF(ret); return 0; } @@ -232,23 +290,17 @@ static int __Pyx_Py23SetsImport(void) { PyObject *sets=0, *Set=0, *ImmutableSet=0; - sets = PyImport_ImportModule("sets"); + sets = PyImport_ImportModule((char *)"sets"); if (!sets) goto bad; - Set = PyObject_GetAttrString(sets, "Set"); + Set = PyObject_GetAttrString(sets, (char *)"Set"); if (!Set) goto bad; - ImmutableSet = PyObject_GetAttrString(sets, "ImmutableSet"); + ImmutableSet = PyObject_GetAttrString(sets, (char *)"ImmutableSet"); if (!ImmutableSet) goto bad; Py_DECREF(sets); - + __Pyx_PySet_Type = (PyTypeObject*) Set; __Pyx_PyFrozenSet_Type = (PyTypeObject*) ImmutableSet; - /* FIXME: this should be done in dedicated module cleanup code */ - /* - Py_DECREF(Set); - Py_DECREF(ImmutableSet); - */ - return 0; bad: @@ -273,6 +325,7 @@ """) builtin_utility_code = { + 'exec' : pyexec_utility_code, 'getattr3' : getattr3_utility_code, 'intern' : intern_utility_code, 'set' : py23_set_utility_code, @@ -291,10 +344,14 @@ for desc in builtin_function_table: declare_builtin_func(*desc) +builtin_types = {} + def init_builtin_types(): + global builtin_types for name, cname, funcs in builtin_types_table: utility = builtin_utility_code.get(name) the_type = builtin_scope.declare_builtin_type(name, cname, utility) + builtin_types[name] = the_type for name, args, ret, cname in funcs: sig = Signature(args, ret) the_type.scope.declare_cfunction(name, sig.function_type(), None, cname) @@ -312,11 +369,13 @@ init_builtin_funcs() init_builtin_types() init_builtin_structs() - global list_type, tuple_type, dict_type, unicode_type, type_type + global list_type, tuple_type, dict_type, set_type, bytes_type, unicode_type, type_type type_type = builtin_scope.lookup('type').type list_type = builtin_scope.lookup('list').type tuple_type = builtin_scope.lookup('tuple').type dict_type = builtin_scope.lookup('dict').type + set_type = builtin_scope.lookup('set').type + bytes_type = builtin_scope.lookup('bytes').type unicode_type = builtin_scope.lookup('unicode').type init_builtins() diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/CmdLine.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/CmdLine.py --- cython-0.10.3/Cython/Compiler/CmdLine.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/CmdLine.py 2009-05-20 16:37:46.000000000 +0100 @@ -38,8 +38,10 @@ -a, --annotate Produce a colorized HTML version of the source. --line-directives Produce #line directives pointing to the .pyx source --cplus Output a c++ rather than c file. - -X, --directive =[,=[,>sys.stderr, "Deprecation warning: The -X command line switch will be changed to a" + print >>sys.stderr, "shorthand for --directive in Cython 0.12. Please use --link instead." + print >>sys.stderr options.c_only = 0 options.obj_only = 0 elif option in ("-+", "--cplus"): options.cplus = 1 + elif option == "--embed": + Options.embed = True elif option.startswith("-I"): options.include_path.append(get_param(option)) elif option == "--include-dir": @@ -145,5 +153,9 @@ sys.exit(1) if len(sources) == 0 and not options.show_version: bad_usage() + if Options.embed and len(sources) > 1: + sys.stderr.write( + "cython: Only one source file allowed when using -embed\n") + sys.exit(1) return options, sources diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/Code.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/Code.py --- cython-0.10.3/Cython/Compiler/Code.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/Code.py 2009-05-20 16:37:46.000000000 +0100 @@ -7,13 +7,16 @@ import Options from Cython.Utils import open_new_file, open_source_file from PyrexTypes import py_object_type, typecast +import PyrexTypes from TypeSlots import method_coexist from Scanning import SourceDescriptor from Cython.StringIOTree import StringIOTree +import DebugFlags try: set except NameError: from sets import Set as set +import DebugFlags class FunctionState(object): # return_label string function return point label @@ -26,8 +29,9 @@ # exc_vars (string * 3) exception variables for reraise, or None # Not used for now, perhaps later - def __init__(self, names_taken=set()): + def __init__(self, owner, names_taken=set()): self.names_taken = names_taken + self.owner = owner self.error_label = None self.label_counter = 0 @@ -40,9 +44,9 @@ self.in_try_finally = 0 self.exc_vars = None - self.temps_allocated = [] # of (name, type) - self.temps_free = {} # type -> list of free vars - self.temps_used_type = {} # name -> type + self.temps_allocated = [] # of (name, type, manage_ref) + self.temps_free = {} # (type, manage_ref) -> list of free vars with same type/managed status + self.temps_used_type = {} # name -> (type, manage_ref) self.temp_counter = 0 def new_label(self, name=None): @@ -70,8 +74,8 @@ def new_loop_labels(self): old_labels = self.get_loop_labels() self.set_loop_labels( - (self.new_label(), - self.new_label())) + (self.new_label("continue"), + self.new_label("break"))) return old_labels def get_all_labels(self): @@ -104,15 +108,28 @@ def label_used(self, lbl): return lbl in self.labels_used - def allocate_temp(self, type): + def allocate_temp(self, type, manage_ref): """ Allocates a temporary (which may create a new one or get a previously allocated and released one of the same type). Type is simply registered and handed back, but will usually be a PyrexType. + If type.is_pyobject, manage_ref comes into play. If manage_ref is set to + True, the temp will be decref-ed on return statements and in exception + handling clauses. Otherwise the caller has to deal with any reference + counting of the variable. + + If not type.is_pyobject, then manage_ref will be ignored, but it + still has to be passed. It is recommended to pass False by convention + if it is known that type will never be a Python object. + A C string referring to the variable is returned. """ - freelist = self.temps_free.get(type) + if not type.is_pyobject: + # Make manage_ref canonical, so that manage_ref will always mean + # a decref is needed. + manage_ref = False + freelist = self.temps_free.get((type, manage_ref)) if freelist is not None and len(freelist) > 0: result = freelist.pop() else: @@ -120,8 +137,10 @@ self.temp_counter += 1 result = "%s%d" % (Naming.codewriter_temp_prefix, self.temp_counter) if not result in self.names_taken: break - self.temps_allocated.append((result, type)) - self.temps_used_type[result] = type + self.temps_allocated.append((result, type, manage_ref)) + self.temps_used_type[result] = (type, manage_ref) + if DebugFlags.debug_temp_code_comments: + self.owner.putln("/* %s allocated */" % result) return result def release_temp(self, name): @@ -129,13 +148,54 @@ Releases a temporary so that it can be reused by other code needing a temp of the same type. """ - type = self.temps_used_type[name] - freelist = self.temps_free.get(type) + type, manage_ref = self.temps_used_type[name] + freelist = self.temps_free.get((type, manage_ref)) if freelist is None: freelist = [] - - self.temps_free[type] = freelist + self.temps_free[(type, manage_ref)] = freelist + if name in freelist: + raise RuntimeError("Temp %s freed twice!" % name) freelist.append(name) + if DebugFlags.debug_temp_code_comments: + self.owner.putln("/* %s released */" % name) + + def temps_in_use(self): + """Return a list of (cname,type,manage_ref) tuples of temp names and their type + that are currently in use. + """ + used = [] + for name, type, manage_ref in self.temps_allocated: + freelist = self.temps_free.get((type, manage_ref)) + if freelist is None or name not in freelist: + used.append((name, type, manage_ref)) + return used + + def temps_holding_reference(self): + """Return a list of (cname,type) tuples of temp names and their type + that are currently in use. This includes only temps of a + Python object type which owns its reference. + """ + return [(name, type) + for name, type, manage_ref in self.temps_in_use() + if manage_ref] + + def all_managed_temps(self): + """Return a list of (cname, type) tuples of refcount-managed Python objects. + """ + return [(cname, type) + for cname, type, manage_ref in self.temps_allocated + if manage_ref] + + def all_free_managed_temps(self): + """Return a list of (cname, type) tuples of refcount-managed Python + objects that are not currently in use. This is used by + try-except and try-finally blocks to clean up temps in the + error case. + """ + return [(cname, type) + for (type, manage_ref), freelist in self.temps_free.iteritems() + if manage_ref + for cname in freelist] class GlobalState(object): # filename_table {string : int} for finding filename table indexes @@ -144,9 +204,7 @@ # to create this output C code. This is # used to annotate the comments. # - # used_utility_code set(string|int) Ids of used utility code (to avoid reinsertion) - # utilprotowriter CCodeWriter - # utildefwriter CCodeWriter + # utility_codes set IDs of used utility code (to avoid reinsertion) # # declared_cnames {string:Entry} used in a transition phase to merge pxd-declared # constants etc. into the pyx-declared ones (i.e, @@ -154,6 +212,8 @@ # In time, hopefully the literals etc. will be # supplied directly instead. + # parts {string:CCodeWriter} + # interned_strings # consts @@ -167,19 +227,39 @@ directives = {} - def __init__(self, rootwriter, emit_linenums=False): + code_layout = [ + 'h_code', + 'utility_code_proto', + 'type_declarations', + 'module_declarations', + 'typeinfo', + 'before_global_var', + 'global_var', + 'all_the_rest', + 'utility_code_def' + ] + + + def __init__(self, writer, emit_linenums=False): self.filename_table = {} self.filename_list = [] self.input_file_contents = {} - self.used_utility_code = set() + self.utility_codes = set() self.declared_cnames = {} self.pystring_table_needed = False self.in_utility_code_generation = False self.emit_linenums = emit_linenums + self.parts = {} + + assert writer.globalstate is None + writer.globalstate = self + self.rootwriter = writer + + def initialize_main_c_code(self): + rootwriter = self.rootwriter + for part in self.code_layout: + self.parts[part] = rootwriter.insertion_point() - def initwriters(self, rootwriter): - self.utilprotowriter = rootwriter.new_writer() - self.utildefwriter = rootwriter.new_writer() self.decls_writer = rootwriter.new_writer() self.pystring_table = rootwriter.new_writer() self.init_cached_builtins_writer = rootwriter.new_writer() @@ -202,12 +282,37 @@ self.pystring_table.putln("static __Pyx_StringTabEntry %s[] = {" % Naming.stringtab_cname) + + # + # utility_code_def + # + code = self.parts['utility_code_def'] + if self.emit_linenums: + code.write('\n#line 1 "cython_utility"\n') + 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("}") + + def finalize_main_c_code(self): + self.close_global_decls() + + # + # utility_code_def + # + code = self.parts['utility_code_def'] + code.put(PyrexTypes.type_conversion_functions) + code.putln("") + + def __getitem__(self, key): + return self.parts[key] + # # Global constants, interned objects, etc. # - def insert_global_var_declarations_into(self, code): - code.insert(self.decls_writer) - def close_global_decls(self): # This is called when it is known that no more global declarations will # declared (but can be called before or after insert_XXX). @@ -251,7 +356,7 @@ code.insert(self.cleanupwriter) def put_pyobject_decl(self, entry): - self.decls_writer.putln("static PyObject *%s;" % entry.cname) + self['global_var'].putln("static PyObject *%s;" % entry.cname) # The functions below are there in a transition phase only # and will be deprecated. They are called from Nodes.BlockNode. @@ -261,7 +366,7 @@ def should_declare(self, cname, entry): if cname in self.declared_cnames: other = self.declared_cnames[cname] - assert entry.type == other.type + assert str(entry.type) == str(other.type) assert entry.init == other.init return False else: @@ -270,16 +375,16 @@ def add_const_definition(self, entry): if self.should_declare(entry.cname, entry): - self.decls_writer.put_var_declaration(entry, static = 1) + self['global_var'].put_var_declaration(entry, static = 1) def add_interned_string_decl(self, entry): if self.should_declare(entry.cname, entry): - self.decls_writer.put_var_declaration(entry, static = 1) + self['global_var'].put_var_declaration(entry, static = 1) self.add_py_string_decl(entry) def add_py_string_decl(self, entry): if self.should_declare(entry.pystring_cname, entry): - self.decls_writer.putln("static PyObject *%s;" % entry.pystring_cname) + self['global_var'].putln("static PyObject *%s;" % entry.pystring_cname) self.pystring_table_needed = True self.pystring_table.putln("{&%s, %s, sizeof(%s), %d, %d, %d}," % ( entry.pystring_cname, @@ -293,9 +398,9 @@ def add_interned_num_decl(self, entry): if self.should_declare(entry.cname, entry): if entry.init[-1] == "L": - self.initwriter.putln('%s = PyLong_FromString("%s", 0, 0); %s;' % ( + self.initwriter.putln('%s = PyLong_FromString((char *)"%s", 0, 0); %s;' % ( entry.cname, - entry.init, + entry.init[:-1], # strip 'L' for Py3 compatibility self.initwriter.error_goto_if_null(entry.cname, self.module_pos))) else: self.initwriter.putln("%s = PyInt_FromLong(%s); %s;" % ( @@ -336,6 +441,8 @@ except KeyError: F = [u' * ' + line.rstrip().replace( u'*/', u'*[inserted by cython to avoid comment closer]/' + ).replace( + u'/*', u'/[inserted by cython to avoid comment start]*' ).encode('ASCII', 'replace') # + Py2 auto-decode to unicode for line in source_desc.get_lines()] if len(F) == 0: F.append(u'') @@ -357,52 +464,18 @@ code twice. Otherwise, id(codetup) is used as such an identifier. """ if name is None: name = id(utility_code) - if self.check_utility_code_needed_and_register(name): + if name not in self.utility_codes: + self.utility_codes.add(name) + if utility_code.requires: + for dependency in utility_code.requires: + self.use_utility_code(dependency) if utility_code.proto: - self.utilprotowriter.put(utility_code.proto) + self.parts['utility_code_proto'].put(utility_code.proto) if utility_code.impl: - self.utildefwriter.put(utility_code.impl) + self.parts['utility_code_def'].put(utility_code.impl) utility_code.write_init_code(self.initwriter, self.module_pos) utility_code.write_cleanup_code(self.cleanupwriter, self.module_pos) - def has_code(self, name): - return name in self.used_utility_code - - def use_code_from(self, func, name, *args, **kw): - """ - Requests that the utility code that func can generate is used in the C - file. func is called like this: - - func(proto, definition, name, *args, **kw) - - where proto and definition are two CCodeWriter instances; the - former should have the prototype written to it and the other the definition. - - The call might happen at some later point (if compiling multiple modules - into a cache for instance), and will only happen once per utility code. - - name is used to identify the utility code, so that it isn't regenerated - when the same code is requested again. - """ - if self.check_utility_code_needed_and_register(name): - func(self.utilprotowriter, self.utildefwriter, - name, *args, **kw) - - def check_utility_code_needed_and_register(self, name): - if name in self.used_utility_code: - return False - else: - self.used_utility_code.add(name) - return True - - def put_utility_code_protos(self, writer): - writer.insert(self.utilprotowriter) - - def put_utility_code_defs(self, writer): - if self.emit_linenums: - writer.write('\n#line 1 "cython_utility"\n') - writer.insert(self.utildefwriter) - def funccontext_property(name): def get(self): @@ -439,6 +512,8 @@ # globalstate GlobalState contains state global for a C file (input file info, # utility code, declared constants etc.) # emit_linenums boolean whether or not to write #line pragmas + + globalstate = None def __init__(self, create_from=None, buffer=None, copy_formatting=False, emit_linenums=None): if buffer is None: buffer = StringIOTree() @@ -449,20 +524,18 @@ self.funcstate = None self.level = 0 + self.call_level = 0 self.bol = 1 - if create_from is None: - # Root CCodeWriter - self.globalstate = GlobalState(self, emit_linenums=emit_linenums) - self.globalstate.initwriters(self) - # ^^^ need seperate step because this will reference self.globalstate - else: + + if create_from is not None: # Use same global state self.globalstate = create_from.globalstate # Clone formatting state if copy_formatting: self.level = create_from.level self.bol = create_from.bol - if emit_linenums is None: + self.call_level = create_from.call_level + if emit_linenums is None and self.globalstate: self.emit_linenums = self.globalstate.emit_linenums else: self.emit_linenums = emit_linenums @@ -470,7 +543,8 @@ def create_new(self, create_from, buffer, copy_formatting): # polymorphic constructor -- very slightly more versatile # than using __class__ - return CCodeWriter(create_from, buffer, copy_formatting) + result = CCodeWriter(create_from, buffer, copy_formatting) + return result def copyto(self, f): self.buffer.copyto(f) @@ -525,18 +599,21 @@ def enter_cfunc_scope(self): - self.funcstate = FunctionState() + self.funcstate = FunctionState(self) def exit_cfunc_scope(self): self.funcstate = None - def putln(self, code = ""): + def putln(self, code = "", safe=False): if self.marker and self.bol: self.emit_marker() if self.emit_linenums and self.last_marker_line != 0: self.write('\n#line %s "%s"\n' % (self.last_marker_line, self.source_desc)) if code: - self.put(code) + if safe: + self.put_safe(code) + else: + self.put(code) self.write("\n"); self.bol = 1 @@ -554,12 +631,18 @@ def put(self, code): fix_indent = False - dl = code.count("{") - code.count("}") - if dl < 0: - self.level += dl - elif dl == 0 and code.startswith('}'): - fix_indent = True - self.level -= 1 + if "{" in code: + dl = code.count("{") + else: + dl = 0 + if "}" in code: + dl -= code.count("}") + if dl < 0: + self.level += dl + elif dl == 0 and code[0] == "}": + # special cases like "} else {" need a temporary dedent + fix_indent = True + self.level -= 1 if self.bol: self.indent() self.write(code) @@ -653,7 +736,7 @@ self.putln(";") def put_temp_declarations(self, func_context): - for name, type in func_context.temps_allocated: + for name, type, manage_ref in func_context.temps_allocated: decl = type.declaration_code(name) if type.is_pyobject: self.putln("%s = NULL;" % decl) @@ -662,8 +745,8 @@ 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): + if (not entry.is_self_arg and not entry.type.is_complete() + or entry.type.is_extension_type): return "(PyObject *)" + entry.cname else: return entry.cname @@ -671,47 +754,91 @@ def as_pyobject(self, cname, type): return typecast(py_object_type, type, cname) - def put_incref(self, cname, type): - self.putln("Py_INCREF(%s);" % self.as_pyobject(cname, type)) + def put_gotref(self, cname): + self.putln("__Pyx_GOTREF(%s);" % cname) + + def put_giveref(self, cname): + self.putln("__Pyx_GIVEREF(%s);" % cname) - def put_decref(self, cname, type): - self.putln("Py_DECREF(%s);" % self.as_pyobject(cname, type)) + def put_xgiveref(self, cname): + self.putln("__Pyx_XGIVEREF(%s);" % cname) + + def put_xgotref(self, cname): + self.putln("__Pyx_XGOTREF(%s);" % cname) + + def put_incref(self, cname, type, nanny=True): + if nanny: + self.putln("__Pyx_INCREF(%s);" % self.as_pyobject(cname, type)) + else: + self.putln("Py_INCREF(%s);" % self.as_pyobject(cname, type)) + def put_decref(self, cname, type, nanny=True): + if nanny: + self.putln("__Pyx_DECREF(%s);" % self.as_pyobject(cname, type)) + else: + self.putln("Py_DECREF(%s);" % self.as_pyobject(cname, type)) + + def put_var_gotref(self, entry): + if entry.type.is_pyobject: + self.putln("__Pyx_GOTREF(%s);" % self.entry_as_pyobject(entry)) + + def put_var_giveref(self, entry): + if entry.type.is_pyobject: + self.putln("__Pyx_GIVEREF(%s);" % self.entry_as_pyobject(entry)) + + def put_var_xgotref(self, entry): + if entry.type.is_pyobject: + self.putln("__Pyx_XGOTREF(%s);" % self.entry_as_pyobject(entry)) + + def put_var_xgiveref(self, entry): + if entry.type.is_pyobject: + self.putln("__Pyx_XGIVEREF(%s);" % self.entry_as_pyobject(entry)) + def put_var_incref(self, entry): if entry.type.is_pyobject: - self.putln("Py_INCREF(%s);" % self.entry_as_pyobject(entry)) + self.putln("__Pyx_INCREF(%s);" % self.entry_as_pyobject(entry)) + + def put_decref_clear(self, cname, type, nanny=True): + if nanny: + self.putln("__Pyx_DECREF(%s); %s = 0;" % ( + typecast(py_object_type, type, cname), cname)) + else: + self.putln("Py_DECREF(%s); %s = 0;" % ( + typecast(py_object_type, type, cname), cname)) + + def put_xdecref(self, cname, type, nanny=True): + if nanny: + self.putln("__Pyx_XDECREF(%s);" % self.as_pyobject(cname, type)) + else: + self.putln("Py_XDECREF(%s);" % self.as_pyobject(cname, type)) - def put_decref_clear(self, cname, type): - self.putln("Py_DECREF(%s); %s = 0;" % ( - typecast(py_object_type, type, cname), cname)) - #self.as_pyobject(cname, type), 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_xdecref_clear(self, cname, type, nanny=True): + if nanny: + self.putln("__Pyx_XDECREF(%s); %s = 0;" % ( + self.as_pyobject(cname, type), cname)) + else: + self.putln("Py_XDECREF(%s); %s = 0;" % ( + self.as_pyobject(cname, type), cname)) def put_var_decref(self, entry): if entry.type.is_pyobject: if entry.init_to_none is False: - self.putln("Py_XDECREF(%s);" % self.entry_as_pyobject(entry)) + self.putln("__Pyx_XDECREF(%s);" % self.entry_as_pyobject(entry)) else: - self.putln("Py_DECREF(%s);" % self.entry_as_pyobject(entry)) + self.putln("__Pyx_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.putln("__Pyx_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)) + self.putln("__Pyx_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.putln("__Pyx_XDECREF(%s); %s = 0;" % ( self.entry_as_pyobject(entry), entry.cname)) def put_var_decrefs(self, entries, used_only = 0): @@ -730,15 +857,18 @@ for entry in entries: self.put_var_xdecref_clear(entry) - def put_init_to_py_none(self, cname, type): + def put_init_to_py_none(self, cname, type, nanny=True): py_none = typecast(type, py_object_type, "Py_None") - self.putln("%s = %s; Py_INCREF(Py_None);" % (cname, py_none)) + if nanny: + self.putln("%s = %s; __Pyx_INCREF(Py_None);" % (cname, py_none)) + else: + self.putln("%s = %s; Py_INCREF(Py_None);" % (cname, py_none)) - def put_init_var_to_py_none(self, entry, template = "%s"): + def put_init_var_to_py_none(self, entry, template = "%s", nanny=True): code = template % entry.cname #if entry.type.is_extension_type: - # code = "((PyObject*)%s)" % code - self.put_init_to_py_none(code, entry.type) + # code = "((PyObject*)%s)" % code + self.put_init_to_py_none(code, entry.type, nanny) def put_pymethoddef(self, entry, term): if entry.doc: @@ -750,13 +880,13 @@ if entry.is_special: method_flags += [method_coexist] self.putln( - '{"%s", (PyCFunction)%s, %s, %s}%s' % ( + '{__Pyx_NAMESTR("%s"), (PyCFunction)%s, %s, __Pyx_DOCSTR(%s)}%s' % ( entry.name, entry.func_cname, "|".join(method_flags), doc_code, term)) - + def put_error_if_neg(self, pos, value): # return self.putln("if (unlikely(%s < 0)) %s" % (value, self.error_goto(pos))) # TODO this path is almost _never_ taken, yet this macro makes is slower! return self.putln("if (%s < 0) %s" % (value, self.error_goto(pos))) @@ -770,21 +900,25 @@ return 'unlikely(%s)' % cond else: return cond - - def error_goto(self, pos): - lbl = self.funcstate.error_label - self.funcstate.use_label(lbl) + + def set_error_info(self, pos): if Options.c_line_in_traceback: cinfo = " %s = %s;" % (Naming.clineno_cname, Naming.line_c_macro) else: cinfo = "" - return "{%s = %s[%s]; %s = %s;%s goto %s;}" % ( + return "%s = %s[%s]; %s = %s;%s" % ( Naming.filename_cname, Naming.filetable_cname, self.lookup_filename(pos[0]), Naming.lineno_cname, pos[1], - cinfo, + cinfo) + + def error_goto(self, pos): + lbl = self.funcstate.error_label + self.funcstate.use_label(lbl) + return "{%s goto %s;}" % ( + self.set_error_info(pos), lbl) def error_goto_if(self, cond, pos): @@ -802,8 +936,14 @@ def lookup_filename(self, filename): return self.globalstate.lookup_filename(filename) + def put_setup_refcount_context(self, name): + self.putln('__Pyx_SetupRefcountContext("%s");' % name) + + def put_finish_refcount_context(self): + self.putln("__Pyx_FinishRefcountContext();") + -class PyrexCodeWriter: +class PyrexCodeWriter(object): # f file output file # level int indentation level diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/ControlFlow.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/ControlFlow.py --- cython-0.10.3/Cython/Compiler/ControlFlow.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/ControlFlow.py 2009-05-20 16:37:46.000000000 +0100 @@ -15,7 +15,7 @@ _END_POS = ((unichr(sys.maxunicode)*10),()) -class ControlFlow: +class ControlFlow(object): def __init__(self, start_pos, incoming, parent): self.start_pos = start_pos diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/CythonScope.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/CythonScope.py --- cython-0.10.3/Cython/Compiler/CythonScope.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/CythonScope.py 2009-05-20 16:37:46.000000000 +0100 @@ -15,7 +15,7 @@ pos=None, defining = 1, cname='') - + def lookup_type(self, name): # This function should go away when types are all first-level objects. type = parse_basic_type(name) @@ -23,4 +23,27 @@ return type def create_cython_scope(context): + create_utility_scope(context) return CythonScope(context) + + +def create_utility_scope(context): + global utility_scope + utility_scope = ModuleScope(u'utility', None, context) + + # These are used to optimize isinstance in FinalOptimizePhase + type_object = utility_scope.declare_typedef('PyTypeObject', + base_type = c_void_type, + pos = None, + cname = 'PyTypeObject') + type_object.is_void = True + + utility_scope.declare_cfunction( + 'PyObject_TypeCheck', + CFuncType(c_bint_type, [CFuncTypeArg("o", py_object_type, None), + CFuncTypeArg("t", c_ptr_type(type_object), None)]), + pos = None, + defining = 1, + cname = 'PyObject_TypeCheck') + + return utility_scope diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/DebugFlags.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/DebugFlags.py --- cython-0.10.3/Cython/Compiler/DebugFlags.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/DebugFlags.py 2009-05-20 16:37:46.000000000 +0100 @@ -2,3 +2,9 @@ debug_temp_alloc = 0 debug_coercion = 0 +# Write comments into the C code that show where temporary variables +# are allocated and released +debug_temp_code_comments = 0 + +# Write a call trace of the code generation phase into the C code +debug_trace_code_generation = 0 diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/Errors.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/Errors.py --- cython-0.10.3/Cython/Compiler/Errors.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/Errors.py 2009-05-20 16:37:46.000000000 +0100 @@ -63,7 +63,28 @@ def __init__(self, message): Exception.__init__(self, "Internal compiler error: %s" % message) - + + +class CompilerCrash(CompileError): + # raised when an unexpected exception occurs in a transform + def __init__(self, pos, context, message, cause, stacktrace=None): + if message: + message = u'\n' + message + else: + message = u'\n' + if context: + message = "Compiler crash in " + context + message + if stacktrace: + import traceback + message += ( + u'\n\nCompiler crash traceback from this point on:\n' + + u''.join(traceback.format_tb(stacktrace))) + if cause: + if not stacktrace: + message += u'\n' + message += u'%s: %s' % (cause.__class__.__name__, cause) + CompileError.__init__(self, pos, message) + listing_file = None num_errors = 0 diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/ExprNodes.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/ExprNodes.py --- cython-0.10.3/Cython/Compiler/ExprNodes.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/ExprNodes.py 2009-05-20 16:37:46.000000000 +0100 @@ -3,17 +3,18 @@ # import operator -from string import join from Errors import error, warning, InternalError from Errors import hold_errors, release_errors, held_errors, report_error from Cython.Utils import UtilityCode import StringEncoding import Naming +import Nodes from Nodes import Node import PyrexTypes from PyrexTypes import py_object_type, c_long_type, typecast, error_type -from Builtin import list_type, tuple_type, dict_type, unicode_type +from Builtin import list_type, tuple_type, set_type, dict_type, unicode_type, bytes_type +import Builtin import Symtab import Options from Annotate import AnnotationItem @@ -22,6 +23,14 @@ from DebugFlags import debug_disposal_code, debug_temp_alloc, \ debug_coercion +try: + set +except NameError: + from sets import Set as set + +class NotConstant(object): pass # just for the name +not_a_constant = NotConstant() +constant_value_not_set = object() class ExprNode(Node): # subexprs [string] Class var holding names of subexpr node attrs @@ -172,9 +181,15 @@ is_temp = 0 is_target = 0 - def get_child_attrs(self): - return self.subexprs - child_attrs = property(fget=get_child_attrs) + constant_result = constant_value_not_set + + try: + _get_child_attrs = operator.attrgetter('subexprs') + except AttributeError: + # Python 2.3 + def _get_child_attrs(self): + return self.subexprs + child_attrs = property(fget=_get_child_attrs) def not_implemented(self, method_name): print_call_chain(method_name, "not implemented") ### @@ -196,17 +211,15 @@ 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 + nodes = [] + for name in self.subexprs: + item = getattr(self, name) + if item is not None: + if type(item) is list: + nodes.extend(item) + else: + nodes.append(item) + return nodes def result(self): if not self.is_temp or self.is_target: @@ -226,7 +239,17 @@ # Return the native C type of the result (i.e. the # C type of the result_code expression). return self.result_ctype or self.type - + + def calculate_constant_result(self): + # Calculate the constant result of this expression and store + # it in ``self.constant_result``. Does nothing by default, + # thus leaving ``self.constant_result`` unknown. + # + # This must only be called when it is assured that all + # sub-expressions have a valid constant_result value. The + # ConstantFolding transform will do this. + pass + def compile_time_value(self, denv): # Return value of compile-time expression, or report error. error(self.pos, "Invalid compile-time expression") @@ -326,7 +349,7 @@ error(self.pos, "Address is not constant") def gil_check(self, env): - if env.nogil and self.type.is_pyobject: + if env is not None and env.nogil and self.type.is_pyobject: self.gil_error() # ----------------- Result Allocation ----------------- @@ -354,6 +377,7 @@ # this must be a temp node and the specified variable # is used as the result instead of allocating a new # one. + assert result is None, "deprecated, contact dagss if this triggers" if debug_temp_alloc: print("%s Allocating temps" % self) self.allocate_subexpr_temps(env) @@ -403,9 +427,9 @@ def calculate_result_code(self): self.not_implemented("calculate_result_code") -# def release_target_temp(self, env): -# # Release temporaries used by LHS of an assignment. -# self.release_subexpr_temps(env) +# def release_target_temp(self, env): +# # Release temporaries used by LHS of an assignment. +# self.release_subexpr_temps(env) def release_temp(self, env): # If this node owns a temporary result, release it, @@ -438,14 +462,11 @@ # its sub-expressions, and dispose of any # temporary results of its sub-expressions. self.generate_subexpr_evaluation_code(code) - self.pre_generate_result_code(code) self.generate_result_code(code) if self.is_temp: self.generate_subexpr_disposal_code(code) + self.free_subexpr_temps(code) - def pre_generate_result_code(self, code): - pass - def generate_subexpr_evaluation_code(self, code): for node in self.subexpr_nodes(): node.generate_evaluation_code(code) @@ -489,7 +510,16 @@ # the argument of a del statement. An error # will have been reported earlier. pass - + + def free_temps(self, code): + if not self.is_temp: + self.free_subexpr_temps(code) + # otherwise, already freed in generate_evaluation_code + + def free_subexpr_temps(self, code): + for sub in self.subexpr_nodes(): + sub.free_temps(code) + # ---------------- Annotation --------------------- def annotate(self, code): @@ -519,10 +549,15 @@ src = PyTypeTestNode(src, dst_type, env) elif src.type.is_pyobject: src = CoerceFromPyTypeNode(dst_type, src, env) + elif (dst_type.is_complex + and src_type != dst_type + and dst_type.assignable_from(src_type) + and not env.directives['c99_complex']): + src = CoerceToComplexNode(src, dst_type, env) else: # neither src nor dst are py types # Added the string comparison, since for c types that # is enough, but Cython gets confused when the types are - # in different files. + # in different pxi files. if not (str(src.type) == str(dst_type) or dst_type.assignable_from(src_type)): error(self.pos, "Cannot assign type '%s' to '%s'" % (src.type, dst_type)) @@ -575,9 +610,23 @@ return None +class RemoveAllocateTemps(type): + def __init__(cls, name, bases, dct): + super(RemoveAllocateTemps, cls).__init__(name, bases, dct) + def noop(self, env): pass + setattr(cls, 'allocate_temps', noop) + setattr(cls, 'allocate_temp', noop) + setattr(cls, 'release_temp', noop) + class NewTempExprNode(ExprNode): - backwards_compatible_result = None - + temp_code = None + old_temp = None # error checker for multiple frees etc. + +# Do not enable this unless you are trying to make all ExprNodes +# NewTempExprNodes (child nodes reached via recursion may not have +# transferred). +# __metaclass__ = RemoveAllocateTemps + def result(self): if self.is_temp: return self.temp_code @@ -586,12 +635,14 @@ def allocate_target_temps(self, env, rhs): self.allocate_subexpr_temps(env) - rhs.release_temp(rhs) + self.is_target = True + if rhs: + rhs.release_temp(env) self.release_subexpr_temps(env) def allocate_temps(self, env, result = None): + assert result is None, "deprecated, contact dagss if this triggers" self.allocate_subexpr_temps(env) - self.backwards_compatible_result = result if self.is_temp: self.release_subexpr_temps(env) @@ -604,39 +655,71 @@ else: self.release_subexpr_temps(env) - def pre_generate_result_code(self, code): - if self.is_temp: - type = self.type - if not type.is_void: - if type.is_pyobject: - type = PyrexTypes.py_object_type - if self.backwards_compatible_result: - self.temp_code = self.backwards_compatible_result - else: - self.temp_code = code.funcstate.allocate_temp(type) + def allocate_temp_result(self, code): + if self.temp_code: + raise RuntimeError("Temp allocated multiple times") + type = self.type + if not type.is_void: + if type.is_pyobject: + type = PyrexTypes.py_object_type + self.temp_code = code.funcstate.allocate_temp( + type, manage_ref=True) + else: + self.temp_code = None + + def release_temp_result(self, code): + if not self.temp_code: + if self.old_temp: + raise RuntimeError("temp %s released multiple times in %s" % ( + self.old_temp, self.__class__.__name__)) else: - self.temp_code = None + raise RuntimeError("no temp, but release requested in %s" % ( + self.__class__.__name__)) + code.funcstate.release_temp(self.temp_code) + self.old_temp = self.temp_code + self.temp_code = None + + def generate_evaluation_code(self, code): + code.mark_pos(self.pos) + + # 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) + + if self.is_temp: + self.allocate_temp_result(code) + + self.generate_result_code(code) + if self.is_temp: + # If we are temp we do not need to wait until this node is disposed + # before disposing children. + self.generate_subexpr_disposal_code(code) + self.free_subexpr_temps(code) def generate_disposal_code(self, code): if self.is_temp: if self.type.is_pyobject: code.put_decref_clear(self.result(), self.ctype()) - if not self.backwards_compatible_result: - code.funcstate.release_temp(self.temp_code) else: + # Already done if self.is_temp self.generate_subexpr_disposal_code(code) def generate_post_assignment_code(self, code): if self.is_temp: if self.type.is_pyobject: - code.putln("%s = 0;" % self.temp_code) - if not self.backwards_compatible_result: - code.funcstate.release_temp(self.temp_code) + code.putln("%s = 0;" % self.result()) else: self.generate_subexpr_disposal_code(code) - + def free_temps(self, code): + if self.is_temp: + if not self.type.is_void: + self.release_temp_result(code) + else: + self.free_subexpr_temps(code) +# ExprNode = NewTempExprNode class AtomicExprNode(ExprNode): # Abstract base class for expression nodes which have @@ -644,8 +727,24 @@ subexprs = [] +class AtomicNewTempExprNode(NewTempExprNode): + # I do not dare to convert NameNode yet. This is now + # ancestor of all former AtomicExprNode except + # NameNode. Should be renamed to AtomicExprNode + # when done. + + # Abstract base class for expression nodes which have + # no sub-expressions. + + subexprs = [] + + # Override to optimize -- we know we have no children + def generate_subexpr_evaluation_code(self, code): + pass + def generate_subexpr_disposal_code(self, code): + pass -class PyConstNode(AtomicExprNode): +class PyConstNode(AtomicNewTempExprNode): # Abstract base class for constant Python values. is_literal = 1 @@ -667,7 +766,9 @@ # The constant value None value = "Py_None" - + + constant_result = None + def compile_time_value(self, denv): return None @@ -676,11 +777,13 @@ value = "Py_Ellipsis" + constant_result = Ellipsis + def compile_time_value(self, denv): return Ellipsis -class ConstNode(AtomicExprNode): +class ConstNode(AtomicNewTempExprNode): # Abstract base type for literal constant nodes. # # value string C code fragment @@ -706,7 +809,10 @@ class BoolNode(ConstNode): type = PyrexTypes.c_bint_type # The constant value True or False - + + def calculate_constant_result(self): + self.constant_result = self.value + def compile_time_value(self, denv): return self.value @@ -716,10 +822,14 @@ class NullNode(ConstNode): type = PyrexTypes.c_null_ptr_type value = "NULL" + constant_result = 0 class CharNode(ConstNode): type = PyrexTypes.c_char_type + + def calculate_constant_result(self): + self.constant_result = ord(self.value) def compile_time_value(self, denv): return ord(self.value) @@ -738,7 +848,7 @@ type = PyrexTypes.c_long_type def coerce_to(self, dst_type, env): - if dst_type.is_numeric: + if dst_type.is_numeric and not dst_type.is_complex: self.type = PyrexTypes.c_long_type return self # Arrange for a Python version of the number to be pre-allocated @@ -761,6 +871,9 @@ else: return str(self.value) + self.unsigned + self.longness + def calculate_constant_result(self): + self.constant_result = int(self.value, 0) + def compile_time_value(self, denv): return int(self.value, 0) @@ -768,11 +881,16 @@ class FloatNode(ConstNode): type = PyrexTypes.c_double_type + def calculate_constant_result(self): + # calculating float values is usually not a good idea + #self.constant_result = float(self.value) + pass + def compile_time_value(self, denv): return float(self.value) def calculate_result_code(self): - strval = str(self.value) + strval = repr(float(self.value)) if strval == 'nan': return "(Py_HUGE_VAL * 0)" elif strval == 'inf': @@ -880,10 +998,13 @@ return self.cname -class LongNode(AtomicExprNode): +class LongNode(AtomicNewTempExprNode): # Python long integer literal # # value string + + def calculate_constant_result(self): + self.constant_result = long(self.value) def compile_time_value(self, denv): return long(self.value) @@ -897,35 +1018,64 @@ gil_message = "Constructing Python long int" - def generate_evaluation_code(self, code): + def generate_result_code(self, code): code.putln( - '%s = PyLong_FromString("%s", 0, 0); %s' % ( + '%s = PyLong_FromString((char *)"%s", 0, 0); %s' % ( self.result(), self.value, code.error_goto_if_null(self.result(), self.pos))) + code.put_gotref(self.py_result()) -class ImagNode(AtomicExprNode): +class ImagNode(AtomicNewTempExprNode): # Imaginary number literal # # value float imaginary part + type = PyrexTypes.c_double_complex_type + + def calculate_constant_result(self): + self.constant_result = complex(0.0, self.value) + def compile_time_value(self, denv): return complex(0.0, self.value) def analyse_types(self, env): - self.type = py_object_type - self.gil_check(env) - self.is_temp = 1 + self.type.create_declaration_utility_code(env) + + def coerce_to(self, dst_type, env): + # Arrange for a Python version of the number to be pre-allocated + # when coercing to a Python type. + if dst_type.is_pyobject: + self.is_temp = 1 + self.type = PyrexTypes.py_object_type + self.gil_check(env) + # 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 AtomicNewTempExprNode.coerce_to(self, dst_type, env) gil_message = "Constructing complex number" - def generate_evaluation_code(self, code): - code.putln( - "%s = PyComplex_FromDoubles(0.0, %s); %s" % ( - self.result(), - self.value, - code.error_goto_if_null(self.result(), self.pos))) + def calculate_result_code(self): + if self.type.is_pyobject: + return self.result() + elif self.c99_complex: + return "%rj" % float(self.value) + else: + return "%s(0, %r)" % (self.type.from_parts, float(self.value)) + + def generate_result_code(self, code): + if self.type.is_pyobject: + code.putln( + "%s = PyComplex_FromDoubles(0.0, %r); %s" % ( + self.result(), + float(self.value), + code.error_goto_if_null(self.result(), self.pos))) + code.put_gotref(self.py_result()) + else: + self.c99_complex = code.globalstate.directives['c99_complex'] + class NameNode(AtomicExprNode): @@ -1146,13 +1296,16 @@ namespace, self.interned_cname, code.error_goto_if_null(self.result(), self.pos))) + code.put_gotref(self.py_result()) + elif entry.is_local and False: # control flow not good enough yet assigned = entry.scope.control_flow.get_state((entry.name, 'initalized'), self.pos) if assigned is False: error(self.pos, "local variable '%s' referenced before assignment" % entry.name) elif not Options.init_local_none and assigned is None: - code.putln('if (%s == 0) { PyErr_SetString(PyExc_UnboundLocalError, "%s"); %s }' % (entry.cname, entry.name, code.error_goto(self.pos))) + code.putln('if (%s == 0) { PyErr_SetString(PyExc_UnboundLocalError, "%s"); %s }' % + (entry.cname, entry.name, code.error_goto(self.pos))) entry.scope.control_flow.set_state(self.pos, (entry.name, 'initalized'), True) def generate_assignment_code(self, rhs, code): @@ -1177,6 +1330,8 @@ namespace, self.interned_cname, rhs.py_result())) + rhs.generate_disposal_code(code) + rhs.free_temps(code) # in Py2.6+, we need to invalidate the method cache code.putln("PyType_Modified(%s);" % entry.scope.parent_type.typeptr_cname) @@ -1190,7 +1345,7 @@ print("NameNode.generate_assignment_code:") print("...generating disposal code for %s" % rhs) rhs.generate_disposal_code(code) - + rhs.free_temps(code) else: if self.type.is_buffer: # Generate code for doing the buffer release/acquisition. @@ -1208,6 +1363,8 @@ #print "...from", rhs ### #print "...LHS type", self.type, "ctype", self.ctype() ### #print "...RHS type", rhs.type, "ctype", rhs.ctype() ### + if entry.is_cglobal: + code.put_gotref(self.py_result()) if not self.lhs_of_first_assignment: if entry.is_local and not Options.init_local_none: initalized = entry.scope.control_flow.get_state((entry.name, 'initalized'), self.pos) @@ -1217,24 +1374,36 @@ code.put_xdecref(self.result(), self.ctype()) else: code.put_decref(self.result(), self.ctype()) + if entry.is_cglobal: + code.put_giveref(rhs.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 %s" % rhs) rhs.generate_post_assignment_code(code) + rhs.free_temps(code) def generate_acquire_buffer(self, rhs, code): - rhstmp = code.funcstate.allocate_temp(self.entry.type) + # rhstmp is only used in case the rhs is a complicated expression leading to + # the object, to avoid repeating the same C expression for every reference + # to the rhs. It does NOT hold a reference. + pretty_rhs = isinstance(rhs, NameNode) or rhs.is_temp + if pretty_rhs: + rhstmp = rhs.result_as(self.ctype()) + else: + rhstmp = code.funcstate.allocate_temp(self.entry.type, manage_ref=False) + code.putln('%s = %s;' % (rhstmp, rhs.result_as(self.ctype()))) + buffer_aux = self.entry.buffer_aux bufstruct = buffer_aux.buffer_info_var.cname - code.putln('%s = %s;' % (rhstmp, rhs.result_as(self.ctype()))) - import Buffer Buffer.put_assign_to_buffer(self.result(), rhstmp, buffer_aux, self.entry.type, is_initialized=not self.lhs_of_first_assignment, pos=self.pos, code=code) - code.putln("%s = 0;" % rhstmp) - code.funcstate.release_temp(rhstmp) + + if not pretty_rhs: + code.putln("%s = 0;" % rhstmp) + code.funcstate.release_temp(rhstmp) def generate_deletion_code(self, code): if self.entry is None: @@ -1243,7 +1412,7 @@ error(self.pos, "Deletion of local or C global name not supported") return code.put_error_if_neg(self.pos, - 'PyObject_DelAttrString(%s, "%s")' % ( + '__Pyx_DelAttrString(%s, "%s")' % ( Naming.module_cname, self.entry.name)) @@ -1271,12 +1440,17 @@ gil_message = "Backquote expression" + def calculate_constant_result(self): + self.constant_result = repr(self.arg.constant_result) + def generate_result_code(self, code): code.putln( "%s = PyObject_Repr(%s); %s" % ( self.result(), self.arg.py_result(), code.error_goto_if_null(self.result(), self.pos))) + code.put_gotref(self.py_result()) + class ImportNode(ExprNode): @@ -1313,10 +1487,15 @@ self.module_name.py_result(), name_list_code, code.error_goto_if_null(self.result(), self.pos))) + code.put_gotref(self.py_result()) -class IteratorNode(ExprNode): +class IteratorNode(NewTempExprNode): # Used as part of for statement implementation. + # + # allocate_counter_temp/release_counter_temp needs to be called + # by parent (ForInStatNode) + # # Implements result = iter(sequence) # # sequence ExprNode @@ -1329,37 +1508,49 @@ self.type = py_object_type self.gil_check(env) self.is_temp = 1 - - self.counter = TempNode(self.pos, PyrexTypes.c_py_ssize_t_type, env) - self.counter.allocate_temp(env) gil_message = "Iterating over Python object" - def release_temp(self, env): - env.release_temp(self.result()) - self.counter.release_temp(env) - + def allocate_counter_temp(self, code): + self.counter_cname = code.funcstate.allocate_temp( + PyrexTypes.c_py_ssize_t_type, manage_ref=False) + + def release_counter_temp(self, code): + code.funcstate.release_temp(self.counter_cname) + def generate_result_code(self, code): + is_builtin_sequence = self.sequence.type is list_type or \ + self.sequence.type is tuple_type + if is_builtin_sequence: + code.putln( + "if (likely(%s != Py_None)) {" % self.sequence.py_result()) + else: + code.putln( + "if (PyList_CheckExact(%s) || PyTuple_CheckExact(%s)) {" % ( + self.sequence.py_result(), + self.sequence.py_result())) code.putln( - "if (PyList_CheckExact(%s) || PyTuple_CheckExact(%s)) {" % ( - self.sequence.py_result(), - self.sequence.py_result())) - code.putln( - "%s = 0; %s = %s; Py_INCREF(%s);" % ( - self.counter.result(), + "%s = 0; %s = %s; __Pyx_INCREF(%s);" % ( + self.counter_cname, self.result(), self.sequence.py_result(), self.result())) code.putln("} else {") - code.putln("%s = -1; %s = PyObject_GetIter(%s); %s" % ( - self.counter.result(), - self.result(), - self.sequence.py_result(), - code.error_goto_if_null(self.result(), self.pos))) + if is_builtin_sequence: + code.putln( + 'PyErr_SetString(PyExc_TypeError, "\'NoneType\' object is not iterable"); %s' % + code.error_goto(self.pos)) + else: + code.putln("%s = -1; %s = PyObject_GetIter(%s); %s" % ( + self.counter_cname, + self.result(), + self.sequence.py_result(), + code.error_goto_if_null(self.result(), self.pos))) + code.put_gotref(self.py_result()) code.putln("}") -class NextNode(AtomicExprNode): +class NextNode(AtomicNewTempExprNode): # Used as part of for statement implementation. # Implements result = iterator.next() # Created during analyse_types phase. @@ -1374,23 +1565,35 @@ self.is_temp = 1 def generate_result_code(self, code): - for py_type in ["List", "Tuple"]: - code.putln( - "if (likely(Py%s_CheckExact(%s))) {" % (py_type, self.iterator.py_result())) + if self.iterator.sequence.type is list_type: + type_checks = [(list_type, "List")] + elif self.iterator.sequence.type is tuple_type: + type_checks = [(tuple_type, "Tuple")] + else: + type_checks = [(list_type, "List"), (tuple_type, "Tuple")] + + for py_type, prefix in type_checks: + if len(type_checks) > 1: + code.putln( + "if (likely(Py%s_CheckExact(%s))) {" % ( + prefix, self.iterator.py_result())) code.putln( "if (%s >= Py%s_GET_SIZE(%s)) break;" % ( - self.iterator.counter.result(), - py_type, + self.iterator.counter_cname, + prefix, self.iterator.py_result())) code.putln( - "%s = Py%s_GET_ITEM(%s, %s); Py_INCREF(%s); %s++;" % ( + "%s = Py%s_GET_ITEM(%s, %s); __Pyx_INCREF(%s); %s++;" % ( self.result(), - py_type, + prefix, self.iterator.py_result(), - self.iterator.counter.result(), + self.iterator.counter_cname, self.result(), - self.iterator.counter.result())) - code.put("} else ") + self.iterator.counter_cname)) + if len(type_checks) > 1: + code.put("} else ") + if len(type_checks) == 1: + return code.putln("{") code.putln( "%s = PyIter_Next(%s);" % ( @@ -1402,10 +1605,11 @@ code.putln(code.error_goto_if_PyErr(self.pos)) code.putln("break;") code.putln("}") + code.put_gotref(self.py_result()) code.putln("}") -class ExcValueNode(AtomicExprNode): +class ExcValueNode(AtomicNewTempExprNode): # Node created during analyse_types phase # of an ExceptClauseNode to fetch the current # exception value. @@ -1425,9 +1629,11 @@ pass -class TempNode(AtomicExprNode): +class TempNode(ExprNode): # Node created during analyse_types phase # of some nodes to hold a temporary value. + + subexprs = [] def __init__(self, pos, type, env): ExprNode.__init__(self, pos) @@ -1474,7 +1680,11 @@ def __init__(self, pos, index, *args, **kw): ExprNode.__init__(self, pos, index=index, *args, **kw) self._index = index - + + def calculate_constant_result(self): + self.constant_result = \ + self.base.constant_result[self.index.constant_result] + def compile_time_value(self, denv): base = self.base.compile_time_value(denv) index = self.index.compile_time_value(denv) @@ -1523,8 +1733,6 @@ if self.indices: indices = self.indices else: - # On cloning, indices is cloned. Otherwise, unpack index into indices - assert not isinstance(self.index, CloneNode) if isinstance(self.index, TupleNode): indices = self.index.args else: @@ -1537,6 +1745,9 @@ if not x.type.is_int: buffer_access = False + # On cloning, indices is cloned. Otherwise, unpack index into indices + assert not (buffer_access and isinstance(self.index, CloneNode)) + if buffer_access: self.indices = indices self.index = None @@ -1558,12 +1769,11 @@ self.index.analyse_types(env) self.original_index_type = self.index.type if self.base.type.is_pyobject: - if self.index.type.is_int and not self.index.type.is_longlong: + if self.index.type.is_int: self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env) else: 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: @@ -1580,9 +1790,21 @@ error(self.pos, "Invalid index type '%s'" % self.index.type) + self.gil_check(env) gil_message = "Indexing Python object" + def gil_check(self, env): + if self.is_buffer_access and env.nogil: + if env.directives['boundscheck']: + error(self.pos, "Cannot check buffer index bounds without gil; use boundscheck(False) directive") + return + elif self.type.is_pyobject: + error(self.pos, "Cannot access buffer with object dtype without gil") + return + super(IndexNode, self).gil_check(env) + + def check_const_addr(self): self.base.check_const_addr() self.index.check_const() @@ -1597,12 +1819,13 @@ return "(%s[%s])" % ( self.base.result(), self.index.result()) - def index_unsigned_parameter(self): + def extra_index_params(self): if self.index.type.is_int: if self.original_index_type.signed: - return ", 0" + size_adjustment = "" else: - return ", sizeof(Py_ssize_t) <= sizeof(%s)" % self.original_index_type.declaration_code("") + size_adjustment = "+1" + return ", sizeof(%s)%s, %s" % (self.original_index_type.declaration_code(""), size_adjustment, self.original_index_type.to_py_function) else: return "" @@ -1622,6 +1845,14 @@ for i in self.indices: i.generate_disposal_code(code) + def free_subexpr_temps(self, code): + self.base.free_temps(code) + if not self.indices: + self.index.free_temps(code) + else: + for i in self.indices: + i.free_temps(code) + def generate_result_code(self, code): if self.is_buffer_access: if code.globalstate.directives['nonecheck']: @@ -1630,11 +1861,16 @@ if self.type.is_pyobject: # is_temp is True, so must pull out value and incref it. code.putln("%s = *%s;" % (self.result(), self.buffer_ptr_code)) - code.putln("Py_INCREF((PyObject*)%s);" % self.result()) + code.putln("__Pyx_INCREF((PyObject*)%s);" % self.result()) elif self.type.is_pyobject: if self.index.type.is_int: - function = "__Pyx_GetItemInt" index_code = self.index.result() + if self.base.type is list_type: + function = "__Pyx_GetItemInt_List" + elif self.base.type is tuple_type: + function = "__Pyx_GetItemInt_Tuple" + else: + function = "__Pyx_GetItemInt" code.globalstate.use_utility_code(getitem_int_utility_code) else: function = "PyObject_GetItem" @@ -1646,25 +1882,36 @@ function, self.base.py_result(), index_code, - self.index_unsigned_parameter(), + self.extra_index_params(), self.result(), code.error_goto(self.pos))) - + code.put_gotref(self.py_result()) + def generate_setitem_code(self, value_code, code): if self.index.type.is_int: function = "__Pyx_SetItemInt" index_code = self.index.result() code.globalstate.use_utility_code(setitem_int_utility_code) else: - function = "PyObject_SetItem" index_code = self.index.py_result() + if self.base.type is dict_type: + function = "PyDict_SetItem" + # It would seem that we could specalized lists/tuples, but that + # shouldn't happen here. + # Both PyList_SetItem PyTuple_SetItem and a Py_ssize_t as input, + # not a PyObject*, and bad conversion here would give the wrong + # exception. Also, tuples are supposed to be immutable, and raise + # TypeErrors when trying to set their entries (PyTuple_SetItem + # is for creating new tuples from). + else: + function = "PyObject_SetItem" code.putln( "if (%s(%s, %s, %s%s) < 0) %s" % ( function, self.base.py_result(), index_code, value_code, - self.index_unsigned_parameter(), + self.extra_index_params(), code.error_goto(self.pos))) def generate_buffer_setitem_code(self, rhs, code, op=""): @@ -1675,18 +1922,15 @@ if self.buffer_type.dtype.is_pyobject: # Must manage refcounts. Decref what is already there # and incref what we put in. - ptr = code.funcstate.allocate_temp(self.buffer_type.buffer_ptr_type) - if rhs.is_temp: - rhs_code = code.funcstate.allocate_temp(rhs.type) - else: - rhs_code = rhs.result() + ptr = code.funcstate.allocate_temp(self.buffer_type.buffer_ptr_type, manage_ref=False) + rhs_code = rhs.result() code.putln("%s = %s;" % (ptr, ptrexpr)) - code.putln("Py_DECREF(*%s); Py_INCREF(%s);" % ( + code.put_gotref("*%s" % ptr) + code.putln("__Pyx_DECREF(*%s); __Pyx_INCREF(%s);" % ( ptr, rhs_code )) code.putln("*%s %s= %s;" % (ptr, op, rhs_code)) - if rhs.is_temp: - code.funcstate.release_temp(rhs_code) + code.put_giveref("*%s" % ptr) code.funcstate.release_temp(ptr) else: # Simple case @@ -1703,7 +1947,9 @@ "%s = %s;" % ( self.result(), rhs.result())) self.generate_subexpr_disposal_code(code) + self.free_subexpr_temps(code) rhs.generate_disposal_code(code) + rhs.free_temps(code) def generate_deletion_code(self, code): self.generate_subexpr_evaluation_code(code) @@ -1713,20 +1959,24 @@ index_code = self.index.result() code.globalstate.use_utility_code(delitem_int_utility_code) else: - function = "PyObject_DelItem" index_code = self.index.py_result() + if self.base.type is dict_type: + function = "PyDict_DelItem" + else: + function = "PyObject_DelItem" code.putln( "if (%s(%s, %s%s) < 0) %s" % ( function, self.base.py_result(), index_code, - self.index_unsigned_parameter(), + self.extra_index_params(), code.error_goto(self.pos))) self.generate_subexpr_disposal_code(code) + self.free_subexpr_temps(code) def buffer_lookup_code(self, code): # Assign indices to temps - index_temps = [code.funcstate.allocate_temp(i.type) for i in self.indices] + index_temps = [code.funcstate.allocate_temp(i.type, manage_ref=False) for i in self.indices] for temp, index in zip(index_temps, self.indices): code.putln("%s = %s;" % (temp, index.result())) # Generate buffer access code using these temps @@ -1736,7 +1986,7 @@ return Buffer.put_buffer_lookup_code(entry=self.base.entry, index_signeds=[i.type.signed for i in self.indices], index_cnames=index_temps, - options=code.globalstate.directives, + directives=code.globalstate.directives, pos=self.pos, code=code) def put_nonecheck(self, code): @@ -1754,7 +2004,11 @@ # stop ExprNode or None subexprs = ['base', 'start', 'stop'] - + + def calculate_constant_result(self): + self.constant_result = self.base.constant_result[ + self.start.constant_result : self.stop.constant_result] + def compile_time_value(self, denv): base = self.base.compile_time_value(denv) if self.start is None: @@ -1772,6 +2026,12 @@ def analyse_target_declaration(self, env): pass + + def analyse_target_types(self, env): + self.analyse_types(env) + # when assigning, we must accept any Python type + if self.type.is_pyobject: + self.type = py_object_type def analyse_types(self, env): self.base.analyse_types(env) @@ -1779,39 +2039,101 @@ self.start.analyse_types(env) if self.stop: self.stop.analyse_types(env) - self.base = self.base.coerce_to_pyobject(env) + base_type = self.base.type + if base_type.is_string: + self.type = bytes_type + elif base_type.is_array or base_type.is_ptr: + # we need a ptr type here instead of an array type, as + # array types can result in invalid type casts in the C + # code + self.type = PyrexTypes.CPtrType(base_type.base_type) + else: + self.base = self.base.coerce_to_pyobject(env) + self.type = py_object_type + if base_type.is_builtin_type: + # slicing builtin types returns something of the same type + self.type = base_type 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): - code.putln( - "%s = PySequence_GetSlice(%s, %s, %s); %s" % ( - self.result(), - self.base.py_result(), - self.start_code(), - self.stop_code(), - code.error_goto_if_null(self.result(), self.pos))) + if not self.type.is_pyobject: + error(self.pos, + "Slicing is not currently supported for '%s'." % self.type) + return + if self.base.type.is_string: + if self.stop is None: + code.putln( + "%s = __Pyx_PyBytes_FromString(%s + %s); %s" % ( + self.result(), + self.base.result(), + self.start_code(), + code.error_goto_if_null(self.result(), self.pos))) + else: + code.putln( + "%s = __Pyx_PyBytes_FromStringAndSize(%s + %s, %s - %s); %s" % ( + self.result(), + self.base.result(), + self.start_code(), + self.stop_code(), + self.start_code(), + code.error_goto_if_null(self.result(), self.pos))) + else: + code.putln( + "%s = PySequence_GetSlice(%s, %s, %s); %s" % ( + self.result(), + self.base.py_result(), + self.start_code(), + self.stop_code(), + code.error_goto_if_null(self.result(), self.pos))) + code.put_gotref(self.py_result()) def generate_assignment_code(self, rhs, code): self.generate_subexpr_evaluation_code(code) - code.put_error_if_neg(self.pos, - "PySequence_SetSlice(%s, %s, %s, %s)" % ( - self.base.py_result(), - self.start_code(), - self.stop_code(), - rhs.result())) + if self.type.is_pyobject: + code.put_error_if_neg(self.pos, + "PySequence_SetSlice(%s, %s, %s, %s)" % ( + self.base.py_result(), + self.start_code(), + self.stop_code(), + rhs.result())) + else: + start_offset = '' + if self.start: + start_offset = self.start_code() + if start_offset == '0': + start_offset = '' + else: + start_offset += '+' + if rhs.type.is_array: + array_length = rhs.type.size + self.generate_slice_guard_code(code, array_length) + else: + error(self.pos, + "Slice assignments from pointers are not yet supported.") + # FIXME: fix the array size according to start/stop + array_length = self.base.type.size + for i in range(array_length): + code.putln("%s[%s%s] = %s[%d];" % ( + self.base.result(), start_offset, i, + rhs.result(), i)) self.generate_subexpr_disposal_code(code) + self.free_subexpr_temps(code) rhs.generate_disposal_code(code) + rhs.free_temps(code) def generate_deletion_code(self, code): + if not self.base.type.is_pyobject: + error(self.pos, + "Deleting slices is only supported for Python types, not '%s'." % self.type) + return self.generate_subexpr_evaluation_code(code) code.put_error_if_neg(self.pos, "PySequence_DelSlice(%s, %s, %s)" % ( @@ -1819,6 +2141,54 @@ self.start_code(), self.stop_code())) self.generate_subexpr_disposal_code(code) + + def generate_slice_guard_code(self, code, target_size): + if not self.base.type.is_array: + return + slice_size = self.base.type.size + start = stop = None + if self.stop: + stop = self.stop.result() + try: + stop = int(stop) + if stop < 0: + slice_size = self.base.type.size + stop + else: + slice_size = stop + stop = None + except ValueError: + pass + if self.start: + start = self.start.result() + try: + start = int(start) + if start < 0: + start = self.base.type.size + start + slice_size -= start + start = None + except ValueError: + pass + check = None + if slice_size < 0: + if target_size > 0: + error(self.pos, "Assignment to empty slice.") + elif start is None and stop is None: + # we know the exact slice length + if target_size != slice_size: + error(self.pos, "Assignment to slice of wrong length, expected %d, got %d" % ( + slice_size, target_size)) + elif start is not None: + if stop is None: + stop = slice_size + check = "(%s)-(%s)" % (stop, start) + else: # stop is not None: + check = stop + if check: + code.putln("if (unlikely((%s) != %d)) {" % (check, target_size)) + code.putln('PyErr_Format(PyExc_ValueError, "Assignment to slice of wrong length, expected %%"PY_FORMAT_SIZE_T"d, got %%"PY_FORMAT_SIZE_T"d", (Py_ssize_t)%d, (Py_ssize_t)(%s));' % ( + target_size, check)) + code.putln(code.error_goto(self.pos)) + code.putln("}") def start_code(self): if self.start: @@ -1829,6 +2199,8 @@ def stop_code(self): if self.stop: return self.stop.result() + elif self.base.type.is_array: + return self.base.type.size else: return "PY_SSIZE_T_MAX" @@ -1843,7 +2215,13 @@ # start ExprNode # stop ExprNode # step ExprNode - + + def calculate_constant_result(self): + self.constant_result = self.base.constant_result[ + self.start.constant_result : \ + self.stop.constant_result : \ + self.step.constant_result] + def compile_time_value(self, denv): start = self.start.compile_time_value(denv) if self.stop is None: @@ -1882,9 +2260,10 @@ self.stop.py_result(), self.step.py_result(), code.error_goto_if_null(self.result(), self.pos))) + code.put_gotref(self.py_result()) -class CallNode(ExprNode): +class CallNode(NewTempExprNode): def gil_check(self, env): # Make sure we're not in a nogil environment if env.nogil: @@ -2042,12 +2421,12 @@ "Python object cannot be passed as a varargs parameter") # Calc result type and code fragment self.type = func_type.return_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 + if self.type.is_pyobject: + self.result_ctype = py_object_type + self.is_temp = 1 + elif func_type.exception_value is not None \ + or func_type.exception_check: + self.is_temp = 1 # C++ exception handler if func_type.exception_check == '+': if func_type.exception_value is None: @@ -2086,7 +2465,7 @@ 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, ", ")) + ', '.join(arg_list_code)) # if self.wrapper_call or \ # self.function.entry.is_unbound_cmethod and self.function.entry.type.is_overridable: # result = "(%s = 1, %s)" % (Naming.skip_dispatch_cname, result) @@ -2102,6 +2481,7 @@ self.function.py_result(), arg_code, code.error_goto_if_null(self.result(), self.pos))) + code.put_gotref(self.py_result()) elif func_type.is_cfunction: if self.has_optional_args: actual_nargs = len(self.args) @@ -2133,7 +2513,7 @@ 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" ### + # "from", return_type, "to pyobject" ### rhs = typecast(py_object_type, self.type, rhs) else: lhs = "" @@ -2156,6 +2536,9 @@ else: goto_error = "" code.putln("%s%s; %s" % (lhs, rhs, goto_error)) + if self.type.is_pyobject and self.result(): + code.put_gotref(self.py_result()) + class GeneralCallNode(CallNode): # General Python function call, including keyword, @@ -2194,7 +2577,11 @@ self.keyword_args.analyse_types(env) if self.starstar_arg: self.starstar_arg.analyse_types(env) - self.function = self.function.coerce_to_pyobject(env) + if not self.function.type.is_pyobject: + if hasattr(self.function, 'entry') and not self.function.entry.as_variable: + error(self.pos, "Keyword arguments not allowed in cdef functions.") + else: + self.function = self.function.coerce_to_pyobject(env) self.positional_args = \ self.positional_args.coerce_to_pyobject(env) if self.starstar_arg: @@ -2231,6 +2618,7 @@ self.result(), call_code, code.error_goto_if_null(self.result(), self.pos))) + code.put_gotref(self.py_result()) class AsTupleNode(ExprNode): @@ -2240,6 +2628,9 @@ # arg ExprNode subexprs = ['arg'] + + def calculate_constant_result(self): + self.constant_result = tuple(self.base.constant_result) def compile_time_value(self, denv): arg = self.arg.compile_time_value(denv) @@ -2251,7 +2642,7 @@ def analyse_types(self, env): self.arg.analyse_types(env) self.arg = self.arg.coerce_to_pyobject(env) - self.type = py_object_type + self.type = tuple_type self.gil_check(env) self.is_temp = 1 @@ -2263,9 +2654,10 @@ self.result(), self.arg.py_result(), code.error_goto_if_null(self.result(), self.pos))) + code.put_gotref(self.py_result()) -class AttributeNode(ExprNode): +class AttributeNode(NewTempExprNode): # obj.attribute # # obj ExprNode @@ -2305,14 +2697,20 @@ self.analyse_as_python_attribute(env) return self return ExprNode.coerce_to(self, dst_type, env) - + + def calculate_constant_result(self): + attr = self.attribute + if attr.startswith("__") and attr.endswith("__"): + return + self.constant_result = getattr(self.obj.constant_result, attr) + def compile_time_value(self, denv): attr = self.attribute - if attr.beginswith("__") and attr.endswith("__"): - self.error("Invalid attribute name '%s' in compile-time expression" - % attr) + if attr.startswith("__") and attr.endswith("__"): + error(self.pos, + "Invalid attribute name '%s' in compile-time expression" % attr) return None - obj = self.arg.compile_time_value(denv) + obj = self.obj.compile_time_value(denv) try: return getattr(obj, attr) except Exception, e: @@ -2414,7 +2812,7 @@ pass ## Reference to C array turns into pointer to first element. #while self.type.is_array: - # self.type = self.type.element_ptr_type() + # self.type = self.type.element_ptr_type() if self.is_py_attr: if not target: self.is_temp = 1 @@ -2515,6 +2913,8 @@ obj.type.vtabslot_cname, self.member) else: return self.member + elif obj.type.is_complex: + return "__Pyx_%s_PART(%s)" % (self.member.upper(), obj_code) else: return "%s%s%s" % (obj_code, self.op, self.member) @@ -2526,6 +2926,7 @@ self.obj.py_result(), self.interned_attr_cname, code.error_goto_if_null(self.result(), self.pos))) + code.put_gotref(self.py_result()) else: # result_code contains what is needed, but we may need to insert # a check and raise an exception @@ -2543,6 +2944,7 @@ self.interned_attr_cname, rhs.py_result())) rhs.generate_disposal_code(code) + rhs.free_temps(code) else: if (self.obj.type.is_extension_type and self.needs_none_check @@ -2552,6 +2954,8 @@ select_code = self.result() if self.type.is_pyobject: rhs.make_owned_reference(code) + code.put_giveref(rhs.py_result()) + code.put_gotref(select_code) code.put_decref(select_code, self.ctype()) code.putln( "%s = %s;" % ( @@ -2559,7 +2963,9 @@ rhs.result_as(self.ctype()))) #rhs.result())) rhs.generate_post_assignment_code(code) + rhs.free_temps(code) self.obj.generate_disposal_code(code) + self.obj.free_temps(code) def generate_deletion_code(self, code): self.obj.generate_evaluation_code(code) @@ -2571,6 +2977,7 @@ else: error(self.pos, "Cannot delete C attribute of extension type") self.obj.generate_disposal_code(code) + self.obj.free_temps(code) def annotate(self, code): if self.is_py_attr: @@ -2592,7 +2999,7 @@ # #------------------------------------------------------------------- -class SequenceNode(ExprNode): +class SequenceNode(NewTempExprNode): # Base class for list and tuple constructor nodes. # Contains common code for performing sequence unpacking. # @@ -2637,74 +3044,100 @@ def allocate_target_temps(self, env, rhs): self.iterator.allocate_temps(env) - for arg, node in zip(self.args, self.coerced_unpacked_items): + for node in self.coerced_unpacked_items: node.allocate_temps(env) - arg.allocate_target_temps(env, node) #arg.release_target_temp(env) #node.release_temp(env) + for arg in self.args: + arg.allocate_target_temps(env, None) if rhs: rhs.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) + for node in self.coerced_unpacked_items: + node.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): + # Need to work around the fact that generate_evaluation_code + # allocates the temps in a rather hacky way -- the assignment + # is evaluated twice, within each if-block. + + if rhs.type is tuple_type: + tuple_check = "likely(%s != Py_None)" + else: + tuple_check = "PyTuple_CheckExact(%s)" code.putln( - "if (PyTuple_CheckExact(%s) && PyTuple_GET_SIZE(%s) == %s) {" % ( - rhs.py_result(), + "if (%s && likely(PyTuple_GET_SIZE(%s) == %s)) {" % ( + tuple_check % rhs.py_result(), rhs.py_result(), len(self.args))) code.putln("PyObject* tuple = %s;" % rhs.py_result()) for i in range(len(self.args)): item = self.unpacked_items[i] - code.putln( - "%s = PyTuple_GET_ITEM(tuple, %s);" % ( + code.put( + "%s = PyTuple_GET_ITEM(tuple, %s); " % ( item.result(), i)) code.put_incref(item.result(), item.ctype()) value_node = self.coerced_unpacked_items[i] value_node.generate_evaluation_code(code) - self.args[i].generate_assignment_code(value_node, code) - rhs.generate_disposal_code(code) - code.putln("}") - code.putln("else {") - code.putln( - "%s = PyObject_GetIter(%s); %s" % ( - self.iterator.result(), - rhs.py_result(), - code.error_goto_if_null(self.iterator.result(), self.pos))) - rhs.generate_disposal_code(code) for i in range(len(self.args)): - item = self.unpacked_items[i] - unpack_code = "__Pyx_UnpackItem(%s, %d)" % ( - self.iterator.py_result(), i) + self.args[i].generate_assignment_code( + self.coerced_unpacked_items[i], code) + + code.putln("} else {") + + if rhs.type is tuple_type: + code.globalstate.use_utility_code(tuple_unpacking_error_code) + code.putln("__Pyx_UnpackTupleError(%s, %s);" % ( + rhs.py_result(), len(self.args))) + code.putln(code.error_goto(self.pos)) + else: code.putln( - "%s = %s; %s" % ( - item.result(), - typecast(item.ctype(), py_object_type, unpack_code), - code.error_goto_if_null(item.result(), 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.put_error_if_neg(self.pos, - "__Pyx_EndUnpack(%s)" % ( - self.iterator.py_result())) - if debug_disposal_code: - print("UnpackNode.generate_assignment_code:") - print("...generating disposal code for %s" % self.iterator) - self.iterator.generate_disposal_code(code) + "%s = PyObject_GetIter(%s); %s" % ( + self.iterator.result(), + rhs.py_result(), + code.error_goto_if_null(self.iterator.result(), self.pos))) + code.put_gotref(self.iterator.py_result()) + rhs.generate_disposal_code(code) + for i in range(len(self.args)): + item = self.unpacked_items[i] + unpack_code = "__Pyx_UnpackItem(%s, %d)" % ( + self.iterator.py_result(), i) + code.putln( + "%s = %s; %s" % ( + item.result(), + typecast(item.ctype(), py_object_type, unpack_code), + code.error_goto_if_null(item.result(), self.pos))) + code.put_gotref(item.py_result()) + value_node = self.coerced_unpacked_items[i] + value_node.generate_evaluation_code(code) + code.put_error_if_neg(self.pos, + "__Pyx_EndUnpack(%s)" % ( + self.iterator.py_result())) + if debug_disposal_code: + print("UnpackNode.generate_assignment_code:") + print("...generating disposal code for %s" % self.iterator) + self.iterator.generate_disposal_code(code) + self.iterator.free_temps(code) + + for i in range(len(self.args)): + self.args[i].generate_assignment_code( + self.coerced_unpacked_items[i], code) code.putln("}") + rhs.free_temps(code) def annotate(self, code): for arg in self.args: @@ -2735,6 +3168,10 @@ else: return Naming.empty_tuple + def calculate_constant_result(self): + self.constant_result = tuple([ + arg.constant_result for arg in self.args]) + def compile_time_value(self, denv): values = self.compile_time_value_list(denv) try: @@ -2751,6 +3188,7 @@ self.result(), len(self.args), code.error_goto_if_null(self.result(), self.pos))) + code.put_gotref(self.py_result()) for i in range(len(self.args)): arg = self.args[i] if not arg.result_in_temp(): @@ -2760,13 +3198,16 @@ self.result(), i, arg.py_result())) + code.put_giveref(arg.py_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) + arg.generate_post_assignment_code(code) + # Should NOT call free_temps -- this is invoked by the default + # generate_evaluation_code which will do that. class ListNode(SequenceNode): @@ -2778,7 +3219,7 @@ gil_message = "Constructing Python list" def analyse_expressions(self, env): - ExprNode.analyse_expressions(self, env) + SequenceNode.analyse_expressions(self, env) self.coerce_to_pyobject(env) def analyse_types(self, env): @@ -2828,6 +3269,10 @@ else: SequenceNode.release_temp(self, env) + def calculate_constant_result(self): + self.constant_result = [ + arg.constant_result for arg in self.args] + def compile_time_value(self, denv): return self.compile_time_value_list(denv) @@ -2839,6 +3284,7 @@ (self.result(), len(self.args), code.error_goto_if_null(self.result(), self.pos))) + code.put_gotref(self.py_result()) for i in range(len(self.args)): arg = self.args[i] #if not arg.is_temp: @@ -2848,6 +3294,7 @@ (self.result(), i, arg.py_result())) + code.put_giveref(arg.py_result()) elif self.type.is_array: for i, arg in enumerate(self.args): code.putln("%s[%s] = %s;" % ( @@ -2862,64 +3309,141 @@ arg.result())) else: raise InternalError("List type never specified") - + 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 ListComprehensionNode(SequenceNode): + arg.generate_post_assignment_code(code) + # Should NOT call free_temps -- this is invoked by the default + # generate_evaluation_code which will do that. - subexprs = [] - is_sequence_constructor = 0 # not unpackable +class ComprehensionNode(NewTempExprNode): + subexprs = ["target"] child_attrs = ["loop", "append"] - def analyse_types(self, env): - self.type = list_type - self.is_temp = 1 + def analyse_types(self, env): + self.target.analyse_expressions(env) + self.type = self.target.type self.append.target = self # this is a CloneNode used in the PyList_Append in the inner loop - + self.loop.analyse_declarations(env) + def allocate_temps(self, env, result = None): if debug_temp_alloc: print("%s Allocating temps" % self) self.allocate_temp(env, result) - self.loop.analyse_declarations(env) + # call loop.analyse_expressions() now to make sure temps get + # allocated at the right time self.loop.analyse_expressions(env) - + + def calculate_result_code(self): + return self.target.result() + + def generate_result_code(self, code): + self.generate_operation_code(code) + def generate_operation_code(self, code): - code.putln("%s = PyList_New(%s); %s" % - (self.result(), - 0, - code.error_goto_if_null(self.result(), self.pos))) self.loop.generate_execution_code(code) - + def annotate(self, code): self.loop.annotate(code) -class ListComprehensionAppendNode(ExprNode): - +class ComprehensionAppendNode(NewTempExprNode): # Need to be careful to avoid infinite recursion: # target must not be in child_attrs/subexprs subexprs = ['expr'] def analyse_types(self, env): self.expr.analyse_types(env) - if self.expr.type != py_object_type: + if not self.expr.type.is_pyobject: self.expr = self.expr.coerce_to_pyobject(env) self.type = PyrexTypes.c_int_type self.is_temp = 1 + + def generate_result_code(self, code): + if self.target.type is list_type: + function = "PyList_Append" + elif self.target.type is set_type: + function = "PySet_Add" + else: + raise InternalError( + "Invalid type for comprehension node: %s" % self.target.type) + + code.putln("%s = %s(%s, (PyObject*)%s); %s" % + (self.result(), + function, + self.target.result(), + self.expr.result(), + code.error_goto_if(self.result(), self.pos))) + +class DictComprehensionAppendNode(ComprehensionAppendNode): + subexprs = ['key_expr', 'value_expr'] + def analyse_types(self, env): + self.key_expr.analyse_types(env) + if not self.key_expr.type.is_pyobject: + self.key_expr = self.key_expr.coerce_to_pyobject(env) + self.value_expr.analyse_types(env) + if not self.value_expr.type.is_pyobject: + self.value_expr = self.value_expr.coerce_to_pyobject(env) + self.type = PyrexTypes.c_int_type + self.is_temp = 1 + def generate_result_code(self, code): - code.putln("%s = PyList_Append(%s, (PyObject*)%s); %s" % + code.putln("%s = PyDict_SetItem(%s, (PyObject*)%s, (PyObject*)%s); %s" % (self.result(), - self.target.result(), - self.expr.result(), - code.error_goto_if(self.result(), self.pos))) + self.target.result(), + self.key_expr.result(), + self.value_expr.result(), + code.error_goto_if(self.result(), self.pos))) + + +class SetNode(NewTempExprNode): + # Set constructor. + + subexprs = ['args'] + + gil_message = "Constructing Python set" + + 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 = set_type + self.gil_check(env) + self.is_temp = 1 + + def calculate_constant_result(self): + self.constant_result = set([ + arg.constant_result for arg in self.args]) + + def compile_time_value(self, denv): + values = [arg.compile_time_value(denv) for arg in self.args] + try: + return set(values) + except Exception, e: + self.compile_time_value_error(e) + + def generate_evaluation_code(self, code): + code.globalstate.use_utility_code(Builtin.py23_set_utility_code) + self.allocate_temp_result(code) + code.putln( + "%s = PySet_New(0); %s" % ( + self.result(), + code.error_goto_if_null(self.result(), self.pos))) + code.put_gotref(self.py_result()) + for arg in self.args: + arg.generate_evaluation_code(code) + code.putln( + code.error_goto_if_neg( + "PySet_Add(%s, %s)" % (self.result(), arg.py_result()), + self.pos)) + arg.generate_disposal_code(code) + arg.free_temps(code) class DictNode(ExprNode): @@ -2930,6 +3454,10 @@ # obj_conversion_errors [PyrexError] used internally subexprs = ['key_value_pairs'] + + def calculate_constant_result(self): + self.constant_result = dict([ + item.constant_result for item in self.key_value_pairs]) def compile_time_value(self, denv): pairs = [(item.key.compile_time_value(denv), item.value.compile_time_value(denv)) @@ -3006,6 +3534,7 @@ "%s = PyDict_New(); %s" % ( self.result(), code.error_goto_if_null(self.result(), self.pos))) + code.put_gotref(self.py_result()) for item in self.key_value_pairs: item.generate_evaluation_code(code) if self.type.is_pyobject: @@ -3020,6 +3549,7 @@ item.key.value, item.value.result())) item.generate_disposal_code(code) + item.free_temps(code) def annotate(self, code): for item in self.key_value_pairs: @@ -3031,6 +3561,10 @@ # key ExprNode # value ExprNode subexprs = ['key', 'value'] + + def calculate_constant_result(self): + self.constant_result = ( + self.key.constant_result, self.value.constant_result) def analyse_types(self, env): self.key.analyse_types(env) @@ -3041,10 +3575,14 @@ def generate_evaluation_code(self, code): self.key.generate_evaluation_code(code) self.value.generate_evaluation_code(code) - + def generate_disposal_code(self, code): self.key.generate_disposal_code(code) self.value.generate_disposal_code(code) + + def free_temps(self, code): + self.key.free_temps(code) + self.value.free_temps(code) def __iter__(self): return iter([self.key, self.value]) @@ -3092,6 +3630,7 @@ self.cname, self.module_name, code.error_goto_if_null(self.result(), self.pos))) + code.put_gotref(self.py_result()) class UnboundMethodNode(ExprNode): @@ -3119,9 +3658,9 @@ self.function.py_result(), self.class_cname, code.error_goto_if_null(self.result(), self.pos))) + code.put_gotref(self.py_result()) - -class PyCFunctionNode(AtomicExprNode): +class PyCFunctionNode(AtomicNewTempExprNode): # Helper class used in the implementation of Python # class definitions. Constructs a PyCFunction object # from a PyMethodDef struct. @@ -3141,6 +3680,7 @@ self.result(), self.pymethdef_cname, code.error_goto_if_null(self.result(), self.pos))) + code.put_gotref(self.py_result()) #------------------------------------------------------------------- # @@ -3168,6 +3708,11 @@ # - Allocate temporary for result if needed. subexprs = ['operand'] + infix = True + + def calculate_constant_result(self): + func = compile_time_unary_operators[self.operator] + self.constant_result = func(self.operand.constant_result) def compile_time_value(self, denv): func = compile_time_unary_operators.get(self.operator) @@ -3215,6 +3760,7 @@ function, self.operand.py_result(), code.error_goto_if_null(self.result(), self.pos))) + code.put_gotref(self.py_result()) def type_error(self): if not self.operand.type.is_error: @@ -3227,7 +3773,10 @@ # 'not' operator # # operand ExprNode - + + def calculate_constant_result(self): + self.constant_result = not self.operand.constant_result + def compile_time_value(self, denv): operand = self.operand.compile_time_value(denv) try: @@ -3274,13 +3823,17 @@ self.type = self.operand.type else: self.type_error() + if self.type.is_complex: + self.infix = env.directives['c99_complex'] def py_operation_function(self): return "PyNumber_Negative" def calculate_result_code(self): - return "(-%s)" % self.operand.result() - + if self.infix: + return "(-%s)" % self.operand.result() + else: + return "%s(%s)" % (self.operand.type.unary_op('-'), self.operand.result()) class TildeNode(UnopNode): # unary '~' operator @@ -3349,7 +3902,7 @@ operand = operand) -class TypecastNode(ExprNode): +class TypecastNode(NewTempExprNode): # C type cast # # operand ExprNode @@ -3377,15 +3930,18 @@ error(self.pos, "Casting temporary Python object to non-numeric non-Python type") if to_py and not from_py: if (self.operand.type.to_py_function and - self.operand.type.create_convert_utility_code(env)): + self.operand.type.create_to_py_utility_code(env)): self.result_ctype = py_object_type self.operand = self.operand.coerce_to_pyobject(env) else: - warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.operand.type, self.type)) + if not (self.operand.type.is_ptr and self.operand.type.base_type.is_void): + warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.operand.type, self.type)) self.operand = self.operand.coerce_to_simple(env) elif from_py and not to_py: if self.type.from_py_function: self.operand = self.operand.coerce_to(self.type, env) + elif self.type.is_ptr and not (self.type.base_type.is_void or self.type.base_type.is_struct): + error(self.pos, "Python objects cannot be casted to pointers of primitive types") else: warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.type, self.operand.type)) elif from_py and to_py: @@ -3394,6 +3950,11 @@ def check_const(self): self.operand.check_const() + + def calculate_constant_result(self): + # we usually do not know the result of a type cast at code + # generation time + pass def calculate_result_code(self): opnd = self.operand @@ -3418,7 +3979,7 @@ class SizeofNode(ExprNode): # Abstract base class for sizeof(x) expression nodes. - type = PyrexTypes.c_int_type + type = PyrexTypes.c_size_t_type def check_const(self): pass @@ -3558,7 +4119,13 @@ # - Allocate temporary for result if needed. subexprs = ['operand1', 'operand2'] - + + def calculate_constant_result(self): + func = compile_time_binary_operators[self.operator] + self.constant_result = func( + self.operand1.constant_result, + self.operand2.constant_result) + def compile_time_value(self, denv): func = get_compile_time_binop(self) operand1 = self.operand1.compile_time_value(denv) @@ -3609,6 +4176,7 @@ self.operand2.py_result(), extra_args, code.error_goto_if_null(self.result(), self.pos))) + code.put_gotref(self.py_result()) else: if self.is_temp: self.generate_c_operation_code(code) @@ -3625,16 +4193,20 @@ class NumBinopNode(BinopNode): # Binary operation taking numeric arguments. + infix = True + 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() + return + if self.type.is_complex and not env.directives['c99_complex']: + self.infix = False + if not self.infix: + self.operand1 = self.operand1.coerce_to(self.type, env) + self.operand2 = self.operand2.coerce_to(self.type, env) def compute_c_result_type(self, type1, type2): if self.c_types_okay(type1, type2): @@ -3648,26 +4220,35 @@ 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()) + if self.infix: + return "(%s %s %s)" % ( + self.operand1.result(), + self.operator, + self.operand2.result()) + else: + func = self.type.binary_op(self.operator) + if func is None: + error(self.pos, "binary operator %s not supported for %s" % (self.operator, self.type)) + return "%s(%s, %s)" % ( + func, + self.operand1.result(), + 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", - "/": "__Pyx_PyNumber_Divide", - "//": "PyNumber_FloorDivide", - "%": "PyNumber_Remainder", + "|": "PyNumber_Or", + "^": "PyNumber_Xor", + "&": "PyNumber_And", + "<<": "PyNumber_Lshift", + ">>": "PyNumber_Rshift", + "+": "PyNumber_Add", + "-": "PyNumber_Subtract", + "*": "PyNumber_Multiply", + "/": "__Pyx_PyNumber_Divide", + "//": "PyNumber_FloorDivide", + "%": "PyNumber_Remainder", "**": "PyNumber_Power" } @@ -3728,72 +4309,181 @@ return NumBinopNode.is_py_operation(self) -class FloorDivNode(NumBinopNode): - # '//' operator. +class DivNode(NumBinopNode): + # '/' or '//' operator. + + cdivision = None + cdivision_warnings = False + zerodivision_check = None + + def analyse_types(self, env): + NumBinopNode.analyse_types(self, env) + if not self.type.is_pyobject: + self.zerodivision_check = self.cdivision is None and not env.directives['cdivision'] + if self.zerodivision_check or env.directives['cdivision_warnings']: + # Need to check ahead of time to warn or raise zero division error + self.operand1 = self.operand1.coerce_to_simple(env) + self.operand2 = self.operand2.coerce_to_simple(env) + if env.nogil: + error(self.pos, "Pythonic division not allowed without gil, consider using cython.cdivision(True)") + + def zero_division_message(self): + if self.type.is_int: + return "integer division or modulo by zero" + else: + return "float division" + + def generate_evaluation_code(self, code): + if not self.type.is_pyobject and not self.type.is_complex: + if self.cdivision is None: + self.cdivision = (code.globalstate.directives['cdivision'] + or not self.type.signed + or self.type.is_float) + if not self.cdivision: + code.globalstate.use_utility_code(div_int_utility_code.specialize(self.type)) + NumBinopNode.generate_evaluation_code(self, code) + self.generate_div_warning_code(code) + + def generate_div_warning_code(self, code): + if not self.type.is_pyobject: + if self.zerodivision_check: + if not self.infix: + zero_test = "%s(%s)" % (self.type.unary_op('zero'), self.operand2.result()) + else: + zero_test = "%s == 0" % self.operand2.result() + code.putln("if (unlikely(%s)) {" % zero_test) + code.putln('PyErr_Format(PyExc_ZeroDivisionError, "%s");' % self.zero_division_message()) + code.putln(code.error_goto(self.pos)) + code.putln("}") + if self.type.is_int and self.type.signed and self.operator != '%': + code.globalstate.use_utility_code(division_overflow_test_code) + code.putln("else if (sizeof(%s) == sizeof(long) && unlikely(%s == -1) && unlikely(UNARY_NEG_WOULD_OVERFLOW(%s))) {" % ( + self.type.declaration_code(''), + self.operand2.result(), + self.operand1.result())) + code.putln('PyErr_Format(PyExc_OverflowError, "value too large to perform division");') + code.putln(code.error_goto(self.pos)) + code.putln("}") + if code.globalstate.directives['cdivision_warnings'] and self.operator != '/': + code.globalstate.use_utility_code(cdivision_warning_utility_code) + code.putln("if ((%s < 0) ^ (%s < 0)) {" % ( + self.operand1.result(), + self.operand2.result())) + code.putln(code.set_error_info(self.pos)); + code.put("if (__Pyx_cdivision_warning()) ") + code.put_goto(code.error_label) + code.putln("}") def calculate_result_code(self): - return "(%s %s %s)" % ( - self.operand1.result(), - "/", # c division is by default floor-div - self.operand2.result()) + if self.type.is_complex: + return NumBinopNode.calculate_result_code(self) + elif self.type.is_float and self.operator == '//': + return "floor(%s / %s)" % ( + self.operand1.result(), + self.operand2.result()) + elif self.cdivision: + return "(%s / %s)" % ( + self.operand1.result(), + self.operand2.result()) + else: + return "__Pyx_div_%s(%s, %s)" % ( + self.type.specalization_name(), + self.operand1.result(), + self.operand2.result()) -class ModNode(NumBinopNode): +class ModNode(DivNode): # '%' operator. - + def is_py_operation(self): return (self.operand1.type.is_string or self.operand2.type.is_string or NumBinopNode.is_py_operation(self)) - def calculate_result_code(self): - if self.operand1.type.is_float or self.operand2.type.is_float: - return "fmod(%s, %s)" % ( - self.operand1.result(), - self.operand2.result()) + def zero_division_message(self): + if self.type.is_int: + return "integer division or modulo by zero" else: - return "(%s %% %s)" % ( - self.operand1.result(), - self.operand2.result()) + return "float divmod()" + + def generate_evaluation_code(self, code): + if not self.type.is_pyobject: + if self.cdivision is None: + self.cdivision = code.globalstate.directives['cdivision'] or not self.type.signed + if not self.cdivision: + if self.type.is_int: + code.globalstate.use_utility_code(mod_int_utility_code.specialize(self.type)) + else: + code.globalstate.use_utility_code( + mod_float_utility_code.specialize(self.type, math_h_modifier=self.type.math_h_modifier)) + NumBinopNode.generate_evaluation_code(self, code) + self.generate_div_warning_code(code) + + def calculate_result_code(self): + if self.cdivision: + if self.type.is_float: + return "fmod%s(%s, %s)" % ( + self.type.math_h_modifier, + self.operand1.result(), + self.operand2.result()) + else: + return "(%s %% %s)" % ( + self.operand1.result(), + self.operand2.result()) + else: + return "__Pyx_mod_%s(%s, %s)" % ( + self.type.specalization_name(), + self.operand1.result(), + self.operand2.result()) class PowNode(NumBinopNode): # '**' operator. - - def compute_c_result_type(self, type1, type2): - if self.c_types_okay(type1, type2): - return PyrexTypes.c_double_type - else: - return None - - def c_types_okay(self, type1, type2): - return (type1.is_float or type2.is_float) and \ - NumBinopNode.c_types_okay(self, type1, type2) - - def type_error(self): - if not (self.operand1.type.is_error or self.operand2.type.is_error): - if self.operand1.type.is_int and self.operand2.type.is_int: - error(self.pos, "C has no integer powering, use python ints or floats instead '%s' (%s; %s)" % - (self.operator, self.operand1.type, self.operand2.type)) - else: - NumBinopNode.type_error(self) - self.type = PyrexTypes.error_type + + def analyse_c_operation(self, env): + NumBinopNode.analyse_c_operation(self, env) + if self.type.is_complex: + error(self.pos, "complex powers not yet supported") + self.pow_func = "" + elif self.type.is_float: + self.pow_func = "pow" + else: + self.pow_func = "__Pyx_pow_%s" % self.type.declaration_code('').replace(' ', '_') + env.use_utility_code( + int_pow_utility_code.specialize(func_name=self.pow_func, + type=self.type.declaration_code(''))) def calculate_result_code(self): - return "pow(%s, %s)" % ( - self.operand1.result(), self.operand2.result()) + return "%s(%s, %s)" % ( + self.pow_func, + self.operand1.result(), + self.operand2.result()) -class BoolBinopNode(ExprNode): +# Note: This class is temporary "shut down" into an ineffective mode temp +# allocation mode. +# +# More sophisticated temp reuse was going on before, +# one could have a look at adding this again after /all/ classes +# are converted to the new temp scheme. (The temp juggling cannot work +# otherwise). +class BoolBinopNode(NewTempExprNode): # Short-circuiting boolean operation. # # operator string # operand1 ExprNode # operand2 ExprNode - # temp_bool ExprNode used internally - temp_bool = None - - subexprs = ['operand1', 'operand2', 'temp_bool'] + subexprs = ['operand1', 'operand2'] + + def calculate_constant_result(self): + if self.operator == 'and': + self.constant_result = \ + self.operand1.constant_result and \ + self.operand2.constant_result + else: + self.constant_result = \ + self.operand1.constant_result or \ + self.operand2.constant_result def compile_time_value(self, denv): if self.operator == 'and': @@ -3816,42 +4506,41 @@ 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_bint_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_bint_type + + # Below disabled for + # 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.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()) - if self.temp_bool: - self.temp_bool.allocate_temp(env) - self.temp_bool.release_temp(env) - self.operand2.allocate_temps(env, self.result()) - # 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 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()) +## self.operand2.allocate_temps(env, self.result()) +## # 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() @@ -3866,8 +4555,9 @@ py_to_c_op = {'and': "&&", 'or': "||"} def generate_evaluation_code(self, code): + code.mark_pos(self.pos) self.operand1.generate_evaluation_code(code) - test_result = self.generate_operand1_test(code) + test_result, uses_temp = self.generate_operand1_test(code) if self.operator == 'and': sense = "" else: @@ -3876,15 +4566,27 @@ "if (%s%s) {" % ( sense, test_result)) + if uses_temp: + code.funcstate.release_temp(test_result) self.operand1.generate_disposal_code(code) self.operand2.generate_evaluation_code(code) - code.putln( - "}") + self.allocate_temp_result(code) + self.operand2.make_owned_reference(code) + code.putln("%s = %s;" % (self.result(), self.operand2.result())) + self.operand2.generate_post_assignment_code(code) + self.operand2.free_temps(code) + code.putln("} else {") + self.operand1.make_owned_reference(code) + code.putln("%s = %s;" % (self.result(), self.operand1.result())) + self.operand1.generate_post_assignment_code(code) + self.operand1.free_temps(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() + test_result = code.funcstate.allocate_temp(PyrexTypes.c_bint_type, + manage_ref=False) code.putln( "%s = __Pyx_PyObject_IsTrue(%s); %s" % ( test_result, @@ -3892,7 +4594,7 @@ code.error_goto_if_neg(test_result, self.pos))) else: test_result = self.operand1.result() - return test_result + return (test_result, self.type.is_pyobject) class CondExprNode(ExprNode): @@ -3902,12 +4604,17 @@ # true_val ExprNode # false_val ExprNode - temp_bool = None true_val = None false_val = None subexprs = ['test', 'true_val', 'false_val'] - + + def calculate_constant_result(self): + if self.test.constant_result: + self.constant_result = self.true_val.constant_result + else: + self.constant_result = self.false_val.constant_result + def analyse_types(self, env): self.test.analyse_types(env) self.test = self.test.coerce_to_boolean(env) @@ -3917,32 +4624,9 @@ if self.true_val.type.is_pyobject or self.false_val.type.is_pyobject: self.true_val = self.true_val.coerce_to(self.type, env) self.false_val = self.false_val.coerce_to(self.type, env) - # must be tmp variables so they can share a result - self.true_val = self.true_val.coerce_to_temp(env) - self.false_val = self.false_val.coerce_to_temp(env) self.is_temp = 1 if self.type == PyrexTypes.error_type: self.type_error() - - def allocate_temps(self, env, result_code = None): - # We only ever evaluate one side, and this is - # after evaluating the truth value, so we may - # 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.test.allocate_temps(env, result_code) - self.true_val.allocate_temps(env, self.result()) - self.false_val.allocate_temps(env, self.result()) - # We haven't called release_temp on either value, - # 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 compute_result_type(self, type1, type2): if type1 == type2: @@ -3974,13 +4658,26 @@ self.false_val.check_const() def generate_evaluation_code(self, code): + # Because subexprs may not be evaluated we can use a more optimal + # subexpr allocation strategy than the default, so override evaluation_code. + + code.mark_pos(self.pos) + #self.allocate_temp_result(code) # uncomment this when we switch to new temps self.test.generate_evaluation_code(code) code.putln("if (%s) {" % self.test.result() ) - self.true_val.generate_evaluation_code(code) + self.eval_and_get(code, self.true_val) code.putln("} else {") - self.false_val.generate_evaluation_code(code) + self.eval_and_get(code, self.false_val) code.putln("}") self.test.generate_disposal_code(code) + self.test.free_temps(code) + + def eval_and_get(self, code, expr): + expr.generate_evaluation_code(code) + expr.make_owned_reference(code) + code.putln("%s = %s;" % (self.result(), expr.result())) + expr.generate_post_assignment_code(code) + expr.free_temps(code) richcmp_constants = { "<" : "Py_LT", @@ -3992,9 +4689,18 @@ ">=": "Py_GE", } -class CmpNode: +class CmpNode(object): # Mixin class containing code common to PrimaryCmpNodes # and CascadedCmpNodes. + + def calculate_cascaded_constant_result(self, operand1_result): + func = compile_time_binary_operators[self.operator] + operand2_result = self.operand2.constant_result + result = func(operand1_result, operand2_result) + if result and self.cascade: + result = result and \ + self.cascade.cascaded_compile_time_value(operand2_result) + self.constant_result = result def cascaded_compile_time_value(self, operand1, denv): func = get_compile_time_binop(self) @@ -4007,6 +4713,7 @@ if result: cascade = self.cascade if cascade: + # FIXME: I bet this must call cascaded_compile_time_value() result = result and cascade.compile_time_value(operand2, denv) return result @@ -4020,7 +4727,13 @@ or (self.cascade and self.cascade.is_python_result())) def check_types(self, env, operand1, op, operand2): - if not self.types_okay(operand1, op, operand2): + if operand1.type.is_complex or operand2.type.is_complex: + if op not in ('==', '!='): + error(self.pos, "complex types unordered") + common_type = PyrexTypes.widest_numeric_type(operand1.type, operand2.type) + self.operand1 = operand1.coerce_to(common_type, env) + self.operand2 = operand2.coerce_to(common_type, env) + elif not self.types_okay(operand1, op, operand2): error(self.pos, "Invalid types for '%s' (%s, %s)" % (self.operator, operand1.type, operand2.type)) @@ -4068,6 +4781,17 @@ operand2.py_result(), richcmp_constants[op], code.error_goto_if_null(result_code, self.pos))) + code.put_gotref(result_code) + elif operand1.type.is_complex and not code.globalstate.directives['c99_complex']: + if op == "!=": negation = "!" + else: negation = "" + code.putln("%s = %s(%s%s(%s, %s));" % ( + result_code, + coerce_result, + negation, + operand1.type.unary_op('eq'), + operand1.result(), + operand2.result())) else: type1 = operand1.type type2 = operand2.type @@ -4096,7 +4820,7 @@ return op -class PrimaryCmpNode(ExprNode, CmpNode): +class PrimaryCmpNode(NewTempExprNode, CmpNode): # Non-cascaded comparison or first comparison of # a cascaded sequence. # @@ -4113,6 +4837,10 @@ child_attrs = ['operand1', 'operand2', 'cascade'] cascade = None + + def calculate_constant_result(self): + self.constant_result = self.calculate_cascaded_constant_result( + self.operand1.constant_result) def compile_time_value(self, denv): operand1 = self.operand1.compile_time_value(denv) @@ -4191,29 +4919,49 @@ self.not_const() def calculate_result_code(self): - return "(%s %s %s)" % ( - self.operand1.result(), - self.c_operator(self.operator), - self.operand2.result()) - + if self.operand1.type.is_complex: + if self.operator == "!=": + negation = "!" + else: + negation = "" + return "(%s%s(%s, %s))" % ( + negation, + self.operand1.type.binary_op('=='), + self.operand1.result(), + self.operand2.result()) + else: + 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: + self.allocate_temp_result(code) self.generate_operation_code(code, self.result(), self.operand1, self.operator, self.operand2) if self.cascade: self.cascade.generate_evaluation_code(code, self.result(), self.operand2) self.operand1.generate_disposal_code(code) + self.operand1.free_temps(code) self.operand2.generate_disposal_code(code) - + self.operand2.free_temps(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) + def free_subexpr_temps(self, code): + # If this is called, it is a non-cascaded cmp, + # so only need to dispose of the two main operands. + self.operand1.free_temps(code) + self.operand2.free_temps(code) + def annotate(self, code): self.operand1.annotate(code) self.operand2.annotate(code) @@ -4234,7 +4982,8 @@ child_attrs = ['operand2', 'cascade'] cascade = None - + constant_result = constant_value_not_set # FIXME: where to calculate this? + def analyse_types(self, env, operand1): self.operand2.analyse_types(env) if self.cascade: @@ -4280,6 +5029,7 @@ def generate_evaluation_code(self, code, result, operand1): if self.type.is_pyobject: code.putln("if (__Pyx_PyObject_IsTrue(%s)) {" % result) + code.put_decref(result, self.type) else: code.putln("if (%s) {" % result) self.operand2.generate_evaluation_code(code) @@ -4290,6 +5040,7 @@ code, result, self.operand2) # Cascaded cmp result is always temp self.operand2.generate_disposal_code(code) + self.operand2.free_temps(code) code.putln("}") def annotate(self, code): @@ -4299,20 +5050,20 @@ binop_node_classes = { - "or": BoolBinopNode, - "and": BoolBinopNode, - "|": IntBinopNode, - "^": IntBinopNode, - "&": IntBinopNode, - "<<": IntBinopNode, - ">>": IntBinopNode, - "+": AddNode, - "-": SubNode, - "*": MulNode, - "/": NumBinopNode, - "//": FloorDivNode, - "%": ModNode, - "**": PowNode + "or": BoolBinopNode, + "and": BoolBinopNode, + "|": IntBinopNode, + "^": IntBinopNode, + "&": IntBinopNode, + "<<": IntBinopNode, + ">>": IntBinopNode, + "+": AddNode, + "-": SubNode, + "*": MulNode, + "/": DivNode, + "//": DivNode, + "%": ModNode, + "**": PowNode } def binop_node(pos, operator, operand1, operand2): @@ -4334,7 +5085,7 @@ # #------------------------------------------------------------------- -class CoercionNode(ExprNode): +class CoercionNode(NewTempExprNode): # Abstract base class for coercion nodes. # # arg ExprNode node being coerced @@ -4346,6 +5097,10 @@ self.arg = arg if debug_coercion: print("%s Coercing %s" % (self, self.arg)) + + def calculate_constant_result(self): + # constant folding can break type coercion, so this is disabled + pass def annotate(self, code): self.arg.annotate(code) @@ -4381,8 +5136,6 @@ self.type = dst_type self.gil_check(env) self.result_ctype = arg.ctype() - if not dst_type.is_builtin_type: - env.use_utility_code(type_test_utility_code) gil_message = "Python type test" @@ -4400,6 +5153,8 @@ def generate_result_code(self, code): if self.type.typeobj_is_available(): + if not self.type.is_builtin_type: + code.globalstate.use_utility_code(type_test_utility_code) code.putln( "if (!(%s)) %s" % ( self.type.type_test_code(self.arg.py_result()), @@ -4410,6 +5165,9 @@ def generate_post_assignment_code(self, code): self.arg.generate_post_assignment_code(code) + + def free_temps(self, code): + self.arg.free_temps(code) class CoerceToPyTypeNode(CoercionNode): @@ -4421,7 +5179,7 @@ self.type = py_object_type self.gil_check(env) self.is_temp = 1 - if not arg.type.to_py_function or not arg.type.create_convert_utility_code(env): + if not arg.type.create_to_py_utility_code(env): error(arg.pos, "Cannot convert '%s' to Python object" % arg.type) @@ -4429,6 +5187,13 @@ def coerce_to_boolean(self, env): return self.arg.coerce_to_boolean(env).coerce_to_temp(env) + + def coerce_to_integer(self, env): + # If not already some C integer type, coerce to longint. + if self.arg.type.is_int: + return self.arg + else: + return self.arg.coerce_to(PyrexTypes.c_long_type, env) def analyse_types(self, env): # The arg is always already analysed @@ -4441,6 +5206,7 @@ function, self.arg.result(), code.error_goto_if_null(self.result(), self.pos))) + code.put_gotref(self.py_result()) class CoerceFromPyTypeNode(CoercionNode): @@ -4451,7 +5217,7 @@ CoercionNode.__init__(self, arg) self.type = result_type self.is_temp = 1 - if not result_type.from_py_function: + if not result_type.create_from_py_utility_code(env): error(arg.pos, "Cannot convert Python object to '%s'" % result_type) if self.type.is_string and self.arg.is_ephemeral(): @@ -4472,6 +5238,8 @@ self.result(), rhs, code.error_goto_if(self.type.error_condition(self.result()), self.pos))) + if self.type.is_pyobject: + code.put_gotref(self.py_result()) class CoerceToBooleanNode(CoercionNode): @@ -4504,6 +5272,29 @@ self.arg.py_result(), code.error_goto_if_neg(self.result(), self.pos))) +class CoerceToComplexNode(CoercionNode): + + def __init__(self, arg, dst_type, env): + if arg.type.is_complex: + arg = arg.coerce_to_simple(env) + self.type = dst_type + CoercionNode.__init__(self, arg) + dst_type.create_declaration_utility_code(env) + + def calculate_result_code(self): + if self.arg.type.is_complex: + real_part = "__Pyx_REAL_PART(%s)" % self.arg.result() + imag_part = "__Pyx_IMAG_PART(%s)" % self.arg.result() + else: + real_part = self.arg.result() + imag_part = "0" + return "%s(%s, %s)" % ( + self.type.from_parts, + real_part, + imag_part) + + def generate_result_code(self, code): + pass class CoerceToTempNode(CoercionNode): # This node is used to force the result of another node @@ -4581,66 +5372,11 @@ def release_temp(self, env): pass - -class PersistentNode(ExprNode): - # A PersistentNode is like a CloneNode except it handles the temporary - # allocation itself by keeping track of the number of times it has been - # used. - - subexprs = ["arg"] - temp_counter = 0 - generate_counter = 0 - analyse_counter = 0 - result_code = None - - def __init__(self, arg, uses): - self.pos = arg.pos - self.arg = arg - self.uses = uses - - def analyse_types(self, env): - if self.analyse_counter == 0: - self.arg.analyse_types(env) - self.type = self.arg.type - self.result_ctype = self.arg.result_ctype - self.is_temp = 1 - self.analyse_counter += 1 - - def calculate_result_code(self): - return self.result() - def generate_evaluation_code(self, code): - if self.generate_counter == 0: - self.arg.generate_evaluation_code(code) - code.putln("%s = %s;" % ( - self.result(), self.arg.result_as(self.ctype()))) - if self.type.is_pyobject: - code.put_incref(self.result(), self.ctype()) - self.arg.generate_disposal_code(code) - self.generate_counter += 1 - - def generate_disposal_code(self, code): - if self.generate_counter == self.uses: - if self.type.is_pyobject: - code.put_decref_clear(self.result(), self.ctype()) + def free_temps(self, code): + pass + - def allocate_temps(self, env, result=None): - if self.temp_counter == 0: - self.arg.allocate_temps(env) - self.allocate_temp(env, result) - self.arg.release_temp(env) - self.temp_counter += 1 - - def allocate_temp(self, env, result=None): - if result is None: - self.result_code = env.allocate_temp(self.type) - else: - self.result_code = result - - def release_temp(self, env): - if self.temp_counter == self.uses: - env.release_temp(self.result()) - #------------------------------------------------------------------------------------ # # Runtime support code @@ -4675,7 +5411,7 @@ PyObject *global_dict = 0; PyObject *empty_dict = 0; PyObject *list; - __import__ = PyObject_GetAttrString(%(BUILTINS)s, "__import__"); + __import__ = __Pyx_GetAttrString(%(BUILTINS)s, "__import__"); if (!__import__) goto bad; if (from_list) @@ -4692,8 +5428,8 @@ empty_dict = PyDict_New(); if (!empty_dict) goto bad; - module = PyObject_CallFunction(__import__, "OOOO", - name, global_dict, empty_dict, list); + module = PyObject_CallFunctionObjArgs(__import__, + name, global_dict, empty_dict, list, NULL); bad: Py_XDECREF(empty_list); Py_XDECREF(__import__); @@ -4751,43 +5487,6 @@ #------------------------------------------------------------------------------------ -unpacking_utility_code = UtilityCode( -proto = """ -static PyObject *__Pyx_UnpackItem(PyObject *, Py_ssize_t index); /*proto*/ -static int __Pyx_EndUnpack(PyObject *); /*proto*/ -""", -impl = """ -static PyObject *__Pyx_UnpackItem(PyObject *iter, Py_ssize_t index) { - PyObject *item; - if (!(item = PyIter_Next(iter))) { - if (!PyErr_Occurred()) { - PyErr_Format(PyExc_ValueError, - #if PY_VERSION_HEX < 0x02050000 - "need more than %d values to unpack", (int)index); - #else - "need more than %zd values to unpack", index); - #endif - } - } - return item; -} - -static int __Pyx_EndUnpack(PyObject *iter) { - PyObject *item; - if ((item = PyIter_Next(iter))) { - Py_DECREF(item); - PyErr_SetString(PyExc_ValueError, "too many values to unpack"); - return -1; - } - else if (!PyErr_Occurred()) - return 0; - else - return -1; -} -""") - -#------------------------------------------------------------------------------------ - type_test_utility_code = UtilityCode( proto = """ static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/ @@ -4810,11 +5509,11 @@ create_class_utility_code = UtilityCode( proto = """ -static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, char *modname); /*proto*/ +static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, const char *modname); /*proto*/ """, impl = """ static PyObject *__Pyx_CreateClass( - PyObject *bases, PyObject *dict, PyObject *name, char *modname) + PyObject *bases, PyObject *dict, PyObject *name, const char *modname) { PyObject *py_modname; PyObject *result = 0; @@ -4874,10 +5573,15 @@ if (likely(PyList_CheckExact(L))) { if (PyList_Append(L, x) < 0) return NULL; Py_INCREF(Py_None); - return Py_None; // this is just to have an accurate signature + return Py_None; /* this is just to have an accurate signature */ } else { - return PyObject_CallMethod(L, "append", "(O)", x); + PyObject *r, *m; + m = __Pyx_GetAttrString(L, "append"); + if (!m) return NULL; + r = PyObject_CallFunctionObjArgs(m, x, NULL); + Py_DECREF(m); + return r; } } """, @@ -4891,24 +5595,58 @@ getitem_int_utility_code = UtilityCode( proto = """ -static INLINE PyObject *__Pyx_GetItemInt(PyObject *o, Py_ssize_t i, int is_unsigned) { + +static INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) { + PyObject *r; + if (!j) return NULL; + r = PyObject_GetItem(o, j); + Py_DECREF(j); + return r; +} + +""" + ''.join([ +""" +#define __Pyx_GetItemInt_%(type)s(o, i, size, to_py_func) ((size <= sizeof(Py_ssize_t)) ? \\ + __Pyx_GetItemInt_%(type)s_Fast(o, i, size <= sizeof(long)) : \\ + __Pyx_GetItemInt_Generic(o, to_py_func(i))) + +static INLINE PyObject *__Pyx_GetItemInt_%(type)s_Fast(PyObject *o, Py_ssize_t i, int fits_long) { + if (likely(o != Py_None)) { + if (likely((0 <= i) & (i < Py%(type)s_GET_SIZE(o)))) { + PyObject *r = Py%(type)s_GET_ITEM(o, i); + Py_INCREF(r); + return r; + } + else if ((-Py%(type)s_GET_SIZE(o) <= i) & (i < 0)) { + PyObject *r = Py%(type)s_GET_ITEM(o, Py%(type)s_GET_SIZE(o) + i); + Py_INCREF(r); + return r; + } + } + return __Pyx_GetItemInt_Generic(o, fits_long ? PyInt_FromLong(i) : PyLong_FromLongLong(i)); +} +""" % {'type' : type_name} for type_name in ('List', 'Tuple') +]) + """ + +#define __Pyx_GetItemInt(o, i, size, to_py_func) ((size <= sizeof(Py_ssize_t)) ? \\ + __Pyx_GetItemInt_Fast(o, i, size <= sizeof(long)) : \\ + __Pyx_GetItemInt_Generic(o, to_py_func(i))) + +static INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int fits_long) { PyObject *r; - if (PyList_CheckExact(o) && 0 <= i && i < PyList_GET_SIZE(o)) { + if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) { r = PyList_GET_ITEM(o, i); Py_INCREF(r); } - else if (PyTuple_CheckExact(o) && 0 <= i && i < PyTuple_GET_SIZE(o)) { + else if (PyTuple_CheckExact(o) && ((0 <= i) & (i < PyTuple_GET_SIZE(o)))) { r = PyTuple_GET_ITEM(o, i); Py_INCREF(r); } - else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_item && (likely(i >= 0) || !is_unsigned)) + else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_item && (likely(i >= 0))) { r = PySequence_GetItem(o, i); + } else { - PyObject *j = (likely(i >= 0) || !is_unsigned) ? PyInt_FromLong(i) : PyLong_FromUnsignedLongLong((sizeof(unsigned long long) > sizeof(Py_ssize_t) ? (1ULL << (sizeof(Py_ssize_t)*8)) : 0) + i); - if (!j) - return 0; - r = PyObject_GetItem(o, j); - Py_DECREF(j); + r = __Pyx_GetItemInt_Generic(o, fits_long ? PyInt_FromLong(i) : PyLong_FromLongLong(i)); } return r; } @@ -4916,28 +5654,37 @@ impl = """ """) + + #------------------------------------------------------------------------------------ setitem_int_utility_code = UtilityCode( proto = """ -static INLINE int __Pyx_SetItemInt(PyObject *o, Py_ssize_t i, PyObject *v, int is_unsigned) { +#define __Pyx_SetItemInt(o, i, v, size, to_py_func) ((size <= sizeof(Py_ssize_t)) ? \\ + __Pyx_SetItemInt_Fast(o, i, v, size <= sizeof(long)) : \\ + __Pyx_SetItemInt_Generic(o, to_py_func(i), v)) + +static INLINE int __Pyx_SetItemInt_Generic(PyObject *o, PyObject *j, PyObject *v) { int r; - if (PyList_CheckExact(o) && 0 <= i && i < PyList_GET_SIZE(o)) { - Py_DECREF(PyList_GET_ITEM(o, i)); + if (!j) return -1; + r = PyObject_SetItem(o, j, v); + Py_DECREF(j); + return r; +} + +static INLINE int __Pyx_SetItemInt_Fast(PyObject *o, Py_ssize_t i, PyObject *v, int fits_long) { + if (PyList_CheckExact(o) && ((0 <= i) & (i < PyList_GET_SIZE(o)))) { Py_INCREF(v); + Py_DECREF(PyList_GET_ITEM(o, i)); PyList_SET_ITEM(o, i, v); return 1; } - else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && (likely(i >= 0) || !is_unsigned)) - r = PySequence_SetItem(o, i, v); + else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && (likely(i >= 0))) + return PySequence_SetItem(o, i, v); else { - PyObject *j = (likely(i >= 0) || !is_unsigned) ? PyInt_FromLong(i) : PyLong_FromUnsignedLongLong((sizeof(unsigned long long) > sizeof(Py_ssize_t) ? (1ULL << (sizeof(Py_ssize_t)*8)) : 0) + i); - if (!j) - return -1; - r = PyObject_SetItem(o, j, v); - Py_DECREF(j); + PyObject *j = fits_long ? PyInt_FromLong(i) : PyLong_FromLongLong(i); + return __Pyx_SetItemInt_Generic(o, j, v); } - return r; } """, impl = """ @@ -4947,18 +5694,25 @@ delitem_int_utility_code = UtilityCode( proto = """ -static INLINE int __Pyx_DelItemInt(PyObject *o, Py_ssize_t i, int is_unsigned) { +#define __Pyx_DelItemInt(o, i, size, to_py_func) ((size <= sizeof(Py_ssize_t)) ? \\ + __Pyx_DelItemInt_Fast(o, i, size <= sizeof(long)) : \\ + __Pyx_DelItem_Generic(o, to_py_func(i))) + +static INLINE int __Pyx_DelItem_Generic(PyObject *o, PyObject *j) { int r; - if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && (likely(i >= 0) || !is_unsigned)) - r = PySequence_DelItem(o, i); + if (!j) return -1; + r = PyObject_DelItem(o, j); + Py_DECREF(j); + return r; +} + +static INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i, int fits_long) { + if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && likely(i >= 0)) + return PySequence_DelItem(o, i); else { - PyObject *j = (likely(i >= 0) || !is_unsigned) ? PyInt_FromLong(i) : PyLong_FromUnsignedLongLong((sizeof(unsigned long long) > sizeof(Py_ssize_t) ? (1ULL << (sizeof(Py_ssize_t)*8)) : 0) + i); - if (!j) - return -1; - r = PyObject_DelItem(o, j); - Py_DECREF(j); + PyObject *j = fits_long ? PyInt_FromLong(i) : PyLong_FromLongLong(i); + return __Pyx_DelItem_Generic(o, j); } - return r; } """, impl = """ @@ -4968,20 +5722,206 @@ raise_noneattr_error_utility_code = UtilityCode( proto = """ -static INLINE void __Pyx_RaiseNoneAttributeError(char* attrname); +static INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname); """, -impl = """ -static INLINE void __Pyx_RaiseNoneAttributeError(char* attrname) { +impl = ''' +static INLINE void __Pyx_RaiseNoneAttributeError(const char* attrname) { PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", attrname); } -""") +''') raise_noneindex_error_utility_code = UtilityCode( proto = """ -static INLINE void __Pyx_RaiseNoneIndexingError(); +static INLINE void __Pyx_RaiseNoneIndexingError(void); """, -impl = """ -static INLINE void __Pyx_RaiseNoneIndexingError() { +impl = ''' +static INLINE void __Pyx_RaiseNoneIndexingError(void) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is unsubscriptable"); } +''') + +raise_none_iter_error_utility_code = UtilityCode( +proto = """ +static INLINE void __Pyx_RaiseNoneNotIterableError(void); +""", +impl = ''' +static INLINE void __Pyx_RaiseNoneNotIterableError(void) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is iterable"); +} +''') + +raise_too_many_values_to_unpack = UtilityCode( +proto = """ +static INLINE void __Pyx_RaiseTooManyValuesError(void); +""", +impl = ''' +static INLINE void __Pyx_RaiseTooManyValuesError(void) { + PyErr_SetString(PyExc_ValueError, "too many values to unpack"); +} +''') + +raise_need_more_values_to_unpack = UtilityCode( +proto = """ +static INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); +""", +impl = ''' +static INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { + PyErr_Format(PyExc_ValueError, + #if PY_VERSION_HEX < 0x02050000 + "need more than %d value%s to unpack", (int)index, + #else + "need more than %zd value%s to unpack", index, + #endif + (index == 1) ? "" : "s"); +} +''') + +#------------------------------------------------------------------------------------ + +tuple_unpacking_error_code = UtilityCode( +proto = """ +static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index); /*proto*/ +""", +impl = """ +static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) { + if (t == Py_None) { + __Pyx_RaiseNoneNotIterableError(); + } else if (PyTuple_GET_SIZE(t) < index) { + __Pyx_RaiseNeedMoreValuesError(PyTuple_GET_SIZE(t)); + } else { + __Pyx_RaiseTooManyValuesError(); + } +} +""", +requires = [raise_none_iter_error_utility_code, + raise_need_more_values_to_unpack, + raise_too_many_values_to_unpack] +) + +unpacking_utility_code = UtilityCode( +proto = """ +static PyObject *__Pyx_UnpackItem(PyObject *, Py_ssize_t index); /*proto*/ +static int __Pyx_EndUnpack(PyObject *); /*proto*/ +""", +impl = """ +static PyObject *__Pyx_UnpackItem(PyObject *iter, Py_ssize_t index) { + PyObject *item; + if (!(item = PyIter_Next(iter))) { + if (!PyErr_Occurred()) { + __Pyx_RaiseNeedMoreValuesError(index); + } + } + return item; +} + +static int __Pyx_EndUnpack(PyObject *iter) { + PyObject *item; + if ((item = PyIter_Next(iter))) { + Py_DECREF(item); + __Pyx_RaiseTooManyValuesError(); + return -1; + } + else if (!PyErr_Occurred()) + return 0; + else + return -1; +} +""", +requires = [raise_need_more_values_to_unpack, + raise_too_many_values_to_unpack] +) + + +#------------------------------------------------------------------------------------ + +int_pow_utility_code = UtilityCode( +proto=""" +static INLINE %(type)s %(func_name)s(%(type)s, %(type)s); /* proto */ +""", +impl=""" +static INLINE %(type)s %(func_name)s(%(type)s b, %(type)s e) { + %(type)s t = b; + switch (e) { + case 3: + t *= b; + case 2: + t *= b; + case 1: + return t; + case 0: + return 1; + } + if (unlikely(e<0)) return 0; + t = 1; + while (likely(e)) { + t *= (b * (e&1)) | ((~e)&1); /* 1 or b */ + b *= b; + e >>= 1; + } + return t; +} +""") + +# ------------------------------ Division ------------------------------------ + +div_int_utility_code = UtilityCode( +proto=""" +static INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s, %(type)s); /* proto */ +""", +impl=""" +static INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s a, %(type)s b) { + %(type)s q = a / b; + %(type)s r = a - q*b; + q -= ((r != 0) & ((r ^ b) < 0)); + return q; +} +""") + +mod_int_utility_code = UtilityCode( +proto=""" +static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */ +""", +impl=""" +static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) { + %(type)s r = a %% b; + r += ((r != 0) & ((r ^ b) < 0)) * b; + return r; +} +""") + +mod_float_utility_code = UtilityCode( +proto=""" +static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */ +""", +impl=""" +static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) { + %(type)s r = fmod%(math_h_modifier)s(a, b); + r += ((r != 0) & ((r < 0) ^ (b < 0))) * b; + return r; +} +""") + +cdivision_warning_utility_code = UtilityCode( +proto=""" +static int __Pyx_cdivision_warning(void); /* proto */ +""", +impl=""" +static int __Pyx_cdivision_warning(void) { + return PyErr_WarnExplicit(PyExc_RuntimeWarning, + "division with oppositely signed operands, C and Python semantics differ", + %(FILENAME)s, + %(LINENO)s, + __Pyx_MODULE_NAME, + NULL); +} +""" % { + 'FILENAME': Naming.filename_cname, + 'LINENO': Naming.lineno_cname, +}) + +# from intobject.c +division_overflow_test_code = UtilityCode( +proto=""" +#define UNARY_NEG_WOULD_OVERFLOW(x) \ + (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x))) """) diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/Interpreter.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/Interpreter.py --- cython-0.10.3/Cython/Compiler/Interpreter.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/Interpreter.py 2009-05-20 16:37:46.000000000 +0100 @@ -12,7 +12,7 @@ from Errors import CompileError -class EmptyScope: +class EmptyScope(object): def lookup(self, name): return None Binary files /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/Lexicon.pickle and /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/Lexicon.pickle differ diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/Lexicon.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/Lexicon.py --- cython-0.10.3/Cython/Compiler/Lexicon.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/Lexicon.py 2009-05-20 16:37:46.000000000 +0100 @@ -7,6 +7,7 @@ raw_prefixes = "rR" string_prefixes = "cCuUbB" +IDENT = 'IDENT' def make_lexicon(): from Cython.Plex import \ @@ -82,7 +83,7 @@ comment = Str("#") + Rep(AnyBut("\n")) return Lexicon([ - (name, 'IDENT'), + (name, IDENT), (intliteral, 'INT'), (fltconst, 'FLOAT'), (imagconst, 'IMAG'), diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/Main.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/Main.py --- cython-0.10.3/Cython/Compiler/Main.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/Main.py 2009-05-20 16:37:46.000000000 +0100 @@ -34,7 +34,7 @@ print t.dump() return t -class CompilationData: +class CompilationData(object): # Bundles the information that is passed from transform to transform. # (For now, this is only) @@ -48,7 +48,7 @@ # result CompilationResult pass -class Context: +class Context(object): # This class encapsulates the context needed for compiling # one or more Cython implementation files along with their # associated and imported declaration files. It includes @@ -82,10 +82,20 @@ from ParseTreeTransforms import InterpretCompilerDirectives, TransformBuiltinMethods from ParseTreeTransforms import AlignFunctionDefinitions from AutoDocTransforms import EmbedSignature - from Optimize import FlattenInListTransform, SwitchTransform, FinalOptimizePhase + from Optimize import FlattenInListTransform, SwitchTransform, IterationTransform + from Optimize import FlattenBuiltinTypeCreation, ConstantFolding, FinalOptimizePhase from Buffer import IntroduceBufferAuxiliaryVars from ModuleNode import check_c_declarations + # Temporary hack that can be used to ensure that all result_code's + # are generated at code generation time. + import Visitor + class ClearResultCodes(Visitor.CythonTransform): + def visit_ExprNode(self, node): + self.visitchildren(node) + node.result_code = "" + return node + if pxd: _check_c_declarations = None _specific_post_parse = PxdPostParse(self) @@ -102,8 +112,8 @@ NormalizeTree(self), PostParse(self), _specific_post_parse, - _align_function_definitions, InterpretCompilerDirectives(self, self.pragma_overrides), + _align_function_definitions, FlattenInListTransform(), WithTransform(self), DecoratorTransform(self), @@ -113,8 +123,12 @@ IntroduceBufferAuxiliaryVars(self), _check_c_declarations, AnalyseExpressionsTransform(self), + FlattenBuiltinTypeCreation(), + ConstantFolding(), + IterationTransform(), SwitchTransform(), FinalOptimizePhase(self), +# ClearResultCodes(self), # SpecialFunctions(self), # CreateClosureClasses(context), ] @@ -239,7 +253,11 @@ if debug_find_module: print("......found ", pxd_pathname) if not pxd_pathname and need_pxd: - error(pos, "'%s.pxd' not found" % module_name) + package_pathname = self.search_include_directories(module_name, ".py", pos) + if package_pathname and package_pathname.endswith('__init__.py'): + pass + else: + error(pos, "'%s.pxd' not found" % module_name) if pxd_pathname: try: if debug_find_module: @@ -541,7 +559,7 @@ self.full_module_name = full_module_name self.cwd = cwd -class CompilationOptions: +class CompilationOptions(object): """ Options to the Cython compiler: @@ -582,7 +600,7 @@ self.obj_only = 0 -class CompilationResult: +class CompilationResult(object): """ Results from the Cython compiler: diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/ModuleNode.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/ModuleNode.py --- cython-0.10.3/Cython/Compiler/ModuleNode.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/ModuleNode.py 2009-05-20 16:37:46.000000000 +0100 @@ -19,6 +19,7 @@ import PyrexTypes import TypeSlots import Version +import DebugFlags from Errors import error, warning from PyrexTypes import py_object_type @@ -55,6 +56,7 @@ else: env.doc = self.doc env.directives = self.directives + self.__main__cname = env.intern_identifier(EncodedString("__main__")) self.body.analyse_declarations(env) def process_implementation(self, options, result): @@ -103,6 +105,7 @@ 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() + Code.GlobalState(h_code) if options.generate_pxi: result.i_file = replace_suffix(result.c_file, ".pxi") i_code = Code.PyrexCodeWriter(result.i_file) @@ -164,6 +167,7 @@ if api_funcs or has_api_extension_types: result.api_file = replace_suffix(result.c_file, "_api.h") h_code = Code.CCodeWriter() + Code.GlobalState(h_code) name = self.api_name(env) guard = Naming.api_guard_prefix + name h_code.put_h_guard(guard) @@ -200,7 +204,7 @@ for entry in api_funcs: sig = entry.type.signature_string() h_code.putln( - 'if (__Pyx_ImportFunction(module, "%s", (void**)&%s, "%s") < 0) goto bad;' % ( + 'if (__Pyx_ImportFunction(module, "%s", (void (**)(void))&%s, "%s") < 0) goto bad;' % ( entry.name, entry.cname, sig)) @@ -240,16 +244,27 @@ def generate_c_code(self, env, options, result): modules = self.referenced_modules + if Options.annotate or options.annotate: - code = Annotate.AnnotationCCodeWriter() + emit_linenums = False + rootwriter = Annotate.AnnotationCCodeWriter() else: - code = Code.CCodeWriter(emit_linenums=options.emit_linenums) - h_code = code.insertion_point() + emit_linenums = options.emit_linenums + rootwriter = Code.CCodeWriter(emit_linenums=emit_linenums) + globalstate = Code.GlobalState(rootwriter, emit_linenums) + globalstate.initialize_main_c_code() + h_code = globalstate['h_code'] + self.generate_module_preamble(env, modules, h_code) - code.globalstate.module_pos = self.pos - code.globalstate.directives = self.directives + globalstate.module_pos = self.pos + globalstate.directives = self.directives + globalstate.use_utility_code(refcount_utility_code) + + code = globalstate['before_global_var'] + code.putln('#define __Pyx_MODULE_NAME "%s"' % self.full_module_name) + code.putln("int %s%s = %s;" % (Naming.module_is_main, self.full_module_name.replace('.', '__'), int(Options.embed))) code.putln("") code.putln("/* Implementation of %s */" % env.qualified_name) self.generate_const_definitions(env, code) @@ -257,8 +272,8 @@ self.generate_interned_string_decls(env, code) self.generate_py_string_decls(env, code) - code.globalstate.insert_global_var_declarations_into(code) - + code = globalstate['all_the_rest'] + self.generate_cached_builtins_decls(env, code) self.body.generate_function_definitions(env, code) code.mark_pos(None) @@ -271,21 +286,24 @@ self.generate_module_init_func(modules[:-1], env, code) code.mark_pos(None) self.generate_module_cleanup_func(env, code) + if Options.embed: + self.generate_main_method(env, code) self.generate_filename_table(code) - self.generate_utility_functions(env, code, h_code) - - self.generate_declarations_for_modules(env, modules, h_code) + + self.generate_declarations_for_modules(env, modules, globalstate) h_code.write('\n') - code.globalstate.close_global_decls() + for codetup, name in env.utility_code_list: + globalstate.use_utility_code(codetup, name) + globalstate.finalize_main_c_code() f = open_new_file(result.c_file) - code.copyto(f) + rootwriter.copyto(f) f.close() result.c_file_generated = 1 if Options.annotate or options.annotate: - self.annotate(code) - code.save_annotation(result.main_source_file, result.c_file) + self.annotate(rootwriter) + rootwriter.save_annotation(result.main_source_file, result.c_file) def find_referenced_modules(self, env, module_list, modules_seen): if env not in modules_seen: @@ -383,18 +401,20 @@ self.generate_exttype_vtable_struct(entry, code) self.generate_exttype_vtabptr_declaration(entry, code) - def generate_declarations_for_modules(self, env, modules, code): - code.putln("") - code.putln("/* Type declarations */") + def generate_declarations_for_modules(self, env, modules, globalstate): + typecode = globalstate['type_declarations'] + typecode.putln("") + typecode.putln("/* Type declarations */") vtab_list, vtabslot_list = self.sort_type_hierarchy(modules, env) self.generate_type_definitions( - env, modules, vtab_list, vtabslot_list, code) + env, modules, vtab_list, vtabslot_list, typecode) + modulecode = globalstate['module_declarations'] for module in modules: defined_here = module is env - code.putln("/* Module declarations from %s */" % + modulecode.putln("/* Module declarations from %s */" % module.qualified_name.encode("ASCII", "ignore")) - self.generate_global_declarations(module, code, defined_here) - self.generate_cfunction_predeclarations(module, code, defined_here) + self.generate_global_declarations(module, modulecode, defined_here) + self.generate_cfunction_predeclarations(module, modulecode, defined_here) def generate_module_preamble(self, env, cimported_modules, code): code.putln('/* Generated by Cython %s on %s */' % ( @@ -403,6 +423,9 @@ code.putln('#define PY_SSIZE_T_CLEAN') for filename in env.python_include_files: code.putln('#include "%s"' % filename) + code.putln("#ifndef Py_PYTHON_H") + code.putln(" #error Python headers needed to compile C extensions, please install development version of Python.") + code.putln("#endif") code.putln("#ifndef PY_LONG_LONG") code.putln(" #define PY_LONG_LONG LONG_LONG") code.putln("#endif") @@ -411,12 +434,14 @@ code.putln("#endif") code.putln("#if PY_VERSION_HEX < 0x02040000") code.putln(" #define METH_COEXIST 0") + code.putln(" #define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type)") 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 PY_FORMAT_SIZE_T \"\"") code.putln(" #define PyInt_FromSsize_t(z) PyInt_FromLong(z)") code.putln(" #define PyInt_AsSsize_t(o) PyInt_AsLong(o)") code.putln(" #define PyNumber_Index(o) PyNumber_Int(o)") @@ -447,7 +472,6 @@ code.putln("") code.putln(" #define PyBUF_SIMPLE 0") code.putln(" #define PyBUF_WRITABLE 0x0001") - code.putln(" #define PyBUF_LOCK 0x0002") code.putln(" #define PyBUF_FORMAT 0x0004") code.putln(" #define PyBUF_ND 0x0008") code.putln(" #define PyBUF_STRIDES (0x0010 | PyBUF_ND)") @@ -472,6 +496,7 @@ code.putln("#if PY_MAJOR_VERSION >= 3") code.putln(" #define PyBaseString_Type PyUnicode_Type") code.putln(" #define PyString_Type PyBytes_Type") + code.putln(" #define PyString_CheckExact PyBytes_CheckExact") code.putln(" #define PyInt_Type PyLong_Type") code.putln(" #define PyInt_Check(op) PyLong_Check(op)") code.putln(" #define PyInt_CheckExact(op) PyLong_CheckExact(op)") @@ -505,14 +530,40 @@ code.putln(" #ifndef __cdecl") code.putln(" #define __cdecl") code.putln(" #endif") + code.putln(" #ifndef __fastcall") + code.putln(" #define __fastcall") + code.putln(" #endif") code.putln("#else") code.putln(" #define _USE_MATH_DEFINES") code.putln("#endif") - + + code.putln("#if PY_VERSION_HEX < 0x02050000") + code.putln(" #define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),((char *)(n)))") + code.putln(" #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))") + code.putln(" #define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),((char *)(n)))") + code.putln("#else") + code.putln(" #define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),(n))") + code.putln(" #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))") + code.putln(" #define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),(n))") + code.putln("#endif") + + code.putln("#if PY_VERSION_HEX < 0x02050000") + code.putln(" #define __Pyx_NAMESTR(n) ((char *)(n))") + code.putln(" #define __Pyx_DOCSTR(n) ((char *)(n))") + code.putln("#else") + code.putln(" #define __Pyx_NAMESTR(n) (n)") + code.putln(" #define __Pyx_DOCSTR(n) (n)") + code.putln("#endif") + self.generate_extern_c_macro_definition(code) code.putln("#include ") code.putln("#define %s" % Naming.api_guard_prefix + self.api_name(env)) self.generate_includes(env, cimported_modules, code) + if env.directives['c99_complex']: + code.putln("#ifndef _Complex_I") + code.putln("#include ") + code.putln("#endif") + code.putln("#define __PYX_USE_C99_COMPLEX defined(_Complex_I)") code.putln('') code.put(Nodes.utility_function_predeclarations) code.put(PyrexTypes.type_conversion_predeclarations) @@ -535,7 +586,15 @@ code.putln('') code.putln('static char %s[] = "%s";' % ( env.doc_cname, escape_byte_string(docstr))) - + + env.use_utility_code(streq_utility_code) + + # XXX this is a mess + for utility_code in PyrexTypes.c_int_from_py_function.specialize_list: + env.use_utility_code(utility_code) + for utility_code in PyrexTypes.c_long_from_py_function.specialize_list: + env.use_utility_code(utility_code) + def generate_extern_c_macro_definition(self, code): name = Naming.extern_c_macro code.putln("#ifdef __cplusplus") @@ -545,12 +604,8 @@ code.putln("#endif") def generate_includes(self, env, cimported_modules, code): - includes = env.include_files[:] - for module in cimported_modules: - for filename in module.include_files: - if filename not in includes: - includes.append(filename) - for filename in includes: + includes = [] + for filename in env.include_files: code.putln('#include "%s"' % filename) def generate_filename_table(self, code): @@ -620,9 +675,18 @@ type = entry.type scope = type.scope if scope: + kind = type.kind + packed = type.is_struct and type.packed + if packed: + kind = "%s %s" % (type.kind, "__Pyx_PACKED") + code.globalstate.use_utility_code(packed_struct_utility_code) header, footer = \ - self.sue_header_footer(type, type.kind, type.cname) + self.sue_header_footer(type, kind, type.cname) code.putln("") + if packed: + code.putln("#if !defined(__GNUC__)") + code.putln("#pragma pack(push, 1)") + code.putln("#endif") code.putln(header) var_entries = scope.var_entries if not var_entries: @@ -634,6 +698,10 @@ "%s;" % attr.type.declaration_code(attr.cname)) code.putln(footer) + if packed: + code.putln("#if !defined(__GNUC__)") + code.putln("#pragma pack(pop)") + code.putln("#endif") def generate_enum_definition(self, entry, code): code.mark_pos(entry.pos) @@ -677,7 +745,7 @@ name)) # ??? Do we really need the rest of this? ??? #else: - # code.putln("staticforward PyTypeObject %s;" % name) + # code.putln("staticforward PyTypeObject %s;" % name) def generate_exttype_vtable_struct(self, entry, code): code.mark_pos(entry.pos) @@ -754,8 +822,8 @@ def generate_cfunction_predeclarations(self, env, code, definition): for entry in env.cfunc_entries: - if not entry.in_cinclude and (definition - or entry.defined_in_pxd or entry.visibility == 'extern'): + if entry.inline_func_in_pxd or (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: @@ -771,8 +839,14 @@ storage_class = "" else: storage_class = "%s " % Naming.extern_c_macro - code.putln("%s%s; /*proto*/" % ( + if entry.func_modifiers: + modifiers = '%s ' % ' '.join([ + modifier.upper() for modifier in entry.func_modifiers]) + else: + modifiers = '' + code.putln("%s%s%s; /*proto*/" % ( storage_class, + modifiers, header)) def generate_typeobj_definitions(self, env, code): @@ -860,7 +934,7 @@ "p = %s;" % type.cast_code("o")) #if need_self_cast: - # self.generate_self_cast(scope, code) + # self.generate_self_cast(scope, code) if type.vtabslot_cname: vtab_base_type = type while vtab_base_type.base_type and vtab_base_type.base_type.vtabstruct_cname: @@ -876,7 +950,7 @@ if entry.name == "__weakref__": code.putln("p->%s = 0;" % entry.cname) else: - code.put_init_var_to_py_none(entry, "p->%s") + code.put_init_var_to_py_none(entry, "p->%s", nanny=False) entry = scope.lookup_here("__new__") if entry and entry.is_special: if entry.trivial_signature: @@ -886,7 +960,7 @@ code.putln( "if (%s(%s) < 0) {" % (entry.func_cname, cinit_args)) - code.put_decref_clear("o", py_object_type); + code.put_decref_clear("o", py_object_type, nanny=False); code.putln( "}") code.putln( @@ -915,7 +989,7 @@ if weakref_slot in scope.var_entries: code.putln("if (p->__weakref__) PyObject_ClearWeakRefs(o);") for entry in py_attrs: - code.put_xdecref("p->%s" % entry.cname, entry.type) + code.put_xdecref("p->%s" % entry.cname, entry.type, nanny=False) if base_type: tp_dealloc = TypeSlots.get_base_slot_function(scope, tp_slot) if tp_dealloc is None: @@ -1024,7 +1098,7 @@ for entry in py_attrs: name = "p->%s" % entry.cname code.putln("tmp = ((PyObject*)%s);" % name) - code.put_init_to_py_none(name, entry.type) + code.put_init_to_py_none(name, entry.type, nanny=False) code.putln("Py_XDECREF(tmp);") code.putln( "return 0;") @@ -1319,7 +1393,7 @@ code.putln( "return -1;") code.putln( - "}") + "}") code.putln( "}") @@ -1401,7 +1475,7 @@ code.putln( "PyVarObject_HEAD_INIT(0, 0)") code.putln( - '"%s.%s", /*tp_name*/' % ( + '__Pyx_NAMESTR("%s.%s"), /*tp_name*/' % ( self.full_module_name, scope.class_name)) if type.typedef_flag: objstruct = type.objstruct_cname @@ -1448,7 +1522,7 @@ flags = "READONLY" else: flags = "0" - code.putln('{"%s", %s, %s, %s, 0},' % ( + code.putln('{(char *)"%s", %s, %s, %s, 0},' % ( entry.name, type_code, "offsetof(%s, %s)" % (objstruct, entry.cname), @@ -1466,7 +1540,7 @@ env.getset_table_cname) for entry in env.property_entries: code.putln( - '{"%s", %s, %s, %s, 0},' % ( + '{(char *)"%s", %s, %s, %s, 0},' % ( entry.name, entry.getter_cname or "0", entry.setter_cname or "0", @@ -1493,7 +1567,7 @@ code.putln("static int %s(PyObject *o, PyObject* py_name, char *name) {" % Naming.import_star_set) code.putln("char** type_name = %s_type_names;" % Naming.import_star) code.putln("while (*type_name) {") - code.putln("if (!strcmp(name, *type_name)) {") + code.putln("if (__Pyx_StrEq(name, *type_name)) {") code.putln('PyErr_Format(PyExc_TypeError, "Cannot overwrite C type %s", name);') code.putln('goto bad;') code.putln("}") @@ -1503,7 +1577,7 @@ code.putln("if (0);") # so the first one can be "else if" for name, entry in env.entries.items(): if entry.is_cglobal and entry.used: - code.putln('else if (!strcmp(name, "%s")) {' % name) + code.putln('else if (__Pyx_StrEq(name, "%s")) {' % name) if entry.type.is_pyobject: if entry.type.is_extension_type or entry.type.is_builtin_type: code.putln("if (!(%s)) %s;" % ( @@ -1559,12 +1633,32 @@ code.putln("#endif") code.putln("{") tempdecl_code = code.insertion_point() + + code.putln("#ifdef CYTHON_REFNANNY") + code.putln("void* __pyx_refchk = NULL;") + code.putln("__Pyx_Refnanny = __Pyx_ImportRefcountAPI(\"refnanny\");") + code.putln("if (!__Pyx_Refnanny) {") + code.putln(" PyErr_Clear();") + code.putln(" __Pyx_Refnanny = __Pyx_ImportRefcountAPI(\"Cython.Runtime.refnanny\");") + code.putln(" if (!__Pyx_Refnanny)") + code.putln(" Py_FatalError(\"failed to import refnanny module\");") + code.putln("}") + code.putln("__pyx_refchk = __Pyx_Refnanny->NewContext(\"%s\", __LINE__, __FILE__);"% header3) + code.putln("#endif") + code.putln("%s = PyTuple_New(0); %s" % (Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos))); code.putln("/*--- Library function declarations ---*/") env.generate_library_function_declarations(code) self.generate_filename_init_call(code) + code.putln("/*--- Threads initialization code ---*/") + code.putln("#if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS") + code.putln("#ifdef WITH_THREAD /* Python build with threading support? */") + code.putln("PyEval_InitThreads();") + code.putln("#endif") + code.putln("#endif") + code.putln("/*--- Initialize various global constants etc. ---*/") code.putln(code.error_goto_if_neg("__Pyx_InitGlobals()", self.pos)) @@ -1602,22 +1696,28 @@ if Options.generate_cleanup_code: # this should be replaced by the module's tp_clear in Py3 + env.use_utility_code(import_module_utility_code) code.putln("if (__Pyx_RegisterCleanup()) %s;" % code.error_goto(self.pos)) - code.putln("#if PY_MAJOR_VERSION < 3") - code.putln("return;") - code.putln("#else") - code.putln("return %s;" % env.module_cname) - code.putln("#endif") + code.put_goto(code.return_label) code.put_label(code.error_label) code.put_var_xdecrefs(env.temp_entries) + for cname, type in code.funcstate.all_managed_temps(): + code.put_xdecref(cname, type) code.putln('__Pyx_AddTraceback("%s");' % env.qualified_name) env.use_utility_code(Nodes.traceback_utility_code) - code.putln("#if PY_MAJOR_VERSION >= 3") - code.putln("return NULL;") + code.put_decref_clear(env.module_cname, py_object_type, nanny=False) + code.put_label(code.return_label) + + code.put_finish_refcount_context() + + code.putln("#if PY_MAJOR_VERSION < 3") + code.putln("return;") + code.putln("#else") + code.putln("return %s;" % env.module_cname) code.putln("#endif") code.putln('}') - + tempdecl_code.put_var_declarations(env.temp_entries) tempdecl_code.put_temp_declarations(code.funcstate) @@ -1626,7 +1726,6 @@ def generate_module_cleanup_func(self, env, code): if not Options.generate_cleanup_code: return - env.use_utility_code(import_module_utility_code) env.use_utility_code(register_cleanup_utility_code) # Insert code stream of __Pyx_CleanupGlobals() code.globalstate.insert_cleanupcode_into(code) @@ -1639,41 +1738,55 @@ for entry in rev_entries: if entry.visibility != 'extern': if entry.type.is_pyobject and entry.used: - code.put_var_decref_clear(entry) + code.putln("Py_DECREF(%s); %s = 0;" % ( + code.entry_as_pyobject(entry), entry.cname)) code.putln("__Pyx_CleanupGlobals();") if Options.generate_cleanup_code >= 3: code.putln("/*--- Type import cleanup code ---*/") for type, _ in env.types_imported.items(): - code.put_decref("((PyObject*)%s)" % type.typeptr_cname, PyrexTypes.py_object_type) + code.putln("Py_DECREF((PyObject *)%s);" % type.typeptr_cname) if Options.cache_builtins: code.putln("/*--- Builtin cleanup code ---*/") for entry in env.cached_builtins: - code.put_var_decref_clear(entry) - code.putln("Py_DECREF(%s); %s = 0;" % (Naming.empty_tuple, Naming.empty_tuple)); + code.put_decref_clear(entry.cname, + PyrexTypes.py_object_type, + nanny=False) code.putln("/*--- Intern cleanup code ---*/") + code.put_decref_clear(Naming.empty_tuple, + PyrexTypes.py_object_type, + nanny=False) for entry in env.pynum_entries: - code.put_var_decref_clear(entry) - if env.all_pystring_entries: - for entry in env.all_pystring_entries: - if entry.is_interned: - code.put_decref_clear( - entry.pystring_cname, PyrexTypes.py_object_type) + code.put_decref_clear(entry.cname, + PyrexTypes.py_object_type, + nanny=False) + for entry in env.all_pystring_entries: + if entry.is_interned: + code.put_decref_clear(entry.pystring_cname, + PyrexTypes.py_object_type, + nanny=False) + for entry in env.default_entries: + if entry.type.is_pyobject and entry.used: + code.putln("Py_DECREF(%s); %s = 0;" % ( + code.entry_as_pyobject(entry), entry.cname)) code.putln("Py_INCREF(Py_None); return Py_None;") code.putln('}') + def generate_main_method(self, env, code): + code.globalstate.use_utility_code(main_method.specialize(module_name=env.module_name)) + def generate_filename_init_call(self, code): code.putln("%s();" % Naming.fileinit_cname) def generate_pymoduledef_struct(self, env, code): if env.doc: - doc = env.doc_cname + doc = "__Pyx_DOCSTR(%s)" % env.doc_cname else: doc = "0" code.putln("") code.putln("#if PY_MAJOR_VERSION >= 3") code.putln("static struct PyModuleDef %s = {" % Naming.pymoduledef_cname) code.putln(" PyModuleDef_HEAD_INIT,") - code.putln(' "%s",' % env.module_name) + code.putln(' __Pyx_NAMESTR("%s"),' % env.module_name) code.putln(" %s, /* m_doc */" % doc) code.putln(" -1, /* m_size */") code.putln(" %s /* m_methods */," % env.method_table_cname) @@ -1693,7 +1806,7 @@ doc = "0" code.putln("#if PY_MAJOR_VERSION < 3") code.putln( - '%s = Py_InitModule4("%s", %s, %s, 0, PYTHON_API_VERSION);' % ( + '%s = Py_InitModule4(__Pyx_NAMESTR("%s"), %s, %s, 0, PYTHON_API_VERSION);' % ( env.module_cname, env.module_name, env.method_table_cname, @@ -1714,20 +1827,27 @@ env.module_cname) code.putln("#endif") code.putln( - '%s = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME);' % + '%s = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME));' % 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;' % ( + 'if (__Pyx_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % ( env.module_cname, Naming.builtins_cname, code.error_goto(self.pos))) + code.putln("if (%s%s) {" % (Naming.module_is_main, self.full_module_name.replace('.', '__'))) + code.putln( + 'if (__Pyx_SetAttrString(%s, "__name__", %s) < 0) %s;' % ( + env.module_cname, + self.__main__cname, + code.error_goto(self.pos))) + code.putln("}") if Options.pre_import is not None: code.putln( - '%s = PyImport_AddModule("%s");' % ( + '%s = PyImport_AddModule(__Pyx_NAMESTR("%s"));' % ( Naming.preimport_cname, Options.pre_import)) code.putln( @@ -1741,7 +1861,7 @@ for entry in env.var_entries: if entry.visibility != 'extern': if entry.type.is_pyobject and entry.used: - code.put_init_var_to_py_none(entry) + code.put_init_var_to_py_none(entry, nanny=False) def generate_c_function_export_code(self, env, code): # Generate code to create PyCFunction wrappers for exported C functions. @@ -1749,7 +1869,7 @@ if entry.api or entry.defined_in_pxd: env.use_utility_code(function_export_utility_code) signature = entry.type.signature_string() - code.putln('if (__Pyx_ExportFunction("%s", (void*)%s, "%s") < 0) %s' % ( + code.putln('if (__Pyx_ExportFunction("%s", (void (*)(void))%s, "%s") < 0) %s' % ( entry.name, entry.cname, signature, @@ -1781,7 +1901,7 @@ code.error_goto(self.pos))) for entry in entries: code.putln( - 'if (__Pyx_ImportFunction(%s, "%s", (void**)&%s, "%s") < 0) %s' % ( + 'if (__Pyx_ImportFunction(%s, "%s", (void (**)(void))&%s, "%s") < 0) %s' % ( temp, entry.name, entry.cname, @@ -1884,7 +2004,7 @@ code.error_goto(entry.pos))) env.use_utility_code(Nodes.set_vtable_utility_code) code.putln( - 'if (PyObject_SetAttrString(%s, "%s", (PyObject *)&%s) < 0) %s' % ( + 'if (__Pyx_SetAttrString(%s, "%s", (PyObject *)&%s) < 0) %s' % ( Naming.module_cname, scope.class_name, typeobj_cname, @@ -1893,10 +2013,14 @@ 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);" % ( + if type.typedef_flag: + objstruct = type.objstruct_cname + else: + objstruct = "struct %s" % type.objstruct_cname + code.putln("if (%s == 0) %s = offsetof(%s, %s);" % ( tp_weaklistoffset, tp_weaklistoffset, - type.objstruct_cname, + objstruct, weakref_entry.cname)) else: error(weakref_entry.pos, "__weakref__ slot must be of type 'object'") @@ -1916,13 +2040,28 @@ 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: + + c_method_entries = [ + entry for entry in type.scope.cfunc_entries + if entry.func_cname ] + if c_method_entries: + code.putln('#if PY_MAJOR_VERSION >= 3') + for meth_entry in c_method_entries: + cast = meth_entry.type.signature_cast_string() + code.putln( + "%s.%s = %s%s;" % ( + type.vtable_cname, + meth_entry.cname, + cast, + meth_entry.func_cname)) + code.putln('#else') + for meth_entry in c_method_entries: code.putln( "*(void(**)(void))&%s.%s = (void(*)(void))%s;" % ( type.vtable_cname, meth_entry.cname, meth_entry.func_cname)) + code.putln('#endif') def generate_typeptr_assignment_code(self, entry, code): # Generate code to initialise the typeptr of an extension @@ -1933,22 +2072,6 @@ "%s = &%s;" % ( type.typeptr_cname, type.typeobj_cname)) - def generate_utility_functions(self, env, code, h_code): - for codetup, name in env.utility_code_list: - code.globalstate.use_utility_code(codetup, name) - - code.globalstate.put_utility_code_protos(h_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("}") - code.globalstate.put_utility_code_defs(code) - code.put(PyrexTypes.type_conversion_functions) - code.putln("") - #------------------------------------------------------------------------------------ # # Runtime support code @@ -1964,6 +2087,21 @@ #endif """) +#------------------------------------------------------------------------------------ + +streq_utility_code = UtilityCode( +proto = """ +static INLINE int __Pyx_StrEq(const char *, const char *); /*proto*/ +""", +impl = """ +static INLINE int __Pyx_StrEq(const char *s1, const char *s2) { + while (*s1 != '\\0' && *s1 == *s2) { s1++; s2++; } + return *s1 == *s2; +} +""") + +#------------------------------------------------------------------------------------ + import_module_utility_code = UtilityCode( proto = """ static PyObject *__Pyx_ImportModule(const char *name); /*proto*/ @@ -2050,31 +2188,44 @@ function_export_utility_code = UtilityCode( proto = """ -static int __Pyx_ExportFunction(char *name, void *f, char *sig); /*proto*/ +static int __Pyx_ExportFunction(const char *name, void (*f)(void), const char *sig); /*proto*/ """, impl = r""" -static int __Pyx_ExportFunction(char *name, void *f, char *sig) { +static int __Pyx_ExportFunction(const char *name, void (*f)(void), const char *sig) { +#if PY_VERSION_HEX < 0x02050000 + char *api = (char *)"%(API)s"; +#else + const char *api = "%(API)s"; +#endif PyObject *d = 0; - PyObject *p = 0; - d = PyObject_GetAttrString(%(MODULE)s, "%(API)s"); + PyObject *cobj = 0; + union { + void (*fp)(void); + void *p; + } tmp; + + + d = PyObject_GetAttrString(%(MODULE)s, api); if (!d) { PyErr_Clear(); d = PyDict_New(); if (!d) goto bad; Py_INCREF(d); - if (PyModule_AddObject(%(MODULE)s, "%(API)s", d) < 0) + if (PyModule_AddObject(%(MODULE)s, api, d) < 0) goto bad; } - p = PyCObject_FromVoidPtrAndDesc(f, sig, 0); - if (!p) + tmp.fp = f; + cobj = PyCObject_FromVoidPtrAndDesc(tmp.p, (void *)sig, 0); + if (!cobj) goto bad; - if (PyDict_SetItemString(d, name, p) < 0) + if (PyDict_SetItemString(d, name, cobj) < 0) goto bad; + Py_DECREF(cobj); Py_DECREF(d); return 0; bad: - Py_XDECREF(p); + Py_XDECREF(cobj); Py_XDECREF(d); return -1; } @@ -2085,17 +2236,27 @@ function_import_utility_code = UtilityCode( proto = """ -static int __Pyx_ImportFunction(PyObject *module, char *funcname, void **f, char *sig); /*proto*/ +static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig); /*proto*/ """, impl = """ #ifndef __PYX_HAVE_RT_ImportFunction #define __PYX_HAVE_RT_ImportFunction -static int __Pyx_ImportFunction(PyObject *module, char *funcname, void **f, char *sig) { +static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig) { +#if PY_VERSION_HEX < 0x02050000 + char *api = (char *)"%(API)s"; +#else + const char *api = "%(API)s"; +#endif PyObject *d = 0; PyObject *cobj = 0; - char *desc; - - d = PyObject_GetAttrString(module, "%(API)s"); + const char *desc; + const char *s1, *s2; + union { + void (*fp)(void); + void *p; + } tmp; + + d = PyObject_GetAttrString(module, api); if (!d) goto bad; cobj = PyDict_GetItemString(d, funcname); @@ -2105,16 +2266,19 @@ PyModule_GetName(module), funcname); goto bad; } - desc = (char *)PyCObject_GetDesc(cobj); + desc = (const char *)PyCObject_GetDesc(cobj); if (!desc) goto bad; - if (strcmp(desc, sig) != 0) { + s1 = desc; s2 = sig; + while (*s1 != '\\0' && *s1 == *s2) { s1++; s2++; } + if (*s1 != *s2) { PyErr_Format(PyExc_TypeError, "C function %%s.%%s has wrong signature (expected %%s, got %%s)", - PyModule_GetName(module), funcname, sig, desc); + PyModule_GetName(module), funcname, sig, desc); goto bad; } - *f = PyCObject_AsVoidPtr(cobj); + tmp.p = PyCObject_AsVoidPtr(cobj); + *f = tmp.fp; Py_DECREF(d); return 0; bad: @@ -2129,7 +2293,7 @@ proto = """ static int __Pyx_RegisterCleanup(void); /*proto*/ static PyObject* __pyx_module_cleanup(PyObject *self, PyObject *unused); /*proto*/ -static PyMethodDef cleanup_def = {"__cleanup", (PyCFunction)&__pyx_module_cleanup, METH_NOARGS, 0}; +static PyMethodDef cleanup_def = {__Pyx_NAMESTR("__cleanup"), (PyCFunction)&__pyx_module_cleanup, METH_NOARGS, 0}; """, impl = """ static int __Pyx_RegisterCleanup(void) { @@ -2154,7 +2318,7 @@ atexit = __Pyx_ImportModule("atexit"); if (!atexit) goto bad; - reg = PyObject_GetAttrString(atexit, "register"); + reg = __Pyx_GetAttrString(atexit, "register"); if (!reg) goto bad; res = PyObject_CallObject(reg, args); @@ -2178,65 +2342,65 @@ static int __Pyx_import_all_from(PyObject *locals, PyObject *v) { - PyObject *all = PyObject_GetAttrString(v, "__all__"); - PyObject *dict, *name, *value; - int skip_leading_underscores = 0; - int pos, err; - - if (all == NULL) { - if (!PyErr_ExceptionMatches(PyExc_AttributeError)) - return -1; /* Unexpected error */ - PyErr_Clear(); - dict = PyObject_GetAttrString(v, "__dict__"); - if (dict == NULL) { - if (!PyErr_ExceptionMatches(PyExc_AttributeError)) - return -1; - PyErr_SetString(PyExc_ImportError, - "from-import-* object has no __dict__ and no __all__"); - return -1; - } - all = PyMapping_Keys(dict); - Py_DECREF(dict); - if (all == NULL) - return -1; - skip_leading_underscores = 1; - } - - for (pos = 0, err = 0; ; pos++) { - name = PySequence_GetItem(all, pos); - if (name == NULL) { - if (!PyErr_ExceptionMatches(PyExc_IndexError)) - err = -1; - else - PyErr_Clear(); - break; - } - if (skip_leading_underscores && + PyObject *all = __Pyx_GetAttrString(v, "__all__"); + PyObject *dict, *name, *value; + int skip_leading_underscores = 0; + int pos, err; + + if (all == NULL) { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) + return -1; /* Unexpected error */ + PyErr_Clear(); + dict = __Pyx_GetAttrString(v, "__dict__"); + if (dict == NULL) { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) + return -1; + PyErr_SetString(PyExc_ImportError, + "from-import-* object has no __dict__ and no __all__"); + return -1; + } + all = PyMapping_Keys(dict); + Py_DECREF(dict); + if (all == NULL) + return -1; + skip_leading_underscores = 1; + } + + for (pos = 0, err = 0; ; pos++) { + name = PySequence_GetItem(all, pos); + if (name == NULL) { + if (!PyErr_ExceptionMatches(PyExc_IndexError)) + err = -1; + else + PyErr_Clear(); + break; + } + if (skip_leading_underscores && #if PY_MAJOR_VERSION < 3 - PyString_Check(name) && - PyString_AS_STRING(name)[0] == '_') + PyString_Check(name) && + PyString_AS_STRING(name)[0] == '_') #else - PyUnicode_Check(name) && - PyUnicode_AS_UNICODE(name)[0] == '_') + PyUnicode_Check(name) && + PyUnicode_AS_UNICODE(name)[0] == '_') #endif - { - Py_DECREF(name); - continue; - } - value = PyObject_GetAttr(v, name); - if (value == NULL) - err = -1; - else if (PyDict_CheckExact(locals)) - err = PyDict_SetItem(locals, name, value); - else - err = PyObject_SetItem(locals, name, value); - Py_DECREF(name); - Py_XDECREF(value); - if (err != 0) - break; - } - Py_DECREF(all); - return err; + { + Py_DECREF(name); + continue; + } + value = PyObject_GetAttr(v, name); + if (value == NULL) + err = -1; + else if (PyDict_CheckExact(locals)) + err = PyDict_SetItem(locals, name, value); + else + err = PyObject_SetItem(locals, name, value); + Py_DECREF(name); + Py_XDECREF(value); + if (err != 0) + break; + } + Py_DECREF(all); + return err; } @@ -2274,3 +2438,74 @@ } """ % {'IMPORT_STAR' : Naming.import_star, 'IMPORT_STAR_SET' : Naming.import_star_set } + +refcount_utility_code = UtilityCode(proto=""" +#ifdef CYTHON_REFNANNY +typedef struct { + void (*INCREF)(void*, PyObject*, int); + void (*DECREF)(void*, PyObject*, int); + void (*GOTREF)(void*, PyObject*, int); + void (*GIVEREF)(void*, PyObject*, int); + void* (*NewContext)(const char*, int, const char*); + void (*FinishContext)(void**); +} __Pyx_RefnannyAPIStruct; +static __Pyx_RefnannyAPIStruct *__Pyx_Refnanny = NULL; +#define __Pyx_ImportRefcountAPI(name) \ + (__Pyx_RefnannyAPIStruct *) PyCObject_Import((char *)name, (char *)\"RefnannyAPI\") +#define __Pyx_INCREF(r) __Pyx_Refnanny->INCREF(__pyx_refchk, (PyObject *)(r), __LINE__) +#define __Pyx_DECREF(r) __Pyx_Refnanny->DECREF(__pyx_refchk, (PyObject *)(r), __LINE__) +#define __Pyx_GOTREF(r) __Pyx_Refnanny->GOTREF(__pyx_refchk, (PyObject *)(r), __LINE__) +#define __Pyx_GIVEREF(r) __Pyx_Refnanny->GIVEREF(__pyx_refchk, (PyObject *)(r), __LINE__) +#define __Pyx_XDECREF(r) if((r) == NULL) ; else __Pyx_DECREF(r) +#define __Pyx_SetupRefcountContext(name) \ + void* __pyx_refchk = __Pyx_Refnanny->NewContext((name), __LINE__, __FILE__) +#define __Pyx_FinishRefcountContext() \ + __Pyx_Refnanny->FinishContext(&__pyx_refchk) +#else +#define __Pyx_INCREF(r) Py_INCREF(r) +#define __Pyx_DECREF(r) Py_DECREF(r) +#define __Pyx_GOTREF(r) +#define __Pyx_GIVEREF(r) +#define __Pyx_XDECREF(r) Py_XDECREF(r) +#define __Pyx_SetupRefcountContext(name) +#define __Pyx_FinishRefcountContext() +#endif /* CYTHON_REFNANNY */ +#define __Pyx_XGIVEREF(r) if((r) == NULL) ; else __Pyx_GIVEREF(r) +#define __Pyx_XGOTREF(r) if((r) == NULL) ; else __Pyx_GOTREF(r) +""") + +main_method = UtilityCode( +impl = """ +#if PY_MAJOR_VERSION < 3 || (!defined(WIN32) && !defined(MS_WINDOWS)) +int main(int argc, char** argv) { +#else +int wmain(int argc, wchar_t **argv) { +#endif + int r = 0; + PyObject* m = NULL; + Py_SetProgramName(argv[0]); + Py_Initialize(); + PySys_SetArgv(argc, argv); +#if PY_MAJOR_VERSION < 3 + init%(module_name)s(); +#else + m = PyInit_%(module_name)s(name); +#endif + if (PyErr_Occurred() != NULL) { + r = 1; + PyErr_Print(); /* This exits with the right code if SystemExit. */ + if (Py_FlushLine()) PyErr_Clear(); + } + Py_XDECREF(m); + Py_Finalize(); + return r; +} +""") + +packed_struct_utility_code = UtilityCode(proto=""" +#if defined(__GNUC__) +#define __Pyx_PACKED __attribute__((__packed__)) +#else +#define __Pyx_PACKED +#endif +""", impl="") diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/Naming.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/Naming.py --- cython-0.10.3/Cython/Compiler/Naming.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/Naming.py 2009-05-20 16:37:46.000000000 +0100 @@ -43,6 +43,7 @@ vtabstruct_prefix = pyrex_prefix + "vtabstruct_" opt_arg_prefix = pyrex_prefix + "opt_args_" convert_func_prefix = pyrex_prefix + "convert_" +module_is_main = pyrex_prefix + "module_is_main_" args_cname = pyrex_prefix + "args" pykwdlist_cname = pyrex_prefix + "pyargnames" @@ -52,6 +53,7 @@ moddict_cname = pyrex_prefix + "d" dummy_cname = pyrex_prefix + "dummy" filename_cname = pyrex_prefix + "filename" +modulename_cname = pyrex_prefix + "modulename" filetable_cname = pyrex_prefix + "f" filenames_cname = pyrex_prefix + "filenames" fileinit_cname = pyrex_prefix + "init_filenames" diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/Nodes.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/Nodes.py --- cython-0.10.3/Cython/Compiler/Nodes.py 2008-12-14 10:58:05.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/Nodes.py 2009-05-20 16:37:46.000000000 +0100 @@ -2,9 +2,10 @@ # Pyrex - Parse tree nodes # -import string, sys, os, time, copy +import sys, os, time, copy import Code +import Builtin from Errors import error, warning, InternalError import Naming import PyrexTypes @@ -16,8 +17,7 @@ from StringEncoding import EncodedString, escape_byte_string, split_docstring import Options import ControlFlow - -from DebugFlags import debug_disposal_code +import DebugFlags absolute_path_length = 0 @@ -67,10 +67,55 @@ doc.encoding = encoding return doc + +from Code import CCodeWriter +from types import FunctionType + +def write_func_call(func): + def f(*args, **kwds): + if len(args) > 1 and isinstance(args[1], CCodeWriter): + # here we annotate the code with this function call + # but only if new code is generated + node, code = args[:2] + marker = ' /* %s -> %s.%s %s */' % ( + ' ' * code.call_level, + node.__class__.__name__, + func.__name__, + node.pos[1:]) + pristine = code.buffer.stream.tell() + code.putln(marker) + start = code.buffer.stream.tell() + code.call_level += 4 + res = func(*args, **kwds) + code.call_level -= 4 + if start == code.buffer.stream.tell(): + code.buffer.stream.seek(pristine) + else: + marker = marker.replace('->', '<-') + code.putln(marker) + return res + else: + return func(*args, **kwds) + return f + +class VerboseCodeWriter(type): + # Set this as a metaclass to trace function calls in code. + # This slows down code generation and makes much larger files. + def __new__(cls, name, bases, attrs): + attrs = dict(attrs) + for mname, m in attrs.items(): + if isinstance(m, FunctionType): + attrs[mname] = write_func_call(m) + return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs) + + class Node(object): # pos (string, int, int) Source file position # is_name boolean Is a NameNode # is_literal boolean Is a ConstNode + + if DebugFlags.debug_trace_code_generation: + __metaclass__ = VerboseCodeWriter is_name = 0 is_literal = 0 @@ -155,12 +200,13 @@ self.body.annotate(code) def end_pos(self): - if not self.child_attrs: - return self.pos try: return self._end_pos except AttributeError: pos = self.pos + if not self.child_attrs: + self._end_pos = pos + return pos for attr in self.child_attrs: child = getattr(self, attr) # Sometimes lists, sometimes nodes @@ -250,7 +296,7 @@ self.body.annotate(code) code.globalstate.directives = old -class BlockNode: +class BlockNode(object): # Mixin class for nodes representing a declaration block. def generate_const_definitions(self, env, code): @@ -441,6 +487,11 @@ if not self.dimension.type.is_int: error(self.dimension.pos, "Array dimension not integer") size = self.dimension.result() + try: + size = int(size) + except ValueError: + # runtime constant? + pass else: size = None if not base_type.is_complete(): @@ -498,7 +549,8 @@ if self.optional_arg_count: scope = StructOrUnionScope() - scope.declare_var('%sn' % Naming.pyrex_prefix, PyrexTypes.c_int_type, self.pos) + arg_count_member = '%sn' % Naming.pyrex_prefix + scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos) for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]: scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1) struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name) @@ -513,6 +565,8 @@ exc_val = None exc_check = 0 + if self.exception_check == '+': + env.add_include_file('stdexcept') if return_type.is_pyobject \ and (self.exception_value or self.exception_check) \ and self.exception_check != '+': @@ -549,6 +603,13 @@ nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable) if self.optional_arg_count: func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type) + callspec = env.directives['callspec'] + if callspec: + current = func_type.calling_convention + if current and current != callspec: + error(self.pos, "cannot have both '%s' and '%s' " + "calling conventions" % (current, callspec)) + func_type.calling_convention = callspec return self.base.analyse(func_type, env) @@ -620,6 +681,7 @@ # is_basic_c_type boolean # signed boolean # longness integer + # complex boolean # is_self_arg boolean Is self argument of C method child_attrs = [] @@ -660,6 +722,11 @@ self.arg_name = self.name else: error(self.pos, "'%s' is not a type identifier" % self.name) + if self.complex: + if not type.is_numeric or type.is_complex: + error(self.pos, "can only complexify c numeric types") + type = PyrexTypes.CComplexType(type) + type.create_declaration_utility_code(env) if type: return type else: @@ -679,6 +746,8 @@ "keyword_args", "dtype_node"] dtype_node = None + + name = None def analyse(self, env, could_be_name = False): base_type = self.base_type_node.analyse(env) @@ -717,23 +786,40 @@ # api boolean # need_properties [entry] + # decorators [cython.locals(...)] or None + # directive_locals { string : NameNode } locals defined by cython.locals(...) + child_attrs = ["base_type", "declarators"] need_properties = () + decorators = None + directive_locals = {} + def analyse_declarations(self, env, dest_scope = None): if not dest_scope: dest_scope = env self.dest_scope = dest_scope base_type = self.base_type.analyse(env) + + need_property = False if (dest_scope.is_c_class_scope - and self.visibility == 'public' - and base_type.is_pyobject - and (base_type.is_builtin_type or base_type.is_extension_type)): - self.need_properties = [] + and self.visibility == 'public' + and base_type.is_pyobject + and (base_type.is_builtin_type or base_type.is_extension_type)): + # If the field is settable and extension type, then the CPython mechanism does + # not do enough type-checking for us. + need_property = True + elif (base_type.is_typedef and base_type.typedef_is_external + and (self.visibility in ('public', 'readonly'))): + # If the field is an external typedef, we cannot be sure about the type, + # so do conversion ourself rather than rely on the CPython mechanism (through + # a property; made in AnalyseDeclarationsTransform). need_property = True + + if need_property: visibility = 'private' + self.need_properties = [] else: - need_property = False visibility = self.visibility for declarator in self.declarators: @@ -754,7 +840,11 @@ entry = dest_scope.declare_cfunction(name, type, declarator.pos, cname = cname, visibility = self.visibility, in_pxd = self.in_pxd, api = self.api) + if entry is not None: + entry.directive_locals = self.directive_locals else: + if self.directive_locals: + s.error("Decorators can only be followed by functions") if self.in_pxd and self.visibility != 'extern': error(self.pos, "Only 'extern' C variable declaration allowed in .pxd file") @@ -774,23 +864,26 @@ # in_pxd boolean # attributes [CVarDefNode] or None # entry Entry + # packed boolean child_attrs = ["attributes"] def analyse_declarations(self, env): scope = None + if self.visibility == 'extern' and self.packed: + error(self.pos, "Cannot declare extern struct as 'packed'") if self.attributes is not None: scope = StructOrUnionScope(self.name) self.entry = env.declare_struct_or_union( self.name, self.kind, scope, self.typedef_flag, self.pos, - self.cname, visibility = self.visibility) - need_typedef_indirection = False + self.cname, visibility = self.visibility, packed = self.packed) if self.attributes is not None: if self.in_pxd and not env.in_cinclude: self.entry.defined_in_pxd = 1 for attr in self.attributes: attr.analyse_declarations(env, scope) if self.visibility != 'extern': + need_typedef_indirection = False for attr in scope.var_entries: type = attr.type while type.is_array: @@ -802,13 +895,13 @@ type = type.base_type if type == self.entry.type: need_typedef_indirection = True - if need_typedef_indirection: - # C can't handle typedef structs that refer to themselves. - struct_entry = self.entry - cname = env.new_const_cname() - self.entry = env.declare_typedef(self.name, struct_entry.type, self.pos, cname = self.cname, visibility='ignore') - struct_entry.type.typedef_flag = False - struct_entry.cname = struct_entry.type.cname = env.new_const_cname() + if need_typedef_indirection: + # C can't handle typedef structs that refer to themselves. + struct_entry = self.entry + cname = env.new_const_cname() + self.entry = env.declare_typedef(self.name, struct_entry.type, self.pos, cname = self.cname, visibility='ignore') + struct_entry.type.typedef_flag = False + struct_entry.cname = struct_entry.type.cname = env.new_const_cname() def analyse_expressions(self, env): pass @@ -850,12 +943,13 @@ self.temp, item.cname, code.error_goto_if_null(self.temp, item.pos))) - code.putln('if (PyObject_SetAttrString(%s, "%s", %s) < 0) %s' % ( + code.put_gotref(self.temp) + code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % ( Naming.module_cname, item.name, self.temp, code.error_goto(item.pos))) - code.putln("%s = 0;" % self.temp) + code.put_decref_clear(self.temp, PyrexTypes.py_object_type) class CEnumDefItemNode(StatNode): @@ -910,6 +1004,7 @@ # #filename string C name of filename string const # entry Symtab.Entry # needs_closure boolean Whether or not this function has inner functions/classes/yield + # directive_locals { string : NameNode } locals defined by cython.locals(...) py_func = None assmt = None @@ -931,6 +1026,8 @@ else: arg.default.allocate_temps(genv) arg.default_entry = genv.add_default_value(arg.type) + if arg.type.is_pyobject: + arg.default_entry.init = 0 arg.default_entry.used = 1 arg.default_result_code = arg.default_entry.cname else: @@ -954,6 +1051,7 @@ if type.is_cfunction: lenv.nogil = type.nogil and not type.with_gil self.local_scope = lenv + lenv.directives = env.directives return lenv def generate_function_definitions(self, env, code): @@ -993,6 +1091,8 @@ code.put_var_declarations(lenv.var_entries) init = "" if not self.return_type.is_void: + if self.return_type.is_pyobject: + init = " = NULL" code.putln( "%s%s;" % (self.return_type.declaration_code( @@ -1005,8 +1105,11 @@ # ----- GIL acquisition acquire_gil = self.need_gil_acquisition(lenv) if acquire_gil: + env.use_utility_code(force_init_threads_utility_code) code.putln("PyGILState_STATE _save = PyGILState_Ensure();") # ----- Automatic lead-ins for certain special functions + if not lenv.nogil: + code.put_setup_refcount_context(self.entry.name) if is_getbuffer_slot: self.getbuffer_init(code) # ----- Fetch arguments @@ -1036,7 +1139,7 @@ code.putln("") if self.return_type.is_pyobject: #if self.return_type.is_extension_type: - # lhs = "(PyObject *)%s" % Naming.retval_cname + # lhs = "(PyObject *)%s" % Naming.retval_cname #else: lhs = Naming.retval_cname code.put_init_to_py_none(lhs, self.return_type) @@ -1048,7 +1151,11 @@ if code.error_label in code.labels_used: code.put_goto(code.return_label) code.put_label(code.error_label) + # cleanup temps the old way code.put_var_xdecrefs(lenv.temp_entries) + # cleanup temps the new way + for cname, type in code.funcstate.all_managed_temps(): + code.put_xdecref(cname, type) # Clean up buffers -- this calls a Python function # so need to save and restore error state @@ -1114,12 +1221,26 @@ for entry in lenv.arg_entries: if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg': code.put_var_decref(entry) - if acquire_gil: - code.putln("PyGILState_Release(_save);") + # code.putln("/* TODO: decref scope object */") # ----- Return + # This code is duplicated in ModuleNode.generate_module_init_func + if not lenv.nogil: + default_retval = self.return_type.default_value + err_val = self.error_value() + if err_val is None and default_retval: + err_val = default_retval + if self.return_type.is_pyobject: + code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname)) + + code.put_finish_refcount_context() + + if acquire_gil: + code.putln("PyGILState_Release(_save);") + if not self.return_type.is_void: code.putln("return %s;" % Naming.retval_cname) + code.putln("}") # ----- Go back and insert temp variable declarations tempvardecl_code.put_var_declarations(lenv.temp_entries) @@ -1154,9 +1275,9 @@ arg.default_entry.cname, default.result_as(arg.default_entry.type))) if default.is_temp and default.type.is_pyobject: - code.putln( - "%s = 0;" % - default.result()) + code.putln("%s = 0;" % default.result()) + default.free_temps(code) + code.put_var_giveref(arg.default_entry) # For Python class methods, create and store function object if self.assmt: self.assmt.generate_execution_code(code) @@ -1170,17 +1291,21 @@ # getbuffer with a NULL parameter. For now we work around this; # the following line should be removed when this bug is fixed. code.putln("if (%s == NULL) return 0;" % info) - code.putln("%s->obj = Py_None; Py_INCREF(Py_None);" % info) + code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info) + code.put_giveref("%s->obj" % info) # Do not refnanny object within structs def getbuffer_error_cleanup(self, code): info = self.local_scope.arg_entries[1].cname - code.putln("Py_DECREF(%s->obj); %s->obj = NULL;" % + code.put_gotref("%s->obj" % info) + code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" % (info, info)) def getbuffer_normal_cleanup(self, code): info = self.local_scope.arg_entries[1].cname - code.putln("if (%s->obj == Py_None) { Py_DECREF(Py_None); %s->obj = NULL; }" % - (info, info)) + code.putln("if (%s->obj == Py_None) {" % info) + code.put_gotref("Py_None") + code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info) + code.putln("}") class CFuncDefNode(FuncDefNode): # C function definition. @@ -1191,23 +1316,25 @@ # declarator CDeclaratorNode # body StatListNode # api boolean + # decorators [DecoratorNode] list of decorators # # with_gil boolean Acquire GIL around body # type CFuncType # py_func wrapper for calling from Python # overridable whether or not this is a cpdef function + # inline_in_pxd whether this is an inline function in a pxd file child_attrs = ["base_type", "declarator", "body", "py_func"] - + + inline_in_pxd = False + decorators = None + directive_locals = {} + def unqualified_name(self): return self.entry.name def analyse_declarations(self, env): - if 'locals' in env.directives: - directive_locals = env.directives['locals'] - else: - directive_locals = {} - self.directive_locals = directive_locals + directive_locals = self.directive_locals = env.directives['locals'] base_type = self.base_type.analyse(env) # The 2 here is because we need both function and argument names. name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None)) @@ -1226,6 +1353,7 @@ self.args = declarator.args for formal_arg, type_arg in zip(self.args, type.args): formal_arg.type = type_arg.type + formal_arg.name = type_arg.name formal_arg.cname = type_arg.cname name = name_declarator.name cname = name_declarator.cname @@ -1233,9 +1361,15 @@ name, type, self.pos, cname = cname, visibility = self.visibility, defining = self.body is not None, - api = self.api) + api = self.api, modifiers = self.modifiers) + self.entry.inline_func_in_pxd = self.inline_in_pxd self.return_type = type.return_type + if self.overridable and not env.is_module_scope: + if len(self.args) < 1 or not self.args[0].type.is_pyobject: + # An error will be produced in the cdef function + self.overridable = False + if self.overridable: import ExprNodes py_func_body = self.call_self_node(is_module_scope = env.is_module_scope) @@ -1292,8 +1426,9 @@ return with_gil def analyse_expressions(self, env): + self.local_scope.directives = env.directives self.analyse_default_values(env) - if self.overridable: + if self.py_func is not None: self.py_func.analyse_expressions(env) def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None): @@ -1312,7 +1447,7 @@ arg_decls = ["void"] if cname is None: cname = self.entry.func_cname - entity = type.function_header_code(cname, string.join(arg_decls, ", ")) + entity = type.function_header_code(cname, ', '.join(arg_decls)) if visibility == 'public': dll_linkage = "DL_EXPORT" else: @@ -1344,6 +1479,8 @@ code.putln('if (%s) {' % Naming.optional_args_cname) for arg in self.args: if arg.default: + # FIXME: simple name prefixing doesn't work when + # argument name mangling is in place code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i)) declarator = arg.declarator while not hasattr(declarator, 'name'): @@ -1480,56 +1617,76 @@ self.num_required_kw_args = rk self.num_required_args = r - def as_cfunction(self, cfunc): + def as_cfunction(self, cfunc=None, scope=None): if self.star_arg: error(self.star_arg.pos, "cdef function cannot have star argument") if self.starstar_arg: error(self.starstar_arg.pos, "cdef function cannot have starstar argument") - if len(self.args) != len(cfunc.type.args) or cfunc.type.has_varargs: - error(self.pos, "wrong number of arguments") - error(declarator.pos, "previous declaration here") - for formal_arg, type_arg in zip(self.args, cfunc.type.args): - name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1) - if type is PyrexTypes.py_object_type or formal_arg.is_self: - formal_arg.type = type_arg.type - formal_arg.name_declarator = name_declarator + if cfunc is None: + cfunc_args = [] + for formal_arg in self.args: + name_declarator, type = formal_arg.analyse(scope, nonempty=1) + cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name, + cname = None, + type = py_object_type, + pos = formal_arg.pos)) + cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type, + args = cfunc_args, + has_varargs = False, + exception_value = None, + exception_check = False, + nogil = False, + with_gil = False, + is_overridable = True) + cfunc = CVarDefNode(self.pos, type=cfunc_type) + else: + cfunc_type = cfunc.type + if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs: + error(self.pos, "wrong number of arguments") + error(declarator.pos, "previous declaration here") + for formal_arg, type_arg in zip(self.args, cfunc_type.args): + name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1) + if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self: + formal_arg.type = type_arg.type + formal_arg.name_declarator = name_declarator import ExprNodes - if cfunc.type.exception_value is None: + if cfunc_type.exception_value is None: exception_value = None else: - exception_value = ExprNodes.ConstNode(self.pos, value=cfunc.type.exception_value, type=cfunc.type.return_type) + exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type) declarator = CFuncDeclaratorNode(self.pos, base = CNameDeclaratorNode(self.pos, name=self.name, cname=None), args = self.args, has_varargs = False, - exception_check = cfunc.type.exception_check, + exception_check = cfunc_type.exception_check, exception_value = exception_value, - with_gil = cfunc.type.with_gil, - nogil = cfunc.type.nogil) + with_gil = cfunc_type.with_gil, + nogil = cfunc_type.nogil) return CFuncDefNode(self.pos, modifiers = [], - base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc.type.return_type), + base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type), declarator = declarator, body = self.body, doc = self.doc, - overridable = cfunc.type.is_overridable, - type = cfunc.type, - with_gil = cfunc.type.with_gil, - nogil = cfunc.type.nogil, + overridable = cfunc_type.is_overridable, + type = cfunc_type, + with_gil = cfunc_type.with_gil, + nogil = cfunc_type.nogil, visibility = 'private', - api = False) + api = False, + directive_locals = getattr(cfunc, 'directive_locals', {})) def analyse_declarations(self, env): - if 'locals' in env.directives: - directive_locals = env.directives['locals'] - else: - directive_locals = {} - self.directive_locals = directive_locals + directive_locals = self.directive_locals = env.directives['locals'] 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 hasattr(arg, 'name'): + type = arg.type + name_declarator = None + else: + base_type = arg.base_type.analyse(env) + name_declarator, type = \ + arg.declarator.analyse(base_type, env) + arg.name = name_declarator.name if arg.name in directive_locals: type_node = directive_locals[arg.name] other_type = type_node.analyse_as_type(env) @@ -1541,7 +1698,7 @@ error(type_node.pos, "Previous declaration here") else: type = other_type - if name_declarator.cname: + if name_declarator and name_declarator.cname: error(self.pos, "Python function argument cannot have C name specification") arg.type = type.as_argument_type() @@ -1558,9 +1715,11 @@ def analyse_signature(self, env): any_type_tests_needed = 0 - # Use the simpler calling signature for zero- and one-argument functions. - if not self.entry.is_special and not self.star_arg and not self.starstar_arg: - if self.entry.signature is TypeSlots.pyfunction_signature and Options.optimize_simple_methods: + if self.entry.is_special: + self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg) + elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg): + # Use the simpler calling signature for zero- and one-argument functions. + if self.entry.signature is TypeSlots.pyfunction_signature: if len(self.args) == 0: self.entry.signature = TypeSlots.pyfunction_noargs elif len(self.args) == 1: @@ -1572,8 +1731,6 @@ elif len(self.args) == 2: if self.args[1].default is None and not self.args[1].kw_only: self.entry.signature = TypeSlots.ibinaryfunc - elif self.entry.is_special: - self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg) sig = self.entry.signature nfixed = sig.num_fixed_args() for i in range(nfixed): @@ -1607,12 +1764,6 @@ (arg.type.is_extension_type or arg.type.is_builtin_type): arg.needs_type_test = 1 any_type_tests_needed = 1 - elif arg.type is PyrexTypes.c_py_ssize_t_type: - # Want to use __index__ rather than __int__ method - # that PyArg_ParseTupleAndKeywords calls - arg.needs_conversion = 1 - arg.hdr_type = PyrexTypes.py_object_type - arg.hdr_cname = Naming.arg_prefix + arg.name if any_type_tests_needed: env.use_utility_code(arg_type_test_utility_code) @@ -1698,6 +1849,7 @@ env.control_flow.set_state((), (arg.name, 'initalized'), True) def analyse_expressions(self, env): + self.local_scope.directives = env.directives self.analyse_default_values(env) if env.is_py_class_scope: self.synthesize_assignment_node(env) @@ -1787,6 +1939,10 @@ has_star_or_kw_args = self.star_arg is not None \ or self.starstar_arg is not None or has_kwonly_args + for arg in self.args: + if not arg.type.is_pyobject and arg.type.from_py_function is None: + arg.type.create_from_py_utility_code(env) + if not self.signature_has_generic_args(): if has_star_or_kw_args: error(self.pos, "This method cannot have * or keyword arguments") @@ -1804,10 +1960,6 @@ arg_entry = arg.entry if arg.is_generic: if arg.default: - code.putln( - "%s = %s;" % ( - arg_entry.cname, - arg.default_result_code)) default_seen = 1 if not arg.is_self_arg: if arg.kw_only: @@ -1821,14 +1973,6 @@ error(arg.pos, "Non-default argument following default argument") elif not arg.is_self_arg: positional_args.append(arg) - if arg.needs_conversion: - format = arg.hdr_type.parsetuple_format - else: - format = arg_entry.type.parsetuple_format - if not format: - error(arg.pos, - "Cannot convert Python object argument to type '%s' (when parsing input arguments)" - % arg.type) self.generate_tuple_and_keyword_parsing_code( positional_args, kw_only_args, end_label, code) @@ -1906,6 +2050,8 @@ code.putln("if (unlikely(!%s)) return %s;" % ( self.starstar_arg.entry.cname, self.error_value())) self.starstar_arg.entry.xdecref_cleanup = 0 + code.put_gotref(self.starstar_arg.entry.cname) + if self.star_arg: code.put_incref(Naming.args_cname, py_object_type) @@ -1979,11 +2125,13 @@ for i, arg in enumerate(positional_args): item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i) self.generate_arg_assignment(arg, item, code) + self.generate_arg_default_assignments(code) else: # parse the positional arguments from the variable length # args tuple code.putln('} else {') + self.generate_arg_default_assignments(code) code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname) if self.star_arg: code.putln('default:') @@ -2020,6 +2168,14 @@ Naming.args_cname)) code.putln(code.error_goto(self.pos)) + def generate_arg_default_assignments(self, code): + for arg in self.args: + if arg.is_generic and arg.default: + code.putln( + "%s = %s;" % ( + arg.entry.cname, + arg.default_result_code)) + def generate_stararg_init_code(self, max_positional_args, code): if self.starstar_arg: self.starstar_arg.entry.xdecref_cleanup = 0 @@ -2027,6 +2183,7 @@ self.starstar_arg.entry.cname, self.starstar_arg.entry.cname, self.error_value())) + code.put_gotref(self.starstar_arg.entry.cname) if self.star_arg: self.star_arg.entry.xdecref_cleanup = 0 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % ( @@ -2035,6 +2192,7 @@ code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % ( self.star_arg.entry.cname, Naming.args_cname, max_positional_args, Naming.args_cname)) + code.put_gotref(self.star_arg.entry.cname) if self.starstar_arg: code.putln("") code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname) @@ -2055,10 +2213,22 @@ all_args = tuple(positional_args) + tuple(kw_only_args) max_args = len(all_args) - code.putln("PyObject* values[%d] = {%s};" % ( - max_args, ('0,'*max_args)[:-1])) + default_args = [] + for i, arg in enumerate(all_args): + if arg.default and arg.type.is_pyobject: + default_value = arg.default_result_code + if arg.type is not PyrexTypes.py_object_type: + default_value = "(PyObject*)"+default_value + default_args.append((i, default_value)) + code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" % Naming.kwds_cname) + # it looks funny to separate the init-to-0 from setting the + # default value, but C89 needs this + code.putln("PyObject* values[%d] = {%s};" % ( + max_args, ','.join(['0']*max_args))) + for i, default_value in default_args: + code.putln('values[%d] = %s;' % (i, default_value)) # parse the tuple and check that it's not too long code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname) @@ -2074,53 +2244,95 @@ code.put_goto(argtuple_error_label) code.putln('}') - # now fill up the required arguments with values from the kw dict - last_required_arg = -1 - for i, arg in enumerate(all_args): - if not arg.default: - last_required_arg = i - if last_required_arg >= 0: - code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname) + # now fill up the positional/required arguments with values + # from the kw dict + if self.num_required_args or max_positional_args > 0: + last_required_arg = -1 + for i, arg in enumerate(all_args): + if not arg.default: + last_required_arg = i + if last_required_arg < max_positional_args: + last_required_arg = max_positional_args-1 + num_required_args = self.num_required_args + if max_positional_args > 0: + code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname) for i, arg in enumerate(all_args[:last_required_arg+1]): - if i <= max_positional_args: + if max_positional_args > 0 and i <= max_positional_args: if self.star_arg and i == max_positional_args: code.putln('default:') else: code.putln('case %2d:' % i) if arg.default: - # handled in ParseOptionalKeywords() below - continue - code.putln('values[%d] = PyDict_GetItem(%s, %s);' % ( + if arg.kw_only: + # handled separately below + continue + code.putln('if (kw_args > %d) {' % num_required_args) + code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % ( + Naming.kwds_cname, arg.name_entry.pystring_cname)) + code.putln('if (unlikely(value)) { values[%d] = value; kw_args--; }' % i) + code.putln('}') + else: + num_required_args -= 1 + code.putln('values[%d] = PyDict_GetItem(%s, %s);' % ( i, Naming.kwds_cname, arg.name_entry.pystring_cname)) - if i < min_positional_args: code.putln('if (likely(values[%d])) kw_args--;' % i); - if i == 0: - # special case: we know arg 0 is missing - code.put('else ') - code.put_goto(argtuple_error_label) - else: - # print the correct number of values (args or - # kwargs) that were passed into positional - # arguments up to this point - code.putln('else {') - code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % ( - self.name.utf8encode(), has_fixed_positional_count, - min_positional_args, max_positional_args, i)) - code.putln(code.error_goto(self.pos)) - code.putln('}') - else: - code.putln('if (values[%d]) kw_args--;' % i); - if arg.kw_only and not arg.default: + if i < min_positional_args: + if i == 0: + # special case: we know arg 0 is missing + code.put('else ') + code.put_goto(argtuple_error_label) + else: + # print the correct number of values (args or + # kwargs) that were passed into positional + # arguments up to this point + code.putln('else {') + code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % ( + self.name.utf8encode(), has_fixed_positional_count, + min_positional_args, max_positional_args, i)) + code.putln(code.error_goto(self.pos)) + code.putln('}') + elif arg.kw_only: code.putln('else {') code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %( self.name.utf8encode(), arg.name_entry.pystring_cname)) code.putln(code.error_goto(self.pos)) code.putln('}') - code.putln('}') + if max_positional_args > 0: + code.putln('}') + + if kw_only_args and not self.starstar_arg: + # unpack optional keyword-only arguments + # checking for interned strings in a dict is faster than iterating + # but it's too likely that we must iterate if we expect **kwargs + optional_args = [] + for i, arg in enumerate(all_args[max_positional_args:]): + if not arg.kw_only or not arg.default: + continue + optional_args.append((i+max_positional_args, arg)) + if optional_args: + # this mimics an unrolled loop so that we can "break" out of it + code.putln('while (kw_args > 0) {') + code.putln('PyObject* value;') + for i, arg in optional_args: + code.putln( + 'value = PyDict_GetItem(%s, %s);' % ( + Naming.kwds_cname, arg.name_entry.pystring_cname)) + code.putln( + 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i) + code.putln('break;') + code.putln('}') code.putln('if (unlikely(kw_args > 0)) {') - # non-positional kw args left in dict: default args, **kwargs or error - if self.star_arg: + # non-positional/-required kw args left in dict: default args, + # kw-only args, **kwargs or error + # + # This is sort of a catch-all: except for checking required + # arguments, this will always do the right thing for unpacking + # keyword arguments, so that we can concentrate on optimising + # common cases above. + if max_positional_args == 0: + pos_arg_count = "0" + elif self.star_arg: code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % ( Naming.args_cname, max_positional_args, Naming.args_cname, max_positional_args)) @@ -2140,10 +2352,15 @@ # convert arg values to their final type and assign them for i, arg in enumerate(all_args): - if arg.default: + if arg.default and not arg.type.is_pyobject: code.putln("if (values[%d]) {" % i) self.generate_arg_assignment(arg, "values[%d]" % i, code) - if arg.default: + if arg.default and not arg.type.is_pyobject: + code.putln('} else {') + code.putln( + "%s = %s;" % ( + arg.entry.cname, + arg.default_result_code)) code.putln('}') def generate_argument_conversion_code(self, code): @@ -2199,6 +2416,7 @@ func, arg.hdr_cname, code.error_goto_if_null(arg.entry.cname, arg.pos))) + code.put_var_gotref(arg.entry) else: error(arg.pos, "Cannot convert argument of type '%s' to Python object" @@ -2280,8 +2498,8 @@ err = code.error_goto_if_null(self.func_node.result(), self.pos) # need to get attribute manually--scope would return cdef method code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (self.func_node.result(), self_arg, self.py_func.interned_attr_cname, err)) - # It appears that this type is not anywhere exposed in the Python/C API - is_builtin_function_or_method = '(strcmp(Py_TYPE(%s)->tp_name, "builtin_function_or_method") == 0)' % self.func_node.result() + code.put_gotref(self.func_node.py_result()) + is_builtin_function_or_method = 'PyCFunction_Check(%s)' % self.func_node.result() is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (self.func_node.result(), self.py_func.entry.func_cname) code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden)) self.body.generate_execution_code(code) @@ -2327,7 +2545,7 @@ def as_cclass(self): """ - Return this node as if it were declared as an extension class" + Return this node as if it were declared as an extension class """ bases = self.classobj.bases.args if len(bases) == 0: @@ -2336,10 +2554,11 @@ elif len(bases) == 1: base = bases[0] path = [] - while isinstance(base, ExprNodes.AttributeNode): + from ExprNodes import AttributeNode, NameNode + while isinstance(base, AttributeNode): path.insert(0, base.attribute) base = base.obj - if isinstance(base, ExprNodes.NameNode): + if isinstance(base, NameNode): path.insert(0, base.name) base_class_name = path[-1] if len(path) > 1: @@ -2372,6 +2591,7 @@ def analyse_declarations(self, env): self.target.analyse_target_declaration(env) cenv = self.create_scope(env) + cenv.directives = env.directives cenv.class_obj_cname = self.target.entry.cname self.body.analyse_declarations(cenv) @@ -2398,6 +2618,7 @@ self.body.generate_execution_code(code) self.target.generate_assignment_code(self.classobj, code) self.dict.generate_disposal_code(code) + self.dict.free_temps(code) class CClassDefNode(ClassDefNode): @@ -2456,13 +2677,19 @@ if self.module is None: self.module = ModuleScope(self.module_name, None, env.context) self.module.has_extern_class = 1 - env.cimported_modules.append(self.module) + env.add_imported_module(self.module) 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 self.base_class_name == 'object': + # extension classes are special and don't need to inherit from object + if base_class_scope is None or base_class_scope.lookup('object') is None: + self.base_class_name = None + self.base_class_module = None + base_class_scope = None if base_class_scope: base_class_entry = base_class_scope.find(self.base_class_name, self.pos) if base_class_entry: @@ -2482,6 +2709,11 @@ return else: home_scope = env + + if self.visibility == 'extern': + if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types: + warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1) + self.entry = home_scope.declare_c_class( name = self.class_name, pos = self.pos, @@ -2498,6 +2730,8 @@ 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 scope is not None: + scope.directives = env.directives if self.doc and Options.docstrings: scope.doc = embed_position(self.pos, self.doc) @@ -2548,6 +2782,7 @@ doc_entry = env.get_string_const( self.doc, identifier = False) entry.doc_cname = doc_entry.cname + entry.scope.directives = env.directives self.body.analyse_declarations(entry.scope) def analyse_expressions(self, env): @@ -2613,6 +2848,7 @@ if not self.expr.is_temp and self.expr.result(): code.putln("%s;" % self.expr.result()) self.expr.generate_disposal_code(code) + self.expr.free_temps(code) def annotate(self, code): self.expr.annotate(code) @@ -2632,9 +2868,9 @@ self.allocate_rhs_temps(env) self.allocate_lhs_temps(env) -# def analyse_expressions(self, env): -# self.analyse_expressions_1(env) -# self.analyse_expressions_2(env) +# def analyse_expressions(self, env): +# self.analyse_expressions_1(env) +# self.analyse_expressions_2(env) def generate_execution_code(self, code): self.generate_rhs_evaluation_code(code) @@ -2734,21 +2970,8 @@ def allocate_lhs_temps(self, env): self.lhs.allocate_target_temps(env, self.rhs) #self.lhs.release_target_temp(env) - #self.rhs.release_temp(env) - -# def analyse_expressions_1(self, env, use_temp = 0): -# self.rhs.analyse_types(env) -# self.lhs.analyse_target_types(env) -# self.rhs = self.rhs.coerce_to(self.lhs.type, env) -# if use_temp: -# self.rhs = self.rhs.coerce_to_temp(env) -# self.rhs.allocate_temps(env) -# -# def analyse_expressions_2(self, env): -# self.lhs.allocate_target_temps(env) -# self.lhs.release_target_temp(env) -# self.rhs.release_temp(env) - + #self.rhs.release_temp(env) + def generate_rhs_evaluation_code(self, code): self.rhs.generate_evaluation_code(code) @@ -2805,28 +3028,6 @@ #rhs.release_temp(env) self.rhs.release_temp(env) -# def analyse_expressions_1(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) -# self.rhs.allocate_temps(env) -# -# def analyse_expressions_2(self, env): -# from ExprNodes import CloneNode -# self.coerced_rhs_list = [] -# for lhs in self.lhs_list: -# lhs.analyse_target_types(env) -# rhs = CloneNode(self.rhs) -# rhs = rhs.coerce_to(lhs.type, env) -# self.coerced_rhs_list.append(rhs) -# rhs.allocate_temps(env) -# lhs.allocate_target_temps(env) -# 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) @@ -2838,6 +3039,7 @@ lhs.generate_assignment_code(rhs, code) # Assignment has disposed of the cloned RHS self.rhs.generate_disposal_code(code) + self.rhs.free_temps(code) def annotate(self, code): for i in range(len(self.lhs_list)): @@ -2873,11 +3075,11 @@ for stat in self.stats: stat.allocate_lhs_temps(env) -# def analyse_expressions(self, env): -# for stat in self.stats: -# stat.analyse_expressions_1(env, use_temp = 1) -# for stat in self.stats: -# stat.analyse_expressions_2(env) +# def analyse_expressions(self, env): +# for stat in self.stats: +# stat.analyse_expressions_1(env, use_temp = 1) +# for stat in self.stats: +# stat.analyse_expressions_2(env) def generate_execution_code(self, code): for stat in self.stats: @@ -2948,14 +3150,18 @@ self.result_value.release_temp(env) def generate_execution_code(self, code): + import ExprNodes self.rhs.generate_evaluation_code(code) self.dup.generate_subexpr_evaluation_code(code) + if isinstance(self.dup, ExprNodes.NewTempExprNode): + # This is because we're manually messing with subexpr nodes + if self.dup.is_temp: + self.dup.allocate_temp_result(code) # self.dup.generate_result_code is run only if it is not buffer access if self.operator == "**": extra = ", Py_None" else: extra = "" - import ExprNodes if self.lhs.type.is_pyobject: if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access: error(self.pos, "In-place operators not allowed on object buffers in this release.") @@ -2968,19 +3174,22 @@ self.rhs.py_result(), extra, code.error_goto_if_null(self.result_value.py_result(), self.pos))) + code.put_gotref(self.result_value.py_result()) self.result_value.generate_evaluation_code(code) # May be a type check... self.rhs.generate_disposal_code(code) + self.rhs.free_temps(code) self.dup.generate_disposal_code(code) + self.dup.free_temps(code) self.lhs.generate_assignment_code(self.result_value, code) else: c_op = self.operator if c_op == "//": c_op = "/" elif c_op == "**": - if self.lhs.type.is_int and self.rhs.type.is_int: - error(self.pos, "** with two C int types is ambiguous") - else: - error(self.pos, "No C inplace power operator") + error(self.pos, "No C inplace power operator") + elif self.lhs.type.is_complex and not code.globalstate.directives['c99_complex']: + error(self.pos, "Inplace operators not implemented for complex types.") + # have to do assignment directly to avoid side-effects if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access: self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op) @@ -2988,8 +3197,10 @@ self.dup.generate_result_code(code) code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) ) self.rhs.generate_disposal_code(code) + self.rhs.free_temps(code) if self.dup.is_temp: self.dup.generate_subexpr_disposal_code(code) + self.dup.free_subexpr_temps(code) def create_dup_node(self, env): import ExprNodes @@ -3019,6 +3230,8 @@ index = index, indices = indices, is_temp = self.dup.is_temp) + else: + assert False self.lhs = target_lhs return self.dup @@ -3026,18 +3239,18 @@ return self.py_functions[self.operator] py_functions = { - "|": "PyNumber_InPlaceOr", - "^": "PyNumber_InPlaceXor", - "&": "PyNumber_InPlaceAnd", - "+": "PyNumber_InPlaceAdd", - "-": "PyNumber_InPlaceSubtract", - "*": "PyNumber_InPlaceMultiply", - "/": "PyNumber_InPlaceDivide", - "%": "PyNumber_InPlaceRemainder", - "<<": "PyNumber_InPlaceLshift", - ">>": "PyNumber_InPlaceRshift", - "**": "PyNumber_InPlacePower", - "//": "PyNumber_InPlaceFloorDivide", + "|": "PyNumber_InPlaceOr", + "^": "PyNumber_InPlaceXor", + "&": "PyNumber_InPlaceAnd", + "+": "PyNumber_InPlaceAdd", + "-": "PyNumber_InPlaceSubtract", + "*": "PyNumber_InPlaceMultiply", + "/": "PyNumber_InPlaceDivide", + "%": "PyNumber_InPlaceRemainder", + "<<": "PyNumber_InPlaceLshift", + ">>": "PyNumber_InPlaceRshift", + "**": "PyNumber_InPlacePower", + "//": "PyNumber_InPlaceFloorDivide", } def annotate(self, code): @@ -3059,23 +3272,78 @@ self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env) self.arg_tuple.release_temp(env) env.use_utility_code(printing_utility_code) + if len(self.arg_tuple.args) == 1 and self.append_newline: + env.use_utility_code(printing_one_utility_code) self.gil_check(env) gil_message = "Python print statement" def generate_execution_code(self, code): - self.arg_tuple.generate_evaluation_code(code) - code.putln( - "if (__Pyx_Print(%s, %d) < 0) %s" % ( - self.arg_tuple.py_result(), - self.append_newline, - code.error_goto(self.pos))) - self.arg_tuple.generate_disposal_code(code) + if len(self.arg_tuple.args) == 1 and self.append_newline: + arg = self.arg_tuple.args[0] + arg.generate_evaluation_code(code) + + code.putln( + "if (__Pyx_PrintOne(%s) < 0) %s" % ( + arg.py_result(), + code.error_goto(self.pos))) + arg.generate_disposal_code(code) + arg.free_temps(code) + else: + self.arg_tuple.generate_evaluation_code(code) + code.putln( + "if (__Pyx_Print(%s, %d) < 0) %s" % ( + self.arg_tuple.py_result(), + self.append_newline, + code.error_goto(self.pos))) + self.arg_tuple.generate_disposal_code(code) + self.arg_tuple.free_temps(code) def annotate(self, code): self.arg_tuple.annotate(code) +class ExecStatNode(StatNode): + # exec statement + # + # args [ExprNode] + + child_attrs = ["args"] + + def analyse_expressions(self, env): + for i, arg in enumerate(self.args): + arg.analyse_expressions(env) + arg = arg.coerce_to_pyobject(env) + arg.release_temp(env) + self.args[i] = arg + self.temp_result = env.allocate_temp_pyobject() + env.release_temp(self.temp_result) + env.use_utility_code(Builtin.pyexec_utility_code) + self.gil_check(env) + + gil_message = "Python exec statement" + + def generate_execution_code(self, code): + args = [] + for arg in self.args: + arg.generate_evaluation_code(code) + args.append( arg.py_result() ) + args = tuple(args + ['0', '0'][:3-len(args)]) + code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % ( + (self.temp_result,) + args)) + for arg in self.args: + arg.generate_disposal_code(code) + arg.free_temps(code) + code.putln( + code.error_goto_if_null(self.temp_result, self.pos)) + code.put_gotref(self.temp_result) + code.put_decref_clear(self.temp_result, py_object_type) + + def annotate(self, code): + for arg in self.args: + arg.annotate(code) + + class DelStatNode(StatNode): # del statement # @@ -3132,9 +3400,6 @@ 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) @@ -3194,6 +3459,9 @@ if not self.return_type: # error reported earlier return + if self.return_type.is_pyobject: + code.put_xdecref(Naming.retval_cname, + self.return_type) if self.value: self.value.generate_evaluation_code(code) self.value.make_owned_reference(code) @@ -3202,6 +3470,7 @@ Naming.retval_cname, self.value.result_as(self.return_type))) self.value.generate_post_assignment_code(code) + self.value.free_temps(code) else: if self.return_type.is_pyobject: code.put_init_to_py_none(Naming.retval_cname, self.return_type) @@ -3210,11 +3479,15 @@ "%s = %s;" % ( Naming.retval_cname, self.return_type.default_value)) + # free temps the old way for entry in self.temps_in_use: code.put_var_decref_clear(entry) + # free temps the new way + for cname, type in code.funcstate.temps_holding_reference(): + code.put_decref_clear(cname, type) #code.putln( - # "goto %s;" % - # code.return_label) + # "goto %s;" % + # code.return_label) code.put_goto(code.return_label) def annotate(self, code): @@ -3261,7 +3534,7 @@ self.exc_type.generate_evaluation_code(code) type_code = self.exc_type.py_result() else: - type_code = 0 + type_code = "0" if self.exc_value: self.exc_value.generate_evaluation_code(code) value_code = self.exc_value.py_result() @@ -3281,12 +3554,10 @@ else: code.putln( "__Pyx_ReRaise();") - 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) + for obj in (self.exc_type, self.exc_value, self.exc_tb): + if obj: + obj.generate_disposal_code(code) + obj.free_temps(code) code.putln( code.error_goto(self.pos)) @@ -3353,6 +3624,7 @@ "PyErr_SetObject(PyExc_AssertionError, %s);" % self.value.py_result()) self.value.generate_disposal_code(code) + self.value.free_temps(code) else: code.putln( "PyErr_SetNone(PyExc_AssertionError);") @@ -3361,6 +3633,7 @@ code.putln( "}") self.cond.generate_disposal_code(code) + self.cond.free_temps(code) code.putln("#endif") def annotate(self, code): @@ -3442,10 +3715,12 @@ code.putln( "if (%s) {" % self.condition.result()) + self.condition.generate_disposal_code(code) + self.condition.free_temps(code) self.body.generate_execution_code(code) #code.putln( - # "goto %s;" % - # end_label) + # "goto %s;" % + # end_label) code.put_goto(end_label) code.putln("}") @@ -3464,6 +3739,7 @@ def generate_execution_code(self, code): for cond in self.conditions: + code.mark_pos(cond.pos) code.putln("case %s:" % cond.calculate_result_code()) self.body.generate_execution_code(code) code.putln("break;") @@ -3499,7 +3775,7 @@ if self.else_clause is not None: self.else_clause.annotate(code) -class LoopNode: +class LoopNode(object): def analyse_control_flow(self, env): env.start_branching(self.pos) @@ -3538,9 +3814,11 @@ code.putln( "while (1) {") self.condition.generate_evaluation_code(code) + self.condition.generate_disposal_code(code) code.putln( "if (!%s) break;" % self.condition.result()) + self.condition.free_temps(code) self.body.generate_execution_code(code) code.put_label(code.continue_label) code.putln("}") @@ -3560,7 +3838,7 @@ def ForStatNode(pos, **kw): - if kw.has_key('iterator'): + if 'iterator' in kw: return ForInStatNode(pos, **kw) else: return ForFromStatNode(pos, **kw) @@ -3582,58 +3860,10 @@ self.body.analyse_declarations(env) if self.else_clause: self.else_clause.analyse_declarations(env) - - def analyse_range_step(self, args): - import ExprNodes - # The direction must be determined at compile time to set relations. - # Otherwise, return False. - if len(args) < 3: - self.step = ExprNodes.IntNode(pos = args[0].pos, value='1') - self.relation1 = '<=' - self.relation2 = '<' - return True - else: - step = args[2] - if isinstance(step, ExprNodes.UnaryMinusNode) and isinstance(step.operand, ExprNodes.IntNode): - step = ExprNodes.IntNode(pos = step.pos, value=str(-int(step.operand.value, 0))) - if isinstance(step, ExprNodes.IntNode): - step_value = int(step.value, 0) - if step_value > 0: - self.step = step - self.relation1 = '<=' - self.relation2 = '<' - return True - elif step_value < 0: - self.step = ExprNodes.IntNode(pos = step.pos, value=str(-step_value)) - self.relation1 = '>=' - self.relation2 = '>' - return True - return False - - + def analyse_expressions(self, env): import ExprNodes self.target.analyse_target_types(env) - if Options.convert_range and self.target.type.is_int: - sequence = self.iterator.sequence - if isinstance(sequence, ExprNodes.SimpleCallNode) \ - and sequence.self is None \ - and isinstance(sequence.function, ExprNodes.NameNode) \ - and (sequence.function.name == 'range' or sequence.function.name == 'xrange'): - args = sequence.args - # Make sure we can determine direction from step - if self.analyse_range_step(args): - # Mutate to ForFrom loop type - self.__class__ = ForFromStatNode - if len(args) == 1: - self.bound1 = ExprNodes.IntNode(pos = sequence.pos, value='0') - self.bound2 = args[0] - else: - self.bound1 = args[0] - self.bound2 = args[1] - ForFromStatNode.analyse_expressions(self, env) - return - self.iterator.analyse_expressions(env) self.item = ExprNodes.NextNode(self.iterator, env) self.item = self.item.coerce_to(self.target.type, env) @@ -3648,6 +3878,7 @@ def generate_execution_code(self, code): old_loop_labels = code.new_loop_labels() + self.iterator.allocate_counter_temp(code) self.iterator.generate_evaluation_code(code) code.putln( "for (;;) {") @@ -3664,7 +3895,9 @@ self.else_clause.generate_execution_code(code) code.putln("}") code.put_label(break_label) + self.iterator.release_counter_temp(code) self.iterator.generate_disposal_code(code) + self.iterator.free_temps(code) def annotate(self, code): self.target.annotate(code) @@ -3689,55 +3922,68 @@ # # Used internally: # + # from_range bool # is_py_target bool - # loopvar_name string + # loopvar_node ExprNode (usually a NameNode or temp node) # py_loopvar_node PyTempNode or None child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"] - + + is_py_target = False + loopvar_node = None + py_loopvar_node = None + from_range = False + 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) - if self.target.type.is_numeric: - self.bound1 = self.bound1.coerce_to(self.target.type, env) - self.bound2 = self.bound2.coerce_to(self.target.type, env) - else: - self.bound1 = self.bound1.coerce_to_integer(env) - self.bound2 = self.bound2.coerce_to_integer(env) if self.step is not None: if isinstance(self.step, ExprNodes.UnaryMinusNode): warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2) self.step.analyse_types(env) - self.step = self.step.coerce_to_integer(env) - if not (self.bound2.is_name or self.bound2.is_literal): + + target_type = self.target.type + if self.target.type.is_numeric: + loop_type = self.target.type + else: + loop_type = PyrexTypes.c_int_type + if not self.bound1.type.is_pyobject: + loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type) + if not self.bound2.type.is_pyobject: + loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type) + if self.step is not None and not self.step.type.is_pyobject: + loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type) + self.bound1 = self.bound1.coerce_to(loop_type, env) + self.bound2 = self.bound2.coerce_to(loop_type, env) + if not self.bound2.is_literal: self.bound2 = self.bound2.coerce_to_temp(env) + if self.step is not None: + self.step = self.step.coerce_to(loop_type, env) + if not self.step.is_literal: + self.step = self.step.coerce_to_temp(env) + target_type = self.target.type if not (target_type.is_pyobject or target_type.is_numeric): 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) + "for-from loop variable must be c numeric type or Python object") if target_type.is_numeric: - self.is_py_target = 0 + self.is_py_target = False if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access: raise error(self.pos, "Buffer indexing not allowed as for loop target.") - self.loopvar_name = self.target.entry.cname + self.loopvar_node = self.target self.py_loopvar_node = None else: - self.is_py_target = 1 - c_loopvar_node = ExprNodes.TempNode(self.pos, - PyrexTypes.c_long_type, env) + self.is_py_target = True + c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env) c_loopvar_node.allocate_temps(env) - self.loopvar_name = c_loopvar_node.result() + self.loopvar_node = c_loopvar_node self.py_loopvar_node = \ ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env) self.bound1.allocate_temps(env) @@ -3761,24 +4007,61 @@ def generate_execution_code(self, code): old_loop_labels = code.new_loop_labels() + from_range = self.from_range self.bound1.generate_evaluation_code(code) self.bound2.generate_evaluation_code(code) offset, incop = self.relation_table[self.relation1] if self.step is not None: self.step.generate_evaluation_code(code) - incop = "%s=%s" % (incop[0], self.step.result()) + step = self.step.result() + incop = "%s=%s" % (incop[0], step) + if from_range: + loopvar_name = code.funcstate.allocate_temp(self.target.type, False) + else: + loopvar_name = self.loopvar_node.result() code.putln( "for (%s = %s%s; %s %s %s; %s%s) {" % ( - self.loopvar_name, + loopvar_name, self.bound1.result(), offset, - self.loopvar_name, self.relation2, self.bound2.result(), - self.loopvar_name, incop)) + loopvar_name, self.relation2, self.bound2.result(), + loopvar_name, incop)) if self.py_loopvar_node: self.py_loopvar_node.generate_evaluation_code(code) self.target.generate_assignment_code(self.py_loopvar_node, code) + elif from_range: + code.putln("%s = %s;" % ( + self.target.result(), loopvar_name)) self.body.generate_execution_code(code) code.put_label(code.continue_label) + if self.py_loopvar_node: + # This mess is to make for..from loops with python targets behave + # exactly like those with C targets with regards to re-assignment + # of the loop variable. + import ExprNodes + if self.target.entry.is_pyglobal: + # We know target is a NameNode, this is the only ugly case. + target_node = ExprNodes.PyTempNode(self.target.pos, None) + target_node.result_code = code.funcstate.allocate_temp(py_object_type, False) + code.putln("%s = __Pyx_GetName(%s, %s); %s" % ( + target_node.result_code, + Naming.module_cname, + self.target.entry.interned_cname, + code.error_goto_if_null(target_node.result_code, self.target.pos))) + code.put_gotref(target_node.result_code) + else: + target_node = self.target + from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None) + from_py_node.temp_code = loopvar_name + from_py_node.generate_result_code(code) + if self.target.entry.is_pyglobal: + code.put_decref_clear(target_node.result_code, py_object_type) + code.funcstate.release_temp(target_node.result_code) code.putln("}") + if self.py_loopvar_node: + # This is potentially wasteful, but we don't want the semantics to + # depend on whether or not the loop is a python type. + self.py_loopvar_node.generate_evaluation_code(code) + self.target.generate_assignment_code(self.py_loopvar_node, code) break_label = code.break_label code.set_loop_labels(old_loop_labels) if self.else_clause: @@ -3787,9 +4070,14 @@ code.putln("}") code.put_label(break_label) self.bound1.generate_disposal_code(code) + self.bound1.free_temps(code) self.bound2.generate_disposal_code(code) + self.bound2.free_temps(code) if self.step is not None: self.step.generate_disposal_code(code) + self.step.free_temps(code) + if from_range: + code.funcstate.release_temp(loopvar_name) relation_table = { # {relop : (initial offset, increment op)} @@ -3828,7 +4116,7 @@ # body StatNode # except_clauses [ExceptClauseNode] # else_clause StatNode or None - # cleanup_list [Entry] temps to clean up on error + # cleanup_list [Entry] old style temps to clean up on error child_attrs = ["body", "except_clauses", "else_clause"] @@ -3878,25 +4166,34 @@ def generate_execution_code(self, code): old_return_label = code.return_label + old_break_label = code.break_label + old_continue_label = code.continue_label old_error_label = code.new_error_label() our_error_label = code.error_label except_end_label = code.new_label('exception_handled') except_error_label = code.new_label('except_error') except_return_label = code.new_label('except_return') try_return_label = code.new_label('try_return') - try_end_label = code.new_label('try') + try_break_label = code.new_label('try_break') + try_continue_label = code.new_label('try_continue') + try_end_label = code.new_label('try_end') code.putln("{") code.putln("PyObject %s;" % ', '.join(['*%s' % var for var in Naming.exc_save_vars])) code.putln("__Pyx_ExceptionSave(%s);" % ', '.join(['&%s' % var for var in Naming.exc_save_vars])) + for var in Naming.exc_save_vars: + code.put_xgotref(var) code.putln( "/*try:*/ {") code.return_label = try_return_label + code.break_label = try_break_label + code.continue_label = try_continue_label self.body.generate_execution_code(code) code.putln( "}") + temps_to_clean_up = code.funcstate.all_free_managed_temps() code.error_label = except_error_label code.return_label = except_return_label if self.else_clause: @@ -3915,6 +4212,8 @@ code.put_goto(old_return_label) code.put_label(our_error_label) code.put_var_xdecrefs_clear(self.cleanup_list) + for temp_name, type in temps_to_clean_up: + code.put_xdecref_clear(temp_name, type) for except_clause in self.except_clauses: except_clause.generate_handling_code(code, except_end_label) @@ -3925,21 +4224,39 @@ for var in Naming.exc_save_vars: code.put_xdecref(var, py_object_type) code.put_goto(old_error_label) + + if code.label_used(try_break_label): + code.put_label(try_break_label) + for var in Naming.exc_save_vars: code.put_xgiveref(var) + code.putln("__Pyx_ExceptionReset(%s);" % + ', '.join(Naming.exc_save_vars)) + code.put_goto(old_break_label) + + if code.label_used(try_continue_label): + code.put_label(try_continue_label) + for var in Naming.exc_save_vars: code.put_xgiveref(var) + code.putln("__Pyx_ExceptionReset(%s);" % + ', '.join(Naming.exc_save_vars)) + code.put_goto(old_continue_label) if code.label_used(except_return_label): code.put_label(except_return_label) + for var in Naming.exc_save_vars: code.put_xgiveref(var) code.putln("__Pyx_ExceptionReset(%s);" % ', '.join(Naming.exc_save_vars)) code.put_goto(old_return_label) if code.label_used(except_end_label): code.put_label(except_end_label) + for var in Naming.exc_save_vars: code.put_xgiveref(var) code.putln("__Pyx_ExceptionReset(%s);" % ', '.join(Naming.exc_save_vars)) code.put_label(try_end_label) code.putln("}") code.return_label = old_return_label + code.break_label = old_break_label + code.continue_label = old_continue_label code.error_label = old_error_label def annotate(self, code): @@ -3988,7 +4305,12 @@ 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)] + + if self.target or self.excinfo_target: + self.exc_vars = [env.allocate_temp(py_object_type) for i in xrange(3)] + else: + self.exc_vars = None + if self.target: self.exc_value = ExprNodes.ExcValueNode(self.pos, env, self.exc_vars[1]) self.exc_value.allocate_temps(env) @@ -4005,10 +4327,10 @@ self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple) self.body.analyse_expressions(env) - for var in self.exc_vars: - env.release_temp(var) - env.use_utility_code(get_exception_utility_code) - env.use_utility_code(restore_exception_utility_code) + + if self.exc_vars: + for var in self.exc_vars: + env.release_temp(var) def generate_handling_code(self, code, end_label): code.mark_pos(self.pos) @@ -4019,18 +4341,39 @@ self.match_flag, self.pattern.py_result())) self.pattern.generate_disposal_code(code) + self.pattern.free_temps(code) code.putln( "if (%s) {" % self.match_flag) else: code.putln("/*except:*/ {") + + if self.exc_vars: + exc_vars = self.exc_vars + elif not getattr(self.body, 'stats', True): + # most simple case: no exception variable, empty body (pass) + # => reset the exception state, done + code.putln("PyErr_Restore(0,0,0);") + code.put_goto(end_label) + code.putln("}") + return + else: + # during type analysis, we didn't know if we need the + # exception value, but apparently, we do + exc_vars = [code.funcstate.allocate_temp(py_object_type, + manage_ref=True) + for i in xrange(3)] + code.putln('__Pyx_AddTraceback("%s");' % self.function_name) # We always have to fetch the exception value even if # there is no target, because this also normalises the # exception and stores it in the thread state. - exc_args = "&%s, &%s, &%s" % tuple(self.exc_vars) + code.globalstate.use_utility_code(get_exception_utility_code) + exc_args = "&%s, &%s, &%s" % tuple(exc_vars) code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args, code.error_goto(self.pos))) + for x in exc_vars: + code.put_gotref(x) if self.target: self.exc_value.generate_evaluation_code(code) self.target.generate_assignment_code(self.exc_value, code) @@ -4038,13 +4381,38 @@ self.excinfo_tuple.generate_evaluation_code(code) self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code) + + old_break_label, old_continue_label = code.break_label, code.continue_label + code.break_label = code.new_label('except_break') + code.continue_label = code.new_label('except_continue') + old_exc_vars = code.funcstate.exc_vars - code.funcstate.exc_vars = self.exc_vars + code.funcstate.exc_vars = exc_vars self.body.generate_execution_code(code) code.funcstate.exc_vars = old_exc_vars - for var in self.exc_vars: - code.putln("Py_DECREF(%s); %s = 0;" % (var, var)) + for var in exc_vars: + code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var)) code.put_goto(end_label) + + if code.label_used(code.break_label): + code.put_label(code.break_label) + for var in exc_vars: + code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var)) + code.put_goto(old_break_label) + code.break_label = old_break_label + + if code.label_used(code.continue_label): + code.put_label(code.continue_label) + for var in exc_vars: + code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var)) + code.put_goto(old_continue_label) + code.continue_label = old_continue_label + + if not self.exc_vars: + # clean up locally allocated temps + for temp in exc_vars: + code.funcstate.release_temp(temp) + code.putln( "}") @@ -4062,7 +4430,7 @@ # body StatNode # finally_clause StatNode # - # cleanup_list [Entry] temps to clean up on error + # cleanup_list [Entry] old_style temps to clean up on error # # The plan is that we funnel all continue, break # return and error gotos into the beginning of the @@ -4123,6 +4491,7 @@ code.funcstate.in_try_finally = was_in_try_finally code.putln( "}") + temps_to_clean_up = code.funcstate.all_free_managed_temps() code.putln( "/*finally:*/ {") cases_used = [] @@ -4154,7 +4523,7 @@ #if new_label and new_label != "": if new_label == new_error_label and self.preserve_exception: self.put_error_catcher(code, - new_error_label, i+1, catch_label) + new_error_label, i+1, catch_label, temps_to_clean_up) else: code.put('%s: ' % new_label) if exc_var_init_zero: @@ -4194,11 +4563,11 @@ i+1, old_label)) code.putln( - "}") + "}") code.putln( "}") - def put_error_catcher(self, code, error_label, i, catch_label): + def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up): code.globalstate.use_utility_code(restore_exception_utility_code) code.putln( "%s: {" % @@ -4207,6 +4576,8 @@ "__pyx_why = %s;" % i) code.put_var_xdecrefs_clear(self.cleanup_list) + for temp_name, type in temps_to_clean_up: + code.put_xdecref_clear(temp_name, type) code.putln( "__Pyx_ErrFetch(&%s, &%s, &%s);" % Naming.exc_vars) @@ -4214,8 +4585,8 @@ "%s = %s;" % ( Naming.exc_lineno_name, Naming.lineno_cname)) #code.putln( - # "goto %s;" % - # catch_label) + # "goto %s;" % + # catch_label) code.put_goto(catch_label) code.putln( "}") @@ -4260,6 +4631,7 @@ finally_clause = GILExitNode(pos, state = state)) def analyse_expressions(self, env): + env.use_utility_code(force_init_threads_utility_code) was_nogil = env.nogil env.nogil = 1 TryFinallyStatNode.analyse_expressions(self, env) @@ -4269,11 +4641,11 @@ pass def generate_execution_code(self, code): - code.putln("/*with %s:*/ {" % self.state) + code.mark_pos(self.pos) if self.state == 'gil': - code.putln("PyGILState_STATE _save = PyGILState_Ensure();") + code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();") else: - code.putln("PyThreadState *_save;") + code.putln("{ PyThreadState *_save;") code.putln("Py_UNBLOCK_THREADS") TryFinallyStatNode.generate_execution_code(self, code) code.putln("}") @@ -4364,26 +4736,30 @@ entry = module_scope.declare_c_class(name, pos = pos, module_name = self.module_name) else: - error(pos, "Name '%s' not declared in module '%s'" - % (name, self.module_name)) + submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos) + if submodule_scope.parent_module is module_scope: + env.declare_module(as_name or name, submodule_scope, self.pos) + else: + error(pos, "Name '%s' not declared in module '%s'" + % (name, self.module_name)) if entry: local_name = as_name or name env.add_imported_entry(local_name, entry, 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 + 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 @@ -4397,7 +4773,7 @@ # # module ImportNode # items [(string, NameNode)] - # interned_items [(string, NameNode)] + # interned_items [(string, NameNode, ExprNode)] # item PyTempNode used internally # import_star boolean used internally @@ -4428,9 +4804,16 @@ env.use_utility_code(ExprNodes.type_test_utility_code) break else: - self.interned_items.append( - (env.intern_identifier(name), target)) + entry = env.lookup(target.name) + if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value: + continue # already cimported target.analyse_target_expression(env, None) + if target.type is py_object_type: + coerced_item = None + else: + coerced_item = self.item.coerce_to(target.type, env) + self.interned_items.append( + (env.intern_identifier(name), target, coerced_item)) #target.release_target_temp(env) # was release_temp ?!? self.module.release_temp(env) self.item.release_temp(env) @@ -4443,15 +4826,24 @@ Naming.import_star, self.module.py_result(), code.error_goto(self.pos))) - for cname, target in self.interned_items: + for cname, target, coerced_item in self.interned_items: code.putln( '%s = PyObject_GetAttr(%s, %s); %s' % ( self.item.result(), self.module.py_result(), cname, code.error_goto_if_null(self.item.result(), self.pos))) - target.generate_assignment_code(self.item, code) + code.put_gotref(self.item.py_result()) + if coerced_item is None: + target.generate_assignment_code(self.item, code) + else: + coerced_item.allocate_temp_result(code) + coerced_item.generate_result_code(code) + target.generate_assignment_code(coerced_item, code) + if self.item.result() != coerced_item.result(): + code.put_decref_clear(self.item.result(), self.item.type) self.module.generate_disposal_code(code) + self.module.free_temps(code) @@ -4523,7 +4915,7 @@ impl = r""" #if PY_MAJOR_VERSION < 3 static PyObject *__Pyx_GetStdout(void) { - PyObject *f = PySys_GetObject("stdout"); + PyObject *f = PySys_GetObject((char *)"stdout"); if (!f) { PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout"); } @@ -4534,7 +4926,7 @@ PyObject *f; PyObject* v; int i; - + if (!(f = __Pyx_GetStdout())) return -1; for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) { @@ -4563,12 +4955,13 @@ } #else /* Python 3 has a print function */ + static int __Pyx_Print(PyObject *arg_tuple, int newline) { PyObject* kwargs = 0; PyObject* result = 0; PyObject* end_string; if (!%(PRINT_FUNCTION)s) { - %(PRINT_FUNCTION)s = PyObject_GetAttrString(%(BUILTINS)s, "print"); + %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print"); if (!%(PRINT_FUNCTION)s) return -1; } @@ -4594,12 +4987,59 @@ Py_DECREF(result); return 0; } + #endif """ % {'BUILTINS' : Naming.builtins_cname, 'PRINT_FUNCTION' : Naming.print_function, 'PRINT_KWARGS' : Naming.print_function_kwargs} ) + +printing_one_utility_code = UtilityCode( +proto = """ +static int __Pyx_PrintOne(PyObject *o); /*proto*/ +""", +impl = r""" +#if PY_MAJOR_VERSION < 3 + +static int __Pyx_PrintOne(PyObject *o) { + PyObject *f; + if (!(f = __Pyx_GetStdout())) + return -1; + if (PyFile_SoftSpace(f, 0)) { + if (PyFile_WriteString(" ", f) < 0) + return -1; + } + if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0) + return -1; + if (PyFile_WriteString("\n", f) < 0) + return -1; + return 0; + /* the line below is just to avoid compiler + * compiler warnings about unused functions */ + return __Pyx_Print(NULL, 0); +} + +#else /* Python 3 has a print function */ + +static int __Pyx_PrintOne(PyObject *o) { + int res; + PyObject* arg_tuple = PyTuple_New(1); + if (unlikely(!arg_tuple)) + return -1; + Py_INCREF(o); + PyTuple_SET_ITEM(arg_tuple, 0, o); + res = __Pyx_Print(arg_tuple, 1); + Py_DECREF(arg_tuple); + return res; +} + +#endif +""", +requires=[printing_utility_code]) + + + #------------------------------------------------------------------------------------ # The following function is based on do_raise() from ceval.c. @@ -4682,14 +5122,19 @@ """, impl = """ 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); - __Pyx_ErrRestore(type, value, tb); + PyThreadState *tstate = PyThreadState_GET(); + PyObject* tmp_type = tstate->curexc_type; + PyObject* tmp_value = tstate->curexc_value; + PyObject* tmp_tb = tstate->curexc_traceback; + tstate->curexc_type = tstate->exc_type; + tstate->curexc_value = tstate->exc_value; + tstate->curexc_traceback = tstate->exc_traceback; + tstate->exc_type = 0; + tstate->exc_value = 0; + tstate->exc_traceback = 0; + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); } """) @@ -4888,18 +5333,17 @@ PyObject*** first_kw_arg = argnames + num_pos_args; while (PyDict_Next(kwds, &pos, &key, &value)) { - #if PY_MAJOR_VERSION < 3 - if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) { - #else - if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) { - #endif - goto invalid_keyword_type; + name = first_kw_arg; + while (*name && (**name != key)) name++; + if (*name) { + values[name-argnames] = value; } else { - name = argnames; - while (*name && (**name != key)) name++; - if (*name) { - if (name < first_kw_arg) goto arg_passed_twice; - values[name-argnames] = value; + #if PY_MAJOR_VERSION < 3 + if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) { + #else + if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) { + #endif + goto invalid_keyword_type; } else { for (name = first_kw_arg; *name; name++) { #if PY_MAJOR_VERSION >= 3 @@ -4907,8 +5351,7 @@ PyUnicode_Compare(**name, key) == 0) break; #else if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) && - strcmp(PyString_AS_STRING(**name), - PyString_AS_STRING(key)) == 0) break; + _PyString_Eq(**name, key)) break; #endif } if (*name) { @@ -4922,8 +5365,7 @@ PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice; #else if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) && - strcmp(PyString_AS_STRING(**name), - PyString_AS_STRING(key)) == 0) goto arg_passed_twice; + _PyString_Eq(**name, key)) goto arg_passed_twice; #endif } if (kwds2) { @@ -4959,32 +5401,6 @@ #------------------------------------------------------------------------------------ -unraisable_exception_utility_code = UtilityCode( -proto = """ -static void __Pyx_WriteUnraisable(const char *name); /*proto*/ -""", -impl = """ -static void __Pyx_WriteUnraisable(const char *name) { - PyObject *old_exc, *old_val, *old_tb; - PyObject *ctx; - __Pyx_ErrFetch(&old_exc, &old_val, &old_tb); - #if PY_MAJOR_VERSION < 3 - ctx = PyString_FromString(name); - #else - ctx = PyUnicode_FromString(name); - #endif - __Pyx_ErrRestore(old_exc, old_val, old_tb); - if (!ctx) { - PyErr_WriteUnraisable(Py_None); - } else { - PyErr_WriteUnraisable(ctx); - Py_DECREF(ctx); - } -} -""") - -#------------------------------------------------------------------------------------ - traceback_utility_code = UtilityCode( proto = """ static void __Pyx_AddTraceback(const char *funcname); /*proto*/ @@ -5086,6 +5502,23 @@ PyObject *tmp_type, *tmp_value, *tmp_tb; PyThreadState *tstate = PyThreadState_GET(); +#if PY_MAJOR_VERSION >= 3 + /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */ + if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) { + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + PyErr_NormalizeException(&type, &value, &tb); + PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb); + tstate->exc_type = 0; + tstate->exc_value = 0; + tstate->exc_traceback = 0; + PyException_SetContext(value, tmp_value); + Py_DECREF(tmp_type); + Py_XDECREF(tmp_tb); + } +#endif + tmp_type = tstate->curexc_type; tmp_value = tstate->curexc_value; tmp_tb = tstate->curexc_traceback; @@ -5112,6 +5545,33 @@ #------------------------------------------------------------------------------------ +unraisable_exception_utility_code = UtilityCode( +proto = """ +static void __Pyx_WriteUnraisable(const char *name); /*proto*/ +""", +impl = """ +static void __Pyx_WriteUnraisable(const char *name) { + PyObject *old_exc, *old_val, *old_tb; + PyObject *ctx; + __Pyx_ErrFetch(&old_exc, &old_val, &old_tb); + #if PY_MAJOR_VERSION < 3 + ctx = PyString_FromString(name); + #else + ctx = PyUnicode_FromString(name); + #endif + __Pyx_ErrRestore(old_exc, old_val, old_tb); + if (!ctx) { + PyErr_WriteUnraisable(Py_None); + } else { + PyErr_WriteUnraisable(ctx); + Py_DECREF(ctx); + } +} +""", +requires=[restore_exception_utility_code]) + +#------------------------------------------------------------------------------------ + set_vtable_utility_code = UtilityCode( proto = """ static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/ @@ -5147,8 +5607,8 @@ static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) { int result; PyObject *pycobj; - - pycobj = PyMapping_GetItemString(dict, "__pyx_vtable__"); + + pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__"); if (!pycobj) goto bad; *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj); @@ -5209,7 +5669,12 @@ static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) { PyObject *tmp_type, *tmp_value, *tmp_tb; PyThreadState *tstate = PyThreadState_GET(); - __Pyx_ErrFetch(type, value, tb); + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; PyErr_NormalizeException(type, value, tb); if (PyErr_Occurred()) goto bad; @@ -5271,3 +5736,16 @@ """) #------------------------------------------------------------------------------------ + +force_init_threads_utility_code = UtilityCode( +proto=""" +#ifndef __PYX_FORCE_INIT_THREADS +#if PY_VERSION_HEX < 0x02040200 +#define __PYX_FORCE_INIT_THREADS 1 +#else +#define __PYX_FORCE_INIT_THREADS 0 +#endif +#endif +""") + +#------------------------------------------------------------------------------------ diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/Optimize.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/Optimize.py --- cython-0.10.3/Cython/Compiler/Optimize.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/Optimize.py 2009-05-20 16:37:46.000000000 +0100 @@ -2,10 +2,22 @@ import ExprNodes import PyrexTypes import Visitor +import Builtin +import UtilNodes +import TypeSlots +import Symtab +import Options +from StringEncoding import EncodedString + +from ParseTreeTransforms import SkipDeclarations + +#def unwrap_node(node): +# while isinstance(node, ExprNodes.PersistentNode): +# node = node.arg +# return node +# Temporary hack while PersistentNode is out of order def unwrap_node(node): - while isinstance(node, ExprNodes.PersistentNode): - node = node.arg return node def is_common_value(a, b): @@ -18,6 +30,270 @@ return False +class IterationTransform(Visitor.VisitorTransform): + """Transform some common for-in loop patterns into efficient C loops: + + - for-in-dict loop becomes a while loop calling PyDict_Next() + - for-in-range loop becomes a plain C for loop + """ + PyDict_Next_func_type = PyrexTypes.CFuncType( + PyrexTypes.c_bint_type, [ + PyrexTypes.CFuncTypeArg("dict", PyrexTypes.py_object_type, None), + PyrexTypes.CFuncTypeArg("pos", PyrexTypes.c_py_ssize_t_ptr_type, None), + PyrexTypes.CFuncTypeArg("key", PyrexTypes.CPtrType(PyrexTypes.py_object_type), None), + PyrexTypes.CFuncTypeArg("value", PyrexTypes.CPtrType(PyrexTypes.py_object_type), None) + ]) + + PyDict_Next_name = EncodedString("PyDict_Next") + + PyDict_Next_entry = Symtab.Entry( + PyDict_Next_name, PyDict_Next_name, PyDict_Next_func_type) + + visit_Node = Visitor.VisitorTransform.recurse_to_children + + def visit_ModuleNode(self, node): + self.current_scope = node.scope + self.visitchildren(node) + return node + + def visit_DefNode(self, node): + oldscope = self.current_scope + self.current_scope = node.entry.scope + self.visitchildren(node) + self.current_scope = oldscope + return node + + def visit_ForInStatNode(self, node): + self.visitchildren(node) + iterator = node.iterator.sequence + if iterator.type is Builtin.dict_type: + # like iterating over dict.keys() + return self._transform_dict_iteration( + node, dict_obj=iterator, keys=True, values=False) + if not isinstance(iterator, ExprNodes.SimpleCallNode): + return node + + function = iterator.function + # dict iteration? + if isinstance(function, ExprNodes.AttributeNode) and \ + function.obj.type == Builtin.dict_type: + dict_obj = function.obj + method = function.attribute + + keys = values = False + if method == 'iterkeys': + keys = True + elif method == 'itervalues': + values = True + elif method == 'iteritems': + keys = values = True + else: + return node + return self._transform_dict_iteration( + node, dict_obj, keys, values) + + # range() iteration? + if Options.convert_range and node.target.type.is_int: + if iterator.self is None and \ + isinstance(function, ExprNodes.NameNode) and \ + function.entry.is_builtin and \ + function.name in ('range', 'xrange'): + return self._transform_range_iteration(node, iterator) + + return node + + def _transform_range_iteration(self, node, range_function): + args = range_function.arg_tuple.args + if len(args) < 3: + step_pos = range_function.pos + step_value = 1 + step = ExprNodes.IntNode(step_pos, value=1) + else: + step = args[2] + step_pos = step.pos + if not isinstance(step.constant_result, (int, long)): + # cannot determine step direction + return node + step_value = step.constant_result + if step_value == 0: + # will lead to an error elsewhere + return node + if not isinstance(step, ExprNodes.IntNode): + step = ExprNodes.IntNode(step_pos, value=step_value) + + if step_value < 0: + step.value = -step_value + relation1 = '>=' + relation2 = '>' + else: + relation1 = '<=' + relation2 = '<' + + if len(args) == 1: + bound1 = ExprNodes.IntNode(range_function.pos, value=0) + bound2 = args[0].coerce_to_integer(self.current_scope) + else: + bound1 = args[0].coerce_to_integer(self.current_scope) + bound2 = args[1].coerce_to_integer(self.current_scope) + step = step.coerce_to_integer(self.current_scope) + + for_node = Nodes.ForFromStatNode( + node.pos, + target=node.target, + bound1=bound1, relation1=relation1, + relation2=relation2, bound2=bound2, + step=step, body=node.body, + else_clause=node.else_clause, + from_range=True) + return for_node + + def _transform_dict_iteration(self, node, dict_obj, keys, values): + py_object_ptr = PyrexTypes.c_void_ptr_type + + temps = [] + temp = UtilNodes.TempHandle(PyrexTypes.py_object_type) + temps.append(temp) + dict_temp = temp.ref(dict_obj.pos) + temp = UtilNodes.TempHandle(PyrexTypes.c_py_ssize_t_type) + temps.append(temp) + pos_temp = temp.ref(node.pos) + pos_temp_addr = ExprNodes.AmpersandNode( + node.pos, operand=pos_temp, + type=PyrexTypes.c_ptr_type(PyrexTypes.c_py_ssize_t_type)) + if keys: + temp = UtilNodes.TempHandle(py_object_ptr) + temps.append(temp) + key_temp = temp.ref(node.target.pos) + key_temp_addr = ExprNodes.AmpersandNode( + node.target.pos, operand=key_temp, + type=PyrexTypes.c_ptr_type(py_object_ptr)) + else: + key_temp_addr = key_temp = ExprNodes.NullNode( + pos=node.target.pos) + if values: + temp = UtilNodes.TempHandle(py_object_ptr) + temps.append(temp) + value_temp = temp.ref(node.target.pos) + value_temp_addr = ExprNodes.AmpersandNode( + node.target.pos, operand=value_temp, + type=PyrexTypes.c_ptr_type(py_object_ptr)) + else: + value_temp_addr = value_temp = ExprNodes.NullNode( + pos=node.target.pos) + + key_target = value_target = node.target + tuple_target = None + if keys and values: + if node.target.is_sequence_constructor: + if len(node.target.args) == 2: + key_target, value_target = node.target.args + else: + # unusual case that may or may not lead to an error + return node + else: + tuple_target = node.target + + def coerce_object_to(obj_node, dest_type): + class FakeEnv(object): + nogil = False + if dest_type.is_pyobject: + if dest_type.is_extension_type or dest_type.is_builtin_type: + obj_node = ExprNodes.PyTypeTestNode(obj_node, dest_type, FakeEnv()) + result = ExprNodes.TypecastNode( + obj_node.pos, + operand = obj_node, + type = dest_type) + return (result, None) + else: + temp = UtilNodes.TempHandle(dest_type) + temps.append(temp) + temp_result = temp.ref(obj_node.pos) + class CoercedTempNode(ExprNodes.CoerceFromPyTypeNode): + def result(self): + return temp_result.result() + def generate_execution_code(self, code): + self.generate_result_code(code) + return (temp_result, CoercedTempNode(dest_type, obj_node, FakeEnv())) + + if isinstance(node.body, Nodes.StatListNode): + body = node.body + else: + body = Nodes.StatListNode(pos = node.body.pos, + stats = [node.body]) + + if tuple_target: + tuple_result = ExprNodes.TupleNode( + pos = tuple_target.pos, + args = [key_temp, value_temp], + is_temp = 1, + type = Builtin.tuple_type, + ) + body.stats.insert( + 0, Nodes.SingleAssignmentNode( + pos = tuple_target.pos, + lhs = tuple_target, + rhs = tuple_result)) + else: + # execute all coercions before the assignments + coercion_stats = [] + assign_stats = [] + if keys: + temp_result, coercion = coerce_object_to( + key_temp, key_target.type) + if coercion: + coercion_stats.append(coercion) + assign_stats.append( + Nodes.SingleAssignmentNode( + pos = key_temp.pos, + lhs = key_target, + rhs = temp_result)) + if values: + temp_result, coercion = coerce_object_to( + value_temp, value_target.type) + if coercion: + coercion_stats.append(coercion) + assign_stats.append( + Nodes.SingleAssignmentNode( + pos = value_temp.pos, + lhs = value_target, + rhs = temp_result)) + body.stats[0:0] = coercion_stats + assign_stats + + result_code = [ + Nodes.SingleAssignmentNode( + pos = dict_obj.pos, + lhs = dict_temp, + rhs = dict_obj), + Nodes.SingleAssignmentNode( + pos = node.pos, + lhs = pos_temp, + rhs = ExprNodes.IntNode(node.pos, value=0)), + Nodes.WhileStatNode( + pos = node.pos, + condition = ExprNodes.SimpleCallNode( + pos = dict_obj.pos, + type = PyrexTypes.c_bint_type, + function = ExprNodes.NameNode( + pos = dict_obj.pos, + name = self.PyDict_Next_name, + type = self.PyDict_Next_func_type, + entry = self.PyDict_Next_entry), + args = [dict_temp, pos_temp_addr, + key_temp_addr, value_temp_addr] + ), + body = body, + else_clause = node.else_clause + ) + ] + + return UtilNodes.TempsBlockNode( + node.pos, temps=temps, + body=Nodes.StatListNode( + node.pos, + stats = result_code + )) + + class SwitchTransform(Visitor.VisitorTransform): """ This transformation tries to turn long if statements into C switch statements. @@ -82,13 +358,10 @@ cases = cases, else_clause = node.else_clause) - - def visit_Node(self, node): - self.visitchildren(node) - return node + visit_Node = Visitor.VisitorTransform.recurse_to_children -class FlattenInListTransform(Visitor.VisitorTransform): +class FlattenInListTransform(Visitor.VisitorTransform, SkipDeclarations): """ This transformation flattens "x in [val1, ..., valn]" into a sequential list of comparisons. @@ -107,38 +380,232 @@ else: return node - if isinstance(node.operand2, ExprNodes.TupleNode) or isinstance(node.operand2, ExprNodes.ListNode): - args = node.operand2.args - if len(args) == 0: - return ExprNodes.BoolNode(pos = node.pos, value = node.operator == 'not_in') - else: - lhs = ExprNodes.PersistentNode(node.operand1, len(args)) - conds = [] - for arg in args: - cond = ExprNodes.PrimaryCmpNode( - pos = node.pos, - operand1 = lhs, - operator = eq_or_neq, - operand2 = arg, - cascade = None) - conds.append(ExprNodes.TypecastNode( - pos = node.pos, - operand = cond, - type = PyrexTypes.c_bint_type)) - def concat(left, right): - return ExprNodes.BoolBinopNode( - pos = node.pos, - operator = conjunction, - operand1 = left, - operand2 = right) - return reduce(concat, conds) + if not isinstance(node.operand2, (ExprNodes.TupleNode, ExprNodes.ListNode)): + return node + + args = node.operand2.args + if len(args) == 0: + return ExprNodes.BoolNode(pos = node.pos, value = node.operator == 'not_in') + + lhs = UtilNodes.ResultRefNode(node.operand1) + + conds = [] + for arg in args: + cond = ExprNodes.PrimaryCmpNode( + pos = node.pos, + operand1 = lhs, + operator = eq_or_neq, + operand2 = arg, + cascade = None) + conds.append(ExprNodes.TypecastNode( + pos = node.pos, + operand = cond, + type = PyrexTypes.c_bint_type)) + def concat(left, right): + return ExprNodes.BoolBinopNode( + pos = node.pos, + operator = conjunction, + operand1 = left, + operand2 = right) + + condition = reduce(concat, conds) + return UtilNodes.EvalWithTempExprNode(lhs, condition) + + visit_Node = Visitor.VisitorTransform.recurse_to_children + + +class FlattenBuiltinTypeCreation(Visitor.VisitorTransform): + """Optimise some common instantiation patterns for builtin types. + """ + PyList_AsTuple_func_type = PyrexTypes.CFuncType( + PyrexTypes.py_object_type, [ + PyrexTypes.CFuncTypeArg("list", Builtin.list_type, None) + ]) + + PyList_AsTuple_name = EncodedString("PyList_AsTuple") + + PyList_AsTuple_entry = Symtab.Entry( + PyList_AsTuple_name, PyList_AsTuple_name, PyList_AsTuple_func_type) + + def visit_GeneralCallNode(self, node): + self.visitchildren(node) + handler = self._find_handler('general', node.function) + if handler is not None: + node = handler(node, node.positional_args, node.keyword_args) + return node + + def visit_SimpleCallNode(self, node): + self.visitchildren(node) + handler = self._find_handler('simple', node.function) + if handler is not None: + node = handler(node, node.arg_tuple) + return node + + def _find_handler(self, call_type, function): + if not function.type.is_builtin_type: + return None + if not isinstance(function, ExprNodes.NameNode): + return None + handler = getattr(self, '_handle_%s_%s' % (call_type, function.name), None) + if handler is None: + handler = getattr(self, '_handle_any_%s' % function.name, None) + return handler + + def _handle_general_dict(self, node, pos_args, kwargs): + """Replace dict(a=b,c=d,...) by the underlying keyword dict + construction which is done anyway. + """ + if not isinstance(pos_args, ExprNodes.TupleNode): + return node + if len(pos_args.args) > 0: + return node + if not isinstance(kwargs, ExprNodes.DictNode): + return node + if node.starstar_arg: + # we could optimise this by updating the kw dict instead + return node + return kwargs + + def _handle_simple_set(self, node, pos_args): + """Replace set([a,b,...]) by a literal set {a,b,...}. + """ + if not isinstance(pos_args, ExprNodes.TupleNode): + return node + arg_count = len(pos_args.args) + if arg_count == 0: + return ExprNodes.SetNode(node.pos, args=[], + type=Builtin.set_type, is_temp=1) + if arg_count > 1: + return node + iterable = pos_args.args[0] + if isinstance(iterable, (ExprNodes.ListNode, ExprNodes.TupleNode)): + return ExprNodes.SetNode(node.pos, args=iterable.args, + type=Builtin.set_type, is_temp=1) + elif isinstance(iterable, ExprNodes.ComprehensionNode) and \ + iterable.type is Builtin.list_type: + iterable.target = ExprNodes.SetNode( + node.pos, args=[], type=Builtin.set_type, is_temp=1) + iterable.type = Builtin.set_type + iterable.pos = node.pos + return iterable else: return node - - def visit_Node(self, node): + + def _handle_simple_tuple(self, node, pos_args): + """Replace tuple([...]) by a call to PyList_AsTuple. + """ + if not isinstance(pos_args, ExprNodes.TupleNode): + return node + if len(pos_args.args) != 1: + return node + list_arg = pos_args.args[0] + if list_arg.type is not Builtin.list_type: + return node + if not isinstance(list_arg, (ExprNodes.ComprehensionNode, + ExprNodes.ListNode)): + # everything else may be None => take the safe path + return node + + node.args = pos_args.args + node.arg_tuple = None + node.type = Builtin.tuple_type + node.result_ctype = Builtin.tuple_type + node.function = ExprNodes.NameNode( + pos = node.pos, + name = self.PyList_AsTuple_name, + type = self.PyList_AsTuple_func_type, + entry = self.PyList_AsTuple_entry) + return node + + def visit_PyTypeTestNode(self, node): + """Flatten redundant type checks after tree changes. + """ + old_arg = node.arg + self.visitchildren(node) + if old_arg is node.arg or node.arg.type != node.type: + return node + return node.arg + + visit_Node = Visitor.VisitorTransform.recurse_to_children + + +class ConstantFolding(Visitor.VisitorTransform, SkipDeclarations): + """Calculate the result of constant expressions to store it in + ``expr_node.constant_result``, and replace trivial cases by their + constant result. + """ + def _calculate_const(self, node): + if node.constant_result is not ExprNodes.constant_value_not_set: + return + + # make sure we always set the value + not_a_constant = ExprNodes.not_a_constant + node.constant_result = not_a_constant + + # check if all children are constant + children = self.visitchildren(node) + for child_result in children.itervalues(): + if type(child_result) is list: + for child in child_result: + if child.constant_result is not_a_constant: + return + elif child_result.constant_result is not_a_constant: + return + + # now try to calculate the real constant value + try: + node.calculate_constant_result() +# if node.constant_result is not ExprNodes.not_a_constant: +# print node.__class__.__name__, node.constant_result + except (ValueError, TypeError, KeyError, IndexError, AttributeError): + # ignore all 'normal' errors here => no constant result + pass + except Exception: + # this looks like a real error + import traceback, sys + traceback.print_exc(file=sys.stdout) + + def visit_ExprNode(self, node): + self._calculate_const(node) + return node + +# def visit_NumBinopNode(self, node): + def visit_BinopNode(self, node): + self._calculate_const(node) + if node.type is PyrexTypes.py_object_type: + return node + if node.constant_result is ExprNodes.not_a_constant: + return node +# print node.constant_result, node.operand1, node.operand2, node.pos + if isinstance(node.operand1, ExprNodes.ConstNode) and \ + node.type is node.operand1.type: + new_node = node.operand1 + elif isinstance(node.operand2, ExprNodes.ConstNode) and \ + node.type is node.operand2.type: + new_node = node.operand2 + else: + return node + new_node.value = new_node.constant_result = node.constant_result + new_node = new_node.coerce_to(node.type, self.current_scope) + return new_node + + # in the future, other nodes can have their own handler method here + # that can replace them with a constant result node + + def visit_ModuleNode(self, node): + self.current_scope = node.scope + self.visitchildren(node) + return node + + def visit_FuncDefNode(self, node): + old_scope = self.current_scope + self.current_scope = node.entry.scope self.visitchildren(node) + self.current_scope = old_scope return node + visit_Node = Visitor.VisitorTransform.recurse_to_children + class FinalOptimizePhase(Visitor.CythonTransform): """ @@ -150,6 +617,10 @@ - isinstance -> typecheck for cdef types """ def visit_SingleAssignmentNode(self, node): + """Avoid redundant initialisation of local variables before their + first assignment. + """ + self.visitchildren(node) if node.first: lhs = node.lhs lhs.lhs_of_first_assignment = True @@ -160,16 +631,17 @@ return node def visit_SimpleCallNode(self, node): + """Replace generic calls to isinstance(x, type) by a more efficient + type check. + """ self.visitchildren(node) if node.function.type.is_cfunction and isinstance(node.function, ExprNodes.NameNode): if node.function.name == 'isinstance': type_arg = node.args[1] if type_arg.type.is_builtin_type and type_arg.type.name == 'type': - object_module = self.context.find_module('python_object') - node.function.entry = object_module.lookup('PyObject_TypeCheck') - if node.function.entry is None: - return node # only happens when there was an error earlier + from CythonScope import utility_scope + node.function.entry = utility_scope.lookup('PyObject_TypeCheck') node.function.type = node.function.entry.type - PyTypeObjectPtr = PyrexTypes.CPtrType(object_module.lookup('PyTypeObject').type) + PyTypeObjectPtr = PyrexTypes.CPtrType(utility_scope.lookup('PyTypeObject').type) node.args[1] = ExprNodes.CastNode(node.args[1], PyTypeObjectPtr) return node diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/Options.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/Options.py --- cython-0.10.3/Cython/Compiler/Options.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/Options.py 2009-05-20 16:37:46.000000000 +0100 @@ -45,30 +45,37 @@ # WARNING: This is a work in progress, may currently segfault. init_local_none = 1 -# Optimize no argument and one argument methods by using the METH_O and METH_NOARGS -# calling conventions. These are faster calling conventions, but disallow the use of -# keywords (which, admittedly, are of little use in these cases). -optimize_simple_methods = 1 - # Append the c file and line number to the traceback for exceptions. c_line_in_traceback = 1 +# Whether or not to embed the Python interpreter, for use in making a +# standalone executable. This will provide a main() method which simply +# executes the body of this module. +embed = False -# Declare pragmas -option_types = { - 'boundscheck' : bool, - 'nonecheck' : bool, - 'embedsignature' : bool, - 'locals' : dict, -} +# Declare compiler directives option_defaults = { 'boundscheck' : True, 'nonecheck' : False, 'embedsignature' : False, - 'locals' : {} + 'locals' : {}, + 'auto_cpdef': False, + 'cdivision': True, # Will be False in 0.12 + 'cdivision_warnings': False, + 'always_allow_keywords': False, + 'wraparound' : True, + 'c99_complex' : False, # Don't use macro wrappers for complex arith, not sure what to name this... + 'callspec' : "", } +# Override types possibilities above, if needed +option_types = { } + +for key, val in option_defaults.items(): + if key not in option_types: + option_types[key] = type(val) + def parse_option_value(name, value): """ Parses value as an option value for the given name and returns @@ -90,6 +97,11 @@ if value == "True": return True elif value == "False": return False else: raise ValueError("%s directive must be set to True or False" % name) + elif type is int: + try: + return int(value) + except ValueError: + raise ValueError("%s directive must be set to an integer" % name) else: assert False diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/ParseTreeTransforms.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/ParseTreeTransforms.py --- cython-0.10.3/Cython/Compiler/ParseTreeTransforms.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/ParseTreeTransforms.py 2009-05-20 16:37:46.000000000 +0100 @@ -1,9 +1,9 @@ -from Cython.Compiler.Visitor import VisitorTransform, CythonTransform +from Cython.Compiler.Visitor import VisitorTransform, CythonTransform, TreeVisitor from Cython.Compiler.ModuleNode import ModuleNode from Cython.Compiler.Nodes import * from Cython.Compiler.ExprNodes import * from Cython.Compiler.UtilNodes import * -from Cython.Compiler.TreeFragment import TreeFragment +from Cython.Compiler.TreeFragment import TreeFragment, TemplateTransform from Cython.Compiler.StringEncoding import EncodedString from Cython.Compiler.Errors import CompileError try: @@ -12,6 +12,48 @@ from sets import Set as set import copy + +class NameNodeCollector(TreeVisitor): + """Collect all NameNodes of a (sub-)tree in the ``name_nodes`` + attribute. + """ + def __init__(self): + super(NameNodeCollector, self).__init__() + self.name_nodes = [] + + visit_Node = TreeVisitor.visitchildren + + def visit_NameNode(self, node): + self.name_nodes.append(node) + + +class SkipDeclarations(object): + """ + Variable and function declarations can often have a deep tree structure, + and yet most transformations don't need to descend to this depth. + + Declaration nodes are removed after AnalyseDeclarationsTransform, so there + is no need to use this for transformations after that point. + """ + def visit_CTypeDefNode(self, node): + return node + + def visit_CVarDefNode(self, node): + return node + + def visit_CDeclaratorNode(self, node): + return node + + def visit_CBaseTypeNode(self, node): + return node + + def visit_CEnumDefNode(self, node): + return node + + def visit_CStructOrUnionDefNode(self, node): + return node + + class NormalizeTree(CythonTransform): """ This transform fixes up a few things after parsing @@ -77,6 +119,9 @@ else: return [] + def visit_CDeclaratorNode(self, node): + return node + class PostParseError(CompileError): pass @@ -202,7 +247,7 @@ raise PostParseError(node.pos, ERR_BUF_LOCALONLY) return node -class PxdPostParse(CythonTransform): +class PxdPostParse(CythonTransform, SkipDeclarations): """ Basic interpretation/validity checking that should only be done on pxd trees. @@ -212,8 +257,12 @@ - "def" functions are let through only if they fill the getbuffer/releasebuffer slots + + - cdef functions are let through only if they are on the + top level and are declared "inline" """ - ERR_FUNCDEF_NOT_ALLOWED = 'function definition not allowed here' + ERR_INLINE_ONLY = "function definition in pxd file must be declared 'cdef inline'" + ERR_NOGO_WITH_INLINE = "inline function definition in pxd file cannot be '%s'" def __call__(self, node): self.scope_type = 'pxd' @@ -229,20 +278,31 @@ def visit_FuncDefNode(self, node): # FuncDefNode always come with an implementation (without # an imp they are CVarDefNodes..) - ok = False + err = self.ERR_INLINE_ONLY if (isinstance(node, DefNode) and self.scope_type == 'cclass' and node.name in ('__getbuffer__', '__releasebuffer__')): - ok = True + err = None # allow these slots + + if isinstance(node, CFuncDefNode): + if u'inline' in node.modifiers and self.scope_type == 'pxd': + node.inline_in_pxd = True + if node.visibility != 'private': + err = self.ERR_NOGO_WITH_INLINE % node.visibility + elif node.api: + err = self.ERR_NOGO_WITH_INLINE % 'api' + else: + err = None # allow inline function + else: + err = self.ERR_INLINE_ONLY - if not ok: - self.context.nonfatal_error(PostParseError(node.pos, - self.ERR_FUNCDEF_NOT_ALLOWED)) + if err: + self.context.nonfatal_error(PostParseError(node.pos, err)) return None else: return node - -class InterpretCompilerDirectives(CythonTransform): + +class InterpretCompilerDirectives(CythonTransform, SkipDeclarations): """ After parsing, options can be stored in a number of places: - #cython-comments at the top of the file (stored in ModuleNode) @@ -272,13 +332,20 @@ def __init__(self, context, compilation_option_overrides): super(InterpretCompilerDirectives, self).__init__(context) - self.compilation_option_overrides = compilation_option_overrides + self.compilation_option_overrides = {} + for key, value in compilation_option_overrides.iteritems(): + self.compilation_option_overrides[unicode(key)] = value self.cython_module_names = set() self.option_names = {} # Set up processing and handle the cython: comments. def visit_ModuleNode(self, node): options = copy.copy(Options.option_defaults) + for key, value in self.compilation_option_overrides.iteritems(): + if key in node.option_comments and node.option_comments[key] != value: + warning(node.pos, "Compiler directive differs between environment and file header; this will change " + "in Cython 0.12. See http://article.gmane.org/gmane.comp.python.cython.devel/5233", 2) + break options.update(node.option_comments) options.update(self.compilation_option_overrides) self.options = options @@ -349,10 +416,6 @@ else: node.cython_attribute = self.option_names.get(node.name) return node - - def visit_Node(self, node): - self.visitchildren(node) - return node def try_to_parse_option(self, node): # If node is the contents of an option (in a with statement or @@ -372,6 +435,11 @@ raise PostParseError(dec.function.pos, 'The %s option takes one compile-time boolean argument' % optname) return (optname, args[0].value) + elif optiontype is str: + if kwds is not None or len(args) != 1 or not isinstance(args[0], StringNode): + raise PostParseError(dec.function.pos, + 'The %s option takes one compile-time string argument' % optname) + return (optname, args[0].value) elif optiontype is dict: if len(args) != 0: raise PostParseError(dec.function.pos, @@ -395,7 +463,7 @@ return directive # Handle decorators - def visit_DefNode(self, node): + def visit_FuncDefNode(self, node): options = [] if node.decorators: @@ -407,7 +475,10 @@ options.append(option) else: realdecs.append(dec) - node.decorators = realdecs + if realdecs and isinstance(node, CFuncDefNode): + raise PostParseError(realdecs[0].pos, "Cdef functions cannot take arbitrary decorators.") + else: + node.decorators = realdecs if options: optdict = {} @@ -419,6 +490,16 @@ return self.visit_with_options(body, optdict) else: return self.visit_Node(node) + + def visit_CVarDefNode(self, node): + if node.decorators: + for dec in node.decorators: + option = self.try_to_parse_option(dec.decorator) + if option is not None and option[0] == u'locals': + node.directive_locals = option[1] + else: + raise PostParseError(dec.pos, "Cdef functions can only take cython.locals() decorator.") + return node # Handle with statements def visit_WithStatNode(self, node): @@ -431,7 +512,7 @@ else: return self.visit_Node(node) -class WithTransform(CythonTransform): +class WithTransform(CythonTransform, SkipDeclarations): # EXCINFO is manually set to a variable that contains # the exc_info() tuple that can be generated by the enclosing except @@ -443,6 +524,7 @@ EXC = True try: try: + EXCINFO = None BODY except: EXC = False @@ -461,6 +543,7 @@ EXC = True try: try: + EXCINFO = None TARGET = VALUE BODY except: @@ -470,34 +553,48 @@ finally: if EXC: EXIT(None, None, None) + MGR = EXIT = VALUE = EXC = None + """, temps=[u'MGR', u'EXC', u"EXIT", u"VALUE"], pipeline=[NormalizeTree(None)]) def visit_WithStatNode(self, node): - excinfo_temp = TempHandle(PyrexTypes.py_object_type) + # TODO: Cleanup badly needed + TemplateTransform.temp_name_counter += 1 + handle = "__tmpvar_%d" % TemplateTransform.temp_name_counter + + self.visitchildren(node, ['body']) + excinfo_temp = NameNode(node.pos, name=handle)#TempHandle(Builtin.tuple_type) if node.target is not None: result = self.template_with_target.substitute({ u'EXPR' : node.manager, u'BODY' : node.body, u'TARGET' : node.target, - u'EXCINFO' : excinfo_temp.ref(node.pos) + u'EXCINFO' : excinfo_temp }, pos=node.pos) - # Set except excinfo target to EXCINFO - result.body.stats[4].body.stats[0].except_clauses[0].excinfo_target = ( - excinfo_temp.ref(node.pos)) else: result = self.template_without_target.substitute({ u'EXPR' : node.manager, u'BODY' : node.body, - u'EXCINFO' : excinfo_temp.ref(node.pos) + u'EXCINFO' : excinfo_temp }, pos=node.pos) - # Set except excinfo target to EXCINFO - result.body.stats[4].body.stats[0].except_clauses[0].excinfo_target = ( - excinfo_temp.ref(node.pos)) - return TempsBlockNode(node.pos, temps=[excinfo_temp], body=result) + # Set except excinfo target to EXCINFO + try_except = result.stats[-1].body.stats[-1] + try_except.except_clauses[0].excinfo_target = NameNode(node.pos, name=handle) +# excinfo_temp.ref(node.pos)) + +# result.stats[-1].body.stats[-1] = TempsBlockNode( +# node.pos, temps=[excinfo_temp], body=try_except) + + return result + + def visit_ExprNode(self, node): + # With statements are never inside expressions. + return node + -class DecoratorTransform(CythonTransform): +class DecoratorTransform(CythonTransform, SkipDeclarations): def visit_DefNode(self, func_node): if not func_node.decorators: @@ -517,6 +614,7 @@ rhs = decorator_result) return [func_node, reassignment] + class AnalyseDeclarationsTransform(CythonTransform): basic_property = TreeFragment(u""" @@ -527,16 +625,31 @@ ATTR = value """, level='c_class') + readonly_property = TreeFragment(u""" +property NAME: + def __get__(self): + return ATTR + """, level='c_class') + def __call__(self, root): self.env_stack = [root.scope] + # needed to determine if a cdef var is declared after it's used. + self.seen_vars_stack = [] return super(AnalyseDeclarationsTransform, self).__call__(root) + def visit_NameNode(self, node): + self.seen_vars_stack[-1].add(node.name) + return node + def visit_ModuleNode(self, node): + self.seen_vars_stack.append(set()) node.analyse_declarations(self.env_stack[-1]) self.visitchildren(node) + self.seen_vars_stack.pop() return node def visit_FuncDefNode(self, node): + self.seen_vars_stack.append(set()) lenv = node.create_local_scope(self.env_stack[-1]) node.body.analyse_control_flow(lenv) # this will be totally refactored node.declare_arguments(lenv) @@ -551,20 +664,50 @@ self.env_stack.append(lenv) self.visitchildren(node) self.env_stack.pop() + self.seen_vars_stack.pop() return node # Some nodes are no longer needed after declaration # analysis and can be dropped. The analysis was performed # on these nodes in a seperate recursive process from the # enclosing function or module, so we can simply drop them. + def visit_CDeclaratorNode(self, node): + # necessary to ensure that all CNameDeclaratorNodes are visited. + self.visitchildren(node) + return node + + def visit_CTypeDefNode(self, node): + return node + + def visit_CBaseTypeNode(self, node): + return None + + def visit_CEnumDefNode(self, node): + return None + + def visit_CStructOrUnionDefNode(self, node): + return None + + def visit_CNameDeclaratorNode(self, node): + if node.name in self.seen_vars_stack[-1]: + entry = self.env_stack[-1].lookup(node.name) + if entry is None or entry.visibility != 'extern': + warning(node.pos, "cdef variable '%s' declared after it is used" % node.name, 2) + self.visitchildren(node) + return node + def visit_CVarDefNode(self, node): + + # to ensure all CNameDeclaratorNodes are visited. + self.visitchildren(node) + if node.need_properties: # cdef public attributes may need type testing on # assignment, so we create a property accesss # mechanism for them. stats = [] for entry in node.need_properties: - property = self.create_Property(entry) + property = self.create_Property(entry, node.visibility == 'readonly') property.analyse_declarations(node.dest_scope) self.visit(property) stats.append(property) @@ -572,8 +715,12 @@ else: return None - def create_Property(self, entry): - property = self.basic_property.substitute({ + def create_Property(self, entry, readonly): + if readonly: + template = self.readonly_property + else: + template = self.basic_property + property = template.substitute({ u"ATTR": AttributeNode(pos=entry.pos, obj=NameNode(pos=entry.pos, name="self"), attribute=entry.name), @@ -601,6 +748,7 @@ def visit_ModuleNode(self, node): self.scope = node.scope + self.directives = node.directives self.visitchildren(node) return node @@ -613,8 +761,8 @@ error(node.pos, "'%s' redeclared" % node.name) error(pxd_def.pos, "previous declaration here") return None - self.visitchildren(node) - return node + else: + return node def visit_CClassDefNode(self, node, pxd_def=None): if pxd_def is None: @@ -630,12 +778,17 @@ def visit_DefNode(self, node): pxd_def = self.scope.lookup(node.name) if pxd_def: + if self.scope.is_c_class_scope and len(pxd_def.type.args) > 0: + # The self parameter type needs adjusting. + pxd_def.type.args[0].type = self.scope.parent_type if pxd_def.is_cfunction: node = node.as_cfunction(pxd_def) else: error(node.pos, "'%s' redeclared" % node.name) error(pxd_def.pos, "previous declaration here") return None + elif self.scope.is_module_scope and self.directives['auto_cpdef']: + node = node.as_cfunction(scope=self.scope) # Enable this when internal def functions are allowed. # self.visitchildren(node) return node @@ -767,6 +920,18 @@ error(node.function.pos, u"sizeof takes exactly one argument" % function) else: node = AmpersandNode(node.function.pos, operand=node.args[0]) + elif function == 'cmod': + if len(node.args) != 2: + error(node.function.pos, u"cmod takes exactly one argument" % function) + else: + node = binop_node(node.function.pos, '%', node.args[0], node.args[1]) + node.cdivision = True + elif function == 'cdiv': + if len(node.args) != 2: + error(node.function.pos, u"cmod takes exactly one argument" % function) + else: + node = binop_node(node.function.pos, '/', node.args[0], node.args[1]) + node.cdivision = True else: error(node.function.pos, u"'%s' not a valid cython language construct" % function) diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/Parsing.pxd /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/Parsing.pxd --- cython-0.10.3/Cython/Compiler/Parsing.pxd 1970-01-01 01:00:00.000000000 +0100 +++ cython-0.11.2/Cython/Compiler/Parsing.pxd 2009-05-20 16:37:46.000000000 +0100 @@ -0,0 +1,151 @@ +# We declare all of these here to type the first argument. + +from Cython.Compiler.Scanning cimport PyrexScanner + + +cpdef p_ident(PyrexScanner s, message =*) +cpdef p_ident_list(PyrexScanner s) + +cpdef p_binop_expr(PyrexScanner s, ops, p_sub_expr) +cpdef p_simple_expr(PyrexScanner s) +cpdef p_test(PyrexScanner s) +cpdef p_or_test(PyrexScanner s) +cpdef p_rassoc_binop_expr(PyrexScanner s, ops, p_subexpr) +cpdef p_and_test(PyrexScanner s) +cpdef p_not_test(PyrexScanner s) +cpdef p_comparison(PyrexScanner s) +cpdef p_cascaded_cmp(PyrexScanner s) +cpdef p_cmp_op(PyrexScanner s) +cpdef p_bit_expr(PyrexScanner s) +cpdef p_xor_expr(PyrexScanner s) +cpdef p_and_expr(PyrexScanner s) +cpdef p_shift_expr(PyrexScanner s) +cpdef p_arith_expr(PyrexScanner s) +cpdef p_term(PyrexScanner s) +cpdef p_factor(PyrexScanner s) +cpdef p_typecast(PyrexScanner s) +cpdef p_sizeof(PyrexScanner s) +cpdef p_yield_expression(PyrexScanner s) +cpdef p_power(PyrexScanner s) +cpdef p_trailer(PyrexScanner s, node1) +cpdef p_call(PyrexScanner s, function) +cpdef p_index(PyrexScanner s, base) +cpdef p_subscript_list(PyrexScanner s) +cpdef p_subscript(PyrexScanner s) +cpdef p_slice_element(PyrexScanner s, follow_set) +cpdef expect_ellipsis(PyrexScanner s) +cpdef make_slice_nodes(pos, subscripts) +cpdef make_slice_node(pos, start, stop = *, step = *) +cpdef p_atom(PyrexScanner s) +cpdef p_name(PyrexScanner s, name) +cpdef p_cat_string_literal(PyrexScanner s) +cpdef p_opt_string_literal(PyrexScanner s) +cpdef p_string_literal(PyrexScanner s) +cpdef p_list_maker(PyrexScanner s) +cpdef p_list_iter(PyrexScanner s, body) +cpdef p_list_for(PyrexScanner s, body) +cpdef p_list_if(PyrexScanner s, body) +cpdef p_dict_or_set_maker(PyrexScanner s) +cpdef p_backquote_expr(PyrexScanner s) +cpdef p_simple_expr_list(PyrexScanner s) +cpdef p_expr(PyrexScanner s) +cpdef p_testlist(PyrexScanner s) + +#------------------------------------------------------- +# +# Statements +# +#------------------------------------------------------- + +cpdef flatten_parallel_assignments(input, output) +cpdef find_parallel_assignment_size(input) + +cpdef p_global_statement(PyrexScanner s) +cpdef p_expression_or_assignment(PyrexScanner s) +cpdef p_print_statement(PyrexScanner s) +cpdef p_exec_statement(PyrexScanner s) +cpdef p_del_statement(PyrexScanner s) +cpdef p_pass_statement(PyrexScanner s, bint with_newline = *) +cpdef p_break_statement(PyrexScanner s) +cpdef p_continue_statement(PyrexScanner s) +cpdef p_return_statement(PyrexScanner s) +cpdef p_raise_statement(PyrexScanner s) +cpdef p_import_statement(PyrexScanner s) +cpdef p_from_import_statement(PyrexScanner s, bint first_statement = *) +cpdef p_imported_name(PyrexScanner s, bint is_cimport) +cpdef p_dotted_name(PyrexScanner s, bint as_allowed) +cpdef p_as_name(PyrexScanner s) +cpdef p_assert_statement(PyrexScanner s) +cpdef p_if_statement(PyrexScanner s) +cpdef p_if_clause(PyrexScanner s) +cpdef p_else_clause(PyrexScanner s) +cpdef p_while_statement(PyrexScanner s) +cpdef p_for_statement(PyrexScanner s) +cpdef p_for_bounds(PyrexScanner s) +cpdef p_for_from_relation(PyrexScanner s) +cpdef p_for_from_step(PyrexScanner s) +cpdef p_target(PyrexScanner s, terminator) +cpdef p_for_target(PyrexScanner s) +cpdef p_for_iterator(PyrexScanner s) +cpdef p_try_statement(PyrexScanner s) +cpdef p_except_clause(PyrexScanner s) +cpdef p_include_statement(PyrexScanner s, ctx) +cpdef p_with_statement(PyrexScanner s) +cpdef p_simple_statement(PyrexScanner s, bint first_statement = *) +cpdef p_simple_statement_list(PyrexScanner s, ctx, bint first_statement = *) +cpdef p_compile_time_expr(PyrexScanner s) +cpdef p_DEF_statement(PyrexScanner s) +cpdef p_IF_statement(PyrexScanner s, ctx) +cpdef p_statement(PyrexScanner s, ctx, bint first_statement = *) +cpdef p_statement_list(PyrexScanner s, ctx, bint first_statement = *) +cpdef p_suite(PyrexScanner s, ctx = *, bint with_doc = *, bint with_pseudo_doc = *) +cpdef p_positional_and_keyword_args(PyrexScanner s, end_sy_set, type_positions= *, type_keywords= * ) + +cpdef p_c_base_type(PyrexScanner s, bint self_flag = *, bint nonempty = *) +cpdef p_calling_convention(PyrexScanner s) +cpdef p_c_complex_base_type(PyrexScanner s) +cpdef p_c_simple_base_type(PyrexScanner s, self_flag, nonempty) +cpdef p_buffer_access(PyrexScanner s, base_type_node) +cpdef bint looking_at_name(PyrexScanner s) except -2 +cpdef bint looking_at_expr(PyrexScanner s) except -2 +cpdef bint looking_at_base_type(PyrexScanner s) except -2 +cpdef bint looking_at_dotted_name(PyrexScanner s) except -2 +cpdef p_sign_and_longness(PyrexScanner s) +cpdef p_opt_cname(PyrexScanner s) +cpdef p_c_declarator(PyrexScanner s, ctx = *, bint empty = *, bint is_type = *, bint cmethod_flag = *, + bint assignable = *, bint nonempty = *, + bint calling_convention_allowed = *) +cpdef p_c_array_declarator(PyrexScanner s, base) +cpdef p_c_func_declarator(PyrexScanner s, pos, ctx, base, bint cmethod_flag) +cpdef p_c_simple_declarator(PyrexScanner s, ctx, bint empty, bint is_type, bint cmethod_flag, + bint assignable, bint nonempty) +cpdef p_nogil(PyrexScanner s) +cpdef p_with_gil(PyrexScanner s) +cpdef p_exception_value_clause(PyrexScanner s) +cpdef p_c_arg_list(PyrexScanner s, ctx = *, bint in_pyfunc = *, bint cmethod_flag = *, + bint nonempty_declarators = *, bint kw_only = *) +cpdef p_optional_ellipsis(PyrexScanner s) +cpdef p_c_arg_decl(PyrexScanner s, ctx, in_pyfunc, bint cmethod_flag = *, bint nonempty = *, bint kw_only = *) +cpdef p_api(PyrexScanner s) +cpdef p_cdef_statement(PyrexScanner s, ctx) +cpdef p_cdef_block(PyrexScanner s, ctx) +cpdef p_cdef_extern_block(PyrexScanner s, pos, ctx) +cpdef p_c_enum_definition(PyrexScanner s, pos, ctx) +cpdef p_c_enum_line(PyrexScanner s, items) +cpdef p_c_enum_item(PyrexScanner s, items) +cpdef p_c_struct_or_union_definition(PyrexScanner s, pos, ctx) +cpdef p_visibility(PyrexScanner s, prev_visibility) +cpdef p_c_modifiers(PyrexScanner s) +cpdef p_c_func_or_var_declaration(PyrexScanner s, pos, ctx) +cpdef p_ctypedef_statement(PyrexScanner s, ctx) +cpdef p_decorators(PyrexScanner s) +cpdef p_def_statement(PyrexScanner s, decorators = *) +cpdef p_py_arg_decl(PyrexScanner s) +cpdef p_class_statement(PyrexScanner s) +cpdef p_c_class_definition(PyrexScanner s, pos, ctx) +cpdef p_c_class_options(PyrexScanner s) +cpdef p_property_decl(PyrexScanner s) +cpdef p_doc_string(PyrexScanner s) +cpdef p_code(PyrexScanner s, level= *) +cpdef p_compiler_directive_comments(PyrexScanner s) +cpdef p_module(PyrexScanner s, pxd, full_module_name) diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/Parsing.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/Parsing.py --- cython-0.10.3/Cython/Compiler/Parsing.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/Parsing.py 2009-05-20 16:37:46.000000000 +0100 @@ -1,12 +1,17 @@ +# cython: auto_cpdef=True # # Pyrex Parser # +# This should be done automatically +import cython +cython.declare(Nodes=object, ExprNodes=object, EncodedString=object) + import os import re import sys from types import ListType, TupleType -from Scanning import PyrexScanner, FileSourceDescriptor +from Cython.Compiler.Scanning import PyrexScanner, FileSourceDescriptor import Nodes import ExprNodes import StringEncoding @@ -79,12 +84,9 @@ if s.sy == 'if': s.next() test = p_or_test(s) - if s.sy == 'else': - s.next() - other = p_test(s) - return ExprNodes.CondExprNode(pos, test=test, true_val=expr, false_val=other) - else: - s.error("Expected 'else'") + s.expect('else') + other = p_test(s) + return ExprNodes.CondExprNode(pos, test=test, true_val=expr, false_val=other) else: return expr @@ -264,6 +266,15 @@ s.expect(')') return node +def p_yield_expression(s): + # s.sy == "yield" + pos = s.position() + s.next() + if s.sy not in ('EOF', 'NEWLINE', ')'): + expr = p_expr(s) + s.error("generators ('yield') are not currently supported") + return Nodes.PassStatNode(pos) + #power: atom trailer* ('**' factor)* def p_power(s): @@ -459,7 +470,7 @@ return ExprNodes.SliceNode(pos, start = start, stop = stop, step = step) -#atom: '(' [testlist] ')' | '[' [listmaker] ']' | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING+ +#atom: '(' [testlist] ')' | '[' [listmaker] ']' | '{' [dict_or_set_maker] '}' | '`' testlist '`' | NAME | NUMBER | STRING+ def p_atom(s): pos = s.position() @@ -468,6 +479,8 @@ s.next() if s.sy == ')': result = ExprNodes.TupleNode(pos, args = []) + elif s.sy == 'yield': + result = p_yield_expression(s) else: result = p_expr(s) s.expect(')') @@ -475,7 +488,7 @@ elif sy == '[': return p_list_maker(s) elif sy == '{': - return p_dict_maker(s) + return p_dict_or_set_maker(s) elif sy == '`': return p_backquote_expr(s) elif sy == 'INT': @@ -527,26 +540,22 @@ def p_name(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, bool): - return ExprNodes.BoolNode(pos, value = value) - elif isinstance(value, int): - return ExprNodes.IntNode(pos, value = rep) - elif isinstance(value, long): - return ExprNodes.IntNode(pos, value = rep, longness = "L") - elif isinstance(value, float): - return ExprNodes.FloatNode(pos, value = rep) - elif isinstance(value, (str, unicode)): - return ExprNodes.StringNode(pos, value = value) - else: - error(pos, "Invalid type for compile-time constant: %s" - % value.__class__.__name__) + if not s.compile_time_expr and name in s.compile_time_env: + value = s.compile_time_env.lookup_here(name) + rep = repr(value) + if isinstance(value, bool): + return ExprNodes.BoolNode(pos, value = value) + elif isinstance(value, int): + return ExprNodes.IntNode(pos, value = rep) + elif isinstance(value, long): + return ExprNodes.IntNode(pos, value = rep, longness = "L") + elif isinstance(value, float): + return ExprNodes.FloatNode(pos, value = rep) + elif isinstance(value, (str, unicode)): + return ExprNodes.StringNode(pos, value = value) + 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): @@ -672,11 +681,11 @@ #print "p_string_literal: value =", repr(value) ### return kind, value -# list_display ::= "[" [listmaker] "]" -# listmaker ::= expression ( list_for | ( "," expression )* [","] ) -# list_iter ::= list_for | list_if -# list_for ::= "for" expression_list "in" testlist [list_iter] -# list_if ::= "if" test [list_iter] +# list_display ::= "[" [listmaker] "]" +# listmaker ::= expression ( list_for | ( "," expression )* [","] ) +# list_iter ::= list_for | list_if +# list_for ::= "for" expression_list "in" testlist [list_iter] +# list_if ::= "if" test [list_iter] def p_list_maker(s): # s.sy == '[' @@ -687,16 +696,13 @@ return ExprNodes.ListNode(pos, args = []) expr = p_simple_expr(s) if s.sy == 'for': - loop = p_list_for(s) + target = ExprNodes.ListNode(pos, args = []) + append = ExprNodes.ComprehensionAppendNode( + pos, expr=expr, target=ExprNodes.CloneNode(target)) + loop = p_list_for(s, Nodes.ExprStatNode(append.pos, expr=append)) s.expect(']') - inner_loop = loop - while not isinstance(inner_loop.body, Nodes.PassStatNode): - inner_loop = inner_loop.body - if isinstance(inner_loop, Nodes.IfStatNode): - inner_loop = inner_loop.if_clauses[0] - append = ExprNodes.ListComprehensionAppendNode( pos, expr = expr ) - inner_loop.body = Nodes.ExprStatNode(pos, expr = append) - return ExprNodes.ListComprehensionNode(pos, loop = loop, append = append) + return ExprNodes.ComprehensionNode( + pos, loop=loop, append=append, target=target) else: exprs = [expr] if s.sy == ',': @@ -705,52 +711,96 @@ s.expect(']') return ExprNodes.ListNode(pos, args = exprs) -def p_list_iter(s): +def p_list_iter(s, body): if s.sy == 'for': - return p_list_for(s) + return p_list_for(s, body) elif s.sy == 'if': - return p_list_if(s) + return p_list_if(s, body) else: - return Nodes.PassStatNode(s.position()) + # insert the 'append' operation into the loop + return body -def p_list_for(s): +def p_list_for(s, body): # s.sy == 'for' pos = s.position() s.next() kw = p_for_bounds(s) kw['else_clause'] = None - kw['body'] = p_list_iter(s) + kw['body'] = p_list_iter(s, body) return Nodes.ForStatNode(pos, **kw) -def p_list_if(s): +def p_list_if(s, body): # s.sy == 'if' pos = s.position() s.next() test = p_test(s) return Nodes.IfStatNode(pos, - if_clauses = [Nodes.IfClauseNode(pos, condition = test, body = p_list_iter(s))], + if_clauses = [Nodes.IfClauseNode(pos, condition = test, + body = p_list_iter(s, body))], else_clause = None ) - + #dictmaker: test ':' test (',' test ':' test)* [','] -def p_dict_maker(s): +def p_dict_or_set_maker(s): # s.sy == '{' pos = s.position() s.next() - items = [] - while s.sy != '}': - items.append(p_dict_item(s)) - if s.sy != ',': - break + if s.sy == '}': s.next() - s.expect('}') - return ExprNodes.DictNode(pos, key_value_pairs = items) - -def p_dict_item(s): - key = p_simple_expr(s) - s.expect(':') - value = p_simple_expr(s) - return ExprNodes.DictItemNode(key.pos, key=key, value=value) + return ExprNodes.DictNode(pos, key_value_pairs = []) + item = p_simple_expr(s) + if s.sy == ',' or s.sy == '}': + # set literal + values = [item] + while s.sy == ',': + s.next() + if s.sy == '}': + break + values.append( p_simple_expr(s) ) + s.expect('}') + return ExprNodes.SetNode(pos, args=values) + elif s.sy == 'for': + # set comprehension + target = ExprNodes.SetNode(pos, args=[]) + append = ExprNodes.ComprehensionAppendNode( + item.pos, expr=item, target=ExprNodes.CloneNode(target)) + loop = p_list_for(s, Nodes.ExprStatNode(append.pos, expr=append)) + s.expect('}') + return ExprNodes.ComprehensionNode( + pos, loop=loop, append=append, target=target) + elif s.sy == ':': + # dict literal or comprehension + key = item + s.next() + value = p_simple_expr(s) + if s.sy == 'for': + # dict comprehension + target = ExprNodes.DictNode(pos, key_value_pairs = []) + append = ExprNodes.DictComprehensionAppendNode( + item.pos, key_expr=key, value_expr=value, + target=ExprNodes.CloneNode(target)) + loop = p_list_for(s, Nodes.ExprStatNode(append.pos, expr=append)) + s.expect('}') + return ExprNodes.ComprehensionNode( + pos, loop=loop, append=append, target=target) + else: + # dict literal + items = [ExprNodes.DictItemNode(key.pos, key=key, value=value)] + while s.sy == ',': + s.next() + if s.sy == '}': + break + key = p_simple_expr(s) + s.expect(':') + value = p_simple_expr(s) + items.append( + ExprNodes.DictItemNode(key.pos, key=key, value=value)) + s.expect('}') + return ExprNodes.DictNode(pos, key_value_pairs=items) + else: + # raise an error + s.expect('}') + return ExprNodes.DictNode(pos, key_value_pairs = []) def p_backquote_expr(s): # s.sy == '`' @@ -902,6 +952,21 @@ return Nodes.PrintStatNode(pos, arg_tuple = arg_tuple, append_newline = not ends_with_comma) +def p_exec_statement(s): + # s.sy == 'exec' + pos = s.position() + s.next() + args = [ p_bit_expr(s) ] + if s.sy == 'in': + s.next() + args.append(p_simple_expr(s)) + if s.sy == ',': + s.next() + args.append(p_simple_expr(s)) + else: + error(pos, "'exec' currently requires a target mapping (globals/locals)") + return Nodes.ExecStatNode(pos, args = args) + def p_del_statement(s): # s.sy == 'del' pos = s.position() @@ -980,7 +1045,8 @@ else: if as_name and "." in dotted_name: name_list = ExprNodes.ListNode(pos, args = [ - ExprNodes.StringNode(pos, value = EncodedString("*"))]) + ExprNodes.IdentifierStringNode( + pos, value = EncodedString("*"))]) else: name_list = None stat = Nodes.SingleAssignmentNode(pos, @@ -1005,14 +1071,20 @@ else: s.error("Expected 'import' or 'cimport'") is_cimport = kind == 'cimport' + is_parenthesized = False if s.sy == '*': imported_names = [(s.position(), "*", None, None)] s.next() else: + if s.sy == '(': + is_parenthesized = True + s.next() imported_names = [p_imported_name(s, is_cimport)] while s.sy == ',': s.next() imported_names.append(p_imported_name(s, is_cimport)) + if is_parenthesized: + s.expect(')') dotted_name = EncodedString(dotted_name) if dotted_name == '__future__': if not first_statement: @@ -1291,7 +1363,7 @@ 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 in ('gil', 'nogil'): if s.sy == 'IDENT' and s.systring == 'nogil': state = s.systring s.next() @@ -1307,8 +1379,8 @@ if not allow_multi and isinstance(target, ExprNodes.TupleNode): s.error("Multiple with statement target values not allowed without paranthesis") body = p_suite(s) - return Nodes.WithStatNode(pos, manager = manager, - target = target, body = body) + return Nodes.WithStatNode(pos, manager = manager, + target = target, body = body) def p_simple_statement(s, first_statement = 0): #print "p_simple_statement:", s.sy, s.systring ### @@ -1316,6 +1388,8 @@ node = p_global_statement(s) elif s.sy == 'print': node = p_print_statement(s) + elif s.sy == 'exec': + node = p_exec_statement(s) elif s.sy == 'del': node = p_del_statement(s) elif s.sy == 'break': @@ -1330,6 +1404,8 @@ node = p_import_statement(s) elif s.sy == 'from': node = p_from_import_statement(s, first_statement = first_statement) + elif s.sy == 'yield': + node = p_yield_expression(s) elif s.sy == 'assert': node = p_assert_statement(s) elif s.sy == 'pass': @@ -1403,6 +1479,7 @@ def p_statement(s, ctx, first_statement = 0): cdef_flag = ctx.cdef_flag + decorators = None if s.sy == 'ctypedef': if ctx.level not in ('module', 'module_pxd'): s.error("ctypedef statement not allowed here") @@ -1414,63 +1491,71 @@ elif s.sy == 'IF': return p_IF_statement(s, ctx) elif s.sy == 'DECORATOR': - if ctx.level not in ('module', 'class', 'c_class', 'property'): + if ctx.level not in ('module', 'class', 'c_class', 'property', 'module_pxd', 'c_class_pxd'): + print ctx.level s.error('decorator not allowed here') s.level = ctx.level decorators = p_decorators(s) - if s.sy != 'def': + if s.sy not in ('def', 'cdef', 'cpdef'): s.error("Decorators can only be followed by functions ") - return p_def_statement(s, decorators) + elif s.sy == 'pass' and cdef_flag: + # empty cdef block + return p_pass_statement(s, with_newline = 1) + + overridable = 0 + if s.sy == 'cdef': + cdef_flag = 1 + s.next() + elif s.sy == 'cpdef': + cdef_flag = 1 + overridable = 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') + s.level = ctx.level + node = p_cdef_statement(s, ctx(overridable = overridable)) + if decorators is not None: + if not isinstance(node, (Nodes.CFuncDefNode, Nodes.CVarDefNode)): + s.error("Decorators can only be followed by functions ") + node.decorators = decorators + return node else: - overridable = 0 - if s.sy == 'cdef': - cdef_flag = 1 - s.next() - if s.sy == 'cpdef': - cdef_flag = 1 - overridable = 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') + if ctx.api: + error(s.pos, "'api' not allowed with this statement") + elif s.sy == 'def': + if ctx.level not in ('module', 'class', 'c_class', 'c_class_pxd', 'property'): + s.error('def statement not allowed here') s.level = ctx.level - return p_cdef_statement(s, ctx(overridable = overridable)) - else: - if ctx.api: - error(s.pos, "'api' not allowed with this statement") - elif s.sy == 'def': - if ctx.level not in ('module', 'class', 'c_class', 'c_class_pxd', 'property'): - s.error('def statement not allowed here') - s.level = ctx.level - 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) + return p_def_statement(s, decorators) + 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_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: - if ctx.level in ('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, first_statement = first_statement) + return p_simple_statement_list( + s, ctx, first_statement = first_statement) def p_statement_list(s, ctx, first_statement = 0): # Parse a series of statements separated by newlines. @@ -1590,7 +1675,7 @@ else: return "" -calling_convention_words = ("__stdcall", "__cdecl") +calling_convention_words = ("__stdcall", "__cdecl", "__fastcall") def p_c_complex_base_type(s): # s.sy == '(' @@ -1607,17 +1692,28 @@ is_basic = 0 signed = 1 longness = 0 + complex = 0 module_path = [] pos = s.position() + if not s.sy == 'IDENT': + error(pos, "Expected an identifier, found '%s'" % s.sy) 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: + if s.sy == 'IDENT' and s.systring in special_basic_c_types: + signed, longness = special_basic_c_types[s.systring] name = s.systring s.next() else: - name = 'int' + 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' + if s.sy == 'IDENT' and s.systring == 'complex': + complex = 1 + s.next() elif looking_at_dotted_name(s): #print "p_c_simple_base_type: looking_at_type_name at", s.position() name = s.systring @@ -1646,7 +1742,8 @@ type_node = Nodes.CSimpleBaseTypeNode(pos, name = name, module_path = module_path, is_basic_c_type = is_basic, signed = signed, - longness = longness, is_self_arg = self_flag) + complex = complex, longness = longness, + is_self_arg = self_flag) # Treat trailing [] on type as buffer access if it appears in a context @@ -1734,13 +1831,19 @@ return result else: return 0 - -basic_c_type_names = ("void", "char", "int", "float", "double", "Py_ssize_t", "bint") + +basic_c_type_names = ("void", "char", "int", "float", "double", "bint") + +special_basic_c_types = { + # name : (signed, longness) + "Py_ssize_t" : (2, 0), + "size_t" : (0, 0), +} sign_and_longness_words = ("short", "long", "signed", "unsigned") base_type_start_words = \ - basic_c_type_names + sign_and_longness_words + basic_c_type_names + sign_and_longness_words + tuple(special_basic_c_types) def p_sign_and_longness(s): signed = 1 @@ -1975,31 +2078,30 @@ elif s.sy == 'import': s.next() return p_cdef_extern_block(s, pos, ctx) - if p_nogil(s): + elif p_nogil(s): ctx.nogil = 1 - if s.sy == ':': + if ctx.overridable: + error(pos, "cdef blocks cannot be declared cpdef") + return p_cdef_block(s, ctx) + elif s.sy == ':': + if ctx.overridable: + error(pos, "cdef blocks cannot be declared cpdef") 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 ctx.api: - # error(pos, "'api' not allowed with extension class") + if ctx.overridable: + error(pos, "Extension types cannot be declared cpdef") return p_c_class_definition(s, pos, ctx) - elif s.sy == 'IDENT' and s.systring in struct_union_or_enum: + elif s.sy == 'IDENT' and s.systring in ("struct", "union", "enum", "packed"): 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 ctx.overridable: + error(pos, "C struct/union/enum cannot be declared cpdef") 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) @@ -2007,6 +2109,8 @@ return p_suite(s, ctx(cdef_flag = 1)) def p_cdef_extern_block(s, pos, ctx): + if ctx.overridable: + error(pos, "cdef extern blocks cannot be declared cpdef") include_file = None s.expect('from') if s.sy == '*': @@ -2021,10 +2125,6 @@ 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() @@ -2075,6 +2175,12 @@ name = name, cname = cname, value = value)) def p_c_struct_or_union_definition(s, pos, ctx): + packed = False + if s.systring == 'packed': + packed = True + s.next() + if s.sy != 'IDENT' or s.systring != 'struct': + s.expected('struct') # s.sy == ident 'struct' or 'union' kind = s.systring s.next() @@ -2100,7 +2206,7 @@ return Nodes.CStructOrUnionDefNode(pos, name = name, cname = cname, kind = kind, attributes = attributes, typedef_flag = ctx.typedef_flag, visibility = ctx.visibility, - in_pxd = ctx.level == 'module_pxd') + in_pxd = ctx.level == 'module_pxd', packed = packed) def p_visibility(s, prev_visibility): pos = s.position() @@ -2128,7 +2234,7 @@ assignable = 1, nonempty = 1) declarator.overridable = ctx.overridable if s.sy == ':': - if ctx.level not in ('module', 'c_class'): + if ctx.level not in ('module', 'c_class', 'module_pxd', 'c_class_pxd'): s.error("C function definition not allowed here") doc, suite = p_suite(s, Ctx(level = 'function'), with_doc = 1) result = Nodes.CFuncDefNode(pos, @@ -2172,7 +2278,7 @@ 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'): + elif s.sy == 'IDENT' and s.systring in ('packed', 'struct', 'union', 'enum'): if s.systring == 'enum': return p_c_enum_definition(s, pos, ctx) else: @@ -2382,7 +2488,7 @@ repr(s.sy), repr(s.systring))) return body -COMPILER_DIRECTIVE_COMMENT_RE = re.compile(r"^#\s*cython:\s*([a-z]+)\s*=(.*)$") +COMPILER_DIRECTIVE_COMMENT_RE = re.compile(r"^#\s*cython:\s*(\w+)\s*=(.*)$") def p_compiler_directive_comments(s): result = {} @@ -2392,10 +2498,10 @@ name = m.group(1) try: value = Options.parse_option_value(str(name), str(m.group(2).strip())) + if value is not None: # can be False! + result[name] = value except ValueError, e: s.error(e.args[0], fatal=False) - if value is not None: # can be False! - result[name] = value s.next() return result diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/PyrexTypes.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/PyrexTypes.py --- cython-0.10.3/Cython/Compiler/PyrexTypes.py 2008-12-17 08:56:17.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/PyrexTypes.py 2009-05-20 16:37:46.000000000 +0100 @@ -7,20 +7,22 @@ import Naming import copy -class BaseType: +class BaseType(object): # # Base class for all Pyrex types including pseudo-types. def cast_code(self, expr_code): return "((%s)%s)" % (self.declaration_code(""), expr_code) + def specalization_name(self): + return self.declaration_code("").replace(" ", "__") + 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 Pyrex types. @@ -31,6 +33,7 @@ # is_int boolean Is a C integer type # is_longlong boolean Is a long long or unsigned long long. # is_float boolean Is a C floating point type + # is_complex boolean Is a C complex 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 @@ -47,7 +50,6 @@ # is_buffer boolean Is buffer access 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, @@ -82,6 +84,7 @@ is_int = 0 is_longlong = 0 is_float = 0 + is_complex = 0 is_void = 0 is_array = 0 is_ptr = 0 @@ -98,7 +101,6 @@ is_buffer = 0 has_attributes = 0 default_value = "" - parsetuple_format = "" pymemberdef_typecode = None def resolve(self): @@ -140,9 +142,15 @@ return 1 def is_simple_buffer_dtype(self): - return (self.is_int or self.is_float or self.is_pyobject or + return (self.is_int or self.is_float or self.is_complex or self.is_pyobject or self.is_extension_type or self.is_ptr) + def struct_nesting_depth(self): + # Returns the number levels of nested structs. This is + # used for constructing a stack for walking the run-time + # type information of the struct. + return 1 + class CTypedefType(BaseType): # # Pseudo-type defined with a ctypedef statement in a @@ -153,12 +161,15 @@ # qualified_name string # typedef_cname string # typedef_base_type PyrexType + # typedef_is_external bool is_typedef = 1 + typedef_is_external = 0 - def __init__(self, cname, base_type): + def __init__(self, cname, base_type, is_external=0): self.typedef_cname = cname self.typedef_base_type = base_type + self.typedef_is_external = is_external def resolve(self): return self.typedef_base_type.resolve() @@ -228,6 +239,11 @@ def __repr__(self): return "" % self.base +def public_decl(base, dll_linkage): + if dll_linkage: + return "%s(%s)" % (dll_linkage, base) + else: + return base class PyObjectType(PyrexType): # @@ -237,7 +253,6 @@ is_pyobject = 1 default_value = "0" - parsetuple_format = "O" pymemberdef_typecode = "T_OBJECT" buffer_defaults = None @@ -257,6 +272,11 @@ else: return "%s *%s" % (public_decl("PyObject", dll_linkage), entity_code) + def as_pyobject(self, cname): + if (not self.is_complete()) or self.is_extension_type: + return "(PyObject *)" + cname + else: + return cname class BuiltinObjectType(PyObjectType): @@ -265,8 +285,14 @@ base_type = None module_name = '__builtin__' + alternative_name = None # used for str/bytes duality + def __init__(self, name, cname): self.name = name + if name == 'str': + self.alternative_name = 'bytes' + elif name == 'bytes': + self.alternative_name = 'str' self.cname = cname self.typeptr_cname = "&" + cname @@ -283,7 +309,9 @@ def assignable_from(self, src_type): if isinstance(src_type, BuiltinObjectType): - return src_type.name == self.name + return src_type.name == self.name or ( + src_type.name == self.alternative_name and + src_type.name is not None) else: return not src_type.is_extension_type @@ -299,14 +327,16 @@ def type_test_code(self, arg): type_name = self.name if type_name == 'str': - type_name = 'String' + check = 'PyString_CheckExact' elif type_name == 'set': - type_name = 'AnySet' + check = 'PyAnySet_CheckExact' elif type_name == 'frozenset': - type_name = 'FrozenSet' + check = 'PyFrozenSet_CheckExact' + elif type_name == 'bool': + check = 'PyBool_Check' else: - type_name = type_name.capitalize() - return 'likely(Py%s_CheckExact(%s)) || (%s) == Py_None || (PyErr_Format(PyExc_TypeError, "Expected %s, got %%s", Py_TYPE(%s)->tp_name), 0)' % (type_name, arg, arg, self.name, arg) + check = 'Py%s_CheckExact' % type_name.capitalize() + return 'likely(%s(%s)) || (%s) == Py_None || (PyErr_Format(PyExc_TypeError, "Expected %s, got %%s", Py_TYPE(%s)->tp_name), 0)' % (check, arg, arg, self.name, arg) def declaration_code(self, entity_code, for_display = 0, dll_linkage = None, pyrex = 0): @@ -414,8 +444,11 @@ exception_value = None exception_check = 1 - def create_convert_utility_code(self, env): - return True + def create_to_py_utility_code(self, env): + return self.to_py_function is not None + + def create_from_py_utility_code(self, env): + return self.from_py_function is not None def error_condition(self, result_code): conds = [] @@ -457,21 +490,11 @@ is_numeric = 1 default_value = "0" - parsetuple_formats = ( # rank -> format - "BHIkK????", # unsigned - "bhilL?fd?", # assumed signed - "bhilL?fd?", # explicitly signed - ) - sign_words = ("unsigned ", "", "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 sign_and_name(self): @@ -490,57 +513,123 @@ return self.base_declaration_code(base, entity_code) -int_conversion_list = {} -type_conversion_functions = "" type_conversion_predeclarations = "" +type_conversion_functions = "" + +c_int_from_py_function = UtilityCode( +proto=""" +static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject *); +""", +impl=""" +static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) { + if (sizeof(%(type)s) < sizeof(long)) { + long val = __Pyx_PyInt_AsLong(x); + if (unlikely(val != (long)(%(type)s)val)) { + if (unlikely(val == -1 && PyErr_Occurred())) + return (%(type)s)-1;""" + \ + "%(IntValSignTest)s" + \ +""" + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to %(type)s"); + return (%(type)s)-1; + } + return (%(type)s)val; + } + return (%(type)s)__Pyx_PyInt_As%(SignWord)sLong(x); +} +""") +intval_signtest = """ + if (unlikely(%(var)s < 0)) { + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to %(type)s"); + return (%(type)s)-1; + }""" + +c_long_from_py_function = UtilityCode( +proto=""" +static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject *); +""", +impl=""" +static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) { +#if PY_VERSION_HEX < 0x03000000 + if (likely(PyInt_CheckExact(x) || PyInt_Check(x))) { + long val = PyInt_AS_LONG(x);""" + \ + "%(IntValSignTest)s" + \ +""" + return (%(type)s)val; + } else +#endif + if (likely(PyLong_CheckExact(x) || PyLong_Check(x))) {""" +\ + "%(PyLongSignTest)s" + \ +""" + return %(PyLongConvert)s(x); + } else { + %(type)s val; + PyObject *tmp = __Pyx_PyNumber_Int(x); + if (!tmp) return (%(type)s)-1; + val = __Pyx_PyInt_As%(SignWord)s%(TypeName)s(tmp); + Py_DECREF(tmp); + return val; + } +} +""") +pylong_signtest = """ + if (unlikely(Py_SIZE(%(var)s) < 0)) { + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to %(type)s"); + return (%(type)s)-1; + }""" + + class CIntType(CNumericType): - + is_int = 1 typedef_flag = 0 to_py_function = "PyInt_FromLong" - from_py_function = "__pyx_PyInt_AsLong" + from_py_function = "__Pyx_PyInt_AsInt" exception_value = -1 def __init__(self, rank, signed, pymemberdef_typecode = None, is_returncode = 0): CNumericType.__init__(self, rank, signed, pymemberdef_typecode) self.is_returncode = is_returncode - if self.from_py_function == '__pyx_PyInt_AsLong': + if self.from_py_function == "__Pyx_PyInt_AsInt": self.from_py_function = self.get_type_conversion() def get_type_conversion(self): - # error on overflow - c_type = self.sign_and_name() - c_name = c_type.replace(' ', '_'); - func_name = "__pyx_PyInt_%s" % c_name; - if not int_conversion_list.has_key(func_name): - # no env to add utility code to - global type_conversion_predeclarations, type_conversion_functions - if self.signed: - neg_test = "" - else: - neg_test = " || (long_val < 0)" - type_conversion_predeclarations += """ -static INLINE %(c_type)s %(func_name)s(PyObject* x);""" % {'c_type': c_type, 'c_name': c_name, 'func_name': func_name } - type_conversion_functions += """ -static INLINE %(c_type)s %(func_name)s(PyObject* x) { - if (sizeof(%(c_type)s) < sizeof(long)) { - long long_val = __pyx_PyInt_AsLong(x); - %(c_type)s val = (%(c_type)s)long_val; - if (unlikely((val != long_val) %(neg_test)s)) { - PyErr_SetString(PyExc_OverflowError, "value too large to convert to %(c_type)s"); - return (%(c_type)s)-1; - } - return val; - } - else { - return __pyx_PyInt_AsLong(x); - } -} -""" % {'c_type': c_type, 'c_name': c_name, 'func_name': func_name, 'neg_test': neg_test } - int_conversion_list[func_name] = True + ctype = self.declaration_code('') + bits = ctype.split(" ", 1) + if len(bits) == 1: + sign_word, type_name = "", bits[0] + else: + sign_word, type_name = bits + type_name = type_name.replace("PY_LONG_LONG","long long") + SignWord = sign_word.title() + TypeName = type_name.title().replace(" ", "") + data = {'IntValSignTest' : "", + 'PyLongSignTest' : "", + 'PyLongConvert' : "", + } + if not self.signed: + data['IntValSignTest'] = intval_signtest % {'var':"val", 'type':ctype} + data['PyLongSignTest'] = pylong_signtest % {'var':"x", 'type':ctype} + if "Long" in TypeName: + data['PyLongConvert'] = \ + "PyLong_As" + SignWord.replace("Signed", "") + TypeName + # the replaces below are just for generating well indented C code + data['IntValSignTest'] = "\n".join( + [ln.replace(" "*4, "", 1) for ln in data['IntValSignTest'].split('\n')] + ) + utility_code = c_long_from_py_function + else: + utility_code = c_int_from_py_function + utility_code.specialize(self, + SignWord=SignWord, + TypeName=TypeName, + **data) + func_name = "__Pyx_PyInt_As%s%s" % (SignWord, TypeName) return func_name - + def assignable_from_resolved_type(self, src_type): return src_type.is_int or src_type.is_enum or src_type is error_type @@ -554,40 +643,56 @@ class CAnonEnumType(CIntType): - is_enum = 1 + is_enum = 1 + + def sign_and_name(self): + return 'int' class CUIntType(CIntType): to_py_function = "PyLong_FromUnsignedLong" - from_py_function = "PyInt_AsUnsignedLongMask" exception_value = -1 +class CLongType(CIntType): + + to_py_function = "PyInt_FromLong" + + class CULongType(CUIntType): to_py_function = "PyLong_FromUnsignedLong" - from_py_function = "PyInt_AsUnsignedLongMask" class CLongLongType(CIntType): is_longlong = 1 to_py_function = "PyLong_FromLongLong" - from_py_function = "__pyx_PyInt_AsLongLong" class CULongLongType(CUIntType): is_longlong = 1 to_py_function = "PyLong_FromUnsignedLongLong" - from_py_function = "__pyx_PyInt_AsUnsignedLongLong" class CPySSizeTType(CIntType): to_py_function = "PyInt_FromSsize_t" - from_py_function = "__pyx_PyIndex_AsSsize_t" + from_py_function = "__Pyx_PyIndex_AsSsize_t" + + def sign_and_name(self): + return rank_to_type_name[self.rank] + + +class CSizeTType(CUIntType): + + to_py_function = "__Pyx_PyInt_FromSize_t" + from_py_function = "__Pyx_PyInt_AsSize_t" + + def sign_and_name(self): + return rank_to_type_name[self.rank] class CFloatType(CNumericType): @@ -596,11 +701,200 @@ to_py_function = "PyFloat_FromDouble" from_py_function = "__pyx_PyFloat_AsDouble" - def __init__(self, rank, pymemberdef_typecode = None): + def __init__(self, rank, pymemberdef_typecode = None, math_h_modifier = ''): CNumericType.__init__(self, rank, 1, pymemberdef_typecode) + self.math_h_modifier = math_h_modifier + + def assignable_from_resolved_type(self, src_type): + return (src_type.is_numeric and not src_type.is_complex) or src_type is error_type + + +class CComplexType(CNumericType): + + is_complex = 1 + to_py_function = "__pyx_PyObject_from_complex" + has_attributes = 1 + scope = None + + def __init__(self, real_type): + self.real_type = real_type + CNumericType.__init__(self, real_type.rank + 0.5, real_type.signed) + self.binops = {} + self.from_parts = "%s_from_parts" % self.specalization_name() + + def __cmp__(self, other): + if isinstance(self, CComplexType) and isinstance(other, CComplexType): + return cmp(self.real_type, other.real_type) + else: + return 1 + def __hash__(self): + return ~hash(self.real_type) + + def sign_and_name(self): + return Naming.type_prefix + self.real_type.specalization_name() + "_complex" + def assignable_from_resolved_type(self, src_type): - return src_type.is_numeric or src_type is error_type + return (src_type.is_complex and self.real_type.assignable_from_resolved_type(src_type.real_type) + or src_type.is_numeric and self.real_type.assignable_from_resolved_type(src_type) + or src_type is error_type) + + def attributes_known(self): + if self.scope is None: + import Symtab + self.scope = Symtab.StructOrUnionScope(self.specalization_name()) + self.scope.declare_var("real", self.real_type, None, "real") + self.scope.declare_var("imag", self.real_type, None, "imag") + return True + + def create_declaration_utility_code(self, env): + # This must always be run, because a single CComplexType instance can be shared + # across multiple compilations (the one created in the module scope) + env.use_utility_code(complex_generic_utility_code) + env.use_utility_code( + complex_arithmatic_utility_code.specialize(self, + math_h_modifier = self.real_type.math_h_modifier, + real_type = self.real_type.declaration_code(''))) + return True + + def create_from_py_utility_code(self, env): + self.real_type.create_from_py_utility_code(env) + env.use_utility_code( + complex_conversion_utility_code.specialize(self, + math_h_modifier = self.real_type.math_h_modifier, + real_type = self.real_type.declaration_code(''), + type_convert = self.real_type.from_py_function)) + self.from_py_function = "__pyx_PyObject_As_" + self.specalization_name() + return True + + def lookup_op(self, nargs, op): + try: + return self.binops[nargs, op] + except KeyError: + pass + try: + op_name = complex_ops[nargs, op] + self.binops[nargs, op] = func_name = "%s_%s" % (self.specalization_name(), op_name) + return func_name + except KeyError: + return None + + def unary_op(self, op): + return self.lookup_op(1, op) + + def binary_op(self, op): + return self.lookup_op(2, op) + +complex_ops = { + (1, '-'): 'neg', + (1, 'zero'): 'is_zero', + (2, '+'): 'add', + (2, '-') : 'sub', + (2, '*'): 'mul', + (2, '/'): 'div', + (2, '=='): 'eq', +} + +complex_generic_utility_code = UtilityCode( +proto=""" +#if __PYX_USE_C99_COMPLEX + #define __Pyx_REAL_PART(z) __real__(z) + #define __Pyx_IMAG_PART(z) __imag__(z) +#else + #define __Pyx_REAL_PART(z) ((z).real) + #define __Pyx_IMAG_PART(z) ((z).imag) +#endif + +#define __pyx_PyObject_from_complex(z) PyComplex_FromDoubles((double)__Pyx_REAL_PART(z), (double)__Pyx_IMAG_PART(z)) +""") + +complex_conversion_utility_code = UtilityCode( +proto=""" +static %(type)s __pyx_PyObject_As_%(type_name)s(PyObject* o); /* proto */ +""", +impl=""" +static %(type)s __pyx_PyObject_As_%(type_name)s(PyObject* o) { + if (PyComplex_Check(o)) { + return %(type_name)s_from_parts( + (%(real_type)s)((PyComplexObject *)o)->cval.real, + (%(real_type)s)((PyComplexObject *)o)->cval.imag); + } + else { + return %(type_name)s_from_parts(%(type_convert)s(o), 0); + } +} +""") + +complex_arithmatic_utility_code = UtilityCode( +proto=""" +#if __PYX_USE_C99_COMPLEX + + typedef %(real_type)s _Complex %(type_name)s; + static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) { + return x + y*(%(type)s)_Complex_I; + } + + #define %(type_name)s_is_zero(a) ((a) == 0) + #define %(type_name)s_eq(a, b) ((a) == (b)) + #define %(type_name)s_add(a, b) ((a)+(b)) + #define %(type_name)s_sub(a, b) ((a)-(b)) + #define %(type_name)s_mul(a, b) ((a)*(b)) + #define %(type_name)s_div(a, b) ((a)/(b)) + #define %(type_name)s_neg(a) (-(a)) + +#else + + typedef struct { %(real_type)s real, imag; } %(type_name)s; + static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) { + %(type)s c; c.real = x; c.imag = y; return c; + } + + static INLINE int %(type_name)s_is_zero(%(type)s a) { + return (a.real == 0) & (a.imag == 0); + } + + static INLINE int %(type_name)s_eq(%(type)s a, %(type)s b) { + return (a.real == b.real) & (a.imag == b.imag); + } + + static INLINE %(type)s %(type_name)s_add(%(type)s a, %(type)s b) { + %(type)s z; + z.real = a.real + b.real; + z.imag = a.imag + b.imag; + return z; + } + + static INLINE %(type)s %(type_name)s_sub(%(type)s a, %(type)s b) { + %(type)s z; + z.real = a.real - b.real; + z.imag = a.imag - b.imag; + return z; + } + + static INLINE %(type)s %(type_name)s_mul(%(type)s a, %(type)s b) { + %(type)s z; + z.real = a.real * b.real - a.imag * b.imag; + z.imag = a.real * b.imag + a.imag * b.real; + return z; + } + + static INLINE %(type)s %(type_name)s_div(%(type)s a, %(type)s b) { + %(type)s z; + %(real_type)s denom = b.real*b.real + b.imag*b.imag; + z.real = (a.real * b.real + a.imag * b.imag) / denom; + z.imag = (a.imag * b.real - a.real * b.imag) / denom; + return z; + } + + static INLINE %(type)s %(type_name)s_neg(%(type)s a) { + %(type)s z; + z.real = -a.real; + z.imag = -a.imag; + return z; + } + +#endif +""") class CArrayType(CType): @@ -744,7 +1038,7 @@ 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 ### + # self, other_type, "as_cmethod =", as_cmethod ### if other_type is error_type: return 1 if not other_type.is_cfunction: @@ -776,7 +1070,7 @@ def compatible_signature_with_resolved_type(self, other_type, as_cmethod): #print "CFuncType.same_c_signature_as_resolved_type:", \ - # self, other_type, "as_cmethod =", as_cmethod ### + # self, other_type, "as_cmethod =", as_cmethod ### if other_type is error_type: return 1 if not other_type.is_cfunction: @@ -835,6 +1129,15 @@ return 1 def same_calling_convention_as(self, other): + ## XXX Under discussion ... + ## callspec_words = ("__stdcall", "__cdecl", "__fastcall") + ## cs1 = self.calling_convention + ## cs2 = other.calling_convention + ## if (cs1 in callspec_words or + ## cs2 in callspec_words): + ## return cs1 == cs2 + ## else: + ## return True sc1 = self.calling_convention == '__stdcall' sc2 = other.calling_convention == '__stdcall' return sc1 == sc2 @@ -858,7 +1161,8 @@ and not (self.nogil and not other_type.nogil) def declaration_code(self, entity_code, - for_display = 0, dll_linkage = None, pyrex = 0): + for_display = 0, dll_linkage = None, pyrex = 0, + with_calling_convention = 1): arg_decl_list = [] for arg in self.args[:len(self.args)-self.optional_arg_count]: arg_decl_list.append( @@ -884,14 +1188,17 @@ " except *" # ignored 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 = "" + if not with_calling_convention: + cc = '' + else: + 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) @@ -900,8 +1207,12 @@ s = self.declaration_code("") return s + def signature_cast_string(self): + s = self.declaration_code("(*)", with_calling_convention=False) + return '(%s)' % s + -class CFuncTypeArg: +class CFuncTypeArg(object): # name string # cname string # type PyrexType @@ -931,11 +1242,12 @@ # kind string "struct" or "union" # scope StructOrUnionScope, or None if incomplete # typedef_flag boolean + # packed boolean is_struct_or_union = 1 has_attributes = 1 - def __init__(self, name, kind, scope, typedef_flag, cname): + def __init__(self, name, kind, scope, typedef_flag, cname, packed=False): self.name = name self.cname = cname self.kind = kind @@ -946,20 +1258,22 @@ self.to_py_function = "%s_to_py_%s" % (Naming.convert_func_prefix, self.cname) self.exception_check = True self._convert_code = None + self.packed = packed - def create_convert_utility_code(self, env): + def create_to_py_utility_code(self, env): if env.outer_scope is None: return False if self._convert_code is None: import Code code = Code.CCodeWriter() + Code.GlobalState(code) header = "static PyObject* %s(%s)" % (self.to_py_function, self.declaration_code('s')) code.putln("%s {" % header) code.putln("PyObject* res;") code.putln("PyObject* member;") code.putln("res = PyDict_New(); if (res == NULL) return NULL;") for member in self.scope.var_entries: - if member.type.to_py_function and member.type.create_convert_utility_code(env): + if member.type.to_py_function and member.type.create_to_py_utility_code(env): interned_name = env.get_string_const(member.name, identifier=True) env.add_py_string(interned_name) code.putln("member = %s(s.%s); if (member == NULL) goto bad;" % ( @@ -1019,10 +1333,18 @@ return self.is_complete() def can_be_complex(self): - # Does the struct consist of exactly two floats? + # Does the struct consist of exactly two identical floats? fields = self.scope.var_entries - return len(fields) == 2 and fields[0].type.is_float and fields[1].type.is_float - + if len(fields) != 2: return False + a, b = fields + return (a.type.is_float and b.type.is_float and + a.type.declaration_code("") == + b.type.declaration_code("")) + + def struct_nesting_depth(self): + child_depths = [x.type.struct_nesting_depth() + for x in self.scope.var_entries] + return max(child_depths) + 1 class CEnumType(CType): # name string @@ -1060,7 +1382,7 @@ return self.base_declaration_code(public_decl(base, dll_linkage), entity_code) -class CStringType: +class CStringType(object): # Mixin class for C string types. is_string = 1 @@ -1078,7 +1400,6 @@ class CUTF8CharArrayType(CStringType, CArrayType): # C 'char []' type. - parsetuple_format = "s" pymemberdef_typecode = "T_STRING_INPLACE" is_unicode = 1 @@ -1091,7 +1412,6 @@ class CCharArrayType(CStringType, CArrayType): # C 'char []' type. - parsetuple_format = "s" pymemberdef_typecode = "T_STRING_INPLACE" def __init__(self, size): @@ -1101,7 +1421,6 @@ class CCharPtrType(CStringType, CPtrType): # C 'char *' type. - parsetuple_format = "s" pymemberdef_typecode = "T_STRING" def __init__(self): @@ -1124,11 +1443,14 @@ is_error = 1 exception_value = "0" - exception_check = 0 + exception_check = 0 to_py_function = "dummy" from_py_function = "dummy" - def create_convert_utility_code(self, env): + def create_to_py_utility_code(self, env): + return True + + def create_from_py_utility_code(self, env): return True def declaration_code(self, entity_code, @@ -1147,11 +1469,12 @@ "short", # 1 "int", # 2 "long", # 3 - "PY_LONG_LONG", # 4 - "Py_ssize_t", # 5 - "float", # 6 - "double", # 7 - "long double", # 8 + "Py_ssize_t", # 4 + "size_t", # 5 + "PY_LONG_LONG", # 6 + "float", # 7 + "double", # 8 + "long double", # 9 ) py_object_type = PyObjectType() @@ -1164,33 +1487,38 @@ 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_ulonglong_type = CULongLongType(6, 0, "T_ULONGLONG") 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_py_ssize_t_type = CPySSizeTType(5, 1) +c_long_type = CLongType(3, 1, "T_LONG") +c_longlong_type = CLongLongType(6, 1, "T_LONGLONG") c_bint_type = CBIntType(2, 1, "T_INT") c_schar_type = CIntType(0, 2, "T_CHAR") c_sshort_type = CIntType(1, 2, "T_SHORT") c_sint_type = CIntType(2, 2, "T_INT") -c_slong_type = CIntType(3, 2, "T_LONG") -c_slonglong_type = CLongLongType(4, 2, "T_LONGLONG") +c_slong_type = CLongType(3, 2, "T_LONG") +c_slonglong_type = CLongLongType(6, 2, "T_LONGLONG") -c_float_type = CFloatType(6, "T_FLOAT") -c_double_type = CFloatType(7, "T_DOUBLE") -c_longdouble_type = CFloatType(8) +c_py_ssize_t_type = CPySSizeTType(4, 2, "T_PYSSIZET") +c_size_t_type = CSizeTType(5, 0, "T_SIZET") + +c_float_type = CFloatType(7, "T_FLOAT", math_h_modifier='f') +c_double_type = CFloatType(8, "T_DOUBLE") +c_longdouble_type = CFloatType(9, math_h_modifier='l') + +c_double_complex_type = CComplexType(c_double_type) c_null_ptr_type = CNullPtrType(c_void_type) c_char_array_type = CCharArrayType(None) c_char_ptr_type = CCharPtrType() c_utf8_char_array_type = CUTF8CharArrayType(None) c_char_ptr_ptr_type = CPtrType(c_char_ptr_type) -c_py_ssize_t_ptr_type = CPtrType(c_py_ssize_t_type) c_int_ptr_type = CPtrType(c_int_type) +c_py_ssize_t_ptr_type = CPtrType(c_py_ssize_t_type) +c_size_t_ptr_type = CPtrType(c_size_t_type) c_returncode_type = CIntType(2, 1, "T_INT", is_returncode = 1) @@ -1203,63 +1531,69 @@ error_type = ErrorType() unspecified_type = UnspecifiedType() -lowest_float_rank = 6 - 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, - (0, 5): c_ulonglong_type, # I'm not sure about this. this should be for size_t Py_ssize_t - (1, 0): c_char_type, - (1, 1): c_short_type, - (1, 2): c_int_type, + (0, 0): c_uchar_type, + (0, 1): c_ushort_type, + (0, 2): c_uint_type, + (0, 3): c_ulong_type, + (0, 6): 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_py_ssize_t_type, - (2, 0): c_schar_type, - (2, 1): c_sshort_type, - (2, 2): c_sint_type, + (1, 6): c_longlong_type, + + (2, 0): c_schar_type, + (2, 1): c_sshort_type, + (2, 2): c_sint_type, (2, 3): c_slong_type, - (2, 4): c_slonglong_type, - (2, 5): c_py_ssize_t_type, - (1, 6): c_float_type, - (1, 7): c_double_type, - (1, 8): c_longdouble_type, + (2, 6): c_slonglong_type, + + (0, 4): c_py_ssize_t_type, + (1, 4): c_py_ssize_t_type, + (2, 4): c_py_ssize_t_type, + (0, 5): c_size_t_type, + (1, 5): c_size_t_type, + (2, 5): c_size_t_type, + + (1, 7): c_float_type, + (1, 8): c_double_type, + (1, 9): c_longdouble_type, # In case we're mixing unsigned ints and floats... - (0, 6): c_float_type, - (0, 7): c_double_type, - (0, 8): c_longdouble_type, + (0, 7): c_float_type, + (0, 8): c_double_type, + (0, 9): 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, 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, 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, "Py_ssize_t"): c_py_ssize_t_type, - (1, 0, "float"): c_float_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, - (1, 0, "bint"): c_bint_type, - (2, 0, "char"): c_schar_type, - (2, -1, "int"): c_sshort_type, - (2, 0, "int"): c_sint_type, + (1, 0, "bint"): c_bint_type, + (2, 0, "char"): c_schar_type, + (2, -1, "int"): c_sshort_type, + (2, 0, "int"): c_sint_type, (2, 1, "int"): c_slong_type, (2, 2, "int"): c_slonglong_type, + (2, 0, "Py_ssize_t"): c_py_ssize_t_type, - + (0, 0, "size_t") : c_size_t_type, + (1, 0, "long"): c_long_type, (1, 0, "short"): c_short_type, (1, 0, "longlong"): c_longlong_type, @@ -1269,6 +1603,15 @@ def widest_numeric_type(type1, type2): # Given two numeric types, return the narrowest type # encompassing both of them. + if type1 == type2: + return type1 + if type1.is_complex: + if type2.is_complex: + return CComplexType(widest_numeric_type(type1.real_type, type2.real_type)) + else: + return CComplexType(widest_numeric_type(type1.real_type, type2)) + elif type2.is_complex: + return CComplexType(widest_numeric_type(type1, type2.real_type)) if type1.is_enum and type2.is_enum: return c_int_type elif type1 is type2: @@ -1333,12 +1676,6 @@ else: error(node.pos, "Bad 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) @@ -1361,27 +1698,111 @@ /* Type Conversion Predeclarations */ #if PY_MAJOR_VERSION < 3 -#define __Pyx_PyBytes_FromString PyString_FromString -#define __Pyx_PyBytes_AsString PyString_AsString +#define __Pyx_PyBytes_FromString PyString_FromString +#define __Pyx_PyBytes_FromStringAndSize PyString_FromStringAndSize +#define __Pyx_PyBytes_AsString PyString_AsString #else -#define __Pyx_PyBytes_FromString PyBytes_FromString -#define __Pyx_PyBytes_AsString PyBytes_AsString +#define __Pyx_PyBytes_FromString PyBytes_FromString +#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +#define __Pyx_PyBytes_AsString PyBytes_AsString #endif #define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False)) -static INLINE int __Pyx_PyObject_IsTrue(PyObject* x); -static INLINE PY_LONG_LONG __pyx_PyInt_AsLongLong(PyObject* x); -static INLINE unsigned PY_LONG_LONG __pyx_PyInt_AsUnsignedLongLong(PyObject* x); -static INLINE Py_ssize_t __pyx_PyIndex_AsSsize_t(PyObject* b); +static INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x); + +#if !defined(T_PYSSIZET) +#if PY_VERSION_HEX < 0x02050000 +#define T_PYSSIZET T_INT +#elif !defined(T_LONGLONG) +#define T_PYSSIZET \\ + ((sizeof(Py_ssize_t) == sizeof(int)) ? T_INT : \\ + ((sizeof(Py_ssize_t) == sizeof(long)) ? T_LONG : -1)) +#else +#define T_PYSSIZET \\ + ((sizeof(Py_ssize_t) == sizeof(int)) ? T_INT : \\ + ((sizeof(Py_ssize_t) == sizeof(long)) ? T_LONG : \\ + ((sizeof(Py_ssize_t) == sizeof(PY_LONG_LONG)) ? T_LONGLONG : -1))) +#endif +#endif + +#if !defined(T_SIZET) +#if !defined(T_ULONGLONG) +#define T_SIZET \\ + ((sizeof(size_t) == sizeof(unsigned int)) ? T_UINT : \\ + ((sizeof(size_t) == sizeof(unsigned long)) ? T_ULONG : -1)) +#else +#define T_SIZET \\ + ((sizeof(size_t) == sizeof(unsigned int)) ? T_UINT : \\ + ((sizeof(size_t) == sizeof(unsigned long)) ? T_ULONG : \\ + ((sizeof(size_t) == sizeof(unsigned PY_LONG_LONG)) ? T_ULONGLONG : -1))) +#endif +#endif + +static INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); +static INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); +static INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*); -#define __pyx_PyInt_AsLong(x) (PyInt_CheckExact(x) ? PyInt_AS_LONG(x) : PyInt_AsLong(x)) #define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) + """ + type_conversion_predeclarations type_conversion_functions = """ /* Type Conversion Functions */ -static INLINE Py_ssize_t __pyx_PyIndex_AsSsize_t(PyObject* b) { +static INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + if (x == Py_True) return 1; + else if ((x == Py_False) | (x == Py_None)) return 0; + else return PyObject_IsTrue(x); +} + +static INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) { + PyNumberMethods *m; + const char *name = NULL; + PyObject *res = NULL; +#if PY_VERSION_HEX < 0x03000000 + if (PyInt_Check(x) || PyLong_Check(x)) +#else + if (PyLong_Check(x)) +#endif + return Py_INCREF(x), x; + m = Py_TYPE(x)->tp_as_number; +#if PY_VERSION_HEX < 0x03000000 + if (m && m->nb_int) { + name = "int"; + res = PyNumber_Int(x); + } + else if (m && m->nb_long) { + name = "long"; + res = PyNumber_Long(x); + } +#else + if (m && m->nb_int) { + name = "int"; + res = PyNumber_Long(x); + } +#endif + if (res) { +#if PY_VERSION_HEX < 0x03000000 + if (!PyInt_Check(res) && !PyLong_Check(res)) { +#else + if (!PyLong_Check(res)) { +#endif + PyErr_Format(PyExc_TypeError, + "__%s__ returned non-%s (type %.200s)", + name, name, Py_TYPE(res)->tp_name); + Py_DECREF(res); + return NULL; + } + } + else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + } + return res; +} + +static INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { Py_ssize_t ival; PyObject* x = PyNumber_Index(b); if (!x) return -1; @@ -1390,47 +1811,32 @@ return ival; } -static INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { - if (x == Py_True) return 1; - else if (x == Py_False) return 0; - else return PyObject_IsTrue(x); -} - -static INLINE PY_LONG_LONG __pyx_PyInt_AsLongLong(PyObject* x) { - if (PyInt_CheckExact(x)) { - return PyInt_AS_LONG(x); - } - else if (PyLong_CheckExact(x)) { - return PyLong_AsLongLong(x); - } - else { - PY_LONG_LONG val; - PyObject* tmp = PyNumber_Int(x); if (!tmp) return (PY_LONG_LONG)-1; - val = __pyx_PyInt_AsLongLong(tmp); - Py_DECREF(tmp); - return val; - } +static INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { +#if PY_VERSION_HEX < 0x02050000 + if (ival <= LONG_MAX) + return PyInt_FromLong((long)ival); + else { + unsigned char *bytes = (unsigned char *) &ival; + int one = 1; int little = (int)*(unsigned char*)&one; + return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0); + } +#else + return PyInt_FromSize_t(ival); +#endif } -static INLINE unsigned PY_LONG_LONG __pyx_PyInt_AsUnsignedLongLong(PyObject* x) { - if (PyInt_CheckExact(x)) { - long val = PyInt_AS_LONG(x); - if (unlikely(val < 0)) { - PyErr_SetString(PyExc_TypeError, "Negative assignment to unsigned type."); - return (unsigned PY_LONG_LONG)-1; - } - return val; - } - else if (PyLong_CheckExact(x)) { - return PyLong_AsUnsignedLongLong(x); - } - else { - PY_LONG_LONG val; - PyObject* tmp = PyNumber_Int(x); if (!tmp) return (PY_LONG_LONG)-1; - val = __pyx_PyInt_AsUnsignedLongLong(tmp); - Py_DECREF(tmp); - return val; - } +static INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) { + unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x); + if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) { + return (size_t)-1; + } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) { + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to size_t"); + return (size_t)-1; + } + return (size_t)val; } """ + type_conversion_functions + + diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/Scanning.pxd /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/Scanning.pxd --- cython-0.10.3/Cython/Compiler/Scanning.pxd 1970-01-01 01:00:00.000000000 +0100 +++ cython-0.11.2/Cython/Compiler/Scanning.pxd 2009-05-20 16:37:46.000000000 +0100 @@ -0,0 +1,29 @@ +import cython + +from Cython.Plex.Scanners cimport Scanner + +cdef class CompileTimeScope: + cdef public entries + cdef public outer + +cdef class PyrexScanner(Scanner): + cdef public context + cdef public list included_files + cdef public compile_time_env + cdef public bint compile_time_eval + cdef public bint compile_time_expr + cdef public bint parse_comments + cdef public source_encoding + cdef public list indentation_stack + cdef public indentation_char + cdef public int bracket_nesting_level + cdef public sy + cdef public systring + + cdef long current_level(self) + cpdef begin(self, state) + cpdef next(self) + cpdef bint expect(self, what, message = *) except -2 + + @cython.locals(current_level=cython.long, new_level=cython.long) + cpdef indentation_action(self, text) diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/Scanning.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/Scanning.py --- cython-0.10.3/Cython/Compiler/Scanning.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/Scanning.py 2009-05-20 16:37:46.000000000 +0100 @@ -11,15 +11,21 @@ import sys from time import time +import cython +cython.declare(EncodedString=object, string_prefixes=object, raw_prefixes=object, IDENT=object) + from Cython import Plex, Utils -from Cython.Plex import Scanner +from Cython.Plex.Scanners import Scanner from Cython.Plex.Errors import UnrecognizedInput from Errors import CompileError, error -from Lexicon import string_prefixes, raw_prefixes, make_lexicon +from Lexicon import string_prefixes, raw_prefixes, make_lexicon, IDENT from StringEncoding import EncodedString -plex_version = getattr(Plex, '_version', None) +try: + plex_version = Plex._version +except AttributeError: + plex_version = None #print "Plex version:", plex_version ### debug_scanner = 0 @@ -42,6 +48,7 @@ from hashlib import md5 as new_md5 except ImportError: from md5 import new as new_md5 + f = None try: try: f = open(path, "rU") @@ -50,7 +57,8 @@ print("Unable to hash scanner source file (%s)" % e) return "" finally: - f.close() + if f: + 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 @@ -78,7 +86,7 @@ print("Lexicon hash mismatch:") ### print(" expected " + expected_hash) ### print(" got " + actual_hash) ### - except IOError, e: + except (IOError, pickle.UnpicklingError), e: print("Warning: Unable to read pickled lexicon " + lexicon_pickle) print(e) if f: @@ -91,12 +99,17 @@ 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) + f = open_pickled_lexicon(lexicon_hash) if f: if notify_lexicon_unpickling: t0 = time() print("Unpickling lexicon...") - lexicon = pickle.load(f) + try: + lexicon = pickle.load(f) + except Exception, e: + print "WARNING: Exception while loading lexicon pickle, regenerating" + print e + lexicon = None f.close() if notify_lexicon_unpickling: t1 = time() @@ -144,11 +157,11 @@ "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", + "and", "or", "not", "is", "in", "lambda", "from", "yield", "cimport", "by", "with", "cpdef", "DEF", "IF", "ELIF", "ELSE" ] -class Method: +class Method(object): def __init__(self, name): self.name = name @@ -165,6 +178,9 @@ d[word] = 1 return d +cython.declare(resword_dict=object) +resword_dict = build_resword_dict() + #------------------------------------------------------------------ class CompileTimeScope(object): @@ -178,6 +194,9 @@ def lookup_here(self, name): return self.entries[name] + + def __contains__(self, name): + return name in self.entries def lookup(self, name): try: @@ -208,7 +227,7 @@ #------------------------------------------------------------------ -class SourceDescriptor: +class SourceDescriptor(object): """ A SourceDescriptor should be considered immutable. """ @@ -286,7 +305,6 @@ # 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, source_encoding=None, parse_comments=True, initial_pos=None): @@ -360,7 +378,7 @@ self.begin('') # Indentation within brackets should be ignored. #if self.bracket_nesting_level > 0: - # return + # return # Check that tabs and spaces are being used consistently. if text: c = text[0] @@ -403,15 +421,15 @@ sy, systring = self.read() except UnrecognizedInput: self.error("Unrecognized character") - if sy == 'IDENT': - if systring in self.resword_dict: + if sy == IDENT: + if systring in resword_dict: sy = systring else: systring = EncodedString(systring) systring.encoding = self.source_encoding self.sy = sy self.systring = systring - if debug_scanner: + if False: # debug_scanner: _, line, col = self.position() if not self.systring or self.sy == self.systring: t = self.sy @@ -443,12 +461,12 @@ self.expected(what, message) def expect_keyword(self, what, message = None): - if self.sy == 'IDENT' and self.systring == what: + if self.sy == IDENT and self.systring == what: self.next() else: self.expected(what, message) - def expected(self, what, message): + def expected(self, what, message = None): if message: self.error(message) else: diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/Symtab.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/Symtab.py --- cython-0.10.3/Cython/Compiler/Symtab.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/Symtab.py 2009-05-20 16:37:46.000000000 +0100 @@ -23,7 +23,24 @@ possible_identifier = re.compile(ur"(?![0-9])\w+$", re.U).match nice_identifier = re.compile('^[a-zA-Z0-0_]+$').match -class BufferAux: +iso_c99_keywords = set( +['auto', 'break', 'case', 'char', 'const', 'continue', 'default', 'do', + 'double', 'else', 'enum', 'extern', 'float', 'for', 'goto', 'if', + 'int', 'long', 'register', 'return', 'short', 'signed', 'sizeof', + 'static', 'struct', 'switch', 'typedef', 'union', 'unsigned', 'void', + 'volatile', 'while', + '_Bool', '_Complex'', _Imaginary', 'inline', 'restrict']) + +def c_safe_identifier(cname): + # There are some C limitations on struct entry names. + if ((cname[:2] == '__' + and not (cname.startswith(Naming.pyrex_prefix) + or cname == '__weakref__')) + or cname in iso_c99_keywords): + cname = Naming.pyrex_prefix + cname + return cname + +class BufferAux(object): writable_needed = False def __init__(self, buffer_info_var, stridevars, shapevars, @@ -36,7 +53,7 @@ def __repr__(self): return "" % self.__dict__ -class Entry: +class Entry(object): # A symbol table entry in a Scope or ModuleNamespace. # # name string Python name of entity @@ -68,6 +85,7 @@ # in_closure boolean Is referenced in an inner scope # is_readonly boolean Can't be assigned to # func_cname string C func implementing Python func + # func_modifiers [string] C function modifiers ('inline') # pos position Source position where declared # namespace_cname string If is_pyglobal, the C variable # holding its home namespace @@ -96,7 +114,10 @@ # utility_code string Utility code needed when this entry is used # # buffer_aux BufferAux or None Extra information needed for buffer variables + # inline_func_in_pxd boolean Hacky special case for inline function in pxd file. + # Ideally this should not be necesarry. + inline_func_in_pxd = False borrowed = 0 init = "" visibility = 'private' @@ -122,6 +143,7 @@ is_declared_generic = 0 is_readonly = 0 func_cname = None + func_modifiers = [] doc = None init_to_none = 0 as_variable = None @@ -153,7 +175,7 @@ error(pos, "'%s' does not match previous declaration" % self.name) error(self.pos, "Previous declaration is here") -class Scope: +class Scope(object): # name string Unqualified name # outer_scope Scope or None Enclosing scope # entries {string : Entry} Python name to entry, non-types @@ -189,7 +211,6 @@ scope_prefix = "" in_cinclude = 0 nogil = 0 - directives = {} temp_prefix = Naming.pyrex_prefix @@ -277,8 +298,8 @@ if not self.in_cinclude and cname and re.match("^_[_A-Z]+$", cname): # See http://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html#Reserved-Names warning(pos, "'%s' is a reserved name in C." % cname, -1) - dict = self.entries - if name and dict.has_key(name): + entries = self.entries + if name and name in entries: if visibility == 'extern': warning(pos, "'%s' redeclared " % name, 0) elif visibility != 'ignore': @@ -287,7 +308,7 @@ entry.in_cinclude = self.in_cinclude if name: entry.qualified_name = self.qualify_name(name) - dict[name] = entry + entries[name] = entry entry.scope = self entry.visibility = visibility return entry @@ -298,7 +319,7 @@ def declare_const(self, name, type, value, pos, cname = None, visibility = 'private'): # Add an entry for a named constant. if not cname: - if self.in_cinclude: + if self.in_cinclude or visibility == 'public': cname = name else: cname = self.mangle(Naming.enum_prefix, name) @@ -326,13 +347,14 @@ cname = name else: cname = self.mangle(Naming.type_prefix, name) - type = PyrexTypes.CTypedefType(cname, base_type) + type = PyrexTypes.CTypedefType(cname, base_type, (visibility == 'extern')) 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'): + typedef_flag, pos, cname = None, visibility = 'private', + packed = False): # Add an entry for a struct or union definition. if not cname: if self.in_cinclude or visibility == 'public': @@ -342,7 +364,7 @@ entry = self.lookup_here(name) if not entry: type = PyrexTypes.CStructOrUnionType( - name, kind, scope, typedef_flag, cname) + name, kind, scope, typedef_flag, cname, packed) entry = self.declare_type(name, type, pos, cname, visibility = visibility, defining = scope is not None) self.sue_entries.append(entry) @@ -387,7 +409,7 @@ visibility = visibility) entry.enum_values = [] self.sue_entries.append(entry) - return entry + return entry def declare_var(self, name, type, pos, cname = None, visibility = 'private', is_cdef = 0): @@ -420,7 +442,8 @@ self.pyfunc_entries.append(entry) def declare_cfunction(self, name, type, pos, - cname = None, visibility = 'private', defining = 0, api = 0, in_pxd = 0): + cname = None, visibility = 'private', defining = 0, + api = 0, in_pxd = 0, modifiers = ()): # Add an entry for a C function. entry = self.lookup_here(name) if entry: @@ -438,7 +461,7 @@ cname = name else: cname = self.mangle(Naming.func_prefix, name) - entry = self.add_cfunction(name, type, pos, cname, visibility) + entry = self.add_cfunction(name, type, pos, cname, visibility, modifiers) entry.func_cname = cname if in_pxd and visibility != 'extern': entry.defined_in_pxd = 1 @@ -448,12 +471,16 @@ error(pos, "Non-extern C function '%s' declared but not defined" % name) if defining: entry.is_implemented = True + if modifiers: + entry.func_modifiers = modifiers return entry - def add_cfunction(self, name, type, pos, cname, visibility): + def add_cfunction(self, name, type, pos, cname, visibility, modifiers): # Add a C function entry without giving it a func_cname. entry = self.declare(name, cname, type, pos, visibility) entry.is_cfunction = 1 + if modifiers: + entry.func_modifiers = modifiers self.cfunc_entries.append(entry) return entry @@ -652,7 +679,7 @@ # Test whether any of the given names are # defined in this scope. for name in names: - if name in self.entries: + if name in self.entries: return 1 return 0 @@ -795,7 +822,12 @@ self.parent_module = parent_module outer_scope = context.find_submodule("__builtin__") Scope.__init__(self, name, outer_scope, parent_module) - self.module_name = name + if name != "__init__": + self.module_name = name + else: + # Treat Spam/__init__.pyx specially, so that when Python loads + # Spam/__init__.so, initSpam() is defined. + self.module_name = parent_module.module_name self.context = context self.module_cname = Naming.module_cname self.module_dict_cname = Naming.moddict_cname @@ -821,6 +853,8 @@ self.cached_builtins = [] self.undeclared_cached_builtins = [] self.namespace_cname = self.module_cname + for name in ['__builtins__', '__name__', '__file__', '__doc__']: + self.declare_var(EncodedString(name), py_object_type, None) def qualifying_scope(self): return self.parent_module @@ -887,7 +921,11 @@ def add_imported_module(self, scope): if scope not in self.cimported_modules: + for filename in scope.include_files: + self.add_include_file(filename) self.cimported_modules.append(scope) + for m in scope.cimported_modules: + self.add_imported_module(m) def add_imported_entry(self, name, entry, pos): if entry not in self.entries: @@ -918,7 +956,7 @@ else: entry = self.declare_var(name, py_object_type, pos) entry.as_module = scope - self.cimported_modules.append(scope) + self.add_imported_module(scope) return entry def declare_var(self, name, type, pos, @@ -1007,7 +1045,7 @@ if objstruct_cname: type.objstruct_cname = objstruct_cname elif not entry.in_cinclude: - type.objstruct_cname = self.mangle(Naming.objstruct_prefix, name) + type.objstruct_cname = self.mangle(Naming.objstruct_prefix, name) else: error(entry.pos, "Object name required for 'public' or 'extern' C class") @@ -1046,13 +1084,13 @@ if objstruct_cname: if type.objstruct_cname and type.objstruct_cname != objstruct_cname: error(pos, "Object struct name differs from previous declaration") - type.objstruct_cname = objstruct_cname + type.objstruct_cname = objstruct_cname if typeobj_cname: if type.typeobj_cname and type.typeobj_cname != typeobj_cname: error(pos, "Type object name differs from previous declaration") type.typeobj_cname = typeobj_cname # - # Return new or existing entry + # Return new or existing entry # return entry @@ -1231,6 +1269,8 @@ # Add an entry for an attribute. if not cname: cname = name + if visibility == 'private': + cname = c_safe_identifier(cname) if type.is_cfunction: type = PyrexTypes.CPtrType(type) entry = self.declare(name, cname, type, pos, visibility) @@ -1245,7 +1285,8 @@ return entry def declare_cfunction(self, name, type, pos, - cname = None, visibility = 'private', defining = 0, api = 0, in_pxd = 0): + cname = None, visibility = 'private', defining = 0, + api = 0, in_pxd = 0, modifiers = ()): self.declare_var(name, type, pos, cname, visibility) class ClassScope(Scope): @@ -1307,7 +1348,7 @@ self.outer_scope.release_temp(cname) #def recycle_pending_temps(self): - # self.outer_scope.recycle_pending_temps() + # self.outer_scope.recycle_pending_temps() def add_default_value(self, type): return self.outer_scope.add_default_value(type) @@ -1365,6 +1406,8 @@ % name) if not cname: cname = name + if visibility == 'private': + cname = c_safe_identifier(cname) entry = self.declare(name, cname, type, pos, visibility) entry.is_variable = 1 self.var_entries.append(entry) @@ -1426,14 +1469,16 @@ return ClassScope.lookup_here(self, name) def declare_cfunction(self, name, type, pos, - cname = None, visibility = 'private', defining = 0, api = 0, in_pxd = 0): + cname = None, visibility = 'private', + defining = 0, api = 0, in_pxd = 0, modifiers = ()): 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") + error(pos, "Self argument (%s) of C method '%s' does not match parent type (%s)" % + (args[0].type, name, self.parent_type)) entry = self.lookup_here(name) if entry: if not entry.is_cfunction: @@ -1445,7 +1490,7 @@ if type.same_c_signature_as(entry.type, as_cmethod = 1) and type.nogil == entry.type.nogil: pass elif type.compatible_signature_with(entry.type, as_cmethod = 1) and type.nogil == entry.type.nogil: - entry = self.add_cfunction(name, type, pos, cname or name, visibility='ignore') + entry = self.add_cfunction(name, type, pos, cname or name, visibility='ignore', modifiers=modifiers) defining = 1 else: error(pos, "Signature not compatible with previous declaration") @@ -1455,15 +1500,17 @@ 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) + entry = self.add_cfunction(name, type, pos, cname or name, + visibility, modifiers) if defining: entry.func_cname = self.mangle(Naming.func_prefix, name) return entry - def add_cfunction(self, name, type, pos, cname, visibility): + def add_cfunction(self, name, type, pos, cname, visibility, modifiers): # Add a cfunction entry without giving it a func_cname. prev_entry = self.lookup_here(name) - entry = ClassScope.add_cfunction(self, name, type, pos, cname, visibility) + entry = ClassScope.add_cfunction(self, name, type, pos, cname, + visibility, modifiers) entry.is_cmethod = 1 entry.prev_entry = prev_entry return entry @@ -1494,7 +1541,8 @@ self.inherited_var_entries.append(entry) for base_entry in base_scope.cfunc_entries: entry = self.add_cfunction(base_entry.name, base_entry.type, - base_entry.pos, adapt(base_entry.cname), base_entry.visibility) + base_entry.pos, adapt(base_entry.cname), + base_entry.visibility, base_entry.func_modifiers) entry.is_inherited = 1 def allocate_temp(self, type): @@ -1536,7 +1584,7 @@ static PyObject* __Pyx_Method_ClassMethod(PyObject *method) { /* It appears that PyMethodDescr_Type is not anywhere exposed in the Python/C API */ /* if (!PyObject_TypeCheck(method, &PyMethodDescr_Type)) { */ - if (strcmp(Py_TYPE(method)->tp_name, "method_descriptor") == 0) { /* cdef classes */ + if (__Pyx_StrEq(Py_TYPE(method)->tp_name, "method_descriptor")) { /* cdef classes */ PyMethodDescrObject *descr = (PyMethodDescrObject *)method; return PyDescr_NewClassMethod(descr->d_type, descr->d_method); } diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/Tests/TestDecorators.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/Tests/TestDecorators.py --- cython-0.10.3/Cython/Compiler/Tests/TestDecorators.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/Tests/TestDecorators.py 2009-05-20 16:37:46.000000000 +0100 @@ -1,25 +1,25 @@ -import unittest -from Cython.TestUtils import TransformTest -from Cython.Compiler.ParseTreeTransforms import DecoratorTransform - -class TestDecorator(TransformTest): - - def test_decorator(self): - t = self.run_pipeline([DecoratorTransform(None)], u""" - def decorator(fun): - return fun - @decorator - def decorated(): - pass - """) - - self.assertCode(u""" - def decorator(fun): - return fun - def decorated(): - pass - decorated = decorator(decorated) - """, t) - -if __name__ == '__main__': - unittest.main() +import unittest +from Cython.TestUtils import TransformTest +from Cython.Compiler.ParseTreeTransforms import DecoratorTransform + +class TestDecorator(TransformTest): + + def test_decorator(self): + t = self.run_pipeline([DecoratorTransform(None)], u""" + def decorator(fun): + return fun + @decorator + def decorated(): + pass + """) + + self.assertCode(u""" + def decorator(fun): + return fun + def decorated(): + pass + decorated = decorator(decorated) + """, t) + +if __name__ == '__main__': + unittest.main() diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/Tests/TestParseTreeTransforms.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/Tests/TestParseTreeTransforms.py --- cython-0.10.3/Cython/Compiler/Tests/TestParseTreeTransforms.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/Tests/TestParseTreeTransforms.py 2009-05-20 16:37:46.000000000 +0100 @@ -85,7 +85,7 @@ t = self.run_pipeline([NormalizeTree(None)], u"pass") self.assert_(len(t.stats) == 0) -class TestWithTransform(TransformTest): +class TestWithTransform(object): # (TransformTest): # Disabled! def test_simplified(self): t = self.run_pipeline([WithTransform(None)], u""" @@ -95,20 +95,21 @@ self.assertCode(u""" - $1_0 = x - $1_2 = $1_0.__exit__ - $1_0.__enter__() - $1_1 = True + $0_0 = x + $0_2 = $0_0.__exit__ + $0_0.__enter__() + $0_1 = True try: try: + $1_0 = None y = z ** 3 except: - $1_1 = False - if (not $1_2($0_0)): + $0_1 = False + if (not $0_2($1_0)): raise finally: - if $1_1: - $1_2(None, None, None) + if $0_1: + $0_2(None, None, None) """, t) @@ -119,21 +120,22 @@ """) self.assertCode(u""" - $1_0 = x - $1_2 = $1_0.__exit__ - $1_3 = $1_0.__enter__() - $1_1 = True + $0_0 = x + $0_2 = $0_0.__exit__ + $0_3 = $0_0.__enter__() + $0_1 = True try: try: - y = $1_3 + $1_0 = None + y = $0_3 y = z ** 3 except: - $1_1 = False - if (not $1_2($0_0)): + $0_1 = False + if (not $0_2($1_0)): raise finally: - if $1_1: - $1_2(None, None, None) + if $0_1: + $0_2(None, None, None) """, t) diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/Tests/TestTreeFragment.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/Tests/TestTreeFragment.py --- cython-0.10.3/Cython/Compiler/Tests/TestTreeFragment.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/Tests/TestTreeFragment.py 2009-05-20 16:37:46.000000000 +0100 @@ -48,17 +48,17 @@ self.assertEquals(v.pos, a.pos) def test_temps(self): - import Cython.Compiler.Visitor as v - v.tmpnamectr = 0 + TemplateTransform.temp_name_counter = 0 F = self.fragment(u""" TMP x = TMP """) T = F.substitute(temps=[u"TMP"]) - s = T.body.stats - self.assert_(isinstance(s[0].expr, TempRefNode)) - self.assert_(isinstance(s[1].rhs, TempRefNode)) - self.assert_(s[0].expr.handle is s[1].rhs.handle) + s = T.stats + self.assert_(s[0].expr.name == "__tmpvar_1") +# self.assert_(isinstance(s[0].expr, TempRefNode)) +# self.assert_(isinstance(s[1].rhs, TempRefNode)) +# self.assert_(s[0].expr.handle is s[1].rhs.handle) if __name__ == "__main__": import unittest diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/TreeFragment.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/TreeFragment.py --- cython-0.10.3/Cython/Compiler/TreeFragment.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/TreeFragment.py 2009-05-20 16:37:46.000000000 +0100 @@ -111,21 +111,25 @@ recursively applied to every member node. """ + temp_name_counter = 0 + def __call__(self, node, substitutions, temps, pos): self.substitutions = substitutions self.pos = pos tempmap = {} temphandles = [] for temp in temps: - handle = UtilNodes.TempHandle(PyrexTypes.py_object_type) + TemplateTransform.temp_name_counter += 1 + handle = "__tmpvar_%d" % TemplateTransform.temp_name_counter +# handle = UtilNodes.TempHandle(PyrexTypes.py_object_type) tempmap[temp] = handle - temphandles.append(handle) +# temphandles.append(handle) self.tempmap = tempmap result = super(TemplateTransform, self).__call__(node) - if temps: - result = UtilNodes.TempsBlockNode(self.get_pos(node), - temps=temphandles, - body=result) +# if temps: +# result = UtilNodes.TempsBlockNode(self.get_pos(node), +# temps=temphandles, +# body=result) return result def get_pos(self, node): @@ -156,8 +160,9 @@ def visit_NameNode(self, node): temphandle = self.tempmap.get(node.name) if temphandle: + return NameNode(pos=node.pos, name=temphandle) # Replace name with temporary - return temphandle.ref(self.get_pos(node)) + #return temphandle.ref(self.get_pos(node)) else: return self.try_substitution(node, node.name) diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/TypeSlots.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/TypeSlots.py --- cython-0.10.3/Cython/Compiler/TypeSlots.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/TypeSlots.py 2009-05-20 16:37:46.000000000 +0100 @@ -8,7 +8,7 @@ import StringEncoding import sys -class Signature: +class Signature(object): # Method slot signature descriptor. # # has_dummy_arg boolean @@ -119,7 +119,7 @@ return None -class SlotDescriptor: +class SlotDescriptor(object): # Abstract base class for type slot descriptors. # # slot_name string Member name of the slot in the type object @@ -154,7 +154,14 @@ code.putln("#if PY_MAJOR_VERSION >= 3") if flag: code.putln("#if (PY_MAJOR_VERSION >= 3) || (Py_TPFLAGS_DEFAULT & %s)" % flag) + if py3k == '': + code.putln("#if PY_MAJOR_VERSION >= 3") + code.putln("0, /*reserved*/") + code.putln("#else") + code.putln("%s, /*%s*/" % (value, self.slot_name)) + if py3k == '': + code.putln("#endif") if flag or (not py3k or not py2) or self.ifdef: code.putln("#endif") @@ -212,10 +219,13 @@ def slot_code(self, scope): entry = scope.lookup_here(self.method_name) - if entry: + if entry and entry.func_cname: return entry.func_cname - else: - return "0" + if self.default is not None: + entry = scope.lookup_here(self.default) + if entry and entry.func_cname: + return entry.func_cname + return "0" class InternalMethodSlot(SlotDescriptor): @@ -314,7 +324,7 @@ doc = scope.doc.utf8encode() else: doc = scope.doc.byteencode() - return '"%s"' % StringEncoding.escape_byte_string(doc) + return '__Pyx_DOCSTR("%s")' % StringEncoding.escape_byte_string(doc) else: return "0" @@ -398,7 +408,7 @@ ## extern function pointer. # #slots_initialised_from_extern = ( -# "tp_free", +# "tp_free", #) #------------------------------------------------------------------------------------------ @@ -557,8 +567,8 @@ MethodSlot(binaryfunc, "nb_xor", "__xor__"), MethodSlot(binaryfunc, "nb_or", "__or__"), EmptySlot("nb_coerce", py3k = False), - MethodSlot(unaryfunc, "nb_int", "__int__"), - MethodSlot(unaryfunc, "nb_long", "__long__"), + MethodSlot(unaryfunc, "nb_int", "__int__", default="__long__"), + MethodSlot(unaryfunc, "nb_long", "__long__", default="__int__", py3k = ""), MethodSlot(unaryfunc, "nb_float", "__float__"), MethodSlot(unaryfunc, "nb_oct", "__oct__", py3k = False), MethodSlot(unaryfunc, "nb_hex", "__hex__", py3k = False), diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/UtilNodes.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/UtilNodes.py --- cython-0.10.3/Cython/Compiler/UtilNodes.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/UtilNodes.py 2009-05-20 16:37:46.000000000 +0100 @@ -7,19 +7,23 @@ import Nodes import ExprNodes from Nodes import Node -from ExprNodes import ExprNode +from ExprNodes import AtomicExprNode class TempHandle(object): temp = None + needs_xdecref = False def __init__(self, type): self.type = type + self.needs_cleanup = type.is_pyobject def ref(self, pos): return TempRefNode(pos, handle=self, type=self.type) -class TempRefNode(ExprNode): + def cleanup_ref(self, pos): + return CleanupTempRefNode(pos, handle=self, type=self.type) + +class TempRefNode(AtomicExprNode): # handle TempHandle - subexprs = [] def analyse_types(self, env): assert self.type == self.handle.type @@ -41,9 +45,22 @@ def generate_assignment_code(self, rhs, code): if self.type.is_pyobject: rhs.make_owned_reference(code) + # TODO: analyse control flow to see if this is necessary code.put_xdecref(self.result(), self.ctype()) code.putln('%s = %s;' % (self.result(), rhs.result_as(self.ctype()))) rhs.generate_post_assignment_code(code) + rhs.free_temps(code) + +class CleanupTempRefNode(TempRefNode): + # handle TempHandle + + def generate_assignment_code(self, rhs, code): + pass + + def generate_execution_code(self, code): + if self.type.is_pyobject: + code.put_decref_clear(self.result(), self.type) + self.handle.needs_cleanup = False class TempsBlockNode(Node): """ @@ -63,9 +80,15 @@ def generate_execution_code(self, code): for handle in self.temps: - handle.temp = code.funcstate.allocate_temp(handle.type) + handle.temp = code.funcstate.allocate_temp( + handle.type, manage_ref=handle.needs_cleanup) self.body.generate_execution_code(code) for handle in self.temps: + if handle.needs_cleanup: + if handle.needs_xdecref: + code.put_xdecref_clear(handle.temp, handle.type) + else: + code.put_decref_clear(handle.temp, handle.type) code.funcstate.release_temp(handle.temp) def analyse_control_flow(self, env): @@ -83,3 +106,76 @@ def annotate(self, code): self.body.annotate(code) + +class ResultRefNode(AtomicExprNode): + # A reference to the result of an expression. The result_code + # must be set externally (usually a temp name). + + subexprs = [] + + def __init__(self, expression): + self.pos = expression.pos + self.expression = expression + + def analyse_types(self, env): + self.type = self.expression.type + + def result(self): + return self.result_code + + def generate_evaluation_code(self, code): + pass + + def generate_result_code(self, code): + pass + + def generate_disposal_code(self, code): + pass + + def allocate_temps(self, env): + pass + + def release_temp(self, env): + pass + + def free_temps(self, code): + pass + + +class EvalWithTempExprNode(ExprNodes.NewTempExprNode): + # A wrapper around a subexpression that moves an expression into a + # temp variable and provides it to the subexpression. + + subexprs = ['temp_expression', 'subexpression'] + + def __init__(self, lazy_temp, subexpression): + self.pos = subexpression.pos + self.lazy_temp = lazy_temp + self.temp_expression = lazy_temp.expression + self.subexpression = subexpression + + def result(self): + return self.subexpression.result() + + def analyse_types(self, env): + self.temp_expression.analyse_types(env) + self.subexpression.analyse_types(env) + self.type = self.subexpression.type + + def generate_evaluation_code(self, code): + self.temp_expression.generate_evaluation_code(code) + result_in_temp = self.temp_expression.result_in_temp() + temp_type = self.temp_expression.type + if result_in_temp: + temp = self.temp_expression.result() + else: + self.temp_expression.make_owned_reference(code) + temp = code.funcstate.allocate_temp( + temp_type, manage_ref=True) + code.putln("%s = %s;" % (temp, self.temp_expression.result())) + self.lazy_temp.result_code = temp + self.subexpression.generate_evaluation_code(code) + if not result_in_temp: + if temp_type.is_pyobject: + code.put_decref_clear(temp, temp_type) + code.funcstate.release_temp(temp) diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/Version.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/Version.py --- cython-0.10.3/Cython/Compiler/Version.py 2008-12-17 09:43:51.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/Version.py 2009-05-20 16:37:46.000000000 +0100 @@ -1 +1 @@ -version = '0.10.3' +version = '0.11.2' diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/Visitor.pxd /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/Visitor.pxd --- cython-0.10.3/Cython/Compiler/Visitor.pxd 1970-01-01 01:00:00.000000000 +0100 +++ cython-0.11.2/Cython/Compiler/Visitor.pxd 2009-05-20 16:37:46.000000000 +0100 @@ -0,0 +1,16 @@ +cdef class BasicVisitor: + cdef dict dispatch_table + cpdef visit(self, obj) + +cdef class TreeVisitor(BasicVisitor): + cdef public list access_path + cpdef visitchild(self, child, parent, attrname, idx) + +cdef class VisitorTransform(TreeVisitor): + cdef object _super_visitchildren + cpdef visitchildren(self, parent, attrs=*) + cpdef recurse_to_children(self, node) + +cdef class CythonTransform(VisitorTransform): + cdef public context + cdef public current_directives diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Compiler/Visitor.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Compiler/Visitor.py --- cython-0.10.3/Cython/Compiler/Visitor.py 2008-12-14 10:37:53.000000000 +0000 +++ cython-0.11.2/Cython/Compiler/Visitor.py 2009-05-20 16:37:46.000000000 +0100 @@ -1,10 +1,12 @@ # # Tree visitor and transform framework # +import cython import inspect import Nodes import ExprNodes import Naming +import Errors from StringEncoding import EncodedString class BasicVisitor(object): @@ -32,7 +34,7 @@ break if handler_method is None: print type(self), type(obj) - if hasattr(self, 'access_path'): + if hasattr(self, 'access_path') and self.access_path: print self.access_path if self.access_path: print self.access_path[-1][0].pos @@ -90,9 +92,85 @@ super(TreeVisitor, self).__init__() self.access_path = [] + def dump_node(self, node, indent=0): + ignored = list(node.child_attrs) + [u'child_attrs', u'pos', + u'gil_message', u'subexprs'] + values = [] + pos = node.pos + if pos: + source = pos[0] + if source: + import os.path + source = os.path.basename(source.get_description()) + values.append(u'%s:%s:%s' % (source, pos[1], pos[2])) + attribute_names = dir(node) + attribute_names.sort() + for attr in attribute_names: + if attr in ignored: + continue + if attr.startswith(u'_') or attr.endswith(u'_'): + continue + try: + value = getattr(node, attr) + except AttributeError: + continue + if value is None or value == 0: + continue + elif isinstance(value, list): + value = u'[...]/%d' % len(value) + elif not isinstance(value, (str, unicode, long, int, float)): + continue + else: + value = repr(value) + values.append(u'%s = %s' % (attr, value)) + return u'%s(%s)' % (node.__class__.__name__, + u',\n '.join(values)) + + def _find_node_path(self, stacktrace): + import os.path + last_traceback = stacktrace + nodes = [] + while hasattr(stacktrace, 'tb_frame'): + frame = stacktrace.tb_frame + node = frame.f_locals.get(u'self') + if isinstance(node, Nodes.Node): + code = frame.f_code + method_name = code.co_name + pos = (os.path.basename(code.co_filename), + code.co_firstlineno) + nodes.append((node, method_name, pos)) + last_traceback = stacktrace + stacktrace = stacktrace.tb_next + return (last_traceback, nodes) + def visitchild(self, child, parent, attrname, idx): self.access_path.append((parent, attrname, idx)) - result = self.visit(child) + try: + result = self.visit(child) + except Errors.CompileError: + raise + except Exception, e: + import sys + trace = [''] + for parent, attribute, index in self.access_path: + node = getattr(parent, attribute) + if index is None: + index = '' + else: + node = node[index] + index = u'[%d]' % index + trace.append(u'%s.%s%s = %s' % ( + parent.__class__.__name__, attribute, index, + self.dump_node(node))) + stacktrace, called_nodes = self._find_node_path(sys.exc_info()[2]) + last_node = child + for node, method_name, pos in called_nodes: + last_node = node + trace.append(u"File '%s', line %d, in %s: %s" % ( + pos[0], pos[1], method_name, self.dump_node(node))) + raise Errors.CompilerCrash( + last_node.pos, self.__class__.__name__, + u'\n'.join(trace), e, stacktrace) self.access_path.pop() return result @@ -142,8 +220,13 @@ was not, an exception will be raised. (Typically you want to ensure that you are within a StatListNode or similar before doing this.) """ + def __init__(self): + super(VisitorTransform, self).__init__() + self._super_visitchildren = super(VisitorTransform, self).visitchildren + def visitchildren(self, parent, attrs=None): - result = super(VisitorTransform, self).visitchildren(parent, attrs) + result = cython.declare(dict) + result = self._super_visitchildren(parent, attrs) for attr, newnode in result.iteritems(): if not isinstance(newnode, list): setattr(parent, attr, newnode) @@ -158,6 +241,10 @@ newlist.append(x) setattr(parent, attr, newlist) return result + + def recurse_to_children(self, node): + self.visitchildren(node) + return node def __call__(self, root): return self.visit(root) @@ -255,7 +342,15 @@ elif isinstance(node, ExprNodes.ExprNode): t = node.type result += "(type=%s)" % repr(t) - + elif node.pos: + pos = node.pos + path = pos[0].get_description() + if '/' in path: + path = path.split('/')[-1] + if '\\' in path: + path = path.split('\\')[-1] + result += "(pos=(%s:%s:%s))" % (path, pos[1], pos[2]) + return result if __name__ == "__main__": diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Distutils/build_ext.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Distutils/build_ext.py --- cython-0.10.3/Cython/Distutils/build_ext.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Distutils/build_ext.py 2009-05-20 16:37:46.000000000 +0100 @@ -7,7 +7,7 @@ __revision__ = "$Id:$" -import sys, os, string, re +import sys, os, re from types import * from distutils.core import Command from distutils.errors import * @@ -22,6 +22,7 @@ compile as cython_compile from Cython.Compiler.Errors import PyrexError except ImportError, e: + print "failed to import Cython: %s" % e PyrexError = None from distutils.command import build_ext as _build_ext @@ -71,7 +72,7 @@ self.pyrex_include_dirs = [] elif type(self.pyrex_include_dirs) is StringType: self.pyrex_include_dirs = \ - string.split(self.pyrex_include_dirs, os.pathsep) + self.pyrex_include_dirs.split(os.pathsep) # finalize_options () def build_extensions(self): @@ -105,17 +106,17 @@ # 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++') + # 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 + # 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) @@ -124,10 +125,10 @@ pyrex_gen_pxi = self.pyrex_gen_pxi or getattr(extension, 'pyrex_gen_pxi', 0) # Set up the include_path for the Cython compiler: - # 1. Start with the command line option. - # 2. Add in any (unique) paths from the extension - # pyrex_include_dirs (if Cython.Distutils.extension is used). - # 3. Add in any (unique) paths from the extension include_dirs + # 1. Start with the command line option. + # 2. Add in any (unique) paths from the extension + # pyrex_include_dirs (if Cython.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: @@ -161,7 +162,7 @@ if ext == ".py": # FIXME: we might want to special case this some more ext = '.pyx' - if ext == ".pyx": # Cython source file + if ext == ".pyx": # Cython source file output_dir = target_dir or os.path.dirname(source) new_sources.append(os.path.join(output_dir, base + target_ext)) pyrex_sources.append(source) diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Distutils/extension.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Distutils/extension.py --- cython-0.10.3/Cython/Distutils/extension.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Distutils/extension.py 2009-05-20 16:37:46.000000000 +0100 @@ -5,7 +5,7 @@ __revision__ = "$Id:$" -import os, string, sys +import os, sys from types import * import distutils.extension as _Extension diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Includes/numpy.pxd /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Includes/numpy.pxd --- cython-0.10.3/Cython/Includes/numpy.pxd 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Includes/numpy.pxd 2009-05-20 16:37:46.000000000 +0100 @@ -1,9 +1,22 @@ +# NumPy static imports for Cython +# +# This also defines backwards-compatability buffer acquisition +# code for use in Python 2.x (or Python <= 2.5 when NumPy starts +# implementing PEP-3118 directly). + + +# Because of laziness, the format string of the buffer is statically +# allocated. Increase the size if this is not enough, or submit a +# patch to do this properly. + +DEF _buffer_format_string_len = 255 + cimport python_buffer as pybuf cimport stdlib cdef extern from "Python.h": ctypedef int Py_intptr_t - + cdef extern from "numpy/arrayobject.h": ctypedef Py_intptr_t npy_intp @@ -29,6 +42,8 @@ ctypedef class numpy.dtype [object PyArray_Descr]: cdef int type_num + cdef int itemsize "elsize" + cdef char byteorder cdef object fields cdef object names @@ -53,6 +68,9 @@ # In particular strided access is always provided regardless # of flags cdef int copy_shape, i, ndim + cdef int endian_detector = 1 + cdef bint little_endian = ((&endian_detector)[0] != 0) + ndim = PyArray_NDIM(self) if sizeof(npy_intp) != sizeof(Py_ssize_t): @@ -89,17 +107,10 @@ cdef char* f = NULL cdef dtype descr = self.descr cdef list stack + cdef int offset cdef bint hasfields = PyDataType_HASFIELDS(descr) - # Ugly hack warning: - # Cython currently will not support helper functions in - # pxd files -- so we must keep our own, manual stack! - # In addition, avoid allocation of the stack in the common - # case that we are dealing with a single non-nested datatype... - # (this would look much prettier if we could use utility - # functions). - if not hasfields and not copy_shape: # do not call releasebuffer info.obj = None @@ -109,6 +120,9 @@ if not hasfields: t = descr.type_num + if ((descr.byteorder == '>' and little_endian) or + (descr.byteorder == '<' and not little_endian)): + raise ValueError("Non-native byte order not supported") if t == NPY_BYTE: f = "b" elif t == NPY_UBYTE: f = "B" elif t == NPY_SHORT: f = "h" @@ -131,59 +145,14 @@ info.format = f return else: - info.format = stdlib.malloc(255) # static size - f = info.format - stack = [iter(descr.fields.iteritems())] - - while True: - iterator = stack[-1] - descr = None - while descr is None: - try: - descr = iterator.next()[1][0] - except StopIteration: - stack.pop() - if len(stack) > 0: - f[0] = 125 #"}" - f += 1 - iterator = stack[-1] - else: - f[0] = 0 # Terminate string! - return - - hasfields = PyDataType_HASFIELDS(descr) - if not hasfields: - t = descr.type_num - if f - info.format > 240: # this should leave room for "T{" and "}" as well - raise RuntimeError("Format string allocated too short.") - - # Until ticket #99 is fixed, use integers to avoid warnings - if t == NPY_BYTE: f[0] = 98 #"b" - elif t == NPY_UBYTE: f[0] = 66 #"B" - elif t == NPY_SHORT: f[0] = 104 #"h" - elif t == NPY_USHORT: f[0] = 72 #"H" - elif t == NPY_INT: f[0] = 105 #"i" - elif t == NPY_UINT: f[0] = 73 #"I" - elif t == NPY_LONG: f[0] = 108 #"l" - elif t == NPY_ULONG: f[0] = 76 #"L" - elif t == NPY_LONGLONG: f[0] = 113 #"q" - elif t == NPY_ULONGLONG: f[0] = 81 #"Q" - elif t == NPY_FLOAT: f[0] = 102 #"f" - elif t == NPY_DOUBLE: f[0] = 100 #"d" - elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" - elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 - elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 - elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 - elif t == NPY_OBJECT: f[0] = 79 #"O" - else: - raise ValueError("unknown dtype code in numpy.pxd (%d)" % t) - f += 1 - else: - f[0] = 84 #"T" - f[1] = 123 #"{" - f += 2 - stack.append(iter(descr.fields.iteritems())) - + info.format = stdlib.malloc(_buffer_format_string_len) + info.format[0] = '^' # Native data types, manual alignment + offset = 0 + f = _util_dtypestring(descr, info.format + 1, + info.format + _buffer_format_string_len, + &offset) + f[0] = 0 # Terminate format string + def __releasebuffer__(ndarray self, Py_buffer* info): if PyArray_HASFIELDS(self): stdlib.free(info.format) @@ -204,53 +173,59 @@ cdef int PyDataType_HASFIELDS(dtype obj) - ctypedef signed int npy_byte - ctypedef signed int npy_short - ctypedef signed int npy_int - ctypedef signed int npy_long - ctypedef signed int npy_longlong - - ctypedef unsigned int npy_ubyte - ctypedef unsigned int npy_ushort - ctypedef unsigned int npy_uint - ctypedef unsigned int npy_ulong - ctypedef unsigned int npy_ulonglong + ctypedef signed char npy_byte + ctypedef signed short npy_short + ctypedef signed int npy_int + ctypedef signed long npy_long + ctypedef signed long long npy_longlong + + ctypedef unsigned char npy_ubyte + ctypedef unsigned short npy_ushort + ctypedef unsigned int npy_uint + ctypedef unsigned long npy_ulong + ctypedef unsigned long long npy_ulonglong ctypedef float npy_float - ctypedef float npy_double - ctypedef float npy_longdouble + ctypedef double npy_double + ctypedef long double npy_longdouble - ctypedef signed int npy_int8 - ctypedef signed int npy_int16 - ctypedef signed int npy_int32 - ctypedef signed int npy_int64 - ctypedef signed int npy_int96 - ctypedef signed int npy_int128 - - ctypedef unsigned int npy_uint8 - ctypedef unsigned int npy_uint16 - ctypedef unsigned int npy_uint32 - ctypedef unsigned int npy_uint64 - ctypedef unsigned int npy_uint96 - ctypedef unsigned int npy_uint128 + ctypedef signed char npy_int8 + ctypedef signed short npy_int16 + ctypedef signed int npy_int32 + ctypedef signed long long npy_int64 + ctypedef signed long long npy_int96 + ctypedef signed long long npy_int128 + + ctypedef unsigned char npy_uint8 + ctypedef unsigned short npy_uint16 + ctypedef unsigned int npy_uint32 + ctypedef unsigned long long npy_uint64 + ctypedef unsigned long long npy_uint96 + ctypedef unsigned long long npy_uint128 ctypedef float npy_float32 - ctypedef float npy_float64 - ctypedef float npy_float80 - ctypedef float npy_float96 - ctypedef float npy_float128 + ctypedef double npy_float64 + ctypedef long double npy_float80 + ctypedef long double npy_float96 + ctypedef long double npy_float128 + + ctypedef float complex npy_complex64 + ctypedef double complex npy_complex128 + ctypedef long double complex npy_complex120 + ctypedef long double complex npy_complex192 + ctypedef long double complex npy_complex256 ctypedef struct npy_cfloat: float real float imag ctypedef struct npy_cdouble: - double real - double imag + float real + float imag ctypedef struct npy_clongdouble: - long double real - long double imag + float real + float imag # Typedefs that matches the runtime dtype objects in # the numpy module. @@ -277,11 +252,15 @@ #ctypedef npy_float80 float80_t #ctypedef npy_float128 float128_t +ctypedef npy_complex64 complex64_t +ctypedef npy_complex128 complex128_t + # The int types are mapped a bit surprising -- # numpy.int corresponds to 'l' and numpy.long to 'q' ctypedef npy_long int_t ctypedef npy_longlong long_t + ctypedef npy_ulong uint_t ctypedef npy_ulonglong ulong_t @@ -292,3 +271,74 @@ ctypedef npy_cfloat cfloat_t ctypedef npy_cdouble cdouble_t ctypedef npy_clongdouble clongdouble_t + +ctypedef npy_cdouble complex_t + +cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL: + # Recursive utility function used in __getbuffer__ to get format + # string. The new location in the format string is returned. + + cdef dtype child + cdef int delta_offset + cdef tuple i + cdef int endian_detector = 1 + cdef bint little_endian = ((&endian_detector)[0] != 0) + + for i in descr.fields.itervalues(): + child = i[0] + new_offset = i[1] + + if (end - f) - (new_offset - offset[0]) < 15: + raise RuntimeError("Format string allocated too short, see comment in numpy.pxd") + + if ((child.byteorder == '>' and little_endian) or + (child.byteorder == '<' and not little_endian)): + raise ValueError("Non-native byte order not supported") + # One could encode it in the format string and have Cython + # complain instead, BUT: < and > in format strings also imply + # standardized sizes for datatypes, and we rely on native in + # order to avoid reencoding data types based on their size. + # + # A proper PEP 3118 exporter for other clients than Cython + # must deal properly with this! + + # Output padding bytes + while offset[0] < new_offset: + f[0] = 120 # "x"; pad byte + f += 1 + offset[0] += 1 + + offset[0] += child.itemsize + + if not PyDataType_HASFIELDS(child): + t = child.type_num + if end - f < 5: + raise RuntimeError("Format string allocated too short.") + + # Until ticket #99 is fixed, use integers to avoid warnings + if t == NPY_BYTE: f[0] = 98 #"b" + elif t == NPY_UBYTE: f[0] = 66 #"B" + elif t == NPY_SHORT: f[0] = 104 #"h" + elif t == NPY_USHORT: f[0] = 72 #"H" + elif t == NPY_INT: f[0] = 105 #"i" + elif t == NPY_UINT: f[0] = 73 #"I" + elif t == NPY_LONG: f[0] = 108 #"l" + elif t == NPY_ULONG: f[0] = 76 #"L" + elif t == NPY_LONGLONG: f[0] = 113 #"q" + elif t == NPY_ULONGLONG: f[0] = 81 #"Q" + elif t == NPY_FLOAT: f[0] = 102 #"f" + elif t == NPY_DOUBLE: f[0] = 100 #"d" + elif t == NPY_LONGDOUBLE: f[0] = 103 #"g" + elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1 # Zf + elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1 # Zd + elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg + elif t == NPY_OBJECT: f[0] = 79 #"O" + else: + raise ValueError("unknown dtype code in numpy.pxd (%d)" % t) + f += 1 + else: + # Cython ignores struct boundary information ("T{...}"), + # so don't output it + f = _util_dtypestring(child, f, end, offset) + return f + diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Includes/python2.5.pxd /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Includes/python2.5.pxd --- cython-0.10.3/Cython/Includes/python2.5.pxd 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Includes/python2.5.pxd 2009-05-20 16:37:46.000000000 +0100 @@ -1,625 +1,622 @@ -# From: Eric Huss -# -# Here is my latest copy. It does not cover 100% of the API. It should be -# current up to 2.5. -# -# -Eric - - - - -# XXX: -# - Need to support "long long" definitions that are different for different platforms. -# - Support unicode platform dependencies. -# - Add unicode calls. -# - Add setobject calls. - -cdef extern from "sys/types.h": - ctypedef unsigned int size_t - -cdef extern from "stdio.h": - ctypedef struct FILE: - pass - -cdef extern from "Python.h": - - # XXX: This is platform dependent. - ctypedef unsigned short Py_UNICODE - - ctypedef struct PyTypeObject: - pass - - ctypedef struct PyObject: - Py_ssize_t ob_refcnt - PyTypeObject * ob_type - - ############################################################################################### - # bool - ############################################################################################### - PyObject * Py_False - PyObject * Py_True - PyTypeObject PyBool_Type - int PyBool_Check (object) # Always succeeds. - object PyBool_FromLong (long) - - ############################################################################################### - # buffer - ############################################################################################### - PyTypeObject PyBuffer_Type - int Py_END_OF_BUFFER - int PyBuffer_Check (object) # Always succeeds. - object PyBuffer_FromMemory (void *, Py_ssize_t) - object PyBuffer_FromObject (object, Py_ssize_t, Py_ssize_t) - object PyBuffer_FromReadWriteMemory (void *, Py_ssize_t) - object PyBuffer_FromReadWriteObject (object, Py_ssize_t, Py_ssize_t) - object PyBuffer_New (Py_ssize_t) - int PyObject_AsCharBuffer (object, char **, Py_ssize_t *) except -1 - int PyObject_AsReadBuffer (object, void **, Py_ssize_t *) except -1 - int PyObject_AsWriteBuffer (object, void **, Py_ssize_t *) except -1 - int PyObject_CheckReadBuffer (object) # Always succeeds. - - ############################################################################################### - # cobject - ############################################################################################### - PyTypeObject PyCObject_Type - - int PyCObject_Check(object) # Always succeeds. - object PyCObject_FromVoidPtr(void *, void (*)(void*)) - object PyCObject_FromVoidPtrAndDesc(void *, void *, void (*)(void*,void*)) - void * PyCObject_AsVoidPtr(object) except NULL - void * PyCObject_GetDesc(object) except NULL - void * PyCObject_Import(char *, char *) except NULL - - ############################################################################################### - # compile - ############################################################################################### - - ctypedef struct PyCodeObject: - int co_argcount - int co_nlocals - int co_stacksize - int co_flags - PyObject *co_code - PyObject *co_consts - PyObject *co_names - PyObject *co_varnames - PyObject *co_freevars - PyObject *co_cellvars - PyObject *co_filename - PyObject *co_name - int co_firstlineno - PyObject *co_lnotab - - int PyCode_Addr2Line(PyCodeObject *, int) - - ############################################################################################### - # complex - ############################################################################################### - ctypedef struct Py_complex: - double real - double imag - - PyTypeObject PyComplex_Type - - Py_complex PyComplex_AsCComplex (object) # Always succeeds. - int PyComplex_Check (object) # Always succeeds. - int PyComplex_CheckExact (object) # Always succeeds. - object PyComplex_FromCComplex (Py_complex) - object PyComplex_FromDoubles (double, double) - double PyComplex_ImagAsDouble (object) except? -1 - double PyComplex_RealAsDouble (object) except? -1 - Py_complex _Py_c_diff (Py_complex, Py_complex) - Py_complex _Py_c_neg (Py_complex) - Py_complex _Py_c_pow (Py_complex, Py_complex) - Py_complex _Py_c_prod (Py_complex, Py_complex) - Py_complex _Py_c_quot (Py_complex, Py_complex) - Py_complex _Py_c_sum (Py_complex, Py_complex) - - ############################################################################################### - # dict - ############################################################################################### - PyTypeObject PyDict_Type - - int PyDict_Check (object) # Always succeeds. - int PyDict_CheckExact (object) # Always succeeds. - void PyDict_Clear (object) - int PyDict_Contains (object, object) except -1 - object PyDict_Copy (object) - int PyDict_DelItem (object, object) except -1 - int PyDict_DelItemString (object, char *) except -1 - object PyDict_Items (object) - object PyDict_Keys (object) - int PyDict_Merge (object, object, int) except -1 - int PyDict_MergeFromSeq2 (object, object, int) except -1 - object PyDict_New () - # XXX: Pyrex doesn't support pointer to a python object? - #int PyDict_Next (object, Py_ssize_t *, object *, object *) # Always succeeds. - int PyDict_SetItem (object, object, object) except -1 - int PyDict_SetItemString (object, char *, object) except -1 - Py_ssize_t PyDict_Size (object) except -1 - int PyDict_Update (object, object) except -1 - object PyDict_Values (object) - # XXX: Borrowed reference. No exception on NULL. - #object PyDict_GetItem (object, object) - # XXX: Borrowed reference. No exception on NULL - #object PyDict_GetItemString (object, char *) - - - ############################################################################################### - # float - ############################################################################################### - PyTypeObject PyFloat_Type - int _PyFloat_Pack4 (double, unsigned char *, int) except -1 - int _PyFloat_Pack8 (double, unsigned char *, int) except -1 - double _PyFloat_Unpack4 (unsigned char *, int) except? -1 - double _PyFloat_Unpack8 (unsigned char *, int) except? -1 - double PyFloat_AS_DOUBLE (object) - double PyFloat_AsDouble (object) except? -1 - void PyFloat_AsReprString (char*, object) - void PyFloat_AsString (char*, object) - int PyFloat_Check (object) # Always succeeds. - int PyFloat_CheckExact (object) # Always succeeds. - object PyFloat_FromDouble (double) - object PyFloat_FromString (object, char**) - - ############################################################################################### - # frame - ############################################################################################### - - ctypedef struct PyFrameObject: - PyFrameObject *f_back - PyCodeObject *f_code - PyObject *f_builtins - PyObject *f_globals - PyObject *f_locals - PyObject *f_trace - PyObject *f_exc_type - PyObject *f_exc_value - PyObject *f_exc_traceback - int f_lasti - int f_lineno - int f_restricted - int f_iblock - int f_nlocals - int f_ncells - int f_nfreevars - int f_stacksize - - ############################################################################################### - # int - ############################################################################################### - PyTypeObject PyInt_Type - long PyInt_AS_LONG (object) # Always succeeds. - long PyInt_AsLong (object) except? -1 - Py_ssize_t PyInt_AsSsize_t (object) except? -1 - unsigned long long PyInt_AsUnsignedLongLongMask (object) except? -1 - unsigned long PyInt_AsUnsignedLongMask (object) except? -1 - int PyInt_Check (object) # Always succeeds. - int PyInt_CheckExact (object) # Always succeeds. - object PyInt_FromLong (long) - object PyInt_FromSsize_t (Py_ssize_t) - object PyInt_FromString (char*, char**, int) - object PyInt_FromUnicode (Py_UNICODE*, Py_ssize_t, int) - long PyInt_GetMax () # Always succeeds. - - ############################################################################################### - # iterator - ############################################################################################### - int PyIter_Check (object) # Always succeeds. - object PyIter_Next (object) - - ############################################################################################### - # list - ############################################################################################### - PyTypeObject PyList_Type - int PyList_Append (object, object) except -1 - object PyList_AsTuple (object) - int PyList_Check (object) # Always succeeds. - int PyList_CheckExact (object) # Always succeeds. - int PyList_GET_SIZE (object) # Always suceeds. - object PyList_GetSlice (object, Py_ssize_t, Py_ssize_t) - int PyList_Insert (object, Py_ssize_t, object) except -1 - object PyList_New (Py_ssize_t) - int PyList_Reverse (object) except -1 - int PyList_SetSlice (object, Py_ssize_t, Py_ssize_t, object) except -1 - Py_ssize_t PyList_Size (object) except -1 - int PyList_Sort (object) except -1 - - ############################################################################################### - # long - ############################################################################################### - PyTypeObject PyLong_Type - int _PyLong_AsByteArray (object, unsigned char *, size_t, int, int) except -1 - object _PyLong_FromByteArray (unsigned char *, size_t, int, int) - size_t _PyLong_NumBits (object) except -1 - int _PyLong_Sign (object) # No error. - long PyLong_AsLong (object) except? -1 - long long PyLong_AsLongLong (object) except? -1 - unsigned long PyLong_AsUnsignedLong (object) except? -1 - unsigned long PyLong_AsUnsignedLongMask (object) except? -1 - unsigned long long PyLong_AsUnsignedLongLong (object) except? -1 - unsigned long long PyLong_AsUnsignedLongLongMask (object) except? -1 - int PyLong_Check (object) # Always succeeds. - int PyLong_CheckExact (object) # Always succeeds. - object PyLong_FromDouble (double) - object PyLong_FromLong (long) - object PyLong_FromLongLong (long long) - object PyLong_FromUnsignedLong (unsigned long) - object PyLong_FromUnsignedLongLong (unsigned long long) - double PyLong_AsDouble (object) except? -1 - object PyLong_FromVoidPtr (void *) - void * PyLong_AsVoidPtr (object) except NULL - object PyLong_FromString (char *, char **, int) - object PyLong_FromUnicode (Py_UNICODE*, Py_ssize_t, int) - - ############################################################################################### - # mapping - ############################################################################################### - int PyMapping_Check (object) # Always succeeds. - int PyMapping_DelItem (object, object) except -1 - int PyMapping_DelItemString (object, char *) except -1 - object PyMapping_GetItemString (object, char *) - int PyMapping_HasKey (object, object) # Always succeeds. - int PyMapping_HasKeyString (object, char *) # Always succeeds. - object PyMapping_Items (object) - object PyMapping_Keys (object) - Py_ssize_t PyMapping_Length (object) except -1 - int PyMapping_SetItemString (object, char *, object) except -1 - Py_ssize_t PyMapping_Size (object) except -1 - object PyMapping_Values (object) - - ############################################################################################### - # mem - ############################################################################################### - void PyMem_Free (void * p) - void * PyMem_Malloc (size_t n) - void * PyMem_Realloc (void *, size_t) - - ############################################################################################### - # modsupport - ############################################################################################### - object Py_BuildValue (char *, ...) - object Py_VaBuildValue (char *, va_list) - - ############################################################################################### - # number - ############################################################################################### - object PyNumber_Absolute (object) - object PyNumber_Add (object, object) - object PyNumber_And (object, object) - Py_ssize_t PyNumber_AsSsize_t (object, object) except? -1 - int PyNumber_Check (object) # Always succeeds. - # XXX: Pyrex doesn't support pointer to python object? - #int PyNumber_Coerce (object*, object*) except -1 - object PyNumber_Divide (object, object) - object PyNumber_Divmod (object, object) - object PyNumber_Float (object) - object PyNumber_FloorDivide (object, object) - object PyNumber_InPlaceAdd (object, object) - object PyNumber_InPlaceAnd (object, object) - object PyNumber_InPlaceDivide (object, object) - object PyNumber_InPlaceFloorDivide (object, object) - object PyNumber_InPlaceLshift (object, object) - object PyNumber_InPlaceMultiply (object, object) - object PyNumber_InPlaceOr (object, object) - object PyNumber_InPlacePower (object, object, object) - object PyNumber_InPlaceRemainder (object, object) - object PyNumber_InPlaceRshift (object, object) - object PyNumber_InPlaceSubtract (object, object) - object PyNumber_InPlaceTrueDivide (object, object) - object PyNumber_InPlaceXor (object, object) - object PyNumber_Int (object) - object PyNumber_Invert (object) - object PyNumber_Long (object) - object PyNumber_Lshift (object, object) - object PyNumber_Multiply (object, object) - object PyNumber_Negative (object) - object PyNumber_Or (object, object) - object PyNumber_Positive (object) - object PyNumber_Power (object, object, object) - object PyNumber_Remainder (object, object) - object PyNumber_Rshift (object, object) - object PyNumber_Subtract (object, object) - object PyNumber_TrueDivide (object, object) - object PyNumber_Xor (object, object) - - ############################################################################################### - # object - ############################################################################################### - int PyCallable_Check (object) # Always succeeds. - int PyObject_AsFileDescriptor (object) except -1 - object PyObject_Call (object, object, object) - object PyObject_CallFunction (object, char *, ...) - object PyObject_CallFunctionObjArgs (object, ...) - object PyObject_CallMethod (object, char *, char *, ...) - object PyObject_CallMethodObjArgs (object, object, ...) - object PyObject_CallObject (object, object) - int PyObject_Cmp (object, object, int *result) except -1 - # Use PyObject_Cmp instead. - #int PyObject_Compare (object, object) - int PyObject_DelAttr (object, object) except -1 - int PyObject_DelAttrString (object, char *) except -1 - int PyObject_DelItem (object, object) except -1 - int PyObject_DelItemString (object, char *) except -1 - object PyObject_Dir (object) - object PyObject_GetAttr (object, object) - object PyObject_GetAttrString (object, char *) - object PyObject_GetItem (object, object) - object PyObject_GetIter (object) - int PyObject_HasAttr (object, object) # Always succeeds. - int PyObject_HasAttrString (object, char *) # Always succeeds. - long PyObject_Hash (object) except -1 - int PyObject_IsInstance (object, object) except -1 - int PyObject_IsSubclass (object, object) except -1 - int PyObject_IsTrue (object) except -1 - Py_ssize_t PyObject_Length (object) except -1 - int PyObject_Not (object) except -1 - int PyObject_Print (object, FILE *, int) except -1 - object PyObject_Repr (object) - object PyObject_RichCompare (object, object, int) - int PyObject_RichCompareBool (object, object, int) except -1 - int PyObject_SetAttr (object, object, object) except -1 - int PyObject_SetAttrString (object, char *, object) except -1 - int PyObject_SetItem (object, object, object) except -1 - Py_ssize_t PyObject_Size (object) except -1 - object PyObject_Str (object) - object PyObject_Type (object) - int PyObject_TypeCheck (object, object) # Always succeeds. - object PyObject_Unicode (object) - - ############################################################################################### - # pyerrors - ############################################################################################### - int PyErr_BadArgument () - void PyErr_BadInternalCall () - int PyErr_CheckSignals () - void PyErr_Clear () - int PyErr_ExceptionMatches (object) - object PyErr_Format (object, char *, ...) - int PyErr_GivenExceptionMatches (object, object) - object PyErr_NoMemory () - object PyErr_Occurred () - void PyErr_Restore (object, object, object) - object PyErr_SetFromErrno (object) - object PyErr_SetFromErrnoWithFilename (object, char *) - object PyErr_SetFromErrnoWithFilenameObject (object, object) - void PyErr_SetInterrupt () - void PyErr_SetNone (object) - void PyErr_SetObject (object, object) - void PyErr_SetString (object, char *) - int PyErr_Warn (object, char *) - int PyErr_WarnExplicit (object, char *, char *, int, char *, object) - void PyErr_WriteUnraisable (object) - - ############################################################################################### - # pyeval - # Be extremely careful with these functions. - ############################################################################################### - - ctypedef struct PyThreadState: - PyFrameObject * frame - int recursion_depth - void * curexc_type, * curexc_value, * curexc_traceback - void * exc_type, * exc_value, * exc_traceback - - void PyEval_AcquireLock () - void PyEval_ReleaseLock () - void PyEval_AcquireThread (PyThreadState *) - void PyEval_ReleaseThread (PyThreadState *) - PyThreadState* PyEval_SaveThread () - void PyEval_RestoreThread (PyThreadState *) - - ############################################################################################### - # pystate - # Be extremely careful with these functions. Read PEP 311 for more detail. - ############################################################################################### - - ctypedef int PyGILState_STATE - PyGILState_STATE PyGILState_Ensure () - void PyGILState_Release (PyGILState_STATE) - - ctypedef struct PyInterpreterState: - pass - - PyThreadState* PyThreadState_New (PyInterpreterState *) - void PyThreadState_Clear (PyThreadState *) - void PyThreadState_Delete (PyThreadState *) - PyThreadState* PyThreadState_Get () - PyThreadState* PyThreadState_Swap (PyThreadState *tstate) - # XXX: Borrowed reference. - #object PyThreadState_GetDict () - - ############################################################################################### - # run - # Functions for embedded interpreters are not included. - ############################################################################################### - ctypedef struct PyCompilerFlags: - int cf_flags - - ctypedef struct _node: - pass - - ctypedef void (*PyOS_sighandler_t)(int) - - void PyErr_Display (object, object, object) - void PyErr_Print () - void PyErr_PrintEx (int) - char * PyOS_Readline (FILE *, FILE *, char *) - PyOS_sighandler_t PyOS_getsig (int) - PyOS_sighandler_t PyOS_setsig (int, PyOS_sighandler_t) - _node * PyParser_SimpleParseFile (FILE *, char *, int) except NULL - _node * PyParser_SimpleParseFileFlags (FILE *, char *, int, - int) except NULL - _node * PyParser_SimpleParseString (char *, int) except NULL - _node * PyParser_SimpleParseStringFlagsFilename(char *, char *, - int, int) except NULL - _node * PyParser_SimpleParseStringFlags (char *, int, int) except NULL - int PyRun_AnyFile (FILE *, char *) except -1 - int PyRun_AnyFileEx (FILE *, char *, int) except -1 - int PyRun_AnyFileExFlags (FILE *, char *, int, - PyCompilerFlags *) except -1 - int PyRun_AnyFileFlags (FILE *, char *, - PyCompilerFlags *) except -1 - object PyRun_File (FILE *, char *, int, - object, object) - object PyRun_FileEx (FILE *, char *, int, - object, object, int) - object PyRun_FileExFlags (FILE *, char *, int, - object, object, int, - PyCompilerFlags *) - object PyRun_FileFlags (FILE *, char *, int, - object, object, - PyCompilerFlags *) - int PyRun_InteractiveLoop (FILE *, char *) except -1 - int PyRun_InteractiveLoopFlags (FILE *, char *, - PyCompilerFlags *) except -1 - int PyRun_InteractiveOne (FILE *, char *) except -1 - int PyRun_InteractiveOneFlags (FILE *, char *, - PyCompilerFlags *) except -1 - int PyRun_SimpleFile (FILE *, char *) except -1 - int PyRun_SimpleFileEx (FILE *, char *, int) except -1 - int PyRun_SimpleFileExFlags (FILE *, char *, int, - PyCompilerFlags *) except -1 - int PyRun_SimpleString (char *) except -1 - int PyRun_SimpleStringFlags (char *, PyCompilerFlags *) except -1 - object PyRun_String (char *, int, object, - object) - object PyRun_StringFlags (char *, int, object, - object, PyCompilerFlags *) - int Py_AtExit (void (*func)()) - object Py_CompileString (char *, char *, int) - object Py_CompileStringFlags (char *, char *, int, PyCompilerFlags *) - void Py_Exit (int) - int Py_FdIsInteractive (FILE *, char *) # Always succeeds. - char * Py_GetBuildInfo () - char * Py_GetCompiler () - char * Py_GetCopyright () - char * Py_GetExecPrefix () - char * Py_GetPath () - char * Py_GetPlatform () - char * Py_GetPrefix () - char * Py_GetProgramFullPath () - char * Py_GetProgramName () - char * Py_GetPythonHome () - char * Py_GetVersion () - - ############################################################################################### - # sequence - ############################################################################################### - int PySequence_Check (object) # Always succeeds. - object PySequence_Concat (object, object) - int PySequence_Contains (object, object) except -1 - Py_ssize_t PySequence_Count (object, object) except -1 - int PySequence_DelItem (object, Py_ssize_t) except -1 - int PySequence_DelSlice (object, Py_ssize_t, Py_ssize_t) except -1 - object PySequence_Fast (object, char *) - int PySequence_Fast_GET_SIZE (object) - object PySequence_GetItem (object, Py_ssize_t) - object PySequence_GetSlice (object, Py_ssize_t, Py_ssize_t) - object PySequence_ITEM (object, int) - int PySequence_In (object, object) except -1 - object PySequence_InPlaceConcat (object, object) - object PySequence_InPlaceRepeat (object, Py_ssize_t) - Py_ssize_t PySequence_Index (object, object) except -1 - Py_ssize_t PySequence_Length (object) except -1 - object PySequence_List (object) - object PySequence_Repeat (object, Py_ssize_t) - int PySequence_SetItem (object, Py_ssize_t, object) except -1 - int PySequence_SetSlice (object, Py_ssize_t, Py_ssize_t, object) except -1 - Py_ssize_t PySequence_Size (object) except -1 - object PySequence_Tuple (object) - - ############################################################################################### - # string - ############################################################################################### - PyTypeObject PyString_Type - # Pyrex cannot support resizing because you have no choice but to use - # realloc which may call free() on the object, and there's no way to tell - # Pyrex to "forget" reference counting for the object. - #int _PyString_Resize (object *, Py_ssize_t) except -1 - char * PyString_AS_STRING (object) # Always succeeds. - object PyString_AsDecodedObject (object, char *, char *) - object PyString_AsEncodedObject (object, char *, char *) - object PyString_AsEncodedString (object, char *, char *) - char * PyString_AsString (object) except NULL - int PyString_AsStringAndSize (object, char **, Py_ssize_t *) except -1 - int PyString_Check (object) # Always succeeds. - int PyString_CHECK_INTERNED (object) # Always succeeds. - int PyString_CheckExact (object) # Always succeeds. - # XXX: Pyrex doesn't support pointer to a python object? - #void PyString_Concat (object *, object) - # XXX: Pyrex doesn't support pointer to a python object? - #void PyString_ConcatAndDel (object *, object) - object PyString_Decode (char *, int, char *, char *) - object PyString_DecodeEscape (char *, int, char *, int, char *) - object PyString_Encode (char *, int, char *, char *) - object PyString_Format (object, object) - object PyString_FromFormat (char*, ...) - object PyString_FromFormatV (char*, va_list) - object PyString_FromString (char *) - object PyString_FromStringAndSize (char *, Py_ssize_t) - Py_ssize_t PyString_GET_SIZE (object) # Always succeeds. - object PyString_InternFromString (char *) - # XXX: Pyrex doesn't support pointer to a python object? - #void PyString_InternImmortal (object*) - # XXX: Pyrex doesn't support pointer to a python object? - #void PyString_InternInPlace (object*) - object PyString_Repr (object, int) - Py_ssize_t PyString_Size (object) except -1 - - # Disgusting hack to access internal object values. - ctypedef struct PyStringObject: - int ob_refcnt - PyTypeObject * ob_type - int ob_size - long ob_shash - int ob_sstate - char * ob_sval - - ############################################################################################### - # tuple - ############################################################################################### - PyTypeObject PyTuple_Type - # See PyString_Resize note about resizing. - #int _PyTuple_Resize (object*, Py_ssize_t) except -1 - int PyTuple_Check (object) # Always succeeds. - int PyTuple_CheckExact (object) # Always succeeds. - Py_ssize_t PyTuple_GET_SIZE (object) # Always succeeds. - object PyTuple_GetSlice (object, Py_ssize_t, Py_ssize_t) - object PyTuple_New (Py_ssize_t) - object PyTuple_Pack (Py_ssize_t, ...) - Py_ssize_t PyTuple_Size (object) except -1 - - ############################################################################################### - # Dangerous things! - # Do not use these unless you really, really know what you are doing. - ############################################################################################### - void Py_INCREF (object) - void Py_XINCREF (object) - void Py_DECREF (object) - void Py_XDECREF (object) - void Py_CLEAR (object) - - # XXX: Stolen reference. - void PyTuple_SET_ITEM (object, Py_ssize_t, value) - # XXX: Borrowed reference. - object PyTuple_GET_ITEM (object, Py_ssize_t) - # XXX: Borrowed reference. - object PyTuple_GetItem (object, Py_ssize_t) - # XXX: Stolen reference. - int PyTuple_SetItem (object, Py_ssize_t, object) except -1 - - # XXX: Steals reference. - int PyList_SetItem (object, Py_ssize_t, object) except -1 - # XXX: Borrowed reference - object PyList_GetItem (object, Py_ssize_t) - # XXX: Borrowed reference, no NULL on error. - object PyList_GET_ITEM (object, Py_ssize_t) - # XXX: Stolen reference. - void PyList_SET_ITEM (object, Py_ssize_t, object) - - # XXX: Borrowed reference. - object PySequence_Fast_GET_ITEM (object, Py_ssize_t) - - # First parameter _must_ be a PyStringObject. - object _PyString_Join (object, object) +# From: Eric Huss +# +# Here is my latest copy. It does not cover 100% of the API. It should be +# current up to 2.5. +# +# -Eric + + + + +# XXX: +# - Need to support "long long" definitions that are different for different platforms. +# - Support unicode platform dependencies. +# - Add unicode calls. +# - Add setobject calls. + +cdef extern from "stdio.h": + ctypedef struct FILE: + pass + +cdef extern from "Python.h": + + # XXX: This is platform dependent. + ctypedef unsigned short Py_UNICODE + + ctypedef struct PyTypeObject: + pass + + ctypedef struct PyObject: + Py_ssize_t ob_refcnt + PyTypeObject * ob_type + + ############################################################################################### + # bool + ############################################################################################### + PyObject * Py_False + PyObject * Py_True + PyTypeObject PyBool_Type + int PyBool_Check (object) # Always succeeds. + object PyBool_FromLong (long) + + ############################################################################################### + # buffer + ############################################################################################### + PyTypeObject PyBuffer_Type + int Py_END_OF_BUFFER + int PyBuffer_Check (object) # Always succeeds. + object PyBuffer_FromMemory (void *, Py_ssize_t) + object PyBuffer_FromObject (object, Py_ssize_t, Py_ssize_t) + object PyBuffer_FromReadWriteMemory (void *, Py_ssize_t) + object PyBuffer_FromReadWriteObject (object, Py_ssize_t, Py_ssize_t) + object PyBuffer_New (Py_ssize_t) + int PyObject_AsCharBuffer (object, char **, Py_ssize_t *) except -1 + int PyObject_AsReadBuffer (object, void **, Py_ssize_t *) except -1 + int PyObject_AsWriteBuffer (object, void **, Py_ssize_t *) except -1 + int PyObject_CheckReadBuffer (object) # Always succeeds. + + ############################################################################################### + # cobject + ############################################################################################### + PyTypeObject PyCObject_Type + + int PyCObject_Check(object) # Always succeeds. + object PyCObject_FromVoidPtr(void *, void (*)(void*)) + object PyCObject_FromVoidPtrAndDesc(void *, void *, void (*)(void*,void*)) + void * PyCObject_AsVoidPtr(object) except NULL + void * PyCObject_GetDesc(object) except NULL + void * PyCObject_Import(char *, char *) except NULL + + ############################################################################################### + # compile + ############################################################################################### + + ctypedef struct PyCodeObject: + int co_argcount + int co_nlocals + int co_stacksize + int co_flags + PyObject *co_code + PyObject *co_consts + PyObject *co_names + PyObject *co_varnames + PyObject *co_freevars + PyObject *co_cellvars + PyObject *co_filename + PyObject *co_name + int co_firstlineno + PyObject *co_lnotab + + int PyCode_Addr2Line(PyCodeObject *, int) + + ############################################################################################### + # complex + ############################################################################################### + ctypedef struct Py_complex: + double real + double imag + + PyTypeObject PyComplex_Type + + Py_complex PyComplex_AsCComplex (object) # Always succeeds. + int PyComplex_Check (object) # Always succeeds. + int PyComplex_CheckExact (object) # Always succeeds. + object PyComplex_FromCComplex (Py_complex) + object PyComplex_FromDoubles (double, double) + double PyComplex_ImagAsDouble (object) except? -1 + double PyComplex_RealAsDouble (object) except? -1 + Py_complex _Py_c_diff (Py_complex, Py_complex) + Py_complex _Py_c_neg (Py_complex) + Py_complex _Py_c_pow (Py_complex, Py_complex) + Py_complex _Py_c_prod (Py_complex, Py_complex) + Py_complex _Py_c_quot (Py_complex, Py_complex) + Py_complex _Py_c_sum (Py_complex, Py_complex) + + ############################################################################################### + # dict + ############################################################################################### + PyTypeObject PyDict_Type + + int PyDict_Check (object) # Always succeeds. + int PyDict_CheckExact (object) # Always succeeds. + void PyDict_Clear (object) + int PyDict_Contains (object, object) except -1 + object PyDict_Copy (object) + int PyDict_DelItem (object, object) except -1 + int PyDict_DelItemString (object, char *) except -1 + object PyDict_Items (object) + object PyDict_Keys (object) + int PyDict_Merge (object, object, int) except -1 + int PyDict_MergeFromSeq2 (object, object, int) except -1 + object PyDict_New () + # XXX: Pyrex doesn't support pointer to a python object? + #int PyDict_Next (object, Py_ssize_t *, object *, object *) # Always succeeds. + int PyDict_SetItem (object, object, object) except -1 + int PyDict_SetItemString (object, char *, object) except -1 + Py_ssize_t PyDict_Size (object) except -1 + int PyDict_Update (object, object) except -1 + object PyDict_Values (object) + # XXX: Borrowed reference. No exception on NULL. + #object PyDict_GetItem (object, object) + # XXX: Borrowed reference. No exception on NULL + #object PyDict_GetItemString (object, char *) + + + ############################################################################################### + # float + ############################################################################################### + PyTypeObject PyFloat_Type + int _PyFloat_Pack4 (double, unsigned char *, int) except -1 + int _PyFloat_Pack8 (double, unsigned char *, int) except -1 + double _PyFloat_Unpack4 (unsigned char *, int) except? -1 + double _PyFloat_Unpack8 (unsigned char *, int) except? -1 + double PyFloat_AS_DOUBLE (object) + double PyFloat_AsDouble (object) except? -1 + void PyFloat_AsReprString (char*, object) + void PyFloat_AsString (char*, object) + int PyFloat_Check (object) # Always succeeds. + int PyFloat_CheckExact (object) # Always succeeds. + object PyFloat_FromDouble (double) + object PyFloat_FromString (object, char**) + + ############################################################################################### + # frame + ############################################################################################### + + ctypedef struct PyFrameObject: + PyFrameObject *f_back + PyCodeObject *f_code + PyObject *f_builtins + PyObject *f_globals + PyObject *f_locals + PyObject *f_trace + PyObject *f_exc_type + PyObject *f_exc_value + PyObject *f_exc_traceback + int f_lasti + int f_lineno + int f_restricted + int f_iblock + int f_nlocals + int f_ncells + int f_nfreevars + int f_stacksize + + ############################################################################################### + # int + ############################################################################################### + PyTypeObject PyInt_Type + long PyInt_AS_LONG (object) # Always succeeds. + long PyInt_AsLong (object) except? -1 + Py_ssize_t PyInt_AsSsize_t (object) except? -1 + unsigned long long PyInt_AsUnsignedLongLongMask (object) except? -1 + unsigned long PyInt_AsUnsignedLongMask (object) except? -1 + int PyInt_Check (object) # Always succeeds. + int PyInt_CheckExact (object) # Always succeeds. + object PyInt_FromLong (long) + object PyInt_FromSsize_t (Py_ssize_t) + object PyInt_FromString (char*, char**, int) + object PyInt_FromUnicode (Py_UNICODE*, Py_ssize_t, int) + long PyInt_GetMax () # Always succeeds. + + ############################################################################################### + # iterator + ############################################################################################### + int PyIter_Check (object) # Always succeeds. + object PyIter_Next (object) + + ############################################################################################### + # list + ############################################################################################### + PyTypeObject PyList_Type + int PyList_Append (object, object) except -1 + object PyList_AsTuple (object) + int PyList_Check (object) # Always succeeds. + int PyList_CheckExact (object) # Always succeeds. + int PyList_GET_SIZE (object) # Always suceeds. + object PyList_GetSlice (object, Py_ssize_t, Py_ssize_t) + int PyList_Insert (object, Py_ssize_t, object) except -1 + object PyList_New (Py_ssize_t) + int PyList_Reverse (object) except -1 + int PyList_SetSlice (object, Py_ssize_t, Py_ssize_t, object) except -1 + Py_ssize_t PyList_Size (object) except -1 + int PyList_Sort (object) except -1 + + ############################################################################################### + # long + ############################################################################################### + PyTypeObject PyLong_Type + int _PyLong_AsByteArray (object, unsigned char *, size_t, int, int) except -1 + object _PyLong_FromByteArray (unsigned char *, size_t, int, int) + size_t _PyLong_NumBits (object) except -1 + int _PyLong_Sign (object) # No error. + long PyLong_AsLong (object) except? -1 + long long PyLong_AsLongLong (object) except? -1 + unsigned long PyLong_AsUnsignedLong (object) except? -1 + unsigned long PyLong_AsUnsignedLongMask (object) except? -1 + unsigned long long PyLong_AsUnsignedLongLong (object) except? -1 + unsigned long long PyLong_AsUnsignedLongLongMask (object) except? -1 + int PyLong_Check (object) # Always succeeds. + int PyLong_CheckExact (object) # Always succeeds. + object PyLong_FromDouble (double) + object PyLong_FromLong (long) + object PyLong_FromLongLong (long long) + object PyLong_FromUnsignedLong (unsigned long) + object PyLong_FromUnsignedLongLong (unsigned long long) + double PyLong_AsDouble (object) except? -1 + object PyLong_FromVoidPtr (void *) + void * PyLong_AsVoidPtr (object) except NULL + object PyLong_FromString (char *, char **, int) + object PyLong_FromUnicode (Py_UNICODE*, Py_ssize_t, int) + + ############################################################################################### + # mapping + ############################################################################################### + int PyMapping_Check (object) # Always succeeds. + int PyMapping_DelItem (object, object) except -1 + int PyMapping_DelItemString (object, char *) except -1 + object PyMapping_GetItemString (object, char *) + int PyMapping_HasKey (object, object) # Always succeeds. + int PyMapping_HasKeyString (object, char *) # Always succeeds. + object PyMapping_Items (object) + object PyMapping_Keys (object) + Py_ssize_t PyMapping_Length (object) except -1 + int PyMapping_SetItemString (object, char *, object) except -1 + Py_ssize_t PyMapping_Size (object) except -1 + object PyMapping_Values (object) + + ############################################################################################### + # mem + ############################################################################################### + void PyMem_Free (void * p) + void * PyMem_Malloc (size_t n) + void * PyMem_Realloc (void *, size_t) + + ############################################################################################### + # modsupport + ############################################################################################### + object Py_BuildValue (char *, ...) + object Py_VaBuildValue (char *, va_list) + + ############################################################################################### + # number + ############################################################################################### + object PyNumber_Absolute (object) + object PyNumber_Add (object, object) + object PyNumber_And (object, object) + Py_ssize_t PyNumber_AsSsize_t (object, object) except? -1 + int PyNumber_Check (object) # Always succeeds. + # XXX: Pyrex doesn't support pointer to python object? + #int PyNumber_Coerce (object*, object*) except -1 + object PyNumber_Divide (object, object) + object PyNumber_Divmod (object, object) + object PyNumber_Float (object) + object PyNumber_FloorDivide (object, object) + object PyNumber_InPlaceAdd (object, object) + object PyNumber_InPlaceAnd (object, object) + object PyNumber_InPlaceDivide (object, object) + object PyNumber_InPlaceFloorDivide (object, object) + object PyNumber_InPlaceLshift (object, object) + object PyNumber_InPlaceMultiply (object, object) + object PyNumber_InPlaceOr (object, object) + object PyNumber_InPlacePower (object, object, object) + object PyNumber_InPlaceRemainder (object, object) + object PyNumber_InPlaceRshift (object, object) + object PyNumber_InPlaceSubtract (object, object) + object PyNumber_InPlaceTrueDivide (object, object) + object PyNumber_InPlaceXor (object, object) + object PyNumber_Int (object) + object PyNumber_Invert (object) + object PyNumber_Long (object) + object PyNumber_Lshift (object, object) + object PyNumber_Multiply (object, object) + object PyNumber_Negative (object) + object PyNumber_Or (object, object) + object PyNumber_Positive (object) + object PyNumber_Power (object, object, object) + object PyNumber_Remainder (object, object) + object PyNumber_Rshift (object, object) + object PyNumber_Subtract (object, object) + object PyNumber_TrueDivide (object, object) + object PyNumber_Xor (object, object) + + ############################################################################################### + # object + ############################################################################################### + int PyCallable_Check (object) # Always succeeds. + int PyObject_AsFileDescriptor (object) except -1 + object PyObject_Call (object, object, object) + object PyObject_CallFunction (object, char *, ...) + object PyObject_CallFunctionObjArgs (object, ...) + object PyObject_CallMethod (object, char *, char *, ...) + object PyObject_CallMethodObjArgs (object, object, ...) + object PyObject_CallObject (object, object) + int PyObject_Cmp (object, object, int *result) except -1 + # Use PyObject_Cmp instead. + #int PyObject_Compare (object, object) + int PyObject_DelAttr (object, object) except -1 + int PyObject_DelAttrString (object, char *) except -1 + int PyObject_DelItem (object, object) except -1 + int PyObject_DelItemString (object, char *) except -1 + object PyObject_Dir (object) + object PyObject_GetAttr (object, object) + object PyObject_GetAttrString (object, char *) + object PyObject_GetItem (object, object) + object PyObject_GetIter (object) + int PyObject_HasAttr (object, object) # Always succeeds. + int PyObject_HasAttrString (object, char *) # Always succeeds. + long PyObject_Hash (object) except -1 + int PyObject_IsInstance (object, object) except -1 + int PyObject_IsSubclass (object, object) except -1 + int PyObject_IsTrue (object) except -1 + Py_ssize_t PyObject_Length (object) except -1 + int PyObject_Not (object) except -1 + int PyObject_Print (object, FILE *, int) except -1 + object PyObject_Repr (object) + object PyObject_RichCompare (object, object, int) + int PyObject_RichCompareBool (object, object, int) except -1 + int PyObject_SetAttr (object, object, object) except -1 + int PyObject_SetAttrString (object, char *, object) except -1 + int PyObject_SetItem (object, object, object) except -1 + Py_ssize_t PyObject_Size (object) except -1 + object PyObject_Str (object) + object PyObject_Type (object) + int PyObject_TypeCheck (object, object) # Always succeeds. + object PyObject_Unicode (object) + + ############################################################################################### + # pyerrors + ############################################################################################### + int PyErr_BadArgument () + void PyErr_BadInternalCall () + int PyErr_CheckSignals () + void PyErr_Clear () + int PyErr_ExceptionMatches (object) + object PyErr_Format (object, char *, ...) + int PyErr_GivenExceptionMatches (object, object) + object PyErr_NoMemory () + object PyErr_Occurred () + void PyErr_Restore (object, object, object) + object PyErr_SetFromErrno (object) + object PyErr_SetFromErrnoWithFilename (object, char *) + object PyErr_SetFromErrnoWithFilenameObject (object, object) + void PyErr_SetInterrupt () + void PyErr_SetNone (object) + void PyErr_SetObject (object, object) + void PyErr_SetString (object, char *) + int PyErr_Warn (object, char *) + int PyErr_WarnExplicit (object, char *, char *, int, char *, object) + void PyErr_WriteUnraisable (object) + + ############################################################################################### + # pyeval + # Be extremely careful with these functions. + ############################################################################################### + + ctypedef struct PyThreadState: + PyFrameObject * frame + int recursion_depth + void * curexc_type, * curexc_value, * curexc_traceback + void * exc_type, * exc_value, * exc_traceback + + void PyEval_AcquireLock () + void PyEval_ReleaseLock () + void PyEval_AcquireThread (PyThreadState *) + void PyEval_ReleaseThread (PyThreadState *) + PyThreadState* PyEval_SaveThread () + void PyEval_RestoreThread (PyThreadState *) + + ############################################################################################### + # pystate + # Be extremely careful with these functions. Read PEP 311 for more detail. + ############################################################################################### + + ctypedef int PyGILState_STATE + PyGILState_STATE PyGILState_Ensure () + void PyGILState_Release (PyGILState_STATE) + + ctypedef struct PyInterpreterState: + pass + + PyThreadState* PyThreadState_New (PyInterpreterState *) + void PyThreadState_Clear (PyThreadState *) + void PyThreadState_Delete (PyThreadState *) + PyThreadState* PyThreadState_Get () + PyThreadState* PyThreadState_Swap (PyThreadState *tstate) + # XXX: Borrowed reference. + #object PyThreadState_GetDict () + + ############################################################################################### + # run + # Functions for embedded interpreters are not included. + ############################################################################################### + ctypedef struct PyCompilerFlags: + int cf_flags + + ctypedef struct _node: + pass + + ctypedef void (*PyOS_sighandler_t)(int) + + void PyErr_Display (object, object, object) + void PyErr_Print () + void PyErr_PrintEx (int) + char * PyOS_Readline (FILE *, FILE *, char *) + PyOS_sighandler_t PyOS_getsig (int) + PyOS_sighandler_t PyOS_setsig (int, PyOS_sighandler_t) + _node * PyParser_SimpleParseFile (FILE *, char *, int) except NULL + _node * PyParser_SimpleParseFileFlags (FILE *, char *, int, + int) except NULL + _node * PyParser_SimpleParseString (char *, int) except NULL + _node * PyParser_SimpleParseStringFlagsFilename(char *, char *, + int, int) except NULL + _node * PyParser_SimpleParseStringFlags (char *, int, int) except NULL + int PyRun_AnyFile (FILE *, char *) except -1 + int PyRun_AnyFileEx (FILE *, char *, int) except -1 + int PyRun_AnyFileExFlags (FILE *, char *, int, + PyCompilerFlags *) except -1 + int PyRun_AnyFileFlags (FILE *, char *, + PyCompilerFlags *) except -1 + object PyRun_File (FILE *, char *, int, + object, object) + object PyRun_FileEx (FILE *, char *, int, + object, object, int) + object PyRun_FileExFlags (FILE *, char *, int, + object, object, int, + PyCompilerFlags *) + object PyRun_FileFlags (FILE *, char *, int, + object, object, + PyCompilerFlags *) + int PyRun_InteractiveLoop (FILE *, char *) except -1 + int PyRun_InteractiveLoopFlags (FILE *, char *, + PyCompilerFlags *) except -1 + int PyRun_InteractiveOne (FILE *, char *) except -1 + int PyRun_InteractiveOneFlags (FILE *, char *, + PyCompilerFlags *) except -1 + int PyRun_SimpleFile (FILE *, char *) except -1 + int PyRun_SimpleFileEx (FILE *, char *, int) except -1 + int PyRun_SimpleFileExFlags (FILE *, char *, int, + PyCompilerFlags *) except -1 + int PyRun_SimpleString (char *) except -1 + int PyRun_SimpleStringFlags (char *, PyCompilerFlags *) except -1 + object PyRun_String (char *, int, object, + object) + object PyRun_StringFlags (char *, int, object, + object, PyCompilerFlags *) + int Py_AtExit (void (*func)()) + object Py_CompileString (char *, char *, int) + object Py_CompileStringFlags (char *, char *, int, PyCompilerFlags *) + void Py_Exit (int) + int Py_FdIsInteractive (FILE *, char *) # Always succeeds. + char * Py_GetBuildInfo () + char * Py_GetCompiler () + char * Py_GetCopyright () + char * Py_GetExecPrefix () + char * Py_GetPath () + char * Py_GetPlatform () + char * Py_GetPrefix () + char * Py_GetProgramFullPath () + char * Py_GetProgramName () + char * Py_GetPythonHome () + char * Py_GetVersion () + + ############################################################################################### + # sequence + ############################################################################################### + int PySequence_Check (object) # Always succeeds. + object PySequence_Concat (object, object) + int PySequence_Contains (object, object) except -1 + Py_ssize_t PySequence_Count (object, object) except -1 + int PySequence_DelItem (object, Py_ssize_t) except -1 + int PySequence_DelSlice (object, Py_ssize_t, Py_ssize_t) except -1 + object PySequence_Fast (object, char *) + int PySequence_Fast_GET_SIZE (object) + object PySequence_GetItem (object, Py_ssize_t) + object PySequence_GetSlice (object, Py_ssize_t, Py_ssize_t) + object PySequence_ITEM (object, int) + int PySequence_In (object, object) except -1 + object PySequence_InPlaceConcat (object, object) + object PySequence_InPlaceRepeat (object, Py_ssize_t) + Py_ssize_t PySequence_Index (object, object) except -1 + Py_ssize_t PySequence_Length (object) except -1 + object PySequence_List (object) + object PySequence_Repeat (object, Py_ssize_t) + int PySequence_SetItem (object, Py_ssize_t, object) except -1 + int PySequence_SetSlice (object, Py_ssize_t, Py_ssize_t, object) except -1 + Py_ssize_t PySequence_Size (object) except -1 + object PySequence_Tuple (object) + + ############################################################################################### + # string + ############################################################################################### + PyTypeObject PyString_Type + # Pyrex cannot support resizing because you have no choice but to use + # realloc which may call free() on the object, and there's no way to tell + # Pyrex to "forget" reference counting for the object. + #int _PyString_Resize (object *, Py_ssize_t) except -1 + char * PyString_AS_STRING (object) # Always succeeds. + object PyString_AsDecodedObject (object, char *, char *) + object PyString_AsEncodedObject (object, char *, char *) + object PyString_AsEncodedString (object, char *, char *) + char * PyString_AsString (object) except NULL + int PyString_AsStringAndSize (object, char **, Py_ssize_t *) except -1 + int PyString_Check (object) # Always succeeds. + int PyString_CHECK_INTERNED (object) # Always succeeds. + int PyString_CheckExact (object) # Always succeeds. + # XXX: Pyrex doesn't support pointer to a python object? + #void PyString_Concat (object *, object) + # XXX: Pyrex doesn't support pointer to a python object? + #void PyString_ConcatAndDel (object *, object) + object PyString_Decode (char *, int, char *, char *) + object PyString_DecodeEscape (char *, int, char *, int, char *) + object PyString_Encode (char *, int, char *, char *) + object PyString_Format (object, object) + object PyString_FromFormat (char*, ...) + object PyString_FromFormatV (char*, va_list) + object PyString_FromString (char *) + object PyString_FromStringAndSize (char *, Py_ssize_t) + Py_ssize_t PyString_GET_SIZE (object) # Always succeeds. + object PyString_InternFromString (char *) + # XXX: Pyrex doesn't support pointer to a python object? + #void PyString_InternImmortal (object*) + # XXX: Pyrex doesn't support pointer to a python object? + #void PyString_InternInPlace (object*) + object PyString_Repr (object, int) + Py_ssize_t PyString_Size (object) except -1 + + # Disgusting hack to access internal object values. + ctypedef struct PyStringObject: + int ob_refcnt + PyTypeObject * ob_type + int ob_size + long ob_shash + int ob_sstate + char * ob_sval + + ############################################################################################### + # tuple + ############################################################################################### + PyTypeObject PyTuple_Type + # See PyString_Resize note about resizing. + #int _PyTuple_Resize (object*, Py_ssize_t) except -1 + int PyTuple_Check (object) # Always succeeds. + int PyTuple_CheckExact (object) # Always succeeds. + Py_ssize_t PyTuple_GET_SIZE (object) # Always succeeds. + object PyTuple_GetSlice (object, Py_ssize_t, Py_ssize_t) + object PyTuple_New (Py_ssize_t) + object PyTuple_Pack (Py_ssize_t, ...) + Py_ssize_t PyTuple_Size (object) except -1 + + ############################################################################################### + # Dangerous things! + # Do not use these unless you really, really know what you are doing. + ############################################################################################### + void Py_INCREF (object) + void Py_XINCREF (object) + void Py_DECREF (object) + void Py_XDECREF (object) + void Py_CLEAR (object) + + # XXX: Stolen reference. + void PyTuple_SET_ITEM (object, Py_ssize_t, value) + # XXX: Borrowed reference. + object PyTuple_GET_ITEM (object, Py_ssize_t) + # XXX: Borrowed reference. + object PyTuple_GetItem (object, Py_ssize_t) + # XXX: Stolen reference. + int PyTuple_SetItem (object, Py_ssize_t, object) except -1 + + # XXX: Steals reference. + int PyList_SetItem (object, Py_ssize_t, object) except -1 + # XXX: Borrowed reference + object PyList_GetItem (object, Py_ssize_t) + # XXX: Borrowed reference, no NULL on error. + object PyList_GET_ITEM (object, Py_ssize_t) + # XXX: Stolen reference. + void PyList_SET_ITEM (object, Py_ssize_t, object) + + # XXX: Borrowed reference. + object PySequence_Fast_GET_ITEM (object, Py_ssize_t) + + # First parameter _must_ be a PyStringObject. + object _PyString_Join (object, object) diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Includes/python_mem.pxd /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Includes/python_mem.pxd --- cython-0.10.3/Cython/Includes/python_mem.pxd 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Includes/python_mem.pxd 2009-05-20 16:37:46.000000000 +0100 @@ -1,6 +1,5 @@ cdef extern from "Python.h": - ctypedef unsigned long size_t - + ##################################################################### # 9.2 Memory Interface ##################################################################### diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Includes/stdio.pxd /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Includes/stdio.pxd --- cython-0.10.3/Cython/Includes/stdio.pxd 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Includes/stdio.pxd 2009-05-20 16:37:46.000000000 +0100 @@ -1,4 +1,4 @@ -cdef extern from "stdio.h": +cdef extern from "stdio.h" nogil: ctypedef struct FILE int printf(char *format, ...) int fprintf(FILE *stream, char *format, ...) diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Includes/stdlib.pxd /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Includes/stdlib.pxd --- cython-0.10.3/Cython/Includes/stdlib.pxd 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Includes/stdlib.pxd 2009-05-20 16:37:46.000000000 +0100 @@ -1,6 +1,5 @@ -cdef extern from "stdlib.h": - ctypedef unsigned long size_t +cdef extern from "stdlib.h" nogil: void free(void *ptr) void *malloc(size_t size) void *realloc(void *ptr, size_t size) diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Mac/DarwinSystem.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Mac/DarwinSystem.py --- cython-0.10.3/Cython/Mac/DarwinSystem.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Mac/DarwinSystem.py 2009-05-20 16:37:46.000000000 +0100 @@ -51,8 +51,8 @@ "-Wl,-F.,-w -bundle -undefined dynamic_lookup" \ .split() #linker_options = \ -# "-Wl,-F.,-w -bundle -framework Python" \ -# .split() +# "-Wl,-F.,-w -bundle -framework Python" \ +# .split() class CCompilerError(PyrexError): pass diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Mac/MacSystem.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Mac/MacSystem.py --- cython-0.10.3/Cython/Mac/MacSystem.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Mac/MacSystem.py 2009-05-20 16:37:46.000000000 +0100 @@ -2,7 +2,7 @@ # Pyrex -- Mac system interface # -import os, sys, string +import os, sys import aetools from aetools import TalkTo from StdSuites.Standard_Suite import Standard_Suite_Events as Standard_Suite @@ -57,8 +57,8 @@ 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") + stdout = stdout.replace("\r", "\n") + stderr = stderr.replace("\r", "\n") if stdout: #print "<<< Begin ToolServer StdOut >>>" sys.stderr.write(stdout) @@ -85,7 +85,7 @@ command = "%s -opt %s -nomapcr -w off -r %s %s -o %s" % ( c_compiler, c_optimizations, - string.join(include_options), + ' '.join(include_options), c_file, o_file, #e_file @@ -106,9 +106,9 @@ 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), + ' '.join(obj_files), pythoncore, - string.join(libraries), + ' '.join(libraries), out_file) stat = do_toolserver_command(command) if stat: diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Mac/TS_Misc_Suite.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Mac/TS_Misc_Suite.py --- cython-0.10.3/Cython/Mac/TS_Misc_Suite.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Mac/TS_Misc_Suite.py 2009-05-20 16:37:46.000000000 +0100 @@ -10,7 +10,7 @@ _code = 'misc' -class TS_Misc_Suite: +class TS_Misc_Suite(object): 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. @@ -20,30 +20,30 @@ _code = 'misc' _subcode = 'dosc' - if _arguments: raise TypeError, 'No optional args expected' + 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) + # raise aetools.Error, aetools.decodeerror(_arguments) # XXXX Optionally decode result #if _arguments.has_key('----'): - # return _arguments['----'] + # return _arguments['----'] errn = 0 stat = 0 stdout = "" stderr = "" - if _arguments.has_key('errn'): + if 'errn' in _arguments: errn = _arguments['errn'] if errn: errn = aetools.decodeerror(_arguments) - if _arguments.has_key('stat'): + if 'stat' in _arguments: stat = _arguments['stat'] - if _arguments.has_key('----'): + if '----' in _arguments: stdout = _arguments['----'] - if _arguments.has_key('diag'): + if 'diag' in _arguments: stderr = _arguments['diag'] return (errn, stat, stdout, stderr) diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Plex/Actions.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Plex/Actions.py --- cython-0.10.3/Cython/Plex/Actions.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Plex/Actions.py 2009-05-20 16:37:46.000000000 +0100 @@ -6,7 +6,7 @@ # #======================================================================= -class Action: +class Action(object): def same_as(self, other): return self is other diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Plex/DFA.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Plex/DFA.py --- cython-0.10.3/Cython/Plex/DFA.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Plex/DFA.py 2009-05-20 16:37:46.000000000 +0100 @@ -29,18 +29,18 @@ # 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(): + for (key, old_state) in old_machine.initial_states.iteritems(): 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(): + for old_state in state_map.new_to_old(new_state): + for event, old_target_states in old_state.transitions.iteritems(): if event and old_target_states: transitions.add_set(event, set_epsilon_closure(old_target_states)) - for event, old_states in transitions.items(): + for event, old_states in transitions.iteritems(): new_machine.add_transitions(new_state, event, state_map.old_to_new(old_states)) if debug: debug.write("\n===== State Mapping =====\n") @@ -53,8 +53,8 @@ closures of its member states. """ result = {} - for state1 in state_set.keys(): - for state2 in epsilon_closure(state1).keys(): + for state1 in state_set: + for state2 in epsilon_closure(state1): result[state2] = 1 return result @@ -80,10 +80,10 @@ state_set[state] = 1 state_set_2 = state.transitions.get_epsilon() if state_set_2: - for state2 in state_set_2.keys(): + for state2 in state_set_2: add_to_epsilon_closure(state_set, state2) -class StateMap: +class StateMap(object): """ 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. @@ -119,19 +119,19 @@ def highest_priority_action(self, state_set): best_action = None best_priority = LOWEST_PRIORITY - for state in state_set.keys(): + for state in state_set: 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 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.""" @@ -142,7 +142,7 @@ Convert a set of states into a uniquified sorted tuple suitable for use as a dictionary key. """ - lst = state_set.keys() + lst = list(state_set) lst.sort() return tuple(lst) diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Plex/Lexicons.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Plex/Lexicons.py --- cython-0.10.3/Cython/Plex/Lexicons.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Plex/Lexicons.py 2009-05-20 16:37:46.000000000 +0100 @@ -18,7 +18,7 @@ DUMP_NFA = 1 DUMP_DFA = 2 -class State: +class State(object): """ This class is used as part of a Plex.Lexicon specification to introduce a user-defined state. @@ -35,7 +35,7 @@ self.name = name self.tokens = tokens -class Lexicon: +class Lexicon(object): """ Lexicon(specification) builds a lexical analyser from the given |specification|. The specification consists of a list of diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Plex/Machines.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Plex/Machines.py --- cython-0.10.3/Cython/Plex/Machines.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Plex/Machines.py 2009-05-20 16:37:46.000000000 +0100 @@ -6,7 +6,6 @@ # #======================================================================= -import string import sys from sys import maxint from types import TupleType @@ -15,7 +14,7 @@ LOWEST_PRIORITY = -sys.maxint -class Machine: +class Machine(object): """A collection of Nodes representing an NFA or DFA.""" states = None # [Node] next_state_number = 1 @@ -54,12 +53,12 @@ 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(): + for (name, state) in self.initial_states.iteritems(): file.write(" '%s': %d\n" % (name, state.number)) for s in self.states: s.dump(file) -class Node: +class Node(object): """A state of an NFA or DFA.""" transitions = None # TransitionMap action = None # Action @@ -101,13 +100,6 @@ 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 @@ -115,11 +107,10 @@ 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.dump_transitions(file) self.transitions.dump(file) # Action action = self.action @@ -128,7 +119,7 @@ file.write(" %s [priority %d]\n" % (action, priority)) -class FastMachine: +class FastMachine(object): """ FastMachine is a deterministic machine represented in a way that allows fast scanning. @@ -150,11 +141,11 @@ 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(): + for name, old_state in old_machine.initial_states.iteritems(): 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(): + for event, old_state_set in old_state.transitions.iteritems(): if old_state_set: new_state[event] = old_to_new[old_state_set.keys()[0]] else: @@ -195,13 +186,12 @@ def dump(self, file): file.write("Plex.FastMachine:\n") file.write(" Initial states:\n") - for name, state in self.initial_states.items(): + for name, state in self.initial_states.iteritems(): 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 @@ -214,7 +204,7 @@ def dump_transitions(self, state, file): chars_leading_to_state = {} special_to_state = {} - for (c, s) in state.items(): + for (c, s) in state.iteritems(): if len(c) == 1: chars = chars_leading_to_state.get(id(s), None) if chars is None: @@ -256,7 +246,7 @@ return tuple(result) def ranges_to_string(self, range_list): - return string.join(map(self.range_to_string, range_list), ",") + return ','.join(map(self.range_to_string, range_list)) def range_to_string(self, range_tuple): (c1, c2) = range_tuple @@ -264,64 +254,3 @@ 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 -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Plex/Regexps.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Plex/Regexps.py --- cython-0.10.3/Cython/Plex/Regexps.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Plex/Regexps.py 2009-05-20 16:37:46.000000000 +0100 @@ -1,20 +1,19 @@ #======================================================================= # -# Python Lexical Analyser +# Python Lexical Analyser # -# Regular Expressions +# Regular Expressions # #======================================================================= import array -import string import types from sys import maxint import Errors # -# Constants +# Constants # BOL = 'bol' @@ -24,7 +23,7 @@ nl_code = ord('\n') # -# Helper functions +# Helper functions # def chars_to_ranges(s): @@ -83,7 +82,7 @@ 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)) + return Alt(*re_list) def CodeRange(code1, code2): """ @@ -98,20 +97,20 @@ return RawCodeRange(code1, code2) # -# Abstract classes +# Abstract classes # -class RE: +class RE(object): """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| + 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 + 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): @@ -173,42 +172,42 @@ num, self.__class__.__name__, expected, got)) # -# Primitive RE constructors -# ------------------------- +# Primitive RE constructors +# ------------------------- # -# These are the basic REs from which all others are built. +# These are the basic REs from which all others are built. # ## class Char(RE): -## """ -## Char(c) is an RE which matches the character |c|. -## """ +## """ +## Char(c) is an RE which matches the character |c|. +## """ -## nullable = 0 +## nullable = 0 -## def __init__(self, char): -## self.char = char -## self.match_nl = char == '\n' +## 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 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 calc_str(self): +## return "Char(%s)" % repr(self.char) def Char(c): """ @@ -229,7 +228,7 @@ """ nullable = 0 match_nl = 0 - range = None # (code, code) + range = None # (code, code) uppercase_range = None # (code, code) or None lowercase_range = None # (code, code) or None @@ -330,7 +329,7 @@ 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), ",") + return "Seq(%s)" % ','.join(map(str, self.re_list)) class Alt(RE): @@ -369,7 +368,7 @@ re.build_machine(m, initial_state, final_state, 0, nocase) def calc_str(self): - return "Alt(%s)" % string.join(map(str, self.re_list), ",") + return "Alt(%s)" % ','.join(map(str, self.re_list)) class Rep1(RE): @@ -420,10 +419,10 @@ return "%s(%s)" % (name, self.re) # -# Composite RE constructors -# ------------------------- +# Composite RE constructors +# ------------------------- # -# These REs are defined in terms of the primitive REs. +# These REs are defined in terms of the primitive REs. # Empty = Seq() @@ -437,7 +436,7 @@ """ Str1(s) is an RE which matches the literal string |s|. """ - result = apply(Seq, tuple(map(Char, s))) + result = Seq(*tuple(map(Char, s))) result.str = "Str(%s)" % repr(s) return result @@ -449,8 +448,8 @@ 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), ",") + result = Alt(*tuple(map(Str1, strs))) + result.str = "Str(%s)" % ','.join(map(repr, strs)) return result def Any(s): @@ -495,7 +494,7 @@ 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 = Alt(*ranges) result.str = "Range(%s)" % repr(s1) return result @@ -531,7 +530,7 @@ return SwitchCase(re, nocase = 0) # -# RE Constants +# RE Constants # Bol = Char(BOL) diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Plex/Scanners.c /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Plex/Scanners.c --- cython-0.10.3/Cython/Plex/Scanners.c 2009-08-11 13:12:08.000000000 +0100 +++ cython-0.11.2/Cython/Plex/Scanners.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,4413 +0,0 @@ -/* Generated by Cython 0.10.3 on Sun Mar 1 18:21:15 2009 */ - -#define PY_SSIZE_T_CLEAN -#include "Python.h" -#include "structmember.h" -#ifndef PY_LONG_LONG - #define PY_LONG_LONG LONG_LONG -#endif -#ifndef DL_EXPORT - #define DL_EXPORT(t) t -#endif -#if PY_VERSION_HEX < 0x02040000 - #define METH_COEXIST 0 -#endif -#if PY_VERSION_HEX < 0x02050000 - typedef int Py_ssize_t; - #define PY_SSIZE_T_MAX INT_MAX - #define PY_SSIZE_T_MIN INT_MIN - #define PyInt_FromSsize_t(z) PyInt_FromLong(z) - #define PyInt_AsSsize_t(o) PyInt_AsLong(o) - #define PyNumber_Index(o) PyNumber_Int(o) - #define PyIndex_Check(o) PyNumber_Check(o) -#endif -#if PY_VERSION_HEX < 0x02060000 - #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt) - #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) - #define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size) - #define PyVarObject_HEAD_INIT(type, size) \ - PyObject_HEAD_INIT(type) size, - #define PyType_Modified(t) - - typedef struct { - void *buf; - PyObject *obj; - Py_ssize_t len; - Py_ssize_t itemsize; - int readonly; - int ndim; - char *format; - Py_ssize_t *shape; - Py_ssize_t *strides; - Py_ssize_t *suboffsets; - void *internal; - } Py_buffer; - - #define PyBUF_SIMPLE 0 - #define PyBUF_WRITABLE 0x0001 - #define PyBUF_LOCK 0x0002 - #define PyBUF_FORMAT 0x0004 - #define PyBUF_ND 0x0008 - #define PyBUF_STRIDES (0x0010 | PyBUF_ND) - #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES) - #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES) - #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES) - #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES) - -#endif -#if PY_MAJOR_VERSION < 3 - #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" -#else - #define __Pyx_BUILTIN_MODULE_NAME "builtins" -#endif -#if PY_MAJOR_VERSION >= 3 - #define Py_TPFLAGS_CHECKTYPES 0 - #define Py_TPFLAGS_HAVE_INDEX 0 -#endif -#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3) - #define Py_TPFLAGS_HAVE_NEWBUFFER 0 -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyBaseString_Type PyUnicode_Type - #define PyString_Type PyBytes_Type - #define PyInt_Type PyLong_Type - #define PyInt_Check(op) PyLong_Check(op) - #define PyInt_CheckExact(op) PyLong_CheckExact(op) - #define PyInt_FromString PyLong_FromString - #define PyInt_FromUnicode PyLong_FromUnicode - #define PyInt_FromLong PyLong_FromLong - #define PyInt_FromSize_t PyLong_FromSize_t - #define PyInt_FromSsize_t PyLong_FromSsize_t - #define PyInt_AsLong PyLong_AsLong - #define PyInt_AS_LONG PyLong_AS_LONG - #define PyInt_AsSsize_t PyLong_AsSsize_t - #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask - #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask - #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) -#else - #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) - #define PyBytes_Type PyString_Type -#endif -#if PY_MAJOR_VERSION >= 3 - #define PyMethod_New(func, self, klass) PyInstanceMethod_New(func) -#endif -#if !defined(WIN32) && !defined(MS_WINDOWS) - #ifndef __stdcall - #define __stdcall - #endif - #ifndef __cdecl - #define __cdecl - #endif -#else - #define _USE_MATH_DEFINES -#endif -#ifdef __cplusplus -#define __PYX_EXTERN_C extern "C" -#else -#define __PYX_EXTERN_C extern -#endif -#include -#define __PYX_HAVE_API__Cython__Plex__Scanners - - -#ifdef __GNUC__ -#define INLINE __inline__ -#elif _WIN32 -#define INLINE __inline -#else -#define INLINE -#endif - -typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/ - - - -static int __pyx_skip_dispatch = 0; - - -/* Type Conversion Predeclarations */ - -#if PY_MAJOR_VERSION < 3 -#define __Pyx_PyBytes_FromString PyString_FromString -#define __Pyx_PyBytes_AsString PyString_AsString -#else -#define __Pyx_PyBytes_FromString PyBytes_FromString -#define __Pyx_PyBytes_AsString PyBytes_AsString -#endif - -#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False)) -static INLINE int __Pyx_PyObject_IsTrue(PyObject* x); -static INLINE PY_LONG_LONG __pyx_PyInt_AsLongLong(PyObject* x); -static INLINE unsigned PY_LONG_LONG __pyx_PyInt_AsUnsignedLongLong(PyObject* x); -static INLINE Py_ssize_t __pyx_PyIndex_AsSsize_t(PyObject* b); - -#define __pyx_PyInt_AsLong(x) (PyInt_CheckExact(x) ? PyInt_AS_LONG(x) : PyInt_AsLong(x)) -#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) - -static INLINE unsigned char __pyx_PyInt_unsigned_char(PyObject* x); -static INLINE unsigned short __pyx_PyInt_unsigned_short(PyObject* x); -static INLINE char __pyx_PyInt_char(PyObject* x); -static INLINE short __pyx_PyInt_short(PyObject* x); -static INLINE int __pyx_PyInt_int(PyObject* x); -static INLINE long __pyx_PyInt_long(PyObject* x); -static INLINE signed char __pyx_PyInt_signed_char(PyObject* x); -static INLINE signed short __pyx_PyInt_signed_short(PyObject* x); -static INLINE signed int __pyx_PyInt_signed_int(PyObject* x); -static INLINE signed long __pyx_PyInt_signed_long(PyObject* x); -static INLINE long double __pyx_PyInt_long_double(PyObject* x); -#ifdef __GNUC__ -/* Test for GCC > 2.95 */ -#if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)) -#define likely(x) __builtin_expect(!!(x), 1) -#define unlikely(x) __builtin_expect(!!(x), 0) -#else /* __GNUC__ > 2 ... */ -#define likely(x) (x) -#define unlikely(x) (x) -#endif /* __GNUC__ > 2 ... */ -#else /* __GNUC__ */ -#define likely(x) (x) -#define unlikely(x) (x) -#endif /* __GNUC__ */ - -static PyObject *__pyx_m; -static PyObject *__pyx_b; -static PyObject *__pyx_empty_tuple; -static int __pyx_lineno; -static int __pyx_clineno = 0; -static const char * __pyx_cfilenm= __FILE__; -static const char *__pyx_filename; -static const char **__pyx_f; - -static void __Pyx_RaiseDoubleKeywordsError( - const char* func_name, PyObject* kw_name); /*proto*/ - -static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, - Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/ - -static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, const char* function_name); /*proto*/ - -static INLINE PyObject *__Pyx_GetItemInt(PyObject *o, Py_ssize_t i, int is_unsigned) { - PyObject *r; - if (PyList_CheckExact(o) && 0 <= i && i < PyList_GET_SIZE(o)) { - r = PyList_GET_ITEM(o, i); - Py_INCREF(r); - } - else if (PyTuple_CheckExact(o) && 0 <= i && i < PyTuple_GET_SIZE(o)) { - r = PyTuple_GET_ITEM(o, i); - Py_INCREF(r); - } - else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_item && (likely(i >= 0) || !is_unsigned)) - r = PySequence_GetItem(o, i); - else { - PyObject *j = (likely(i >= 0) || !is_unsigned) ? PyInt_FromLong(i) : PyLong_FromUnsignedLongLong((sizeof(unsigned long long) > sizeof(Py_ssize_t) ? (1ULL << (sizeof(Py_ssize_t)*8)) : 0) + i); - if (!j) - return 0; - r = PyObject_GetItem(o, j); - Py_DECREF(j); - } - return r; -} - -static INLINE int __Pyx_DelItemInt(PyObject *o, Py_ssize_t i, int is_unsigned) { - int r; - if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_ass_item && (likely(i >= 0) || !is_unsigned)) - r = PySequence_DelItem(o, i); - else { - PyObject *j = (likely(i >= 0) || !is_unsigned) ? PyInt_FromLong(i) : PyLong_FromUnsignedLongLong((sizeof(unsigned long long) > sizeof(Py_ssize_t) ? (1ULL << (sizeof(Py_ssize_t)*8)) : 0) + i); - if (!j) - return -1; - r = PyObject_DelItem(o, j); - Py_DECREF(j); - } - return r; -} - -static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/ - -static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, char *modname); /*proto*/ - -static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/ - -static PyObject *__Pyx_UnpackItem(PyObject *, Py_ssize_t index); /*proto*/ -static int __Pyx_EndUnpack(PyObject *); /*proto*/ - -static int __Pyx_Print(PyObject *, int); /*proto*/ -#if PY_MAJOR_VERSION >= 3 -static PyObject* __pyx_print = 0; -static PyObject* __pyx_print_kwargs = 0; -#endif - -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/ - -static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/ -static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/ - -static INLINE PyObject* __Pyx_PyObject_Append(PyObject* L, PyObject* x) { - if (likely(PyList_CheckExact(L))) { - if (PyList_Append(L, x) < 0) return NULL; - Py_INCREF(Py_None); - return Py_None; // this is just to have an accurate signature - } - else { - return PyObject_CallMethod(L, "append", "(O)", x); - } -} - -static void __Pyx_AddTraceback(const char *funcname); /*proto*/ - -static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/ - -/* Type declarations */ -/* Module declarations from Cython.Plex.Scanners */ - - - -/* Implementation of Cython.Plex.Scanners */ -static char __pyx_k_1[] = "\n A Scanner is used to read tokens from a stream of characters\n using the token set specified by a Plex.Lexicon.\n\n Constructor:\n\n Scanner(lexicon, stream, name = '')\n\n See the docstring of the __init__ method for details.\n\n Methods:\n\n See the docstrings of the individual methods for more\n information.\n\n read() --> (value, text)\n Reads the next lexical token from the stream.\n\n position() --> (name, line, col)\n Returns the position of the last token read using the\n read() method.\n \n begin(state_name)\n Causes scanner to change state.\n \n produce(value [, text])\n Causes return of a token value to the caller of the\n Scanner.\n\n "; -static char __pyx_k_2[] = ""; -static char __pyx_k_3[] = ""; -static char __pyx_k_4[] = ""; -static char __pyx_k_5[] = ""; -static PyObject *__pyx_int_0; -static PyObject *__pyx_int_1; -static PyObject *__pyx_int_neg_1; -static PyObject *__pyx_int_0x1000; -static PyObject *__pyx_int_2; -static PyObject *__pyx_int_4; -static PyObject *__pyx_int_3; -static PyObject *__pyx_int_5; -static PyObject *__pyx_int_20; -static char __pyx_k_self[] = "self"; -static PyObject *__pyx_kp_self; -static char __pyx_k_lexicon[] = "lexicon"; -static PyObject *__pyx_kp_lexicon; -static char __pyx_k_stream[] = "stream"; -static PyObject *__pyx_kp_stream; -static char __pyx_k_name[] = "name"; -static PyObject *__pyx_kp_name; -static char __pyx_k_initial_pos[] = "initial_pos"; -static PyObject *__pyx_kp_initial_pos; -static char __pyx_k_state_name[] = "state_name"; -static PyObject *__pyx_kp_state_name; -static char __pyx_k_value[] = "value"; -static PyObject *__pyx_kp_value; -static char __pyx_k_text[] = "text"; -static PyObject *__pyx_kp_text; -static char __pyx_k_Errors[] = "Errors"; -static PyObject *__pyx_kp_Errors; -static char __pyx_k_Regexps[] = "Regexps"; -static PyObject *__pyx_kp_Regexps; -static char __pyx_k_BOL[] = "BOL"; -static PyObject *__pyx_kp_BOL; -static char __pyx_k_EOL[] = "EOL"; -static PyObject *__pyx_kp_EOL; -static char __pyx_k_EOF[] = "EOF"; -static PyObject *__pyx_kp_EOF; -static char __pyx_k_Scanner[] = "Scanner"; -static PyObject *__pyx_kp_Scanner; -static char __pyx_k_buffer[] = "buffer"; -static PyObject *__pyx_kp_buffer; -static char __pyx_k_buf_start_pos[] = "buf_start_pos"; -static PyObject *__pyx_kp_buf_start_pos; -static char __pyx_k_next_pos[] = "next_pos"; -static PyObject *__pyx_kp_next_pos; -static char __pyx_k_cur_pos[] = "cur_pos"; -static PyObject *__pyx_kp_cur_pos; -static char __pyx_k_cur_line[] = "cur_line"; -static PyObject *__pyx_kp_cur_line; -static char __pyx_k_cur_line_start[] = "cur_line_start"; -static PyObject *__pyx_kp_cur_line_start; -static char __pyx_k_start_pos[] = "start_pos"; -static PyObject *__pyx_kp_start_pos; -static char __pyx_k_start_line[] = "start_line"; -static PyObject *__pyx_kp_start_line; -static char __pyx_k_start_col[] = "start_col"; -static PyObject *__pyx_kp_start_col; -static char __pyx_k_initial_state[] = "initial_state"; -static PyObject *__pyx_kp_initial_state; -static char __pyx_k_queue[] = "queue"; -static PyObject *__pyx_kp_queue; -static char __pyx_k_trace[] = "trace"; -static PyObject *__pyx_kp_trace; -static char __pyx_k___init__[] = "__init__"; -static PyObject *__pyx_kp___init__; -static char __pyx_k_read[] = "read"; -static PyObject *__pyx_kp_read; -static char __pyx_k_scan_a_token[] = "scan_a_token"; -static PyObject *__pyx_kp_scan_a_token; -static char __pyx_k_run_machine[] = "run_machine"; -static PyObject *__pyx_kp_run_machine; -static char __pyx_k_run_machine_inlined[] = "run_machine_inlined"; -static PyObject *__pyx_kp_run_machine_inlined; -static char __pyx_k_next_char[] = "next_char"; -static PyObject *__pyx_kp_next_char; -static char __pyx_k_position[] = "position"; -static PyObject *__pyx_kp_position; -static char __pyx_k_begin[] = "begin"; -static PyObject *__pyx_kp_begin; -static char __pyx_k_produce[] = "produce"; -static PyObject *__pyx_kp_produce; -static char __pyx_k_eof[] = "eof"; -static PyObject *__pyx_kp_eof; -static char __pyx_k_6[] = "yield"; -static PyObject *__pyx_kp_6; -static char __pyx_k_cur_char[] = "cur_char"; -static PyObject *__pyx_kp_cur_char; -static char __pyx_k_input_state[] = "input_state"; -static PyObject *__pyx_kp_input_state; -static char __pyx_k_perform[] = "perform"; -static PyObject *__pyx_kp_perform; -static char __pyx_k_UnrecognizedInput[] = "UnrecognizedInput"; -static PyObject *__pyx_kp_UnrecognizedInput; -static char __pyx_k_state[] = "state"; -static PyObject *__pyx_kp_state; -static char __pyx_k_backup_state[] = "backup_state"; -static PyObject *__pyx_kp_backup_state; -static char __pyx_k_transition[] = "transition"; -static PyObject *__pyx_kp_transition; -static char __pyx_k_back_up[] = "back_up"; -static PyObject *__pyx_kp_back_up; -static char __pyx_k_11[] = "number"; -static PyObject *__pyx_kp_11; -static char __pyx_k_12[] = "action"; -static PyObject *__pyx_kp_12; -static char __pyx_k_get[] = "get"; -static PyObject *__pyx_kp_get; -static char __pyx_k_13[] = "else"; -static PyObject *__pyx_kp_13; -static char __pyx_k_15[] = "number"; -static PyObject *__pyx_kp_15; -static char __pyx_k_20[] = "blocked"; -static PyObject *__pyx_kp_20; -static char __pyx_k_read_char[] = "read_char"; -static PyObject *__pyx_kp_read_char; -static char __pyx_k_get_initial_state[] = "get_initial_state"; -static PyObject *__pyx_kp_get_initial_state; -static char __pyx_k_append[] = "append"; -static PyObject *__pyx_kp_append; -static PyObject *__pyx_kp_1; -static PyObject *__pyx_kp_5; -static PyObject *__pyx_kp_2; -static PyObject *__pyx_kp_3; -static PyObject *__pyx_kp_4; -static PyObject *__pyx_kp_7; -static char __pyx_k_7[] = ""; -static PyObject *__pyx_kp_8; -static PyObject *__pyx_kp_9; -static char __pyx_k_8[] = "Scanner: read: Performing %s %d:%d"; -static char __pyx_k_9[] = ""; -static PyObject *__pyx_kp_10; -static PyObject *__pyx_kp_14; -static PyObject *__pyx_kp_16; -static PyObject *__pyx_kp_17; -static PyObject *__pyx_kp_18; -static PyObject *__pyx_kp_19; -static PyObject *__pyx_kp_21; -static char __pyx_k_10[] = "State %d, %d/%d:%s -->"; -static char __pyx_k_14[] = "State %d"; -static char __pyx_k_16[] = ""; -static char __pyx_k_17[] = "\n"; -static char __pyx_k_18[] = "\n"; -static char __pyx_k_19[] = ""; -static char __pyx_k_21[] = "Doing "; -static PyObject *__pyx_kp_23; -static PyObject *__pyx_kp_22; -static PyObject *__pyx_kp_24; -static PyObject *__pyx_kp_25; -static PyObject *__pyx_kp_26; -static PyObject *__pyx_kp_27; -static char __pyx_k_22[] = "Scanner: next: %s [%d] %d"; -static char __pyx_k_23[] = " "; -static char __pyx_k_24[] = "\n"; -static char __pyx_k_25[] = "\n"; -static char __pyx_k_26[] = ""; -static char __pyx_k_27[] = "--> [%d] %d %s"; - -/* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":63 - * trace = 0 - * - * def __init__(self, lexicon, stream, name = '', initial_pos = None): # <<<<<<<<<<<<<< - * """ - * Scanner(lexicon, stream, name = '') - */ - -static PyObject *__pyx_pf_6Cython_4Plex_8Scanners_7Scanner___init__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static char __pyx_doc_6Cython_4Plex_8Scanners_7Scanner___init__[] = "\n Scanner(lexicon, stream, name = '')\n\n |lexicon| is a Plex.Lexicon instance specifying the lexical tokens\n to be recognised.\n\n |stream| can be a file object or anything which implements a\n compatible read() method.\n\n |name| is optional, and may be the name of the file being\n scanned or any other identifying string.\n "; -static PyMethodDef __pyx_mdef_6Cython_4Plex_8Scanners_7Scanner___init__ = {"__init__", (PyCFunction)__pyx_pf_6Cython_4Plex_8Scanners_7Scanner___init__, METH_VARARGS|METH_KEYWORDS, __pyx_doc_6Cython_4Plex_8Scanners_7Scanner___init__}; -static PyObject *__pyx_pf_6Cython_4Plex_8Scanners_7Scanner___init__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_self = 0; - PyObject *__pyx_v_lexicon = 0; - PyObject *__pyx_v_stream = 0; - PyObject *__pyx_v_name = 0; - PyObject *__pyx_v_initial_pos = 0; - PyObject *__pyx_r; - PyObject *__pyx_1 = 0; - PyObject *__pyx_2 = 0; - PyObject *__pyx_3 = 0; - int __pyx_4; - static PyObject **__pyx_pyargnames[] = {&__pyx_kp_self,&__pyx_kp_lexicon,&__pyx_kp_stream,&__pyx_kp_name,&__pyx_kp_initial_pos,0}; - __pyx_self = __pyx_self; - __pyx_v_name = __pyx_kp_5; - __pyx_v_initial_pos = Py_None; - if (unlikely(__pyx_kwds)) { - PyObject* values[5] = {0,0,0,0,0}; - Py_ssize_t kw_args = PyDict_Size(__pyx_kwds); - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4); - case 4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3); - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 0: - values[0] = PyDict_GetItem(__pyx_kwds, __pyx_kp_self); - if (likely(values[0])) kw_args--; - else goto __pyx_L5_argtuple_error; - case 1: - values[1] = PyDict_GetItem(__pyx_kwds, __pyx_kp_lexicon); - if (likely(values[1])) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__init__", 0, 3, 5, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - } - case 2: - values[2] = PyDict_GetItem(__pyx_kwds, __pyx_kp_stream); - if (likely(values[2])) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("__init__", 0, 3, 5, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - } - __pyx_v_self = values[0]; - __pyx_v_lexicon = values[1]; - __pyx_v_stream = values[2]; - if (values[3]) { - __pyx_v_name = values[3]; - } - if (values[4]) { - __pyx_v_initial_pos = values[4]; - } - } else { - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 5: - __pyx_v_initial_pos = PyTuple_GET_ITEM(__pyx_args, 4); - case 4: - __pyx_v_name = PyTuple_GET_ITEM(__pyx_args, 3); - case 3: - __pyx_v_stream = PyTuple_GET_ITEM(__pyx_args, 2); - __pyx_v_lexicon = PyTuple_GET_ITEM(__pyx_args, 1); - __pyx_v_self = PyTuple_GET_ITEM(__pyx_args, 0); - break; - default: goto __pyx_L5_argtuple_error; - } - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("__init__", 0, 3, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - __pyx_L3_error:; - __Pyx_AddTraceback("Cython.Plex.Scanners.Scanner.__init__"); - return NULL; - __pyx_L4_argument_unpacking_done:; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":76 - * scanned or any other identifying string. - * """ - * self.lexicon = lexicon # <<<<<<<<<<<<<< - * self.stream = stream - * self.name = name - */ - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_lexicon, __pyx_v_lexicon) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":77 - * """ - * self.lexicon = lexicon - * self.stream = stream # <<<<<<<<<<<<<< - * self.name = name - * self.queue = [] - */ - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_stream, __pyx_v_stream) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":78 - * self.lexicon = lexicon - * self.stream = stream - * self.name = name # <<<<<<<<<<<<<< - * self.queue = [] - * self.initial_state = None - */ - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_name, __pyx_v_name) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":79 - * self.stream = stream - * self.name = name - * self.queue = [] # <<<<<<<<<<<<<< - * self.initial_state = None - * self.begin('') - */ - __pyx_1 = PyList_New(0); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_queue, ((PyObject *)__pyx_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 79; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":80 - * self.name = name - * self.queue = [] - * self.initial_state = None # <<<<<<<<<<<<<< - * self.begin('') - * self.next_pos = 0 - */ - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_initial_state, Py_None) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":81 - * self.queue = [] - * self.initial_state = None - * self.begin('') # <<<<<<<<<<<<<< - * self.next_pos = 0 - * self.cur_pos = 0 - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_begin); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_2 = PyTuple_New(1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_INCREF(__pyx_kp_7); - PyTuple_SET_ITEM(__pyx_2, 0, __pyx_kp_7); - __pyx_3 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_2), NULL); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 81; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0; - Py_DECREF(__pyx_3); __pyx_3 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":82 - * self.initial_state = None - * self.begin('') - * self.next_pos = 0 # <<<<<<<<<<<<<< - * self.cur_pos = 0 - * self.cur_line_start = 0 - */ - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_next_pos, __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 82; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":83 - * self.begin('') - * self.next_pos = 0 - * self.cur_pos = 0 # <<<<<<<<<<<<<< - * self.cur_line_start = 0 - * self.cur_char = BOL - */ - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_cur_pos, __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 83; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":84 - * self.next_pos = 0 - * self.cur_pos = 0 - * self.cur_line_start = 0 # <<<<<<<<<<<<<< - * self.cur_char = BOL - * self.input_state = 1 - */ - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_cur_line_start, __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 84; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":85 - * self.cur_pos = 0 - * self.cur_line_start = 0 - * self.cur_char = BOL # <<<<<<<<<<<<<< - * self.input_state = 1 - * if initial_pos is not None: - */ - __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_kp_BOL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_cur_char, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 85; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":86 - * self.cur_line_start = 0 - * self.cur_char = BOL - * self.input_state = 1 # <<<<<<<<<<<<<< - * if initial_pos is not None: - * self.cur_line, self.cur_line_start = initial_pos[1], -initial_pos[2] - */ - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_input_state, __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 86; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":87 - * self.cur_char = BOL - * self.input_state = 1 - * if initial_pos is not None: # <<<<<<<<<<<<<< - * self.cur_line, self.cur_line_start = initial_pos[1], -initial_pos[2] - * - */ - __pyx_4 = (__pyx_v_initial_pos != Py_None); - if (__pyx_4) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":88 - * self.input_state = 1 - * if initial_pos is not None: - * self.cur_line, self.cur_line_start = initial_pos[1], -initial_pos[2] # <<<<<<<<<<<<<< - * - * def read(self): - */ - __pyx_2 = __Pyx_GetItemInt(__pyx_v_initial_pos, 1, 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_3 = __Pyx_GetItemInt(__pyx_v_initial_pos, 2, 0); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_1 = PyNumber_Negative(__pyx_3); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_3); __pyx_3 = 0; - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_cur_line, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_2); __pyx_2 = 0; - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_cur_line_start, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - goto __pyx_L6; - } - __pyx_L6:; - - __pyx_r = Py_None; Py_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - Py_XDECREF(__pyx_1); - Py_XDECREF(__pyx_2); - Py_XDECREF(__pyx_3); - __Pyx_AddTraceback("Cython.Plex.Scanners.Scanner.__init__"); - __pyx_r = NULL; - __pyx_L0:; - return __pyx_r; -} - -/* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":90 - * self.cur_line, self.cur_line_start = initial_pos[1], -initial_pos[2] - * - * def read(self): # <<<<<<<<<<<<<< - * """ - * Read the next lexical token from the stream and return a - */ - -static PyObject *__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_read(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/ -static char __pyx_doc_6Cython_4Plex_8Scanners_7Scanner_read[] = "\n Read the next lexical token from the stream and return a\n tuple (value, text), where |value| is the value associated with\n the token as specified by the Lexicon, and |text| is the actual\n string read from the stream. Returns (None, '') on end of file.\n "; -static PyMethodDef __pyx_mdef_6Cython_4Plex_8Scanners_7Scanner_read = {"read", (PyCFunction)__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_read, METH_O, __pyx_doc_6Cython_4Plex_8Scanners_7Scanner_read}; -static PyObject *__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_read(PyObject *__pyx_self, PyObject *__pyx_v_self) { - PyObject *__pyx_v_queue; - PyObject *__pyx_v_action; - PyObject *__pyx_v_value; - PyObject *__pyx_v_result; - PyObject *__pyx_r; - PyObject *__pyx_1 = 0; - int __pyx_2; - int __pyx_3; - PyObject *__pyx_4 = 0; - PyObject *__pyx_5 = 0; - __pyx_self = __pyx_self; - __pyx_v_queue = Py_None; Py_INCREF(Py_None); - __pyx_v_action = Py_None; Py_INCREF(Py_None); - __pyx_v_value = Py_None; Py_INCREF(Py_None); - __pyx_v_result = Py_None; Py_INCREF(Py_None); - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":97 - * string read from the stream. Returns (None, '') on end of file. - * """ - * queue = self.queue # <<<<<<<<<<<<<< - * while not queue: - * self.text, action = self.scan_a_token() - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_queue); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_queue); - __pyx_v_queue = __pyx_1; - __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":98 - * """ - * queue = self.queue - * while not queue: # <<<<<<<<<<<<<< - * self.text, action = self.scan_a_token() - * if action is None: - */ - while (1) { - __pyx_2 = __Pyx_PyObject_IsTrue(__pyx_v_queue); if (unlikely(__pyx_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 98; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_3 = (!__pyx_2); - if (!__pyx_3) break; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":99 - * queue = self.queue - * while not queue: - * self.text, action = self.scan_a_token() # <<<<<<<<<<<<<< - * if action is None: - * self.produce(None) - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_scan_a_token); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_4 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - if (PyTuple_CheckExact(__pyx_4) && PyTuple_GET_SIZE(__pyx_4) == 2) { - PyObject* tuple = __pyx_4; - __pyx_5 = PyTuple_GET_ITEM(tuple, 0); - Py_INCREF(__pyx_5); - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_text, __pyx_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_5); __pyx_5 = 0; - __pyx_5 = PyTuple_GET_ITEM(tuple, 1); - Py_INCREF(__pyx_5); - Py_DECREF(__pyx_v_action); - __pyx_v_action = __pyx_5; - __pyx_5 = 0; - Py_DECREF(__pyx_4); __pyx_4 = 0; - } - else { - __pyx_1 = PyObject_GetIter(__pyx_4); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_4); __pyx_4 = 0; - __pyx_5 = __Pyx_UnpackItem(__pyx_1, 0); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_text, __pyx_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_5); __pyx_5 = 0; - __pyx_5 = __Pyx_UnpackItem(__pyx_1, 1); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_action); - __pyx_v_action = __pyx_5; - __pyx_5 = 0; - if (__Pyx_EndUnpack(__pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 99; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - } - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":100 - * while not queue: - * self.text, action = self.scan_a_token() - * if action is None: # <<<<<<<<<<<<<< - * self.produce(None) - * self.eof() - */ - __pyx_2 = (__pyx_v_action == Py_None); - if (__pyx_2) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":101 - * self.text, action = self.scan_a_token() - * if action is None: - * self.produce(None) # <<<<<<<<<<<<<< - * self.eof() - * else: - */ - __pyx_5 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_produce); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_4 = PyTuple_New(1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_INCREF(Py_None); - PyTuple_SET_ITEM(__pyx_4, 0, Py_None); - __pyx_1 = PyObject_Call(__pyx_5, ((PyObject *)__pyx_4), NULL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_5); __pyx_5 = 0; - Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0; - Py_DECREF(__pyx_1); __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":102 - * if action is None: - * self.produce(None) - * self.eof() # <<<<<<<<<<<<<< - * else: - * value = action.perform(self, self.text) - */ - __pyx_5 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_eof); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_4 = PyObject_Call(__pyx_5, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_5); __pyx_5 = 0; - Py_DECREF(__pyx_4); __pyx_4 = 0; - goto __pyx_L7; - } - /*else*/ { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":104 - * self.eof() - * else: - * value = action.perform(self, self.text) # <<<<<<<<<<<<<< - * if value is not None: - * self.produce(value) - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_action, __pyx_kp_perform); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_5 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_text); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_4 = PyTuple_New(2); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_INCREF(__pyx_v_self); - PyTuple_SET_ITEM(__pyx_4, 0, __pyx_v_self); - PyTuple_SET_ITEM(__pyx_4, 1, __pyx_5); - __pyx_5 = 0; - __pyx_5 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_4), NULL); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0; - Py_DECREF(__pyx_v_value); - __pyx_v_value = __pyx_5; - __pyx_5 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":105 - * else: - * value = action.perform(self, self.text) - * if value is not None: # <<<<<<<<<<<<<< - * self.produce(value) - * result = queue[0] - */ - __pyx_3 = (__pyx_v_value != Py_None); - if (__pyx_3) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":106 - * value = action.perform(self, self.text) - * if value is not None: - * self.produce(value) # <<<<<<<<<<<<<< - * result = queue[0] - * del queue[0] - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_produce); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_4 = PyTuple_New(1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_INCREF(__pyx_v_value); - PyTuple_SET_ITEM(__pyx_4, 0, __pyx_v_value); - __pyx_5 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_4), NULL); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0; - Py_DECREF(__pyx_5); __pyx_5 = 0; - goto __pyx_L8; - } - __pyx_L8:; - } - __pyx_L7:; - } - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":107 - * if value is not None: - * self.produce(value) - * result = queue[0] # <<<<<<<<<<<<<< - * del queue[0] - * return result - */ - __pyx_1 = __Pyx_GetItemInt(__pyx_v_queue, 0, 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 107; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_result); - __pyx_v_result = __pyx_1; - __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":108 - * self.produce(value) - * result = queue[0] - * del queue[0] # <<<<<<<<<<<<<< - * return result - * - */ - if (__Pyx_DelItemInt(__pyx_v_queue, 0, 0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":109 - * result = queue[0] - * del queue[0] - * return result # <<<<<<<<<<<<<< - * - * def scan_a_token(self): - */ - Py_INCREF(__pyx_v_result); - __pyx_r = __pyx_v_result; - goto __pyx_L0; - - __pyx_r = Py_None; Py_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - Py_XDECREF(__pyx_1); - Py_XDECREF(__pyx_4); - Py_XDECREF(__pyx_5); - __Pyx_AddTraceback("Cython.Plex.Scanners.Scanner.read"); - __pyx_r = NULL; - __pyx_L0:; - Py_DECREF(__pyx_v_queue); - Py_DECREF(__pyx_v_action); - Py_DECREF(__pyx_v_value); - Py_DECREF(__pyx_v_result); - return __pyx_r; -} - -/* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":111 - * return result - * - * def scan_a_token(self): # <<<<<<<<<<<<<< - * """ - * Read the next input sequence recognised by the machine - */ - -static PyObject *__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_scan_a_token(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/ -static char __pyx_doc_6Cython_4Plex_8Scanners_7Scanner_scan_a_token[] = "\n Read the next input sequence recognised by the machine\n and return (text, action). Returns ('', None) on end of\n file.\n "; -static PyMethodDef __pyx_mdef_6Cython_4Plex_8Scanners_7Scanner_scan_a_token = {"scan_a_token", (PyCFunction)__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_scan_a_token, METH_O, __pyx_doc_6Cython_4Plex_8Scanners_7Scanner_scan_a_token}; -static PyObject *__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_scan_a_token(PyObject *__pyx_self, PyObject *__pyx_v_self) { - PyObject *__pyx_v_action; - PyObject *__pyx_v_base; - PyObject *__pyx_v_text; - PyObject *__pyx_r; - PyObject *__pyx_1 = 0; - PyObject *__pyx_2 = 0; - int __pyx_3; - PyObject *__pyx_4 = 0; - Py_ssize_t __pyx_5 = 0; - Py_ssize_t __pyx_6 = 0; - int __pyx_7; - PyObject *__pyx_t_1 = NULL; - __pyx_self = __pyx_self; - __pyx_v_action = Py_None; Py_INCREF(Py_None); - __pyx_v_base = Py_None; Py_INCREF(Py_None); - __pyx_v_text = Py_None; Py_INCREF(Py_None); - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":117 - * file. - * """ - * self.start_pos = self.cur_pos # <<<<<<<<<<<<<< - * self.start_line = self.cur_line - * self.start_col = self.cur_pos - self.cur_line_start - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_cur_pos); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_start_pos, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":118 - * """ - * 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: - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_cur_line); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_start_line, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":119 - * 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() - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_cur_pos); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_cur_line_start); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_t_1 = PyNumber_Subtract(__pyx_1, __pyx_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - Py_DECREF(__pyx_2); __pyx_2 = 0; - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_start_col, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":124 - * # else: - * # action = self.run_machine_inlined() - * action = self.run_machine_inlined() # <<<<<<<<<<<<<< - * if action: - * if self.trace: - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_run_machine_inlined); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_2 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - Py_DECREF(__pyx_v_action); - __pyx_v_action = __pyx_2; - __pyx_2 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":125 - * # action = self.run_machine_inlined() - * action = self.run_machine_inlined() - * if action: # <<<<<<<<<<<<<< - * if self.trace: - * print("Scanner: read: Performing %s %d:%d" % ( - */ - __pyx_3 = __Pyx_PyObject_IsTrue(__pyx_v_action); if (unlikely(__pyx_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 125; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (__pyx_3) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":126 - * action = self.run_machine_inlined() - * if action: - * if self.trace: # <<<<<<<<<<<<<< - * print("Scanner: read: Performing %s %d:%d" % ( - * action, self.start_pos, self.cur_pos)) - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_trace); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 126; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_3 = __Pyx_PyObject_IsTrue(__pyx_1); if (unlikely(__pyx_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 126; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - if (__pyx_3) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":128 - * if self.trace: - * print("Scanner: read: Performing %s %d:%d" % ( - * action, self.start_pos, self.cur_pos)) # <<<<<<<<<<<<<< - * base = self.buf_start_pos - * text = self.buffer[self.start_pos - base : self.cur_pos - base] - */ - __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_start_pos); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_cur_pos); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_4 = PyTuple_New(3); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 128; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_INCREF(__pyx_v_action); - PyTuple_SET_ITEM(__pyx_4, 0, __pyx_v_action); - PyTuple_SET_ITEM(__pyx_4, 1, __pyx_2); - PyTuple_SET_ITEM(__pyx_4, 2, __pyx_1); - __pyx_2 = 0; - __pyx_1 = 0; - __pyx_t_1 = PyNumber_Remainder(__pyx_kp_8, ((PyObject *)__pyx_4)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0; - __pyx_2 = PyTuple_New(1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - PyTuple_SET_ITEM(__pyx_2, 0, __pyx_t_1); - __pyx_t_1 = 0; - if (__Pyx_Print(((PyObject *)__pyx_2), 1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 127; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0; - goto __pyx_L6; - } - __pyx_L6:; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":129 - * print("Scanner: read: Performing %s %d:%d" % ( - * action, 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) - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_buf_start_pos); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_base); - __pyx_v_base = __pyx_1; - __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":130 - * action, 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: - */ - __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_buffer); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_start_pos); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_t_1 = PyNumber_Subtract(__pyx_2, __pyx_v_base); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_2); __pyx_2 = 0; - __pyx_5 = __pyx_PyIndex_AsSsize_t(__pyx_t_1); if (unlikely((__pyx_5 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_cur_pos); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_t_1 = PyNumber_Subtract(__pyx_1, __pyx_v_base); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - __pyx_6 = __pyx_PyIndex_AsSsize_t(__pyx_t_1); if (unlikely((__pyx_6 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_2 = PySequence_GetSlice(__pyx_4, __pyx_5, __pyx_6); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_4); __pyx_4 = 0; - Py_DECREF(__pyx_v_text); - __pyx_v_text = __pyx_2; - __pyx_2 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":131 - * 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: - */ - __pyx_1 = PyTuple_New(2); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 131; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_INCREF(__pyx_v_text); - PyTuple_SET_ITEM(__pyx_1, 0, __pyx_v_text); - Py_INCREF(__pyx_v_action); - PyTuple_SET_ITEM(__pyx_1, 1, __pyx_v_action); - __pyx_r = ((PyObject *)__pyx_1); - __pyx_1 = 0; - goto __pyx_L0; - goto __pyx_L5; - } - /*else*/ { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":133 - * return (text, action) - * else: - * if self.cur_pos == self.start_pos: # <<<<<<<<<<<<<< - * if self.cur_char == EOL: - * self.next_char() - */ - __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_cur_pos); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_start_pos); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_1 = PyObject_RichCompare(__pyx_4, __pyx_2, Py_EQ); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_4); __pyx_4 = 0; - Py_DECREF(__pyx_2); __pyx_2 = 0; - __pyx_3 = __Pyx_PyObject_IsTrue(__pyx_1); if (unlikely(__pyx_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 133; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - if (__pyx_3) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":134 - * 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: - */ - __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_cur_char); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_kp_EOL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_1 = PyObject_RichCompare(__pyx_4, __pyx_2, Py_EQ); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_4); __pyx_4 = 0; - Py_DECREF(__pyx_2); __pyx_2 = 0; - __pyx_3 = __Pyx_PyObject_IsTrue(__pyx_1); if (unlikely(__pyx_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - if (__pyx_3) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":135 - * 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) - */ - __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_next_char); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_2 = PyObject_Call(__pyx_4, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_4); __pyx_4 = 0; - Py_DECREF(__pyx_2); __pyx_2 = 0; - goto __pyx_L8; - } - __pyx_L8:; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":136 - * 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) - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_cur_char); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_7 = __Pyx_PyObject_IsTrue(__pyx_1); if (unlikely(__pyx_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - __pyx_3 = (!__pyx_7); - if (!__pyx_3) { - __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_cur_char); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_kp_EOF); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_1 = PyObject_RichCompare(__pyx_4, __pyx_2, Py_EQ); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_4); __pyx_4 = 0; - Py_DECREF(__pyx_2); __pyx_2 = 0; - __pyx_3 = __Pyx_PyObject_IsTrue(__pyx_1); if (unlikely(__pyx_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - } - if (__pyx_3) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":137 - * self.next_char() - * if not self.cur_char or self.cur_char == EOF: - * return ('', None) # <<<<<<<<<<<<<< - * raise Errors.UnrecognizedInput(self, self.state_name) - * - */ - __pyx_4 = PyTuple_New(2); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 137; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_INCREF(__pyx_kp_9); - PyTuple_SET_ITEM(__pyx_4, 0, __pyx_kp_9); - Py_INCREF(Py_None); - PyTuple_SET_ITEM(__pyx_4, 1, Py_None); - __pyx_r = ((PyObject *)__pyx_4); - __pyx_4 = 0; - goto __pyx_L0; - goto __pyx_L9; - } - __pyx_L9:; - goto __pyx_L7; - } - __pyx_L7:; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":138 - * if not self.cur_char or self.cur_char == EOF: - * return ('', None) - * raise Errors.UnrecognizedInput(self, self.state_name) # <<<<<<<<<<<<<< - * - * def run_machine(self): - */ - __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_kp_Errors); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_UnrecognizedInput); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_2); __pyx_2 = 0; - __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_state_name); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_2 = PyTuple_New(2); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_INCREF(__pyx_v_self); - PyTuple_SET_ITEM(__pyx_2, 0, __pyx_v_self); - PyTuple_SET_ITEM(__pyx_2, 1, __pyx_4); - __pyx_4 = 0; - __pyx_4 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_2), NULL); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0; - __Pyx_Raise(__pyx_4, 0, 0); - Py_DECREF(__pyx_4); __pyx_4 = 0; - {__pyx_filename = __pyx_f[0]; __pyx_lineno = 138; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - } - __pyx_L5:; - - __pyx_r = Py_None; Py_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - Py_XDECREF(__pyx_1); - Py_XDECREF(__pyx_2); - Py_XDECREF(__pyx_4); - __Pyx_AddTraceback("Cython.Plex.Scanners.Scanner.scan_a_token"); - __pyx_r = NULL; - __pyx_L0:; - Py_DECREF(__pyx_v_action); - Py_DECREF(__pyx_v_base); - Py_DECREF(__pyx_v_text); - return __pyx_r; -} - -/* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":140 - * raise Errors.UnrecognizedInput(self, self.state_name) - * - * def run_machine(self): # <<<<<<<<<<<<<< - * """ - * Run the machine until no more transitions are possible. - */ - -static PyObject *__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_run_machine(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/ -static char __pyx_doc_6Cython_4Plex_8Scanners_7Scanner_run_machine[] = "\n Run the machine until no more transitions are possible.\n "; -static PyMethodDef __pyx_mdef_6Cython_4Plex_8Scanners_7Scanner_run_machine = {"run_machine", (PyCFunction)__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_run_machine, METH_O, __pyx_doc_6Cython_4Plex_8Scanners_7Scanner_run_machine}; -static PyObject *__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_run_machine(PyObject *__pyx_self, PyObject *__pyx_v_self) { - PyObject *__pyx_r; - PyObject *__pyx_1 = 0; - PyObject *__pyx_2 = 0; - int __pyx_3; - __pyx_self = __pyx_self; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":144 - * Run the machine until no more transitions are possible. - * """ - * self.state = self.initial_state # <<<<<<<<<<<<<< - * self.backup_state = None - * while self.transition(): - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_initial_state); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_state, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":145 - * """ - * self.state = self.initial_state - * self.backup_state = None # <<<<<<<<<<<<<< - * while self.transition(): - * pass - */ - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_backup_state, Py_None) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":146 - * self.state = self.initial_state - * self.backup_state = None - * while self.transition(): # <<<<<<<<<<<<<< - * pass - * return self.back_up() - */ - while (1) { - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_transition); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 146; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_2 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 146; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - __pyx_3 = __Pyx_PyObject_IsTrue(__pyx_2); if (unlikely(__pyx_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 146; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_2); __pyx_2 = 0; - if (!__pyx_3) break; - } - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":148 - * while self.transition(): - * pass - * return self.back_up() # <<<<<<<<<<<<<< - * - * def run_machine_inlined(self): - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_back_up); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_2 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - __pyx_r = __pyx_2; - __pyx_2 = 0; - goto __pyx_L0; - - __pyx_r = Py_None; Py_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - Py_XDECREF(__pyx_1); - Py_XDECREF(__pyx_2); - __Pyx_AddTraceback("Cython.Plex.Scanners.Scanner.run_machine"); - __pyx_r = NULL; - __pyx_L0:; - return __pyx_r; -} - -/* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":150 - * return self.back_up() - * - * def run_machine_inlined(self): # <<<<<<<<<<<<<< - * """ - * Inlined version of run_machine for speed. - */ - -static PyObject *__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_run_machine_inlined(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/ -static char __pyx_doc_6Cython_4Plex_8Scanners_7Scanner_run_machine_inlined[] = "\n Inlined version of run_machine for speed.\n "; -static PyMethodDef __pyx_mdef_6Cython_4Plex_8Scanners_7Scanner_run_machine_inlined = {"run_machine_inlined", (PyCFunction)__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_run_machine_inlined, METH_O, __pyx_doc_6Cython_4Plex_8Scanners_7Scanner_run_machine_inlined}; -static PyObject *__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_run_machine_inlined(PyObject *__pyx_self, PyObject *__pyx_v_self) { - PyObject *__pyx_v_state; - PyObject *__pyx_v_cur_pos; - PyObject *__pyx_v_cur_line; - PyObject *__pyx_v_cur_line_start; - PyObject *__pyx_v_cur_char; - PyObject *__pyx_v_input_state; - PyObject *__pyx_v_next_pos; - PyObject *__pyx_v_buffer; - PyObject *__pyx_v_buf_start_pos; - PyObject *__pyx_v_buf_len; - PyObject *__pyx_v_backup_state; - PyObject *__pyx_v_trace; - PyObject *__pyx_v_action; - PyObject *__pyx_v_c; - PyObject *__pyx_v_new_state; - PyObject *__pyx_v_buf_index; - PyObject *__pyx_v_discard; - PyObject *__pyx_v_data; - PyObject *__pyx_r; - PyObject *__pyx_1 = 0; - Py_ssize_t __pyx_2 = 0; - int __pyx_3; - PyObject *__pyx_4 = 0; - PyObject *__pyx_5 = 0; - int __pyx_6; - PyObject *__pyx_t_1 = NULL; - __pyx_self = __pyx_self; - __pyx_v_state = Py_None; Py_INCREF(Py_None); - __pyx_v_cur_pos = Py_None; Py_INCREF(Py_None); - __pyx_v_cur_line = Py_None; Py_INCREF(Py_None); - __pyx_v_cur_line_start = Py_None; Py_INCREF(Py_None); - __pyx_v_cur_char = Py_None; Py_INCREF(Py_None); - __pyx_v_input_state = Py_None; Py_INCREF(Py_None); - __pyx_v_next_pos = Py_None; Py_INCREF(Py_None); - __pyx_v_buffer = Py_None; Py_INCREF(Py_None); - __pyx_v_buf_start_pos = Py_None; Py_INCREF(Py_None); - __pyx_v_buf_len = Py_None; Py_INCREF(Py_None); - __pyx_v_backup_state = Py_None; Py_INCREF(Py_None); - __pyx_v_trace = Py_None; Py_INCREF(Py_None); - __pyx_v_action = Py_None; Py_INCREF(Py_None); - __pyx_v_c = Py_None; Py_INCREF(Py_None); - __pyx_v_new_state = Py_None; Py_INCREF(Py_None); - __pyx_v_buf_index = Py_None; Py_INCREF(Py_None); - __pyx_v_discard = Py_None; Py_INCREF(Py_None); - __pyx_v_data = Py_None; Py_INCREF(Py_None); - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":154 - * Inlined version of run_machine for speed. - * """ - * state = self.initial_state # <<<<<<<<<<<<<< - * cur_pos = self.cur_pos - * cur_line = self.cur_line - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_initial_state); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_state); - __pyx_v_state = __pyx_1; - __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":155 - * """ - * state = self.initial_state - * cur_pos = self.cur_pos # <<<<<<<<<<<<<< - * cur_line = self.cur_line - * cur_line_start = self.cur_line_start - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_cur_pos); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_cur_pos); - __pyx_v_cur_pos = __pyx_1; - __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":156 - * 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 - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_cur_line); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 156; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_cur_line); - __pyx_v_cur_line = __pyx_1; - __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":157 - * 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 - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_cur_line_start); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_cur_line_start); - __pyx_v_cur_line_start = __pyx_1; - __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":158 - * 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 - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_cur_char); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_cur_char); - __pyx_v_cur_char = __pyx_1; - __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":159 - * 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 - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_input_state); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 159; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_input_state); - __pyx_v_input_state = __pyx_1; - __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":160 - * 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 - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_next_pos); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_next_pos); - __pyx_v_next_pos = __pyx_1; - __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":161 - * input_state = self.input_state - * next_pos = self.next_pos - * buffer = self.buffer # <<<<<<<<<<<<<< - * buf_start_pos = self.buf_start_pos - * buf_len = len(buffer) - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_buffer); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_buffer); - __pyx_v_buffer = __pyx_1; - __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":162 - * next_pos = self.next_pos - * buffer = self.buffer - * buf_start_pos = self.buf_start_pos # <<<<<<<<<<<<<< - * buf_len = len(buffer) - * backup_state = None - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_buf_start_pos); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_buf_start_pos); - __pyx_v_buf_start_pos = __pyx_1; - __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":163 - * buffer = self.buffer - * buf_start_pos = self.buf_start_pos - * buf_len = len(buffer) # <<<<<<<<<<<<<< - * backup_state = None - * trace = self.trace - */ - __pyx_2 = PyObject_Length(__pyx_v_buffer); if (unlikely(__pyx_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_1 = PyInt_FromSsize_t(__pyx_2); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_buf_len); - __pyx_v_buf_len = __pyx_1; - __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":164 - * buf_start_pos = self.buf_start_pos - * buf_len = len(buffer) - * backup_state = None # <<<<<<<<<<<<<< - * trace = self.trace - * while 1: - */ - Py_INCREF(Py_None); - Py_DECREF(__pyx_v_backup_state); - __pyx_v_backup_state = Py_None; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":165 - * buf_len = len(buffer) - * backup_state = None - * trace = self.trace # <<<<<<<<<<<<<< - * while 1: - * if trace: #TRACE# - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_trace); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_trace); - __pyx_v_trace = __pyx_1; - __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":166 - * backup_state = None - * trace = self.trace - * while 1: # <<<<<<<<<<<<<< - * if trace: #TRACE# - * print("State %d, %d/%d:%s -->" % ( #TRACE# - */ - while (1) { - __pyx_3 = 1; - if (!__pyx_3) break; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":167 - * 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# - */ - __pyx_3 = __Pyx_PyObject_IsTrue(__pyx_v_trace); if (unlikely(__pyx_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 167; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (__pyx_3) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":169 - * 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 - */ - __pyx_1 = PyObject_GetItem(__pyx_v_state, __pyx_kp_11); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_4 = PyObject_Repr(__pyx_v_cur_char); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_5 = PyTuple_New(4); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - PyTuple_SET_ITEM(__pyx_5, 0, __pyx_1); - Py_INCREF(__pyx_v_input_state); - PyTuple_SET_ITEM(__pyx_5, 1, __pyx_v_input_state); - Py_INCREF(__pyx_v_cur_pos); - PyTuple_SET_ITEM(__pyx_5, 2, __pyx_v_cur_pos); - PyTuple_SET_ITEM(__pyx_5, 3, __pyx_4); - __pyx_1 = 0; - __pyx_4 = 0; - __pyx_t_1 = PyNumber_Remainder(__pyx_kp_10, ((PyObject *)__pyx_5)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(((PyObject *)__pyx_5)); __pyx_5 = 0; - __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - PyTuple_SET_ITEM(__pyx_1, 0, __pyx_t_1); - __pyx_t_1 = 0; - if (__Pyx_Print(((PyObject *)__pyx_1), 1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0; - goto __pyx_L7; - } - __pyx_L7:; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":172 - * # Begin inlined self.save_for_backup() - * #action = state.action #@slow - * action = state['action'] #@fast # <<<<<<<<<<<<<< - * if action: - * backup_state = ( - */ - __pyx_4 = PyObject_GetItem(__pyx_v_state, __pyx_kp_12); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_action); - __pyx_v_action = __pyx_4; - __pyx_4 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":173 - * #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) - */ - __pyx_3 = __Pyx_PyObject_IsTrue(__pyx_v_action); if (unlikely(__pyx_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (__pyx_3) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":175 - * 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 - */ - __pyx_5 = PyTuple_New(7); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_INCREF(__pyx_v_action); - PyTuple_SET_ITEM(__pyx_5, 0, __pyx_v_action); - Py_INCREF(__pyx_v_cur_pos); - PyTuple_SET_ITEM(__pyx_5, 1, __pyx_v_cur_pos); - Py_INCREF(__pyx_v_cur_line); - PyTuple_SET_ITEM(__pyx_5, 2, __pyx_v_cur_line); - Py_INCREF(__pyx_v_cur_line_start); - PyTuple_SET_ITEM(__pyx_5, 3, __pyx_v_cur_line_start); - Py_INCREF(__pyx_v_cur_char); - PyTuple_SET_ITEM(__pyx_5, 4, __pyx_v_cur_char); - Py_INCREF(__pyx_v_input_state); - PyTuple_SET_ITEM(__pyx_5, 5, __pyx_v_input_state); - Py_INCREF(__pyx_v_next_pos); - PyTuple_SET_ITEM(__pyx_5, 6, __pyx_v_next_pos); - Py_DECREF(__pyx_v_backup_state); - __pyx_v_backup_state = ((PyObject *)__pyx_5); - __pyx_5 = 0; - goto __pyx_L8; - } - __pyx_L8:; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":177 - * 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 - */ - Py_INCREF(__pyx_v_cur_char); - Py_DECREF(__pyx_v_c); - __pyx_v_c = __pyx_v_cur_char; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":179 - * 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 - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_state, __pyx_kp_get); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_4 = PyTuple_New(2); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_INCREF(__pyx_v_c); - PyTuple_SET_ITEM(__pyx_4, 0, __pyx_v_c); - Py_INCREF(__pyx_int_neg_1); - PyTuple_SET_ITEM(__pyx_4, 1, __pyx_int_neg_1); - __pyx_5 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_4), NULL); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0; - Py_DECREF(__pyx_v_new_state); - __pyx_v_new_state = __pyx_5; - __pyx_5 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":180 - * #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: - */ - __pyx_1 = PyObject_RichCompare(__pyx_v_new_state, __pyx_int_neg_1, Py_EQ); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_3 = __Pyx_PyObject_IsTrue(__pyx_1); if (unlikely(__pyx_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - if (__pyx_3) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":181 - * 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# - */ - __pyx_4 = __pyx_v_c; - Py_INCREF(__pyx_4); - __pyx_3 = __Pyx_PyObject_IsTrue(__pyx_4); if (unlikely(__pyx_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (__pyx_3) { - Py_DECREF(__pyx_4); __pyx_4 = 0; - __pyx_5 = PyObject_GetAttr(__pyx_v_state, __pyx_kp_get); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_INCREF(__pyx_kp_13); - PyTuple_SET_ITEM(__pyx_1, 0, __pyx_kp_13); - __pyx_4 = PyObject_Call(__pyx_5, ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_5); __pyx_5 = 0; - Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0; - } - Py_DECREF(__pyx_v_new_state); - __pyx_v_new_state = __pyx_4; - __pyx_4 = 0; - goto __pyx_L9; - } - __pyx_L9:; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":182 - * 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# - */ - __pyx_3 = __Pyx_PyObject_IsTrue(__pyx_v_new_state); if (unlikely(__pyx_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (__pyx_3) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":183 - * new_state = c and state.get('else') #@fast - * if new_state: - * if trace: #TRACE# # <<<<<<<<<<<<<< - * print("State %d" % new_state['number']) #TRACE# - * state = new_state - */ - __pyx_3 = __Pyx_PyObject_IsTrue(__pyx_v_trace); if (unlikely(__pyx_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 183; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (__pyx_3) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":184 - * if new_state: - * if trace: #TRACE# - * print("State %d" % new_state['number']) #TRACE# # <<<<<<<<<<<<<< - * state = new_state - * # Begin inlined: self.next_char() - */ - __pyx_5 = PyObject_GetItem(__pyx_v_new_state, __pyx_kp_15); if (!__pyx_5) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 184; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_t_1 = PyNumber_Remainder(__pyx_kp_14, __pyx_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 184; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_5); __pyx_5 = 0; - __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 184; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - PyTuple_SET_ITEM(__pyx_1, 0, __pyx_t_1); - __pyx_t_1 = 0; - if (__Pyx_Print(((PyObject *)__pyx_1), 1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 184; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0; - goto __pyx_L11; - } - __pyx_L11:; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":185 - * if trace: #TRACE# - * print("State %d" % new_state['number']) #TRACE# - * state = new_state # <<<<<<<<<<<<<< - * # Begin inlined: self.next_char() - * if input_state == 1: - */ - Py_INCREF(__pyx_v_new_state); - Py_DECREF(__pyx_v_state); - __pyx_v_state = __pyx_v_new_state; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":187 - * state = new_state - * # Begin inlined: self.next_char() - * if input_state == 1: # <<<<<<<<<<<<<< - * cur_pos = next_pos - * # Begin inlined: c = self.read_char() - */ - __pyx_4 = PyObject_RichCompare(__pyx_v_input_state, __pyx_int_1, Py_EQ); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_3 = __Pyx_PyObject_IsTrue(__pyx_4); if (unlikely(__pyx_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_4); __pyx_4 = 0; - if (__pyx_3) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":188 - * # 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 - */ - Py_INCREF(__pyx_v_next_pos); - Py_DECREF(__pyx_v_cur_pos); - __pyx_v_cur_pos = __pyx_v_next_pos; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":190 - * 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] - */ - __pyx_t_1 = PyNumber_Subtract(__pyx_v_next_pos, __pyx_v_buf_start_pos); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_buf_index); - __pyx_v_buf_index = __pyx_t_1; - __pyx_t_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":191 - * # 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 - */ - __pyx_5 = PyObject_RichCompare(__pyx_v_buf_index, __pyx_v_buf_len, Py_LT); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_3 = __Pyx_PyObject_IsTrue(__pyx_5); if (unlikely(__pyx_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_5); __pyx_5 = 0; - if (__pyx_3) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":192 - * buf_index = next_pos - buf_start_pos - * if buf_index < buf_len: - * c = buffer[buf_index] # <<<<<<<<<<<<<< - * next_pos = next_pos + 1 - * else: - */ - __pyx_1 = PyObject_GetItem(__pyx_v_buffer, __pyx_v_buf_index); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_c); - __pyx_v_c = __pyx_1; - __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":193 - * if buf_index < buf_len: - * c = buffer[buf_index] - * next_pos = next_pos + 1 # <<<<<<<<<<<<<< - * else: - * discard = self.start_pos - buf_start_pos - */ - __pyx_t_1 = PyNumber_Add(__pyx_v_next_pos, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 193; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_next_pos); - __pyx_v_next_pos = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L13; - } - /*else*/ { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":195 - * next_pos = next_pos + 1 - * else: - * discard = self.start_pos - buf_start_pos # <<<<<<<<<<<<<< - * data = self.stream.read(0x1000) - * buffer = self.buffer[discard:] + data - */ - __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_start_pos); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 195; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_t_1 = PyNumber_Subtract(__pyx_4, __pyx_v_buf_start_pos); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 195; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_4); __pyx_4 = 0; - Py_DECREF(__pyx_v_discard); - __pyx_v_discard = __pyx_t_1; - __pyx_t_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":196 - * else: - * discard = self.start_pos - buf_start_pos - * data = self.stream.read(0x1000) # <<<<<<<<<<<<<< - * buffer = self.buffer[discard:] + data - * self.buffer = buffer - */ - __pyx_5 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_stream); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_1 = PyObject_GetAttr(__pyx_5, __pyx_kp_read); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_5); __pyx_5 = 0; - __pyx_4 = PyTuple_New(1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_INCREF(__pyx_int_0x1000); - PyTuple_SET_ITEM(__pyx_4, 0, __pyx_int_0x1000); - __pyx_5 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_4), NULL); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0; - Py_DECREF(__pyx_v_data); - __pyx_v_data = __pyx_5; - __pyx_5 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":197 - * 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 - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_buffer); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_2 = __pyx_PyIndex_AsSsize_t(__pyx_v_discard); if (unlikely((__pyx_2 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_4 = PySequence_GetSlice(__pyx_1, __pyx_2, PY_SSIZE_T_MAX); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - __pyx_t_1 = PyNumber_Add(__pyx_4, __pyx_v_data); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_4); __pyx_4 = 0; - Py_DECREF(__pyx_v_buffer); - __pyx_v_buffer = __pyx_t_1; - __pyx_t_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":198 - * 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 - */ - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_buffer, __pyx_v_buffer) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 198; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":199 - * 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) - */ - __pyx_t_1 = PyNumber_Add(__pyx_v_buf_start_pos, __pyx_v_discard); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 199; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_buf_start_pos); - __pyx_v_buf_start_pos = __pyx_t_1; - __pyx_t_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":200 - * 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 (PyObject_SetAttr(__pyx_v_self, __pyx_kp_buf_start_pos, __pyx_v_buf_start_pos) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":201 - * 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: - */ - __pyx_2 = PyObject_Length(__pyx_v_buffer); if (unlikely(__pyx_2 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_5 = PyInt_FromSsize_t(__pyx_2); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_buf_len); - __pyx_v_buf_len = __pyx_5; - __pyx_5 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":202 - * self.buf_start_pos = buf_start_pos - * buf_len = len(buffer) - * buf_index = buf_index - discard # <<<<<<<<<<<<<< - * if data: - * c = buffer[buf_index] - */ - __pyx_t_1 = PyNumber_Subtract(__pyx_v_buf_index, __pyx_v_discard); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 202; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_buf_index); - __pyx_v_buf_index = __pyx_t_1; - __pyx_t_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":203 - * buf_len = len(buffer) - * buf_index = buf_index - discard - * if data: # <<<<<<<<<<<<<< - * c = buffer[buf_index] - * next_pos = next_pos + 1 - */ - __pyx_3 = __Pyx_PyObject_IsTrue(__pyx_v_data); if (unlikely(__pyx_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (__pyx_3) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":204 - * buf_index = buf_index - discard - * if data: - * c = buffer[buf_index] # <<<<<<<<<<<<<< - * next_pos = next_pos + 1 - * else: - */ - __pyx_1 = PyObject_GetItem(__pyx_v_buffer, __pyx_v_buf_index); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_c); - __pyx_v_c = __pyx_1; - __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":205 - * if data: - * c = buffer[buf_index] - * next_pos = next_pos + 1 # <<<<<<<<<<<<<< - * else: - * c = '' - */ - __pyx_t_1 = PyNumber_Add(__pyx_v_next_pos, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 205; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_next_pos); - __pyx_v_next_pos = __pyx_t_1; - __pyx_t_1 = 0; - goto __pyx_L14; - } - /*else*/ { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":207 - * next_pos = next_pos + 1 - * else: - * c = '' # <<<<<<<<<<<<<< - * # End inlined: c = self.read_char() - * if c == '\n': - */ - Py_INCREF(__pyx_kp_16); - Py_DECREF(__pyx_v_c); - __pyx_v_c = __pyx_kp_16; - } - __pyx_L14:; - } - __pyx_L13:; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":209 - * c = '' - * # End inlined: c = self.read_char() - * if c == '\n': # <<<<<<<<<<<<<< - * cur_char = EOL - * input_state = 2 - */ - __pyx_4 = PyObject_RichCompare(__pyx_v_c, __pyx_kp_17, Py_EQ); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_3 = __Pyx_PyObject_IsTrue(__pyx_4); if (unlikely(__pyx_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_4); __pyx_4 = 0; - if (__pyx_3) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":210 - * # End inlined: c = self.read_char() - * if c == '\n': - * cur_char = EOL # <<<<<<<<<<<<<< - * input_state = 2 - * elif not c: - */ - __pyx_5 = __Pyx_GetName(__pyx_m, __pyx_kp_EOL); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_cur_char); - __pyx_v_cur_char = __pyx_5; - __pyx_5 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":211 - * if c == '\n': - * cur_char = EOL - * input_state = 2 # <<<<<<<<<<<<<< - * elif not c: - * cur_char = EOL - */ - Py_INCREF(__pyx_int_2); - Py_DECREF(__pyx_v_input_state); - __pyx_v_input_state = __pyx_int_2; - goto __pyx_L15; - } - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":212 - * cur_char = EOL - * input_state = 2 - * elif not c: # <<<<<<<<<<<<<< - * cur_char = EOL - * input_state = 4 - */ - __pyx_3 = __Pyx_PyObject_IsTrue(__pyx_v_c); if (unlikely(__pyx_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_6 = (!__pyx_3); - if (__pyx_6) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":213 - * input_state = 2 - * elif not c: - * cur_char = EOL # <<<<<<<<<<<<<< - * input_state = 4 - * else: - */ - __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_kp_EOL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 213; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_cur_char); - __pyx_v_cur_char = __pyx_1; - __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":214 - * elif not c: - * cur_char = EOL - * input_state = 4 # <<<<<<<<<<<<<< - * else: - * cur_char = c - */ - Py_INCREF(__pyx_int_4); - Py_DECREF(__pyx_v_input_state); - __pyx_v_input_state = __pyx_int_4; - goto __pyx_L15; - } - /*else*/ { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":216 - * input_state = 4 - * else: - * cur_char = c # <<<<<<<<<<<<<< - * elif input_state == 2: - * cur_char = '\n' - */ - Py_INCREF(__pyx_v_c); - Py_DECREF(__pyx_v_cur_char); - __pyx_v_cur_char = __pyx_v_c; - } - __pyx_L15:; - goto __pyx_L12; - } - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":217 - * else: - * cur_char = c - * elif input_state == 2: # <<<<<<<<<<<<<< - * cur_char = '\n' - * input_state = 3 - */ - __pyx_4 = PyObject_RichCompare(__pyx_v_input_state, __pyx_int_2, Py_EQ); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_3 = __Pyx_PyObject_IsTrue(__pyx_4); if (unlikely(__pyx_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_4); __pyx_4 = 0; - if (__pyx_3) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":218 - * cur_char = c - * elif input_state == 2: - * cur_char = '\n' # <<<<<<<<<<<<<< - * input_state = 3 - * elif input_state == 3: - */ - Py_INCREF(__pyx_kp_18); - Py_DECREF(__pyx_v_cur_char); - __pyx_v_cur_char = __pyx_kp_18; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":219 - * elif input_state == 2: - * cur_char = '\n' - * input_state = 3 # <<<<<<<<<<<<<< - * elif input_state == 3: - * cur_line = cur_line + 1 - */ - Py_INCREF(__pyx_int_3); - Py_DECREF(__pyx_v_input_state); - __pyx_v_input_state = __pyx_int_3; - goto __pyx_L12; - } - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":220 - * cur_char = '\n' - * input_state = 3 - * elif input_state == 3: # <<<<<<<<<<<<<< - * cur_line = cur_line + 1 - * cur_line_start = cur_pos = next_pos - */ - __pyx_5 = PyObject_RichCompare(__pyx_v_input_state, __pyx_int_3, Py_EQ); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_6 = __Pyx_PyObject_IsTrue(__pyx_5); if (unlikely(__pyx_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 220; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_5); __pyx_5 = 0; - if (__pyx_6) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":221 - * input_state = 3 - * elif input_state == 3: - * cur_line = cur_line + 1 # <<<<<<<<<<<<<< - * cur_line_start = cur_pos = next_pos - * cur_char = BOL - */ - __pyx_t_1 = PyNumber_Add(__pyx_v_cur_line, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 221; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_cur_line); - __pyx_v_cur_line = __pyx_t_1; - __pyx_t_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":222 - * elif input_state == 3: - * cur_line = cur_line + 1 - * cur_line_start = cur_pos = next_pos # <<<<<<<<<<<<<< - * cur_char = BOL - * input_state = 1 - */ - Py_INCREF(__pyx_v_next_pos); - Py_DECREF(__pyx_v_cur_line_start); - __pyx_v_cur_line_start = __pyx_v_next_pos; - Py_INCREF(__pyx_v_next_pos); - Py_DECREF(__pyx_v_cur_pos); - __pyx_v_cur_pos = __pyx_v_next_pos; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":223 - * cur_line = cur_line + 1 - * cur_line_start = cur_pos = next_pos - * cur_char = BOL # <<<<<<<<<<<<<< - * input_state = 1 - * elif input_state == 4: - */ - __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_kp_BOL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 223; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_cur_char); - __pyx_v_cur_char = __pyx_1; - __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":224 - * cur_line_start = cur_pos = next_pos - * cur_char = BOL - * input_state = 1 # <<<<<<<<<<<<<< - * elif input_state == 4: - * cur_char = EOF - */ - Py_INCREF(__pyx_int_1); - Py_DECREF(__pyx_v_input_state); - __pyx_v_input_state = __pyx_int_1; - goto __pyx_L12; - } - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":225 - * cur_char = BOL - * input_state = 1 - * elif input_state == 4: # <<<<<<<<<<<<<< - * cur_char = EOF - * input_state = 5 - */ - __pyx_4 = PyObject_RichCompare(__pyx_v_input_state, __pyx_int_4, Py_EQ); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_3 = __Pyx_PyObject_IsTrue(__pyx_4); if (unlikely(__pyx_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_4); __pyx_4 = 0; - if (__pyx_3) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":226 - * input_state = 1 - * elif input_state == 4: - * cur_char = EOF # <<<<<<<<<<<<<< - * input_state = 5 - * else: # input_state = 5 - */ - __pyx_5 = __Pyx_GetName(__pyx_m, __pyx_kp_EOF); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_cur_char); - __pyx_v_cur_char = __pyx_5; - __pyx_5 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":227 - * elif input_state == 4: - * cur_char = EOF - * input_state = 5 # <<<<<<<<<<<<<< - * else: # input_state = 5 - * cur_char = '' - */ - Py_INCREF(__pyx_int_5); - Py_DECREF(__pyx_v_input_state); - __pyx_v_input_state = __pyx_int_5; - goto __pyx_L12; - } - /*else*/ { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":229 - * input_state = 5 - * else: # input_state = 5 - * cur_char = '' # <<<<<<<<<<<<<< - * # End inlined self.next_char() - * else: # not new_state - */ - Py_INCREF(__pyx_kp_19); - Py_DECREF(__pyx_v_cur_char); - __pyx_v_cur_char = __pyx_kp_19; - } - __pyx_L12:; - goto __pyx_L10; - } - /*else*/ { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":232 - * # End inlined self.next_char() - * else: # not new_state - * if trace: #TRACE# # <<<<<<<<<<<<<< - * print("blocked") #TRACE# - * # Begin inlined: action = self.back_up() - */ - __pyx_6 = __Pyx_PyObject_IsTrue(__pyx_v_trace); if (unlikely(__pyx_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 232; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (__pyx_6) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":233 - * else: # not new_state - * if trace: #TRACE# - * print("blocked") #TRACE# # <<<<<<<<<<<<<< - * # Begin inlined: action = self.back_up() - * if backup_state: - */ - __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_INCREF(__pyx_kp_20); - PyTuple_SET_ITEM(__pyx_1, 0, __pyx_kp_20); - if (__Pyx_Print(((PyObject *)__pyx_1), 1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0; - goto __pyx_L16; - } - __pyx_L16:; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":235 - * 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 - */ - __pyx_3 = __Pyx_PyObject_IsTrue(__pyx_v_backup_state); if (unlikely(__pyx_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 235; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (__pyx_3) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":237 - * if backup_state: - * (action, cur_pos, cur_line, cur_line_start, - * cur_char, input_state, next_pos) = backup_state # <<<<<<<<<<<<<< - * else: - * action = None - */ - if (PyTuple_CheckExact(__pyx_v_backup_state) && PyTuple_GET_SIZE(__pyx_v_backup_state) == 7) { - PyObject* tuple = __pyx_v_backup_state; - __pyx_5 = PyTuple_GET_ITEM(tuple, 0); - Py_INCREF(__pyx_5); - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":236 - * # 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: - */ - Py_DECREF(__pyx_v_action); - __pyx_v_action = __pyx_5; - __pyx_5 = 0; - __pyx_1 = PyTuple_GET_ITEM(tuple, 1); - Py_INCREF(__pyx_1); - Py_DECREF(__pyx_v_cur_pos); - __pyx_v_cur_pos = __pyx_1; - __pyx_1 = 0; - __pyx_5 = PyTuple_GET_ITEM(tuple, 2); - Py_INCREF(__pyx_5); - Py_DECREF(__pyx_v_cur_line); - __pyx_v_cur_line = __pyx_5; - __pyx_5 = 0; - __pyx_1 = PyTuple_GET_ITEM(tuple, 3); - Py_INCREF(__pyx_1); - Py_DECREF(__pyx_v_cur_line_start); - __pyx_v_cur_line_start = __pyx_1; - __pyx_1 = 0; - __pyx_5 = PyTuple_GET_ITEM(tuple, 4); - Py_INCREF(__pyx_5); - Py_DECREF(__pyx_v_cur_char); - __pyx_v_cur_char = __pyx_5; - __pyx_5 = 0; - __pyx_1 = PyTuple_GET_ITEM(tuple, 5); - Py_INCREF(__pyx_1); - Py_DECREF(__pyx_v_input_state); - __pyx_v_input_state = __pyx_1; - __pyx_1 = 0; - __pyx_5 = PyTuple_GET_ITEM(tuple, 6); - Py_INCREF(__pyx_5); - Py_DECREF(__pyx_v_next_pos); - __pyx_v_next_pos = __pyx_5; - __pyx_5 = 0; - } - else { - __pyx_4 = PyObject_GetIter(__pyx_v_backup_state); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 236; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_5 = __Pyx_UnpackItem(__pyx_4, 0); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 236; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_action); - __pyx_v_action = __pyx_5; - __pyx_5 = 0; - __pyx_1 = __Pyx_UnpackItem(__pyx_4, 1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 236; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_cur_pos); - __pyx_v_cur_pos = __pyx_1; - __pyx_1 = 0; - __pyx_5 = __Pyx_UnpackItem(__pyx_4, 2); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 236; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_cur_line); - __pyx_v_cur_line = __pyx_5; - __pyx_5 = 0; - __pyx_1 = __Pyx_UnpackItem(__pyx_4, 3); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 236; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_cur_line_start); - __pyx_v_cur_line_start = __pyx_1; - __pyx_1 = 0; - __pyx_5 = __Pyx_UnpackItem(__pyx_4, 4); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 236; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_cur_char); - __pyx_v_cur_char = __pyx_5; - __pyx_5 = 0; - __pyx_1 = __Pyx_UnpackItem(__pyx_4, 5); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 236; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_input_state); - __pyx_v_input_state = __pyx_1; - __pyx_1 = 0; - __pyx_5 = __Pyx_UnpackItem(__pyx_4, 6); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 236; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_next_pos); - __pyx_v_next_pos = __pyx_5; - __pyx_5 = 0; - if (__Pyx_EndUnpack(__pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 236; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_4); __pyx_4 = 0; - } - goto __pyx_L17; - } - /*else*/ { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":239 - * cur_char, input_state, next_pos) = backup_state - * else: - * action = None # <<<<<<<<<<<<<< - * break # while 1 - * # End inlined: action = self.back_up() - */ - Py_INCREF(Py_None); - Py_DECREF(__pyx_v_action); - __pyx_v_action = Py_None; - } - __pyx_L17:; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":240 - * else: - * action = None - * break # while 1 # <<<<<<<<<<<<<< - * # End inlined: action = self.back_up() - * self.cur_pos = cur_pos - */ - goto __pyx_L6; - } - __pyx_L10:; - } - __pyx_L6:; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":242 - * 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 - */ - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_cur_pos, __pyx_v_cur_pos) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":243 - * # 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 - */ - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_cur_line, __pyx_v_cur_line) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":244 - * 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 - */ - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_cur_line_start, __pyx_v_cur_line_start) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":245 - * 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 (PyObject_SetAttr(__pyx_v_self, __pyx_kp_cur_char, __pyx_v_cur_char) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 245; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":246 - * 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 (PyObject_SetAttr(__pyx_v_self, __pyx_kp_input_state, __pyx_v_input_state) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 246; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":247 - * self.cur_char = cur_char - * self.input_state = input_state - * self.next_pos = next_pos # <<<<<<<<<<<<<< - * if trace: #TRACE# - * if action: #TRACE# - */ - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_next_pos, __pyx_v_next_pos) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 247; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":248 - * self.input_state = input_state - * self.next_pos = next_pos - * if trace: #TRACE# # <<<<<<<<<<<<<< - * if action: #TRACE# - * print("Doing " + action) #TRACE# - */ - __pyx_6 = __Pyx_PyObject_IsTrue(__pyx_v_trace); if (unlikely(__pyx_6 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (__pyx_6) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":249 - * self.next_pos = next_pos - * if trace: #TRACE# - * if action: #TRACE# # <<<<<<<<<<<<<< - * print("Doing " + action) #TRACE# - * return action - */ - __pyx_3 = __Pyx_PyObject_IsTrue(__pyx_v_action); if (unlikely(__pyx_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 249; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (__pyx_3) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":250 - * if trace: #TRACE# - * if action: #TRACE# - * print("Doing " + action) #TRACE# # <<<<<<<<<<<<<< - * return action - * - */ - __pyx_t_1 = PyNumber_Add(__pyx_kp_21, __pyx_v_action); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - PyTuple_SET_ITEM(__pyx_1, 0, __pyx_t_1); - __pyx_t_1 = 0; - if (__Pyx_Print(((PyObject *)__pyx_1), 1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 250; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0; - goto __pyx_L19; - } - __pyx_L19:; - goto __pyx_L18; - } - __pyx_L18:; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":251 - * if action: #TRACE# - * print("Doing " + action) #TRACE# - * return action # <<<<<<<<<<<<<< - * - * # def transition(self): - */ - Py_INCREF(__pyx_v_action); - __pyx_r = __pyx_v_action; - goto __pyx_L0; - - __pyx_r = Py_None; Py_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - Py_XDECREF(__pyx_1); - Py_XDECREF(__pyx_4); - Py_XDECREF(__pyx_5); - __Pyx_AddTraceback("Cython.Plex.Scanners.Scanner.run_machine_inlined"); - __pyx_r = NULL; - __pyx_L0:; - Py_DECREF(__pyx_v_state); - Py_DECREF(__pyx_v_cur_pos); - Py_DECREF(__pyx_v_cur_line); - Py_DECREF(__pyx_v_cur_line_start); - Py_DECREF(__pyx_v_cur_char); - Py_DECREF(__pyx_v_input_state); - Py_DECREF(__pyx_v_next_pos); - Py_DECREF(__pyx_v_buffer); - Py_DECREF(__pyx_v_buf_start_pos); - Py_DECREF(__pyx_v_buf_len); - Py_DECREF(__pyx_v_backup_state); - Py_DECREF(__pyx_v_trace); - Py_DECREF(__pyx_v_action); - Py_DECREF(__pyx_v_c); - Py_DECREF(__pyx_v_new_state); - Py_DECREF(__pyx_v_buf_index); - Py_DECREF(__pyx_v_discard); - Py_DECREF(__pyx_v_data); - return __pyx_r; -} - -/* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":290 - * # return None - * - * def next_char(self): # <<<<<<<<<<<<<< - * input_state = self.input_state - * if self.trace: - */ - -static PyObject *__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_next_char(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/ -static PyMethodDef __pyx_mdef_6Cython_4Plex_8Scanners_7Scanner_next_char = {"next_char", (PyCFunction)__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_next_char, METH_O, 0}; -static PyObject *__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_next_char(PyObject *__pyx_self, PyObject *__pyx_v_self) { - PyObject *__pyx_v_input_state; - PyObject *__pyx_v_c; - PyObject *__pyx_r; - PyObject *__pyx_1 = 0; - int __pyx_2; - PyObject *__pyx_3 = 0; - int __pyx_4; - PyObject *__pyx_5 = 0; - PyObject *__pyx_t_1 = NULL; - __pyx_self = __pyx_self; - __pyx_v_input_state = Py_None; Py_INCREF(Py_None); - __pyx_v_c = Py_None; Py_INCREF(Py_None); - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":291 - * - * def next_char(self): - * input_state = self.input_state # <<<<<<<<<<<<<< - * if self.trace: - * print("Scanner: next: %s [%d] %d" % (" "*20, input_state, self.cur_pos)) - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_input_state); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 291; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_input_state); - __pyx_v_input_state = __pyx_1; - __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":292 - * def next_char(self): - * input_state = self.input_state - * if self.trace: # <<<<<<<<<<<<<< - * print("Scanner: next: %s [%d] %d" % (" "*20, input_state, self.cur_pos)) - * if input_state == 1: - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_trace); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 292; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_2 = __Pyx_PyObject_IsTrue(__pyx_1); if (unlikely(__pyx_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 292; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - if (__pyx_2) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":293 - * input_state = self.input_state - * if self.trace: - * print("Scanner: next: %s [%d] %d" % (" "*20, input_state, self.cur_pos)) # <<<<<<<<<<<<<< - * if input_state == 1: - * self.cur_pos = self.next_pos - */ - __pyx_t_1 = PyNumber_Multiply(__pyx_kp_23, __pyx_int_20); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_cur_pos); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_3 = PyTuple_New(3); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - PyTuple_SET_ITEM(__pyx_3, 0, __pyx_t_1); - Py_INCREF(__pyx_v_input_state); - PyTuple_SET_ITEM(__pyx_3, 1, __pyx_v_input_state); - PyTuple_SET_ITEM(__pyx_3, 2, __pyx_1); - __pyx_t_1 = 0; - __pyx_1 = 0; - __pyx_t_1 = PyNumber_Remainder(__pyx_kp_22, ((PyObject *)__pyx_3)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(((PyObject *)__pyx_3)); __pyx_3 = 0; - __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - PyTuple_SET_ITEM(__pyx_1, 0, __pyx_t_1); - __pyx_t_1 = 0; - if (__Pyx_Print(((PyObject *)__pyx_1), 1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0; - goto __pyx_L5; - } - __pyx_L5:; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":294 - * if self.trace: - * print("Scanner: next: %s [%d] %d" % (" "*20, input_state, self.cur_pos)) - * if input_state == 1: # <<<<<<<<<<<<<< - * self.cur_pos = self.next_pos - * c = self.read_char() - */ - __pyx_3 = PyObject_RichCompare(__pyx_v_input_state, __pyx_int_1, Py_EQ); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_2 = __Pyx_PyObject_IsTrue(__pyx_3); if (unlikely(__pyx_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 294; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_3); __pyx_3 = 0; - if (__pyx_2) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":295 - * print("Scanner: next: %s [%d] %d" % (" "*20, input_state, self.cur_pos)) - * if input_state == 1: - * self.cur_pos = self.next_pos # <<<<<<<<<<<<<< - * c = self.read_char() - * if c == '\n': - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_next_pos); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_cur_pos, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 295; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":296 - * if input_state == 1: - * self.cur_pos = self.next_pos - * c = self.read_char() # <<<<<<<<<<<<<< - * if c == '\n': - * self.cur_char = EOL - */ - __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_read_char); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_1 = PyObject_Call(__pyx_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 296; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_3); __pyx_3 = 0; - Py_DECREF(__pyx_v_c); - __pyx_v_c = __pyx_1; - __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":297 - * self.cur_pos = self.next_pos - * c = self.read_char() - * if c == '\n': # <<<<<<<<<<<<<< - * self.cur_char = EOL - * self.input_state = 2 - */ - __pyx_3 = PyObject_RichCompare(__pyx_v_c, __pyx_kp_24, Py_EQ); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_2 = __Pyx_PyObject_IsTrue(__pyx_3); if (unlikely(__pyx_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_3); __pyx_3 = 0; - if (__pyx_2) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":298 - * c = self.read_char() - * if c == '\n': - * self.cur_char = EOL # <<<<<<<<<<<<<< - * self.input_state = 2 - * elif not c: - */ - __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_kp_EOL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 298; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_cur_char, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 298; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":299 - * if c == '\n': - * self.cur_char = EOL - * self.input_state = 2 # <<<<<<<<<<<<<< - * elif not c: - * self.cur_char = EOL - */ - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_input_state, __pyx_int_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 299; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - goto __pyx_L7; - } - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":300 - * self.cur_char = EOL - * self.input_state = 2 - * elif not c: # <<<<<<<<<<<<<< - * self.cur_char = EOL - * self.input_state = 4 - */ - __pyx_2 = __Pyx_PyObject_IsTrue(__pyx_v_c); if (unlikely(__pyx_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 300; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_4 = (!__pyx_2); - if (__pyx_4) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":301 - * self.input_state = 2 - * elif not c: - * self.cur_char = EOL # <<<<<<<<<<<<<< - * self.input_state = 4 - * else: - */ - __pyx_3 = __Pyx_GetName(__pyx_m, __pyx_kp_EOL); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 301; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_cur_char, __pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 301; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_3); __pyx_3 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":302 - * elif not c: - * self.cur_char = EOL - * self.input_state = 4 # <<<<<<<<<<<<<< - * else: - * self.cur_char = c - */ - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_input_state, __pyx_int_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 302; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - goto __pyx_L7; - } - /*else*/ { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":304 - * self.input_state = 4 - * else: - * self.cur_char = c # <<<<<<<<<<<<<< - * elif input_state == 2: - * self.cur_char = '\n' - */ - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_cur_char, __pyx_v_c) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 304; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - } - __pyx_L7:; - goto __pyx_L6; - } - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":305 - * else: - * self.cur_char = c - * elif input_state == 2: # <<<<<<<<<<<<<< - * self.cur_char = '\n' - * self.input_state = 3 - */ - __pyx_1 = PyObject_RichCompare(__pyx_v_input_state, __pyx_int_2, Py_EQ); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_2 = __Pyx_PyObject_IsTrue(__pyx_1); if (unlikely(__pyx_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 305; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - if (__pyx_2) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":306 - * self.cur_char = c - * elif input_state == 2: - * self.cur_char = '\n' # <<<<<<<<<<<<<< - * self.input_state = 3 - * elif input_state == 3: - */ - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_cur_char, __pyx_kp_25) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 306; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":307 - * elif input_state == 2: - * self.cur_char = '\n' - * self.input_state = 3 # <<<<<<<<<<<<<< - * elif input_state == 3: - * self.cur_line = self.cur_line + 1 - */ - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_input_state, __pyx_int_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 307; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - goto __pyx_L6; - } - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":308 - * 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 - */ - __pyx_3 = PyObject_RichCompare(__pyx_v_input_state, __pyx_int_3, Py_EQ); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_4 = __Pyx_PyObject_IsTrue(__pyx_3); if (unlikely(__pyx_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 308; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_3); __pyx_3 = 0; - if (__pyx_4) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":309 - * 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 - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_cur_line); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_t_1 = PyNumber_Add(__pyx_1, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_cur_line, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_t_1); __pyx_t_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":310 - * 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 - */ - __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_next_pos); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_cur_line_start, __pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_cur_pos, __pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 310; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_3); __pyx_3 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":311 - * 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: - */ - __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_kp_BOL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_cur_char, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":312 - * 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 - */ - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_input_state, __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 312; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - goto __pyx_L6; - } - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":313 - * self.cur_char = BOL - * self.input_state = 1 - * elif input_state == 4: # <<<<<<<<<<<<<< - * self.cur_char = EOF - * self.input_state = 5 - */ - __pyx_3 = PyObject_RichCompare(__pyx_v_input_state, __pyx_int_4, Py_EQ); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 313; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_2 = __Pyx_PyObject_IsTrue(__pyx_3); if (unlikely(__pyx_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 313; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_3); __pyx_3 = 0; - if (__pyx_2) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":314 - * self.input_state = 1 - * elif input_state == 4: - * self.cur_char = EOF # <<<<<<<<<<<<<< - * self.input_state = 5 - * else: # input_state = 5 - */ - __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_kp_EOF); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 314; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_cur_char, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 314; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":315 - * elif input_state == 4: - * self.cur_char = EOF - * self.input_state = 5 # <<<<<<<<<<<<<< - * else: # input_state = 5 - * self.cur_char = '' - */ - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_input_state, __pyx_int_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 315; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - goto __pyx_L6; - } - /*else*/ { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":317 - * 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))) - */ - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_cur_char, __pyx_kp_26) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 317; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - } - __pyx_L6:; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":318 - * else: # input_state = 5 - * self.cur_char = '' - * if self.trace: # <<<<<<<<<<<<<< - * print("--> [%d] %d %s" % (input_state, self.cur_pos, repr(self.cur_char))) - * - */ - __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_trace); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_4 = __Pyx_PyObject_IsTrue(__pyx_3); if (unlikely(__pyx_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_3); __pyx_3 = 0; - if (__pyx_4) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":319 - * self.cur_char = '' - * if self.trace: - * print("--> [%d] %d %s" % (input_state, self.cur_pos, repr(self.cur_char))) # <<<<<<<<<<<<<< - * - * # def read_char(self): - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_cur_pos); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 319; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_cur_char); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 319; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_5 = PyObject_Repr(__pyx_3); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 319; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_3); __pyx_3 = 0; - __pyx_3 = PyTuple_New(3); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 319; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_INCREF(__pyx_v_input_state); - PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_input_state); - PyTuple_SET_ITEM(__pyx_3, 1, __pyx_1); - PyTuple_SET_ITEM(__pyx_3, 2, __pyx_5); - __pyx_1 = 0; - __pyx_5 = 0; - __pyx_t_1 = PyNumber_Remainder(__pyx_kp_27, ((PyObject *)__pyx_3)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 319; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(((PyObject *)__pyx_3)); __pyx_3 = 0; - __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 319; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - PyTuple_SET_ITEM(__pyx_1, 0, __pyx_t_1); - __pyx_t_1 = 0; - if (__Pyx_Print(((PyObject *)__pyx_1), 1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 319; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0; - goto __pyx_L8; - } - __pyx_L8:; - - __pyx_r = Py_None; Py_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - Py_XDECREF(__pyx_1); - Py_XDECREF(__pyx_3); - Py_XDECREF(__pyx_5); - __Pyx_AddTraceback("Cython.Plex.Scanners.Scanner.next_char"); - __pyx_r = NULL; - __pyx_L0:; - Py_DECREF(__pyx_v_input_state); - Py_DECREF(__pyx_v_c); - return __pyx_r; -} - -/* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":340 - * # return c - * - * def position(self): # <<<<<<<<<<<<<< - * """ - * Return a tuple (name, line, col) representing the location of - */ - -static PyObject *__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_position(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/ -static char __pyx_doc_6Cython_4Plex_8Scanners_7Scanner_position[] = "\n Return a tuple (name, line, col) representing the location of\n the last token read using the read() method. |name| is the\n name that was provided to the Scanner constructor; |line|\n is the line number in the stream (1-based); |col| is the\n position within the line of the first character of the token\n (0-based).\n "; -static PyMethodDef __pyx_mdef_6Cython_4Plex_8Scanners_7Scanner_position = {"position", (PyCFunction)__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_position, METH_O, __pyx_doc_6Cython_4Plex_8Scanners_7Scanner_position}; -static PyObject *__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_position(PyObject *__pyx_self, PyObject *__pyx_v_self) { - PyObject *__pyx_r; - PyObject *__pyx_1 = 0; - PyObject *__pyx_2 = 0; - PyObject *__pyx_3 = 0; - PyObject *__pyx_4 = 0; - __pyx_self = __pyx_self; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":349 - * (0-based). - * """ - * return (self.name, self.start_line, self.start_col) # <<<<<<<<<<<<<< - * - * def begin(self, state_name): - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_name); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_start_line); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_start_col); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_4 = PyTuple_New(3); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 349; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - PyTuple_SET_ITEM(__pyx_4, 0, __pyx_1); - PyTuple_SET_ITEM(__pyx_4, 1, __pyx_2); - PyTuple_SET_ITEM(__pyx_4, 2, __pyx_3); - __pyx_1 = 0; - __pyx_2 = 0; - __pyx_3 = 0; - __pyx_r = ((PyObject *)__pyx_4); - __pyx_4 = 0; - goto __pyx_L0; - - __pyx_r = Py_None; Py_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - Py_XDECREF(__pyx_1); - Py_XDECREF(__pyx_2); - Py_XDECREF(__pyx_3); - Py_XDECREF(__pyx_4); - __Pyx_AddTraceback("Cython.Plex.Scanners.Scanner.position"); - __pyx_r = NULL; - __pyx_L0:; - return __pyx_r; -} - -/* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":351 - * 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 = ( - */ - -static PyObject *__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_begin(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static char __pyx_doc_6Cython_4Plex_8Scanners_7Scanner_begin[] = "Set the current state of the scanner to the named state."; -static PyMethodDef __pyx_mdef_6Cython_4Plex_8Scanners_7Scanner_begin = {"begin", (PyCFunction)__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_begin, METH_VARARGS|METH_KEYWORDS, __pyx_doc_6Cython_4Plex_8Scanners_7Scanner_begin}; -static PyObject *__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_begin(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_self = 0; - PyObject *__pyx_v_state_name = 0; - PyObject *__pyx_r; - PyObject *__pyx_1 = 0; - PyObject *__pyx_2 = 0; - PyObject *__pyx_3 = 0; - static PyObject **__pyx_pyargnames[] = {&__pyx_kp_self,&__pyx_kp_state_name,0}; - __pyx_self = __pyx_self; - if (unlikely(__pyx_kwds)) { - PyObject* values[2] = {0,0}; - Py_ssize_t kw_args = PyDict_Size(__pyx_kwds); - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 0: - values[0] = PyDict_GetItem(__pyx_kwds, __pyx_kp_self); - if (likely(values[0])) kw_args--; - else goto __pyx_L5_argtuple_error; - case 1: - values[1] = PyDict_GetItem(__pyx_kwds, __pyx_kp_state_name); - if (likely(values[1])) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("begin", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "begin") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - } - __pyx_v_self = values[0]; - __pyx_v_state_name = values[1]; - } else if (PyTuple_GET_SIZE(__pyx_args) != 2) { - goto __pyx_L5_argtuple_error; - } else { - __pyx_v_self = PyTuple_GET_ITEM(__pyx_args, 0); - __pyx_v_state_name = PyTuple_GET_ITEM(__pyx_args, 1); - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("begin", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - __pyx_L3_error:; - __Pyx_AddTraceback("Cython.Plex.Scanners.Scanner.begin"); - return NULL; - __pyx_L4_argument_unpacking_done:; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":354 - * """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 - * - */ - __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lexicon); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_get_initial_state); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_INCREF(__pyx_v_state_name); - PyTuple_SET_ITEM(__pyx_1, 0, __pyx_v_state_name); - __pyx_3 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_2); __pyx_2 = 0; - Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":353 - * 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 - */ - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_initial_state, __pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 353; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_3); __pyx_3 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":355 - * self.initial_state = ( - * self.lexicon.get_initial_state(state_name)) - * self.state_name = state_name # <<<<<<<<<<<<<< - * - * def produce(self, value, text = None): - */ - if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_state_name, __pyx_v_state_name) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 355; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - __pyx_r = Py_None; Py_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - Py_XDECREF(__pyx_1); - Py_XDECREF(__pyx_2); - Py_XDECREF(__pyx_3); - __Pyx_AddTraceback("Cython.Plex.Scanners.Scanner.begin"); - __pyx_r = NULL; - __pyx_L0:; - return __pyx_r; -} - -/* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":357 - * self.state_name = state_name - * - * def produce(self, value, text = None): # <<<<<<<<<<<<<< - * """ - * Called from an action procedure, causes |value| to be returned - */ - -static PyObject *__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_produce(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ -static char __pyx_doc_6Cython_4Plex_8Scanners_7Scanner_produce[] = "\n Called from an action procedure, causes |value| to be returned\n as the token value from read(). If |text| is supplied, it is\n returned in place of the scanned text.\n\n produce() can be called more than once during a single call to an action\n procedure, in which case the tokens are queued up and returned one\n at a time by subsequent calls to read(), until the queue is empty,\n whereupon scanning resumes.\n "; -static PyMethodDef __pyx_mdef_6Cython_4Plex_8Scanners_7Scanner_produce = {"produce", (PyCFunction)__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_produce, METH_VARARGS|METH_KEYWORDS, __pyx_doc_6Cython_4Plex_8Scanners_7Scanner_produce}; -static PyObject *__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_produce(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { - PyObject *__pyx_v_self = 0; - PyObject *__pyx_v_value = 0; - PyObject *__pyx_v_text = 0; - PyObject *__pyx_r; - int __pyx_1; - PyObject *__pyx_2 = 0; - PyObject *__pyx_3 = 0; - PyObject *__pyx_4 = 0; - static PyObject **__pyx_pyargnames[] = {&__pyx_kp_self,&__pyx_kp_value,&__pyx_kp_text,0}; - __pyx_self = __pyx_self; - __pyx_v_text = Py_None; - if (unlikely(__pyx_kwds)) { - PyObject* values[3] = {0,0,0}; - Py_ssize_t kw_args = PyDict_Size(__pyx_kwds); - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); - case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); - case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); - case 0: break; - default: goto __pyx_L5_argtuple_error; - } - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 0: - values[0] = PyDict_GetItem(__pyx_kwds, __pyx_kp_self); - if (likely(values[0])) kw_args--; - else goto __pyx_L5_argtuple_error; - case 1: - values[1] = PyDict_GetItem(__pyx_kwds, __pyx_kp_value); - if (likely(values[1])) kw_args--; - else { - __Pyx_RaiseArgtupleInvalid("produce", 0, 2, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - } - } - if (unlikely(kw_args > 0)) { - if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "produce") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - } - __pyx_v_self = values[0]; - __pyx_v_value = values[1]; - if (values[2]) { - __pyx_v_text = values[2]; - } - } else { - switch (PyTuple_GET_SIZE(__pyx_args)) { - case 3: - __pyx_v_text = PyTuple_GET_ITEM(__pyx_args, 2); - case 2: - __pyx_v_value = PyTuple_GET_ITEM(__pyx_args, 1); - __pyx_v_self = PyTuple_GET_ITEM(__pyx_args, 0); - break; - default: goto __pyx_L5_argtuple_error; - } - } - goto __pyx_L4_argument_unpacking_done; - __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("produce", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L3_error;} - __pyx_L3_error:; - __Pyx_AddTraceback("Cython.Plex.Scanners.Scanner.produce"); - return NULL; - __pyx_L4_argument_unpacking_done:; - Py_INCREF(__pyx_v_text); - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":368 - * whereupon scanning resumes. - * """ - * if text is None: # <<<<<<<<<<<<<< - * text = self.text - * self.queue.append((value, text)) - */ - __pyx_1 = (__pyx_v_text == Py_None); - if (__pyx_1) { - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":369 - * """ - * if text is None: - * text = self.text # <<<<<<<<<<<<<< - * self.queue.append((value, text)) - * - */ - __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_text); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 369; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_v_text); - __pyx_v_text = __pyx_2; - __pyx_2 = 0; - goto __pyx_L6; - } - __pyx_L6:; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":370 - * if text is None: - * text = self.text - * self.queue.append((value, text)) # <<<<<<<<<<<<<< - * - * def eof(self): - */ - __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_queue); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_3 = PyTuple_New(2); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_INCREF(__pyx_v_value); - PyTuple_SET_ITEM(__pyx_3, 0, __pyx_v_value); - Py_INCREF(__pyx_v_text); - PyTuple_SET_ITEM(__pyx_3, 1, __pyx_v_text); - __pyx_4 = __Pyx_PyObject_Append(__pyx_2, ((PyObject *)__pyx_3)); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 370; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_2); __pyx_2 = 0; - Py_DECREF(((PyObject *)__pyx_3)); __pyx_3 = 0; - Py_DECREF(__pyx_4); __pyx_4 = 0; - - __pyx_r = Py_None; Py_INCREF(Py_None); - goto __pyx_L0; - __pyx_L1_error:; - Py_XDECREF(__pyx_2); - Py_XDECREF(__pyx_3); - Py_XDECREF(__pyx_4); - __Pyx_AddTraceback("Cython.Plex.Scanners.Scanner.produce"); - __pyx_r = NULL; - __pyx_L0:; - Py_DECREF(__pyx_v_text); - return __pyx_r; -} - -/* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":372 - * self.queue.append((value, text)) - * - * def eof(self): # <<<<<<<<<<<<<< - * """ - * Override this method if you want something to be done at - */ - -static PyObject *__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_eof(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/ -static char __pyx_doc_6Cython_4Plex_8Scanners_7Scanner_eof[] = "\n Override this method if you want something to be done at\n end of file.\n "; -static PyMethodDef __pyx_mdef_6Cython_4Plex_8Scanners_7Scanner_eof = {"eof", (PyCFunction)__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_eof, METH_O, __pyx_doc_6Cython_4Plex_8Scanners_7Scanner_eof}; -static PyObject *__pyx_pf_6Cython_4Plex_8Scanners_7Scanner_eof(PyObject *__pyx_self, PyObject *__pyx_v_self) { - PyObject *__pyx_r; - __pyx_self = __pyx_self; - - __pyx_r = Py_None; Py_INCREF(Py_None); - return __pyx_r; -} - -static struct PyMethodDef __pyx_methods[] = { - {0, 0, 0, 0} -}; - -static void __pyx_init_filenames(void); /*proto*/ - -#if PY_MAJOR_VERSION >= 3 -static struct PyModuleDef __pyx_moduledef = { - PyModuleDef_HEAD_INIT, - "Scanners", - 0, /* m_doc */ - -1, /* m_size */ - __pyx_methods /* m_methods */, - NULL, /* m_reload */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL /* m_free */ -}; -#endif - -static __Pyx_StringTabEntry __pyx_string_tab[] = { - {&__pyx_kp_self, __pyx_k_self, sizeof(__pyx_k_self), 1, 1, 1}, - {&__pyx_kp_lexicon, __pyx_k_lexicon, sizeof(__pyx_k_lexicon), 1, 1, 1}, - {&__pyx_kp_stream, __pyx_k_stream, sizeof(__pyx_k_stream), 1, 1, 1}, - {&__pyx_kp_name, __pyx_k_name, sizeof(__pyx_k_name), 1, 1, 1}, - {&__pyx_kp_initial_pos, __pyx_k_initial_pos, sizeof(__pyx_k_initial_pos), 1, 1, 1}, - {&__pyx_kp_state_name, __pyx_k_state_name, sizeof(__pyx_k_state_name), 1, 1, 1}, - {&__pyx_kp_value, __pyx_k_value, sizeof(__pyx_k_value), 1, 1, 1}, - {&__pyx_kp_text, __pyx_k_text, sizeof(__pyx_k_text), 1, 1, 1}, - {&__pyx_kp_Errors, __pyx_k_Errors, sizeof(__pyx_k_Errors), 1, 1, 1}, - {&__pyx_kp_Regexps, __pyx_k_Regexps, sizeof(__pyx_k_Regexps), 1, 1, 1}, - {&__pyx_kp_BOL, __pyx_k_BOL, sizeof(__pyx_k_BOL), 1, 1, 1}, - {&__pyx_kp_EOL, __pyx_k_EOL, sizeof(__pyx_k_EOL), 1, 1, 1}, - {&__pyx_kp_EOF, __pyx_k_EOF, sizeof(__pyx_k_EOF), 1, 1, 1}, - {&__pyx_kp_Scanner, __pyx_k_Scanner, sizeof(__pyx_k_Scanner), 0, 1, 1}, - {&__pyx_kp_buffer, __pyx_k_buffer, sizeof(__pyx_k_buffer), 1, 1, 1}, - {&__pyx_kp_buf_start_pos, __pyx_k_buf_start_pos, sizeof(__pyx_k_buf_start_pos), 1, 1, 1}, - {&__pyx_kp_next_pos, __pyx_k_next_pos, sizeof(__pyx_k_next_pos), 1, 1, 1}, - {&__pyx_kp_cur_pos, __pyx_k_cur_pos, sizeof(__pyx_k_cur_pos), 1, 1, 1}, - {&__pyx_kp_cur_line, __pyx_k_cur_line, sizeof(__pyx_k_cur_line), 1, 1, 1}, - {&__pyx_kp_cur_line_start, __pyx_k_cur_line_start, sizeof(__pyx_k_cur_line_start), 1, 1, 1}, - {&__pyx_kp_start_pos, __pyx_k_start_pos, sizeof(__pyx_k_start_pos), 1, 1, 1}, - {&__pyx_kp_start_line, __pyx_k_start_line, sizeof(__pyx_k_start_line), 1, 1, 1}, - {&__pyx_kp_start_col, __pyx_k_start_col, sizeof(__pyx_k_start_col), 1, 1, 1}, - {&__pyx_kp_initial_state, __pyx_k_initial_state, sizeof(__pyx_k_initial_state), 1, 1, 1}, - {&__pyx_kp_queue, __pyx_k_queue, sizeof(__pyx_k_queue), 1, 1, 1}, - {&__pyx_kp_trace, __pyx_k_trace, sizeof(__pyx_k_trace), 1, 1, 1}, - {&__pyx_kp___init__, __pyx_k___init__, sizeof(__pyx_k___init__), 1, 1, 1}, - {&__pyx_kp_read, __pyx_k_read, sizeof(__pyx_k_read), 1, 1, 1}, - {&__pyx_kp_scan_a_token, __pyx_k_scan_a_token, sizeof(__pyx_k_scan_a_token), 1, 1, 1}, - {&__pyx_kp_run_machine, __pyx_k_run_machine, sizeof(__pyx_k_run_machine), 1, 1, 1}, - {&__pyx_kp_run_machine_inlined, __pyx_k_run_machine_inlined, sizeof(__pyx_k_run_machine_inlined), 1, 1, 1}, - {&__pyx_kp_next_char, __pyx_k_next_char, sizeof(__pyx_k_next_char), 1, 1, 1}, - {&__pyx_kp_position, __pyx_k_position, sizeof(__pyx_k_position), 1, 1, 1}, - {&__pyx_kp_begin, __pyx_k_begin, sizeof(__pyx_k_begin), 1, 1, 1}, - {&__pyx_kp_produce, __pyx_k_produce, sizeof(__pyx_k_produce), 1, 1, 1}, - {&__pyx_kp_eof, __pyx_k_eof, sizeof(__pyx_k_eof), 1, 1, 1}, - {&__pyx_kp_6, __pyx_k_6, sizeof(__pyx_k_6), 0, 1, 0}, - {&__pyx_kp_cur_char, __pyx_k_cur_char, sizeof(__pyx_k_cur_char), 1, 1, 1}, - {&__pyx_kp_input_state, __pyx_k_input_state, sizeof(__pyx_k_input_state), 1, 1, 1}, - {&__pyx_kp_perform, __pyx_k_perform, sizeof(__pyx_k_perform), 1, 1, 1}, - {&__pyx_kp_UnrecognizedInput, __pyx_k_UnrecognizedInput, sizeof(__pyx_k_UnrecognizedInput), 1, 1, 1}, - {&__pyx_kp_state, __pyx_k_state, sizeof(__pyx_k_state), 1, 1, 1}, - {&__pyx_kp_backup_state, __pyx_k_backup_state, sizeof(__pyx_k_backup_state), 1, 1, 1}, - {&__pyx_kp_transition, __pyx_k_transition, sizeof(__pyx_k_transition), 1, 1, 1}, - {&__pyx_kp_back_up, __pyx_k_back_up, sizeof(__pyx_k_back_up), 1, 1, 1}, - {&__pyx_kp_11, __pyx_k_11, sizeof(__pyx_k_11), 0, 1, 0}, - {&__pyx_kp_12, __pyx_k_12, sizeof(__pyx_k_12), 0, 1, 0}, - {&__pyx_kp_get, __pyx_k_get, sizeof(__pyx_k_get), 1, 1, 1}, - {&__pyx_kp_13, __pyx_k_13, sizeof(__pyx_k_13), 0, 1, 0}, - {&__pyx_kp_15, __pyx_k_15, sizeof(__pyx_k_15), 0, 1, 0}, - {&__pyx_kp_20, __pyx_k_20, sizeof(__pyx_k_20), 0, 1, 0}, - {&__pyx_kp_read_char, __pyx_k_read_char, sizeof(__pyx_k_read_char), 1, 1, 1}, - {&__pyx_kp_get_initial_state, __pyx_k_get_initial_state, sizeof(__pyx_k_get_initial_state), 1, 1, 1}, - {&__pyx_kp_append, __pyx_k_append, sizeof(__pyx_k_append), 1, 1, 1}, - {&__pyx_kp_1, __pyx_k_1, sizeof(__pyx_k_1), 0, 0, 0}, - {&__pyx_kp_5, __pyx_k_5, sizeof(__pyx_k_5), 0, 0, 0}, - {&__pyx_kp_2, __pyx_k_2, sizeof(__pyx_k_2), 0, 0, 0}, - {&__pyx_kp_3, __pyx_k_3, sizeof(__pyx_k_3), 0, 0, 0}, - {&__pyx_kp_4, __pyx_k_4, sizeof(__pyx_k_4), 0, 0, 0}, - {&__pyx_kp_7, __pyx_k_7, sizeof(__pyx_k_7), 0, 0, 0}, - {&__pyx_kp_8, __pyx_k_8, sizeof(__pyx_k_8), 0, 0, 0}, - {&__pyx_kp_9, __pyx_k_9, sizeof(__pyx_k_9), 0, 0, 0}, - {&__pyx_kp_10, __pyx_k_10, sizeof(__pyx_k_10), 0, 0, 0}, - {&__pyx_kp_14, __pyx_k_14, sizeof(__pyx_k_14), 0, 0, 0}, - {&__pyx_kp_16, __pyx_k_16, sizeof(__pyx_k_16), 0, 0, 0}, - {&__pyx_kp_17, __pyx_k_17, sizeof(__pyx_k_17), 0, 0, 0}, - {&__pyx_kp_18, __pyx_k_18, sizeof(__pyx_k_18), 0, 0, 0}, - {&__pyx_kp_19, __pyx_k_19, sizeof(__pyx_k_19), 0, 0, 0}, - {&__pyx_kp_21, __pyx_k_21, sizeof(__pyx_k_21), 0, 0, 0}, - {&__pyx_kp_23, __pyx_k_23, sizeof(__pyx_k_23), 0, 0, 0}, - {&__pyx_kp_22, __pyx_k_22, sizeof(__pyx_k_22), 0, 0, 0}, - {&__pyx_kp_24, __pyx_k_24, sizeof(__pyx_k_24), 0, 0, 0}, - {&__pyx_kp_25, __pyx_k_25, sizeof(__pyx_k_25), 0, 0, 0}, - {&__pyx_kp_26, __pyx_k_26, sizeof(__pyx_k_26), 0, 0, 0}, - {&__pyx_kp_27, __pyx_k_27, sizeof(__pyx_k_27), 0, 0, 0}, - {0, 0, 0, 0, 0, 0} -}; -static int __Pyx_InitCachedBuiltins(void) { - return 0; - return -1; -} - -static int __Pyx_InitGlobals(void) { - __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; - __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; - __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; - __pyx_int_0x1000 = PyInt_FromLong(0x1000); if (unlikely(!__pyx_int_0x1000)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; - __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; - __pyx_int_4 = PyInt_FromLong(4); if (unlikely(!__pyx_int_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; - __pyx_int_3 = PyInt_FromLong(3); if (unlikely(!__pyx_int_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; - __pyx_int_5 = PyInt_FromLong(5); if (unlikely(!__pyx_int_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; - __pyx_int_20 = PyInt_FromLong(20); if (unlikely(!__pyx_int_20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; - if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; - return 0; - __pyx_L1_error:; - return -1; -} - -#if PY_MAJOR_VERSION < 3 -PyMODINIT_FUNC initScanners(void); /*proto*/ -PyMODINIT_FUNC initScanners(void) -#else -PyMODINIT_FUNC PyInit_Scanners(void); /*proto*/ -PyMODINIT_FUNC PyInit_Scanners(void) -#endif -{ - PyObject *__pyx_1 = 0; - PyObject *__pyx_2 = 0; - PyObject *__pyx_3 = 0; - PyObject *__pyx_4 = 0; - int __pyx_5; - __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - /*--- Library function declarations ---*/ - __pyx_init_filenames(); - /*--- Initialize various global constants etc. ---*/ - if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - /*--- Module creation code ---*/ - #if PY_MAJOR_VERSION < 3 - __pyx_m = Py_InitModule4("Scanners", __pyx_methods, 0, 0, PYTHON_API_VERSION); - #else - __pyx_m = PyModule_Create(&__pyx_moduledef); - #endif - if (!__pyx_m) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; - #if PY_MAJOR_VERSION < 3 - Py_INCREF(__pyx_m); - #endif - __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); - if (!__pyx_b) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; - if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}; - /*--- Builtin init code ---*/ - if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_skip_dispatch = 0; - /*--- Global init code ---*/ - /*--- Function export code ---*/ - /*--- Type init code ---*/ - /*--- Type import code ---*/ - /*--- Function import code ---*/ - /*--- Execution code ---*/ - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":10 - * #======================================================================= - * - * import Errors # <<<<<<<<<<<<<< - * from Regexps import BOL, EOL, EOF - * - */ - __pyx_1 = __Pyx_Import(__pyx_kp_Errors, 0); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (PyObject_SetAttr(__pyx_m, __pyx_kp_Errors, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 10; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":11 - * - * import Errors - * from Regexps import BOL, EOL, EOF # <<<<<<<<<<<<<< - * - * class Scanner: - */ - __pyx_1 = PyList_New(3); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_INCREF(__pyx_kp_BOL); - PyList_SET_ITEM(__pyx_1, 0, __pyx_kp_BOL); - Py_INCREF(__pyx_kp_EOL); - PyList_SET_ITEM(__pyx_1, 1, __pyx_kp_EOL); - Py_INCREF(__pyx_kp_EOF); - PyList_SET_ITEM(__pyx_1, 2, __pyx_kp_EOF); - __pyx_2 = __Pyx_Import(__pyx_kp_Regexps, ((PyObject *)__pyx_1)); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0; - __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_BOL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (PyObject_SetAttr(__pyx_m, __pyx_kp_BOL, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_EOL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (PyObject_SetAttr(__pyx_m, __pyx_kp_EOL, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_EOF); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (PyObject_SetAttr(__pyx_m, __pyx_kp_EOF, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 11; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - Py_DECREF(__pyx_2); __pyx_2 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":13 - * from Regexps import BOL, EOL, EOF - * - * class Scanner: # <<<<<<<<<<<<<< - * """ - * A Scanner is used to read tokens from a stream of characters - */ - __pyx_2 = PyDict_New(); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - if (PyDict_SetItemString(((PyObject *)__pyx_2), "__doc__", __pyx_kp_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_1 = __Pyx_CreateClass(((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_2), __pyx_kp_Scanner, "Cython.Plex.Scanners"); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":45 - * """ - * - * lexicon = None # Lexicon # <<<<<<<<<<<<<< - * stream = None # file-like object - * name = '' - */ - if (PyObject_SetAttr(__pyx_1, __pyx_kp_lexicon, Py_None) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":46 - * - * lexicon = None # Lexicon - * stream = None # file-like object # <<<<<<<<<<<<<< - * name = '' - * buffer = '' - */ - if (PyObject_SetAttr(__pyx_1, __pyx_kp_stream, Py_None) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":47 - * lexicon = None # Lexicon - * stream = None # file-like object - * name = '' # <<<<<<<<<<<<<< - * buffer = '' - * buf_start_pos = 0 # position in input of start of buffer - */ - if (PyObject_SetAttr(__pyx_1, __pyx_kp_name, __pyx_kp_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":48 - * 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 - */ - if (PyObject_SetAttr(__pyx_1, __pyx_kp_buffer, __pyx_kp_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":49 - * 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 - */ - if (PyObject_SetAttr(__pyx_1, __pyx_kp_buf_start_pos, __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":50 - * 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 - */ - if (PyObject_SetAttr(__pyx_1, __pyx_kp_next_pos, __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":51 - * 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 - */ - if (PyObject_SetAttr(__pyx_1, __pyx_kp_cur_pos, __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":52 - * 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 - */ - if (PyObject_SetAttr(__pyx_1, __pyx_kp_cur_line, __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 52; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":53 - * 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 - */ - if (PyObject_SetAttr(__pyx_1, __pyx_kp_cur_line_start, __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":54 - * 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 - */ - if (PyObject_SetAttr(__pyx_1, __pyx_kp_start_pos, __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":55 - * 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 - */ - if (PyObject_SetAttr(__pyx_1, __pyx_kp_start_line, __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":56 - * 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 - */ - if (PyObject_SetAttr(__pyx_1, __pyx_kp_start_col, __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":57 - * 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 - */ - if (PyObject_SetAttr(__pyx_1, __pyx_kp_text, Py_None) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":58 - * 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 - */ - if (PyObject_SetAttr(__pyx_1, __pyx_kp_initial_state, Py_None) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":59 - * 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 - */ - if (PyObject_SetAttr(__pyx_1, __pyx_kp_state_name, __pyx_kp_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":60 - * initial_state = None # Node - * state_name = '' # Name of initial state - * queue = None # list of tokens to be returned # <<<<<<<<<<<<<< - * trace = 0 - * - */ - if (PyObject_SetAttr(__pyx_1, __pyx_kp_queue, Py_None) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":61 - * state_name = '' # Name of initial state - * queue = None # list of tokens to be returned - * trace = 0 # <<<<<<<<<<<<<< - * - * def __init__(self, lexicon, stream, name = '', initial_pos = None): - */ - if (PyObject_SetAttr(__pyx_1, __pyx_kp_trace, __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":63 - * trace = 0 - * - * def __init__(self, lexicon, stream, name = '', initial_pos = None): # <<<<<<<<<<<<<< - * """ - * Scanner(lexicon, stream, name = '') - */ - __pyx_3 = PyCFunction_New(&__pyx_mdef_6Cython_4Plex_8Scanners_7Scanner___init__, 0); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_4 = PyMethod_New(__pyx_3, 0, __pyx_1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_3); __pyx_3 = 0; - if (PyObject_SetAttr(__pyx_1, __pyx_kp___init__, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_4); __pyx_4 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":90 - * self.cur_line, self.cur_line_start = initial_pos[1], -initial_pos[2] - * - * def read(self): # <<<<<<<<<<<<<< - * """ - * Read the next lexical token from the stream and return a - */ - __pyx_3 = PyCFunction_New(&__pyx_mdef_6Cython_4Plex_8Scanners_7Scanner_read, 0); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_4 = PyMethod_New(__pyx_3, 0, __pyx_1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_3); __pyx_3 = 0; - if (PyObject_SetAttr(__pyx_1, __pyx_kp_read, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_4); __pyx_4 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":111 - * return result - * - * def scan_a_token(self): # <<<<<<<<<<<<<< - * """ - * Read the next input sequence recognised by the machine - */ - __pyx_3 = PyCFunction_New(&__pyx_mdef_6Cython_4Plex_8Scanners_7Scanner_scan_a_token, 0); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_4 = PyMethod_New(__pyx_3, 0, __pyx_1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_3); __pyx_3 = 0; - if (PyObject_SetAttr(__pyx_1, __pyx_kp_scan_a_token, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_4); __pyx_4 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":140 - * raise Errors.UnrecognizedInput(self, self.state_name) - * - * def run_machine(self): # <<<<<<<<<<<<<< - * """ - * Run the machine until no more transitions are possible. - */ - __pyx_3 = PyCFunction_New(&__pyx_mdef_6Cython_4Plex_8Scanners_7Scanner_run_machine, 0); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_4 = PyMethod_New(__pyx_3, 0, __pyx_1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_3); __pyx_3 = 0; - if (PyObject_SetAttr(__pyx_1, __pyx_kp_run_machine, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 140; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_4); __pyx_4 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":150 - * return self.back_up() - * - * def run_machine_inlined(self): # <<<<<<<<<<<<<< - * """ - * Inlined version of run_machine for speed. - */ - __pyx_3 = PyCFunction_New(&__pyx_mdef_6Cython_4Plex_8Scanners_7Scanner_run_machine_inlined, 0); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_4 = PyMethod_New(__pyx_3, 0, __pyx_1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_3); __pyx_3 = 0; - if (PyObject_SetAttr(__pyx_1, __pyx_kp_run_machine_inlined, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 150; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_4); __pyx_4 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":290 - * # return None - * - * def next_char(self): # <<<<<<<<<<<<<< - * input_state = self.input_state - * if self.trace: - */ - __pyx_3 = PyCFunction_New(&__pyx_mdef_6Cython_4Plex_8Scanners_7Scanner_next_char, 0); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_4 = PyMethod_New(__pyx_3, 0, __pyx_1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_3); __pyx_3 = 0; - if (PyObject_SetAttr(__pyx_1, __pyx_kp_next_char, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_4); __pyx_4 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":340 - * # return c - * - * def position(self): # <<<<<<<<<<<<<< - * """ - * Return a tuple (name, line, col) representing the location of - */ - __pyx_3 = PyCFunction_New(&__pyx_mdef_6Cython_4Plex_8Scanners_7Scanner_position, 0); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 340; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_4 = PyMethod_New(__pyx_3, 0, __pyx_1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 340; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_3); __pyx_3 = 0; - if (PyObject_SetAttr(__pyx_1, __pyx_kp_position, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 340; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_4); __pyx_4 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":351 - * 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 = ( - */ - __pyx_3 = PyCFunction_New(&__pyx_mdef_6Cython_4Plex_8Scanners_7Scanner_begin, 0); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_4 = PyMethod_New(__pyx_3, 0, __pyx_1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_3); __pyx_3 = 0; - if (PyObject_SetAttr(__pyx_1, __pyx_kp_begin, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_4); __pyx_4 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":357 - * self.state_name = state_name - * - * def produce(self, value, text = None): # <<<<<<<<<<<<<< - * """ - * Called from an action procedure, causes |value| to be returned - */ - __pyx_3 = PyCFunction_New(&__pyx_mdef_6Cython_4Plex_8Scanners_7Scanner_produce, 0); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_4 = PyMethod_New(__pyx_3, 0, __pyx_1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_3); __pyx_3 = 0; - if (PyObject_SetAttr(__pyx_1, __pyx_kp_produce, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_4); __pyx_4 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":372 - * self.queue.append((value, text)) - * - * def eof(self): # <<<<<<<<<<<<<< - * """ - * Override this method if you want something to be done at - */ - __pyx_3 = PyCFunction_New(&__pyx_mdef_6Cython_4Plex_8Scanners_7Scanner_eof, 0); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_4 = PyMethod_New(__pyx_3, 0, __pyx_1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_3); __pyx_3 = 0; - if (PyObject_SetAttr(__pyx_1, __pyx_kp_eof, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 372; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_4); __pyx_4 = 0; - if (PyObject_SetAttr(__pyx_m, __pyx_kp_Scanner, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 13; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_1); __pyx_1 = 0; - Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0; - - /* "/tmp/buildd/cython-0.10.3/Cython/Plex/Scanners.py":379 - * - * # For backward compatibility: - * setattr(Scanner, "yield", Scanner.produce) # <<<<<<<<<<<<<< - */ - __pyx_3 = __Pyx_GetName(__pyx_m, __pyx_kp_Scanner); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_4 = __Pyx_GetName(__pyx_m, __pyx_kp_Scanner); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - __pyx_1 = PyObject_GetAttr(__pyx_4, __pyx_kp_produce); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_4); __pyx_4 = 0; - __pyx_5 = PyObject_SetAttr(__pyx_3, __pyx_kp_6, __pyx_1); if (unlikely(__pyx_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 379; __pyx_clineno = __LINE__; goto __pyx_L1_error;} - Py_DECREF(__pyx_3); __pyx_3 = 0; - Py_DECREF(__pyx_1); __pyx_1 = 0; - #if PY_MAJOR_VERSION < 3 - return; - #else - return __pyx_m; - #endif - __pyx_L1_error:; - Py_XDECREF(__pyx_1); - Py_XDECREF(__pyx_2); - Py_XDECREF(__pyx_3); - Py_XDECREF(__pyx_4); - __Pyx_AddTraceback("Cython.Plex.Scanners"); - #if PY_MAJOR_VERSION >= 3 - return NULL; - #endif -} - -static const char *__pyx_filenames[] = { - "Scanners.py", -}; - -/* Runtime support code */ - -static void __pyx_init_filenames(void) { - __pyx_f = __pyx_filenames; -} - -static void __Pyx_RaiseDoubleKeywordsError( - const char* func_name, - PyObject* kw_name) -{ - PyErr_Format(PyExc_TypeError, - #if PY_MAJOR_VERSION >= 3 - "%s() got multiple values for keyword argument '%U'", func_name, kw_name); - #else - "%s() got multiple values for keyword argument '%s'", func_name, - PyString_AS_STRING(kw_name)); - #endif -} - -static void __Pyx_RaiseArgtupleInvalid( - const char* func_name, - int exact, - Py_ssize_t num_min, - Py_ssize_t num_max, - Py_ssize_t num_found) -{ - Py_ssize_t num_expected; - const char *number, *more_or_less; - - if (num_found < num_min) { - num_expected = num_min; - more_or_less = "at least"; - } else { - num_expected = num_max; - more_or_less = "at most"; - } - if (exact) { - more_or_less = "exactly"; - } - number = (num_expected == 1) ? "" : "s"; - PyErr_Format(PyExc_TypeError, - #if PY_VERSION_HEX < 0x02050000 - "%s() takes %s %d positional argument%s (%d given)", - #else - "%s() takes %s %zd positional argument%s (%zd given)", - #endif - func_name, more_or_less, num_expected, number, num_found); -} - -static int __Pyx_ParseOptionalKeywords( - PyObject *kwds, - PyObject **argnames[], - PyObject *kwds2, - PyObject *values[], - Py_ssize_t num_pos_args, - const char* function_name) -{ - PyObject *key = 0, *value = 0; - Py_ssize_t pos = 0; - PyObject*** name; - PyObject*** first_kw_arg = argnames + num_pos_args; - - while (PyDict_Next(kwds, &pos, &key, &value)) { - #if PY_MAJOR_VERSION < 3 - if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) { - #else - if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) { - #endif - goto invalid_keyword_type; - } else { - name = argnames; - while (*name && (**name != key)) name++; - if (*name) { - if (name < first_kw_arg) goto arg_passed_twice; - values[name-argnames] = value; - } else { - for (name = first_kw_arg; *name; name++) { - #if PY_MAJOR_VERSION >= 3 - if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) && - PyUnicode_Compare(**name, key) == 0) break; - #else - if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) && - strcmp(PyString_AS_STRING(**name), - PyString_AS_STRING(key)) == 0) break; - #endif - } - if (*name) { - values[name-argnames] = value; - } else { - /* unexpected keyword found */ - for (name=argnames; name != first_kw_arg; name++) { - if (**name == key) goto arg_passed_twice; - #if PY_MAJOR_VERSION >= 3 - if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) && - PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice; - #else - if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) && - strcmp(PyString_AS_STRING(**name), - PyString_AS_STRING(key)) == 0) goto arg_passed_twice; - #endif - } - if (kwds2) { - if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; - } else { - goto invalid_keyword; - } - } - } - } - } - return 0; -arg_passed_twice: - __Pyx_RaiseDoubleKeywordsError(function_name, **name); - goto bad; -invalid_keyword_type: - PyErr_Format(PyExc_TypeError, - "%s() keywords must be strings", function_name); - goto bad; -invalid_keyword: - PyErr_Format(PyExc_TypeError, - #if PY_MAJOR_VERSION < 3 - "%s() got an unexpected keyword argument '%s'", - function_name, PyString_AsString(key)); - #else - "%s() got an unexpected keyword argument '%U'", - function_name, key); - #endif -bad: - return -1; -} - - - -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(__pyx_b, "__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(__pyx_m); - 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; -} - -static PyObject *__Pyx_CreateClass( - PyObject *bases, PyObject *dict, PyObject *name, char *modname) -{ - PyObject *py_modname; - PyObject *result = 0; - - #if PY_MAJOR_VERSION < 3 - py_modname = PyString_FromString(modname); - #else - py_modname = PyUnicode_FromString(modname); - #endif - if (!py_modname) - goto bad; - if (PyDict_SetItemString(dict, "__module__", py_modname) < 0) - goto bad; - #if PY_MAJOR_VERSION < 3 - result = PyClass_New(bases, dict, name); - #else - result = PyObject_CallFunctionObjArgs((PyObject *)&PyType_Type, name, bases, dict, NULL); - #endif -bad: - Py_XDECREF(py_modname); - return result; -} - -static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) { - PyObject *result; - result = PyObject_GetAttr(dict, name); - if (!result) - PyErr_SetObject(PyExc_NameError, name); - return result; -} - -static PyObject *__Pyx_UnpackItem(PyObject *iter, Py_ssize_t index) { - PyObject *item; - if (!(item = PyIter_Next(iter))) { - if (!PyErr_Occurred()) { - PyErr_Format(PyExc_ValueError, - #if PY_VERSION_HEX < 0x02050000 - "need more than %d values to unpack", (int)index); - #else - "need more than %zd values to unpack", index); - #endif - } - } - return item; -} - -static int __Pyx_EndUnpack(PyObject *iter) { - PyObject *item; - if ((item = PyIter_Next(iter))) { - Py_DECREF(item); - PyErr_SetString(PyExc_ValueError, "too many values to unpack"); - return -1; - } - else if (!PyErr_Occurred()) - return 0; - else - return -1; -} - -#if PY_MAJOR_VERSION < 3 -static PyObject *__Pyx_GetStdout(void) { - PyObject *f = PySys_GetObject("stdout"); - if (!f) { - PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout"); - } - return f; -} - -static int __Pyx_Print(PyObject *arg_tuple, int newline) { - PyObject *f; - PyObject* v; - int i; - - if (!(f = __Pyx_GetStdout())) - return -1; - for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) { - if (PyFile_SoftSpace(f, 1)) { - if (PyFile_WriteString(" ", f) < 0) - return -1; - } - v = PyTuple_GET_ITEM(arg_tuple, i); - 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); - } - } - if (newline) { - if (PyFile_WriteString("\n", f) < 0) - return -1; - PyFile_SoftSpace(f, 0); - } - return 0; -} - -#else /* Python 3 has a print function */ -static int __Pyx_Print(PyObject *arg_tuple, int newline) { - PyObject* kwargs = 0; - PyObject* result = 0; - PyObject* end_string; - if (!__pyx_print) { - __pyx_print = PyObject_GetAttrString(__pyx_b, "print"); - if (!__pyx_print) - return -1; - } - if (!newline) { - if (!__pyx_print_kwargs) { - __pyx_print_kwargs = PyDict_New(); - if (!__pyx_print_kwargs) - return -1; - end_string = PyUnicode_FromStringAndSize(" ", 1); - if (!end_string) - return -1; - if (PyDict_SetItemString(__pyx_print_kwargs, "end", end_string) < 0) { - Py_DECREF(end_string); - return -1; - } - Py_DECREF(end_string); - } - kwargs = __pyx_print_kwargs; - } - result = PyObject_Call(__pyx_print, arg_tuple, kwargs); - if (!result) - return -1; - Py_DECREF(result); - return 0; -} -#endif - -static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) { - Py_XINCREF(type); - Py_XINCREF(value); - Py_XINCREF(tb); - /* First, check the traceback argument, replacing None with NULL. */ - if (tb == Py_None) { - Py_DECREF(tb); - tb = 0; - } - else if (tb != NULL && !PyTraceBack_Check(tb)) { - PyErr_SetString(PyExc_TypeError, - "raise: arg 3 must be a traceback or None"); - goto raise_error; - } - /* Next, replace a missing value with None */ - if (value == NULL) { - value = Py_None; - Py_INCREF(value); - } - #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 != Py_None) { - PyErr_SetString(PyExc_TypeError, - "instance exception may not have a separate value"); - goto raise_error; - } - /* Normalize to raise , */ - Py_DECREF(value); - value = type; - #if PY_VERSION_HEX < 0x02050000 - if (PyInstance_Check(type)) { - type = (PyObject*) ((PyInstanceObject*)type)->in_class; - Py_INCREF(type); - } - else { - type = 0; - PyErr_SetString(PyExc_TypeError, - "raise: exception must be an old-style class or instance"); - goto raise_error; - } - #else - type = (PyObject*) Py_TYPE(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 - } - __Pyx_ErrRestore(type, value, tb); - return; -raise_error: - Py_XDECREF(value); - Py_XDECREF(type); - Py_XDECREF(tb); - return; -} - -static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) { - PyObject *tmp_type, *tmp_value, *tmp_tb; - PyThreadState *tstate = PyThreadState_GET(); - - tmp_type = tstate->curexc_type; - tmp_value = tstate->curexc_value; - tmp_tb = tstate->curexc_traceback; - tstate->curexc_type = type; - tstate->curexc_value = value; - tstate->curexc_traceback = tb; - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -} - -static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) { - PyThreadState *tstate = PyThreadState_GET(); - *type = tstate->curexc_type; - *value = tstate->curexc_value; - *tb = tstate->curexc_traceback; - - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; -} - - -#include "compile.h" -#include "frameobject.h" -#include "traceback.h" - -static void __Pyx_AddTraceback(const char *funcname) { - PyObject *py_srcfile = 0; - PyObject *py_funcname = 0; - PyObject *py_globals = 0; - PyObject *empty_string = 0; - PyCodeObject *py_code = 0; - PyFrameObject *py_frame = 0; - - #if PY_MAJOR_VERSION < 3 - py_srcfile = PyString_FromString(__pyx_filename); - #else - py_srcfile = PyUnicode_FromString(__pyx_filename); - #endif - if (!py_srcfile) goto bad; - if (__pyx_clineno) { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, __pyx_clineno); - #else - py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, __pyx_clineno); - #endif - } - else { - #if PY_MAJOR_VERSION < 3 - py_funcname = PyString_FromString(funcname); - #else - py_funcname = PyUnicode_FromString(funcname); - #endif - } - if (!py_funcname) goto bad; - py_globals = PyModule_GetDict(__pyx_m); - if (!py_globals) goto bad; - #if PY_MAJOR_VERSION < 3 - empty_string = PyString_FromStringAndSize("", 0); - #else - empty_string = PyBytes_FromStringAndSize("", 0); - #endif - if (!empty_string) goto bad; - py_code = PyCode_New( - 0, /*int argcount,*/ - #if PY_MAJOR_VERSION >= 3 - 0, /*int kwonlyargcount,*/ - #endif - 0, /*int nlocals,*/ - 0, /*int stacksize,*/ - 0, /*int flags,*/ - empty_string, /*PyObject *code,*/ - __pyx_empty_tuple, /*PyObject *consts,*/ - __pyx_empty_tuple, /*PyObject *names,*/ - __pyx_empty_tuple, /*PyObject *varnames,*/ - __pyx_empty_tuple, /*PyObject *freevars,*/ - __pyx_empty_tuple, /*PyObject *cellvars,*/ - py_srcfile, /*PyObject *filename,*/ - py_funcname, /*PyObject *name,*/ - __pyx_lineno, /*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 = __pyx_lineno; - PyTraceBack_Here(py_frame); -bad: - Py_XDECREF(py_srcfile); - Py_XDECREF(py_funcname); - Py_XDECREF(empty_string); - Py_XDECREF(py_code); - Py_XDECREF(py_frame); -} - -static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { - while (t->p) { - #if PY_MAJOR_VERSION < 3 - if (t->is_unicode && (!t->is_identifier)) { - *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); - } else if (t->intern) { - *t->p = PyString_InternFromString(t->s); - } else { - *t->p = PyString_FromStringAndSize(t->s, t->n - 1); - } - #else /* Python 3+ has unicode identifiers */ - if (t->is_identifier || (t->is_unicode && t->intern)) { - *t->p = PyUnicode_InternFromString(t->s); - } else if (t->is_unicode) { - *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); - } else { - *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); - } - #endif - if (!*t->p) - return -1; - ++t; - } - return 0; -} - -/* Type Conversion Functions */ - -static INLINE Py_ssize_t __pyx_PyIndex_AsSsize_t(PyObject* b) { - Py_ssize_t ival; - PyObject* x = PyNumber_Index(b); - if (!x) return -1; - ival = PyInt_AsSsize_t(x); - Py_DECREF(x); - return ival; -} - -static INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { - if (x == Py_True) return 1; - else if (x == Py_False) return 0; - else return PyObject_IsTrue(x); -} - -static INLINE PY_LONG_LONG __pyx_PyInt_AsLongLong(PyObject* x) { - if (PyInt_CheckExact(x)) { - return PyInt_AS_LONG(x); - } - else if (PyLong_CheckExact(x)) { - return PyLong_AsLongLong(x); - } - else { - PY_LONG_LONG val; - PyObject* tmp = PyNumber_Int(x); if (!tmp) return (PY_LONG_LONG)-1; - val = __pyx_PyInt_AsLongLong(tmp); - Py_DECREF(tmp); - return val; - } -} - -static INLINE unsigned PY_LONG_LONG __pyx_PyInt_AsUnsignedLongLong(PyObject* x) { - if (PyInt_CheckExact(x)) { - long val = PyInt_AS_LONG(x); - if (unlikely(val < 0)) { - PyErr_SetString(PyExc_TypeError, "Negative assignment to unsigned type."); - return (unsigned PY_LONG_LONG)-1; - } - return val; - } - else if (PyLong_CheckExact(x)) { - return PyLong_AsUnsignedLongLong(x); - } - else { - PY_LONG_LONG val; - PyObject* tmp = PyNumber_Int(x); if (!tmp) return (PY_LONG_LONG)-1; - val = __pyx_PyInt_AsUnsignedLongLong(tmp); - Py_DECREF(tmp); - return val; - } -} - - -static INLINE unsigned char __pyx_PyInt_unsigned_char(PyObject* x) { - if (sizeof(unsigned char) < sizeof(long)) { - long long_val = __pyx_PyInt_AsLong(x); - unsigned char val = (unsigned char)long_val; - if (unlikely((val != long_val) || (long_val < 0))) { - PyErr_SetString(PyExc_OverflowError, "value too large to convert to unsigned char"); - return (unsigned char)-1; - } - return val; - } - else { - return __pyx_PyInt_AsLong(x); - } -} - -static INLINE unsigned short __pyx_PyInt_unsigned_short(PyObject* x) { - if (sizeof(unsigned short) < sizeof(long)) { - long long_val = __pyx_PyInt_AsLong(x); - unsigned short val = (unsigned short)long_val; - if (unlikely((val != long_val) || (long_val < 0))) { - PyErr_SetString(PyExc_OverflowError, "value too large to convert to unsigned short"); - return (unsigned short)-1; - } - return val; - } - else { - return __pyx_PyInt_AsLong(x); - } -} - -static INLINE char __pyx_PyInt_char(PyObject* x) { - if (sizeof(char) < sizeof(long)) { - long long_val = __pyx_PyInt_AsLong(x); - char val = (char)long_val; - if (unlikely((val != long_val) )) { - PyErr_SetString(PyExc_OverflowError, "value too large to convert to char"); - return (char)-1; - } - return val; - } - else { - return __pyx_PyInt_AsLong(x); - } -} - -static INLINE short __pyx_PyInt_short(PyObject* x) { - if (sizeof(short) < sizeof(long)) { - long long_val = __pyx_PyInt_AsLong(x); - short val = (short)long_val; - if (unlikely((val != long_val) )) { - PyErr_SetString(PyExc_OverflowError, "value too large to convert to short"); - return (short)-1; - } - return val; - } - else { - return __pyx_PyInt_AsLong(x); - } -} - -static INLINE int __pyx_PyInt_int(PyObject* x) { - if (sizeof(int) < sizeof(long)) { - long long_val = __pyx_PyInt_AsLong(x); - int val = (int)long_val; - if (unlikely((val != long_val) )) { - PyErr_SetString(PyExc_OverflowError, "value too large to convert to int"); - return (int)-1; - } - return val; - } - else { - return __pyx_PyInt_AsLong(x); - } -} - -static INLINE long __pyx_PyInt_long(PyObject* x) { - if (sizeof(long) < sizeof(long)) { - long long_val = __pyx_PyInt_AsLong(x); - long val = (long)long_val; - if (unlikely((val != long_val) )) { - PyErr_SetString(PyExc_OverflowError, "value too large to convert to long"); - return (long)-1; - } - return val; - } - else { - return __pyx_PyInt_AsLong(x); - } -} - -static INLINE signed char __pyx_PyInt_signed_char(PyObject* x) { - if (sizeof(signed char) < sizeof(long)) { - long long_val = __pyx_PyInt_AsLong(x); - signed char val = (signed char)long_val; - if (unlikely((val != long_val) )) { - PyErr_SetString(PyExc_OverflowError, "value too large to convert to signed char"); - return (signed char)-1; - } - return val; - } - else { - return __pyx_PyInt_AsLong(x); - } -} - -static INLINE signed short __pyx_PyInt_signed_short(PyObject* x) { - if (sizeof(signed short) < sizeof(long)) { - long long_val = __pyx_PyInt_AsLong(x); - signed short val = (signed short)long_val; - if (unlikely((val != long_val) )) { - PyErr_SetString(PyExc_OverflowError, "value too large to convert to signed short"); - return (signed short)-1; - } - return val; - } - else { - return __pyx_PyInt_AsLong(x); - } -} - -static INLINE signed int __pyx_PyInt_signed_int(PyObject* x) { - if (sizeof(signed int) < sizeof(long)) { - long long_val = __pyx_PyInt_AsLong(x); - signed int val = (signed int)long_val; - if (unlikely((val != long_val) )) { - PyErr_SetString(PyExc_OverflowError, "value too large to convert to signed int"); - return (signed int)-1; - } - return val; - } - else { - return __pyx_PyInt_AsLong(x); - } -} - -static INLINE signed long __pyx_PyInt_signed_long(PyObject* x) { - if (sizeof(signed long) < sizeof(long)) { - long long_val = __pyx_PyInt_AsLong(x); - signed long val = (signed long)long_val; - if (unlikely((val != long_val) )) { - PyErr_SetString(PyExc_OverflowError, "value too large to convert to signed long"); - return (signed long)-1; - } - return val; - } - else { - return __pyx_PyInt_AsLong(x); - } -} - -static INLINE long double __pyx_PyInt_long_double(PyObject* x) { - if (sizeof(long double) < sizeof(long)) { - long long_val = __pyx_PyInt_AsLong(x); - long double val = (long double)long_val; - if (unlikely((val != long_val) )) { - PyErr_SetString(PyExc_OverflowError, "value too large to convert to long double"); - return (long double)-1; - } - return val; - } - else { - return __pyx_PyInt_AsLong(x); - } -} - diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Plex/Scanners.pxd /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Plex/Scanners.pxd --- cython-0.10.3/Cython/Plex/Scanners.pxd 1970-01-01 01:00:00.000000000 +0100 +++ cython-0.11.2/Cython/Plex/Scanners.pxd 2009-05-20 16:37:46.000000000 +0100 @@ -0,0 +1,41 @@ +import cython + +cdef class Scanner: + + cdef public lexicon + cdef public stream + cdef public name + cdef public buffer + cdef public Py_ssize_t buf_start_pos + cdef public Py_ssize_t next_pos + cdef public Py_ssize_t cur_pos + cdef public Py_ssize_t cur_line + cdef public Py_ssize_t cur_line_start + cdef public Py_ssize_t start_pos + cdef public Py_ssize_t start_line + cdef public Py_ssize_t start_col + cdef public text + cdef public initial_state # int? + cdef public state_name + cdef public list queue + cdef public bint trace + cdef public cur_char + cdef public int input_state + + cdef public level + + @cython.locals(input_state=long) + cpdef next_char(self) + @cython.locals(queue=list) + cpdef tuple read(self) + cpdef tuple scan_a_token(self) + cpdef tuple position(self) + + @cython.locals(cur_pos=long, cur_line=long, cur_line_start=long, + input_state=long, next_pos=long, + buf_start_pos=long, buf_len=long, buf_index=long, + trace=bint, discard=long) + cpdef run_machine_inlined(self) + + cpdef begin(self, state) + cpdef produce(self, value, text = *) diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Plex/Scanners.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Plex/Scanners.py --- cython-0.10.3/Cython/Plex/Scanners.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Plex/Scanners.py 2009-05-20 16:37:46.000000000 +0100 @@ -10,7 +10,9 @@ import Errors from Regexps import BOL, EOL, EOF -class Scanner: +import cython + +class Scanner(object): """ A Scanner is used to read tokens from a stream of characters using the token set specified by a Plex.Lexicon. @@ -42,23 +44,23 @@ """ - 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 +# 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 = '', initial_pos = None): """ @@ -73,6 +75,19 @@ |name| is optional, and may be the name of the file being scanned or any other identifying string. """ + self.trace = 0 + + self.buffer = '' + self.buf_start_pos = 0 + self.next_pos = 0 + self.cur_pos = 0 + self.cur_line = 1 + self.start_pos = 0 + self.start_line = 0 + self.start_col = 0 + self.text = None + self.state_name = None + self.lexicon = lexicon self.stream = stream self.name = name @@ -117,12 +132,8 @@ 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 action is not None: if self.trace: print("Scanner: read: Performing %s %d:%d" % ( action, self.start_pos, self.cur_pos)) @@ -131,22 +142,12 @@ return (text, action) else: if self.cur_pos == self.start_pos: - if self.cur_char == EOL: + if self.cur_char is EOL: self.next_char() - if not self.cur_char or self.cur_char == EOF: + if self.cur_char is None or self.cur_char is 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. @@ -170,7 +171,7 @@ # Begin inlined self.save_for_backup() #action = state.action #@slow action = state['action'] #@fast - if action: + if action is not None: backup_state = ( action, cur_pos, cur_line, cur_line_start, cur_char, input_state, next_pos) # End inlined self.save_for_backup() @@ -232,7 +233,7 @@ if trace: #TRACE# print("blocked") #TRACE# # Begin inlined: action = self.back_up() - if backup_state: + if backup_state is not None: (action, cur_pos, cur_line, cur_line_start, cur_char, input_state, next_pos) = backup_state else: @@ -244,49 +245,12 @@ self.cur_line_start = cur_line_start self.cur_char = cur_char self.input_state = input_state - self.next_pos = next_pos + self.next_pos = next_pos if trace: #TRACE# - if action: #TRACE# - print("Doing " + action) #TRACE# + if action is not None: #TRACE# + print("Doing %s" % 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: @@ -317,26 +281,7 @@ 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 @@ -374,6 +319,3 @@ Override this method if you want something to be done at end of file. """ - -# For backward compatibility: -setattr(Scanner, "yield", Scanner.produce) diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Plex/Traditional.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Plex/Traditional.py --- cython-0.10.3/Cython/Plex/Traditional.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Plex/Traditional.py 2009-05-20 16:37:46.000000000 +0100 @@ -19,7 +19,7 @@ """ return REParser(s).parse_re() -class REParser: +class REParser(object): def __init__(self, s): self.s = s @@ -41,7 +41,7 @@ while self.c == '|': self.next() re_list.append(self.parse_seq()) - re = apply(Alt, tuple(re_list)) + re = Alt(*re_list) return re def parse_seq(self): @@ -49,7 +49,7 @@ re_list = [] while not self.end and not self.c in "|)": re_list.append(self.parse_mod()) - return apply(Seq, tuple(re_list)) + return Seq(*re_list) def parse_mod(self): """Parse a primitive regexp followed by *, +, ? modifiers.""" diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Plex/Transitions.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Plex/Transitions.py --- cython-0.10.3/Cython/Plex/Transitions.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Plex/Transitions.py 2009-05-20 16:37:46.000000000 +0100 @@ -6,11 +6,10 @@ # from copy import copy -import string from sys import maxint from types import TupleType -class TransitionMap: +class TransitionMap(object): """ A TransitionMap maps an input event to a set of states. An input event is one of: a range of character codes, @@ -89,10 +88,10 @@ """ return self.special.get('', none) - def items(self, + def iteritems(self, len = len): """ - Return the mapping as a list of ((code1, code2), state_set) and + Return the mapping as an iterable of ((code1, code2), state_set) and (special_event, state_set) pairs. """ result = [] @@ -108,10 +107,10 @@ result.append(((code0, code1), set)) code0 = code1 i = i + 2 - for event, set in self.special.items(): + for event, set in self.special.iteritems(): if set: result.append((event, set)) - return result + return iter(result) # ------------------- Private methods -------------------- @@ -178,10 +177,10 @@ map_strs.append(state_set_str(map[i])) i = i + 1 special_strs = {} - for event, set in self.special.items(): + for event, set in self.special.iteritems(): special_strs[event] = state_set_str(set) return "[%s]+%s" % ( - string.join(map_strs, ","), + ','.join(map_strs), special_strs ) @@ -200,7 +199,7 @@ 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(): + for event, set in self.special.iteritems(): if set: if not event: event = 'empty' @@ -239,15 +238,11 @@ # #def merge_state_sets(set1, set2): -# for state in set2.keys(): -# set1[state] = 1 +# 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, ",") + return "[%s]" % ','.join(["S%d" % state.number for state in set]) diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Runtime/refnanny.pyx /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Runtime/refnanny.pyx --- cython-0.10.3/Cython/Runtime/refnanny.pyx 1970-01-01 01:00:00.000000000 +0100 +++ cython-0.11.2/Cython/Runtime/refnanny.pyx 2009-05-20 16:37:46.000000000 +0100 @@ -0,0 +1,165 @@ +from python_ref cimport Py_INCREF, Py_DECREF, Py_XDECREF +from python_exc cimport PyObject, PyErr_Fetch, PyErr_Restore + + +loglevel = 0 +reflog = [] + +cdef log(level, action, obj, lineno): + if loglevel >= level: + reflog.append((lineno, action, id(obj))) + +LOG_NONE, LOG_ALL = range(2) + +class Context(object): + def __init__(self, name, line=0, filename=None): + self.name = name + self.start = line + self.filename = filename + self.refs = {} # id -> (count, [lineno]) + self.errors = [] + + def regref(self, obj, lineno, is_null): + log(LOG_ALL, u'regref', u"" if is_null else obj, lineno) + if is_null: + self.errors.append(u"NULL argument on line %d" % lineno) + return + id_ = id(obj) + count, linenumbers = self.refs.get(id_, (0, [])) + self.refs[id_] = (count + 1, linenumbers) + linenumbers.append(lineno) + + def delref(self, obj, lineno, is_null): + # returns whether it is ok to do the decref operation + log(LOG_ALL, u'delref', u"" if is_null else obj, lineno) + if is_null: + self.errors.append(u"NULL argument on line %d" % lineno) + return False + id_ = id(obj) + count, linenumbers = self.refs.get(id_, (0, [])) + if count == 0: + self.errors.append(u"Too many decrefs on line %d, reference acquired on lines %r" % + (lineno, linenumbers)) + return False + elif count == 1: + del self.refs[id_] + return True + else: + self.refs[id_] = (count - 1, linenumbers) + return True + + def end(self): + if len(self.refs) > 0: + msg = u"" + for count, linenos in self.refs.itervalues(): + msg += u"\n Acquired on lines: " + u", ".join([u"%d" % x for x in linenos]) + self.errors.append(u"References leaked: %s" % msg) + if self.errors: + return u"\n".join(self.errors) + else: + return None + +cpdef report_unraisable(e): + try: + print "refnanny raised an exception: %s" % e + except: + pass # We absolutely cannot exit with an exception + +# All Python operations must happen after any existing +# exception has been fetched, in case we are called from +# exception-handling code. + +cdef PyObject* NewContext(char* funcname, int lineno, char* filename) except NULL: + if Context is None: + # Context may be None during finalize phase. + # In that case, we don't want to be doing anything fancy + # like caching and resetting exceptions. + return NULL + cdef PyObject* type = NULL, *value = NULL, *tb = NULL + cdef PyObject* result = NULL + PyErr_Fetch(&type, &value, &tb) + try: + ctx = Context(funcname, lineno, filename) + Py_INCREF(ctx) + result = ctx + except Exception, e: + report_unraisable(e) + PyErr_Restore(type, value, tb) + return result + +cdef void GOTREF(PyObject* ctx, PyObject* p_obj, int lineno): + if ctx == NULL: return + cdef PyObject* type = NULL, *value = NULL, *tb = NULL + PyErr_Fetch(&type, &value, &tb) + try: + if p_obj is NULL: + (ctx).regref(None, lineno, True) + else: + (ctx).regref(p_obj, lineno, False) + except Exception, e: + report_unraisable(e) + PyErr_Restore(type, value, tb) + +cdef int GIVEREF_and_report(PyObject* ctx, PyObject* p_obj, int lineno): + if ctx == NULL: return 1 + cdef PyObject* type = NULL, *value = NULL, *tb = NULL + cdef bint decref_ok = False + PyErr_Fetch(&type, &value, &tb) + try: + if p_obj is NULL: + decref_ok = (ctx).delref(None, lineno, True) + else: + decref_ok = (ctx).delref(p_obj, lineno, False) + except Exception, e: + report_unraisable(e) + PyErr_Restore(type, value, tb) + return decref_ok + +cdef void GIVEREF(PyObject* ctx, PyObject* p_obj, int lineno): + GIVEREF_and_report(ctx, p_obj, lineno) + +cdef void INCREF(PyObject* ctx, PyObject* obj, int lineno): + if obj is not NULL: Py_INCREF(obj) + GOTREF(ctx, obj, lineno) + +cdef void DECREF(PyObject* ctx, PyObject* obj, int lineno): + if GIVEREF_and_report(ctx, obj, lineno): + if obj is not NULL: Py_DECREF(obj) + +cdef void FinishContext(PyObject** ctx): + if ctx == NULL or ctx[0] == NULL: return + cdef PyObject* type = NULL, *value = NULL, *tb = NULL + cdef object errors = None + PyErr_Fetch(&type, &value, &tb) + try: + errors = (ctx[0]).end() + pos = (ctx[0]).filename, (ctx[0]).name + if errors: + print u"%s: %s()" % pos + print errors + except Exception, e: + report_unraisable(e) + Py_DECREF(ctx[0]) + ctx[0] = NULL + PyErr_Restore(type, value, tb) + +cdef extern from "Python.h": + object PyCObject_FromVoidPtr(void*, void (*)(void*)) + +ctypedef struct RefnannyAPIStruct: + void (*INCREF)(PyObject*, PyObject*, int) + void (*DECREF)(PyObject*, PyObject*, int) + void (*GOTREF)(PyObject*, PyObject*, int) + void (*GIVEREF)(PyObject*, PyObject*, int) + PyObject* (*NewContext)(char*, int, char*) except NULL + void (*FinishContext)(PyObject**) + +cdef RefnannyAPIStruct api +api.INCREF = INCREF +api.DECREF = DECREF +api.GOTREF = GOTREF +api.GIVEREF = GIVEREF +api.NewContext = NewContext +api.FinishContext = FinishContext + +RefnannyAPI = PyCObject_FromVoidPtr(&api, NULL) diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Shadow.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Shadow.py --- cython-0.10.3/Cython/Shadow.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Shadow.py 2009-05-20 16:37:46.000000000 +0100 @@ -6,6 +6,19 @@ def locals(**arg_types): return empty_decorator +# Special functions + +def cdiv(a, b): + q = a / b + if q < 0: + q += 1 + +def cmod(a, b): + r = a % b + if (a*b) < 0: + r -= b + return r + # Emulated language constructs @@ -57,12 +70,12 @@ def __getitem__(self, ix): if ix < 0: - raise IndexError, "negative indexing not allowed in C" + raise IndexError("negative indexing not allowed in C") return self._items[ix] def __setitem__(self, ix, value): if ix < 0: - raise IndexError, "negative indexing not allowed in C" + raise IndexError("negative indexing not allowed in C") self._items[ix] = cast(self._basetype, value) class ArrayType(PointerType): @@ -74,22 +87,22 @@ class StructType(CythonType): def __init__(self, **data): - for key, value in data.items(): + for key, value in data.iteritems(): setattr(self, key, value) def __setattr__(self, key, value): if key in self._members: self.__dict__[key] = cast(self._members[key], value) else: - raise AttributeError, "Struct has no member '%s'" % key + raise AttributeError("Struct has no member '%s'" % key) class UnionType(CythonType): def __init__(self, **data): if len(data) > 0: - raise AttributeError, "Union can only store one field at a time." - for key, value in data.items(): + raise AttributeError("Union can only store one field at a time.") + for key, value in data.iteritems(): setattr(self, key, value) def __setattr__(self, key, value): @@ -98,7 +111,7 @@ elif key in self._members: self.__dict__ = {key: cast(self._members[key], value)} else: - raise AttributeError, "Union has no member '%s'" % key + raise AttributeError("Union has no member '%s'" % key) def pointer(basetype): class PointerInstance(PointerType): @@ -114,14 +127,14 @@ def struct(**members): class StructInstance(StructType): _members = members - for key in members.keys(): + for key in members: setattr(StructInstance, key, None) return StructInstance def union(**members): class UnionInstance(UnionType): _members = members - for key in members.keys(): + for key in members: setattr(UnionInstance, key, None) return UnionInstance diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/StringIOTree.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/StringIOTree.py --- cython-0.10.3/Cython/StringIOTree.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/StringIOTree.py 2009-05-20 16:37:46.000000000 +0100 @@ -7,31 +7,32 @@ def __init__(self, stream=None): self.prepended_children = [] - self.stream = stream # if set to None, it will be constructed on first write + if stream is None: + stream = StringIO() + self.stream = stream + self.write = stream.write def getvalue(self): - return ("".join([x.getvalue() for x in self.prepended_children]) + - self.stream.getvalue()) + content = [x.getvalue() for x in self.prepended_children] + content.append(self.stream.getvalue()) + return "".join(content) def copyto(self, target): """Potentially cheaper than getvalue as no string concatenation needs to happen.""" for child in self.prepended_children: child.copyto(target) - if self.stream: - target.write(self.stream.getvalue()) - - def write(self, what): - if not self.stream: - self.stream = StringIO() - self.stream.write(what) + stream_content = self.stream.getvalue() + if stream_content: + target.write(stream_content) def commit(self): # Save what we have written until now so that the buffer # itself is empty -- this makes it ready for insertion - if self.stream: + if self.stream.tell(): self.prepended_children.append(StringIOTree(self.stream)) - self.stream = None + self.stream = StringIO() + self.write = self.stream.write def insert(self, iotree): """ @@ -87,4 +88,4 @@ >>> a.copyto(out) >>> out.getvalue().split() ['first', 'second', 'alpha', 'inserted', 'beta', 'gamma', 'third'] -""" \ No newline at end of file +""" diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/TestUtils.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/TestUtils.py --- cython-0.10.3/Cython/TestUtils.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/TestUtils.py 2009-05-20 16:37:46.000000000 +0100 @@ -38,6 +38,15 @@ class CythonTest(unittest.TestCase): + def setUp(self): + self.listing_file = Errors.listing_file + self.echo_file = Errors.echo_file + Errors.listing_file = Errors.echo_file = None + + def tearDown(self): + Errors.listing_file = self.listing_file + Errors.echo_file = self.echo_file + def assertLines(self, expected, result): "Checks that the given strings or lists of strings are equal line by line" if not isinstance(expected, list): expected = expected.split(u"\n") diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Cython/Utils.py /tmp/bvXOgNtCTr/cython-0.11.2/Cython/Utils.py --- cython-0.10.3/Cython/Utils.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Cython/Utils.py 2009-05-20 16:37:46.000000000 +0100 @@ -10,22 +10,22 @@ return base + newsuf def open_new_file(path): - # Open and truncate existing file to - # preserve metadata on the Mac. - return open(path, "w+") + if os.path.exists(path): + # Make sure to create a new file here so we can + # safely hard link the output files. + os.unlink(path) + 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. + # failed compilation. # Also sets access and modification times back to # those specified by st (a stat struct). try: - f = open(path, "r+") + f = open_new_file(path) 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 Cython compilation.\n") f.close() @@ -89,14 +89,23 @@ value = int(value) return not -2**31 <= value < 2**31 +def none_or_sub(s, data): + if s is None: + return s + else: + return s % data + # a simple class that simplifies the usage of utility code class UtilityCode(object): - def __init__(self, proto=None, impl=None, init=None, cleanup=None): + def __init__(self, proto=None, impl=None, init=None, cleanup=None, requires=None): self.proto = proto self.impl = impl self.init = init self.cleanup = cleanup + self.requires = requires + self._cache = {} + self.specialize_list = [] def write_init_code(self, writer, pos): if not self.init: @@ -113,3 +122,25 @@ self.cleanup(writer, pos) else: writer.put(self.cleanup) + + def specialize(self, pyrex_type=None, **data): + # Dicts aren't hashable... + if pyrex_type is not None: + data['type'] = pyrex_type.declaration_code('') + data['type_name'] = pyrex_type.specalization_name() + key = data.items(); key.sort(); key = tuple(key) + try: + return self._cache[key] + except KeyError: + if self.requires is None: + requires = None + else: + requires = [r.specialize(data) for r in self.requires] + s = self._cache[key] = UtilityCode( + none_or_sub(self.proto, data), + none_or_sub(self.impl, data), + none_or_sub(self.init, data), + none_or_sub(self.cleanup, data), + requires) + self.specialize_list.append(s) + return s diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/debian/changelog /tmp/bvXOgNtCTr/cython-0.11.2/debian/changelog --- cython-0.10.3/debian/changelog 2009-08-11 13:12:08.000000000 +0100 +++ cython-0.11.2/debian/changelog 2009-08-11 13:12:09.000000000 +0100 @@ -1,8 +1,21 @@ -cython (0.10.3-1build1) jaunty; urgency=low +cython (0.11.2-1ubuntu1) karmic; urgency=low - * No-change rebuild for Python 2.6 transition. + * Build test - -- James Westby Sun, 01 Mar 2009 18:14:31 +0000 + -- Bhavani Shankar Tue, 11 Aug 2009 17:21:08 +0530 + +cython (0.11.2-1) unstable; urgency=low + + [ Ryan Kavanagh ] + * New upstream release (Closes: #525620, #536213) + + [ Jakub Wilk ] + * debian/rules: remove generated files. + + [ Piotr Ożarowski ] + * Standards-Version bumped to 3.8.2 (no change needed) + + -- Python Applications Packaging Team Mon, 10 Aug 2009 23:18:51 +0200 cython (0.10.3-1) unstable; urgency=low diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/debian/control /tmp/bvXOgNtCTr/cython-0.11.2/debian/control --- cython-0.10.3/debian/control 2009-08-11 13:12:08.000000000 +0100 +++ cython-0.11.2/debian/control 2009-08-11 13:12:09.000000000 +0100 @@ -4,7 +4,7 @@ Maintainer: Python Applications Packaging Team Uploaders: Ondrej Certik Build-Depends: cdbs (>= 0.4.49), debhelper (>= 5.0.38), python (>= 2.4.4-6), python-all-dev (>= 2.4.4-6), python-support (>= 0.7.5) -Standards-Version: 3.8.0 +Standards-Version: 3.8.2 Homepage: http://cython.org/ Vcs-Svn: svn://svn.debian.org/svn/python-apps/packages/cython/trunk Vcs-Browser: http://svn.debian.org/viewsvn/python-apps/packages/cython/trunk/ diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/debian/rules /tmp/bvXOgNtCTr/cython-0.11.2/debian/rules --- cython-0.10.3/debian/rules 2009-08-11 13:12:08.000000000 +0100 +++ cython-0.11.2/debian/rules 2009-08-11 13:12:09.000000000 +0100 @@ -8,3 +8,6 @@ install/cython:: dh_installman debian/cython.1 + +clean:: + rm -f Cython/Compiler/Lexicon.pickle Cython/*/*.c diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Demos/embed/embedded.pyx /tmp/bvXOgNtCTr/cython-0.11.2/Demos/embed/embedded.pyx --- cython-0.10.3/Demos/embed/embedded.pyx 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Demos/embed/embedded.pyx 2009-05-20 16:37:46.000000000 +0100 @@ -1,5 +1,7 @@ -cdef public void spam(): - praise() -def praise(): - print "Spam, glorious spam!" +print __name__ + +if __name__ == "__main__": + print "Hi, I'm embedded." +else: + print "I'm being imported." diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Demos/embed/Makefile /tmp/bvXOgNtCTr/cython-0.11.2/Demos/embed/Makefile --- cython-0.10.3/Demos/embed/Makefile 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Demos/embed/Makefile 2009-05-20 16:37:46.000000000 +0100 @@ -1,30 +1,19 @@ -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 +# Makefile for creating our standalone Cython program +PYVERSION=2.3 +PYPREFIX=/usr +INCLUDES=-I$(PYPREFIX)/include/python$(PYVERSION) + +embedded: embedded.o + gcc -o $@ $^ -lpython$(PYVERSION) -%.c: %.pyx - ../../bin/cython $< +embedded.o: embedded.c + gcc -c $^ $(INCLUDES) -%.o: %.c - gcc -c -fPIC $(PYINCLUDE) $< +embedded.c: embedded.pyx + @python ../../cython.py --embed embedded.pyx -#%.so: %.o -# gcc -shared $< -lm -o $@ - -all: main - -main: main.o embedded.o - gcc main.o embedded.o $(PYLIB) -o main +all: embedded clean: @echo Cleaning Demos/embed - @rm -f *~ *.o *.so core core.* embedded.h embedded.c main - -embedded.h: embedded.c -main.o: embedded.h + @rm -f *~ *.o *.so core core.* *.c embedded diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Demos/embed/Makefile.unix /tmp/bvXOgNtCTr/cython-0.11.2/Demos/embed/Makefile.unix --- cython-0.10.3/Demos/embed/Makefile.unix 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Demos/embed/Makefile.unix 2009-05-20 16:37:46.000000000 +0100 @@ -1,30 +1,19 @@ -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 +# Makefile for creating our standalone Cython program +PYVERSION=2.3 +PYPREFIX=/usr +INCLUDES=-I$(PYPREFIX)/include/python$(PYVERSION) + +embedded: embedded.o + gcc -o $@ $^ -lpython$(PYVERSION) -%.c: %.pyx - ../../bin/cython $< +embedded.o: embedded.c + gcc -c $^ $(INCLUDES) -%.o: %.c - gcc -c -fPIC $(PYINCLUDE) $< +embedded.c: embedded.pyx + @python ../../cython.py --embed embedded.pyx -#%.so: %.o -# gcc -shared $< -lm -o $@ - -all: main - -main: main.o embedded.o - gcc main.o embedded.o $(PYLIB) -o main +all: embedded clean: @echo Cleaning Demos/embed - @rm -f *~ *.o *.so core core.* embedded.h embedded.c main - -embedded.h: embedded.c -main.o: embedded.h + @rm -f *~ *.o *.so core core.* *.c embedded diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Demos/memleak_py.py /tmp/bvXOgNtCTr/cython-0.11.2/Demos/memleak_py.py --- cython-0.10.3/Demos/memleak_py.py 2008-12-14 09:50:07.000000000 +0000 +++ cython-0.11.2/Demos/memleak_py.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,14 +0,0 @@ -from memleak import foo -from sage.all import get_memory_usage - -def test(): - print get_memory_usage() - for i in range(100000): - try: - foo() - raise TypeError - except TypeError: - pass - print get_memory_usage() - -test() diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Demos/memleak.pyx /tmp/bvXOgNtCTr/cython-0.11.2/Demos/memleak.pyx --- cython-0.10.3/Demos/memleak.pyx 2008-12-14 10:55:39.000000000 +0000 +++ cython-0.11.2/Demos/memleak.pyx 1970-01-01 01:00:00.000000000 +0100 @@ -1,6 +0,0 @@ -def foo(): - cdef int x - try: - return 1 - except: - return 2 diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Demos/moduletryexcept.pyx /tmp/bvXOgNtCTr/cython-0.11.2/Demos/moduletryexcept.pyx --- cython-0.10.3/Demos/moduletryexcept.pyx 2008-12-14 10:52:54.000000000 +0000 +++ cython-0.11.2/Demos/moduletryexcept.pyx 1970-01-01 01:00:00.000000000 +0100 @@ -1,15 +0,0 @@ -__doc__ = u""" ->>> a -2 -""" - -a = 0 - -try: - raise KeyError -except AttributeError: - a = 1 -except KeyError: - a = 2 -except: - a = 3 diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Demos/setup.py /tmp/bvXOgNtCTr/cython-0.11.2/Demos/setup.py --- cython-0.10.3/Demos/setup.py 1970-01-01 01:00:00.000000000 +0100 +++ cython-0.11.2/Demos/setup.py 2009-05-20 16:37:46.000000000 +0100 @@ -0,0 +1,20 @@ +import glob + +from distutils.core import setup +from distutils.extension import Extension +from Cython.Distutils import build_ext + +ext_modules=[ + Extension("primes", ["primes.pyx"]), + Extension("spam", ["spam.pyx"]), +] + +for file in glob.glob("*.pyx"): + if file != "numeric_demo.pyx": + ext_modules.append(Extension(file[:-4], [file])) + +setup( + name = 'Demos', + cmdclass = {'build_ext': build_ext}, + ext_modules = ext_modules, +) diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Demos/Setup.py /tmp/bvXOgNtCTr/cython-0.11.2/Demos/Setup.py --- cython-0.10.3/Demos/Setup.py 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Demos/Setup.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,20 +0,0 @@ -import glob - -from distutils.core import setup -from distutils.extension import Extension -from Cython.Distutils import build_ext - -ext_modules=[ - Extension("primes", ["primes.pyx"]), - Extension("spam", ["spam.pyx"]), -] - -for file in glob.glob("*.pyx"): - if file != "numeric_demo.pyx": - ext_modules.append(Extension(file[:-4], [file])) - -setup( - name = 'Demos', - cmdclass = {'build_ext': build_ext}, - ext_modules = ext_modules, -) diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Demos/spam.pyx /tmp/bvXOgNtCTr/cython-0.11.2/Demos/spam.pyx --- cython-0.10.3/Demos/spam.pyx 2008-12-14 09:25:14.000000000 +0000 +++ cython-0.11.2/Demos/spam.pyx 2009-05-20 16:37:46.000000000 +0100 @@ -3,6 +3,7 @@ # cdef class Spam: + cdef public int amount def __new__(self): self.amount = 0 diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Doc/s5/cython-ep2008.txt /tmp/bvXOgNtCTr/cython-0.11.2/Doc/s5/cython-ep2008.txt --- cython-0.10.3/Doc/s5/cython-ep2008.txt 1970-01-01 01:00:00.000000000 +0100 +++ cython-0.11.2/Doc/s5/cython-ep2008.txt 2009-05-20 16:37:46.000000000 +0100 @@ -0,0 +1,401 @@ +============================================== +The Cython Compiler for C-Extensions in Python +============================================== + +Dr. Stefan Behnel +----------------- + +.. class:: center + + http://www.cython.org/ + + cython-dev@codespeak.net + +.. footer:: Dr. Stefan Behnel, EuroPython 2008, Vilnius/Lietuva + +.. include:: + + +About myself +============ + +* Passionate Python developer since 2002 + + * after Basic, Logo, Pascal, Prolog, Scheme, Java, ... + +* CS studies in Germany, Ireland, France + +* PhD in distributed systems in 2007 + + * Language design for self-organising systems + + * Darmstadt University of Technologies, Germany + +* Current occupations: + + * Employed by Senacor Technologies AG, Germany + + * IT transformations, SOA design, Java-Development, ... + + * »lxml« OpenSource XML toolkit for Python + + * http://codespeak.net/lxml/ + + * Cython + + +What is Cython? +=============== + +Cython is + +* an Open-Source project + + * http://cython.org + +* a Python compiler (almost) + + * an enhanced, optimising fork of Pyrex + +* an extended Python language for + + * writing fast Python extension modules + + * interfacing Python with C libraries + + +A little bit of history +======================= + +* April 2002: release of Pyrex 0.1 by Greg Ewing + + * Greg considers Pyrex a language in design phase + + * Pyrex became a key language for many projects + + * over the years, many people patched their Pyrex + + * not all patches were answered by Greg (not in time) + +* minor forks and enhanced branches followed + + * March 2006: my fork of Pyrex for »lxml« XML toolkit + + * November 2006: »SageX« fork of Pyrex + + * by Robert Bradshaw, William Stein (Univ. Seattle, USA) + + * context: »Sage«, a free mathematics software package + +* 28th July 2007: official Cython launch + + * integration of lxml's Pyrex fork into SageX + + * the rest is in http://hg.cython.org/cython-devel/ + + +Major Cython Developers +======================= + +* Robert Bradshaw and Stefan Behnel + + * lead developers + +* Greg Ewing + + * main developer and maintainer of Pyrex + + * we happily share code and discuss ideas + +* Dag Sverre Seljebotn + + * Google Summer-of-Code developer + + * NumPy integration, many ideas and enhancements + +* many, *many* others - see + + * http://cython.org/ + + * the mailing list archives of Cython and Pyrex + + +How to use Cython +================= + +* you write Python code + + * Cython translates it into C code + + * your C compiler builds a shared library for CPython + + * you import your module + +* Cython has support for + + * compile-time includes/imports + + * with dependency tracking + + * distutils + + * *optionally* compile Python code from setup.py! + + +Example: compiling Python code +============================== + +.. sourcecode:: bash + + $ cat worker.py + +.. sourcecode:: python + + class HardWorker(object): + u"Almost Sisyphus" + def __init__(self, task): + self.task = task + + def work_hard(self): + for i in range(100): + self.task() + +.. sourcecode:: bash + + $ cython worker.py + +* translates to 842 line `.c file `_ (Cython 0.9.8) + + * lots of portability #define's + + * tons of helpful C comments with Python code snippets + + * a lot of code that you don't want to write yourself + + +Portable Code +============= + +* Cython compiler generates C code that compiles + + * with all major compilers (C and C++) + + * on all major platforms + + * in Python 2.3 to 3.0 beta1 + +* Cython language syntax follows Python 2.6 + + * optional Python 3 syntax support is on TODO list + + * get involved to get it quicker! + +\... the fastest way to port Python 2 code to Py3 ;-) + + +Python 2 feature support +======================== + +* most of Python 2 syntax is supported + + * top-level classes and functions + + * exceptions + + * object operations, arithmetic, ... + +* plus some Py3/2.6 features: + + * keyword-only arguments + + * unicode literals via ``__future__`` import + +* in recent developer branch: + + * ``with`` statement + + * closures (i.e. local classes and functions) are close! + + +Speed +===== + +Cython generates very efficient C code + +* according to PyBench: + + * conditions and loops run 2-8x faster than in Py2.5 + + * most benchmarks run 30%-80% faster + + * overall more than 30% faster for plain Python code + +* optional type declarations + + * let Cython generate plain C instead of C-API calls + + * make code several times faster than the above + + +Type declarations +================= + +* »cdef« keyword declares + + * local variables with C types + + * functions with C signatures + + * classes as builtin extension types + +* Example:: + + def stupid_lower_case(char* s): + cdef Py_ssize_t size, i + + size = len(s) + for i in range(size): + if s[i] >= 'A' and s[i] <= 'Z': + s[i] += 'a' - 'A' + return s + + +Why is this stupid? +=================== + +Ask Cython! + +.. sourcecode:: bash + + $ cat stupidlowercase.py + +:: + + def stupid_lower_case(char* s): + cdef Py_ssize_t size, i + + size = len(s) + for i in range(size): + if s[i] >= 'A' and s[i] <= 'Z': + s[i] += 'a' - 'A' + return s + +.. sourcecode:: bash + + $ cython --annotate stupidlowercase.py + +=> `stupidlowercase.html `_ + + +Calling C functions +=================== + +* Example:: + + cdef extern from "Python.h": + # copied from the Python C-API docs: + object PyUnicode_DecodeASCII( + char* s, Py_ssize_t size, char* errors) + + cdef extern from "string.h": + int strlen(char *s) + + + cdef slightly_better_lower_case(char* s): + cdef Py_ssize_t i, size = strlen(s) + for i in range(size): + if s[i] >= 'A' and s[i] <= 'Z': + s[i] += 'a' - 'A' + return PyUnicode_DecodeASCII(s, size, NULL) + + +Features in work +================ + +* Dynamic classes and functions with closures + + .. sourcecode:: python + + def factory(a,b): + def closure_function(c): + return a+b+c + return closure_function + +* Native support for new ``buffer`` protocol + + * part of NumPy integration by Dag Seljebotn + + .. sourcecode:: python + + def inplace_negative_grayscale_image( + ndarray[unsigned char, 2] image): + cdef int i, j + for i in range(image.shape[0]): + for j in range(image.shape[1]): + arr[i, j] = 255 - arr[i, j] + + +Huge pile of great ideas +======================== + +* Cython Enhancement Proposals (CEPs) + + * http://wiki.cython.org/enhancements + +* native pickle support for extension classes + +* meta-programming facilities + +* type inference strategies + +* compile-time assertions for optimisations + +* object-like C-array handling + +* improved C++ integration + +* ... + + +Conclusion +========== + +* Cython is a tool for + + * efficiently translating Python code to C + + * easily interfacing to external C libraries + +* Use it to + + * speed up existing Python modules + + * concentrate on optimisations, not rewrites! + + * write C extensions for CPython + + * don't change the language just to get fast code! + + * wrap C libraries *in Python* + + * concentrate on the mapping, not the glue! + + +... but Cython is also +====================== + +* a great project + +* a very open playground for great ideas! + + +Cython +====== + + **Cython** + + **C-Extensions in Python** + + \... use it, and join the project! + + http://cython.org/ diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Doc/s5/ep2008/stupidlowercase.py /tmp/bvXOgNtCTr/cython-0.11.2/Doc/s5/ep2008/stupidlowercase.py --- cython-0.10.3/Doc/s5/ep2008/stupidlowercase.py 1970-01-01 01:00:00.000000000 +0100 +++ cython-0.11.2/Doc/s5/ep2008/stupidlowercase.py 2009-05-20 16:37:46.000000000 +0100 @@ -0,0 +1,9 @@ + +def stupid_lower_case(char* s): + cdef Py_ssize_t size, i + + size = len(s) + for i in range(size): + if s[i] >= 'A' and s[i] <= 'Z': + s[i] += 'a' - 'A' + return s diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Doc/s5/ep2008/worker.py /tmp/bvXOgNtCTr/cython-0.11.2/Doc/s5/ep2008/worker.py --- cython-0.10.3/Doc/s5/ep2008/worker.py 1970-01-01 01:00:00.000000000 +0100 +++ cython-0.11.2/Doc/s5/ep2008/worker.py 2009-05-20 16:37:46.000000000 +0100 @@ -0,0 +1,9 @@ + +class HardWorker(object): + u"Almost Sisyphus" + def __init__(self, task): + self.task = task + + def work_hard(self): + for i in range(100): + self.task() diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Doc/s5/Makefile /tmp/bvXOgNtCTr/cython-0.11.2/Doc/s5/Makefile --- cython-0.10.3/Doc/s5/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ cython-0.11.2/Doc/s5/Makefile 2009-05-20 16:37:46.000000000 +0100 @@ -0,0 +1,17 @@ + +SLIDES=$(subst .txt,.html,$(wildcard *.txt)) +SOURCES=$(subst .py,.c,$(subst .pyx,.c,$(wildcard */*.py */*.pyx))) + +slides: $(SLIDES) $(SOURCES) + +%.html: %.txt + rst2s5 --current-slide --language=en $< $@ + +%.c: %.py + cython --annotate $< + +%.c: %.pyx + cython --annotate $< + +clean: + rm -f *~ $(SLIDES) $(SOURCES) $(subst .c,.html,$(SOURCES)) Binary files /tmp/ypPL5pAcDN/cython-0.10.3/Doc/s5/ui/default/blank.gif and /tmp/bvXOgNtCTr/cython-0.11.2/Doc/s5/ui/default/blank.gif differ Binary files /tmp/ypPL5pAcDN/cython-0.10.3/Doc/s5/ui/default/bodybg.gif and /tmp/bvXOgNtCTr/cython-0.11.2/Doc/s5/ui/default/bodybg.gif differ Binary files /tmp/ypPL5pAcDN/cython-0.10.3/Doc/s5/ui/default/cython-logo64.png and /tmp/bvXOgNtCTr/cython-0.11.2/Doc/s5/ui/default/cython-logo64.png differ diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Doc/s5/ui/default/framing.css /tmp/bvXOgNtCTr/cython-0.11.2/Doc/s5/ui/default/framing.css --- cython-0.10.3/Doc/s5/ui/default/framing.css 1970-01-01 01:00:00.000000000 +0100 +++ cython-0.11.2/Doc/s5/ui/default/framing.css 2009-05-20 16:37:46.000000000 +0100 @@ -0,0 +1,23 @@ +/* The following styles size, place, and layer the slide components. + Edit these if you want to change the overall slide layout. + The commented lines can be uncommented (and modified, if necessary) + to help you with the rearrangement process. */ + +/* target = 1024x768 */ + +div#header, div#footer, .slide {width: 100%; top: 0; left: 0;} +div#header {top: 0; height: 3em; z-index: 1;} +div#footer {top: auto; bottom: 0; height: 2.5em; z-index: 5;} +.slide {top: 0; width: 92%; padding: 3.5em 4% 4%; z-index: 2; list-style: none;} +div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0;} +#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em; z-index: 10;} +html>body #currentSlide {position: fixed;} + +/* +div#header {background: #FCC;} +div#footer {background: #CCF;} +div#controls {background: #BBD;} +div#currentSlide {background: #FFC;} +*/ diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Doc/s5/ui/default/iepngfix.htc /tmp/bvXOgNtCTr/cython-0.11.2/Doc/s5/ui/default/iepngfix.htc --- cython-0.10.3/Doc/s5/ui/default/iepngfix.htc 1970-01-01 01:00:00.000000000 +0100 +++ cython-0.11.2/Doc/s5/ui/default/iepngfix.htc 2009-05-20 16:37:46.000000000 +0100 @@ -0,0 +1,42 @@ + + + + + \ No newline at end of file diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Doc/s5/ui/default/opera.css /tmp/bvXOgNtCTr/cython-0.11.2/Doc/s5/ui/default/opera.css --- cython-0.10.3/Doc/s5/ui/default/opera.css 1970-01-01 01:00:00.000000000 +0100 +++ cython-0.11.2/Doc/s5/ui/default/opera.css 2009-05-20 16:37:46.000000000 +0100 @@ -0,0 +1,7 @@ +/* DO NOT CHANGE THESE unless you really want to break Opera Show */ +.slide { + visibility: visible !important; + position: static !important; + page-break-before: always; +} +#slide0 {page-break-before: avoid;} diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Doc/s5/ui/default/outline.css /tmp/bvXOgNtCTr/cython-0.11.2/Doc/s5/ui/default/outline.css --- cython-0.10.3/Doc/s5/ui/default/outline.css 1970-01-01 01:00:00.000000000 +0100 +++ cython-0.11.2/Doc/s5/ui/default/outline.css 2009-05-20 16:37:46.000000000 +0100 @@ -0,0 +1,15 @@ +/* don't change this unless you want the layout stuff to show up in the outline view! */ + +.layout div, #footer *, #controlForm * {display: none;} +#footer, #controls, #controlForm, #navLinks, #toggle { + display: block; visibility: visible; margin: 0; padding: 0;} +#toggle {float: right; padding: 0.5em;} +html>body #toggle {position: fixed; top: 0; right: 0;} + +/* making the outline look pretty-ish */ + +#slide0 h1, #slide0 h2, #slide0 h3, #slide0 h4 {border: none; margin: 0;} +#slide0 h1 {padding-top: 1.5em;} +.slide h1 {margin: 1.5em 0 0; padding-top: 0.25em; + border-top: 1px solid #888; border-bottom: 1px solid #AAA;} +#toggle {border: 1px solid; border-width: 0 0 1px 1px; background: #FFF;} diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Doc/s5/ui/default/pretty.css /tmp/bvXOgNtCTr/cython-0.11.2/Doc/s5/ui/default/pretty.css --- cython-0.10.3/Doc/s5/ui/default/pretty.css 1970-01-01 01:00:00.000000000 +0100 +++ cython-0.11.2/Doc/s5/ui/default/pretty.css 2009-05-20 16:37:46.000000000 +0100 @@ -0,0 +1,163 @@ +/* Following are the presentation styles -- edit away! */ + +/* body {background: #FFF url(cython.png) 1em 1em no-repeat; color: #000; font-size: 2em;} */ +:link, :visited {text-decoration: none; color: #545454;} +#controls :active {color: #545454 !important;} +#controls :focus {outline: 1px dotted #545454;} +h1, h2, h3, h4 {font-size: 100%; margin: 0; padding: 0; font-weight: inherit;} +ul, pre {margin: 0; line-height: 1em;} +html, body {margin: 0; padding: 0;} + +blockquote, q {font-style: italic;} +blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em; text-align: center; font-size: 1em;} +blockquote p {margin: 2em;} +blockquote p strong {font-size: 1.5em;} +blockquote i {font-style: normal;} +blockquote b {display: block; margin-top: 0.5em; font-weight: normal; font-size: smaller; font-style: normal;} +blockquote b i {font-style: italic;} + +kbd {font-weight: bold; font-size: 1em;} +sup {font-size: smaller; line-height: 1px;} + +.slide {padding-top: 3em; } + +.slide code {padding: 2px 0.25em; font-weight: bold; color: #533;} +.slide code.bad, code del {color: red;} +.slide code.old {color: silver;} +.slide .pre {padding: 0; margin: 0 0 0 0; color: #533; font-size: 80%;} +.slide pre {padding: 0; margin: 0.25em 0 0.5em 0.5em; color: #533; font-size: 90%;} +/* .slide pre {padding: 0; margin: 0 0 0 0; color: #533; font-size: 90%;} */ +.slide pre code {display: block;} +.slide div > ul {padding-left: 0; margin-left: 0; list-style: disc; } +.slide li {margin-top: 0.75em; margin-right: 0;} +.slide ul ul {line-height: 1; padding-left: 1em; margin-left: 2%; margin-right: 5%; list-style: disc; } +.slide ul ul li {margin: .4em; font-size: 85%; list-style: square;} +.slide img.leader {display: block; margin: 0 auto;} + +div#header, div#footer {background: #f0f0f0; color: #545454; + font-family: Verdana, Helvetica, sans-serif; padding: 0;} +div#header {background: #f0f0f0 url(cython-logo64.png) 1ex 0.2ex no-repeat; + line-height: 1px; border-bottom: solid #545454 4px; height: 2.4em;} +div#footer {font-size: 0.5em; font-weight: bold; padding: 0.6em 0; + border-top: solid #545454 3px;} +#footer h1, #footer h2 {display: block; padding: 0 1.5ex;} +#footer h2 {font-style: italic;} +#footer a {color: #545454;} + +div.long {font-size: 0.75em;} +.slide h1 {position: absolute; top: 0.2em; left: 87px; z-index: 1; + margin: 0; padding: 0.3ex 0 0 25px; white-space: nowrap; + font: bold 150%/1em Helvetica, sans-serif; /* text-transform: capitalize; */ + color: #646464; background: #f0f0f0;} +.slide h3 {font-size: 130%;} +h1 abbr {font-variant: small-caps;} + +div#controls {position: absolute; left: 50%; bottom: 0; + width: 50%; + text-align: right; font: bold 0.7em Verdana, Helvetica, sans-serif;} +html>body div#controls {position: fixed; padding: 0 0 1em 0; + top: auto;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0; padding: 0;} +#controls #navLinks a {padding: 0; margin: 0 0.5em; + background: #f0f0f0; border: none; color: #545454; + cursor: pointer;} +#controls #navList {height: 1em;} +#controls #navList #jumplist {position: absolute; bottom: 0; right: 0; background: #f0f0f0; color: black;} + +#currentSlide {text-align: center; font-size: 0.5em; color: #545454; left: 90%; bottom: 2px;} + +#slide0 {padding-top: 3em; font-size: 90%;} +#slide0 h1 {position: static; margin: 1em 0 0; padding: 0; + font: bold 2em Helvetica, sans-serif; white-space: normal; + color: #000; background: transparent;} +#slide0 h2 {font: bold italic 1em Helvetica, sans-serif; margin: 1.25em;} +#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;} +#slide0 h4 {margin-top: 0; font-size: 1em;} + +ul.urls {list-style: none; display: inline; margin: 0;} +.urls li {display: inline; margin: 0;} +.note {display: none;} +.external {border-bottom: 1px dotted gray;} +html>body .external {border-bottom: none;} +/* .external:after {content: " \274F"; font-size: smaller; color: #7B7;} */ + +/* .incremental, .incremental *, .incremental *:after {color: #545454; visibility: visible;} */ +.incremental, .incremental *, .incremental *:after {visibility: hidden;} +img.incremental {visibility: hidden;} +.slide .current {color: #B02;} + +.center {text-align: center; } +.right {text-align: right; } +.small {font-size: 60%; } +img.center {display: block; margin-left: auto; margin-right: auto; } + +.slide .syntax {padding: 2px 0.25em; font-weight: bold; color: #533; font-size:85%; } + +/* diagnostics + +li:after {content: " [" attr(class) "]"; color: #F88;} + */ + +/* Syntax highlighting */ + +/* .syntax { background: #f0f0f0; } */ +.syntax .c { color: #60a0b0; font-style: italic } /* Comment */ +.syntax .err { border: 1px solid #FF0000 } /* Error */ +.syntax .k { color: #007020; font-weight: bold } /* Keyword */ +.syntax .o { color: #666666 } /* Operator */ +.syntax .cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */ +.syntax .cp { color: #007020 } /* Comment.Preproc */ +.syntax .c1 { color: #60a0b0; font-style: italic } /* Comment.Single */ +.syntax .cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */ +.syntax .gd { color: #A00000 } /* Generic.Deleted */ +.syntax .ge { font-style: italic } /* Generic.Emph */ +.syntax .gr { color: #FF0000 } /* Generic.Error */ +.syntax .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.syntax .gi { color: #00A000 } /* Generic.Inserted */ +.syntax .go { color: #404040 } /* Generic.Output */ +.syntax .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.syntax .gs { font-weight: bold } /* Generic.Strong */ +.syntax .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.syntax .gt { color: #0040D0 } /* Generic.Traceback */ +.syntax .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ +.syntax .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ +.syntax .kp { color: #007020 } /* Keyword.Pseudo */ +.syntax .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ +.syntax .kt { color: #902000 } /* Keyword.Type */ +.syntax .m { color: #40a070 } /* Literal.Number */ +.syntax .s { color: #4070a0 } /* Literal.String */ +.syntax .na { color: #4070a0 } /* Name.Attribute */ +.syntax .nb { color: #007020 } /* Name.Builtin */ +.syntax .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ +.syntax .no { color: #60add5 } /* Name.Constant */ +.syntax .nd { color: #555555; font-weight: bold } /* Name.Decorator */ +.syntax .ni { color: #d55537; font-weight: bold } /* Name.Entity */ +.syntax .ne { color: #007020 } /* Name.Exception */ +.syntax .nf { color: #06287e } /* Name.Function */ +.syntax .nl { color: #002070; font-weight: bold } /* Name.Label */ +.syntax .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.syntax .nt { color: #062873; font-weight: bold } /* Name.Tag */ +.syntax .nv { color: #bb60d5 } /* Name.Variable */ +.syntax .ow { color: #007020; font-weight: bold } /* Operator.Word */ +.syntax .w { color: #bbbbbb } /* Text.Whitespace */ +.syntax .mf { color: #40a070 } /* Literal.Number.Float */ +.syntax .mh { color: #40a070 } /* Literal.Number.Hex */ +.syntax .mi { color: #40a070 } /* Literal.Number.Integer */ +.syntax .mo { color: #40a070 } /* Literal.Number.Oct */ +.syntax .sb { color: #4070a0 } /* Literal.String.Backtick */ +.syntax .sc { color: #4070a0 } /* Literal.String.Char */ +.syntax .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ +.syntax .s2 { color: #4070a0 } /* Literal.String.Double */ +.syntax .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ +.syntax .sh { color: #4070a0 } /* Literal.String.Heredoc */ +.syntax .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ +.syntax .sx { color: #c65d09 } /* Literal.String.Other */ +.syntax .sr { color: #235388 } /* Literal.String.Regex */ +.syntax .s1 { color: #4070a0 } /* Literal.String.Single */ +.syntax .ss { color: #517918 } /* Literal.String.Symbol */ +.syntax .bp { color: #007020 } /* Name.Builtin.Pseudo */ +.syntax .vc { color: #bb60d5 } /* Name.Variable.Class */ +.syntax .vg { color: #bb60d5 } /* Name.Variable.Global */ +.syntax .vi { color: #bb60d5 } /* Name.Variable.Instance */ +.syntax .il { color: #40a070 } /* Literal.Number.Integer.Long */ diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Doc/s5/ui/default/print.css /tmp/bvXOgNtCTr/cython-0.11.2/Doc/s5/ui/default/print.css --- cython-0.10.3/Doc/s5/ui/default/print.css 1970-01-01 01:00:00.000000000 +0100 +++ cython-0.11.2/Doc/s5/ui/default/print.css 2009-05-20 16:37:46.000000000 +0100 @@ -0,0 +1,24 @@ +/* The following rule is necessary to have all slides appear in print! DO NOT REMOVE IT! */ +.slide, ul {page-break-inside: avoid; visibility: visible !important;} +h1 {page-break-after: avoid;} + +body {font-size: 12pt; background: white;} +* {color: black;} + +#slide0 h1 {font-size: 200%; border: none; margin: 0.5em 0 0.25em;} +#slide0 h3 {margin: 0; padding: 0;} +#slide0 h4 {margin: 0 0 0.5em; padding: 0;} +#slide0 {margin-bottom: 3em;} + +h1 {border-top: 2pt solid gray; border-bottom: 1px dotted silver;} +.extra {background: transparent !important;} +div.extra, pre.extra, .example {font-size: 10pt; color: #333;} +ul.extra a {font-weight: bold;} +p.example {display: none;} + +#header {display: none;} +#footer h1 {margin: 0; border-bottom: 1px solid; color: gray; font-style: italic;} +#footer h2, #controls {display: none;} + +/* The following rule keeps the layout stuff out of print. Remove at your own risk! */ +.layout, .layout * {display: none !important;} diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Doc/s5/ui/default/s5-core.css /tmp/bvXOgNtCTr/cython-0.11.2/Doc/s5/ui/default/s5-core.css --- cython-0.10.3/Doc/s5/ui/default/s5-core.css 1970-01-01 01:00:00.000000000 +0100 +++ cython-0.11.2/Doc/s5/ui/default/s5-core.css 2009-05-20 16:37:46.000000000 +0100 @@ -0,0 +1,9 @@ +/* Do not edit or override these styles! The system will likely break if you do. */ + +div#header, div#footer, div#controls, .slide {position: absolute;} +html>body div#header, html>body div#footer, + html>body div#controls, html>body .slide {position: fixed;} +.handout {display: none;} +.layout {display: block;} +.slide, .hideme, .incremental {visibility: hidden;} +#slide0 {visibility: visible;} diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Doc/s5/ui/default/slides.css /tmp/bvXOgNtCTr/cython-0.11.2/Doc/s5/ui/default/slides.css --- cython-0.10.3/Doc/s5/ui/default/slides.css 1970-01-01 01:00:00.000000000 +0100 +++ cython-0.11.2/Doc/s5/ui/default/slides.css 2009-05-20 16:37:46.000000000 +0100 @@ -0,0 +1,3 @@ +@import url(s5-core.css); /* required to make the slide show run at all */ +@import url(framing.css); /* sets basic placement and size of slide components */ +@import url(pretty.css); /* stuff that makes the slides look better than blah */ \ No newline at end of file diff -Nru /tmp/ypPL5pAcDN/cython-0.10.3/Doc/s5/ui/default/slides.js /tmp/bvXOgNtCTr/cython-0.11.2/Doc/s5/ui/default/slides.js --- cython-0.10.3/Doc/s5/ui/default/slides.js 1970-01-01 01:00:00.000000000 +0100 +++ cython-0.11.2/Doc/s5/ui/default/slides.js 2009-05-20 16:37:46.000000000 +0100 @@ -0,0 +1,552 @@ +// S5 v1.1 slides.js -- released into the Public Domain +// +// Please see http://www.meyerweb.com/eric/tools/s5/credits.html for information +// about all the wonderful and talented contributors to this code! + +var undef; +var slideCSS = ''; +var snum = 0; +var smax = 1; +var incpos = 0; +var number = undef; +var s5mode = true; +var defaultView = 'slideshow'; +var controlVis = 'visible'; + +var isIE = navigator.appName == 'Microsoft Internet Explorer' ? 1 : 0; +var isOp = navigator.userAgent.indexOf('Opera') > -1 ? 1 : 0; +var isGe = navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('Safari') < 1 ? 1 : 0; + +function hasClass(object, className) { + if (!object.className) return false; + return (object.className.search('(^|\\s)' + className + '(\\s|$)') != -1); +} + +function hasValue(object, value) { + if (!object) return false; + return (object.search('(^|\\s)' + value + '(\\s|$)') != -1); +} + +function removeClass(object,className) { + if (!object) return; + object.className = object.className.replace(new RegExp('(^|\\s)'+className+'(\\s|$)'), RegExp.$1+RegExp.$2); +} + +function addClass(object,className) { + if (!object || hasClass(object, className)) return; + if (object.className) { + object.className += ' '+className; + } else { + object.className = className; + } +} + +function GetElementsWithClassName(elementName,className) { + var allElements = document.getElementsByTagName(elementName); + var elemColl = new Array(); + for (var i = 0; i< allElements.length; i++) { + if (hasClass(allElements[i], className)) { + elemColl[elemColl.length] = allElements[i]; + } + } + return elemColl; +} + +function isParentOrSelf(element, id) { + if (element == null || element.nodeName=='BODY') return false; + else if (element.id == id) return true; + else return isParentOrSelf(element.parentNode, id); +} + +function nodeValue(node) { + var result = ""; + if (node.nodeType == 1) { + var children = node.childNodes; + for (var i = 0; i < children.length; ++i) { + result += nodeValue(children[i]); + } + } + else if (node.nodeType == 3) { + result = node.nodeValue; + } + return(result); +} + +function slideLabel() { + var slideColl = GetElementsWithClassName('*','slide'); + var list = document.getElementById('jumplist'); + smax = slideColl.length; + for (var n = 0; n < smax; n++) { + var obj = slideColl[n]; + + var did = 'slide' + n.toString(); + obj.setAttribute('id',did); + if (isOp) continue; + + var otext = ''; + var menu = obj.firstChild; + if (!menu) continue; // to cope with empty slides + while (menu && menu.nodeType == 3) { + menu = menu.nextSibling; + } + if (!menu) continue; // to cope with slides with only text nodes + + var menunodes = menu.childNodes; + for (var o = 0; o < menunodes.length; o++) { + otext += nodeValue(menunodes[o]); + } + list.options[list.length] = new Option(n + ' : ' + otext, n); + } +} + +function currentSlide() { + var cs; + if (document.getElementById) { + cs = document.getElementById('currentSlide'); + } else { + cs = document.currentSlide; + } + cs.innerHTML = '' + snum + '<\/span> ' + + '\/<\/span> ' + + '' + (smax-1) + '<\/span>'; + if (snum == 0) { + cs.style.visibility = 'hidden'; + } else { + cs.style.visibility = 'visible'; + } +} + +function go(step) { + if (document.getElementById('slideProj').disabled || step == 0) return; + var jl = document.getElementById('jumplist'); + var cid = 'slide' + snum; + var ce = document.getElementById(cid); + if (incrementals[snum].length > 0) { + for (var i = 0; i < incrementals[snum].length; i++) { + removeClass(incrementals[snum][i], 'current'); + removeClass(incrementals[snum][i], 'incremental'); + } + } + if (step != 'j') { + snum += step; + lmax = smax - 1; + if (snum > lmax) snum = lmax; + if (snum < 0) snum = 0; + } else + snum = parseInt(jl.value); + var nid = 'slide' + snum; + var ne = document.getElementById(nid); + if (!ne) { + ne = document.getElementById('slide0'); + snum = 0; + } + if (step < 0) {incpos = incrementals[snum].length} else {incpos = 0;} + if (incrementals[snum].length > 0 && incpos == 0) { + for (var i = 0; i < incrementals[snum].length; i++) { + if (hasClass(incrementals[snum][i], 'current')) + incpos = i + 1; + else + addClass(incrementals[snum][i], 'incremental'); + } + } + if (incrementals[snum].length > 0 && incpos > 0) + addClass(incrementals[snum][incpos - 1], 'current'); + ce.style.visibility = 'hidden'; + ne.style.visibility = 'visible'; + jl.selectedIndex = snum; + currentSlide(); + number = 0; +} + +function goTo(target) { + if (target >= smax || target == snum) return; + go(target - snum); +} + +function subgo(step) { + if (step > 0) { + removeClass(incrementals[snum][incpos - 1],'current'); + removeClass(incrementals[snum][incpos], 'incremental'); + addClass(incrementals[snum][incpos],'current'); + incpos++; + } else { + incpos--; + removeClass(incrementals[snum][incpos],'current'); + addClass(incrementals[snum][incpos], 'incremental'); + addClass(incrementals[snum][incpos - 1],'current'); + } +} + +function toggle() { + var slideColl = GetElementsWithClassName('*','slide'); + var slides = document.getElementById('slideProj'); + var outline = document.getElementById('outlineStyle'); + if (!slides.disabled) { + slides.disabled = true; + outline.disabled = false; + s5mode = false; + fontSize('1em'); + for (var n = 0; n < smax; n++) { + var slide = slideColl[n]; + slide.style.visibility = 'visible'; + } + } else { + slides.disabled = false; + outline.disabled = true; + s5mode = true; + fontScale(); + for (var n = 0; n < smax; n++) { + var slide = slideColl[n]; + slide.style.visibility = 'hidden'; + } + slideColl[snum].style.visibility = 'visible'; + } +} + +function showHide(action) { + var obj = GetElementsWithClassName('*','hideme')[0]; + switch (action) { + case 's': obj.style.visibility = 'visible'; break; + case 'h': obj.style.visibility = 'hidden'; break; + case 'k': + if (obj.style.visibility != 'visible') { + obj.style.visibility = 'visible'; + } else { + obj.style.visibility = 'hidden'; + } + break; + } +} + +// 'keys' code adapted from MozPoint (http://mozpoint.mozdev.org/) +function keys(key) { + if (!key) { + key = event; + key.which = key.keyCode; + } + if (key.which == 84) { + toggle(); + return; + } + if (s5mode) { + switch (key.which) { + case 10: // return + case 13: // enter + if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return; + if (key.target && isParentOrSelf(key.target, 'controls')) return; + if(number != undef) { + goTo(number); + break; + } + case 32: // spacebar + case 34: // page down + case 39: // rightkey + case 40: // downkey + if(number != undef) { + go(number); + } else if (!incrementals[snum] || incpos >= incrementals[snum].length) { + go(1); + } else { + subgo(1); + } + break; + case 33: // page up + case 37: // leftkey + case 38: // upkey + if(number != undef) { + go(-1 * number); + } else if (!incrementals[snum] || incpos <= 0) { + go(-1); + } else { + subgo(-1); + } + break; + case 36: // home + goTo(0); + break; + case 35: // end + goTo(smax-1); + break; + case 67: // c + showHide('k'); + break; + } + if (key.which < 48 || key.which > 57) { + number = undef; + } else { + if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return; + if (key.target && isParentOrSelf(key.target, 'controls')) return; + number = (((number != undef) ? number : 0) * 10) + (key.which - 48); + } + } + return false; +} + +function clicker(e) { + number = undef; + var target; + if (window.event) { + target = window.event.srcElement; + e = window.event; + } else target = e.target; + if (target.getAttribute('href') != null || hasValue(target.rel, 'external') || isParentOrSelf(target, 'controls') || isParentOrSelf(target,'embed') || isParentOrSelf(target,'object')) return true; + if (!e.which || e.which == 1) { + if (!incrementals[snum] || incpos >= incrementals[snum].length) { + go(1); + } else { + subgo(1); + } + } +} + +function findSlide(hash) { + var target = null; + var slides = GetElementsWithClassName('*','slide'); + for (var i = 0; i < slides.length; i++) { + var targetSlide = slides[i]; + if ( (targetSlide.name && targetSlide.name == hash) + || (targetSlide.id && targetSlide.id == hash) ) { + target = targetSlide; + break; + } + } + while(target != null && target.nodeName != 'BODY') { + if (hasClass(target, 'slide')) { + return parseInt(target.id.slice(5)); + } + target = target.parentNode; + } + return null; +} + +function slideJump() { + if (window.location.hash == null) return; + var sregex = /^#slide(\d+)$/; + var matches = sregex.exec(window.location.hash); + var dest = null; + if (matches != null) { + dest = parseInt(matches[1]); + } else { + dest = findSlide(window.location.hash.slice(1)); + } + if (dest != null) + go(dest - snum); +} + +function fixLinks() { + var thisUri = window.location.href; + thisUri = thisUri.slice(0, thisUri.length - window.location.hash.length); + var aelements = document.getElementsByTagName('A'); + for (var i = 0; i < aelements.length; i++) { + var a = aelements[i].href; + var slideID = a.match('\#slide[0-9]{1,2}'); + if ((slideID) && (slideID[0].slice(0,1) == '#')) { + var dest = findSlide(slideID[0].slice(1)); + if (dest != null) { + if (aelements[i].addEventListener) { + aelements[i].addEventListener("click", new Function("e", + "if (document.getElementById('slideProj').disabled) return;" + + "go("+dest+" - snum); " + + "if (e.preventDefault) e.preventDefault();"), true); + } else if (aelements[i].attachEvent) { + aelements[i].attachEvent("onclick", new Function("", + "if (document.getElementById('slideProj').disabled) return;" + + "go("+dest+" - snum); " + + "event.returnValue = false;")); + } + } + } + } +} + +function externalLinks() { + if (!document.getElementsByTagName) return; + var anchors = document.getElementsByTagName('a'); + for (var i=0; i' + + '