static int _p_object_newindex_set(lua_State *L, py_object *obj, int keyn, int valuen) { PyObject *value; PyObject *key = LuaConvert(L, keyn); if (!key) { return luaL_argerror(L, 1, "failed to convert key"); } if (!lua_isnil(L, valuen)) { value = LuaConvert(L, valuen); if (!value) { Py_DECREF(key); return luaL_argerror(L, 1, "failed to convert value"); } if (PyObject_SetItem(obj->o, key, value) == -1) { PyErr_Print(); luaL_error(L, "failed to set item"); } Py_DECREF(value); } else { if (PyObject_DelItem(obj->o, key) == -1) { PyErr_Print(); luaL_error(L, "failed to delete item"); } } Py_DECREF(key); return 0; }
static int _p_object_newindex_set(lua_State *L, py_object *obj, int keyn, int valuen) { PyObject *value; PyObject *key = LuaConvert(L, keyn); if (!key) luaL_argerror(L, 1, "failed to convert key"); lua_Object lobj = lua_getparam(L, valuen); if (!lua_isnil(L, lobj)) { value = LuaConvert(L, valuen); if (!value) { Py_DECREF(key); luaL_argerror(L, 1, "failed to convert value"); } // setitem (obj[0] = 1) if int else setattr(obj.val = 1) if (obj->asindx) { if (PyObject_SetItem(obj->o, key, value) == -1) { PyErr_Print(); lua_error(L, "failed to set item"); } } else if (PyObject_SetAttr(obj->o, key, value) == -1) { PyErr_Print(); lua_error(L, "failed to set item"); } Py_DECREF(value); } else { if (PyObject_DelItem(obj->o, key) == -1) { PyErr_Print(); lua_error(L, "failed to delete item"); } } Py_DECREF(key); return 0; }
PyObject* convertDictFromTable(lua_State* L, int index) { if (lua_type(L, index) != LUA_TTABLE) { luaL_error(L, "must be table"); } PyObject *obj = PyDict_New(); if(!obj) { luaL_error(L, "convertDictFromTable"); } Py_INCREF(obj); lua_pushnil(L); while (lua_next(L, index) != 0) { // key at index -2, value at index -1 // Python can't use arbitrary types as dict keys; only allow numbers // and strings. Also, if you use float keys, you're insane. PyObject *key = LuaConvert(L, -2); PyObject *value = LuaConvert(L, -1); if (value) { PyDict_SetItem(obj, key, value); } lua_pop(L, 1); // keep key for next iteration } return obj; }
static int py_object_newindex(lua_State *L) { py_object *obj = (py_object*) luaL_checkudata(L, 1, POBJECT); const char *attr; PyObject *value; if (!obj) { return luaL_argerror(L, 1, "not a python object"); } if (obj->asindx) return _p_object_newindex_set(L, obj, 2, 3); attr = luaL_checkstring(L, 2); if (!attr) { return luaL_argerror(L, 2, "string needed"); } value = LuaConvert(L, 3); if (!value) { return luaL_argerror(L, 1, "failed to convert value"); } if (PyObject_SetAttrString(obj->o, (char*)attr, value) == -1) { Py_DECREF(value); PyErr_Print(); return luaL_error(L, "failed to set value"); } Py_DECREF(value); return 0; }
static int _p_object_index_get(lua_State *L, py_object *obj, int keyn) { PyObject *key = LuaConvert(L, keyn); PyObject *item; int ret = 0; if (!key) { luaL_argerror(L, 1, "failed to convert key"); return 0; } item = PyObject_GetItem(obj->o, key); Py_DECREF(key); if (item) { ret = py_convert(L, item, 0); Py_DECREF(item); } else { PyErr_Clear(); if (lua_gettop(L) > keyn) { lua_pushvalue(L, keyn+1); ret = 1; } } return ret; }
static void py_object_newindex(lua_State *L) { py_object *obj = get_py_object(L, 1); const char *attr; PyObject *value; if (!obj) { luaL_argerror(L, 1, "not a python object"); } if (obj->asindx) { _p_object_newindex_set(L, obj, 2, 3); return; } attr = luaL_check_string(L, 2); if (!attr) { luaL_argerror(L, 2, "string needed"); } value = LuaConvert(L, 3); if (!value) { luaL_argerror(L, 1, "failed to convert value"); } if (PyObject_SetAttrString(obj->o, (char *) attr, value) == -1) { Py_DECREF(value); PyErr_Print(); lua_error(L, "failed to set value"); } Py_DECREF(value); }
static PyObject *LuaObject_getattr(PyObject *obj, PyObject *attr) { PyObject *ret; int rc; lua_rawgeti(LuaState, LUA_REGISTRYINDEX, ((LuaObject*)obj)->ref); if (lua_isnil(LuaState, -1)) { lua_pop(LuaState, 1); PyErr_SetString(PyExc_RuntimeError, "lost reference"); return NULL; } if (!lua_isstring(LuaState, -1) && !lua_istable(LuaState, -1) && !lua_isuserdata(LuaState, -1)) { lua_pop(LuaState, 1); PyErr_SetString(PyExc_RuntimeError, "not an indexable value"); return NULL; } ret = NULL; rc = py_convert(LuaState, attr, 0); if (rc) { lua_gettable(LuaState, -2); ret = LuaConvert(LuaState, -1); } else { PyErr_SetString(PyExc_ValueError, "can't convert attr/key"); } lua_settop(LuaState, 0); return ret; }
static PyObject *LuaObject_iternext(LuaObject *obj) { PyObject *ret = NULL; lua_rawgeti(LuaState, LUA_REGISTRYINDEX, ((LuaObject*)obj)->ref); if (obj->refiter == 0) lua_pushnil(LuaState); else lua_rawgeti(LuaState, LUA_REGISTRYINDEX, obj->refiter); if (lua_next(LuaState, -2) != 0) { /* Remove value. */ lua_pop(LuaState, 1); ret = LuaConvert(LuaState, -1); /* Save key for next iteration. */ if (!obj->refiter) obj->refiter = luaL_ref(LuaState, LUA_REGISTRYINDEX); else lua_rawseti(LuaState, LUA_REGISTRYINDEX, obj->refiter); } else if (obj->refiter) { luaL_unref(LuaState, LUA_REGISTRYINDEX, obj->refiter); obj->refiter = 0; } return ret; }
static int _p_object_index_get(lua_State *L, py_object *pobj, int keyn) { PyObject *key = LuaConvert(L, keyn); PyObject *item; int ret = 0; if (!key) luaL_argerror(L, 1, "failed to convert key"); if (pobj->asindx) { item = PyObject_GetItem(pobj->o, key); } else { item = PyObject_GetAttr(pobj->o, key); } Py_DECREF(key); if (item) { ret = py_convert(L, item); Py_DECREF(item); } else { PyErr_Clear(); char *keystr = get_pyobject_repr(L, key); char *error = "%s \"%s\" not found"; char *name = pobj->asindx ? "index or key" : "attribute"; char buff[strlen(error) + strlen(name) + strlen(keystr) + 1]; sprintf(buff, error, name, keystr); lua_error(L, &buff[0]); } return ret; }
static void py_object_call(lua_State *L) { py_object *pobj = get_py_object(L, 1); PyObject *args; PyObject *value; int nargs = lua_gettop(L)-1; int i; if (!pobj) { luaL_argerror(L, 1, "not a python object"); } if (!PyCallable_Check(pobj->o)) { lua_error(L, "object is not callable"); } args = PyTuple_New(nargs); if (!args) { PyErr_Print(); lua_error(L, "failed to create arguments tuple"); } for (i = 0; i != nargs; i++) { PyObject *arg = LuaConvert(L, i + 2); if (!arg) { Py_DECREF(args); char *error = "failed to convert argument #%d"; char buff[strlen(error) + 10]; sprintf(buff, error, i + 1); lua_error(L, &buff[0]); } PyTuple_SetItem(args, i, arg); } value = PyObject_CallObject(pobj->o, args); if (value) { py_convert(L, value); Py_DECREF(value); } else { PyErr_Print(); char *name = get_pyobject_repr(L, pobj->o); char *error = "error calling python function \"%s\""; char buff[strlen(error) + strlen(name) + strlen(name) + 1]; sprintf(buff, error, name); lua_error(L, &buff[0]); } free(pobj); }
PyObject *Lua_globals(PyObject *self, PyObject *args) { PyObject *ret = NULL; lua_getglobal(LuaState, "_G"); if (lua_isnil(LuaState, -1)) { PyErr_SetString(PyExc_RuntimeError, "lost globals reference"); lua_pop(LuaState, 1); return NULL; } ret = LuaConvert(LuaState, -1); if (!ret) PyErr_Format(PyExc_TypeError, "failed to convert globals table"); lua_settop(LuaState, 0); return ret; }
static int py_object_call(lua_State *L) { py_object *obj = (py_object*) luaL_checkudata(L, 1, POBJECT); PyObject *args; PyObject *value; int nargs = lua_gettop(L)-1; int ret = 0; int i; if (!obj) { luaL_argerror(L, 1, "not a python object"); return 0; } if (!PyCallable_Check(obj->o)) { luaL_error(L, "object is not callable"); return 0; } args = PyTuple_New(nargs); if (!args) { PyErr_Print(); luaL_error(L, "failed to create arguments tuple"); return 0; } for (i = 0; i != nargs; i++) { PyObject *arg = LuaConvert(L, i+2); if (!arg) { luaL_error(L, "failed to convert argument #%d", i+1); Py_DECREF(args); return 0; } PyTuple_SetItem(args, i, arg); } value = PyObject_CallObject(obj->o, args); if (value) { ret = py_convert(L, value, 0); Py_DECREF(value); } else { PyErr_Print(); luaL_error(L, "error calling python function"); } return ret; }
PyObject *Lua_globals(PyObject *self, PyObject *args) { PyObject *ret = NULL; lua_pushliteral(L, "_G"); lua_rawget(L, LUA_GLOBALSINDEX); if (lua_isnil(L, -1)) { PyErr_SetString(PyExc_RuntimeError, "lost globals reference"); lua_pop(L, 1); return NULL; } ret = LuaConvert(L, -1); if (!ret) PyErr_Format(PyExc_TypeError, "failed to convert globals table"); lua_settop(L, 0); return ret; }
static PyObject *LuaObject_getattr(PyObject *obj, PyObject *attr) { PyObject *ret = NULL; int rc; lua_rawgeti(L, LUA_REGISTRYINDEX, ((LuaObject*)obj)->ref); if (lua_isnil(L, -1)) { PyErr_SetString(PyExc_RuntimeError, "lost reference"); goto error; } rc = e_py_convert(L, attr, 0); if (rc) { TRY { lua_gettable(L, -2); } CATCH { goto error; } ENDTRY; ret = LuaConvert(L, -1); } else {
static PyObject *Lua_to_table(PyObject *self, PyObject *args) { if (!PyTuple_Check(args)) { PyErr_SetString(PyExc_TypeError, "tuple expected"); lua_settop(LuaState, 0); return NULL; } PyObject *obj = PyTuple_GetItem(args, 0); if (PyDict_Check(obj)) { lua_newtable(LuaState); Py_ssize_t pos = 0; PyObject* key = NULL; PyObject* value = NULL; // key, value are borrowed while (PyDict_Next(obj, &pos, &key, &value)) { if (!key) { luaL_error(LuaState, "retrieve dictionary key"); } if (!value) { luaL_error(LuaState, "retrieve dictionary value"); } Py_INCREF(key); Py_INCREF(value); py_convert(LuaState, key, 0); py_convert(LuaState, value, 0); lua_rawset(LuaState, -3); } return LuaConvert(LuaState, -1); } PyErr_SetString(PyExc_TypeError, "dictionary expected"); lua_settop(LuaState, 0); return NULL; }
PyObject *Lua_run(PyObject *args, int eval) { PyObject *ret; char *buf = NULL; char *s; int len; if (!PyArg_ParseTuple(args, "s#", &s, &len)) return NULL; if (eval) { buf = (char *) malloc(strlen("return ")+len+1); strcpy(buf, "return "); strncat(buf, s, len); s = buf; len = strlen("return ")+len; } if (luaL_loadbuffer(LuaState, s, len, "<python>") != 0) { PyErr_Format(PyExc_RuntimeError, "error loading code: %s", lua_tostring(LuaState, -1)); return NULL; } free(buf); if (lua_pcall(LuaState, 0, 1, 0) != 0) { PyErr_Format(PyExc_RuntimeError, "error executing code: %s", lua_tostring(LuaState, -1)); return NULL; } ret = LuaConvert(LuaState, -1); lua_settop(LuaState, 0); return ret; }
static PyObject *LuaCall(lua_State *L, PyObject *args) { PyObject *ret = NULL; PyObject *arg; int nargs, rc, i; if (!PyTuple_Check(args)) { PyErr_SetString(PyExc_TypeError, "tuple expected"); lua_settop(L, 0); return NULL; } nargs = PyTuple_Size(args); for (i = 0; i != nargs; i++) { arg = PyTuple_GetItem(args, i); if (arg == NULL) { PyErr_Format(PyExc_TypeError, "failed to get tuple item #%d", i); lua_settop(L, 0); return NULL; } rc = py_convert(L, arg, 0); if (!rc) { PyErr_Format(PyExc_TypeError, "failed to convert argument #%d", i); lua_settop(L, 0); return NULL; } } if (lua_pcall(L, nargs, LUA_MULTRET, 0) != 0) { PyErr_Format(PyExc_Exception, "error: %s", lua_tostring(L, -1)); return NULL; } nargs = lua_gettop(L); if (nargs == 1) { ret = LuaConvert(L, 1); if (!ret) { PyErr_SetString(PyExc_TypeError, "failed to convert return"); lua_settop(L, 0); Py_DECREF(ret); return NULL; } } else if (nargs > 1) { ret = PyTuple_New(nargs); if (!ret) { PyErr_SetString(PyExc_RuntimeError, "failed to create return tuple"); lua_settop(L, 0); return NULL; } for (i = 0; i != nargs; i++) { arg = LuaConvert(L, i+1); if (!arg) { PyErr_Format(PyExc_TypeError, "failed to convert return #%d", i); lua_settop(L, 0); Py_DECREF(ret); return NULL; } PyTuple_SetItem(ret, i, arg); } } else { Py_INCREF(Py_None); ret = Py_None; } lua_settop(L, 0); return ret; }
static PyObject *LuaCall(LuaStateObject *state, PyObject *args) { PyObject *ret = NULL; PyObject *arg; int nargs, rc, i; assert(PyTuple_Check(args)); /* Note: Convert tuple length from 64-bit to 32-bit */ nargs = (int)PyTuple_Size(args); for (i = 0; i != nargs; i++) { arg = PyTuple_GetItem(args, i); if (arg == NULL) { PyErr_Format(PyExc_TypeError, "failed to get tuple item #%d", i); lua_settop(state->LuaState, 0); return NULL; } rc = e_py_convert(state->LuaState, arg, 0); if (!rc) { PyErr_Format(PyExc_TypeError, "failed to convert argument #%d", i); lua_settop(state->LuaState, 0); return NULL; } } if (lua_pcall(state->LuaState, nargs, LUA_MULTRET, 0) != 0) { PyErr_Format(PyExc_Exception, "error: %s", lua_tostring(state->LuaState, -1)); return NULL; } nargs = lua_gettop(state->LuaState); if (nargs == 1) { ret = LuaConvert(state, 1); if (!ret) { PyErr_SetString(PyExc_TypeError, "failed to convert return"); lua_settop(state->LuaState, 0); return NULL; } } else if (nargs > 1) { ret = PyTuple_New(nargs); if (!ret) { PyErr_SetString(PyExc_RuntimeError, "failed to create return tuple"); lua_settop(state->LuaState, 0); return NULL; } for (i = 0; i != nargs; i++) { arg = LuaConvert(state, i+1); if (!arg) { PyErr_Format(PyExc_TypeError, "failed to convert return #%d", i); lua_settop(state->LuaState, 0); Py_DECREF(ret); return NULL; } PyTuple_SetItem(ret, i, arg); } } else { Py_INCREF(Py_None); ret = Py_None; } lua_settop(state->LuaState, 0); return ret; }