ScanFileForMsgs.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Last Edited by: Willie-Sue, August 5, 1985 10:53:27 am PDT
DIRECTORY
Commander USING [CommandProc, Register],
FS,
FSRope USING [StreamFromRope],
IO,
Process USING [Detach],
RefText,
Rope USING [ROPE],
ViewerClasses USING [Viewer],
ViewerIO USING [CreateViewerStreams],
ViewerOps USING [FindViewer, OpenIcon],
ViewerTools USING [TiogaContents, TiogaContentsRec],
WalnutKernelDefs USING [LogEntry, MsgLogEntry],
WalnutOps USING [CreateMsg],
WalnutStream USING [Open, FindNextEntry, PeekEntry, ReadEntry],
WalnutWindow USING [OutCome, QueueCall];
ScanFileForMsgs:
CEDAR
PROGRAM
IMPORTS
Commander, FS, FSRope, IO, Process, RefText, ViewerIO, ViewerOps,
WalnutOps, WalnutStream, WalnutWindow
= BEGIN
ROPE: TYPE = Rope.ROPE;
STREAM: TYPE = IO.STREAM;
out: STREAM ← NIL;
TSStream:
PROC[name:
ROPE]
RETURNS [
IO.
STREAM] = {
v: ViewerClasses.Viewer ← ViewerOps.FindViewer[name];
out: IO.STREAM ← ViewerIO.CreateViewerStreams[name, v].out;
IF v#NIL THEN IF v.iconic THEN ViewerOps.OpenIcon[v];
RETURN[out];
};
SetupScan:
PROC[commandLine:
ROPE] = {
clStream: STREAM ← FSRope.StreamFromRope[commandLine];
strm: STREAM;
length, startPos, endPos: INT;
file: ROPE;
outCome: WalnutWindow.OutCome;
out: STREAM ← TSStream["Walnut Rescue"];
numMsgs: INT ← 0;
Scan:
PROC
RETURNS[doReset:
BOOL] = {
strm.SetIndex[startPos];
numMsgs ← DoScan[strm, out, startPos, endPos];
RETURN[TRUE];
};
out.PutRope["\n\n************************************************************\n"];
out.PutF["\t\tScanForMsgs, started @ %g\n", IO.time[] ];
strm ← WalnutStream.Open[name: file, readOnly: TRUE ! FS.Error => CONTINUE];
file ← clStream.GetTokenRope[IO.IDProc ! IO.EndOfStream => CONTINUE].token;
IF file =
NIL
THEN {
out.PutRope["No input file specified - quitting\n"];
RETURN;
};
strm ← WalnutStream.Open[name: file, readOnly: TRUE ! FS.Error => CONTINUE];
IF strm =
NIL
THEN {
out.PutF["Could not open %g - quitting ..\n", IO.rope[file] ];
RETURN
};
startPos ← clStream.GetInt[ ! IO.EndOfStream => { startPos ← 0; CONTINUE}];
endPos ← clStream.GetInt[ ! IO.EndOfStream => { endPos ← LAST[INT]; CONTINUE}];
length ← strm.GetLength[];
IF endPos > length THEN endPos ← length;
IF startPos >= length
THEN {
out.PutF[" StartPos (%g) is >= length (%g) - quitting ..\n", IO.int[startPos], IO.int[length]];
strm.Close[];
RETURN;
};
out.PutF["\n Scanning the file %g, looking at [%g .. %g]\n\n",
IO.rope[file], IO.int[startPos], IO.int[endPos] ];
outCome ← WalnutWindow.QueueCall[Scan];
SELECT outCome
FROM
ok => out.PutF[" Call completed ok at %g\n", IO.time[] ];
flushed => out.PutF[" Call was flushed (%g)\n", IO.time[] ];
notRunning => out.PutF[" Walnut is not running at %g\n", IO.time[] ];
ENDCASE => NULL;
IF outCome = ok
THEN
out.PutF[" %g messages were read from %g\n", IO.int[numMsgs], IO.rope[file] ];
strm.Close[];
};
DoScan:
PROC[strm, out:
STREAM, startPos, endPos:
INT]
RETURNS[numMsgs:
INT] = {
ident: ATOM;
le: WalnutKernelDefs.LogEntry;
mle: WalnutKernelDefs.MsgLogEntry;
msgID: REF TEXT ← NEW[TEXT[RefText.line]];
body: ViewerTools.TiogaContents ← NEW[ViewerTools.TiogaContentsRec];
bodyContents: REF TEXT ← NEW[TEXT[5*RefText.page]];
bodyFormatting: REF TEXT ← NEW[TEXT[5*RefText.page]];
length: INT;
nonMsgCount: INT ← 0;
numMsgs ← 0;
DO
at: INT ← WalnutStream.FindNextEntry[strm];
IF at > endPos
THEN {
out.PutF["\nNext entry (%g) is beyond endPos (%g)\n", IO.int[at], IO.int[endPos] ];
RETURN
};
IF at = -1
THEN {
out.PutRope["\n No more entries\n"];
RETURN
};
[ident, msgID, length] ← WalnutStream.PeekEntry[strm];
IF ident =
NIL
THEN {
out.PutF["PeekEntry says no valid entry at %g - quitting", IO.int[at] ];
RETURN
};
IF ident # $CreateMsg
THEN {
IF (nonMsgCount ← nonMsgCount + 1)
MOD 10 = 0
THEN
out.PutF["{%g}", IO.int[nonMsgCount]] ELSE out.PutChar['!];
strm.SetIndex[at + length];
LOOP;
};
le ← WalnutStream.ReadEntry[strm: strm, quick: TRUE].le;
mle ← NARROW[le];
IF mle.formatLen # 0
THEN {
strm.SetIndex[mle.entryStart+mle.textOffset-1];
bodyContents ← TextFromStream[strm, mle.textLen+1, bodyContents];
bodyFormatting ← TextFromStream[strm, mle.formatLen, bodyFormatting];
}
ELSE {
strm.SetIndex[mle.entryStart+mle.textOffset];
bodyContents ← TextFromStream[strm, mle.textLen, bodyContents];
bodyFormatting.length ← 0;
};
body.contents ← RefText.TrustTextAsRope[bodyContents];
body.formatting ← RefText.TrustTextAsRope[bodyFormatting];
WalnutOps.CreateMsg[RefText.TrustTextAsRope[msgID], body];
IF (numMsgs ← numMsgs + 1)
MOD 10 = 0
THEN out.PutF["(%g)",
IO.int[numMsgs]]
ELSE out.PutChar['.];
ENDLOOP;
};
TextFromStream:
PROC[strm:
STREAM, len:
INT, text:
REF
TEXT]
RETURNS[
REF
TEXT] = {
natLen: NAT ← len;
bytesRead: INT;
IF text = NIL OR len > text.maxLength THEN text ← RefText.New[natLen];
bytesRead ← strm.GetBlock[block: text, startIndex: 0, count: natLen];
IF bytesRead < natLen THEN text.length ← 0;
RETURN[text]
};
ScanForMsgs: Commander.CommandProc =
TRUSTED { Process.Detach[FORK SetupScan[cmd.commandLine]] };
Commander.Register["ScanForMsgs", ScanForMsgs, "Scan a file for walnut msgs; syntax is \"ScanForMsgs file startPos( ← 0) endPos( ← endOfFile)\""];
END.
Willie-Sue Orr July 30, 1985 - created