/ util / scripts / config
config
  1  #!/usr/bin/env bash
  2  # SPDX-License-Identifier: GPL-2.0-only
  3  # Manipulate options in a .config file from the command line
  4  
  5  myname=${0##*/}
  6  
  7  # If no prefix forced, use the default CONFIG_
  8  CONFIG_="${CONFIG_-CONFIG_}"
  9  
 10  usage() {
 11  	cat >&2 <<EOL
 12  Manipulate options in a .config file from the command line.
 13  Usage:
 14  $myname options command ...
 15  commands:
 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  
 35  options:
 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
 40  make time.
 41  
 42  By default, $myname will upper-case the given symbol. Use --keep-case to keep
 43  the case of all following symbols unchanged.
 44  
 45  $myname uses 'CONFIG_' as the default symbol prefix. Set the environment
 46  variable CONFIG_ to the prefix to use. Eg.: CONFIG_="FOO_" $myname ...
 47  EOL
 48  	exit 1
 49  }
 50  
 51  checkarg() {
 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  
 66  txt_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  
 80  txt_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  
 91  txt_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  
101  set_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  
117  undef_var() {
118  	local name=$1
119  
120  	txt_delete "^$name=" "$FN"
121  	txt_delete "^# $name is not set" "$FN"
122  }
123  
124  if [ "$1" = "--file" ]; then
125  	FN="$2"
126  	if [ "$FN" = "" ] ; then
127  		usage
128  	fi
129  	shift 2
130  else
131  	FN=.config
132  fi
133  
134  if [ "$1" = "" ] ; then
135  	usage
136  fi
137  
138  MUNGE_CASE=yes
139  while [ "$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
226  done