Pablo Greco 7b2c62
#!/bin/bash
Pablo Greco 7b2c62
#
Pablo Greco 7b2c62
# This script takes the merged config files and processes them through oldconfig
Pablo Greco 7b2c62
# and listnewconfig
Pablo Greco 7b2c62
#
Pablo Greco 7b2c62
Pablo Greco 7b2c62
usage()
Pablo Greco 7b2c62
{
Pablo Greco 7b2c62
	# alphabetical order please
Pablo Greco 7b2c62
	echo "process_configs.sh [ options ] package_name kernel_version"
Pablo Greco 7b2c62
	echo "     -a: report all errors, equivalent to [-c -n -w -i]"
Pablo Greco 7b2c62
	echo "     -c: error on mismatched config options"
Pablo Greco 7b2c62
	echo "     -i: continue on error"
Pablo Greco 7b2c62
	echo "     -n: error on unset config options"
Pablo Greco 7b2c62
	echo "     -t: test run, do not overwrite original config"
Pablo Greco 7b2c62
	echo "     -w: error on misconfigured config options"
Pablo Greco 7b2c62
	echo "     -z: commit new configs to pending directory"
Pablo Greco 7b2c62
	exit 1
Pablo Greco 7b2c62
}
Pablo Greco 7b2c62
Pablo Greco 7b2c62
die()
Pablo Greco 7b2c62
{
Pablo Greco 7b2c62
	echo "$1"
Pablo Greco 7b2c62
	exit 1
Pablo Greco 7b2c62
}
Pablo Greco 7b2c62
Pablo Greco 7b2c62
# stupid function to find top of tree to do kernel make configs
Pablo Greco 7b2c62
switch_to_toplevel()
Pablo Greco 7b2c62
{
Pablo Greco 7b2c62
	path="$(pwd)"
Pablo Greco 7b2c62
	while test -n "$path"
Pablo Greco 7b2c62
	do
Pablo Greco 7b2c62
		test -e $path/MAINTAINERS && \
Pablo Greco 7b2c62
			test -d $path/drivers && \
Pablo Greco 7b2c62
			break
Pablo Greco 7b2c62
Pablo Greco 7b2c62
		path="$(dirname $path)"
Pablo Greco 7b2c62
	done
Pablo Greco 7b2c62
Pablo Greco 7b2c62
	test -n "$path"  || die "Can't find toplevel"
Pablo Greco 7b2c62
	echo "$path"
Pablo Greco 7b2c62
}
Pablo Greco 7b2c62
Pablo Greco 7b2c62
checkoptions()
Pablo Greco 7b2c62
{
Pablo Greco 7b2c62
	/usr/bin/awk '
Pablo Greco 7b2c62
Pablo Greco 7b2c62
		/is not set/ {
Pablo Greco 7b2c62
			split ($0, a, "#");
Pablo Greco 7b2c62
			split(a[2], b);
Pablo Greco 7b2c62
			if (NR==FNR) {
Pablo Greco 7b2c62
				configs[b[1]]="is not set";
Pablo Greco 7b2c62
			} else {
Pablo Greco 7b2c62
				if (configs[b[1]] != "" && configs[b[1]] != "is not set")
Pablo Greco 7b2c62
					 print "Found # "b[1] " is not set, after generation, had " b[1] " " configs[b[1]] " in Source tree";
Pablo Greco 7b2c62
			}
Pablo Greco 7b2c62
		}
Pablo Greco 7b2c62
Pablo Greco 7b2c62
		/=/     {
Pablo Greco 7b2c62
			split ($0, a, "=");
Pablo Greco 7b2c62
			if (NR==FNR) {
Pablo Greco 7b2c62
				configs[a[1]]=a[2];
Pablo Greco 7b2c62
			} else {
Pablo Greco 7b2c62
				if (configs[a[1]] != "" && configs[a[1]] != a[2])
Pablo Greco 7b2c62
					 print "Found "a[1]"="a[2]" after generation, had " a[1]"="configs[a[1]]" in Source tree";
Pablo Greco 7b2c62
			}
Pablo Greco 7b2c62
		}
Pablo Greco 7b2c62
	' $1 $2 > .mismatches
Pablo Greco 7b2c62
Pablo Greco 7b2c62
	if test -s .mismatches
Pablo Greco 7b2c62
	then
Pablo Greco 7b2c62
		echo "Error: Mismatches found in configuration files"
Pablo Greco 7b2c62
		cat .mismatches
Pablo Greco 7b2c62
		RETURNCODE=1
Pablo Greco 7b2c62
		[ "$CONTINUEONERROR" ] || exit 1
Pablo Greco 7b2c62
	fi
Pablo Greco 7b2c62
}
Pablo Greco 7b2c62
Pablo Greco 7b2c62
parsenewconfigs()
Pablo Greco 7b2c62
{
Pablo Greco 7b2c62
	tmpdir=$(mktemp -d)
Pablo Greco 7b2c62
Pablo Greco 7b2c62
	# This awk script reads the output of make listnewconfig
Pablo Greco 7b2c62
	# and puts it into CONFIG_FOO files. Using the output of
Pablo Greco 7b2c62
	# listnewconfig is much easier to ensure we get the default
Pablo Greco 7b2c62
	# output.
Pablo Greco 7b2c62
        /usr/bin/awk -v BASE=$tmpdir '
Pablo Greco 7b2c62
                /is not set/ {
Pablo Greco 7b2c62
                        split ($0, a, "#");
Pablo Greco 7b2c62
                        split(a[2], b);
Pablo Greco 7b2c62
                        OUT_FILE=BASE"/"b[1];
Pablo Greco 7b2c62
                        print $0 >> OUT_FILE;
Pablo Greco 7b2c62
                }
Pablo Greco 7b2c62
Pablo Greco 7b2c62
                /=/     {
Pablo Greco 7b2c62
                        split ($0, a, "=");
Pablo Greco 7b2c62
                        OUT_FILE=BASE"/"a[1];
Pablo Greco 7b2c62
                        if (a[2] == "n")
Pablo Greco 7b2c62
                                print "# " a[1] " is not set" >> OUT_FILE;
Pablo Greco 7b2c62
                        else
Pablo Greco 7b2c62
                                print $0 >> OUT_FILE;
Pablo Greco 7b2c62
                }
Pablo Greco 7b2c62
Pablo Greco 7b2c62
        ' .newoptions
Pablo Greco 7b2c62
Pablo Greco 7b2c62
	# This awk script parses the output of helpnewconfig.
Pablo Greco 7b2c62
	# Each option is separated between ----- markers
Pablo Greco 7b2c62
	# The goal is to put all the help text as a comment in
Pablo Greco 7b2c62
	# each CONFIG_FOO file. Because of how awk works
Pablo Greco 7b2c62
	# there's a lot of moving files around and catting to
Pablo Greco 7b2c62
	# get what we need.
Pablo Greco 7b2c62
        /usr/bin/awk -v BASE=$tmpdir '
Pablo Greco 7b2c62
                BEGIN { inpatch=0;
Pablo Greco 7b2c62
			outfile="none";
Pablo Greco 7b2c62
                        symbol="none"; }
Pablo Greco 7b2c62
                /^CONFIG_.*:$/ {
Pablo Greco 7b2c62
                        split($0, a, ":");
Pablo Greco 7b2c62
                        symbol=a[1];
Pablo Greco 7b2c62
                        outfile=BASE "/fake_"symbol
Pablo Greco 7b2c62
                }
Pablo Greco 7b2c62
                /-----/ {
Pablo Greco 7b2c62
			if (inpatch == 0) {
Pablo Greco 7b2c62
				inpatch = 1;
Pablo Greco 7b2c62
			}
Pablo Greco 7b2c62
                        else {
Pablo Greco 7b2c62
                                if (symbol != "none") {
Pablo Greco 7b2c62
                                    system("cat " outfile " " BASE "/" symbol " > " BASE "/tmpf");
Pablo Greco 7b2c62
                                    system("mv " BASE "/tmpf " BASE "/" symbol);
Pablo Greco 7b2c62
                                    symbol="none"
Pablo Greco 7b2c62
				}
Pablo Greco 7b2c62
                                outfile="none"
Pablo Greco 7b2c62
				inpatch = 0;
Pablo Greco 7b2c62
                        }
Pablo Greco 7b2c62
                }
Pablo Greco 7b2c62
                !/-----/ {
Pablo Greco 7b2c62
                        if (inpatch == 1 && outfile != "none") {
Pablo Greco 7b2c62
                                print "# "$0 >> outfile;
Pablo Greco 7b2c62
                        }
Pablo Greco 7b2c62
                }
Pablo Greco 7b2c62
Pablo Greco 7b2c62
Pablo Greco 7b2c62
        ' .helpnewconfig
Pablo Greco 7b2c62
Pablo Greco 7b2c62
	pushd $tmpdir &> /dev/null
Pablo Greco 7b2c62
	rm fake_*
Pablo Greco 7b2c62
	popd &> /dev/null
Pablo Greco 7b2c62
	for f in `ls $tmpdir`; do
Pablo Greco 7b2c62
		[[ -e "$tmpdir/$f" ]] || break
Pablo Greco 7b2c62
		cp $tmpdir/$f $SCRIPT_DIR/pending"$FLAVOR"/generic/
Pablo Greco 7b2c62
	done
Pablo Greco 7b2c62
Pablo Greco 7b2c62
	rm -rf $tmpdir
Pablo Greco 7b2c62
}
Pablo Greco 7b2c62
Pablo Greco 7b2c62
function commit_new_configs()
Pablo Greco 7b2c62
{
Pablo Greco 7b2c62
	# assume we are in $source_tree/configs, need to get to top level
Pablo Greco 7b2c62
	pushd $(switch_to_toplevel) &>/dev/null
Pablo Greco 7b2c62
Pablo Greco 7b2c62
	for cfg in $SCRIPT_DIR/${PACKAGE_NAME}${KVERREL}${SUBARCH}*.config
Pablo Greco 7b2c62
	do
Pablo Greco 7b2c62
		arch=$(head -1 $cfg | cut -b 3-)
Pablo Greco 7b2c62
		cfgtmp="${cfg}.tmp"
Pablo Greco 7b2c62
		cfgorig="${cfg}.orig"
Pablo Greco 7b2c62
		cat $cfg > $cfgorig
Pablo Greco 7b2c62
Pablo Greco 7b2c62
		if [ "$arch" = "EMPTY" ]
Pablo Greco 7b2c62
		then
Pablo Greco 7b2c62
			# This arch is intentionally left blank
Pablo Greco 7b2c62
			continue
Pablo Greco 7b2c62
		fi
Pablo Greco 7b2c62
		echo -n "Checking for new configs in $cfg ... "
Pablo Greco 7b2c62
Pablo Greco 7b2c62
		make ARCH=$arch KCONFIG_CONFIG=$cfgorig listnewconfig >& .listnewconfig
Pablo Greco 7b2c62
		grep -E 'CONFIG_' .listnewconfig > .newoptions
Pablo Greco 7b2c62
		if test -s .newoptions
Pablo Greco 7b2c62
		then
Pablo Greco 7b2c62
			make ARCH=$arch KCONFIG_CONFIG=$cfgorig helpnewconfig >& .helpnewconfig
Pablo Greco 7b2c62
			parsenewconfigs
Pablo Greco 7b2c62
		fi
Pablo Greco 7b2c62
		rm .newoptions
Pablo Greco 7b2c62
		echo "done"
Pablo Greco 7b2c62
	done
Pablo Greco 7b2c62
Pablo Greco 7b2c62
	git add $SCRIPT_DIR/pending"$FLAVOR"
Pablo Greco 7b2c62
	git commit -m "[redhat] AUTOMATIC: New configs"
Pablo Greco 7b2c62
}
Pablo Greco 7b2c62
Pablo Greco 7b2c62
function process_configs()
Pablo Greco 7b2c62
{
Pablo Greco 7b2c62
	# assume we are in $source_tree/configs, need to get to top level
Pablo Greco 7b2c62
	pushd $(switch_to_toplevel) &>/dev/null
Pablo Greco 7b2c62
Pablo Greco 7b2c62
	for cfg in $SCRIPT_DIR/${PACKAGE_NAME}${KVERREL}${SUBARCH}*.config
Pablo Greco 7b2c62
	do
Pablo Greco 7b2c62
		arch=$(head -1 $cfg | cut -b 3-)
Pablo Greco 7b2c62
		cfgtmp="${cfg}.tmp"
Pablo Greco 7b2c62
		cfgorig="${cfg}.orig"
Pablo Greco 7b2c62
		cat $cfg > $cfgorig
Pablo Greco 7b2c62
Pablo Greco 7b2c62
		if [ "$arch" = "EMPTY" ]
Pablo Greco 7b2c62
		then
Pablo Greco 7b2c62
			# This arch is intentionally left blank
Pablo Greco 7b2c62
			continue
Pablo Greco 7b2c62
		fi
Pablo Greco 7b2c62
		echo -n "Processing $cfg ... "
Pablo Greco 7b2c62
Pablo Greco 7b2c62
		make ARCH=$arch KCONFIG_CONFIG=$cfgorig listnewconfig >& .listnewconfig
Pablo Greco 7b2c62
		grep -E 'CONFIG_' .listnewconfig > .newoptions
Pablo Greco 7b2c62
		if test -n "$NEWOPTIONS" && test -s .newoptions
Pablo Greco 7b2c62
		then
Pablo Greco 7b2c62
			echo "Found unset config items, please set them to an appropriate value"
Pablo Greco 7b2c62
			cat .newoptions
Pablo Greco 7b2c62
			rm .newoptions
Pablo Greco 7b2c62
			RETURNCODE=1
Pablo Greco 7b2c62
			[ "$CONTINUEONERROR" ] || exit 1
Pablo Greco 7b2c62
		fi
Pablo Greco 7b2c62
		rm .newoptions
Pablo Greco 7b2c62
Pablo Greco 7b2c62
		grep -E 'config.*warning' .listnewconfig > .warnings
Pablo Greco 7b2c62
		if test -n "$CHECKWARNINGS" && test -s .warnings
Pablo Greco 7b2c62
		then
Pablo Greco 7b2c62
			echo "Found misconfigured config items, please set them to an appropriate value"
Pablo Greco 7b2c62
			cat .warnings
Pablo Greco 7b2c62
			rm .warnings
Pablo Greco 7b2c62
			RETURNCODE=1
Pablo Greco 7b2c62
			[ "$CONTINUEONERROR" ] || exit 1
Pablo Greco 7b2c62
		fi
Pablo Greco 7b2c62
		rm .warnings
Pablo Greco 7b2c62
Pablo Greco 7b2c62
		rm .listnewconfig
Pablo Greco 7b2c62
Pablo Greco 7b2c62
		make ARCH=$arch KCONFIG_CONFIG=$cfgorig olddefconfig > /dev/null || exit 1
Pablo Greco 7b2c62
		echo "# $arch" > ${cfgtmp}
Pablo Greco 7b2c62
		cat "${cfgorig}" >> ${cfgtmp}
Pablo Greco 7b2c62
		if test -n "$CHECKOPTIONS"
Pablo Greco 7b2c62
		then
Pablo Greco 7b2c62
			checkoptions $cfg $cfgtmp
Pablo Greco 7b2c62
		fi
Pablo Greco 7b2c62
		# if test run, don't overwrite original
Pablo Greco 7b2c62
		if test -n "$TESTRUN"
Pablo Greco 7b2c62
		then
Pablo Greco 7b2c62
			rm ${cfgtmp}
Pablo Greco 7b2c62
		else
Pablo Greco 7b2c62
			mv ${cfgtmp} ${cfg}
Pablo Greco 7b2c62
		fi
Pablo Greco 7b2c62
		rm ${cfgorig}
Pablo Greco 7b2c62
		echo "done"
Pablo Greco 7b2c62
	done
Pablo Greco 7b2c62
	rm "$SCRIPT_DIR"/*.config*.old
Pablo Greco 7b2c62
	popd > /dev/null
Pablo Greco 7b2c62
Pablo Greco 7b2c62
	echo "Processed config files are in $SCRIPT_DIR"
Pablo Greco 7b2c62
}
Pablo Greco 7b2c62
Pablo Greco 7b2c62
CHECKOPTIONS=""
Pablo Greco 7b2c62
CONTINUEONERROR=""
Pablo Greco 7b2c62
NEWOPTIONS=""
Pablo Greco 7b2c62
TESTRUN=""
Pablo Greco 7b2c62
CHECKWARNINGS=""
Pablo Greco 7b2c62
Pablo Greco 7b2c62
RETURNCODE=0
Pablo Greco 7b2c62
Pablo Greco 7b2c62
while [[ $# -gt 0 ]]
Pablo Greco 7b2c62
do
Pablo Greco 7b2c62
	key="$1"
Pablo Greco 7b2c62
	case $key in
Pablo Greco 7b2c62
		-a)
Pablo Greco 7b2c62
			CHECKOPTIONS="x"
Pablo Greco 7b2c62
			CONTINUEONERROR="x"
Pablo Greco 7b2c62
			NEWOPTIONS="x"
Pablo Greco 7b2c62
			CHECKWARNINGS="x"
Pablo Greco 7b2c62
			;;
Pablo Greco 7b2c62
		-c)
Pablo Greco 7b2c62
			CHECKOPTIONS="x"
Pablo Greco 7b2c62
			;;
Pablo Greco 7b2c62
		-h)
Pablo Greco 7b2c62
			usage
Pablo Greco 7b2c62
			;;
Pablo Greco 7b2c62
		-i)
Pablo Greco 7b2c62
			CONTINUEONERROR="x"
Pablo Greco 7b2c62
			;;
Pablo Greco 7b2c62
		-n)
Pablo Greco 7b2c62
			NEWOPTIONS="x"
Pablo Greco 7b2c62
			;;
Pablo Greco 7b2c62
		-t)
Pablo Greco 7b2c62
			TESTRUN="x"
Pablo Greco 7b2c62
			;;
Pablo Greco 7b2c62
		-w)
Pablo Greco 7b2c62
			CHECKWARNINGS="x"
Pablo Greco 7b2c62
			;;
Pablo Greco 7b2c62
		-z)
Pablo Greco 7b2c62
			COMMITNEWCONFIGS="x"
Pablo Greco 7b2c62
			;;
Pablo Greco 7b2c62
		*)
Pablo Greco 7b2c62
			break;;
Pablo Greco 7b2c62
	esac
Pablo Greco 7b2c62
	shift
Pablo Greco 7b2c62
done
Pablo Greco 7b2c62
Pablo Greco 7b2c62
PACKAGE_NAME="${1:-kernel}" # defines the package name used
Pablo Greco 7b2c62
KVERREL="$(test -n "$2" && echo "-$2" || echo "")"
Pablo Greco 7b2c62
SUBARCH="$(test -n "$3" && echo "-$3" || echo "")"
Pablo Greco 7b2c62
FLAVOR="$(test -n "$4" && echo "-$4" || echo "-common")"
Pablo Greco 7b2c62
SCRIPT="$(readlink -f $0)"
Pablo Greco 7b2c62
OUTPUT_DIR="$PWD"
Pablo Greco 7b2c62
SCRIPT_DIR="$(dirname $SCRIPT)"
Pablo Greco 7b2c62
Pablo Greco 7b2c62
# Most RHEL options are options we want in Fedora so RHEL pending settings head
Pablo Greco 7b2c62
# to common/
Pablo Greco 7b2c62
if [ "$FLAVOR" = "-rhel" ]
Pablo Greco 7b2c62
then
Pablo Greco 7b2c62
	FLAVOR="-common"
Pablo Greco 7b2c62
fi
Pablo Greco 7b2c62
Pablo Greco 7b2c62
# to handle this script being a symlink
Pablo Greco 7b2c62
cd $SCRIPT_DIR
Pablo Greco 7b2c62
Pablo Greco 7b2c62
if test -n "$COMMITNEWCONFIGS"; then
Pablo Greco 7b2c62
	commit_new_configs
Pablo Greco 7b2c62
else
Pablo Greco 7b2c62
	process_configs
Pablo Greco 7b2c62
fi
Pablo Greco 7b2c62
Pablo Greco 7b2c62
exit $RETURNCODE