summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2013-12-30 11:21:45 (GMT)
committerRemko Tronçon <git@el-tramo.be>2014-01-03 11:09:06 (GMT)
commit26bb5aa9e2f520c3c943797e6143c32e5b16806b (patch)
tree0caa41938acf53da946847f8803c62e579525af9 /Sluift/Lua
parent0b19dc7292b7672c9fbb711a411c392bc5b2bb34 (diff)
downloadswift-26bb5aa9e2f520c3c943797e6143c32e5b16806b.zip
swift-26bb5aa9e2f520c3c943797e6143c32e5b16806b.tar.bz2
Sluift: Add help support
Provide a 'help' function that takes a table/function, and prints help for it. A structured representation can be retrieved through 'get_help'. Change-Id: I2b3ce8992943ef30cee2604fba9200feed263fa5
Diffstat (limited to 'Sluift/Lua')
-rw-r--r--Sluift/Lua/Check.cpp8
-rw-r--r--Sluift/Lua/Check.h6
-rw-r--r--Sluift/Lua/FunctionRegistration.cpp4
-rw-r--r--Sluift/Lua/FunctionRegistration.h13
-rw-r--r--Sluift/Lua/FunctionRegistry.cpp27
-rw-r--r--Sluift/Lua/FunctionRegistry.h9
-rw-r--r--Sluift/Lua/LuaUtils.cpp101
-rw-r--r--Sluift/Lua/LuaUtils.h4
8 files changed, 142 insertions, 30 deletions
diff --git a/Sluift/Lua/Check.cpp b/Sluift/Lua/Check.cpp
index cfb726a..65ada7b 100644
--- a/Sluift/Lua/Check.cpp
+++ b/Sluift/Lua/Check.cpp
@@ -43,7 +43,7 @@ std::string Lua::checkString(lua_State* L, int arg) {
return std::string(s);
}
-void* Lua::checkUserDataRaw(lua_State* L, int arg, const char* tableName) {
+void* Lua::checkUserDataRaw(lua_State* L, int arg) {
void* userData = lua_touserdata(L, arg);
if (!userData) {
throw Lua::Exception(getArgTypeError(L, arg, LUA_TUSERDATA));
@@ -51,10 +51,6 @@ void* Lua::checkUserDataRaw(lua_State* L, int arg, const char* tableName) {
if (!lua_getmetatable(L, arg)) {
throw Lua::Exception(getArgTypeError(L, arg, LUA_TUSERDATA));
}
- lua_getfield(L, LUA_REGISTRYINDEX, tableName);
- if (!lua_rawequal(L, -1, -2)) {
- throw Lua::Exception(getArgTypeError(L, arg, LUA_TUSERDATA));
- }
- lua_pop(L, 2);
+ lua_pop(L, 1);
return userData;
}
diff --git a/Sluift/Lua/Check.h b/Sluift/Lua/Check.h
index a569826..8a8b64a 100644
--- a/Sluift/Lua/Check.h
+++ b/Sluift/Lua/Check.h
@@ -16,11 +16,11 @@ namespace Swift {
int checkIntNumber(lua_State* L, int arg);
std::string checkString(lua_State* L, int arg);
- void* checkUserDataRaw(lua_State* L, int arg, const char* tableName);
+ void* checkUserDataRaw(lua_State* L, int arg);
template<typename T>
- T** checkUserData(lua_State* L, int arg, const char* tableName) {
- return reinterpret_cast<T**>(checkUserDataRaw(L, arg, tableName));
+ T** checkUserData(lua_State* L, int arg) {
+ return reinterpret_cast<T**>(checkUserDataRaw(L, arg));
}
}
}
diff --git a/Sluift/Lua/FunctionRegistration.cpp b/Sluift/Lua/FunctionRegistration.cpp
index b773952..ddfa1f0 100644
--- a/Sluift/Lua/FunctionRegistration.cpp
+++ b/Sluift/Lua/FunctionRegistration.cpp
@@ -8,8 +8,8 @@
using namespace Swift::Lua;
-FunctionRegistration::FunctionRegistration(const std::string& name, lua_CFunction function, const std::string& type) {
- FunctionRegistry::getInstance().addFunction(name, function, type);
+FunctionRegistration::FunctionRegistration(const std::string& name, lua_CFunction function, const std::string& type, const std::string& helpDescription, const std::string& helpParameters, const std::string& helpOptions) {
+ FunctionRegistry::getInstance().addFunction(name, function, type, helpDescription, helpParameters, helpOptions);
}
FunctionRegistration::~FunctionRegistration() {
diff --git a/Sluift/Lua/FunctionRegistration.h b/Sluift/Lua/FunctionRegistration.h
index 0df1da1..74269e2 100644
--- a/Sluift/Lua/FunctionRegistration.h
+++ b/Sluift/Lua/FunctionRegistration.h
@@ -16,15 +16,19 @@ namespace Swift {
namespace Lua {
class FunctionRegistration {
public:
- FunctionRegistration(const std::string& name, lua_CFunction function, const std::string& type);
+ FunctionRegistration(
+ const std::string& name, lua_CFunction function, const std::string& type,
+ const std::string& helpDescription, const std::string& helpParameters, const std::string& helpOptions);
~FunctionRegistration();
};
}
}
-#define SLUIFT_LUA_FUNCTION(TYPE, NAME) \
+
+
+#define SLUIFT_LUA_FUNCTION_WITH_HELP(TYPE, NAME, HELP_DESCRIPTION, HELP_PARAMETERS, HELP_OPTIONS) \
static int TYPE##_##NAME(lua_State* L); \
static int TYPE##_##NAME##_wrapper(lua_State* L); \
- static ::Swift::Lua::FunctionRegistration TYPE##_##NAME##_registration( #NAME , TYPE##_##NAME##_wrapper, #TYPE); \
+ static ::Swift::Lua::FunctionRegistration TYPE##_##NAME##_registration( #NAME , TYPE##_##NAME##_wrapper, #TYPE, HELP_DESCRIPTION, HELP_PARAMETERS, HELP_OPTIONS); \
static int TYPE##_##NAME##_wrapper(lua_State* L) { \
try { \
return TYPE ## _ ## NAME (L); \
@@ -34,3 +38,6 @@ namespace Swift {
} \
} \
static int TYPE ## _ ## NAME (lua_State* L)
+
+#define SLUIFT_LUA_FUNCTION(TYPE, NAME) \
+ SLUIFT_LUA_FUNCTION_WITH_HELP(TYPE, NAME, "", "", "")
diff --git a/Sluift/Lua/FunctionRegistry.cpp b/Sluift/Lua/FunctionRegistry.cpp
index 99ea096..df24d9c 100644
--- a/Sluift/Lua/FunctionRegistry.cpp
+++ b/Sluift/Lua/FunctionRegistry.cpp
@@ -7,6 +7,9 @@
#include <Sluift/Lua/FunctionRegistry.h>
#include <Swiften/Base/foreach.h>
+#include <Sluift/Lua/LuaUtils.h>
+#include <Sluift/Lua/Exception.h>
+#include <Sluift/globals.h>
using namespace Swift::Lua;
@@ -21,25 +24,19 @@ FunctionRegistry& FunctionRegistry::getInstance() {
return instance;
}
-void FunctionRegistry::addFunction(const std::string& name, lua_CFunction function, const std::string& type) {
+void FunctionRegistry::addFunction(
+ const std::string& name, lua_CFunction function, const std::string& type,
+ const std::string& helpDescription, const std::string& helpParameters, const std::string& helpOptions) {
Registration registration;
registration.name = name;
registration.function = function;
registration.type = type;
+ registration.helpDescription = helpDescription;
+ registration.helpParameters = helpParameters;
+ registration.helpOptions = helpOptions;
registrations.push_back(registration);
}
-std::string FunctionRegistry::getMetaTableNameForType(const std::string& type) {
- return "Sluift_" + type;
-}
-
-void FunctionRegistry::registerTypeMetaTable(lua_State* L, const std::string& type) {
- luaL_newmetatable(L, getMetaTableNameForType(type).c_str());
- lua_pushvalue(L, -1);
- lua_setfield(L, -2, "__index");
- addFunctionsToTable(L, type);
-}
-
void FunctionRegistry::createFunctionTable(lua_State* L, const std::string& type) {
lua_newtable(L);
addFunctionsToTable(L, type);
@@ -49,6 +46,12 @@ void FunctionRegistry::addFunctionsToTable(lua_State* L, const std::string& type
foreach(const Registration& registration, registrations) {
if (registration.type == type) {
lua_pushcclosure(L, registration.function, 0);
+ if (!registration.helpDescription.empty()) {
+ Lua::registerHelp(L, -1, registration.helpDescription, registration.helpParameters, registration.helpOptions);
+ }
+ else {
+ Lua::registerExtraHelp(L, -1, registration.type + "." + registration.name);
+ }
lua_setfield(L, -2, registration.name.c_str());
}
}
diff --git a/Sluift/Lua/FunctionRegistry.h b/Sluift/Lua/FunctionRegistry.h
index e3ad620..b20108d 100644
--- a/Sluift/Lua/FunctionRegistry.h
+++ b/Sluift/Lua/FunctionRegistry.h
@@ -18,10 +18,8 @@ namespace Swift {
~FunctionRegistry();
static FunctionRegistry& getInstance();
- void addFunction(const std::string& name, lua_CFunction function, const std::string& type);
-
- static std::string getMetaTableNameForType(const std::string& type);
- void registerTypeMetaTable(lua_State* L, const std::string& type);
+ void addFunction(const std::string& name, lua_CFunction function, const std::string& type,
+ const std::string& helpDescription, const std::string& helpParameters, const std::string& helpOptions);
void createFunctionTable(lua_State* L, const std::string& type);
@@ -39,6 +37,9 @@ namespace Swift {
std::string name;
lua_CFunction function;
std::string type;
+ std::string helpDescription;
+ std::string helpParameters;
+ std::string helpOptions;
};
std::vector<Registration> registrations;
};
diff --git a/Sluift/Lua/LuaUtils.cpp b/Sluift/Lua/LuaUtils.cpp
index b00ab56..2192689 100644
--- a/Sluift/Lua/LuaUtils.cpp
+++ b/Sluift/Lua/LuaUtils.cpp
@@ -14,6 +14,7 @@
#include <cassert>
#include <sstream>
#include <boost/numeric/conversion/cast.hpp>
+#include <boost/algorithm/string/trim.hpp>
#include <Sluift/globals.h>
using namespace Swift::Lua;
@@ -77,3 +78,103 @@ boost::optional<int> Swift::Lua::getIntField(lua_State* L, int index, const std:
lua_pop(L, 1);
return result;
}
+
+void Swift::Lua::registerHelp(lua_State* L, int index, const std::string& description, const std::string& parameters, const std::string& options) {
+ index = Lua::absoluteOffset(L, index);
+ lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.coreLibIndex);
+ lua_getfield(L, -1, "register_help");
+ lua_pushvalue(L, index);
+
+ lua_newtable(L);
+ lua_pushstring(L, description.c_str());
+ lua_rawseti(L, -2, 1);
+
+ if (!parameters.empty()) {
+ std::istringstream s(parameters);
+ lua_newtable(L);
+ int i = 1;
+ for (std::string line; std::getline(s, line); ) {
+ std::string trimmedLine = boost::trim_copy(line);
+ if (trimmedLine.empty()) {
+ continue;
+ }
+ size_t splitIndex = trimmedLine.find_first_of(" \t");
+ std::string key;
+ std::string value;
+ if (splitIndex == std::string::npos) {
+ key = trimmedLine;
+ }
+ else {
+ key = trimmedLine.substr(0, splitIndex);
+ value = boost::trim_copy(trimmedLine.substr(splitIndex+1));
+ }
+ lua_createtable(L, 2, 0);
+ lua_pushstring(L, key.c_str());
+ lua_rawseti(L, -2, 1);
+ lua_pushstring(L, value.c_str());
+ lua_rawseti(L, -2, 2);
+
+ lua_rawseti(L, -2, i++);
+ }
+ lua_setfield(L, -2, "parameters");
+ }
+ if (!options.empty()) {
+ std::istringstream s(options);
+ lua_newtable(L);
+ for (std::string line; std::getline(s, line); ) {
+ std::string trimmedLine = boost::trim_copy(line);
+ if (trimmedLine.empty()) {
+ continue;
+ }
+ size_t splitIndex = trimmedLine.find_first_of(" \t");
+ std::string key;
+ std::string value;
+ if (splitIndex == std::string::npos) {
+ key = trimmedLine;
+ }
+ else {
+ key = trimmedLine.substr(0, splitIndex);
+ value = boost::trim_copy(trimmedLine.substr(splitIndex+1));
+ }
+ lua_pushstring(L, value.c_str());
+ lua_setfield(L, -2, key.c_str());
+ }
+ lua_setfield(L, -2, "options");
+ }
+
+ if (lua_pcall(L, 2, 0, 0) != 0) {
+ throw Lua::Exception(lua_tostring(L, -1));
+ }
+ lua_pop(L, 1);
+}
+
+void Swift::Lua::registerClassHelp(lua_State* L, const std::string& name, const std::string& description) {
+ lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.coreLibIndex);
+ lua_getfield(L, -1, "register_class_help");
+ lua_pushstring(L, name.c_str());
+
+ lua_newtable(L);
+ lua_pushstring(L, description.c_str());
+ lua_rawseti(L, -2, 1);
+
+ if (lua_pcall(L, 2, 0, 0) != 0) {
+ throw Lua::Exception(lua_tostring(L, -1));
+ }
+ lua_pop(L, 1);
+}
+
+void Swift::Lua::registerExtraHelp(lua_State* L, int index, const std::string& name) {
+ index = Lua::absoluteOffset(L, index);
+ lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.coreLibIndex);
+ lua_getfield(L, -1, "extra_help");
+ lua_getfield(L, -1, name.c_str());
+ if (!lua_isnil(L, -1)) {
+ lua_getfield(L, -3, "register_help");
+ lua_pushvalue(L, index);
+ lua_pushvalue(L, -3);
+ if (lua_pcall(L, 2, 0, 0) != 0) {
+ throw Lua::Exception(lua_tostring(L, -1));
+ }
+ }
+ lua_pop(L, 3);
+}
diff --git a/Sluift/Lua/LuaUtils.h b/Sluift/Lua/LuaUtils.h
index f677307..19ab74e 100644
--- a/Sluift/Lua/LuaUtils.h
+++ b/Sluift/Lua/LuaUtils.h
@@ -24,6 +24,10 @@ namespace Swift {
void registerTableToString(lua_State* L, int index);
void registerGetByTypeIndex(lua_State* L, int index);
+ void registerHelp(lua_State* L, int index,
+ const std::string& description, const std::string& parameters, const std::string& options);
+ void registerClassHelp(lua_State* L, const std::string& name, const std::string& description);
+ void registerExtraHelp(lua_State* L, int index, const std::string& name);
inline int absoluteOffset(lua_State* L, int index) {
return index > 0 ? index : lua_gettop(L) + index + 1;