PrintLogImpl.mesa
Copyright Ó 1989 by Xerox Corporation. All rights reserved.
Bob Hagmann May 30, 1989 3:56:05 pm PDT
DIRECTORY
BasicTime,
Camelot,
Commander,
CommandTool,
Convert,
IO,
Rope,
YggDID,
YggDIDPrivate,
YggDIDMapPrivate,
YggdrasilInit,
YggLock,
YggLog,
YggLogBasic,
YggLogControl,
YggLogRep,
YggInternal,
YggEnvironment;
PrintLogImpl: CEDAR PROGRAM
IMPORTS Commander, IO, YggLogBasic, YggLog, YggLogControl
EXPORTS YggDID, YggInternal
= BEGIN
ROPE: TYPE = Rope.ROPE;
junk
DID: PUBLIC TYPE ~ REF DIDRep;
DIDRep: PUBLIC TYPE ~ YggDIDPrivate.DIDRep;
Document: TYPE = REF DocumentRep;
DocumentRep: PUBLIC TYPE = YggDIDMapPrivate.DocumentRep;
Global data
VolatilizeTest Command
RecoveryBlock: REF ARRAY [0..4096) OF CARD32;
PrintLogProc: Commander.CommandProc = {
[cmd: Handle] RETURNS [result: REFNIL, msg: ROPENIL]
CommandObject = [in, out, err: STREAM, commandLine, command: ROPE, ...]
out: IO.STREAM;
noisy: BOOLFALSE;
offset: INT ← 0;
ok: BOOL;
checkpointWord: YggEnvironment.WordNumber;
checkpointRecord: YggLog.RecordID;
startAnalysisRecord: YggLog.RecordID;
currentRecord: YggLog.RecordID;
nextRecord: YggLog.RecordID;
out ← cmd.out;
[] ← YggLogBasic.EstablishLogFile[];
[ok, checkpointWord, checkpointRecord, startAnalysisRecord] ← YggLogControl.DiscoverWhereToStartAnalysisPass[FALSE];
IF ~ok THEN out.PutF["\nCheckpoint does not point at the start of a checkpoint record"];
out.PutF["\nCheckpoint at %g words and %g record ID, with start at %g words\n", IO.card[checkpointWord.low], IO.card[checkpointRecord.low], IO.card[startAnalysisRecord.low] ];
{
notStartOfRecord: BOOL;
[notStartOfRecord: notStartOfRecord, currentRecord: currentRecord] ←
YggLogBasic.OpenRecordStreamFromCheckpoint[checkpointWord: checkpointWord,
checkpointRecord: checkpointRecord, firstRecord: startAnalysisRecord];
IF notStartOfRecord THEN ERROR;
};
DO
status: YggLog.ReadProcStatus;
wordsRead: CARDINAL;
sizeOfRecordDataInWords: CARD;
recordHeader: LONG POINTER TO YggLogRep.TransactionHeader;
recordData: LONG POINTER;
IF YggLogBasic.CheckCurrentRecord[].truncated THEN EXIT;
[status: status, wordsRead: wordsRead] ← YggLog.ReadForRecovery[thisRecord: currentRecord, wordsToSkip: 0, to: [base: LOOPHOLE[RecoveryBlock], length: 4096]];
IF status # normal THEN ERROR;
IF wordsRead < 4 THEN ERROR; -- fix this
recordHeader ← LOOPHOLE[RecoveryBlock];
sizeOfRecordDataInWords ← wordsRead - WORDS[YggLogRep.TransactionHeader]/WORDS[CARD32];
recordData ← LOOPHOLE[RecoveryBlock, LONG POINTER] + UNITS[YggLogRep.TransactionHeader];
Now we have:
sizeOfRecordDataInWords 32 bit words of data starting at recordData
it is for optr of recordHeader.optr
= [segmentId: segmentIdT, highOffset: CARD16, lowOffset: CARD32]
TRUSTED {
out.PutF["segmentId: %g, lowOffset: %g, sizeOfRecordDataInWords: %g\n", IO.card[recordHeader.optr.segmentId.value], IO.card[recordHeader.optr.lowOffset], IO.card[sizeOfRecordDataInWords]];
};
{
endOfLog, truncatedRecord: BOOL;
[endOfLog: endOfLog, truncatedRecord: truncatedRecord, currentRecord: nextRecord] ← YggLogBasic.AdvanceRecordStream[];
IF endOfLog THEN EXIT;
};
currentRecord ← nextRecord;
ENDLOOP;
};
Initialization
Init: PROC = {
Commander.Register["PrintLog", PrintLogProc, "PrintLog "];
RecoveryBlock ← NEW[ARRAY [0..4096) OF CARD32];
};
Init[];
END.