While porting the script to FreeBSD I've made a few changes.
Can someone test them on non-ancient Linux?

I've myself tested only on

  GNU sed 4.2.1[1]
  GNU sleep 7.5
  bash 4.1.7
  dash 0.5.6[2]
  rlwrap 0.36

without installing real Linux system. So, I'm not sure how well
e.g. termcap solution will work there.

[1] compatible with -E option
[2] bultin echo there prints both \102 and \0102 as B

 - try to guess whether sleep(1) supports fractions
 - remove GNUisms from sed(1) lines without breaking GNU sed usage
 - try termcap(5) capabilities first
 - correct example line in usage
 - prevent word splitting when reading command list
 - remove command list on SIGINT and SIGTERM, too
 - don't use backquotes, they have side effect of removing one layer of quoting
 - prevent glob expansion when stripping output

---
 contrib/stumpish |   93 ++++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 63 insertions(+), 30 deletions(-)

diff --git contrib/stumpish~ contrib/stumpish
index 1d48bb4..2b0fca1 100755
--- contrib/stumpish~
+++ contrib/stumpish
@@ -21,19 +21,25 @@
 
 ### STUMPwm Interactive SHell.
 
-if sleep --version 2>/dev/null | grep -q GNU
+DELAY=0.01
+
+if ! sleep $DELAY 2>/dev/null >&2
 then
-    DELAY=0.1
-else
     DELAY=1
 fi
 
+# parse C-style backslash sequences by default
+if [ "$(echo -e foo)" = foo ]; then
+    echo() { builtin echo -e "$@"; }
+fi
+
 wait_result ()
 {
     while true
     do
-	RESULT=`xprop -root -f STUMPWM_COMMAND_RESULT 8s STUMPWM_COMMAND_RESULT 2>/dev/null`
-
+	RESULT=$(xprop -root -f STUMPWM_COMMAND_RESULT 8s \
+	    STUMPWM_COMMAND_RESULT 2>/dev/null |
+	    sed -E 's/\\([[:digit:]]+)/\\0\1/g')
 	if echo "$RESULT" | grep -v -q 'not found.$'
 	then
 	    break
@@ -49,8 +55,14 @@ wait_result ()
 	return 1
     fi
 
-    echo $RESULT | sed 's/[^"]*"//;s/"$//;s/\\n/\n/g;s/\\"/"/g;s/\n\+$//;
-			s/\^[*[:digit:]]\{2\}//g;s/\^[Bbn]//g;'
+    echo "$RESULT" |
+    sed -E 's/[^"\\n]+"//
+            s/"[[:space:]]*$//
+            s/([^\\])\\n/\1\
+/g
+            s/\\(["\\n])/\1/g
+            s/\^([*[:digit:]]+|[Bbn])//g' |
+    sed '/^[[:space:]]*$/d'
 }
 
 send_cmd ()
@@ -73,7 +85,7 @@ send_cmd ()
 usage ()
 {
     cat <<EOF
-Usage: "$0" [[-e] command [args...]]
+Usage: ${0##*/} [[-e|-r] command [args...]]
 
 StumpIsh is the StumpWM shell. Use it to interact a running StumpWM
 instance.  When run from a terminal with no arguments, stumpish
@@ -87,11 +99,31 @@ the first is considered the name of the command to execute and the
 remainder is concatenated to form the argument.
 
 Example:
-	echo '(group-windows (current-group))' | "$0" eval
+	echo '(group-windows (current-group))' | ${0##*/} -e eval
 EOF
     exit 0;
 }
 
+warn ()
+{
+  {
+    tput md bold
+    tput AF setaf 1
+    echo 'WARN:\c'
+    tput me sgr0
+    echo " $*"
+  } >&2
+}
+
+tput ()
+{
+    local cap1=$1 cap2=$2
+    shift 2
+
+    command tput $cap1 $@ ||
+    command tput $cap2 $@
+}
+
 READLINE=yes
 
 if [ "x$1" = "x-r" ]
@@ -112,7 +144,7 @@ then
 	fi
 	shift 1
 	IFS=''
-	ARGS=`cat /dev/stdin`
+	ARGS=$(cat /dev/stdin)
 	send_cmd "$1 $ARGS"
     else
 	IFS=' '
@@ -121,37 +153,38 @@ then
 else
     if [ -t 0 ]
     then
-	if [ $READLINE = yes ] && type rlwrap >/dev/null 2>&1
+	if ! type rlwrap 2>/dev/null >&2
+	then
+	    warn rlwrap not found, command completion won\'t work
+	elif [ $READLINE = yes ]
 	then
 	    # Note: $TEMP is not conventional; it is left here purely
 	    # for backwards compatibility.
-	    COMMANDS="${TEMP:-${TEMPDIR:-/var/tmp}}/stumpish.commands.$$"
-	    echo `send_cmd "commands"` | sed 's/[[:space:]]\+/\n/g' | sort > "$COMMANDS"
-	    rlwrap -f "$COMMANDS" "$0" -r
-	    rm -f "$COMMANDS"
+	    COMMANDS="${TMPDIR:-/tmp}/stumpish.commands.$$"
+	    echo $(send_cmd "commands") |
+	    sed -E 's/[[:space:]]+/\
+/g' |
+	    sort > "$COMMANDS"
+	    trap 'rm -f "$COMMANDS"' exit int term
+	    rlwrap -b '' -f "$COMMANDS" "$0" -r
 	    exit
 	fi
 
-	tput setaf 5
+	tput AF setaf 5
         echo Welcome to the STUMPwm Interactive SHell.
-        tput sgr0
-        echo -n 'Type '
-        tput setaf 2
-        echo -n commands
-        tput sgr0
+        tput me sgr0
+        echo 'Type \c'
+        tput AF setaf 2
+        echo 'commands\c'
+        tput me sgr0
         echo \ for a list of commands.
 
-        IFS='
-'
-	echo -n "> "
-	while read REPLY
+	while read -p '> ' REPLY
 	do
-	    tput bold
-	    tput setaf 2
+	    tput md bold
+	    tput AF setaf 2
 	    send_cmd "$REPLY"
-	    tput sgr0
-
-	    echo -n "> "
+	    tput me sgr0
 	done
     else
 	while read REPLY
-- 
1.7.1.1

_______________________________________________
Stumpwm-devel mailing list
Stumpwm-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/stumpwm-devel

Reply via email to