240 lines · 4.8 KB · Text
RawDownload
#!/usr/bin/env 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_}" # We use an uncommon delimiter for sed substitutionsSED_DELIM=$(echo -en "\001") usage() {	cat >&2 <<EOLManipulate 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	--refresh            Refresh the config using old settings 	commands can be repeated multiple times options:	--file config-file   .config file to change (default .config)	--keep-case|-k       Keep next symbols' case (don't upper-case it) $myname doesn't check the validity of the .config file. This is done at nextmake time. By default, $myname will upper-case the given symbol. Use --keep-case to keepthe case of all following symbols unchanged. $myname uses 'CONFIG_' as the default symbol prefix. Set the environmentvariable 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" 	# sed append cmd: 'a\' + newline + text + newline	cmd="$(printf "a\\%b$insert" "\n")" 	# We don't really need a backup file, but in-place editing with backup	# skipped is not portable due to different implementations parsing	# arguments in incompatible manners.	# Create a backup file anyway to ensure portability. The file will be	# deleted on exit.	sed -E -i.swp -e "/$anchor/$cmd" "$infile"	SED_EDITED=1} txt_subst() {	local before="$1"	local after="$2"	local infile="$3" 	sed -E -i.swp -e "s$SED_DELIM$before$SED_DELIM$after$SED_DELIM" "$infile"	SED_EDITED=1} txt_delete() {	local text="$1"	local infile="$2" 	sed -E -i.swp -e "/$text/d" "$infile"	SED_EDITED=1} 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_re" "$new" "$FN"	elif grep -Eq "$name_re" "$FN"; then		txt_subst "$name_re" "$new" "$FN"	else		echo "$new" >>"$FN"	fi} undef_var() {	local name=$1 	txt_delete "^($name=|# $name is not set)" "$FN"} SED_EDITED=0on_exit() {	if [ "$SED_EDITED" -ge 1 ]; then		rm -f "$FN.swp"	fi}trap on_exit EXIT FN=.configCMDS=()while [[ $# -gt 0 ]]; do	if [ "$1" = "--file" ]; then		if [ "$2" = "" ]; then			usage		fi		FN="$2"		shift 2	else		CMDS+=("$1")		shift	fidone set -- "${CMDS[@]}"if [ "$1" = "" ] ; then	usagefi MUNGE_CASE=yeswhile [ "$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"		;; 	--refresh)		yes "" | make oldconfig KCONFIG_CONFIG=$FN		;; 	*)		echo "bad command: $CMD" >&2		usage		;;	esacdone