static int gettraceback(lua_State* l) { lua_checkstack(l, 5); char errormsg[2048] = ""; // obtain the error first: const char* p = lua_tostring(l, -1); if (p) { unsigned int i = strlen(p); if (i >= sizeof(errormsg)) {i = sizeof(errormsg)-1;} memcpy(errormsg, p, i); errormsg[i] = 0; } lua_pop(l, 1); // add a line break if we can if (strlen(errormsg) + strlen("\n") < sizeof(errormsg)) { strcat(errormsg, "\n"); } // call the original debug.traceback lua_pushstring(l, "debug_traceback_preserved"); lua_gettable(l, LUA_REGISTRYINDEX); if (lua_type(l, -1) != LUA_TFUNCTION) { // make sure it is valid // oops. char invaliddebugtraceback[] = "OOPS: The debug traceback " "couldn't be generated:\n" " Traceback function is not present or invalid (lua type is '"; if (strlen(errormsg) + strlen(invaliddebugtraceback) < sizeof(errormsg)) { strcat(errormsg, invaliddebugtraceback); } // clarify on the invalid type of the function (which is not a func): char typebuf[64] = ""; luatypetoname(lua_type(l, -1), typebuf, 16); strcat(typebuf, "')"); if (strlen(errormsg) + strlen(typebuf) < sizeof(errormsg)) { strcat(errormsg, typebuf); } // pop non-function: lua_pop(l, 1); // push error: lua_pushstring(l, errormsg); return 1; } lua_call(l, 0, 1); // add the traceback as much as we can p = lua_tostring(l, -1); if (p) { int len = strlen(p); if (strlen(errormsg) + len >= sizeof(errormsg)) { len = sizeof(errormsg) - strlen(errormsg) - 1; } if (len > 0) { int offset = strlen(errormsg); memcpy(errormsg + offset, p, len); errormsg[offset + len] = 0; } } lua_pop(l, 1); // pop traceback // push the whole result lua_pushstring(l, errormsg); return 1; }
const char* lua_strtype(lua_State* l, int stack) { int type = lua_type(l, stack); luatypetoname(type, strtypebuf, sizeof(strtypebuf)); return strtypebuf; }