Index: Makefile
===================================================================
--- Makefile	(revision 8b863a629c2a1c274eeb1ea973a7ac4fead954cd)
+++ Makefile	(revision f857e8b0d7e7691bf604feaaf406a4154472a44a)
@@ -91,4 +91,7 @@
 	$(CONFIG) $<
 
+random-config: $(CONFIG_RULES)
+	$(CONFIG) $< random
+
 # Release files
 
Index: contrib/tools/random_check.sh
===================================================================
--- contrib/tools/random_check.sh	(revision f857e8b0d7e7691bf604feaaf406a4154472a44a)
+++ contrib/tools/random_check.sh	(revision f857e8b0d7e7691bf604feaaf406a4154472a44a)
@@ -0,0 +1,88 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2014 Vojtech Horky
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+LOOPS="$1"
+PARALLELISM="$2"
+[ -z "$LOOPS" ] && LOOPS=1
+[ -z "$PARALLELISM" ] && PARALLELISM=1
+
+
+run_clean() {
+	echo "  Cleaning after previous build." >&2
+	make distclean -j$PARALLELISM 2>&1 || exit 1
+}
+
+run_random_config() {
+	echo "  Preparing random configuration." >&2
+	make random-config 2>&1 || exit 1
+}
+
+run_make() {
+	echo -n "  Building... " >&2
+	make -j$PARALLELISM 2>&1
+	if [ $? -eq 0 ]; then
+		echo "okay." >&2
+		return 0
+	else
+		(
+			echo -n "failed ("
+			sed -n \
+				-e 's#PLATFORM = \(.*\)#\1#p' \
+				-e 's#MACHINE = \(.*\)#\1#p' \
+				-e 's#COMPILER = \(.*\)#\1#p' \
+				Makefile.config \
+				| paste '-sd,' | sed -e 's#,#, #g' -e 's#.*#&).#'
+		) >&2
+		return 1
+	fi
+}
+
+
+
+COUNTER=0
+FAILED=0
+while [ $COUNTER -lt $LOOPS ]; do
+	COUNTER=$(( $COUNTER + 1 ))
+	echo "Try #$COUNTER ($FAILED failures):" >&2
+	(
+		run_clean
+		run_random_config
+		run_make
+		exit $?
+	) >random_run_$COUNTER.log
+	if [ $? -ne 0 ]; then
+		tail -n 10 random_run_$COUNTER.log | sed 's#.*#    | &#'
+		FAILED=$(( FAILED + 1 ))
+	fi
+	cp Makefile.config random_run_$COUNTER.Makefile.config
+	cp config.h random_run_$COUNTER.config.h	
+done
+
+echo "Out of $LOOPS tries, $FAILED configurations failed to compile." >&2
Index: tools/config.py
===================================================================
--- tools/config.py	(revision 8b863a629c2a1c274eeb1ea973a7ac4fead954cd)
+++ tools/config.py	(revision f857e8b0d7e7691bf604feaaf406a4154472a44a)
@@ -40,4 +40,5 @@
 import subprocess
 import xtui
+import random
 
 RULES_FILE = sys.argv[1]
@@ -256,4 +257,85 @@
 	
 	return True
+
+## Fill the configuration with random (but valid) values.
+#
+# The random selection takes next rule and if the condition does
+# not violate existing configuration, random value of the variable
+# is selected.
+# This happens recursively as long as there are more rules.
+# If a conflict is found, we backtrack and try other settings of the
+# variable or ignoring the variable altogether.
+#
+# @param config Configuration to work on
+# @param rules  Rules
+# @param start_index With which rule to start (initial call must specify 0 here).
+# @return True if able to find a valid configuration 
+def random_choices(config, rules, start_index):
+	"Fill the configuration with random (but valid) values."
+	if start_index >= len(rules):
+		return True
+	
+	varname, vartype, name, choices, cond = rules[start_index]
+
+	# First check that this rule would make sense	
+	if cond:
+		if not check_condition(cond, config, rules):
+			return random_choices(config, rules, start_index + 1)
+	
+	# Remember previous choices for backtracking
+	yes_no = 0
+	choices_indexes = range(0, len(choices))
+	random.shuffle(choices_indexes)
+	
+	# Remember current configuration value
+	old_value = None
+	try:
+		old_value = config[varname]
+	except KeyError:
+		old_value = None
+	
+	# For yes/no choices, we ran the loop at most 2 times, for select
+	# choices as many times as there are options.
+	try_counter = 0
+	while True:
+		if vartype == 'choice':
+			if try_counter >= len(choices_indexes):
+				break
+			value = choices[choices_indexes[try_counter]][0]
+		elif vartype == 'y' or vartype == 'n':
+			if try_counter > 0:
+				break
+			value = vartype
+		elif vartype == 'y/n' or vartype == 'n/y':
+			if try_counter == 0:
+				yes_no = random.randint(0, 1)
+			elif try_counter == 1:
+				yes_no = 1 - yes_no
+			else:
+				break
+			if yes_no == 0:
+				value = 'n'
+			else:
+				value = 'y'
+		else:
+			raise RuntimeError("Unknown variable type: %s" % vartype)
+	
+		config[varname] = value
+		
+		ok = random_choices(config, rules, start_index + 1)
+		if ok:
+			return True
+		
+		try_counter = try_counter + 1
+	
+	# Restore the old value and backtrack
+	# (need to delete to prevent "ghost" variables that do not exist under
+	# certain configurations)
+	config[varname] = old_value
+	if old_value is None:
+		del config[varname]
+	
+	return random_choices(config, rules, start_index + 1)
+	
 
 ## Get default value from a rule.
@@ -555,4 +637,18 @@
 		return 1
 	
+	# Random mode
+	if (len(sys.argv) == 3) and (sys.argv[2] == 'random'):
+		ok = random_choices(config, rules, 0)
+		if not ok:
+			sys.stderr.write("Internal error: unable to generate random config.\n")
+			return 2
+		if not infer_verify_choices(config, rules):
+			sys.stderr.write("Internal error: random configuration not consistent.\n")
+			return 2
+		preprocess_config(config, rules)
+		create_output(MAKEFILE, MACROS, config, rules)
+		
+		return 0	
+	
 	screen = xtui.screen_init()
 	try:
