diff options
Diffstat (limited to 'Python/getargs.c')
| -rw-r--r-- | Python/getargs.c | 96 | 
1 files changed, 50 insertions, 46 deletions
| diff --git a/Python/getargs.c b/Python/getargs.c index 8aab067..05ec27b 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -20,12 +20,12 @@ int PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *,  #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_Parse_SizeT(PyObject *, const char *, ...); +PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, const 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_VaParse_SizeT(PyObject *, const char *, va_list);  PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *,                                                const char *, char **, va_list);  #endif @@ -56,18 +56,18 @@ typedef struct {  /* Forward */  static int vgetargs1(PyObject *, const char *, va_list *, int);  static void seterror(Py_ssize_t, const char *, int *, const char *, const char *); -static char *convertitem(PyObject *, const char **, va_list *, int, int *, -                         char *, size_t, freelist_t *); -static char *converttuple(PyObject *, const char **, va_list *, int, -                          int *, char *, size_t, int, freelist_t *); -static char *convertsimple(PyObject *, const char **, va_list *, int, char *, -                           size_t, freelist_t *); -static Py_ssize_t convertbuffer(PyObject *, void **p, char **); -static int getbuffer(PyObject *, Py_buffer *, char**); +static const char *convertitem(PyObject *, const char **, va_list *, int, int *, +                               char *, size_t, freelist_t *); +static const char *converttuple(PyObject *, const char **, va_list *, int, +                                int *, char *, size_t, int, freelist_t *); +static const char *convertsimple(PyObject *, const char **, va_list *, int, +                                 char *, size_t, freelist_t *); +static Py_ssize_t convertbuffer(PyObject *, void **p, const char **); +static int getbuffer(PyObject *, Py_buffer *, const char**);  static int vgetargskeywords(PyObject *, PyObject *,                              const char *, char **, va_list *, int); -static char *skipitem(const char **, va_list *, int); +static const char *skipitem(const char **, va_list *, int);  int  PyArg_Parse(PyObject *args, const char *format, ...) @@ -82,7 +82,7 @@ PyArg_Parse(PyObject *args, const char *format, ...)  }  int -_PyArg_Parse_SizeT(PyObject *args, char *format, ...) +_PyArg_Parse_SizeT(PyObject *args, const char *format, ...)  {      int retval;      va_list va; @@ -107,7 +107,7 @@ PyArg_ParseTuple(PyObject *args, const char *format, ...)  }  int -_PyArg_ParseTuple_SizeT(PyObject *args, char *format, ...) +_PyArg_ParseTuple_SizeT(PyObject *args, const char *format, ...)  {      int retval;      va_list va; @@ -130,7 +130,7 @@ PyArg_VaParse(PyObject *args, const char *format, va_list va)  }  int -_PyArg_VaParse_SizeT(PyObject *args, char *format, va_list va) +_PyArg_VaParse_SizeT(PyObject *args, const char *format, va_list va)  {      va_list lva; @@ -208,7 +208,7 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)      int endfmt = 0;      const char *formatsave = format;      Py_ssize_t i, len; -    char *msg; +    const char *msg;      int compat = flags & FLAG_COMPAT;      freelistentry_t static_entries[STATIC_FREELIST_ENTRIES];      freelist_t freelist; @@ -394,7 +394,12 @@ seterror(Py_ssize_t iarg, const char *msg, int *levels, const char *fname,          PyOS_snprintf(p, sizeof(buf) - (p - buf), " %.256s", msg);          message = buf;      } -    PyErr_SetString(PyExc_TypeError, message); +    if (msg[0] == '(') { +        PyErr_SetString(PyExc_SystemError, message); +    } +    else { +        PyErr_SetString(PyExc_TypeError, message); +    }  } @@ -416,7 +421,7 @@ seterror(Py_ssize_t iarg, const char *msg, int *levels, const char *fname,        and msgbuf is returned.  */ -static char * +static const char *  converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,               int *levels, char *msgbuf, size_t bufsize, int toplevel,               freelist_t *freelist) @@ -474,7 +479,7 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,      format = *p_format;      for (i = 0; i < n; i++) { -        char *msg; +        const char *msg;          PyObject *item;          item = PySequence_GetItem(arg, i);          if (item == NULL) { @@ -501,11 +506,11 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,  /* Convert a single item. */ -static char * +static const char *  convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags,              int *levels, char *msgbuf, size_t bufsize, freelist_t *freelist)  { -    char *msg; +    const char *msg;      const char *format = *p_format;      if (*format == '(' /* ')' */) { @@ -530,7 +535,7 @@ convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags,  /* Format an error message generated by convertsimple(). */ -static char * +static const char *  converterr(const char *expected, PyObject *arg, char *msgbuf, size_t bufsize)  {      assert(expected != NULL); @@ -572,7 +577,7 @@ float_argument_error(PyObject *arg)     When you add new format codes, please don't forget poor skipitem() below.  */ -static char * +static const char *  convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,                char *msgbuf, size_t bufsize, freelist_t *freelist)  { @@ -857,7 +862,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,      case 'y': {/* any bytes-like object */          void **p = (void **)va_arg(*p_va, char **); -        char *buf; +        const char *buf;          Py_ssize_t count;          if (*format == '*') {              if (getbuffer(arg, (Py_buffer*)p, &buf) < 0) @@ -904,7 +909,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,                  PyBuffer_FillInfo(p, arg, sarg, len, 1, 0);              }              else { /* any bytes-like object */ -                char *buf; +                const char *buf;                  if (getbuffer(arg, p, &buf) < 0)                      return converterr(buf, arg, msgbuf, bufsize);              } @@ -934,7 +939,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,              }              else { /* read-only bytes-like object */                  /* XXX Really? */ -                char *buf; +                const char *buf;                  Py_ssize_t count = convertbuffer(arg, p, &buf);                  if (count < 0)                      return converterr(buf, arg, msgbuf, bufsize); @@ -1129,7 +1134,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,              } else {                  if (size + 1 > BUFFER_LEN) {                      Py_DECREF(s); -                    PyErr_Format(PyExc_TypeError, +                    PyErr_Format(PyExc_ValueError,                                   "encoded string too long "                                   "(%zd, maximum length %zd)",                                   (Py_ssize_t)size, (Py_ssize_t)(BUFFER_LEN-1)); @@ -1283,7 +1288,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,  }  static Py_ssize_t -convertbuffer(PyObject *arg, void **p, char **errmsg) +convertbuffer(PyObject *arg, void **p, const char **errmsg)  {      PyBufferProcs *pb = Py_TYPE(arg)->tp_as_buffer;      Py_ssize_t count; @@ -1305,7 +1310,7 @@ convertbuffer(PyObject *arg, void **p, char **errmsg)  }  static int -getbuffer(PyObject *arg, Py_buffer *view, char **errmsg) +getbuffer(PyObject *arg, Py_buffer *view, const char **errmsg)  {      if (PyObject_GetBuffer(arg, view, PyBUF_SIMPLE) != 0) {          *errmsg = "bytes-like object"; @@ -1507,7 +1512,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,          keyword = kwlist[i];          if (*format == '|') {              if (min != INT_MAX) { -                PyErr_SetString(PyExc_RuntimeError, +                PyErr_SetString(PyExc_SystemError,                                  "Invalid format string (| specified twice)");                  return cleanreturn(0, &freelist);              } @@ -1516,14 +1521,14 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,              format++;              if (max != INT_MAX) { -                PyErr_SetString(PyExc_RuntimeError, +                PyErr_SetString(PyExc_SystemError,                                  "Invalid format string ($ before |)");                  return cleanreturn(0, &freelist);              }          }          if (*format == '$') {              if (max != INT_MAX) { -                PyErr_SetString(PyExc_RuntimeError, +                PyErr_SetString(PyExc_SystemError,                                  "Invalid format string ($ specified twice)");                  return cleanreturn(0, &freelist);              } @@ -1541,7 +1546,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,              }          }          if (IS_END_OF_FORMAT(*format)) { -            PyErr_Format(PyExc_RuntimeError, +            PyErr_Format(PyExc_SystemError,                           "More keyword list entries (%d) than "                           "format specifiers (%d)", len, i);              return cleanreturn(0, &freelist); @@ -1593,14 +1598,14 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,           * keyword args */          msg = skipitem(&format, p_va, flags);          if (msg) { -            PyErr_Format(PyExc_RuntimeError, "%s: '%s'", msg, +            PyErr_Format(PyExc_SystemError, "%s: '%s'", msg,                           format);              return cleanreturn(0, &freelist);          }      }      if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) { -        PyErr_Format(PyExc_RuntimeError, +        PyErr_Format(PyExc_SystemError,              "more argument specifiers than keyword list entries "              "(remaining format:'%s')", format);          return cleanreturn(0, &freelist); @@ -1637,7 +1642,7 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,  } -static char * +static const char *  skipitem(const char **p_format, va_list *p_va, int flags)  {      const char *format = *p_format; @@ -1730,7 +1735,7 @@ skipitem(const char **p_format, va_list *p_va, int flags)      case '(':           /* bypass tuple, not handled at all previously */          { -            char *msg; +            const char *msg;              for (;;) {                  if (*format==')')                      break; @@ -1766,16 +1771,9 @@ PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t m      PyObject **o;      va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES -    va_start(vargs, max); -#else -    va_start(vargs); -#endif -      assert(min >= 0);      assert(min <= max);      if (!PyTuple_Check(args)) { -        va_end(vargs);          PyErr_SetString(PyExc_SystemError,              "PyArg_UnpackTuple() argument list is not a tuple");          return 0; @@ -1793,9 +1791,10 @@ PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t m                  "unpacked tuple should have %s%zd elements,"                  " but has %zd",                  (min == max ? "" : "at least "), min, l); -        va_end(vargs);          return 0;      } +    if (l == 0) +        return 1;      if (l > max) {          if (name != NULL)              PyErr_Format( @@ -1808,9 +1807,14 @@ PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t m                  "unpacked tuple should have %s%zd elements,"                  " but has %zd",                  (min == max ? "" : "at most "), max, l); -        va_end(vargs);          return 0;      } + +#ifdef HAVE_STDARG_PROTOTYPES +    va_start(vargs, max); +#else +    va_start(vargs); +#endif      for (i = 0; i < l; i++) {          o = va_arg(vargs, PyObject **);          *o = PyTuple_GET_ITEM(args, i); | 
