diff options
-rw-r--r-- | server/src/formattools.cc | 109 | ||||
-rw-r--r-- | server/src/luaformatmapper.cc | 17 | ||||
-rw-r--r-- | server/src/luaformatmapperutils.cc | 98 | ||||
-rw-r--r-- | server/src/mltokenizer.cc | 196 | ||||
-rw-r--r-- | server/src/mltokenizer.h | 55 |
5 files changed, 300 insertions, 175 deletions
diff --git a/server/src/formattools.cc b/server/src/formattools.cc index 63cfec6..6a58d74 100644 --- a/server/src/formattools.cc +++ b/server/src/formattools.cc @@ -25,7 +25,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include "formattools.h" - +#include "mltokenizer.h" #include "luaformatmapper.h" /** @@ -49,7 +49,8 @@ static std::string deescape_string(std::string str, char c) std::string out; for(size_t i = 0; i < str.length(); i++) { if(i < str.length() - 1 && str[i] == c && str[i + 1] == c) { - // We simply do nothing here, thus skipping the current character. + out += str[i]; + i++; // Skip the next character } else { out += str[i]; } @@ -67,82 +68,32 @@ std::string escape_resume_string(std::string str) return escape_string(escape_string(str, '['), ']'); } -// FIXME: This function doesn't work... reimplement using regexps. -Fields get_multilist_values(std::string str) +Fields get_multilist_values(std::string mlvalue) { std::map<std::string, std::string> values; - // Replace ${foo|bar} with bar - for(size_t i = 0; i < str.length(); i++) { - if(str[i] == '$') { - if(i < str.length() - 2 && - str[i+1] == '{' && str[i+2] != '{') { - // We are in a key/value - - // Look for end marker, and | - size_t j; - for(j = i + 2; j < str.length(); j++) { - if(str[j] == '}' && str[j + 1] != '}') { - // We have an end marker - break; - } - } - - std::string key_value = str.substr(i + 2, j - (i + 2)); - printf("Found [%s]\n", key_value.c_str()); - - std::string value = key_value.substr(key_value.find('|') + 1); - std::string key = key_value.substr(0, key_value.find('|') - 1); - - values[key] = value; - - i = j; - - } - } + std::vector< mltoken_t > tokens = mltokenize(mlvalue); + std::vector< mltoken_t >::iterator i = tokens.begin(); + while(i != tokens.end()) { + if(i->type == MLTT_VALUE) values[i->name] = i->value; + i++; } return values; } - -// FIXME: This function doesn't work... reimplement using regexps. -std::string render_multilist_string(std::string str) +std::string render_multilist_string(std::string mlvalue) { - std::string out; - - // Replace ${foo|bar} with bar - for(size_t i = 0; i < str.length(); i++) { - if(str[i] == '$') { - if(i < str.length() - 2 && - str[i+1] == '{' && str[i+2] != '{') { - // We are in a key/value - - // Look for end marker, and | - size_t j; - for(j = i + 2; j < str.length(); j++) { - if(str[j] == '}' && str[j + 1] != '}') { - // We have an end marker - break; - } - } - - std::string key_value = str.substr(i + 2, j - (i + 2)); - printf("Found [%s]\n", key_value.c_str()); - - std::string value = key_value.substr(key_value.find('|') + 1); + std::string output; - out += value; - - i = j; - - } else out += str[i]; - } else { - out += str[i]; - } + std::vector< mltoken_t > tokens = mltokenize(mlvalue); + std::vector< mltoken_t >::iterator i = tokens.begin(); + while(i != tokens.end()) { + output += i->value; + i++; } - - return deescape_string(deescape_string(out, '{'), '}'); + + return output; } std::string render_resume_string(std::string str, Fields &fields) @@ -158,7 +109,7 @@ std::string render_resume_string(std::string str, Fields &fields) str[i+1] == '[' && str[i+2] != '[') { // We are in a key/value - // Look for end marker, and | + // Look for end marker size_t j; for(j = i + 2; j < str.length(); j++) { if(str[j] == ']' && str[j + 1] != ']') { @@ -168,11 +119,8 @@ std::string render_resume_string(std::string str, Fields &fields) } std::string luaprogram = str.substr(i + 2, j - (i + 2)); - printf("Found [%s]\n", luaprogram.c_str()); - std::string value = mapper.map(luaprogram); - - out += value; + out += escape_resume_string(value); i = j; @@ -192,19 +140,28 @@ int main() Fields fields; fields["dingo"] = "[[meget dyr]]"; fields["fnuld"] = "Zimbabwe"; - fields["mlstring"] = "Ladidaa ${foo|bar} ${{dingo|dyt}} ${dims|dulle}."; + fields["mlstring"] = + "Ladidaa ${myname|bar} ${{dingo|dyt}} ${dims|{{dimmer}}}.\n" + "Ladidaa ${myname|bole} ${{dingo|dyt}} ${dims|[[fillerhejs]]}.\n" + "Ladidaa ${myname|daske} ${{dingo|dyt}} ${dims|buller}.\n"; + /* printf("%s\n", deescape_string(deescape_string("[[] []]", '['), ']').c_str()); if(escape_multilist_string("${} {{}}") != "${{}} {{{{}}}}") return 1; if(escape_resume_string("$[] [[]]") != "$[[]] [[[[]]]]") return 1; - std::string mlstring = "Ladidaa ${foo|bar} ${{dingo|dyt}} ${dims|dulle}."; + std::string mlstring = "Ladidaa ${myname|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, '<p>', 'myname', '</p>')] dalidaadoo."; + std::string resumestring = "Ladidaa \n$[" + "printfmlval(mlstring, ' * ', true, '<p>', 'myname', '</p>', 'PRE', 'dims', 'POST')" + "] dalidaadoo."; printf("{%s}\n", render_resume_string(resumestring, fields).c_str()); + + // std::string resumestring2 = "Ladidaa \n$[printfmlval(mlstring, ' * ', false, '<p>', 'myname', '</p>', 'PRE', 'dims', 'POST')] dalidaadoo."; + // printf("{%s}\n", render_resume_string(resumestring2, fields).c_str()); return 0; } diff --git a/server/src/luaformatmapper.cc b/server/src/luaformatmapper.cc index 6c0115d..652a34d 100644 --- a/server/src/luaformatmapper.cc +++ b/server/src/luaformatmapper.cc @@ -31,20 +31,22 @@ #include "exception.h" #include "luaformatmapperutils.h" - +/* static std::string loadresultstring(Fields &fields) { std::string s; Fields::iterator v = fields.begin(); while(v != fields.end()) { - s += (*v).first + " = \"" + (*v).second + "\"\n"; + lua_pushstring(L, v->second); // Push the pointer to 'this' instance + lua_setglobal(L, v->first); // Assign it to a global lua var. + // s += (*v).first + " = \"" + (*v).second + "\"\n"; v++; } return s; } - +*/ LUAFormatMapper::LUAFormatMapper(Fields &fields) { L = luaL_newstate(); @@ -58,6 +60,13 @@ LUAFormatMapper::LUAFormatMapper(Fields &fields) setGlobal(L, "LUAFormatMapper", this); preload_formatutils(L); + Fields::iterator v = fields.begin(); + while(v != fields.end()) { + lua_pushstring(L, v->second.c_str()); // Push the pointer to 'this' instance + lua_setglobal(L, v->first.c_str()); // Assign it to a global lua var. + v++; + } + /* std::string preload = loadresultstring(fields); if(luaL_loadbuffer(L, preload.c_str(), preload.size(), "preload")) { @@ -70,7 +79,7 @@ LUAFormatMapper::LUAFormatMapper(Fields &fields) error(lua_tostring(L, lua_gettop(L))); return; } - + */ clean_top = lua_gettop(L); } diff --git a/server/src/luaformatmapperutils.cc b/server/src/luaformatmapperutils.cc index 228c9f5..b163477 100644 --- a/server/src/luaformatmapperutils.cc +++ b/server/src/luaformatmapperutils.cc @@ -26,6 +26,7 @@ */ #include "luaformatmapperutils.h" #include "luaformatmapper.h" +#include "mltokenizer.h" #include <string> #include <vector> @@ -88,97 +89,6 @@ void setGlobal(lua_State *L, const char *name, void *p) } } -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; @@ -207,20 +117,18 @@ int printfmlval(lua_State *L) 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); + // 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); + // printf("[%s], [%s], [%s]\n", p.prefix.c_str(), name.c_str(), p.postfix.c_str()); fflush(stdout); transforms[name] = p; diff --git a/server/src/mltokenizer.cc b/server/src/mltokenizer.cc new file mode 100644 index 0000000..91d5b4b --- /dev/null +++ b/server/src/mltokenizer.cc @@ -0,0 +1,196 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * mltokenizer.cc + * + * Tue Nov 4 08:46:35 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 "mltokenizer.h" + +static std::string rereplaceescaping(std::string mlvalue) +{ + std::string output; + size_t i = 0; + while(i < mlvalue.length()) { + if(mlvalue[i] == '\1') { + output += '{'; + i++; + } else if(mlvalue[i] == '\2') { + output += '}'; + i++; + } else { + output += mlvalue[i]; + i++; + } + } + return output; +} + +static std::string replaceescaping(std::string mlvalue) +{ + std::string output; + size_t i = 0; + while(i < mlvalue.length()) { + if(i < mlvalue.length() - 1 && mlvalue[i] == '{' && mlvalue[i + 1] == '{') { + output += '\1'; + i+=2; + } else if(i < mlvalue.length() - 1 && mlvalue[i] == '}' && mlvalue[i + 1] == '}') { + output += '\2'; + i+=2; + } else { + output += mlvalue[i]; + i++; + } + } + return output; +} + +static std::string gettoken(std::string input, size_t start, std::string term) +{ + std::string output; + + size_t i = start; + while(i < input.length()) { + + size_t j = 0; + while(j < term.length()) { + if(input[i] == term[j]) return output; + j++; + } + + output += input[i]; + i++; + } + + return output; +} + +typedef enum { + NAME, + VALUE, + TEXT, + ENDOFITEM, + UNDEFINED +} tokenizerstate_t; + +std::vector< mltoken_t > mltokenize(std::string mlvalue) +{ + std::vector< mltoken_t > tokens; + + mlvalue = replaceescaping(mlvalue); + + tokenizerstate_t state = UNDEFINED; + mltoken_t token; + size_t i = 0; + while(i < mlvalue.length()) { + switch(state) { + case NAME: + token.name = gettoken(mlvalue, i, "|"); + i += token.name.length() + 1; + token.type = MLTT_VALUE; + token.value = ""; + state = VALUE; + break; + + case VALUE: + token.value = gettoken(mlvalue, i, "}\n"); + i += token.value.length() + 1; + + token.value = rereplaceescaping(token.value); + token.type = MLTT_VALUE; + tokens.push_back(token); + + state = UNDEFINED; + break; + + case TEXT: + if(mlvalue[i] == '$') token.value = "$"; + else token.value = gettoken(mlvalue, i, "$\n"); + i += token.value.length(); + + token.value = rereplaceescaping(token.value); + token.type = MLTT_TEXT; + token.name = ""; + if(tokens.size() && tokens.back().type == MLTT_TEXT) tokens.back().value += token.value; + else tokens.push_back(token); + + state = UNDEFINED; + break; + + case ENDOFITEM: + token.value = "\n"; + i++; + + token.type = MLTT_ENDOFITEM; + token.name = ""; + tokens.push_back(token); + + state = UNDEFINED; + break; + + case UNDEFINED: + switch(mlvalue[i]) { + case '$': + if(i < mlvalue.length() - 1 && mlvalue[i + 1] == '{') { i++; break; } // ignore + else { state = TEXT; break; } + case '{': state = NAME; i++; break; + case '\n': state = ENDOFITEM; break; + default: state = TEXT; break; + } + } + } + + if(state != UNDEFINED) { + printf("Oups... missed something in the end!\n"); + tokens.push_back(token); + } + + return tokens; +} + +#ifdef TEST_MLTOKENIZER + +int main() +{ + std::string mlvalue = "$ab}}c\ndef ${na$me|${{va$lue}}}\n12${34}\n"; + + std::vector< mltoken_t > tokens = mltokenize(mlvalue); + std::vector< mltoken_t >::iterator i = tokens.begin(); + while(i != tokens.end()) { + printf("Token:\n"); + printf("\tType: "); + switch(i->type) { + case MLTT_VALUE: printf("VALUE\n"); break; + case MLTT_TEXT: printf("TEXT\n"); break; + case MLTT_ENDOFITEM: printf("ENDOFITEM\n"); break; + case MLTT_UNDEFINED: printf("UNDEFINED\n"); break; + } + printf("\tName: %s\n", i->name.c_str()); + printf("\tValue: %s\n", i->value.c_str()); + printf("\n"); + i++; + } + + return 0; +} + +#endif diff --git a/server/src/mltokenizer.h b/server/src/mltokenizer.h new file mode 100644 index 0000000..d784178 --- /dev/null +++ b/server/src/mltokenizer.h @@ -0,0 +1,55 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * mltokenizer.h + * + * Tue Nov 4 08:46:35 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_MLTOKENIZER_H__ +#define __PRACRO_MLTOKENIZER_H__ + +#include <string> +#include <vector> + +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; + +/** + * Split a multilist string into a sequence of tokens, eg. + * This is ${{}} some text ${myname|myvalue}\n + * MLTT_TEXT(value="This is ${{}} some text "), + * MLTT_VALUE(name="myname", value="myvalue"), + * MLTT_ENDOFITEM() + */ +std::vector< mltoken_t > mltokenize(std::string mlvalue); + +#endif/*__PRACRO_MLTOKENIZER_H__*/ |