mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-09-01 21:51:40 +02:00
70 lines
1.6 KiB
Text
70 lines
1.6 KiB
Text
# Generalised printf.
|
|
# Arguments of the form -%X=... give the output to be used with
|
|
# the directive %x.
|
|
#
|
|
# -P indicates that any unhandled directives are to be
|
|
# passed to printf. With this option, any %-escapes passed to printf
|
|
# are assumed to consume exactly one argument from the command line.
|
|
# Unused command line arguments are ignored. This is only minimally
|
|
# implemented.
|
|
#
|
|
# -R indicates the value is to be put into REPLY rather than printed.
|
|
#
|
|
# -r indicates that print formatting (backslash escapes etc.) should
|
|
# not be replied to the result. When using -R, no print formatting
|
|
# is applied in any case.
|
|
|
|
emulate -L zsh
|
|
setopt extendedglob
|
|
|
|
local opt printf fmt usereply match mbegin mend raw c
|
|
typeset -A chars
|
|
chars=(% %)
|
|
|
|
while getopts "%:PrR" opt; do
|
|
case $opt in
|
|
(%) if [[ $OPTARG != ?=* ]]; then
|
|
print -r "Bad % option: should be -%${OPTARG[1]}=..." >&2
|
|
return 1
|
|
fi
|
|
chars[${OPTARG[1]}]=${OPTARG[3,-1]}
|
|
;;
|
|
(P) printf=1
|
|
;;
|
|
(r) raw=-r
|
|
;;
|
|
(R) usereply=1
|
|
;;
|
|
esac
|
|
done
|
|
(( OPTIND > 1 )) && shift $(( OPTIND - 1 ))
|
|
|
|
[[ -z $usereply ]] && local REPLY
|
|
REPLY=
|
|
|
|
if (( $# )); then
|
|
fmt=$1
|
|
shift
|
|
fi
|
|
|
|
while [[ $fmt = (#b)([^%]#)%([-0-9.*]#?)(*) ]]; do
|
|
REPLY+=$match[1]
|
|
c=$match[2]
|
|
fmt=$match[3]
|
|
if [[ -n ${chars[$c]} ]]; then
|
|
REPLY+=${chars[$c]}
|
|
elif [[ -n $P ]]; then
|
|
# hmmm, we need sprintf...
|
|
# TODO: %ld etc.
|
|
REPLY+=`printf "%$c" $1`
|
|
(( $? )) && return 1
|
|
shift
|
|
else
|
|
print -r "Format not handled: %$c" >&2
|
|
return 1
|
|
fi
|
|
done
|
|
|
|
REPLY+=$fmt
|
|
[[ -z $usereply ]] && print -n $raw - $REPLY
|
|
return 0
|