[Python-checkins] r46830 - in external/ctypes: ANNOUNCE BUGS ChangeLog MANIFEST.in TODO ctypes/__init__.py ctypes/test/test_anon.py ctypes/test/test_cast.py ctypes/test/test_cfuncs.py ctypes/test/test_find.py ctypes/test/test_keeprefs.py ctypes/test/test_loading.py ctypes/test/test_objects.py ctypes/test/test_pointers.py ctypes/test/test_python_api.py ctypes/test/test_slicing.py ctypes/test/test_structures.py ctypes/test/test_varsize_struct.py docs/anatomy.txt docs/manual/callbacks.txt docs/manual/ctypes.txt docs/manual/docs.txt docs/manual/filter.py docs/manual/functions.txt docs/manual/libctypes.txt docs/manual/libraries.txt docs/manual/make.bat docs/manual/manual.html docs/manual/manual.txt docs/manual/mkpydoc.py docs/manual/reference.txt docs/manual/simple_types.txt docs/manual/struct_union.txt docs/manual/table.txt docs/manual/test-tutorial.py docs/manual/tutorial.txt docs/manual/utilities.txt docs/test-anatomy.py env.bat setup.py source/_ctypes.c source/_ctypes_test.c source/callbacks.c source/callproc.c source/cfield.c source/ctypes.h source/libffi/configure source/libffi/configure.ac source/libffi/fficonfig.h.in source/libffi/fficonfig.py.in source/libffi/src/darwin source/libffi/src/darwin/ffitarget.h source/libffi/src/powerpc/darwin.S source/libffi/src/powerpc/darwin_closure.S source/libffi/src/powerpc/ffi_darwin.c source/libffi/src/prep_cif.c source/libffi/src/x86/darwin.S source/libffi/src/x86/ffi_darwin.c source/libffi/src/x86/ffitarget.h source/stgdict.c
thomas.heller
python-checkins at python.org
Sat Jun 10 22:08:22 CEST 2006
Author: thomas.heller
Date: Sat Jun 10 22:08:12 2006
New Revision: 46830
Added:
external/ctypes/BUGS
external/ctypes/TODO
external/ctypes/ctypes/test/test_anon.py
external/ctypes/ctypes/test/test_objects.py
external/ctypes/ctypes/test/test_varsize_struct.py
external/ctypes/docs/anatomy.txt
external/ctypes/docs/manual/ctypes.txt
external/ctypes/docs/manual/filter.py
external/ctypes/docs/test-anatomy.py
external/ctypes/source/libffi/src/darwin/
external/ctypes/source/libffi/src/darwin/ffitarget.h
external/ctypes/source/libffi/src/x86/darwin.S
external/ctypes/source/libffi/src/x86/ffi_darwin.c
Removed:
external/ctypes/docs/manual/callbacks.txt
external/ctypes/docs/manual/docs.txt
external/ctypes/docs/manual/functions.txt
external/ctypes/docs/manual/libctypes.txt
external/ctypes/docs/manual/libraries.txt
external/ctypes/docs/manual/manual.html
external/ctypes/docs/manual/manual.txt
external/ctypes/docs/manual/simple_types.txt
external/ctypes/docs/manual/struct_union.txt
external/ctypes/docs/manual/table.txt
external/ctypes/docs/manual/utilities.txt
Modified:
external/ctypes/ANNOUNCE
external/ctypes/ChangeLog
external/ctypes/MANIFEST.in
external/ctypes/ctypes/__init__.py
external/ctypes/ctypes/test/test_cast.py
external/ctypes/ctypes/test/test_cfuncs.py
external/ctypes/ctypes/test/test_find.py
external/ctypes/ctypes/test/test_keeprefs.py
external/ctypes/ctypes/test/test_loading.py
external/ctypes/ctypes/test/test_pointers.py
external/ctypes/ctypes/test/test_python_api.py
external/ctypes/ctypes/test/test_slicing.py
external/ctypes/ctypes/test/test_structures.py
external/ctypes/docs/manual/make.bat
external/ctypes/docs/manual/mkpydoc.py
external/ctypes/docs/manual/reference.txt
external/ctypes/docs/manual/test-tutorial.py
external/ctypes/docs/manual/tutorial.txt
external/ctypes/env.bat
external/ctypes/setup.py
external/ctypes/source/_ctypes.c
external/ctypes/source/_ctypes_test.c
external/ctypes/source/callbacks.c
external/ctypes/source/callproc.c
external/ctypes/source/cfield.c
external/ctypes/source/ctypes.h
external/ctypes/source/libffi/configure
external/ctypes/source/libffi/configure.ac
external/ctypes/source/libffi/fficonfig.h.in
external/ctypes/source/libffi/fficonfig.py.in
external/ctypes/source/libffi/src/powerpc/darwin.S
external/ctypes/source/libffi/src/powerpc/darwin_closure.S
external/ctypes/source/libffi/src/powerpc/ffi_darwin.c
external/ctypes/source/libffi/src/prep_cif.c
external/ctypes/source/libffi/src/x86/ffitarget.h
external/ctypes/source/stgdict.c
Log:
Import ctypes version 0.9.9.7.
For changes see the ChangeLog file.
Modified: external/ctypes/ANNOUNCE
==============================================================================
--- external/ctypes/ANNOUNCE (original)
+++ external/ctypes/ANNOUNCE Sat Jun 10 22:08:12 2006
@@ -1,5 +1,5 @@
-ctypes 0.9.9.6 released - Apr 20, 2006
-=====================================
+ctypes 0.9.9.7 released - June 9, 2006
+======================================
Overview
@@ -17,6 +17,30 @@
libffi supports this platform.
+Changes in 0.9.9.7
+
+ Fixes for 64-bit big endian machines.
+
+ It is now possible to read and write any index of pointer
+ instances (up to 0.9.9.6, reading was allowed for any index, but
+ writing only for index zero).
+
+ Support for unnamed (anonymous) structure fields has been added,
+ the field names must be listed in the '_anonymous_' class
+ variable. Fields of unnamed structure fields can be accessed
+ directly from the parent structure.
+
+ Enabled darwin/x86 support for libffi (Bob Ippolito and Ronald
+ Oussuren).
+
+ Added support for variable sized data structures: array
+ types with exactly 1 element don't do bounds checking any more,
+ and a resize function can resize the internal memory buffer of
+ ctypes instances.
+
+ Fixed a bug with certain array or structure types that contained
+ more than 256 elements.
+
Changes in 0.9.9.6
The most important change is that the old way to load libraries
Added: external/ctypes/BUGS
==============================================================================
--- (empty file)
+++ external/ctypes/BUGS Sat Jun 10 22:08:12 2006
@@ -0,0 +1,2 @@
+- Memory leak in the _pointer_type_cache dictionary since types are
+ made immortal.
Modified: external/ctypes/ChangeLog
==============================================================================
--- external/ctypes/ChangeLog (original)
+++ external/ctypes/ChangeLog Sat Jun 10 22:08:12 2006
@@ -1,3 +1,105 @@
+2006-06-10 Thomas Heller <theller at python.net>
+
+ * Tagged release_0_9_9_7.
+
+ * Fix build on MIPS for libffi.
+
+2006-06-09 Thomas Heller <theller at python.net>
+
+ * Correctly support nested anonymous structures/union fields.
+
+ * Remove the restriction that pointer item assignments only work
+ with index of zero. Another fix for the cast function to keep
+ needed objects alive.
+
+ * A casted object does now reference the source objects '_objects'
+ member.
+
+ * It is now possible to assign arbitrary indexes on pointer
+ instances.
+
+2006-06-08 Thomas Heller <theller at python.net>
+
+ * Merged in changes done in Python trunk: Fixes for 64-bit big
+ endian machines.
+
+2006-06-02 Thomas Heller <theller at python.net>
+
+ * Fixed slice assignment to variable-sized arrays, with test.
+
+2006-06-01 Thomas Heller <theller at python.net>
+
+ * Added support for unnamed structure fields, they must be listed
+ in the '_anonymous_' class variable.
+
+2006-05-31 Thomas Heller <theller at python.net>
+
+ * Merged in changes done in Python trunk, by Bob Ippolito and
+ Ronald Oussuren: enable darwin/x86 support for libffi and hence
+ ctypes (doesn't yet support --enable-universalsdk)
+
+2006-05-23 Thomas Heller <theller at python.net>
+
+ * ctypes\__init__.py: Fixed a possible FutureWarning when id()
+ returned an integer less than zero or larger than sys.maxint, in
+ CDLL.__repr__.
+
+2006-05-19 Thomas Heller <theller at python.net>
+
+ * docs\anatomy.txt: Add some documentation, also containing
+ doctest testcases, about some ctypes object internals.
+
+ * docs\manual\tutorial.txt: Document variable-sized data types.
+
+ * source\_ctypes.c: Allow zero-sized arrays again, although
+ accessing elements will always raise IndexError.
+
+ * source\_ctypes.c: Change the way unique_key calculates the keys
+ into the b_objects array. The previous way was broken for arrays
+ or structures having more than 256 components, which led to
+ strange errors.
+
+2006-05-18 Thomas Heller <theller at python.net>
+
+ * source\callproc.c: Fix compiler warning about comparison of
+ signed and unsigned values.
+
+ * source\_ctypes.c: Correct refcount issues in the (unlikely) case
+ that KeepRef fails.
+
+2006-05-12 Thomas Heller <theller at python.net>
+
+ * Bug fix for the cast function, so that it better keeps needed
+ objects alive. Prevent creation of array types with zero or
+ negative sizes.
+
+ * Implemented support for variable sized data structures: array
+ types with exactly 1 element don't do bounds checking any more,
+ and a resize function can resize the internal memory buffer of
+ ctypes instances.
+
+ * Some fixes to the test-suite. Free allocated memory, remove
+ duplicate tests, don't run unreliable tests by default.
+
+2006-04-28 Thomas Heller <theller at python.net>
+
+ * docs/manual/tutorial.txt: End each code sample with '>>>', so
+ that doctest also works on the LaTeX version of the tutorial
+ (otherwise some tests would break because doctest would see
+ '\end{verbatim}' as expected output.
+
+ * docs/manual/test-tutorial.py: Python 2.5a2 formats exceptions in
+ a different way (I'm not sure if this will be fixed or not). Add
+ doctest.IGNORE_EXCEPTION_DETAIL.
+
+2006-04-26 Thomas Heller <theller at python.net>
+
+ * Tagged release_0_9_9_6, and released it.
+
+2006-04-25 Thomas Heller <theller at python.net>
+
+ * Fix compiler warnings on Darwin, patch by Brett Canon.
+
2006-04-19 Thomas Heller <theller at python.net>
* docs\manual\tutorial.txt: Updates to the tutorial.
Modified: external/ctypes/MANIFEST.in
==============================================================================
--- external/ctypes/MANIFEST.in (original)
+++ external/ctypes/MANIFEST.in Sat Jun 10 22:08:12 2006
@@ -1,5 +1,5 @@
# standard files
-include ACKS ANNOUNCE ChangeLog MANIFEST MANIFEST.in LICENSE.txt NEWS.txt README*
+include ACKS ANNOUNCE BUGS ChangeLog MANIFEST MANIFEST.in LICENSE.txt NEWS.txt README*
# support files for development
include ctypes-dev.el
@@ -25,6 +25,7 @@
include wince/_ctypes.vcw wince/_ctypes.vcp wince/_ctypes_test.vcp
# docs/manual
+include docs/anatomy.txt
include docs/manual/tutorial.txt
include docs/manual/tutorial.html
include docs/manual/mkpydoc.py
Added: external/ctypes/TODO
==============================================================================
--- (empty file)
+++ external/ctypes/TODO Sat Jun 10 22:08:12 2006
@@ -0,0 +1,12 @@
+to-do list for ctypes
+---------------------
+
+- Docs, docs, docs.
+
+- Integrate newer libffi sources (HPPA architecture).
+
+- Finish the MingW32 port.
+
+- Port to Win64 (AMD).
+
+- Remove the _pointer_type_cache leak.
Modified: external/ctypes/ctypes/__init__.py
==============================================================================
--- external/ctypes/ctypes/__init__.py (original)
+++ external/ctypes/ctypes/__init__.py Sat Jun 10 22:08:12 2006
@@ -1,7 +1,6 @@
"""create and manipulate C data types in Python"""
import os as _os, sys as _sys
-from itertools import chain as _chain
# special developer support to use ctypes from the CVS sandbox,
# without installing it
@@ -11,7 +10,7 @@
execfile(_magicfile)
del _magicfile
-__version__ = "0.9.9.6"
+__version__ = "0.9.9.7"
from _ctypes import Union, Structure, Array
from _ctypes import _Pointer
@@ -119,7 +118,7 @@
elif _os.name == "posix":
from _ctypes import dlopen as _dlopen
-from _ctypes import sizeof, byref, addressof, alignment
+from _ctypes import sizeof, byref, addressof, alignment, resize
from _ctypes import _SimpleCData
class py_object(_SimpleCData):
@@ -301,7 +300,7 @@
return "<%s '%s', handle %x at %x>" % \
(self.__class__.__name__, self._name,
(self._handle & (_sys.maxint*2 + 1)),
- id(self))
+ id(self) & (_sys.maxint*2 + 1))
def __getattr__(self, name):
if name.startswith('__') and name.endswith('__'):
@@ -427,12 +426,10 @@
_restype_ = restype
_flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
return CFunctionType
-_cast = PYFUNCTYPE(py_object, c_void_p, py_object)(_cast_addr)
+_cast = PYFUNCTYPE(py_object, c_void_p, py_object, py_object)(_cast_addr)
def cast(obj, typ):
- result = _cast(obj, typ)
- result.__keepref = obj
- return result
+ return _cast(obj, obj, typ)
_string_at = CFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr)
def string_at(ptr, size=0):
Added: external/ctypes/ctypes/test/test_anon.py
==============================================================================
--- (empty file)
+++ external/ctypes/ctypes/test/test_anon.py Sat Jun 10 22:08:12 2006
@@ -0,0 +1,60 @@
+import unittest
+from ctypes import *
+
+class AnonTest(unittest.TestCase):
+
+ def test_anon(self):
+ class ANON(Union):
+ _fields_ = [("a", c_int),
+ ("b", c_int)]
+
+ class Y(Structure):
+ _fields_ = [("x", c_int),
+ ("_", ANON),
+ ("y", c_int)]
+ _anonymous_ = ["_"]
+
+ self.failUnlessEqual(Y.a.offset, sizeof(c_int))
+ self.failUnlessEqual(Y.b.offset, sizeof(c_int))
+
+ self.failUnlessEqual(ANON.a.offset, 0)
+ self.failUnlessEqual(ANON.b.offset, 0)
+
+ def test_anon_nonseq(self):
+ # TypeError: _anonymous_ must be a sequence
+ self.failUnlessRaises(TypeError,
+ lambda: type(Structure)("Name",
+ (Structure,),
+ {"_fields_": [], "_anonymous_": 42}))
+
+ def test_anon_nonmember(self):
+ # AttributeError: type object 'Name' has no attribute 'x'
+ self.failUnlessRaises(AttributeError,
+ lambda: type(Structure)("Name",
+ (Structure,),
+ {"_fields_": [],
+ "_anonymous_": ["x"]}))
+
+ def test_nested(self):
+ class ANON_S(Structure):
+ _fields_ = [("a", c_int)]
+
+ class ANON_U(Union):
+ _fields_ = [("_", ANON_S),
+ ("b", c_int)]
+ _anonymous_ = ["_"]
+
+ class Y(Structure):
+ _fields_ = [("x", c_int),
+ ("_", ANON_U),
+ ("y", c_int)]
+ _anonymous_ = ["_"]
+
+ self.failUnlessEqual(Y.x.offset, 0)
+ self.failUnlessEqual(Y.a.offset, sizeof(c_int))
+ self.failUnlessEqual(Y.b.offset, sizeof(c_int))
+ self.failUnlessEqual(Y._.offset, sizeof(c_int))
+ self.failUnlessEqual(Y.y.offset, sizeof(c_int) * 2)
+
+if __name__ == "__main__":
+ unittest.main()
Modified: external/ctypes/ctypes/test/test_cast.py
==============================================================================
--- external/ctypes/ctypes/test/test_cast.py (original)
+++ external/ctypes/ctypes/test/test_cast.py Sat Jun 10 22:08:12 2006
@@ -30,17 +30,32 @@
ptr = cast(address, POINTER(c_int))
self.failUnlessEqual([ptr[i] for i in range(3)], [42, 17, 2])
+ def test_p2a_objects(self):
+ array = (c_char_p * 5)()
+ self.failUnlessEqual(array._objects, None)
+ array[0] = "foo bar"
+ self.failUnlessEqual(array._objects, {'0': "foo bar"})
- def test_ptr2array(self):
- array = (c_int * 3)(42, 17, 2)
+ p = cast(array, POINTER(c_char_p))
+ # array and p share a common _objects attribute
+ self.failUnless(p._objects is array._objects)
+ self.failUnlessEqual(array._objects, {'0': "foo bar", id(array): array})
+ p[0] = "spam spam"
+ self.failUnlessEqual(p._objects, {'0': "spam spam", id(array): array})
+ self.failUnless(array._objects is p._objects)
+ p[1] = "foo bar"
+ self.failUnlessEqual(p._objects, {'1': 'foo bar', '0': "spam spam", id(array): array})
+ self.failUnless(array._objects is p._objects)
- from sys import getrefcount
-
- before = getrefcount(array)
- ptr = cast(array, POINTER(c_int))
- self.failUnlessEqual(getrefcount(array), before + 1)
- del ptr
- self.failUnlessEqual(getrefcount(array), before)
+ def test_other(self):
+ p = cast((c_int * 4)(1, 2, 3, 4), POINTER(c_int))
+ self.failUnlessEqual(p[:4], [1,2, 3, 4])
+ c_int()
+ self.failUnlessEqual(p[:4], [1, 2, 3, 4])
+ p[2] = 96
+ self.failUnlessEqual(p[:4], [1, 2, 96, 4])
+ c_int()
+ self.failUnlessEqual(p[:4], [1, 2, 96, 4])
if __name__ == "__main__":
unittest.main()
Modified: external/ctypes/ctypes/test/test_cfuncs.py
==============================================================================
--- external/ctypes/ctypes/test/test_cfuncs.py (original)
+++ external/ctypes/ctypes/test/test_cfuncs.py Sat Jun 10 22:08:12 2006
@@ -40,41 +40,49 @@
def test_short(self):
self._dll.tf_h.restype = c_short
+ self._dll.tf_h.argtypes = (c_short,)
self.failUnlessEqual(self._dll.tf_h(-32766), -10922)
self.failUnlessEqual(self.S(), -32766)
def test_short_plus(self):
self._dll.tf_bh.restype = c_short
+ self._dll.tf_bh.argtypes = (c_byte, c_short)
self.failUnlessEqual(self._dll.tf_bh(0, -32766), -10922)
self.failUnlessEqual(self.S(), -32766)
def test_ushort(self):
self._dll.tf_H.restype = c_ushort
+ self._dll.tf_H.argtypes = (c_ushort,)
self.failUnlessEqual(self._dll.tf_H(65535), 21845)
self.failUnlessEqual(self.U(), 65535)
def test_ushort_plus(self):
self._dll.tf_bH.restype = c_ushort
+ self._dll.tf_bH.argtypes = (c_byte, c_ushort)
self.failUnlessEqual(self._dll.tf_bH(0, 65535), 21845)
self.failUnlessEqual(self.U(), 65535)
def test_int(self):
self._dll.tf_i.restype = c_int
+ self._dll.tf_i.argtypes = (c_int,)
self.failUnlessEqual(self._dll.tf_i(-2147483646), -715827882)
self.failUnlessEqual(self.S(), -2147483646)
def test_int_plus(self):
self._dll.tf_bi.restype = c_int
+ self._dll.tf_bi.argtypes = (c_byte, c_int)
self.failUnlessEqual(self._dll.tf_bi(0, -2147483646), -715827882)
self.failUnlessEqual(self.S(), -2147483646)
def test_uint(self):
self._dll.tf_I.restype = c_uint
+ self._dll.tf_I.argtypes = (c_uint,)
self.failUnlessEqual(self._dll.tf_I(4294967295), 1431655765)
self.failUnlessEqual(self.U(), 4294967295)
def test_uint_plus(self):
self._dll.tf_bI.restype = c_uint
+ self._dll.tf_bI.argtypes = (c_byte, c_uint)
self.failUnlessEqual(self._dll.tf_bI(0, 4294967295), 1431655765)
self.failUnlessEqual(self.U(), 4294967295)
Modified: external/ctypes/ctypes/test/test_find.py
==============================================================================
--- external/ctypes/ctypes/test/test_find.py (original)
+++ external/ctypes/ctypes/test/test_find.py Sat Jun 10 22:08:12 2006
@@ -39,9 +39,23 @@
if lib_glu:
self.glu = CDLL(lib_glu, RTLD_GLOBAL)
if lib_glut:
- self.glut = CDLL(lib_glut)
+ # On some systems, additional libraries seem to be
+ # required, loading glut fails with
+ # "OSError: /usr/lib/libglut.so.3: undefined symbol: XGetExtensionVersion"
+ # I cannot figure out how to repair the test on these
+ # systems (red hat), so we ignore it when the glut or gle
+ # libraries cannot be loaded. See also:
+ # https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1478253&group_id=5470
+ # http://mail.python.org/pipermail/python-dev/2006-May/064789.html
+ try:
+ self.glut = CDLL(lib_glut)
+ except OSError:
+ pass
if lib_gle:
- self.gle = CDLL(lib_gle)
+ try:
+ self.gle = CDLL(lib_gle)
+ except OSError:
+ pass
if lib_gl:
def test_gl(self):
Modified: external/ctypes/ctypes/test/test_keeprefs.py
==============================================================================
--- external/ctypes/ctypes/test/test_keeprefs.py (original)
+++ external/ctypes/ctypes/test/test_keeprefs.py Sat Jun 10 22:08:12 2006
@@ -61,6 +61,8 @@
r.ul.x = 22
r.ul.y = 44
self.assertEquals(r._objects, {'0': {}})
+ r.lr = POINT()
+ self.assertEquals(r._objects, {'0': {}, '1': {}})
class ArrayTestCase(unittest.TestCase):
def test_cint_array(self):
@@ -86,9 +88,10 @@
self.assertEquals(x._objects, {'1': {}})
class PointerTestCase(unittest.TestCase):
- def X_test_p_cint(self):
- x = pointer(c_int(42))
- print x._objects
+ def test_p_cint(self):
+ i = c_int(42)
+ x = pointer(i)
+ self.failUnlessEqual(x._objects, {'1': i})
class DeletePointerTestCase(unittest.TestCase):
def X_test(self):
Modified: external/ctypes/ctypes/test/test_loading.py
==============================================================================
--- external/ctypes/ctypes/test/test_loading.py (original)
+++ external/ctypes/ctypes/test/test_loading.py Sat Jun 10 22:08:12 2006
@@ -51,8 +51,9 @@
if os.name in ("nt", "ce"):
def test_load_library(self):
- print find_library("kernel32")
- print find_library("user32")
+ if is_resource_enabled("printing"):
+ print find_library("kernel32")
+ print find_library("user32")
if os.name == "nt":
windll.kernel32.GetModuleHandleW
Added: external/ctypes/ctypes/test/test_objects.py
==============================================================================
--- (empty file)
+++ external/ctypes/ctypes/test/test_objects.py Sat Jun 10 22:08:12 2006
@@ -0,0 +1,66 @@
+r'''
+This tests the '_objects' attribute of ctypes instances. '_objects'
+holds references to objects that must be kept alive as long as the
+ctypes instance, to make sure that the memory buffer is valid.
+
+WARNING: The '_objects' attribute is exposed ONLY for debugging ctypes itself,
+it MUST NEVER BE MODIFIED!
+
+'_objects' is initialized to a dictionary on first use, before that it
+is None.
+
+Here is an array of string pointers:
+
+>>> from ctypes import *
+>>> array = (c_char_p * 5)()
+>>> print array._objects
+None
+>>>
+
+The memory block stores pointers to strings, and the strings itself
+assigned from Python must be kept.
+
+>>> array[4] = 'foo bar'
+>>> array._objects
+{'4': 'foo bar'}
+>>> array[4]
+'foo bar'
+>>>
+
+It gets more complicated when the ctypes instance itself is contained
+in a 'base' object.
+
+>>> class X(Structure):
+... _fields_ = [("x", c_int), ("y", c_int), ("array", c_char_p * 5)]
+...
+>>> x = X()
+>>> print x._objects
+None
+>>>
+
+The'array' attribute of the 'x' object shares part of the memory buffer
+of 'x' ('_b_base_' is either None, or the root object owning the memory block):
+
+>>> print x.array._b_base_ # doctest: +ELLIPSIS
+<ctypes.test.test_objects.X object at 0x...>
+>>>
+
+>>> x.array[0] = 'spam spam spam'
+>>> x._objects
+{'0:2': 'spam spam spam'}
+>>> x.array._b_base_._objects
+{'0:2': 'spam spam spam'}
+>>>
+
+'''
+
+import unittest, doctest
+
+import ctypes.test.test_objects
+
+class TestCase(unittest.TestCase):
+ def test(self):
+ doctest.testmod(ctypes.test.test_objects)
+
+if __name__ == '__main__':
+ doctest.testmod(ctypes.test.test_objects)
Modified: external/ctypes/ctypes/test/test_pointers.py
==============================================================================
--- external/ctypes/ctypes/test/test_pointers.py (original)
+++ external/ctypes/ctypes/test/test_pointers.py Sat Jun 10 22:08:12 2006
@@ -133,28 +133,7 @@
self.failUnlessEqual(p[0], 42)
self.failUnlessEqual(p.contents.value, 42)
- def test_incomplete(self):
- lpcell = POINTER("cell")
- class cell(Structure):
- _fields_ = [("value", c_int),
- ("next", lpcell)]
- SetPointerType(lpcell, cell)
-
- # Make a structure containing a pointer to itself:
- c = cell()
- c.value = 42
- c.next = pointer(c)
-
- result = []
- for i in range(8):
- result.append(c.value)
- c = c.next[0]
- self.failUnlessEqual(result, [42] * 8)
-
- from ctypes import _pointer_type_cache
- del _pointer_type_cache[cell]
-
- def test_charpp( self ):
+ def test_charpp(self):
"""Test that a character pointer-to-pointer is correctly passed"""
dll = CDLL(_ctypes_test.__file__)
func = dll._testfunc_c_p_p
Modified: external/ctypes/ctypes/test/test_python_api.py
==============================================================================
--- external/ctypes/ctypes/test/test_python_api.py (original)
+++ external/ctypes/ctypes/test/test_python_api.py Sat Jun 10 22:08:12 2006
@@ -1,5 +1,6 @@
from ctypes import *
import unittest, sys
+from ctypes.test import is_resource_enabled
################################################################
# This section should be moved into ctypes\__init__.py, when it's ready.
@@ -33,20 +34,24 @@
del pyob
self.failUnlessEqual(grc(s), refcnt)
- def test_PyInt_Long(self):
- ref42 = grc(42)
- pythonapi.PyInt_FromLong.restype = py_object
- self.failUnlessEqual(pythonapi.PyInt_FromLong(42), 42)
-
- self.failUnlessEqual(grc(42), ref42)
-
- pythonapi.PyInt_AsLong.argtypes = (py_object,)
- pythonapi.PyInt_AsLong.restype = c_long
-
- res = pythonapi.PyInt_AsLong(42)
- self.failUnlessEqual(grc(res), ref42 + 1)
- del res
- self.failUnlessEqual(grc(42), ref42)
+ if is_resource_enabled("refcount"):
+ # This test is unreliable, because it is possible that code in
+ # unittest changes the refcount of the '42' integer. So, it
+ # is disabled by default.
+ def test_PyInt_Long(self):
+ ref42 = grc(42)
+ pythonapi.PyInt_FromLong.restype = py_object
+ self.failUnlessEqual(pythonapi.PyInt_FromLong(42), 42)
+
+ self.failUnlessEqual(grc(42), ref42)
+
+ pythonapi.PyInt_AsLong.argtypes = (py_object,)
+ pythonapi.PyInt_AsLong.restype = c_long
+
+ res = pythonapi.PyInt_AsLong(42)
+ self.failUnlessEqual(grc(res), ref42 + 1)
+ del res
+ self.failUnlessEqual(grc(42), ref42)
def test_PyObj_FromPtr(self):
s = "abc def ghi jkl"
Modified: external/ctypes/ctypes/test/test_slicing.py
==============================================================================
--- external/ctypes/ctypes/test/test_slicing.py (original)
+++ external/ctypes/ctypes/test/test_slicing.py Sat Jun 10 22:08:12 2006
@@ -35,20 +35,45 @@
self.assertRaises(ValueError, setslice, a, 0, 5, range(32))
def test_char_ptr(self):
- s = "abcdefghijklmnopqrstuvwxyz\0"
+ s = "abcdefghijklmnopqrstuvwxyz"
dll = CDLL(_ctypes_test.__file__)
dll.my_strdup.restype = POINTER(c_char)
+ dll.my_free.restype = None
res = dll.my_strdup(s)
self.failUnlessEqual(res[:len(s)], s)
import operator
self.assertRaises(TypeError, operator.setslice,
res, 0, 5, u"abcde")
+ dll.my_free(res)
dll.my_strdup.restype = POINTER(c_byte)
res = dll.my_strdup(s)
- self.failUnlessEqual(res[:len(s)-1], range(ord("a"), ord("z")+1))
+ self.failUnlessEqual(res[:len(s)], range(ord("a"), ord("z")+1))
+ dll.my_free(res)
+
+ def test_char_ptr_with_free(self):
+ dll = CDLL(_ctypes_test.__file__)
+ s = "abcdefghijklmnopqrstuvwxyz"
+
+ class allocated_c_char_p(c_char_p):
+ pass
+
+ dll.my_free.restype = None
+ def errcheck(result, func, args):
+ retval = result.value
+ dll.my_free(result)
+ return retval
+
+ dll.my_strdup.restype = allocated_c_char_p
+ dll.my_strdup.errcheck = errcheck
+ try:
+ res = dll.my_strdup(s)
+ self.failUnlessEqual(res, s)
+ finally:
+ del dll.my_strdup.errcheck
+
def test_char_array(self):
s = "abcdefghijklmnopqrstuvwxyz\0"
@@ -68,12 +93,14 @@
dll = CDLL(_ctypes_test.__file__)
dll.my_wcsdup.restype = POINTER(c_wchar)
dll.my_wcsdup.argtypes = POINTER(c_wchar),
+ dll.my_free.restype = None
res = dll.my_wcsdup(s)
self.failUnlessEqual(res[:len(s)], s)
import operator
self.assertRaises(TypeError, operator.setslice,
res, 0, 5, u"abcde")
+ dll.my_free(res)
if sizeof(c_wchar) == sizeof(c_short):
dll.my_wcsdup.restype = POINTER(c_short)
@@ -81,8 +108,11 @@
dll.my_wcsdup.restype = POINTER(c_int)
elif sizeof(c_wchar) == sizeof(c_long):
dll.my_wcsdup.restype = POINTER(c_long)
+ else:
+ return
res = dll.my_wcsdup(s)
self.failUnlessEqual(res[:len(s)-1], range(ord("a"), ord("z")+1))
+ dll.my_free(res)
################################################################
Modified: external/ctypes/ctypes/test/test_structures.py
==============================================================================
--- external/ctypes/ctypes/test/test_structures.py (original)
+++ external/ctypes/ctypes/test/test_structures.py Sat Jun 10 22:08:12 2006
@@ -138,8 +138,8 @@
self.failUnlessEqual(X.y.size, sizeof(c_char))
# readonly
- self.assertRaises(TypeError, setattr, X.x, "offset", 92)
- self.assertRaises(TypeError, setattr, X.x, "size", 92)
+ self.assertRaises((TypeError, AttributeError), setattr, X.x, "offset", 92)
+ self.assertRaises((TypeError, AttributeError), setattr, X.x, "size", 92)
class X(Union):
_fields_ = [("x", c_int),
@@ -152,8 +152,8 @@
self.failUnlessEqual(X.y.size, sizeof(c_char))
# readonly
- self.assertRaises(TypeError, setattr, X.x, "offset", 92)
- self.assertRaises(TypeError, setattr, X.x, "size", 92)
+ self.assertRaises((TypeError, AttributeError), setattr, X.x, "offset", 92)
+ self.assertRaises((TypeError, AttributeError), setattr, X.x, "size", 92)
# XXX Should we check nested data types also?
# offset is always relative to the class...
@@ -294,7 +294,7 @@
# In Python 2.5, Exception is a new-style class, and the repr changed
if issubclass(Exception, object):
self.failUnlessEqual(msg,
- "(Phone) <class 'exceptions.TypeError'>: "
+ "(Phone) <type 'exceptions.TypeError'>: "
"expected string or Unicode object, int found")
else:
self.failUnlessEqual(msg,
@@ -305,7 +305,7 @@
self.failUnlessEqual(cls, RuntimeError)
if issubclass(Exception, object):
self.failUnlessEqual(msg,
- "(Phone) <class 'exceptions.ValueError'>: too many initializers")
+ "(Phone) <type 'exceptions.ValueError'>: too many initializers")
else:
self.failUnlessEqual(msg, "(Phone) exceptions.ValueError: too many initializers")
Added: external/ctypes/ctypes/test/test_varsize_struct.py
==============================================================================
--- (empty file)
+++ external/ctypes/ctypes/test/test_varsize_struct.py Sat Jun 10 22:08:12 2006
@@ -0,0 +1,115 @@
+from ctypes import *
+import unittest
+
+class VarSizeTest(unittest.TestCase):
+ def test_resize(self):
+ class X(Structure):
+ _fields_ = [("item", c_int),
+ ("array", c_int * 1)]
+
+ self.failUnlessEqual(sizeof(X), sizeof(c_int) * 2)
+ x = X()
+ x.item = 42
+ x.array[0] = 100
+ self.failUnlessEqual(sizeof(x), sizeof(c_int) * 2)
+
+ # make room for one additional item
+ new_size = sizeof(X) + sizeof(c_int) * 1
+ resize(x, new_size)
+ self.failUnlessEqual(sizeof(x), new_size)
+ self.failUnlessEqual((x.item, x.array[0]), (42, 100))
+
+ # make room for 10 additional items
+ new_size = sizeof(X) + sizeof(c_int) * 9
+ resize(x, new_size)
+ self.failUnlessEqual(sizeof(x), new_size)
+ self.failUnlessEqual((x.item, x.array[0]), (42, 100))
+
+ # make room for one additional item
+ new_size = sizeof(X) + sizeof(c_int) * 1
+ resize(x, new_size)
+ self.failUnlessEqual(sizeof(x), new_size)
+ self.failUnlessEqual((x.item, x.array[0]), (42, 100))
+
+ def test_array_invalid_length(self):
+ # cannot create arrays with non-positive size
+ self.failUnlessRaises(ValueError, lambda: c_int * -1)
+ self.failUnlessRaises(ValueError, lambda: c_int * -3)
+
+ def test_zerosized_array(self):
+ array = (c_int * 0)()
+ # accessing elements of zero-sized arrays raise IndexError
+ self.failUnlessRaises(IndexError, array.__setitem__, 0, None)
+ self.failUnlessRaises(IndexError, array.__getitem__, 0)
+ self.failUnlessRaises(IndexError, array.__setitem__, 1, None)
+ self.failUnlessRaises(IndexError, array.__getitem__, 1)
+ self.failUnlessRaises(IndexError, array.__setitem__, -1, None)
+ self.failUnlessRaises(IndexError, array.__getitem__, -1)
+
+ def test_varsized_array(self):
+ array = (c_int * 20)(20, 21, 22, 23, 24, 25, 26, 27, 28, 29)
+
+ # no range checking is done on arrays with size == 1
+ varsize_array = (c_int * 1).from_address(addressof(array))
+
+ # __getitem__
+ self.failUnlessEqual(varsize_array[0], 20)
+ self.failUnlessEqual(varsize_array[1], 21)
+ self.failUnlessEqual(varsize_array[2], 22)
+ self.failUnlessEqual(varsize_array[3], 23)
+ self.failUnlessEqual(varsize_array[4], 24)
+ self.failUnlessEqual(varsize_array[5], 25)
+ self.failUnlessEqual(varsize_array[6], 26)
+ self.failUnlessEqual(varsize_array[7], 27)
+ self.failUnlessEqual(varsize_array[8], 28)
+ self.failUnlessEqual(varsize_array[9], 29)
+
+ # still, normal sequence of length one behaviour:
+ self.failUnlessEqual(varsize_array[-1], 20)
+ self.failUnlessRaises(IndexError, lambda: varsize_array[-2])
+ # except for this one, which will raise MemoryError
+ self.failUnlessRaises(MemoryError, lambda: varsize_array[:])
+
+ # __setitem__
+ varsize_array[0] = 100
+ varsize_array[1] = 101
+ varsize_array[2] = 102
+ varsize_array[3] = 103
+ varsize_array[4] = 104
+ varsize_array[5] = 105
+ varsize_array[6] = 106
+ varsize_array[7] = 107
+ varsize_array[8] = 108
+ varsize_array[9] = 109
+
+ for i in range(10):
+ self.failUnlessEqual(varsize_array[i], i + 100)
+ self.failUnlessEqual(array[i], i + 100)
+
+ # __getslice__
+ self.failUnlessEqual(varsize_array[0:10], range(100, 110))
+ self.failUnlessEqual(varsize_array[1:9], range(101, 109))
+ self.failUnlessEqual(varsize_array[1:-1], [])
+
+ # __setslice__
+ varsize_array[0:10] = range(1000, 1010)
+ self.failUnlessEqual(varsize_array[0:10], range(1000, 1010))
+
+ varsize_array[1:9] = range(1001, 1009)
+ self.failUnlessEqual(varsize_array[1:9], range(1001, 1009))
+
+ def test_vararray_is_sane(self):
+ array = (c_int * 15)(20, 21, 22, 23, 24, 25, 26, 27, 28, 29)
+
+ varsize_array = (c_int * 1).from_address(addressof(array))
+ varsize_array[:] = [1, 2, 3, 4, 5]
+
+ self.failUnlessEqual(array[:], [1, 2, 3, 4, 5, 25, 26, 27, 28, 29, 0, 0, 0, 0, 0])
+ self.failUnlessEqual(varsize_array[0:10], [1, 2, 3, 4, 5, 25, 26, 27, 28, 29])
+
+ array[:5] = [10, 11, 12, 13, 14]
+ self.failUnlessEqual(array[:], [10, 11, 12, 13, 14, 25, 26, 27, 28, 29, 0, 0, 0, 0, 0])
+ self.failUnlessEqual(varsize_array[0:10], [10, 11, 12, 13, 14, 25, 26, 27, 28, 29])
+
+if __name__ == "__main__":
+ unittest.main()
Added: external/ctypes/docs/anatomy.txt
==============================================================================
--- (empty file)
+++ external/ctypes/docs/anatomy.txt Sat Jun 10 22:08:12 2006
@@ -0,0 +1,233 @@
+ctypes objects anatomy
+======================
+
+This article describes some of the internals of ctypes types and
+ctypes instances.
+
+The object structure
+--------------------
+
+Definition of the structure that each ctypes instance has::
+
+ struct tagCDataObject {
+ PyObject_HEAD /* Standard Python object fields */
+ char *b_ptr; /* pointer to memory block */
+ int b_needsfree; /* does the object own its memory block? */
+ CDataObject *b_base; /* pointer to base object or NULL */
+ Py_ssize_t b_size; /* size of memory block in bytes */
+ Py_ssize_t b_length; /* number of fields of this object */
+ Py_ssize_t b_index; /* index of this object into the base
+ objects b_object list */
+ PyObject *b_objects; /* references we need to keep */
+ union value b_value; /* a small default buffer */
+ };
+
+Here is what the fields contain:
+
+- ``PyObject_HEAD``
+
+ Standard for every Python object.
+
+- ``b_ptr``
+
+ Pointer to the memory block that the object uses.
+
+- ``b_needsfree``
+
+ A flag which is nonzero if the object does owns the memory block,
+ nonzero otherwise.
+
+- ``b_base``
+
+ If the object does not own the memory block, this is the 'root' object
+ that owns the memory block. Otherwise it is NULL.
+
+- ``b_size``
+
+ Size of memory block in bytes.
+
+- ``b_length``
+
+ ...
+
+- ``b_index``
+
+ If b_base is not NULL, this is the index of this object in the
+ 'root' object.
+
+- ``b_objects``
+
+ This is a pointer containing a Python object which contains other
+ objects that have to be kept alive as long as this object lives.
+ Either ``None``, or a dictionary.
+
+- ``b_value``
+
+ A default memory block which can be used by small objects to avoid
+ a PyMem_Malloc calls.
+
+The memory block
+----------------
+
+Basically, a ctypes object instance has a memory block containing C
+compatible data, plus the ``b_objects`` Python object pointer. The
+latter is used to keep referenced objects alive that are referenced by
+pointers in the memory block.
+
+Consider an array of 4 string pointers, defined by this C code::
+
+ char *string_array[4];
+
+The ctypes definition is::
+
+ >>> from ctypes import *
+ >>> string_array = (c_char_p * 4)()
+ >>>
+
+The memory block of ``string_array`` is initialized to all zeros,
+and retrieving items returns 4 ``None`` objects::
+
+ >>> string_array[:]
+ [None, None, None, None]
+ >>>
+
+We can assign Python strings to the items, and get them back::
+
+ >>> string_array[0] = "foo bar"; string_array[1] = "spam, spam, spam"
+ >>> string_array[0:2]
+ ['foo bar', 'spam, spam, spam']
+ >>>
+
+The memory block contains the *pointers* to the strings (ctypes
+objects implement the buffer interface, so we can use the following
+snippet to examine the buffer contents)::
+
+ >>> print repr(str(buffer(string_array))) # doctest: +SKIP
+ '\x94\xb7\xbd\x00\xfc\x80\xbf\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+ >>>
+
+The strings themselves must also be kept in memory, otherwise the
+pointers in the memory block would access invalid or freed memory.
+The are stored in a dictionary in the``b_objects`` field of the
+``tagCDataObject`` structure defined above. This field is exposed as
+attribute named ``_objects`` to Python, but you should be aware that
+this object is only exposed for debugging (and understanding) of
+ctypes objects, you should *never* modify it::
+
+ >>> string_array._objects
+ {'1': 'spam, spam, spam', '0': 'foo bar'}
+ >>>
+
+The ``b_objects`` dictionary stores these needed objects as values, at
+a key that is calculated from the item index or field index.
+
+Not all ctypes objects have to keep references, simple types like
+integers or floats for example can happily live in the memory block,
+without any other needs. In this case ``b_objects`` contains
+``Py_None``, and the dictionary is never created::
+
+ >>> int_array = (c_int * 3)()
+ >>> int_array[:] = 1, 2, 3
+ >>> print int_array._objects
+ None
+ >>>
+
+XXX remove this?
+
+ >>> s_a = (c_char_p * 5210)()
+ >>> s_a[0] = "zero"
+ >>> s_a[255] = "ali baba"
+ >>> s_a[257] = "forty robbers"
+ >>> s_a[1] = "spam and eggs"
+ >>> s_a._objects
+ {'1': 'spam and eggs', '0': 'zero', '101': 'forty robbers', 'ff': 'ali baba'}
+ >>>
+
+The important thing to keep in mind is that it must be possible to
+'reconstruct' the whole ctypes object from the memory block and the
+``b_objects`` pointer.
+
+
+What happens if a ctypes object is stored in another ctypes object
+field? Define a structure which has a field storing a string array::
+
+ >>> class Container(Structure):
+ ... _fields_ = [("count", c_uint),
+ ... ("strings", c_char_p * 4)]
+ ...
+ >>>
+ >>> container = Container()
+ >>> container.strings = string_array
+ >>> container._objects
+ {'1': {'1': 'spam, spam, spam', '0': 'foo bar'}}
+ >>>
+
+As we can see, the ``string_array`` ``b_objects`` dictionary has been
+inserted into the ``container`` ``b_objects`` dictionary at index 1,
+because 1 is the index of the ``strings`` field. The contents of the
+``string_array`` memory block has been copied into the ``container``
+memory block as well.
+
+Again, things get slighlty more complicated when we use a structure
+containing a pointer field instead of an array field. In this case,
+the memory block of the pointer object must be kept alive in addition
+to the pointer ``b_object`` dictionary. Here is what ctypes does::
+
+ >>> class PointerContainer(Structure):
+ ... _fields_ = [("count", c_uint),
+ ... ("string_p", POINTER(c_char_p))]
+ ...
+ >>> pc = PointerContainer()
+ >>> pc.string_p = string_array
+ >>> pc._objects
+ {'1': ({'1': 'spam, spam, spam', '0': 'foo bar'}, <c_char_p_Array_4 object at 0x...>)}
+ >>>
+
+So, assigning an array instance to a pointer type field stores a tuple
+containing the arrays ``b_objects`` dictionary plus the array object
+itself. Of course, in this case the memory block of ``string_array``
+is NOT copied into the ``PointerContainer`` memory block, only the
+address is copied.
+
+What happens if we retrieve the string pointer from the
+PointerContainer instance? ctypes doesn't do OOR (original object
+return), ctypes returns a new object on each attribute access::
+
+ >>> pc.string_p is pc.string_p
+ False
+ >>>
+
+ >>> print pc.string_p._objects
+ None
+ >>> print pc.string_p._b_base_
+ <PointerContainer object at 0x...>
+ >>>
+
+ >>> other = PointerContainer()
+ >>> other.string_p = pc.string_p
+ >>> print other._objects
+ {'1': {'1': ({'1': 'spam, spam, spam', '0': 'foo bar'}, <c_char_p_Array_4 object at 0x...>)}}
+ >>>
+
+ >>> x = Container()
+ >>> x.strings = (c_char_p * 4)()
+ >>> print x._objects
+ {'1': {}}
+ >>> x.strings[2] = "python ctypes"
+ >>> print x._objects
+ {'1': {}, '2:1': 'python ctypes'}
+ >>>
+
+ >>> class X(Structure):
+ ... _fields_ = [("a", c_int),
+ ... ("b", c_int),
+ ... ("c", c_int),
+ ... ("d", c_int),
+ ... ("container", Container)]
+ ...
+ >>> x = X()
+ >>> x.container.strings = (c_char_p * 4)()
+ >>> x.container.strings[1] = "foobar.org"
+ >>> x._objects
+ {'1:4': {}, '1:1:4': 'foobar.org'}
+ >>>
\ No newline at end of file
Deleted: /external/ctypes/docs/manual/callbacks.txt
==============================================================================
--- /external/ctypes/docs/manual/callbacks.txt Sat Jun 10 22:08:12 2006
+++ (empty file)
@@ -1,31 +0,0 @@
-Callback functions
-++++++++++++++++++
-
-ctypes is able to create C callable functions from Python callables.
-This is useful because sometimes library functions need a callback
-function parameter; the ``qsort`` C function is such an example.
-
-Callback functions are created by first creating a function prototype
-with a call to ``CFUNCTYPE`` or ``WINFUNCTYPE``, specifying the return
-type and the argument types that the callback function will receive.
-
-Calling the prototype with a single Python callable will create and
-return a C-callable function pointer or callback function. Note that
-this allows using prototypes as decorators creating callback
-functions (Windows example)::
-
- @WINFUNCTYPE(BOOL, HWND, LPARAM)
- def enumwindowsproc(hwnd, lParam):
- ....
- return True
-
-When a Python exception is raised in the Python callable, the return
-value of the C callable function is undefined.
-
-Important note: You must keep a reference to the callback AS LONG as
-foreign code will call it! Segfaults will result if the callback is
-cleaned up by Python's garbage collector and external code then
-tries to call it.
-
-Callback objects can also be called from Python - this may be useful
-for debugging.
Added: external/ctypes/docs/manual/ctypes.txt
==============================================================================
--- (empty file)
+++ external/ctypes/docs/manual/ctypes.txt Sat Jun 10 22:08:12 2006
@@ -0,0 +1,11 @@
+:Module: ctypes
+:Summary: A foreign function library for Python.
+:Module Type: standard
+:Author: Thomas Heller <theller at python.net>
+:Synopsis: A foreign function library for Python.
+:Version Added: 2.5
+
+``ctypes`` is a foreign function library for Python.
+
+.. include:: tutorial.txt
+.. include:: reference.txt
Deleted: /external/ctypes/docs/manual/docs.txt
==============================================================================
--- /external/ctypes/docs/manual/docs.txt Sat Jun 10 22:08:12 2006
+++ (empty file)
@@ -1,7 +0,0 @@
-
-.. include:: libraries.txt
-.. include:: functions.txt
-.. include:: callbacks.txt
-.. include:: simple_types.txt
-.. include:: struct_union.txt
-.. include:: utilities.txt
Added: external/ctypes/docs/manual/filter.py
==============================================================================
--- (empty file)
+++ external/ctypes/docs/manual/filter.py Sat Jun 10 22:08:12 2006
@@ -0,0 +1,18 @@
+import sys
+
+TOKENS = """: funcdesc
+: excdesc
+: vardesc
+: classdesc
+: methoddesc
+: memberdesc
+: classdesc*""".splitlines()
+
+for line in open(sys.argv[1], "r"):
+ for token in TOKENS:
+ line = line.rstrip()
+ if line.endswith(token):
+ print line[:-len(token)]
+ break
+ else:
+ print line
Deleted: /external/ctypes/docs/manual/functions.txt
==============================================================================
--- /external/ctypes/docs/manual/functions.txt Sat Jun 10 22:08:12 2006
+++ (empty file)
@@ -1,135 +0,0 @@
-
-Foreign functions
-+++++++++++++++++
-
-Functions exported from loaded shared libraries (foreign functions)
-can be accessed in two ways. The easiest way is to retrieve them as
-attributes of library objects by name::
-
- libc = cdll.find("c") # posix
- libc = cdll.msvcrt # windows
- # attribute access
- atoi = libc.atoi
- # alternative indexing notation
- atoi = libc["atoi"]
-
-This creates an instance of a foreign function object, using the
-calling convention specified by the library object ``cdll``, bound to
-the C library ``atoi`` function. The C function is assumed to return
-an integer (which is correct for ``atoi``), and the argument types are
-not specified (``atoi`` expects a single ``char *`` argument).
-
-If the library function returns a type different from ``int``, the
-``restype`` attribute can be set to a ctypes type that describes the
-return type, or to ``None`` meaning no return value (``void``).
-
-The optional ``argtypes`` attribute can be set to a sequence of ctypes
-types that the function expects.
-
-If needed, the function can (as in C) be called with more arguments
-than the length of the argtypes sequence.
-
-The optional ``errcheck`` attribute can be set to a Python callable,
-which can be used to validate and/or process the library function's return
-value. ``errcheck`` will be called with three arguments, after the
-library function has returned::
-
- errcheck(retval, function, arguments)
-
-``retval`` is the value that the library function returned, converted
-according to ``restype``. ``function`` is the ctypes function object
-(libc.atoi in this case), and ``arguments`` is a tuple containing the
-arguments that have been used to call ``function``. ``errcheck``
-should validate the library function result, raise an error if it
-detects a failure, or return the needed return value otherwise.
-
-Function prototypes
--------------------
-
-Another way to access a function exported from shared libraries is to
-first create a prototype by calling a factory function, specifying the
-return type and the argument types. The factory function itself
-specifies the calling convention: ``CFUNCTYPE`` uses the standard C
-calling convention, ``WINFUNCTYPE`` (Windows only) uses the stdcall
-calling convention. The factory function must be called with the
-return type plus the argument types. For the C ``atoi`` function one
-would use ``CFUNCTYPE(c_int, c_char_p)``.
-
-This returns a function prototype, which is a ctypes type representing
-all functions that are compatible with the calling convention, return
-type, and argument types.
-
-The ``CFUNCTYPE`` and ``WINFUNCTYPE`` factory functions cache and
-reuse the types they create in internal caches, so is is cheap to call
-them over and over with the same or different arguments.
-
-An instance of this function prototype, bound to a foreign library
-function, can be created by calling the prototype with the name of the
-function as string, and a loaded library::
-
- proto = CFUNCTYPE(c_int, c_char_p)
- atoi = proto("atoi", libc)
-
-Parameter flags
----------------
-
-It is possible to specify a third argument ``paramflags`` when calling
-the prototype. This is used to specify additional information for
-each argument: direction of data transfer, the name, and a default
-value.
-
-A tuple with the same length as ``argtypes`` (the second argument in
-the prototype call) must be used. Each item in this tuple must be a
-tuple, having either one, two, or three items.
-
-The first item is the direction flag, an integer specifying if this is
-an input (use ``1``) or an output (use ``2``) parameter. The optional
-second item is a string containing the parameter name, the optional
-third item is a default value for the parameter.
-
-If parameter names are specified, the function object created can be
-called with named arguments in the usual way. Arguments with default
-values do not need to be specified when the function is called.
-
-``out`` parameter types must be pointer types. When the function
-object is called, ctypes will automatically create empty instances of
-them, pass them to the library function, retrieve the value from them,
-and return the value, if there is exactly one ``out`` parameter, or a
-tuple of values, if there is more than one ``out`` parameter. The
-original foreign function return value is lost in this case (but see
-below for how it can be retrieved).
-
-If ``paramflags`` have been used in the prototype call, and an
-``errcheck`` attribute is also present, the ``errcheck`` callable will
-be called with a fourth parameter ``outargs``::
-
- errcheck(retval, function, arguments, outargs)
-
-``outargs`` is a tuple containing all the ``out`` parameters that
-ctypes has created. Without the ``errcheck`` function ctypes would
-retrieve the values contained in these pointer objects, and return
-them. The ``errcheck`` function can let ctypes continue this
-processing by returning the ``outargs`` tuple. It could also return
-something else, or raise an error if it detects that the library
-function has failed.
-
-COM methods (Windows only)
---------------------------
-
-XXX Should this be left undocumented? Mentioned for completeness.
-
-The prototypes created by ``WINFUNCTYPE`` can be called with a
-positive small integer ``index``, a string ``name``, an optional
-``paramflags`` tuple, and a optional ``iid`` parameter.
-
-This creates a function object wrapping a COM method. ``index`` is
-the index into the COM object's virtual function table, ``name`` is
-the name of the COM method (only useful for debugging), ``paramflags``
-has the same meaning as for normal function objects, and ``iid`` is a
-string or buffer containing the interface id of the COM interface
-this method belongs to. ``iid`` is used to get extended COM error
-information in case the method returns a FAILED ''HRESULT`` value.
-
-Note that COM methods expect an additional first argument that is NOT
-listed in the prototypes ``argtypes`` when they are called: this must
-be the integer address of a COM interface pointer.
Deleted: /external/ctypes/docs/manual/libctypes.txt
==============================================================================
--- /external/ctypes/docs/manual/libctypes.txt Sat Jun 10 22:08:12 2006
+++ (empty file)
@@ -1,4 +0,0 @@
-Blah blah short overview of ctypes.
-
-.. include:: tutorial.txt
-.. include:: reference.txt
\ No newline at end of file
Deleted: /external/ctypes/docs/manual/libraries.txt
==============================================================================
--- /external/ctypes/docs/manual/libraries.txt Sat Jun 10 22:08:12 2006
+++ (empty file)
@@ -1,169 +0,0 @@
-
-Shared Libraries, DLLs
-++++++++++++++++++++++
-
-Shared libraries are accessed when compiling/linking a program, and
-when the program is run. The purpose of the ``find`` method is to
-locate a library in a way similar to what the compiler does (on
-platforms with several versions of a shared library the most recent
-should be loaded), while ``load`` acts like when a program is run, and
-uses the runtime loader directly. ``load_version`` works like ``load``
-but tries to be platform independent (for cases where this makes
-sense). Loading via attribute access is a shorthand notation
-especially usefull for interactive use, it is equivalent to calling
-``load_version`` with no version specified.
-
-
-class LibraryLoader
--------------------
-
-Instances of ``LibraryLoader`` are used to load shared libraries.
-Usually there is no need to create a libraryloader, instead one of the
-predefined loaders should be used.
-
-Libraryloaders have the following methods:
-
-``find(name, mode=None)``
-
- Try to find a library, load and return it. ``name`` is the
- library name without any prefix like ``lib``, suffix like ``.so``,
- ``.dylib`` or version number (this is the form used for the posix
- linker option ``-l``).
-
- ``mode`` allows to override the default flags passed to the
- ``dlopen()`` function, ignored on Windows.
-
- On Windows, this method does exactly the same as the ``load``
- method.
-
- On other platforms, this function might call other programs like
- the compiler to find the library. When using ctypes to write a
- shared library wrapping, consider using ``load_version`` or
- ``load`` instead.
-
-``load_version(name, version=None, mode=None)``
-
- Build a system dependent filename from ``name`` and optionally
- ``version``, then load and return it. ``name`` is the library
- name without any prefix like ``lib`` and suffix like ``.so`` or
- ``.dylib``. This method should be used if a library is available
- on different platforms, using the particular naming convention of
- each platform.
-
- ``mode`` allows to override the default flags passed to the
- ``dlopen()`` function, ignored on Windows.
-
- Example: calling ``loader.load_version('z', '1.1.3')`` would
- possibly load ``/usr/lib/libz.1.1.3.dylib`` on Mac OS X, or
- ``/lib/libz.so.1.1.3`` on a Linux system.
-
-``load(libname, mode=None)``
-
- Load and return the library with the given libname. On most
- systems ``libname`` is the filename of the shared library; when
- it's not a pathname it will be searched in a system dependent list
- of locations (on many systems additional search paths can be
- specified by an environment variable). Sometimes the file
- extension (like ``.dll`` on Windows) can be omitted.
-
- ``mode`` allows to override the default flags passed to the
- ``dlopen()`` function. ``RTLD_LOCAL`` and ``RTLD_GLOBAL`` are
- typical values. On Windows, ``mode`` is ignored.
-
-``load_library(pathname, mode=None``
-
- Load and return the library with the given pathname. This method
- passes the ``pathname`` directly to the underlying ``dlopen`` or
- ``LoadLibrary`` function.
-
- ``mode`` allows to override the default flags passed to the
- ``dlopen()`` function. ``RTLD_LOCAL`` and ``RTLD_GLOBAL`` are
- typical values. On Windows, ``mode`` is ignored.
-
-``LoadLibrary(pathname, mode=None)``
-
- This is an alias for the ``load_library`` method documented above,
- maintained for backwards comatibility only.
-
-
-Libaries can also be loaded by accessing them as attributes of the
-loader instance, internally this calls ``load_version`` without
-specifying ``version`` or ``mode``. Obviously this only works for
-libraries with names that are valid Python identifiers, and when the
-name does not start with a ``_`` character.
-
-Predefined library loaders
---------------------------
-
-ctypes provides some LibraryLoader instances, the differences between
-them are the calling conventions the functions will use and the
-default return type of the functions. All these loaders use the
-``RTLD_LOCAL`` mode flag.
-
-Functions can be accessed as named attributes of loaded libraries.
-
-On Windows, structured exception handling is used around the function
-call to protect Python from crashing in case you pass invalid
-parameters to the function.
-
-``cdll``
-
- Functions provided by libraries loaded using the ``cdll`` loader
- will be called with the standard C calling convention, and have a
- default return type of ``int``. ctypes releases the Python global
- interpreter lock (GIL) just before calling the foreign function,
- and reacquires it before returing, so other threads are able to
- run.
-
-``windll``
-
- Windows only. Functions provided by libraries loaded by
- ``windll`` will be called using the Windows ``__stdcall`` calling
- convention. ctypes can detect when the wrong number
- of parameters has been passed to the function call by examining
- the stack pointer before and after the function call. If the
- wrong parameter count was used, an exception is raised (although
- the function really *has* been called). The return value of the
- function is lost in this case. Again, the GIL is released during
- the duration of the function call.
-
-``oledll``
-
- Windows only. ``oledll`` behaves in the same way as ``windll``,
- except that the called function is expected to return a
- ``HRESULT`` value. These are long values containing error or
- success codes. In case the function returns an error ``HRESULT``
- value, a ``WindowsError`` is raised. The GIL is released during the
- duration of function call.
-
-``pydll``
-
- This loader allows to call functions in libraries using the
- *Python* calling convention, for example Python C API functions.
- The GIL is *not* released during the function call, and the state
- of the Python error flag is examined after the function returns.
- If the error flag is set, the Python exception is raised.
-
- ctypes provides a prefabricated instance of ``pydll`` exposing the
- Python C api as the ``pythonapi`` symbol, you should however make
- sure to set the correct ``restype`` for the functions you use.
-
-Library objects
----------------
-
-The library loaders create instances of ``CDLL``, ``WinDLL``,
-``OleDLL``, or ``PyDLL`` classes. You can, however, also load a
-library by constructing one of these classes by calling the
-constructor with the pathname of the library and an optional ``mode``
-argument as described in the previous section.
-
-Library objects implement ``__getattr__`` and ``__getitem__`` methods
-that allow to access foreign functions by attribute access or
-indexing. The latter is useful if the name of the function is not a
-valid Python identifier, or clashes with special Python method names
-that start and end with two underscore characters.
-
-Library objects have two private attributes: ``_name`` is the pathname
-of the library, ``_handle`` is the handle to the library that
-``dlopen`` has returned.
-
Modified: external/ctypes/docs/manual/make.bat
==============================================================================
--- external/ctypes/docs/manual/make.bat (original)
+++ external/ctypes/docs/manual/make.bat Sat Jun 10 22:08:12 2006
@@ -1,3 +1,3 @@
-c:\python24\scripts\rst2html.py manual.txt manual.html
-c:\python24\scripts\rst2html.py docs.txt docs.html
-c:\python24\scripts\rst2html.py tutorial.txt tutorial.html
+filter.py tutorial.txt | c:\python24\python c:\python24\scripts\rst2html.py > tutorial.html
+filter.py reference.txt | c:\python24\python c:\python24\scripts\rst2html.py > reference.html
+filter.py ctypes.txt | c:\python24\python c:\python24\scripts\rst2html.py > ctypes.html
Deleted: /external/ctypes/docs/manual/manual.html
==============================================================================
--- /external/ctypes/docs/manual/manual.html Sat Jun 10 22:08:12 2006
+++ (empty file)
@@ -1,950 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
-<title>ctypes manual</title>
-<style type="text/css">
-
-/*
-:Author: David Goodger
-:Contact: goodger at users.sourceforge.net
-:Date: $Date: 2006/04/13 20:25:29 $
-:Revision: $Revision: 1.5 $
-:Copyright: This stylesheet has been placed in the public domain.
-
-Default cascading style sheet for the HTML output of Docutils.
-
-See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
-customize this style sheet.
-*/
-
-/* used to remove borders from tables and images */
-.borderless, table.borderless td, table.borderless th {
- border: 0 }
-
-table.borderless td, table.borderless th {
- /* Override padding for "table.docutils td" with "! important".
- The right padding separates the table cells. */
- padding: 0 0.5em 0 0 ! important }
-
-.first {
- /* Override more specific margin styles with "! important". */
- margin-top: 0 ! important }
-
-.last, .with-subtitle {
- margin-bottom: 0 ! important }
-
-.hidden {
- display: none }
-
-a.toc-backref {
- text-decoration: none ;
- color: black }
-
-blockquote.epigraph {
- margin: 2em 5em ; }
-
-dl.docutils dd {
- margin-bottom: 0.5em }
-
-/* Uncomment (and remove this text!) to get bold-faced definition list terms
-dl.docutils dt {
- font-weight: bold }
-*/
-
-div.abstract {
- margin: 2em 5em }
-
-div.abstract p.topic-title {
- font-weight: bold ;
- text-align: center }
-
-div.admonition, div.attention, div.caution, div.danger, div.error,
-div.hint, div.important, div.note, div.tip, div.warning {
- margin: 2em ;
- border: medium outset ;
- padding: 1em }
-
-div.admonition p.admonition-title, div.hint p.admonition-title,
-div.important p.admonition-title, div.note p.admonition-title,
-div.tip p.admonition-title {
- font-weight: bold ;
- font-family: sans-serif }
-
-div.attention p.admonition-title, div.caution p.admonition-title,
-div.danger p.admonition-title, div.error p.admonition-title,
-div.warning p.admonition-title {
- color: red ;
- font-weight: bold ;
- font-family: sans-serif }
-
-/* Uncomment (and remove this text!) to get reduced vertical space in
- compound paragraphs.
-div.compound .compound-first, div.compound .compound-middle {
- margin-bottom: 0.5em }
-
-div.compound .compound-last, div.compound .compound-middle {
- margin-top: 0.5em }
-*/
-
-div.dedication {
- margin: 2em 5em ;
- text-align: center ;
- font-style: italic }
-
-div.dedication p.topic-title {
- font-weight: bold ;
- font-style: normal }
-
-div.figure {
- margin-left: 2em ;
- margin-right: 2em }
-
-div.footer, div.header {
- clear: both;
- font-size: smaller }
-
-div.line-block {
- display: block ;
- margin-top: 1em ;
- margin-bottom: 1em }
-
-div.line-block div.line-block {
- margin-top: 0 ;
- margin-bottom: 0 ;
- margin-left: 1.5em }
-
-div.sidebar {
- margin-left: 1em ;
- border: medium outset ;
- padding: 1em ;
- background-color: #ffffee ;
- width: 40% ;
- float: right ;
- clear: right }
-
-div.sidebar p.rubric {
- font-family: sans-serif ;
- font-size: medium }
-
-div.system-messages {
- margin: 5em }
-
-div.system-messages h1 {
- color: red }
-
-div.system-message {
- border: medium outset ;
- padding: 1em }
-
-div.system-message p.system-message-title {
- color: red ;
- font-weight: bold }
-
-div.topic {
- margin: 2em }
-
-h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
-h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
- margin-top: 0.4em }
-
-h1.title {
- text-align: center }
-
-h2.subtitle {
- text-align: center }
-
-hr.docutils {
- width: 75% }
-
-img.align-left {
- clear: left }
-
-img.align-right {
- clear: right }
-
-ol.simple, ul.simple {
- margin-bottom: 1em }
-
-ol.arabic {
- list-style: decimal }
-
-ol.loweralpha {
- list-style: lower-alpha }
-
-ol.upperalpha {
- list-style: upper-alpha }
-
-ol.lowerroman {
- list-style: lower-roman }
-
-ol.upperroman {
- list-style: upper-roman }
-
-p.attribution {
- text-align: right ;
- margin-left: 50% }
-
-p.caption {
- font-style: italic }
-
-p.credits {
- font-style: italic ;
- font-size: smaller }
-
-p.label {
- white-space: nowrap }
-
-p.rubric {
- font-weight: bold ;
- font-size: larger ;
- color: maroon ;
- text-align: center }
-
-p.sidebar-title {
- font-family: sans-serif ;
- font-weight: bold ;
- font-size: larger }
-
-p.sidebar-subtitle {
- font-family: sans-serif ;
- font-weight: bold }
-
-p.topic-title {
- font-weight: bold }
-
-pre.address {
- margin-bottom: 0 ;
- margin-top: 0 ;
- font-family: serif ;
- font-size: 100% }
-
-pre.literal-block, pre.doctest-block {
- margin-left: 2em ;
- margin-right: 2em }
-
-span.classifier {
- font-family: sans-serif ;
- font-style: oblique }
-
-span.classifier-delimiter {
- font-family: sans-serif ;
- font-weight: bold }
-
-span.interpreted {
- font-family: sans-serif }
-
-span.option {
- white-space: nowrap }
-
-span.pre {
- white-space: pre }
-
-span.problematic {
- color: red }
-
-span.section-subtitle {
- /* font-size relative to parent (h1..h6 element) */
- font-size: 80% }
-
-table.citation {
- border-left: solid 1px gray;
- margin-left: 1px }
-
-table.docinfo {
- margin: 2em 4em }
-
-table.docutils {
- margin-top: 0.5em ;
- margin-bottom: 0.5em }
-
-table.footnote {
- border-left: solid 1px black;
- margin-left: 1px }
-
-table.docutils td, table.docutils th,
-table.docinfo td, table.docinfo th {
- padding-left: 0.5em ;
- padding-right: 0.5em ;
- vertical-align: top }
-
-table.docutils th.field-name, table.docinfo th.docinfo-name {
- font-weight: bold ;
- text-align: left ;
- white-space: nowrap ;
- padding-left: 0 }
-
-h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
-h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
- font-size: 100% }
-
-ul.auto-toc {
- list-style-type: none }
-
-</style>
-</head>
-<body>
-<div class="document" id="ctypes-manual">
-<h1 class="title">ctypes manual</h1>
-<p>(work in progress, $Revision: 1.5 $)</p>
-<div class="contents topic">
-<p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
-<ul class="simple">
-<li><a class="reference" href="#shared-libraries-dlls" id="id1" name="id1">Shared Libraries, DLLs</a><ul>
-<li><a class="reference" href="#class-libraryloader" id="id2" name="id2">class LibraryLoader</a></li>
-<li><a class="reference" href="#predefined-library-loaders" id="id3" name="id3">Predefined library loaders</a></li>
-<li><a class="reference" href="#library-objects" id="id4" name="id4">Library objects</a></li>
-</ul>
-</li>
-<li><a class="reference" href="#foreign-functions" id="id5" name="id5">Foreign functions</a><ul>
-<li><a class="reference" href="#function-prototypes" id="id6" name="id6">Function prototypes</a></li>
-<li><a class="reference" href="#parameter-flags" id="id7" name="id7">Parameter flags</a></li>
-<li><a class="reference" href="#com-methods-windows-only" id="id8" name="id8">COM methods (Windows only)</a></li>
-</ul>
-</li>
-<li><a class="reference" href="#callback-functions" id="id9" name="id9">Callback functions</a></li>
-<li><a class="reference" href="#simple-types" id="id10" name="id10">Simple types</a><ul>
-<li><a class="reference" href="#class-attributes-of-simple-types" id="id11" name="id11">Class attributes of simple types</a></li>
-<li><a class="reference" href="#class-methods-of-simple-types" id="id12" name="id12">Class methods of simple types</a></li>
-<li><a class="reference" href="#instance-attributes-of-simple-types" id="id13" name="id13">Instance attributes of simple types</a></li>
-<li><a class="reference" href="#numeric-types" id="id14" name="id14">Numeric types</a></li>
-<li><a class="reference" href="#character-types" id="id15" name="id15">Character types</a></li>
-<li><a class="reference" href="#pointer-types" id="id16" name="id16">Pointer types</a></li>
-<li><a class="reference" href="#string-types" id="id17" name="id17">String types</a></li>
-</ul>
-</li>
-<li><a class="reference" href="#structure-and-union-types" id="id18" name="id18">Structure and union types</a><ul>
-<li><a class="reference" href="#defining-field-names-and-types" id="id19" name="id19">Defining field names and types</a></li>
-<li><a class="reference" href="#packing-fields" id="id20" name="id20">Packing fields</a></li>
-<li><a class="reference" href="#bit-fields" id="id21" name="id21">Bit fields</a></li>
-<li><a class="reference" href="#recursive-data-types" id="id22" name="id22">Recursive data types</a></li>
-<li><a class="reference" href="#byte-order" id="id23" name="id23">Byte order</a></li>
-<li><a class="reference" href="#builtin-functions" id="id24" name="id24">Builtin functions</a></li>
-<li><a class="reference" href="#deprecated-functions" id="id25" name="id25">Deprecated functions</a></li>
-</ul>
-</li>
-</ul>
-</div>
-<div class="section">
-<h1><a class="toc-backref" href="#id1" id="shared-libraries-dlls" name="shared-libraries-dlls">Shared Libraries, DLLs</a></h1>
-<p>Shared libraries are accessed when compiling/linking a program, and
-when the program is run. The purpose of the <tt class="docutils literal"><span class="pre">find</span></tt> method is to
-locate a library in a way similar to what the compiler does (on
-platforms with several versions of a shared library the most recent
-should be loaded), while <tt class="docutils literal"><span class="pre">load</span></tt> acts like when a program is run, and
-uses the runtime loader directly. <tt class="docutils literal"><span class="pre">load_version</span></tt> works like <tt class="docutils literal"><span class="pre">load</span></tt>
-but tries to be platform independent (for cases where this makes
-sense). Loading via attribute access is a shorthand notation
-especially usefull for interactive use, it is equivalent to calling
-<tt class="docutils literal"><span class="pre">load_version</span></tt> with no version specified.</p>
-<div class="section">
-<h2><a class="toc-backref" href="#id2" id="class-libraryloader" name="class-libraryloader">class LibraryLoader</a></h2>
-<p>Instances of <tt class="docutils literal"><span class="pre">LibraryLoader</span></tt> are used to load shared libraries.
-Usually there is no need to create a libraryloader, instead one of the
-predefined loaders should be used.</p>
-<p>Libraryloaders have the following methods:</p>
-<p><tt class="docutils literal"><span class="pre">find(name,</span> <span class="pre">mode=None)</span></tt></p>
-<blockquote>
-<p>Try to find a library, load and return it. <tt class="docutils literal"><span class="pre">name</span></tt> is the
-library name without any prefix like <tt class="docutils literal"><span class="pre">lib</span></tt>, suffix like <tt class="docutils literal"><span class="pre">.so</span></tt>,
-<tt class="docutils literal"><span class="pre">.dylib</span></tt> or version number (this is the form used for the posix
-linker option <tt class="docutils literal"><span class="pre">-l</span></tt>).</p>
-<p><tt class="docutils literal"><span class="pre">mode</span></tt> allows to override the default flags passed to the
-<tt class="docutils literal"><span class="pre">dlopen()</span></tt> function, ignored on Windows.</p>
-<p>On Windows, this method does exactly the same as the <tt class="docutils literal"><span class="pre">load</span></tt>
-method.</p>
-<p>On other platforms, this function might call other programs like
-the compiler to find the library. When using ctypes to write a
-shared library wrapping, consider using <tt class="docutils literal"><span class="pre">load_version</span></tt> or
-<tt class="docutils literal"><span class="pre">load</span></tt> instead.</p>
-</blockquote>
-<p><tt class="docutils literal"><span class="pre">load_version(name,</span> <span class="pre">version=None,</span> <span class="pre">mode=None)</span></tt></p>
-<blockquote>
-<p>Build a system dependent filename from <tt class="docutils literal"><span class="pre">name</span></tt> and optionally
-<tt class="docutils literal"><span class="pre">version</span></tt>, then load and return it. <tt class="docutils literal"><span class="pre">name</span></tt> is the library
-name without any prefix like <tt class="docutils literal"><span class="pre">lib</span></tt> and suffix like <tt class="docutils literal"><span class="pre">.so</span></tt> or
-<tt class="docutils literal"><span class="pre">.dylib</span></tt>. This method should be used if a library is available
-on different platforms, using the particular naming convention of
-each platform.</p>
-<p><tt class="docutils literal"><span class="pre">mode</span></tt> allows to override the default flags passed to the
-<tt class="docutils literal"><span class="pre">dlopen()</span></tt> function, ignored on Windows.</p>
-<p>Example: calling <tt class="docutils literal"><span class="pre">loader.load_version('z',</span> <span class="pre">'1.1.3')</span></tt> would
-possibly load <tt class="docutils literal"><span class="pre">/usr/lib/libz.1.1.3.dylib</span></tt> on Mac OS X, or
-<tt class="docutils literal"><span class="pre">/lib/libz.so.1.1.3</span></tt> on a Linux system.</p>
-</blockquote>
-<p><tt class="docutils literal"><span class="pre">load(libname,</span> <span class="pre">mode=None)</span></tt></p>
-<blockquote>
-<p>Load and return the library with the given libname. On most
-systems <tt class="docutils literal"><span class="pre">libname</span></tt> is the filename of the shared library; when
-it's not a pathname it will be searched in a system dependent list
-of locations (on many systems additional search paths can be
-specified by an environment variable). Sometimes the file
-extension (like <tt class="docutils literal"><span class="pre">.dll</span></tt> on Windows) can be omitted.</p>
-<p><tt class="docutils literal"><span class="pre">mode</span></tt> allows to override the default flags passed to the
-<tt class="docutils literal"><span class="pre">dlopen()</span></tt> function. <tt class="docutils literal"><span class="pre">RTLD_LOCAL</span></tt> and <tt class="docutils literal"><span class="pre">RTLD_GLOBAL</span></tt> are
-typical values. On Windows, <tt class="docutils literal"><span class="pre">mode</span></tt> is ignored.</p>
-</blockquote>
-<p><tt class="docutils literal"><span class="pre">load_library(pathname,</span> <span class="pre">mode=None</span></tt></p>
-<blockquote>
-<p>Load and return the library with the given pathname. This method
-passes the <tt class="docutils literal"><span class="pre">pathname</span></tt> directly to the underlying <tt class="docutils literal"><span class="pre">dlopen</span></tt> or
-<tt class="docutils literal"><span class="pre">LoadLibrary</span></tt> function.</p>
-<p><tt class="docutils literal"><span class="pre">mode</span></tt> allows to override the default flags passed to the
-<tt class="docutils literal"><span class="pre">dlopen()</span></tt> function. <tt class="docutils literal"><span class="pre">RTLD_LOCAL</span></tt> and <tt class="docutils literal"><span class="pre">RTLD_GLOBAL</span></tt> are
-typical values. On Windows, <tt class="docutils literal"><span class="pre">mode</span></tt> is ignored.</p>
-</blockquote>
-<p><tt class="docutils literal"><span class="pre">LoadLibrary(pathname,</span> <span class="pre">mode=None)</span></tt></p>
-<blockquote>
-This is an alias for the <tt class="docutils literal"><span class="pre">load_library</span></tt> method documented above,
-maintained for backwards comatibility only.</blockquote>
-<p>Libaries can also be loaded by accessing them as attributes of the
-loader instance, internally this calls <tt class="docutils literal"><span class="pre">load_version</span></tt> without
-specifying <tt class="docutils literal"><span class="pre">version</span></tt> or <tt class="docutils literal"><span class="pre">mode</span></tt>. Obviously this only works for
-libraries with names that are valid Python identifiers, and when the
-name does not start with a <tt class="docutils literal"><span class="pre">_</span></tt> character.</p>
-</div>
-<div class="section">
-<h2><a class="toc-backref" href="#id3" id="predefined-library-loaders" name="predefined-library-loaders">Predefined library loaders</a></h2>
-<p>ctypes provides some LibraryLoader instances, the differences between
-them are the calling conventions the functions will use and the
-default return type of the functions. All these loaders use the
-<tt class="docutils literal"><span class="pre">RTLD_LOCAL</span></tt> mode flag.</p>
-<p>Functions can be accessed as named attributes of loaded libraries.</p>
-<p>On Windows, structured exception handling is used around the function
-call to protect Python from crashing in case you pass invalid
-parameters to the function.</p>
-<p><tt class="docutils literal"><span class="pre">cdll</span></tt></p>
-<blockquote>
-Functions provided by libraries loaded using the <tt class="docutils literal"><span class="pre">cdll</span></tt> loader
-will be called with the standard C calling convention, and have a
-default return type of <tt class="docutils literal"><span class="pre">int</span></tt>. ctypes releases the Python global
-interpreter lock (GIL) just before calling the foreign function,
-and reacquires it before returing, so other threads are able to
-run.</blockquote>
-<p><tt class="docutils literal"><span class="pre">windll</span></tt></p>
-<blockquote>
-Windows only. Functions provided by libraries loaded by
-<tt class="docutils literal"><span class="pre">windll</span></tt> will be called using the Windows <tt class="docutils literal"><span class="pre">__stdcall</span></tt> calling
-convention. ctypes can detect when the wrong number
-of parameters has been passed to the function call by examining
-the stack pointer before and after the function call. If the
-wrong parameter count was used, an exception is raised (although
-the function really <em>has</em> been called). The return value of the
-function is lost in this case. Again, the GIL is released during
-the duration of the function call.</blockquote>
-<p><tt class="docutils literal"><span class="pre">oledll</span></tt></p>
-<blockquote>
-Windows only. <tt class="docutils literal"><span class="pre">oledll</span></tt> behaves in the same way as <tt class="docutils literal"><span class="pre">windll</span></tt>,
-except that the called function is expected to return a
-<tt class="docutils literal"><span class="pre">HRESULT</span></tt> value. These are long values containing error or
-success codes. In case the function returns an error <tt class="docutils literal"><span class="pre">HRESULT</span></tt>
-value, a <tt class="docutils literal"><span class="pre">WindowsError</span></tt> is raised. The GIL is released during the
-duration of function call.</blockquote>
-<p><tt class="docutils literal"><span class="pre">pydll</span></tt></p>
-<blockquote>
-<p>This loader allows to call functions in libraries using the
-<em>Python</em> calling convention, for example Python C API functions.
-The GIL is <em>not</em> released during the function call, and the state
-of the Python error flag is examined after the function returns.
-If the error flag is set, the Python exception is raised.</p>
-<p>ctypes provides a prefabricated instance of <tt class="docutils literal"><span class="pre">pydll</span></tt> exposing the
-Python C api as the <tt class="docutils literal"><span class="pre">pythonapi</span></tt> symbol, you should however make
-sure to set the correct <tt class="docutils literal"><span class="pre">restype</span></tt> for the functions you use.</p>
-</blockquote>
-</div>
-<div class="section">
-<h2><a class="toc-backref" href="#id4" id="library-objects" name="library-objects">Library objects</a></h2>
-<p>The library loaders create instances of <tt class="docutils literal"><span class="pre">CDLL</span></tt>, <tt class="docutils literal"><span class="pre">WinDLL</span></tt>,
-<tt class="docutils literal"><span class="pre">OleDLL</span></tt>, or <tt class="docutils literal"><span class="pre">PyDLL</span></tt> classes. You can, however, also load a
-library by constructing one of these classes by calling the
-constructor with the pathname of the library and an optional <tt class="docutils literal"><span class="pre">mode</span></tt>
-argument as described in the previous section.</p>
-<p>Library objects implement <tt class="docutils literal"><span class="pre">__getattr__</span></tt> and <tt class="docutils literal"><span class="pre">__getitem__</span></tt> methods
-that allow to access foreign functions by attribute access or
-indexing. The latter is useful if the name of the function is not a
-valid Python identifier, or clashes with special Python method names
-that start and end with two underscore characters.</p>
-<p>Library objects have two private attributes: <tt class="docutils literal"><span class="pre">_name</span></tt> is the pathname
-of the library, <tt class="docutils literal"><span class="pre">_handle</span></tt> is the handle to the library that
-<tt class="docutils literal"><span class="pre">dlopen</span></tt> has returned.</p>
-</div>
-</div>
-<div class="section">
-<h1><a class="toc-backref" href="#id5" id="foreign-functions" name="foreign-functions">Foreign functions</a></h1>
-<p>Functions exported from loaded shared libraries (foreign functions)
-can be accessed in two ways. The easiest way is to retrieve them as
-attributes of library objects by name:</p>
-<pre class="literal-block">
-libc = cdll.find("c") # posix
-libc = cdll.msvcrt # windows
-# attribute access
-atoi = libc.atoi
-# alternative indexing notation
-atoi = libc["atoi"]
-</pre>
-<p>This creates an instance of a foreign function object, using the
-calling convention specified by the library object <tt class="docutils literal"><span class="pre">cdll</span></tt>, bound to
-the C library <tt class="docutils literal"><span class="pre">atoi</span></tt> function. The C function is assumed to return
-an integer (which is correct for <tt class="docutils literal"><span class="pre">atoi</span></tt>), and the argument types are
-not specified (<tt class="docutils literal"><span class="pre">atoi</span></tt> expects a single <tt class="docutils literal"><span class="pre">char</span> <span class="pre">*</span></tt> argument).</p>
-<p>If the library function returns a type different from <tt class="docutils literal"><span class="pre">int</span></tt>, the
-<tt class="docutils literal"><span class="pre">restype</span></tt> attribute can be set to a ctypes type that describes the
-return type, or to <tt class="docutils literal"><span class="pre">None</span></tt> meaning no return value (<tt class="docutils literal"><span class="pre">void</span></tt>).</p>
-<p>The optional <tt class="docutils literal"><span class="pre">argtypes</span></tt> attribute can be set to a sequence of ctypes
-types that the function expects.</p>
-<p>If needed, the function can (as in C) be called with more arguments
-than the length of the argtypes sequence.</p>
-<p>The optional <tt class="docutils literal"><span class="pre">errcheck</span></tt> attribute can be set to a Python callable,
-which can be used to validate and/or process the library function's return
-value. <tt class="docutils literal"><span class="pre">errcheck</span></tt> will be called with three arguments, after the
-library function has returned:</p>
-<pre class="literal-block">
-errcheck(retval, function, arguments)
-</pre>
-<p><tt class="docutils literal"><span class="pre">retval</span></tt> is the value that the library function returned, converted
-according to <tt class="docutils literal"><span class="pre">restype</span></tt>. <tt class="docutils literal"><span class="pre">function</span></tt> is the ctypes function object
-(libc.atoi in this case), and <tt class="docutils literal"><span class="pre">arguments</span></tt> is a tuple containing the
-arguments that have been used to call <tt class="docutils literal"><span class="pre">function</span></tt>. <tt class="docutils literal"><span class="pre">errcheck</span></tt>
-should validate the library function result, raise an error if it
-detects a failure, or return the needed return value otherwise.</p>
-<div class="section">
-<h2><a class="toc-backref" href="#id6" id="function-prototypes" name="function-prototypes">Function prototypes</a></h2>
-<p>Another way to access a function exported from shared libraries is to
-first create a prototype by calling a factory function, specifying the
-return type and the argument types. The factory function itself
-specifies the calling convention: <tt class="docutils literal"><span class="pre">CFUNCTYPE</span></tt> uses the standard C
-calling convention, <tt class="docutils literal"><span class="pre">WINFUNCTYPE</span></tt> (Windows only) uses the stdcall
-calling convention. The factory function must be called with the
-return type plus the argument types. For the C <tt class="docutils literal"><span class="pre">atoi</span></tt> function one
-would use <tt class="docutils literal"><span class="pre">CFUNCTYPE(c_int,</span> <span class="pre">c_char_p)</span></tt>.</p>
-<p>This returns a function prototype, which is a ctypes type representing
-all functions that are compatible with the calling convention, return
-type, and argument types.</p>
-<p>The <tt class="docutils literal"><span class="pre">CFUNCTYPE</span></tt> and <tt class="docutils literal"><span class="pre">WINFUNCTYPE</span></tt> factory functions cache and
-reuse the types they create in internal caches, so is is cheap to call
-them over and over with the same or different arguments.</p>
-<p>An instance of this function prototype, bound to a foreign library
-function, can be created by calling the prototype with the name of the
-function as string, and a loaded library:</p>
-<pre class="literal-block">
-proto = CFUNCTYPE(c_int, c_char_p)
-atoi = proto("atoi", libc)
-</pre>
-</div>
-<div class="section">
-<h2><a class="toc-backref" href="#id7" id="parameter-flags" name="parameter-flags">Parameter flags</a></h2>
-<p>It is possible to specify a third argument <tt class="docutils literal"><span class="pre">paramflags</span></tt> when calling
-the prototype. This is used to specify additional information for
-each argument: direction of data transfer, the name, and a default
-value.</p>
-<p>A tuple with the same length as <tt class="docutils literal"><span class="pre">argtypes</span></tt> (the second argument in
-the prototype call) must be used. Each item in this tuple must be a
-tuple, having either one, two, or three items.</p>
-<p>The first item is the direction flag, an integer specifying if this is
-an input (use <tt class="docutils literal"><span class="pre">1</span></tt>) or an output (use <tt class="docutils literal"><span class="pre">2</span></tt>) parameter. The optional
-second item is a string containing the parameter name, the optional
-third item is a default value for the parameter.</p>
-<p>If parameter names are specified, the function object created can be
-called with named arguments in the usual way. Arguments with default
-values do not need to be specified when the function is called.</p>
-<p><tt class="docutils literal"><span class="pre">out</span></tt> parameter types must be pointer types. When the function
-object is called, ctypes will automatically create empty instances of
-them, pass them to the library function, retrieve the value from them,
-and return the value, if there is exactly one <tt class="docutils literal"><span class="pre">out</span></tt> parameter, or a
-tuple of values, if there is more than one <tt class="docutils literal"><span class="pre">out</span></tt> parameter. The
-original foreign function return value is lost in this case (but see
-below for how it can be retrieved).</p>
-<p>If <tt class="docutils literal"><span class="pre">paramflags</span></tt> have been used in the prototype call, and an
-<tt class="docutils literal"><span class="pre">errcheck</span></tt> attribute is also present, the <tt class="docutils literal"><span class="pre">errcheck</span></tt> callable will
-be called with a fourth parameter <tt class="docutils literal"><span class="pre">outargs</span></tt>:</p>
-<pre class="literal-block">
-errcheck(retval, function, arguments, outargs)
-</pre>
-<p><tt class="docutils literal"><span class="pre">outargs</span></tt> is a tuple containing all the <tt class="docutils literal"><span class="pre">out</span></tt> parameters that
-ctypes has created. Without the <tt class="docutils literal"><span class="pre">errcheck</span></tt> function ctypes would
-retrieve the values contained in these pointer objects, and return
-them. The <tt class="docutils literal"><span class="pre">errcheck</span></tt> function can let ctypes continue this
-processing by returning the <tt class="docutils literal"><span class="pre">outargs</span></tt> tuple. It could also return
-something else, or raise an error if it detects that the library
-function has failed.</p>
-</div>
-<div class="section">
-<h2><a class="toc-backref" href="#id8" id="com-methods-windows-only" name="com-methods-windows-only">COM methods (Windows only)</a></h2>
-<p>XXX Should this be left undocumented? Mentioned for completeness.</p>
-<p>The prototypes created by <tt class="docutils literal"><span class="pre">WINFUNCTYPE</span></tt> can be called with a
-positive small integer <tt class="docutils literal"><span class="pre">index</span></tt>, a string <tt class="docutils literal"><span class="pre">name</span></tt>, an optional
-<tt class="docutils literal"><span class="pre">paramflags</span></tt> tuple, and a optional <tt class="docutils literal"><span class="pre">iid</span></tt> parameter.</p>
-<p>This creates a function object wrapping a COM method. <tt class="docutils literal"><span class="pre">index</span></tt> is
-the index into the COM object's virtual function table, <tt class="docutils literal"><span class="pre">name</span></tt> is
-the name of the COM method (only useful for debugging), <tt class="docutils literal"><span class="pre">paramflags</span></tt>
-has the same meaning as for normal function objects, and <tt class="docutils literal"><span class="pre">iid</span></tt> is a
-string or buffer containing the interface id of the COM interface
-this method belongs to. <tt class="docutils literal"><span class="pre">iid</span></tt> is used to get extended COM error
-information in case the method returns a FAILED ''HRESULT`` value.</p>
-<p>Note that COM methods expect an additional first argument that is NOT
-listed in the prototypes <tt class="docutils literal"><span class="pre">argtypes</span></tt> when they are called: this must
-be the integer address of a COM interface pointer.</p>
-</div>
-</div>
-<div class="section">
-<h1><a class="toc-backref" href="#id9" id="callback-functions" name="callback-functions">Callback functions</a></h1>
-<p>ctypes is able to create C callable functions from Python callables.
-This is useful because sometimes library functions need a callback
-function parameter; the <tt class="docutils literal"><span class="pre">qsort</span></tt> C function is such an example.</p>
-<p>Callback functions are created by first creating a function prototype
-with a call to <tt class="docutils literal"><span class="pre">CFUNCTYPE</span></tt> or <tt class="docutils literal"><span class="pre">WINFUNCTYPE</span></tt>, specifying the return
-type and the argument types that the callback function will receive.</p>
-<p>Calling the prototype with a single Python callable will create and
-return a C-callable function pointer or callback function. Note that
-this allows using prototypes as decorators creating callback
-functions (Windows example):</p>
-<pre class="literal-block">
-@WINFUNCTYPE(BOOL, HWND, LPARAM)
-def enumwindowsproc(hwnd, lParam):
- ....
- return True
-</pre>
-<p>When a Python exception is raised in the Python callable, the return
-value of the C callable function is undefined.</p>
-<p>Important note: You must keep a reference to the callback AS LONG as
-foreign code will call it! Segfaults will result if the callback is
-cleaned up by Python's garbage collector and external code then
-tries to call it.</p>
-<p>Callback objects can also be called from Python - this may be useful
-for debugging.</p>
-</div>
-<div class="section">
-<h1><a class="toc-backref" href="#id10" id="simple-types" name="simple-types">Simple types</a></h1>
-<p>Simple types have some special behaviour: When they are accessed as
-structure or union fields, items of array instances, or as foreign
-function return values, they are transparently converted from and to
-the native Python types int, long, string, and unicode.</p>
-<p>This is <em>not</em> the case for subclasses of simple data types, so while a
-<tt class="docutils literal"><span class="pre">c_void_p</span></tt> type is transparently converted from and to Python
-integer or long, a subclass of c_void_p is <em>not</em> converted. This
-allows you to define new behaviour almost completely.</p>
-<div class="section">
-<h2><a class="toc-backref" href="#id11" id="class-attributes-of-simple-types" name="class-attributes-of-simple-types">Class attributes of simple types</a></h2>
-<p><tt class="docutils literal"><span class="pre">__ctype_be__</span></tt>, <tt class="docutils literal"><span class="pre">__ctype_le__</span></tt></p>
-<blockquote>
-If the type supports different byte order (pointer types do NOT
-support this), <tt class="docutils literal"><span class="pre">__ctype_be__</span></tt> and <tt class="docutils literal"><span class="pre">__ctype_le__</span></tt> are types
-with bug endian and little endian byte order. For example,
-<tt class="docutils literal"><span class="pre">c_int.__ctype_be__</span></tt> is an integer type with the memory block in
-big endian byte order.</blockquote>
-<p><tt class="docutils literal"><span class="pre">_type_</span></tt></p>
-<blockquote>
-Implementation artifact: the typecode for this type, a single
-character string code compatible to what the <tt class="docutils literal"><span class="pre">struct</span></tt> module uses.
-Additional characters are used for types that the <tt class="docutils literal"><span class="pre">struct</span></tt> module
-does not support.</blockquote>
-</div>
-<div class="section">
-<h2><a class="toc-backref" href="#id12" id="class-methods-of-simple-types" name="class-methods-of-simple-types">Class methods of simple types</a></h2>
-<p>(To be exact, these are not class methods, instead these are methods
-of the metaclass. The most prominent difference to classmethods is
-that you can call these methods on the class, but not on the instance
-of the simple type.)</p>
-<p><tt class="docutils literal"><span class="pre">__ctypes_from_outparam__</span></tt></p>
-<blockquote>
-TBD</blockquote>
-<p><tt class="docutils literal"><span class="pre">from_address</span></tt></p>
-<blockquote>
-TBD</blockquote>
-<p><tt class="docutils literal"><span class="pre">from_param</span></tt></p>
-<blockquote>
-<p>This class method is used to adapt function parameters. If a type
-is specified in a function's argtypes sequence, in a function call
-the <tt class="docutils literal"><span class="pre">from_param(arg)</span></tt> method will be called with the actual
-argument, and the result will be passed to the foreign function
-call as a parameter.</p>
-<p><tt class="docutils literal"><span class="pre">from_param</span></tt> usually returns an internal object that you cannot
-use in Python code - it only makes sense to pass this object to
-foreign functions.</p>
-<p>On one hand, <tt class="docutils literal"><span class="pre">from_param</span></tt> is a performance optimization - it
-allows you to pass Python integers to function calls expecting a
-<tt class="docutils literal"><span class="pre">c_int</span></tt> argument type, without having to create a full-featured
-<tt class="docutils literal"><span class="pre">c_int</span></tt> instance.</p>
-<p>On the other hand, <tt class="docutils literal"><span class="pre">from_param</span></tt> can adapt other objects to
-parameters. XXX explain the automatic <tt class="docutils literal"><span class="pre">byref</span></tt> call for byref
-arguments.</p>
-</blockquote>
-<p><tt class="docutils literal"><span class="pre">in_dll</span></tt></p>
-<blockquote>
-TBD</blockquote>
-</div>
-<div class="section">
-<h2><a class="toc-backref" href="#id13" id="instance-attributes-of-simple-types" name="instance-attributes-of-simple-types">Instance attributes of simple types</a></h2>
-<p><tt class="docutils literal"><span class="pre">value</span></tt></p>
-<blockquote>
-Allows to get or set the current value of the object. For simple
-types, this is always a native Python object like integer, long,
-string, unicode, or None.</blockquote>
-<p><tt class="docutils literal"><span class="pre">_objects</span></tt> (never modify this)</p>
-<blockquote>
-Implementation artifact: a Python object keeping references to
-other objects which must be kept alive. Never modify anything on
-the returned object. XXX Should probably not be exposed.</blockquote>
-<p><tt class="docutils literal"><span class="pre">_b_base_</span></tt> (readonly)</p>
-<blockquote>
-Implementation artifact: the base object owning the memory block
-(if any).</blockquote>
-<p><tt class="docutils literal"><span class="pre">_b_needsfree_</span></tt> (readonly)</p>
-<blockquote>
-Implementation artifact: does this object have to free its memory
-block on destruction.</blockquote>
-<p><tt class="docutils literal"><span class="pre">_as_parameter_</span></tt> (readonly)</p>
-<blockquote>
-Implementation artifact (?): how to pass this object as a function
-parameter.</blockquote>
-</div>
-<div class="section">
-<h2><a class="toc-backref" href="#id14" id="numeric-types" name="numeric-types">Numeric types</a></h2>
-<p>Integer types are <tt class="docutils literal"><span class="pre">c_byte</span></tt>, <tt class="docutils literal"><span class="pre">c_short</span></tt>, <tt class="docutils literal"><span class="pre">c_int</span></tt>, <tt class="docutils literal"><span class="pre">c_long</span></tt>,
-<tt class="docutils literal"><span class="pre">c_longlong</span></tt> and their unsigned variants <tt class="docutils literal"><span class="pre">c_ubyte</span></tt>, <tt class="docutils literal"><span class="pre">c_ushort</span></tt>,
-<tt class="docutils literal"><span class="pre">c_uint</span></tt>, <tt class="docutils literal"><span class="pre">c_ulong</span></tt> and <tt class="docutils literal"><span class="pre">c_ulonglong</span></tt>, floating point types are
-<tt class="docutils literal"><span class="pre">c_float</span></tt> and <tt class="docutils literal"><span class="pre">c_double</span></tt>.</p>
-<p>The constructor and the <tt class="docutils literal"><span class="pre">from_param</span></tt> class method accept a Python
-integer for integer types, a Python float for floating point types.</p>
-<p>On 32-bit platforms where sizeof(int) == sizeof(long), <tt class="docutils literal"><span class="pre">c_int</span></tt> is an
-alias for <tt class="docutils literal"><span class="pre">c_long</span></tt>, on 64-bit platforms where sizeof(long) ==
-sizeof(long long), <tt class="docutils literal"><span class="pre">c_long</span></tt> is an alias for <tt class="docutils literal"><span class="pre">c_longlong</span></tt>.</p>
-</div>
-<div class="section">
-<h2><a class="toc-backref" href="#id15" id="character-types" name="character-types">Character types</a></h2>
-<p>Character types are <tt class="docutils literal"><span class="pre">c_char</span></tt> and <tt class="docutils literal"><span class="pre">c_wchar</span></tt>, representing the C
-<tt class="docutils literal"><span class="pre">char</span></tt> and <tt class="docutils literal"><span class="pre">wchar_t</span></tt> types.</p>
-<p>The constructor and the <tt class="docutils literal"><span class="pre">from_param</span></tt> class method accept a single
-character Python string or unicode string. Conversion between string
-and unicode, if needed, is done according to the ctypes
-encoding/decoding rules.</p>
-</div>
-<div class="section">
-<h2><a class="toc-backref" href="#id16" id="pointer-types" name="pointer-types">Pointer types</a></h2>
-<p>The only simple pointer type is <tt class="docutils literal"><span class="pre">c_void_p</span></tt>, which represents the C
-<tt class="docutils literal"><span class="pre">void</span> <span class="pre">*</span></tt> data type. <tt class="docutils literal"><span class="pre">c_void_p</span></tt> can also be written as
-<tt class="docutils literal"><span class="pre">POINTER(None)</span></tt>.</p>
-<p>The constructor accepts one optional argument, which must be an
-integer or long (interpreted as an address), or <tt class="docutils literal"><span class="pre">None</span></tt>.</p>
-<p>The <tt class="docutils literal"><span class="pre">from_param</span></tt> class method accepts everything that could be used
-as a pointer. XXX Should accept objects using the buffer interface as
-well.</p>
-<p>The <tt class="docutils literal"><span class="pre">value</span></tt> attribute accepts and returns None or integer.</p>
-<p>XXX Shouldn't the constructor accept the same types as from_param?</p>
-</div>
-<div class="section">
-<h2><a class="toc-backref" href="#id17" id="string-types" name="string-types">String types</a></h2>
-<p>ctypes has the <tt class="docutils literal"><span class="pre">c_char_p</span></tt> and <tt class="docutils literal"><span class="pre">c_wchar_p</span></tt> types which represent
-const pointers to zero terminated strings in C: <tt class="docutils literal"><span class="pre">const</span> <span class="pre">char</span> <span class="pre">*</span></tt> and
-<tt class="docutils literal"><span class="pre">const</span> <span class="pre">wchar_t</span> <span class="pre">*</span></tt>. Since strings and Unicode instances are
-immutable, these types should be considered readonly: do not pass them
-to functions that write into the buffer.</p>
-<p>The constructor accepts one optional argument, which must be a Python
-or unicode string, an integer, or <tt class="docutils literal"><span class="pre">None</span></tt>.</p>
-<p>The <tt class="docutils literal"><span class="pre">from_param</span></tt> class method accepts a string or a Unicode string,
-as well as <tt class="docutils literal"><span class="pre">None</span></tt>. Conversion between string and Unicode, if
-needed, is done according to the ctypes encoding/decoding rules.</p>
-<p>XXX Why does the constructor accept an integer, and from_param doesn't?</p>
-</div>
-</div>
-<div class="section">
-<h1><a class="toc-backref" href="#id18" id="structure-and-union-types" name="structure-and-union-types">Structure and union types</a></h1>
-<p>ctypes provides the abstract base classes <tt class="docutils literal"><span class="pre">Structure</span></tt> and <tt class="docutils literal"><span class="pre">Union</span></tt>
-to define structure and union types. Subclasses must at least define
-a <tt class="docutils literal"><span class="pre">_fields_</span></tt> attribute.</p>
-<div class="section">
-<h2><a class="toc-backref" href="#id19" id="defining-field-names-and-types" name="defining-field-names-and-types">Defining field names and types</a></h2>
-<p><tt class="docutils literal"><span class="pre">_fields_</span></tt> must be a sequence of tuples. The first item of each
-tuple is a string specifying the name of the structure/union field.
-The second item must by a ctypes type.</p>
-<p>A descriptor will be created for each field, allowing you to access the
-field's contents from instances. Accessed from the class, the fields
-expose readonly <tt class="docutils literal"><span class="pre">.offset</span></tt> and <tt class="docutils literal"><span class="pre">.size</span></tt> attributes. <tt class="docutils literal"><span class="pre">offset</span></tt> is
-the byte-offset of the field from the beginning of the
-structure/union, <tt class="docutils literal"><span class="pre">size</span></tt> is the number of bytes the field contains.</p>
-<p>A simple example is a POINT structure containing integer fields named
-<tt class="docutils literal"><span class="pre">x</span></tt> and <tt class="docutils literal"><span class="pre">y</span></tt>:</p>
-<pre class="literal-block">
-class Point(Structure):
- _fields_ = [("x", c_int),
- ("y", c_int)]
-</pre>
-</div>
-<div class="section">
-<h2><a class="toc-backref" href="#id20" id="packing-fields" name="packing-fields">Packing fields</a></h2>
-<p>Normally fields are aligned in the same way as the host's C compiler
-would do it. This native alignment can be overridden by setting a
-<tt class="docutils literal"><span class="pre">_pack_</span></tt> attribute in the type. It must be a small positive integer
-which is the maximum field alignment.</p>
-</div>
-<div class="section">
-<h2><a class="toc-backref" href="#id21" id="bit-fields" name="bit-fields">Bit fields</a></h2>
-<p>Integer fields support bit sizes. The bit-size must be specified as
-the third item of the <tt class="docutils literal"><span class="pre">_fields_</span></tt> tuple. Bit fields are constructed
-in the same way the host's C compiler does it. For bit fields, the
-field descriptor's <tt class="docutils literal"><span class="pre">.size</span></tt> attribute contains the number of bits in
-the high word, and the bit offset from the beginning of the structure in
-the low word. XXX is that correct?</p>
-</div>
-<div class="section">
-<h2><a class="toc-backref" href="#id22" id="recursive-data-types" name="recursive-data-types">Recursive data types</a></h2>
-<p>To define recursive types, it is possible to assign the <tt class="docutils literal"><span class="pre">_fields_</span></tt>
-value <em>after</em> the class statement. Here is an example of a linked
-list data structure, which contains a pointer to itself:</p>
-<pre class="literal-block">
-class Node(Structure):
- pass
-Node._fields_ = [("next", POINTER(Node)),
- ("value", ...)]
-</pre>
-<p><tt class="docutils literal"><span class="pre">_fields_</span></tt> must be set, and cannot be changed, after the type is
-used for the first time.</p>
-</div>
-<div class="section">
-<h2><a class="toc-backref" href="#id23" id="byte-order" name="byte-order">Byte order</a></h2>
-<p>It is possible to create Structure and Union types using non-native
-byte order by using the <tt class="docutils literal"><span class="pre">BigEndianStructure</span></tt>,
-<tt class="docutils literal"><span class="pre">LittleEndianStructure</span></tt>, <tt class="docutils literal"><span class="pre">BigEndianUnion</span></tt>, and
-<tt class="docutils literal"><span class="pre">LittleEndianUnion</span></tt> base classes. Structures and Unions with
-non-native byte order do <em>not</em> support pointer fields.</p>
-</div>
-<div class="section">
-<h2><a class="toc-backref" href="#id24" id="builtin-functions" name="builtin-functions">Builtin functions</a></h2>
-<p><tt class="docutils literal"><span class="pre">addressof(object)</span></tt></p>
-<blockquote>
-Returns the address of a ctypes instance as an integer.</blockquote>
-<p><tt class="docutils literal"><span class="pre">alignment(type_or_object)</span></tt></p>
-<blockquote>
-Returns the alignment requirements in bytes of a ctypes type or
-instance.</blockquote>
-<p><tt class="docutils literal"><span class="pre">byref(object)</span></tt></p>
-<blockquote>
-Returns a light-weight pointer to a ctypes instance. The returned
-object can only be used as function call parameter. Behaves the
-same as calling <tt class="docutils literal"><span class="pre">pointer(object)</span></tt>, but is a lot faster. Same as
-<tt class="docutils literal"><span class="pre">&object</span></tt> in C.</blockquote>
-<p><tt class="docutils literal"><span class="pre">cast(object,</span> <span class="pre">typ)</span></tt></p>
-<blockquote>
-This function is similar to the cast operator in C. Returns a new
-instance of <tt class="docutils literal"><span class="pre">type</span></tt> which shares the memory block of <tt class="docutils literal"><span class="pre">object</span></tt>.
-<tt class="docutils literal"><span class="pre">typ</span></tt> must be a pointer type.</blockquote>
-<p><tt class="docutils literal"><span class="pre">CFUNCTYPE(restype,</span> <span class="pre">*argtypes)</span></tt></p>
-<blockquote>
-Create a function prototype using the C calling convention.</blockquote>
-<p><tt class="docutils literal"><span class="pre">create_string_buffer(init,</span> <span class="pre">size=None)</span></tt></p>
-<blockquote>
-<p>Convenience function to create a mutable character buffer.</p>
-<p><tt class="docutils literal"><span class="pre">init</span></tt> must be a string. If <tt class="docutils literal"><span class="pre">size</span></tt> is supplied it must be a
-positive integer that specifies the size of the buffer, otherwise
-the length of the <tt class="docutils literal"><span class="pre">init</span></tt> string is used.
-This function returns a ctypes array of characters <tt class="docutils literal"><span class="pre">c_char</span></tt>.</p>
-</blockquote>
-<p><tt class="docutils literal"><span class="pre">create_unicode_buffer(init,</span> <span class="pre">size=None)</span></tt></p>
-<blockquote>
-<p>Convenience function to create a mutable unicode buffer.</p>
-<p><tt class="docutils literal"><span class="pre">init</span></tt> must be a unicode string. If <tt class="docutils literal"><span class="pre">size</span></tt> is supplied it
-must be a positive integer that specifies the number of characters
-in the buffer, otherwise the length of the <tt class="docutils literal"><span class="pre">init</span></tt> string is
-used. This function returns a ctypes array of characters <tt class="docutils literal"><span class="pre">c_wchar</span></tt>.</p>
-</blockquote>
-<p><tt class="docutils literal"><span class="pre">DllCanUnloadNow()</span></tt>, <tt class="docutils literal"><span class="pre">DllGetClassObject(rclsid,</span> <span class="pre">riid,</span> <span class="pre">ppv)</span></tt> (Windows only)</p>
-<blockquote>
-Functions used to implement COM servers.</blockquote>
-<p><tt class="docutils literal"><span class="pre">FormatError([code])</span></tt> (Windows only)</p>
-<blockquote>
-Returns a textual description of the error code, or the last error
-code set by Windows.</blockquote>
-<p><tt class="docutils literal"><span class="pre">GetLastError()</span></tt> (Windows only)</p>
-<blockquote>
-Returns the last error code set by Windows.</blockquote>
-<p><tt class="docutils literal"><span class="pre">memmove(dst,</span> <span class="pre">src,</span> <span class="pre">count)</span></tt></p>
-<blockquote>
-Same as the standard C <tt class="docutils literal"><span class="pre">memmove</span></tt> library function: copies
-<tt class="docutils literal"><span class="pre">count</span></tt> bytes from <tt class="docutils literal"><span class="pre">src</span></tt> to <tt class="docutils literal"><span class="pre">dst</span></tt>. <tt class="docutils literal"><span class="pre">dst</span></tt> and <tt class="docutils literal"><span class="pre">src</span></tt> must
-be integers or anything else that can be converted into a pointer.</blockquote>
-<p><tt class="docutils literal"><span class="pre">memset(dst,</span> <span class="pre">c,</span> <span class="pre">count)</span></tt></p>
-<blockquote>
-Same as the standard C <tt class="docutils literal"><span class="pre">memset</span></tt> function. Fills the memory block
-at address <tt class="docutils literal"><span class="pre">dst</span></tt> with <tt class="docutils literal"><span class="pre">count</span></tt> bytes of value <tt class="docutils literal"><span class="pre">c</span></tt>. <tt class="docutils literal"><span class="pre">dst</span></tt> must be
-an integer specifying an address, or a ctypes instance.</blockquote>
-<p><tt class="docutils literal"><span class="pre">pointer(object)</span></tt></p>
-<blockquote>
-<p>This function creates a new pointer instance, pointing to the
-supplied argument which must be an instance of a ctypes type. The
-return pointer is of type <tt class="docutils literal"><span class="pre">POINTER(type(object))</span></tt>. If you have
-a ctypes instance, and you want to pass the address of it to a
-function call, you should use <tt class="docutils literal"><span class="pre">byref(object)</span></tt> instead which is
-much faster.</p>
-<p>NULL pointer instances are boolean``False``, so to check for a
-NULL pointer do this:</p>
-<pre class="literal-block">
-# assuming ptr is in ctypes pointer instance
-if ptr:
- print "Non-NULL pointer instance"
-else:
- print "NULL pointer instance"
-</pre>
-</blockquote>
-<p><tt class="docutils literal"><span class="pre">POINTER(cls)</span></tt></p>
-<blockquote>
-<p>This factory function creates and returns a new ctypes type.
-Pointer types are cached, so calling this function is cheap.</p>
-<p>To create a <tt class="docutils literal"><span class="pre">NULL</span></tt> pointer instance, call the created type
-without an argument:</p>
-<pre class="literal-block">
-null_ptr = POINTER(c_int)()
-</pre>
-</blockquote>
-<p><tt class="docutils literal"><span class="pre">set_conversion_mode(encoding,</span> <span class="pre">errors)</span></tt></p>
-<blockquote>
-This function sets the encoding/decoding rules which are used when
-ctypes has to convert between unicode and byte strings. It
-returns the previous encoding, as well as a tuple of any errors.
-If not set, default conversions are used:
-On Windows, <tt class="docutils literal"><span class="pre">msbc,</span> <span class="pre">ignore</span></tt> , on other systems, <tt class="docutils literal"><span class="pre">ascii,</span> <span class="pre">strict</span></tt>.</blockquote>
-<p><tt class="docutils literal"><span class="pre">sizeof(type_or_object)</span></tt></p>
-<blockquote>
-Returns the size in bytes of a ctypes type or instance memory
-buffer. Does the same as the C sizeof() function.</blockquote>
-<p><tt class="docutils literal"><span class="pre">string_at(addr[,</span> <span class="pre">size])</span></tt></p>
-<blockquote>
-This function does the same as the Python <tt class="docutils literal"><span class="pre">PyString_FromString</span></tt> /
-<tt class="docutils literal"><span class="pre">PyString_FromStringAndSize</span></tt> C api functions.</blockquote>
-<p><tt class="docutils literal"><span class="pre">WinError(code=None,</span> <span class="pre">descr=None)</span></tt></p>
-<blockquote>
-<p>XXX This is probably the worst named thing in ctypes!</p>
-<p>This function creates a <tt class="docutils literal"><span class="pre">WindowsError</span></tt> instance. If <tt class="docutils literal"><span class="pre">code</span></tt> is
-not specified, GetLastError() is called to determine the error
-code. If <tt class="docutils literal"><span class="pre">descr</span></tt> is not specified, <tt class="docutils literal"><span class="pre">FormatError</span></tt> is called to
-get a textual description of the error.</p>
-</blockquote>
-<p><tt class="docutils literal"><span class="pre">WINFUNCTYPE(restype,</span> <span class="pre">*argtypes)</span></tt> (Windows only)</p>
-<blockquote>
-Create a function prototype using the __stdcall calling convention
-(on Windows), or using the C calling convention (on Windows CE).</blockquote>
-<p><tt class="docutils literal"><span class="pre">wstring_at(addr[,</span> <span class="pre">size])</span></tt></p>
-<blockquote>
-This function does the same as the Python <tt class="docutils literal"><span class="pre">PyUnicode_FromWideString</span></tt>
-C api function. If <tt class="docutils literal"><span class="pre">size</span></tt> is not specified, <tt class="docutils literal"><span class="pre">wcslen</span></tt> is used
-to determine the string length.</blockquote>
-</div>
-<div class="section">
-<h2><a class="toc-backref" href="#id25" id="deprecated-functions" name="deprecated-functions">Deprecated functions</a></h2>
-<p>These deprecated functions are still supported for backwards
-comatibility, they should not be used for new code:</p>
-<p><tt class="docutils literal"><span class="pre">c_buffer(init,</span> <span class="pre">size=None)</span></tt></p>
-<blockquote>
-Deprecated. Use <tt class="docutils literal"><span class="pre">create_string_buffer()</span></tt> instead.</blockquote>
-<p><tt class="docutils literal"><span class="pre">ARRAY(cls,</span> <span class="pre">len)</span></tt></p>
-<blockquote>
-Deprecated. Use <tt class="docutils literal"><span class="pre">cls</span> <span class="pre">*</span> <span class="pre">len</span></tt> instead.</blockquote>
-<p><tt class="docutils literal"><span class="pre">SetPointerType(pointer_class,</span> <span class="pre">cls)</span></tt></p>
-<blockquote>
-Deprecated.</blockquote>
-</div>
-</div>
-</div>
-</body>
-</html>
Deleted: /external/ctypes/docs/manual/manual.txt
==============================================================================
--- /external/ctypes/docs/manual/manual.txt Sat Jun 10 22:08:12 2006
+++ (empty file)
@@ -1,9 +0,0 @@
-=============
-ctypes manual
-=============
-
-(work in progress, $Revision: 1.3 $)
-
-.. contents::
-
-.. include:: docs.txt
Modified: external/ctypes/docs/manual/mkpydoc.py
==============================================================================
--- external/ctypes/docs/manual/mkpydoc.py (original)
+++ external/ctypes/docs/manual/mkpydoc.py Sat Jun 10 22:08:12 2006
@@ -1,12 +1,11 @@
-#!/usr/bin/env python
-# Convert the ctypes docs to LaTeX for use in Python docs
+#!/usr/bin/python
+
+# Convert the reStructuredText docs to LaTeX for use in Python docs
# This script is a hacked version taken from the Optik SVN repository.
import sys, os
import re
-from popen2 import popen2
-from glob import glob
import rfc822
from distutils.dep_util import newer_group, newer
from docutils.core import Publisher
@@ -42,15 +41,7 @@
class PyLaTeXTranslator(LaTeXTranslator):
remap_title = {
}
-
- # XXX need to factor this out
- module_name = "ctypes"
- module_summary = "A foreign function library for Python."
- module_type = "standard"
- module_author = "Thomas Heller"
- module_author_email = "theller at python.net"
- module_synopsis = ("A foreign function library for Python.")
- version_added = "2.5"
+ roman = (None,None,"ii","iii","iv","v")
refuri_override = {
"reference" : "reference-guide",
@@ -59,10 +50,14 @@
def __init__(self, document):
LaTeXTranslator.__init__(self, document)
+ self.label_prefix = ""
+ self.docinfo = {}
self.head_prefix = []
self.head = []
self.body_prefix = []
self.in_title = False
+ self.in_anydesc = False # _title is different if it is a funcdesc
+ self.admonition_stack = []
# Disable a bunch of methods from the base class.
empty_method = lambda self: None
@@ -72,19 +67,10 @@
'field_name'):
setattr(self, 'visit_' + nodetype, empty_method)
setattr(self, 'depart_' + nodetype, empty_method)
-
- self.head_prefix = [
- "\\section{\\module{%(module_name)s} --- %(module_summary)s}\n"
- "\\declaremodule{%(module_type)s}{%(module_name)s}\n"
- "\\moduleauthor{%(module_author)s}{%(module_author_email)s}\n"
- "\\modulesynopsis{%(module_synopsis)s}\n"
- "\\versionadded{%(version_added)s}\n"
- % vars(self.__class__)
- ]
- # TODO definitions get from latexwriter
- # TODO definitions must be guarded if multiple modules are included
+ self.head_prefix = []
+ # definitions must be guarded if multiple modules are included
self.definitions = [
- "\\newlength{\\locallinewidth}\n"
+ "\\ifx\\locallinewidth\\undefined\\newlength{\\locallinewidth}\\fi\n"
"\\setlength{\\locallinewidth}{\\linewidth}\n"
]
def astext(self):
@@ -95,14 +81,16 @@
self.body +
self.body_suffix)
+ def set_label_prefix(self, text):
+ self.label_prefix = text.replace(" ","-")
+
def generate_section_label(self, title):
title = title.lower()
title = re.sub(r'\([^\)]*\)', '', title)
title = re.sub(r'[^\w\s\-]', '', title)
title = re.sub(r'\b(the|an?|and|your|are)\b', '', title)
title = re.sub(r'(example \d+).*', r'\1', title)
-## title = title.replace("optik", "optparse")
- return "ctypes-" + "-".join(title.split())
+ return self.label_prefix + "-" + "-".join(title.split())
def visit_document(self, node):
pass
@@ -111,32 +99,66 @@
pass
def visit_docinfo(self, node):
- #print "visit_docinfo: %r" % node
- self.docinfo = []
+ pass
def depart_docinfo(self, node):
- #print "depart_docinfo: %r" % node
- self.body = self.docinfo + self.body
- self.docinfo = None
+ # module and summary are mandatory
+ self.body.append(
+ "\\section{\\module{%(module)s} --- %(summary)s}\n"
+ % self.docinfo )
+ if self.docinfo.has_key("moduletype"):
+ self.body.append(
+ "\\declaremodule{%(moduletype)s}{%(module)s}\n"
+ % self.docinfo )
+ if self.docinfo.has_key("moduleauthor"):
+ self.body.append(
+ "\\moduleauthor{%(moduleauthor)s}{%(moduleauthoremail)s}\n"
+ % self.docinfo )
+ if self.docinfo.has_key("synopsis"):
+ self.body.append(
+ "\\modulesynopsis{%(synopsis)s}\n"
+ % self.docinfo )
+ if self.docinfo.has_key("release"):
+ self.body.append( "\\release{%(release)s}\n" % self.docinfo )
+ if self.docinfo.has_key("shortversion"):
+ self.body.append( "\\setshortversion{%(shortversion)s}\n"
+ % self.docinfo )
+ if self.docinfo.has_key("sectionauthor"):
+ self.body.append(
+ "\\sectionauthor{%(sectionauthor)s}{%(sectionauthoremail)s}\n"
+ % self.docinfo )
+ if self.docinfo.has_key("versionadded"):
+ self.body.append(
+ "\\versionadded{%(versionadded)s}\n"
+ % self.docinfo )
def visit_docinfo_item(self, node, name):
- #print "visit_docinfo_item: node=%r, name=%r" % (node, name)
if name == "author":
- (name, email) = rfc822.parseaddr(node.astext())
- self.docinfo.append("\\sectionauthor{%s}{%s}\n" % (name, email))
+ (ename, email) = rfc822.parseaddr(node.astext())
+ self.docinfo["moduleauthor"] = ename
+ self.docinfo["moduleauthoremail"] = email
raise nodes.SkipNode
def depart_docinfo_item(self, node):
pass
- #def visit_field(self, node):
- # (name, value) = (node[0].astext(), node[1].astext())
- # print "visit_field: node=%r (name=%r, value=%r)" % (node, name, value)
- # if self.docinfo is not None:
- # if name == "VersionAdded":
- # self.docinfo.append("\\versionadded{%s}\n" % value)
- # raise nodes.SkipNode
-
+ def visit_field(self, node):
+ if isinstance(node.parent, nodes.docinfo):
+ name = node[0].astext().lower().replace(" ","")
+ if name == "moduleauthor":
+ (ename, email) = rfc822.parseaddr(node[1].astext())
+ self.docinfo["moduleauthor"] = ename
+ self.docinfo["moduleauthoremail"] = email
+ elif name in ("author", "sectionauthor") :
+ (ename, email) = rfc822.parseaddr(node[1].astext())
+ self.docinfo["sectionauthor"] = ename
+ self.docinfo["sectionauthoremail"] = email
+ else:
+ if name == "module":
+ self.set_label_prefix(node[1].astext())
+ self.docinfo[name] = node[1].astext()
+ raise nodes.SkipNode
+
_quoted_string_re = re.compile(r'\"[^\"]*\"')
_short_opt_string_re = re.compile(r'-[a-zA-Z]')
_long_opt_string_re = re.compile(r'--[a-zA-Z-]+')
@@ -147,7 +169,6 @@
def visit_literal(self, node):
assert isinstance(node[0], nodes.Text)
text = node[0].data
-#### text = re.sub(r'optik(\.[a-z]+)?\.', 'optparse.', text)
if self.in_title:
cmd = None
elif self._quoted_string_re.match(text):
@@ -171,6 +192,93 @@
if cmd is not None:
self.body.append('\\%s{' % cmd)
+ # use topics for special environments
+ def visit_topic(self, node):
+ classes = node.get('classes', ['topic', ])
+ if classes[0] in ('datadesc', 'datadescni', 'excdesc', 'classdesc*',
+ 'csimplemacrodesc', 'ctypedesc', 'memberdesc',
+ 'memberdescni', 'cvardesc', 'excclassdesc',
+ 'funcdesc', 'funcdescni', 'methoddesc',
+ 'methoddescni', 'cmemberdesc', 'classdesc',
+ 'cfuncdesc'):
+ self.body.append('\n\\begin{%s}' % classes[0])
+ self.context.append('\\end{%s}\n' % classes[0])
+ self.in_anydesc = classes[0]
+ else:
+ self.context.append('')
+
+ def depart_topic(self, node):
+ self.in_anydesc = False
+ self.body.append(self.context.pop())
+
+ # use definition lists for special environments
+ #
+ # definition_list
+ # defintion_list_item
+ # term
+ # classifier
+ # definition
+ # paragraph ?
+ def visit_definition_list(self, node):
+ pass
+
+ def depart_definition_list(self, node):
+ pass
+
+ def visit_definition_list_item(self, node):
+ self._dl_term = []
+
+ def depart_definition_list_item(self, node):
+ try:
+ self.body.append(self.context.pop())
+ except:
+ self.body.append("% WARN definition list without classifier\n")
+
+
+ def visit_term(self, node):
+ self._dl_term.append(node.astext())
+ raise nodes.SkipNode
+
+ def depart_term(self, node):
+ pass
+
+ def visit_classifier(self, node):
+ # TODO here it should be decided if it is latex or python
+ classifier = node.astext()
+
+ if classifier in ('datadesc', 'datadescni', 'excdesc', 'classdesc*',
+ 'csimplemacrodesc', 'ctypedesc', 'memberdesc',
+ 'memberdescni', 'cvardesc', 'excclassdesc',
+ 'funcdesc', 'funcdescni', 'methoddesc',
+ 'methoddescni', 'cmemberdesc', 'classdesc',
+ 'cfuncdesc'):
+ pass
+ else:
+ classifier = 'datadescni'
+ self.body.append('\n\\begin{%s}' % classifier)
+ self.in_anydesc = classifier
+ self.body.append(self.anydesc_title(self._dl_term.pop()))
+ self.context.append('\\end{%s}\n' % classifier)
+ self.in_anydesc = None
+ raise nodes.SkipNode
+
+ def depart_classifier(self, node):
+ pass
+
+ def visit_definition(self, node):
+ if len(self._dl_term)>0:
+ # no classifier, fake it (maybe make a plain latex description).
+ classifier = 'datadescni'
+ self.body.append('\n\\begin{%s}' % classifier)
+ self.in_anydesc = classifier
+ self.body.append(self.anydesc_title(self._dl_term.pop()))
+ self.context.append('\\end{%s}\n' % classifier)
+ self.in_anydesc = None
+
+ def depart_definition(self, node):
+ pass
+
+
def depart_literal(self, node):
if not self.in_title:
self.body.append('}')
@@ -184,11 +292,52 @@
self.verbatim = 0
self.body.append("\n\\end{verbatim}\n")
+ def anydesc_title(self, title):
+ """Returns the title for xxxdesc environments."""
+ def markup_optional_parameters(s):
+ return s.replace('[','\\optional{').replace(']','}')
+ def with_params(s):
+ return markup_optional_parameters(
+ '{%s}' % s.replace('(','}{').replace(')',''))
+ def with_tag_or_typename(s, braces):
+ # "name", "tag name", "name(params)", "type name(params)"
+ param_pos = s.find("(")
+ blank_pos = s.find(" ")
+ if ((blank_pos>0 and param_pos<0)
+ or (blank_pos>0 and blank_pos<param_pos)):
+ (tag,rest) = s.split(None,1)
+ return braces[0] + tag + braces[1] + with_params(rest)
+ return with_params(s)
+ #
+ if self.in_anydesc in ('datadesc','datadescni','excdesc','classdesc*',
+ 'csimplemacrodesc'):
+ # \begin{xdesc}{name}
+ return '{%s}' % title
+ elif self.in_anydesc in ('ctypedesc','memberdesc','memberdescni',):
+ # \begin{ctypedesc} [tag]{name}
+ return with_tag_or_typename(title, '[]')
+ elif self.in_anydesc in ('classdesc', 'cvardesc','excclassdesc',
+ 'funcdesc','funcdescni'):
+ # "funcname(arguments)" to "{funcname}{arguments}"
+ # "funcname([arguments])" to "{funcname}{\optional{arguments}}"
+ return with_params(title)
+ elif self.in_anydesc in ('methoddesc','methoddescni'):
+ # \begin{methoddesc} [type name]{name}{parameters}
+ return with_tag_or_typename(title, '[]')
+ elif self.in_anydesc in ('cmemberdesc','cfuncdesc'):
+ # \begin{cmemberdesc} {container}{type}{name}
+ return with_tag_or_typename(title, '{}')
+ # fallback
+ return "{%s}" % title
+
def visit_title(self, node):
title = node.astext()
+ if self.in_anydesc:
+ self.body.append(self.anydesc_title(title))
+ raise nodes.SkipNode
title = self.remap_title.get(title, title)
+ # TODO label_prefix might not be set yet.
label = self.generate_section_label(title)
- #print "%s -> %s" % (title, label)
section_name = self.d_class.section(self.section_level + 1)
self.body.append("\n\n\\%s{" % section_name)
self.context.append("\\label{%s}}\n" % label)
@@ -197,40 +346,41 @@
def depart_title(self, node):
self.in_title = False
self.body.append(self.context.pop())
-
+
def visit_target(self, node):
pass
def depart_target(self, node):
pass
- def bookmark(self, node):
- pass
-
- def visit_definition(self, node):
- pass
-
- def depart_definition(self, node):
- pass
-
- def visit_definition_list_item(self, node):
- pass
+ def visit_admonition(self, node, name=''):
+ self.admonition_stack.append(name)
+ if name in ('note', 'warning'):
+ self.body.append('\\begin{notice}[%s]' % name)
+ else:
+ LaTeXTranslator.visit_admonition(self, node, name)
+ def depart_admonition(self, node=None):
+ name = self.admonition_stack.pop()
+ if name=="note":
+ self.body.append('\\end{notice}\n')
+ else:
+ LaTeXTranslator.depart_admonition(self, node)
- def depart_definition_list_item(self, node):
+ def bookmark(self, node):
pass
def visit_reference(self, node):
if node.has_key('refuri'):
refuri = node['refuri']
basename = os.path.splitext(refuri)[0]
- label = "optparse-" + self.refuri_override.get(basename, basename)
+ label = self.label_prefix + "-" + self.refuri_override.get(basename, basename)
print "got refuri=%r, label=%r" % (refuri, label)
elif node.has_key('refid'):
label = self.generate_section_label(node['refid'])
print "got refid=%r, label=%r" % (node['refid'], label)
else:
print "warning: unhandled reference: node=%r" % node
- LaTeXTranslator.visit_reference(self, node)
+ LaTeXTranslator.visit_reference(self, node)
self.body.append("section~\\ref{%s}, " % label)
raise nodes.SkipDeparture
@@ -247,12 +397,10 @@
text = self._em_dash_re.sub(u"\u2014", text)
text = self._quoted_phrase_re.sub(u"\u201C\\1\u201D", text)
text = re.sub(r'\bdocument\b', "section", text)
-#### text = re.sub(r'optik(\.[a-z]+)?', 'optparse', text)
text = self.encode(text)
# A couple of transformations are easiest if they go direct
# to LaTeX, so do them *after* encode().
-## text = text.replace("Optik", "\\module{optparse}")
text = text.replace("UNIX", "\\UNIX{}")
self.body.append(text)
@@ -260,24 +408,44 @@
def depart_Text(self, node):
pass
+ # table handling
+ # TODO move table handling into latex2e writer Table class.
+ def visit_table(self, node):
+ self.active_table.open()
+ def depart_table(self, node):
+ self.body.append('\\end{table%s}\n' %
+ (self.roman[len(self.active_table._col_specs)]) )
+ # TODO use roman to map name ? only i ... iv is supported
+ self.active_table.close()
+ def visit_thead(self, node):
+ self.body.append('\\begin{table%s}{l%s}{textrm}\n' %
+ (self.roman[len(self.active_table._col_specs)],
+ '|l'*(len(self.active_table._col_specs)-1)
+ ) )
+ self.active_table.set('preamble written',1)
+ def depart_thead(self, node):
+ pass
+ def visit_row(self, node):
+ if not isinstance(node.parent, nodes.thead):
+ self.body.append('\\line%s' %
+ (self.roman[len(self.active_table._col_specs)], )
+ )
+ def depart_row(self, node):
+ # CAUTION: latex2html stuffs content outside of {} into paragraphs
+ # before the table.
+ pass
+ def visit_entry(self, node):
+ if node.has_key('morerows') or node.has_key('morecols'):
+ raise NotImplementedError('Cells spanning rows or columns are not'
+ ' supported.')
+ # CAUTION: latex2html needs ``\lineii{`` the brace must follow
+ # immediately
+ self.body.append('{')
+ def depart_entry(self, node):
+ self.body.append('}\n')
-def concatenate_sources(sources, target):
- print "concatenating source files to %s" % target
- outdir = os.path.dirname(target)
- if not os.path.isdir(outdir):
- os.makedirs(outdir)
- outfile = open(target, "wt")
- for filename in sources:
- file = open(filename, "rt")
- for line in file:
- outfile.write(line)
- outfile.write("\n\n")
- file.close()
- outfile.close()
-
def convert(infilename, outfilename):
-
print "converting %s to %s" % (infilename, outfilename)
pub = Publisher()
pub.set_components('standalone', # reader
@@ -291,8 +459,7 @@
pub.publish()
def main():
- convert("tutorial.txt", "tutorial.tex")
- convert("tutorial.txt", "../../../trunk/Doc/lib/libctypes.tex")
+ convert(sys.argv[1], sys.argv[2])
if missing:
mod = open("missing.py", "w")
mod.write("# possible markups:\n")
Modified: external/ctypes/docs/manual/reference.txt
==============================================================================
--- external/ctypes/docs/manual/reference.txt (original)
+++ external/ctypes/docs/manual/reference.txt Sat Jun 10 22:08:12 2006
@@ -1,746 +1,552 @@
-ctypes manual
-+++++++++++++
+ctypes reference
+================
+Loading shared libraries
+------------------------
-Shared Libraries, DLLs
-----------------------
-
-Shared libraries are accessed when compiling/linking a program, and
-when the program is run. The purpose of the ``find`` method is to
-locate a library in a way similar to what the compiler does (on
-platforms with several versions of a shared library the most recent
-should be loaded), while ``load`` acts like when a program is run, and
-uses the runtime loader directly. ``load_version`` works like ``load``
-but tries to be platform independent (for cases where this makes
-sense). Loading via attribute access is a shorthand notation
-especially usefull for interactive use, it is equivalent to calling
-``load_version`` with no version specified.
-
-
-class LibraryLoader
-...................
-
-Instances of ``LibraryLoader`` are used to load shared libraries.
-Usually there is no need to create a libraryloader, instead one of the
-predefined loaders should be used.
-
-Libraryloaders have the following methods:
-
-``find(name, mode=None)``
-
- Try to find a library, load and return it. ``name`` is the
- library name without any prefix like ``lib``, suffix like ``.so``,
- ``.dylib`` or version number (this is the form used for the posix
- linker option ``-l``).
-
- ``mode`` allows to override the default flags passed to the
- ``dlopen()`` function, ignored on Windows.
-
- On Windows, this method does exactly the same as the ``load``
- method.
-
- On other platforms, this function might call other programs like
- the compiler to find the library. When using ctypes to write a
- shared library wrapping, consider using ``load_version`` or
- ``load`` instead.
-
-``load_version(name, version=None, mode=None)``
-
- Build a system dependent filename from ``name`` and optionally
- ``version``, then load and return it. ``name`` is the library
- name without any prefix like ``lib`` and suffix like ``.so`` or
- ``.dylib``. This method should be used if a library is available
- on different platforms, using the particular naming convention of
- each platform.
-
- ``mode`` allows to override the default flags passed to the
- ``dlopen()`` function, ignored on Windows.
-
- Example: calling ``loader.load_version('z', '1.1.3')`` would
- possibly load ``/usr/lib/libz.1.1.3.dylib`` on Mac OS X, or
- ``/lib/libz.so.1.1.3`` on a Linux system.
-
-``load(libname, mode=None)``
-
- Load and return the library with the given libname. On most
- systems ``libname`` is the filename of the shared library; when
- it's not a pathname it will be searched in a system dependent list
- of locations (on many systems additional search paths can be
- specified by an environment variable). Sometimes the file
- extension (like ``.dll`` on Windows) can be omitted.
-
- ``mode`` allows to override the default flags passed to the
- ``dlopen()`` function. ``RTLD_LOCAL`` and ``RTLD_GLOBAL`` are
- typical values. On Windows, ``mode`` is ignored.
-
-``load_library(pathname, mode=None``
-
- Load and return the library with the given pathname. This method
- passes the ``pathname`` directly to the underlying ``dlopen`` or
- ``LoadLibrary`` function.
-
- ``mode`` allows to override the default flags passed to the
- ``dlopen()`` function. ``RTLD_LOCAL`` and ``RTLD_GLOBAL`` are
- typical values. On Windows, ``mode`` is ignored.
-
-``LoadLibrary(pathname, mode=None)``
-
- This is an alias for the ``load_library`` method documented above,
- maintained for backwards comatibility only.
-
-
-Libaries can also be loaded by accessing them as attributes of the
-loader instance, internally this calls ``load_version`` without
-specifying ``version`` or ``mode``. Obviously this only works for
-libraries with names that are valid Python identifiers, and when the
-name does not start with a ``_`` character.
-
-Predefined library loaders
-..........................
-
-ctypes provides some LibraryLoader instances, the differences between
-them are the calling conventions the functions will use and the
-default return type of the functions. All these loaders use the
-``RTLD_LOCAL`` mode flag.
-
-Functions can be accessed as named attributes of loaded libraries.
-
-On Windows, structured exception handling is used around the function
-call to protect Python from crashing in case you pass invalid
-parameters to the function.
-
-``cdll``
-
- Functions provided by libraries loaded using the ``cdll`` loader
- will be called with the standard C calling convention, and have a
- default return type of ``int``. ctypes releases the Python global
- interpreter lock (GIL) just before calling the foreign function,
- and reacquires it before returing, so other threads are able to
- run.
-
-``windll``
-
- Windows only. Functions provided by libraries loaded by
- ``windll`` will be called using the Windows ``__stdcall`` calling
- convention. ctypes can detect when the wrong number
- of parameters has been passed to the function call by examining
- the stack pointer before and after the function call. If the
- wrong parameter count was used, an exception is raised (although
- the function really *has* been called). The return value of the
- function is lost in this case. Again, the GIL is released during
- the duration of the function call.
-
-``oledll``
-
- Windows only. ``oledll`` behaves in the same way as ``windll``,
- except that the called function is expected to return a
- ``HRESULT`` value. These are long values containing error or
- success codes. In case the function returns an error ``HRESULT``
- value, a ``WindowsError`` is raised. The GIL is released during the
- duration of function call.
-
-``pydll``
-
- This loader allows to call functions in libraries using the
- *Python* calling convention, for example Python C API functions.
- The GIL is *not* released during the function call, and the state
- of the Python error flag is examined after the function returns.
- If the error flag is set, the Python exception is raised.
-
- ctypes provides a prefabricated instance of ``pydll`` exposing the
- Python C api as the ``pythonapi`` symbol, you should however make
- sure to set the correct ``restype`` for the functions you use.
-
-Library objects
-...............
-
-The library loaders create instances of ``CDLL``, ``WinDLL``,
-``OleDLL``, or ``PyDLL`` classes. You can, however, also load a
-library by constructing one of these classes by calling the
-constructor with the pathname of the library and an optional ``mode``
-argument as described in the previous section.
-
-Library objects implement ``__getattr__`` and ``__getitem__`` methods
-that allow to access foreign functions by attribute access or
-indexing. The latter is useful if the name of the function is not a
-valid Python identifier, or clashes with special Python method names
-that start and end with two underscore characters.
-
-Library objects have two private attributes: ``_name`` is the pathname
-of the library, ``_handle`` is the handle to the library that
-``dlopen`` has returned.
-
-
-Foreign functions
------------------
-
-Functions exported from loaded shared libraries (foreign functions)
-can be accessed in two ways. The easiest way is to retrieve them as
-attributes of library objects by name::
-
- libc = cdll.find("c") # posix
- libc = cdll.msvcrt # windows
- # attribute access
- atoi = libc.atoi
- # alternative indexing notation
- atoi = libc["atoi"]
-
-This creates an instance of a foreign function object, using the
-calling convention specified by the library object ``cdll``, bound to
-the C library ``atoi`` function. The C function is assumed to return
-an integer (which is correct for ``atoi``), and the argument types are
-not specified (``atoi`` expects a single ``char *`` argument).
-
-If the library function returns a type different from ``int``, the
-``restype`` attribute can be set to a ctypes type that describes the
-return type, or to ``None`` meaning no return value (``void``).
-
-The optional ``argtypes`` attribute can be set to a sequence of ctypes
-types that the function expects.
-
-If needed, the function can (as in C) be called with more arguments
-than the length of the argtypes sequence.
-
-The optional ``errcheck`` attribute can be set to a Python callable,
-which can be used to validate and/or process the library function's return
-value. ``errcheck`` will be called with three arguments, after the
-library function has returned::
-
- errcheck(retval, function, arguments)
-
-``retval`` is the value that the library function returned, converted
-according to ``restype``. ``function`` is the ctypes function object
-(libc.atoi in this case), and ``arguments`` is a tuple containing the
-arguments that have been used to call ``function``. ``errcheck``
-should validate the library function result, raise an error if it
-detects a failure, or return the needed return value otherwise.
-
-Function prototypes
-...................
-
-Another way to access a function exported from shared libraries is to
-first create a prototype by calling a factory function, specifying the
-return type and the argument types. The factory function itself
-specifies the calling convention: ``CFUNCTYPE`` uses the standard C
-calling convention, ``WINFUNCTYPE`` (Windows only) uses the stdcall
-calling convention. The factory function must be called with the
-return type plus the argument types. For the C ``atoi`` function one
-would use ``CFUNCTYPE(c_int, c_char_p)``.
-
-This returns a function prototype, which is a ctypes type representing
-all functions that are compatible with the calling convention, return
-type, and argument types.
-
-The ``CFUNCTYPE`` and ``WINFUNCTYPE`` factory functions cache and
-reuse the types they create in internal caches, so is is cheap to call
-them over and over with the same or different arguments.
-
-An instance of this function prototype, bound to a foreign library
-function, can be created by calling the prototype with the name of the
-function as string, and a loaded library::
-
- proto = CFUNCTYPE(c_int, c_char_p)
- atoi = proto("atoi", libc)
-
-Parameter flags
-...............
-
-It is possible to specify a third argument ``paramflags`` when calling
-the prototype. This is used to specify additional information for
-each argument: direction of data transfer, the name, and a default
-value.
-
-A tuple with the same length as ``argtypes`` (the second argument in
-the prototype call) must be used. Each item in this tuple must be a
-tuple, having either one, two, or three items.
-
-The first item is the direction flag, an integer specifying if this is
-an input (use ``1``) or an output (use ``2``) parameter. The optional
-second item is a string containing the parameter name, the optional
-third item is a default value for the parameter.
-
-If parameter names are specified, the function object created can be
-called with named arguments in the usual way. Arguments with default
-values do not need to be specified when the function is called.
-
-``out`` parameter types must be pointer types. When the function
-object is called, ctypes will automatically create empty instances of
-them, pass them to the library function, retrieve the value from them,
-and return the value, if there is exactly one ``out`` parameter, or a
-tuple of values, if there is more than one ``out`` parameter. The
-original foreign function return value is lost in this case (but see
-below for how it can be retrieved).
-
-If ``paramflags`` have been used in the prototype call, and an
-``errcheck`` attribute is also present, the ``errcheck`` callable will
-be called with a fourth parameter ``outargs``::
-
- errcheck(retval, function, arguments, outargs)
-
-``outargs`` is a tuple containing all the ``out`` parameters that
-ctypes has created. Without the ``errcheck`` function ctypes would
-retrieve the values contained in these pointer objects, and return
-them. The ``errcheck`` function can let ctypes continue this
-processing by returning the ``outargs`` tuple. It could also return
-something else, or raise an error if it detects that the library
-function has failed.
-
-Callback functions
-..................
-
-ctypes is able to create C callable functions from Python callables.
-This is useful because sometimes library functions need a callback
-function parameter; the ``qsort`` C function is such an example.
-
-Callback functions are created by first creating a function prototype
-with a call to ``CFUNCTYPE`` or ``WINFUNCTYPE``, specifying the return
-type and the argument types that the callback function will receive.
-
-Calling the prototype with a single Python callable will create and
-return a C-callable function pointer or callback function. Note that
-this allows using prototypes as decorators creating callback
-functions (Windows example)::
-
- @WINFUNCTYPE(BOOL, HWND, LPARAM)
- def enumwindowsproc(hwnd, lParam):
- ....
- return True
-
-When a Python exception is raised in the Python callable, the return
-value of the C callable function is undefined.
-
-Important note: You must keep a reference to the callback AS LONG as
-foreign code will call it! Segfaults will result if the callback is
-cleaned up by Python's garbage collector and external code then
-tries to call it.
-
-Callback objects can also be called from Python - this may be useful
-for debugging.
-
-
-COM methods (Windows only)
-..........................
-
-XXX Should this be left undocumented? Mentioned for completeness.
-
-The prototypes created by ``WINFUNCTYPE`` can be called with a
-positive small integer ``index``, a string ``name``, an optional
-``paramflags`` tuple, and a optional ``iid`` parameter.
-
-This creates a function object wrapping a COM method. ``index`` is
-the index into the COM object's virtual function table, ``name`` is
-the name of the COM method (only useful for debugging), ``paramflags``
-has the same meaning as for normal function objects, and ``iid`` is a
-string or buffer containing the interface id of the COM interface
-this method belongs to. ``iid`` is used to get extended COM error
-information in case the method returns a FAILED ''HRESULT`` value.
-
-Note that COM methods expect an additional first argument that is NOT
-listed in the prototypes ``argtypes`` when they are called: this must
-be the integer address of a COM interface pointer.
-
-
-Simple types
-------------
-
-Simple types have some special behaviour: When they are accessed as
-structure or union fields, items of array instances, or as foreign
-function return values, they are transparently converted from and to
-the native Python types int, long, string, and unicode.
-
-This is *not* the case for subclasses of simple data types, so while a
-``c_void_p`` type is transparently converted from and to Python
-integer or long, a subclass of c_void_p is *not* converted. This
-allows you to define new behaviour almost completely.
-
-Class attributes of simple types
-................................
-
-``__ctype__be__``, ``__ctype_le__``
-
- If the type supports different byte order (pointer types do NOT
- support this), ``__ctype_be__`` and ``__ctype_le__`` are types
- with bug endian and little endian byte order. For example,
- ``c_int.__ctype_be__`` is an integer type with the memory block in
- big endian byte order.
-
-``_type_``
-
- Implementation artifact: the typecode for this type, a single
- character string code compatible to what the ``struct`` module uses.
- Additional characters are used for types that the ``struct`` module
- does not support.
-
-
-Class methods of simple types
-.............................
-
-(To be exact, these are not class methods, instead these are methods
-of the metaclass. The most prominent difference to classmethods is
-that you can call these methods on the class, but not on the instance
-of the simple type.)
-
-``__ctypes_from_outparam__``
-
- TBD
-
-``from_address``
-
- TBD
-
-``from_param``
-
- This class method is used to adapt function parameters. If a type
- is specified in a function's argtypes sequence, in a function call
- the ``from_param(arg)`` method will be called with the actual
- argument, and the result will be passed to the foreign function
- call as a parameter.
-
- ``from_param`` usually returns an internal object that you cannot
- use in Python code - it only makes sense to pass this object to
- foreign functions.
-
- On one hand, ``from_param`` is a performance optimization - it
- allows you to pass Python integers to function calls expecting a
- ``c_int`` argument type, without having to create a full-featured
- ``c_int`` instance.
-
- On the other hand, ``from_param`` can adapt other objects to
- parameters. XXX explain the automatic ``byref`` call for byref
- arguments.
-
-``in_dll``
-
- TBD
-
-Instance attributes of simple types
-...................................
-
-``value``
-
- Allows to get or set the current value of the object. For simple
- types, this is always a native Python object like integer, long,
- string, unicode, or None.
-
-``_objects`` (never modify this)
-
- Implementation artifact: a Python object keeping references to
- other objects which must be kept alive. Never modify anything on
- the returned object. XXX Should probably not be exposed.
-
-``_b_base_`` (readonly)
-
- Implementation artifact: the base object owning the memory block
- (if any).
-
-``_b_needsfree_`` (readonly)
-
- Implementation artifact: does this object have to free its memory
- block on destruction.
-
-``_as_parameter_`` (readonly)
-
- Implementation artifact (?): how to pass this object as a function
- parameter.
-
-
-Numeric types
-.............
-
-Integer types are ``c_byte``, ``c_short``, ``c_int``, ``c_long``,
-``c_longlong`` and their unsigned variants ``c_ubyte``, ``c_ushort``,
-``c_uint``, ``c_ulong`` and ``c_ulonglong``, floating point types are
-``c_float`` and ``c_double``.
-
-The constructor and the ``from_param`` class method accept a Python
-integer for integer types, a Python float for floating point types.
-
-On 32-bit platforms where sizeof(int) == sizeof(long), ``c_int`` is an
-alias for ``c_long``, on 64-bit platforms where sizeof(long) ==
-sizeof(long long), ``c_long`` is an alias for ``c_longlong``.
-
-Character types
-...............
-
-Character types are ``c_char`` and ``c_wchar``, representing the C
-``char`` and ``wchar_t`` types.
-
-The constructor and the ``from_param`` class method accept a single
-character Python string or unicode string. Conversion between string
-and unicode, if needed, is done according to the ctypes
-encoding/decoding rules.
-
-
-Pointer types
-.............
-
-The only simple pointer type is ``c_void_p``, which represents the C
-``void *`` data type. ``c_void_p`` can also be written as
-``POINTER(None)``.
-
-The constructor accepts one optional argument, which must be an
-integer or long (interpreted as an address), or ``None``.
-
-The ``from_param`` class method accepts everything that could be used
-as a pointer. XXX Should accept objects using the buffer interface as
-well.
-
-The ``value`` attribute accepts and returns None or integer.
-
-XXX Shouldn't the constructor accept the same types as from_param?
-
-
-String types
-............
-
-ctypes has the ``c_char_p`` and ``c_wchar_p`` types which represent
-const pointers to zero terminated strings in C: ``const char *`` and
-``const wchar_t *``. Since strings and Unicode instances are
-immutable, these types should be considered readonly: do not pass them
-to functions that write into the buffer.
-
-The constructor accepts one optional argument, which must be a Python
-or unicode string, an integer, or ``None``.
-
-The ``from_param`` class method accepts a string or a Unicode string,
-as well as ``None``. Conversion between string and Unicode, if
-needed, is done according to the ctypes encoding/decoding rules.
-
-XXX Why does the constructor accept an integer, and from_param doesn't?
-
-Structure and union types
--------------------------
-
-ctypes provides the abstract base classes ``Structure`` and ``Union``
-to define structure and union types. Subclasses must at least define
-a ``_fields_`` attribute.
-
-Defining field names and types
-..............................
-
-``_fields_`` must be a sequence of tuples. The first item of each
-tuple is a string specifying the name of the structure/union field.
-The second item must by a ctypes type.
-
-A descriptor will be created for each field, allowing you to access the
-field's contents from instances. Accessed from the class, the fields
-expose readonly ``.offset`` and ``.size`` attributes. ``offset`` is
-the byte-offset of the field from the beginning of the
-structure/union, ``size`` is the number of bytes the field contains.
+``LibraryLoader(dlltype)`` : classdesc
+ Class which loads shared libraries.
-A simple example is a POINT structure containing integer fields named
-``x`` and ``y``::
+``LoadLibrary(name, mode=RTLD_LOCAL, handle=None)`` : methoddesc
+ Load a shared library.
- class Point(Structure):
- _fields_ = [("x", c_int),
- ("y", c_int)]
+``CDLL(name, mode=RTLD_LOCAL, handle=None)`` : classdesc
+ XXX
+``cdll`` : vardesc
+ XXX
+``OleDLL(name, mode=RTLD_LOCAL, handle=None)`` : funcdesc
+ XXX
-Field alignment
-...............
+``oledll`` : vardesc
+ XXX
-Normally fields are aligned in the same way as the host's C compiler
-would do it. This native alignment can be overridden by setting a
-``_pack_`` attribute in the type. It must be a small positive integer
-which is the maximum field alignment.
+``py_object`` : classdesc*
+ XXX
-Bit fields
-..........
+``PyDLL(name, mode=RTLD_LOCAL, handle=None)`` : funcdesc
+ XXX
-Integer fields support bit sizes. The bit-size must be specified as
-the third item of the ``_fields_`` tuple. Bit fields are constructed
-in the same way the host's C compiler does it. For bit fields, the
-field descriptor's ``.size`` attribute contains the number of bits in
-the high word, and the bit offset from the beginning of the structure in
-the low word. XXX is that correct?
+``pydll`` : vardesc
+ XXX
-Recursive data types
-....................
+``RTLD_GLOBAL`` : vardesc
+ XXX
-To define recursive types, it is possible to assign the ``_fields_``
-value *after* the class statement. Here is an example of a linked
-list data structure, which contains a pointer to itself::
+``RTLD_LOCAL`` : vardesc
+ XXX
- class Node(Structure):
- pass
- Node._fields_ = [("next", POINTER(Node)),
- ("value", ...)]
+``WinDLL(name, mode=RTLD_LOCAL, handle=None)`` : funcdesc
+ XXX
-``_fields_`` must be set, and cannot be changed, after the type is
-used for the first time.
+``windll`` : vardesc
+ XXX
-Byte order
-..........
+``pythonapi()`` : vardesc
+ XXX
-It is possible to create Structure and Union types using non-native
-byte order by using the ``BigEndianStructure``,
-``LittleEndianStructure``, ``BigEndianUnion``, and
-``LittleEndianUnion`` base classes. Structures and Unions with
-non-native byte order do *not* support pointer fields.
-
-
-Builtin functions
+Foreign functions
-----------------
-``addressof(object)``
-
- Returns the address of a ctypes instance as an integer.
-
-``alignment(type_or_object)``
-
- Returns the alignment requirements in bytes of a ctypes type or
- instance.
-
-``byref(object)``
-
- Returns a light-weight pointer to a ctypes instance. The returned
- object can only be used as function call parameter. Behaves the
- same as calling ``pointer(object)``, but is a lot faster. Same as
- ``&object`` in C.
-
-``cast(object, typ)``
-
- This function is similar to the cast operator in C. Returns a new
- instance of ``type`` which shares the memory block of ``object``.
- ``typ`` must be a pointer type.
-
-``CFUNCTYPE(restype, *argtypes)``
-
- Create a function prototype using the C calling convention.
-
-
-``create_string_buffer(init, size=None)``
-
- Convenience function to create a mutable character buffer.
-
- ``init`` must be a string. If ``size`` is supplied it must be a
- positive integer that specifies the size of the buffer, otherwise
- the length of the ``init`` string is used.
- This function returns a ctypes array of characters ``c_char``.
-
-``create_unicode_buffer(init, size=None)``
-
- Convenience function to create a mutable unicode buffer.
-
- ``init`` must be a unicode string. If ``size`` is supplied it
- must be a positive integer that specifies the number of characters
- in the buffer, otherwise the length of the ``init`` string is
- used. This function returns a ctypes array of characters ``c_wchar``.
-
-
-``DllCanUnloadNow()``, ``DllGetClassObject(rclsid, riid, ppv)`` (Windows only)
-
- Functions used to implement COM servers.
-
-
-``FormatError([code])`` (Windows only)
-
- Returns a textual description of the error code, or the last error
- code set by Windows.
-
-``GetLastError()`` (Windows only)
-
- Returns the last error code set by Windows.
-
-``memmove(dst, src, count)``
+The ultimate goal of ``ctypes`` is to call functions in shared
+libraries, aka as foreign functions. Foreign function instances can
+be created by retrieving them as attributes of loaded shared
+libraries, or by instantiating a *function prototype*.
+
+By default, functions got as attributes of loaded shared libraries
+accept any arguments, and have a return type of ``c_int``.
+
+Function prototypes are created by factory functions.
+
+They are created by calling one of the following factory functions:
+
+``CFUNCTYPE(restype, *argtypes)`` : funcdesc
+ This is a factory function that returns a function prototype. The
+ function prototype describes a function that has a result type of
+ ``restype``, and accepts arguments as specified by
+ ``argtypes``. The function prototype can be used to construct
+ several kinds of functions, depending on how the prototype is
+ called.
+
+ The prototypes returned by ``CFUNCTYPE`` or ``PYFUNCTYPE`` create
+ functions that use the standard C calling convention, prototypes
+ returned from ``WINFUNCTYPE`` (on Windows) use the ``__stdcall``
+ calling convention.
+
+ Functions created by calling the ``CFUNCTYPE`` and ``WINFUNCTYPE``
+ prototypes release the Python GIL before entering the foreign
+ function, and acquire it back after leaving the function code.
- Same as the standard C ``memmove`` library function: copies
- ``count`` bytes from ``src`` to ``dst``. ``dst`` and ``src`` must
- be integers or anything else that can be converted into a pointer.
-
-``memset(dst, c, count)``
-
- Same as the standard C ``memset`` function. Fills the memory block
- at address ``dst`` with ``count`` bytes of value ``c``. ``dst`` must be
- an integer specifying an address, or a ctypes instance.
-
-
-``pointer(object)``
-
- This function creates a new pointer instance, pointing to the
- supplied argument which must be an instance of a ctypes type. The
- return pointer is of type ``POINTER(type(object))``. If you have
- a ctypes instance, and you want to pass the address of it to a
- function call, you should use ``byref(object)`` instead which is
- much faster.
-
- NULL pointer instances are boolean``False``, so to check for a
- NULL pointer do this::
-
- # assuming ptr is in ctypes pointer instance
- if ptr:
- print "Non-NULL pointer instance"
- else:
- print "NULL pointer instance"
-
-
-``POINTER(cls)``
-
- This factory function creates and returns a new ctypes type.
- Pointer types are cached, so calling this function is cheap.
-
- To create a ``NULL`` pointer instance, call the created type
- without an argument::
+``WINFUNCTYPE(restype, *argtypes)`` : funcdesc
+ TBD
- null_ptr = POINTER(c_int)()
+``PYFUNCTYPE(restype, *argtypes)`` : funcdesc
+ TBD
+``ArgumentError()`` : excdesc
+ This exception is raised when a foreign function call cannot
+ convert one of the passed arguments.
-``set_conversion_mode(encoding, errors)``
- This function sets the encoding/decoding rules which are used when
- ctypes has to convert between unicode and byte strings. It
- returns the previous encoding, as well as a tuple of any errors.
- If not set, default conversions are used:
- On Windows, ``msbc, ignore`` , on other systems, ``ascii, strict``.
+Utility functions
+-----------------
-``sizeof(type_or_object)``
+``addressof(obj)`` : funcdesc
+ Returns the address of the memory buffer as integer. ``obj`` must
+ be an instance of a ctypes type.
+
+``alignment(obj_or_type)`` : funcdesc
+ Returns the alignment requirements of a ctypes type.
+ ``obj_or_type`` must be a ctypes type or instance.
+
+``byref(obj)`` : funcdesc
+ Returns a light-weight pointer to ``obj``, which must be an
+ instance of a ctypes type. The returned object can only be used as
+ a foreign function call parameter. It behaves similar to
+ ``pointer(obj)``, but the construction is a lot faster.
+
+``cast(obj, type)`` : funcdesc
+ This function is similar to the cast operator in C. It returns a
+ new instance of ``type`` which points to the same memory block as
+ ``obj``. ``type`` must be a pointer type, and ``obj`` must be an
+ object that can be interpreted as a pointer.
+
+``create_string_buffer(init_or_size[, size])`` : funcdesc
+ This function creates a mutable character buffer. The returned
+ object is a ctypes array of ``c_char``.
+
+ ``init_or_size`` must be an integer which specifies the size of
+ the array, or a string which will be used to initialize the array
+ items.
+
+ If a string is specified as first argument, the buffer is made one
+ item larger than the length of the string so that the last element
+ in the array is a NUL termination character. An integer can be
+ passed as second argument which allows to specify the size of the
+ array if the length of the string should not be used.
+
+ If the first parameter is a unicode string, it is converted into
+ an 8-bit string according to ctypes conversion rules.
+
+``create_unicode_buffer(init_or_size[, size])`` : funcdesc
+ This function creates a mutable unicode character buffer. The
+ returned object is a ctypes array of ``c_wchar``.
+
+ ``init_or_size`` must be an integer which specifies the size of
+ the array, or a unicode string which will be used to initialize
+ the array items.
+
+ If a unicode string is specified as first argument, the buffer is
+ made one item larger than the length of the string so that the
+ last element in the array is a NUL termination character. An
+ integer can be passed as second argument which allows to specify
+ the size of the array if the length of the string should not be
+ used.
+
+ If the first parameter is a 8-bit string, it is converted into an
+ unicode string according to ctypes conversion rules.
+
+``DllCanUnloadNow()`` : funcdesc
+ Windows only: This function is a hook which allows to implement
+ inprocess COM servers with ctypes. It is called from the
+ DllCanUnloadNow function that the _ctypes extension dll exports.
+
+``DllGetClassObject()`` : funcdesc
+ Windows only: This function is a hook which allows to implement
+ inprocess COM servers with ctypes. It is called from the
+ DllGetClassObject function that the ``_ctypes`` extension dll exports.
+
+``FormatError([code])`` : funcdesc
+ Windows only: Returns a textual description of the error code. If
+ no error code is specified, the last error code is used by calling
+ the Windows api function GetLastError.
+
+``GetLastError()`` : funcdesc
+ Windows only: Returns the last error code set by Windows in the
+ calling thread.
+
+``memmove(dst, src, count)`` : funcdesc
+ Same as the standard C memmove library function: copies ``count``
+ bytes from ``src`` to ``dst``. ``dst`` and ``src`` must be
+ integers or ctypes instances that can be converted to pointers.
+
+``memset(dst, c, count)`` : funcdesc
+ Same as the standard C memset library function: fills the memory
+ block at address ``dst`` with ``count`` bytes of value
+ ``c``. ``dst`` must be an integer specifying an address, or a
+ ctypes instance.
+
+``POINTER(type)`` : funcdesc
+ This factory function creates and returns a new ctypes pointer
+ type. Pointer types are cached an reused internally, so calling
+ this function repeatedly is cheap. type must be a ctypes type.
+
+``pointer(obj)`` : funcdesc
+ This function creates a new pointer instance, pointing to
+ ``obj``. The returned object is of the type POINTER(type(obj)).
+
+ Note: If you just want to pass a pointer to an object to a foreign
+ function call, you should use ``byref(obj)`` which is much faster.
+
+``resize(obj, size)`` : funcdesc
+ This function resizes the internal memory buffer of obj, which
+ must be an instance of a ctypes type. It is not possible to make
+ the buffer smaller than the native size of the objects type, as
+ given by sizeof(type(obj)), but it is possible to enlarge the
+ buffer.
+
+``set_conversion_mode(encoding, errors)`` : funcdesc
+ This function sets the rules that ctypes objects use when
+ converting between 8-bit strings and unicode strings. encoding
+ must be a string specifying an encoding, like ``'utf-8'`` or
+ ``'mbcs'``, errors must be a string specifying the error handling
+ on encoding/decoding errors. Examples of possible values are
+ ``"strict"``, ``"replace"``, or ``"ignore"``.
+
+ set_conversion_mode returns a 2-tuple containing the previous
+ conversion rules. On windows, the initial conversion rules are
+ ``('mbcs', 'ignore')``, on other systems ``('ascii', 'strict')``.
+``sizeof(obj_or_type)`` : funcdesc
Returns the size in bytes of a ctypes type or instance memory
- buffer. Does the same as the C sizeof() function.
-
+ buffer. Does the same as the C ``sizeof()`` function.
-``string_at(addr[, size])``
-
- This function does the same as the Python ``PyString_FromString`` /
- ``PyString_FromStringAndSize`` C api functions.
-
-``WinError(code=None, descr=None)``
-
- XXX This is probably the worst named thing in ctypes!
-
- This function creates a ``WindowsError`` instance. If ``code`` is
- not specified, GetLastError() is called to determine the error
- code. If ``descr`` is not specified, ``FormatError`` is called to
+``string_at(address[, size])`` : funcdesc
+ This function returns the string starting at memory address
+ address. If size is specified, it is used as size, otherwise the
+ string is assumed to be zero-terminated.
+
+``WinError(code=None, descr=None)`` : funcdesc
+ Windows only: this function is probably the worst-named thing in
+ ctypes. It creates an instance of WindowsError. If ``code`` is not
+ specified, ``GetLastError`` is called to determine the error
+ code. If ``descr`` is not spcified, ``FormatError`` is called to
get a textual description of the error.
-``WINFUNCTYPE(restype, *argtypes)`` (Windows only)
-
- Create a function prototype using the __stdcall calling convention
- (on Windows), or using the C calling convention (on Windows CE).
-
-``wstring_at(addr[, size])``
-
- This function does the same as the Python ``PyUnicode_FromWideString``
- C api function. If ``size`` is not specified, ``wcslen`` is used
- to determine the string length.
+``wstring_at(address)`` : funcdesc
+ This function returns the wide character string starting at memory
+ address ``address`` as unicode string. If ``size`` is specified,
+ it is used as the number of characters of the string, otherwise
+ the string is assumed to be zero-terminated.
+
+
+Data types
+----------
+
+``_CData`` : classdesc*
+ This non-public class is the common base class of all ctypes data
+ types. Among other things, all ctypes type instances contain a
+ memory block that hold C compatible data; the address of the
+ memory block is returned by the ``addressof()`` helper function.
+ Another instance variable is exposed as ``_objects``; this
+ contains other Python objects that need to be kept alive in case
+ the memory block contains pointers.
+
+Common methods of ctypes data types, these are all class methods (to
+be exact, they are methods of the metaclass):
+
+``from_address(address)`` : methoddesc
+ This method returns a ctypes type instance using the memory
+ specified by address.
+
+``from_param(obj)`` : methoddesc
+ This method adapts obj to a ctypes type.
+
+``in_dll(name, library)`` : methoddesc
+ This method returns a ctypes type instance exported by a shared
+ library. ``name`` is the name of the symbol that exports the data,
+ ``library`` is the loaded shared library.
+
+Common instance variables of ctypes data types:
+
+``_b_base_`` : memberdesc
+ Sometimes ctypes data instances do not own the memory block they
+ contain, instead they share part of the memory block of a base
+ object. The ``_b_base_`` readonly member is the root ctypes
+ object that owns the memory block.
+
+``_b_needsfree_`` : memberdesc
+ This readonly variable is true when the ctypes data instance has
+ allocated the memory block itself, false otherwise.
+
+``_objects`` : memberdesc
+ This member is either ``None`` or a dictionary containing Python
+ objects that need to be kept alive so that the memory block
+ contents is kept valid. This object is only exposed for
+ debugging; never modify the contents of this dictionary.
+Fundamental data types
+----------------------
-Deprecated functions
-....................
-
-These deprecated functions are still supported for backwards
-comatibility, they should not be used for new code:
-
-``c_buffer(init, size=None)``
-
- Deprecated. Use ``create_string_buffer()`` instead.
-
-``ARRAY(cls, len)``
-
- Deprecated. Use ``cls * len`` instead.
+``_SimpleCData`` : classdesc*
+ This non-public class is the base class of all fundamental ctypes
+ data types. It is mentioned here because it contains the common
+ attributes of the fundamental ctypes data types. ``_SimpleCData``
+ is a subclass of ``_CData``, so it inherits their methods and
+ attributes.
+
+Instances have a single attribute:
+
+``value`` : memberdesc
+ This attribute contains the actual value of the instance. For
+ integer and pointer types, it is an integer, for character types,
+ it is a single character string, for character pointer types it
+ is a Python string or unicode string.
+
+ When the ``value`` attribute is retrieved from a ctypes instance,
+ usually a new object is returned each time. ``ctypes`` does *not*
+ implement original object return, always a new object is
+ constructed. The same is true for all other ctypes object
+ instances.
+
+Fundamental data types, when returned as foreign function call
+results, or, for example, by retrieving structure field members or
+array items, are transparently converted to native Python types. In
+other words, if a foreign function has a ``restype`` of ``c_char_p``,
+you will always receive a Python string, *not* a ``c_char_p``
+instance.
+
+Subclasses of fundamental data types do *not* inherit this behaviour.
+So, if a foreign functions ``restype`` is a subclass of ``c_void_p``,
+you will receive an instance of this subclass from the function call.
+Of course, you can get the value of the pointer by accessing the
+``value`` attribute.
+
+These are the fundamental ctypes data types:
+
+``c_byte`` : classdesc*
+ Represents the C signed char datatype, and interprets the value as
+ small integer. The constructor accepts an optional integer
+ initializer; no overflow checking is done.
+
+``c_char`` : classdesc*
+ Represents the C char datatype, and interprets the value as a single
+ character. The constructor accepts an optional string initializer,
+ the length of the string must be exactly one character.
+
+``c_char_p`` : classdesc*
+ Represents the C char * datatype, which must be a pointer to a
+ zero-terminated string. The constructor accepts an integer
+ address, or a string.
+
+``c_double`` : classdesc*
+ Represents the C double datatype. The constructor accepts an
+ optional float initializer.
+
+``c_float`` : classdesc*
+ Represents the C double datatype. The constructor accepts an
+ optional float initializer.
+
+``c_int`` : classdesc*
+ Represents the C signed int datatype. The constructor accepts an
+ optional integer initializer; no overflow checking is done. On
+ platforms where ``sizeof(int) == sizeof(long)`` it is an alias to
+ ``c_long``.
+
+``c_int8`` : classdesc*
+ Represents the C 8-bit ``signed int`` datatype. Usually an alias for
+ ``c_byte``.
+
+``c_int16`` : classdesc*
+ Represents the C 16-bit signed int datatype. Usually an alias for
+ ``c_short``.
+
+``c_int32`` : classdesc*
+ Represents the C 32-bit signed int datatype. Usually an alias for
+ ``c_int``.
+
+``c_int64`` : classdesc*
+ Represents the C 64-bit ``signed int`` datatype. Usually an alias
+ for ``c_longlong``.
+
+``c_long`` : classdesc*
+ Represents the C ``signed long`` datatype. The constructor accepts an
+ optional integer initializer; no overflow checking is done.
+
+``c_longlong`` : classdesc*
+ Represents the C ``signed long long`` datatype. The constructor accepts
+ an optional integer initializer; no overflow checking is done.
+
+``c_short`` : classdesc*
+ Represents the C ``signed short`` datatype. The constructor accepts an
+ optional integer initializer; no overflow checking is done.
+
+``c_size_t`` : classdesc*
+ Represents the C ``size_t`` datatype.
+
+``c_ubyte`` : classdesc*
+ Represents the C ``unsigned char`` datatype, it interprets the
+ value as small integer. The constructor accepts an optional
+ integer initializer; no overflow checking is done.
+
+``c_uint`` : classdesc*
+ Represents the C ``unsigned int`` datatype. The constructor accepts an
+ optional integer initializer; no overflow checking is done. On
+ platforms where ``sizeof(int) == sizeof(long)`` it is an alias for
+ ``c_ulong``.
+
+``c_uint8`` : classdesc*
+ Represents the C 8-bit unsigned int datatype. Usually an alias for
+ ``c_ubyte``.
+
+``c_uint16`` : classdesc*
+ Represents the C 16-bit unsigned int datatype. Usually an alias for
+ ``c_ushort``.
+
+``c_uint32`` : classdesc*
+ Represents the C 32-bit unsigned int datatype. Usually an alias for
+ ``c_uint``.
+
+``c_uint64`` : classdesc*
+ Represents the C 64-bit unsigned int datatype. Usually an alias for
+ ``c_ulonglong``.
+
+``c_ulong`` : classdesc*
+ Represents the C ``unsigned long`` datatype. The constructor accepts an
+ optional integer initializer; no overflow checking is done.
+
+``c_ulonglong`` : classdesc*
+ Represents the C ``unsigned long long`` datatype. The constructor
+ accepts an optional integer initializer; no overflow checking is
+ done.
+
+``c_ushort`` : classdesc*
+ Represents the C ``unsigned short`` datatype. The constructor accepts an
+ optional integer initializer; no overflow checking is done.
+
+``c_void_p`` : classdesc*
+ Represents the C ``void *`` type. The value is represented as
+ integer. The constructor accepts an optional integer initializer.
+
+``c_wchar`` : classdesc*
+ Represents the C ``wchar_t`` datatype, and interprets the value as a
+ single character unicode string. The constructor accepts an
+ optional string initializer, the length of the string must be
+ exactly one character.
+
+``c_wchar_p`` : classdesc*
+ Represents the C ``wchar_t *`` datatype, which must be a pointer to
+ a zero-terminated wide character string. The constructor accepts
+ an integer address, or a string.
+
+``HRESULT`` : classdesc*
+ Windows only: Represents a ``HRESULT`` value, which contains success
+ or error information for a function or method call.
+
+Structured data types
+---------------------
+
+``Union(*args, **kw)`` : classdesc
+ Abstract base class for unions in native byte order.
+
+``BigEndianStructure(*args, **kw)`` : classdesc
+ Abstract base class for structures in *big endian* byte order.
+
+``LittleEndianStructure(*args, **kw)`` : classdesc
+ Abstract base class for structures in *little endian* byte order.
+
+Structures with non-native byte order cannot contain pointer type
+fields, or any other data types containing pointer type fields.
+
+``Structure(*args, **kw)`` : classdesc
+ Abstract base class for structures in *native* byte order.
+
+Concrete structure and union types must be created by subclassing one
+of these types, and at least define a ``_fields_`` class variable.
+``ctypes`` will create descriptors which allow reading and writing the
+fields by direct attribute accesses. These are the
+
+``_fields_`` : memberdesc
+ A sequence defining the structure fields. The items must be
+ 2-tuples or 3-tuples. The first item is the name of the field,
+ the second item specifies the type of the field; it can be any
+ ctypes data type.
+
+ For integer type fields, a third optional item can be given. It
+ must be a small positive integer defining the bit width of the
+ field.
+
+ Field names must be unique within one structure or union. This is
+ not checked, only one field can be accessed when names are
+ repeated.
+
+ It is possible to define the ``_fields_`` class variable *after*
+ the class statement that defines the Structure subclass, this
+ allows to create data types that directly or indirectly reference
+ themselves::
+
+ class List(Structure):
+ pass
+ List._fields_ = [("pnext", POINTER(List)),
+ ...
+ ]
+
+ The ``_fields_`` class variable must, however, be defined before
+ the type is first used (an instance is created, ``sizeof()`` is
+ called on it, and so on). Later assignments to the ``_fields_``
+ class variable will raise an AttributeError.
+
+ Structure and union subclass constructors accept both positional
+ and named arguments. Positional arguments are used to initialize
+ the fields in the same order as they appear in the ``_fields_``
+ definition, named arguments are used to initialize the fields with
+ the corresponding name.
+
+ It is possible to defined sub-subclasses of structure types, they
+ inherit the fields of the base class plus the ``_fields_`` defined
+ in the sub-subclass, if any.
+
+
+``_pack_`` : memberdesc
+ An optional small integer that allows to override the alignment of
+ structure fields in the instance. ``_pack_`` must already be
+ defined when ``_fields_`` is assigned, otherwise it will have no
+ effect.
+
+``_anonymous_`` : memberdesc
+ An optional sequence that lists the names of unnamed (anonymous)
+ fields. ``_anonymous_`` must be already defined when ``_fields_``
+ is assigned, otherwise it will have no effect.
+
+ The fields listed in this variable must be structure or union type
+ fields. ``ctypes`` will create descriptors in the structure type
+ that allows to access the nested fields directly, without the need
+ to create the structure or union field.
+
+ Here is an example type (Windows)::
+
+ class _U(Union):
+ _fields_ = [("lptdesc", POINTER(TYPEDESC)),
+ ("lpadesc", POINTER(ARRAYDESC)),
+ ("hreftype", HREFTYPE)]
+
+ class TYPEDESC(Structure):
+ _fields_ = [("u", _U),
+ ("vt", VARTYPE)]
+
+ _anonymous_ = ("u",)
+
+ The ``TYPEDESC`` structure describes a COM data type, the ``vt``
+ field specifies which one of the union fields is valid. Since the
+ ``u`` field is defined as anonymous field, it is now possible to
+ access the members directly off the TYPEDESC instance.
+ ``td.lptdesc`` and ``td.u.lptdesc`` are equivalent, but the former
+ is faster since it does not need to create a temporary ``_U``
+ instance::
+
+ td = TYPEDESC()
+ td.vt = VT_PTR
+ td.lptdesc = POINTER(some_type)
+ td.u.lptdesc = POINTER(some_type)
+
+It is possible to defined sub-subclasses of structures, they inherit
+the fields of the base class. If the subclass definition has a
+separate``_fields_`` variable, the fields specified in this are
+appended to the fields of the base class.
-``SetPointerType(pointer_class, cls)``
+Arrays and pointers
+-------------------
- Deprecated.
+XXX
Deleted: /external/ctypes/docs/manual/simple_types.txt
==============================================================================
--- /external/ctypes/docs/manual/simple_types.txt Sat Jun 10 22:08:12 2006
+++ (empty file)
@@ -1,167 +0,0 @@
-Simple types
-++++++++++++
-
-Simple types have some special behaviour: When they are accessed as
-structure or union fields, items of array instances, or as foreign
-function return values, they are transparently converted from and to
-the native Python types int, long, string, and unicode.
-
-This is *not* the case for subclasses of simple data types, so while a
-``c_void_p`` type is transparently converted from and to Python
-integer or long, a subclass of c_void_p is *not* converted. This
-allows you to define new behaviour almost completely.
-
-Class attributes of simple types
---------------------------------
-
-``__ctype_be__``, ``__ctype_le__``
-
- If the type supports different byte order (pointer types do NOT
- support this), ``__ctype_be__`` and ``__ctype_le__`` are types
- with bug endian and little endian byte order. For example,
- ``c_int.__ctype_be__`` is an integer type with the memory block in
- big endian byte order.
-
-``_type_``
-
- Implementation artifact: the typecode for this type, a single
- character string code compatible to what the ``struct`` module uses.
- Additional characters are used for types that the ``struct`` module
- does not support.
-
-
-Class methods of simple types
------------------------------
-
-(To be exact, these are not class methods, instead these are methods
-of the metaclass. The most prominent difference to classmethods is
-that you can call these methods on the class, but not on the instance
-of the simple type.)
-
-``__ctypes_from_outparam__``
-
- TBD
-
-``from_address``
-
- TBD
-
-``from_param``
-
- This class method is used to adapt function parameters. If a type
- is specified in a function's argtypes sequence, in a function call
- the ``from_param(arg)`` method will be called with the actual
- argument, and the result will be passed to the foreign function
- call as a parameter.
-
- ``from_param`` usually returns an internal object that you cannot
- use in Python code - it only makes sense to pass this object to
- foreign functions.
-
- On one hand, ``from_param`` is a performance optimization - it
- allows you to pass Python integers to function calls expecting a
- ``c_int`` argument type, without having to create a full-featured
- ``c_int`` instance.
-
- On the other hand, ``from_param`` can adapt other objects to
- parameters. XXX explain the automatic ``byref`` call for byref
- arguments.
-
-``in_dll``
-
- TBD
-
-Instance attributes of simple types
------------------------------------
-
-``value``
-
- Allows to get or set the current value of the object. For simple
- types, this is always a native Python object like integer, long,
- string, unicode, or None.
-
-``_objects`` (never modify this)
-
- Implementation artifact: a Python object keeping references to
- other objects which must be kept alive. Never modify anything on
- the returned object. XXX Should probably not be exposed.
-
-``_b_base_`` (readonly)
-
- Implementation artifact: the base object owning the memory block
- (if any).
-
-``_b_needsfree_`` (readonly)
-
- Implementation artifact: does this object have to free its memory
- block on destruction.
-
-``_as_parameter_`` (readonly)
-
- Implementation artifact (?): how to pass this object as a function
- parameter.
-
-
-Numeric types
--------------
-
-Integer types are ``c_byte``, ``c_short``, ``c_int``, ``c_long``,
-``c_longlong`` and their unsigned variants ``c_ubyte``, ``c_ushort``,
-``c_uint``, ``c_ulong`` and ``c_ulonglong``, floating point types are
-``c_float`` and ``c_double``.
-
-The constructor and the ``from_param`` class method accept a Python
-integer for integer types, a Python float for floating point types.
-
-On 32-bit platforms where sizeof(int) == sizeof(long), ``c_int`` is an
-alias for ``c_long``, on 64-bit platforms where sizeof(long) ==
-sizeof(long long), ``c_long`` is an alias for ``c_longlong``.
-
-Character types
----------------
-
-Character types are ``c_char`` and ``c_wchar``, representing the C
-``char`` and ``wchar_t`` types.
-
-The constructor and the ``from_param`` class method accept a single
-character Python string or unicode string. Conversion between string
-and unicode, if needed, is done according to the ctypes
-encoding/decoding rules.
-
-
-Pointer types
--------------
-
-The only simple pointer type is ``c_void_p``, which represents the C
-``void *`` data type. ``c_void_p`` can also be written as
-``POINTER(None)``.
-
-The constructor accepts one optional argument, which must be an
-integer or long (interpreted as an address), or ``None``.
-
-The ``from_param`` class method accepts everything that could be used
-as a pointer. XXX Should accept objects using the buffer interface as
-well.
-
-The ``value`` attribute accepts and returns None or integer.
-
-XXX Shouldn't the constructor accept the same types as from_param?
-
-
-String types
-------------
-
-ctypes has the ``c_char_p`` and ``c_wchar_p`` types which represent
-const pointers to zero terminated strings in C: ``const char *`` and
-``const wchar_t *``. Since strings and Unicode instances are
-immutable, these types should be considered readonly: do not pass them
-to functions that write into the buffer.
-
-The constructor accepts one optional argument, which must be a Python
-or unicode string, an integer, or ``None``.
-
-The ``from_param`` class method accepts a string or a Unicode string,
-as well as ``None``. Conversion between string and Unicode, if
-needed, is done according to the ctypes encoding/decoding rules.
-
-XXX Why does the constructor accept an integer, and from_param doesn't?
\ No newline at end of file
Deleted: /external/ctypes/docs/manual/struct_union.txt
==============================================================================
--- /external/ctypes/docs/manual/struct_union.txt Sat Jun 10 22:08:12 2006
+++ (empty file)
@@ -1,70 +0,0 @@
-Structure and union types
-+++++++++++++++++++++++++
-
-ctypes provides the abstract base classes ``Structure`` and ``Union``
-to define structure and union types. Subclasses must at least define
-a ``_fields_`` attribute.
-
-Defining field names and types
-------------------------------
-
-``_fields_`` must be a sequence of tuples. The first item of each
-tuple is a string specifying the name of the structure/union field.
-The second item must by a ctypes type.
-
-A descriptor will be created for each field, allowing you to access the
-field's contents from instances. Accessed from the class, the fields
-expose readonly ``.offset`` and ``.size`` attributes. ``offset`` is
-the byte-offset of the field from the beginning of the
-structure/union, ``size`` is the number of bytes the field contains.
-
-A simple example is a POINT structure containing integer fields named
-``x`` and ``y``::
-
- class Point(Structure):
- _fields_ = [("x", c_int),
- ("y", c_int)]
-
-
-
-Packing fields
---------------
-
-Normally fields are aligned in the same way as the host's C compiler
-would do it. This native alignment can be overridden by setting a
-``_pack_`` attribute in the type. It must be a small positive integer
-which is the maximum field alignment.
-
-Bit fields
-----------
-
-Integer fields support bit sizes. The bit-size must be specified as
-the third item of the ``_fields_`` tuple. Bit fields are constructed
-in the same way the host's C compiler does it. For bit fields, the
-field descriptor's ``.size`` attribute contains the number of bits in
-the high word, and the bit offset from the beginning of the structure in
-the low word. XXX is that correct?
-
-Recursive data types
---------------------
-
-To define recursive types, it is possible to assign the ``_fields_``
-value *after* the class statement. Here is an example of a linked
-list data structure, which contains a pointer to itself::
-
- class Node(Structure):
- pass
- Node._fields_ = [("next", POINTER(Node)),
- ("value", ...)]
-
-``_fields_`` must be set, and cannot be changed, after the type is
-used for the first time.
-
-Byte order
-----------
-
-It is possible to create Structure and Union types using non-native
-byte order by using the ``BigEndianStructure``,
-``LittleEndianStructure``, ``BigEndianUnion``, and
-``LittleEndianUnion`` base classes. Structures and Unions with
-non-native byte order do *not* support pointer fields.
Deleted: /external/ctypes/docs/manual/table.txt
==============================================================================
--- /external/ctypes/docs/manual/table.txt Sat Jun 10 22:08:12 2006
+++ (empty file)
@@ -1,41 +0,0 @@
- +---------------+-----------------------+-----------+
- |ctypes' type |C type |Python type|
- +===============+=======================+===========+
- |``c_char`` |``char`` |character |
- +---------------+-----------------------+-----------+
- |``c_byte`` |``char`` |integer |
- +---------------+-----------------------+-----------+
- |``c_ubyte`` |``unsigned char`` |integer |
- +---------------+-----------------------+-----------+
- |``c_short`` |``short`` |integer |
- +---------------+-----------------------+-----------+
- |``c_ushort`` |``unsigned short`` |integer |
- +---------------+-----------------------+-----------+
- |``c_int`` |``int`` |integer |
- +---------------+-----------------------+-----------+
- |``c_uint`` |``unsigned int`` |integer |
- +---------------+-----------------------+-----------+
- |``c_long`` |``long`` |integer |
- +---------------+-----------------------+-----------+
- |``c_ulong`` |``unsigned long`` |long |
- +---------------+-----------------------+-----------+
- |``c_longlong`` |``__int64`` or |long |
- | |``long long`` | |
- +---------------+-----------------------+-----------+
- |``c_ulonglong``|``unsigned __int64`` or|long |
- | |``unsigned long long`` | |
- +---------------+-----------------------+-----------+
- |``c_float`` |``float`` |float |
- +---------------+-----------------------+-----------+
- |``c_double`` |``double`` |float |
- +---------------+-----------------------+-----------+
- |``c_char_p`` |``char *`` |string or |
- | |(NUL terminated) |``None`` |
- +---------------+-----------------------+-----------+
- |``c_wchar_p`` |``wchar_t *`` |unicode or |
- | |(NUL terminated) |``None`` |
- +---------------+-----------------------+-----------+
- |``c_void_p`` |``void *`` |integer or |
- | | |``None`` |
- +---------------+-----------------------+-----------+
-
Modified: external/ctypes/docs/manual/test-tutorial.py
==============================================================================
--- external/ctypes/docs/manual/test-tutorial.py (original)
+++ external/ctypes/docs/manual/test-tutorial.py Sat Jun 10 22:08:12 2006
@@ -5,6 +5,7 @@
# handle platform specific issues
WINDOWS = doctest.register_optionflag("WINDOWS")
LINUX = doctest.register_optionflag("LINUX")
+OSX = doctest.register_optionflag("OSX")
SKIP = doctest.register_optionflag("SKIP")
# handle size specific issues
@@ -20,6 +21,8 @@
examples.remove(ex)
elif LINUX in ex.options and not sys.platform.startswith("linux"):
examples.remove(ex)
+ elif OSX in ex.options and not sys.platform.startswith("darwin"):
+ examples.remove(ex)
elif SKIP in ex.options:
examples.remove(ex)
elif "printf(" in ex.source:
@@ -38,5 +41,11 @@
doctest.DocTestRunner = MyDocTestRunner
if __name__ == "__main__":
+ # Python 2.5a2 formats exceptions differently than before, so we
+ # add IGNORE_EXCEPTION_DETAIL. I do not know if this will be
+ # fixed or not. (Is apparently fixed).
+ #
+ # ctypes may give localized error messages from the operating
+ # syetem, so we need IGNORE_EXCEPTION_DETAIL anyway.
doctest.testfile("tutorial.txt",
- optionflags=doctest.ELLIPSIS)
+ optionflags=doctest.ELLIPSIS | doctest.IGNORE_EXCEPTION_DETAIL)
Modified: external/ctypes/docs/manual/tutorial.txt
==============================================================================
--- external/ctypes/docs/manual/tutorial.txt (original)
+++ external/ctypes/docs/manual/tutorial.txt Sat Jun 10 22:08:12 2006
@@ -1,5 +1,3 @@
-``ctypes`` is a foreign function library for Python.
-
ctypes tutorial
===============
@@ -59,6 +57,12 @@
XXX Add section for Mac OS X.
+Finding shared libraries
+------------------------
+
+XXX Add description of ctypes.util.find_library (once I really
+understand it enough to describe it).
+
Accessing functions from loaded dlls
------------------------------------
@@ -168,8 +172,8 @@
Before we move on calling functions with other parameter types, we
have to learn more about ``ctypes`` data types.
-Simple data types
------------------
+Fundamental data types
+----------------------
``ctypes`` defines a number of primitive C compatible data types :
@@ -254,6 +258,7 @@
c_char_p('Hi, there')
>>> print s # first string is unchanged
Hello, World
+ >>>
You should be careful, however, not to pass them to functions
expecting pointers to mutable memory. If you need mutable memory
@@ -442,7 +447,7 @@
>>> GetModuleHandle.restype = ValidHandle # doctest: +WINDOWS
>>> GetModuleHandle(None) # doctest: +WINDOWS
486539264
- >>> GetModuleHandle("something silly") # doctest: +WINDOWS +IGNORE_EXCEPTION_DETAIL
+ >>> GetModuleHandle("something silly") # doctest: +WINDOWS
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in ValidHandle
@@ -606,6 +611,7 @@
>>>
>>> print len(MyStruct().point_array)
4
+ >>>
Instances are created in the usual way, by calling the class::
@@ -632,54 +638,64 @@
Pointers
--------
+XXX Rewrite this section. Normally one only uses indexing, not the .contents
+attribute!
+List some recipes with pointers. bool(ptr), POINTER(tp)(), ...?
+
Pointer instances are created by calling the ``pointer`` function on a
``ctypes`` type::
- >>> from ctypes import *
- >>> i = c_int(42)
- >>> pi = pointer(i)
- >>>
-
-XXX XXX Not correct: use indexing, not the contents atribute
+ >>> from ctypes import *
+ >>> i = c_int(42)
+ >>> pi = pointer(i)
+ >>>
Pointer instances have a ``contents`` attribute which returns the
-ctypes' type pointed to, the ``c_int(42)`` in the above case::
+object to which the pointer points, the ``i`` object above::
- >>> pi.contents
- c_long(42)
- >>>
+ >>> pi.contents
+ c_long(42)
+ >>>
+
+Note that ``ctypes`` does not have OOR (original object return), it
+constructs a new, equivalent object each time you retrieve an
+attribute::
+
+ >>> pi.contents is i
+ False
+ >>> pi.contents is pi.contents
+ False
+ >>>
Assigning another ``c_int`` instance to the pointer's contents
attribute would cause the pointer to point to the memory location
where this is stored::
- >>> pi.contents = c_int(99)
- >>> pi.contents
- c_long(99)
- >>>
+ >>> pi.contents = c_int(99)
+ >>> pi.contents
+ c_long(99)
+ >>>
Pointer instances can also be indexed with integers::
- >>> pi[0]
- 99
- >>>
+ >>> pi[0]
+ 99
+ >>>
-XXX What is this???
Assigning to an integer index changes the pointed to value::
- >>> i2 = pi[0]
- >>> i2
- 99
- >>> pi[0] = 22
- >>> i2
- 99
- >>>
+ >>> print i
+ c_long(99)
+ >>> pi[0] = 22
+ >>> print i
+ c_long(22)
+ >>>
It is also possible to use indexes different from 0, but you must know
-what you're doing when you use this: You access or change arbitrary
-memory locations when you do this. Generally you only use this feature
-if you receive a pointer from a C function, and you *know* that the
-pointer actually points to an array instead of a single item.
+what you're doing, just as in C: You can access or change arbitrary
+memory locations. Generally you only use this feature if you receive a
+pointer from a C function, and you *know* that the pointer actually
+points to an array instead of a single item.
Pointer classes/types
---------------------
@@ -692,7 +708,7 @@
>>> PI = POINTER(c_int)
>>> PI
<class 'ctypes.LP_c_long'>
- >>> PI(42) # doctest: +IGNORE_EXCEPTION_DETAIL
+ >>> PI(42)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: expected c_long instead of int
@@ -700,6 +716,78 @@
<ctypes.LP_c_long object at 0x...>
>>>
+Type conversions
+----------------
+
+Usually, ctypes does strict type checking. This means, if you have
+``POINTER(c_int)`` in the ``argtypes`` list of a function or in the
+``_fields_`` of a structure definition, only instances of exactly the
+same type are accepted. There are some exceptions to this rule, where
+ctypes accepts other objects. For example, you can pass compatible
+array instances instead of pointer types. So, for ``POINTER(c_int)``,
+ctypes accepts an array of c_int values::
+
+ >>> class Bar(Structure):
+ ... _fields_ = [("count", c_int), ("values", POINTER(c_int))]
+ ...
+ >>> bar = Bar()
+ >>> print bar._objects
+ None
+ >>> bar.values = (c_int * 3)(1, 2, 3)
+ >>> print bar._objects
+ {'1': ({}, <ctypes._endian.c_long_Array_3 object at ...>)}
+ >>> bar.count = 3
+ >>> for i in range(bar.count):
+ ... print bar.values[i]
+ ...
+ 1
+ 2
+ 3
+ >>>
+
+To set a POINTER type field to ``NULL``, you can assign ``None``::
+
+ >>> bar.values = None
+ >>>
+
+XXX list other conversions...
+
+Sometimes you have instances of incompatible types. In ``C``, you can
+cast one type into another type. ``ctypes`` provides a ``cast``
+function which can be used in the same way. The Bar structure defined
+above accepts ``POINTER(c_int)`` pointers or ``c_int`` arrays for its
+``values`` field, but not instances of other types::
+
+ >>> bar.values = (c_byte * 4)()
+ Traceback (most recent call last):
+ File "<stdin>", line 1, in ?
+ TypeError: incompatible types, c_byte_Array_4 instance instead of LP_c_long instance
+ >>>
+
+For these cases, the ``cast`` function is handy.
+
+The ``cast`` function can be used to cast a ctypes instance into a
+pointer to a different ctypes data type. ``cast`` takes two
+parameters, a ctypes object that is or can be converted to a pointer
+of some kind, and a ctypes pointer type. It returns an instance of
+the second argument, which references the same memory block as the
+first argument::
+
+ >>> a = (c_byte * 4)()
+ >>> cast(a, POINTER(c_int))
+ <ctypes.LP_c_long object at ...>
+ >>>
+
+So, ``cast`` can be used to assign to the ``values`` field of ``Bar``
+the structure::
+
+ >>> bar = Bar()
+ >>> bar.values = cast((c_byte * 4)(), POINTER(c_int))
+ >>> print bar.values[0]
+ 0
+ >>>
+
+
Incomplete Types
----------------
@@ -1010,6 +1098,7 @@
>>> rc.a, rc.b = rc.b, rc.a
>>> print rc.a.x, rc.a.y, rc.b.x, rc.b.y
3 4 3 4
+ >>>
Hm. We certainly expected the last statement to print ``3 4 1 2``.
What happended? Here are the steps of the ``rc.a, rc.b = rc.b, rc.a``
@@ -1018,6 +1107,7 @@
>>> temp0, temp1 = rc.b, rc.a
>>> rc.a = temp0
>>> rc.b = temp1
+ >>>
Note that ``temp0`` and ``temp1`` are objects still using the internal
buffer of the ``rc`` object above. So executing ``rc.a = temp0``
@@ -1046,6 +1136,76 @@
the object itself, instead the ``contents`` of the object is stored.
Accessing the contents again constructs a new Python each time!
+Variable-sized data types
+-------------------------
+
+``ctypes`` provides some support for variable-sized arrays and
+structures (this was added in version 0.9.9.7).
+
+The ``resize`` function can be used to resize the memory buffer of an
+existing ctypes object. The function takes the object as first
+argument, and the requested size in bytes as the second argument. The
+memory block cannot be made smaller than the natural memory block
+specified by the objects type, a ``ValueError`` is raised if this is
+tried::
+
+ >>> short_array = (c_short * 4)()
+ >>> print sizeof(short_array)
+ 8
+ >>> resize(short_array, 4)
+ Traceback (most recent call last):
+ ...
+ ValueError: minimum size is 8
+ >>> resize(short_array, 32)
+ >>> sizeof(short_array)
+ 32
+ >>> sizeof(type(short_array))
+ 8
+ >>>
+
+This is nice and fine, but how would one access the additional
+elements contained in this array? Since the type still only knows
+about 4 elements, we get errors accessing other elements::
+
+ >>> short_array[:]
+ [0, 0, 0, 0]
+ >>> short_array[7]
+ Traceback (most recent call last):
+ ...
+ IndexError: invalid index
+ >>>
+
+The solution is to use 1-element arrays; as a special case ctypes does
+no bounds checking on them::
+
+ >>> short_array = (c_short * 1)()
+ >>> print sizeof(short_array)
+ 2
+ >>> resize(short_array, 32)
+ >>> sizeof(short_array)
+ 32
+ >>> sizeof(type(short_array))
+ 2
+ >>> short_array[0:8]
+ [0, 0, 0, 0, 0, 0, 0, 0]
+ >>> short_array[7] = 42
+ >>> short_array[0:8]
+ [0, 0, 0, 0, 0, 0, 0, 42]
+ >>>
+
+Using 1-element arrays as variable sized fields in structures works as
+well, but they should be used as the last field in the structure
+definition. This example shows a definition from the Windows header
+files::
+
+ class SP_DEVICE_INTERFACE_DETAIL_DATA(Structure):
+ _fields_ = [("cbSize", c_int),
+ ("DevicePath", c_char * 1)]
+
+Another way to use variable-sized data types with ``ctypes`` is to use
+the dynamic nature of Python, and (re-)define the data type after the
+required size is already known, on a case by case basis.
+
Bugs, ToDo and non-implemented things
-------------------------------------
Deleted: /external/ctypes/docs/manual/utilities.txt
==============================================================================
--- /external/ctypes/docs/manual/utilities.txt Sat Jun 10 22:08:12 2006
+++ (empty file)
@@ -1,164 +0,0 @@
-Builtin functions
------------------
-
-``addressof(object)``
-
- Returns the address of a ctypes instance as an integer.
-
-``alignment(type_or_object)``
-
- Returns the alignment requirements in bytes of a ctypes type or
- instance.
-
-``byref(object)``
-
- Returns a light-weight pointer to a ctypes instance. The returned
- object can only be used as function call parameter. Behaves the
- same as calling ``pointer(object)``, but is a lot faster. Same as
- ``&object`` in C.
-
-``cast(object, typ)``
-
- This function is similar to the cast operator in C. Returns a new
- instance of ``type`` which shares the memory block of ``object``.
- ``typ`` must be a pointer type.
-
-``CFUNCTYPE(restype, *argtypes)``
-
- Create a function prototype using the C calling convention.
-
-
-``create_string_buffer(init, size=None)``
-
- Convenience function to create a mutable character buffer.
-
- ``init`` must be a string. If ``size`` is supplied it must be a
- positive integer that specifies the size of the buffer, otherwise
- the length of the ``init`` string is used.
- This function returns a ctypes array of characters ``c_char``.
-
-``create_unicode_buffer(init, size=None)``
-
- Convenience function to create a mutable unicode buffer.
-
- ``init`` must be a unicode string. If ``size`` is supplied it
- must be a positive integer that specifies the number of characters
- in the buffer, otherwise the length of the ``init`` string is
- used. This function returns a ctypes array of characters ``c_wchar``.
-
-
-``DllCanUnloadNow()``, ``DllGetClassObject(rclsid, riid, ppv)`` (Windows only)
-
- Functions used to implement COM servers.
-
-
-``FormatError([code])`` (Windows only)
-
- Returns a textual description of the error code, or the last error
- code set by Windows.
-
-``GetLastError()`` (Windows only)
-
- Returns the last error code set by Windows.
-
-``memmove(dst, src, count)``
-
- Same as the standard C ``memmove`` library function: copies
- ``count`` bytes from ``src`` to ``dst``. ``dst`` and ``src`` must
- be integers or anything else that can be converted into a pointer.
-
-``memset(dst, c, count)``
-
- Same as the standard C ``memset`` function. Fills the memory block
- at address ``dst`` with ``count`` bytes of value ``c``. ``dst`` must be
- an integer specifying an address, or a ctypes instance.
-
-
-``pointer(object)``
-
- This function creates a new pointer instance, pointing to the
- supplied argument which must be an instance of a ctypes type. The
- return pointer is of type ``POINTER(type(object))``. If you have
- a ctypes instance, and you want to pass the address of it to a
- function call, you should use ``byref(object)`` instead which is
- much faster.
-
- NULL pointer instances are boolean``False``, so to check for a
- NULL pointer do this::
-
- # assuming ptr is in ctypes pointer instance
- if ptr:
- print "Non-NULL pointer instance"
- else:
- print "NULL pointer instance"
-
-
-``POINTER(cls)``
-
- This factory function creates and returns a new ctypes type.
- Pointer types are cached, so calling this function is cheap.
-
- To create a ``NULL`` pointer instance, call the created type
- without an argument::
-
- null_ptr = POINTER(c_int)()
-
-
-``set_conversion_mode(encoding, errors)``
-
- This function sets the encoding/decoding rules which are used when
- ctypes has to convert between unicode and byte strings. It
- returns the previous encoding, as well as a tuple of any errors.
- If not set, default conversions are used:
- On Windows, ``msbc, ignore`` , on other systems, ``ascii, strict``.
-
-
-``sizeof(type_or_object)``
-
- Returns the size in bytes of a ctypes type or instance memory
- buffer. Does the same as the C sizeof() function.
-
-
-``string_at(addr[, size])``
-
- This function does the same as the Python ``PyString_FromString`` /
- ``PyString_FromStringAndSize`` C api functions.
-
-``WinError(code=None, descr=None)``
-
- XXX This is probably the worst named thing in ctypes!
-
- This function creates a ``WindowsError`` instance. If ``code`` is
- not specified, GetLastError() is called to determine the error
- code. If ``descr`` is not specified, ``FormatError`` is called to
- get a textual description of the error.
-
-``WINFUNCTYPE(restype, *argtypes)`` (Windows only)
-
- Create a function prototype using the __stdcall calling convention
- (on Windows), or using the C calling convention (on Windows CE).
-
-``wstring_at(addr[, size])``
-
- This function does the same as the Python ``PyUnicode_FromWideString``
- C api function. If ``size`` is not specified, ``wcslen`` is used
- to determine the string length.
-
-
-Deprecated functions
---------------------
-
-These deprecated functions are still supported for backwards
-comatibility, they should not be used for new code:
-
-``c_buffer(init, size=None)``
-
- Deprecated. Use ``create_string_buffer()`` instead.
-
-``ARRAY(cls, len)``
-
- Deprecated. Use ``cls * len`` instead.
-
-``SetPointerType(pointer_class, cls)``
-
- Deprecated.
Added: external/ctypes/docs/test-anatomy.py
==============================================================================
--- (empty file)
+++ external/ctypes/docs/test-anatomy.py Sat Jun 10 22:08:12 2006
@@ -0,0 +1,45 @@
+#!/usr/bin/env python
+import sys
+import doctest
+
+# handle platform specific issues
+WINDOWS = doctest.register_optionflag("WINDOWS")
+LINUX = doctest.register_optionflag("LINUX")
+SKIP = doctest.register_optionflag("SKIP")
+
+# handle size specific issues
+import ctypes
+c_int_name = ctypes.c_int.__name__
+
+base = doctest.DocTestRunner
+class MyDocTestRunner(base):
+ def run(self, test, compileflags=None, out=None, clear_globs=True):
+ examples = test.examples[:]
+ for ex in test.examples:
+ if WINDOWS in ex.options and sys.platform != "win32":
+ examples.remove(ex)
+ elif LINUX in ex.options and not sys.platform.startswith("linux"):
+ examples.remove(ex)
+ elif SKIP in ex.options:
+ examples.remove(ex)
+## elif "printf(" in ex.source:
+## # handle that doctest doesn't catch printf's output
+## lines = ex.want.splitlines()
+## try:
+## int(lines[-1])
+## except ValueError:
+## pass
+## else:
+## ex.want = "\n".join(lines[1:]) + "\n"
+## else:
+ ex.want = ex.want.replace("c_long", c_int_name)
+ test.examples = examples
+ return base.run(self, test, compileflags, out, clear_globs)
+doctest.DocTestRunner = MyDocTestRunner
+
+if __name__ == "__main__":
+ # Python 2.5a2 formats exceptions differently than before, so we
+ # add IGNORE_EXCEPTION_DETAIL. I do not know if this will be
+ # fixed or not.
+ doctest.testfile("anatomy.txt",
+ optionflags=doctest.ELLIPSIS | doctest.IGNORE_EXCEPTION_DETAIL)
Modified: external/ctypes/env.bat
==============================================================================
--- external/ctypes/env.bat (original)
+++ external/ctypes/env.bat Sat Jun 10 22:08:12 2006
@@ -1,2 +1,2 @@
@echo off
-for %%i in (.) do set PYTHONPATH=%%~fi
\ No newline at end of file
+for %%i in (.) do set PYTHONPATH=%%~fi;%%~fi\codegen;%%~fi\codegen\scripts
Modified: external/ctypes/setup.py
==============================================================================
--- external/ctypes/setup.py (original)
+++ external/ctypes/setup.py Sat Jun 10 22:08:12 2006
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# $Id: setup.py,v 1.140 2006/04/14 15:49:33 theller Exp $
+# $Id: setup.py,v 1.141 2006/05/19 20:06:31 theller Exp $
#
#
@@ -11,7 +11,7 @@
LIBFFI_SOURCES='source/libffi'
-__version__ = "0.9.9.6"
+__version__ = "0.9.9.7"
################################################################
Modified: external/ctypes/source/_ctypes.c
==============================================================================
--- external/ctypes/source/_ctypes.c (original)
+++ external/ctypes/source/_ctypes.c Sat Jun 10 22:08:12 2006
@@ -342,6 +342,14 @@
static PyObject *
CDataType_repeat(PyObject *self, Py_ssize_t length)
{
+ if (length < 0)
+ return PyErr_Format(PyExc_ValueError,
+#if (PY_VERSION_HEX < 0x02050000)
+ "Array length must be >= 0, not %d",
+#else
+ "Array length must be >= 0, not %zd",
+#endif
+ length);
return CreateArrayType(self, length);
}
@@ -1809,23 +1817,62 @@
}
static PyObject *
-unique_key(CDataObject *target, int index)
+unique_key(CDataObject *target, Py_ssize_t index)
{
- char string[256]; /* XXX is that enough? */
+ char string[256];
char *cp = string;
- *cp++ = index + '0';
+ size_t bytes_left;
+
+ assert(sizeof(string) - 1 > sizeof(Py_ssize_t) * 2);
+#if (PY_VERSION_HEX < 0x02050000)
+ cp += sprintf(cp, "%x", index);
+#else
+#ifdef MS_WIN32
+/* MSVC does not understand the 'z' size specifier */
+ cp += sprintf(cp, "%Ix", index);
+#else
+ cp += sprintf(cp, "%zx", index);
+#endif
+#endif
while (target->b_base) {
- *cp++ = target->b_index + '0';
+ bytes_left = sizeof(string) - (cp - string) - 1;
+ /* Hex format needs 2 characters per byte */
+ if (bytes_left < sizeof(Py_ssize_t) * 2) {
+ PyErr_SetString(PyExc_ValueError,
+ "ctypes object structure too deep");
+ return NULL;
+ }
+#if (PY_VERSION_HEX < 0x02050000)
+ cp += sprintf(cp, ":%x", (int)target->b_index);
+#else
+#ifdef MS_WIN32
+ cp += sprintf(cp, ":%Ix", (size_t)target->b_index);
+#else
+ cp += sprintf(cp, ":%zx", (size_t)target->b_index);
+#endif
+#endif
target = target->b_base;
}
return PyString_FromStringAndSize(string, cp-string);
}
-/* Keep a reference to 'keep' in the 'target', at index 'index' */
+
/*
- * KeepRef travels the target's b_base pointer down to the root,
- * building a sequence of indexes during the path. The indexes, which are a
- * couple of small integers, are used to build a byte string usable as
- * key int the root object's _objects dict.
+ * Keep a reference to 'keep' in the 'target', at index 'index'.
+ *
+ * If 'keep' is None, do nothing.
+ *
+ * Otherwise create a dictionary (if it does not yet exist) id the root
+ * objects 'b_objects' item, which will store the 'keep' object under a unique
+ * key.
+ *
+ * The unique_key helper travels the target's b_base pointer down to the root,
+ * building a string containing hex-formatted indexes found during traversal,
+ * separated by colons.
+ *
+ * The index tuple is used as a key into the root object's b_objects dict.
+ *
+ * Note: This function steals a refcount of the third argument, even if it
+ * fails!
*/
static int
KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep)
@@ -1846,6 +1893,10 @@
return 0;
}
key = unique_key(target, index);
+ if (key == NULL) {
+ Py_DECREF(keep);
+ return -1;
+ }
result = PyDict_SetItem(ob->b_objects, key, keep);
Py_DECREF(key);
Py_DECREF(keep);
@@ -2611,11 +2662,11 @@
*(void **)self->b_ptr = address;
+ Py_INCREF((PyObject *)dll); /* for KeepRef */
if (-1 == KeepRef((CDataObject *)self, 0, dll)) {
Py_DECREF((PyObject *)self);
return NULL;
}
- Py_INCREF((PyObject *)dll); /* for KeepRef above */
Py_INCREF(self);
self->callable = (PyObject *)self;
@@ -2751,11 +2802,11 @@
correctly...
*/
+ Py_INCREF((PyObject *)self); /* for KeepRef */
if (-1 == KeepRef((CDataObject *)self, 0, (PyObject *)self)) {
Py_DECREF((PyObject *)self);
return NULL;
}
- Py_INCREF((PyObject *)self); /* for KeepRef above */
return (PyObject *)self;
}
@@ -3520,7 +3571,7 @@
int offset, size;
StgDictObject *stgdict;
- if (index < 0 || index >= self->b_length) {
+ if (self->b_length == 0 || index < 0 || (self->b_length > 1 && index >= self->b_length)) {
PyErr_SetString(PyExc_IndexError,
"invalid index");
return NULL;
@@ -3549,11 +3600,11 @@
if (ilow < 0)
ilow = 0;
- else if (ilow > self->b_length)
+ else if (ilow > self->b_length && self->b_length != 1)
ilow = self->b_length;
if (ihigh < ilow)
ihigh = ilow;
- else if (ihigh > self->b_length)
+ else if (ihigh > self->b_length && self->b_length != 1)
ihigh = self->b_length;
len = ihigh - ilow;
@@ -3596,7 +3647,8 @@
}
stgdict = PyObject_stgdict((PyObject *)self);
- if (index < 0 || index >= stgdict->length) {
+ if (self->b_length == 0 || index < 0
+ || (self->b_length > 1 && index >= self->b_length)) {
PyErr_SetString(PyExc_IndexError,
"invalid index");
return -1;
@@ -3623,17 +3675,19 @@
if (ilow < 0)
ilow = 0;
- else if (ilow > self->b_length)
+ else if (ilow > self->b_length && self->b_length != 1)
ilow = self->b_length;
+
if (ihigh < 0)
ihigh = 0;
+
if (ihigh < ilow)
ihigh = ilow;
- else if (ihigh > self->b_length)
+ else if (ihigh > self->b_length && self->b_length != 1)
ihigh = self->b_length;
len = PySequence_Length(value);
- if (len != ihigh - ilow) {
+ if (self->b_length != 1 && len != ihigh - ilow) {
PyErr_SetString(PyExc_ValueError,
"Can only assign sequence of same size");
return -1;
@@ -4020,7 +4074,8 @@
Pointer_item(PyObject *_self, Py_ssize_t index)
{
CDataObject *self = (CDataObject *)_self;
- int size, offset;
+ int size;
+ Py_ssize_t offset;
StgDictObject *stgdict, *itemdict;
PyObject *proto;
@@ -4030,9 +4085,9 @@
return NULL;
}
-
stgdict = PyObject_stgdict((PyObject *)self);
assert(stgdict);
+ assert(stgdict->proto);
proto = stgdict->proto;
/* XXXXXX MAKE SURE PROTO IS NOT NULL! */
@@ -4040,7 +4095,7 @@
size = itemdict->size;
offset = index * itemdict->size;
- return CData_get(stgdict->proto, stgdict->getfunc, (PyObject *)self,
+ return CData_get(proto, stgdict->getfunc, (PyObject *)self,
index, size, (*(char **)self->b_ptr) + offset);
}
@@ -4049,7 +4104,9 @@
{
CDataObject *self = (CDataObject *)_self;
int size;
- StgDictObject *stgdict;
+ Py_ssize_t offset;
+ StgDictObject *stgdict, *itemdict;
+ PyObject *proto;
if (value == NULL) {
PyErr_SetString(PyExc_TypeError,
@@ -4064,16 +4121,17 @@
}
stgdict = PyObject_stgdict((PyObject *)self);
- if (index != 0) {
- PyErr_SetString(PyExc_IndexError,
- "invalid index");
- return -1;
- }
- size = stgdict->size / stgdict->length;
+ assert(stgdict);
+ assert(stgdict->proto);
- /* XXXXX Make sure proto is NOT NULL! */
- return CData_set((PyObject *)self, stgdict->proto, stgdict->setfunc, value,
- index, size, *(void **)self->b_ptr);
+ proto = stgdict->proto;
+ /* XXXXXX MAKE SURE PROTO IS NOT NULL! */
+ itemdict = PyType_stgdict(proto);
+ size = itemdict->size;
+ offset = index * itemdict->size;
+
+ return CData_set((PyObject *)self, proto, stgdict->setfunc, value,
+ index, size, (*(char **)self->b_ptr) + offset);
}
static PyObject *
@@ -4090,8 +4148,8 @@
stgdict = PyObject_stgdict((PyObject *)self);
assert(stgdict);
return CData_FromBaseObj(stgdict->proto,
- (PyObject *)self, 0,
- *(void **)self->b_ptr);
+ (PyObject *)self, 0,
+ *(void **)self->b_ptr);
}
static int
@@ -4439,7 +4497,7 @@
}
static PyObject *
-cast(void *ptr, PyObject *ctype)
+cast(void *ptr, PyObject *src, PyObject *ctype)
{
CDataObject *result;
if (0 == cast_check_pointertype(ctype))
@@ -4447,6 +4505,36 @@
result = (CDataObject *)PyObject_CallFunctionObjArgs(ctype, NULL);
if (result == NULL)
return NULL;
+
+ /*
+ The casted objects '_objects' member:
+
+ It must certainly contain the source objects one.
+ It must contain the source object itself.
+ */
+ if (CDataObject_Check(src)) {
+ CDataObject *obj = (CDataObject *)src;
+ /* CData_GetContainer will initialize src.b_objects, we need
+ this so it can be shared */
+ CData_GetContainer(obj);
+ /* But we need a dictionary! */
+ if (obj->b_objects == Py_None) {
+ Py_DECREF(Py_None);
+ obj->b_objects = PyDict_New();
+ }
+ Py_INCREF(obj->b_objects);
+ result->b_objects = obj->b_objects;
+ if (result->b_objects) {
+ PyObject *index = PyLong_FromVoidPtr((void *)src);
+ int rc;
+ if (index == NULL)
+ return NULL;
+ rc = PyDict_SetItem(result->b_objects, index, src);
+ Py_DECREF(index);
+ if (rc == -1)
+ return NULL;
+ }
+ }
/* Should we assert that result is a pointer type? */
memcpy(result->b_ptr, &ptr, sizeof(void *));
return (PyObject *)result;
@@ -4581,7 +4669,7 @@
#endif
PyModule_AddObject(m, "FUNCFLAG_CDECL", PyInt_FromLong(FUNCFLAG_CDECL));
PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyInt_FromLong(FUNCFLAG_PYTHONAPI));
- PyModule_AddStringConstant(m, "__version__", "0.9.9.6");
+ PyModule_AddStringConstant(m, "__version__", "0.9.9.7");
PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset));
Modified: external/ctypes/source/_ctypes_test.c
==============================================================================
--- external/ctypes/source/_ctypes_test.c (original)
+++ external/ctypes/source/_ctypes_test.c Sat Jun 10 22:08:12 2006
@@ -96,6 +96,11 @@
return dst;
}
+EXPORT(void)my_free(void *ptr)
+{
+ free(ptr);
+}
+
#ifdef HAVE_WCHAR_H
EXPORT(wchar_t *) my_wcsdup(wchar_t *src)
{
@@ -199,11 +204,6 @@
return 0;
}
-EXPORT(void) my_free(void *p)
-{
- printf("my_free got %p\n", p);
-}
-
typedef struct {
char *name;
char *value;
Modified: external/ctypes/source/callbacks.c
==============================================================================
--- external/ctypes/source/callbacks.c (original)
+++ external/ctypes/source/callbacks.c Sat Jun 10 22:08:12 2006
@@ -199,45 +199,16 @@
result = PyObject_CallObject(callable, arglist);
CHECK("'calling callback function'", result);
- if ((restype != &ffi_type_void)
- && result && result != Py_None) { /* XXX What is returned for Py_None ? */
- /* another big endian hack */
- union {
- char c;
- short s;
- int i;
- long l;
- } r;
+ if ((restype != &ffi_type_void) && result && result != Py_None) {
PyObject *keep;
assert(setfunc);
- switch (restype->size) {
- case 1:
- keep = setfunc(&r, result, 0);
- CHECK("'converting callback result'", keep);
- *(ffi_arg *)mem = r.c;
- break;
- case SIZEOF_SHORT:
- keep = setfunc(&r, result, 0);
- CHECK("'converting callback result'", keep);
- *(ffi_arg *)mem = r.s;
- break;
- case SIZEOF_INT:
- keep = setfunc(&r, result, 0);
- CHECK("'converting callback result'", keep);
- *(ffi_arg *)mem = r.i;
- break;
-#if (SIZEOF_LONG != SIZEOF_INT)
- case SIZEOF_LONG:
- keep = setfunc(&r, result, 0);
- CHECK("'converting callback result'", keep);
- *(ffi_arg *)mem = r.l;
- break;
+#ifdef WORDS_BIGENDIAN
+ /* See the corresponding code in callproc.c, around line 961 */
+ if (restype->type != FFI_TYPE_FLOAT && restype->size < sizeof(ffi_arg))
+ mem = (char *)mem + sizeof(ffi_arg) - restype->size;
#endif
- default:
- keep = setfunc(mem, result, 0);
- CHECK("'converting callback result'", keep);
- break;
- }
+ keep = setfunc(mem, result, 0);
+ CHECK("'converting callback result'", keep);
/* keep is an object we have to keep alive so that the result
stays valid. If there is no such object, the setfunc will
have returned Py_None.
Modified: external/ctypes/source/callproc.c
==============================================================================
--- external/ctypes/source/callproc.c (original)
+++ external/ctypes/source/callproc.c Sat Jun 10 22:08:12 2006
@@ -964,7 +964,14 @@
address cannot simply be used as result pointer, instead we must
adjust the pointer value:
*/
- if (rtype->size < sizeof(ffi_arg))
+ /*
+ XXX I should find out and clarify why this is needed at all,
+ especially why adjusting for ffi_type_float must be avoided on
+ 64-bit platforms.
+ */
+ if (rtype->type != FFI_TYPE_FLOAT
+ && rtype->type != FFI_TYPE_STRUCT
+ && rtype->size < sizeof(ffi_arg))
resbuf = (char *)resbuf + sizeof(ffi_arg) - rtype->size;
#endif
@@ -1437,7 +1444,64 @@
}
#endif
+static PyObject *
+resize(PyObject *self, PyObject *args)
+{
+ CDataObject *obj;
+ StgDictObject *dict;
+ Py_ssize_t size;
+
+ if (!PyArg_ParseTuple(args,
+#if (PY_VERSION_HEX < 0x02050000)
+ "Oi:resize",
+#else
+ "On:resize",
+#endif
+ (PyObject *)&obj, &size))
+ return NULL;
+
+ dict = PyObject_stgdict((PyObject *)obj);
+ if (dict == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "excepted ctypes instance");
+ return NULL;
+ }
+ if (size < dict->size) {
+ PyErr_Format(PyExc_ValueError,
+ "minimum size is %d", dict->size);
+ return NULL;
+ }
+ if (obj->b_needsfree == 0) {
+ PyErr_Format(PyExc_ValueError,
+ "Memory cannot be resized because this object doesn't own it");
+ return NULL;
+ }
+ if (size <= sizeof(obj->b_value)) {
+ /* internal default buffer is large enough */
+ obj->b_size = size;
+ goto done;
+ }
+ if (obj->b_size <= sizeof(obj->b_value)) {
+ /* We are currently using the objects default buffer, but it
+ isn't large enough any more. */
+ void *ptr = PyMem_Malloc(size);
+ if (ptr == NULL)
+ return PyErr_NoMemory();
+ memset(ptr, 0, size);
+ memmove(ptr, obj->b_ptr, obj->b_size);
+ obj->b_ptr = ptr;
+ obj->b_size = size;
+ } else {
+ obj->b_ptr = PyMem_Realloc(obj->b_ptr, size);
+ obj->b_size = size;
+ }
+ done:
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
PyMethodDef module_methods[] = {
+ {"resize", resize, METH_VARARGS, "Resize the memory buffer of a ctypes instance"},
#ifdef CTYPES_UNICODE
{"set_conversion_mode", set_conversion_mode, METH_VARARGS, set_conversion_mode_doc},
#endif
Modified: external/ctypes/source/cfield.c
==============================================================================
--- external/ctypes/source/cfield.c (original)
+++ external/ctypes/source/cfield.c Sat Jun 10 22:08:12 2006
@@ -1,5 +1,4 @@
#include "Python.h"
-#include "structmember.h"
#include <ffi.h>
#ifdef MS_WIN32
@@ -208,14 +207,30 @@
self->index, self->size, src->b_ptr + self->offset);
}
-static PyMemberDef CField_members[] = {
- { "offset", T_UINT,
- offsetof(CFieldObject, offset), READONLY,
- "offset in bytes of this field"},
- { "size", T_UINT,
- offsetof(CFieldObject, size), READONLY,
- "size in bytes of this field"},
- { NULL },
+static PyObject *
+CField_get_offset(PyObject *self, void *data)
+{
+#if (PY_VERSION_HEX < 0x02050000)
+ return PyInt_FromLong(((CFieldObject *)self)->offset);
+#else
+ return PyInt_FromSsize_t(((CFieldObject *)self)->offset);
+#endif
+}
+
+static PyObject *
+CField_get_size(PyObject *self, void *data)
+{
+#if (PY_VERSION_HEX < 0x02050000)
+ return PyInt_FromLong(((CFieldObject *)self)->size);
+#else
+ return PyInt_FromSsize_t(((CFieldObject *)self)->size);
+#endif
+}
+
+static PyGetSetDef CField_getset[] = {
+ { "offset", CField_get_offset, NULL, "offset in bytes of this field" },
+ { "size", CField_get_size, NULL, "size in bytes of this field" },
+ { NULL, NULL, NULL, NULL },
};
static int
@@ -298,8 +313,8 @@
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
- CField_members, /* tp_members */
- 0, /* tp_getset */
+ 0, /* tp_members */
+ CField_getset, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
(descrgetfunc)CField_get, /* tp_descr_get */
Modified: external/ctypes/source/ctypes.h
==============================================================================
--- external/ctypes/source/ctypes.h (original)
+++ external/ctypes/source/ctypes.h Sat Jun 10 22:08:12 2006
@@ -59,7 +59,7 @@
Py_ssize_t b_length; /* number of references we need */
Py_ssize_t b_index; /* index of this object into base's
b_object list */
- PyObject *b_objects; /* list of references we need to keep */
+ PyObject *b_objects; /* dictionary of references we need to keep, or Py_None */
union value b_value;
};
@@ -181,6 +181,7 @@
PyObject *proto; /* a type or NULL */
GETFUNC getfunc; /* getter function if proto is NULL */
SETFUNC setfunc; /* setter function if proto is NULL */
+ int anonymous;
} CFieldObject;
/* A subclass of PyDictObject, used as the instance dictionary of ctypes
Modified: external/ctypes/source/libffi/configure
==============================================================================
--- external/ctypes/source/libffi/configure (original)
+++ external/ctypes/source/libffi/configure Sat Jun 10 22:08:12 2006
@@ -310,7 +310,7 @@
# include <unistd.h>
#endif"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC ac_ct_CC EXEEXT OBJEXT CFLAGS CPP CPPFLAGS EGREP ALLOCA HAVE_LONG_DOUBLE TARGET TARGETDIR LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC ac_ct_CC EXEEXT OBJEXT CFLAGS CPP CPPFLAGS EGREP ALLOCA HAVE_LONG_DOUBLE TARGET TARGETDIR MKTARGET LIBOBJS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@@ -3483,6 +3483,7 @@
TARGETDIR="unknown"
case "$host" in
+i*86-*-darwin*) TARGET=X86_DARWIN; TARGETDIR=x86;;
i*86-*-linux*) TARGET=X86; TARGETDIR=x86;;
i*86-*-gnu*) TARGET=X86; TARGETDIR=x86;;
i*86-*-solaris2.1[0-9]*) TARGET=X86_64; TARGETDIR=x86;;
@@ -3534,6 +3535,8 @@
{ (exit 1); exit 1; }; }
fi
+MKTARGET=$TARGET
+
case x$TARGET in
xMIPS*) TARGET=MIPS ;;
*) ;;
@@ -5241,6 +5244,9 @@
esac
+
+
+
if test x$TARGET = xSPARC; then
echo "$as_me:$LINENO: checking assembler and linker support unaligned pc related relocs" >&5
echo $ECHO_N "checking assembler and linker support unaligned pc related relocs... $ECHO_C" >&6
@@ -5457,6 +5463,7 @@
+
cat >>confdefs.h <<\_ACEOF
#define FFI_NO_RAW_API 1
_ACEOF
@@ -5467,7 +5474,15 @@
ac_config_commands="$ac_config_commands src"
- ac_config_links="$ac_config_links include/ffitarget.h:src/$TARGETDIR/ffitarget.h"
+TARGETINCDIR=$TARGETDIR
+case $host in
+*-*-darwin*)
+ TARGETINCDIR="darwin"
+ ;;
+esac
+
+
+ ac_config_links="$ac_config_links include/ffitarget.h:src/$TARGETINCDIR/ffitarget.h"
ac_config_links="$ac_config_links include/ffi_common.h:include/ffi_common.h"
@@ -6014,7 +6029,7 @@
# Handling of arguments.
"include/ffi.h" ) CONFIG_FILES="$CONFIG_FILES include/ffi.h" ;;
"fficonfig.py" ) CONFIG_FILES="$CONFIG_FILES fficonfig.py" ;;
- "include/ffitarget.h" ) CONFIG_LINKS="$CONFIG_LINKS include/ffitarget.h:src/$TARGETDIR/ffitarget.h" ;;
+ "include/ffitarget.h" ) CONFIG_LINKS="$CONFIG_LINKS include/ffitarget.h:src/$TARGETINCDIR/ffitarget.h" ;;
"include/ffi_common.h" ) CONFIG_LINKS="$CONFIG_LINKS include/ffi_common.h:include/ffi_common.h" ;;
"include" ) CONFIG_COMMANDS="$CONFIG_COMMANDS include" ;;
"src" ) CONFIG_COMMANDS="$CONFIG_COMMANDS src" ;;
@@ -6129,6 +6144,7 @@
s, at HAVE_LONG_DOUBLE@,$HAVE_LONG_DOUBLE,;t t
s, at TARGET@,$TARGET,;t t
s, at TARGETDIR@,$TARGETDIR,;t t
+s, at MKTARGET@,$MKTARGET,;t t
s, at LIBOBJS@,$LIBOBJS,;t t
s, at LTLIBOBJS@,$LTLIBOBJS,;t t
CEOF
Modified: external/ctypes/source/libffi/configure.ac
==============================================================================
--- external/ctypes/source/libffi/configure.ac (original)
+++ external/ctypes/source/libffi/configure.ac Sat Jun 10 22:08:12 2006
@@ -21,6 +21,7 @@
TARGETDIR="unknown"
case "$host" in
+i*86-*-darwin*) TARGET=X86_DARWIN; TARGETDIR=x86;;
i*86-*-linux*) TARGET=X86; TARGETDIR=x86;;
i*86-*-gnu*) TARGET=X86; TARGETDIR=x86;;
i*86-*-solaris2.1[[0-9]]*) TARGET=X86_64; TARGETDIR=x86;;
@@ -70,6 +71,12 @@
AC_MSG_ERROR(["libffi has not been ported to $host."])
fi
+dnl libffi changes TARGET for MIPS to define a such macro in the header
+dnl while MIPS_IRIX or MIPS_LINUX is separatedly used to decide which
+dnl files will be compiled. So, we need to keep the original decision
+dnl of TARGET to use in fficonfig.py.in.
+MKTARGET=$TARGET
+
case x$TARGET in
xMIPS*) TARGET=MIPS ;;
*) ;;
@@ -93,6 +100,24 @@
AC_SUBST(HAVE_LONG_DOUBLE)
AC_C_BIGENDIAN
+AH_VERBATIM([WORDS_BIGENDIAN],
+[
+/* Define to 1 if your processor stores words with the most significant byte
+ first (like Motorola and SPARC, unlike Intel and VAX).
+
+ The block below does compile-time checking for endianness on platforms
+ that use GCC and therefore allows compiling fat binaries on OSX by using
+ '-arch ppc -arch i386' as the compile flags. The phrasing was choosen
+ such that the configure-result is used on systems that don't use GCC.
+*/
+#ifdef __BIG_ENDIAN__
+#define WORDS_BIGENDIAN 1
+#else
+#ifndef __LITTLE_ENDIAN__
+#undef WORDS_BIGENDIAN
+#endif
+#endif])
+
if test x$TARGET = xSPARC; then
AC_CACHE_CHECK([assembler and linker support unaligned pc related relocs],
@@ -183,6 +208,7 @@
AC_SUBST(TARGET)
AC_SUBST(TARGETDIR)
+AC_SUBST(MKTARGET)
AC_SUBST(SHELL)
@@ -194,7 +220,15 @@
test -d src/$TARGETDIR || mkdir src/$TARGETDIR
], [TARGETDIR="$TARGETDIR"])
-AC_CONFIG_LINKS(include/ffitarget.h:src/$TARGETDIR/ffitarget.h)
+TARGETINCDIR=$TARGETDIR
+case $host in
+*-*-darwin*)
+ TARGETINCDIR="darwin"
+ ;;
+esac
+
+
+AC_CONFIG_LINKS(include/ffitarget.h:src/$TARGETINCDIR/ffitarget.h)
AC_CONFIG_LINKS(include/ffi_common.h:include/ffi_common.h)
AC_CONFIG_FILES(include/ffi.h fficonfig.py)
Modified: external/ctypes/source/libffi/fficonfig.h.in
==============================================================================
--- external/ctypes/source/libffi/fficonfig.h.in (original)
+++ external/ctypes/source/libffi/fficonfig.h.in Sat Jun 10 22:08:12 2006
@@ -114,9 +114,22 @@
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
+
/* Define to 1 if your processor stores words with the most significant byte
- first (like Motorola and SPARC, unlike Intel and VAX). */
+ first (like Motorola and SPARC, unlike Intel and VAX).
+
+ The block below does compile-time checking for endianness on platforms
+ that use GCC and therefore allows compiling fat binaries on OSX by using
+ '-arch ppc -arch i386' as the compile flags. The phrasing was choosen
+ such that the configure-result is used on systems that don't use GCC.
+*/
+#ifdef __BIG_ENDIAN__
+#define WORDS_BIGENDIAN 1
+#else
+#ifndef __LITTLE_ENDIAN__
#undef WORDS_BIGENDIAN
+#endif
+#endif
#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
Modified: external/ctypes/source/libffi/fficonfig.py.in
==============================================================================
--- external/ctypes/source/libffi/fficonfig.py.in (original)
+++ external/ctypes/source/libffi/fficonfig.py.in Sat Jun 10 22:08:12 2006
@@ -6,6 +6,7 @@
'MIPS_IRIX': ['src/mips/ffi.c', 'src/mips/o32.S', 'src/mips/n32.S'],
'MIPS_LINUX': ['src/mips/ffi.c', 'src/mips/o32.S'],
'X86': ['src/x86/ffi.c', 'src/x86/sysv.S'],
+ 'X86_DARWIN': ['src/x86/ffi_darwin.c', 'src/x86/darwin.S'],
'X86_WIN32': ['src/x86/ffi.c', 'src/x86/win32.S'],
'SPARC': ['src/sparc/ffi.c', 'src/sparc/v8.S', 'src/sparc/v9.S'],
'ALPHA': ['src/alpha/ffi.c', 'src/alpha/osf.S'],
@@ -26,8 +27,19 @@
'PA': ['src/pa/linux.S', 'src/pa/ffi.c'],
}
+# Build all darwin related files on all supported darwin architectures, this
+# makes it easier to build universal binaries.
+if 1:
+ all_darwin = ('X86_DARWIN', 'POWERPC_DARWIN')
+ all_darwin_files = []
+ for pn in all_darwin:
+ all_darwin_files.extend(ffi_platforms[pn])
+ for pn in all_darwin:
+ ffi_platforms[pn] = all_darwin_files
+ del all_darwin, all_darwin_files, pn
+
ffi_srcdir = '@srcdir@'
-ffi_sources += ffi_platforms['@TARGET@']
+ffi_sources += ffi_platforms['@MKTARGET@']
ffi_sources = [os.path.join('@srcdir@', f) for f in ffi_sources]
ffi_cflags = '@CFLAGS@'
Added: external/ctypes/source/libffi/src/darwin/ffitarget.h
==============================================================================
--- (empty file)
+++ external/ctypes/source/libffi/src/darwin/ffitarget.h Sat Jun 10 22:08:12 2006
@@ -0,0 +1,25 @@
+/*
+ * This file is for MacOSX only. Dispatch to the right architecture include
+ * file based on the current archictecture (instead of relying on a symlink
+ * created by configure). This makes is possible to build a univeral binary
+ * of ctypes in one go.
+ */
+#if defined(__i386__)
+
+#ifndef X86_DARWIN
+#define X86_DARWIN
+#endif
+#undef POWERPC_DARWIN
+
+#include "../src/x86/ffitarget.h"
+
+#elif defined(__ppc__)
+
+#ifndef POWERPC_DARWIN
+#define POWERPC_DARWIN
+#endif
+#undef X86_DARWIN
+
+#include "../src/powerpc/ffitarget.h"
+
+#endif
Modified: external/ctypes/source/libffi/src/powerpc/darwin.S
==============================================================================
--- external/ctypes/source/libffi/src/powerpc/darwin.S (original)
+++ external/ctypes/source/libffi/src/powerpc/darwin.S Sat Jun 10 22:08:12 2006
@@ -1,3 +1,4 @@
+#ifdef __ppc__
/* -----------------------------------------------------------------------
darwin.S - Copyright (c) 2000 John Hornkvist
Copyright (c) 2004 Free Software Foundation, Inc.
@@ -243,3 +244,4 @@
.align LOG2_GPR_BYTES
LLFB0$non_lazy_ptr:
.g_long LFB0
+#endif
Modified: external/ctypes/source/libffi/src/powerpc/darwin_closure.S
==============================================================================
--- external/ctypes/source/libffi/src/powerpc/darwin_closure.S (original)
+++ external/ctypes/source/libffi/src/powerpc/darwin_closure.S Sat Jun 10 22:08:12 2006
@@ -1,3 +1,4 @@
+#ifdef __ppc__
/* -----------------------------------------------------------------------
darwin_closure.S - Copyright (c) 2002, 2003, 2004, Free Software Foundation,
Inc. based on ppc_closure.S
@@ -315,3 +316,4 @@
.align LOG2_GPR_BYTES
LLFB1$non_lazy_ptr:
.g_long LFB1
+#endif
Modified: external/ctypes/source/libffi/src/powerpc/ffi_darwin.c
==============================================================================
--- external/ctypes/source/libffi/src/powerpc/ffi_darwin.c (original)
+++ external/ctypes/source/libffi/src/powerpc/ffi_darwin.c Sat Jun 10 22:08:12 2006
@@ -1,3 +1,4 @@
+#ifdef __ppc__
/* -----------------------------------------------------------------------
ffi.c - Copyright (c) 1998 Geoffrey Keating
@@ -380,18 +381,18 @@
extern void ffi_call_AIX(/*@out@*/ extended_cif *,
unsigned, unsigned,
/*@out@*/ unsigned *,
- void (*fn)(),
- void (*fn2)());
+ void (*fn)(void),
+ void (*fn2)(extended_cif *, unsigned *const));
extern void ffi_call_DARWIN(/*@out@*/ extended_cif *,
unsigned, unsigned,
/*@out@*/ unsigned *,
- void (*fn)(),
- void (*fn2)());
+ void (*fn)(void),
+ void (*fn2)(extended_cif *, unsigned *const));
/*@=declundef@*/
/*@=exportheader@*/
void ffi_call(/*@dependent@*/ ffi_cif *cif,
- void (*fn)(),
+ void (*fn)(void),
/*@out@*/ void *rvalue,
/*@dependent@*/ void **avalue)
{
@@ -767,3 +768,4 @@
/* Tell ffi_closure_ASM to perform return type promotions. */
return cif->rtype->type;
}
+#endif
Modified: external/ctypes/source/libffi/src/prep_cif.c
==============================================================================
--- external/ctypes/source/libffi/src/prep_cif.c (original)
+++ external/ctypes/source/libffi/src/prep_cif.c Sat Jun 10 22:08:12 2006
@@ -55,11 +55,29 @@
/* Perform a sanity check on the argument type */
FFI_ASSERT_VALID_TYPE(*ptr);
+#ifdef POWERPC_DARWIN
+ {
+ int curalign;
+
+ curalign = (*ptr)->alignment;
+ if (ptr != &(arg->elements[0])) {
+ if (curalign > 4 && curalign != 16) {
+ curalign = 4;
+ }
+ }
+ arg->size = ALIGN(arg->size, curalign);
+ arg->size += (*ptr)->size;
+
+ arg->alignment = (arg->alignment > curalign) ?
+ arg->alignment : curalign;
+ }
+#else
arg->size = ALIGN(arg->size, (*ptr)->alignment);
arg->size += (*ptr)->size;
arg->alignment = (arg->alignment > (*ptr)->alignment) ?
arg->alignment : (*ptr)->alignment;
+#endif
ptr++;
}
@@ -89,6 +107,19 @@
/* Perform machine independent ffi_cif preparation, then call
machine dependent routine. */
+#ifdef X86_DARWIN
+static inline int struct_on_stack(int size)
+{
+ if (size > 8) return 1;
+ /* This is not what the ABI says, but is what is really implemented */
+ switch (size) {
+ case 1: case 2: case 4: case 8: return 0;
+ }
+ return 1;
+}
+#endif
+
+
ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
ffi_abi abi, unsigned int nargs,
/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype,
@@ -124,6 +155,10 @@
#ifdef SPARC
&& (cif->abi != FFI_V9 || cif->rtype->size > 32)
#endif
+#ifdef X86_DARWIN
+
+ && (struct_on_stack(cif->rtype->size))
+#endif
)
bytes = STACK_ARG_SIZE(sizeof(void*));
#endif
@@ -139,7 +174,16 @@
check after the initialization. */
FFI_ASSERT_VALID_TYPE(*ptr);
-#if !defined __x86_64__ && !defined S390 && !defined PA
+#if defined(X86_DARWIN)
+ {
+ int align = (*ptr)->alignment;
+ if (align > 4) align = 4;
+ if ((align - 1) & bytes)
+ bytes = ALIGN(bytes, align);
+ bytes += STACK_ARG_SIZE((*ptr)->size);
+ }
+
+#elif !defined __x86_64__ && !defined S390 && !defined PA
#ifdef SPARC
if (((*ptr)->type == FFI_TYPE_STRUCT
&& ((*ptr)->size > 16 || cif->abi != FFI_V9))
Added: external/ctypes/source/libffi/src/x86/darwin.S
==============================================================================
--- (empty file)
+++ external/ctypes/source/libffi/src/x86/darwin.S Sat Jun 10 22:08:12 2006
@@ -0,0 +1,390 @@
+#ifdef __i386__
+/* -----------------------------------------------------------------------
+ darwin.S - Copyright (c) 1996, 1998, 2001, 2002, 2003 Red Hat, Inc.
+
+ X86 Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+/*
+ * This file is based on sysv.S and then hacked up by Ronald who hasn't done
+ * assembly programming in 8 years.
+ */
+
+#ifndef __x86_64__
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+.text
+
+.globl _ffi_prep_args
+
+.align 4
+.globl _ffi_call_SYSV
+
+_ffi_call_SYSV:
+.LFB1:
+ pushl %ebp
+.LCFI0:
+ movl %esp,%ebp
+.LCFI1:
+ /* Make room for all of the new args. */
+ movl 16(%ebp),%ecx
+ subl %ecx,%esp
+
+ movl %esp,%eax
+
+ /* Place all of the ffi_prep_args in position */
+ pushl 12(%ebp)
+ pushl %eax
+ call *8(%ebp)
+
+ /* Return stack to previous state and call the function */
+ addl $8,%esp
+
+ call *28(%ebp)
+
+ /* Remove the space we pushed for the args */
+ movl 16(%ebp),%ecx
+ addl %ecx,%esp
+
+ /* Load %ecx with the return type code */
+ movl 20(%ebp),%ecx
+
+ /* If the return value pointer is NULL, assume no return value. */
+ cmpl $0,24(%ebp)
+ jne retint
+
+ /* Even if there is no space for the return value, we are
+ obliged to handle floating-point values. */
+ cmpl $FFI_TYPE_FLOAT,%ecx
+ jne noretval
+ fstp %st(0)
+
+ jmp epilogue
+
+retint:
+ cmpl $FFI_TYPE_INT,%ecx
+ jne retfloat
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+ jmp epilogue
+
+retfloat:
+ cmpl $FFI_TYPE_FLOAT,%ecx
+ jne retdouble
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ fstps (%ecx)
+ jmp epilogue
+
+retdouble:
+ cmpl $FFI_TYPE_DOUBLE,%ecx
+ jne retlongdouble
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ fstpl (%ecx)
+ jmp epilogue
+
+retlongdouble:
+ cmpl $FFI_TYPE_LONGDOUBLE,%ecx
+ jne retint64
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ fstpt (%ecx)
+ jmp epilogue
+
+retint64:
+ cmpl $FFI_TYPE_SINT64,%ecx
+ jne retstruct
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+ movl %edx,4(%ecx)
+
+retstruct:
+ /* Nothing to do! */
+
+noretval:
+epilogue:
+ movl %ebp,%esp
+ popl %ebp
+ ret
+.LFE1:
+.ffi_call_SYSV_end:
+#if 0
+ .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
+#endif
+
+#if 0
+ .section .eh_frame,EH_FRAME_FLAGS, at progbits
+.Lframe1:
+ .long .LECIE1-.LSCIE1 /* Length of Common Information Entry */
+.LSCIE1:
+ .long 0x0 /* CIE Identifier Tag */
+ .byte 0x1 /* CIE Version */
+#ifdef __PIC__
+ .ascii "zR\0" /* CIE Augmentation */
+#else
+ .ascii "\0" /* CIE Augmentation */
+#endif
+ .byte 0x1 /* .uleb128 0x1; CIE Code Alignment Factor */
+ .byte 0x7c /* .sleb128 -4; CIE Data Alignment Factor */
+ .byte 0x8 /* CIE RA Column */
+#ifdef __PIC__
+ .byte 0x1 /* .uleb128 0x1; Augmentation size */
+ .byte 0x1b /* FDE Encoding (pcrel sdata4) */
+#endif
+ .byte 0xc /* DW_CFA_def_cfa */
+ .byte 0x4 /* .uleb128 0x4 */
+ .byte 0x4 /* .uleb128 0x4 */
+ .byte 0x88 /* DW_CFA_offset, column 0x8 */
+ .byte 0x1 /* .uleb128 0x1 */
+ .align 4
+.LECIE1:
+.LSFDE1:
+ .long .LEFDE1-.LASFDE1 /* FDE Length */
+.LASFDE1:
+ .long .LASFDE1-.Lframe1 /* FDE CIE offset */
+#ifdef __PIC__
+ .long .LFB1-. /* FDE initial location */
+#else
+ .long .LFB1 /* FDE initial location */
+#endif
+ .long .LFE1-.LFB1 /* FDE address range */
+#ifdef __PIC__
+ .byte 0x0 /* .uleb128 0x0; Augmentation size */
+#endif
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI0-.LFB1
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .byte 0x8 /* .uleb128 0x8 */
+ .byte 0x85 /* DW_CFA_offset, column 0x5 */
+ .byte 0x2 /* .uleb128 0x2 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI1-.LCFI0
+ .byte 0xd /* DW_CFA_def_cfa_register */
+ .byte 0x5 /* .uleb128 0x5 */
+ .align 4
+.LEFDE1:
+#endif
+
+#endif /* ifndef __x86_64__ */
+
+#endif /* defined __i386__ */
+#ifdef __i386__
+/* -----------------------------------------------------------------------
+ darwin.S - Copyright (c) 1996, 1998, 2001, 2002, 2003 Red Hat, Inc.
+
+ X86 Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+/*
+ * This file is based on sysv.S and then hacked up by Ronald who hasn't done
+ * assembly programming in 8 years.
+ */
+
+#ifndef __x86_64__
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+.text
+
+.globl _ffi_prep_args
+
+.align 4
+.globl _ffi_call_SYSV
+
+_ffi_call_SYSV:
+.LFB1:
+ pushl %ebp
+.LCFI0:
+ movl %esp,%ebp
+.LCFI1:
+ /* Make room for all of the new args. */
+ movl 16(%ebp),%ecx
+ subl %ecx,%esp
+
+ movl %esp,%eax
+
+ /* Place all of the ffi_prep_args in position */
+ pushl 12(%ebp)
+ pushl %eax
+ call *8(%ebp)
+
+ /* Return stack to previous state and call the function */
+ addl $8,%esp
+
+ call *28(%ebp)
+
+ /* Remove the space we pushed for the args */
+ movl 16(%ebp),%ecx
+ addl %ecx,%esp
+
+ /* Load %ecx with the return type code */
+ movl 20(%ebp),%ecx
+
+ /* If the return value pointer is NULL, assume no return value. */
+ cmpl $0,24(%ebp)
+ jne retint
+
+ /* Even if there is no space for the return value, we are
+ obliged to handle floating-point values. */
+ cmpl $FFI_TYPE_FLOAT,%ecx
+ jne noretval
+ fstp %st(0)
+
+ jmp epilogue
+
+retint:
+ cmpl $FFI_TYPE_INT,%ecx
+ jne retfloat
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+ jmp epilogue
+
+retfloat:
+ cmpl $FFI_TYPE_FLOAT,%ecx
+ jne retdouble
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ fstps (%ecx)
+ jmp epilogue
+
+retdouble:
+ cmpl $FFI_TYPE_DOUBLE,%ecx
+ jne retlongdouble
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ fstpl (%ecx)
+ jmp epilogue
+
+retlongdouble:
+ cmpl $FFI_TYPE_LONGDOUBLE,%ecx
+ jne retint64
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ fstpt (%ecx)
+ jmp epilogue
+
+retint64:
+ cmpl $FFI_TYPE_SINT64,%ecx
+ jne retstruct
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+ movl %edx,4(%ecx)
+
+retstruct:
+ /* Nothing to do! */
+
+noretval:
+epilogue:
+ movl %ebp,%esp
+ popl %ebp
+ ret
+.LFE1:
+.ffi_call_SYSV_end:
+#if 0
+ .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
+#endif
+
+#if 0
+ .section .eh_frame,EH_FRAME_FLAGS, at progbits
+.Lframe1:
+ .long .LECIE1-.LSCIE1 /* Length of Common Information Entry */
+.LSCIE1:
+ .long 0x0 /* CIE Identifier Tag */
+ .byte 0x1 /* CIE Version */
+#ifdef __PIC__
+ .ascii "zR\0" /* CIE Augmentation */
+#else
+ .ascii "\0" /* CIE Augmentation */
+#endif
+ .byte 0x1 /* .uleb128 0x1; CIE Code Alignment Factor */
+ .byte 0x7c /* .sleb128 -4; CIE Data Alignment Factor */
+ .byte 0x8 /* CIE RA Column */
+#ifdef __PIC__
+ .byte 0x1 /* .uleb128 0x1; Augmentation size */
+ .byte 0x1b /* FDE Encoding (pcrel sdata4) */
+#endif
+ .byte 0xc /* DW_CFA_def_cfa */
+ .byte 0x4 /* .uleb128 0x4 */
+ .byte 0x4 /* .uleb128 0x4 */
+ .byte 0x88 /* DW_CFA_offset, column 0x8 */
+ .byte 0x1 /* .uleb128 0x1 */
+ .align 4
+.LECIE1:
+.LSFDE1:
+ .long .LEFDE1-.LASFDE1 /* FDE Length */
+.LASFDE1:
+ .long .LASFDE1-.Lframe1 /* FDE CIE offset */
+#ifdef __PIC__
+ .long .LFB1-. /* FDE initial location */
+#else
+ .long .LFB1 /* FDE initial location */
+#endif
+ .long .LFE1-.LFB1 /* FDE address range */
+#ifdef __PIC__
+ .byte 0x0 /* .uleb128 0x0; Augmentation size */
+#endif
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI0-.LFB1
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .byte 0x8 /* .uleb128 0x8 */
+ .byte 0x85 /* DW_CFA_offset, column 0x5 */
+ .byte 0x2 /* .uleb128 0x2 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI1-.LCFI0
+ .byte 0xd /* DW_CFA_def_cfa_register */
+ .byte 0x5 /* .uleb128 0x5 */
+ .align 4
+.LEFDE1:
+#endif
+
+#endif /* ifndef __x86_64__ */
+
+#endif /* defined __i386__ */
Added: external/ctypes/source/libffi/src/x86/ffi_darwin.c
==============================================================================
--- (empty file)
+++ external/ctypes/source/libffi/src/x86/ffi_darwin.c Sat Jun 10 22:08:12 2006
@@ -0,0 +1,610 @@
+# ifdef __i386__
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 1996, 1998, 1999, 2001 Red Hat, Inc.
+ Copyright (c) 2002 Ranjit Mathew
+ Copyright (c) 2002 Bo Thorsen
+ Copyright (c) 2002 Roger Sayle
+
+ x86 Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#ifndef __x86_64__
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack space
+ has been allocated for the function's arguments */
+
+/*@-exportheader@*/
+void ffi_prep_args(char *stack, extended_cif *ecif);
+
+static inline int retval_on_stack(ffi_type* tp)
+{
+ if (tp->type == FFI_TYPE_STRUCT) {
+ int sz = tp->size;
+ if (sz > 8) {
+ return 1;
+ }
+ switch (sz) {
+ case 1: case 2: case 4: case 8: return 0;
+ default: return 1;
+ }
+ }
+ return 0;
+}
+
+
+void ffi_prep_args(char *stack, extended_cif *ecif)
+/*@=exportheader@*/
+{
+ register unsigned int i;
+ register void **p_argv;
+ register char *argp;
+ register ffi_type **p_arg;
+
+ argp = stack;
+
+ if (retval_on_stack(ecif->cif->rtype)) {
+ *(void **) argp = ecif->rvalue;
+ argp += 4;
+ }
+
+
+ p_argv = ecif->avalue;
+
+ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+ i != 0;
+ i--, p_arg++)
+ {
+ size_t z;
+
+ /* Align if necessary */
+ if ((sizeof(int) - 1) & (unsigned) argp)
+ argp = (char *) ALIGN(argp, sizeof(int));
+
+ z = (*p_arg)->size;
+ if (z < sizeof(int))
+ {
+ z = sizeof(int);
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT32:
+ *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT32:
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_STRUCT:
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+ }
+ else
+ {
+ memcpy(argp, *p_argv, z);
+ }
+ p_argv++;
+ argp += z;
+ }
+
+ return;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ /* Set the return type flag */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_VOID:
+#if !defined(X86_WIN32)
+ case FFI_TYPE_STRUCT:
+#endif
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ case FFI_TYPE_LONGDOUBLE:
+ cif->flags = (unsigned) cif->rtype->type;
+ break;
+
+ case FFI_TYPE_UINT64:
+ cif->flags = FFI_TYPE_SINT64;
+ break;
+
+#if defined X86_WIN32
+
+ case FFI_TYPE_STRUCT:
+ if (cif->rtype->size == 1)
+ {
+ cif->flags = FFI_TYPE_SINT8; /* same as char size */
+ }
+ else if (cif->rtype->size == 2)
+ {
+ cif->flags = FFI_TYPE_SINT16; /* same as short size */
+ }
+ else if (cif->rtype->size == 4)
+ {
+ cif->flags = FFI_TYPE_INT; /* same as int type */
+ }
+ else if (cif->rtype->size == 8)
+ {
+ cif->flags = FFI_TYPE_SINT64; /* same as int64 type */
+ }
+ else
+ {
+ cif->flags = FFI_TYPE_STRUCT;
+ }
+ break;
+#endif
+
+ default:
+ cif->flags = FFI_TYPE_INT;
+ break;
+ }
+
+ /* Darwin: The stack needs to be aligned to a multiple of 16 bytes */
+#if 0
+ cif->bytes = (cif->bytes + 15) & ~0xF;
+#endif
+
+ return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)(void));
+/*@=declundef@*/
+/*@=exportheader@*/
+
+#ifdef X86_WIN32
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_STDCALL(void (*)(char *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)(void));
+/*@=declundef@*/
+/*@=exportheader@*/
+#endif /* X86_WIN32 */
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ void **avalue)
+{
+ extended_cif ecif;
+ int flags;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+
+ if ((rvalue == NULL) && retval_on_stack(cif->rtype))
+ {
+ /*@-sysunrecog@*/
+ ecif.rvalue = alloca(cif->rtype->size);
+ /*@=sysunrecog@*/
+ }
+ else
+ ecif.rvalue = rvalue;
+
+ flags = cif->flags;
+ if (flags == FFI_TYPE_STRUCT) {
+ if (cif->rtype->size == 8) {
+ flags = FFI_TYPE_SINT64;
+ } else if (cif->rtype->size == 4) {
+ flags = FFI_TYPE_INT;
+ } else if (cif->rtype->size == 2) {
+ flags = FFI_TYPE_INT;
+ } else if (cif->rtype->size == 1) {
+ flags = FFI_TYPE_INT;
+ }
+ }
+
+
+ switch (cif->abi)
+ {
+ case FFI_SYSV:
+ /*@-usedef@*/
+ /* To avoid changing the assembly code make sure the size of the argument
+ * block is a multiple of 16. Then add 8 to compensate for local variables
+ * in ffi_call_SYSV.
+ */
+ ffi_call_SYSV(ffi_prep_args, &ecif, ALIGN(cif->bytes, 16) +8,
+ flags, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+#ifdef X86_WIN32
+ case FFI_STDCALL:
+ /*@-usedef@*/
+ ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+#endif /* X86_WIN32 */
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+}
+
+
+/** private members **/
+
+static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
+ void** args, ffi_cif* cif);
+static void ffi_closure_SYSV (ffi_closure *)
+ __attribute__ ((regparm(1)));
+#if !FFI_NO_RAW_API
+static void ffi_closure_raw_SYSV (ffi_raw_closure *)
+ __attribute__ ((regparm(1)));
+#endif
+
+/* This function is jumped to by the trampoline */
+
+static void
+ffi_closure_SYSV (closure)
+ ffi_closure *closure;
+{
+ // this is our return value storage
+ long double res;
+
+ // our various things...
+ ffi_cif *cif;
+ void **arg_area;
+ unsigned short rtype;
+ void *resp = (void*)&res;
+ void *args = __builtin_dwarf_cfa ();
+
+ cif = closure->cif;
+ arg_area = (void**) alloca (cif->nargs * sizeof (void*));
+
+ /* this call will initialize ARG_AREA, such that each
+ * element in that array points to the corresponding
+ * value on the stack; and if the function returns
+ * a structure, it will re-set RESP to point to the
+ * structure return address. */
+
+ ffi_prep_incoming_args_SYSV(args, (void**)&resp, arg_area, cif);
+
+ (closure->fun) (cif, resp, arg_area, closure->user_data);
+
+ rtype = cif->flags;
+
+ if (!retval_on_stack(cif->rtype) && cif->flags == FFI_TYPE_STRUCT) {
+ if (cif->rtype->size == 8) {
+ rtype = FFI_TYPE_SINT64;
+ } else {
+ rtype = FFI_TYPE_INT;
+ }
+ }
+
+ /* now, do a generic return based on the value of rtype */
+ if (rtype == FFI_TYPE_INT)
+ {
+ asm ("movl (%0),%%eax" : : "r" (resp) : "eax");
+ }
+ else if (rtype == FFI_TYPE_FLOAT)
+ {
+ asm ("flds (%0)" : : "r" (resp) : "st" );
+ }
+ else if (rtype == FFI_TYPE_DOUBLE)
+ {
+ asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" );
+ }
+ else if (rtype == FFI_TYPE_LONGDOUBLE)
+ {
+ asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" );
+ }
+ else if (rtype == FFI_TYPE_SINT64)
+ {
+ asm ("movl 0(%0),%%eax;"
+ "movl 4(%0),%%edx"
+ : : "r"(resp)
+ : "eax", "edx");
+ }
+#ifdef X86_WIN32
+ else if (rtype == FFI_TYPE_SINT8) /* 1-byte struct */
+ {
+ asm ("movsbl (%0),%%eax" : : "r" (resp) : "eax");
+ }
+ else if (rtype == FFI_TYPE_SINT16) /* 2-bytes struct */
+ {
+ asm ("movswl (%0),%%eax" : : "r" (resp) : "eax");
+ }
+#endif
+}
+
+/*@-exportheader@*/
+static void
+ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
+ void **avalue, ffi_cif *cif)
+/*@=exportheader@*/
+{
+ register unsigned int i;
+ register void **p_argv;
+ register char *argp;
+ register ffi_type **p_arg;
+
+ argp = stack;
+
+ if (retval_on_stack(cif->rtype)) {
+ *rvalue = *(void **) argp;
+ argp += 4;
+ }
+
+ p_argv = avalue;
+
+ for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
+ {
+ size_t z;
+
+ /* Align if necessary */
+ if ((sizeof(int) - 1) & (unsigned) argp) {
+ argp = (char *) ALIGN(argp, sizeof(int));
+ }
+
+ z = (*p_arg)->size;
+
+ /* because we're little endian, this is what it turns into. */
+
+ *p_argv = (void*) argp;
+
+ p_argv++;
+ argp += z;
+ }
+
+ return;
+}
+
+/* How to make a trampoline. Derived from gcc/config/i386/i386.c. */
+
+#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
+({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
+ unsigned int __fun = (unsigned int)(FUN); \
+ unsigned int __ctx = (unsigned int)(CTX); \
+ unsigned int __dis = __fun - ((unsigned int) __tramp + FFI_TRAMPOLINE_SIZE); \
+ *(unsigned char*) &__tramp[0] = 0xb8; \
+ *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
+ *(unsigned char *) &__tramp[5] = 0xe9; \
+ *(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \
+ })
+
+
+/* the cif must already be prep'ed */
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*,void*,void**,void*),
+ void *user_data)
+{
+ FFI_ASSERT (cif->abi == FFI_SYSV);
+
+ FFI_INIT_TRAMPOLINE (&closure->tramp[0], \
+ &ffi_closure_SYSV, \
+ (void*)closure);
+
+ closure->cif = cif;
+ closure->user_data = user_data;
+ closure->fun = fun;
+
+ return FFI_OK;
+}
+
+/* ------- Native raw API support -------------------------------- */
+
+#if !FFI_NO_RAW_API
+
+static void
+ffi_closure_raw_SYSV (closure)
+ ffi_raw_closure *closure;
+{
+ // this is our return value storage
+ long double res;
+
+ // our various things...
+ ffi_raw *raw_args;
+ ffi_cif *cif;
+ unsigned short rtype;
+ void *resp = (void*)&res;
+
+ /* get the cif */
+ cif = closure->cif;
+
+ /* the SYSV/X86 abi matches the RAW API exactly, well.. almost */
+ raw_args = (ffi_raw*) __builtin_dwarf_cfa ();
+
+ (closure->fun) (cif, resp, raw_args, closure->user_data);
+
+ rtype = cif->flags;
+
+ /* now, do a generic return based on the value of rtype */
+ if (rtype == FFI_TYPE_INT)
+ {
+ asm ("movl (%0),%%eax" : : "r" (resp) : "eax");
+ }
+ else if (rtype == FFI_TYPE_FLOAT)
+ {
+ asm ("flds (%0)" : : "r" (resp) : "st" );
+ }
+ else if (rtype == FFI_TYPE_DOUBLE)
+ {
+ asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" );
+ }
+ else if (rtype == FFI_TYPE_LONGDOUBLE)
+ {
+ asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" );
+ }
+ else if (rtype == FFI_TYPE_SINT64)
+ {
+ asm ("movl 0(%0),%%eax; movl 4(%0),%%edx"
+ : : "r"(resp)
+ : "eax", "edx");
+ }
+}
+
+
+
+
+ffi_status
+ffi_prep_raw_closure (ffi_raw_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+ void *user_data)
+{
+ int i;
+
+ FFI_ASSERT (cif->abi == FFI_SYSV);
+
+ // we currently don't support certain kinds of arguments for raw
+ // closures. This should be implemented by a separate assembly language
+ // routine, since it would require argument processing, something we
+ // don't do now for performance.
+
+ for (i = cif->nargs-1; i >= 0; i--)
+ {
+ FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT);
+ FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
+ }
+
+
+ FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
+ (void*)closure);
+
+ closure->cif = cif;
+ closure->user_data = user_data;
+ closure->fun = fun;
+
+ return FFI_OK;
+}
+
+static void
+ffi_prep_args_raw(char *stack, extended_cif *ecif)
+{
+ memcpy (stack, ecif->avalue, ecif->cif->bytes);
+}
+
+/* we borrow this routine from libffi (it must be changed, though, to
+ * actually call the function passed in the first argument. as of
+ * libffi-1.20, this is not the case.)
+ */
+
+extern void
+ffi_call_SYSV(void (*)(char *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)());
+
+#ifdef X86_WIN32
+extern void
+ffi_call_STDCALL(void (*)(char *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)());
+#endif /* X86_WIN32 */
+
+void
+ffi_raw_call(/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ ffi_raw *fake_avalue)
+{
+ extended_cif ecif;
+ void **avalue = (void **)fake_avalue;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+
+ if ((rvalue == NULL) && retval_on_stack(cif->rtype))
+ {
+ /*@-sysunrecog@*/
+ ecif.rvalue = alloca(cif->rtype->size);
+ /*@=sysunrecog@*/
+ }
+ else
+ ecif.rvalue = rvalue;
+
+
+ switch (cif->abi)
+ {
+ case FFI_SYSV:
+ /*@-usedef@*/
+ ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+#ifdef X86_WIN32
+ case FFI_STDCALL:
+ /*@-usedef@*/
+ ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+#endif /* X86_WIN32 */
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+}
+
+#endif
+
+#endif /* __x86_64__ */
+
+#endif /* __i386__ */
Modified: external/ctypes/source/libffi/src/x86/ffitarget.h
==============================================================================
--- external/ctypes/source/libffi/src/x86/ffitarget.h (original)
+++ external/ctypes/source/libffi/src/x86/ffitarget.h Sat Jun 10 22:08:12 2006
@@ -51,7 +51,7 @@
#endif
/* ---- Intel x86 and AMD x86-64 - */
-#if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__))
+#if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__))
FFI_SYSV,
FFI_UNIX64, /* Unix variants all use the same ABI for x86-64 */
#ifdef __i386__
Modified: external/ctypes/source/stgdict.c
==============================================================================
--- external/ctypes/source/stgdict.c (original)
+++ external/ctypes/source/stgdict.c Sat Jun 10 22:08:12 2006
@@ -142,30 +142,129 @@
return PyType_stgdict((PyObject *)self->ob_type);
}
-#if 0
-/* work in progress: anonymous structure fields */
-int
-GetFields(PyObject *desc, int *pindex, int *psize, int *poffset, int *palign, int pack);
+/* descr is the descriptor for a field marked as anonymous. Get all the
+ _fields_ descriptors from descr->proto, create new descriptors with offset
+ and index adjusted, and stuff them into type.
+ */
+static int
+MakeFields(PyObject *type, CFieldObject *descr,
+ Py_ssize_t index, Py_ssize_t offset)
+{
+ Py_ssize_t i;
+ PyObject *fields;
+ PyObject *fieldlist;
+
+ fields = PyObject_GetAttrString(descr->proto, "_fields_");
+ if (fields == NULL)
+ return -1;
+ fieldlist = PySequence_Fast(fields, "_fields_ must be a sequence");
+ Py_DECREF(fields);
+ if (fieldlist == NULL)
+ return -1;
+
+ for (i = 0; i < PySequence_Fast_GET_SIZE(fieldlist); ++i) {
+ PyObject *pair = PySequence_Fast_GET_ITEM(fieldlist, i); /* borrowed */
+ PyObject *fname, *ftype;
+ CFieldObject *fdescr;
+ CFieldObject *new_descr;
+ // Convert to PyArg_UnpackTuple...
+ if (!PyArg_ParseTuple(pair, "OO", &fname, &ftype)) {
+ Py_DECREF(fieldlist);
+ return -1;
+ }
+ fdescr = (CFieldObject *)PyObject_GetAttr(descr->proto, fname);
+ if (fdescr == NULL) {
+ Py_DECREF(fieldlist);
+ return -1;
+ }
+ if (fdescr->ob_type != &CField_Type) {
+ PyErr_SetString(PyExc_TypeError, "unexpected type");
+ Py_DECREF(fdescr);
+ Py_DECREF(fieldlist);
+ return -1;
+ }
+ if (fdescr->anonymous) {
+ int rc = MakeFields(type, fdescr,
+ index + fdescr->index,
+ offset + fdescr->offset);
+ Py_DECREF(fdescr);
+ if (rc == -1) {
+ Py_DECREF(fieldlist);
+ return -1;
+ }
+ continue;
+ }
+ new_descr = (CFieldObject *)PyObject_CallObject((PyObject *)&CField_Type, NULL);
+ assert(new_descr->ob_type == &CField_Type);
+ if (new_descr == NULL) {
+ Py_DECREF(fdescr);
+ Py_DECREF(fieldlist);
+ return -1;
+ }
+ new_descr->size = fdescr->size;
+ new_descr->offset = fdescr->offset + offset;
+ new_descr->index = fdescr->index + index;
+ new_descr->proto = fdescr->proto;
+ Py_XINCREF(new_descr->proto);
+ new_descr->getfunc = fdescr->getfunc;
+ new_descr->setfunc = fdescr->setfunc;
+
+ Py_DECREF(fdescr);
+
+ if (-1 == PyObject_SetAttr(type, fname, (PyObject *)new_descr)) {
+ Py_DECREF(fieldlist);
+ Py_DECREF(new_descr);
+ return -1;
+ }
+ Py_DECREF(new_descr);
+ }
+ Py_DECREF(fieldlist);
+ return 0;
+}
+/* Iterate over the names in the type's _anonymous_ attribute, if present,
+ */
+static int
+MakeAnonFields(PyObject *type)
{
- int i;
- PyObject *tuples = PyObject_GetAttrString(desc, "_fields_");
- if (tuples == NULL)
- return -1;
- if (!PyTuple_Check(tuples))
- return -1; /* leak */
- for (i = 0; i < PyTuple_GET_SIZE(tuples); ++i) {
- char *fname;
- PyObject *dummy;
- CFieldObject *field;
- PyObject *pair = PyTuple_GET_ITEM(tuples, i);
- if (!PyArg_ParseTuple(pair, "sO", &fname, &dummy))
- return -1; /* leak */
- field = PyObject_GetAttrString(desc, fname);
- Py_DECREF(field);
+ PyObject *anon;
+ PyObject *anon_names;
+ Py_ssize_t i;
+
+ anon = PyObject_GetAttrString(type, "_anonymous_");
+ if (anon == NULL) {
+ PyErr_Clear();
+ return 0;
}
+ anon_names = PySequence_Fast(anon, "_anonymous_ must be a sequence");
+ Py_DECREF(anon);
+ if (anon_names == NULL)
+ return -1;
+
+ for (i = 0; i < PySequence_Fast_GET_SIZE(anon_names); ++i) {
+ PyObject *fname = PySequence_Fast_GET_ITEM(anon_names, i); /* borrowed */
+ CFieldObject *descr = (CFieldObject *)PyObject_GetAttr(type, fname);
+ if (descr == NULL) {
+ Py_DECREF(anon_names);
+ return -1;
+ }
+ assert(descr->ob_type == &CField_Type);
+ descr->anonymous = 1;
+
+ /* descr is in the field descriptor. */
+ if (-1 == MakeFields(type, (CFieldObject *)descr,
+ ((CFieldObject *)descr)->index,
+ ((CFieldObject *)descr)->offset)) {
+ Py_DECREF(descr);
+ Py_DECREF(anon_names);
+ return -1;
+ }
+ Py_DECREF(descr);
+ }
+
+ Py_DECREF(anon_names);
+ return 0;
}
-#endif
/*
Retrive the (optional) _pack_ attribute from a type, the _fields_ attribute,
@@ -368,5 +467,5 @@
stgdict->size = size;
stgdict->align = total_align;
stgdict->length = len; /* ADD ffi_ofs? */
- return 0;
+ return MakeAnonFields(type);
}
More information about the Python-checkins
mailing list