Initial revision of lua 'doc' function
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
#include "source.hpp"
|
||||
#include "luasnap.hpp"
|
||||
|
||||
LuaDefine(source_makeclass, "f") {
|
||||
LuaDefine(makeclass, "classname", "create a class if it doesn't already exist") {
|
||||
LuaArg classname;
|
||||
LuaRet classtab;
|
||||
LuaStack LS(L, classname, classtab);
|
||||
@@ -23,7 +23,7 @@ LuaDefine(source_makeclass, "f") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(source_classname, "f") {
|
||||
LuaDefine(classname, "classtable", "get the class name from a class table") {
|
||||
LuaArg table;
|
||||
LuaRet result;
|
||||
LuaStack LS(L, table, result);
|
||||
@@ -36,7 +36,7 @@ LuaDefine(source_classname, "f") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(source_maketangible, "f") {
|
||||
LuaDefine(maketangible, "classname", "create a class if it doesn't already exist, and add tangible features") {
|
||||
LuaArg classname;
|
||||
LuaRet classtab;
|
||||
LuaVar subtab;
|
||||
@@ -46,6 +46,18 @@ LuaDefine(source_maketangible, "f") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
static void get_reg_name(const LuaFunctionReg *reg, std::string &classname, std::string &funcname) {
|
||||
std::string name = reg->get_name();
|
||||
size_t upos = name.find('_');
|
||||
if (upos == std::string::npos) {
|
||||
funcname = name;
|
||||
classname = "";
|
||||
} else {
|
||||
funcname = name.substr(upos + 1);
|
||||
classname = name.substr(0, upos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// the 'luaopen' function creates a new table.
|
||||
//
|
||||
@@ -299,25 +311,16 @@ static void source_load_cfunctions(lua_State *L) {
|
||||
LuaStack LS(L, classobj);
|
||||
auto regs = LuaFunctionReg::all();
|
||||
for (const LuaFunctionReg *r : regs) {
|
||||
const std::string &name = r->get_name();
|
||||
size_t upos = name.find('_');
|
||||
lua_CFunction func = r->get_func();
|
||||
std::string classname;
|
||||
std::string funcname;
|
||||
if (upos == std::string::npos) {
|
||||
continue;
|
||||
} else {
|
||||
funcname = name.substr(upos + 1);
|
||||
classname = name.substr(0, upos);
|
||||
}
|
||||
lua_CFunction func = r->get_func();
|
||||
std::string mode = r->get_mode();
|
||||
if (mode.find('c') != std::string::npos) { // Insert into class
|
||||
LS.makeclass(classobj, classname);
|
||||
LS.rawset(classobj, funcname, func);
|
||||
}
|
||||
if (mode.find('f') != std::string::npos) { // Make global function
|
||||
get_reg_name(r, classname, funcname);
|
||||
if (classname.empty()) {
|
||||
LS.getglobaltable(classobj);
|
||||
LS.rawset(classobj, funcname, func);
|
||||
} else {
|
||||
LS.makeclass(classobj, classname);
|
||||
LS.rawset(classobj, funcname, func);
|
||||
}
|
||||
}
|
||||
LS.result();
|
||||
@@ -465,8 +468,80 @@ void SourceDB::deserialize_source(util::LuaSourceVec *sv, StreamBuffer *sb) {
|
||||
}
|
||||
}
|
||||
|
||||
std::string SourceDB::function_docs(const LuaStack &LS0, LuaSlot fn) {
|
||||
lua_State *L = LS0.state();
|
||||
LuaVar sourcedb, fname, finfo, code;
|
||||
LuaStack LS(L, sourcedb, fname, finfo, code);
|
||||
|
||||
if (LS.iscfunction(fn)) {
|
||||
lua_CFunction cfn = lua_tocfunction(L, fn.index());
|
||||
const LuaFunctionReg *reg = LuaFunctionReg::lookup(cfn);
|
||||
if (reg == nullptr) {
|
||||
return "";
|
||||
}
|
||||
std::string classname;
|
||||
std::string funcname;
|
||||
get_reg_name(reg, classname, funcname);
|
||||
std::ostringstream oss;
|
||||
util::StringVec docs = util::split_lines(reg->get_docs());
|
||||
for (const std::string &line : docs) {
|
||||
oss << "-- " << line << std::endl;
|
||||
}
|
||||
oss << "function ";
|
||||
if (!classname.empty()) {
|
||||
oss << classname << ".";
|
||||
}
|
||||
oss << funcname << "(" << reg->get_args() << ")";
|
||||
return oss.str();
|
||||
} else if (LS.isfunction(fn)) {
|
||||
lua_Debug ar;
|
||||
lua_pushvalue(L, fn.index());
|
||||
int status = lua_getinfo(L, ">S", &ar);
|
||||
if (status == 0) return "";
|
||||
|
||||
// Get the source database.
|
||||
LS.rawget(sourcedb, LuaRegistry, "sourcedb");
|
||||
if (!LS.istable(sourcedb)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// Get the finfo table from the source db.
|
||||
LS.set(fname, std::string(ar.short_src));
|
||||
LS.rawget(finfo, sourcedb, fname);
|
||||
if (!LS.istable(finfo)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// Get the code from the finfo table.
|
||||
LS.rawget(code, finfo, "code");
|
||||
if (!LS.isstring(code)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// Split the code into lines.
|
||||
util::StringVec lines = util::split_lines(LS.ckstring(code));
|
||||
int linehi = ar.linedefined - 1;
|
||||
if ((linehi < 0) || (linehi >= int(lines.size()))) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// Incorporate the function comment.
|
||||
int linelo = linehi;
|
||||
while ((linelo > 0) && (util::is_lua_comment(lines[linelo-1]))) linelo -= 1;
|
||||
|
||||
// Output the docs.
|
||||
std::ostringstream result;
|
||||
for (int i = linelo; i <= linehi; i++) {
|
||||
result << lines[i] << std::endl;
|
||||
}
|
||||
return result.str();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// These should go away eventually. They're for debugging.
|
||||
LuaDefine(coroutine_setnextid, "c") {
|
||||
LuaDefine(coroutine_setnextid, "thread,id", "set the next id of a thread (debugging only)") {
|
||||
LuaArg co, lid;
|
||||
LuaStack LS(L, co, lid);
|
||||
lua_State *CO = LS.ckthread(co);
|
||||
@@ -475,7 +550,7 @@ LuaDefine(coroutine_setnextid, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(coroutine_getnextid, "c") {
|
||||
LuaDefine(coroutine_getnextid, "thread", "get the next id of a thread (debugging only)") {
|
||||
LuaArg co;
|
||||
LuaRet lid;
|
||||
LuaStack LS(L, co, lid);
|
||||
@@ -484,7 +559,7 @@ LuaDefine(coroutine_getnextid, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(unittests_sourcedb, "c") {
|
||||
LuaDefine(unittests_sourcedb, "", "some unit tests") {
|
||||
LuaSnap msnap;
|
||||
LuaSnap ssnap;
|
||||
SourceDB mdb;
|
||||
|
||||
Reference in New Issue
Block a user