Initial revision of lua 'doc' function
This commit is contained in:
@@ -576,7 +576,7 @@ static bool diff_works(const AnimQueue &master, AnimQueue &sync) {
|
||||
return sync.size_and_steps_equal(master);
|
||||
}
|
||||
|
||||
LuaDefine(unittests_animqueue, "c") {
|
||||
LuaDefine(unittests_animqueue, "", "some unit tests") {
|
||||
// Useful objects.
|
||||
AnimStep stp;
|
||||
AnimQueue aq(util::WORLD_TYPE_MASTER);
|
||||
|
||||
@@ -2,14 +2,7 @@
|
||||
#include "globaldb.hpp"
|
||||
|
||||
|
||||
// Get a table from the global database.
|
||||
//
|
||||
// GLOBALNAME
|
||||
// if globalname is already present, and is a table, return it.
|
||||
// if globalname is already present, and not a table, error.
|
||||
// if globalname is not present, create and initialize it.
|
||||
//
|
||||
LuaDefine(globaldb_global, "f") {
|
||||
LuaDefine(global, "globalname", "get a table where global data can be stored") {
|
||||
LuaArg globalname;
|
||||
LuaRet globaltab;
|
||||
LuaVar globaldb;
|
||||
|
||||
@@ -52,7 +52,7 @@ std::string Gui::menu_debug_string() const {
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
LuaDefine(gui_menu_item, "c") {
|
||||
LuaDefine(gui_menu_item, "action,label", "add a menu item to the current gui") {
|
||||
Gui *gui = Gui::fetch_global_pointer(L);
|
||||
LuaArg laction, llabel;
|
||||
LuaStack LS(L, laction, llabel);
|
||||
|
||||
@@ -250,7 +250,7 @@ static int64_t nthbatch(int64_t n) {
|
||||
return int64_t(0x0001000000000000) + n*256;
|
||||
}
|
||||
|
||||
LuaDefine(unittests_idalloc, "c") {
|
||||
LuaDefine(unittests_idalloc, "", "some unit tests") {
|
||||
IdGlobalPool gp;
|
||||
IdPlayerPool pp(&gp);
|
||||
IdGlobalPool gpds;
|
||||
|
||||
@@ -6,9 +6,10 @@ LuaSpecial LuaRegistry(LUA_REGISTRYINDEX);
|
||||
LuaNilMarker LuaNil;
|
||||
LuaNewTableMarker LuaNewTable;
|
||||
|
||||
LuaFunctionReg::LuaFunctionReg(const char *m, const char *n, lua_CFunction f) {
|
||||
mode_ = m;
|
||||
LuaFunctionReg::LuaFunctionReg(const char *n, const char *a, const char *d, lua_CFunction f) {
|
||||
name_ = n;
|
||||
args_ = a;
|
||||
docs_ = d;
|
||||
func_ = f;
|
||||
next_ = LuaFunctionRegistry;
|
||||
LuaFunctionRegistry = this;
|
||||
@@ -22,6 +23,15 @@ LuaFunctionReg::List LuaFunctionReg::all() {
|
||||
return result;
|
||||
}
|
||||
|
||||
const LuaFunctionReg *LuaFunctionReg::lookup(lua_CFunction fn) {
|
||||
for (const LuaFunctionReg *r = LuaFunctionRegistry; r != 0; r = r->next_) {
|
||||
if (r->func_ == fn) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LuaFunctionReg *LuaFunctionReg::LuaFunctionRegistry;
|
||||
|
||||
bool LuaStack::issortablekey(LuaSlot s) const {
|
||||
@@ -350,6 +360,31 @@ int LuaStack::rawlen(LuaSlot obj) const {
|
||||
return lua_rawlen(L_, obj.index());
|
||||
}
|
||||
|
||||
std::string LuaStack::get_function_name(LuaSlot fn) {
|
||||
LuaVar globals, key, val, skey, sval;
|
||||
LuaStack LS(L_, globals, key, val, skey, sval);
|
||||
LS.getglobaltable(globals);
|
||||
LS.set(key, LuaNil);
|
||||
while (LS.next(globals, key, val)) {
|
||||
if (LS.isstring(key)) {
|
||||
if (LS.rawequal(val, fn)) {
|
||||
return LS.ckstring(key);
|
||||
}
|
||||
if (LS.istable(val)) {
|
||||
LS.set(skey, LuaNil);
|
||||
while (LS.next(val, skey, sval)) {
|
||||
if (LS.isstring(skey) && LS.rawequal(sval, fn)) {
|
||||
std::string n1 = LS.ckstring(key);
|
||||
std::string n2 = LS.ckstring(skey);
|
||||
return n1 + "." + n2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
int LuaStack::gettabletype(LuaSlot tab) const {
|
||||
uint16_t bits = lua_getflagbits(L_, tab.index());
|
||||
return LUA_TT_GENERAL + (bits & 0x000F);
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
// exposed to lua. It creates a global registry of functions
|
||||
// created with LuaDefine. You use it like so:
|
||||
//
|
||||
// LuaDefine(function_name, "modebits") {
|
||||
// LuaDefine(function_name, "arguments", "documentation") {
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
@@ -450,6 +450,9 @@ public:
|
||||
lua_rawseti(L_, tab, key);
|
||||
}
|
||||
|
||||
// Get function name
|
||||
std::string get_function_name(LuaSlot ls);
|
||||
|
||||
// Lua flagbits manipulation: Table types.
|
||||
int gettabletype(LuaSlot tab) const;
|
||||
void settabletype(LuaSlot tab, int t) const;
|
||||
@@ -466,8 +469,9 @@ public:
|
||||
|
||||
class LuaFunctionReg {
|
||||
private:
|
||||
const char *mode_;
|
||||
const char *name_;
|
||||
const char *args_;
|
||||
const char *docs_;
|
||||
lua_CFunction func_;
|
||||
LuaFunctionReg *next_;
|
||||
|
||||
@@ -476,18 +480,20 @@ private:
|
||||
public:
|
||||
using List = std::vector<const LuaFunctionReg *>;
|
||||
|
||||
LuaFunctionReg(const char *mode, const char *n, lua_CFunction f);
|
||||
LuaFunctionReg(const char *name, const char *args, const char *docs, lua_CFunction f);
|
||||
static List all();
|
||||
static const LuaFunctionReg *lookup(lua_CFunction fn);
|
||||
|
||||
const char *get_mode() const { return mode_; }
|
||||
const char *get_name() const { return name_; }
|
||||
const char *get_args() const { return args_; }
|
||||
const char *get_docs() const { return docs_; }
|
||||
lua_CFunction get_func() const { return func_; }
|
||||
};
|
||||
|
||||
|
||||
#define LuaDefine(name, mode) \
|
||||
#define LuaDefine(name, args, docs) \
|
||||
int lfn_##name(lua_State *L); \
|
||||
LuaFunctionReg reg_##name(mode, #name, lfn_##name); \
|
||||
LuaFunctionReg reg_##name(#name, args, docs, lfn_##name); \
|
||||
int lfn_##name(lua_State *L)
|
||||
|
||||
|
||||
|
||||
@@ -201,7 +201,7 @@ PlaneMap::IdVector PlaneMap::scan_radius(const std::string &plane, float x, floa
|
||||
return result;
|
||||
}
|
||||
|
||||
LuaDefine(unittests_planemap, "c") {
|
||||
LuaDefine(unittests_planemap, "", "some unit tests") {
|
||||
float SC = CELL_SCALE;
|
||||
float E = CELL_SCALE * 0.4;
|
||||
int LO = -CELL_LIMIT;
|
||||
|
||||
@@ -5,14 +5,19 @@
|
||||
#include <iostream>
|
||||
|
||||
|
||||
void atomic_print(LuaStack &LS, LuaSlot val, std::ostream *os) {
|
||||
switch (LS.type(val)) {
|
||||
void atomic_print(LuaStack &LS, LuaSlot val, bool quote, std::ostream *os) {
|
||||
int tt = LS.type(val);
|
||||
switch (tt) {
|
||||
case LUA_TNIL:
|
||||
(*os) << "nil";
|
||||
return;
|
||||
case LUA_TSTRING:
|
||||
// TODO: this could be more efficient.
|
||||
(*os) << LS.ckstring(val);
|
||||
if (quote) {
|
||||
util::quote_string(LS.ckstring(val), os);
|
||||
} else {
|
||||
// TODO: this could be more efficient.
|
||||
(*os) << LS.ckstring(val);
|
||||
}
|
||||
return;
|
||||
case LUA_TNUMBER: {
|
||||
double value = LS.cknumber(val);
|
||||
@@ -27,38 +32,18 @@ void atomic_print(LuaStack &LS, LuaSlot val, std::ostream *os) {
|
||||
case LUA_TBOOLEAN:
|
||||
(*os) << (LS.ckboolean(val) ? "true" : "false");
|
||||
return;
|
||||
case LUA_TTABLE:
|
||||
(*os) << "table";
|
||||
return;
|
||||
default:
|
||||
(*os) << "unknown";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static bool string_quote(LuaStack &LS, LuaSlot val, std::ostream *os) {
|
||||
switch (LS.type(val)) {
|
||||
case LUA_TNIL:
|
||||
(*os) << "nil";
|
||||
return true;
|
||||
case LUA_TSTRING:
|
||||
util::quote_string(LS.ckstring(val), os);
|
||||
return true;
|
||||
case LUA_TNUMBER: {
|
||||
double value = LS.cknumber(val);
|
||||
int64_t ivalue = int64_t(value);
|
||||
if (double(ivalue) == value) {
|
||||
(*os) << ivalue;
|
||||
case LUA_TFUNCTION: {
|
||||
std::string name = LS.get_function_name(val);
|
||||
if (name.empty()) {
|
||||
(*os) << "<fn>";
|
||||
} else {
|
||||
(*os) << value;
|
||||
(*os) << "<fn." << name << ">";
|
||||
}
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
case LUA_TBOOLEAN:
|
||||
(*os) << (LS.ckboolean(val) ? "true" : "false");
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
(*os) << "<" << lua_typename(LS.state(), tt) << ">";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +90,7 @@ static void findtables(LuaStack &LS0, LuaSlot root, LuaSlot tabcount) {
|
||||
LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(table_findtables, "c") {
|
||||
LuaDefine(table_findtables, "root", "recursively find tables (debugging only)") {
|
||||
LuaArg root;
|
||||
LuaRet tabcount;
|
||||
LuaStack LS(L, root, tabcount);
|
||||
@@ -140,16 +125,9 @@ static void pprint_r(Inspector &insp, int level, LuaSlot root) {
|
||||
LuaVar idv, pairs, key, val;
|
||||
LuaStack LS(insp.L, idv, pairs, key, val);
|
||||
|
||||
// If it's a simple type, print it quoted.
|
||||
if (string_quote(LS, root, insp.stream)) {
|
||||
LS.result();
|
||||
return;
|
||||
}
|
||||
|
||||
// If it's not a table, just print the typename.
|
||||
int t = LS.type(root);
|
||||
if (t != LUA_TTABLE) {
|
||||
(*insp.stream) << "<" << lua_typename(insp.L, t) << ">";
|
||||
// If it's anything but a table, use 'atomic_print'.
|
||||
if (!LS.istable(root)) {
|
||||
atomic_print(LS, root, true, insp.stream);
|
||||
LS.result();
|
||||
return;
|
||||
}
|
||||
@@ -272,7 +250,7 @@ void pprint(LuaStack &LS0, LuaSlot root, bool indent, std::ostream *os) {
|
||||
LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(string_isidentifier, "c") {
|
||||
LuaDefine(string_isidentifier, "str", "return true if the string is a valid lua identifier") {
|
||||
LuaArg str;
|
||||
LuaRet result;
|
||||
LuaStack LS(L, str, result);
|
||||
@@ -285,17 +263,17 @@ LuaDefine(string_isidentifier, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(string_print, "c") {
|
||||
LuaDefine(string_print, "obj", "print the specified object into a string") {
|
||||
LuaArg val;
|
||||
LuaRet result;
|
||||
LuaStack LS(L, val, result);
|
||||
std::ostringstream oss;
|
||||
atomic_print(LS, val, &oss);
|
||||
atomic_print(LS, val, false, &oss);
|
||||
LS.set(result, oss.str());
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(string_pprint, "c") {
|
||||
LuaDefine(string_pprint, "obj,indent", "pretty-print the specified object into a string") {
|
||||
LuaArg root, indent;
|
||||
LuaRet result;
|
||||
LuaStack LS(L, root, indent, result);
|
||||
@@ -306,12 +284,12 @@ LuaDefine(string_pprint, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(string_tostring, "f") {
|
||||
LuaDefine(tostring, "obj", "print the specified object into a string") {
|
||||
LuaArg val;
|
||||
LuaRet result;
|
||||
LuaStack LS(L, val, result);
|
||||
std::ostringstream oss;
|
||||
atomic_print(LS, val, &oss);
|
||||
atomic_print(LS, val, false, &oss);
|
||||
LS.set(result, oss.str());
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
@@ -24,19 +24,13 @@
|
||||
// Atomic print to a stream.
|
||||
//
|
||||
// This prints an atomic value to a stream. If you give it a table,
|
||||
// it just prints "table". This routine is the heart of the lua
|
||||
// it just prints "<table>". This routine is the heart of the lua
|
||||
// primitives 'print' and 'tostring'.
|
||||
//
|
||||
void atomic_print(LuaStack &LS, LuaSlot val, std::ostream *os);
|
||||
void atomic_print(LuaStack &LS, LuaSlot val, bool quote, std::ostream *os);
|
||||
|
||||
// Pretty print to a stream.
|
||||
//
|
||||
// If indent is >=0, the output is indented. If indent<0, then
|
||||
// the output is emitted without newlines or indentation.
|
||||
//
|
||||
// Maxlen specifies the maximum number of characters output. If
|
||||
// this is exceeded, then the printout is truncated.
|
||||
//
|
||||
void pprint(LuaStack &LS, LuaSlot val, bool indent, std::ostream *os);
|
||||
|
||||
#endif // PPRINT_HPP
|
||||
@@ -189,7 +189,7 @@ Invocation PrintChanneler::invocation(int64_t actor_id) {
|
||||
return Invocation(Invocation::KIND_FLUSH_PRINTS, actor_id, actor_id, std::to_string(line_), InvocationData());
|
||||
}
|
||||
|
||||
LuaDefine(unittests_printbuffer, "c") {
|
||||
LuaDefine(unittests_printbuffer, "", "some unit tests") {
|
||||
PrintBuffer pbm;
|
||||
PrintBuffer pbs;
|
||||
StreamBuffer sb;
|
||||
|
||||
@@ -64,7 +64,7 @@ void Schedule::deserialize(StreamBuffer *sb) {
|
||||
}
|
||||
}
|
||||
|
||||
LuaDefine(unittests_scheduler, "c") {
|
||||
LuaDefine(unittests_scheduler, "", "some unit tests") {
|
||||
Schedule s, xs;
|
||||
StreamBuffer sb;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -173,6 +173,9 @@ public:
|
||||
void set(const std::string &fn, const std::string &code, int sequence);
|
||||
std::string get(const std::string &fn);
|
||||
|
||||
// Get function documentation.
|
||||
static std::string function_docs(const LuaStack &LS, LuaSlot slot);
|
||||
|
||||
// Serialize and unserialize a source vector.
|
||||
//
|
||||
static void serialize_source(const util::LuaSourceVec &sv, StreamBuffer *sb);
|
||||
|
||||
@@ -521,7 +521,7 @@ static void write_ztbytes(StreamBuffer *sb, const char *bytes) {
|
||||
sb->write_bytes(bytes, strlen(bytes));
|
||||
}
|
||||
|
||||
LuaDefine(unittests_streambuffer, "c") {
|
||||
LuaDefine(unittests_streambuffer, "", "some unit tests") {
|
||||
// An 11-byte fixed-size stream buffer.
|
||||
StreamBuffer sb11(11, true);
|
||||
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
#include "table.hpp"
|
||||
#include "source.hpp"
|
||||
|
||||
LuaDefine(table_getregistry, "f") {
|
||||
LuaArg key;
|
||||
LuaRet result;
|
||||
LuaStack LS(L, key, result);
|
||||
LS.rawget(result, LuaRegistry, key);
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
bool table_equal(LuaStack &LS, LuaSlot t1, LuaSlot t2) {
|
||||
lua_State *L = LS.state();
|
||||
@@ -33,7 +26,7 @@ bool table_equal(LuaStack &LS, LuaSlot t1, LuaSlot t2) {
|
||||
return total1 == total2;
|
||||
}
|
||||
|
||||
LuaDefine(table_equal, "c") {
|
||||
LuaDefine(table_equal, "table1,table2", "return true if two tables contain the same keys and values") {
|
||||
LuaArg t1, t2;
|
||||
LuaRet eql;
|
||||
LuaStack LS(L, t1, t2, eql);
|
||||
@@ -41,7 +34,7 @@ LuaDefine(table_equal, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(table_findremove, "c") {
|
||||
LuaDefine(table_findremove, "vector,value", "remove all occurrences of value from vector") {
|
||||
luaL_checktype(L, -2, LUA_TTABLE);
|
||||
int src = 1;
|
||||
int dst = 1;
|
||||
@@ -78,7 +71,7 @@ LuaDefine(table_findremove, "c") {
|
||||
}
|
||||
|
||||
|
||||
LuaDefine(table_push, "c") {
|
||||
LuaDefine(table_push, "vector,value", "push a value onto the end of a vector") {
|
||||
luaL_checktype(L, -2, LUA_TTABLE);
|
||||
int len = lua_rawlen(L, -2);
|
||||
lua_pushinteger(L, len+1);
|
||||
@@ -88,7 +81,7 @@ LuaDefine(table_push, "c") {
|
||||
return 0;
|
||||
}
|
||||
|
||||
LuaDefine(table_find, "c") {
|
||||
LuaDefine(table_find, "vector,value", "find the first occurrence of value in vector") {
|
||||
luaL_checktype(L, -2, LUA_TTABLE);
|
||||
for (int i = 1; ; i++) {
|
||||
lua_pushinteger(L, i);
|
||||
@@ -107,28 +100,21 @@ LuaDefine(table_find, "c") {
|
||||
}
|
||||
}
|
||||
|
||||
LuaDefine(table_empty, "c") {
|
||||
LuaDefine(table_empty, "table", "return true if the table is empty") {
|
||||
luaL_checktype(L, -1, LUA_TTABLE);
|
||||
lua_pushnil(L);
|
||||
if (lua_next(L, -2) != 0) {
|
||||
lua_pop(L, 3);
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
} else {
|
||||
lua_pop(L, 1);
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
int total = lua_nkeys(L, -1);
|
||||
lua_pushboolean(L, (total == 0)?1:0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
LuaDefine(table_count, "c") {
|
||||
LuaDefine(table_count, "table", "return the number of keys in table") {
|
||||
luaL_checktype(L, -1, LUA_TTABLE);
|
||||
int total = lua_nkeys(L, -1);
|
||||
lua_pushinteger(L, total);
|
||||
return 1;
|
||||
}
|
||||
|
||||
LuaDefine(table_clear, "c") {
|
||||
LuaDefine(table_clear, "table,metaflag", "clear all keys, and optionally the metatable") {
|
||||
LuaArg tab, clearmeta;
|
||||
LuaVar metatable, metafield;
|
||||
LuaStack LS(L, tab, clearmeta, metatable, metafield);
|
||||
@@ -148,7 +134,7 @@ LuaDefine(table_clear, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(table_getflagbits, "c") {
|
||||
LuaDefine(table_getflagbits, "table", "get the table's flag bits (debugging only)") {
|
||||
LuaArg tab;
|
||||
LuaRet bits;
|
||||
LuaStack LS(L, tab, bits);
|
||||
@@ -157,7 +143,7 @@ LuaDefine(table_getflagbits, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(table_setflagbits, "c") {
|
||||
LuaDefine(table_setflagbits, "table,bits", "set the table's flag bits (debugging only)") {
|
||||
LuaArg tab, bits;
|
||||
LuaStack LS(L, tab, bits);
|
||||
uint16_t ubits = LS.ckinteger(bits);
|
||||
@@ -238,7 +224,7 @@ int deque_make_room(lua_State *L, int deque, int left, int fill, int max) {
|
||||
return max;
|
||||
}
|
||||
|
||||
LuaDefine(deque_create, "c") {
|
||||
LuaDefine(deque_create, "", "create a deque") {
|
||||
LuaRet rdeque;
|
||||
LuaVar classobj;
|
||||
LuaStack LS(L, rdeque, classobj);
|
||||
@@ -255,7 +241,7 @@ LuaDefine(deque_create, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(deque_pushl, "c") {
|
||||
LuaDefine(deque_pushl, "deque,value", "push onto the left end of a deque") {
|
||||
LuaArg deque, elt;
|
||||
LuaStack LS(L, deque, elt);
|
||||
int left, fill, max;
|
||||
@@ -269,7 +255,7 @@ LuaDefine(deque_pushl, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(deque_pushr, "c") {
|
||||
LuaDefine(deque_pushr, "deque,value", "push onto the right end of a deque") {
|
||||
LuaArg deque, elt;
|
||||
LuaStack LS(L, deque, elt);
|
||||
int left, fill, max;
|
||||
@@ -282,7 +268,7 @@ LuaDefine(deque_pushr, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(deque_popl, "c") {
|
||||
LuaDefine(deque_popl, "deque", "pop the left end of a deque") {
|
||||
LuaArg deque;
|
||||
LuaRet result;
|
||||
LuaStack LS(L, deque, result);
|
||||
@@ -300,7 +286,7 @@ LuaDefine(deque_popl, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(deque_popr, "c") {
|
||||
LuaDefine(deque_popr, "deque", "pop the right end of a deque") {
|
||||
LuaArg deque;
|
||||
LuaRet result;
|
||||
LuaStack LS(L, deque, result);
|
||||
@@ -318,7 +304,7 @@ LuaDefine(deque_popr, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(deque_nthl, "c") {
|
||||
LuaDefine(deque_nthl, "deque,n", "return the nth item from the left end of a deque") {
|
||||
LuaArg deque, nn;
|
||||
LuaRet result;
|
||||
LuaStack LS(L, deque, nn, result);
|
||||
@@ -334,7 +320,7 @@ LuaDefine(deque_nthl, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(deque_nthr, "c") {
|
||||
LuaDefine(deque_nthr, "deque,n", "return the nth item from the right end of a deque") {
|
||||
LuaArg deque, nn;
|
||||
LuaRet result;
|
||||
LuaStack LS(L, deque, nn, result);
|
||||
@@ -350,7 +336,7 @@ LuaDefine(deque_nthr, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(deque_setl, "c") {
|
||||
LuaDefine(deque_setl, "deque,n,value", "set the nth item from the left end of a deque") {
|
||||
LuaArg deque, nn, val;
|
||||
LuaStack LS(L, deque, nn, val);
|
||||
int left, fill, max;
|
||||
@@ -365,7 +351,7 @@ LuaDefine(deque_setl, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(deque_setr, "c") {
|
||||
LuaDefine(deque_setr, "deque,n,value", "set the nth item from the right end of a deque") {
|
||||
LuaArg deque, nn, val;
|
||||
LuaStack LS(L, deque, nn, val);
|
||||
int left, fill, max;
|
||||
@@ -380,7 +366,7 @@ LuaDefine(deque_setr, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(deque_findl, "c") {
|
||||
LuaDefine(deque_findl, "deque,value", "find the first occurence of value in deque, starting from left") {
|
||||
LuaArg deque, val;
|
||||
LuaRet pos;
|
||||
LuaVar check;
|
||||
@@ -399,7 +385,7 @@ LuaDefine(deque_findl, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(deque_findr, "c") {
|
||||
LuaDefine(deque_findr, "deque,value", "find the first occurrence of value in deque, starting from right") {
|
||||
LuaArg deque, val;
|
||||
LuaRet pos;
|
||||
LuaVar check;
|
||||
@@ -419,7 +405,7 @@ LuaDefine(deque_findr, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(deque_size, "c") {
|
||||
LuaDefine(deque_size, "deque", "return the number of items in the deque") {
|
||||
LuaArg deque;
|
||||
LuaRet size;
|
||||
LuaStack LS(L, deque, size);
|
||||
@@ -576,7 +562,7 @@ bool table_getpairs(LuaStack &LS0, LuaSlot tab, LuaSlot pairs, bool sort) {
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
LuaDefine(table_nextsortedpair, "c") {
|
||||
LuaDefine(table_nextsortedpair, "sortedpairs,dummy", "next function used by sortedpairs") {
|
||||
if (lua_gettop(L) < 2) {
|
||||
luaL_error(L, "Not enough arguments to nextpair");
|
||||
}
|
||||
@@ -595,20 +581,20 @@ LuaDefine(table_nextsortedpair, "c") {
|
||||
}
|
||||
}
|
||||
|
||||
LuaDefine(table_sortedpairs, "c") {
|
||||
LuaDefine(table_sortedpairs, "table", "iterate over table, sorting all keys") {
|
||||
LuaArg tab;
|
||||
LuaRet closure, rtab, key;
|
||||
LuaStack LS(L, tab, closure, rtab, key);
|
||||
bool sorted = table_getpairs(LS, tab, rtab, true);
|
||||
if (!sorted) {
|
||||
luaL_error(L, "Cannot iterate over a table with unsortable keys");
|
||||
luaL_error(L, "Cannot sort the table keys");
|
||||
}
|
||||
LS.set(closure, lfn_table_nextsortedpair);
|
||||
LS.set(key, LuaNil);
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(table_semisortedpairs, "c") {
|
||||
LuaDefine(table_semisortedpairs, "table", "iterate over table, sorting those keys that can be sorted") {
|
||||
LuaArg tab;
|
||||
LuaRet closure, rtab, key;
|
||||
LuaStack LS(L, tab, closure, rtab, key);
|
||||
@@ -618,7 +604,7 @@ LuaDefine(table_semisortedpairs, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(table_genlt, "f") {
|
||||
LuaDefine(genlt, "obj1,obj2", "return true if obj1 is less than obj2 in general ordering") {
|
||||
LuaArg o1,o2;
|
||||
LuaRet lt;
|
||||
LuaStack LS(L, o1, o2, lt);
|
||||
|
||||
@@ -142,6 +142,28 @@ StringVec split(const std::string &s, char sep) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::string substr_nocr(const std::string &s, int start, int len) {
|
||||
if ((len > 0) && (s[start + len - 1] == '\r')) {
|
||||
len -= 1;
|
||||
}
|
||||
return s.substr(start, len);
|
||||
}
|
||||
|
||||
StringVec split_lines(const std::string &s) {
|
||||
StringVec result;
|
||||
int start = 0;
|
||||
for (int i = 0; i < int(s.size()); i++) {
|
||||
if (s[i]=='\n') {
|
||||
result.push_back(substr_nocr(s, start, i-start));
|
||||
start = i + 1;
|
||||
}
|
||||
}
|
||||
if (start < int(s.size())) {
|
||||
result.push_back(substr_nocr(s, start, s.size()-start));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string join(const StringVec &strs, const std::string &sep) {
|
||||
if (strs.empty()) return "";
|
||||
std::ostringstream oss;
|
||||
@@ -271,6 +293,12 @@ LuaSourcePtr make_lua_source(const std::string &code) {
|
||||
return result;
|
||||
}
|
||||
|
||||
bool is_lua_comment(const std::string &s) {
|
||||
int start = 0;
|
||||
while ((start < int(s.size())) && ((s[start]==' ') || (s[start]=='\t'))) start++;
|
||||
return s.substr(start, 2) == "--";
|
||||
}
|
||||
|
||||
static std::string get_file_contents(const std::string &fn) {
|
||||
std::ifstream fs(fn);
|
||||
std::stringstream buffer;
|
||||
@@ -329,7 +357,7 @@ std::ostream &operator<<(std::ostream &oss, const util::hex8 &v) {
|
||||
return oss;
|
||||
}
|
||||
|
||||
LuaDefine(unittests_util, "c") {
|
||||
LuaDefine(unittests_util, "", "some unit tests") {
|
||||
// Test the unioning of ID vectors.
|
||||
util::IdVector idv1,idv2;
|
||||
idv1.push_back(1);
|
||||
@@ -358,6 +386,15 @@ LuaDefine(unittests_util, "c") {
|
||||
LuaAssert(L, sv2[2]=="");
|
||||
LuaAssert(L, sv2[3]=="bar");
|
||||
|
||||
// Test the split_lines routine.
|
||||
util::StringVec sv3 = util::split_lines("foo\n\nbar\r\nbaz\r\n\r\n");
|
||||
LuaAssert(L, sv3.size() == 5);
|
||||
LuaAssert(L, sv3[0] == "foo");
|
||||
LuaAssert(L, sv3[1] == "");
|
||||
LuaAssert(L, sv3[2] == "bar");
|
||||
LuaAssert(L, sv3[3] == "baz");
|
||||
LuaAssert(L, sv3[4] == "");
|
||||
|
||||
// Test the repeat string routine.
|
||||
LuaAssertStrEq(L, util::repeat_string("abc", 3), "abcabcabc");
|
||||
|
||||
|
||||
@@ -64,6 +64,9 @@ std::string hash_to_hex(const HashValue &hash);
|
||||
// Split a string into multiple strings
|
||||
StringVec split(const std::string &s, char sep);
|
||||
|
||||
// Split a string into multiple strings using \r or \n
|
||||
StringVec split_lines(const std::string &s);
|
||||
|
||||
// Join multiple strings into one string
|
||||
std::string join(const StringVec &strs, std::string sep);
|
||||
|
||||
@@ -108,6 +111,9 @@ bool world_type_authoritative(util::WorldType wt);
|
||||
// Make a LuaSourceVec with one element, for unit testing.
|
||||
LuaSourcePtr make_lua_source(const std::string &code);
|
||||
|
||||
// Return true if the line of code is a lua comment.
|
||||
bool is_lua_comment(const std::string &line);
|
||||
|
||||
// Remove nullptrs from a vector of unique pointers.
|
||||
template<class T>
|
||||
void remove_nullptrs(std::vector<std::unique_ptr<T>> &vec) {
|
||||
|
||||
@@ -17,7 +17,7 @@ static void tangible_getall(LuaStack &LS0, LuaSlot list, const util::IdVector &i
|
||||
LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(tangible_animstate, "c") {
|
||||
LuaDefine(tangible_animstate, "tan", "get the final animation state of the tangible") {
|
||||
LuaArg tanobj;
|
||||
LuaRet graphic, plane, x, y, z, facing;
|
||||
LuaStack LS(L, tanobj, graphic, plane, x, y, z, facing);
|
||||
@@ -33,7 +33,7 @@ LuaDefine(tangible_animstate, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(tangible_animate, "c") {
|
||||
LuaDefine(tangible_animate, "tan,configtable", "add an animation step to the tangible") {
|
||||
LuaArg tanobj, config;
|
||||
LuaStack LS(L, tanobj, config);
|
||||
World *w = World::fetch_global_pointer(L);
|
||||
@@ -50,7 +50,7 @@ LuaDefine(tangible_animate, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(tangible_setclass, "c") {
|
||||
LuaDefine(tangible_setclass, "tan,classname", "set the class of the tangible") {
|
||||
LuaArg tanobj, classname;
|
||||
LuaVar classtab, mt;
|
||||
LuaStack LS(L, tanobj, classname, classtab, mt);
|
||||
@@ -66,7 +66,7 @@ LuaDefine(tangible_setclass, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(tangible_getclass, "c") {
|
||||
LuaDefine(tangible_getclass, "tan", "get the class of the tangible, if any") {
|
||||
LuaArg tanobj;
|
||||
LuaVar mt, classtab;
|
||||
LuaRet classname;
|
||||
@@ -84,7 +84,7 @@ LuaDefine(tangible_getclass, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(tangible_delete, "c") {
|
||||
LuaDefine(tangible_delete, "tan", "delete the specified tangible") {
|
||||
LuaArg tanobj;
|
||||
LuaStack LS(L, tanobj);
|
||||
World *w = World::fetch_global_pointer(L);
|
||||
@@ -98,7 +98,7 @@ LuaDefine(tangible_delete, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(tangible_build, "c") {
|
||||
LuaDefine(tangible_build, "configtable", "build a new tangible object") {
|
||||
LuaArg config;
|
||||
LuaVar classname, classtab, mt;
|
||||
LuaRet database;
|
||||
@@ -148,7 +148,7 @@ LuaDefine(tangible_build, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(tangible_get, "c") {
|
||||
LuaDefine(tangible_get, "id", "get the tangible with the specified id (debugging only)") {
|
||||
LuaArg id;
|
||||
LuaVar tangibles;
|
||||
LuaRet database;
|
||||
@@ -162,7 +162,7 @@ LuaDefine(tangible_get, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(tangible_redirect, "c") {
|
||||
LuaDefine(tangible_redirect, "tan1,tan2,bulldozetan1", "redirect is not working yet") {
|
||||
LuaArg actor1, actor2, bldz;
|
||||
LuaStack LS(L, actor1, actor2, bldz);
|
||||
World *w = World::fetch_global_pointer(L);
|
||||
@@ -184,7 +184,7 @@ LuaDefine(tangible_redirect, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(tangible_id, "c") {
|
||||
LuaDefine(tangible_id, "tan", "return the tangible's id number (debugging only)") {
|
||||
LuaArg tanobj;
|
||||
LuaRet id;
|
||||
LuaStack LS(L, tanobj, id);
|
||||
@@ -196,7 +196,7 @@ LuaDefine(tangible_id, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(tangible_actor, "c") {
|
||||
LuaDefine(tangible_actor, "", "return the current actor") {
|
||||
LuaRet actor;
|
||||
LuaVar tangibles;
|
||||
LuaStack LS(L, tangibles, actor);
|
||||
@@ -206,7 +206,7 @@ LuaDefine(tangible_actor, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(tangible_place, "c") {
|
||||
LuaDefine(tangible_place, "", "return the current place") {
|
||||
LuaRet place;
|
||||
LuaVar tangibles;
|
||||
LuaStack LS(L, tangibles, place);
|
||||
@@ -216,7 +216,7 @@ LuaDefine(tangible_place, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(tangible_near, "c") {
|
||||
LuaDefine(tangible_near, "tan,radius,omit_nowhere,omit_self", "scan near the specified tangible") {
|
||||
LuaArg ltan, lradius, lomit_nowhere, lomit_self;
|
||||
LuaRet list;
|
||||
LuaStack LS(L, ltan, lradius, lomit_nowhere, lomit_self, list);
|
||||
@@ -231,7 +231,7 @@ LuaDefine(tangible_near, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(tangible_scan, "c") {
|
||||
LuaDefine(tangible_scan, "plane,x,y,radius,omit_nowhere", "scan the specified plane") {
|
||||
LuaArg lplane, lx, ly, lradius, lomit_nowhere;
|
||||
LuaRet list;
|
||||
LuaStack LS(L, lplane, lx, ly, lradius, lomit_nowhere, list);
|
||||
@@ -246,14 +246,14 @@ LuaDefine(tangible_scan, "c") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(world_wait, "f") {
|
||||
LuaDefine(wait, "nticks", "wait the specified number of ticks") {
|
||||
if ((lua_gettop(L) != 1) || (lua_type(L, -1) != LUA_TNUMBER)) {
|
||||
luaL_error(L, "Argument to wait must be a number.");
|
||||
}
|
||||
return lua_yield(L, 1);
|
||||
}
|
||||
|
||||
LuaDefine(tangible_nopredict, "c") {
|
||||
LuaDefine(tangible_nopredict, "", "stop predictive execution of this thread") {
|
||||
if (lua_gettop(L) != 0) {
|
||||
luaL_error(L, "tangible.nopredict takes no arguments");
|
||||
}
|
||||
@@ -265,35 +265,7 @@ LuaDefine(tangible_nopredict, "c") {
|
||||
}
|
||||
}
|
||||
|
||||
LuaDefine(world_getregistry, "f") {
|
||||
lua_pushvalue(L, LUA_REGISTRYINDEX);
|
||||
return 1;
|
||||
}
|
||||
|
||||
LuaDefine(world_xtype, "f") {
|
||||
LuaArg tab;
|
||||
LuaRet rtype;
|
||||
LuaStack LS(L, tab, rtype);
|
||||
int xt = LS.xtype(tab);
|
||||
LS.set(rtype, xt);
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(world_settabletype, "f") {
|
||||
LuaArg tab, ttype;
|
||||
LuaStack LS(L, tab, ttype);
|
||||
if (!LS.istable(tab)) {
|
||||
luaL_error(L, "Not a table");
|
||||
}
|
||||
int tt = LS.ckinteger(ttype);
|
||||
if ((tt < LUA_TT_GENERAL) || (tt > LUA_TT_CLASS)) {
|
||||
luaL_error(L, "table type out of range");
|
||||
}
|
||||
LS.settabletype(tab, tt);
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(world_pprint, "f") {
|
||||
LuaDefine(pprint, "obj1,obj2,...", "pretty-print all the objects") {
|
||||
World *w = World::fetch_global_pointer(L);
|
||||
std::ostream *ostream = w->lthread_print_stream();
|
||||
LuaStack LS(L);
|
||||
@@ -305,14 +277,27 @@ LuaDefine(world_pprint, "f") {
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(world_print, "f") {
|
||||
LuaDefine(print, "obj1,obj2,...", "print all the objects") {
|
||||
World *w = World::fetch_global_pointer(L);
|
||||
std::ostream *ostream = w->lthread_print_stream();
|
||||
LuaStack LS(L);
|
||||
for (int i = 1; i <= lua_gettop(L); i++) {
|
||||
LuaSpecial root(i);
|
||||
atomic_print(LS, root, ostream);
|
||||
atomic_print(LS, root, false, ostream);
|
||||
(*ostream) << std::endl;
|
||||
}
|
||||
return LS.result();
|
||||
}
|
||||
|
||||
LuaDefine(doc, "function", "print documentation for specified function") {
|
||||
World *w = World::fetch_global_pointer(L);
|
||||
std::ostream *ostream = w->lthread_print_stream();
|
||||
LuaArg func;
|
||||
LuaStack LS(L, func);
|
||||
std::string doc = SourceDB::function_docs(LS, func);
|
||||
if (doc == "") {
|
||||
(*ostream) << "no doc found" << std::endl;
|
||||
}
|
||||
(*ostream) << doc;
|
||||
return LS.result();
|
||||
}
|
||||
@@ -711,6 +711,7 @@ void World::run_scheduled_threads() {
|
||||
if (LS.ckboolean(print)) {
|
||||
for (int i = 1; i <= lua_gettop(CO); i++) {
|
||||
pprint(LSCO, LuaSpecial(i), true, ostream);
|
||||
(*ostream) << std::endl;
|
||||
}
|
||||
}
|
||||
LS.rawset(threads, sched.thread_id(), LuaNil);
|
||||
|
||||
@@ -438,8 +438,8 @@ void World::diff_tangible_databases(const IdVector &basis, lua_State *master, St
|
||||
MLS.result();
|
||||
}
|
||||
|
||||
LuaDefine(table_diffcompare, "c") {
|
||||
LuaArg mtnmap, mtab, mstnmap, mstab, stnmap, stab;
|
||||
LuaDefine(table_diffcompare, "mtnmap,mtab,stnmap,stab", "for unit testing only") {
|
||||
LuaArg mtnmap, mtab, mstnmap, mstab;
|
||||
LuaRet dbgstring;
|
||||
LuaVar tthread;
|
||||
LuaStack MLS(L, mtnmap, mtab, mstnmap, mstab, dbgstring, tthread);
|
||||
@@ -456,6 +456,7 @@ LuaDefine(table_diffcompare, "c") {
|
||||
lua_pushvalue(L, mstnmap.index());
|
||||
lua_pushvalue(L, mstab.index());
|
||||
lua_xmove(L, synch, 2);
|
||||
LuaArg stnmap,stab;
|
||||
LuaStack SLS(synch, stnmap, stab);
|
||||
|
||||
// Call tablecmp_diff.
|
||||
@@ -467,8 +468,8 @@ LuaDefine(table_diffcompare, "c") {
|
||||
return MLS.result();
|
||||
}
|
||||
|
||||
LuaDefine(table_diffapply, "c") {
|
||||
LuaArg mtnmap, mtab, mstab, stnmap, stab;
|
||||
LuaDefine(table_diffapply, "mtnmap,mtab,mstab", "for unit testing only") {
|
||||
LuaArg mtnmap, mtab, mstab;
|
||||
LuaRet eql, eqlstr, rtab;
|
||||
LuaVar tthread, tangibles, mntmap, key, val;
|
||||
LuaStack MLS(L, mtnmap, mtab, mstab, eql, eqlstr, rtab, tthread, tangibles, mntmap, key, val);
|
||||
@@ -494,6 +495,7 @@ LuaDefine(table_diffapply, "c") {
|
||||
lua_pushvalue(L, mtnmap.index());
|
||||
lua_pushvalue(L, mstab.index());
|
||||
lua_xmove(L, synch, 2);
|
||||
LuaArg stnmap, stab;
|
||||
LuaStack SLS(synch, stnmap, stab);
|
||||
|
||||
// Call diff_tables and patch_tables
|
||||
|
||||
@@ -240,7 +240,7 @@ static bool worlds_identical(const UniqueWorld &w1, const UniqueWorld &w2) {
|
||||
return sbw1.contents_equal(&sbw2);
|
||||
}
|
||||
|
||||
LuaDefine(unittests_world1animdiff, "c") {
|
||||
LuaDefine(unittests_world1animdiff, "", "some unit tests") {
|
||||
UniqueWorld m(new World(util::WORLD_TYPE_MASTER));
|
||||
UniqueWorld ss(new World(util::WORLD_TYPE_S_SYNC));
|
||||
UniqueWorld cs(new World(util::WORLD_TYPE_C_SYNC));
|
||||
@@ -310,7 +310,7 @@ LuaDefine(unittests_world1animdiff, "c") {
|
||||
return 0;
|
||||
}
|
||||
|
||||
LuaDefine(unittests_world2pairtab, "c") {
|
||||
LuaDefine(unittests_world2pairtab, "", "some unit tests") {
|
||||
UniqueWorld m(new World(util::WORLD_TYPE_MASTER));
|
||||
UniqueWorld ss(new World(util::WORLD_TYPE_S_SYNC));
|
||||
StreamBuffer sb;
|
||||
@@ -358,7 +358,7 @@ LuaDefine(unittests_world2pairtab, "c") {
|
||||
return 0;
|
||||
}
|
||||
|
||||
LuaDefine(unittests_world3diffluatab, "c") {
|
||||
LuaDefine(unittests_world3diffluatab, "", "some unit tests") {
|
||||
UniqueWorld m(new World(util::WORLD_TYPE_MASTER));
|
||||
UniqueWorld ss(new World(util::WORLD_TYPE_S_SYNC));
|
||||
UniqueWorld cs(new World(util::WORLD_TYPE_C_SYNC));
|
||||
@@ -412,7 +412,7 @@ LuaDefine(unittests_world3diffluatab, "c") {
|
||||
return 0;
|
||||
}
|
||||
|
||||
LuaDefine(unittests_world4difftanclass, "c") {
|
||||
LuaDefine(unittests_world4difftanclass, "", "some unit tests") {
|
||||
UniqueWorld m(new World(util::WORLD_TYPE_MASTER));
|
||||
UniqueWorld ss(new World(util::WORLD_TYPE_S_SYNC));
|
||||
UniqueWorld cs(new World(util::WORLD_TYPE_C_SYNC));
|
||||
|
||||
Reference in New Issue
Block a user