summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordeva <deva>2011-07-01 10:02:42 +0000
committerdeva <deva>2011-07-01 10:02:42 +0000
commit42e43b044ffc49e3128ae59e75ce5ffd84c371be (patch)
tree013b7f5a3134d6dd97ef23adb524c3ba4e5d5bf2
parent0a9bb105ff1534868886e68e3309aabc6c0315c0 (diff)
Fixed bug in field check/creation with depth greater than 1.
-rw-r--r--server/src/luaquerymapper.cc67
-rw-r--r--server/src/luautil.cc143
-rw-r--r--server/src/luautil.h13
3 files changed, 188 insertions, 35 deletions
diff --git a/server/src/luaquerymapper.cc b/server/src/luaquerymapper.cc
index 380960c..f593c28 100644
--- a/server/src/luaquerymapper.cc
+++ b/server/src/luaquerymapper.cc
@@ -29,35 +29,24 @@
#include <sstream>
#include <string>
-static bool hasField(lua_State *L, int i, std::string name)
-{
- lua_getfield(L, i, name.c_str());
- bool ret = lua_isnil(L, lua_gettop(L));
- lua_pop(L, 1);
- return ret;
-}
+#include "luautil.h"
static void loadResult(lua_State *L, QueryResult &res,
- std::vector<std::string> group = std::vector<std::string>())
+ std::vector<std::string> group = std::vector<std::string>())
{
- int grp = 0;
+ std::vector<std::string> groups;
std::vector<std::string>::iterator gi = group.begin();
while(gi != group.end()) {
const char *name = gi->c_str();
- printf("[%d: %s]", grp, name); fflush(stdout);
- if(grp == 0) grp = LUA_GLOBALSINDEX;
- if(hasField(L, grp, name)) {
- lua_newtable(L);
- lua_setfield(L, grp, name);
- lua_getfield(L, grp, name);
+ if(!Pracro::testField(L, groups, name)) {
+ Pracro::createField(L, groups, name);
}
- grp = lua_gettop(L);
+ groups.push_back(name);
gi++;
}
- printf("\n"); fflush(stdout);
-
+
std::string s;
std::stringstream timestamp; timestamp << res.timestamp;
@@ -66,33 +55,30 @@ static void loadResult(lua_State *L, QueryResult &res,
const char *name = v->first.c_str();
- if(grp == 0) grp = LUA_GLOBALSINDEX;
- if(hasField(L, grp, name)) {
- lua_newtable(L);
- lua_setfield(L, grp, name);
+ if(!Pracro::testField(L, group, name)) {
+ Pracro::createField(L, group, name);
}
- int val;
+ int top = lua_gettop(L);
+ Pracro::getField(L, group, name);
- lua_getfield(L, grp, name);
- val = lua_gettop(L);
lua_pushstring(L, v->second.c_str());
- lua_setfield(L, val, "value");
+ lua_setfield(L, -2, "value");
- lua_getfield(L, grp, name);
- val = lua_gettop(L);
lua_pushstring(L, timestamp.str().c_str());
- lua_setfield(L, val, "timestamp");
+ lua_setfield(L, -2, "timestamp");
- lua_getfield(L, grp, name);
- val = lua_gettop(L);
lua_pushstring(L, res.source.c_str());
- lua_setfield(L, val, "source");
+ lua_setfield(L, -2, "source");
+
+ while(lua_gettop(L) > top) lua_pop(L, 1);
v++;
}
- while(lua_gettop(L) > 1) lua_pop(L, 1);
+ while(lua_gettop(L)) lua_pop(L, 1);
+
+ printf("< %d\n", lua_gettop(L)); fflush(stdout);
std::map< std::string, QueryResult >::iterator g = res.groups.begin();
while(g != res.groups.end()) {
@@ -232,7 +218,7 @@ std::string LUAQueryMapper::automap(const std::string &name)
}
#ifdef TEST_LUAQUERYMAPPER
-//deps: exception.cc log.cc debug.cc
+//deps: exception.cc log.cc debug.cc luautil.cc
//cflags: -I.. ${LUA_CFLAGS}
//libs:${LUA_LIBS}
#include <test.h>
@@ -250,15 +236,26 @@ time_t now = time(NULL);
res.groups["test"].groups["subtest"].source = "test app 2";
res.groups["test"].groups["subtest"].timestamp = now + 1;
res.groups["test"].groups["subtest"].values["somevalue"] = "hello world!";
+ res.groups["test"].groups["subtest"].groups["subsubtest"].source = "test app 3";
+ res.groups["test"].groups["subtest"].groups["subsubtest"].timestamp = now + 2;
+ res.groups["test"].groups["subtest"].groups["subsubtest"].values["somevalue"] = "hello world!!";
LUAQueryMapper mapper;
mapper.addQueryResult(res);
// Test simple value forwarding with nesting
- std::string luamap = "return test.subtest.somevalue.value, test.subtest.somevalue.timestamp, test.subtest.somevalue.source";
+ std::string luamap = "return test.subtest.subsubtest.somevalue.value, test.subtest.subsubtest.somevalue.timestamp, test.subtest.subsubtest.somevalue.source";
Value value = mapper.map(luamap);
+ TEST_EQUAL_STR(value.value, "hello world!!", "Test value");
+ TEST_EQUAL_INT(value.timestamp, now + 2, "Test timestamp");
+ TEST_EQUAL_STR(value.source, "test app 3", "Test source");
+
+ luamap = "return test.subtest.somevalue.value, test.subtest.somevalue.timestamp, test.subtest.somevalue.source";
+
+ value = mapper.map(luamap);
+
TEST_EQUAL_STR(value.value, "hello world!", "Test value");
TEST_EQUAL_INT(value.timestamp, now + 1, "Test timestamp");
TEST_EQUAL_STR(value.source, "test app 2", "Test source");
diff --git a/server/src/luautil.cc b/server/src/luautil.cc
index 116d219..1042d8f 100644
--- a/server/src/luautil.cc
+++ b/server/src/luautil.cc
@@ -217,6 +217,129 @@ int Pracro::checkParameters(lua_State *L, ...)
return 0;
}
+void Pracro::stack(lua_State* l, const char *fmt, ...)
+{
+ int i;
+ int top = lua_gettop(l);
+
+ va_list va;
+ va_start(va, fmt);
+
+ printf("---Stack: ");
+ vprintf(fmt, va);
+ printf("---\nSize: %d\n", top);
+
+ for (i = 1; i <= top; i++) {
+ int t = lua_type(l, i);
+ switch (t) {
+ case LUA_TSTRING:
+ printf("string: '%s'\n", lua_tostring(l, i));
+ break;
+ case LUA_TBOOLEAN:
+ printf("boolean %s\n",lua_toboolean(l, i) ? "true" : "false");
+ break;
+ case LUA_TNUMBER:
+ printf("number: %g\n", lua_tonumber(l, i));
+ break;
+ default:
+ printf("%s\n", lua_typename(l, t));
+ break;
+ }
+ printf(" ");
+ }
+ printf("\n");
+ fflush(stdout);
+}
+
+bool Pracro::hasField(lua_State *L, int i, std::string name)
+{
+ // stack []
+ lua_getfield(L, i, name.c_str()); // stack [field|nil]
+ bool ret = !lua_isnil(L, lua_gettop(L)); // stack [field|nil]
+ lua_pop(L, 1); // stack []
+
+ return ret;
+}
+
+bool Pracro::testField(lua_State *L, std::vector<std::string> groups,
+ std::string field)
+{
+ int top = lua_gettop(L);
+
+ groups.push_back(field);
+
+ int grp = LUA_GLOBALSINDEX;
+ std::vector<std::string>::iterator gi = groups.begin();
+ while(gi != groups.end()) {
+ const char *name = gi->c_str();
+
+ if(!hasField(L, grp, name)) {
+ while(lua_gettop(L) > top) lua_pop(L, 1);
+ return false;
+ }
+ lua_getfield(L, grp, name);
+
+ grp = lua_gettop(L);
+ gi++;
+ }
+
+ while(lua_gettop(L) > top) lua_pop(L, 1);
+
+ return true;
+}
+
+bool Pracro::getField(lua_State *L, std::vector<std::string> groups,
+ std::string field)
+{
+ int top = lua_gettop(L);
+ groups.push_back(field);
+
+ int grp = LUA_GLOBALSINDEX;
+ std::vector<std::string>::iterator gi = groups.begin();
+ while(gi != groups.end()) {
+ const char *name = gi->c_str();
+
+ if(!hasField(L, grp, name)) {
+ while(lua_gettop(L) > top) lua_pop(L, 1);
+ return false;
+ }
+ lua_getfield(L, grp, name);
+
+ grp = lua_gettop(L);
+ gi++;
+ }
+
+ return true;
+}
+
+bool Pracro::createField(lua_State *L, std::vector<std::string> groups,
+ std::string field)
+{
+ int top = lua_gettop(L);
+
+ int grp = LUA_GLOBALSINDEX;
+ std::vector<std::string>::iterator gi = groups.begin();
+ while(gi != groups.end()) {
+ const char *name = gi->c_str();
+
+ if(!hasField(L, grp, name)) {
+ while(lua_gettop(L) > top) lua_pop(L, 1);
+ return false;
+ }
+ lua_getfield(L, grp, name);
+
+ grp = lua_gettop(L);
+ gi++;
+ }
+
+ lua_newtable(L);
+ lua_setfield(L, grp, field.c_str());
+
+ while(lua_gettop(L) > top) lua_pop(L, 1);
+
+ return true;
+}
+
#ifdef TEST_LUAUTIL
//deps:
//cflags: $(LUA_CFLAGS) -I..
@@ -305,6 +428,26 @@ if(luaL_loadstring(L, LUAPROG_MISSING_END)) {
}
TEST_NOTEQUAL_INT(lua_pcall(L, 0, LUA_MULTRET, 0), 0, "Missing T_END");
+std::string src =
+ "foo = {}"
+ "foo.bar = {}"
+ "foo.bar.bas = {}"
+ "foo.bar.bas.value = 'hello'"
+ "print('done')";
+
+luaL_loadbuffer(L, src.c_str(), src.size(), "src");
+lua_pcall(L, 0, LUA_MULTRET, 0);
+
+std::vector<std::string> g;
+g.push_back("foo");
+g.push_back("bar");
+g.push_back("bas");
+TEST_TRUE(Pracro::testField(L, g, "value"), "?");
+
+TEST_TRUE(Pracro::createField(L, g, "abe"), "?");
+
+TEST_TRUE(Pracro::testField(L, g, "abe"), "?");
+
lua_close(L);
TEST_END;
diff --git a/server/src/luautil.h b/server/src/luautil.h
index ebbba45..0d9d445 100644
--- a/server/src/luautil.h
+++ b/server/src/luautil.h
@@ -31,6 +31,7 @@
#include <lauxlib.h>
#include <string>
+#include <vector>
namespace Pracro {
@@ -76,6 +77,18 @@ namespace Pracro {
// int checkParameters(lua_State *L, types_t types[]);
int checkParameters(lua_State *L, ...);
+ bool hasField(lua_State *L, int i, std::string name);
+
+ bool testField(lua_State *L, std::vector<std::string> groups,
+ std::string field);
+
+ bool getField(lua_State *L, std::vector<std::string> groups,
+ std::string field);
+
+ bool createField(lua_State *L, std::vector<std::string> groups,
+ std::string field);
+
+ void stack(lua_State* l, const char *fmt, ...);
};
#endif/*__PRACRO_LUAUTIL_H__*/