LCOV - code coverage report
Current view: top level - Python - getargs.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit 5e6661bce9] Lines: 427 1357 31.5 %
Date: 2023-03-20 08:15:36 Functions: 26 55 47.3 %
Branches: 268 1098 24.4 %

           Branch data     Line data    Source code
       1                 :            : 
       2                 :            : /* New getargs implementation */
       3                 :            : 
       4                 :            : #include "Python.h"
       5                 :            : #include "pycore_tuple.h"         // _PyTuple_ITEMS()
       6                 :            : #include "pycore_pylifecycle.h"   // _PyArg_Fini
       7                 :            : 
       8                 :            : #include <ctype.h>
       9                 :            : #include <float.h>
      10                 :            : 
      11                 :            : 
      12                 :            : #ifdef __cplusplus
      13                 :            : extern "C" {
      14                 :            : #endif
      15                 :            : int PyArg_Parse(PyObject *, const char *, ...);
      16                 :            : int PyArg_ParseTuple(PyObject *, const char *, ...);
      17                 :            : int PyArg_VaParse(PyObject *, const char *, va_list);
      18                 :            : 
      19                 :            : int PyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
      20                 :            :                                 const char *, char **, ...);
      21                 :            : int PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *,
      22                 :            :                                 const char *, char **, va_list);
      23                 :            : 
      24                 :            : int _PyArg_ParseTupleAndKeywordsFast(PyObject *, PyObject *,
      25                 :            :                                             struct _PyArg_Parser *, ...);
      26                 :            : int _PyArg_VaParseTupleAndKeywordsFast(PyObject *, PyObject *,
      27                 :            :                                             struct _PyArg_Parser *, va_list);
      28                 :            : 
      29                 :            : #ifdef HAVE_DECLSPEC_DLL
      30                 :            : /* Export functions */
      31                 :            : PyAPI_FUNC(int) _PyArg_Parse_SizeT(PyObject *, const char *, ...);
      32                 :            : PyAPI_FUNC(int) _PyArg_ParseStack_SizeT(PyObject *const *args, Py_ssize_t nargs,
      33                 :            :                                         const char *format, ...);
      34                 :            : PyAPI_FUNC(int) _PyArg_ParseStackAndKeywords_SizeT(PyObject *const *args, Py_ssize_t nargs,
      35                 :            :                                         PyObject *kwnames,
      36                 :            :                                         struct _PyArg_Parser *parser, ...);
      37                 :            : PyAPI_FUNC(int) _PyArg_ParseTuple_SizeT(PyObject *, const char *, ...);
      38                 :            : PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
      39                 :            :                                                   const char *, char **, ...);
      40                 :            : PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...);
      41                 :            : PyAPI_FUNC(int) _PyArg_VaParse_SizeT(PyObject *, const char *, va_list);
      42                 :            : PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
      43                 :            :                                               const char *, char **, va_list);
      44                 :            : 
      45                 :            : PyAPI_FUNC(int) _PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *, PyObject *,
      46                 :            :                                             struct _PyArg_Parser *, ...);
      47                 :            : PyAPI_FUNC(int) _PyArg_VaParseTupleAndKeywordsFast_SizeT(PyObject *, PyObject *,
      48                 :            :                                             struct _PyArg_Parser *, va_list);
      49                 :            : #endif
      50                 :            : 
      51                 :            : #define FLAG_COMPAT 1
      52                 :            : #define FLAG_SIZE_T 2
      53                 :            : 
      54                 :            : typedef int (*destr_t)(PyObject *, void *);
      55                 :            : 
      56                 :            : 
      57                 :            : /* Keep track of "objects" that have been allocated or initialized and
      58                 :            :    which will need to be deallocated or cleaned up somehow if overall
      59                 :            :    parsing fails.
      60                 :            : */
      61                 :            : typedef struct {
      62                 :            :   void *item;
      63                 :            :   destr_t destructor;
      64                 :            : } freelistentry_t;
      65                 :            : 
      66                 :            : typedef struct {
      67                 :            :   freelistentry_t *entries;
      68                 :            :   int first_available;
      69                 :            :   int entries_malloced;
      70                 :            : } freelist_t;
      71                 :            : 
      72                 :            : #define STATIC_FREELIST_ENTRIES 8
      73                 :            : 
      74                 :            : /* Forward */
      75                 :            : static int vgetargs1_impl(PyObject *args, PyObject *const *stack, Py_ssize_t nargs,
      76                 :            :                           const char *format, va_list *p_va, int flags);
      77                 :            : static int vgetargs1(PyObject *, const char *, va_list *, int);
      78                 :            : static void seterror(Py_ssize_t, const char *, int *, const char *, const char *);
      79                 :            : static const char *convertitem(PyObject *, const char **, va_list *, int, int *,
      80                 :            :                                char *, size_t, freelist_t *);
      81                 :            : static const char *converttuple(PyObject *, const char **, va_list *, int,
      82                 :            :                                 int *, char *, size_t, int, freelist_t *);
      83                 :            : static const char *convertsimple(PyObject *, const char **, va_list *, int,
      84                 :            :                                  char *, size_t, freelist_t *);
      85                 :            : static Py_ssize_t convertbuffer(PyObject *, const void **p, const char **);
      86                 :            : static int getbuffer(PyObject *, Py_buffer *, const char**);
      87                 :            : 
      88                 :            : static int vgetargskeywords(PyObject *, PyObject *,
      89                 :            :                             const char *, char **, va_list *, int);
      90                 :            : static int vgetargskeywordsfast(PyObject *, PyObject *,
      91                 :            :                             struct _PyArg_Parser *, va_list *, int);
      92                 :            : static int vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs,
      93                 :            :                           PyObject *keywords, PyObject *kwnames,
      94                 :            :                           struct _PyArg_Parser *parser,
      95                 :            :                           va_list *p_va, int flags);
      96                 :            : static const char *skipitem(const char **, va_list *, int);
      97                 :            : 
      98                 :            : int
      99                 :          0 : PyArg_Parse(PyObject *args, const char *format, ...)
     100                 :            : {
     101                 :            :     int retval;
     102                 :            :     va_list va;
     103                 :            : 
     104                 :          0 :     va_start(va, format);
     105                 :          0 :     retval = vgetargs1(args, format, &va, FLAG_COMPAT);
     106                 :          0 :     va_end(va);
     107                 :          0 :     return retval;
     108                 :            : }
     109                 :            : 
     110                 :            : PyAPI_FUNC(int)
     111                 :          0 : _PyArg_Parse_SizeT(PyObject *args, const char *format, ...)
     112                 :            : {
     113                 :            :     int retval;
     114                 :            :     va_list va;
     115                 :            : 
     116                 :          0 :     va_start(va, format);
     117                 :          0 :     retval = vgetargs1(args, format, &va, FLAG_COMPAT|FLAG_SIZE_T);
     118                 :          0 :     va_end(va);
     119                 :          0 :     return retval;
     120                 :            : }
     121                 :            : 
     122                 :            : 
     123                 :            : int
     124                 :     106645 : PyArg_ParseTuple(PyObject *args, const char *format, ...)
     125                 :            : {
     126                 :            :     int retval;
     127                 :            :     va_list va;
     128                 :            : 
     129                 :     106645 :     va_start(va, format);
     130                 :     106645 :     retval = vgetargs1(args, format, &va, 0);
     131                 :     106645 :     va_end(va);
     132                 :     106645 :     return retval;
     133                 :            : }
     134                 :            : 
     135                 :            : PyAPI_FUNC(int)
     136                 :      23529 : _PyArg_ParseTuple_SizeT(PyObject *args, const char *format, ...)
     137                 :            : {
     138                 :            :     int retval;
     139                 :            :     va_list va;
     140                 :            : 
     141                 :      23529 :     va_start(va, format);
     142                 :      23529 :     retval = vgetargs1(args, format, &va, FLAG_SIZE_T);
     143                 :      23529 :     va_end(va);
     144                 :      23529 :     return retval;
     145                 :            : }
     146                 :            : 
     147                 :            : 
     148                 :            : int
     149                 :          0 : _PyArg_ParseStack(PyObject *const *args, Py_ssize_t nargs, const char *format, ...)
     150                 :            : {
     151                 :            :     int retval;
     152                 :            :     va_list va;
     153                 :            : 
     154                 :          0 :     va_start(va, format);
     155                 :          0 :     retval = vgetargs1_impl(NULL, args, nargs, format, &va, 0);
     156                 :          0 :     va_end(va);
     157                 :          0 :     return retval;
     158                 :            : }
     159                 :            : 
     160                 :            : PyAPI_FUNC(int)
     161                 :          1 : _PyArg_ParseStack_SizeT(PyObject *const *args, Py_ssize_t nargs, const char *format, ...)
     162                 :            : {
     163                 :            :     int retval;
     164                 :            :     va_list va;
     165                 :            : 
     166                 :          1 :     va_start(va, format);
     167                 :          1 :     retval = vgetargs1_impl(NULL, args, nargs, format, &va, FLAG_SIZE_T);
     168                 :          1 :     va_end(va);
     169                 :          1 :     return retval;
     170                 :            : }
     171                 :            : 
     172                 :            : 
     173                 :            : int
     174                 :          0 : PyArg_VaParse(PyObject *args, const char *format, va_list va)
     175                 :            : {
     176                 :            :     va_list lva;
     177                 :            :     int retval;
     178                 :            : 
     179                 :          0 :     va_copy(lva, va);
     180                 :            : 
     181                 :          0 :     retval = vgetargs1(args, format, &lva, 0);
     182                 :          0 :     va_end(lva);
     183                 :          0 :     return retval;
     184                 :            : }
     185                 :            : 
     186                 :            : PyAPI_FUNC(int)
     187                 :          0 : _PyArg_VaParse_SizeT(PyObject *args, const char *format, va_list va)
     188                 :            : {
     189                 :            :     va_list lva;
     190                 :            :     int retval;
     191                 :            : 
     192                 :          0 :     va_copy(lva, va);
     193                 :            : 
     194                 :          0 :     retval = vgetargs1(args, format, &lva, FLAG_SIZE_T);
     195                 :          0 :     va_end(lva);
     196                 :          0 :     return retval;
     197                 :            : }
     198                 :            : 
     199                 :            : 
     200                 :            : /* Handle cleanup of allocated memory in case of exception */
     201                 :            : 
     202                 :            : static int
     203                 :          0 : cleanup_ptr(PyObject *self, void *ptr)
     204                 :            : {
     205                 :          0 :     void **pptr = (void **)ptr;
     206                 :          0 :     PyMem_Free(*pptr);
     207                 :          0 :     *pptr = NULL;
     208                 :          0 :     return 0;
     209                 :            : }
     210                 :            : 
     211                 :            : static int
     212                 :          0 : cleanup_buffer(PyObject *self, void *ptr)
     213                 :            : {
     214                 :          0 :     Py_buffer *buf = (Py_buffer *)ptr;
     215         [ #  # ]:          0 :     if (buf) {
     216                 :          0 :         PyBuffer_Release(buf);
     217                 :            :     }
     218                 :          0 :     return 0;
     219                 :            : }
     220                 :            : 
     221                 :            : static int
     222                 :          0 : addcleanup(void *ptr, freelist_t *freelist, destr_t destructor)
     223                 :            : {
     224                 :            :     int index;
     225                 :            : 
     226                 :          0 :     index = freelist->first_available;
     227                 :          0 :     freelist->first_available += 1;
     228                 :            : 
     229                 :          0 :     freelist->entries[index].item = ptr;
     230                 :          0 :     freelist->entries[index].destructor = destructor;
     231                 :            : 
     232                 :          0 :     return 0;
     233                 :            : }
     234                 :            : 
     235                 :            : static int
     236                 :     260408 : cleanreturn(int retval, freelist_t *freelist)
     237                 :            : {
     238                 :            :     int index;
     239                 :            : 
     240         [ -  + ]:     260408 :     if (retval == 0) {
     241                 :            :       /* A failure occurred, therefore execute all of the cleanup
     242                 :            :          functions.
     243                 :            :       */
     244         [ #  # ]:          0 :       for (index = 0; index < freelist->first_available; ++index) {
     245                 :          0 :           freelist->entries[index].destructor(NULL,
     246                 :          0 :                                               freelist->entries[index].item);
     247                 :            :       }
     248                 :            :     }
     249         [ +  + ]:     260408 :     if (freelist->entries_malloced)
     250                 :         30 :         PyMem_Free(freelist->entries);
     251                 :     260408 :     return retval;
     252                 :            : }
     253                 :            : 
     254                 :            : 
     255                 :            : static int
     256                 :     130175 : vgetargs1_impl(PyObject *compat_args, PyObject *const *stack, Py_ssize_t nargs, const char *format,
     257                 :            :                va_list *p_va, int flags)
     258                 :            : {
     259                 :            :     char msgbuf[256];
     260                 :            :     int levels[32];
     261                 :     130175 :     const char *fname = NULL;
     262                 :     130175 :     const char *message = NULL;
     263                 :     130175 :     int min = -1;
     264                 :     130175 :     int max = 0;
     265                 :     130175 :     int level = 0;
     266                 :     130175 :     int endfmt = 0;
     267                 :     130175 :     const char *formatsave = format;
     268                 :            :     Py_ssize_t i;
     269                 :            :     const char *msg;
     270                 :     130175 :     int compat = flags & FLAG_COMPAT;
     271                 :            :     freelistentry_t static_entries[STATIC_FREELIST_ENTRIES];
     272                 :            :     freelist_t freelist;
     273                 :            : 
     274                 :            :     assert(nargs == 0 || stack != NULL);
     275                 :            : 
     276                 :     130175 :     freelist.entries = static_entries;
     277                 :     130175 :     freelist.first_available = 0;
     278                 :     130175 :     freelist.entries_malloced = 0;
     279                 :            : 
     280                 :     130175 :     flags = flags & ~FLAG_COMPAT;
     281                 :            : 
     282         [ +  + ]:     486266 :     while (endfmt == 0) {
     283                 :     356091 :         int c = *format++;
     284   [ -  -  +  +  :     356091 :         switch (c) {
                +  +  + ]
     285                 :          0 :         case '(':
     286         [ #  # ]:          0 :             if (level == 0)
     287                 :          0 :                 max++;
     288                 :          0 :             level++;
     289         [ #  # ]:          0 :             if (level >= 30)
     290                 :          0 :                 Py_FatalError("too many tuple nesting levels "
     291                 :            :                               "in argument format string");
     292                 :          0 :             break;
     293                 :          0 :         case ')':
     294         [ #  # ]:          0 :             if (level == 0)
     295                 :          0 :                 Py_FatalError("excess ')' in getargs format");
     296                 :            :             else
     297                 :          0 :                 level--;
     298                 :          0 :             break;
     299                 :        298 :         case '\0':
     300                 :        298 :             endfmt = 1;
     301                 :        298 :             break;
     302                 :     129861 :         case ':':
     303                 :     129861 :             fname = format;
     304                 :     129861 :             endfmt = 1;
     305                 :     129861 :             break;
     306                 :         16 :         case ';':
     307                 :         16 :             message = format;
     308                 :         16 :             endfmt = 1;
     309                 :         16 :             break;
     310                 :      23513 :         case '|':
     311         [ +  - ]:      23513 :             if (level == 0)
     312                 :      23513 :                 min = max;
     313                 :      23513 :             break;
     314                 :     202403 :         default:
     315         [ +  - ]:     202403 :             if (level == 0) {
     316         [ +  + ]:     202403 :                 if (Py_ISALPHA(c))
     317         [ +  - ]:     189815 :                     if (c != 'e') /* skip encoded */
     318                 :     189815 :                         max++;
     319                 :            :             }
     320                 :     202403 :             break;
     321                 :            :         }
     322                 :            :     }
     323                 :            : 
     324         [ -  + ]:     130175 :     if (level != 0)
     325                 :          0 :         Py_FatalError(/* '(' */ "missing ')' in getargs format");
     326                 :            : 
     327         [ +  + ]:     130175 :     if (min < 0)
     328                 :     106662 :         min = max;
     329                 :            : 
     330                 :     130175 :     format = formatsave;
     331                 :            : 
     332         [ -  + ]:     130175 :     if (max > STATIC_FREELIST_ENTRIES) {
     333         [ #  # ]:          0 :         freelist.entries = PyMem_NEW(freelistentry_t, max);
     334         [ #  # ]:          0 :         if (freelist.entries == NULL) {
     335                 :          0 :             PyErr_NoMemory();
     336                 :          0 :             return 0;
     337                 :            :         }
     338                 :          0 :         freelist.entries_malloced = 1;
     339                 :            :     }
     340                 :            : 
     341         [ -  + ]:     130175 :     if (compat) {
     342         [ #  # ]:          0 :         if (max == 0) {
     343         [ #  # ]:          0 :             if (compat_args == NULL)
     344                 :          0 :                 return 1;
     345   [ #  #  #  # ]:          0 :             PyErr_Format(PyExc_TypeError,
     346                 :            :                          "%.200s%s takes no arguments",
     347                 :            :                          fname==NULL ? "function" : fname,
     348                 :            :                          fname==NULL ? "" : "()");
     349                 :          0 :             return cleanreturn(0, &freelist);
     350                 :            :         }
     351   [ #  #  #  # ]:          0 :         else if (min == 1 && max == 1) {
     352         [ #  # ]:          0 :             if (compat_args == NULL) {
     353   [ #  #  #  # ]:          0 :                 PyErr_Format(PyExc_TypeError,
     354                 :            :                              "%.200s%s takes at least one argument",
     355                 :            :                              fname==NULL ? "function" : fname,
     356                 :            :                              fname==NULL ? "" : "()");
     357                 :          0 :                 return cleanreturn(0, &freelist);
     358                 :            :             }
     359                 :          0 :             msg = convertitem(compat_args, &format, p_va, flags, levels,
     360                 :            :                               msgbuf, sizeof(msgbuf), &freelist);
     361         [ #  # ]:          0 :             if (msg == NULL)
     362                 :          0 :                 return cleanreturn(1, &freelist);
     363                 :          0 :             seterror(levels[0], msg, levels+1, fname, message);
     364                 :          0 :             return cleanreturn(0, &freelist);
     365                 :            :         }
     366                 :            :         else {
     367                 :          0 :             PyErr_SetString(PyExc_SystemError,
     368                 :            :                 "old style getargs format uses new features");
     369                 :          0 :             return cleanreturn(0, &freelist);
     370                 :            :         }
     371                 :            :     }
     372                 :            : 
     373   [ +  -  -  + ]:     130175 :     if (nargs < min || max < nargs) {
     374         [ #  # ]:          0 :         if (message == NULL)
     375   [ #  #  #  #  :          0 :             PyErr_Format(PyExc_TypeError,
             #  #  #  # ]
     376                 :            :                          "%.150s%s takes %s %d argument%s (%zd given)",
     377                 :            :                          fname==NULL ? "function" : fname,
     378                 :            :                          fname==NULL ? "" : "()",
     379                 :            :                          min==max ? "exactly"
     380         [ #  # ]:          0 :                          : nargs < min ? "at least" : "at most",
     381         [ #  # ]:          0 :                          nargs < min ? min : max,
     382         [ #  # ]:          0 :                          (nargs < min ? min : max) == 1 ? "" : "s",
     383                 :            :                          nargs);
     384                 :            :         else
     385                 :          0 :             PyErr_SetString(PyExc_TypeError, message);
     386                 :          0 :         return cleanreturn(0, &freelist);
     387                 :            :     }
     388                 :            : 
     389         [ +  + ]:     273914 :     for (i = 0; i < nargs; i++) {
     390         [ +  + ]:     143739 :         if (*format == '|')
     391                 :        835 :             format++;
     392                 :     143739 :         msg = convertitem(stack[i], &format, p_va,
     393                 :            :                           flags, levels, msgbuf,
     394                 :            :                           sizeof(msgbuf), &freelist);
     395         [ -  + ]:     143739 :         if (msg) {
     396                 :          0 :             seterror(i+1, msg, levels, fname, message);
     397                 :          0 :             return cleanreturn(0, &freelist);
     398                 :            :         }
     399                 :            :     }
     400                 :            : 
     401   [ +  +  +  + ]:     130175 :     if (*format != '\0' && !Py_ISALPHA(*format) &&
     402         [ +  - ]:     129156 :         *format != '(' &&
     403   [ +  +  +  +  :     129156 :         *format != '|' && *format != ':' && *format != ';') {
                   -  + ]
     404                 :          0 :         PyErr_Format(PyExc_SystemError,
     405                 :            :                      "bad format string: %.200s", formatsave);
     406                 :          0 :         return cleanreturn(0, &freelist);
     407                 :            :     }
     408                 :            : 
     409                 :     130175 :     return cleanreturn(1, &freelist);
     410                 :            : }
     411                 :            : 
     412                 :            : static int
     413                 :     130174 : vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
     414                 :            : {
     415                 :            :     PyObject **stack;
     416                 :            :     Py_ssize_t nargs;
     417                 :            : 
     418         [ +  - ]:     130174 :     if (!(flags & FLAG_COMPAT)) {
     419                 :            :         assert(args != NULL);
     420                 :            : 
     421         [ -  + ]:     130174 :         if (!PyTuple_Check(args)) {
     422                 :          0 :             PyErr_SetString(PyExc_SystemError,
     423                 :            :                 "new style getargs format but argument is not a tuple");
     424                 :          0 :             return 0;
     425                 :            :         }
     426                 :            : 
     427                 :     130174 :         stack = _PyTuple_ITEMS(args);
     428                 :     130174 :         nargs = PyTuple_GET_SIZE(args);
     429                 :            :     }
     430                 :            :     else {
     431                 :          0 :         stack = NULL;
     432                 :          0 :         nargs = 0;
     433                 :            :     }
     434                 :            : 
     435                 :     130174 :     return vgetargs1_impl(args, stack, nargs, format, p_va, flags);
     436                 :            : }
     437                 :            : 
     438                 :            : 
     439                 :            : static void
     440                 :          0 : seterror(Py_ssize_t iarg, const char *msg, int *levels, const char *fname,
     441                 :            :          const char *message)
     442                 :            : {
     443                 :            :     char buf[512];
     444                 :            :     int i;
     445                 :          0 :     char *p = buf;
     446                 :            : 
     447         [ #  # ]:          0 :     if (PyErr_Occurred())
     448                 :          0 :         return;
     449         [ #  # ]:          0 :     else if (message == NULL) {
     450         [ #  # ]:          0 :         if (fname != NULL) {
     451                 :          0 :             PyOS_snprintf(p, sizeof(buf), "%.200s() ", fname);
     452                 :          0 :             p += strlen(p);
     453                 :            :         }
     454         [ #  # ]:          0 :         if (iarg != 0) {
     455                 :          0 :             PyOS_snprintf(p, sizeof(buf) - (p - buf),
     456                 :            :                           "argument %zd", iarg);
     457                 :          0 :             i = 0;
     458                 :          0 :             p += strlen(p);
     459   [ #  #  #  #  :          0 :             while (i < 32 && levels[i] > 0 && (int)(p-buf) < 220) {
                   #  # ]
     460                 :          0 :                 PyOS_snprintf(p, sizeof(buf) - (p - buf),
     461                 :          0 :                               ", item %d", levels[i]-1);
     462                 :          0 :                 p += strlen(p);
     463                 :          0 :                 i++;
     464                 :            :             }
     465                 :            :         }
     466                 :            :         else {
     467                 :          0 :             PyOS_snprintf(p, sizeof(buf) - (p - buf), "argument");
     468                 :          0 :             p += strlen(p);
     469                 :            :         }
     470                 :          0 :         PyOS_snprintf(p, sizeof(buf) - (p - buf), " %.256s", msg);
     471                 :          0 :         message = buf;
     472                 :            :     }
     473         [ #  # ]:          0 :     if (msg[0] == '(') {
     474                 :          0 :         PyErr_SetString(PyExc_SystemError, message);
     475                 :            :     }
     476                 :            :     else {
     477                 :          0 :         PyErr_SetString(PyExc_TypeError, message);
     478                 :            :     }
     479                 :            : }
     480                 :            : 
     481                 :            : 
     482                 :            : /* Convert a tuple argument.
     483                 :            :    On entry, *p_format points to the character _after_ the opening '('.
     484                 :            :    On successful exit, *p_format points to the closing ')'.
     485                 :            :    If successful:
     486                 :            :       *p_format and *p_va are updated,
     487                 :            :       *levels and *msgbuf are untouched,
     488                 :            :       and NULL is returned.
     489                 :            :    If the argument is invalid:
     490                 :            :       *p_format is unchanged,
     491                 :            :       *p_va is undefined,
     492                 :            :       *levels is a 0-terminated list of item numbers,
     493                 :            :       *msgbuf contains an error message, whose format is:
     494                 :            :      "must be <typename1>, not <typename2>", where:
     495                 :            :         <typename1> is the name of the expected type, and
     496                 :            :         <typename2> is the name of the actual type,
     497                 :            :       and msgbuf is returned.
     498                 :            : */
     499                 :            : 
     500                 :            : static const char *
     501                 :          0 : converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
     502                 :            :              int *levels, char *msgbuf, size_t bufsize, int toplevel,
     503                 :            :              freelist_t *freelist)
     504                 :            : {
     505                 :          0 :     int level = 0;
     506                 :          0 :     int n = 0;
     507                 :          0 :     const char *format = *p_format;
     508                 :            :     int i;
     509                 :            :     Py_ssize_t len;
     510                 :            : 
     511                 :          0 :     for (;;) {
     512                 :          0 :         int c = *format++;
     513         [ #  # ]:          0 :         if (c == '(') {
     514         [ #  # ]:          0 :             if (level == 0)
     515                 :          0 :                 n++;
     516                 :          0 :             level++;
     517                 :            :         }
     518         [ #  # ]:          0 :         else if (c == ')') {
     519         [ #  # ]:          0 :             if (level == 0)
     520                 :          0 :                 break;
     521                 :          0 :             level--;
     522                 :            :         }
     523   [ #  #  #  #  :          0 :         else if (c == ':' || c == ';' || c == '\0')
                   #  # ]
     524                 :            :             break;
     525   [ #  #  #  # ]:          0 :         else if (level == 0 && Py_ISALPHA(c))
     526                 :          0 :             n++;
     527                 :            :     }
     528                 :            : 
     529   [ #  #  #  # ]:          0 :     if (!PySequence_Check(arg) || PyBytes_Check(arg)) {
     530                 :          0 :         levels[0] = 0;
     531   [ #  #  #  # ]:          0 :         PyOS_snprintf(msgbuf, bufsize,
     532                 :            :                       toplevel ? "expected %d arguments, not %.50s" :
     533                 :            :                       "must be %d-item sequence, not %.50s",
     534                 :            :                   n,
     535                 :          0 :                   arg == Py_None ? "None" : Py_TYPE(arg)->tp_name);
     536                 :          0 :         return msgbuf;
     537                 :            :     }
     538                 :            : 
     539                 :          0 :     len = PySequence_Size(arg);
     540         [ #  # ]:          0 :     if (len != n) {
     541                 :          0 :         levels[0] = 0;
     542         [ #  # ]:          0 :         if (toplevel) {
     543         [ #  # ]:          0 :             PyOS_snprintf(msgbuf, bufsize,
     544                 :            :                           "expected %d argument%s, not %zd",
     545                 :            :                           n,
     546                 :            :                           n == 1 ? "" : "s",
     547                 :            :                           len);
     548                 :            :         }
     549                 :            :         else {
     550                 :          0 :             PyOS_snprintf(msgbuf, bufsize,
     551                 :            :                           "must be sequence of length %d, not %zd",
     552                 :            :                           n, len);
     553                 :            :         }
     554                 :          0 :         return msgbuf;
     555                 :            :     }
     556                 :            : 
     557                 :          0 :     format = *p_format;
     558         [ #  # ]:          0 :     for (i = 0; i < n; i++) {
     559                 :            :         const char *msg;
     560                 :            :         PyObject *item;
     561                 :          0 :         item = PySequence_GetItem(arg, i);
     562         [ #  # ]:          0 :         if (item == NULL) {
     563                 :          0 :             PyErr_Clear();
     564                 :          0 :             levels[0] = i+1;
     565                 :          0 :             levels[1] = 0;
     566                 :          0 :             strncpy(msgbuf, "is not retrievable", bufsize);
     567                 :          0 :             return msgbuf;
     568                 :            :         }
     569                 :          0 :         msg = convertitem(item, &format, p_va, flags, levels+1,
     570                 :            :                           msgbuf, bufsize, freelist);
     571                 :            :         /* PySequence_GetItem calls tp->sq_item, which INCREFs */
     572                 :          0 :         Py_XDECREF(item);
     573         [ #  # ]:          0 :         if (msg != NULL) {
     574                 :          0 :             levels[0] = i+1;
     575                 :          0 :             return msg;
     576                 :            :         }
     577                 :            :     }
     578                 :            : 
     579                 :          0 :     *p_format = format;
     580                 :          0 :     return NULL;
     581                 :            : }
     582                 :            : 
     583                 :            : 
     584                 :            : /* Convert a single item. */
     585                 :            : 
     586                 :            : static const char *
     587                 :     144805 : convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags,
     588                 :            :             int *levels, char *msgbuf, size_t bufsize, freelist_t *freelist)
     589                 :            : {
     590                 :            :     const char *msg;
     591                 :     144805 :     const char *format = *p_format;
     592                 :            : 
     593         [ -  + ]:     144805 :     if (*format == '(' /* ')' */) {
     594                 :          0 :         format++;
     595                 :          0 :         msg = converttuple(arg, &format, p_va, flags, levels, msgbuf,
     596                 :            :                            bufsize, 0, freelist);
     597         [ #  # ]:          0 :         if (msg == NULL)
     598                 :          0 :             format++;
     599                 :            :     }
     600                 :            :     else {
     601                 :     144805 :         msg = convertsimple(arg, &format, p_va, flags,
     602                 :            :                             msgbuf, bufsize, freelist);
     603         [ -  + ]:     144805 :         if (msg != NULL)
     604                 :          0 :             levels[0] = 0;
     605                 :            :     }
     606         [ +  - ]:     144805 :     if (msg == NULL)
     607                 :     144805 :         *p_format = format;
     608                 :     144805 :     return msg;
     609                 :            : }
     610                 :            : 
     611                 :            : 
     612                 :            : 
     613                 :            : /* Format an error message generated by convertsimple().
     614                 :            :    displayname must be UTF-8 encoded.
     615                 :            : */
     616                 :            : 
     617                 :            : void
     618                 :          0 : _PyArg_BadArgument(const char *fname, const char *displayname,
     619                 :            :                    const char *expected, PyObject *arg)
     620                 :            : {
     621         [ #  # ]:          0 :     PyErr_Format(PyExc_TypeError,
     622                 :            :                  "%.200s() %.200s must be %.50s, not %.50s",
     623                 :            :                  fname, displayname, expected,
     624                 :          0 :                  arg == Py_None ? "None" : Py_TYPE(arg)->tp_name);
     625                 :          0 : }
     626                 :            : 
     627                 :            : static const char *
     628                 :          0 : converterr(const char *expected, PyObject *arg, char *msgbuf, size_t bufsize)
     629                 :            : {
     630                 :            :     assert(expected != NULL);
     631                 :            :     assert(arg != NULL);
     632         [ #  # ]:          0 :     if (expected[0] == '(') {
     633                 :          0 :         PyOS_snprintf(msgbuf, bufsize,
     634                 :            :                       "%.100s", expected);
     635                 :            :     }
     636                 :            :     else {
     637         [ #  # ]:          0 :         PyOS_snprintf(msgbuf, bufsize,
     638                 :            :                       "must be %.50s, not %.50s", expected,
     639                 :          0 :                       arg == Py_None ? "None" : Py_TYPE(arg)->tp_name);
     640                 :            :     }
     641                 :          0 :     return msgbuf;
     642                 :            : }
     643                 :            : 
     644                 :            : #define CONV_UNICODE "(unicode conversion error)"
     645                 :            : 
     646                 :            : /* Convert a non-tuple argument.  Return NULL if conversion went OK,
     647                 :            :    or a string with a message describing the failure.  The message is
     648                 :            :    formatted as "must be <desired type>, not <actual type>".
     649                 :            :    When failing, an exception may or may not have been raised.
     650                 :            :    Don't call if a tuple is expected.
     651                 :            : 
     652                 :            :    When you add new format codes, please don't forget poor skipitem() below.
     653                 :            : */
     654                 :            : 
     655                 :            : static const char *
     656                 :     144805 : convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
     657                 :            :               char *msgbuf, size_t bufsize, freelist_t *freelist)
     658                 :            : {
     659                 :            : #define RETURN_ERR_OCCURRED return msgbuf
     660                 :            :     /* For # codes */
     661                 :            : #define REQUIRE_PY_SSIZE_T_CLEAN \
     662                 :            :     if (!(flags & FLAG_SIZE_T)) { \
     663                 :            :         PyErr_SetString(PyExc_SystemError, \
     664                 :            :                         "PY_SSIZE_T_CLEAN macro must be defined for '#' formats"); \
     665                 :            :         RETURN_ERR_OCCURRED; \
     666                 :            :     }
     667                 :            : 
     668                 :     144805 :     const char *format = *p_format;
     669                 :     144805 :     char c = *format++;
     670                 :            :     const char *sarg;
     671                 :            : 
     672   [ -  -  -  -  :     144805 :     switch (c) {
          +  -  +  -  -  
          -  +  -  -  -  
          -  -  +  -  -  
          -  -  -  +  +  
                   -  - ]
     673                 :            : 
     674                 :          0 :     case 'b': { /* unsigned byte -- very short int */
     675                 :          0 :         char *p = va_arg(*p_va, char *);
     676                 :          0 :         long ival = PyLong_AsLong(arg);
     677   [ #  #  #  # ]:          0 :         if (ival == -1 && PyErr_Occurred())
     678                 :          0 :             RETURN_ERR_OCCURRED;
     679         [ #  # ]:          0 :         else if (ival < 0) {
     680                 :          0 :             PyErr_SetString(PyExc_OverflowError,
     681                 :            :                             "unsigned byte integer is less than minimum");
     682                 :          0 :             RETURN_ERR_OCCURRED;
     683                 :            :         }
     684         [ #  # ]:          0 :         else if (ival > UCHAR_MAX) {
     685                 :          0 :             PyErr_SetString(PyExc_OverflowError,
     686                 :            :                             "unsigned byte integer is greater than maximum");
     687                 :          0 :             RETURN_ERR_OCCURRED;
     688                 :            :         }
     689                 :            :         else
     690                 :          0 :             *p = (unsigned char) ival;
     691                 :          0 :         break;
     692                 :            :     }
     693                 :            : 
     694                 :          0 :     case 'B': {/* byte sized bitfield - both signed and unsigned
     695                 :            :                   values allowed */
     696                 :          0 :         char *p = va_arg(*p_va, char *);
     697                 :          0 :         unsigned long ival = PyLong_AsUnsignedLongMask(arg);
     698   [ #  #  #  # ]:          0 :         if (ival == (unsigned long)-1 && PyErr_Occurred())
     699                 :          0 :             RETURN_ERR_OCCURRED;
     700                 :            :         else
     701                 :          0 :             *p = (unsigned char) ival;
     702                 :          0 :         break;
     703                 :            :     }
     704                 :            : 
     705                 :          0 :     case 'h': {/* signed short int */
     706                 :          0 :         short *p = va_arg(*p_va, short *);
     707                 :          0 :         long ival = PyLong_AsLong(arg);
     708   [ #  #  #  # ]:          0 :         if (ival == -1 && PyErr_Occurred())
     709                 :          0 :             RETURN_ERR_OCCURRED;
     710         [ #  # ]:          0 :         else if (ival < SHRT_MIN) {
     711                 :          0 :             PyErr_SetString(PyExc_OverflowError,
     712                 :            :                             "signed short integer is less than minimum");
     713                 :          0 :             RETURN_ERR_OCCURRED;
     714                 :            :         }
     715         [ #  # ]:          0 :         else if (ival > SHRT_MAX) {
     716                 :          0 :             PyErr_SetString(PyExc_OverflowError,
     717                 :            :                             "signed short integer is greater than maximum");
     718                 :          0 :             RETURN_ERR_OCCURRED;
     719                 :            :         }
     720                 :            :         else
     721                 :          0 :             *p = (short) ival;
     722                 :          0 :         break;
     723                 :            :     }
     724                 :            : 
     725                 :          0 :     case 'H': { /* short int sized bitfield, both signed and
     726                 :            :                    unsigned allowed */
     727                 :          0 :         unsigned short *p = va_arg(*p_va, unsigned short *);
     728                 :          0 :         unsigned long ival = PyLong_AsUnsignedLongMask(arg);
     729   [ #  #  #  # ]:          0 :         if (ival == (unsigned long)-1 && PyErr_Occurred())
     730                 :          0 :             RETURN_ERR_OCCURRED;
     731                 :            :         else
     732                 :          0 :             *p = (unsigned short) ival;
     733                 :          0 :         break;
     734                 :            :     }
     735                 :            : 
     736                 :          6 :     case 'i': {/* signed int */
     737                 :          6 :         int *p = va_arg(*p_va, int *);
     738                 :          6 :         long ival = PyLong_AsLong(arg);
     739   [ +  +  -  + ]:          6 :         if (ival == -1 && PyErr_Occurred())
     740                 :          0 :             RETURN_ERR_OCCURRED;
     741         [ -  + ]:          6 :         else if (ival > INT_MAX) {
     742                 :          0 :             PyErr_SetString(PyExc_OverflowError,
     743                 :            :                             "signed integer is greater than maximum");
     744                 :          0 :             RETURN_ERR_OCCURRED;
     745                 :            :         }
     746         [ -  + ]:          6 :         else if (ival < INT_MIN) {
     747                 :          0 :             PyErr_SetString(PyExc_OverflowError,
     748                 :            :                             "signed integer is less than minimum");
     749                 :          0 :             RETURN_ERR_OCCURRED;
     750                 :            :         }
     751                 :            :         else
     752                 :          6 :             *p = ival;
     753                 :          6 :         break;
     754                 :            :     }
     755                 :            : 
     756                 :          0 :     case 'I': { /* int sized bitfield, both signed and
     757                 :            :                    unsigned allowed */
     758                 :          0 :         unsigned int *p = va_arg(*p_va, unsigned int *);
     759                 :          0 :         unsigned long ival = PyLong_AsUnsignedLongMask(arg);
     760   [ #  #  #  # ]:          0 :         if (ival == (unsigned long)-1 && PyErr_Occurred())
     761                 :          0 :             RETURN_ERR_OCCURRED;
     762                 :            :         else
     763                 :          0 :             *p = (unsigned int) ival;
     764                 :          0 :         break;
     765                 :            :     }
     766                 :            : 
     767                 :        348 :     case 'n': /* Py_ssize_t */
     768                 :            :     {
     769                 :            :         PyObject *iobj;
     770                 :        348 :         Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *);
     771                 :        348 :         Py_ssize_t ival = -1;
     772                 :        348 :         iobj = _PyNumber_Index(arg);
     773         [ +  - ]:        348 :         if (iobj != NULL) {
     774                 :        348 :             ival = PyLong_AsSsize_t(iobj);
     775                 :        348 :             Py_DECREF(iobj);
     776                 :            :         }
     777   [ -  +  -  - ]:        348 :         if (ival == -1 && PyErr_Occurred())
     778                 :          0 :             RETURN_ERR_OCCURRED;
     779                 :        348 :         *p = ival;
     780                 :        348 :         break;
     781                 :            :     }
     782                 :          0 :     case 'l': {/* long int */
     783                 :          0 :         long *p = va_arg(*p_va, long *);
     784                 :          0 :         long ival = PyLong_AsLong(arg);
     785   [ #  #  #  # ]:          0 :         if (ival == -1 && PyErr_Occurred())
     786                 :          0 :             RETURN_ERR_OCCURRED;
     787                 :            :         else
     788                 :          0 :             *p = ival;
     789                 :          0 :         break;
     790                 :            :     }
     791                 :            : 
     792                 :          0 :     case 'k': { /* long sized bitfield */
     793                 :          0 :         unsigned long *p = va_arg(*p_va, unsigned long *);
     794                 :            :         unsigned long ival;
     795         [ #  # ]:          0 :         if (PyLong_Check(arg))
     796                 :          0 :             ival = PyLong_AsUnsignedLongMask(arg);
     797                 :            :         else
     798                 :          0 :             return converterr("int", arg, msgbuf, bufsize);
     799                 :          0 :         *p = ival;
     800                 :          0 :         break;
     801                 :            :     }
     802                 :            : 
     803                 :          0 :     case 'L': {/* long long */
     804                 :          0 :         long long *p = va_arg( *p_va, long long * );
     805                 :          0 :         long long ival = PyLong_AsLongLong(arg);
     806   [ #  #  #  # ]:          0 :         if (ival == (long long)-1 && PyErr_Occurred())
     807                 :          0 :             RETURN_ERR_OCCURRED;
     808                 :            :         else
     809                 :          0 :             *p = ival;
     810                 :          0 :         break;
     811                 :            :     }
     812                 :            : 
     813                 :          8 :     case 'K': { /* long long sized bitfield */
     814                 :          8 :         unsigned long long *p = va_arg(*p_va, unsigned long long *);
     815                 :            :         unsigned long long ival;
     816         [ +  - ]:          8 :         if (PyLong_Check(arg))
     817                 :          8 :             ival = PyLong_AsUnsignedLongLongMask(arg);
     818                 :            :         else
     819                 :          0 :             return converterr("int", arg, msgbuf, bufsize);
     820                 :          8 :         *p = ival;
     821                 :          8 :         break;
     822                 :            :     }
     823                 :            : 
     824                 :          0 :     case 'f': {/* float */
     825                 :          0 :         float *p = va_arg(*p_va, float *);
     826                 :          0 :         double dval = PyFloat_AsDouble(arg);
     827   [ #  #  #  # ]:          0 :         if (dval == -1.0 && PyErr_Occurred())
     828                 :          0 :             RETURN_ERR_OCCURRED;
     829                 :            :         else
     830                 :          0 :             *p = (float) dval;
     831                 :          0 :         break;
     832                 :            :     }
     833                 :            : 
     834                 :          0 :     case 'd': {/* double */
     835                 :          0 :         double *p = va_arg(*p_va, double *);
     836                 :          0 :         double dval = PyFloat_AsDouble(arg);
     837   [ #  #  #  # ]:          0 :         if (dval == -1.0 && PyErr_Occurred())
     838                 :          0 :             RETURN_ERR_OCCURRED;
     839                 :            :         else
     840                 :          0 :             *p = dval;
     841                 :          0 :         break;
     842                 :            :     }
     843                 :            : 
     844                 :          0 :     case 'D': {/* complex double */
     845                 :          0 :         Py_complex *p = va_arg(*p_va, Py_complex *);
     846                 :            :         Py_complex cval;
     847                 :          0 :         cval = PyComplex_AsCComplex(arg);
     848         [ #  # ]:          0 :         if (PyErr_Occurred())
     849                 :          0 :             RETURN_ERR_OCCURRED;
     850                 :            :         else
     851                 :          0 :             *p = cval;
     852                 :          0 :         break;
     853                 :            :     }
     854                 :            : 
     855                 :          0 :     case 'c': {/* char */
     856                 :          0 :         char *p = va_arg(*p_va, char *);
     857   [ #  #  #  # ]:          0 :         if (PyBytes_Check(arg) && PyBytes_Size(arg) == 1)
     858                 :          0 :             *p = PyBytes_AS_STRING(arg)[0];
     859   [ #  #  #  # ]:          0 :         else if (PyByteArray_Check(arg) && PyByteArray_Size(arg) == 1)
     860                 :          0 :             *p = PyByteArray_AS_STRING(arg)[0];
     861                 :            :         else
     862                 :          0 :             return converterr("a byte string of length 1", arg, msgbuf, bufsize);
     863                 :          0 :         break;
     864                 :            :     }
     865                 :            : 
     866                 :          0 :     case 'C': {/* unicode char */
     867                 :          0 :         int *p = va_arg(*p_va, int *);
     868                 :            :         int kind;
     869                 :            :         const void *data;
     870                 :            : 
     871         [ #  # ]:          0 :         if (!PyUnicode_Check(arg))
     872                 :          0 :             return converterr("a unicode character", arg, msgbuf, bufsize);
     873                 :            : 
     874         [ #  # ]:          0 :         if (PyUnicode_READY(arg))
     875                 :          0 :             RETURN_ERR_OCCURRED;
     876                 :            : 
     877         [ #  # ]:          0 :         if (PyUnicode_GET_LENGTH(arg) != 1)
     878                 :          0 :             return converterr("a unicode character", arg, msgbuf, bufsize);
     879                 :            : 
     880                 :          0 :         kind = PyUnicode_KIND(arg);
     881                 :          0 :         data = PyUnicode_DATA(arg);
     882                 :          0 :         *p = PyUnicode_READ(kind, data, 0);
     883                 :          0 :         break;
     884                 :            :     }
     885                 :            : 
     886                 :         61 :     case 'p': {/* boolean *p*redicate */
     887                 :         61 :         int *p = va_arg(*p_va, int *);
     888                 :         61 :         int val = PyObject_IsTrue(arg);
     889         [ +  + ]:         61 :         if (val > 0)
     890                 :         26 :             *p = 1;
     891         [ +  - ]:         35 :         else if (val == 0)
     892                 :         35 :             *p = 0;
     893                 :            :         else
     894                 :          0 :             RETURN_ERR_OCCURRED;
     895                 :         61 :         break;
     896                 :            :     }
     897                 :            : 
     898                 :            :     /* XXX WAAAAH!  's', 'y', 'z', 'u', 'Z', 'e', 'w' codes all
     899                 :            :        need to be cleaned up! */
     900                 :            : 
     901                 :          0 :     case 'y': {/* any bytes-like object */
     902                 :          0 :         void **p = (void **)va_arg(*p_va, char **);
     903                 :            :         const char *buf;
     904                 :            :         Py_ssize_t count;
     905         [ #  # ]:          0 :         if (*format == '*') {
     906         [ #  # ]:          0 :             if (getbuffer(arg, (Py_buffer*)p, &buf) < 0)
     907                 :          0 :                 return converterr(buf, arg, msgbuf, bufsize);
     908                 :          0 :             format++;
     909         [ #  # ]:          0 :             if (addcleanup(p, freelist, cleanup_buffer)) {
     910                 :          0 :                 return converterr(
     911                 :            :                     "(cleanup problem)",
     912                 :            :                     arg, msgbuf, bufsize);
     913                 :            :             }
     914                 :          0 :             break;
     915                 :            :         }
     916                 :          0 :         count = convertbuffer(arg, (const void **)p, &buf);
     917         [ #  # ]:          0 :         if (count < 0)
     918                 :          0 :             return converterr(buf, arg, msgbuf, bufsize);
     919         [ #  # ]:          0 :         if (*format == '#') {
     920         [ #  # ]:          0 :             REQUIRE_PY_SSIZE_T_CLEAN;
     921                 :          0 :             Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*);
     922                 :          0 :             *psize = count;
     923                 :          0 :             format++;
     924                 :            :         } else {
     925         [ #  # ]:          0 :             if (strlen(*p) != (size_t)count) {
     926                 :          0 :                 PyErr_SetString(PyExc_ValueError, "embedded null byte");
     927                 :          0 :                 RETURN_ERR_OCCURRED;
     928                 :            :             }
     929                 :            :         }
     930                 :          0 :         break;
     931                 :            :     }
     932                 :            : 
     933                 :          0 :     case 's': /* text string or bytes-like object */
     934                 :            :     case 'z': /* text string, bytes-like object or None */
     935                 :            :     {
     936         [ #  # ]:          0 :         if (*format == '*') {
     937                 :            :             /* "s*" or "z*" */
     938                 :          0 :             Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
     939                 :            : 
     940   [ #  #  #  # ]:          0 :             if (c == 'z' && arg == Py_None)
     941                 :          0 :                 PyBuffer_FillInfo(p, NULL, NULL, 0, 1, 0);
     942         [ #  # ]:          0 :             else if (PyUnicode_Check(arg)) {
     943                 :            :                 Py_ssize_t len;
     944                 :          0 :                 sarg = PyUnicode_AsUTF8AndSize(arg, &len);
     945         [ #  # ]:          0 :                 if (sarg == NULL)
     946                 :          0 :                     return converterr(CONV_UNICODE,
     947                 :            :                                       arg, msgbuf, bufsize);
     948                 :          0 :                 PyBuffer_FillInfo(p, arg, (void *)sarg, len, 1, 0);
     949                 :            :             }
     950                 :            :             else { /* any bytes-like object */
     951                 :            :                 const char *buf;
     952         [ #  # ]:          0 :                 if (getbuffer(arg, p, &buf) < 0)
     953                 :          0 :                     return converterr(buf, arg, msgbuf, bufsize);
     954                 :            :             }
     955         [ #  # ]:          0 :             if (addcleanup(p, freelist, cleanup_buffer)) {
     956                 :          0 :                 return converterr(
     957                 :            :                     "(cleanup problem)",
     958                 :            :                     arg, msgbuf, bufsize);
     959                 :            :             }
     960                 :          0 :             format++;
     961         [ #  # ]:          0 :         } else if (*format == '#') { /* a string or read-only bytes-like object */
     962                 :            :             /* "s#" or "z#" */
     963                 :          0 :             const void **p = (const void **)va_arg(*p_va, const char **);
     964         [ #  # ]:          0 :             REQUIRE_PY_SSIZE_T_CLEAN;
     965                 :          0 :             Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*);
     966                 :            : 
     967   [ #  #  #  # ]:          0 :             if (c == 'z' && arg == Py_None) {
     968                 :          0 :                 *p = NULL;
     969                 :          0 :                 *psize = 0;
     970                 :            :             }
     971         [ #  # ]:          0 :             else if (PyUnicode_Check(arg)) {
     972                 :            :                 Py_ssize_t len;
     973                 :          0 :                 sarg = PyUnicode_AsUTF8AndSize(arg, &len);
     974         [ #  # ]:          0 :                 if (sarg == NULL)
     975                 :          0 :                     return converterr(CONV_UNICODE,
     976                 :            :                                       arg, msgbuf, bufsize);
     977                 :          0 :                 *p = sarg;
     978                 :          0 :                 *psize = len;
     979                 :            :             }
     980                 :            :             else { /* read-only bytes-like object */
     981                 :            :                 /* XXX Really? */
     982                 :            :                 const char *buf;
     983                 :          0 :                 Py_ssize_t count = convertbuffer(arg, p, &buf);
     984         [ #  # ]:          0 :                 if (count < 0)
     985                 :          0 :                     return converterr(buf, arg, msgbuf, bufsize);
     986                 :          0 :                 *psize = count;
     987                 :            :             }
     988                 :          0 :             format++;
     989                 :            :         } else {
     990                 :            :             /* "s" or "z" */
     991                 :          0 :             const char **p = va_arg(*p_va, const char **);
     992                 :            :             Py_ssize_t len;
     993                 :          0 :             sarg = NULL;
     994                 :            : 
     995   [ #  #  #  # ]:          0 :             if (c == 'z' && arg == Py_None)
     996                 :          0 :                 *p = NULL;
     997         [ #  # ]:          0 :             else if (PyUnicode_Check(arg)) {
     998                 :          0 :                 sarg = PyUnicode_AsUTF8AndSize(arg, &len);
     999         [ #  # ]:          0 :                 if (sarg == NULL)
    1000                 :          0 :                     return converterr(CONV_UNICODE,
    1001                 :            :                                       arg, msgbuf, bufsize);
    1002         [ #  # ]:          0 :                 if (strlen(sarg) != (size_t)len) {
    1003                 :          0 :                     PyErr_SetString(PyExc_ValueError, "embedded null character");
    1004                 :          0 :                     RETURN_ERR_OCCURRED;
    1005                 :            :                 }
    1006                 :          0 :                 *p = sarg;
    1007                 :            :             }
    1008                 :            :             else
    1009         [ #  # ]:          0 :                 return converterr(c == 'z' ? "str or None" : "str",
    1010                 :            :                                   arg, msgbuf, bufsize);
    1011                 :            :         }
    1012                 :          0 :         break;
    1013                 :            :     }
    1014                 :            : 
    1015                 :          0 :     case 'e': {/* encoded string */
    1016                 :            :         char **buffer;
    1017                 :            :         const char *encoding;
    1018                 :            :         PyObject *s;
    1019                 :            :         int recode_strings;
    1020                 :            :         Py_ssize_t size;
    1021                 :            :         const char *ptr;
    1022                 :            : 
    1023                 :            :         /* Get 'e' parameter: the encoding name */
    1024                 :          0 :         encoding = (const char *)va_arg(*p_va, const char *);
    1025         [ #  # ]:          0 :         if (encoding == NULL)
    1026                 :          0 :             encoding = PyUnicode_GetDefaultEncoding();
    1027                 :            : 
    1028                 :            :         /* Get output buffer parameter:
    1029                 :            :            's' (recode all objects via Unicode) or
    1030                 :            :            't' (only recode non-string objects)
    1031                 :            :         */
    1032         [ #  # ]:          0 :         if (*format == 's')
    1033                 :          0 :             recode_strings = 1;
    1034         [ #  # ]:          0 :         else if (*format == 't')
    1035                 :          0 :             recode_strings = 0;
    1036                 :            :         else
    1037                 :          0 :             return converterr(
    1038                 :            :                 "(unknown parser marker combination)",
    1039                 :            :                 arg, msgbuf, bufsize);
    1040                 :          0 :         buffer = (char **)va_arg(*p_va, char **);
    1041                 :          0 :         format++;
    1042         [ #  # ]:          0 :         if (buffer == NULL)
    1043                 :          0 :             return converterr("(buffer is NULL)",
    1044                 :            :                               arg, msgbuf, bufsize);
    1045                 :            : 
    1046                 :            :         /* Encode object */
    1047   [ #  #  #  # ]:          0 :         if (!recode_strings &&
    1048         [ #  # ]:          0 :             (PyBytes_Check(arg) || PyByteArray_Check(arg))) {
    1049                 :          0 :             s = Py_NewRef(arg);
    1050         [ #  # ]:          0 :             if (PyBytes_Check(arg)) {
    1051                 :          0 :                 size = PyBytes_GET_SIZE(s);
    1052                 :          0 :                 ptr = PyBytes_AS_STRING(s);
    1053                 :            :             }
    1054                 :            :             else {
    1055                 :          0 :                 size = PyByteArray_GET_SIZE(s);
    1056                 :          0 :                 ptr = PyByteArray_AS_STRING(s);
    1057                 :            :             }
    1058                 :            :         }
    1059         [ #  # ]:          0 :         else if (PyUnicode_Check(arg)) {
    1060                 :            :             /* Encode object; use default error handling */
    1061                 :          0 :             s = PyUnicode_AsEncodedString(arg,
    1062                 :            :                                           encoding,
    1063                 :            :                                           NULL);
    1064         [ #  # ]:          0 :             if (s == NULL)
    1065                 :          0 :                 return converterr("(encoding failed)",
    1066                 :            :                                   arg, msgbuf, bufsize);
    1067                 :            :             assert(PyBytes_Check(s));
    1068                 :          0 :             size = PyBytes_GET_SIZE(s);
    1069                 :          0 :             ptr = PyBytes_AS_STRING(s);
    1070         [ #  # ]:          0 :             if (ptr == NULL)
    1071                 :          0 :                 ptr = "";
    1072                 :            :         }
    1073                 :            :         else {
    1074         [ #  # ]:          0 :             return converterr(
    1075                 :            :                 recode_strings ? "str" : "str, bytes or bytearray",
    1076                 :            :                 arg, msgbuf, bufsize);
    1077                 :            :         }
    1078                 :            : 
    1079                 :            :         /* Write output; output is guaranteed to be 0-terminated */
    1080         [ #  # ]:          0 :         if (*format == '#') {
    1081                 :            :             /* Using buffer length parameter '#':
    1082                 :            : 
    1083                 :            :                - if *buffer is NULL, a new buffer of the
    1084                 :            :                needed size is allocated and the data
    1085                 :            :                copied into it; *buffer is updated to point
    1086                 :            :                to the new buffer; the caller is
    1087                 :            :                responsible for PyMem_Free()ing it after
    1088                 :            :                usage
    1089                 :            : 
    1090                 :            :                - if *buffer is not NULL, the data is
    1091                 :            :                copied to *buffer; *buffer_len has to be
    1092                 :            :                set to the size of the buffer on input;
    1093                 :            :                buffer overflow is signalled with an error;
    1094                 :            :                buffer has to provide enough room for the
    1095                 :            :                encoded string plus the trailing 0-byte
    1096                 :            : 
    1097                 :            :                - in both cases, *buffer_len is updated to
    1098                 :            :                the size of the buffer /excluding/ the
    1099                 :            :                trailing 0-byte
    1100                 :            : 
    1101                 :            :             */
    1102         [ #  # ]:          0 :             REQUIRE_PY_SSIZE_T_CLEAN;
    1103                 :          0 :             Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*);
    1104                 :            : 
    1105                 :          0 :             format++;
    1106         [ #  # ]:          0 :             if (psize == NULL) {
    1107                 :          0 :                 Py_DECREF(s);
    1108                 :          0 :                 return converterr(
    1109                 :            :                     "(buffer_len is NULL)",
    1110                 :            :                     arg, msgbuf, bufsize);
    1111                 :            :             }
    1112         [ #  # ]:          0 :             if (*buffer == NULL) {
    1113         [ #  # ]:          0 :                 *buffer = PyMem_NEW(char, size + 1);
    1114         [ #  # ]:          0 :                 if (*buffer == NULL) {
    1115                 :          0 :                     Py_DECREF(s);
    1116                 :          0 :                     PyErr_NoMemory();
    1117                 :          0 :                     RETURN_ERR_OCCURRED;
    1118                 :            :                 }
    1119         [ #  # ]:          0 :                 if (addcleanup(buffer, freelist, cleanup_ptr)) {
    1120                 :          0 :                     Py_DECREF(s);
    1121                 :          0 :                     return converterr(
    1122                 :            :                         "(cleanup problem)",
    1123                 :            :                         arg, msgbuf, bufsize);
    1124                 :            :                 }
    1125                 :            :             } else {
    1126         [ #  # ]:          0 :                 if (size + 1 > *psize) {
    1127                 :          0 :                     Py_DECREF(s);
    1128                 :          0 :                     PyErr_Format(PyExc_ValueError,
    1129                 :            :                                  "encoded string too long "
    1130                 :            :                                  "(%zd, maximum length %zd)",
    1131                 :          0 :                                  (Py_ssize_t)size, (Py_ssize_t)(*psize - 1));
    1132                 :          0 :                     RETURN_ERR_OCCURRED;
    1133                 :            :                 }
    1134                 :            :             }
    1135                 :          0 :             memcpy(*buffer, ptr, size+1);
    1136                 :            : 
    1137                 :          0 :             *psize = size;
    1138                 :            :         }
    1139                 :            :         else {
    1140                 :            :             /* Using a 0-terminated buffer:
    1141                 :            : 
    1142                 :            :                - the encoded string has to be 0-terminated
    1143                 :            :                for this variant to work; if it is not, an
    1144                 :            :                error raised
    1145                 :            : 
    1146                 :            :                - a new buffer of the needed size is
    1147                 :            :                allocated and the data copied into it;
    1148                 :            :                *buffer is updated to point to the new
    1149                 :            :                buffer; the caller is responsible for
    1150                 :            :                PyMem_Free()ing it after usage
    1151                 :            : 
    1152                 :            :             */
    1153         [ #  # ]:          0 :             if ((Py_ssize_t)strlen(ptr) != size) {
    1154                 :          0 :                 Py_DECREF(s);
    1155                 :          0 :                 return converterr(
    1156                 :            :                     "encoded string without null bytes",
    1157                 :            :                     arg, msgbuf, bufsize);
    1158                 :            :             }
    1159         [ #  # ]:          0 :             *buffer = PyMem_NEW(char, size + 1);
    1160         [ #  # ]:          0 :             if (*buffer == NULL) {
    1161                 :          0 :                 Py_DECREF(s);
    1162                 :          0 :                 PyErr_NoMemory();
    1163                 :          0 :                 RETURN_ERR_OCCURRED;
    1164                 :            :             }
    1165         [ #  # ]:          0 :             if (addcleanup(buffer, freelist, cleanup_ptr)) {
    1166                 :          0 :                 Py_DECREF(s);
    1167                 :          0 :                 return converterr("(cleanup problem)",
    1168                 :            :                                 arg, msgbuf, bufsize);
    1169                 :            :             }
    1170                 :          0 :             memcpy(*buffer, ptr, size+1);
    1171                 :            :         }
    1172                 :          0 :         Py_DECREF(s);
    1173                 :          0 :         break;
    1174                 :            :     }
    1175                 :            : 
    1176                 :          0 :     case 'S': { /* PyBytes object */
    1177                 :          0 :         PyObject **p = va_arg(*p_va, PyObject **);
    1178         [ #  # ]:          0 :         if (PyBytes_Check(arg))
    1179                 :          0 :             *p = arg;
    1180                 :            :         else
    1181                 :          0 :             return converterr("bytes", arg, msgbuf, bufsize);
    1182                 :          0 :         break;
    1183                 :            :     }
    1184                 :            : 
    1185                 :          0 :     case 'Y': { /* PyByteArray object */
    1186                 :          0 :         PyObject **p = va_arg(*p_va, PyObject **);
    1187         [ #  # ]:          0 :         if (PyByteArray_Check(arg))
    1188                 :          0 :             *p = arg;
    1189                 :            :         else
    1190                 :          0 :             return converterr("bytearray", arg, msgbuf, bufsize);
    1191                 :          0 :         break;
    1192                 :            :     }
    1193                 :            : 
    1194                 :       6595 :     case 'U': { /* PyUnicode object */
    1195                 :       6595 :         PyObject **p = va_arg(*p_va, PyObject **);
    1196         [ +  - ]:       6595 :         if (PyUnicode_Check(arg)) {
    1197         [ -  + ]:       6595 :             if (PyUnicode_READY(arg) == -1)
    1198                 :          0 :                 RETURN_ERR_OCCURRED;
    1199                 :       6595 :             *p = arg;
    1200                 :            :         }
    1201                 :            :         else
    1202                 :          0 :             return converterr("str", arg, msgbuf, bufsize);
    1203                 :       6595 :         break;
    1204                 :            :     }
    1205                 :            : 
    1206                 :     137787 :     case 'O': { /* object */
    1207                 :            :         PyTypeObject *type;
    1208                 :            :         PyObject **p;
    1209         [ +  + ]:     137787 :         if (*format == '!') {
    1210                 :      12588 :             type = va_arg(*p_va, PyTypeObject*);
    1211                 :      12588 :             p = va_arg(*p_va, PyObject **);
    1212                 :      12588 :             format++;
    1213         [ +  - ]:      12588 :             if (PyType_IsSubtype(Py_TYPE(arg), type))
    1214                 :      12588 :                 *p = arg;
    1215                 :            :             else
    1216                 :          0 :                 return converterr(type->tp_name, arg, msgbuf, bufsize);
    1217                 :            : 
    1218                 :            :         }
    1219         [ -  + ]:     125199 :         else if (*format == '&') {
    1220                 :            :             typedef int (*converter)(PyObject *, void *);
    1221                 :          0 :             converter convert = va_arg(*p_va, converter);
    1222                 :          0 :             void *addr = va_arg(*p_va, void *);
    1223                 :            :             int res;
    1224                 :          0 :             format++;
    1225         [ #  # ]:          0 :             if (! (res = (*convert)(arg, addr)))
    1226                 :          0 :                 return converterr("(unspecified)",
    1227                 :            :                                   arg, msgbuf, bufsize);
    1228   [ #  #  #  # ]:          0 :             if (res == Py_CLEANUP_SUPPORTED &&
    1229                 :          0 :                 addcleanup(addr, freelist, convert) == -1)
    1230                 :          0 :                 return converterr("(cleanup problem)",
    1231                 :            :                                 arg, msgbuf, bufsize);
    1232                 :            :         }
    1233                 :            :         else {
    1234                 :     125199 :             p = va_arg(*p_va, PyObject **);
    1235                 :     125199 :             *p = arg;
    1236                 :            :         }
    1237                 :     137787 :         break;
    1238                 :            :     }
    1239                 :            : 
    1240                 :            : 
    1241                 :          0 :     case 'w': { /* "w*": memory buffer, read-write access */
    1242                 :          0 :         void **p = va_arg(*p_va, void **);
    1243                 :            : 
    1244         [ #  # ]:          0 :         if (*format != '*')
    1245                 :          0 :             return converterr(
    1246                 :            :                 "(invalid use of 'w' format character)",
    1247                 :            :                 arg, msgbuf, bufsize);
    1248                 :          0 :         format++;
    1249                 :            : 
    1250                 :            :         /* Caller is interested in Py_buffer, and the object
    1251                 :            :            supports it directly. */
    1252         [ #  # ]:          0 :         if (PyObject_GetBuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) {
    1253                 :          0 :             PyErr_Clear();
    1254                 :          0 :             return converterr("read-write bytes-like object",
    1255                 :            :                               arg, msgbuf, bufsize);
    1256                 :            :         }
    1257         [ #  # ]:          0 :         if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C')) {
    1258                 :          0 :             PyBuffer_Release((Py_buffer*)p);
    1259                 :          0 :             return converterr("contiguous buffer", arg, msgbuf, bufsize);
    1260                 :            :         }
    1261         [ #  # ]:          0 :         if (addcleanup(p, freelist, cleanup_buffer)) {
    1262                 :          0 :             return converterr(
    1263                 :            :                 "(cleanup problem)",
    1264                 :            :                 arg, msgbuf, bufsize);
    1265                 :            :         }
    1266                 :          0 :         break;
    1267                 :            :     }
    1268                 :            : 
    1269                 :          0 :     default:
    1270                 :          0 :         return converterr("(impossible<bad format char>)", arg, msgbuf, bufsize);
    1271                 :            : 
    1272                 :            :     }
    1273                 :            : 
    1274                 :     144805 :     *p_format = format;
    1275                 :     144805 :     return NULL;
    1276                 :            : 
    1277                 :            : #undef REQUIRE_PY_SSIZE_T_CLEAN
    1278                 :            : #undef RETURN_ERR_OCCURRED
    1279                 :            : }
    1280                 :            : 
    1281                 :            : static Py_ssize_t
    1282                 :          0 : convertbuffer(PyObject *arg, const void **p, const char **errmsg)
    1283                 :            : {
    1284                 :          0 :     PyBufferProcs *pb = Py_TYPE(arg)->tp_as_buffer;
    1285                 :            :     Py_ssize_t count;
    1286                 :            :     Py_buffer view;
    1287                 :            : 
    1288                 :          0 :     *errmsg = NULL;
    1289                 :          0 :     *p = NULL;
    1290   [ #  #  #  # ]:          0 :     if (pb != NULL && pb->bf_releasebuffer != NULL) {
    1291                 :          0 :         *errmsg = "read-only bytes-like object";
    1292                 :          0 :         return -1;
    1293                 :            :     }
    1294                 :            : 
    1295         [ #  # ]:          0 :     if (getbuffer(arg, &view, errmsg) < 0)
    1296                 :          0 :         return -1;
    1297                 :          0 :     count = view.len;
    1298                 :          0 :     *p = view.buf;
    1299                 :          0 :     PyBuffer_Release(&view);
    1300                 :          0 :     return count;
    1301                 :            : }
    1302                 :            : 
    1303                 :            : static int
    1304                 :          0 : getbuffer(PyObject *arg, Py_buffer *view, const char **errmsg)
    1305                 :            : {
    1306         [ #  # ]:          0 :     if (PyObject_GetBuffer(arg, view, PyBUF_SIMPLE) != 0) {
    1307                 :          0 :         *errmsg = "bytes-like object";
    1308                 :          0 :         return -1;
    1309                 :            :     }
    1310         [ #  # ]:          0 :     if (!PyBuffer_IsContiguous(view, 'C')) {
    1311                 :          0 :         PyBuffer_Release(view);
    1312                 :          0 :         *errmsg = "contiguous buffer";
    1313                 :          0 :         return -1;
    1314                 :            :     }
    1315                 :          0 :     return 0;
    1316                 :            : }
    1317                 :            : 
    1318                 :            : /* Support for keyword arguments donated by
    1319                 :            :    Geoff Philbrick <philbric@delphi.hks.com> */
    1320                 :            : 
    1321                 :            : /* Return false (0) for error, else true. */
    1322                 :            : int
    1323                 :     115790 : PyArg_ParseTupleAndKeywords(PyObject *args,
    1324                 :            :                             PyObject *keywords,
    1325                 :            :                             const char *format,
    1326                 :            :                             char **kwlist, ...)
    1327                 :            : {
    1328                 :            :     int retval;
    1329                 :            :     va_list va;
    1330                 :            : 
    1331   [ +  -  +  -  :     115790 :     if ((args == NULL || !PyTuple_Check(args)) ||
                   +  + ]
    1332   [ +  -  +  - ]:     115790 :         (keywords != NULL && !PyDict_Check(keywords)) ||
    1333         [ -  + ]:     115790 :         format == NULL ||
    1334                 :            :         kwlist == NULL)
    1335                 :            :     {
    1336                 :          0 :         PyErr_BadInternalCall();
    1337                 :          0 :         return 0;
    1338                 :            :     }
    1339                 :            : 
    1340                 :     115790 :     va_start(va, kwlist);
    1341                 :     115790 :     retval = vgetargskeywords(args, keywords, format, kwlist, &va, 0);
    1342                 :     115790 :     va_end(va);
    1343                 :     115790 :     return retval;
    1344                 :            : }
    1345                 :            : 
    1346                 :            : PyAPI_FUNC(int)
    1347                 :      14443 : _PyArg_ParseTupleAndKeywords_SizeT(PyObject *args,
    1348                 :            :                                   PyObject *keywords,
    1349                 :            :                                   const char *format,
    1350                 :            :                                   char **kwlist, ...)
    1351                 :            : {
    1352                 :            :     int retval;
    1353                 :            :     va_list va;
    1354                 :            : 
    1355   [ +  -  +  -  :      14443 :     if ((args == NULL || !PyTuple_Check(args)) ||
                   +  + ]
    1356   [ +  -  +  - ]:      14443 :         (keywords != NULL && !PyDict_Check(keywords)) ||
    1357         [ -  + ]:      14443 :         format == NULL ||
    1358                 :            :         kwlist == NULL)
    1359                 :            :     {
    1360                 :          0 :         PyErr_BadInternalCall();
    1361                 :          0 :         return 0;
    1362                 :            :     }
    1363                 :            : 
    1364                 :      14443 :     va_start(va, kwlist);
    1365                 :      14443 :     retval = vgetargskeywords(args, keywords, format,
    1366                 :            :                               kwlist, &va, FLAG_SIZE_T);
    1367                 :      14443 :     va_end(va);
    1368                 :      14443 :     return retval;
    1369                 :            : }
    1370                 :            : 
    1371                 :            : 
    1372                 :            : int
    1373                 :          0 : PyArg_VaParseTupleAndKeywords(PyObject *args,
    1374                 :            :                               PyObject *keywords,
    1375                 :            :                               const char *format,
    1376                 :            :                               char **kwlist, va_list va)
    1377                 :            : {
    1378                 :            :     int retval;
    1379                 :            :     va_list lva;
    1380                 :            : 
    1381   [ #  #  #  #  :          0 :     if ((args == NULL || !PyTuple_Check(args)) ||
                   #  # ]
    1382   [ #  #  #  # ]:          0 :         (keywords != NULL && !PyDict_Check(keywords)) ||
    1383         [ #  # ]:          0 :         format == NULL ||
    1384                 :            :         kwlist == NULL)
    1385                 :            :     {
    1386                 :          0 :         PyErr_BadInternalCall();
    1387                 :          0 :         return 0;
    1388                 :            :     }
    1389                 :            : 
    1390                 :          0 :     va_copy(lva, va);
    1391                 :            : 
    1392                 :          0 :     retval = vgetargskeywords(args, keywords, format, kwlist, &lva, 0);
    1393                 :          0 :     va_end(lva);
    1394                 :          0 :     return retval;
    1395                 :            : }
    1396                 :            : 
    1397                 :            : PyAPI_FUNC(int)
    1398                 :          0 : _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args,
    1399                 :            :                                     PyObject *keywords,
    1400                 :            :                                     const char *format,
    1401                 :            :                                     char **kwlist, va_list va)
    1402                 :            : {
    1403                 :            :     int retval;
    1404                 :            :     va_list lva;
    1405                 :            : 
    1406   [ #  #  #  #  :          0 :     if ((args == NULL || !PyTuple_Check(args)) ||
                   #  # ]
    1407   [ #  #  #  # ]:          0 :         (keywords != NULL && !PyDict_Check(keywords)) ||
    1408         [ #  # ]:          0 :         format == NULL ||
    1409                 :            :         kwlist == NULL)
    1410                 :            :     {
    1411                 :          0 :         PyErr_BadInternalCall();
    1412                 :          0 :         return 0;
    1413                 :            :     }
    1414                 :            : 
    1415                 :          0 :     va_copy(lva, va);
    1416                 :            : 
    1417                 :          0 :     retval = vgetargskeywords(args, keywords, format,
    1418                 :            :                               kwlist, &lva, FLAG_SIZE_T);
    1419                 :          0 :     va_end(lva);
    1420                 :          0 :     return retval;
    1421                 :            : }
    1422                 :            : 
    1423                 :            : PyAPI_FUNC(int)
    1424                 :          0 : _PyArg_ParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords,
    1425                 :            :                             struct _PyArg_Parser *parser, ...)
    1426                 :            : {
    1427                 :            :     int retval;
    1428                 :            :     va_list va;
    1429                 :            : 
    1430                 :          0 :     va_start(va, parser);
    1431                 :          0 :     retval = vgetargskeywordsfast(args, keywords, parser, &va, 0);
    1432                 :          0 :     va_end(va);
    1433                 :          0 :     return retval;
    1434                 :            : }
    1435                 :            : 
    1436                 :            : PyAPI_FUNC(int)
    1437                 :          0 : _PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords,
    1438                 :            :                             struct _PyArg_Parser *parser, ...)
    1439                 :            : {
    1440                 :            :     int retval;
    1441                 :            :     va_list va;
    1442                 :            : 
    1443                 :          0 :     va_start(va, parser);
    1444                 :          0 :     retval = vgetargskeywordsfast(args, keywords, parser, &va, FLAG_SIZE_T);
    1445                 :          0 :     va_end(va);
    1446                 :          0 :     return retval;
    1447                 :            : }
    1448                 :            : 
    1449                 :            : PyAPI_FUNC(int)
    1450                 :          0 : _PyArg_ParseStackAndKeywords(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames,
    1451                 :            :                   struct _PyArg_Parser *parser, ...)
    1452                 :            : {
    1453                 :            :     int retval;
    1454                 :            :     va_list va;
    1455                 :            : 
    1456                 :          0 :     va_start(va, parser);
    1457                 :          0 :     retval = vgetargskeywordsfast_impl(args, nargs, NULL, kwnames, parser, &va, 0);
    1458                 :          0 :     va_end(va);
    1459                 :          0 :     return retval;
    1460                 :            : }
    1461                 :            : 
    1462                 :            : PyAPI_FUNC(int)
    1463                 :          0 : _PyArg_ParseStackAndKeywords_SizeT(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames,
    1464                 :            :                         struct _PyArg_Parser *parser, ...)
    1465                 :            : {
    1466                 :            :     int retval;
    1467                 :            :     va_list va;
    1468                 :            : 
    1469                 :          0 :     va_start(va, parser);
    1470                 :          0 :     retval = vgetargskeywordsfast_impl(args, nargs, NULL, kwnames, parser, &va, FLAG_SIZE_T);
    1471                 :          0 :     va_end(va);
    1472                 :          0 :     return retval;
    1473                 :            : }
    1474                 :            : 
    1475                 :            : 
    1476                 :            : PyAPI_FUNC(int)
    1477                 :          0 : _PyArg_VaParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords,
    1478                 :            :                             struct _PyArg_Parser *parser, va_list va)
    1479                 :            : {
    1480                 :            :     int retval;
    1481                 :            :     va_list lva;
    1482                 :            : 
    1483                 :          0 :     va_copy(lva, va);
    1484                 :            : 
    1485                 :          0 :     retval = vgetargskeywordsfast(args, keywords, parser, &lva, 0);
    1486                 :          0 :     va_end(lva);
    1487                 :          0 :     return retval;
    1488                 :            : }
    1489                 :            : 
    1490                 :            : PyAPI_FUNC(int)
    1491                 :          0 : _PyArg_VaParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords,
    1492                 :            :                             struct _PyArg_Parser *parser, va_list va)
    1493                 :            : {
    1494                 :            :     int retval;
    1495                 :            :     va_list lva;
    1496                 :            : 
    1497                 :          0 :     va_copy(lva, va);
    1498                 :            : 
    1499                 :          0 :     retval = vgetargskeywordsfast(args, keywords, parser, &lva, FLAG_SIZE_T);
    1500                 :          0 :     va_end(lva);
    1501                 :          0 :     return retval;
    1502                 :            : }
    1503                 :            : 
    1504                 :            : static void
    1505                 :          0 : error_unexpected_keyword_arg(PyObject *kwargs, PyObject *kwnames, PyObject *kwtuple, const char *fname)
    1506                 :            : {
    1507                 :            :     /* make sure there are no extraneous keyword arguments */
    1508                 :          0 :     Py_ssize_t j = 0;
    1509                 :          0 :     while (1) {
    1510                 :            :         PyObject *keyword;
    1511         [ #  # ]:          0 :         if (kwargs != NULL) {
    1512         [ #  # ]:          0 :             if (!PyDict_Next(kwargs, &j, &keyword, NULL))
    1513                 :          0 :                 break;
    1514                 :            :         }
    1515                 :            :         else {
    1516         [ #  # ]:          0 :             if (j >= PyTuple_GET_SIZE(kwnames))
    1517                 :          0 :                 break;
    1518                 :          0 :             keyword = PyTuple_GET_ITEM(kwnames, j);
    1519                 :          0 :             j++;
    1520                 :            :         }
    1521         [ #  # ]:          0 :         if (!PyUnicode_Check(keyword)) {
    1522                 :          0 :             PyErr_SetString(PyExc_TypeError,
    1523                 :            :                             "keywords must be strings");
    1524                 :          0 :             return;
    1525                 :            :         }
    1526                 :            : 
    1527                 :          0 :         int match = PySequence_Contains(kwtuple, keyword);
    1528         [ #  # ]:          0 :         if (match <= 0) {
    1529         [ #  # ]:          0 :             if (!match) {
    1530   [ #  #  #  # ]:          0 :                 PyErr_Format(PyExc_TypeError,
    1531                 :            :                              "'%S' is an invalid keyword "
    1532                 :            :                              "argument for %.200s%s",
    1533                 :            :                              keyword,
    1534                 :            :                              (fname == NULL) ? "this function" : fname,
    1535                 :            :                              (fname == NULL) ? "" : "()");
    1536                 :            :             }
    1537                 :          0 :             return;
    1538                 :            :         }
    1539                 :            :     }
    1540                 :            :     /* Something wrong happened. There are extraneous keyword arguments,
    1541                 :            :      * but we don't know what. And we don't bother. */
    1542   [ #  #  #  # ]:          0 :     PyErr_Format(PyExc_TypeError,
    1543                 :            :                  "invalid keyword argument for %.200s%s",
    1544                 :            :                  (fname == NULL) ? "this function" : fname,
    1545                 :            :                  (fname == NULL) ? "" : "()");
    1546                 :            : }
    1547                 :            : 
    1548                 :            : int
    1549                 :        124 : PyArg_ValidateKeywordArguments(PyObject *kwargs)
    1550                 :            : {
    1551         [ -  + ]:        124 :     if (!PyDict_Check(kwargs)) {
    1552                 :          0 :         PyErr_BadInternalCall();
    1553                 :          0 :         return 0;
    1554                 :            :     }
    1555         [ -  + ]:        124 :     if (!_PyDict_HasOnlyStringKeys(kwargs)) {
    1556                 :          0 :         PyErr_SetString(PyExc_TypeError,
    1557                 :            :                         "keywords must be strings");
    1558                 :          0 :         return 0;
    1559                 :            :     }
    1560                 :        124 :     return 1;
    1561                 :            : }
    1562                 :            : 
    1563                 :            : #define IS_END_OF_FORMAT(c) (c == '\0' || c == ';' || c == ':')
    1564                 :            : 
    1565                 :            : static int
    1566                 :     130233 : vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
    1567                 :            :                  char **kwlist, va_list *p_va, int flags)
    1568                 :            : {
    1569                 :            :     char msgbuf[512];
    1570                 :            :     int levels[32];
    1571                 :            :     const char *fname, *msg, *custom_msg;
    1572                 :     130233 :     int min = INT_MAX;
    1573                 :     130233 :     int max = INT_MAX;
    1574                 :            :     int i, pos, len;
    1575                 :     130233 :     int skip = 0;
    1576                 :            :     Py_ssize_t nargs, nkwargs;
    1577                 :            :     PyObject *current_arg;
    1578                 :            :     freelistentry_t static_entries[STATIC_FREELIST_ENTRIES];
    1579                 :            :     freelist_t freelist;
    1580                 :            : 
    1581                 :     130233 :     freelist.entries = static_entries;
    1582                 :     130233 :     freelist.first_available = 0;
    1583                 :     130233 :     freelist.entries_malloced = 0;
    1584                 :            : 
    1585                 :            :     assert(args != NULL && PyTuple_Check(args));
    1586                 :            :     assert(kwargs == NULL || PyDict_Check(kwargs));
    1587                 :            :     assert(format != NULL);
    1588                 :            :     assert(kwlist != NULL);
    1589                 :            :     assert(p_va != NULL);
    1590                 :            : 
    1591                 :            :     /* grab the function name or custom error msg first (mutually exclusive) */
    1592                 :     130233 :     fname = strchr(format, ':');
    1593         [ +  + ]:     130233 :     if (fname) {
    1594                 :     130049 :         fname++;
    1595                 :     130049 :         custom_msg = NULL;
    1596                 :            :     }
    1597                 :            :     else {
    1598                 :        184 :         custom_msg = strchr(format,';');
    1599         [ -  + ]:        184 :         if (custom_msg)
    1600                 :          0 :             custom_msg++;
    1601                 :            :     }
    1602                 :            : 
    1603                 :            :     /* scan kwlist and count the number of positional-only parameters */
    1604   [ +  -  -  + ]:     130233 :     for (pos = 0; kwlist[pos] && !*kwlist[pos]; pos++) {
    1605                 :            :     }
    1606                 :            :     /* scan kwlist and get greatest possible nbr of args */
    1607         [ +  + ]:     391040 :     for (len = pos; kwlist[len]; len++) {
    1608         [ -  + ]:     260807 :         if (!*kwlist[len]) {
    1609                 :          0 :             PyErr_SetString(PyExc_SystemError,
    1610                 :            :                             "Empty keyword parameter name");
    1611                 :          0 :             return cleanreturn(0, &freelist);
    1612                 :            :         }
    1613                 :            :     }
    1614                 :            : 
    1615         [ +  + ]:     130233 :     if (len > STATIC_FREELIST_ENTRIES) {
    1616         [ +  - ]:         30 :         freelist.entries = PyMem_NEW(freelistentry_t, len);
    1617         [ -  + ]:         30 :         if (freelist.entries == NULL) {
    1618                 :          0 :             PyErr_NoMemory();
    1619                 :          0 :             return 0;
    1620                 :            :         }
    1621                 :         30 :         freelist.entries_malloced = 1;
    1622                 :            :     }
    1623                 :            : 
    1624                 :     130233 :     nargs = PyTuple_GET_SIZE(args);
    1625         [ +  + ]:     130233 :     nkwargs = (kwargs == NULL) ? 0 : PyDict_GET_SIZE(kwargs);
    1626         [ -  + ]:     130233 :     if (nargs + nkwargs > len) {
    1627                 :            :         /* Adding "keyword" (when nargs == 0) prevents producing wrong error
    1628                 :            :            messages in some special cases (see bpo-31229). */
    1629   [ #  #  #  #  :          0 :         PyErr_Format(PyExc_TypeError,
             #  #  #  # ]
    1630                 :            :                      "%.200s%s takes at most %d %sargument%s (%zd given)",
    1631                 :            :                      (fname == NULL) ? "function" : fname,
    1632                 :            :                      (fname == NULL) ? "" : "()",
    1633                 :            :                      len,
    1634                 :            :                      (nargs == 0) ? "keyword " : "",
    1635                 :            :                      (len == 1) ? "" : "s",
    1636                 :            :                      nargs + nkwargs);
    1637                 :          0 :         return cleanreturn(0, &freelist);
    1638                 :            :     }
    1639                 :            : 
    1640                 :            :     /* convert tuple args and keyword args in same loop, using kwlist to drive process */
    1641         [ +  + ]:     131523 :     for (i = 0; i < len; i++) {
    1642         [ +  + ]:     131015 :         if (*format == '|') {
    1643         [ -  + ]:     130118 :             if (min != INT_MAX) {
    1644                 :          0 :                 PyErr_SetString(PyExc_SystemError,
    1645                 :            :                                 "Invalid format string (| specified twice)");
    1646                 :          0 :                 return cleanreturn(0, &freelist);
    1647                 :            :             }
    1648                 :            : 
    1649                 :     130118 :             min = i;
    1650                 :     130118 :             format++;
    1651                 :            : 
    1652         [ -  + ]:     130118 :             if (max != INT_MAX) {
    1653                 :          0 :                 PyErr_SetString(PyExc_SystemError,
    1654                 :            :                                 "Invalid format string ($ before |)");
    1655                 :          0 :                 return cleanreturn(0, &freelist);
    1656                 :            :             }
    1657                 :            :         }
    1658         [ +  + ]:     131015 :         if (*format == '$') {
    1659         [ -  + ]:     126975 :             if (max != INT_MAX) {
    1660                 :          0 :                 PyErr_SetString(PyExc_SystemError,
    1661                 :            :                                 "Invalid format string ($ specified twice)");
    1662                 :          0 :                 return cleanreturn(0, &freelist);
    1663                 :            :             }
    1664                 :            : 
    1665                 :     126975 :             max = i;
    1666                 :     126975 :             format++;
    1667                 :            : 
    1668         [ -  + ]:     126975 :             if (max < pos) {
    1669                 :          0 :                 PyErr_SetString(PyExc_SystemError,
    1670                 :            :                                 "Empty parameter name after $");
    1671                 :          0 :                 return cleanreturn(0, &freelist);
    1672                 :            :             }
    1673         [ -  + ]:     126975 :             if (skip) {
    1674                 :            :                 /* Now we know the minimal and the maximal numbers of
    1675                 :            :                  * positional arguments and can raise an exception with
    1676                 :            :                  * informative message (see below). */
    1677                 :          0 :                 break;
    1678                 :            :             }
    1679         [ -  + ]:     126975 :             if (max < nargs) {
    1680         [ #  # ]:          0 :                 if (max == 0) {
    1681   [ #  #  #  # ]:          0 :                     PyErr_Format(PyExc_TypeError,
    1682                 :            :                                  "%.200s%s takes no positional arguments",
    1683                 :            :                                  (fname == NULL) ? "function" : fname,
    1684                 :            :                                  (fname == NULL) ? "" : "()");
    1685                 :            :                 }
    1686                 :            :                 else {
    1687   [ #  #  #  #  :          0 :                     PyErr_Format(PyExc_TypeError,
             #  #  #  # ]
    1688                 :            :                                  "%.200s%s takes %s %d positional argument%s"
    1689                 :            :                                  " (%zd given)",
    1690                 :            :                                  (fname == NULL) ? "function" : fname,
    1691                 :            :                                  (fname == NULL) ? "" : "()",
    1692                 :            :                                  (min != INT_MAX) ? "at most" : "exactly",
    1693                 :            :                                  max,
    1694                 :            :                                  max == 1 ? "" : "s",
    1695                 :            :                                  nargs);
    1696                 :            :                 }
    1697                 :          0 :                 return cleanreturn(0, &freelist);
    1698                 :            :             }
    1699                 :            :         }
    1700   [ +  -  +  -  :     131015 :         if (IS_END_OF_FORMAT(*format)) {
                   -  + ]
    1701                 :          0 :             PyErr_Format(PyExc_SystemError,
    1702                 :            :                          "More keyword list entries (%d) than "
    1703                 :            :                          "format specifiers (%d)", len, i);
    1704                 :          0 :             return cleanreturn(0, &freelist);
    1705                 :            :         }
    1706         [ +  - ]:     131015 :         if (!skip) {
    1707         [ +  + ]:     131015 :             if (i < nargs) {
    1708                 :        352 :                 current_arg = PyTuple_GET_ITEM(args, i);
    1709                 :            :             }
    1710   [ +  +  +  - ]:     130663 :             else if (nkwargs && i >= pos) {
    1711                 :        938 :                 current_arg = _PyDict_GetItemStringWithError(kwargs, kwlist[i]);
    1712         [ +  + ]:        938 :                 if (current_arg) {
    1713                 :        714 :                     --nkwargs;
    1714                 :            :                 }
    1715         [ -  + ]:        224 :                 else if (PyErr_Occurred()) {
    1716                 :          0 :                     return cleanreturn(0, &freelist);
    1717                 :            :                 }
    1718                 :            :             }
    1719                 :            :             else {
    1720                 :     129725 :                 current_arg = NULL;
    1721                 :            :             }
    1722                 :            : 
    1723         [ +  + ]:     131015 :             if (current_arg) {
    1724                 :       1066 :                 msg = convertitem(current_arg, &format, p_va, flags,
    1725                 :            :                     levels, msgbuf, sizeof(msgbuf), &freelist);
    1726         [ -  + ]:       1066 :                 if (msg) {
    1727                 :          0 :                     seterror(i+1, msg, levels, fname, custom_msg);
    1728                 :          0 :                     return cleanreturn(0, &freelist);
    1729                 :            :                 }
    1730                 :       1066 :                 continue;
    1731                 :            :             }
    1732                 :            : 
    1733         [ -  + ]:     129949 :             if (i < min) {
    1734         [ #  # ]:          0 :                 if (i < pos) {
    1735                 :            :                     assert (min == INT_MAX);
    1736                 :            :                     assert (max == INT_MAX);
    1737                 :          0 :                     skip = 1;
    1738                 :            :                     /* At that moment we still don't know the minimal and
    1739                 :            :                      * the maximal numbers of positional arguments.  Raising
    1740                 :            :                      * an exception is deferred until we encounter | and $
    1741                 :            :                      * or the end of the format. */
    1742                 :            :                 }
    1743                 :            :                 else {
    1744         [ #  # ]:          0 :                     PyErr_Format(PyExc_TypeError,  "%.200s%s missing required "
    1745                 :            :                                  "argument '%s' (pos %d)",
    1746                 :            :                                  (fname == NULL) ? "function" : fname,
    1747                 :            :                                  (fname == NULL) ? "" : "()",
    1748         [ #  # ]:          0 :                                  kwlist[i], i+1);
    1749                 :          0 :                     return cleanreturn(0, &freelist);
    1750                 :            :                 }
    1751                 :            :             }
    1752                 :            :             /* current code reports success when all required args
    1753                 :            :              * fulfilled and no keyword args left, with no further
    1754                 :            :              * validation. XXX Maybe skip this in debug build ?
    1755                 :            :              */
    1756   [ +  +  +  - ]:     129949 :             if (!nkwargs && !skip) {
    1757                 :     129725 :                 return cleanreturn(1, &freelist);
    1758                 :            :             }
    1759                 :            :         }
    1760                 :            : 
    1761                 :            :         /* We are into optional args, skip through to any remaining
    1762                 :            :          * keyword args */
    1763                 :        224 :         msg = skipitem(&format, p_va, flags);
    1764         [ -  + ]:        224 :         if (msg) {
    1765                 :          0 :             PyErr_Format(PyExc_SystemError, "%s: '%s'", msg,
    1766                 :            :                          format);
    1767                 :          0 :             return cleanreturn(0, &freelist);
    1768                 :            :         }
    1769                 :            :     }
    1770                 :            : 
    1771         [ -  + ]:        508 :     if (skip) {
    1772   [ #  #  #  # ]:          0 :         PyErr_Format(PyExc_TypeError,
    1773                 :            :                      "%.200s%s takes %s %d positional argument%s"
    1774                 :            :                      " (%zd given)",
    1775                 :            :                      (fname == NULL) ? "function" : fname,
    1776                 :            :                      (fname == NULL) ? "" : "()",
    1777         [ #  # ]:          0 :                      (Py_MIN(pos, min) < i) ? "at least" : "exactly",
    1778                 :            :                      Py_MIN(pos, min),
    1779         [ #  # ]:          0 :                      Py_MIN(pos, min) == 1 ? "" : "s",
    1780                 :            :                      nargs);
    1781                 :          0 :         return cleanreturn(0, &freelist);
    1782                 :            :     }
    1783                 :            : 
    1784   [ +  -  +  -  :        508 :     if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) {
          -  +  -  -  -  
                      - ]
    1785                 :          0 :         PyErr_Format(PyExc_SystemError,
    1786                 :            :             "more argument specifiers than keyword list entries "
    1787                 :            :             "(remaining format:'%s')", format);
    1788                 :          0 :         return cleanreturn(0, &freelist);
    1789                 :            :     }
    1790                 :            : 
    1791         [ -  + ]:        508 :     if (nkwargs > 0) {
    1792                 :            :         PyObject *key;
    1793                 :            :         Py_ssize_t j;
    1794                 :            :         /* make sure there are no arguments given by name and position */
    1795         [ #  # ]:          0 :         for (i = pos; i < nargs; i++) {
    1796                 :          0 :             current_arg = _PyDict_GetItemStringWithError(kwargs, kwlist[i]);
    1797         [ #  # ]:          0 :             if (current_arg) {
    1798                 :            :                 /* arg present in tuple and in dict */
    1799         [ #  # ]:          0 :                 PyErr_Format(PyExc_TypeError,
    1800                 :            :                              "argument for %.200s%s given by name ('%s') "
    1801                 :            :                              "and position (%d)",
    1802                 :            :                              (fname == NULL) ? "function" : fname,
    1803                 :            :                              (fname == NULL) ? "" : "()",
    1804         [ #  # ]:          0 :                              kwlist[i], i+1);
    1805                 :          0 :                 return cleanreturn(0, &freelist);
    1806                 :            :             }
    1807         [ #  # ]:          0 :             else if (PyErr_Occurred()) {
    1808                 :          0 :                 return cleanreturn(0, &freelist);
    1809                 :            :             }
    1810                 :            :         }
    1811                 :            :         /* make sure there are no extraneous keyword arguments */
    1812                 :          0 :         j = 0;
    1813         [ #  # ]:          0 :         while (PyDict_Next(kwargs, &j, &key, NULL)) {
    1814                 :          0 :             int match = 0;
    1815         [ #  # ]:          0 :             if (!PyUnicode_Check(key)) {
    1816                 :          0 :                 PyErr_SetString(PyExc_TypeError,
    1817                 :            :                                 "keywords must be strings");
    1818                 :          0 :                 return cleanreturn(0, &freelist);
    1819                 :            :             }
    1820         [ #  # ]:          0 :             for (i = pos; i < len; i++) {
    1821         [ #  # ]:          0 :                 if (_PyUnicode_EqualToASCIIString(key, kwlist[i])) {
    1822                 :          0 :                     match = 1;
    1823                 :          0 :                     break;
    1824                 :            :                 }
    1825                 :            :             }
    1826         [ #  # ]:          0 :             if (!match) {
    1827   [ #  #  #  # ]:          0 :                 PyErr_Format(PyExc_TypeError,
    1828                 :            :                              "'%U' is an invalid keyword "
    1829                 :            :                              "argument for %.200s%s",
    1830                 :            :                              key,
    1831                 :            :                              (fname == NULL) ? "this function" : fname,
    1832                 :            :                              (fname == NULL) ? "" : "()");
    1833                 :          0 :                 return cleanreturn(0, &freelist);
    1834                 :            :             }
    1835                 :            :         }
    1836                 :            :         /* Something wrong happened. There are extraneous keyword arguments,
    1837                 :            :          * but we don't know what. And we don't bother. */
    1838   [ #  #  #  # ]:          0 :         PyErr_Format(PyExc_TypeError,
    1839                 :            :                      "invalid keyword argument for %.200s%s",
    1840                 :            :                      (fname == NULL) ? "this function" : fname,
    1841                 :            :                      (fname == NULL) ? "" : "()");
    1842                 :          0 :         return cleanreturn(0, &freelist);
    1843                 :            :     }
    1844                 :            : 
    1845                 :        508 :     return cleanreturn(1, &freelist);
    1846                 :            : }
    1847                 :            : 
    1848                 :            : 
    1849                 :            : static int
    1850                 :         88 : scan_keywords(const char * const *keywords, int *ptotal, int *pposonly)
    1851                 :            : {
    1852                 :            :     /* scan keywords and count the number of positional-only parameters */
    1853                 :            :     int i;
    1854   [ +  -  +  + ]:         89 :     for (i = 0; keywords[i] && !*keywords[i]; i++) {
    1855                 :            :     }
    1856                 :         88 :     *pposonly = i;
    1857                 :            : 
    1858                 :            :     /* scan keywords and get greatest possible nbr of args */
    1859         [ +  + ]:        517 :     for (; keywords[i]; i++) {
    1860         [ -  + ]:        429 :         if (!*keywords[i]) {
    1861                 :          0 :             PyErr_SetString(PyExc_SystemError,
    1862                 :            :                             "Empty keyword parameter name");
    1863                 :          0 :             return -1;
    1864                 :            :         }
    1865                 :            :     }
    1866                 :         88 :     *ptotal = i;
    1867                 :         88 :     return 0;
    1868                 :            : }
    1869                 :            : 
    1870                 :            : static int
    1871                 :          0 : parse_format(const char *format, int total, int npos,
    1872                 :            :              const char **pfname, const char **pcustommsg,
    1873                 :            :              int *pmin, int *pmax)
    1874                 :            : {
    1875                 :            :     /* grab the function name or custom error msg first (mutually exclusive) */
    1876                 :            :     const char *custommsg;
    1877                 :          0 :     const char *fname = strchr(format, ':');
    1878         [ #  # ]:          0 :     if (fname) {
    1879                 :          0 :         fname++;
    1880                 :          0 :         custommsg = NULL;
    1881                 :            :     }
    1882                 :            :     else {
    1883                 :          0 :         custommsg = strchr(format,';');
    1884         [ #  # ]:          0 :         if (custommsg) {
    1885                 :          0 :             custommsg++;
    1886                 :            :         }
    1887                 :            :     }
    1888                 :            : 
    1889                 :          0 :     int min = INT_MAX;
    1890                 :          0 :     int max = INT_MAX;
    1891         [ #  # ]:          0 :     for (int i = 0; i < total; i++) {
    1892         [ #  # ]:          0 :         if (*format == '|') {
    1893         [ #  # ]:          0 :             if (min != INT_MAX) {
    1894                 :          0 :                 PyErr_SetString(PyExc_SystemError,
    1895                 :            :                                 "Invalid format string (| specified twice)");
    1896                 :          0 :                 return -1;
    1897                 :            :             }
    1898         [ #  # ]:          0 :             if (max != INT_MAX) {
    1899                 :          0 :                 PyErr_SetString(PyExc_SystemError,
    1900                 :            :                                 "Invalid format string ($ before |)");
    1901                 :          0 :                 return -1;
    1902                 :            :             }
    1903                 :          0 :             min = i;
    1904                 :          0 :             format++;
    1905                 :            :         }
    1906         [ #  # ]:          0 :         if (*format == '$') {
    1907         [ #  # ]:          0 :             if (max != INT_MAX) {
    1908                 :          0 :                 PyErr_SetString(PyExc_SystemError,
    1909                 :            :                                 "Invalid format string ($ specified twice)");
    1910                 :          0 :                 return -1;
    1911                 :            :             }
    1912         [ #  # ]:          0 :             if (i < npos) {
    1913                 :          0 :                 PyErr_SetString(PyExc_SystemError,
    1914                 :            :                                 "Empty parameter name after $");
    1915                 :          0 :                 return -1;
    1916                 :            :             }
    1917                 :          0 :             max = i;
    1918                 :          0 :             format++;
    1919                 :            :         }
    1920   [ #  #  #  #  :          0 :         if (IS_END_OF_FORMAT(*format)) {
                   #  # ]
    1921                 :          0 :             PyErr_Format(PyExc_SystemError,
    1922                 :            :                         "More keyword list entries (%d) than "
    1923                 :            :                         "format specifiers (%d)", total, i);
    1924                 :          0 :             return -1;
    1925                 :            :         }
    1926                 :            : 
    1927                 :          0 :         const char *msg = skipitem(&format, NULL, 0);
    1928         [ #  # ]:          0 :         if (msg) {
    1929                 :          0 :             PyErr_Format(PyExc_SystemError, "%s: '%s'", msg,
    1930                 :            :                         format);
    1931                 :          0 :             return -1;
    1932                 :            :         }
    1933                 :            :     }
    1934                 :          0 :     min = Py_MIN(min, total);
    1935                 :          0 :     max = Py_MIN(max, total);
    1936                 :            : 
    1937   [ #  #  #  #  :          0 :     if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) {
          #  #  #  #  #  
                      # ]
    1938                 :          0 :         PyErr_Format(PyExc_SystemError,
    1939                 :            :             "more argument specifiers than keyword list entries "
    1940                 :            :             "(remaining format:'%s')", format);
    1941                 :          0 :         return -1;
    1942                 :            :     }
    1943                 :            : 
    1944                 :          0 :     *pfname = fname;
    1945                 :          0 :     *pcustommsg = custommsg;
    1946                 :          0 :     *pmin = min;
    1947                 :          0 :     *pmax = max;
    1948                 :          0 :     return 0;
    1949                 :            : }
    1950                 :            : 
    1951                 :            : static PyObject *
    1952                 :         15 : new_kwtuple(const char * const *keywords, int total, int pos)
    1953                 :            : {
    1954                 :         15 :     int nkw = total - pos;
    1955                 :         15 :     PyObject *kwtuple = PyTuple_New(nkw);
    1956         [ -  + ]:         15 :     if (kwtuple == NULL) {
    1957                 :          0 :         return NULL;
    1958                 :            :     }
    1959                 :         15 :     keywords += pos;
    1960         [ +  + ]:         46 :     for (int i = 0; i < nkw; i++) {
    1961                 :         31 :         PyObject *str = PyUnicode_FromString(keywords[i]);
    1962         [ -  + ]:         31 :         if (str == NULL) {
    1963                 :          0 :             Py_DECREF(kwtuple);
    1964                 :          0 :             return NULL;
    1965                 :            :         }
    1966                 :         31 :         PyUnicode_InternInPlace(&str);
    1967                 :         31 :         PyTuple_SET_ITEM(kwtuple, i, str);
    1968                 :            :     }
    1969                 :         15 :     return kwtuple;
    1970                 :            : }
    1971                 :            : 
    1972                 :            : static int
    1973                 :         88 : _parser_init(struct _PyArg_Parser *parser)
    1974                 :            : {
    1975                 :         88 :     const char * const *keywords = parser->keywords;
    1976                 :            :     assert(keywords != NULL);
    1977                 :            :     assert(parser->pos == 0 &&
    1978                 :            :            (parser->format == NULL || parser->fname == NULL) &&
    1979                 :            :            parser->custom_msg == NULL &&
    1980                 :            :            parser->min == 0 &&
    1981                 :            :            parser->max == 0);
    1982                 :            : 
    1983                 :            :     int len, pos;
    1984         [ -  + ]:         88 :     if (scan_keywords(keywords, &len, &pos) < 0) {
    1985                 :          0 :         return 0;
    1986                 :            :     }
    1987                 :            : 
    1988                 :         88 :     const char *fname, *custommsg = NULL;
    1989                 :         88 :     int min = 0, max = 0;
    1990         [ -  + ]:         88 :     if (parser->format) {
    1991                 :            :         assert(parser->fname == NULL);
    1992         [ #  # ]:          0 :         if (parse_format(parser->format, len, pos,
    1993                 :            :                          &fname, &custommsg, &min, &max) < 0) {
    1994                 :          0 :             return 0;
    1995                 :            :         }
    1996                 :            :     }
    1997                 :            :     else {
    1998                 :            :         assert(parser->fname != NULL);
    1999                 :         88 :         fname = parser->fname;
    2000                 :            :     }
    2001                 :            : 
    2002                 :            :     int owned;
    2003                 :         88 :     PyObject *kwtuple = parser->kwtuple;
    2004         [ +  + ]:         88 :     if (kwtuple == NULL) {
    2005                 :         15 :         kwtuple = new_kwtuple(keywords, len, pos);
    2006         [ -  + ]:         15 :         if (kwtuple == NULL) {
    2007                 :          0 :             return 0;
    2008                 :            :         }
    2009                 :         15 :         owned = 1;
    2010                 :            :     }
    2011                 :            :     else {
    2012                 :         73 :         owned = 0;
    2013                 :            :     }
    2014                 :            : 
    2015                 :         88 :     parser->pos = pos;
    2016                 :         88 :     parser->fname = fname;
    2017                 :         88 :     parser->custom_msg = custommsg;
    2018                 :         88 :     parser->min = min;
    2019                 :         88 :     parser->max = max;
    2020                 :         88 :     parser->kwtuple = kwtuple;
    2021         [ +  + ]:         88 :     parser->initialized = owned ? 1 : -1;
    2022                 :            : 
    2023                 :            :     assert(parser->next == NULL);
    2024                 :         88 :     parser->next = _PyRuntime.getargs.static_parsers;
    2025                 :         88 :     _PyRuntime.getargs.static_parsers = parser;
    2026                 :         88 :     return 1;
    2027                 :            : }
    2028                 :            : 
    2029                 :            : static int
    2030                 :       1148 : parser_init(struct _PyArg_Parser *parser)
    2031                 :            : {
    2032                 :            :     // volatile as it can be modified by other threads
    2033                 :            :     // and should not be optimized or reordered by compiler
    2034         [ +  + ]:       1148 :     if (*((volatile int *)&parser->initialized)) {
    2035                 :            :         assert(parser->kwtuple != NULL);
    2036                 :       1060 :         return 1;
    2037                 :            :     }
    2038                 :         88 :     PyThread_acquire_lock(_PyRuntime.getargs.mutex, WAIT_LOCK);
    2039                 :            :     // Check again if another thread initialized the parser
    2040                 :            :     // while we were waiting for the lock.
    2041         [ -  + ]:         88 :     if (*((volatile int *)&parser->initialized)) {
    2042                 :            :         assert(parser->kwtuple != NULL);
    2043                 :          0 :         PyThread_release_lock(_PyRuntime.getargs.mutex);
    2044                 :          0 :         return 1;
    2045                 :            :     }
    2046                 :         88 :     int ret = _parser_init(parser);
    2047                 :         88 :     PyThread_release_lock(_PyRuntime.getargs.mutex);
    2048                 :         88 :     return ret;
    2049                 :            : }
    2050                 :            : 
    2051                 :            : static void
    2052                 :         88 : parser_clear(struct _PyArg_Parser *parser)
    2053                 :            : {
    2054         [ +  + ]:         88 :     if (parser->initialized == 1) {
    2055         [ +  - ]:         15 :         Py_CLEAR(parser->kwtuple);
    2056                 :            :     }
    2057                 :         88 : }
    2058                 :            : 
    2059                 :            : static PyObject*
    2060                 :       3127 : find_keyword(PyObject *kwnames, PyObject *const *kwstack, PyObject *key)
    2061                 :            : {
    2062                 :            :     Py_ssize_t i, nkwargs;
    2063                 :            : 
    2064                 :       3127 :     nkwargs = PyTuple_GET_SIZE(kwnames);
    2065         [ +  + ]:       5443 :     for (i = 0; i < nkwargs; i++) {
    2066                 :       3726 :         PyObject *kwname = PyTuple_GET_ITEM(kwnames, i);
    2067                 :            : 
    2068                 :            :         /* kwname == key will normally find a match in since keyword keys
    2069                 :            :            should be interned strings; if not retry below in a new loop. */
    2070         [ +  + ]:       3726 :         if (kwname == key) {
    2071                 :       1410 :             return kwstack[i];
    2072                 :            :         }
    2073                 :            :     }
    2074                 :            : 
    2075         [ +  + ]:       3752 :     for (i = 0; i < nkwargs; i++) {
    2076                 :       2035 :         PyObject *kwname = PyTuple_GET_ITEM(kwnames, i);
    2077                 :            :         assert(PyUnicode_Check(kwname));
    2078         [ -  + ]:       2035 :         if (_PyUnicode_EQ(kwname, key)) {
    2079                 :          0 :             return kwstack[i];
    2080                 :            :         }
    2081                 :            :     }
    2082                 :       1717 :     return NULL;
    2083                 :            : }
    2084                 :            : 
    2085                 :            : static int
    2086                 :          0 : vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs,
    2087                 :            :                           PyObject *kwargs, PyObject *kwnames,
    2088                 :            :                           struct _PyArg_Parser *parser,
    2089                 :            :                           va_list *p_va, int flags)
    2090                 :            : {
    2091                 :            :     PyObject *kwtuple;
    2092                 :            :     char msgbuf[512];
    2093                 :            :     int levels[32];
    2094                 :            :     const char *format;
    2095                 :            :     const char *msg;
    2096                 :            :     PyObject *keyword;
    2097                 :            :     int i, pos, len;
    2098                 :            :     Py_ssize_t nkwargs;
    2099                 :            :     PyObject *current_arg;
    2100                 :            :     freelistentry_t static_entries[STATIC_FREELIST_ENTRIES];
    2101                 :            :     freelist_t freelist;
    2102                 :          0 :     PyObject *const *kwstack = NULL;
    2103                 :            : 
    2104                 :          0 :     freelist.entries = static_entries;
    2105                 :          0 :     freelist.first_available = 0;
    2106                 :          0 :     freelist.entries_malloced = 0;
    2107                 :            : 
    2108                 :            :     assert(kwargs == NULL || PyDict_Check(kwargs));
    2109                 :            :     assert(kwargs == NULL || kwnames == NULL);
    2110                 :            :     assert(p_va != NULL);
    2111                 :            : 
    2112         [ #  # ]:          0 :     if (parser == NULL) {
    2113                 :          0 :         PyErr_BadInternalCall();
    2114                 :          0 :         return 0;
    2115                 :            :     }
    2116                 :            : 
    2117   [ #  #  #  # ]:          0 :     if (kwnames != NULL && !PyTuple_Check(kwnames)) {
    2118                 :          0 :         PyErr_BadInternalCall();
    2119                 :          0 :         return 0;
    2120                 :            :     }
    2121                 :            : 
    2122         [ #  # ]:          0 :     if (!parser_init(parser)) {
    2123                 :          0 :         return 0;
    2124                 :            :     }
    2125                 :            : 
    2126                 :          0 :     kwtuple = parser->kwtuple;
    2127                 :          0 :     pos = parser->pos;
    2128                 :          0 :     len = pos + (int)PyTuple_GET_SIZE(kwtuple);
    2129                 :            : 
    2130         [ #  # ]:          0 :     if (len > STATIC_FREELIST_ENTRIES) {
    2131         [ #  # ]:          0 :         freelist.entries = PyMem_NEW(freelistentry_t, len);
    2132         [ #  # ]:          0 :         if (freelist.entries == NULL) {
    2133                 :          0 :             PyErr_NoMemory();
    2134                 :          0 :             return 0;
    2135                 :            :         }
    2136                 :          0 :         freelist.entries_malloced = 1;
    2137                 :            :     }
    2138                 :            : 
    2139         [ #  # ]:          0 :     if (kwargs != NULL) {
    2140                 :          0 :         nkwargs = PyDict_GET_SIZE(kwargs);
    2141                 :            :     }
    2142         [ #  # ]:          0 :     else if (kwnames != NULL) {
    2143                 :          0 :         nkwargs = PyTuple_GET_SIZE(kwnames);
    2144                 :          0 :         kwstack = args + nargs;
    2145                 :            :     }
    2146                 :            :     else {
    2147                 :          0 :         nkwargs = 0;
    2148                 :            :     }
    2149         [ #  # ]:          0 :     if (nargs + nkwargs > len) {
    2150                 :            :         /* Adding "keyword" (when nargs == 0) prevents producing wrong error
    2151                 :            :            messages in some special cases (see bpo-31229). */
    2152   [ #  #  #  # ]:          0 :         PyErr_Format(PyExc_TypeError,
    2153                 :            :                      "%.200s%s takes at most %d %sargument%s (%zd given)",
    2154         [ #  # ]:          0 :                      (parser->fname == NULL) ? "function" : parser->fname,
    2155         [ #  # ]:          0 :                      (parser->fname == NULL) ? "" : "()",
    2156                 :            :                      len,
    2157                 :            :                      (nargs == 0) ? "keyword " : "",
    2158                 :            :                      (len == 1) ? "" : "s",
    2159                 :            :                      nargs + nkwargs);
    2160                 :          0 :         return cleanreturn(0, &freelist);
    2161                 :            :     }
    2162         [ #  # ]:          0 :     if (parser->max < nargs) {
    2163         [ #  # ]:          0 :         if (parser->max == 0) {
    2164                 :          0 :             PyErr_Format(PyExc_TypeError,
    2165                 :            :                          "%.200s%s takes no positional arguments",
    2166         [ #  # ]:          0 :                          (parser->fname == NULL) ? "function" : parser->fname,
    2167         [ #  # ]:          0 :                          (parser->fname == NULL) ? "" : "()");
    2168                 :            :         }
    2169                 :            :         else {
    2170                 :          0 :             PyErr_Format(PyExc_TypeError,
    2171                 :            :                          "%.200s%s takes %s %d positional argument%s (%zd given)",
    2172         [ #  # ]:          0 :                          (parser->fname == NULL) ? "function" : parser->fname,
    2173         [ #  # ]:          0 :                          (parser->fname == NULL) ? "" : "()",
    2174         [ #  # ]:          0 :                          (parser->min < parser->max) ? "at most" : "exactly",
    2175                 :            :                          parser->max,
    2176         [ #  # ]:          0 :                          parser->max == 1 ? "" : "s",
    2177                 :            :                          nargs);
    2178                 :            :         }
    2179                 :          0 :         return cleanreturn(0, &freelist);
    2180                 :            :     }
    2181                 :            : 
    2182                 :          0 :     format = parser->format;
    2183                 :            :     assert(format != NULL || len == 0);
    2184                 :            :     /* convert tuple args and keyword args in same loop, using kwtuple to drive process */
    2185         [ #  # ]:          0 :     for (i = 0; i < len; i++) {
    2186         [ #  # ]:          0 :         if (*format == '|') {
    2187                 :          0 :             format++;
    2188                 :            :         }
    2189         [ #  # ]:          0 :         if (*format == '$') {
    2190                 :          0 :             format++;
    2191                 :            :         }
    2192                 :            :         assert(!IS_END_OF_FORMAT(*format));
    2193                 :            : 
    2194         [ #  # ]:          0 :         if (i < nargs) {
    2195                 :          0 :             current_arg = args[i];
    2196                 :            :         }
    2197   [ #  #  #  # ]:          0 :         else if (nkwargs && i >= pos) {
    2198                 :          0 :             keyword = PyTuple_GET_ITEM(kwtuple, i - pos);
    2199         [ #  # ]:          0 :             if (kwargs != NULL) {
    2200                 :          0 :                 current_arg = PyDict_GetItemWithError(kwargs, keyword);
    2201   [ #  #  #  # ]:          0 :                 if (!current_arg && PyErr_Occurred()) {
    2202                 :          0 :                     return cleanreturn(0, &freelist);
    2203                 :            :                 }
    2204                 :            :             }
    2205                 :            :             else {
    2206                 :          0 :                 current_arg = find_keyword(kwnames, kwstack, keyword);
    2207                 :            :             }
    2208         [ #  # ]:          0 :             if (current_arg) {
    2209                 :          0 :                 --nkwargs;
    2210                 :            :             }
    2211                 :            :         }
    2212                 :            :         else {
    2213                 :          0 :             current_arg = NULL;
    2214                 :            :         }
    2215                 :            : 
    2216         [ #  # ]:          0 :         if (current_arg) {
    2217                 :          0 :             msg = convertitem(current_arg, &format, p_va, flags,
    2218                 :            :                 levels, msgbuf, sizeof(msgbuf), &freelist);
    2219         [ #  # ]:          0 :             if (msg) {
    2220                 :          0 :                 seterror(i+1, msg, levels, parser->fname, parser->custom_msg);
    2221                 :          0 :                 return cleanreturn(0, &freelist);
    2222                 :            :             }
    2223                 :          0 :             continue;
    2224                 :            :         }
    2225                 :            : 
    2226         [ #  # ]:          0 :         if (i < parser->min) {
    2227                 :            :             /* Less arguments than required */
    2228         [ #  # ]:          0 :             if (i < pos) {
    2229                 :          0 :                 Py_ssize_t min = Py_MIN(pos, parser->min);
    2230         [ #  # ]:          0 :                 PyErr_Format(PyExc_TypeError,
    2231                 :            :                              "%.200s%s takes %s %d positional argument%s"
    2232                 :            :                              " (%zd given)",
    2233         [ #  # ]:          0 :                              (parser->fname == NULL) ? "function" : parser->fname,
    2234         [ #  # ]:          0 :                              (parser->fname == NULL) ? "" : "()",
    2235         [ #  # ]:          0 :                              min < parser->max ? "at least" : "exactly",
    2236                 :            :                              min,
    2237                 :            :                              min == 1 ? "" : "s",
    2238                 :            :                              nargs);
    2239                 :            :             }
    2240                 :            :             else {
    2241                 :          0 :                 keyword = PyTuple_GET_ITEM(kwtuple, i - pos);
    2242                 :          0 :                 PyErr_Format(PyExc_TypeError,  "%.200s%s missing required "
    2243                 :            :                              "argument '%U' (pos %d)",
    2244         [ #  # ]:          0 :                              (parser->fname == NULL) ? "function" : parser->fname,
    2245         [ #  # ]:          0 :                              (parser->fname == NULL) ? "" : "()",
    2246                 :            :                              keyword, i+1);
    2247                 :            :             }
    2248                 :          0 :             return cleanreturn(0, &freelist);
    2249                 :            :         }
    2250                 :            :         /* current code reports success when all required args
    2251                 :            :          * fulfilled and no keyword args left, with no further
    2252                 :            :          * validation. XXX Maybe skip this in debug build ?
    2253                 :            :          */
    2254         [ #  # ]:          0 :         if (!nkwargs) {
    2255                 :          0 :             return cleanreturn(1, &freelist);
    2256                 :            :         }
    2257                 :            : 
    2258                 :            :         /* We are into optional args, skip through to any remaining
    2259                 :            :          * keyword args */
    2260                 :          0 :         msg = skipitem(&format, p_va, flags);
    2261                 :            :         assert(msg == NULL);
    2262                 :            :     }
    2263                 :            : 
    2264                 :            :     assert(IS_END_OF_FORMAT(*format) || (*format == '|') || (*format == '$'));
    2265                 :            : 
    2266         [ #  # ]:          0 :     if (nkwargs > 0) {
    2267                 :            :         /* make sure there are no arguments given by name and position */
    2268         [ #  # ]:          0 :         for (i = pos; i < nargs; i++) {
    2269                 :          0 :             keyword = PyTuple_GET_ITEM(kwtuple, i - pos);
    2270         [ #  # ]:          0 :             if (kwargs != NULL) {
    2271                 :          0 :                 current_arg = PyDict_GetItemWithError(kwargs, keyword);
    2272   [ #  #  #  # ]:          0 :                 if (!current_arg && PyErr_Occurred()) {
    2273                 :          0 :                     return cleanreturn(0, &freelist);
    2274                 :            :                 }
    2275                 :            :             }
    2276                 :            :             else {
    2277                 :          0 :                 current_arg = find_keyword(kwnames, kwstack, keyword);
    2278                 :            :             }
    2279         [ #  # ]:          0 :             if (current_arg) {
    2280                 :            :                 /* arg present in tuple and in dict */
    2281                 :          0 :                 PyErr_Format(PyExc_TypeError,
    2282                 :            :                              "argument for %.200s%s given by name ('%U') "
    2283                 :            :                              "and position (%d)",
    2284         [ #  # ]:          0 :                              (parser->fname == NULL) ? "function" : parser->fname,
    2285         [ #  # ]:          0 :                              (parser->fname == NULL) ? "" : "()",
    2286                 :            :                              keyword, i+1);
    2287                 :          0 :                 return cleanreturn(0, &freelist);
    2288                 :            :             }
    2289                 :            :         }
    2290                 :            : 
    2291                 :          0 :         error_unexpected_keyword_arg(kwargs, kwnames, kwtuple, parser->fname);
    2292                 :          0 :         return cleanreturn(0, &freelist);
    2293                 :            :     }
    2294                 :            : 
    2295                 :          0 :     return cleanreturn(1, &freelist);
    2296                 :            : }
    2297                 :            : 
    2298                 :            : static int
    2299                 :          0 : vgetargskeywordsfast(PyObject *args, PyObject *keywords,
    2300                 :            :                      struct _PyArg_Parser *parser, va_list *p_va, int flags)
    2301                 :            : {
    2302                 :            :     PyObject **stack;
    2303                 :            :     Py_ssize_t nargs;
    2304                 :            : 
    2305         [ #  # ]:          0 :     if (args == NULL
    2306         [ #  # ]:          0 :         || !PyTuple_Check(args)
    2307   [ #  #  #  # ]:          0 :         || (keywords != NULL && !PyDict_Check(keywords)))
    2308                 :            :     {
    2309                 :          0 :         PyErr_BadInternalCall();
    2310                 :          0 :         return 0;
    2311                 :            :     }
    2312                 :            : 
    2313                 :          0 :     stack = _PyTuple_ITEMS(args);
    2314                 :          0 :     nargs = PyTuple_GET_SIZE(args);
    2315                 :          0 :     return vgetargskeywordsfast_impl(stack, nargs, keywords, NULL,
    2316                 :            :                                      parser, p_va, flags);
    2317                 :            : }
    2318                 :            : 
    2319                 :            : 
    2320                 :            : #undef _PyArg_UnpackKeywords
    2321                 :            : 
    2322                 :            : PyObject * const *
    2323                 :       1100 : _PyArg_UnpackKeywords(PyObject *const *args, Py_ssize_t nargs,
    2324                 :            :                       PyObject *kwargs, PyObject *kwnames,
    2325                 :            :                       struct _PyArg_Parser *parser,
    2326                 :            :                       int minpos, int maxpos, int minkw,
    2327                 :            :                       PyObject **buf)
    2328                 :            : {
    2329                 :            :     PyObject *kwtuple;
    2330                 :            :     PyObject *keyword;
    2331                 :            :     int i, posonly, minposonly, maxargs;
    2332         [ -  + ]:       1100 :     int reqlimit = minkw ? maxpos + minkw : minpos;
    2333                 :            :     Py_ssize_t nkwargs;
    2334                 :            :     PyObject *current_arg;
    2335                 :       1100 :     PyObject * const *kwstack = NULL;
    2336                 :            : 
    2337                 :            :     assert(kwargs == NULL || PyDict_Check(kwargs));
    2338                 :            :     assert(kwargs == NULL || kwnames == NULL);
    2339                 :            : 
    2340         [ -  + ]:       1100 :     if (parser == NULL) {
    2341                 :          0 :         PyErr_BadInternalCall();
    2342                 :          0 :         return NULL;
    2343                 :            :     }
    2344                 :            : 
    2345   [ +  +  -  + ]:       1100 :     if (kwnames != NULL && !PyTuple_Check(kwnames)) {
    2346                 :          0 :         PyErr_BadInternalCall();
    2347                 :          0 :         return NULL;
    2348                 :            :     }
    2349                 :            : 
    2350   [ -  +  -  - ]:       1100 :     if (args == NULL && nargs == 0) {
    2351                 :          0 :         args = buf;
    2352                 :            :     }
    2353                 :            : 
    2354         [ -  + ]:       1100 :     if (!parser_init(parser)) {
    2355                 :          0 :         return NULL;
    2356                 :            :     }
    2357                 :            : 
    2358                 :       1100 :     kwtuple = parser->kwtuple;
    2359                 :       1100 :     posonly = parser->pos;
    2360                 :       1100 :     minposonly = Py_MIN(posonly, minpos);
    2361                 :       1100 :     maxargs = posonly + (int)PyTuple_GET_SIZE(kwtuple);
    2362                 :            : 
    2363         [ +  + ]:       1100 :     if (kwargs != NULL) {
    2364                 :          3 :         nkwargs = PyDict_GET_SIZE(kwargs);
    2365                 :            :     }
    2366         [ +  + ]:       1097 :     else if (kwnames != NULL) {
    2367                 :       1095 :         nkwargs = PyTuple_GET_SIZE(kwnames);
    2368                 :       1095 :         kwstack = args + nargs;
    2369                 :            :     }
    2370                 :            :     else {
    2371                 :          2 :         nkwargs = 0;
    2372                 :            :     }
    2373   [ +  +  +  -  :       1100 :     if (nkwargs == 0 && minkw == 0 && minpos <= nargs && nargs <= maxpos) {
             +  +  -  + ]
    2374                 :            :         /* Fast path. */
    2375                 :          0 :         return args;
    2376                 :            :     }
    2377         [ -  + ]:       1100 :     if (nargs + nkwargs > maxargs) {
    2378                 :            :         /* Adding "keyword" (when nargs == 0) prevents producing wrong error
    2379                 :            :            messages in some special cases (see bpo-31229). */
    2380   [ #  #  #  # ]:          0 :         PyErr_Format(PyExc_TypeError,
    2381                 :            :                      "%.200s%s takes at most %d %sargument%s (%zd given)",
    2382         [ #  # ]:          0 :                      (parser->fname == NULL) ? "function" : parser->fname,
    2383         [ #  # ]:          0 :                      (parser->fname == NULL) ? "" : "()",
    2384                 :            :                      maxargs,
    2385                 :            :                      (nargs == 0) ? "keyword " : "",
    2386                 :            :                      (maxargs == 1) ? "" : "s",
    2387                 :            :                      nargs + nkwargs);
    2388                 :          0 :         return NULL;
    2389                 :            :     }
    2390         [ +  + ]:       1100 :     if (nargs > maxpos) {
    2391         [ -  + ]:          1 :         if (maxpos == 0) {
    2392                 :          0 :             PyErr_Format(PyExc_TypeError,
    2393                 :            :                          "%.200s%s takes no positional arguments",
    2394         [ #  # ]:          0 :                          (parser->fname == NULL) ? "function" : parser->fname,
    2395         [ #  # ]:          0 :                          (parser->fname == NULL) ? "" : "()");
    2396                 :            :         }
    2397                 :            :         else {
    2398   [ +  -  -  + ]:          3 :             PyErr_Format(PyExc_TypeError,
    2399                 :            :                          "%.200s%s takes %s %d positional argument%s (%zd given)",
    2400         [ +  - ]:          1 :                          (parser->fname == NULL) ? "function" : parser->fname,
    2401         [ -  + ]:          1 :                          (parser->fname == NULL) ? "" : "()",
    2402                 :            :                          (minpos < maxpos) ? "at most" : "exactly",
    2403                 :            :                          maxpos,
    2404                 :            :                          (maxpos == 1) ? "" : "s",
    2405                 :            :                          nargs);
    2406                 :            :         }
    2407                 :          1 :         return NULL;
    2408                 :            :     }
    2409         [ +  + ]:       1099 :     if (nargs < minposonly) {
    2410   [ +  -  -  + ]:          3 :         PyErr_Format(PyExc_TypeError,
    2411                 :            :                      "%.200s%s takes %s %d positional argument%s"
    2412                 :            :                      " (%zd given)",
    2413         [ +  - ]:          1 :                      (parser->fname == NULL) ? "function" : parser->fname,
    2414         [ -  + ]:          1 :                      (parser->fname == NULL) ? "" : "()",
    2415                 :            :                      minposonly < maxpos ? "at least" : "exactly",
    2416                 :            :                      minposonly,
    2417                 :            :                      minposonly == 1 ? "" : "s",
    2418                 :            :                      nargs);
    2419                 :          1 :         return NULL;
    2420                 :            :     }
    2421                 :            : 
    2422                 :            :     /* copy tuple args */
    2423         [ +  + ]:       2677 :     for (i = 0; i < nargs; i++) {
    2424                 :       1579 :         buf[i] = args[i];
    2425                 :            :     }
    2426                 :            : 
    2427                 :            :     /* copy keyword args using kwtuple to drive process */
    2428         [ +  + ]:       4118 :     for (i = Py_MAX((int)nargs, posonly); i < maxargs; i++) {
    2429         [ +  + ]:       3929 :         if (nkwargs) {
    2430                 :       3020 :             keyword = PyTuple_GET_ITEM(kwtuple, i - posonly);
    2431         [ +  + ]:       3020 :             if (kwargs != NULL) {
    2432                 :          9 :                 current_arg = PyDict_GetItemWithError(kwargs, keyword);
    2433   [ +  +  -  + ]:          9 :                 if (!current_arg && PyErr_Occurred()) {
    2434                 :          0 :                     return NULL;
    2435                 :            :                 }
    2436                 :            :             }
    2437                 :            :             else {
    2438                 :       3011 :                 current_arg = find_keyword(kwnames, kwstack, keyword);
    2439                 :            :             }
    2440                 :            :         }
    2441         [ +  - ]:        909 :         else if (i >= reqlimit) {
    2442                 :        909 :             break;
    2443                 :            :         }
    2444                 :            :         else {
    2445                 :          0 :             current_arg = NULL;
    2446                 :            :         }
    2447                 :            : 
    2448                 :       3020 :         buf[i] = current_arg;
    2449                 :            : 
    2450         [ +  + ]:       3020 :         if (current_arg) {
    2451                 :       1339 :             --nkwargs;
    2452                 :            :         }
    2453   [ +  -  +  +  :       1681 :         else if (i < minpos || (maxpos <= i && i < reqlimit)) {
                   -  + ]
    2454                 :            :             /* Less arguments than required */
    2455                 :          0 :             keyword = PyTuple_GET_ITEM(kwtuple, i - posonly);
    2456                 :          0 :             PyErr_Format(PyExc_TypeError,  "%.200s%s missing required "
    2457                 :            :                          "argument '%U' (pos %d)",
    2458         [ #  # ]:          0 :                          (parser->fname == NULL) ? "function" : parser->fname,
    2459         [ #  # ]:          0 :                          (parser->fname == NULL) ? "" : "()",
    2460                 :            :                          keyword, i+1);
    2461                 :          0 :             return NULL;
    2462                 :            :         }
    2463                 :            :     }
    2464                 :            : 
    2465         [ -  + ]:       1098 :     if (nkwargs > 0) {
    2466                 :            :         /* make sure there are no arguments given by name and position */
    2467         [ #  # ]:          0 :         for (i = posonly; i < nargs; i++) {
    2468                 :          0 :             keyword = PyTuple_GET_ITEM(kwtuple, i - posonly);
    2469         [ #  # ]:          0 :             if (kwargs != NULL) {
    2470                 :          0 :                 current_arg = PyDict_GetItemWithError(kwargs, keyword);
    2471   [ #  #  #  # ]:          0 :                 if (!current_arg && PyErr_Occurred()) {
    2472                 :          0 :                     return NULL;
    2473                 :            :                 }
    2474                 :            :             }
    2475                 :            :             else {
    2476                 :          0 :                 current_arg = find_keyword(kwnames, kwstack, keyword);
    2477                 :            :             }
    2478         [ #  # ]:          0 :             if (current_arg) {
    2479                 :            :                 /* arg present in tuple and in dict */
    2480                 :          0 :                 PyErr_Format(PyExc_TypeError,
    2481                 :            :                              "argument for %.200s%s given by name ('%U') "
    2482                 :            :                              "and position (%d)",
    2483         [ #  # ]:          0 :                              (parser->fname == NULL) ? "function" : parser->fname,
    2484         [ #  # ]:          0 :                              (parser->fname == NULL) ? "" : "()",
    2485                 :            :                              keyword, i+1);
    2486                 :          0 :                 return NULL;
    2487                 :            :             }
    2488                 :            :         }
    2489                 :            : 
    2490                 :          0 :         error_unexpected_keyword_arg(kwargs, kwnames, kwtuple, parser->fname);
    2491                 :          0 :         return NULL;
    2492                 :            :     }
    2493                 :            : 
    2494                 :       1098 :     return buf;
    2495                 :            : }
    2496                 :            : 
    2497                 :            : PyObject * const *
    2498                 :         48 : _PyArg_UnpackKeywordsWithVararg(PyObject *const *args, Py_ssize_t nargs,
    2499                 :            :                                 PyObject *kwargs, PyObject *kwnames,
    2500                 :            :                                 struct _PyArg_Parser *parser,
    2501                 :            :                                 int minpos, int maxpos, int minkw,
    2502                 :            :                                 int vararg, PyObject **buf)
    2503                 :            : {
    2504                 :            :     PyObject *kwtuple;
    2505                 :            :     PyObject *keyword;
    2506                 :         48 :     Py_ssize_t varargssize = 0;
    2507                 :            :     int i, posonly, minposonly, maxargs;
    2508         [ -  + ]:         48 :     int reqlimit = minkw ? maxpos + minkw : minpos;
    2509                 :            :     Py_ssize_t nkwargs;
    2510                 :            :     PyObject *current_arg;
    2511                 :         48 :     PyObject * const *kwstack = NULL;
    2512                 :            : 
    2513                 :            :     assert(kwargs == NULL || PyDict_Check(kwargs));
    2514                 :            :     assert(kwargs == NULL || kwnames == NULL);
    2515                 :            : 
    2516         [ -  + ]:         48 :     if (parser == NULL) {
    2517                 :          0 :         PyErr_BadInternalCall();
    2518                 :          0 :         return NULL;
    2519                 :            :     }
    2520                 :            : 
    2521   [ +  +  -  + ]:         48 :     if (kwnames != NULL && !PyTuple_Check(kwnames)) {
    2522                 :          0 :         PyErr_BadInternalCall();
    2523                 :          0 :         return NULL;
    2524                 :            :     }
    2525                 :            : 
    2526   [ -  +  -  - ]:         48 :     if (args == NULL && nargs == 0) {
    2527                 :          0 :         args = buf;
    2528                 :            :     }
    2529                 :            : 
    2530         [ -  + ]:         48 :     if (!parser_init(parser)) {
    2531                 :          0 :         return NULL;
    2532                 :            :     }
    2533                 :            : 
    2534                 :         48 :     kwtuple = parser->kwtuple;
    2535                 :         48 :     posonly = parser->pos;
    2536                 :         48 :     minposonly = Py_MIN(posonly, minpos);
    2537                 :         48 :     maxargs = posonly + (int)PyTuple_GET_SIZE(kwtuple);
    2538         [ -  + ]:         48 :     if (kwargs != NULL) {
    2539                 :          0 :         nkwargs = PyDict_GET_SIZE(kwargs);
    2540                 :            :     }
    2541         [ +  + ]:         48 :     else if (kwnames != NULL) {
    2542                 :         38 :         nkwargs = PyTuple_GET_SIZE(kwnames);
    2543                 :         38 :         kwstack = args + nargs;
    2544                 :            :     }
    2545                 :            :     else {
    2546                 :         10 :         nkwargs = 0;
    2547                 :            :     }
    2548         [ -  + ]:         48 :     if (nargs < minposonly) {
    2549   [ #  #  #  # ]:          0 :         PyErr_Format(PyExc_TypeError,
    2550                 :            :                      "%.200s%s takes %s %d positional argument%s"
    2551                 :            :                      " (%zd given)",
    2552         [ #  # ]:          0 :                      (parser->fname == NULL) ? "function" : parser->fname,
    2553         [ #  # ]:          0 :                      (parser->fname == NULL) ? "" : "()",
    2554                 :            :                      minposonly < maxpos ? "at least" : "exactly",
    2555                 :            :                      minposonly,
    2556                 :            :                      minposonly == 1 ? "" : "s",
    2557                 :            :                      nargs);
    2558                 :          0 :         return NULL;
    2559                 :            :     }
    2560                 :            : 
    2561                 :            :     /* create varargs tuple */
    2562                 :         48 :     varargssize = nargs - maxpos;
    2563         [ -  + ]:         48 :     if (varargssize < 0) {
    2564                 :          0 :         varargssize = 0;
    2565                 :            :     }
    2566                 :         48 :     buf[vararg] = PyTuple_New(varargssize);
    2567         [ -  + ]:         48 :     if (!buf[vararg]) {
    2568                 :          0 :         return NULL;
    2569                 :            :     }
    2570                 :            : 
    2571                 :            :     /* copy tuple args */
    2572         [ +  + ]:         94 :     for (i = 0; i < nargs; i++) {
    2573         [ +  - ]:         46 :         if (i >= vararg) {
    2574                 :         46 :             PyTuple_SET_ITEM(buf[vararg], i - vararg, Py_NewRef(args[i]));
    2575                 :         46 :             continue;
    2576                 :            :         }
    2577                 :            :         else {
    2578                 :          0 :             buf[i] = args[i];
    2579                 :            :         }
    2580                 :            :     }
    2581                 :            : 
    2582                 :            :     /* copy keyword args using kwtuple to drive process */
    2583         [ +  + ]:        240 :     for (i = Py_MAX((int)nargs, posonly) -
    2584                 :        240 :          Py_SAFE_DOWNCAST(varargssize, Py_ssize_t, int); i < maxargs; i++) {
    2585         [ +  + ]:        192 :         if (nkwargs) {
    2586                 :        116 :             keyword = PyTuple_GET_ITEM(kwtuple, i - posonly);
    2587         [ -  + ]:        116 :             if (kwargs != NULL) {
    2588                 :          0 :                 current_arg = PyDict_GetItemWithError(kwargs, keyword);
    2589   [ #  #  #  # ]:          0 :                 if (!current_arg && PyErr_Occurred()) {
    2590                 :          0 :                     goto exit;
    2591                 :            :                 }
    2592                 :            :             }
    2593                 :            :             else {
    2594                 :        116 :                 current_arg = find_keyword(kwnames, kwstack, keyword);
    2595                 :            :             }
    2596                 :            :         }
    2597                 :            :         else {
    2598                 :         76 :             current_arg = NULL;
    2599                 :            :         }
    2600                 :            : 
    2601                 :            :         /* If an arguments is passed in as a keyword argument,
    2602                 :            :          * it should be placed before `buf[vararg]`.
    2603                 :            :          *
    2604                 :            :          * For example:
    2605                 :            :          * def f(a, /, b, *args):
    2606                 :            :          *     pass
    2607                 :            :          * f(1, b=2)
    2608                 :            :          *
    2609                 :            :          * This `buf` array should be: [1, 2, NULL].
    2610                 :            :          * In this case, nargs < vararg.
    2611                 :            :          *
    2612                 :            :          * Otherwise, we leave a place at `buf[vararg]` for vararg tuple
    2613                 :            :          * so the index is `i + 1`. */
    2614         [ -  + ]:        192 :         if (nargs < vararg) {
    2615                 :          0 :             buf[i] = current_arg;
    2616                 :            :         }
    2617                 :            :         else {
    2618                 :        192 :             buf[i + 1] = current_arg;
    2619                 :            :         }
    2620                 :            : 
    2621         [ +  + ]:        192 :         if (current_arg) {
    2622                 :         74 :             --nkwargs;
    2623                 :            :         }
    2624   [ +  -  +  -  :        118 :         else if (i < minpos || (maxpos <= i && i < reqlimit)) {
                   -  + ]
    2625                 :            :             /* Less arguments than required */
    2626                 :          0 :             keyword = PyTuple_GET_ITEM(kwtuple, i - posonly);
    2627                 :          0 :             PyErr_Format(PyExc_TypeError,  "%.200s%s missing required "
    2628                 :            :                          "argument '%U' (pos %d)",
    2629         [ #  # ]:          0 :                          (parser->fname == NULL) ? "function" : parser->fname,
    2630         [ #  # ]:          0 :                          (parser->fname == NULL) ? "" : "()",
    2631                 :            :                          keyword, i+1);
    2632                 :          0 :             goto exit;
    2633                 :            :         }
    2634                 :            :     }
    2635                 :            : 
    2636         [ -  + ]:         48 :     if (nkwargs > 0) {
    2637                 :          0 :         error_unexpected_keyword_arg(kwargs, kwnames, kwtuple, parser->fname);
    2638                 :          0 :         goto exit;
    2639                 :            :     }
    2640                 :            : 
    2641                 :         48 :     return buf;
    2642                 :            : 
    2643                 :          0 : exit:
    2644                 :          0 :     Py_XDECREF(buf[vararg]);
    2645                 :          0 :     return NULL;
    2646                 :            : }
    2647                 :            : 
    2648                 :            : 
    2649                 :            : static const char *
    2650                 :        224 : skipitem(const char **p_format, va_list *p_va, int flags)
    2651                 :            : {
    2652                 :        224 :     const char *format = *p_format;
    2653                 :        224 :     char c = *format++;
    2654                 :            : 
    2655   [ +  -  -  +  :        224 :     switch (c) {
                -  -  - ]
    2656                 :            : 
    2657                 :            :     /*
    2658                 :            :      * codes that take a single data pointer as an argument
    2659                 :            :      * (the type of the pointer is irrelevant)
    2660                 :            :      */
    2661                 :            : 
    2662                 :          3 :     case 'b': /* byte -- very short int */
    2663                 :            :     case 'B': /* byte as bitfield */
    2664                 :            :     case 'h': /* short int */
    2665                 :            :     case 'H': /* short int as bitfield */
    2666                 :            :     case 'i': /* int */
    2667                 :            :     case 'I': /* int sized bitfield */
    2668                 :            :     case 'l': /* long int */
    2669                 :            :     case 'k': /* long int sized bitfield */
    2670                 :            :     case 'L': /* long long */
    2671                 :            :     case 'K': /* long long sized bitfield */
    2672                 :            :     case 'n': /* Py_ssize_t */
    2673                 :            :     case 'f': /* float */
    2674                 :            :     case 'd': /* double */
    2675                 :            :     case 'D': /* complex double */
    2676                 :            :     case 'c': /* char */
    2677                 :            :     case 'C': /* unicode char */
    2678                 :            :     case 'p': /* boolean predicate */
    2679                 :            :     case 'S': /* string object */
    2680                 :            :     case 'Y': /* string object */
    2681                 :            :     case 'U': /* unicode string object */
    2682                 :            :         {
    2683         [ +  - ]:          3 :             if (p_va != NULL) {
    2684                 :          3 :                 (void) va_arg(*p_va, void *);
    2685                 :            :             }
    2686                 :          3 :             break;
    2687                 :            :         }
    2688                 :            : 
    2689                 :            :     /* string codes */
    2690                 :            : 
    2691                 :          0 :     case 'e': /* string with encoding */
    2692                 :            :         {
    2693         [ #  # ]:          0 :             if (p_va != NULL) {
    2694                 :          0 :                 (void) va_arg(*p_va, const char *);
    2695                 :            :             }
    2696   [ #  #  #  # ]:          0 :             if (!(*format == 's' || *format == 't'))
    2697                 :            :                 /* after 'e', only 's' and 't' is allowed */
    2698                 :          0 :                 goto err;
    2699                 :          0 :             format++;
    2700                 :            :         }
    2701                 :            :         /* fall through */
    2702                 :            : 
    2703                 :          0 :     case 's': /* string */
    2704                 :            :     case 'z': /* string or None */
    2705                 :            :     case 'y': /* bytes */
    2706                 :            :     case 'w': /* buffer, read-write */
    2707                 :            :         {
    2708         [ #  # ]:          0 :             if (p_va != NULL) {
    2709                 :          0 :                 (void) va_arg(*p_va, char **);
    2710                 :            :             }
    2711         [ #  # ]:          0 :             if (*format == '#') {
    2712         [ #  # ]:          0 :                 if (p_va != NULL) {
    2713         [ #  # ]:          0 :                     if (!(flags & FLAG_SIZE_T)) {
    2714                 :          0 :                         return "PY_SSIZE_T_CLEAN macro must be defined for '#' formats";
    2715                 :            :                     }
    2716                 :          0 :                     (void) va_arg(*p_va, Py_ssize_t *);
    2717                 :            :                 }
    2718                 :          0 :                 format++;
    2719   [ #  #  #  #  :          0 :             } else if ((c == 's' || c == 'z' || c == 'y' || c == 'w')
             #  #  #  # ]
    2720         [ #  # ]:          0 :                        && *format == '*')
    2721                 :            :             {
    2722                 :          0 :                 format++;
    2723                 :            :             }
    2724                 :          0 :             break;
    2725                 :            :         }
    2726                 :            : 
    2727                 :        221 :     case 'O': /* object */
    2728                 :            :         {
    2729         [ -  + ]:        221 :             if (*format == '!') {
    2730                 :          0 :                 format++;
    2731         [ #  # ]:          0 :                 if (p_va != NULL) {
    2732                 :          0 :                     (void) va_arg(*p_va, PyTypeObject*);
    2733                 :          0 :                     (void) va_arg(*p_va, PyObject **);
    2734                 :            :                 }
    2735                 :            :             }
    2736         [ -  + ]:        221 :             else if (*format == '&') {
    2737                 :            :                 typedef int (*converter)(PyObject *, void *);
    2738         [ #  # ]:          0 :                 if (p_va != NULL) {
    2739                 :          0 :                     (void) va_arg(*p_va, converter);
    2740                 :          0 :                     (void) va_arg(*p_va, void *);
    2741                 :            :                 }
    2742                 :          0 :                 format++;
    2743                 :            :             }
    2744                 :            :             else {
    2745         [ +  - ]:        221 :                 if (p_va != NULL) {
    2746                 :        221 :                     (void) va_arg(*p_va, PyObject **);
    2747                 :            :                 }
    2748                 :            :             }
    2749                 :        221 :             break;
    2750                 :            :         }
    2751                 :            : 
    2752                 :          0 :     case '(':           /* bypass tuple, not handled at all previously */
    2753                 :            :         {
    2754                 :            :             const char *msg;
    2755                 :            :             for (;;) {
    2756         [ #  # ]:          0 :                 if (*format==')')
    2757                 :          0 :                     break;
    2758   [ #  #  #  #  :          0 :                 if (IS_END_OF_FORMAT(*format))
                   #  # ]
    2759                 :          0 :                     return "Unmatched left paren in format "
    2760                 :            :                            "string";
    2761                 :          0 :                 msg = skipitem(&format, p_va, flags);
    2762         [ #  # ]:          0 :                 if (msg)
    2763                 :          0 :                     return msg;
    2764                 :            :             }
    2765                 :          0 :             format++;
    2766                 :          0 :             break;
    2767                 :            :         }
    2768                 :            : 
    2769                 :          0 :     case ')':
    2770                 :          0 :         return "Unmatched right paren in format string";
    2771                 :            : 
    2772                 :            :     default:
    2773                 :          0 : err:
    2774                 :          0 :         return "impossible<bad format char>";
    2775                 :            : 
    2776                 :            :     }
    2777                 :            : 
    2778                 :        224 :     *p_format = format;
    2779                 :        224 :     return NULL;
    2780                 :            : }
    2781                 :            : 
    2782                 :            : 
    2783                 :            : #undef _PyArg_CheckPositional
    2784                 :            : 
    2785                 :            : int
    2786                 :      11414 : _PyArg_CheckPositional(const char *name, Py_ssize_t nargs,
    2787                 :            :                        Py_ssize_t min, Py_ssize_t max)
    2788                 :            : {
    2789                 :            :     assert(min >= 0);
    2790                 :            :     assert(min <= max);
    2791                 :            : 
    2792         [ +  + ]:      11414 :     if (nargs < min) {
    2793         [ +  - ]:         12 :         if (name != NULL)
    2794   [ +  +  +  + ]:         12 :             PyErr_Format(
    2795                 :            :                 PyExc_TypeError,
    2796                 :            :                 "%.200s expected %s%zd argument%s, got %zd",
    2797                 :            :                 name, (min == max ? "" : "at least "), min, min == 1 ? "" : "s", nargs);
    2798                 :            :         else
    2799   [ #  #  #  # ]:          0 :             PyErr_Format(
    2800                 :            :                 PyExc_TypeError,
    2801                 :            :                 "unpacked tuple should have %s%zd element%s,"
    2802                 :            :                 " but has %zd",
    2803                 :            :                 (min == max ? "" : "at least "), min, min == 1 ? "" : "s", nargs);
    2804                 :         12 :         return 0;
    2805                 :            :     }
    2806                 :            : 
    2807         [ +  + ]:      11402 :     if (nargs == 0) {
    2808                 :        854 :         return 1;
    2809                 :            :     }
    2810                 :            : 
    2811         [ +  + ]:      10548 :     if (nargs > max) {
    2812         [ +  - ]:          4 :         if (name != NULL)
    2813   [ -  +  +  + ]:          4 :             PyErr_Format(
    2814                 :            :                 PyExc_TypeError,
    2815                 :            :                 "%.200s expected %s%zd argument%s, got %zd",
    2816                 :            :                 name, (min == max ? "" : "at most "), max, max == 1 ? "" : "s", nargs);
    2817                 :            :         else
    2818   [ #  #  #  # ]:          0 :             PyErr_Format(
    2819                 :            :                 PyExc_TypeError,
    2820                 :            :                 "unpacked tuple should have %s%zd element%s,"
    2821                 :            :                 " but has %zd",
    2822                 :            :                 (min == max ? "" : "at most "), max, max == 1 ? "" : "s", nargs);
    2823                 :          4 :         return 0;
    2824                 :            :     }
    2825                 :            : 
    2826                 :      10544 :     return 1;
    2827                 :            : }
    2828                 :            : 
    2829                 :            : static int
    2830                 :      11398 : unpack_stack(PyObject *const *args, Py_ssize_t nargs, const char *name,
    2831                 :            :              Py_ssize_t min, Py_ssize_t max, va_list vargs)
    2832                 :            : {
    2833                 :            :     Py_ssize_t i;
    2834                 :            :     PyObject **o;
    2835                 :            : 
    2836         [ -  + ]:      11398 :     if (!_PyArg_CheckPositional(name, nargs, min, max)) {
    2837                 :          0 :         return 0;
    2838                 :            :     }
    2839                 :            : 
    2840         [ +  + ]:      28417 :     for (i = 0; i < nargs; i++) {
    2841                 :      17019 :         o = va_arg(vargs, PyObject **);
    2842                 :      17019 :         *o = args[i];
    2843                 :            :     }
    2844                 :      11398 :     return 1;
    2845                 :            : }
    2846                 :            : 
    2847                 :            : int
    2848                 :      10321 : PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...)
    2849                 :            : {
    2850                 :            :     PyObject **stack;
    2851                 :            :     Py_ssize_t nargs;
    2852                 :            :     int retval;
    2853                 :            :     va_list vargs;
    2854                 :            : 
    2855         [ -  + ]:      10321 :     if (!PyTuple_Check(args)) {
    2856                 :          0 :         PyErr_SetString(PyExc_SystemError,
    2857                 :            :             "PyArg_UnpackTuple() argument list is not a tuple");
    2858                 :          0 :         return 0;
    2859                 :            :     }
    2860                 :      10321 :     stack = _PyTuple_ITEMS(args);
    2861                 :      10321 :     nargs = PyTuple_GET_SIZE(args);
    2862                 :            : 
    2863                 :      10321 :     va_start(vargs, max);
    2864                 :      10321 :     retval = unpack_stack(stack, nargs, name, min, max, vargs);
    2865                 :      10321 :     va_end(vargs);
    2866                 :      10321 :     return retval;
    2867                 :            : }
    2868                 :            : 
    2869                 :            : int
    2870                 :       1077 : _PyArg_UnpackStack(PyObject *const *args, Py_ssize_t nargs, const char *name,
    2871                 :            :                    Py_ssize_t min, Py_ssize_t max, ...)
    2872                 :            : {
    2873                 :            :     int retval;
    2874                 :            :     va_list vargs;
    2875                 :            : 
    2876                 :       1077 :     va_start(vargs, max);
    2877                 :       1077 :     retval = unpack_stack(args, nargs, name, min, max, vargs);
    2878                 :       1077 :     va_end(vargs);
    2879                 :       1077 :     return retval;
    2880                 :            : }
    2881                 :            : 
    2882                 :            : 
    2883                 :            : #undef _PyArg_NoKeywords
    2884                 :            : #undef _PyArg_NoKwnames
    2885                 :            : #undef _PyArg_NoPositional
    2886                 :            : 
    2887                 :            : /* For type constructors that don't take keyword args
    2888                 :            :  *
    2889                 :            :  * Sets a TypeError and returns 0 if the args/kwargs is
    2890                 :            :  * not empty, returns 1 otherwise
    2891                 :            :  */
    2892                 :            : int
    2893                 :          0 : _PyArg_NoKeywords(const char *funcname, PyObject *kwargs)
    2894                 :            : {
    2895         [ #  # ]:          0 :     if (kwargs == NULL) {
    2896                 :          0 :         return 1;
    2897                 :            :     }
    2898         [ #  # ]:          0 :     if (!PyDict_CheckExact(kwargs)) {
    2899                 :          0 :         PyErr_BadInternalCall();
    2900                 :          0 :         return 0;
    2901                 :            :     }
    2902         [ #  # ]:          0 :     if (PyDict_GET_SIZE(kwargs) == 0) {
    2903                 :          0 :         return 1;
    2904                 :            :     }
    2905                 :            : 
    2906                 :          0 :     PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
    2907                 :            :                     funcname);
    2908                 :          0 :     return 0;
    2909                 :            : }
    2910                 :            : 
    2911                 :            : int
    2912                 :          0 : _PyArg_NoPositional(const char *funcname, PyObject *args)
    2913                 :            : {
    2914         [ #  # ]:          0 :     if (args == NULL)
    2915                 :          0 :         return 1;
    2916         [ #  # ]:          0 :     if (!PyTuple_CheckExact(args)) {
    2917                 :          0 :         PyErr_BadInternalCall();
    2918                 :          0 :         return 0;
    2919                 :            :     }
    2920         [ #  # ]:          0 :     if (PyTuple_GET_SIZE(args) == 0)
    2921                 :          0 :         return 1;
    2922                 :            : 
    2923                 :          0 :     PyErr_Format(PyExc_TypeError, "%.200s() takes no positional arguments",
    2924                 :            :                     funcname);
    2925                 :          0 :     return 0;
    2926                 :            : }
    2927                 :            : 
    2928                 :            : int
    2929                 :          0 : _PyArg_NoKwnames(const char *funcname, PyObject *kwnames)
    2930                 :            : {
    2931         [ #  # ]:          0 :     if (kwnames == NULL) {
    2932                 :          0 :         return 1;
    2933                 :            :     }
    2934                 :            : 
    2935                 :            :     assert(PyTuple_CheckExact(kwnames));
    2936                 :            : 
    2937         [ #  # ]:          0 :     if (PyTuple_GET_SIZE(kwnames) == 0) {
    2938                 :          0 :         return 1;
    2939                 :            :     }
    2940                 :            : 
    2941                 :          0 :     PyErr_Format(PyExc_TypeError, "%s() takes no keyword arguments", funcname);
    2942                 :          0 :     return 0;
    2943                 :            : }
    2944                 :            : 
    2945                 :            : void
    2946                 :         25 : _PyArg_Fini(void)
    2947                 :            : {
    2948                 :         25 :     struct _PyArg_Parser *tmp, *s = _PyRuntime.getargs.static_parsers;
    2949         [ +  + ]:        113 :     while (s) {
    2950                 :         88 :         tmp = s->next;
    2951                 :         88 :         s->next = NULL;
    2952                 :         88 :         parser_clear(s);
    2953                 :         88 :         s = tmp;
    2954                 :            :     }
    2955                 :         25 :     _PyRuntime.getargs.static_parsers = NULL;
    2956                 :         25 : }
    2957                 :            : 
    2958                 :            : #ifdef __cplusplus
    2959                 :            : };
    2960                 :            : #endif

Generated by: LCOV version 1.14