-- file: FormatImpl.mesa; last edit: -- Mark: Apr 11, 1980 12:37 PM -- Evans: May 19, 1980 10:28 AM -- JGS: August 12, 1980 12:09 PM -- Karlton: July 24, 1980 8:41 AM -- Smokey: Aug 4, 1980 2:56 PM -- Forrest: October 25, 1980 8:32 PM DIRECTORY Format USING [ DateFormat, LongSubString, LongSubStringDescriptor, NumberFormat, StringProc], String USING [AppendLongNumber, AppendNumber, AppendChar, SubString], Time USING [Append, Packed, Unpack]; FormatImpl: PROGRAM IMPORTS String, Time EXPORTS Format = BEGIN OPEN Format, String; -- Public procedures Char: PUBLIC PROCEDURE [c: CHARACTER, proc: StringProc] = BEGIN s: STRING ← [2]; s[0] ← c; s.length ← 1; proc[s] END; Date: PUBLIC PROCEDURE [ pt: Time.Packed, format: DateFormat ← noSeconds, proc: StringProc] = BEGIN s: STRING ← [22]; Time.Append[s, Time.Unpack[pt], TRUE]; s.length ← s.length-(SELECT format FROM dateOnly => 13, noSeconds => 7, dateTime => 4, ENDCASE => 0); proc[s] END; LongNumber: PUBLIC PROCEDURE [ n: LONG UNSPECIFIED, format: NumberFormat, proc: StringProc] = BEGIN s: STRING ← [34]; neg: BOOLEAN; IF LOOPHOLE[n, LONG INTEGER] < 0 AND ~format.unsigned THEN {n ← -LOOPHOLE[n, LONG INTEGER]; neg ← TRUE} ELSE neg ← FALSE; AppendLongNumber[s, n, format.base]; FormatNumber[s: s, format: format, neg: neg, proc: proc]; END; LongOctal: PUBLIC PROCEDURE [n: LONG CARDINAL, proc: StringProc] = BEGIN s: STRING ← [12]; AppendLongNumber[s, n, 8]; IF n > 7 THEN AppendChar[s, 'B]; proc[s]; END; LongString: PUBLIC PROCEDURE [s: LONG STRING, proc: StringProc] = BEGIN IF s#NIL THEN BEGIN lss: LongSubStringDescriptor ← [base: s, offset: 0, length: s.length]; LongSubStringItem[@lss, proc]; END; END; LongSubStringItem: PUBLIC PROCEDURE [ss: LongSubString, proc: StringProc] = BEGIN -- Repeatedly calls proc with strings filled from ss s: STRING ← [100]; sPos, ssPos: CARDINAL ← 0; IF ss = NIL OR ss.base = NIL OR ss.base.length = 0 THEN RETURN[]; s.length ← 0; FOR ssPos IN [ss.offset..MIN[ss.base.length, ss.offset+ss.length]) DO IF sPos >= s.maxlength THEN {IF s.length # 0 THEN proc[s]; sPos ← 0; s.length ← 0}; s[sPos] ← ss.base[ssPos]; s.length ← s.length+1; sPos ← sPos+1; REPEAT FINISHED => IF s.length # 0 THEN proc[s]; ENDLOOP; RETURN[]; END; Number: PUBLIC PROCEDURE [n: UNSPECIFIED, format: NumberFormat, proc: StringProc] = BEGIN s: STRING ← [18]; neg: BOOLEAN; IF INTEGER[n] < 0 AND ~format.unsigned THEN {n ← -INTEGER[n]; neg ← TRUE} ELSE neg ← FALSE; AppendNumber[s, n, format.base]; FormatNumber[s: s, format: format, neg: neg, proc: proc]; END; Octal: PUBLIC PROCEDURE [n: CARDINAL, proc: StringProc] = BEGIN s: STRING ← [10]; AppendNumber[s, n, 8]; IF n > 7 THEN AppendChar[s, 'B]; proc[s]; END; SubString: PUBLIC PROCEDURE [ss: String.SubString, proc: StringProc] = BEGIN IF ss#NIL THEN BEGIN lss: LongSubStringDescriptor ← [base: ss.base, offset: ss.offset, length: ss.length]; LongSubStringItem[@lss, proc]; END; END; -- Private procedures FormatNumber: PROCEDURE [ s: STRING, format: NumberFormat, neg: BOOLEAN, proc: StringProc] = BEGIN l: CARDINAL; fill: STRING ← (IF format.zerofill THEN "00000000"L ELSE " "L ); l ← s.length + (IF neg THEN 1 ELSE 0); IF l < format.columns THEN BEGIN fillChars: CARDINAL ← format.columns - l; IF neg AND format.zerofill THEN Char['-, proc]; THROUGH [0..fillChars/8) DO proc[fill]; ENDLOOP; IF (fill.length ← fillChars MOD 8) # 0 THEN proc[fill]; IF neg AND ~format.zerofill THEN Char['-, proc]; END ELSE IF neg THEN Char['-, proc]; proc[s]; END; -- Mainline Code END.