From 40bad69cd77f32730f6939553d7f9667338c646f Mon Sep 17 00:00:00 2001 From: deva Date: Mon, 3 Nov 2008 15:22:10 +0000 Subject: Did a lot of work on format utils. --- server/src/Makefile.am | 6 +- server/src/database.cc | 2 +- server/src/formattools.cc | 10 +- server/src/luaformatmapper.cc | 16 +- server/src/luaformatmapper.h | 2 + server/src/luaformatmapperutils.cc | 322 +++++++++++++++++++++++++++++++++++++ server/src/luaformatmapperutils.h | 38 +++++ 7 files changed, 388 insertions(+), 8 deletions(-) create mode 100644 server/src/luaformatmapperutils.cc create mode 100644 server/src/luaformatmapperutils.h (limited to 'server') diff --git a/server/src/Makefile.am b/server/src/Makefile.am index 3449e6b..6721b8c 100644 --- a/server/src/Makefile.am +++ b/server/src/Makefile.am @@ -18,6 +18,7 @@ pracrod_SOURCES = \ journal_commit.cc \ log.cc \ luaformatmapper.cc \ + luaformatmapperutils.cc \ luaquerymapper.cc \ macroparser.cc \ resumeparser.cc \ @@ -42,6 +43,7 @@ EXTRA_DIST = \ journal_commit.h \ log.h \ luaformatmapper.h \ + luaformatmapperutils.h \ luaquerymapper.h \ macroparser.h \ resumeparser.h \ @@ -73,8 +75,8 @@ test: $(TESTFILES) test_clean: rm -f $(TESTFILES) -test_formattools: formattools.cc luaformatmapper.cc - @../../tools/test formattools.cc luaformatmapper.cc exception.cc log.cc $(LUA_LIBS) +test_formattools: formattools.cc luaformatmapper.cc luaformatmapperutils.cc + @../../tools/test formattools.cc luaformatmapper.cc luaformatmapperutils.cc exception.cc log.cc $(LUA_LIBS) test_queryhandler: queryhandler.cc @../../tools/test queryhandler.cc tcpsocket.cc exception.cc log.cc diff --git a/server/src/database.cc b/server/src/database.cc index 08e8465..dbc5849 100644 --- a/server/src/database.cc +++ b/server/src/database.cc @@ -106,7 +106,7 @@ void Database::commit(std::string user, std::map< std::string, std::string >::iterator i = fields.begin(); while(i != fields.end()) { if(i == fields.begin()) query << " WHERE name = '" << protect(i->first) << "'"; - else query << " OR name = '" << protect(i->first) << "';"; + else query << " OR name = '" << protect(i->first) << "'"; i++; } #ifdef WITH_DEBUG diff --git a/server/src/formattools.cc b/server/src/formattools.cc index b90ca51..63cfec6 100644 --- a/server/src/formattools.cc +++ b/server/src/formattools.cc @@ -192,13 +192,19 @@ int main() Fields fields; fields["dingo"] = "[[meget dyr]]"; fields["fnuld"] = "Zimbabwe"; + fields["mlstring"] = "Ladidaa ${foo|bar} ${{dingo|dyt}} ${dims|dulle}."; printf("%s\n", deescape_string(deescape_string("[[] []]", '['), ']').c_str()); if(escape_multilist_string("${} {{}}") != "${{}} {{{{}}}}") return 1; if(escape_resume_string("$[] [[]]") != "$[[]] [[[[]]]]") return 1; - printf("{%s}\n", render_multilist_string("Ladidaa ${foo|bar} ${{dingo|dyt}} ${dims|dulle}.").c_str()); - printf("{%s}\n", render_resume_string("Ladidaa $[return 'dims' .. dingo] $[[et eller andet]] $[return 'noget andet'].", fields).c_str()); + + std::string mlstring = "Ladidaa ${foo|bar} ${{dingo|dyt}} ${dims|dulle}."; + printf("{%s}\n", render_multilist_string(mlstring).c_str()); + + // std::string resumestring = "Ladidaa $[printval('dims' .. dingo)] $[[et eller andet]] $[printval('noget andet')]."; + std::string resumestring = "Ladidaa \n$[printfmlval('mlstring', ' * ', true, '

', 'myname', '

')] dalidaadoo."; + printf("{%s}\n", render_resume_string(resumestring, fields).c_str()); return 0; } diff --git a/server/src/luaformatmapper.cc b/server/src/luaformatmapper.cc index b45c170..6c0115d 100644 --- a/server/src/luaformatmapper.cc +++ b/server/src/luaformatmapper.cc @@ -30,6 +30,8 @@ #include "exception.h" +#include "luaformatmapperutils.h" + static std::string loadresultstring(Fields &fields) { std::string s; @@ -53,6 +55,9 @@ LUAFormatMapper::LUAFormatMapper(Fields &fields) luaL_openlibs(L); + setGlobal(L, "LUAFormatMapper", this); + preload_formatutils(L); + std::string preload = loadresultstring(fields); if(luaL_loadbuffer(L, preload.c_str(), preload.size(), "preload")) { @@ -101,14 +106,14 @@ std::string LUAFormatMapper::map(const std::string &mapper) } // Check if app messed up the stack. - if(lua_gettop(L) != clean_top + 1) { + if(lua_gettop(L) != clean_top) { error("Wrong number of return values in " + mapper); lua_pop(L, lua_gettop(L) - clean_top); return output; } - output = lua_tostring(L, lua_gettop(L)); - lua_pop(L, 1); + // output = lua_tostring(L, lua_gettop(L)); + // lua_pop(L, 1); return output; } @@ -117,3 +122,8 @@ void LUAFormatMapper::error(std::string message) { throw Exception("ERROR in LUAFormatMapper: " + message); } + +void LUAFormatMapper::bufferoutput(std::string value) +{ + output += value; +} diff --git a/server/src/luaformatmapper.h b/server/src/luaformatmapper.h index b4cb8c9..8715eed 100644 --- a/server/src/luaformatmapper.h +++ b/server/src/luaformatmapper.h @@ -49,6 +49,8 @@ public: void error(std::string message); + void bufferoutput(std::string value); + private: lua_State *L; int clean_top; diff --git a/server/src/luaformatmapperutils.cc b/server/src/luaformatmapperutils.cc new file mode 100644 index 0000000..228c9f5 --- /dev/null +++ b/server/src/luaformatmapperutils.cc @@ -0,0 +1,322 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * luaformatmapperutils.cc + * + * Mon Nov 3 08:46:51 CET 2008 + * Copyright 2008 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Pracro. + * + * Pracro is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Pracro is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Pracro; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include "luaformatmapperutils.h" +#include "luaformatmapper.h" + +#include +#include + +std::vector< void * > pointers; + +#define GLOBAL_PREFIX "magic_global_" + +void *getGlobal(lua_State *L, const char *name) +{ + unsigned int top; + unsigned int index; + + std::string var = std::string(GLOBAL_PREFIX) + name; + + lua_getfield(L, LUA_GLOBALSINDEX, var.c_str()); + top = lua_gettop(L); + index = lua_tointeger(L, top); + + return pointers.at(index); +} + +void setGlobal(lua_State *L, const char *name, void *p) +{ + // Put the value of this in the globals + char value_of_this[256]; + + std::string val = std::string(GLOBAL_PREFIX) + name; + + pointers.push_back(p); + unsigned int index = pointers.size() - 1; + + sprintf(value_of_this, "%s = %u\n", val.c_str(), index); + int s = luaL_loadstring(L, value_of_this); + switch(s) { + case 0: //no errors; + break; + case LUA_ERRSYNTAX: //syntax error during pre-compilation; + case LUA_ERRMEM: //memory allocation error. + fprintf(stderr, "Error: %s\n", lua_tostring(L, lua_gettop(L))); + default: + fprintf(stderr, "Unknown return value of luaL_loadstring.\n"); + } + + // Run program (init) + s = lua_pcall(L, 0, LUA_MULTRET, 0); + // Check for errors + switch(s) { + case 0: // Success + break; + case LUA_ERRRUN:// a runtime error. + case LUA_ERRMEM:// memory allocation error. + // For such errors, Lua does not call the error handler function. + case LUA_ERRERR:// error while running the error handler function. + fprintf(stderr, "Error: %s\n", lua_tostring(L, lua_gettop(L))); + break; + default: + fprintf(stderr, "Error: Unknown return value of lua_pcall.\n"); + break; + } +} + +typedef enum { + MLTT_VALUE, + MLTT_TEXT, + MLTT_ENDOFITEM, // newline + MLTT_UNDEFINED +} mltokentype_t; + +typedef struct { + mltokentype_t type; + std::string name; + std::string value; +} mltoken_t; + +std::vector< mltoken_t > mltokenize(std::string mlvalue) +{ + std::vector< mltoken_t > tokens; + /* + mltoken_t token; + token = MLTT_UNDEFINED; + for(size_t i = 0; i < mlvalue.length(); i++) { + switch(mlvalue[i]) { + case '$': + case '[': + case ']': + case '\n': + default: + } + } + */ + { + mltoken_t token; + token.type = MLTT_TEXT; + token.value = "noget tekst "; + tokens.push_back(token); + } + + { + mltoken_t token; + token.type = MLTT_VALUE; + token.name = "myname"; + token.value = "myvalue"; + tokens.push_back(token); + } + + { + mltoken_t token; + token.type = MLTT_TEXT; + token.value = " noget mere tekst"; + tokens.push_back(token); + } + + { + mltoken_t token; + token.type = MLTT_ENDOFITEM; + token.value = "\n"; + tokens.push_back(token); + } + + // en entry mere... + { + mltoken_t token; + token.type = MLTT_TEXT; + token.value = "yet another "; + tokens.push_back(token); + } + + { + mltoken_t token; + token.type = MLTT_VALUE; + token.name = "myname"; + token.value = "another value"; + tokens.push_back(token); + } + + { + mltoken_t token; + token.type = MLTT_TEXT; + token.value = " and thats final!"; + tokens.push_back(token); + } + + { + mltoken_t token; + token.type = MLTT_ENDOFITEM; + token.value = "\n"; + tokens.push_back(token); + } + + return tokens; +} + +typedef struct { + std::string prefix; + std::string postfix; +} transform_params_t; + +std::map< std::string, transform_params_t > transforms; + +/** + * Args: mlvalue, bullet, usetext, name1, prefix1, postfix1, name2, prefix2, postfix2, ... + * Iterates list items, prepends bullet, and replaces all name/value pairs with + * corresponding prefix/value/postfix. + */ +int printfmlval(lua_State *L) +{ + int n = lua_gettop(L); // number of arguments + if(n < 3 || (n - 3) % 3 != 0) { + char errstr[512]; + sprintf(errstr, "Minimum number of args expected 3, got %d", n); + fprintf(stderr, errstr); + lua_pushstring(L, errstr); + lua_error(L); + return 0; + } + + std::string mlvalue = lua_tostring(L, lua_gettop(L) - (n - 1)); + std::string bullet = lua_tostring(L, lua_gettop(L) - (n - 2)); + bool usetext = lua_toboolean(L, lua_gettop(L) - (n - 3)); + + printf("[%s], [%s], [%d]\n", mlvalue.c_str(), bullet.c_str(), usetext); fflush(stdout); + + // Read in the (prefix, name, postfix) 3-tuples + int m = 4; + while(m < lua_gettop(L)) { + + printf("!\n"); fflush(stdout); + + transform_params_t p; + p.prefix = lua_tostring(L, lua_gettop(L) - (n - m)); + std::string name = lua_tostring(L, lua_gettop(L) - (n - (m + 1))); + p.postfix = lua_tostring(L, lua_gettop(L) - (n - (m + 2))); + + printf("[%s], [%s], [%s]\n", p.prefix.c_str(), name.c_str(), p.postfix.c_str()); fflush(stdout); + + transforms[name] = p; + + m += 3; + } + + LUAFormatMapper *lfm = (LUAFormatMapper*)getGlobal(L, "LUAFormatMapper"); + + mltokentype_t lasttype = MLTT_ENDOFITEM; + std::vector< mltoken_t > tokens = mltokenize(mlvalue); + std::vector< mltoken_t >::iterator i = tokens.begin(); + while(i != tokens.end()) { + if(lasttype == MLTT_ENDOFITEM) lfm->bufferoutput(bullet); + + switch(i->type) { + case MLTT_VALUE: + lfm->bufferoutput(transforms[i->name].prefix); + lfm->bufferoutput(i->value); + lfm->bufferoutput(transforms[i->name].postfix); + break; + + case MLTT_TEXT: + if(usetext) lfm->bufferoutput(i->value); + break; + + case MLTT_ENDOFITEM: + if(usetext) lfm->bufferoutput(i->value); + break; + + case MLTT_UNDEFINED: + // Undefined + break; + } + + lasttype = i->type; + i++; + } + + return 0; +} + + +int printval(lua_State *L) +{ + int n = lua_gettop(L); // number of arguments + if(n != 1) { + char errstr[512]; + sprintf(errstr, "Number of args expected 1, got %d", n); + fprintf(stderr, errstr); + lua_pushstring(L, errstr); + lua_error(L); + return 0; + } + + std::string value = lua_tostring(L, lua_gettop(L)); + + LUAFormatMapper *lfm = (LUAFormatMapper*)getGlobal(L, "LUAFormatMapper"); + + lfm->bufferoutput(value); + + return 0; +} + +/* +int pg_query(lua_State *L) +{ + int n = lua_gettop(L); // number of arguments + if(n != 2) { + char errstr[512]; + sprintf(errstr, "Number of args expected 2, got %d", n); + fprintf(stderr, errstr); + lua_pushstring(L, errstr); + lua_error(L); + return 0; + } + + std::string query = lua_tostring(L, lua_gettop(L)); + unsigned int pg = lua_tointeger(L, lua_gettop(L) - 1); + + printf("query [%s]\n", query.c_str()); + + // lua_createtable(L, 0, 1); + // lua_pushinteger(L, 41); + // lua_rawseti(L, -2, 1); + // lua_setfenv(L, -2); + + lua_pushinteger(L, 42); + lua_pushinteger(L, 41); + lua_rawset(L, -3); + + return 1; +} +*/ + +void preload_formatutils(lua_State *L) +{ + lua_register(L, "printval", printval); + lua_register(L, "printfmlval", printfmlval); +} diff --git a/server/src/luaformatmapperutils.h b/server/src/luaformatmapperutils.h new file mode 100644 index 0000000..28f2b48 --- /dev/null +++ b/server/src/luaformatmapperutils.h @@ -0,0 +1,38 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * luaformatmapperutils.h + * + * Mon Nov 3 08:46:51 CET 2008 + * Copyright 2008 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Pracro. + * + * Pracro is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Pracro is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Pracro; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#ifndef __PRACRO_LUAFORMATMAPPERUTILS_H__ +#define __PRACRO_LUAFORMATMAPPERUTILS_H__ + +#include +#include + +void preload_formatutils(lua_State *L); + +void *getGlobal(lua_State *L, const char *name); +void setGlobal(lua_State *L, const char *name, void *p); + +#endif/*__PRACRO_LUAFORMATMAPPERUTILS_H__*/ -- cgit v1.2.3