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; DID: PUBLIC TYPE ~ REF DIDRep; DIDRep: PUBLIC TYPE ~ YggDIDPrivate.DIDRep; Document: TYPE = REF DocumentRep; DocumentRep: PUBLIC TYPE = YggDIDMapPrivate.DocumentRep; RecoveryBlock: REF ARRAY [0..4096) OF CARD32; PrintLogProc: Commander.CommandProc = { out: IO.STREAM; noisy: BOOL _ FALSE; 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]; 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; }; Init: PROC = { Commander.Register["PrintLog", PrintLogProc, "PrintLog "]; RecoveryBlock _ NEW[ARRAY [0..4096) OF CARD32]; }; Init[]; END. τPrintLogImpl.mesa Copyright Σ 1989 by Xerox Corporation. All rights reserved. Bob Hagmann May 30, 1989 3:56:05 pm PDT junk Global data VolatilizeTest Command [cmd: Handle] RETURNS [result: REF _ NIL, msg: ROPE _ NIL] CommandObject = [in, out, err: STREAM, commandLine, command: ROPE, ...] 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] Initialization ΚΣ˜šœ™Icodešœ<™