Beispiel #1
0
static int
vgetargs1(PyObject *args, char *format, va_list *p_va, int compat)
{
	char msgbuf[256];
	int levels[32];
	char *fname = NULL;
	char *message = NULL;
	int min = -1;
	int max = 0;
	int level = 0;
	int endfmt = 0;
	char *formatsave = format;
	int i, len;
	char *msg;
	PyObject *freelist = NULL;
	
	assert(compat || (args != (PyObject*)NULL));

	while (endfmt == 0) {
		int c = *format++;
		switch (c) {
		case '(':
			if (level == 0)
				max++;
			level++;
			break;
		case ')':
			if (level == 0)
				Py_FatalError("excess ')' in getargs format");
			else
				level--;
			break;
		case '\0':
			endfmt = 1;
			break;
		case ':':
			fname = format;
			endfmt = 1;
			break;
		case ';':
			message = format;
			endfmt = 1;
			break;
		default:
			if (level == 0) {
				if (c == 'O')
					max++;
				else if (isalpha(c)) {
					if (c != 'e') /* skip encoded */
						max++;
				} else if (c == '|')
					min = max;
			}
			break;
		}
	}
	
	if (level != 0)
	Py_FatalError(/* '(' */ "missing ')' in getargs format");
	
	if (min < 0)
		min = max;
	
	format = formatsave;
	
	if (compat) {
		if (max == 0) {
			if (args == NULL)
				return 1;
			PyOS_snprintf(msgbuf, sizeof(msgbuf),
				      "%.200s%s takes no arguments",
				      fname==NULL ? "function" : fname,
				      fname==NULL ? "" : "()");
			PyErr_SetString(PyExc_TypeError, msgbuf);
			return 0;
		}
		else if (min == 1 && max == 1) {
			if (args == NULL) {
				PyOS_snprintf(msgbuf, sizeof(msgbuf),
				      "%.200s%s takes at least one argument",
					      fname==NULL ? "function" : fname,
					      fname==NULL ? "" : "()");
				PyErr_SetString(PyExc_TypeError, msgbuf);
				return 0;
			}
			msg = convertitem(args, &format, p_va, levels, msgbuf,
					  sizeof(msgbuf), &freelist);
			if (msg == NULL)
				return cleanreturn(1, freelist);
			seterror(levels[0], msg, levels+1, fname, message);
			return cleanreturn(0, freelist);
		}
		else {
			PyErr_SetString(PyExc_SystemError,
			    "old style getargs format uses new features");
			return 0;
		}
	}
	
	if (!PyTuple_Check(args)) {
		PyErr_SetString(PyExc_SystemError,
		    "new style getargs format but argument is not a tuple");
		return 0;
	}
	
	len = PyTuple_GET_SIZE(args);
	
	if (len < min || max < len) {
		if (message == NULL) {
			PyOS_snprintf(msgbuf, sizeof(msgbuf),
				      "%.150s%s takes %s %d argument%s "
				      "(%d given)",
				      fname==NULL ? "function" : fname,
				      fname==NULL ? "" : "()",
				      min==max ? "exactly"
				      : len < min ? "at least" : "at most",
				      len < min ? min : max,
				      (len < min ? min : max) == 1 ? "" : "s",
				      len);
			message = msgbuf;
		}
		PyErr_SetString(PyExc_TypeError, message);
		return 0;
	}
	
	for (i = 0; i < len; i++) {
		if (*format == '|')
			format++;
		msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va,
				  levels, msgbuf, sizeof(msgbuf), &freelist);
		if (msg) {
			seterror(i+1, msg, levels, fname, message);
			return cleanreturn(0, freelist);
		}
	}

	if (*format != '\0' && !isalpha((int)(*format)) &&
	    *format != '(' &&
	    *format != '|' && *format != ':' && *format != ';') {
		PyErr_Format(PyExc_SystemError,
			     "bad format string: %.200s", formatsave);
		return cleanreturn(0, freelist);
	}
	
	return cleanreturn(1, freelist);
}
Beispiel #2
0
static int
vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
{
	//puts("vgetargs1");
	//puts(format);
	char msgbuf[256];
	int levels[32];
	const char *fname = NULL;
	const char *message = NULL;
	int min = -1;
	int max = 0;
	int level = 0;
	int endfmt = 0;
	const char *formatsave = format;
	Py_ssize_t i, len;
	char *msg;
	PyObject *freelist = NULL;
	int compat = flags & FLAG_COMPAT;

	if (args == (PyObject*)NULL) jputs("vgetargs1 call with NULL-args");
	assert(compat || (args != (PyObject*)NULL));
	flags = flags & ~FLAG_COMPAT;

	while (endfmt == 0) {
		int c = *format++;
		//printf("process char: %c\n", c);
		switch (c) {
		case '(':
			if (level == 0)
				max++;
			level++;
			if (level >= 30)
				Py_FatalError("too many tuple nesting levels "
							  "in argument format string");
			break;
		case ')':
			if (level == 0)
				Py_FatalError("excess ')' in getargs format");
			else
				level--;
			break;
		case '\0':
			endfmt = 1;
			break;
		case ':':
			fname = format;
			//puts("fname:");
			//puts(fname);
			endfmt = 1;
			break;
		case ';':
			message = format;
			endfmt = 1;
			break;
		default:
			if (level == 0) {
				if (c == 'O')
					max++;
				else if (isalpha(Py_CHARMASK(c))) {
					if (c != 'e') /* skip encoded */
						max++;
				} else if (c == '|')
					min = max;
			}
			break;
		}
	}
	//puts("format processed");
	if (level != 0)
		Py_FatalError(/* '(' */ "missing ')' in getargs format");
	//puts("a");
	if (min < 0)
		min = max;

	format = formatsave;

	if (compat) {
		//puts("compat");
		if (max == 0) {
			if (args == NULL)
				return 1;
			PyOS_snprintf(msgbuf, sizeof(msgbuf),
						  "%.200s%s takes no arguments",
						  fname==NULL ? "function" : fname,
						  fname==NULL ? "" : "()");
			PyErr_SetString(PyExc_TypeError, msgbuf);
			return 0;
		}
		else if (min == 1 && max == 1) {
			if (args == NULL) {
				PyOS_snprintf(msgbuf, sizeof(msgbuf),
					  "%.200s%s takes at least one argument",
						  fname==NULL ? "function" : fname,
						  fname==NULL ? "" : "()");
				PyErr_SetString(PyExc_TypeError, msgbuf);
				return 0;
			}
			msg = convertitem(args, &format, p_va, flags, levels,
							  msgbuf, sizeof(msgbuf), &freelist);
			if (msg == NULL)
				return cleanreturn(1, freelist);
			seterror(levels[0], msg, levels+1, fname, message);
			return cleanreturn(0, freelist);
		}
		else {
			PyErr_SetString(PyExc_SystemError,
				"old style getargs format uses new features");
			return 0;
		}
	}
	//puts("compat done");
	if (!PyTuple_Check(args)) {
		PyErr_SetString(PyExc_SystemError,
			"new style getargs format but argument is not a tuple");
		return 0;
	}

	len = PyTuple_GET_SIZE(args);

	if (len < min || max < len) {
		if (message == NULL) {
			PyOS_snprintf(msgbuf, sizeof(msgbuf),
						  "%.150s%s takes %s %d argument%s "
						  "(%ld given)",
						  fname==NULL ? "function" : fname,
						  fname==NULL ? "" : "()",
						  min==max ? "exactly"
						  : len < min ? "at least" : "at most",
						  len < min ? min : max,
						  (len < min ? min : max) == 1 ? "" : "s",
						  Py_SAFE_DOWNCAST(len, Py_ssize_t, long));
			message = msgbuf;
		}

		PyErr_SetString(PyExc_TypeError, message);
		return 0;
	}