object $code_lib: $libraries; var $root inited = 1; public method $code_lib.verify_code() { arg code, method, warn; var l, line, m, warns, isadmin, msg; warns = []; method = "\." + tostr(method) + "\("; isadmin = sender().is($admin); for l in [1 .. code.length()] { line = code[l]; // if its in a comment, ignore it if (match_begin(line, "//")) continue; // required warnings, sorry if ((m = line.match_regexp("[^._]anticipate_assignment\("))) warns += .point_to_line("WARNING: call to anticipate_assignment()", m[1][1] + 2, m[1][2] - 2, l, line); if ((m = line.match_regexp("(!)[a-z0-9_]+ in "))) { warns += ["WARNING: possible ambiguity, line " + l]; warns += .point_to_line("WARNING: parenthesis suggested around followup expression to '!'", m[2][1] + 1, m[2][2], l, line); } if ((m = line.match_regexp("(if *\(|&&|\|\|) *[a-z0-9_]+ *(=)[^=]"))) warns += .point_to_line("WARNING: parenthesis suggested around assignment expression", m[3][1] + 1, m[3][2], l, line); // optional warnings if (warn && (m = line.match_regexp(method))) warns += .point_to_line("WARNING: Possible Recursion", m[1][1] + 2, m[1][2] - 2, l, line); } return warns; }; public method $code_lib.generate_object_listing() { arg objs, multi, @args; var line, obj, col, name, fmt, out; if (!objs) { out = ["** None **"]; } else { col = ((| sender().linelen() |) || 79) / 10; fmt = "%3L%" + tostr(col * 4) + "L %" + tostr(col) + "L %" + tostr(col) + "R "; out = [strfmt(fmt, "#", "Name", "Perms", "Size") + "Manager"]; col = col * 4; for obj in (objs) { line = strfmt(fmt, obj.(multi)(@args).length(), obj.namef('xref), $object_lib.see_perms(obj, ["", ""]), obj.size()); name = obj.manager().namef('xref); if (name.length() > col) name = name.pad(col); out += [line + name]; } } return out; }; public method $code_lib.point_to_line() { arg err, left, right, lineno, line; var out; return [err + ", line " + lineno + ":", " " + line, strfmt("%*{-}l%*{^}l", left, "", right, "")]; }; public method $code_lib._debug_listing() { arg list; var indent, i, out, t, j; indent = ""; out = [" Tick# Event", " ----- -----------------------------"]; t = 0; for i in (list) { if (type(i) == 'integer) { if (indent) indent = indent.subrange(3); out += [strfmt("%6r %lreturn", i - t, indent)]; } else { if (!t) t = i[1]; j = strfmt("%6r %l%l(%l)", i[1] - t, indent, ._show_ref(i).replace("()", ""), (toliteral(i[5]).match_pattern("[*]"))[1]); out += [j]; indent += " "; } refresh(); } return out; // $#Edited: 03 Aug 97 13:53 $miro }; public method $code_lib.generate_debug_listing() { arg info, mode; return .(tosym("_" + tostr(mode) + "_listing"))(info); }; public method $code_lib._trace_listing() { arg list; var indent, i, out, t, j; indent = ""; out = [" Tick# Event", " ----- -----------------------------"]; t = 0; for i in (list) { if (type(i) == 'integer) { if (indent) indent = indent.subrange(3); } else { if (!t) t = i[1]; j = strfmt("%6r %l%l", i[1] - t, indent, ._show_ref(i)); out += [j.chop(79)]; indent += " "; } refresh(); } return out; }; public method $code_lib._trace_profile() { arg list; var i, out, ref, times, sums, callers, t, tic, max, start; out = ["Object<definer>.method Tics (%) Cummul. (%)"]; times = #[]; sums = #[]; callers = []; for i in (list) { refresh(); if (type(i) == 'integer) { if (callers) { [[ref, tic], @callers] = callers; times = times.add(ref, ((| times[ref] |) || 0) + i[1] - t); sums = sums.add(ref, ((| sums[ref] |) || 0) + i[1] - tic); } t = i; } else { if (callers) { ref = callers[1][1]; times = times.add(ref, ((| sums[ref] |) || 0) + i[1] - t); } ref = strfmt("%l<%l>.%l", i[2], i[3], i[4]); callers = [[ref, i[1]], @callers]; t = i[1]; } start ?= t; } max = 0.01 * (t - start); out = map i in (times.keys()) to (refresh() && [i, times[i], times[i] / max, sums[i], sums[i] / max]); out = out.sort(out.slice(2)); out = map i in (out) to (strfmt(i, "%50l%7r%7r%7r%7r")); return out; }; public method $code_lib._profile_listing() { arg list; var i, out, ref, times, sums, callers, t, tic, max, start, head; head = ["Object<definer>.method Tics (%) Total (%)", "---------------------- ---- --- ----- ---"]; times = #[]; sums = #[]; callers = []; for i in (list) { refresh(); if (type(i) == 'integer) { if (callers) { [[ref, tic], @callers] = callers; times = times.add(ref, ((| times[ref] |) || 0) + i - t); if (!(ref in callers)) sums = sums.add(ref, ((| sums[ref] |) || 0) + i - tic); } t = i; } else { if (callers) { ref = callers[1][1]; times = times.add(ref, ((| times[ref] |) || 0) + i[1] - t); } ref = ._show_ref(i); callers = [[ref, i[1]], @callers]; t = i[1]; } start ?= t; } max = 0.01 * (t - start); out = map i in (times.keys()) to (refresh() && [i.chop(50), times[i], times[i] / max, sums[i], sums[i] / max]); out = out.sort(map i in (out) to (refresh() && -i[2])); out = map i in (out) to (strfmt("%50l%7r%6.1r%%%7r%6.1r%%", @i)); out = head + out; return out; // $#Edited: 04 Nov 97 06:55 $miro }; public method $code_lib._show_ref() { arg i; return i[2] != i[3] ? strfmt("%l<%l>.%l()", i[2], i[3], i[4]) : strfmt("%l.%l()", i[2], i[4]); };