Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
fd878b88
Commit
fd878b88
authored
Mar 16, 2012
by
Eli Bendersky
Browse files
Options
Browse Files
Download
Plain Diff
merge heads
parents
2b711409
c961b4ab
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
85 additions
and
120 deletions
+85
-120
Python/getargs.c
Python/getargs.c
+85
-120
No files found.
Python/getargs.c
View file @
fd878b88
...
...
@@ -33,16 +33,33 @@ PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
#define FLAG_COMPAT 1
#define FLAG_SIZE_T 2
typedef
int
(
*
destr_t
)(
PyObject
*
,
void
*
);
/* Keep track of "objects" that have been allocated or initialized and
which will need to be deallocated or cleaned up somehow if overall
parsing fails.
*/
typedef
struct
{
void
*
item
;
destr_t
destructor
;
}
freelistentry_t
;
typedef
struct
{
int
first_available
;
freelistentry_t
*
entries
;
}
freelist_t
;
/* Forward */
static
int
vgetargs1
(
PyObject
*
,
const
char
*
,
va_list
*
,
int
);
static
void
seterror
(
int
,
const
char
*
,
int
*
,
const
char
*
,
const
char
*
);
static
char
*
convertitem
(
PyObject
*
,
const
char
**
,
va_list
*
,
int
,
int
*
,
char
*
,
size_t
,
PyObject
*
*
);
char
*
,
size_t
,
freelist_t
*
);
static
char
*
converttuple
(
PyObject
*
,
const
char
**
,
va_list
*
,
int
,
int
*
,
char
*
,
size_t
,
int
,
PyObject
*
*
);
int
*
,
char
*
,
size_t
,
int
,
freelist_t
*
);
static
char
*
convertsimple
(
PyObject
*
,
const
char
**
,
va_list
*
,
int
,
char
*
,
size_t
,
PyObject
*
*
);
size_t
,
freelist_t
*
);
static
Py_ssize_t
convertbuffer
(
PyObject
*
,
void
**
p
,
char
**
);
static
int
getbuffer
(
PyObject
*
,
Py_buffer
*
,
char
**
);
...
...
@@ -127,111 +144,54 @@ _PyArg_VaParse_SizeT(PyObject *args, char *format, va_list va)
#define GETARGS_CAPSULE_NAME_CLEANUP_BUFFER "getargs.cleanup_buffer"
#define GETARGS_CAPSULE_NAME_CLEANUP_CONVERT "getargs.cleanup_convert"
static
void
cleanup_ptr
(
PyObject
*
self
)
static
int
cleanup_ptr
(
PyObject
*
self
,
void
*
ptr
)
{
void
*
ptr
=
PyCapsule_GetPointer
(
self
,
GETARGS_CAPSULE_NAME_CLEANUP_PTR
);
if
(
ptr
)
{
PyMem_FREE
(
ptr
);
}
return
0
;
}
static
void
cleanup_buffer
(
PyObject
*
self
)
static
int
cleanup_buffer
(
PyObject
*
self
,
void
*
ptr
)
{
Py_buffer
*
ptr
=
(
Py_buffer
*
)
PyCapsule_GetPointer
(
self
,
GETARGS_CAPSULE_NAME_CLEANUP_BUFFER
)
;
if
(
ptr
)
{
PyBuffer_Release
(
ptr
);
Py_buffer
*
buf
=
(
Py_buffer
*
)
ptr
;
if
(
buf
)
{
PyBuffer_Release
(
buf
);
}
return
0
;
}
static
int
addcleanup
(
void
*
ptr
,
PyObject
**
freelist
,
int
is_buffe
r
)
addcleanup
(
void
*
ptr
,
freelist_t
*
freelist
,
destr_t
destructo
r
)
{
PyObject
*
cobj
;
const
char
*
name
;
PyCapsule_Destructor
destr
;
if
(
is_buffer
)
{
destr
=
cleanup_buffer
;
name
=
GETARGS_CAPSULE_NAME_CLEANUP_BUFFER
;
}
else
{
destr
=
cleanup_ptr
;
name
=
GETARGS_CAPSULE_NAME_CLEANUP_PTR
;
}
if
(
!*
freelist
)
{
*
freelist
=
PyList_New
(
0
);
if
(
!*
freelist
)
{
destr
(
ptr
);
return
-
1
;
}
}
int
index
;
cobj
=
PyCapsule_New
(
ptr
,
name
,
destr
);
if
(
!
cobj
)
{
destr
(
ptr
);
return
-
1
;
}
if
(
PyList_Append
(
*
freelist
,
cobj
))
{
Py_DECREF
(
cobj
);
return
-
1
;
}
Py_DECREF
(
cobj
);
return
0
;
}
index
=
freelist
->
first_available
;
freelist
->
first_available
+=
1
;
static
void
cleanup_convert
(
PyObject
*
self
)
{
typedef
int
(
*
destr_t
)(
PyObject
*
,
void
*
);
destr_t
destr
=
(
destr_t
)
PyCapsule_GetContext
(
self
);
void
*
ptr
=
PyCapsule_GetPointer
(
self
,
GETARGS_CAPSULE_NAME_CLEANUP_CONVERT
);
if
(
ptr
&&
destr
)
destr
(
NULL
,
ptr
);
}
freelist
->
entries
[
index
].
item
=
ptr
;
freelist
->
entries
[
index
].
destructor
=
destructor
;
static
int
addcleanup_convert
(
void
*
ptr
,
PyObject
**
freelist
,
int
(
*
destr
)(
PyObject
*
,
void
*
))
{
PyObject
*
cobj
;
if
(
!*
freelist
)
{
*
freelist
=
PyList_New
(
0
);
if
(
!*
freelist
)
{
destr
(
NULL
,
ptr
);
return
-
1
;
}
}
cobj
=
PyCapsule_New
(
ptr
,
GETARGS_CAPSULE_NAME_CLEANUP_CONVERT
,
cleanup_convert
);
if
(
!
cobj
)
{
destr
(
NULL
,
ptr
);
return
-
1
;
}
if
(
PyCapsule_SetContext
(
cobj
,
destr
)
==
-
1
)
{
/* This really should not happen. */
Py_FatalError
(
"capsule refused setting of context."
);
}
if
(
PyList_Append
(
*
freelist
,
cobj
))
{
Py_DECREF
(
cobj
);
/* This will also call destr. */
return
-
1
;
}
Py_DECREF
(
cobj
);
return
0
;
}
static
int
cleanreturn
(
int
retval
,
PyObjec
t
*
freelist
)
cleanreturn
(
int
retval
,
freelist_
t
*
freelist
)
{
if
(
freelist
&&
retval
!=
0
)
{
/* We were successful, reset the destructors so that they
don't get called. */
Py_ssize_t
len
=
PyList_GET_SIZE
(
freelist
),
i
;
for
(
i
=
0
;
i
<
len
;
i
++
)
PyCapsule_SetDestructor
(
PyList_GET_ITEM
(
freelist
,
i
),
NULL
);
}
Py_XDECREF
(
freelist
);
int
index
;
if
(
retval
==
0
)
{
/* A failure occurred, therefore execute all of the cleanup
functions.
*/
for
(
index
=
0
;
index
<
freelist
->
first_available
;
++
index
)
{
freelist
->
entries
[
index
].
destructor
(
NULL
,
freelist
->
entries
[
index
].
item
);
}
}
PyMem_Free
(
freelist
->
entries
);
return
retval
;
}
...
...
@@ -250,7 +210,7 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
const
char
*
formatsave
=
format
;
Py_ssize_t
i
,
len
;
char
*
msg
;
PyObject
*
freelist
=
NULL
;
freelist_t
freelist
=
{
0
,
NULL
}
;
int
compat
=
flags
&
FLAG_COMPAT
;
assert
(
compat
||
(
args
!=
(
PyObject
*
)
NULL
));
...
...
@@ -306,6 +266,8 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
format
=
formatsave
;
freelist
.
entries
=
PyMem_New
(
freelistentry_t
,
max
);
if
(
compat
)
{
if
(
max
==
0
)
{
if
(
args
==
NULL
)
...
...
@@ -314,7 +276,7 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
"%.200s%s takes no arguments"
,
fname
==
NULL
?
"function"
:
fname
,
fname
==
NULL
?
""
:
"()"
);
return
0
;
return
cleanreturn
(
0
,
&
freelist
)
;
}
else
if
(
min
==
1
&&
max
==
1
)
{
if
(
args
==
NULL
)
{
...
...
@@ -322,26 +284,26 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
"%.200s%s takes at least one argument"
,
fname
==
NULL
?
"function"
:
fname
,
fname
==
NULL
?
""
:
"()"
);
return
0
;
return
cleanreturn
(
0
,
&
freelist
)
;
}
msg
=
convertitem
(
args
,
&
format
,
p_va
,
flags
,
levels
,
msgbuf
,
sizeof
(
msgbuf
),
&
freelist
);
if
(
msg
==
NULL
)
return
cleanreturn
(
1
,
freelist
);
return
cleanreturn
(
1
,
&
freelist
);
seterror
(
levels
[
0
],
msg
,
levels
+
1
,
fname
,
message
);
return
cleanreturn
(
0
,
freelist
);
return
cleanreturn
(
0
,
&
freelist
);
}
else
{
PyErr_SetString
(
PyExc_SystemError
,
"old style getargs format uses new features"
);
return
0
;
return
cleanreturn
(
0
,
&
freelist
)
;
}
}
if
(
!
PyTuple_Check
(
args
))
{
PyErr_SetString
(
PyExc_SystemError
,
"new style getargs format but argument is not a tuple"
);
return
0
;
return
cleanreturn
(
0
,
&
freelist
)
;
}
len
=
PyTuple_GET_SIZE
(
args
);
...
...
@@ -359,7 +321,7 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
Py_SAFE_DOWNCAST
(
len
,
Py_ssize_t
,
long
));
else
PyErr_SetString
(
PyExc_TypeError
,
message
);
return
0
;
return
cleanreturn
(
0
,
&
freelist
)
;
}
for
(
i
=
0
;
i
<
len
;
i
++
)
{
...
...
@@ -370,7 +332,7 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
sizeof
(
msgbuf
),
&
freelist
);
if
(
msg
)
{
seterror
(
i
+
1
,
msg
,
levels
,
fname
,
msg
);
return
cleanreturn
(
0
,
freelist
);
return
cleanreturn
(
0
,
&
freelist
);
}
}
...
...
@@ -379,10 +341,10 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
*
format
!=
'|'
&&
*
format
!=
':'
&&
*
format
!=
';'
)
{
PyErr_Format
(
PyExc_SystemError
,
"bad format string: %.200s"
,
formatsave
);
return
cleanreturn
(
0
,
freelist
);
return
cleanreturn
(
0
,
&
freelist
);
}
return
cleanreturn
(
1
,
freelist
);
return
cleanreturn
(
1
,
&
freelist
);
}
...
...
@@ -446,7 +408,7 @@ seterror(int iarg, const char *msg, int *levels, const char *fname,
static
char
*
converttuple
(
PyObject
*
arg
,
const
char
**
p_format
,
va_list
*
p_va
,
int
flags
,
int
*
levels
,
char
*
msgbuf
,
size_t
bufsize
,
int
toplevel
,
PyObject
*
*
freelist
)
freelist_t
*
freelist
)
{
int
level
=
0
;
int
n
=
0
;
...
...
@@ -521,7 +483,7 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
static
char
*
convertitem
(
PyObject
*
arg
,
const
char
**
p_format
,
va_list
*
p_va
,
int
flags
,
int
*
levels
,
char
*
msgbuf
,
size_t
bufsize
,
PyObject
*
*
freelist
)
int
*
levels
,
char
*
msgbuf
,
size_t
bufsize
,
freelist_t
*
freelist
)
{
char
*
msg
;
const
char
*
format
=
*
p_format
;
...
...
@@ -586,7 +548,7 @@ float_argument_error(PyObject *arg)
static
char
*
convertsimple
(
PyObject
*
arg
,
const
char
**
p_format
,
va_list
*
p_va
,
int
flags
,
char
*
msgbuf
,
size_t
bufsize
,
PyObject
*
*
freelist
)
char
*
msgbuf
,
size_t
bufsize
,
freelist_t
*
freelist
)
{
/* For # codes */
#define FETCH_SIZE int *q=NULL;Py_ssize_t *q2=NULL;\
...
...
@@ -863,7 +825,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
if
(
getbuffer
(
arg
,
(
Py_buffer
*
)
p
,
&
buf
)
<
0
)
return
converterr
(
buf
,
arg
,
msgbuf
,
bufsize
);
format
++
;
if
(
addcleanup
(
p
,
freelist
,
1
))
{
if
(
addcleanup
(
p
,
freelist
,
cleanup_buffer
))
{
return
converterr
(
"(cleanup problem)"
,
arg
,
msgbuf
,
bufsize
);
...
...
@@ -908,7 +870,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
if
(
getbuffer
(
arg
,
p
,
&
buf
)
<
0
)
return
converterr
(
buf
,
arg
,
msgbuf
,
bufsize
);
}
if
(
addcleanup
(
p
,
freelist
,
1
))
{
if
(
addcleanup
(
p
,
freelist
,
cleanup_buffer
))
{
return
converterr
(
"(cleanup problem)"
,
arg
,
msgbuf
,
bufsize
);
...
...
@@ -1120,7 +1082,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
PyErr_NoMemory
();
RETURN_ERR_OCCURRED
;
}
if
(
addcleanup
(
*
buffer
,
freelist
,
0
))
{
if
(
addcleanup
(
*
buffer
,
freelist
,
cleanup_ptr
))
{
Py_DECREF
(
s
);
return
converterr
(
"(cleanup problem)"
,
...
...
@@ -1162,7 +1124,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
PyErr_NoMemory
();
RETURN_ERR_OCCURRED
;
}
if
(
addcleanup
(
*
buffer
,
freelist
,
0
))
{
if
(
addcleanup
(
*
buffer
,
freelist
,
cleanup_ptr
))
{
Py_DECREF
(
s
);
return
converterr
(
"(cleanup problem)"
,
arg
,
msgbuf
,
bufsize
);
...
...
@@ -1223,7 +1185,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
return
converterr
(
"(unspecified)"
,
arg
,
msgbuf
,
bufsize
);
if
(
res
==
Py_CLEANUP_SUPPORTED
&&
addcleanup
_convert
(
addr
,
freelist
,
convert
)
==
-
1
)
addcleanup
(
addr
,
freelist
,
convert
)
==
-
1
)
return
converterr
(
"(cleanup problem)"
,
arg
,
msgbuf
,
bufsize
);
}
...
...
@@ -1254,7 +1216,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
PyBuffer_Release
((
Py_buffer
*
)
p
);
return
converterr
(
"contiguous buffer"
,
arg
,
msgbuf
,
bufsize
);
}
if
(
addcleanup
(
p
,
freelist
,
1
))
{
if
(
addcleanup
(
p
,
freelist
,
cleanup_buffer
))
{
return
converterr
(
"(cleanup problem)"
,
arg
,
msgbuf
,
bufsize
);
...
...
@@ -1442,7 +1404,8 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
const
char
*
fname
,
*
msg
,
*
custom_msg
,
*
keyword
;
int
min
=
INT_MAX
;
int
i
,
len
,
nargs
,
nkeywords
;
PyObject
*
freelist
=
NULL
,
*
current_arg
;
PyObject
*
current_arg
;
freelist_t
freelist
=
{
0
,
NULL
};
assert
(
args
!=
NULL
&&
PyTuple_Check
(
args
));
assert
(
keywords
==
NULL
||
PyDict_Check
(
keywords
));
...
...
@@ -1466,6 +1429,8 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
for
(
len
=
0
;
kwlist
[
len
];
len
++
)
continue
;
freelist
.
entries
=
PyMem_New
(
freelistentry_t
,
len
);
nargs
=
PyTuple_GET_SIZE
(
args
);
nkeywords
=
(
keywords
==
NULL
)
?
0
:
PyDict_Size
(
keywords
);
if
(
nargs
+
nkeywords
>
len
)
{
...
...
@@ -1490,7 +1455,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
PyErr_Format
(
PyExc_RuntimeError
,
"More keyword list entries (%d) than "
"format specifiers (%d)"
,
len
,
i
);
return
cleanreturn
(
0
,
freelist
);
return
cleanreturn
(
0
,
&
freelist
);
}
current_arg
=
NULL
;
if
(
nkeywords
)
{
...
...
@@ -1504,11 +1469,11 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
"Argument given by name ('%s') "
"and position (%d)"
,
keyword
,
i
+
1
);
return
cleanreturn
(
0
,
freelist
);
return
cleanreturn
(
0
,
&
freelist
);
}
}
else
if
(
nkeywords
&&
PyErr_Occurred
())
return
cleanreturn
(
0
,
freelist
);
return
cleanreturn
(
0
,
&
freelist
);
else
if
(
i
<
nargs
)
current_arg
=
PyTuple_GET_ITEM
(
args
,
i
);
...
...
@@ -1517,7 +1482,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
levels
,
msgbuf
,
sizeof
(
msgbuf
),
&
freelist
);
if
(
msg
)
{
seterror
(
i
+
1
,
msg
,
levels
,
fname
,
custom_msg
);
return
cleanreturn
(
0
,
freelist
);
return
cleanreturn
(
0
,
&
freelist
);
}
continue
;
}
...
...
@@ -1526,14 +1491,14 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
PyErr_Format
(
PyExc_TypeError
,
"Required argument "
"'%s' (pos %d) not found"
,
keyword
,
i
+
1
);
return
cleanreturn
(
0
,
freelist
);
return
cleanreturn
(
0
,
&
freelist
);
}
/* current code reports success when all required args
* fulfilled and no keyword args left, with no further
* validation. XXX Maybe skip this in debug build ?
*/
if
(
!
nkeywords
)
return
cleanreturn
(
1
,
freelist
);
return
cleanreturn
(
1
,
&
freelist
);
/* We are into optional args, skip thru to any remaining
* keyword args */
...
...
@@ -1541,7 +1506,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
if
(
msg
)
{
PyErr_Format
(
PyExc_RuntimeError
,
"%s: '%s'"
,
msg
,
format
);
return
cleanreturn
(
0
,
freelist
);
return
cleanreturn
(
0
,
&
freelist
);
}
}
...
...
@@ -1549,7 +1514,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
PyErr_Format
(
PyExc_RuntimeError
,
"more argument specifiers than keyword list entries "
"(remaining format:'%s')"
,
format
);
return
cleanreturn
(
0
,
freelist
);
return
cleanreturn
(
0
,
&
freelist
);
}
/* make sure there are no extraneous keyword arguments */
...
...
@@ -1562,7 +1527,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
if
(
!
PyUnicode_Check
(
key
))
{
PyErr_SetString
(
PyExc_TypeError
,
"keywords must be strings"
);
return
cleanreturn
(
0
,
freelist
);
return
cleanreturn
(
0
,
&
freelist
);
}
/* check that _PyUnicode_AsString() result is not NULL */
ks
=
_PyUnicode_AsString
(
key
);
...
...
@@ -1579,12 +1544,12 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
"'%U' is an invalid keyword "
"argument for this function"
,
key
);
return
cleanreturn
(
0
,
freelist
);
return
cleanreturn
(
0
,
&
freelist
);
}
}
}
return
cleanreturn
(
1
,
freelist
);
return
cleanreturn
(
1
,
&
freelist
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment