From 94de650f41d82079703bf0bb37fa30527008c9e8 Mon Sep 17 00:00:00 2001 From: Al Riddoch Date: Tue, 15 Aug 2006 15:38:29 +0000 Subject: [PATCH] 2006-08-15 Al Riddoch * rulesets/Python_API.cpp: In Python Entity constructor, tighten up checks so exceptions are thrown for initialisers of the wrong type. Convert xyz sequence more directly to C++ vector for efficiency. --- ChangeLog | 7 +++++ rulesets/Python_API.cpp | 61 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 895d273ee..dd5e3419e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2006-08-15 Al Riddoch + + * rulesets/Python_API.cpp: In Python Entity constructor, tighten + up checks so exceptions are thrown for initialisers of the wrong + type. Convert xyz sequence more directly to C++ vector for + efficiency. + 2006-08-15 Al Riddoch * rulesets/Py_Object.cpp: Avoid calling python list length diff --git a/rulesets/Python_API.cpp b/rulesets/Python_API.cpp index 871acaf04..086cdc23b 100644 --- a/rulesets/Python_API.cpp +++ b/rulesets/Python_API.cpp @@ -679,6 +679,42 @@ static PyObject * oplist_new(PyObject * self, PyObject * args) return (PyObject *)o; } +static int PySequence_asVector(PyObject * o, std::vector & ret) +{ + int len; + PyObject * item; + if (PyList_Check(o)) { + len = PyList_Size(o); + ret.resize(len); + for(int i = 0; i < len; i++) { + item = PyList_GetItem(o, i); + if (PyFloat_Check(item)) { + ret[i] = PyFloat_AsDouble(item); + } else if (PyInt_Check(item)) { + ret[i] = PyInt_AsLong(item); + } else { + return -1; + } + } + } else if (PyTuple_Check(o)) { + len = PyTuple_Size(o); + ret.resize(len); + for(int i = 0; i < len; i++) { + item = PyTuple_GetItem(o, i); + if (PyFloat_Check(item)) { + ret[i] = PyFloat_AsDouble(item); + } else if (PyInt_Check(item)) { + ret[i] = PyInt_AsLong(item); + } else { + return -1; + } + } + } else { + return -1; + } + return 0; +} + static PyObject * entity_new(PyObject * self, PyObject * args, PyObject * kwds) { char * id = NULL; @@ -701,14 +737,31 @@ static PyObject * entity_new(PyObject * self, PyObject * args, PyObject * kwds) for(i = 0; i < size; i++) { char * key = PyString_AsString(PyList_GetItem(keys, i)); PyObject * val = PyList_GetItem(vals, i); - if ((strcmp(key, "location") == 0) && (PyLocation_Check(val))) { + if (strcmp(key, "location") == 0) { + if (!PyLocation_Check(val)) { + PyErr_SetString(PyExc_TypeError, "location must be a Location object"); + return NULL; + } PyLocation * loc = (PyLocation*)val; loc->location->addToEntity(ent); } else if (strcmp(key, "xyz") == 0) { - ent->setAttr("pos", PyObject_asMessageElement(val)); - } else if ((strcmp(key, "parent") == 0) && (PyString_Check(val))) { + std::vector vector_val; + if (PySequence_asVector(val, vector_val) != 0) { + PyErr_SetString(PyExc_TypeError, "xyz must be a number sequence."); + return NULL; + } + ent->setPos(vector_val); + } else if (strcmp(key, "parent") == 0) { + if (!PyString_Check(val)) { + PyErr_SetString(PyExc_TypeError, "parent must be a string."); + return NULL; + } ent->setLoc(PyString_AsString(val)); - } else if ((strcmp(key, "type") == 0) && (PyString_Check(val))) { + } else if (strcmp(key, "type") == 0) { + if (!PyString_Check(val)) { + PyErr_SetString(PyExc_TypeError, "type must be a string."); + return NULL; + } ent->setParents(std::list(1, PyString_AsString(val))); ent->setObjtype("obj"); } else {