MODULE M3PPSmarts; (***************************************************************************) (* Copyright (C) Olivetti 1989 *) (* All Rights reserved *) (* *) (* Use and copy of this software and preparation of derivative works based *) (* upon this software are permitted to any person, provided this same *) (* copyright notice and the following Olivetti warranty disclaimer are *) (* included in any copy of the software or any modification thereof or *) (* derivative work therefrom made by any person. *) (* *) (* This software is made available AS IS and Olivetti disclaims all *) (* warranties with respect to this software, whether expressed or implied *) (* under any law, including all implied warranties of merchantibility and *) (* fitness for any purpose. In no event shall Olivetti be liable for any *) (* damages whatsoever resulting from loss of use, data or profits or *) (* otherwise arising out of or in connection with the use or performance *) (* of this software. *) (***************************************************************************) IMPORT IO, Text; IMPORT M3AST_AS, ASTWalk, M3CSrcPos; IMPORT AST_DisplayRep, M3ASTDisplay_handle; IMPORT M3PPStream; FROM M3PPIO IMPORT Indent, DecIndent, IncIndent; CONST MaxLineLength = 78; PROCEDURE IsNLSuppressed(h: AST_DisplayRep.Handle): BOOLEAN RAISES {}= BEGIN RETURN h.nlSuppressNode # NIL; END IsNLSuppressed; PROCEDURE CheckNLSuppress( n: M3AST_AS.SRC_NODE; vm: ASTWalk.VisitMode; h: AST_DisplayRep.Handle; ) RAISES {}= BEGIN IF h.checking OR h.nlSuppressNode # NIL THEN RETURN END; IF vm = ASTWalk.VisitMode.Entry THEN h.checking := TRUE; IF FitsOnThisLine(n, h) THEN h.nlSuppressNode := n; M3PPStream.NLToSpace(h.stream, TRUE); END; h.checking := FALSE; ELSE IF n = h.nlSuppressNode THEN M3PPStream.NLToSpace(h.stream, FALSE); h.nlSuppressNode := NIL; END; END; (* if *) END CheckNLSuppress; PROCEDURE FitsOnThisLine(n: M3AST_AS.SRC_NODE; h: AST_DisplayRep.Handle): BOOLEAN RAISES {}= VAR t: M3CSrcPos.T; r: BOOLEAN; BEGIN M3PPStream.Suppress(h.stream, TRUE, t); M3PPStream.NLToSpace(h.stream, TRUE); (* recursive call to see how big this sub-tree is *) h.Visit(n); IF CurPos(h) <= MaxLineLength THEN r := TRUE; ELSE r := FALSE; END; M3PPStream.NLToSpace(h.stream, FALSE); M3PPStream.Suppress(h.stream, FALSE, t); RETURN r; END FitsOnThisLine; <*INLINE*> PROCEDURE CurPos(h: AST_DisplayRep.Handle): CARDINAL RAISES {}= VAR pos, line: CARDINAL; BEGIN line := M3CSrcPos.Unpack(M3PPStream.GetSrcPos(h.stream), pos); RETURN pos; END CurPos; PROCEDURE SeeIfStringFits( s: TEXT; wsc: CARDINAL; h: AST_DisplayRep.Handle): BOOLEAN RAISES {}= BEGIN (* Check if we need a line break before outputting 's' + 'wsc' white-space chars. *) IF h.checking THEN RETURN FALSE END; IF (Text.Length(s) + wsc + CurPos(h)) > MaxLineLength THEN IO.Put(h.stream, '\n'); IF NOT h.lineBroken THEN h.lineBroken := TRUE; IncIndent(h); IncIndent(h); END; Indent(h); RETURN TRUE ELSE RETURN FALSE END; END SeeIfStringFits; PROCEDURE SeeIfNodeFits(n: M3AST_AS.SRC_NODE; h: AST_DisplayRep.Handle) RAISES {}= BEGIN IF h.checking THEN RETURN END; h.checking := TRUE; IF NOT FitsOnThisLine(n, h) THEN IO.Put(h.stream, '\n'); IF NOT h.lineBroken THEN h.lineBroken := TRUE; IncIndent(h); IncIndent(h); END; Indent(h); END; h.checking := FALSE; END SeeIfNodeFits; PROCEDURE ResetLineBreak(h: AST_DisplayRep.Handle) RAISES {}= BEGIN IF h.lineBroken THEN h.lineBroken := FALSE; DecIndent(h); DecIndent(h) END; END ResetLineBreak; BEGIN END M3PPSmarts.