-- PPHelperImpl.mesa -- Russ Atkinson, June 9, 1982 3:49 pm DIRECTORY Ascii USING [ControlZ, CR, FF, TAB], PPHelper, PPLeaves USING [HTIndex, LTIndex], PPP1 USING [IdOfLock], PPTree USING [Handle, Link, NodeName], PPTreeOps USING [NSons, NthSon], PPUtil USING [ShowChar], Rope USING [Equal, ROPE, Text]; PPHelperImpl: CEDAR PROGRAM IMPORTS PPP1, PPTreeOps, PPUtil, Rope EXPORTS PPHelper SHARES Rope = BEGIN OPEN Ascii, PPLeaves, PPTreeOps, Tree: PPTree, Rope; LockId: HTIndex ← PPP1.IdOfLock[]; -- this handle is used to hold on to the log stream indent, position, line, page: PUBLIC INT ← 0; sizing: PUBLIC BOOL ← FALSE; lastChar: PUBLIC CHAR ← 0C; lateTrigger: PUBLIC INT ← 80; earlyTrigger: PUBLIC INT ← 64; Excess: PUBLIC ERROR = CODE; Init: PUBLIC PROC = { indent ← position ← line ← page ← 0; sizing ← FALSE; }; GetInfo: PUBLIC PROC [t: Tree.Link] RETURNS [info: INT] = { DO WITH t SELECT FROM hti: HTIndex => info ← IF hti = LockId THEN 0 ELSE hti.index; lti: LTIndex => info ← lti.index; x: Tree.Handle => {info ← x.info; IF info = 0 THEN FOR i: NAT IN [1..NSons[t]] WHILE info = 0 DO info ← GetInfo[NthSon[t, i]] ENDLOOP} ENDCASE => info ← 0; EXIT ENDLOOP}; GetAttrs: PUBLIC PROC [t: Tree.Link] RETURNS [a1,a2,a3: BOOL] = { WITH t SELECT FROM x: Tree.Handle => RETURN [x.attr[1], x.attr[2], x.attr[3]] ENDCASE => a1 ← a2 ← a3 ← FALSE}; WriteChar: PUBLIC PROC [c: CHAR] = { IF (lastChar ← c) < 40C THEN {SELECT c FROM TAB => {position ← position + 8; position ← position - position MOD 8; lastChar ← ' }; CR => {position ← 0; line ← line + 1}; FF => {position ← 0; line ← 0; page ← page + 1}; ENDCASE} ELSE position ← position + 1; IF sizing THEN {IF lastChar # ' AND position >= lateTrigger THEN ERROR Excess; RETURN}; TRUSTED {PPUtil.ShowChar[c]}}; WriteId: PUBLIC PROC [r: ROPE] = { s: Text ← NARROW[r]; c: CHAR ← lastChar ← 'A; len: NAT ← IF s = NIL THEN 0 ELSE s.length; IF len = 0 THEN RETURN; c ← s[0]; IF c IN ['B..'C] THEN {-- could be a trivial translation SELECT len FROM 7 => IF Rope.Equal[s, "BOOLEAN"] THEN {s ← "BOOL"; len ← 4}; 9 => IF Rope.Equal[s, "CHARACTER"] THEN {s ← "CHAR"; len ← 4}; ENDCASE}; position ← position + len; IF sizing THEN {IF position > lateTrigger THEN ERROR Excess; RETURN}; FOR i: NAT IN [0..len) DO TRUSTED {PPUtil.ShowChar[s[i]]}; ENDLOOP}; WriteText: PUBLIC PROC [r: ROPE] = { -- we assume that the rope has been flattened -- an error occurs if it is not IF r # NIL THEN { s: Text = NARROW[r]; FOR i: NAT IN [0..s.length) DO c: CHAR ← s[i]; IF c = Ascii.ControlZ THEN {WriteChar[Ascii.CR]; RETURN}; WriteChar[c] ENDLOOP}}; WriteQuotedText: PUBLIC PROC [r: ROPE] = { -- we assume that the rope has been flattened -- an error occurs if it is not -- we also assume that the scanner has escape marks in -- but that the leading and trailing quotes are gone WriteChar['"]; IF r # NIL THEN { s: Text = NARROW[r]; FOR i: NAT IN [0..s.length) DO WriteChar[s[i]]; ENDLOOP}; WriteChar['"]}; Indent: PUBLIC PROC = { count: INT ← indent - position; WHILE (count←count-1) >= 0 DO WriteChar[' ] ENDLOOP}; Break: PUBLIC PROC = { IF position > indent THEN WriteChar[CR]; Indent[]}; END.