Merge branch 'master' of git+ssh://git.debian.org/git/bash-completion/bash-completion

This commit is contained in:
David Paleino 2010-03-08 12:38:33 +01:00
commit 8755f716fc
23 changed files with 375 additions and 127 deletions

21
CHANGES
View File

@ -25,9 +25,10 @@ bash-completion (2.x)
* Apply cardctl completion to pccardctl too.
* Apply pine completion to alpine too.
* Remove many unnecessary short option completions where long ones exist.
* Improve chsh, configure, cvs, gkrellm, gzip, lftp, look, make, mdadm,
modprobe, mplayer, mysqladmin, rsync, screen, service, scp, ssh, sshfs,
update-alternatives, vncviewer, yp-tools, and general hostname completions.
* Improve chsh, chgrp, chown, configure, cvs, gkrellm, gzip, lftp, look,
make, mdadm, modprobe, mplayer, mysqladmin, perldoc, rsync, screen,
service, scp, ssh, sshfs, update-alternatives, vncviewer, yp-tools, and
general hostname completions.
* Add abook and wtf completion, based on work by Raphaël Droz.
* Add cvsps, dragon, fusermount, jarsigner, k3b, lftpget, pm-utils, rtcwake,
pack200, unpack200, pbzip2, pbunzip2, pbzcat, pigz and unpigz completions.
@ -54,6 +55,7 @@ bash-completion (2.x)
* Split mount and umount completion into contrib/mount.
* Do basic HTML file completion with Firefox and Chrome and friends,
and Epiphany.
* Do basic diff/patch completion with cdiff and kompare.
[ Freddy Vulto ]
* Added _get_pword() helper function, thanks to Sung Pae (Alioth: #312030)
@ -69,6 +71,12 @@ bash-completion (2.x)
* Fix NFS mounts completion (Alioth: #312285).
* Fix completion of usernames (Alioth: #311396, Debian: #511788).
* Fix chown test crashing on systems with no root group (Alioth: #312306).
* Fixed tests when BASH_COMPLETION or TESTDIR contain spaces.
* Fix mount handling of escapes (Alioth: #311410, Launchpad: #219971).
* Cleanup scripts to run tests. Make runUnit and runCompletion use test/run.
Make it possible to run tests from any directory.
* Add a --debug-xtrace option to test/run using BASH_XTRACEFD from bash-4.1.
* Add a --timeout option to test/run to override the default expect timeout.
[ Raphaël Droz ]
* Add xsltproc completion (Alioth: #311843).
@ -79,6 +87,9 @@ bash-completion (2.x)
[ Ildar Mulyukov ]
* Add showmount completion (Alioth: #312285).
[ Neville Gao ]
* Fix mount completion error "bash: [: too many arguments" (Alioth #312381).
-- David Paleino <d.paleino@gmail.com> Sun, 11 Oct 2009 11:11:57 +0200
bash-completion (1.1)
@ -265,6 +276,10 @@ bash-completion (1.1)
* Fix leaking $muttcmd from mutt completion
* Fix completing multiple hosts (Debian: #535585)
[ Michele Ballabio ]
* Add more extensions to pkgtools completion.
-- David Paleino <d.paleino@gmail.com> Sat, 03 Oct 2009 15:41:49 +0200
bash-completion (1.0)

36
README
View File

@ -12,7 +12,7 @@ if [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
(if you happen to have *only* bash >= 3, see further if not)
(if you happen to have *only* bash >= 3.2 installed, see further if not)
If you don't have the package readily available for your distribution, or
you simply don't want to do this, put the bash_completion file somewhere
@ -98,36 +98,6 @@ function used by mutt completion, where the function calls itself
recursively. This seems to confuse bash and it issues spurious
warnings if 'nounset' is set.
V.
After upgrading to bash 3.1, you may notice that completing on certain
commands now fails with a message something like this:
sed: -e expression #1, char 20: unterminated `s' command
The reason for this is that bash 3.1 contains the following,
innocent-looking bug fix (from bash's CHANGES file):
t. Fixed a bug that caused the expanded value of a $'...' string
to be incorrectly re-quoted if it occurred within a
double-quoted ${...} parameter expansion.
Unfortunately, this also had the side effect of causing single quotes
to be stripped from $'...' strings inside double-quoted command
substitutions. Confused?
Efforts have been made to work around this issue in the bash
completion code as of the 20060301 release. All previous versions are
vulnerable to the problem. However, it's possible that, even in the
20060301 release and later, affected code remains.
The issue has now been officially recognised as a regression in the
bash 3.1 release and is fixed by official patch 11. If you encounter
problems of this nature, please apply the patch below to your copy of
bash:
ftp://ftp.gnu.org/gnu/bash/bash-3.1-patches/bash31-011
FAQ
---
@ -318,10 +288,10 @@ guidelines in mind:
start interpreters. Use lightweight programs such as grep(1), awk(1)
and sed(1).
- Use the full power of bash >= 3. We no longer support earlier bash
- Use the full power of bash >= 3.2. We no longer support earlier bash
versions, so you may as well use all the features of that version of
bash to optimise your code. However, be careful when using features
added since bash 3.0, since not everyone will be able to use them. Be
added since bash 3.2, since not everyone will be able to use them. Be
ESPECIALLY careful of using features exclusive to 4.x, as many people
are still using 3.x.

4
TODO
View File

@ -2,8 +2,8 @@ bash completion needs to be rewritten from the ground up.
---------------------------------------------------------
bash completion really needs to be rewritten from the ground up, using all of
the features available in bash 3.1 and without regard for compatibility with
the 2.x line.
the features available in bash 3.2+ and without regard for compatibility with
earlier versions.
At that time, it should be split into multiple files for easier source
management. Whether or not it is actually installed on the destination

View File

@ -1,5 +1,5 @@
#
# bash_completion - programmable completion functions for bash 3.x
# bash_completion - programmable completion functions for bash 3.2+
#
# Copyright © 2006-2008, Ian Macdonald <ian@caliban.org>
# © 2009-2010, Bash Completion Maintainers
@ -121,6 +121,7 @@ complete -f -X '!*.po' poedit gtranslator kbabel lokalize
complete -f -X '!*.@([Pp][Rr][Gg]|[Cc][Ll][Pp])' harbour gharbour hbpp
complete -f -X '!*.[Hh][Rr][Bb]' hbrun
complete -f -X '!*.ly' lilypond ly2dvi
complete -f -X '!*.@(dif?(f)|?(d)patch)' cdiff kompare
# FINISH exclude -- do not remove this line
# start of section containing compspecs that can be handled within bash
@ -1084,9 +1085,13 @@ _chown()
if [[ "$cur" == -* ]]; then
# Complete -options
local w opts
for w in "${COMP_WORDS[@]}" ; do
[[ "$w" == -@(R|-recursive) ]] && opts="-H -L -P" && break
done
COMPREPLY=( $( compgen -W '-c -h -f -R -v --changes --dereference \
--no-dereference --from --silent --quiet --reference --recursive \
--verbose --help --version' -- "$cur" ) )
--verbose --help --version $opts' -- "$cur" ) )
else
local args
@ -1125,9 +1130,13 @@ _chgrp()
# options completion
if [[ "$cur" == -* ]]; then
local w opts
for w in "${COMP_WORDS[@]}" ; do
[[ "$w" == -@(R|-recursive) ]] && opts="-H -L -P" && break
done
COMPREPLY=( $( compgen -W '-c -h -f -R -v --changes --dereference \
--no-dereference --silent --quiet --reference --recursive \
--verbose --help --version' -- "$cur" ) )
--verbose --help --version $opts' -- "$cur" ) )
return 0
fi
@ -1810,7 +1819,7 @@ _filedir_xspec()
# get first exclusion compspec that matches this command
xspec=$( awk "/^complete[ \t]+.*[ \t]${1##*/}([ \t]|\$)/ { print \$0; exit }" \
$BASH_COMPLETION )
"$BASH_COMPLETION" )
# prune to leave nothing but the -X spec
xspec=${xspec#*-X }
xspec=${xspec%% *}
@ -1837,7 +1846,7 @@ _filedir_xspec()
COMPREPLY=( "${toks[@]}" )
}
list=( $( sed -ne '/^# START exclude/,/^# FINISH exclude/p' $BASH_COMPLETION | \
list=( $( sed -ne '/^# START exclude/,/^# FINISH exclude/p' "$BASH_COMPLETION" | \
# read exclusion compspecs
(
while read line
@ -1863,19 +1872,19 @@ unset list
# source completion directory definitions
if [[ -d $BASH_COMPLETION_COMPAT_DIR && -r $BASH_COMPLETION_COMPAT_DIR && \
-x $BASH_COMPLETION_COMPAT_DIR ]]; then
for i in $(LC_ALL=C command ls $BASH_COMPLETION_COMPAT_DIR); do
for i in $(LC_ALL=C command ls "$BASH_COMPLETION_COMPAT_DIR"); do
i=$BASH_COMPLETION_COMPAT_DIR/$i
[[ ${i##*/} != @(*~|*.bak|*.swp|\#*\#|*.dpkg*|*.rpm@(orig|new|save)) \
&& ( -f $i || -h $i ) && -r $i ]] && . $i
&& ( -f $i || -h $i ) && -r $i ]] && . "$i"
done
fi
if [[ $BASH_COMPLETION_DIR != $BASH_COMPLETION_COMPAT_DIR && \
-d $BASH_COMPLETION_DIR && -r $BASH_COMPLETION_DIR && \
-x $BASH_COMPLETION_DIR ]]; then
for i in $(LC_ALL=C command ls $BASH_COMPLETION_DIR); do
for i in $(LC_ALL=C command ls "$BASH_COMPLETION_DIR"); do
i=$BASH_COMPLETION_DIR/$i
[[ ${i##*/} != @(*~|*.bak|*.swp|\#*\#|*.dpkg*|*.rpm@(orig|new|save)) \
&& ( -f $i || -h $i ) && -r $i ]] && . $i
&& ( -f $i || -h $i ) && -r $i ]] && . "$i"
done
fi
unset i

View File

@ -2,9 +2,11 @@
[ -z "$BASH_VERSION" -o -z "$PS1" -o -n "$BASH_COMPLETION" ] && return
# Check for recent enough version of bash.
bash=${BASH_VERSION%.*}; bmajor=${bash%.*}
if [ $bmajor -ge 3 -a -r @sysconfdir@/bash_completion ]; then
bash=${BASH_VERSION%.*}; bmajor=${bash%.*}; bminor=${bash#*.}
if [ $bmajor -gt 3 ] || [ $bmajor -eq 3 -a $bminor -ge 2 ]; then
if [ -r @sysconfdir@/bash_completion ]; then
# Source completion code.
. @sysconfdir@/bash_completion
fi
fi
unset bash bmajor
unset bash bmajor bminor

View File

@ -7,6 +7,74 @@
have mount &&
{
# Just like COMPREPLY=(`compgen -W "${COMPREPLY[*]}" -- "$cur"`), only better!
#
# This will correctly escape special characters in COMPREPLY.
_reply_compgen_array()
{
# Create the argument for compgen -W by escaping twice.
#
# One round of escape is because we want to reply with escaped arguments. A
# second round is required because compgen -W will helpfully expand it's
# argument.
local i wlist
for i in ${!COMPREPLY[*]}; do
local q=$(quote "$(printf %q "${COMPREPLY[$i]}")")
wlist+=$q$'\n'
done
# We also have to add another round of escaping to $cur.
local ecur="$cur"
ecur="${ecur//\\/\\\\}"
ecur="${ecur//\'/\'}"
# Actually generate completions.
local oldifs=$IFS
IFS=$'\n' eval 'COMPREPLY=(`compgen -W "$wlist" -- "${ecur}"`)'
IFS=$oldifs
}
# Unescape strings in the linux fstab(5) format (with octal escapes).
__linux_fstab_unescape() {
eval $1="'${!1//\'/\047}'"
eval $1="'${!1/%\\/\\\\}'"
eval "$1=$'${!1}'"
}
# Complete linux fstab entries.
#
# Reads a file from stdin in the linux fstab(5) format; as used by /etc/fstab
# and /proc/mounts.
_linux_fstab()
{
COMPREPLY=()
# Read and unescape values into COMPREPLY
local fs_spec fs_file fs_other
local oldifs="$IFS"
while read -r fs_spec fs_file fs_other; do
if [[ $fs_spec = [#]* ]]; then continue; fi
if [[ $1 == -L ]]; then
local fs_label=${fs_spec/#LABEL=}
if [[ $fs_label != "$fs_spec" ]]; then
__linux_fstab_unescape fs_label
IFS=$'\0'
COMPREPLY+=("$fs_label")
IFS=$oldifs
fi
else
__linux_fstab_unescape fs_spec
__linux_fstab_unescape fs_file
IFS=$'\0'
[[ $fs_spec = */* ]] && COMPREPLY+=("$fs_spec")
[[ $fs_file = */* ]] && COMPREPLY+=("$fs_file")
IFS=$oldifs
fi
done
_reply_compgen_array
}
_mount()
{
local cur sm host prev
@ -17,7 +85,7 @@ _mount()
[[ "$cur" == \\ ]] && cur="/"
if [[ "$cur" == *:* ]]; then
for sm in $(type -P showmount) {,/usr}/{,s}bin/showmount; do
for sm in "$(type -P showmount)" {,/usr}/{,s}bin/showmount; do
[ -x "$sm" ] || continue
COMPREPLY=( $( compgen -W "$( "$sm" -e ${cur%%:*} | \
awk 'NR>1 {print $1}' )" -- "${cur#*:}" ) )
@ -43,12 +111,12 @@ _mount()
COMPREPLY=( $( compgen -W "$( mount | awk '! /^[ \t]*#/ {if ($3 ~ /\//) print $3}' )" -- "$cur" ) )
else
# probably Linux
if [ $prev = -L ]; then
COMPREPLY=( $( compgen -W '$(sed -ne "s/^[[:space:]]*LABEL=\([^[:space:]]*\).*/\1/p" /etc/fstab )' -- "$cur" ) )
elif [ $prev = -U ]; then
if [ "$prev" = -L ]; then
_linux_fstab -L < /etc/fstab
elif [ "$prev" = -U ]; then
COMPREPLY=( $( compgen -W '$(sed -ne "s/^[[:space:]]*UUID=\([^[:space:]]*\).*/\1/p" /etc/fstab )' -- "$cur" ) )
else
COMPREPLY=( $( compgen -W "$( awk '! /^[ \t]*#/ {if ($2 ~ /\//) print $2}' /etc/fstab )" -- "$cur" ) )
_linux_fstab < /etc/fstab
fi
fi
@ -62,12 +130,18 @@ complete -F _mount -o default -o dirnames mount
have umount &&
_umount()
{
local cur IFS=$'\n'
COMPREPLY=()
cur=`_get_cword`
local cur=`_get_cword`
if [[ $(uname -s) = Linux && -r /proc/mounts ]]; then
# Linux /proc/mounts is properly quoted. This is important when
# unmounting usb devices with pretty names.
_linux_fstab < /proc/mounts
else
local IFS=$'\n'
COMPREPLY=( $( compgen -W '$( mount | cut -d" " -f 3 )' -- "$cur" ) )
fi
return 0
} &&

View File

@ -77,14 +77,14 @@ _perldoc()
shift splice unshift grep join map qw reverse sort unpack \
delete each exists keys values binmode close closedir \
dbmclose dbmopen die eof fileno flock format getc print \
printf read readdir rewinddir seek seekdir select syscall \
printf read readdir rewinddir say seek seekdir select syscall \
sysread sysseek syswrite tell telldir truncate warn write \
pack read syscall sysread syswrite unpack vec -X chdir chmod \
chown chroot fcntl glob ioctl link lstat mkdir open opendir \
readlink rename rmdir stat symlink umask unlink utime caller \
continue do dump eval exit goto last next redo return \
sub wantarray caller import local my our package use defined \
formline reset scalar undef \
sub wantarray break caller import local my our state package \
use defined formline reset scalar undef \
alarm exec fork getpgrp getppid getpriority kill pipe qx \
setpgrp setpriority sleep system times wait waitpid \
import no package require use bless dbmclose dbmopen package \
@ -98,7 +98,7 @@ _perldoc()
getnetbyaddr getnetbyname getnetent getprotobyname \
getprotobynumber getprotoent getservbyname getservbyport \
getservent sethostent setnetent setprotoent setservent \
gmtime localtime time times' -- "$cur" ) )
gmtime localtime time times lock' -- "$cur" ) )
return 0
;;
esac
@ -114,9 +114,10 @@ _perldoc()
sed -ne "/perl.*Perl overview/,/perlwin32/p" | \
awk "\$NF=2 { print \$1}" | command grep perl )' -- "$cur" ) )
fi
_filedir '@(pl|PL|pm|PM|pod|POD)'
fi
}
complete -F _perldoc -o default perldoc
complete -F _perldoc -o bashdefault perldoc
}
# Local variables:

View File

@ -11,7 +11,7 @@ _removepkg()
COMPREPLY=( $( (cd /var/log/packages; compgen -f -- "$cur") ) )
} &&
complete -F _removepkg -o filenames removepkg &&
complete -o dirnames -f -X '!*.tgz' installpkg upgradepkg explodepkg
complete -o dirnames -f -X '!*.t[bglx]z' installpkg upgradepkg explodepkg
# Local variables:
# mode: shell-script

View File

@ -19,7 +19,7 @@ _tar()
return 0
;;
+([^IZzJjy])f)
ext='t@(ar?(.@(Z|gz|bz?(2)|lz?(ma)))|gz|bz?(2)|lz?(ma))'
ext='t@(ar?(.@(Z|gz|bz?(2)|lz?(ma)|xz))|gz|bz?(2)|lz?(ma)|xz)'
regex='t\(ar\(\.\(Z\|gz\|bz2\?\|lzma\|xz\)\)\?\|gz\|bz2\?\|lzma\|xz\)'
;;
*[Zz]*f)

1
test/.gitignore vendored
View File

@ -1 +1,2 @@
dbg.log
xtrace.log

24
test/fixtures/mount/test-fstab vendored Normal file
View File

@ -0,0 +1,24 @@
proc /proc proc defaults 0 0
none /debug debugfs defaults,noauto 0 0
# Simple obvious test.
/mnt/nice-test-path /dev/null auto ro,noauto 0 0
# Test octal escapes
# Contains ' ' and '-'
/mnt/nice\040test\055path /dev/null auto ro,noauto 0 0
# Contains '$' and '-'
/mnt/nice\044test\055path /dev/null auto ro,noauto 0 0
# Contains ' ' and '\\'
/mnt/nice\040test\134path /dev/null auto ro,noauto 0 0
# Contains '\n' and '\ '
/mnt/nice\012test\040path /dev/null auto ro,noauto 0 0
# Test apostrophe
/mnt/nice'test-path /dev/null auto ro,noauto 0 0
/mnt/other'test\040path /dev/null auto ro,noauto 0 0
# Test some labels
LABEL=Ubuntu\040Karmic /mnt/ubuntu auto no,noauto 0 0
LABEL=Fedora /mnt/fedora auto ro,noauto 0 0
LABEL=Debian-it's\040awesome /mnt/debian auto ro,noauto 0 0

View File

@ -2,16 +2,13 @@ source ${srcdir}/lib/library.exp
proc completion_exit {} {
# Exit bash
send "\rexit\r"
}; # completion_exit()
}
proc completion_start {} {
start_bash
source_bash_completion
init_tcl_bash_globals
}; # completion_start()
start_interactive_test
}
proc completion_version {} {

View File

@ -1,11 +1,38 @@
# mount completion from fstab can't be tested directly because it
# (correctly) uses absolute paths. So we create a custom completion which
# reads from a file in our text fixture instead.
proc setup_dummy_mnt {} {
assert_bash_exec {unset COMPREPLY cur}
assert_bash_exec {unset -f _mnt}
global TESTDIR
assert_bash_exec { \
_mnt() { \
local cur=$(_get_cword); \
_linux_fstab $(_get_pword) < "$TESTDIR/fixtures/mount/test-fstab"; \
}; \
complete -F _mnt mnt \
}
}
proc teardown_dummy_mnt {} {
assert_bash_exec {unset COMPREPLY cur}
assert_bash_exec {unset -f _mnt}
assert_bash_exec {complete -r mnt}
}
proc setup {} {
save_env
};
setup_dummy_mnt
}
proc teardown {} {
teardown_dummy_mnt
assert_env_unmodified
};
}
setup
@ -30,4 +57,59 @@ assert_bash_exec {PATH="$OLDPATH"; unset -v OLDPATH}
sync_after_int
set test "Testing internal __linux_fstab_unescape function for mount"
# One round of slashes is for bash.
assert_bash_exec {var=one\'two\\040three\\}
assert_bash_exec {__linux_fstab_unescape var}
set cmd {echo $var}
send "$cmd\r"
expect {
-ex "$cmd\r\none'two three\\" { pass $test }
# default { fail $test }
}
sync_after_int
assert_bash_exec {unset var}
sync_after_int
# Begin testing through mnt (see setup_dummy_mnt).
assert_complete {/mnt/nice-test-path} {mnt /mnt/nice-test-p}
sync_after_int
assert_complete {/mnt/nice\ test-path} {mnt /mnt/nice\ test-p}
sync_after_int
assert_complete {/mnt/nice\$test-path} {mnt /mnt/nice\$test-p}
sync_after_int
assert_complete {/mnt/nice\ test\\path} {mnt /mnt/nice\ test\\p}
sync_after_int
assert_complete {{/mnt/nice\ test\\path} {/mnt/nice\ test-path}} \
{mnt /mnt/nice\ } "" /@ 20 {/mnt/nice\ }
sync_after_int
assert_complete {/mnt/nice\$test-path} {mnt /mnt/nice\$}
sync_after_int
assert_complete {/mnt/nice\'test-path} {mnt /mnt/nice\'}
sync_after_int
assert_complete {/mnt/other\'test\ path} {mnt /mnt/other}
sync_after_int
assert_complete {Ubuntu\ Karmic} {mnt -L Ubu}
sync_after_int
assert_complete {Debian-it\'s\ awesome} {mnt -L Deb}
sync_after_int
# This does not work. Proper support for this requires smarter parsing of
# $COMP_LINE and it's not worth doing just for mount.
#assert_complete {$'/mnt/nice\ntest-path'} {mnt $'/mnt/nice\n}
#sync_after_int
teardown

View File

@ -112,7 +112,7 @@ if {[match_items [lsort -unique $expected] $test]} {
if {[lindex $::BASH_VERSINFO 0] >= 4} {xfail "$test"} {fail "$test"}
}; # if
sync_after_int $prompt
assert_bash_exec "cd \$TESTDIR"
assert_bash_exec {cd "$TESTDIR"}
sync_after_int

View File

@ -42,7 +42,7 @@ expect {
default { unresolved "$test" }
}; # expect
sync_after_int $prompt
assert_bash_exec "cd \$TESTDIR"
assert_bash_exec {cd "$TESTDIR"}

View File

@ -71,7 +71,7 @@ expect {
default { unresolved "$test" }
}; # expect
sync_after_int $prompt
assert_bash_exec "cd \$TESTDIR"
assert_bash_exec {cd "$TESTDIR"}
teardown

View File

@ -29,7 +29,7 @@ expect {
default { unresolved "$test" }
}; # expect
sync_after_int $prompt
assert_bash_exec "cd \$TESTDIR"
assert_bash_exec {cd "$TESTDIR"}
sync_after_int
@ -84,7 +84,7 @@ expect {
default { unresolved "$test" }
}; # expect
sync_after_int $prompt
assert_bash_exec "cd \$TESTDIR"
assert_bash_exec {cd "$TESTDIR"}
sync_after_int

View File

@ -102,7 +102,7 @@ proc assert_bash_list_dir {expected cmd dir {test ""} {prompt /@} {size 20}} {
assert_bash_exec "cd $dir" "" $prompt
assert_bash_list $expected $cmd $test $prompt $size
sync_after_int $prompt
assert_bash_exec "cd \$TESTDIR"
assert_bash_exec {cd "$TESTDIR"}
}; # assert_bash_list_dir()
@ -272,7 +272,7 @@ proc assert_complete_dir {expected cmd dir {test ""} {size 20} {cword ""}} {
assert_bash_exec "cd $dir" "" $prompt
assert_complete $expected $cmd $test $prompt $size $cword
sync_after_int $prompt
assert_bash_exec "cd \$TESTDIR"
assert_bash_exec {cd "$TESTDIR"}
}; # assert_complete_dir
@ -692,16 +692,16 @@ proc save_env {{file ""}} {
# @param string File to save the environment to. Default is "$TESTDIR/tmp/env1~".
# @see assert_env_unmodified()
proc _save_env {{file ""}} {
assert_bash_exec "{ set; declare -F; shopt -p; } > $file"
assert_bash_exec "{ set; declare -F; shopt -p; } > \"$file\""
}; # _save_env()
# Source bash_completion package
proc source_bash_completion {} {
assert_bash_exec {BASH_COMPLETION_DIR=$(cd $TESTDIR/..; pwd)/contrib}
assert_bash_exec {BASH_COMPLETION_DIR=$(cd "$TESTDIR/.."; pwd)/contrib}
assert_bash_exec {BASH_COMPLETION_COMPAT_DIR=$BASH_COMPLETION_DIR}
assert_bash_exec {BASH_COMPLETION=$(cd $TESTDIR/..; pwd)/bash_completion}
assert_bash_exec {source $BASH_COMPLETION}
assert_bash_exec {BASH_COMPLETION=$(cd "$TESTDIR/.."; pwd)/bash_completion}
assert_bash_exec {source "$BASH_COMPLETION"}
}; # source_bash_completion()
@ -829,6 +829,48 @@ proc start_bash {} {
}; # start_bash()
# Redirect xtrace output to a file.
#
# 'set -x' can be very useful for debugging but by default it writes to
# stderr. Bash 4.1 has a feature to redirect this output to a random FD.
#
# This function uses file descriptor 6. This will break if any completion
# tries to use the same descriptor.
proc init_bash_xtrace {{fname xtrace.log}} {
global BASH_VERSINFO
if {([lindex $BASH_VERSINFO 0] == 4 && [lindex $BASH_VERSINFO 1] < 1) ||
[lindex $BASH_VERSINFO 0] < 4} {
note "BASH_XTRACEFD not available in this version; no xtrace.log"
return
}
verbose "Enabling bash xtrace output to '$fname'"
assert_bash_exec "exec 6>'$fname'"
assert_bash_exec "BASH_XTRACEFD=6"
assert_bash_exec "set -o xtrace"
}
# Setup test environment
#
# Common initialization for unit and completion tests.
proc start_interactive_test {} {
start_bash
source_bash_completion
init_tcl_bash_globals
global OPT_BASH_XTRACE
if {[info exists OPT_BASH_XTRACE]} {
init_bash_xtrace
}
global OPT_TIMEOUT
if {[info exists OPT_TIMEOUT]} {
global timeout
verbose "Changing default expect timeout from $timeout to $OPT_TIMEOUT"
set timeout $OPT_TIMEOUT
}
}
# Interrupt completion and sync with prompt.
# Send signals QUIT & INT.
# @param string $prompt (optional) Bash prompt. Default is "/@"
@ -836,13 +878,17 @@ proc sync_after_int {{prompt /@}} {
set test "Sync after INT"
sleep .1
send \031\003; # QUIT/INT
# Wait to allow bash to become ready
# See also: http://lists.alioth.debian.org/pipermail/bash-completion-devel/
# 2010-February/002566.html
sleep .1
# NOTE: Regexp `.*' causes `expect' to discard previous unknown output.
# This is necessary if a completion doesn't match expectations.
# For instance with `filetype_xspec' completion (e.g. `kdvi') if
# one expects `.txt' as a completion (wrong, because it isn't
# there), the unmatched completions need to be cleaned up.
expect -re ".*$prompt$"
}; # sync_after_int()
}
proc sync_after_tab {} {

View File

@ -4,14 +4,12 @@ source lib/library.exp
proc unit_exit {} {
# Exit bash
send "\rexit\r"
}; # unit_exit()
}
proc unit_start {} {
start_bash
source_bash_completion
init_tcl_bash_globals
}; # unit_start()
start_interactive_test
}
proc unit_version {} {

View File

@ -1,31 +1,60 @@
#!/bin/bash
# Run test of specified tool.
# The first directory of the first file (first argument ending with .exp) is
# used as the `tool' specification.
# Usage: ./run [FILE]...
# Example run: ./run unit/_get_cword.exp unit/compgen.exp
# Process arguments
# @param $1 Name of variable to return `tool' name
# @param $2 Name of variable to return processed arguments
# @param $@ Arguments to process
process_args() {
local arg
for arg in "${@:3}"; do
case "$arg" in
completion/*.exp|unit/*.exp)
[[ ${!1} ]] || printf -v $1 "${arg%%/*}"
eval $2[\${#$2[@]}]=\""${arg#*/}"\"
;;
*)
eval $2[\${#$2[@]}]=\""$arg"\"
esac
done
# Print some helpful messages.
usage() {
echo "Run bash-completion tests"
echo
echo "The 'tool' is determined automatically from filenames."
echo "Unrecognized options are passed through to dejagnu by default."
echo
echo "Interesting options:"
echo " --tool_exec= Test against a different bash executable."
echo " --debug Create a dbg.log in the test directory with detailed expect match information."
echo " --timeout Change expect timeout from the default of 10 seconds."
echo " --debug-xtrace Create an xtrace.log in the test directory with set -x output. Requires bash 4.1."
echo
echo "Example run: ./run unit/_get_cword.exp unit/compgen.exp"
}
args=()
process_args tool args "$@"
runtest --outdir log --tool $tool "${args[@]}"
unset -v args tool
# Try to set the tool variable; or fail if trying to set different values.
set_tool() {
if [[ $tool ]]; then
if [[ $tool != $1 ]]; then
echo "Tool spec mismatch ('$tool' and '$1'). See --usage."
exit 1
fi
else
tool=$1
fi
}
cd "${BASH_SOURCE[0]%/*}"
# Loop over the arguments.
args=()
while [[ $# > 0 ]]; do
case "$1" in
--help|--usage) usage; exit 1;;
--debug-xtrace) args+=(OPT_BASH_XTRACE=1);;
--timeout) shift; timeout=$1;;
--timeout=*) timeout=${1/--timeout=};;
--tool=*) set_tool "${1#/--tool=}";;
--tool) shift; set_tool "$1";;
*/completion/*.exp|*/unit/*.exp)
arg=${1%/*}
set_tool "${arg##*/}"
args+=("${1##*/}")
;;
*) args+=("$1")
esac
shift
done
[[ -n $timeout ]] && args+=("OPT_TIMEOUT=$timeout")
[[ -z $tool ]] && { echo "Must specify tool somehow"; exit 1; }
runtest --outdir log --tool $tool "${args[@]}"

View File

@ -4,4 +4,4 @@
# isn't initialized at that point (i.e. output of `expect' is shown on
# stdout - `open_logs' hasn't run yet?). And running code from a library
# file isn't probably a good idea either.
runtest --outdir log --tool completion $*
"${BASH_SOURCE[0]%/*}/run" --tool completion $*

View File

@ -4,4 +4,4 @@
# isn't initialized at that point (i.e. output of `expect' is shown on
# stdout - `open_logs' hasn't run yet?). And running code from a library
# file isn't probably a good idea either.
runtest --outdir log --tool unit $*
"${BASH_SOURCE[0]%/*}/run" --tool unit $*

View File

@ -41,7 +41,7 @@ expect {
-re eof { unresolved "eof" }
}; # expect
sync_after_int $prompt
assert_bash_exec "cd \$TESTDIR"
assert_bash_exec {cd "$TESTDIR"}
#assert_bash_list_dir {a\\\'b/c} $cmd fixtures/compgen