-
Notifications
You must be signed in to change notification settings - Fork 3
/
openwrt_make
183 lines (160 loc) · 5.63 KB
/
openwrt_make
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#
# Bash completion script for OpenWrt make targets
# https://github.com/sairon/openwrt-bash-completion
#
# Copyright (C) 2015 Jan Cermak <[email protected]>
# Released under the MIT license.
#
# source standard make completion as a fallback for non-openwrt targets
[ -f /usr/share/bash-completion/completions/make ] && . /usr/share/bash-completion/completions/make
[[ -n $OPENWRT_COMPL_USE_PRINTDB ]] || OPENWRT_COMPL_USE_PRINTDB=0
[[ -n $OPENWRT_COMPL_CACHE_PRINTDB ]] || OPENWRT_COMPL_CACHE_PRINTDB=1
OPENWRT_COMPL_CACHE=
# remove slashes from COMPREPLY items for replies that are valid directory path
# this is a workaround for unwanted behaviour of completion with option -o filenames
_deslash_compreply_dirs()
{
local i
for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
[[ -d ${COMPREPLY[$i]} ]] && COMPREPLY[$i]=${COMPREPLY[$i]::(-1)}
done
}
_rebuild_tokens()
{
local IFS="/"
echo "$*"
}
# completion based on simple search for Makefiles in the relevant parts of the buildroot
_complete_noprintdb()
{
local cur=${2}
# split to tokens by '/' delimiter
local tokens=(${cur//// })
# we want to complete next token if the last character is slash
if [[ ${cur:(-1)} = "/" ]]; then
tokens+=('')
fi
compopt -o filenames
# query is equivalent of "$cur" in context of slash-separated path
local query="${tokens[@]:(-1)}"
local main_target="${tokens[0]}"
local completions=""
case ${#tokens[@]} in
2)
completions=$(_discover_subtargets "${main_target}")
COMPREPLY=( $(compgen -P "${main_target}/" -S / -W "$completions" -- "$query") )
completions=$(_discover_subtargets "actions")
COMPREPLY+=( $(compgen -P "${main_target}/" -W "$completions" -- "$query") )
_deslash_compreply_dirs
return 0;
;;
3)
local subtarget=${tokens[${#tokens[@]}-2])}
# add space after this completion
compopt +o nospace
completions=$(_discover_subtargets "actions")
COMPREPLY=( $(compgen -P "${main_target}/${subtarget}/" -W "$completions" -- "$query") )
_deslash_compreply_dirs
return 0;
;;
esac
}
_discover_subtargets()
{
local actions="clean compile configure dist distcheck download install prepare prereq refresh update"
case "$1" in
package)
find -L package/ -name Makefile | grep -v src/Makefile | rev | cut -d/ -f2 | rev
;;
tools)
find tools/ -name Makefile | grep -v src/Makefile | rev | cut -d/ -f2 | rev
;;
target)
find target/ -name Makefile | cut -d/ -f2 | grep -v ^Makefile | sort | uniq
;;
toolchain)
# uClibc and gcc have more levels - this is not reflected here
find toolchain/ -name Makefile | grep -v src/Makefile | cut -d/ -f2 | grep -v ^Makefile
;;
actions)
echo "$actions"
;;
*)
echo ""
;;
esac
}
# completion based on 'make printdb' output - slower but more accurate
# if OPENWRT_COMPL_CACHE_PRINTDB is set to 1, output of printdb is cached
# in a global OPENWRT_COMPL_CACHE - this variable must be cleared if the
# package definitions were changed, but completion is then way faster
_complete_printdb()
{
compopt -o filenames
local cur=${2}
# split to tokens by '/' delimiter
local tokens=(${cur//// })
# we want to complete next token if the last character is slash
if [[ ${cur:(-1)} = "/" ]]; then
tokens+=('')
fi
local main_target="${tokens[0]}"
local query="${tokens[@]:(-1)}"
local prefix="$(_rebuild_tokens ${tokens[@]::${#tokens[@]}-1})/"
local db=""
if [[ $OPENWRT_COMPL_CACHE_PRINTDB = 0 || $OPENWRT_COMPL_CACHE_PRINTDB = 1 && -z $OPENWRT_COMPL_CACHE ]]; then
db=$(make printdb | sed "/# Not a target:/,+1 d" | grep '^\(package\|target\|toolchain\|tools\).*:\([^=].*\|$\)' | sed 's/:.*$//')
fi
# populate/fetch from cache
if [[ $OPENWRT_COMPL_CACHE_PRINTDB = 1 ]]; then
if [[ -z $OPENWRT_COMPL_CACHE ]]; then
OPENWRT_COMPL_CACHE="$db"
else
db="$OPENWRT_COMPL_CACHE"
fi
fi
# sed for normalization of package paths
local packages_sed="/.*host\/[^\/]*/ s~package/.*/([^/]*/host/.*)$~package/\1~;
/.*host\/[^\/]*/b; s~package/.*/([^/]*)/([^/]*)$~package/\1/\2~"
local filtered_db=$(echo "$db" \
| grep "^${main_target}.*${query}.*$" \
| sed -r "$packages_sed" \
| grep "$prefix" \
| sed -r "s~^${prefix}([^/]*/?).*~\1~" \
| sort | uniq \
)
COMPREPLY=( $(compgen -P "${prefix}" -W "$filtered_db" -- "$query") )
# add space if we have nothing to complete (= last chart is not slash)
[[ ${#COMPREPLY[@]} = 1 && ${COMPREPLY:(-1)} != "/" ]] && compopt +o nospace
_deslash_compreply_dirs
return 0;
}
_is_openwrt_buildroot()
{
# heuristics based on head of Makefile
[[ -f Makefile ]] && return $( head Makefile -n5 | grep -q OpenWrt )
return 1
}
_openwrt_make()
{
if ( ! _is_openwrt_buildroot ); then
_make
return 0;
fi
local cur=$2
COMPREPLY=()
compopt -o nospace
if [[ $cur =~ (package|target|toolchain|tools)/.* ]]; then
if [[ $OPENWRT_COMPL_USE_PRINTDB -eq 1 ]]; then
_complete_printdb "$@"
else
_complete_noprintdb "$@"
fi
return 0;
fi
# add default make targets if make completion exists
declare -f _make > /dev/null && _make
COMPREPLY+=( $(compgen -S / -W "package target tools toolchain" -- "$cur") )
return 0;
}
complete -F _openwrt_make make