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