printf %s is not lazy enough
Taking a fixpoint of printf fix (printf "a%s") :: String, or printf'ing an infinite string printf "%s" (repeat ' ') :: String either fails with stack overflow or diverges.
The culprit is in this code:
fmt cs us =
let (width, prec, ladj, zero, plus, cs', us') = getSpecs False False False cs us
adjust (pre, str) =
let lstr = length str
lpre = length pre
fill = if lstr+lpre < width then take (width-(lstr+lpre)) (repeat (if zero then '0' else ' ')) else ""
in if ladj then pre ++ str ++ fill else if zero then pre ++ fill ++ str else fill ++ pre ++ str
If width == 0, then no filling should be done, but the code is still forcing the evaluation of lstr and lpre (which in the case of an infinite str does not ever complete). A simple fix is to check that width is larger than zero before trying to test width against lstr and lpre, like this:
fill = if width > 0 && lstr+lpre < width then {-etc-}
Trac metadata
| Trac field | Value |
|---|---|
| Version | 6.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries/base |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | Unknown |
| Architecture | Unknown |