seqlua

annotate seqlualib.c @ 57:da4b9d6a5b7e

Fixed bug due to problem combining luaL_buffinit with seqlua_iterinit
author jbe
date Tue Jan 05 04:26:49 2016 +0100 (2016-01-05)
parents 92ce3958aca7
children
rev   line source
jbe@0 1 #include <lua.h>
jbe@0 2 #include <lauxlib.h>
jbe@0 3 #include "seqlualib.h"
jbe@35 4 #include <string.h>
jbe@0 5
jbe@30 6 #define SEQLUA_ITERTYPE_IPAIRS 1
jbe@30 7 #define SEQLUA_ITERTYPE_CALL 2
jbe@30 8 #define SEQLUA_ITERTYPE_INDEX 3
jbe@30 9 #define SEQLUA_ITERTYPE_RAW 4
jbe@0 10
jbe@57 11 // TODO: allow combining luaL_buffinit with seqlua_iterinit somehow
jbe@57 12
jbe@54 13 void seqlua_iterinit(lua_State *L, seqlua_Iterator *iter, int idx) {
jbe@30 14 if (luaL_getmetafield(L, idx, "__ipairs")) {
jbe@54 15 lua_pushvalue(L, idx);
jbe@30 16 lua_call(L, 1, 3);
jbe@35 17 if (lua_type(L, -3) == LUA_TSTRING) {
jbe@35 18 const char *method = lua_tostring(L, -3);
jbe@35 19 if (!strcmp(method, "raw")) {
jbe@35 20 iter->itertype = SEQLUA_ITERTYPE_RAW;
jbe@35 21 } else if (!strcmp(method, "index")) {
jbe@35 22 iter->itertype = SEQLUA_ITERTYPE_INDEX;
jbe@35 23 } else if (!strcmp(method, "call")) {
jbe@35 24 iter->itertype = SEQLUA_ITERTYPE_CALL;
jbe@35 25 } else {
jbe@35 26 luaL_error(L, "Unexpected string returned by __ipairs metamethod");
jbe@35 27 }
jbe@35 28 iter->idx = lua_gettop(L) - 1;
jbe@35 29 } else {
jbe@35 30 iter->itertype = SEQLUA_ITERTYPE_IPAIRS;
jbe@35 31 }
jbe@30 32 } else {
jbe@30 33 if (lua_type(L, idx) == LUA_TFUNCTION) {
jbe@54 34 iter->itertype = SEQLUA_ITERTYPE_CALL;
jbe@32 35 } else if (luaL_getmetafield(L, idx, "__index")) {
jbe@30 36 lua_pop(L, 1);
jbe@30 37 iter->itertype = SEQLUA_ITERTYPE_INDEX;
jbe@54 38 } else {
jbe@54 39 luaL_checktype(L, idx, LUA_TTABLE);
jbe@54 40 iter->itertype = SEQLUA_ITERTYPE_RAW;
jbe@30 41 }
jbe@30 42 // always occupy 3 stack indicies
jbe@54 43 lua_pushnil(L);
jbe@30 44 lua_pushnil(L);
jbe@30 45 lua_pushnil(L);
jbe@30 46 iter->idx = idx;
jbe@30 47 }
jbe@0 48 iter->L = L;
jbe@0 49 iter->i = 0;
jbe@0 50 }
jbe@0 51
jbe@0 52 int seqlua_iternext(seqlua_Iterator *iter) {
jbe@0 53 lua_State *L = iter->L;
jbe@0 54 lua_Integer i = ++iter->i;
jbe@0 55 switch (iter->itertype) {
jbe@30 56 case SEQLUA_ITERTYPE_IPAIRS:
jbe@30 57 lua_pushvalue(L, -3);
jbe@30 58 lua_pushvalue(L, -3);
jbe@30 59 lua_pushvalue(L, -3);
jbe@30 60 lua_call(L, 2, 2);
jbe@30 61 if (lua_isnil(L, -2)) {
jbe@30 62 lua_pop(L, 5);
jbe@30 63 return 0;
jbe@30 64 }
jbe@30 65 lua_remove(L, -3);
jbe@30 66 return 1;
jbe@30 67 case SEQLUA_ITERTYPE_CALL:
jbe@8 68 lua_pushvalue(L, iter->idx);
jbe@0 69 lua_call(L, 0, 1);
jbe@0 70 break;
jbe@30 71 case SEQLUA_ITERTYPE_INDEX:
jbe@0 72 lua_pushinteger(L, i);
jbe@8 73 lua_gettable(L, iter->idx);
jbe@32 74 break;
jbe@0 75 case SEQLUA_ITERTYPE_RAW:
jbe@8 76 lua_rawgeti(L, iter->idx, i);
jbe@8 77 break;
jbe@0 78 }
jbe@0 79 if (lua_isnil(L, -1)) {
jbe@30 80 lua_pop(L, 4);
jbe@0 81 return 0;
jbe@0 82 }
jbe@0 83 return 1;
jbe@0 84 }
jbe@0 85

Impressum / About Us