From: Andre Noll Date: Thu, 29 Sep 2011 13:12:33 +0000 (+0200) Subject: gsu: Overhaul of the rexexp matching for help commands. X-Git-Url: http://git.tuebingen.mpg.de/?p=gsu.git;a=commitdiff_plain;h=45ca1b29b59a43524fb3ad6a013c5705ad3bdbde gsu: Overhaul of the rexexp matching for help commands. The old sed scripts were unreadable and broken on non-gnu systems since they made use of some gnuisms of grep and sed like \+ in regular expressions to match at least one character or sed's T command which jumps to a label if no substitution has been made since the most recent reading of an input line. This patch switches to extended regular expressions and replaces all broken sed scripts by portable ones, which are known to work at least on FreeBSD and MacOS. The new scripts are commented verbosely so that any subsequent changes do not require a full rewrite, hopefully. --- diff --git a/misc/gsu/subcommand b/misc/gsu/subcommand index f5f4745..a688ed5 100644 --- a/misc/gsu/subcommand +++ b/misc/gsu/subcommand @@ -11,16 +11,33 @@ _gsu_usage() gsu_short_msg "# Usage: $_gsu_self command [options]" } -# Each line matching this is recognized as a subcommand. The name -# of the subcommand is the first subexpression. -export gsu_command_regex='^com_\([-a-zA-Z_0-9]\+\)()' +# Each line matching this is recognized as a subcommand. The name of the may be +# given as $1. In any case the subcommand is the first subexpression. +_gsu_get_command_regex() +{ + local cmd="${1:-[-a-zA-Z_0-9]+}" + result="^com_($cmd)\(\)" +} _gsu_available_commands() { + local ere + + _gsu_get_command_regex + ere="$result" result="$({ printf "help\nman\nprefs\ncomplete\n" - sed -ne "s/$gsu_command_regex/\1/g;T;p" $0 - } | sort | tr '\n' ' ')" + sed -Ee ' + # if line matches, isolate command name + s/'"$ere"'/\1/g + + # if there is a match, (print it and) start next cycle + t + + # otherwise delete it + d + ' $0 + } | sort | tr '\n' ' ')" } _gsu_print_available_commands() @@ -194,7 +211,11 @@ was given. _com_help() { - local a b + local a b ere tab=' ' + + _gsu_get_command_regex + ere="$result" + if test -z "$1"; then _gsu_banner_msg 2>&1 _gsu_usage 2>&1 @@ -203,21 +224,28 @@ _com_help() printf "com_man()\n$gsu_man_txt" | head -n 4; echo "--" printf "com_prefs()\n$gsu_prefs_txt" | head -n 4; echo "--" printf "com_complete()\n$gsu_complete_txt" | head -n 4; echo "--" - grep -A 2 "$gsu_command_regex" $0 + grep -EA 2 "$ere" $0 } | grep -v -- '--' \ - | sed -e "/$gsu_command_regex/bs" \ - -e 'H;$!d;x;s/\n//g;b' \ - -e :s \ - -e 'x;s/\n//g;${p;x;}' \ - | sed -e "s/${gsu_command_regex}#*/\1\t/" \ - | sort \ - | while read a b; do - printf "$a\t" - if test ${#a} -lt 8; then - printf "\t" - fi - echo "$b" - done + | sed -En "/$ere/"'!d + # remove everything but the command name + s/^com_(.*)\(\).*/\1/ + + # append tab after short commands (less than 8 chars) + s/^(.{1,7})$/\1'"$tab"'/g + + # remove next line (should contain only ## anyway) + N + s/#.*// + + # append next line, removing leading ## + N + s/#+ *//g + + # replace newline by tab + y/\n/'"$tab"'/ + + # and print the sucker + p' echo echo "# Try $_gsu_self help for info on ." ret=$GSU_SUCCESS @@ -244,13 +272,32 @@ _com_help() return fi ret=$GSU_SUCCESS - if grep -q "^com_$1()" $0; then - sed -e "1,/^com_$1()$/d" -e '/^{/,$d' -e 's/^## *//' $0 + _gsu_get_command_regex "$1" + ere="$result" + if ! grep -Eq "$ere" $0; then + _gsu_print_available_commands + result="$1" + ret=-$E_GSU_BAD_COMMAND return fi - _gsu_print_available_commands - result="$1" - ret=-$E_GSU_BAD_COMMAND + sed -nEe ' + # only consider lines in the comment of the function + /'"$ere"'/,/^[^#]/ { + + # remove leading ## + s/^## *// + + # if it did start with ##, jump to label p and print it + tp + + # otherwise, move on to next line + d + + # print it + :p + p + } + ' $0 } complete_help()