blob: 2ec5d91a7721b5106ee76387f0d8a3f95fd5cbae [file] [edit]
make_small() {
local w=$1
echo $w | tr A-Z a-z
}
prev_keyword() {
local i=$1
shift
local words=("$@")
while [ $i -gt 0 ]; do
let i=$i-1
local w=$(make_small ${words[$i]})
case $w in
select)
echo "select"
return
;;
from)
echo "from"
return
;;
as)
echo "as"
return
;;
on)
echo "on"
return
;;
join)
echo "join"
return
;;
where)
echo "where"
return
;;
cast)
echo "cast"
return
;;
*)
if [ "$w" != "${w%%,}" ]; then
echo ","
return
fi
if [ "$w" != "${w%%=}" ]; then
echo "="
return
fi
if [ "$w" != "${w%%&}" ]; then
echo "&"
return
fi
;;
esac
done
echo ""
}
prev_command() {
local i=$1
shift
local words=("$@")
while [ $i -gt 0 ]; do
let i=$i-1
local w=$(make_small ${words[$i]})
case $w in
select)
echo "select"
return
;;
from)
echo "from"
return
;;
on)
echo "on"
return
;;
join)
echo "join"
return
;;
where)
echo "where"
return
;;
cast)
echo "cast"
return
;;
*)
# treat commas as a "select"
if [ "$w" != "${w%%,}" ]; then
echo "select"
return
fi
;;
esac
done
echo ""
}
add_vars() {
local words=("$@")
local i=$COMP_CWORD
local event=""
let found_from=0
let found_as=0
while [ $i -gt 0 ]; do
let i=$i-1
local w=$(make_small ${words[$i]})
case $w in
"from")
let found_from=1
;;
"as")
# Do not add the event itself if it was used by name
if [ $found_as -eq 0 ]; then
event=${words[$i-1]};
fi
let found_as=1
;;
*)
if [ $found_from -eq 1 ]; then
start=$(echo $w | sed -e 's/\.[^\.]*$//')
if [ "$start" != "$w" -a "$start" == "${start%%\.*}" -a \
"$start" != "$event" ]; then
echo -n "$start "
fi
fi
;;
esac
done
}
add_options() {
local cur="$1"
local list="$2"
COMPREPLY=( $(compgen -W "${list}" -- "${cur}") )
}
print_fields() {
local event=$1
local var=$2
local extra=$3
local list=$(trace-cmd list -e "^${event/\./:}\$" -F | cut -d';' -f1 | sed -ne 's/\t.*:.* \(.*\)/\1/p' |sed -e 's/\[.*\]//')
for field in $list $extra; do
if [ -z "$var" ]; then
echo "$event.$field"
else
echo "$var.$field"
fi
done
}
__list_events() {
local cur=$1
local list=$(trace-cmd list -e "$cur")
local prefix=${cur%%:*}
if [ -z "$cur" -o "$cur" != "$prefix" ]; then
echo "${list}"
else
local events=$(for e in $list; do echo ${e/*:/}; done | sort -u)
local systems=$(for s in $list; do echo ${s/:*/:}; done | sort -u)
echo "${events} ${systems}"
fi
}
select_options() {
local cur=$1
local extra=$2
local select_list="$extra"
local select_fields=" TIMESTAMP TIMESTAMP_USECS STACKTRACE COMM"
local list;
# Do not show events if nothing was typed yet
if [ ! -z "$cur" ]; then
list=$(__list_events "${cur/\./:}" | sed -e 's/:/./g')
if [ "cast" != "${cast%%$cur}" ]; then
list+=" cast"
fi
fi
add_options "$cur" "$list $select_list"
local cnt=${#COMPREPLY[@]}
if [ $cnt -eq 1 ]; then
local comp=${COMPREPLY[0]}
local w=$(compgen -W "$select_list" -- "$comp" )
if [ -z "$w" -a $(make_small "$comp") != "cast" ]; then
COMPREPLY=("$comp.")
compopt -o nospace
fi
elif [ $cnt -eq 0 ]; then
local w=$(echo $cur | sed -e 's/\.[^\.]*$//')
list=$(print_fields $w "" "$select_fields")
COMPREPLY=( $(compgen -W "${list}" -- "${cur}") )
fi
}
check_as() {
local words=("$@")
last_key=$(prev_keyword $COMP_CWORD ${words[@]})
if [ "$last_key" != "as" ]; then
echo -n "AS"
fi
}
on_list() {
local type=$1
shift
local words=("$@")
local i=$COMP_CWORD
local var=""
while [ $i -gt 0 ]; do
let i=$i-1
local w=$(make_small ${words[$i]})
case $w in
"from"|"join")
if [ $w == $type ]; then
print_fields ${words[$i+1]} "$var"
return
fi
var=""
;;
as)
var=${words[$i+1]}
;;
esac
done
}
update_completion() {
local cur=$1
shift
local words=("$@")
if [ ${#COMPREPLY[@]} -gt 0 ]; then
return
fi
for w in ${words[@]}; do
if [ "$w" != "${w##$cur}" ]; then
COMPREPLY=("$w")
return
fi
done
}
# return 0 if it was handled, otherwise return 1
tracefs_sql_completion()
{
local prev=$1
local cur=$2
shift 2
local words=("$@")
if [ "$cur" != "${cur%%,}" ]; then
COMPREPLY=("$cur")
return 0
fi
local p=$(make_small $prev)
if [ "$p" != "${p%%,}" ]; then
p=$(prev_command $COMP_CWORD ${words[@]})
fi
case "$p" in
"select")
select_options "$cur" "CAST TIMESTAMP_DELTA TIMESTAMP_DELTA_USECS"
;;
"on")
list=$(on_list "from" ${words[@]})
add_options "$cur" "$list"
;;
"where")
flist=$(on_list "from" ${words[@]})
jlist=$(on_list "join" ${words[@]})
add_options "$cur" "$flist $jlist"
;;
"cast")
COMPREPLY=("'('")
;;
"as")
local last_cmd=$(prev_command $COMP_CWORD ${words[@]})
case $last_cmd in
"select")
if [ ! -z "$cur" ]; then
COMPREPLY=("$cur" "$cur,")
fi
;;
"from"|"join")
list=$(add_vars ${words[@]})
if [ ! -z "$list" ]; then
add_options "$cur" "$list"
fi
;;
"cast")
local list="hex sym sym-offset log log2 buckets stacktrace"
local w;
if [ -z "$cur" ]; then
w=${words[$COMP_CWORD-1]}
else
w=${words[$COMP_CWORD-2]}
fi
if [ "$w" != "${w%%.common_pid}" ]; then
list+=" execname"
fi
add_options "$cur" "$list"
;;
esac
;;
"from"|"join")
local list=$(trace-cmd list -e "${cur/\./:}" | tr : .)
local prefix=${cur/\./}
if [ -z "$cur" -o "$cur" != "$prefix" ]; then
COMPREPLY=( $(compgen -W "${list}" -- "${cur}") )
else
local events=$(for e in $list; do echo ${e/*\./}; done | sort -u)
local systems=$(for s in $list; do echo ${s/\.*/.}; done | sort -u)
COMPREPLY=( $(compgen -W "all ${events} ${systems}" -- "${cur}") )
fi
;;
# TIMESTAMP_DELTA must be labeled
"timestamp_delta"|"timestamp_delta_usecs")
COMPREPLY=( $(compgen -W "AS" -- "${cur}") )
update_completion "$cur" "as"
;;
"'('")
if [ ! -z "$cur" ]; then
select_options "$cur"
fi
;;
"')'")
add_options "$cur" "FROM , $list"
update_completion "$cur" from $alist
;;
*)
local last_cmd=$(prev_command $COMP_CWORD ${words[@]})
local list=$(check_as ${words[@]})
local alist=""
if [ ! -z "$list" ]; then
alist="as"
fi
case $last_cmd in
"select")
if [ "$cur" != "${cur%%,}" ]; then
select_options "$cur" "CAST TIMESTAMP_DELTA TIMESTAMP_DELTA_USECS $list"
else
add_options "$cur" "FROM , $list"
update_completion "$cur" from $alist
fi
;;
"from")
add_options "$cur" "JOIN $list"
update_completion "$cur" join $alist
;;
"join")
add_options "$cur" "ON $list"
update_completion "$cur" on $alist
;;
"on")
if [ "$cur" != "${cur%%=}" ]; then
COMPREPLY=("")
else
last_key=$(prev_keyword $COMP_CWORD ${words[@]})
if [ "$last_key" == "=" ]; then
if [ $prev == "=" ]; then
list=$(on_list "join" ${words[@]})
add_options "$cur" "$list"
else
add_options "$cur" "WHERE"
update_completion "$cur" where
fi
else
add_options "$cur" "="
fi
fi
;;
"where")
if [ "$cur" != "${cur%%[=&]}" ]; then
COMPREPLY=("")
else
add_options "$cur" "== != &"
fi
;;
"cast")
local last_key=$(prev_keyword $COMP_CWORD ${words[@]})
if [ "$prev" == "\"(\"" -a ! -z "$cur" ]; then
select_options "$cur"
elif [ "$prev" == "buckets" ]; then
COMPREPLY=("=")
elif [ "$last_key" == "=" ]; then
if [ "$prev" != "=" ]; then
COMPREPLY=("')'")
fi
elif [ "$last_key" != "as" ]; then
COMPREPLY=("AS")
update_completion "$cur" as
else
COMPREPLY=("')'")
fi
;;
*)
return 1
esac
;;
esac
return 0
}