From 402e94a76a9f01bc3b5cebee4d616e4121b4c5ff Mon Sep 17 00:00:00 2001 From: zelgadis Date: Thu, 6 Dec 2007 12:13:42 +0000 Subject: Database entries fetched with getLongDescription() can contain embeded Lua code. The code will be replaced with its return value before being displayed to the user. The Lua code has no access to the thing being described, and so can only rely on global data. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3011 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/database.cc | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'crawl-ref/source/database.cc') diff --git a/crawl-ref/source/database.cc b/crawl-ref/source/database.cc index fb695332ee..ff1b59bf2c 100644 --- a/crawl-ref/source/database.cc +++ b/crawl-ref/source/database.cc @@ -14,6 +14,8 @@ #include #include #include + +#include "clua.h" #include "database.h" #include "files.h" #include "libutil.h" @@ -211,6 +213,42 @@ std::vector database_find_bodies(DBM *database, /////////////////////////////////////////////////////////////////////////// // Internal DB utility functions +static void execute_embedded_lua(std::string &str) +{ + // Execute any lua code found between "{{" and "}}". The lua code + // is expected to return a string, with which the lua code and braces + // will be replaced. + std::string::size_type pos = str.find("{{"); + while (pos != std::string::npos) + { + std::string::size_type end = str.find("}}", pos + 2); + if (end == std::string::npos) + { + mpr("Unbalanced {{, bailing.", MSGCH_DIAGNOSTICS); + break; + } + + std::string lua_full = str.substr(pos, end - pos + 2); + std::string lua = str.substr(pos + 2, end - pos - 2); + + if (clua.execstring(lua.c_str(), "db_embedded_lua", 1)) + { + std::string err = "{{" + clua.error; + err += "}}"; + str.replace(pos, lua_full.length(), err); + + return; + } + + std::string result; + clua.fnreturns(">s", &result); + + str.replace(pos, lua_full.length(), result); + + pos = str.find("{{", pos + result.length()); + } // while (pos != std::string::npos) +} + static void trim_right(std::string &s) { s.erase(s.find_last_not_of(" \r\t\n") + 1); @@ -457,7 +495,10 @@ std::string getLongDescription(const std::string &key) datum result = database_fetch(descriptionDB, canonical_key); // Cons up a (C++) string to return. The caller must release it. - return std::string((const char *)result.dptr, result.dsize); + std::string str((const char *)result.dptr, result.dsize); + + execute_embedded_lua(str); + return (str); } std::vector getLongDescKeysByRegex(const std::string ®ex, -- cgit v1.2.3-54-g00ecf