Added print/dump_r functions used to print/dump a specific variable or script context using flags to filter what to print: props only (default), funcs only ...
git-svn-id: http://voip.null.ro/svn/yate@6437 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
41c8c9a632
commit
a51728652e
|
@ -125,10 +125,17 @@ protected:
|
|||
|
||||
|
||||
// Helper function that does the actual object printing
|
||||
static void dumpRecursiveObj(const GenObject* obj, String& buf, unsigned int depth, ObjList& seen)
|
||||
static void dumpRecursiveObj(const GenObject* obj, String& buf, unsigned int depth, ObjList& seen,
|
||||
unsigned int flags)
|
||||
{
|
||||
if (!obj)
|
||||
return;
|
||||
if (depth > 1 && !(flags & JsObject::DumpRecursive))
|
||||
return;
|
||||
// Check if we have something to dump
|
||||
unsigned int dump = flags & (JsObject::DumpFunc | JsObject::DumpProp);
|
||||
if (!dump)
|
||||
return;
|
||||
String str(' ',2 * depth);
|
||||
if (seen.find(obj)) {
|
||||
str << "(recursivity encountered)";
|
||||
|
@ -136,12 +143,17 @@ static void dumpRecursiveObj(const GenObject* obj, String& buf, unsigned int dep
|
|||
return;
|
||||
}
|
||||
const NamedString* nstr = YOBJECT(NamedString,obj);
|
||||
// Check for prototype dump (always dump the first level if original object is a prototype)
|
||||
bool isProto = nstr && nstr->name() == JsObject::protoName();
|
||||
if (depth && isProto && !(flags & JsObject::DumpProto))
|
||||
return;
|
||||
const NamedPointer* nptr = YOBJECT(NamedPointer,nstr);
|
||||
const char* type = nstr ? (nptr ? "NamedPointer" : "NamedString") : "???";
|
||||
const char* subType = 0;
|
||||
const ScriptContext* scr = YOBJECT(ScriptContext,obj);
|
||||
const ExpWrapper* wrap = 0;
|
||||
bool objRecursed = false;
|
||||
bool isFunc = false;
|
||||
if (scr) {
|
||||
const JsObject* jso = YOBJECT(JsObject,scr);
|
||||
if (jso) {
|
||||
|
@ -150,8 +162,10 @@ static void dumpRecursiveObj(const GenObject* obj, String& buf, unsigned int dep
|
|||
seen.append(jso)->setDelete(false);
|
||||
if (YOBJECT(JsArray,scr))
|
||||
type = "JsArray";
|
||||
else if (YOBJECT(JsFunction,scr))
|
||||
else if (YOBJECT(JsFunction,scr)) {
|
||||
type = "JsFunction";
|
||||
isFunc = true;
|
||||
}
|
||||
else if (YOBJECT(JsRegExp,scr))
|
||||
type = "JsRegExp";
|
||||
else if (YOBJECT(JsDate,scr))
|
||||
|
@ -167,38 +181,79 @@ static void dumpRecursiveObj(const GenObject* obj, String& buf, unsigned int dep
|
|||
if (exp && !scr) {
|
||||
if ((wrap = YOBJECT(ExpWrapper,exp)))
|
||||
type = wrap->object() ? "ExpWrapper" : "Undefined";
|
||||
else if (YOBJECT(ExpFunction,exp))
|
||||
else if (YOBJECT(ExpFunction,exp)) {
|
||||
type = "ExpFunction";
|
||||
isFunc = true;
|
||||
}
|
||||
else {
|
||||
type = "ExpOperation";
|
||||
subType = exp->typeOf();
|
||||
}
|
||||
}
|
||||
if (nstr)
|
||||
str << "'" << nstr->name() << "' = '" << *nstr << "'";
|
||||
// Check for func/prop dump (don't do it if we are printing a prototype)
|
||||
if (depth && !isProto && ((isFunc && (0 == (flags & JsObject::DumpFunc))) ||
|
||||
(!isFunc && (0 == (flags & JsObject::DumpProp)))))
|
||||
return;
|
||||
bool dumpType = flags & JsObject::DumpType;
|
||||
if (nstr) {
|
||||
str << "'" << nstr->name() << "'";
|
||||
// Nicely dump property value if dumping props only and type is not shown
|
||||
if ((dump == JsObject::DumpProp) && !isProto && !dumpType) {
|
||||
if (scr) {
|
||||
if (exp && JsParser::isNull(*exp))
|
||||
str << " = null";
|
||||
else if (YOBJECT(JsRegExp,scr))
|
||||
str << " = /" << *nstr << "/";
|
||||
else if (flags & JsObject::DumpPropObjType) {
|
||||
if (YOBJECT(JsObject,scr))
|
||||
str << " = " << *nstr;
|
||||
else
|
||||
str << " = [ScriptContext]";
|
||||
}
|
||||
}
|
||||
else if (exp) {
|
||||
if (JsParser::isUndefined(*exp))
|
||||
str << " = undefined";
|
||||
else if (exp->isInteger()) {
|
||||
if (exp->isBoolean())
|
||||
str << " = " << exp->valBoolean();
|
||||
else
|
||||
str << " = " << exp->number();
|
||||
}
|
||||
else if (exp->isNumber()) // NaN
|
||||
str << " = " << *nstr;
|
||||
else // string
|
||||
str << " = '" << *nstr << "'";
|
||||
}
|
||||
else
|
||||
str << " = '" << *nstr << "'";
|
||||
}
|
||||
else
|
||||
str << " = '" << *nstr << "'";
|
||||
}
|
||||
else
|
||||
str << "'" << obj->toString() << "'";
|
||||
str << " (" << type << (subType ? ", " : "") << subType << ")";
|
||||
if (dumpType)
|
||||
str << " (" << type << (subType ? ", " : "") << subType << ")";
|
||||
if (objRecursed)
|
||||
str << " (already seen)";
|
||||
buf.append(str,"\r\n");
|
||||
if (objRecursed)
|
||||
return;
|
||||
str.clear();
|
||||
if (scr) {
|
||||
NamedIterator iter(scr->params());
|
||||
while (const NamedString* p = iter.get())
|
||||
dumpRecursiveObj(p,buf,depth + 1,seen);
|
||||
dumpRecursiveObj(p,buf,depth + 1,seen,flags);
|
||||
if (scr->nativeParams()) {
|
||||
iter = *scr->nativeParams();
|
||||
while (const NamedString* p = iter.get())
|
||||
dumpRecursiveObj(p,buf,depth + 1,seen);
|
||||
dumpRecursiveObj(p,buf,depth + 1,seen,flags);
|
||||
}
|
||||
}
|
||||
else if (wrap)
|
||||
dumpRecursiveObj(wrap->object(),buf,depth + 1,seen);
|
||||
dumpRecursiveObj(wrap->object(),buf,depth + 1,seen,flags);
|
||||
else if (nptr)
|
||||
dumpRecursiveObj(nptr->userData(),buf,depth + 1,seen);
|
||||
dumpRecursiveObj(nptr->userData(),buf,depth + 1,seen,flags);
|
||||
}
|
||||
|
||||
|
||||
|
@ -243,16 +298,16 @@ JsObject* JsObject::copy(Mutex* mtx) const
|
|||
return jso;
|
||||
}
|
||||
|
||||
void JsObject::dumpRecursive(const GenObject* obj, String& buf)
|
||||
void JsObject::dumpRecursive(const GenObject* obj, String& buf, unsigned int flags)
|
||||
{
|
||||
ObjList seen;
|
||||
dumpRecursiveObj(obj,buf,0,seen);
|
||||
dumpRecursiveObj(obj,buf,0,seen,flags);
|
||||
}
|
||||
|
||||
void JsObject::printRecursive(const GenObject* obj)
|
||||
void JsObject::printRecursive(const GenObject* obj, unsigned int flags)
|
||||
{
|
||||
String buf;
|
||||
dumpRecursive(obj,buf);
|
||||
dumpRecursive(obj,buf,flags);
|
||||
Output("%s",buf.c_str());
|
||||
}
|
||||
|
||||
|
|
|
@ -1954,6 +1954,21 @@ class YSCRIPT_API JsObject : public ScriptContext
|
|||
friend class JsFunction;
|
||||
YCLASS(JsObject,ScriptContext)
|
||||
public:
|
||||
/**
|
||||
* Dump object flags
|
||||
*/
|
||||
enum DumpFlags {
|
||||
DumpFunc = 0x01, // Dump functions
|
||||
DumpProp = 0x02, // Dump non functions (data)
|
||||
DumpRecursive = 0x10, // Dump recursive (stop on root if not set)
|
||||
DumpType = 0x20, // Dump type (apply to functions also),
|
||||
DumpProto = 0x40, // Dump prototype
|
||||
DumpPropObjType = 0x80, // Dump non basic type for DumpPropOnly whithout DumpType
|
||||
// Masks
|
||||
DumpFuncOnly = DumpRecursive | DumpProto | DumpFunc,
|
||||
DumpPropOnly = DumpRecursive | DumpPropObjType | DumpProp,
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param name Name of the object
|
||||
|
@ -2276,14 +2291,16 @@ public:
|
|||
* Helper method to return the hierarchical structure of an object
|
||||
* @param obj Object to dump structure
|
||||
* @param buf String to which the structure is added
|
||||
* @param flags Flags indicating what to dump
|
||||
*/
|
||||
static void dumpRecursive(const GenObject* obj, String& buf);
|
||||
static void dumpRecursive(const GenObject* obj, String& buf, unsigned int flags = 0xffffffff);
|
||||
|
||||
/**
|
||||
* Helper method to display the hierarchical structure of an object
|
||||
* @param obj Object to display
|
||||
* @param flags Flags indicating what to dump (display)
|
||||
*/
|
||||
static void printRecursive(const GenObject* obj);
|
||||
static void printRecursive(const GenObject* obj, unsigned int flags = 0xffffffff);
|
||||
|
||||
/**
|
||||
* Static method to obtain a JSON representation of the given object
|
||||
|
|
|
@ -362,6 +362,7 @@ private:
|
|||
|
||||
#define MKDEBUG(lvl) params().addParam(new ExpOperation((int64_t)Debug ## lvl,"Debug" # lvl))
|
||||
#define MKTIME(typ) params().addParam(new ExpOperation((int64_t)SysUsage:: typ ## Time,# typ "Time"))
|
||||
#define MKDUMP(typ) params().addParam(new ExpOperation((int64_t)JsObject:: Dump ## typ,"Dump" # typ))
|
||||
class JsEngine : public JsObject, public DebugEnabler
|
||||
{
|
||||
YCLASS(JsEngine,JsObject)
|
||||
|
@ -387,6 +388,14 @@ public:
|
|||
MKTIME(Wall);
|
||||
MKTIME(User);
|
||||
MKTIME(Kernel);
|
||||
MKDUMP(PropOnly),
|
||||
MKDUMP(FuncOnly),
|
||||
MKDUMP(Func),
|
||||
MKDUMP(Prop),
|
||||
MKDUMP(Recursive),
|
||||
MKDUMP(Type),
|
||||
MKDUMP(Proto),
|
||||
MKDUMP(PropObjType),
|
||||
params().addParam(new ExpFunction("output"));
|
||||
params().addParam(new ExpFunction("debug"));
|
||||
params().addParam(new ExpFunction("traceDebug"));
|
||||
|
@ -405,6 +414,10 @@ public:
|
|||
params().addParam(new ExpFunction("init"));
|
||||
params().addParam(new ExpFunction("dump_r"));
|
||||
params().addParam(new ExpFunction("print_r"));
|
||||
params().addParam(new ExpFunction("dump_var_r"));
|
||||
params().addParam(new ExpFunction("print_var_r"));
|
||||
params().addParam(new ExpFunction("dump_root_r"));
|
||||
params().addParam(new ExpFunction("print_root_r"));
|
||||
params().addParam(new ExpFunction("dump_t"));
|
||||
params().addParam(new ExpFunction("print_t"));
|
||||
params().addParam(new ExpFunction("debugName"));
|
||||
|
@ -1185,7 +1198,7 @@ static void dumpTable(const ExpOperation& oper, String& str, const char* eol)
|
|||
// Return false if the number of arguments is not the expected one
|
||||
static bool extractStackArgs(int minArgc, JsObject* obj,
|
||||
ObjList& stack, const ExpOperation& oper, GenObject* context, ObjList& args,
|
||||
ExpOperation** op1, ExpOperation** op2, ExpOperation** op3 = 0)
|
||||
ExpOperation** op1, ExpOperation** op2 = 0, ExpOperation** op3 = 0)
|
||||
{
|
||||
if (!obj)
|
||||
return false;
|
||||
|
@ -1204,6 +1217,9 @@ static bool extractStackArgs(int minArgc, JsObject* obj,
|
|||
EXTRACT_ARG_CHECK(op1,1);
|
||||
return true;
|
||||
#undef EXTRACT_ARG_CHECK
|
||||
case 0:
|
||||
if (!minArgc)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1517,6 +1533,48 @@ bool JsEngine::runNative(ObjList& stack, const ExpOperation& oper, GenObject* co
|
|||
else
|
||||
return false;
|
||||
}
|
||||
else if (oper.name() == YSTRING("dump_var_r")) {
|
||||
// str = Engine.dump_var_r(obj[,flags])
|
||||
ObjList args;
|
||||
ExpOperation* obj = 0;
|
||||
ExpOperation* flags = 0;
|
||||
if (!extractStackArgs(1,this,stack,oper,context,args,&obj,&flags))
|
||||
return false;
|
||||
String buf;
|
||||
dumpRecursive(obj,buf,flags ? flags->valInteger(DumpPropOnly) : DumpPropOnly);
|
||||
ExpEvaluator::pushOne(stack,new ExpOperation(buf));
|
||||
}
|
||||
else if (oper.name() == YSTRING("print_var_r")) {
|
||||
// Engine.print_var_r(obj[,flags])
|
||||
ObjList args;
|
||||
ExpOperation* obj = 0;
|
||||
ExpOperation* flags = 0;
|
||||
if (!extractStackArgs(1,this,stack,oper,context,args,&obj,&flags))
|
||||
return false;
|
||||
printRecursive(obj,flags ? flags->valInteger(DumpPropOnly) : DumpPropOnly);
|
||||
}
|
||||
else if (oper.name() == YSTRING("dump_root_r")) {
|
||||
// str = Engine.dump_root_r([flags])
|
||||
ObjList args;
|
||||
ExpOperation* flags = 0;
|
||||
if (!extractStackArgs(0,this,stack,oper,context,args,&flags))
|
||||
return false;
|
||||
String buf;
|
||||
ScriptRun* run = YOBJECT(ScriptRun,context);
|
||||
dumpRecursive(run ? run->context() : context,buf,
|
||||
flags ? flags->valInteger(DumpPropOnly) : DumpPropOnly);
|
||||
ExpEvaluator::pushOne(stack,new ExpOperation(buf));
|
||||
}
|
||||
else if (oper.name() == YSTRING("print_root_r")) {
|
||||
// Engine.print_root_r([flags])
|
||||
ObjList args;
|
||||
ExpOperation* flags = 0;
|
||||
if (!extractStackArgs(0,this,stack,oper,context,args,&flags))
|
||||
return false;
|
||||
ScriptRun* run = YOBJECT(ScriptRun,context);
|
||||
printRecursive(run ? run->context() : context,
|
||||
flags ? flags->valInteger(DumpPropOnly) : DumpPropOnly);
|
||||
}
|
||||
else if (oper.name() == YSTRING("dump_t")) {
|
||||
if (oper.number() != 1)
|
||||
return false;
|
||||
|
|
Loading…
Reference in New Issue