summaryrefslogtreecommitdiff
path: root/ipl/procs/printf.icn
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2013-01-28 19:02:21 +0000
committerIgor Pashev <pashev.igor@gmail.com>2013-01-28 19:02:21 +0000
commitf627f77f23d1497c9e1f4269b5c8812d12b42f18 (patch)
tree708772d83a8355e25155cf233d5a9e38f8ad4d96 /ipl/procs/printf.icn
parent6ab0c0f5bf14ed9c15370407b9ee7e0b4b089ae1 (diff)
downloadicon-f627f77f23d1497c9e1f4269b5c8812d12b42f18.tar.gz
Imported Upstream version 9.5.0upstream/9.5.0upstream
Diffstat (limited to 'ipl/procs/printf.icn')
-rw-r--r--ipl/procs/printf.icn133
1 files changed, 44 insertions, 89 deletions
diff --git a/ipl/procs/printf.icn b/ipl/procs/printf.icn
index b5f99b9..b264692 100644
--- a/ipl/procs/printf.icn
+++ b/ipl/procs/printf.icn
@@ -6,7 +6,7 @@
#
# Author: William H. Mitchell
#
-# Date: July 20, 2005
+# Date: February 13, 2006
#
############################################################################
#
@@ -14,30 +14,19 @@
#
############################################################################
#
-# Contributors: Cheyenne Wills, Phillip Lee Thomas, Michael Glass
+# Contributors: Cheyenne Wills, Phillip Lee Thomas,
+# Michael Glass, Gregg M. Townsend
#
############################################################################
#
# This procedure behaves somewhat like the standard printf.
# Supports d, e, s, o, and x formats like printf. An "r" format
-# prints real numbers in a manner similar to that of printf's "f",
-# but will produce a result in an exponential format if the number
-# is larger than the largest integer plus one. Though "e" differs
-# from printf in some details, it always produces exponential format.
+# prints real numbers in a manner similar to that of printf's "f".
+# Though "e" differs from printf in some details, it always produces
+# exponential format.
#
-# Left or right justification and field width control are pro-
-# vided as in printf. %s, %r, and %e handle precision specifications.
-#
-# The %r format is quite a bit of a hack, but it meets the
-# author's requirements for accuracy and speed. Code contributions
-# for %f, %e, and %g formats that work like printf are welcome.
-#
-# Possible new formats:
-#
-# %t -- print a real number as a time in hh:mm
-# %R -- roman numerals
-# %w -- integers in English
-# %b -- binary
+# Left or right justification and field width control are provided
+# as in printf. %s, %r, and %e handle precision specifications.
#
############################################################################
@@ -100,86 +89,52 @@ procedure _doprnt(format, args)
end
procedure hexstr(n)
- local h, neg
- static BigNeg, hexdigs, hexfix
-
- initial {
- BigNeg := -2147483647-1
- hexdigs := "0123456789abcdef"
- hexfix := "89abcdef"
- }
-
- n := integer(n)
- if n = BigNeg then
- return "80000000"
- h := ""
- if n < 0 then {
- n := -(BigNeg - n)
- neg := 1
- }
- repeat {
- h := hexdigs[n%16+1]||h
- if (n /:= 16) = 0 then
- break
- }
- if \neg then {
- h := right(h,8,"0")
- h[1] := hexfix[h[1]+1]
- }
- return h
+ return _basestr(n, 4)
end
+
procedure octstr(n)
- local h, neg
- static BigNeg, octdigs, octfix
+ return _basestr(n, 3)
+end
- initial {
- BigNeg := -2147483647-1
- octdigs := "01234567"
- octfix := "23"
- }
+procedure _basestr(n, b)
+ local s, mask
- n := integer(n)
- if n = BigNeg then
- return "20000000000"
- h := ""
- if n < 0 then {
- n := -(BigNeg - n)
- neg := 1
- }
- repeat {
- h := octdigs[n%8+1]||h
- if (n /:= 8) = 0 then
- break
- }
- if \neg then {
- h := right(h,11,"0")
- h[1] := octfix[h[1]+1]
+ n := integer(n) | return image(n)
+
+ if n = 0 then
+ return "0"
+
+ # backwards compatibility hack
+ # treat 31-bit negative integers as positive values
+ if -16r80000000 <= n <= -1 then
+ n +:= 16r100000000
+
+ s := ""
+ mask := ishift(1, b) - 1
+ while n ~= 0 & n ~= -1 do {
+ s := "0123456789abcdef" [1 + iand(n, mask)] || s
+ n := ishift(n, -b)
}
- return h
+ return s
end
procedure fixnum(x, prec)
- local int, frac, f1, f2, p10
+ local s
/prec := 6
x := real(x) | return image(x)
- int := integer(x) | return image(x)
- frac := image(x - int)
- if find("e", frac) then {
- frac ?:= {
- f1 := tab(upto('.')) &
- move(1) &
- f2 := tab(upto('e')) &
- move(1) &
- p10 := -integer(tab(0)) &
- repl("0",p10-1) || f1 || f2
- }
- }
+
+ if x < 0 then {
+ s := "-"
+ x := -x
+ }
else
- frac ?:= (tab(upto('.')) & move(1) & tab(0))
- frac := adjustfracprec(frac, prec)
- int +:= if int >= 0 then frac[2] else -frac[2]
- return int || "." || frac[1]
+ s := ""
+
+ x := string(integer(x * 10 ^ prec + 0.5))
+ if *x <= prec then
+ x := right(x, prec + 1, "0")
+ return s || x[1:-prec] || "." || x[-prec:0]
end
@@ -302,10 +257,10 @@ procedure adjustfracprec(fracpart, prec)
carryout := 1
}
# In the usual case, round up simply increments the
- # fractional part. (We put back any trailing
+ # fractional part. (We put back any leading
# zeros that got lost.)
else {
- fracpart := left(integer(fracpart)+1, prec, "0")
+ fracpart := right(integer(fracpart)+1, prec, "0")
}
}
}