+
+ if(luabotnick) {
+ freesstring(luabotnick);
+ luabotnick = NULL;
+ }
+}
+
+int _lua_vpcall(lua_State *l, void *function, int mode, const char *sig, ...) {
+ va_list va;
+ int narg = 0, nres, top = lua_gettop(l);
+
+ lua_getglobal(l, "scripterror");
+ if(mode == LUA_CHARMODE) {
+ lua_getglobal(l, (const char *)function);
+ } else {
+ lua_rawgeti(l, LUA_REGISTRYINDEX, (long)function);
+ }
+
+ if(!lua_isfunction(l, -1)) {
+ lua_settop(l, top);
+ return 1;
+ }
+
+ va_start(va, sig);
+
+ while(*sig) {
+ switch(*sig++) {
+ case 'i':
+ lua_pushint(l, va_arg(va, int));
+ break;
+ case 'l':
+ lua_pushlong(l, va_arg(va, long));
+ break;
+ case 's':
+ lua_pushstring(l, va_arg(va, char *));
+ break;
+ case 'S':
+ lua_pushstring(l, ((sstring *)(va_arg(va, sstring *)))->content);
+ break;
+ case 'L': /* BE VERY CAREFUL USING THIS, MAKE SURE YOU CAST THE VALUE TO LONG */
+ {
+ char *p = va_arg(va, char *);
+ long len = va_arg(va, long);
+ lua_pushlstring(l, p, len);
+ }
+ break;
+ case 'N':
+ {
+ nick *np = va_arg(va, nick *);
+ lua_pushnumeric(l, np->numeric);
+ break;
+ }
+ case 'C':
+ {
+ channel *cp = va_arg(va, channel *);
+ LUA_PUSHCHAN(l, cp);
+ break;
+ }
+ case '0':
+ lua_pushnil(l);
+ break;
+ case 'R':
+ lua_rawgeti(l, LUA_REGISTRYINDEX, va_arg(va, long));
+ break;
+ case 'b':
+ lua_pushboolean(l, va_arg(va, int));
+ break;
+ case '>':
+ goto endwhile;
+
+ default:
+ Error("lua", ERR_ERROR, "Unable to parse vpcall signature (%c)", *(sig - 1));
+ }
+ narg++;
+ }
+
+endwhile:
+
+ nres = strlen(sig);
+
+ if(lua_debugpcall(l, (mode==LUA_CHARMODE)?function:"some_handler", narg, nres, top + 1)) {
+ Error("lua", ERR_ERROR, "Error pcalling %s: %s.", (mode==LUA_CHARMODE)?(char *)function:"some_handler", lua_tostring(l, -1));
+ } else {
+ nres = -nres;
+ while(*sig) {
+ switch(*sig++) {
+ default:
+ Error("lua", ERR_ERROR, "Unable to parse vpcall return structure (%c)", *(sig - 1));
+ }
+ nres++;
+ }
+ }
+
+ lua_settop(l, top);
+ va_end(va);
+ return 0;