use internal functions to speed up, not too effective in reading tho…
[shellsnippets/shellsnippets.git] / mksh / shuffle
index 3cec229..2021659 100644 (file)
@@ -1,7 +1,7 @@
 #!/usr/bin/env mksh
-# $MirOS: contrib/code/Snippets/shuffle,v 1.5 2010/11/06 14:59:20 tg Exp $
+# $MirOS: contrib/code/Snippets/shuffle,v 1.7+urandom 2012/10/19 18:59:39 tg Exp $
 #-
-# Copyright © 2006, 2010
+# Copyright © 2006, 2010, 2011, 2012
 #      Thorsten “mirabilos” Glaser <tg@mirbsd.org>
 #
 # Provided that these terms and disclaimer and all copyright notices
 # Provide shuffled input to mpg123, mplayer, mppdec, and other tools
 # that do not properly employ arc4random(3) et al.
 
-function usage {
-       print -u2 "Syntax: $0 program [args ...] -- file ... [ -- args ... ]"
-       print -u2 "To escape '--' in first args prepend another hyphen-minus"
-       exit 1
+usage() {
+       print -u2 "Syntax: $0 [-v] program [args ...] -- file ... [-- args ...]"
+       print -u2 "Prepend another hyphen-minus to escape multi-dash first-args"
+       exit ${1:-1}
 }
 
-[[ -z $1 || $1 = -@(h|H|?) ]] && usage
+[[ -z $1 || $1 = -[hH?] ]] && usage ${1:+0}
+
+if [[ $1 = -v ]]; then
+       verbose=1
+       shift
+else
+       verbose=0
+fi
 
 set -A cmdline
 set -A files
@@ -44,8 +51,8 @@ for arg in "$@"; do
        case $state {
        (0)     if [[ $arg = -- ]]; then
                        let state++
-               elif [[ $arg = --- ]]; then
-                       cmdline[ncmdline++]=--
+               elif [[ $arg = --+(-) ]]; then
+                       cmdline[ncmdline++]=${arg#-}
                else
                        cmdline[ncmdline++]=$arg
                fi
@@ -64,8 +71,8 @@ done
 (( ncmdline < 1 || nfiles < 1 )) && usage
 
 
-# arc4random(3) and arc4random_uniform(3) in Pure mksh™
-set -A seedbuf -- $(dd if=/dev/arandom bs=257 count=1 2>&- | \
+# arc4random(3) in Pure mksh™
+set -A seedbuf -- $(dd if=/dev/urandom bs=257 count=1 2>&- | \
     hexdump -ve '1/1 "0x%02X "')
 set -A rs_S
 typeset -i rs_S rs_i=-1 rs_j=0 n
@@ -93,7 +100,7 @@ function arcfour_byte {
        (( rs_S[rs_j] = si ))
        (( rs_out = rs_S[(si + sj) & 0xFF] ))
 }
-(( n = 1024 + seedbuf[256] + (RANDOM & 0xFF) ))
+(( n = 256 * 12 + seedbuf[256] + (RANDOM & 0xFF) ))
 while (( n-- )); do
        arcfour_byte
 done
@@ -118,6 +125,7 @@ function arc4random {
        (( arc4random_rv |= rs_out << 24 ))
 }
 
+# arc4random_uniform(3) in Pure mksh™
 function arc4random_uniform {
        # Derived from code written by Damien Miller <djm@openbsd.org>
        # published under the ISC licence, with simplifications by
@@ -175,8 +183,19 @@ done
 
 # Append post-command arguments, if any
 for arg in "${postfix[@]}"; do
-       cmdline[${#cmdline[*]}]=$arg
+       cmdline[ncmdline++]=$arg
 done
 
 # Run the command
+if (( verbose )); then
+       C_QUOTE=$'[]\t\n "#$&'\''()*;<=>?[\\`|]'
+       for i in "${cmdline[@]}"; do
+               if [[ $i = *${C_QUOTE}* ]]; then
+                       print -nr " '${i//\'/\'\\\'\'}'"
+               else
+                       print -nr " $i"
+               fi
+       done
+       print
+fi
 exec "${cmdline[@]}"