config 4.5 KB
Newer Older
1 2 3
#!/bin/bash
# Manipulate options in a .config file from the command line

4 5
myname=${0##*/}

6 7 8
# If no prefix forced, use the default CONFIG_
CONFIG_="${CONFIG_-CONFIG_}"

9 10 11 12
usage() {
	cat >&2 <<EOL
Manipulate options in a .config file from the command line.
Usage:
13
$myname options command ...
14 15 16
commands:
	--enable|-e option   Enable option
	--disable|-d option  Disable option
17
	--module|-m option   Turn option into a module
18 19 20 21
	--set-str option string
	                     Set option to "string"
	--set-val option value
	                     Set option to value
22
	--undefine|-u option Undefine option
23
	--state|-s option    Print state of option (n,y,m,undef)
24 25 26 27 28 29 30 31 32 33 34

	--enable-after|-E beforeopt option
                             Enable option directly after other option
	--disable-after|-D beforeopt option
                             Disable option directly after other option
	--module-after|-M beforeopt option
                             Turn option into module directly after other option

	commands can be repeated multiple times

options:
35 36
	--file config-file   .config file to change (default .config)
	--keep-case|-k       Keep next symbols' case (dont' upper-case it)
37

38
$myname doesn't check the validity of the .config file. This is done at next
39 40
make time.

41
By default, $myname will upper-case the given symbol. Use --keep-case to keep
42
the case of all following symbols unchanged.
43

44 45
$myname uses 'CONFIG_' as the default symbol prefix. Set the environment
variable CONFIG_ to the prefix to use. Eg.: CONFIG_="FOO_" $myname ...
46 47 48 49 50 51 52 53 54 55
EOL
	exit 1
}

checkarg() {
	ARG="$1"
	if [ "$ARG" = "" ] ; then
		usage
	fi
	case "$ARG" in
56 57
	${CONFIG_}*)
		ARG="${ARG/${CONFIG_}/}"
58 59
		;;
	esac
60 61 62
	if [ "$MUNGE_CASE" = "yes" ] ; then
		ARG="`echo $ARG | tr a-z A-Z`"
	fi
63 64
}

65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
txt_append() {
	local anchor="$1"
	local insert="$2"
	local infile="$3"
	local tmpfile="$infile.swp"

	# sed append cmd: 'a\' + newline + text + newline
	cmd="$(printf "a\\%b$insert" "\n")"

	sed -e "/$anchor/$cmd" "$infile" >"$tmpfile"
	# replace original file with the edited one
	mv "$tmpfile" "$infile"
}

txt_subst() {
	local before="$1"
	local after="$2"
	local infile="$3"
	local tmpfile="$infile.swp"

85
	sed -e "s:$before:$after:" "$infile" >"$tmpfile"
86 87 88 89 90 91 92 93 94 95 96 97 98 99
	# replace original file with the edited one
	mv "$tmpfile" "$infile"
}

txt_delete() {
	local text="$1"
	local infile="$2"
	local tmpfile="$infile.swp"

	sed -e "/$text/d" "$infile" >"$tmpfile"
	# replace original file with the edited one
	mv "$tmpfile" "$infile"
}

100 101 102 103 104 105
set_var() {
	local name=$1 new=$2 before=$3

	name_re="^($name=|# $name is not set)"
	before_re="^($before=|# $before is not set)"
	if test -n "$before" && grep -Eq "$before_re" "$FN"; then
106 107
		txt_append "^$before=" "$new" "$FN"
		txt_append "^# $before is not set" "$new" "$FN"
108
	elif grep -Eq "$name_re" "$FN"; then
109 110
		txt_subst "^$name=.*" "$new" "$FN"
		txt_subst "^# $name is not set" "$new" "$FN"
111 112 113
	else
		echo "$new" >>"$FN"
	fi
114 115
}

116 117 118
undef_var() {
	local name=$1

119 120
	txt_delete "^$name=" "$FN"
	txt_delete "^# $name is not set" "$FN"
121 122
}

123 124 125 126 127
if [ "$1" = "--file" ]; then
	FN="$2"
	if [ "$FN" = "" ] ; then
		usage
	fi
128
	shift 2
129 130 131 132
else
	FN=.config
fi

133 134 135 136
if [ "$1" = "" ] ; then
	usage
fi

137
MUNGE_CASE=yes
138 139 140 141
while [ "$1" != "" ] ; do
	CMD="$1"
	shift
	case "$CMD" in
142 143 144 145
	--keep-case|-k)
		MUNGE_CASE=no
		continue
		;;
146 147
	--refresh)
		;;
148
	--*-after|-E|-D|-M)
149 150 151 152 153 154
		checkarg "$1"
		A=$ARG
		checkarg "$2"
		B=$ARG
		shift 2
		;;
155
	-*)
156 157 158
		checkarg "$1"
		shift
		;;
159 160 161
	esac
	case "$CMD" in
	--enable|-e)
162
		set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=y"
163
		;;
164 165

	--disable|-d)
166
		set_var "${CONFIG_}$ARG" "# ${CONFIG_}$ARG is not set"
167 168 169
		;;

	--module|-m)
170
		set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=m"
171 172
		;;

173
	--set-str)
174
		# sed swallows one level of escaping, so we need double-escaping
175
		set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=\"${1//\"/\\\\\"}\""
176 177 178
		shift
		;;

179
	--set-val)
180
		set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=$1"
181 182
		shift
		;;
183 184 185
	--undefine|-u)
		undef_var "${CONFIG_}$ARG"
		;;
186

187
	--state|-s)
188
		if grep -q "# ${CONFIG_}$ARG is not set" $FN ; then
189 190
			echo n
		else
191
			V="$(grep "^${CONFIG_}$ARG=" $FN)"
192 193 194
			if [ $? != 0 ] ; then
				echo undef
			else
195
				V="${V/#${CONFIG_}$ARG=/}"
196 197
				V="${V/#\"/}"
				V="${V/%\"/}"
198
				V="${V//\\\"/\"}"
199
				echo "${V}"
200 201 202 203 204
			fi
		fi
		;;

	--enable-after|-E)
205
		set_var "${CONFIG_}$B" "${CONFIG_}$B=y" "${CONFIG_}$A"
206 207 208
		;;

	--disable-after|-D)
209
		set_var "${CONFIG_}$B" "# ${CONFIG_}$B is not set" "${CONFIG_}$A"
210 211 212
		;;

	--module-after|-M)
213
		set_var "${CONFIG_}$B" "${CONFIG_}$B=m" "${CONFIG_}$A"
214 215 216 217 218 219 220 221 222 223 224 225
		;;

	# undocumented because it ignores --file (fixme)
	--refresh)
		yes "" | make oldconfig
		;;

	*)
		usage
		;;
	esac
done