blob: a73bc8043f5f5b7abecc3ae1a4e2e3e69cdb1fdd [file] [log] [blame]
Guido van Rossumfe3f1a21994-09-29 09:42:55 +00001/***********************************************************
Guido van Rossum6d023c91995-01-04 19:12:13 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumfe3f1a21994-09-29 09:42:55 +00004
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumfe3f1a21994-09-29 09:42:55 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumfe3f1a21994-09-29 09:42:55 +000029
30******************************************************************/
31
32/* New getargs implementation */
33
34/* XXX There are several unchecked sprintf or strcat calls in this file.
35 XXX The only way these can become a danger is if some C code in the
36 XXX Python source (or in an extension) uses ridiculously long names
37 XXX or riduculously deep nesting in format strings. */
38
39#include "allobjects.h"
40
Guido van Rossumc1d50531996-08-21 23:38:24 +000041#include <ctype.h>
42
Guido van Rossumfe3f1a21994-09-29 09:42:55 +000043
44int getargs PROTO((object *, char *, ...));
45int newgetargs PROTO((object *, char *, ...));
46int vgetargs PROTO((object *, char *, va_list));
47
Guido van Rossumaa354651996-08-19 19:32:04 +000048int PyArg_ParseTupleAndKeywords PROTO((object *, object *,
49 char *, char **, ...));
Guido van Rossumfe3f1a21994-09-29 09:42:55 +000050
51/* Forward */
Guido van Rossum1ae940a1995-01-02 19:04:15 +000052static int vgetargs1 PROTO((object *, char *, va_list *, int));
Guido van Rossumfe3f1a21994-09-29 09:42:55 +000053static void seterror PROTO((int, char *, int *, char *, char *));
54static char *convertitem PROTO((object *, char **, va_list *, int *, char *));
55static char *converttuple PROTO((object *, char **, va_list *,
56 int *, char *, int));
57static char *convertsimple PROTO((object *, char **, va_list *, char *));
58static char *convertsimple1 PROTO((object *, char **, va_list *));
59
Guido van Rossumaa354651996-08-19 19:32:04 +000060static int vgetargskeywords PROTO((object *, object *,
61 char *, char **, va_list *));
62static char *skipitem PROTO((char **, va_list *));
Guido van Rossumfe3f1a21994-09-29 09:42:55 +000063
64#ifdef HAVE_STDARG_PROTOTYPES
65/* VARARGS2 */
66int getargs(object *args, char *format, ...)
67#else
68/* VARARGS */
69int getargs(va_alist) va_dcl
70#endif
71{
72 int retval;
73 va_list va;
74#ifdef HAVE_STDARG_PROTOTYPES
75
76 va_start(va, format);
77#else
78 object *args;
79 char *format;
80
81 va_start(va);
82 args = va_arg(va, object *);
83 format = va_arg(va, char *);
84#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +000085 retval = vgetargs1(args, format, &va, 1);
Guido van Rossumfe3f1a21994-09-29 09:42:55 +000086 va_end(va);
87 return retval;
88}
89
90
91#ifdef HAVE_STDARG_PROTOTYPES
92/* VARARGS2 */
93int newgetargs(object *args, char *format, ...)
94#else
95/* VARARGS */
96int newgetargs(va_alist) va_dcl
97#endif
98{
99 int retval;
100 va_list va;
101#ifdef HAVE_STDARG_PROTOTYPES
102
103 va_start(va, format);
104#else
105 object *args;
106 char *format;
107
108 va_start(va);
109 args = va_arg(va, object *);
110 format = va_arg(va, char *);
111#endif
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000112 retval = vgetargs1(args, format, &va, 0);
Guido van Rossumfe3f1a21994-09-29 09:42:55 +0000113 va_end(va);
114 return retval;
115}
116
117
118int
119vgetargs(args, format, va)
120 object *args;
121 char *format;
122 va_list va;
123{
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000124 va_list lva;
125
126#ifdef VA_LIST_IS_ARRAY
127 memcpy(lva, va, sizeof(va_list));
128#else
129 lva = va;
130#endif
131
132 return vgetargs1(args, format, &lva, 0);
Guido van Rossumfe3f1a21994-09-29 09:42:55 +0000133}
134
135
136static int
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000137vgetargs1(args, format, p_va, compat)
Guido van Rossumfe3f1a21994-09-29 09:42:55 +0000138 object *args;
139 char *format;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000140 va_list *p_va;
Guido van Rossumfe3f1a21994-09-29 09:42:55 +0000141 int compat;
142{
143 char msgbuf[256];
144 int levels[32];
145 char *fname = NULL;
146 char *message = NULL;
147 int min = -1;
148 int max = 0;
149 int level = 0;
150 char *formatsave = format;
151 int i, len;
152 char *msg;
153
154 for (;;) {
155 int c = *format++;
156 if (c == '(' /* ')' */) {
157 if (level == 0)
158 max++;
159 level++;
160 }
161 else if (/* '(' */ c == ')') {
162 if (level == 0)
163 fatal(/* '(' */
164 "excess ')' in getargs format");
165 else
166 level--;
167 }
168 else if (c == '\0')
169 break;
170 else if (c == ':') {
171 fname = format;
172 break;
173 }
174 else if (c == ';') {
175 message = format;
176 break;
177 }
178 else if (level != 0)
179 ; /* Pass */
180 else if (isalpha(c))
181 max++;
182 else if (c == '|')
183 min = max;
184 }
185
186 if (level != 0)
187 fatal(/* '(' */ "missing ')' in getargs format");
188
189 if (min < 0)
190 min = max;
191
192 format = formatsave;
193
194 if (compat) {
195 if (max == 0) {
196 if (args == NULL)
197 return 1;
198 sprintf(msgbuf, "%s requires no arguments",
199 fname==NULL ? "function" : fname);
200 err_setstr(TypeError, msgbuf);
201 return 0;
202 }
203 else if (min == 1 && max == 1) {
Guido van Rossum13d0ed11994-11-10 22:35:48 +0000204 if (args == NULL) {
205 sprintf(msgbuf,
206 "%s requires at least one argument",
207 fname==NULL ? "function" : fname);
208 err_setstr(TypeError, msgbuf);
209 return 0;
210 }
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000211 msg = convertitem(args, &format, p_va, levels, msgbuf);
Guido van Rossumfe3f1a21994-09-29 09:42:55 +0000212 if (msg == NULL)
213 return 1;
214 seterror(levels[0], msg, levels+1, fname, message);
215 return 0;
216 }
217 else {
218 err_setstr(SystemError,
219 "old style getargs format uses new features");
220 return 0;
221 }
222 }
223
224 if (!is_tupleobject(args)) {
225 err_setstr(SystemError,
226 "new style getargs format but argument is not a tuple");
227 return 0;
228 }
229
230 len = gettuplesize(args);
231
232 if (len < min || max < len) {
233 if (message == NULL) {
234 sprintf(msgbuf,
235 "%s requires %s %d argument%s; %d given",
236 fname==NULL ? "function" : fname,
237 min==max ? "exactly"
238 : len < min ? "at least" : "at most",
239 len < min ? min : max,
240 (len < min ? min : max) == 1 ? "" : "s",
241 len);
242 message = msgbuf;
243 }
244 err_setstr(TypeError, message);
245 return 0;
246 }
247
248 for (i = 0; i < len; i++) {
249 if (*format == '|')
250 format++;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000251 msg = convertitem(gettupleitem(args, i), &format, p_va,
Guido van Rossumfe3f1a21994-09-29 09:42:55 +0000252 levels, msgbuf);
253 if (msg) {
254 seterror(i+1, msg, levels, fname, message);
255 return 0;
256 }
257 }
258
259 return 1;
260}
261
262
263
264static void
265seterror(iarg, msg, levels, fname, message)
266 int iarg;
267 char *msg;
268 int *levels;
269 char *fname;
270 char *message;
271{
272 char buf[256];
273 int i;
274 char *p = buf;
275
Guido van Rossum64fc6491995-01-21 14:09:37 +0000276 if (err_occurred())
277 return;
Guido van Rossumfe3f1a21994-09-29 09:42:55 +0000278 if (iarg == 0 && message == NULL)
279 message = msg;
280 else if (message == NULL) {
281 if (fname != NULL) {
282 sprintf(p, "%s, ", fname);
283 p += strlen(p);
284 }
285 sprintf(p, "argument %d", iarg);
286 i = 0;
287 p += strlen(p);
288 while (levels[i] > 0) {
289 sprintf(p, ", item %d", levels[i]-1);
290 p += strlen(p);
291 i++;
292 }
293 sprintf(p, ": expected %s found", msg);
294 message = buf;
295 }
296 err_setstr(TypeError, message);
297}
298
299
300/* Convert a tuple argument.
301 On entry, *p_format points to the character _after_ the opening '('.
302 On successful exit, *p_format points to the closing ')'.
303 If successful:
304 *p_format and *p_va are updated,
305 *levels and *msgbuf are untouched,
306 and NULL is returned.
307 If the argument is invalid:
308 *p_format is unchanged,
309 *p_va is undefined,
310 *levels is a 0-terminated list of item numbers,
311 *msgbuf contains an error message, whose format is:
312 "<typename1>, <typename2>", where:
313 <typename1> is the name of the expected type, and
314 <typename2> is the name of the actual type,
315 (so you can surround it by "expected ... found"),
316 and msgbuf is returned.
317*/
318
319static char *
320converttuple(arg, p_format, p_va, levels, msgbuf, toplevel)
321 object *arg;
322 char **p_format;
323 va_list *p_va;
324 int *levels;
325 char *msgbuf;
326 int toplevel;
327{
328 int level = 0;
329 int n = 0;
330 char *format = *p_format;
331 int i;
332
333 for (;;) {
334 int c = *format++;
335 if (c == '(') {
336 if (level == 0)
337 n++;
338 level++;
339 }
340 else if (c == ')') {
341 if (level == 0)
342 break;
343 level--;
344 }
345 else if (c == ':' || c == ';' || c == '\0')
346 break;
347 else if (level == 0 && isalpha(c))
348 n++;
349 }
350
351 if (!is_tupleobject(arg)) {
352 levels[0] = 0;
353 sprintf(msgbuf,
354 toplevel ? "%d arguments, %s" : "%d-tuple, %s",
355 n, arg == None ? "None" : arg->ob_type->tp_name);
356 return msgbuf;
357 }
358
359 if ((i = gettuplesize(arg)) != n) {
360 levels[0] = 0;
361 sprintf(msgbuf,
362 toplevel ? "%d arguments, %d" : "%d-tuple, %d-tuple",
363 n, i);
364 return msgbuf;
365 }
366
367 format = *p_format;
368 for (i = 0; i < n; i++) {
369 char *msg;
370 msg = convertitem(gettupleitem(arg, i), &format, p_va,
371 levels+1, msgbuf);
372 if (msg != NULL) {
373 levels[0] = i+1;
374 return msg;
375 }
376 }
377
378 *p_format = format;
379 return NULL;
380}
381
382
383/* Convert a single item. */
384
385static char *
386convertitem(arg, p_format, p_va, levels, msgbuf)
387 object *arg;
388 char **p_format;
389 va_list *p_va;
390 int *levels;
391 char *msgbuf;
392{
393 char *msg;
394 char *format = *p_format;
395
396 if (*format == '(' /* ')' */) {
397 format++;
398 msg = converttuple(arg, &format, p_va, levels, msgbuf, 0);
399 if (msg == NULL)
400 format++;
401 }
402 else {
403 msg = convertsimple(arg, &format, p_va, msgbuf);
404 if (msg != NULL)
405 levels[0] = 0;
406 }
407 if (msg == NULL)
408 *p_format = format;
409 return msg;
410}
411
412
413/* Convert a non-tuple argument. Adds to convertsimple1 functionality
414 by appending ", <actual argument type>" to error message. */
415
416static char *
417convertsimple(arg, p_format, p_va, msgbuf)
418 object *arg;
419 char **p_format;
420 va_list *p_va;
421 char *msgbuf;
422{
423 char *msg = convertsimple1(arg, p_format, p_va);
424 if (msg != NULL) {
425 sprintf(msgbuf, "%.50s, %.50s", msg,
426 arg == None ? "None" : arg->ob_type->tp_name);
427 msg = msgbuf;
428 }
429 return msg;
430}
431
432
433/* Convert a non-tuple argument. Return NULL if conversion went OK,
434 or a string representing the expected type if the conversion failed.
435 When failing, an exception may or may not have been raised.
436 Don't call if a tuple is expected. */
437
438static char *
439convertsimple1(arg, p_format, p_va)
440 object *arg;
441 char **p_format;
442 va_list *p_va;
443{
444 char *format = *p_format;
445 char c = *format++;
446
447 switch (c) {
448
449 case 'b': /* byte -- very short int */
450 {
451 char *p = va_arg(*p_va, char *);
452 long ival = getintvalue(arg);
453 if (ival == -1 && err_occurred())
454 return "integer<b>";
455 else
456 *p = ival;
457 break;
458 }
459
460 case 'h': /* short int */
461 {
462 short *p = va_arg(*p_va, short *);
463 long ival = getintvalue(arg);
464 if (ival == -1 && err_occurred())
465 return "integer<h>";
466 else
467 *p = ival;
468 break;
469 }
470
471 case 'i': /* int */
472 {
473 int *p = va_arg(*p_va, int *);
474 long ival = getintvalue(arg);
475 if (ival == -1 && err_occurred())
476 return "integer<i>";
477 else
478 *p = ival;
479 break;
480 }
481
482 case 'l': /* long int */
483 {
484 long *p = va_arg(*p_va, long *);
485 long ival = getintvalue(arg);
486 if (ival == -1 && err_occurred())
487 return "integer<l>";
488 else
489 *p = ival;
490 break;
491 }
492
493 case 'f': /* float */
494 {
495 float *p = va_arg(*p_va, float *);
496 double dval = getfloatvalue(arg);
497 if (err_occurred())
498 return "float<f>";
499 else
500 *p = dval;
501 break;
502 }
503
504 case 'd': /* double */
505 {
506 double *p = va_arg(*p_va, double *);
507 double dval = getfloatvalue(arg);
508 if (err_occurred())
509 return "float<d>";
510 else
511 *p = dval;
512 break;
513 }
514
Guido van Rossum530956d1996-07-21 02:27:43 +0000515#ifndef WITHOUT_COMPLEX
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000516 case 'D': /* complex double */
517 {
Guido van Rossum530956d1996-07-21 02:27:43 +0000518 Py_complex *p = va_arg(*p_va, Py_complex *);
Guido van Rossumaa354651996-08-19 19:32:04 +0000519 Py_complex cval;
520 cval = PyComplex_AsCComplex(arg);
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000521 if (err_occurred())
522 return "complex<D>";
523 else
524 *p = cval;
525 break;
526 }
Guido van Rossum530956d1996-07-21 02:27:43 +0000527#endif /* WITHOUT_COMPLEX */
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000528
Guido van Rossumfe3f1a21994-09-29 09:42:55 +0000529 case 'c': /* char */
530 {
531 char *p = va_arg(*p_va, char *);
532 if (is_stringobject(arg) && getstringsize(arg) == 1)
533 *p = getstringvalue(arg)[0];
534 else
535 return "char";
536 break;
537 }
538
539 case 's': /* string */
540 {
541 char **p = va_arg(*p_va, char **);
542 if (is_stringobject(arg))
543 *p = getstringvalue(arg);
544 else
545 return "string";
546 if (*format == '#') {
547 int *q = va_arg(*p_va, int *);
548 *q = getstringsize(arg);
549 format++;
550 }
551 else if (strlen(*p) != getstringsize(arg))
552 return "string without null bytes";
553 break;
554 }
555
556 case 'z': /* string, may be NULL (None) */
557 {
558 char **p = va_arg(*p_va, char **);
559 if (arg == None)
560 *p = 0;
561 else if (is_stringobject(arg))
562 *p = getstringvalue(arg);
563 else
564 return "None or string";
565 if (*format == '#') {
566 int *q = va_arg(*p_va, int *);
567 if (arg == None)
568 *q = 0;
569 else
570 *q = getstringsize(arg);
571 format++;
572 }
Guido van Rossumaa354651996-08-19 19:32:04 +0000573 else if (*p != NULL &&
574 strlen(*p) != getstringsize(arg))
Guido van Rossumfe3f1a21994-09-29 09:42:55 +0000575 return "None or string without null bytes";
576 break;
577 }
578
579 case 'S': /* string object */
580 {
581 object **p = va_arg(*p_va, object **);
582 if (is_stringobject(arg))
583 *p = arg;
584 else
585 return "string";
586 break;
587 }
588
589 case 'O': /* object */
590 {
591 typeobject *type;
592 object **p;
593 if (*format == '!') {
594 format++;
595 type = va_arg(*p_va, typeobject*);
596 if (arg->ob_type != type)
597 return type->tp_name;
598 else {
599 p = va_arg(*p_va, object **);
600 *p = arg;
601 }
602 }
603 else if (*format == '?') {
604 inquiry pred = va_arg(*p_va, inquiry);
605 format++;
606 if ((*pred)(arg)) {
607 p = va_arg(*p_va, object **);
608 *p = arg;
609 }
610 }
611 else if (*format == '&') {
Guido van Rossumaa354651996-08-19 19:32:04 +0000612 typedef int (*converter)
613 PROTO((object *, void *));
Guido van Rossumfe3f1a21994-09-29 09:42:55 +0000614 converter convert = va_arg(*p_va, converter);
615 void *addr = va_arg(*p_va, void *);
616 format++;
617 if (! (*convert)(arg, addr))
Guido van Rossum64fc6491995-01-21 14:09:37 +0000618 return "(unspecified)";
Guido van Rossumfe3f1a21994-09-29 09:42:55 +0000619 }
620 else {
621 p = va_arg(*p_va, object **);
622 *p = arg;
623 }
624 break;
625 }
626
627 default:
628 return "impossible<bad format char>";
629
630 }
631
632 *p_format = format;
633 return NULL;
634}
Guido van Rossumaa354651996-08-19 19:32:04 +0000635
636
637/* Support for keyword arguments donated by
638 Geoff Philbrick <philbric@delphi.hks.com> */
639
640#ifdef HAVE_STDARG_PROTOTYPES
641/* VARARGS2 */
642int PyArg_ParseTupleAndKeywords(object *args,
643 object *keywords,
644 char *format,
645 char **kwlist, ...)
646#else
647/* VARARGS */
648int PyArg_ParseTupleAndKeywords(va_alist) va_dcl
649#endif
650{
651 int retval;
652 va_list va;
653#ifdef HAVE_STDARG_PROTOTYPES
654
655 va_start(va, kwlist);
656#else
657 object *args;
658 object *keywords;
659 char *format;
660 char **kwlist;
661
662 va_start(va);
663 args = va_arg(va, object *);
664 keywords = va_arg(va, object *);
665 format = va_arg(va, char *);
666 kwlist = va_arg(va, char **);
667#endif
668 retval = vgetargskeywords(args, keywords, format, kwlist, &va);
669 va_end(va);
670 return retval;
671}
672
673
674static int
675vgetargskeywords(args, keywords, format, kwlist, p_va)
676 object *args;
677 object *keywords;
678 char *format;
679 char **kwlist;
680 va_list *p_va;
681{
682 char msgbuf[256];
683 int levels[32];
684 char *fname = NULL;
685 char *message = NULL;
686 int min = -1;
687 int max = 0;
688 int level = 0;
689 char *formatsave = format;
690 int i, len, tplen, kwlen;
691 char *msg, *ks, **p;
692 int nkwds, pos, match, converted;
693 object *key, *value, *item;
694
695 /* nested tuples cannot be parsed when using keyword arguments */
696
697 for (;;) {
698 int c = *format++;
699 if (c == '(') {
700 PyErr_SetString(PyExc_SystemError,
701 "tuple found in format when using keyword arguments");
702 return 0;
703 }
704 else if (c == '\0')
705 break;
706 else if (c == ':') {
707 fname = format;
708 break;
709 }
710 else if (c == ';') {
711 message = format;
712 break;
713 }
714 else if (isalpha(c))
715 max++;
716 else if (c == '|')
717 min = max;
718 }
719
720 if (min < 0)
721 min = max;
722
723 format = formatsave;
724
725 if (!PyTuple_Check(args)) {
726 PyErr_SetString(PyExc_SystemError,
727 "new style getargs format but argument is not a tuple");
728 return 0;
729 }
730
731 tplen = PyTuple_Size(args);
732
733 /* do a cursory check of the keywords just to see how many we got */
734
735 if (keywords) {
736 if (!PyDict_Check(keywords)) {
737 PyErr_SetString(PyExc_SystemError,
738 "non-dictionary object received when keyword dictionary expected");
739 return 0;
740 }
741 kwlen = PyDict_Size(keywords);
742 }
743 else {
744 kwlen = 0;
745 }
746
747 /* make sure there are no duplicate values for an argument;
748 its not clear when to use the term "keyword argument vs.
749 keyword parameter in messages */
750
751 if (keywords) {
752 for (i = 0; i < tplen; i++) {
753 if (PyMapping_HasKeyString(keywords, kwlist[i])) {
754 sprintf(msgbuf,
755 "keyword parameter %s redefined",
756 kwlist[i]);
757 PyErr_SetString(PyExc_TypeError, msgbuf);
758 return 0;
759 }
760 }
761 }
762 PyErr_Clear(); /* I'm not which Py functions set the error string */
763
764 /* required arguments missing from args can be supplied by keyword
765 arguments */
766
767 len = tplen;
768 if (keywords && tplen < min) {
769 for (i = tplen; i < min; i++) {
770 if (PyMapping_HasKeyString(keywords, kwlist[i])) {
771 len++;
772 }
773 }
774 }
775 PyErr_Clear();
776
777 /* make sure we got an acceptable number of arguments; the message
778 is a little confusing with keywords since keyword arguments
779 which are supplied, but don't match the required arguments
780 are not included in the "%d given" part of the message */
781
782 if (len < min || max < len) {
783 if (message == NULL) {
784 sprintf(msgbuf,
785 "%s requires %s %d argument%s; %d given",
786 fname==NULL ? "function" : fname,
787 min==max ? "exactly"
788 : len < min ? "at least" : "at most",
789 len < min ? min : max,
790 (len < min ? min : max) == 1 ? "" : "s",
791 len);
792 message = msgbuf;
793 }
794 PyErr_SetString(PyExc_TypeError, message);
795 return 0;
796 }
797
798 for (i = 0; i < tplen; i++) {
799 if (*format == '|')
800 format++;
801 msg = convertitem(PyTuple_GetItem(args, i), &format, p_va,
802 levels, msgbuf);
803 if (msg) {
804 seterror(i+1, msg, levels, fname, message);
805 return 0;
806 }
807 }
808
809 /* handle no keyword parameters in call */
810
811 if (!keywords) return 1;
812
813 /* make sure the number of keywords in the keyword list matches the
814 number of items in the format string */
815
816 nkwds = 0;
817 p = kwlist;
818 for (;;) {
819 if (!*(p++)) break;
820 nkwds++;
821 }
822
823 if (nkwds != max) {
824 PyErr_SetString(PyExc_SystemError,
825 "number of items in format string and keyword list do not match");
826 return 0;
827 }
828
829 /* convert the keyword arguments; this uses the format
830 string where it was left after processing args */
831
832 converted = 0;
833 for (i = tplen; i < nkwds; i++) {
834 if (*format == '|')
835 format++;
836 if (item = PyMapping_GetItemString(keywords, kwlist[i])) {
837 msg = convertitem(item, &format, p_va, levels, msgbuf);
838 if (msg) {
839 seterror(i+1, msg, levels, fname, message);
840 return 0;
841 }
842 converted++;
843 }
844 else {
845 PyErr_Clear();
846 msg = skipitem(&format, p_va);
847 if (msg) {
848 seterror(i+1, msg, levels, fname, message);
849 return 0;
850 }
851 }
852 }
853
854 /* make sure there are no extraneous keyword arguments */
855
856 pos = 0;
857 if (converted < kwlen) {
858 while (PyDict_Next(keywords, &pos, &key, &value)) {
859 match = 0;
860 ks = PyString_AsString(key);
861 for (i = 0; i < nkwds; i++) {
862 if (!strcmp(ks, kwlist[i])) {
863 match = 1;
864 break;
865 }
866 }
867 if (!match) {
868 sprintf(msgbuf,
869 "%s is an invalid keyword argument for this function",
870 ks);
871 PyErr_SetString(PyExc_TypeError, msgbuf);
872 return 0;
873 }
874 }
875 }
876
877 return 1;
878}
879
880
881static char *
882skipitem(p_format, p_va)
883 char **p_format;
884 va_list *p_va;
885{
886 char *format = *p_format;
887 char c = *format++;
888
889 switch (c) {
890
891 case 'b': /* byte -- very short int */
892 {
893 va_arg(*p_va, char *);
894 break;
895 }
896
897 case 'h': /* short int */
898 {
899 va_arg(*p_va, short *);
900 break;
901 }
902
903 case 'i': /* int */
904 {
905 va_arg(*p_va, int *);
906 break;
907 }
908
909 case 'l': /* long int */
910 {
911 va_arg(*p_va, long *);
912 break;
913 }
914
915 case 'f': /* float */
916 {
917 va_arg(*p_va, float *);
918 break;
919 }
920
921 case 'd': /* double */
922 {
923 va_arg(*p_va, double *);
924 break;
925 }
926
927#ifndef WITHOUT_COMPLEX
928 case 'D': /* complex double */
929 {
930 va_arg(*p_va, Py_complex *);
931 break;
932 }
933#endif /* WITHOUT_COMPLEX */
934
935 case 'c': /* char */
936 {
937 va_arg(*p_va, char *);
938 break;
939 }
940
941 case 's': /* string */
942 {
943 va_arg(*p_va, char **);
944 if (*format == '#') {
945 va_arg(*p_va, int *);
946 format++;
947 }
948 break;
949 }
950
951 case 'z': /* string */
952 {
953 va_arg(*p_va, char **);
954 if (*format == '#') {
955 va_arg(*p_va, int *);
956 format++;
957 }
958 break;
959 }
960
961 case 'S': /* string object */
962 {
963 va_arg(*p_va, object **);
964 break;
965 }
966
967 case 'O': /* object */
968 {
969 typeobject *type;
970 object **p;
971 if (*format == '!') {
972 format++;
973 va_arg(*p_va, typeobject*);
974 va_arg(*p_va, object **);
975 }
976#if 0
977/* I don't know what this is for */
978 else if (*format == '?') {
979 inquiry pred = va_arg(*p_va, inquiry);
980 format++;
981 if ((*pred)(arg)) {
982 va_arg(*p_va, object **);
983 }
984 }
985#endif
986 else if (*format == '&') {
987 typedef int (*converter)
988 PROTO((object *, void *));
989 va_arg(*p_va, converter);
990 va_arg(*p_va, void *);
991 format++;
992 }
993 else {
994 va_arg(*p_va, object **);
995 }
996 break;
997 }
998
999 default:
1000 return "impossible<bad format char>";
1001
1002 }
1003
1004 *p_format = format;
1005 return NULL;
1006}