* Internal function to initialize keyword argument parsing. * * This does a few simple jobs: * * * Check the input for consistency to find coding errors, for example * a parameter not marked with | after one marked with | (optional). * 2. Find the number of positional-only arguments, the number of * total, required, and keyword arguments. * 3. Intern all keyword arguments strings to a
| 71 | * @return 0 on success, -1 on failure |
| 72 | */ |
| 73 | static int |
| 74 | initialize_keywords(const char *funcname, |
| 75 | _NpyArgParserCache *cache, va_list va_orig) { |
| 76 | va_list va; |
| 77 | int nargs = 0; |
| 78 | int nkwargs = 0; |
| 79 | int npositional_only = 0; |
| 80 | int nrequired = 0; |
| 81 | int npositional = 0; |
| 82 | char state = '\0'; |
| 83 | |
| 84 | va_copy(va, va_orig); |
| 85 | while (1) { |
| 86 | /* Count length first: */ |
| 87 | char *name = va_arg(va, char *); |
| 88 | convert *converter = va_arg(va, convert *); |
| 89 | void *data = va_arg(va, void *); |
| 90 | |
| 91 | /* Check if this is the sentinel, only converter may be NULL */ |
| 92 | if ((name == NULL) && (converter == NULL) && (data == NULL)) { |
| 93 | break; |
| 94 | } |
| 95 | |
| 96 | if (name == NULL) { |
| 97 | PyErr_Format(PyExc_SystemError, |
| 98 | "NumPy internal error: name is NULL in %s() at " |
| 99 | "argument %d.", funcname, nargs); |
| 100 | va_end(va); |
| 101 | return -1; |
| 102 | } |
| 103 | if (data == NULL) { |
| 104 | PyErr_Format(PyExc_SystemError, |
| 105 | "NumPy internal error: data is NULL in %s() at " |
| 106 | "argument %d.", funcname, nargs); |
| 107 | va_end(va); |
| 108 | return -1; |
| 109 | } |
| 110 | |
| 111 | nargs += 1; |
| 112 | if (*name == '|') { |
| 113 | if (state == '$') { |
| 114 | PyErr_Format(PyExc_SystemError, |
| 115 | "NumPy internal error: positional argument `|` " |
| 116 | "after keyword only `$` one to %s() at argument %d.", |
| 117 | funcname, nargs); |
| 118 | va_end(va); |
| 119 | return -1; |
| 120 | } |
| 121 | state = '|'; |
| 122 | name++; /* advance to actual name. */ |
| 123 | npositional += 1; |
| 124 | } |
| 125 | else if (*name == '$') { |
| 126 | state = '$'; |
| 127 | name++; /* advance to actual name. */ |
| 128 | } |
| 129 | else { |
| 130 | if (state != '\0') { |
no outgoing calls
no test coverage detected