Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1#!/usr/bin/env bash
2# SPDX-License-Identifier: GPL-2.0
3# Manipulate options in a .config file from the command line
4
5myname=${0##*/}
6
7# If no prefix forced, use the default CONFIG_
8CONFIG_="${CONFIG_-CONFIG_}"
9
10# We use an uncommon delimiter for sed substitutions
11SED_DELIM=$(echo -en "\001")
12
13usage() {
14 cat >&2 <<EOL
15Manipulate options in a .config file from the command line.
16Usage:
17$myname options command ...
18commands:
19 --enable|-e option Enable option
20 --disable|-d option Disable option
21 --module|-m option Turn option into a module
22 --set-str option string
23 Set option to "string"
24 --set-val option value
25 Set option to value
26 --undefine|-u option Undefine option
27 --state|-s option Print state of option (n,y,m,undef)
28
29 --enable-after|-E beforeopt option
30 Enable option directly after other option
31 --disable-after|-D beforeopt option
32 Disable option directly after other option
33 --module-after|-M beforeopt option
34 Turn option into module directly after other option
35 --refresh Refresh the config using old settings
36
37 commands can be repeated multiple times
38
39options:
40 --file config-file .config file to change (default .config)
41 --keep-case|-k Keep next symbols' case (dont' upper-case it)
42
43$myname doesn't check the validity of the .config file. This is done at next
44make time.
45
46By default, $myname will upper-case the given symbol. Use --keep-case to keep
47the case of all following symbols unchanged.
48
49$myname uses 'CONFIG_' as the default symbol prefix. Set the environment
50variable CONFIG_ to the prefix to use. Eg.: CONFIG_="FOO_" $myname ...
51EOL
52 exit 1
53}
54
55checkarg() {
56 ARG="$1"
57 if [ "$ARG" = "" ] ; then
58 usage
59 fi
60 case "$ARG" in
61 ${CONFIG_}*)
62 ARG="${ARG/${CONFIG_}/}"
63 ;;
64 esac
65 if [ "$MUNGE_CASE" = "yes" ] ; then
66 ARG="`echo $ARG | tr a-z A-Z`"
67 fi
68}
69
70txt_append() {
71 local anchor="$1"
72 local insert="$2"
73 local infile="$3"
74 local tmpfile="$infile.swp"
75
76 # sed append cmd: 'a\' + newline + text + newline
77 cmd="$(printf "a\\%b$insert" "\n")"
78
79 sed -e "/$anchor/$cmd" "$infile" >"$tmpfile"
80 # replace original file with the edited one
81 mv "$tmpfile" "$infile"
82}
83
84txt_subst() {
85 local before="$1"
86 local after="$2"
87 local infile="$3"
88 local tmpfile="$infile.swp"
89
90 sed -e "s$SED_DELIM$before$SED_DELIM$after$SED_DELIM" "$infile" >"$tmpfile"
91 # replace original file with the edited one
92 mv "$tmpfile" "$infile"
93}
94
95txt_delete() {
96 local text="$1"
97 local infile="$2"
98 local tmpfile="$infile.swp"
99
100 sed -e "/$text/d" "$infile" >"$tmpfile"
101 # replace original file with the edited one
102 mv "$tmpfile" "$infile"
103}
104
105set_var() {
106 local name=$1 new=$2 before=$3
107
108 name_re="^($name=|# $name is not set)"
109 before_re="^($before=|# $before is not set)"
110 if test -n "$before" && grep -Eq "$before_re" "$FN"; then
111 txt_append "^$before=" "$new" "$FN"
112 txt_append "^# $before is not set" "$new" "$FN"
113 elif grep -Eq "$name_re" "$FN"; then
114 txt_subst "^$name=.*" "$new" "$FN"
115 txt_subst "^# $name is not set" "$new" "$FN"
116 else
117 echo "$new" >>"$FN"
118 fi
119}
120
121undef_var() {
122 local name=$1
123
124 txt_delete "^$name=" "$FN"
125 txt_delete "^# $name is not set" "$FN"
126}
127
128FN=.config
129CMDS=()
130while [[ $# -gt 0 ]]; do
131 if [ "$1" = "--file" ]; then
132 if [ "$2" = "" ]; then
133 usage
134 fi
135 FN="$2"
136 shift 2
137 else
138 CMDS+=("$1")
139 shift
140 fi
141done
142
143set -- "${CMDS[@]}"
144if [ "$1" = "" ] ; then
145 usage
146fi
147
148MUNGE_CASE=yes
149while [ "$1" != "" ] ; do
150 CMD="$1"
151 shift
152 case "$CMD" in
153 --keep-case|-k)
154 MUNGE_CASE=no
155 continue
156 ;;
157 --refresh)
158 ;;
159 --*-after|-E|-D|-M)
160 checkarg "$1"
161 A=$ARG
162 checkarg "$2"
163 B=$ARG
164 shift 2
165 ;;
166 -*)
167 checkarg "$1"
168 shift
169 ;;
170 esac
171 case "$CMD" in
172 --enable|-e)
173 set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=y"
174 ;;
175
176 --disable|-d)
177 set_var "${CONFIG_}$ARG" "# ${CONFIG_}$ARG is not set"
178 ;;
179
180 --module|-m)
181 set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=m"
182 ;;
183
184 --set-str)
185 # sed swallows one level of escaping, so we need double-escaping
186 set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=\"${1//\"/\\\\\"}\""
187 shift
188 ;;
189
190 --set-val)
191 set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=$1"
192 shift
193 ;;
194 --undefine|-u)
195 undef_var "${CONFIG_}$ARG"
196 ;;
197
198 --state|-s)
199 if grep -q "# ${CONFIG_}$ARG is not set" $FN ; then
200 echo n
201 else
202 V="$(grep "^${CONFIG_}$ARG=" $FN)"
203 if [ $? != 0 ] ; then
204 echo undef
205 else
206 V="${V/#${CONFIG_}$ARG=/}"
207 V="${V/#\"/}"
208 V="${V/%\"/}"
209 V="${V//\\\"/\"}"
210 echo "${V}"
211 fi
212 fi
213 ;;
214
215 --enable-after|-E)
216 set_var "${CONFIG_}$B" "${CONFIG_}$B=y" "${CONFIG_}$A"
217 ;;
218
219 --disable-after|-D)
220 set_var "${CONFIG_}$B" "# ${CONFIG_}$B is not set" "${CONFIG_}$A"
221 ;;
222
223 --module-after|-M)
224 set_var "${CONFIG_}$B" "${CONFIG_}$B=m" "${CONFIG_}$A"
225 ;;
226
227 --refresh)
228 yes "" | make oldconfig KCONFIG_CONFIG=$FN
229 ;;
230
231 *)
232 echo "bad command: $CMD" >&2
233 usage
234 ;;
235 esac
236done