-- The Program FogIO. -- The file handler for program Fog. -- Documentation on [Ivy]FogReport.press. -- Last edited by McKeeman on December 17, 1980 3:41 PM -- Last edited by Brotz on December 16, 1980 2:51 PM -- Version for Laurel RUN command. -- Author: W.M. McKeeman. -- Consultants: J.J. Horning, D. Brotz. DIRECTORY Ascii, FogDefs, FrameDefs, inD: FROM "InteractorDefs", InlineDefs, InsertMailDefs, intCommon, IODefs, LaurelExecDefs, SegmentDefs, StreamDefs, TimeDefs, ovD: FROM "OverviewDefs", vmD: FROM "VirtualMgrDefs"; FogIO:z19932e12k40(635)\3b18B536b5B PROGRAM IMPORTS FogDefs, FrameDefs, InlineDefs, InsertMailDefs, intC: intCommon, IODefs, LaurelExecDefs, SegmentDefs, StreamDefs, TimeDefs, vmD EXPORTS FogDefs =z19932k40 BEGIN OPEN FogDefs;z19932k40 -- Global variables and constants. -- A counter for the last LA characters after EoF is sensed. chleft: INTEGER; -- A counter for the input characters processed. chprocessed: LONG CARDINAL _ 0; laurelPresent: BOOLEAN = FrameDefs.IsBound[LaurelExecDefs.MakeMenuCommandCallable]; message: vmD.ComposeMessagePtr _ IF laurelPresent THEN LOOPHOLE[intC.cmTextNbr.message] ELSE NIL; messageLength: ovD.CharIndex _ IF laurelPresent AND message # NIL THEN vmD.GetMessageSize[message] ELSE 0; charIndex: ovD.CharIndex _ 0; outMessage: vmD.ComposeMessagePtr _ NIL; Ch: PUBLIC ARRAY [0..LA] OF CHARACTER; -- Steady state: EoF=FALSE chleft=2 |ch|ch|ch| -- after EoF EoF=TRUE chleft=1 |ch|ch|? | -- EoF=TRUE chleft=0 |ch|? |? | FileIn, FileOut, Keyboard: StreamDefs.StreamHandle; z19932k40 EoS: PUBLIC SIGNAL = CODE; -- End of Stream, LA characters after EoF. QuickQuit: SIGNAL = CODE; -- User hit DEL to stop processing. Open: PROCEDURE[FileName: STRING] RETURNS [h: StreamDefs.StreamHandle] = BEGIN -- Hook onto composition window. SELECT TRUE FROM laurelPresent => BEGIN h _ NIL; IF FileName[4] = 'o THEN -- kludge to identify "Fog.out" BEGIN outMessage _ vmD.AllocateComposeMessageObject[]; vmD.InitComposeMessage[outMessage, ""L]; END; END; FileName[4] = 'o => -- kludge to identify "Fog.out" BEGIN h _ StreamDefs.CreateByteStream[ SegmentDefs.NewFile [FileName, StreamDefs.Write+StreamDefs.Append, SegmentDefs.DefaultVersion], StreamDefs.Write+StreamDefs.Append]; IODefs.SetOutputStream[h]; END; FileName[4] = 'i => -- kludge to identify "Fog.in" BEGIN h _ StreamDefs.CreateByteStream[ SegmentDefs.NewFile[FileName, StreamDefs.Read, SegmentDefs.DefaultVersion], StreamDefs.Read]; IODefs.SetInputStream[h]; END; ENDCASE => ERROR; END; z19932k40\b3B70b9B55b5B Close: PROCEDURE[File: StreamDefs.StreamHandle] = BEGIN IF laurelPresent THEN BEGIN IF outMessage # NIL THEN BEGIN InsertMailDefs.InsertVMInMailFile [outMessage, vmD.GetFirstFreeTOCIndex[]]; vmD.FreeVirtualMessageObject[outMessage]; END; outMessage _ NIL; END ELSE File.destroy[File]; END; z19932k40\b5B EoF: PUBLIC PROCEDURE[File: StreamDefs.StreamHandle] RETURNS[BOOLEAN] = BEGIN -- Detect end-of-file in composition window. IF laurelPresent THEN RETURN[charIndex >= messageLength] ELSE RETURN[File.endof[File]]; END; GetChar: PUBLIC PROCEDURE[] RETURNS[char: CHARACTER] = BEGIN -- Read character from input file. IF laurelPresent THEN BEGIN char _ vmD.GetMessageChar[message, charIndex]; charIndex _ charIndex + 1; END ELSE RETURN[IODefs.ReadChar[]]; chprocessed _ chprocessed + 1; -- Count the input characters. END; PutChar: PUBLIC PROCEDURE[ch: CHARACTER] = BEGIN -- Pass character to output file. IF laurelPresent THEN [] _ vmD.AppendMessageChar[outMessage, ch] ELSE IODefs.WriteChar[ch] -- Pass ch to the output file. END; PutString: PUBLIC PROCEDURE[s: STRING] = BEGIN -- Pass string to output file. FOR i: CARDINAL IN [0..s.length) DO PutChar[s[i]] ENDLOOP; END; PutDecimal: PUBLIC PROCEDURE[n: LONG CARDINAL] = BEGIN -- Pass character to output file. digit: ARRAY[0..20] OF CHARACTER; i, j: INTEGER; FOR i DECREASING IN [0..20] DO digit[i] _ '0 + InlineDefs.LowHalf[n MOD 10]; n _ n / 10; IF n = 0 THEN EXIT; ENDLOOP; FOR j IN [i..20] DO PutChar[digit[j]] ENDLOOP; END; StepInputOutput: PUBLIC PROCEDURE = BEGIN -- Pass examined character to output file and update lookahead. PutChar[FogDefs.Ch[0]]; StepInput[]; END; z19932k40\b3B222b7B319b7B211b9B140b10B322b15B StepInput: PUBLIC PROCEDURE = BEGIN -- Update lookahead with fresh input (if any). i: INTEGER; -- Give the user a chance to signal DEL. WHILE ~Keyboard.endof[Keyboard] DO IF Keyboard.get[Keyboard] = Ascii.DEL THEN SIGNAL QuickQuit; ENDLOOP; IF chleft=0 THEN SIGNAL EoS; -- Push lookahead up. FOR i IN [0..FogDefs.LA) DO FogDefs.Ch[i] _ FogDefs.Ch[i+1] ENDLOOP; FogDefs.Ch[FogDefs.LA] _ Ascii.NUL; -- Default lookahead beyond EoF. IF chleft = FogDefs.LA AND EoF[FileIn] THEN chleft _ FogDefs.LA-1 ELSE IF chleft = FogDefs.LA THEN FogDefs.Ch[FogDefs.LA] _ GetChar[] ELSE chleft _ chleft-1; END; z19932k40\b9B ReportStatistics: PUBLIC PROCEDURE[Index, Fogp, Fogs, Fogw: LONG INTEGER] = BEGIN PutChar[Ascii.CR]; PutChar[Ascii.CR]; PutString[" Fog Analysis: [P S W] = ["]; PutDecimal[Fogp]; PutChar[Ascii.SP]; PutDecimal[Fogs]; PutChar[Ascii.SP]; PutDecimal[Fogw]; PutString["], Fog Index = "]; PutDecimal[Index]; PutChar['.]; PutChar[Ascii.CR]; PutChar[Ascii.CR]; END; z19932k40\b16B30o252 1o0 5o252 1o0 5o252 1o0 128o252 1o0 40o252 1o0 38o252 1o0 Prolog: PROCEDURE = BEGIN i: INTEGER; d: STRING _ [100]; Keyboard _ IODefs.GetInputStream[]; -- Set up IO path to composition window. FileIn _ Open["Fog.in"]; FileOut _ Open["Fog.out"]; -- Header. PutString["Date: "]; d.length _ 0; TimeDefs.AppendDayTime[d, TimeDefs.UnpackDT[TimeDefs.CurrentDayTime[]]]; PutString[d]; PutChar[Ascii.CR]; PutString["From: Fog"]; PutChar[Ascii.CR]; PutString["Subject: Analysis: [P S W] signifies complexity is in Paragraph, Sentence and Word structure, respectively."]; PutChar[Ascii.CR]; PutChar[Ascii.CR]; -- Set up lookahead. IF EoF[FileIn] THEN SIGNAL EoS; -- Ridiculously short file. FOR i IN [0..FogDefs.LA] DO IF EoF[FileIn] THEN EXIT -- Ridiculously short file. ELSE FogDefs.Ch[i] _ GetChar[]; chleft _ i; ENDLOOP; END; z19932k40\b6B Epilog: PROCEDURE[ReportParagraphs, RecordFog, TotalFog, Reports: LONG INTEGER] = BEGIN -- Print trailing information. PutChar[Ascii.CR]; PutChar[Ascii.CR]; PutString[" End of fog index utility run:"]; PutChar[Ascii.CR]; PutDecimal[ReportParagraphs]; PutString[" paragraphs consisting of "]; PutDecimal[chprocessed]; PutString[" characters processed."]; PutChar[Ascii.CR]; PutString["Maximum index = "]; PutDecimal[RecordFog]; IF Reports>0 THEN BEGIN -- Avoid divide by zero in pathological cases. PutString[", average index = "]; PutDecimal[TotalFog/Reports]; END; PutChar[Ascii.CR]; END; z19932k40\b6B Main: PROCEDURE = BEGIN ENABLE BEGIN EoS => GOTO NullFile; QuickQuit => GOTO QuickAbort; END; ReportParagraphs, RecordFog, TotalFog, Reports: LONG INTEGER; Prolog[]; [ReportParagraphs, RecordFog, TotalFog, Reports] _ FogDefs.ComputeFog[]; -- Report results in composition window. Epilog[ReportParagraphs, RecordFog, TotalFog, Reports]; Close[FileIn]; Close[FileOut]; EXITS NullFile => BEGIN PutString[" Empty input file."]; Close[FileIn]; Close[FileOut]; END; QuickAbort => BEGIN PutChar[Ascii.CR]; PutString[" User-requested abrupt termination."]; PutChar[Ascii.CR]; Close[FileIn]; Close[FileOut]; END; END; z19932k40\b4B Main[]; END.z19932k40