SearchForLog.mesa
Sweet November 25, 1985 11:44:32 am PST
DIRECTORY
Basics,
Commander,
FS,
IO,
List,
ProcMap,
Rope;
SearchForLog: CEDAR PROGRAM
IMPORTS Commander, FS, IO, List, ProcMap, Rope = {
STREAM: TYPE = IO.STREAM;
ROPE: TYPE = Rope.ROPE;
SortRecord: TYPE = RECORD [msg, mod, locProc: ROPE, src: INT, call: CHAR];
SortItem: TYPE = REF SortRecord;
ShortName: PUBLIC PROC [rope: ROPE] RETURNS [ROPE] = {
pos: INT ← Rope.Length[rope];
end: INT ← pos;
WHILE pos > 0 DO
under: INT = pos - 1;
SELECT Rope.Fetch[rope, under] FROM
'!, '. => end ← under;
'>, '/, '<, '] => RETURN [Rope.Flatten[rope, pos, end-pos]];
ENDCASE;
pos ← under;
ENDLOOP;
RETURN [Rope.Flatten[rope, 0, end]];
};
SetExt: PROC [fileName, ext: ROPE] RETURNS [ROPE] = {
pos: INT ← Rope.Length[fileName];
dot: INT ← pos;
WHILE pos > 0 DO
under: INT = pos - 1;
SELECT Rope.Fetch[fileName, under] FROM
'. => {dot ← under; EXIT};
'>, '/ => EXIT;
ENDCASE;
pos ← under;
ENDLOOP;
RETURN [Rope.Cat[Rope.Substr[base: fileName, start: 0, len: dot], ".", ext]];
};
OpenFile: PROC [name: ROPE] RETURNS [st: STREAM] = {
st ← FS.StreamOpen[name, $read
! FS.Error => IF error.group # bug THEN CONTINUE]};
MyTokenProc: IO.BreakProc = {
RETURN[SELECT char FROM
IN [IO.NUL .. IO.SP], ',, ':, ';, '[ => sepr,
'], '(, '), '{, '}, '", '+, '-, '*, '/, '@, '←, '. => break,
ENDCASE => other]};
SearchFile: PROC [fileName: ROPE, list: LIST OF REF ANY, log: STREAM] RETURNS[LIST OF REF ANY] = {
st: STREAM;
h: ProcMap.Handle;
source, obj, short: ROPE;
src: INT;
ros: IO.STREAM;
called, msg, locProc: ROPE;
source ← SetExt[fileName, "mesa"];
obj ← SetExt[fileName, "bcd"];
short ← ShortName[fileName];
st ← OpenFile[source];
IF st = NIL THEN {log.PutRope[" can't be opened"]; RETURN[list]};
ros ← IO.ROS[];
h ← ProcMap.Create[obj];
DO
ENABLE IO.EndOfStream => EXIT;
IF Rope.Equal[st.GetTokenRope[MyTokenProc].token, "Log"] AND Rope.Equal[st.GetTokenRope[MyTokenProc].token, "."] THEN {
src ← st.GetIndex[];
IF h = NIL THEN locProc ← NIL
ELSE locProc ← h.FromSource[src];
called ← st.GetTokenRope[MyTokenProc].token;
msg ← st.GetTokenRope[MyTokenProc].token;
list ← CONS [NEW[SortRecord ← [
msg: msg, call: Rope.Fetch[called, 0], mod: short, locProc: locProc, src: src]], list];
};
ENDLOOP;
RETURN[list]};
SearchListOfFiles: Commander.CommandProc = {
[cmd: Commander.Handle] RETURNS [result: REF ANY ← NIL, msg: ROPE ← NIL]
CompareItems: List.CompareProc = TRUSTED {
[ref1: REF ANY, ref2: REF ANY] RETURNS [Basics.Comparison]
r1: SortItem = NARROW[ref1];
r2: SortItem = NARROW[ref2];
comp: Basics.Comparison ← Rope.Compare[r1.msg, r2.msg, FALSE];
IF comp # equal THEN RETURN[comp];
comp ← Rope.Compare[r1.mod, r2.mod, FALSE];
IF comp # equal THEN RETURN[comp];
SELECT r1.src FROM
< r2.src => RETURN [less];
> r2.src => RETURN [greater];
ENDCASE => RETURN [equal];
};
ris: IO.STREAMIO.RIS[cmd.commandLine];
log: IO.STREAM ← cmd.err;
out: IO.STREAM ← cmd.out;
list: LIST OF REF ANYNIL;
file: ROPE;
DO
ENABLE IO.EndOfStream => EXIT;
file ← ris.GetTokenRope[IO.IDProc].token;
log.PutF["\n%g", [rope[file]]];
list ← SearchFile[file, list, log];
ENDLOOP;
log.PutRope["\nSorting..."];
list ← List.Sort[list, CompareItems];
WHILE list # NIL DO
item: SortItem ← NARROW[list.first];
out.PutF["\n%-20g %g %5g %g \t%g",
[rope[item.msg]],
[character[item.call]],
[integer[item.src]],
[rope[item.mod]],
[rope[item.locProc]]];
list ← list.rest;
ENDLOOP;
out.PutRope["\n"];
};
Commander.Register[
"SearchForLog", SearchListOfFiles,
"Search list of files, finding all calls to Log"];
}.