scc@cl.cam.ac.uk (Stephen Crawley) (01/31/89)
I found that I needed a routine for unparsing integers in hexadecimal with leading zero padding. The MIT libraries include a routine i_hunparse, but it is too simple minded for the job in hand. So I've written a routine i_unparse() that solves the general problem. -- Steve ================ %% Unparse an integer into a string. %% 'i' is the number to be unparsed. %% 'base' is the base for the number which must be in the %% range 2 <= base <= 36. %% 'width' is the minimum width for the result string. %% If 'zero_fill' is TRUE the result is padded with zeros to the left. %% If 'left_adjust' is TRUE the result is padded with spaces to the right. %% Otherwise the result is padded with spaces to the left hand. i_unparse = PROC (i, base, width: int, zero_fill, left_adjust: bool) RETURNS (string) SIGNALS (bad_args) ac = array[char] OWN digits: string := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" IF base <= 1 COR base > string$size(digits) COR width < 0 COR width > 2**16 - 1 THEN SIGNAL bad_args END hi: int := width fill: char := ' ' IF width = 0 THEN hi := 20 left_adjust := FALSE zero_fill := FALSE ELSEIF zero_fill THEN fill := '0' left_adjust := FALSE END chars: ac := ac$fill(1, hi, fill) pos: int := hi IF i = 0 THEN chars[pos] := '0' pos := pos - 1 ELSE negative: bool := i < 0 IF negative THEN i := -i END EXCEPT WHEN overflow: %% Phooey!!! MIN_INT can't be negated! %% Do the 1st loop iteration by steam. i := -(i + 1) d: int := i // base + 1 i := i / base IF d = base THEN d := 0 i := i + 1 END chars[pos] := digits[d + 1] pos := pos - 1 END %% Build the digits WHILE i > 0 DO digit: char := digits[i // base + 1] i := i / base IF pos > 0 THEN chars[pos] := digit ELSE ac$addl(chars, digit) END pos := pos - 1 END %% Prepend the '-' sign before the 1st digit IF negative THEN IF pos <= 0 THEN ac$addl(chars, '-') pos := pos - 1 ELSEIF zero_fill THEN chars[1] := '-' pos := 0 ELSE chars[pos] := '-' pos := pos - 1 END END END %% Left adjust by shuffling the chars down and filling with ' 's IF left_adjust CAND pos > 0 THEN FOR j: int IN int$from_to(1, hi - pos) DO chars[j] := chars[j + pos] END FOR j: int IN int$from_to(hi - pos + 1, hi) DO chars[j] := ' ' END END IF width = 0 CAND pos > 0 THEN ac$trim(chars, pos + 1, hi - pos) END RETURN (string$ac2s(chars)) END i_unparse ================ %% Unparse an integer in hexadecimal i_hunparse = PROC (i: int) RETURNS (string) RETURN (i_unparse(i, 16, 0, FALSE, FALSE)) END i_hunparse ================ %% Unparse an integer in octal i_ounparse = PROC (i: int) RETURNS (string) RETURN (i_unparse(i, 8, 0, FALSE, FALSE)) END i_ounparse