summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin v. Löwis <martin@v.loewis.de>2006-04-14 09:08:42 (GMT)
committerMartin v. Löwis <martin@v.loewis.de>2006-04-14 09:08:42 (GMT)
commit5cb6936672a1410f5502d754570bc548064f9dc4 (patch)
tree16c2d4cecdd7441b642707a43ed37ce900197175
parent38a76a101796d43fb8cd6c6d5ba54bb811d06f49 (diff)
downloadcpython-5cb6936672a1410f5502d754570bc548064f9dc4.zip
cpython-5cb6936672a1410f5502d754570bc548064f9dc4.tar.gz
cpython-5cb6936672a1410f5502d754570bc548064f9dc4.tar.bz2
Make Py_BuildValue, PyObject_CallFunction and
PyObject_CallMethod aware of PY_SSIZE_T_CLEAN.
-rw-r--r--Include/abstract.h5
-rw-r--r--Include/modsupport.h14
-rw-r--r--Objects/abstract.c118
-rw-r--r--Objects/stringobject.c1
-rw-r--r--Objects/unicodeobject.c1
-rw-r--r--Python/exceptions.c7
-rw-r--r--Python/getargs.c12
-rw-r--r--Python/modsupport.c79
8 files changed, 172 insertions, 65 deletions
diff --git a/Include/abstract.h b/Include/abstract.h
index 9ec18fa..3dcc0b0 100644
--- a/Include/abstract.h
+++ b/Include/abstract.h
@@ -4,6 +4,11 @@
extern "C" {
#endif
+#ifdef PY_SSIZE_T_CLEAN
+#define PyObject_CallFunction _PyObject_CallFunction_SizeT
+#define PyObject_CallMethod _PyObject_CallMethod_SizeT
+#endif
+
/* Abstract Object Interface (many thanks to Jim Fulton) */
/*
diff --git a/Include/modsupport.h b/Include/modsupport.h
index 5471197..1141d6a 100644
--- a/Include/modsupport.h
+++ b/Include/modsupport.h
@@ -17,21 +17,11 @@ extern "C" {
#define PyArg_ParseTupleAndKeywords _PyArg_ParseTupleAndKeywords_SizeT
#define PyArg_VaParse _PyArg_VaParse_SizeT
#define PyArg_VaParseTupleAndKeywords _PyArg_VaParseTupleAndKeywords_SizeT
-#define PyArg_BuildValue _PyArg_BuildValue_SizeT
-#define PyArg_VaBuildValue _PyArg_VaBuildValue_SizeT
+#define Py_BuildValue _Py_BuildValue_SizeT
+#define Py_VaBuildValue _Py_VaBuildValue_SizeT
#else
-#ifdef HAVE_DECLSPEC_DLL
-PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, char *, ...);
-PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, char *, ...);
-PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
- const char *, char **, ...);
-PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...);
-PyAPI_FUNC(int) _PyArg_VaParse_SizeT(PyObject *, char *, va_list);
-PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
- const char *, char **, va_list);
PyAPI_FUNC(PyObject *) _Py_VaBuildValue_SizeT(const char *, va_list);
#endif
-#endif
PyAPI_FUNC(int) PyArg_Parse(PyObject *, const char *, ...);
PyAPI_FUNC(int) PyArg_ParseTuple(PyObject *, const char *, ...);
diff --git a/Objects/abstract.c b/Objects/abstract.c
index 4ef3e5a..7e2cdbc 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -10,6 +10,14 @@
#define HASINDEX(o) PyType_HasFeature((o)->ob_type, Py_TPFLAGS_HAVE_INDEX)
+#ifdef HAVE_DECLSPEC_DLL
+PyAPI_FUNC(PyObject *) _PyObject_CallFunction_SizeT(PyObject *callable_object,
+ char *format, ...);
+PyAPI_FUNC(PyObject *) _PyObject_CallMethod_SizeT(PyObject *o, char *m,
+ char *format, ...);
+#endif
+
+
/* Shorthands to return certain errors */
static PyObject *
@@ -1800,11 +1808,37 @@ PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw)
return NULL;
}
+static PyObject*
+call_function_tail(PyObject *callable, PyObject *args)
+{
+ PyObject *retval;
+
+ if (args == NULL)
+ return NULL;
+
+ if (!PyTuple_Check(args)) {
+ PyObject *a;
+
+ a = PyTuple_New(1);
+ if (a == NULL) {
+ Py_DECREF(args);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(a, 0, args);
+ args = a;
+ }
+ retval = PyObject_Call(callable, args, NULL);
+
+ Py_DECREF(args);
+
+ return retval;
+}
+
PyObject *
PyObject_CallFunction(PyObject *callable, char *format, ...)
{
va_list va;
- PyObject *args, *retval;
+ PyObject *args;
if (callable == NULL)
return null_error();
@@ -1817,31 +1851,34 @@ PyObject_CallFunction(PyObject *callable, char *format, ...)
else
args = PyTuple_New(0);
- if (args == NULL)
- return NULL;
+ return call_function_tail(callable, args);
+}
- if (!PyTuple_Check(args)) {
- PyObject *a;
+PyObject *
+_PyObject_CallFunction_SizeT(PyObject *callable, char *format, ...)
+{
+ va_list va;
+ PyObject *args;
- a = PyTuple_New(1);
- if (a == NULL)
- return NULL;
- if (PyTuple_SetItem(a, 0, args) < 0)
- return NULL;
- args = a;
- }
- retval = PyObject_Call(callable, args, NULL);
+ if (callable == NULL)
+ return null_error();
- Py_DECREF(args);
+ if (format && *format) {
+ va_start(va, format);
+ args = _Py_VaBuildValue_SizeT(format, va);
+ va_end(va);
+ }
+ else
+ args = PyTuple_New(0);
- return retval;
+ return call_function_tail(callable, args);
}
PyObject *
PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
{
va_list va;
- PyObject *args = NULL;
+ PyObject *args;
PyObject *func = NULL;
PyObject *retval = NULL;
@@ -1867,24 +1904,49 @@ PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
else
args = PyTuple_New(0);
- if (!args)
- goto exit;
+ retval = call_function_tail(func, args);
- if (!PyTuple_Check(args)) {
- PyObject *a;
+ exit:
+ /* args gets consumed in call_function_tail */
+ Py_XDECREF(func);
- a = PyTuple_New(1);
- if (a == NULL)
- goto exit;
- if (PyTuple_SetItem(a, 0, args) < 0)
- goto exit;
- args = a;
+ return retval;
+}
+
+PyObject *
+_PyObject_CallMethod_SizeT(PyObject *o, char *name, char *format, ...)
+{
+ va_list va;
+ PyObject *args;
+ PyObject *func = NULL;
+ PyObject *retval = NULL;
+
+ if (o == NULL || name == NULL)
+ return null_error();
+
+ func = PyObject_GetAttrString(o, name);
+ if (func == NULL) {
+ PyErr_SetString(PyExc_AttributeError, name);
+ return 0;
+ }
+
+ if (!PyCallable_Check(func)) {
+ type_error("call of non-callable attribute");
+ goto exit;
+ }
+
+ if (format && *format) {
+ va_start(va, format);
+ args = _Py_VaBuildValue_SizeT(format, va);
+ va_end(va);
}
+ else
+ args = PyTuple_New(0);
- retval = PyObject_Call(func, args, NULL);
+ retval = call_function_tail(func, args);
exit:
- Py_XDECREF(args);
+ /* args gets consumed in call_function_tail */
Py_XDECREF(func);
return retval;
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index b399415..99cadca 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -1,5 +1,6 @@
/* String object implementation */
+#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include <ctype.h>
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 668d6e4..f6996c7 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -36,6 +36,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include "unicodeobject.h"
diff --git a/Python/exceptions.c b/Python/exceptions.c
index e5f8f05..5c824e6 100644
--- a/Python/exceptions.c
+++ b/Python/exceptions.c
@@ -14,6 +14,7 @@
* Copyright (c) 1998-2000 by Secret Labs AB. All rights reserved.
*/
+#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include "osdefs.h"
@@ -1450,8 +1451,8 @@ PyObject * PyUnicodeDecodeError_Create(
assert(length < INT_MAX);
assert(start < INT_MAX);
assert(end < INT_MAX);
- return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#iis",
- encoding, object, (int)length, (int)start, (int)end, reason);
+ return PyObject_CallFunction(PyExc_UnicodeDecodeError, "ss#nns",
+ encoding, object, length, start, end, reason);
}
@@ -1565,7 +1566,7 @@ PyObject * PyUnicodeTranslateError_Create(
const Py_UNICODE *object, Py_ssize_t length,
Py_ssize_t start, Py_ssize_t end, const char *reason)
{
- return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#iis",
+ return PyObject_CallFunction(PyExc_UnicodeTranslateError, "u#nns",
object, length, start, end, reason);
}
#endif
diff --git a/Python/getargs.c b/Python/getargs.c
index 5908e6b..f5e2154 100644
--- a/Python/getargs.c
+++ b/Python/getargs.c
@@ -18,6 +18,18 @@ int PyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
int PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *,
const char *, char **, va_list);
+#ifdef HAVE_DECLSPEC_DLL
+/* Export functions */
+PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, char *, ...);
+PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, char *, ...);
+PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
+ const char *, char **, ...);
+PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...);
+PyAPI_FUNC(int) _PyArg_VaParse_SizeT(PyObject *, char *, va_list);
+PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
+ const char *, char **, va_list);
+#endif
+
#define FLAG_COMPAT 1
#define FLAG_SIZE_T 2
diff --git a/Python/modsupport.c b/Python/modsupport.c
index 65480c8..dd7454c 100644
--- a/Python/modsupport.c
+++ b/Python/modsupport.c
@@ -3,8 +3,14 @@
#include "Python.h"
+#define FLAG_SIZE_T 1
typedef double va_double;
+static PyObject *va_build_value(const char *, va_list, int);
+#ifdef HAVE_DECLSPEC_DLL
+PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...);
+#endif
+
/* Package context -- the full module name for package imports */
char *_Py_PackageContext = NULL;
@@ -146,14 +152,14 @@ countformat(const char *format, int endchar)
/* Generic function to create a value -- the inverse of getargs() */
/* After an original idea and first implementation by Steven Miale */
-static PyObject *do_mktuple(const char**, va_list *, int, int);
-static PyObject *do_mklist(const char**, va_list *, int, int);
-static PyObject *do_mkdict(const char**, va_list *, int, int);
-static PyObject *do_mkvalue(const char**, va_list *);
+static PyObject *do_mktuple(const char**, va_list *, int, int, int);
+static PyObject *do_mklist(const char**, va_list *, int, int, int);
+static PyObject *do_mkdict(const char**, va_list *, int, int, int);
+static PyObject *do_mkvalue(const char**, va_list *, int);
static PyObject *
-do_mkdict(const char **p_format, va_list *p_va, int endchar, int n)
+do_mkdict(const char **p_format, va_list *p_va, int endchar, int n, int flags)
{
PyObject *d;
int i;
@@ -167,13 +173,13 @@ do_mkdict(const char **p_format, va_list *p_va, int endchar, int n)
for (i = 0; i < n; i+= 2) {
PyObject *k, *v;
int err;
- k = do_mkvalue(p_format, p_va);
+ k = do_mkvalue(p_format, p_va, flags);
if (k == NULL) {
itemfailed = 1;
Py_INCREF(Py_None);
k = Py_None;
}
- v = do_mkvalue(p_format, p_va);
+ v = do_mkvalue(p_format, p_va, flags);
if (v == NULL) {
itemfailed = 1;
Py_INCREF(Py_None);
@@ -199,7 +205,7 @@ do_mkdict(const char **p_format, va_list *p_va, int endchar, int n)
}
static PyObject *
-do_mklist(const char **p_format, va_list *p_va, int endchar, int n)
+do_mklist(const char **p_format, va_list *p_va, int endchar, int n, int flags)
{
PyObject *v;
int i;
@@ -212,7 +218,7 @@ do_mklist(const char **p_format, va_list *p_va, int endchar, int n)
/* Note that we can't bail immediately on error as this will leak
refcounts on any 'N' arguments. */
for (i = 0; i < n; i++) {
- PyObject *w = do_mkvalue(p_format, p_va);
+ PyObject *w = do_mkvalue(p_format, p_va, flags);
if (w == NULL) {
itemfailed = 1;
Py_INCREF(Py_None);
@@ -249,7 +255,7 @@ _ustrlen(Py_UNICODE *u)
#endif
static PyObject *
-do_mktuple(const char **p_format, va_list *p_va, int endchar, int n)
+do_mktuple(const char **p_format, va_list *p_va, int endchar, int n, int flags)
{
PyObject *v;
int i;
@@ -261,7 +267,7 @@ do_mktuple(const char **p_format, va_list *p_va, int endchar, int n)
/* Note that we can't bail immediately on error as this will leak
refcounts on any 'N' arguments. */
for (i = 0; i < n; i++) {
- PyObject *w = do_mkvalue(p_format, p_va);
+ PyObject *w = do_mkvalue(p_format, p_va, flags);
if (w == NULL) {
itemfailed = 1;
Py_INCREF(Py_None);
@@ -286,21 +292,21 @@ do_mktuple(const char **p_format, va_list *p_va, int endchar, int n)
}
static PyObject *
-do_mkvalue(const char **p_format, va_list *p_va)
+do_mkvalue(const char **p_format, va_list *p_va, int flags)
{
for (;;) {
switch (*(*p_format)++) {
case '(':
return do_mktuple(p_format, p_va, ')',
- countformat(*p_format, ')'));
+ countformat(*p_format, ')'), flags);
case '[':
return do_mklist(p_format, p_va, ']',
- countformat(*p_format, ']'));
+ countformat(*p_format, ']'), flags);
case '{':
return do_mkdict(p_format, p_va, '}',
- countformat(*p_format, '}'));
+ countformat(*p_format, '}'), flags);
case 'b':
case 'B':
@@ -351,10 +357,13 @@ do_mkvalue(const char **p_format, va_list *p_va)
{
PyObject *v;
Py_UNICODE *u = va_arg(*p_va, Py_UNICODE *);
- int n;
+ Py_ssize_t n;
if (**p_format == '#') {
++*p_format;
- n = va_arg(*p_va, int);
+ if (flags & FLAG_SIZE_T)
+ n = va_arg(*p_va, Py_ssize_t);
+ else
+ n = va_arg(*p_va, int);
}
else
n = -1;
@@ -393,10 +402,13 @@ do_mkvalue(const char **p_format, va_list *p_va)
{
PyObject *v;
char *str = va_arg(*p_va, char *);
- int n;
+ Py_ssize_t n;
if (**p_format == '#') {
++*p_format;
- n = va_arg(*p_va, int);
+ if (flags & FLAG_SIZE_T)
+ n = va_arg(*p_va, Py_ssize_t);
+ else
+ n = va_arg(*p_va, int);
}
else
n = -1;
@@ -472,7 +484,18 @@ Py_BuildValue(const char *format, ...)
va_list va;
PyObject* retval;
va_start(va, format);
- retval = Py_VaBuildValue(format, va);
+ retval = va_build_value(format, va, 0);
+ va_end(va);
+ return retval;
+}
+
+PyObject *
+_Py_BuildValue_SizeT(const char *format, ...)
+{
+ va_list va;
+ PyObject* retval;
+ va_start(va, format);
+ retval = va_build_value(format, va, FLAG_SIZE_T);
va_end(va);
return retval;
}
@@ -480,6 +503,18 @@ Py_BuildValue(const char *format, ...)
PyObject *
Py_VaBuildValue(const char *format, va_list va)
{
+ return va_build_value(format, va, 0);
+}
+
+PyObject *
+_Py_VaBuildValue_SizeT(const char *format, va_list va)
+{
+ return va_build_value(format, va, FLAG_SIZE_T);
+}
+
+static PyObject *
+va_build_value(const char *format, va_list va, int flags)
+{
const char *f = format;
int n = countformat(f, '\0');
va_list lva;
@@ -501,8 +536,8 @@ Py_VaBuildValue(const char *format, va_list va)
return Py_None;
}
if (n == 1)
- return do_mkvalue(&f, &lva);
- return do_mktuple(&f, &lva, '\0', n);
+ return do_mkvalue(&f, &lva, flags);
+ return do_mktuple(&f, &lva, '\0', n, flags);
}