diff options
Diffstat (limited to 'Functions/TCP/zgprintf')
-rw-r--r-- | Functions/TCP/zgprintf | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/Functions/TCP/zgprintf b/Functions/TCP/zgprintf new file mode 100644 index 000000000..c448b35a2 --- /dev/null +++ b/Functions/TCP/zgprintf @@ -0,0 +1,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 |