summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
Diffstat (limited to 'Modules')
-rw-r--r--Modules/Setup.dist2
-rw-r--r--Modules/_codecsmodule.c18
-rw-r--r--Modules/_csv.c2
-rw-r--r--Modules/_ctypes/_ctypes.c19
-rw-r--r--Modules/_ctypes/_ctypes_test.c10
-rwxr-xr-xModules/_ctypes/libffi/configure22
-rw-r--r--Modules/_ctypes/libffi/configure.ac36
-rw-r--r--Modules/_ctypes/libffi/fficonfig.h.in15
-rw-r--r--Modules/_ctypes/libffi/fficonfig.py.in15
-rw-r--r--Modules/_ctypes/libffi/src/darwin/ffitarget.h25
-rw-r--r--Modules/_ctypes/libffi/src/powerpc/darwin.S2
-rw-r--r--Modules/_ctypes/libffi/src/powerpc/darwin_closure.S2
-rw-r--r--Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c12
-rw-r--r--Modules/_ctypes/libffi/src/prep_cif.c46
-rw-r--r--Modules/_ctypes/libffi/src/x86/darwin.S195
-rw-r--r--Modules/_ctypes/libffi/src/x86/ffi_darwin.c610
-rw-r--r--Modules/_ctypes/libffi/src/x86/ffitarget.h2
-rw-r--r--Modules/_ctypes/libffi_msvc/ffi.c85
-rw-r--r--Modules/_ctypes/libffi_msvc/ffi.h4
-rw-r--r--Modules/_ctypes/libffi_msvc/ffi_common.h19
-rw-r--r--Modules/_ctypes/libffi_msvc/ffitarget.h20
-rw-r--r--Modules/_ctypes/libffi_msvc/mingwin32.S228
-rw-r--r--Modules/_ctypes/libffi_msvc/prep_cif.c2
-rw-r--r--Modules/_ctypes/libffi_msvc/win32.S20
-rw-r--r--Modules/_elementtree.c4
-rw-r--r--Modules/_hotshot.c2
-rw-r--r--Modules/_localemodule.c5
-rw-r--r--Modules/_sqlite/adapters.c40
-rw-r--r--Modules/_sqlite/adapters.h33
-rw-r--r--Modules/_sqlite/cache.c23
-rw-r--r--Modules/_sqlite/cache.h14
-rw-r--r--Modules/_sqlite/connection.c197
-rw-r--r--Modules/_sqlite/connection.h25
-rw-r--r--Modules/_sqlite/converters.c40
-rw-r--r--Modules/_sqlite/converters.h33
-rw-r--r--Modules/_sqlite/cursor.c62
-rw-r--r--Modules/_sqlite/cursor.h2
-rw-r--r--Modules/_sqlite/microprotocols.h4
-rw-r--r--Modules/_sqlite/module.c8
-rw-r--r--Modules/_sqlite/module.h4
-rw-r--r--Modules/_sqlite/statement.c9
-rw-r--r--Modules/_sqlite/statement.h1
-rw-r--r--Modules/_sre.c8
-rw-r--r--Modules/_ssl.c6
-rw-r--r--Modules/_struct.c (renamed from Modules/structmodule.c)973
-rw-r--r--Modules/_testcapimodule.c45
-rw-r--r--Modules/_tkinter.c18
-rw-r--r--Modules/arraymodule.c6
-rw-r--r--Modules/cPickle.c10
-rw-r--r--Modules/cjkcodecs/multibytecodec.c2
-rw-r--r--Modules/datetimemodule.c7
-rw-r--r--Modules/expat/expat_config.h19
-rw-r--r--Modules/expat/xmlparse.c8
-rw-r--r--Modules/expat/xmlrole.c4
-rw-r--r--Modules/expat/xmltok.c4
-rw-r--r--Modules/fcntlmodule.c15
-rw-r--r--Modules/gcmodule.c23
-rw-r--r--Modules/grpmodule.c36
-rw-r--r--Modules/itertoolsmodule.c58
-rw-r--r--Modules/main.c2
-rw-r--r--Modules/operator.c10
-rw-r--r--Modules/parsermodule.c4
-rw-r--r--Modules/posixmodule.c653
-rw-r--r--Modules/rotatingtree.h2
-rw-r--r--Modules/selectmodule.c83
-rw-r--r--Modules/sha512module.c198
-rw-r--r--Modules/socketmodule.c504
-rw-r--r--Modules/threadmodule.c9
-rw-r--r--Modules/timemodule.c30
-rw-r--r--Modules/unicodedata.c4
-rw-r--r--Modules/zlibmodule.c106
71 files changed, 3513 insertions, 1251 deletions
diff --git a/Modules/Setup.dist b/Modules/Setup.dist
index 49c8425..1b2502d 100644
--- a/Modules/Setup.dist
+++ b/Modules/Setup.dist
@@ -167,7 +167,7 @@ GLHACK=-Dclear=__GLclear
#array arraymodule.c # array objects
#cmath cmathmodule.c # -lm # complex math library functions
#math mathmodule.c # -lm # math library functions, e.g. sin()
-#struct structmodule.c # binary structure packing/unpacking
+#_struct _struct.c # binary structure packing/unpacking
#time timemodule.c # -lm # time operations and variables
#operator operator.c # operator.add() and similar goodies
#_weakref _weakref.c # basic weak reference support
diff --git a/Modules/_codecsmodule.c b/Modules/_codecsmodule.c
index 39b443b..d8d23c4 100644
--- a/Modules/_codecsmodule.c
+++ b/Modules/_codecsmodule.c
@@ -169,7 +169,7 @@ codec_decode(PyObject *self, PyObject *args)
static
PyObject *codec_tuple(PyObject *unicode,
- int len)
+ Py_ssize_t len)
{
PyObject *v,*w;
@@ -181,7 +181,7 @@ PyObject *codec_tuple(PyObject *unicode,
return NULL;
}
PyTuple_SET_ITEM(v,0,unicode);
- w = PyInt_FromLong(len);
+ w = PyInt_FromSsize_t(len);
if (w == NULL) {
Py_DECREF(v);
return NULL;
@@ -213,7 +213,7 @@ escape_encode(PyObject *self,
PyObject *str;
const char *errors = NULL;
char *buf;
- int len;
+ Py_ssize_t len;
if (!PyArg_ParseTuple(args, "O!|z:escape_encode",
&PyString_Type, &str, &errors))
@@ -319,12 +319,11 @@ utf_16_decode(PyObject *self,
if (!PyArg_ParseTuple(args, "t#|zi:utf_16_decode",
&data, &size, &errors, &final))
return NULL;
- /* XXX Why is consumed initialized to size? mvl */
if (size < 0) {
PyErr_SetString(PyExc_ValueError, "negative argument");
return 0;
}
- consumed = size;
+ consumed = size; /* This is overwritten unless final is true. */
decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder,
final ? NULL : &consumed);
if (decoded == NULL)
@@ -348,12 +347,11 @@ utf_16_le_decode(PyObject *self,
&data, &size, &errors, &final))
return NULL;
- /* XXX Why is consumed initialized to size? mvl */
if (size < 0) {
PyErr_SetString(PyExc_ValueError, "negative argument");
return 0;
}
- consumed = size;
+ consumed = size; /* This is overwritten unless final is true. */
decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors,
&byteorder, final ? NULL : &consumed);
if (decoded == NULL)
@@ -377,12 +375,11 @@ utf_16_be_decode(PyObject *self,
if (!PyArg_ParseTuple(args, "t#|zi:utf_16_be_decode",
&data, &size, &errors, &final))
return NULL;
- /* XXX Why is consumed initialized to size? mvl */
if (size < 0) {
PyErr_SetString(PyExc_ValueError, "negative argument");
return 0;
}
- consumed = size;
+ consumed = size; /* This is overwritten unless final is true. */
decoded = PyUnicode_DecodeUTF16Stateful(data, size, errors,
&byteorder, final ? NULL : &consumed);
if (decoded == NULL)
@@ -413,12 +410,11 @@ utf_16_ex_decode(PyObject *self,
if (!PyArg_ParseTuple(args, "t#|zii:utf_16_ex_decode",
&data, &size, &errors, &byteorder, &final))
return NULL;
- /* XXX Why is consumed initialized to size? mvl */
if (size < 0) {
PyErr_SetString(PyExc_ValueError, "negative argument");
return 0;
}
- consumed = size;
+ consumed = size; /* This is overwritten unless final is true. */
unicode = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder,
final ? NULL : &consumed);
if (unicode == NULL)
diff --git a/Modules/_csv.c b/Modules/_csv.c
index 4704c16..a341eb4 100644
--- a/Modules/_csv.c
+++ b/Modules/_csv.c
@@ -1104,6 +1104,8 @@ join_append_lineterminator(WriterObj *self)
char *terminator;
terminator_len = PyString_Size(self->dialect->lineterminator);
+ if (terminator_len == -1)
+ return 0;
/* grow record buffer if necessary */
if (!join_check_rec_size(self, self->rec_len + terminator_len))
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
index e6d6aa4..eaa3ced 100644
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -1223,6 +1223,19 @@ c_void_p_from_param(PyObject *type, PyObject *value)
return value;
}
}
+/* function pointer */
+ if (CFuncPtrObject_Check(value)) {
+ PyCArgObject *parg;
+ CFuncPtrObject *func;
+ func = (CFuncPtrObject *)value;
+ parg = new_CArgObject();
+ parg->pffi_type = &ffi_type_pointer;
+ parg->tag = 'P';
+ Py_INCREF(value);
+ parg->value.p = *(void **)func->b_ptr;
+ parg->obj = value;
+ return (PyObject *)parg;
+ }
/* c_char_p, c_wchar_p */
stgd = PyObject_stgdict(value);
if (stgd && CDataObject_Check(value) && stgd->proto && PyString_Check(stgd->proto)) {
@@ -2172,7 +2185,7 @@ _CData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
only it's object list. So we create a tuple, containing
b_objects list PLUS the array itself, and return that!
*/
- return Py_BuildValue("(OO)", keep, value);
+ return PyTuple_Pack(2, keep, value);
}
PyErr_Format(PyExc_TypeError,
"incompatible types, %s instance instead of %s instance",
@@ -4405,6 +4418,8 @@ cast_check_pointertype(PyObject *arg)
if (PointerTypeObject_Check(arg))
return 1;
+ if (CFuncPtrTypeObject_Check(arg))
+ return 1;
dict = PyType_stgdict(arg);
if (dict) {
if (PyString_Check(dict->proto)
@@ -4564,7 +4579,7 @@ init_ctypes(void)
#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.4");
+ PyModule_AddStringConstant(m, "__version__", "0.9.9.6");
PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset));
diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c
index ad3b047..b10d6fe 100644
--- a/Modules/_ctypes/_ctypes_test.c
+++ b/Modules/_ctypes/_ctypes_test.c
@@ -96,6 +96,11 @@ EXPORT(char *) my_strdup(char *src)
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 @@ EXPORT(int) _testfunc_ppp(char ***p)
return 0;
}
-EXPORT(void) my_free(void *p)
-{
- printf("my_free got %p\n", p);
-}
-
typedef struct {
char *name;
char *value;
diff --git a/Modules/_ctypes/libffi/configure b/Modules/_ctypes/libffi/configure
index c1e5cd4..9fdd654 100755
--- a/Modules/_ctypes/libffi/configure
+++ b/Modules/_ctypes/libffi/configure
@@ -310,7 +310,7 @@ ac_includes_default="\
# 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 @@ fi
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 @@ echo "$as_me: error: \"libffi has not been ported to $host.\"" >&2;}
{ (exit 1); exit 1; }; }
fi
+MKTARGET=$TARGET
+
case x$TARGET in
xMIPS*) TARGET=MIPS ;;
*) ;;
@@ -5241,6 +5244,9 @@ presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
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 @@ fi
+
cat >>confdefs.h <<\_ACEOF
#define FFI_NO_RAW_API 1
_ACEOF
@@ -5467,7 +5474,15 @@ _ACEOF
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 @@ do
# 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,@ALLOCA@,$ALLOCA,;t t
s,@HAVE_LONG_DOUBLE@,$HAVE_LONG_DOUBLE,;t t
s,@TARGET@,$TARGET,;t t
s,@TARGETDIR@,$TARGETDIR,;t t
+s,@MKTARGET@,$MKTARGET,;t t
s,@LIBOBJS@,$LIBOBJS,;t t
s,@LTLIBOBJS@,$LTLIBOBJS,;t t
CEOF
diff --git a/Modules/_ctypes/libffi/configure.ac b/Modules/_ctypes/libffi/configure.ac
index c7f05d6..a0d7513 100644
--- a/Modules/_ctypes/libffi/configure.ac
+++ b/Modules/_ctypes/libffi/configure.ac
@@ -21,6 +21,7 @@ AC_FUNC_MMAP_BLACKLIST
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 @@ if test $TARGETDIR = unknown; then
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 @@ fi
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 @@ AH_BOTTOM([
AC_SUBST(TARGET)
AC_SUBST(TARGETDIR)
+AC_SUBST(MKTARGET)
AC_SUBST(SHELL)
@@ -194,7 +220,15 @@ test -d src || mkdir src
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)
diff --git a/Modules/_ctypes/libffi/fficonfig.h.in b/Modules/_ctypes/libffi/fficonfig.h.in
index 0fd2db5..bcc5a58 100644
--- a/Modules/_ctypes/libffi/fficonfig.h.in
+++ b/Modules/_ctypes/libffi/fficonfig.h.in
@@ -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
diff --git a/Modules/_ctypes/libffi/fficonfig.py.in b/Modules/_ctypes/libffi/fficonfig.py.in
index 2ed2347..3364049 100644
--- a/Modules/_ctypes/libffi/fficonfig.py.in
+++ b/Modules/_ctypes/libffi/fficonfig.py.in
@@ -6,6 +6,7 @@ ffi_platforms = {
'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,10 +27,22 @@ ffi_platforms = {
'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@'
+# I think this may no longer be needed:
if sys.platform == "openbsd3":
ffi_cflags += " -fno-stack-protector"
diff --git a/Modules/_ctypes/libffi/src/darwin/ffitarget.h b/Modules/_ctypes/libffi/src/darwin/ffitarget.h
new file mode 100644
index 0000000..2dc308a
--- /dev/null
+++ b/Modules/_ctypes/libffi/src/darwin/ffitarget.h
@@ -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
diff --git a/Modules/_ctypes/libffi/src/powerpc/darwin.S b/Modules/_ctypes/libffi/src/powerpc/darwin.S
index d8a1df5..917dc93 100644
--- a/Modules/_ctypes/libffi/src/powerpc/darwin.S
+++ b/Modules/_ctypes/libffi/src/powerpc/darwin.S
@@ -1,3 +1,4 @@
+#ifdef __ppc__
/* -----------------------------------------------------------------------
darwin.S - Copyright (c) 2000 John Hornkvist
Copyright (c) 2004 Free Software Foundation, Inc.
@@ -243,3 +244,4 @@ LEFDE1:
.align LOG2_GPR_BYTES
LLFB0$non_lazy_ptr:
.g_long LFB0
+#endif
diff --git a/Modules/_ctypes/libffi/src/powerpc/darwin_closure.S b/Modules/_ctypes/libffi/src/powerpc/darwin_closure.S
index 6d9a364..71054f5 100644
--- a/Modules/_ctypes/libffi/src/powerpc/darwin_closure.S
+++ b/Modules/_ctypes/libffi/src/powerpc/darwin_closure.S
@@ -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 @@ L_ffi_closure_helper_DARWIN$lazy_ptr:
.align LOG2_GPR_BYTES
LLFB1$non_lazy_ptr:
.g_long LFB1
+#endif
diff --git a/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c b/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c
index d758f8f..1595b00 100644
--- a/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c
+++ b/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c
@@ -1,3 +1,4 @@
+#ifdef __ppc__
/* -----------------------------------------------------------------------
ffi.c - Copyright (c) 1998 Geoffrey Keating
@@ -380,18 +381,18 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
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 @@ int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
/* Tell ffi_closure_ASM to perform return type promotions. */
return cif->rtype->type;
}
+#endif
diff --git a/Modules/_ctypes/libffi/src/prep_cif.c b/Modules/_ctypes/libffi/src/prep_cif.c
index 0faa5dd..2db65ce 100644
--- a/Modules/_ctypes/libffi/src/prep_cif.c
+++ b/Modules/_ctypes/libffi/src/prep_cif.c
@@ -55,11 +55,29 @@ static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg)
/* 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 @@ static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg)
/* 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 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
#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 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
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))
diff --git a/Modules/_ctypes/libffi/src/x86/darwin.S b/Modules/_ctypes/libffi/src/x86/darwin.S
new file mode 100644
index 0000000..c5e55b5
--- /dev/null
+++ b/Modules/_ctypes/libffi/src/x86/darwin.S
@@ -0,0 +1,195 @@
+#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,@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__ */
diff --git a/Modules/_ctypes/libffi/src/x86/ffi_darwin.c b/Modules/_ctypes/libffi/src/x86/ffi_darwin.c
new file mode 100644
index 0000000..4f82b3a
--- /dev/null
+++ b/Modules/_ctypes/libffi/src/x86/ffi_darwin.c
@@ -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__ */
diff --git a/Modules/_ctypes/libffi/src/x86/ffitarget.h b/Modules/_ctypes/libffi/src/x86/ffitarget.h
index 9500f40..8b20d3c 100644
--- a/Modules/_ctypes/libffi/src/x86/ffitarget.h
+++ b/Modules/_ctypes/libffi/src/x86/ffitarget.h
@@ -51,7 +51,7 @@ typedef enum ffi_abi {
#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__
diff --git a/Modules/_ctypes/libffi_msvc/ffi.c b/Modules/_ctypes/libffi_msvc/ffi.c
index 5c49b39..e5600b2 100644
--- a/Modules/_ctypes/libffi_msvc/ffi.c
+++ b/Modules/_ctypes/libffi_msvc/ffi.c
@@ -26,8 +26,6 @@
OTHER DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
-#ifndef __x86_64__
-
#include <ffi.h>
#include <ffi_common.h>
@@ -143,11 +141,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
/*@-declundef@*/
/*@-exportheader@*/
-#ifdef _MSC_VER
extern int
-#else
-extern void
-#endif
ffi_call_SYSV(void (*)(char *, extended_cif *),
/*@out@*/ extended_cif *,
unsigned, unsigned,
@@ -156,14 +150,9 @@ ffi_call_SYSV(void (*)(char *, extended_cif *),
/*@=declundef@*/
/*@=exportheader@*/
-#if defined(X86_WIN32) || defined(_MSC_VER)
/*@-declundef@*/
/*@-exportheader@*/
-#ifdef _MSC_VER
extern int
-#else
-extern void
-#endif
ffi_call_STDCALL(void (*)(char *, extended_cif *),
/*@out@*/ extended_cif *,
unsigned, unsigned,
@@ -171,13 +160,8 @@ ffi_call_STDCALL(void (*)(char *, extended_cif *),
void (*fn)());
/*@=declundef@*/
/*@=exportheader@*/
-#endif /* X86_WIN32 || _MSC_VER*/
-#ifdef _MSC_VER
int
-#else
-void
-#endif
ffi_call(/*@dependent@*/ ffi_cif *cif,
void (*fn)(),
/*@out@*/ void *rvalue,
@@ -206,24 +190,18 @@ ffi_call(/*@dependent@*/ ffi_cif *cif,
{
case FFI_SYSV:
/*@-usedef@*/
-#ifdef _MSC_VER
- return
-#endif
- ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes,
- cif->flags, ecif.rvalue, fn);
+ return ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
/*@=usedef@*/
break;
-#if defined(X86_WIN32) || defined(_MSC_VER)
+
case FFI_STDCALL:
/*@-usedef@*/
-#ifdef _MSC_VER
- return
-#endif
- ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes,
- cif->flags, ecif.rvalue, fn);
+ return ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
/*@=usedef@*/
break;
-#endif /* X86_WIN32 */
+
default:
FFI_ASSERT(0);
break;
@@ -236,23 +214,10 @@ ffi_call(/*@dependent@*/ ffi_cif *cif,
static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
void** args, ffi_cif* cif);
-#ifndef _MSC_VER
-static void ffi_closure_SYSV (ffi_closure *)
- __attribute__ ((regparm(1)));
-static void ffi_closure_raw_SYSV (ffi_raw_closure *)
- __attribute__ ((regparm(1)));
-#endif
-
/* This function is jumped to by the trampoline */
-#ifdef _MSC_VER
static void __fastcall
ffi_closure_SYSV (ffi_closure *closure, int *argp)
-#else
-static void
-ffi_closure_SYSV (closure)
- ffi_closure *closure;
-#endif
{
// this is our return value storage
long double res;
@@ -262,11 +227,11 @@ ffi_closure_SYSV (closure)
void **arg_area;
unsigned short rtype;
void *resp = (void*)&res;
-#ifdef _MSC_VER
+//#ifdef _MSC_VER
void *args = &argp[1];
-#else
- void *args = __builtin_dwarf_cfa ();
-#endif
+//#else
+// void *args = __builtin_dwarf_cfa ();
+//#endif
cif = closure->cif;
arg_area = (void**) alloca (cif->nargs * sizeof (void*));
@@ -390,7 +355,7 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
/* MOV EDX, ESP is 0x8b 0xd4 */
-#ifdef _MSC_VER
+//#ifdef _MSC_VER
#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX,BYTES) \
{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
@@ -407,18 +372,18 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
*(unsigned short*) &__tramp[13] = BYTES; \
}
-#else
-#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX,BYTES) \
-({ 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 */ \
- })
-#endif
+//#else
+//#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX,BYTES) \
+//({ 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 */ \
+// })
+//#endif
/* the cif must already be prep'ed */
@@ -433,10 +398,8 @@ ffi_prep_closure (ffi_closure* closure,
if (cif->abi == FFI_SYSV)
bytes = 0;
-#ifdef _MSC_VER
else if (cif->abi == FFI_STDCALL)
bytes = cif->bytes;
-#endif
else
return FFI_BAD_ABI;
@@ -450,5 +413,3 @@ ffi_prep_closure (ffi_closure* closure,
return FFI_OK;
}
-
-#endif /* __x86_64__ */
diff --git a/Modules/_ctypes/libffi_msvc/ffi.h b/Modules/_ctypes/libffi_msvc/ffi.h
index b9d31fd..203142d 100644
--- a/Modules/_ctypes/libffi_msvc/ffi.h
+++ b/Modules/_ctypes/libffi_msvc/ffi.h
@@ -272,11 +272,7 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype,
/*@dependent@*/ ffi_type **atypes);
-#ifdef _MSC_VER
int
-#else
-void
-#endif
ffi_call(/*@dependent@*/ ffi_cif *cif,
void (*fn)(),
/*@out@*/ void *rvalue,
diff --git a/Modules/_ctypes/libffi_msvc/ffi_common.h b/Modules/_ctypes/libffi_msvc/ffi_common.h
index 1b948d5..43fb83b 100644
--- a/Modules/_ctypes/libffi_msvc/ffi_common.h
+++ b/Modules/_ctypes/libffi_msvc/ffi_common.h
@@ -13,24 +13,7 @@ extern "C" {
#endif
#include <fficonfig.h>
-
-/* Do not move this. Some versions of AIX are very picky about where
- this is positioned. */
-#ifdef __GNUC__
-# define alloca __builtin_alloca
-#else
-# if HAVE_ALLOCA_H
-# include <alloca.h>
-# else
-# ifdef _AIX
- #pragma alloca
-# else
-# ifndef alloca /* predefined by HP cc +Olibcalls */
-char *alloca ();
-# endif
-# endif
-# endif
-#endif
+#include <malloc.h>
/* Check for the existence of memcpy. */
#if STDC_HEADERS
diff --git a/Modules/_ctypes/libffi_msvc/ffitarget.h b/Modules/_ctypes/libffi_msvc/ffitarget.h
index c9d95bc..57d275b 100644
--- a/Modules/_ctypes/libffi_msvc/ffitarget.h
+++ b/Modules/_ctypes/libffi_msvc/ffitarget.h
@@ -43,23 +43,21 @@ typedef enum ffi_abi {
FFI_FIRST_ABI = 0,
/* ---- Intel x86 Win32 ---------- */
-#if defined(X86_WIN32) || defined(_MSC_VER)
FFI_SYSV,
FFI_STDCALL,
/* TODO: Add fastcall support for the sake of completeness */
FFI_DEFAULT_ABI = FFI_SYSV,
-#endif
/* ---- Intel x86 and AMD 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__
- FFI_DEFAULT_ABI = FFI_SYSV,
-#else
- FFI_DEFAULT_ABI = FFI_UNIX64,
-#endif
-#endif
+/* #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__ */
+/* FFI_DEFAULT_ABI = FFI_SYSV, */
+/* #else */
+/* FFI_DEFAULT_ABI = FFI_UNIX64, */
+/* #endif */
+/* #endif */
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
} ffi_abi;
diff --git a/Modules/_ctypes/libffi_msvc/mingwin32.S b/Modules/_ctypes/libffi_msvc/mingwin32.S
new file mode 100644
index 0000000..e71f2b2
--- /dev/null
+++ b/Modules/_ctypes/libffi_msvc/mingwin32.S
@@ -0,0 +1,228 @@
+/* -----------------------------------------------------------------------
+ win32.S - Copyright (c) 1996, 1998, 2001, 2002 Red Hat, Inc.
+ Copyright (c) 2001 John Beniton
+ Copyright (c) 2002 Ranjit Mathew
+
+
+ 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.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+.text
+
+.globl ffi_prep_args
+
+ # This assumes we are using gas.
+ .balign 16
+.globl _ffi_call_SYSV
+
+_ffi_call_SYSV:
+ pushl %ebp
+ movl %esp,%ebp
+
+ # 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
+
+ # FIXME: Align the stack to a 128-bit boundary to avoid
+ # potential performance hits.
+
+ 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 $2,%ecx # Float_type
+ jne noretval
+ fstp %st(0)
+
+ jmp epilogue
+
+retint:
+ cmpl $1,%ecx # Int_type
+ 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 $2,%ecx # Float_type
+ jne retdouble
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ fstps (%ecx)
+ jmp epilogue
+
+retdouble:
+ cmpl $3,%ecx # Double_type
+ jne retlongdouble
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ fstpl (%ecx)
+ jmp epilogue
+
+retlongdouble:
+ cmpl $4,%ecx # Longdouble_type
+ jne retint64
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ fstpt (%ecx)
+ jmp epilogue
+
+retint64:
+ cmpl $12,%ecx # SINT64_type
+ 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
+
+.ffi_call_SYSV_end:
+
+ # This assumes we are using gas.
+ .balign 16
+.globl _ffi_call_STDCALL
+
+_ffi_call_STDCALL:
+ pushl %ebp
+ movl %esp,%ebp
+
+ # 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
+
+ # FIXME: Align the stack to a 128-bit boundary to avoid
+ # potential performance hits.
+
+ call *28(%ebp)
+
+ # stdcall functions pop arguments off the stack themselves
+
+ # 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 sc_retint
+
+ # Even if there is no space for the return value, we are
+ # obliged to handle floating-point values.
+ cmpl $2,%ecx # Float_type
+ jne sc_noretval
+ fstp %st(0)
+
+ jmp sc_epilogue
+
+sc_retint:
+ cmpl $1,%ecx # Int_type
+ jne sc_retfloat
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+ jmp sc_epilogue
+
+sc_retfloat:
+ cmpl $2,%ecx # Float_type
+ jne sc_retdouble
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ fstps (%ecx)
+ jmp sc_epilogue
+
+sc_retdouble:
+ cmpl $2,%ecx # Double_type
+ jne sc_retlongdouble
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ fstpl (%ecx)
+ jmp sc_epilogue
+
+sc_retlongdouble:
+ cmpl $4,%ecx # Longdouble_type
+ jne sc_retint64
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ fstpt (%ecx)
+ jmp sc_epilogue
+
+sc_retint64:
+ cmpl $12,%ecx # SINT64_Type
+ jne sc_retstruct
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+ movl %edx,4(%ecx)
+
+sc_retstruct:
+ # Nothing to do!
+
+sc_noretval:
+sc_epilogue:
+ movl %ebp,%esp
+ popl %ebp
+ ret
+
+.ffi_call_STDCALL_end:
+
diff --git a/Modules/_ctypes/libffi_msvc/prep_cif.c b/Modules/_ctypes/libffi_msvc/prep_cif.c
index 9edce2f..2650fa0 100644
--- a/Modules/_ctypes/libffi_msvc/prep_cif.c
+++ b/Modules/_ctypes/libffi_msvc/prep_cif.c
@@ -147,7 +147,7 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
else
#endif
{
-#ifndef _MSC_VER
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
/* Don't know if this is a libffi bug or not. At least on
Windows with MSVC, function call parameters are *not*
aligned in the same way as structure fields are, they are
diff --git a/Modules/_ctypes/libffi_msvc/win32.S b/Modules/_ctypes/libffi_msvc/win32.S
index 40743af..cc82ab9 100644
--- a/Modules/_ctypes/libffi_msvc/win32.S
+++ b/Modules/_ctypes/libffi_msvc/win32.S
@@ -41,7 +41,11 @@
_ffi_call_SYSV:
pushl %ebp
movl %esp,%ebp
-
+
+ #THe: save previous %esi, and store the current stack pointer in %esi
+ pushl %esi
+ movl %esp,%esi
+
# Make room for all of the new args.
movl 16(%ebp),%ecx
subl %ecx,%esp
@@ -64,7 +68,9 @@ _ffi_call_SYSV:
# Remove the space we pushed for the args
movl 16(%ebp),%ecx
addl %ecx,%esp
-
+
+ sub %esp,%esi # calculate stack pointer difference
+
# Load %ecx with the return type code
movl 20(%ebp),%ecx
@@ -125,6 +131,8 @@ retstruct:
noretval:
epilogue:
+ movl %esi,%eax # return the stack pointer detlta in %eax
+ popl %esi # restore previous %esi
movl %ebp,%esp
popl %ebp
ret
@@ -139,6 +147,10 @@ _ffi_call_STDCALL:
pushl %ebp
movl %esp,%ebp
+ #THe: save previous %esi, and store the current stack pointer in %esi
+ pushl %esi
+ movl %esp,%esi
+
# Make room for all of the new args.
movl 16(%ebp),%ecx
subl %ecx,%esp
@@ -158,6 +170,8 @@ _ffi_call_STDCALL:
call *28(%ebp)
+ sub %esp,%esi # difference in stack
+
# stdcall functions pop arguments off the stack themselves
# Load %ecx with the return type code
@@ -220,6 +234,8 @@ sc_retstruct:
sc_noretval:
sc_epilogue:
+ movl %esi,%eax # return the stack difference
+ popl %esi # restore previous %esi value
movl %ebp,%esp
popl %ebp
ret
diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c
index 7e36ea3..871aa18 100644
--- a/Modules/_elementtree.c
+++ b/Modules/_elementtree.c
@@ -327,8 +327,10 @@ element_new(PyObject* tag, PyObject* attrib)
if (attrib != Py_None) {
- if (element_new_extra(self, attrib) < 0)
+ if (element_new_extra(self, attrib) < 0) {
+ PyObject_Del(self);
return NULL;
+ }
self->extra->length = 0;
self->extra->allocated = STATIC_CHILDREN;
diff --git a/Modules/_hotshot.c b/Modules/_hotshot.c
index 2ee4eb9..3ad0a9e 100644
--- a/Modules/_hotshot.c
+++ b/Modules/_hotshot.c
@@ -1420,7 +1420,7 @@ write_header(ProfilerObject *self)
char *buffer;
char cwdbuffer[PATH_MAX];
PyObject *temp;
- int i, len;
+ Py_ssize_t i, len;
buffer = get_version_string();
if (buffer == NULL) {
diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c
index e3d1e7f..58beb5c 100644
--- a/Modules/_localemodule.c
+++ b/Modules/_localemodule.c
@@ -12,11 +12,14 @@ This software comes with no warranty. Use at your own risk.
#include "Python.h"
#include <stdio.h>
-#include <errno.h>
#include <locale.h>
#include <string.h>
#include <ctype.h>
+#ifndef DONT_HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
#ifdef HAVE_LANGINFO_H
#include <langinfo.h>
#endif
diff --git a/Modules/_sqlite/adapters.c b/Modules/_sqlite/adapters.c
deleted file mode 100644
index e6fde03..0000000
--- a/Modules/_sqlite/adapters.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/* adapters.c - default adapters
- *
- * Copyright (C) 2005 Gerhard Häring <gh@ghaering.de>
- *
- * This file is part of pysqlite.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty. In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- * claim that you wrote the original software. If you use this software
- * in a product, an acknowledgment in the product documentation would be
- * appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- * misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-#include "util.h"
-#include "module.h"
-#include "adapters.h"
-
-/* dummy, will be implemented in a later version */
-
-PyObject* adapt_date(PyObject* self, PyObject* args, PyObject* kwargs)
-{
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-PyObject* adapt_datetime(PyObject* self, PyObject* args, PyObject* kwargs)
-{
- Py_INCREF(Py_None);
- return Py_None;
-}
diff --git a/Modules/_sqlite/adapters.h b/Modules/_sqlite/adapters.h
deleted file mode 100644
index d2e8479..0000000
--- a/Modules/_sqlite/adapters.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* adapters.h - default adapters
- *
- * Copyright (C) 2005 Gerhard Häring <gh@ghaering.de>
- *
- * This file is part of pysqlite.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty. In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- * claim that you wrote the original software. If you use this software
- * in a product, an acknowledgment in the product documentation would be
- * appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- * misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-#ifndef PYSQLITE_ADAPTERS_H
-#define PYSQLITE_ADAPTERS_H
-#include "Python.h"
-#include "pythread.h"
-#include "sqlite3.h"
-
-PyObject* adapt_date(PyObject* self, PyObject* args, PyObject* kwargs);
-PyObject* adapt_datetime(PyObject* self, PyObject* args, PyObject* kwargs);
-
-#endif
diff --git a/Modules/_sqlite/cache.c b/Modules/_sqlite/cache.c
index d102e97..6962695 100644
--- a/Modules/_sqlite/cache.c
+++ b/Modules/_sqlite/cache.c
@@ -22,6 +22,7 @@
*/
#include "cache.h"
+#include <limits.h>
/* only used internally */
Node* new_node(PyObject* key, PyObject* data)
@@ -60,11 +61,11 @@ int cache_init(Cache* self, PyObject* args, PyObject* kwargs)
self->factory = NULL;
- if (!PyArg_ParseTuple(args, "O|i", &factory, &size))
- {
- return -1;
+ if (!PyArg_ParseTuple(args, "O|i", &factory, &size)) {
+ return -1;
}
+ /* minimum cache size is 5 entries */
if (size < 5) {
size = 5;
}
@@ -95,6 +96,7 @@ void cache_dealloc(Cache* self)
return;
}
+ /* iterate over all nodes and deallocate them */
node = self->first;
while (node) {
delete_node = node;
@@ -119,7 +121,14 @@ PyObject* cache_get(Cache* self, PyObject* args)
node = (Node*)PyDict_GetItem(self->mapping, key);
if (node) {
- node->count++;
+ /* an entry for this key already exists in the cache */
+
+ /* increase usage counter of the node found */
+ if (node->count < LONG_MAX) {
+ node->count++;
+ }
+
+ /* if necessary, reorder entries in the cache by swapping positions */
if (node->prev && node->count > node->prev->count) {
ptr = node->prev;
@@ -149,6 +158,10 @@ PyObject* cache_get(Cache* self, PyObject* args)
ptr->prev = node;
}
} else {
+ /* There is no entry for this key in the cache, yet. We'll insert a new
+ * entry in the cache, and make space if necessary by throwing the
+ * least used item out of the cache. */
+
if (PyDict_Size(self->mapping) == self->size) {
if (self->last) {
node = self->last;
@@ -253,7 +266,7 @@ PyObject* cache_display(Cache* self, PyObject* args)
static PyMethodDef cache_methods[] = {
{"get", (PyCFunction)cache_get, METH_O,
- PyDoc_STR("Gets an entry from the cache.")},
+ PyDoc_STR("Gets an entry from the cache or calls the factory function to produce one.")},
{"display", (PyCFunction)cache_display, METH_NOARGS,
PyDoc_STR("For debugging only.")},
{NULL, NULL}
diff --git a/Modules/_sqlite/cache.h b/Modules/_sqlite/cache.h
index 5cc16f3..1f13907 100644
--- a/Modules/_sqlite/cache.h
+++ b/Modules/_sqlite/cache.h
@@ -1,6 +1,6 @@
/* cache.h - definitions for the LRU cache
*
- * Copyright (C) 2004-2005 Gerhard Häring <gh@ghaering.de>
+ * Copyright (C) 2004-2006 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
@@ -25,6 +25,10 @@
#define PYSQLITE_CACHE_H
#include "Python.h"
+/* The LRU cache is implemented as a combination of a doubly-linked with a
+ * dictionary. The list items are of type 'Node' and the dictionary has the
+ * nodes as values. */
+
typedef struct _Node
{
PyObject_HEAD
@@ -39,10 +43,18 @@ typedef struct
{
PyObject_HEAD
int size;
+
+ /* a dictionary mapping keys to Node entries */
PyObject* mapping;
+
+ /* the factory callable */
PyObject* factory;
+
Node* first;
Node* last;
+
+ /* if set, decrement the factory function when the Cache is deallocated.
+ * this is almost always desirable, but not in the pysqlite context */
int decref_factory;
} Cache;
diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c
index 78aad37..64e43eb 100644
--- a/Modules/_sqlite/connection.c
+++ b/Modules/_sqlite/connection.c
@@ -56,6 +56,7 @@ int connection_init(Connection* self, PyObject* args, PyObject* kwargs)
self->begin_statement = NULL;
self->statement_cache = NULL;
+ self->statements = NULL;
Py_INCREF(Py_None);
self->row_factory = Py_None;
@@ -74,6 +75,9 @@ int connection_init(Connection* self, PyObject* args, PyObject* kwargs)
if (!isolation_level) {
isolation_level = PyString_FromString("");
+ if (!isolation_level) {
+ return -1;
+ }
} else {
Py_INCREF(isolation_level);
}
@@ -86,6 +90,12 @@ int connection_init(Connection* self, PyObject* args, PyObject* kwargs)
return -1;
}
+ self->statements = PyList_New(0);
+ if (!self->statements) {
+ return -1;
+ }
+ self->created_statements = 0;
+
/* By default, the Cache class INCREFs the factory in its initializer, and
* decrefs it in its deallocator method. Since this would create a circular
* reference here, we're breaking it by decrementing self, and telling the
@@ -126,6 +136,7 @@ int connection_init(Connection* self, PyObject* args, PyObject* kwargs)
return 0;
}
+/* Empty the entire statement cache of this connection */
void flush_statement_cache(Connection* self)
{
Node* node;
@@ -147,15 +158,16 @@ void flush_statement_cache(Connection* self)
void reset_all_statements(Connection* self)
{
- Node* node;
- Statement* statement;
-
- node = self->statement_cache->first;
-
- while (node) {
- statement = (Statement*)(node->data);
- (void)statement_reset(statement);
- node = node->next;
+ int i;
+ PyObject* weakref;
+ PyObject* statement;
+
+ for (i = 0; i < PyList_Size(self->statements); i++) {
+ weakref = PyList_GetItem(self->statements, i);
+ statement = PyWeakref_GetObject(weakref);
+ if (statement != Py_None) {
+ (void)statement_reset((Statement*)statement);
+ }
}
}
@@ -178,6 +190,7 @@ void connection_dealloc(Connection* self)
Py_XDECREF(self->row_factory);
Py_XDECREF(self->text_factory);
Py_XDECREF(self->collations);
+ Py_XDECREF(self->statements);
self->ob_type->tp_free((PyObject*)self);
}
@@ -391,7 +404,7 @@ void _set_result(sqlite3_context* context, PyObject* py_val)
Py_ssize_t buflen;
PyObject* stringval;
- if (PyErr_Occurred()) {
+ if ((!py_val) || PyErr_Occurred()) {
/* Errors in callbacks are ignored, and we return NULL */
PyErr_Clear();
sqlite3_result_null(context);
@@ -399,21 +412,23 @@ void _set_result(sqlite3_context* context, PyObject* py_val)
sqlite3_result_null(context);
} else if (PyInt_Check(py_val)) {
longval = PyInt_AsLong(py_val);
- /* TODO: investigate what to do with range overflows - long vs. long long */
sqlite3_result_int64(context, (PY_LONG_LONG)longval);
} else if (PyFloat_Check(py_val)) {
sqlite3_result_double(context, PyFloat_AsDouble(py_val));
} else if (PyBuffer_Check(py_val)) {
if (PyObject_AsCharBuffer(py_val, &buffer, &buflen) != 0) {
PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer");
+ } else {
+ sqlite3_result_blob(context, buffer, buflen, SQLITE_TRANSIENT);
}
- sqlite3_result_blob(context, buffer, buflen, SQLITE_TRANSIENT);
} else if (PyString_Check(py_val)) {
sqlite3_result_text(context, PyString_AsString(py_val), -1, SQLITE_TRANSIENT);
} else if (PyUnicode_Check(py_val)) {
stringval = PyUnicode_AsUTF8String(py_val);
- sqlite3_result_text(context, PyString_AsString(stringval), -1, SQLITE_TRANSIENT);
- Py_DECREF(stringval);
+ if (stringval) {
+ sqlite3_result_text(context, PyString_AsString(stringval), -1, SQLITE_TRANSIENT);
+ Py_DECREF(stringval);
+ }
} else {
/* TODO: raise error */
}
@@ -450,6 +465,7 @@ PyObject* _build_py_params(sqlite3_context *context, int argc, sqlite3_value** a
cur_py_value = PyUnicode_DecodeUTF8(val_str, strlen(val_str), NULL);
/* TODO: have a way to show errors here */
if (!cur_py_value) {
+ PyErr_Clear();
Py_INCREF(Py_None);
cur_py_value = Py_None;
}
@@ -458,10 +474,12 @@ PyObject* _build_py_params(sqlite3_context *context, int argc, sqlite3_value** a
buflen = sqlite3_value_bytes(cur_value);
cur_py_value = PyBuffer_New(buflen);
if (!cur_py_value) {
- /* TODO: error */
+ break;
}
if (PyObject_AsWriteBuffer(cur_py_value, &raw_buffer, &buflen)) {
- /* TODO: error */
+ Py_DECREF(cur_py_value);
+ cur_py_value = NULL;
+ break;
}
memcpy(raw_buffer, sqlite3_value_blob(cur_value), buflen);
break;
@@ -470,6 +488,12 @@ PyObject* _build_py_params(sqlite3_context *context, int argc, sqlite3_value** a
Py_INCREF(Py_None);
cur_py_value = Py_None;
}
+
+ if (!cur_py_value) {
+ Py_DECREF(args);
+ return NULL;
+ }
+
PyTuple_SetItem(args, i, cur_py_value);
}
@@ -481,8 +505,7 @@ void _func_callback(sqlite3_context* context, int argc, sqlite3_value** argv)
{
PyObject* args;
PyObject* py_func;
- PyObject* py_retval;
-
+ PyObject* py_retval = NULL;
PyGILState_STATE threadstate;
@@ -491,9 +514,10 @@ void _func_callback(sqlite3_context* context, int argc, sqlite3_value** argv)
py_func = (PyObject*)sqlite3_user_data(context);
args = _build_py_params(context, argc, argv);
-
- py_retval = PyObject_CallObject(py_func, args);
- Py_DECREF(args);
+ if (args) {
+ py_retval = PyObject_CallObject(py_func, args);
+ Py_DECREF(args);
+ }
_set_result(context, py_retval);
Py_XDECREF(py_retval);
@@ -504,10 +528,10 @@ void _func_callback(sqlite3_context* context, int argc, sqlite3_value** argv)
static void _step_callback(sqlite3_context *context, int argc, sqlite3_value** params)
{
PyObject* args;
- PyObject* function_result;
+ PyObject* function_result = NULL;
PyObject* aggregate_class;
PyObject** aggregate_instance;
- PyObject* stepmethod;
+ PyObject* stepmethod = NULL;
PyGILState_STATE threadstate;
@@ -520,44 +544,42 @@ static void _step_callback(sqlite3_context *context, int argc, sqlite3_value** p
if (*aggregate_instance == 0) {
*aggregate_instance = PyObject_CallFunction(aggregate_class, "");
- if (PyErr_Occurred())
- {
+ if (PyErr_Occurred()) {
PyErr_Clear();
*aggregate_instance = 0;
- PyGILState_Release(threadstate);
- return;
+ goto error;
}
}
stepmethod = PyObject_GetAttrString(*aggregate_instance, "step");
- if (!stepmethod)
- {
- PyGILState_Release(threadstate);
- return;
+ if (!stepmethod) {
+ goto error;
}
args = _build_py_params(context, argc, params);
+ if (!args) {
+ goto error;
+ }
function_result = PyObject_CallObject(stepmethod, args);
Py_DECREF(args);
- Py_DECREF(stepmethod);
- if (function_result == NULL) {
+ if (!function_result) {
PyErr_Clear();
- } else {
- Py_DECREF(function_result);
}
+error:
+ Py_XDECREF(stepmethod);
+ Py_XDECREF(function_result);
+
PyGILState_Release(threadstate);
}
void _final_callback(sqlite3_context* context)
{
- PyObject* args;
- PyObject* function_result;
+ PyObject* function_result = NULL;
PyObject** aggregate_instance;
PyObject* aggregate_class;
- PyObject* finalizemethod;
PyGILState_STATE threadstate;
@@ -570,35 +592,56 @@ void _final_callback(sqlite3_context* context)
/* this branch is executed if there was an exception in the aggregate's
* __init__ */
- PyGILState_Release(threadstate);
- return;
+ goto error;
}
- finalizemethod = PyObject_GetAttrString(*aggregate_instance, "finalize");
-
- if (!finalizemethod) {
- /*
- PyErr_SetString(ProgrammingError, "finalize method missing");
- goto error;
- */
+ function_result = PyObject_CallMethod(*aggregate_instance, "finalize", "");
+ if (!function_result) {
+ PyErr_Clear();
Py_INCREF(Py_None);
function_result = Py_None;
- } else {
- args = PyTuple_New(0);
- if (!args)
- return;
- function_result = PyObject_CallObject(finalizemethod, args);
- Py_DECREF(args);
- Py_DECREF(finalizemethod);
}
_set_result(context, function_result);
+
+error:
Py_XDECREF(*aggregate_instance);
Py_XDECREF(function_result);
PyGILState_Release(threadstate);
}
+void _drop_unused_statement_references(Connection* self)
+{
+ PyObject* new_list;
+ PyObject* weakref;
+ int i;
+
+ /* we only need to do this once in a while */
+ if (self->created_statements++ < 200) {
+ return;
+ }
+
+ self->created_statements = 0;
+
+ new_list = PyList_New(0);
+ if (!new_list) {
+ return;
+ }
+
+ for (i = 0; i < PyList_Size(self->statements); i++) {
+ weakref = PyList_GetItem(self->statements, i);
+ if (weakref != Py_None) {
+ if (PyList_Append(new_list, weakref) != 0) {
+ Py_DECREF(new_list);
+ return;
+ }
+ }
+ }
+
+ Py_DECREF(self->statements);
+ self->statements = new_list;
+}
PyObject* connection_create_function(Connection* self, PyObject* args, PyObject* kwargs)
{
@@ -617,10 +660,16 @@ PyObject* connection_create_function(Connection* self, PyObject* args, PyObject*
rc = sqlite3_create_function(self->db, name, narg, SQLITE_UTF8, (void*)func, _func_callback, NULL, NULL);
- PyDict_SetItem(self->function_pinboard, func, Py_None);
+ if (rc != SQLITE_OK) {
+ /* Workaround for SQLite bug: no error code or string is available here */
+ PyErr_SetString(OperationalError, "Error creating function");
+ return NULL;
+ } else {
+ PyDict_SetItem(self->function_pinboard, func, Py_None);
- Py_INCREF(Py_None);
- return Py_None;
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
}
PyObject* connection_create_aggregate(Connection* self, PyObject* args, PyObject* kwargs)
@@ -639,7 +688,8 @@ PyObject* connection_create_aggregate(Connection* self, PyObject* args, PyObject
rc = sqlite3_create_function(self->db, name, n_arg, SQLITE_UTF8, (void*)aggregate_class, 0, &_step_callback, &_final_callback);
if (rc != SQLITE_OK) {
- _seterror(self->db);
+ /* Workaround for SQLite bug: no error code or string is available here */
+ PyErr_SetString(OperationalError, "Error creating aggregate");
return NULL;
} else {
PyDict_SetItem(self->function_pinboard, aggregate_class, Py_None);
@@ -682,7 +732,6 @@ static PyObject* connection_get_total_changes(Connection* self, void* unused)
static int connection_set_isolation_level(Connection* self, PyObject* isolation_level)
{
- PyObject* empty;
PyObject* res;
PyObject* begin_statement;
@@ -697,15 +746,10 @@ static int connection_set_isolation_level(Connection* self, PyObject* isolation_
Py_INCREF(Py_None);
self->isolation_level = Py_None;
- empty = PyTuple_New(0);
- if (!empty) {
- return -1;
- }
- res = connection_commit(self, empty);
+ res = connection_commit(self, NULL);
if (!res) {
return -1;
}
- Py_DECREF(empty);
Py_DECREF(res);
self->inTransaction = 0;
@@ -738,12 +782,15 @@ PyObject* connection_call(Connection* self, PyObject* args, PyObject* kwargs)
{
PyObject* sql;
Statement* statement;
+ PyObject* weakref;
int rc;
if (!PyArg_ParseTuple(args, "O", &sql)) {
return NULL;
}
+ _drop_unused_statement_references(self);
+
statement = PyObject_New(Statement, &StatementType);
if (!statement) {
return NULL;
@@ -762,8 +809,24 @@ PyObject* connection_call(Connection* self, PyObject* args, PyObject* kwargs)
Py_DECREF(statement);
statement = 0;
+ } else {
+ weakref = PyWeakref_NewRef((PyObject*)statement, NULL);
+ if (!weakref) {
+ Py_DECREF(statement);
+ statement = 0;
+ goto error;
+ }
+
+ if (PyList_Append(self->statements, weakref) != 0) {
+ Py_DECREF(weakref);
+ statement = 0;
+ goto error;
+ }
+
+ Py_DECREF(weakref);
}
+error:
return (PyObject*)statement;
}
@@ -983,7 +1046,7 @@ finally:
}
static char connection_doc[] =
-PyDoc_STR("<missing docstring>");
+PyDoc_STR("SQLite database connection object.");
static PyGetSetDef connection_getset[] = {
{"isolation_level", (getter)connection_get_isolation_level, (setter)connection_set_isolation_level},
@@ -1011,7 +1074,7 @@ static PyMethodDef connection_methods[] = {
{"executescript", (PyCFunction)connection_executescript, METH_VARARGS,
PyDoc_STR("Executes a multiple SQL statements at once. Non-standard.")},
{"create_collation", (PyCFunction)connection_create_collation, METH_VARARGS,
- PyDoc_STR("Creates a collation function.")},
+ PyDoc_STR("Creates a collation function. Non-standard.")},
{NULL, NULL}
};
diff --git a/Modules/_sqlite/connection.h b/Modules/_sqlite/connection.h
index faae6e4..8f4d36e 100644
--- a/Modules/_sqlite/connection.h
+++ b/Modules/_sqlite/connection.h
@@ -1,6 +1,6 @@
/* connection.h - definitions for the connection type
*
- * Copyright (C) 2004-2005 Gerhard Häring <gh@ghaering.de>
+ * Copyright (C) 2004-2006 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
@@ -37,7 +37,12 @@ typedef struct
PyObject_HEAD
sqlite3* db;
+ /* 1 if we are currently within a transaction, i. e. if a BEGIN has been
+ * issued */
int inTransaction;
+
+ /* the type detection mode. Only 0, PARSE_DECLTYPES, PARSE_COLNAMES or a
+ * bitwise combination thereof makes sense */
int detect_types;
/* the timeout value in seconds for database locks */
@@ -54,13 +59,31 @@ typedef struct
* freed in connection destructor */
char* begin_statement;
+ /* 1 if a check should be performed for each API call if the connection is
+ * used from the same thread it was created in */
int check_same_thread;
+
+ /* thread identification of the thread the connection was created in */
long thread_ident;
Cache* statement_cache;
+ /* A list of weak references to statements used within this connection */
+ PyObject* statements;
+
+ /* a counter for how many statements were created in the connection. May be
+ * reset to 0 at certain intervals */
+ int created_statements;
+
PyObject* row_factory;
+ /* Determines how bytestrings from SQLite are converted to Python objects:
+ * - PyUnicode_Type: Python Unicode objects are constructed from UTF-8 bytestrings
+ * - OptimizedUnicode: Like before, but for ASCII data, only PyStrings are created.
+ * - PyString_Type: PyStrings are created as-is.
+ * - Any custom callable: Any object returned from the callable called with the bytestring
+ * as single parameter.
+ */
PyObject* text_factory;
/* remember references to functions/classes used in
diff --git a/Modules/_sqlite/converters.c b/Modules/_sqlite/converters.c
deleted file mode 100644
index 018063a..0000000
--- a/Modules/_sqlite/converters.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/* converters.c - default converters
- *
- * Copyright (C) 2005 Gerhard Häring <gh@ghaering.de>
- *
- * This file is part of pysqlite.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty. In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- * claim that you wrote the original software. If you use this software
- * in a product, an acknowledgment in the product documentation would be
- * appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- * misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-#include "util.h"
-#include "module.h"
-#include "adapters.h"
-
-/* dummy, will be implemented in a later version */
-
-PyObject* convert_date(PyObject* self, PyObject* args, PyObject* kwargs)
-{
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-PyObject* convert_timestamp(PyObject* self, PyObject* args, PyObject* kwargs)
-{
- Py_INCREF(Py_None);
- return Py_None;
-}
diff --git a/Modules/_sqlite/converters.h b/Modules/_sqlite/converters.h
deleted file mode 100644
index df3768a..0000000
--- a/Modules/_sqlite/converters.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* converters.h - default converters
- *
- * Copyright (C) 2005 Gerhard Häring <gh@ghaering.de>
- *
- * This file is part of pysqlite.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty. In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- * claim that you wrote the original software. If you use this software
- * in a product, an acknowledgment in the product documentation would be
- * appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- * misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-#ifndef PYSQLITE_CONVERTERS_H
-#define PYSQLITE_CONVERTERS_H
-#include "Python.h"
-#include "pythread.h"
-#include "sqlite3.h"
-
-PyObject* convert_date(PyObject* self, PyObject* args, PyObject* kwargs);
-PyObject* convert_timestamp(PyObject* self, PyObject* args, PyObject* kwargs);
-
-#endif
diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c
index c6b8c77..6ee8bea 100644
--- a/Modules/_sqlite/cursor.c
+++ b/Modules/_sqlite/cursor.c
@@ -27,8 +27,12 @@
#include "sqlitecompat.h"
/* used to decide wether to call PyInt_FromLong or PyLong_FromLongLong */
+#ifndef INT32_MIN
#define INT32_MIN (-2147483647 - 1)
+#endif
+#ifndef INT32_MAX
#define INT32_MAX 2147483647
+#endif
PyObject* cursor_iternext(Cursor *self);
@@ -157,24 +161,24 @@ int build_row_cast_map(Cursor* self)
if (self->connection->detect_types | PARSE_COLNAMES) {
colname = sqlite3_column_name(self->statement->st, i);
+ if (colname) {
+ for (pos = colname; *pos != 0; pos++) {
+ if (*pos == '[') {
+ type_start = pos + 1;
+ } else if (*pos == ']' && type_start != (const char*)-1) {
+ key = PyString_FromStringAndSize(type_start, pos - type_start);
+ if (!key) {
+ /* creating a string failed, but it is too complicated
+ * to propagate the error here, we just assume there is
+ * no converter and proceed */
+ break;
+ }
- for (pos = colname; *pos != 0; pos++) {
- if (*pos == '[') {
- type_start = pos + 1;
- } else if (*pos == ']' && type_start != (const char*)-1) {
- key = PyString_FromStringAndSize(type_start, pos - type_start);
- if (!key) {
- /* creating a string failed, but it is too complicated
- * to propagate the error here, we just assume there is
- * no converter and proceed */
+ converter = PyDict_GetItem(converters, key);
+ Py_DECREF(key);
break;
}
-
- converter = PyDict_GetItem(converters, key);
- Py_DECREF(key);
- break;
}
-
}
}
@@ -276,6 +280,7 @@ PyObject* _fetch_one_row(Cursor* self)
void* raw_buffer;
const char* val_str;
char buf[200];
+ const char* colname;
Py_BEGIN_ALLOW_THREADS
numcols = sqlite3_data_count(self->statement->st);
@@ -340,8 +345,12 @@ PyObject* _fetch_one_row(Cursor* self)
self->connection->text_factory == OptimizedUnicode ? 1 : 0);
if (!converted) {
+ colname = sqlite3_column_name(self->statement->st, i);
+ if (colname) {
+ colname = "<unknown column name>";
+ }
PyOS_snprintf(buf, sizeof(buf) - 1, "Could not decode to UTF-8 column %s with text %s",
- sqlite3_column_name(self->statement->st, i), val_str);
+ colname , val_str);
PyErr_SetString(OperationalError, buf);
}
} else if (self->connection->text_factory == (PyObject*)&PyString_Type) {
@@ -419,8 +428,7 @@ PyObject* _query_execute(Cursor* self, int multiple, PyObject* args)
} else {
/* sequence */
parameters_iter = PyObject_GetIter(second_argument);
- if (!parameters_iter)
- {
+ if (!parameters_iter) {
return NULL;
}
}
@@ -506,12 +514,7 @@ PyObject* _query_execute(Cursor* self, int multiple, PyObject* args)
/* it's a DDL statement or something similar
- we better COMMIT first so it works for all cases */
if (self->connection->inTransaction) {
- func_args = PyTuple_New(0);
- if (!func_args) {
- goto error;
- }
- result = connection_commit(self->connection, func_args);
- Py_DECREF(func_args);
+ result = connection_commit(self->connection, NULL);
if (!result) {
goto error;
}
@@ -701,7 +704,6 @@ PyObject* cursor_executescript(Cursor* self, PyObject* args)
const char* script_cstr;
sqlite3_stmt* statement;
int rc;
- PyObject* func_args;
PyObject* result;
int statement_completed = 0;
@@ -728,12 +730,7 @@ PyObject* cursor_executescript(Cursor* self, PyObject* args)
}
/* commit first */
- func_args = PyTuple_New(0);
- if (!func_args) {
- goto error;
- }
- result = connection_commit(self->connection, func_args);
- Py_DECREF(func_args);
+ result = connection_commit(self->connection, NULL);
if (!result) {
goto error;
}
@@ -977,6 +974,9 @@ static struct PyMemberDef cursor_members[] =
{NULL}
};
+static char cursor_doc[] =
+PyDoc_STR("SQLite database cursor class.");
+
PyTypeObject CursorType = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
@@ -999,7 +999,7 @@ PyTypeObject CursorType = {
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_ITER|Py_TPFLAGS_BASETYPE, /* tp_flags */
- 0, /* tp_doc */
+ cursor_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
diff --git a/Modules/_sqlite/cursor.h b/Modules/_sqlite/cursor.h
index 7f56799..831ff81 100644
--- a/Modules/_sqlite/cursor.h
+++ b/Modules/_sqlite/cursor.h
@@ -1,6 +1,6 @@
/* cursor.h - definitions for the cursor type
*
- * Copyright (C) 2004-2005 Gerhard Häring <gh@ghaering.de>
+ * Copyright (C) 2004-2006 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
diff --git a/Modules/_sqlite/microprotocols.h b/Modules/_sqlite/microprotocols.h
index d2d9b65..f601bb3 100644
--- a/Modules/_sqlite/microprotocols.h
+++ b/Modules/_sqlite/microprotocols.h
@@ -54,6 +54,6 @@ extern PyObject *microprotocols_adapt(
extern PyObject *
psyco_microprotocols_adapt(Cursor* self, PyObject *args);
#define psyco_microprotocols_adapt_doc \
- "adapt(obj, protocol, alternate) -> adapt obj to given protocol"
-
+ "adapt(obj, protocol, alternate) -> adapt obj to given protocol. Non-standard."
+
#endif /* !defined(PSYCOPG_MICROPROTOCOLS_H) */
diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c
index 1537e79..fb6eb06 100644
--- a/Modules/_sqlite/module.c
+++ b/Modules/_sqlite/module.c
@@ -167,12 +167,12 @@ void converters_init(PyObject* dict)
static PyMethodDef module_methods[] = {
{"connect", (PyCFunction)module_connect, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Creates a connection.")},
- {"complete_statement", (PyCFunction)module_complete, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Checks if a string contains a complete SQL statement.")},
+ {"complete_statement", (PyCFunction)module_complete, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Checks if a string contains a complete SQL statement. Non-standard.")},
#ifdef HAVE_SHARED_CACHE
- {"enable_shared_cache", (PyCFunction)module_enable_shared_cache, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Enable or disable shared cache mode for the calling thread.")},
+ {"enable_shared_cache", (PyCFunction)module_enable_shared_cache, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Enable or disable shared cache mode for the calling thread. Experimental/Non-standard.")},
#endif
- {"register_adapter", (PyCFunction)module_register_adapter, METH_VARARGS, PyDoc_STR("Registers an adapter with sqlite's adapter registry.")},
- {"register_converter", (PyCFunction)module_register_converter, METH_VARARGS, PyDoc_STR("Registers a converter with sqlite.")},
+ {"register_adapter", (PyCFunction)module_register_adapter, METH_VARARGS, PyDoc_STR("Registers an adapter with pysqlite's adapter registry. Non-standard.")},
+ {"register_converter", (PyCFunction)module_register_converter, METH_VARARGS, PyDoc_STR("Registers a converter with pysqlite. Non-standard.")},
{"adapt", (PyCFunction)psyco_microprotocols_adapt, METH_VARARGS, psyco_microprotocols_adapt_doc},
{NULL, NULL}
};
diff --git a/Modules/_sqlite/module.h b/Modules/_sqlite/module.h
index 6694735..f3e2aa1 100644
--- a/Modules/_sqlite/module.h
+++ b/Modules/_sqlite/module.h
@@ -1,6 +1,6 @@
/* module.h - definitions for the module
*
- * Copyright (C) 2004-2005 Gerhard Häring <gh@ghaering.de>
+ * Copyright (C) 2004-2006 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
@@ -25,7 +25,7 @@
#define PYSQLITE_MODULE_H
#include "Python.h"
-#define PYSQLITE_VERSION "2.2.0"
+#define PYSQLITE_VERSION "2.2.2"
extern PyObject* Error;
extern PyObject* Warning;
diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c
index 0c93651..55923e7 100644
--- a/Modules/_sqlite/statement.c
+++ b/Modules/_sqlite/statement.c
@@ -64,6 +64,7 @@ int statement_create(Statement* self, Connection* connection, PyObject* sql)
return rc;
}
+ self->in_weakreflist = NULL;
self->sql = sql_str;
sql_cstr = PyString_AsString(sql_str);
@@ -304,6 +305,10 @@ void statement_dealloc(Statement* self)
Py_XDECREF(self->sql);
+ if (self->in_weakreflist != NULL) {
+ PyObject_ClearWeakRefs((PyObject*)self);
+ }
+
self->ob_type->tp_free((PyObject*)self);
}
@@ -398,12 +403,12 @@ PyTypeObject StatementType = {
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
+ offsetof(Statement, in_weakreflist), /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
diff --git a/Modules/_sqlite/statement.h b/Modules/_sqlite/statement.h
index e45a0fc..57ee36f 100644
--- a/Modules/_sqlite/statement.h
+++ b/Modules/_sqlite/statement.h
@@ -38,6 +38,7 @@ typedef struct
sqlite3_stmt* st;
PyObject* sql;
int in_use;
+ PyObject* in_weakreflist; /* List of weak references */
} Statement;
extern PyTypeObject StatementType;
diff --git a/Modules/_sre.c b/Modules/_sre.c
index 4af08ed..06acb68 100644
--- a/Modules/_sre.c
+++ b/Modules/_sre.c
@@ -254,7 +254,7 @@ static void
data_stack_dealloc(SRE_STATE* state)
{
if (state->data_stack) {
- free(state->data_stack);
+ PyMem_FREE(state->data_stack);
state->data_stack = NULL;
}
state->data_stack_size = state->data_stack_base = 0;
@@ -270,7 +270,7 @@ data_stack_grow(SRE_STATE* state, int size)
void* stack;
cursize = minsize+minsize/4+1024;
TRACE(("allocate/grow stack %d\n", cursize));
- stack = realloc(state->data_stack, cursize);
+ stack = PyMem_REALLOC(state->data_stack, cursize);
if (!stack) {
data_stack_dealloc(state);
return SRE_ERROR_MEMORY;
@@ -1163,7 +1163,7 @@ entrance:
ctx->pattern[1], ctx->pattern[2]));
/* install new repeat context */
- ctx->u.rep = (SRE_REPEAT*) malloc(sizeof(*ctx->u.rep));
+ ctx->u.rep = (SRE_REPEAT*) PyObject_MALLOC(sizeof(*ctx->u.rep));
ctx->u.rep->count = -1;
ctx->u.rep->pattern = ctx->pattern;
ctx->u.rep->prev = state->repeat;
@@ -1173,7 +1173,7 @@ entrance:
state->ptr = ctx->ptr;
DO_JUMP(JUMP_REPEAT, jump_repeat, ctx->pattern+ctx->pattern[0]);
state->repeat = ctx->u.rep->prev;
- free(ctx->u.rep);
+ PyObject_FREE(ctx->u.rep);
if (ret) {
RETURN_ON_ERROR(ret);
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index 4c0da6f..f49391d 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -183,10 +183,8 @@ newPySSLObject(PySocketSockObject *Sock, char *key_file, char *cert_file)
int sockstate;
self = PyObject_New(PySSLObject, &PySSL_Type); /* Create new object */
- if (self == NULL){
- errstr = "newPySSLObject error";
- goto fail;
- }
+ if (self == NULL)
+ return NULL;
memset(self->server, '\0', sizeof(char) * X509_NAME_MAXLEN);
memset(self->issuer, '\0', sizeof(char) * X509_NAME_MAXLEN);
self->server_cert = NULL;
diff --git a/Modules/structmodule.c b/Modules/_struct.c
index 4713c0c..cb2e538 100644
--- a/Modules/structmodule.c
+++ b/Modules/_struct.c
@@ -3,35 +3,51 @@
/* New version supporting byte order, alignment and size options,
character strings, and unsigned numbers */
+#define PY_SSIZE_T_CLEAN
+
#include "Python.h"
+#include "structseq.h"
+#include "structmember.h"
#include <ctype.h>
-PyDoc_STRVAR(struct__doc__,
-"Functions to convert between Python values and C structs.\n\
-Python strings are used to hold the data representing the C struct\n\
-and also as format strings to describe the layout of data in the C struct.\n\
-\n\
-The optional first format char indicates byte order, size and alignment:\n\
- @: native order, size & alignment (default)\n\
- =: native order, std. size & alignment\n\
- <: little-endian, std. size & alignment\n\
- >: big-endian, std. size & alignment\n\
- !: same as >\n\
-\n\
-The remaining chars indicate types of args and must match exactly;\n\
-these can be preceded by a decimal repeat count:\n\
- x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
- h:short; H:unsigned short; i:int; I:unsigned int;\n\
- l:long; L:unsigned long; f:float; d:double.\n\
-Special cases (preceding decimal count indicates length):\n\
- s:string (array of char); p: pascal string (with count byte).\n\
-Special case (only available in native format):\n\
- P:an integer type that is wide enough to hold a pointer.\n\
-Special case (not in native mode unless 'long long' in platform C):\n\
- q:long long; Q:unsigned long long\n\
-Whitespace between formats is ignored.\n\
-\n\
-The variable struct.error is an exception raised on errors.");
+static PyTypeObject PyStructType;
+
+/* compatibility macros */
+#if (PY_VERSION_HEX < 0x02050000)
+typedef int Py_ssize_t;
+#endif
+
+/* The translation function for each format character is table driven */
+typedef struct _formatdef {
+ char format;
+ Py_ssize_t size;
+ Py_ssize_t alignment;
+ PyObject* (*unpack)(const char *,
+ const struct _formatdef *);
+ int (*pack)(char *, PyObject *,
+ const struct _formatdef *);
+} formatdef;
+
+typedef struct _formatcode {
+ const struct _formatdef *fmtdef;
+ Py_ssize_t offset;
+ Py_ssize_t size;
+} formatcode;
+
+/* Struct object interface */
+
+typedef struct {
+ PyObject_HEAD
+ Py_ssize_t s_size;
+ Py_ssize_t s_len;
+ formatcode *s_codes;
+ PyObject *s_format;
+ PyObject *weakreflist; /* List of weak references */
+} PyStructObject;
+
+
+#define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType)
+#define PyStruct_CheckExact(op) ((op)->ob_type == &PyStructType)
/* Exception */
@@ -127,9 +143,14 @@ get_ulong(PyObject *v, unsigned long *p)
*p = x;
return 0;
}
- else {
- return get_long(v, (long *)p);
+ if (get_long(v, (long *)p) < 0)
+ return -1;
+ if (((long)*p) < 0) {
+ PyErr_SetString(StructError,
+ "unsigned argument is < 0");
+ return -1;
}
+ return 0;
}
#ifdef HAVE_LONG_LONG
@@ -200,22 +221,40 @@ unpack_double(const char *p, /* start of 8-byte string */
return PyFloat_FromDouble(x);
}
+/* Helper to format the range error exceptions */
+static int
+_range_error(char format, Py_ssize_t size, int is_unsigned)
+{
+ if (is_unsigned == 0) {
+ long smallest = 0, largest = 0;
+ Py_ssize_t i = size * 8;
+ while (--i > 0) {
+ smallest = (smallest * 2) - 1;
+ largest = (largest * 2) + 1;
+ }
+ PyErr_Format(StructError,
+ "'%c' format requires %ld <= number <= %ld",
+ format,
+ smallest,
+ largest);
+ } else {
+ unsigned long largest = 0;
+ Py_ssize_t i = size * 8;
+ while (--i >= 0)
+ largest = (largest * 2) + 1;
+ PyErr_Format(StructError,
+ "'%c' format requires 0 <= number <= %lu",
+ format,
+ largest);
+ }
+ return -1;
+}
-/* The translation function for each format character is table driven */
-typedef struct _formatdef {
- char format;
- int size;
- int alignment;
- PyObject* (*unpack)(const char *,
- const struct _formatdef *);
- int (*pack)(char *, PyObject *,
- const struct _formatdef *);
-} formatdef;
/* A large number of small routines follow, with names of the form
- [bln][up]_TYPE
+ [bln][up]_TYPE
[bln] distiguishes among big-endian, little-endian and native.
[pu] distiguishes between pack (to struct) and unpack (from struct).
@@ -279,7 +318,13 @@ nu_uint(const char *p, const formatdef *f)
{
unsigned int x;
memcpy((char *)&x, p, sizeof x);
+#if (SIZEOF_LONG > SIZEOF_INT)
+ return PyInt_FromLong((long)x);
+#else
+ if (x <= ((unsigned int)LONG_MAX))
+ return PyInt_FromLong((long)x);
return PyLong_FromUnsignedLong((unsigned long)x);
+#endif
}
static PyObject *
@@ -295,6 +340,8 @@ nu_ulong(const char *p, const formatdef *f)
{
unsigned long x;
memcpy((char *)&x, p, sizeof x);
+ if (x <= LONG_MAX)
+ return PyInt_FromLong((long)x);
return PyLong_FromUnsignedLong(x);
}
@@ -308,6 +355,8 @@ nu_longlong(const char *p, const formatdef *f)
{
PY_LONG_LONG x;
memcpy((char *)&x, p, sizeof x);
+ if (x >= LONG_MIN && x <= LONG_MAX)
+ return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
return PyLong_FromLongLong(x);
}
@@ -316,6 +365,8 @@ nu_ulonglong(const char *p, const formatdef *f)
{
unsigned PY_LONG_LONG x;
memcpy((char *)&x, p, sizeof x);
+ if (x <= LONG_MAX)
+ return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
return PyLong_FromUnsignedLongLong(x);
}
@@ -353,7 +404,7 @@ np_byte(char *p, PyObject *v, const formatdef *f)
return -1;
if (x < -128 || x > 127){
PyErr_SetString(StructError,
- "byte format requires -128<=number<=127");
+ "byte format requires -128 <= number <= 127");
return -1;
}
*p = (char)x;
@@ -368,7 +419,7 @@ np_ubyte(char *p, PyObject *v, const formatdef *f)
return -1;
if (x < 0 || x > 255){
PyErr_SetString(StructError,
- "ubyte format requires 0<=number<=255");
+ "ubyte format requires 0 <= number <= 255");
return -1;
}
*p = (char)x;
@@ -397,7 +448,7 @@ np_short(char *p, PyObject *v, const formatdef *f)
if (x < SHRT_MIN || x > SHRT_MAX){
PyErr_SetString(StructError,
"short format requires " STRINGIFY(SHRT_MIN)
- "<=number<=" STRINGIFY(SHRT_MAX));
+ " <= number <= " STRINGIFY(SHRT_MAX));
return -1;
}
y = (short)x;
@@ -414,7 +465,7 @@ np_ushort(char *p, PyObject *v, const formatdef *f)
return -1;
if (x < 0 || x > USHRT_MAX){
PyErr_SetString(StructError,
- "short format requires 0<=number<=" STRINGIFY(USHRT_MAX));
+ "short format requires 0 <= number <= " STRINGIFY(USHRT_MAX));
return -1;
}
y = (unsigned short)x;
@@ -429,6 +480,10 @@ np_int(char *p, PyObject *v, const formatdef *f)
int y;
if (get_long(v, &x) < 0)
return -1;
+#if (SIZEOF_LONG > SIZEOF_INT)
+ if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
+ return _range_error(f->format, sizeof(y), 0);
+#endif
y = (int)x;
memcpy(p, (char *)&y, sizeof y);
return 0;
@@ -440,8 +495,12 @@ np_uint(char *p, PyObject *v, const formatdef *f)
unsigned long x;
unsigned int y;
if (get_ulong(v, &x) < 0)
- return -1;
+ return _range_error(f->format, sizeof(y), 1);
y = (unsigned int)x;
+#if (SIZEOF_LONG > SIZEOF_INT)
+ if (x > ((unsigned long)UINT_MAX))
+ return _range_error(f->format, sizeof(y), 1);
+#endif
memcpy(p, (char *)&y, sizeof y);
return 0;
}
@@ -461,7 +520,7 @@ np_ulong(char *p, PyObject *v, const formatdef *f)
{
unsigned long x;
if (get_ulong(v, &x) < 0)
- return -1;
+ return _range_error(f->format, sizeof(x), 1);
memcpy(p, (char *)&x, sizeof x);
return 0;
}
@@ -545,13 +604,13 @@ static formatdef native_table[] = {
{'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
{'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
{'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
- {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
- {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
- {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
#ifdef HAVE_LONG_LONG
{'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
{'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
#endif
+ {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
+ {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
+ {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
{0}
};
@@ -561,13 +620,13 @@ static PyObject *
bu_int(const char *p, const formatdef *f)
{
long x = 0;
- int i = f->size;
+ Py_ssize_t i = f->size;
do {
x = (x<<8) | (*p++ & 0xFF);
} while (--i > 0);
/* Extend the sign bit. */
if (SIZEOF_LONG > f->size)
- x |= -(x & (1L << (8*f->size - 1)));
+ x |= -(x & (1L << ((8 * f->size) - 1)));
return PyInt_FromLong(x);
}
@@ -575,32 +634,56 @@ static PyObject *
bu_uint(const char *p, const formatdef *f)
{
unsigned long x = 0;
- int i = f->size;
+ Py_ssize_t i = f->size;
do {
x = (x<<8) | (*p++ & 0xFF);
} while (--i > 0);
- if (f->size >= 4)
- return PyLong_FromUnsignedLong(x);
- else
+ if (x <= LONG_MAX)
return PyInt_FromLong((long)x);
+ return PyLong_FromUnsignedLong(x);
}
static PyObject *
bu_longlong(const char *p, const formatdef *f)
{
+#ifdef HAVE_LONG_LONG
+ PY_LONG_LONG x = 0;
+ Py_ssize_t i = f->size;
+ do {
+ x = (x<<8) | (*p++ & 0xFF);
+ } while (--i > 0);
+ /* Extend the sign bit. */
+ if (SIZEOF_LONG_LONG > f->size)
+ x |= -(x & (1L << ((8 * f->size) - 1)));
+ if (x >= LONG_MIN && x <= LONG_MAX)
+ return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
+ return PyLong_FromLongLong(x);
+#else
return _PyLong_FromByteArray((const unsigned char *)p,
8,
0, /* little-endian */
1 /* signed */);
+#endif
}
static PyObject *
bu_ulonglong(const char *p, const formatdef *f)
{
+#ifdef HAVE_LONG_LONG
+ unsigned PY_LONG_LONG x = 0;
+ Py_ssize_t i = f->size;
+ do {
+ x = (x<<8) | (*p++ & 0xFF);
+ } while (--i > 0);
+ if (x <= LONG_MAX)
+ return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
+ return PyLong_FromUnsignedLongLong(x);
+#else
return _PyLong_FromByteArray((const unsigned char *)p,
8,
0, /* little-endian */
0 /* signed */);
+#endif
}
static PyObject *
@@ -619,10 +702,18 @@ static int
bp_int(char *p, PyObject *v, const formatdef *f)
{
long x;
- int i;
+ Py_ssize_t i;
if (get_long(v, &x) < 0)
return -1;
i = f->size;
+ if (i != SIZEOF_LONG) {
+ if ((i == 2) && (x < -32768 || x > 32767))
+ return _range_error(f->format, i, 0);
+#if (SIZEOF_LONG != 4)
+ else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
+ return _range_error(f->format, i, 0);
+#endif
+ }
do {
p[--i] = (char)x;
x >>= 8;
@@ -634,10 +725,16 @@ static int
bp_uint(char *p, PyObject *v, const formatdef *f)
{
unsigned long x;
- int i;
+ Py_ssize_t i;
if (get_ulong(v, &x) < 0)
return -1;
i = f->size;
+ if (i != SIZEOF_LONG) {
+ unsigned long maxint = 1;
+ maxint <<= (unsigned long)(i * 8);
+ if (x >= maxint)
+ return _range_error(f->format, f->size, 1);
+ }
do {
p[--i] = (char)x;
x >>= 8;
@@ -703,8 +800,8 @@ bp_double(char *p, PyObject *v, const formatdef *f)
static formatdef bigendian_table[] = {
{'x', 1, 0, NULL},
- {'b', 1, 0, bu_int, bp_int},
- {'B', 1, 0, bu_uint, bp_int},
+ {'b', 1, 0, nu_byte, np_byte},
+ {'B', 1, 0, nu_ubyte, np_ubyte},
{'c', 1, 0, nu_char, np_char},
{'s', 1, 0, NULL},
{'p', 1, 0, NULL},
@@ -727,13 +824,13 @@ static PyObject *
lu_int(const char *p, const formatdef *f)
{
long x = 0;
- int i = f->size;
+ Py_ssize_t i = f->size;
do {
x = (x<<8) | (p[--i] & 0xFF);
} while (i > 0);
/* Extend the sign bit. */
if (SIZEOF_LONG > f->size)
- x |= -(x & (1L << (8*f->size - 1)));
+ x |= -(x & (1L << ((8 * f->size) - 1)));
return PyInt_FromLong(x);
}
@@ -741,32 +838,56 @@ static PyObject *
lu_uint(const char *p, const formatdef *f)
{
unsigned long x = 0;
- int i = f->size;
+ Py_ssize_t i = f->size;
do {
x = (x<<8) | (p[--i] & 0xFF);
} while (i > 0);
- if (f->size >= 4)
- return PyLong_FromUnsignedLong(x);
- else
+ if (x <= LONG_MAX)
return PyInt_FromLong((long)x);
+ return PyLong_FromUnsignedLong((long)x);
}
static PyObject *
lu_longlong(const char *p, const formatdef *f)
{
+#ifdef HAVE_LONG_LONG
+ PY_LONG_LONG x = 0;
+ Py_ssize_t i = f->size;
+ do {
+ x = (x<<8) | (p[--i] & 0xFF);
+ } while (i > 0);
+ /* Extend the sign bit. */
+ if (SIZEOF_LONG_LONG > f->size)
+ x |= -(x & (1L << ((8 * f->size) - 1)));
+ if (x >= LONG_MIN && x <= LONG_MAX)
+ return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
+ return PyLong_FromLongLong(x);
+#else
return _PyLong_FromByteArray((const unsigned char *)p,
8,
1, /* little-endian */
1 /* signed */);
+#endif
}
static PyObject *
lu_ulonglong(const char *p, const formatdef *f)
{
+#ifdef HAVE_LONG_LONG
+ unsigned PY_LONG_LONG x = 0;
+ Py_ssize_t i = f->size;
+ do {
+ x = (x<<8) | (p[--i] & 0xFF);
+ } while (i > 0);
+ if (x <= LONG_MAX)
+ return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
+ return PyLong_FromUnsignedLongLong(x);
+#else
return _PyLong_FromByteArray((const unsigned char *)p,
8,
1, /* little-endian */
0 /* signed */);
+#endif
}
static PyObject *
@@ -785,10 +906,18 @@ static int
lp_int(char *p, PyObject *v, const formatdef *f)
{
long x;
- int i;
+ Py_ssize_t i;
if (get_long(v, &x) < 0)
return -1;
i = f->size;
+ if (i != SIZEOF_LONG) {
+ if ((i == 2) && (x < -32768 || x > 32767))
+ return _range_error(f->format, i, 0);
+#if (SIZEOF_LONG != 4)
+ else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
+ return _range_error(f->format, i, 0);
+#endif
+ }
do {
*p++ = (char)x;
x >>= 8;
@@ -800,10 +929,16 @@ static int
lp_uint(char *p, PyObject *v, const formatdef *f)
{
unsigned long x;
- int i;
+ Py_ssize_t i;
if (get_ulong(v, &x) < 0)
return -1;
i = f->size;
+ if (i != SIZEOF_LONG) {
+ unsigned long maxint = 1;
+ maxint <<= (unsigned long)(i * 8);
+ if (x >= maxint)
+ return _range_error(f->format, f->size, 1);
+ }
do {
*p++ = (char)x;
x >>= 8;
@@ -869,8 +1004,8 @@ lp_double(char *p, PyObject *v, const formatdef *f)
static formatdef lilendian_table[] = {
{'x', 1, 0, NULL},
- {'b', 1, 0, lu_int, lp_int},
- {'B', 1, 0, lu_uint, lp_int},
+ {'b', 1, 0, nu_byte, np_byte},
+ {'B', 1, 0, nu_ubyte, np_ubyte},
{'c', 1, 0, nu_char, np_char},
{'s', 1, 0, NULL},
{'p', 1, 0, NULL},
@@ -933,7 +1068,7 @@ getentry(int c, const formatdef *f)
/* Align a size according to a format code */
static int
-align(int size, int c, const formatdef *e)
+align(Py_ssize_t size, char c, const formatdef *e)
{
if (e->format == c) {
if (e->alignment) {
@@ -949,15 +1084,24 @@ align(int size, int c, const formatdef *e)
/* calculate the size of a format string */
static int
-calcsize(const char *fmt, const formatdef *f)
+prepare_s(PyStructObject *self)
{
+ const formatdef *f;
const formatdef *e;
+ formatcode *codes;
+
const char *s;
+ const char *fmt;
char c;
- int size, num, itemsize, x;
+ Py_ssize_t size, len, num, itemsize, x;
+
+ fmt = PyString_AS_STRING(self->s_format);
+ f = whichtable((char **)&fmt);
+
s = fmt;
size = 0;
+ len = 0;
while ((c = *s++) != '\0') {
if (isspace(Py_CHARMASK(c)))
continue;
@@ -982,6 +1126,14 @@ calcsize(const char *fmt, const formatdef *f)
e = getentry(c, f);
if (e == NULL)
return -1;
+
+ switch (c) {
+ case 's': /* fall through */
+ case 'p': len++; break;
+ case 'x': break;
+ default: len += num; break;
+ }
+
itemsize = e->size;
size = align(size, c, e);
x = num * itemsize;
@@ -993,78 +1145,24 @@ calcsize(const char *fmt, const formatdef *f)
}
}
- return size;
-}
-
-
-PyDoc_STRVAR(calcsize__doc__,
-"calcsize(fmt) -> int\n\
-Return size of C struct described by format string fmt.\n\
-See struct.__doc__ for more on format strings.");
-
-static PyObject *
-struct_calcsize(PyObject *self, PyObject *args)
-{
- char *fmt;
- const formatdef *f;
- int size;
-
- if (!PyArg_ParseTuple(args, "s:calcsize", &fmt))
- return NULL;
- f = whichtable(&fmt);
- size = calcsize(fmt, f);
- if (size < 0)
- return NULL;
- return PyInt_FromLong((long)size);
-}
-
-
-PyDoc_STRVAR(pack__doc__,
-"pack(fmt, v1, v2, ...) -> string\n\
-Return string containing values v1, v2, ... packed according to fmt.\n\
-See struct.__doc__ for more on format strings.");
-
-static PyObject *
-struct_pack(PyObject *self, PyObject *args)
-{
- const formatdef *f, *e;
- PyObject *format, *result, *v;
- char *fmt;
- int size, num;
- Py_ssize_t i, n;
- char *s, *res, *restart, *nres;
- char c;
-
- if (args == NULL || !PyTuple_Check(args) ||
- (n = PyTuple_Size(args)) < 1)
- {
- PyErr_SetString(PyExc_TypeError,
- "struct.pack requires at least one argument");
- return NULL;
+ self->s_size = size;
+ self->s_len = len;
+ codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
+ if (codes == NULL) {
+ PyErr_NoMemory();
+ return -1;
}
- format = PyTuple_GetItem(args, 0);
- fmt = PyString_AsString(format);
- if (!fmt)
- return NULL;
- f = whichtable(&fmt);
- size = calcsize(fmt, f);
- if (size < 0)
- return NULL;
- result = PyString_FromStringAndSize((char *)NULL, size);
- if (result == NULL)
- return NULL;
-
+ self->s_codes = codes;
+
s = fmt;
- i = 1;
- res = restart = PyString_AsString(result);
-
+ size = 0;
while ((c = *s++) != '\0') {
if (isspace(Py_CHARMASK(c)))
continue;
if ('0' <= c && c <= '9') {
num = c - '0';
while ('0' <= (c = *s++) && c <= '9')
- num = num*10 + (c - '0');
+ num = num*10 + (c - '0');
if (c == '\0')
break;
}
@@ -1072,222 +1170,491 @@ struct_pack(PyObject *self, PyObject *args)
num = 1;
e = getentry(c, f);
- if (e == NULL)
- goto fail;
- nres = restart + align((int)(res-restart), c, e);
- /* Fill padd bytes with zeros */
- while (res < nres)
- *res++ = '\0';
- if (num == 0 && c != 's')
- continue;
- do {
- if (c == 'x') {
- /* doesn't consume arguments */
- memset(res, '\0', num);
- res += num;
- break;
+
+ size = align(size, c, e);
+ if (c == 's' || c == 'p') {
+ codes->offset = size;
+ codes->size = num;
+ codes->fmtdef = e;
+ codes++;
+ size += num;
+ } else if (c == 'x') {
+ size += num;
+ } else {
+ while (--num >= 0) {
+ codes->offset = size;
+ codes->size = e->size;
+ codes->fmtdef = e;
+ codes++;
+ size += e->size;
}
- if (i >= n) {
- PyErr_SetString(StructError,
- "insufficient arguments to pack");
+ }
+ }
+ codes->fmtdef = NULL;
+ codes->offset = size;
+ codes->size = 0;
+
+ return 0;
+}
+
+static PyObject *
+s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *self;
+
+ assert(type != NULL && type->tp_alloc != NULL);
+
+ self = type->tp_alloc(type, 0);
+ if (self != NULL) {
+ PyStructObject *s = (PyStructObject*)self;
+ Py_INCREF(Py_None);
+ s->s_format = Py_None;
+ s->s_codes = NULL;
+ s->s_size = -1;
+ s->s_len = -1;
+ }
+ return self;
+}
+
+static int
+s_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ PyStructObject *soself = (PyStructObject *)self;
+ PyObject *o_format = NULL;
+ int ret = 0;
+ static char *kwlist[] = {"format", 0};
+
+ assert(PyStruct_Check(self));
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:Struct", kwlist,
+ &o_format))
+ return -1;
+
+ Py_INCREF(o_format);
+ Py_XDECREF(soself->s_format);
+ soself->s_format = o_format;
+
+ ret = prepare_s(soself);
+ return ret;
+}
+
+static void
+s_dealloc(PyStructObject *s)
+{
+ if (s->weakreflist != NULL)
+ PyObject_ClearWeakRefs((PyObject *)s);
+ if (s->s_codes != NULL) {
+ PyMem_FREE(s->s_codes);
+ }
+ Py_XDECREF(s->s_format);
+ s->ob_type->tp_free((PyObject *)s);
+}
+
+static PyObject *
+s_unpack_internal(PyStructObject *soself, char *startfrom) {
+ formatcode *code;
+ Py_ssize_t i = 0;
+ PyObject *result = PyTuple_New(soself->s_len);
+ if (result == NULL)
+ return NULL;
+
+ for (code = soself->s_codes; code->fmtdef != NULL; code++) {
+ PyObject *v;
+ const formatdef *e = code->fmtdef;
+ const char *res = startfrom + code->offset;
+ if (e->format == 's') {
+ v = PyString_FromStringAndSize(res, code->size);
+ if (v == NULL)
goto fail;
- }
- v = PyTuple_GetItem(args, i++);
+ PyTuple_SET_ITEM(result, i++, v);
+ } else if (e->format == 'p') {
+ Py_ssize_t n = *(unsigned char*)res;
+ if (n >= code->size)
+ n = code->size - 1;
+ v = PyString_FromStringAndSize(res + 1, n);
if (v == NULL)
goto fail;
- if (c == 's') {
- /* num is string size, not repeat count */
- Py_ssize_t n;
- if (!PyString_Check(v)) {
- PyErr_SetString(StructError,
- "argument for 's' must be a string");
- goto fail;
- }
- n = PyString_Size(v);
- if (n > num)
- n = num;
- if (n > 0)
- memcpy(res, PyString_AsString(v), n);
- if (n < num)
- memset(res+n, '\0', num-n);
- res += num;
- break;
- }
- else if (c == 'p') {
- /* num is string size + 1,
- to fit in the count byte */
- Py_ssize_t n;
- num--; /* now num is max string size */
- if (!PyString_Check(v)) {
- PyErr_SetString(StructError,
- "argument for 'p' must be a string");
- goto fail;
- }
- n = PyString_Size(v);
- if (n > num)
- n = num;
- if (n > 0)
- memcpy(res+1, PyString_AsString(v), n);
- if (n < num)
- /* no real need, just to be nice */
- memset(res+1+n, '\0', num-n);
- if (n > 255)
- n = 255;
- /* store the length byte */
- *res++ = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
- res += num;
- break;
- }
- else {
- if (e->pack(res, v, e) < 0)
- goto fail;
- res += e->size;
- }
- } while (--num > 0);
- }
-
- if (i < n) {
- PyErr_SetString(StructError,
- "too many arguments for pack format");
- goto fail;
+ PyTuple_SET_ITEM(result, i++, v);
+ } else {
+ v = e->unpack(res, e);
+ if (v == NULL)
+ goto fail;
+ PyTuple_SET_ITEM(result, i++, v);
+ }
}
return result;
-
- fail:
+fail:
Py_DECREF(result);
return NULL;
}
-PyDoc_STRVAR(unpack__doc__,
-"unpack(fmt, string) -> (v1, v2, ...)\n\
-Unpack the string, containing packed C structure data, according\n\
-to fmt. Requires len(string)==calcsize(fmt).\n\
+PyDoc_STRVAR(s_unpack__doc__,
+"S.unpack(str) -> (v1, v2, ...)\n\
+\n\
+Return tuple containing values unpacked according to this Struct's format.\n\
+Requires len(str) == self.size. See struct.__doc__ for more on format\n\
+strings.");
+
+static PyObject *
+s_unpack(PyObject *self, PyObject *inputstr)
+{
+ PyStructObject *soself = (PyStructObject *)self;
+ assert(PyStruct_Check(self));
+ assert(soself->s_codes != NULL);
+ if (inputstr == NULL || !PyString_Check(inputstr) ||
+ PyString_GET_SIZE(inputstr) != soself->s_size) {
+ PyErr_Format(StructError,
+ "unpack requires a string argument of length %zd", soself->s_size);
+ return NULL;
+ }
+ return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
+}
+
+PyDoc_STRVAR(s_unpack_from__doc__,
+"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
+\n\
+Return tuple containing values unpacked according to this Struct's format.\n\
+Unlike unpack, unpack_from can unpack values from any object supporting\n\
+the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
See struct.__doc__ for more on format strings.");
static PyObject *
-struct_unpack(PyObject *self, PyObject *args)
+s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
{
- const formatdef *f, *e;
- char *str, *start, *fmt, *s;
- char c;
- int len, size, num;
- PyObject *res, *v;
-
- if (!PyArg_ParseTuple(args, "ss#:unpack", &fmt, &start, &len))
- return NULL;
- f = whichtable(&fmt);
- size = calcsize(fmt, f);
- if (size < 0)
+ static char *kwlist[] = {"buffer", "offset", 0};
+#if (PY_VERSION_HEX < 0x02050000)
+ static char *fmt = "z#|i:unpack_from";
+#else
+ static char *fmt = "z#|n:unpack_from";
+#endif
+ Py_ssize_t buffer_len = 0, offset = 0;
+ char *buffer = NULL;
+ PyStructObject *soself = (PyStructObject *)self;
+ assert(PyStruct_Check(self));
+ assert(soself->s_codes != NULL);
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
+ &buffer, &buffer_len, &offset))
return NULL;
- if (size != len) {
- PyErr_SetString(StructError,
- "unpack str size does not match format");
+
+ if (buffer == NULL) {
+ PyErr_Format(StructError,
+ "unpack_from requires a buffer argument");
return NULL;
}
- res = PyList_New(0);
- if (res == NULL)
+
+ if (offset < 0)
+ offset += buffer_len;
+
+ if (offset < 0 || (buffer_len - offset) < soself->s_size) {
+ PyErr_Format(StructError,
+ "unpack_from requires a buffer of at least %zd bytes",
+ soself->s_size);
return NULL;
- str = start;
- s = fmt;
- while ((c = *s++) != '\0') {
- if (isspace(Py_CHARMASK(c)))
- continue;
- if ('0' <= c && c <= '9') {
- num = c - '0';
- while ('0' <= (c = *s++) && c <= '9')
- num = num*10 + (c - '0');
- if (c == '\0')
- break;
- }
- else
- num = 1;
+ }
+ return s_unpack_internal(soself, buffer + offset);
+}
- e = getentry(c, f);
- if (e == NULL)
- goto fail;
- str = start + align((int)(str-start), c, e);
- if (num == 0 && c != 's')
- continue;
- do {
- if (c == 'x') {
- str += num;
- break;
- }
- if (c == 's') {
- /* num is string size, not repeat count */
- v = PyString_FromStringAndSize(str, num);
- if (v == NULL)
- goto fail;
- str += num;
- num = 0;
- }
- else if (c == 'p') {
- /* num is string buffer size,
- not repeat count */
- int n = *(unsigned char*)str;
- /* first byte (unsigned) is string size */
- if (n >= num)
- n = num-1;
- v = PyString_FromStringAndSize(str+1, n);
- if (v == NULL)
- goto fail;
- str += num;
- num = 0;
+/*
+ * Guts of the pack function.
+ *
+ * Takes a struct object, a tuple of arguments, and offset in that tuple of
+ * argument for where to start processing the arguments for packing, and a
+ * character buffer for writing the packed string. The caller must insure
+ * that the buffer may contain the required length for packing the arguments.
+ * 0 is returned on success, 1 is returned if there is an error.
+ *
+ */
+static int
+s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
+{
+ formatcode *code;
+ Py_ssize_t i;
+
+ memset(buf, '\0', soself->s_size);
+ i = offset;
+ for (code = soself->s_codes; code->fmtdef != NULL; code++) {
+ Py_ssize_t n;
+ PyObject *v;
+ const formatdef *e = code->fmtdef;
+ char *res = buf + code->offset;
+ if (e->format == 's') {
+ v = PyTuple_GET_ITEM(args, i++);
+ if (!PyString_Check(v)) {
+ PyErr_SetString(StructError,
+ "argument for 's' must be a string");
+ return -1;
}
- else {
- v = e->unpack(str, e);
- if (v == NULL)
- goto fail;
- str += e->size;
+ n = PyString_GET_SIZE(v);
+ if (n > code->size)
+ n = code->size;
+ if (n > 0)
+ memcpy(res, PyString_AS_STRING(v), n);
+ } else if (e->format == 'p') {
+ v = PyTuple_GET_ITEM(args, i++);
+ if (!PyString_Check(v)) {
+ PyErr_SetString(StructError,
+ "argument for 'p' must be a string");
+ return -1;
}
- if (v == NULL || PyList_Append(res, v) < 0)
- goto fail;
- Py_DECREF(v);
- } while (--num > 0);
+ n = PyString_GET_SIZE(v);
+ if (n > (code->size - 1))
+ n = code->size - 1;
+ if (n > 0)
+ memcpy(res + 1, PyString_AS_STRING(v), n);
+ if (n > 255)
+ n = 255;
+ *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
+ } else {
+ v = PyTuple_GET_ITEM(args, i++);
+ if (e->pack(res, v, e) < 0)
+ return -1;
+ }
}
+
+ /* Success */
+ return 0;
+}
- v = PyList_AsTuple(res);
- Py_DECREF(res);
- return v;
- fail:
- Py_DECREF(res);
- return NULL;
+PyDoc_STRVAR(s_pack__doc__,
+"S.pack(v1, v2, ...) -> string\n\
+\n\
+Return a string containing values v1, v2, ... packed according to this\n\
+Struct's format. See struct.__doc__ for more on format strings.");
+
+static PyObject *
+s_pack(PyObject *self, PyObject *args)
+{
+ PyStructObject *soself;
+ PyObject *result;
+
+ /* Validate arguments. */
+ soself = (PyStructObject *)self;
+ assert(PyStruct_Check(self));
+ assert(soself->s_codes != NULL);
+ if (args == NULL || !PyTuple_Check(args) ||
+ PyTuple_GET_SIZE(args) != soself->s_len)
+ {
+ PyErr_Format(StructError,
+ "pack requires exactly %zd arguments", soself->s_len);
+ return NULL;
+ }
+
+ /* Allocate a new string */
+ result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
+ if (result == NULL)
+ return NULL;
+
+ /* Call the guts */
+ if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) {
+ Py_DECREF(result);
+ return NULL;
+ }
+
+ return result;
}
+PyDoc_STRVAR(s_pack_to__doc__,
+"S.pack_to(buffer, offset, v1, v2, ...)\n\
+\n\
+Pack the values v2, v2, ... according to this Struct's format, write \n\
+the packed bytes into the writable buffer buf starting at offset. Note\n\
+that the offset is not an optional argument. See struct.__doc__ for \n\
+more on format strings.");
+
+static PyObject *
+s_pack_to(PyObject *self, PyObject *args)
+{
+ PyStructObject *soself;
+ char *buffer;
+ Py_ssize_t buffer_len, offset;
+
+ /* Validate arguments. +1 is for the first arg as buffer. */
+ soself = (PyStructObject *)self;
+ assert(PyStruct_Check(self));
+ assert(soself->s_codes != NULL);
+ if (args == NULL || !PyTuple_Check(args) ||
+ PyTuple_GET_SIZE(args) != (soself->s_len + 2))
+ {
+ PyErr_Format(StructError,
+ "pack_to requires exactly %zd arguments",
+ (soself->s_len + 2));
+ return NULL;
+ }
+
+ /* Extract a writable memory buffer from the first argument */
+ if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
+ (void**)&buffer, &buffer_len) == -1 ) {
+ return NULL;
+ }
+ assert( buffer_len >= 0 );
+
+ /* Extract the offset from the first argument */
+ offset = PyInt_AsLong(PyTuple_GET_ITEM(args, 1));
+
+ /* Support negative offsets. */
+ if (offset < 0)
+ offset += buffer_len;
+
+ /* Check boundaries */
+ if (offset < 0 || (buffer_len - offset) < soself->s_size) {
+ PyErr_Format(StructError,
+ "pack_to requires a buffer of at least %zd bytes",
+ soself->s_size);
+ return NULL;
+ }
+
+ /* Call the guts */
+ if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
+ return NULL;
+ }
+
+ return Py_None;
+}
+
+static PyObject *
+s_get_format(PyStructObject *self, void *unused)
+{
+ Py_INCREF(self->s_format);
+ return self->s_format;
+}
+
+static PyObject *
+s_get_size(PyStructObject *self, void *unused)
+{
+ return PyInt_FromSsize_t(self->s_size);
+}
/* List of functions */
-static PyMethodDef struct_methods[] = {
- {"calcsize", struct_calcsize, METH_VARARGS, calcsize__doc__},
- {"pack", struct_pack, METH_VARARGS, pack__doc__},
- {"unpack", struct_unpack, METH_VARARGS, unpack__doc__},
- {NULL, NULL} /* sentinel */
+static struct PyMethodDef s_methods[] = {
+ {"pack", (PyCFunction)s_pack, METH_VARARGS, s_pack__doc__},
+ {"pack_to", (PyCFunction)s_pack_to, METH_VARARGS, s_pack_to__doc__},
+ {"unpack", (PyCFunction)s_unpack, METH_O, s_unpack__doc__},
+ {"unpack_from", (PyCFunction)s_unpack_from, METH_KEYWORDS, s_unpack_from__doc__},
+ {NULL, NULL} /* sentinel */
};
+PyDoc_STRVAR(s__doc__, "Compiled struct object");
+
+#define OFF(x) offsetof(PyStructObject, x)
+
+static PyGetSetDef s_getsetlist[] = {
+ {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
+ {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
+ {NULL} /* sentinel */
+};
+
+static
+PyTypeObject PyStructType = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "Struct",
+ sizeof(PyStructObject),
+ 0,
+ (destructor)s_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ PyObject_GenericSetAttr, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,/* tp_flags */
+ s__doc__, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ s_methods, /* tp_methods */
+ NULL, /* tp_members */
+ s_getsetlist, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ s_init, /* tp_init */
+ PyType_GenericAlloc,/* tp_alloc */
+ s_new, /* tp_new */
+ PyObject_Del, /* tp_free */
+};
/* Module initialization */
PyMODINIT_FUNC
-initstruct(void)
+init_struct(void)
{
- PyObject *m;
-
- /* Create the module and add the functions */
- m = Py_InitModule4("struct", struct_methods, struct__doc__,
- (PyObject*)NULL, PYTHON_API_VERSION);
+ PyObject *m = Py_InitModule("_struct", NULL);
if (m == NULL)
return;
+ PyStructType.ob_type = &PyType_Type;
+ if (PyType_Ready(&PyStructType) < 0)
+ return;
+
+ /* Check endian and swap in faster functions */
+ {
+ int one = 1;
+ formatdef *native = native_table;
+ formatdef *other, *ptr;
+ if ((int)*(unsigned char*)&one)
+ other = lilendian_table;
+ else
+ other = bigendian_table;
+ /* Scan through the native table, find a matching
+ entry in the endian table and swap in the
+ native implementations whenever possible
+ (64-bit platforms may not have "standard" sizes) */
+ while (native->format != '\0' && other->format != '\0') {
+ ptr = other;
+ while (ptr->format != '\0') {
+ if (ptr->format == native->format) {
+ /* Match faster when formats are
+ listed in the same order */
+ if (ptr == other)
+ other++;
+ /* Only use the trick if the
+ size matches */
+ if (ptr->size != native->size)
+ break;
+ /* Skip float and double, could be
+ "unknown" float format */
+ if (ptr->format == 'd' || ptr->format == 'f')
+ break;
+ ptr->pack = native->pack;
+ ptr->unpack = native->unpack;
+ break;
+ }
+ ptr++;
+ }
+ native++;
+ }
+ }
+
/* Add some symbolic constants to the module */
if (StructError == NULL) {
StructError = PyErr_NewException("struct.error", NULL, NULL);
if (StructError == NULL)
return;
}
+
Py_INCREF(StructError);
PyModule_AddObject(m, "error", StructError);
+
+ Py_INCREF((PyObject*)&PyStructType);
+ PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
}
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index e8881dc..6b9dffd 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -486,8 +486,8 @@ test_u_code(PyObject *self)
return Py_None;
}
-static
-PyObject *codec_incrementalencoder(PyObject *self, PyObject *args)
+static PyObject *
+codec_incrementalencoder(PyObject *self, PyObject *args)
{
const char *encoding, *errors = NULL;
if (!PyArg_ParseTuple(args, "s|s:test_incrementalencoder",
@@ -496,8 +496,8 @@ PyObject *codec_incrementalencoder(PyObject *self, PyObject *args)
return PyCodec_IncrementalEncoder(encoding, errors);
}
-static
-PyObject *codec_incrementaldecoder(PyObject *self, PyObject *args)
+static PyObject *
+codec_incrementaldecoder(PyObject *self, PyObject *args)
{
const char *encoding, *errors = NULL;
if (!PyArg_ParseTuple(args, "s|s:test_incrementaldecoder",
@@ -660,6 +660,42 @@ test_thread_state(PyObject *self, PyObject *args)
}
#endif
+/* Some tests of PyString_FromFormat(). This needs more tests. */
+static PyObject *
+test_string_from_format(PyObject *self, PyObject *args)
+{
+ PyObject *result;
+ char *msg;
+
+#define CHECK_1_FORMAT(FORMAT, TYPE) \
+ result = PyString_FromFormat(FORMAT, (TYPE)1); \
+ if (result == NULL) \
+ return NULL; \
+ if (strcmp(PyString_AsString(result), "1")) { \
+ msg = FORMAT " failed at 1"; \
+ goto Fail; \
+ } \
+ Py_DECREF(result)
+
+ CHECK_1_FORMAT("%d", int);
+ CHECK_1_FORMAT("%ld", long);
+ /* The z width modifier was added in Python 2.5. */
+ CHECK_1_FORMAT("%zd", Py_ssize_t);
+
+ /* The u type code was added in Python 2.5. */
+ CHECK_1_FORMAT("%u", unsigned int);
+ CHECK_1_FORMAT("%lu", unsigned long);
+ CHECK_1_FORMAT("%zu", size_t);
+
+ Py_RETURN_NONE;
+
+ Fail:
+ Py_XDECREF(result);
+ return raiseTestError("test_string_from_format", msg);
+
+#undef CHECK_1_FORMAT
+}
+
static PyMethodDef TestMethods[] = {
{"raise_exception", raise_exception, METH_VARARGS},
{"test_config", (PyCFunction)test_config, METH_NOARGS},
@@ -669,6 +705,7 @@ static PyMethodDef TestMethods[] = {
{"test_long_numbits", (PyCFunction)test_long_numbits, METH_NOARGS},
{"test_k_code", (PyCFunction)test_k_code, METH_NOARGS},
{"test_null_strings", (PyCFunction)test_null_strings, METH_NOARGS},
+ {"test_string_from_format", (PyCFunction)test_string_from_format, METH_NOARGS},
{"getargs_b", getargs_b, METH_VARARGS},
{"getargs_B", getargs_B, METH_VARARGS},
diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c
index c17b6c6..77583b7 100644
--- a/Modules/_tkinter.c
+++ b/Modules/_tkinter.c
@@ -2619,21 +2619,32 @@ Tkapp_InterpAddr(PyObject *self, PyObject *args)
static PyObject *
Tkapp_TkInit(PyObject *self, PyObject *args)
{
+ static int has_failed;
Tcl_Interp *interp = Tkapp_Interp(self);
Tk_Window main_window;
const char * _tk_exists = NULL;
- PyObject *res = NULL;
int err;
main_window = Tk_MainWindow(interp);
+ /* In all current versions of Tk (including 8.4.13), Tk_Init
+ deadlocks on the second call when the first call failed.
+ To avoid the deadlock, we just refuse the second call through
+ a static variable. */
+ if (has_failed) {
+ PyErr_SetString(Tkinter_TclError,
+ "Calling Tk_Init again after a previous call failed might deadlock");
+ return NULL;
+ }
+
/* We want to guard against calling Tk_Init() multiple times */
CHECK_TCL_APPARTMENT;
ENTER_TCL
err = Tcl_Eval(Tkapp_Interp(self), "info exists tk_version");
ENTER_OVERLAP
if (err == TCL_ERROR) {
- /* XXX: shouldn't we do something with res? */
- res = Tkinter_Error(self);
+ /* This sets an exception, but we cannot return right
+ away because we need to exit the overlap first. */
+ Tkinter_Error(self);
} else {
_tk_exists = Tkapp_Result(self);
}
@@ -2644,6 +2655,7 @@ Tkapp_TkInit(PyObject *self, PyObject *args)
if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) {
if (Tk_Init(interp) == TCL_ERROR) {
PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self)));
+ has_failed = 1;
return NULL;
}
}
diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c
index 52a7f5e..af12769 100644
--- a/Modules/arraymodule.c
+++ b/Modules/arraymodule.c
@@ -1975,9 +1975,9 @@ static PyTypeObject Arraytype = {
0, /* tp_setattr */
0, /* tp_compare */
(reprfunc)array_repr, /* tp_repr */
- 0, /* tp_as _number*/
- &array_as_sequence, /* tp_as _sequence*/
- &array_as_mapping, /* tp_as _mapping*/
+ 0, /* tp_as_number*/
+ &array_as_sequence, /* tp_as_sequence*/
+ &array_as_mapping, /* tp_as_mapping*/
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
diff --git a/Modules/cPickle.c b/Modules/cPickle.c
index 18df599..85fd459 100644
--- a/Modules/cPickle.c
+++ b/Modules/cPickle.c
@@ -1151,7 +1151,9 @@ save_float(Picklerobject *self, PyObject *args)
else {
char c_str[250];
c_str[0] = FLOAT;
- PyOS_snprintf(c_str + 1, sizeof(c_str) - 1, "%.17g\n", x);
+ PyOS_ascii_formatd(c_str + 1, sizeof(c_str) - 2, "%.17g", x);
+ /* Extend the formatted string with a newline character */
+ strcat(c_str, "\n");
if (self->write_func(self, c_str, strlen(c_str)) < 0)
return -1;
@@ -3071,8 +3073,8 @@ find_class(PyObject *py_module_name, PyObject *py_global_name, PyObject *fc)
"pickles are not supported.");
return NULL;
}
- return PyObject_CallFunction(fc, "OO", py_module_name,
- py_global_name);
+ return PyObject_CallFunctionObjArgs(fc, py_module_name,
+ py_global_name, NULL);
}
module = PySys_GetObject("modules");
@@ -5623,7 +5625,6 @@ init_stuff(PyObject *module_dict)
if (!( t=PyDict_New())) return -1;
if (!( r=PyRun_String(
- "def __init__(self, *args): self.args=args\n\n"
"def __str__(self):\n"
" return self.args and ('%s' % self.args[0]) or '(what)'\n",
Py_file_input,
@@ -5643,7 +5644,6 @@ init_stuff(PyObject *module_dict)
if (!( t=PyDict_New())) return -1;
if (!( r=PyRun_String(
- "def __init__(self, *args): self.args=args\n\n"
"def __str__(self):\n"
" a=self.args\n"
" a=a and type(a[0]) or '(what)'\n"
diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c
index aa0096a..7e6aedc 100644
--- a/Modules/cjkcodecs/multibytecodec.c
+++ b/Modules/cjkcodecs/multibytecodec.c
@@ -831,7 +831,7 @@ decoder_feed_buffer(MultibyteStatefulDecoderContext *ctx,
{
while (buf->inbuf < buf->inbuf_end) {
Py_ssize_t inleft, outleft;
- int r;
+ Py_ssize_t r;
inleft = (Py_ssize_t)(buf->inbuf_end - buf->inbuf);
outleft = (Py_ssize_t)(buf->outbuf_end - buf->outbuf);
diff --git a/Modules/datetimemodule.c b/Modules/datetimemodule.c
index 9ae235a..760ab31 100644
--- a/Modules/datetimemodule.c
+++ b/Modules/datetimemodule.c
@@ -3679,6 +3679,13 @@ datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp,
return NULL;
fraction = timestamp - (double)timet;
us = (int)round_to_long(fraction * 1e6);
+ /* If timestamp is less than one microsecond smaller than a
+ * full second, round up. Otherwise, ValueErrors are raised
+ * for some floats. */
+ if (us == 1000000) {
+ timet += 1;
+ us = 0;
+ }
return datetime_from_timet_and_us(cls, f, timet, us, tzinfo);
}
diff --git a/Modules/expat/expat_config.h b/Modules/expat/expat_config.h
new file mode 100644
index 0000000..b8c1639
--- /dev/null
+++ b/Modules/expat/expat_config.h
@@ -0,0 +1,19 @@
+/*
+ * Expat configuration for python. This file is not part of the expat
+ * distribution.
+ */
+#ifndef EXPAT_CONFIG_H
+#define EXPAT_CONFIG_H
+
+#include <pyconfig.h>
+#ifdef WORDS_BIGENDIAN
+#define BYTEORDER 4321
+#else
+#define BYTEORDER 1234
+#endif
+
+#define XML_NS 1
+#define XML_DTD 1
+#define XML_CONTEXT_BYTES 1024
+
+#endif /* EXPAT_CONFIG_H */
diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c
index 3372bc9..42d95b7 100644
--- a/Modules/expat/xmlparse.c
+++ b/Modules/expat/xmlparse.c
@@ -2,10 +2,6 @@
See the file COPYING for copying permission.
*/
-#include <stddef.h>
-#include <string.h> /* memset(), memcpy() */
-#include <assert.h>
-
#define XML_BUILDING_EXPAT 1
#ifdef COMPILED_FROM_DSP
@@ -16,6 +12,10 @@
#include <expat_config.h>
#endif /* ndef COMPILED_FROM_DSP */
+#include <stddef.h>
+#include <string.h> /* memset(), memcpy() */
+#include <assert.h>
+
#include "expat.h"
#ifdef XML_UNICODE
diff --git a/Modules/expat/xmlrole.c b/Modules/expat/xmlrole.c
index 1924fcb..2587fdf 100644
--- a/Modules/expat/xmlrole.c
+++ b/Modules/expat/xmlrole.c
@@ -2,8 +2,6 @@
See the file COPYING for copying permission.
*/
-#include <stddef.h>
-
#ifdef COMPILED_FROM_DSP
#include "winconfig.h"
#elif defined(MACOS_CLASSIC)
@@ -14,6 +12,8 @@
#endif
#endif /* ndef COMPILED_FROM_DSP */
+#include <stddef.h>
+
#include "expat_external.h"
#include "internal.h"
#include "xmlrole.h"
diff --git a/Modules/expat/xmltok.c b/Modules/expat/xmltok.c
index 160fa40..8b9d997 100644
--- a/Modules/expat/xmltok.c
+++ b/Modules/expat/xmltok.c
@@ -2,8 +2,6 @@
See the file COPYING for copying permission.
*/
-#include <stddef.h>
-
#ifdef COMPILED_FROM_DSP
#include "winconfig.h"
#elif defined(MACOS_CLASSIC)
@@ -14,6 +12,8 @@
#endif
#endif /* ndef COMPILED_FROM_DSP */
+#include <stddef.h>
+
#include "expat_external.h"
#include "internal.h"
#include "xmltok.h"
diff --git a/Modules/fcntlmodule.c b/Modules/fcntlmodule.c
index a368494..477af06 100644
--- a/Modules/fcntlmodule.c
+++ b/Modules/fcntlmodule.c
@@ -95,6 +95,7 @@ corresponding to the return value of the fcntl call in the C code.");
static PyObject *
fcntl_ioctl(PyObject *self, PyObject *args)
{
+#define IOCTL_BUFSZ 1024
int fd;
/* In PyArg_ParseTuple below, use the unsigned int 'I' format for
the signed int 'code' variable, because Python turns 0x8000000
@@ -106,7 +107,7 @@ fcntl_ioctl(PyObject *self, PyObject *args)
char *str;
Py_ssize_t len;
int mutate_arg = 1;
- char buf[1024];
+ char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */
if (PyArg_ParseTuple(args, "O&Iw#|i:ioctl",
conv_descriptor, &fd, &code,
@@ -114,8 +115,9 @@ fcntl_ioctl(PyObject *self, PyObject *args)
char *arg;
if (mutate_arg) {
- if (len <= sizeof buf) {
+ if (len <= IOCTL_BUFSZ) {
memcpy(buf, str, len);
+ buf[len] = '\0';
arg = buf;
}
else {
@@ -123,13 +125,14 @@ fcntl_ioctl(PyObject *self, PyObject *args)
}
}
else {
- if (len > sizeof buf) {
+ if (len > IOCTL_BUFSZ) {
PyErr_SetString(PyExc_ValueError,
"ioctl string arg too long");
return NULL;
}
else {
memcpy(buf, str, len);
+ buf[len] = '\0';
arg = buf;
}
}
@@ -141,7 +144,7 @@ fcntl_ioctl(PyObject *self, PyObject *args)
else {
ret = ioctl(fd, code, arg);
}
- if (mutate_arg && (len < sizeof buf)) {
+ if (mutate_arg && (len < IOCTL_BUFSZ)) {
memcpy(str, buf, len);
}
if (ret < 0) {
@@ -159,12 +162,13 @@ fcntl_ioctl(PyObject *self, PyObject *args)
PyErr_Clear();
if (PyArg_ParseTuple(args, "O&Is#:ioctl",
conv_descriptor, &fd, &code, &str, &len)) {
- if (len > sizeof buf) {
+ if (len > IOCTL_BUFSZ) {
PyErr_SetString(PyExc_ValueError,
"ioctl string arg too long");
return NULL;
}
memcpy(buf, str, len);
+ buf[len] = '\0';
Py_BEGIN_ALLOW_THREADS
ret = ioctl(fd, code, buf);
Py_END_ALLOW_THREADS
@@ -195,6 +199,7 @@ fcntl_ioctl(PyObject *self, PyObject *args)
return NULL;
}
return PyInt_FromLong((long)ret);
+#undef IOCTL_BUFSZ
}
PyDoc_STRVAR(ioctl_doc,
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 0176d6f..872727d 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -75,6 +75,7 @@ static PyObject *delstr = NULL;
DEBUG_OBJECTS | \
DEBUG_SAVEALL
static int debug;
+static PyObject *tmod = NULL;
/*--------------------------------------------------------------------------
gc_refs values.
@@ -602,7 +603,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
assert(callback != NULL);
/* copy-paste of weakrefobject.c's handle_callback() */
- temp = PyObject_CallFunction(callback, "O", wr);
+ temp = PyObject_CallFunctionObjArgs(callback, wr, NULL);
if (temp == NULL)
PyErr_WriteUnraisable(callback);
else
@@ -734,7 +735,6 @@ collect(int generation)
PyGC_Head unreachable; /* non-problematic unreachable trash */
PyGC_Head finalizers; /* objects with, & reachable from, __del__ */
PyGC_Head *gc;
- static PyObject *tmod = NULL;
double t1 = 0.0;
if (delstr == NULL) {
@@ -743,12 +743,6 @@ collect(int generation)
Py_FatalError("gc couldn't allocate \"__del__\"");
}
- if (tmod == NULL) {
- tmod = PyImport_ImportModule("time");
- if (tmod == NULL)
- PyErr_Clear();
- }
-
if (debug & DEBUG_STATS) {
if (tmod != NULL) {
PyObject *f = PyObject_CallMethod(tmod, "time", NULL);
@@ -1233,6 +1227,19 @@ initgc(void)
Py_INCREF(garbage);
if (PyModule_AddObject(m, "garbage", garbage) < 0)
return;
+
+ /* Importing can't be done in collect() because collect()
+ * can be called via PyGC_Collect() in Py_Finalize().
+ * This wouldn't be a problem, except that <initialized> is
+ * reset to 0 before calling collect which trips up
+ * the import and triggers an assertion.
+ */
+ if (tmod == NULL) {
+ tmod = PyImport_ImportModule("time");
+ if (tmod == NULL)
+ PyErr_Clear();
+ }
+
#define ADD_INT(NAME) if (PyModule_AddIntConstant(m, #NAME, NAME) < 0) return
ADD_INT(DEBUG_STATS);
ADD_INT(DEBUG_COLLECTABLE);
diff --git a/Modules/grpmodule.c b/Modules/grpmodule.c
index 12d33dd..e5b9f47 100644
--- a/Modules/grpmodule.c
+++ b/Modules/grpmodule.c
@@ -84,12 +84,18 @@ mkgrent(struct group *p)
}
static PyObject *
-grp_getgrgid(PyObject *self, PyObject *args)
+grp_getgrgid(PyObject *self, PyObject *pyo_id)
{
+ PyObject *py_int_id;
unsigned int gid;
struct group *p;
- if (!PyArg_ParseTuple(args, "I:getgrgid", &gid))
- return NULL;
+
+ py_int_id = PyNumber_Int(pyo_id);
+ if (!py_int_id)
+ return NULL;
+ gid = PyInt_AS_LONG(py_int_id);
+ Py_DECREF(py_int_id);
+
if ((p = getgrgid(gid)) == NULL) {
PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %d", gid);
return NULL;
@@ -98,27 +104,33 @@ grp_getgrgid(PyObject *self, PyObject *args)
}
static PyObject *
-grp_getgrnam(PyObject *self, PyObject *args)
+grp_getgrnam(PyObject *self, PyObject *pyo_name)
{
+ PyObject *py_str_name;
char *name;
struct group *p;
- if (!PyArg_ParseTuple(args, "s:getgrnam", &name))
- return NULL;
+
+ py_str_name = PyObject_Str(pyo_name);
+ if (!py_str_name)
+ return NULL;
+ name = PyString_AS_STRING(py_str_name);
+
if ((p = getgrnam(name)) == NULL) {
PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name);
+ Py_DECREF(py_str_name);
return NULL;
}
+
+ Py_DECREF(py_str_name);
return mkgrent(p);
}
static PyObject *
-grp_getgrall(PyObject *self, PyObject *args)
+grp_getgrall(PyObject *self, PyObject *ignore)
{
PyObject *d;
struct group *p;
- if (!PyArg_ParseTuple(args, ":getgrall"))
- return NULL;
if ((d = PyList_New(0)) == NULL)
return NULL;
setgrent();
@@ -136,15 +148,15 @@ grp_getgrall(PyObject *self, PyObject *args)
}
static PyMethodDef grp_methods[] = {
- {"getgrgid", grp_getgrgid, METH_VARARGS,
+ {"getgrgid", grp_getgrgid, METH_O,
"getgrgid(id) -> tuple\n\
Return the group database entry for the given numeric group ID. If\n\
id is not valid, raise KeyError."},
- {"getgrnam", grp_getgrnam, METH_VARARGS,
+ {"getgrnam", grp_getgrnam, METH_O,
"getgrnam(name) -> tuple\n\
Return the group database entry for the given group name. If\n\
name is not valid, raise KeyError."},
- {"getgrall", grp_getgrall, METH_VARARGS,
+ {"getgrall", grp_getgrall, METH_NOARGS,
"getgrall() -> list of tuples\n\
Return a list of all available group entries, in arbitrary order."},
{NULL, NULL} /* sentinel */
diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c
index 94617a9..86b1bbf 100644
--- a/Modules/itertoolsmodule.c
+++ b/Modules/itertoolsmodule.c
@@ -1093,10 +1093,10 @@ static PyTypeObject takewhile_type = {
typedef struct {
PyObject_HEAD
PyObject *it;
- long next;
- long stop;
- long step;
- long cnt;
+ Py_ssize_t next;
+ Py_ssize_t stop;
+ Py_ssize_t step;
+ Py_ssize_t cnt;
} isliceobject;
static PyTypeObject islice_type;
@@ -1105,7 +1105,7 @@ static PyObject *
islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyObject *seq;
- long start=0, stop=-1, step=1;
+ Py_ssize_t start=0, stop=-1, step=1;
PyObject *it, *a1=NULL, *a2=NULL, *a3=NULL;
Py_ssize_t numargs;
isliceobject *lz;
@@ -1119,7 +1119,7 @@ islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
numargs = PyTuple_Size(args);
if (numargs == 2) {
if (a1 != Py_None) {
- stop = PyInt_AsLong(a1);
+ stop = PyInt_AsSsize_t(a1);
if (stop == -1) {
if (PyErr_Occurred())
PyErr_Clear();
@@ -1130,11 +1130,11 @@ islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
}
} else {
if (a1 != Py_None)
- start = PyInt_AsLong(a1);
+ start = PyInt_AsSsize_t(a1);
if (start == -1 && PyErr_Occurred())
PyErr_Clear();
if (a2 != Py_None) {
- stop = PyInt_AsLong(a2);
+ stop = PyInt_AsSsize_t(a2);
if (stop == -1) {
if (PyErr_Occurred())
PyErr_Clear();
@@ -1152,7 +1152,7 @@ islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
if (a3 != NULL) {
if (a3 != Py_None)
- step = PyInt_AsLong(a3);
+ step = PyInt_AsSsize_t(a3);
if (step == -1 && PyErr_Occurred())
PyErr_Clear();
}
@@ -1202,7 +1202,7 @@ islice_next(isliceobject *lz)
{
PyObject *item;
PyObject *it = lz->it;
- long oldnext;
+ Py_ssize_t oldnext;
PyObject *(*iternext)(PyObject *);
assert(PyIter_Check(it));
@@ -1600,8 +1600,8 @@ static PyTypeObject imap_type = {
typedef struct {
PyObject_HEAD
- Py_ssize_t tuplesize;
- long iternum; /* which iterator is active */
+ Py_ssize_t tuplesize;
+ Py_ssize_t iternum; /* which iterator is active */
PyObject *ittuple; /* tuple of iterators */
} chainobject;
@@ -1612,7 +1612,7 @@ chain_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
chainobject *lz;
Py_ssize_t tuplesize = PySequence_Length(args);
- int i;
+ Py_ssize_t i;
PyObject *ittuple;
if (!_PyArg_NoKeywords("chain()", kwds))
@@ -1621,7 +1621,7 @@ chain_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
/* obtain iterators */
assert(PyTuple_Check(args));
ittuple = PyTuple_New(tuplesize);
- if(ittuple == NULL)
+ if (ittuple == NULL)
return NULL;
for (i=0; i < tuplesize; ++i) {
PyObject *item = PyTuple_GET_ITEM(args, i);
@@ -1629,7 +1629,7 @@ chain_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
if (it == NULL) {
if (PyErr_ExceptionMatches(PyExc_TypeError))
PyErr_Format(PyExc_TypeError,
- "chain argument #%d must support iteration",
+ "chain argument #%zd must support iteration",
i+1);
Py_DECREF(ittuple);
return NULL;
@@ -2033,7 +2033,7 @@ static PyTypeObject ifilterfalse_type = {
typedef struct {
PyObject_HEAD
- long cnt;
+ Py_ssize_t cnt;
} countobject;
static PyTypeObject count_type;
@@ -2042,12 +2042,12 @@ static PyObject *
count_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
countobject *lz;
- long cnt = 0;
+ Py_ssize_t cnt = 0;
if (!_PyArg_NoKeywords("count()", kwds))
return NULL;
- if (!PyArg_ParseTuple(args, "|l:count", &cnt))
+ if (!PyArg_ParseTuple(args, "|n:count", &cnt))
return NULL;
/* create countobject structure */
@@ -2062,13 +2062,13 @@ count_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
static PyObject *
count_next(countobject *lz)
{
- return PyInt_FromLong(lz->cnt++);
+ return PyInt_FromSize_t(lz->cnt++);
}
static PyObject *
count_repr(countobject *lz)
{
- return PyString_FromFormat("count(%ld)", lz->cnt);
+ return PyString_FromFormat("count(%zd)", lz->cnt);
}
PyDoc_STRVAR(count_doc,
@@ -2138,7 +2138,7 @@ static PyObject *
izip_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
izipobject *lz;
- int i;
+ Py_ssize_t i;
PyObject *ittuple; /* tuple of iterators */
PyObject *result;
Py_ssize_t tuplesize = PySequence_Length(args);
@@ -2151,7 +2151,7 @@ izip_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
/* obtain iterators */
ittuple = PyTuple_New(tuplesize);
- if(ittuple == NULL)
+ if (ittuple == NULL)
return NULL;
for (i=0; i < tuplesize; ++i) {
PyObject *item = PyTuple_GET_ITEM(args, i);
@@ -2159,7 +2159,7 @@ izip_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
if (it == NULL) {
if (PyErr_ExceptionMatches(PyExc_TypeError))
PyErr_Format(PyExc_TypeError,
- "izip argument #%d must support iteration",
+ "izip argument #%zd must support iteration",
i+1);
Py_DECREF(ittuple);
return NULL;
@@ -2212,7 +2212,7 @@ izip_traverse(izipobject *lz, visitproc visit, void *arg)
static PyObject *
izip_next(izipobject *lz)
{
- int i;
+ Py_ssize_t i;
Py_ssize_t tuplesize = lz->tuplesize;
PyObject *result = lz->result;
PyObject *it;
@@ -2314,7 +2314,7 @@ static PyTypeObject izip_type = {
typedef struct {
PyObject_HEAD
PyObject *element;
- long cnt;
+ Py_ssize_t cnt;
} repeatobject;
static PyTypeObject repeat_type;
@@ -2324,12 +2324,12 @@ repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
repeatobject *ro;
PyObject *element;
- long cnt = -1;
+ Py_ssize_t cnt = -1;
if (!_PyArg_NoKeywords("repeat()", kwds))
return NULL;
- if (!PyArg_ParseTuple(args, "O|l:repeat", &element, &cnt))
+ if (!PyArg_ParseTuple(args, "O|n:repeat", &element, &cnt))
return NULL;
if (PyTuple_Size(args) == 2 && cnt < 0)
@@ -2383,7 +2383,7 @@ repeat_repr(repeatobject *ro)
result = PyString_FromFormat("repeat(%s)",
PyString_AS_STRING(objrepr));
else
- result = PyString_FromFormat("repeat(%s, %ld)",
+ result = PyString_FromFormat("repeat(%s, %zd)",
PyString_AS_STRING(objrepr), ro->cnt);
Py_DECREF(objrepr);
return result;
@@ -2396,7 +2396,7 @@ repeat_len(repeatobject *ro)
PyErr_SetString(PyExc_TypeError, "len() of unsized object");
return NULL;
}
- return PyInt_FromLong(ro->cnt);
+ return PyInt_FromSize_t(ro->cnt);
}
PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
diff --git a/Modules/main.c b/Modules/main.c
index 7326a27..23a760f 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -9,8 +9,10 @@
#endif
#if defined(MS_WINDOWS) || defined(__CYGWIN__)
+#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
+#endif
#if (defined(PYOS_OS2) && !defined(PYCC_GCC)) || defined(MS_WINDOWS)
#define PYTHONHOMEHELP "<prefix>\\lib"
diff --git a/Modules/operator.c b/Modules/operator.c
index cbce16e..bf3def4 100644
--- a/Modules/operator.c
+++ b/Modules/operator.c
@@ -48,6 +48,12 @@ used for special class methods; variants without leading and trailing\n\
if(-1 == (r=AOP(a1,a2))) return NULL; \
return PyInt_FromLong(r); }
+#define spamn2(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
+ PyObject *a1, *a2; Py_ssize_t r; \
+ if(! PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2)) return NULL; \
+ if(-1 == (r=AOP(a1,a2))) return NULL; \
+ return PyInt_FromSsize_t(r); }
+
#define spami2b(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \
PyObject *a1, *a2; long r; \
if(! PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2)) return NULL; \
@@ -97,8 +103,8 @@ spam2(op_iconcat , PySequence_InPlaceConcat)
spamoi(op_irepeat , PySequence_InPlaceRepeat)
spami2b(op_contains , PySequence_Contains)
spami2b(sequenceIncludes, PySequence_Contains)
-spami2(indexOf , PySequence_Index)
-spami2(countOf , PySequence_Count)
+spamn2(indexOf , PySequence_Index)
+spamn2(countOf , PySequence_Count)
spami(isMappingType , PyMapping_Check)
spam2(op_getitem , PyObject_GetItem)
spam2n(op_delitem , PyObject_DelItem)
diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c
index c9edae6..e33197e 100644
--- a/Modules/parsermodule.c
+++ b/Modules/parsermodule.c
@@ -3267,8 +3267,8 @@ initparser(void)
&& (pickler != NULL)) {
PyObject *res;
- res = PyObject_CallFunction(func, "OOO", &PyST_Type, pickler,
- pickle_constructor);
+ res = PyObject_CallFunctionObjArgs(func, &PyST_Type, pickler,
+ pickle_constructor, NULL);
Py_XDECREF(res);
}
Py_XDECREF(func);
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index b51ba5d..7f0a261 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -13,6 +13,18 @@
/* See also ../Dos/dosmodule.c */
+#ifdef __APPLE__
+ /*
+ * Step 1 of support for weak-linking a number of symbols existing on
+ * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
+ * at the end of this file for more information.
+ */
+# pragma weak lchown
+# pragma weak statvfs
+# pragma weak fstatvfs
+
+#endif /* __APPLE__ */
+
#define PY_SSIZE_T_CLEAN
#include "Python.h"
@@ -250,7 +262,11 @@ extern int lstat(const char *, struct stat *);
#endif /* OS2 */
#ifndef MAXPATHLEN
+#if defined(PATH_MAX) && PATH_MAX > 1024
+#define MAXPATHLEN PATH_MAX
+#else
#define MAXPATHLEN 1024
+#endif
#endif /* MAXPATHLEN */
#ifdef UNION_WAIT
@@ -442,21 +458,29 @@ win32_error_unicode(char* function, Py_UNICODE* filename)
static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
{
- /* XXX Perhaps we should make this API an alias of
- PyObject_Unicode() instead ?! */
- if (PyUnicode_CheckExact(obj)) {
- Py_INCREF(obj);
- return obj;
- }
- if (PyUnicode_Check(obj)) {
+}
+
+/* Function suitable for O& conversion */
+static int
+convert_to_unicode(PyObject *arg, void* _param)
+{
+ PyObject **param = (PyObject**)_param;
+ if (PyUnicode_CheckExact(arg)) {
+ Py_INCREF(arg);
+ *param = arg;
+ }
+ else if (PyUnicode_Check(arg)) {
/* For a Unicode subtype that's not a Unicode object,
return a true Unicode object with the same data. */
- return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
- PyUnicode_GET_SIZE(obj));
+ *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(arg),
+ PyUnicode_GET_SIZE(arg));
+ return *param != NULL;
}
- return PyUnicode_FromEncodedObject(obj,
- Py_FileSystemDefaultEncoding,
- "strict");
+ else
+ *param = PyUnicode_FromEncodedObject(arg,
+ Py_FileSystemDefaultEncoding,
+ "strict");
+ return (*param) != NULL;
}
#endif /* Py_WIN_WIDE_FILENAMES */
@@ -573,35 +597,10 @@ unicode_file_names(void)
#endif
static PyObject *
-posix_1str(PyObject *args, char *format, int (*func)(const char*),
- char *wformat, int (*wfunc)(const Py_UNICODE*))
+posix_1str(PyObject *args, char *format, int (*func)(const char*))
{
char *path1 = NULL;
int res;
-#ifdef Py_WIN_WIDE_FILENAMES
- if (unicode_file_names()) {
- PyUnicodeObject *po;
- if (PyArg_ParseTuple(args, wformat, &po)) {
- Py_BEGIN_ALLOW_THREADS
- /* PyUnicode_AS_UNICODE OK without thread
- lock as it is a simple dereference. */
- res = (*wfunc)(PyUnicode_AS_UNICODE(po));
- Py_END_ALLOW_THREADS
- if (res < 0)
- return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po));
- Py_INCREF(Py_None);
- return Py_None;
- }
- /* Drop the argument parsing error as narrow
- strings are also valid. */
- PyErr_Clear();
- }
-#else
- /* Platforms that don't support Unicode filenames
- shouldn't be passing these extra params */
- assert(wformat==NULL && wfunc == NULL);
-#endif
-
if (!PyArg_ParseTuple(args, format,
Py_FileSystemDefaultEncoding, &path1))
return NULL;
@@ -618,52 +617,10 @@ posix_1str(PyObject *args, char *format, int (*func)(const char*),
static PyObject *
posix_2str(PyObject *args,
char *format,
- int (*func)(const char *, const char *),
- char *wformat,
- int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *))
+ int (*func)(const char *, const char *))
{
char *path1 = NULL, *path2 = NULL;
int res;
-#ifdef Py_WIN_WIDE_FILENAMES
- if (unicode_file_names()) {
- PyObject *po1;
- PyObject *po2;
- if (PyArg_ParseTuple(args, wformat, &po1, &po2)) {
- if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) {
- PyObject *wpath1;
- PyObject *wpath2;
- wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1);
- wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2);
- if (!wpath1 || !wpath2) {
- Py_XDECREF(wpath1);
- Py_XDECREF(wpath2);
- return NULL;
- }
- Py_BEGIN_ALLOW_THREADS
- /* PyUnicode_AS_UNICODE OK without thread
- lock as it is a simple dereference. */
- res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1),
- PyUnicode_AS_UNICODE(wpath2));
- Py_END_ALLOW_THREADS
- Py_XDECREF(wpath1);
- Py_XDECREF(wpath2);
- if (res != 0)
- return posix_error();
- Py_INCREF(Py_None);
- return Py_None;
- }
- /* Else flow through as neither is Unicode. */
- }
- /* Drop the argument parsing error as narrow
- strings are also valid. */
- PyErr_Clear();
- }
-#else
- /* Platforms that don't support Unicode filenames
- shouldn't be passing these extra params */
- assert(wformat==NULL && wfunc == NULL);
-#endif
-
if (!PyArg_ParseTuple(args, format,
Py_FileSystemDefaultEncoding, &path1,
Py_FileSystemDefaultEncoding, &path2))
@@ -680,6 +637,101 @@ posix_2str(PyObject *args,
return Py_None;
}
+#ifdef Py_WIN_WIDE_FILENAMES
+static PyObject*
+win32_1str(PyObject* args, char* func,
+ char* format, BOOL (__stdcall *funcA)(LPCSTR),
+ char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
+{
+ PyObject *uni;
+ char *ansi;
+ BOOL result;
+ if (unicode_file_names()) {
+ if (!PyArg_ParseTuple(args, wformat, &uni))
+ PyErr_Clear();
+ else {
+ Py_BEGIN_ALLOW_THREADS
+ result = funcW(PyUnicode_AsUnicode(uni));
+ Py_END_ALLOW_THREADS
+ if (!result)
+ return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ }
+ if (!PyArg_ParseTuple(args, format, &ansi))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ result = funcA(ansi);
+ Py_END_ALLOW_THREADS
+ if (!result)
+ return win32_error(func, ansi);
+ Py_INCREF(Py_None);
+ return Py_None;
+
+}
+
+/* This is a reimplementation of the C library's chdir function,
+ but one that produces Win32 errors instead of DOS error codes.
+ chdir is essentially a wrapper around SetCurrentDirectory; however,
+ it also needs to set "magic" environment variables indicating
+ the per-drive current directory, which are of the form =<drive>: */
+BOOL __stdcall
+win32_chdir(LPCSTR path)
+{
+ char new_path[MAX_PATH+1];
+ int result;
+ char env[4] = "=x:";
+
+ if(!SetCurrentDirectoryA(path))
+ return FALSE;
+ result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
+ if (!result)
+ return FALSE;
+ /* In the ANSI API, there should not be any paths longer
+ than MAX_PATH. */
+ assert(result <= MAX_PATH+1);
+ if (strncmp(new_path, "\\\\", 2) == 0 ||
+ strncmp(new_path, "//", 2) == 0)
+ /* UNC path, nothing to do. */
+ return TRUE;
+ env[1] = new_path[0];
+ return SetEnvironmentVariableA(env, new_path);
+}
+
+/* The Unicode version differs from the ANSI version
+ since the current directory might exceed MAX_PATH characters */
+BOOL __stdcall
+win32_wchdir(LPCWSTR path)
+{
+ wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
+ int result;
+ wchar_t env[4] = L"=x:";
+
+ if(!SetCurrentDirectoryW(path))
+ return FALSE;
+ result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
+ if (!result)
+ return FALSE;
+ if (result > MAX_PATH+1) {
+ new_path = malloc(result);
+ if (!new_path) {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return FALSE;
+ }
+ }
+ if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
+ wcsncmp(new_path, L"//", 2) == 0)
+ /* UNC path, nothing to do. */
+ return TRUE;
+ env[1] = new_path[0];
+ result = SetEnvironmentVariableW(env, new_path);
+ if (new_path != _new_path)
+ free(new_path);
+ return result;
+}
+#endif
+
#ifdef MS_WINDOWS
/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
- time stamps are restricted to second resolution
@@ -711,13 +763,26 @@ static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 an
static void
FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
{
- /* XXX endianness */
- __int64 in = *(__int64*)in_ptr;
+ /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
+ /* Cannot simply cast and dereference in_ptr,
+ since it might not be aligned properly */
+ __int64 in;
+ memcpy(&in, in_ptr, sizeof(in));
*nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
/* XXX Win32 supports time stamps past 2038; we currently don't */
*time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
}
+static void
+time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
+{
+ /* XXX endianness */
+ __int64 out;
+ out = time_in + secs_between_epochs;
+ out = out * 10000000 + nsec_in;
+ memcpy(out_ptr, &out, sizeof(out));
+}
+
/* Below, we *know* that ugo+r is 0444 */
#if _S_IREAD != 0400
#error Unsupported C library
@@ -1292,24 +1357,39 @@ posix_access(PyObject *self, PyObject *args)
{
char *path;
int mode;
- int res;
-
+
#ifdef Py_WIN_WIDE_FILENAMES
+ DWORD attr;
if (unicode_file_names()) {
PyUnicodeObject *po;
if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
Py_BEGIN_ALLOW_THREADS
/* PyUnicode_AS_UNICODE OK without thread lock as
it is a simple dereference. */
- res = _waccess(PyUnicode_AS_UNICODE(po), mode);
+ attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Py_END_ALLOW_THREADS
- return PyBool_FromLong(res == 0);
+ goto finish;
}
/* Drop the argument parsing error as narrow strings
are also valid. */
PyErr_Clear();
}
-#endif
+ if (!PyArg_ParseTuple(args, "eti:access",
+ Py_FileSystemDefaultEncoding, &path, &mode))
+ return 0;
+ Py_BEGIN_ALLOW_THREADS
+ attr = GetFileAttributesA(path);
+ Py_END_ALLOW_THREADS
+ PyMem_Free(path);
+finish:
+ if (attr == 0xFFFFFFFF)
+ /* File does not exist, or cannot read attributes */
+ return PyBool_FromLong(0);
+ /* Access is possible if either write access wasn't requested, or
+ the file isn't read-only. */
+ return PyBool_FromLong(!(mode & 2) || !(attr && FILE_ATTRIBUTE_READONLY));
+#else
+ int res;
if (!PyArg_ParseTuple(args, "eti:access",
Py_FileSystemDefaultEncoding, &path, &mode))
return NULL;
@@ -1318,6 +1398,7 @@ posix_access(PyObject *self, PyObject *args)
Py_END_ALLOW_THREADS
PyMem_Free(path);
return PyBool_FromLong(res == 0);
+#endif
}
#ifndef F_OK
@@ -1394,14 +1475,13 @@ static PyObject *
posix_chdir(PyObject *self, PyObject *args)
{
#ifdef MS_WINDOWS
- return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
+ return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
#elif defined(PYOS_OS2) && defined(PYCC_GCC)
- return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
+ return posix_1str(args, "et:chdir", _chdir2);
#elif defined(__VMS)
- return posix_1str(args, "et:chdir", (int (*)(const char *))chdir,
- NULL, NULL);
+ return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
#else
- return posix_1str(args, "et:chdir", chdir, NULL, NULL);
+ return posix_1str(args, "et:chdir", chdir);
#endif
}
@@ -1430,14 +1510,24 @@ posix_chmod(PyObject *self, PyObject *args)
int i;
int res;
#ifdef Py_WIN_WIDE_FILENAMES
+ DWORD attr;
if (unicode_file_names()) {
PyUnicodeObject *po;
if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
Py_BEGIN_ALLOW_THREADS
- res = _wchmod(PyUnicode_AS_UNICODE(po), i);
+ attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
+ if (attr != 0xFFFFFFFF) {
+ if (i & _S_IWRITE)
+ attr &= ~FILE_ATTRIBUTE_READONLY;
+ else
+ attr |= FILE_ATTRIBUTE_READONLY;
+ res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
+ }
+ else
+ res = 0;
Py_END_ALLOW_THREADS
- if (res < 0)
- return posix_error_with_unicode_filename(
+ if (!res)
+ return win32_error_unicode("chmod",
PyUnicode_AS_UNICODE(po));
Py_INCREF(Py_None);
return Py_None;
@@ -1446,7 +1536,30 @@ posix_chmod(PyObject *self, PyObject *args)
are also valid. */
PyErr_Clear();
}
-#endif /* Py_WIN_WIDE_FILENAMES */
+ if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
+ &path, &i))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ attr = GetFileAttributesA(path);
+ if (attr != 0xFFFFFFFF) {
+ if (i & _S_IWRITE)
+ attr &= ~FILE_ATTRIBUTE_READONLY;
+ else
+ attr |= FILE_ATTRIBUTE_READONLY;
+ res = SetFileAttributesA(path, attr);
+ }
+ else
+ res = 0;
+ Py_END_ALLOW_THREADS
+ if (!res) {
+ win32_error("chmod", path);
+ PyMem_Free(path);
+ return NULL;
+ }
+ PyMem_Free(path);
+ Py_INCREF(Py_None);
+ return Py_None;
+#else /* Py_WIN_WIDE_FILENAMES */
if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
&path, &i))
return NULL;
@@ -1458,6 +1571,7 @@ posix_chmod(PyObject *self, PyObject *args)
PyMem_Free(path);
Py_INCREF(Py_None);
return Py_None;
+#endif
}
@@ -1469,7 +1583,7 @@ Change root directory to path.");
static PyObject *
posix_chroot(PyObject *self, PyObject *args)
{
- return posix_1str(args, "et:chroot", chroot, NULL, NULL);
+ return posix_1str(args, "et:chroot", chroot);
}
#endif
@@ -1593,15 +1707,33 @@ posix_getcwdu(PyObject *self, PyObject *noargs)
char *res;
#ifdef Py_WIN_WIDE_FILENAMES
+ DWORD len;
if (unicode_file_names()) {
- wchar_t *wres;
wchar_t wbuf[1026];
+ wchar_t *wbuf2 = wbuf;
+ PyObject *resobj;
Py_BEGIN_ALLOW_THREADS
- wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
+ len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
+ /* If the buffer is large enough, len does not include the
+ terminating \0. If the buffer is too small, len includes
+ the space needed for the terminator. */
+ if (len >= sizeof wbuf/ sizeof wbuf[0]) {
+ wbuf2 = malloc(len * sizeof(wchar_t));
+ if (wbuf2)
+ len = GetCurrentDirectoryW(len, wbuf2);
+ }
Py_END_ALLOW_THREADS
- if (wres == NULL)
- return posix_error();
- return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
+ if (!wbuf2) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ if (!len) {
+ if (wbuf2 != wbuf) free(wbuf2);
+ return win32_error("getcwdu", NULL);
+ }
+ resobj = PyUnicode_FromWideChar(wbuf2, len);
+ if (wbuf2 != wbuf) free(wbuf2);
+ return resobj;
}
#endif
@@ -1628,7 +1760,7 @@ Create a hard link to a file.");
static PyObject *
posix_link(PyObject *self, PyObject *args)
{
- return posix_2str(args, "etet:link", link, NULL, NULL);
+ return posix_2str(args, "etet:link", link);
}
#endif /* HAVE_LINK */
@@ -1653,37 +1785,46 @@ posix_listdir(PyObject *self, PyObject *args)
HANDLE hFindFile;
BOOL result;
WIN32_FIND_DATA FileData;
- /* MAX_PATH characters could mean a bigger encoded string */
- char namebuf[MAX_PATH*2+5];
+ char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
char *bufptr = namebuf;
- Py_ssize_t len = sizeof(namebuf)/sizeof(namebuf[0]);
+ Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
#ifdef Py_WIN_WIDE_FILENAMES
/* If on wide-character-capable OS see if argument
is Unicode and if so use wide API. */
if (unicode_file_names()) {
- PyUnicodeObject *po;
+ PyObject *po;
if (PyArg_ParseTuple(args, "U:listdir", &po)) {
WIN32_FIND_DATAW wFileData;
- Py_UNICODE wnamebuf[MAX_PATH*2+5];
+ Py_UNICODE *wnamebuf;
Py_UNICODE wch;
- wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
- wnamebuf[MAX_PATH] = L'\0';
- len = wcslen(wnamebuf);
- wch = (len > 0) ? wnamebuf[len-1] : L'\0';
+ /* Overallocate for \\*.*\0 */
+ len = PyUnicode_GET_SIZE(po);
+ wnamebuf = malloc((len + 5) * sizeof(wchar_t));
+ if (!wnamebuf) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
+ wch = len > 0 ? wnamebuf[len-1] : '\0';
if (wch != L'/' && wch != L'\\' && wch != L':')
- wnamebuf[len++] = L'/';
+ wnamebuf[len++] = L'\\';
wcscpy(wnamebuf + len, L"*.*");
- if ((d = PyList_New(0)) == NULL)
+ if ((d = PyList_New(0)) == NULL) {
+ free(wnamebuf);
return NULL;
+ }
hFindFile = FindFirstFileW(wnamebuf, &wFileData);
if (hFindFile == INVALID_HANDLE_VALUE) {
- errno = GetLastError();
- if (errno == ERROR_FILE_NOT_FOUND) {
+ int error = GetLastError();
+ if (error == ERROR_FILE_NOT_FOUND) {
+ free(wnamebuf);
return d;
}
Py_DECREF(d);
- return win32_error_unicode("FindFirstFileW", wnamebuf);
+ win32_error_unicode("FindFirstFileW", wnamebuf);
+ free(wnamebuf);
+ return NULL;
}
do {
/* Skip over . and .. */
@@ -1710,8 +1851,11 @@ posix_listdir(PyObject *self, PyObject *args)
if (FindClose(hFindFile) == FALSE) {
Py_DECREF(d);
- return win32_error_unicode("FindClose", wnamebuf);
+ win32_error_unicode("FindClose", wnamebuf);
+ free(wnamebuf);
+ return NULL;
}
+ free(wnamebuf);
return d;
}
/* Drop the argument parsing error as narrow strings
@@ -1735,8 +1879,8 @@ posix_listdir(PyObject *self, PyObject *args)
hFindFile = FindFirstFile(namebuf, &FileData);
if (hFindFile == INVALID_HANDLE_VALUE) {
- errno = GetLastError();
- if (errno == ERROR_FILE_NOT_FOUND)
+ int error = GetLastError();
+ if (error == ERROR_FILE_NOT_FOUND)
return d;
Py_DECREF(d);
return win32_error("FindFirstFile", namebuf);
@@ -1982,10 +2126,10 @@ posix_mkdir(PyObject *self, PyObject *args)
Py_BEGIN_ALLOW_THREADS
/* PyUnicode_AS_UNICODE OK without thread lock as
it is a simple dereference. */
- res = _wmkdir(PyUnicode_AS_UNICODE(po));
+ res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Py_END_ALLOW_THREADS
- if (res < 0)
- return posix_error();
+ if (!res)
+ return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Py_INCREF(Py_None);
return Py_None;
}
@@ -1993,13 +2137,29 @@ posix_mkdir(PyObject *self, PyObject *args)
are also valid. */
PyErr_Clear();
}
-#endif
+ if (!PyArg_ParseTuple(args, "et|i:mkdir",
+ Py_FileSystemDefaultEncoding, &path, &mode))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ /* PyUnicode_AS_UNICODE OK without thread lock as
+ it is a simple dereference. */
+ res = CreateDirectoryA(path, NULL);
+ Py_END_ALLOW_THREADS
+ if (!res) {
+ win32_error("mkdir", path);
+ PyMem_Free(path);
+ return NULL;
+ }
+ PyMem_Free(path);
+ Py_INCREF(Py_None);
+ return Py_None;
+#else
if (!PyArg_ParseTuple(args, "et|i:mkdir",
Py_FileSystemDefaultEncoding, &path, &mode))
return NULL;
Py_BEGIN_ALLOW_THREADS
-#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
+#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
res = mkdir(path);
#else
res = mkdir(path, mode);
@@ -2010,6 +2170,7 @@ posix_mkdir(PyObject *self, PyObject *args)
PyMem_Free(path);
Py_INCREF(Py_None);
return Py_None;
+#endif
}
@@ -2055,7 +2216,6 @@ posix_nice(PyObject *self, PyObject *args)
}
#endif /* HAVE_NICE */
-
PyDoc_STRVAR(posix_rename__doc__,
"rename(old, new)\n\n\
Rename a file or directory.");
@@ -2064,9 +2224,38 @@ static PyObject *
posix_rename(PyObject *self, PyObject *args)
{
#ifdef MS_WINDOWS
- return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
+ PyObject *o1, *o2;
+ char *p1, *p2;
+ BOOL result;
+ if (unicode_file_names()) {
+ if (!PyArg_ParseTuple(args, "O&O&:rename",
+ convert_to_unicode, &o1,
+ convert_to_unicode, &o2))
+ PyErr_Clear();
+ else {
+ Py_BEGIN_ALLOW_THREADS
+ result = MoveFileW(PyUnicode_AsUnicode(o1),
+ PyUnicode_AsUnicode(o2));
+ Py_END_ALLOW_THREADS
+ Py_DECREF(o1);
+ Py_DECREF(o2);
+ if (!result)
+ return win32_error("rename", NULL);
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ }
+ if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ result = MoveFileA(p1, p2);
+ Py_END_ALLOW_THREADS
+ if (!result)
+ return win32_error("rename", NULL);
+ Py_INCREF(Py_None);
+ return Py_None;
#else
- return posix_2str(args, "etet:rename", rename, NULL, NULL);
+ return posix_2str(args, "etet:rename", rename);
#endif
}
@@ -2079,9 +2268,9 @@ static PyObject *
posix_rmdir(PyObject *self, PyObject *args)
{
#ifdef MS_WINDOWS
- return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
+ return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
#else
- return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
+ return posix_1str(args, "et:rmdir", rmdir);
#endif
}
@@ -2150,9 +2339,9 @@ static PyObject *
posix_unlink(PyObject *self, PyObject *args)
{
#ifdef MS_WINDOWS
- return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
+ return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
#else
- return posix_1str(args, "et:remove", unlink, NULL, NULL);
+ return posix_1str(args, "et:remove", unlink);
#endif
}
@@ -2212,7 +2401,7 @@ extract_time(PyObject *t, long* sec, long* usec)
}
PyDoc_STRVAR(posix_utime__doc__,
-"utime(path, (atime, utime))\n\
+"utime(path, (atime, mtime))\n\
utime(path, None)\n\n\
Set the access and modified time of the file to the given values. If the\n\
second form is used, set the access and modified times to the current time.");
@@ -2220,6 +2409,84 @@ second form is used, set the access and modified times to the current time.");
static PyObject *
posix_utime(PyObject *self, PyObject *args)
{
+#ifdef Py_WIN_WIDE_FILENAMES
+ PyObject *arg;
+ PyUnicodeObject *obwpath;
+ wchar_t *wpath = NULL;
+ char *apath = NULL;
+ HANDLE hFile;
+ long atimesec, mtimesec, ausec, musec;
+ FILETIME atime, mtime;
+ PyObject *result = NULL;
+
+ if (unicode_file_names()) {
+ if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
+ wpath = PyUnicode_AS_UNICODE(obwpath);
+ Py_BEGIN_ALLOW_THREADS
+ hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
+ NULL, OPEN_EXISTING, 0, NULL);
+ Py_END_ALLOW_THREADS
+ if (hFile == INVALID_HANDLE_VALUE)
+ return win32_error_unicode("utime", wpath);
+ } else
+ /* Drop the argument parsing error as narrow strings
+ are also valid. */
+ PyErr_Clear();
+ }
+ if (!wpath) {
+ if (!PyArg_ParseTuple(args, "etO:utime",
+ Py_FileSystemDefaultEncoding, &apath, &arg))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
+ NULL, OPEN_EXISTING, 0, NULL);
+ Py_END_ALLOW_THREADS
+ if (hFile == INVALID_HANDLE_VALUE) {
+ win32_error("utime", apath);
+ PyMem_Free(apath);
+ return NULL;
+ }
+ PyMem_Free(apath);
+ }
+
+ if (arg == Py_None) {
+ SYSTEMTIME now;
+ GetSystemTime(&now);
+ if (!SystemTimeToFileTime(&now, &mtime) ||
+ !SystemTimeToFileTime(&now, &atime)) {
+ win32_error("utime", NULL);
+ goto done;
+ }
+ }
+ else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "utime() arg 2 must be a tuple (atime, mtime)");
+ goto done;
+ }
+ else {
+ if (extract_time(PyTuple_GET_ITEM(arg, 0),
+ &atimesec, &ausec) == -1)
+ goto done;
+ time_t_to_FILE_TIME(atimesec, ausec, &atime);
+ if (extract_time(PyTuple_GET_ITEM(arg, 1),
+ &mtimesec, &musec) == -1)
+ goto done;
+ time_t_to_FILE_TIME(mtimesec, musec, &mtime);
+ }
+ if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
+ /* Avoid putting the file name into the error here,
+ as that may confuse the user into believing that
+ something is wrong with the file, when it also
+ could be the time stamp that gives a problem. */
+ win32_error("utime", NULL);
+ }
+ Py_INCREF(Py_None);
+ result = Py_None;
+done:
+ CloseHandle(hFile);
+ return result;
+#else /* Py_WIN_WIDE_FILENAMES */
+
char *path = NULL;
long atime, mtime, ausec, musec;
int res;
@@ -2242,33 +2509,13 @@ posix_utime(PyObject *self, PyObject *args)
#define UTIME_ARG buf
#endif /* HAVE_UTIMES */
- int have_unicode_filename = 0;
-#ifdef Py_WIN_WIDE_FILENAMES
- PyUnicodeObject *obwpath;
- wchar_t *wpath;
- if (unicode_file_names()) {
- if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
- wpath = PyUnicode_AS_UNICODE(obwpath);
- have_unicode_filename = 1;
- } else
- /* Drop the argument parsing error as narrow strings
- are also valid. */
- PyErr_Clear();
- }
-#endif /* Py_WIN_WIDE_FILENAMES */
- if (!have_unicode_filename && \
- !PyArg_ParseTuple(args, "etO:utime",
+ if (!PyArg_ParseTuple(args, "etO:utime",
Py_FileSystemDefaultEncoding, &path, &arg))
return NULL;
if (arg == Py_None) {
/* optional time values not given */
Py_BEGIN_ALLOW_THREADS
-#ifdef Py_WIN_WIDE_FILENAMES
- if (have_unicode_filename)
- res = _wutime(wpath, NULL);
- else
-#endif /* Py_WIN_WIDE_FILENAMES */
res = utime(path, NULL);
Py_END_ALLOW_THREADS
}
@@ -2299,23 +2546,11 @@ posix_utime(PyObject *self, PyObject *args)
Py_END_ALLOW_THREADS
#else
Py_BEGIN_ALLOW_THREADS
-#ifdef Py_WIN_WIDE_FILENAMES
- if (have_unicode_filename)
- /* utime is OK with utimbuf, but _wutime insists
- on _utimbuf (the msvc headers assert the
- underscore version is ansi) */
- res = _wutime(wpath, (struct _utimbuf *)UTIME_ARG);
- else
-#endif /* Py_WIN_WIDE_FILENAMES */
res = utime(path, UTIME_ARG);
Py_END_ALLOW_THREADS
#endif /* HAVE_UTIMES */
}
if (res < 0) {
-#ifdef Py_WIN_WIDE_FILENAMES
- if (have_unicode_filename)
- return posix_error_with_unicode_filename(wpath);
-#endif /* Py_WIN_WIDE_FILENAMES */
return posix_error_with_allocated_filename(path);
}
PyMem_Free(path);
@@ -2324,6 +2559,7 @@ posix_utime(PyObject *self, PyObject *args)
#undef UTIME_ARG
#undef ATIME
#undef MTIME
+#endif /* Py_WIN_WIDE_FILENAMES */
}
@@ -2440,7 +2676,7 @@ posix_execve(PyObject *self, PyObject *args)
PyObject *key, *val, *keys=NULL, *vals=NULL;
Py_ssize_t i, pos, argc, envc;
PyObject *(*getitem)(PyObject *, Py_ssize_t);
- int lastarg = 0;
+ Py_ssize_t lastarg = 0;
/* execve has three arguments: (path, argv, env), where
argv is a list or tuple of strings and env is a dictionary
@@ -2581,7 +2817,8 @@ posix_spawnv(PyObject *self, PyObject *args)
char *path;
PyObject *argv;
char **argvlist;
- int mode, i, argc;
+ int mode, i;
+ Py_ssize_t argc;
Py_intptr_t spawnval;
PyObject *(*getitem)(PyObject *, Py_ssize_t);
@@ -2670,10 +2907,11 @@ posix_spawnve(PyObject *self, PyObject *args)
char **argvlist;
char **envlist;
PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
- int mode, i, pos, argc, envc;
+ int mode, pos, envc;
+ Py_ssize_t argc, i;
Py_intptr_t spawnval;
PyObject *(*getitem)(PyObject *, Py_ssize_t);
- int lastarg = 0;
+ Py_ssize_t lastarg = 0;
/* spawnve has four arguments: (mode, path, argv, env), where
argv is a list or tuple of strings and env is a dictionary
@@ -4374,7 +4612,7 @@ _PyPopenCreateProcess(char *cmdstring,
char modulepath[_MAX_PATH];
struct stat statinfo;
GetModuleFileName(NULL, modulepath, sizeof(modulepath));
- for (i = x = 0; modulepath[i]; i++)
+ for (x = i = 0; modulepath[i]; i++)
if (modulepath[i] == SEP)
x = i+1;
modulepath[x] = '\0';
@@ -4551,7 +4789,7 @@ _PyPopen(char *cmdstring, int mode, int n)
switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
case _O_WRONLY | _O_TEXT:
/* Case for writing to child Stdin in text mode. */
- fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
+ fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
f1 = _fdopen(fd1, "w");
f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
PyFile_SetBufSize(f, 0);
@@ -4562,7 +4800,7 @@ _PyPopen(char *cmdstring, int mode, int n)
case _O_RDONLY | _O_TEXT:
/* Case for reading from child Stdout in text mode. */
- fd1 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
+ fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
f1 = _fdopen(fd1, "r");
f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
PyFile_SetBufSize(f, 0);
@@ -4573,7 +4811,7 @@ _PyPopen(char *cmdstring, int mode, int n)
case _O_RDONLY | _O_BINARY:
/* Case for readinig from child Stdout in binary mode. */
- fd1 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
+ fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
f1 = _fdopen(fd1, "rb");
f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
PyFile_SetBufSize(f, 0);
@@ -4584,7 +4822,7 @@ _PyPopen(char *cmdstring, int mode, int n)
case _O_WRONLY | _O_BINARY:
/* Case for writing to child Stdin in binary mode. */
- fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
+ fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
f1 = _fdopen(fd1, "wb");
f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
PyFile_SetBufSize(f, 0);
@@ -4610,9 +4848,9 @@ _PyPopen(char *cmdstring, int mode, int n)
m2 = "wb";
}
- fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
+ fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
f1 = _fdopen(fd1, m2);
- fd2 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
+ fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
f2 = _fdopen(fd2, m1);
p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
PyFile_SetBufSize(p1, 0);
@@ -4642,11 +4880,11 @@ _PyPopen(char *cmdstring, int mode, int n)
m2 = "wb";
}
- fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
+ fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
f1 = _fdopen(fd1, m2);
- fd2 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
+ fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
f2 = _fdopen(fd2, m1);
- fd3 = _open_osfhandle((intptr_t)hChildStderrRdDup, mode);
+ fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
f3 = _fdopen(fd3, m1);
p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
@@ -5250,7 +5488,7 @@ PyDoc_STRVAR(posix_waitpid__doc__,
static PyObject *
posix_waitpid(PyObject *self, PyObject *args)
{
- intptr_t pid;
+ Py_intptr_t pid;
int status, options;
if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
@@ -5339,7 +5577,7 @@ Create a symbolic link pointing to src named dst.");
static PyObject *
posix_symlink(PyObject *self, PyObject *args)
{
- return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
+ return posix_2str(args, "etet:symlink", symlink);
}
#endif /* HAVE_SYMLINK */
@@ -6280,7 +6518,7 @@ posix_WSTOPSIG(PyObject *self, PyObject *args)
#endif /* HAVE_SYS_WAIT_H */
-#if defined(HAVE_FSTATVFS)
+#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
#ifdef _SCO_DS
/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
needed definitions in sys/statvfs.h */
@@ -6347,10 +6585,10 @@ posix_fstatvfs(PyObject *self, PyObject *args)
return _pystatvfs_fromstructstatvfs(st);
}
-#endif /* HAVE_FSTATVFS */
+#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
-#if defined(HAVE_STATVFS)
+#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
#include <sys/statvfs.h>
PyDoc_STRVAR(posix_statvfs__doc__,
@@ -7888,10 +8126,10 @@ static PyMethodDef posix_methods[] = {
{"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
#endif /* WSTOPSIG */
#endif /* HAVE_SYS_WAIT_H */
-#ifdef HAVE_FSTATVFS
+#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
{"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
#endif
-#ifdef HAVE_STATVFS
+#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
{"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
#endif
#ifdef HAVE_TMPFILE
@@ -8264,6 +8502,45 @@ INITFUNC(void)
PyModule_AddObject(m, "statvfs_result",
(PyObject*) &StatVFSResultType);
initialized = 1;
+
+#ifdef __APPLE__
+ /*
+ * Step 2 of weak-linking support on Mac OS X.
+ *
+ * The code below removes functions that are not available on the
+ * currently active platform.
+ *
+ * This block allow one to use a python binary that was build on
+ * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
+ * OSX 10.4.
+ */
+#ifdef HAVE_FSTATVFS
+ if (fstatvfs == NULL) {
+ if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
+ return;
+ }
+ }
+#endif /* HAVE_FSTATVFS */
+
+#ifdef HAVE_STATVFS
+ if (statvfs == NULL) {
+ if (PyObject_DelAttrString(m, "statvfs") == -1) {
+ return;
+ }
+ }
+#endif /* HAVE_STATVFS */
+
+# ifdef HAVE_LCHOWN
+ if (lchown == NULL) {
+ if (PyObject_DelAttrString(m, "lchown") == -1) {
+ return;
+ }
+ }
+#endif /* HAVE_LCHOWN */
+
+
+#endif /* __APPLE__ */
+
}
#ifdef __cplusplus
diff --git a/Modules/rotatingtree.h b/Modules/rotatingtree.h
index 97cc8e8..3aa0986 100644
--- a/Modules/rotatingtree.h
+++ b/Modules/rotatingtree.h
@@ -4,7 +4,7 @@
*
* It's a dict-like data structure that works best when accesses are not
* random, but follow a strong pattern. The one implemented here is for
- * accesses patterns where the same small set of keys is looked up over
+ * access patterns where the same small set of keys is looked up over
* and over again, and this set of keys evolves slowly over time.
*/
diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c
index c9d403a..4a04af1 100644
--- a/Modules/selectmodule.c
+++ b/Modules/selectmodule.c
@@ -8,6 +8,13 @@
#include "Python.h"
+#ifdef __APPLE__
+ /* Perform runtime testing for a broken poll on OSX to make it easier
+ * to use the same binary on multiple releases of the OS.
+ */
+#undef HAVE_BROKEN_POLL
+#endif
+
/* Windows #defines FD_SETSIZE to 64 if FD_SETSIZE isn't already defined.
64 is too small (too many people have bumped into that limit).
Here we boost it.
@@ -618,7 +625,38 @@ select_poll(PyObject *self, PyObject *args)
return NULL;
return (PyObject *)rv;
}
-#endif /* HAVE_POLL && !HAVE_BROKEN_POLL */
+
+#ifdef __APPLE__
+/*
+ * On some systems poll() sets errno on invalid file descriptors. We test
+ * for this at runtime because this bug may be fixed or introduced between
+ * OS releases.
+ */
+static int select_have_broken_poll(void)
+{
+ int poll_test;
+ int filedes[2];
+
+ struct pollfd poll_struct = { 0, POLLIN|POLLPRI|POLLOUT, 0 };
+
+ /* Create a file descriptor to make invalid */
+ if (pipe(filedes) < 0) {
+ return 1;
+ }
+ poll_struct.fd = filedes[0];
+ close(filedes[0]);
+ close(filedes[1]);
+ poll_test = poll(&poll_struct, 1, 0);
+ if (poll_test < 0) {
+ return 1;
+ } else if (poll_test == 0 && poll_struct.revents != POLLNVAL) {
+ return 1;
+ }
+ return 0;
+}
+#endif /* __APPLE__ */
+
+#endif /* HAVE_POLL */
PyDoc_STRVAR(select_doc,
"select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)\n\
@@ -645,9 +683,9 @@ On Windows, only sockets are supported; on Unix, all file descriptors.");
static PyMethodDef select_methods[] = {
{"select", select_select, METH_VARARGS, select_doc},
-#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
+#if defined(HAVE_POLL)
{"poll", select_poll, METH_VARARGS, poll_doc},
-#endif /* HAVE_POLL && !HAVE_BROKEN_POLL */
+#endif /* HAVE_POLL */
{0, 0}, /* sentinel */
};
@@ -668,29 +706,40 @@ initselect(void)
SelectError = PyErr_NewException("select.error", NULL, NULL);
Py_INCREF(SelectError);
PyModule_AddObject(m, "error", SelectError);
-#if defined(HAVE_POLL) && !defined(HAVE_BROKEN_POLL)
- poll_Type.ob_type = &PyType_Type;
- PyModule_AddIntConstant(m, "POLLIN", POLLIN);
- PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
- PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
- PyModule_AddIntConstant(m, "POLLERR", POLLERR);
- PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
- PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
+#if defined(HAVE_POLL)
+
+#ifdef __APPLE__
+ if (select_have_broken_poll()) {
+ if (PyObject_DelAttrString(m, "poll") == -1) {
+ PyErr_Clear();
+ }
+ } else {
+#else
+ {
+#endif
+ poll_Type.ob_type = &PyType_Type;
+ PyModule_AddIntConstant(m, "POLLIN", POLLIN);
+ PyModule_AddIntConstant(m, "POLLPRI", POLLPRI);
+ PyModule_AddIntConstant(m, "POLLOUT", POLLOUT);
+ PyModule_AddIntConstant(m, "POLLERR", POLLERR);
+ PyModule_AddIntConstant(m, "POLLHUP", POLLHUP);
+ PyModule_AddIntConstant(m, "POLLNVAL", POLLNVAL);
#ifdef POLLRDNORM
- PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
+ PyModule_AddIntConstant(m, "POLLRDNORM", POLLRDNORM);
#endif
#ifdef POLLRDBAND
- PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
+ PyModule_AddIntConstant(m, "POLLRDBAND", POLLRDBAND);
#endif
#ifdef POLLWRNORM
- PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
+ PyModule_AddIntConstant(m, "POLLWRNORM", POLLWRNORM);
#endif
#ifdef POLLWRBAND
- PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
+ PyModule_AddIntConstant(m, "POLLWRBAND", POLLWRBAND);
#endif
#ifdef POLLMSG
- PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
+ PyModule_AddIntConstant(m, "POLLMSG", POLLMSG);
#endif
-#endif /* HAVE_POLL && !HAVE_BROKEN_POLL */
+ }
+#endif /* HAVE_POLL */
}
diff --git a/Modules/sha512module.c b/Modules/sha512module.c
index 539204e..c5a85ff 100644
--- a/Modules/sha512module.c
+++ b/Modules/sha512module.c
@@ -121,12 +121,12 @@ static void SHAcopy(SHAobject *src, SHAobject *dest)
/* Various logical functions */
#define ROR64(x, y) \
- ( ((((x) & 0xFFFFFFFFFFFFFFFFULL)>>((unsigned PY_LONG_LONG)(y) & 63)) | \
- ((x)<<((unsigned PY_LONG_LONG)(64-((y) & 63))))) & 0xFFFFFFFFFFFFFFFFULL)
+ ( ((((x) & Py_ULL(0xFFFFFFFFFFFFFFFF))>>((unsigned PY_LONG_LONG)(y) & 63)) | \
+ ((x)<<((unsigned PY_LONG_LONG)(64-((y) & 63))))) & Py_ULL(0xFFFFFFFFFFFFFFFF))
#define Ch(x,y,z) (z ^ (x & (y ^ z)))
#define Maj(x,y,z) (((x | y) & z) | (x & y))
#define S(x, n) ROR64((x),(n))
-#define R(x, n) (((x) & 0xFFFFFFFFFFFFFFFFULL) >> ((unsigned PY_LONG_LONG)n))
+#define R(x, n) (((x) & Py_ULL(0xFFFFFFFFFFFFFFFF)) >> ((unsigned PY_LONG_LONG)n))
#define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39))
#define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41))
#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7))
@@ -156,86 +156,86 @@ sha512_transform(SHAobject *sha_info)
d += t0; \
h = t0 + t1;
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98d728ae22ULL);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x7137449123ef65cdULL);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcfec4d3b2fULL);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba58189dbbcULL);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25bf348b538ULL);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1b605d019ULL);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4af194f9bULL);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5da6d8118ULL);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98a3030242ULL);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b0145706fbeULL);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be4ee4b28cULL);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3d5ffb4e2ULL);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74f27b896fULL);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe3b1696b1ULL);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a725c71235ULL);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174cf692694ULL);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c19ef14ad2ULL);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786384f25e3ULL);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc68b8cd5b5ULL);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc77ac9c65ULL);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f592b0275ULL);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa6ea6e483ULL);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dcbd41fbd4ULL);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da831153b5ULL);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152ee66dfabULL);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d2db43210ULL);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c898fb213fULL);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7beef0ee4ULL);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf33da88fc2ULL);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147930aa725ULL);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351e003826fULL);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x142929670a0e6e70ULL);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a8546d22ffcULL);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b21385c26c926ULL);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc5ac42aedULL);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d139d95b3dfULL);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a73548baf63deULL);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb3c77b2a8ULL);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e47edaee6ULL);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c851482353bULL);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a14cf10364ULL);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664bbc423001ULL);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70d0f89791ULL);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a30654be30ULL);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819d6ef5218ULL);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd69906245565a910ULL);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e35855771202aULL);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa07032bbd1b8ULL);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116b8d2d0c8ULL);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c085141ab53ULL);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774cdf8eeb99ULL);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5e19b48a8ULL);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3c5c95a63ULL);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4ae3418acbULL);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f7763e373ULL);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3d6b2b8a3ULL);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee5defb2fcULL);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f43172f60ULL);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814a1f0ab72ULL);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc702081a6439ecULL);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa23631e28ULL);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506cebde82bde9ULL);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7b2c67915ULL);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2e372532bULL);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],64,0xca273eceea26619cULL);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],65,0xd186b8c721c0c207ULL);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],66,0xeada7dd6cde0eb1eULL);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],67,0xf57d4f7fee6ed178ULL);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],68,0x06f067aa72176fbaULL);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],69,0x0a637dc5a2c898a6ULL);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],70,0x113f9804bef90daeULL);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],71,0x1b710b35131c471bULL);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],72,0x28db77f523047d84ULL);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],73,0x32caab7b40c72493ULL);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],74,0x3c9ebe0a15c9bebcULL);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],75,0x431d67c49c100d4cULL);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],76,0x4cc5d4becb3e42b6ULL);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],77,0x597f299cfc657e2aULL);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],78,0x5fcb6fab3ad6faecULL);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],79,0x6c44198c4a475817ULL);
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,Py_ULL(0x428a2f98d728ae22));
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,Py_ULL(0x7137449123ef65cd));
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,Py_ULL(0xb5c0fbcfec4d3b2f));
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,Py_ULL(0xe9b5dba58189dbbc));
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,Py_ULL(0x3956c25bf348b538));
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,Py_ULL(0x59f111f1b605d019));
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,Py_ULL(0x923f82a4af194f9b));
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,Py_ULL(0xab1c5ed5da6d8118));
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,Py_ULL(0xd807aa98a3030242));
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,Py_ULL(0x12835b0145706fbe));
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,Py_ULL(0x243185be4ee4b28c));
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,Py_ULL(0x550c7dc3d5ffb4e2));
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,Py_ULL(0x72be5d74f27b896f));
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,Py_ULL(0x80deb1fe3b1696b1));
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,Py_ULL(0x9bdc06a725c71235));
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,Py_ULL(0xc19bf174cf692694));
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,Py_ULL(0xe49b69c19ef14ad2));
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,Py_ULL(0xefbe4786384f25e3));
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,Py_ULL(0x0fc19dc68b8cd5b5));
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,Py_ULL(0x240ca1cc77ac9c65));
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,Py_ULL(0x2de92c6f592b0275));
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,Py_ULL(0x4a7484aa6ea6e483));
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,Py_ULL(0x5cb0a9dcbd41fbd4));
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,Py_ULL(0x76f988da831153b5));
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,Py_ULL(0x983e5152ee66dfab));
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,Py_ULL(0xa831c66d2db43210));
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,Py_ULL(0xb00327c898fb213f));
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,Py_ULL(0xbf597fc7beef0ee4));
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,Py_ULL(0xc6e00bf33da88fc2));
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,Py_ULL(0xd5a79147930aa725));
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,Py_ULL(0x06ca6351e003826f));
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,Py_ULL(0x142929670a0e6e70));
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,Py_ULL(0x27b70a8546d22ffc));
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,Py_ULL(0x2e1b21385c26c926));
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,Py_ULL(0x4d2c6dfc5ac42aed));
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,Py_ULL(0x53380d139d95b3df));
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,Py_ULL(0x650a73548baf63de));
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,Py_ULL(0x766a0abb3c77b2a8));
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,Py_ULL(0x81c2c92e47edaee6));
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,Py_ULL(0x92722c851482353b));
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,Py_ULL(0xa2bfe8a14cf10364));
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,Py_ULL(0xa81a664bbc423001));
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,Py_ULL(0xc24b8b70d0f89791));
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,Py_ULL(0xc76c51a30654be30));
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,Py_ULL(0xd192e819d6ef5218));
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,Py_ULL(0xd69906245565a910));
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,Py_ULL(0xf40e35855771202a));
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,Py_ULL(0x106aa07032bbd1b8));
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,Py_ULL(0x19a4c116b8d2d0c8));
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,Py_ULL(0x1e376c085141ab53));
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,Py_ULL(0x2748774cdf8eeb99));
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,Py_ULL(0x34b0bcb5e19b48a8));
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,Py_ULL(0x391c0cb3c5c95a63));
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,Py_ULL(0x4ed8aa4ae3418acb));
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,Py_ULL(0x5b9cca4f7763e373));
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,Py_ULL(0x682e6ff3d6b2b8a3));
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,Py_ULL(0x748f82ee5defb2fc));
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,Py_ULL(0x78a5636f43172f60));
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,Py_ULL(0x84c87814a1f0ab72));
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,Py_ULL(0x8cc702081a6439ec));
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,Py_ULL(0x90befffa23631e28));
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,Py_ULL(0xa4506cebde82bde9));
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,Py_ULL(0xbef9a3f7b2c67915));
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,Py_ULL(0xc67178f2e372532b));
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],64,Py_ULL(0xca273eceea26619c));
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],65,Py_ULL(0xd186b8c721c0c207));
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],66,Py_ULL(0xeada7dd6cde0eb1e));
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],67,Py_ULL(0xf57d4f7fee6ed178));
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],68,Py_ULL(0x06f067aa72176fba));
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],69,Py_ULL(0x0a637dc5a2c898a6));
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],70,Py_ULL(0x113f9804bef90dae));
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],71,Py_ULL(0x1b710b35131c471b));
+ RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],72,Py_ULL(0x28db77f523047d84));
+ RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],73,Py_ULL(0x32caab7b40c72493));
+ RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],74,Py_ULL(0x3c9ebe0a15c9bebc));
+ RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],75,Py_ULL(0x431d67c49c100d4c));
+ RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],76,Py_ULL(0x4cc5d4becb3e42b6));
+ RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],77,Py_ULL(0x597f299cfc657e2a));
+ RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],78,Py_ULL(0x5fcb6fab3ad6faec));
+ RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],79,Py_ULL(0x6c44198c4a475817));
#undef RND
@@ -254,14 +254,14 @@ static void
sha512_init(SHAobject *sha_info)
{
TestEndianness(sha_info->Endianness)
- sha_info->digest[0] = 0x6a09e667f3bcc908ULL;
- sha_info->digest[1] = 0xbb67ae8584caa73bULL;
- sha_info->digest[2] = 0x3c6ef372fe94f82bULL;
- sha_info->digest[3] = 0xa54ff53a5f1d36f1ULL;
- sha_info->digest[4] = 0x510e527fade682d1ULL;
- sha_info->digest[5] = 0x9b05688c2b3e6c1fULL;
- sha_info->digest[6] = 0x1f83d9abfb41bd6bULL;
- sha_info->digest[7] = 0x5be0cd19137e2179ULL;
+ sha_info->digest[0] = Py_ULL(0x6a09e667f3bcc908);
+ sha_info->digest[1] = Py_ULL(0xbb67ae8584caa73b);
+ sha_info->digest[2] = Py_ULL(0x3c6ef372fe94f82b);
+ sha_info->digest[3] = Py_ULL(0xa54ff53a5f1d36f1);
+ sha_info->digest[4] = Py_ULL(0x510e527fade682d1);
+ sha_info->digest[5] = Py_ULL(0x9b05688c2b3e6c1f);
+ sha_info->digest[6] = Py_ULL(0x1f83d9abfb41bd6b);
+ sha_info->digest[7] = Py_ULL(0x5be0cd19137e2179);
sha_info->count_lo = 0L;
sha_info->count_hi = 0L;
sha_info->local = 0;
@@ -272,14 +272,14 @@ static void
sha384_init(SHAobject *sha_info)
{
TestEndianness(sha_info->Endianness)
- sha_info->digest[0] = 0xcbbb9d5dc1059ed8ULL;
- sha_info->digest[1] = 0x629a292a367cd507ULL;
- sha_info->digest[2] = 0x9159015a3070dd17ULL;
- sha_info->digest[3] = 0x152fecd8f70e5939ULL;
- sha_info->digest[4] = 0x67332667ffc00b31ULL;
- sha_info->digest[5] = 0x8eb44a8768581511ULL;
- sha_info->digest[6] = 0xdb0c2e0d64f98fa7ULL;
- sha_info->digest[7] = 0x47b5481dbefa4fa4ULL;
+ sha_info->digest[0] = Py_ULL(0xcbbb9d5dc1059ed8);
+ sha_info->digest[1] = Py_ULL(0x629a292a367cd507);
+ sha_info->digest[2] = Py_ULL(0x9159015a3070dd17);
+ sha_info->digest[3] = Py_ULL(0x152fecd8f70e5939);
+ sha_info->digest[4] = Py_ULL(0x67332667ffc00b31);
+ sha_info->digest[5] = Py_ULL(0x8eb44a8768581511);
+ sha_info->digest[6] = Py_ULL(0xdb0c2e0d64f98fa7);
+ sha_info->digest[7] = Py_ULL(0x47b5481dbefa4fa4);
sha_info->count_lo = 0L;
sha_info->count_hi = 0L;
sha_info->local = 0;
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index c9dd4a3..164a5d1 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -61,6 +61,15 @@ Local naming conventions:
*/
+#ifdef __APPLE__
+ /*
+ * inet_aton is not available on OSX 10.3, yet we want to use a binary
+ * that was build on 10.4 or later to work on that release, weak linking
+ * comes to the rescue.
+ */
+# pragma weak inet_aton
+#endif
+
#include "Python.h"
#include "structmember.h"
@@ -95,7 +104,10 @@ gettimeout() -- return timeout or None\n\
listen(n) -- start listening for incoming connections\n\
makefile([mode, [bufsize]]) -- return a file object for the socket [*]\n\
recv(buflen[, flags]) -- receive data\n\
-recvfrom(buflen[, flags]) -- receive data and sender's address\n\
+recv_buf(buffer[, nbytes[, flags]]) -- receive data (into a buffer)\n\
+recvfrom(buflen[, flags]) -- receive data and sender\'s address\n\
+recvfrom_buf(buffer[, nbytes, [, flags])\n\
+ -- receive data and sender\'s address (into a buffer)\n\
sendall(data[, flags]) -- send all data\n\
send(data[, flags]) -- send data, may not send all of it\n\
sendto(data[, flags], addr) -- send data to a given address\n\
@@ -196,7 +208,7 @@ shutdown(how) -- shut down traffic in one or both directions\n\
functions are declared correctly if compiling with
MIPSPro 7.x in ANSI C mode (default) */
-/* XXX Using _SGIAPI is the wrong thing,
+/* XXX Using _SGIAPI is the wrong thing,
but I don't know what the right thing is. */
#undef _SGIAPI /* to avoid warning */
#define _SGIAPI 1
@@ -214,8 +226,8 @@ shutdown(how) -- shut down traffic in one or both directions\n\
#include <netdb.h>
#endif
-/* Irix 6.5 fails to define this variable at all. This is needed
- for both GCC and SGI's compiler. I'd say that the SGI headers
+/* Irix 6.5 fails to define this variable at all. This is needed
+ for both GCC and SGI's compiler. I'd say that the SGI headers
are just busted. Same thing for Solaris. */
#if (defined(__sgi) || defined(sun)) && !defined(INET_ADDRSTRLEN)
#define INET_ADDRSTRLEN 16
@@ -306,6 +318,11 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
older releases don't have */
#undef HAVE_GETADDRINFO
#endif
+
+#ifdef HAVE_INET_ATON
+#define USE_INET_ATON_WEAKLINK
+#endif
+
#endif
/* I know this is a bad practice, but it is the easiest... */
@@ -1180,10 +1197,10 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
args->ob_type->tp_name);
return 0;
}
- if (!PyArg_ParseTuple(args, "eti:getsockaddrarg",
+ if (!PyArg_ParseTuple(args, "eti:getsockaddrarg",
"idna", &host, &port))
return 0;
- result = setipaddr(host, (struct sockaddr *)addr,
+ result = setipaddr(host, (struct sockaddr *)addr,
sizeof(*addr), AF_INET);
PyMem_Free(host);
if (result < 0)
@@ -1203,12 +1220,20 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
int port, flowinfo, scope_id, result;
addr = (struct sockaddr_in6*)&(s->sock_addr).in6;
flowinfo = scope_id = 0;
- if (!PyArg_ParseTuple(args, "eti|ii",
+ if (!PyTuple_Check(args)) {
+ PyErr_Format(
+ PyExc_TypeError,
+ "getsockaddrarg: "
+ "AF_INET6 address must be tuple, not %.500s",
+ args->ob_type->tp_name);
+ return 0;
+ }
+ if (!PyArg_ParseTuple(args, "eti|ii",
"idna", &host, &port, &flowinfo,
&scope_id)) {
return 0;
}
- result = setipaddr(host, (struct sockaddr *)addr,
+ result = setipaddr(host, (struct sockaddr *)addr,
sizeof(*addr), AF_INET6);
PyMem_Free(host);
if (result < 0)
@@ -1305,6 +1330,14 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
char *haddr = NULL;
unsigned int halen = 0;
+ if (!PyTuple_Check(args)) {
+ PyErr_Format(
+ PyExc_TypeError,
+ "getsockaddrarg: "
+ "AF_PACKET address must be tuple, not %.500s",
+ args->ob_type->tp_name);
+ return 0;
+ }
if (!PyArg_ParseTuple(args, "si|iis#", &interfaceName,
&protoNumber, &pkttype, &hatype,
&haddr, &halen))
@@ -1809,7 +1842,7 @@ internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen,
int res_size = sizeof res;
/* It must be in the exception set */
assert(FD_ISSET(s->sock_fd, &fds_exc));
- if (0 == getsockopt(s->sock_fd, SOL_SOCKET, SO_ERROR,
+ if (0 == getsockopt(s->sock_fd, SOL_SOCKET, SO_ERROR,
(char *)&res, &res_size))
/* getsockopt also clears WSAGetLastError,
so reset it back. */
@@ -2105,95 +2138,126 @@ The mode and buffersize arguments are as for the built-in open() function.");
#endif /* NO_DUP */
-
-/* s.recv(nbytes [,flags]) method */
-
-static PyObject *
-sock_recv(PySocketSockObject *s, PyObject *args)
+/*
+ * This is the guts of the recv() and recv_buf() methods, which reads into a
+ * char buffer. If you have any inc/def ref to do to the objects that contain
+ * the buffer, do it in the caller. This function returns the number of bytes
+ * succesfully read. If there was an error, it returns -1. Note that it is
+ * also possible that we return a number of bytes smaller than the request
+ * bytes.
+ */
+static int
+sock_recv_guts(PySocketSockObject *s, char* cbuf, int len, int flags)
{
- int len, n = 0, flags = 0, timeout;
- PyObject *buf;
+ int timeout, outlen = 0;
#ifdef __VMS
- int read_length;
+ int remaining, nread;
char *read_buf;
#endif
- if (!PyArg_ParseTuple(args, "i|i:recv", &len, &flags))
- return NULL;
-
- if (len < 0) {
- PyErr_SetString(PyExc_ValueError,
- "negative buffersize in recv");
- return NULL;
+ if (!IS_SELECTABLE(s)) {
+ select_error();
+ return -1;
}
- buf = PyString_FromStringAndSize((char *) 0, len);
- if (buf == NULL)
- return NULL;
-
- if (!IS_SELECTABLE(s))
- return select_error();
-
#ifndef __VMS
Py_BEGIN_ALLOW_THREADS
timeout = internal_select(s, 0);
if (!timeout)
- n = recv(s->sock_fd, PyString_AS_STRING(buf), len, flags);
+ outlen = recv(s->sock_fd, cbuf, len, flags);
Py_END_ALLOW_THREADS
if (timeout) {
- Py_DECREF(buf);
PyErr_SetString(socket_timeout, "timed out");
- return NULL;
+ return -1;
}
- if (n < 0) {
- Py_DECREF(buf);
- return s->errorhandler();
+ if (outlen < 0) {
+ /* Note: the call to errorhandler() ALWAYS indirectly returned
+ NULL, so ignore its return value */
+ s->errorhandler();
+ return -1;
}
- if (n != len)
- _PyString_Resize(&buf, n);
#else
- read_buf = PyString_AsString(buf);
- read_length = len;
- while (read_length != 0) {
+ read_buf = cbuf;
+ remaining = len;
+ while (remaining != 0) {
unsigned int segment;
- segment = read_length /SEGMENT_SIZE;
+ segment = remaining /SEGMENT_SIZE;
if (segment != 0) {
segment = SEGMENT_SIZE;
}
else {
- segment = read_length;
+ segment = remaining;
}
Py_BEGIN_ALLOW_THREADS
timeout = internal_select(s, 0);
if (!timeout)
- n = recv(s->sock_fd, read_buf, segment, flags);
+ nread = recv(s->sock_fd, read_buf, segment, flags);
Py_END_ALLOW_THREADS
if (timeout) {
- Py_DECREF(buf);
PyErr_SetString(socket_timeout, "timed out");
- return NULL;
+ return -1;
}
- if (n < 0) {
- Py_DECREF(buf);
- return s->errorhandler();
+ if (nread < 0) {
+ s->errorhandler();
+ return -1;
}
- if (n != read_length) {
- read_buf += n;
+ if (nread != remaining) {
+ read_buf += nread;
break;
}
- read_length -= segment;
+ remaining -= segment;
read_buf += segment;
}
- if (_PyString_Resize(&buf, (read_buf - PyString_AsString(buf))) < 0)
- {
- return NULL;
- }
+ outlen = read_buf - cbuf;
#endif /* !__VMS */
+
+ return outlen;
+}
+
+
+/* s.recv(nbytes [,flags]) method */
+
+static PyObject *
+sock_recv(PySocketSockObject *s, PyObject *args)
+{
+ int recvlen, flags = 0, outlen;
+ PyObject *buf;
+
+ if (!PyArg_ParseTuple(args, "i|i:recv", &recvlen, &flags))
+ return NULL;
+
+ if (recvlen < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "negative buffersize in recv");
+ return NULL;
+ }
+
+ /* Allocate a new string. */
+ buf = PyString_FromStringAndSize((char *) 0, recvlen);
+ if (buf == NULL)
+ return NULL;
+
+ /* Call the guts */
+ outlen = sock_recv_guts(s, PyString_AsString(buf), recvlen, flags);
+ if (outlen < 0) {
+ /* An error occured, release the string and return an
+ error. */
+ Py_DECREF(buf);
+ return NULL;
+ }
+ if (outlen != recvlen) {
+ /* We did not read as many bytes as we anticipated, resize the
+ string if possible and be succesful. */
+ if (_PyString_Resize(&buf, outlen) < 0)
+ /* Oopsy, not so succesful after all. */
+ return NULL;
+ }
+
return buf;
}
@@ -2206,29 +2270,90 @@ at least one byte is available or until the remote end is closed. When\n\
the remote end is closed and all data is read, return the empty string.");
-/* s.recvfrom(nbytes [,flags]) method */
+/* s.recv_buf(buffer, [nbytes [,flags]]) method */
-static PyObject *
-sock_recvfrom(PySocketSockObject *s, PyObject *args)
+static PyObject*
+sock_recv_buf(PySocketSockObject *s, PyObject *args, PyObject *kwds)
{
- sock_addr_t addrbuf;
- PyObject *buf = NULL;
- PyObject *addr = NULL;
- PyObject *ret = NULL;
- int len, n = 0, flags = 0, timeout;
- socklen_t addrlen;
+ static char *kwlist[] = {"buffer", "nbytes", "flags", 0};
+
+ int recvlen = 0, flags = 0, readlen;
+ char *buf;
+ int buflen;
- if (!PyArg_ParseTuple(args, "i|i:recvfrom", &len, &flags))
+ /* Get the buffer's memory */
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "s#|ii:recv", kwlist,
+ &buf, &buflen, &recvlen, &flags))
return NULL;
+ assert(buf != 0 && buflen > 0);
- if (!getsockaddrlen(s, &addrlen))
+ if (recvlen < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "negative buffersize in recv");
return NULL;
- buf = PyString_FromStringAndSize((char *) 0, len);
- if (buf == NULL)
+ }
+ if (recvlen == 0) {
+ /* If nbytes was not specified, use the buffer's length */
+ recvlen = buflen;
+ }
+
+ /* Check if the buffer is large enough */
+ if (buflen < recvlen) {
+ PyErr_SetString(PyExc_ValueError,
+ "buffer too small for requested bytes");
return NULL;
+ }
- if (!IS_SELECTABLE(s))
- return select_error();
+ /* Call the guts */
+ readlen = sock_recv_guts(s, buf, recvlen, flags);
+ if (readlen < 0) {
+ /* Return an error. */
+ return NULL;
+ }
+
+ /* Return the number of bytes read. Note that we do not do anything
+ special here in the case that readlen < recvlen. */
+ return PyInt_FromLong(readlen);
+}
+
+PyDoc_STRVAR(recv_buf_doc,
+"recv_buf(buffer, [nbytes[, flags]]) -> nbytes_read\n\
+\n\
+A version of recv() that stores its data into a buffer rather than creating \n\
+a new string. Receive up to buffersize bytes from the socket. If buffersize \n\
+is not specified (or 0), receive up to the size available in the given buffer.\n\
+\n\
+See recv() for documentation about the flags.");
+
+
+/*
+ * This is the guts of the recv() and recv_buf() methods, which reads into a
+ * char buffer. If you have any inc/def ref to do to the objects that contain
+ * the buffer, do it in the caller. This function returns the number of bytes
+ * succesfully read. If there was an error, it returns -1. Note that it is
+ * also possible that we return a number of bytes smaller than the request
+ * bytes.
+ *
+ * 'addr' is a return value for the address object. Note that you must decref
+ * it yourself.
+ */
+static int
+sock_recvfrom_guts(PySocketSockObject *s, char* cbuf, int len, int flags,
+ PyObject** addr)
+{
+ sock_addr_t addrbuf;
+ int n = 0, timeout;
+ socklen_t addrlen;
+
+ *addr = NULL;
+
+ if (!getsockaddrlen(s, &addrlen))
+ return -1;
+
+ if (!IS_SELECTABLE(s)) {
+ select_error();
+ return -1;
+ }
Py_BEGIN_ALLOW_THREADS
memset(&addrbuf, 0, addrlen);
@@ -2236,41 +2361,71 @@ sock_recvfrom(PySocketSockObject *s, PyObject *args)
if (!timeout) {
#ifndef MS_WINDOWS
#if defined(PYOS_OS2) && !defined(PYCC_GCC)
- n = recvfrom(s->sock_fd, PyString_AS_STRING(buf), len, flags,
+ n = recvfrom(s->sock_fd, cbuf, len, flags,
(struct sockaddr *) &addrbuf, &addrlen);
#else
- n = recvfrom(s->sock_fd, PyString_AS_STRING(buf), len, flags,
+ n = recvfrom(s->sock_fd, cbuf, len, flags,
(void *) &addrbuf, &addrlen);
#endif
#else
- n = recvfrom(s->sock_fd, PyString_AS_STRING(buf), len, flags,
+ n = recvfrom(s->sock_fd, cbuf, len, flags,
(struct sockaddr *) &addrbuf, &addrlen);
#endif
}
Py_END_ALLOW_THREADS
if (timeout) {
- Py_DECREF(buf);
PyErr_SetString(socket_timeout, "timed out");
- return NULL;
+ return -1;
}
if (n < 0) {
- Py_DECREF(buf);
- return s->errorhandler();
+ s->errorhandler();
+ return -1;
}
- if (n != len && _PyString_Resize(&buf, n) < 0)
+ if (!(*addr = makesockaddr(s->sock_fd, (struct sockaddr *) &addrbuf,
+ addrlen, s->sock_proto)))
+ return -1;
+
+ return n;
+}
+
+/* s.recvfrom(nbytes [,flags]) method */
+
+static PyObject *
+sock_recvfrom(PySocketSockObject *s, PyObject *args)
+{
+ PyObject *buf = NULL;
+ PyObject *addr = NULL;
+ PyObject *ret = NULL;
+ int recvlen, outlen, flags = 0;
+
+ if (!PyArg_ParseTuple(args, "i|i:recvfrom", &recvlen, &flags))
return NULL;
- if (!(addr = makesockaddr(s->sock_fd, (struct sockaddr *) &addrbuf,
- addrlen, s->sock_proto)))
+ buf = PyString_FromStringAndSize((char *) 0, recvlen);
+ if (buf == NULL)
+ return NULL;
+
+ outlen = sock_recvfrom_guts(s, PyString_AS_STRING(buf),
+ recvlen, flags, &addr);
+ if (outlen < 0) {
goto finally;
+ }
+
+ if (outlen != recvlen) {
+ /* We did not read as many bytes as we anticipated, resize the
+ string if possible and be succesful. */
+ if (_PyString_Resize(&buf, outlen) < 0)
+ /* Oopsy, not so succesful after all. */
+ goto finally;
+ }
ret = PyTuple_Pack(2, buf, addr);
finally:
- Py_XDECREF(addr);
Py_XDECREF(buf);
+ Py_XDECREF(addr);
return ret;
}
@@ -2279,6 +2434,57 @@ PyDoc_STRVAR(recvfrom_doc,
\n\
Like recv(buffersize, flags) but also return the sender's address info.");
+
+/* s.recvfrom_buf(buffer[, nbytes [,flags]]) method */
+
+static PyObject *
+sock_recvfrom_buf(PySocketSockObject *s, PyObject *args, PyObject* kwds)
+{
+ static char *kwlist[] = {"buffer", "nbytes", "flags", 0};
+
+ int recvlen = 0, flags = 0, readlen;
+ char *buf;
+ int buflen;
+
+ PyObject *addr = NULL;
+ PyObject *ret = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "s#|ii:recvfrom", kwlist,
+ &buf, &buflen, &recvlen, &flags))
+ return NULL;
+ assert(buf != 0 && buflen > 0);
+
+ if (recvlen < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "negative buffersize in recv");
+ return NULL;
+ }
+ if (recvlen == 0) {
+ /* If nbytes was not specified, use the buffer's length */
+ recvlen = buflen;
+ }
+
+ readlen = sock_recvfrom_guts(s, buf, recvlen, flags, &addr);
+ if (readlen < 0) {
+ /* Return an error */
+ goto finally;
+ }
+
+ /* Return the number of bytes read and the address. Note that we do
+ not do anything special here in the case that readlen < recvlen. */
+ ret = PyTuple_Pack(2, PyInt_FromLong(readlen), addr);
+
+finally:
+ Py_XDECREF(addr);
+ return ret;
+}
+
+PyDoc_STRVAR(recvfrom_buf_doc,
+"recvfrom_buf(buffer[, nbytes[, flags]]) -> (nbytes, address info)\n\
+\n\
+Like recv_buf(buffer[, nbytes[, flags]]) but also return the sender's address info.");
+
+
/* s.send(data [,flags]) method */
static PyObject *
@@ -2473,59 +2679,63 @@ of the socket (flag == SHUT_WR), or both ends (flag == SHUT_RDWR).");
/* List of methods for socket objects */
static PyMethodDef sock_methods[] = {
- {"accept", (PyCFunction)sock_accept, METH_NOARGS,
- accept_doc},
- {"bind", (PyCFunction)sock_bind, METH_O,
- bind_doc},
- {"close", (PyCFunction)sock_close, METH_NOARGS,
- close_doc},
- {"connect", (PyCFunction)sock_connect, METH_O,
- connect_doc},
- {"connect_ex", (PyCFunction)sock_connect_ex, METH_O,
- connect_ex_doc},
+ {"accept", (PyCFunction)sock_accept, METH_NOARGS,
+ accept_doc},
+ {"bind", (PyCFunction)sock_bind, METH_O,
+ bind_doc},
+ {"close", (PyCFunction)sock_close, METH_NOARGS,
+ close_doc},
+ {"connect", (PyCFunction)sock_connect, METH_O,
+ connect_doc},
+ {"connect_ex", (PyCFunction)sock_connect_ex, METH_O,
+ connect_ex_doc},
#ifndef NO_DUP
- {"dup", (PyCFunction)sock_dup, METH_NOARGS,
- dup_doc},
+ {"dup", (PyCFunction)sock_dup, METH_NOARGS,
+ dup_doc},
#endif
- {"fileno", (PyCFunction)sock_fileno, METH_NOARGS,
- fileno_doc},
+ {"fileno", (PyCFunction)sock_fileno, METH_NOARGS,
+ fileno_doc},
#ifdef HAVE_GETPEERNAME
- {"getpeername", (PyCFunction)sock_getpeername,
- METH_NOARGS, getpeername_doc},
-#endif
- {"getsockname", (PyCFunction)sock_getsockname,
- METH_NOARGS, getsockname_doc},
- {"getsockopt", (PyCFunction)sock_getsockopt, METH_VARARGS,
- getsockopt_doc},
- {"listen", (PyCFunction)sock_listen, METH_O,
- listen_doc},
+ {"getpeername", (PyCFunction)sock_getpeername,
+ METH_NOARGS, getpeername_doc},
+#endif
+ {"getsockname", (PyCFunction)sock_getsockname,
+ METH_NOARGS, getsockname_doc},
+ {"getsockopt", (PyCFunction)sock_getsockopt, METH_VARARGS,
+ getsockopt_doc},
+ {"listen", (PyCFunction)sock_listen, METH_O,
+ listen_doc},
#ifndef NO_DUP
- {"makefile", (PyCFunction)sock_makefile, METH_VARARGS,
- makefile_doc},
-#endif
- {"recv", (PyCFunction)sock_recv, METH_VARARGS,
- recv_doc},
- {"recvfrom", (PyCFunction)sock_recvfrom, METH_VARARGS,
- recvfrom_doc},
- {"send", (PyCFunction)sock_send, METH_VARARGS,
- send_doc},
- {"sendall", (PyCFunction)sock_sendall, METH_VARARGS,
- sendall_doc},
- {"sendto", (PyCFunction)sock_sendto, METH_VARARGS,
- sendto_doc},
- {"setblocking", (PyCFunction)sock_setblocking, METH_O,
- setblocking_doc},
- {"settimeout", (PyCFunction)sock_settimeout, METH_O,
- settimeout_doc},
- {"gettimeout", (PyCFunction)sock_gettimeout, METH_NOARGS,
- gettimeout_doc},
- {"setsockopt", (PyCFunction)sock_setsockopt, METH_VARARGS,
- setsockopt_doc},
- {"shutdown", (PyCFunction)sock_shutdown, METH_O,
- shutdown_doc},
+ {"makefile", (PyCFunction)sock_makefile, METH_VARARGS,
+ makefile_doc},
+#endif
+ {"recv", (PyCFunction)sock_recv, METH_VARARGS,
+ recv_doc},
+ {"recv_buf", (PyCFunction)sock_recv_buf, METH_VARARGS | METH_KEYWORDS,
+ recv_buf_doc},
+ {"recvfrom", (PyCFunction)sock_recvfrom, METH_VARARGS,
+ recvfrom_doc},
+ {"recvfrom_buf", (PyCFunction)sock_recvfrom_buf, METH_VARARGS | METH_KEYWORDS,
+ recvfrom_buf_doc},
+ {"send", (PyCFunction)sock_send, METH_VARARGS,
+ send_doc},
+ {"sendall", (PyCFunction)sock_sendall, METH_VARARGS,
+ sendall_doc},
+ {"sendto", (PyCFunction)sock_sendto, METH_VARARGS,
+ sendto_doc},
+ {"setblocking", (PyCFunction)sock_setblocking, METH_O,
+ setblocking_doc},
+ {"settimeout", (PyCFunction)sock_settimeout, METH_O,
+ settimeout_doc},
+ {"gettimeout", (PyCFunction)sock_gettimeout, METH_NOARGS,
+ gettimeout_doc},
+ {"setsockopt", (PyCFunction)sock_setsockopt, METH_VARARGS,
+ setsockopt_doc},
+ {"shutdown", (PyCFunction)sock_shutdown, METH_O,
+ shutdown_doc},
#ifdef RISCOS
- {"sleeptaskw", (PyCFunction)sock_sleeptaskw, METH_O,
- sleeptaskw_doc},
+ {"sleeptaskw", (PyCFunction)sock_sleeptaskw, METH_O,
+ sleeptaskw_doc},
#endif
{NULL, NULL} /* sentinel */
};
@@ -3333,7 +3543,9 @@ socket_inet_aton(PyObject *self, PyObject *args)
#endif
#ifdef HAVE_INET_ATON
struct in_addr buf;
-#else
+#endif
+
+#if !defined(HAVE_INET_ATON) || defined(USE_INET_ATON_WEAKLINK)
/* Have to use inet_addr() instead */
unsigned long packed_addr;
#endif
@@ -3344,6 +3556,10 @@ socket_inet_aton(PyObject *self, PyObject *args)
#ifdef HAVE_INET_ATON
+
+#ifdef USE_INET_ATON_WEAKLINK
+ if (inet_aton != NULL) {
+#endif
if (inet_aton(ip_addr, &buf))
return PyString_FromStringAndSize((char *)(&buf),
sizeof(buf));
@@ -3352,13 +3568,20 @@ socket_inet_aton(PyObject *self, PyObject *args)
"illegal IP address string passed to inet_aton");
return NULL;
-#else /* ! HAVE_INET_ATON */
+#ifdef USE_INET_ATON_WEAKLINK
+ } else {
+#endif
+
+#endif
+
+#if !defined(HAVE_INET_ATON) || defined(USE_INET_ATON_WEAKLINK)
+
/* special-case this address as inet_addr might return INADDR_NONE
* for this */
if (strcmp(ip_addr, "255.255.255.255") == 0) {
packed_addr = 0xFFFFFFFF;
} else {
-
+
packed_addr = inet_addr(ip_addr);
if (packed_addr == INADDR_NONE) { /* invalid address */
@@ -3369,6 +3592,11 @@ socket_inet_aton(PyObject *self, PyObject *args)
}
return PyString_FromStringAndSize((char *) &packed_addr,
sizeof(packed_addr));
+
+#ifdef USE_INET_ATON_WEAKLINK
+ }
+#endif
+
#endif
}
@@ -3428,7 +3656,7 @@ socket_inet_pton(PyObject *self, PyObject *args)
"can't use AF_INET6, IPv6 is disabled");
return NULL;
}
-#endif
+#endif
retval = inet_pton(af, ip, packed);
if (retval < 0) {
@@ -3451,7 +3679,7 @@ socket_inet_pton(PyObject *self, PyObject *args)
return NULL;
}
}
-
+
PyDoc_STRVAR(inet_ntop_doc,
"inet_ntop(af, packed_ip) -> string formatted IP address\n\
\n\
@@ -3469,7 +3697,7 @@ socket_inet_ntop(PyObject *self, PyObject *args)
#else
char ip[INET_ADDRSTRLEN + 1];
#endif
-
+
/* Guarantee NUL-termination for PyString_FromString() below */
memset((void *) &ip[0], '\0', sizeof(ip));
@@ -3547,7 +3775,7 @@ socket_getaddrinfo(PyObject *self, PyObject *args)
} else if (PyString_Check(hobj)) {
hptr = PyString_AsString(hobj);
} else {
- PyErr_SetString(PyExc_TypeError,
+ PyErr_SetString(PyExc_TypeError,
"getaddrinfo() argument 1 must be string or None");
return NULL;
}
diff --git a/Modules/threadmodule.c b/Modules/threadmodule.c
index 83313df..9ac9881 100644
--- a/Modules/threadmodule.c
+++ b/Modules/threadmodule.c
@@ -98,13 +98,6 @@ PyDoc_STRVAR(locked_doc,
\n\
Return whether the lock is in the locked state.");
-static PyObject *
-lock_context(lockobject *self)
-{
- Py_INCREF(self);
- return (PyObject *)self;
-}
-
static PyMethodDef lock_methods[] = {
{"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
METH_VARARGS, acquire_doc},
@@ -118,8 +111,6 @@ static PyMethodDef lock_methods[] = {
METH_NOARGS, locked_doc},
{"locked", (PyCFunction)lock_locked_lock,
METH_NOARGS, locked_doc},
- {"__context__", (PyCFunction)lock_context,
- METH_NOARGS, PyDoc_STR("__context__() -> self.")},
{"__enter__", (PyCFunction)lock_PyThread_acquire_lock,
METH_VARARGS, acquire_doc},
{"__exit__", (PyCFunction)lock_PyThread_release_lock,
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
index 08d28a1..e03b7e1 100644
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -5,6 +5,18 @@
#include "structseq.h"
#include "timefuncs.h"
+#ifdef __APPLE__
+#if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_FTIME)
+ /*
+ * floattime falls back to ftime when getttimeofday fails because the latter
+ * might fail on some platforms. This fallback is unwanted on MacOSX because
+ * that makes it impossible to use a binary build on OSX 10.4 on earlier
+ * releases of the OS. Therefore claim we don't support ftime.
+ */
+# undef HAVE_FTIME
+#endif
+#endif
+
#include <ctype.h>
#include <sys/types.h>
@@ -51,11 +63,10 @@ static long main_thread;
#endif /* MS_WINDOWS */
#endif /* !__WATCOMC__ || __QNX__ */
-#if defined(MS_WINDOWS) && !defined(MS_WIN64) && !defined(__BORLANDC__)
-/* Win32 has better clock replacement
- XXX Win64 does not yet, but might when the platform matures. */
-#undef HAVE_CLOCK /* We have our own version down below */
-#endif /* MS_WINDOWS && !MS_WIN64 */
+#if defined(MS_WINDOWS) && !defined(__BORLANDC__)
+/* Win32 has better clock replacement; we have our own version below. */
+#undef HAVE_CLOCK
+#endif /* MS_WINDOWS && !defined(__BORLANDC__) */
#if defined(PYOS_OS2)
#define INCL_DOS
@@ -150,7 +161,7 @@ time_clock(PyObject *self, PyObject *args)
}
#endif /* HAVE_CLOCK */
-#if defined(MS_WINDOWS) && !defined(MS_WIN64) && !defined(__BORLANDC__)
+#if defined(MS_WINDOWS) && !defined(__BORLANDC__)
/* Due to Mark Hammond and Tim Peters */
static PyObject *
time_clock(PyObject *self, PyObject *args)
@@ -179,7 +190,7 @@ time_clock(PyObject *self, PyObject *args)
}
#define HAVE_CLOCK /* So it gets included in the methods */
-#endif /* MS_WINDOWS && !MS_WIN64 */
+#endif /* MS_WINDOWS && !defined(__BORLANDC__) */
#ifdef HAVE_CLOCK
PyDoc_STRVAR(clock_doc,
@@ -701,7 +712,7 @@ void inittimezone(PyObject *m) {
#ifdef __CYGWIN__
tzset();
PyModule_AddIntConstant(m, "timezone", _timezone);
- PyModule_AddIntConstant(m, "altzone", _timezone);
+ PyModule_AddIntConstant(m, "altzone", _timezone-3600);
PyModule_AddIntConstant(m, "daylight", _daylight);
PyModule_AddObject(m, "tzname",
Py_BuildValue("(zz)", _tzname[0], _tzname[1]));
@@ -809,7 +820,7 @@ inittime(void)
SetConsoleCtrlHandler( PyCtrlHandler, TRUE);
#endif /* MS_WINDOWS */
if (!initialized) {
- PyStructSequence_InitType(&StructTimeType,
+ PyStructSequence_InitType(&StructTimeType,
&struct_time_type_desc);
}
Py_INCREF(&StructTimeType);
@@ -842,6 +853,7 @@ floattime(void)
return (double)t.tv_sec + t.tv_usec*0.000001;
#endif /* !GETTIMEOFDAY_NO_TZ */
}
+
#endif /* !HAVE_GETTIMEOFDAY */
{
#if defined(HAVE_FTIME)
diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c
index 297611c..0660353 100644
--- a/Modules/unicodedata.c
+++ b/Modules/unicodedata.c
@@ -209,7 +209,7 @@ unicodedata_numeric(PyObject *self, PyObject *args)
if (old->category_changed == 0) {
/* unassigned */
have_old = 1;
- rc = -1;
+ rc = -1.0;
}
else if (old->decimal_changed != 0xFF) {
have_old = 1;
@@ -219,7 +219,7 @@ unicodedata_numeric(PyObject *self, PyObject *args)
if (!have_old)
rc = Py_UNICODE_TONUMERIC(*PyUnicode_AS_UNICODE(v));
- if (rc < 0) {
+ if (rc == -1.0) {
if (defobj == NULL) {
PyErr_SetString(PyExc_ValueError, "not a numeric character");
return NULL;
diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c
index 35b8c32..06b0690 100644
--- a/Modules/zlibmodule.c
+++ b/Modules/zlibmodule.c
@@ -653,6 +653,108 @@ PyZlib_flush(compobject *self, PyObject *args)
return RetVal;
}
+PyDoc_STRVAR(comp_copy__doc__,
+"copy() -- Return a copy of the compression object.");
+
+static PyObject *
+PyZlib_copy(compobject *self)
+{
+ compobject *retval = NULL;
+ int err;
+
+ retval = newcompobject(&Comptype);
+ if (!retval) return NULL;
+
+ /* Copy the zstream state
+ * We use ENTER_ZLIB / LEAVE_ZLIB to make this thread-safe
+ */
+ ENTER_ZLIB
+ err = deflateCopy(&retval->zst, &self->zst);
+ switch(err) {
+ case(Z_OK):
+ break;
+ case(Z_STREAM_ERROR):
+ PyErr_SetString(PyExc_ValueError, "Inconsistent stream state");
+ goto error;
+ case(Z_MEM_ERROR):
+ PyErr_SetString(PyExc_MemoryError,
+ "Can't allocate memory for compression object");
+ goto error;
+ default:
+ zlib_error(self->zst, err, "while copying compression object");
+ goto error;
+ }
+
+ Py_INCREF(self->unused_data);
+ Py_INCREF(self->unconsumed_tail);
+ Py_XDECREF(retval->unused_data);
+ Py_XDECREF(retval->unconsumed_tail);
+ retval->unused_data = self->unused_data;
+ retval->unconsumed_tail = self->unconsumed_tail;
+
+ /* Mark it as being initialized */
+ retval->is_initialised = 1;
+
+ LEAVE_ZLIB
+ return (PyObject *)retval;
+
+error:
+ LEAVE_ZLIB
+ Py_XDECREF(retval);
+ return NULL;
+}
+
+PyDoc_STRVAR(decomp_copy__doc__,
+"copy() -- Return a copy of the decompression object.");
+
+static PyObject *
+PyZlib_uncopy(compobject *self)
+{
+ compobject *retval = NULL;
+ int err;
+
+ retval = newcompobject(&Decomptype);
+ if (!retval) return NULL;
+
+ /* Copy the zstream state
+ * We use ENTER_ZLIB / LEAVE_ZLIB to make this thread-safe
+ */
+ ENTER_ZLIB
+ err = inflateCopy(&retval->zst, &self->zst);
+ switch(err) {
+ case(Z_OK):
+ break;
+ case(Z_STREAM_ERROR):
+ PyErr_SetString(PyExc_ValueError, "Inconsistent stream state");
+ goto error;
+ case(Z_MEM_ERROR):
+ PyErr_SetString(PyExc_MemoryError,
+ "Can't allocate memory for decompression object");
+ goto error;
+ default:
+ zlib_error(self->zst, err, "while copying decompression object");
+ goto error;
+ }
+
+ Py_INCREF(self->unused_data);
+ Py_INCREF(self->unconsumed_tail);
+ Py_XDECREF(retval->unused_data);
+ Py_XDECREF(retval->unconsumed_tail);
+ retval->unused_data = self->unused_data;
+ retval->unconsumed_tail = self->unconsumed_tail;
+
+ /* Mark it as being initialized */
+ retval->is_initialised = 1;
+
+ LEAVE_ZLIB
+ return (PyObject *)retval;
+
+error:
+ LEAVE_ZLIB
+ Py_XDECREF(retval);
+ return NULL;
+}
+
PyDoc_STRVAR(decomp_flush__doc__,
"flush( [length] ) -- Return a string containing any remaining\n"
"decompressed data. length, if given, is the initial size of the\n"
@@ -725,6 +827,8 @@ static PyMethodDef comp_methods[] =
comp_compress__doc__},
{"flush", (binaryfunc)PyZlib_flush, METH_VARARGS,
comp_flush__doc__},
+ {"copy", (PyCFunction)PyZlib_copy, METH_NOARGS,
+ comp_copy__doc__},
{NULL, NULL}
};
@@ -734,6 +838,8 @@ static PyMethodDef Decomp_methods[] =
decomp_decompress__doc__},
{"flush", (binaryfunc)PyZlib_unflush, METH_VARARGS,
decomp_flush__doc__},
+ {"copy", (PyCFunction)PyZlib_uncopy, METH_NOARGS,
+ decomp_copy__doc__},
{NULL, NULL}
};