18c2ecf20Sopenharmony_ci#!/usr/bin/env bash
28c2ecf20Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0
38c2ecf20Sopenharmony_ci# Manipulate options in a .config file from the command line
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_cimyname=${0##*/}
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci# If no prefix forced, use the default CONFIG_
88c2ecf20Sopenharmony_ciCONFIG_="${CONFIG_-CONFIG_}"
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci# We use an uncommon delimiter for sed substitutions
118c2ecf20Sopenharmony_ciSED_DELIM=$(echo -en "\001")
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ciusage() {
148c2ecf20Sopenharmony_ci	cat >&2 <<EOL
158c2ecf20Sopenharmony_ciManipulate options in a .config file from the command line.
168c2ecf20Sopenharmony_ciUsage:
178c2ecf20Sopenharmony_ci$myname options command ...
188c2ecf20Sopenharmony_cicommands:
198c2ecf20Sopenharmony_ci	--enable|-e option   Enable option
208c2ecf20Sopenharmony_ci	--disable|-d option  Disable option
218c2ecf20Sopenharmony_ci	--module|-m option   Turn option into a module
228c2ecf20Sopenharmony_ci	--set-str option string
238c2ecf20Sopenharmony_ci	                     Set option to "string"
248c2ecf20Sopenharmony_ci	--set-val option value
258c2ecf20Sopenharmony_ci	                     Set option to value
268c2ecf20Sopenharmony_ci	--undefine|-u option Undefine option
278c2ecf20Sopenharmony_ci	--state|-s option    Print state of option (n,y,m,undef)
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci	--enable-after|-E beforeopt option
308c2ecf20Sopenharmony_ci                             Enable option directly after other option
318c2ecf20Sopenharmony_ci	--disable-after|-D beforeopt option
328c2ecf20Sopenharmony_ci                             Disable option directly after other option
338c2ecf20Sopenharmony_ci	--module-after|-M beforeopt option
348c2ecf20Sopenharmony_ci                             Turn option into module directly after other option
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci	commands can be repeated multiple times
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_cioptions:
398c2ecf20Sopenharmony_ci	--file config-file   .config file to change (default .config)
408c2ecf20Sopenharmony_ci	--keep-case|-k       Keep next symbols' case (dont' upper-case it)
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci$myname doesn't check the validity of the .config file. This is done at next
438c2ecf20Sopenharmony_cimake time.
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ciBy default, $myname will upper-case the given symbol. Use --keep-case to keep
468c2ecf20Sopenharmony_cithe case of all following symbols unchanged.
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci$myname uses 'CONFIG_' as the default symbol prefix. Set the environment
498c2ecf20Sopenharmony_civariable CONFIG_ to the prefix to use. Eg.: CONFIG_="FOO_" $myname ...
508c2ecf20Sopenharmony_ciEOL
518c2ecf20Sopenharmony_ci	exit 1
528c2ecf20Sopenharmony_ci}
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_cicheckarg() {
558c2ecf20Sopenharmony_ci	ARG="$1"
568c2ecf20Sopenharmony_ci	if [ "$ARG" = "" ] ; then
578c2ecf20Sopenharmony_ci		usage
588c2ecf20Sopenharmony_ci	fi
598c2ecf20Sopenharmony_ci	case "$ARG" in
608c2ecf20Sopenharmony_ci	${CONFIG_}*)
618c2ecf20Sopenharmony_ci		ARG="${ARG/${CONFIG_}/}"
628c2ecf20Sopenharmony_ci		;;
638c2ecf20Sopenharmony_ci	esac
648c2ecf20Sopenharmony_ci	if [ "$MUNGE_CASE" = "yes" ] ; then
658c2ecf20Sopenharmony_ci		ARG="`echo $ARG | tr a-z A-Z`"
668c2ecf20Sopenharmony_ci	fi
678c2ecf20Sopenharmony_ci}
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_citxt_append() {
708c2ecf20Sopenharmony_ci	local anchor="$1"
718c2ecf20Sopenharmony_ci	local insert="$2"
728c2ecf20Sopenharmony_ci	local infile="$3"
738c2ecf20Sopenharmony_ci	local tmpfile="$infile.swp"
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci	# sed append cmd: 'a\' + newline + text + newline
768c2ecf20Sopenharmony_ci	cmd="$(printf "a\\%b$insert" "\n")"
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci	sed -e "/$anchor/$cmd" "$infile" >"$tmpfile"
798c2ecf20Sopenharmony_ci	# replace original file with the edited one
808c2ecf20Sopenharmony_ci	mv "$tmpfile" "$infile"
818c2ecf20Sopenharmony_ci}
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_citxt_subst() {
848c2ecf20Sopenharmony_ci	local before="$1"
858c2ecf20Sopenharmony_ci	local after="$2"
868c2ecf20Sopenharmony_ci	local infile="$3"
878c2ecf20Sopenharmony_ci	local tmpfile="$infile.swp"
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci	sed -e "s$SED_DELIM$before$SED_DELIM$after$SED_DELIM" "$infile" >"$tmpfile"
908c2ecf20Sopenharmony_ci	# replace original file with the edited one
918c2ecf20Sopenharmony_ci	mv "$tmpfile" "$infile"
928c2ecf20Sopenharmony_ci}
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_citxt_delete() {
958c2ecf20Sopenharmony_ci	local text="$1"
968c2ecf20Sopenharmony_ci	local infile="$2"
978c2ecf20Sopenharmony_ci	local tmpfile="$infile.swp"
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci	sed -e "/$text/d" "$infile" >"$tmpfile"
1008c2ecf20Sopenharmony_ci	# replace original file with the edited one
1018c2ecf20Sopenharmony_ci	mv "$tmpfile" "$infile"
1028c2ecf20Sopenharmony_ci}
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ciset_var() {
1058c2ecf20Sopenharmony_ci	local name=$1 new=$2 before=$3
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci	name_re="^($name=|# $name is not set)"
1088c2ecf20Sopenharmony_ci	before_re="^($before=|# $before is not set)"
1098c2ecf20Sopenharmony_ci	if test -n "$before" && grep -Eq "$before_re" "$FN"; then
1108c2ecf20Sopenharmony_ci		txt_append "^$before=" "$new" "$FN"
1118c2ecf20Sopenharmony_ci		txt_append "^# $before is not set" "$new" "$FN"
1128c2ecf20Sopenharmony_ci	elif grep -Eq "$name_re" "$FN"; then
1138c2ecf20Sopenharmony_ci		txt_subst "^$name=.*" "$new" "$FN"
1148c2ecf20Sopenharmony_ci		txt_subst "^# $name is not set" "$new" "$FN"
1158c2ecf20Sopenharmony_ci	else
1168c2ecf20Sopenharmony_ci		echo "$new" >>"$FN"
1178c2ecf20Sopenharmony_ci	fi
1188c2ecf20Sopenharmony_ci}
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ciundef_var() {
1218c2ecf20Sopenharmony_ci	local name=$1
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci	txt_delete "^$name=" "$FN"
1248c2ecf20Sopenharmony_ci	txt_delete "^# $name is not set" "$FN"
1258c2ecf20Sopenharmony_ci}
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ciif [ "$1" = "--file" ]; then
1288c2ecf20Sopenharmony_ci	FN="$2"
1298c2ecf20Sopenharmony_ci	if [ "$FN" = "" ] ; then
1308c2ecf20Sopenharmony_ci		usage
1318c2ecf20Sopenharmony_ci	fi
1328c2ecf20Sopenharmony_ci	shift 2
1338c2ecf20Sopenharmony_cielse
1348c2ecf20Sopenharmony_ci	FN=.config
1358c2ecf20Sopenharmony_cifi
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ciif [ "$1" = "" ] ; then
1388c2ecf20Sopenharmony_ci	usage
1398c2ecf20Sopenharmony_cifi
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_ciMUNGE_CASE=yes
1428c2ecf20Sopenharmony_ciwhile [ "$1" != "" ] ; do
1438c2ecf20Sopenharmony_ci	CMD="$1"
1448c2ecf20Sopenharmony_ci	shift
1458c2ecf20Sopenharmony_ci	case "$CMD" in
1468c2ecf20Sopenharmony_ci	--keep-case|-k)
1478c2ecf20Sopenharmony_ci		MUNGE_CASE=no
1488c2ecf20Sopenharmony_ci		continue
1498c2ecf20Sopenharmony_ci		;;
1508c2ecf20Sopenharmony_ci	--refresh)
1518c2ecf20Sopenharmony_ci		;;
1528c2ecf20Sopenharmony_ci	--*-after|-E|-D|-M)
1538c2ecf20Sopenharmony_ci		checkarg "$1"
1548c2ecf20Sopenharmony_ci		A=$ARG
1558c2ecf20Sopenharmony_ci		checkarg "$2"
1568c2ecf20Sopenharmony_ci		B=$ARG
1578c2ecf20Sopenharmony_ci		shift 2
1588c2ecf20Sopenharmony_ci		;;
1598c2ecf20Sopenharmony_ci	-*)
1608c2ecf20Sopenharmony_ci		checkarg "$1"
1618c2ecf20Sopenharmony_ci		shift
1628c2ecf20Sopenharmony_ci		;;
1638c2ecf20Sopenharmony_ci	esac
1648c2ecf20Sopenharmony_ci	case "$CMD" in
1658c2ecf20Sopenharmony_ci	--enable|-e)
1668c2ecf20Sopenharmony_ci		set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=y"
1678c2ecf20Sopenharmony_ci		;;
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci	--disable|-d)
1708c2ecf20Sopenharmony_ci		set_var "${CONFIG_}$ARG" "# ${CONFIG_}$ARG is not set"
1718c2ecf20Sopenharmony_ci		;;
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_ci	--module|-m)
1748c2ecf20Sopenharmony_ci		set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=m"
1758c2ecf20Sopenharmony_ci		;;
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_ci	--set-str)
1788c2ecf20Sopenharmony_ci		# sed swallows one level of escaping, so we need double-escaping
1798c2ecf20Sopenharmony_ci		set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=\"${1//\"/\\\\\"}\""
1808c2ecf20Sopenharmony_ci		shift
1818c2ecf20Sopenharmony_ci		;;
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_ci	--set-val)
1848c2ecf20Sopenharmony_ci		set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=$1"
1858c2ecf20Sopenharmony_ci		shift
1868c2ecf20Sopenharmony_ci		;;
1878c2ecf20Sopenharmony_ci	--undefine|-u)
1888c2ecf20Sopenharmony_ci		undef_var "${CONFIG_}$ARG"
1898c2ecf20Sopenharmony_ci		;;
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ci	--state|-s)
1928c2ecf20Sopenharmony_ci		if grep -q "# ${CONFIG_}$ARG is not set" $FN ; then
1938c2ecf20Sopenharmony_ci			echo n
1948c2ecf20Sopenharmony_ci		else
1958c2ecf20Sopenharmony_ci			V="$(grep "^${CONFIG_}$ARG=" $FN)"
1968c2ecf20Sopenharmony_ci			if [ $? != 0 ] ; then
1978c2ecf20Sopenharmony_ci				echo undef
1988c2ecf20Sopenharmony_ci			else
1998c2ecf20Sopenharmony_ci				V="${V/#${CONFIG_}$ARG=/}"
2008c2ecf20Sopenharmony_ci				V="${V/#\"/}"
2018c2ecf20Sopenharmony_ci				V="${V/%\"/}"
2028c2ecf20Sopenharmony_ci				V="${V//\\\"/\"}"
2038c2ecf20Sopenharmony_ci				echo "${V}"
2048c2ecf20Sopenharmony_ci			fi
2058c2ecf20Sopenharmony_ci		fi
2068c2ecf20Sopenharmony_ci		;;
2078c2ecf20Sopenharmony_ci
2088c2ecf20Sopenharmony_ci	--enable-after|-E)
2098c2ecf20Sopenharmony_ci		set_var "${CONFIG_}$B" "${CONFIG_}$B=y" "${CONFIG_}$A"
2108c2ecf20Sopenharmony_ci		;;
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_ci	--disable-after|-D)
2138c2ecf20Sopenharmony_ci		set_var "${CONFIG_}$B" "# ${CONFIG_}$B is not set" "${CONFIG_}$A"
2148c2ecf20Sopenharmony_ci		;;
2158c2ecf20Sopenharmony_ci
2168c2ecf20Sopenharmony_ci	--module-after|-M)
2178c2ecf20Sopenharmony_ci		set_var "${CONFIG_}$B" "${CONFIG_}$B=m" "${CONFIG_}$A"
2188c2ecf20Sopenharmony_ci		;;
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_ci	# undocumented because it ignores --file (fixme)
2218c2ecf20Sopenharmony_ci	--refresh)
2228c2ecf20Sopenharmony_ci		yes "" | make oldconfig
2238c2ecf20Sopenharmony_ci		;;
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_ci	*)
2268c2ecf20Sopenharmony_ci		usage
2278c2ecf20Sopenharmony_ci		;;
2288c2ecf20Sopenharmony_ci	esac
2298c2ecf20Sopenharmony_cidone
230