diff --git a/Nasal/debug.nas b/Nasal/debug.nas index c960ae5c8..eb3693e55 100644 --- a/Nasal/debug.nas +++ b/Nasal/debug.nas @@ -1,11 +1,20 @@ # debug.nas -- debugging helpers # -# debug.dump() ... dumps full contents of variable +# debug.dump() ... dumps contents of variable to terminal; +# abbreviation for print(debug.string(v)) +# +# debug.local([]) ... dump local variables of current +# or given frame +# # debug.backtrace([]} ... writes backtrace with local variables # (similar to gdb's "bt full) +# # debug.exit() ... exits fgfs # # debug.bt ... abbreviation for debug.backtrace +# +# debug.string() ... returns contents of variable as string +# @@ -20,23 +29,24 @@ if (caller(0)[2][1] != `:`) { # for color codes see $ man console_codes # -_title = func(s) { _c("33;42;1", s) } # backtrace header -_section = func(s) { _c("37;41;1", s) } # backtrace frame +var _title = func(s) { _c("33;42;1", s) } # backtrace header +var _section = func(s) { _c("37;41;1", s) } # backtrace frame +var _error = func(s) { _c("31;1", s) } # internal errors -_nil = func(s) { _c("32", s) } # nil -_string = func(s) { _c("31", s) } # "foo" -_num = func(s) { _c("31", s) } # 0.0 -_bracket = func(s) { _c("", s) } # [ ] -_brace = func(s) { _c("", s) } # { } -_angle = func(s) { _c("", s) } # < > -_vartype = func(s) { _c("33", s) } # func ghost -_proptype = func(s) { _c("34", s) } # BOOL INT LONG DOUBLE ... -_path = func(s) { _c("36", s) } # /some/property/path -_internal = func(s) { _c("35", s) } # me parents -_varname = func(s) { _c("1", s) } # variable_name +var _nil = func(s) { _c("32", s) } # nil +var _string = func(s) { _c("31", s) } # "foo" +var _num = func(s) { _c("31", s) } # 0.0 +var _bracket = func(s) { _c("", s) } # [ ] +var _brace = func(s) { _c("", s) } # { } +var _angle = func(s) { _c("", s) } # < > +var _vartype = func(s) { _c("33", s) } # func ghost +var _proptype = func(s) { _c("34", s) } # BOOL INT LONG DOUBLE ... +var _path = func(s) { _c("36", s) } # /some/property/path +var _internal = func(s) { _c("35", s) } # me parents +var _varname = func(s) { _c("1", s) } # variable_name -_dump_prop = func(p) { +var _dump_prop = func(p) { var r = p.getAttribute("read") ? "" : "r"; var w = p.getAttribute("write") ? "" : "w"; var R = p.getAttribute("trace-read") ? "R" : ""; @@ -46,11 +56,11 @@ _dump_prop = func(p) { var T = p.getAttribute("tied") ? "T" : ""; var attrib = r ~ w ~ R ~ W ~ A ~ U ~ T; var type = "(" ~ _proptype(p.getType()) ~ (size(attrib) ? ", " ~ attrib : "") ~ ")"; - return _path(p.getPath()) ~ "=" ~ _dump(p.getValue()) ~ " " ~ type; + return _path(p.getPath()) ~ "=" ~ string(p.getValue()) ~ " " ~ type; } -_dump_var = func(v) { +var _dump_var = func(v) { if (v == "me" or v == "parents") { return _internal(v); } else { @@ -59,7 +69,7 @@ _dump_var = func(v) { } -_dump = func(o) { +var string = func(o) { var t = typeof(o); if (t == "nil") { return _nil("nil"); @@ -68,7 +78,7 @@ _dump = func(o) { } elsif (t == "vector") { var s = ""; forindex (var i; o) { - s ~= (i == 0 ? "" : ", ") ~ _dump(o[i]); + s ~= (i == 0 ? "" : ", ") ~ string(o[i]); } return _bracket("[") ~ " " ~ s ~ " " ~ _bracket("]"); } elsif (t == "hash") { @@ -79,7 +89,7 @@ _dump = func(o) { var k = keys(o); var s = ""; forindex (var i; k) { - s ~= (i == 0 ? "" : ", ") ~ _dump_var(k[i]) ~ " : " ~ _dump(o[k[i]]); + s ~= (i == 0 ? "" : ", ") ~ _dump_var(k[i]) ~ " : " ~ string(o[k[i]]); } return _brace("{") ~ " " ~ s ~ " " ~ _brace("}"); } else { @@ -88,10 +98,17 @@ _dump = func(o) { } -dump = func(o = nil) { print(_dump(o != nil ? o : caller()[0])) } +var dump = func { size(arg) ? print(string(arg[0])) : local(1) } -backtrace = func(desc = nil, l = 0) { +var local = func(frame = 0) { + var v = caller(frame + 1); + print(v == nil ? _error("") : string(v[0])); + return v; +} + + +var backtrace = func(desc = nil, l = 0) { var v = caller(l); if (v == nil) { return; @@ -105,10 +122,10 @@ backtrace = func(desc = nil, l = 0) { } backtrace(nil, l + 1); } -bt = backtrace; +var bt = backtrace; -exit = func { fgcommand("exit", props.Node.new()) } +var exit = func { fgcommand("exit", props.Node.new()) } if (getprop("/sim/logging/priority") != "alert") {