blob: c448b35a21e46c6659bd508b9e0d97b86846c323 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
# 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
|