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