#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# Manipulate options in a .config file from the command line

myname=${0##*/}

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

usage() {
	cat >&2 <<EOL
Manipulate options in a .config file from the command line.
Usage:
$myname options command ...
commands:
	--enable|-e option   Enable option
	--disable|-d option  Disable option
	--module|-m option   Turn option into a module
	--set-str option string
	                     Set option to "string"
	--set-val option value
	                     Set option to value
	--undefine|-u option Undefine option
	--state|-s option    Print state of option (n,y,m,undef)

	--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:
	--file config-file   .config file to change (default .config)
	--keep-case|-k       Keep next symbols' case (dont' upper-case it)

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

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

$myname uses 'CONFIG_' as the default symbol prefix. Set the environment
variable CONFIG_ to the prefix to use. Eg.: CONFIG_="FOO_" $myname ...
EOL
	exit 1
}

checkarg() {
	ARG="$1"
	if [ "$ARG" = "" ] ; then
		usage
	fi
	case "$ARG" in
	${CONFIG_}*)
		ARG="${ARG/${CONFIG_}/}"
		;;
	esac
	if [ "$MUNGE_CASE" = "yes" ] ; then
		ARG="`echo $ARG | tr a-z A-Z`"
	fi
}

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"

	sed -e "s:$before:$after:" "$infile" >"$tmpfile"
	# 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"
}

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
		txt_append "^$before=" "$new" "$FN"
		txt_append "^# $before is not set" "$new" "$FN"
	elif grep -Eq "$name_re" "$FN"; then
		txt_subst "^$name=.*" "$new" "$FN"
		txt_subst "^# $name is not set" "$new" "$FN"
	else
		echo "$new" >>"$FN"
	fi
}

undef_var() {
	local name=$1

	txt_delete "^$name=" "$FN"
	txt_delete "^# $name is not set" "$FN"
}

if [ "$1" = "--file" ]; then
	FN="$2"
	if [ "$FN" = "" ] ; then
		usage
	fi
	shift 2
else
	FN=.config
fi

if [ "$1" = "" ] ; then
	usage
fi

MUNGE_CASE=yes
while [ "$1" != "" ] ; do
	CMD="$1"
	shift
	case "$CMD" in
	--keep-case|-k)
		MUNGE_CASE=no
		continue
		;;
	--refresh)
		;;
	--*-after|-E|-D|-M)
		checkarg "$1"
		A=$ARG
		checkarg "$2"
		B=$ARG
		shift 2
		;;
	-*)
		checkarg "$1"
		shift
		;;
	esac
	case "$CMD" in
	--enable|-e)
		set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=y"
		;;

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

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

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

	--set-val)
		set_var "${CONFIG_}$ARG" "${CONFIG_}$ARG=$1"
		shift
		;;
	--undefine|-u)
		undef_var "${CONFIG_}$ARG"
		;;

	--state|-s)
		if grep -q "# ${CONFIG_}$ARG is not set" $FN ; then
			echo n
		else
			V="$(grep "^${CONFIG_}$ARG=" $FN)"
			if [ $? != 0 ] ; then
				echo undef
			else
				V="${V/#${CONFIG_}$ARG=/}"
				V="${V/#\"/}"
				V="${V/%\"/}"
				V="${V//\\\"/\"}"
				echo "${V}"
			fi
		fi
		;;

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

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

	--module-after|-M)
		set_var "${CONFIG_}$B" "${CONFIG_}$B=m" "${CONFIG_}$A"
		;;

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

	*)
		usage
		;;
	esac
done
