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]);
};