diff options
author | Tim Peters <tim.peters@gmail.com> | 2001-10-27 04:26:57 (GMT) |
---|---|---|
committer | Tim Peters <tim.peters@gmail.com> | 2001-10-27 04:26:57 (GMT) |
commit | f8cd3e86218d8fda0da7feb1db939709a6c4f379 (patch) | |
tree | 265c87511ae721d3c87642e2576c017e46b3c7b9 | |
parent | 45772cde7e6d936cb37a4762eba3ca23c0b1c667 (diff) | |
download | cpython-f8cd3e86218d8fda0da7feb1db939709a6c4f379.zip cpython-f8cd3e86218d8fda0da7feb1db939709a6c4f379.tar.gz cpython-f8cd3e86218d8fda0da7feb1db939709a6c4f379.tar.bz2 |
PyArg_ParseTupleAndKeywords: return false on internal error, not -1 (I
introduced this bug just a little while ago, when *adding* internal error
checks).
vgetargskeywords: Rewrote the section that crawls over the format string.
+ Added block comment so it won't take the next person 15 minutes to
reverse-engineer what it's doing.
+ Lined up the "else" clauses.
+ Rearranged the ifs in decreasing order of likelihood (for speed).
-rw-r--r-- | Python/getargs.c | 64 |
1 files changed, 34 insertions, 30 deletions
diff --git a/Python/getargs.c b/Python/getargs.c index 840bf51..607d037 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -997,6 +997,7 @@ convertbuffer(PyObject *arg, void **p, char **errmsg) /* Support for keyword arguments donated by Geoff Philbrick <philbric@delphi.hks.com> */ +/* Return false (0) for error, else true. */ int PyArg_ParseTupleAndKeywords(PyObject *args, PyObject *keywords, @@ -1012,7 +1013,7 @@ PyArg_ParseTupleAndKeywords(PyObject *args, kwlist == NULL) { PyErr_BadInternalCall(); - return -1; + return 0; } va_start(va, kwlist); @@ -1028,10 +1029,8 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format, { char msgbuf[256]; int levels[32]; - char *fname = NULL; - char *message = NULL; - int min = -1; - int max = 0; + char *fname, *message; + int min, max; char *formatsave = format; int i, len, tplen, kwlen; char *msg, *ks, **p; @@ -1044,44 +1043,49 @@ vgetargskeywords(PyObject *args, PyObject *keywords, char *format, assert(kwlist != NULL); assert(p_va != NULL); - /* nested tuples cannot be parsed when using keyword arguments */ - - for (;;) { - int c = *format++; - if (c == '(') { - PyErr_SetString(PyExc_SystemError, - "tuple found in format when using keyword arguments"); - return 0; - } - else if (c == '\0') - break; - else if (c == ':') { + /* Search the format: + message <- error msg, if any (else NULL). + name <- routine name, if any (else NULL). + min <- # of required arguments, or -1 if all are required. + max <- most arguments (required + optional). + Raise error if a tuple arg spec is found. + */ + fname = message = NULL; + min = -1; + max = 0; + while ((i = *format++) != '\0') { + if (isalpha(i) && i != 'e') + max++; + else if (i == '|') + min = max; + else if (i == ':') { fname = format; break; - } else if (c == ';') { + } + else if (i == ';') { message = format; break; - } else if (c == 'e') - ; /* Pass */ - else if (isalpha(c)) - max++; - else if (c == '|') - min = max; + } + else if (i == '(') { + PyErr_SetString(PyExc_SystemError, + "tuple found in format when using keyword arguments"); + return 0; + } } - - if (min < 0) + if (min < 0) { + /* All arguments are required. */ min = max; - + } format = formatsave; - + if (!PyTuple_Check(args)) { PyErr_SetString(PyExc_SystemError, "new style getargs format but argument is not a tuple"); return 0; } - + tplen = PyTuple_GET_SIZE(args); - + /* do a cursory check of the keywords just to see how many we got */ kwlen = 0; |