diff Python/getargs.c @ 20711:2890769b1e69 legacy-trunk

PyArg_ParseTupleAndKeywords: return false on internal error, not -1 (I introduced this bug just a little while ago, when *adding* internal error checks). vgetargskeywords: Rewrote the section that crawls over the format string. + Added block comment so it won't take the next person 15 minutes to reverse-engineer what it's doing. + Lined up the "else" clauses. + Rearranged the ifs in decreasing order of likelihood (for speed).
author Tim Peters <tim.peters@gmail.com>
date Sat, 27 Oct 2001 04:26:57 +0000
parents a44cc0c21cfe
children a6a4bd2f06d0
line wrap: on
line diff
--- a/Python/getargs.c	Sat Oct 27 03:58:40 2001 +0000
+++ b/Python/getargs.c	Sat Oct 27 04:26:57 2001 +0000
@@ -997,6 +997,7 @@
 /* Support for keyword arguments donated by
    Geoff Philbrick <philbric@delphi.hks.com> */
 
+/* Return false (0) for error, else true. */
 int
 PyArg_ParseTupleAndKeywords(PyObject *args,
 			    PyObject *keywords,
@@ -1012,7 +1013,7 @@
 	    kwlist == NULL)
 	{
 		PyErr_BadInternalCall();
-		return -1;
+		return 0;
 	}
 
 	va_start(va, kwlist);
@@ -1028,10 +1029,8 @@
 {
 	char msgbuf[256];
 	int levels[32];
-	char *fname = NULL;
-	char *message = NULL;
-	int min = -1;
-	int max = 0;
+	char *fname, *message;
+	int min, max;
 	char *formatsave = format;
 	int i, len, tplen, kwlen;
 	char *msg, *ks, **p;
@@ -1044,44 +1043,49 @@
 	assert(kwlist != NULL);
 	assert(p_va != NULL);
 
-	/* nested tuples cannot be parsed when using keyword arguments */
-
-	for (;;) {
-		int c = *format++;
-		if (c == '(') {
+	/* Search the format:
+	   message <- error msg, if any (else NULL).
+	   name <- routine name, if any (else NULL).
+	   min <- # of required arguments, or -1 if all are required.
+	   max <- most arguments (required + optional).
+	   Raise error if a tuple arg spec is found.
+	*/
+	fname = message = NULL;
+	min = -1;
+	max = 0;
+	while ((i = *format++) != '\0') {
+		if (isalpha(i) && i != 'e')
+			max++;
+		else if (i == '|')
+			min = max;
+		else if (i == ':') {
+			fname = format;
+			break;
+		}
+		else if (i == ';') {
+			message = format;
+			break;
+		}
+		else if (i == '(') {
 			PyErr_SetString(PyExc_SystemError,
 		      "tuple found in format when using keyword arguments");
 			return 0;
 		}
-		else if (c == '\0')
-			break;
-		else if (c == ':') {
-			fname = format;
-			break;
-		} else if (c == ';') {
-			message = format;
-			break;
-		} else if (c == 'e')
-			; /* Pass */
-		else if (isalpha(c))
-			max++;
-		else if (c == '|')
-			min = max;
 	}	
-	
-	if (min < 0)
+	if (min < 0) {
+		/* All arguments are required. */
 		min = max;
-	
+	}
 	format = formatsave;
-	
+
 	if (!PyTuple_Check(args)) {
 		PyErr_SetString(PyExc_SystemError,
 		    "new style getargs format but argument is not a tuple");
 		return 0;
 	}	
-	
+
 	tplen = PyTuple_GET_SIZE(args);
-	
+
 	/* do a cursory check of the keywords just to see how many we got */
 
 	kwlen = 0;