
/* Module support implementation */

#include "Python.h"

#define FLAG_SIZE_T 1
typedef double va_double;

static PyObject *va_build_value(const char *, va_list, int);

/* Package context -- the full module name for package imports */
char *_Py_PackageContext = NULL;

/* Helper for mkvalue() to scan the length of a format */

static int
countformat(const char *format, int endchar)
{
	int count = 0;
	int level = 0;
	while (level > 0 || *format != endchar) {
		switch (*format) {
		case '\0':
			/* Premature end */
			PyErr_SetString(PyExc_SystemError,
					"unmatched paren in format");
			return -1;
		case '(':
		case '[':
		case '{':
			if (level == 0)
				count++;
			level++;
			break;
		case ')':
		case ']':
		case '}':
			level--;
			break;
		case '#':
		case '&':
		case ',':
		case ':':
		case ' ':
		case '\t':
			break;
		default:
			if (level == 0)
				count++;
		}
		format++;
	}
	return count;
}


/* Generic function to create a value -- the inverse of getargs() */
/* After an original idea and first implementation by Steven Miale */

static PyObject *do_mktuple(const char**, va_list *, int, int, int);
static PyObject *do_mklist(const char**, va_list *, int, int, int);
static PyObject *do_mkdict(const char**, va_list *, int, int, int);
static PyObject *do_mkvalue(const char**, va_list *, int);


static PyObject *
do_mkdict(const char **p_format, va_list *p_va, int endchar, int n, int flags)
{
	PyObject *d;
	int i;
	int itemfailed = 0;
	if (n < 0)
		return NULL;
	if ((d = PyDict_New()) == NULL)
		return NULL;
	/* Note that we can't bail immediately on error as this will leak
	   refcounts on any 'N' arguments. */
	for (i = 0; i < n; i+= 2) {
		PyObject *k, *v;
		int err;
		k = do_mkvalue(p_format, p_va, flags);
		if (k == NULL) {
			itemfailed = 1;
			Py_INCREF(Py_None);
			k = Py_None;
		}
		v = do_mkvalue(p_format, p_va, flags);
		if (v == NULL) {
			itemfailed = 1;
			Py_INCREF(Py_None);
			v = Py_None;
		}
		err = PyDict_SetItem(d, k, v);
		Py_DECREF(k);
		Py_DECREF(v);
		if (err < 0 || itemfailed) {
			Py_DECREF(d);
			return NULL;
		}
	}
	if (d != NULL && **p_format != endchar) {
		Py_DECREF(d);
		d = NULL;
		PyErr_SetString(PyExc_SystemError,
				"Unmatched paren in format");
	}
	else if (endchar)
		++*p_format;
	return d;
}

static PyObject *
do_mklist(const char **p_format, va_list *p_va, int endchar, int n, int flags)
{
	PyObject *v;
	int i;
	int itemfailed = 0;
	if (n < 0)
		return NULL;
	v = PyList_New(n);
	if (v == NULL)
		return NULL;
	/* Note that we can't bail immediately on error as this will leak
	   refcounts on any 'N' arguments. */
	for (i = 0; i < n; i++) {
		PyObject *w = do_mkvalue(p_format, p_va, flags);
		if (w == NULL) {
			itemfailed = 1;
			Py_INCREF(Py_None);
			w = Py_None;
		}
		PyList_SET_ITEM(v, i, w);
	}

	if (itemfailed) {
		/* do_mkvalue() should have already set an error */
		Py_DECREF(v);
		return NULL;
	}
	if (**p_format != endchar) {
		Py_DECREF(v);
		PyErr_SetString(PyExc_SystemError,
				"Unmatched paren in format");
		return NULL;
	}
	if (endchar)
		++*p_format;
	return v;
}

static int
_ustrlen(Py_UNICODE *u)
{
	int i = 0;
	Py_UNICODE *v = u;
	while (*v != 0) { i++; v++; } 
	return i;
}

static PyObject *
do_mktuple(const char **p_format, va_list *p_va, int endchar, int n, int flags)
{
	PyObject *v;
	int i;
	int itemfailed = 0;
	if (n < 0)
		return NULL;
	if ((v = PyTuple_New(n)) == NULL)
		return NULL;
	/* Note that we can't bail immediately on error as this will leak
	   refcounts on any 'N' arguments. */
	for (i = 0; i < n; i++) {
		PyObject *w = do_mkvalue(p_format, p_va, flags);
		if (w == NULL) {
			itemfailed = 1;
			Py_INCREF(Py_None);
			w = Py_None;
		}
		PyTuple_SET_ITEM(v, i, w);
	}
	if (itemfailed) {
		/* do_mkvalue() should have already set an error */
		Py_DECREF(v);
		return NULL;
	}
	if (**p_format != endchar) {
		Py_DECREF(v);
		PyErr_SetString(PyExc_SystemError,
				"Unmatched paren in format");
		return NULL;
	}
	if (endchar)
		++*p_format;
	return v;
}

static PyObject *
do_mkvalue(const char **p_format, va_list *p_va, int flags)
{
	for (;;) {
		switch (*(*p_format)++) {
		case '(':
			return do_mktuple(p_format, p_va, ')',
					  countformat(*p_format, ')'), flags);

		case '[':
			return do_mklist(p_format, p_va, ']',
					 countformat(*p_format, ']'), flags);

		case '{':
			return do_mkdict(p_format, p_va, '}',
					 countformat(*p_format, '}'), flags);

		case 'b':
		case 'B':
		case 'h':
		case 'i':
			return PyLong_FromLong((long)va_arg(*p_va, int));
			
		case 'H':
			return PyLong_FromLong((long)va_arg(*p_va, unsigned int));

		case 'I':
		{
			unsigned int n;
			n = va_arg(*p_va, unsigned int);
			return PyLong_FromUnsignedLong(n);
		}
		
		case 'n':
#if SIZEOF_SIZE_T!=SIZEOF_LONG
			return PyLong_FromSsize_t(va_arg(*p_va, Py_ssize_t));
#endif
			/* Fall through from 'n' to 'l' if Py_ssize_t is long */
		case 'l':
			return PyLong_FromLong(va_arg(*p_va, long));

		case 'k':
		{
			unsigned long n;
			n = va_arg(*p_va, unsigned long);
			return PyLong_FromUnsignedLong(n);
		}

#ifdef HAVE_LONG_LONG
		case 'L':
			return PyLong_FromLongLong((PY_LONG_LONG)va_arg(*p_va, PY_LONG_LONG));

		case 'K':
			return PyLong_FromUnsignedLongLong((PY_LONG_LONG)va_arg(*p_va, unsigned PY_LONG_LONG));
#endif
		case 'u':
		{
			PyObject *v;
			Py_UNICODE *u = va_arg(*p_va, Py_UNICODE *);
			Py_ssize_t n;	
			if (**p_format == '#') {
				++*p_format;
				if (flags & FLAG_SIZE_T)
					n = va_arg(*p_va, Py_ssize_t);
				else
					n = va_arg(*p_va, int);
			}
			else
				n = -1;
			if (u == NULL) {
				v = Py_None;
				Py_INCREF(v);
			}
			else {
				if (n < 0)
					n = _ustrlen(u);
				v = PyUnicode_FromUnicode(u, n);
			}
			return v;
		}
		case 'f':
		case 'd':
			return PyFloat_FromDouble(
				(double)va_arg(*p_va, va_double));

#ifndef WITHOUT_COMPLEX
		case 'D':
			return PyComplex_FromCComplex(
				*((Py_complex *)va_arg(*p_va, Py_complex *)));
#endif /* WITHOUT_COMPLEX */

		case 'c':
		{
			char p[1];
			p[0] = (char)va_arg(*p_va, int);
			return PyBytes_FromStringAndSize(p, 1);
		}
		case 'C':
		{
			int i = va_arg(*p_va, int);
			if (i < 0 || i > PyUnicode_GetMax()) {
				PyErr_SetString(PyExc_OverflowError,
				                "%c arg not in range(0x110000)");
				return NULL;
			}
			return PyUnicode_FromOrdinal(i);
		}

		case 's':
		case 'z':
		{
			PyObject *v;
			char *str = va_arg(*p_va, char *);
			Py_ssize_t n;
			if (**p_format == '#') {
				++*p_format;
				if (flags & FLAG_SIZE_T)
					n = va_arg(*p_va, Py_ssize_t);
				else
					n = va_arg(*p_va, int);
			}
			else
				n = -1;
			if (str == NULL) {
				v = Py_None;
				Py_INCREF(v);
			}
			else {
				if (n < 0) {
					size_t m = strlen(str);
					if (m > PY_SSIZE_T_MAX) {
						PyErr_SetString(PyExc_OverflowError,
							"string too long for Python string");
						return NULL;
					}
					n = (Py_ssize_t)m;
				}
				v = PyUnicode_FromStringAndSize(str, n);
			}
			return v;
		}

		case 'U':
		{
			PyObject *v;
			char *str = va_arg(*p_va, char *);
			Py_ssize_t n;
			if (**p_format == '#') {
				++*p_format;
				if (flags & FLAG_SIZE_T)
					n = va_arg(*p_va, Py_ssize_t);
				else
					n = va_arg(*p_va, int);
			}
			else
				n = -1;
			if (str == NULL) {
				v = Py_None;
				Py_INCREF(v);
			}
			else {
				if (n < 0) {
					size_t m = strlen(str);
					if (m > PY_SSIZE_T_MAX) {
						PyErr_SetString(PyExc_OverflowError,
							"string too long for Python string");
						return NULL;
					}
					n = (Py_ssize_t)m;
				}
				v = PyUnicode_FromStringAndSize(str, n);
			}
			return v;
		}

		case 'y':
		{
			PyObject *v;
			char *str = va_arg(*p_va, char *);
			Py_ssize_t n;
			if (**p_format == '#') {
				++*p_format;
				if (flags & FLAG_SIZE_T)
					n = va_arg(*p_va, Py_ssize_t);
				else
					n = va_arg(*p_va, int);
			}
			else
				n = -1;
			if (str == NULL) {
				v = Py_None;
				Py_INCREF(v);
			}
			else {
				if (n < 0) {
					size_t m = strlen(str);
					if (m > PY_SSIZE_T_MAX) {
						PyErr_SetString(PyExc_OverflowError,
							"string too long for Python bytes");
						return NULL;
					}
					n = (Py_ssize_t)m;
				}
				v = PyBytes_FromStringAndSize(str, n);
			}
			return v;
		}

		case 'N':
		case 'S':
		case 'O':
		if (**p_format == '&') {
			typedef PyObject *(*converter)(void *);
			converter func = va_arg(*p_va, converter);
			void *arg = va_arg(*p_va, void *);
			++*p_format;
			return (*func)(arg);
		}
		else {
			PyObject *v;
			v = va_arg(*p_va, PyObject *);
			if (v != NULL) {
				if (*(*p_format - 1) != 'N')
					Py_INCREF(v);
			}
			else if (!PyErr_Occurred())
				/* If a NULL was passed
				 * because a call that should
				 * have constructed a value
				 * failed, that's OK, and we
				 * pass the error on; but if
				 * no error occurred it's not
				 * clear that the caller knew
				 * what she was doing. */
				PyErr_SetString(PyExc_SystemError,
					"NULL object passed to Py_BuildValue");
			return v;
		}

		case ':':
		case ',':
		case ' ':
		case '\t':
			break;

		default:
			PyErr_SetString(PyExc_SystemError,
				"bad format char passed to Py_BuildValue");
			return NULL;

		}
	}
}


PyObject *
Py_BuildValue(const char *format, ...)
{
	va_list va;
	PyObject* retval;
	va_start(va, format);
	retval = va_build_value(format, va, 0);
	va_end(va);
	return retval;
}

PyObject *
_Py_BuildValue_SizeT(const char *format, ...)
{
	va_list va;
	PyObject* retval;
	va_start(va, format);
	retval = va_build_value(format, va, FLAG_SIZE_T);
	va_end(va);
	return retval;
}

PyObject *
Py_VaBuildValue(const char *format, va_list va)
{
	return va_build_value(format, va, 0);
}

PyObject *
_Py_VaBuildValue_SizeT(const char *format, va_list va)
{
	return va_build_value(format, va, FLAG_SIZE_T);
}

static PyObject *
va_build_value(const char *format, va_list va, int flags)
{
	const char *f = format;
	int n = countformat(f, '\0');
	va_list lva;

#ifdef VA_LIST_IS_ARRAY
	memcpy(lva, va, sizeof(va_list));
#else
#ifdef __va_copy
	__va_copy(lva, va);
#else
	lva = va;
#endif
#endif

	if (n < 0)
		return NULL;
	if (n == 0) {
		Py_INCREF(Py_None);
		return Py_None;
	}
	if (n == 1)
		return do_mkvalue(&f, &lva, flags);
	return do_mktuple(&f, &lva, '\0', n, flags);
}


PyObject *
PyEval_CallFunction(PyObject *obj, const char *format, ...)
{
	va_list vargs;
	PyObject *args;
	PyObject *res;

	va_start(vargs, format);

	args = Py_VaBuildValue(format, vargs);
	va_end(vargs);

	if (args == NULL)
		return NULL;

	res = PyEval_CallObject(obj, args);
	Py_DECREF(args);

	return res;
}


PyObject *
PyEval_CallMethod(PyObject *obj, const char *methodname, const char *format, ...)
{
	va_list vargs;
	PyObject *meth;
	PyObject *args;
	PyObject *res;

	meth = PyObject_GetAttrString(obj, methodname);
	if (meth == NULL)
		return NULL;

	va_start(vargs, format);

	args = Py_VaBuildValue(format, vargs);
	va_end(vargs);

	if (args == NULL) {
		Py_DECREF(meth);
		return NULL;
	}

	res = PyEval_CallObject(meth, args);
	Py_DECREF(meth);
	Py_DECREF(args);

	return res;
}

int
PyModule_AddObject(PyObject *m, const char *name, PyObject *o)
{
	PyObject *dict;
	if (!PyModule_Check(m)) {
		PyErr_SetString(PyExc_TypeError,
			    "PyModule_AddObject() needs module as first arg");
		return -1;
	}
	if (!o) {
		if (!PyErr_Occurred())
			PyErr_SetString(PyExc_TypeError,
					"PyModule_AddObject() needs non-NULL value");
		return -1;
	}

	dict = PyModule_GetDict(m);
	if (dict == NULL) {
		/* Internal error -- modules must have a dict! */
		PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__",
			     PyModule_GetName(m));
		return -1;
	}
	if (PyDict_SetItemString(dict, name, o))
		return -1;
	Py_DECREF(o);
	return 0;
}

int 
PyModule_AddIntConstant(PyObject *m, const char *name, long value)
{
	PyObject *o = PyLong_FromLong(value);
	if (!o)
		return -1;
	if (PyModule_AddObject(m, name, o) == 0)
		return 0;
	Py_DECREF(o);
	return -1;
}

int 
PyModule_AddStringConstant(PyObject *m, const char *name, const char *value)
{
	PyObject *o = PyUnicode_FromString(value);
	if (!o)
		return -1;
	if (PyModule_AddObject(m, name, o) == 0)
		return 0;
	Py_DECREF(o);
	return -1;
}
