[luci] [PATCH 3/4] libs/web: add support for string templates to the template parser

Matthias Schiffer mschiffer at universe-factory.net
Sun Jul 27 04:44:55 CEST 2014


Signed-off-by: Matthias Schiffer <mschiffer at universe-factory.net>
---
 modules/base/src/template_lualib.c | 24 +++++++++++++++++----
 modules/base/src/template_parser.c | 43 +++++++++++++++++++++++++++++++++-----
 modules/base/src/template_parser.h |  1 +
 3 files changed, 59 insertions(+), 9 deletions(-)

diff --git a/modules/base/src/template_lualib.c b/modules/base/src/template_lualib.c
index 0d43641..1035611 100644
--- a/modules/base/src/template_lualib.c
+++ b/modules/base/src/template_lualib.c
@@ -18,10 +18,8 @@
 
 #include "template_lualib.h"
 
-int template_L_parse(lua_State *L)
+static int template_L_do_parse(lua_State *L, struct template_parser *parser, const char *chunkname)
 {
-	const char *file = luaL_checkstring(L, 1);
-	struct template_parser *parser = template_open(file);
 	int lua_status, rv;
 
 	if (!parser)
@@ -32,7 +30,7 @@ int template_L_parse(lua_State *L)
 		return 3;
 	}
 
-	lua_status = lua_load(L, template_reader, parser, file);
+	lua_status = lua_load(L, template_reader, parser, chunkname);
 
 	if (lua_status == 0)
 		rv = 1;
@@ -44,6 +42,23 @@ int template_L_parse(lua_State *L)
 	return rv;
 }
 
+int template_L_parse(lua_State *L)
+{
+	const char *file = luaL_checkstring(L, 1);
+	struct template_parser *parser = template_open(file);
+
+	return template_L_do_parse(L, parser, file);
+}
+
+int template_L_parse_string(lua_State *L)
+{
+	size_t len;
+	const char *str = luaL_checklstring(L, 1, &len);
+	struct template_parser *parser = template_string(str, len);
+
+	return template_L_do_parse(L, parser, "[string]");
+}
+
 int template_L_utf8(lua_State *L)
 {
 	size_t len = 0;
@@ -146,6 +161,7 @@ static int template_L_hash(lua_State *L) {
 /* module table */
 static const luaL_reg R[] = {
 	{ "parse",				template_L_parse },
+	{ "parse_string",		template_L_parse_string },
 	{ "utf8",				template_L_utf8 },
 	{ "pcdata",				template_L_pcdata },
 	{ "striptags",			template_L_striptags },
diff --git a/modules/base/src/template_parser.c b/modules/base/src/template_parser.c
index 1aa5131..c263fbf 100644
--- a/modules/base/src/template_parser.c
+++ b/modules/base/src/template_parser.c
@@ -100,6 +100,36 @@ err:
 	return NULL;
 }
 
+struct template_parser * template_string(const char *str, uint32_t len)
+{
+	struct template_parser *parser;
+
+	if (!str) {
+		errno = EINVAL;
+		goto err;
+	}
+
+	if (!(parser = malloc(sizeof(*parser))))
+		goto err;
+
+	memset(parser, 0, sizeof(*parser));
+	parser->fd = -1;
+
+	parser->size = len;
+	parser->data = (char*)str;
+
+	parser->off = parser->data;
+	parser->cur_chunk.type = T_TYPE_INIT;
+	parser->cur_chunk.s    = parser->data;
+	parser->cur_chunk.e    = parser->data;
+
+	return parser;
+
+err:
+	template_close(parser);
+	return NULL;
+}
+
 void template_close(struct template_parser *parser)
 {
 	if (!parser)
@@ -108,11 +138,14 @@ void template_close(struct template_parser *parser)
 	if (parser->gc != NULL)
 		free(parser->gc);
 
-	if ((parser->data != NULL) && (parser->data != MAP_FAILED))
-		munmap(parser->data, parser->size);
+	/* if file is not set, we were parsing a string */
+	if (parser->file) {
+		if ((parser->data != NULL) && (parser->data != MAP_FAILED))
+			munmap(parser->data, parser->size);
 
-	if (parser->fd >= 0)
-		close(parser->fd);
+		if (parser->fd >= 0)
+			close(parser->fd);
+	}
 
 	free(parser);
 }
@@ -376,7 +409,7 @@ int template_error(lua_State *L, struct template_parser *parser)
 			line++;
 
 	snprintf(msg, sizeof(msg), "Syntax error in %s:%d: %s",
-			 parser->file, line + chunkline, err ? err : "(unknown error)");
+			 parser->file ? parser->file : "[string]", line + chunkline, err ? err : "(unknown error)");
 
 	lua_pushnil(L);
 	lua_pushinteger(L, line + chunkline);
diff --git a/modules/base/src/template_parser.h b/modules/base/src/template_parser.h
index ad03cbc..a3200a2 100644
--- a/modules/base/src/template_parser.h
+++ b/modules/base/src/template_parser.h
@@ -71,6 +71,7 @@ struct template_parser {
 };
 
 struct template_parser * template_open(const char *file);
+struct template_parser * template_string(const char *str, uint32_t len);
 void template_close(struct template_parser *parser);
 
 const char *template_reader(lua_State *L, void *ud, size_t *sz);
-- 
2.0.3



More information about the luci mailing list