}
function _printf(fmt, unevald, env, d, dlave, evald, s, a, i, p) {
# mostly like _sprintf above
n = 1
dlave = _nil()
for(; !_is_null(unevald); unevald=_cdr(unevald)) {
dlave = _cons(_eval3(_car(unevald), env, env, d+1), dlave)
}
evald = _nreverse(dlave)
_list_to_flat_awk_array_of_any(evald, a)
i = 1
s = ""
fmt = _STRING[fmt]
while(fmt != "") {
if(match(fmt, /%/)) {
# vv printf the bit before the %
if(_OUTPUT_REDIR_NAME) {
if(_OUTPUT_REDIR_KIND == ">") {
printf substr(fmt, 1, RSTART-1) > _OUTPUT_REDIR_NAME
# don't re-overwrite the file with the next bit
_OUTPUT_REDIR_KIND = ">>"
} else if(_OUTPUT_REDIR_KIND == ">>") {
printf substr(fmt, 1, RSTART-1) >> _OUTPUT_REDIR_NAME
} else if(_OUTPUT_REDIR_KIND == "|") {
printf substr(fmt, 1, RSTART-1) | _OUTPUT_REDIR_NAME
}
} else {
printf substr(fmt, 1, RSTART-1)
}
# ^^
fmt = substr(fmt, RSTART)
# now do the %
if(match(fmt, /^%%/)) {
# vv printf a percent character
if(_OUTPUT_REDIR_NAME) {
if(_OUTPUT_REDIR_KIND == ">") { # shouldn't be, by now
printf "%%" > _OUTPUT_REDIR_NAME
_OUTPUT_REDIR_KIND = ">>"
} else if(_OUTPUT_REDIR_KIND == ">>") {
printf "%%" >> _OUTPUT_REDIR_NAME
} else if(_OUTPUT_REDIR_KIND == "|") {
printf "%%" | _OUTPUT_REDIR_NAME
}
} else {
printf "%%"
}
# ^^
fmt = substr(fmt, 3)
continue
}
# now the %-thing is at the beginning of fmt. how long is
# it? (grammar derived from FreeBSD printf(3); your libc
# may vary)
match(fmt,/^%[*#+ 0-9.'-]*[diouxXfFeEgGaAcsb]/);
if(i > length(a)) {
logg_err("_printf", "not enough values for printf!")
return _nil()
} else {
p = a[i++]
}
# RLENGTH is the length of the format specifier
# vv printf %omgwtfbbq, p
if(_OUTPUT_REDIR_NAME) {
if(_OUTPUT_REDIR_KIND == ">") {
printf substr(fmt,1,RLENGTH), p > _OUTPUT_REDIR_NAME
_OUTPUT_REDIR_KIND = ">>"
} else if(_OUTPUT_REDIR_KIND == ">>") {
printf substr(fmt,1,RLENGTH), p >> _OUTPUT_REDIR_NAME
} else if(_OUTPUT_REDIR_KIND == "|") {
printf substr(fmt,1,RLENGTH), p | _OUTPUT_REDIR_NAME
}
} else {
printf substr(fmt,1,RLENGTH), p
}
# ^^
fmt = substr(fmt, RLENGTH+1)
} else {
# vv no more %, printf the rest
if(_OUTPUT_REDIR_NAME) {
if(_OUTPUT_REDIR_KIND == ">") {
printf fmt > _OUTPUT_REDIR_NAME
_OUTPUT_REDIR_KIND = ">>"
} else if(_OUTPUT_REDIR_KIND == ">>") {
printf fmt >> _OUTPUT_REDIR_NAME
} else if(_OUTPUT_REDIR_KIND == "|") {
printf fmt | _OUTPUT_REDIR_NAME
}
} else {
printf fmt
}
# ^^
fmt = ""
}
}
return _nil()