diff options
Diffstat (limited to 'Python/getargs.c')
| -rw-r--r-- | Python/getargs.c | 65 | 
1 files changed, 36 insertions, 29 deletions
| diff --git a/Python/getargs.c b/Python/getargs.c index ae931b9..2c2628f 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -46,14 +46,16 @@ typedef struct {  } freelistentry_t;  typedef struct { -  int first_available;    freelistentry_t *entries; +  int first_available; +  int entries_malloced;  } freelist_t; +#define STATIC_FREELIST_ENTRIES 8  /* Forward */  static int vgetargs1(PyObject *, const char *, va_list *, int); -static void seterror(int, const char *, int *, const char *, const char *); +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, @@ -187,7 +189,8 @@ cleanreturn(int retval, freelist_t *freelist)                                                freelist->entries[index].item);        }      } -    PyMem_FREE(freelist->entries); +    if (freelist->entries_malloced) +        PyMem_FREE(freelist->entries);      return retval;  } @@ -197,6 +200,8 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)  {      char msgbuf[256];      int levels[32]; +    freelistentry_t static_entries[STATIC_FREELIST_ENTRIES]; +    freelist_t freelist = {static_entries, 0, 0};      const char *fname = NULL;      const char *message = NULL;      int min = -1; @@ -206,7 +211,6 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)      const char *formatsave = format;      Py_ssize_t i, len;      char *msg; -    freelist_t freelist = {0, NULL};      int compat = flags & FLAG_COMPAT;      assert(compat || (args != (PyObject*)NULL)); @@ -240,15 +244,15 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)              message = format;              endfmt = 1;              break; +        case '|': +            if (level == 0) +                min = max; +            break;          default:              if (level == 0) { -                if (c == 'O') -                    max++; -                else if (Py_ISALPHA(Py_CHARMASK(c))) { +                if (Py_ISALPHA(Py_CHARMASK(c)))                      if (c != 'e') /* skip encoded */                          max++; -                } else if (c == '|') -                    min = max;              }              break;          } @@ -262,10 +266,13 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)      format = formatsave; -    freelist.entries = PyMem_NEW(freelistentry_t, max); -    if (freelist.entries == NULL) { -        PyErr_NoMemory(); -        return 0; +    if (max > STATIC_FREELIST_ENTRIES) { +        freelist.entries = PyMem_NEW(freelistentry_t, max); +        if (freelist.entries == NULL) { +            PyErr_NoMemory(); +            return 0; +        } +        freelist.entries_malloced = 1;      }      if (compat) { @@ -350,7 +357,7 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)  static void -seterror(int iarg, const char *msg, int *levels, const char *fname, +seterror(Py_ssize_t iarg, const char *msg, int *levels, const char *fname,           const char *message)  {      char buf[512]; @@ -366,7 +373,7 @@ seterror(int iarg, const char *msg, int *levels, const char *fname,          }          if (iarg != 0) {              PyOS_snprintf(p, sizeof(buf) - (p - buf), -                          "argument %d", iarg); +                          "argument %" PY_FORMAT_SIZE_T "d", iarg);              i = 0;              p += strlen(p);              while (levels[i] > 0 && i < 32 && (int)(p-buf) < 220) { @@ -563,7 +570,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,                  "size does not fit in an int"); \              return converterr("", arg, msgbuf, bufsize); \          } \ -        *q=s; \ +        *q = (int)s; \      }  #define BUFFER_LEN      ((flags & FLAG_SIZE_T) ? *q2:*q)  #define RETURN_ERR_OCCURRED return msgbuf @@ -1421,7 +1428,8 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,      int max = INT_MAX;      int i, len, nargs, nkeywords;      PyObject *current_arg; -    freelist_t freelist = {0, NULL}; +    freelistentry_t static_entries[STATIC_FREELIST_ENTRIES]; +    freelist_t freelist = {static_entries, 0, 0};      assert(args != NULL && PyTuple_Check(args));      assert(keywords == NULL || PyDict_Check(keywords)); @@ -1445,10 +1453,13 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,      for (len=0; kwlist[len]; len++)          continue; -    freelist.entries = PyMem_NEW(freelistentry_t, len); -    if (freelist.entries == NULL) { -        PyErr_NoMemory(); -        return 0; +    if (len > STATIC_FREELIST_ENTRIES) { +        freelist.entries = PyMem_NEW(freelistentry_t, len); +        if (freelist.entries == NULL) { +            PyErr_NoMemory(); +            return 0; +        } +        freelist.entries_malloced = 1;      }      nargs = PyTuple_GET_SIZE(args); @@ -1574,20 +1585,16 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,          Py_ssize_t pos = 0;          while (PyDict_Next(keywords, &pos, &key, &value)) {              int match = 0; -            char *ks;              if (!PyUnicode_Check(key)) {                  PyErr_SetString(PyExc_TypeError,                                  "keywords must be strings");                  return cleanreturn(0, &freelist);              }              /* check that _PyUnicode_AsString() result is not NULL */ -            ks = _PyUnicode_AsString(key); -            if (ks != NULL) { -                for (i = 0; i < len; i++) { -                    if (!strcmp(ks, kwlist[i])) { -                        match = 1; -                        break; -                    } +            for (i = 0; i < len; i++) { +                if (!PyUnicode_CompareWithASCIIString(key, kwlist[i])) { +                    match = 1; +                    break;                  }              }              if (!match) { | 
