Author: dteske
Date: Wed Jan 27 02:11:58 2016
New Revision: 294880
URL: https://svnweb.freebsd.org/changeset/base/294880

Log:
  Replace awk with more efficient builtins-only algo

Modified:
  head/usr.sbin/bsdconfig/share/strings.subr

Modified: head/usr.sbin/bsdconfig/share/strings.subr
==============================================================================
--- head/usr.sbin/bsdconfig/share/strings.subr  Wed Jan 27 02:08:30 2016        
(r294879)
+++ head/usr.sbin/bsdconfig/share/strings.subr  Wed Jan 27 02:11:58 2016        
(r294880)
@@ -70,17 +70,63 @@ f_substr()
 #
 f_snprintf()
 {
+       local __funcname=f_snprintf
        local __var_to_set="$1" __size="$2"
        shift 2 # var_to_set size
-       eval "$__var_to_set"=\$\( printf -- \"\$@\" \| \
-               awk -v max=\"\$__size\" \''
-       {
-               len = length($0)
-               max -= len
-               print substr($0,0,(max > 0 ? len : max + len))
-               if ( max < 0 ) exit
-               max--
-       }'\' \)
+
+       if [ "$__size" -eq 0 ] 2> /dev/null; then
+               setvar "$__var_to_set" ""
+               return ${SUCCESS:-0}
+       elif [ $? -ge 2 ] || [ $__size -lt 0 ]; then
+               setvar "$__var_to_set" ""
+               echo "$__funcname: invalid size argument \`__size'" >&2
+               return ${FAILURE:-1}
+       fi
+
+       local __f_snprintf_tmp
+       f_sprintf __f_snprintf_tmp "$@"
+
+       local __tmp_size=${#__f_snprintf_tmp}
+       local __trim=$(( $__tmp_size - $__size )) __trimq
+       local __tbuf __tbuf_len
+       local __mask __mask_len
+       while [ $__trim -gt 0 ]; do
+               __tbuf="?"
+               __tbuf_len=1
+               if [ $__trim -le $__size ]; then
+                       while [ $__tbuf_len -lt $(( $__trim / $__tbuf_len )) ]
+                       do
+                               __tbuf="$__tbuf?"
+                               __tbuf_len=$(( $__tbuf_len + 1 ))
+                       done
+                       __trimq=$(( $__trim / $__tbuf_len ))
+                       __trim=$(( $__trim - $__tbuf_len * $__trimq ))
+                       while [ $__trimq -gt 0 ]; do
+                               __f_snprintf_tmp="${__f_snprintf_tmp%$__tbuf}"
+                               __trimq=$(( $__trimq - 1 ))
+                       done
+               else
+                       __mask="$__f_snprintf_tmp"
+                       while [ $__tbuf_len -lt $(( $__size / $__tbuf_len )) ]
+                       do
+                               __tbuf="$__tbuf?"
+                               __tbuf_len=$(( $__tbuf_len + 1 ))
+                       done
+                       __trimq=$(( $__size / $__tbuf_len ))
+                       if [ $(( $__trimq * $__tbuf_len )) -ne $__size ]; then
+                               __tbuf="$__tbuf?"
+                               __tbuf_len=$(( $__tbuf_len + 1 ))
+                       fi
+                       __mask_len=$(( $__tmp_size - $__tbuf_len * $__trimq ))
+                       __trim=$(( $__tmp_size - $__mask_len - $__size ))
+                       while [ $__trimq -gt 0 ]; do
+                               __mask="${__mask#$__tbuf}"
+                               __trimq=$(( $__trimq - 1 ))
+                       done
+                       __f_snprintf_tmp="${__f_snprintf_tmp%"$__mask"}"
+               fi
+       done
+       setvar "$__var_to_set" "$__f_snprintf_tmp"
 }
 
 # f_sprintf $var_to_set $format [$arguments ...]
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to