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